From 3dd3c61c30bde9647dfb8c9a487bcf73d340f3fd Mon Sep 17 00:00:00 2001 From: Mieczyslaw Nalewaj Date: Tue, 17 Sep 2024 21:59:28 +0200 Subject: [PATCH 01/23] realtek: drop 5.15 support Drop config and files for Linux 5.15. Signed-off-by: Mieczyslaw Nalewaj Link: https://github.com/openwrt/openwrt/pull/16417 Signed-off-by: Robert Marko --- .../bindings/realtek,otto-timer.yaml | 85 - .../mips/include/asm/mach-rtl838x/ioremap.h | 29 - .../include/asm/mach-rtl838x/mach-rtl83xx.h | 415 -- .../files-5.15/arch/mips/rtl838x/Makefile | 5 - .../files-5.15/arch/mips/rtl838x/Platform | 5 - .../files-5.15/arch/mips/rtl838x/prom.c | 212 - .../files-5.15/arch/mips/rtl838x/setup.c | 102 - .../files-5.15/drivers/clk/realtek/Kconfig | 19 - .../files-5.15/drivers/clk/realtek/Makefile | 2 - .../drivers/clk/realtek/clk-rtl838x-sram.S | 149 - .../drivers/clk/realtek/clk-rtl839x-sram.S | 141 - .../drivers/clk/realtek/clk-rtl83xx.c | 770 ---- .../drivers/clk/realtek/clk-rtl83xx.h | 75 - .../drivers/clocksource/timer-rtl-otto.c | 286 -- .../files-5.15/drivers/gpio/gpio-rtl8231.c | 364 -- .../drivers/i2c/busses/i2c-rtl9300.c | 486 -- .../drivers/i2c/busses/i2c-rtl9300.h | 62 - .../drivers/i2c/muxes/i2c-mux-rtl9300.c | 293 -- .../drivers/net/dsa/rtl83xx/Kconfig | 7 - .../drivers/net/dsa/rtl83xx/Makefile | 3 - .../drivers/net/dsa/rtl83xx/common.c | 1714 ------- .../drivers/net/dsa/rtl83xx/debugfs.c | 719 --- .../files-5.15/drivers/net/dsa/rtl83xx/dsa.c | 2237 --------- .../files-5.15/drivers/net/dsa/rtl83xx/qos.c | 565 --- .../drivers/net/dsa/rtl83xx/rtl838x.c | 2036 --------- .../drivers/net/dsa/rtl83xx/rtl838x.h | 1103 ----- .../drivers/net/dsa/rtl83xx/rtl839x.c | 1911 -------- .../drivers/net/dsa/rtl83xx/rtl83xx.h | 136 - .../drivers/net/dsa/rtl83xx/rtl930x.c | 2568 ----------- .../drivers/net/dsa/rtl83xx/rtl931x.c | 1694 ------- .../files-5.15/drivers/net/dsa/rtl83xx/tc.c | 410 -- .../drivers/net/ethernet/rtl838x_eth.c | 2733 ----------- .../drivers/net/ethernet/rtl838x_eth.h | 470 -- .../files-5.15/drivers/net/phy/rtl83xx-phy.c | 4001 ----------------- .../files-5.15/drivers/net/phy/rtl83xx-phy.h | 64 - .../include/dt-bindings/clock/rtl83xx-clk.h | 15 - ...hdog-add-realtek-otto-watchdog-timer.patch | 467 -- ...pers-to-extract-clause-45-regad-and-.patch | 53 - ...k-otto-Support-reversed-port-layouts.patch | 123 - ...ltek-otto-Support-per-cpu-interrupts.patch | 153 - ...pio-realtek-otto-Add-RTL930x-support.patch | 29 - ...pio-realtek-otto-Add-RTL931x-support.patch | 30 - .../300-mips-add-rtl838x-platform.patch | 86 - .../301-gpio-add-rtl8231-driver.patch | 50 - .../302-clocksource-add-otto-driver.patch | 93 - ...e-dependencies-for-gpio-realtek-otto.patch | 26 - ...pdate-dependency-for-spi-realtek-rtl.patch | 25 - ...pdate-dependency-for-irq-realtek-rtl.patch | 25 - ...date-dependency-for-realtek-otto-wdt.patch | 32 - ...308-otto-wdt-fix-missing-math-header.patch | 28 - .../310-add-i2c-rtl9300-support.patch | 46 - .../311-add-i2c-mux-rtl9300-support.patch | 46 - ...chip-irq-realtek-rtl-add-VPE-support.patch | 402 -- .../316-otto-gpio-uniprocessor-irq-mask.patch | 51 - ...io-realtek-otto-switch-to-32-bit-I-O.patch | 368 -- .../318-add-rtl83xx-clk-support.patch | 33 - ...hip-irq-realtek-rtl-fix-VPE-affinity.patch | 159 - ...t-dsa-add-support-for-rtl838x-switch.patch | 42 - ...-add-rtl838x-support-for-tag-trailer.patch | 61 - ...a-increase-dsa-max-ports-for-rtl838x.patch | 32 - ...net-add-support-for-rtl838x-ethernet.patch | 48 - ...nclude-linux-add-phy-ops-for-rtl838x.patch | 34 - ...vers-net-phy-eee-support-for-rtl838x.patch | 61 - ...04-include-linux-add-phy-hsgmii-mode.patch | 62 - .../patches-5.15/705-add-rtl-phy.patch | 39 - ...rease-phy-address-number-for-rtl839x.patch | 32 - ...sfp-re-probe-modules-on-DEV_UP-event.patch | 26 - ...11-net-phy-add-an-MDIO-SMBus-library.patch | 148 - ...12-net-phy-sfp-add-support-for-SMBus.patch | 99 - target/linux/realtek/rtl838x/config-5.15 | 224 - target/linux/realtek/rtl839x/config-5.15 | 244 - target/linux/realtek/rtl930x/config-5.15 | 205 - target/linux/realtek/rtl931x/config-5.15 | 241 - 73 files changed, 29809 deletions(-) delete mode 100644 target/linux/realtek/files-5.15/Documentation/devicetree/bindings/realtek,otto-timer.yaml delete mode 100644 target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/ioremap.h delete mode 100644 target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h delete mode 100644 target/linux/realtek/files-5.15/arch/mips/rtl838x/Makefile delete mode 100644 target/linux/realtek/files-5.15/arch/mips/rtl838x/Platform delete mode 100644 target/linux/realtek/files-5.15/arch/mips/rtl838x/prom.c delete mode 100644 target/linux/realtek/files-5.15/arch/mips/rtl838x/setup.c delete mode 100644 target/linux/realtek/files-5.15/drivers/clk/realtek/Kconfig delete mode 100644 target/linux/realtek/files-5.15/drivers/clk/realtek/Makefile delete mode 100644 target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl838x-sram.S delete mode 100644 target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl839x-sram.S delete mode 100644 target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.c delete mode 100644 target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.h delete mode 100644 target/linux/realtek/files-5.15/drivers/clocksource/timer-rtl-otto.c delete mode 100644 target/linux/realtek/files-5.15/drivers/gpio/gpio-rtl8231.c delete mode 100644 target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.c delete mode 100644 target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.h delete mode 100644 target/linux/realtek/files-5.15/drivers/i2c/muxes/i2c-mux-rtl9300.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Kconfig delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Makefile delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/debugfs.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/qos.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.h delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl839x.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl930x.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl931x.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/tc.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.h delete mode 100644 target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.c delete mode 100644 target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.h delete mode 100644 target/linux/realtek/files-5.15/include/dt-bindings/clock/rtl83xx-clk.h delete mode 100644 target/linux/realtek/patches-5.15/008-5.17-watchdog-add-realtek-otto-watchdog-timer.patch delete mode 100644 target/linux/realtek/patches-5.15/020-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch delete mode 100644 target/linux/realtek/patches-5.15/021-v5.19-02-gpio-realtek-otto-Support-reversed-port-layouts.patch delete mode 100644 target/linux/realtek/patches-5.15/021-v5.19-03-gpio-realtek-otto-Support-per-cpu-interrupts.patch delete mode 100644 target/linux/realtek/patches-5.15/021-v5.19-04-gpio-realtek-otto-Add-RTL930x-support.patch delete mode 100644 target/linux/realtek/patches-5.15/021-v5.19-06-gpio-realtek-otto-Add-RTL931x-support.patch delete mode 100644 target/linux/realtek/patches-5.15/300-mips-add-rtl838x-platform.patch delete mode 100644 target/linux/realtek/patches-5.15/301-gpio-add-rtl8231-driver.patch delete mode 100644 target/linux/realtek/patches-5.15/302-clocksource-add-otto-driver.patch delete mode 100644 target/linux/realtek/patches-5.15/303-gpio-update-dependencies-for-gpio-realtek-otto.patch delete mode 100644 target/linux/realtek/patches-5.15/304-spi-update-dependency-for-spi-realtek-rtl.patch delete mode 100644 target/linux/realtek/patches-5.15/305-irqchip-update-dependency-for-irq-realtek-rtl.patch delete mode 100644 target/linux/realtek/patches-5.15/307-wdt-update-dependency-for-realtek-otto-wdt.patch delete mode 100644 target/linux/realtek/patches-5.15/308-otto-wdt-fix-missing-math-header.patch delete mode 100644 target/linux/realtek/patches-5.15/310-add-i2c-rtl9300-support.patch delete mode 100644 target/linux/realtek/patches-5.15/311-add-i2c-mux-rtl9300-support.patch delete mode 100644 target/linux/realtek/patches-5.15/315-irqchip-irq-realtek-rtl-add-VPE-support.patch delete mode 100644 target/linux/realtek/patches-5.15/316-otto-gpio-uniprocessor-irq-mask.patch delete mode 100644 target/linux/realtek/patches-5.15/317-gpio-realtek-otto-switch-to-32-bit-I-O.patch delete mode 100644 target/linux/realtek/patches-5.15/318-add-rtl83xx-clk-support.patch delete mode 100644 target/linux/realtek/patches-5.15/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch delete mode 100644 target/linux/realtek/patches-5.15/700-net-dsa-add-support-for-rtl838x-switch.patch delete mode 100644 target/linux/realtek/patches-5.15/701-net-dsa-add-rtl838x-support-for-tag-trailer.patch delete mode 100644 target/linux/realtek/patches-5.15/702-net-dsa-increase-dsa-max-ports-for-rtl838x.patch delete mode 100644 target/linux/realtek/patches-5.15/702-net-ethernet-add-support-for-rtl838x-ethernet.patch delete mode 100644 target/linux/realtek/patches-5.15/703-include-linux-add-phy-ops-for-rtl838x.patch delete mode 100644 target/linux/realtek/patches-5.15/704-drivers-net-phy-eee-support-for-rtl838x.patch delete mode 100644 target/linux/realtek/patches-5.15/704-include-linux-add-phy-hsgmii-mode.patch delete mode 100644 target/linux/realtek/patches-5.15/705-add-rtl-phy.patch delete mode 100644 target/linux/realtek/patches-5.15/705-include-linux-phy-increase-phy-address-number-for-rtl839x.patch delete mode 100644 target/linux/realtek/patches-5.15/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch delete mode 100644 target/linux/realtek/patches-5.15/711-net-phy-add-an-MDIO-SMBus-library.patch delete mode 100644 target/linux/realtek/patches-5.15/712-net-phy-sfp-add-support-for-SMBus.patch delete mode 100644 target/linux/realtek/rtl838x/config-5.15 delete mode 100644 target/linux/realtek/rtl839x/config-5.15 delete mode 100644 target/linux/realtek/rtl930x/config-5.15 delete mode 100644 target/linux/realtek/rtl931x/config-5.15 diff --git a/target/linux/realtek/files-5.15/Documentation/devicetree/bindings/realtek,otto-timer.yaml b/target/linux/realtek/files-5.15/Documentation/devicetree/bindings/realtek,otto-timer.yaml deleted file mode 100644 index 40e834e3775263..00000000000000 --- a/target/linux/realtek/files-5.15/Documentation/devicetree/bindings/realtek,otto-timer.yaml +++ /dev/null @@ -1,85 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/timer/realtek,rtl8300-timer.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Realtek Timer Device Tree Bindings - -maintainers: - - Markus Stockhausen - -description: | - The Realtek SOCs of the RTL83XX and RTL93XX series have at least 5 known - timers with corresponding interrupt lines . Their speed is derived from the - Lexra Bus (LXB) by dividers. Each timer has a block of 4 control registers in - the address range 0xb800xxxx with following start offsets. - - RTL83XX: 0x3100, 0x3110, 0x3120, 0x3130, 0x3140 - RTL93XX: 0x3200, 0x3210, 0x3220, 0x3230, 0x3240 - -properties: - compatible: - items: - - enum: - - realtek,rtl8380-timer - - realtek,rtl8390-timer - - realtek,rtl9300-timer - - const: realtek,otto-timer - - reg: - minItems: 5 - maxItems: 5 - description: - List of timer register addresses. - - interrupts: - minItems: 5 - maxItems: 5 - description: - List of timer interrupts. - - clocks: - maxItems: 1 - -required: - - compatible - - reg - - interrupts - - clocks - -additionalProperties: false - -examples: - - | - timer0: timer@3100 { - compatible = "realtek,rtl8380-timer", "realtek,otto-timer"; - reg = <0x3100 0x10>, <0x3110 0x10>, <0x3120 0x10>, - <0x3130 0x10>, <0x3140 0x10>; - - interrupt-parent = <&intc>; - interrupts = <29 4>, <28 4>, <17 4>, <16 4>, <15 4>; - clocks = <&ccu CLK_LXB>; - }; - - | - timer0: timer@3100 { - compatible = "realtek,rtl8390-timer", "realtek,otto-timer"; - reg = <0x3100 0x10>, <0x3110 0x10>, <0x3120 0x10>, - <0x3130 0x10>, <0x3140 0x10>; - - interrupt-parent = <&intc>; - interrupts = <29 4>, <28 4>, <17 4>, <16 4>, <15 4>; - clocks = <&ccu CLK_LXB>; - }; - - | - timer0: timer@3200 { - compatible = "realtek,rtl9300-timer", "realtek,otto-timer"; - reg = <0x3200 0x10>, <0x3210 0x10>, <0x3220 0x10>, - <0x3230 0x10>, <0x3240 0x10>; - - interrupt-parent = <&intc>; - interrupts = <7 4>, <8 4>, <9 4>, <10 4>, <11 4>; - clocks = <&ccu CLK_LXB>; - }; - -... diff --git a/target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/ioremap.h b/target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/ioremap.h deleted file mode 100644 index c49a0957923372..00000000000000 --- a/target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/ioremap.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef RTL838X_IOREMAP_H_ -#define RTL838X_IOREMAP_H_ - -static inline int is_rtl838x_internal_registers(phys_addr_t offset) -{ - /* IO-Block */ - if (offset >= 0xb8000000 && offset < 0xb9000000) - return 1; - /* Switch block */ - if (offset >= 0xbb000000 && offset < 0xbc000000) - return 1; - return 0; -} - -static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, - unsigned long flags) -{ - if (is_rtl838x_internal_registers(offset)) - return (void __iomem *)offset; - return NULL; -} - -static inline int plat_iounmap(const volatile void __iomem *addr) -{ - return is_rtl838x_internal_registers((unsigned long)addr); -} - -#endif diff --git a/target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h b/target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h deleted file mode 100644 index 8ea580f3d113fa..00000000000000 --- a/target/linux/realtek/files-5.15/arch/mips/include/asm/mach-rtl838x/mach-rtl83xx.h +++ /dev/null @@ -1,415 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2006-2012 Tony Wu (tonywu@realtek.com) - * Copyright (C) 2020 B. Koblitz - */ -#ifndef _MACH_RTL838X_H_ -#define _MACH_RTL838X_H_ - -#include -/* - * Register access macros - */ - -#define RTL838X_SW_BASE ((volatile void *) 0xBB000000) - -#define rtl83xx_r32(reg) readl(reg) -#define rtl83xx_w32(val, reg) writel(val, reg) -#define rtl83xx_w32_mask(clear, set, reg) rtl83xx_w32((rtl83xx_r32(reg) & ~(clear)) | (set), reg) - -#define rtl83xx_r8(reg) readb(reg) -#define rtl83xx_w8(val, reg) writeb(val, reg) - -#define sw_r32(reg) readl(RTL838X_SW_BASE + reg) -#define sw_w32(val, reg) writel(val, RTL838X_SW_BASE + reg) -#define sw_w32_mask(clear, set, reg) \ - sw_w32((sw_r32(reg) & ~(clear)) | (set), reg) -#define sw_r64(reg) ((((u64)readl(RTL838X_SW_BASE + reg)) << 32) | \ - readl(RTL838X_SW_BASE + reg + 4)) - -#define sw_w64(val, reg) do { \ - writel((u32)((val) >> 32), RTL838X_SW_BASE + reg); \ - writel((u32)((val) & 0xffffffff), \ - RTL838X_SW_BASE + reg + 4); \ - } while (0) - -/* - * SPRAM - */ -#define RTL838X_ISPRAM_BASE 0x0 -#define RTL838X_DSPRAM_BASE 0x0 - -/* - * IRQ Controller - */ -#define RTL838X_IRQ_CPU_BASE 0 -#define RTL838X_IRQ_CPU_NUM 8 -#define RTL838X_IRQ_ICTL_BASE (RTL838X_IRQ_CPU_BASE + RTL838X_IRQ_CPU_NUM) -#define RTL838X_IRQ_ICTL_NUM 32 - -#define RTL83XX_IRQ_UART0 31 -#define RTL83XX_IRQ_UART1 30 -#define RTL83XX_IRQ_TC0 29 -#define RTL83XX_IRQ_TC1 28 -#define RTL83XX_IRQ_OCPTO 27 -#define RTL83XX_IRQ_HLXTO 26 -#define RTL83XX_IRQ_SLXTO 25 -#define RTL83XX_IRQ_NIC 24 -#define RTL83XX_IRQ_GPIO_ABCD 23 -#define RTL83XX_IRQ_GPIO_EFGH 22 -#define RTL83XX_IRQ_RTC 21 -#define RTL83XX_IRQ_SWCORE 20 -#define RTL83XX_IRQ_WDT_IP1 19 -#define RTL83XX_IRQ_WDT_IP2 18 - -#define RTL9300_UART1_IRQ 31 -#define RTL9300_UART0_IRQ 30 -#define RTL9300_USB_H2_IRQ 28 -#define RTL9300_NIC_IRQ 24 -#define RTL9300_SWCORE_IRQ 23 -#define RTL9300_GPIO_ABC_IRQ 13 -#define RTL9300_TC4_IRQ 11 -#define RTL9300_TC3_IRQ 10 -#define RTL9300_TC2_IRQ 9 -#define RTL9300_TC1_IRQ 8 -#define RTL9300_TC0_IRQ 7 - - -/* - * MIPS32R2 counter - */ -#define RTL838X_COMPARE_IRQ (RTL838X_IRQ_CPU_BASE + 7) - -/* - * ICTL - * Base address 0xb8003000UL - */ -#define RTL838X_ICTL1_IRQ (RTL838X_IRQ_CPU_BASE + 2) -#define RTL838X_ICTL2_IRQ (RTL838X_IRQ_CPU_BASE + 3) -#define RTL838X_ICTL3_IRQ (RTL838X_IRQ_CPU_BASE + 4) -#define RTL838X_ICTL4_IRQ (RTL838X_IRQ_CPU_BASE + 5) -#define RTL838X_ICTL5_IRQ (RTL838X_IRQ_CPU_BASE + 6) - -#define GIMR (0x00) -#define UART0_IE (1 << 31) -#define UART1_IE (1 << 30) -#define TC0_IE (1 << 29) -#define TC1_IE (1 << 28) -#define OCPTO_IE (1 << 27) -#define HLXTO_IE (1 << 26) -#define SLXTO_IE (1 << 25) -#define NIC_IE (1 << 24) -#define GPIO_ABCD_IE (1 << 23) -#define GPIO_EFGH_IE (1 << 22) -#define RTC_IE (1 << 21) -#define WDT_IP1_IE (1 << 19) -#define WDT_IP2_IE (1 << 18) - -#define GISR (0x04) -#define UART0_IP (1 << 31) -#define UART1_IP (1 << 30) -#define TC0_IP (1 << 29) -#define TC1_IP (1 << 28) -#define OCPTO_IP (1 << 27) -#define HLXTO_IP (1 << 26) -#define SLXTO_IP (1 << 25) -#define NIC_IP (1 << 24) -#define GPIO_ABCD_IP (1 << 23) -#define GPIO_EFGH_IP (1 << 22) -#define RTC_IP (1 << 21) -#define WDT_IP1_IP (1 << 19) -#define WDT_IP2_IP (1 << 18) - - -/* Interrupt Routing Selection */ -#define UART0_RS 2 -#define UART1_RS 1 -#define TC0_RS 5 -#define TC1_RS 1 -#define OCPTO_RS 1 -#define HLXTO_RS 1 -#define SLXTO_RS 1 -#define NIC_RS 4 -#define GPIO_ABCD_RS 4 -#define GPIO_EFGH_RS 4 -#define RTC_RS 4 -#define SWCORE_RS 3 -#define WDT_IP1_RS 4 -#define WDT_IP2_RS 5 - -/* Interrupt IRQ Assignments */ -#define UART0_IRQ 31 -#define UART1_IRQ 30 -#define TC0_IRQ 29 -#define TC1_IRQ 28 -#define OCPTO_IRQ 27 -#define HLXTO_IRQ 26 -#define SLXTO_IRQ 25 -#define NIC_IRQ 24 -#define GPIO_ABCD_IRQ 23 -#define GPIO_EFGH_IRQ 22 -#define RTC_IRQ 21 -#define SWCORE_IRQ 20 -#define WDT_IP1_IRQ 19 -#define WDT_IP2_IRQ 18 - -#define SYSTEM_FREQ 200000000 -#define RTL838X_UART0_BASE ((volatile void *)(0xb8002000UL)) -#define RTL838X_UART0_BAUD 38400 /* ex. 19200 or 38400 or 57600 or 115200 */ -#define RTL838X_UART0_FREQ (SYSTEM_FREQ - RTL838X_UART0_BAUD * 24) -#define RTL838X_UART0_MAPBASE 0x18002000UL -#define RTL838X_UART0_MAPSIZE 0x100 -#define RTL838X_UART0_IRQ UART0_IRQ - -#define RTL838X_UART1_BASE ((volatile void *)(0xb8002100UL)) -#define RTL838X_UART1_BAUD 38400 /* ex. 19200 or 38400 or 57600 or 115200 */ -#define RTL838X_UART1_FREQ (SYSTEM_FREQ - RTL838X_UART1_BAUD * 24) -#define RTL838X_UART1_MAPBASE 0x18002100UL -#define RTL838X_UART1_MAPSIZE 0x100 -#define RTL838X_UART1_IRQ UART1_IRQ - -#define UART0_RBR (RTL838X_UART0_BASE + 0x000) -#define UART0_THR (RTL838X_UART0_BASE + 0x000) -#define UART0_DLL (RTL838X_UART0_BASE + 0x000) -#define UART0_IER (RTL838X_UART0_BASE + 0x004) -#define UART0_DLM (RTL838X_UART0_BASE + 0x004) -#define UART0_IIR (RTL838X_UART0_BASE + 0x008) -#define UART0_FCR (RTL838X_UART0_BASE + 0x008) -#define UART0_LCR (RTL838X_UART0_BASE + 0x00C) -#define UART0_MCR (RTL838X_UART0_BASE + 0x010) -#define UART0_LSR (RTL838X_UART0_BASE + 0x014) - -#define UART1_RBR (RTL838X_UART1_BASE + 0x000) -#define UART1_THR (RTL838X_UART1_BASE + 0x000) -#define UART1_DLL (RTL838X_UART1_BASE + 0x000) -#define UART1_IER (RTL838X_UART1_BASE + 0x004) -#define UART1_DLM (RTL838X_UART1_BASE + 0x004) -#define UART1_IIR (RTL838X_UART1_BASE + 0x008) -#define UART1_FCR (RTL838X_UART1_BASE + 0x008) -#define UART1_LCR (RTL838X_UART1_BASE + 0x00C) -#define UART1_MCR (RTL838X_UART1_BASE + 0x010) -#define UART1_LSR (RTL838X_UART1_BASE + 0x014) - -/* - * Memory Controller - */ -#define MC_MCR 0xB8001000 -#define MC_MCR_VAL 0x00000000 - -#define MC_DCR 0xB8001004 -#define MC_DCR0_VAL 0x54480000 - -#define MC_DTCR 0xB8001008 -#define MC_DTCR_VAL 0xFFFF05C0 - -/* - * GPIO - */ -#define GPIO_CTRL_REG_BASE ((volatile void *) 0xb8003500) -#define RTL838X_GPIO_PABC_CNR (GPIO_CTRL_REG_BASE + 0x0) -#define RTL838X_GPIO_PABC_TYPE (GPIO_CTRL_REG_BASE + 0x04) -#define RTL838X_GPIO_PABC_DIR (GPIO_CTRL_REG_BASE + 0x8) -#define RTL838X_GPIO_PABC_DATA (GPIO_CTRL_REG_BASE + 0xc) -#define RTL838X_GPIO_PABC_ISR (GPIO_CTRL_REG_BASE + 0x10) -#define RTL838X_GPIO_PAB_IMR (GPIO_CTRL_REG_BASE + 0x14) -#define RTL838X_GPIO_PC_IMR (GPIO_CTRL_REG_BASE + 0x18) - -#define RTL930X_GPIO_CTRL_REG_BASE ((volatile void *) 0xb8003300) -#define RTL930X_GPIO_PABCD_DIR (RTL930X_GPIO_CTRL_REG_BASE + 0x8) -#define RTL930X_GPIO_PABCD_DAT (RTL930X_GPIO_CTRL_REG_BASE + 0xc) -#define RTL930X_GPIO_PABCD_ISR (RTL930X_GPIO_CTRL_REG_BASE + 0x10) -#define RTL930X_GPIO_PAB_IMR (RTL930X_GPIO_CTRL_REG_BASE + 0x14) -#define RTL930X_GPIO_PCD_IMR (RTL930X_GPIO_CTRL_REG_BASE + 0x18) - -#define RTL838X_MODEL_NAME_INFO (0x00D4) -#define RTL839X_MODEL_NAME_INFO (0x0FF0) -#define RTL93XX_MODEL_NAME_INFO (0x0004) -#define RTL931X_CHIP_INFO_ADDR (0x0008) - -#define RTL838X_LED_GLB_CTRL (0xA000) -#define RTL839X_LED_GLB_CTRL (0x00E4) -#define RTL9302_LED_GLB_CTRL (0xcc00) -#define RTL930X_LED_GLB_CTRL (0xCC00) -#define RTL931X_LED_GLB_CTRL (0x0600) - -#define RTL838X_EXT_GPIO_DIR (0xA08C) -#define RTL839X_EXT_GPIO_DIR (0x0214) -#define RTL838X_EXT_GPIO_DATA (0xA094) -#define RTL839X_EXT_GPIO_DATA (0x021c) -#define RTL838X_EXT_GPIO_INDRT_ACCESS (0xA09C) -#define RTL839X_EXT_GPIO_INDRT_ACCESS (0x0224) -#define RTL838X_EXTRA_GPIO_CTRL (0xA0E0) -#define RTL838X_DMY_REG5 (0x0144) -#define RTL838X_EXTRA_GPIO_CTRL (0xA0E0) - -#define RTL838X_GMII_INTF_SEL (0x1000) -#define RTL838X_IO_DRIVING_ABILITY_CTRL (0x1010) - -#define RTL838X_GPIO_A7 31 -#define RTL838X_GPIO_A6 30 -#define RTL838X_GPIO_A5 29 -#define RTL838X_GPIO_A4 28 -#define RTL838X_GPIO_A3 27 -#define RTL838X_GPIO_A2 26 -#define RTL838X_GPIO_A1 25 -#define RTL838X_GPIO_A0 24 -#define RTL838X_GPIO_B7 23 -#define RTL838X_GPIO_B6 22 -#define RTL838X_GPIO_B5 21 -#define RTL838X_GPIO_B4 20 -#define RTL838X_GPIO_B3 19 -#define RTL838X_GPIO_B2 18 -#define RTL838X_GPIO_B1 17 -#define RTL838X_GPIO_B0 16 -#define RTL838X_GPIO_C7 15 -#define RTL838X_GPIO_C6 14 -#define RTL838X_GPIO_C5 13 -#define RTL838X_GPIO_C4 12 -#define RTL838X_GPIO_C3 11 -#define RTL838X_GPIO_C2 10 -#define RTL838X_GPIO_C1 9 -#define RTL838X_GPIO_C0 8 - -#define RTL838X_INT_RW_CTRL (0x0058) -#define RTL838X_EXT_VERSION (0x00D0) -#define RTL838X_PLL_CML_CTRL (0x0FF8) -#define RTL838X_STRAP_DBG (0x100C) - -/* - * Reset - */ -#define RGCR (0x1E70) -#define RTL838X_RST_GLB_CTRL_0 (0x003c) -#define RTL838X_RST_GLB_CTRL_1 (0x0040) -#define RTL839X_RST_GLB_CTRL (0x0014) -#define RTL930X_RST_GLB_CTRL_0 (0x000c) -#define RTL931X_RST_GLB_CTRL (0x0400) - -/* LED control by switch */ -#define RTL838X_LED_MODE_SEL (0x1004) -#define RTL838X_LED_MODE_CTRL (0xA004) -#define RTL838X_LED_P_EN_CTRL (0xA008) - -/* LED control by software */ -#define RTL838X_LED_SW_CTRL (0xA00C) -#define RTL839X_LED_SW_CTRL (0xA00C) -#define RTL838X_LED_SW_P_EN_CTRL (0xA010) -#define RTL839X_LED_SW_P_EN_CTRL (0x012C) -#define RTL838X_LED0_SW_P_EN_CTRL (0xA010) -#define RTL839X_LED0_SW_P_EN_CTRL (0x012C) -#define RTL838X_LED1_SW_P_EN_CTRL (0xA014) -#define RTL839X_LED1_SW_P_EN_CTRL (0x0130) -#define RTL838X_LED2_SW_P_EN_CTRL (0xA018) -#define RTL839X_LED2_SW_P_EN_CTRL (0x0134) -#define RTL838X_LED_SW_P_CTRL (0xA01C) -#define RTL838X_LED_SW_P_CTRL_PORT(p) (RTL838X_LED_SW_P_CTRL + (((p) << 2))) -#define RTL839X_LED_SW_P_CTRL (0x0144) - -#define RTL839X_MAC_EFUSE_CTRL (0x02ac) - -/* - * MDIO via Realtek's SMI interface - */ -#define RTL838X_SMI_GLB_CTRL (0xa100) -#define RTL838X_SMI_ACCESS_PHY_CTRL_0 (0xa1b8) -#define RTL838X_SMI_ACCESS_PHY_CTRL_1 (0xa1bc) -#define RTL838X_SMI_ACCESS_PHY_CTRL_2 (0xa1c0) -#define RTL838X_SMI_ACCESS_PHY_CTRL_3 (0xa1c4) -#define RTL838X_SMI_PORT0_5_ADDR_CTRL (0xa1c8) -#define RTL838X_SMI_POLL_CTRL (0xa17c) - -#define RTL839X_SMI_GLB_CTRL (0x03f8) -#define RTL839X_SMI_PORT_POLLING_CTRL (0x03fc) -#define RTL839X_PHYREG_ACCESS_CTRL (0x03DC) -#define RTL839X_PHYREG_CTRL (0x03E0) -#define RTL839X_PHYREG_PORT_CTRL (0x03E4) -#define RTL839X_PHYREG_DATA_CTRL (0x03F0) -#define RTL839X_PHYREG_MMD_CTRL (0x3F4) - -#define RTL930X_SMI_GLB_CTRL (0xCA00) -#define RTL930X_SMI_POLL_CTRL (0xca90) -#define RTL930X_SMI_PORT0_15_POLLING_SEL (0xCA08) -#define RTL930X_SMI_PORT16_27_POLLING_SEL (0xCA0C) -#define RTL930X_SMI_PORT0_5_ADDR (0xCB80) -#define RTL930X_SMI_ACCESS_PHY_CTRL_0 (0xCB70) -#define RTL930X_SMI_ACCESS_PHY_CTRL_1 (0xCB74) -#define RTL930X_SMI_ACCESS_PHY_CTRL_2 (0xCB78) -#define RTL930X_SMI_ACCESS_PHY_CTRL_3 (0xCB7C) - -#define RTL931X_SMI_GLB_CTRL1 (0x0CBC) -#define RTL931X_SMI_GLB_CTRL0 (0x0CC0) -#define RTL931X_SMI_PORT_POLLING_CTRL (0x0CCC) -#define RTL931X_SMI_PORT_ADDR (0x0C74) -#define RTL931X_SMI_PORT_POLLING_SEL (0x0C9C) -#define RTL9310_SMI_PORT_POLLING_CTRL (0x0CCC) -#define RTL931X_SMI_INDRT_ACCESS_CTRL_0 (0x0C00) -#define RTL931X_SMI_INDRT_ACCESS_CTRL_1 (0x0C04) -#define RTL931X_SMI_INDRT_ACCESS_CTRL_2 (0x0C08) -#define RTL931X_SMI_INDRT_ACCESS_CTRL_3 (0x0C10) -#define RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL (0x0C14) -#define RTL931X_SMI_INDRT_ACCESS_MMD_CTRL (0xC18) -#define RTL931X_MAC_L2_GLOBAL_CTRL2 (0x1358) -#define RTL931X_MAC_L2_GLOBAL_CTRL1 (0x5548) - -/* Switch interrupts */ -#define RTL838X_IMR_GLB (0x1100) -#define RTL838X_IMR_PORT_LINK_STS_CHG (0x1104) -#define RTL838X_ISR_GLB_SRC (0x1148) -#define RTL838X_ISR_PORT_LINK_STS_CHG (0x114C) - -#define RTL839X_IMR_GLB (0x0064) -#define RTL839X_IMR_PORT_LINK_STS_CHG (0x0068) -#define RTL839X_ISR_GLB_SRC (0x009c) -#define RTL839X_ISR_PORT_LINK_STS_CHG (0x00a0) - -#define RTL930X_IMR_GLB (0xC628) -#define RTL930X_IMR_PORT_LINK_STS_CHG (0xC62C) -#define RTL930X_ISR_GLB (0xC658) -#define RTL930X_ISR_PORT_LINK_STS_CHG (0xC660) - -/* IMR_GLB does not exit on RTL931X */ -#define RTL931X_IMR_PORT_LINK_STS_CHG (0x126C) -#define RTL931X_ISR_GLB_SRC (0x12B4) -#define RTL931X_ISR_PORT_LINK_STS_CHG (0x12B8) - -/* Definition of family IDs */ -#define RTL8389_FAMILY_ID (0x8389) -#define RTL8328_FAMILY_ID (0x8328) -#define RTL8390_FAMILY_ID (0x8390) -#define RTL8350_FAMILY_ID (0x8350) -#define RTL8380_FAMILY_ID (0x8380) -#define RTL8330_FAMILY_ID (0x8330) -#define RTL9300_FAMILY_ID (0x9300) -#define RTL9310_FAMILY_ID (0x9310) - -/* SPI Support */ -#define RTL931X_SPI_CTRL0 (0x103C) - -/* Basic SoC Features */ -#define RTL838X_CPU_PORT 28 -#define RTL839X_CPU_PORT 52 -#define RTL930X_CPU_PORT 28 -#define RTL931X_CPU_PORT 56 - -struct rtl83xx_soc_info { - unsigned char *name; - unsigned int id; - unsigned int family; - unsigned char *compatible; - volatile void *sw_base; - volatile void *icu_base; - int cpu_port; -}; - -/* rtl83xx-related functions used across subsystems */ -int rtl838x_smi_wait_op(int timeout); -int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val); -int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val); -int rtl839x_read_phy(u32 port, u32 page, u32 reg, u32 *val); -int rtl839x_write_phy(u32 port, u32 page, u32 reg, u32 val); -int rtl930x_read_phy(u32 port, u32 page, u32 reg, u32 *val); -int rtl930x_write_phy(u32 port, u32 page, u32 reg, u32 val); -int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val); -int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val); - -#endif /* _MACH_RTL838X_H_ */ diff --git a/target/linux/realtek/files-5.15/arch/mips/rtl838x/Makefile b/target/linux/realtek/files-5.15/arch/mips/rtl838x/Makefile deleted file mode 100644 index a9d1666d4652e8..00000000000000 --- a/target/linux/realtek/files-5.15/arch/mips/rtl838x/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the rtl838x specific parts of the kernel -# - -obj-y := setup.o prom.o diff --git a/target/linux/realtek/files-5.15/arch/mips/rtl838x/Platform b/target/linux/realtek/files-5.15/arch/mips/rtl838x/Platform deleted file mode 100644 index 98f18cac1be13b..00000000000000 --- a/target/linux/realtek/files-5.15/arch/mips/rtl838x/Platform +++ /dev/null @@ -1,5 +0,0 @@ -# -# Realtek RTL838x SoCs -# -cflags-$(CONFIG_RTL83XX) += -I$(srctree)/arch/mips/include/asm/mach-rtl838x/ -load-$(CONFIG_RTL83XX) += 0xffffffff80100000 diff --git a/target/linux/realtek/files-5.15/arch/mips/rtl838x/prom.c b/target/linux/realtek/files-5.15/arch/mips/rtl838x/prom.c deleted file mode 100644 index 0c98af954859e1..00000000000000 --- a/target/linux/realtek/files-5.15/arch/mips/rtl838x/prom.c +++ /dev/null @@ -1,212 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * prom.c - * Early intialization code for the Realtek RTL838X SoC - * - * based on the original BSP by - * Copyright (C) 2006-2012 Tony Wu (tonywu@realtek.com) - * Copyright (C) 2020 B. Koblitz - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -extern char arcs_cmdline[]; - -struct rtl83xx_soc_info soc_info; -const void *fdt; - -#ifdef CONFIG_MIPS_MT_SMP -extern const struct plat_smp_ops vsmp_smp_ops; -static struct plat_smp_ops rtl_smp_ops; - -static void rtl_init_secondary(void) -{ -#ifndef CONFIG_CEVT_R4K -/* - * These devices are low on resources. There might be the chance that CEVT_R4K - * is not enabled in kernel build. Nevertheless the timer and interrupt 7 might - * be active by default after startup of secondary VPE. With no registered - * handler that leads to continuous unhandeled interrupts. In this case disable - * counting (DC) in the core and confirm a pending interrupt. - */ - write_c0_cause(read_c0_cause() | CAUSEF_DC); - write_c0_compare(0); -#endif /* CONFIG_CEVT_R4K */ -/* - * Enable all CPU interrupts, as everything is managed by the external - * controller. TODO: Standard vsmp_init_secondary() has special treatment for - * Malta if external GIC is available. Maybe we need this too. - */ - if (mips_gic_present()) - pr_warn("%s: GIC present. Maybe interrupt enabling required.\n", __func__); - else - set_c0_status(ST0_IM); -} -#endif /* CONFIG_MIPS_MT_SMP */ - -const char *get_system_type(void) -{ - return soc_info.name; -} - -void __init prom_free_prom_memory(void) -{ - -} - -void __init device_tree_init(void) -{ - if (!fdt_check_header(&__appended_dtb)) { - fdt = &__appended_dtb; - pr_info("Using appended Device Tree.\n"); - } - initial_boot_params = (void *)fdt; - unflatten_and_copy_device_tree(); -} - -void __init identify_rtl9302(void) -{ - switch (sw_r32(RTL93XX_MODEL_NAME_INFO) & 0xfffffff0) { - case 0x93020810: - soc_info.name = "RTL9302A 12x2.5G"; - break; - case 0x93021010: - soc_info.name = "RTL9302B 8x2.5G"; - break; - case 0x93021810: - soc_info.name = "RTL9302C 16x2.5G"; - break; - case 0x93022010: - soc_info.name = "RTL9302D 24x2.5G"; - break; - case 0x93020800: - soc_info.name = "RTL9302A"; - break; - case 0x93021000: - soc_info.name = "RTL9302B"; - break; - case 0x93021800: - soc_info.name = "RTL9302C"; - break; - case 0x93022000: - soc_info.name = "RTL9302D"; - break; - case 0x93023001: - soc_info.name = "RTL9302F"; - break; - default: - soc_info.name = "RTL9302"; - } -} - -void __init prom_init(void) -{ - uint32_t model; - - model = sw_r32(RTL838X_MODEL_NAME_INFO); - pr_info("RTL838X model is %x\n", model); - model = model >> 16 & 0xFFFF; - - if ((model != 0x8328) && (model != 0x8330) && (model != 0x8332) - && (model != 0x8380) && (model != 0x8382)) { - model = sw_r32(RTL839X_MODEL_NAME_INFO); - pr_info("RTL839X model is %x\n", model); - model = model >> 16 & 0xFFFF; - } - - if ((model & 0x8390) != 0x8380 && (model & 0x8390) != 0x8390) { - model = sw_r32(RTL93XX_MODEL_NAME_INFO); - pr_info("RTL93XX model is %x\n", model); - model = model >> 16 & 0xFFFF; - } - - soc_info.id = model; - - switch (model) { - case 0x8328: - soc_info.name = "RTL8328"; - soc_info.family = RTL8328_FAMILY_ID; - break; - case 0x8332: - soc_info.name = "RTL8332"; - soc_info.family = RTL8380_FAMILY_ID; - break; - case 0x8380: - soc_info.name = "RTL8380"; - soc_info.family = RTL8380_FAMILY_ID; - break; - case 0x8382: - soc_info.name = "RTL8382"; - soc_info.family = RTL8380_FAMILY_ID; - break; - case 0x8390: - soc_info.name = "RTL8390"; - soc_info.family = RTL8390_FAMILY_ID; - break; - case 0x8391: - soc_info.name = "RTL8391"; - soc_info.family = RTL8390_FAMILY_ID; - break; - case 0x8392: - soc_info.name = "RTL8392"; - soc_info.family = RTL8390_FAMILY_ID; - break; - case 0x8393: - soc_info.name = "RTL8393"; - soc_info.family = RTL8390_FAMILY_ID; - break; - case 0x9301: - soc_info.name = "RTL9301"; - soc_info.family = RTL9300_FAMILY_ID; - break; - case 0x9302: - identify_rtl9302(); - soc_info.family = RTL9300_FAMILY_ID; - break; - case 0x9303: - soc_info.name = "RTL9303"; - soc_info.family = RTL9300_FAMILY_ID; - break; - case 0x9313: - soc_info.name = "RTL9313"; - soc_info.family = RTL9310_FAMILY_ID; - break; - default: - soc_info.name = "DEFAULT"; - soc_info.family = 0; - } - - pr_info("SoC Type: %s\n", get_system_type()); - - fw_init_cmdline(); - - mips_cpc_probe(); - - if (!register_cps_smp_ops()) - return; - -#ifdef CONFIG_MIPS_MT_SMP - if (cpu_has_mipsmt) { - rtl_smp_ops = vsmp_smp_ops; - rtl_smp_ops.init_secondary = rtl_init_secondary; - register_smp_ops(&rtl_smp_ops); - return; - } -#endif - - register_up_smp_ops(); -} diff --git a/target/linux/realtek/files-5.15/arch/mips/rtl838x/setup.c b/target/linux/realtek/files-5.15/arch/mips/rtl838x/setup.c deleted file mode 100644 index 546b2fa2f81320..00000000000000 --- a/target/linux/realtek/files-5.15/arch/mips/rtl838x/setup.c +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Setup for the Realtek RTL838X SoC: - * Memory, Timer and Serial - * - * Copyright (C) 2020 B. Koblitz - * based on the original BSP by - * Copyright (C) 2006-2012 Tony Wu (tonywu@realtek.com) - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "mach-rtl83xx.h" - -extern struct rtl83xx_soc_info soc_info; - -void __init plat_mem_setup(void) -{ - void *dtb; - - set_io_port_base(KSEG1); - - dtb = get_fdt(); - if (!dtb) - panic("no dtb found"); - - /* - * Load the devicetree. This causes the chosen node to be - * parsed resulting in our memory appearing - */ - __dt_setup_arch(dtb); -} - -void plat_time_init_fallback(void) -{ - struct device_node *np; - u32 freq = 500000000; - - np = of_find_node_by_name(NULL, "cpus"); - if (!np) { - pr_err("Missing 'cpus' DT node, using default frequency."); - } else { - if (of_property_read_u32(np, "frequency", &freq) < 0) - pr_err("No 'frequency' property in DT, using default."); - else - pr_info("CPU frequency from device tree: %dMHz", freq / 1000000); - of_node_put(np); - } - mips_hpt_frequency = freq / 2; -} - -void __init plat_time_init(void) -{ -/* - * Initialization routine resembles generic MIPS plat_time_init() with - * lazy error handling. The final fallback is only needed until we have - * converted all device trees to new clock syntax. - */ - struct device_node *np; - struct clk *clk; - - of_clk_init(NULL); - - mips_hpt_frequency = 0; - np = of_get_cpu_node(0, NULL); - if (!np) { - pr_err("Failed to get CPU node\n"); - } else { - clk = of_clk_get(np, 0); - if (IS_ERR(clk)) { - pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk)); - } else { - mips_hpt_frequency = clk_get_rate(clk) / 2; - clk_put(clk); - } - } - - if (!mips_hpt_frequency) - plat_time_init_fallback(); - - timer_probe(); -} - -void __init arch_init_irq(void) -{ - irqchip_init(); -} diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/Kconfig b/target/linux/realtek/files-5.15/drivers/clk/realtek/Kconfig deleted file mode 100644 index 4cf3cd963399a2..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/clk/realtek/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -menuconfig COMMON_CLK_REALTEK - bool "Support for Realtek's clock controllers" - depends on RTL83XX - -if COMMON_CLK_REALTEK - -config COMMON_CLK_RTL83XX - bool "Clock driver for Realtek RTL83XX" - depends on RTL83XX - select SRAM - help - This driver adds support for the Realtek RTL83xx series basic clocks. - This includes chips in the RTL838x series, such as RTL8380, RTL8381, - RTL832, as well as chips from the RTL839x series, such as RTL8390, - RT8391, RTL8392, RTL8393 and RTL8396. - -endif diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/Makefile b/target/linux/realtek/files-5.15/drivers/clk/realtek/Makefile deleted file mode 100644 index 7bc4ed910c5226..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/clk/realtek/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_COMMON_CLK_RTL83XX) += clk-rtl83xx.o clk-rtl838x-sram.o clk-rtl839x-sram.o diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl838x-sram.S b/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl838x-sram.S deleted file mode 100644 index 24317231330a65..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl838x-sram.S +++ /dev/null @@ -1,149 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Realtek RTL838X SRAM clock setters - * Copyright (C) 2022 Markus Stockhausen - */ - -#include - -#include "clk-rtl83xx.h" - -#define rGLB $t0 -#define rCTR $t1 -#define rMSK $t2 -#define rSLP $t3 -#define rTMP $t4 - -.set noreorder - -.globl rtcl_838x_dram_start -rtcl_838x_dram_start: - -/* - * Functions start here and should avoid access to normal memory. REMARK! Do not forget about - * stack pointer and dirty caches that might interfere. - */ - -.globl rtcl_838x_dram_set_rate -.ent rtcl_838x_dram_set_rate -rtcl_838x_dram_set_rate: - -#ifdef CONFIG_RTL838X - - li rCTR, RTL_SW_CORE_BASE - addiu rGLB, rCTR, RTL838X_PLL_GLB_CTRL - ori rTMP, $0, CLK_CPU - beq $a0, rTMP, pre_cpu - ori rTMP, $0, CLK_MEM - beq $a0, rTMP, pre_mem - nop -pre_lxb: - ori rSLP, $0, RTL838X_GLB_CTRL_LXB_PLL_READY_MASK - addiu rCTR, rCTR, RTL838X_PLL_LXB_CTRL0 - b main_set - ori rMSK, $0, RTL838X_GLB_CTRL_EN_LXB_PLL_MASK -pre_mem: - /* simple 64K data cache flush to avoid unexpected memory access */ - li rMSK, RTL_SRAM_BASE - li rTMP, 2048 -pre_flush: - lw $0, 0(rMSK) - addiu rMSK, rMSK, 32 - addiu rTMP, rTMP, -1 - bne rTMP, $0, pre_flush - lw $0, -4(rMSK) - - ori rSLP, $0, RTL838X_GLB_CTRL_MEM_PLL_READY_MASK - addiu rCTR, rCTR, RTL838X_PLL_MEM_CTRL0 - b main_set - ori rMSK, $0, RTL838X_GLB_CTRL_EN_MEM_PLL_MASK -pre_cpu: - /* switch CPU to LXB clock */ - ori rMSK, $0, RTL838X_GLB_CTRL_CPU_PLL_SC_MUX_MASK - nor rMSK, rMSK, $0 - sync - lw rTMP, 0(rGLB) - and rTMP, rTMP, rMSK - sw rTMP, 0(rGLB) - sync - - ori rSLP, $0, RTL838X_GLB_CTRL_CPU_PLL_READY_MASK - addiu rCTR, rCTR, RTL838X_PLL_CPU_CTRL0 - ori rMSK, $0, RTL838X_GLB_CTRL_EN_CPU_PLL_MASK -main_set: - /* disable PLL */ - nor rMSK, rMSK, 0 - sync - lw rTMP, 0(rGLB) - sync - and rTMP, rTMP, rMSK - sync - sw rTMP, 0(rGLB) - - /* set new PLL values */ - sync - sw $a1, 0(rCTR) - sw $a2, 4(rCTR) - sync - - /* enable PLL (will reset it and clear ready status) */ - nor rMSK, rMSK, 0 - sync - lw rTMP, 0(rGLB) - sync - or rTMP, rTMP, rMSK - sync - sw rTMP, 0(rGLB) - - /* wait for PLL to become ready */ -wait_ready: - lw rTMP, 0(rGLB) - and rTMP, rTMP, rSLP - bne rTMP, $0, wait_ready - sync - - /* branch to post processing */ - ori rTMP, $0, CLK_CPU - beq $a0, rTMP, post_cpu - ori rTMP, $0, CLK_MEM - beq $a0, rTMP, post_mem - nop -post_lxb: - jr $ra - nop -post_mem: - jr $ra - nop -post_cpu: - /* stabilize clock to avoid crash, empirically determined */ - ori rSLP, $0, 0x3000 -wait_cpu: - bnez rSLP, wait_cpu - addiu rSLP, rSLP, -1 - - /* switch CPU to PLL clock */ - ori rMSK, $0, RTL838X_GLB_CTRL_CPU_PLL_SC_MUX_MASK - sync - lw rTMP, 0(rGLB) - or rTMP, rTMP, rMSK - sw rTMP, 0(rGLB) - sync - jr $ra - nop - -#else /* !CONFIG_RTL838X */ - - jr $ra - nop - -#endif - -.end rtcl_838x_dram_set_rate - -/* - * End marker. Do not delete. - */ - .word RTL_SRAM_MARKER -.globl rtcl_838x_dram_size -rtcl_838x_dram_size: - .word .-rtcl_838x_dram_start diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl839x-sram.S b/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl839x-sram.S deleted file mode 100644 index eb44cd90f14953..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl839x-sram.S +++ /dev/null @@ -1,141 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Realtek RTL839X SRAM clock setters - * Copyright (C) 2022 Markus Stockhausen - */ - -#include -#include - -#include "clk-rtl83xx.h" - -#define rGLB $t0 -#define rCTR $t1 -#define rMSK $t2 -#define rSLP1 $t3 -#define rSLP2 $t4 -#define rSLP3 $t5 -#define rTMP $t6 -#define rCP0 $t7 - -.set noreorder - -.globl rtcl_839x_dram_start -rtcl_839x_dram_start: - -/* - * Functions start here and should avoid access to normal memory. REMARK! Do not forget about - * stack pointer and dirty caches that might interfere. - */ - -.globl rtcl_839x_dram_set_rate -.ent rtcl_839x_dram_set_rate -rtcl_839x_dram_set_rate: - -#ifdef CONFIG_RTL839X - - /* disable MIPS 34K branch and return prediction */ - mfc0 rCP0, CP0_CONFIG, 7 - ori rTMP, rCP0, 0xc - mtc0 rTMP, CP0_CONFIG, 7 - - li rCTR, RTL_SW_CORE_BASE - addiu rGLB, rCTR, RTL839X_PLL_GLB_CTRL - ori rTMP, $0, CLK_CPU - beq $a0, rTMP, pre_cpu - ori rTMP, $0, CLK_MEM - beq $a0, rTMP, pre_mem - nop -pre_lxb: - li rSLP1, 0x400000 - li rSLP2, 0x400000 - li rSLP3, 0x400000 - addiu rCTR, rCTR, RTL839X_PLL_LXB_CTRL0 - b main_set - ori rMSK, $0, RTL839X_GLB_CTRL_LXB_CLKSEL_MASK -pre_mem: - /* try to avoid memory access with simple 64K data cache flush */ - li rMSK, RTL_SRAM_BASE - li rTMP, 2048 -pre_flush: - lw $0, 0(rMSK) - addiu rMSK, rMSK, 32 - addiu rTMP, rTMP, -1 - bne rTMP, $0, pre_flush - lw $0, -4(rMSK) - - li rSLP1, 0x10000 - li rSLP2, 0x10000 - li rSLP3, 0x10000 - addiu rCTR, rCTR, RTL839X_PLL_MEM_CTRL0 - b main_set - ori rMSK, $0, RTL839X_GLB_CTRL_MEM_CLKSEL_MASK -pre_cpu: - li rSLP1, 0x1000 - li rSLP2, 0x1000 - li rSLP3, 0x200 - addiu rCTR, rCTR, RTL839X_PLL_CPU_CTRL0 - ori rMSK, $0, RTL839X_GLB_CTRL_CPU_CLKSEL_MASK -main_set: - /* switch to fixed clock */ - sync - lw rTMP, 0(rGLB) - sync - or rTMP, rTMP, rMSK - sync - sw rTMP, 0(rGLB) - - /* wait until fixed clock in use */ - or rTMP, rSLP1, $0 -wait_fixclock: - bnez rTMP, wait_fixclock - addiu rTMP, rTMP, -1 - - /* set new PLL values */ - sync - sw $a1, 0(rCTR) - sw $a2, 4(rCTR) - sync - - /* wait for value takeover */ - or rTMP, rSLP2, $0 -wait_pll: - bnez rTMP, wait_pll - addiu rTMP, rTMP, -1 - - /* switch back to PLL clock*/ - nor rMSK, rMSK, $0 - sync - lw rTMP, 0(rGLB) - sync - and rTMP, rTMP, rMSK - sync - sw rTMP, 0(rGLB) - - /* wait until PLL clock in use */ - or rTMP, rSLP3, $0 -wait_pllclock: - bnez rTMP, wait_pllclock - addiu rTMP, rTMP, -1 - - /* restore branch prediction */ - mtc0 rCP0, CP0_CONFIG, 7 - jr $ra - nop - -#else /* !CONFIG_RTL839X */ - - jr $ra - nop - -#endif - -.end rtcl_839x_dram_set_rate - -/* - * End marker. Do not delete. - */ - .word RTL_SRAM_MARKER -.globl rtcl_839x_dram_size -rtcl_839x_dram_size: - .word .-rtcl_839x_dram_start diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.c b/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.c deleted file mode 100644 index 0cca32ab3447b2..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.c +++ /dev/null @@ -1,770 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Realtek RTL83XX clock driver - * Copyright (C) 2022 Markus Stockhausen - * - * This driver provides basic clock support for the central core clock unit (CCU) and its PLLs - * inside the RTL838X and RTL8389X SOC. Currently CPU, memory and LXB clock information can be - * accessed. To make use of the driver add the following devices and configurations at the - * appropriate locations to the DT. - * - * #include - * - * sram0: sram@9f000000 { - * compatible = "mmio-sram"; - * reg = <0x9f000000 0x18000>; - * #address-cells = <1>; - * #size-cells = <1>; - * ranges = <0 0x9f000000 0x18000>; - * }; - * - * osc: oscillator { - * compatible = "fixed-clock"; - * #clock-cells = <0>; - * clock-frequency = <25000000>; - * }; - * - * ccu: clock-controller { - * compatible = "realtek,rtl8380-clock"; - * #clock-cells = <1>; - * clocks = <&osc>; - * clock-names = "ref_clk"; - * }; - * - * - * The SRAM part is needed to be able to set clocks. When changing clocks the code must not run - * from DRAM. Otherwise system might freeze. Take care to adjust CCU compatibility, SRAM address - * and size to the target SOC device. Afterwards one can access/identify the clocks in the other - * DT devices with <&ccu CLK_CPU>, <&ccu CLK_MEM> or <&ccu CLK_LXB>. Additionally the clocks can - * be used inside the kernel with - * - * cpu_clk = clk_get(NULL, "cpu_clk"); - * mem_clk = clk_get(NULL, "mem_clk"); - * lxb_clk = clk_get(NULL, "lxb_clk"); - * - * This driver can be directly used by the DT based cpufreq driver (CONFIG_CPUFREQ_DT) if CPU - * references the right clock and sane operating points (OPP) are provided. E.g. - * - * cpu@0 { - * compatible = "mips,mips4KEc"; - * reg = <0>; - * clocks = <&ccu CLK_CPU>; - * operating-points-v2 = <&cpu_opp_table>; - * }; - * - * cpu_opp_table: opp-table-0 { - * compatible = "operating-points-v2"; - * opp-shared; - * opp00 { - * opp-hz = /bits/ 64 <425000000>; - * }; - * ... - * } - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "clk-rtl83xx.h" - -#define read_sw(reg) ioread32(((void *)RTL_SW_CORE_BASE) + reg) -#define read_soc(reg) ioread32(((void *)RTL_SOC_BASE) + reg) - -#define write_sw(val, reg) iowrite32(val, ((void *)RTL_SW_CORE_BASE) + reg) -#define write_soc(val, reg) iowrite32(val, ((void *)RTL_SOC_BASE) + reg) - -/* - * some hardware specific definitions - */ - -#define SOC_RTL838X 0 -#define SOC_RTL839X 1 -#define SOC_COUNT 2 - -#define MEM_DDR1 1 -#define MEM_DDR2 2 -#define MEM_DDR3 3 - -#define REG_CTRL0 0 -#define REG_CTRL1 1 -#define REG_COUNT 2 - -#define OSC_RATE 25000000 - -static const int rtcl_regs[SOC_COUNT][REG_COUNT][CLK_COUNT] = { - { - { RTL838X_PLL_CPU_CTRL0, RTL838X_PLL_MEM_CTRL0, RTL838X_PLL_LXB_CTRL0 }, - { RTL838X_PLL_CPU_CTRL1, RTL838X_PLL_MEM_CTRL1, RTL838X_PLL_LXB_CTRL1 }, - }, { - { RTL839X_PLL_CPU_CTRL0, RTL839X_PLL_MEM_CTRL0, RTL839X_PLL_LXB_CTRL0 }, - { RTL839X_PLL_CPU_CTRL1, RTL839X_PLL_MEM_CTRL1, RTL839X_PLL_LXB_CTRL1 }, - } -}; - -#define RTCL_REG_SET(_rate, _ctrl0, _ctrl1) \ - { \ - .rate = _rate, \ - .ctrl0 = _ctrl0, \ - .ctrl1 = _ctrl1, \ - } - -struct rtcl_reg_set { - unsigned int rate; - unsigned int ctrl0; - unsigned int ctrl1; -}; - -/* - * The following configuration tables are valid operation points for their - * corresponding PLLs. The magic numbers are precalculated mulitpliers and - * dividers to keep the driver simple. They also provide rates outside the - * allowed physical specifications. E.g. DDR3 memory has a lower limit of 303 - * MHz or the CPU might get unstable if set to anything above its startup - * frequency. Additionally the Realtek SOCs tend to expect CPU speed larger - * than MEM speed larger than LXB speed. The caller or DT configuration must - * take care that only valid operating points are selected. - */ - -static const struct rtcl_reg_set rtcl_838x_cpu_reg_set[] = { - RTCL_REG_SET(300000000, 0x045c8, 0x1414530e), - RTCL_REG_SET(325000000, 0x04648, 0x1414530e), - RTCL_REG_SET(350000000, 0x046c8, 0x1414530e), - RTCL_REG_SET(375000000, 0x04748, 0x1414530e), - RTCL_REG_SET(400000000, 0x045c8, 0x0c14530e), - RTCL_REG_SET(425000000, 0x04628, 0x0c14530e), - RTCL_REG_SET(450000000, 0x04688, 0x0c14530e), - RTCL_REG_SET(475000000, 0x046e8, 0x0c14530e), - RTCL_REG_SET(500000000, 0x04748, 0x0c14530e), - RTCL_REG_SET(525000000, 0x047a8, 0x0c14530e), - RTCL_REG_SET(550000000, 0x04808, 0x0c14530e), - RTCL_REG_SET(575000000, 0x04868, 0x0c14530e), - RTCL_REG_SET(600000000, 0x048c8, 0x0c14530e), - RTCL_REG_SET(625000000, 0x04928, 0x0c14530e) -}; - -static const struct rtcl_reg_set rtcl_838x_mem_reg_set[] = { - RTCL_REG_SET(200000000, 0x041bc, 0x14018C80), - RTCL_REG_SET(225000000, 0x0417c, 0x0c018C80), - RTCL_REG_SET(250000000, 0x041ac, 0x0c018C80), - RTCL_REG_SET(275000000, 0x0412c, 0x04018C80), - RTCL_REG_SET(300000000, 0x0414c, 0x04018c80), - RTCL_REG_SET(325000000, 0x0416c, 0x04018c80), - RTCL_REG_SET(350000000, 0x0418c, 0x04018c80), - RTCL_REG_SET(375000000, 0x041ac, 0x04018c80) -}; - -static const struct rtcl_reg_set rtcl_838x_lxb_reg_set[] = { - RTCL_REG_SET(100000000, 0x043c8, 0x001ad30e), - RTCL_REG_SET(125000000, 0x043c8, 0x001ad30e), - RTCL_REG_SET(150000000, 0x04508, 0x1c1ad30e), - RTCL_REG_SET(175000000, 0x04508, 0x1c1ad30e), - RTCL_REG_SET(200000000, 0x047c8, 0x001ad30e) -}; - -static const struct rtcl_reg_set rtcl_839x_cpu_reg_set[] = { - RTCL_REG_SET(400000000, 0x0414c, 0x00000005), - RTCL_REG_SET(425000000, 0x041ec, 0x00000006), - RTCL_REG_SET(450000000, 0x0417c, 0x00000005), - RTCL_REG_SET(475000000, 0x0422c, 0x00000006), - RTCL_REG_SET(500000000, 0x041ac, 0x00000005), - RTCL_REG_SET(525000000, 0x0426c, 0x00000006), - RTCL_REG_SET(550000000, 0x0412c, 0x00000004), - RTCL_REG_SET(575000000, 0x042ac, 0x00000006), - RTCL_REG_SET(600000000, 0x0414c, 0x00000004), - RTCL_REG_SET(625000000, 0x042ec, 0x00000006), - RTCL_REG_SET(650000000, 0x0416c, 0x00000004), - RTCL_REG_SET(675000000, 0x04324, 0x00000006), - RTCL_REG_SET(700000000, 0x0418c, 0x00000004), - RTCL_REG_SET(725000000, 0x0436c, 0x00000006), - RTCL_REG_SET(750000000, 0x0438c, 0x00000006), - RTCL_REG_SET(775000000, 0x043ac, 0x00000006), - RTCL_REG_SET(800000000, 0x043cc, 0x00000006), - RTCL_REG_SET(825000000, 0x043ec, 0x00000006), - RTCL_REG_SET(850000000, 0x0440c, 0x00000006) -}; - -static const struct rtcl_reg_set rtcl_839x_mem_reg_set[] = { - RTCL_REG_SET(100000000, 0x041cc, 0x00000000), - RTCL_REG_SET(125000000, 0x041ac, 0x00000007), - RTCL_REG_SET(150000000, 0x0414c, 0x00000006), - RTCL_REG_SET(175000000, 0x0418c, 0x00000006), - RTCL_REG_SET(200000000, 0x041cc, 0x00000006), - RTCL_REG_SET(225000000, 0x0417c, 0x00000005), - RTCL_REG_SET(250000000, 0x041ac, 0x00000005), - RTCL_REG_SET(275000000, 0x0412c, 0x00000004), - RTCL_REG_SET(300000000, 0x0414c, 0x00000004), - RTCL_REG_SET(325000000, 0x0416c, 0x00000004), - RTCL_REG_SET(350000000, 0x0418c, 0x00000004), - RTCL_REG_SET(375000000, 0x041ac, 0x00000004), - RTCL_REG_SET(400000000, 0x041cc, 0x00000004) -}; - -static const struct rtcl_reg_set rtcl_839x_lxb_reg_set[] = { - RTCL_REG_SET(50000000, 0x1414c, 0x00000003), - RTCL_REG_SET(100000000, 0x0814c, 0x00000003), - RTCL_REG_SET(150000000, 0x0414c, 0x00000003), - RTCL_REG_SET(200000000, 0x0414c, 0x00000007) -}; - -struct rtcl_rtab_set { - int count; - const struct rtcl_reg_set *rset; -}; - -#define RTCL_RTAB_SET(_rset) \ - { \ - .count = ARRAY_SIZE(_rset), \ - .rset = _rset, \ - } - -static const struct rtcl_rtab_set rtcl_rtab_set[SOC_COUNT][CLK_COUNT] = { - { - RTCL_RTAB_SET(rtcl_838x_cpu_reg_set), - RTCL_RTAB_SET(rtcl_838x_mem_reg_set), - RTCL_RTAB_SET(rtcl_838x_lxb_reg_set) - }, { - RTCL_RTAB_SET(rtcl_839x_cpu_reg_set), - RTCL_RTAB_SET(rtcl_839x_mem_reg_set), - RTCL_RTAB_SET(rtcl_839x_lxb_reg_set) - } -}; - -#define RTCL_ROUND_SET(_min, _max, _step) \ - { \ - .min = _min, \ - .max = _max, \ - .step = _step, \ - } - -struct rtcl_round_set { - unsigned long min; - unsigned long max; - unsigned long step; -}; - -static const struct rtcl_round_set rtcl_round_set[SOC_COUNT][CLK_COUNT] = { - { - RTCL_ROUND_SET(300000000, 625000000, 25000000), - RTCL_ROUND_SET(200000000, 375000000, 25000000), - RTCL_ROUND_SET(100000000, 200000000, 25000000) - }, { - RTCL_ROUND_SET(400000000, 850000000, 25000000), - RTCL_ROUND_SET(100000000, 400000000, 25000000), - RTCL_ROUND_SET(50000000, 200000000, 50000000) - } -}; - -static const int rtcl_divn3[] = { 2, 3, 4, 6 }; -static const int rtcl_xdiv[] = { 2, 4, 2 }; - -/* - * module data structures - */ - -#define RTCL_CLK_INFO(_idx, _name, _pname, _dname) \ - { \ - .idx = _idx, \ - .name = _name, \ - .parent_name = _pname, \ - .display_name = _dname, \ - } - -struct rtcl_clk_info { - unsigned int idx; - const char *name; - const char *parent_name; - const char *display_name; -}; - -struct rtcl_clk { - struct clk_hw hw; - unsigned int idx; - unsigned long min; - unsigned long max; - unsigned long rate; - unsigned long startup; -}; - -static const struct rtcl_clk_info rtcl_clk_info[CLK_COUNT] = { - RTCL_CLK_INFO(CLK_CPU, "cpu_clk", "ref_clk", "CPU"), - RTCL_CLK_INFO(CLK_MEM, "mem_clk", "ref_clk", "MEM"), - RTCL_CLK_INFO(CLK_LXB, "lxb_clk", "ref_clk", "LXB") -}; - -struct rtcl_dram { - int type; - int buswidth; -}; - -struct rtcl_sram { - int *pmark; - unsigned long vbase; -}; - -struct rtcl_ccu { - spinlock_t lock; - unsigned int soc; - struct rtcl_sram sram; - struct rtcl_dram dram; - struct device_node *np; - struct platform_device *pdev; - struct rtcl_clk clks[CLK_COUNT]; -}; - -struct rtcl_ccu *rtcl_ccu; - -#define rtcl_hw_to_clk(_hw) container_of(_hw, struct rtcl_clk, hw) - -/* - * SRAM relocatable assembler functions. The dram() parts point to normal kernel - * memory while the sram() parts are the same functions but relocated to SRAM. - */ - -extern void rtcl_838x_dram_start(void); -extern int rtcl_838x_dram_size; - -extern void (*rtcl_838x_dram_set_rate)(int clk_idx, int ctrl0, int ctrl1); -static void (*rtcl_838x_sram_set_rate)(int clk_idx, int ctrl0, int ctrl1); - -extern void rtcl_839x_dram_start(void); -extern int rtcl_839x_dram_size; - -extern void (*rtcl_839x_dram_set_rate)(int clk_idx, int ctrl0, int ctrl1); -static void (*rtcl_839x_sram_set_rate)(int clk_idx, int ctrl0, int ctrl1); - -/* - * clock setter/getter functions - */ - -static unsigned long rtcl_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) -{ - struct rtcl_clk *clk = rtcl_hw_to_clk(hw); - unsigned int ctrl0, ctrl1, div1, div2, cmu_ncode_in; - unsigned int cmu_sel_prediv, cmu_sel_div4, cmu_divn2, cmu_divn2_selb, cmu_divn3_sel; - - if ((clk->idx >= CLK_COUNT) || (!rtcl_ccu) || (rtcl_ccu->soc >= SOC_COUNT)) - return 0; - - ctrl0 = read_sw(rtcl_regs[rtcl_ccu->soc][REG_CTRL0][clk->idx]); - ctrl1 = read_sw(rtcl_regs[rtcl_ccu->soc][REG_CTRL1][clk->idx]); - - cmu_sel_prediv = 1 << RTL_PLL_CTRL0_CMU_SEL_PREDIV(ctrl0); - cmu_sel_div4 = RTL_PLL_CTRL0_CMU_SEL_DIV4(ctrl0) ? 4 : 1; - cmu_ncode_in = RTL_PLL_CTRL0_CMU_NCODE_IN(ctrl0) + 4; - cmu_divn2 = RTL_PLL_CTRL0_CMU_DIVN2(ctrl0) + 4; - - switch (rtcl_ccu->soc) { - case SOC_RTL838X: - if ((ctrl0 == 0) && (ctrl1 == 0) && (clk->idx == CLK_LXB)) - return 200000000; - - cmu_divn2_selb = RTL838X_PLL_CTRL1_CMU_DIVN2_SELB(ctrl1); - cmu_divn3_sel = rtcl_divn3[RTL838X_PLL_CTRL1_CMU_DIVN3_SEL(ctrl1)]; - break; - case SOC_RTL839X: - cmu_divn2_selb = RTL839X_PLL_CTRL1_CMU_DIVN2_SELB(ctrl1); - cmu_divn3_sel = rtcl_divn3[RTL839X_PLL_CTRL1_CMU_DIVN3_SEL(ctrl1)]; - break; - } - div1 = cmu_divn2_selb ? cmu_divn3_sel : cmu_divn2; - div2 = rtcl_xdiv[clk->idx]; - - return (((parent_rate / 16) * cmu_ncode_in) / (div1 * div2)) * - cmu_sel_prediv * cmu_sel_div4 * 16; -} - -static int rtcl_838x_set_rate(int clk_idx, const struct rtcl_reg_set *reg) -{ - unsigned long irqflags; -/* - * Runtime of this function (including locking) - * CPU: up to 14000 cycles / up to 56 us at 250 MHz (half default speed) - */ - spin_lock_irqsave(&rtcl_ccu->lock, irqflags); - rtcl_838x_sram_set_rate(clk_idx, reg->ctrl0, reg->ctrl1); - spin_unlock_irqrestore(&rtcl_ccu->lock, irqflags); - - return 0; -} - -static int rtcl_839x_set_rate(int clk_idx, const struct rtcl_reg_set *reg) -{ - unsigned long vpflags; - unsigned long irqflags; -/* - * Runtime of this function (including locking) - * CPU: up to 31000 cycles / up to 89 us at 350 MHz (half default speed) - */ - spin_lock_irqsave(&rtcl_ccu->lock, irqflags); - vpflags = dvpe(); - rtcl_839x_sram_set_rate(clk_idx, reg->ctrl0, reg->ctrl1); - evpe(vpflags); - spin_unlock_irqrestore(&rtcl_ccu->lock, irqflags); - - return 0; -} - -static int rtcl_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) -{ - int tab_idx; - struct rtcl_clk *clk = rtcl_hw_to_clk(hw); - const struct rtcl_rtab_set *rtab = &rtcl_rtab_set[rtcl_ccu->soc][clk->idx]; - const struct rtcl_round_set *round = &rtcl_round_set[rtcl_ccu->soc][clk->idx]; - - if ((parent_rate != OSC_RATE) || (!rtcl_ccu->sram.vbase)) - return -EINVAL; -/* - * Currently we do not know if SRAM is stable on these devices. Maybe someone - * changes memory in this region and does not care about proper allocation. So - * check if something might go wrong. - */ - if (unlikely(*rtcl_ccu->sram.pmark != RTL_SRAM_MARKER)) { - dev_err(&rtcl_ccu->pdev->dev, "SRAM code lost\n"); - return -EINVAL; - } - - tab_idx = (rate - round->min) / round->step; - if ((tab_idx < 0) || (tab_idx >= rtab->count) || (rtab->rset[tab_idx].rate != rate)) - return -EINVAL; - - rtcl_ccu->clks[clk->idx].rate = rate; - - switch (rtcl_ccu->soc) { - case SOC_RTL838X: - return rtcl_838x_set_rate(clk->idx, &rtab->rset[tab_idx]); - case SOC_RTL839X: - return rtcl_839x_set_rate(clk->idx, &rtab->rset[tab_idx]); - } - - return -ENXIO; -} - -static long rtcl_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) -{ - struct rtcl_clk *clk = rtcl_hw_to_clk(hw); - unsigned long rrate = max(clk->min, min(clk->max, rate)); - const struct rtcl_round_set *round = &rtcl_round_set[rtcl_ccu->soc][clk->idx]; - - rrate = ((rrate + (round->step >> 1)) / round->step) * round->step; - rrate -= (rrate > clk->max) ? round->step : 0; - rrate += (rrate < clk->min) ? round->step : 0; - - return rrate; -} - -/* - * Initialization functions to register the CCU and its clocks - */ - -#define RTCL_SRAM_FUNC(SOC, PBASE, FN) ({ \ - rtcl_##SOC##_sram_##FN = ((void *)&rtcl_##SOC##_dram_##FN - \ - (void *)&rtcl_##SOC##_dram_start) + \ - (void *)PBASE; }) - -static const struct clk_ops rtcl_clk_ops = { - .set_rate = rtcl_set_rate, - .round_rate = rtcl_round_rate, - .recalc_rate = rtcl_recalc_rate, -}; - -static int rtcl_ccu_create(struct device_node *np) -{ - int soc; - - if (of_device_is_compatible(np, "realtek,rtl8380-clock")) - soc = SOC_RTL838X; - else if (of_device_is_compatible(np, "realtek,rtl8390-clock")) - soc = SOC_RTL839X; - else - return -ENXIO; - - rtcl_ccu = kzalloc(sizeof(*rtcl_ccu), GFP_KERNEL); - if (IS_ERR(rtcl_ccu)) - return -ENOMEM; - - rtcl_ccu->np = np; - rtcl_ccu->soc = soc; - rtcl_ccu->dram.type = RTL_MC_MCR_DRAMTYPE(read_soc(RTL_MC_MCR)); - rtcl_ccu->dram.buswidth = RTL_MC_DCR_BUSWIDTH(read_soc(RTL_MC_DCR)); - spin_lock_init(&rtcl_ccu->lock); - - return 0; -} - -int rtcl_register_clkhw(int clk_idx) -{ - int ret; - struct clk *clk; - struct clk_init_data hw_init = { }; - struct rtcl_clk *rclk = &rtcl_ccu->clks[clk_idx]; - struct clk_parent_data parent_data = { .fw_name = rtcl_clk_info[clk_idx].parent_name }; - - rclk->idx = clk_idx; - rclk->hw.init = &hw_init; - - hw_init.num_parents = 1; - hw_init.ops = &rtcl_clk_ops; - hw_init.parent_data = &parent_data; - hw_init.name = rtcl_clk_info[clk_idx].name; - - ret = of_clk_hw_register(rtcl_ccu->np, &rclk->hw); - if (ret) - return ret; - - clk_hw_register_clkdev(&rclk->hw, rtcl_clk_info[clk_idx].name, NULL); - - clk = clk_get(NULL, rtcl_clk_info[clk_idx].name); - rclk->startup = clk_get_rate(clk); - clk_put(clk); - - switch (clk_idx) { - case CLK_CPU: - rclk->min = rtcl_round_set[rtcl_ccu->soc][clk_idx].min; - rclk->max = rtcl_round_set[rtcl_ccu->soc][clk_idx].max; - break; - default: -/* - * TODO: This driver supports PLL reclocking and nothing else. Additional - * required steps for non CPU PLLs are missing. E.g. if we want to change memory - * clocks the right way we must adapt a lot of other settings. This includes - * MCR and DTRx timing registers (0xb80001000, 0xb8001008, ...) and a DLL reset - * so that hardware operates in the allowed limits. This is far too complex - * without official support. Avoid this for now. - */ - rclk->min = rclk->max = rclk->startup; - break; - } - - return 0; -} - -static struct clk_hw *rtcl_get_clkhw(struct of_phandle_args *clkspec, void *prv) -{ - unsigned int idx = clkspec->args[0]; - - if (idx >= CLK_COUNT) { - pr_err("%s: Invalid index %u\n", __func__, idx); - return ERR_PTR(-EINVAL); - } - - return &rtcl_ccu->clks[idx].hw; -} - -static int rtcl_ccu_register_clocks(void) -{ - int clk_idx, ret; - - for (clk_idx = 0; clk_idx < CLK_COUNT; clk_idx++) { - ret = rtcl_register_clkhw(clk_idx); - if (ret) { - pr_err("%s: Couldn't register %s clock\n", - __func__, rtcl_clk_info[clk_idx].display_name); - goto err_hw_unregister; - } - } - - ret = of_clk_add_hw_provider(rtcl_ccu->np, rtcl_get_clkhw, rtcl_ccu); - if (ret) { - pr_err("%s: Couldn't register clock provider of %s\n", - __func__, of_node_full_name(rtcl_ccu->np)); - goto err_hw_unregister; - } - - return 0; - -err_hw_unregister: - for (--clk_idx; clk_idx >= 0; --clk_idx) - clk_hw_unregister(&rtcl_ccu->clks[clk_idx].hw); - - return ret; -} - -int rtcl_init_sram(void) -{ - struct gen_pool *sram_pool; - phys_addr_t sram_pbase; - unsigned long sram_vbase; - struct device_node *node; - struct platform_device *pdev = NULL; - void *dram_start; - int dram_size; - const char *wrn = ", rate setting disabled.\n"; - - switch (rtcl_ccu->soc) { - case SOC_RTL838X: - dram_start = &rtcl_838x_dram_start; - dram_size = rtcl_838x_dram_size; - break; - case SOC_RTL839X: - dram_start = &rtcl_839x_dram_start; - dram_size = rtcl_839x_dram_size; - break; - default: - return -ENXIO; - } - - for_each_compatible_node(node, NULL, "mmio-sram") { - pdev = of_find_device_by_node(node); - if (pdev) { - of_node_put(node); - break; - } - } - - if (!pdev) { - dev_warn(&rtcl_ccu->pdev->dev, "no SRAM device found%s", wrn); - return -ENXIO; - } - - sram_pool = gen_pool_get(&pdev->dev, NULL); - if (!sram_pool) { - dev_warn(&rtcl_ccu->pdev->dev, "SRAM pool unavailable%s", wrn); - goto err_put_device; - } - - sram_vbase = gen_pool_alloc(sram_pool, dram_size); - if (!sram_vbase) { - dev_warn(&rtcl_ccu->pdev->dev, "can not allocate SRAM%s", wrn); - goto err_put_device; - } - - sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_vbase); - memcpy((void *)sram_pbase, dram_start, dram_size); - flush_icache_range((unsigned long)sram_pbase, (unsigned long)(sram_pbase + dram_size)); - - switch (rtcl_ccu->soc) { - case SOC_RTL838X: - RTCL_SRAM_FUNC(838x, sram_pbase, set_rate); - break; - case SOC_RTL839X: - RTCL_SRAM_FUNC(839x, sram_pbase, set_rate); - break; - } - - rtcl_ccu->sram.pmark = (int *)((void *)sram_pbase + (dram_size - 4)); - rtcl_ccu->sram.vbase = sram_vbase; - - return 0; - -err_put_device: - put_device(&pdev->dev); - - return -ENXIO; -} - -void rtcl_ccu_log_early(void) -{ - char meminfo[80], clkinfo[255], msg[255] = "rtl83xx-clk: initialized"; - - sprintf(meminfo, " (%d Bit DDR%d)", rtcl_ccu->dram.buswidth, rtcl_ccu->dram.type); - for (int clk_idx = 0; clk_idx < CLK_COUNT; clk_idx++) { - sprintf(clkinfo, ", %s %lu MHz", rtcl_clk_info[clk_idx].display_name, - rtcl_ccu->clks[clk_idx].startup / 1000000); - if (clk_idx == CLK_MEM) - strcat(clkinfo, meminfo); - strcat(msg, clkinfo); - } - pr_info("%s\n", msg); -} - -void rtcl_ccu_log_late(void) -{ - struct rtcl_clk *rclk; - bool overclock = false; - char clkinfo[80], msg[255] = "rate setting enabled"; - - for (int clk_idx = 0; clk_idx < CLK_COUNT; clk_idx++) { - rclk = &rtcl_ccu->clks[clk_idx]; - overclock |= rclk->max > rclk->startup; - sprintf(clkinfo, ", %s %lu-%lu MHz", rtcl_clk_info[clk_idx].display_name, - rclk->min / 1000000, rclk->max / 1000000); - strcat(msg, clkinfo); - } - if (overclock) - strcat(msg, ", OVERCLOCK AT OWN RISK"); - - dev_info(&rtcl_ccu->pdev->dev, "%s\n", msg); -} - -/* - * Early registration: This module provides core startup clocks that are needed - * for generic SOC init and for further builtin devices (e.g. UART). Register - * asap via clock framework. - */ - -static void __init rtcl_probe_early(struct device_node *np) -{ - if (rtcl_ccu_create(np)) - return; - - if (rtcl_ccu_register_clocks()) - kfree(rtcl_ccu); - else - rtcl_ccu_log_early(); -} - -CLK_OF_DECLARE_DRIVER(rtl838x_clk, "realtek,rtl8380-clock", rtcl_probe_early); -CLK_OF_DECLARE_DRIVER(rtl839x_clk, "realtek,rtl8390-clock", rtcl_probe_early); - -/* - * Late registration: Finally register as normal platform driver. At this point - * we can make use of other modules like SRAM. - */ - -static const struct of_device_id rtcl_dt_ids[] = { - { .compatible = "realtek,rtl8380-clock" }, - { .compatible = "realtek,rtl8390-clock" }, - {} -}; - -static int rtcl_probe_late(struct platform_device *pdev) -{ - int ret; - - if (!rtcl_ccu) { - dev_err(&pdev->dev, "early initialization not run"); - return -ENXIO; - } - rtcl_ccu->pdev = pdev; - ret = rtcl_init_sram(); - if (ret) - return ret; - - rtcl_ccu_log_late(); - - return 0; -} - -static struct platform_driver rtcl_platform_driver = { - .driver = { - .name = "rtl83xx-clk", - .of_match_table = rtcl_dt_ids, - }, - .probe = rtcl_probe_late, -}; - -static int __init rtcl_init_subsys(void) -{ - return platform_driver_register(&rtcl_platform_driver); -} - -/* - * The driver does not know when SRAM module has finally loaded. With an - * arch_initcall() we might overtake SRAM initialization. Be polite and give the - * system a little more time. - */ - -subsys_initcall(rtcl_init_subsys); diff --git a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.h b/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.h deleted file mode 100644 index a69b16b475eb0d..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/clk/realtek/clk-rtl83xx.h +++ /dev/null @@ -1,75 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Realtek RTL83XX clock headers - * Copyright (C) 2022 Markus Stockhausen - */ - -/* - * Switch registers (e.g. PLL) - */ - -#define RTL_SW_CORE_BASE (0xbb000000) - -#define RTL838X_PLL_GLB_CTRL (0x0fc0) -#define RTL838X_PLL_CPU_CTRL0 (0x0fc4) -#define RTL838X_PLL_CPU_CTRL1 (0x0fc8) -#define RTL838X_PLL_LXB_CTRL0 (0x0fd0) -#define RTL838X_PLL_LXB_CTRL1 (0x0fd4) -#define RTL838X_PLL_MEM_CTRL0 (0x0fdc) -#define RTL838X_PLL_MEM_CTRL1 (0x0fe0) - -#define RTL839X_PLL_GLB_CTRL (0x0024) -#define RTL839X_PLL_CPU_CTRL0 (0x0028) -#define RTL839X_PLL_CPU_CTRL1 (0x002c) -#define RTL839X_PLL_LXB_CTRL0 (0x0038) -#define RTL839X_PLL_LXB_CTRL1 (0x003c) -#define RTL839X_PLL_MEM_CTRL0 (0x0048) -#define RTL839X_PLL_MEM_CTRL1 (0x004c) - -#define RTL_PLL_CTRL0_CMU_SEL_PREDIV(v) (((v) >> 0) & 0x3) -#define RTL_PLL_CTRL0_CMU_SEL_DIV4(v) (((v) >> 2) & 0x1) -#define RTL_PLL_CTRL0_CMU_NCODE_IN(v) (((v) >> 4) & 0xff) -#define RTL_PLL_CTRL0_CMU_DIVN2(v) (((v) >> 12) & 0xff) - -#define RTL838X_GLB_CTRL_EN_CPU_PLL_MASK (1 << 0) -#define RTL838X_GLB_CTRL_EN_LXB_PLL_MASK (1 << 1) -#define RTL838X_GLB_CTRL_EN_MEM_PLL_MASK (1 << 2) -#define RTL838X_GLB_CTRL_CPU_PLL_READY_MASK (1 << 8) -#define RTL838X_GLB_CTRL_LXB_PLL_READY_MASK (1 << 9) -#define RTL838X_GLB_CTRL_MEM_PLL_READY_MASK (1 << 10) -#define RTL838X_GLB_CTRL_CPU_PLL_SC_MUX_MASK (1 << 12) - -#define RTL838X_PLL_CTRL1_CMU_DIVN2_SELB(v) (((v) >> 26) & 0x1) -#define RTL838X_PLL_CTRL1_CMU_DIVN3_SEL(v) (((v) >> 27) & 0x3) - -#define RTL839X_GLB_CTRL_CPU_CLKSEL_MASK (1 << 11) -#define RTL839X_GLB_CTRL_MEM_CLKSEL_MASK (1 << 12) -#define RTL839X_GLB_CTRL_LXB_CLKSEL_MASK (1 << 13) - -#define RTL839X_PLL_CTRL1_CMU_DIVN2_SELB(v) (((v) >> 2) & 0x1) -#define RTL839X_PLL_CTRL1_CMU_DIVN3_SEL(v) (((v) >> 0) & 0x3) - -/* - * Core registers (e.g. memory controller) - */ - -#define RTL_SOC_BASE (0xB8000000) - -#define RTL_MC_MCR (0x1000) -#define RTL_MC_DCR (0x1004) -#define RTL_MC_DTR0 (0x1008) -#define RTL_MC_DTR1 (0x100c) -#define RTL_MC_DTR2 (0x1010) -#define RTL_MC_DMCR (0x101c) -#define RTL_MC_DACCR (0x1500) -#define RTL_MC_DCDR (0x1060) - -#define RTL_MC_MCR_DRAMTYPE(v) ((((v) >> 28) & 0xf) + 1) -#define RTL_MC_DCR_BUSWIDTH(v) (8 << (((v) >> 24) & 0xf)) - -/* - * Other stuff - */ - -#define RTL_SRAM_MARKER (0x5eaf00d5) -#define RTL_SRAM_BASE (0x9f000000) diff --git a/target/linux/realtek/files-5.15/drivers/clocksource/timer-rtl-otto.c b/target/linux/realtek/files-5.15/drivers/clocksource/timer-rtl-otto.c deleted file mode 100644 index 086f62112aec32..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/clocksource/timer-rtl-otto.c +++ /dev/null @@ -1,286 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include - -#include "timer-of.h" - -#define RTTM_DATA 0x0 -#define RTTM_CNT 0x4 -#define RTTM_CTRL 0x8 -#define RTTM_INT 0xc - -#define RTTM_CTRL_ENABLE BIT(28) -#define RTTM_INT_PENDING BIT(16) -#define RTTM_INT_ENABLE BIT(20) - -/* - * The Otto platform provides multiple 28 bit timers/counters with the following - * operating logic. If enabled the timer counts up. Per timer one can set a - * maximum counter value as an end marker. If end marker is reached the timer - * fires an interrupt. If the timer "overflows" by reaching the end marker or - * by adding 1 to 0x0fffffff the counter is reset to 0. When this happens and - * the timer is in operating mode COUNTER it stops. In mode TIMER it will - * continue to count up. - */ -#define RTTM_CTRL_COUNTER 0 -#define RTTM_CTRL_TIMER BIT(24) - -#define RTTM_BIT_COUNT 28 -#define RTTM_MIN_DELTA 8 -#define RTTM_MAX_DELTA CLOCKSOURCE_MASK(28) - -/* - * Timers are derived from the LXB clock frequency. Usually this is a fixed - * multiple of the 25 MHz oscillator. The 930X SOC is an exception from that. - * Its LXB clock has only dividers and uses the switch PLL of 2.45 GHz as its - * base. The only meaningful frequencies we can achieve from that are 175.000 - * MHz and 153.125 MHz. The greatest common divisor of all explained possible - * speeds is 3125000. Pin the timers to this 3.125 MHz reference frequency. - */ -#define RTTM_TICKS_PER_SEC 3125000 - -struct rttm_cs { - struct timer_of to; - struct clocksource cs; -}; - -/* Simple internal register functions */ -static inline void rttm_set_counter(void __iomem *base, unsigned int counter) -{ - iowrite32(counter, base + RTTM_CNT); -} - -static inline unsigned int rttm_get_counter(void __iomem *base) -{ - return ioread32(base + RTTM_CNT); -} - -static inline void rttm_set_period(void __iomem *base, unsigned int period) -{ - iowrite32(period, base + RTTM_DATA); -} - -static inline void rttm_disable_timer(void __iomem *base) -{ - iowrite32(0, base + RTTM_CTRL); -} - -static inline void rttm_enable_timer(void __iomem *base, u32 mode, u32 divisor) -{ - iowrite32(RTTM_CTRL_ENABLE | mode | divisor, base + RTTM_CTRL); -} - -static inline void rttm_ack_irq(void __iomem *base) -{ - iowrite32(ioread32(base + RTTM_INT) | RTTM_INT_PENDING, base + RTTM_INT); -} - -static inline void rttm_enable_irq(void __iomem *base) -{ - iowrite32(RTTM_INT_ENABLE, base + RTTM_INT); -} - -static inline void rttm_disable_irq(void __iomem *base) -{ - iowrite32(0, base + RTTM_INT); -} - -/* Aggregated control functions for kernel clock framework */ -#define RTTM_DEBUG(base) \ - pr_debug("------------- %s %d %08x\n", __func__, \ - smp_processor_id(), (u32)base) - -static irqreturn_t rttm_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *clkevt = dev_id; - struct timer_of *to = to_timer_of(clkevt); - - rttm_ack_irq(to->of_base.base); - RTTM_DEBUG(to->of_base.base); - clkevt->event_handler(clkevt); - - return IRQ_HANDLED; -} - -static void rttm_stop_timer(void __iomem *base) -{ - rttm_disable_timer(base); - rttm_ack_irq(base); -} - -static void rttm_start_timer(struct timer_of *to, u32 mode) -{ - rttm_set_counter(to->of_base.base, 0); - rttm_enable_timer(to->of_base.base, mode, to->of_clk.rate / RTTM_TICKS_PER_SEC); -} - -static int rttm_next_event(unsigned long delta, struct clock_event_device *clkevt) -{ - struct timer_of *to = to_timer_of(clkevt); - - RTTM_DEBUG(to->of_base.base); - rttm_stop_timer(to->of_base.base); - rttm_set_period(to->of_base.base, delta); - rttm_start_timer(to, RTTM_CTRL_COUNTER); - - return 0; -} - -static int rttm_state_oneshot(struct clock_event_device *clkevt) -{ - struct timer_of *to = to_timer_of(clkevt); - - RTTM_DEBUG(to->of_base.base); - rttm_stop_timer(to->of_base.base); - rttm_set_period(to->of_base.base, RTTM_TICKS_PER_SEC / HZ); - rttm_start_timer(to, RTTM_CTRL_COUNTER); - - return 0; -} - -static int rttm_state_periodic(struct clock_event_device *clkevt) -{ - struct timer_of *to = to_timer_of(clkevt); - - RTTM_DEBUG(to->of_base.base); - rttm_stop_timer(to->of_base.base); - rttm_set_period(to->of_base.base, RTTM_TICKS_PER_SEC / HZ); - rttm_start_timer(to, RTTM_CTRL_TIMER); - - return 0; -} - -static int rttm_state_shutdown(struct clock_event_device *clkevt) -{ - struct timer_of *to = to_timer_of(clkevt); - - RTTM_DEBUG(to->of_base.base); - rttm_stop_timer(to->of_base.base); - - return 0; -} - -static void rttm_setup_timer(void __iomem *base) -{ - RTTM_DEBUG(base); - rttm_stop_timer(base); - rttm_set_period(base, 0); -} - -static u64 rttm_read_clocksource(struct clocksource *cs) -{ - struct rttm_cs *rcs = container_of(cs, struct rttm_cs, cs); - - return (u64)rttm_get_counter(rcs->to.of_base.base); -} - -/* Module initialization part. */ -static DEFINE_PER_CPU(struct timer_of, rttm_to) = { - .flags = TIMER_OF_BASE | TIMER_OF_CLOCK | TIMER_OF_IRQ, - .of_irq = { - .flags = IRQF_PERCPU | IRQF_TIMER, - .handler = rttm_timer_interrupt, - }, - .clkevt = { - .rating = 400, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_state_periodic = rttm_state_periodic, - .set_state_shutdown = rttm_state_shutdown, - .set_state_oneshot = rttm_state_oneshot, - .set_next_event = rttm_next_event - }, -}; - -static int rttm_enable_clocksource(struct clocksource *cs) -{ - struct rttm_cs *rcs = container_of(cs, struct rttm_cs, cs); - - rttm_disable_irq(rcs->to.of_base.base); - rttm_setup_timer(rcs->to.of_base.base); - rttm_enable_timer(rcs->to.of_base.base, RTTM_CTRL_TIMER, - rcs->to.of_clk.rate / RTTM_TICKS_PER_SEC); - - return 0; -} - -struct rttm_cs rttm_cs = { - .to = { - .flags = TIMER_OF_BASE | TIMER_OF_CLOCK, - }, - .cs = { - .name = "realtek_otto_timer", - .rating = 400, - .mask = CLOCKSOURCE_MASK(RTTM_BIT_COUNT), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, - .read = rttm_read_clocksource, - } -}; - -static u64 notrace rttm_read_clock(void) -{ - return (u64)rttm_get_counter(rttm_cs.to.of_base.base); -} - -static int rttm_cpu_starting(unsigned int cpu) -{ - struct timer_of *to = per_cpu_ptr(&rttm_to, cpu); - - RTTM_DEBUG(to->of_base.base); - to->clkevt.cpumask = cpumask_of(cpu); - irq_force_affinity(to->of_irq.irq, to->clkevt.cpumask); - clockevents_config_and_register(&to->clkevt, RTTM_TICKS_PER_SEC, - RTTM_MIN_DELTA, RTTM_MAX_DELTA); - rttm_enable_irq(to->of_base.base); - - return 0; -} - -static int __init rttm_probe(struct device_node *np) -{ - int cpu, cpu_rollback; - struct timer_of *to; - int clkidx = num_possible_cpus(); - - /* Use the first n timers as per CPU clock event generators */ - for_each_possible_cpu(cpu) { - to = per_cpu_ptr(&rttm_to, cpu); - to->of_irq.index = to->of_base.index = cpu; - if (timer_of_init(np, to)) { - pr_err("%s: setup of timer %d failed\n", __func__, cpu); - goto rollback; - } - rttm_setup_timer(to->of_base.base); - } - - /* Activate the n'th + 1 timer as a stable CPU clocksource. */ - to = &rttm_cs.to; - to->of_base.index = clkidx; - timer_of_init(np, to); - if (rttm_cs.to.of_base.base && rttm_cs.to.of_clk.rate) { - rttm_enable_clocksource(&rttm_cs.cs); - clocksource_register_hz(&rttm_cs.cs, RTTM_TICKS_PER_SEC); - sched_clock_register(rttm_read_clock, RTTM_BIT_COUNT, RTTM_TICKS_PER_SEC); - } else - pr_err("%s: setup of timer %d as clocksoure failed", __func__, clkidx); - - return cpuhp_setup_state(CPUHP_AP_REALTEK_TIMER_STARTING, - "timer/realtek:online", - rttm_cpu_starting, NULL); -rollback: - pr_err("%s: timer registration failed\n", __func__); - for_each_possible_cpu(cpu_rollback) { - if (cpu_rollback == cpu) - break; - to = per_cpu_ptr(&rttm_to, cpu_rollback); - timer_of_cleanup(to); - } - - return -EINVAL; -} - -TIMER_OF_DECLARE(otto_timer, "realtek,otto-timer", rttm_probe); diff --git a/target/linux/realtek/files-5.15/drivers/gpio/gpio-rtl8231.c b/target/linux/realtek/files-5.15/drivers/gpio/gpio-rtl8231.c deleted file mode 100644 index 2821591a97ed9d..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/gpio/gpio-rtl8231.c +++ /dev/null @@ -1,364 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include -#include -#include - -/* RTL8231 registers for LED control */ -#define RTL8231_LED_FUNC0 0x0000 -#define RTL8231_LED_FUNC1 0x0001 -#define RTL8231_READY_MASK 0x03f0 -#define RTL8231_READY_VALUE 0x0370 -#define RTL8231_GPIO_PIN_SEL(gpio) ((0x0002) + ((gpio) >> 4)) -#define RTL8231_GPIO_DIR(gpio) ((0x0005) + ((gpio) >> 4)) -#define RTL8231_GPIO_DATA(gpio) ((0x001C) + ((gpio) >> 4)) - -#define USEC_TIMEOUT 5000 - -#define RTL8231_SMI_BUS_ID_MAX 0x1F - -struct rtl8231_gpios { - struct gpio_chip gc; - struct device *dev; - u32 id; - u32 smi_bus_id; - u16 reg_shadow[0x20]; - u32 reg_cached; - int ext_gpio_indrt_access; -}; - -extern struct rtl83xx_soc_info soc_info; - -DEFINE_MUTEX(miim_lock); - -static u32 rtl8231_read(struct rtl8231_gpios *gpios, u32 reg) -{ - u32 t = 0, n = 0; - - reg &= 0x1f; - - /* Calculate read register address */ - t = (gpios->smi_bus_id << 2) | (reg << 7); - - /* Set execution bit: cleared when operation completed */ - t |= 1; - - /* Start execution */ - sw_w32(t, gpios->ext_gpio_indrt_access); - do { - udelay(1); - t = sw_r32(gpios->ext_gpio_indrt_access); - n++; - } while ((t & 1) && (n < USEC_TIMEOUT)); - - if (n >= USEC_TIMEOUT) - return 0x80000000; - - pr_debug("%s: %x, %x, %x\n", __func__, gpios->smi_bus_id, - reg, (t & 0xffff0000) >> 16); - - return (t & 0xffff0000) >> 16; -} - -static int rtl8231_write(struct rtl8231_gpios *gpios, u32 reg, u32 data) -{ - u32 t = 0, n = 0; - - pr_debug("%s: %x, %x, %x\n", __func__, gpios->smi_bus_id, reg, data); - reg &= 0x1f; - - t = (gpios->smi_bus_id << 2) | (reg << 7) | (data << 16); - /* Set write bit */ - t |= 2; - - /* Set execution bit: cleared when operation completed */ - t |= 1; - - /* Start execution */ - sw_w32(t, gpios->ext_gpio_indrt_access); - do { - udelay(1); - t = sw_r32(gpios->ext_gpio_indrt_access); - } while ((t & 1) && (n < USEC_TIMEOUT)); - - if (n >= USEC_TIMEOUT) - return -1; - - return 0; -} - -static u32 rtl8231_read_cached(struct rtl8231_gpios *gpios, u32 reg) -{ - if (reg > 0x1f) - return 0; - - if (gpios->reg_cached & (1 << reg)) - return gpios->reg_shadow[reg]; - - return rtl8231_read(gpios, reg); -} - -/* Set Direction of the RTL8231 pin: - * dir 1: input - * dir 0: output - */ -static int rtl8231_pin_dir(struct rtl8231_gpios *gpios, u32 gpio, u32 dir) -{ - u32 v; - int pin_sel_addr = RTL8231_GPIO_PIN_SEL(gpio); - int pin_dir_addr = RTL8231_GPIO_DIR(gpio); - int dpin = gpio % 16; - - if (gpio > 31) { - pr_debug("WARNING: HIGH pin\n"); - dpin += 5; - pin_dir_addr = pin_sel_addr; - } - - v = rtl8231_read_cached(gpios, pin_dir_addr); - if (v & 0x80000000) { - pr_err("Error reading RTL8231\n"); - return -1; - } - - v = (v & ~(1 << dpin)) | (dir << dpin); - rtl8231_write(gpios, pin_dir_addr, v); - gpios->reg_shadow[pin_dir_addr] = v; - gpios->reg_cached |= 1 << pin_dir_addr; - - return 0; -} - -static int rtl8231_pin_dir_get(struct rtl8231_gpios *gpios, u32 gpio, u32 *dir) -{ - /* dir 1: input - * dir 0: output - */ - - u32 v; - int pin_dir_addr = RTL8231_GPIO_DIR(gpio); - int pin = gpio % 16; - - if (gpio > 31) { - pin_dir_addr = RTL8231_GPIO_PIN_SEL(gpio); - pin += 5; - } - - v = rtl8231_read(gpios, pin_dir_addr); - if (v & (1 << pin)) - *dir = 1; - else - *dir = 0; - - return 0; -} - -static int rtl8231_pin_set(struct rtl8231_gpios *gpios, u32 gpio, u32 data) -{ - u32 v = rtl8231_read(gpios, RTL8231_GPIO_DATA(gpio)); - - pr_debug("%s: %d to %d\n", __func__, gpio, data); - if (v & 0x80000000) { - pr_err("Error reading RTL8231\n"); - return -1; - } - v = (v & ~(1 << (gpio % 16))) | (data << (gpio % 16)); - rtl8231_write(gpios, RTL8231_GPIO_DATA(gpio), v); - gpios->reg_shadow[RTL8231_GPIO_DATA(gpio)] = v; - gpios->reg_cached |= 1 << RTL8231_GPIO_DATA(gpio); - - return 0; -} - -static int rtl8231_pin_get(struct rtl8231_gpios *gpios, u32 gpio, u16 *state) -{ - u32 v = rtl8231_read(gpios, RTL8231_GPIO_DATA(gpio)); - - if (v & 0x80000000) { - pr_err("Error reading RTL8231\n"); - return -1; - } - - *state = v & 0xffff; - - return 0; -} - -static int rtl8231_direction_input(struct gpio_chip *gc, unsigned int offset) -{ - int err; - struct rtl8231_gpios *gpios = gpiochip_get_data(gc); - - pr_debug("%s: %d\n", __func__, offset); - mutex_lock(&miim_lock); - err = rtl8231_pin_dir(gpios, offset, 1); - mutex_unlock(&miim_lock); - - return err; -} - -static int rtl8231_direction_output(struct gpio_chip *gc, unsigned int offset, int value) -{ - int err; - struct rtl8231_gpios *gpios = gpiochip_get_data(gc); - - pr_debug("%s: %d\n", __func__, offset); - mutex_lock(&miim_lock); - err = rtl8231_pin_dir(gpios, offset, 0); - mutex_unlock(&miim_lock); - - if (!err) - err = rtl8231_pin_set(gpios, offset, value); - - return err; -} - -static int rtl8231_get_direction(struct gpio_chip *gc, unsigned int offset) -{ - u32 v = 0; - struct rtl8231_gpios *gpios = gpiochip_get_data(gc); - - pr_debug("%s: %d\n", __func__, offset); - mutex_lock(&miim_lock); - rtl8231_pin_dir_get(gpios, offset, &v); - mutex_unlock(&miim_lock); - - return v; -} - -static int rtl8231_gpio_get(struct gpio_chip *gc, unsigned int offset) -{ - u16 state = 0; - struct rtl8231_gpios *gpios = gpiochip_get_data(gc); - - mutex_lock(&miim_lock); - rtl8231_pin_get(gpios, offset, &state); - mutex_unlock(&miim_lock); - - if (state & (1 << (offset % 16))) - return 1; - - return 0; -} - -void rtl8231_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) -{ - struct rtl8231_gpios *gpios = gpiochip_get_data(gc); - - rtl8231_pin_set(gpios, offset, value); -} - -int rtl8231_init(struct rtl8231_gpios *gpios) -{ - u32 ret; - - pr_info("%s called, MDIO bus ID: %d\n", __func__, gpios->smi_bus_id); - - gpios->reg_cached = 0; - - if (soc_info.family == RTL8390_FAMILY_ID) { - /* RTL8390: Enable external gpio in global led control register */ - sw_w32_mask(0x7 << 18, 0x4 << 18, RTL839X_LED_GLB_CTRL); - } else if (soc_info.family == RTL8380_FAMILY_ID) { - /* RTL8380: Enable RTL8231 indirect access mode */ - sw_w32_mask(0, 1, RTL838X_EXTRA_GPIO_CTRL); - sw_w32_mask(3, 1, RTL838X_DMY_REG5); - } - - ret = rtl8231_read(gpios, RTL8231_LED_FUNC1); - if ((ret & 0x80000000) || ((ret & RTL8231_READY_MASK) != RTL8231_READY_VALUE)) - return -ENXIO; - - /* Select GPIO functionality and force input direction for pins 0-36 */ - rtl8231_write(gpios, RTL8231_GPIO_PIN_SEL(0), 0xffff); - rtl8231_write(gpios, RTL8231_GPIO_DIR(0), 0xffff); - rtl8231_write(gpios, RTL8231_GPIO_PIN_SEL(16), 0xffff); - rtl8231_write(gpios, RTL8231_GPIO_DIR(16), 0xffff); - rtl8231_write(gpios, RTL8231_GPIO_PIN_SEL(32), 0x03ff); - - /* Set LED_Start to enable drivers for output mode */ - rtl8231_write(gpios, RTL8231_LED_FUNC0, 1 << 1); - - return 0; -} - -static const struct of_device_id rtl8231_gpio_of_match[] = { - { .compatible = "realtek,rtl8231-gpio" }, - {}, -}; - -MODULE_DEVICE_TABLE(of, rtl8231_gpio_of_match); - -static int rtl8231_gpio_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct rtl8231_gpios *gpios; - int err; - - pr_info("Probing RTL8231 GPIOs\n"); - - if (!np) { - dev_err(&pdev->dev, "No DT found\n"); - return -EINVAL; - } - - gpios = devm_kzalloc(dev, sizeof(*gpios), GFP_KERNEL); - if (!gpios) - return -ENOMEM; - - gpios->id = soc_info.id; - if (soc_info.family == RTL8380_FAMILY_ID) { - gpios->ext_gpio_indrt_access = RTL838X_EXT_GPIO_INDRT_ACCESS; - } - - if (soc_info.family == RTL8390_FAMILY_ID) { - gpios->ext_gpio_indrt_access = RTL839X_EXT_GPIO_INDRT_ACCESS; - } - - err = of_property_read_u32(np, "indirect-access-bus-id", &gpios->smi_bus_id); - if (!err && gpios->smi_bus_id > RTL8231_SMI_BUS_ID_MAX) - err = -EINVAL; - - if (err) { - dev_err(dev, "invalid or missing indirect-access-bus-id\n"); - return err; - } - - err = rtl8231_init(gpios); - if (err) { - dev_err(dev, "no device found at bus address %d\n", gpios->smi_bus_id); - return err; - } - - gpios->dev = dev; - gpios->gc.base = -1; - gpios->gc.ngpio = 37; - gpios->gc.label = "rtl8231"; - gpios->gc.parent = dev; - gpios->gc.owner = THIS_MODULE; - gpios->gc.can_sleep = true; - - gpios->gc.direction_input = rtl8231_direction_input; - gpios->gc.direction_output = rtl8231_direction_output; - gpios->gc.set = rtl8231_gpio_set; - gpios->gc.get = rtl8231_gpio_get; - gpios->gc.get_direction = rtl8231_get_direction; - - return devm_gpiochip_add_data(dev, &gpios->gc, gpios); -} - -static struct platform_driver rtl8231_gpio_driver = { - .driver = { - .name = "rtl8231-gpio", - .of_match_table = rtl8231_gpio_of_match, - }, - .probe = rtl8231_gpio_probe, -}; - -module_platform_driver(rtl8231_gpio_driver); - -MODULE_DESCRIPTION("Realtek RTL8231 GPIO expansion chip support"); -MODULE_LICENSE("GPL v2"); diff --git a/target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.c b/target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.c deleted file mode 100644 index 54d916d17a923c..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.c +++ /dev/null @@ -1,486 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include "i2c-rtl9300.h" - -#define REG(i, x) (i->base + x + (i->scl_num ? i->mst2_offset : 0)) -#define REG_MASK(i, clear, set, reg) \ - writel((readl(REG(i, reg)) & ~(clear)) | (set), REG(i, reg)) - -struct i2c_drv_data { - int scl0_pin; - int scl1_pin; - int sda0_pin; - struct i2c_algorithm *algo; - int (*read)(struct rtl9300_i2c *i2c, u8 *buf, int len); - int (*write)(struct rtl9300_i2c *i2c, u8 *buf, int len); - void (*reg_addr_set)(struct rtl9300_i2c *i2c, u32 reg, u16 len); - int (*config_xfer)(struct rtl9300_i2c *i2c, u16 addr, u16 len); - int (*execute_xfer)(struct rtl9300_i2c *i2c, char read_write, int size, - union i2c_smbus_data * data, int len); - void (*writel)(struct rtl9300_i2c *i2c, u32 data); - void (*config_io)(struct rtl9300_i2c *i2c, int scl_num, int sda_num); - u32 mst2_offset; -}; - -DEFINE_MUTEX(i2c_lock); - -static void rtl9300_i2c_reg_addr_set(struct rtl9300_i2c *i2c, u32 reg, u16 len) -{ - /* Set register address width */ - REG_MASK(i2c, 0x3 << RTL9300_I2C_CTRL2_MADDR_WIDTH, len << RTL9300_I2C_CTRL2_MADDR_WIDTH, - RTL9300_I2C_CTRL2); - - /* Set register address */ - REG_MASK(i2c, 0xffffff << RTL9300_I2C_CTRL1_MEM_ADDR, reg << RTL9300_I2C_CTRL1_MEM_ADDR, - RTL9300_I2C_CTRL1); -} - -static void rtl9310_i2c_reg_addr_set(struct rtl9300_i2c *i2c, u32 reg, u16 len) -{ - /* Set register address width */ - REG_MASK(i2c, 0x3 << RTL9310_I2C_CTRL_MADDR_WIDTH, len << RTL9310_I2C_CTRL_MADDR_WIDTH, - RTL9310_I2C_CTRL); - - /* Set register address */ - writel(reg, REG(i2c, RTL9310_I2C_MEMADDR)); -} - -static void rtl9300_i2c_config_io(struct rtl9300_i2c *i2c, int scl_num, int sda_num) -{ - u32 v; - - /* Set SCL pin */ - REG_MASK(i2c, 0, BIT(RTL9300_I2C_CTRL1_GPIO8_SCL_SEL), RTL9300_I2C_CTRL1); - - /* Set SDA pin */ - REG_MASK(i2c, 0x7 << RTL9300_I2C_CTRL1_SDA_OUT_SEL, - i2c->sda_num << RTL9300_I2C_CTRL1_SDA_OUT_SEL, RTL9300_I2C_CTRL1); - - /* Set SDA pin to I2C functionality */ - v = readl(i2c->base + RTL9300_I2C_MST_GLB_CTRL); - v |= BIT(i2c->sda_num); - writel(v, i2c->base + RTL9300_I2C_MST_GLB_CTRL); -} - -static void rtl9310_i2c_config_io(struct rtl9300_i2c *i2c, int scl_num, int sda_num) -{ - u32 v; - - /* Set SCL pin */ - REG_MASK(i2c, 0, BIT(RTL9310_I2C_MST_IF_SEL_GPIO_SCL_SEL + scl_num), RTL9310_I2C_MST_IF_SEL); - - /* Set SDA pin */ - REG_MASK(i2c, 0x7 << RTL9310_I2C_CTRL_SDA_OUT_SEL, - i2c->sda_num << RTL9310_I2C_CTRL_SDA_OUT_SEL, RTL9310_I2C_CTRL); - - /* Set SDA pin to I2C functionality */ - v = readl(i2c->base + RTL9310_I2C_MST_IF_SEL); - v |= BIT(i2c->sda_num); - writel(v, i2c->base + RTL9310_I2C_MST_IF_SEL); -} - -static int rtl9300_i2c_config_xfer(struct rtl9300_i2c *i2c, u16 addr, u16 len) -{ - /* Set bus frequency */ - REG_MASK(i2c, 0x3 << RTL9300_I2C_CTRL2_SCL_FREQ, - i2c->bus_freq << RTL9300_I2C_CTRL2_SCL_FREQ, RTL9300_I2C_CTRL2); - - /* Set slave device address */ - REG_MASK(i2c, 0x7f << RTL9300_I2C_CTRL2_DEV_ADDR, - addr << RTL9300_I2C_CTRL2_DEV_ADDR, RTL9300_I2C_CTRL2); - - /* Set data length */ - REG_MASK(i2c, 0xf << RTL9300_I2C_CTRL2_DATA_WIDTH, - ((len - 1) & 0xf) << RTL9300_I2C_CTRL2_DATA_WIDTH, RTL9300_I2C_CTRL2); - - /* Set read mode to random */ - REG_MASK(i2c, 0x1 << RTL9300_I2C_CTRL2_READ_MODE, 0, RTL9300_I2C_CTRL2); - - return 0; -} - -static int rtl9310_i2c_config_xfer(struct rtl9300_i2c *i2c, u16 addr, u16 len) -{ - /* Set bus frequency */ - REG_MASK(i2c, 0x3 << RTL9310_I2C_CTRL_SCL_FREQ, - i2c->bus_freq << RTL9310_I2C_CTRL_SCL_FREQ, RTL9310_I2C_CTRL); - - /* Set slave device address */ - REG_MASK(i2c, 0x7f << RTL9310_I2C_CTRL_DEV_ADDR, - addr << RTL9310_I2C_CTRL_DEV_ADDR, RTL9310_I2C_CTRL); - - /* Set data length */ - REG_MASK(i2c, 0xf << RTL9310_I2C_CTRL_DATA_WIDTH, - ((len - 1) & 0xf) << RTL9310_I2C_CTRL_DATA_WIDTH, RTL9310_I2C_CTRL); - - /* Set read mode to random */ - REG_MASK(i2c, 0x1 << RTL9310_I2C_CTRL_READ_MODE, 0, RTL9310_I2C_CTRL); - - return 0; -} - -static int i2c_read(void __iomem *r0, u8 *buf, int len) -{ - if (len > 16) - return -EIO; - - for (int i = 0; i < len; i++) { - u32 v; - - if (i % 4 == 0) - v = readl(r0 + i); - buf[i] = v; - v >>= 8; - } - - return len; -} - -static int i2c_write(void __iomem *r0, u8 *buf, int len) -{ - if (len > 16) - return -EIO; - - for (int i = 0; i < len; i++) { - u32 v; - - if (! (i % 4)) - v = 0; - v <<= 8; - v |= buf[i]; - if (i % 4 == 3 || i == len - 1) - writel(v, r0 + (i / 4) * 4); - } - - return len; -} - -static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, int len) -{ - return i2c_read(REG(i2c, RTL9300_I2C_DATA_WORD0), buf, len); -} - -static int rtl9300_i2c_write(struct rtl9300_i2c *i2c, u8 *buf, int len) -{ - return i2c_write(REG(i2c, RTL9300_I2C_DATA_WORD0), buf, len); -} - -static int rtl9310_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, int len) -{ - return i2c_read(REG(i2c, RTL9310_I2C_DATA), buf, len); -} - -static int rtl9310_i2c_write(struct rtl9300_i2c *i2c, u8 *buf, int len) -{ - return i2c_write(REG(i2c, RTL9310_I2C_DATA), buf, len); -} - -static void rtl9300_writel(struct rtl9300_i2c *i2c, u32 data) -{ - writel(data, REG(i2c, RTL9300_I2C_DATA_WORD0)); -} - -static void rtl9310_writel(struct rtl9300_i2c *i2c, u32 data) -{ - writel(data, REG(i2c, RTL9310_I2C_DATA)); -} - - -static int rtl9300_execute_xfer(struct rtl9300_i2c *i2c, char read_write, - int size, union i2c_smbus_data * data, int len) -{ - u32 v; - - if (read_write == I2C_SMBUS_READ) - REG_MASK(i2c, BIT(RTL9300_I2C_CTRL1_RWOP), 0, RTL9300_I2C_CTRL1); - else - REG_MASK(i2c, 0, BIT(RTL9300_I2C_CTRL1_RWOP), RTL9300_I2C_CTRL1); - - REG_MASK(i2c, 0, BIT(RTL9300_I2C_CTRL1_I2C_TRIG), RTL9300_I2C_CTRL1); - do { - v = readl(REG(i2c, RTL9300_I2C_CTRL1)); - } while (v & BIT(RTL9300_I2C_CTRL1_I2C_TRIG)); - - if (v & BIT(RTL9300_I2C_CTRL1_I2C_FAIL)) - return -EIO; - - if (read_write == I2C_SMBUS_READ) { - if (size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA){ - data->byte = readl(REG(i2c, RTL9300_I2C_DATA_WORD0)); - } else if (size == I2C_SMBUS_WORD_DATA) { - data->word = readl(REG(i2c, RTL9300_I2C_DATA_WORD0)); - } else if (len > 0) { - rtl9300_i2c_read(i2c, &data->block[0], len); - } - } - - return 0; -} - -static int rtl9310_execute_xfer(struct rtl9300_i2c *i2c, char read_write, - int size, union i2c_smbus_data * data, int len) -{ - u32 v; - - if (read_write == I2C_SMBUS_READ) - REG_MASK(i2c, BIT(RTL9310_I2C_CTRL_RWOP), 0, RTL9310_I2C_CTRL); - else - REG_MASK(i2c, 0, BIT(RTL9310_I2C_CTRL_RWOP), RTL9310_I2C_CTRL); - - REG_MASK(i2c, 0, BIT(RTL9310_I2C_CTRL_I2C_TRIG), RTL9310_I2C_CTRL); - do { - v = readl(REG(i2c, RTL9310_I2C_CTRL)); - } while (v & BIT(RTL9310_I2C_CTRL_I2C_TRIG)); - - if (v & BIT(RTL9310_I2C_CTRL_I2C_FAIL)) - return -EIO; - - if (read_write == I2C_SMBUS_READ) { - if (size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA){ - data->byte = readl(REG(i2c, RTL9310_I2C_DATA)); - } else if (size == I2C_SMBUS_WORD_DATA) { - data->word = readl(REG(i2c, RTL9310_I2C_DATA)); - } else if (len > 0) { - rtl9310_i2c_read(i2c, &data->block[0], len); - } - } - - return 0; -} - -static int rtl9300_i2c_smbus_xfer(struct i2c_adapter * adap, u16 addr, - unsigned short flags, char read_write, - u8 command, int size, union i2c_smbus_data * data) -{ - struct rtl9300_i2c *i2c = i2c_get_adapdata(adap); - struct i2c_drv_data *drv_data = (struct i2c_drv_data *)device_get_match_data(i2c->dev); - int len = 0, ret; - - mutex_lock(&i2c_lock); - switch (size) { - case I2C_SMBUS_QUICK: - drv_data->config_xfer(i2c, addr, 0); - drv_data->reg_addr_set(i2c, 0, 0); - break; - - case I2C_SMBUS_BYTE: - if (read_write == I2C_SMBUS_WRITE) { - drv_data->config_xfer(i2c, addr, 0); - drv_data->reg_addr_set(i2c, command, 1); - } else { - drv_data->config_xfer(i2c, addr, 1); - drv_data->reg_addr_set(i2c, 0, 0); - } - break; - - case I2C_SMBUS_BYTE_DATA: - pr_debug("I2C_SMBUS_BYTE_DATA %02x, read %d cmd %02x\n", addr, read_write, command); - drv_data->reg_addr_set(i2c, command, 1); - drv_data->config_xfer(i2c, addr, 1); - - if (read_write == I2C_SMBUS_WRITE) { - pr_debug("--> data %02x\n", data->byte); - drv_data->writel(i2c, data->byte); - } - break; - - case I2C_SMBUS_WORD_DATA: - pr_debug("I2C_SMBUS_WORD %02x, read %d\n", addr, read_write); - drv_data->reg_addr_set(i2c, command, 1); - drv_data->config_xfer(i2c, addr, 2); - if (read_write == I2C_SMBUS_WRITE) - drv_data->writel(i2c, data->word); - break; - - case I2C_SMBUS_BLOCK_DATA: - pr_debug("I2C_SMBUS_BLOCK_DATA %02x, read %d, len %d\n", - addr, read_write, data->block[0]); - drv_data->reg_addr_set(i2c, command, 1); - drv_data->config_xfer(i2c, addr, data->block[0]); - if (read_write == I2C_SMBUS_WRITE) - drv_data->write(i2c, &data->block[1], data->block[0]); - len = data->block[0]; - break; - - default: - dev_warn(&adap->dev, "Unsupported transaction %d\n", size); - return -EOPNOTSUPP; - } - - ret = drv_data->execute_xfer(i2c, read_write, size, data, len); - - mutex_unlock(&i2c_lock); - - return ret; -} - -static u32 rtl9300_i2c_func(struct i2c_adapter *a) -{ - return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BLOCK_DATA; -} - -static const struct i2c_algorithm rtl9300_i2c_algo = { - .smbus_xfer = rtl9300_i2c_smbus_xfer, - .functionality = rtl9300_i2c_func, -}; - -struct i2c_adapter_quirks rtl9300_i2c_quirks = { - .flags = I2C_AQ_NO_CLK_STRETCH, - .max_read_len = 16, - .max_write_len = 16, -}; - -static int rtl9300_i2c_probe(struct platform_device *pdev) -{ - struct resource *res; - struct rtl9300_i2c *i2c; - struct i2c_adapter *adap; - struct i2c_drv_data *drv_data; - struct device_node *node = pdev->dev.of_node; - u32 clock_freq, pin; - int ret = 0; - - pr_info("%s probing I2C adapter\n", __func__); - - if (!node) { - dev_err(i2c->dev, "No DT found\n"); - return -EINVAL; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - drv_data = (struct i2c_drv_data *) device_get_match_data(&pdev->dev); - - i2c = devm_kzalloc(&pdev->dev, sizeof(struct rtl9300_i2c), GFP_KERNEL); - if (!i2c) - return -ENOMEM; - - i2c->base = devm_ioremap_resource(&pdev->dev, res); - i2c->mst2_offset = drv_data->mst2_offset; - if (IS_ERR(i2c->base)) - return PTR_ERR(i2c->base); - - pr_debug("%s base memory %08x\n", __func__, (u32)i2c->base); - i2c->dev = &pdev->dev; - - if (of_property_read_u32(node, "clock-frequency", &clock_freq)) { - clock_freq = I2C_MAX_STANDARD_MODE_FREQ; - } - switch(clock_freq) { - case I2C_MAX_STANDARD_MODE_FREQ: - i2c->bus_freq = RTL9300_I2C_STD_FREQ; - break; - - case I2C_MAX_FAST_MODE_FREQ: - i2c->bus_freq = RTL9300_I2C_FAST_FREQ; - break; - default: - dev_warn(i2c->dev, "clock-frequency %d not supported\n", clock_freq); - return -EINVAL; - } - - dev_info(&pdev->dev, "SCL speed %d, mode is %d\n", clock_freq, i2c->bus_freq); - - if (of_property_read_u32(node, "scl-pin", &pin)) { - dev_warn(i2c->dev, "SCL pin not found in DT, using default\n"); - pin = drv_data->scl0_pin; - } - if (!(pin == drv_data->scl0_pin || pin == drv_data->scl1_pin)) { - dev_warn(i2c->dev, "SCL pin %d not supported\n", pin); - return -EINVAL; - } - i2c->scl_num = pin == drv_data->scl0_pin ? 0 : 1; - pr_info("%s scl_num %d\n", __func__, i2c->scl_num); - - if (of_property_read_u32(node, "sda-pin", &pin)) { - dev_warn(i2c->dev, "SDA pin not found in DT, using default \n"); - pin = drv_data->sda0_pin; - } - i2c->sda_num = pin - drv_data->sda0_pin; - if (i2c->sda_num < 0 || i2c->sda_num > 7) { - dev_warn(i2c->dev, "SDA pin %d not supported\n", pin); - return -EINVAL; - } - pr_info("%s sda_num %d\n", __func__, i2c->sda_num); - - adap = &i2c->adap; - adap->owner = THIS_MODULE; - adap->algo = &rtl9300_i2c_algo; - adap->retries = 3; - adap->dev.parent = &pdev->dev; - i2c_set_adapdata(adap, i2c); - adap->dev.of_node = node; - strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); - - platform_set_drvdata(pdev, i2c); - - drv_data->config_io(i2c, i2c->scl_num, i2c->sda_num); - - ret = i2c_add_adapter(adap); - - return ret; -} - -static int rtl9300_i2c_remove(struct platform_device *pdev) -{ - struct rtl9300_i2c *i2c = platform_get_drvdata(pdev); - - i2c_del_adapter(&i2c->adap); - - return 0; -} - -struct i2c_drv_data rtl9300_i2c_drv_data = { - .scl0_pin = 8, - .scl1_pin = 17, - .sda0_pin = 9, - .read = rtl9300_i2c_read, - .read = rtl9300_i2c_write, - .reg_addr_set = rtl9300_i2c_reg_addr_set, - .config_xfer = rtl9300_i2c_config_xfer, - .execute_xfer = rtl9300_execute_xfer, - .writel = rtl9300_writel, - .config_io = rtl9300_i2c_config_io, - .mst2_offset = 0x1c, -}; - -struct i2c_drv_data rtl9310_i2c_drv_data = { - .scl0_pin = 13, - .scl1_pin = 14, - .sda0_pin = 0, - .read = rtl9310_i2c_read, - .read = rtl9310_i2c_write, - .reg_addr_set = rtl9310_i2c_reg_addr_set, - .config_xfer = rtl9310_i2c_config_xfer, - .execute_xfer = rtl9310_execute_xfer, - .writel = rtl9310_writel, - .config_io = rtl9310_i2c_config_io, - .mst2_offset = 0x18, -}; - -static const struct of_device_id i2c_rtl9300_dt_ids[] = { - { .compatible = "realtek,rtl9300-i2c", .data = (void *) &rtl9300_i2c_drv_data }, - { .compatible = "realtek,rtl9310-i2c", .data = (void *) &rtl9310_i2c_drv_data }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, rtl838x_eth_of_ids); - -static struct platform_driver rtl9300_i2c_driver = { - .probe = rtl9300_i2c_probe, - .remove = rtl9300_i2c_remove, - .driver = { - .name = "i2c-rtl9300", - .pm = NULL, - .of_match_table = i2c_rtl9300_dt_ids, - }, -}; - -module_platform_driver(rtl9300_i2c_driver); - -MODULE_AUTHOR("Birger Koblitz"); -MODULE_DESCRIPTION("RTL9300 I2C host driver"); -MODULE_LICENSE("GPL v2"); diff --git a/target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.h b/target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.h deleted file mode 100644 index 617a1b6632cf33..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef I2C_RTL9300_H -#define I2C_RTL9300_H - -#include - -#define RTL9300_I2C_CTRL1 0x00 -#define RTL9300_I2C_CTRL1_MEM_ADDR 8 -#define RTL9300_I2C_CTRL1_SDA_OUT_SEL 4 -#define RTL9300_I2C_CTRL1_GPIO8_SCL_SEL 3 -#define RTL9300_I2C_CTRL1_RWOP 2 -#define RTL9300_I2C_CTRL1_I2C_FAIL 1 -#define RTL9300_I2C_CTRL1_I2C_TRIG 0 - -#define RTL9300_I2C_CTRL2 0x04 -#define RTL9300_I2C_CTRL2_DRIVE_ACK_DELAY 20 -#define RTL9300_I2C_CTRL2_CHECK_ACK_DELAY 16 -#define RTL9300_I2C_CTRL2_READ_MODE 15 -#define RTL9300_I2C_CTRL2_DEV_ADDR 8 -#define RTL9300_I2C_CTRL2_DATA_WIDTH 4 -#define RTL9300_I2C_CTRL2_MADDR_WIDTH 2 -#define RTL9300_I2C_CTRL2_SCL_FREQ 0 - -#define RTL9300_I2C_DATA_WORD0 0x08 - -#define RTL9300_I2C_MST_GLB_CTRL 0x18 - -#define RTL9310_I2C_MST_IF_CTRL 0x00 - -#define RTL9310_I2C_MST_IF_SEL 0x04 -#define RTL9310_I2C_MST_IF_SEL_GPIO_SCL_SEL 12 - -#define RTL9310_I2C_CTRL 0x08 -#define RTL9310_I2C_CTRL_SCL_FREQ 30 -#define RTL9310_I2C_CTRL_CHECK_ACK_DELAY 26 -#define RTL9310_I2C_CTRL_DRIVE_ACK_DELAY 22 -#define RTL9310_I2C_CTRL_SDA_OUT_SEL 18 -#define RTL9310_I2C_CTRL_DEV_ADDR 11 -#define RTL9310_I2C_CTRL_MADDR_WIDTH 9 -#define RTL9310_I2C_CTRL_DATA_WIDTH 5 -#define RTL9310_I2C_CTRL_READ_MODE 4 -#define RTL9310_I2C_CTRL_RWOP 2 -#define RTL9310_I2C_CTRL_I2C_FAIL 1 -#define RTL9310_I2C_CTRL_I2C_TRIG 0 - -#define RTL9310_I2C_MEMADDR 0x0c - -#define RTL9310_I2C_DATA 0x10 - -#define RTL9300_I2C_STD_FREQ 0 -#define RTL9300_I2C_FAST_FREQ 1 - -struct rtl9300_i2c { - void __iomem *base; - u32 mst2_offset; - struct device *dev; - struct i2c_adapter adap; - u8 bus_freq; - u8 sda_num; /* SDA channel number */ - u8 scl_num; /* SCL channel, mapping to master 1 or 2 */ -}; - -#endif diff --git a/target/linux/realtek/files-5.15/drivers/i2c/muxes/i2c-mux-rtl9300.c b/target/linux/realtek/files-5.15/drivers/i2c/muxes/i2c-mux-rtl9300.c deleted file mode 100644 index 57036d9d566a31..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/i2c/muxes/i2c-mux-rtl9300.c +++ /dev/null @@ -1,293 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * I2C multiplexer for the 2 I2C Masters of the RTL9300 - * with up to 8 channels each, but which are not entirely - * independent of each other - */ -#include -#include -#include -#include -#include -#include - -#include "../busses/i2c-rtl9300.h" - -#define NUM_MASTERS 2 -#define NUM_BUSSES 8 - -#define REG(mst, x) (mux->base + x + (mst ? mux->i2c->mst2_offset : 0)) -#define REG_MASK(mst, clear, set, reg) \ - writel((readl(REG((mst),(reg))) & ~(clear)) | (set), REG((mst),(reg))) - -struct channel { - u8 sda_num; - u8 scl_num; -}; - -static struct channel channels[NUM_MASTERS * NUM_BUSSES]; - -struct rtl9300_mux { - void __iomem *base; - struct device *dev; - struct i2c_adapter *parent; - struct rtl9300_i2c * i2c; -}; - -struct i2c_mux_data { - int scl0_pin; - int scl1_pin; - int sda0_pin; - int sda_pins; - int (*i2c_mux_select)(struct i2c_mux_core *muxc, u32 chan); - int (*i2c_mux_deselect)(struct i2c_mux_core *muxc, u32 chan); - void (*sda_sel)(struct i2c_mux_core *muxc, int pin); -}; - -static int rtl9300_i2c_mux_select(struct i2c_mux_core *muxc, u32 chan) -{ - struct rtl9300_mux *mux = i2c_mux_priv(muxc); - - /* Set SCL pin */ - REG_MASK(channels[chan].scl_num, 0, - BIT(RTL9300_I2C_CTRL1_GPIO8_SCL_SEL), RTL9300_I2C_CTRL1); - - /* Set SDA pin */ - REG_MASK(channels[chan].scl_num, 0x7 << RTL9300_I2C_CTRL1_SDA_OUT_SEL, - channels[chan].sda_num << RTL9300_I2C_CTRL1_SDA_OUT_SEL, RTL9300_I2C_CTRL1); - - mux->i2c->sda_num = channels[chan].sda_num; - mux->i2c->scl_num = channels[chan].scl_num; - - return 0; -} - -static int rtl9310_i2c_mux_select(struct i2c_mux_core *muxc, u32 chan) -{ - struct rtl9300_mux *mux = i2c_mux_priv(muxc); - - /* Set SCL pin */ - REG_MASK(0, 0, BIT(RTL9310_I2C_MST_IF_SEL_GPIO_SCL_SEL + channels[chan].scl_num), - RTL9310_I2C_MST_IF_SEL); - - /* Set SDA pin */ - REG_MASK(channels[chan].scl_num, 0xf << RTL9310_I2C_CTRL_SDA_OUT_SEL, - channels[chan].sda_num << RTL9310_I2C_CTRL_SDA_OUT_SEL, RTL9310_I2C_CTRL); - - mux->i2c->sda_num = channels[chan].sda_num; - mux->i2c->scl_num = channels[chan].scl_num; - - return 0; -} - -static int rtl9300_i2c_mux_deselect(struct i2c_mux_core *muxc, u32 chan) -{ - return 0; -} - -static void rtl9300_sda_sel(struct i2c_mux_core *muxc, int pin) -{ - struct rtl9300_mux *mux = i2c_mux_priv(muxc); - u32 v; - - /* Set SDA pin to I2C functionality */ - v = readl(REG(0, RTL9300_I2C_MST_GLB_CTRL)); - v |= BIT(pin); - writel(v, REG(0, RTL9300_I2C_MST_GLB_CTRL)); -} - -static void rtl9310_sda_sel(struct i2c_mux_core *muxc, int pin) -{ - struct rtl9300_mux *mux = i2c_mux_priv(muxc); - u32 v; - - /* Set SDA pin to I2C functionality */ - v = readl(REG(0, RTL9310_I2C_MST_IF_SEL)); - v |= BIT(pin); - writel(v, REG(0, RTL9310_I2C_MST_IF_SEL)); -} - -static struct device_node *mux_parent_adapter(struct device *dev, struct rtl9300_mux *mux) -{ - struct device_node *node = dev->of_node; - struct device_node *parent_np; - struct i2c_adapter *parent; - - parent_np = of_parse_phandle(node, "i2c-parent", 0); - if (!parent_np) { - dev_err(dev, "Cannot parse i2c-parent\n"); - return ERR_PTR(-ENODEV); - } - parent = of_find_i2c_adapter_by_node(parent_np); - of_node_put(parent_np); - if (!parent) - return ERR_PTR(-EPROBE_DEFER); - - if (!(of_device_is_compatible(parent_np, "realtek,rtl9300-i2c") || - of_device_is_compatible(parent_np, "realtek,rtl9310-i2c"))){ - dev_err(dev, "I2C parent not an RTL9300 I2C controller\n"); - return ERR_PTR(-ENODEV); - } - - mux->parent = parent; - mux->i2c = (struct rtl9300_i2c *)i2c_get_adapdata(parent); - mux->base = mux->i2c->base; - - return parent_np; -} - -struct i2c_mux_data rtl9300_i2c_mux_data = { - .scl0_pin = 8, - .scl1_pin = 17, - .sda0_pin = 9, - .sda_pins = 8, - .i2c_mux_select = rtl9300_i2c_mux_select, - .i2c_mux_deselect = rtl9300_i2c_mux_deselect, - .sda_sel = rtl9300_sda_sel, -}; - -struct i2c_mux_data rtl9310_i2c_mux_data = { - .scl0_pin = 13, - .scl1_pin = 14, - .sda0_pin = 0, - .sda_pins = 16, - .i2c_mux_select = rtl9310_i2c_mux_select, - .i2c_mux_deselect = rtl9300_i2c_mux_deselect, - .sda_sel = rtl9310_sda_sel, -}; - -static const struct of_device_id rtl9300_i2c_mux_of_match[] = { - { .compatible = "realtek,i2c-mux-rtl9300", .data = (void *) &rtl9300_i2c_mux_data}, - { .compatible = "realtek,i2c-mux-rtl9310", .data = (void *) &rtl9310_i2c_mux_data}, - {}, -}; - -MODULE_DEVICE_TABLE(of, rtl9300_i2c_mux_of_match); - -static int rtl9300_i2c_mux_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *node = dev->of_node; - struct device_node *parent_np; - struct device_node *child; - struct i2c_mux_core *muxc; - struct rtl9300_mux *mux; - struct i2c_mux_data *mux_data; - int children; - int ret; - - pr_info("%s probing I2C adapter\n", __func__); - - if (!node) { - dev_err(dev, "No DT found\n"); - return -EINVAL; - } - - mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); - if (!mux) - return -ENOMEM; - - mux->dev = dev; - - mux_data = (struct i2c_mux_data *) device_get_match_data(dev); - - parent_np = mux_parent_adapter(dev, mux); - if (IS_ERR(parent_np)) - return dev_err_probe(dev, PTR_ERR(parent_np), "i2c-parent adapter not found\n"); - - pr_info("%s base memory %08x\n", __func__, (u32)mux->base); - - children = of_get_child_count(node); - - muxc = i2c_mux_alloc(mux->parent, dev, children, 0, 0, - mux_data->i2c_mux_select, mux_data->i2c_mux_deselect); - if (!muxc) { - ret = -ENOMEM; - goto err_parent; - } - muxc->priv = mux; - - platform_set_drvdata(pdev, muxc); - - for_each_child_of_node(node, child) { - u32 chan; - u32 pin; - - ret = of_property_read_u32(child, "reg", &chan); - if (ret < 0) { - dev_err(dev, "no reg property for node '%pOFn'\n", - child); - goto err_children; - } - - if (chan >= NUM_MASTERS * NUM_BUSSES) { - dev_err(dev, "invalid reg %u\n", chan); - ret = -EINVAL; - goto err_children; - } - - if (of_property_read_u32(child, "scl-pin", &pin)) { - dev_warn(dev, "SCL pin not found in DT, using default\n"); - pin = mux_data->scl0_pin; - } - if (!(pin == mux_data->scl0_pin || pin == mux_data->scl1_pin)) { - dev_warn(dev, "SCL pin %d not supported\n", pin); - ret = -EINVAL; - goto err_children; - } - channels[chan].scl_num = pin == mux_data->scl0_pin ? 0 : 1; - pr_info("%s channel %d scl_num %d\n", __func__, chan, channels[chan].scl_num); - - if (of_property_read_u32(child, "sda-pin", &pin)) { - dev_warn(dev, "SDA pin not found in DT, using default \n"); - pin = mux_data->sda0_pin; - } - channels[chan].sda_num = pin - mux_data->sda0_pin; - if (channels[chan].sda_num < 0 || channels[chan].sda_num >= mux_data->sda_pins) { - dev_warn(dev, "SDA pin %d not supported\n", pin); - return -EINVAL; - } - pr_info("%s channel %d sda_num %d\n", __func__, chan, channels[chan].sda_num); - - mux_data->sda_sel(muxc, channels[chan].sda_num); - - ret = i2c_mux_add_adapter(muxc, 0, chan, 0); - if (ret) - goto err_children; - } - - dev_info(dev, "%d-port mux on %s adapter\n", children, mux->parent->name); - - return 0; - -err_children: - i2c_mux_del_adapters(muxc); -err_parent: - i2c_put_adapter(mux->parent); - - return ret; -} - -static int rtl9300_i2c_mux_remove(struct platform_device *pdev) -{ - struct i2c_mux_core *muxc = platform_get_drvdata(pdev); - - i2c_mux_del_adapters(muxc); - i2c_put_adapter(muxc->parent); - - return 0; -} - -static struct platform_driver i2c_mux_driver = { - .probe = rtl9300_i2c_mux_probe, - .remove = rtl9300_i2c_mux_remove, - .driver = { - .name = "i2c-mux-rtl9300", - .of_match_table = rtl9300_i2c_mux_of_match, - }, -}; -module_platform_driver(i2c_mux_driver); - -MODULE_DESCRIPTION("RTL9300 I2C multiplexer driver"); -MODULE_AUTHOR("Birger Koblitz"); -MODULE_LICENSE("GPL v2"); diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Kconfig b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Kconfig deleted file mode 100644 index 3124ee8d20c219..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config NET_DSA_RTL83XX - tristate "Realtek RTL838x/RTL839x switch support" - depends on RTL83XX - select NET_DSA_TAG_TRAILER - help - This driver adds support for Realtek RTL83xx series switching. diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Makefile b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Makefile deleted file mode 100644 index 8752c797004d74..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_NET_DSA_RTL83XX) += common.o dsa.o \ - rtl838x.o rtl839x.o rtl930x.o rtl931x.o debugfs.o qos.o tc.o diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c deleted file mode 100644 index 7ce5f0146e71a1..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/common.c +++ /dev/null @@ -1,1714 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rtl83xx.h" - -extern struct rtl83xx_soc_info soc_info; - -extern const struct rtl838x_reg rtl838x_reg; -extern const struct rtl838x_reg rtl839x_reg; -extern const struct rtl838x_reg rtl930x_reg; -extern const struct rtl838x_reg rtl931x_reg; - -extern const struct dsa_switch_ops rtl83xx_switch_ops; -extern const struct dsa_switch_ops rtl930x_switch_ops; - -DEFINE_MUTEX(smi_lock); - -int rtl83xx_port_get_stp_state(struct rtl838x_switch_priv *priv, int port) -{ - u32 msti = 0; - u32 port_state[4]; - int index, bit; - int pos = port; - int n = priv->port_width << 1; - - /* Ports above or equal CPU port can never be configured */ - if (port >= priv->cpu_port) - return -1; - - mutex_lock(&priv->reg_mutex); - - /* For the RTL839x and following, the bits are left-aligned in the 64/128 bit field */ - if (priv->family_id == RTL8390_FAMILY_ID) - pos += 12; - if (priv->family_id == RTL9300_FAMILY_ID) - pos += 3; - if (priv->family_id == RTL9310_FAMILY_ID) - pos += 8; - - index = n - (pos >> 4) - 1; - bit = (pos << 1) % 32; - - priv->r->stp_get(priv, msti, port_state); - - mutex_unlock(&priv->reg_mutex); - - return (port_state[index] >> bit) & 3; -} - -static struct table_reg rtl838x_tbl_regs[] = { - TBL_DESC(0x6900, 0x6908, 3, 15, 13, 1), /* RTL8380_TBL_L2 */ - TBL_DESC(0x6914, 0x6918, 18, 14, 12, 1), /* RTL8380_TBL_0 */ - TBL_DESC(0xA4C8, 0xA4CC, 6, 14, 12, 1), /* RTL8380_TBL_1 */ - - TBL_DESC(0x1180, 0x1184, 3, 16, 14, 0), /* RTL8390_TBL_L2 */ - TBL_DESC(0x1190, 0x1194, 17, 15, 12, 0), /* RTL8390_TBL_0 */ - TBL_DESC(0x6B80, 0x6B84, 4, 14, 12, 0), /* RTL8390_TBL_1 */ - TBL_DESC(0x611C, 0x6120, 9, 8, 6, 0), /* RTL8390_TBL_2 */ - - TBL_DESC(0xB320, 0xB334, 3, 18, 16, 0), /* RTL9300_TBL_L2 */ - TBL_DESC(0xB340, 0xB344, 19, 16, 12, 0), /* RTL9300_TBL_0 */ - TBL_DESC(0xB3A0, 0xB3A4, 20, 16, 13, 0), /* RTL9300_TBL_1 */ - TBL_DESC(0xCE04, 0xCE08, 6, 14, 12, 0), /* RTL9300_TBL_2 */ - TBL_DESC(0xD600, 0xD604, 30, 7, 6, 0), /* RTL9300_TBL_HSB */ - TBL_DESC(0x7880, 0x7884, 22, 9, 8, 0), /* RTL9300_TBL_HSA */ - - TBL_DESC(0x8500, 0x8508, 8, 19, 15, 0), /* RTL9310_TBL_0 */ - TBL_DESC(0x40C0, 0x40C4, 22, 16, 14, 0), /* RTL9310_TBL_1 */ - TBL_DESC(0x8528, 0x852C, 6, 18, 14, 0), /* RTL9310_TBL_2 */ - TBL_DESC(0x0200, 0x0204, 9, 15, 12, 0), /* RTL9310_TBL_3 */ - TBL_DESC(0x20dc, 0x20e0, 29, 7, 6, 0), /* RTL9310_TBL_4 */ - TBL_DESC(0x7e1c, 0x7e20, 53, 8, 6, 0), /* RTL9310_TBL_5 */ -}; - -void rtl_table_init(void) -{ - for (int i = 0; i < RTL_TBL_END; i++) - mutex_init(&rtl838x_tbl_regs[i].lock); -} - -/* Request access to table t in table access register r - * Returns a handle to a lock for that table - */ -struct table_reg *rtl_table_get(rtl838x_tbl_reg_t r, int t) -{ - if (r >= RTL_TBL_END) - return NULL; - - if (t >= BIT(rtl838x_tbl_regs[r].c_bit-rtl838x_tbl_regs[r].t_bit)) - return NULL; - - mutex_lock(&rtl838x_tbl_regs[r].lock); - rtl838x_tbl_regs[r].tbl = t; - - return &rtl838x_tbl_regs[r]; -} - -/* Release a table r, unlock the corresponding lock */ -void rtl_table_release(struct table_reg *r) -{ - if (!r) - return; - -/* pr_info("Unlocking %08x\n", (u32)r); */ - mutex_unlock(&r->lock); -/* pr_info("Unlock done\n"); */ -} - -static int rtl_table_exec(struct table_reg *r, bool is_write, int idx) -{ - int ret = 0; - u32 cmd, val; - - /* Read/write bit has inverted meaning on RTL838x */ - if (r->rmode) - cmd = is_write ? 0 : BIT(r->c_bit); - else - cmd = is_write ? BIT(r->c_bit) : 0; - - cmd |= BIT(r->c_bit + 1); /* Execute bit */ - cmd |= r->tbl << r->t_bit; /* Table type */ - cmd |= idx & (BIT(r->t_bit) - 1); /* Index */ - - sw_w32(cmd, r->addr); - - ret = readx_poll_timeout(sw_r32, r->addr, val, - !(val & BIT(r->c_bit + 1)), 20, 10000); - if (ret) - pr_err("%s: timeout\n", __func__); - - return ret; -} - -/* Reads table index idx into the data registers of the table */ -int rtl_table_read(struct table_reg *r, int idx) -{ - return rtl_table_exec(r, false, idx); -} - -/* Writes the content of the table data registers into the table at index idx */ -int rtl_table_write(struct table_reg *r, int idx) -{ - return rtl_table_exec(r, true, idx); -} - -/* Returns the address of the ith data register of table register r - * the address is relative to the beginning of the Switch-IO block at 0xbb000000 - */ -inline u16 rtl_table_data(struct table_reg *r, int i) -{ - if (i >= r->max_data) - i = r->max_data - 1; - return r->data + i * 4; -} - -inline u32 rtl_table_data_r(struct table_reg *r, int i) -{ - return sw_r32(rtl_table_data(r, i)); -} - -inline void rtl_table_data_w(struct table_reg *r, u32 v, int i) -{ - sw_w32(v, rtl_table_data(r, i)); -} - -/* Port register accessor functions for the RTL838x and RTL930X SoCs */ -void rtl838x_mask_port_reg(u64 clear, u64 set, int reg) -{ - sw_w32_mask((u32)clear, (u32)set, reg); -} - -void rtl838x_set_port_reg(u64 set, int reg) -{ - sw_w32((u32)set, reg); -} - -u64 rtl838x_get_port_reg(int reg) -{ - return ((u64)sw_r32(reg)); -} - -/* Port register accessor functions for the RTL839x and RTL931X SoCs */ -void rtl839x_mask_port_reg_be(u64 clear, u64 set, int reg) -{ - sw_w32_mask((u32)(clear >> 32), (u32)(set >> 32), reg); - sw_w32_mask((u32)(clear & 0xffffffff), (u32)(set & 0xffffffff), reg + 4); -} - -u64 rtl839x_get_port_reg_be(int reg) -{ - u64 v = sw_r32(reg); - - v <<= 32; - v |= sw_r32(reg + 4); - - return v; -} - -void rtl839x_set_port_reg_be(u64 set, int reg) -{ - sw_w32(set >> 32, reg); - sw_w32(set & 0xffffffff, reg + 4); -} - -void rtl839x_mask_port_reg_le(u64 clear, u64 set, int reg) -{ - sw_w32_mask((u32)clear, (u32)set, reg); - sw_w32_mask((u32)(clear >> 32), (u32)(set >> 32), reg + 4); -} - -void rtl839x_set_port_reg_le(u64 set, int reg) -{ - sw_w32(set, reg); - sw_w32(set >> 32, reg + 4); -} - -u64 rtl839x_get_port_reg_le(int reg) -{ - u64 v = sw_r32(reg + 4); - - v <<= 32; - v |= sw_r32(reg); - - return v; -} - -int read_phy(u32 port, u32 page, u32 reg, u32 *val) -{ - switch (soc_info.family) { - case RTL8380_FAMILY_ID: - return rtl838x_read_phy(port, page, reg, val); - case RTL8390_FAMILY_ID: - return rtl839x_read_phy(port, page, reg, val); - case RTL9300_FAMILY_ID: - return rtl930x_read_phy(port, page, reg, val); - case RTL9310_FAMILY_ID: - return rtl931x_read_phy(port, page, reg, val); - } - - return -1; -} - -int write_phy(u32 port, u32 page, u32 reg, u32 val) -{ - switch (soc_info.family) { - case RTL8380_FAMILY_ID: - return rtl838x_write_phy(port, page, reg, val); - case RTL8390_FAMILY_ID: - return rtl839x_write_phy(port, page, reg, val); - case RTL9300_FAMILY_ID: - return rtl930x_write_phy(port, page, reg, val); - case RTL9310_FAMILY_ID: - return rtl931x_write_phy(port, page, reg, val); - } - - return -1; -} - -static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv) -{ - struct device *dev = priv->dev; - struct device_node *dn, *phy_node, *led_node, *mii_np = dev->of_node; - struct mii_bus *bus; - int ret; - u32 pn; - - pr_debug("In %s\n", __func__); - mii_np = of_find_compatible_node(NULL, NULL, "realtek,rtl838x-mdio"); - if (mii_np) { - pr_debug("Found compatible MDIO node!\n"); - } else { - dev_err(priv->dev, "no %s child node found", "mdio-bus"); - return -ENODEV; - } - - priv->mii_bus = of_mdio_find_bus(mii_np); - if (!priv->mii_bus) { - pr_debug("Deferring probe of mdio bus\n"); - return -EPROBE_DEFER; - } - if (!of_device_is_available(mii_np)) - ret = -ENODEV; - - bus = devm_mdiobus_alloc(priv->ds->dev); - if (!bus) - return -ENOMEM; - - bus->name = "rtl838x slave mii"; - - /* Since the NIC driver is loaded first, we can use the mdio rw functions - * assigned there. - */ - bus->read = priv->mii_bus->read; - bus->write = priv->mii_bus->write; - snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", bus->name, dev->id); - - bus->parent = dev; - priv->ds->slave_mii_bus = bus; - priv->ds->slave_mii_bus->priv = priv->mii_bus->priv; - - ret = mdiobus_register(priv->ds->slave_mii_bus); - if (ret && mii_np) { - of_node_put(dn); - return ret; - } - - dn = of_find_compatible_node(NULL, NULL, "realtek,rtl83xx-switch"); - if (!dn) { - dev_err(priv->dev, "No RTL switch node in DTS\n"); - return -ENODEV; - } - - led_node = of_find_compatible_node(NULL, NULL, "realtek,rtl9300-leds"); - - for_each_node_by_name(dn, "port") { - phy_interface_t interface; - u32 led_set; - char led_set_str[16] = {0}; - - if (!of_device_is_available(dn)) - continue; - - if (of_property_read_u32(dn, "reg", &pn)) - continue; - - phy_node = of_parse_phandle(dn, "phy-handle", 0); - if (!phy_node) { - if (pn != priv->cpu_port) - dev_err(priv->dev, "Port node %d misses phy-handle\n", pn); - continue; - } - - if (of_property_read_u32(phy_node, "sds", &priv->ports[pn].sds_num)) - priv->ports[pn].sds_num = -1; - pr_debug("%s port %d has SDS %d\n", __func__, pn, priv->ports[pn].sds_num); - - if (of_get_phy_mode(dn, &interface)) - interface = PHY_INTERFACE_MODE_NA; - if (interface == PHY_INTERFACE_MODE_HSGMII) - priv->ports[pn].is2G5 = true; - if (interface == PHY_INTERFACE_MODE_USXGMII) - priv->ports[pn].is2G5 = priv->ports[pn].is10G = true; - if (interface == PHY_INTERFACE_MODE_10GBASER) - priv->ports[pn].is10G = true; - - priv->ports[pn].leds_on_this_port = 0; - if (led_node) { - if (of_property_read_u32(dn, "led-set", &led_set)) - led_set = 0; - priv->ports[pn].led_set = led_set; - sprintf(led_set_str, "led_set%d", led_set); - priv->ports[pn].leds_on_this_port = of_property_count_u32_elems(led_node, led_set_str); - if (priv->ports[pn].leds_on_this_port > 4) { - dev_err(priv->dev, "led_set %d for port %d configuration is invalid\n", led_set, pn); - return -ENODEV; - } - } - - /* Check for the integrated SerDes of the RTL8380M first */ - if (of_property_read_bool(phy_node, "phy-is-integrated") - && priv->id == 0x8380 && pn >= 24) { - pr_debug("----> FÓUND A SERDES\n"); - priv->ports[pn].phy = PHY_RTL838X_SDS; - continue; - } - - if (priv->id >= 0x9300) { - priv->ports[pn].phy_is_integrated = false; - if (of_property_read_bool(phy_node, "phy-is-integrated")) { - priv->ports[pn].phy_is_integrated = true; - priv->ports[pn].phy = PHY_RTL930X_SDS; - } - } else { - if (of_property_read_bool(phy_node, "phy-is-integrated") && - !of_property_read_bool(phy_node, "sfp")) { - priv->ports[pn].phy = PHY_RTL8218B_INT; - continue; - } - } - - if (!of_property_read_bool(phy_node, "phy-is-integrated") && - of_property_read_bool(phy_node, "sfp")) { - priv->ports[pn].phy = PHY_RTL8214FC; - continue; - } - - if (!of_property_read_bool(phy_node, "phy-is-integrated") && - !of_property_read_bool(phy_node, "sfp")) { - priv->ports[pn].phy = PHY_RTL8218B_EXT; - continue; - } - } - - /* Disable MAC polling the PHY so that we can start configuration */ - priv->r->set_port_reg_le(0ULL, priv->r->smi_poll_ctrl); - - /* Enable PHY control via SoC */ - if (priv->family_id == RTL8380_FAMILY_ID) { - /* Enable SerDes NWAY and PHY control via SoC */ - sw_w32_mask(BIT(7), BIT(15), RTL838X_SMI_GLB_CTRL); - } else if (priv->family_id == RTL8390_FAMILY_ID) { - /* Disable PHY polling via SoC */ - sw_w32_mask(BIT(7), 0, RTL839X_SMI_GLB_CTRL); - } - - /* Power on fibre ports and reset them if necessary */ - if (priv->ports[24].phy == PHY_RTL838X_SDS) { - pr_debug("Powering on fibre ports & reset\n"); - rtl8380_sds_power(24, 1); - rtl8380_sds_power(26, 1); - } - - pr_debug("%s done\n", __func__); - - return 0; -} - -static int __init rtl83xx_get_l2aging(struct rtl838x_switch_priv *priv) -{ - int t = sw_r32(priv->r->l2_ctrl_1); - - t &= priv->family_id == RTL8380_FAMILY_ID ? 0x7fffff : 0x1FFFFF; - - if (priv->family_id == RTL8380_FAMILY_ID) - t = t * 128 / 625; /* Aging time in seconds. 0: L2 aging disabled */ - else - t = (t * 3) / 5; - - pr_debug("L2 AGING time: %d sec\n", t); - pr_debug("Dynamic aging for ports: %x\n", sw_r32(priv->r->l2_port_aging_out)); - - return t; -} - -/* Caller must hold priv->reg_mutex */ -int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_lag_upper_info *info) -{ - struct rtl838x_switch_priv *priv = ds->priv; - int i; - u32 algomsk = 0; - u32 algoidx = 0; - - if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) { - pr_err("%s: Only mode LACP 802.3ad (4) allowed.\n", __func__); - return -EINVAL; - } - - if (group >= priv->n_lags) { - pr_err("%s: LAG %d invalid.\n", __func__, group); - return -EINVAL; - } - - if (port >= priv->cpu_port) { - pr_err("%s: Port %d invalid.\n", __func__, port); - return -EINVAL; - } - - for (i = 0; i < priv->n_lags; i++) { - if (priv->lags_port_members[i] & BIT_ULL(port)) - break; - } - if (i != priv->n_lags) { - pr_err("%s: Port %d already member of LAG %d.\n", __func__, port, i); - return -ENOSPC; - } - - switch(info->hash_type) { - case NETDEV_LAG_HASH_L2: - algomsk |= TRUNK_DISTRIBUTION_ALGO_DMAC_BIT; - algomsk |= TRUNK_DISTRIBUTION_ALGO_SMAC_BIT; - break; - case NETDEV_LAG_HASH_L23: - algomsk |= TRUNK_DISTRIBUTION_ALGO_DMAC_BIT; - algomsk |= TRUNK_DISTRIBUTION_ALGO_SMAC_BIT; - algomsk |= TRUNK_DISTRIBUTION_ALGO_SIP_BIT; /* source ip */ - algomsk |= TRUNK_DISTRIBUTION_ALGO_DIP_BIT; /* dest ip */ - algoidx = 1; - break; - case NETDEV_LAG_HASH_L34: - algomsk |= TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT; /* sport */ - algomsk |= TRUNK_DISTRIBUTION_ALGO_DST_L4PORT_BIT; /* dport */ - algomsk |= TRUNK_DISTRIBUTION_ALGO_SIP_BIT; /* source ip */ - algomsk |= TRUNK_DISTRIBUTION_ALGO_DIP_BIT; /* dest ip */ - algoidx = 2; - break; - default: - algomsk |= 0x7f; - } - priv->r->set_distribution_algorithm(group, algoidx, algomsk); - priv->r->mask_port_reg_be(0, BIT_ULL(port), priv->r->trk_mbr_ctr(group)); - priv->lags_port_members[group] |= BIT_ULL(port); - - pr_info("%s: Added port %d to LAG %d. Members now %016llx.\n", - __func__, port, group, priv->lags_port_members[group]); - - return 0; -} - -/* Caller must hold priv->reg_mutex */ -int rtl83xx_lag_del(struct dsa_switch *ds, int group, int port) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - if (group >= priv->n_lags) { - pr_err("%s: LAG %d invalid.\n", __func__, group); - return -EINVAL; - } - - if (port >= priv->cpu_port) { - pr_err("%s: Port %d invalid.\n", __func__, port); - return -EINVAL; - } - - if (!(priv->lags_port_members[group] & BIT_ULL(port))) { - pr_err("%s: Port %d not member of LAG %d.\n", __func__, port, group); - return -ENOSPC; - } - - /* 0x7f algo mask all */ - priv->r->mask_port_reg_be(BIT_ULL(port), 0, priv->r->trk_mbr_ctr(group)); - priv->lags_port_members[group] &= ~BIT_ULL(port); - - pr_info("%s: Removed port %d from LAG %d. Members now %016llx.\n", - __func__, port, group, priv->lags_port_members[group]); - - return 0; -} - -// Currently Unused -// /* Allocate a 64 bit octet counter located in the LOG HW table */ -// static int rtl83xx_octet_cntr_alloc(struct rtl838x_switch_priv *priv) -// { -// int idx; - -// mutex_lock(&priv->reg_mutex); - -// idx = find_first_zero_bit(priv->octet_cntr_use_bm, MAX_COUNTERS); -// if (idx >= priv->n_counters) { -// mutex_unlock(&priv->reg_mutex); -// return -1; -// } - -// set_bit(idx, priv->octet_cntr_use_bm); -// mutex_unlock(&priv->reg_mutex); - -// return idx; -// } - -/* Allocate a 32-bit packet counter - * 2 32-bit packet counters share the location of a 64-bit octet counter - * Initially there are no free packet counters and 2 new ones need to be freed - * by allocating the corresponding octet counter - */ -int rtl83xx_packet_cntr_alloc(struct rtl838x_switch_priv *priv) -{ - int idx, j; - - mutex_lock(&priv->reg_mutex); - - /* Because initially no packet counters are free, the logic is reversed: - * a 0-bit means the counter is already allocated (for octets) - */ - idx = find_first_bit(priv->packet_cntr_use_bm, MAX_COUNTERS * 2); - if (idx >= priv->n_counters * 2) { - j = find_first_zero_bit(priv->octet_cntr_use_bm, MAX_COUNTERS); - if (j >= priv->n_counters) { - mutex_unlock(&priv->reg_mutex); - return -1; - } - set_bit(j, priv->octet_cntr_use_bm); - idx = j * 2; - set_bit(j * 2 + 1, priv->packet_cntr_use_bm); - - } else { - clear_bit(idx, priv->packet_cntr_use_bm); - } - - mutex_unlock(&priv->reg_mutex); - - return idx; -} - -/* Add an L2 nexthop entry for the L3 routing system / PIE forwarding in the SoC - * Use VID and MAC in rtl838x_l2_entry to identify either a free slot in the L2 hash table - * or mark an existing entry as a nexthop by setting it's nexthop bit - * Called from the L3 layer - * The index in the L2 hash table is filled into nh->l2_id; - */ -int rtl83xx_l2_nexthop_add(struct rtl838x_switch_priv *priv, struct rtl83xx_nexthop *nh) -{ - struct rtl838x_l2_entry e; - u64 seed = priv->r->l2_hash_seed(nh->mac, nh->rvid); - u32 key = priv->r->l2_hash_key(priv, seed); - int idx = -1; - u64 entry; - - pr_debug("%s searching for %08llx vid %d with key %d, seed: %016llx\n", - __func__, nh->mac, nh->rvid, key, seed); - - e.type = L2_UNICAST; - u64_to_ether_addr(nh->mac, &e.mac[0]); - e.port = nh->port; - - /* Loop over all entries in the hash-bucket and over the second block on 93xx SoCs */ - for (int i = 0; i < priv->l2_bucket_size; i++) { - entry = priv->r->read_l2_entry_using_hash(key, i, &e); - - if (!e.valid || ((entry & 0x0fffffffffffffffULL) == seed)) { - idx = i > 3 ? ((key >> 14) & 0xffff) | i >> 1 - : ((key << 2) | i) & 0xffff; - break; - } - } - - if (idx < 0) { - pr_err("%s: No more L2 forwarding entries available\n", __func__); - return -1; - } - - /* Found an existing (e->valid is true) or empty entry, make it a nexthop entry */ - nh->l2_id = idx; - if (e.valid) { - nh->port = e.port; - nh->vid = e.vid; /* Save VID */ - nh->rvid = e.rvid; - nh->dev_id = e.stack_dev; - /* If the entry is already a valid next hop entry, don't change it */ - if (e.next_hop) - return 0; - } else { - e.valid = true; - e.is_static = true; - e.rvid = nh->rvid; - e.is_ip_mc = false; - e.is_ipv6_mc = false; - e.block_da = false; - e.block_sa = false; - e.suspended = false; - e.age = 0; /* With port-ignore */ - e.port = priv->port_ignore; - u64_to_ether_addr(nh->mac, &e.mac[0]); - } - e.next_hop = true; - e.nh_route_id = nh->id; /* NH route ID takes place of VID */ - e.nh_vlan_target = false; - - priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e); - - return 0; -} - -/* Removes a Layer 2 next hop entry in the forwarding database - * If it was static, the entire entry is removed, otherwise the nexthop bit is cleared - * and we wait until the entry ages out - */ -int rtl83xx_l2_nexthop_rm(struct rtl838x_switch_priv *priv, struct rtl83xx_nexthop *nh) -{ - struct rtl838x_l2_entry e; - u32 key = nh->l2_id >> 2; - int i = nh->l2_id & 0x3; - u64 entry = entry = priv->r->read_l2_entry_using_hash(key, i, &e); - - pr_debug("%s: id %d, key %d, index %d\n", __func__, nh->l2_id, key, i); - if (!e.valid) { - dev_err(priv->dev, "unknown nexthop, id %x\n", nh->l2_id); - return -1; - } - - if (e.is_static) - e.valid = false; - e.next_hop = false; - e.vid = nh->vid; /* Restore VID */ - e.rvid = nh->rvid; - - priv->r->write_l2_entry_using_hash(key, i, &e); - - return 0; -} - -static int rtl83xx_handle_changeupper(struct rtl838x_switch_priv *priv, - struct net_device *ndev, - struct netdev_notifier_changeupper_info *info) -{ - struct net_device *upper = info->upper_dev; - struct netdev_lag_upper_info *lag_upper_info = NULL; - int i, j, err; - - if (!netif_is_lag_master(upper)) - return 0; - - mutex_lock(&priv->reg_mutex); - - for (i = 0; i < priv->n_lags; i++) { - if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == upper)) - break; - } - for (j = 0; j < priv->cpu_port; j++) { - if (priv->ports[j].dp->slave == ndev) - break; - } - if (j >= priv->cpu_port) { - err = -EINVAL; - goto out; - } - - if (info->linking) { - lag_upper_info = info->upper_info; - if (!priv->lag_devs[i]) - priv->lag_devs[i] = upper; - err = rtl83xx_lag_add(priv->ds, i, priv->ports[j].dp->index, lag_upper_info); - if (err) { - err = -EINVAL; - goto out; - } - } else { - if (!priv->lag_devs[i]) - err = -EINVAL; - err = rtl83xx_lag_del(priv->ds, i, priv->ports[j].dp->index); - if (err) { - err = -EINVAL; - goto out; - } - if (!priv->lags_port_members[i]) - priv->lag_devs[i] = NULL; - } - -out: - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -/* Is the lower network device a DSA slave network device of our RTL930X-switch? - * Unfortunately we cannot just follow dev->dsa_prt as this is only set for the - * DSA master device. - */ -int rtl83xx_port_is_under(const struct net_device * dev, struct rtl838x_switch_priv *priv) -{ -/* TODO: On 5.12: - * if(!dsa_slave_dev_check(dev)) { - * netdev_info(dev, "%s: not a DSA device.\n", __func__); - * return -EINVAL; - * } - */ - - for (int i = 0; i < priv->cpu_port; i++) { - if (!priv->ports[i].dp) - continue; - if (priv->ports[i].dp->slave == dev) - return i; - } - - return -EINVAL; -} - -static int rtl83xx_netdevice_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - struct net_device *ndev = netdev_notifier_info_to_dev(ptr); - struct rtl838x_switch_priv *priv; - int err; - - pr_debug("In: %s, event: %lu\n", __func__, event); - - if ((event != NETDEV_CHANGEUPPER) && (event != NETDEV_CHANGELOWERSTATE)) - return NOTIFY_DONE; - - priv = container_of(this, struct rtl838x_switch_priv, nb); - switch (event) { - case NETDEV_CHANGEUPPER: - err = rtl83xx_handle_changeupper(priv, ndev, ptr); - break; - } - - if (err) - return err; - - return NOTIFY_DONE; -} - -const static struct rhashtable_params route_ht_params = { - .key_len = sizeof(u32), - .key_offset = offsetof(struct rtl83xx_route, gw_ip), - .head_offset = offsetof(struct rtl83xx_route, linkage), -}; - -/* Updates an L3 next hop entry in the ROUTING table */ -static int rtl83xx_l3_nexthop_update(struct rtl838x_switch_priv *priv, __be32 ip_addr, u64 mac) -{ - struct rtl83xx_route *r; - struct rhlist_head *tmp, *list; - - rcu_read_lock(); - list = rhltable_lookup(&priv->routes, &ip_addr, route_ht_params); - if (!list) { - rcu_read_unlock(); - return -ENOENT; - } - - rhl_for_each_entry_rcu(r, tmp, list, linkage) { - pr_info("%s: Setting up fwding: ip %pI4, GW mac %016llx\n", - __func__, &ip_addr, mac); - - /* Reads the ROUTING table entry associated with the route */ - priv->r->route_read(r->id, r); - pr_info("Route with id %d to %pI4 / %d\n", r->id, &r->dst_ip, r->prefix_len); - - r->nh.mac = r->nh.gw = mac; - r->nh.port = priv->port_ignore; - r->nh.id = r->id; - - /* Do we need to explicitly add a DMAC entry with the route's nh index? */ - if (priv->r->set_l3_egress_mac) - priv->r->set_l3_egress_mac(r->id, mac); - - /* Update ROUTING table: map gateway-mac and switch-mac id to route id */ - rtl83xx_l2_nexthop_add(priv, &r->nh); - - r->attr.valid = true; - r->attr.action = ROUTE_ACT_FORWARD; - r->attr.type = 0; - r->attr.hit = false; /* Reset route-used indicator */ - - /* Add PIE entry with dst_ip and prefix_len */ - r->pr.dip = r->dst_ip; - r->pr.dip_m = inet_make_mask(r->prefix_len); - - if (r->is_host_route) { - int slot = priv->r->find_l3_slot(r, false); - - pr_info("%s: Got slot for route: %d\n", __func__, slot); - priv->r->host_route_write(slot, r); - } else { - priv->r->route_write(r->id, r); - r->pr.fwd_sel = true; - r->pr.fwd_data = r->nh.l2_id; - r->pr.fwd_act = PIE_ACT_ROUTE_UC; - } - - if (priv->r->set_l3_nexthop) - priv->r->set_l3_nexthop(r->nh.id, r->nh.l2_id, r->nh.if_id); - - if (r->pr.id < 0) { - r->pr.packet_cntr = rtl83xx_packet_cntr_alloc(priv); - if (r->pr.packet_cntr >= 0) { - pr_info("Using packet counter %d\n", r->pr.packet_cntr); - r->pr.log_sel = true; - r->pr.log_data = r->pr.packet_cntr; - } - priv->r->pie_rule_add(priv, &r->pr); - } else { - int pkts = priv->r->packet_cntr_read(r->pr.packet_cntr); - pr_info("%s: total packets: %d\n", __func__, pkts); - - priv->r->pie_rule_write(priv, r->pr.id, &r->pr); - } - } - rcu_read_unlock(); - - return 0; -} - -static int rtl83xx_port_ipv4_resolve(struct rtl838x_switch_priv *priv, - struct net_device *dev, __be32 ip_addr) -{ - struct neighbour *n = neigh_lookup(&arp_tbl, &ip_addr, dev); - int err = 0; - u64 mac; - - if (!n) { - n = neigh_create(&arp_tbl, &ip_addr, dev); - if (IS_ERR(n)) - return PTR_ERR(n); - } - - /* If the neigh is already resolved, then go ahead and - * install the entry, otherwise start the ARP process to - * resolve the neigh. - */ - if (n->nud_state & NUD_VALID) { - mac = ether_addr_to_u64(n->ha); - pr_info("%s: resolved mac: %016llx\n", __func__, mac); - rtl83xx_l3_nexthop_update(priv, ip_addr, mac); - } else { - pr_info("%s: need to wait\n", __func__); - neigh_event_send(n, NULL); - } - - neigh_release(n); - - return err; -} - -struct rtl83xx_walk_data { - struct rtl838x_switch_priv *priv; - int port; -}; - -static int rtl83xx_port_lower_walk(struct net_device *lower, struct netdev_nested_priv *_priv) -{ - struct rtl83xx_walk_data *data = (struct rtl83xx_walk_data *)_priv->data; - struct rtl838x_switch_priv *priv = data->priv; - int ret = 0; - int index; - - index = rtl83xx_port_is_under(lower, priv); - data->port = index; - if (index >= 0) { - pr_debug("Found DSA-port, index %d\n", index); - ret = 1; - } - - return ret; -} - -int rtl83xx_port_dev_lower_find(struct net_device *dev, struct rtl838x_switch_priv *priv) -{ - struct rtl83xx_walk_data data; - struct netdev_nested_priv _priv; - - data.priv = priv; - data.port = 0; - _priv.data = (void *)&data; - - netdev_walk_all_lower_dev(dev, rtl83xx_port_lower_walk, &_priv); - - return data.port; -} - -static struct rtl83xx_route *rtl83xx_route_alloc(struct rtl838x_switch_priv *priv, u32 ip) -{ - struct rtl83xx_route *r; - int idx = 0, err; - - mutex_lock(&priv->reg_mutex); - - idx = find_first_zero_bit(priv->route_use_bm, MAX_ROUTES); - pr_debug("%s id: %d, ip %pI4\n", __func__, idx, &ip); - - r = kzalloc(sizeof(*r), GFP_KERNEL); - if (!r) { - mutex_unlock(&priv->reg_mutex); - return r; - } - - r->id = idx; - r->gw_ip = ip; - r->pr.id = -1; /* We still need to allocate a rule in HW */ - r->is_host_route = false; - - err = rhltable_insert(&priv->routes, &r->linkage, route_ht_params); - if (err) { - pr_err("Could not insert new rule\n"); - mutex_unlock(&priv->reg_mutex); - goto out_free; - } - - set_bit(idx, priv->route_use_bm); - - mutex_unlock(&priv->reg_mutex); - - return r; - -out_free: - kfree(r); - - return NULL; -} - - -static struct rtl83xx_route *rtl83xx_host_route_alloc(struct rtl838x_switch_priv *priv, u32 ip) -{ - struct rtl83xx_route *r; - int idx = 0, err; - - mutex_lock(&priv->reg_mutex); - - idx = find_first_zero_bit(priv->host_route_use_bm, MAX_HOST_ROUTES); - pr_debug("%s id: %d, ip %pI4\n", __func__, idx, &ip); - - r = kzalloc(sizeof(*r), GFP_KERNEL); - if (!r) { - mutex_unlock(&priv->reg_mutex); - return r; - } - - /* We require a unique route ID irrespective of whether it is a prefix or host - * route (on RTL93xx) as we use this ID to associate a DMAC and next-hop entry - */ - r->id = idx + MAX_ROUTES; - - r->gw_ip = ip; - r->pr.id = -1; /* We still need to allocate a rule in HW */ - r->is_host_route = true; - - err = rhltable_insert(&priv->routes, &r->linkage, route_ht_params); - if (err) { - pr_err("Could not insert new rule\n"); - mutex_unlock(&priv->reg_mutex); - goto out_free; - } - - set_bit(idx, priv->host_route_use_bm); - - mutex_unlock(&priv->reg_mutex); - - return r; - -out_free: - kfree(r); - - return NULL; -} - - - -static void rtl83xx_route_rm(struct rtl838x_switch_priv *priv, struct rtl83xx_route *r) -{ - int id; - - if (rhltable_remove(&priv->routes, &r->linkage, route_ht_params)) - dev_warn(priv->dev, "Could not remove route\n"); - - if (r->is_host_route) { - id = priv->r->find_l3_slot(r, false); - pr_debug("%s: Got id for host route: %d\n", __func__, id); - r->attr.valid = false; - priv->r->host_route_write(id, r); - clear_bit(r->id - MAX_ROUTES, priv->host_route_use_bm); - } else { - /* If there is a HW representation of the route, delete it */ - if (priv->r->route_lookup_hw) { - id = priv->r->route_lookup_hw(r); - pr_info("%s: Got id for prefix route: %d\n", __func__, id); - r->attr.valid = false; - priv->r->route_write(id, r); - } - clear_bit(r->id, priv->route_use_bm); - } - - kfree(r); -} - -static int rtl83xx_fib4_del(struct rtl838x_switch_priv *priv, - struct fib_entry_notifier_info *info) -{ - struct fib_nh *nh = fib_info_nh(info->fi, 0); - struct rtl83xx_route *r; - struct rhlist_head *tmp, *list; - - pr_debug("In %s, ip %pI4, len %d\n", __func__, &info->dst, info->dst_len); - rcu_read_lock(); - list = rhltable_lookup(&priv->routes, &nh->fib_nh_gw4, route_ht_params); - if (!list) { - rcu_read_unlock(); - pr_err("%s: no such gateway: %pI4\n", __func__, &nh->fib_nh_gw4); - return -ENOENT; - } - rhl_for_each_entry_rcu(r, tmp, list, linkage) { - if (r->dst_ip == info->dst && r->prefix_len == info->dst_len) { - pr_info("%s: found a route with id %d, nh-id %d\n", - __func__, r->id, r->nh.id); - break; - } - } - rcu_read_unlock(); - - rtl83xx_l2_nexthop_rm(priv, &r->nh); - - pr_debug("%s: Releasing packet counter %d\n", __func__, r->pr.packet_cntr); - set_bit(r->pr.packet_cntr, priv->packet_cntr_use_bm); - priv->r->pie_rule_rm(priv, &r->pr); - - rtl83xx_route_rm(priv, r); - - nh->fib_nh_flags &= ~RTNH_F_OFFLOAD; - - return 0; -} - -/* On the RTL93xx, an L3 termination endpoint MAC address on which the router waits - * for packets to be routed needs to be allocated. - */ -static int rtl83xx_alloc_router_mac(struct rtl838x_switch_priv *priv, u64 mac) -{ - int free_mac = -1; - struct rtl93xx_rt_mac m; - - mutex_lock(&priv->reg_mutex); - for (int i = 0; i < MAX_ROUTER_MACS; i++) { - priv->r->get_l3_router_mac(i, &m); - if (free_mac < 0 && !m.valid) { - free_mac = i; - continue; - } - if (m.valid && m.mac == mac) { - free_mac = i; - break; - } - } - - if (free_mac < 0) { - pr_err("No free router MACs, cannot offload\n"); - mutex_unlock(&priv->reg_mutex); - return -1; - } - - m.valid = true; - m.mac = mac; - m.p_type = 0; /* An individual port, not a trunk port */ - m.p_id = 0x3f; /* Listen on any port */ - m.p_id_mask = 0; - m.vid = 0; /* Listen on any VLAN... */ - m.vid_mask = 0; /* ... so mask needs to be 0 */ - m.mac_mask = 0xffffffffffffULL; /* We want an exact match of the interface MAC */ - m.action = L3_FORWARD; /* Route the packet */ - priv->r->set_l3_router_mac(free_mac, &m); - - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -static int rtl83xx_alloc_egress_intf(struct rtl838x_switch_priv *priv, u64 mac, int vlan) -{ - int free_mac = -1; - struct rtl838x_l3_intf intf; - u64 m; - - mutex_lock(&priv->reg_mutex); - for (int i = 0; i < MAX_SMACS; i++) { - m = priv->r->get_l3_egress_mac(L3_EGRESS_DMACS + i); - if (free_mac < 0 && !m) { - free_mac = i; - continue; - } - if (m == mac) { - mutex_unlock(&priv->reg_mutex); - return i; - } - } - - if (free_mac < 0) { - pr_err("No free egress interface, cannot offload\n"); - return -1; - } - - /* Set up default egress interface 1 */ - intf.vid = vlan; - intf.smac_idx = free_mac; - intf.ip4_mtu_id = 1; - intf.ip6_mtu_id = 1; - intf.ttl_scope = 1; /* TTL */ - intf.hl_scope = 1; /* Hop Limit */ - intf.ip4_icmp_redirect = intf.ip6_icmp_redirect = 2; /* FORWARD */ - intf.ip4_pbr_icmp_redirect = intf.ip6_pbr_icmp_redirect = 2; /* FORWARD; */ - priv->r->set_l3_egress_intf(free_mac, &intf); - - priv->r->set_l3_egress_mac(L3_EGRESS_DMACS + free_mac, mac); - - mutex_unlock(&priv->reg_mutex); - - return free_mac; -} - -static int rtl83xx_fib4_add(struct rtl838x_switch_priv *priv, - struct fib_entry_notifier_info *info) -{ - struct fib_nh *nh = fib_info_nh(info->fi, 0); - struct net_device *dev = fib_info_nh(info->fi, 0)->fib_nh_dev; - int port; - struct rtl83xx_route *r; - bool to_localhost; - int vlan = is_vlan_dev(dev) ? vlan_dev_vlan_id(dev) : 0; - - pr_debug("In %s, ip %pI4, len %d\n", __func__, &info->dst, info->dst_len); - if (!info->dst) { - pr_info("Not offloading default route for now\n"); - return 0; - } - - pr_debug("GW: %pI4, interface name %s, mac %016llx, vlan %d\n", &nh->fib_nh_gw4, dev->name, - ether_addr_to_u64(dev->dev_addr), vlan - ); - - port = rtl83xx_port_dev_lower_find(dev, priv); - if (port < 0) - return -1; - - /* For now we only work with routes that have a gateway and are not ourself */ -/* if ((!nh->fib_nh_gw4) && (info->dst_len != 32)) */ -/* return 0; */ - - if ((info->dst & 0xff) == 0xff) - return 0; - - /* Do not offload routes to 192.168.100.x */ - if ((info->dst & 0xffffff00) == 0xc0a86400) - return 0; - - /* Do not offload routes to 127.x.x.x */ - if ((info->dst & 0xff000000) == 0x7f000000) - return 0; - - /* Allocate route or host-route (entry if hardware supports this) */ - if (info->dst_len == 32 && priv->r->host_route_write) - r = rtl83xx_host_route_alloc(priv, nh->fib_nh_gw4); - else - r = rtl83xx_route_alloc(priv, nh->fib_nh_gw4); - - if (!r) { - pr_err("%s: No more free route entries\n", __func__); - return -1; - } - - r->dst_ip = info->dst; - r->prefix_len = info->dst_len; - r->nh.rvid = vlan; - to_localhost = !nh->fib_nh_gw4; - - if (priv->r->set_l3_router_mac) { - u64 mac = ether_addr_to_u64(dev->dev_addr); - - pr_debug("Local route and router mac %016llx\n", mac); - - if (rtl83xx_alloc_router_mac(priv, mac)) - goto out_free_rt; - - /* vid = 0: Do not care about VID */ - r->nh.if_id = rtl83xx_alloc_egress_intf(priv, mac, vlan); - if (r->nh.if_id < 0) - goto out_free_rmac; - - if (to_localhost) { - int slot; - - r->nh.mac = mac; - r->nh.port = priv->port_ignore; - r->attr.valid = true; - r->attr.action = ROUTE_ACT_TRAP2CPU; - r->attr.type = 0; - - slot = priv->r->find_l3_slot(r, false); - pr_debug("%s: Got slot for route: %d\n", __func__, slot); - priv->r->host_route_write(slot, r); - } - } - - /* We need to resolve the mac address of the GW */ - if (!to_localhost) - rtl83xx_port_ipv4_resolve(priv, dev, nh->fib_nh_gw4); - - nh->fib_nh_flags |= RTNH_F_OFFLOAD; - - return 0; - -out_free_rmac: -out_free_rt: - return 0; -} - -static int rtl83xx_fib6_add(struct rtl838x_switch_priv *priv, - struct fib6_entry_notifier_info *info) -{ - pr_debug("In %s\n", __func__); -/* nh->fib_nh_flags |= RTNH_F_OFFLOAD; */ - - return 0; -} - -struct net_event_work { - struct work_struct work; - struct rtl838x_switch_priv *priv; - u64 mac; - u32 gw_addr; -}; - -static void rtl83xx_net_event_work_do(struct work_struct *work) -{ - struct net_event_work *net_work = - container_of(work, struct net_event_work, work); - struct rtl838x_switch_priv *priv = net_work->priv; - - rtl83xx_l3_nexthop_update(priv, net_work->gw_addr, net_work->mac); - - kfree(net_work); -} - -static int rtl83xx_netevent_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - struct rtl838x_switch_priv *priv; - struct net_device *dev; - struct neighbour *n = ptr; - int err, port; - struct net_event_work *net_work; - - priv = container_of(this, struct rtl838x_switch_priv, ne_nb); - - switch (event) { - case NETEVENT_NEIGH_UPDATE: - if (n->tbl != &arp_tbl) - return NOTIFY_DONE; - dev = n->dev; - port = rtl83xx_port_dev_lower_find(dev, priv); - if (port < 0 || !(n->nud_state & NUD_VALID)) { - pr_debug("%s: Neigbour invalid, not updating\n", __func__); - return NOTIFY_DONE; - } - - net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC); - if (!net_work) - return NOTIFY_BAD; - - INIT_WORK(&net_work->work, rtl83xx_net_event_work_do); - net_work->priv = priv; - - net_work->mac = ether_addr_to_u64(n->ha); - net_work->gw_addr = *(__be32 *) n->primary_key; - - pr_debug("%s: updating neighbour on port %d, mac %016llx\n", - __func__, port, net_work->mac); - schedule_work(&net_work->work); - if (err) - netdev_warn(dev, "failed to handle neigh update (err %d)\n", err); - break; - } - - return NOTIFY_DONE; -} - -struct rtl83xx_fib_event_work { - struct work_struct work; - union { - struct fib_entry_notifier_info fen_info; - struct fib6_entry_notifier_info fen6_info; - struct fib_rule_notifier_info fr_info; - }; - struct rtl838x_switch_priv *priv; - bool is_fib6; - unsigned long event; -}; - -static void rtl83xx_fib_event_work_do(struct work_struct *work) -{ - struct rtl83xx_fib_event_work *fib_work = - container_of(work, struct rtl83xx_fib_event_work, work); - struct rtl838x_switch_priv *priv = fib_work->priv; - struct fib_rule *rule; - int err; - - /* Protect internal structures from changes */ - rtnl_lock(); - pr_debug("%s: doing work, event %ld\n", __func__, fib_work->event); - switch (fib_work->event) { - case FIB_EVENT_ENTRY_ADD: - case FIB_EVENT_ENTRY_REPLACE: - case FIB_EVENT_ENTRY_APPEND: - if (fib_work->is_fib6) { - err = rtl83xx_fib6_add(priv, &fib_work->fen6_info); - } else { - err = rtl83xx_fib4_add(priv, &fib_work->fen_info); - fib_info_put(fib_work->fen_info.fi); - } - if (err) - pr_err("%s: FIB4 failed\n", __func__); - break; - case FIB_EVENT_ENTRY_DEL: - rtl83xx_fib4_del(priv, &fib_work->fen_info); - fib_info_put(fib_work->fen_info.fi); - break; - case FIB_EVENT_RULE_ADD: - case FIB_EVENT_RULE_DEL: - rule = fib_work->fr_info.rule; - if (!fib4_rule_default(rule)) - pr_err("%s: FIB4 default rule failed\n", __func__); - fib_rule_put(rule); - break; - } - rtnl_unlock(); - kfree(fib_work); -} - -/* Called with rcu_read_lock() */ -static int rtl83xx_fib_event(struct notifier_block *this, unsigned long event, void *ptr) -{ - struct fib_notifier_info *info = ptr; - struct rtl838x_switch_priv *priv; - struct rtl83xx_fib_event_work *fib_work; - - if ((info->family != AF_INET && info->family != AF_INET6 && - info->family != RTNL_FAMILY_IPMR && - info->family != RTNL_FAMILY_IP6MR)) - return NOTIFY_DONE; - - priv = container_of(this, struct rtl838x_switch_priv, fib_nb); - - fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC); - if (!fib_work) - return NOTIFY_BAD; - - INIT_WORK(&fib_work->work, rtl83xx_fib_event_work_do); - fib_work->priv = priv; - fib_work->event = event; - fib_work->is_fib6 = false; - - switch (event) { - case FIB_EVENT_ENTRY_ADD: - case FIB_EVENT_ENTRY_REPLACE: - case FIB_EVENT_ENTRY_APPEND: - case FIB_EVENT_ENTRY_DEL: - pr_debug("%s: FIB_ENTRY ADD/DEL, event %ld\n", __func__, event); - if (info->family == AF_INET) { - struct fib_entry_notifier_info *fen_info = ptr; - - if (fen_info->fi->fib_nh_is_v6) { - NL_SET_ERR_MSG_MOD(info->extack, - "IPv6 gateway with IPv4 route is not supported"); - kfree(fib_work); - return notifier_from_errno(-EINVAL); - } - - memcpy(&fib_work->fen_info, ptr, sizeof(fib_work->fen_info)); - /* Take referece on fib_info to prevent it from being - * freed while work is queued. Release it afterwards. - */ - fib_info_hold(fib_work->fen_info.fi); - - } else if (info->family == AF_INET6) { - //struct fib6_entry_notifier_info *fen6_info = ptr; - pr_warn("%s: FIB_RULE ADD/DEL for IPv6 not supported\n", __func__); - kfree(fib_work); - return NOTIFY_DONE; - } - break; - - case FIB_EVENT_RULE_ADD: - case FIB_EVENT_RULE_DEL: - pr_debug("%s: FIB_RULE ADD/DEL, event: %ld\n", __func__, event); - memcpy(&fib_work->fr_info, ptr, sizeof(fib_work->fr_info)); - fib_rule_get(fib_work->fr_info.rule); - break; - } - - schedule_work(&fib_work->work); - - return NOTIFY_DONE; -} - -static int __init rtl83xx_sw_probe(struct platform_device *pdev) -{ - int err = 0; - struct rtl838x_switch_priv *priv; - struct device *dev = &pdev->dev; - u64 bpdu_mask; - - pr_debug("Probing RTL838X switch device\n"); - if (!pdev->dev.of_node) { - dev_err(dev, "No DT found\n"); - return -EINVAL; - } - - /* Initialize access to RTL switch tables */ - rtl_table_init(); - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL); - - if (!priv->ds) - return -ENOMEM; - priv->ds->dev = dev; - priv->ds->priv = priv; - priv->ds->ops = &rtl83xx_switch_ops; - priv->ds->needs_standalone_vlan_filtering = true; - priv->dev = dev; - - mutex_init(&priv->reg_mutex); - - priv->family_id = soc_info.family; - priv->id = soc_info.id; - switch(soc_info.family) { - case RTL8380_FAMILY_ID: - priv->ds->ops = &rtl83xx_switch_ops; - priv->cpu_port = RTL838X_CPU_PORT; - priv->port_mask = 0x1f; - priv->port_width = 1; - priv->irq_mask = 0x0FFFFFFF; - priv->r = &rtl838x_reg; - priv->ds->num_ports = 29; - priv->fib_entries = 8192; - rtl8380_get_version(priv); - priv->n_lags = 8; - priv->l2_bucket_size = 4; - priv->n_pie_blocks = 12; - priv->port_ignore = 0x1f; - priv->n_counters = 128; - break; - case RTL8390_FAMILY_ID: - priv->ds->ops = &rtl83xx_switch_ops; - priv->cpu_port = RTL839X_CPU_PORT; - priv->port_mask = 0x3f; - priv->port_width = 2; - priv->irq_mask = 0xFFFFFFFFFFFFFULL; - priv->r = &rtl839x_reg; - priv->ds->num_ports = 53; - priv->fib_entries = 16384; - rtl8390_get_version(priv); - priv->n_lags = 16; - priv->l2_bucket_size = 4; - priv->n_pie_blocks = 18; - priv->port_ignore = 0x3f; - priv->n_counters = 1024; - break; - case RTL9300_FAMILY_ID: - priv->ds->ops = &rtl930x_switch_ops; - priv->cpu_port = RTL930X_CPU_PORT; - priv->port_mask = 0x1f; - priv->port_width = 1; - priv->irq_mask = 0x0FFFFFFF; - priv->r = &rtl930x_reg; - priv->ds->num_ports = 29; - priv->fib_entries = 16384; - priv->version = RTL8390_VERSION_A; - priv->n_lags = 16; - sw_w32(1, RTL930X_ST_CTRL); - priv->l2_bucket_size = 8; - priv->n_pie_blocks = 16; - priv->port_ignore = 0x3f; - priv->n_counters = 2048; - break; - case RTL9310_FAMILY_ID: - priv->ds->ops = &rtl930x_switch_ops; - priv->cpu_port = RTL931X_CPU_PORT; - priv->port_mask = 0x3f; - priv->port_width = 2; - priv->irq_mask = 0xFFFFFFFFFFFFFULL; - priv->r = &rtl931x_reg; - priv->ds->num_ports = 57; - priv->fib_entries = 16384; - priv->version = RTL8390_VERSION_A; - priv->n_lags = 16; - priv->l2_bucket_size = 8; - break; - } - pr_debug("Chip version %c\n", priv->version); - - err = rtl83xx_mdio_probe(priv); - if (err) { - /* Probing fails the 1st time because of missing ethernet driver - * initialization. Use this to disable traffic in case the bootloader left if on - */ - return err; - } - - err = dsa_register_switch(priv->ds); - if (err) { - dev_err(dev, "Error registering switch: %d\n", err); - return err; - } - - /* dsa_to_port returns dsa_port from the port list in - * dsa_switch_tree, the tree is built when the switch - * is registered by dsa_register_switch - */ - for (int i = 0; i <= priv->cpu_port; i++) - priv->ports[i].dp = dsa_to_port(priv->ds, i); - - /* Enable link and media change interrupts. Are the SERDES masks needed? */ - sw_w32_mask(0, 3, priv->r->isr_glb_src); - - priv->r->set_port_reg_le(priv->irq_mask, priv->r->isr_port_link_sts_chg); - priv->r->set_port_reg_le(priv->irq_mask, priv->r->imr_port_link_sts_chg); - - priv->link_state_irq = platform_get_irq(pdev, 0); - pr_info("LINK state irq: %d\n", priv->link_state_irq); - switch (priv->family_id) { - case RTL8380_FAMILY_ID: - err = request_irq(priv->link_state_irq, rtl838x_switch_irq, - IRQF_SHARED, "rtl838x-link-state", priv->ds); - break; - case RTL8390_FAMILY_ID: - err = request_irq(priv->link_state_irq, rtl839x_switch_irq, - IRQF_SHARED, "rtl839x-link-state", priv->ds); - break; - case RTL9300_FAMILY_ID: - err = request_irq(priv->link_state_irq, rtl930x_switch_irq, - IRQF_SHARED, "rtl930x-link-state", priv->ds); - break; - case RTL9310_FAMILY_ID: - err = request_irq(priv->link_state_irq, rtl931x_switch_irq, - IRQF_SHARED, "rtl931x-link-state", priv->ds); - break; - } - if (err) { - dev_err(dev, "Error setting up switch interrupt.\n"); - /* Need to free allocated switch here */ - } - - /* Enable interrupts for switch, on RTL931x, the IRQ is always on globally */ - if (soc_info.family != RTL9310_FAMILY_ID) - sw_w32(0x1, priv->r->imr_glb); - - rtl83xx_get_l2aging(priv); - - rtl83xx_setup_qos(priv); - - priv->r->l3_setup(priv); - - /* Clear all destination ports for mirror groups */ - for (int i = 0; i < 4; i++) - priv->mirror_group_ports[i] = -1; - - /* Register netdevice event callback to catch changes in link aggregation groups */ - priv->nb.notifier_call = rtl83xx_netdevice_event; - if (register_netdevice_notifier(&priv->nb)) { - priv->nb.notifier_call = NULL; - dev_err(dev, "Failed to register LAG netdev notifier\n"); - goto err_register_nb; - } - - /* Initialize hash table for L3 routing */ - rhltable_init(&priv->routes, &route_ht_params); - - /* Register netevent notifier callback to catch notifications about neighboring - * changes to update nexthop entries for L3 routing. - */ - priv->ne_nb.notifier_call = rtl83xx_netevent_event; - if (register_netevent_notifier(&priv->ne_nb)) { - priv->ne_nb.notifier_call = NULL; - dev_err(dev, "Failed to register netevent notifier\n"); - goto err_register_ne_nb; - } - - priv->fib_nb.notifier_call = rtl83xx_fib_event; - - /* Register Forwarding Information Base notifier to offload routes where - * where possible - * Only FIBs pointing to our own netdevs are programmed into - * the device, so no need to pass a callback. - */ - err = register_fib_notifier(&init_net, &priv->fib_nb, NULL, NULL); - if (err) - goto err_register_fib_nb; - - /* TODO: put this into l2_setup() */ - /* Flood BPDUs to all ports including cpu-port */ - if (soc_info.family != RTL9300_FAMILY_ID) { - bpdu_mask = soc_info.family == RTL8380_FAMILY_ID ? 0x1FFFFFFF : 0x1FFFFFFFFFFFFF; - priv->r->set_port_reg_be(bpdu_mask, priv->r->rma_bpdu_fld_pmask); - - /* TRAP 802.1X frames (EAPOL) to the CPU-Port, bypass STP and VLANs */ - sw_w32(7, priv->r->spcl_trap_eapol_ctrl); - - rtl838x_dbgfs_init(priv); - } else { - rtl930x_dbgfs_init(priv); - } - - return 0; - -err_register_fib_nb: - unregister_netevent_notifier(&priv->ne_nb); -err_register_ne_nb: - unregister_netdevice_notifier(&priv->nb); -err_register_nb: - return err; -} - -static int rtl83xx_sw_remove(struct platform_device *pdev) -{ - /* TODO: */ - pr_debug("Removing platform driver for rtl83xx-sw\n"); - - return 0; -} - -static const struct of_device_id rtl83xx_switch_of_ids[] = { - { .compatible = "realtek,rtl83xx-switch"}, - { /* sentinel */ } -}; - - -MODULE_DEVICE_TABLE(of, rtl83xx_switch_of_ids); - -static struct platform_driver rtl83xx_switch_driver = { - .probe = rtl83xx_sw_probe, - .remove = rtl83xx_sw_remove, - .driver = { - .name = "rtl83xx-switch", - .pm = NULL, - .of_match_table = rtl83xx_switch_of_ids, - }, -}; - -module_platform_driver(rtl83xx_switch_driver); - -MODULE_AUTHOR("B. Koblitz"); -MODULE_DESCRIPTION("RTL83XX SoC Switch Driver"); -MODULE_LICENSE("GPL"); diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/debugfs.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/debugfs.c deleted file mode 100644 index 92d6932dc55a44..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/debugfs.c +++ /dev/null @@ -1,719 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include - -#include "rtl83xx.h" - -#define RTL838X_DRIVER_NAME "rtl838x" - -#define RTL8390_LED_GLB_CTRL (0x00E4) -#define RTL8390_LED_SET_2_3_CTRL (0x00E8) -#define RTL8390_LED_SET_0_1_CTRL (0x00EC) -#define RTL8390_LED_COPR_SET_SEL_CTRL(p) (0x00F0 + (((p >> 4) << 2))) -#define RTL8390_LED_FIB_SET_SEL_CTRL(p) (0x0100 + (((p >> 4) << 2))) -#define RTL8390_LED_COPR_PMASK_CTRL(p) (0x0110 + (((p >> 5) << 2))) -#define RTL8390_LED_FIB_PMASK_CTRL(p) (0x00118 + (((p >> 5) << 2))) -#define RTL8390_LED_COMBO_CTRL(p) (0x0120 + (((p >> 5) << 2))) -#define RTL8390_LED_SW_CTRL (0x0128) -#define RTL8390_LED_SW_P_EN_CTRL(p) (0x012C + (((p / 10) << 2))) -#define RTL8390_LED_SW_P_CTRL(p) (0x0144 + (((p) << 2))) - -#define RTL838X_MIR_QID_CTRL(grp) (0xAD44 + (((grp) << 2))) -#define RTL838X_MIR_RSPAN_VLAN_CTRL(grp) (0xA340 + (((grp) << 2))) -#define RTL838X_MIR_RSPAN_VLAN_CTRL_MAC(grp) (0xAA70 + (((grp) << 2))) -#define RTL838X_MIR_RSPAN_TX_CTRL (0xA350) -#define RTL838X_MIR_RSPAN_TX_TAG_RM_CTRL (0xAA80) -#define RTL838X_MIR_RSPAN_TX_TAG_EN_CTRL (0xAA84) -#define RTL839X_MIR_RSPAN_VLAN_CTRL(grp) (0xA340 + (((grp) << 2))) -#define RTL839X_MIR_RSPAN_TX_CTRL (0x69b0) -#define RTL839X_MIR_RSPAN_TX_TAG_RM_CTRL (0x2550) -#define RTL839X_MIR_RSPAN_TX_TAG_EN_CTRL (0x2554) -#define RTL839X_MIR_SAMPLE_RATE_CTRL (0x2558) - -#define RTL838X_STAT_PRVTE_DROP_COUNTERS (0x6A00) -#define RTL839X_STAT_PRVTE_DROP_COUNTERS (0x3E00) -#define RTL930X_STAT_PRVTE_DROP_COUNTERS (0xB5B8) -#define RTL931X_STAT_PRVTE_DROP_COUNTERS (0xd800) - -int rtl83xx_port_get_stp_state(struct rtl838x_switch_priv *priv, int port); -void rtl83xx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state); -void rtl83xx_fast_age(struct dsa_switch *ds, int port); -u32 rtl838x_get_egress_rate(struct rtl838x_switch_priv *priv, int port); -u32 rtl839x_get_egress_rate(struct rtl838x_switch_priv *priv, int port); -int rtl838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate); -int rtl839x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate); - - -const char *rtl838x_drop_cntr[] = { - "ALE_TX_GOOD_PKTS", "MAC_RX_DROP", "ACL_FWD_DROP", "HW_ATTACK_PREVENTION_DROP", - "RMA_DROP", "VLAN_IGR_FLTR_DROP", "INNER_OUTER_CFI_EQUAL_1_DROP", "PORT_MOVE_DROP", - "NEW_SA_DROP", "MAC_LIMIT_SYS_DROP", "MAC_LIMIT_VLAN_DROP", "MAC_LIMIT_PORT_DROP", - "SWITCH_MAC_DROP", "ROUTING_EXCEPTION_DROP", "DA_LKMISS_DROP", "RSPAN_DROP", - "ACL_LKMISS_DROP", "ACL_DROP", "INBW_DROP", "IGR_METER_DROP", - "ACCEPT_FRAME_TYPE_DROP", "STP_IGR_DROP", "INVALID_SA_DROP", "SA_BLOCKING_DROP", - "DA_BLOCKING_DROP", "L2_INVALID_DPM_DROP", "MCST_INVALID_DPM_DROP", "RX_FLOW_CONTROL_DROP", - "STORM_SPPRS_DROP", "LALS_DROP", "VLAN_EGR_FILTER_DROP", "STP_EGR_DROP", - "SRC_PORT_FILTER_DROP", "PORT_ISOLATION_DROP", "ACL_FLTR_DROP", "MIRROR_FLTR_DROP", - "TX_MAX_DROP", "LINK_DOWN_DROP", "FLOW_CONTROL_DROP", "BRIDGE .1d discards" -}; - -const char *rtl839x_drop_cntr[] = { - "ALE_TX_GOOD_PKTS", "ERROR_PKTS", "EGR_ACL_DROP", "EGR_METER_DROP", - "OAM", "CFM" "VLAN_IGR_FLTR", "VLAN_ERR", - "INNER_OUTER_CFI_EQUAL_1", "VLAN_TAG_FORMAT", "SRC_PORT_SPENDING_TREE", "INBW", - "RMA", "HW_ATTACK_PREVENTION", "PROTO_STORM", "MCAST_SA", - "IGR_ACL_DROP", "IGR_METER_DROP", "DFLT_ACTION_FOR_MISS_ACL_AND_C2SC", "NEW_SA", - "PORT_MOVE", "SA_BLOCKING", "ROUTING_EXCEPTION", "SRC_PORT_SPENDING_TREE_NON_FWDING", - "MAC_LIMIT", "UNKNOW_STORM", "MISS_DROP", "CPU_MAC_DROP", - "DA_BLOCKING", "SRC_PORT_FILTER_BEFORE_EGR_ACL", "VLAN_EGR_FILTER", "SPANNING_TRE", - "PORT_ISOLATION", "OAM_EGRESS_DROP", "MIRROR_ISOLATION", "MAX_LEN_BEFORE_EGR_ACL", - "SRC_PORT_FILTER_BEFORE_MIRROR", "MAX_LEN_BEFORE_MIRROR", "SPECIAL_CONGEST_BEFORE_MIRROR", - "LINK_STATUS_BEFORE_MIRROR", - "WRED_BEFORE_MIRROR", "MAX_LEN_AFTER_MIRROR", "SPECIAL_CONGEST_AFTER_MIRROR", - "LINK_STATUS_AFTER_MIRROR", - "WRED_AFTER_MIRROR" -}; - -const char *rtl930x_drop_cntr[] = { - "OAM_PARSER", "UC_RPF", "DEI_CFI", "MAC_IP_SUBNET_BASED_VLAN", "VLAN_IGR_FILTER", - "L2_UC_MC", "IPV_IP6_MC_BRIDGE", "PTP", "USER_DEF_0_3", "RESERVED", - "RESERVED1", "RESERVED2", "BPDU_RMA", "LACP", "LLDP", - "EAPOL", "XX_RMA", "L3_IPUC_NON_IP", "IP4_IP6_HEADER_ERROR", "L3_BAD_IP", - "L3_DIP_DMAC_MISMATCH", "IP4_IP_OPTION", "IP_UC_MC_ROUTING_LOOK_UP_MISS", "L3_DST_NULL_INTF", - "L3_PBR_NULL_INTF", - "HOST_NULL_INTF", "ROUTE_NULL_INTF", "BRIDGING_ACTION", "ROUTING_ACTION", "IPMC_RPF", - "L2_NEXTHOP_AGE_OUT", "L3_UC_TTL_FAIL", "L3_MC_TTL_FAIL", "L3_UC_MTU_FAIL", "L3_MC_MTU_FAIL", - "L3_UC_ICMP_REDIR", "IP6_MLD_OTHER_ACT", "ND", "IP_MC_RESERVED", "IP6_HBH", - "INVALID_SA", "L2_HASH_FULL", "NEW_SA", "PORT_MOVE_FORBID", "STATIC_PORT_MOVING", - "DYNMIC_PORT_MOVING", "L3_CRC", "MAC_LIMIT", "ATTACK_PREVENT", "ACL_FWD_ACTION", - "OAMPDU", "OAM_MUX", "TRUNK_FILTER", "ACL_DROP", "IGR_BW", - "ACL_METER", "VLAN_ACCEPT_FRAME_TYPE", "MSTP_SRC_DROP_DISABLED_BLOCKING", "SA_BLOCK", "DA_BLOCK", - "STORM_CONTROL", "VLAN_EGR_FILTER", "MSTP_DESTINATION_DROP", "SRC_PORT_FILTER", "PORT_ISOLATION", - "TX_MAX_FRAME_SIZE", "EGR_LINK_STATUS", "MAC_TX_DISABLE", "MAC_PAUSE_FRAME", "MAC_RX_DROP", - "MIRROR_ISOLATE", "RX_FC", "EGR_QUEUE", "HSM_RUNOUT", "ROUTING_DISABLE", "INVALID_L2_NEXTHOP_ENTRY", - "L3_MC_SRC_FLT", "CPUTAG_FLT", "FWD_PMSK_NULL", "IPUC_ROUTING_LOOKUP_MISS", "MY_DEV_DROP", - "STACK_NONUC_BLOCKING_PMSK", "STACK_PORT_NOT_FOUND", "ACL_LOOPBACK_DROP", "IP6_ROUTING_EXT_HEADER" -}; - -const char *rtl931x_drop_cntr[] = { - "ALE_RX_GOOD_PKTS", "RX_MAX_FRAME_SIZE", "MAC_RX_DROP", "OPENFLOW_IP_MPLS_TTL", "OPENFLOW_TBL_MISS", - "IGR_BW", "SPECIAL_CONGEST", "EGR_QUEUE", "RESERVED", "EGR_LINK_STATUS", "STACK_UCAST_NONUCAST_TTL", /* 10 */ - "STACK_NONUC_BLOCKING_PMSK", "L2_CRC", "SRC_PORT_FILTER", "PARSER_PACKET_TOO_LONG", "PARSER_MALFORM_PACKET", - "MPLS_OVER_2_LBL", "EACL_METER", "IACL_METER", "PROTO_STORM", "INVALID_CAPWAP_HEADER", /* 20 */ - "MAC_IP_SUBNET_BASED_VLAN", "OAM_PARSER", "UC_MC_RPF", "IP_MAC_BINDING_MATCH_MISMATCH", "SA_BLOCK", - "TUNNEL_IP_ADDRESS_CHECK", "EACL_DROP", "IACL_DROP", "ATTACK_PREVENT", "SYSTEM_PORT_LIMIT_LEARN", /* 30 */ - "OAMPDU", "CCM_RX", "CFM_UNKNOWN_TYPE", "LBM_LBR_LTM_LTR", "Y_1731", "VLAN_LIMIT_LEARN", - "VLAN_ACCEPT_FRAME_TYPE", "CFI_1", "STATIC_DYNAMIC_PORT_MOVING", "PORT_MOVE_FORBID", /* 40 */ - "L3_CRC", "BPDU_PTP_LLDP_EAPOL_RMA", "MSTP_SRC_DROP_DISABLED_BLOCKING", "INVALID_SA", "NEW_SA", - "VLAN_IGR_FILTER", "IGR_VLAN_CONVERT", "GRATUITOUS_ARP", "MSTP_SRC_DROP", "L2_HASH_FULL", /* 50 */ - "MPLS_UNKNOWN_LBL", "L3_IPUC_NON_IP", "TTL", "MTU", "ICMP_REDIRECT", "STORM_CONTROL", "L3_DIP_DMAC_MISMATCH", - "IP4_IP_OPTION", "IP6_HBH_EXT_HEADER", "IP4_IP6_HEADER_ERROR", /* 60 */ - "ROUTING_IP_ADDR_CHECK", "ROUTING_EXCEPTION", "DA_BLOCK", "OAM_MUX", "PORT_ISOLATION", "VLAN_EGR_FILTER", - "MIRROR_ISOLATE", "MSTP_DESTINATION_DROP", "L2_MC_BRIDGE", "IP_UC_MC_ROUTING_LOOK_UP_MISS", /* 70 */ - "L2_UC", "L2_MC", "IP4_MC", "IP6_MC", "L3_UC_MC_ROUTE", "UNKNOWN_L2_UC_FLPM", "BC_FLPM", - "VLAN_PRO_UNKNOWN_L2_MC_FLPM", "VLAN_PRO_UNKNOWN_IP4_MC_FLPM", "VLAN_PROFILE_UNKNOWN_IP6_MC_FLPM", /* 80 */ -}; - -static ssize_t rtl838x_common_read(char __user *buffer, size_t count, - loff_t *ppos, unsigned int value) -{ - char *buf; - ssize_t len; - - if (*ppos != 0) - return 0; - - buf = kasprintf(GFP_KERNEL, "0x%08x\n", value); - if (!buf) - return -ENOMEM; - - if (count < strlen(buf)) { - kfree(buf); - return -ENOSPC; - } - - len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); - kfree(buf); - - return len; -} - -static ssize_t rtl838x_common_write(const char __user *buffer, size_t count, - loff_t *ppos, unsigned int *value) -{ - char b[32]; - ssize_t len; - int ret; - - if (*ppos != 0) - return -EINVAL; - - if (count >= sizeof(b)) - return -ENOSPC; - - len = simple_write_to_buffer(b, sizeof(b) - 1, ppos, - buffer, count); - if (len < 0) - return len; - - b[len] = '\0'; - ret = kstrtouint(b, 16, value); - if (ret) - return -EIO; - - return len; -} - -static ssize_t stp_state_read(struct file *filp, char __user *buffer, size_t count, - loff_t *ppos) -{ - struct rtl838x_port *p = filp->private_data; - struct dsa_switch *ds = p->dp->ds; - int value = rtl83xx_port_get_stp_state(ds->priv, p->dp->index); - - if (value < 0) - return -EINVAL; - - return rtl838x_common_read(buffer, count, ppos, (u32)value); -} - -static ssize_t stp_state_write(struct file *filp, const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct rtl838x_port *p = filp->private_data; - u32 value; - size_t res = rtl838x_common_write(buffer, count, ppos, &value); - if (res < 0) - return res; - - rtl83xx_port_stp_state_set(p->dp->ds, p->dp->index, (u8)value); - - return res; -} - -static const struct file_operations stp_state_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = stp_state_read, - .write = stp_state_write, -}; - -static ssize_t drop_counter_read(struct file *filp, char __user *buffer, size_t count, - loff_t *ppos) -{ - struct rtl838x_switch_priv *priv = filp->private_data; - const char **d; - u32 v; - char *buf; - int n = 0, len, offset; - int num; - - switch (priv->family_id) { - case RTL8380_FAMILY_ID: - d = rtl838x_drop_cntr; - offset = RTL838X_STAT_PRVTE_DROP_COUNTERS; - num = 40; - break; - case RTL8390_FAMILY_ID: - d = rtl839x_drop_cntr; - offset = RTL839X_STAT_PRVTE_DROP_COUNTERS; - num = 45; - break; - case RTL9300_FAMILY_ID: - d = rtl930x_drop_cntr; - offset = RTL930X_STAT_PRVTE_DROP_COUNTERS; - num = 85; - break; - case RTL9310_FAMILY_ID: - d = rtl931x_drop_cntr; - offset = RTL931X_STAT_PRVTE_DROP_COUNTERS; - num = 81; - break; - } - - buf = kmalloc(30 * num, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - for (int i = 0; i < num; i++) { - v = sw_r32(offset + (i << 2)) & 0xffff; - n += sprintf(buf + n, "%s: %d\n", d[i], v); - } - - if (count < strlen(buf)) { - kfree(buf); - return -ENOSPC; - } - - len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); - kfree(buf); - - return len; -} - -static const struct file_operations drop_counter_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = drop_counter_read, -}; - -static void l2_table_print_entry(struct seq_file *m, struct rtl838x_switch_priv *priv, - struct rtl838x_l2_entry *e) -{ - u64 portmask; - - if (e->type == L2_UNICAST) { - seq_puts(m, "L2_UNICAST\n"); - - seq_printf(m, " mac %02x:%02x:%02x:%02x:%02x:%02x vid %u rvid %u\n", - e->mac[0], e->mac[1], e->mac[2], e->mac[3], e->mac[4], e->mac[5], - e->vid, e->rvid); - - seq_printf(m, " port %d age %d", e->port, e->age); - if (e->is_static) - seq_puts(m, " static"); - if (e->block_da) - seq_puts(m, " block_da"); - if (e->block_sa) - seq_puts(m, " block_sa"); - if (e->suspended) - seq_puts(m, " suspended"); - if (e->next_hop) - seq_printf(m, " next_hop route_id %u", e->nh_route_id); - seq_puts(m, "\n"); - - } else { - if (e->type == L2_MULTICAST) { - seq_puts(m, "L2_MULTICAST\n"); - - seq_printf(m, " mac %02x:%02x:%02x:%02x:%02x:%02x vid %u rvid %u\n", - e->mac[0], e->mac[1], e->mac[2], e->mac[3], e->mac[4], e->mac[5], - e->vid, e->rvid); - } - - if (e->type == IP4_MULTICAST || e->type == IP6_MULTICAST) { - seq_puts(m, (e->type == IP4_MULTICAST) ? - "IP4_MULTICAST\n" : "IP6_MULTICAST\n"); - - seq_printf(m, " gip %08x sip %08x vid %u rvid %u\n", - e->mc_gip, e->mc_sip, e->vid, e->rvid); - } - - portmask = priv->r->read_mcast_pmask(e->mc_portmask_index); - seq_printf(m, " index %u ports", e->mc_portmask_index); - for (int i = 0; i < 64; i++) { - if (portmask & BIT_ULL(i)) - seq_printf(m, " %d", i); - } - seq_puts(m, "\n"); - } - - seq_puts(m, "\n"); -} - -static int l2_table_show(struct seq_file *m, void *v) -{ - struct rtl838x_switch_priv *priv = m->private; - struct rtl838x_l2_entry e; - int bucket, index; - - mutex_lock(&priv->reg_mutex); - - for (int i = 0; i < priv->fib_entries; i++) { - bucket = i >> 2; - index = i & 0x3; - priv->r->read_l2_entry_using_hash(bucket, index, &e); - - if (!e.valid) - continue; - - seq_printf(m, "Hash table bucket %d index %d ", bucket, index); - l2_table_print_entry(m, priv, &e); - - if (!((i + 1) % 64)) - cond_resched(); - } - - for (int i = 0; i < 64; i++) { - priv->r->read_cam(i, &e); - - if (!e.valid) - continue; - - seq_printf(m, "CAM index %d ", i); - l2_table_print_entry(m, priv, &e); - } - - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -static int l2_table_open(struct inode *inode, struct file *filp) -{ - return single_open(filp, l2_table_show, inode->i_private); -} - -static const struct file_operations l2_table_fops = { - .owner = THIS_MODULE, - .open = l2_table_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static ssize_t age_out_read(struct file *filp, char __user *buffer, size_t count, - loff_t *ppos) -{ - struct rtl838x_port *p = filp->private_data; - struct dsa_switch *ds = p->dp->ds; - struct rtl838x_switch_priv *priv = ds->priv; - int value = sw_r32(priv->r->l2_port_aging_out); - - if (value < 0) - return -EINVAL; - - return rtl838x_common_read(buffer, count, ppos, (u32)value); -} - -static ssize_t age_out_write(struct file *filp, const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct rtl838x_port *p = filp->private_data; - u32 value; - size_t res = rtl838x_common_write(buffer, count, ppos, &value); - if (res < 0) - return res; - - rtl83xx_fast_age(p->dp->ds, p->dp->index); - - return res; -} - -static const struct file_operations age_out_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = age_out_read, - .write = age_out_write, -}; - -static ssize_t port_egress_rate_read(struct file *filp, char __user *buffer, size_t count, - loff_t *ppos) -{ - struct rtl838x_port *p = filp->private_data; - struct dsa_switch *ds = p->dp->ds; - struct rtl838x_switch_priv *priv = ds->priv; - int value; - if (priv->family_id == RTL8380_FAMILY_ID) - value = rtl838x_get_egress_rate(priv, p->dp->index); - else - value = rtl839x_get_egress_rate(priv, p->dp->index); - - if (value < 0) - return -EINVAL; - - return rtl838x_common_read(buffer, count, ppos, (u32)value); -} - -static ssize_t port_egress_rate_write(struct file *filp, const char __user *buffer, - size_t count, loff_t *ppos) -{ - struct rtl838x_port *p = filp->private_data; - struct dsa_switch *ds = p->dp->ds; - struct rtl838x_switch_priv *priv = ds->priv; - u32 value; - size_t res = rtl838x_common_write(buffer, count, ppos, &value); - if (res < 0) - return res; - - if (priv->family_id == RTL8380_FAMILY_ID) - rtl838x_set_egress_rate(priv, p->dp->index, value); - else - rtl839x_set_egress_rate(priv, p->dp->index, value); - - return res; -} - -static const struct file_operations port_egress_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = port_egress_rate_read, - .write = port_egress_rate_write, -}; - - -static const struct debugfs_reg32 port_ctrl_regs[] = { - { .name = "port_isolation", .offset = RTL838X_PORT_ISO_CTRL(0), }, - { .name = "mac_force_mode", .offset = RTL838X_MAC_FORCE_MODE_CTRL, }, -}; - -void rtl838x_dbgfs_cleanup(struct rtl838x_switch_priv *priv) -{ - debugfs_remove_recursive(priv->dbgfs_dir); - -/* kfree(priv->dbgfs_entries); */ -} - -static int rtl838x_dbgfs_port_init(struct dentry *parent, struct rtl838x_switch_priv *priv, - int port) -{ - struct dentry *port_dir; - struct debugfs_regset32 *port_ctrl_regset; - - port_dir = debugfs_create_dir(priv->ports[port].dp->name, parent); - - if (priv->family_id == RTL8380_FAMILY_ID) { - debugfs_create_x32("storm_rate_uc", 0644, port_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_STORM_CTRL_PORT_UC(port))); - - debugfs_create_x32("storm_rate_mc", 0644, port_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_STORM_CTRL_PORT_MC(port))); - - debugfs_create_x32("storm_rate_bc", 0644, port_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_STORM_CTRL_PORT_BC(port))); - } else { - debugfs_create_x32("storm_rate_uc", 0644, port_dir, - (u32 *)(RTL838X_SW_BASE + RTL839X_STORM_CTRL_PORT_UC_0(port))); - - debugfs_create_x32("storm_rate_mc", 0644, port_dir, - (u32 *)(RTL838X_SW_BASE + RTL839X_STORM_CTRL_PORT_MC_0(port))); - - debugfs_create_x32("storm_rate_bc", 0644, port_dir, - (u32 *)(RTL838X_SW_BASE + RTL839X_STORM_CTRL_PORT_BC_0(port))); - } - - debugfs_create_u32("id", 0444, port_dir, (u32 *)&priv->ports[port].dp->index); - - port_ctrl_regset = devm_kzalloc(priv->dev, sizeof(*port_ctrl_regset), GFP_KERNEL); - if (!port_ctrl_regset) - return -ENOMEM; - - port_ctrl_regset->regs = port_ctrl_regs; - port_ctrl_regset->nregs = ARRAY_SIZE(port_ctrl_regs); - port_ctrl_regset->base = (void *)(RTL838X_SW_BASE + (port << 2)); - debugfs_create_regset32("port_ctrl", 0400, port_dir, port_ctrl_regset); - - debugfs_create_file("stp_state", 0600, port_dir, &priv->ports[port], &stp_state_fops); - debugfs_create_file("age_out", 0600, port_dir, &priv->ports[port], &age_out_fops); - debugfs_create_file("port_egress_rate", 0600, port_dir, &priv->ports[port], - &port_egress_fops); - return 0; -} - -static int rtl838x_dbgfs_leds(struct dentry *parent, struct rtl838x_switch_priv *priv) -{ - struct dentry *led_dir; - - led_dir = debugfs_create_dir("led", parent); - - if (priv->family_id == RTL8380_FAMILY_ID) { - debugfs_create_x32("led_glb_ctrl", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_LED_GLB_CTRL)); - debugfs_create_x32("led_mode_sel", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_LED_MODE_SEL)); - debugfs_create_x32("led_mode_ctrl", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_LED_MODE_CTRL)); - debugfs_create_x32("led_p_en_ctrl", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_LED_P_EN_CTRL)); - debugfs_create_x32("led_sw_ctrl", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_LED_SW_CTRL)); - debugfs_create_x32("led0_sw_p_en_ctrl", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_LED0_SW_P_EN_CTRL)); - debugfs_create_x32("led1_sw_p_en_ctrl", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_LED1_SW_P_EN_CTRL)); - debugfs_create_x32("led2_sw_p_en_ctrl", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_LED2_SW_P_EN_CTRL)); - for (int p = 0; p < 28; p++) { - char led_sw_p_ctrl_name[20]; - - snprintf(led_sw_p_ctrl_name, sizeof(led_sw_p_ctrl_name), - "led_sw_p_ctrl.%02d", p); - debugfs_create_x32(led_sw_p_ctrl_name, 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_LED_SW_P_CTRL_PORT(p))); - } - } else if (priv->family_id == RTL8390_FAMILY_ID) { - char port_led_name[20]; - - debugfs_create_x32("led_glb_ctrl", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_GLB_CTRL)); - debugfs_create_x32("led_set_2_3", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_SET_2_3_CTRL)); - debugfs_create_x32("led_set_0_1", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_SET_0_1_CTRL)); - for (int p = 0; p < 4; p++) { - snprintf(port_led_name, sizeof(port_led_name), "led_copr_set_sel.%1d", p); - debugfs_create_x32(port_led_name, 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_COPR_SET_SEL_CTRL(p << 4))); - snprintf(port_led_name, sizeof(port_led_name), "led_fib_set_sel.%1d", p); - debugfs_create_x32(port_led_name, 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_FIB_SET_SEL_CTRL(p << 4))); - } - debugfs_create_x32("led_copr_pmask_ctrl_0", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_COPR_PMASK_CTRL(0))); - debugfs_create_x32("led_copr_pmask_ctrl_1", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_COPR_PMASK_CTRL(32))); - debugfs_create_x32("led_fib_pmask_ctrl_0", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_FIB_PMASK_CTRL(0))); - debugfs_create_x32("led_fib_pmask_ctrl_1", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_FIB_PMASK_CTRL(32))); - debugfs_create_x32("led_combo_ctrl_0", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_COMBO_CTRL(0))); - debugfs_create_x32("led_combo_ctrl_1", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_COMBO_CTRL(32))); - debugfs_create_x32("led_sw_ctrl", 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_SW_CTRL)); - for (int p = 0; p < 5; p++) { - snprintf(port_led_name, sizeof(port_led_name), "led_sw_p_en_ctrl.%1d", p); - debugfs_create_x32(port_led_name, 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_SW_P_EN_CTRL(p * 10))); - } - for (int p = 0; p < 28; p++) { - snprintf(port_led_name, sizeof(port_led_name), "led_sw_p_ctrl.%02d", p); - debugfs_create_x32(port_led_name, 0644, led_dir, - (u32 *)(RTL838X_SW_BASE + RTL8390_LED_SW_P_CTRL(p))); - } - } - return 0; -} - -void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv) -{ - struct dentry *rtl838x_dir; - struct dentry *port_dir; - struct dentry *mirror_dir; - struct debugfs_regset32 *port_ctrl_regset; - int ret; - char lag_name[10]; - char mirror_name[10]; - - pr_info("%s called\n", __func__); - rtl838x_dir = debugfs_lookup(RTL838X_DRIVER_NAME, NULL); - if (!rtl838x_dir) - rtl838x_dir = debugfs_create_dir(RTL838X_DRIVER_NAME, NULL); - - priv->dbgfs_dir = rtl838x_dir; - - debugfs_create_x32("soc", 0444, rtl838x_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_MODEL_NAME_INFO)); - - /* Create one directory per port */ - for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) { - ret = rtl838x_dbgfs_port_init(rtl838x_dir, priv, i); - if (ret) - goto err; - } - } - - /* Create directory for CPU-port */ - port_dir = debugfs_create_dir("cpu_port", rtl838x_dir); - port_ctrl_regset = devm_kzalloc(priv->dev, sizeof(*port_ctrl_regset), GFP_KERNEL); - if (!port_ctrl_regset) { - ret = -ENOMEM; - goto err; - } - - port_ctrl_regset->regs = port_ctrl_regs; - port_ctrl_regset->nregs = ARRAY_SIZE(port_ctrl_regs); - port_ctrl_regset->base = (void *)(RTL838X_SW_BASE + (priv->cpu_port << 2)); - debugfs_create_regset32("port_ctrl", 0400, port_dir, port_ctrl_regset); - debugfs_create_u8("id", 0444, port_dir, &priv->cpu_port); - - /* Create entries for LAGs */ - for (int i = 0; i < priv->n_lags; i++) { - snprintf(lag_name, sizeof(lag_name), "lag.%02d", i); - if (priv->family_id == RTL8380_FAMILY_ID) - debugfs_create_x32(lag_name, 0644, rtl838x_dir, - (u32 *)(RTL838X_SW_BASE + priv->r->trk_mbr_ctr(i))); - else - debugfs_create_x64(lag_name, 0644, rtl838x_dir, - (u64 *)(RTL838X_SW_BASE + priv->r->trk_mbr_ctr(i))); - } - - /* Create directories for mirror groups */ - for (int i = 0; i < 4; i++) { - snprintf(mirror_name, sizeof(mirror_name), "mirror.%1d", i); - mirror_dir = debugfs_create_dir(mirror_name, rtl838x_dir); - if (priv->family_id == RTL8380_FAMILY_ID) { - debugfs_create_x32("ctrl", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_CTRL + i * 4)); - debugfs_create_x32("ingress_pm", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + priv->r->mir_spm + i * 4)); - debugfs_create_x32("egress_pm", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + priv->r->mir_dpm + i * 4)); - debugfs_create_x32("qid", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_QID_CTRL(i))); - debugfs_create_x32("rspan_vlan", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_RSPAN_VLAN_CTRL(i))); - debugfs_create_x32("rspan_vlan_mac", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_RSPAN_VLAN_CTRL_MAC(i))); - debugfs_create_x32("rspan_tx", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_RSPAN_TX_CTRL)); - debugfs_create_x32("rspan_tx_tag_rm", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_RSPAN_TX_TAG_RM_CTRL)); - debugfs_create_x32("rspan_tx_tag_en", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_RSPAN_TX_TAG_EN_CTRL)); - } else { - debugfs_create_x32("ctrl", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_CTRL + i * 4)); - debugfs_create_x64("ingress_pm", 0644, mirror_dir, - (u64 *)(RTL838X_SW_BASE + priv->r->mir_spm + i * 8)); - debugfs_create_x64("egress_pm", 0644, mirror_dir, - (u64 *)(RTL838X_SW_BASE + priv->r->mir_dpm + i * 8)); - debugfs_create_x32("rspan_vlan", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_RSPAN_VLAN_CTRL(i))); - debugfs_create_x32("rspan_tx", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_RSPAN_TX_CTRL)); - debugfs_create_x32("rspan_tx_tag_rm", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_RSPAN_TX_TAG_RM_CTRL)); - debugfs_create_x32("rspan_tx_tag_en", 0644, mirror_dir, - (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_RSPAN_TX_TAG_EN_CTRL)); - debugfs_create_x64("sample_rate", 0644, mirror_dir, - (u64 *)(RTL838X_SW_BASE + RTL839X_MIR_SAMPLE_RATE_CTRL)); - } - } - - if (priv->family_id == RTL8380_FAMILY_ID) - debugfs_create_x32("bpdu_flood_mask", 0644, rtl838x_dir, - (u32 *)(RTL838X_SW_BASE + priv->r->rma_bpdu_fld_pmask)); - else - debugfs_create_x64("bpdu_flood_mask", 0644, rtl838x_dir, - (u64 *)(RTL838X_SW_BASE + priv->r->rma_bpdu_fld_pmask)); - - if (priv->family_id == RTL8380_FAMILY_ID) - debugfs_create_x32("vlan_ctrl", 0644, rtl838x_dir, - (u32 *)(RTL838X_SW_BASE + RTL838X_VLAN_CTRL)); - else - debugfs_create_x32("vlan_ctrl", 0644, rtl838x_dir, - (u32 *)(RTL838X_SW_BASE + RTL839X_VLAN_CTRL)); - - ret = rtl838x_dbgfs_leds(rtl838x_dir, priv); - if (ret) - goto err; - - debugfs_create_file("drop_counters", 0400, rtl838x_dir, priv, &drop_counter_fops); - - debugfs_create_file("l2_table", 0400, rtl838x_dir, priv, &l2_table_fops); - - return; -err: - rtl838x_dbgfs_cleanup(priv); -} - -void rtl930x_dbgfs_init(struct rtl838x_switch_priv *priv) -{ - struct dentry *dbg_dir; - - pr_info("%s called\n", __func__); - dbg_dir = debugfs_lookup(RTL838X_DRIVER_NAME, NULL); - if (!dbg_dir) - dbg_dir = debugfs_create_dir(RTL838X_DRIVER_NAME, NULL); - - priv->dbgfs_dir = dbg_dir; - - debugfs_create_file("drop_counters", 0400, dbg_dir, priv, &drop_counter_fops); - - debugfs_create_file("l2_table", 0400, dbg_dir, priv, &l2_table_fops); -} diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c deleted file mode 100644 index ee87de8e0784f6..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/dsa.c +++ /dev/null @@ -1,2237 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include -#include - -#include "rtl83xx.h" - -extern struct rtl83xx_soc_info soc_info; - -static void rtl83xx_init_stats(struct rtl838x_switch_priv *priv) -{ - mutex_lock(&priv->reg_mutex); - - /* Enable statistics module: all counters plus debug. - * On RTL839x all counters are enabled by default - */ - if (priv->family_id == RTL8380_FAMILY_ID) - sw_w32_mask(0, 3, RTL838X_STAT_CTRL); - - /* Reset statistics counters */ - sw_w32_mask(0, 1, priv->r->stat_rst); - - mutex_unlock(&priv->reg_mutex); -} - -static void rtl83xx_enable_phy_polling(struct rtl838x_switch_priv *priv) -{ - u64 v = 0; - - msleep(1000); - /* Enable all ports with a PHY, including the SFP-ports */ - for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) - v |= BIT_ULL(i); - } - - pr_info("%s: %16llx\n", __func__, v); - priv->r->set_port_reg_le(v, priv->r->smi_poll_ctrl); - - /* PHY update complete, there is no global PHY polling enable bit on the 9300 */ - if (priv->family_id == RTL8390_FAMILY_ID) - sw_w32_mask(0, BIT(7), RTL839X_SMI_GLB_CTRL); - else if(priv->family_id == RTL9300_FAMILY_ID) - sw_w32_mask(0, 0x8000, RTL838X_SMI_GLB_CTRL); -} - -const struct rtl83xx_mib_desc rtl83xx_mib[] = { - MIB_DESC(2, 0xf8, "ifInOctets"), - MIB_DESC(2, 0xf0, "ifOutOctets"), - MIB_DESC(1, 0xec, "dot1dTpPortInDiscards"), - MIB_DESC(1, 0xe8, "ifInUcastPkts"), - MIB_DESC(1, 0xe4, "ifInMulticastPkts"), - MIB_DESC(1, 0xe0, "ifInBroadcastPkts"), - MIB_DESC(1, 0xdc, "ifOutUcastPkts"), - MIB_DESC(1, 0xd8, "ifOutMulticastPkts"), - MIB_DESC(1, 0xd4, "ifOutBroadcastPkts"), - MIB_DESC(1, 0xd0, "ifOutDiscards"), - MIB_DESC(1, 0xcc, ".3SingleCollisionFrames"), - MIB_DESC(1, 0xc8, ".3MultipleCollisionFrames"), - MIB_DESC(1, 0xc4, ".3DeferredTransmissions"), - MIB_DESC(1, 0xc0, ".3LateCollisions"), - MIB_DESC(1, 0xbc, ".3ExcessiveCollisions"), - MIB_DESC(1, 0xb8, ".3SymbolErrors"), - MIB_DESC(1, 0xb4, ".3ControlInUnknownOpcodes"), - MIB_DESC(1, 0xb0, ".3InPauseFrames"), - MIB_DESC(1, 0xac, ".3OutPauseFrames"), - MIB_DESC(1, 0xa8, "DropEvents"), - MIB_DESC(1, 0xa4, "tx_BroadcastPkts"), - MIB_DESC(1, 0xa0, "tx_MulticastPkts"), - MIB_DESC(1, 0x9c, "CRCAlignErrors"), - MIB_DESC(1, 0x98, "tx_UndersizePkts"), - MIB_DESC(1, 0x94, "rx_UndersizePkts"), - MIB_DESC(1, 0x90, "rx_UndersizedropPkts"), - MIB_DESC(1, 0x8c, "tx_OversizePkts"), - MIB_DESC(1, 0x88, "rx_OversizePkts"), - MIB_DESC(1, 0x84, "Fragments"), - MIB_DESC(1, 0x80, "Jabbers"), - MIB_DESC(1, 0x7c, "Collisions"), - MIB_DESC(1, 0x78, "tx_Pkts64Octets"), - MIB_DESC(1, 0x74, "rx_Pkts64Octets"), - MIB_DESC(1, 0x70, "tx_Pkts65to127Octets"), - MIB_DESC(1, 0x6c, "rx_Pkts65to127Octets"), - MIB_DESC(1, 0x68, "tx_Pkts128to255Octets"), - MIB_DESC(1, 0x64, "rx_Pkts128to255Octets"), - MIB_DESC(1, 0x60, "tx_Pkts256to511Octets"), - MIB_DESC(1, 0x5c, "rx_Pkts256to511Octets"), - MIB_DESC(1, 0x58, "tx_Pkts512to1023Octets"), - MIB_DESC(1, 0x54, "rx_Pkts512to1023Octets"), - MIB_DESC(1, 0x50, "tx_Pkts1024to1518Octets"), - MIB_DESC(1, 0x4c, "rx_StatsPkts1024to1518Octets"), - MIB_DESC(1, 0x48, "tx_Pkts1519toMaxOctets"), - MIB_DESC(1, 0x44, "rx_Pkts1519toMaxOctets"), - MIB_DESC(1, 0x40, "rxMacDiscards") -}; - - -/* DSA callbacks */ - - -static enum dsa_tag_protocol rtl83xx_get_tag_protocol(struct dsa_switch *ds, - int port, - enum dsa_tag_protocol mprot) -{ - /* The switch does not tag the frames, instead internally the header - * structure for each packet is tagged accordingly. - */ - return DSA_TAG_PROTO_TRAILER; -} - -static void rtl83xx_vlan_set_pvid(struct rtl838x_switch_priv *priv, - int port, int pvid) -{ - /* Set both inner and outer PVID of the port */ - priv->r->vlan_port_pvid_set(port, PBVLAN_TYPE_INNER, pvid); - priv->r->vlan_port_pvid_set(port, PBVLAN_TYPE_OUTER, pvid); - priv->r->vlan_port_pvidmode_set(port, PBVLAN_TYPE_INNER, - PBVLAN_MODE_UNTAG_AND_PRITAG); - priv->r->vlan_port_pvidmode_set(port, PBVLAN_TYPE_OUTER, - PBVLAN_MODE_UNTAG_AND_PRITAG); - - priv->ports[port].pvid = pvid; -} - -/* Initialize all VLANS */ -static void rtl83xx_vlan_setup(struct rtl838x_switch_priv *priv) -{ - struct rtl838x_vlan_info info; - - pr_info("In %s\n", __func__); - - priv->r->vlan_profile_setup(0); - priv->r->vlan_profile_setup(1); - pr_info("UNKNOWN_MC_PMASK: %016llx\n", priv->r->read_mcast_pmask(UNKNOWN_MC_PMASK)); - priv->r->vlan_profile_dump(0); - - info.fid = 0; /* Default Forwarding ID / MSTI */ - info.hash_uc_fid = false; /* Do not build the L2 lookup hash with FID, but VID */ - info.hash_mc_fid = false; /* Do the same for Multicast packets */ - info.profile_id = 0; /* Use default Vlan Profile 0 */ - info.tagged_ports = 0; /* Initially no port members */ - if (priv->family_id == RTL9310_FAMILY_ID) { - info.if_id = 0; - info.multicast_grp_mask = 0; - info.l2_tunnel_list_id = -1; - } - - /* Initialize normal VLANs 1-4095 */ - for (int i = 1; i < MAX_VLANS; i ++) - priv->r->vlan_set_tagged(i, &info); - - /* - * Initialize the special VLAN 0 and reset PVIDs. The CPU port PVID - * is applied to packets from the CPU for untagged destinations, - * regardless if the actual ingress VID. Any port with untagged - * egress VLAN(s) must therefore be a member of VLAN 0 to support - * CPU port as ingress when VLAN filtering is enabled. - */ - for (int i = 0; i <= priv->cpu_port; i++) { - rtl83xx_vlan_set_pvid(priv, i, 0); - info.tagged_ports |= BIT_ULL(i); - } - priv->r->vlan_set_tagged(0, &info); - - /* Set forwarding action based on inner VLAN tag */ - for (int i = 0; i < priv->cpu_port; i++) - priv->r->vlan_fwd_on_inner(i, true); -} - -static void rtl83xx_setup_bpdu_traps(struct rtl838x_switch_priv *priv) -{ - for (int i = 0; i < priv->cpu_port; i++) - priv->r->set_receive_management_action(i, BPDU, TRAP2CPU); -} - -static void rtl83xx_setup_lldp_traps(struct rtl838x_switch_priv *priv) -{ - for (int i = 0; i < priv->cpu_port; i++) - priv->r->set_receive_management_action(i, LLDP, TRAP2CPU); -} - -static void rtl83xx_port_set_salrn(struct rtl838x_switch_priv *priv, - int port, bool enable) -{ - int shift = SALRN_PORT_SHIFT(port); - int val = enable ? SALRN_MODE_HARDWARE : SALRN_MODE_DISABLED; - - sw_w32_mask(SALRN_MODE_MASK << shift, val << shift, - priv->r->l2_port_new_salrn(port)); -} - -static int rtl83xx_setup(struct dsa_switch *ds) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - pr_debug("%s called\n", __func__); - - /* Disable MAC polling the PHY so that we can start configuration */ - priv->r->set_port_reg_le(0ULL, priv->r->smi_poll_ctrl); - - for (int i = 0; i < ds->num_ports; i++) - priv->ports[i].enable = false; - priv->ports[priv->cpu_port].enable = true; - - /* Configure ports so they are disabled by default, but once enabled - * they will work in isolated mode (only traffic between port and CPU). - */ - for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) { - priv->ports[i].pm = BIT_ULL(priv->cpu_port); - priv->r->traffic_set(i, BIT_ULL(i)); - } - } - priv->r->traffic_set(priv->cpu_port, BIT_ULL(priv->cpu_port)); - - /* For standalone ports, forward packets even if a static fdb - * entry for the source address exists on another port. - */ - if (priv->r->set_static_move_action) { - for (int i = 0; i <= priv->cpu_port; i++) - priv->r->set_static_move_action(i, true); - } - - if (priv->family_id == RTL8380_FAMILY_ID) - rtl838x_print_matrix(); - else - rtl839x_print_matrix(); - - rtl83xx_init_stats(priv); - - rtl83xx_vlan_setup(priv); - - rtl83xx_setup_bpdu_traps(priv); - rtl83xx_setup_lldp_traps(priv); - - ds->configure_vlan_while_not_filtering = true; - - priv->r->l2_learning_setup(); - - rtl83xx_port_set_salrn(priv, priv->cpu_port, false); - ds->assisted_learning_on_cpu_port = true; - - /* 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 */ - rtl83xx_enable_phy_polling(priv); - pr_debug("Please wait until PHY is settled\n"); - msleep(1000); - priv->r->pie_init(priv); - - return 0; -} - -static int rtl93xx_setup(struct dsa_switch *ds) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - pr_info("%s called\n", __func__); - - /* Disable MAC polling the PHY so that we can start configuration */ - if (priv->family_id == RTL9300_FAMILY_ID) - sw_w32(0, RTL930X_SMI_POLL_CTRL); - - if (priv->family_id == RTL9310_FAMILY_ID) { - sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL); - sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL + 4); - } - - /* Disable all ports except CPU port */ - for (int i = 0; i < ds->num_ports; i++) - priv->ports[i].enable = false; - priv->ports[priv->cpu_port].enable = true; - - /* Configure ports so they are disabled by default, but once enabled - * they will work in isolated mode (only traffic between port and CPU). - */ - for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) { - priv->ports[i].pm = BIT_ULL(priv->cpu_port); - priv->r->traffic_set(i, BIT_ULL(i)); - } - } - priv->r->traffic_set(priv->cpu_port, BIT_ULL(priv->cpu_port)); - - rtl930x_print_matrix(); - - /* TODO: Initialize statistics */ - - rtl83xx_vlan_setup(priv); - - ds->configure_vlan_while_not_filtering = true; - - priv->r->l2_learning_setup(); - - rtl83xx_port_set_salrn(priv, priv->cpu_port, false); - ds->assisted_learning_on_cpu_port = true; - - rtl83xx_enable_phy_polling(priv); - - priv->r->pie_init(priv); - - priv->r->led_init(priv); - - return 0; -} - -static int rtl93xx_get_sds(struct phy_device *phydev) -{ - struct device *dev = &phydev->mdio.dev; - struct device_node *dn; - u32 sds_num; - - if (!dev) - return -1; - if (dev->of_node) { - dn = dev->of_node; - if (of_property_read_u32(dn, "sds", &sds_num)) - sds_num = -1; - } else { - dev_err(dev, "No DT node.\n"); - return -1; - } - - return sds_num; -} - -static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port, - unsigned long *supported, - struct phylink_link_state *state) -{ - struct rtl838x_switch_priv *priv = ds->priv; - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - - pr_debug("In %s port %d, state is %d", __func__, port, state->interface); - - if (!phy_interface_mode_is_rgmii(state->interface) && - state->interface != PHY_INTERFACE_MODE_NA && - state->interface != PHY_INTERFACE_MODE_1000BASEX && - state->interface != PHY_INTERFACE_MODE_MII && - state->interface != PHY_INTERFACE_MODE_REVMII && - state->interface != PHY_INTERFACE_MODE_GMII && - state->interface != PHY_INTERFACE_MODE_QSGMII && - state->interface != PHY_INTERFACE_MODE_INTERNAL && - state->interface != PHY_INTERFACE_MODE_SGMII) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); - dev_err(ds->dev, - "Unsupported interface: %d for port %d\n", - state->interface, port); - return; - } - - /* Allow all the expected bits */ - phylink_set(mask, Autoneg); - phylink_set_port_modes(mask); - phylink_set(mask, Pause); - phylink_set(mask, Asym_Pause); - - /* With the exclusion of MII and Reverse MII, we support Gigabit, - * including Half duplex - */ - if (state->interface != PHY_INTERFACE_MODE_MII && - state->interface != PHY_INTERFACE_MODE_REVMII) { - phylink_set(mask, 1000baseT_Full); - phylink_set(mask, 1000baseT_Half); - } - - /* On both the 8380 and 8382, ports 24-27 are SFP ports */ - if (port >= 24 && port <= 27 && priv->family_id == RTL8380_FAMILY_ID) - phylink_set(mask, 1000baseX_Full); - - /* On the RTL839x family of SoCs, ports 48 to 51 are SFP ports */ - if (port >= 48 && port <= 51 && priv->family_id == RTL8390_FAMILY_ID) - phylink_set(mask, 1000baseX_Full); - - phylink_set(mask, 10baseT_Half); - phylink_set(mask, 10baseT_Full); - phylink_set(mask, 100baseT_Half); - phylink_set(mask, 100baseT_Full); - - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); -} - -static void rtl93xx_phylink_validate(struct dsa_switch *ds, int port, - unsigned long *supported, - struct phylink_link_state *state) -{ - struct rtl838x_switch_priv *priv = ds->priv; - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - - pr_debug("In %s port %d, state is %d (%s)", __func__, port, state->interface, - phy_modes(state->interface)); - - if (!phy_interface_mode_is_rgmii(state->interface) && - state->interface != PHY_INTERFACE_MODE_NA && - state->interface != PHY_INTERFACE_MODE_1000BASEX && - state->interface != PHY_INTERFACE_MODE_MII && - state->interface != PHY_INTERFACE_MODE_REVMII && - state->interface != PHY_INTERFACE_MODE_GMII && - state->interface != PHY_INTERFACE_MODE_QSGMII && - state->interface != PHY_INTERFACE_MODE_XGMII && - state->interface != PHY_INTERFACE_MODE_HSGMII && - state->interface != PHY_INTERFACE_MODE_10GBASER && - state->interface != PHY_INTERFACE_MODE_10GKR && - state->interface != PHY_INTERFACE_MODE_USXGMII && - state->interface != PHY_INTERFACE_MODE_INTERNAL && - state->interface != PHY_INTERFACE_MODE_SGMII) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); - dev_err(ds->dev, - "Unsupported interface: %d for port %d\n", - state->interface, port); - return; - } - - /* Allow all the expected bits */ - phylink_set(mask, Autoneg); - phylink_set_port_modes(mask); - phylink_set(mask, Pause); - phylink_set(mask, Asym_Pause); - - /* With the exclusion of MII and Reverse MII, we support Gigabit, - * including Half duplex - */ - if (state->interface != PHY_INTERFACE_MODE_MII && - state->interface != PHY_INTERFACE_MODE_REVMII) { - phylink_set(mask, 1000baseT_Full); - phylink_set(mask, 1000baseT_Half); - } - - /* Internal phys of the RTL93xx family provide 10G */ - if (priv->ports[port].phy_is_integrated && - state->interface == PHY_INTERFACE_MODE_1000BASEX) { - phylink_set(mask, 1000baseX_Full); - } else if (priv->ports[port].phy_is_integrated) { - phylink_set(mask, 1000baseX_Full); - phylink_set(mask, 10000baseKR_Full); - phylink_set(mask, 10000baseSR_Full); - phylink_set(mask, 10000baseCR_Full); - } - if (state->interface == PHY_INTERFACE_MODE_INTERNAL) { - phylink_set(mask, 1000baseX_Full); - phylink_set(mask, 1000baseT_Full); - phylink_set(mask, 10000baseKR_Full); - phylink_set(mask, 10000baseT_Full); - phylink_set(mask, 10000baseSR_Full); - phylink_set(mask, 10000baseCR_Full); - } - - if (state->interface == PHY_INTERFACE_MODE_USXGMII) { - phylink_set(mask, 2500baseT_Full); - phylink_set(mask, 5000baseT_Full); - phylink_set(mask, 10000baseT_Full); - } - - phylink_set(mask, 10baseT_Half); - phylink_set(mask, 10baseT_Full); - phylink_set(mask, 100baseT_Half); - phylink_set(mask, 100baseT_Full); - - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - pr_debug("%s leaving supported: %*pb", __func__, __ETHTOOL_LINK_MODE_MASK_NBITS, supported); -} - -static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port, - struct phylink_link_state *state) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u64 speed; - u64 link; - - if (port < 0 || port > priv->cpu_port) - return -EINVAL; - - state->link = 0; - link = priv->r->get_port_reg_le(priv->r->mac_link_sts); - if (link & BIT_ULL(port)) - state->link = 1; - pr_debug("%s: link state port %d: %llx\n", __func__, port, link & BIT_ULL(port)); - - state->duplex = 0; - if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port)) - state->duplex = 1; - - speed = priv->r->get_port_reg_le(priv->r->mac_link_spd_sts(port)); - speed >>= (port % 16) << 1; - switch (speed & 0x3) { - case 0: - state->speed = SPEED_10; - break; - case 1: - state->speed = SPEED_100; - break; - case 2: - state->speed = SPEED_1000; - break; - case 3: - if (priv->family_id == RTL9300_FAMILY_ID - && (port == 24 || port == 26)) /* Internal serdes */ - state->speed = SPEED_2500; - else - state->speed = SPEED_100; /* Is in fact 500Mbit */ - } - - state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX); - if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port)) - state->pause |= MLO_PAUSE_RX; - if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port)) - state->pause |= MLO_PAUSE_TX; - - return 1; -} - -static int rtl93xx_phylink_mac_link_state(struct dsa_switch *ds, int port, - struct phylink_link_state *state) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u64 speed; - u64 link; - u64 media; - - if (port < 0 || port > priv->cpu_port) - return -EINVAL; - - /* On the RTL9300 for at least the RTL8226B PHY, the MAC-side link - * state needs to be read twice in order to read a correct result. - * This would not be necessary for ports connected e.g. to RTL8218D - * PHYs. - */ - state->link = 0; - link = priv->r->get_port_reg_le(priv->r->mac_link_sts); - link = priv->r->get_port_reg_le(priv->r->mac_link_sts); - if (link & BIT_ULL(port)) - state->link = 1; - - if (priv->family_id == RTL9310_FAMILY_ID) - media = priv->r->get_port_reg_le(RTL931X_MAC_LINK_MEDIA_STS); - - if (priv->family_id == RTL9300_FAMILY_ID) - media = sw_r32(RTL930X_MAC_LINK_MEDIA_STS); - - if (media & BIT_ULL(port)) - state->link = 1; - - pr_debug("%s: link state port %d: %llx, media %llx\n", __func__, port, - link & BIT_ULL(port), media); - - state->duplex = 0; - if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port)) - state->duplex = 1; - - speed = priv->r->get_port_reg_le(priv->r->mac_link_spd_sts(port)); - speed >>= (port % 8) << 2; - switch (speed & 0xf) { - case 0: - state->speed = SPEED_10; - break; - case 1: - state->speed = SPEED_100; - break; - case 2: - case 7: - state->speed = SPEED_1000; - break; - case 4: - state->speed = SPEED_10000; - break; - case 5: - case 8: - state->speed = SPEED_2500; - break; - case 6: - state->speed = SPEED_5000; - break; - default: - pr_err("%s: unknown speed: %d\n", __func__, (u32)speed & 0xf); - } - - if (priv->family_id == RTL9310_FAMILY_ID - && (port >= 52 && port <= 55)) { /* Internal serdes */ - state->speed = SPEED_10000; - state->link = 1; - state->duplex = 1; - } - - pr_debug("%s: speed is: %d %d\n", __func__, (u32)speed & 0xf, state->speed); - state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX); - if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port)) - state->pause |= MLO_PAUSE_RX; - if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port)) - state->pause |= MLO_PAUSE_TX; - - return 1; -} - -static void rtl83xx_config_interface(int port, phy_interface_t interface) -{ - u32 old, int_shift, sds_shift; - - switch (port) { - case 24: - int_shift = 0; - sds_shift = 5; - break; - case 26: - int_shift = 3; - sds_shift = 0; - break; - default: - return; - } - - old = sw_r32(RTL838X_SDS_MODE_SEL); - switch (interface) { - case PHY_INTERFACE_MODE_1000BASEX: - if ((old >> sds_shift & 0x1f) == 4) - return; - sw_w32_mask(0x7 << int_shift, 1 << int_shift, RTL838X_INT_MODE_CTRL); - sw_w32_mask(0x1f << sds_shift, 4 << sds_shift, RTL838X_SDS_MODE_SEL); - break; - case PHY_INTERFACE_MODE_SGMII: - if ((old >> sds_shift & 0x1f) == 2) - return; - sw_w32_mask(0x7 << int_shift, 2 << int_shift, RTL838X_INT_MODE_CTRL); - sw_w32_mask(0x1f << sds_shift, 2 << sds_shift, RTL838X_SDS_MODE_SEL); - break; - default: - return; - } - pr_debug("configured port %d for interface %s\n", port, phy_modes(interface)); -} - -static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port, - unsigned int mode, - const struct phylink_link_state *state) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u32 reg; - int speed_bit = priv->family_id == RTL8380_FAMILY_ID ? 4 : 3; - - pr_debug("%s port %d, mode %x\n", __func__, port, mode); - - if (port == priv->cpu_port) { - /* Set Speed, duplex, flow control - * FORCE_EN | LINK_EN | NWAY_EN | DUP_SEL - * | SPD_SEL = 0b10 | FORCE_FC_EN | PHY_MASTER_SLV_MANUAL_EN - * | MEDIA_SEL - */ - if (priv->family_id == RTL8380_FAMILY_ID) { - sw_w32(0x6192F, priv->r->mac_force_mode_ctrl(priv->cpu_port)); - /* allow CRC errors on CPU-port */ - sw_w32_mask(0, 0x8, RTL838X_MAC_PORT_CTRL(priv->cpu_port)); - } else { - sw_w32_mask(0, 3, priv->r->mac_force_mode_ctrl(priv->cpu_port)); - } - return; - } - - reg = sw_r32(priv->r->mac_force_mode_ctrl(port)); - /* Auto-Negotiation does not work for MAC in RTL8390 */ - if (priv->family_id == RTL8380_FAMILY_ID) { - if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) { - pr_debug("PHY autonegotiates\n"); - reg |= RTL838X_NWAY_EN; - sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); - rtl83xx_config_interface(port, state->interface); - return; - } - } - - if (mode != MLO_AN_FIXED) - pr_debug("Fixed state.\n"); - - /* Clear id_mode_dis bit, and the existing port mode, let - * RGMII_MODE_EN bet set by mac_link_{up,down} */ - if (priv->family_id == RTL8380_FAMILY_ID) { - reg &= ~(RTL838X_RX_PAUSE_EN | RTL838X_TX_PAUSE_EN); - if (state->pause & MLO_PAUSE_TXRX_MASK) { - if (state->pause & MLO_PAUSE_TX) - reg |= RTL838X_TX_PAUSE_EN; - reg |= RTL838X_RX_PAUSE_EN; - } - } else if (priv->family_id == RTL8390_FAMILY_ID) { - reg &= ~(RTL839X_RX_PAUSE_EN | RTL839X_TX_PAUSE_EN); - if (state->pause & MLO_PAUSE_TXRX_MASK) { - if (state->pause & MLO_PAUSE_TX) - reg |= RTL839X_TX_PAUSE_EN; - reg |= RTL839X_RX_PAUSE_EN; - } - } - - - reg &= ~(3 << speed_bit); - switch (state->speed) { - case SPEED_1000: - reg |= 2 << speed_bit; - break; - case SPEED_100: - reg |= 1 << speed_bit; - break; - default: - break; /* Ignore, including 10MBit which has a speed value of 0 */ - } - - if (priv->family_id == RTL8380_FAMILY_ID) { - reg &= ~(RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN); - if (state->link) - reg |= RTL838X_FORCE_LINK_EN; - if (state->duplex == RTL838X_DUPLEX_MODE) - reg |= RTL838X_DUPLEX_MODE; - } else if (priv->family_id == RTL8390_FAMILY_ID) { - reg &= ~(RTL839X_DUPLEX_MODE | RTL839X_FORCE_LINK_EN); - if (state->link) - reg |= RTL839X_FORCE_LINK_EN; - if (state->duplex == RTL839X_DUPLEX_MODE) - reg |= RTL839X_DUPLEX_MODE; - } - - /* LAG members must use DUPLEX and we need to enable the link */ - if (priv->lagmembers & BIT_ULL(port)) { - switch(priv->family_id) { - case RTL8380_FAMILY_ID: - reg |= (RTL838X_DUPLEX_MODE | RTL838X_FORCE_LINK_EN); - break; - case RTL8390_FAMILY_ID: - reg |= (RTL839X_DUPLEX_MODE | RTL839X_FORCE_LINK_EN); - break; - } - } - - /* Disable AN */ - if (priv->family_id == RTL8380_FAMILY_ID) - reg &= ~RTL838X_NWAY_EN; - sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); -} - -static void rtl931x_phylink_mac_config(struct dsa_switch *ds, int port, - unsigned int mode, - const struct phylink_link_state *state) -{ - struct rtl838x_switch_priv *priv = ds->priv; - int sds_num; - u32 reg, band; - - sds_num = priv->ports[port].sds_num; - pr_info("%s: speed %d sds_num %d\n", __func__, state->speed, sds_num); - - switch (state->interface) { - case PHY_INTERFACE_MODE_HSGMII: - pr_info("%s setting mode PHY_INTERFACE_MODE_HSGMII\n", __func__); - band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_HSGMII); - rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_HSGMII); - band = rtl931x_sds_cmu_band_set(sds_num, true, 62, PHY_INTERFACE_MODE_HSGMII); - break; - case PHY_INTERFACE_MODE_1000BASEX: - band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_1000BASEX); - rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_1000BASEX); - break; - case PHY_INTERFACE_MODE_XGMII: - band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_XGMII); - rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_XGMII); - break; - case PHY_INTERFACE_MODE_10GBASER: - case PHY_INTERFACE_MODE_10GKR: - band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_10GBASER); - rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_10GBASER); - break; - case PHY_INTERFACE_MODE_USXGMII: - /* Translates to MII_USXGMII_10GSXGMII */ - band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_USXGMII); - rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_USXGMII); - break; - case PHY_INTERFACE_MODE_SGMII: - pr_info("%s setting mode PHY_INTERFACE_MODE_SGMII\n", __func__); - band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_SGMII); - rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_SGMII); - band = rtl931x_sds_cmu_band_set(sds_num, true, 62, PHY_INTERFACE_MODE_SGMII); - break; - case PHY_INTERFACE_MODE_QSGMII: - band = rtl931x_sds_cmu_band_get(sds_num, PHY_INTERFACE_MODE_QSGMII); - rtl931x_sds_init(sds_num, PHY_INTERFACE_MODE_QSGMII); - break; - default: - pr_err("%s: unknown serdes mode: %s\n", - __func__, phy_modes(state->interface)); - return; - } - - reg = sw_r32(priv->r->mac_force_mode_ctrl(port)); - pr_info("%s reading FORCE_MODE_CTRL: %08x\n", __func__, reg); - - reg &= ~(RTL931X_DUPLEX_MODE | RTL931X_FORCE_EN | RTL931X_FORCE_LINK_EN); - - reg &= ~(0xf << 12); - reg |= 0x2 << 12; /* Set SMI speed to 0x2 */ - - reg |= RTL931X_TX_PAUSE_EN | RTL931X_RX_PAUSE_EN; - - if (priv->lagmembers & BIT_ULL(port)) - reg |= RTL931X_DUPLEX_MODE; - - if (state->duplex == DUPLEX_FULL) - reg |= RTL931X_DUPLEX_MODE; - - sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); - -} - -static void rtl93xx_phylink_mac_config(struct dsa_switch *ds, int port, - unsigned int mode, - const struct phylink_link_state *state) -{ - struct rtl838x_switch_priv *priv = ds->priv; - int sds_num; - u32 reg; - - pr_info("%s port %d, mode %x, phy-mode: %s, speed %d, link %d\n", __func__, - port, mode, phy_modes(state->interface), state->speed, state->link); - - /* Nothing to be done for the CPU-port */ - if (port == priv->cpu_port) - return; - - if (priv->family_id == RTL9310_FAMILY_ID) - return rtl931x_phylink_mac_config(ds, port, mode, state); - - sds_num = priv->ports[port].sds_num; - pr_info("%s SDS is %d\n", __func__, sds_num); - if (sds_num >= 0 && - (state->interface == PHY_INTERFACE_MODE_1000BASEX || - state->interface == PHY_INTERFACE_MODE_10GBASER)) - rtl9300_serdes_setup(port, sds_num, state->interface); - - reg = sw_r32(priv->r->mac_force_mode_ctrl(port)); - reg &= ~(0xf << 3); - - switch (state->speed) { - case SPEED_10000: - reg |= 4 << 3; - break; - case SPEED_5000: - reg |= 6 << 3; - break; - case SPEED_2500: - reg |= 5 << 3; - break; - case SPEED_1000: - reg |= 2 << 3; - break; - case SPEED_100: - reg |= 1 << 3; - break; - default: - /* Also covers 10M */ - break; - } - - if (state->link) - reg |= RTL930X_FORCE_LINK_EN; - - if (priv->lagmembers & BIT_ULL(port)) - reg |= RTL930X_DUPLEX_MODE | RTL930X_FORCE_LINK_EN; - - if (state->duplex == DUPLEX_FULL) - reg |= RTL930X_DUPLEX_MODE; - else - reg &= ~RTL930X_DUPLEX_MODE; /* Clear duplex bit otherwise */ - - if (priv->ports[port].phy_is_integrated) - reg &= ~RTL930X_FORCE_EN; /* Clear MAC_FORCE_EN to allow SDS-MAC link */ - else - reg |= RTL930X_FORCE_EN; - - sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); -} - -static void rtl83xx_phylink_mac_link_down(struct dsa_switch *ds, int port, - unsigned int mode, - phy_interface_t interface) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - /* Stop TX/RX to port */ - sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port)); - - /* No longer force link */ - sw_w32_mask(0x3, 0, priv->r->mac_force_mode_ctrl(port)); -} - -static void rtl93xx_phylink_mac_link_down(struct dsa_switch *ds, int port, - unsigned int mode, - phy_interface_t interface) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u32 v = 0; - - /* Stop TX/RX to port */ - sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(port)); - - /* No longer force link */ - if (priv->family_id == RTL9300_FAMILY_ID) - v = RTL930X_FORCE_EN | RTL930X_FORCE_LINK_EN; - else if (priv->family_id == RTL9310_FAMILY_ID) - v = RTL931X_FORCE_EN | RTL931X_FORCE_LINK_EN; - sw_w32_mask(v, 0, priv->r->mac_force_mode_ctrl(port)); -} - -static void rtl83xx_phylink_mac_link_up(struct dsa_switch *ds, int port, - unsigned int mode, - phy_interface_t interface, - struct phy_device *phydev, - int speed, int duplex, - bool tx_pause, bool rx_pause) -{ - struct rtl838x_switch_priv *priv = ds->priv; - /* Restart TX/RX to port */ - sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port)); - /* TODO: Set speed/duplex/pauses */ -} - -static void rtl93xx_phylink_mac_link_up(struct dsa_switch *ds, int port, - unsigned int mode, - phy_interface_t interface, - struct phy_device *phydev, - int speed, int duplex, - bool tx_pause, bool rx_pause) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - /* Restart TX/RX to port */ - sw_w32_mask(0, 0x3, priv->r->mac_port_ctrl(port)); - /* TODO: Set speed/duplex/pauses */ -} - -static void rtl83xx_get_strings(struct dsa_switch *ds, - int port, u32 stringset, u8 *data) -{ - if (stringset != ETH_SS_STATS) - return; - - for (int i = 0; i < ARRAY_SIZE(rtl83xx_mib); i++) - ethtool_puts(&data, rtl83xx_mib[i].name); -} - -static void rtl83xx_get_ethtool_stats(struct dsa_switch *ds, int port, - uint64_t *data) -{ - struct rtl838x_switch_priv *priv = ds->priv; - const struct rtl83xx_mib_desc *mib; - u64 h; - - for (int i = 0; i < ARRAY_SIZE(rtl83xx_mib); i++) { - mib = &rtl83xx_mib[i]; - - data[i] = sw_r32(priv->r->stat_port_std_mib + (port << 8) + 252 - mib->offset); - if (mib->size == 2) { - h = sw_r32(priv->r->stat_port_std_mib + (port << 8) + 248 - mib->offset); - data[i] |= h << 32; - } - } -} - -static int rtl83xx_get_sset_count(struct dsa_switch *ds, int port, int sset) -{ - if (sset != ETH_SS_STATS) - return 0; - - return ARRAY_SIZE(rtl83xx_mib); -} - -static int rtl83xx_mc_group_alloc(struct rtl838x_switch_priv *priv, int port) -{ - int mc_group = find_first_zero_bit(priv->mc_group_bm, MAX_MC_GROUPS - 1); - u64 portmask; - - if (mc_group >= MAX_MC_GROUPS - 1) - return -1; - - set_bit(mc_group, priv->mc_group_bm); - portmask = BIT_ULL(port); - priv->r->write_mcast_pmask(mc_group, portmask); - - return mc_group; -} - -static u64 rtl83xx_mc_group_add_port(struct rtl838x_switch_priv *priv, int mc_group, int port) -{ - u64 portmask = priv->r->read_mcast_pmask(mc_group); - - pr_debug("%s: %d\n", __func__, port); - - portmask |= BIT_ULL(port); - priv->r->write_mcast_pmask(mc_group, portmask); - - return portmask; -} - -static u64 rtl83xx_mc_group_del_port(struct rtl838x_switch_priv *priv, int mc_group, int port) -{ - u64 portmask = priv->r->read_mcast_pmask(mc_group); - - pr_debug("%s: %d\n", __func__, port); - - portmask &= ~BIT_ULL(port); - priv->r->write_mcast_pmask(mc_group, portmask); - if (!portmask) - clear_bit(mc_group, priv->mc_group_bm); - - return portmask; -} - -static int rtl83xx_port_enable(struct dsa_switch *ds, int port, - struct phy_device *phydev) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u64 v; - - pr_debug("%s: %x %d", __func__, (u32) priv, port); - priv->ports[port].enable = true; - - /* enable inner tagging on egress, do not keep any tags */ - priv->r->vlan_port_keep_tag_set(port, 0, 1); - - if (dsa_is_cpu_port(ds, port)) - return 0; - - /* add port to switch mask of CPU_PORT */ - priv->r->traffic_enable(priv->cpu_port, port); - - if (priv->is_lagmember[port]) { - pr_debug("%s: %d is lag slave. ignore\n", __func__, port); - return 0; - } - - /* add all other ports in the same bridge to switch mask of port */ - v = priv->r->traffic_get(port); - v |= priv->ports[port].pm; - priv->r->traffic_set(port, v); - - /* TODO: Figure out if this is necessary */ - if (priv->family_id == RTL9300_FAMILY_ID) { - sw_w32_mask(0, BIT(port), RTL930X_L2_PORT_SABLK_CTRL); - sw_w32_mask(0, BIT(port), RTL930X_L2_PORT_DABLK_CTRL); - } - - if (priv->ports[port].sds_num < 0) - priv->ports[port].sds_num = rtl93xx_get_sds(phydev); - - return 0; -} - -static void rtl83xx_port_disable(struct dsa_switch *ds, int port) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u64 v; - - pr_debug("%s %x: %d", __func__, (u32)priv, port); - /* you can only disable user ports */ - if (!dsa_is_user_port(ds, port)) - return; - - /* BUG: This does not work on RTL931X */ - /* remove port from switch mask of CPU_PORT */ - priv->r->traffic_disable(priv->cpu_port, port); - - /* remove all other ports in the same bridge from switch mask of port */ - v = priv->r->traffic_get(port); - v &= ~priv->ports[port].pm; - priv->r->traffic_set(port, v); - - priv->ports[port].enable = false; -} - -static int rtl83xx_set_mac_eee(struct dsa_switch *ds, int port, - struct ethtool_eee *e) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - if (e->eee_enabled && !priv->eee_enabled) { - pr_info("Globally enabling EEE\n"); - priv->r->init_eee(priv, true); - } - - priv->r->port_eee_set(priv, port, e->eee_enabled); - - if (e->eee_enabled) - pr_info("Enabled EEE for port %d\n", port); - else - pr_info("Disabled EEE for port %d\n", port); - - return 0; -} - -static int rtl83xx_get_mac_eee(struct dsa_switch *ds, int port, - struct ethtool_eee *e) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - e->supported = SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full; - - priv->r->eee_port_ability(priv, e, port); - - e->eee_enabled = priv->ports[port].eee_enabled; - - e->eee_active = !!(e->advertised & e->lp_advertised); - - return 0; -} - -static int rtl93xx_get_mac_eee(struct dsa_switch *ds, int port, - struct ethtool_eee *e) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - e->supported = SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseX_Full; - - priv->r->eee_port_ability(priv, e, port); - - e->eee_enabled = priv->ports[port].eee_enabled; - - e->eee_active = !!(e->advertised & e->lp_advertised); - - return 0; -} - -static int rtl83xx_set_ageing_time(struct dsa_switch *ds, unsigned int msec) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - priv->r->set_ageing_time(msec); - - return 0; -} - -static int rtl83xx_port_bridge_join(struct dsa_switch *ds, int port, - struct net_device *bridge) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u64 port_bitmap = BIT_ULL(priv->cpu_port), v; - - pr_debug("%s %x: %d %llx", __func__, (u32)priv, port, port_bitmap); - - if (priv->is_lagmember[port]) { - pr_debug("%s: %d is lag slave. ignore\n", __func__, port); - return 0; - } - - mutex_lock(&priv->reg_mutex); - for (int i = 0; i < ds->num_ports; i++) { - /* Add this port to the port matrix of the other ports in the - * same bridge. If the port is disabled, port matrix is kept - * and not being setup until the port becomes enabled. - */ - if (dsa_is_user_port(ds, i) && !priv->is_lagmember[i] && i != port) { - if (dsa_to_port(ds, i)->bridge_dev != bridge) - continue; - if (priv->ports[i].enable) - priv->r->traffic_enable(i, port); - - priv->ports[i].pm |= BIT_ULL(port); - port_bitmap |= BIT_ULL(i); - } - } - - /* Add all other ports to this port matrix. */ - if (priv->ports[port].enable) { - priv->r->traffic_enable(priv->cpu_port, port); - v = priv->r->traffic_get(port); - v |= port_bitmap; - priv->r->traffic_set(port, v); - } - priv->ports[port].pm |= port_bitmap; - - if (priv->r->set_static_move_action) - priv->r->set_static_move_action(port, false); - - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -static void rtl83xx_port_bridge_leave(struct dsa_switch *ds, int port, - struct net_device *bridge) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u64 port_bitmap = 0, v; - - pr_debug("%s %x: %d", __func__, (u32)priv, port); - mutex_lock(&priv->reg_mutex); - for (int i = 0; i < ds->num_ports; i++) { - /* Remove this port from the port matrix of the other ports - * in the same bridge. If the port is disabled, port matrix - * is kept and not being setup until the port becomes enabled. - * And the other port's port matrix cannot be broken when the - * other port is still a VLAN-aware port. - */ - if (dsa_is_user_port(ds, i) && i != port) { - if (dsa_to_port(ds, i)->bridge_dev != bridge) - continue; - if (priv->ports[i].enable) - priv->r->traffic_disable(i, port); - - priv->ports[i].pm &= ~BIT_ULL(port); - port_bitmap |= BIT_ULL(i); - } - } - - /* Remove all other ports from this port matrix. */ - if (priv->ports[port].enable) { - v = priv->r->traffic_get(port); - v &= ~port_bitmap; - priv->r->traffic_set(port, v); - } - priv->ports[port].pm &= ~port_bitmap; - - if (priv->r->set_static_move_action) - priv->r->set_static_move_action(port, true); - - mutex_unlock(&priv->reg_mutex); -} - -void rtl83xx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) -{ - u32 msti = 0; - u32 port_state[4]; - int index, bit; - int pos = port; - struct rtl838x_switch_priv *priv = ds->priv; - int n = priv->port_width << 1; - - /* Ports above or equal CPU port can never be configured */ - if (port >= priv->cpu_port) - return; - - mutex_lock(&priv->reg_mutex); - - /* For the RTL839x and following, the bits are left-aligned, 838x and 930x - * have 64 bit fields, 839x and 931x have 128 bit fields - */ - if (priv->family_id == RTL8390_FAMILY_ID) - pos += 12; - if (priv->family_id == RTL9300_FAMILY_ID) - pos += 3; - if (priv->family_id == RTL9310_FAMILY_ID) - pos += 8; - - index = n - (pos >> 4) - 1; - bit = (pos << 1) % 32; - - priv->r->stp_get(priv, msti, port_state); - - pr_debug("Current state, port %d: %d\n", port, (port_state[index] >> bit) & 3); - port_state[index] &= ~(3 << bit); - - switch (state) { - case BR_STATE_DISABLED: /* 0 */ - port_state[index] |= (0 << bit); - break; - case BR_STATE_BLOCKING: /* 4 */ - case BR_STATE_LISTENING: /* 1 */ - port_state[index] |= (1 << bit); - break; - case BR_STATE_LEARNING: /* 2 */ - port_state[index] |= (2 << bit); - break; - case BR_STATE_FORWARDING: /* 3 */ - port_state[index] |= (3 << bit); - default: - break; - } - - priv->r->stp_set(priv, msti, port_state); - - mutex_unlock(&priv->reg_mutex); -} - -void rtl83xx_fast_age(struct dsa_switch *ds, int port) -{ - struct rtl838x_switch_priv *priv = ds->priv; - int s = priv->family_id == RTL8390_FAMILY_ID ? 2 : 0; - - pr_debug("FAST AGE port %d\n", port); - mutex_lock(&priv->reg_mutex); - /* RTL838X_L2_TBL_FLUSH_CTRL register bits, 839x has 1 bit larger - * port fields: - * 0-4: Replacing port - * 5-9: Flushed/replaced port - * 10-21: FVID - * 22: Entry types: 1: dynamic, 0: also static - * 23: Match flush port - * 24: Match FVID - * 25: Flush (0) or replace (1) L2 entries - * 26: Status of action (1: Start, 0: Done) - */ - sw_w32(1 << (26 + s) | 1 << (23 + s) | port << (5 + (s / 2)), priv->r->l2_tbl_flush_ctrl); - - do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & BIT(26 + s)); - - mutex_unlock(&priv->reg_mutex); -} - -void rtl931x_fast_age(struct dsa_switch *ds, int port) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - pr_info("%s port %d\n", __func__, port); - mutex_lock(&priv->reg_mutex); - sw_w32(port << 11, RTL931X_L2_TBL_FLUSH_CTRL + 4); - - sw_w32(BIT(24) | BIT(28), RTL931X_L2_TBL_FLUSH_CTRL); - - do { } while (sw_r32(RTL931X_L2_TBL_FLUSH_CTRL) & BIT (28)); - - mutex_unlock(&priv->reg_mutex); -} - -void rtl930x_fast_age(struct dsa_switch *ds, int port) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - if (priv->family_id == RTL9310_FAMILY_ID) - return rtl931x_fast_age(ds, port); - - pr_debug("FAST AGE port %d\n", port); - mutex_lock(&priv->reg_mutex); - sw_w32(port << 11, RTL930X_L2_TBL_FLUSH_CTRL + 4); - - sw_w32(BIT(26) | BIT(30), RTL930X_L2_TBL_FLUSH_CTRL); - - do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & BIT(30)); - - mutex_unlock(&priv->reg_mutex); -} - -static int rtl83xx_vlan_filtering(struct dsa_switch *ds, int port, - bool vlan_filtering, - struct netlink_ext_ack *extack) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - pr_debug("%s: port %d\n", __func__, port); - mutex_lock(&priv->reg_mutex); - - if (vlan_filtering) { - /* Enable ingress and egress filtering - * The VLAN_PORT_IGR_FILTER register uses 2 bits for each port to define - * the filter action: - * 0: Always Forward - * 1: Drop packet - * 2: Trap packet to CPU port - * The Egress filter used 1 bit per state (0: DISABLED, 1: ENABLED) - */ - if (port != priv->cpu_port) { - priv->r->set_vlan_igr_filter(port, IGR_DROP); - priv->r->set_vlan_egr_filter(port, EGR_ENABLE); - } - else { - priv->r->set_vlan_igr_filter(port, IGR_TRAP); - priv->r->set_vlan_egr_filter(port, EGR_DISABLE); - } - - } else { - /* Disable ingress and egress filtering */ - if (port != priv->cpu_port) - priv->r->set_vlan_igr_filter(port, IGR_FORWARD); - - priv->r->set_vlan_egr_filter(port, EGR_DISABLE); - } - - /* Do we need to do something to the CPU-Port, too? */ - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -static int rtl83xx_vlan_prepare(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan) -{ - struct rtl838x_vlan_info info; - struct rtl838x_switch_priv *priv = ds->priv; - - priv->r->vlan_tables_read(0, &info); - - pr_debug("VLAN 0: Tagged ports %llx, untag %llx, profile %d, MC# %d, UC# %d, FID %x\n", - info.tagged_ports, info.untagged_ports, info.profile_id, - info.hash_mc_fid, info.hash_uc_fid, info.fid); - - priv->r->vlan_tables_read(1, &info); - pr_debug("VLAN 1: Tagged ports %llx, untag %llx, profile %d, MC# %d, UC# %d, FID %x\n", - info.tagged_ports, info.untagged_ports, info.profile_id, - info.hash_mc_fid, info.hash_uc_fid, info.fid); - priv->r->vlan_set_untagged(1, info.untagged_ports); - pr_debug("SET: Untagged ports, VLAN %d: %llx\n", 1, info.untagged_ports); - - priv->r->vlan_set_tagged(1, &info); - pr_debug("SET: Tagged ports, VLAN %d: %llx\n", 1, info.tagged_ports); - - return 0; -} - -static int rtl83xx_vlan_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct netlink_ext_ack *extack) -{ - struct rtl838x_vlan_info info; - struct rtl838x_switch_priv *priv = ds->priv; - int err; - - pr_debug("%s port %d, vid %d, flags %x\n", - __func__, port, vlan->vid, vlan->flags); - - /* Let no one mess with our special VLAN 0 */ - if (!vlan->vid) return 0; - - if (vlan->vid > 4095) { - dev_err(priv->dev, "VLAN out of range: %d", vlan->vid); - return -ENOTSUPP; - } - - err = rtl83xx_vlan_prepare(ds, port, vlan); - if (err) - return err; - - mutex_lock(&priv->reg_mutex); - - /* - * Realtek switches copy frames as-is to/from the CPU. For a proper - * VLAN handling the 12 bit RVID field (= VLAN id) for incoming traffic - * and the 1 bit RVID_SEL field (0 = use inner tag, 1 = use outer tag) - * for outgoing traffic of the CPU tag structure need to be handled. As - * of now no such logic is in place. So for the CPU port keep the fixed - * PVID=0 from initial setup in place and ignore all subsequent settings. - */ - if (port != priv->cpu_port) { - if (vlan->flags & BRIDGE_VLAN_INFO_PVID) - rtl83xx_vlan_set_pvid(priv, port, vlan->vid); - else if (priv->ports[port].pvid == vlan->vid) - rtl83xx_vlan_set_pvid(priv, port, 0); - } - - /* Get port memberships of this vlan */ - priv->r->vlan_tables_read(vlan->vid, &info); - - /* new VLAN? */ - if (!info.tagged_ports) { - info.fid = 0; - info.hash_mc_fid = false; - info.hash_uc_fid = false; - info.profile_id = 0; - } - - /* sanitize untagged_ports - must be a subset */ - if (info.untagged_ports & ~info.tagged_ports) - info.untagged_ports = 0; - - info.tagged_ports |= BIT_ULL(port); - if (vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED) - info.untagged_ports |= BIT_ULL(port); - else - info.untagged_ports &= ~BIT_ULL(port); - - priv->r->vlan_set_untagged(vlan->vid, info.untagged_ports); - pr_debug("Untagged ports, VLAN %d: %llx\n", vlan->vid, info.untagged_ports); - - priv->r->vlan_set_tagged(vlan->vid, &info); - pr_debug("Tagged ports, VLAN %d: %llx\n", vlan->vid, info.tagged_ports); - - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -static int rtl83xx_vlan_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan) -{ - struct rtl838x_vlan_info info; - struct rtl838x_switch_priv *priv = ds->priv; - u16 pvid; - - pr_debug("%s: port %d, vid %d, flags %x\n", - __func__, port, vlan->vid, vlan->flags); - - /* Let no one mess with our special VLAN 0 */ - if (!vlan->vid) return 0; - - if (vlan->vid > 4095) { - dev_err(priv->dev, "VLAN out of range: %d", vlan->vid); - return -ENOTSUPP; - } - - mutex_lock(&priv->reg_mutex); - pvid = priv->ports[port].pvid; - - /* Reset to default if removing the current PVID */ - if (vlan->vid == pvid) { - rtl83xx_vlan_set_pvid(priv, port, 0); - } - /* Get port memberships of this vlan */ - priv->r->vlan_tables_read(vlan->vid, &info); - - /* remove port from both tables */ - info.untagged_ports &= (~BIT_ULL(port)); - info.tagged_ports &= (~BIT_ULL(port)); - - priv->r->vlan_set_untagged(vlan->vid, info.untagged_ports); - pr_debug("Untagged ports, VLAN %d: %llx\n", vlan->vid, info.untagged_ports); - - priv->r->vlan_set_tagged(vlan->vid, &info); - pr_debug("Tagged ports, VLAN %d: %llx\n", vlan->vid, info.tagged_ports); - - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -static void rtl83xx_setup_l2_uc_entry(struct rtl838x_l2_entry *e, int port, int vid, u64 mac) -{ - memset(e, 0, sizeof(*e)); - - e->type = L2_UNICAST; - e->valid = true; - - e->age = 3; - e->is_static = true; - - e->port = port; - - e->rvid = e->vid = vid; - e->is_ip_mc = e->is_ipv6_mc = false; - u64_to_ether_addr(mac, e->mac); -} - -static void rtl83xx_setup_l2_mc_entry(struct rtl838x_l2_entry *e, int vid, u64 mac, int mc_group) -{ - memset(e, 0, sizeof(*e)); - - e->type = L2_MULTICAST; - e->valid = true; - - e->mc_portmask_index = mc_group; - - e->rvid = e->vid = vid; - e->is_ip_mc = e->is_ipv6_mc = false; - u64_to_ether_addr(mac, e->mac); -} - -/* Uses the seed to identify a hash bucket in the L2 using the derived hash key and then loops - * over the entries in the bucket until either a matching entry is found or an empty slot - * Returns the filled in rtl838x_l2_entry and the index in the bucket when an entry was found - * when an empty slot was found and must exist is false, the index of the slot is returned - * when no slots are available returns -1 - */ -static int rtl83xx_find_l2_hash_entry(struct rtl838x_switch_priv *priv, u64 seed, - bool must_exist, struct rtl838x_l2_entry *e) -{ - int idx = -1; - u32 key = priv->r->l2_hash_key(priv, seed); - u64 entry; - - pr_debug("%s: using key %x, for seed %016llx\n", __func__, key, seed); - /* Loop over all entries in the hash-bucket and over the second block on 93xx SoCs */ - for (int i = 0; i < priv->l2_bucket_size; i++) { - entry = priv->r->read_l2_entry_using_hash(key, i, e); - pr_debug("valid %d, mac %016llx\n", e->valid, ether_addr_to_u64(&e->mac[0])); - if (must_exist && !e->valid) - continue; - if (!e->valid || ((entry & 0x0fffffffffffffffULL) == seed)) { - idx = i > 3 ? ((key >> 14) & 0xffff) | i >> 1 : ((key << 2) | i) & 0xffff; - break; - } - } - - return idx; -} - -/* Uses the seed to identify an entry in the CAM by looping over all its entries - * Returns the filled in rtl838x_l2_entry and the index in the CAM when an entry was found - * when an empty slot was found the index of the slot is returned - * when no slots are available returns -1 - */ -static int rtl83xx_find_l2_cam_entry(struct rtl838x_switch_priv *priv, u64 seed, - bool must_exist, struct rtl838x_l2_entry *e) -{ - int idx = -1; - u64 entry; - - for (int i = 0; i < 64; i++) { - entry = priv->r->read_cam(i, e); - if (!must_exist && !e->valid) { - if (idx < 0) /* First empty entry? */ - idx = i; - break; - } else if ((entry & 0x0fffffffffffffffULL) == seed) { - pr_debug("Found entry in CAM\n"); - idx = i; - break; - } - } - - return idx; -} - -static int rtl83xx_port_fdb_add(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u64 mac = ether_addr_to_u64(addr); - struct rtl838x_l2_entry e; - int err = 0, idx; - u64 seed = priv->r->l2_hash_seed(mac, vid); - - if (priv->is_lagmember[port]) { - pr_debug("%s: %d is lag slave. ignore\n", __func__, port); - return 0; - } - - mutex_lock(&priv->reg_mutex); - - idx = rtl83xx_find_l2_hash_entry(priv, seed, false, &e); - - /* Found an existing or empty entry */ - if (idx >= 0) { - rtl83xx_setup_l2_uc_entry(&e, port, vid, mac); - priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e); - goto out; - } - - /* Hash buckets full, try CAM */ - idx = rtl83xx_find_l2_cam_entry(priv, seed, false, &e); - - if (idx >= 0) { - rtl83xx_setup_l2_uc_entry(&e, port, vid, mac); - priv->r->write_cam(idx, &e); - goto out; - } - - err = -ENOTSUPP; - -out: - mutex_unlock(&priv->reg_mutex); - - return err; -} - -static int rtl83xx_port_fdb_del(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u64 mac = ether_addr_to_u64(addr); - struct rtl838x_l2_entry e; - int err = 0, idx; - u64 seed = priv->r->l2_hash_seed(mac, vid); - - pr_debug("In %s, mac %llx, vid: %d\n", __func__, mac, vid); - mutex_lock(&priv->reg_mutex); - - idx = rtl83xx_find_l2_hash_entry(priv, seed, true, &e); - - if (idx >= 0) { - pr_debug("Found entry index %d, key %d and bucket %d\n", idx, idx >> 2, idx & 3); - e.valid = false; - priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e); - goto out; - } - - /* Check CAM for spillover from hash buckets */ - idx = rtl83xx_find_l2_cam_entry(priv, seed, true, &e); - - if (idx >= 0) { - e.valid = false; - priv->r->write_cam(idx, &e); - goto out; - } - err = -ENOENT; - -out: - mutex_unlock(&priv->reg_mutex); - - return err; -} - -static int rtl83xx_port_fdb_dump(struct dsa_switch *ds, int port, - dsa_fdb_dump_cb_t *cb, void *data) -{ - struct rtl838x_l2_entry e; - struct rtl838x_switch_priv *priv = ds->priv; - - mutex_lock(&priv->reg_mutex); - - for (int i = 0; i < priv->fib_entries; i++) { - priv->r->read_l2_entry_using_hash(i >> 2, i & 0x3, &e); - - if (!e.valid) - continue; - - if (e.port == port || e.port == RTL930X_PORT_IGNORE) - cb(e.mac, e.vid, e.is_static, data); - - if (!((i + 1) % 64)) - cond_resched(); - } - - for (int i = 0; i < 64; i++) { - priv->r->read_cam(i, &e); - - if (!e.valid) - continue; - - if (e.port == port) - cb(e.mac, e.vid, e.is_static, data); - } - - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -static int rtl83xx_port_mdb_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_mdb *mdb) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u64 mac = ether_addr_to_u64(mdb->addr); - struct rtl838x_l2_entry e; - int err = 0, idx; - int vid = mdb->vid; - u64 seed = priv->r->l2_hash_seed(mac, vid); - int mc_group; - - if (priv->id >= 0x9300) - return -EOPNOTSUPP; - - pr_debug("In %s port %d, mac %llx, vid: %d\n", __func__, port, mac, vid); - - if (priv->is_lagmember[port]) { - pr_debug("%s: %d is lag slave. ignore\n", __func__, port); - return -EINVAL; - } - - mutex_lock(&priv->reg_mutex); - - idx = rtl83xx_find_l2_hash_entry(priv, seed, false, &e); - - /* Found an existing or empty entry */ - if (idx >= 0) { - if (e.valid) { - pr_debug("Found an existing entry %016llx, mc_group %d\n", - ether_addr_to_u64(e.mac), e.mc_portmask_index); - rtl83xx_mc_group_add_port(priv, e.mc_portmask_index, port); - } else { - pr_debug("New entry for seed %016llx\n", seed); - mc_group = rtl83xx_mc_group_alloc(priv, port); - if (mc_group < 0) { - err = -ENOTSUPP; - goto out; - } - rtl83xx_setup_l2_mc_entry(&e, vid, mac, mc_group); - priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e); - } - goto out; - } - - /* Hash buckets full, try CAM */ - idx = rtl83xx_find_l2_cam_entry(priv, seed, false, &e); - - if (idx >= 0) { - if (e.valid) { - pr_debug("Found existing CAM entry %016llx, mc_group %d\n", - ether_addr_to_u64(e.mac), e.mc_portmask_index); - rtl83xx_mc_group_add_port(priv, e.mc_portmask_index, port); - } else { - pr_debug("New entry\n"); - mc_group = rtl83xx_mc_group_alloc(priv, port); - if (mc_group < 0) { - err = -ENOTSUPP; - goto out; - } - rtl83xx_setup_l2_mc_entry(&e, vid, mac, mc_group); - priv->r->write_cam(idx, &e); - } - goto out; - } - - err = -ENOTSUPP; - -out: - mutex_unlock(&priv->reg_mutex); - if (err) - dev_err(ds->dev, "failed to add MDB entry\n"); - - return err; -} - -int rtl83xx_port_mdb_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_mdb *mdb) -{ - struct rtl838x_switch_priv *priv = ds->priv; - u64 mac = ether_addr_to_u64(mdb->addr); - struct rtl838x_l2_entry e; - int err = 0, idx; - int vid = mdb->vid; - u64 seed = priv->r->l2_hash_seed(mac, vid); - u64 portmask; - - pr_debug("In %s, port %d, mac %llx, vid: %d\n", __func__, port, mac, vid); - - if (priv->is_lagmember[port]) { - pr_info("%s: %d is lag slave. ignore\n", __func__, port); - return 0; - } - - mutex_lock(&priv->reg_mutex); - - idx = rtl83xx_find_l2_hash_entry(priv, seed, true, &e); - - if (idx >= 0) { - pr_debug("Found entry index %d, key %d and bucket %d\n", idx, idx >> 2, idx & 3); - portmask = rtl83xx_mc_group_del_port(priv, e.mc_portmask_index, port); - if (!portmask) { - e.valid = false; - priv->r->write_l2_entry_using_hash(idx >> 2, idx & 0x3, &e); - } - goto out; - } - - /* Check CAM for spillover from hash buckets */ - idx = rtl83xx_find_l2_cam_entry(priv, seed, true, &e); - - if (idx >= 0) { - portmask = rtl83xx_mc_group_del_port(priv, e.mc_portmask_index, port); - if (!portmask) { - e.valid = false; - priv->r->write_cam(idx, &e); - } - goto out; - } - /* TODO: Re-enable with a newer kernel: err = -ENOENT; */ - -out: - mutex_unlock(&priv->reg_mutex); - - return err; -} - -static int rtl83xx_port_mirror_add(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror, - bool ingress) -{ - /* We support 4 mirror groups, one destination port per group */ - int group; - struct rtl838x_switch_priv *priv = ds->priv; - int ctrl_reg, dpm_reg, spm_reg; - - pr_debug("In %s\n", __func__); - - for (group = 0; group < 4; group++) { - if (priv->mirror_group_ports[group] == mirror->to_local_port) - break; - } - if (group >= 4) { - for (group = 0; group < 4; group++) { - if (priv->mirror_group_ports[group] < 0) - break; - } - } - - if (group >= 4) - return -ENOSPC; - - ctrl_reg = priv->r->mir_ctrl + group * 4; - dpm_reg = priv->r->mir_dpm + group * 4 * priv->port_width; - spm_reg = priv->r->mir_spm + group * 4 * priv->port_width; - - pr_debug("Using group %d\n", group); - mutex_lock(&priv->reg_mutex); - - if (priv->family_id == RTL8380_FAMILY_ID) { - /* Enable mirroring to port across VLANs (bit 11) */ - sw_w32(1 << 11 | (mirror->to_local_port << 4) | 1, ctrl_reg); - } else { - /* Enable mirroring to destination port */ - sw_w32((mirror->to_local_port << 4) | 1, ctrl_reg); - } - - if (ingress && (priv->r->get_port_reg_be(spm_reg) & (1ULL << port))) { - mutex_unlock(&priv->reg_mutex); - return -EEXIST; - } - if ((!ingress) && (priv->r->get_port_reg_be(dpm_reg) & (1ULL << port))) { - mutex_unlock(&priv->reg_mutex); - return -EEXIST; - } - - if (ingress) - priv->r->mask_port_reg_be(0, 1ULL << port, spm_reg); - else - priv->r->mask_port_reg_be(0, 1ULL << port, dpm_reg); - - priv->mirror_group_ports[group] = mirror->to_local_port; - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -static void rtl83xx_port_mirror_del(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror) -{ - int group = 0; - struct rtl838x_switch_priv *priv = ds->priv; - int ctrl_reg, dpm_reg, spm_reg; - - pr_debug("In %s\n", __func__); - for (group = 0; group < 4; group++) { - if (priv->mirror_group_ports[group] == mirror->to_local_port) - break; - } - if (group >= 4) - return; - - ctrl_reg = priv->r->mir_ctrl + group * 4; - dpm_reg = priv->r->mir_dpm + group * 4 * priv->port_width; - spm_reg = priv->r->mir_spm + group * 4 * priv->port_width; - - mutex_lock(&priv->reg_mutex); - if (mirror->ingress) { - /* Ingress, clear source port matrix */ - priv->r->mask_port_reg_be(1ULL << port, 0, spm_reg); - } else { - /* Egress, clear destination port matrix */ - priv->r->mask_port_reg_be(1ULL << port, 0, dpm_reg); - } - - if (!(sw_r32(spm_reg) || sw_r32(dpm_reg))) { - priv->mirror_group_ports[group] = -1; - sw_w32(0, ctrl_reg); - } - - mutex_unlock(&priv->reg_mutex); -} - -static int rtl83xx_port_pre_bridge_flags(struct dsa_switch *ds, int port, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack) -{ - struct rtl838x_switch_priv *priv = ds->priv; - unsigned long features = 0; - pr_debug("%s: %d %lX\n", __func__, port, flags.val); - if (priv->r->enable_learning) - features |= BR_LEARNING; - if (priv->r->enable_flood) - features |= BR_FLOOD; - if (priv->r->enable_mcast_flood) - features |= BR_MCAST_FLOOD; - if (priv->r->enable_bcast_flood) - features |= BR_BCAST_FLOOD; - if (flags.mask & ~(features)) - return -EINVAL; - - return 0; -} - -static int rtl83xx_port_bridge_flags(struct dsa_switch *ds, int port, struct switchdev_brport_flags flags, struct netlink_ext_ack *extack) -{ - struct rtl838x_switch_priv *priv = ds->priv; - - pr_debug("%s: %d %lX\n", __func__, port, flags.val); - if (priv->r->enable_learning && (flags.mask & BR_LEARNING)) - priv->r->enable_learning(port, !!(flags.val & BR_LEARNING)); - - if (priv->r->enable_flood && (flags.mask & BR_FLOOD)) - priv->r->enable_flood(port, !!(flags.val & BR_FLOOD)); - - if (priv->r->enable_mcast_flood && (flags.mask & BR_MCAST_FLOOD)) - priv->r->enable_mcast_flood(port, !!(flags.val & BR_MCAST_FLOOD)); - - if (priv->r->enable_bcast_flood && (flags.mask & BR_BCAST_FLOOD)) - priv->r->enable_bcast_flood(port, !!(flags.val & BR_BCAST_FLOOD)); - - return 0; -} - -static bool rtl83xx_lag_can_offload(struct dsa_switch *ds, - struct net_device *lag, - struct netdev_lag_upper_info *info) -{ - int id; - - id = dsa_lag_id(ds->dst, lag); - if (id < 0 || id >= ds->num_lag_ids) - return false; - - if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) { - return false; - } - if (info->hash_type != NETDEV_LAG_HASH_L2 && info->hash_type != NETDEV_LAG_HASH_L23) - return false; - - return true; -} - -static int rtl83xx_port_lag_change(struct dsa_switch *ds, int port) -{ - pr_debug("%s: %d\n", __func__, port); - /* Nothing to be done... */ - - return 0; -} - -static int rtl83xx_port_lag_join(struct dsa_switch *ds, int port, - struct net_device *lag, - struct netdev_lag_upper_info *info) -{ - struct rtl838x_switch_priv *priv = ds->priv; - int i, err = 0; - - if (!rtl83xx_lag_can_offload(ds, lag, info)) - return -EOPNOTSUPP; - - mutex_lock(&priv->reg_mutex); - - for (i = 0; i < priv->n_lags; i++) { - if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == lag)) - break; - } - if (port >= priv->cpu_port) { - err = -EINVAL; - goto out; - } - pr_info("port_lag_join: group %d, port %d\n",i, port); - if (!priv->lag_devs[i]) - priv->lag_devs[i] = lag; - - if (priv->lag_primary[i] == -1) { - priv->lag_primary[i] = port; - } else - priv->is_lagmember[port] = 1; - - priv->lagmembers |= (1ULL << port); - - pr_debug("lag_members = %llX\n", priv->lagmembers); - err = rtl83xx_lag_add(priv->ds, i, port, info); - if (err) { - err = -EINVAL; - goto out; - } - -out: - mutex_unlock(&priv->reg_mutex); - - return err; -} - -static int rtl83xx_port_lag_leave(struct dsa_switch *ds, int port, - struct net_device *lag) -{ - int i, group = -1, err; - struct rtl838x_switch_priv *priv = ds->priv; - - mutex_lock(&priv->reg_mutex); - for (i = 0; i < priv->n_lags; i++) { - if (priv->lags_port_members[i] & BIT_ULL(port)) { - group = i; - break; - } - } - - if (group == -1) { - pr_info("port_lag_leave: port %d is not a member\n", port); - err = -EINVAL; - goto out; - } - - if (port >= priv->cpu_port) { - err = -EINVAL; - goto out; - } - pr_info("port_lag_del: group %d, port %d\n",group, port); - priv->lagmembers &=~ (1ULL << port); - priv->lag_primary[i] = -1; - priv->is_lagmember[port] = 0; - pr_debug("lag_members = %llX\n", priv->lagmembers); - err = rtl83xx_lag_del(priv->ds, group, port); - if (err) { - err = -EINVAL; - goto out; - } - if (!priv->lags_port_members[i]) - priv->lag_devs[i] = NULL; - -out: - mutex_unlock(&priv->reg_mutex); - return 0; -} - -int dsa_phy_read(struct dsa_switch *ds, int phy_addr, int phy_reg) -{ - u32 val; - u32 offset = 0; - struct rtl838x_switch_priv *priv = ds->priv; - - if ((phy_addr >= 24) && - (phy_addr <= 27) && - (priv->ports[24].phy == PHY_RTL838X_SDS)) { - if (phy_addr == 26) - offset = 0x100; - val = sw_r32(RTL838X_SDS4_FIB_REG0 + offset + (phy_reg << 2)) & 0xffff; - return val; - } - - read_phy(phy_addr, 0, phy_reg, &val); - return val; -} - -int dsa_phy_write(struct dsa_switch *ds, int phy_addr, int phy_reg, u16 val) -{ - u32 offset = 0; - struct rtl838x_switch_priv *priv = ds->priv; - - if ((phy_addr >= 24) && - (phy_addr <= 27) && - (priv->ports[24].phy == PHY_RTL838X_SDS)) { - if (phy_addr == 26) - offset = 0x100; - sw_w32(val, RTL838X_SDS4_FIB_REG0 + offset + (phy_reg << 2)); - return 0; - } - return write_phy(phy_addr, 0, phy_reg, val); -} - -const struct dsa_switch_ops rtl83xx_switch_ops = { - .get_tag_protocol = rtl83xx_get_tag_protocol, - .setup = rtl83xx_setup, - - .phy_read = dsa_phy_read, - .phy_write = dsa_phy_write, - - .phylink_validate = rtl83xx_phylink_validate, - .phylink_mac_link_state = rtl83xx_phylink_mac_link_state, - .phylink_mac_config = rtl83xx_phylink_mac_config, - .phylink_mac_link_down = rtl83xx_phylink_mac_link_down, - .phylink_mac_link_up = rtl83xx_phylink_mac_link_up, - - .get_strings = rtl83xx_get_strings, - .get_ethtool_stats = rtl83xx_get_ethtool_stats, - .get_sset_count = rtl83xx_get_sset_count, - - .port_enable = rtl83xx_port_enable, - .port_disable = rtl83xx_port_disable, - - .get_mac_eee = rtl83xx_get_mac_eee, - .set_mac_eee = rtl83xx_set_mac_eee, - - .set_ageing_time = rtl83xx_set_ageing_time, - .port_bridge_join = rtl83xx_port_bridge_join, - .port_bridge_leave = rtl83xx_port_bridge_leave, - .port_stp_state_set = rtl83xx_port_stp_state_set, - .port_fast_age = rtl83xx_fast_age, - - .port_vlan_filtering = rtl83xx_vlan_filtering, - .port_vlan_add = rtl83xx_vlan_add, - .port_vlan_del = rtl83xx_vlan_del, - - .port_fdb_add = rtl83xx_port_fdb_add, - .port_fdb_del = rtl83xx_port_fdb_del, - .port_fdb_dump = rtl83xx_port_fdb_dump, - - .port_mdb_add = rtl83xx_port_mdb_add, - .port_mdb_del = rtl83xx_port_mdb_del, - - .port_mirror_add = rtl83xx_port_mirror_add, - .port_mirror_del = rtl83xx_port_mirror_del, - - .port_lag_change = rtl83xx_port_lag_change, - .port_lag_join = rtl83xx_port_lag_join, - .port_lag_leave = rtl83xx_port_lag_leave, - - .port_pre_bridge_flags = rtl83xx_port_pre_bridge_flags, - .port_bridge_flags = rtl83xx_port_bridge_flags, -}; - -const struct dsa_switch_ops rtl930x_switch_ops = { - .get_tag_protocol = rtl83xx_get_tag_protocol, - .setup = rtl93xx_setup, - - .phy_read = dsa_phy_read, - .phy_write = dsa_phy_write, - - .phylink_validate = rtl93xx_phylink_validate, - .phylink_mac_link_state = rtl93xx_phylink_mac_link_state, - .phylink_mac_config = rtl93xx_phylink_mac_config, - .phylink_mac_link_down = rtl93xx_phylink_mac_link_down, - .phylink_mac_link_up = rtl93xx_phylink_mac_link_up, - - .get_strings = rtl83xx_get_strings, - .get_ethtool_stats = rtl83xx_get_ethtool_stats, - .get_sset_count = rtl83xx_get_sset_count, - - .port_enable = rtl83xx_port_enable, - .port_disable = rtl83xx_port_disable, - - .get_mac_eee = rtl93xx_get_mac_eee, - .set_mac_eee = rtl83xx_set_mac_eee, - - .set_ageing_time = rtl83xx_set_ageing_time, - .port_bridge_join = rtl83xx_port_bridge_join, - .port_bridge_leave = rtl83xx_port_bridge_leave, - .port_stp_state_set = rtl83xx_port_stp_state_set, - .port_fast_age = rtl930x_fast_age, - - .port_vlan_filtering = rtl83xx_vlan_filtering, - .port_vlan_add = rtl83xx_vlan_add, - .port_vlan_del = rtl83xx_vlan_del, - - .port_fdb_add = rtl83xx_port_fdb_add, - .port_fdb_del = rtl83xx_port_fdb_del, - .port_fdb_dump = rtl83xx_port_fdb_dump, - - .port_mdb_add = rtl83xx_port_mdb_add, - .port_mdb_del = rtl83xx_port_mdb_del, - - .port_lag_change = rtl83xx_port_lag_change, - .port_lag_join = rtl83xx_port_lag_join, - .port_lag_leave = rtl83xx_port_lag_leave, - - .port_pre_bridge_flags = rtl83xx_port_pre_bridge_flags, - .port_bridge_flags = rtl83xx_port_bridge_flags, -}; diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/qos.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/qos.c deleted file mode 100644 index d101e1c97e6567..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/qos.c +++ /dev/null @@ -1,565 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include - -#include "rtl83xx.h" - -static struct rtl838x_switch_priv *switch_priv; -extern struct rtl83xx_soc_info soc_info; - -enum scheduler_type { - WEIGHTED_FAIR_QUEUE = 0, - WEIGHTED_ROUND_ROBIN, -}; - -int max_available_queue[] = {0, 1, 2, 3, 4, 5, 6, 7}; -int default_queue_weights[] = {1, 1, 1, 1, 1, 1, 1, 1}; -int dot1p_priority_remapping[] = {0, 1, 2, 3, 4, 5, 6, 7}; - -static void rtl839x_read_scheduling_table(int port) -{ - u32 cmd = 1 << 9 | /* Execute cmd */ - 0 << 8 | /* Read */ - 0 << 6 | /* Table type 0b00 */ - (port & 0x3f); - rtl839x_exec_tbl2_cmd(cmd); -} - -static void rtl839x_write_scheduling_table(int port) -{ - u32 cmd = 1 << 9 | /* Execute cmd */ - 1 << 8 | /* Write */ - 0 << 6 | /* Table type 0b00 */ - (port & 0x3f); - rtl839x_exec_tbl2_cmd(cmd); -} - -static void rtl839x_read_out_q_table(int port) -{ - u32 cmd = 1 << 9 | /* Execute cmd */ - 0 << 8 | /* Read */ - 2 << 6 | /* Table type 0b10 */ - (port & 0x3f); - rtl839x_exec_tbl2_cmd(cmd); -} - -static void rtl838x_storm_enable(struct rtl838x_switch_priv *priv, int port, bool enable) -{ - /* Enable Storm control for that port for UC, MC, and BC */ - if (enable) - sw_w32(0x7, RTL838X_STORM_CTRL_LB_CTRL(port)); - else - sw_w32(0x0, RTL838X_STORM_CTRL_LB_CTRL(port)); -} - -u32 rtl838x_get_egress_rate(struct rtl838x_switch_priv *priv, int port) -{ - if (port > priv->cpu_port) - return 0; - - return sw_r32(RTL838X_SCHED_P_EGR_RATE_CTRL(port)) & 0x3fff; -} - -/* Sets the rate limit, 10MBit/s is equal to a rate value of 625 */ -int rtl838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate) -{ - u32 old_rate; - - if (port > priv->cpu_port) - return -1; - - old_rate = sw_r32(RTL838X_SCHED_P_EGR_RATE_CTRL(port)); - sw_w32(rate, RTL838X_SCHED_P_EGR_RATE_CTRL(port)); - - return old_rate; -} - -/* Set the rate limit for a particular queue in Bits/s - * units of the rate is 16Kbps - */ -void rtl838x_egress_rate_queue_limit(struct rtl838x_switch_priv *priv, int port, - int queue, u32 rate) -{ - if (port > priv->cpu_port) - return; - - if (queue > 7) - return; - - sw_w32(rate, RTL838X_SCHED_Q_EGR_RATE_CTRL(port, queue)); -} - -static void rtl838x_rate_control_init(struct rtl838x_switch_priv *priv) -{ - pr_info("Enabling Storm control\n"); - /* TICK_PERIOD_PPS */ - if (priv->id == 0x8380) - sw_w32_mask(0x3ff << 20, 434 << 20, RTL838X_SCHED_LB_TICK_TKN_CTRL_0); - - /* Set burst rate */ - sw_w32(0x00008000, RTL838X_STORM_CTRL_BURST_0); /* UC */ - sw_w32(0x80008000, RTL838X_STORM_CTRL_BURST_1); /* MC and BC */ - - /* Set burst Packets per Second to 32 */ - sw_w32(0x00000020, RTL838X_STORM_CTRL_BURST_PPS_0); /* UC */ - sw_w32(0x00200020, RTL838X_STORM_CTRL_BURST_PPS_1); /* MC and BC */ - - /* Include IFG in storm control, rate based on bytes/s (0 = packets) */ - sw_w32_mask(0, 1 << 6 | 1 << 5, RTL838X_STORM_CTRL); - /* Bandwidth control includes preamble and IFG (10 Bytes) */ - sw_w32_mask(0, 1, RTL838X_SCHED_CTRL); - - /* On SoCs except RTL8382M, set burst size of port egress */ - if (priv->id != 0x8382) - sw_w32_mask(0xffff, 0x800, RTL838X_SCHED_LB_THR); - - /* Enable storm control on all ports with a PHY and limit rates, - * for UC and MC for both known and unknown addresses - */ - for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) { - sw_w32((1 << 18) | 0x8000, RTL838X_STORM_CTRL_PORT_UC(i)); - sw_w32((1 << 18) | 0x8000, RTL838X_STORM_CTRL_PORT_MC(i)); - sw_w32(0x8000, RTL838X_STORM_CTRL_PORT_BC(i)); - rtl838x_storm_enable(priv, i, true); - } - } - - /* Attack prevention, enable all attack prevention measures */ - /* sw_w32(0x1ffff, RTL838X_ATK_PRVNT_CTRL); */ - /* Attack prevention, drop (bit = 0) problematic packets on all ports. - * Setting bit = 1 means: trap to CPU - */ - /* sw_w32(0, RTL838X_ATK_PRVNT_ACT); */ - /* Enable attack prevention on all ports */ - /* sw_w32(0x0fffffff, RTL838X_ATK_PRVNT_PORT_EN); */ -} - -/* Sets the rate limit, 10MBit/s is equal to a rate value of 625 */ -u32 rtl839x_get_egress_rate(struct rtl838x_switch_priv *priv, int port) -{ - u32 rate; - - pr_debug("%s: Getting egress rate on port %d to %d\n", __func__, port, rate); - if (port >= priv->cpu_port) - return 0; - - mutex_lock(&priv->reg_mutex); - - rtl839x_read_scheduling_table(port); - - rate = sw_r32(RTL839X_TBL_ACCESS_DATA_2(7)); - rate <<= 12; - rate |= sw_r32(RTL839X_TBL_ACCESS_DATA_2(8)) >> 20; - - mutex_unlock(&priv->reg_mutex); - - return rate; -} - -/* Sets the rate limit, 10MBit/s is equal to a rate value of 625, returns previous rate */ -int rtl839x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate) -{ - u32 old_rate; - - pr_debug("%s: Setting egress rate on port %d to %d\n", __func__, port, rate); - if (port >= priv->cpu_port) - return -1; - - mutex_lock(&priv->reg_mutex); - - rtl839x_read_scheduling_table(port); - - old_rate = sw_r32(RTL839X_TBL_ACCESS_DATA_2(7)) & 0xff; - old_rate <<= 12; - old_rate |= sw_r32(RTL839X_TBL_ACCESS_DATA_2(8)) >> 20; - sw_w32_mask(0xff, (rate >> 12) & 0xff, RTL839X_TBL_ACCESS_DATA_2(7)); - sw_w32_mask(0xfff << 20, rate << 20, RTL839X_TBL_ACCESS_DATA_2(8)); - - rtl839x_write_scheduling_table(port); - - mutex_unlock(&priv->reg_mutex); - - return old_rate; -} - -/* Set the rate limit for a particular queue in Bits/s - * units of the rate is 16Kbps - */ -void rtl839x_egress_rate_queue_limit(struct rtl838x_switch_priv *priv, int port, - int queue, u32 rate) -{ - int lsb = 128 + queue * 20; - int low_byte = 8 - (lsb >> 5); - int start_bit = lsb - (low_byte << 5); - u32 high_mask = 0xfffff >> (32 - start_bit); - - pr_debug("%s: Setting egress rate on port %d, queue %d to %d\n", - __func__, port, queue, rate); - if (port >= priv->cpu_port) - return; - if (queue > 7) - return; - - mutex_lock(&priv->reg_mutex); - - rtl839x_read_scheduling_table(port); - - sw_w32_mask(0xfffff << start_bit, (rate & 0xfffff) << start_bit, - RTL839X_TBL_ACCESS_DATA_2(low_byte)); - if (high_mask) - sw_w32_mask(high_mask, (rate & 0xfffff) >> (32- start_bit), - RTL839X_TBL_ACCESS_DATA_2(low_byte - 1)); - - rtl839x_write_scheduling_table(port); - - mutex_unlock(&priv->reg_mutex); -} - -static void rtl839x_rate_control_init(struct rtl838x_switch_priv *priv) -{ - pr_info("%s: enabling rate control\n", __func__); - /* Tick length and token size settings for SoC with 250MHz, - * RTL8350 family would use 50MHz - */ - /* Set the special tick period */ - sw_w32(976563, RTL839X_STORM_CTRL_SPCL_LB_TICK_TKN_CTRL); - /* Ingress tick period and token length 10G */ - sw_w32(18 << 11 | 151, RTL839X_IGR_BWCTRL_LB_TICK_TKN_CTRL_0); - /* Ingress tick period and token length 1G */ - sw_w32(245 << 11 | 129, RTL839X_IGR_BWCTRL_LB_TICK_TKN_CTRL_1); - /* Egress tick period 10G, bytes/token 10G and tick period 1G, bytes/token 1G */ - sw_w32(18 << 24 | 151 << 16 | 185 << 8 | 97, RTL839X_SCHED_LB_TICK_TKN_CTRL); - /* Set the tick period of the CPU and the Token Len */ - sw_w32(3815 << 8 | 1, RTL839X_SCHED_LB_TICK_TKN_PPS_CTRL); - - /* Set the Weighted Fair Queueing burst size */ - sw_w32_mask(0xffff, 4500, RTL839X_SCHED_LB_THR); - - /* Storm-rate calculation is based on bytes/sec (bit 5), include IFG (bit 6) */ - sw_w32_mask(0, 1 << 5 | 1 << 6, RTL839X_STORM_CTRL); - - /* Based on the rate control mode being bytes/s - * set tick period and token length for 10G - */ - sw_w32(18 << 10 | 151, RTL839X_STORM_CTRL_LB_TICK_TKN_CTRL_0); - /* and for 1G ports */ - sw_w32(246 << 10 | 129, RTL839X_STORM_CTRL_LB_TICK_TKN_CTRL_1); - - /* Set default burst rates on all ports (the same for 1G / 10G) with a PHY - * for UC, MC and BC - * For 1G port, the minimum burst rate is 1700, maximum 65535, - * For 10G ports it is 2650 and 1048575 respectively */ - for (int p = 0; p < priv->cpu_port; p++) { - if (priv->ports[p].phy && !priv->ports[p].is10G) { - sw_w32_mask(0xffff, 0x8000, RTL839X_STORM_CTRL_PORT_UC_1(p)); - sw_w32_mask(0xffff, 0x8000, RTL839X_STORM_CTRL_PORT_MC_1(p)); - sw_w32_mask(0xffff, 0x8000, RTL839X_STORM_CTRL_PORT_BC_1(p)); - } - } - - /* Setup ingress/egress per-port rate control */ - for (int p = 0; p < priv->cpu_port; p++) { - if (!priv->ports[p].phy) - continue; - - if (priv->ports[p].is10G) - rtl839x_set_egress_rate(priv, p, 625000); /* 10GB/s */ - else - rtl839x_set_egress_rate(priv, p, 62500); /* 1GB/s */ - - /* Setup queues: all RTL83XX SoCs have 8 queues, maximum rate */ - for (int q = 0; q < 8; q++) - rtl839x_egress_rate_queue_limit(priv, p, q, 0xfffff); - - if (priv->ports[p].is10G) { - /* Set high threshold to maximum */ - sw_w32_mask(0xffff, 0xffff, RTL839X_IGR_BWCTRL_PORT_CTRL_10G_0(p)); - } else { - /* Set high threshold to maximum */ - sw_w32_mask(0xffff, 0xffff, RTL839X_IGR_BWCTRL_PORT_CTRL_1(p)); - } - } - - /* Set global ingress low watermark rate */ - sw_w32(65532, RTL839X_IGR_BWCTRL_CTRL_LB_THR); -} - - - -void rtl838x_setup_prio2queue_matrix(int *min_queues) -{ - u32 v = 0; - - pr_info("Current Intprio2queue setting: %08x\n", sw_r32(RTL838X_QM_INTPRI2QID_CTRL)); - for (int i = 0; i < MAX_PRIOS; i++) - v |= i << (min_queues[i] * 3); - sw_w32(v, RTL838X_QM_INTPRI2QID_CTRL); -} - -void rtl839x_setup_prio2queue_matrix(int *min_queues) -{ - pr_info("Current Intprio2queue setting: %08x\n", sw_r32(RTL839X_QM_INTPRI2QID_CTRL(0))); - for (int i = 0; i < MAX_PRIOS; i++) { - int q = min_queues[i]; - sw_w32(i << (q * 3), RTL839X_QM_INTPRI2QID_CTRL(q)); - } -} - -/* Sets the CPU queue depending on the internal priority of a packet */ -void rtl83xx_setup_prio2queue_cpu_matrix(int *max_queues) -{ - int reg = soc_info.family == RTL8380_FAMILY_ID ? RTL838X_QM_PKT2CPU_INTPRI_MAP - : RTL839X_QM_PKT2CPU_INTPRI_MAP; - u32 v = 0; - - pr_info("QM_PKT2CPU_INTPRI_MAP: %08x\n", sw_r32(reg)); - for (int i = 0; i < MAX_PRIOS; i++) - v |= max_queues[i] << (i * 3); - sw_w32(v, reg); -} - -void rtl83xx_setup_default_prio2queue(void) -{ - if (soc_info.family == RTL8380_FAMILY_ID) { - rtl838x_setup_prio2queue_matrix(max_available_queue); - } else { - rtl839x_setup_prio2queue_matrix(max_available_queue); - } - rtl83xx_setup_prio2queue_cpu_matrix(max_available_queue); -} - -/* Sets the output queue assigned to a port, the port can be the CPU-port */ -void rtl839x_set_egress_queue(int port, int queue) -{ - sw_w32(queue << ((port % 10) *3), RTL839X_QM_PORT_QNUM(port)); -} - -/* Sets the priority assigned of an ingress port, the port can be the CPU-port */ -void rtl83xx_set_ingress_priority(int port, int priority) -{ - if (soc_info.family == RTL8380_FAMILY_ID) - sw_w32(priority << ((port % 10) *3), RTL838X_PRI_SEL_PORT_PRI(port)); - else - sw_w32(priority << ((port % 10) *3), RTL839X_PRI_SEL_PORT_PRI(port)); -} - -int rtl839x_get_scheduling_algorithm(struct rtl838x_switch_priv *priv, int port) -{ - u32 v; - - mutex_lock(&priv->reg_mutex); - - rtl839x_read_scheduling_table(port); - v = sw_r32(RTL839X_TBL_ACCESS_DATA_2(8)); - - mutex_unlock(&priv->reg_mutex); - - if (v & BIT(19)) - return WEIGHTED_ROUND_ROBIN; - - return WEIGHTED_FAIR_QUEUE; -} - -void rtl839x_set_scheduling_algorithm(struct rtl838x_switch_priv *priv, int port, - enum scheduler_type sched) -{ - enum scheduler_type t = rtl839x_get_scheduling_algorithm(priv, port); - u32 v, oam_state, oam_port_state; - u32 count; - int i, egress_rate; - - mutex_lock(&priv->reg_mutex); - /* Check whether we need to empty the egress queue of that port due to Errata E0014503 */ - if (sched == WEIGHTED_FAIR_QUEUE && t == WEIGHTED_ROUND_ROBIN && port != priv->cpu_port) { - /* Read Operations, Adminstatrion and Management control register */ - oam_state = sw_r32(RTL839X_OAM_CTRL); - - /* Get current OAM state */ - oam_port_state = sw_r32(RTL839X_OAM_PORT_ACT_CTRL(port)); - - /* Disable OAM to block traffice */ - v = sw_r32(RTL839X_OAM_CTRL); - sw_w32_mask(0, 1, RTL839X_OAM_CTRL); - v = sw_r32(RTL839X_OAM_CTRL); - - /* Set to trap action OAM forward (bits 1, 2) and OAM Mux Action Drop (bit 0) */ - sw_w32(0x2, RTL839X_OAM_PORT_ACT_CTRL(port)); - - /* Set port egress rate to unlimited */ - egress_rate = rtl839x_set_egress_rate(priv, port, 0xFFFFF); - - /* Wait until the egress used page count of that port is 0 */ - i = 0; - do { - usleep_range(100, 200); - rtl839x_read_out_q_table(port); - count = sw_r32(RTL839X_TBL_ACCESS_DATA_2(6)); - count >>= 20; - i++; - } while (i < 3500 && count > 0); - } - - /* Actually set the scheduling algorithm */ - rtl839x_read_scheduling_table(port); - sw_w32_mask(BIT(19), sched ? BIT(19) : 0, RTL839X_TBL_ACCESS_DATA_2(8)); - rtl839x_write_scheduling_table(port); - - if (sched == WEIGHTED_FAIR_QUEUE && t == WEIGHTED_ROUND_ROBIN && port != priv->cpu_port) { - /* Restore OAM state to control register */ - sw_w32(oam_state, RTL839X_OAM_CTRL); - - /* Restore trap action state */ - sw_w32(oam_port_state, RTL839X_OAM_PORT_ACT_CTRL(port)); - - /* Restore port egress rate */ - rtl839x_set_egress_rate(priv, port, egress_rate); - } - - mutex_unlock(&priv->reg_mutex); -} - -void rtl839x_set_scheduling_queue_weights(struct rtl838x_switch_priv *priv, int port, - int *queue_weights) -{ - mutex_lock(&priv->reg_mutex); - - rtl839x_read_scheduling_table(port); - - for (int i = 0; i < 8; i++) { - int lsb = 48 + i * 8; - int low_byte = 8 - (lsb >> 5); - int start_bit = lsb - (low_byte << 5); - int high_mask = 0x3ff >> (32 - start_bit); - - sw_w32_mask(0x3ff << start_bit, (queue_weights[i] & 0x3ff) << start_bit, - RTL839X_TBL_ACCESS_DATA_2(low_byte)); - if (high_mask) - sw_w32_mask(high_mask, (queue_weights[i] & 0x3ff) >> (32- start_bit), - RTL839X_TBL_ACCESS_DATA_2(low_byte - 1)); - } - - rtl839x_write_scheduling_table(port); - mutex_unlock(&priv->reg_mutex); -} - -void rtl838x_config_qos(void) -{ - u32 v; - - pr_info("Setting up RTL838X QoS\n"); - pr_info("RTL838X_PRI_SEL_TBL_CTRL(i): %08x\n", sw_r32(RTL838X_PRI_SEL_TBL_CTRL(0))); - rtl83xx_setup_default_prio2queue(); - - /* Enable inner (bit 12) and outer (bit 13) priority remapping from DSCP */ - sw_w32_mask(0, BIT(12) | BIT(13), RTL838X_PRI_DSCP_INVLD_CTRL0); - - /* Set default weight for calculating internal priority, in prio selection group 0 - * Port based (prio 3), Port outer-tag (4), DSCP (5), Inner Tag (6), Outer Tag (7) - */ - v = 3 | (4 << 3) | (5 << 6) | (6 << 9) | (7 << 12); - sw_w32(v, RTL838X_PRI_SEL_TBL_CTRL(0)); - - /* Set the inner and outer priority one-to-one to re-marked outer dot1p priority */ - v = 0; - for (int p = 0; p < 8; p++) - v |= p << (3 * p); - sw_w32(v, RTL838X_RMK_OPRI_CTRL); - sw_w32(v, RTL838X_RMK_IPRI_CTRL); - - v = 0; - for (int p = 0; p < 8; p++) - v |= (dot1p_priority_remapping[p] & 0x7) << (p * 3); - sw_w32(v, RTL838X_PRI_SEL_IPRI_REMAP); - - /* On all ports set scheduler type to WFQ */ - for (int i = 0; i <= soc_info.cpu_port; i++) - sw_w32(0, RTL838X_SCHED_P_TYPE_CTRL(i)); - - /* Enable egress scheduler for CPU-Port */ - sw_w32_mask(0, BIT(8), RTL838X_SCHED_LB_CTRL(soc_info.cpu_port)); - - /* Enable egress drop allways on */ - sw_w32_mask(0, BIT(11), RTL838X_FC_P_EGR_DROP_CTRL(soc_info.cpu_port)); - - /* Give special trap frames priority 7 (BPDUs) and routing exceptions: */ - sw_w32_mask(0, 7 << 3 | 7, RTL838X_QM_PKT2CPU_INTPRI_2); - /* Give RMA frames priority 7: */ - sw_w32_mask(0, 7, RTL838X_QM_PKT2CPU_INTPRI_1); -} - -void rtl839x_config_qos(void) -{ - u32 v; - struct rtl838x_switch_priv *priv = switch_priv; - - pr_info("Setting up RTL839X QoS\n"); - pr_info("RTL839X_PRI_SEL_TBL_CTRL(i): %08x\n", sw_r32(RTL839X_PRI_SEL_TBL_CTRL(0))); - rtl83xx_setup_default_prio2queue(); - - for (int port = 0; port < soc_info.cpu_port; port++) - sw_w32(7, RTL839X_QM_PORT_QNUM(port)); - - /* CPU-port gets queue number 7 */ - sw_w32(7, RTL839X_QM_PORT_QNUM(soc_info.cpu_port)); - - for (int port = 0; port <= soc_info.cpu_port; port++) { - rtl83xx_set_ingress_priority(port, 0); - rtl839x_set_scheduling_algorithm(priv, port, WEIGHTED_FAIR_QUEUE); - rtl839x_set_scheduling_queue_weights(priv, port, default_queue_weights); - /* Do re-marking based on outer tag */ - sw_w32_mask(0, BIT(port % 32), RTL839X_RMK_PORT_DEI_TAG_CTRL(port)); - } - - /* Remap dot1p priorities to internal priority, for this the outer tag needs be re-marked */ - v = 0; - for (int p = 0; p < 8; p++) - v |= (dot1p_priority_remapping[p] & 0x7) << (p * 3); - sw_w32(v, RTL839X_PRI_SEL_IPRI_REMAP); - - /* Configure Drop Precedence for Drop Eligible Indicator (DEI) - * Index 0: 0 - * Index 1: 2 - * Each indicator is 2 bits long - */ - sw_w32(2 << 2, RTL839X_PRI_SEL_DEI2DP_REMAP); - - /* Re-mark DEI: 4 bit-fields of 2 bits each, field 0 is bits 0-1, ... */ - sw_w32((0x1 << 2) | (0x1 << 4), RTL839X_RMK_DEI_CTRL); - - /* Set Congestion avoidance drop probability to 0 for drop precedences 0-2 (bits 24-31) - * low threshold (bits 0-11) to 4095 and high threshold (bits 12-23) to 4095 - * Weighted Random Early Detection (WRED) is used - */ - sw_w32(4095 << 12| 4095, RTL839X_WRED_PORT_THR_CTRL(0)); - sw_w32(4095 << 12| 4095, RTL839X_WRED_PORT_THR_CTRL(1)); - sw_w32(4095 << 12| 4095, RTL839X_WRED_PORT_THR_CTRL(2)); - - /* Set queue-based congestion avoidance properties, register fields are as - * for forward RTL839X_WRED_PORT_THR_CTRL - */ - for (int q = 0; q < 8; q++) { - sw_w32(255 << 24 | 78 << 12 | 68, RTL839X_WRED_QUEUE_THR_CTRL(q, 0)); - sw_w32(255 << 24 | 74 << 12 | 64, RTL839X_WRED_QUEUE_THR_CTRL(q, 0)); - sw_w32(255 << 24 | 70 << 12 | 60, RTL839X_WRED_QUEUE_THR_CTRL(q, 0)); - } -} - -void __init rtl83xx_setup_qos(struct rtl838x_switch_priv *priv) -{ - switch_priv = priv; - - pr_info("In %s\n", __func__); - - if (priv->family_id == RTL8380_FAMILY_ID) - return rtl838x_config_qos(); - else if (priv->family_id == RTL8390_FAMILY_ID) - return rtl839x_config_qos(); - - if (priv->family_id == RTL8380_FAMILY_ID) - rtl838x_rate_control_init(priv); - else if (priv->family_id == RTL8390_FAMILY_ID) - rtl839x_rate_control_init(priv); -} diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.c deleted file mode 100644 index d93087f5b1aa6c..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.c +++ /dev/null @@ -1,2036 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include -#include - -#include "rtl83xx.h" - -#define RTL838X_VLAN_PORT_TAG_STS_UNTAG 0x0 -#define RTL838X_VLAN_PORT_TAG_STS_TAGGED 0x1 -#define RTL838X_VLAN_PORT_TAG_STS_PRIORITY_TAGGED 0x2 - -#define RTL838X_VLAN_PORT_TAG_STS_CTRL_BASE 0xA530 -/* port 0-28 */ -#define RTL838X_VLAN_PORT_TAG_STS_CTRL(port) \ - RTL838X_VLAN_PORT_TAG_STS_CTRL_BASE + (port << 2) - -#define RTL838X_VLAN_PORT_TAG_STS_CTRL_EGR_P_OTAG_KEEP_MASK GENMASK(11,10) -#define RTL838X_VLAN_PORT_TAG_STS_CTRL_EGR_P_ITAG_KEEP_MASK GENMASK(9,8) -#define RTL838X_VLAN_PORT_TAG_STS_CTRL_IGR_P_OTAG_KEEP_MASK GENMASK(7,6) -#define RTL838X_VLAN_PORT_TAG_STS_CTRL_IGR_P_ITAG_KEEP_MASK GENMASK(5,4) -#define RTL838X_VLAN_PORT_TAG_STS_CTRL_OTAG_STS_MASK GENMASK(3,2) -#define RTL838X_VLAN_PORT_TAG_STS_CTRL_ITAG_STS_MASK GENMASK(1,0) - -extern struct mutex smi_lock; - -/* see_dal_maple_acl_log2PhyTmplteField and src/app/diag_v2/src/diag_acl.c */ -/* Definition of the RTL838X-specific template field IDs as used in the PIE */ -enum template_field_id { - TEMPLATE_FIELD_SPMMASK = 0, - TEMPLATE_FIELD_SPM0 = 1, /* Source portmask ports 0-15 */ - TEMPLATE_FIELD_SPM1 = 2, /* Source portmask ports 16-28 */ - TEMPLATE_FIELD_RANGE_CHK = 3, - TEMPLATE_FIELD_DMAC0 = 4, /* Destination MAC [15:0] */ - TEMPLATE_FIELD_DMAC1 = 5, /* Destination MAC [31:16] */ - TEMPLATE_FIELD_DMAC2 = 6, /* Destination MAC [47:32] */ - TEMPLATE_FIELD_SMAC0 = 7, /* Source MAC [15:0] */ - TEMPLATE_FIELD_SMAC1 = 8, /* Source MAC [31:16] */ - TEMPLATE_FIELD_SMAC2 = 9, /* Source MAC [47:32] */ - TEMPLATE_FIELD_ETHERTYPE = 10, /* Ethernet typ */ - TEMPLATE_FIELD_OTAG = 11, /* Outer VLAN tag */ - TEMPLATE_FIELD_ITAG = 12, /* Inner VLAN tag */ - TEMPLATE_FIELD_SIP0 = 13, /* IPv4 or IPv6 source IP[15:0] or ARP/RARP */ - /* source protocol address in header */ - TEMPLATE_FIELD_SIP1 = 14, /* IPv4 or IPv6 source IP[31:16] or ARP/RARP */ - TEMPLATE_FIELD_DIP0 = 15, /* IPv4 or IPv6 destination IP[15:0] */ - TEMPLATE_FIELD_DIP1 = 16, /* IPv4 or IPv6 destination IP[31:16] */ - TEMPLATE_FIELD_IP_TOS_PROTO = 17, /* IPv4 TOS/IPv6 traffic class and */ - /* IPv4 proto/IPv6 next header fields */ - TEMPLATE_FIELD_L34_HEADER = 18, /* packet with extra tag and IPv6 with auth, dest, */ - /* frag, route, hop-by-hop option header, */ - /* IGMP type, TCP flag */ - TEMPLATE_FIELD_L4_SPORT = 19, /* TCP/UDP source port */ - TEMPLATE_FIELD_L4_DPORT = 20, /* TCP/UDP destination port */ - TEMPLATE_FIELD_ICMP_IGMP = 21, - TEMPLATE_FIELD_IP_RANGE = 22, - TEMPLATE_FIELD_FIELD_SELECTOR_VALID = 23, /* Field selector mask */ - TEMPLATE_FIELD_FIELD_SELECTOR_0 = 24, - TEMPLATE_FIELD_FIELD_SELECTOR_1 = 25, - TEMPLATE_FIELD_FIELD_SELECTOR_2 = 26, - TEMPLATE_FIELD_FIELD_SELECTOR_3 = 27, - TEMPLATE_FIELD_SIP2 = 28, /* IPv6 source IP[47:32] */ - TEMPLATE_FIELD_SIP3 = 29, /* IPv6 source IP[63:48] */ - TEMPLATE_FIELD_SIP4 = 30, /* IPv6 source IP[79:64] */ - TEMPLATE_FIELD_SIP5 = 31, /* IPv6 source IP[95:80] */ - TEMPLATE_FIELD_SIP6 = 32, /* IPv6 source IP[111:96] */ - TEMPLATE_FIELD_SIP7 = 33, /* IPv6 source IP[127:112] */ - TEMPLATE_FIELD_DIP2 = 34, /* IPv6 destination IP[47:32] */ - TEMPLATE_FIELD_DIP3 = 35, /* IPv6 destination IP[63:48] */ - TEMPLATE_FIELD_DIP4 = 36, /* IPv6 destination IP[79:64] */ - TEMPLATE_FIELD_DIP5 = 37, /* IPv6 destination IP[95:80] */ - TEMPLATE_FIELD_DIP6 = 38, /* IPv6 destination IP[111:96] */ - TEMPLATE_FIELD_DIP7 = 39, /* IPv6 destination IP[127:112] */ - TEMPLATE_FIELD_FWD_VID = 40, /* Forwarding VLAN-ID */ - TEMPLATE_FIELD_FLOW_LABEL = 41, -}; - -/* The RTL838X SoCs use 5 fixed templates with definitions for which data fields are to - * be copied from the Ethernet Frame header into the 12 User-definable fields of the Packet - * Inspection Engine's buffer. The following defines the field contents for each of the fixed - * templates. Additionally, 3 user-definable templates can be set up via the definitions - * in RTL838X_ACL_TMPLTE_CTRL control registers. - * TODO: See all src/app/diag_v2/src/diag_pie.c - */ -#define N_FIXED_TEMPLATES 5 -static enum template_field_id fixed_templates[N_FIXED_TEMPLATES][N_FIXED_FIELDS] = -{ - { - TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1, TEMPLATE_FIELD_OTAG, - TEMPLATE_FIELD_SMAC0, TEMPLATE_FIELD_SMAC1, TEMPLATE_FIELD_SMAC2, - TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2, - TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_ITAG, TEMPLATE_FIELD_RANGE_CHK - }, { - TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0, - TEMPLATE_FIELD_DIP1,TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_L4_SPORT, - TEMPLATE_FIELD_L4_DPORT, TEMPLATE_FIELD_ICMP_IGMP, TEMPLATE_FIELD_ITAG, - TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1 - }, { - TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2, - TEMPLATE_FIELD_ITAG, TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_IP_TOS_PROTO, - TEMPLATE_FIELD_L4_DPORT, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_SIP0, - TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0, TEMPLATE_FIELD_DIP1 - }, { - TEMPLATE_FIELD_DIP0, TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_DIP2, - TEMPLATE_FIELD_DIP3, TEMPLATE_FIELD_DIP4, TEMPLATE_FIELD_DIP5, - TEMPLATE_FIELD_DIP6, TEMPLATE_FIELD_DIP7, TEMPLATE_FIELD_L4_DPORT, - TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_ICMP_IGMP, TEMPLATE_FIELD_IP_TOS_PROTO - }, { - TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_SIP2, - TEMPLATE_FIELD_SIP3, TEMPLATE_FIELD_SIP4, TEMPLATE_FIELD_SIP5, - TEMPLATE_FIELD_SIP6, TEMPLATE_FIELD_SIP7, TEMPLATE_FIELD_ITAG, - TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1 - }, -}; - -void rtl838x_print_matrix(void) -{ - unsigned volatile int *ptr8; - - ptr8 = RTL838X_SW_BASE + RTL838X_PORT_ISO_CTRL(0); - for (int i = 0; i < 28; i += 8) - pr_debug("> %8x %8x %8x %8x %8x %8x %8x %8x\n", - ptr8[i + 0], ptr8[i + 1], ptr8[i + 2], ptr8[i + 3], - ptr8[i + 4], ptr8[i + 5], ptr8[i + 6], ptr8[i + 7]); - pr_debug("CPU_PORT> %8x\n", ptr8[28]); -} - -static inline int rtl838x_port_iso_ctrl(int p) -{ - return RTL838X_PORT_ISO_CTRL(p); -} - -static inline void rtl838x_exec_tbl0_cmd(u32 cmd) -{ - sw_w32(cmd, RTL838X_TBL_ACCESS_CTRL_0); - do { } while (sw_r32(RTL838X_TBL_ACCESS_CTRL_0) & BIT(15)); -} - -static inline void rtl838x_exec_tbl1_cmd(u32 cmd) -{ - sw_w32(cmd, RTL838X_TBL_ACCESS_CTRL_1); - do { } while (sw_r32(RTL838X_TBL_ACCESS_CTRL_1) & BIT(15)); -} - -static inline int rtl838x_tbl_access_data_0(int i) -{ - return RTL838X_TBL_ACCESS_DATA_0(i); -} - -static void rtl838x_vlan_tables_read(u32 vlan, struct rtl838x_vlan_info *info) -{ - u32 v; - /* Read VLAN table (0) via register 0 */ - struct table_reg *r = rtl_table_get(RTL8380_TBL_0, 0); - - rtl_table_read(r, vlan); - info->tagged_ports = sw_r32(rtl_table_data(r, 0)); - v = sw_r32(rtl_table_data(r, 1)); - pr_debug("VLAN_READ %d: %016llx %08x\n", vlan, info->tagged_ports, v); - rtl_table_release(r); - - info->profile_id = v & 0x7; - info->hash_mc_fid = !!(v & 0x8); - info->hash_uc_fid = !!(v & 0x10); - info->fid = (v >> 5) & 0x3f; - - /* Read UNTAG table (0) via table register 1 */ - r = rtl_table_get(RTL8380_TBL_1, 0); - rtl_table_read(r, vlan); - info->untagged_ports = sw_r32(rtl_table_data(r, 0)); - rtl_table_release(r); -} - -static void rtl838x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info) -{ - u32 v; - /* Access VLAN table (0) via register 0 */ - struct table_reg *r = rtl_table_get(RTL8380_TBL_0, 0); - - sw_w32(info->tagged_ports, rtl_table_data(r, 0)); - - v = info->profile_id; - v |= info->hash_mc_fid ? 0x8 : 0; - v |= info->hash_uc_fid ? 0x10 : 0; - v |= ((u32)info->fid) << 5; - sw_w32(v, rtl_table_data(r, 1)); - - rtl_table_write(r, vlan); - rtl_table_release(r); -} - -static void rtl838x_vlan_set_untagged(u32 vlan, u64 portmask) -{ - /* Access UNTAG table (0) via register 1 */ - struct table_reg *r = rtl_table_get(RTL8380_TBL_1, 0); - - sw_w32(portmask & 0x1fffffff, rtl_table_data(r, 0)); - rtl_table_write(r, vlan); - rtl_table_release(r); -} - -/* Sets the L2 forwarding to be based on either the inner VLAN tag or the outer - */ -static void rtl838x_vlan_fwd_on_inner(int port, bool is_set) -{ - if (is_set) - sw_w32_mask(BIT(port), 0, RTL838X_VLAN_PORT_FWD); - else - sw_w32_mask(0, BIT(port), RTL838X_VLAN_PORT_FWD); -} - -static u64 rtl838x_l2_hash_seed(u64 mac, u32 vid) -{ - return mac << 12 | vid; -} - -/* Applies the same hash algorithm as the one used currently by the ASIC to the seed - * and returns a key into the L2 hash table - */ -static u32 rtl838x_l2_hash_key(struct rtl838x_switch_priv *priv, u64 seed) -{ - u32 h1, h2, h3, h; - - if (sw_r32(priv->r->l2_ctrl_0) & 1) { - h1 = (seed >> 11) & 0x7ff; - h1 = ((h1 & 0x1f) << 6) | ((h1 >> 5) & 0x3f); - - h2 = (seed >> 33) & 0x7ff; - h2 = ((h2 & 0x3f) << 5) | ((h2 >> 6) & 0x1f); - - h3 = (seed >> 44) & 0x7ff; - h3 = ((h3 & 0x7f) << 4) | ((h3 >> 7) & 0xf); - - h = h1 ^ h2 ^ h3 ^ ((seed >> 55) & 0x1ff); - h ^= ((seed >> 22) & 0x7ff) ^ (seed & 0x7ff); - } else { - h = ((seed >> 55) & 0x1ff) ^ ((seed >> 44) & 0x7ff) ^ - ((seed >> 33) & 0x7ff) ^ ((seed >> 22) & 0x7ff) ^ - ((seed >> 11) & 0x7ff) ^ (seed & 0x7ff); - } - - return h; -} - -static inline int rtl838x_mac_force_mode_ctrl(int p) -{ - return RTL838X_MAC_FORCE_MODE_CTRL + (p << 2); -} - -static inline int rtl838x_mac_port_ctrl(int p) -{ - return RTL838X_MAC_PORT_CTRL(p); -} - -static inline int rtl838x_l2_port_new_salrn(int p) -{ - return RTL838X_L2_PORT_NEW_SALRN(p); -} - -static inline int rtl838x_l2_port_new_sa_fwd(int p) -{ - return RTL838X_L2_PORT_NEW_SA_FWD(p); -} - -static inline int rtl838x_mac_link_spd_sts(int p) -{ - return RTL838X_MAC_LINK_SPD_STS(p); -} - -inline static int rtl838x_trk_mbr_ctr(int group) -{ - return RTL838X_TRK_MBR_CTR + (group << 2); -} - -/* Fills an L2 entry structure from the SoC registers */ -static void rtl838x_fill_l2_entry(u32 r[], struct rtl838x_l2_entry *e) -{ - /* Table contains different entry types, we need to identify the right one: - * Check for MC entries, first - * In contrast to the RTL93xx SoCs, there is no valid bit, use heuristics to - * identify valid entries - */ - e->is_ip_mc = !!(r[0] & BIT(22)); - e->is_ipv6_mc = !!(r[0] & BIT(21)); - e->type = L2_INVALID; - - if (!e->is_ip_mc && !e->is_ipv6_mc) { - e->mac[0] = (r[1] >> 20); - e->mac[1] = (r[1] >> 12); - e->mac[2] = (r[1] >> 4); - e->mac[3] = (r[1] & 0xf) << 4 | (r[2] >> 28); - e->mac[4] = (r[2] >> 20); - e->mac[5] = (r[2] >> 12); - - e->rvid = r[2] & 0xfff; - e->vid = r[0] & 0xfff; - - /* Is it a unicast entry? check multicast bit */ - if (!(e->mac[0] & 1)) { - e->is_static = !!((r[0] >> 19) & 1); - e->port = (r[0] >> 12) & 0x1f; - e->block_da = !!(r[1] & BIT(30)); - e->block_sa = !!(r[1] & BIT(31)); - e->suspended = !!(r[1] & BIT(29)); - e->next_hop = !!(r[1] & BIT(28)); - if (e->next_hop) { - pr_debug("Found next hop entry, need to read extra data\n"); - e->nh_vlan_target = !!(r[0] & BIT(9)); - e->nh_route_id = r[0] & 0x1ff; - e->vid = e->rvid; - } - e->age = (r[0] >> 17) & 0x3; - e->valid = true; - - /* A valid entry has one of mutli-cast, aging, sa/da-blocking, - * next-hop or static entry bit set - */ - if (!(r[0] & 0x007c0000) && !(r[1] & 0xd0000000)) - e->valid = false; - else - e->type = L2_UNICAST; - } else { /* L2 multicast */ - pr_debug("Got L2 MC entry: %08x %08x %08x\n", r[0], r[1], r[2]); - e->valid = true; - e->type = L2_MULTICAST; - e->mc_portmask_index = (r[0] >> 12) & 0x1ff; - } - } else { /* IPv4 and IPv6 multicast */ - e->valid = true; - e->mc_portmask_index = (r[0] >> 12) & 0x1ff; - e->mc_gip = (r[1] << 20) | (r[2] >> 12); - e->rvid = r[2] & 0xfff; - } - if (e->is_ip_mc) - e->type = IP4_MULTICAST; - if (e->is_ipv6_mc) - e->type = IP6_MULTICAST; -} - -/* Fills the 3 SoC table registers r[] with the information of in the rtl838x_l2_entry */ -static void rtl838x_fill_l2_row(u32 r[], struct rtl838x_l2_entry *e) -{ - u64 mac = ether_addr_to_u64(e->mac); - - if (!e->valid) { - r[0] = r[1] = r[2] = 0; - return; - } - - r[0] = e->is_ip_mc ? BIT(22) : 0; - r[0] |= e->is_ipv6_mc ? BIT(21) : 0; - - if (!e->is_ip_mc && !e->is_ipv6_mc) { - r[1] = mac >> 20; - r[2] = (mac & 0xfffff) << 12; - - /* Is it a unicast entry? check multicast bit */ - if (!(e->mac[0] & 1)) { - r[0] |= e->is_static ? BIT(19) : 0; - r[0] |= (e->port & 0x3f) << 12; - r[0] |= e->vid; - r[1] |= e->block_da ? BIT(30) : 0; - r[1] |= e->block_sa ? BIT(31) : 0; - r[1] |= e->suspended ? BIT(29) : 0; - r[2] |= e->rvid & 0xfff; - if (e->next_hop) { - r[1] |= BIT(28); - r[0] |= e->nh_vlan_target ? BIT(9) : 0; - r[0] |= e->nh_route_id & 0x1ff; - } - r[0] |= (e->age & 0x3) << 17; - } else { /* L2 Multicast */ - r[0] |= (e->mc_portmask_index & 0x1ff) << 12; - r[2] |= e->rvid & 0xfff; - r[0] |= e->vid & 0xfff; - pr_debug("FILL MC: %08x %08x %08x\n", r[0], r[1], r[2]); - } - } else { /* IPv4 and IPv6 multicast */ - r[0] |= (e->mc_portmask_index & 0x1ff) << 12; - r[1] = e->mc_gip >> 20; - r[2] = e->mc_gip << 12; - r[2] |= e->rvid; - } -} - -/* Read an L2 UC or MC entry out of a hash bucket of the L2 forwarding table - * hash is the id of the bucket and pos is the position of the entry in that bucket - * The data read from the SoC is filled into rtl838x_l2_entry - */ -static u64 rtl838x_read_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 0); /* Access L2 Table 0 */ - u32 idx = (0 << 14) | (hash << 2) | pos; /* Search SRAM, with hash and at pos in bucket */ - - rtl_table_read(q, idx); - for (int i = 0; i < 3; i++) - r[i] = sw_r32(rtl_table_data(q, i)); - - rtl_table_release(q); - - rtl838x_fill_l2_entry(r, e); - if (!e->valid) - return 0; - - return (((u64) r[1]) << 32) | (r[2]); /* mac and vid concatenated as hash seed */ -} - -static void rtl838x_write_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 0); - - u32 idx = (0 << 14) | (hash << 2) | pos; /* Access SRAM, with hash and at pos in bucket */ - - rtl838x_fill_l2_row(r, e); - - for (int i = 0; i < 3; i++) - sw_w32(r[i], rtl_table_data(q, i)); - - rtl_table_write(q, idx); - rtl_table_release(q); -} - -static u64 rtl838x_read_cam(int idx, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 1); /* Access L2 Table 1 */ - - rtl_table_read(q, idx); - for (int i = 0; i < 3; i++) - r[i] = sw_r32(rtl_table_data(q, i)); - - rtl_table_release(q); - - rtl838x_fill_l2_entry(r, e); - if (!e->valid) - return 0; - - pr_debug("Found in CAM: R1 %x R2 %x R3 %x\n", r[0], r[1], r[2]); - - /* Return MAC with concatenated VID ac concatenated ID */ - return (((u64) r[1]) << 32) | r[2]; -} - -static void rtl838x_write_cam(int idx, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 1); /* Access L2 Table 1 */ - - rtl838x_fill_l2_row(r, e); - - for (int i = 0; i < 3; i++) - sw_w32(r[i], rtl_table_data(q, i)); - - rtl_table_write(q, idx); - rtl_table_release(q); -} - -static u64 rtl838x_read_mcast_pmask(int idx) -{ - u32 portmask; - /* Read MC_PMSK (2) via register RTL8380_TBL_L2 */ - struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 2); - - rtl_table_read(q, idx); - portmask = sw_r32(rtl_table_data(q, 0)); - rtl_table_release(q); - - return portmask; -} - -static void rtl838x_write_mcast_pmask(int idx, u64 portmask) -{ - /* Access MC_PMSK (2) via register RTL8380_TBL_L2 */ - struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 2); - - sw_w32(((u32)portmask) & 0x1fffffff, rtl_table_data(q, 0)); - rtl_table_write(q, idx); - rtl_table_release(q); -} - -static void rtl838x_vlan_profile_setup(int profile) -{ - u32 pmask_id = UNKNOWN_MC_PMASK; - /* Enable L2 Learning BIT 0, portmask UNKNOWN_MC_PMASK for unknown MC traffic flooding */ - u32 p = 1 | pmask_id << 1 | pmask_id << 10 | pmask_id << 19; - - sw_w32(p, RTL838X_VLAN_PROFILE(profile)); - - /* RTL8380 and RTL8390 use an index into the portmask table to set the - * unknown multicast portmask, setup a default at a safe location - * On RTL93XX, the portmask is directly set in the profile, - * see e.g. rtl9300_vlan_profile_setup - */ - rtl838x_write_mcast_pmask(UNKNOWN_MC_PMASK, 0x1fffffff); -} - -static void rtl838x_l2_learning_setup(void) -{ - /* Set portmask for broadcast traffic and unknown unicast address flooding - * to the reserved entry in the portmask table used also for - * multicast flooding */ - sw_w32(UNKNOWN_MC_PMASK << 12 | UNKNOWN_MC_PMASK, RTL838X_L2_FLD_PMSK); - - /* Enable learning constraint system-wide (bit 0), per-port (bit 1) - * and per vlan (bit 2) */ - sw_w32(0x7, RTL838X_L2_LRN_CONSTRT_EN); - - /* Limit learning to maximum: 16k entries, after that just flood (bits 0-1) */ - sw_w32((0x3fff << 2) | 0, RTL838X_L2_LRN_CONSTRT); - - /* Do not trap ARP packets to CPU_PORT */ - sw_w32(0, RTL838X_SPCL_TRAP_ARP_CTRL); -} - -static void rtl838x_enable_learning(int port, bool enable) -{ - /* Limit learning to maximum: 16k entries */ - - sw_w32_mask(0x3fff << 2, enable ? (0x3fff << 2) : 0, - RTL838X_L2_PORT_LRN_CONSTRT + (port << 2)); -} - -static void rtl838x_enable_flood(int port, bool enable) -{ - /* 0: Forward - * 1: Disable - * 2: to CPU - * 3: Copy to CPU - */ - sw_w32_mask(0x3, enable ? 0 : 1, - RTL838X_L2_PORT_LRN_CONSTRT + (port << 2)); -} - -static void rtl838x_enable_mcast_flood(int port, bool enable) -{ - -} - -static void rtl838x_enable_bcast_flood(int port, bool enable) -{ - -} - -static void rtl838x_set_static_move_action(int port, bool forward) -{ - int shift = MV_ACT_PORT_SHIFT(port); - u32 val = forward ? MV_ACT_FORWARD : MV_ACT_DROP; - - sw_w32_mask(MV_ACT_MASK << shift, val << shift, - RTL838X_L2_PORT_STATIC_MV_ACT(port)); -} - -static void rtl838x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]) -{ - u32 cmd = 1 << 15 | /* Execute cmd */ - 1 << 14 | /* Read */ - 2 << 12 | /* Table type 0b10 */ - (msti & 0xfff); - priv->r->exec_tbl0_cmd(cmd); - - for (int i = 0; i < 2; i++) - port_state[i] = sw_r32(priv->r->tbl_access_data_0(i)); -} - -static void rtl838x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]) -{ - u32 cmd = 1 << 15 | /* Execute cmd */ - 0 << 14 | /* Write */ - 2 << 12 | /* Table type 0b10 */ - (msti & 0xfff); - - for (int i = 0; i < 2; i++) - sw_w32(port_state[i], priv->r->tbl_access_data_0(i)); - priv->r->exec_tbl0_cmd(cmd); -} - -u64 rtl838x_traffic_get(int source) -{ - return rtl838x_get_port_reg(rtl838x_port_iso_ctrl(source)); -} - -void rtl838x_traffic_set(int source, u64 dest_matrix) -{ - rtl838x_set_port_reg(dest_matrix, rtl838x_port_iso_ctrl(source)); -} - -void rtl838x_traffic_enable(int source, int dest) -{ - rtl838x_mask_port_reg(0, BIT(dest), rtl838x_port_iso_ctrl(source)); -} - -void rtl838x_traffic_disable(int source, int dest) -{ - rtl838x_mask_port_reg(BIT(dest), 0, rtl838x_port_iso_ctrl(source)); -} - -/* Enables or disables the EEE/EEEP capability of a port */ -static void rtl838x_port_eee_set(struct rtl838x_switch_priv *priv, int port, bool enable) -{ - u32 v; - - /* This works only for Ethernet ports, and on the RTL838X, ports from 24 are SFP */ - if (port >= 24) - return; - - pr_debug("In %s: setting port %d to %d\n", __func__, port, enable); - v = enable ? 0x3 : 0x0; - - /* Set EEE state for 100 (bit 9) & 1000MBit (bit 10) */ - sw_w32_mask(0x3 << 9, v << 9, priv->r->mac_force_mode_ctrl(port)); - - /* Set TX/RX EEE state */ - if (enable) { - sw_w32_mask(0, BIT(port), RTL838X_EEE_PORT_TX_EN); - sw_w32_mask(0, BIT(port), RTL838X_EEE_PORT_RX_EN); - } else { - sw_w32_mask(BIT(port), 0, RTL838X_EEE_PORT_TX_EN); - sw_w32_mask(BIT(port), 0, RTL838X_EEE_PORT_RX_EN); - } - priv->ports[port].eee_enabled = enable; -} - - -/* Get EEE own capabilities and negotiation result */ -static int rtl838x_eee_port_ability(struct rtl838x_switch_priv *priv, - struct ethtool_eee *e, int port) -{ - u64 link; - - if (port >= 24) - return 0; - - link = rtl839x_get_port_reg_le(RTL838X_MAC_LINK_STS); - if (!(link & BIT(port))) - return 0; - - if (sw_r32(rtl838x_mac_force_mode_ctrl(port)) & BIT(9)) - e->advertised |= ADVERTISED_100baseT_Full; - - if (sw_r32(rtl838x_mac_force_mode_ctrl(port)) & BIT(10)) - e->advertised |= ADVERTISED_1000baseT_Full; - - if (sw_r32(RTL838X_MAC_EEE_ABLTY) & BIT(port)) { - e->lp_advertised = ADVERTISED_100baseT_Full; - e->lp_advertised |= ADVERTISED_1000baseT_Full; - return 1; - } - - return 0; -} - -static void rtl838x_init_eee(struct rtl838x_switch_priv *priv, bool enable) -{ - pr_info("Setting up EEE, state: %d\n", enable); - sw_w32_mask(0x4, 0, RTL838X_SMI_GLB_CTRL); - - /* Set timers for EEE */ - sw_w32(0x5001411, RTL838X_EEE_TX_TIMER_GIGA_CTRL); - sw_w32(0x5001417, RTL838X_EEE_TX_TIMER_GELITE_CTRL); - - /* Enable EEE MAC support on ports */ - for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) - rtl838x_port_eee_set(priv, i, enable); - } - priv->eee_enabled = enable; -} - -static void rtl838x_pie_lookup_enable(struct rtl838x_switch_priv *priv, int index) -{ - int block = index / PIE_BLOCK_SIZE; - u32 block_state = sw_r32(RTL838X_ACL_BLK_LOOKUP_CTRL); - - /* Make sure rule-lookup is enabled in the block */ - if (!(block_state & BIT(block))) - sw_w32(block_state | BIT(block), RTL838X_ACL_BLK_LOOKUP_CTRL); -} - -static void rtl838x_pie_rule_del(struct rtl838x_switch_priv *priv, int index_from, int index_to) -{ - int block_from = index_from / PIE_BLOCK_SIZE; - int block_to = index_to / PIE_BLOCK_SIZE; - u32 v = (index_from << 1)| (index_to << 12 ) | BIT(0); - u32 block_state; - - pr_debug("%s: from %d to %d\n", __func__, index_from, index_to); - mutex_lock(&priv->reg_mutex); - - /* Remember currently active blocks */ - block_state = sw_r32(RTL838X_ACL_BLK_LOOKUP_CTRL); - - /* Make sure rule-lookup is disabled in the relevant blocks */ - for (int block = block_from; block <= block_to; block++) { - if (block_state & BIT(block)) - sw_w32(block_state & (~BIT(block)), RTL838X_ACL_BLK_LOOKUP_CTRL); - } - - /* Write from-to and execute bit into control register */ - sw_w32(v, RTL838X_ACL_CLR_CTRL); - - /* Wait until command has completed */ - do { - } while (sw_r32(RTL838X_ACL_CLR_CTRL) & BIT(0)); - - /* Re-enable rule lookup */ - for (int block = block_from; block <= block_to; block++) { - if (!(block_state & BIT(block))) - sw_w32(block_state | BIT(block), RTL838X_ACL_BLK_LOOKUP_CTRL); - } - - mutex_unlock(&priv->reg_mutex); -} - -/* Reads the intermediate representation of the templated match-fields of the - * PIE rule in the pie_rule structure and fills in the raw data fields in the - * raw register space r[]. - * The register space configuration size is identical for the RTL8380/90 and RTL9300, - * however the RTL9310 has 2 more registers / fields and the physical field-ids - * are specific to every platform. - */ -static void rtl838x_write_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[]) -{ - for (int i = 0; i < N_FIXED_FIELDS; i++) { - enum template_field_id field_type = t[i]; - u16 data = 0, data_m = 0; - - switch (field_type) { - case TEMPLATE_FIELD_SPM0: - data = pr->spm; - data_m = pr->spm_m; - break; - case TEMPLATE_FIELD_SPM1: - data = pr->spm >> 16; - data_m = pr->spm_m >> 16; - break; - case TEMPLATE_FIELD_OTAG: - data = pr->otag; - data_m = pr->otag_m; - break; - case TEMPLATE_FIELD_SMAC0: - data = pr->smac[4]; - data = (data << 8) | pr->smac[5]; - data_m = pr->smac_m[4]; - data_m = (data_m << 8) | pr->smac_m[5]; - break; - case TEMPLATE_FIELD_SMAC1: - data = pr->smac[2]; - data = (data << 8) | pr->smac[3]; - data_m = pr->smac_m[2]; - data_m = (data_m << 8) | pr->smac_m[3]; - break; - case TEMPLATE_FIELD_SMAC2: - data = pr->smac[0]; - data = (data << 8) | pr->smac[1]; - data_m = pr->smac_m[0]; - data_m = (data_m << 8) | pr->smac_m[1]; - break; - case TEMPLATE_FIELD_DMAC0: - data = pr->dmac[4]; - data = (data << 8) | pr->dmac[5]; - data_m = pr->dmac_m[4]; - data_m = (data_m << 8) | pr->dmac_m[5]; - break; - case TEMPLATE_FIELD_DMAC1: - data = pr->dmac[2]; - data = (data << 8) | pr->dmac[3]; - data_m = pr->dmac_m[2]; - data_m = (data_m << 8) | pr->dmac_m[3]; - break; - case TEMPLATE_FIELD_DMAC2: - data = pr->dmac[0]; - data = (data << 8) | pr->dmac[1]; - data_m = pr->dmac_m[0]; - data_m = (data_m << 8) | pr->dmac_m[1]; - break; - case TEMPLATE_FIELD_ETHERTYPE: - data = pr->ethertype; - data_m = pr->ethertype_m; - break; - case TEMPLATE_FIELD_ITAG: - data = pr->itag; - data_m = pr->itag_m; - break; - case TEMPLATE_FIELD_RANGE_CHK: - data = pr->field_range_check; - data_m = pr->field_range_check_m; - break; - case TEMPLATE_FIELD_SIP0: - if (pr->is_ipv6) { - data = pr->sip6.s6_addr16[7]; - data_m = pr->sip6_m.s6_addr16[7]; - } else { - data = pr->sip; - data_m = pr->sip_m; - } - break; - case TEMPLATE_FIELD_SIP1: - if (pr->is_ipv6) { - data = pr->sip6.s6_addr16[6]; - data_m = pr->sip6_m.s6_addr16[6]; - } else { - data = pr->sip >> 16; - data_m = pr->sip_m >> 16; - } - break; - case TEMPLATE_FIELD_SIP2: - case TEMPLATE_FIELD_SIP3: - case TEMPLATE_FIELD_SIP4: - case TEMPLATE_FIELD_SIP5: - case TEMPLATE_FIELD_SIP6: - case TEMPLATE_FIELD_SIP7: - data = pr->sip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)]; - data_m = pr->sip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)]; - break; - case TEMPLATE_FIELD_DIP0: - if (pr->is_ipv6) { - data = pr->dip6.s6_addr16[7]; - data_m = pr->dip6_m.s6_addr16[7]; - } else { - data = pr->dip; - data_m = pr->dip_m; - } - break; - case TEMPLATE_FIELD_DIP1: - if (pr->is_ipv6) { - data = pr->dip6.s6_addr16[6]; - data_m = pr->dip6_m.s6_addr16[6]; - } else { - data = pr->dip >> 16; - data_m = pr->dip_m >> 16; - } - break; - case TEMPLATE_FIELD_DIP2: - case TEMPLATE_FIELD_DIP3: - case TEMPLATE_FIELD_DIP4: - case TEMPLATE_FIELD_DIP5: - case TEMPLATE_FIELD_DIP6: - case TEMPLATE_FIELD_DIP7: - data = pr->dip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)]; - data_m = pr->dip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)]; - break; - case TEMPLATE_FIELD_IP_TOS_PROTO: - data = pr->tos_proto; - data_m = pr->tos_proto_m; - break; - case TEMPLATE_FIELD_L4_SPORT: - data = pr->sport; - data_m = pr->sport_m; - break; - case TEMPLATE_FIELD_L4_DPORT: - data = pr->dport; - data_m = pr->dport_m; - break; - case TEMPLATE_FIELD_ICMP_IGMP: - data = pr->icmp_igmp; - data_m = pr->icmp_igmp_m; - break; - default: - pr_info("%s: unknown field %d\n", __func__, field_type); - continue; - } - if (!(i % 2)) { - r[5 - i / 2] = data; - r[12 - i / 2] = data_m; - } else { - r[5 - i / 2] |= ((u32)data) << 16; - r[12 - i / 2] |= ((u32)data_m) << 16; - } - } -} - -/* Creates the intermediate representation of the templated match-fields of the - * PIE rule in the pie_rule structure by reading the raw data fields in the - * raw register space r[]. - * The register space configuration size is identical for the RTL8380/90 and RTL9300, - * however the RTL9310 has 2 more registers / fields and the physical field-ids - */ -static void rtl838x_read_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[]) -{ - for (int i = 0; i < N_FIXED_FIELDS; i++) { - enum template_field_id field_type = t[i]; - u16 data, data_m; - - field_type = t[i]; - if (!(i % 2)) { - data = r[5 - i / 2]; - data_m = r[12 - i / 2]; - } else { - data = r[5 - i / 2] >> 16; - data_m = r[12 - i / 2] >> 16; - } - - switch (field_type) { - case TEMPLATE_FIELD_SPM0: - pr->spm = (pr->spn << 16) | data; - pr->spm_m = (pr->spn << 16) | data_m; - break; - case TEMPLATE_FIELD_SPM1: - pr->spm = data; - pr->spm_m = data_m; - break; - case TEMPLATE_FIELD_OTAG: - pr->otag = data; - pr->otag_m = data_m; - break; - case TEMPLATE_FIELD_SMAC0: - pr->smac[4] = data >> 8; - pr->smac[5] = data; - pr->smac_m[4] = data >> 8; - pr->smac_m[5] = data; - break; - case TEMPLATE_FIELD_SMAC1: - pr->smac[2] = data >> 8; - pr->smac[3] = data; - pr->smac_m[2] = data >> 8; - pr->smac_m[3] = data; - break; - case TEMPLATE_FIELD_SMAC2: - pr->smac[0] = data >> 8; - pr->smac[1] = data; - pr->smac_m[0] = data >> 8; - pr->smac_m[1] = data; - break; - case TEMPLATE_FIELD_DMAC0: - pr->dmac[4] = data >> 8; - pr->dmac[5] = data; - pr->dmac_m[4] = data >> 8; - pr->dmac_m[5] = data; - break; - case TEMPLATE_FIELD_DMAC1: - pr->dmac[2] = data >> 8; - pr->dmac[3] = data; - pr->dmac_m[2] = data >> 8; - pr->dmac_m[3] = data; - break; - case TEMPLATE_FIELD_DMAC2: - pr->dmac[0] = data >> 8; - pr->dmac[1] = data; - pr->dmac_m[0] = data >> 8; - pr->dmac_m[1] = data; - break; - case TEMPLATE_FIELD_ETHERTYPE: - pr->ethertype = data; - pr->ethertype_m = data_m; - break; - case TEMPLATE_FIELD_ITAG: - pr->itag = data; - pr->itag_m = data_m; - break; - case TEMPLATE_FIELD_RANGE_CHK: - pr->field_range_check = data; - pr->field_range_check_m = data_m; - break; - case TEMPLATE_FIELD_SIP0: - pr->sip = data; - pr->sip_m = data_m; - break; - case TEMPLATE_FIELD_SIP1: - pr->sip = (pr->sip << 16) | data; - pr->sip_m = (pr->sip << 16) | data_m; - break; - case TEMPLATE_FIELD_SIP2: - pr->is_ipv6 = true; - /* Make use of limitiations on the position of the match values */ - ipv6_addr_set(&pr->sip6, pr->sip, r[5 - i / 2], - r[4 - i / 2], r[3 - i / 2]); - ipv6_addr_set(&pr->sip6_m, pr->sip_m, r[5 - i / 2], - r[4 - i / 2], r[3 - i / 2]); - case TEMPLATE_FIELD_SIP3: - case TEMPLATE_FIELD_SIP4: - case TEMPLATE_FIELD_SIP5: - case TEMPLATE_FIELD_SIP6: - case TEMPLATE_FIELD_SIP7: - break; - case TEMPLATE_FIELD_DIP0: - pr->dip = data; - pr->dip_m = data_m; - break; - case TEMPLATE_FIELD_DIP1: - pr->dip = (pr->dip << 16) | data; - pr->dip_m = (pr->dip << 16) | data_m; - break; - case TEMPLATE_FIELD_DIP2: - pr->is_ipv6 = true; - ipv6_addr_set(&pr->dip6, pr->dip, r[5 - i / 2], - r[4 - i / 2], r[3 - i / 2]); - ipv6_addr_set(&pr->dip6_m, pr->dip_m, r[5 - i / 2], - r[4 - i / 2], r[3 - i / 2]); - case TEMPLATE_FIELD_DIP3: - case TEMPLATE_FIELD_DIP4: - case TEMPLATE_FIELD_DIP5: - case TEMPLATE_FIELD_DIP6: - case TEMPLATE_FIELD_DIP7: - break; - case TEMPLATE_FIELD_IP_TOS_PROTO: - pr->tos_proto = data; - pr->tos_proto_m = data_m; - break; - case TEMPLATE_FIELD_L4_SPORT: - pr->sport = data; - pr->sport_m = data_m; - break; - case TEMPLATE_FIELD_L4_DPORT: - pr->dport = data; - pr->dport_m = data_m; - break; - case TEMPLATE_FIELD_ICMP_IGMP: - pr->icmp_igmp = data; - pr->icmp_igmp_m = data_m; - break; - default: - pr_info("%s: unknown field %d\n", __func__, field_type); - } - } -} - -static void rtl838x_read_pie_fixed_fields(u32 r[], struct pie_rule *pr) -{ - pr->spmmask_fix = (r[6] >> 22) & 0x3; - pr->spn = (r[6] >> 16) & 0x3f; - pr->mgnt_vlan = (r[6] >> 15) & 1; - pr->dmac_hit_sw = (r[6] >> 14) & 1; - pr->not_first_frag = (r[6] >> 13) & 1; - pr->frame_type_l4 = (r[6] >> 10) & 7; - pr->frame_type = (r[6] >> 8) & 3; - pr->otag_fmt = (r[6] >> 7) & 1; - pr->itag_fmt = (r[6] >> 6) & 1; - pr->otag_exist = (r[6] >> 5) & 1; - pr->itag_exist = (r[6] >> 4) & 1; - pr->frame_type_l2 = (r[6] >> 2) & 3; - pr->tid = r[6] & 3; - - pr->spmmask_fix_m = (r[13] >> 22) & 0x3; - pr->spn_m = (r[13] >> 16) & 0x3f; - pr->mgnt_vlan_m = (r[13] >> 15) & 1; - pr->dmac_hit_sw_m = (r[13] >> 14) & 1; - pr->not_first_frag_m = (r[13] >> 13) & 1; - pr->frame_type_l4_m = (r[13] >> 10) & 7; - pr->frame_type_m = (r[13] >> 8) & 3; - pr->otag_fmt_m = (r[13] >> 7) & 1; - pr->itag_fmt_m = (r[13] >> 6) & 1; - pr->otag_exist_m = (r[13] >> 5) & 1; - pr->itag_exist_m = (r[13] >> 4) & 1; - pr->frame_type_l2_m = (r[13] >> 2) & 3; - pr->tid_m = r[13] & 3; - - pr->valid = r[14] & BIT(31); - pr->cond_not = r[14] & BIT(30); - pr->cond_and1 = r[14] & BIT(29); - pr->cond_and2 = r[14] & BIT(28); - pr->ivalid = r[14] & BIT(27); - - pr->drop = (r[17] >> 14) & 3; - pr->fwd_sel = r[17] & BIT(13); - pr->ovid_sel = r[17] & BIT(12); - pr->ivid_sel = r[17] & BIT(11); - pr->flt_sel = r[17] & BIT(10); - pr->log_sel = r[17] & BIT(9); - pr->rmk_sel = r[17] & BIT(8); - pr->meter_sel = r[17] & BIT(7); - pr->tagst_sel = r[17] & BIT(6); - pr->mir_sel = r[17] & BIT(5); - pr->nopri_sel = r[17] & BIT(4); - pr->cpupri_sel = r[17] & BIT(3); - pr->otpid_sel = r[17] & BIT(2); - pr->itpid_sel = r[17] & BIT(1); - pr->shaper_sel = r[17] & BIT(0); -} - -static void rtl838x_write_pie_fixed_fields(u32 r[], struct pie_rule *pr) -{ - r[6] = ((u32) (pr->spmmask_fix & 0x3)) << 22; - r[6] |= ((u32) (pr->spn & 0x3f)) << 16; - r[6] |= pr->mgnt_vlan ? BIT(15) : 0; - r[6] |= pr->dmac_hit_sw ? BIT(14) : 0; - r[6] |= pr->not_first_frag ? BIT(13) : 0; - r[6] |= ((u32) (pr->frame_type_l4 & 0x7)) << 10; - r[6] |= ((u32) (pr->frame_type & 0x3)) << 8; - r[6] |= pr->otag_fmt ? BIT(7) : 0; - r[6] |= pr->itag_fmt ? BIT(6) : 0; - r[6] |= pr->otag_exist ? BIT(5) : 0; - r[6] |= pr->itag_exist ? BIT(4) : 0; - r[6] |= ((u32) (pr->frame_type_l2 & 0x3)) << 2; - r[6] |= ((u32) (pr->tid & 0x3)); - - r[13] = ((u32) (pr->spmmask_fix_m & 0x3)) << 22; - r[13] |= ((u32) (pr->spn_m & 0x3f)) << 16; - r[13] |= pr->mgnt_vlan_m ? BIT(15) : 0; - r[13] |= pr->dmac_hit_sw_m ? BIT(14) : 0; - r[13] |= pr->not_first_frag_m ? BIT(13) : 0; - r[13] |= ((u32) (pr->frame_type_l4_m & 0x7)) << 10; - r[13] |= ((u32) (pr->frame_type_m & 0x3)) << 8; - r[13] |= pr->otag_fmt_m ? BIT(7) : 0; - r[13] |= pr->itag_fmt_m ? BIT(6) : 0; - r[13] |= pr->otag_exist_m ? BIT(5) : 0; - r[13] |= pr->itag_exist_m ? BIT(4) : 0; - r[13] |= ((u32) (pr->frame_type_l2_m & 0x3)) << 2; - r[13] |= ((u32) (pr->tid_m & 0x3)); - - r[14] = pr->valid ? BIT(31) : 0; - r[14] |= pr->cond_not ? BIT(30) : 0; - r[14] |= pr->cond_and1 ? BIT(29) : 0; - r[14] |= pr->cond_and2 ? BIT(28) : 0; - r[14] |= pr->ivalid ? BIT(27) : 0; - - if (pr->drop) - r[17] = 0x1 << 14; /* Standard drop action */ - else - r[17] = 0; - r[17] |= pr->fwd_sel ? BIT(13) : 0; - r[17] |= pr->ovid_sel ? BIT(12) : 0; - r[17] |= pr->ivid_sel ? BIT(11) : 0; - r[17] |= pr->flt_sel ? BIT(10) : 0; - r[17] |= pr->log_sel ? BIT(9) : 0; - r[17] |= pr->rmk_sel ? BIT(8) : 0; - r[17] |= pr->meter_sel ? BIT(7) : 0; - r[17] |= pr->tagst_sel ? BIT(6) : 0; - r[17] |= pr->mir_sel ? BIT(5) : 0; - r[17] |= pr->nopri_sel ? BIT(4) : 0; - r[17] |= pr->cpupri_sel ? BIT(3) : 0; - r[17] |= pr->otpid_sel ? BIT(2) : 0; - r[17] |= pr->itpid_sel ? BIT(1) : 0; - r[17] |= pr->shaper_sel ? BIT(0) : 0; -} - -static int rtl838x_write_pie_action(u32 r[], struct pie_rule *pr) -{ - u16 *aif = (u16 *)&r[17]; - u16 data; - int fields_used = 0; - - aif--; - - pr_debug("%s, at %08x\n", __func__, (u32)aif); - /* Multiple actions can be linked to a match of a PIE rule, - * they have different precedence depending on their type and this precedence - * defines which Action Information Field (0-4) in the IACL table stores - * the additional data of the action (like e.g. the port number a packet is - * forwarded to) */ - /* TODO: count bits in selectors to limit to a maximum number of actions */ - if (pr->fwd_sel) { /* Forwarding action */ - data = pr->fwd_act << 13; - data |= pr->fwd_data; - data |= pr->bypass_all ? BIT(12) : 0; - data |= pr->bypass_ibc_sc ? BIT(11) : 0; - data |= pr->bypass_igr_stp ? BIT(10) : 0; - *aif-- = data; - fields_used++; - } - - if (pr->ovid_sel) { /* Outer VID action */ - data = (pr->ovid_act & 0x3) << 12; - data |= pr->ovid_data; - *aif-- = data; - fields_used++; - } - - if (pr->ivid_sel) { /* Inner VID action */ - data = (pr->ivid_act & 0x3) << 12; - data |= pr->ivid_data; - *aif-- = data; - fields_used++; - } - - if (pr->flt_sel) { /* Filter action */ - *aif-- = pr->flt_data; - fields_used++; - } - - if (pr->log_sel) { /* Log action */ - if (fields_used >= 4) - return -1; - *aif-- = pr->log_data; - fields_used++; - } - - if (pr->rmk_sel) { /* Remark action */ - if (fields_used >= 4) - return -1; - *aif-- = pr->rmk_data; - fields_used++; - } - - if (pr->meter_sel) { /* Meter action */ - if (fields_used >= 4) - return -1; - *aif-- = pr->meter_data; - fields_used++; - } - - if (pr->tagst_sel) { /* Egress Tag Status action */ - if (fields_used >= 4) - return -1; - *aif-- = pr->tagst_data; - fields_used++; - } - - if (pr->mir_sel) { /* Mirror action */ - if (fields_used >= 4) - return -1; - *aif-- = pr->mir_data; - fields_used++; - } - - if (pr->nopri_sel) { /* Normal Priority action */ - if (fields_used >= 4) - return -1; - *aif-- = pr->nopri_data; - fields_used++; - } - - if (pr->cpupri_sel) { /* CPU Priority action */ - if (fields_used >= 4) - return -1; - *aif-- = pr->nopri_data; - fields_used++; - } - - if (pr->otpid_sel) { /* OTPID action */ - if (fields_used >= 4) - return -1; - *aif-- = pr->otpid_data; - fields_used++; - } - - if (pr->itpid_sel) { /* ITPID action */ - if (fields_used >= 4) - return -1; - *aif-- = pr->itpid_data; - fields_used++; - } - - if (pr->shaper_sel) { /* Traffic shaper action */ - if (fields_used >= 4) - return -1; - *aif-- = pr->shaper_data; - fields_used++; - } - - return 0; -} - -static void rtl838x_read_pie_action(u32 r[], struct pie_rule *pr) -{ - u16 *aif = (u16 *)&r[17]; - - aif--; - - pr_debug("%s, at %08x\n", __func__, (u32)aif); - if (pr->drop) - pr_debug("%s: Action Drop: %d", __func__, pr->drop); - - if (pr->fwd_sel){ /* Forwarding action */ - pr->fwd_act = *aif >> 13; - pr->fwd_data = *aif--; - pr->bypass_all = pr->fwd_data & BIT(12); - pr->bypass_ibc_sc = pr->fwd_data & BIT(11); - pr->bypass_igr_stp = pr->fwd_data & BIT(10); - if (pr->bypass_all || pr->bypass_ibc_sc || pr->bypass_igr_stp) - pr->bypass_sel = true; - } - if (pr->ovid_sel) /* Outer VID action */ - pr->ovid_data = *aif--; - if (pr->ivid_sel) /* Inner VID action */ - pr->ivid_data = *aif--; - if (pr->flt_sel) /* Filter action */ - pr->flt_data = *aif--; - if (pr->log_sel) /* Log action */ - pr->log_data = *aif--; - if (pr->rmk_sel) /* Remark action */ - pr->rmk_data = *aif--; - if (pr->meter_sel) /* Meter action */ - pr->meter_data = *aif--; - if (pr->tagst_sel) /* Egress Tag Status action */ - pr->tagst_data = *aif--; - if (pr->mir_sel) /* Mirror action */ - pr->mir_data = *aif--; - if (pr->nopri_sel) /* Normal Priority action */ - pr->nopri_data = *aif--; - if (pr->cpupri_sel) /* CPU Priority action */ - pr->nopri_data = *aif--; - if (pr->otpid_sel) /* OTPID action */ - pr->otpid_data = *aif--; - if (pr->itpid_sel) /* ITPID action */ - pr->itpid_data = *aif--; - if (pr->shaper_sel) /* Traffic shaper action */ - pr->shaper_data = *aif--; -} - -static void rtl838x_pie_rule_dump_raw(u32 r[]) -{ - pr_info("Raw IACL table entry:\n"); - pr_info("Match : %08x %08x %08x %08x %08x %08x\n", r[0], r[1], r[2], r[3], r[4], r[5]); - pr_info("Fixed : %08x\n", r[6]); - pr_info("Match M: %08x %08x %08x %08x %08x %08x\n", r[7], r[8], r[9], r[10], r[11], r[12]); - pr_info("Fixed M: %08x\n", r[13]); - pr_info("AIF : %08x %08x %08x\n", r[14], r[15], r[16]); - pr_info("Sel : %08x\n", r[17]); -} - -// Currently not used -// static void rtl838x_pie_rule_dump(struct pie_rule *pr) -// { -// pr_info("Drop: %d, fwd: %d, ovid: %d, ivid: %d, flt: %d, log: %d, rmk: %d, meter: %d tagst: %d, mir: %d, nopri: %d, cpupri: %d, otpid: %d, itpid: %d, shape: %d\n", -// pr->drop, pr->fwd_sel, pr->ovid_sel, pr->ivid_sel, pr->flt_sel, pr->log_sel, pr->rmk_sel, pr->log_sel, pr->tagst_sel, pr->mir_sel, pr->nopri_sel, -// pr->cpupri_sel, pr->otpid_sel, pr->itpid_sel, pr->shaper_sel); -// if (pr->fwd_sel) -// pr_info("FWD: %08x\n", pr->fwd_data); -// pr_info("TID: %x, %x\n", pr->tid, pr->tid_m); -// } - -static int rtl838x_pie_rule_read(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr) -{ - /* Read IACL table (1) via register 0 */ - struct table_reg *q = rtl_table_get(RTL8380_TBL_0, 1); - u32 r[18]; - int block = idx / PIE_BLOCK_SIZE; - u32 t_select = sw_r32(RTL838X_ACL_BLK_TMPLTE_CTRL(block)); - - memset(pr, 0, sizeof(*pr)); - rtl_table_read(q, idx); - for (int i = 0; i < 18; i++) - r[i] = sw_r32(rtl_table_data(q, i)); - - rtl_table_release(q); - - rtl838x_read_pie_fixed_fields(r, pr); - if (!pr->valid) - return 0; - - pr_info("%s: template_selectors %08x, tid: %d\n", __func__, t_select, pr->tid); - rtl838x_pie_rule_dump_raw(r); - - rtl838x_read_pie_templated(r, pr, fixed_templates[(t_select >> (pr->tid * 3)) & 0x7]); - - rtl838x_read_pie_action(r, pr); - - return 0; -} - -static int rtl838x_pie_rule_write(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr) -{ - /* Access IACL table (1) via register 0 */ - struct table_reg *q = rtl_table_get(RTL8380_TBL_0, 1); - u32 r[18]; - int err; - int block = idx / PIE_BLOCK_SIZE; - u32 t_select = sw_r32(RTL838X_ACL_BLK_TMPLTE_CTRL(block)); - - pr_debug("%s: %d, t_select: %08x\n", __func__, idx, t_select); - - for (int i = 0; i < 18; i++) - r[i] = 0; - - if (!pr->valid) { - err = -EINVAL; - pr_err("Rule invalid\n"); - goto errout; - } - - rtl838x_write_pie_fixed_fields(r, pr); - - pr_debug("%s: template %d\n", __func__, (t_select >> (pr->tid * 3)) & 0x7); - rtl838x_write_pie_templated(r, pr, fixed_templates[(t_select >> (pr->tid * 3)) & 0x7]); - - err = rtl838x_write_pie_action(r, pr); - if (err) { - pr_err("Rule actions too complex\n"); - goto errout; - } - -/* rtl838x_pie_rule_dump_raw(r); */ - - for (int i = 0; i < 18; i++) - sw_w32(r[i], rtl_table_data(q, i)); - -errout: - rtl_table_write(q, idx); - rtl_table_release(q); - - return err; -} - -static bool rtl838x_pie_templ_has(int t, enum template_field_id field_type) -{ - enum template_field_id ft; - - for (int i = 0; i < N_FIXED_FIELDS; i++) { - ft = fixed_templates[t][i]; - if (field_type == ft) - return true; - } - - return false; -} - -static int rtl838x_pie_verify_template(struct rtl838x_switch_priv *priv, - struct pie_rule *pr, int t, int block) -{ - int i; - - if (!pr->is_ipv6 && pr->sip_m && !rtl838x_pie_templ_has(t, TEMPLATE_FIELD_SIP0)) - return -1; - - if (!pr->is_ipv6 && pr->dip_m && !rtl838x_pie_templ_has(t, TEMPLATE_FIELD_DIP0)) - return -1; - - if (pr->is_ipv6) { - if ((pr->sip6_m.s6_addr32[0] || - pr->sip6_m.s6_addr32[1] || - pr->sip6_m.s6_addr32[2] || - pr->sip6_m.s6_addr32[3]) && - !rtl838x_pie_templ_has(t, TEMPLATE_FIELD_SIP2)) - return -1; - if ((pr->dip6_m.s6_addr32[0] || - pr->dip6_m.s6_addr32[1] || - pr->dip6_m.s6_addr32[2] || - pr->dip6_m.s6_addr32[3]) && - !rtl838x_pie_templ_has(t, TEMPLATE_FIELD_DIP2)) - return -1; - } - - if (ether_addr_to_u64(pr->smac) && !rtl838x_pie_templ_has(t, TEMPLATE_FIELD_SMAC0)) - return -1; - - if (ether_addr_to_u64(pr->dmac) && !rtl838x_pie_templ_has(t, TEMPLATE_FIELD_DMAC0)) - return -1; - - /* TODO: Check more */ - - i = find_first_zero_bit(&priv->pie_use_bm[block * 4], PIE_BLOCK_SIZE); - - if (i >= PIE_BLOCK_SIZE) - return -1; - - return i + PIE_BLOCK_SIZE * block; -} - -static int rtl838x_pie_rule_add(struct rtl838x_switch_priv *priv, struct pie_rule *pr) -{ - int idx, block, j; - - pr_debug("In %s\n", __func__); - - mutex_lock(&priv->pie_mutex); - - for (block = 0; block < priv->n_pie_blocks; block++) { - for (j = 0; j < 3; j++) { - int t = (sw_r32(RTL838X_ACL_BLK_TMPLTE_CTRL(block)) >> (j * 3)) & 0x7; - pr_debug("Testing block %d, template %d, template id %d\n", block, j, t); - idx = rtl838x_pie_verify_template(priv, pr, t, block); - if (idx >= 0) - break; - } - if (j < 3) - break; - } - - if (block >= priv->n_pie_blocks) { - mutex_unlock(&priv->pie_mutex); - return -EOPNOTSUPP; - } - - pr_debug("Using block: %d, index %d, template-id %d\n", block, idx, j); - set_bit(idx, priv->pie_use_bm); - - pr->valid = true; - pr->tid = j; /* Mapped to template number */ - pr->tid_m = 0x3; - pr->id = idx; - - rtl838x_pie_lookup_enable(priv, idx); - rtl838x_pie_rule_write(priv, idx, pr); - - mutex_unlock(&priv->pie_mutex); - - return 0; -} - -static void rtl838x_pie_rule_rm(struct rtl838x_switch_priv *priv, struct pie_rule *pr) -{ - int idx = pr->id; - - rtl838x_pie_rule_del(priv, idx, idx); - clear_bit(idx, priv->pie_use_bm); -} - -/* Initializes the Packet Inspection Engine: - * powers it up, enables default matching templates for all blocks - * and clears all rules possibly installed by u-boot - */ -static void rtl838x_pie_init(struct rtl838x_switch_priv *priv) -{ - u32 template_selectors; - - mutex_init(&priv->pie_mutex); - - /* Enable ACL lookup on all ports, including CPU_PORT */ - for (int i = 0; i <= priv->cpu_port; i++) - sw_w32(1, RTL838X_ACL_PORT_LOOKUP_CTRL(i)); - - /* Power on all PIE blocks */ - for (int i = 0; i < priv->n_pie_blocks; i++) - sw_w32_mask(0, BIT(i), RTL838X_ACL_BLK_PWR_CTRL); - - /* Include IPG in metering */ - sw_w32(1, RTL838X_METER_GLB_CTRL); - - /* Delete all present rules */ - rtl838x_pie_rule_del(priv, 0, priv->n_pie_blocks * PIE_BLOCK_SIZE - 1); - - /* Routing bypasses source port filter: disable write-protection, first */ - sw_w32_mask(0, 3, RTL838X_INT_RW_CTRL); - sw_w32_mask(0, 1, RTL838X_DMY_REG27); - sw_w32_mask(3, 0, RTL838X_INT_RW_CTRL); - - /* Enable predefined templates 0, 1 and 2 for even blocks */ - template_selectors = 0 | (1 << 3) | (2 << 6); - for (int i = 0; i < 6; i += 2) - sw_w32(template_selectors, RTL838X_ACL_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 0, 3 and 4 (IPv6 support) for odd blocks */ - template_selectors = 0 | (3 << 3) | (4 << 6); - for (int i = 1; i < priv->n_pie_blocks; i += 2) - sw_w32(template_selectors, RTL838X_ACL_BLK_TMPLTE_CTRL(i)); - - /* Group each pair of physical blocks together to a logical block */ - sw_w32(0b10101010101, RTL838X_ACL_BLK_GROUP_CTRL); -} - -static u32 rtl838x_packet_cntr_read(int counter) -{ - u32 v; - - /* Read LOG table (3) via register RTL8380_TBL_0 */ - struct table_reg *r = rtl_table_get(RTL8380_TBL_0, 3); - - pr_debug("In %s, id %d\n", __func__, counter); - rtl_table_read(r, counter / 2); - - pr_debug("Registers: %08x %08x\n", - sw_r32(rtl_table_data(r, 0)), sw_r32(rtl_table_data(r, 1))); - /* The table has a size of 2 registers */ - if (counter % 2) - v = sw_r32(rtl_table_data(r, 0)); - else - v = sw_r32(rtl_table_data(r, 1)); - - rtl_table_release(r); - - return v; -} - -static void rtl838x_packet_cntr_clear(int counter) -{ - /* Access LOG table (3) via register RTL8380_TBL_0 */ - struct table_reg *r = rtl_table_get(RTL8380_TBL_0, 3); - - pr_debug("In %s, id %d\n", __func__, counter); - /* The table has a size of 2 registers */ - if (counter % 2) - sw_w32(0, rtl_table_data(r, 0)); - else - sw_w32(0, rtl_table_data(r, 1)); - - rtl_table_write(r, counter / 2); - - rtl_table_release(r); -} - -static void rtl838x_route_read(int idx, struct rtl83xx_route *rt) -{ - /* Read ROUTING table (2) via register RTL8380_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL8380_TBL_1, 2); - - pr_debug("In %s, id %d\n", __func__, idx); - rtl_table_read(r, idx); - - /* The table has a size of 2 registers */ - rt->nh.gw = sw_r32(rtl_table_data(r, 0)); - rt->nh.gw <<= 32; - rt->nh.gw |= sw_r32(rtl_table_data(r, 1)); - - rtl_table_release(r); -} - -static void rtl838x_route_write(int idx, struct rtl83xx_route *rt) -{ - /* Access ROUTING table (2) via register RTL8380_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL8380_TBL_1, 2); - - pr_debug("In %s, id %d, gw: %016llx\n", __func__, idx, rt->nh.gw); - sw_w32(rt->nh.gw >> 32, rtl_table_data(r, 0)); - sw_w32(rt->nh.gw, rtl_table_data(r, 1)); - rtl_table_write(r, idx); - - rtl_table_release(r); -} - -static int rtl838x_l3_setup(struct rtl838x_switch_priv *priv) -{ - /* Nothing to be done */ - return 0; -} - -void rtl838x_vlan_port_keep_tag_set(int port, bool keep_outer, bool keep_inner) -{ - sw_w32(FIELD_PREP(RTL838X_VLAN_PORT_TAG_STS_CTRL_OTAG_STS_MASK, - keep_outer ? RTL838X_VLAN_PORT_TAG_STS_TAGGED : RTL838X_VLAN_PORT_TAG_STS_UNTAG) | - FIELD_PREP(RTL838X_VLAN_PORT_TAG_STS_CTRL_ITAG_STS_MASK, - keep_inner ? RTL838X_VLAN_PORT_TAG_STS_TAGGED : RTL838X_VLAN_PORT_TAG_STS_UNTAG), - RTL838X_VLAN_PORT_TAG_STS_CTRL(port)); -} - -void rtl838x_vlan_port_pvidmode_set(int port, enum pbvlan_type type, enum pbvlan_mode mode) -{ - if (type == PBVLAN_TYPE_INNER) - sw_w32_mask(0x3, mode, RTL838X_VLAN_PORT_PB_VLAN + (port << 2)); - else - sw_w32_mask(0x3 << 14, mode << 14, RTL838X_VLAN_PORT_PB_VLAN + (port << 2)); -} - -void rtl838x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid) -{ - if (type == PBVLAN_TYPE_INNER) - sw_w32_mask(0xfff << 2, pvid << 2, RTL838X_VLAN_PORT_PB_VLAN + (port << 2)); - else - sw_w32_mask(0xfff << 16, pvid << 16, RTL838X_VLAN_PORT_PB_VLAN + (port << 2)); -} - -static int rtl838x_set_ageing_time(unsigned long msec) -{ - int t = sw_r32(RTL838X_L2_CTRL_1); - - t &= 0x7FFFFF; - t = t * 128 / 625; /* Aging time in seconds. 0: L2 aging disabled */ - pr_debug("L2 AGING time: %d sec\n", t); - - t = (msec * 625 + 127000) / 128000; - t = t > 0x7FFFFF ? 0x7FFFFF : t; - sw_w32_mask(0x7FFFFF, t, RTL838X_L2_CTRL_1); - pr_debug("Dynamic aging for ports: %x\n", sw_r32(RTL838X_L2_PORT_AGING_OUT)); - - return 0; -} - -static void rtl838x_set_igr_filter(int port, enum igr_filter state) -{ - sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1), - RTL838X_VLAN_PORT_IGR_FLTR + (((port >> 4) << 2))); -} - -static void rtl838x_set_egr_filter(int port, enum egr_filter state) -{ - sw_w32_mask(0x1 << (port % 0x1d), state << (port % 0x1d), - RTL838X_VLAN_PORT_EGR_FLTR + (((port / 29) << 2))); -} - -void rtl838x_set_distribution_algorithm(int group, int algoidx, u32 algomsk) -{ - algoidx &= 1; /* RTL838X only supports 2 concurrent algorithms */ - sw_w32_mask(1 << (group % 8), algoidx << (group % 8), - RTL838X_TRK_HASH_IDX_CTRL + ((group >> 3) << 2)); - sw_w32(algomsk, RTL838X_TRK_HASH_CTRL + (algoidx << 2)); -} - -void rtl838x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action) -{ - switch(type) { - case BPDU: - sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1), - RTL838X_RMA_BPDU_CTRL + ((port >> 4) << 2)); - break; - case PTP: - sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1), - RTL838X_RMA_PTP_CTRL + ((port >> 4) << 2)); - break; - case LLDP: - sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1), - RTL838X_RMA_LLDP_CTRL + ((port >> 4) << 2)); - break; - default: - break; - } -} - -const struct rtl838x_reg rtl838x_reg = { - .mask_port_reg_be = rtl838x_mask_port_reg, - .set_port_reg_be = rtl838x_set_port_reg, - .get_port_reg_be = rtl838x_get_port_reg, - .mask_port_reg_le = rtl838x_mask_port_reg, - .set_port_reg_le = rtl838x_set_port_reg, - .get_port_reg_le = rtl838x_get_port_reg, - .stat_port_rst = RTL838X_STAT_PORT_RST, - .stat_rst = RTL838X_STAT_RST, - .stat_port_std_mib = RTL838X_STAT_PORT_STD_MIB, - .port_iso_ctrl = rtl838x_port_iso_ctrl, - .traffic_enable = rtl838x_traffic_enable, - .traffic_disable = rtl838x_traffic_disable, - .traffic_get = rtl838x_traffic_get, - .traffic_set = rtl838x_traffic_set, - .l2_ctrl_0 = RTL838X_L2_CTRL_0, - .l2_ctrl_1 = RTL838X_L2_CTRL_1, - .l2_port_aging_out = RTL838X_L2_PORT_AGING_OUT, - .set_ageing_time = rtl838x_set_ageing_time, - .smi_poll_ctrl = RTL838X_SMI_POLL_CTRL, - .l2_tbl_flush_ctrl = RTL838X_L2_TBL_FLUSH_CTRL, - .exec_tbl0_cmd = rtl838x_exec_tbl0_cmd, - .exec_tbl1_cmd = rtl838x_exec_tbl1_cmd, - .tbl_access_data_0 = rtl838x_tbl_access_data_0, - .isr_glb_src = RTL838X_ISR_GLB_SRC, - .isr_port_link_sts_chg = RTL838X_ISR_PORT_LINK_STS_CHG, - .imr_port_link_sts_chg = RTL838X_IMR_PORT_LINK_STS_CHG, - .imr_glb = RTL838X_IMR_GLB, - .vlan_tables_read = rtl838x_vlan_tables_read, - .vlan_set_tagged = rtl838x_vlan_set_tagged, - .vlan_set_untagged = rtl838x_vlan_set_untagged, - .mac_force_mode_ctrl = rtl838x_mac_force_mode_ctrl, - .vlan_profile_dump = rtl838x_vlan_profile_dump, - .vlan_profile_setup = rtl838x_vlan_profile_setup, - .vlan_fwd_on_inner = rtl838x_vlan_fwd_on_inner, - .set_vlan_igr_filter = rtl838x_set_igr_filter, - .set_vlan_egr_filter = rtl838x_set_egr_filter, - .enable_learning = rtl838x_enable_learning, - .enable_flood = rtl838x_enable_flood, - .enable_mcast_flood = rtl838x_enable_mcast_flood, - .enable_bcast_flood = rtl838x_enable_bcast_flood, - .set_static_move_action = rtl838x_set_static_move_action, - .stp_get = rtl838x_stp_get, - .stp_set = rtl838x_stp_set, - .mac_port_ctrl = rtl838x_mac_port_ctrl, - .l2_port_new_salrn = rtl838x_l2_port_new_salrn, - .l2_port_new_sa_fwd = rtl838x_l2_port_new_sa_fwd, - .mir_ctrl = RTL838X_MIR_CTRL, - .mir_dpm = RTL838X_MIR_DPM_CTRL, - .mir_spm = RTL838X_MIR_SPM_CTRL, - .mac_link_sts = RTL838X_MAC_LINK_STS, - .mac_link_dup_sts = RTL838X_MAC_LINK_DUP_STS, - .mac_link_spd_sts = rtl838x_mac_link_spd_sts, - .mac_rx_pause_sts = RTL838X_MAC_RX_PAUSE_STS, - .mac_tx_pause_sts = RTL838X_MAC_TX_PAUSE_STS, - .read_l2_entry_using_hash = rtl838x_read_l2_entry_using_hash, - .write_l2_entry_using_hash = rtl838x_write_l2_entry_using_hash, - .read_cam = rtl838x_read_cam, - .write_cam = rtl838x_write_cam, - .vlan_port_keep_tag_set = rtl838x_vlan_port_keep_tag_set, - .vlan_port_pvidmode_set = rtl838x_vlan_port_pvidmode_set, - .vlan_port_pvid_set = rtl838x_vlan_port_pvid_set, - .trk_mbr_ctr = rtl838x_trk_mbr_ctr, - .rma_bpdu_fld_pmask = RTL838X_RMA_BPDU_FLD_PMSK, - .spcl_trap_eapol_ctrl = RTL838X_SPCL_TRAP_EAPOL_CTRL, - .init_eee = rtl838x_init_eee, - .port_eee_set = rtl838x_port_eee_set, - .eee_port_ability = rtl838x_eee_port_ability, - .l2_hash_seed = rtl838x_l2_hash_seed, - .l2_hash_key = rtl838x_l2_hash_key, - .read_mcast_pmask = rtl838x_read_mcast_pmask, - .write_mcast_pmask = rtl838x_write_mcast_pmask, - .pie_init = rtl838x_pie_init, - .pie_rule_read = rtl838x_pie_rule_read, - .pie_rule_write = rtl838x_pie_rule_write, - .pie_rule_add = rtl838x_pie_rule_add, - .pie_rule_rm = rtl838x_pie_rule_rm, - .l2_learning_setup = rtl838x_l2_learning_setup, - .packet_cntr_read = rtl838x_packet_cntr_read, - .packet_cntr_clear = rtl838x_packet_cntr_clear, - .route_read = rtl838x_route_read, - .route_write = rtl838x_route_write, - .l3_setup = rtl838x_l3_setup, - .set_distribution_algorithm = rtl838x_set_distribution_algorithm, - .set_receive_management_action = rtl838x_set_receive_management_action, -}; - -irqreturn_t rtl838x_switch_irq(int irq, void *dev_id) -{ - struct dsa_switch *ds = dev_id; - u32 status = sw_r32(RTL838X_ISR_GLB_SRC); - u32 ports = sw_r32(RTL838X_ISR_PORT_LINK_STS_CHG); - u32 link; - - /* Clear status */ - sw_w32(ports, RTL838X_ISR_PORT_LINK_STS_CHG); - pr_info("RTL8380 Link change: status: %x, ports %x\n", status, ports); - - for (int i = 0; i < 28; i++) { - if (ports & BIT(i)) { - link = sw_r32(RTL838X_MAC_LINK_STS); - if (link & BIT(i)) - dsa_port_phylink_mac_change(ds, i, true); - else - dsa_port_phylink_mac_change(ds, i, false); - } - } - - return IRQ_HANDLED; -} - -int rtl838x_smi_wait_op(int timeout) -{ - int ret = 0; - u32 val; - - ret = readx_poll_timeout(sw_r32, RTL838X_SMI_ACCESS_PHY_CTRL_1, - val, !(val & 0x1), 20, timeout); - if (ret) - pr_err("%s: timeout\n", __func__); - - return ret; -} - -/* Reads a register in a page from the PHY */ -int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val) -{ - int err; - u32 v; - u32 park_page; - - if (port > 31) { - *val = 0xffff; - return 0; - } - - if (page > 4095 || reg > 31) - return -ENOTSUPP; - - mutex_lock(&smi_lock); - - err = rtl838x_smi_wait_op(100000); - if (err) - goto errout; - - sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2); - - park_page = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1) & ((0x1f << 15) | 0x2); - v = reg << 20 | page << 3; - sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1); - sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1); - - err = rtl838x_smi_wait_op(100000); - if (err) - goto errout; - - *val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff; - - err = 0; - -errout: - mutex_unlock(&smi_lock); - - return err; -} - -/* Write to a register in a page of the PHY */ -int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val) -{ - int err; - u32 v; - u32 park_page; - - val &= 0xffff; - if (port > 31 || page > 4095 || reg > 31) - return -ENOTSUPP; - - mutex_lock(&smi_lock); - err = rtl838x_smi_wait_op(100000); - if (err) - goto errout; - - sw_w32(BIT(port), RTL838X_SMI_ACCESS_PHY_CTRL_0); - mdelay(10); - - sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2); - - park_page = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_1) & ((0x1f << 15) | 0x2); - v = reg << 20 | page << 3 | 0x4; - sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1); - sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1); - - err = rtl838x_smi_wait_op(100000); - if (err) - goto errout; - - err = 0; - -errout: - mutex_unlock(&smi_lock); - - return err; -} - -/* Read an mmd register of a PHY */ -int rtl838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val) -{ - int err; - u32 v; - - mutex_lock(&smi_lock); - - err = rtl838x_smi_wait_op(100000); - if (err) - goto errout; - - sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0); - mdelay(10); - - sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2); - - v = addr << 16 | reg; - sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_3); - - /* mmd-access | read | cmd-start */ - v = 1 << 1 | 0 << 2 | 1; - sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1); - - err = rtl838x_smi_wait_op(100000); - if (err) - goto errout; - - *val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff; - - err = 0; - -errout: - mutex_unlock(&smi_lock); - - return err; -} - -/* Write to an mmd register of a PHY */ -int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val) -{ - int err; - u32 v; - - pr_debug("MMD write: port %d, dev %d, reg %d, val %x\n", port, addr, reg, val); - val &= 0xffff; - mutex_lock(&smi_lock); - - err = rtl838x_smi_wait_op(100000); - if (err) - goto errout; - - sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0); - mdelay(10); - - sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2); - - sw_w32_mask(0x1f << 16, addr << 16, RTL838X_SMI_ACCESS_PHY_CTRL_3); - sw_w32_mask(0xffff, reg, RTL838X_SMI_ACCESS_PHY_CTRL_3); - /* mmd-access | write | cmd-start */ - v = 1 << 1 | 1 << 2 | 1; - sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1); - - err = rtl838x_smi_wait_op(100000); - if (err) - goto errout; - - err = 0; - -errout: - mutex_unlock(&smi_lock); - return err; -} - -void rtl8380_get_version(struct rtl838x_switch_priv *priv) -{ - u32 rw_save, info_save; - u32 info; - - rw_save = sw_r32(RTL838X_INT_RW_CTRL); - sw_w32(rw_save | 0x3, RTL838X_INT_RW_CTRL); - - info_save = sw_r32(RTL838X_CHIP_INFO); - sw_w32(info_save | 0xA0000000, RTL838X_CHIP_INFO); - - info = sw_r32(RTL838X_CHIP_INFO); - sw_w32(info_save, RTL838X_CHIP_INFO); - sw_w32(rw_save, RTL838X_INT_RW_CTRL); - - if ((info & 0xFFFF) == 0x6275) { - if (((info >> 16) & 0x1F) == 0x1) - priv->version = RTL8380_VERSION_A; - else if (((info >> 16) & 0x1F) == 0x2) - priv->version = RTL8380_VERSION_B; - else - priv->version = RTL8380_VERSION_B; - } else { - priv->version = '-'; - } -} - -void rtl838x_vlan_profile_dump(int profile) -{ - u32 p; - - if (profile < 0 || profile > 7) - return; - - p = sw_r32(RTL838X_VLAN_PROFILE(profile)); - - pr_info("VLAN profile %d: L2 learning: %d, UNKN L2MC FLD PMSK %d, \ - UNKN IPMC FLD PMSK %d, UNKN IPv6MC FLD PMSK: %d", - profile, p & 1, (p >> 1) & 0x1ff, (p >> 10) & 0x1ff, (p >> 19) & 0x1ff); -} - -void rtl8380_sds_rst(int mac) -{ - u32 offset = (mac == 24) ? 0 : 0x100; - - sw_w32_mask(1 << 11, 0, RTL838X_SDS4_FIB_REG0 + offset); - sw_w32_mask(0x3, 0, RTL838X_SDS4_REG28 + offset); - sw_w32_mask(0x3, 0x3, RTL838X_SDS4_REG28 + offset); - sw_w32_mask(0, 0x1 << 6, RTL838X_SDS4_DUMMY0 + offset); - sw_w32_mask(0x1 << 6, 0, RTL838X_SDS4_DUMMY0 + offset); - pr_debug("SERDES reset: %d\n", mac); -} - -int rtl8380_sds_power(int mac, int val) -{ - u32 mode = (val == 1) ? 0x4 : 0x9; - u32 offset = (mac == 24) ? 5 : 0; - - if ((mac != 24) && (mac != 26)) { - pr_err("%s: not a fibre port: %d\n", __func__, mac); - return -1; - } - - sw_w32_mask(0x1f << offset, mode << offset, RTL838X_SDS_MODE_SEL); - - rtl8380_sds_rst(mac); - - return 0; -} diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.h b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.h deleted file mode 100644 index 261af32bb46ee7..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl838x.h +++ /dev/null @@ -1,1103 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _RTL838X_H -#define _RTL838X_H - -#include - -/* Register definition */ -#define RTL838X_MAC_PORT_CTRL(port) (0xd560 + (((port) << 7))) -#define RTL839X_MAC_PORT_CTRL(port) (0x8004 + (((port) << 7))) -#define RTL930X_MAC_PORT_CTRL(port) (0x3260 + (((port) << 6))) -#define RTL931X_MAC_PORT_CTRL (0x6004) - -#define RTL930X_MAC_L2_PORT_CTRL(port) (0x3268 + (((port) << 6))) -#define RTL931X_MAC_L2_PORT_CTRL (0x6000) - -#define RTL838X_RST_GLB_CTRL_0 (0x003c) - -#define RTL838X_MAC_FORCE_MODE_CTRL (0xa104) -#define RTL839X_MAC_FORCE_MODE_CTRL (0x02bc) -#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C) -#define RTL931X_MAC_FORCE_MODE_CTRL (0x0DCC) - -#define RTL838X_DMY_REG31 (0x3b28) -#define RTL838X_SDS_MODE_SEL (0x0028) -#define RTL838X_SDS_CFG_REG (0x0034) -#define RTL838X_INT_MODE_CTRL (0x005c) -#define RTL838X_CHIP_INFO (0x00d8) -#define RTL839X_CHIP_INFO (0x0ff4) -#define RTL838X_PORT_ISO_CTRL(port) (0x4100 + ((port) << 2)) -#define RTL839X_PORT_ISO_CTRL(port) (0x1400 + ((port) << 3)) - -/* Packet statistics */ -#define RTL838X_STAT_PORT_STD_MIB (0x1200) -#define RTL839X_STAT_PORT_STD_MIB (0xC000) -#define RTL930X_STAT_PORT_MIB_CNTR (0x0664) -#define RTL838X_STAT_RST (0x3100) -#define RTL839X_STAT_RST (0xF504) -#define RTL930X_STAT_RST (0x3240) -#define RTL931X_STAT_RST (0x7ef4) -#define RTL838X_STAT_PORT_RST (0x3104) -#define RTL839X_STAT_PORT_RST (0xF508) -#define RTL930X_STAT_PORT_RST (0x3244) -#define RTL931X_STAT_PORT_RST (0x7ef8) -#define RTL838X_STAT_CTRL (0x3108) -#define RTL839X_STAT_CTRL (0x04cc) -#define RTL930X_STAT_CTRL (0x3248) -#define RTL931X_STAT_CTRL (0x5720) - -/* Registers of the internal Serdes of the 8390 */ -#define RTL8390_SDS0_1_XSG0 (0xA000) -#define RTL8390_SDS0_1_XSG1 (0xA100) -#define RTL839X_SDS12_13_XSG0 (0xB800) -#define RTL839X_SDS12_13_XSG1 (0xB900) -#define RTL839X_SDS12_13_PWR0 (0xb880) -#define RTL839X_SDS12_13_PWR1 (0xb980) - -/* Registers of the internal Serdes of the 8380 */ -#define RTL838X_SDS4_FIB_REG0 (0xF800) -#define RTL838X_SDS4_REG28 (0xef80) -#define RTL838X_SDS4_DUMMY0 (0xef8c) -#define RTL838X_SDS5_EXT_REG6 (0xf18c) - -/* VLAN registers */ -#define RTL838X_VLAN_CTRL (0x3A74) -#define RTL838X_VLAN_PROFILE(idx) (0x3A88 + ((idx) << 2)) -#define RTL838X_VLAN_PORT_EGR_FLTR (0x3A84) -#define RTL838X_VLAN_PORT_PB_VLAN (0x3C00) -#define RTL838X_VLAN_PORT_IGR_FLTR (0x3A7C) - -#define RTL839X_VLAN_PROFILE(idx) (0x25C0 + (((idx) << 3))) -#define RTL839X_VLAN_CTRL (0x26D4) -#define RTL839X_VLAN_PORT_PB_VLAN (0x26D8) -#define RTL839X_VLAN_PORT_IGR_FLTR (0x27B4) -#define RTL839X_VLAN_PORT_EGR_FLTR (0x27C4) - -#define RTL930X_VLAN_PROFILE_SET(idx) (0x9c60 + (((idx) * 20))) -#define RTL930X_VLAN_CTRL (0x82D4) -#define RTL930X_VLAN_PORT_PB_VLAN (0x82D8) -#define RTL930X_VLAN_PORT_IGR_FLTR (0x83C0) -#define RTL930X_VLAN_PORT_EGR_FLTR (0x83C8) - -#define RTL931X_VLAN_PROFILE_SET(idx) (0x9800 + (((idx) * 28))) -#define RTL931X_VLAN_CTRL (0x94E4) -#define RTL931X_VLAN_PORT_IGR_CTRL (0x94E8) -#define RTL931X_VLAN_PORT_IGR_FLTR (0x96B4) -#define RTL931X_VLAN_PORT_EGR_FLTR (0x96C4) - -/* Table access registers */ -#define RTL838X_TBL_ACCESS_CTRL_0 (0x6914) -#define RTL838X_TBL_ACCESS_DATA_0(idx) (0x6918 + ((idx) << 2)) -#define RTL838X_TBL_ACCESS_CTRL_1 (0xA4C8) -#define RTL838X_TBL_ACCESS_DATA_1(idx) (0xA4CC + ((idx) << 2)) - -#define RTL839X_TBL_ACCESS_CTRL_0 (0x1190) -#define RTL839X_TBL_ACCESS_DATA_0(idx) (0x1194 + ((idx) << 2)) -#define RTL839X_TBL_ACCESS_CTRL_1 (0x6b80) -#define RTL839X_TBL_ACCESS_DATA_1(idx) (0x6b84 + ((idx) << 2)) -#define RTL839X_TBL_ACCESS_CTRL_2 (0x611C) -#define RTL839X_TBL_ACCESS_DATA_2(i) (0x6120 + (((i) << 2))) - -#define RTL930X_TBL_ACCESS_CTRL_0 (0xB340) -#define RTL930X_TBL_ACCESS_DATA_0(idx) (0xB344 + ((idx) << 2)) -#define RTL930X_TBL_ACCESS_CTRL_1 (0xB3A0) -#define RTL930X_TBL_ACCESS_DATA_1(idx) (0xB3A4 + ((idx) << 2)) -#define RTL930X_TBL_ACCESS_CTRL_2 (0xCE04) -#define RTL930X_TBL_ACCESS_DATA_2(i) (0xCE08 + (((i) << 2))) - -#define RTL931X_TBL_ACCESS_CTRL_0 (0x8500) -#define RTL931X_TBL_ACCESS_DATA_0(idx) (0x8508 + ((idx) << 2)) -#define RTL931X_TBL_ACCESS_CTRL_1 (0x40C0) -#define RTL931X_TBL_ACCESS_DATA_1(idx) (0x40C4 + ((idx) << 2)) -#define RTL931X_TBL_ACCESS_CTRL_2 (0x8528) -#define RTL931X_TBL_ACCESS_DATA_2(i) (0x852C + (((i) << 2))) -#define RTL931X_TBL_ACCESS_CTRL_3 (0x0200) -#define RTL931X_TBL_ACCESS_DATA_3(i) (0x0204 + (((i) << 2))) -#define RTL931X_TBL_ACCESS_CTRL_4 (0x20DC) -#define RTL931X_TBL_ACCESS_DATA_4(i) (0x20E0 + (((i) << 2))) -#define RTL931X_TBL_ACCESS_CTRL_5 (0x7E1C) -#define RTL931X_TBL_ACCESS_DATA_5(i) (0x7E20 + (((i) << 2))) - -/* MAC handling */ -#define RTL838X_MAC_LINK_STS (0xa188) -#define RTL839X_MAC_LINK_STS (0x0390) -#define RTL930X_MAC_LINK_STS (0xCB10) -#define RTL931X_MAC_LINK_STS (0x0EC0) -#define RTL838X_MAC_LINK_SPD_STS(p) (0xa190 + (((p >> 4) << 2))) -#define RTL839X_MAC_LINK_SPD_STS(p) (0x03a0 + (((p >> 4) << 2))) -#define RTL930X_MAC_LINK_SPD_STS(p) (0xCB18 + (((p >> 3) << 2))) -#define RTL931X_MAC_LINK_SPD_STS (0x0ED0) -#define RTL838X_MAC_LINK_DUP_STS (0xa19c) -#define RTL839X_MAC_LINK_DUP_STS (0x03b0) -#define RTL930X_MAC_LINK_DUP_STS (0xCB28) -#define RTL931X_MAC_LINK_DUP_STS (0x0EF0) -#define RTL838X_MAC_TX_PAUSE_STS (0xa1a0) -#define RTL839X_MAC_TX_PAUSE_STS (0x03b8) -#define RTL930X_MAC_TX_PAUSE_STS (0xCB2C) -#define RTL931X_MAC_TX_PAUSE_STS (0x0EF8) -#define RTL838X_MAC_RX_PAUSE_STS (0xa1a4) -#define RTL839X_MAC_RX_PAUSE_STS (0x03c0) -#define RTL930X_MAC_RX_PAUSE_STS (0xCB30) -#define RTL931X_MAC_RX_PAUSE_STS (0x0F00) -#define RTL930X_MAC_LINK_MEDIA_STS (0xCB14) -#define RTL931X_MAC_LINK_MEDIA_STS (0x0EC8) - -/* MAC link state bits */ -#define RTL838X_FORCE_EN (1 << 0) -#define RTL838X_FORCE_LINK_EN (1 << 1) -#define RTL838X_NWAY_EN (1 << 2) -#define RTL838X_DUPLEX_MODE (1 << 3) -#define RTL838X_TX_PAUSE_EN (1 << 6) -#define RTL838X_RX_PAUSE_EN (1 << 7) -#define RTL838X_MAC_FORCE_FC_EN (1 << 8) - -#define RTL839X_FORCE_EN (1 << 0) -#define RTL839X_FORCE_LINK_EN (1 << 1) -#define RTL839X_DUPLEX_MODE (1 << 2) -#define RTL839X_TX_PAUSE_EN (1 << 5) -#define RTL839X_RX_PAUSE_EN (1 << 6) -#define RTL839X_MAC_FORCE_FC_EN (1 << 7) - -#define RTL930X_FORCE_EN (1 << 0) -#define RTL930X_FORCE_LINK_EN (1 << 1) -#define RTL930X_DUPLEX_MODE (1 << 2) -#define RTL930X_TX_PAUSE_EN (1 << 7) -#define RTL930X_RX_PAUSE_EN (1 << 8) -#define RTL930X_MAC_FORCE_FC_EN (1 << 9) - -#define RTL931X_FORCE_EN (1 << 9) -#define RTL931X_FORCE_LINK_EN (1 << 0) -#define RTL931X_DUPLEX_MODE (1 << 2) -#define RTL931X_MAC_FORCE_FC_EN (1 << 4) -#define RTL931X_TX_PAUSE_EN (1 << 16) -#define RTL931X_RX_PAUSE_EN (1 << 17) - -/* EEE */ -#define RTL838X_MAC_EEE_ABLTY (0xa1a8) -#define RTL838X_EEE_PORT_TX_EN (0x014c) -#define RTL838X_EEE_PORT_RX_EN (0x0150) -#define RTL838X_EEE_CLK_STOP_CTRL (0x0148) -#define RTL838X_EEE_TX_TIMER_GIGA_CTRL (0xaa04) -#define RTL838X_EEE_TX_TIMER_GELITE_CTRL (0xaa08) - -#define RTL839X_EEE_TX_TIMER_GELITE_CTRL (0x042C) -#define RTL839X_EEE_TX_TIMER_GIGA_CTRL (0x0430) -#define RTL839X_EEE_TX_TIMER_10G_CTRL (0x0434) -#define RTL839X_EEE_CTRL(p) (0x8008 + ((p) << 7)) -#define RTL839X_MAC_EEE_ABLTY (0x03C8) - -#define RTL930X_MAC_EEE_ABLTY (0xCB34) -#define RTL930X_EEE_CTRL(p) (0x3274 + ((p) << 6)) -#define RTL930X_EEEP_PORT_CTRL(p) (0x3278 + ((p) << 6)) - -/* L2 functionality */ -#define RTL838X_L2_CTRL_0 (0x3200) -#define RTL839X_L2_CTRL_0 (0x3800) -#define RTL930X_L2_CTRL (0x8FD8) -#define RTL931X_L2_CTRL (0xC800) -#define RTL838X_L2_CTRL_1 (0x3204) -#define RTL839X_L2_CTRL_1 (0x3804) -#define RTL930X_L2_AGE_CTRL (0x8FDC) -#define RTL931X_L2_AGE_CTRL (0xC804) -#define RTL838X_L2_PORT_AGING_OUT (0x3358) -#define RTL839X_L2_PORT_AGING_OUT (0x3b74) -#define RTL930X_L2_PORT_AGE_CTRL (0x8FE0) -#define RTL931X_L2_PORT_AGE_CTRL (0xc808) -#define RTL838X_TBL_ACCESS_L2_CTRL (0x6900) -#define RTL839X_TBL_ACCESS_L2_CTRL (0x1180) -#define RTL930X_TBL_ACCESS_L2_CTRL (0xB320) -#define RTL930X_TBL_ACCESS_L2_METHOD_CTRL (0xB324) -#define RTL838X_TBL_ACCESS_L2_DATA(idx) (0x6908 + ((idx) << 2)) -#define RTL839X_TBL_ACCESS_L2_DATA(idx) (0x1184 + ((idx) << 2)) -#define RTL930X_TBL_ACCESS_L2_DATA(idx) (0xab08 + ((idx) << 2)) - -#define RTL838X_L2_TBL_FLUSH_CTRL (0x3370) -#define RTL839X_L2_TBL_FLUSH_CTRL (0x3ba0) -#define RTL930X_L2_TBL_FLUSH_CTRL (0x9404) -#define RTL931X_L2_TBL_FLUSH_CTRL (0xCD9C) - -#define RTL838X_L2_LRN_CONSTRT (0x329C) -#define RTL839X_L2_LRN_CONSTRT (0x3910) -#define RTL930X_L2_LRN_CONSTRT_CTRL (0x909c) -#define RTL931X_L2_LRN_CONSTRT_CTRL (0xC964) - -#define RTL838X_L2_FLD_PMSK (0x3288) -#define RTL839X_L2_FLD_PMSK (0x38EC) -#define RTL930X_L2_BC_FLD_PMSK (0x9068) -#define RTL931X_L2_BC_FLD_PMSK (0xC8FC) - -#define RTL930X_L2_UNKN_UC_FLD_PMSK (0x9064) -#define RTL931X_L2_UNKN_UC_FLD_PMSK (0xC8F4) - -#define RTL838X_L2_LRN_CONSTRT_EN (0x3368) -#define RTL838X_L2_PORT_LRN_CONSTRT (0x32A0) -#define RTL839X_L2_PORT_LRN_CONSTRT (0x3914) - -#define RTL838X_L2_PORT_NEW_SALRN(p) (0x328c + (((p >> 4) << 2))) -#define RTL839X_L2_PORT_NEW_SALRN(p) (0x38F0 + (((p >> 4) << 2))) -#define RTL930X_L2_PORT_SALRN(p) (0x8FEC + (((p >> 4) << 2))) -#define RTL931X_L2_PORT_NEW_SALRN(p) (0xC820 + (((p >> 4) << 2))) - -#define SALRN_PORT_SHIFT(p) ((p % 16) * 2) -#define SALRN_MODE_MASK 0x3 -#define SALRN_MODE_HARDWARE 0 -#define SALRN_MODE_DISABLED 2 - -#define RTL838X_L2_PORT_NEW_SA_FWD(p) (0x3294 + (((p >> 4) << 2))) -#define RTL839X_L2_PORT_NEW_SA_FWD(p) (0x3900 + (((p >> 4) << 2))) -#define RTL930X_L2_PORT_NEW_SA_FWD(p) (0x8FF4 + (((p / 10) << 2))) -#define RTL931X_L2_PORT_NEW_SA_FWD(p) (0xC830 + (((p / 10) << 2))) - -#define RTL838X_L2_PORT_MV_ACT(p) (0x335c + (((p >> 4) << 2))) -#define RTL839X_L2_PORT_MV_ACT(p) (0x3b80 + (((p >> 4) << 2))) - -#define RTL838X_L2_PORT_STATIC_MV_ACT(p) (0x327c + (((p >> 4) << 2))) -#define RTL839X_L2_PORT_STATIC_MV_ACT(p) (0x38dc + (((p >> 4) << 2))) - -#define MV_ACT_PORT_SHIFT(p) ((p % 16) * 2) -#define MV_ACT_MASK 0x3 -#define MV_ACT_FORWARD 0 -#define MV_ACT_DROP 1 -#define MV_ACT_TRAP2CPU 2 -#define MV_ACT_COPY2CPU 3 - -#define RTL930X_ST_CTRL (0x8798) - -#define RTL930X_L2_PORT_SABLK_CTRL (0x905c) -#define RTL930X_L2_PORT_DABLK_CTRL (0x9060) - -#define RTL838X_L2_PORT_LM_ACT(p) (0x3208 + ((p) << 2)) -#define RTL838X_VLAN_PORT_FWD (0x3A78) -#define RTL839X_VLAN_PORT_FWD (0x27AC) -#define RTL930X_VLAN_PORT_FWD (0x834C) -#define RTL931X_VLAN_PORT_FWD (0x95CC) -#define RTL838X_VLAN_FID_CTRL (0x3aa8) - -/* Port Mirroring */ -#define RTL838X_MIR_CTRL (0x5D00) -#define RTL838X_MIR_DPM_CTRL (0x5D20) -#define RTL838X_MIR_SPM_CTRL (0x5D10) - -#define RTL839X_MIR_CTRL (0x2500) -#define RTL839X_MIR_DPM_CTRL (0x2530) -#define RTL839X_MIR_SPM_CTRL (0x2510) - -#define RTL930X_MIR_CTRL (0xA2A0) -#define RTL930X_MIR_DPM_CTRL (0xA2C0) -#define RTL930X_MIR_SPM_CTRL (0xA2B0) - -#define RTL931X_MIR_CTRL (0xAF00) -#define RTL931X_MIR_DPM_CTRL (0xAF30) -#define RTL931X_MIR_SPM_CTRL (0xAF10) - -/* Storm/rate control and scheduling */ -#define RTL838X_STORM_CTRL (0x4700) -#define RTL839X_STORM_CTRL (0x1800) -#define RTL838X_STORM_CTRL_LB_CTRL(p) (0x4884 + (((p) << 2))) -#define RTL838X_STORM_CTRL_BURST_PPS_0 (0x4874) -#define RTL838X_STORM_CTRL_BURST_PPS_1 (0x4878) -#define RTL838X_STORM_CTRL_BURST_0 (0x487c) -#define RTL838X_STORM_CTRL_BURST_1 (0x4880) -#define RTL839X_STORM_CTRL_LB_TICK_TKN_CTRL_0 (0x1804) -#define RTL839X_STORM_CTRL_LB_TICK_TKN_CTRL_1 (0x1808) -#define RTL838X_SCHED_CTRL (0xB980) -#define RTL839X_SCHED_CTRL (0x60F4) -#define RTL838X_SCHED_LB_TICK_TKN_CTRL_0 (0xAD58) -#define RTL838X_SCHED_LB_TICK_TKN_CTRL_1 (0xAD5C) -#define RTL839X_SCHED_LB_TICK_TKN_CTRL_0 (0x1804) -#define RTL839X_SCHED_LB_TICK_TKN_CTRL_1 (0x1808) -#define RTL839X_STORM_CTRL_SPCL_LB_TICK_TKN_CTRL (0x2000) -#define RTL839X_IGR_BWCTRL_LB_TICK_TKN_CTRL_0 (0x1604) -#define RTL839X_IGR_BWCTRL_LB_TICK_TKN_CTRL_1 (0x1608) -#define RTL839X_SCHED_LB_TICK_TKN_CTRL (0x60F8) -#define RTL839X_SCHED_LB_TICK_TKN_PPS_CTRL (0x6200) -#define RTL838X_SCHED_LB_THR (0xB984) -#define RTL839X_SCHED_LB_THR (0x60FC) -#define RTL838X_SCHED_P_EGR_RATE_CTRL(p) (0xC008 + (((p) << 7))) -#define RTL838X_SCHED_Q_EGR_RATE_CTRL(p, q) (0xC00C + (p << 7) + (((q) << 2))) -#define RTL838X_STORM_CTRL_PORT_BC_EXCEED (0x470C) -#define RTL838X_STORM_CTRL_PORT_MC_EXCEED (0x4710) -#define RTL838X_STORM_CTRL_PORT_UC_EXCEED (0x4714) -#define RTL839X_STORM_CTRL_PORT_BC_EXCEED(p) (0x180c + (((p >> 5) << 2))) -#define RTL839X_STORM_CTRL_PORT_MC_EXCEED(p) (0x1814 + (((p >> 5) << 2))) -#define RTL839X_STORM_CTRL_PORT_UC_EXCEED(p) (0x181c + (((p >> 5) << 2))) -#define RTL838X_STORM_CTRL_PORT_UC(p) (0x4718 + (((p) << 2))) -#define RTL838X_STORM_CTRL_PORT_MC(p) (0x478c + (((p) << 2))) -#define RTL838X_STORM_CTRL_PORT_BC(p) (0x4800 + (((p) << 2))) -#define RTL839X_STORM_CTRL_PORT_UC_0(p) (0x185C + (((p) << 3))) -#define RTL839X_STORM_CTRL_PORT_UC_1(p) (0x1860 + (((p) << 3))) -#define RTL839X_STORM_CTRL_PORT_MC_0(p) (0x19FC + (((p) << 3))) -#define RTL839X_STORM_CTRL_PORT_MC_1(p) (0x1a00 + (((p) << 3))) -#define RTL839X_STORM_CTRL_PORT_BC_0(p) (0x1B9C + (((p) << 3))) -#define RTL839X_STORM_CTRL_PORT_BC_1(p) (0x1BA0 + (((p) << 3))) -#define RTL839X_TBL_ACCESS_CTRL_2 (0x611C) -#define RTL839X_TBL_ACCESS_DATA_2(i) (0x6120 + (((i) << 2))) -#define RTL839X_IGR_BWCTRL_PORT_CTRL_10G_0(p) (0x1618 + (((p) << 3))) -#define RTL839X_IGR_BWCTRL_PORT_CTRL_10G_1(p) (0x161C + (((p) << 3))) -#define RTL839X_IGR_BWCTRL_PORT_CTRL_0(p) (0x1640 + (((p) << 3))) -#define RTL839X_IGR_BWCTRL_PORT_CTRL_1(p) (0x1644 + (((p) << 3))) -#define RTL839X_IGR_BWCTRL_CTRL_LB_THR (0x1614) - -/* Link aggregation (Trunking) */ -#define TRUNK_DISTRIBUTION_ALGO_SPA_BIT 0x01 -#define TRUNK_DISTRIBUTION_ALGO_SMAC_BIT 0x02 -#define TRUNK_DISTRIBUTION_ALGO_DMAC_BIT 0x04 -#define TRUNK_DISTRIBUTION_ALGO_SIP_BIT 0x08 -#define TRUNK_DISTRIBUTION_ALGO_DIP_BIT 0x10 -#define TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT 0x20 -#define TRUNK_DISTRIBUTION_ALGO_DST_L4PORT_BIT 0x40 -#define TRUNK_DISTRIBUTION_ALGO_MASKALL 0x7F - -#define TRUNK_DISTRIBUTION_ALGO_L2_SPA_BIT 0x01 -#define TRUNK_DISTRIBUTION_ALGO_L2_SMAC_BIT 0x02 -#define TRUNK_DISTRIBUTION_ALGO_L2_DMAC_BIT 0x04 -#define TRUNK_DISTRIBUTION_ALGO_L2_VLAN_BIT 0x08 -#define TRUNK_DISTRIBUTION_ALGO_L2_MASKALL 0xF - -#define TRUNK_DISTRIBUTION_ALGO_L3_SPA_BIT 0x01 -#define TRUNK_DISTRIBUTION_ALGO_L3_SMAC_BIT 0x02 -#define TRUNK_DISTRIBUTION_ALGO_L3_DMAC_BIT 0x04 -#define TRUNK_DISTRIBUTION_ALGO_L3_VLAN_BIT 0x08 -#define TRUNK_DISTRIBUTION_ALGO_L3_SIP_BIT 0x10 -#define TRUNK_DISTRIBUTION_ALGO_L3_DIP_BIT 0x20 -#define TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT 0x40 -#define TRUNK_DISTRIBUTION_ALGO_L3_DST_L4PORT_BIT 0x80 -#define TRUNK_DISTRIBUTION_ALGO_L3_PROTO_BIT 0x100 -#define TRUNK_DISTRIBUTION_ALGO_L3_FLOW_LABEL_BIT 0x200 -#define TRUNK_DISTRIBUTION_ALGO_L3_MASKALL 0x3FF - -#define RTL838X_TRK_MBR_CTR (0x3E00) -#define RTL838X_TRK_HASH_IDX_CTRL (0x3E20) -#define RTL838X_TRK_HASH_CTRL (0x3E24) - -#define RTL839X_TRK_MBR_CTR (0x2200) -#define RTL839X_TRK_HASH_IDX_CTRL (0x2280) -#define RTL839X_TRK_HASH_CTRL (0x2284) - -#define RTL930X_TRK_MBR_CTRL (0xA41C) -#define RTL930X_TRK_HASH_CTRL (0x9F80) - -#define RTL931X_TRK_MBR_CTRL (0xB8D0) -#define RTL931X_TRK_HASH_CTRL (0xBA70) - -/* Attack prevention */ -#define RTL838X_ATK_PRVNT_PORT_EN (0x5B00) -#define RTL838X_ATK_PRVNT_CTRL (0x5B04) -#define RTL838X_ATK_PRVNT_ACT (0x5B08) -#define RTL838X_ATK_PRVNT_STS (0x5B1C) - -/* 802.1X */ -#define RTL838X_RMA_BPDU_FLD_PMSK (0x4348) -#define RTL930X_RMA_BPDU_FLD_PMSK (0x9F18) -#define RTL931X_RMA_BPDU_FLD_PMSK (0x8950) -#define RTL839X_RMA_BPDU_FLD_PMSK (0x125C) - -#define RTL838X_SPCL_TRAP_CTRL (0x6980) -#define RTL838X_SPCL_TRAP_EAPOL_CTRL (0x6988) -#define RTL838X_SPCL_TRAP_ARP_CTRL (0x698C) -#define RTL838X_SPCL_TRAP_IGMP_CTRL (0x6984) -#define RTL838X_SPCL_TRAP_IPV6_CTRL (0x6994) -#define RTL838X_SPCL_TRAP_SWITCH_MAC_CTRL (0x6998) - -#define RTL839X_SPCL_TRAP_CTRL (0x1054) -#define RTL839X_SPCL_TRAP_EAPOL_CTRL (0x105C) -#define RTL839X_SPCL_TRAP_ARP_CTRL (0x1060) -#define RTL839X_SPCL_TRAP_IGMP_CTRL (0x1058) -#define RTL839X_SPCL_TRAP_IPV6_CTRL (0x1064) -#define RTL839X_SPCL_TRAP_SWITCH_MAC_CTRL (0x1068) -#define RTL839X_SPCL_TRAP_SWITCH_IPV4_ADDR_CTRL (0x106C) -#define RTL839X_SPCL_TRAP_CRC_CTRL (0x1070) -/* special port action controls */ -/* values: - * 0 = FORWARD (default) - * 1 = DROP - * 2 = TRAP2CPU - * 3 = FLOOD IN ALL PORT - * - * Register encoding. - * offset = CTRL + (port >> 4) << 2 - * value/mask = 3 << ((port & 0xF) << 1) - */ - -typedef enum { - BPDU = 0, - PTP, - PTP_UDP, - PTP_ETH2, - LLDP, - EAPOL, - GRATARP, -} rma_ctrl_t; - -typedef enum { - FORWARD = 0, - DROP, - TRAP2CPU, - FLOODALL, - TRAP2MASTERCPU, - COPY2CPU, -} action_type_t; - -#define RTL838X_RMA_BPDU_CTRL (0x4330) -#define RTL839X_RMA_BPDU_CTRL (0x122C) -#define RTL930X_RMA_BPDU_CTRL (0x9E7C) -#define RTL931X_RMA_BPDU_CTRL (0x881C) - -#define RTL838X_RMA_PTP_CTRL (0x4338) -#define RTL839X_RMA_PTP_CTRL (0x123C) -#define RTL930X_RMA_PTP_CTRL (0x9E88) -#define RTL931X_RMA_PTP_CTRL (0x8834) - -#define RTL838X_RMA_LLDP_CTRL (0x4340) -#define RTL839X_RMA_LLDP_CTRL (0x124C) -#define RTL930X_RMA_LLDP_CTRL (0x9EFC) -#define RTL931X_RMA_LLDP_CTRL (0x8918) - -#define RTL930X_RMA_EAPOL_CTRL (0x9F08) -#define RTL931X_RMA_EAPOL_CTRL (0x8930) -#define RTL931X_TRAP_ARP_GRAT_PORT_ACT (0x8C04) - -/* QoS */ -#define RTL838X_QM_INTPRI2QID_CTRL (0x5F00) -#define RTL839X_QM_INTPRI2QID_CTRL(q) (0x1110 + (q << 2)) -#define RTL839X_QM_PORT_QNUM(p) (0x1130 + (((p / 10) << 2))) -#define RTL838X_PRI_SEL_PORT_PRI(p) (0x5FB8 + (((p / 10) << 2))) -#define RTL839X_PRI_SEL_PORT_PRI(p) (0x10A8 + (((p / 10) << 2))) -#define RTL838X_QM_PKT2CPU_INTPRI_MAP (0x5F10) -#define RTL839X_QM_PKT2CPU_INTPRI_MAP (0x1154) -#define RTL838X_PRI_SEL_CTRL (0x10E0) -#define RTL839X_PRI_SEL_CTRL (0x10E0) -#define RTL838X_PRI_SEL_TBL_CTRL(i) (0x5FD8 + (((i) << 2))) -#define RTL839X_PRI_SEL_TBL_CTRL(i) (0x10D0 + (((i) << 2))) -#define RTL838X_QM_PKT2CPU_INTPRI_0 (0x5F04) -#define RTL838X_QM_PKT2CPU_INTPRI_1 (0x5F08) -#define RTL838X_QM_PKT2CPU_INTPRI_2 (0x5F0C) -#define RTL839X_OAM_CTRL (0x2100) -#define RTL839X_OAM_PORT_ACT_CTRL(p) (0x2104 + (((p) << 2))) -#define RTL839X_RMK_PORT_DEI_TAG_CTRL(p) (0x6A9C + (((p >> 5) << 2))) -#define RTL839X_PRI_SEL_IPRI_REMAP (0x1080) -#define RTL838X_PRI_SEL_IPRI_REMAP (0x5F8C) -#define RTL839X_PRI_SEL_DEI2DP_REMAP (0x10EC) -#define RTL839X_PRI_SEL_DSCP2DP_REMAP_ADDR(i) (0x10F0 + (((i >> 4) << 2))) -#define RTL839X_RMK_DEI_CTRL (0x6AA4) -#define RTL839X_WRED_PORT_THR_CTRL(i) (0x6084 + ((i) << 2)) -#define RTL839X_WRED_QUEUE_THR_CTRL(q, i) (0x6090 + ((q) * 12) + ((i) << 2)) -#define RTL838X_PRI_DSCP_INVLD_CTRL0 (0x5FE8) -#define RTL838X_RMK_IPRI_CTRL (0xA460) -#define RTL838X_RMK_OPRI_CTRL (0xA464) -#define RTL838X_SCHED_P_TYPE_CTRL(p) (0xC04C + (((p) << 7))) -#define RTL838X_SCHED_LB_CTRL(p) (0xC004 + (((p) << 7))) -#define RTL838X_FC_P_EGR_DROP_CTRL(p) (0x6B1C + (((p) << 2))) - -/* Debug features */ -#define RTL930X_STAT_PRVTE_DROP_COUNTER0 (0xB5B8) - -/* Packet Inspection Engine */ -#define RTL838X_METER_GLB_CTRL (0x4B08) -#define RTL839X_METER_GLB_CTRL (0x1300) -#define RTL930X_METER_GLB_CTRL (0xa0a0) -#define RTL931X_METER_GLB_CTRL (0x411C) - -#define RTL839X_ACL_CTRL (0x1288) - -#define RTL838X_ACL_BLK_LOOKUP_CTRL (0x6100) -#define RTL839X_ACL_BLK_LOOKUP_CTRL (0x1280) -#define RTL930X_PIE_BLK_LOOKUP_CTRL (0xa5a0) -#define RTL931X_PIE_BLK_LOOKUP_CTRL (0x4180) - -#define RTL838X_ACL_BLK_PWR_CTRL (0x6104) -#define RTL839X_PS_ACL_PWR_CTRL (0x049c) - -#define RTL838X_ACL_BLK_TMPLTE_CTRL(block) (0x6108 + ((block) << 2)) -#define RTL839X_ACL_BLK_TMPLTE_CTRL(block) (0x128c + ((block) << 2)) -#define RTL930X_PIE_BLK_TMPLTE_CTRL(block) (0xa624 + ((block) << 2)) -#define RTL931X_PIE_BLK_TMPLTE_CTRL(block) (0x4214 + ((block) << 2)) - -#define RTL838X_ACL_BLK_GROUP_CTRL (0x615C) -#define RTL839X_ACL_BLK_GROUP_CTRL (0x12ec) - -#define RTL838X_ACL_CLR_CTRL (0x6168) -#define RTL839X_ACL_CLR_CTRL (0x12fc) -#define RTL930X_PIE_CLR_CTRL (0xa66c) -#define RTL931X_PIE_CLR_CTRL (0x42D8) - -#define RTL838X_DMY_REG27 (0x3378) - -#define RTL838X_ACL_PORT_LOOKUP_CTRL(p) (0x616C + (((p) << 2))) -#define RTL930X_ACL_PORT_LOOKUP_CTRL(p) (0xA784 + (((p) << 2))) -#define RTL931X_ACL_PORT_LOOKUP_CTRL(p) (0x44F8 + (((p) << 2))) - -#define RTL930X_PIE_BLK_PHASE_CTRL (0xA5A4) -#define RTL931X_PIE_BLK_PHASE_CTRL (0x4184) - -/* PIE actions */ -#define PIE_ACT_COPY_TO_PORT 2 -#define PIE_ACT_REDIRECT_TO_PORT 4 -#define PIE_ACT_ROUTE_UC 6 -#define PIE_ACT_VID_ASSIGN 0 - -/* L3 actions */ -#define L3_FORWARD 0 -#define L3_DROP 1 -#define L3_TRAP2CPU 2 -#define L3_COPY2CPU 3 -#define L3_TRAP2MASTERCPU 4 -#define L3_COPY2MASTERCPU 5 -#define L3_HARDDROP 6 - -/* Route actions */ -#define ROUTE_ACT_FORWARD 0 -#define ROUTE_ACT_TRAP2CPU 1 -#define ROUTE_ACT_COPY2CPU 2 -#define ROUTE_ACT_DROP 3 - -/* L3 Routing */ -#define RTL839X_ROUTING_SA_CTRL 0x6afc -#define RTL930X_L3_HOST_TBL_CTRL (0xAB48) -#define RTL930X_L3_IPUC_ROUTE_CTRL (0xAB4C) -#define RTL930X_L3_IP6UC_ROUTE_CTRL (0xAB50) -#define RTL930X_L3_IPMC_ROUTE_CTRL (0xAB54) -#define RTL930X_L3_IP6MC_ROUTE_CTRL (0xAB58) -#define RTL930X_L3_IP_MTU_CTRL(i) (0xAB5C + ((i >> 1) << 2)) -#define RTL930X_L3_IP6_MTU_CTRL(i) (0xAB6C + ((i >> 1) << 2)) -#define RTL930X_L3_HW_LU_KEY_CTRL (0xAC9C) -#define RTL930X_L3_HW_LU_KEY_IP_CTRL (0xACA0) -#define RTL930X_L3_HW_LU_CTRL (0xACC0) -#define RTL930X_L3_IP_ROUTE_CTRL 0xab44 - -/* Port LED Control */ -#define RTL930X_LED_PORT_NUM_CTRL(p) (0xCC04 + (((p >> 4) << 2))) -#define RTL930X_LED_SET0_0_CTRL (0xCC28) -#define RTL930X_LED_PORT_COPR_SET_SEL_CTRL(p) (0xCC2C + (((p >> 4) << 2))) -#define RTL930X_LED_PORT_FIB_SET_SEL_CTRL(p) (0xCC34 + (((p >> 4) << 2))) -#define RTL930X_LED_PORT_COPR_MASK_CTRL (0xCC3C) -#define RTL930X_LED_PORT_FIB_MASK_CTRL (0xCC40) -#define RTL930X_LED_PORT_COMBO_MASK_CTRL (0xCC44) - -#define RTL931X_LED_PORT_NUM_CTRL(p) (0x0604 + (((p >> 4) << 2))) -#define RTL931X_LED_SET0_0_CTRL (0x0630) -#define RTL931X_LED_PORT_COPR_SET_SEL_CTRL(p) (0x0634 + (((p >> 4) << 2))) -#define RTL931X_LED_PORT_FIB_SET_SEL_CTRL(p) (0x0644 + (((p >> 4) << 2))) -#define RTL931X_LED_PORT_COPR_MASK_CTRL (0x0654) -#define RTL931X_LED_PORT_FIB_MASK_CTRL (0x065c) -#define RTL931X_LED_PORT_COMBO_MASK_CTRL (0x0664) - -#define MAX_VLANS 4096 -#define MAX_LAGS 16 -#define MAX_PRIOS 8 -#define RTL930X_PORT_IGNORE 0x3f -#define MAX_MC_GROUPS 512 -#define UNKNOWN_MC_PMASK (MAX_MC_GROUPS - 1) -#define PIE_BLOCK_SIZE 128 -#define MAX_PIE_ENTRIES (18 * PIE_BLOCK_SIZE) -#define N_FIXED_FIELDS 12 -#define N_FIXED_FIELDS_RTL931X 14 -#define MAX_COUNTERS 2048 -#define MAX_ROUTES 512 -#define MAX_HOST_ROUTES 1536 -#define MAX_INTF_MTUS 8 -#define DEFAULT_MTU 1536 -#define MAX_INTERFACES 100 -#define MAX_ROUTER_MACS 64 -#define L3_EGRESS_DMACS 2048 -#define MAX_SMACS 64 - -enum phy_type { - PHY_NONE = 0, - PHY_RTL838X_SDS = 1, - PHY_RTL8218B_INT = 2, - PHY_RTL8218B_EXT = 3, - PHY_RTL8214FC = 4, - PHY_RTL839X_SDS = 5, - PHY_RTL930X_SDS = 6, -}; - -enum pbvlan_type { - PBVLAN_TYPE_INNER = 0, - PBVLAN_TYPE_OUTER, -}; - -enum pbvlan_mode { - PBVLAN_MODE_UNTAG_AND_PRITAG = 0, - PBVLAN_MODE_UNTAG_ONLY, - PBVLAN_MODE_ALL_PKT, -}; - -struct rtl838x_port { - bool enable; - u64 pm; - u16 pvid; - bool eee_enabled; - enum phy_type phy; - bool phy_is_integrated; - bool is10G; - bool is2G5; - int sds_num; - int led_set; - int leds_on_this_port; - const struct dsa_port *dp; -}; - -struct rtl838x_vlan_info { - u64 untagged_ports; - u64 tagged_ports; - u8 profile_id; - bool hash_mc_fid; - bool hash_uc_fid; - u8 fid; /* AKA MSTI */ - - /* The following fields are used only by the RTL931X */ - int if_id; /* Interface (index in L3_EGR_INTF_IDX) */ - u16 multicast_grp_mask; - int l2_tunnel_list_id; -}; - -enum l2_entry_type { - L2_INVALID = 0, - L2_UNICAST = 1, - L2_MULTICAST = 2, - IP4_MULTICAST = 3, - IP6_MULTICAST = 4, -}; - -struct rtl838x_l2_entry { - u8 mac[6]; - u16 vid; - u16 rvid; - u8 port; - bool valid; - enum l2_entry_type type; - bool is_static; - bool is_ip_mc; - bool is_ipv6_mc; - bool block_da; - bool block_sa; - bool suspended; - bool next_hop; - int age; - u8 trunk; - bool is_trunk; - u8 stack_dev; - u16 mc_portmask_index; - u32 mc_gip; - u32 mc_sip; - u16 mc_mac_index; - u16 nh_route_id; - bool nh_vlan_target; /* Only RTL83xx: VLAN used for next hop */ - - /* The following is only valid on RTL931x */ - bool is_open_flow; - bool is_pe_forward; - bool is_local_forward; - bool is_remote_forward; - bool is_l2_tunnel; - int l2_tunnel_id; - int l2_tunnel_list_id; -}; - -enum fwd_rule_action { - FWD_RULE_ACTION_NONE = 0, - FWD_RULE_ACTION_FWD = 1, -}; - -enum pie_phase { - PHASE_VACL = 0, - PHASE_IACL = 1, -}; - -enum igr_filter { - IGR_FORWARD = 0, - IGR_DROP = 1, - IGR_TRAP = 2, -}; - -enum egr_filter { - EGR_DISABLE = 0, - EGR_ENABLE = 1, -}; - -/* Intermediate representation of a Packet Inspection Engine Rule - * as suggested by the Kernel's tc flower offload subsystem - * Field meaning is universal across SoC families, but data content is specific - * to SoC family (e.g. because of different port ranges) */ -struct pie_rule { - int id; - enum pie_phase phase; /* Phase in which this template is applied */ - int packet_cntr; /* ID of a packet counter assigned to this rule */ - int octet_cntr; /* ID of a byte counter assigned to this rule */ - u32 last_packet_cnt; - u64 last_octet_cnt; - - /* The following are requirements for the pie template */ - bool is_egress; - bool is_ipv6; /* This is a rule with IPv6 fields */ - - /* Fixed fields that are always matched against on RTL8380 */ - u8 spmmask_fix; - u8 spn; /* Source port number */ - bool stacking_port; /* Source port is stacking port */ - bool mgnt_vlan; /* Packet arrived on management VLAN */ - bool dmac_hit_sw; /* The packet's destination MAC matches one of the device's */ - bool content_too_deep; /* The content of the packet cannot be parsed: too many layers */ - bool not_first_frag; /* Not the first IP fragment */ - u8 frame_type_l4; /* 0: UDP, 1: TCP, 2: ICMP/ICMPv6, 3: IGMP */ - u8 frame_type; /* 0: ARP, 1: L2 only, 2: IPv4, 3: IPv6 */ - bool otag_fmt; /* 0: outer tag packet, 1: outer priority tag or untagged */ - bool itag_fmt; /* 0: inner tag packet, 1: inner priority tag or untagged */ - bool otag_exist; /* packet with outer tag */ - bool itag_exist; /* packet with inner tag */ - bool frame_type_l2; /* 0: Ethernet, 1: LLC_SNAP, 2: LLC_Other, 3: Reserved */ - bool igr_normal_port; /* Ingress port is not cpu or stacking port */ - u8 tid; /* The template ID defining the what the templated fields mean */ - - /* Masks for the fields that are always matched against on RTL8380 */ - u8 spmmask_fix_m; - u8 spn_m; - bool stacking_port_m; - bool mgnt_vlan_m; - bool dmac_hit_sw_m; - bool content_too_deep_m; - bool not_first_frag_m; - u8 frame_type_l4_m; - u8 frame_type_m; - bool otag_fmt_m; - bool itag_fmt_m; - bool otag_exist_m; - bool itag_exist_m; - bool frame_type_l2_m; - bool igr_normal_port_m; - u8 tid_m; - - /* Logical operations between rules, special rules for rule numbers apply */ - bool valid; - bool cond_not; /* Matches when conditions not match */ - bool cond_and1; /* And this rule 2n with the next rule 2n+1 in same block */ - bool cond_and2; /* And this rule m in block 2n with rule m in block 2n+1 */ - bool ivalid; - - /* Actions to be performed */ - bool drop; /* Drop the packet */ - bool fwd_sel; /* Forward packet: to port, portmask, dest route, next rule, drop */ - bool ovid_sel; /* So something to outer vlan-id: shift, re-assign */ - bool ivid_sel; /* Do something to inner vlan-id: shift, re-assign */ - bool flt_sel; /* Filter the packet when sending to certain ports */ - bool log_sel; /* Log the packet in one of the LOG-table counters */ - bool rmk_sel; /* Re-mark the packet, i.e. change the priority-tag */ - bool meter_sel; /* Meter the packet, i.e. limit rate of this type of packet */ - bool tagst_sel; /* Change the ergress tag */ - bool mir_sel; /* Mirror the packet to a Link Aggregation Group */ - bool nopri_sel; /* Change the normal priority */ - bool cpupri_sel; /* Change the CPU priority */ - bool otpid_sel; /* Change Outer Tag Protocol Identifier (802.1q) */ - bool itpid_sel; /* Change Inner Tag Protocol Identifier (802.1q) */ - bool shaper_sel; /* Apply traffic shaper */ - bool mpls_sel; /* MPLS actions */ - bool bypass_sel; /* Bypass actions */ - bool fwd_sa_lrn; /* Learn the source address when forwarding */ - bool fwd_mod_to_cpu; /* Forward the modified VLAN tag format to CPU-port */ - - /* Fields used in predefined templates 0-2 on RTL8380 / 90 / 9300 */ - u64 spm; /* Source Port Matrix */ - u16 otag; /* Outer VLAN-ID */ - u8 smac[ETH_ALEN]; /* Source MAC address */ - u8 dmac[ETH_ALEN]; /* Destination MAC address */ - u16 ethertype; /* Ethernet frame type field in ethernet header */ - u16 itag; /* Inner VLAN-ID */ - u16 field_range_check; - u32 sip; /* Source IP */ - struct in6_addr sip6; /* IPv6 Source IP */ - u32 dip; /* Destination IP */ - struct in6_addr dip6; /* IPv6 Destination IP */ - u16 tos_proto; /* IPv4: TOS + Protocol fields, IPv6: Traffic class + next header */ - u16 sport; /* TCP/UDP source port */ - u16 dport; /* TCP/UDP destination port */ - u16 icmp_igmp; - u16 tcp_info; - u16 dsap_ssap; /* Destination / Source Service Access Point bytes (802.3) */ - - u64 spm_m; - u16 otag_m; - u8 smac_m[ETH_ALEN]; - u8 dmac_m[ETH_ALEN]; - u8 ethertype_m; - u16 itag_m; - u16 field_range_check_m; - u32 sip_m; - struct in6_addr sip6_m; /* IPv6 Source IP mask */ - u32 dip_m; - struct in6_addr dip6_m; /* IPv6 Destination IP mask */ - u16 tos_proto_m; - u16 sport_m; - u16 dport_m; - u16 icmp_igmp_m; - u16 tcp_info_m; - u16 dsap_ssap_m; - - /* Data associated with actions */ - u8 fwd_act; /* Type of forwarding action */ - /* 0: permit, 1: drop, 2: copy to port id, 4: copy to portmask */ - /* 4: redirect to portid, 5: redirect to portmask */ - /* 6: route, 7: vlan leaky (only 8380) */ - u16 fwd_data; /* Additional data for forwarding action, e.g. destination port */ - u8 ovid_act; - u16 ovid_data; /* Outer VLAN ID */ - u8 ivid_act; - u16 ivid_data; /* Inner VLAN ID */ - u16 flt_data; /* Filtering data */ - u16 log_data; /* ID of packet or octet counter in LOG table, on RTL93xx */ - /* unnecessary since PIE-Rule-ID == LOG-counter-ID */ - bool log_octets; - u8 mpls_act; /* MPLS action type */ - u16 mpls_lib_idx; /* MPLS action data */ - - u16 rmk_data; /* Data for remarking */ - u16 meter_data; /* ID of meter for bandwidth control */ - u16 tagst_data; - u16 mir_data; - u16 nopri_data; - u16 cpupri_data; - u16 otpid_data; - u16 itpid_data; - u16 shaper_data; - - /* Bypass actions, ignored on RTL8380 */ - bool bypass_all; /* Not clear */ - bool bypass_igr_stp; /* Bypass Ingress STP state */ - bool bypass_ibc_sc; /* Bypass Ingress Bandwidth Control and Storm Control */ -}; - -struct rtl838x_l3_intf { - u16 vid; - u8 smac_idx; - u8 ip4_mtu_id; - u8 ip6_mtu_id; - u16 ip4_mtu; - u16 ip6_mtu; - u8 ttl_scope; - u8 hl_scope; - u8 ip4_icmp_redirect; - u8 ip6_icmp_redirect; - u8 ip4_pbr_icmp_redirect; - u8 ip6_pbr_icmp_redirect; -}; - -/* An entry in the RTL93XX SoC's ROUTER_MAC tables setting up a termination point - * for the L3 routing system. Packets arriving and matching an entry in this table - * will be considered for routing. - * Mask fields state whether the corresponding data fields matter for matching - */ -struct rtl93xx_rt_mac { - bool valid; /* Valid or not */ - bool p_type; /* Individual (0) or trunk (1) port */ - bool p_mask; /* Whether the port type is used */ - u8 p_id; - u8 p_id_mask; /* Mask for the port */ - u8 action; /* Routing action performed: 0: FORWARD, 1: DROP, 2: TRAP2CPU */ - /* 3: COPY2CPU, 4: TRAP2MASTERCPU, 5: COPY2MASTERCPU, 6: HARDDROP */ - u16 vid; - u16 vid_mask; - u64 mac; /* MAC address used as source MAC in the routed packet */ - u64 mac_mask; -}; - -struct rtl83xx_nexthop { - u16 id; /* ID: L3_NEXT_HOP table-index or route-index set in L2_NEXT_HOP */ - u32 dev_id; - u16 port; - u16 vid; /* VLAN-ID for L2 table entry (saved from L2-UC entry) */ - u16 rvid; /* Relay VID/FID for the L2 table entry */ - u64 mac; /* The MAC address of the entry in the L2_NEXT_HOP table */ - u16 mac_id; - u16 l2_id; /* Index of this next hop forwarding entry in L2 FIB table */ - u64 gw; /* The gateway MAC address packets are forwarded to */ - int if_id; /* Interface (into L3_EGR_INTF_IDX) */ -}; - -struct rtl838x_switch_priv; - -struct rtl83xx_flow { - unsigned long cookie; - struct rhash_head node; - struct rcu_head rcu_head; - struct rtl838x_switch_priv *priv; - struct pie_rule rule; - u32 flags; -}; - -struct rtl93xx_route_attr { - bool valid; - bool hit; - bool ttl_dec; - bool ttl_check; - bool dst_null; - bool qos_as; - u8 qos_prio; - u8 type; - u8 action; -}; - -struct rtl83xx_route { - u32 gw_ip; /* IP of the route's gateway */ - u32 dst_ip; /* IP of the destination net */ - struct in6_addr dst_ip6; - int prefix_len; /* Network prefix len of the destination net */ - bool is_host_route; - int id; /* ID number of this route */ - struct rhlist_head linkage; - u16 switch_mac_id; /* Index into switch's own MACs, RTL839X only */ - struct rtl83xx_nexthop nh; - struct pie_rule pr; - struct rtl93xx_route_attr attr; -}; - -struct rtl838x_reg { - void (*mask_port_reg_be)(u64 clear, u64 set, int reg); - void (*set_port_reg_be)(u64 set, int reg); - u64 (*get_port_reg_be)(int reg); - void (*mask_port_reg_le)(u64 clear, u64 set, int reg); - void (*set_port_reg_le)(u64 set, int reg); - u64 (*get_port_reg_le)(int reg); - int stat_port_rst; - int stat_rst; - int stat_port_std_mib; - int (*port_iso_ctrl)(int p); - void (*traffic_enable)(int source, int dest); - void (*traffic_disable)(int source, int dest); - void (*traffic_set)(int source, u64 dest_matrix); - u64 (*traffic_get)(int source); - int l2_ctrl_0; - int l2_ctrl_1; - int smi_poll_ctrl; - u32 l2_port_aging_out; - int l2_tbl_flush_ctrl; - void (*exec_tbl0_cmd)(u32 cmd); - void (*exec_tbl1_cmd)(u32 cmd); - int (*tbl_access_data_0)(int i); - int isr_glb_src; - int isr_port_link_sts_chg; - int imr_port_link_sts_chg; - int imr_glb; - void (*vlan_tables_read)(u32 vlan, struct rtl838x_vlan_info *info); - void (*vlan_set_tagged)(u32 vlan, struct rtl838x_vlan_info *info); - void (*vlan_set_untagged)(u32 vlan, u64 portmask); - void (*vlan_profile_dump)(int index); - void (*vlan_profile_setup)(int profile); - void (*vlan_port_pvidmode_set)(int port, enum pbvlan_type type, enum pbvlan_mode mode); - void (*vlan_port_pvid_set)(int port, enum pbvlan_type type, int pvid); - void (*vlan_port_keep_tag_set)(int port, bool keep_outer, bool keep_inner); - void (*set_vlan_igr_filter)(int port, enum igr_filter state); - void (*set_vlan_egr_filter)(int port, enum egr_filter state); - void (*enable_learning)(int port, bool enable); - void (*enable_flood)(int port, bool enable); - void (*enable_mcast_flood)(int port, bool enable); - void (*enable_bcast_flood)(int port, bool enable); - void (*set_static_move_action)(int port, bool forward); - void (*stp_get)(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]); - void (*stp_set)(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]); - int (*mac_force_mode_ctrl)(int port); - int (*mac_port_ctrl)(int port); - int (*l2_port_new_salrn)(int port); - int (*l2_port_new_sa_fwd)(int port); - int (*set_ageing_time)(unsigned long msec); - int mir_ctrl; - int mir_dpm; - int mir_spm; - int mac_link_sts; - int mac_link_dup_sts; - int (*mac_link_spd_sts)(int port); - int mac_rx_pause_sts; - int mac_tx_pause_sts; - u64 (*read_l2_entry_using_hash)(u32 hash, u32 position, struct rtl838x_l2_entry *e); - void (*write_l2_entry_using_hash)(u32 hash, u32 pos, struct rtl838x_l2_entry *e); - u64 (*read_cam)(int idx, struct rtl838x_l2_entry *e); - void (*write_cam)(int idx, struct rtl838x_l2_entry *e); - int (*trk_mbr_ctr)(int group); - int rma_bpdu_fld_pmask; - int spcl_trap_eapol_ctrl; - void (*init_eee)(struct rtl838x_switch_priv *priv, bool enable); - void (*port_eee_set)(struct rtl838x_switch_priv *priv, int port, bool enable); - int (*eee_port_ability)(struct rtl838x_switch_priv *priv, - struct ethtool_eee *e, int port); - u64 (*l2_hash_seed)(u64 mac, u32 vid); - u32 (*l2_hash_key)(struct rtl838x_switch_priv *priv, u64 seed); - u64 (*read_mcast_pmask)(int idx); - void (*write_mcast_pmask)(int idx, u64 portmask); - void (*vlan_fwd_on_inner)(int port, bool is_set); - void (*pie_init)(struct rtl838x_switch_priv *priv); - int (*pie_rule_read)(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr); - int (*pie_rule_write)(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr); - int (*pie_rule_add)(struct rtl838x_switch_priv *priv, struct pie_rule *rule); - void (*pie_rule_rm)(struct rtl838x_switch_priv *priv, struct pie_rule *rule); - void (*l2_learning_setup)(void); - u32 (*packet_cntr_read)(int counter); - void (*packet_cntr_clear)(int counter); - void (*route_read)(int idx, struct rtl83xx_route *rt); - void (*route_write)(int idx, struct rtl83xx_route *rt); - void (*host_route_write)(int idx, struct rtl83xx_route *rt); - int (*l3_setup)(struct rtl838x_switch_priv *priv); - void (*set_l3_nexthop)(int idx, u16 dmac_id, u16 interface); - void (*get_l3_nexthop)(int idx, u16 *dmac_id, u16 *interface); - u64 (*get_l3_egress_mac)(u32 idx); - void (*set_l3_egress_mac)(u32 idx, u64 mac); - int (*find_l3_slot)(struct rtl83xx_route *rt, bool must_exist); - int (*route_lookup_hw)(struct rtl83xx_route *rt); - void (*get_l3_router_mac)(u32 idx, struct rtl93xx_rt_mac *m); - void (*set_l3_router_mac)(u32 idx, struct rtl93xx_rt_mac *m); - void (*set_l3_egress_intf)(int idx, struct rtl838x_l3_intf *intf); - void (*set_distribution_algorithm)(int group, int algoidx, u32 algomask); - void (*set_receive_management_action)(int port, rma_ctrl_t type, action_type_t action); - void (*led_init)(struct rtl838x_switch_priv *priv); -}; - -struct rtl838x_switch_priv { - /* Switch operation */ - struct dsa_switch *ds; - struct device *dev; - u16 id; - u16 family_id; - char version; - struct rtl838x_port ports[57]; - struct mutex reg_mutex; /* Mutex for individual register manipulations */ - struct mutex pie_mutex; /* Mutex for Packet Inspection Engine */ - int link_state_irq; - int mirror_group_ports[4]; - struct mii_bus *mii_bus; - const struct rtl838x_reg *r; - u8 cpu_port; - u8 port_mask; - u8 port_width; - u8 port_ignore; - u64 irq_mask; - u32 fib_entries; - int l2_bucket_size; - struct dentry *dbgfs_dir; - int n_lags; - u64 lags_port_members[MAX_LAGS]; - struct net_device *lag_devs[MAX_LAGS]; - u32 lag_primary[MAX_LAGS]; - u32 is_lagmember[57]; - u64 lagmembers; - struct notifier_block nb; /* TODO: change to different name */ - struct notifier_block ne_nb; - struct notifier_block fib_nb; - bool eee_enabled; - unsigned long int mc_group_bm[MAX_MC_GROUPS >> 5]; - int n_pie_blocks; - struct rhashtable tc_ht; - unsigned long int pie_use_bm[MAX_PIE_ENTRIES >> 5]; - int n_counters; - unsigned long int octet_cntr_use_bm[MAX_COUNTERS >> 5]; - unsigned long int packet_cntr_use_bm[MAX_COUNTERS >> 4]; - struct rhltable routes; - unsigned long int route_use_bm[MAX_ROUTES >> 5]; - unsigned long int host_route_use_bm[MAX_HOST_ROUTES >> 5]; - struct rtl838x_l3_intf *interfaces[MAX_INTERFACES]; - u16 intf_mtus[MAX_INTF_MTUS]; - int intf_mtu_count[MAX_INTF_MTUS]; -}; - -void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv); -void rtl930x_dbgfs_init(struct rtl838x_switch_priv *priv); - -#endif /* _RTL838X_H */ diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl839x.c deleted file mode 100644 index 5889cea6d66736..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl839x.c +++ /dev/null @@ -1,1911 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include - -#include "rtl83xx.h" - -#define RTL839X_VLAN_PORT_TAG_STS_UNTAG 0x0 -#define RTL839X_VLAN_PORT_TAG_STS_TAGGED 0x1 -#define RTL839X_VLAN_PORT_TAG_STS_PRIORITY_TAGGED 0x2 - -#define RTL839X_VLAN_PORT_TAG_STS_CTRL_BASE 0x6828 -/* port 0-52 */ -#define RTL839X_VLAN_PORT_TAG_STS_CTRL(port) \ - RTL839X_VLAN_PORT_TAG_STS_CTRL_BASE + (port << 2) -#define RTL839X_VLAN_PORT_TAG_STS_CTRL_OTAG_STS_MASK GENMASK(7,6) -#define RTL839X_VLAN_PORT_TAG_STS_CTRL_ITAG_STS_MASK GENMASK(5,4) -#define RTL839X_VLAN_PORT_TAG_STS_CTRL_EGR_P_OTAG_KEEP_MASK GENMASK(3,3) -#define RTL839X_VLAN_PORT_TAG_STS_CTRL_EGR_P_ITAG_KEEP_MASK GENMASK(2,2) -#define RTL839X_VLAN_PORT_TAG_STS_CTRL_IGR_P_OTAG_KEEP_MASK GENMASK(1,1) -#define RTL839X_VLAN_PORT_TAG_STS_CTRL_IGR_P_ITAG_KEEP_MASK GENMASK(0,0) - -extern struct mutex smi_lock; -extern struct rtl83xx_soc_info soc_info; - -/* Definition of the RTL839X-specific template field IDs as used in the PIE */ -enum template_field_id { - TEMPLATE_FIELD_SPMMASK = 0, - TEMPLATE_FIELD_SPM0 = 1, /* Source portmask ports 0-15 */ - TEMPLATE_FIELD_SPM1 = 2, /* Source portmask ports 16-31 */ - TEMPLATE_FIELD_SPM2 = 3, /* Source portmask ports 32-47 */ - TEMPLATE_FIELD_SPM3 = 4, /* Source portmask ports 48-56 */ - TEMPLATE_FIELD_DMAC0 = 5, /* Destination MAC [15:0] */ - TEMPLATE_FIELD_DMAC1 = 6, /* Destination MAC [31:16] */ - TEMPLATE_FIELD_DMAC2 = 7, /* Destination MAC [47:32] */ - TEMPLATE_FIELD_SMAC0 = 8, /* Source MAC [15:0] */ - TEMPLATE_FIELD_SMAC1 = 9, /* Source MAC [31:16] */ - TEMPLATE_FIELD_SMAC2 = 10, /* Source MAC [47:32] */ - TEMPLATE_FIELD_ETHERTYPE = 11, /* Ethernet frame type field */ - /* Field-ID 12 is not used */ - TEMPLATE_FIELD_OTAG = 13, - TEMPLATE_FIELD_ITAG = 14, - TEMPLATE_FIELD_SIP0 = 15, - TEMPLATE_FIELD_SIP1 = 16, - TEMPLATE_FIELD_DIP0 = 17, - TEMPLATE_FIELD_DIP1 = 18, - TEMPLATE_FIELD_IP_TOS_PROTO = 19, - TEMPLATE_FIELD_IP_FLAG = 20, - TEMPLATE_FIELD_L4_SPORT = 21, - TEMPLATE_FIELD_L4_DPORT = 22, - TEMPLATE_FIELD_L34_HEADER = 23, - TEMPLATE_FIELD_ICMP_IGMP = 24, - TEMPLATE_FIELD_VID_RANG0 = 25, - TEMPLATE_FIELD_VID_RANG1 = 26, - TEMPLATE_FIELD_L4_PORT_RANG = 27, - TEMPLATE_FIELD_FIELD_SELECTOR_VALID = 28, - TEMPLATE_FIELD_FIELD_SELECTOR_0 = 29, - TEMPLATE_FIELD_FIELD_SELECTOR_1 = 30, - TEMPLATE_FIELD_FIELD_SELECTOR_2 = 31, - TEMPLATE_FIELD_FIELD_SELECTOR_3 = 32, - TEMPLATE_FIELD_FIELD_SELECTOR_4 = 33, - TEMPLATE_FIELD_FIELD_SELECTOR_5 = 34, - TEMPLATE_FIELD_SIP2 = 35, - TEMPLATE_FIELD_SIP3 = 36, - TEMPLATE_FIELD_SIP4 = 37, - TEMPLATE_FIELD_SIP5 = 38, - TEMPLATE_FIELD_SIP6 = 39, - TEMPLATE_FIELD_SIP7 = 40, - TEMPLATE_FIELD_OLABEL = 41, - TEMPLATE_FIELD_ILABEL = 42, - TEMPLATE_FIELD_OILABEL = 43, - TEMPLATE_FIELD_DPMMASK = 44, - TEMPLATE_FIELD_DPM0 = 45, - TEMPLATE_FIELD_DPM1 = 46, - TEMPLATE_FIELD_DPM2 = 47, - TEMPLATE_FIELD_DPM3 = 48, - TEMPLATE_FIELD_L2DPM0 = 49, - TEMPLATE_FIELD_L2DPM1 = 50, - TEMPLATE_FIELD_L2DPM2 = 51, - TEMPLATE_FIELD_L2DPM3 = 52, - TEMPLATE_FIELD_IVLAN = 53, - TEMPLATE_FIELD_OVLAN = 54, - TEMPLATE_FIELD_FWD_VID = 55, - TEMPLATE_FIELD_DIP2 = 56, - TEMPLATE_FIELD_DIP3 = 57, - TEMPLATE_FIELD_DIP4 = 58, - TEMPLATE_FIELD_DIP5 = 59, - TEMPLATE_FIELD_DIP6 = 60, - TEMPLATE_FIELD_DIP7 = 61, -}; - -/* Number of fixed templates predefined in the SoC */ -#define N_FIXED_TEMPLATES 5 -static enum template_field_id fixed_templates[N_FIXED_TEMPLATES][N_FIXED_FIELDS] = -{ - { - TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1, TEMPLATE_FIELD_ITAG, - TEMPLATE_FIELD_SMAC0, TEMPLATE_FIELD_SMAC1, TEMPLATE_FIELD_SMAC2, - TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2, - TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3 - }, { - TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0, - TEMPLATE_FIELD_DIP1,TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_L4_SPORT, - TEMPLATE_FIELD_L4_DPORT, TEMPLATE_FIELD_ICMP_IGMP, TEMPLATE_FIELD_SPM0, - TEMPLATE_FIELD_SPM1, TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3 - }, { - TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2, - TEMPLATE_FIELD_ITAG, TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_IP_TOS_PROTO, - TEMPLATE_FIELD_L4_DPORT, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_SIP0, - TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0, TEMPLATE_FIELD_DIP1 - }, { - TEMPLATE_FIELD_DIP0, TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_DIP2, - TEMPLATE_FIELD_DIP3, TEMPLATE_FIELD_DIP4, TEMPLATE_FIELD_DIP5, - TEMPLATE_FIELD_DIP6, TEMPLATE_FIELD_DIP7, TEMPLATE_FIELD_L4_DPORT, - TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_ICMP_IGMP, TEMPLATE_FIELD_IP_TOS_PROTO - }, { - TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_SIP2, - TEMPLATE_FIELD_SIP3, TEMPLATE_FIELD_SIP4, TEMPLATE_FIELD_SIP5, - TEMPLATE_FIELD_SIP6, TEMPLATE_FIELD_SIP7, TEMPLATE_FIELD_SPM0, - TEMPLATE_FIELD_SPM1, TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3 - }, -}; - -void rtl839x_print_matrix(void) -{ - volatile u64 *ptr9; - - ptr9 = RTL838X_SW_BASE + RTL839X_PORT_ISO_CTRL(0); - for (int i = 0; i < 52; i += 4) - pr_debug("> %16llx %16llx %16llx %16llx\n", - ptr9[i + 0], ptr9[i + 1], ptr9[i + 2], ptr9[i + 3]); - pr_debug("CPU_PORT> %16llx\n", ptr9[52]); -} - -static inline int rtl839x_port_iso_ctrl(int p) -{ - return RTL839X_PORT_ISO_CTRL(p); -} - -static inline void rtl839x_exec_tbl0_cmd(u32 cmd) -{ - sw_w32(cmd, RTL839X_TBL_ACCESS_CTRL_0); - do { } while (sw_r32(RTL839X_TBL_ACCESS_CTRL_0) & BIT(16)); -} - -static inline void rtl839x_exec_tbl1_cmd(u32 cmd) -{ - sw_w32(cmd, RTL839X_TBL_ACCESS_CTRL_1); - do { } while (sw_r32(RTL839X_TBL_ACCESS_CTRL_1) & BIT(16)); -} - -inline void rtl839x_exec_tbl2_cmd(u32 cmd) -{ - sw_w32(cmd, RTL839X_TBL_ACCESS_CTRL_2); - do { } while (sw_r32(RTL839X_TBL_ACCESS_CTRL_2) & (1 << 9)); -} - -static inline int rtl839x_tbl_access_data_0(int i) -{ - return RTL839X_TBL_ACCESS_DATA_0(i); -} - -static void rtl839x_vlan_tables_read(u32 vlan, struct rtl838x_vlan_info *info) -{ - u32 u, v, w; - /* Read VLAN table (0) via register 0 */ - struct table_reg *r = rtl_table_get(RTL8390_TBL_0, 0); - - rtl_table_read(r, vlan); - u = sw_r32(rtl_table_data(r, 0)); - v = sw_r32(rtl_table_data(r, 1)); - w = sw_r32(rtl_table_data(r, 2)); - rtl_table_release(r); - - info->tagged_ports = u; - info->tagged_ports = (info->tagged_ports << 21) | ((v >> 11) & 0x1fffff); - info->profile_id = w >> 30 | ((v & 1) << 2); - info->hash_mc_fid = !!(w & BIT(2)); - info->hash_uc_fid = !!(w & BIT(3)); - info->fid = (v >> 3) & 0xff; - - /* Read UNTAG table (0) via table register 1 */ - r = rtl_table_get(RTL8390_TBL_1, 0); - rtl_table_read(r, vlan); - u = sw_r32(rtl_table_data(r, 0)); - v = sw_r32(rtl_table_data(r, 1)); - rtl_table_release(r); - - info->untagged_ports = u; - info->untagged_ports = (info->untagged_ports << 21) | ((v >> 11) & 0x1fffff); -} - -static void rtl839x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info) -{ - u32 u, v, w; - /* Access VLAN table (0) via register 0 */ - struct table_reg *r = rtl_table_get(RTL8390_TBL_0, 0); - - u = info->tagged_ports >> 21; - v = info->tagged_ports << 11; - v |= ((u32)info->fid) << 3; - v |= info->hash_uc_fid ? BIT(2) : 0; - v |= info->hash_mc_fid ? BIT(1) : 0; - v |= (info->profile_id & 0x4) ? 1 : 0; - w = ((u32)(info->profile_id & 3)) << 30; - - sw_w32(u, rtl_table_data(r, 0)); - sw_w32(v, rtl_table_data(r, 1)); - sw_w32(w, rtl_table_data(r, 2)); - - rtl_table_write(r, vlan); - rtl_table_release(r); -} - -static void rtl839x_vlan_set_untagged(u32 vlan, u64 portmask) -{ - u32 u, v; - - /* Access UNTAG table (0) via table register 1 */ - struct table_reg *r = rtl_table_get(RTL8390_TBL_1, 0); - - u = portmask >> 21; - v = portmask << 11; - - sw_w32(u, rtl_table_data(r, 0)); - sw_w32(v, rtl_table_data(r, 1)); - rtl_table_write(r, vlan); - - rtl_table_release(r); -} - -/* Sets the L2 forwarding to be based on either the inner VLAN tag or the outer */ -static void rtl839x_vlan_fwd_on_inner(int port, bool is_set) -{ - if (is_set) - rtl839x_mask_port_reg_be(BIT_ULL(port), 0ULL, RTL839X_VLAN_PORT_FWD); - else - rtl839x_mask_port_reg_be(0ULL, BIT_ULL(port), RTL839X_VLAN_PORT_FWD); -} - -/* Hash seed is vid (actually rvid) concatenated with the MAC address */ -static u64 rtl839x_l2_hash_seed(u64 mac, u32 vid) -{ - u64 v = vid; - - v <<= 48; - v |= mac; - - return v; -} - -/* Applies the same hash algorithm as the one used currently by the ASIC to the seed - * and returns a key into the L2 hash table - */ -static u32 rtl839x_l2_hash_key(struct rtl838x_switch_priv *priv, u64 seed) -{ - u32 h1, h2, h; - - if (sw_r32(priv->r->l2_ctrl_0) & 1) { - h1 = (u32) (((seed >> 60) & 0x3f) ^ ((seed >> 54) & 0x3f) ^ - ((seed >> 36) & 0x3f) ^ ((seed >> 30) & 0x3f) ^ - ((seed >> 12) & 0x3f) ^ ((seed >> 6) & 0x3f)); - h2 = (u32) (((seed >> 48) & 0x3f) ^ ((seed >> 42) & 0x3f) ^ - ((seed >> 24) & 0x3f) ^ ((seed >> 18) & 0x3f) ^ - (seed & 0x3f)); - h = (h1 << 6) | h2; - } else { - h = (seed >> 60) ^ - ((((seed >> 48) & 0x3f) << 6) | ((seed >> 54) & 0x3f)) ^ - ((seed >> 36) & 0xfff) ^ ((seed >> 24) & 0xfff) ^ - ((seed >> 12) & 0xfff) ^ (seed & 0xfff); - } - - return h; -} - -static inline int rtl839x_mac_force_mode_ctrl(int p) -{ - return RTL839X_MAC_FORCE_MODE_CTRL + (p << 2); -} - -static inline int rtl839x_mac_port_ctrl(int p) -{ - return RTL839X_MAC_PORT_CTRL(p); -} - -static inline int rtl839x_l2_port_new_salrn(int p) -{ - return RTL839X_L2_PORT_NEW_SALRN(p); -} - -static inline int rtl839x_l2_port_new_sa_fwd(int p) -{ - return RTL839X_L2_PORT_NEW_SA_FWD(p); -} - -static inline int rtl839x_mac_link_spd_sts(int p) -{ - return RTL839X_MAC_LINK_SPD_STS(p); -} - -static inline int rtl839x_trk_mbr_ctr(int group) -{ - return RTL839X_TRK_MBR_CTR + (group << 3); -} - -static void rtl839x_fill_l2_entry(u32 r[], struct rtl838x_l2_entry *e) -{ - /* Table contains different entry types, we need to identify the right one: - * Check for MC entries, first - */ - e->is_ip_mc = !!(r[2] & BIT(31)); - e->is_ipv6_mc = !!(r[2] & BIT(30)); - e->type = L2_INVALID; - if (!e->is_ip_mc && !e->is_ipv6_mc) { - e->mac[0] = (r[0] >> 12); - e->mac[1] = (r[0] >> 4); - e->mac[2] = ((r[1] >> 28) | (r[0] << 4)); - e->mac[3] = (r[1] >> 20); - e->mac[4] = (r[1] >> 12); - e->mac[5] = (r[1] >> 4); - - e->vid = (r[2] >> 4) & 0xfff; - e->rvid = (r[0] >> 20) & 0xfff; - - /* Is it a unicast entry? check multicast bit */ - if (!(e->mac[0] & 1)) { - e->is_static = !!((r[2] >> 18) & 1); - e->port = (r[2] >> 24) & 0x3f; - e->block_da = !!(r[2] & (1 << 19)); - e->block_sa = !!(r[2] & (1 << 20)); - e->suspended = !!(r[2] & (1 << 17)); - e->next_hop = !!(r[2] & (1 << 16)); - if (e->next_hop) { - pr_debug("Found next hop entry, need to read data\n"); - e->nh_vlan_target = !!(r[2] & BIT(15)); - e->nh_route_id = (r[2] >> 4) & 0x1ff; - e->vid = e->rvid; - } - e->age = (r[2] >> 21) & 3; - e->valid = true; - if (!(r[2] & 0xc0fd0000)) /* Check for valid entry */ - e->valid = false; - else - e->type = L2_UNICAST; - } else { - e->valid = true; - e->type = L2_MULTICAST; - e->mc_portmask_index = (r[2] >> 6) & 0xfff; - e->vid = e->rvid; - } - } else { /* IPv4 and IPv6 multicast */ - e->vid = e->rvid = (r[0] << 20) & 0xfff; - e->mc_gip = r[1]; - e->mc_portmask_index = (r[2] >> 6) & 0xfff; - } - if (e->is_ip_mc) { - e->valid = true; - e->type = IP4_MULTICAST; - } - if (e->is_ipv6_mc) { - e->valid = true; - e->type = IP6_MULTICAST; - } - /* pr_info("%s: vid %d, rvid: %d\n", __func__, e->vid, e->rvid); */ -} - -/* Fills the 3 SoC table registers r[] with the information in the rtl838x_l2_entry */ -static void rtl839x_fill_l2_row(u32 r[], struct rtl838x_l2_entry *e) -{ - if (!e->valid) { - r[0] = r[1] = r[2] = 0; - return; - } - - r[2] = e->is_ip_mc ? BIT(31) : 0; - r[2] |= e->is_ipv6_mc ? BIT(30) : 0; - - if (!e->is_ip_mc && !e->is_ipv6_mc) { - r[0] = ((u32)e->mac[0]) << 12; - r[0] |= ((u32)e->mac[1]) << 4; - r[0] |= ((u32)e->mac[2]) >> 4; - r[1] = ((u32)e->mac[2]) << 28; - r[1] |= ((u32)e->mac[3]) << 20; - r[1] |= ((u32)e->mac[4]) << 12; - r[1] |= ((u32)e->mac[5]) << 4; - - if (!(e->mac[0] & 1)) { /* Not multicast */ - r[2] |= e->is_static ? BIT(18) : 0; - r[0] |= ((u32)e->rvid) << 20; - r[2] |= e->port << 24; - r[2] |= e->block_da ? BIT(19) : 0; - r[2] |= e->block_sa ? BIT(20) : 0; - r[2] |= e->suspended ? BIT(17) : 0; - r[2] |= ((u32)e->age) << 21; - if (e->next_hop) { - r[2] |= BIT(16); - r[2] |= e->nh_vlan_target ? BIT(15) : 0; - r[2] |= (e->nh_route_id & 0x7ff) << 4; - } else { - r[2] |= e->vid << 4; - } - pr_debug("Write L2 NH: %08x %08x %08x\n", r[0], r[1], r[2]); - } else { /* L2 Multicast */ - r[0] |= ((u32)e->rvid) << 20; - r[2] |= ((u32)e->mc_portmask_index) << 6; - } - } else { /* IPv4 or IPv6 MC entry */ - r[0] = ((u32)e->rvid) << 20; - r[1] = e->mc_gip; - r[2] |= ((u32)e->mc_portmask_index) << 6; - } -} - -/* Read an L2 UC or MC entry out of a hash bucket of the L2 forwarding table - * hash is the id of the bucket and pos is the position of the entry in that bucket - * The data read from the SoC is filled into rtl838x_l2_entry - */ -static u64 rtl839x_read_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL8390_TBL_L2, 0); - u32 idx = (0 << 14) | (hash << 2) | pos; /* Search SRAM, with hash and at pos in bucket */ - - rtl_table_read(q, idx); - for (int i = 0; i < 3; i++) - r[i] = sw_r32(rtl_table_data(q, i)); - - rtl_table_release(q); - - rtl839x_fill_l2_entry(r, e); - if (!e->valid) - return 0; - - return rtl839x_l2_hash_seed(ether_addr_to_u64(&e->mac[0]), e->rvid); -} - -static void rtl839x_write_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL8390_TBL_L2, 0); - - u32 idx = (0 << 14) | (hash << 2) | pos; /* Access SRAM, with hash and at pos in bucket */ - - rtl839x_fill_l2_row(r, e); - - for (int i = 0; i < 3; i++) - sw_w32(r[i], rtl_table_data(q, i)); - - rtl_table_write(q, idx); - rtl_table_release(q); -} - -static u64 rtl839x_read_cam(int idx, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL8390_TBL_L2, 1); /* Access L2 Table 1 */ - - rtl_table_read(q, idx); - for (int i = 0; i < 3; i++) - r[i] = sw_r32(rtl_table_data(q, i)); - - rtl_table_release(q); - - rtl839x_fill_l2_entry(r, e); - if (!e->valid) - return 0; - - pr_debug("Found in CAM: R1 %x R2 %x R3 %x\n", r[0], r[1], r[2]); - - /* Return MAC with concatenated VID ac concatenated ID */ - return rtl839x_l2_hash_seed(ether_addr_to_u64(&e->mac[0]), e->rvid); -} - -static void rtl839x_write_cam(int idx, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL8390_TBL_L2, 1); /* Access L2 Table 1 */ - - rtl839x_fill_l2_row(r, e); - - for (int i = 0; i < 3; i++) - sw_w32(r[i], rtl_table_data(q, i)); - - rtl_table_write(q, idx); - rtl_table_release(q); -} - -static u64 rtl839x_read_mcast_pmask(int idx) -{ - u64 portmask; - /* Read MC_PMSK (2) via register RTL8390_TBL_L2 */ - struct table_reg *q = rtl_table_get(RTL8390_TBL_L2, 2); - - rtl_table_read(q, idx); - portmask = sw_r32(rtl_table_data(q, 0)); - portmask <<= 32; - portmask |= sw_r32(rtl_table_data(q, 1)); - portmask >>= 11; /* LSB is bit 11 in data registers */ - rtl_table_release(q); - - return portmask; -} - -static void rtl839x_write_mcast_pmask(int idx, u64 portmask) -{ - /* Access MC_PMSK (2) via register RTL8380_TBL_L2 */ - struct table_reg *q = rtl_table_get(RTL8390_TBL_L2, 2); - - portmask <<= 11; /* LSB is bit 11 in data registers */ - sw_w32((u32)(portmask >> 32), rtl_table_data(q, 0)); - sw_w32((u32)((portmask & 0xfffff800)), rtl_table_data(q, 1)); - rtl_table_write(q, idx); - rtl_table_release(q); -} - -static void rtl839x_vlan_profile_setup(int profile) -{ - u32 p[2]; - u32 pmask_id = UNKNOWN_MC_PMASK; - - p[0] = pmask_id; /* Use portmaks 0xfff for unknown IPv6 MC flooding */ - /* Enable L2 Learning BIT 0, portmask UNKNOWN_MC_PMASK for IP/L2-MC traffic flooding */ - p[1] = 1 | pmask_id << 1 | pmask_id << 13; - - sw_w32(p[0], RTL839X_VLAN_PROFILE(profile)); - sw_w32(p[1], RTL839X_VLAN_PROFILE(profile) + 4); - - rtl839x_write_mcast_pmask(UNKNOWN_MC_PMASK, 0x001fffffffffffff); -} - -u64 rtl839x_traffic_get(int source) -{ - return rtl839x_get_port_reg_be(rtl839x_port_iso_ctrl(source)); -} - -void rtl839x_traffic_set(int source, u64 dest_matrix) -{ - rtl839x_set_port_reg_be(dest_matrix, rtl839x_port_iso_ctrl(source)); -} - -void rtl839x_traffic_enable(int source, int dest) -{ - rtl839x_mask_port_reg_be(0, BIT_ULL(dest), rtl839x_port_iso_ctrl(source)); -} - -void rtl839x_traffic_disable(int source, int dest) -{ - rtl839x_mask_port_reg_be(BIT_ULL(dest), 0, rtl839x_port_iso_ctrl(source)); -} - -static void rtl839x_l2_learning_setup(void) -{ - /* Set portmask for broadcast (offset bit 12) and unknown unicast (offset 0) - * address flooding to the reserved entry in the portmask table used - * also for multicast flooding */ - sw_w32(UNKNOWN_MC_PMASK << 12 | UNKNOWN_MC_PMASK, RTL839X_L2_FLD_PMSK); - - /* Limit learning to maximum: 32k entries, after that just flood (bits 0-1) */ - sw_w32((0x7fff << 2) | 0, RTL839X_L2_LRN_CONSTRT); - - /* Do not trap ARP packets to CPU_PORT */ - sw_w32(0, RTL839X_SPCL_TRAP_ARP_CTRL); -} - -static void rtl839x_enable_learning(int port, bool enable) -{ - /* Limit learning to maximum: 32k entries */ - - sw_w32_mask(0x7fff << 2, enable ? (0x7fff << 2) : 0, - RTL839X_L2_PORT_LRN_CONSTRT + (port << 2)); -} - -static void rtl839x_enable_flood(int port, bool enable) -{ - /* 0: Forward - * 1: Disable - * 2: to CPU - * 3: Copy to CPU - */ - sw_w32_mask(0x3, enable ? 0 : 1, - RTL839X_L2_PORT_LRN_CONSTRT + (port << 2)); -} - -static void rtl839x_enable_mcast_flood(int port, bool enable) -{ - -} - -static void rtl839x_enable_bcast_flood(int port, bool enable) -{ - -} - -static void rtl839x_set_static_move_action(int port, bool forward) -{ - int shift = MV_ACT_PORT_SHIFT(port); - u32 val = forward ? MV_ACT_FORWARD : MV_ACT_DROP; - - sw_w32_mask(MV_ACT_MASK << shift, val << shift, - RTL839X_L2_PORT_STATIC_MV_ACT(port)); -} - -irqreturn_t rtl839x_switch_irq(int irq, void *dev_id) -{ - struct dsa_switch *ds = dev_id; - u32 status = sw_r32(RTL839X_ISR_GLB_SRC); - u64 ports = rtl839x_get_port_reg_le(RTL839X_ISR_PORT_LINK_STS_CHG); - u64 link; - - /* Clear status */ - rtl839x_set_port_reg_le(ports, RTL839X_ISR_PORT_LINK_STS_CHG); - pr_debug("RTL8390 Link change: status: %x, ports %llx\n", status, ports); - - for (int i = 0; i < RTL839X_CPU_PORT; i++) { - if (ports & BIT_ULL(i)) { - link = rtl839x_get_port_reg_le(RTL839X_MAC_LINK_STS); - if (link & BIT_ULL(i)) - dsa_port_phylink_mac_change(ds, i, true); - else - dsa_port_phylink_mac_change(ds, i, false); - } - } - - return IRQ_HANDLED; -} - -/* TODO: unused */ -int rtl8390_sds_power(int mac, int val) -{ - u32 offset = (mac == 48) ? 0x0 : 0x100; - u32 mode = val ? 0 : 1; - - pr_debug("In %s: mac %d, set %d\n", __func__, mac, val); - - if ((mac != 48) && (mac != 49)) { - pr_err("%s: not an SFP port: %d\n", __func__, mac); - return -1; - } - - /* Set bit 1003. 1000 starts at 7c */ - sw_w32_mask(BIT(11), mode << 11, RTL839X_SDS12_13_PWR0 + offset); - - return 0; -} - -static int rtl839x_smi_wait_op(int timeout) -{ - int ret = 0; - u32 val; - - ret = readx_poll_timeout(sw_r32, RTL839X_PHYREG_ACCESS_CTRL, - val, !(val & 0x1), 20, timeout); - if (ret) - pr_err("%s: timeout\n", __func__); - - return ret; -} - -int rtl839x_read_phy(u32 port, u32 page, u32 reg, u32 *val) -{ - u32 v; - int err = 0; - - if (port > 63 || page > 4095 || reg > 31) - return -ENOTSUPP; - - /* Take bug on RTL839x Rev <= C into account */ - if (port >= RTL839X_CPU_PORT) - return -EIO; - - mutex_lock(&smi_lock); - - sw_w32_mask(0xffff0000, port << 16, RTL839X_PHYREG_DATA_CTRL); - v = reg << 5 | page << 10 | ((page == 0x1fff) ? 0x1f : 0) << 23; - sw_w32(v, RTL839X_PHYREG_ACCESS_CTRL); - - sw_w32(0x1ff, RTL839X_PHYREG_CTRL); - - v |= 1; - sw_w32(v, RTL839X_PHYREG_ACCESS_CTRL); - - err = rtl839x_smi_wait_op(100000); - if (err) - goto errout; - - *val = sw_r32(RTL839X_PHYREG_DATA_CTRL) & 0xffff; - -errout: - mutex_unlock(&smi_lock); - - return err; -} - -int rtl839x_write_phy(u32 port, u32 page, u32 reg, u32 val) -{ - u32 v; - int err = 0; - - val &= 0xffff; - if (port > 63 || page > 4095 || reg > 31) - return -ENOTSUPP; - - /* Take bug on RTL839x Rev <= C into account */ - if (port >= RTL839X_CPU_PORT) - return -EIO; - - mutex_lock(&smi_lock); - - /* Set PHY to access */ - rtl839x_set_port_reg_le(BIT_ULL(port), RTL839X_PHYREG_PORT_CTRL); - - sw_w32_mask(0xffff0000, val << 16, RTL839X_PHYREG_DATA_CTRL); - - v = reg << 5 | page << 10 | ((page == 0x1fff) ? 0x1f : 0) << 23; - sw_w32(v, RTL839X_PHYREG_ACCESS_CTRL); - - sw_w32(0x1ff, RTL839X_PHYREG_CTRL); - - v |= BIT(3) | 1; /* Write operation and execute */ - sw_w32(v, RTL839X_PHYREG_ACCESS_CTRL); - - err = rtl839x_smi_wait_op(100000); - if (err) - goto errout; - - if (sw_r32(RTL839X_PHYREG_ACCESS_CTRL) & 0x2) - err = -EIO; - -errout: - mutex_unlock(&smi_lock); - - return err; -} - -/* Read an mmd register of the PHY */ -int rtl839x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val) -{ - int err = 0; - u32 v; - - /* Take bug on RTL839x Rev <= C into account */ - if (port >= RTL839X_CPU_PORT) - return -EIO; - - mutex_lock(&smi_lock); - - /* Set PHY to access */ - sw_w32_mask(0xffff << 16, port << 16, RTL839X_PHYREG_DATA_CTRL); - - /* Set MMD device number and register to write to */ - sw_w32(devnum << 16 | (regnum & 0xffff), RTL839X_PHYREG_MMD_CTRL); - - v = BIT(2) | BIT(0); /* MMD-access | EXEC */ - sw_w32(v, RTL839X_PHYREG_ACCESS_CTRL); - - err = rtl839x_smi_wait_op(100000); - if (err) - goto errout; - - /* There is no error-checking via BIT 1 of v, as it does not seem to be set correctly */ - *val = (sw_r32(RTL839X_PHYREG_DATA_CTRL) & 0xffff); - pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, *val, err); - -errout: - mutex_unlock(&smi_lock); - - return err; -} - -/* Write to an mmd register of the PHY */ -int rtl839x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val) -{ - int err = 0; - u32 v; - - /* Take bug on RTL839x Rev <= C into account */ - if (port >= RTL839X_CPU_PORT) - return -EIO; - - mutex_lock(&smi_lock); - - /* Set PHY to access */ - rtl839x_set_port_reg_le(BIT_ULL(port), RTL839X_PHYREG_PORT_CTRL); - - /* Set data to write */ - sw_w32_mask(0xffff << 16, val << 16, RTL839X_PHYREG_DATA_CTRL); - - /* Set MMD device number and register to write to */ - sw_w32(devnum << 16 | (regnum & 0xffff), RTL839X_PHYREG_MMD_CTRL); - - v = BIT(3) | BIT(2) | BIT(0); /* WRITE | MMD-access | EXEC */ - sw_w32(v, RTL839X_PHYREG_ACCESS_CTRL); - - err = rtl839x_smi_wait_op(100000); - if (err) - goto errout; - - pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, val, err); - -errout: - mutex_unlock(&smi_lock); - - return err; -} - -void rtl8390_get_version(struct rtl838x_switch_priv *priv) -{ - u32 info, model; - - sw_w32_mask(0xf << 28, 0xa << 28, RTL839X_CHIP_INFO); - info = sw_r32(RTL839X_CHIP_INFO); - - model = sw_r32(RTL839X_MODEL_NAME_INFO); - priv->version = RTL8390_VERSION_A + ((model & 0x3f) >> 1); - - pr_info("RTL839X Chip-Info: %x, version %c\n", info, priv->version); -} - -void rtl839x_vlan_profile_dump(int profile) -{ - u32 p[2]; - - if (profile < 0 || profile > 7) - return; - - p[0] = sw_r32(RTL839X_VLAN_PROFILE(profile)); - p[1] = sw_r32(RTL839X_VLAN_PROFILE(profile) + 4); - - pr_info("VLAN profile %d: L2 learning: %d, UNKN L2MC FLD PMSK %d, \ - UNKN IPMC FLD PMSK %d, UNKN IPv6MC FLD PMSK: %d", - profile, p[1] & 1, (p[1] >> 1) & 0xfff, (p[1] >> 13) & 0xfff, - (p[0]) & 0xfff); - pr_info("VLAN profile %d: raw %08x, %08x\n", profile, p[0], p[1]); -} - -static void rtl839x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]) -{ - u32 cmd = 1 << 16 | /* Execute cmd */ - 0 << 15 | /* Read */ - 5 << 12 | /* Table type 0b101 */ - (msti & 0xfff); - priv->r->exec_tbl0_cmd(cmd); - - for (int i = 0; i < 4; i++) - port_state[i] = sw_r32(priv->r->tbl_access_data_0(i)); -} - -static void rtl839x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]) -{ - u32 cmd = 1 << 16 | /* Execute cmd */ - 1 << 15 | /* Write */ - 5 << 12 | /* Table type 0b101 */ - (msti & 0xfff); - for (int i = 0; i < 4; i++) - sw_w32(port_state[i], priv->r->tbl_access_data_0(i)); - priv->r->exec_tbl0_cmd(cmd); -} - -/* Enables or disables the EEE/EEEP capability of a port */ -void rtl839x_port_eee_set(struct rtl838x_switch_priv *priv, int port, bool enable) -{ - u32 v; - - /* This works only for Ethernet ports, and on the RTL839X, ports above 47 are SFP */ - if (port >= 48) - return; - - enable = true; - pr_debug("In %s: setting port %d to %d\n", __func__, port, enable); - v = enable ? 0xf : 0x0; - - /* Set EEE for 100, 500, 1000MBit and 10GBit */ - sw_w32_mask(0xf << 8, v << 8, rtl839x_mac_force_mode_ctrl(port)); - - /* Set TX/RX EEE state */ - v = enable ? 0x3 : 0x0; - sw_w32(v, RTL839X_EEE_CTRL(port)); - - priv->ports[port].eee_enabled = enable; -} - -/* Get EEE own capabilities and negotiation result */ -int rtl839x_eee_port_ability(struct rtl838x_switch_priv *priv, struct ethtool_eee *e, int port) -{ - u64 link, a; - - if (port >= 48) - return 0; - - link = rtl839x_get_port_reg_le(RTL839X_MAC_LINK_STS); - if (!(link & BIT_ULL(port))) - return 0; - - if (sw_r32(rtl839x_mac_force_mode_ctrl(port)) & BIT(8)) - e->advertised |= ADVERTISED_100baseT_Full; - - if (sw_r32(rtl839x_mac_force_mode_ctrl(port)) & BIT(10)) - e->advertised |= ADVERTISED_1000baseT_Full; - - a = rtl839x_get_port_reg_le(RTL839X_MAC_EEE_ABLTY); - pr_info("Link partner: %016llx\n", a); - if (rtl839x_get_port_reg_le(RTL839X_MAC_EEE_ABLTY) & BIT_ULL(port)) { - e->lp_advertised = ADVERTISED_100baseT_Full; - e->lp_advertised |= ADVERTISED_1000baseT_Full; - return 1; - } - - return 0; -} - -static void rtl839x_init_eee(struct rtl838x_switch_priv *priv, bool enable) -{ - pr_info("Setting up EEE, state: %d\n", enable); - - /* Set wake timer for TX and pause timer both to 0x21 */ - sw_w32_mask(0xff << 20| 0xff, 0x21 << 20| 0x21, RTL839X_EEE_TX_TIMER_GELITE_CTRL); - /* Set pause wake timer for GIGA-EEE to 0x11 */ - sw_w32_mask(0xff << 20, 0x11 << 20, RTL839X_EEE_TX_TIMER_GIGA_CTRL); - /* Set pause wake timer for 10GBit ports to 0x11 */ - sw_w32_mask(0xff << 20, 0x11 << 20, RTL839X_EEE_TX_TIMER_10G_CTRL); - - /* Setup EEE on all ports */ - for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) - rtl839x_port_eee_set(priv, i, enable); - } - priv->eee_enabled = enable; -} - -static void rtl839x_pie_lookup_enable(struct rtl838x_switch_priv *priv, int index) -{ - int block = index / PIE_BLOCK_SIZE; - - sw_w32_mask(0, BIT(block), RTL839X_ACL_BLK_LOOKUP_CTRL); -} - -/* Delete a range of Packet Inspection Engine rules */ -static int rtl839x_pie_rule_del(struct rtl838x_switch_priv *priv, int index_from, int index_to) -{ - u32 v = (index_from << 1)| (index_to << 13 ) | BIT(0); - - pr_debug("%s: from %d to %d\n", __func__, index_from, index_to); - mutex_lock(&priv->reg_mutex); - - /* Write from-to and execute bit into control register */ - sw_w32(v, RTL839X_ACL_CLR_CTRL); - - /* Wait until command has completed */ - do { - } while (sw_r32(RTL839X_ACL_CLR_CTRL) & BIT(0)); - - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -/* Reads the intermediate representation of the templated match-fields of the - * PIE rule in the pie_rule structure and fills in the raw data fields in the - * raw register space r[]. - * The register space configuration size is identical for the RTL8380/90 and RTL9300, - * however the RTL9310 has 2 more registers / fields and the physical field-ids are different - * on all SoCs - * On the RTL8390 the template mask registers are not word-aligned! - */ -static void rtl839x_write_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[]) -{ - for (int i = 0; i < N_FIXED_FIELDS; i++) { - enum template_field_id field_type = t[i]; - u16 data = 0, data_m = 0; - - switch (field_type) { - case TEMPLATE_FIELD_SPM0: - data = pr->spm; - data_m = pr->spm_m; - break; - case TEMPLATE_FIELD_SPM1: - data = pr->spm >> 16; - data_m = pr->spm_m >> 16; - break; - case TEMPLATE_FIELD_SPM2: - data = pr->spm >> 32; - data_m = pr->spm_m >> 32; - break; - case TEMPLATE_FIELD_SPM3: - data = pr->spm >> 48; - data_m = pr->spm_m >> 48; - break; - case TEMPLATE_FIELD_OTAG: - data = pr->otag; - data_m = pr->otag_m; - break; - case TEMPLATE_FIELD_SMAC0: - data = pr->smac[4]; - data = (data << 8) | pr->smac[5]; - data_m = pr->smac_m[4]; - data_m = (data_m << 8) | pr->smac_m[5]; - break; - case TEMPLATE_FIELD_SMAC1: - data = pr->smac[2]; - data = (data << 8) | pr->smac[3]; - data_m = pr->smac_m[2]; - data_m = (data_m << 8) | pr->smac_m[3]; - break; - case TEMPLATE_FIELD_SMAC2: - data = pr->smac[0]; - data = (data << 8) | pr->smac[1]; - data_m = pr->smac_m[0]; - data_m = (data_m << 8) | pr->smac_m[1]; - break; - case TEMPLATE_FIELD_DMAC0: - data = pr->dmac[4]; - data = (data << 8) | pr->dmac[5]; - data_m = pr->dmac_m[4]; - data_m = (data_m << 8) | pr->dmac_m[5]; - break; - case TEMPLATE_FIELD_DMAC1: - data = pr->dmac[2]; - data = (data << 8) | pr->dmac[3]; - data_m = pr->dmac_m[2]; - data_m = (data_m << 8) | pr->dmac_m[3]; - break; - case TEMPLATE_FIELD_DMAC2: - data = pr->dmac[0]; - data = (data << 8) | pr->dmac[1]; - data_m = pr->dmac_m[0]; - data_m = (data_m << 8) | pr->dmac_m[1]; - break; - case TEMPLATE_FIELD_ETHERTYPE: - data = pr->ethertype; - data_m = pr->ethertype_m; - break; - case TEMPLATE_FIELD_ITAG: - data = pr->itag; - data_m = pr->itag_m; - break; - case TEMPLATE_FIELD_SIP0: - if (pr->is_ipv6) { - data = pr->sip6.s6_addr16[7]; - data_m = pr->sip6_m.s6_addr16[7]; - } else { - data = pr->sip; - data_m = pr->sip_m; - } - break; - case TEMPLATE_FIELD_SIP1: - if (pr->is_ipv6) { - data = pr->sip6.s6_addr16[6]; - data_m = pr->sip6_m.s6_addr16[6]; - } else { - data = pr->sip >> 16; - data_m = pr->sip_m >> 16; - } - break; - case TEMPLATE_FIELD_SIP2: - case TEMPLATE_FIELD_SIP3: - case TEMPLATE_FIELD_SIP4: - case TEMPLATE_FIELD_SIP5: - case TEMPLATE_FIELD_SIP6: - case TEMPLATE_FIELD_SIP7: - data = pr->sip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)]; - data_m = pr->sip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)]; - break; - case TEMPLATE_FIELD_DIP0: - if (pr->is_ipv6) { - data = pr->dip6.s6_addr16[7]; - data_m = pr->dip6_m.s6_addr16[7]; - } else { - data = pr->dip; - data_m = pr->dip_m; - } - break; - case TEMPLATE_FIELD_DIP1: - if (pr->is_ipv6) { - data = pr->dip6.s6_addr16[6]; - data_m = pr->dip6_m.s6_addr16[6]; - } else { - data = pr->dip >> 16; - data_m = pr->dip_m >> 16; - } - break; - case TEMPLATE_FIELD_DIP2: - case TEMPLATE_FIELD_DIP3: - case TEMPLATE_FIELD_DIP4: - case TEMPLATE_FIELD_DIP5: - case TEMPLATE_FIELD_DIP6: - case TEMPLATE_FIELD_DIP7: - data = pr->dip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)]; - data_m = pr->dip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)]; - break; - case TEMPLATE_FIELD_IP_TOS_PROTO: - data = pr->tos_proto; - data_m = pr->tos_proto_m; - break; - case TEMPLATE_FIELD_L4_SPORT: - data = pr->sport; - data_m = pr->sport_m; - break; - case TEMPLATE_FIELD_L4_DPORT: - data = pr->dport; - data_m = pr->dport_m; - break; - case TEMPLATE_FIELD_ICMP_IGMP: - data = pr->icmp_igmp; - data_m = pr->icmp_igmp_m; - break; - default: - pr_info("%s: unknown field %d\n", __func__, field_type); - } - - /* On the RTL8390, the mask fields are not word aligned! */ - if (!(i % 2)) { - r[5 - i / 2] = data; - r[12 - i / 2] |= ((u32)data_m << 8); - } else { - r[5 - i / 2] |= ((u32)data) << 16; - r[12 - i / 2] |= ((u32)data_m) << 24; - r[11 - i / 2] |= ((u32)data_m) >> 8; - } - } -} - -/* Creates the intermediate representation of the templated match-fields of the - * PIE rule in the pie_rule structure by reading the raw data fields in the - * raw register space r[]. - * The register space configuration size is identical for the RTL8380/90 and RTL9300, - * however the RTL9310 has 2 more registers / fields and the physical field-ids - * On the RTL8390 the template mask registers are not word-aligned! - */ -void rtl839x_read_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[]) -{ - for (int i = 0; i < N_FIXED_FIELDS; i++) { - enum template_field_id field_type = t[i]; - u16 data, data_m; - - if (!(i % 2)) { - data = r[5 - i / 2]; - data_m = r[12 - i / 2]; - } else { - data = r[5 - i / 2] >> 16; - data_m = r[12 - i / 2] >> 16; - } - - switch (field_type) { - case TEMPLATE_FIELD_SPM0: - pr->spm = (pr->spn << 16) | data; - pr->spm_m = (pr->spn << 16) | data_m; - break; - case TEMPLATE_FIELD_SPM1: - pr->spm = data; - pr->spm_m = data_m; - break; - case TEMPLATE_FIELD_OTAG: - pr->otag = data; - pr->otag_m = data_m; - break; - case TEMPLATE_FIELD_SMAC0: - pr->smac[4] = data >> 8; - pr->smac[5] = data; - pr->smac_m[4] = data >> 8; - pr->smac_m[5] = data; - break; - case TEMPLATE_FIELD_SMAC1: - pr->smac[2] = data >> 8; - pr->smac[3] = data; - pr->smac_m[2] = data >> 8; - pr->smac_m[3] = data; - break; - case TEMPLATE_FIELD_SMAC2: - pr->smac[0] = data >> 8; - pr->smac[1] = data; - pr->smac_m[0] = data >> 8; - pr->smac_m[1] = data; - break; - case TEMPLATE_FIELD_DMAC0: - pr->dmac[4] = data >> 8; - pr->dmac[5] = data; - pr->dmac_m[4] = data >> 8; - pr->dmac_m[5] = data; - break; - case TEMPLATE_FIELD_DMAC1: - pr->dmac[2] = data >> 8; - pr->dmac[3] = data; - pr->dmac_m[2] = data >> 8; - pr->dmac_m[3] = data; - break; - case TEMPLATE_FIELD_DMAC2: - pr->dmac[0] = data >> 8; - pr->dmac[1] = data; - pr->dmac_m[0] = data >> 8; - pr->dmac_m[1] = data; - break; - case TEMPLATE_FIELD_ETHERTYPE: - pr->ethertype = data; - pr->ethertype_m = data_m; - break; - case TEMPLATE_FIELD_ITAG: - pr->itag = data; - pr->itag_m = data_m; - break; - case TEMPLATE_FIELD_SIP0: - pr->sip = data; - pr->sip_m = data_m; - break; - case TEMPLATE_FIELD_SIP1: - pr->sip = (pr->sip << 16) | data; - pr->sip_m = (pr->sip << 16) | data_m; - break; - case TEMPLATE_FIELD_SIP2: - pr->is_ipv6 = true; - /* Make use of limitiations on the position of the match values */ - ipv6_addr_set(&pr->sip6, pr->sip, r[5 - i / 2], - r[4 - i / 2], r[3 - i / 2]); - ipv6_addr_set(&pr->sip6_m, pr->sip_m, r[5 - i / 2], - r[4 - i / 2], r[3 - i / 2]); - case TEMPLATE_FIELD_SIP3: - case TEMPLATE_FIELD_SIP4: - case TEMPLATE_FIELD_SIP5: - case TEMPLATE_FIELD_SIP6: - case TEMPLATE_FIELD_SIP7: - break; - - case TEMPLATE_FIELD_DIP0: - pr->dip = data; - pr->dip_m = data_m; - break; - - case TEMPLATE_FIELD_DIP1: - pr->dip = (pr->dip << 16) | data; - pr->dip_m = (pr->dip << 16) | data_m; - break; - - case TEMPLATE_FIELD_DIP2: - pr->is_ipv6 = true; - ipv6_addr_set(&pr->dip6, pr->dip, r[5 - i / 2], - r[4 - i / 2], r[3 - i / 2]); - ipv6_addr_set(&pr->dip6_m, pr->dip_m, r[5 - i / 2], - r[4 - i / 2], r[3 - i / 2]); - case TEMPLATE_FIELD_DIP3: - case TEMPLATE_FIELD_DIP4: - case TEMPLATE_FIELD_DIP5: - case TEMPLATE_FIELD_DIP6: - case TEMPLATE_FIELD_DIP7: - break; - case TEMPLATE_FIELD_IP_TOS_PROTO: - pr->tos_proto = data; - pr->tos_proto_m = data_m; - break; - case TEMPLATE_FIELD_L4_SPORT: - pr->sport = data; - pr->sport_m = data_m; - break; - case TEMPLATE_FIELD_L4_DPORT: - pr->dport = data; - pr->dport_m = data_m; - break; - case TEMPLATE_FIELD_ICMP_IGMP: - pr->icmp_igmp = data; - pr->icmp_igmp_m = data_m; - break; - default: - pr_info("%s: unknown field %d\n", __func__, field_type); - } - } -} - -static void rtl839x_read_pie_fixed_fields(u32 r[], struct pie_rule *pr) -{ - pr->spmmask_fix = (r[6] >> 30) & 0x3; - pr->spn = (r[6] >> 24) & 0x3f; - pr->mgnt_vlan = (r[6] >> 23) & 1; - pr->dmac_hit_sw = (r[6] >> 22) & 1; - pr->not_first_frag = (r[6] >> 21) & 1; - pr->frame_type_l4 = (r[6] >> 18) & 7; - pr->frame_type = (r[6] >> 16) & 3; - pr->otag_fmt = (r[6] >> 15) & 1; - pr->itag_fmt = (r[6] >> 14) & 1; - pr->otag_exist = (r[6] >> 13) & 1; - pr->itag_exist = (r[6] >> 12) & 1; - pr->frame_type_l2 = (r[6] >> 10) & 3; - pr->tid = (r[6] >> 8) & 3; - - pr->spmmask_fix_m = (r[12] >> 6) & 0x3; - pr->spn_m = r[12] & 0x3f; - pr->mgnt_vlan_m = (r[13] >> 31) & 1; - pr->dmac_hit_sw_m = (r[13] >> 30) & 1; - pr->not_first_frag_m = (r[13] >> 29) & 1; - pr->frame_type_l4_m = (r[13] >> 26) & 7; - pr->frame_type_m = (r[13] >> 24) & 3; - pr->otag_fmt_m = (r[13] >> 23) & 1; - pr->itag_fmt_m = (r[13] >> 22) & 1; - pr->otag_exist_m = (r[13] >> 21) & 1; - pr->itag_exist_m = (r[13] >> 20) & 1; - pr->frame_type_l2_m = (r[13] >> 18) & 3; - pr->tid_m = (r[13] >> 16) & 3; - - pr->valid = r[13] & BIT(15); - pr->cond_not = r[13] & BIT(14); - pr->cond_and1 = r[13] & BIT(13); - pr->cond_and2 = r[13] & BIT(12); -} - -static void rtl839x_write_pie_fixed_fields(u32 r[], struct pie_rule *pr) -{ - r[6] = ((u32) (pr->spmmask_fix & 0x3)) << 30; - r[6] |= ((u32) (pr->spn & 0x3f)) << 24; - r[6] |= pr->mgnt_vlan ? BIT(23) : 0; - r[6] |= pr->dmac_hit_sw ? BIT(22) : 0; - r[6] |= pr->not_first_frag ? BIT(21) : 0; - r[6] |= ((u32) (pr->frame_type_l4 & 0x7)) << 18; - r[6] |= ((u32) (pr->frame_type & 0x3)) << 16; - r[6] |= pr->otag_fmt ? BIT(15) : 0; - r[6] |= pr->itag_fmt ? BIT(14) : 0; - r[6] |= pr->otag_exist ? BIT(13) : 0; - r[6] |= pr->itag_exist ? BIT(12) : 0; - r[6] |= ((u32) (pr->frame_type_l2 & 0x3)) << 10; - r[6] |= ((u32) (pr->tid & 0x3)) << 8; - - r[12] |= ((u32) (pr->spmmask_fix_m & 0x3)) << 6; - r[12] |= (u32) (pr->spn_m & 0x3f); - r[13] |= pr->mgnt_vlan_m ? BIT(31) : 0; - r[13] |= pr->dmac_hit_sw_m ? BIT(30) : 0; - r[13] |= pr->not_first_frag_m ? BIT(29) : 0; - r[13] |= ((u32) (pr->frame_type_l4_m & 0x7)) << 26; - r[13] |= ((u32) (pr->frame_type_m & 0x3)) << 24; - r[13] |= pr->otag_fmt_m ? BIT(23) : 0; - r[13] |= pr->itag_fmt_m ? BIT(22) : 0; - r[13] |= pr->otag_exist_m ? BIT(21) : 0; - r[13] |= pr->itag_exist_m ? BIT(20) : 0; - r[13] |= ((u32) (pr->frame_type_l2_m & 0x3)) << 18; - r[13] |= ((u32) (pr->tid_m & 0x3)) << 16; - - r[13] |= pr->valid ? BIT(15) : 0; - r[13] |= pr->cond_not ? BIT(14) : 0; - r[13] |= pr->cond_and1 ? BIT(13) : 0; - r[13] |= pr->cond_and2 ? BIT(12) : 0; -} - -static void rtl839x_write_pie_action(u32 r[], struct pie_rule *pr) -{ - if (pr->drop) { - r[13] |= 0x9; /* Set ACT_MASK_FWD & FWD_ACT = DROP */ - r[13] |= BIT(3); - } else { - r[13] |= pr->fwd_sel ? BIT(3) : 0; - r[13] |= pr->fwd_act; - } - r[13] |= pr->bypass_sel ? BIT(11) : 0; - r[13] |= pr->mpls_sel ? BIT(10) : 0; - r[13] |= pr->nopri_sel ? BIT(9) : 0; - r[13] |= pr->ovid_sel ? BIT(8) : 0; - r[13] |= pr->ivid_sel ? BIT(7) : 0; - r[13] |= pr->meter_sel ? BIT(6) : 0; - r[13] |= pr->mir_sel ? BIT(5) : 0; - r[13] |= pr->log_sel ? BIT(4) : 0; - - r[14] |= ((u32)(pr->fwd_data & 0x3fff)) << 18; - r[14] |= pr->log_octets ? BIT(17) : 0; - r[14] |= ((u32)(pr->log_data & 0x7ff)) << 4; - r[14] |= (pr->mir_data & 0x3) << 3; - r[14] |= ((u32)(pr->meter_data >> 7)) & 0x7; - r[15] |= (u32)(pr->meter_data) << 26; - r[15] |= ((u32)(pr->ivid_act) << 23) & 0x3; - r[15] |= ((u32)(pr->ivid_data) << 9) & 0xfff; - r[15] |= ((u32)(pr->ovid_act) << 6) & 0x3; - r[15] |= ((u32)(pr->ovid_data) >> 4) & 0xff; - r[16] |= ((u32)(pr->ovid_data) & 0xf) << 28; - r[16] |= ((u32)(pr->nopri_data) & 0x7) << 20; - r[16] |= ((u32)(pr->mpls_act) & 0x7) << 20; - r[16] |= ((u32)(pr->mpls_lib_idx) & 0x7) << 20; - r[16] |= pr->bypass_all ? BIT(9) : 0; - r[16] |= pr->bypass_igr_stp ? BIT(8) : 0; - r[16] |= pr->bypass_ibc_sc ? BIT(7) : 0; -} - -static void rtl839x_read_pie_action(u32 r[], struct pie_rule *pr) -{ - if (r[13] & BIT(3)) { /* ACT_MASK_FWD set, is it a drop? */ - if ((r[14] & 0x7) == 1) { - pr->drop = true; - } else { - pr->fwd_sel = true; - pr->fwd_act = r[14] & 0x7; - } - } - - pr->bypass_sel = r[13] & BIT(11); - pr->mpls_sel = r[13] & BIT(10); - pr->nopri_sel = r[13] & BIT(9); - pr->ovid_sel = r[13] & BIT(8); - pr->ivid_sel = r[13] & BIT(7); - pr->meter_sel = r[13] & BIT(6); - pr->mir_sel = r[13] & BIT(5); - pr->log_sel = r[13] & BIT(4); - - /* TODO: Read in data fields */ - - pr->bypass_all = r[16] & BIT(9); - pr->bypass_igr_stp = r[16] & BIT(8); - pr->bypass_ibc_sc = r[16] & BIT(7); -} - -void rtl839x_pie_rule_dump_raw(u32 r[]) -{ - pr_info("Raw IACL table entry:\n"); - pr_info("Match : %08x %08x %08x %08x %08x %08x\n", r[0], r[1], r[2], r[3], r[4], r[5]); - pr_info("Fixed : %06x\n", r[6] >> 8); - pr_info("Match M: %08x %08x %08x %08x %08x %08x\n", - (r[6] << 24) | (r[7] >> 8), (r[7] << 24) | (r[8] >> 8), (r[8] << 24) | (r[9] >> 8), - (r[9] << 24) | (r[10] >> 8), (r[10] << 24) | (r[11] >> 8), - (r[11] << 24) | (r[12] >> 8)); - pr_info("R[13]: %08x\n", r[13]); - pr_info("Fixed M: %06x\n", ((r[12] << 16) | (r[13] >> 16)) & 0xffffff); - pr_info("Valid / not / and1 / and2 : %1x\n", (r[13] >> 12) & 0xf); - pr_info("r 13-16: %08x %08x %08x %08x\n", r[13], r[14], r[15], r[16]); -} - -void rtl839x_pie_rule_dump(struct pie_rule *pr) -{ - pr_info("Drop: %d, fwd: %d, ovid: %d, ivid: %d, flt: %d, log: %d, rmk: %d, meter: %d tagst: %d, mir: %d, nopri: %d, cpupri: %d, otpid: %d, itpid: %d, shape: %d\n", - pr->drop, pr->fwd_sel, pr->ovid_sel, pr->ivid_sel, pr->flt_sel, pr->log_sel, pr->rmk_sel, pr->log_sel, pr->tagst_sel, pr->mir_sel, pr->nopri_sel, - pr->cpupri_sel, pr->otpid_sel, pr->itpid_sel, pr->shaper_sel); - if (pr->fwd_sel) - pr_info("FWD: %08x\n", pr->fwd_data); - pr_info("TID: %x, %x\n", pr->tid, pr->tid_m); -} - -static int rtl839x_pie_rule_read(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr) -{ - /* Read IACL table (2) via register 0 */ - struct table_reg *q = rtl_table_get(RTL8380_TBL_0, 2); - u32 r[17]; - int block = idx / PIE_BLOCK_SIZE; - u32 t_select = sw_r32(RTL839X_ACL_BLK_TMPLTE_CTRL(block)); - - memset(pr, 0, sizeof(*pr)); - rtl_table_read(q, idx); - for (int i = 0; i < 17; i++) - r[i] = sw_r32(rtl_table_data(q, i)); - - rtl_table_release(q); - - rtl839x_read_pie_fixed_fields(r, pr); - if (!pr->valid) - return 0; - - pr_debug("%s: template_selectors %08x, tid: %d\n", __func__, t_select, pr->tid); - rtl839x_pie_rule_dump_raw(r); - - rtl839x_read_pie_templated(r, pr, fixed_templates[(t_select >> (pr->tid * 3)) & 0x7]); - - rtl839x_read_pie_action(r, pr); - - return 0; -} - -static int rtl839x_pie_rule_write(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr) -{ - /* Access IACL table (2) via register 0 */ - struct table_reg *q = rtl_table_get(RTL8390_TBL_0, 2); - u32 r[17]; - int block = idx / PIE_BLOCK_SIZE; - u32 t_select = sw_r32(RTL839X_ACL_BLK_TMPLTE_CTRL(block)); - - pr_debug("%s: %d, t_select: %08x\n", __func__, idx, t_select); - - for (int i = 0; i < 17; i++) - r[i] = 0; - - if (!pr->valid) { - rtl_table_write(q, idx); - rtl_table_release(q); - return 0; - } - rtl839x_write_pie_fixed_fields(r, pr); - - pr_debug("%s: template %d\n", __func__, (t_select >> (pr->tid * 3)) & 0x7); - rtl839x_write_pie_templated(r, pr, fixed_templates[(t_select >> (pr->tid * 3)) & 0x7]); - - rtl839x_write_pie_action(r, pr); - -/* rtl839x_pie_rule_dump_raw(r); */ - - for (int i = 0; i < 17; i++) - sw_w32(r[i], rtl_table_data(q, i)); - - rtl_table_write(q, idx); - rtl_table_release(q); - - return 0; -} - -static bool rtl839x_pie_templ_has(int t, enum template_field_id field_type) -{ - for (int i = 0; i < N_FIXED_FIELDS; i++) { - enum template_field_id ft = fixed_templates[t][i]; - if (field_type == ft) - return true; - } - - return false; -} - -static int rtl839x_pie_verify_template(struct rtl838x_switch_priv *priv, - struct pie_rule *pr, int t, int block) -{ - int i; - - if (!pr->is_ipv6 && pr->sip_m && !rtl839x_pie_templ_has(t, TEMPLATE_FIELD_SIP0)) - return -1; - - if (!pr->is_ipv6 && pr->dip_m && !rtl839x_pie_templ_has(t, TEMPLATE_FIELD_DIP0)) - return -1; - - if (pr->is_ipv6) { - if ((pr->sip6_m.s6_addr32[0] || - pr->sip6_m.s6_addr32[1] || - pr->sip6_m.s6_addr32[2] || - pr->sip6_m.s6_addr32[3]) && - !rtl839x_pie_templ_has(t, TEMPLATE_FIELD_SIP2)) - return -1; - if ((pr->dip6_m.s6_addr32[0] || - pr->dip6_m.s6_addr32[1] || - pr->dip6_m.s6_addr32[2] || - pr->dip6_m.s6_addr32[3]) && - !rtl839x_pie_templ_has(t, TEMPLATE_FIELD_DIP2)) - return -1; - } - - if (ether_addr_to_u64(pr->smac) && !rtl839x_pie_templ_has(t, TEMPLATE_FIELD_SMAC0)) - return -1; - - if (ether_addr_to_u64(pr->dmac) && !rtl839x_pie_templ_has(t, TEMPLATE_FIELD_DMAC0)) - return -1; - - /* TODO: Check more */ - - i = find_first_zero_bit(&priv->pie_use_bm[block * 4], PIE_BLOCK_SIZE); - - if (i >= PIE_BLOCK_SIZE) - return -1; - - return i + PIE_BLOCK_SIZE * block; -} - -static int rtl839x_pie_rule_add(struct rtl838x_switch_priv *priv, struct pie_rule *pr) -{ - int idx, block, j, t; - int min_block = 0; - int max_block = priv->n_pie_blocks / 2; - - if (pr->is_egress) { - min_block = max_block; - max_block = priv->n_pie_blocks; - } - - mutex_lock(&priv->pie_mutex); - - for (block = min_block; block < max_block; block++) { - for (j = 0; j < 2; j++) { - t = (sw_r32(RTL839X_ACL_BLK_TMPLTE_CTRL(block)) >> (j * 3)) & 0x7; - idx = rtl839x_pie_verify_template(priv, pr, t, block); - if (idx >= 0) - break; - } - if (j < 2) - break; - } - - if (block >= priv->n_pie_blocks) { - mutex_unlock(&priv->pie_mutex); - return -EOPNOTSUPP; - } - - set_bit(idx, priv->pie_use_bm); - - pr->valid = true; - pr->tid = j; /* Mapped to template number */ - pr->tid_m = 0x3; - pr->id = idx; - - rtl839x_pie_lookup_enable(priv, idx); - rtl839x_pie_rule_write(priv, idx, pr); - - mutex_unlock(&priv->pie_mutex); - - return 0; -} - -static void rtl839x_pie_rule_rm(struct rtl838x_switch_priv *priv, struct pie_rule *pr) -{ - int idx = pr->id; - - rtl839x_pie_rule_del(priv, idx, idx); - clear_bit(idx, priv->pie_use_bm); -} - -static void rtl839x_pie_init(struct rtl838x_switch_priv *priv) -{ - u32 template_selectors; - - mutex_init(&priv->pie_mutex); - - /* Power on all PIE blocks */ - for (int i = 0; i < priv->n_pie_blocks; i++) - sw_w32_mask(0, BIT(i), RTL839X_PS_ACL_PWR_CTRL); - - /* Set ingress and egress ACL blocks to 50/50: first Egress block is 9 */ - sw_w32_mask(0x1f, 9, RTL839X_ACL_CTRL); /* Writes 9 to cutline field */ - - /* Include IPG in metering */ - sw_w32(1, RTL839X_METER_GLB_CTRL); - - /* Delete all present rules */ - rtl839x_pie_rule_del(priv, 0, priv->n_pie_blocks * PIE_BLOCK_SIZE - 1); - - /* Enable predefined templates 0, 1 for blocks 0-2 */ - template_selectors = 0 | (1 << 3); - for (int i = 0; i < 3; i++) - sw_w32(template_selectors, RTL839X_ACL_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 2, 3 for blocks 3-5 */ - template_selectors = 2 | (3 << 3); - for (int i = 3; i < 6; i++) - sw_w32(template_selectors, RTL839X_ACL_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 1, 4 for blocks 6-8 */ - template_selectors = 2 | (3 << 3); - for (int i = 6; i < 9; i++) - sw_w32(template_selectors, RTL839X_ACL_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 0, 1 for blocks 9-11 */ - template_selectors = 0 | (1 << 3); - for (int i = 9; i < 12; i++) - sw_w32(template_selectors, RTL839X_ACL_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 2, 3 for blocks 12-14 */ - template_selectors = 2 | (3 << 3); - for (int i = 12; i < 15; i++) - sw_w32(template_selectors, RTL839X_ACL_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 1, 4 for blocks 15-17 */ - template_selectors = 2 | (3 << 3); - for (int i = 15; i < 18; i++) - sw_w32(template_selectors, RTL839X_ACL_BLK_TMPLTE_CTRL(i)); -} - -static u32 rtl839x_packet_cntr_read(int counter) -{ - u32 v; - - /* Read LOG table (4) via register RTL8390_TBL_0 */ - struct table_reg *r = rtl_table_get(RTL8390_TBL_0, 4); - - pr_debug("In %s, id %d\n", __func__, counter); - rtl_table_read(r, counter / 2); - - /* The table has a size of 2 registers */ - if (counter % 2) - v = sw_r32(rtl_table_data(r, 0)); - else - v = sw_r32(rtl_table_data(r, 1)); - - rtl_table_release(r); - - return v; -} - -static void rtl839x_packet_cntr_clear(int counter) -{ - /* Access LOG table (4) via register RTL8390_TBL_0 */ - struct table_reg *r = rtl_table_get(RTL8390_TBL_0, 4); - - pr_debug("In %s, id %d\n", __func__, counter); - /* The table has a size of 2 registers */ - if (counter % 2) - sw_w32(0, rtl_table_data(r, 0)); - else - sw_w32(0, rtl_table_data(r, 1)); - - rtl_table_write(r, counter / 2); - - rtl_table_release(r); -} - -static void rtl839x_route_read(int idx, struct rtl83xx_route *rt) -{ - u64 v; - /* Read ROUTING table (2) via register RTL8390_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL8390_TBL_1, 2); - - pr_debug("In %s\n", __func__); - rtl_table_read(r, idx); - - /* The table has a size of 2 registers */ - v = sw_r32(rtl_table_data(r, 0)); - v <<= 32; - v |= sw_r32(rtl_table_data(r, 1)); - rt->switch_mac_id = (v >> 12) & 0xf; - rt->nh.gw = v >> 16; - - rtl_table_release(r); -} - -static void rtl839x_route_write(int idx, struct rtl83xx_route *rt) -{ - u32 v; - - /* Read ROUTING table (2) via register RTL8390_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL8390_TBL_1, 2); - - pr_debug("In %s\n", __func__); - sw_w32(rt->nh.gw >> 16, rtl_table_data(r, 0)); - v = rt->nh.gw << 16; - v |= rt->switch_mac_id << 12; - sw_w32(v, rtl_table_data(r, 1)); - rtl_table_write(r, idx); - - rtl_table_release(r); -} - -/* Configure the switch's own MAC addresses used when routing packets */ -static void rtl839x_setup_port_macs(struct rtl838x_switch_priv *priv) -{ - struct net_device *dev; - u64 mac; - - pr_debug("%s: got port %08x\n", __func__, (u32)priv->ports[priv->cpu_port].dp); - dev = priv->ports[priv->cpu_port].dp->slave; - mac = ether_addr_to_u64(dev->dev_addr); - - for (int i = 0; i < 15; i++) { - mac++; /* BUG: VRRP for testing */ - sw_w32(mac >> 32, RTL839X_ROUTING_SA_CTRL + i * 8); - sw_w32(mac, RTL839X_ROUTING_SA_CTRL + i * 8 + 4); - } -} - -int rtl839x_l3_setup(struct rtl838x_switch_priv *priv) -{ - rtl839x_setup_port_macs(priv); - - return 0; -} - -void rtl839x_vlan_port_keep_tag_set(int port, bool keep_outer, bool keep_inner) -{ - sw_w32(FIELD_PREP(RTL839X_VLAN_PORT_TAG_STS_CTRL_OTAG_STS_MASK, - keep_outer ? RTL839X_VLAN_PORT_TAG_STS_TAGGED : RTL839X_VLAN_PORT_TAG_STS_UNTAG) | - FIELD_PREP(RTL839X_VLAN_PORT_TAG_STS_CTRL_ITAG_STS_MASK, - keep_inner ? RTL839X_VLAN_PORT_TAG_STS_TAGGED : RTL839X_VLAN_PORT_TAG_STS_UNTAG), - RTL839X_VLAN_PORT_TAG_STS_CTRL(port)); -} - -void rtl839x_vlan_port_pvidmode_set(int port, enum pbvlan_type type, enum pbvlan_mode mode) -{ - if (type == PBVLAN_TYPE_INNER) - sw_w32_mask(0x3, mode, RTL839X_VLAN_PORT_PB_VLAN + (port << 2)); - else - sw_w32_mask(0x3 << 14, mode << 14, RTL839X_VLAN_PORT_PB_VLAN + (port << 2)); -} - -void rtl839x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid) -{ - if (type == PBVLAN_TYPE_INNER) - sw_w32_mask(0xfff << 2, pvid << 2, RTL839X_VLAN_PORT_PB_VLAN + (port << 2)); - else - sw_w32_mask(0xfff << 16, pvid << 16, RTL839X_VLAN_PORT_PB_VLAN + (port << 2)); -} - -static int rtl839x_set_ageing_time(unsigned long msec) -{ - int t = sw_r32(RTL839X_L2_CTRL_1); - - t &= 0x1FFFFF; - t = t * 3 / 5; /* Aging time in seconds. 0: L2 aging disabled */ - pr_debug("L2 AGING time: %d sec\n", t); - - t = (msec * 5 + 2000) / 3000; - t = t > 0x1FFFFF ? 0x1FFFFF : t; - sw_w32_mask(0x1FFFFF, t, RTL839X_L2_CTRL_1); - pr_debug("Dynamic aging for ports: %x\n", sw_r32(RTL839X_L2_PORT_AGING_OUT)); - - return 0; -} - -static void rtl839x_set_igr_filter(int port, enum igr_filter state) -{ - sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1), - RTL839X_VLAN_PORT_IGR_FLTR + (((port >> 4) << 2))); -} - -static void rtl839x_set_egr_filter(int port, enum egr_filter state) -{ - sw_w32_mask(0x1 << (port % 0x20), state << (port % 0x20), - RTL839X_VLAN_PORT_EGR_FLTR + (((port >> 5) << 2))); -} - -void rtl839x_set_distribution_algorithm(int group, int algoidx, u32 algomsk) -{ - sw_w32_mask(3 << ((group & 0xf) << 1), algoidx << ((group & 0xf) << 1), - RTL839X_TRK_HASH_IDX_CTRL + ((group >> 4) << 2)); - sw_w32(algomsk, RTL839X_TRK_HASH_CTRL + (algoidx << 2)); -} - -void rtl839x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action) -{ - switch(type) { - case BPDU: - sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1), - RTL839X_RMA_BPDU_CTRL + ((port >> 4) << 2)); - break; - case PTP: - sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1), - RTL839X_RMA_PTP_CTRL + ((port >> 4) << 2)); - break; - case LLDP: - sw_w32_mask(3 << ((port & 0xf) << 1), (action & 0x3) << ((port & 0xf) << 1), - RTL839X_RMA_LLDP_CTRL + ((port >> 4) << 2)); - break; - default: - break; - } -} - -const struct rtl838x_reg rtl839x_reg = { - .mask_port_reg_be = rtl839x_mask_port_reg_be, - .set_port_reg_be = rtl839x_set_port_reg_be, - .get_port_reg_be = rtl839x_get_port_reg_be, - .mask_port_reg_le = rtl839x_mask_port_reg_le, - .set_port_reg_le = rtl839x_set_port_reg_le, - .get_port_reg_le = rtl839x_get_port_reg_le, - .stat_port_rst = RTL839X_STAT_PORT_RST, - .stat_rst = RTL839X_STAT_RST, - .stat_port_std_mib = RTL839X_STAT_PORT_STD_MIB, - .traffic_enable = rtl839x_traffic_enable, - .traffic_disable = rtl839x_traffic_disable, - .traffic_get = rtl839x_traffic_get, - .traffic_set = rtl839x_traffic_set, - .port_iso_ctrl = rtl839x_port_iso_ctrl, - .l2_ctrl_0 = RTL839X_L2_CTRL_0, - .l2_ctrl_1 = RTL839X_L2_CTRL_1, - .l2_port_aging_out = RTL839X_L2_PORT_AGING_OUT, - .set_ageing_time = rtl839x_set_ageing_time, - .smi_poll_ctrl = RTL839X_SMI_PORT_POLLING_CTRL, - .l2_tbl_flush_ctrl = RTL839X_L2_TBL_FLUSH_CTRL, - .exec_tbl0_cmd = rtl839x_exec_tbl0_cmd, - .exec_tbl1_cmd = rtl839x_exec_tbl1_cmd, - .tbl_access_data_0 = rtl839x_tbl_access_data_0, - .isr_glb_src = RTL839X_ISR_GLB_SRC, - .isr_port_link_sts_chg = RTL839X_ISR_PORT_LINK_STS_CHG, - .imr_port_link_sts_chg = RTL839X_IMR_PORT_LINK_STS_CHG, - .imr_glb = RTL839X_IMR_GLB, - .vlan_tables_read = rtl839x_vlan_tables_read, - .vlan_set_tagged = rtl839x_vlan_set_tagged, - .vlan_set_untagged = rtl839x_vlan_set_untagged, - .vlan_profile_dump = rtl839x_vlan_profile_dump, - .vlan_profile_setup = rtl839x_vlan_profile_setup, - .vlan_fwd_on_inner = rtl839x_vlan_fwd_on_inner, - .vlan_port_keep_tag_set = rtl839x_vlan_port_keep_tag_set, - .vlan_port_pvidmode_set = rtl839x_vlan_port_pvidmode_set, - .vlan_port_pvid_set = rtl839x_vlan_port_pvid_set, - .set_vlan_igr_filter = rtl839x_set_igr_filter, - .set_vlan_egr_filter = rtl839x_set_egr_filter, - .enable_learning = rtl839x_enable_learning, - .enable_flood = rtl839x_enable_flood, - .enable_mcast_flood = rtl839x_enable_mcast_flood, - .enable_bcast_flood = rtl839x_enable_bcast_flood, - .set_static_move_action = rtl839x_set_static_move_action, - .stp_get = rtl839x_stp_get, - .stp_set = rtl839x_stp_set, - .mac_force_mode_ctrl = rtl839x_mac_force_mode_ctrl, - .mac_port_ctrl = rtl839x_mac_port_ctrl, - .l2_port_new_salrn = rtl839x_l2_port_new_salrn, - .l2_port_new_sa_fwd = rtl839x_l2_port_new_sa_fwd, - .mir_ctrl = RTL839X_MIR_CTRL, - .mir_dpm = RTL839X_MIR_DPM_CTRL, - .mir_spm = RTL839X_MIR_SPM_CTRL, - .mac_link_sts = RTL839X_MAC_LINK_STS, - .mac_link_dup_sts = RTL839X_MAC_LINK_DUP_STS, - .mac_link_spd_sts = rtl839x_mac_link_spd_sts, - .mac_rx_pause_sts = RTL839X_MAC_RX_PAUSE_STS, - .mac_tx_pause_sts = RTL839X_MAC_TX_PAUSE_STS, - .read_l2_entry_using_hash = rtl839x_read_l2_entry_using_hash, - .write_l2_entry_using_hash = rtl839x_write_l2_entry_using_hash, - .read_cam = rtl839x_read_cam, - .write_cam = rtl839x_write_cam, - .trk_mbr_ctr = rtl839x_trk_mbr_ctr, - .rma_bpdu_fld_pmask = RTL839X_RMA_BPDU_FLD_PMSK, - .spcl_trap_eapol_ctrl = RTL839X_SPCL_TRAP_EAPOL_CTRL, - .init_eee = rtl839x_init_eee, - .port_eee_set = rtl839x_port_eee_set, - .eee_port_ability = rtl839x_eee_port_ability, - .l2_hash_seed = rtl839x_l2_hash_seed, - .l2_hash_key = rtl839x_l2_hash_key, - .read_mcast_pmask = rtl839x_read_mcast_pmask, - .write_mcast_pmask = rtl839x_write_mcast_pmask, - .pie_init = rtl839x_pie_init, - .pie_rule_read = rtl839x_pie_rule_read, - .pie_rule_write = rtl839x_pie_rule_write, - .pie_rule_add = rtl839x_pie_rule_add, - .pie_rule_rm = rtl839x_pie_rule_rm, - .l2_learning_setup = rtl839x_l2_learning_setup, - .packet_cntr_read = rtl839x_packet_cntr_read, - .packet_cntr_clear = rtl839x_packet_cntr_clear, - .route_read = rtl839x_route_read, - .route_write = rtl839x_route_write, - .l3_setup = rtl839x_l3_setup, - .set_distribution_algorithm = rtl839x_set_distribution_algorithm, - .set_receive_management_action = rtl839x_set_receive_management_action, -}; diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h deleted file mode 100644 index 55a6851d4630d8..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl83xx.h +++ /dev/null @@ -1,136 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _NET_DSA_RTL83XX_H -#define _NET_DSA_RTL83XX_H - -#include -#include "rtl838x.h" - - -#define RTL8380_VERSION_A 'A' -#define RTL8390_VERSION_A 'A' -#define RTL8380_VERSION_B 'B' - -struct fdb_update_work { - struct work_struct work; - struct net_device *ndev; - u64 macs[]; -}; - -#define MIB_DESC(_size, _offset, _name) {.size = _size, .offset = _offset, .name = _name} -struct rtl83xx_mib_desc { - unsigned int size; - unsigned int offset; - const char *name; -}; - -/* API for switch table access */ -struct table_reg { - u16 addr; - u16 data; - u8 max_data; - u8 c_bit; - u8 t_bit; - u8 rmode; - u8 tbl; - struct mutex lock; -}; - -#define TBL_DESC(_addr, _data, _max_data, _c_bit, _t_bit, _rmode) \ - { .addr = _addr, .data = _data, .max_data = _max_data, .c_bit = _c_bit, \ - .t_bit = _t_bit, .rmode = _rmode \ - } - -typedef enum { - RTL8380_TBL_L2 = 0, - RTL8380_TBL_0, - RTL8380_TBL_1, - RTL8390_TBL_L2, - RTL8390_TBL_0, - RTL8390_TBL_1, - RTL8390_TBL_2, - RTL9300_TBL_L2, - RTL9300_TBL_0, - RTL9300_TBL_1, - RTL9300_TBL_2, - RTL9300_TBL_HSB, - RTL9300_TBL_HSA, - RTL9310_TBL_0, - RTL9310_TBL_1, - RTL9310_TBL_2, - RTL9310_TBL_3, - RTL9310_TBL_4, - RTL9310_TBL_5, - RTL_TBL_END -} rtl838x_tbl_reg_t; - -void rtl_table_init(void); -struct table_reg *rtl_table_get(rtl838x_tbl_reg_t r, int t); -void rtl_table_release(struct table_reg *r); -int rtl_table_read(struct table_reg *r, int idx); -int rtl_table_write(struct table_reg *r, int idx); -inline u16 rtl_table_data(struct table_reg *r, int i); -inline u32 rtl_table_data_r(struct table_reg *r, int i); -inline void rtl_table_data_w(struct table_reg *r, u32 v, int i); - -void __init rtl83xx_setup_qos(struct rtl838x_switch_priv *priv); - -int rtl83xx_packet_cntr_alloc(struct rtl838x_switch_priv *priv); - -int rtl83xx_port_is_under(const struct net_device * dev, struct rtl838x_switch_priv *priv); - -int read_phy(u32 port, u32 page, u32 reg, u32 *val); -int write_phy(u32 port, u32 page, u32 reg, u32 val); - -/* Port register accessor functions for the RTL839x and RTL931X SoCs */ -void rtl839x_mask_port_reg_be(u64 clear, u64 set, int reg); -u64 rtl839x_get_port_reg_be(int reg); -void rtl839x_set_port_reg_be(u64 set, int reg); -void rtl839x_mask_port_reg_le(u64 clear, u64 set, int reg); -void rtl839x_set_port_reg_le(u64 set, int reg); -u64 rtl839x_get_port_reg_le(int reg); - -/* Port register accessor functions for the RTL838x and RTL930X SoCs */ -void rtl838x_mask_port_reg(u64 clear, u64 set, int reg); -void rtl838x_set_port_reg(u64 set, int reg); -u64 rtl838x_get_port_reg(int reg); - -/* RTL838x-specific */ -u32 rtl838x_hash(struct rtl838x_switch_priv *priv, u64 seed); -irqreturn_t rtl838x_switch_irq(int irq, void *dev_id); -void rtl8380_get_version(struct rtl838x_switch_priv *priv); -void rtl838x_vlan_profile_dump(int index); -int rtl83xx_dsa_phy_read(struct dsa_switch *ds, int phy_addr, int phy_reg); -void rtl8380_sds_rst(int mac); -int rtl8380_sds_power(int mac, int val); -void rtl838x_print_matrix(void); - -/* RTL839x-specific */ -u32 rtl839x_hash(struct rtl838x_switch_priv *priv, u64 seed); -irqreturn_t rtl839x_switch_irq(int irq, void *dev_id); -void rtl8390_get_version(struct rtl838x_switch_priv *priv); -void rtl839x_vlan_profile_dump(int index); -int rtl83xx_dsa_phy_write(struct dsa_switch *ds, int phy_addr, int phy_reg, u16 val); -void rtl839x_exec_tbl2_cmd(u32 cmd); -void rtl839x_print_matrix(void); - -/* RTL930x-specific */ -u32 rtl930x_hash(struct rtl838x_switch_priv *priv, u64 seed); -irqreturn_t rtl930x_switch_irq(int irq, void *dev_id); -irqreturn_t rtl839x_switch_irq(int irq, void *dev_id); -void rtl930x_vlan_profile_dump(int index); -int rtl9300_sds_power(int mac, int val); -void rtl9300_sds_rst(int sds_num, u32 mode); -int rtl9300_serdes_setup(int port, int sds_num, phy_interface_t phy_mode); -void rtl930x_print_matrix(void); - -/* RTL931x-specific */ -irqreturn_t rtl931x_switch_irq(int irq, void *dev_id); -int rtl931x_sds_cmu_band_get(int sds, phy_interface_t mode); -int rtl931x_sds_cmu_band_set(int sds, bool enable, u32 band, phy_interface_t mode); -void rtl931x_sds_init(u32 sds, phy_interface_t mode); - -int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_lag_upper_info *info); -int rtl83xx_lag_del(struct dsa_switch *ds, int group, int port); - -#endif /* _NET_DSA_RTL83XX_H */ diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl930x.c deleted file mode 100644 index 793d7624897db0..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl930x.c +++ /dev/null @@ -1,2568 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include - -#include "rtl83xx.h" - -#define RTL930X_VLAN_PORT_TAG_STS_INTERNAL 0x0 -#define RTL930X_VLAN_PORT_TAG_STS_UNTAG 0x1 -#define RTL930X_VLAN_PORT_TAG_STS_TAGGED 0x2 -#define RTL930X_VLAN_PORT_TAG_STS_PRIORITY_TAGGED 0x3 - -#define RTL930X_VLAN_PORT_TAG_STS_CTRL_BASE 0xCE24 -/* port 0-28 */ -#define RTL930X_VLAN_PORT_TAG_STS_CTRL(port) \ - RTL930X_VLAN_PORT_TAG_STS_CTRL_BASE + (port << 2) -#define RTL930X_VLAN_PORT_TAG_STS_CTRL_EGR_OTAG_STS_MASK GENMASK(7,6) -#define RTL930X_VLAN_PORT_TAG_STS_CTRL_EGR_ITAG_STS_MASK GENMASK(5,4) -#define RTL930X_VLAN_PORT_TAG_STS_CTRL_EGR_P_OTAG_KEEP_MASK GENMASK(3,3) -#define RTL930X_VLAN_PORT_TAG_STS_CTRL_EGR_P_ITAG_KEEP_MASK GENMASK(2,2) -#define RTL930X_VLAN_PORT_TAG_STS_CTRL_IGR_P_OTAG_KEEP_MASK GENMASK(1,1) -#define RTL930X_VLAN_PORT_TAG_STS_CTRL_IGR_P_ITAG_KEEP_MASK GENMASK(0,0) - -#define RTL930X_LED_GLB_ACTIVE_LOW BIT(22) - -#define RTL930X_LED_SETX_0_CTRL(x) (RTL930X_LED_SET0_0_CTRL - (x * 8)) -#define RTL930X_LED_SETX_1_CTRL(x) (RTL930X_LED_SETX_0_CTRL(x) - 4) - -/* get register for given set and led in the set */ -#define RTL930X_LED_SETX_LEDY(x,y) (RTL930X_LED_SETX_0_CTRL(x) - 4 * (y / 2)) - -/* get shift for given led in any set */ -#define RTL930X_LED_SET_LEDX_SHIFT(x) (16 * (x % 2)) - -extern struct mutex smi_lock; -extern struct rtl83xx_soc_info soc_info; - -/* Definition of the RTL930X-specific template field IDs as used in the PIE */ -enum template_field_id { - TEMPLATE_FIELD_SPM0 = 0, /* Source portmask ports 0-15 */ - TEMPLATE_FIELD_SPM1 = 1, /* Source portmask ports 16-31 */ - TEMPLATE_FIELD_DMAC0 = 2, /* Destination MAC [15:0] */ - TEMPLATE_FIELD_DMAC1 = 3, /* Destination MAC [31:16] */ - TEMPLATE_FIELD_DMAC2 = 4, /* Destination MAC [47:32] */ - TEMPLATE_FIELD_SMAC0 = 5, /* Source MAC [15:0] */ - TEMPLATE_FIELD_SMAC1 = 6, /* Source MAC [31:16] */ - TEMPLATE_FIELD_SMAC2 = 7, /* Source MAC [47:32] */ - TEMPLATE_FIELD_ETHERTYPE = 8, /* Ethernet frame type field */ - TEMPLATE_FIELD_OTAG = 9, - TEMPLATE_FIELD_ITAG = 10, - TEMPLATE_FIELD_SIP0 = 11, - TEMPLATE_FIELD_SIP1 = 12, - TEMPLATE_FIELD_DIP0 = 13, - TEMPLATE_FIELD_DIP1 = 14, - TEMPLATE_FIELD_IP_TOS_PROTO = 15, - TEMPLATE_FIELD_L4_SPORT = 16, - TEMPLATE_FIELD_L4_DPORT = 17, - TEMPLATE_FIELD_L34_HEADER = 18, - TEMPLATE_FIELD_TCP_INFO = 19, - TEMPLATE_FIELD_FIELD_SELECTOR_VALID = 20, - TEMPLATE_FIELD_FIELD_SELECTOR_0 = 21, - TEMPLATE_FIELD_FIELD_SELECTOR_1 = 22, - TEMPLATE_FIELD_FIELD_SELECTOR_2 = 23, - TEMPLATE_FIELD_FIELD_SELECTOR_3 = 24, - TEMPLATE_FIELD_FIELD_SELECTOR_4 = 25, - TEMPLATE_FIELD_FIELD_SELECTOR_5 = 26, - TEMPLATE_FIELD_SIP2 = 27, - TEMPLATE_FIELD_SIP3 = 28, - TEMPLATE_FIELD_SIP4 = 29, - TEMPLATE_FIELD_SIP5 = 30, - TEMPLATE_FIELD_SIP6 = 31, - TEMPLATE_FIELD_SIP7 = 32, - TEMPLATE_FIELD_DIP2 = 33, - TEMPLATE_FIELD_DIP3 = 34, - TEMPLATE_FIELD_DIP4 = 35, - TEMPLATE_FIELD_DIP5 = 36, - TEMPLATE_FIELD_DIP6 = 37, - TEMPLATE_FIELD_DIP7 = 38, - TEMPLATE_FIELD_PKT_INFO = 39, - TEMPLATE_FIELD_FLOW_LABEL = 40, - TEMPLATE_FIELD_DSAP_SSAP = 41, - TEMPLATE_FIELD_SNAP_OUI = 42, - TEMPLATE_FIELD_FWD_VID = 43, - TEMPLATE_FIELD_RANGE_CHK = 44, - TEMPLATE_FIELD_VLAN_GMSK = 45, /* VLAN Group Mask/IP range check */ - TEMPLATE_FIELD_DLP = 46, - TEMPLATE_FIELD_META_DATA = 47, - TEMPLATE_FIELD_SRC_FWD_VID = 48, - TEMPLATE_FIELD_SLP = 49, -}; - -/* The meaning of TEMPLATE_FIELD_VLAN depends on phase and the configuration in - * RTL930X_PIE_CTRL. We use always the same definition and map to the inner VLAN tag: - */ -#define TEMPLATE_FIELD_VLAN TEMPLATE_FIELD_ITAG - -/* Number of fixed templates predefined in the RTL9300 SoC */ -#define N_FIXED_TEMPLATES 5 -/* RTL9300 specific predefined templates */ -static enum template_field_id fixed_templates[N_FIXED_TEMPLATES][N_FIXED_FIELDS] = -{ - { - TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2, - TEMPLATE_FIELD_SMAC0, TEMPLATE_FIELD_SMAC1, TEMPLATE_FIELD_SMAC2, - TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_DSAP_SSAP, - TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1 - }, { - TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0, - TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_TCP_INFO, - TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT, TEMPLATE_FIELD_VLAN, - TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1 - }, { - TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2, - TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_IP_TOS_PROTO, - TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0, - TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT - }, { - TEMPLATE_FIELD_DIP0, TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_DIP2, - TEMPLATE_FIELD_DIP3, TEMPLATE_FIELD_DIP4, TEMPLATE_FIELD_DIP5, - TEMPLATE_FIELD_DIP6, TEMPLATE_FIELD_DIP7, TEMPLATE_FIELD_IP_TOS_PROTO, - TEMPLATE_FIELD_TCP_INFO, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT - }, { - TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_SIP2, - TEMPLATE_FIELD_SIP3, TEMPLATE_FIELD_SIP4, TEMPLATE_FIELD_SIP5, - TEMPLATE_FIELD_SIP6, TEMPLATE_FIELD_SIP7, TEMPLATE_FIELD_VLAN, - TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SPM1, TEMPLATE_FIELD_SPM1 - }, -}; - -void rtl930x_print_matrix(void) -{ - struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6); - - for (int i = 0; i < 29; i++) { - rtl_table_read(r, i); - pr_debug("> %08x\n", sw_r32(rtl_table_data(r, 0))); - } - rtl_table_release(r); -} - -inline void rtl930x_exec_tbl0_cmd(u32 cmd) -{ - sw_w32(cmd, RTL930X_TBL_ACCESS_CTRL_0); - do { } while (sw_r32(RTL930X_TBL_ACCESS_CTRL_0) & (1 << 17)); -} - -inline void rtl930x_exec_tbl1_cmd(u32 cmd) -{ - sw_w32(cmd, RTL930X_TBL_ACCESS_CTRL_1); - do { } while (sw_r32(RTL930X_TBL_ACCESS_CTRL_1) & (1 << 17)); -} - -inline int rtl930x_tbl_access_data_0(int i) -{ - return RTL930X_TBL_ACCESS_DATA_0(i); -} - -static inline int rtl930x_l2_port_new_salrn(int p) -{ - return RTL930X_L2_PORT_SALRN(p); -} - -static inline int rtl930x_l2_port_new_sa_fwd(int p) -{ - /* TODO: The definition of the fields changed, because of the master-cpu in a stack */ - return RTL930X_L2_PORT_NEW_SA_FWD(p); -} - -inline static int rtl930x_trk_mbr_ctr(int group) -{ - return RTL930X_TRK_MBR_CTRL + (group << 2); -} - -static void rtl930x_vlan_tables_read(u32 vlan, struct rtl838x_vlan_info *info) -{ - u32 v, w; - /* Read VLAN table (1) via register 0 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 1); - - rtl_table_read(r, vlan); - v = sw_r32(rtl_table_data(r, 0)); - w = sw_r32(rtl_table_data(r, 1)); - pr_debug("VLAN_READ %d: %08x %08x\n", vlan, v, w); - rtl_table_release(r); - - info->tagged_ports = v >> 3; - info->profile_id = (w >> 24) & 7; - info->hash_mc_fid = !!(w & BIT(27)); - info->hash_uc_fid = !!(w & BIT(28)); - info->fid = ((v & 0x7) << 3) | ((w >> 29) & 0x7); - - /* Read UNTAG table via table register 2 */ - r = rtl_table_get(RTL9300_TBL_2, 0); - rtl_table_read(r, vlan); - v = sw_r32(rtl_table_data(r, 0)); - rtl_table_release(r); - - info->untagged_ports = v >> 3; -} - -static void rtl930x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info) -{ - u32 v, w; - /* Access VLAN table (1) via register 0 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 1); - - v = info->tagged_ports << 3; - v |= ((u32)info->fid) >> 3; - - w = ((u32)info->fid) << 29; - w |= info->hash_mc_fid ? BIT(27) : 0; - w |= info->hash_uc_fid ? BIT(28) : 0; - w |= info->profile_id << 24; - - sw_w32(v, rtl_table_data(r, 0)); - sw_w32(w, rtl_table_data(r, 1)); - - rtl_table_write(r, vlan); - rtl_table_release(r); -} - -void rtl930x_vlan_profile_dump(int profile) -{ - u32 p[5]; - - if (profile < 0 || profile > 7) - return; - - p[0] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile)); - p[1] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 4); - p[2] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 8) & 0x1FFFFFFF; - p[3] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 12) & 0x1FFFFFFF; - p[4] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 16) & 0x1FFFFFFF; - - pr_info("VLAN %d: L2 learn: %d; Unknown MC PMasks: L2 %0x, IPv4 %0x, IPv6: %0x", - profile, p[0] & (3 << 21), p[2], p[3], p[4]); - pr_info(" Routing enabled: IPv4 UC %c, IPv6 UC %c, IPv4 MC %c, IPv6 MC %c\n", - p[0] & BIT(17) ? 'y' : 'n', p[0] & BIT(16) ? 'y' : 'n', - p[0] & BIT(13) ? 'y' : 'n', p[0] & BIT(12) ? 'y' : 'n'); - pr_info(" Bridge enabled: IPv4 MC %c, IPv6 MC %c,\n", - p[0] & BIT(15) ? 'y' : 'n', p[0] & BIT(14) ? 'y' : 'n'); - pr_info("VLAN profile %d: raw %08x %08x %08x %08x %08x\n", - profile, p[0], p[1], p[2], p[3], p[4]); -} - -static void rtl930x_vlan_set_untagged(u32 vlan, u64 portmask) -{ - struct table_reg *r = rtl_table_get(RTL9300_TBL_2, 0); - - sw_w32(portmask << 3, rtl_table_data(r, 0)); - rtl_table_write(r, vlan); - rtl_table_release(r); -} - -/* Sets the L2 forwarding to be based on either the inner VLAN tag or the outer */ -static void rtl930x_vlan_fwd_on_inner(int port, bool is_set) -{ - /* Always set all tag modes to fwd based on either inner or outer tag */ - if (is_set) - sw_w32_mask(0xf, 0, RTL930X_VLAN_PORT_FWD + (port << 2)); - else - sw_w32_mask(0, 0xf, RTL930X_VLAN_PORT_FWD + (port << 2)); -} - -static void rtl930x_vlan_profile_setup(int profile) -{ - u32 p[5]; - - pr_info("In %s\n", __func__); - p[0] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile)); - p[1] = sw_r32(RTL930X_VLAN_PROFILE_SET(profile) + 4); - - /* Enable routing of Ipv4/6 Unicast and IPv4/6 Multicast traffic */ - p[0] |= BIT(17) | BIT(16) | BIT(13) | BIT(12); - p[2] = 0x1fffffff; /* L2 unknown MC flooding portmask all ports, including the CPU-port */ - p[3] = 0x1fffffff; /* IPv4 unknown MC flooding portmask */ - p[4] = 0x1fffffff; /* IPv6 unknown MC flooding portmask */ - - sw_w32(p[0], RTL930X_VLAN_PROFILE_SET(profile)); - sw_w32(p[1], RTL930X_VLAN_PROFILE_SET(profile) + 4); - sw_w32(p[2], RTL930X_VLAN_PROFILE_SET(profile) + 8); - sw_w32(p[3], RTL930X_VLAN_PROFILE_SET(profile) + 12); - sw_w32(p[4], RTL930X_VLAN_PROFILE_SET(profile) + 16); -} - -static void rtl930x_l2_learning_setup(void) -{ - /* Portmask for flooding broadcast traffic */ - sw_w32(0x1fffffff, RTL930X_L2_BC_FLD_PMSK); - - /* Portmask for flooding unicast traffic with unknown destination */ - sw_w32(0x1fffffff, RTL930X_L2_UNKN_UC_FLD_PMSK); - - /* Limit learning to maximum: 32k entries, after that just flood (bits 0-1) */ - sw_w32((0x7fff << 2) | 0, RTL930X_L2_LRN_CONSTRT_CTRL); -} - -static void rtl930x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]) -{ - u32 cmd = 1 << 17 | /* Execute cmd */ - 0 << 16 | /* Read */ - 4 << 12 | /* Table type 0b10 */ - (msti & 0xfff); - priv->r->exec_tbl0_cmd(cmd); - - for (int i = 0; i < 2; i++) - port_state[i] = sw_r32(RTL930X_TBL_ACCESS_DATA_0(i)); - pr_debug("MSTI: %d STATE: %08x, %08x\n", msti, port_state[0], port_state[1]); -} - -static void rtl930x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]) -{ - u32 cmd = 1 << 17 | /* Execute cmd */ - 1 << 16 | /* Write */ - 4 << 12 | /* Table type 4 */ - (msti & 0xfff); - - for (int i = 0; i < 2; i++) - sw_w32(port_state[i], RTL930X_TBL_ACCESS_DATA_0(i)); - priv->r->exec_tbl0_cmd(cmd); -} - -static inline int rtl930x_mac_force_mode_ctrl(int p) -{ - return RTL930X_MAC_FORCE_MODE_CTRL + (p << 2); -} - -static inline int rtl930x_mac_port_ctrl(int p) -{ - return RTL930X_MAC_L2_PORT_CTRL(p); -} - -static inline int rtl930x_mac_link_spd_sts(int p) -{ - return RTL930X_MAC_LINK_SPD_STS(p); -} - -static u64 rtl930x_l2_hash_seed(u64 mac, u32 vid) -{ - u64 v = vid; - - v <<= 48; - v |= mac; - - return v; -} - -/* Calculate both the block 0 and the block 1 hash by applyingthe same hash - * algorithm as the one used currently by the ASIC to the seed, and return - * both hashes in the lower and higher word of the return value since only 12 bit of - * the hash are significant - */ -static u32 rtl930x_l2_hash_key(struct rtl838x_switch_priv *priv, u64 seed) -{ - u32 k0, k1, h1, h2, h; - - k0 = (u32) (((seed >> 55) & 0x1f) ^ - ((seed >> 44) & 0x7ff) ^ - ((seed >> 33) & 0x7ff) ^ - ((seed >> 22) & 0x7ff) ^ - ((seed >> 11) & 0x7ff) ^ - (seed & 0x7ff)); - - h1 = (seed >> 11) & 0x7ff; - h1 = ((h1 & 0x1f) << 6) | ((h1 >> 5) & 0x3f); - - h2 = (seed >> 33) & 0x7ff; - h2 = ((h2 & 0x3f) << 5)| ((h2 >> 6) & 0x3f); - - k1 = (u32) (((seed << 55) & 0x1f) ^ - ((seed >> 44) & 0x7ff) ^ - h2 ^ - ((seed >> 22) & 0x7ff) ^ - h1 ^ - (seed & 0x7ff)); - - /* Algorithm choice for block 0 */ - if (sw_r32(RTL930X_L2_CTRL) & BIT(0)) - h = k1; - else - h = k0; - - /* Algorithm choice for block 1 - * Since k0 and k1 are < 2048, adding 2048 will offset the hash into the second - * half of hash-space - * 2048 is in fact the hash-table size 16384 divided by 4 hashes per bucket - * divided by 2 to divide the hash space in 2 - */ - if (sw_r32(RTL930X_L2_CTRL) & BIT(1)) - h |= (k1 + 2048) << 16; - else - h |= (k0 + 2048) << 16; - - return h; -} - -/* Fills an L2 entry structure from the SoC registers */ -static void rtl930x_fill_l2_entry(u32 r[], struct rtl838x_l2_entry *e) -{ - pr_debug("In %s valid?\n", __func__); - e->valid = !!(r[2] & BIT(31)); - if (!e->valid) - return; - - pr_debug("In %s is valid\n", __func__); - e->is_ip_mc = false; - e->is_ipv6_mc = false; - - /* TODO: Is there not a function to copy directly MAC memory? */ - e->mac[0] = (r[0] >> 24); - e->mac[1] = (r[0] >> 16); - e->mac[2] = (r[0] >> 8); - e->mac[3] = r[0]; - e->mac[4] = (r[1] >> 24); - e->mac[5] = (r[1] >> 16); - - e->next_hop = !!(r[2] & BIT(12)); - e->rvid = r[1] & 0xfff; - - /* Is it a unicast entry? check multicast bit */ - if (!(e->mac[0] & 1)) { - e->type = L2_UNICAST; - e->is_static = !!(r[2] & BIT(14)); - e->port = (r[2] >> 20) & 0x3ff; - /* Check for trunk port */ - if (r[2] & BIT(30)) { - e->is_trunk = true; - e->stack_dev = (e->port >> 9) & 1; - e->trunk = e->port & 0x3f; - } else { - e->is_trunk = false; - e->stack_dev = (e->port >> 6) & 0xf; - e->port = e->port & 0x3f; - } - - e->block_da = !!(r[2] & BIT(15)); - e->block_sa = !!(r[2] & BIT(16)); - e->suspended = !!(r[2] & BIT(13)); - e->age = (r[2] >> 17) & 3; - e->valid = true; - /* the UC_VID field in hardware is used for the VID or for the route id */ - if (e->next_hop) { - e->nh_route_id = r[2] & 0x7ff; - e->vid = 0; - } else { - e->vid = r[2] & 0xfff; - e->nh_route_id = 0; - } - } else { - e->valid = true; - e->type = L2_MULTICAST; - e->mc_portmask_index = (r[2] >> 16) & 0x3ff; - } -} - -/* Fills the 3 SoC table registers r[] with the information of in the rtl838x_l2_entry */ -static void rtl930x_fill_l2_row(u32 r[], struct rtl838x_l2_entry *e) -{ - u32 port; - - if (!e->valid) { - r[0] = r[1] = r[2] = 0; - return; - } - - r[2] = BIT(31); /* Set valid bit */ - - r[0] = ((u32)e->mac[0]) << 24 | - ((u32)e->mac[1]) << 16 | - ((u32)e->mac[2]) << 8 | - ((u32)e->mac[3]); - r[1] = ((u32)e->mac[4]) << 24 | - ((u32)e->mac[5]) << 16; - - r[2] |= e->next_hop ? BIT(12) : 0; - - if (e->type == L2_UNICAST) { - r[2] |= e->is_static ? BIT(14) : 0; - r[1] |= e->rvid & 0xfff; - r[2] |= (e->port & 0x3ff) << 20; - if (e->is_trunk) { - r[2] |= BIT(30); - port = e->stack_dev << 9 | (e->port & 0x3f); - } else { - port = (e->stack_dev & 0xf) << 6; - port |= e->port & 0x3f; - } - r[2] |= port << 20; - r[2] |= e->block_da ? BIT(15) : 0; - r[2] |= e->block_sa ? BIT(17) : 0; - r[2] |= e->suspended ? BIT(13) : 0; - r[2] |= (e->age & 0x3) << 17; - /* the UC_VID field in hardware is used for the VID or for the route id */ - if (e->next_hop) - r[2] |= e->nh_route_id & 0x7ff; - else - r[2] |= e->vid & 0xfff; - } else { /* L2_MULTICAST */ - r[2] |= (e->mc_portmask_index & 0x3ff) << 16; - r[2] |= e->mc_mac_index & 0x7ff; - } -} - -/* Read an L2 UC or MC entry out of a hash bucket of the L2 forwarding table - * hash is the id of the bucket and pos is the position of the entry in that bucket - * The data read from the SoC is filled into rtl838x_l2_entry - */ -static u64 rtl930x_read_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 0); - u32 idx; - u64 mac; - u64 seed; - - pr_debug("%s: hash %08x, pos: %d\n", __func__, hash, pos); - - /* On the RTL93xx, 2 different hash algorithms are used making it a - * total of 8 buckets that need to be searched, 4 for each hash-half - * Use second hash space when bucket is between 4 and 8 - */ - if (pos >= 4) { - pos -= 4; - hash >>= 16; - } else { - hash &= 0xffff; - } - - idx = (0 << 14) | (hash << 2) | pos; /* Search SRAM, with hash and at pos in bucket */ - pr_debug("%s: NOW hash %08x, pos: %d\n", __func__, hash, pos); - - rtl_table_read(q, idx); - for (int i = 0; i < 3; i++) - r[i] = sw_r32(rtl_table_data(q, i)); - - rtl_table_release(q); - - rtl930x_fill_l2_entry(r, e); - - pr_debug("%s: valid: %d, nh: %d\n", __func__, e->valid, e->next_hop); - if (!e->valid) - return 0; - - mac = ((u64)e->mac[0]) << 40 | - ((u64)e->mac[1]) << 32 | - ((u64)e->mac[2]) << 24 | - ((u64)e->mac[3]) << 16 | - ((u64)e->mac[4]) << 8 | - ((u64)e->mac[5]); - - seed = rtl930x_l2_hash_seed(mac, e->rvid); - pr_debug("%s: mac %016llx, seed %016llx\n", __func__, mac, seed); - - /* return vid with concatenated mac as unique id */ - return seed; -} - -static void rtl930x_write_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 0); - u32 idx = (0 << 14) | (hash << 2) | pos; /* Access SRAM, with hash and at pos in bucket */ - - pr_debug("%s: hash %d, pos %d\n", __func__, hash, pos); - pr_debug("%s: index %d -> mac %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, idx, - e->mac[0], e->mac[1], e->mac[2], e->mac[3],e->mac[4],e->mac[5]); - - rtl930x_fill_l2_row(r, e); - - for (int i = 0; i < 3; i++) - sw_w32(r[i], rtl_table_data(q, i)); - - rtl_table_write(q, idx); - rtl_table_release(q); -} - -static u64 rtl930x_read_cam(int idx, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 1); - - rtl_table_read(q, idx); - for (int i = 0; i < 3; i++) - r[i] = sw_r32(rtl_table_data(q, i)); - - rtl_table_release(q); - - rtl930x_fill_l2_entry(r, e); - if (!e->valid) - return 0; - - /* return mac with concatenated vid as unique id */ - return ((u64)r[0] << 28) | ((r[1] & 0xffff0000) >> 4) | e->vid; -} - -static void rtl930x_write_cam(int idx, struct rtl838x_l2_entry *e) -{ - u32 r[3]; - struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 1); /* Access L2 Table 1 */ - - rtl930x_fill_l2_row(r, e); - - for (int i = 0; i < 3; i++) - sw_w32(r[i], rtl_table_data(q, i)); - - rtl_table_write(q, idx); - rtl_table_release(q); -} - -static u64 rtl930x_read_mcast_pmask(int idx) -{ - u32 portmask; - /* Read MC_PORTMASK (2) via register RTL9300_TBL_L2 */ - struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 2); - - rtl_table_read(q, idx); - portmask = sw_r32(rtl_table_data(q, 0)); - portmask >>= 3; - rtl_table_release(q); - - pr_debug("%s: Index idx %d has portmask %08x\n", __func__, idx, portmask); - - return portmask; -} - -static void rtl930x_write_mcast_pmask(int idx, u64 portmask) -{ - u32 pm = portmask; - - /* Access MC_PORTMASK (2) via register RTL9300_TBL_L2 */ - struct table_reg *q = rtl_table_get(RTL9300_TBL_L2, 2); - - pr_debug("%s: Index idx %d has portmask %08x\n", __func__, idx, pm); - pm <<= 3; - sw_w32(pm, rtl_table_data(q, 0)); - rtl_table_write(q, idx); - rtl_table_release(q); -} - -u64 rtl930x_traffic_get(int source) -{ - u32 v; - struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6); - - rtl_table_read(r, source); - v = sw_r32(rtl_table_data(r, 0)); - rtl_table_release(r); - v = v >> 3; - - return v; -} - -/* Enable traffic between a source port and a destination port matrix */ -void rtl930x_traffic_set(int source, u64 dest_matrix) -{ - struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6); - - sw_w32((dest_matrix << 3), rtl_table_data(r, 0)); - rtl_table_write(r, source); - rtl_table_release(r); -} - -void rtl930x_traffic_enable(int source, int dest) -{ - struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6); - rtl_table_read(r, source); - sw_w32_mask(0, BIT(dest + 3), rtl_table_data(r, 0)); - rtl_table_write(r, source); - rtl_table_release(r); -} - -void rtl930x_traffic_disable(int source, int dest) -{ - struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 6); - rtl_table_read(r, source); - sw_w32_mask(BIT(dest + 3), 0, rtl_table_data(r, 0)); - rtl_table_write(r, source); - rtl_table_release(r); -} - -void rtl9300_dump_debug(void) -{ - u16 r = RTL930X_STAT_PRVTE_DROP_COUNTER0; - - for (int i = 0; i < 10; i ++) { - pr_info("# %d %08x %08x %08x %08x %08x %08x %08x %08x\n", i * 8, - sw_r32(r), sw_r32(r + 4), sw_r32(r + 8), sw_r32(r + 12), - sw_r32(r + 16), sw_r32(r + 20), sw_r32(r + 24), sw_r32(r + 28)); - r += 32; - } - pr_info("# %08x %08x %08x %08x %08x\n", - sw_r32(r), sw_r32(r + 4), sw_r32(r + 8), sw_r32(r + 12), sw_r32(r + 16)); - rtl930x_print_matrix(); - pr_info("RTL930X_L2_PORT_SABLK_CTRL: %08x, RTL930X_L2_PORT_DABLK_CTRL %08x\n", - sw_r32(RTL930X_L2_PORT_SABLK_CTRL), sw_r32(RTL930X_L2_PORT_DABLK_CTRL) - - ); -} - -irqreturn_t rtl930x_switch_irq(int irq, void *dev_id) -{ - struct dsa_switch *ds = dev_id; - u32 ports = sw_r32(RTL930X_ISR_PORT_LINK_STS_CHG); - u32 link; - - /* Clear status */ - sw_w32(ports, RTL930X_ISR_PORT_LINK_STS_CHG); - - for (int i = 0; i < 28; i++) { - if (ports & BIT(i)) { - /* Read the register twice because of issues with latency at least - * with the external RTL8226 PHY on the XGS1210 - */ - link = sw_r32(RTL930X_MAC_LINK_STS); - link = sw_r32(RTL930X_MAC_LINK_STS); - if (link & BIT(i)) - dsa_port_phylink_mac_change(ds, i, true); - else - dsa_port_phylink_mac_change(ds, i, false); - } - } - - return IRQ_HANDLED; -} - -int rtl930x_write_phy(u32 port, u32 page, u32 reg, u32 val) -{ - u32 v; - int err = 0; - - pr_debug("%s: port %d, page: %d, reg: %x, val: %x\n", __func__, port, page, reg, val); - - if (port > 63 || page > 4095 || reg > 31) - return -ENOTSUPP; - - val &= 0xffff; - mutex_lock(&smi_lock); - - sw_w32(BIT(port), RTL930X_SMI_ACCESS_PHY_CTRL_0); - sw_w32_mask(0xffff << 16, val << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2); - v = reg << 20 | page << 3 | 0x1f << 15 | BIT(2) | BIT(0); - sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1); - - do { - v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1); - } while (v & 0x1); - - if (v & 0x2) - err = -EIO; - - mutex_unlock(&smi_lock); - - return err; -} - -int rtl930x_read_phy(u32 port, u32 page, u32 reg, u32 *val) -{ - u32 v; - int err = 0; - - if (port > 63 || page > 4095 || reg > 31) - return -ENOTSUPP; - - mutex_lock(&smi_lock); - - sw_w32_mask(0xffff << 16, port << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2); - v = reg << 20 | page << 3 | 0x1f << 15 | 1; - sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1); - - do { - v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1); - } while ( v & 0x1); - - if (v & BIT(25)) { - pr_debug("Error reading phy %d, register %d\n", port, reg); - err = -EIO; - } - *val = (sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_2) & 0xffff); - - pr_debug("%s: port %d, page: %d, reg: %x, val: %x\n", __func__, port, page, reg, *val); - - mutex_unlock(&smi_lock); - - return err; -} - -/* Write to an mmd register of the PHY */ -int rtl930x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val) -{ - int err = 0; - u32 v; - - mutex_lock(&smi_lock); - - /* Set PHY to access */ - sw_w32(BIT(port), RTL930X_SMI_ACCESS_PHY_CTRL_0); - - /* Set data to write */ - sw_w32_mask(0xffff << 16, val << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2); - - /* Set MMD device number and register to write to */ - sw_w32(devnum << 16 | (regnum & 0xffff), RTL930X_SMI_ACCESS_PHY_CTRL_3); - - v = BIT(2) | BIT(1) | BIT(0); /* WRITE | MMD-access | EXEC */ - sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1); - - do { - v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1); - } while (v & BIT(0)); - - pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, val, err); - mutex_unlock(&smi_lock); - return err; -} - -/* Read an mmd register of the PHY */ -int rtl930x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val) -{ - int err = 0; - u32 v; - - mutex_lock(&smi_lock); - - /* Set PHY to access */ - sw_w32_mask(0xffff << 16, port << 16, RTL930X_SMI_ACCESS_PHY_CTRL_2); - - /* Set MMD device number and register to write to */ - sw_w32(devnum << 16 | (regnum & 0xffff), RTL930X_SMI_ACCESS_PHY_CTRL_3); - - v = BIT(1) | BIT(0); /* MMD-access | EXEC */ - sw_w32(v, RTL930X_SMI_ACCESS_PHY_CTRL_1); - - do { - v = sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_1); - } while (v & BIT(0)); - /* There is no error-checking via BIT 25 of v, as it does not seem to be set correctly */ - *val = (sw_r32(RTL930X_SMI_ACCESS_PHY_CTRL_2) & 0xffff); - pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, *val, err); - - mutex_unlock(&smi_lock); - - return err; -} - -/* Calculate both the block 0 and the block 1 hash, and return in - * lower and higher word of the return value since only 12 bit of - * the hash are significant - */ -u32 rtl930x_hash(struct rtl838x_switch_priv *priv, u64 seed) -{ - u32 k0, k1, h1, h2, h; - - k0 = (u32) (((seed >> 55) & 0x1f) ^ - ((seed >> 44) & 0x7ff) ^ - ((seed >> 33) & 0x7ff) ^ - ((seed >> 22) & 0x7ff) ^ - ((seed >> 11) & 0x7ff) ^ - (seed & 0x7ff)); - - h1 = (seed >> 11) & 0x7ff; - h1 = ((h1 & 0x1f) << 6) | ((h1 >> 5) & 0x3f); - - h2 = (seed >> 33) & 0x7ff; - h2 = ((h2 & 0x3f) << 5) | ((h2 >> 6) & 0x3f); - - k1 = (u32) (((seed << 55) & 0x1f) ^ - ((seed >> 44) & 0x7ff) ^ - h2 ^ - ((seed >> 22) & 0x7ff) ^ - h1 ^ - (seed & 0x7ff)); - - /* Algorithm choice for block 0 */ - if (sw_r32(RTL930X_L2_CTRL) & BIT(0)) - h = k1; - else - h = k0; - - /* Algorithm choice for block 1 - * Since k0 and k1 are < 2048, adding 2048 will offset the hash into the second - * half of hash-space - * 2048 is in fact the hash-table size 16384 divided by 4 hashes per bucket - * divided by 2 to divide the hash space in 2 - */ - if (sw_r32(RTL930X_L2_CTRL) & BIT(1)) - h |= (k1 + 2048) << 16; - else - h |= (k0 + 2048) << 16; - - return h; -} - -/* Enables or disables the EEE/EEEP capability of a port */ -void rtl930x_port_eee_set(struct rtl838x_switch_priv *priv, int port, bool enable) -{ - u32 v; - - /* This works only for Ethernet ports, and on the RTL930X, ports from 26 are SFP */ - if (port >= 26) - return; - - pr_debug("In %s: setting port %d to %d\n", __func__, port, enable); - v = enable ? 0x3f : 0x0; - - /* Set EEE/EEEP state for 100, 500, 1000MBit and 2.5, 5 and 10GBit */ - sw_w32_mask(0, v << 10, rtl930x_mac_force_mode_ctrl(port)); - - /* Set TX/RX EEE state */ - v = enable ? 0x3 : 0x0; - sw_w32(v, RTL930X_EEE_CTRL(port)); - - priv->ports[port].eee_enabled = enable; -} - -/* Get EEE own capabilities and negotiation result */ -int rtl930x_eee_port_ability(struct rtl838x_switch_priv *priv, struct ethtool_eee *e, int port) -{ - u32 link, a; - - if (port >= 26) - return -ENOTSUPP; - - pr_info("In %s, port %d\n", __func__, port); - link = sw_r32(RTL930X_MAC_LINK_STS); - link = sw_r32(RTL930X_MAC_LINK_STS); - if (!(link & BIT(port))) - return 0; - - pr_info("Setting advertised\n"); - if (sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(10)) - e->advertised |= ADVERTISED_100baseT_Full; - - if (sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(12)) - e->advertised |= ADVERTISED_1000baseT_Full; - - if (priv->ports[port].is2G5 && sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(13)) { - pr_info("ADVERTISING 2.5G EEE\n"); - e->advertised |= ADVERTISED_2500baseX_Full; - } - - if (priv->ports[port].is10G && sw_r32(rtl930x_mac_force_mode_ctrl(port)) & BIT(15)) - e->advertised |= ADVERTISED_10000baseT_Full; - - a = sw_r32(RTL930X_MAC_EEE_ABLTY); - a = sw_r32(RTL930X_MAC_EEE_ABLTY); - pr_info("Link partner: %08x\n", a); - if (a & BIT(port)) { - e->lp_advertised = ADVERTISED_100baseT_Full; - e->lp_advertised |= ADVERTISED_1000baseT_Full; - if (priv->ports[port].is2G5) - e->lp_advertised |= ADVERTISED_2500baseX_Full; - if (priv->ports[port].is10G) - e->lp_advertised |= ADVERTISED_10000baseT_Full; - } - - /* Read 2x to clear latched state */ - a = sw_r32(RTL930X_EEEP_PORT_CTRL(port)); - a = sw_r32(RTL930X_EEEP_PORT_CTRL(port)); - pr_info("%s RTL930X_EEEP_PORT_CTRL: %08x\n", __func__, a); - - return 0; -} - -static void rtl930x_init_eee(struct rtl838x_switch_priv *priv, bool enable) -{ - pr_info("Setting up EEE, state: %d\n", enable); - - /* Setup EEE on all ports */ - for (int i = 0; i < priv->cpu_port; i++) { - if (priv->ports[i].phy) - rtl930x_port_eee_set(priv, i, enable); - } - - priv->eee_enabled = enable; -} -#define HASH_PICK(val, lsb, len) ((val & (((1 << len) - 1) << lsb)) >> lsb) - -static u32 rtl930x_l3_hash4(u32 ip, int algorithm, bool move_dip) -{ - u32 rows[4]; - u32 hash; - u32 s0, s1, pH; - - memset(rows, 0, sizeof(rows)); - - rows[0] = HASH_PICK(ip, 27, 5); - rows[1] = HASH_PICK(ip, 18, 9); - rows[2] = HASH_PICK(ip, 9, 9); - - if (!move_dip) - rows[3] = HASH_PICK(ip, 0, 9); - - if (!algorithm) { - hash = rows[0] ^ rows[1] ^ rows[2] ^ rows[3]; - } else { - s0 = rows[0] + rows[1] + rows[2]; - s1 = (s0 & 0x1ff) + ((s0 & (0x1ff << 9)) >> 9); - pH = (s1 & 0x1ff) + ((s1 & (0x1ff << 9)) >> 9); - hash = pH ^ rows[3]; - } - return hash; -} - -// Currently not used -// static u32 rtl930x_l3_hash6(struct in6_addr *ip6, int algorithm, bool move_dip) -// { -// u32 rows[16]; -// u32 hash; -// u32 s0, s1, pH; - -// rows[0] = (HASH_PICK(ip6->s6_addr[0], 6, 2) << 0); -// rows[1] = (HASH_PICK(ip6->s6_addr[0], 0, 6) << 3) | HASH_PICK(ip6->s6_addr[1], 5, 3); -// rows[2] = (HASH_PICK(ip6->s6_addr[1], 0, 5) << 4) | HASH_PICK(ip6->s6_addr[2], 4, 4); -// rows[3] = (HASH_PICK(ip6->s6_addr[2], 0, 4) << 5) | HASH_PICK(ip6->s6_addr[3], 3, 5); -// rows[4] = (HASH_PICK(ip6->s6_addr[3], 0, 3) << 6) | HASH_PICK(ip6->s6_addr[4], 2, 6); -// rows[5] = (HASH_PICK(ip6->s6_addr[4], 0, 2) << 7) | HASH_PICK(ip6->s6_addr[5], 1, 7); -// rows[6] = (HASH_PICK(ip6->s6_addr[5], 0, 1) << 8) | HASH_PICK(ip6->s6_addr[6], 0, 8); -// rows[7] = (HASH_PICK(ip6->s6_addr[7], 0, 8) << 1) | HASH_PICK(ip6->s6_addr[8], 7, 1); -// rows[8] = (HASH_PICK(ip6->s6_addr[8], 0, 7) << 2) | HASH_PICK(ip6->s6_addr[9], 6, 2); -// rows[9] = (HASH_PICK(ip6->s6_addr[9], 0, 6) << 3) | HASH_PICK(ip6->s6_addr[10], 5, 3); -// rows[10] = (HASH_PICK(ip6->s6_addr[10], 0, 5) << 4) | HASH_PICK(ip6->s6_addr[11], 4, 4); -// if (!algorithm) { -// rows[11] = (HASH_PICK(ip6->s6_addr[11], 0, 4) << 5) | -// (HASH_PICK(ip6->s6_addr[12], 3, 5) << 0); -// rows[12] = (HASH_PICK(ip6->s6_addr[12], 0, 3) << 6) | -// (HASH_PICK(ip6->s6_addr[13], 2, 6) << 0); -// rows[13] = (HASH_PICK(ip6->s6_addr[13], 0, 2) << 7) | -// (HASH_PICK(ip6->s6_addr[14], 1, 7) << 0); -// if (!move_dip) { -// rows[14] = (HASH_PICK(ip6->s6_addr[14], 0, 1) << 8) | -// (HASH_PICK(ip6->s6_addr[15], 0, 8) << 0); -// } -// hash = rows[0] ^ rows[1] ^ rows[2] ^ rows[3] ^ rows[4] ^ -// rows[5] ^ rows[6] ^ rows[7] ^ rows[8] ^ rows[9] ^ -// rows[10] ^ rows[11] ^ rows[12] ^ rows[13] ^ rows[14]; -// } else { -// rows[11] = (HASH_PICK(ip6->s6_addr[11], 0, 4) << 5); -// rows[12] = (HASH_PICK(ip6->s6_addr[12], 3, 5) << 0); -// rows[13] = (HASH_PICK(ip6->s6_addr[12], 0, 3) << 6) | -// HASH_PICK(ip6->s6_addr[13], 2, 6); -// rows[14] = (HASH_PICK(ip6->s6_addr[13], 0, 2) << 7) | -// HASH_PICK(ip6->s6_addr[14], 1, 7); -// if (!move_dip) { -// rows[15] = (HASH_PICK(ip6->s6_addr[14], 0, 1) << 8) | -// (HASH_PICK(ip6->s6_addr[15], 0, 8) << 0); -// } -// s0 = rows[12] + rows[13] + rows[14]; -// s1 = (s0 & 0x1ff) + ((s0 & (0x1ff << 9)) >> 9); -// pH = (s1 & 0x1ff) + ((s1 & (0x1ff << 9)) >> 9); -// hash = rows[0] ^ rows[1] ^ rows[2] ^ rows[3] ^ rows[4] ^ -// rows[5] ^ rows[6] ^ rows[7] ^ rows[8] ^ rows[9] ^ -// rows[10] ^ rows[11] ^ pH ^ rows[15]; -// } -// return hash; -// } - -/* Read a prefix route entry from the L3_PREFIX_ROUTE_IPUC table - * We currently only support IPv4 and IPv6 unicast route - */ -static void rtl930x_route_read(int idx, struct rtl83xx_route *rt) -{ - u32 v, ip4_m; - bool host_route, default_route; - struct in6_addr ip6_m; - - /* Read L3_PREFIX_ROUTE_IPUC table (2) via register RTL9300_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 2); - - rtl_table_read(r, idx); - /* The table has a size of 11 registers */ - rt->attr.valid = !!(sw_r32(rtl_table_data(r, 0)) & BIT(31)); - if (!rt->attr.valid) - goto out; - - rt->attr.type = (sw_r32(rtl_table_data(r, 0)) >> 29) & 0x3; - - v = sw_r32(rtl_table_data(r, 10)); - host_route = !!(v & BIT(21)); - default_route = !!(v & BIT(20)); - rt->prefix_len = -1; - pr_info("%s: host route %d, default_route %d\n", __func__, host_route, default_route); - - switch (rt->attr.type) { - case 0: /* IPv4 Unicast route */ - rt->dst_ip = sw_r32(rtl_table_data(r, 4)); - ip4_m = sw_r32(rtl_table_data(r, 9)); - pr_info("%s: Read ip4 mask: %08x\n", __func__, ip4_m); - rt->prefix_len = host_route ? 32 : -1; - rt->prefix_len = (rt->prefix_len < 0 && default_route) ? 0 : -1; - if (rt->prefix_len < 0) - rt->prefix_len = inet_mask_len(ip4_m); - break; - case 2: /* IPv6 Unicast route */ - ipv6_addr_set(&rt->dst_ip6, - sw_r32(rtl_table_data(r, 1)), sw_r32(rtl_table_data(r, 2)), - sw_r32(rtl_table_data(r, 3)), sw_r32(rtl_table_data(r, 4))); - ipv6_addr_set(&ip6_m, - sw_r32(rtl_table_data(r, 6)), sw_r32(rtl_table_data(r, 7)), - sw_r32(rtl_table_data(r, 8)), sw_r32(rtl_table_data(r, 9))); - rt->prefix_len = host_route ? 128 : 0; - rt->prefix_len = (rt->prefix_len < 0 && default_route) ? 0 : -1; - if (rt->prefix_len < 0) - rt->prefix_len = find_last_bit((unsigned long int *)&ip6_m.s6_addr32, - 128); - break; - case 1: /* IPv4 Multicast route */ - case 3: /* IPv6 Multicast route */ - pr_warn("%s: route type not supported\n", __func__); - goto out; - } - - rt->attr.hit = !!(v & BIT(22)); - rt->attr.action = (v >> 18) & 3; - rt->nh.id = (v >> 7) & 0x7ff; - rt->attr.ttl_dec = !!(v & BIT(6)); - rt->attr.ttl_check = !!(v & BIT(5)); - rt->attr.dst_null = !!(v & BIT(4)); - rt->attr.qos_as = !!(v & BIT(3)); - rt->attr.qos_prio = v & 0x7; - pr_info("%s: index %d is valid: %d\n", __func__, idx, rt->attr.valid); - pr_info("%s: next_hop: %d, hit: %d, action :%d, ttl_dec %d, ttl_check %d, dst_null %d\n", - __func__, rt->nh.id, rt->attr.hit, rt->attr.action, - rt->attr.ttl_dec, rt->attr.ttl_check, rt->attr.dst_null); - pr_info("%s: GW: %pI4, prefix_len: %d\n", __func__, &rt->dst_ip, rt->prefix_len); -out: - rtl_table_release(r); -} - -static void rtl930x_net6_mask(int prefix_len, struct in6_addr *ip6_m) -{ - int o, b; - /* Define network mask */ - o = prefix_len >> 3; - b = prefix_len & 0x7; - memset(ip6_m->s6_addr, 0xff, o); - ip6_m->s6_addr[o] |= b ? 0xff00 >> b : 0x00; -} - -/* Read a host route entry from the table using its index - * We currently only support IPv4 and IPv6 unicast route - */ -static void rtl930x_host_route_read(int idx, struct rtl83xx_route *rt) -{ - u32 v; - /* Read L3_HOST_ROUTE_IPUC table (1) via register RTL9300_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 1); - - idx = ((idx / 6) * 8) + (idx % 6); - - pr_debug("In %s, physical index %d\n", __func__, idx); - rtl_table_read(r, idx); - /* The table has a size of 5 (for UC, 11 for MC) registers */ - v = sw_r32(rtl_table_data(r, 0)); - rt->attr.valid = !!(v & BIT(31)); - if (!rt->attr.valid) - goto out; - rt->attr.type = (v >> 29) & 0x3; - switch (rt->attr.type) { - case 0: /* IPv4 Unicast route */ - rt->dst_ip = sw_r32(rtl_table_data(r, 4)); - break; - case 2: /* IPv6 Unicast route */ - ipv6_addr_set(&rt->dst_ip6, - sw_r32(rtl_table_data(r, 3)), sw_r32(rtl_table_data(r, 2)), - sw_r32(rtl_table_data(r, 1)), sw_r32(rtl_table_data(r, 0))); - break; - case 1: /* IPv4 Multicast route */ - case 3: /* IPv6 Multicast route */ - pr_warn("%s: route type not supported\n", __func__); - goto out; - } - - rt->attr.hit = !!(v & BIT(20)); - rt->attr.dst_null = !!(v & BIT(19)); - rt->attr.action = (v >> 17) & 3; - rt->nh.id = (v >> 6) & 0x7ff; - rt->attr.ttl_dec = !!(v & BIT(5)); - rt->attr.ttl_check = !!(v & BIT(4)); - rt->attr.qos_as = !!(v & BIT(3)); - rt->attr.qos_prio = v & 0x7; - pr_debug("%s: index %d is valid: %d\n", __func__, idx, rt->attr.valid); - pr_debug("%s: next_hop: %d, hit: %d, action :%d, ttl_dec %d, ttl_check %d, dst_null %d\n", - __func__, rt->nh.id, rt->attr.hit, rt->attr.action, rt->attr.ttl_dec, rt->attr.ttl_check, - rt->attr.dst_null); - pr_debug("%s: Destination: %pI4\n", __func__, &rt->dst_ip); - -out: - rtl_table_release(r); -} - -/* Write a host route entry from the table using its index - * We currently only support IPv4 and IPv6 unicast route - */ -static void rtl930x_host_route_write(int idx, struct rtl83xx_route *rt) -{ - u32 v; - /* Access L3_HOST_ROUTE_IPUC table (1) via register RTL9300_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 1); - /* The table has a size of 5 (for UC, 11 for MC) registers */ - - idx = ((idx / 6) * 8) + (idx % 6); - - pr_debug("%s: index %d is valid: %d\n", __func__, idx, rt->attr.valid); - pr_debug("%s: next_hop: %d, hit: %d, action :%d, ttl_dec %d, ttl_check %d, dst_null %d\n", - __func__, rt->nh.id, rt->attr.hit, rt->attr.action, rt->attr.ttl_dec, rt->attr.ttl_check, - rt->attr.dst_null); - pr_debug("%s: GW: %pI4, prefix_len: %d\n", __func__, &rt->dst_ip, rt->prefix_len); - - v = BIT(31); /* Entry is valid */ - v |= (rt->attr.type & 0x3) << 29; - v |= rt->attr.hit ? BIT(20) : 0; - v |= rt->attr.dst_null ? BIT(19) : 0; - v |= (rt->attr.action & 0x3) << 17; - v |= (rt->nh.id & 0x7ff) << 6; - v |= rt->attr.ttl_dec ? BIT(5) : 0; - v |= rt->attr.ttl_check ? BIT(4) : 0; - v |= rt->attr.qos_as ? BIT(3) : 0; - v |= rt->attr.qos_prio & 0x7; - - sw_w32(v, rtl_table_data(r, 0)); - switch (rt->attr.type) { - case 0: /* IPv4 Unicast route */ - sw_w32(0, rtl_table_data(r, 1)); - sw_w32(0, rtl_table_data(r, 2)); - sw_w32(0, rtl_table_data(r, 3)); - sw_w32(rt->dst_ip, rtl_table_data(r, 4)); - break; - case 2: /* IPv6 Unicast route */ - sw_w32(rt->dst_ip6.s6_addr32[0], rtl_table_data(r, 1)); - sw_w32(rt->dst_ip6.s6_addr32[1], rtl_table_data(r, 2)); - sw_w32(rt->dst_ip6.s6_addr32[2], rtl_table_data(r, 3)); - sw_w32(rt->dst_ip6.s6_addr32[3], rtl_table_data(r, 4)); - break; - case 1: /* IPv4 Multicast route */ - case 3: /* IPv6 Multicast route */ - pr_warn("%s: route type not supported\n", __func__); - goto out; - } - - rtl_table_write(r, idx); - -out: - rtl_table_release(r); -} - -/* Look up the index of a prefix route in the routing table CAM for unicast IPv4/6 routes - * using hardware offload. - */ -static int rtl930x_route_lookup_hw(struct rtl83xx_route *rt) -{ - u32 ip4_m, v; - struct in6_addr ip6_m; - - if (rt->attr.type == 1 || rt->attr.type == 3) /* Hardware only supports UC routes */ - return -1; - - sw_w32_mask(0x3 << 19, rt->attr.type, RTL930X_L3_HW_LU_KEY_CTRL); - if (rt->attr.type) { /* IPv6 */ - rtl930x_net6_mask(rt->prefix_len, &ip6_m); - for (int i = 0; i < 4; i++) - sw_w32(rt->dst_ip6.s6_addr32[0] & ip6_m.s6_addr32[0], - RTL930X_L3_HW_LU_KEY_IP_CTRL + (i << 2)); - } else { /* IPv4 */ - ip4_m = inet_make_mask(rt->prefix_len); - sw_w32(0, RTL930X_L3_HW_LU_KEY_IP_CTRL); - sw_w32(0, RTL930X_L3_HW_LU_KEY_IP_CTRL + 4); - sw_w32(0, RTL930X_L3_HW_LU_KEY_IP_CTRL + 8); - v = rt->dst_ip & ip4_m; - pr_info("%s: searching for %pI4\n", __func__, &v); - sw_w32(v, RTL930X_L3_HW_LU_KEY_IP_CTRL + 12); - } - - /* Execute CAM lookup in SoC */ - sw_w32(BIT(15), RTL930X_L3_HW_LU_CTRL); - - /* Wait until execute bit clears and result is ready */ - do { - v = sw_r32(RTL930X_L3_HW_LU_CTRL); - } while (v & BIT(15)); - - pr_info("%s: found: %d, index: %d\n", __func__, !!(v & BIT(14)), v & 0x1ff); - - /* Test if search successful (BIT 14 set) */ - if (v & BIT(14)) - return v & 0x1ff; - - return -1; -} - -static int rtl930x_find_l3_slot(struct rtl83xx_route *rt, bool must_exist) -{ - int slot_width, algorithm, addr, idx; - u32 hash; - struct rtl83xx_route route_entry; - - /* IPv6 entries take up 3 slots */ - slot_width = (rt->attr.type == 0) || (rt->attr.type == 2) ? 1 : 3; - - for (int t = 0; t < 2; t++) { - algorithm = (sw_r32(RTL930X_L3_HOST_TBL_CTRL) >> (2 + t)) & 0x1; - hash = rtl930x_l3_hash4(rt->dst_ip, algorithm, false); - - pr_debug("%s: table %d, algorithm %d, hash %04x\n", __func__, t, algorithm, hash); - - for (int s = 0; s < 6; s += slot_width) { - addr = (t << 12) | ((hash & 0x1ff) << 3) | s; - pr_debug("%s physical address %d\n", __func__, addr); - idx = ((addr / 8) * 6) + (addr % 8); - pr_debug("%s logical address %d\n", __func__, idx); - - rtl930x_host_route_read(idx, &route_entry); - pr_debug("%s route valid %d, route dest: %pI4, hit %d\n", __func__, - rt->attr.valid, &rt->dst_ip, rt->attr.hit); - if (!must_exist && rt->attr.valid) - return idx; - if (must_exist && route_entry.dst_ip == rt->dst_ip) - return idx; - } - } - - return -1; -} - -/* Write a prefix route into the routing table CAM at position idx - * Currently only IPv4 and IPv6 unicast routes are supported - */ -static void rtl930x_route_write(int idx, struct rtl83xx_route *rt) -{ - u32 v, ip4_m; - struct in6_addr ip6_m; - /* Access L3_PREFIX_ROUTE_IPUC table (2) via register RTL9300_TBL_1 */ - /* The table has a size of 11 registers (20 for MC) */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 2); - - pr_debug("%s: index %d is valid: %d\n", __func__, idx, rt->attr.valid); - pr_debug("%s: nexthop: %d, hit: %d, action :%d, ttl_dec %d, ttl_check %d, dst_null %d\n", - __func__, rt->nh.id, rt->attr.hit, rt->attr.action, - rt->attr.ttl_dec, rt->attr.ttl_check, rt->attr.dst_null); - pr_debug("%s: GW: %pI4, prefix_len: %d\n", __func__, &rt->dst_ip, rt->prefix_len); - - v = rt->attr.valid ? BIT(31) : 0; - v |= (rt->attr.type & 0x3) << 29; - sw_w32(v, rtl_table_data(r, 0)); - - v = rt->attr.hit ? BIT(22) : 0; - v |= (rt->attr.action & 0x3) << 18; - v |= (rt->nh.id & 0x7ff) << 7; - v |= rt->attr.ttl_dec ? BIT(6) : 0; - v |= rt->attr.ttl_check ? BIT(5) : 0; - v |= rt->attr.dst_null ? BIT(6) : 0; - v |= rt->attr.qos_as ? BIT(6) : 0; - v |= rt->attr.qos_prio & 0x7; - v |= rt->prefix_len == 0 ? BIT(20) : 0; /* set default route bit */ - - /* set bit mask for entry type always to 0x3 */ - sw_w32(0x3 << 29, rtl_table_data(r, 5)); - - switch (rt->attr.type) { - case 0: /* IPv4 Unicast route */ - sw_w32(0, rtl_table_data(r, 1)); - sw_w32(0, rtl_table_data(r, 2)); - sw_w32(0, rtl_table_data(r, 3)); - sw_w32(rt->dst_ip, rtl_table_data(r, 4)); - - v |= rt->prefix_len == 32 ? BIT(21) : 0; /* set host-route bit */ - ip4_m = inet_make_mask(rt->prefix_len); - sw_w32(0, rtl_table_data(r, 6)); - sw_w32(0, rtl_table_data(r, 7)); - sw_w32(0, rtl_table_data(r, 8)); - sw_w32(ip4_m, rtl_table_data(r, 9)); - break; - case 2: /* IPv6 Unicast route */ - sw_w32(rt->dst_ip6.s6_addr32[0], rtl_table_data(r, 1)); - sw_w32(rt->dst_ip6.s6_addr32[1], rtl_table_data(r, 2)); - sw_w32(rt->dst_ip6.s6_addr32[2], rtl_table_data(r, 3)); - sw_w32(rt->dst_ip6.s6_addr32[3], rtl_table_data(r, 4)); - - v |= rt->prefix_len == 128 ? BIT(21) : 0; /* set host-route bit */ - - rtl930x_net6_mask(rt->prefix_len, &ip6_m); - - sw_w32(ip6_m.s6_addr32[0], rtl_table_data(r, 6)); - sw_w32(ip6_m.s6_addr32[1], rtl_table_data(r, 7)); - sw_w32(ip6_m.s6_addr32[2], rtl_table_data(r, 8)); - sw_w32(ip6_m.s6_addr32[3], rtl_table_data(r, 9)); - break; - case 1: /* IPv4 Multicast route */ - case 3: /* IPv6 Multicast route */ - pr_warn("%s: route type not supported\n", __func__); - rtl_table_release(r); - return; - } - sw_w32(v, rtl_table_data(r, 10)); - - pr_debug("%s: %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", __func__, - sw_r32(rtl_table_data(r, 0)), sw_r32(rtl_table_data(r, 1)), sw_r32(rtl_table_data(r, 2)), - sw_r32(rtl_table_data(r, 3)), sw_r32(rtl_table_data(r, 4)), sw_r32(rtl_table_data(r, 5)), - sw_r32(rtl_table_data(r, 6)), sw_r32(rtl_table_data(r, 7)), sw_r32(rtl_table_data(r, 8)), - sw_r32(rtl_table_data(r, 9)), sw_r32(rtl_table_data(r, 10))); - - rtl_table_write(r, idx); - rtl_table_release(r); -} - - -/* Get the destination MAC and L3 egress interface ID of a nexthop entry from - * the SoC's L3_NEXTHOP table - */ -static void rtl930x_get_l3_nexthop(int idx, u16 *dmac_id, u16 *interface) -{ - u32 v; - /* Read L3_NEXTHOP table (3) via register RTL9300_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 3); - - rtl_table_read(r, idx); - /* The table has a size of 1 register */ - v = sw_r32(rtl_table_data(r, 0)); - rtl_table_release(r); - - *dmac_id = (v >> 7) & 0x7fff; - *interface = v & 0x7f; -} - -// Currently not used -// static int rtl930x_l3_mtu_del(struct rtl838x_switch_priv *priv, int mtu) -// { -// int i; - -// for (i = 0; i < MAX_INTF_MTUS; i++) { -// if (mtu == priv->intf_mtus[i]) -// break; -// } -// if (i >= MAX_INTF_MTUS || !priv->intf_mtu_count[i]) { -// pr_err("%s: No MTU slot found for MTU: %d\n", __func__, mtu); -// return -EINVAL; -// } - -// priv->intf_mtu_count[i]--; -// } - -// Currently not used -// static int rtl930x_l3_mtu_add(struct rtl838x_switch_priv *priv, int mtu) -// { -// int i, free_mtu; -// int mtu_id; - -// /* Try to find an existing mtu-value or a free slot */ -// free_mtu = MAX_INTF_MTUS; -// for (i = 0; i < MAX_INTF_MTUS && priv->intf_mtus[i] != mtu; i++) { -// if ((!priv->intf_mtu_count[i]) && (free_mtu == MAX_INTF_MTUS)) -// free_mtu = i; -// } -// i = (i < MAX_INTF_MTUS) ? i : free_mtu; -// if (i < MAX_INTF_MTUS) { -// mtu_id = i; -// } else { -// pr_err("%s: No free MTU slot available!\n", __func__); -// return -EINVAL; -// } - -// priv->intf_mtus[i] = mtu; -// pr_info("Writing MTU %d to slot %d\n", priv->intf_mtus[i], i); -// /* Set MTU-value of the slot TODO: distinguish between IPv4/IPv6 routes / slots */ -// sw_w32_mask(0xffff << ((i % 2) * 16), priv->intf_mtus[i] << ((i % 2) * 16), -// RTL930X_L3_IP_MTU_CTRL(i)); -// sw_w32_mask(0xffff << ((i % 2) * 16), priv->intf_mtus[i] << ((i % 2) * 16), -// RTL930X_L3_IP6_MTU_CTRL(i)); - -// priv->intf_mtu_count[i]++; - -// return mtu_id; -// } - - -// Currently not used -// /* Creates an interface for a route by setting up the HW tables in the SoC -// static int rtl930x_l3_intf_add(struct rtl838x_switch_priv *priv, struct rtl838x_l3_intf *intf) -// { -// int i, intf_id, mtu_id; -// /* number of MTU-values < 16384 *\/ - -// /* Use the same IPv6 mtu as the ip4 mtu for this route if unset */ -// intf->ip6_mtu = intf->ip6_mtu ? intf->ip6_mtu : intf->ip4_mtu; - -// mtu_id = rtl930x_l3_mtu_add(priv, intf->ip4_mtu); -// pr_info("%s: added mtu %d with mtu-id %d\n", __func__, intf->ip4_mtu, mtu_id); -// if (mtu_id < 0) -// return -ENOSPC; -// intf->ip4_mtu_id = mtu_id; -// intf->ip6_mtu_id = mtu_id; - -// for (i = 0; i < MAX_INTERFACES; i++) { -// if (!priv->interfaces[i]) -// break; -// } -// if (i >= MAX_INTERFACES) { -// pr_err("%s: cannot find free interface entry\n", __func__); -// return -EINVAL; -// } -// intf_id = i; -// priv->interfaces[i] = kzalloc(sizeof(struct rtl838x_l3_intf), GFP_KERNEL); -// if (!priv->interfaces[i]) { -// pr_err("%s: no memory to allocate new interface\n", __func__); -// return -ENOMEM; -// } -// } - -/* Set the destination MAC and L3 egress interface ID for a nexthop entry in the SoC's - * L3_NEXTHOP table. The nexthop entry is identified by idx. - * dmac_id is the reference to the L2 entry in the L2 forwarding table, special values are - * 0x7ffe: TRAP2CPU - * 0x7ffd: TRAP2MASTERCPU - * 0x7fff: DMAC_ID_DROP - */ -static void rtl930x_set_l3_nexthop(int idx, u16 dmac_id, u16 interface) -{ - /* Access L3_NEXTHOP table (3) via register RTL9300_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 3); - - pr_info("%s: Writing to L3_NEXTHOP table, index %d, dmac_id %d, interface %d\n", - __func__, idx, dmac_id, interface); - sw_w32(((dmac_id & 0x7fff) << 7) | (interface & 0x7f), rtl_table_data(r, 0)); - - pr_info("%s: %08x\n", __func__, sw_r32(rtl_table_data(r,0))); - rtl_table_write(r, idx); - rtl_table_release(r); -} - -static void rtl930x_pie_lookup_enable(struct rtl838x_switch_priv *priv, int index) -{ - int block = index / PIE_BLOCK_SIZE; - - sw_w32_mask(0, BIT(block), RTL930X_PIE_BLK_LOOKUP_CTRL); -} - -/* Reads the intermediate representation of the templated match-fields of the - * PIE rule in the pie_rule structure and fills in the raw data fields in the - * raw register space r[]. - * The register space configuration size is identical for the RTL8380/90 and RTL9300, - * however the RTL9310 has 2 more registers / fields and the physical field-ids are different - * on all SoCs - * On the RTL9300 the mask fields are not word-aligend! - */ -static void rtl930x_write_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[]) -{ - for (int i = 0; i < N_FIXED_FIELDS; i++) { - enum template_field_id field_type = t[i]; - u16 data = 0, data_m = 0; - - switch (field_type) { - case TEMPLATE_FIELD_SPM0: - data = pr->spm; - data_m = pr->spm_m; - break; - case TEMPLATE_FIELD_SPM1: - data = pr->spm >> 16; - data_m = pr->spm_m >> 16; - break; - case TEMPLATE_FIELD_OTAG: - data = pr->otag; - data_m = pr->otag_m; - break; - case TEMPLATE_FIELD_SMAC0: - data = pr->smac[4]; - data = (data << 8) | pr->smac[5]; - data_m = pr->smac_m[4]; - data_m = (data_m << 8) | pr->smac_m[5]; - break; - case TEMPLATE_FIELD_SMAC1: - data = pr->smac[2]; - data = (data << 8) | pr->smac[3]; - data_m = pr->smac_m[2]; - data_m = (data_m << 8) | pr->smac_m[3]; - break; - case TEMPLATE_FIELD_SMAC2: - data = pr->smac[0]; - data = (data << 8) | pr->smac[1]; - data_m = pr->smac_m[0]; - data_m = (data_m << 8) | pr->smac_m[1]; - break; - case TEMPLATE_FIELD_DMAC0: - data = pr->dmac[4]; - data = (data << 8) | pr->dmac[5]; - data_m = pr->dmac_m[4]; - data_m = (data_m << 8) | pr->dmac_m[5]; - break; - case TEMPLATE_FIELD_DMAC1: - data = pr->dmac[2]; - data = (data << 8) | pr->dmac[3]; - data_m = pr->dmac_m[2]; - data_m = (data_m << 8) | pr->dmac_m[3]; - break; - case TEMPLATE_FIELD_DMAC2: - data = pr->dmac[0]; - data = (data << 8) | pr->dmac[1]; - data_m = pr->dmac_m[0]; - data_m = (data_m << 8) | pr->dmac_m[1]; - break; - case TEMPLATE_FIELD_ETHERTYPE: - data = pr->ethertype; - data_m = pr->ethertype_m; - break; - case TEMPLATE_FIELD_ITAG: - data = pr->itag; - data_m = pr->itag_m; - break; - case TEMPLATE_FIELD_SIP0: - if (pr->is_ipv6) { - data = pr->sip6.s6_addr16[7]; - data_m = pr->sip6_m.s6_addr16[7]; - } else { - data = pr->sip; - data_m = pr->sip_m; - } - break; - case TEMPLATE_FIELD_SIP1: - if (pr->is_ipv6) { - data = pr->sip6.s6_addr16[6]; - data_m = pr->sip6_m.s6_addr16[6]; - } else { - data = pr->sip >> 16; - data_m = pr->sip_m >> 16; - } - break; - case TEMPLATE_FIELD_SIP2: - case TEMPLATE_FIELD_SIP3: - case TEMPLATE_FIELD_SIP4: - case TEMPLATE_FIELD_SIP5: - case TEMPLATE_FIELD_SIP6: - case TEMPLATE_FIELD_SIP7: - data = pr->sip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)]; - data_m = pr->sip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)]; - break; - case TEMPLATE_FIELD_DIP0: - if (pr->is_ipv6) { - data = pr->dip6.s6_addr16[7]; - data_m = pr->dip6_m.s6_addr16[7]; - } else { - data = pr->dip; - data_m = pr->dip_m; - } - break; - case TEMPLATE_FIELD_DIP1: - if (pr->is_ipv6) { - data = pr->dip6.s6_addr16[6]; - data_m = pr->dip6_m.s6_addr16[6]; - } else { - data = pr->dip >> 16; - data_m = pr->dip_m >> 16; - } - break; - case TEMPLATE_FIELD_DIP2: - case TEMPLATE_FIELD_DIP3: - case TEMPLATE_FIELD_DIP4: - case TEMPLATE_FIELD_DIP5: - case TEMPLATE_FIELD_DIP6: - case TEMPLATE_FIELD_DIP7: - data = pr->dip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)]; - data_m = pr->dip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)]; - break; - case TEMPLATE_FIELD_IP_TOS_PROTO: - data = pr->tos_proto; - data_m = pr->tos_proto_m; - break; - case TEMPLATE_FIELD_L4_SPORT: - data = pr->sport; - data_m = pr->sport_m; - break; - case TEMPLATE_FIELD_L4_DPORT: - data = pr->dport; - data_m = pr->dport_m; - break; - case TEMPLATE_FIELD_DSAP_SSAP: - data = pr->dsap_ssap; - data_m = pr->dsap_ssap_m; - break; - case TEMPLATE_FIELD_TCP_INFO: - data = pr->tcp_info; - data_m = pr->tcp_info_m; - break; - case TEMPLATE_FIELD_RANGE_CHK: - pr_warn("Warning: TEMPLATE_FIELD_RANGE_CHK: not configured\n"); - break; - default: - pr_info("%s: unknown field %d\n", __func__, field_type); - } - - /* On the RTL9300, the mask fields are not word aligned! */ - if (!(i % 2)) { - r[5 - i / 2] = data; - r[12 - i / 2] |= ((u32)data_m << 8); - } else { - r[5 - i / 2] |= ((u32)data) << 16; - r[12 - i / 2] |= ((u32)data_m) << 24; - r[11 - i / 2] |= ((u32)data_m) >> 8; - } - } -} - -// Currently not used -// static void rtl930x_read_pie_fixed_fields(u32 r[], struct pie_rule *pr) -// { -// pr->stacking_port = r[6] & BIT(31); -// pr->spn = (r[6] >> 24) & 0x7f; -// pr->mgnt_vlan = r[6] & BIT(23); -// if (pr->phase == PHASE_IACL) -// pr->dmac_hit_sw = r[6] & BIT(22); -// else -// pr->content_too_deep = r[6] & BIT(22); -// pr->not_first_frag = r[6] & BIT(21); -// pr->frame_type_l4 = (r[6] >> 18) & 7; -// pr->frame_type = (r[6] >> 16) & 3; -// pr->otag_fmt = (r[6] >> 15) & 1; -// pr->itag_fmt = (r[6] >> 14) & 1; -// pr->otag_exist = (r[6] >> 13) & 1; -// pr->itag_exist = (r[6] >> 12) & 1; -// pr->frame_type_l2 = (r[6] >> 10) & 3; -// pr->igr_normal_port = (r[6] >> 9) & 1; -// pr->tid = (r[6] >> 8) & 1; - -// pr->stacking_port_m = r[12] & BIT(7); -// pr->spn_m = r[12] & 0x7f; -// pr->mgnt_vlan_m = r[13] & BIT(31); -// if (pr->phase == PHASE_IACL) -// pr->dmac_hit_sw_m = r[13] & BIT(30); -// else -// pr->content_too_deep_m = r[13] & BIT(30); -// pr->not_first_frag_m = r[13] & BIT(29); -// pr->frame_type_l4_m = (r[13] >> 26) & 7; -// pr->frame_type_m = (r[13] >> 24) & 3; -// pr->otag_fmt_m = r[13] & BIT(23); -// pr->itag_fmt_m = r[13] & BIT(22); -// pr->otag_exist_m = r[13] & BIT(21); -// pr->itag_exist_m = r[13] & BIT (20); -// pr->frame_type_l2_m = (r[13] >> 18) & 3; -// pr->igr_normal_port_m = r[13] & BIT(17); -// pr->tid_m = (r[13] >> 16) & 1; - -// pr->valid = r[13] & BIT(15); -// pr->cond_not = r[13] & BIT(14); -// pr->cond_and1 = r[13] & BIT(13); -// pr->cond_and2 = r[13] & BIT(12); -// } - -static void rtl930x_write_pie_fixed_fields(u32 r[], struct pie_rule *pr) -{ - r[6] = pr->stacking_port ? BIT(31) : 0; - r[6] |= ((u32) (pr->spn & 0x7f)) << 24; - r[6] |= pr->mgnt_vlan ? BIT(23) : 0; - if (pr->phase == PHASE_IACL) - r[6] |= pr->dmac_hit_sw ? BIT(22) : 0; - else - r[6] |= pr->content_too_deep ? BIT(22) : 0; - r[6] |= pr->not_first_frag ? BIT(21) : 0; - r[6] |= ((u32) (pr->frame_type_l4 & 0x7)) << 18; - r[6] |= ((u32) (pr->frame_type & 0x3)) << 16; - r[6] |= pr->otag_fmt ? BIT(15) : 0; - r[6] |= pr->itag_fmt ? BIT(14) : 0; - r[6] |= pr->otag_exist ? BIT(13) : 0; - r[6] |= pr->itag_exist ? BIT(12) : 0; - r[6] |= ((u32) (pr->frame_type_l2 & 0x3)) << 10; - r[6] |= pr->igr_normal_port ? BIT(9) : 0; - r[6] |= ((u32) (pr->tid & 0x1)) << 8; - - r[12] |= pr->stacking_port_m ? BIT(7) : 0; - r[12] |= (u32) (pr->spn_m & 0x7f); - r[13] |= pr->mgnt_vlan_m ? BIT(31) : 0; - if (pr->phase == PHASE_IACL) - r[13] |= pr->dmac_hit_sw_m ? BIT(30) : 0; - else - r[13] |= pr->content_too_deep_m ? BIT(30) : 0; - r[13] |= pr->not_first_frag_m ? BIT(29) : 0; - r[13] |= ((u32) (pr->frame_type_l4_m & 0x7)) << 26; - r[13] |= ((u32) (pr->frame_type_m & 0x3)) << 24; - r[13] |= pr->otag_fmt_m ? BIT(23) : 0; - r[13] |= pr->itag_fmt_m ? BIT(22) : 0; - r[13] |= pr->otag_exist_m ? BIT(21) : 0; - r[13] |= pr->itag_exist_m ? BIT(20) : 0; - r[13] |= ((u32) (pr->frame_type_l2_m & 0x3)) << 18; - r[13] |= pr->igr_normal_port_m ? BIT(17) : 0; - r[13] |= ((u32) (pr->tid_m & 0x1)) << 16; - - r[13] |= pr->valid ? BIT(15) : 0; - r[13] |= pr->cond_not ? BIT(14) : 0; - r[13] |= pr->cond_and1 ? BIT(13) : 0; - r[13] |= pr->cond_and2 ? BIT(12) : 0; -} - -static void rtl930x_write_pie_action(u32 r[], struct pie_rule *pr) -{ - /* Either drop or forward */ - if (pr->drop) { - r[14] |= BIT(24) | BIT(25) | BIT(26); /* Do Green, Yellow and Red drops */ - /* Actually DROP, not PERMIT in Green / Yellow / Red */ - r[14] |= BIT(23) | BIT(22) | BIT(20); - } else { - r[14] |= pr->fwd_sel ? BIT(27) : 0; - r[14] |= pr->fwd_act << 18; - r[14] |= BIT(14); /* We overwrite any drop */ - } - if (pr->phase == PHASE_VACL) - r[14] |= pr->fwd_sa_lrn ? BIT(15) : 0; - r[13] |= pr->bypass_sel ? BIT(5) : 0; - r[13] |= pr->nopri_sel ? BIT(4) : 0; - r[13] |= pr->tagst_sel ? BIT(3) : 0; - r[13] |= pr->ovid_sel ? BIT(1) : 0; - r[14] |= pr->ivid_sel ? BIT(31) : 0; - r[14] |= pr->meter_sel ? BIT(30) : 0; - r[14] |= pr->mir_sel ? BIT(29) : 0; - r[14] |= pr->log_sel ? BIT(28) : 0; - - r[14] |= ((u32)(pr->fwd_data & 0x3fff)) << 3; - r[15] |= pr->log_octets ? BIT(31) : 0; - r[15] |= (u32)(pr->meter_data) << 23; - - r[15] |= ((u32)(pr->ivid_act) << 21) & 0x3; - r[15] |= ((u32)(pr->ivid_data) << 9) & 0xfff; - r[16] |= ((u32)(pr->ovid_act) << 30) & 0x3; - r[16] |= ((u32)(pr->ovid_data) & 0xfff) << 16; - r[16] |= (pr->mir_data & 0x3) << 6; - r[17] |= ((u32)(pr->tagst_data) & 0xf) << 28; - r[17] |= ((u32)(pr->nopri_data) & 0x7) << 25; - r[17] |= pr->bypass_ibc_sc ? BIT(16) : 0; -} - -void rtl930x_pie_rule_dump_raw(u32 r[]) -{ - pr_info("Raw IACL table entry:\n"); - pr_info("r 0 - 7: %08x %08x %08x %08x %08x %08x %08x %08x\n", - r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]); - pr_info("r 8 - 15: %08x %08x %08x %08x %08x %08x %08x %08x\n", - r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]); - pr_info("r 16 - 18: %08x %08x %08x\n", r[16], r[17], r[18]); - pr_info("Match : %08x %08x %08x %08x %08x %08x\n", r[0], r[1], r[2], r[3], r[4], r[5]); - pr_info("Fixed : %06x\n", r[6] >> 8); - pr_info("Match M: %08x %08x %08x %08x %08x %08x\n", - (r[6] << 24) | (r[7] >> 8), (r[7] << 24) | (r[8] >> 8), (r[8] << 24) | (r[9] >> 8), - (r[9] << 24) | (r[10] >> 8), (r[10] << 24) | (r[11] >> 8), - (r[11] << 24) | (r[12] >> 8)); - pr_info("R[13]: %08x\n", r[13]); - pr_info("Fixed M: %06x\n", ((r[12] << 16) | (r[13] >> 16)) & 0xffffff); - pr_info("Valid / not / and1 / and2 : %1x\n", (r[13] >> 12) & 0xf); - pr_info("r 13-16: %08x %08x %08x %08x\n", r[13], r[14], r[15], r[16]); -} - -static int rtl930x_pie_rule_write(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr) -{ - /* Access IACL table (2) via register 0 */ - struct table_reg *q = rtl_table_get(RTL9300_TBL_0, 2); - u32 r[19]; - int block = idx / PIE_BLOCK_SIZE; - u32 t_select = sw_r32(RTL930X_PIE_BLK_TMPLTE_CTRL(block)); - - pr_debug("%s: %d, t_select: %08x\n", __func__, idx, t_select); - - for (int i = 0; i < 19; i++) - r[i] = 0; - - if (!pr->valid) { - rtl_table_write(q, idx); - rtl_table_release(q); - return 0; - } - rtl930x_write_pie_fixed_fields(r, pr); - - pr_debug("%s: template %d\n", __func__, (t_select >> (pr->tid * 4)) & 0xf); - rtl930x_write_pie_templated(r, pr, fixed_templates[(t_select >> (pr->tid * 4)) & 0xf]); - - rtl930x_write_pie_action(r, pr); - -/* rtl930x_pie_rule_dump_raw(r); */ - - for (int i = 0; i < 19; i++) - sw_w32(r[i], rtl_table_data(q, i)); - - rtl_table_write(q, idx); - rtl_table_release(q); - - return 0; -} - -static bool rtl930x_pie_templ_has(int t, enum template_field_id field_type) -{ - for (int i = 0; i < N_FIXED_FIELDS; i++) { - enum template_field_id ft = fixed_templates[t][i]; - if (field_type == ft) - return true; - } - - return false; -} - -/* Verify that the rule pr is compatible with a given template t in block block - * Note that this function is SoC specific since the values of e.g. TEMPLATE_FIELD_SIP0 - * depend on the SoC - */ -static int rtl930x_pie_verify_template(struct rtl838x_switch_priv *priv, - struct pie_rule *pr, int t, int block) -{ - int i; - - if (!pr->is_ipv6 && pr->sip_m && !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_SIP0)) - return -1; - - if (!pr->is_ipv6 && pr->dip_m && !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_DIP0)) - return -1; - - if (pr->is_ipv6) { - if ((pr->sip6_m.s6_addr32[0] || - pr->sip6_m.s6_addr32[1] || - pr->sip6_m.s6_addr32[2] || - pr->sip6_m.s6_addr32[3]) && - !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_SIP2)) - return -1; - if ((pr->dip6_m.s6_addr32[0] || - pr->dip6_m.s6_addr32[1] || - pr->dip6_m.s6_addr32[2] || - pr->dip6_m.s6_addr32[3]) && - !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_DIP2)) - return -1; - } - - if (ether_addr_to_u64(pr->smac) && !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_SMAC0)) - return -1; - - if (ether_addr_to_u64(pr->dmac) && !rtl930x_pie_templ_has(t, TEMPLATE_FIELD_DMAC0)) - return -1; - - /* TODO: Check more */ - - i = find_first_zero_bit(&priv->pie_use_bm[block * 4], PIE_BLOCK_SIZE); - - if (i >= PIE_BLOCK_SIZE) - return -1; - - return i + PIE_BLOCK_SIZE * block; -} - -static int rtl930x_pie_rule_add(struct rtl838x_switch_priv *priv, struct pie_rule *pr) -{ - int idx, block, j, t; - int min_block = 0; - int max_block = priv->n_pie_blocks / 2; - - if (pr->is_egress) { - min_block = max_block; - max_block = priv->n_pie_blocks; - } - pr_debug("In %s\n", __func__); - - mutex_lock(&priv->pie_mutex); - - for (block = min_block; block < max_block; block++) { - for (j = 0; j < 2; j++) { - t = (sw_r32(RTL930X_PIE_BLK_TMPLTE_CTRL(block)) >> (j * 4)) & 0xf; - pr_debug("Testing block %d, template %d, template id %d\n", block, j, t); - pr_debug("%s: %08x\n", - __func__, sw_r32(RTL930X_PIE_BLK_TMPLTE_CTRL(block))); - idx = rtl930x_pie_verify_template(priv, pr, t, block); - if (idx >= 0) - break; - } - if (j < 2) - break; - } - - if (block >= priv->n_pie_blocks) { - mutex_unlock(&priv->pie_mutex); - return -EOPNOTSUPP; - } - - pr_debug("Using block: %d, index %d, template-id %d\n", block, idx, j); - set_bit(idx, priv->pie_use_bm); - - pr->valid = true; - pr->tid = j; /* Mapped to template number */ - pr->tid_m = 0x1; - pr->id = idx; - - rtl930x_pie_lookup_enable(priv, idx); - rtl930x_pie_rule_write(priv, idx, pr); - - mutex_unlock(&priv->pie_mutex); - return 0; -} - -/* Delete a range of Packet Inspection Engine rules */ -static int rtl930x_pie_rule_del(struct rtl838x_switch_priv *priv, int index_from, int index_to) -{ - u32 v = (index_from << 1)| (index_to << 12 ) | BIT(0); - - pr_debug("%s: from %d to %d\n", __func__, index_from, index_to); - mutex_lock(&priv->reg_mutex); - - /* Write from-to and execute bit into control register */ - sw_w32(v, RTL930X_PIE_CLR_CTRL); - - /* Wait until command has completed */ - do { - } while (sw_r32(RTL930X_PIE_CLR_CTRL) & BIT(0)); - - mutex_unlock(&priv->reg_mutex); - return 0; -} - -static void rtl930x_pie_rule_rm(struct rtl838x_switch_priv *priv, struct pie_rule *pr) -{ - int idx = pr->id; - - rtl930x_pie_rule_del(priv, idx, idx); - clear_bit(idx, priv->pie_use_bm); -} - -static void rtl930x_pie_init(struct rtl838x_switch_priv *priv) -{ - u32 template_selectors; - - mutex_init(&priv->pie_mutex); - - pr_info("%s\n", __func__); - /* Enable ACL lookup on all ports, including CPU_PORT */ - for (int i = 0; i <= priv->cpu_port; i++) - sw_w32(1, RTL930X_ACL_PORT_LOOKUP_CTRL(i)); - - /* Include IPG in metering */ - sw_w32_mask(0, 1, RTL930X_METER_GLB_CTRL); - - /* Delete all present rules, block size is 128 on all SoC families */ - rtl930x_pie_rule_del(priv, 0, priv->n_pie_blocks * 128 - 1); - - /* Assign blocks 0-7 to VACL phase (bit = 0), blocks 8-15 to IACL (bit = 1) */ - sw_w32(0xff00, RTL930X_PIE_BLK_PHASE_CTRL); - - /* Enable predefined templates 0, 1 for first quarter of all blocks */ - template_selectors = 0 | (1 << 4); - for (int i = 0; i < priv->n_pie_blocks / 4; i++) - sw_w32(template_selectors, RTL930X_PIE_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 2, 3 for second quarter of all blocks */ - template_selectors = 2 | (3 << 4); - for (int i = priv->n_pie_blocks / 4; i < priv->n_pie_blocks / 2; i++) - sw_w32(template_selectors, RTL930X_PIE_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 0, 1 for third half of all blocks */ - template_selectors = 0 | (1 << 4); - for (int i = priv->n_pie_blocks / 2; i < priv->n_pie_blocks * 3 / 4; i++) - sw_w32(template_selectors, RTL930X_PIE_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 2, 3 for fourth quater of all blocks */ - template_selectors = 2 | (3 << 4); - for (int i = priv->n_pie_blocks * 3 / 4; i < priv->n_pie_blocks; i++) - sw_w32(template_selectors, RTL930X_PIE_BLK_TMPLTE_CTRL(i)); - -} - -/* Sets up an egress interface for L3 actions - * Actions for ip4/6_icmp_redirect, ip4/6_pbr_icmp_redirect are: - * 0: FORWARD, 1: DROP, 2: TRAP2CPU, 3: COPY2CPU, 4: TRAP2MASTERCPU 5: COPY2MASTERCPU - * 6: HARDDROP - * idx is the index in the HW interface table: idx < 0x80 - */ -static void rtl930x_set_l3_egress_intf(int idx, struct rtl838x_l3_intf *intf) -{ - u32 u, v; - /* Read L3_EGR_INTF table (4) via register RTL9300_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 4); - - /* The table has 2 registers */ - u = (intf->vid & 0xfff) << 9; - u |= (intf->smac_idx & 0x3f) << 3; - u |= (intf->ip4_mtu_id & 0x7); - - v = (intf->ip6_mtu_id & 0x7) << 28; - v |= (intf->ttl_scope & 0xff) << 20; - v |= (intf->hl_scope & 0xff) << 12; - v |= (intf->ip4_icmp_redirect & 0x7) << 9; - v |= (intf->ip6_icmp_redirect & 0x7)<< 6; - v |= (intf->ip4_pbr_icmp_redirect & 0x7) << 3; - v |= (intf->ip6_pbr_icmp_redirect & 0x7); - - sw_w32(u, rtl_table_data(r, 0)); - sw_w32(v, rtl_table_data(r, 1)); - - pr_info("%s writing to index %d: %08x %08x\n", __func__, idx, u, v); - rtl_table_write(r, idx & 0x7f); - rtl_table_release(r); -} - -/* Reads a MAC entry for L3 termination as entry point for routing - * from the hardware table - * idx is the index into the L3_ROUTER_MAC table - */ -static void rtl930x_get_l3_router_mac(u32 idx, struct rtl93xx_rt_mac *m) -{ - u32 v, w; - /* Read L3_ROUTER_MAC table (0) via register RTL9300_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 0); - - rtl_table_read(r, idx); - /* The table has a size of 7 registers, 64 entries */ - v = sw_r32(rtl_table_data(r, 0)); - w = sw_r32(rtl_table_data(r, 3)); - m->valid = !!(v & BIT(20)); - if (!m->valid) - goto out; - - m->p_type = !!(v & BIT(19)); - m->p_id = (v >> 13) & 0x3f; /* trunk id of port */ - m->vid = v & 0xfff; - m->vid_mask = w & 0xfff; - m->action = sw_r32(rtl_table_data(r, 6)) & 0x7; - m->mac_mask = ((((u64)sw_r32(rtl_table_data(r, 5))) << 32) & 0xffffffffffffULL) | - (sw_r32(rtl_table_data(r, 4))); - m->mac = ((((u64)sw_r32(rtl_table_data(r, 1))) << 32) & 0xffffffffffffULL) | - (sw_r32(rtl_table_data(r, 2))); - /* Bits L3_INTF and BMSK_L3_INTF are 0 */ - -out: - rtl_table_release(r); -} - -/* Writes a MAC entry for L3 termination as entry point for routing - * into the hardware table - * idx is the index into the L3_ROUTER_MAC table - */ -static void rtl930x_set_l3_router_mac(u32 idx, struct rtl93xx_rt_mac *m) -{ - u32 v, w; - /* Read L3_ROUTER_MAC table (0) via register RTL9300_TBL_1 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_1, 0); - - /* The table has a size of 7 registers, 64 entries */ - v = BIT(20); /* mac entry valid, port type is 0: individual */ - v |= (m->p_id & 0x3f) << 13; - v |= (m->vid & 0xfff); /* Set the interface_id to the vlan id */ - - w = m->vid_mask; - w |= (m->p_id_mask & 0x3f) << 13; - - sw_w32(v, rtl_table_data(r, 0)); - sw_w32(w, rtl_table_data(r, 3)); - - /* Set MAC address, L3_INTF (bit 12 in register 1) needs to be 0 */ - sw_w32((u32)(m->mac), rtl_table_data(r, 2)); - sw_w32(m->mac >> 32, rtl_table_data(r, 1)); - - /* Set MAC address mask, BMSK_L3_INTF (bit 12 in register 5) needs to be 0 */ - sw_w32((u32)(m->mac_mask >> 32), rtl_table_data(r, 4)); - sw_w32((u32)m->mac_mask, rtl_table_data(r, 5)); - - sw_w32(m->action & 0x7, rtl_table_data(r, 6)); - - pr_debug("%s writing index %d: %08x %08x %08x %08x %08x %08x %08x\n", __func__, idx, - sw_r32(rtl_table_data(r, 0)), sw_r32(rtl_table_data(r, 1)), sw_r32(rtl_table_data(r, 2)), - sw_r32(rtl_table_data(r, 3)), sw_r32(rtl_table_data(r, 4)), sw_r32(rtl_table_data(r, 5)), - sw_r32(rtl_table_data(r, 6)) - ); - rtl_table_write(r, idx); - rtl_table_release(r); -} - -/* Get the Destination-MAC of an L3 egress interface or the Source MAC for routed packets - * from the SoC's L3_EGR_INTF_MAC table - * Indexes 0-2047 are DMACs, 2048+ are SMACs - */ -static u64 rtl930x_get_l3_egress_mac(u32 idx) -{ - u64 mac; - /* Read L3_EGR_INTF_MAC table (2) via register RTL9300_TBL_2 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_2, 2); - - rtl_table_read(r, idx); - /* The table has a size of 2 registers */ - mac = sw_r32(rtl_table_data(r, 0)); - mac <<= 32; - mac |= sw_r32(rtl_table_data(r, 1)); - rtl_table_release(r); - - return mac; -} - -/* Set the Destination-MAC of a route or the Source MAC of an L3 egress interface - * in the SoC's L3_EGR_INTF_MAC table - * Indexes 0-2047 are DMACs, 2048+ are SMACs - */ -static void rtl930x_set_l3_egress_mac(u32 idx, u64 mac) -{ - /* Access L3_EGR_INTF_MAC table (2) via register RTL9300_TBL_2 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_2, 2); - - /* The table has a size of 2 registers */ - sw_w32(mac >> 32, rtl_table_data(r, 0)); - sw_w32(mac, rtl_table_data(r, 1)); - - pr_debug("%s: setting index %d to %016llx\n", __func__, idx, mac); - rtl_table_write(r, idx); - rtl_table_release(r); -} - -/* Configure L3 routing settings of the device: - * - MTUs - * - Egress interface - * - The router's MAC address on which routed packets are expected - * - MAC addresses used as source macs of routed packets - */ -int rtl930x_l3_setup(struct rtl838x_switch_priv *priv) -{ - /* Setup MTU with id 0 for default interface */ - for (int i = 0; i < MAX_INTF_MTUS; i++) - priv->intf_mtu_count[i] = priv->intf_mtus[i] = 0; - - priv->intf_mtu_count[0] = 0; /* Needs to stay forever */ - priv->intf_mtus[0] = DEFAULT_MTU; - sw_w32_mask(0xffff, DEFAULT_MTU, RTL930X_L3_IP_MTU_CTRL(0)); - sw_w32_mask(0xffff, DEFAULT_MTU, RTL930X_L3_IP6_MTU_CTRL(0)); - priv->intf_mtus[1] = DEFAULT_MTU; - sw_w32_mask(0xffff0000, DEFAULT_MTU << 16, RTL930X_L3_IP_MTU_CTRL(0)); - sw_w32_mask(0xffff0000, DEFAULT_MTU << 16, RTL930X_L3_IP6_MTU_CTRL(0)); - - sw_w32_mask(0xffff, DEFAULT_MTU, RTL930X_L3_IP_MTU_CTRL(1)); - sw_w32_mask(0xffff, DEFAULT_MTU, RTL930X_L3_IP6_MTU_CTRL(1)); - sw_w32_mask(0xffff0000, DEFAULT_MTU << 16, RTL930X_L3_IP_MTU_CTRL(1)); - sw_w32_mask(0xffff0000, DEFAULT_MTU << 16, RTL930X_L3_IP6_MTU_CTRL(1)); - - /* Clear all source port MACs */ - for (int i = 0; i < MAX_SMACS; i++) - rtl930x_set_l3_egress_mac(L3_EGRESS_DMACS + i, 0ULL); - - /* Configure the default L3 hash algorithm */ - sw_w32_mask(BIT(2), 0, RTL930X_L3_HOST_TBL_CTRL); /* Algorithm selection 0 = 0 */ - sw_w32_mask(0, BIT(3), RTL930X_L3_HOST_TBL_CTRL); /* Algorithm selection 1 = 1 */ - - pr_info("L3_IPUC_ROUTE_CTRL %08x, IPMC_ROUTE %08x, IP6UC_ROUTE %08x, IP6MC_ROUTE %08x\n", - sw_r32(RTL930X_L3_IPUC_ROUTE_CTRL), sw_r32(RTL930X_L3_IPMC_ROUTE_CTRL), - sw_r32(RTL930X_L3_IP6UC_ROUTE_CTRL), sw_r32(RTL930X_L3_IP6MC_ROUTE_CTRL)); - sw_w32_mask(0, 1, RTL930X_L3_IPUC_ROUTE_CTRL); - sw_w32_mask(0, 1, RTL930X_L3_IP6UC_ROUTE_CTRL); - sw_w32_mask(0, 1, RTL930X_L3_IPMC_ROUTE_CTRL); - sw_w32_mask(0, 1, RTL930X_L3_IP6MC_ROUTE_CTRL); - - sw_w32(0x00002001, RTL930X_L3_IPUC_ROUTE_CTRL); - sw_w32(0x00014581, RTL930X_L3_IP6UC_ROUTE_CTRL); - sw_w32(0x00000501, RTL930X_L3_IPMC_ROUTE_CTRL); - sw_w32(0x00012881, RTL930X_L3_IP6MC_ROUTE_CTRL); - - pr_info("L3_IPUC_ROUTE_CTRL %08x, IPMC_ROUTE %08x, IP6UC_ROUTE %08x, IP6MC_ROUTE %08x\n", - sw_r32(RTL930X_L3_IPUC_ROUTE_CTRL), sw_r32(RTL930X_L3_IPMC_ROUTE_CTRL), - sw_r32(RTL930X_L3_IP6UC_ROUTE_CTRL), sw_r32(RTL930X_L3_IP6MC_ROUTE_CTRL)); - - /* Trap non-ip traffic to the CPU-port (e.g. ARP so we stay reachable) */ - sw_w32_mask(0x3 << 8, 0x1 << 8, RTL930X_L3_IP_ROUTE_CTRL); - pr_info("L3_IP_ROUTE_CTRL %08x\n", sw_r32(RTL930X_L3_IP_ROUTE_CTRL)); - - /* PORT_ISO_RESTRICT_ROUTE_CTRL? */ - - /* Do not use prefix route 0 because of HW limitations */ - set_bit(0, priv->route_use_bm); - - return 0; -} - -static u32 rtl930x_packet_cntr_read(int counter) -{ - u32 v; - - /* Read LOG table (3) via register RTL9300_TBL_0 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 3); - - pr_debug("In %s, id %d\n", __func__, counter); - rtl_table_read(r, counter / 2); - - pr_debug("Registers: %08x %08x\n", - sw_r32(rtl_table_data(r, 0)), sw_r32(rtl_table_data(r, 1))); - /* The table has a size of 2 registers */ - if (counter % 2) - v = sw_r32(rtl_table_data(r, 0)); - else - v = sw_r32(rtl_table_data(r, 1)); - - rtl_table_release(r); - - return v; -} - -static void rtl930x_packet_cntr_clear(int counter) -{ - /* Access LOG table (3) via register RTL9300_TBL_0 */ - struct table_reg *r = rtl_table_get(RTL9300_TBL_0, 3); - - pr_info("In %s, id %d\n", __func__, counter); - /* The table has a size of 2 registers */ - if (counter % 2) - sw_w32(0, rtl_table_data(r, 0)); - else - sw_w32(0, rtl_table_data(r, 1)); - - rtl_table_write(r, counter / 2); - - rtl_table_release(r); -} - -void rtl930x_vlan_port_keep_tag_set(int port, bool keep_outer, bool keep_inner) -{ - sw_w32(FIELD_PREP(RTL930X_VLAN_PORT_TAG_STS_CTRL_EGR_OTAG_STS_MASK, - keep_outer ? RTL930X_VLAN_PORT_TAG_STS_TAGGED : RTL930X_VLAN_PORT_TAG_STS_UNTAG) | - FIELD_PREP(RTL930X_VLAN_PORT_TAG_STS_CTRL_EGR_ITAG_STS_MASK, - keep_inner ? RTL930X_VLAN_PORT_TAG_STS_TAGGED : RTL930X_VLAN_PORT_TAG_STS_UNTAG), - RTL930X_VLAN_PORT_TAG_STS_CTRL(port)); -} - -void rtl930x_vlan_port_pvidmode_set(int port, enum pbvlan_type type, enum pbvlan_mode mode) -{ - if (type == PBVLAN_TYPE_INNER) - sw_w32_mask(0x3, mode, RTL930X_VLAN_PORT_PB_VLAN + (port << 2)); - else - sw_w32_mask(0x3 << 14, mode << 14 ,RTL930X_VLAN_PORT_PB_VLAN + (port << 2)); -} - -void rtl930x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid) -{ - if (type == PBVLAN_TYPE_INNER) - sw_w32_mask(0xfff << 2, pvid << 2, RTL930X_VLAN_PORT_PB_VLAN + (port << 2)); - else - sw_w32_mask(0xfff << 16, pvid << 16, RTL930X_VLAN_PORT_PB_VLAN + (port << 2)); -} - -static int rtl930x_set_ageing_time(unsigned long msec) -{ - int t = sw_r32(RTL930X_L2_AGE_CTRL); - - t &= 0x1FFFFF; - t = (t * 7) / 10; - pr_debug("L2 AGING time: %d sec\n", t); - - t = (msec / 100 + 6) / 7; - t = t > 0x1FFFFF ? 0x1FFFFF : t; - sw_w32_mask(0x1FFFFF, t, RTL930X_L2_AGE_CTRL); - pr_debug("Dynamic aging for ports: %x\n", sw_r32(RTL930X_L2_PORT_AGE_CTRL)); - - return 0; -} - -static void rtl930x_set_igr_filter(int port, enum igr_filter state) -{ - sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1), - RTL930X_VLAN_PORT_IGR_FLTR + (((port >> 4) << 2))); -} - -static void rtl930x_set_egr_filter(int port, enum egr_filter state) -{ - sw_w32_mask(0x1 << (port % 0x1D), state << (port % 0x1D), - RTL930X_VLAN_PORT_EGR_FLTR + (((port / 29) << 2))); -} - -void rtl930x_set_distribution_algorithm(int group, int algoidx, u32 algomsk) -{ - u32 l3shift = 0; - u32 newmask = 0; - - /* TODO: for now we set algoidx to 0 */ - algoidx = 0; - if (algomsk & TRUNK_DISTRIBUTION_ALGO_SIP_BIT) { - l3shift = 4; - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SIP_BIT; - } - if (algomsk & TRUNK_DISTRIBUTION_ALGO_DIP_BIT) { - l3shift = 4; - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_DIP_BIT; - } - if (algomsk & TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT) { - l3shift = 4; - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT; - } - if (algomsk & TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT) { - l3shift = 4; - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT; - } - - if (l3shift == 4) { - if (algomsk & TRUNK_DISTRIBUTION_ALGO_SMAC_BIT) - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SMAC_BIT; - - if (algomsk & TRUNK_DISTRIBUTION_ALGO_DMAC_BIT) - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_DMAC_BIT; - } else { - if (algomsk & TRUNK_DISTRIBUTION_ALGO_SMAC_BIT) - newmask |= TRUNK_DISTRIBUTION_ALGO_L2_SMAC_BIT; - if (algomsk & TRUNK_DISTRIBUTION_ALGO_DMAC_BIT) - newmask |= TRUNK_DISTRIBUTION_ALGO_L2_DMAC_BIT; - } - - sw_w32(newmask << l3shift, RTL930X_TRK_HASH_CTRL + (algoidx << 2)); -} - -static void rtl930x_led_init(struct rtl838x_switch_priv *priv) -{ - struct device_node *node; - u32 pm = 0; - - pr_info("%s called\n", __func__); - node = of_find_compatible_node(NULL, NULL, "realtek,rtl9300-leds"); - if (!node) { - pr_info("%s No compatible LED node found\n", __func__); - return; - } - - for (int set = 0; set < 4; set++) { - char set_name[16] = {0}; - u32 set_config[4]; - int leds_in_this_set = 0; - - /* Reset LED set configuration */ - sw_w32(0, RTL930X_LED_SETX_0_CTRL(set)); - sw_w32(0, RTL930X_LED_SETX_1_CTRL(set)); - - /** - * Each led set has 4 number of leds, and each LED is configured with 16 bits - * So each 32bit register holds configuration for 2 leds - * And therefore each set requires 2 registers for configuring 4 LEDs - * - */ - sprintf(set_name, "led_set%d", set); - leds_in_this_set = of_property_count_u32_elems(node, set_name); - - if (leds_in_this_set == 0 || leds_in_this_set > sizeof(set_config)) { - pr_err("%s led_set configuration invalid skipping over this set\n", __func__); - continue; - } - - if (of_property_read_u32_array(node, set_name, set_config, leds_in_this_set)) { - break; - } - - /* Write configuration as per number of LEDs */ - for (int i=0, led = leds_in_this_set-1; led >= 0; led--,i++) { - sw_w32_mask(0xffff << RTL930X_LED_SET_LEDX_SHIFT(led), - (0xffff & set_config[i]) << RTL930X_LED_SET_LEDX_SHIFT(led), - RTL930X_LED_SETX_LEDY(set, led)); - } - } - - for (int i = 0; i < priv->cpu_port; i++) { - int pos = (i << 1) % 32; - u32 set; - - sw_w32_mask(0x3 << pos, 0, RTL930X_LED_PORT_FIB_SET_SEL_CTRL(i)); - sw_w32_mask(0x3 << pos, 0, RTL930X_LED_PORT_COPR_SET_SEL_CTRL(i)); - - if (!priv->ports[i].phy) - continue; - - /* 0x0 = 1 led, 0x1 = 2 leds, 0x2 = 3 leds, 0x3 = 4 leds per port */ - sw_w32_mask(0x3 << pos, (priv->ports[i].leds_on_this_port -1) << pos, RTL930X_LED_PORT_NUM_CTRL(i)); - - pm |= BIT(i); - - set = priv->ports[i].led_set; - sw_w32_mask(0, set << pos, RTL930X_LED_PORT_COPR_SET_SEL_CTRL(i)); - sw_w32_mask(0, set << pos, RTL930X_LED_PORT_FIB_SET_SEL_CTRL(i)); - } - - /* Set LED mode to serial (0x1) */ - sw_w32_mask(0x3, 0x1, RTL930X_LED_GLB_CTRL); - - /* Set LED active state */ - if (of_property_read_bool(node, "active-low")) - sw_w32_mask(RTL930X_LED_GLB_ACTIVE_LOW, 0, RTL930X_LED_GLB_CTRL); - else - sw_w32_mask(0, RTL930X_LED_GLB_ACTIVE_LOW, RTL930X_LED_GLB_CTRL); - - /* Set port type masks */ - sw_w32(pm, RTL930X_LED_PORT_COPR_MASK_CTRL); - sw_w32(pm, RTL930X_LED_PORT_FIB_MASK_CTRL); - sw_w32(pm, RTL930X_LED_PORT_COMBO_MASK_CTRL); - - for (int i = 0; i < 24; i++) - pr_info("%s %08x: %08x\n",__func__, 0xbb00cc00 + i * 4, sw_r32(0xcc00 + i * 4)); -} - -const struct rtl838x_reg rtl930x_reg = { - .mask_port_reg_be = rtl838x_mask_port_reg, - .set_port_reg_be = rtl838x_set_port_reg, - .get_port_reg_be = rtl838x_get_port_reg, - .mask_port_reg_le = rtl838x_mask_port_reg, - .set_port_reg_le = rtl838x_set_port_reg, - .get_port_reg_le = rtl838x_get_port_reg, - .stat_port_rst = RTL930X_STAT_PORT_RST, - .stat_rst = RTL930X_STAT_RST, - .stat_port_std_mib = RTL930X_STAT_PORT_MIB_CNTR, - .traffic_enable = rtl930x_traffic_enable, - .traffic_disable = rtl930x_traffic_disable, - .traffic_get = rtl930x_traffic_get, - .traffic_set = rtl930x_traffic_set, - .l2_ctrl_0 = RTL930X_L2_CTRL, - .l2_ctrl_1 = RTL930X_L2_AGE_CTRL, - .l2_port_aging_out = RTL930X_L2_PORT_AGE_CTRL, - .set_ageing_time = rtl930x_set_ageing_time, - .smi_poll_ctrl = RTL930X_SMI_POLL_CTRL, /* TODO: Difference to RTL9300_SMI_PRVTE_POLLING_CTRL */ - .l2_tbl_flush_ctrl = RTL930X_L2_TBL_FLUSH_CTRL, - .exec_tbl0_cmd = rtl930x_exec_tbl0_cmd, - .exec_tbl1_cmd = rtl930x_exec_tbl1_cmd, - .tbl_access_data_0 = rtl930x_tbl_access_data_0, - .isr_glb_src = RTL930X_ISR_GLB, - .isr_port_link_sts_chg = RTL930X_ISR_PORT_LINK_STS_CHG, - .imr_port_link_sts_chg = RTL930X_IMR_PORT_LINK_STS_CHG, - .imr_glb = RTL930X_IMR_GLB, - .vlan_tables_read = rtl930x_vlan_tables_read, - .vlan_set_tagged = rtl930x_vlan_set_tagged, - .vlan_set_untagged = rtl930x_vlan_set_untagged, - .vlan_profile_dump = rtl930x_vlan_profile_dump, - .vlan_profile_setup = rtl930x_vlan_profile_setup, - .vlan_fwd_on_inner = rtl930x_vlan_fwd_on_inner, - .set_vlan_igr_filter = rtl930x_set_igr_filter, - .set_vlan_egr_filter = rtl930x_set_egr_filter, - .stp_get = rtl930x_stp_get, - .stp_set = rtl930x_stp_set, - .mac_force_mode_ctrl = rtl930x_mac_force_mode_ctrl, - .mac_port_ctrl = rtl930x_mac_port_ctrl, - .l2_port_new_salrn = rtl930x_l2_port_new_salrn, - .l2_port_new_sa_fwd = rtl930x_l2_port_new_sa_fwd, - .mir_ctrl = RTL930X_MIR_CTRL, - .mir_dpm = RTL930X_MIR_DPM_CTRL, - .mir_spm = RTL930X_MIR_SPM_CTRL, - .mac_link_sts = RTL930X_MAC_LINK_STS, - .mac_link_dup_sts = RTL930X_MAC_LINK_DUP_STS, - .mac_link_spd_sts = rtl930x_mac_link_spd_sts, - .mac_rx_pause_sts = RTL930X_MAC_RX_PAUSE_STS, - .mac_tx_pause_sts = RTL930X_MAC_TX_PAUSE_STS, - .read_l2_entry_using_hash = rtl930x_read_l2_entry_using_hash, - .write_l2_entry_using_hash = rtl930x_write_l2_entry_using_hash, - .read_cam = rtl930x_read_cam, - .write_cam = rtl930x_write_cam, - .vlan_port_keep_tag_set = rtl930x_vlan_port_keep_tag_set, - .vlan_port_pvidmode_set = rtl930x_vlan_port_pvidmode_set, - .vlan_port_pvid_set = rtl930x_vlan_port_pvid_set, - .trk_mbr_ctr = rtl930x_trk_mbr_ctr, - .rma_bpdu_fld_pmask = RTL930X_RMA_BPDU_FLD_PMSK, - .init_eee = rtl930x_init_eee, - .port_eee_set = rtl930x_port_eee_set, - .eee_port_ability = rtl930x_eee_port_ability, - .l2_hash_seed = rtl930x_l2_hash_seed, - .l2_hash_key = rtl930x_l2_hash_key, - .read_mcast_pmask = rtl930x_read_mcast_pmask, - .write_mcast_pmask = rtl930x_write_mcast_pmask, - .pie_init = rtl930x_pie_init, - .pie_rule_write = rtl930x_pie_rule_write, - .pie_rule_add = rtl930x_pie_rule_add, - .pie_rule_rm = rtl930x_pie_rule_rm, - .l2_learning_setup = rtl930x_l2_learning_setup, - .packet_cntr_read = rtl930x_packet_cntr_read, - .packet_cntr_clear = rtl930x_packet_cntr_clear, - .route_read = rtl930x_route_read, - .route_write = rtl930x_route_write, - .host_route_write = rtl930x_host_route_write, - .l3_setup = rtl930x_l3_setup, - .set_l3_nexthop = rtl930x_set_l3_nexthop, - .get_l3_nexthop = rtl930x_get_l3_nexthop, - .get_l3_egress_mac = rtl930x_get_l3_egress_mac, - .set_l3_egress_mac = rtl930x_set_l3_egress_mac, - .find_l3_slot = rtl930x_find_l3_slot, - .route_lookup_hw = rtl930x_route_lookup_hw, - .get_l3_router_mac = rtl930x_get_l3_router_mac, - .set_l3_router_mac = rtl930x_set_l3_router_mac, - .set_l3_egress_intf = rtl930x_set_l3_egress_intf, - .set_distribution_algorithm = rtl930x_set_distribution_algorithm, - .led_init = rtl930x_led_init, -}; diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl931x.c deleted file mode 100644 index 2ba3a7819d64f9..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/rtl931x.c +++ /dev/null @@ -1,1694 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include - -#include "rtl83xx.h" - -#define RTL931X_VLAN_PORT_TAG_STS_INTERNAL 0x0 -#define RTL931X_VLAN_PORT_TAG_STS_UNTAG 0x1 -#define RTL931X_VLAN_PORT_TAG_STS_TAGGED 0x2 -#define RTL931X_VLAN_PORT_TAG_STS_PRIORITY_TAGGED 0x3 - -#define RTL931X_VLAN_PORT_TAG_CTRL_BASE 0x4860 -/* port 0-56 */ -#define RTL931X_VLAN_PORT_TAG_CTRL(port) \ - RTL931X_VLAN_PORT_TAG_CTRL_BASE + (port << 2) -#define RTL931X_VLAN_PORT_TAG_EGR_OTAG_STS_MASK GENMASK(13,12) -#define RTL931X_VLAN_PORT_TAG_EGR_ITAG_STS_MASK GENMASK(11,10) -#define RTL931X_VLAN_PORT_TAG_EGR_OTAG_KEEP_MASK GENMASK(9,9) -#define RTL931X_VLAN_PORT_TAG_EGR_ITAG_KEEP_MASK GENMASK(8,8) -#define RTL931X_VLAN_PORT_TAG_IGR_OTAG_KEEP_MASK GENMASK(7,7) -#define RTL931X_VLAN_PORT_TAG_IGR_ITAG_KEEP_MASK GENMASK(6,6) -#define RTL931X_VLAN_PORT_TAG_OTPID_IDX_MASK GENMASK(5,4) -#define RTL931X_VLAN_PORT_TAG_OTPID_KEEP_MASK GENMASK(3,3) -#define RTL931X_VLAN_PORT_TAG_ITPID_IDX_MASK GENMASK(2,1) -#define RTL931X_VLAN_PORT_TAG_ITPID_KEEP_MASK GENMASK(0,0) - -extern struct mutex smi_lock; -extern struct rtl83xx_soc_info soc_info; - -/* Definition of the RTL931X-specific template field IDs as used in the PIE */ -enum template_field_id { - TEMPLATE_FIELD_SPM0 = 1, - TEMPLATE_FIELD_SPM1 = 2, - TEMPLATE_FIELD_SPM2 = 3, - TEMPLATE_FIELD_SPM3 = 4, - TEMPLATE_FIELD_DMAC0 = 9, - TEMPLATE_FIELD_DMAC1 = 10, - TEMPLATE_FIELD_DMAC2 = 11, - TEMPLATE_FIELD_SMAC0 = 12, - TEMPLATE_FIELD_SMAC1 = 13, - TEMPLATE_FIELD_SMAC2 = 14, - TEMPLATE_FIELD_ETHERTYPE = 15, - TEMPLATE_FIELD_OTAG = 16, - TEMPLATE_FIELD_ITAG = 17, - TEMPLATE_FIELD_SIP0 = 18, - TEMPLATE_FIELD_SIP1 = 19, - TEMPLATE_FIELD_DIP0 = 20, - TEMPLATE_FIELD_DIP1 = 21, - TEMPLATE_FIELD_IP_TOS_PROTO = 22, - TEMPLATE_FIELD_L4_SPORT = 23, - TEMPLATE_FIELD_L4_DPORT = 24, - TEMPLATE_FIELD_L34_HEADER = 25, - TEMPLATE_FIELD_TCP_INFO = 26, - TEMPLATE_FIELD_SIP2 = 34, - TEMPLATE_FIELD_SIP3 = 35, - TEMPLATE_FIELD_SIP4 = 36, - TEMPLATE_FIELD_SIP5 = 37, - TEMPLATE_FIELD_SIP6 = 38, - TEMPLATE_FIELD_SIP7 = 39, - TEMPLATE_FIELD_DIP2 = 42, - TEMPLATE_FIELD_DIP3 = 43, - TEMPLATE_FIELD_DIP4 = 44, - TEMPLATE_FIELD_DIP5 = 45, - TEMPLATE_FIELD_DIP6 = 46, - TEMPLATE_FIELD_DIP7 = 47, - TEMPLATE_FIELD_FLOW_LABEL = 49, - TEMPLATE_FIELD_DSAP_SSAP = 50, - TEMPLATE_FIELD_FWD_VID = 52, - TEMPLATE_FIELD_RANGE_CHK = 53, - TEMPLATE_FIELD_SLP = 55, - TEMPLATE_FIELD_DLP = 56, - TEMPLATE_FIELD_META_DATA = 57, - TEMPLATE_FIELD_FIRST_MPLS1 = 60, - TEMPLATE_FIELD_FIRST_MPLS2 = 61, - TEMPLATE_FIELD_DPM3 = 8, -}; - -/* The meaning of TEMPLATE_FIELD_VLAN depends on phase and the configuration in - * RTL931X_PIE_CTRL. We use always the same definition and map to the inner VLAN tag: - */ -#define TEMPLATE_FIELD_VLAN TEMPLATE_FIELD_ITAG - -/* Number of fixed templates predefined in the RTL9300 SoC */ -#define N_FIXED_TEMPLATES 5 -/* RTL931x specific predefined templates */ -static enum template_field_id fixed_templates[N_FIXED_TEMPLATES][N_FIXED_FIELDS_RTL931X] = -{ - { - TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2, - TEMPLATE_FIELD_SMAC0, TEMPLATE_FIELD_SMAC1, TEMPLATE_FIELD_SMAC2, - TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_DSAP_SSAP, - TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1, - TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3 - }, { - TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0, - TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_IP_TOS_PROTO, TEMPLATE_FIELD_TCP_INFO, - TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT, TEMPLATE_FIELD_VLAN, - TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1, - TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3 - }, { - TEMPLATE_FIELD_DMAC0, TEMPLATE_FIELD_DMAC1, TEMPLATE_FIELD_DMAC2, - TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_ETHERTYPE, TEMPLATE_FIELD_IP_TOS_PROTO, - TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_DIP0, - TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT, - TEMPLATE_FIELD_META_DATA, TEMPLATE_FIELD_SLP - }, { - TEMPLATE_FIELD_DIP0, TEMPLATE_FIELD_DIP1, TEMPLATE_FIELD_DIP2, - TEMPLATE_FIELD_DIP3, TEMPLATE_FIELD_DIP4, TEMPLATE_FIELD_DIP5, - TEMPLATE_FIELD_DIP6, TEMPLATE_FIELD_DIP7, TEMPLATE_FIELD_IP_TOS_PROTO, - TEMPLATE_FIELD_TCP_INFO, TEMPLATE_FIELD_L4_SPORT, TEMPLATE_FIELD_L4_DPORT, - TEMPLATE_FIELD_RANGE_CHK, TEMPLATE_FIELD_SLP - }, { - TEMPLATE_FIELD_SIP0, TEMPLATE_FIELD_SIP1, TEMPLATE_FIELD_SIP2, - TEMPLATE_FIELD_SIP3, TEMPLATE_FIELD_SIP4, TEMPLATE_FIELD_SIP5, - TEMPLATE_FIELD_SIP6, TEMPLATE_FIELD_SIP7, TEMPLATE_FIELD_META_DATA, - TEMPLATE_FIELD_VLAN, TEMPLATE_FIELD_SPM0, TEMPLATE_FIELD_SPM1, - TEMPLATE_FIELD_SPM2, TEMPLATE_FIELD_SPM3 - }, -}; - -inline void rtl931x_exec_tbl0_cmd(u32 cmd) -{ - sw_w32(cmd, RTL931X_TBL_ACCESS_CTRL_0); - do { } while (sw_r32(RTL931X_TBL_ACCESS_CTRL_0) & (1 << 20)); -} - -inline void rtl931x_exec_tbl1_cmd(u32 cmd) -{ - sw_w32(cmd, RTL931X_TBL_ACCESS_CTRL_1); - do { } while (sw_r32(RTL931X_TBL_ACCESS_CTRL_1) & (1 << 17)); -} - -inline int rtl931x_tbl_access_data_0(int i) -{ - return RTL931X_TBL_ACCESS_DATA_0(i); -} - -void rtl931x_vlan_profile_dump(int index) -{ - u64 profile[4]; - - if (index < 0 || index > 15) - return; - - profile[0] = sw_r32(RTL931X_VLAN_PROFILE_SET(index)); - profile[1] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 4) & 0x1FFFFFFFULL) << 32 | - (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 8) & 0xFFFFFFFF); - profile[2] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 16) & 0x1FFFFFFFULL) << 32 | - (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 12) & 0xFFFFFFFF); - profile[3] = (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 20) & 0x1FFFFFFFULL) << 32 | - (sw_r32(RTL931X_VLAN_PROFILE_SET(index) + 24) & 0xFFFFFFFF); - - pr_info("VLAN %d: L2 learning: %d, L2 Unknown MultiCast Field %llx, \ - IPv4 Unknown MultiCast Field %llx, IPv6 Unknown MultiCast Field: %llx", - index, (u32) (profile[0] & (3 << 14)), profile[1], profile[2], profile[3]); -} - -static void rtl931x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]) -{ - u32 cmd = 1 << 20 | /* Execute cmd */ - 0 << 19 | /* Read */ - 5 << 15 | /* Table type 0b101 */ - (msti & 0x3fff); - priv->r->exec_tbl0_cmd(cmd); - - for (int i = 0; i < 4; i++) - port_state[i] = sw_r32(priv->r->tbl_access_data_0(i)); -} - -static void rtl931x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[]) -{ - u32 cmd = 1 << 20 | /* Execute cmd */ - 1 << 19 | /* Write */ - 5 << 15 | /* Table type 0b101 */ - (msti & 0x3fff); - for (int i = 0; i < 4; i++) - sw_w32(port_state[i], priv->r->tbl_access_data_0(i)); - priv->r->exec_tbl0_cmd(cmd); -} - -inline static int rtl931x_trk_mbr_ctr(int group) -{ - return RTL931X_TRK_MBR_CTRL + (group << 2); -} - -static void rtl931x_vlan_tables_read(u32 vlan, struct rtl838x_vlan_info *info) -{ - u32 v, w, x, y; - /* Read VLAN table (3) via register 0 */ - struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 3); - - rtl_table_read(r, vlan); - v = sw_r32(rtl_table_data(r, 0)); - w = sw_r32(rtl_table_data(r, 1)); - x = sw_r32(rtl_table_data(r, 2)); - y = sw_r32(rtl_table_data(r, 3)); - rtl_table_release(r); - - pr_debug("VLAN_READ %d: %08x %08x %08x %08x\n", vlan, v, w, x, y); - info->tagged_ports = ((u64) v) << 25 | (w >> 7); - info->profile_id = (x >> 16) & 0xf; - info->fid = w & 0x7f; /* AKA MSTI depending on context */ - info->hash_uc_fid = !!(x & BIT(31)); - info->hash_mc_fid = !!(x & BIT(30)); - info->if_id = (x >> 20) & 0x3ff; - info->profile_id = (x >> 16) & 0xf; - info->multicast_grp_mask = x & 0xffff; - if (x & BIT(31)) - info->l2_tunnel_list_id = y >> 18; - else - info->l2_tunnel_list_id = -1; - pr_debug("%s read tagged %016llx, profile-id %d, uc %d, mc %d, intf-id %d\n", __func__, - info->tagged_ports, info->profile_id, info->hash_uc_fid, info->hash_mc_fid, - info->if_id); - - /* Read UNTAG table via table register 3 */ - r = rtl_table_get(RTL9310_TBL_3, 0); - rtl_table_read(r, vlan); - v = ((u64)sw_r32(rtl_table_data(r, 0))) << 25; - v |= sw_r32(rtl_table_data(r, 1)) >> 7; - rtl_table_release(r); - - info->untagged_ports = v; -} - -static void rtl931x_vlan_set_tagged(u32 vlan, struct rtl838x_vlan_info *info) -{ - u32 v, w, x, y; - /* Access VLAN table (1) via register 0 */ - struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 3); - - v = info->tagged_ports >> 25; - w = (info->tagged_ports & 0x1fffff) << 7; - w |= info->fid & 0x7f; - x = info->hash_uc_fid ? BIT(31) : 0; - x |= info->hash_mc_fid ? BIT(30) : 0; - x |= info->if_id & 0x3ff << 20; - x |= (info->profile_id & 0xf) << 16; - x |= info->multicast_grp_mask & 0xffff; - if (info->l2_tunnel_list_id >= 0) { - y = info->l2_tunnel_list_id << 18; - y |= BIT(31); - } else { - y = 0; - } - - sw_w32(v, rtl_table_data(r, 0)); - sw_w32(w, rtl_table_data(r, 1)); - sw_w32(x, rtl_table_data(r, 2)); - sw_w32(y, rtl_table_data(r, 3)); - - rtl_table_write(r, vlan); - rtl_table_release(r); -} - -static void rtl931x_vlan_set_untagged(u32 vlan, u64 portmask) -{ - struct table_reg *r = rtl_table_get(RTL9310_TBL_3, 0); - - rtl839x_set_port_reg_be(portmask << 7, rtl_table_data(r, 0)); - rtl_table_write(r, vlan); - rtl_table_release(r); -} - -static inline int rtl931x_mac_force_mode_ctrl(int p) -{ - return RTL931X_MAC_FORCE_MODE_CTRL + (p << 2); -} - -static inline int rtl931x_mac_link_spd_sts(int p) -{ - return RTL931X_MAC_LINK_SPD_STS + (((p >> 3) << 2)); -} - -static inline int rtl931x_mac_port_ctrl(int p) -{ - return RTL931X_MAC_L2_PORT_CTRL + (p << 7); -} - -static inline int rtl931x_l2_port_new_salrn(int p) -{ - return RTL931X_L2_PORT_NEW_SALRN(p); -} - -static inline int rtl931x_l2_port_new_sa_fwd(int p) -{ - return RTL931X_L2_PORT_NEW_SA_FWD(p); -} - -irqreturn_t rtl931x_switch_irq(int irq, void *dev_id) -{ - struct dsa_switch *ds = dev_id; - u32 status = sw_r32(RTL931X_ISR_GLB_SRC); - u64 ports = rtl839x_get_port_reg_le(RTL931X_ISR_PORT_LINK_STS_CHG); - u64 link; - - /* Clear status */ - rtl839x_set_port_reg_le(ports, RTL931X_ISR_PORT_LINK_STS_CHG); - pr_debug("RTL931X Link change: status: %x, ports %016llx\n", status, ports); - - link = rtl839x_get_port_reg_le(RTL931X_MAC_LINK_STS); - /* Must re-read this to get correct status */ - link = rtl839x_get_port_reg_le(RTL931X_MAC_LINK_STS); - pr_debug("RTL931X Link change: status: %x, link status %016llx\n", status, link); - - for (int i = 0; i < 56; i++) { - if (ports & BIT_ULL(i)) { - if (link & BIT_ULL(i)) { - pr_info("%s port %d up\n", __func__, i); - dsa_port_phylink_mac_change(ds, i, true); - } else { - pr_info("%s port %d down\n", __func__, i); - dsa_port_phylink_mac_change(ds, i, false); - } - } - } - - return IRQ_HANDLED; -} - -int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val) -{ - u32 v; - int err = 0; - - val &= 0xffff; - if (port > 63 || page > 4095 || reg > 31) - return -ENOTSUPP; - - mutex_lock(&smi_lock); - pr_debug("%s: writing to phy %d %d %d %d\n", __func__, port, page, reg, val); - /* Clear both port registers */ - sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2); - sw_w32(0, RTL931X_SMI_INDRT_ACCESS_CTRL_2 + 4); - sw_w32_mask(0, BIT(port % 32), RTL931X_SMI_INDRT_ACCESS_CTRL_2 + (port / 32) * 4); - - sw_w32_mask(0xffff, val, RTL931X_SMI_INDRT_ACCESS_CTRL_3); - - v = reg << 6 | page << 11 ; - sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); - - sw_w32(0x1ff, RTL931X_SMI_INDRT_ACCESS_CTRL_1); - - v |= BIT(4) | 1; /* Write operation and execute */ - sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); - - do { - } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x1); - - if (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x2) - err = -EIO; - - mutex_unlock(&smi_lock); - - return err; -} - -int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val) -{ - u32 v; - - if (port > 63 || page > 4095 || reg > 31) - return -ENOTSUPP; - - mutex_lock(&smi_lock); - - sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL); - - v = reg << 6 | page << 11 | 1; - sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); - - do { - } while (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0) & 0x1); - - v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0); - *val = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3); - *val = (*val & 0xffff0000) >> 16; - - pr_debug("%s: port %d, page: %d, reg: %x, val: %x, v: %08x\n", - __func__, port, page, reg, *val, v); - - mutex_unlock(&smi_lock); - - return 0; -} - -/* Read an mmd register of the PHY */ -int rtl931x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val) -{ - int err = 0; - u32 v; - /* Select PHY register type - * If select 1G/10G MMD register type, registers EXT_PAGE, MAIN_PAGE and REG settings are don’t care. - * 0x0 Normal register (Clause 22) - * 0x1: 1G MMD register (MMD via Clause 22 registers 13 and 14) - * 0x2: 10G MMD register (MMD via Clause 45) - */ - int type = 2; - - mutex_lock(&smi_lock); - - /* Set PHY to access via port-number */ - sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL); - - /* Set MMD device number and register to write to */ - sw_w32(devnum << 16 | regnum, RTL931X_SMI_INDRT_ACCESS_MMD_CTRL); - - v = type << 2 | BIT(0); /* MMD-access-type | EXEC */ - sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); - - do { - v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0); - } while (v & BIT(0)); - - /* Check for error condition */ - if (v & BIT(1)) - err = -EIO; - - *val = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3) >> 16; - - pr_debug("%s: port %d, dev: %x, regnum: %x, val: %x (err %d)\n", __func__, - port, devnum, regnum, *val, err); - - mutex_unlock(&smi_lock); - - return err; -} - -/* Write to an mmd register of the PHY */ -int rtl931x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val) -{ - int err = 0; - u32 v; - int type = 2; - u64 pm; - - mutex_lock(&smi_lock); - - /* Set PHY to access via port-mask */ - pm = (u64)1 << port; - sw_w32((u32)pm, RTL931X_SMI_INDRT_ACCESS_CTRL_2); - sw_w32((u32)(pm >> 32), RTL931X_SMI_INDRT_ACCESS_CTRL_2 + 4); - - /* Set data to write */ - sw_w32_mask(0xffff, val, RTL931X_SMI_INDRT_ACCESS_CTRL_3); - - /* Set MMD device number and register to write to */ - sw_w32(devnum << 16 | regnum, RTL931X_SMI_INDRT_ACCESS_MMD_CTRL); - - v = BIT(4) | type << 2 | BIT(0); /* WRITE | MMD-access-type | EXEC */ - sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0); - - do { - v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0); - } while (v & BIT(0)); - - pr_debug("%s: port %d, dev: %x, regnum: %x, val: %x (err %d)\n", __func__, - port, devnum, regnum, val, err); - mutex_unlock(&smi_lock); - - return err; -} - -void rtl931x_print_matrix(void) -{ - volatile u64 *ptr = RTL838X_SW_BASE + RTL839X_PORT_ISO_CTRL(0); - - for (int i = 0; i < 52; i += 4) - pr_info("> %16llx %16llx %16llx %16llx\n", - ptr[i + 0], ptr[i + 1], ptr[i + 2], ptr[i + 3]); - pr_info("CPU_PORT> %16llx\n", ptr[52]); -} - -void rtl931x_set_receive_management_action(int port, rma_ctrl_t type, action_type_t action) -{ - u32 value = 0; - - /* hack for value mapping */ - if (type == GRATARP && action == COPY2CPU) - action = TRAP2MASTERCPU; - - switch(action) { - case FORWARD: - value = 0; - break; - case DROP: - value = 1; - break; - case TRAP2CPU: - value = 2; - break; - case TRAP2MASTERCPU: - value = 3; - break; - case FLOODALL: - value = 4; - break; - default: - break; - } - - switch(type) { - case BPDU: - sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_BPDU_CTRL + ((port / 10) << 2)); - break; - case PTP: - /* udp */ - sw_w32_mask(3 << 2, value << 2, RTL931X_RMA_PTP_CTRL + (port << 2)); - /* eth2 */ - sw_w32_mask(3, value, RTL931X_RMA_PTP_CTRL + (port << 2)); - break; - case PTP_UDP: - sw_w32_mask(3 << 2, value << 2, RTL931X_RMA_PTP_CTRL + (port << 2)); - break; - case PTP_ETH2: - sw_w32_mask(3, value, RTL931X_RMA_PTP_CTRL + (port << 2)); - break; - case LLDP: - sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_LLDP_CTRL + ((port / 10) << 2)); - break; - case EAPOL: - sw_w32_mask(7 << ((port % 10) * 3), value << ((port % 10) * 3), RTL931X_RMA_EAPOL_CTRL + ((port / 10) << 2)); - break; - case GRATARP: - sw_w32_mask(3 << ((port & 0xf) << 1), value << ((port & 0xf) << 1), RTL931X_TRAP_ARP_GRAT_PORT_ACT + ((port >> 4) << 2)); - break; - } -} - -u64 rtl931x_traffic_get(int source) -{ - u32 v; - struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6); - - rtl_table_read(r, source); - v = sw_r32(rtl_table_data(r, 0)); - rtl_table_release(r); - v = v >> 3; - - return v; -} - -/* Enable traffic between a source port and a destination port matrix */ -void rtl931x_traffic_set(int source, u64 dest_matrix) -{ - struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6); - - sw_w32((dest_matrix << 3), rtl_table_data(r, 0)); - rtl_table_write(r, source); - rtl_table_release(r); -} - -void rtl931x_traffic_enable(int source, int dest) -{ - struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6); - rtl_table_read(r, source); - sw_w32_mask(0, BIT(dest + 3), rtl_table_data(r, 0)); - rtl_table_write(r, source); - rtl_table_release(r); -} - -void rtl931x_traffic_disable(int source, int dest) -{ - struct table_reg *r = rtl_table_get(RTL9310_TBL_0, 6); - rtl_table_read(r, source); - sw_w32_mask(BIT(dest + 3), 0, rtl_table_data(r, 0)); - rtl_table_write(r, source); - rtl_table_release(r); -} - -static u64 rtl931x_l2_hash_seed(u64 mac, u32 vid) -{ - u64 v = vid; - - v <<= 48; - v |= mac; - - return v; -} - -/* Calculate both the block 0 and the block 1 hash by applyingthe same hash - * algorithm as the one used currently by the ASIC to the seed, and return - * both hashes in the lower and higher word of the return value since only 12 bit of - * the hash are significant. - */ -static u32 rtl931x_l2_hash_key(struct rtl838x_switch_priv *priv, u64 seed) -{ - u32 h, h0, h1, h2, h3, h4, k0, k1; - - h0 = seed & 0xfff; - h1 = (seed >> 12) & 0xfff; - h2 = (seed >> 24) & 0xfff; - h3 = (seed >> 36) & 0xfff; - h4 = (seed >> 48) & 0xfff; - h4 = ((h4 & 0x7) << 9) | ((h4 >> 3) & 0x1ff); - k0 = h0 ^ h1 ^ h2 ^ h3 ^ h4; - - h0 = seed & 0xfff; - h0 = ((h0 & 0x1ff) << 3) | ((h0 >> 9) & 0x7); - h1 = (seed >> 12) & 0xfff; - h1 = ((h1 & 0x3f) << 6) | ((h1 >> 6) & 0x3f); - h2 = (seed >> 24) & 0xfff; - h3 = (seed >> 36) & 0xfff; - h3 = ((h3 & 0x3f) << 6) | ((h3 >> 6) & 0x3f); - h4 = (seed >> 48) & 0xfff; - k1 = h0 ^ h1 ^ h2 ^ h3 ^ h4; - - /* Algorithm choice for block 0 */ - if (sw_r32(RTL931X_L2_CTRL) & BIT(0)) - h = k1; - else - h = k0; - - /* Algorithm choice for block 1 - * Since k0 and k1 are < 4096, adding 4096 will offset the hash into the second - * half of hash-space - * 4096 is in fact the hash-table size 32768 divided by 4 hashes per bucket - * divided by 2 to divide the hash space in 2 - */ - if (sw_r32(RTL931X_L2_CTRL) & BIT(1)) - h |= (k1 + 4096) << 16; - else - h |= (k0 + 4096) << 16; - - return h; -} - -/* Fills an L2 entry structure from the SoC registers */ -static void rtl931x_fill_l2_entry(u32 r[], struct rtl838x_l2_entry *e) -{ - pr_debug("In %s valid?\n", __func__); - e->valid = !!(r[0] & BIT(31)); - if (!e->valid) - return; - - pr_debug("%s: entry valid, raw: %08x %08x %08x %08x\n", __func__, r[0], r[1], r[2], r[3]); - e->is_ip_mc = false; - e->is_ipv6_mc = false; - - e->mac[0] = r[0] >> 8; - e->mac[1] = r[0]; - e->mac[2] = r[1] >> 24; - e->mac[3] = r[1] >> 16; - e->mac[4] = r[1] >> 8; - e->mac[5] = r[1]; - - e->is_open_flow = !!(r[0] & BIT(30)); - e->is_pe_forward = !!(r[0] & BIT(29)); - e->next_hop = !!(r[2] & BIT(30)); - e->rvid = (r[0] >> 16) & 0xfff; - - /* Is it a unicast entry? check multicast bit */ - if (!(e->mac[0] & 1)) { - e->type = L2_UNICAST; - e->is_l2_tunnel = !!(r[2] & BIT(31)); - e->is_static = !!(r[2] & BIT(13)); - e->port = (r[2] >> 19) & 0x3ff; - /* Check for trunk port */ - if (r[2] & BIT(29)) { - e->is_trunk = true; - e->stack_dev = (e->port >> 9) & 1; - e->trunk = e->port & 0x3f; - } else { - e->is_trunk = false; - e->stack_dev = (e->port >> 6) & 0xf; - e->port = e->port & 0x3f; - } - - e->block_da = !!(r[2] & BIT(14)); - e->block_sa = !!(r[2] & BIT(15)); - e->suspended = !!(r[2] & BIT(12)); - e->age = (r[2] >> 16) & 3; - - /* the UC_VID field in hardware is used for the VID or for the route id */ - if (e->next_hop) { - e->nh_route_id = r[2] & 0x7ff; - e->vid = 0; - } else { - e->vid = r[2] & 0xfff; - e->nh_route_id = 0; - } - if (e->is_l2_tunnel) - e->l2_tunnel_id = ((r[2] & 0xff) << 4) | (r[3] >> 28); - /* TODO: Implement VLAN conversion */ - } else { - e->type = L2_MULTICAST; - e->is_local_forward = !!(r[2] & BIT(31)); - e->is_remote_forward = !!(r[2] & BIT(17)); - e->mc_portmask_index = (r[2] >> 18) & 0xfff; - e->l2_tunnel_list_id = (r[2] >> 4) & 0x1fff; - } -} - -/* Fills the 3 SoC table registers r[] with the information of in the rtl838x_l2_entry */ -static void rtl931x_fill_l2_row(u32 r[], struct rtl838x_l2_entry *e) -{ - u32 port; - - if (!e->valid) { - r[0] = r[1] = r[2] = 0; - return; - } - - r[2] = BIT(31); /* Set valid bit */ - - r[0] = ((u32)e->mac[0]) << 24 | - ((u32)e->mac[1]) << 16 | - ((u32)e->mac[2]) << 8 | - ((u32)e->mac[3]); - r[1] = ((u32)e->mac[4]) << 24 | - ((u32)e->mac[5]) << 16; - - r[2] |= e->next_hop ? BIT(12) : 0; - - if (e->type == L2_UNICAST) { - r[2] |= e->is_static ? BIT(14) : 0; - r[1] |= e->rvid & 0xfff; - r[2] |= (e->port & 0x3ff) << 20; - if (e->is_trunk) { - r[2] |= BIT(30); - port = e->stack_dev << 9 | (e->port & 0x3f); - } else { - port = (e->stack_dev & 0xf) << 6; - port |= e->port & 0x3f; - } - r[2] |= port << 20; - r[2] |= e->block_da ? BIT(15) : 0; - r[2] |= e->block_sa ? BIT(17) : 0; - r[2] |= e->suspended ? BIT(13) : 0; - r[2] |= (e->age & 0x3) << 17; - /* the UC_VID field in hardware is used for the VID or for the route id */ - if (e->next_hop) - r[2] |= e->nh_route_id & 0x7ff; - else - r[2] |= e->vid & 0xfff; - } else { /* L2_MULTICAST */ - r[2] |= (e->mc_portmask_index & 0x3ff) << 16; - r[2] |= e->mc_mac_index & 0x7ff; - } -} - -/* Read an L2 UC or MC entry out of a hash bucket of the L2 forwarding table - * hash is the id of the bucket and pos is the position of the entry in that bucket - * The data read from the SoC is filled into rtl838x_l2_entry - */ -static u64 rtl931x_read_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e) -{ - u32 r[4]; - struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 0); - u32 idx; - u64 mac; - u64 seed; - - pr_debug("%s: hash %08x, pos: %d\n", __func__, hash, pos); - - /* On the RTL93xx, 2 different hash algorithms are used making it a total of - * 8 buckets that need to be searched, 4 for each hash-half - * Use second hash space when bucket is between 4 and 8 - */ - if (pos >= 4) { - pos -= 4; - hash >>= 16; - } else { - hash &= 0xffff; - } - - idx = (0 << 14) | (hash << 2) | pos; /* Search SRAM, with hash and at pos in bucket */ - pr_debug("%s: NOW hash %08x, pos: %d\n", __func__, hash, pos); - - rtl_table_read(q, idx); - for (int i = 0; i < 4; i++) - r[i] = sw_r32(rtl_table_data(q, i)); - - rtl_table_release(q); - - rtl931x_fill_l2_entry(r, e); - - pr_debug("%s: valid: %d, nh: %d\n", __func__, e->valid, e->next_hop); - if (!e->valid) - return 0; - - mac = ((u64)e->mac[0]) << 40 | - ((u64)e->mac[1]) << 32 | - ((u64)e->mac[2]) << 24 | - ((u64)e->mac[3]) << 16 | - ((u64)e->mac[4]) << 8 | - ((u64)e->mac[5]); - - seed = rtl931x_l2_hash_seed(mac, e->rvid); - pr_debug("%s: mac %016llx, seed %016llx\n", __func__, mac, seed); - - /* return vid with concatenated mac as unique id */ - return seed; -} - -static u64 rtl931x_read_cam(int idx, struct rtl838x_l2_entry *e) -{ - return 0; -} - -static void rtl931x_write_cam(int idx, struct rtl838x_l2_entry *e) -{ -} - -static void rtl931x_write_l2_entry_using_hash(u32 hash, u32 pos, struct rtl838x_l2_entry *e) -{ - u32 r[4]; - struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 0); - u32 idx = (0 << 14) | (hash << 2) | pos; /* Access SRAM, with hash and at pos in bucket */ - - pr_info("%s: hash %d, pos %d\n", __func__, hash, pos); - pr_info("%s: index %d -> mac %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, idx, - e->mac[0], e->mac[1], e->mac[2], e->mac[3],e->mac[4],e->mac[5]); - - rtl931x_fill_l2_row(r, e); - pr_info("%s: %d: %08x %08x %08x\n", __func__, idx, r[0], r[1], r[2]); - - for (int i = 0; i < 4; i++) - sw_w32(r[i], rtl_table_data(q, i)); - - rtl_table_write(q, idx); - rtl_table_release(q); -} - -static void rtl931x_vlan_fwd_on_inner(int port, bool is_set) -{ - /* Always set all tag modes to fwd based on either inner or outer tag */ - if (is_set) - sw_w32_mask(0xf, 0, RTL931X_VLAN_PORT_FWD + (port << 2)); - else - sw_w32_mask(0, 0xf, RTL931X_VLAN_PORT_FWD + (port << 2)); -} - -static void rtl931x_vlan_profile_setup(int profile) -{ - u32 p[7]; - - pr_info("In %s\n", __func__); - - if (profile > 15) - return; - - p[0] = sw_r32(RTL931X_VLAN_PROFILE_SET(profile)); - - /* Enable routing of Ipv4/6 Unicast and IPv4/6 Multicast traffic */ - /* p[0] |= BIT(17) | BIT(16) | BIT(13) | BIT(12); */ - p[0] |= 0x3 << 11; /* COPY2CPU */ - - p[1] = 0x1FFFFFF; /* L2 unknwon MC flooding portmask all ports, including the CPU-port */ - p[2] = 0xFFFFFFFF; - p[3] = 0x1FFFFFF; /* IPv4 unknwon MC flooding portmask */ - p[4] = 0xFFFFFFFF; - p[5] = 0x1FFFFFF; /* IPv6 unknwon MC flooding portmask */ - p[6] = 0xFFFFFFFF; - - for (int i = 0; i < 7; i++) - sw_w32(p[i], RTL931X_VLAN_PROFILE_SET(profile) + i * 4); - pr_info("Leaving %s\n", __func__); -} - -static void rtl931x_l2_learning_setup(void) -{ - /* Portmask for flooding broadcast traffic */ - rtl839x_set_port_reg_be(0x1FFFFFFFFFFFFFF, RTL931X_L2_BC_FLD_PMSK); - - /* Portmask for flooding unicast traffic with unknown destination */ - rtl839x_set_port_reg_be(0x1FFFFFFFFFFFFFF, RTL931X_L2_UNKN_UC_FLD_PMSK); - - /* Limit learning to maximum: 64k entries, after that just flood (bits 0-2) */ - sw_w32((0xffff << 3) | FORWARD, RTL931X_L2_LRN_CONSTRT_CTRL); -} - -static u64 rtl931x_read_mcast_pmask(int idx) -{ - u64 portmask; - /* Read MC_PMSK (2) via register RTL9310_TBL_0 */ - struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 2); - - rtl_table_read(q, idx); - portmask = sw_r32(rtl_table_data(q, 0)); - portmask <<= 32; - portmask |= sw_r32(rtl_table_data(q, 1)); - portmask >>= 7; - rtl_table_release(q); - - pr_debug("%s: Index idx %d has portmask %016llx\n", __func__, idx, portmask); - - return portmask; -} - -static void rtl931x_write_mcast_pmask(int idx, u64 portmask) -{ - u64 pm = portmask; - - /* Access MC_PMSK (2) via register RTL9310_TBL_0 */ - struct table_reg *q = rtl_table_get(RTL9310_TBL_0, 2); - - pr_debug("%s: Index idx %d has portmask %016llx\n", __func__, idx, pm); - pm <<= 7; - sw_w32((u32)(pm >> 32), rtl_table_data(q, 0)); - sw_w32((u32)pm, rtl_table_data(q, 1)); - rtl_table_write(q, idx); - rtl_table_release(q); -} - - -static int rtl931x_set_ageing_time(unsigned long msec) -{ - int t = sw_r32(RTL931X_L2_AGE_CTRL); - - t &= 0x1FFFFF; - t = (t * 8) / 10; - pr_debug("L2 AGING time: %d sec\n", t); - - t = (msec / 100 + 7) / 8; - t = t > 0x1FFFFF ? 0x1FFFFF : t; - sw_w32_mask(0x1FFFFF, t, RTL931X_L2_AGE_CTRL); - pr_debug("Dynamic aging for ports: %x\n", sw_r32(RTL931X_L2_PORT_AGE_CTRL)); - - return 0; -} -void rtl931x_sw_init(struct rtl838x_switch_priv *priv) -{ -/* rtl931x_sds_init(priv); */ -} - -static void rtl931x_pie_lookup_enable(struct rtl838x_switch_priv *priv, int index) -{ - int block = index / PIE_BLOCK_SIZE; - - sw_w32_mask(0, BIT(block), RTL931X_PIE_BLK_LOOKUP_CTRL); -} - -/* Fills the data in the intermediate representation in the pie_rule structure - * into a data field for a given template field field_type - * TODO: This function looks very similar to the function of the rtl9300, but - * since it uses the physical template_field_id, which are different for each - * SoC and there are other field types, it is actually not. If we would also use - * an intermediate representation for a field type, we would could have one - * pie_data_fill function for all SoCs, provided we have also for each SoC a - * function to map between physical and intermediate field type - */ -int rtl931x_pie_data_fill(enum template_field_id field_type, struct pie_rule *pr, u16 *data, u16 *data_m) -{ - *data = *data_m = 0; - - switch (field_type) { - case TEMPLATE_FIELD_SPM0: - *data = pr->spm; - *data_m = pr->spm_m; - break; - case TEMPLATE_FIELD_SPM1: - *data = pr->spm >> 16; - *data_m = pr->spm_m >> 16; - break; - case TEMPLATE_FIELD_OTAG: - *data = pr->otag; - *data_m = pr->otag_m; - break; - case TEMPLATE_FIELD_SMAC0: - *data = pr->smac[4]; - *data = (*data << 8) | pr->smac[5]; - *data_m = pr->smac_m[4]; - *data_m = (*data_m << 8) | pr->smac_m[5]; - break; - case TEMPLATE_FIELD_SMAC1: - *data = pr->smac[2]; - *data = (*data << 8) | pr->smac[3]; - *data_m = pr->smac_m[2]; - *data_m = (*data_m << 8) | pr->smac_m[3]; - break; - case TEMPLATE_FIELD_SMAC2: - *data = pr->smac[0]; - *data = (*data << 8) | pr->smac[1]; - *data_m = pr->smac_m[0]; - *data_m = (*data_m << 8) | pr->smac_m[1]; - break; - case TEMPLATE_FIELD_DMAC0: - *data = pr->dmac[4]; - *data = (*data << 8) | pr->dmac[5]; - *data_m = pr->dmac_m[4]; - *data_m = (*data_m << 8) | pr->dmac_m[5]; - break; - case TEMPLATE_FIELD_DMAC1: - *data = pr->dmac[2]; - *data = (*data << 8) | pr->dmac[3]; - *data_m = pr->dmac_m[2]; - *data_m = (*data_m << 8) | pr->dmac_m[3]; - break; - case TEMPLATE_FIELD_DMAC2: - *data = pr->dmac[0]; - *data = (*data << 8) | pr->dmac[1]; - *data_m = pr->dmac_m[0]; - *data_m = (*data_m << 8) | pr->dmac_m[1]; - break; - case TEMPLATE_FIELD_ETHERTYPE: - *data = pr->ethertype; - *data_m = pr->ethertype_m; - break; - case TEMPLATE_FIELD_ITAG: - *data = pr->itag; - *data_m = pr->itag_m; - break; - case TEMPLATE_FIELD_SIP0: - if (pr->is_ipv6) { - *data = pr->sip6.s6_addr16[7]; - *data_m = pr->sip6_m.s6_addr16[7]; - } else { - *data = pr->sip; - *data_m = pr->sip_m; - } - break; - case TEMPLATE_FIELD_SIP1: - if (pr->is_ipv6) { - *data = pr->sip6.s6_addr16[6]; - *data_m = pr->sip6_m.s6_addr16[6]; - } else { - *data = pr->sip >> 16; - *data_m = pr->sip_m >> 16; - } - break; - case TEMPLATE_FIELD_SIP2: - case TEMPLATE_FIELD_SIP3: - case TEMPLATE_FIELD_SIP4: - case TEMPLATE_FIELD_SIP5: - case TEMPLATE_FIELD_SIP6: - case TEMPLATE_FIELD_SIP7: - *data = pr->sip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)]; - *data_m = pr->sip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_SIP2)]; - break; - case TEMPLATE_FIELD_DIP0: - if (pr->is_ipv6) { - *data = pr->dip6.s6_addr16[7]; - *data_m = pr->dip6_m.s6_addr16[7]; - } else { - *data = pr->dip; - *data_m = pr->dip_m; - } - break; - case TEMPLATE_FIELD_DIP1: - if (pr->is_ipv6) { - *data = pr->dip6.s6_addr16[6]; - *data_m = pr->dip6_m.s6_addr16[6]; - } else { - *data = pr->dip >> 16; - *data_m = pr->dip_m >> 16; - } - break; - case TEMPLATE_FIELD_DIP2: - case TEMPLATE_FIELD_DIP3: - case TEMPLATE_FIELD_DIP4: - case TEMPLATE_FIELD_DIP5: - case TEMPLATE_FIELD_DIP6: - case TEMPLATE_FIELD_DIP7: - *data = pr->dip6.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)]; - *data_m = pr->dip6_m.s6_addr16[5 - (field_type - TEMPLATE_FIELD_DIP2)]; - break; - case TEMPLATE_FIELD_IP_TOS_PROTO: - *data = pr->tos_proto; - *data_m = pr->tos_proto_m; - break; - case TEMPLATE_FIELD_L4_SPORT: - *data = pr->sport; - *data_m = pr->sport_m; - break; - case TEMPLATE_FIELD_L4_DPORT: - *data = pr->dport; - *data_m = pr->dport_m; - break; - case TEMPLATE_FIELD_DSAP_SSAP: - *data = pr->dsap_ssap; - *data_m = pr->dsap_ssap_m; - break; - case TEMPLATE_FIELD_TCP_INFO: - *data = pr->tcp_info; - *data_m = pr->tcp_info_m; - break; - case TEMPLATE_FIELD_RANGE_CHK: - pr_info("TEMPLATE_FIELD_RANGE_CHK: not configured\n"); - break; - default: - pr_info("%s: unknown field %d\n", __func__, field_type); - return -1; - } - - return 0; -} - -/* Reads the intermediate representation of the templated match-fields of the - * PIE rule in the pie_rule structure and fills in the raw data fields in the - * raw register space r[]. - * The register space configuration size is identical for the RTL8380/90 and RTL9300, - * however the RTL931X has 2 more registers / fields and the physical field-ids are different - * on all SoCs - * On the RTL9300 the mask fields are not word-aligend! - */ -static void rtl931x_write_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[]) -{ - for (int i = 0; i < N_FIXED_FIELDS; i++) { - u16 data, data_m; - - rtl931x_pie_data_fill(t[i], pr, &data, &data_m); - - /* On the RTL9300, the mask fields are not word aligned! */ - if (!(i % 2)) { - r[5 - i / 2] = data; - r[12 - i / 2] |= ((u32)data_m << 8); - } else { - r[5 - i / 2] |= ((u32)data) << 16; - r[12 - i / 2] |= ((u32)data_m) << 24; - r[11 - i / 2] |= ((u32)data_m) >> 8; - } - } -} - -// Currently unused -// static void rtl931x_read_pie_fixed_fields(u32 r[], struct pie_rule *pr) -// { -// pr->mgnt_vlan = r[7] & BIT(31); -// if (pr->phase == PHASE_IACL) -// pr->dmac_hit_sw = r[7] & BIT(30); -// else /* TODO: EACL/VACL phase handling */ -// pr->content_too_deep = r[7] & BIT(30); -// pr->not_first_frag = r[7] & BIT(29); -// pr->frame_type_l4 = (r[7] >> 26) & 7; -// pr->frame_type = (r[7] >> 24) & 3; -// pr->otag_fmt = (r[7] >> 23) & 1; -// pr->itag_fmt = (r[7] >> 22) & 1; -// pr->otag_exist = (r[7] >> 21) & 1; -// pr->itag_exist = (r[7] >> 20) & 1; -// pr->frame_type_l2 = (r[7] >> 18) & 3; -// pr->igr_normal_port = (r[7] >> 17) & 1; -// pr->tid = (r[7] >> 16) & 1; - -// pr->mgnt_vlan_m = r[14] & BIT(15); -// if (pr->phase == PHASE_IACL) -// pr->dmac_hit_sw_m = r[14] & BIT(14); -// else -// pr->content_too_deep_m = r[14] & BIT(14); -// pr->not_first_frag_m = r[14] & BIT(13); -// pr->frame_type_l4_m = (r[14] >> 10) & 7; -// pr->frame_type_m = (r[14] >> 8) & 3; -// pr->otag_fmt_m = r[14] & BIT(7); -// pr->itag_fmt_m = r[14] & BIT(6); -// pr->otag_exist_m = r[14] & BIT(5); -// pr->itag_exist_m = r[14] & BIT (4); -// pr->frame_type_l2_m = (r[14] >> 2) & 3; -// pr->igr_normal_port_m = r[14] & BIT(1); -// pr->tid_m = r[14] & 1; - -// pr->valid = r[15] & BIT(31); -// pr->cond_not = r[15] & BIT(30); -// pr->cond_and1 = r[15] & BIT(29); -// pr->cond_and2 = r[15] & BIT(28); -// } - -static void rtl931x_write_pie_fixed_fields(u32 r[], struct pie_rule *pr) -{ - r[7] |= pr->mgnt_vlan ? BIT(31) : 0; - if (pr->phase == PHASE_IACL) - r[7] |= pr->dmac_hit_sw ? BIT(30) : 0; - else - r[7] |= pr->content_too_deep ? BIT(30) : 0; - r[7] |= pr->not_first_frag ? BIT(29) : 0; - r[7] |= ((u32) (pr->frame_type_l4 & 0x7)) << 26; - r[7] |= ((u32) (pr->frame_type & 0x3)) << 24; - r[7] |= pr->otag_fmt ? BIT(23) : 0; - r[7] |= pr->itag_fmt ? BIT(22) : 0; - r[7] |= pr->otag_exist ? BIT(21) : 0; - r[7] |= pr->itag_exist ? BIT(20) : 0; - r[7] |= ((u32) (pr->frame_type_l2 & 0x3)) << 18; - r[7] |= pr->igr_normal_port ? BIT(17) : 0; - r[7] |= ((u32) (pr->tid & 0x1)) << 16; - - r[14] |= pr->mgnt_vlan_m ? BIT(15) : 0; - if (pr->phase == PHASE_IACL) - r[14] |= pr->dmac_hit_sw_m ? BIT(14) : 0; - else - r[14] |= pr->content_too_deep_m ? BIT(14) : 0; - r[14] |= pr->not_first_frag_m ? BIT(13) : 0; - r[14] |= ((u32) (pr->frame_type_l4_m & 0x7)) << 10; - r[14] |= ((u32) (pr->frame_type_m & 0x3)) << 8; - r[14] |= pr->otag_fmt_m ? BIT(7) : 0; - r[14] |= pr->itag_fmt_m ? BIT(6) : 0; - r[14] |= pr->otag_exist_m ? BIT(5) : 0; - r[14] |= pr->itag_exist_m ? BIT(4) : 0; - r[14] |= ((u32) (pr->frame_type_l2_m & 0x3)) << 2; - r[14] |= pr->igr_normal_port_m ? BIT(1) : 0; - r[14] |= (u32) (pr->tid_m & 0x1); - - r[15] |= pr->valid ? BIT(31) : 0; - r[15] |= pr->cond_not ? BIT(30) : 0; - r[15] |= pr->cond_and1 ? BIT(29) : 0; - r[15] |= pr->cond_and2 ? BIT(28) : 0; -} - -static void rtl931x_write_pie_action(u32 r[], struct pie_rule *pr) -{ - /* Either drop or forward */ - if (pr->drop) { - r[15] |= BIT(11) | BIT(12) | BIT(13); /* Do Green, Yellow and Red drops */ - /* Actually DROP, not PERMIT in Green / Yellow / Red */ - r[16] |= BIT(27) | BIT(28) | BIT(29); - } else { - r[15] |= pr->fwd_sel ? BIT(14) : 0; - r[16] |= pr->fwd_act << 24; - r[16] |= BIT(21); /* We overwrite any drop */ - } - if (pr->phase == PHASE_VACL) - r[16] |= pr->fwd_sa_lrn ? BIT(22) : 0; - r[15] |= pr->bypass_sel ? BIT(10) : 0; - r[15] |= pr->nopri_sel ? BIT(21) : 0; - r[15] |= pr->tagst_sel ? BIT(20) : 0; - r[15] |= pr->ovid_sel ? BIT(18) : 0; - r[15] |= pr->ivid_sel ? BIT(16) : 0; - r[15] |= pr->meter_sel ? BIT(27) : 0; - r[15] |= pr->mir_sel ? BIT(15) : 0; - r[15] |= pr->log_sel ? BIT(26) : 0; - - r[16] |= ((u32)(pr->fwd_data & 0xfff)) << 9; -/* r[15] |= pr->log_octets ? BIT(31) : 0; */ - r[15] |= (u32)(pr->meter_data) >> 2; - r[16] |= (((u32)(pr->meter_data) >> 7) & 0x3) << 29; - - r[16] |= ((u32)(pr->ivid_act & 0x3)) << 21; - r[15] |= ((u32)(pr->ivid_data & 0xfff)) << 9; - r[16] |= ((u32)(pr->ovid_act & 0x3)) << 30; - r[16] |= ((u32)(pr->ovid_data & 0xfff)) << 16; - r[16] |= ((u32)(pr->mir_data & 0x3)) << 6; - r[17] |= ((u32)(pr->tagst_data & 0xf)) << 28; - r[17] |= ((u32)(pr->nopri_data & 0x7)) << 25; - r[17] |= pr->bypass_ibc_sc ? BIT(16) : 0; -} - -void rtl931x_pie_rule_dump_raw(u32 r[]) -{ - pr_info("Raw IACL table entry:\n"); - pr_info("r 0 - 7: %08x %08x %08x %08x %08x %08x %08x %08x\n", - r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]); - pr_info("r 8 - 15: %08x %08x %08x %08x %08x %08x %08x %08x\n", - r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]); - pr_info("r 16 - 18: %08x %08x %08x\n", r[16], r[17], r[18]); - pr_info("Match : %08x %08x %08x %08x %08x %08x\n", r[0], r[1], r[2], r[3], r[4], r[5]); - pr_info("Fixed : %06x\n", r[6] >> 8); - pr_info("Match M: %08x %08x %08x %08x %08x %08x\n", - (r[6] << 24) | (r[7] >> 8), (r[7] << 24) | (r[8] >> 8), (r[8] << 24) | (r[9] >> 8), - (r[9] << 24) | (r[10] >> 8), (r[10] << 24) | (r[11] >> 8), - (r[11] << 24) | (r[12] >> 8)); - pr_info("R[13]: %08x\n", r[13]); - pr_info("Fixed M: %06x\n", ((r[12] << 16) | (r[13] >> 16)) & 0xffffff); - pr_info("Valid / not / and1 / and2 : %1x\n", (r[13] >> 12) & 0xf); - pr_info("r 13-16: %08x %08x %08x %08x\n", r[13], r[14], r[15], r[16]); -} - -static int rtl931x_pie_rule_write(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr) -{ - /* Access IACL table (0) via register 1, the table size is 4096 */ - struct table_reg *q = rtl_table_get(RTL9310_TBL_1, 0); - u32 r[22]; - int block = idx / PIE_BLOCK_SIZE; - u32 t_select = sw_r32(RTL931X_PIE_BLK_TMPLTE_CTRL(block)); - - pr_info("%s: %d, t_select: %08x\n", __func__, idx, t_select); - - for (int i = 0; i < 22; i++) - r[i] = 0; - - if (!pr->valid) { - rtl_table_write(q, idx); - rtl_table_release(q); - return 0; - } - rtl931x_write_pie_fixed_fields(r, pr); - - pr_info("%s: template %d\n", __func__, (t_select >> (pr->tid * 4)) & 0xf); - rtl931x_write_pie_templated(r, pr, fixed_templates[(t_select >> (pr->tid * 4)) & 0xf]); - - rtl931x_write_pie_action(r, pr); - - rtl931x_pie_rule_dump_raw(r); - - for (int i = 0; i < 22; i++) - sw_w32(r[i], rtl_table_data(q, i)); - - rtl_table_write(q, idx); - rtl_table_release(q); - - return 0; -} - -static bool rtl931x_pie_templ_has(int t, enum template_field_id field_type) -{ - for (int i = 0; i < N_FIXED_FIELDS_RTL931X; i++) { - enum template_field_id ft = fixed_templates[t][i]; - if (field_type == ft) - return true; - } - - return false; -} - -/* Verify that the rule pr is compatible with a given template t in block block - * Note that this function is SoC specific since the values of e.g. TEMPLATE_FIELD_SIP0 - * depend on the SoC - */ -static int rtl931x_pie_verify_template(struct rtl838x_switch_priv *priv, - struct pie_rule *pr, int t, int block) -{ - int i; - - if (!pr->is_ipv6 && pr->sip_m && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_SIP0)) - return -1; - - if (!pr->is_ipv6 && pr->dip_m && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_DIP0)) - return -1; - - if (pr->is_ipv6) { - if ((pr->sip6_m.s6_addr32[0] || - pr->sip6_m.s6_addr32[1] || - pr->sip6_m.s6_addr32[2] || - pr->sip6_m.s6_addr32[3]) && - !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_SIP2)) - return -1; - if ((pr->dip6_m.s6_addr32[0] || - pr->dip6_m.s6_addr32[1] || - pr->dip6_m.s6_addr32[2] || - pr->dip6_m.s6_addr32[3]) && - !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_DIP2)) - return -1; - } - - if (ether_addr_to_u64(pr->smac) && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_SMAC0)) - return -1; - - if (ether_addr_to_u64(pr->dmac) && !rtl931x_pie_templ_has(t, TEMPLATE_FIELD_DMAC0)) - return -1; - - /* TODO: Check more */ - - i = find_first_zero_bit(&priv->pie_use_bm[block * 4], PIE_BLOCK_SIZE); - - if (i >= PIE_BLOCK_SIZE) - return -1; - - return i + PIE_BLOCK_SIZE * block; -} - -static int rtl931x_pie_rule_add(struct rtl838x_switch_priv *priv, struct pie_rule *pr) -{ - int idx, block, j; - int min_block = 0; - int max_block = priv->n_pie_blocks / 2; - - if (pr->is_egress) { - min_block = max_block; - max_block = priv->n_pie_blocks; - } - pr_info("In %s\n", __func__); - - mutex_lock(&priv->pie_mutex); - - for (block = min_block; block < max_block; block++) { - for (j = 0; j < 2; j++) { - int t = (sw_r32(RTL931X_PIE_BLK_TMPLTE_CTRL(block)) >> (j * 4)) & 0xf; - pr_info("Testing block %d, template %d, template id %d\n", block, j, t); - pr_info("%s: %08x\n", - __func__, sw_r32(RTL931X_PIE_BLK_TMPLTE_CTRL(block))); - idx = rtl931x_pie_verify_template(priv, pr, t, block); - if (idx >= 0) - break; - } - if (j < 2) - break; - } - - if (block >= priv->n_pie_blocks) { - mutex_unlock(&priv->pie_mutex); - return -EOPNOTSUPP; - } - - pr_info("Using block: %d, index %d, template-id %d\n", block, idx, j); - set_bit(idx, priv->pie_use_bm); - - pr->valid = true; - pr->tid = j; /* Mapped to template number */ - pr->tid_m = 0x1; - pr->id = idx; - - rtl931x_pie_lookup_enable(priv, idx); - rtl931x_pie_rule_write(priv, idx, pr); - - mutex_unlock(&priv->pie_mutex); - - return 0; -} - -/* Delete a range of Packet Inspection Engine rules */ -static int rtl931x_pie_rule_del(struct rtl838x_switch_priv *priv, int index_from, int index_to) -{ - u32 v = (index_from << 1)| (index_to << 13 ) | BIT(0); - - pr_info("%s: from %d to %d\n", __func__, index_from, index_to); - mutex_lock(&priv->reg_mutex); - - /* Write from-to and execute bit into control register */ - sw_w32(v, RTL931X_PIE_CLR_CTRL); - - /* Wait until command has completed */ - do { - } while (sw_r32(RTL931X_PIE_CLR_CTRL) & BIT(0)); - - mutex_unlock(&priv->reg_mutex); - - return 0; -} - -static void rtl931x_pie_rule_rm(struct rtl838x_switch_priv *priv, struct pie_rule *pr) -{ - int idx = pr->id; - - rtl931x_pie_rule_del(priv, idx, idx); - clear_bit(idx, priv->pie_use_bm); -} - -static void rtl931x_pie_init(struct rtl838x_switch_priv *priv) -{ - u32 template_selectors; - - mutex_init(&priv->pie_mutex); - - pr_info("%s\n", __func__); - /* Enable ACL lookup on all ports, including CPU_PORT */ - for (int i = 0; i <= priv->cpu_port; i++) - sw_w32(1, RTL931X_ACL_PORT_LOOKUP_CTRL(i)); - - /* Include IPG in metering */ - sw_w32_mask(0, 1, RTL931X_METER_GLB_CTRL); - - /* Delete all present rules, block size is 128 on all SoC families */ - rtl931x_pie_rule_del(priv, 0, priv->n_pie_blocks * 128 - 1); - - /* Assign first half blocks 0-7 to VACL phase, second half to IACL */ - /* 3 bits are used for each block, values for PIE blocks are */ - /* 6: Disabled, 0: VACL, 1: IACL, 2: EACL */ - /* And for OpenFlow Flow blocks: 3: Ingress Flow table 0, */ - /* 4: Ingress Flow Table 3, 5: Egress flow table 0 */ - for (int i = 0; i < priv->n_pie_blocks; i++) { - int pos = (i % 10) * 3; - u32 r = RTL931X_PIE_BLK_PHASE_CTRL + 4 * (i / 10); - - if (i < priv->n_pie_blocks / 2) - sw_w32_mask(0x7 << pos, 0, r); - else - sw_w32_mask(0x7 << pos, 1 << pos, r); - } - - /* Enable predefined templates 0, 1 for first quarter of all blocks */ - template_selectors = 0 | (1 << 4); - for (int i = 0; i < priv->n_pie_blocks / 4; i++) - sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 2, 3 for second quarter of all blocks */ - template_selectors = 2 | (3 << 4); - for (int i = priv->n_pie_blocks / 4; i < priv->n_pie_blocks / 2; i++) - sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 0, 1 for third quater of all blocks */ - template_selectors = 0 | (1 << 4); - for (int i = priv->n_pie_blocks / 2; i < priv->n_pie_blocks * 3 / 4; i++) - sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i)); - - /* Enable predefined templates 2, 3 for fourth quater of all blocks */ - template_selectors = 2 | (3 << 4); - for (int i = priv->n_pie_blocks * 3 / 4; i < priv->n_pie_blocks; i++) - sw_w32(template_selectors, RTL931X_PIE_BLK_TMPLTE_CTRL(i)); - -} - -int rtl931x_l3_setup(struct rtl838x_switch_priv *priv) -{ - return 0; -} - -void rtl931x_vlan_port_keep_tag_set(int port, bool keep_outer, bool keep_inner) -{ - sw_w32(FIELD_PREP(RTL931X_VLAN_PORT_TAG_EGR_OTAG_STS_MASK, - keep_outer ? RTL931X_VLAN_PORT_TAG_STS_TAGGED : RTL931X_VLAN_PORT_TAG_STS_UNTAG) | - FIELD_PREP(RTL931X_VLAN_PORT_TAG_EGR_ITAG_STS_MASK, - keep_inner ? RTL931X_VLAN_PORT_TAG_STS_TAGGED : RTL931X_VLAN_PORT_TAG_STS_UNTAG), - RTL931X_VLAN_PORT_TAG_CTRL(port)); -} - -void rtl931x_vlan_port_pvidmode_set(int port, enum pbvlan_type type, enum pbvlan_mode mode) -{ - if (type == PBVLAN_TYPE_INNER) - sw_w32_mask(0x3 << 12, mode << 12, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2)); - else - sw_w32_mask(0x3 << 26, mode << 26, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2)); -} - -void rtl931x_vlan_port_pvid_set(int port, enum pbvlan_type type, int pvid) -{ - if (type == PBVLAN_TYPE_INNER) - sw_w32_mask(0xfff, pvid, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2)); - else - sw_w32_mask(0xfff << 14, pvid << 14, RTL931X_VLAN_PORT_IGR_CTRL + (port << 2)); -} - -static void rtl931x_set_igr_filter(int port, enum igr_filter state) -{ - sw_w32_mask(0x3 << ((port & 0xf)<<1), state << ((port & 0xf)<<1), - RTL931X_VLAN_PORT_IGR_FLTR + (((port >> 4) << 2))); -} - -static void rtl931x_set_egr_filter(int port, enum egr_filter state) -{ - sw_w32_mask(0x1 << (port % 0x20), state << (port % 0x20), - RTL931X_VLAN_PORT_EGR_FLTR + (((port >> 5) << 2))); -} - -void rtl931x_set_distribution_algorithm(int group, int algoidx, u32 algomsk) -{ - u32 l3shift = 0; - u32 newmask = 0; - - /* TODO: for now we set algoidx to 0 */ - algoidx = 0; - - if (algomsk & TRUNK_DISTRIBUTION_ALGO_SIP_BIT) { - l3shift = 4; - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SIP_BIT; - } - if (algomsk & TRUNK_DISTRIBUTION_ALGO_DIP_BIT) { - l3shift = 4; - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_DIP_BIT; - } - if (algomsk & TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT) { - l3shift = 4; - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT; - } - if (algomsk & TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT) { - l3shift = 4; - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SRC_L4PORT_BIT; - } - - if (l3shift == 4) { - if (algomsk & TRUNK_DISTRIBUTION_ALGO_SMAC_BIT) - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_SMAC_BIT; - if (algomsk & TRUNK_DISTRIBUTION_ALGO_DMAC_BIT) - newmask |= TRUNK_DISTRIBUTION_ALGO_L3_DMAC_BIT; - } else { - if (algomsk & TRUNK_DISTRIBUTION_ALGO_SMAC_BIT) - newmask |= TRUNK_DISTRIBUTION_ALGO_L2_SMAC_BIT; - if (algomsk & TRUNK_DISTRIBUTION_ALGO_DMAC_BIT) - newmask |= TRUNK_DISTRIBUTION_ALGO_L2_DMAC_BIT; - } - - sw_w32(newmask << l3shift, RTL931X_TRK_HASH_CTRL + (algoidx << 2)); -} - -static void rtl931x_led_init(struct rtl838x_switch_priv *priv) -{ - u64 pm_copper = 0, pm_fiber = 0; - struct device_node *node; - - pr_info("%s called\n", __func__); - node = of_find_compatible_node(NULL, NULL, "realtek,rtl9300-leds"); - if (!node) { - pr_info("%s No compatible LED node found\n", __func__); - return; - } - - for (int i = 0; i < priv->cpu_port; i++) { - int pos = (i << 1) % 32; - u32 set; - u32 v; - - sw_w32_mask(0x3 << pos, 0, RTL931X_LED_PORT_FIB_SET_SEL_CTRL(i)); - sw_w32_mask(0x3 << pos, 0, RTL931X_LED_PORT_COPR_SET_SEL_CTRL(i)); - - if (!priv->ports[i].phy) - continue; - - v = 0x1; /* Found on the EdgeCore, but we do not have any HW description */ - sw_w32_mask(0x3 << pos, v << pos, RTL931X_LED_PORT_NUM_CTRL(i)); - - if (priv->ports[i].phy_is_integrated) - pm_fiber |= BIT_ULL(i); - else - pm_copper |= BIT_ULL(i); - - set = priv->ports[i].led_set; - sw_w32_mask(0, set << pos, RTL931X_LED_PORT_COPR_SET_SEL_CTRL(i)); - sw_w32_mask(0, set << pos, RTL931X_LED_PORT_FIB_SET_SEL_CTRL(i)); - } - - for (int i = 0; i < 4; i++) { - const __be32 *led_set; - char set_name[9]; - u32 setlen; - u32 v; - - sprintf(set_name, "led_set%d", i); - pr_info(">%s<\n", set_name); - led_set = of_get_property(node, set_name, &setlen); - if (!led_set || setlen != 16) - break; - v = be32_to_cpup(led_set) << 16 | be32_to_cpup(led_set + 1); - sw_w32(v, RTL931X_LED_SET0_0_CTRL - 4 - i * 8); - v = be32_to_cpup(led_set + 2) << 16 | be32_to_cpup(led_set + 3); - sw_w32(v, RTL931X_LED_SET0_0_CTRL - i * 8); - } - - /* Set LED mode to serial (0x1) */ - sw_w32_mask(0x3, 0x1, RTL931X_LED_GLB_CTRL); - - rtl839x_set_port_reg_le(pm_copper, RTL931X_LED_PORT_COPR_MASK_CTRL); - rtl839x_set_port_reg_le(pm_fiber, RTL931X_LED_PORT_FIB_MASK_CTRL); - rtl839x_set_port_reg_le(pm_copper | pm_fiber, RTL931X_LED_PORT_COMBO_MASK_CTRL); - - for (int i = 0; i < 32; i++) - pr_info("%s %08x: %08x\n",__func__, 0xbb000600 + i * 4, sw_r32(0x0600 + i * 4)); -} - -const struct rtl838x_reg rtl931x_reg = { - .mask_port_reg_be = rtl839x_mask_port_reg_be, - .set_port_reg_be = rtl839x_set_port_reg_be, - .get_port_reg_be = rtl839x_get_port_reg_be, - .mask_port_reg_le = rtl839x_mask_port_reg_le, - .set_port_reg_le = rtl839x_set_port_reg_le, - .get_port_reg_le = rtl839x_get_port_reg_le, - .stat_port_rst = RTL931X_STAT_PORT_RST, - .stat_rst = RTL931X_STAT_RST, - .stat_port_std_mib = 0, /* Not defined */ - .traffic_enable = rtl931x_traffic_enable, - .traffic_disable = rtl931x_traffic_disable, - .traffic_get = rtl931x_traffic_get, - .traffic_set = rtl931x_traffic_set, - .l2_ctrl_0 = RTL931X_L2_CTRL, - .l2_ctrl_1 = RTL931X_L2_AGE_CTRL, - .l2_port_aging_out = RTL931X_L2_PORT_AGE_CTRL, - .set_ageing_time = rtl931x_set_ageing_time, - /* .smi_poll_ctrl does not exist */ - .l2_tbl_flush_ctrl = RTL931X_L2_TBL_FLUSH_CTRL, - .exec_tbl0_cmd = rtl931x_exec_tbl0_cmd, - .exec_tbl1_cmd = rtl931x_exec_tbl1_cmd, - .tbl_access_data_0 = rtl931x_tbl_access_data_0, - .isr_glb_src = RTL931X_ISR_GLB_SRC, - .isr_port_link_sts_chg = RTL931X_ISR_PORT_LINK_STS_CHG, - .imr_port_link_sts_chg = RTL931X_IMR_PORT_LINK_STS_CHG, - /* imr_glb does not exist on RTL931X */ - .vlan_tables_read = rtl931x_vlan_tables_read, - .vlan_set_tagged = rtl931x_vlan_set_tagged, - .vlan_set_untagged = rtl931x_vlan_set_untagged, - .vlan_profile_dump = rtl931x_vlan_profile_dump, - .vlan_profile_setup = rtl931x_vlan_profile_setup, - .vlan_fwd_on_inner = rtl931x_vlan_fwd_on_inner, - .stp_get = rtl931x_stp_get, - .stp_set = rtl931x_stp_set, - .mac_force_mode_ctrl = rtl931x_mac_force_mode_ctrl, - .mac_port_ctrl = rtl931x_mac_port_ctrl, - .l2_port_new_salrn = rtl931x_l2_port_new_salrn, - .l2_port_new_sa_fwd = rtl931x_l2_port_new_sa_fwd, - .mir_ctrl = RTL931X_MIR_CTRL, - .mir_dpm = RTL931X_MIR_DPM_CTRL, - .mir_spm = RTL931X_MIR_SPM_CTRL, - .mac_link_sts = RTL931X_MAC_LINK_STS, - .mac_link_dup_sts = RTL931X_MAC_LINK_DUP_STS, - .mac_link_spd_sts = rtl931x_mac_link_spd_sts, - .mac_rx_pause_sts = RTL931X_MAC_RX_PAUSE_STS, - .mac_tx_pause_sts = RTL931X_MAC_TX_PAUSE_STS, - .read_l2_entry_using_hash = rtl931x_read_l2_entry_using_hash, - .write_l2_entry_using_hash = rtl931x_write_l2_entry_using_hash, - .read_cam = rtl931x_read_cam, - .write_cam = rtl931x_write_cam, - .vlan_port_keep_tag_set = rtl931x_vlan_port_keep_tag_set, - .vlan_port_pvidmode_set = rtl931x_vlan_port_pvidmode_set, - .vlan_port_pvid_set = rtl931x_vlan_port_pvid_set, - .trk_mbr_ctr = rtl931x_trk_mbr_ctr, - .set_vlan_igr_filter = rtl931x_set_igr_filter, - .set_vlan_egr_filter = rtl931x_set_egr_filter, - .set_distribution_algorithm = rtl931x_set_distribution_algorithm, - .l2_hash_key = rtl931x_l2_hash_key, - .read_mcast_pmask = rtl931x_read_mcast_pmask, - .write_mcast_pmask = rtl931x_write_mcast_pmask, - .pie_init = rtl931x_pie_init, - .pie_rule_write = rtl931x_pie_rule_write, - .pie_rule_add = rtl931x_pie_rule_add, - .pie_rule_rm = rtl931x_pie_rule_rm, - .l2_learning_setup = rtl931x_l2_learning_setup, - .l3_setup = rtl931x_l3_setup, - .led_init = rtl931x_led_init, -}; diff --git a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/tc.c b/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/tc.c deleted file mode 100644 index 3f7c31e04d38ea..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/dsa/rtl83xx/tc.c +++ /dev/null @@ -1,410 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include -#include -#include -#include -#include - -#include "rtl83xx.h" -#include "rtl838x.h" - -/* Parse the flow rule for the matching conditions */ -static int rtl83xx_parse_flow_rule(struct rtl838x_switch_priv *priv, - struct flow_rule *rule, struct rtl83xx_flow *flow) -{ - struct flow_dissector *dissector = rule->match.dissector; - - pr_debug("In %s\n", __func__); - /* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */ - if ((dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) == 0 || - (dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC)) == 0) { - pr_err("Cannot form TC key: used_keys = 0x%x\n", dissector->used_keys); - return -EOPNOTSUPP; - } - - if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { - struct flow_match_basic match; - - pr_debug("%s: BASIC\n", __func__); - flow_rule_match_basic(rule, &match); - if (match.key->n_proto == htons(ETH_P_ARP)) - flow->rule.frame_type = 0; - if (match.key->n_proto == htons(ETH_P_IP)) - flow->rule.frame_type = 2; - if (match.key->n_proto == htons(ETH_P_IPV6)) - flow->rule.frame_type = 3; - if ((match.key->n_proto == htons(ETH_P_ARP)) || flow->rule.frame_type) - flow->rule.frame_type_m = 3; - if (flow->rule.frame_type >= 2) { - if (match.key->ip_proto == IPPROTO_UDP) - flow->rule.frame_type_l4 = 0; - if (match.key->ip_proto == IPPROTO_TCP) - flow->rule.frame_type_l4 = 1; - if (match.key->ip_proto == IPPROTO_ICMP || match.key->ip_proto == IPPROTO_ICMPV6) - flow->rule.frame_type_l4 = 2; - if (match.key->ip_proto == IPPROTO_TCP) - flow->rule.frame_type_l4 = 3; - if ((match.key->ip_proto == IPPROTO_UDP) || flow->rule.frame_type_l4) - flow->rule.frame_type_l4_m = 7; - } - } - - if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { - struct flow_match_eth_addrs match; - - pr_debug("%s: ETH_ADDR\n", __func__); - flow_rule_match_eth_addrs(rule, &match); - ether_addr_copy(flow->rule.dmac, match.key->dst); - ether_addr_copy(flow->rule.dmac_m, match.mask->dst); - ether_addr_copy(flow->rule.smac, match.key->src); - ether_addr_copy(flow->rule.smac_m, match.mask->src); - } - - if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) { - struct flow_match_vlan match; - - pr_debug("%s: VLAN\n", __func__); - flow_rule_match_vlan(rule, &match); - flow->rule.itag = match.key->vlan_id; - flow->rule.itag_m = match.mask->vlan_id; - /* TODO: What about match.key->vlan_priority? */ - } - - if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) { - struct flow_match_ipv4_addrs match; - - pr_debug("%s: IPV4\n", __func__); - flow_rule_match_ipv4_addrs(rule, &match); - flow->rule.is_ipv6 = false; - flow->rule.dip = match.key->dst; - flow->rule.dip_m = match.mask->dst; - flow->rule.sip = match.key->src; - flow->rule.sip_m = match.mask->src; - } else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) { - struct flow_match_ipv6_addrs match; - - pr_debug("%s: IPV6\n", __func__); - flow->rule.is_ipv6 = true; - flow_rule_match_ipv6_addrs(rule, &match); - flow->rule.dip6 = match.key->dst; - flow->rule.dip6_m = match.mask->dst; - flow->rule.sip6 = match.key->src; - flow->rule.sip6_m = match.mask->src; - } - - if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { - struct flow_match_ports match; - - pr_debug("%s: PORTS\n", __func__); - flow_rule_match_ports(rule, &match); - flow->rule.dport = match.key->dst; - flow->rule.dport_m = match.mask->dst; - flow->rule.sport = match.key->src; - flow->rule.sport_m = match.mask->src; - } - - /* TODO: ICMP */ - return 0; -} - -static void rtl83xx_flow_bypass_all(struct rtl83xx_flow *flow) -{ - flow->rule.bypass_sel = true; - flow->rule.bypass_all = true; - flow->rule.bypass_igr_stp = true; - flow->rule.bypass_ibc_sc = true; -} - -static int rtl83xx_parse_fwd(struct rtl838x_switch_priv *priv, - const struct flow_action_entry *act, struct rtl83xx_flow *flow) -{ - struct net_device *dev = act->dev; - int port; - - port = rtl83xx_port_is_under(dev, priv); - if (port < 0) { - netdev_info(dev, "%s: not a DSA device.\n", __func__); - return -EINVAL; - } - - flow->rule.fwd_sel = true; - flow->rule.fwd_data = port; - pr_debug("Using port index: %d\n", port); - rtl83xx_flow_bypass_all(flow); - - return 0; -} - -static int rtl83xx_add_flow(struct rtl838x_switch_priv *priv, struct flow_cls_offload *f, - struct rtl83xx_flow *flow) -{ - struct flow_rule *rule = flow_cls_offload_flow_rule(f); - const struct flow_action_entry *act; - int i, err; - - pr_debug("%s\n", __func__); - - rtl83xx_parse_flow_rule(priv, rule, flow); - - flow_action_for_each(i, act, &rule->action) { - switch (act->id) { - case FLOW_ACTION_DROP: - pr_debug("%s: DROP\n", __func__); - flow->rule.drop = true; - rtl83xx_flow_bypass_all(flow); - return 0; - - case FLOW_ACTION_TRAP: - pr_debug("%s: TRAP\n", __func__); - flow->rule.fwd_data = priv->cpu_port; - flow->rule.fwd_act = PIE_ACT_REDIRECT_TO_PORT; - rtl83xx_flow_bypass_all(flow); - break; - - case FLOW_ACTION_MANGLE: - pr_err("%s: FLOW_ACTION_MANGLE not supported\n", __func__); - return -EOPNOTSUPP; - - case FLOW_ACTION_ADD: - pr_err("%s: FLOW_ACTION_ADD not supported\n", __func__); - return -EOPNOTSUPP; - - case FLOW_ACTION_VLAN_PUSH: - pr_debug("%s: VLAN_PUSH\n", __func__); -/* TODO: act->vlan.proto */ - flow->rule.ivid_act = PIE_ACT_VID_ASSIGN; - flow->rule.ivid_sel = true; - flow->rule.ivid_data = htons(act->vlan.vid); - flow->rule.ovid_act = PIE_ACT_VID_ASSIGN; - flow->rule.ovid_sel = true; - flow->rule.ovid_data = htons(act->vlan.vid); - flow->rule.fwd_mod_to_cpu = true; - break; - - case FLOW_ACTION_VLAN_POP: - pr_debug("%s: VLAN_POP\n", __func__); - flow->rule.ivid_act = PIE_ACT_VID_ASSIGN; - flow->rule.ivid_data = 0; - flow->rule.ivid_sel = true; - flow->rule.ovid_act = PIE_ACT_VID_ASSIGN; - flow->rule.ovid_data = 0; - flow->rule.ovid_sel = true; - flow->rule.fwd_mod_to_cpu = true; - break; - - case FLOW_ACTION_CSUM: - pr_err("%s: FLOW_ACTION_CSUM not supported\n", __func__); - return -EOPNOTSUPP; - - case FLOW_ACTION_REDIRECT: - pr_debug("%s: REDIRECT\n", __func__); - err = rtl83xx_parse_fwd(priv, act, flow); - if (err) - return err; - flow->rule.fwd_act = PIE_ACT_REDIRECT_TO_PORT; - break; - - case FLOW_ACTION_MIRRED: - pr_debug("%s: MIRRED\n", __func__); - err = rtl83xx_parse_fwd(priv, act, flow); - if (err) - return err; - flow->rule.fwd_act = PIE_ACT_COPY_TO_PORT; - break; - - default: - pr_err("%s: Flow action not supported: %d\n", __func__, act->id); - return -EOPNOTSUPP; - } - } - - return 0; -} - -static const struct rhashtable_params tc_ht_params = { - .head_offset = offsetof(struct rtl83xx_flow, node), - .key_offset = offsetof(struct rtl83xx_flow, cookie), - .key_len = sizeof(((struct rtl83xx_flow *)0)->cookie), - .automatic_shrinking = true, -}; - -static int rtl83xx_configure_flower(struct rtl838x_switch_priv *priv, - struct flow_cls_offload *f) -{ - struct rtl83xx_flow *flow; - int err = 0; - - pr_debug("In %s\n", __func__); - - rcu_read_lock(); - pr_debug("Cookie %08lx\n", f->cookie); - flow = rhashtable_lookup(&priv->tc_ht, &f->cookie, tc_ht_params); - if (flow) { - pr_info("%s: Got flow\n", __func__); - err = -EEXIST; - goto rcu_unlock; - } - -rcu_unlock: - rcu_read_unlock(); - if (flow) - goto out; - pr_debug("%s: New flow\n", __func__); - - flow = kzalloc(sizeof(*flow), GFP_KERNEL); - if (!flow) { - err = -ENOMEM; - goto out; - } - - flow->cookie = f->cookie; - flow->priv = priv; - - err = rhashtable_insert_fast(&priv->tc_ht, &flow->node, tc_ht_params); - if (err) { - pr_err("Could not insert add new rule\n"); - goto out_free; - } - - rtl83xx_add_flow(priv, f, flow); /* TODO: check error */ - - /* Add log action to flow */ - flow->rule.packet_cntr = rtl83xx_packet_cntr_alloc(priv); - if (flow->rule.packet_cntr >= 0) { - pr_debug("Using packet counter %d\n", flow->rule.packet_cntr); - flow->rule.log_sel = true; - flow->rule.log_data = flow->rule.packet_cntr; - } - - err = priv->r->pie_rule_add(priv, &flow->rule); - return err; - -out_free: - kfree(flow); -out: - pr_err("%s: error %d\n", __func__, err); - - return err; -} - -static int rtl83xx_delete_flower(struct rtl838x_switch_priv *priv, - struct flow_cls_offload * cls_flower) -{ - struct rtl83xx_flow *flow; - - pr_debug("In %s\n", __func__); - rcu_read_lock(); - flow = rhashtable_lookup_fast(&priv->tc_ht, &cls_flower->cookie, tc_ht_params); - if (!flow) { - rcu_read_unlock(); - return -EINVAL; - } - - priv->r->pie_rule_rm(priv, &flow->rule); - - rhashtable_remove_fast(&priv->tc_ht, &flow->node, tc_ht_params); - - kfree_rcu(flow, rcu_head); - - rcu_read_unlock(); - - return 0; -} - -static int rtl83xx_stats_flower(struct rtl838x_switch_priv *priv, - struct flow_cls_offload * cls_flower) -{ - struct rtl83xx_flow *flow; - unsigned long lastused = 0; - int total_packets, new_packets; - - pr_debug("%s: \n", __func__); - flow = rhashtable_lookup_fast(&priv->tc_ht, &cls_flower->cookie, tc_ht_params); - if (!flow) - return -1; - - if (flow->rule.packet_cntr >= 0) { - total_packets = priv->r->packet_cntr_read(flow->rule.packet_cntr); - pr_debug("Total packets: %d\n", total_packets); - new_packets = total_packets - flow->rule.last_packet_cnt; - flow->rule.last_packet_cnt = total_packets; - } - - /* TODO: We need a second PIE rule to count the bytes */ - flow_stats_update(&cls_flower->stats, 100 * new_packets, new_packets, 0, lastused, - FLOW_ACTION_HW_STATS_IMMEDIATE); - - return 0; -} - -static int rtl83xx_setup_tc_cls_flower(struct rtl838x_switch_priv *priv, - struct flow_cls_offload *cls_flower) -{ - pr_debug("%s: %d\n", __func__, cls_flower->command); - switch (cls_flower->command) { - case FLOW_CLS_REPLACE: - return rtl83xx_configure_flower(priv, cls_flower); - case FLOW_CLS_DESTROY: - return rtl83xx_delete_flower(priv, cls_flower); - case FLOW_CLS_STATS: - return rtl83xx_stats_flower(priv, cls_flower); - default: - return -EOPNOTSUPP; - } -} - - -static int rtl83xx_setup_tc_block_cb(enum tc_setup_type type, void *type_data, - void *cb_priv) -{ - struct rtl838x_switch_priv *priv = cb_priv; - - switch (type) { - case TC_SETUP_CLSFLOWER: - pr_debug("%s: TC_SETUP_CLSFLOWER\n", __func__); - return rtl83xx_setup_tc_cls_flower(priv, type_data); - default: - return -EOPNOTSUPP; - } -} - -static LIST_HEAD(rtl83xx_block_cb_list); - -int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data) -{ - struct rtl838x_switch_priv *priv; - struct flow_block_offload *f = type_data; - static bool first_time = true; - int err; - - pr_debug("%s: %d\n", __func__, type); - - if(!netdev_uses_dsa(dev)) { - pr_err("%s: no DSA\n", __func__); - return 0; - } - priv = dev->dsa_ptr->ds->priv; - - switch (type) { - case TC_SETUP_BLOCK: - if (first_time) { - first_time = false; - err = rhashtable_init(&priv->tc_ht, &tc_ht_params); - if (err) - pr_err("%s: Could not initialize hash table\n", __func__); - } - - f->unlocked_driver_cb = true; - return flow_block_cb_setup_simple(type_data, - &rtl83xx_block_cb_list, - rtl83xx_setup_tc_block_cb, - priv, priv, true); - default: - return -EOPNOTSUPP; - } - - return 0; -} diff --git a/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.c deleted file mode 100644 index 7ad9b5f0291d9c..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.c +++ /dev/null @@ -1,2733 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* linux/drivers/net/ethernet/rtl838x_eth.c - * Copyright (C) 2020 B. Koblitz - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "rtl838x_eth.h" - -extern struct rtl83xx_soc_info soc_info; - -/* Maximum number of RX rings is 8 on RTL83XX and 32 on the 93XX - * The ring is assigned by switch based on packet/port priortity - * Maximum number of TX rings is 2, Ring 2 being the high priority - * ring on the RTL93xx SoCs. MAX_RXLEN gives the maximum length - * for an RX ring, MAX_ENTRIES the maximum number of entries - * available in total for all queues. - */ -#define MAX_RXRINGS 32 -#define MAX_RXLEN 300 -#define MAX_ENTRIES (300 * 8) -#define TXRINGS 2 -#define TXRINGLEN 160 -#define NOTIFY_EVENTS 10 -#define NOTIFY_BLOCKS 10 -#define TX_EN 0x8 -#define RX_EN 0x4 -#define TX_EN_93XX 0x20 -#define RX_EN_93XX 0x10 -#define RX_TRUNCATE_EN_93XX BIT(6) -#define RX_TRUNCATE_EN_83XX BIT(4) -#define TX_PAD_EN_838X BIT(5) -#define TX_DO 0x2 -#define WRAP 0x2 -#define MAX_PORTS 57 -#define MAX_SMI_BUSSES 4 - -#define RING_BUFFER 1600 - -struct p_hdr { - uint8_t *buf; - uint16_t reserved; - uint16_t size; /* buffer size */ - uint16_t offset; - uint16_t len; /* pkt len */ - /* cpu_tag[0] is a reserved uint16_t on RTL83xx */ - uint16_t cpu_tag[10]; -} __packed __aligned(1); - -struct n_event { - uint32_t type:2; - uint32_t fidVid:12; - uint64_t mac:48; - uint32_t slp:6; - uint32_t valid:1; - uint32_t reserved:27; -} __packed __aligned(1); - -struct ring_b { - uint32_t rx_r[MAX_RXRINGS][MAX_RXLEN]; - uint32_t tx_r[TXRINGS][TXRINGLEN]; - struct p_hdr rx_header[MAX_RXRINGS][MAX_RXLEN]; - struct p_hdr tx_header[TXRINGS][TXRINGLEN]; - uint32_t c_rx[MAX_RXRINGS]; - uint32_t c_tx[TXRINGS]; - uint8_t tx_space[TXRINGS * TXRINGLEN * RING_BUFFER]; - uint8_t *rx_space; -}; - -struct notify_block { - struct n_event events[NOTIFY_EVENTS]; -}; - -struct notify_b { - struct notify_block blocks[NOTIFY_BLOCKS]; - u32 reserved1[8]; - u32 ring[NOTIFY_BLOCKS]; - u32 reserved2[8]; -}; - -static void rtl838x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio) -{ - /* cpu_tag[0] is reserved on the RTL83XX SoCs */ - h->cpu_tag[1] = 0x0400; /* BIT 10: RTL8380_CPU_TAG */ - h->cpu_tag[2] = 0x0200; /* Set only AS_DPM, to enable DPM settings below */ - h->cpu_tag[3] = 0x0000; - h->cpu_tag[4] = BIT(dest_port) >> 16; - h->cpu_tag[5] = BIT(dest_port) & 0xffff; - - /* Set internal priority (PRI) and enable (AS_PRI) */ - if (prio >= 0) - h->cpu_tag[2] |= ((prio & 0x7) | BIT(3)) << 12; -} - -static void rtl839x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio) -{ - /* cpu_tag[0] is reserved on the RTL83XX SoCs */ - h->cpu_tag[1] = 0x0100; /* RTL8390_CPU_TAG marker */ - h->cpu_tag[2] = BIT(4); /* AS_DPM flag */ - h->cpu_tag[3] = h->cpu_tag[4] = h->cpu_tag[5] = 0; - /* h->cpu_tag[1] |= BIT(1) | BIT(0); */ /* Bypass filter 1/2 */ - if (dest_port >= 32) { - dest_port -= 32; - h->cpu_tag[2] |= (BIT(dest_port) >> 16) & 0xf; - h->cpu_tag[3] = BIT(dest_port) & 0xffff; - } else { - h->cpu_tag[4] = BIT(dest_port) >> 16; - h->cpu_tag[5] = BIT(dest_port) & 0xffff; - } - - /* Set internal priority (PRI) and enable (AS_PRI) */ - if (prio >= 0) - h->cpu_tag[2] |= ((prio & 0x7) | BIT(3)) << 8; -} - -static void rtl930x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio) -{ - h->cpu_tag[0] = 0x8000; /* CPU tag marker */ - h->cpu_tag[1] = h->cpu_tag[2] = 0; - h->cpu_tag[3] = 0; - h->cpu_tag[4] = 0; - h->cpu_tag[5] = 0; - h->cpu_tag[6] = BIT(dest_port) >> 16; - h->cpu_tag[7] = BIT(dest_port) & 0xffff; - - /* Enable (AS_QID) and set priority queue (QID) */ - if (prio >= 0) - h->cpu_tag[2] = (BIT(5) | (prio & 0x1f)) << 8; -} - -static void rtl931x_create_tx_header(struct p_hdr *h, unsigned int dest_port, int prio) -{ - h->cpu_tag[0] = 0x8000; /* CPU tag marker */ - h->cpu_tag[1] = h->cpu_tag[2] = 0; - h->cpu_tag[3] = 0; - h->cpu_tag[4] = h->cpu_tag[5] = h->cpu_tag[6] = h->cpu_tag[7] = 0; - if (dest_port >= 32) { - dest_port -= 32; - h->cpu_tag[4] = BIT(dest_port) >> 16; - h->cpu_tag[5] = BIT(dest_port) & 0xffff; - } else { - h->cpu_tag[6] = BIT(dest_port) >> 16; - h->cpu_tag[7] = BIT(dest_port) & 0xffff; - } - - /* Enable (AS_QID) and set priority queue (QID) */ - if (prio >= 0) - h->cpu_tag[2] = (BIT(5) | (prio & 0x1f)) << 8; -} - -// Currently unused -// static void rtl93xx_header_vlan_set(struct p_hdr *h, int vlan) -// { -// h->cpu_tag[2] |= BIT(4); /* Enable VLAN forwarding offload */ -// h->cpu_tag[2] |= (vlan >> 8) & 0xf; -// h->cpu_tag[3] |= (vlan & 0xff) << 8; -// } - -struct rtl838x_rx_q { - int id; - struct rtl838x_eth_priv *priv; - struct napi_struct napi; -}; - -struct rtl838x_eth_priv { - struct net_device *netdev; - struct platform_device *pdev; - void *membase; - spinlock_t lock; - struct mii_bus *mii_bus; - struct rtl838x_rx_q rx_qs[MAX_RXRINGS]; - struct phylink *phylink; - struct phylink_config phylink_config; - u16 id; - u16 family_id; - const struct rtl838x_eth_reg *r; - u8 cpu_port; - u32 lastEvent; - u16 rxrings; - u16 rxringlen; - u8 smi_bus[MAX_PORTS]; - u8 smi_addr[MAX_PORTS]; - u32 sds_id[MAX_PORTS]; - bool smi_bus_isc45[MAX_SMI_BUSSES]; - bool phy_is_internal[MAX_PORTS]; - phy_interface_t interfaces[MAX_PORTS]; -}; - -extern int rtl838x_phy_init(struct rtl838x_eth_priv *priv); -extern int rtl838x_read_sds_phy(int phy_addr, int phy_reg); -extern int rtl839x_read_sds_phy(int phy_addr, int phy_reg); -extern int rtl839x_write_sds_phy(int phy_addr, int phy_reg, u16 v); -extern int rtl930x_read_sds_phy(int phy_addr, int page, int phy_reg); -extern int rtl930x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v); -extern int rtl931x_read_sds_phy(int phy_addr, int page, int phy_reg); -extern int rtl931x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v); -extern int rtl930x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val); -extern int rtl930x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val); -extern int rtl931x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val); -extern int rtl931x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val); - -/* On the RTL93XX, the RTL93XX_DMA_IF_RX_RING_CNTR track the fill level of - * the rings. Writing x into these registers substracts x from its content. - * When the content reaches the ring size, the ASIC no longer adds - * packets to this receive queue. - */ -void rtl838x_update_cntr(int r, int released) -{ - /* This feature is not available on RTL838x SoCs */ -} - -void rtl839x_update_cntr(int r, int released) -{ - /* This feature is not available on RTL839x SoCs */ -} - -void rtl930x_update_cntr(int r, int released) -{ - int pos = (r % 3) * 10; - u32 reg = RTL930X_DMA_IF_RX_RING_CNTR + ((r / 3) << 2); - u32 v = sw_r32(reg); - - v = (v >> pos) & 0x3ff; - pr_debug("RX: Work done %d, old value: %d, pos %d, reg %04x\n", released, v, pos, reg); - sw_w32_mask(0x3ff << pos, released << pos, reg); - sw_w32(v, reg); -} - -void rtl931x_update_cntr(int r, int released) -{ - int pos = (r % 3) * 10; - u32 reg = RTL931X_DMA_IF_RX_RING_CNTR + ((r / 3) << 2); - u32 v = sw_r32(reg); - - v = (v >> pos) & 0x3ff; - sw_w32_mask(0x3ff << pos, released << pos, reg); - sw_w32(v, reg); -} - -struct dsa_tag { - u8 reason; - u8 queue; - u16 port; - u8 l2_offloaded; - u8 prio; - bool crc_error; -}; - -bool rtl838x_decode_tag(struct p_hdr *h, struct dsa_tag *t) -{ - /* cpu_tag[0] is reserved. Fields are off-by-one */ - t->reason = h->cpu_tag[4] & 0xf; - t->queue = (h->cpu_tag[1] & 0xe0) >> 5; - t->port = h->cpu_tag[1] & 0x1f; - t->crc_error = t->reason == 13; - - pr_debug("Reason: %d\n", t->reason); - if (t->reason != 6) /* NIC_RX_REASON_SPECIAL_TRAP */ - t->l2_offloaded = 1; - else - t->l2_offloaded = 0; - - return t->l2_offloaded; -} - -bool rtl839x_decode_tag(struct p_hdr *h, struct dsa_tag *t) -{ - /* cpu_tag[0] is reserved. Fields are off-by-one */ - t->reason = h->cpu_tag[5] & 0x1f; - t->queue = (h->cpu_tag[4] & 0xe000) >> 13; - t->port = h->cpu_tag[1] & 0x3f; - t->crc_error = h->cpu_tag[4] & BIT(6); - - pr_debug("Reason: %d\n", t->reason); - if ((t->reason >= 7 && t->reason <= 13) || /* NIC_RX_REASON_RMA */ - (t->reason >= 23 && t->reason <= 25)) /* NIC_RX_REASON_SPECIAL_TRAP */ - t->l2_offloaded = 0; - else - t->l2_offloaded = 1; - - return t->l2_offloaded; -} - -bool rtl930x_decode_tag(struct p_hdr *h, struct dsa_tag *t) -{ - t->reason = h->cpu_tag[7] & 0x3f; - t->queue = (h->cpu_tag[2] >> 11) & 0x1f; - t->port = (h->cpu_tag[0] >> 8) & 0x1f; - t->crc_error = h->cpu_tag[1] & BIT(6); - - pr_debug("Reason %d, port %d, queue %d\n", t->reason, t->port, t->queue); - if (t->reason >= 19 && t->reason <= 27) - t->l2_offloaded = 0; - else - t->l2_offloaded = 1; - - return t->l2_offloaded; -} - -bool rtl931x_decode_tag(struct p_hdr *h, struct dsa_tag *t) -{ - t->reason = h->cpu_tag[7] & 0x3f; - t->queue = (h->cpu_tag[2] >> 11) & 0x1f; - t->port = (h->cpu_tag[0] >> 8) & 0x3f; - t->crc_error = h->cpu_tag[1] & BIT(6); - - if (t->reason != 63) - pr_info("%s: Reason %d, port %d, queue %d\n", __func__, t->reason, t->port, t->queue); - if (t->reason >= 19 && t->reason <= 27) /* NIC_RX_REASON_RMA */ - t->l2_offloaded = 0; - else - t->l2_offloaded = 1; - - return t->l2_offloaded; -} - -/* Discard the RX ring-buffers, called as part of the net-ISR - * when the buffer runs over - */ -static void rtl838x_rb_cleanup(struct rtl838x_eth_priv *priv, int status) -{ - for (int r = 0; r < priv->rxrings; r++) { - struct ring_b *ring = priv->membase; - struct p_hdr *h; - u32 *last; - - pr_debug("In %s working on r: %d\n", __func__, r); - last = (u32 *)KSEG1ADDR(sw_r32(priv->r->dma_if_rx_cur + r * 4)); - do { - if ((ring->rx_r[r][ring->c_rx[r]] & 0x1)) - break; - pr_debug("Got something: %d\n", ring->c_rx[r]); - h = &ring->rx_header[r][ring->c_rx[r]]; - memset(h, 0, sizeof(struct p_hdr)); - h->buf = (u8 *)KSEG1ADDR(ring->rx_space + - r * priv->rxringlen * RING_BUFFER + - ring->c_rx[r] * RING_BUFFER); - h->size = RING_BUFFER; - /* make sure the header is visible to the ASIC */ - mb(); - - ring->rx_r[r][ring->c_rx[r]] = KSEG1ADDR(h) | 0x1 | (ring->c_rx[r] == (priv->rxringlen - 1) ? - WRAP : - 0x1); - ring->c_rx[r] = (ring->c_rx[r] + 1) % priv->rxringlen; - } while (&ring->rx_r[r][ring->c_rx[r]] != last); - } -} - -struct fdb_update_work { - struct work_struct work; - struct net_device *ndev; - u64 macs[NOTIFY_EVENTS + 1]; -}; - -void rtl838x_fdb_sync(struct work_struct *work) -{ - const struct fdb_update_work *uw = container_of(work, struct fdb_update_work, work); - - for (int i = 0; uw->macs[i]; i++) { - struct switchdev_notifier_fdb_info info; - u8 addr[ETH_ALEN]; - int action; - - action = (uw->macs[i] & (1ULL << 63)) ? - SWITCHDEV_FDB_ADD_TO_BRIDGE : - SWITCHDEV_FDB_DEL_TO_BRIDGE; - u64_to_ether_addr(uw->macs[i] & 0xffffffffffffULL, addr); - info.addr = &addr[0]; - info.vid = 0; - info.offloaded = 1; - pr_debug("FDB entry %d: %llx, action %d\n", i, uw->macs[0], action); - call_switchdev_notifiers(action, uw->ndev, &info.info, NULL); - } - kfree(work); -} - -static void rtl839x_l2_notification_handler(struct rtl838x_eth_priv *priv) -{ - struct notify_b *nb = priv->membase + sizeof(struct ring_b); - u32 e = priv->lastEvent; - - while (!(nb->ring[e] & 1)) { - struct fdb_update_work *w; - struct n_event *event; - u64 mac; - int i; - - w = kzalloc(sizeof(*w), GFP_ATOMIC); - if (!w) { - pr_err("Out of memory: %s", __func__); - return; - } - INIT_WORK(&w->work, rtl838x_fdb_sync); - - for (i = 0; i < NOTIFY_EVENTS; i++) { - event = &nb->blocks[e].events[i]; - if (!event->valid) - continue; - mac = event->mac; - if (event->type) - mac |= 1ULL << 63; - w->ndev = priv->netdev; - w->macs[i] = mac; - } - - /* Hand the ring entry back to the switch */ - nb->ring[e] = nb->ring[e] | 1; - e = (e + 1) % NOTIFY_BLOCKS; - - w->macs[i] = 0ULL; - schedule_work(&w->work); - } - priv->lastEvent = e; -} - -static irqreturn_t rtl83xx_net_irq(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct rtl838x_eth_priv *priv = netdev_priv(dev); - u32 status = sw_r32(priv->r->dma_if_intr_sts); - - pr_debug("IRQ: %08x\n", status); - - /* Ignore TX interrupt */ - if ((status & 0xf0000)) { - /* Clear ISR */ - sw_w32(0x000f0000, priv->r->dma_if_intr_sts); - } - - /* RX interrupt */ - if (status & 0x0ff00) { - /* ACK and disable RX interrupt for this ring */ - sw_w32_mask(0xff00 & status, 0, priv->r->dma_if_intr_msk); - sw_w32(0x0000ff00 & status, priv->r->dma_if_intr_sts); - for (int i = 0; i < priv->rxrings; i++) { - if (status & BIT(i + 8)) { - pr_debug("Scheduling queue: %d\n", i); - napi_schedule(&priv->rx_qs[i].napi); - } - } - } - - /* RX buffer overrun */ - if (status & 0x000ff) { - pr_debug("RX buffer overrun: status %x, mask: %x\n", - status, sw_r32(priv->r->dma_if_intr_msk)); - sw_w32(status, priv->r->dma_if_intr_sts); - rtl838x_rb_cleanup(priv, status & 0xff); - } - - if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00100000) { - sw_w32(0x00100000, priv->r->dma_if_intr_sts); - rtl839x_l2_notification_handler(priv); - } - - if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00200000) { - sw_w32(0x00200000, priv->r->dma_if_intr_sts); - rtl839x_l2_notification_handler(priv); - } - - if (priv->family_id == RTL8390_FAMILY_ID && status & 0x00400000) { - sw_w32(0x00400000, priv->r->dma_if_intr_sts); - rtl839x_l2_notification_handler(priv); - } - - return IRQ_HANDLED; -} - -static irqreturn_t rtl93xx_net_irq(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct rtl838x_eth_priv *priv = netdev_priv(dev); - u32 status_rx_r = sw_r32(priv->r->dma_if_intr_rx_runout_sts); - u32 status_rx = sw_r32(priv->r->dma_if_intr_rx_done_sts); - u32 status_tx = sw_r32(priv->r->dma_if_intr_tx_done_sts); - - pr_debug("In %s, status_tx: %08x, status_rx: %08x, status_rx_r: %08x\n", - __func__, status_tx, status_rx, status_rx_r); - - /* Ignore TX interrupt */ - if (status_tx) { - /* Clear ISR */ - pr_debug("TX done\n"); - sw_w32(status_tx, priv->r->dma_if_intr_tx_done_sts); - } - - /* RX interrupt */ - if (status_rx) { - pr_debug("RX IRQ\n"); - /* ACK and disable RX interrupt for given rings */ - sw_w32(status_rx, priv->r->dma_if_intr_rx_done_sts); - sw_w32_mask(status_rx, 0, priv->r->dma_if_intr_rx_done_msk); - for (int i = 0; i < priv->rxrings; i++) { - if (status_rx & BIT(i)) { - pr_debug("Scheduling queue: %d\n", i); - napi_schedule(&priv->rx_qs[i].napi); - } - } - } - - /* RX buffer overrun */ - if (status_rx_r) { - pr_debug("RX buffer overrun: status %x, mask: %x\n", - status_rx_r, sw_r32(priv->r->dma_if_intr_rx_runout_msk)); - sw_w32(status_rx_r, priv->r->dma_if_intr_rx_runout_sts); - rtl838x_rb_cleanup(priv, status_rx_r); - } - - return IRQ_HANDLED; -} - -static const struct rtl838x_eth_reg rtl838x_reg = { - .net_irq = rtl83xx_net_irq, - .mac_port_ctrl = rtl838x_mac_port_ctrl, - .dma_if_intr_sts = RTL838X_DMA_IF_INTR_STS, - .dma_if_intr_msk = RTL838X_DMA_IF_INTR_MSK, - .dma_if_ctrl = RTL838X_DMA_IF_CTRL, - .mac_force_mode_ctrl = RTL838X_MAC_FORCE_MODE_CTRL, - .dma_rx_base = RTL838X_DMA_RX_BASE, - .dma_tx_base = RTL838X_DMA_TX_BASE, - .dma_if_rx_ring_size = rtl838x_dma_if_rx_ring_size, - .dma_if_rx_ring_cntr = rtl838x_dma_if_rx_ring_cntr, - .dma_if_rx_cur = RTL838X_DMA_IF_RX_CUR, - .rst_glb_ctrl = RTL838X_RST_GLB_CTRL_0, - .get_mac_link_sts = rtl838x_get_mac_link_sts, - .get_mac_link_dup_sts = rtl838x_get_mac_link_dup_sts, - .get_mac_link_spd_sts = rtl838x_get_mac_link_spd_sts, - .get_mac_rx_pause_sts = rtl838x_get_mac_rx_pause_sts, - .get_mac_tx_pause_sts = rtl838x_get_mac_tx_pause_sts, - .mac = RTL838X_MAC, - .l2_tbl_flush_ctrl = RTL838X_L2_TBL_FLUSH_CTRL, - .update_cntr = rtl838x_update_cntr, - .create_tx_header = rtl838x_create_tx_header, - .decode_tag = rtl838x_decode_tag, -}; - -static const struct rtl838x_eth_reg rtl839x_reg = { - .net_irq = rtl83xx_net_irq, - .mac_port_ctrl = rtl839x_mac_port_ctrl, - .dma_if_intr_sts = RTL839X_DMA_IF_INTR_STS, - .dma_if_intr_msk = RTL839X_DMA_IF_INTR_MSK, - .dma_if_ctrl = RTL839X_DMA_IF_CTRL, - .mac_force_mode_ctrl = RTL839X_MAC_FORCE_MODE_CTRL, - .dma_rx_base = RTL839X_DMA_RX_BASE, - .dma_tx_base = RTL839X_DMA_TX_BASE, - .dma_if_rx_ring_size = rtl839x_dma_if_rx_ring_size, - .dma_if_rx_ring_cntr = rtl839x_dma_if_rx_ring_cntr, - .dma_if_rx_cur = RTL839X_DMA_IF_RX_CUR, - .rst_glb_ctrl = RTL839X_RST_GLB_CTRL, - .get_mac_link_sts = rtl839x_get_mac_link_sts, - .get_mac_link_dup_sts = rtl839x_get_mac_link_dup_sts, - .get_mac_link_spd_sts = rtl839x_get_mac_link_spd_sts, - .get_mac_rx_pause_sts = rtl839x_get_mac_rx_pause_sts, - .get_mac_tx_pause_sts = rtl839x_get_mac_tx_pause_sts, - .mac = RTL839X_MAC, - .l2_tbl_flush_ctrl = RTL839X_L2_TBL_FLUSH_CTRL, - .update_cntr = rtl839x_update_cntr, - .create_tx_header = rtl839x_create_tx_header, - .decode_tag = rtl839x_decode_tag, -}; - -static const struct rtl838x_eth_reg rtl930x_reg = { - .net_irq = rtl93xx_net_irq, - .mac_port_ctrl = rtl930x_mac_port_ctrl, - .dma_if_intr_rx_runout_sts = RTL930X_DMA_IF_INTR_RX_RUNOUT_STS, - .dma_if_intr_rx_done_sts = RTL930X_DMA_IF_INTR_RX_DONE_STS, - .dma_if_intr_tx_done_sts = RTL930X_DMA_IF_INTR_TX_DONE_STS, - .dma_if_intr_rx_runout_msk = RTL930X_DMA_IF_INTR_RX_RUNOUT_MSK, - .dma_if_intr_rx_done_msk = RTL930X_DMA_IF_INTR_RX_DONE_MSK, - .dma_if_intr_tx_done_msk = RTL930X_DMA_IF_INTR_TX_DONE_MSK, - .l2_ntfy_if_intr_sts = RTL930X_L2_NTFY_IF_INTR_STS, - .l2_ntfy_if_intr_msk = RTL930X_L2_NTFY_IF_INTR_MSK, - .dma_if_ctrl = RTL930X_DMA_IF_CTRL, - .mac_force_mode_ctrl = RTL930X_MAC_FORCE_MODE_CTRL, - .dma_rx_base = RTL930X_DMA_RX_BASE, - .dma_tx_base = RTL930X_DMA_TX_BASE, - .dma_if_rx_ring_size = rtl930x_dma_if_rx_ring_size, - .dma_if_rx_ring_cntr = rtl930x_dma_if_rx_ring_cntr, - .dma_if_rx_cur = RTL930X_DMA_IF_RX_CUR, - .rst_glb_ctrl = RTL930X_RST_GLB_CTRL_0, - .get_mac_link_sts = rtl930x_get_mac_link_sts, - .get_mac_link_dup_sts = rtl930x_get_mac_link_dup_sts, - .get_mac_link_spd_sts = rtl930x_get_mac_link_spd_sts, - .get_mac_rx_pause_sts = rtl930x_get_mac_rx_pause_sts, - .get_mac_tx_pause_sts = rtl930x_get_mac_tx_pause_sts, - .mac = RTL930X_MAC_L2_ADDR_CTRL, - .l2_tbl_flush_ctrl = RTL930X_L2_TBL_FLUSH_CTRL, - .update_cntr = rtl930x_update_cntr, - .create_tx_header = rtl930x_create_tx_header, - .decode_tag = rtl930x_decode_tag, -}; - -static const struct rtl838x_eth_reg rtl931x_reg = { - .net_irq = rtl93xx_net_irq, - .mac_port_ctrl = rtl931x_mac_port_ctrl, - .dma_if_intr_rx_runout_sts = RTL931X_DMA_IF_INTR_RX_RUNOUT_STS, - .dma_if_intr_rx_done_sts = RTL931X_DMA_IF_INTR_RX_DONE_STS, - .dma_if_intr_tx_done_sts = RTL931X_DMA_IF_INTR_TX_DONE_STS, - .dma_if_intr_rx_runout_msk = RTL931X_DMA_IF_INTR_RX_RUNOUT_MSK, - .dma_if_intr_rx_done_msk = RTL931X_DMA_IF_INTR_RX_DONE_MSK, - .dma_if_intr_tx_done_msk = RTL931X_DMA_IF_INTR_TX_DONE_MSK, - .l2_ntfy_if_intr_sts = RTL931X_L2_NTFY_IF_INTR_STS, - .l2_ntfy_if_intr_msk = RTL931X_L2_NTFY_IF_INTR_MSK, - .dma_if_ctrl = RTL931X_DMA_IF_CTRL, - .mac_force_mode_ctrl = RTL931X_MAC_FORCE_MODE_CTRL, - .dma_rx_base = RTL931X_DMA_RX_BASE, - .dma_tx_base = RTL931X_DMA_TX_BASE, - .dma_if_rx_ring_size = rtl931x_dma_if_rx_ring_size, - .dma_if_rx_ring_cntr = rtl931x_dma_if_rx_ring_cntr, - .dma_if_rx_cur = RTL931X_DMA_IF_RX_CUR, - .rst_glb_ctrl = RTL931X_RST_GLB_CTRL, - .get_mac_link_sts = rtl931x_get_mac_link_sts, - .get_mac_link_dup_sts = rtl931x_get_mac_link_dup_sts, - .get_mac_link_spd_sts = rtl931x_get_mac_link_spd_sts, - .get_mac_rx_pause_sts = rtl931x_get_mac_rx_pause_sts, - .get_mac_tx_pause_sts = rtl931x_get_mac_tx_pause_sts, - .mac = RTL931X_MAC_L2_ADDR_CTRL, - .l2_tbl_flush_ctrl = RTL931X_L2_TBL_FLUSH_CTRL, - .update_cntr = rtl931x_update_cntr, - .create_tx_header = rtl931x_create_tx_header, - .decode_tag = rtl931x_decode_tag, -}; - -static void rtl838x_hw_reset(struct rtl838x_eth_priv *priv) -{ - u32 int_saved, nbuf; - u32 reset_mask; - - pr_info("RESETTING %x, CPU_PORT %d\n", priv->family_id, priv->cpu_port); - sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(priv->cpu_port)); - mdelay(100); - - /* Disable and clear interrupts */ - if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) { - sw_w32(0x00000000, priv->r->dma_if_intr_rx_runout_msk); - sw_w32(0xffffffff, priv->r->dma_if_intr_rx_runout_sts); - sw_w32(0x00000000, priv->r->dma_if_intr_rx_done_msk); - sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_sts); - sw_w32(0x00000000, priv->r->dma_if_intr_tx_done_msk); - sw_w32(0x0000000f, priv->r->dma_if_intr_tx_done_sts); - } else { - sw_w32(0x00000000, priv->r->dma_if_intr_msk); - sw_w32(0xffffffff, priv->r->dma_if_intr_sts); - } - - if (priv->family_id == RTL8390_FAMILY_ID) { - /* Preserve L2 notification and NBUF settings */ - int_saved = sw_r32(priv->r->dma_if_intr_msk); - nbuf = sw_r32(RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL); - - /* Disable link change interrupt on RTL839x */ - sw_w32(0, RTL839X_IMR_PORT_LINK_STS_CHG); - sw_w32(0, RTL839X_IMR_PORT_LINK_STS_CHG + 4); - - sw_w32(0x00000000, priv->r->dma_if_intr_msk); - sw_w32(0xffffffff, priv->r->dma_if_intr_sts); - } - - /* Reset NIC (SW_NIC_RST) and queues (SW_Q_RST) */ - if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) - reset_mask = 0x6; - else - reset_mask = 0xc; - - sw_w32_mask(0, reset_mask, priv->r->rst_glb_ctrl); - - do { /* Wait for reset of NIC and Queues done */ - udelay(20); - } while (sw_r32(priv->r->rst_glb_ctrl) & reset_mask); - mdelay(100); - - /* Setup Head of Line */ - if (priv->family_id == RTL8380_FAMILY_ID) - sw_w32(0, RTL838X_DMA_IF_RX_RING_SIZE); /* Disabled on RTL8380 */ - if (priv->family_id == RTL8390_FAMILY_ID) - sw_w32(0xffffffff, RTL839X_DMA_IF_RX_RING_CNTR); - if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) { - for (int i = 0; i < priv->rxrings; i++) { - int pos = (i % 3) * 10; - - sw_w32_mask(0x3ff << pos, 0, priv->r->dma_if_rx_ring_size(i)); - sw_w32_mask(0x3ff << pos, priv->rxringlen, - priv->r->dma_if_rx_ring_cntr(i)); - } - } - - /* Re-enable link change interrupt */ - if (priv->family_id == RTL8390_FAMILY_ID) { - sw_w32(0xffffffff, RTL839X_ISR_PORT_LINK_STS_CHG); - sw_w32(0xffffffff, RTL839X_ISR_PORT_LINK_STS_CHG + 4); - sw_w32(0xffffffff, RTL839X_IMR_PORT_LINK_STS_CHG); - sw_w32(0xffffffff, RTL839X_IMR_PORT_LINK_STS_CHG + 4); - - /* Restore notification settings: on RTL838x these bits are null */ - sw_w32_mask(7 << 20, int_saved & (7 << 20), priv->r->dma_if_intr_msk); - sw_w32(nbuf, RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL); - } -} - -static void rtl838x_hw_ring_setup(struct rtl838x_eth_priv *priv) -{ - struct ring_b *ring = priv->membase; - - for (int i = 0; i < priv->rxrings; i++) - sw_w32(KSEG1ADDR(&ring->rx_r[i]), priv->r->dma_rx_base + i * 4); - - for (int i = 0; i < TXRINGS; i++) - sw_w32(KSEG1ADDR(&ring->tx_r[i]), priv->r->dma_tx_base + i * 4); -} - -static void rtl838x_hw_en_rxtx(struct rtl838x_eth_priv *priv) -{ - /* Disable Head of Line features for all RX rings */ - sw_w32(0xffffffff, priv->r->dma_if_rx_ring_size(0)); - - /* Truncate RX buffer to DEFAULT_MTU bytes, pad TX */ - sw_w32((DEFAULT_MTU << 16) | RX_TRUNCATE_EN_83XX | TX_PAD_EN_838X, priv->r->dma_if_ctrl); - - /* Enable RX done, RX overflow and TX done interrupts */ - sw_w32(0xfffff, priv->r->dma_if_intr_msk); - - /* Enable DMA, engine expects empty FCS field */ - sw_w32_mask(0, RX_EN | TX_EN, priv->r->dma_if_ctrl); - - /* Restart TX/RX to CPU port */ - sw_w32_mask(0x0, 0x3, priv->r->mac_port_ctrl(priv->cpu_port)); - /* Set Speed, duplex, flow control - * FORCE_EN | LINK_EN | NWAY_EN | DUP_SEL - * | SPD_SEL = 0b10 | FORCE_FC_EN | PHY_MASTER_SLV_MANUAL_EN - * | MEDIA_SEL - */ - sw_w32(0x6192F, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4); - - /* Enable CRC checks on CPU-port */ - sw_w32_mask(0, BIT(3), priv->r->mac_port_ctrl(priv->cpu_port)); -} - -static void rtl839x_hw_en_rxtx(struct rtl838x_eth_priv *priv) -{ - /* Setup CPU-Port: RX Buffer */ - sw_w32((DEFAULT_MTU << 5) | RX_TRUNCATE_EN_83XX, priv->r->dma_if_ctrl); - - /* Enable Notify, RX done, RX overflow and TX done interrupts */ - sw_w32(0x007fffff, priv->r->dma_if_intr_msk); /* Notify IRQ! */ - - /* Enable DMA */ - sw_w32_mask(0, RX_EN | TX_EN, priv->r->dma_if_ctrl); - - /* Restart TX/RX to CPU port, enable CRC checking */ - sw_w32_mask(0x0, 0x3 | BIT(3), priv->r->mac_port_ctrl(priv->cpu_port)); - - /* CPU port joins Lookup Miss Flooding Portmask */ - /* TODO: The code below should also work for the RTL838x */ - sw_w32(0x28000, RTL839X_TBL_ACCESS_L2_CTRL); - sw_w32_mask(0, 0x80000000, RTL839X_TBL_ACCESS_L2_DATA(0)); - sw_w32(0x38000, RTL839X_TBL_ACCESS_L2_CTRL); - - /* Force CPU port link up */ - sw_w32_mask(0, 3, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4); -} - -static void rtl93xx_hw_en_rxtx(struct rtl838x_eth_priv *priv) -{ - /* Setup CPU-Port: RX Buffer truncated at DEFAULT_MTU Bytes */ - sw_w32((DEFAULT_MTU << 16) | RX_TRUNCATE_EN_93XX, priv->r->dma_if_ctrl); - - for (int i = 0; i < priv->rxrings; i++) { - int pos = (i % 3) * 10; - u32 v; - - sw_w32_mask(0x3ff << pos, priv->rxringlen << pos, priv->r->dma_if_rx_ring_size(i)); - - /* Some SoCs have issues with missing underflow protection */ - v = (sw_r32(priv->r->dma_if_rx_ring_cntr(i)) >> pos) & 0x3ff; - sw_w32_mask(0x3ff << pos, v, priv->r->dma_if_rx_ring_cntr(i)); - } - - /* Enable Notify, RX done, RX overflow and TX done interrupts */ - sw_w32(0xffffffff, priv->r->dma_if_intr_rx_runout_msk); - sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_msk); - sw_w32(0x0000000f, priv->r->dma_if_intr_tx_done_msk); - - /* Enable DMA */ - sw_w32_mask(0, RX_EN_93XX | TX_EN_93XX, priv->r->dma_if_ctrl); - - /* Restart TX/RX to CPU port, enable CRC checking */ - sw_w32_mask(0x0, 0x3 | BIT(4), priv->r->mac_port_ctrl(priv->cpu_port)); - - if (priv->family_id == RTL9300_FAMILY_ID) - sw_w32_mask(0, BIT(priv->cpu_port), RTL930X_L2_UNKN_UC_FLD_PMSK); - else - sw_w32_mask(0, BIT(priv->cpu_port), RTL931X_L2_UNKN_UC_FLD_PMSK); - - if (priv->family_id == RTL9300_FAMILY_ID) - sw_w32(0x217, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4); - else - sw_w32(0x2a1d, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4); -} - -static void rtl838x_setup_ring_buffer(struct rtl838x_eth_priv *priv, struct ring_b *ring) -{ - for (int i = 0; i < priv->rxrings; i++) { - struct p_hdr *h; - int j; - - for (j = 0; j < priv->rxringlen; j++) { - h = &ring->rx_header[i][j]; - memset(h, 0, sizeof(struct p_hdr)); - h->buf = (u8 *)KSEG1ADDR(ring->rx_space + - i * priv->rxringlen * RING_BUFFER + - j * RING_BUFFER); - h->size = RING_BUFFER; - /* All rings owned by switch, last one wraps */ - ring->rx_r[i][j] = KSEG1ADDR(h) | 1 | (j == (priv->rxringlen - 1) ? - WRAP : - 0); - } - ring->c_rx[i] = 0; - } - - for (int i = 0; i < TXRINGS; i++) { - struct p_hdr *h; - int j; - - for (j = 0; j < TXRINGLEN; j++) { - h = &ring->tx_header[i][j]; - memset(h, 0, sizeof(struct p_hdr)); - h->buf = (u8 *)KSEG1ADDR(ring->tx_space + - i * TXRINGLEN * RING_BUFFER + - j * RING_BUFFER); - h->size = RING_BUFFER; - ring->tx_r[i][j] = KSEG1ADDR(&ring->tx_header[i][j]); - } - /* Last header is wrapping around */ - ring->tx_r[i][j - 1] |= WRAP; - ring->c_tx[i] = 0; - } -} - -static void rtl839x_setup_notify_ring_buffer(struct rtl838x_eth_priv *priv) -{ - struct notify_b *b = priv->membase + sizeof(struct ring_b); - - for (int i = 0; i < NOTIFY_BLOCKS; i++) - b->ring[i] = KSEG1ADDR(&b->blocks[i]) | 1 | (i == (NOTIFY_BLOCKS - 1) ? WRAP : 0); - - sw_w32((u32) b->ring, RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL); - sw_w32_mask(0x3ff << 2, 100 << 2, RTL839X_L2_NOTIFICATION_CTRL); - - /* Setup notification events */ - sw_w32_mask(0, 1 << 14, RTL839X_L2_CTRL_0); /* RTL8390_L2_CTRL_0_FLUSH_NOTIFY_EN */ - sw_w32_mask(0, 1 << 12, RTL839X_L2_NOTIFICATION_CTRL); /* SUSPEND_NOTIFICATION_EN */ - - /* Enable Notification */ - sw_w32_mask(0, 1 << 0, RTL839X_L2_NOTIFICATION_CTRL); - priv->lastEvent = 0; -} - -static int rtl838x_eth_open(struct net_device *ndev) -{ - unsigned long flags; - struct rtl838x_eth_priv *priv = netdev_priv(ndev); - struct ring_b *ring = priv->membase; - - pr_debug("%s called: RX rings %d(length %d), TX rings %d(length %d)\n", - __func__, priv->rxrings, priv->rxringlen, TXRINGS, TXRINGLEN); - - spin_lock_irqsave(&priv->lock, flags); - rtl838x_hw_reset(priv); - rtl838x_setup_ring_buffer(priv, ring); - if (priv->family_id == RTL8390_FAMILY_ID) { - rtl839x_setup_notify_ring_buffer(priv); - /* Make sure the ring structure is visible to the ASIC */ - mb(); - flush_cache_all(); - } - - rtl838x_hw_ring_setup(priv); - phylink_start(priv->phylink); - - for (int i = 0; i < priv->rxrings; i++) - napi_enable(&priv->rx_qs[i].napi); - - switch (priv->family_id) { - case RTL8380_FAMILY_ID: - rtl838x_hw_en_rxtx(priv); - /* Trap IGMP/MLD traffic to CPU-Port */ - sw_w32(0x3, RTL838X_SPCL_TRAP_IGMP_CTRL); - /* Flush learned FDB entries on link down of a port */ - sw_w32_mask(0, BIT(7), RTL838X_L2_CTRL_0); - break; - - case RTL8390_FAMILY_ID: - rtl839x_hw_en_rxtx(priv); - /* Trap MLD and IGMP messages to CPU_PORT */ - sw_w32(0x3, RTL839X_SPCL_TRAP_IGMP_CTRL); - /* Flush learned FDB entries on link down of a port */ - sw_w32_mask(0, BIT(7), RTL839X_L2_CTRL_0); - break; - - case RTL9300_FAMILY_ID: - rtl93xx_hw_en_rxtx(priv); - /* Flush learned FDB entries on link down of a port */ - sw_w32_mask(0, BIT(7), RTL930X_L2_CTRL); - /* Trap MLD and IGMP messages to CPU_PORT */ - sw_w32((0x2 << 3) | 0x2, RTL930X_VLAN_APP_PKT_CTRL); - break; - - case RTL9310_FAMILY_ID: - rtl93xx_hw_en_rxtx(priv); - - /* Trap MLD and IGMP messages to CPU_PORT */ - sw_w32((0x2 << 3) | 0x2, RTL931X_VLAN_APP_PKT_CTRL); - - /* Disable External CPU access to switch, clear EXT_CPU_EN */ - sw_w32_mask(BIT(2), 0, RTL931X_MAC_L2_GLOBAL_CTRL2); - - /* Set PCIE_PWR_DOWN */ - sw_w32_mask(0, BIT(1), RTL931X_PS_SOC_CTRL); - break; - } - - netif_tx_start_all_queues(ndev); - - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static void rtl838x_hw_stop(struct rtl838x_eth_priv *priv) -{ - u32 force_mac = priv->family_id == RTL8380_FAMILY_ID ? 0x6192C : 0x75; - u32 clear_irq = priv->family_id == RTL8380_FAMILY_ID ? 0x000fffff : 0x007fffff; - - /* Disable RX/TX from/to CPU-port */ - sw_w32_mask(0x3, 0, priv->r->mac_port_ctrl(priv->cpu_port)); - - /* Disable traffic */ - if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) - sw_w32_mask(RX_EN_93XX | TX_EN_93XX, 0, priv->r->dma_if_ctrl); - else - sw_w32_mask(RX_EN | TX_EN, 0, priv->r->dma_if_ctrl); - mdelay(200); /* Test, whether this is needed */ - - /* Block all ports */ - if (priv->family_id == RTL8380_FAMILY_ID) { - sw_w32(0x03000000, RTL838X_TBL_ACCESS_DATA_0(0)); - sw_w32(0x00000000, RTL838X_TBL_ACCESS_DATA_0(1)); - sw_w32(1 << 15 | 2 << 12, RTL838X_TBL_ACCESS_CTRL_0); - } - - /* Flush L2 address cache */ - if (priv->family_id == RTL8380_FAMILY_ID) { - for (int i = 0; i <= priv->cpu_port; i++) { - sw_w32(1 << 26 | 1 << 23 | i << 5, priv->r->l2_tbl_flush_ctrl); - do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & (1 << 26)); - } - } else if (priv->family_id == RTL8390_FAMILY_ID) { - for (int i = 0; i <= priv->cpu_port; i++) { - sw_w32(1 << 28 | 1 << 25 | i << 5, priv->r->l2_tbl_flush_ctrl); - do { } while (sw_r32(priv->r->l2_tbl_flush_ctrl) & (1 << 28)); - } - } - /* TODO: L2 flush register is 64 bit on RTL931X and 930X */ - - /* CPU-Port: Link down */ - if (priv->family_id == RTL8380_FAMILY_ID || priv->family_id == RTL8390_FAMILY_ID) - sw_w32(force_mac, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4); - else if (priv->family_id == RTL9300_FAMILY_ID) - sw_w32_mask(0x3, 0, priv->r->mac_force_mode_ctrl + priv->cpu_port *4); - else if (priv->family_id == RTL9310_FAMILY_ID) - sw_w32_mask(BIT(0) | BIT(9), 0, priv->r->mac_force_mode_ctrl + priv->cpu_port *4); - mdelay(100); - - /* Disable all TX/RX interrupts */ - if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) { - sw_w32(0x00000000, priv->r->dma_if_intr_rx_runout_msk); - sw_w32(0xffffffff, priv->r->dma_if_intr_rx_runout_sts); - sw_w32(0x00000000, priv->r->dma_if_intr_rx_done_msk); - sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_sts); - sw_w32(0x00000000, priv->r->dma_if_intr_tx_done_msk); - sw_w32(0x0000000f, priv->r->dma_if_intr_tx_done_sts); - } else { - sw_w32(0x00000000, priv->r->dma_if_intr_msk); - sw_w32(clear_irq, priv->r->dma_if_intr_sts); - } - - /* Disable TX/RX DMA */ - sw_w32(0x00000000, priv->r->dma_if_ctrl); - mdelay(200); -} - -static int rtl838x_eth_stop(struct net_device *ndev) -{ - struct rtl838x_eth_priv *priv = netdev_priv(ndev); - - pr_info("in %s\n", __func__); - - phylink_stop(priv->phylink); - rtl838x_hw_stop(priv); - - for (int i = 0; i < priv->rxrings; i++) - napi_disable(&priv->rx_qs[i].napi); - - netif_tx_stop_all_queues(ndev); - - return 0; -} - -static void rtl838x_eth_set_multicast_list(struct net_device *ndev) -{ - /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F}) - * CTRL_0_FULL = GENMASK(21, 0) = 0x3FFFFF - */ - if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) { - sw_w32(0x0, RTL838X_RMA_CTRL_0); - sw_w32(0x0, RTL838X_RMA_CTRL_1); - } - if (ndev->flags & IFF_ALLMULTI) - sw_w32(GENMASK(21, 0), RTL838X_RMA_CTRL_0); - if (ndev->flags & IFF_PROMISC) { - sw_w32(GENMASK(21, 0), RTL838X_RMA_CTRL_0); - sw_w32(0x7fff, RTL838X_RMA_CTRL_1); - } -} - -static void rtl839x_eth_set_multicast_list(struct net_device *ndev) -{ - /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F}) - * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC - * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00 - * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0) - */ - if (!(ndev->flags & (IFF_PROMISC | IFF_ALLMULTI))) { - sw_w32(0x0, RTL839X_RMA_CTRL_0); - sw_w32(0x0, RTL839X_RMA_CTRL_1); - sw_w32(0x0, RTL839X_RMA_CTRL_2); - sw_w32(0x0, RTL839X_RMA_CTRL_3); - } - if (ndev->flags & IFF_ALLMULTI) { - sw_w32(GENMASK(31, 2), RTL839X_RMA_CTRL_0); - sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_1); - sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_2); - } - if (ndev->flags & IFF_PROMISC) { - sw_w32(GENMASK(31, 2), RTL839X_RMA_CTRL_0); - sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_1); - sw_w32(GENMASK(31, 0), RTL839X_RMA_CTRL_2); - sw_w32(0x3ff, RTL839X_RMA_CTRL_3); - } -} - -static void rtl930x_eth_set_multicast_list(struct net_device *ndev) -{ - /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F}) - * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC - * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00 - * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0) - */ - if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)) { - sw_w32(GENMASK(31, 2), RTL930X_RMA_CTRL_0); - sw_w32(GENMASK(31, 0), RTL930X_RMA_CTRL_1); - sw_w32(GENMASK(31, 0), RTL930X_RMA_CTRL_2); - } else { - sw_w32(0x0, RTL930X_RMA_CTRL_0); - sw_w32(0x0, RTL930X_RMA_CTRL_1); - sw_w32(0x0, RTL930X_RMA_CTRL_2); - } -} - -static void rtl931x_eth_set_multicast_list(struct net_device *ndev) -{ - /* Flood all classes of RMA addresses (01-80-C2-00-00-{01..2F}) - * CTRL_0_FULL = GENMASK(31, 2) = 0xFFFFFFFC - * Lower two bits are reserved, corresponding to RMA 01-80-C2-00-00-00. - * CTRL_1_FULL = CTRL_2_FULL = GENMASK(31, 0) - */ - if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)) { - sw_w32(GENMASK(31, 2), RTL931X_RMA_CTRL_0); - sw_w32(GENMASK(31, 0), RTL931X_RMA_CTRL_1); - sw_w32(GENMASK(31, 0), RTL931X_RMA_CTRL_2); - } else { - sw_w32(0x0, RTL931X_RMA_CTRL_0); - sw_w32(0x0, RTL931X_RMA_CTRL_1); - sw_w32(0x0, RTL931X_RMA_CTRL_2); - } -} - -static void rtl838x_eth_tx_timeout(struct net_device *ndev, unsigned int txqueue) -{ - unsigned long flags; - struct rtl838x_eth_priv *priv = netdev_priv(ndev); - - pr_warn("%s\n", __func__); - spin_lock_irqsave(&priv->lock, flags); - rtl838x_hw_stop(priv); - rtl838x_hw_ring_setup(priv); - rtl838x_hw_en_rxtx(priv); - netif_trans_update(ndev); - netif_start_queue(ndev); - spin_unlock_irqrestore(&priv->lock, flags); -} - -static int rtl838x_eth_tx(struct sk_buff *skb, struct net_device *dev) -{ - int len; - struct rtl838x_eth_priv *priv = netdev_priv(dev); - struct ring_b *ring = priv->membase; - int ret; - unsigned long flags; - struct p_hdr *h; - int dest_port = -1; - int q = skb_get_queue_mapping(skb) % TXRINGS; - - if (q) /* Check for high prio queue */ - pr_debug("SKB priority: %d\n", skb->priority); - - spin_lock_irqsave(&priv->lock, flags); - len = skb->len; - - /* Check for DSA tagging at the end of the buffer */ - if (netdev_uses_dsa(dev) && - skb->data[len - 4] == 0x80 && - skb->data[len - 3] < priv->cpu_port && - skb->data[len - 2] == 0x10 && - skb->data[len - 1] == 0x00) { - /* Reuse tag space for CRC if possible */ - dest_port = skb->data[len - 3]; - skb->data[len - 4] = skb->data[len - 3] = skb->data[len - 2] = skb->data[len - 1] = 0x00; - len -= 4; - } - - len += 4; /* Add space for CRC */ - - if (skb_padto(skb, len)) { - ret = NETDEV_TX_OK; - goto txdone; - } - - /* We can send this packet if CPU owns the descriptor */ - if (!(ring->tx_r[q][ring->c_tx[q]] & 0x1)) { - - /* Set descriptor for tx */ - h = &ring->tx_header[q][ring->c_tx[q]]; - h->size = len; - h->len = len; - /* On RTL8380 SoCs, small packet lengths being sent need adjustments */ - if (priv->family_id == RTL8380_FAMILY_ID) { - if (len < ETH_ZLEN - 4) - h->len -= 4; - } - - if (dest_port >= 0) - priv->r->create_tx_header(h, dest_port, skb->priority >> 1); - - /* Copy packet data to tx buffer */ - memcpy((void *)KSEG1ADDR(h->buf), skb->data, len); - /* Make sure packet data is visible to ASIC */ - wmb(); - - /* Hand over to switch */ - ring->tx_r[q][ring->c_tx[q]] |= 1; - - /* Before starting TX, prevent a Lextra bus bug on RTL8380 SoCs */ - if (priv->family_id == RTL8380_FAMILY_ID) { - for (int i = 0; i < 10; i++) { - u32 val = sw_r32(priv->r->dma_if_ctrl); - if ((val & 0xc) == 0xc) - break; - } - } - - /* Tell switch to send data */ - if (priv->family_id == RTL9310_FAMILY_ID || priv->family_id == RTL9300_FAMILY_ID) { - /* Ring ID q == 0: Low priority, Ring ID = 1: High prio queue */ - if (!q) - sw_w32_mask(0, BIT(2), priv->r->dma_if_ctrl); - else - sw_w32_mask(0, BIT(3), priv->r->dma_if_ctrl); - } else { - sw_w32_mask(0, TX_DO, priv->r->dma_if_ctrl); - } - - dev->stats.tx_packets++; - dev->stats.tx_bytes += len; - dev_kfree_skb(skb); - ring->c_tx[q] = (ring->c_tx[q] + 1) % TXRINGLEN; - ret = NETDEV_TX_OK; - } else { - dev_warn(&priv->pdev->dev, "Data is owned by switch\n"); - ret = NETDEV_TX_BUSY; - } - -txdone: - spin_unlock_irqrestore(&priv->lock, flags); - - return ret; -} - -/* Return queue number for TX. On the RTL83XX, these queues have equal priority - * so we do round-robin - */ -u16 rtl83xx_pick_tx_queue(struct net_device *dev, struct sk_buff *skb, - struct net_device *sb_dev) -{ - static u8 last = 0; - - last++; - return last % TXRINGS; -} - -/* Return queue number for TX. On the RTL93XX, queue 1 is the high priority queue - */ -u16 rtl93xx_pick_tx_queue(struct net_device *dev, struct sk_buff *skb, - struct net_device *sb_dev) -{ - if (skb->priority >= TC_PRIO_CONTROL) - return 1; - - return 0; -} - -static int rtl838x_hw_receive(struct net_device *dev, int r, int budget) -{ - struct rtl838x_eth_priv *priv = netdev_priv(dev); - struct ring_b *ring = priv->membase; - LIST_HEAD(rx_list); - unsigned long flags; - int work_done = 0; - u32 *last; - bool dsa = netdev_uses_dsa(dev); - - pr_debug("---------------------------------------------------------- RX - %d\n", r); - spin_lock_irqsave(&priv->lock, flags); - last = (u32 *)KSEG1ADDR(sw_r32(priv->r->dma_if_rx_cur + r * 4)); - - do { - struct sk_buff *skb; - struct dsa_tag tag; - struct p_hdr *h; - u8 *skb_data; - u8 *data; - int len; - - if ((ring->rx_r[r][ring->c_rx[r]] & 0x1)) { - if (&ring->rx_r[r][ring->c_rx[r]] != last) { - netdev_warn(dev, "Ring contention: r: %x, last %x, cur %x\n", - r, (uint32_t)last, (u32) &ring->rx_r[r][ring->c_rx[r]]); - } - break; - } - - h = &ring->rx_header[r][ring->c_rx[r]]; - data = (u8 *)KSEG1ADDR(h->buf); - len = h->len; - if (!len) - break; - work_done++; - - len -= 4; /* strip the CRC */ - /* Add 4 bytes for cpu_tag */ - if (dsa) - len += 4; - - skb = netdev_alloc_skb(dev, len + 4); - skb_reserve(skb, NET_IP_ALIGN); - - if (likely(skb)) { - /* BUG: Prevent bug on RTL838x SoCs */ - if (priv->family_id == RTL8380_FAMILY_ID) { - sw_w32(0xffffffff, priv->r->dma_if_rx_ring_size(0)); - for (int i = 0; i < priv->rxrings; i++) { - unsigned int val; - - /* Update each ring cnt */ - val = sw_r32(priv->r->dma_if_rx_ring_cntr(i)); - sw_w32(val, priv->r->dma_if_rx_ring_cntr(i)); - } - } - - skb_data = skb_put(skb, len); - /* Make sure data is visible */ - mb(); - memcpy(skb->data, (u8 *)KSEG1ADDR(data), len); - /* Overwrite CRC with cpu_tag */ - if (dsa) { - priv->r->decode_tag(h, &tag); - skb->data[len - 4] = 0x80; - skb->data[len - 3] = tag.port; - skb->data[len - 2] = 0x10; - skb->data[len - 1] = 0x00; - if (tag.l2_offloaded) - skb->data[len - 3] |= 0x40; - } - - if (tag.queue >= 0) - pr_debug("Queue: %d, len: %d, reason %d port %d\n", - tag.queue, len, tag.reason, tag.port); - - skb->protocol = eth_type_trans(skb, dev); - if (dev->features & NETIF_F_RXCSUM) { - if (tag.crc_error) - skb_checksum_none_assert(skb); - else - skb->ip_summed = CHECKSUM_UNNECESSARY; - } - dev->stats.rx_packets++; - dev->stats.rx_bytes += len; - - list_add_tail(&skb->list, &rx_list); - } else { - if (net_ratelimit()) - dev_warn(&dev->dev, "low on memory - packet dropped\n"); - dev->stats.rx_dropped++; - } - - /* Reset header structure */ - memset(h, 0, sizeof(struct p_hdr)); - h->buf = data; - h->size = RING_BUFFER; - - ring->rx_r[r][ring->c_rx[r]] = KSEG1ADDR(h) | 0x1 | (ring->c_rx[r] == (priv->rxringlen - 1) ? - WRAP : - 0x1); - ring->c_rx[r] = (ring->c_rx[r] + 1) % priv->rxringlen; - last = (u32 *)KSEG1ADDR(sw_r32(priv->r->dma_if_rx_cur + r * 4)); - } while (&ring->rx_r[r][ring->c_rx[r]] != last && work_done < budget); - - netif_receive_skb_list(&rx_list); - - /* Update counters */ - priv->r->update_cntr(r, 0); - - spin_unlock_irqrestore(&priv->lock, flags); - - return work_done; -} - -static int rtl838x_poll_rx(struct napi_struct *napi, int budget) -{ - struct rtl838x_rx_q *rx_q = container_of(napi, struct rtl838x_rx_q, napi); - struct rtl838x_eth_priv *priv = rx_q->priv; - int work_done = 0; - int r = rx_q->id; - int work; - - while (work_done < budget) { - work = rtl838x_hw_receive(priv->netdev, r, budget - work_done); - if (!work) - break; - work_done += work; - } - - if (work_done < budget) { - napi_complete_done(napi, work_done); - - /* Enable RX interrupt */ - if (priv->family_id == RTL9300_FAMILY_ID || priv->family_id == RTL9310_FAMILY_ID) - sw_w32(0xffffffff, priv->r->dma_if_intr_rx_done_msk); - else - sw_w32_mask(0, 0xf00ff | BIT(r + 8), priv->r->dma_if_intr_msk); - } - - return work_done; -} - - -static void rtl838x_validate(struct phylink_config *config, - unsigned long *supported, - struct phylink_link_state *state) -{ - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - - pr_debug("In %s\n", __func__); - - if (!phy_interface_mode_is_rgmii(state->interface) && - state->interface != PHY_INTERFACE_MODE_1000BASEX && - state->interface != PHY_INTERFACE_MODE_MII && - state->interface != PHY_INTERFACE_MODE_REVMII && - state->interface != PHY_INTERFACE_MODE_GMII && - state->interface != PHY_INTERFACE_MODE_QSGMII && - state->interface != PHY_INTERFACE_MODE_INTERNAL && - state->interface != PHY_INTERFACE_MODE_SGMII) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); - pr_err("Unsupported interface: %d\n", state->interface); - return; - } - - /* Allow all the expected bits */ - phylink_set(mask, Autoneg); - phylink_set_port_modes(mask); - phylink_set(mask, Pause); - phylink_set(mask, Asym_Pause); - - /* With the exclusion of MII and Reverse MII, we support Gigabit, - * including Half duplex - */ - if (state->interface != PHY_INTERFACE_MODE_MII && - state->interface != PHY_INTERFACE_MODE_REVMII) { - phylink_set(mask, 1000baseT_Full); - phylink_set(mask, 1000baseT_Half); - } - - phylink_set(mask, 10baseT_Half); - phylink_set(mask, 10baseT_Full); - phylink_set(mask, 100baseT_Half); - phylink_set(mask, 100baseT_Full); - - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); -} - - -static void rtl838x_mac_config(struct phylink_config *config, - unsigned int mode, - const struct phylink_link_state *state) -{ - /* This is only being called for the master device, - * i.e. the CPU-Port. We don't need to do anything. - */ - - pr_info("In %s, mode %x\n", __func__, mode); -} - -static void rtl838x_mac_an_restart(struct phylink_config *config) -{ - struct net_device *dev = container_of(config->dev, struct net_device, dev); - struct rtl838x_eth_priv *priv = netdev_priv(dev); - - /* This works only on RTL838x chips */ - if (priv->family_id != RTL8380_FAMILY_ID) - return; - - pr_debug("In %s\n", __func__); - /* Restart by disabling and re-enabling link */ - sw_w32(0x6192D, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4); - mdelay(20); - sw_w32(0x6192F, priv->r->mac_force_mode_ctrl + priv->cpu_port * 4); -} - -static void rtl838x_mac_pcs_get_state(struct phylink_config *config, - struct phylink_link_state *state) -{ - u32 speed; - struct net_device *dev = container_of(config->dev, struct net_device, dev); - struct rtl838x_eth_priv *priv = netdev_priv(dev); - int port = priv->cpu_port; - - pr_info("In %s\n", __func__); - - state->link = priv->r->get_mac_link_sts(port) ? 1 : 0; - state->duplex = priv->r->get_mac_link_dup_sts(port) ? 1 : 0; - - pr_info("%s link status is %d\n", __func__, state->link); - speed = priv->r->get_mac_link_spd_sts(port); - switch (speed) { - case 0: - state->speed = SPEED_10; - break; - case 1: - state->speed = SPEED_100; - break; - case 2: - state->speed = SPEED_1000; - break; - case 5: - state->speed = SPEED_2500; - break; - case 6: - state->speed = SPEED_5000; - break; - case 4: - state->speed = SPEED_10000; - break; - default: - state->speed = SPEED_UNKNOWN; - break; - } - - state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX); - if (priv->r->get_mac_rx_pause_sts(port)) - state->pause |= MLO_PAUSE_RX; - if (priv->r->get_mac_tx_pause_sts(port)) - state->pause |= MLO_PAUSE_TX; -} - -static void rtl838x_mac_link_down(struct phylink_config *config, - unsigned int mode, - phy_interface_t interface) -{ - struct net_device *dev = container_of(config->dev, struct net_device, dev); - struct rtl838x_eth_priv *priv = netdev_priv(dev); - - pr_debug("In %s\n", __func__); - /* Stop TX/RX to port */ - sw_w32_mask(0x03, 0, priv->r->mac_port_ctrl(priv->cpu_port)); -} - -static void rtl838x_mac_link_up(struct phylink_config *config, - struct phy_device *phy, unsigned int mode, - phy_interface_t interface, int speed, int duplex, - bool tx_pause, bool rx_pause) -{ - struct net_device *dev = container_of(config->dev, struct net_device, dev); - struct rtl838x_eth_priv *priv = netdev_priv(dev); - - pr_debug("In %s\n", __func__); - /* Restart TX/RX to port */ - sw_w32_mask(0, 0x03, priv->r->mac_port_ctrl(priv->cpu_port)); -} - -static void rtl838x_set_mac_hw(struct net_device *dev, u8 *mac) -{ - struct rtl838x_eth_priv *priv = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - pr_debug("In %s\n", __func__); - sw_w32((mac[0] << 8) | mac[1], priv->r->mac); - sw_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], priv->r->mac + 4); - - if (priv->family_id == RTL8380_FAMILY_ID) { - /* 2 more registers, ALE/MAC block */ - sw_w32((mac[0] << 8) | mac[1], RTL838X_MAC_ALE); - sw_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], - (RTL838X_MAC_ALE + 4)); - - sw_w32((mac[0] << 8) | mac[1], RTL838X_MAC2); - sw_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5], - RTL838X_MAC2 + 4); - } - spin_unlock_irqrestore(&priv->lock, flags); -} - -static int rtl838x_set_mac_address(struct net_device *dev, void *p) -{ - struct rtl838x_eth_priv *priv = netdev_priv(dev); - const struct sockaddr *addr = p; - u8 *mac = (u8 *) (addr->sa_data); - - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - dev_addr_set(dev, addr->sa_data); - rtl838x_set_mac_hw(dev, mac); - - pr_info("Using MAC %08x%08x\n", sw_r32(priv->r->mac), sw_r32(priv->r->mac + 4)); - - return 0; -} - -static int rtl8390_init_mac(struct rtl838x_eth_priv *priv) -{ - /* We will need to set-up EEE and the egress-rate limitation */ - return 0; -} - -static int rtl8380_init_mac(struct rtl838x_eth_priv *priv) -{ - if (priv->family_id == 0x8390) - return rtl8390_init_mac(priv); - - /* At present we do not know how to set up EEE on any other SoC than RTL8380 */ - if (priv->family_id != 0x8380) - return 0; - - pr_info("%s\n", __func__); - /* fix timer for EEE */ - sw_w32(0x5001411, RTL838X_EEE_TX_TIMER_GIGA_CTRL); - sw_w32(0x5001417, RTL838X_EEE_TX_TIMER_GELITE_CTRL); - - /* Init VLAN. TODO: Understand what is being done, here */ - if (priv->id == 0x8382) { - for (int i = 0; i <= 28; i++) - sw_w32(0, 0xd57c + i * 0x80); - } - if (priv->id == 0x8380) { - for (int i = 8; i <= 28; i++) - sw_w32(0, 0xd57c + i * 0x80); - } - - return 0; -} - -static int rtl838x_get_link_ksettings(struct net_device *ndev, - struct ethtool_link_ksettings *cmd) -{ - struct rtl838x_eth_priv *priv = netdev_priv(ndev); - - pr_debug("%s called\n", __func__); - - return phylink_ethtool_ksettings_get(priv->phylink, cmd); -} - -static int rtl838x_set_link_ksettings(struct net_device *ndev, - const struct ethtool_link_ksettings *cmd) -{ - struct rtl838x_eth_priv *priv = netdev_priv(ndev); - - pr_debug("%s called\n", __func__); - - return phylink_ethtool_ksettings_set(priv->phylink, cmd); -} - -/* - * On all Realtek switch platforms the hardware periodically reads the link status of all - * PHYs. This is to some degree programmable, so that one can tell the hardware to read - * specific C22 registers from specific pages, or C45 registers, to determine the current - * link speed, duplex, flow-control, ... - * - * This happens without any need for the driver to do anything at runtime, completely - * invisible and in a parallel hardware thread, independent of the CPU running Linux. - * All one needs to do is to set it up once. Having the MAC link settings automatically - * follow the PHY link status also happens to be the only way to control MAC port status - * in a meaningful way, or at least it's the only way we fully understand, as this is - * what every vendor firmware is doing. - * - * The hardware PHY polling unit doesn't care about bus locking, it just assumes that all - * paged PHY operations are also done via the same hardware unit offering this PHY access - * abstractions. - * - * Additionally at least the RTL838x and RTL839x devices are known to have a so called - * raw mode. Using the special MAX_PAGE-1 with the MDIO controller found in Realtek - * SoCs allows to access the PHY in raw mode, ie. bypassing the cache and paging engine - * of the MDIO controller. E.g. for RTL838x this is 0xfff. - * - * On the other hand Realtek PHYs usually make use of select register 0x1f to switch - * pages. There is no problem to issue separate page and access bus calls to the PHYs - * when they are not attached to an Realtek SoC. The paradigm should be to keep the PHY - * implementation bus independent. - * - * As if this is not enough the PHY packages consist of 4 or 8 ports that all can be - * programmed individually. Some registers are only available on port 0 and configure - * the whole package. - * - * To bring all this together we need a tricky bus design that intercepts select page - * calls but lets raw page accesses through. And especially knows how to handle raw - * accesses to the select register. Additionally we need the possibility to write to - * all 8 ports of the PHY individually. - * - * While the C45 clause stuff is pretty standard the legacy functions basically track - * the accesses and the state of the bus with the attributes page[], raw[] and portaddr - * of the bus_priv structure. The page selection works as follows: - * - * phy_write(phydev, RTMDIO_PAGE_SELECT, 12) : store internal page 12 in driver - * phy_write(phydev, 7, 33) : write page=12, reg=7, val=33 - * - * or simply - * - * phy_write_paged(phydev, 12, 7, 33) : write page=12, reg=7, val=33 - * - * The port selection works as follows and must be called under a held mdio bus lock - * - * __mdiobus_write(bus, RTMDIO_PORT_SELECT, 4) : switch to port 4 - * __phy_write(phydev, RTMDIO_PAGE_SELECT, 11) : store internal page 11 in driver - * __phy_write(phydev, 8, 19) : write page=11, reg=8, val=19, port=4 - * - * Any Realtek PHY that will be connected to this bus must simply provide the standard - * page functions: - * - * define RTL821X_PAGE_SELECT 0x1f - * - * static int rtl821x_read_page(struct phy_device *phydev) - * { - * return __phy_read(phydev, RTL821X_PAGE_SELECT); - * } - * - * static int rtl821x_write_page(struct phy_device *phydev, int page) - * { - * return __phy_write(phydev, RTL821X_PAGE_SELECT, page); - * } - * - * In case there are non Realtek PHYs attached to the bus the logic might need to be - * reimplemented. For now it should be sufficient. - */ - -#define RTMDIO_PAGE_SELECT 0x1f -#define RTMDIO_PORT_SELECT 0x2000 -#define RTMDIO_READ 0x1 -#define RTMDIO_WRITE 0x2 -#define RTMDIO_ABS 0x4 -#define RTMDIO_PKG 0x8 - -/* - * Provide a generic read/write function so we can access arbitrary ports on the bus. - * E.g. other ports of a PHY package on the bus. This basically resembles the kernel - * phy_read_paged() and phy_write_paged() functions. To inform the bus that we are - * working on a not default port send a RTMDIO_PORT_SELECT command at the beginning - * and the end to switch the port handling logic. - */ - -static int rtmdio_access(struct phy_device *phydev, int op, int port, - int page, u32 regnum, u16 val) -{ - int r, ret = 0, oldpage; - - if (op & RTMDIO_PKG) { - if (!phydev->shared) - return -EIO; - port = phydev->shared->addr + port; - } - - /* lock and inform bus about non default addressing */ - phy_lock_mdio_bus(phydev); - __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, - RTMDIO_PORT_SELECT, port); - - oldpage = ret = __phy_read(phydev, RTMDIO_PAGE_SELECT); - if (oldpage >= 0 && oldpage != page) { - ret = __phy_write(phydev, RTMDIO_PAGE_SELECT, page); - if (ret < 0) - oldpage = ret; - } - - if (oldpage >= 0) { - if (op & RTMDIO_WRITE) - ret = __phy_write(phydev, regnum, val); - else - ret = __phy_read(phydev, regnum); - } - - if (oldpage >= 0) { - r = __phy_write(phydev, RTMDIO_PAGE_SELECT, oldpage); - if (ret >= 0 && r < 0) - ret = r; - } else - ret = oldpage; - - /* reset bus to default adressing and unlock it */ - __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr, - RTMDIO_PORT_SELECT, -1); - phy_unlock_mdio_bus(phydev); - - return ret; -} - -/* - * To make use of the shared package functions provide wrappers that align with kernel - * naming conventions. The package() functions are useful to change settings on the - * package as a whole. The package_port() functions will allow to target the PHYs - * of a package individually. The port() only functions allow to access arbitrary ports - * on the bus through a PHY. - */ - -int phy_package_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val) -{ - return rtmdio_access(phydev, RTMDIO_WRITE | RTMDIO_PKG, port, page, regnum, val); -} - -int phy_package_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val) -{ - return rtmdio_access(phydev, RTMDIO_WRITE | RTMDIO_PKG, 0, page, regnum, val); -} - -int phy_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val) -{ - return rtmdio_access(phydev, RTMDIO_WRITE | RTMDIO_ABS, port, page, regnum, val); -} - -int phy_package_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum) -{ - return rtmdio_access(phydev, RTMDIO_READ | RTMDIO_PKG, port, page, regnum, 0); -} - -int phy_package_read_paged(struct phy_device *phydev, int page, u32 regnum) -{ - return rtmdio_access(phydev, RTMDIO_READ | RTMDIO_PKG, 0, page, regnum, 0); -} - -int phy_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum) -{ - return rtmdio_access(phydev, RTMDIO_READ | RTMDIO_ABS, port, page, regnum, 0); -} - -/* These are the core functions of our new Realtek SoC MDIO bus. */ - -static int rtmdio_read_c45(struct mii_bus *bus, int addr, int devnum, int regnum) -{ - int err, val; - struct rtl838x_bus_priv *bus_priv = bus->priv; - - if (bus_priv->extaddr >= 0) - addr = bus_priv->extaddr; - - err = (*bus_priv->read_mmd_phy)(addr, devnum, regnum, &val); - pr_debug("rd_MMD(adr=%d, dev=%d, reg=%d) = %d, err = %d\n", - addr, devnum, regnum, val, err); - return err ? err : val; -} - -static int rtmdio_83xx_read(struct mii_bus *bus, int addr, int regnum) -{ - int err, val; - struct rtl838x_bus_priv *bus_priv = bus->priv; - struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv; - - if (bus_priv->extaddr >= 0) - addr = bus_priv->extaddr; - - if (addr >= 24 && addr <= 27 && eth_priv->id == 0x8380) - return rtl838x_read_sds_phy(addr, regnum); - - if (eth_priv->family_id == RTL8390_FAMILY_ID && eth_priv->phy_is_internal[addr]) - return rtl839x_read_sds_phy(addr, regnum); - - if (regnum == RTMDIO_PAGE_SELECT && bus_priv->page[addr] != bus_priv->rawpage) - return bus_priv->page[addr]; - - bus_priv->raw[addr] = (bus_priv->page[addr] == bus_priv->rawpage); - err = (*bus_priv->read_phy)(addr, bus_priv->page[addr], regnum, &val); - pr_debug("rd_PHY(adr=%d, pag=%d, reg=%d) = %d, err = %d\n", - addr, bus_priv->page[addr], regnum, val, err); - return err ? err : val; -} - -static int rtmdio_93xx_read(struct mii_bus *bus, int addr, int regnum) -{ - int err, val; - struct rtl838x_bus_priv *bus_priv = bus->priv; - struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv; - - if (bus_priv->extaddr >= 0) - addr = bus_priv->extaddr; - - if (regnum == RTMDIO_PAGE_SELECT && bus_priv->page[addr] != bus_priv->rawpage) - return bus_priv->page[addr]; - - bus_priv->raw[addr] = (bus_priv->page[addr] == bus_priv->rawpage); - if (eth_priv->phy_is_internal[addr]) { - if (eth_priv->family_id == RTL9300_FAMILY_ID) - return rtl930x_read_sds_phy(eth_priv->sds_id[addr], - bus_priv->page[addr], regnum); - else - return rtl931x_read_sds_phy(eth_priv->sds_id[addr], - bus_priv->page[addr], regnum); - } - - err = (*bus_priv->read_phy)(addr, bus_priv->page[addr], regnum, &val); - pr_debug("rd_PHY(adr=%d, pag=%d, reg=%d) = %d, err = %d\n", - addr, bus_priv->page[addr], regnum, val, err); - return err ? err : val; -} - -static int rtmdio_write_c45(struct mii_bus *bus, int addr, int devnum, int regnum, u16 val) -{ - int err; - struct rtl838x_bus_priv *bus_priv = bus->priv; - - if (bus_priv->extaddr >= 0) - addr = bus_priv->extaddr; - - err = (*bus_priv->write_mmd_phy)(addr, devnum, regnum, val); - pr_debug("wr_MMD(adr=%d, dev=%d, reg=%d, val=%d) err = %d\n", - addr, devnum, regnum, val, err); - return err; -} - -static int rtmdio_83xx_write(struct mii_bus *bus, int addr, int regnum, u16 val) -{ - int err, page, offset = 0; - struct rtl838x_bus_priv *bus_priv = bus->priv; - struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv; - - if (regnum == RTMDIO_PORT_SELECT) { - bus_priv->extaddr = (s16)val; - return 0; - } - - if (bus_priv->extaddr >= 0) - addr = bus_priv->extaddr; - page = bus_priv->page[addr]; - - if (addr >= 24 && addr <= 27 && eth_priv->id == 0x8380) { - if (addr == 26) - offset = 0x100; - sw_w32(val, RTL838X_SDS4_FIB_REG0 + offset + (regnum << 2)); - return 0; - } - - if (eth_priv->family_id == RTL8390_FAMILY_ID && eth_priv->phy_is_internal[addr]) - return rtl839x_write_sds_phy(addr, regnum, val); - - if (regnum == RTMDIO_PAGE_SELECT) - bus_priv->page[addr] = val; - - if (!bus_priv->raw[addr] && (regnum != RTMDIO_PAGE_SELECT || page == bus_priv->rawpage)) { - bus_priv->raw[addr] = (page == bus_priv->rawpage); - err = (*bus_priv->write_phy)(addr, page, regnum, val); - pr_debug("wr_PHY(adr=%d, pag=%d, reg=%d, val=%d) err = %d\n", - addr, page, regnum, val, err); - return err; - } - - bus_priv->raw[addr] = false; - return 0; -} - -static int rtmdio_93xx_write(struct mii_bus *bus, int addr, int regnum, u16 val) -{ - int err, page; - struct rtl838x_bus_priv *bus_priv = bus->priv; - struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv; - - if (regnum == RTMDIO_PORT_SELECT) { - bus_priv->extaddr = (s16)val; - return 0; - } - - if (bus_priv->extaddr >= 0) - addr = bus_priv->extaddr; - page = bus_priv->page[addr]; - - if (regnum == RTMDIO_PAGE_SELECT) - bus_priv->page[addr] = val; - - if (!bus_priv->raw[addr] && (regnum != RTMDIO_PAGE_SELECT || page == bus_priv->rawpage)) { - bus_priv->raw[addr] = (page == bus_priv->rawpage); - if (eth_priv->phy_is_internal[addr]) { - if (eth_priv->family_id == RTL9300_FAMILY_ID) - return rtl930x_write_sds_phy(eth_priv->sds_id[addr], - page, regnum, val); - else - return rtl931x_write_sds_phy(eth_priv->sds_id[addr], - page, regnum, val); - } - - err = (*bus_priv->write_phy)(addr, page, regnum, val); - pr_debug("wr_PHY(adr=%d, pag=%d, reg=%d, val=%d) err = %d\n", - addr, page, regnum, val, err); - } - - bus_priv->raw[addr] = false; - return 0; -} - -/* These wrappers can be dropped after switch to kernel 6.6 */ - -static int rtmdio_83xx_read_legacy(struct mii_bus *bus, int addr, int regnum) -{ - if (regnum & MII_ADDR_C45) - return rtmdio_read_c45(bus, addr, mdiobus_c45_devad(regnum), - mdiobus_c45_regad(regnum)); - else - return rtmdio_83xx_read(bus, addr, regnum); -} - -static int rtmdio_93xx_read_legacy(struct mii_bus *bus, int addr, int regnum) -{ - if (regnum & MII_ADDR_C45) - return rtmdio_read_c45(bus, addr, mdiobus_c45_devad(regnum), - mdiobus_c45_regad(regnum)); - else - return rtmdio_93xx_read(bus, addr, regnum); -} - -static int rtmdio_83xx_write_legacy(struct mii_bus *bus, int addr, int regnum, u16 val) -{ - if (regnum & MII_ADDR_C45) - return rtmdio_write_c45(bus, addr, mdiobus_c45_devad(regnum), - mdiobus_c45_regad(regnum), val); - else - return rtmdio_83xx_write(bus, addr, regnum, val); -} - -static int rtmdio_93xx_write_legacy(struct mii_bus *bus, int addr, int regnum, u16 val) -{ - if (regnum & MII_ADDR_C45) - return rtmdio_write_c45(bus, addr, mdiobus_c45_devad(regnum), - mdiobus_c45_regad(regnum), val); - else - return rtmdio_93xx_write(bus, addr, regnum, val); -} - -static int rtmdio_838x_reset(struct mii_bus *bus) -{ - pr_debug("%s called\n", __func__); - /* Disable MAC polling the PHY so that we can start configuration */ - sw_w32(0x00000000, RTL838X_SMI_POLL_CTRL); - - /* Enable PHY control via SoC */ - sw_w32_mask(0, 1 << 15, RTL838X_SMI_GLB_CTRL); - - /* Probably should reset all PHYs here... */ - return 0; -} - -static int rtmdio_839x_reset(struct mii_bus *bus) -{ - return 0; - - pr_debug("%s called\n", __func__); - /* BUG: The following does not work, but should! */ - /* Disable MAC polling the PHY so that we can start configuration */ - sw_w32(0x00000000, RTL839X_SMI_PORT_POLLING_CTRL); - sw_w32(0x00000000, RTL839X_SMI_PORT_POLLING_CTRL + 4); - /* Disable PHY polling via SoC */ - sw_w32_mask(1 << 7, 0, RTL839X_SMI_GLB_CTRL); - - /* Probably should reset all PHYs here... */ - return 0; -} - -u8 mac_type_bit[RTL930X_CPU_PORT] = {0, 0, 0, 0, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6, 6, - 8, 8, 8, 8, 10, 10, 10, 10, 12, 15, 18, 21}; - -static int rtmdio_930x_reset(struct mii_bus *bus) -{ - struct rtl838x_bus_priv *bus_priv = bus->priv; - struct rtl838x_eth_priv *priv = bus_priv->eth_priv; - u32 c45_mask = 0; - u32 poll_sel[2]; - u32 poll_ctrl = 0; - u32 private_poll_mask = 0; - u32 v; - bool uses_usxgmii = false; /* For the Aquantia PHYs */ - bool uses_hisgmii = false; /* For the RTL8221/8226 */ - - /* Mapping of port to phy-addresses on an SMI bus */ - poll_sel[0] = poll_sel[1] = 0; - for (int i = 0; i < RTL930X_CPU_PORT; i++) { - int pos; - - if (priv->smi_bus[i] > 3) - continue; - pos = (i % 6) * 5; - sw_w32_mask(0x1f << pos, priv->smi_addr[i] << pos, - RTL930X_SMI_PORT0_5_ADDR + (i / 6) * 4); - - pos = (i * 2) % 32; - poll_sel[i / 16] |= priv->smi_bus[i] << pos; - poll_ctrl |= BIT(20 + priv->smi_bus[i]); - } - - /* Configure which SMI bus is behind which port number */ - sw_w32(poll_sel[0], RTL930X_SMI_PORT0_15_POLLING_SEL); - sw_w32(poll_sel[1], RTL930X_SMI_PORT16_27_POLLING_SEL); - - /* Disable POLL_SEL for any SMI bus with a normal PHY (not RTL8295R for SFP+) */ - sw_w32_mask(poll_ctrl, 0, RTL930X_SMI_GLB_CTRL); - - /* Configure which SMI busses are polled in c45 based on a c45 PHY being on that bus */ - for (int i = 0; i < 4; i++) - if (priv->smi_bus_isc45[i]) - c45_mask |= BIT(i + 16); - - pr_info("c45_mask: %08x\n", c45_mask); - sw_w32_mask(0, c45_mask, RTL930X_SMI_GLB_CTRL); - - /* Set the MAC type of each port according to the PHY-interface */ - /* Values are FE: 2, GE: 3, XGE/2.5G: 0(SERDES) or 1(otherwise), SXGE: 0 */ - v = 0; - for (int i = 0; i < RTL930X_CPU_PORT; i++) { - switch (priv->interfaces[i]) { - case PHY_INTERFACE_MODE_10GBASER: - break; /* Serdes: Value = 0 */ - case PHY_INTERFACE_MODE_HSGMII: - private_poll_mask |= BIT(i); - fallthrough; - case PHY_INTERFACE_MODE_USXGMII: - v |= BIT(mac_type_bit[i]); - uses_usxgmii = true; - break; - case PHY_INTERFACE_MODE_QSGMII: - private_poll_mask |= BIT(i); - v |= 3 << mac_type_bit[i]; - break; - default: - break; - } - } - sw_w32(v, RTL930X_SMI_MAC_TYPE_CTRL); - - /* Set the private polling mask for all Realtek PHYs (i.e. not the 10GBit Aquantia ones) */ - sw_w32(private_poll_mask, RTL930X_SMI_PRVTE_POLLING_CTRL); - - /* The following magic values are found in the port configuration, they seem to - * define different ways of polling a PHY. The below is for the Aquantia PHYs of - * the XGS1250 and the RTL8226 of the XGS1210 - */ - if (uses_usxgmii) { - sw_w32(0x01010000, RTL930X_SMI_10GPHY_POLLING_REG0_CFG); - sw_w32(0x01E7C400, RTL930X_SMI_10GPHY_POLLING_REG9_CFG); - sw_w32(0x01E7E820, RTL930X_SMI_10GPHY_POLLING_REG10_CFG); - } - if (uses_hisgmii) { - sw_w32(0x011FA400, RTL930X_SMI_10GPHY_POLLING_REG0_CFG); - sw_w32(0x013FA412, RTL930X_SMI_10GPHY_POLLING_REG9_CFG); - sw_w32(0x017FA414, RTL930X_SMI_10GPHY_POLLING_REG10_CFG); - } - - pr_debug("%s: RTL930X_SMI_GLB_CTRL %08x\n", __func__, - sw_r32(RTL930X_SMI_GLB_CTRL)); - pr_debug("%s: RTL930X_SMI_PORT0_15_POLLING_SEL %08x\n", __func__, - sw_r32(RTL930X_SMI_PORT0_15_POLLING_SEL)); - pr_debug("%s: RTL930X_SMI_PORT16_27_POLLING_SEL %08x\n", __func__, - sw_r32(RTL930X_SMI_PORT16_27_POLLING_SEL)); - pr_debug("%s: RTL930X_SMI_MAC_TYPE_CTRL %08x\n", __func__, - sw_r32(RTL930X_SMI_MAC_TYPE_CTRL)); - pr_debug("%s: RTL930X_SMI_10GPHY_POLLING_REG0_CFG %08x\n", __func__, - sw_r32(RTL930X_SMI_10GPHY_POLLING_REG0_CFG)); - pr_debug("%s: RTL930X_SMI_10GPHY_POLLING_REG9_CFG %08x\n", __func__, - sw_r32(RTL930X_SMI_10GPHY_POLLING_REG9_CFG)); - pr_debug("%s: RTL930X_SMI_10GPHY_POLLING_REG10_CFG %08x\n", __func__, - sw_r32(RTL930X_SMI_10GPHY_POLLING_REG10_CFG)); - pr_debug("%s: RTL930X_SMI_PRVTE_POLLING_CTRL %08x\n", __func__, - sw_r32(RTL930X_SMI_PRVTE_POLLING_CTRL)); - - return 0; -} - -static int rtmdio_931x_reset(struct mii_bus *bus) -{ - struct rtl838x_bus_priv *bus_priv = bus->priv; - struct rtl838x_eth_priv *priv = bus_priv->eth_priv; - u32 c45_mask = 0; - u32 poll_sel[4]; - u32 poll_ctrl = 0; - bool mdc_on[4]; - - pr_info("%s called\n", __func__); - /* Disable port polling for configuration purposes */ - sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL); - sw_w32(0, RTL931X_SMI_PORT_POLLING_CTRL + 4); - msleep(100); - - mdc_on[0] = mdc_on[1] = mdc_on[2] = mdc_on[3] = false; - /* Mapping of port to phy-addresses on an SMI bus */ - poll_sel[0] = poll_sel[1] = poll_sel[2] = poll_sel[3] = 0; - for (int i = 0; i < 56; i++) { - u32 pos; - - pos = (i % 6) * 5; - sw_w32_mask(0x1f << pos, priv->smi_addr[i] << pos, RTL931X_SMI_PORT_ADDR + (i / 6) * 4); - pos = (i * 2) % 32; - poll_sel[i / 16] |= priv->smi_bus[i] << pos; - poll_ctrl |= BIT(20 + priv->smi_bus[i]); - mdc_on[priv->smi_bus[i]] = true; - } - - /* Configure which SMI bus is behind which port number */ - for (int i = 0; i < 4; i++) { - pr_info("poll sel %d, %08x\n", i, poll_sel[i]); - sw_w32(poll_sel[i], RTL931X_SMI_PORT_POLLING_SEL + (i * 4)); - } - - /* Configure which SMI busses */ - pr_info("%s: WAS RTL931X_MAC_L2_GLOBAL_CTRL2 %08x\n", __func__, sw_r32(RTL931X_MAC_L2_GLOBAL_CTRL2)); - pr_info("c45_mask: %08x, RTL931X_SMI_GLB_CTRL0 was %X", c45_mask, sw_r32(RTL931X_SMI_GLB_CTRL0)); - for (int i = 0; i < 4; i++) { - /* bus is polled in c45 */ - if (priv->smi_bus_isc45[i]) - c45_mask |= 0x2 << (i * 2); /* Std. C45, non-standard is 0x3 */ - /* Enable bus access via MDC */ - if (mdc_on[i]) - sw_w32_mask(0, BIT(9 + i), RTL931X_MAC_L2_GLOBAL_CTRL2); - } - - pr_info("%s: RTL931X_MAC_L2_GLOBAL_CTRL2 %08x\n", __func__, sw_r32(RTL931X_MAC_L2_GLOBAL_CTRL2)); - pr_info("c45_mask: %08x, RTL931X_SMI_GLB_CTRL0 was %X", c45_mask, sw_r32(RTL931X_SMI_GLB_CTRL0)); - - /* We have a 10G PHY enable polling - * sw_w32(0x01010000, RTL931X_SMI_10GPHY_POLLING_SEL2); - * sw_w32(0x01E7C400, RTL931X_SMI_10GPHY_POLLING_SEL3); - * sw_w32(0x01E7E820, RTL931X_SMI_10GPHY_POLLING_SEL4); - */ - sw_w32_mask(0xff, c45_mask, RTL931X_SMI_GLB_CTRL1); - - return 0; -} - -static int rtl931x_chip_init(struct rtl838x_eth_priv *priv) -{ - pr_info("In %s\n", __func__); - - /* Initialize Encapsulation memory and wait until finished */ - sw_w32(0x1, RTL931X_MEM_ENCAP_INIT); - do { } while (sw_r32(RTL931X_MEM_ENCAP_INIT) & 1); - pr_info("%s: init ENCAP done\n", __func__); - - /* Initialize Managemen Information Base memory and wait until finished */ - sw_w32(0x1, RTL931X_MEM_MIB_INIT); - do { } while (sw_r32(RTL931X_MEM_MIB_INIT) & 1); - pr_info("%s: init MIB done\n", __func__); - - /* Initialize ACL (PIE) memory and wait until finished */ - sw_w32(0x1, RTL931X_MEM_ACL_INIT); - do { } while (sw_r32(RTL931X_MEM_ACL_INIT) & 1); - pr_info("%s: init ACL done\n", __func__); - - /* Initialize ALE memory and wait until finished */ - sw_w32(0xFFFFFFFF, RTL931X_MEM_ALE_INIT_0); - do { } while (sw_r32(RTL931X_MEM_ALE_INIT_0)); - sw_w32(0x7F, RTL931X_MEM_ALE_INIT_1); - sw_w32(0x7ff, RTL931X_MEM_ALE_INIT_2); - do { } while (sw_r32(RTL931X_MEM_ALE_INIT_2) & 0x7ff); - pr_info("%s: init ALE done\n", __func__); - - /* Enable ESD auto recovery */ - sw_w32(0x1, RTL931X_MDX_CTRL_RSVD); - - /* Init SPI, is this for thermal control or what? */ - sw_w32_mask(0x7 << 11, 0x2 << 11, RTL931X_SPI_CTRL0); - - return 0; -} - -static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv) -{ - struct device_node *mii_np, *dn; - struct rtl838x_bus_priv *bus_priv; - u32 pn; - int i, ret; - - pr_debug("%s called\n", __func__); - mii_np = of_get_child_by_name(priv->pdev->dev.of_node, "mdio-bus"); - - if (!mii_np) { - dev_err(&priv->pdev->dev, "no %s child node found", "mdio-bus"); - return -ENODEV; - } - - if (!of_device_is_available(mii_np)) { - ret = -ENODEV; - goto err_put_node; - } - - priv->mii_bus = devm_mdiobus_alloc_size(&priv->pdev->dev, sizeof(*bus_priv)); - if (!priv->mii_bus) { - ret = -ENOMEM; - goto err_put_node; - } - - bus_priv = priv->mii_bus->priv; - bus_priv->eth_priv = priv; - for (i=0; i < 64; i++) { - bus_priv->page[i] = 0; - bus_priv->raw[i] = false; - } - bus_priv->extaddr = -1; - - switch(priv->family_id) { - case RTL8380_FAMILY_ID: - priv->mii_bus->name = "rtl838x-eth-mdio"; - priv->mii_bus->read = rtmdio_83xx_read_legacy; - priv->mii_bus->write = rtmdio_83xx_write_legacy; - priv->mii_bus->reset = rtmdio_838x_reset; - bus_priv->read_mmd_phy = rtl838x_read_mmd_phy; - bus_priv->write_mmd_phy = rtl838x_write_mmd_phy; - bus_priv->read_phy = rtl838x_read_phy; - bus_priv->write_phy = rtl838x_write_phy; - bus_priv->rawpage = 0xfff; - break; - case RTL8390_FAMILY_ID: - priv->mii_bus->name = "rtl839x-eth-mdio"; - priv->mii_bus->read = rtmdio_83xx_read_legacy; - priv->mii_bus->write = rtmdio_83xx_write_legacy; - priv->mii_bus->reset = rtmdio_839x_reset; - bus_priv->read_mmd_phy = rtl839x_read_mmd_phy; - bus_priv->write_mmd_phy = rtl839x_write_mmd_phy; - bus_priv->read_phy = rtl839x_read_phy; - bus_priv->write_phy = rtl839x_write_phy; - bus_priv->rawpage = 0x1fff; - break; - case RTL9300_FAMILY_ID: - priv->mii_bus->name = "rtl930x-eth-mdio"; - priv->mii_bus->read = rtmdio_93xx_read_legacy; - priv->mii_bus->write = rtmdio_93xx_write_legacy; - priv->mii_bus->reset = rtmdio_930x_reset; - bus_priv->read_mmd_phy = rtl930x_read_mmd_phy; - bus_priv->write_mmd_phy = rtl930x_write_mmd_phy; - bus_priv->read_phy = rtl930x_read_phy; - bus_priv->write_phy = rtl930x_write_phy; - bus_priv->rawpage = 0xfff; - priv->mii_bus->probe_capabilities = MDIOBUS_C22_C45; - break; - case RTL9310_FAMILY_ID: - priv->mii_bus->name = "rtl931x-eth-mdio"; - priv->mii_bus->read = rtmdio_93xx_read_legacy; - priv->mii_bus->write = rtmdio_93xx_write_legacy; - priv->mii_bus->reset = rtmdio_931x_reset; - bus_priv->read_mmd_phy = rtl931x_read_mmd_phy; - bus_priv->write_mmd_phy = rtl931x_write_mmd_phy; - bus_priv->read_phy = rtl931x_read_phy; - bus_priv->write_phy = rtl931x_write_phy; - bus_priv->rawpage = 0x1fff; - priv->mii_bus->probe_capabilities = MDIOBUS_C22_C45; - break; - } - priv->mii_bus->parent = &priv->pdev->dev; - - for_each_node_by_name(dn, "ethernet-phy") { - u32 smi_addr[2]; - - if (of_property_read_u32(dn, "reg", &pn)) - continue; - - if (of_property_read_u32_array(dn, "rtl9300,smi-address", &smi_addr[0], 2)) { - smi_addr[0] = 0; - smi_addr[1] = pn; - } - - if (of_property_read_u32(dn, "sds", &priv->sds_id[pn])) - priv->sds_id[pn] = -1; - else { - pr_info("set sds port %d to %d\n", pn, priv->sds_id[pn]); - } - - if (pn < MAX_PORTS) { - priv->smi_bus[pn] = smi_addr[0]; - priv->smi_addr[pn] = smi_addr[1]; - } else { - pr_err("%s: illegal port number %d\n", __func__, pn); - } - - if (of_device_is_compatible(dn, "ethernet-phy-ieee802.3-c45")) - priv->smi_bus_isc45[smi_addr[0]] = true; - - if (of_property_read_bool(dn, "phy-is-integrated")) { - priv->phy_is_internal[pn] = true; - } - } - - dn = of_find_compatible_node(NULL, NULL, "realtek,rtl83xx-switch"); - if (!dn) { - dev_err(&priv->pdev->dev, "No RTL switch node in DTS\n"); - return -ENODEV; - } - - for_each_node_by_name(dn, "port") { - if (of_property_read_u32(dn, "reg", &pn)) - continue; - pr_debug("%s Looking at port %d\n", __func__, pn); - if (pn > priv->cpu_port) - continue; - if (of_get_phy_mode(dn, &priv->interfaces[pn])) - priv->interfaces[pn] = PHY_INTERFACE_MODE_NA; - pr_debug("%s phy mode of port %d is %s\n", __func__, pn, phy_modes(priv->interfaces[pn])); - } - - snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np); - ret = of_mdiobus_register(priv->mii_bus, mii_np); - -err_put_node: - of_node_put(mii_np); - - return ret; -} - -static int rtl838x_mdio_remove(struct rtl838x_eth_priv *priv) -{ - pr_debug("%s called\n", __func__); - if (!priv->mii_bus) - return 0; - - mdiobus_unregister(priv->mii_bus); - mdiobus_free(priv->mii_bus); - - return 0; -} - -static netdev_features_t rtl838x_fix_features(struct net_device *dev, - netdev_features_t features) -{ - return features; -} - -static int rtl83xx_set_features(struct net_device *dev, netdev_features_t features) -{ - struct rtl838x_eth_priv *priv = netdev_priv(dev); - - if ((features ^ dev->features) & NETIF_F_RXCSUM) { - if (!(features & NETIF_F_RXCSUM)) - sw_w32_mask(BIT(3), 0, priv->r->mac_port_ctrl(priv->cpu_port)); - else - sw_w32_mask(0, BIT(3), priv->r->mac_port_ctrl(priv->cpu_port)); - } - - return 0; -} - -static int rtl93xx_set_features(struct net_device *dev, netdev_features_t features) -{ - struct rtl838x_eth_priv *priv = netdev_priv(dev); - - if ((features ^ dev->features) & NETIF_F_RXCSUM) { - if (!(features & NETIF_F_RXCSUM)) - sw_w32_mask(BIT(4), 0, priv->r->mac_port_ctrl(priv->cpu_port)); - else - sw_w32_mask(0, BIT(4), priv->r->mac_port_ctrl(priv->cpu_port)); - } - - return 0; -} - -static const struct net_device_ops rtl838x_eth_netdev_ops = { - .ndo_open = rtl838x_eth_open, - .ndo_stop = rtl838x_eth_stop, - .ndo_start_xmit = rtl838x_eth_tx, - .ndo_select_queue = rtl83xx_pick_tx_queue, - .ndo_set_mac_address = rtl838x_set_mac_address, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_rx_mode = rtl838x_eth_set_multicast_list, - .ndo_tx_timeout = rtl838x_eth_tx_timeout, - .ndo_set_features = rtl83xx_set_features, - .ndo_fix_features = rtl838x_fix_features, - .ndo_setup_tc = rtl83xx_setup_tc, -}; - -static const struct net_device_ops rtl839x_eth_netdev_ops = { - .ndo_open = rtl838x_eth_open, - .ndo_stop = rtl838x_eth_stop, - .ndo_start_xmit = rtl838x_eth_tx, - .ndo_select_queue = rtl83xx_pick_tx_queue, - .ndo_set_mac_address = rtl838x_set_mac_address, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_rx_mode = rtl839x_eth_set_multicast_list, - .ndo_tx_timeout = rtl838x_eth_tx_timeout, - .ndo_set_features = rtl83xx_set_features, - .ndo_fix_features = rtl838x_fix_features, - .ndo_setup_tc = rtl83xx_setup_tc, -}; - -static const struct net_device_ops rtl930x_eth_netdev_ops = { - .ndo_open = rtl838x_eth_open, - .ndo_stop = rtl838x_eth_stop, - .ndo_start_xmit = rtl838x_eth_tx, - .ndo_select_queue = rtl93xx_pick_tx_queue, - .ndo_set_mac_address = rtl838x_set_mac_address, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_rx_mode = rtl930x_eth_set_multicast_list, - .ndo_tx_timeout = rtl838x_eth_tx_timeout, - .ndo_set_features = rtl93xx_set_features, - .ndo_fix_features = rtl838x_fix_features, - .ndo_setup_tc = rtl83xx_setup_tc, -}; - -static const struct net_device_ops rtl931x_eth_netdev_ops = { - .ndo_open = rtl838x_eth_open, - .ndo_stop = rtl838x_eth_stop, - .ndo_start_xmit = rtl838x_eth_tx, - .ndo_select_queue = rtl93xx_pick_tx_queue, - .ndo_set_mac_address = rtl838x_set_mac_address, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_rx_mode = rtl931x_eth_set_multicast_list, - .ndo_tx_timeout = rtl838x_eth_tx_timeout, - .ndo_set_features = rtl93xx_set_features, - .ndo_fix_features = rtl838x_fix_features, -}; - -static const struct phylink_mac_ops rtl838x_phylink_ops = { - .validate = rtl838x_validate, - .mac_pcs_get_state = rtl838x_mac_pcs_get_state, - .mac_an_restart = rtl838x_mac_an_restart, - .mac_config = rtl838x_mac_config, - .mac_link_down = rtl838x_mac_link_down, - .mac_link_up = rtl838x_mac_link_up, -}; - -static const struct ethtool_ops rtl838x_ethtool_ops = { - .get_link_ksettings = rtl838x_get_link_ksettings, - .set_link_ksettings = rtl838x_set_link_ksettings, -}; - -static int __init rtl838x_eth_probe(struct platform_device *pdev) -{ - struct net_device *dev; - struct device_node *dn = pdev->dev.of_node; - struct rtl838x_eth_priv *priv; - struct resource *res, *mem; - phy_interface_t phy_mode; - struct phylink *phylink; - u8 mac_addr[ETH_ALEN]; - int err = 0, rxrings, rxringlen; - struct ring_b *ring; - - pr_info("Probing RTL838X eth device pdev: %x, dev: %x\n", - (u32)pdev, (u32)(&(pdev->dev))); - - if (!dn) { - dev_err(&pdev->dev, "No DT found\n"); - return -EINVAL; - } - - rxrings = (soc_info.family == RTL8380_FAMILY_ID - || soc_info.family == RTL8390_FAMILY_ID) ? 8 : 32; - rxrings = rxrings > MAX_RXRINGS ? MAX_RXRINGS : rxrings; - rxringlen = MAX_ENTRIES / rxrings; - rxringlen = rxringlen > MAX_RXLEN ? MAX_RXLEN : rxringlen; - - dev = alloc_etherdev_mqs(sizeof(struct rtl838x_eth_priv), TXRINGS, rxrings); - if (!dev) { - err = -ENOMEM; - goto err_free; - } - SET_NETDEV_DEV(dev, &pdev->dev); - priv = netdev_priv(dev); - - /* obtain buffer memory space */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res) { - mem = devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), res->name); - if (!mem) { - dev_err(&pdev->dev, "cannot request memory space\n"); - err = -ENXIO; - goto err_free; - } - - dev->mem_start = mem->start; - dev->mem_end = mem->end; - } else { - dev_err(&pdev->dev, "cannot request IO resource\n"); - err = -ENXIO; - goto err_free; - } - - /* Allocate buffer memory */ - priv->membase = dmam_alloc_coherent(&pdev->dev, rxrings * rxringlen * RING_BUFFER + - sizeof(struct ring_b) + sizeof(struct notify_b), - (void *)&dev->mem_start, GFP_KERNEL); - if (!priv->membase) { - dev_err(&pdev->dev, "cannot allocate DMA buffer\n"); - err = -ENOMEM; - goto err_free; - } - - /* Allocate ring-buffer space at the end of the allocated memory */ - ring = priv->membase; - ring->rx_space = priv->membase + sizeof(struct ring_b) + sizeof(struct notify_b); - - spin_lock_init(&priv->lock); - - dev->ethtool_ops = &rtl838x_ethtool_ops; - dev->min_mtu = ETH_ZLEN; - dev->max_mtu = DEFAULT_MTU; - dev->features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM; - dev->hw_features = NETIF_F_RXCSUM; - - priv->id = soc_info.id; - priv->family_id = soc_info.family; - if (priv->id) { - pr_info("Found SoC ID: %4x: %s, family %x\n", - priv->id, soc_info.name, priv->family_id); - } else { - pr_err("Unknown chip id (%04x)\n", priv->id); - return -ENODEV; - } - - switch (priv->family_id) { - case RTL8380_FAMILY_ID: - priv->cpu_port = RTL838X_CPU_PORT; - priv->r = &rtl838x_reg; - dev->netdev_ops = &rtl838x_eth_netdev_ops; - break; - case RTL8390_FAMILY_ID: - priv->cpu_port = RTL839X_CPU_PORT; - priv->r = &rtl839x_reg; - dev->netdev_ops = &rtl839x_eth_netdev_ops; - break; - case RTL9300_FAMILY_ID: - priv->cpu_port = RTL930X_CPU_PORT; - priv->r = &rtl930x_reg; - dev->netdev_ops = &rtl930x_eth_netdev_ops; - break; - case RTL9310_FAMILY_ID: - priv->cpu_port = RTL931X_CPU_PORT; - priv->r = &rtl931x_reg; - dev->netdev_ops = &rtl931x_eth_netdev_ops; - rtl931x_chip_init(priv); - break; - default: - pr_err("Unknown SoC family\n"); - return -ENODEV; - } - priv->rxringlen = rxringlen; - priv->rxrings = rxrings; - - /* Obtain device IRQ number */ - dev->irq = platform_get_irq(pdev, 0); - if (dev->irq < 0) { - dev_err(&pdev->dev, "cannot obtain network-device IRQ\n"); - goto err_free; - } - - err = devm_request_irq(&pdev->dev, dev->irq, priv->r->net_irq, - IRQF_SHARED, dev->name, dev); - if (err) { - dev_err(&pdev->dev, "%s: could not acquire interrupt: %d\n", - __func__, err); - goto err_free; - } - - rtl8380_init_mac(priv); - - /* Try to get mac address in the following order: - * 1) from device tree data - * 2) from internal registers set by bootloader - */ - of_get_mac_address(pdev->dev.of_node, mac_addr); - if (is_valid_ether_addr(mac_addr)) { - rtl838x_set_mac_hw(dev, mac_addr); - } else { - mac_addr[0] = (sw_r32(priv->r->mac) >> 8) & 0xff; - mac_addr[1] = sw_r32(priv->r->mac) & 0xff; - mac_addr[2] = (sw_r32(priv->r->mac + 4) >> 24) & 0xff; - mac_addr[3] = (sw_r32(priv->r->mac + 4) >> 16) & 0xff; - mac_addr[4] = (sw_r32(priv->r->mac + 4) >> 8) & 0xff; - mac_addr[5] = sw_r32(priv->r->mac + 4) & 0xff; - } - dev_addr_set(dev, mac_addr); - /* if the address is invalid, use a random value */ - if (!is_valid_ether_addr(dev->dev_addr)) { - struct sockaddr sa = { AF_UNSPEC }; - - netdev_warn(dev, "Invalid MAC address, using random\n"); - eth_hw_addr_random(dev); - memcpy(sa.sa_data, dev->dev_addr, ETH_ALEN); - if (rtl838x_set_mac_address(dev, &sa)) - netdev_warn(dev, "Failed to set MAC address.\n"); - } - pr_info("Using MAC %08x%08x\n", sw_r32(priv->r->mac), - sw_r32(priv->r->mac + 4)); - strcpy(dev->name, "eth%d"); - priv->pdev = pdev; - priv->netdev = dev; - - err = rtl838x_mdio_init(priv); - if (err) - goto err_free; - - err = register_netdev(dev); - if (err) - goto err_free; - - for (int i = 0; i < priv->rxrings; i++) { - priv->rx_qs[i].id = i; - priv->rx_qs[i].priv = priv; - netif_napi_add(dev, &priv->rx_qs[i].napi, rtl838x_poll_rx, 64); - } - - platform_set_drvdata(pdev, dev); - - phy_mode = PHY_INTERFACE_MODE_NA; - err = of_get_phy_mode(dn, &phy_mode); - if (err < 0) { - dev_err(&pdev->dev, "incorrect phy-mode\n"); - err = -EINVAL; - goto err_free; - } - - priv->phylink_config.dev = &dev->dev; - priv->phylink_config.type = PHYLINK_NETDEV; - - phylink = phylink_create(&priv->phylink_config, pdev->dev.fwnode, - phy_mode, &rtl838x_phylink_ops); - - if (IS_ERR(phylink)) { - err = PTR_ERR(phylink); - goto err_free; - } - priv->phylink = phylink; - - return 0; - -err_free: - pr_err("Error setting up netdev, freeing it again.\n"); - free_netdev(dev); - - return err; -} - -static int rtl838x_eth_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct rtl838x_eth_priv *priv = netdev_priv(dev); - - if (dev) { - pr_info("Removing platform driver for rtl838x-eth\n"); - rtl838x_mdio_remove(priv); - rtl838x_hw_stop(priv); - - netif_tx_stop_all_queues(dev); - - for (int i = 0; i < priv->rxrings; i++) - netif_napi_del(&priv->rx_qs[i].napi); - - unregister_netdev(dev); - free_netdev(dev); - } - - return 0; -} - -static const struct of_device_id rtl838x_eth_of_ids[] = { - { .compatible = "realtek,rtl838x-eth"}, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, rtl838x_eth_of_ids); - -static struct platform_driver rtl838x_eth_driver = { - .probe = rtl838x_eth_probe, - .remove = rtl838x_eth_remove, - .driver = { - .name = "rtl838x-eth", - .pm = NULL, - .of_match_table = rtl838x_eth_of_ids, - }, -}; - -module_platform_driver(rtl838x_eth_driver); - -MODULE_AUTHOR("B. Koblitz"); -MODULE_DESCRIPTION("RTL838X SoC Ethernet Driver"); -MODULE_LICENSE("GPL"); diff --git a/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.h b/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.h deleted file mode 100644 index d6d88fc2ed01b8..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/ethernet/rtl838x_eth.h +++ /dev/null @@ -1,470 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _RTL838X_ETH_H -#define _RTL838X_ETH_H - -/* Register definition */ - -/* Per port MAC control */ -#define RTL838X_MAC_PORT_CTRL (0xd560) -#define RTL839X_MAC_PORT_CTRL (0x8004) -#define RTL930X_MAC_L2_PORT_CTRL (0x3268) -#define RTL930X_MAC_PORT_CTRL (0x3260) -#define RTL931X_MAC_L2_PORT_CTRL (0x6000) -#define RTL931X_MAC_PORT_CTRL (0x6004) - -/* DMA interrupt control and status registers */ -#define RTL838X_DMA_IF_CTRL (0x9f58) -#define RTL838X_DMA_IF_INTR_STS (0x9f54) -#define RTL838X_DMA_IF_INTR_MSK (0x9f50) - -#define RTL839X_DMA_IF_CTRL (0x786c) -#define RTL839X_DMA_IF_INTR_STS (0x7868) -#define RTL839X_DMA_IF_INTR_MSK (0x7864) - -#define RTL930X_DMA_IF_CTRL (0xe028) -#define RTL930X_DMA_IF_INTR_RX_RUNOUT_STS (0xe01C) -#define RTL930X_DMA_IF_INTR_RX_DONE_STS (0xe020) -#define RTL930X_DMA_IF_INTR_TX_DONE_STS (0xe024) -#define RTL930X_DMA_IF_INTR_RX_RUNOUT_MSK (0xe010) -#define RTL930X_DMA_IF_INTR_RX_DONE_MSK (0xe014) -#define RTL930X_DMA_IF_INTR_TX_DONE_MSK (0xe018) -#define RTL930X_L2_NTFY_IF_INTR_MSK (0xe04C) -#define RTL930X_L2_NTFY_IF_INTR_STS (0xe050) - -/* TODO: RTL931X_DMA_IF_CTRL has different bits meanings */ -#define RTL931X_DMA_IF_CTRL (0x0928) -#define RTL931X_DMA_IF_INTR_RX_RUNOUT_STS (0x091c) -#define RTL931X_DMA_IF_INTR_RX_DONE_STS (0x0920) -#define RTL931X_DMA_IF_INTR_TX_DONE_STS (0x0924) -#define RTL931X_DMA_IF_INTR_RX_RUNOUT_MSK (0x0910) -#define RTL931X_DMA_IF_INTR_RX_DONE_MSK (0x0914) -#define RTL931X_DMA_IF_INTR_TX_DONE_MSK (0x0918) -#define RTL931X_L2_NTFY_IF_INTR_MSK (0x09E4) -#define RTL931X_L2_NTFY_IF_INTR_STS (0x09E8) - -#define RTL838X_MAC_FORCE_MODE_CTRL (0xa104) -#define RTL839X_MAC_FORCE_MODE_CTRL (0x02bc) -#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C) -#define RTL931X_MAC_FORCE_MODE_CTRL (0x0ddc) - -/* MAC address settings */ -#define RTL838X_MAC (0xa9ec) -#define RTL839X_MAC (0x02b4) -#define RTL838X_MAC_ALE (0x6b04) -#define RTL838X_MAC2 (0xa320) -#define RTL930X_MAC_L2_ADDR_CTRL (0xC714) -#define RTL931X_MAC_L2_ADDR_CTRL (0x135c) - -/* Ringbuffer setup */ -#define RTL838X_DMA_RX_BASE (0x9f00) -#define RTL839X_DMA_RX_BASE (0x780c) -#define RTL930X_DMA_RX_BASE (0xdf00) -#define RTL931X_DMA_RX_BASE (0x0800) - -#define RTL838X_DMA_TX_BASE (0x9f40) -#define RTL839X_DMA_TX_BASE (0x784c) -#define RTL930X_DMA_TX_BASE (0xe000) -#define RTL931X_DMA_TX_BASE (0x0900) - -#define RTL838X_DMA_IF_RX_RING_SIZE (0xB7E4) -#define RTL839X_DMA_IF_RX_RING_SIZE (0x6038) -#define RTL930X_DMA_IF_RX_RING_SIZE (0x7C60) -#define RTL931X_DMA_IF_RX_RING_SIZE (0x2080) - -#define RTL838X_DMA_IF_RX_RING_CNTR (0xB7E8) -#define RTL839X_DMA_IF_RX_RING_CNTR (0x603c) -#define RTL930X_DMA_IF_RX_RING_CNTR (0x7C8C) -#define RTL931X_DMA_IF_RX_RING_CNTR (0x20AC) - -#define RTL838X_DMA_IF_RX_CUR (0x9F20) -#define RTL839X_DMA_IF_RX_CUR (0x782c) -#define RTL930X_DMA_IF_RX_CUR (0xdf80) -#define RTL931X_DMA_IF_RX_CUR (0x0880) - -#define RTL838X_DMA_IF_TX_CUR_DESC_ADDR_CTRL (0x9F48) -#define RTL930X_DMA_IF_TX_CUR_DESC_ADDR_CTRL (0xE008) - -#define RTL838X_DMY_REG31 (0x3b28) -#define RTL838X_SDS_MODE_SEL (0x0028) -#define RTL838X_SDS_CFG_REG (0x0034) -#define RTL838X_INT_MODE_CTRL (0x005c) -#define RTL838X_CHIP_INFO (0x00d8) -#define RTL838X_SDS4_REG28 (0xef80) -#define RTL838X_SDS4_DUMMY0 (0xef8c) -#define RTL838X_SDS5_EXT_REG6 (0xf18c) - -/* L2 features */ -#define RTL839X_TBL_ACCESS_L2_CTRL (0x1180) -#define RTL839X_TBL_ACCESS_L2_DATA(idx) (0x1184 + ((idx) << 2)) -#define RTL838X_TBL_ACCESS_CTRL_0 (0x6914) -#define RTL838X_TBL_ACCESS_DATA_0(idx) (0x6918 + ((idx) << 2)) - -/* MAC-side link state handling */ -#define RTL838X_MAC_LINK_STS (0xa188) -#define RTL839X_MAC_LINK_STS (0x0390) -#define RTL930X_MAC_LINK_STS (0xCB10) -#define RTL931X_MAC_LINK_STS (0x0ec0) - -#define RTL838X_MAC_LINK_SPD_STS (0xa190) -#define RTL839X_MAC_LINK_SPD_STS (0x03a0) -#define RTL930X_MAC_LINK_SPD_STS (0xCB18) -#define RTL931X_MAC_LINK_SPD_STS (0x0ed0) - -#define RTL838X_MAC_LINK_DUP_STS (0xa19c) -#define RTL839X_MAC_LINK_DUP_STS (0x03b0) -#define RTL930X_MAC_LINK_DUP_STS (0xCB28) -#define RTL931X_MAC_LINK_DUP_STS (0x0ef0) - -/* TODO: RTL8390_MAC_LINK_MEDIA_STS_ADDR??? */ - -#define RTL838X_MAC_TX_PAUSE_STS (0xa1a0) -#define RTL839X_MAC_TX_PAUSE_STS (0x03b8) -#define RTL930X_MAC_TX_PAUSE_STS (0xCB2C) -#define RTL931X_MAC_TX_PAUSE_STS (0x0ef8) - -#define RTL838X_MAC_RX_PAUSE_STS (0xa1a4) -#define RTL839X_MAC_RX_PAUSE_STS (0xCB30) -#define RTL930X_MAC_RX_PAUSE_STS (0xC2F8) -#define RTL931X_MAC_RX_PAUSE_STS (0x0f00) - -#define RTL838X_EEE_TX_TIMER_GIGA_CTRL (0xaa04) -#define RTL838X_EEE_TX_TIMER_GELITE_CTRL (0xaa08) - -#define RTL930X_L2_UNKN_UC_FLD_PMSK (0x9064) -#define RTL931X_L2_UNKN_UC_FLD_PMSK (0xC8F4) - -#define RTL839X_MAC_GLB_CTRL (0x02a8) -#define RTL839X_SCHED_LB_TICK_TKN_CTRL (0x60f8) - -#define RTL838X_L2_TBL_FLUSH_CTRL (0x3370) -#define RTL839X_L2_TBL_FLUSH_CTRL (0x3ba0) -#define RTL930X_L2_TBL_FLUSH_CTRL (0x9404) -#define RTL931X_L2_TBL_FLUSH_CTRL (0xCD9C) - -#define RTL930X_L2_PORT_SABLK_CTRL (0x905c) -#define RTL930X_L2_PORT_DABLK_CTRL (0x9060) - -/* MAC link state bits */ -#define FORCE_EN (1 << 0) -#define FORCE_LINK_EN (1 << 1) -#define NWAY_EN (1 << 2) -#define DUPLX_MODE (1 << 3) -#define TX_PAUSE_EN (1 << 6) -#define RX_PAUSE_EN (1 << 7) - -/* L2 Notification DMA interface */ -#define RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL (0x785C) -#define RTL839X_L2_NOTIFICATION_CTRL (0x7808) -#define RTL931X_L2_NTFY_RING_BASE_ADDR (0x09DC) -#define RTL931X_L2_NTFY_RING_CUR_ADDR (0x09E0) -#define RTL839X_L2_NOTIFICATION_CTRL (0x7808) -#define RTL931X_L2_NTFY_CTRL (0xCDC8) -#define RTL838X_L2_CTRL_0 (0x3200) -#define RTL839X_L2_CTRL_0 (0x3800) -#define RTL930X_L2_CTRL (0x8FD8) -#define RTL931X_L2_CTRL (0xC800) - -/* TRAPPING to CPU-PORT */ -#define RTL838X_SPCL_TRAP_IGMP_CTRL (0x6984) -#define RTL838X_RMA_CTRL_0 (0x4300) -#define RTL838X_RMA_CTRL_1 (0x4304) -#define RTL839X_RMA_CTRL_0 (0x1200) - -#define RTL839X_SPCL_TRAP_IGMP_CTRL (0x1058) -#define RTL839X_RMA_CTRL_1 (0x1204) -#define RTL839X_RMA_CTRL_2 (0x1208) -#define RTL839X_RMA_CTRL_3 (0x120C) - -#define RTL930X_VLAN_APP_PKT_CTRL (0xA23C) -#define RTL930X_RMA_CTRL_0 (0x9E60) -#define RTL930X_RMA_CTRL_1 (0x9E64) -#define RTL930X_RMA_CTRL_2 (0x9E68) - -#define RTL931X_VLAN_APP_PKT_CTRL (0x96b0) -#define RTL931X_RMA_CTRL_0 (0x8800) -#define RTL931X_RMA_CTRL_1 (0x8804) -#define RTL931X_RMA_CTRL_2 (0x8808) - -/* Advanced SMI control for clause 45 PHYs */ -#define RTL930X_SMI_MAC_TYPE_CTRL (0xCA04) -#define RTL930X_SMI_PORT24_27_ADDR_CTRL (0xCB90) -#define RTL930X_SMI_PORT0_15_POLLING_SEL (0xCA08) -#define RTL930X_SMI_PORT16_27_POLLING_SEL (0xCA0C) - -#define RTL930X_SMI_10GPHY_POLLING_REG0_CFG (0xCBB4) -#define RTL930X_SMI_10GPHY_POLLING_REG9_CFG (0xCBB8) -#define RTL930X_SMI_10GPHY_POLLING_REG10_CFG (0xCBBC) -#define RTL930X_SMI_PRVTE_POLLING_CTRL (0xCA10) - -/* Registers of the internal Serdes of the 8390 */ -#define RTL839X_SDS12_13_XSG0 (0xB800) - -/* Chip configuration registers of the RTL9310 */ -#define RTL931X_MEM_ENCAP_INIT (0x4854) -#define RTL931X_MEM_MIB_INIT (0x7E18) -#define RTL931X_MEM_ACL_INIT (0x40BC) -#define RTL931X_MEM_ALE_INIT_0 (0x83F0) -#define RTL931X_MEM_ALE_INIT_1 (0x83F4) -#define RTL931X_MEM_ALE_INIT_2 (0x82E4) -#define RTL931X_MDX_CTRL_RSVD (0x0fcc) -#define RTL931X_PS_SOC_CTRL (0x13f8) -#define RTL931X_SMI_10GPHY_POLLING_SEL2 (0xCF8) -#define RTL931X_SMI_10GPHY_POLLING_SEL3 (0xCFC) -#define RTL931X_SMI_10GPHY_POLLING_SEL4 (0xD00) - -/* Registers of the internal Serdes of the 8380 */ -#define RTL838X_SDS4_FIB_REG0 (0xF800) - -/* Default MTU with jumbo frames support */ -#define DEFAULT_MTU 9000 - -inline int rtl838x_mac_port_ctrl(int p) -{ - return RTL838X_MAC_PORT_CTRL + (p << 7); -} - -inline int rtl839x_mac_port_ctrl(int p) -{ - return RTL839X_MAC_PORT_CTRL + (p << 7); -} - -/* On the RTL931XX, the functionality of the MAC port control register is split up - * into RTL931X_MAC_L2_PORT_CTRL and RTL931X_MAC_PORT_CTRL the functionality used - * by the Ethernet driver is in the same bits now in RTL931X_MAC_L2_PORT_CTRL - */ - -inline int rtl930x_mac_port_ctrl(int p) -{ - return RTL930X_MAC_L2_PORT_CTRL + (p << 6); -} - -inline int rtl931x_mac_port_ctrl(int p) -{ - return RTL931X_MAC_L2_PORT_CTRL + (p << 7); -} - -inline int rtl838x_dma_if_rx_ring_size(int i) -{ - return RTL838X_DMA_IF_RX_RING_SIZE + ((i >> 3) << 2); -} - -inline int rtl839x_dma_if_rx_ring_size(int i) -{ - return RTL839X_DMA_IF_RX_RING_SIZE + ((i >> 3) << 2); -} - -inline int rtl930x_dma_if_rx_ring_size(int i) -{ - return RTL930X_DMA_IF_RX_RING_SIZE + ((i / 3) << 2); -} - -inline int rtl931x_dma_if_rx_ring_size(int i) -{ - return RTL931X_DMA_IF_RX_RING_SIZE + ((i / 3) << 2); -} - -inline int rtl838x_dma_if_rx_ring_cntr(int i) -{ - return RTL838X_DMA_IF_RX_RING_CNTR + ((i >> 3) << 2); -} - -inline int rtl839x_dma_if_rx_ring_cntr(int i) -{ - return RTL839X_DMA_IF_RX_RING_CNTR + ((i >> 3) << 2); -} - -inline int rtl930x_dma_if_rx_ring_cntr(int i) -{ - return RTL930X_DMA_IF_RX_RING_CNTR + ((i / 3) << 2); -} - -inline int rtl931x_dma_if_rx_ring_cntr(int i) -{ - return RTL931X_DMA_IF_RX_RING_CNTR + ((i / 3) << 2); -} - -inline u32 rtl838x_get_mac_link_sts(int port) -{ - return (sw_r32(RTL838X_MAC_LINK_STS) & BIT(port)); -} - -inline u32 rtl839x_get_mac_link_sts(int p) -{ - return (sw_r32(RTL839X_MAC_LINK_STS + ((p >> 5) << 2)) & BIT(p % 32)); -} - -inline u32 rtl930x_get_mac_link_sts(int port) -{ - u32 link = sw_r32(RTL930X_MAC_LINK_STS); - - link = sw_r32(RTL930X_MAC_LINK_STS); - pr_info("%s link state is %08x\n", __func__, link); - return link & BIT(port); -} - -inline u32 rtl931x_get_mac_link_sts(int p) -{ - return (sw_r32(RTL931X_MAC_LINK_STS + ((p >> 5) << 2)) & BIT(p % 32)); -} - -inline u32 rtl838x_get_mac_link_dup_sts(int port) -{ - return (sw_r32(RTL838X_MAC_LINK_DUP_STS) & BIT(port)); -} - -inline u32 rtl839x_get_mac_link_dup_sts(int p) -{ - return (sw_r32(RTL839X_MAC_LINK_DUP_STS + ((p >> 5) << 2)) & BIT(p % 32)); -} - -inline u32 rtl930x_get_mac_link_dup_sts(int port) -{ - return (sw_r32(RTL930X_MAC_LINK_DUP_STS) & BIT(port)); -} - -inline u32 rtl931x_get_mac_link_dup_sts(int p) -{ - return (sw_r32(RTL931X_MAC_LINK_DUP_STS + ((p >> 5) << 2)) & BIT(p % 32)); -} - -inline u32 rtl838x_get_mac_link_spd_sts(int port) -{ - int r = RTL838X_MAC_LINK_SPD_STS + ((port >> 4) << 2); - u32 speed = sw_r32(r); - - speed >>= (port % 16) << 1; - return (speed & 0x3); -} - -inline u32 rtl839x_get_mac_link_spd_sts(int port) -{ - int r = RTL839X_MAC_LINK_SPD_STS + ((port >> 4) << 2); - u32 speed = sw_r32(r); - - speed >>= (port % 16) << 1; - return (speed & 0x3); -} - - -inline u32 rtl930x_get_mac_link_spd_sts(int port) -{ - int r = RTL930X_MAC_LINK_SPD_STS + ((port >> 3) << 2); - u32 speed = sw_r32(r); - - speed >>= (port % 8) << 2; - return (speed & 0xf); -} - -inline u32 rtl931x_get_mac_link_spd_sts(int port) -{ - int r = RTL931X_MAC_LINK_SPD_STS + ((port >> 3) << 2); - u32 speed = sw_r32(r); - - speed >>= (port % 8) << 2; - return (speed & 0xf); -} - -inline u32 rtl838x_get_mac_rx_pause_sts(int port) -{ - return (sw_r32(RTL838X_MAC_RX_PAUSE_STS) & (1 << port)); -} - -inline u32 rtl839x_get_mac_rx_pause_sts(int p) -{ - return (sw_r32(RTL839X_MAC_RX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32)); -} - -inline u32 rtl930x_get_mac_rx_pause_sts(int port) -{ - return (sw_r32(RTL930X_MAC_RX_PAUSE_STS) & (1 << port)); -} - -inline u32 rtl931x_get_mac_rx_pause_sts(int p) -{ - return (sw_r32(RTL931X_MAC_RX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32)); -} - -inline u32 rtl838x_get_mac_tx_pause_sts(int port) -{ - return (sw_r32(RTL838X_MAC_TX_PAUSE_STS) & (1 << port)); -} - -inline u32 rtl839x_get_mac_tx_pause_sts(int p) -{ - return (sw_r32(RTL839X_MAC_TX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32)); -} - -inline u32 rtl930x_get_mac_tx_pause_sts(int port) -{ - return (sw_r32(RTL930X_MAC_TX_PAUSE_STS) & (1 << port)); -} - -inline u32 rtl931x_get_mac_tx_pause_sts(int p) -{ - return (sw_r32(RTL931X_MAC_TX_PAUSE_STS + ((p >> 5) << 2)) & BIT(p % 32)); -} - -struct p_hdr; -struct dsa_tag; - -struct rtl838x_bus_priv { - struct rtl838x_eth_priv *eth_priv; - int extaddr; - int rawpage; - int page[64]; - bool raw[64]; - int (*read_mmd_phy)(u32 port, u32 addr, u32 reg, u32 *val); - int (*write_mmd_phy)(u32 port, u32 addr, u32 reg, u32 val); - int (*read_phy)(u32 port, u32 page, u32 reg, u32 *val); - int (*write_phy)(u32 port, u32 page, u32 reg, u32 val); -}; - -struct rtl838x_eth_reg { - irqreturn_t (*net_irq)(int irq, void *dev_id); - int (*mac_port_ctrl)(int port); - int dma_if_intr_sts; - int dma_if_intr_msk; - int dma_if_intr_rx_runout_sts; - int dma_if_intr_rx_done_sts; - int dma_if_intr_tx_done_sts; - int dma_if_intr_rx_runout_msk; - int dma_if_intr_rx_done_msk; - int dma_if_intr_tx_done_msk; - int l2_ntfy_if_intr_sts; - int l2_ntfy_if_intr_msk; - int dma_if_ctrl; - int mac_force_mode_ctrl; - int dma_rx_base; - int dma_tx_base; - int (*dma_if_rx_ring_size)(int ring); - int (*dma_if_rx_ring_cntr)(int ring); - int dma_if_rx_cur; - int rst_glb_ctrl; - u32 (*get_mac_link_sts)(int port); - u32 (*get_mac_link_dup_sts)(int port); - u32 (*get_mac_link_spd_sts)(int port); - u32 (*get_mac_rx_pause_sts)(int port); - u32 (*get_mac_tx_pause_sts)(int port); - int mac; - int l2_tbl_flush_ctrl; - void (*update_cntr)(int r, int work_done); - void (*create_tx_header)(struct p_hdr *h, unsigned int dest_port, int prio); - bool (*decode_tag)(struct p_hdr *h, struct dsa_tag *tag); -}; - -int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val); -int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val); -int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val); -int rtl838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val); -int rtl839x_write_phy(u32 port, u32 page, u32 reg, u32 val); -int rtl839x_read_phy(u32 port, u32 page, u32 reg, u32 *val); -int rtl839x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val); -int rtl839x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val); -int rtl930x_write_phy(u32 port, u32 page, u32 reg, u32 val); -int rtl930x_read_phy(u32 port, u32 page, u32 reg, u32 *val); -int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val); -int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val); -int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data); - -#endif /* _RTL838X_ETH_H */ diff --git a/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.c deleted file mode 100644 index df5e2e444067ab..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.c +++ /dev/null @@ -1,4001 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* Realtek RTL838X Ethernet MDIO interface driver - * - * Copyright (C) 2020 B. Koblitz - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "rtl83xx-phy.h" - -extern struct rtl83xx_soc_info soc_info; -extern struct mutex smi_lock; -extern int phy_package_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val); -extern int phy_package_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val); -extern int phy_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val); -extern int phy_package_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum); -extern int phy_package_read_paged(struct phy_device *phydev, int page, u32 regnum); -extern int phy_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum); - -#define PHY_PAGE_2 2 -#define PHY_PAGE_4 4 - -/* all Clause-22 RealTek MDIO PHYs use register 0x1f for page select */ -#define RTL8XXX_PAGE_SELECT 0x1f - -#define RTL8XXX_PAGE_MAIN 0x0000 -#define RTL821X_PAGE_PORT 0x0266 -#define RTL821X_PAGE_POWER 0x0a40 -#define RTL821X_PAGE_GPHY 0x0a42 -#define RTL821X_PAGE_MAC 0x0a43 -#define RTL821X_PAGE_STATE 0x0b80 -#define RTL821X_PAGE_PATCH 0x0b82 - -/* Using the special page 0xfff with the MDIO controller found in - * RealTek SoCs allows to access the PHY in RAW mode, ie. bypassing - * the cache and paging engine of the MDIO controller. - */ -#define RTL83XX_PAGE_RAW 0x0fff - -/* internal RTL821X PHY uses register 0x1d to select media page */ -#define RTL821XINT_MEDIA_PAGE_SELECT 0x1d -/* external RTL821X PHY uses register 0x1e to select media page */ -#define RTL821XEXT_MEDIA_PAGE_SELECT 0x1e - -#define RTL821X_CHIP_ID 0x6276 - -#define RTL821X_MEDIA_PAGE_AUTO 0 -#define RTL821X_MEDIA_PAGE_COPPER 1 -#define RTL821X_MEDIA_PAGE_FIBRE 3 -#define RTL821X_MEDIA_PAGE_INTERNAL 8 - -#define RTL9300_PHY_ID_MASK 0xf0ffffff - -/* RTL930X SerDes supports the following modes: - * 0x02: SGMII 0x04: 1000BX_FIBER 0x05: FIBER100 - * 0x06: QSGMII 0x09: RSGMII 0x0d: USXGMII - * 0x10: XSGMII 0x12: HISGMII 0x16: 2500Base_X - * 0x17: RXAUI_LITE 0x19: RXAUI_PLUS 0x1a: 10G Base-R - * 0x1b: 10GR1000BX_AUTO 0x1f: OFF - */ -#define RTL930X_SDS_MODE_SGMII 0x02 -#define RTL930X_SDS_MODE_1000BASEX 0x04 -#define RTL930X_SDS_MODE_USXGMII 0x0d -#define RTL930X_SDS_MODE_XGMII 0x10 -#define RTL930X_SDS_MODE_HSGMII 0x12 -#define RTL930X_SDS_MODE_2500BASEX 0x16 -#define RTL930X_SDS_MODE_10GBASER 0x1a -#define RTL930X_SDS_OFF 0x1f -#define RTL930X_SDS_MASK 0x1f - -/* This lock protects the state of the SoC automatically polling the PHYs over the SMI - * bus to detect e.g. link and media changes. For operations on the PHYs such as - * patching or other configuration changes such as EEE, polling needs to be disabled - * since otherwise these operations may fails or lead to unpredictable results. - */ -DEFINE_MUTEX(poll_lock); - -static const struct firmware rtl838x_8380_fw; -static const struct firmware rtl838x_8214fc_fw; -static const struct firmware rtl838x_8218b_fw; - -static u64 disable_polling(int port) -{ - u64 saved_state; - - mutex_lock(&poll_lock); - - switch (soc_info.family) { - case RTL8380_FAMILY_ID: - saved_state = sw_r32(RTL838X_SMI_POLL_CTRL); - sw_w32_mask(BIT(port), 0, RTL838X_SMI_POLL_CTRL); - break; - case RTL8390_FAMILY_ID: - saved_state = sw_r32(RTL839X_SMI_PORT_POLLING_CTRL + 4); - saved_state <<= 32; - saved_state |= sw_r32(RTL839X_SMI_PORT_POLLING_CTRL); - sw_w32_mask(BIT(port % 32), 0, - RTL839X_SMI_PORT_POLLING_CTRL + ((port >> 5) << 2)); - break; - case RTL9300_FAMILY_ID: - saved_state = sw_r32(RTL930X_SMI_POLL_CTRL); - sw_w32_mask(BIT(port), 0, RTL930X_SMI_POLL_CTRL); - break; - case RTL9310_FAMILY_ID: - pr_warn("%s not implemented for RTL931X\n", __func__); - break; - } - - mutex_unlock(&poll_lock); - - return saved_state; -} - -static int resume_polling(u64 saved_state) -{ - mutex_lock(&poll_lock); - - switch (soc_info.family) { - case RTL8380_FAMILY_ID: - sw_w32(saved_state, RTL838X_SMI_POLL_CTRL); - break; - case RTL8390_FAMILY_ID: - sw_w32(saved_state >> 32, RTL839X_SMI_PORT_POLLING_CTRL + 4); - sw_w32(saved_state, RTL839X_SMI_PORT_POLLING_CTRL); - break; - case RTL9300_FAMILY_ID: - sw_w32(saved_state, RTL930X_SMI_POLL_CTRL); - break; - case RTL9310_FAMILY_ID: - pr_warn("%s not implemented for RTL931X\n", __func__); - break; - } - - mutex_unlock(&poll_lock); - - return 0; -} - -static void rtl8380_int_phy_on_off(struct phy_device *phydev, bool on) -{ - phy_modify(phydev, 0, BMCR_PDOWN, on ? 0 : BMCR_PDOWN); -} - -static void rtl8380_rtl8214fc_on_off(struct phy_device *phydev, bool on) -{ - /* fiber ports */ - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_FIBRE); - phy_modify(phydev, 0x10, BMCR_PDOWN, on ? 0 : BMCR_PDOWN); - - /* copper ports */ - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER); - phy_modify_paged(phydev, RTL821X_PAGE_POWER, 0x10, BMCR_PDOWN, on ? 0 : BMCR_PDOWN); -} - -static void rtl8380_phy_reset(struct phy_device *phydev) -{ - phy_modify(phydev, 0, BMCR_RESET, BMCR_RESET); -} - -/* The access registers for SDS_MODE_SEL and the LSB for each SDS within */ -u16 rtl9300_sds_regs[] = { 0x0194, 0x0194, 0x0194, 0x0194, 0x02a0, 0x02a0, 0x02a0, 0x02a0, - 0x02A4, 0x02A4, 0x0198, 0x0198 }; -u8 rtl9300_sds_lsb[] = { 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 0, 6}; - -/* Reset the SerDes by powering it off and set a new operation mode - * of the SerDes. - */ -void rtl9300_sds_rst(int sds_num, u32 mode) -{ - pr_info("%s %d\n", __func__, mode); - if (sds_num < 0 || sds_num > 11) { - pr_err("Wrong SerDes number: %d\n", sds_num); - return; - } - - sw_w32_mask(RTL930X_SDS_MASK << rtl9300_sds_lsb[sds_num], - RTL930X_SDS_OFF << rtl9300_sds_lsb[sds_num], - rtl9300_sds_regs[sds_num]); - mdelay(10); - - sw_w32_mask(RTL930X_SDS_MASK << rtl9300_sds_lsb[sds_num], mode << rtl9300_sds_lsb[sds_num], - rtl9300_sds_regs[sds_num]); - mdelay(10); - - pr_debug("%s: 194:%08x 198:%08x 2a0:%08x 2a4:%08x\n", __func__, - sw_r32(0x194), sw_r32(0x198), sw_r32(0x2a0), sw_r32(0x2a4)); -} - -void rtl9300_sds_set(int sds_num, u32 mode) -{ - pr_info("%s %d\n", __func__, mode); - if (sds_num < 0 || sds_num > 11) { - pr_err("Wrong SerDes number: %d\n", sds_num); - return; - } - - sw_w32_mask(RTL930X_SDS_MASK << rtl9300_sds_lsb[sds_num], mode << rtl9300_sds_lsb[sds_num], - rtl9300_sds_regs[sds_num]); - mdelay(10); - - pr_debug("%s: 194:%08x 198:%08x 2a0:%08x 2a4:%08x\n", __func__, - sw_r32(0x194), sw_r32(0x198), sw_r32(0x2a0), sw_r32(0x2a4)); -} - -u32 rtl9300_sds_mode_get(int sds_num) -{ - u32 v; - - if (sds_num < 0 || sds_num > 11) { - pr_err("Wrong SerDes number: %d\n", sds_num); - return 0; - } - - v = sw_r32(rtl9300_sds_regs[sds_num]); - v >>= rtl9300_sds_lsb[sds_num]; - - return v & RTL930X_SDS_MASK; -} - -/* On the RTL839x family of SoCs with inbuilt SerDes, these SerDes are accessed through - * a 2048 bit register that holds the contents of the PHY being simulated by the SoC. - */ -int rtl839x_read_sds_phy(int phy_addr, int phy_reg) -{ - int offset = 0; - int reg; - u32 val; - - if (phy_addr == 49) - offset = 0x100; - - /* For the RTL8393 internal SerDes, we simulate a PHY ID in registers 2/3 - * which would otherwise read as 0. - */ - if (soc_info.id == 0x8393) { - if (phy_reg == MII_PHYSID1) - return 0x1c; - if (phy_reg == MII_PHYSID2) - return 0x8393; - } - - /* Register RTL839X_SDS12_13_XSG0 is 2048 bit broad, the MSB (bit 15) of the - * 0th PHY register is bit 1023 (in byte 0x80). Because PHY-registers are 16 - * bit broad, we offset by reg << 1. In the SoC 2 registers are stored in - * one 32 bit register. - */ - reg = (phy_reg << 1) & 0xfc; - val = sw_r32(RTL839X_SDS12_13_XSG0 + offset + 0x80 + reg); - - if (phy_reg & 1) - val = (val >> 16) & 0xffff; - else - val &= 0xffff; - - return val; -} - -/* On the RTL930x family of SoCs, the internal SerDes are accessed through an IO - * register which simulates commands to an internal MDIO bus. - */ -int rtl930x_read_sds_phy(int phy_addr, int page, int phy_reg) -{ - int i; - u32 cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 1; - - sw_w32(cmd, RTL930X_SDS_INDACS_CMD); - - for (i = 0; i < 100; i++) { - if (!(sw_r32(RTL930X_SDS_INDACS_CMD) & 0x1)) - break; - mdelay(1); - } - - if (i >= 100) - return -EIO; - - return sw_r32(RTL930X_SDS_INDACS_DATA) & 0xffff; -} - -int rtl930x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v) -{ - int i; - u32 cmd; - - sw_w32(v, RTL930X_SDS_INDACS_DATA); - cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 0x3; - - sw_w32(cmd, RTL930X_SDS_INDACS_CMD); - - for (i = 0; i < 100; i++) { - if (!(sw_r32(RTL930X_SDS_INDACS_CMD) & 0x1)) - break; - mdelay(1); - } - - - if (i >= 100) { - pr_info("%s ERROR !!!!!!!!!!!!!!!!!!!!\n", __func__); - return -EIO; - } - - return 0; -} - -int rtl931x_read_sds_phy(int phy_addr, int page, int phy_reg) -{ - int i; - u32 cmd = phy_addr << 2 | page << 7 | phy_reg << 13 | 1; - - pr_debug("%s: phy_addr(SDS-ID) %d, phy_reg: %d\n", __func__, phy_addr, phy_reg); - sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL); - - for (i = 0; i < 100; i++) { - if (!(sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) & 0x1)) - break; - mdelay(1); - } - - if (i >= 100) - return -EIO; - - pr_debug("%s: returning %04x\n", __func__, sw_r32(RTL931X_SERDES_INDRT_DATA_CTRL) & 0xffff); - - return sw_r32(RTL931X_SERDES_INDRT_DATA_CTRL) & 0xffff; -} - -int rtl931x_write_sds_phy(int phy_addr, int page, int phy_reg, u16 v) -{ - int i; - u32 cmd; - - cmd = phy_addr << 2 | page << 7 | phy_reg << 13; - sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL); - - sw_w32(v, RTL931X_SERDES_INDRT_DATA_CTRL); - - cmd = sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) | 0x3; - sw_w32(cmd, RTL931X_SERDES_INDRT_ACCESS_CTRL); - - for (i = 0; i < 100; i++) { - if (!(sw_r32(RTL931X_SERDES_INDRT_ACCESS_CTRL) & 0x1)) - break; - mdelay(1); - } - - if (i >= 100) - return -EIO; - - return 0; -} - -/* On the RTL838x SoCs, the internal SerDes is accessed through direct access to - * standard PHY registers, where a 32 bit register holds a 16 bit word as found - * in a standard page 0 of a PHY - */ -int rtl838x_read_sds_phy(int phy_addr, int phy_reg) -{ - int offset = 0; - u32 val; - - if (phy_addr == 26) - offset = 0x100; - val = sw_r32(RTL838X_SDS4_FIB_REG0 + offset + (phy_reg << 2)) & 0xffff; - - return val; -} - -int rtl839x_write_sds_phy(int phy_addr, int phy_reg, u16 v) -{ - int offset = 0; - int reg; - u32 val; - - if (phy_addr == 49) - offset = 0x100; - - reg = (phy_reg << 1) & 0xfc; - val = v; - if (phy_reg & 1) { - val = val << 16; - sw_w32_mask(0xffff0000, val, - RTL839X_SDS12_13_XSG0 + offset + 0x80 + reg); - } else { - sw_w32_mask(0xffff, val, - RTL839X_SDS12_13_XSG0 + offset + 0x80 + reg); - } - - return 0; -} - -/* Read the link and speed status of the 2 internal SGMII/1000Base-X - * ports of the RTL838x SoCs - */ -static int rtl8380_read_status(struct phy_device *phydev) -{ - int err; - - err = genphy_read_status(phydev); - - if (phydev->link) { - phydev->speed = SPEED_1000; - phydev->duplex = DUPLEX_FULL; - } - - return err; -} - -/* Read the link and speed status of the 2 internal SGMII/1000Base-X - * ports of the RTL8393 SoC - */ -static int rtl8393_read_status(struct phy_device *phydev) -{ - int offset = 0; - int err; - int phy_addr = phydev->mdio.addr; - u32 v; - - err = genphy_read_status(phydev); - if (phy_addr == 49) - offset = 0x100; - - if (phydev->link) { - phydev->speed = SPEED_100; - /* Read SPD_RD_00 (bit 13) and SPD_RD_01 (bit 6) out of the internal - * PHY registers - */ - v = sw_r32(RTL839X_SDS12_13_XSG0 + offset + 0x80); - if (!(v & (1 << 13)) && (v & (1 << 6))) - phydev->speed = SPEED_1000; - phydev->duplex = DUPLEX_FULL; - } - - return err; -} - -static int rtl821x_read_page(struct phy_device *phydev) -{ - return __phy_read(phydev, RTL8XXX_PAGE_SELECT); -} - -static int rtl821x_write_page(struct phy_device *phydev, int page) -{ - return __phy_write(phydev, RTL8XXX_PAGE_SELECT, page); -} - -static int rtl8226_read_status(struct phy_device *phydev) -{ - int ret = 0; - u32 val; - -/* TODO: ret = genphy_read_status(phydev); - * if (ret < 0) { - * pr_info("%s: genphy_read_status failed\n", __func__); - * return ret; - * } - */ - - /* Link status must be read twice */ - for (int i = 0; i < 2; i++) - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA402); - - phydev->link = val & BIT(2) ? 1 : 0; - if (!phydev->link) - goto out; - - /* Read duplex status */ - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA434); - if (val < 0) - goto out; - phydev->duplex = !!(val & BIT(3)); - - /* Read speed */ - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA434); - switch (val & 0x0630) { - case 0x0000: - phydev->speed = SPEED_10; - break; - case 0x0010: - phydev->speed = SPEED_100; - break; - case 0x0020: - phydev->speed = SPEED_1000; - break; - case 0x0200: - phydev->speed = SPEED_10000; - break; - case 0x0210: - phydev->speed = SPEED_2500; - break; - case 0x0220: - phydev->speed = SPEED_5000; - break; - default: - break; - } - -out: - return ret; -} - -static int rtl8226_advertise_aneg(struct phy_device *phydev) -{ - int ret = 0; - u32 v; - - pr_info("In %s\n", __func__); - - v = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE); - if (v < 0) - goto out; - - v |= ADVERTISE_10HALF; - v |= ADVERTISE_10FULL; - v |= ADVERTISE_100HALF; - v |= ADVERTISE_100FULL; - - ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, v); - - /* Allow 1GBit */ - v = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA412); - if (v < 0) - goto out; - v |= ADVERTISE_1000FULL; - - ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xA412, v); - if (ret < 0) - goto out; - - /* Allow 2.5G */ - v = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL); - if (v < 0) - goto out; - - v |= MDIO_AN_10GBT_CTRL_ADV2_5G; - ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, v); - -out: - return ret; -} - -static int rtl8226_config_aneg(struct phy_device *phydev) -{ - int ret = 0; - u32 v; - - pr_debug("In %s\n", __func__); - if (phydev->autoneg == AUTONEG_ENABLE) { - ret = rtl8226_advertise_aneg(phydev); - if (ret) - goto out; - /* AutoNegotiationEnable */ - v = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1); - if (v < 0) - goto out; - - v |= MDIO_AN_CTRL1_ENABLE; /* Enable AN */ - ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1, v); - if (ret < 0) - goto out; - - /* RestartAutoNegotiation */ - v = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA400); - if (v < 0) - goto out; - v |= MDIO_AN_CTRL1_RESTART; - - ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xA400, v); - } - -/* TODO: ret = __genphy_config_aneg(phydev, ret); */ - -out: - return ret; -} - -static int rtl8226_get_eee(struct phy_device *phydev, - struct ethtool_eee *e) -{ - u32 val; - int addr = phydev->mdio.addr; - - pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled); - - val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); - if (e->eee_enabled) { - e->eee_enabled = !!(val & MDIO_EEE_100TX); - if (!e->eee_enabled) { - val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2); - e->eee_enabled = !!(val & MDIO_EEE_2_5GT); - } - } - pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled); - - return 0; -} - -static int rtl8226_set_eee(struct phy_device *phydev, struct ethtool_eee *e) -{ - int port = phydev->mdio.addr; - u64 poll_state; - bool an_enabled; - u32 val; - - pr_info("In %s, port %d, enabled %d\n", __func__, port, e->eee_enabled); - - poll_state = disable_polling(port); - - /* Remember aneg state */ - val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_CTRL1); - an_enabled = !!(val & MDIO_AN_CTRL1_ENABLE); - - /* Setup 100/1000MBit */ - val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); - if (e->eee_enabled) - val |= (MDIO_EEE_100TX | MDIO_EEE_1000T); - else - val &= (MDIO_EEE_100TX | MDIO_EEE_1000T); - phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val); - - /* Setup 2.5GBit */ - val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2); - if (e->eee_enabled) - val |= MDIO_EEE_2_5GT; - else - val &= MDIO_EEE_2_5GT; - phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV2, val); - - /* RestartAutoNegotiation */ - val = phy_read_mmd(phydev, MDIO_MMD_VEND2, 0xA400); - val |= MDIO_AN_CTRL1_RESTART; - phy_write_mmd(phydev, MDIO_MMD_VEND2, 0xA400, val); - - resume_polling(poll_state); - - return 0; -} - -static struct fw_header *rtl838x_request_fw(struct phy_device *phydev, - const struct firmware *fw, - const char *name) -{ - struct device *dev = &phydev->mdio.dev; - int err; - struct fw_header *h; - uint32_t checksum, my_checksum; - - err = request_firmware(&fw, name, dev); - if (err < 0) - goto out; - - if (fw->size < sizeof(struct fw_header)) { - pr_err("Firmware size too small.\n"); - err = -EINVAL; - goto out; - } - - h = (struct fw_header *) fw->data; - pr_info("Firmware loaded. Size %d, magic: %08x\n", fw->size, h->magic); - - if (h->magic != 0x83808380) { - pr_err("Wrong firmware file: MAGIC mismatch.\n"); - goto out; - } - - checksum = h->checksum; - h->checksum = 0; - my_checksum = ~crc32(0xFFFFFFFFU, fw->data, fw->size); - if (checksum != my_checksum) { - pr_err("Firmware checksum mismatch.\n"); - err = -EINVAL; - goto out; - } - h->checksum = checksum; - - return h; -out: - dev_err(dev, "Unable to load firmware %s (%d)\n", name, err); - return NULL; -} - -static void rtl821x_phy_setup_package_broadcast(struct phy_device *phydev, bool enable) -{ - int mac = phydev->mdio.addr; - - /* select main page 0 */ - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN); - /* write to 0x8 to register 0x1d on main page 0 */ - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL); - /* select page 0x266 */ - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PORT); - /* set phy id and target broadcast bitmap in register 0x16 on page 0x266 */ - phy_write_paged(phydev, RTL83XX_PAGE_RAW, 0x16, (enable?0xff00:0x00) | mac); - /* return to main page 0 */ - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN); - /* write to 0x0 to register 0x1d on main page 0 */ - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); - mdelay(1); -} - -static int rtl8390_configure_generic(struct phy_device *phydev) -{ - int mac = phydev->mdio.addr; - u32 val, phy_id; - - val = phy_read(phydev, 2); - phy_id = val << 16; - val = phy_read(phydev, 3); - phy_id |= val; - pr_debug("Phy on MAC %d: %x\n", mac, phy_id); - - /* Read internal PHY ID */ - phy_write_paged(phydev, 31, 27, 0x0002); - val = phy_read_paged(phydev, 31, 28); - - /* Internal RTL8218B, version 2 */ - phydev_info(phydev, "Detected unknown %x\n", val); - - return 0; -} - -static int rtl8380_configure_int_rtl8218b(struct phy_device *phydev) -{ - u32 val, phy_id; - int mac = phydev->mdio.addr; - struct fw_header *h; - u32 *rtl838x_6275B_intPhy_perport; - u32 *rtl8218b_6276B_hwEsd_perport; - - val = phy_read(phydev, 2); - phy_id = val << 16; - val = phy_read(phydev, 3); - phy_id |= val; - pr_debug("Phy on MAC %d: %x\n", mac, phy_id); - - /* Read internal PHY ID */ - phy_write_paged(phydev, 31, 27, 0x0002); - val = phy_read_paged(phydev, 31, 28); - if (val != 0x6275) { - phydev_err(phydev, "Expected internal RTL8218B, found PHY-ID %x\n", val); - return -1; - } - - /* Internal RTL8218B, version 2 */ - phydev_info(phydev, "Detected internal RTL8218B\n"); - - h = rtl838x_request_fw(phydev, &rtl838x_8380_fw, FIRMWARE_838X_8380_1); - if (!h) - return -1; - - if (h->phy != 0x83800000) { - phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n"); - return -1; - } - - rtl838x_6275B_intPhy_perport = (void *)h + sizeof(struct fw_header) + h->parts[8].start; - rtl8218b_6276B_hwEsd_perport = (void *)h + sizeof(struct fw_header) + h->parts[9].start; - - // Currently not used - // if (sw_r32(RTL838X_DMY_REG31) == 0x1) { - // int ipd_flag = 1; - // } - - val = phy_read(phydev, MII_BMCR); - if (val & BMCR_PDOWN) - rtl8380_int_phy_on_off(phydev, true); - else - rtl8380_phy_reset(phydev); - msleep(100); - - /* Ready PHY for patch */ - for (int p = 0; p < 8; p++) { - phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH); - phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW, 0x10, 0x0010); - } - msleep(500); - for (int p = 0; p < 8; p++) { - int i; - - for (i = 0; i < 100 ; i++) { - val = phy_package_port_read_paged(phydev, p, RTL821X_PAGE_STATE, 0x10); - if (val & 0x40) - break; - } - if (i >= 100) { - phydev_err(phydev, - "ERROR: Port %d not ready for patch.\n", - mac + p); - return -1; - } - } - for (int p = 0; p < 8; p++) { - int i; - - i = 0; - while (rtl838x_6275B_intPhy_perport[i * 2]) { - phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW, - rtl838x_6275B_intPhy_perport[i * 2], - rtl838x_6275B_intPhy_perport[i * 2 + 1]); - i++; - } - i = 0; - while (rtl8218b_6276B_hwEsd_perport[i * 2]) { - phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW, - rtl8218b_6276B_hwEsd_perport[i * 2], - rtl8218b_6276B_hwEsd_perport[i * 2 + 1]); - i++; - } - } - - return 0; -} - -static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev) -{ - u32 val, ipd, phy_id; - int mac = phydev->mdio.addr; - struct fw_header *h; - u32 *rtl8380_rtl8218b_perchip; - u32 *rtl8218B_6276B_rtl8380_perport; - u32 *rtl8380_rtl8218b_perport; - - if (soc_info.family == RTL8380_FAMILY_ID && mac != 0 && mac != 16) { - phydev_err(phydev, "External RTL8218B must have PHY-IDs 0 or 16!\n"); - return -1; - } - val = phy_read(phydev, 2); - phy_id = val << 16; - val = phy_read(phydev, 3); - phy_id |= val; - pr_info("Phy on MAC %d: %x\n", mac, phy_id); - - /* Read internal PHY ID */ - phy_write_paged(phydev, 31, 27, 0x0002); - val = phy_read_paged(phydev, 31, 28); - if (val != RTL821X_CHIP_ID) { - phydev_err(phydev, "Expected external RTL8218B, found PHY-ID %x\n", val); - return -1; - } - phydev_info(phydev, "Detected external RTL8218B\n"); - - h = rtl838x_request_fw(phydev, &rtl838x_8218b_fw, FIRMWARE_838X_8218b_1); - if (!h) - return -1; - - if (h->phy != 0x8218b000) { - phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n"); - return -1; - } - - rtl8380_rtl8218b_perchip = (void *)h + sizeof(struct fw_header) + h->parts[0].start; - rtl8218B_6276B_rtl8380_perport = (void *)h + sizeof(struct fw_header) + h->parts[1].start; - rtl8380_rtl8218b_perport = (void *)h + sizeof(struct fw_header) + h->parts[2].start; - - val = phy_read(phydev, MII_BMCR); - if (val & BMCR_PDOWN) - rtl8380_int_phy_on_off(phydev, true); - else - rtl8380_phy_reset(phydev); - - msleep(100); - - /* Get Chip revision */ - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN); - phy_write_paged(phydev, RTL83XX_PAGE_RAW, 0x1b, 0x4); - val = phy_read_paged(phydev, RTL83XX_PAGE_RAW, 0x1c); - - phydev_info(phydev, "Detected chip revision %04x\n", val); - - for (int i = 0; rtl8380_rtl8218b_perchip[i * 3] && - rtl8380_rtl8218b_perchip[i * 3 + 1]; i++) { - phy_package_port_write_paged(phydev, rtl8380_rtl8218b_perchip[i * 3], - RTL83XX_PAGE_RAW, rtl8380_rtl8218b_perchip[i * 3 + 1], - rtl8380_rtl8218b_perchip[i * 3 + 2]); - } - - /* Enable PHY */ - for (int i = 0; i < 8; i++) { - phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN); - phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x00, 0x1140); - } - mdelay(100); - - /* Request patch */ - for (int i = 0; i < 8; i++) { - phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH); - phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x10, 0x0010); - } - - mdelay(300); - - /* Verify patch readiness */ - for (int i = 0; i < 8; i++) { - int l; - - for (l = 0; l < 100; l++) { - val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_STATE, 0x10); - if (val & 0x40) - break; - } - if (l >= 100) { - phydev_err(phydev, "Could not patch PHY\n"); - return -1; - } - } - - /* Use Broadcast ID method for patching */ - rtl821x_phy_setup_package_broadcast(phydev, true); - - phy_write_paged(phydev, RTL83XX_PAGE_RAW, 30, 8); - phy_write_paged(phydev, 0x26e, 17, 0xb); - phy_write_paged(phydev, 0x26e, 16, 0x2); - mdelay(1); - ipd = phy_read_paged(phydev, 0x26e, 19); - phy_write_paged(phydev, 0, 30, 0); - ipd = (ipd >> 4) & 0xf; /* unused ? */ - - for (int i = 0; rtl8218B_6276B_rtl8380_perport[i * 2]; i++) { - phy_write_paged(phydev, RTL83XX_PAGE_RAW, rtl8218B_6276B_rtl8380_perport[i * 2], - rtl8218B_6276B_rtl8380_perport[i * 2 + 1]); - } - - /* Disable broadcast ID */ - rtl821x_phy_setup_package_broadcast(phydev, false); - - return 0; -} - -static int rtl8218b_ext_match_phy_device(struct phy_device *phydev) -{ - int addr = phydev->mdio.addr; - - /* Both the RTL8214FC and the external RTL8218B have the same - * PHY ID. On the RTL838x, the RTL8218B can only be attached_dev - * at PHY IDs 0-7, while the RTL8214FC must be attached via - * the pair of SGMII/1000Base-X with higher PHY-IDs - */ - if (soc_info.family == RTL8380_FAMILY_ID) - return phydev->phy_id == PHY_ID_RTL8218B_E && addr < 8; - else - return phydev->phy_id == PHY_ID_RTL8218B_E; -} - -static bool rtl8214fc_media_is_fibre(struct phy_device *phydev) -{ - int mac = phydev->mdio.addr; - - static int reg[] = {16, 19, 20, 21}; - u32 val; - - phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL); - val = phy_package_read_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4]); - phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); - - if (val & BMCR_PDOWN) - return false; - - return true; -} - -static void rtl8214fc_power_set(struct phy_device *phydev, int port, bool on) -{ - char *state = on ? "on" : "off"; - - if (port == PORT_FIBRE) { - pr_info("%s: Powering %s FIBRE (port %d)\n", __func__, state, phydev->mdio.addr); - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_FIBRE); - } else { - pr_info("%s: Powering %s COPPER (port %d)\n", __func__, state, phydev->mdio.addr); - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER); - } - - if (on) { - phy_modify_paged(phydev, RTL821X_PAGE_POWER, 0x10, BMCR_PDOWN, 0); - } else { - phy_modify_paged(phydev, RTL821X_PAGE_POWER, 0x10, 0, BMCR_PDOWN); - } - - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); -} - -static int rtl8214fc_suspend(struct phy_device *phydev) -{ - rtl8214fc_power_set(phydev, PORT_MII, false); - rtl8214fc_power_set(phydev, PORT_FIBRE, false); - - return 0; -} - -static int rtl8214fc_resume(struct phy_device *phydev) -{ - if (rtl8214fc_media_is_fibre(phydev)) { - rtl8214fc_power_set(phydev, PORT_MII, false); - rtl8214fc_power_set(phydev, PORT_FIBRE, true); - } else { - rtl8214fc_power_set(phydev, PORT_FIBRE, false); - rtl8214fc_power_set(phydev, PORT_MII, true); - } - - return 0; -} - -static void rtl8214fc_media_set(struct phy_device *phydev, bool set_fibre) -{ - int mac = phydev->mdio.addr; - - static int reg[] = {16, 19, 20, 21}; - int val; - - pr_info("%s: port %d, set_fibre: %d\n", __func__, mac, set_fibre); - phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL); - val = phy_package_read_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4]); - - val |= BIT(10); - if (set_fibre) { - val &= ~BMCR_PDOWN; - } else { - val |= BMCR_PDOWN; - } - - phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL); - phy_package_write_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4], val); - phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); - - if (!phydev->suspended) { - if (set_fibre) { - rtl8214fc_power_set(phydev, PORT_MII, false); - rtl8214fc_power_set(phydev, PORT_FIBRE, true); - } else { - rtl8214fc_power_set(phydev, PORT_FIBRE, false); - rtl8214fc_power_set(phydev, PORT_MII, true); - } - } -} - -static int rtl8214fc_set_port(struct phy_device *phydev, int port) -{ - bool is_fibre = (port == PORT_FIBRE ? true : false); - int addr = phydev->mdio.addr; - - pr_debug("%s port %d to %d\n", __func__, addr, port); - - rtl8214fc_media_set(phydev, is_fibre); - - return 0; -} - -static int rtl8214fc_get_port(struct phy_device *phydev) -{ - int addr = phydev->mdio.addr; - - pr_debug("%s: port %d\n", __func__, addr); - if (rtl8214fc_media_is_fibre(phydev)) - return PORT_FIBRE; - - return PORT_MII; -} - -/* Enable EEE on the RTL8218B PHYs - * The method used is not the preferred way (which would be based on the MAC-EEE state, - * but the only way that works since the kernel first enables EEE in the MAC - * and then sets up the PHY. The MAC-based approach would require the oppsite. - */ -void rtl8218d_eee_set(struct phy_device *phydev, bool enable) -{ - u32 val; - bool an_enabled; - - pr_debug("In %s %d, enable %d\n", __func__, phydev->mdio.addr, enable); - /* Set GPHY page to copper */ - phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER); - - val = phy_read(phydev, MII_BMCR); - an_enabled = val & BMCR_ANENABLE; - - val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); - val |= MDIO_EEE_1000T | MDIO_EEE_100TX; - phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, enable ? (MDIO_EEE_100TX | MDIO_EEE_1000T) : 0); - - /* 500M EEE ability */ - val = phy_read_paged(phydev, RTL821X_PAGE_GPHY, 20); - if (enable) - val |= BIT(7); - else - val &= ~BIT(7); - phy_write_paged(phydev, RTL821X_PAGE_GPHY, 20, val); - - /* Restart AN if enabled */ - if (an_enabled) { - val = phy_read(phydev, MII_BMCR); - val |= BMCR_ANRESTART; - phy_write(phydev, MII_BMCR, val); - } - - /* GPHY page back to auto */ - phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); -} - -static int rtl8218b_get_eee(struct phy_device *phydev, - struct ethtool_eee *e) -{ - u32 val; - int addr = phydev->mdio.addr; - - pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled); - - /* Set GPHY page to copper */ - phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER); - - val = phy_read_paged(phydev, 7, MDIO_AN_EEE_ADV); - if (e->eee_enabled) { - /* Verify vs MAC-based EEE */ - e->eee_enabled = !!(val & BIT(7)); - if (!e->eee_enabled) { - val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25); - e->eee_enabled = !!(val & BIT(4)); - } - } - pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled); - - /* GPHY page to auto */ - phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); - - return 0; -} - -static int rtl8218d_get_eee(struct phy_device *phydev, - struct ethtool_eee *e) -{ - u32 val; - int addr = phydev->mdio.addr; - - pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled); - - /* Set GPHY page to copper */ - phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER); - - val = phy_read_paged(phydev, 7, MDIO_AN_EEE_ADV); - if (e->eee_enabled) - e->eee_enabled = !!(val & BIT(7)); - pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled); - - /* GPHY page to auto */ - phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); - - return 0; -} - -static int rtl8214fc_set_eee(struct phy_device *phydev, - struct ethtool_eee *e) -{ - u32 poll_state; - int port = phydev->mdio.addr; - bool an_enabled; - u32 val; - - pr_debug("In %s port %d, enabled %d\n", __func__, port, e->eee_enabled); - - if (rtl8214fc_media_is_fibre(phydev)) { - netdev_err(phydev->attached_dev, "Port %d configured for FIBRE", port); - return -ENOTSUPP; - } - - poll_state = disable_polling(port); - - /* Set GPHY page to copper */ - phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER); - - /* Get auto-negotiation status */ - val = phy_read(phydev, MII_BMCR); - an_enabled = val & BMCR_ANENABLE; - - pr_info("%s: aneg: %d\n", __func__, an_enabled); - val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25); - val &= ~BIT(5); /* Use MAC-based EEE */ - phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val); - - /* Enable 100M (bit 1) / 1000M (bit 2) EEE */ - phy_write_paged(phydev, 7, MDIO_AN_EEE_ADV, e->eee_enabled ? (MDIO_EEE_100TX | MDIO_EEE_1000T) : 0); - - /* 500M EEE ability */ - val = phy_read_paged(phydev, RTL821X_PAGE_GPHY, 20); - if (e->eee_enabled) - val |= BIT(7); - else - val &= ~BIT(7); - - phy_write_paged(phydev, RTL821X_PAGE_GPHY, 20, val); - - /* Restart AN if enabled */ - if (an_enabled) { - pr_info("%s: doing aneg\n", __func__); - val = phy_read(phydev, MII_BMCR); - val |= BMCR_ANRESTART; - phy_write(phydev, MII_BMCR, val); - } - - /* GPHY page back to auto */ - phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); - - resume_polling(poll_state); - - return 0; -} - -static int rtl8214fc_get_eee(struct phy_device *phydev, - struct ethtool_eee *e) -{ - int addr = phydev->mdio.addr; - - pr_debug("In %s port %d, enabled %d\n", __func__, addr, e->eee_enabled); - if (rtl8214fc_media_is_fibre(phydev)) { - netdev_err(phydev->attached_dev, "Port %d configured for FIBRE", addr); - return -ENOTSUPP; - } - - return rtl8218b_get_eee(phydev, e); -} - -static int rtl8218b_set_eee(struct phy_device *phydev, struct ethtool_eee *e) -{ - int port = phydev->mdio.addr; - u64 poll_state; - u32 val; - bool an_enabled; - - pr_info("In %s, port %d, enabled %d\n", __func__, port, e->eee_enabled); - - poll_state = disable_polling(port); - - /* Set GPHY page to copper */ - phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER); - val = phy_read(phydev, MII_BMCR); - an_enabled = val & BMCR_ANENABLE; - - if (e->eee_enabled) { - /* 100/1000M EEE Capability */ - phy_write(phydev, 13, 0x0007); - phy_write(phydev, 14, 0x003C); - phy_write(phydev, 13, 0x4007); - phy_write(phydev, 14, 0x0006); - - val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25); - val |= BIT(4); - phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val); - } else { - /* 100/1000M EEE Capability */ - phy_write(phydev, 13, 0x0007); - phy_write(phydev, 14, 0x003C); - phy_write(phydev, 13, 0x0007); - phy_write(phydev, 14, 0x0000); - - val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25); - val &= ~BIT(4); - phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val); - } - - /* Restart AN if enabled */ - if (an_enabled) { - val = phy_read(phydev, MII_BMCR); - val |= BMCR_ANRESTART; - phy_write(phydev, MII_BMCR, val); - } - - /* GPHY page back to auto */ - phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); - - pr_info("%s done\n", __func__); - resume_polling(poll_state); - - return 0; -} - -static int rtl8218d_set_eee(struct phy_device *phydev, struct ethtool_eee *e) -{ - int addr = phydev->mdio.addr; - u64 poll_state; - - pr_info("In %s, port %d, enabled %d\n", __func__, addr, e->eee_enabled); - - poll_state = disable_polling(addr); - - rtl8218d_eee_set(phydev, (bool) e->eee_enabled); - - resume_polling(poll_state); - - return 0; -} - -static int rtl8214c_match_phy_device(struct phy_device *phydev) -{ - return phydev->phy_id == PHY_ID_RTL8214C; -} - -static int rtl8380_configure_rtl8214c(struct phy_device *phydev) -{ - u32 phy_id, val; - int mac = phydev->mdio.addr; - - val = phy_read(phydev, 2); - phy_id = val << 16; - val = phy_read(phydev, 3); - phy_id |= val; - pr_debug("Phy on MAC %d: %x\n", mac, phy_id); - - phydev_info(phydev, "Detected external RTL8214C\n"); - - /* GPHY auto conf */ - phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); - - return 0; -} - -static int rtl8380_configure_rtl8214fc(struct phy_device *phydev) -{ - int mac = phydev->mdio.addr; - struct fw_header *h; - u32 *rtl8380_rtl8214fc_perchip; - u32 *rtl8380_rtl8214fc_perport; - u32 phy_id; - u32 val; - - val = phy_read(phydev, 2); - phy_id = val << 16; - val = phy_read(phydev, 3); - phy_id |= val; - pr_debug("Phy on MAC %d: %x\n", mac, phy_id); - - /* Read internal PHY id */ - phy_write_paged(phydev, 0, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER); - phy_write_paged(phydev, 0x1f, 0x1b, 0x0002); - val = phy_read_paged(phydev, 0x1f, 0x1c); - if (val != RTL821X_CHIP_ID) { - phydev_err(phydev, "Expected external RTL8214FC, found PHY-ID %x\n", val); - return -1; - } - phydev_info(phydev, "Detected external RTL8214FC\n"); - - h = rtl838x_request_fw(phydev, &rtl838x_8214fc_fw, FIRMWARE_838X_8214FC_1); - if (!h) - return -1; - - if (h->phy != 0x8214fc00) { - phydev_err(phydev, "Wrong firmware file: PHY mismatch.\n"); - return -1; - } - - rtl8380_rtl8214fc_perchip = (void *)h + sizeof(struct fw_header) + h->parts[0].start; - - rtl8380_rtl8214fc_perport = (void *)h + sizeof(struct fw_header) + h->parts[1].start; - - /* detect phy version */ - phy_write_paged(phydev, RTL83XX_PAGE_RAW, 27, 0x0004); - val = phy_read_paged(phydev, RTL83XX_PAGE_RAW, 28); - - val = phy_read(phydev, 16); - if (val & BMCR_PDOWN) - rtl8380_rtl8214fc_on_off(phydev, true); - else - rtl8380_phy_reset(phydev); - - msleep(100); - phy_write_paged(phydev, 0, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER); - - for (int i = 0; rtl8380_rtl8214fc_perchip[i * 3] && - rtl8380_rtl8214fc_perchip[i * 3 + 1]; i++) { - u32 page = 0; - - if (rtl8380_rtl8214fc_perchip[i * 3 + 1] == 0x1f) - page = rtl8380_rtl8214fc_perchip[i * 3 + 2]; - if (rtl8380_rtl8214fc_perchip[i * 3 + 1] == 0x13 && page == 0x260) { - val = phy_read_paged(phydev, 0x260, 13); - val = (val & 0x1f00) | (rtl8380_rtl8214fc_perchip[i * 3 + 2] & 0xe0ff); - phy_write_paged(phydev, RTL83XX_PAGE_RAW, - rtl8380_rtl8214fc_perchip[i * 3 + 1], val); - } else { - phy_write_paged(phydev, RTL83XX_PAGE_RAW, - rtl8380_rtl8214fc_perchip[i * 3 + 1], - rtl8380_rtl8214fc_perchip[i * 3 + 2]); - } - } - - /* Force copper medium */ - for (int i = 0; i < 4; i++) { - phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN); - phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER); - } - - /* Enable PHY */ - for (int i = 0; i < 4; i++) { - phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN); - phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x00, 0x1140); - } - mdelay(100); - - /* Disable Autosensing */ - for (int i = 0; i < 4; i++) { - int l; - - for (l = 0; l < 100; l++) { - val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_GPHY, 0x10); - if ((val & 0x7) >= 3) - break; - } - if (l >= 100) { - phydev_err(phydev, "Could not disable autosensing\n"); - return -1; - } - } - - /* Request patch */ - for (int i = 0; i < 4; i++) { - phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH); - phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x10, 0x0010); - } - mdelay(300); - - /* Verify patch readiness */ - for (int i = 0; i < 4; i++) { - int l; - - for (l = 0; l < 100; l++) { - val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_STATE, 0x10); - if (val & 0x40) - break; - } - if (l >= 100) { - phydev_err(phydev, "Could not patch PHY\n"); - return -1; - } - } - /* Use Broadcast ID method for patching */ - rtl821x_phy_setup_package_broadcast(phydev, true); - - for (int i = 0; rtl8380_rtl8214fc_perport[i * 2]; i++) { - phy_write_paged(phydev, RTL83XX_PAGE_RAW, rtl8380_rtl8214fc_perport[i * 2], - rtl8380_rtl8214fc_perport[i * 2 + 1]); - } - - /* Disable broadcast ID */ - rtl821x_phy_setup_package_broadcast(phydev, false); - - /* Auto medium selection */ - for (int i = 0; i < 4; i++) { - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN); - phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO); - } - - return 0; -} - -static int rtl8214fc_match_phy_device(struct phy_device *phydev) -{ - int addr = phydev->mdio.addr; - - return phydev->phy_id == PHY_ID_RTL8214FC && addr >= 24; -} - -static int rtl8380_configure_serdes(struct phy_device *phydev) -{ - u32 v; - u32 sds_conf_value; - int i; - struct fw_header *h; - u32 *rtl8380_sds_take_reset; - u32 *rtl8380_sds_common; - u32 *rtl8380_sds01_qsgmii_6275b; - u32 *rtl8380_sds23_qsgmii_6275b; - u32 *rtl8380_sds4_fiber_6275b; - u32 *rtl8380_sds5_fiber_6275b; - u32 *rtl8380_sds_reset; - u32 *rtl8380_sds_release_reset; - - phydev_info(phydev, "Detected internal RTL8380 SERDES\n"); - - h = rtl838x_request_fw(phydev, &rtl838x_8218b_fw, FIRMWARE_838X_8380_1); - if (!h) - return -1; - - if (h->magic != 0x83808380) { - phydev_err(phydev, "Wrong firmware file: magic number mismatch.\n"); - return -1; - } - - rtl8380_sds_take_reset = (void *)h + sizeof(struct fw_header) + h->parts[0].start; - - rtl8380_sds_common = (void *)h + sizeof(struct fw_header) + h->parts[1].start; - - rtl8380_sds01_qsgmii_6275b = (void *)h + sizeof(struct fw_header) + h->parts[2].start; - - rtl8380_sds23_qsgmii_6275b = (void *)h + sizeof(struct fw_header) + h->parts[3].start; - - rtl8380_sds4_fiber_6275b = (void *)h + sizeof(struct fw_header) + h->parts[4].start; - - rtl8380_sds5_fiber_6275b = (void *)h + sizeof(struct fw_header) + h->parts[5].start; - - rtl8380_sds_reset = (void *)h + sizeof(struct fw_header) + h->parts[6].start; - - rtl8380_sds_release_reset = (void *)h + sizeof(struct fw_header) + h->parts[7].start; - - /* Back up serdes power off value */ - sds_conf_value = sw_r32(RTL838X_SDS_CFG_REG); - pr_info("SDS power down value: %x\n", sds_conf_value); - - /* take serdes into reset */ - i = 0; - while (rtl8380_sds_take_reset[2 * i]) { - sw_w32(rtl8380_sds_take_reset[2 * i + 1], rtl8380_sds_take_reset[2 * i]); - i++; - udelay(1000); - } - - /* apply common serdes patch */ - i = 0; - while (rtl8380_sds_common[2 * i]) { - sw_w32(rtl8380_sds_common[2 * i + 1], rtl8380_sds_common[2 * i]); - i++; - udelay(1000); - } - - /* internal R/W enable */ - sw_w32(3, RTL838X_INT_RW_CTRL); - - /* SerDes ports 4 and 5 are FIBRE ports */ - sw_w32_mask(0x7 | 0x38, 1 | (1 << 3), RTL838X_INT_MODE_CTRL); - - /* SerDes module settings, SerDes 0-3 are QSGMII */ - v = 0x6 << 25 | 0x6 << 20 | 0x6 << 15 | 0x6 << 10; - /* SerDes 4 and 5 are 1000BX FIBRE */ - v |= 0x4 << 5 | 0x4; - sw_w32(v, RTL838X_SDS_MODE_SEL); - - pr_info("PLL control register: %x\n", sw_r32(RTL838X_PLL_CML_CTRL)); - sw_w32_mask(0xfffffff0, 0xaaaaaaaf & 0xf, RTL838X_PLL_CML_CTRL); - i = 0; - while (rtl8380_sds01_qsgmii_6275b[2 * i]) { - sw_w32(rtl8380_sds01_qsgmii_6275b[2 * i + 1], - rtl8380_sds01_qsgmii_6275b[2 * i]); - i++; - } - - i = 0; - while (rtl8380_sds23_qsgmii_6275b[2 * i]) { - sw_w32(rtl8380_sds23_qsgmii_6275b[2 * i + 1], rtl8380_sds23_qsgmii_6275b[2 * i]); - i++; - } - - i = 0; - while (rtl8380_sds4_fiber_6275b[2 * i]) { - sw_w32(rtl8380_sds4_fiber_6275b[2 * i + 1], rtl8380_sds4_fiber_6275b[2 * i]); - i++; - } - - i = 0; - while (rtl8380_sds5_fiber_6275b[2 * i]) { - sw_w32(rtl8380_sds5_fiber_6275b[2 * i + 1], rtl8380_sds5_fiber_6275b[2 * i]); - i++; - } - - i = 0; - while (rtl8380_sds_reset[2 * i]) { - sw_w32(rtl8380_sds_reset[2 * i + 1], rtl8380_sds_reset[2 * i]); - i++; - } - - i = 0; - while (rtl8380_sds_release_reset[2 * i]) { - sw_w32(rtl8380_sds_release_reset[2 * i + 1], rtl8380_sds_release_reset[2 * i]); - i++; - } - - pr_info("SDS power down value now: %x\n", sw_r32(RTL838X_SDS_CFG_REG)); - sw_w32(sds_conf_value, RTL838X_SDS_CFG_REG); - - pr_info("Configuration of SERDES done\n"); - - return 0; -} - -static int rtl8390_configure_serdes(struct phy_device *phydev) -{ - phydev_info(phydev, "Detected internal RTL8390 SERDES\n"); - - /* In autoneg state, force link, set SR4_CFG_EN_LINK_FIB1G */ - sw_w32_mask(0, 1 << 18, RTL839X_SDS12_13_XSG0 + 0x0a); - - /* Disable EEE: Clear FRE16_EEE_RSG_FIB1G, FRE16_EEE_STD_FIB1G, - * FRE16_C1_PWRSAV_EN_FIB1G, FRE16_C2_PWRSAV_EN_FIB1G - * and FRE16_EEE_QUIET_FIB1G - */ - sw_w32_mask(0x1f << 10, 0, RTL839X_SDS12_13_XSG0 + 0xe0); - - return 0; -} - -void rtl9300_sds_field_w(int sds, u32 page, u32 reg, int end_bit, int start_bit, u32 v) -{ - int l = end_bit - start_bit + 1; - u32 data = v; - - if (l < 32) { - u32 mask = BIT(l) - 1; - - data = rtl930x_read_sds_phy(sds, page, reg); - data &= ~(mask << start_bit); - data |= (v & mask) << start_bit; - } - - rtl930x_write_sds_phy(sds, page, reg, data); -} - -u32 rtl9300_sds_field_r(int sds, u32 page, u32 reg, int end_bit, int start_bit) -{ - int l = end_bit - start_bit + 1; - u32 v = rtl930x_read_sds_phy(sds, page, reg); - - if (l >= 32) - return v; - - return (v >> start_bit) & (BIT(l) - 1); -} - -/* Read the link and speed status of the internal SerDes of the RTL9300 - */ -static int rtl9300_read_status(struct phy_device *phydev) -{ - struct device *dev = &phydev->mdio.dev; - int phy_addr = phydev->mdio.addr; - struct device_node *dn; - u32 sds_num = 0, status, latch_status, mode; - - if (dev->of_node) { - dn = dev->of_node; - - if (of_property_read_u32(dn, "sds", &sds_num)) - sds_num = -1; - pr_info("%s: Port %d, SerDes is %d\n", __func__, phy_addr, sds_num); - } else { - dev_err(dev, "No DT node.\n"); - return -EINVAL; - } - - if (sds_num < 0) - return 0; - - mode = rtl9300_sds_mode_get(sds_num); - pr_info("%s got SDS mode %02x\n", __func__, mode); - if (mode == RTL930X_SDS_OFF) - mode = rtl9300_sds_field_r(sds_num, 0x1f, 9, 11, 7); - if (mode == RTL930X_SDS_MODE_10GBASER) { /* 10GR mode */ - status = rtl9300_sds_field_r(sds_num, 0x5, 0, 12, 12); - latch_status = rtl9300_sds_field_r(sds_num, 0x4, 1, 2, 2); - status |= rtl9300_sds_field_r(sds_num, 0x5, 0, 12, 12); - latch_status |= rtl9300_sds_field_r(sds_num, 0x4, 1, 2, 2); - } else { - status = rtl9300_sds_field_r(sds_num, 0x1, 29, 8, 0); - latch_status = rtl9300_sds_field_r(sds_num, 0x1, 30, 8, 0); - status |= rtl9300_sds_field_r(sds_num, 0x1, 29, 8, 0); - latch_status |= rtl9300_sds_field_r(sds_num, 0x1, 30, 8, 0); - } - - pr_info("%s link status: status: %d, latch %d\n", __func__, status, latch_status); - - if (latch_status) { - phydev->link = true; - if (mode == RTL930X_SDS_MODE_10GBASER) { - phydev->speed = SPEED_10000; - phydev->interface = PHY_INTERFACE_MODE_10GBASER; - } else { - phydev->speed = SPEED_1000; - phydev->interface = PHY_INTERFACE_MODE_1000BASEX; - } - - phydev->duplex = DUPLEX_FULL; - } - - return 0; -} - -void rtl930x_sds_rx_rst(int sds_num, phy_interface_t phy_if) -{ - int page = 0x2e; /* 10GR and USXGMII */ - - if (phy_if == PHY_INTERFACE_MODE_1000BASEX) - page = 0x24; - - rtl9300_sds_field_w(sds_num, page, 0x15, 4, 4, 0x1); - mdelay(5); - rtl9300_sds_field_w(sds_num, page, 0x15, 4, 4, 0x0); -} - -/* Force PHY modes on 10GBit Serdes - */ -void rtl9300_force_sds_mode(int sds, phy_interface_t phy_if) -{ - int lc_value; - int sds_mode; - bool lc_on; - int lane_0 = (sds % 2) ? sds - 1 : sds; - u32 v; - - pr_info("%s: SDS: %d, mode %d\n", __func__, sds, phy_if); - switch (phy_if) { - case PHY_INTERFACE_MODE_SGMII: - sds_mode = RTL930X_SDS_MODE_SGMII; - lc_on = false; - lc_value = 0x1; - break; - - case PHY_INTERFACE_MODE_HSGMII: - sds_mode = RTL930X_SDS_MODE_HSGMII; - lc_value = 0x3; - /* Configure LC */ - break; - - case PHY_INTERFACE_MODE_1000BASEX: - sds_mode = RTL930X_SDS_MODE_1000BASEX; - lc_on = false; - break; - - case PHY_INTERFACE_MODE_2500BASEX: - sds_mode = RTL930X_SDS_MODE_2500BASEX; - lc_value = 0x3; - /* Configure LC */ - break; - - case PHY_INTERFACE_MODE_10GBASER: - sds_mode = RTL930X_SDS_MODE_10GBASER; - lc_on = true; - lc_value = 0x5; - break; - - case PHY_INTERFACE_MODE_NA: - /* This will disable SerDes */ - sds_mode = RTL930X_SDS_OFF; - break; - - default: - pr_err("%s: unknown serdes mode: %s\n", - __func__, phy_modes(phy_if)); - return; - } - - pr_info("%s --------------------- serdes %d forcing to %x ...\n", __func__, sds, sds_mode); - /* Power down SerDes */ - rtl9300_sds_field_w(sds, 0x20, 0, 7, 6, 0x3); - if (sds == 5) pr_info("%s after %x\n", __func__, rtl930x_read_sds_phy(sds, 0x20, 0)); - - if (sds == 5) pr_info("%s a %x\n", __func__, rtl930x_read_sds_phy(sds, 0x1f, 9)); - /* Force mode enable */ - rtl9300_sds_field_w(sds, 0x1f, 9, 6, 6, 0x1); - if (sds == 5) pr_info("%s b %x\n", __func__, rtl930x_read_sds_phy(sds, 0x1f, 9)); - - /* SerDes off */ - rtl9300_sds_field_w(sds, 0x1f, 9, 11, 7, RTL930X_SDS_OFF); - - if (phy_if == PHY_INTERFACE_MODE_NA) - return; - - if (sds == 5) pr_info("%s c %x\n", __func__, rtl930x_read_sds_phy(sds, 0x20, 18)); - /* Enable LC and ring */ - rtl9300_sds_field_w(lane_0, 0x20, 18, 3, 0, 0xf); - - if (sds == lane_0) - rtl9300_sds_field_w(lane_0, 0x20, 18, 5, 4, 0x1); - else - rtl9300_sds_field_w(lane_0, 0x20, 18, 7, 6, 0x1); - - rtl9300_sds_field_w(sds, 0x20, 0, 5, 4, 0x3); - - if (lc_on) - rtl9300_sds_field_w(lane_0, 0x20, 18, 11, 8, lc_value); - else - rtl9300_sds_field_w(lane_0, 0x20, 18, 15, 12, lc_value); - - /* Force analog LC & ring on */ - rtl9300_sds_field_w(lane_0, 0x21, 11, 3, 0, 0xf); - - v = lc_on ? 0x3 : 0x1; - - if (sds == lane_0) - rtl9300_sds_field_w(lane_0, 0x20, 18, 5, 4, v); - else - rtl9300_sds_field_w(lane_0, 0x20, 18, 7, 6, v); - - /* Force SerDes mode */ - rtl9300_sds_field_w(sds, 0x1f, 9, 6, 6, 1); - rtl9300_sds_field_w(sds, 0x1f, 9, 11, 7, sds_mode); - - /* Toggle LC or Ring */ - for (int i = 0; i < 20; i++) { - u32 cr_0, cr_1, cr_2; - u32 m_bit, l_bit; - - mdelay(200); - - rtl930x_write_sds_phy(lane_0, 0x1f, 2, 53); - - m_bit = (lane_0 == sds) ? (4) : (5); - l_bit = (lane_0 == sds) ? (4) : (5); - - cr_0 = rtl9300_sds_field_r(lane_0, 0x1f, 20, m_bit, l_bit); - mdelay(10); - cr_1 = rtl9300_sds_field_r(lane_0, 0x1f, 20, m_bit, l_bit); - mdelay(10); - cr_2 = rtl9300_sds_field_r(lane_0, 0x1f, 20, m_bit, l_bit); - - if (cr_0 && cr_1 && cr_2) { - u32 t; - - if (phy_if != PHY_INTERFACE_MODE_10GBASER) - break; - - t = rtl9300_sds_field_r(sds, 0x6, 0x1, 2, 2); - rtl9300_sds_field_w(sds, 0x6, 0x1, 2, 2, 0x1); - - /* Reset FSM */ - rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x1); - mdelay(10); - rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x0); - mdelay(10); - - /* Need to read this twice */ - v = rtl9300_sds_field_r(sds, 0x5, 0, 12, 12); - v = rtl9300_sds_field_r(sds, 0x5, 0, 12, 12); - - rtl9300_sds_field_w(sds, 0x6, 0x1, 2, 2, t); - - /* Reset FSM again */ - rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x1); - mdelay(10); - rtl9300_sds_field_w(sds, 0x6, 0x2, 12, 12, 0x0); - mdelay(10); - - if (v == 1) - break; - } - - m_bit = (phy_if == PHY_INTERFACE_MODE_10GBASER) ? 3 : 1; - l_bit = (phy_if == PHY_INTERFACE_MODE_10GBASER) ? 2 : 0; - - rtl9300_sds_field_w(lane_0, 0x21, 11, m_bit, l_bit, 0x2); - mdelay(10); - rtl9300_sds_field_w(lane_0, 0x21, 11, m_bit, l_bit, 0x3); - } - - rtl930x_sds_rx_rst(sds, phy_if); - - /* Re-enable power */ - rtl9300_sds_field_w(sds, 0x20, 0, 7, 6, 0); - - pr_info("%s --------------------- serdes %d forced to %x DONE\n", __func__, sds, sds_mode); -} - -void rtl9300_sds_tx_config(int sds, phy_interface_t phy_if) -{ - /* parameters: rtl9303_80G_txParam_s2 */ - int impedance = 0x8; - int pre_amp = 0x2; - int main_amp = 0x9; - int post_amp = 0x2; - int pre_en = 0x1; - int post_en = 0x1; - int page; - - switch(phy_if) { - case PHY_INTERFACE_MODE_1000BASEX: - pre_amp = 0x1; - main_amp = 0x9; - post_amp = 0x1; - page = 0x25; - break; - case PHY_INTERFACE_MODE_HSGMII: - case PHY_INTERFACE_MODE_2500BASEX: - pre_amp = 0; - post_amp = 0x8; - pre_en = 0; - page = 0x29; - break; - case PHY_INTERFACE_MODE_10GBASER: - case PHY_INTERFACE_MODE_USXGMII: - case PHY_INTERFACE_MODE_XGMII: - pre_en = 0; - pre_amp = 0; - main_amp = 0x10; - post_amp = 0; - post_en = 0; - page = 0x2f; - break; - default: - pr_err("%s: unsupported PHY mode\n", __func__); - return; - } - - rtl9300_sds_field_w(sds, page, 0x01, 15, 11, pre_amp); - rtl9300_sds_field_w(sds, page, 0x06, 4, 0, post_amp); - rtl9300_sds_field_w(sds, page, 0x07, 0, 0, pre_en); - rtl9300_sds_field_w(sds, page, 0x07, 3, 3, post_en); - rtl9300_sds_field_w(sds, page, 0x07, 8, 4, main_amp); - rtl9300_sds_field_w(sds, page, 0x18, 15, 12, impedance); -} - -/* Wait for clock ready, this assumes the SerDes is in XGMII mode - * timeout is in ms - */ -int rtl9300_sds_clock_wait(int timeout) -{ - u32 v; - unsigned long start = jiffies; - - do { - rtl9300_sds_field_w(2, 0x1f, 0x2, 15, 0, 53); - v = rtl9300_sds_field_r(2, 0x1f, 20, 5, 4); - if (v == 3) - return 0; - } while (jiffies < start + (HZ / 1000) * timeout); - - return 1; -} - -void rtl9300_serdes_mac_link_config(int sds, bool tx_normal, bool rx_normal) -{ - u32 v10, v1; - - v10 = rtl930x_read_sds_phy(sds, 6, 2); /* 10GBit, page 6, reg 2 */ - v1 = rtl930x_read_sds_phy(sds, 0, 0); /* 1GBit, page 0, reg 0 */ - pr_info("%s: registers before %08x %08x\n", __func__, v10, v1); - - v10 &= ~(BIT(13) | BIT(14)); - v1 &= ~(BIT(8) | BIT(9)); - - v10 |= rx_normal ? 0 : BIT(13); - v1 |= rx_normal ? 0 : BIT(9); - - v10 |= tx_normal ? 0 : BIT(14); - v1 |= tx_normal ? 0 : BIT(8); - - rtl930x_write_sds_phy(sds, 6, 2, v10); - rtl930x_write_sds_phy(sds, 0, 0, v1); - - v10 = rtl930x_read_sds_phy(sds, 6, 2); - v1 = rtl930x_read_sds_phy(sds, 0, 0); - pr_info("%s: registers after %08x %08x\n", __func__, v10, v1); -} - -void rtl9300_sds_rxcal_dcvs_manual(u32 sds_num, u32 dcvs_id, bool manual, u32 dvcs_list[]) -{ - if (manual) { - switch(dcvs_id) { - case 0: - rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 14, 14, 0x1); - rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 5, 5, dvcs_list[0]); - rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 4, 0, dvcs_list[1]); - break; - case 1: - rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 13, 13, 0x1); - rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 15, 15, dvcs_list[0]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 14, 11, dvcs_list[1]); - break; - case 2: - rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 12, 12, 0x1); - rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 10, 10, dvcs_list[0]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 9, 6, dvcs_list[1]); - break; - case 3: - rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 11, 11, 0x1); - rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 5, 5, dvcs_list[0]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x1d, 4, 1, dvcs_list[1]); - break; - case 4: - rtl9300_sds_field_w(sds_num, 0x2e, 0x01, 15, 15, 0x1); - rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 10, 10, dvcs_list[0]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 9, 6, dvcs_list[1]); - break; - case 5: - rtl9300_sds_field_w(sds_num, 0x2e, 0x02, 11, 11, 0x1); - rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 4, 4, dvcs_list[0]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x11, 3, 0, dvcs_list[1]); - break; - default: - break; - } - } else { - switch(dcvs_id) { - case 0: - rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 14, 14, 0x0); - break; - case 1: - rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 13, 13, 0x0); - break; - case 2: - rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 12, 12, 0x0); - break; - case 3: - rtl9300_sds_field_w(sds_num, 0x2e, 0x1e, 11, 11, 0x0); - break; - case 4: - rtl9300_sds_field_w(sds_num, 0x2e, 0x01, 15, 15, 0x0); - break; - case 5: - rtl9300_sds_field_w(sds_num, 0x2e, 0x02, 11, 11, 0x0); - break; - default: - break; - } - mdelay(1); - } -} - -void rtl9300_sds_rxcal_dcvs_get(u32 sds_num, u32 dcvs_id, u32 dcvs_list[]) -{ - u32 dcvs_sign_out = 0, dcvs_coef_bin = 0; - bool dcvs_manual; - - if (!(sds_num % 2)) - rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f); - else - rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31); - - /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */ - rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1); - - /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */ - rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20); - - switch(dcvs_id) { - case 0: - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x22); - mdelay(1); - - /* ##DCVS0 Read Out */ - dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4); - dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0); - dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 14, 14); - break; - - case 1: - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x23); - mdelay(1); - - /* ##DCVS0 Read Out */ - dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4); - dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0); - dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 13, 13); - break; - - case 2: - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x24); - mdelay(1); - - /* ##DCVS0 Read Out */ - dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4); - dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0); - dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 12, 12); - break; - case 3: - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x25); - mdelay(1); - - /* ##DCVS0 Read Out */ - dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4); - dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0); - dcvs_manual = rtl9300_sds_field_r(sds_num, 0x2e, 0x1e, 11, 11); - break; - - case 4: - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x2c); - mdelay(1); - - /* ##DCVS0 Read Out */ - dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4); - dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0); - dcvs_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x01, 15, 15); - break; - - case 5: - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0x2d); - mdelay(1); - - /* ##DCVS0 Read Out */ - dcvs_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 4); - dcvs_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 3, 0); - dcvs_manual = rtl9300_sds_field_r(sds_num, 0x2e, 0x02, 11, 11); - break; - - default: - break; - } - - if (dcvs_sign_out) - pr_info("%s DCVS %u Sign: -", __func__, dcvs_id); - else - pr_info("%s DCVS %u Sign: +", __func__, dcvs_id); - - pr_info("DCVS %u even coefficient = %u", dcvs_id, dcvs_coef_bin); - pr_info("DCVS %u manual = %u", dcvs_id, dcvs_manual); - - dcvs_list[0] = dcvs_sign_out; - dcvs_list[1] = dcvs_coef_bin; -} - -void rtl9300_sds_rxcal_leq_manual(u32 sds_num, bool manual, u32 leq_gray) -{ - if (manual) { - rtl9300_sds_field_w(sds_num, 0x2e, 0x18, 15, 15, 0x1); - rtl9300_sds_field_w(sds_num, 0x2e, 0x16, 14, 10, leq_gray); - } else { - rtl9300_sds_field_w(sds_num, 0x2e, 0x18, 15, 15, 0x0); - mdelay(100); - } -} - -void rtl9300_sds_rxcal_leq_offset_manual(u32 sds_num, bool manual, u32 offset) -{ - if (manual) { - rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 6, 2, offset); - } else { - rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 6, 2, offset); - mdelay(1); - } -} - -#define GRAY_BITS 5 -u32 rtl9300_sds_rxcal_gray_to_binary(u32 gray_code) -{ - int i, j, m; - u32 g[GRAY_BITS]; - u32 c[GRAY_BITS]; - u32 leq_binary = 0; - - for(i = 0; i < GRAY_BITS; i++) - g[i] = (gray_code & BIT(i)) >> i; - - m = GRAY_BITS - 1; - - c[m] = g[m]; - - for(i = 0; i < m; i++) { - c[i] = g[i]; - for(j = i + 1; j < GRAY_BITS; j++) - c[i] = c[i] ^ g[j]; - } - - for(i = 0; i < GRAY_BITS; i++) - leq_binary += c[i] << i; - - return leq_binary; -} - -u32 rtl9300_sds_rxcal_leq_read(int sds_num) -{ - u32 leq_gray, leq_bin; - bool leq_manual; - - if (!(sds_num % 2)) - rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f); - else - rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31); - - /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */ - rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1); - - /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[0 1 x x x x] */ - rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x10); - mdelay(1); - - /* ##LEQ Read Out */ - leq_gray = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 7, 3); - leq_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x18, 15, 15); - leq_bin = rtl9300_sds_rxcal_gray_to_binary(leq_gray); - - pr_info("LEQ_gray: %u, LEQ_bin: %u", leq_gray, leq_bin); - pr_info("LEQ manual: %u", leq_manual); - - return leq_bin; -} - -void rtl9300_sds_rxcal_vth_manual(u32 sds_num, bool manual, u32 vth_list[]) -{ - if (manual) { - rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, 13, 13, 0x1); - rtl9300_sds_field_w(sds_num, 0x2e, 0x13, 5, 3, vth_list[0]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x13, 2, 0, vth_list[1]); - } else { - rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, 13, 13, 0x0); - mdelay(10); - } -} - -void rtl9300_sds_rxcal_vth_get(u32 sds_num, u32 vth_list[]) -{ - u32 vth_manual; - - /* ##Page0x1F, Reg0x02[15 0], REG_DBGO_SEL=[0x002F]; */ /* Lane0 */ - /* ##Page0x1F, Reg0x02[15 0], REG_DBGO_SEL=[0x0031]; */ /* Lane1 */ - if (!(sds_num % 2)) - rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f); - else - rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31); - - /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */ - rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1); - /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */ - rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20); - /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 1 1 0 0] */ - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0xc); - - mdelay(1); - - /* ##VthP & VthN Read Out */ - vth_list[0] = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 2, 0); /* v_thp set bin */ - vth_list[1] = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 3); /* v_thn set bin */ - - pr_info("vth_set_bin = %d", vth_list[0]); - pr_info("vth_set_bin = %d", vth_list[1]); - - vth_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x0f, 13, 13); - pr_info("Vth Maunal = %d", vth_manual); -} - -void rtl9300_sds_rxcal_tap_manual(u32 sds_num, int tap_id, bool manual, u32 tap_list[]) -{ - if (manual) { - switch(tap_id) { - case 0: - /* ##REG0_LOAD_IN_INIT[0]=1; REG0_TAP0_INIT[5:0]=Tap0_Value */ - rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1); - rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 5, 5, tap_list[0]); - rtl9300_sds_field_w(sds_num, 0x2f, 0x03, 4, 0, tap_list[1]); - break; - case 1: - rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1); - rtl9300_sds_field_w(sds_num, 0x21, 0x07, 6, 6, tap_list[0]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x09, 11, 6, tap_list[1]); - rtl9300_sds_field_w(sds_num, 0x21, 0x07, 5, 5, tap_list[2]); - rtl9300_sds_field_w(sds_num, 0x2f, 0x12, 5, 0, tap_list[3]); - break; - case 2: - rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1); - rtl9300_sds_field_w(sds_num, 0x2e, 0x09, 5, 5, tap_list[0]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x09, 4, 0, tap_list[1]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 11, 11, tap_list[2]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 10, 6, tap_list[3]); - break; - case 3: - rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1); - rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 5, 5, tap_list[0]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x0a, 4, 0, tap_list[1]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 5, 5, tap_list[2]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 4, 0, tap_list[3]); - break; - case 4: - rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x1); - rtl9300_sds_field_w(sds_num, 0x2f, 0x01, 5, 5, tap_list[0]); - rtl9300_sds_field_w(sds_num, 0x2f, 0x01, 4, 0, tap_list[1]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 11, 11, tap_list[2]); - rtl9300_sds_field_w(sds_num, 0x2e, 0x06, 10, 6, tap_list[3]); - break; - default: - break; - } - } else { - rtl9300_sds_field_w(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7, 0x0); - mdelay(10); - } -} - -void rtl9300_sds_rxcal_tap_get(u32 sds_num, u32 tap_id, u32 tap_list[]) -{ - u32 tap0_sign_out; - u32 tap0_coef_bin; - u32 tap_sign_out_even; - u32 tap_coef_bin_even; - u32 tap_sign_out_odd; - u32 tap_coef_bin_odd; - bool tap_manual; - - if (!(sds_num % 2)) - rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f); - else - rtl930x_write_sds_phy(sds_num - 1, 0x1f, 0x2, 0x31); - - /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */ - rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1); - /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */ - rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20); - - if (!tap_id) { - /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 0 0 0 1] */ - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0); - /* ##Tap1 Even Read Out */ - mdelay(1); - tap0_sign_out = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 5); - tap0_coef_bin = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 0); - - if (tap0_sign_out == 1) - pr_info("Tap0 Sign : -"); - else - pr_info("Tap0 Sign : +"); - - pr_info("tap0_coef_bin = %d", tap0_coef_bin); - - tap_list[0] = tap0_sign_out; - tap_list[1] = tap0_coef_bin; - - tap_manual = !!rtl9300_sds_field_r(sds_num, 0x2e, 0x0f, 7, 7); - pr_info("tap0 manual = %u",tap_manual); - } else { - /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 0 0 0 1] */ - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, tap_id); - mdelay(1); - /* ##Tap1 Even Read Out */ - tap_sign_out_even = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 5); - tap_coef_bin_even = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 0); - - /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 0 1 1 0] */ - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, (tap_id + 5)); - /* ##Tap1 Odd Read Out */ - tap_sign_out_odd = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 5); - tap_coef_bin_odd = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 4, 0); - - if (tap_sign_out_even == 1) - pr_info("Tap %u even sign: -", tap_id); - else - pr_info("Tap %u even sign: +", tap_id); - - pr_info("Tap %u even coefficient = %u", tap_id, tap_coef_bin_even); - - if (tap_sign_out_odd == 1) - pr_info("Tap %u odd sign: -", tap_id); - else - pr_info("Tap %u odd sign: +", tap_id); - - pr_info("Tap %u odd coefficient = %u", tap_id,tap_coef_bin_odd); - - tap_list[0] = tap_sign_out_even; - tap_list[1] = tap_coef_bin_even; - tap_list[2] = tap_sign_out_odd; - tap_list[3] = tap_coef_bin_odd; - - tap_manual = rtl9300_sds_field_r(sds_num, 0x2e, 0x0f, tap_id + 7, tap_id + 7); - pr_info("tap %u manual = %d",tap_id, tap_manual); - } -} - -void rtl9300_do_rx_calibration_1(int sds, phy_interface_t phy_mode) -{ - /* From both rtl9300_rxCaliConf_serdes_myParam and rtl9300_rxCaliConf_phy_myParam */ - int tap0_init_val = 0x1f; /* Initial Decision Fed Equalizer 0 tap */ - int vth_min = 0x0; - - pr_info("start_1.1.1 initial value for sds %d\n", sds); - rtl930x_write_sds_phy(sds, 6, 0, 0); - - /* FGCAL */ - rtl9300_sds_field_w(sds, 0x2e, 0x01, 14, 14, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x1c, 10, 5, 0x20); - rtl9300_sds_field_w(sds, 0x2f, 0x02, 0, 0, 0x01); - - /* DCVS */ - rtl9300_sds_field_w(sds, 0x2e, 0x1e, 14, 11, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x01, 15, 15, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x02, 11, 11, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x1c, 4, 0, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x1d, 15, 11, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x1d, 10, 6, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x1d, 5, 1, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x02, 10, 6, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x11, 4, 0, 0x00); - rtl9300_sds_field_w(sds, 0x2f, 0x00, 3, 0, 0x0f); - rtl9300_sds_field_w(sds, 0x2e, 0x04, 6, 6, 0x01); - rtl9300_sds_field_w(sds, 0x2e, 0x04, 7, 7, 0x01); - - /* LEQ (Long Term Equivalent signal level) */ - rtl9300_sds_field_w(sds, 0x2e, 0x16, 14, 8, 0x00); - - /* DFE (Decision Fed Equalizer) */ - rtl9300_sds_field_w(sds, 0x2f, 0x03, 5, 0, tap0_init_val); - rtl9300_sds_field_w(sds, 0x2e, 0x09, 11, 6, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x09, 5, 0, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x0a, 5, 0, 0x00); - rtl9300_sds_field_w(sds, 0x2f, 0x01, 5, 0, 0x00); - rtl9300_sds_field_w(sds, 0x2f, 0x12, 5, 0, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x0a, 11, 6, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x06, 5, 0, 0x00); - rtl9300_sds_field_w(sds, 0x2f, 0x01, 5, 0, 0x00); - - /* Vth */ - rtl9300_sds_field_w(sds, 0x2e, 0x13, 5, 3, 0x07); - rtl9300_sds_field_w(sds, 0x2e, 0x13, 2, 0, 0x07); - rtl9300_sds_field_w(sds, 0x2f, 0x0b, 5, 3, vth_min); - - pr_info("end_1.1.1 --\n"); - - pr_info("start_1.1.2 Load DFE init. value\n"); - - rtl9300_sds_field_w(sds, 0x2e, 0x0f, 13, 7, 0x7f); - - pr_info("end_1.1.2\n"); - - pr_info("start_1.1.3 disable LEQ training,enable DFE clock\n"); - - rtl9300_sds_field_w(sds, 0x2e, 0x17, 7, 7, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x17, 6, 2, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x0c, 8, 8, 0x00); - rtl9300_sds_field_w(sds, 0x2e, 0x0b, 4, 4, 0x01); - rtl9300_sds_field_w(sds, 0x2e, 0x12, 14, 14, 0x00); - rtl9300_sds_field_w(sds, 0x2f, 0x02, 15, 15, 0x00); - - pr_info("end_1.1.3 --\n"); - - pr_info("start_1.1.4 offset cali setting\n"); - - rtl9300_sds_field_w(sds, 0x2e, 0x0f, 15, 14, 0x03); - - pr_info("end_1.1.4\n"); - - pr_info("start_1.1.5 LEQ and DFE setting\n"); - - /* TODO: make this work for DAC cables of different lengths */ - /* For a 10GBit serdes wit Fibre, SDS 8 or 9 */ - if (phy_mode == PHY_INTERFACE_MODE_10GBASER || PHY_INTERFACE_MODE_1000BASEX) - rtl9300_sds_field_w(sds, 0x2e, 0x16, 3, 2, 0x02); - else - pr_err("%s not PHY-based or SerDes, implement DAC!\n", __func__); - - /* No serdes, check for Aquantia PHYs */ - rtl9300_sds_field_w(sds, 0x2e, 0x16, 3, 2, 0x02); - - rtl9300_sds_field_w(sds, 0x2e, 0x0f, 6, 0, 0x5f); - rtl9300_sds_field_w(sds, 0x2f, 0x05, 7, 2, 0x1f); - rtl9300_sds_field_w(sds, 0x2e, 0x19, 9, 5, 0x1f); - rtl9300_sds_field_w(sds, 0x2f, 0x0b, 15, 9, 0x3c); - rtl9300_sds_field_w(sds, 0x2e, 0x0b, 1, 0, 0x03); - - pr_info("end_1.1.5\n"); -} - -void rtl9300_do_rx_calibration_2_1(u32 sds_num) -{ - pr_info("start_1.2.1 ForegroundOffsetCal_Manual\n"); - - /* Gray config endis to 1 */ - rtl9300_sds_field_w(sds_num, 0x2f, 0x02, 2, 2, 0x01); - - /* ForegroundOffsetCal_Manual(auto mode) */ - rtl9300_sds_field_w(sds_num, 0x2e, 0x01, 14, 14, 0x00); - - pr_info("end_1.2.1"); -} - -void rtl9300_do_rx_calibration_2_2(int sds_num) -{ - /* Force Rx-Run = 0 */ - rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 8, 8, 0x0); - - rtl930x_sds_rx_rst(sds_num, PHY_INTERFACE_MODE_10GBASER); -} - -void rtl9300_do_rx_calibration_2_3(int sds_num) -{ - u32 fgcal_binary, fgcal_gray; - u32 offset_range; - - pr_info("start_1.2.3 Foreground Calibration\n"); - - while(1) { - if (!(sds_num % 2)) - rtl930x_write_sds_phy(sds_num, 0x1f, 0x2, 0x2f); - else - rtl930x_write_sds_phy(sds_num -1 , 0x1f, 0x2, 0x31); - - /* ##Page0x2E, Reg0x15[9], REG0_RX_EN_TEST=[1] */ - rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 9, 9, 0x1); - /* ##Page0x21, Reg0x06[11 6], REG0_RX_DEBUG_SEL=[1 0 x x x x] */ - rtl9300_sds_field_w(sds_num, 0x21, 0x06, 11, 6, 0x20); - /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 1 1 1 1] */ - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0xf); - /* ##FGCAL read gray */ - fgcal_gray = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 0); - /* ##Page0x2F, Reg0x0C[5 0], REG0_COEF_SEL=[0 0 1 1 1 0] */ - rtl9300_sds_field_w(sds_num, 0x2f, 0x0c, 5, 0, 0xe); - /* ##FGCAL read binary */ - fgcal_binary = rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 5, 0); - - pr_info("%s: fgcal_gray: %d, fgcal_binary %d\n", - __func__, fgcal_gray, fgcal_binary); - - offset_range = rtl9300_sds_field_r(sds_num, 0x2e, 0x15, 15, 14); - - if (fgcal_binary > 60 || fgcal_binary < 3) { - if (offset_range == 3) { - pr_info("%s: Foreground Calibration result marginal!", __func__); - break; - } else { - offset_range++; - rtl9300_sds_field_w(sds_num, 0x2e, 0x15, 15, 14, offset_range); - rtl9300_do_rx_calibration_2_2(sds_num); - } - } else { - break; - } - } - pr_info("%s: end_1.2.3\n", __func__); -} - -void rtl9300_do_rx_calibration_2(int sds) -{ - rtl930x_sds_rx_rst(sds, PHY_INTERFACE_MODE_10GBASER); - rtl9300_do_rx_calibration_2_1(sds); - rtl9300_do_rx_calibration_2_2(sds); - rtl9300_do_rx_calibration_2_3(sds); -} - -void rtl9300_sds_rxcal_3_1(int sds_num, phy_interface_t phy_mode) -{ - pr_info("start_1.3.1"); - - /* ##1.3.1 */ - if (phy_mode != PHY_INTERFACE_MODE_10GBASER && phy_mode != PHY_INTERFACE_MODE_1000BASEX) - rtl9300_sds_field_w(sds_num, 0x2e, 0xc, 8, 8, 0); - - rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, 0x0); - rtl9300_sds_rxcal_leq_manual(sds_num, false, 0); - - pr_info("end_1.3.1"); -} - -void rtl9300_sds_rxcal_3_2(int sds_num, phy_interface_t phy_mode) -{ - u32 sum10 = 0, avg10, int10; - int dac_long_cable_offset; - bool eq_hold_enabled; - int i; - - if (phy_mode == PHY_INTERFACE_MODE_10GBASER || phy_mode == PHY_INTERFACE_MODE_1000BASEX) { - /* rtl9300_rxCaliConf_serdes_myParam */ - dac_long_cable_offset = 3; - eq_hold_enabled = true; - } else { - /* rtl9300_rxCaliConf_phy_myParam */ - dac_long_cable_offset = 0; - eq_hold_enabled = false; - } - - if (phy_mode == PHY_INTERFACE_MODE_1000BASEX) - pr_warn("%s: LEQ only valid for 10GR!\n", __func__); - - pr_info("start_1.3.2"); - - for(i = 0; i < 10; i++) { - sum10 += rtl9300_sds_rxcal_leq_read(sds_num); - mdelay(10); - } - - avg10 = (sum10 / 10) + (((sum10 % 10) >= 5) ? 1 : 0); - int10 = sum10 / 10; - - pr_info("sum10:%u, avg10:%u, int10:%u", sum10, avg10, int10); - - if (phy_mode == PHY_INTERFACE_MODE_10GBASER || phy_mode == PHY_INTERFACE_MODE_1000BASEX) { - if (dac_long_cable_offset) { - rtl9300_sds_rxcal_leq_offset_manual(sds_num, 1, dac_long_cable_offset); - rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, eq_hold_enabled); - if (phy_mode == PHY_INTERFACE_MODE_10GBASER) - rtl9300_sds_rxcal_leq_manual(sds_num, true, avg10); - } else { - if (sum10 >= 5) { - rtl9300_sds_rxcal_leq_offset_manual(sds_num, 1, 3); - rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, 0x1); - if (phy_mode == PHY_INTERFACE_MODE_10GBASER) - rtl9300_sds_rxcal_leq_manual(sds_num, true, avg10); - } else { - rtl9300_sds_rxcal_leq_offset_manual(sds_num, 1, 0); - rtl9300_sds_field_w(sds_num, 0x2e, 0x17, 7, 7, 0x1); - if (phy_mode == PHY_INTERFACE_MODE_10GBASER) - rtl9300_sds_rxcal_leq_manual(sds_num, true, avg10); - } - } - } - - pr_info("Sds:%u LEQ = %u",sds_num, rtl9300_sds_rxcal_leq_read(sds_num)); - - pr_info("end_1.3.2"); -} - -void rtl9300_do_rx_calibration_3(int sds_num, phy_interface_t phy_mode) -{ - rtl9300_sds_rxcal_3_1(sds_num, phy_mode); - - if (phy_mode == PHY_INTERFACE_MODE_10GBASER || phy_mode == PHY_INTERFACE_MODE_1000BASEX) - rtl9300_sds_rxcal_3_2(sds_num, phy_mode); -} - -void rtl9300_do_rx_calibration_4_1(int sds_num) -{ - u32 vth_list[2] = {0, 0}; - u32 tap0_list[4] = {0, 0, 0, 0}; - - pr_info("start_1.4.1"); - - /* ##1.4.1 */ - rtl9300_sds_rxcal_vth_manual(sds_num, false, vth_list); - rtl9300_sds_rxcal_tap_manual(sds_num, 0, false, tap0_list); - mdelay(200); - - pr_info("end_1.4.1"); -} - -void rtl9300_do_rx_calibration_4_2(u32 sds_num) -{ - u32 vth_list[2]; - u32 tap_list[4]; - - pr_info("start_1.4.2"); - - rtl9300_sds_rxcal_vth_get(sds_num, vth_list); - rtl9300_sds_rxcal_vth_manual(sds_num, true, vth_list); - - mdelay(100); - - rtl9300_sds_rxcal_tap_get(sds_num, 0, tap_list); - rtl9300_sds_rxcal_tap_manual(sds_num, 0, true, tap_list); - - pr_info("end_1.4.2"); -} - -void rtl9300_do_rx_calibration_4(u32 sds_num) -{ - rtl9300_do_rx_calibration_4_1(sds_num); - rtl9300_do_rx_calibration_4_2(sds_num); -} - -void rtl9300_do_rx_calibration_5_2(u32 sds_num) -{ - u32 tap1_list[4] = {0}; - u32 tap2_list[4] = {0}; - u32 tap3_list[4] = {0}; - u32 tap4_list[4] = {0}; - - pr_info("start_1.5.2"); - - rtl9300_sds_rxcal_tap_manual(sds_num, 1, false, tap1_list); - rtl9300_sds_rxcal_tap_manual(sds_num, 2, false, tap2_list); - rtl9300_sds_rxcal_tap_manual(sds_num, 3, false, tap3_list); - rtl9300_sds_rxcal_tap_manual(sds_num, 4, false, tap4_list); - - mdelay(30); - - pr_info("end_1.5.2"); -} - -void rtl9300_do_rx_calibration_5(u32 sds_num, phy_interface_t phy_mode) -{ - if (phy_mode == PHY_INTERFACE_MODE_10GBASER) /* dfeTap1_4Enable true */ - rtl9300_do_rx_calibration_5_2(sds_num); -} - - -void rtl9300_do_rx_calibration_dfe_disable(u32 sds_num) -{ - u32 tap1_list[4] = {0}; - u32 tap2_list[4] = {0}; - u32 tap3_list[4] = {0}; - u32 tap4_list[4] = {0}; - - rtl9300_sds_rxcal_tap_manual(sds_num, 1, true, tap1_list); - rtl9300_sds_rxcal_tap_manual(sds_num, 2, true, tap2_list); - rtl9300_sds_rxcal_tap_manual(sds_num, 3, true, tap3_list); - rtl9300_sds_rxcal_tap_manual(sds_num, 4, true, tap4_list); - - mdelay(10); -} - -void rtl9300_do_rx_calibration(int sds, phy_interface_t phy_mode) -{ - u32 latch_sts; - - rtl9300_do_rx_calibration_1(sds, phy_mode); - rtl9300_do_rx_calibration_2(sds); - rtl9300_do_rx_calibration_4(sds); - rtl9300_do_rx_calibration_5(sds, phy_mode); - mdelay(20); - - /* Do this only for 10GR mode, SDS active in mode 0x1a */ - if (rtl9300_sds_field_r(sds, 0x1f, 9, 11, 7) == RTL930X_SDS_MODE_10GBASER) { - pr_info("%s: SDS enabled\n", __func__); - latch_sts = rtl9300_sds_field_r(sds, 0x4, 1, 2, 2); - mdelay(1); - latch_sts = rtl9300_sds_field_r(sds, 0x4, 1, 2, 2); - if (latch_sts) { - rtl9300_do_rx_calibration_dfe_disable(sds); - rtl9300_do_rx_calibration_4(sds); - rtl9300_do_rx_calibration_5(sds, phy_mode); - } - } -} - -int rtl9300_sds_sym_err_reset(int sds_num, phy_interface_t phy_mode) -{ - switch (phy_mode) { - case PHY_INTERFACE_MODE_XGMII: - break; - - case PHY_INTERFACE_MODE_10GBASER: - /* Read twice to clear */ - rtl930x_read_sds_phy(sds_num, 5, 1); - rtl930x_read_sds_phy(sds_num, 5, 1); - break; - - case PHY_INTERFACE_MODE_1000BASEX: - rtl9300_sds_field_w(sds_num, 0x1, 24, 2, 0, 0); - rtl9300_sds_field_w(sds_num, 0x1, 3, 15, 8, 0); - rtl9300_sds_field_w(sds_num, 0x1, 2, 15, 0, 0); - break; - - default: - pr_info("%s unsupported phy mode\n", __func__); - return -1; - } - - return 0; -} - -u32 rtl9300_sds_sym_err_get(int sds_num, phy_interface_t phy_mode) -{ - u32 v = 0; - - switch (phy_mode) { - case PHY_INTERFACE_MODE_XGMII: - break; - - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_10GBASER: - v = rtl930x_read_sds_phy(sds_num, 5, 1); - return v & 0xff; - - default: - pr_info("%s unsupported PHY-mode\n", __func__); - } - - return v; -} - -int rtl9300_sds_check_calibration(int sds_num, phy_interface_t phy_mode) -{ - u32 errors1, errors2; - - rtl9300_sds_sym_err_reset(sds_num, phy_mode); - rtl9300_sds_sym_err_reset(sds_num, phy_mode); - - /* Count errors during 1ms */ - errors1 = rtl9300_sds_sym_err_get(sds_num, phy_mode); - mdelay(1); - errors2 = rtl9300_sds_sym_err_get(sds_num, phy_mode); - - switch (phy_mode) { - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_XGMII: - if ((errors2 - errors1 > 100) || - (errors1 >= 0xffff00) || (errors2 >= 0xffff00)) { - pr_info("%s XSGMII error rate too high\n", __func__); - return 1; - } - break; - case PHY_INTERFACE_MODE_10GBASER: - if (errors2 > 0) { - pr_info("%s 10GBASER error rate too high\n", __func__); - return 1; - } - break; - default: - return 1; - } - - return 0; -} - -void rtl9300_phy_enable_10g_1g(int sds_num) -{ - u32 v; - - /* Enable 1GBit PHY */ - v = rtl930x_read_sds_phy(sds_num, PHY_PAGE_2, MII_BMCR); - pr_info("%s 1gbit phy: %08x\n", __func__, v); - v &= ~BMCR_PDOWN; - rtl930x_write_sds_phy(sds_num, PHY_PAGE_2, MII_BMCR, v); - pr_info("%s 1gbit phy enabled: %08x\n", __func__, v); - - /* Enable 10GBit PHY */ - v = rtl930x_read_sds_phy(sds_num, PHY_PAGE_4, MII_BMCR); - pr_info("%s 10gbit phy: %08x\n", __func__, v); - v &= ~BMCR_PDOWN; - rtl930x_write_sds_phy(sds_num, PHY_PAGE_4, MII_BMCR, v); - pr_info("%s 10gbit phy after: %08x\n", __func__, v); - - /* dal_longan_construct_mac_default_10gmedia_fiber */ - v = rtl930x_read_sds_phy(sds_num, 0x1f, 11); - pr_info("%s set medium: %08x\n", __func__, v); - v |= BIT(1); - rtl930x_write_sds_phy(sds_num, 0x1f, 11, v); - pr_info("%s set medium after: %08x\n", __func__, v); -} - -static int rtl9300_sds_10g_idle(int sds_num); -static void rtl9300_serdes_patch(int sds_num); - -#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C) -int rtl9300_serdes_setup(int port, int sds_num, phy_interface_t phy_mode) -{ - int calib_tries = 0; - - /* Turn Off Serdes */ - rtl9300_sds_rst(sds_num, RTL930X_SDS_OFF); - - /* Apply serdes patches */ - rtl9300_serdes_patch(sds_num); - - /* Maybe use dal_longan_sds_init */ - - /* dal_longan_construct_serdesConfig_init */ /* Serdes Construct */ - rtl9300_phy_enable_10g_1g(sds_num); - - /* Disable MAC */ - sw_w32_mask(0, 1, RTL930X_MAC_FORCE_MODE_CTRL + 4 * port); - mdelay(20); - - /* ----> dal_longan_sds_mode_set */ - pr_info("%s: Configuring RTL9300 SERDES %d\n", __func__, sds_num); - - /* Configure link to MAC */ - rtl9300_serdes_mac_link_config(sds_num, true, true); /* MAC Construct */ - - /* Re-Enable MAC */ - sw_w32_mask(1, 0, RTL930X_MAC_FORCE_MODE_CTRL + 4 * port); - - /* Enable SDS in desired mode */ - rtl9300_force_sds_mode(sds_num, phy_mode); - - /* Enable Fiber RX */ - rtl9300_sds_field_w(sds_num, 0x20, 2, 12, 12, 0); - - /* Calibrate SerDes receiver in loopback mode */ - rtl9300_sds_10g_idle(sds_num); - do { - rtl9300_do_rx_calibration(sds_num, phy_mode); - calib_tries++; - mdelay(50); - } while (rtl9300_sds_check_calibration(sds_num, phy_mode) && calib_tries < 3); - if (calib_tries >= 3) - pr_warn("%s: SerDes RX calibration failed\n", __func__); - - /* Leave loopback mode */ - rtl9300_sds_tx_config(sds_num, phy_mode); - - return 0; -} - -static int rtl9300_sds_10g_idle(int sds_num) -{ - bool busy; - int i = 0; - - do { - if (sds_num % 2) { - rtl9300_sds_field_w(sds_num - 1, 0x1f, 0x2, 15, 0, 53); - busy = !!rtl9300_sds_field_r(sds_num - 1, 0x1f, 0x14, 1, 1); - } else { - rtl9300_sds_field_w(sds_num, 0x1f, 0x2, 15, 0, 53); - busy = !!rtl9300_sds_field_r(sds_num, 0x1f, 0x14, 0, 0); - } - i++; - } while (busy && i < 100); - - if (i < 100) - return 0; - - pr_warn("%s WARNING: Waiting for RX idle timed out, SDS %d\n", __func__, sds_num); - return -EIO; -} - -typedef struct { - u8 page; - u8 reg; - u16 data; -} sds_config; - -sds_config rtl9300_a_sds_10gr_lane0[] = -{ - /* 1G */ - {0x00, 0x0E, 0x3053}, {0x01, 0x14, 0x0100}, {0x21, 0x03, 0x8206}, - {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010}, {0x21, 0x07, 0xF09F}, - {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009}, {0x21, 0x0E, 0x0000}, - {0x21, 0x0F, 0x0008}, {0x24, 0x00, 0x0668}, {0x24, 0x02, 0xD020}, - {0x24, 0x06, 0xC000}, {0x24, 0x0B, 0x1892}, {0x24, 0x0F, 0xFFDF}, - {0x24, 0x12, 0x03C4}, {0x24, 0x13, 0x027F}, {0x24, 0x14, 0x1311}, - {0x24, 0x16, 0x00C9}, {0x24, 0x17, 0xA100}, {0x24, 0x1A, 0x0001}, - {0x24, 0x1C, 0x0400}, {0x25, 0x01, 0x0300}, {0x25, 0x02, 0x1017}, - {0x25, 0x03, 0xFFDF}, {0x25, 0x05, 0x7F7C}, {0x25, 0x07, 0x8100}, - {0x25, 0x08, 0x0001}, {0x25, 0x09, 0xFFD4}, {0x25, 0x0A, 0x7C2F}, - {0x25, 0x0E, 0x003F}, {0x25, 0x0F, 0x0121}, {0x25, 0x10, 0x0020}, - {0x25, 0x11, 0x8840}, {0x2B, 0x13, 0x0050}, {0x2B, 0x18, 0x8E88}, - {0x2B, 0x19, 0x4902}, {0x2B, 0x1D, 0x2501}, {0x2D, 0x13, 0x0050}, - {0x2D, 0x18, 0x8E88}, {0x2D, 0x19, 0x4902}, {0x2D, 0x1D, 0x2641}, - {0x2F, 0x13, 0x0050}, {0x2F, 0x18, 0x8E88}, {0x2F, 0x19, 0x4902}, - {0x2F, 0x1D, 0x66E1}, - /* 3.125G */ - {0x28, 0x00, 0x0668}, {0x28, 0x02, 0xD020}, {0x28, 0x06, 0xC000}, - {0x28, 0x0B, 0x1892}, {0x28, 0x0F, 0xFFDF}, {0x28, 0x12, 0x01C4}, - {0x28, 0x13, 0x027F}, {0x28, 0x14, 0x1311}, {0x28, 0x16, 0x00C9}, - {0x28, 0x17, 0xA100}, {0x28, 0x1A, 0x0001}, {0x28, 0x1C, 0x0400}, - {0x29, 0x01, 0x0300}, {0x29, 0x02, 0x1017}, {0x29, 0x03, 0xFFDF}, - {0x29, 0x05, 0x7F7C}, {0x29, 0x07, 0x8100}, {0x29, 0x08, 0x0001}, - {0x29, 0x09, 0xFFD4}, {0x29, 0x0A, 0x7C2F}, {0x29, 0x0E, 0x003F}, - {0x29, 0x0F, 0x0121}, {0x29, 0x10, 0x0020}, {0x29, 0x11, 0x8840}, - /* 10G */ - {0x06, 0x0D, 0x0F00}, {0x06, 0x00, 0x0000}, {0x06, 0x01, 0xC800}, - {0x21, 0x03, 0x8206}, {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010}, - {0x21, 0x07, 0xF09F}, {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009}, - {0x21, 0x0E, 0x0000}, {0x21, 0x0F, 0x0008}, {0x2E, 0x00, 0xA668}, - {0x2E, 0x02, 0xD020}, {0x2E, 0x06, 0xC000}, {0x2E, 0x0B, 0x1892}, - {0x2E, 0x0F, 0xFFDF}, {0x2E, 0x11, 0x8280}, {0x2E, 0x12, 0x0044}, - {0x2E, 0x13, 0x027F}, {0x2E, 0x14, 0x1311}, {0x2E, 0x17, 0xA100}, - {0x2E, 0x1A, 0x0001}, {0x2E, 0x1C, 0x0400}, {0x2F, 0x01, 0x0300}, - {0x2F, 0x02, 0x1217}, {0x2F, 0x03, 0xFFDF}, {0x2F, 0x05, 0x7F7C}, - {0x2F, 0x07, 0x80C4}, {0x2F, 0x08, 0x0001}, {0x2F, 0x09, 0xFFD4}, - {0x2F, 0x0A, 0x7C2F}, {0x2F, 0x0E, 0x003F}, {0x2F, 0x0F, 0x0121}, - {0x2F, 0x10, 0x0020}, {0x2F, 0x11, 0x8840}, {0x2F, 0x14, 0xE008}, - {0x2B, 0x13, 0x0050}, {0x2B, 0x18, 0x8E88}, {0x2B, 0x19, 0x4902}, - {0x2B, 0x1D, 0x2501}, {0x2D, 0x13, 0x0050}, {0x2D, 0x17, 0x4109}, - {0x2D, 0x18, 0x8E88}, {0x2D, 0x19, 0x4902}, {0x2D, 0x1C, 0x1109}, - {0x2D, 0x1D, 0x2641}, {0x2F, 0x13, 0x0050}, {0x2F, 0x18, 0x8E88}, - {0x2F, 0x19, 0x4902}, {0x2F, 0x1D, 0x76E1}, -}; - -sds_config rtl9300_a_sds_10gr_lane1[] = -{ - /* 1G */ - {0x00, 0x0E, 0x3053}, {0x01, 0x14, 0x0100}, {0x21, 0x03, 0x8206}, - {0x21, 0x06, 0x0010}, {0x21, 0x07, 0xF09F}, {0x21, 0x0A, 0x0003}, - {0x21, 0x0B, 0x0005}, {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009}, - {0x21, 0x0E, 0x0000}, {0x21, 0x0F, 0x0008}, {0x24, 0x00, 0x0668}, - {0x24, 0x02, 0xD020}, {0x24, 0x06, 0xC000}, {0x24, 0x0B, 0x1892}, - {0x24, 0x0F, 0xFFDF}, {0x24, 0x12, 0x03C4}, {0x24, 0x13, 0x027F}, - {0x24, 0x14, 0x1311}, {0x24, 0x16, 0x00C9}, {0x24, 0x17, 0xA100}, - {0x24, 0x1A, 0x0001}, {0x24, 0x1C, 0x0400}, {0x25, 0x00, 0x820F}, - {0x25, 0x01, 0x0300}, {0x25, 0x02, 0x1017}, {0x25, 0x03, 0xFFDF}, - {0x25, 0x05, 0x7F7C}, {0x25, 0x07, 0x8100}, {0x25, 0x08, 0x0001}, - {0x25, 0x09, 0xFFD4}, {0x25, 0x0A, 0x7C2F}, {0x25, 0x0E, 0x003F}, - {0x25, 0x0F, 0x0121}, {0x25, 0x10, 0x0020}, {0x25, 0x11, 0x8840}, - {0x2B, 0x13, 0x3D87}, {0x2B, 0x14, 0x3108}, {0x2D, 0x13, 0x3C87}, - {0x2D, 0x14, 0x1808}, - /* 3.125G */ - {0x28, 0x00, 0x0668}, {0x28, 0x02, 0xD020}, {0x28, 0x06, 0xC000}, - {0x28, 0x0B, 0x1892}, {0x28, 0x0F, 0xFFDF}, {0x28, 0x12, 0x01C4}, - {0x28, 0x13, 0x027F}, {0x28, 0x14, 0x1311}, {0x28, 0x16, 0x00C9}, - {0x28, 0x17, 0xA100}, {0x28, 0x1A, 0x0001}, {0x28, 0x1C, 0x0400}, - {0x29, 0x00, 0x820F}, {0x29, 0x01, 0x0300}, {0x29, 0x02, 0x1017}, - {0x29, 0x03, 0xFFDF}, {0x29, 0x05, 0x7F7C}, {0x29, 0x07, 0x8100}, - {0x29, 0x08, 0x0001}, {0x29, 0x0A, 0x7C2F}, {0x29, 0x0E, 0x003F}, - {0x29, 0x0F, 0x0121}, {0x29, 0x10, 0x0020}, {0x29, 0x11, 0x8840}, - /* 10G */ - {0x06, 0x0D, 0x0F00}, {0x06, 0x00, 0x0000}, {0x06, 0x01, 0xC800}, - {0x21, 0x03, 0x8206}, {0x21, 0x05, 0x40B0}, {0x21, 0x06, 0x0010}, - {0x21, 0x07, 0xF09F}, {0x21, 0x0A, 0x0003}, {0x21, 0x0B, 0x0005}, - {0x21, 0x0C, 0x0007}, {0x21, 0x0D, 0x6009}, {0x21, 0x0E, 0x0000}, - {0x21, 0x0F, 0x0008}, {0x2E, 0x00, 0xA668}, {0x2E, 0x02, 0xD020}, - {0x2E, 0x06, 0xC000}, {0x2E, 0x0B, 0x1892}, {0x2E, 0x0F, 0xFFDF}, - {0x2E, 0x11, 0x8280}, {0x2E, 0x12, 0x0044}, {0x2E, 0x13, 0x027F}, - {0x2E, 0x14, 0x1311}, {0x2E, 0x17, 0xA100}, {0x2E, 0x1A, 0x0001}, - {0x2E, 0x1C, 0x0400}, {0x2F, 0x00, 0x820F}, {0x2F, 0x01, 0x0300}, - {0x2F, 0x02, 0x1217}, {0x2F, 0x03, 0xFFDF}, {0x2F, 0x05, 0x7F7C}, - {0x2F, 0x07, 0x80C4}, {0x2F, 0x08, 0x0001}, {0x2F, 0x09, 0xFFD4}, - {0x2F, 0x0A, 0x7C2F}, {0x2F, 0x0E, 0x003F}, {0x2F, 0x0F, 0x0121}, - {0x2F, 0x10, 0x0020}, {0x2F, 0x11, 0x8840}, {0x2B, 0x13, 0x3D87}, - {0x2B, 0x14, 0x3108}, {0x2D, 0x13, 0x3C87}, {0x2D, 0x14, 0x1808}, -}; - -static void rtl9300_serdes_patch(int sds_num) -{ - if (sds_num % 2) { - for (int i = 0; i < sizeof(rtl9300_a_sds_10gr_lane1) / sizeof(sds_config); ++i) { - rtl930x_write_sds_phy(sds_num, rtl9300_a_sds_10gr_lane1[i].page, - rtl9300_a_sds_10gr_lane1[i].reg, - rtl9300_a_sds_10gr_lane1[i].data); - } - } else { - for (int i = 0; i < sizeof(rtl9300_a_sds_10gr_lane0) / sizeof(sds_config); ++i) { - rtl930x_write_sds_phy(sds_num, rtl9300_a_sds_10gr_lane0[i].page, - rtl9300_a_sds_10gr_lane0[i].reg, - rtl9300_a_sds_10gr_lane0[i].data); - } - } -} - -int rtl9300_sds_cmu_band_get(int sds) -{ - u32 page; - u32 en; - u32 cmu_band; - -/* page = rtl9300_sds_cmu_page_get(sds); */ - page = 0x25; /* 10GR and 1000BX */ - sds = (sds % 2) ? (sds - 1) : (sds); - - rtl9300_sds_field_w(sds, page, 0x1c, 15, 15, 1); - rtl9300_sds_field_w(sds + 1, page, 0x1c, 15, 15, 1); - - en = rtl9300_sds_field_r(sds, page, 27, 1, 1); - if(!en) { /* Auto mode */ - rtl930x_write_sds_phy(sds, 0x1f, 0x02, 31); - - cmu_band = rtl9300_sds_field_r(sds, 0x1f, 0x15, 5, 1); - } else { - cmu_band = rtl9300_sds_field_r(sds, page, 30, 4, 0); - } - - return cmu_band; -} - -void rtl9310_sds_field_w(int sds, u32 page, u32 reg, int end_bit, int start_bit, u32 v) -{ - int l = end_bit - start_bit + 1; - u32 data = v; - - if (l < 32) { - u32 mask = BIT(l) - 1; - - data = rtl930x_read_sds_phy(sds, page, reg); - data &= ~(mask << start_bit); - data |= (v & mask) << start_bit; - } - - rtl931x_write_sds_phy(sds, page, reg, data); -} - -u32 rtl9310_sds_field_r(int sds, u32 page, u32 reg, int end_bit, int start_bit) -{ - int l = end_bit - start_bit + 1; - u32 v = rtl931x_read_sds_phy(sds, page, reg); - - if (l >= 32) - return v; - - return (v >> start_bit) & (BIT(l) - 1); -} - -static void rtl931x_sds_rst(u32 sds) -{ - u32 o, v, o_mode; - int shift = ((sds & 0x3) << 3); - - /* TODO: We need to lock this! */ - - o = sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR); - v = o | BIT(sds); - sw_w32(v, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR); - - o_mode = sw_r32(RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2)); - v = BIT(7) | 0x1F; - sw_w32_mask(0xff << shift, v << shift, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2)); - sw_w32(o_mode, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2)); - - sw_w32(o, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR); -} - -static void rtl931x_symerr_clear(u32 sds, phy_interface_t mode) -{ - - switch (mode) { - case PHY_INTERFACE_MODE_NA: - break; - case PHY_INTERFACE_MODE_XGMII: - u32 xsg_sdsid_0, xsg_sdsid_1; - - if (sds < 2) - xsg_sdsid_0 = sds; - else - xsg_sdsid_0 = (sds - 1) * 2; - xsg_sdsid_1 = xsg_sdsid_0 + 1; - - for (int i = 0; i < 4; ++i) { - rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 24, 2, 0, i); - rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 3, 15, 8, 0x0); - rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 2, 15, 0, 0x0); - } - - for (int i = 0; i < 4; ++i) { - rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 24, 2, 0, i); - rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 3, 15, 8, 0x0); - rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 2, 15, 0, 0x0); - } - - rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 0, 15, 0, 0x0); - rtl9310_sds_field_w(xsg_sdsid_0, 0x1, 1, 15, 8, 0x0); - rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 0, 15, 0, 0x0); - rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 1, 15, 8, 0x0); - break; - default: - break; - } - - return; -} - -static u32 rtl931x_get_analog_sds(u32 sds) -{ - u32 sds_map[] = { 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23 }; - - if (sds < 14) - return sds_map[sds]; - - return sds; -} - -void rtl931x_sds_fiber_disable(u32 sds) -{ - u32 v = 0x3F; - u32 asds = rtl931x_get_analog_sds(sds); - - rtl9310_sds_field_w(asds, 0x1F, 0x9, 11, 6, v); -} - -static void rtl931x_sds_fiber_mode_set(u32 sds, phy_interface_t mode) -{ - u32 val, asds = rtl931x_get_analog_sds(sds); - - /* clear symbol error count before changing mode */ - rtl931x_symerr_clear(sds, mode); - - val = 0x9F; - sw_w32(val, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2)); - - switch (mode) { - case PHY_INTERFACE_MODE_SGMII: - val = 0x5; - break; - - case PHY_INTERFACE_MODE_1000BASEX: - /* serdes mode FIBER1G */ - val = 0x9; - break; - - case PHY_INTERFACE_MODE_10GBASER: - case PHY_INTERFACE_MODE_10GKR: - val = 0x35; - break; -/* case MII_10GR1000BX_AUTO: - val = 0x39; - break; */ - - - case PHY_INTERFACE_MODE_USXGMII: - val = 0x1B; - break; - default: - val = 0x25; - } - - pr_info("%s writing analog SerDes Mode value %02x\n", __func__, val); - rtl9310_sds_field_w(asds, 0x1F, 0x9, 11, 6, val); - - return; -} - -static int rtl931x_sds_cmu_page_get(phy_interface_t mode) -{ - switch (mode) { - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_1000BASEX: /* MII_1000BX_FIBER / 100BX_FIBER / 1000BX100BX_AUTO */ - return 0x24; - case PHY_INTERFACE_MODE_HSGMII: - case PHY_INTERFACE_MODE_2500BASEX: /* MII_2500Base_X: */ - return 0x28; -/* case MII_HISGMII_5G: */ -/* return 0x2a; */ - case PHY_INTERFACE_MODE_QSGMII: - return 0x2a; /* Code also has 0x34 */ - case PHY_INTERFACE_MODE_XAUI: /* MII_RXAUI_LITE: */ - return 0x2c; - case PHY_INTERFACE_MODE_XGMII: /* MII_XSGMII */ - case PHY_INTERFACE_MODE_10GKR: - case PHY_INTERFACE_MODE_10GBASER: /* MII_10GR */ - return 0x2e; - default: - return -1; - } - - return -1; -} - -static void rtl931x_cmu_type_set(u32 asds, phy_interface_t mode, int chiptype) -{ - int cmu_type = 0; /* Clock Management Unit */ - u32 cmu_page = 0; - u32 frc_cmu_spd; - u32 evenSds; - u32 lane, frc_lc_mode_bitnum, frc_lc_mode_val_bitnum; - - switch (mode) { - case PHY_INTERFACE_MODE_NA: - case PHY_INTERFACE_MODE_10GKR: - case PHY_INTERFACE_MODE_XGMII: - case PHY_INTERFACE_MODE_10GBASER: - case PHY_INTERFACE_MODE_USXGMII: - return; - -/* case MII_10GR1000BX_AUTO: - if (chiptype) - rtl9310_sds_field_w(asds, 0x24, 0xd, 14, 14, 0); - return; */ - - case PHY_INTERFACE_MODE_QSGMII: - cmu_type = 1; - frc_cmu_spd = 0; - break; - - case PHY_INTERFACE_MODE_HSGMII: - cmu_type = 1; - frc_cmu_spd = 1; - break; - - case PHY_INTERFACE_MODE_1000BASEX: - cmu_type = 1; - frc_cmu_spd = 0; - break; - -/* case MII_1000BX100BX_AUTO: - cmu_type = 1; - frc_cmu_spd = 0; - break; */ - - case PHY_INTERFACE_MODE_SGMII: - cmu_type = 1; - frc_cmu_spd = 0; - break; - - case PHY_INTERFACE_MODE_2500BASEX: - cmu_type = 1; - frc_cmu_spd = 1; - break; - - default: - pr_info("SerDes %d mode is invalid\n", asds); - return; - } - - if (cmu_type == 1) - cmu_page = rtl931x_sds_cmu_page_get(mode); - - lane = asds % 2; - - if (!lane) { - frc_lc_mode_bitnum = 4; - frc_lc_mode_val_bitnum = 5; - } else { - frc_lc_mode_bitnum = 6; - frc_lc_mode_val_bitnum = 7; - } - - evenSds = asds - lane; - - pr_info("%s: cmu_type %0d cmu_page %x frc_cmu_spd %d lane %d asds %d\n", - __func__, cmu_type, cmu_page, frc_cmu_spd, lane, asds); - - if (cmu_type == 1) { - pr_info("%s A CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7)); - rtl9310_sds_field_w(asds, cmu_page, 0x7, 15, 15, 0); - pr_info("%s B CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7)); - if (chiptype) { - rtl9310_sds_field_w(asds, cmu_page, 0xd, 14, 14, 0); - } - - rtl9310_sds_field_w(evenSds, 0x20, 0x12, 3, 2, 0x3); - rtl9310_sds_field_w(evenSds, 0x20, 0x12, frc_lc_mode_bitnum, frc_lc_mode_bitnum, 1); - rtl9310_sds_field_w(evenSds, 0x20, 0x12, frc_lc_mode_val_bitnum, frc_lc_mode_val_bitnum, 0); - rtl9310_sds_field_w(evenSds, 0x20, 0x12, 12, 12, 1); - rtl9310_sds_field_w(evenSds, 0x20, 0x12, 15, 13, frc_cmu_spd); - } - - pr_info("%s CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7)); - return; -} - -static void rtl931x_sds_rx_rst(u32 sds) -{ - u32 asds = rtl931x_get_analog_sds(sds); - - if (sds < 2) - return; - - rtl931x_write_sds_phy(asds, 0x2e, 0x12, 0x2740); - rtl931x_write_sds_phy(asds, 0x2f, 0x0, 0x0); - rtl931x_write_sds_phy(asds, 0x2f, 0x2, 0x2010); - rtl931x_write_sds_phy(asds, 0x20, 0x0, 0xc10); - - rtl931x_write_sds_phy(asds, 0x2e, 0x12, 0x27c0); - rtl931x_write_sds_phy(asds, 0x2f, 0x0, 0xc000); - rtl931x_write_sds_phy(asds, 0x2f, 0x2, 0x6010); - rtl931x_write_sds_phy(asds, 0x20, 0x0, 0xc30); - - mdelay(50); -} - -// Currently not used -// static void rtl931x_sds_disable(u32 sds) -// { -// u32 v = 0x1f; - -// v |= BIT(7); -// sw_w32(v, RTL931X_SERDES_MODE_CTRL + (sds >> 2) * 4); -// } - -static void rtl931x_sds_mii_mode_set(u32 sds, phy_interface_t mode) -{ - u32 val; - - switch (mode) { - case PHY_INTERFACE_MODE_QSGMII: - val = 0x6; - break; - case PHY_INTERFACE_MODE_XGMII: - val = 0x10; /* serdes mode XSGMII */ - break; - case PHY_INTERFACE_MODE_USXGMII: - case PHY_INTERFACE_MODE_2500BASEX: - val = 0xD; - break; - case PHY_INTERFACE_MODE_HSGMII: - val = 0x12; - break; - case PHY_INTERFACE_MODE_SGMII: - val = 0x2; - break; - default: - return; - } - - val |= (1 << 7); - - sw_w32(val, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2)); -} - -static sds_config sds_config_10p3125g_type1[] = { - { 0x2E, 0x00, 0x0107 }, { 0x2E, 0x01, 0x01A3 }, { 0x2E, 0x02, 0x6A24 }, - { 0x2E, 0x03, 0xD10D }, { 0x2E, 0x04, 0x8000 }, { 0x2E, 0x05, 0xA17E }, - { 0x2E, 0x06, 0xE31D }, { 0x2E, 0x07, 0x800E }, { 0x2E, 0x08, 0x0294 }, - { 0x2E, 0x09, 0x0CE4 }, { 0x2E, 0x0A, 0x7FC8 }, { 0x2E, 0x0B, 0xE0E7 }, - { 0x2E, 0x0C, 0x0200 }, { 0x2E, 0x0D, 0xDF80 }, { 0x2E, 0x0E, 0x0000 }, - { 0x2E, 0x0F, 0x1FC2 }, { 0x2E, 0x10, 0x0C3F }, { 0x2E, 0x11, 0x0000 }, - { 0x2E, 0x12, 0x27C0 }, { 0x2E, 0x13, 0x7E1D }, { 0x2E, 0x14, 0x1300 }, - { 0x2E, 0x15, 0x003F }, { 0x2E, 0x16, 0xBE7F }, { 0x2E, 0x17, 0x0090 }, - { 0x2E, 0x18, 0x0000 }, { 0x2E, 0x19, 0x4000 }, { 0x2E, 0x1A, 0x0000 }, - { 0x2E, 0x1B, 0x8000 }, { 0x2E, 0x1C, 0x011F }, { 0x2E, 0x1D, 0x0000 }, - { 0x2E, 0x1E, 0xC8FF }, { 0x2E, 0x1F, 0x0000 }, { 0x2F, 0x00, 0xC000 }, - { 0x2F, 0x01, 0xF000 }, { 0x2F, 0x02, 0x6010 }, { 0x2F, 0x12, 0x0EE7 }, - { 0x2F, 0x13, 0x0000 } -}; - -static sds_config sds_config_10p3125g_cmu_type1[] = { - { 0x2F, 0x03, 0x4210 }, { 0x2F, 0x04, 0x0000 }, { 0x2F, 0x05, 0x0019 }, - { 0x2F, 0x06, 0x18A6 }, { 0x2F, 0x07, 0x2990 }, { 0x2F, 0x08, 0xFFF4 }, - { 0x2F, 0x09, 0x1F08 }, { 0x2F, 0x0A, 0x0000 }, { 0x2F, 0x0B, 0x8000 }, - { 0x2F, 0x0C, 0x4224 }, { 0x2F, 0x0D, 0x0000 }, { 0x2F, 0x0E, 0x0000 }, - { 0x2F, 0x0F, 0xA470 }, { 0x2F, 0x10, 0x8000 }, { 0x2F, 0x11, 0x037B } -}; - -void rtl931x_sds_init(u32 sds, phy_interface_t mode) -{ - u32 board_sds_tx_type1[] = { - 0x01c3, 0x01c3, 0x01c3, 0x01a3, 0x01a3, 0x01a3, - 0x0143, 0x0143, 0x0143, 0x0143, 0x0163, 0x0163, - }; - u32 board_sds_tx[] = { - 0x1a00, 0x1a00, 0x0200, 0x0200, 0x0200, 0x0200, - 0x01a3, 0x01a3, 0x01a3, 0x01a3, 0x01e3, 0x01e3 - }; - u32 board_sds_tx2[] = { - 0x0dc0, 0x01c0, 0x0200, 0x0180, 0x0160, 0x0123, - 0x0123, 0x0163, 0x01a3, 0x01a0, 0x01c3, 0x09c3, - }; - u32 asds, dSds, ori, model_info, val; - int chiptype = 0; - - asds = rtl931x_get_analog_sds(sds); - - if (sds > 13) - return; - - pr_info("%s: set sds %d to mode %d\n", __func__, sds, mode); - val = rtl9310_sds_field_r(asds, 0x1F, 0x9, 11, 6); - - pr_info("%s: fibermode %08X stored mode 0x%x analog SDS %d", __func__, - rtl931x_read_sds_phy(asds, 0x1f, 0x9), val, asds); - pr_info("%s: SGMII mode %08X in 0x24 0x9 analog SDS %d", __func__, - rtl931x_read_sds_phy(asds, 0x24, 0x9), asds); - pr_info("%s: CMU mode %08X stored even SDS %d", __func__, - rtl931x_read_sds_phy(asds & ~1, 0x20, 0x12), asds & ~1); - pr_info("%s: serdes_mode_ctrl %08X", __func__, RTL931X_SERDES_MODE_CTRL + 4 * (sds >> 2)); - pr_info("%s CMU page 0x24 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x24, 0x7)); - pr_info("%s CMU page 0x26 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x26, 0x7)); - pr_info("%s CMU page 0x28 0x7 %08x\n", __func__, rtl931x_read_sds_phy(asds, 0x28, 0x7)); - pr_info("%s XSG page 0x0 0xe %08x\n", __func__, rtl931x_read_sds_phy(dSds, 0x0, 0xe)); - pr_info("%s XSG2 page 0x0 0xe %08x\n", __func__, rtl931x_read_sds_phy(dSds + 1, 0x0, 0xe)); - - model_info = sw_r32(RTL93XX_MODEL_NAME_INFO); - if ((model_info >> 4) & 0x1) { - pr_info("detected chiptype 1\n"); - chiptype = 1; - } else { - pr_info("detected chiptype 0\n"); - } - - if (sds < 2) - dSds = sds; - else - dSds = (sds - 1) * 2; - - pr_info("%s: 2.5gbit %08X dsds %d", __func__, - rtl931x_read_sds_phy(dSds, 0x1, 0x14), dSds); - - pr_info("%s: RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR 0x%08X\n", __func__, sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR)); - ori = sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR); - val = ori | (1 << sds); - sw_w32(val, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR); - - switch (mode) { - case PHY_INTERFACE_MODE_NA: - break; - - case PHY_INTERFACE_MODE_XGMII: /* MII_XSGMII */ - - if (chiptype) { - u32 xsg_sdsid_1; - xsg_sdsid_1 = dSds + 1; - /* fifo inv clk */ - rtl9310_sds_field_w(dSds, 0x1, 0x1, 7, 4, 0xf); - rtl9310_sds_field_w(dSds, 0x1, 0x1, 3, 0, 0xf); - - rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 0x1, 7, 4, 0xf); - rtl9310_sds_field_w(xsg_sdsid_1, 0x1, 0x1, 3, 0, 0xf); - - } - - rtl9310_sds_field_w(dSds, 0x0, 0xE, 12, 12, 1); - rtl9310_sds_field_w(dSds + 1, 0x0, 0xE, 12, 12, 1); - break; - - case PHY_INTERFACE_MODE_USXGMII: /* MII_USXGMII_10GSXGMII/10GDXGMII/10GQXGMII: */ - u32 op_code = 0x6003; - u32 evenSds; - - if (chiptype) { - rtl9310_sds_field_w(asds, 0x6, 0x2, 12, 12, 1); - - for (int i = 0; i < sizeof(sds_config_10p3125g_type1) / sizeof(sds_config); ++i) { - rtl931x_write_sds_phy(asds, sds_config_10p3125g_type1[i].page - 0x4, sds_config_10p3125g_type1[i].reg, sds_config_10p3125g_type1[i].data); - } - - evenSds = asds - (asds % 2); - - for (int i = 0; i < sizeof(sds_config_10p3125g_cmu_type1) / sizeof(sds_config); ++i) { - rtl931x_write_sds_phy(evenSds, - sds_config_10p3125g_cmu_type1[i].page - 0x4, sds_config_10p3125g_cmu_type1[i].reg, sds_config_10p3125g_cmu_type1[i].data); - } - - rtl9310_sds_field_w(asds, 0x6, 0x2, 12, 12, 0); - } else { - - rtl9310_sds_field_w(asds, 0x2e, 0xd, 6, 0, 0x0); - rtl9310_sds_field_w(asds, 0x2e, 0xd, 7, 7, 0x1); - - rtl9310_sds_field_w(asds, 0x2e, 0x1c, 5, 0, 0x1E); - rtl9310_sds_field_w(asds, 0x2e, 0x1d, 11, 0, 0x00); - rtl9310_sds_field_w(asds, 0x2e, 0x1f, 11, 0, 0x00); - rtl9310_sds_field_w(asds, 0x2f, 0x0, 11, 0, 0x00); - rtl9310_sds_field_w(asds, 0x2f, 0x1, 11, 0, 0x00); - - rtl9310_sds_field_w(asds, 0x2e, 0xf, 12, 6, 0x7F); - rtl931x_write_sds_phy(asds, 0x2f, 0x12, 0xaaa); - - rtl931x_sds_rx_rst(sds); - - rtl931x_write_sds_phy(asds, 0x7, 0x10, op_code); - rtl931x_write_sds_phy(asds, 0x6, 0x1d, 0x0480); - rtl931x_write_sds_phy(asds, 0x6, 0xe, 0x0400); - } - break; - - case PHY_INTERFACE_MODE_10GBASER: /* MII_10GR / MII_10GR1000BX_AUTO: */ - /* configure 10GR fiber mode=1 */ - rtl9310_sds_field_w(asds, 0x1f, 0xb, 1, 1, 1); - - /* init fiber_1g */ - rtl9310_sds_field_w(dSds, 0x3, 0x13, 15, 14, 0); - - rtl9310_sds_field_w(dSds, 0x2, 0x0, 12, 12, 1); - rtl9310_sds_field_w(dSds, 0x2, 0x0, 6, 6, 1); - rtl9310_sds_field_w(dSds, 0x2, 0x0, 13, 13, 0); - - /* init auto */ - rtl9310_sds_field_w(asds, 0x1f, 13, 15, 0, 0x109e); - rtl9310_sds_field_w(asds, 0x1f, 0x6, 14, 10, 0x8); - rtl9310_sds_field_w(asds, 0x1f, 0x7, 10, 4, 0x7f); - break; - - case PHY_INTERFACE_MODE_HSGMII: - rtl9310_sds_field_w(dSds, 0x1, 0x14, 8, 8, 1); - break; - - case PHY_INTERFACE_MODE_1000BASEX: /* MII_1000BX_FIBER */ - rtl9310_sds_field_w(dSds, 0x3, 0x13, 15, 14, 0); - - rtl9310_sds_field_w(dSds, 0x2, 0x0, 12, 12, 1); - rtl9310_sds_field_w(dSds, 0x2, 0x0, 6, 6, 1); - rtl9310_sds_field_w(dSds, 0x2, 0x0, 13, 13, 0); - break; - - case PHY_INTERFACE_MODE_SGMII: - rtl9310_sds_field_w(asds, 0x24, 0x9, 15, 15, 0); - break; - - case PHY_INTERFACE_MODE_2500BASEX: - rtl9310_sds_field_w(dSds, 0x1, 0x14, 8, 8, 1); - break; - - case PHY_INTERFACE_MODE_QSGMII: - default: - pr_info("%s: PHY mode %s not supported by SerDes %d\n", - __func__, phy_modes(mode), sds); - return; - } - - rtl931x_cmu_type_set(asds, mode, chiptype); - - if (sds >= 2 && sds <= 13) { - if (chiptype) - rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx_type1[sds - 2]); - else { - val = 0xa0000; - sw_w32(val, RTL931X_CHIP_INFO_ADDR); - val = sw_r32(RTL931X_CHIP_INFO_ADDR); - if (val & BIT(28)) /* consider 9311 etc. RTL9313_CHIP_ID == HWP_CHIP_ID(unit)) */ - { - rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx2[sds - 2]); - } else { - rtl931x_write_sds_phy(asds, 0x2E, 0x1, board_sds_tx[sds - 2]); - } - val = 0; - sw_w32(val, RTL931X_CHIP_INFO_ADDR); - } - } - - val = ori & ~BIT(sds); - sw_w32(val, RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR); - pr_debug("%s: RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR 0x%08X\n", __func__, sw_r32(RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR)); - - if (mode == PHY_INTERFACE_MODE_XGMII || - mode == PHY_INTERFACE_MODE_QSGMII || - mode == PHY_INTERFACE_MODE_HSGMII || - mode == PHY_INTERFACE_MODE_SGMII || - mode == PHY_INTERFACE_MODE_USXGMII) { - if (mode == PHY_INTERFACE_MODE_XGMII) - rtl931x_sds_mii_mode_set(sds, mode); - else - rtl931x_sds_fiber_mode_set(sds, mode); - } -} - -int rtl931x_sds_cmu_band_set(int sds, bool enable, u32 band, phy_interface_t mode) -{ - u32 asds; - int page = rtl931x_sds_cmu_page_get(mode); - - sds -= (sds % 2); - sds = sds & ~1; - asds = rtl931x_get_analog_sds(sds); - page += 1; - - if (enable) { - rtl9310_sds_field_w(asds, page, 0x7, 13, 13, 0); - rtl9310_sds_field_w(asds, page, 0x7, 11, 11, 0); - } else { - rtl9310_sds_field_w(asds, page, 0x7, 13, 13, 0); - rtl9310_sds_field_w(asds, page, 0x7, 11, 11, 0); - } - - rtl9310_sds_field_w(asds, page, 0x7, 4, 0, band); - - rtl931x_sds_rst(sds); - - return 0; -} - -int rtl931x_sds_cmu_band_get(int sds, phy_interface_t mode) -{ - int page = rtl931x_sds_cmu_page_get(mode); - u32 asds, band; - - sds -= (sds % 2); - asds = rtl931x_get_analog_sds(sds); - page += 1; - rtl931x_write_sds_phy(asds, 0x1f, 0x02, 73); - - rtl9310_sds_field_w(asds, page, 0x5, 15, 15, 1); - band = rtl9310_sds_field_r(asds, 0x1f, 0x15, 8, 3); - pr_info("%s band is: %d\n", __func__, band); - - return band; -} - - -int rtl931x_link_sts_get(u32 sds) -{ - u32 sts, sts1, latch_sts, latch_sts1; - if (0){ - u32 xsg_sdsid_0, xsg_sdsid_1; - - xsg_sdsid_0 = sds < 2 ? sds : (sds - 1) * 2; - xsg_sdsid_1 = xsg_sdsid_0 + 1; - - sts = rtl9310_sds_field_r(xsg_sdsid_0, 0x1, 29, 8, 0); - sts1 = rtl9310_sds_field_r(xsg_sdsid_1, 0x1, 29, 8, 0); - latch_sts = rtl9310_sds_field_r(xsg_sdsid_0, 0x1, 30, 8, 0); - latch_sts1 = rtl9310_sds_field_r(xsg_sdsid_1, 0x1, 30, 8, 0); - } else { - u32 asds, dsds; - - asds = rtl931x_get_analog_sds(sds); - sts = rtl9310_sds_field_r(asds, 0x5, 0, 12, 12); - latch_sts = rtl9310_sds_field_r(asds, 0x4, 1, 2, 2); - - dsds = sds < 2 ? sds : (sds - 1) * 2; - latch_sts1 = rtl9310_sds_field_r(dsds, 0x2, 1, 2, 2); - sts1 = rtl9310_sds_field_r(dsds, 0x2, 1, 2, 2); - } - - pr_info("%s: serdes %d sts %d, sts1 %d, latch_sts %d, latch_sts1 %d\n", __func__, - sds, sts, sts1, latch_sts, latch_sts1); - - return sts1; -} - -static int rtl8214fc_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) -{ - struct phy_device *phydev = upstream; - - rtl8214fc_media_set(phydev, true); - - return 0; -} - -static void rtl8214fc_sfp_remove(void *upstream) -{ - struct phy_device *phydev = upstream; - - rtl8214fc_media_set(phydev, false); -} - -static const struct sfp_upstream_ops rtl8214fc_sfp_ops = { - .attach = phy_sfp_attach, - .detach = phy_sfp_detach, - .module_insert = rtl8214fc_sfp_insert, - .module_remove = rtl8214fc_sfp_remove, -}; - -static int rtl8214fc_phy_probe(struct phy_device *phydev) -{ - struct device *dev = &phydev->mdio.dev; - int addr = phydev->mdio.addr; - int ret = 0; - - /* 839x has internal SerDes */ - if (soc_info.id == 0x8393) - return -ENODEV; - - /* All base addresses of the PHYs start at multiples of 8 */ - devm_phy_package_join(dev, phydev, addr & (~7), - sizeof(struct rtl83xx_shared_private)); - - if (!(addr % 8)) { - struct rtl83xx_shared_private *shared = phydev->shared->priv; - shared->name = "RTL8214FC"; - /* Configuration must be done while patching still possible */ - ret = rtl8380_configure_rtl8214fc(phydev); - if (ret) - return ret; - } - - return phy_sfp_probe(phydev, &rtl8214fc_sfp_ops); -} - -static int rtl8214c_phy_probe(struct phy_device *phydev) -{ - struct device *dev = &phydev->mdio.dev; - int addr = phydev->mdio.addr; - - /* All base addresses of the PHYs start at multiples of 8 */ - devm_phy_package_join(dev, phydev, addr & (~7), - sizeof(struct rtl83xx_shared_private)); - - if (!(addr % 8)) { - struct rtl83xx_shared_private *shared = phydev->shared->priv; - shared->name = "RTL8214C"; - /* Configuration must be done whil patching still possible */ - return rtl8380_configure_rtl8214c(phydev); - } - - return 0; -} - -static int rtl8218b_ext_phy_probe(struct phy_device *phydev) -{ - struct device *dev = &phydev->mdio.dev; - int addr = phydev->mdio.addr; - - /* All base addresses of the PHYs start at multiples of 8 */ - devm_phy_package_join(dev, phydev, addr & (~7), - sizeof(struct rtl83xx_shared_private)); - - if (!(addr % 8)) { - struct rtl83xx_shared_private *shared = phydev->shared->priv; - shared->name = "RTL8218B (external)"; - if (soc_info.family == RTL8380_FAMILY_ID) { - /* Configuration must be done while patching still possible */ - return rtl8380_configure_ext_rtl8218b(phydev); - } - } - - return 0; -} - -static int rtl8218b_int_phy_probe(struct phy_device *phydev) -{ - struct device *dev = &phydev->mdio.dev; - int addr = phydev->mdio.addr; - - if (soc_info.family != RTL8380_FAMILY_ID) - return -ENODEV; - if (addr >= 24) - return -ENODEV; - - pr_debug("%s: id: %d\n", __func__, addr); - /* All base addresses of the PHYs start at multiples of 8 */ - devm_phy_package_join(dev, phydev, addr & (~7), - sizeof(struct rtl83xx_shared_private)); - - if (!(addr % 8)) { - struct rtl83xx_shared_private *shared = phydev->shared->priv; - shared->name = "RTL8218B (internal)"; - /* Configuration must be done while patching still possible */ - return rtl8380_configure_int_rtl8218b(phydev); - } - - return 0; -} - -static int rtl8218d_phy_probe(struct phy_device *phydev) -{ - struct device *dev = &phydev->mdio.dev; - int addr = phydev->mdio.addr; - - pr_debug("%s: id: %d\n", __func__, addr); - /* All base addresses of the PHYs start at multiples of 8 */ - devm_phy_package_join(dev, phydev, addr & (~7), - sizeof(struct rtl83xx_shared_private)); - - /* All base addresses of the PHYs start at multiples of 8 */ - if (!(addr % 8)) { - struct rtl83xx_shared_private *shared = phydev->shared->priv; - shared->name = "RTL8218D"; - /* Configuration must be done while patching still possible */ -/* TODO: return configure_rtl8218d(phydev); */ - } - - return 0; -} - -static int rtl838x_serdes_probe(struct phy_device *phydev) -{ - int addr = phydev->mdio.addr; - - if (soc_info.family != RTL8380_FAMILY_ID) - return -ENODEV; - if (addr < 24) - return -ENODEV; - - /* On the RTL8380M, PHYs 24-27 connect to the internal SerDes */ - if (soc_info.id == 0x8380) { - if (addr == 24) - return rtl8380_configure_serdes(phydev); - return 0; - } - - return -ENODEV; -} - -static int rtl8393_serdes_probe(struct phy_device *phydev) -{ - int addr = phydev->mdio.addr; - - pr_info("%s: id: %d\n", __func__, addr); - if (soc_info.family != RTL8390_FAMILY_ID) - return -ENODEV; - - if (addr < 24) - return -ENODEV; - - return rtl8390_configure_serdes(phydev); -} - -static int rtl8390_serdes_probe(struct phy_device *phydev) -{ - int addr = phydev->mdio.addr; - - if (soc_info.family != RTL8390_FAMILY_ID) - return -ENODEV; - - if (addr < 24) - return -ENODEV; - - return rtl8390_configure_generic(phydev); -} - -static int rtl9300_serdes_probe(struct phy_device *phydev) -{ - if (soc_info.family != RTL9300_FAMILY_ID) - return -ENODEV; - - phydev_info(phydev, "Detected internal RTL9300 Serdes\n"); - - return 0; -} - -static struct phy_driver rtl83xx_phy_driver[] = { - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL8214C), - .name = "Realtek RTL8214C", - .features = PHY_GBIT_FEATURES, - .match_phy_device = rtl8214c_match_phy_device, - .probe = rtl8214c_phy_probe, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .suspend = genphy_suspend, - .resume = genphy_resume, - .set_loopback = genphy_loopback, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC), - .name = "Realtek RTL8214FC", - .features = PHY_GBIT_FIBRE_FEATURES, - .match_phy_device = rtl8214fc_match_phy_device, - .probe = rtl8214fc_phy_probe, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .suspend = rtl8214fc_suspend, - .resume = rtl8214fc_resume, - .set_loopback = genphy_loopback, - .set_port = rtl8214fc_set_port, - .get_port = rtl8214fc_get_port, - .set_eee = rtl8214fc_set_eee, - .get_eee = rtl8214fc_get_eee, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_E), - .name = "Realtek RTL8218B (external)", - .features = PHY_GBIT_FEATURES, - .match_phy_device = rtl8218b_ext_match_phy_device, - .probe = rtl8218b_ext_phy_probe, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .suspend = genphy_suspend, - .resume = genphy_resume, - .set_loopback = genphy_loopback, - .set_eee = rtl8218b_set_eee, - .get_eee = rtl8218b_get_eee, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL8218D), - .name = "REALTEK RTL8218D", - .features = PHY_GBIT_FEATURES, - .probe = rtl8218d_phy_probe, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .suspend = genphy_suspend, - .resume = genphy_resume, - .set_loopback = genphy_loopback, - .set_eee = rtl8218d_set_eee, - .get_eee = rtl8218d_get_eee, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL8221B), - .name = "REALTEK RTL8221B", - .features = PHY_GBIT_FEATURES, - .suspend = genphy_suspend, - .resume = genphy_resume, - .set_loopback = genphy_loopback, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .read_status = rtl8226_read_status, - .config_aneg = rtl8226_config_aneg, - .set_eee = rtl8226_set_eee, - .get_eee = rtl8226_get_eee, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL8226), - .name = "REALTEK RTL8226", - .features = PHY_GBIT_FEATURES, - .suspend = genphy_suspend, - .resume = genphy_resume, - .set_loopback = genphy_loopback, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .read_status = rtl8226_read_status, - .config_aneg = rtl8226_config_aneg, - .set_eee = rtl8226_set_eee, - .get_eee = rtl8226_get_eee, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I), - .name = "Realtek RTL8218B (internal)", - .features = PHY_GBIT_FEATURES, - .probe = rtl8218b_int_phy_probe, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .suspend = genphy_suspend, - .resume = genphy_resume, - .set_loopback = genphy_loopback, - .set_eee = rtl8218b_set_eee, - .get_eee = rtl8218b_get_eee, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL8218B_I), - .name = "Realtek RTL8380 SERDES", - .features = PHY_GBIT_FIBRE_FEATURES, - .probe = rtl838x_serdes_probe, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .suspend = genphy_suspend, - .resume = genphy_resume, - .set_loopback = genphy_loopback, - .read_status = rtl8380_read_status, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL8393_I), - .name = "Realtek RTL8393 SERDES", - .features = PHY_GBIT_FIBRE_FEATURES, - .probe = rtl8393_serdes_probe, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .suspend = genphy_suspend, - .resume = genphy_resume, - .set_loopback = genphy_loopback, - .read_status = rtl8393_read_status, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL8390_GENERIC), - .name = "Realtek RTL8390 Generic", - .features = PHY_GBIT_FIBRE_FEATURES, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .probe = rtl8390_serdes_probe, - .suspend = genphy_suspend, - .resume = genphy_resume, - .set_loopback = genphy_loopback, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_RTL9300_I), - .name = "REALTEK RTL9300 SERDES", - .features = PHY_GBIT_FIBRE_FEATURES, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, - .probe = rtl9300_serdes_probe, - .suspend = genphy_suspend, - .resume = genphy_resume, - .set_loopback = genphy_loopback, - .read_status = rtl9300_read_status, - }, -}; - -module_phy_driver(rtl83xx_phy_driver); - -static struct mdio_device_id __maybe_unused rtl83xx_tbl[] = { - { PHY_ID_MATCH_MODEL(PHY_ID_RTL8214FC) }, - { } -}; - -MODULE_DEVICE_TABLE(mdio, rtl83xx_tbl); - -MODULE_AUTHOR("B. Koblitz"); -MODULE_DESCRIPTION("RTL83xx PHY driver"); -MODULE_LICENSE("GPL"); diff --git a/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.h b/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.h deleted file mode 100644 index fb79560e6b6948..00000000000000 --- a/target/linux/realtek/files-5.15/drivers/net/phy/rtl83xx-phy.h +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -struct rtl83xx_shared_private { - char *name; -}; - -struct __attribute__ ((__packed__)) part { - uint16_t start; - uint8_t wordsize; - uint8_t words; -}; - -struct __attribute__ ((__packed__)) fw_header { - uint32_t magic; - uint32_t phy; - uint32_t checksum; - uint32_t version; - struct part parts[10]; -}; - -/* TODO: fixed path? */ -#define FIRMWARE_838X_8380_1 "rtl838x_phy/rtl838x_8380.fw" -#define FIRMWARE_838X_8214FC_1 "rtl838x_phy/rtl838x_8214fc.fw" -#define FIRMWARE_838X_8218b_1 "rtl838x_phy/rtl838x_8218b.fw" - -/* External RTL8218B and RTL8214FC IDs are identical */ -#define PHY_ID_RTL8214C 0x001cc942 -#define PHY_ID_RTL8214FC 0x001cc981 -#define PHY_ID_RTL8218B_E 0x001cc981 -#define PHY_ID_RTL8218D 0x001cc983 -#define PHY_ID_RTL8218B_I 0x001cca40 -#define PHY_ID_RTL8221B 0x001cc849 -#define PHY_ID_RTL8226 0x001cc838 -#define PHY_ID_RTL8390_GENERIC 0x001ccab0 -#define PHY_ID_RTL8393_I 0x001c8393 -#define PHY_ID_RTL9300_I 0x70d03106 - -/* Registers of the internal Serdes of the 8380 */ -#define RTL838X_SDS_MODE_SEL (0x0028) -#define RTL838X_SDS_CFG_REG (0x0034) -#define RTL838X_INT_MODE_CTRL (0x005c) -#define RTL838X_DMY_REG31 (0x3b28) - -#define RTL8380_SDS4_FIB_REG0 (0xF800) -#define RTL838X_SDS4_REG28 (0xef80) -#define RTL838X_SDS4_DUMMY0 (0xef8c) -#define RTL838X_SDS5_EXT_REG6 (0xf18c) -#define RTL838X_SDS4_FIB_REG0 (RTL838X_SDS4_REG28 + 0x880) -#define RTL838X_SDS5_FIB_REG0 (RTL838X_SDS4_REG28 + 0x980) - -/* Registers of the internal SerDes of the RTL8390 */ -#define RTL839X_SDS12_13_XSG0 (0xB800) - -/* Registers of the internal Serdes of the 9300 */ -#define RTL930X_SDS_INDACS_CMD (0x03B0) -#define RTL930X_SDS_INDACS_DATA (0x03B4) -#define RTL930X_MAC_FORCE_MODE_CTRL (0xCA1C) - -/* Registers of the internal SerDes of the 9310 */ -#define RTL931X_SERDES_INDRT_ACCESS_CTRL (0x5638) -#define RTL931X_SERDES_INDRT_DATA_CTRL (0x563C) -#define RTL931X_SERDES_MODE_CTRL (0x13cc) -#define RTL931X_PS_SERDES_OFF_MODE_CTRL_ADDR (0x13F4) -#define RTL931X_MAC_SERDES_MODE_CTRL(sds) (0x136C + (((sds) << 2))) diff --git a/target/linux/realtek/files-5.15/include/dt-bindings/clock/rtl83xx-clk.h b/target/linux/realtek/files-5.15/include/dt-bindings/clock/rtl83xx-clk.h deleted file mode 100644 index 3937052cc50ff4..00000000000000 --- a/target/linux/realtek/files-5.15/include/dt-bindings/clock/rtl83xx-clk.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2022 Markus Stockhausen - * - * RTL83XX clock indices - */ -#ifndef __DT_BINDINGS_CLOCK_RTL83XX_H -#define __DT_BINDINGS_CLOCK_RTL83XX_H - -#define CLK_CPU 0 -#define CLK_MEM 1 -#define CLK_LXB 2 -#define CLK_COUNT 3 - -#endif /* __DT_BINDINGS_CLOCK_RTL83XX_H */ diff --git a/target/linux/realtek/patches-5.15/008-5.17-watchdog-add-realtek-otto-watchdog-timer.patch b/target/linux/realtek/patches-5.15/008-5.17-watchdog-add-realtek-otto-watchdog-timer.patch deleted file mode 100644 index 7df22b0725805b..00000000000000 --- a/target/linux/realtek/patches-5.15/008-5.17-watchdog-add-realtek-otto-watchdog-timer.patch +++ /dev/null @@ -1,467 +0,0 @@ -From 293903b9dfe43520f01374dc1661be11d6838c49 Mon Sep 17 00:00:00 2001 -From: Sander Vanheule -Date: Thu, 18 Nov 2021 17:29:52 +0100 -Subject: watchdog: Add Realtek Otto watchdog timer - -Realtek MIPS SoCs (platform name Otto) have a watchdog timer with -pretimeout notifitication support. The WDT can (partially) hard reset, -or soft reset the SoC. - -This driver implements all features as described in the devicetree -binding, except the phase2 interrupt, and also functions as a restart -handler. The cpu reset mode is considered to be a "warm" restart, since -this mode does not reset all peripherals. Being an embedded system -though, the "cpu" and "software" modes will still cause the bootloader -to run on restart. - -It is not known how a forced system reset can be disabled on the -supported platforms. This means that the phase2 interrupt will only fire -at the same time as reset, so implementing phase2 is of little use. - -Signed-off-by: Sander Vanheule -Reviewed-by: Guenter Roeck -Link: https://lore.kernel.org/r/6d060bccbdcc709cfa79203485db85aad3c3beb5.1637252610.git.sander@svanheule.net -Signed-off-by: Guenter Roeck ---- - MAINTAINERS | 7 + - drivers/watchdog/Kconfig | 13 ++ - drivers/watchdog/Makefile | 1 + - drivers/watchdog/realtek_otto_wdt.c | 384 ++++++++++++++++++++++++++++++++++++ - 4 files changed, 405 insertions(+) - create mode 100644 drivers/watchdog/realtek_otto_wdt.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -15903,6 +15903,13 @@ S: Maintained - F: include/sound/rt*.h - F: sound/soc/codecs/rt* - -+REALTEK OTTO WATCHDOG -+M: Sander Vanheule -+L: linux-watchdog@vger.kernel.org -+S: Maintained -+F: Documentation/devicetree/bindings/watchdog/realtek,otto-wdt.yaml -+F: driver/watchdog/realtek_otto_wdt.c -+ - REALTEK RTL83xx SMI DSA ROUTER CHIPS - M: Linus Walleij - S: Maintained ---- a/drivers/watchdog/Kconfig -+++ b/drivers/watchdog/Kconfig -@@ -954,6 +954,19 @@ config RTD119X_WATCHDOG - Say Y here to include support for the watchdog timer in - Realtek RTD1295 SoCs. - -+config REALTEK_OTTO_WDT -+ tristate "Realtek Otto MIPS watchdog support" -+ depends on MACH_REALTEK_RTL || COMPILE_TEST -+ depends on COMMON_CLK -+ select WATCHDOG_CORE -+ default MACH_REALTEK_RTL -+ help -+ Say Y here to include support for the watchdog timer on Realtek -+ RTL838x, RTL839x, RTL930x SoCs. This watchdog has pretimeout -+ notifications and system reset on timeout. -+ -+ When built as a module this will be called realtek_otto_wdt. -+ - config SPRD_WATCHDOG - tristate "Spreadtrum watchdog support" - depends on ARCH_SPRD || COMPILE_TEST ---- a/drivers/watchdog/Makefile -+++ b/drivers/watchdog/Makefile -@@ -171,6 +171,7 @@ obj-$(CONFIG_IMGPDC_WDT) += imgpdc_wdt.o - obj-$(CONFIG_MT7621_WDT) += mt7621_wdt.o - obj-$(CONFIG_PIC32_WDT) += pic32-wdt.o - obj-$(CONFIG_PIC32_DMT) += pic32-dmt.o -+obj-$(CONFIG_REALTEK_OTTO_WDT) += realtek_otto_wdt.o - - # PARISC Architecture - ---- /dev/null -+++ b/drivers/watchdog/realtek_otto_wdt.c -@@ -0,0 +1,384 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+ -+/* -+ * Realtek Otto MIPS platform watchdog -+ * -+ * Watchdog timer that will reset the system after timeout, using the selected -+ * reset mode. -+ * -+ * Counter scaling and timeouts: -+ * - Base prescale of (2 << 25), providing tick duration T_0: 168ms @ 200MHz -+ * - PRESCALE: logarithmic prescaler adding a factor of {1, 2, 4, 8} -+ * - Phase 1: Times out after (PHASE1 + 1) × PRESCALE × T_0 -+ * Generates an interrupt, WDT cannot be stopped after phase 1 -+ * - Phase 2: starts after phase 1, times out after (PHASE2 + 1) × PRESCALE × T_0 -+ * Resets the system according to RST_MODE -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define OTTO_WDT_REG_CNTR 0x0 -+#define OTTO_WDT_CNTR_PING BIT(31) -+ -+#define OTTO_WDT_REG_INTR 0x4 -+#define OTTO_WDT_INTR_PHASE_1 BIT(31) -+#define OTTO_WDT_INTR_PHASE_2 BIT(30) -+ -+#define OTTO_WDT_REG_CTRL 0x8 -+#define OTTO_WDT_CTRL_ENABLE BIT(31) -+#define OTTO_WDT_CTRL_PRESCALE GENMASK(30, 29) -+#define OTTO_WDT_CTRL_PHASE1 GENMASK(26, 22) -+#define OTTO_WDT_CTRL_PHASE2 GENMASK(19, 15) -+#define OTTO_WDT_CTRL_RST_MODE GENMASK(1, 0) -+#define OTTO_WDT_MODE_SOC 0 -+#define OTTO_WDT_MODE_CPU 1 -+#define OTTO_WDT_MODE_SOFTWARE 2 -+#define OTTO_WDT_CTRL_DEFAULT OTTO_WDT_MODE_CPU -+ -+#define OTTO_WDT_PRESCALE_MAX 3 -+ -+/* -+ * One higher than the max values contained in PHASE{1,2}, since a value of 0 -+ * corresponds to one tick. -+ */ -+#define OTTO_WDT_PHASE_TICKS_MAX 32 -+ -+/* -+ * The maximum reset delay is actually 2×32 ticks, but that would require large -+ * pretimeout values for timeouts longer than 32 ticks. Limit the maximum timeout -+ * to 32 + 1 to ensure small pretimeout values can be configured as expected. -+ */ -+#define OTTO_WDT_TIMEOUT_TICKS_MAX (OTTO_WDT_PHASE_TICKS_MAX + 1) -+ -+struct otto_wdt_ctrl { -+ struct watchdog_device wdev; -+ struct device *dev; -+ void __iomem *base; -+ unsigned int clk_rate_khz; -+ int irq_phase1; -+}; -+ -+static int otto_wdt_start(struct watchdog_device *wdev) -+{ -+ struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev); -+ u32 v; -+ -+ v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL); -+ v |= OTTO_WDT_CTRL_ENABLE; -+ iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL); -+ -+ return 0; -+} -+ -+static int otto_wdt_stop(struct watchdog_device *wdev) -+{ -+ struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev); -+ u32 v; -+ -+ v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL); -+ v &= ~OTTO_WDT_CTRL_ENABLE; -+ iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL); -+ -+ return 0; -+} -+ -+static int otto_wdt_ping(struct watchdog_device *wdev) -+{ -+ struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev); -+ -+ iowrite32(OTTO_WDT_CNTR_PING, ctrl->base + OTTO_WDT_REG_CNTR); -+ -+ return 0; -+} -+ -+static int otto_wdt_tick_ms(struct otto_wdt_ctrl *ctrl, int prescale) -+{ -+ return DIV_ROUND_CLOSEST(1 << (25 + prescale), ctrl->clk_rate_khz); -+} -+ -+/* -+ * The timer asserts the PHASE1/PHASE2 IRQs when the number of ticks exceeds -+ * the value stored in those fields. This means each phase will run for at least -+ * one tick, so small values need to be clamped to correctly reflect the timeout. -+ */ -+static inline unsigned int div_round_ticks(unsigned int val, unsigned int tick_duration, -+ unsigned int min_ticks) -+{ -+ return max(min_ticks, DIV_ROUND_UP(val, tick_duration)); -+} -+ -+static int otto_wdt_determine_timeouts(struct watchdog_device *wdev, unsigned int timeout, -+ unsigned int pretimeout) -+{ -+ struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev); -+ unsigned int pretimeout_ms = pretimeout * 1000; -+ unsigned int timeout_ms = timeout * 1000; -+ unsigned int prescale_next = 0; -+ unsigned int phase1_ticks; -+ unsigned int phase2_ticks; -+ unsigned int total_ticks; -+ unsigned int prescale; -+ unsigned int tick_ms; -+ u32 v; -+ -+ do { -+ prescale = prescale_next; -+ if (prescale > OTTO_WDT_PRESCALE_MAX) -+ return -EINVAL; -+ -+ tick_ms = otto_wdt_tick_ms(ctrl, prescale); -+ total_ticks = div_round_ticks(timeout_ms, tick_ms, 2); -+ phase1_ticks = div_round_ticks(timeout_ms - pretimeout_ms, tick_ms, 1); -+ phase2_ticks = total_ticks - phase1_ticks; -+ -+ prescale_next++; -+ } while (phase1_ticks > OTTO_WDT_PHASE_TICKS_MAX -+ || phase2_ticks > OTTO_WDT_PHASE_TICKS_MAX); -+ -+ v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL); -+ -+ v &= ~(OTTO_WDT_CTRL_PRESCALE | OTTO_WDT_CTRL_PHASE1 | OTTO_WDT_CTRL_PHASE2); -+ v |= FIELD_PREP(OTTO_WDT_CTRL_PHASE1, phase1_ticks - 1); -+ v |= FIELD_PREP(OTTO_WDT_CTRL_PHASE2, phase2_ticks - 1); -+ v |= FIELD_PREP(OTTO_WDT_CTRL_PRESCALE, prescale); -+ -+ iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL); -+ -+ timeout_ms = total_ticks * tick_ms; -+ ctrl->wdev.timeout = timeout_ms / 1000; -+ -+ pretimeout_ms = phase2_ticks * tick_ms; -+ ctrl->wdev.pretimeout = pretimeout_ms / 1000; -+ -+ return 0; -+} -+ -+static int otto_wdt_set_timeout(struct watchdog_device *wdev, unsigned int val) -+{ -+ return otto_wdt_determine_timeouts(wdev, val, min(wdev->pretimeout, val - 1)); -+} -+ -+static int otto_wdt_set_pretimeout(struct watchdog_device *wdev, unsigned int val) -+{ -+ return otto_wdt_determine_timeouts(wdev, wdev->timeout, val); -+} -+ -+static int otto_wdt_restart(struct watchdog_device *wdev, unsigned long reboot_mode, -+ void *data) -+{ -+ struct otto_wdt_ctrl *ctrl = watchdog_get_drvdata(wdev); -+ u32 reset_mode; -+ u32 v; -+ -+ disable_irq(ctrl->irq_phase1); -+ -+ switch (reboot_mode) { -+ case REBOOT_SOFT: -+ reset_mode = OTTO_WDT_MODE_SOFTWARE; -+ break; -+ case REBOOT_WARM: -+ reset_mode = OTTO_WDT_MODE_CPU; -+ break; -+ default: -+ reset_mode = OTTO_WDT_MODE_SOC; -+ break; -+ } -+ -+ /* Configure for shortest timeout and wait for reset to occur */ -+ v = FIELD_PREP(OTTO_WDT_CTRL_RST_MODE, reset_mode) | OTTO_WDT_CTRL_ENABLE; -+ iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL); -+ -+ mdelay(3 * otto_wdt_tick_ms(ctrl, 0)); -+ -+ return 0; -+} -+ -+static irqreturn_t otto_wdt_phase1_isr(int irq, void *dev_id) -+{ -+ struct otto_wdt_ctrl *ctrl = dev_id; -+ -+ iowrite32(OTTO_WDT_INTR_PHASE_1, ctrl->base + OTTO_WDT_REG_INTR); -+ dev_crit(ctrl->dev, "phase 1 timeout\n"); -+ watchdog_notify_pretimeout(&ctrl->wdev); -+ -+ return IRQ_HANDLED; -+} -+ -+static const struct watchdog_ops otto_wdt_ops = { -+ .owner = THIS_MODULE, -+ .start = otto_wdt_start, -+ .stop = otto_wdt_stop, -+ .ping = otto_wdt_ping, -+ .set_timeout = otto_wdt_set_timeout, -+ .set_pretimeout = otto_wdt_set_pretimeout, -+ .restart = otto_wdt_restart, -+}; -+ -+static const struct watchdog_info otto_wdt_info = { -+ .identity = "Realtek Otto watchdog timer", -+ .options = WDIOF_KEEPALIVEPING | -+ WDIOF_MAGICCLOSE | -+ WDIOF_SETTIMEOUT | -+ WDIOF_PRETIMEOUT, -+}; -+ -+static void otto_wdt_clock_action(void *data) -+{ -+ clk_disable_unprepare(data); -+} -+ -+static int otto_wdt_probe_clk(struct otto_wdt_ctrl *ctrl) -+{ -+ struct clk *clk = devm_clk_get(ctrl->dev, NULL); -+ int ret; -+ -+ if (IS_ERR(clk)) -+ return dev_err_probe(ctrl->dev, PTR_ERR(clk), "Failed to get clock\n"); -+ -+ ret = clk_prepare_enable(clk); -+ if (ret) -+ return dev_err_probe(ctrl->dev, ret, "Failed to enable clock\n"); -+ -+ ret = devm_add_action_or_reset(ctrl->dev, otto_wdt_clock_action, clk); -+ if (ret) -+ return ret; -+ -+ ctrl->clk_rate_khz = clk_get_rate(clk) / 1000; -+ if (ctrl->clk_rate_khz == 0) -+ return dev_err_probe(ctrl->dev, -ENXIO, "Failed to get clock rate\n"); -+ -+ return 0; -+} -+ -+static int otto_wdt_probe_reset_mode(struct otto_wdt_ctrl *ctrl) -+{ -+ static const char *mode_property = "realtek,reset-mode"; -+ const struct fwnode_handle *node = ctrl->dev->fwnode; -+ int mode_count; -+ u32 mode; -+ u32 v; -+ -+ if (!node) -+ return -ENXIO; -+ -+ mode_count = fwnode_property_string_array_count(node, mode_property); -+ if (mode_count < 0) -+ return mode_count; -+ else if (mode_count == 0) -+ return 0; -+ else if (mode_count != 1) -+ return -EINVAL; -+ -+ if (fwnode_property_match_string(node, mode_property, "soc") == 0) -+ mode = OTTO_WDT_MODE_SOC; -+ else if (fwnode_property_match_string(node, mode_property, "cpu") == 0) -+ mode = OTTO_WDT_MODE_CPU; -+ else if (fwnode_property_match_string(node, mode_property, "software") == 0) -+ mode = OTTO_WDT_MODE_SOFTWARE; -+ else -+ return -EINVAL; -+ -+ v = ioread32(ctrl->base + OTTO_WDT_REG_CTRL); -+ v &= ~OTTO_WDT_CTRL_RST_MODE; -+ v |= FIELD_PREP(OTTO_WDT_CTRL_RST_MODE, mode); -+ iowrite32(v, ctrl->base + OTTO_WDT_REG_CTRL); -+ -+ return 0; -+} -+ -+static int otto_wdt_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct otto_wdt_ctrl *ctrl; -+ unsigned int max_tick_ms; -+ int ret; -+ -+ ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); -+ if (!ctrl) -+ return -ENOMEM; -+ -+ ctrl->dev = dev; -+ ctrl->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(ctrl->base)) -+ return PTR_ERR(ctrl->base); -+ -+ /* Clear any old interrupts and reset initial state */ -+ iowrite32(OTTO_WDT_INTR_PHASE_1 | OTTO_WDT_INTR_PHASE_2, -+ ctrl->base + OTTO_WDT_REG_INTR); -+ iowrite32(OTTO_WDT_CTRL_DEFAULT, ctrl->base + OTTO_WDT_REG_CTRL); -+ -+ ret = otto_wdt_probe_clk(ctrl); -+ if (ret) -+ return ret; -+ -+ ctrl->irq_phase1 = platform_get_irq_byname(pdev, "phase1"); -+ if (ctrl->irq_phase1 < 0) -+ return ctrl->irq_phase1; -+ -+ ret = devm_request_irq(dev, ctrl->irq_phase1, otto_wdt_phase1_isr, 0, -+ "realtek-otto-wdt", ctrl); -+ if (ret) -+ return dev_err_probe(dev, ret, "Failed to get IRQ for phase1\n"); -+ -+ ret = otto_wdt_probe_reset_mode(ctrl); -+ if (ret) -+ return dev_err_probe(dev, ret, "Invalid reset mode specified\n"); -+ -+ ctrl->wdev.parent = dev; -+ ctrl->wdev.info = &otto_wdt_info; -+ ctrl->wdev.ops = &otto_wdt_ops; -+ -+ /* -+ * Since pretimeout cannot be disabled, min. timeout is twice the -+ * subsystem resolution. Max. timeout is ca. 43s at a bus clock of 200MHz. -+ */ -+ ctrl->wdev.min_timeout = 2; -+ max_tick_ms = otto_wdt_tick_ms(ctrl, OTTO_WDT_PRESCALE_MAX); -+ ctrl->wdev.max_hw_heartbeat_ms = max_tick_ms * OTTO_WDT_TIMEOUT_TICKS_MAX; -+ ctrl->wdev.timeout = min(30U, ctrl->wdev.max_hw_heartbeat_ms / 1000); -+ -+ watchdog_set_drvdata(&ctrl->wdev, ctrl); -+ watchdog_init_timeout(&ctrl->wdev, 0, dev); -+ watchdog_stop_on_reboot(&ctrl->wdev); -+ watchdog_set_restart_priority(&ctrl->wdev, 128); -+ -+ ret = otto_wdt_determine_timeouts(&ctrl->wdev, ctrl->wdev.timeout, 1); -+ if (ret) -+ return dev_err_probe(dev, ret, "Failed to set timeout\n"); -+ -+ return devm_watchdog_register_device(dev, &ctrl->wdev); -+} -+ -+static const struct of_device_id otto_wdt_ids[] = { -+ { .compatible = "realtek,rtl8380-wdt" }, -+ { .compatible = "realtek,rtl8390-wdt" }, -+ { .compatible = "realtek,rtl9300-wdt" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, otto_wdt_ids); -+ -+static struct platform_driver otto_wdt_driver = { -+ .probe = otto_wdt_probe, -+ .driver = { -+ .name = "realtek-otto-watchdog", -+ .of_match_table = otto_wdt_ids, -+ }, -+}; -+module_platform_driver(otto_wdt_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Sander Vanheule "); -+MODULE_DESCRIPTION("Realtek Otto watchdog timer driver"); diff --git a/target/linux/realtek/patches-5.15/020-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch b/target/linux/realtek/patches-5.15/020-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch deleted file mode 100644 index da33aaa72f30c8..00000000000000 --- a/target/linux/realtek/patches-5.15/020-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch +++ /dev/null @@ -1,53 +0,0 @@ -From c6af53f038aa32cec12e8a305ba07c7ef168f1b0 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 4 Jan 2022 12:07:00 +0000 -Subject: [PATCH 2/3] net: mdio: add helpers to extract clause 45 regad and - devad fields - -Add a couple of helpers and definitions to extract the clause 45 regad -and devad fields from the regnum passed into MDIO drivers. - -Tested-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - include/linux/mdio.h | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/include/linux/mdio.h -+++ b/include/linux/mdio.h -@@ -7,6 +7,7 @@ - #define __LINUX_MDIO_H__ - - #include -+#include - #include - - /* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit -@@ -14,6 +15,7 @@ - */ - #define MII_ADDR_C45 (1<<30) - #define MII_DEVADDR_C45_SHIFT 16 -+#define MII_DEVADDR_C45_MASK GENMASK(20, 16) - #define MII_REGADDR_C45_MASK GENMASK(15, 0) - - struct gpio_desc; -@@ -355,6 +357,16 @@ static inline u32 mdiobus_c45_addr(int d - return MII_ADDR_C45 | devad << MII_DEVADDR_C45_SHIFT | regnum; - } - -+static inline u16 mdiobus_c45_regad(u32 regnum) -+{ -+ return FIELD_GET(MII_REGADDR_C45_MASK, regnum); -+} -+ -+static inline u16 mdiobus_c45_devad(u32 regnum) -+{ -+ return FIELD_GET(MII_DEVADDR_C45_MASK, regnum); -+} -+ - static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad, - u16 regnum) - { diff --git a/target/linux/realtek/patches-5.15/021-v5.19-02-gpio-realtek-otto-Support-reversed-port-layouts.patch b/target/linux/realtek/patches-5.15/021-v5.19-02-gpio-realtek-otto-Support-reversed-port-layouts.patch deleted file mode 100644 index 437e7862d912ac..00000000000000 --- a/target/linux/realtek/patches-5.15/021-v5.19-02-gpio-realtek-otto-Support-reversed-port-layouts.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 512c5be35223d9baa2629efa1084cf5210eaee80 Mon Sep 17 00:00:00 2001 -From: Sander Vanheule -Date: Sat, 9 Apr 2022 21:55:47 +0200 -Subject: [PATCH 2/6] gpio: realtek-otto: Support reversed port layouts - -The GPIO port layout on the RTL930x SoC series is reversed compared to -the RTL838x and RTL839x SoC series. Add new port offset calculator -functions to ensure the correct order is used when reading port IRQ -data, and ensure bgpio uses the right byte ordering. - -Signed-off-by: Sander Vanheule -Signed-off-by: Bartosz Golaszewski ---- - drivers/gpio/gpio-realtek-otto.c | 55 +++++++++++++++++++++++++++++--- - 1 file changed, 51 insertions(+), 4 deletions(-) - ---- a/drivers/gpio/gpio-realtek-otto.c -+++ b/drivers/gpio/gpio-realtek-otto.c -@@ -58,6 +58,8 @@ struct realtek_gpio_ctrl { - raw_spinlock_t lock; - u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK]; - u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK]; -+ unsigned int (*port_offset_u8)(unsigned int port); -+ unsigned int (*port_offset_u16)(unsigned int port); - }; - - /* Expand with more flags as devices with other quirks are added */ -@@ -69,6 +71,11 @@ enum realtek_gpio_flags { - * line the IRQ handler was assigned to, causing uncaught interrupts. - */ - GPIO_INTERRUPTS_DISABLED = BIT(0), -+ /* -+ * Port order is reversed, meaning DCBA register layout for 1-bit -+ * fields, and [BA, DC] for 2-bit fields. -+ */ -+ GPIO_PORTS_REVERSED = BIT(1), - }; - - static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data) -@@ -86,21 +93,50 @@ static struct realtek_gpio_ctrl *irq_dat - * port. The two interrupt mask registers store two bits per GPIO, so use u16 - * values. - */ -+static unsigned int realtek_gpio_port_offset_u8(unsigned int port) -+{ -+ return port; -+} -+ -+static unsigned int realtek_gpio_port_offset_u16(unsigned int port) -+{ -+ return 2 * port; -+} -+ -+/* -+ * Reversed port order register access -+ * -+ * For registers with one bit per GPIO, all ports are stored as u8-s in one -+ * register in reversed order. The two interrupt mask registers store two bits -+ * per GPIO, so use u16 values. The first register contains ports 1 and 0, the -+ * second ports 3 and 2. -+ */ -+static unsigned int realtek_gpio_port_offset_u8_rev(unsigned int port) -+{ -+ return 3 - port; -+} -+ -+static unsigned int realtek_gpio_port_offset_u16_rev(unsigned int port) -+{ -+ return 2 * (port ^ 1); -+} -+ - static void realtek_gpio_write_imr(struct realtek_gpio_ctrl *ctrl, - unsigned int port, u16 irq_type, u16 irq_mask) - { -- iowrite16(irq_type & irq_mask, ctrl->base + REALTEK_GPIO_REG_IMR + 2 * port); -+ iowrite16(irq_type & irq_mask, -+ ctrl->base + REALTEK_GPIO_REG_IMR + ctrl->port_offset_u16(port)); - } - - static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl, - unsigned int port, u8 mask) - { -- iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + port); -+ iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port)); - } - - static u8 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl, unsigned int port) - { -- return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + port); -+ return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port)); - } - - /* Set the rising and falling edge mask bits for a GPIO port pin */ -@@ -250,6 +286,7 @@ MODULE_DEVICE_TABLE(of, realtek_gpio_of_ - static int realtek_gpio_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -+ unsigned long bgpio_flags; - unsigned int dev_flags; - struct gpio_irq_chip *girq; - struct realtek_gpio_ctrl *ctrl; -@@ -277,10 +314,20 @@ static int realtek_gpio_probe(struct pla - - raw_spin_lock_init(&ctrl->lock); - -+ if (dev_flags & GPIO_PORTS_REVERSED) { -+ bgpio_flags = 0; -+ ctrl->port_offset_u8 = realtek_gpio_port_offset_u8_rev; -+ ctrl->port_offset_u16 = realtek_gpio_port_offset_u16_rev; -+ } else { -+ bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER; -+ ctrl->port_offset_u8 = realtek_gpio_port_offset_u8; -+ ctrl->port_offset_u16 = realtek_gpio_port_offset_u16; -+ } -+ - err = bgpio_init(&ctrl->gc, dev, 4, - ctrl->base + REALTEK_GPIO_REG_DATA, NULL, NULL, - ctrl->base + REALTEK_GPIO_REG_DIR, NULL, -- BGPIOF_BIG_ENDIAN_BYTE_ORDER); -+ bgpio_flags); - if (err) { - dev_err(dev, "unable to init generic GPIO"); - return err; diff --git a/target/linux/realtek/patches-5.15/021-v5.19-03-gpio-realtek-otto-Support-per-cpu-interrupts.patch b/target/linux/realtek/patches-5.15/021-v5.19-03-gpio-realtek-otto-Support-per-cpu-interrupts.patch deleted file mode 100644 index b632095c362213..00000000000000 --- a/target/linux/realtek/patches-5.15/021-v5.19-03-gpio-realtek-otto-Support-per-cpu-interrupts.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 95fa6dbe58f286a8f87cb37b7516232eb678de2d Mon Sep 17 00:00:00 2001 -From: Sander Vanheule -Date: Sat, 9 Apr 2022 21:55:48 +0200 -Subject: [PATCH 3/6] gpio: realtek-otto: Support per-cpu interrupts - -On SoCs with multiple cores, it is possible that the GPIO interrupt -controller supports assigning specific pins to one or more cores. - -IRQ balancing can be performed on a line-by-line basis if the parent -interrupt is routed to all available cores, which is the default upon -initialisation. - -Signed-off-by: Sander Vanheule -Signed-off-by: Bartosz Golaszewski ---- - drivers/gpio/gpio-realtek-otto.c | 75 +++++++++++++++++++++++++++++++- - 1 file changed, 74 insertions(+), 1 deletion(-) - ---- a/drivers/gpio/gpio-realtek-otto.c -+++ b/drivers/gpio/gpio-realtek-otto.c -@@ -1,6 +1,7 @@ - // SPDX-License-Identifier: GPL-2.0-only - - #include -+#include - #include - #include - #include -@@ -55,6 +56,8 @@ - struct realtek_gpio_ctrl { - struct gpio_chip gc; - void __iomem *base; -+ void __iomem *cpumask_base; -+ struct cpumask cpu_irq_maskable; - raw_spinlock_t lock; - u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK]; - u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK]; -@@ -76,6 +79,11 @@ enum realtek_gpio_flags { - * fields, and [BA, DC] for 2-bit fields. - */ - GPIO_PORTS_REVERSED = BIT(1), -+ /* -+ * Interrupts can be enabled per cpu. This requires a secondary IO -+ * range, where the per-cpu enable masks are located. -+ */ -+ GPIO_INTERRUPTS_PER_CPU = BIT(2), - }; - - static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data) -@@ -247,14 +255,61 @@ static void realtek_gpio_irq_handler(str - chained_irq_exit(irq_chip, desc); - } - -+static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl, -+ unsigned int port, int cpu) -+{ -+ return ctrl->cpumask_base + ctrl->port_offset_u8(port) + -+ REALTEK_GPIO_PORTS_PER_BANK * cpu; -+} -+ -+static int realtek_gpio_irq_set_affinity(struct irq_data *data, -+ const struct cpumask *dest, bool force) -+{ -+ struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); -+ unsigned int line = irqd_to_hwirq(data); -+ unsigned int port = line / 8; -+ unsigned int port_pin = line % 8; -+ void __iomem *irq_cpu_mask; -+ unsigned long flags; -+ int cpu; -+ u8 v; -+ -+ if (!ctrl->cpumask_base) -+ return -ENXIO; -+ -+ raw_spin_lock_irqsave(&ctrl->lock, flags); -+ -+ for_each_cpu(cpu, &ctrl->cpu_irq_maskable) { -+ irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu); -+ v = ioread8(irq_cpu_mask); -+ -+ if (cpumask_test_cpu(cpu, dest)) -+ v |= BIT(port_pin); -+ else -+ v &= ~BIT(port_pin); -+ -+ iowrite8(v, irq_cpu_mask); -+ } -+ -+ raw_spin_unlock_irqrestore(&ctrl->lock, flags); -+ -+ irq_data_update_effective_affinity(data, dest); -+ -+ return 0; -+} -+ - static int realtek_gpio_irq_init(struct gpio_chip *gc) - { - struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc); - unsigned int port; -+ int cpu; - - for (port = 0; (port * 8) < gc->ngpio; port++) { - realtek_gpio_write_imr(ctrl, port, 0, 0); - realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0)); -+ -+ for_each_cpu(cpu, &ctrl->cpu_irq_maskable) -+ iowrite8(GENMASK(7, 0), realtek_gpio_irq_cpu_mask(ctrl, port, cpu)); - } - - return 0; -@@ -266,6 +321,7 @@ static struct irq_chip realtek_gpio_irq_ - .irq_mask = realtek_gpio_irq_mask, - .irq_unmask = realtek_gpio_irq_unmask, - .irq_set_type = realtek_gpio_irq_set_type, -+ .irq_set_affinity = realtek_gpio_irq_set_affinity, - }; - - static const struct of_device_id realtek_gpio_of_match[] = { -@@ -290,8 +346,10 @@ static int realtek_gpio_probe(struct pla - unsigned int dev_flags; - struct gpio_irq_chip *girq; - struct realtek_gpio_ctrl *ctrl; -+ struct resource *res; - u32 ngpios; -- int err, irq; -+ unsigned int nr_cpus; -+ int cpu, err, irq; - - ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); - if (!ctrl) -@@ -352,6 +410,21 @@ static int realtek_gpio_probe(struct pla - girq->init_hw = realtek_gpio_irq_init; - } - -+ cpumask_clear(&ctrl->cpu_irq_maskable); -+ -+ if ((dev_flags & GPIO_INTERRUPTS_PER_CPU) && irq > 0) { -+ ctrl->cpumask_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); -+ if (IS_ERR(ctrl->cpumask_base)) -+ return dev_err_probe(dev, PTR_ERR(ctrl->cpumask_base), -+ "missing CPU IRQ mask registers"); -+ -+ nr_cpus = resource_size(res) / REALTEK_GPIO_PORTS_PER_BANK; -+ nr_cpus = min(nr_cpus, num_present_cpus()); -+ -+ for (cpu = 0; cpu < nr_cpus; cpu++) -+ cpumask_set_cpu(cpu, &ctrl->cpu_irq_maskable); -+ } -+ - return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl); - } - diff --git a/target/linux/realtek/patches-5.15/021-v5.19-04-gpio-realtek-otto-Add-RTL930x-support.patch b/target/linux/realtek/patches-5.15/021-v5.19-04-gpio-realtek-otto-Add-RTL930x-support.patch deleted file mode 100644 index 9b2580313898ca..00000000000000 --- a/target/linux/realtek/patches-5.15/021-v5.19-04-gpio-realtek-otto-Add-RTL930x-support.patch +++ /dev/null @@ -1,29 +0,0 @@ -From deaf1cecdeb052cdb5e92fd642016198724b44a4 Mon Sep 17 00:00:00 2001 -From: Sander Vanheule -Date: Sat, 9 Apr 2022 21:55:49 +0200 -Subject: [PATCH 4/6] gpio: realtek-otto: Add RTL930x support - -The RTL930x SoC series has support for 24 GPIOs, with the port order -reversed compared to RTL838x and RTL839x. The RTL930x series also has -two CPUs (VPEs) and can distribute individual GPIO interrupts between -them. - -Signed-off-by: Sander Vanheule -Signed-off-by: Bartosz Golaszewski ---- - drivers/gpio/gpio-realtek-otto.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/gpio/gpio-realtek-otto.c -+++ b/drivers/gpio/gpio-realtek-otto.c -@@ -335,6 +335,10 @@ static const struct of_device_id realtek - { - .compatible = "realtek,rtl8390-gpio", - }, -+ { -+ .compatible = "realtek,rtl9300-gpio", -+ .data = (void *)(GPIO_PORTS_REVERSED | GPIO_INTERRUPTS_PER_CPU) -+ }, - {} - }; - MODULE_DEVICE_TABLE(of, realtek_gpio_of_match); diff --git a/target/linux/realtek/patches-5.15/021-v5.19-06-gpio-realtek-otto-Add-RTL931x-support.patch b/target/linux/realtek/patches-5.15/021-v5.19-06-gpio-realtek-otto-Add-RTL931x-support.patch deleted file mode 100644 index 810856eb8911a3..00000000000000 --- a/target/linux/realtek/patches-5.15/021-v5.19-06-gpio-realtek-otto-Add-RTL931x-support.patch +++ /dev/null @@ -1,30 +0,0 @@ -From d3bf3dc4bbbf6109bd9b4bd60089d36205ec4a37 Mon Sep 17 00:00:00 2001 -From: Sander Vanheule -Date: Sat, 9 Apr 2022 21:55:51 +0200 -Subject: [PATCH 6/6] gpio: realtek-otto: Add RTL931x support - -The RTL931x SoC series has support for 32 GPIOs, although not all lines -may be broken out to a physical pad. - -The GPIO bank's parent interrupt can be routed to either or both of the -SoC's CPU cores by the GIC. Line-by-line IRQ balancing is not possible -on these SoCs. - -Signed-off-by: Sander Vanheule -Signed-off-by: Bartosz Golaszewski ---- - drivers/gpio/gpio-realtek-otto.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/gpio/gpio-realtek-otto.c -+++ b/drivers/gpio/gpio-realtek-otto.c -@@ -339,6 +339,9 @@ static const struct of_device_id realtek - .compatible = "realtek,rtl9300-gpio", - .data = (void *)(GPIO_PORTS_REVERSED | GPIO_INTERRUPTS_PER_CPU) - }, -+ { -+ .compatible = "realtek,rtl9310-gpio", -+ }, - {} - }; - MODULE_DEVICE_TABLE(of, realtek_gpio_of_match); diff --git a/target/linux/realtek/patches-5.15/300-mips-add-rtl838x-platform.patch b/target/linux/realtek/patches-5.15/300-mips-add-rtl838x-platform.patch deleted file mode 100644 index eaeea0991d5e69..00000000000000 --- a/target/linux/realtek/patches-5.15/300-mips-add-rtl838x-platform.patch +++ /dev/null @@ -1,86 +0,0 @@ -From fce11f68491b46b93df69de0630cd9edb90bc772 Mon Sep 17 00:00:00 2001 -From: Birger Koblitz -Date: Wed, 29 Dec 2021 21:54:21 +0100 -Subject: [PATCH] realtek: Create 4 different Realtek Platforms - -Creates RTL83XX as a basic kernel config parameter for the -RTL838X, RTL839x, RTL930X and RTL931X platforms with respective -configurations for the SoCs, which are introduced in addition. - -Submitted-by: Birger Koblitz ---- - arch/mips/Kbuild.platforms | 1 + - arch/mips/Kconfig | 57 ++++++++++++++ - 2 files changed, 58 insertions(+) - ---- a/arch/mips/Kbuild.platforms -+++ b/arch/mips/Kbuild.platforms -@@ -23,6 +23,7 @@ platform-$(CONFIG_NLM_COMMON) += netlog - platform-$(CONFIG_PIC32MZDA) += pic32/ - platform-$(CONFIG_RALINK) += ralink/ - platform-$(CONFIG_MIKROTIK_RB532) += rb532/ -+platform-$(CONFIG_RTL83XX) += rtl838x/ - platform-$(CONFIG_SGI_IP22) += sgi-ip22/ - platform-$(CONFIG_SGI_IP27) += sgi-ip27/ - platform-$(CONFIG_SGI_IP28) += sgi-ip22/ ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -1056,8 +1056,58 @@ config NLM_XLP_BOARD - This board is based on Netlogic XLP Processor. - Say Y here if you have a XLP based board. - -+config RTL83XX -+ bool "Realtek based platforms" -+ select DMA_NONCOHERENT -+ select IRQ_MIPS_CPU -+ select NO_EXCEPT_FILL -+ select SYS_HAS_CPU_MIPS32_R1 -+ select SYS_HAS_CPU_MIPS32_R2 -+ select SYS_SUPPORTS_BIG_ENDIAN -+ select SYS_SUPPORTS_HIGHMEM -+ select SYS_SUPPORTS_32BIT_KERNEL -+ select SYS_SUPPORTS_MIPS16 -+ select SYS_HAS_EARLY_PRINTK -+ select SYS_HAS_EARLY_PRINTK_8250 -+ select USE_GENERIC_EARLY_PRINTK_8250 -+ select BOOT_RAW -+ select PINCTRL -+ select ARCH_HAS_RESET_CONTROLLER -+ select RESET_CONTROLLER -+ select USE_OF -+ - endchoice - -+config RTL838X -+ bool "Realtek RTL838X based platforms" -+ depends on RTL83XX -+ select CPU_SUPPORTS_CPUFREQ -+ select MIPS_EXTERNAL_TIMER -+ -+config RTL839X -+ bool "Realtek RTL839X based platforms" -+ depends on RTL83XX -+ select CPU_SUPPORTS_CPUFREQ -+ select MIPS_EXTERNAL_TIMER -+ select SYS_SUPPORTS_MULTITHREADING -+ -+config RTL930X -+ bool "Realtek RTL930X based platforms" -+ depends on RTL83XX -+ select MIPS_CPU_SCACHE -+ select MIPS_EXTERNAL_TIMER -+ select SYS_SUPPORTS_MULTITHREADING -+ -+config RTL931X -+ bool "Realtek RTL931X based platforms" -+ depends on RTL930X -+ select MIPS_GIC -+ select COMMON_CLK -+ select CLKSRC_MIPS_GIC -+ select SYS_SUPPORTS_VPE_LOADER -+ select SYS_SUPPORTS_SMP -+ select SYS_SUPPORTS_MIPS_CPS -+ - source "arch/mips/alchemy/Kconfig" - source "arch/mips/ath25/Kconfig" - source "arch/mips/ath79/Kconfig" diff --git a/target/linux/realtek/patches-5.15/301-gpio-add-rtl8231-driver.patch b/target/linux/realtek/patches-5.15/301-gpio-add-rtl8231-driver.patch deleted file mode 100644 index 7603a037442445..00000000000000 --- a/target/linux/realtek/patches-5.15/301-gpio-add-rtl8231-driver.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 26 Nov 2020 12:02:21 +0100 -Subject: [PATCH] realtek: update the tree to the latest refactored version -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -* rename the target to realtek -* add refactored DSA driver -* add latest gpio driver -* lots of arch cleanups -* new irq driver -* additional boards - -Submitted-by: Bert Vermeulen -Submitted-by: Birger Koblitz -Submitted-by: Sander Vanheule -Submitted-by: Bjørn Mork -Submitted-by: John Crispin ---- - drivers/gpio/Kconfig | 6 ++++++ - drivers/gpio/Makefile | 1 + - 2 files changed, 7 insertions(+) - ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -529,6 +529,12 @@ config GPIO_ROCKCHIP - help - Say yes here to support GPIO on Rockchip SoCs. - -+config GPIO_RTL8231 -+ tristate "RTL8231 GPIO" -+ depends on RTL83XX -+ help -+ Say yes here to support Realtek RTL8231 GPIO expansion chips. -+ - config GPIO_SAMA5D2_PIOBU - tristate "SAMA5D2 PIOBU GPIO support" - depends on MFD_SYSCON ---- a/drivers/gpio/Makefile -+++ b/drivers/gpio/Makefile -@@ -129,6 +129,7 @@ obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc3 - obj-$(CONFIG_GPIO_REALTEK_OTTO) += gpio-realtek-otto.o - obj-$(CONFIG_GPIO_REG) += gpio-reg.o - obj-$(CONFIG_GPIO_ROCKCHIP) += gpio-rockchip.o -+obj-$(CONFIG_GPIO_RTL8231) += gpio-rtl8231.o - obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o - obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o - obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o diff --git a/target/linux/realtek/patches-5.15/302-clocksource-add-otto-driver.patch b/target/linux/realtek/patches-5.15/302-clocksource-add-otto-driver.patch deleted file mode 100644 index 63a5050ebb5fa9..00000000000000 --- a/target/linux/realtek/patches-5.15/302-clocksource-add-otto-driver.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 3cc8011171186d906c547bc6f0c1f8e350edc7cf Mon Sep 17 00:00:00 2001 -From: Markus Stockhausen -Date: Mon, 3 Oct 2022 14:45:21 +0200 -Subject: [PATCH] realtek: resurrect timer driver - -Now that we provide a clock driver for the Reltek SOCs the CPU frequency might -change on demand. This has direct visible effects during operation - -- the CEVT 4K timer is no longer a stable clocksource -- after CPU frequencies changes time calculation works wrong -- sched_clock falls back to kernel default interval (100 Hz) -- timestamps in dmesg have only 2 digits left - -[ 0.000000] sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps ... -[ 0.060000] pid_max: default: 32768 minimum: 301 -[ 0.070000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) -[ 0.070000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) -[ 0.080000] dyndbg: Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build -[ 0.090000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, ... - -Looking around where we can start the CEVT timer for RTL930X is a good basis. -Initially it was developed as a clocksource driver for the broken timer in that -specific SOC series. Afterwards it was shifted around to the CEVT location, -got SMP enablement and lost its clocksource feature. So we at least have -something to copy from. As the timers on these devices are well understood -the implementation follows this way: - -- leave the RTL930X implementation as is -- provide a new driver for RTL83XX devices only -- swap RTL930X driver at a later time - -Like the clock driver this patch contains a self contained module that is SOC -independet and already provides full support for the RTL838X, RTL839X and -RTL930X devices. Some of the new (or reestablished) features are: - -- simplified initialization routines -- SMP setup with CPU hotplug framework -- derived from LXB clock speed -- supplied clocksource -- dedicated register functions for better readability -- documentation about some caveats - -Signed-off-by: Markus Stockhausen -[remove unused header includes, remove old CONFIG_MIPS dependency, add -REALTEK_ prefix to driver symbol] -Signed-off-by: Sander Vanheule - ---- - drivers/clocksource/Kconfig | 12 +++ - drivers/clocksource/Makefile | 1 + - include/linux/cpuhotplug.h | 1 + - 3 files changed, 14 insertions(+) - ---- a/drivers/clocksource/Kconfig -+++ b/drivers/clocksource/Kconfig -@@ -127,6 +127,17 @@ config RDA_TIMER - help - Enables the support for the RDA Micro timer driver. - -+config REALTEK_OTTO_TIMER -+ bool "Clocksource/timer for the Realtek Otto platform" -+ select COMMON_CLK -+ select TIMER_OF -+ help -+ This driver adds support for the timers found in the Realtek RTL83xx -+ and RTL93xx SoCs series. This includes chips such as RTL8380, RTL8381 -+ and RTL832, as well as chips from the RTL839x series, such as RTL8390 -+ RT8391, RTL8392, RTL8393 and RTL8396 and chips of the RTL930x series -+ such as RTL9301, RTL9302 or RTL9303. -+ - config SUN4I_TIMER - bool "Sun4i timer driver" if COMPILE_TEST - depends on HAS_IOMEM ---- a/drivers/clocksource/Makefile -+++ b/drivers/clocksource/Makefile -@@ -58,6 +58,7 @@ obj-$(CONFIG_MILBEAUT_TIMER) += timer-mi - obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o - obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o - obj-$(CONFIG_RDA_TIMER) += timer-rda.o -+obj-$(CONFIG_REALTEK_OTTO_TIMER) += timer-rtl-otto.o - - obj-$(CONFIG_ARC_TIMERS) += arc_timer.o - obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o ---- a/include/linux/cpuhotplug.h -+++ b/include/linux/cpuhotplug.h -@@ -176,6 +176,7 @@ enum cpuhp_state { - CPUHP_AP_MARCO_TIMER_STARTING, - CPUHP_AP_MIPS_GIC_TIMER_STARTING, - CPUHP_AP_ARC_TIMER_STARTING, -+ CPUHP_AP_REALTEK_TIMER_STARTING, - CPUHP_AP_RISCV_TIMER_STARTING, - CPUHP_AP_CLINT_TIMER_STARTING, - CPUHP_AP_CSKY_TIMER_STARTING, diff --git a/target/linux/realtek/patches-5.15/303-gpio-update-dependencies-for-gpio-realtek-otto.patch b/target/linux/realtek/patches-5.15/303-gpio-update-dependencies-for-gpio-realtek-otto.patch deleted file mode 100644 index beaddcb58e624d..00000000000000 --- a/target/linux/realtek/patches-5.15/303-gpio-update-dependencies-for-gpio-realtek-otto.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9bac1c20b8f39f2e0e342b087add5093b94feaed Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Wed, 5 May 2021 22:05:39 +0900 -Subject: realtek: backport gpio-realtek-otto driver from 5.13 to 5.10 - -This patch backports "gpio-realtek-otto" driver to Kernel 5.10. -"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X" -is used in OpenWrt, so update the dependency by the additional patch. - -Submitted-by: INAGAKI Hiroshi ---- - drivers/gpio/Kconfig | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -503,8 +503,8 @@ config GPIO_RDA - - config GPIO_REALTEK_OTTO - tristate "Realtek Otto GPIO support" -- depends on MACH_REALTEK_RTL -- default MACH_REALTEK_RTL -+ depends on RTL83XX -+ default RTL838X - select GPIO_GENERIC - select GPIOLIB_IRQCHIP - help diff --git a/target/linux/realtek/patches-5.15/304-spi-update-dependency-for-spi-realtek-rtl.patch b/target/linux/realtek/patches-5.15/304-spi-update-dependency-for-spi-realtek-rtl.patch deleted file mode 100644 index f2b57bacde9916..00000000000000 --- a/target/linux/realtek/patches-5.15/304-spi-update-dependency-for-spi-realtek-rtl.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0b000cbfe0aa0323bffa855ef8449c0687a4c071 Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Thu, 6 May 2021 19:30:58 +0900 -Subject: realtek: backport spi-realtek-rtl driver from 5.12 to 5.10 - -This patch backports "spi-realtek-rtl" driver to Kernel 5.10 from 5.12. -"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X" -is used in OpenWrt, so update the dependency by the additional patch. - -Submitted-by: INAGAKI Hiroshi ---- - drivers/spi/Makefile | 2 +- - 1 files changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -97,7 +97,7 @@ obj-$(CONFIG_SPI_QUP) += spi-qup.o - obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o - obj-$(CONFIG_SPI_ROCKCHIP_SFC) += spi-rockchip-sfc.o - obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o --obj-$(CONFIG_MACH_REALTEK_RTL) += spi-realtek-rtl.o -+obj-$(CONFIG_RTL83XX) += spi-realtek-rtl.o - obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o - obj-$(CONFIG_SPI_RSPI) += spi-rspi.o - obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o diff --git a/target/linux/realtek/patches-5.15/305-irqchip-update-dependency-for-irq-realtek-rtl.patch b/target/linux/realtek/patches-5.15/305-irqchip-update-dependency-for-irq-realtek-rtl.patch deleted file mode 100644 index a94a3ff8ac7968..00000000000000 --- a/target/linux/realtek/patches-5.15/305-irqchip-update-dependency-for-irq-realtek-rtl.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 2cd00b51470a30198b048a5fca48a04db77e29cc Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Fri, 21 May 2021 23:16:37 +0900 -Subject: [PATCH] realtek: backport irq-realtek-rtl driver from 5.12 to 5.10 - -This patch backports "irq-realtek-rtl" driver to Kernel 5.10 from 5.12. -"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X" -is used in OpenWrt, so update the dependency by the additional patch. - -Submitted-by: INAGAKI Hiroshi ---- - drivers/irqchip/Makefile | 2 +- - 1 files changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/irqchip/Makefile -+++ b/drivers/irqchip/Makefile -@@ -112,7 +112,7 @@ obj-$(CONFIG_LOONGSON_PCH_PIC) += irq-l - obj-$(CONFIG_LOONGSON_PCH_MSI) += irq-loongson-pch-msi.o - obj-$(CONFIG_MST_IRQ) += irq-mst-intc.o - obj-$(CONFIG_SL28CPLD_INTC) += irq-sl28cpld.o --obj-$(CONFIG_MACH_REALTEK_RTL) += irq-realtek-rtl.o -+obj-$(CONFIG_RTL83XX) += irq-realtek-rtl.o - obj-$(CONFIG_WPCM450_AIC) += irq-wpcm450-aic.o - obj-$(CONFIG_IRQ_IDT3243X) += irq-idt3243x.o - obj-$(CONFIG_APPLE_AIC) += irq-apple-aic.o diff --git a/target/linux/realtek/patches-5.15/307-wdt-update-dependency-for-realtek-otto-wdt.patch b/target/linux/realtek/patches-5.15/307-wdt-update-dependency-for-realtek-otto-wdt.patch deleted file mode 100644 index b44aebea129c41..00000000000000 --- a/target/linux/realtek/patches-5.15/307-wdt-update-dependency-for-realtek-otto-wdt.patch +++ /dev/null @@ -1,32 +0,0 @@ -From b8fc5eecdc5d33cf261986436597b5482ab856da Mon Sep 17 00:00:00 2001 -From: Sander Vanheule -Date: Sun, 14 Nov 2021 19:45:32 +0100 -Subject: [PATCH] realtek: Backport Realtek Otto WDT driver - -Add patch submitted upstream to linux-watchdog and replace the MIPS -architecture symbols. Requires one extra patch for the DIV_ROUND_* -macros, which have moved to a different header since 5.10. - -Submitted-by: Sander Vanheule -Tested-by: Stijn Segers -Tested-by: Paul Fertser -Tested-by: Stijn Tintel ---- - drivers/watchdog/Kconfig | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/watchdog/Kconfig -+++ b/drivers/watchdog/Kconfig -@@ -956,10 +956,10 @@ config RTD119X_WATCHDOG - - config REALTEK_OTTO_WDT - tristate "Realtek Otto MIPS watchdog support" -- depends on MACH_REALTEK_RTL || COMPILE_TEST -+ depends on RTL83XX - depends on COMMON_CLK - select WATCHDOG_CORE -- default MACH_REALTEK_RTL -+ default RTL83XX - help - Say Y here to include support for the watchdog timer on Realtek - RTL838x, RTL839x, RTL930x SoCs. This watchdog has pretimeout diff --git a/target/linux/realtek/patches-5.15/308-otto-wdt-fix-missing-math-header.patch b/target/linux/realtek/patches-5.15/308-otto-wdt-fix-missing-math-header.patch deleted file mode 100644 index 78b145617fabcc..00000000000000 --- a/target/linux/realtek/patches-5.15/308-otto-wdt-fix-missing-math-header.patch +++ /dev/null @@ -1,28 +0,0 @@ -From b8fc5eecdc5d33cf261986436597b5482ab856da Mon Sep 17 00:00:00 2001 -From: Sander Vanheule -Date: Sun, 14 Nov 2021 19:45:32 +0100 -Subject: [PATCH] realtek: Backport Realtek Otto WDT driver - -Add patch submitted upstream to linux-watchdog and replace the MIPS -architecture symbols. Requires one extra patch for the DIV_ROUND_* -macros, which have moved to a different header since 5.10. - -Submitted-by: Sander Vanheule -Tested-by: Stijn Segers -Tested-by: Paul Fertser -Tested-by: Stijn Tintel ---- - drivers/watchdog/realtek_otto_wdt.c | 2 +- - 1 files changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/watchdog/realtek_otto_wdt.c -+++ b/drivers/watchdog/realtek_otto_wdt.c -@@ -21,7 +21,7 @@ - #include - #include - #include --#include -+#include - #include - #include - #include diff --git a/target/linux/realtek/patches-5.15/310-add-i2c-rtl9300-support.patch b/target/linux/realtek/patches-5.15/310-add-i2c-rtl9300-support.patch deleted file mode 100644 index 2125aea77f0cf4..00000000000000 --- a/target/linux/realtek/patches-5.15/310-add-i2c-rtl9300-support.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 63a0a4d85bc900464c5b046b13808a582345f8c8 Mon Sep 17 00:00:00 2001 -From: Birger Koblitz -Date: Sat, 11 Dec 2021 20:14:47 +0100 -Subject: [PATCH] realtek: Add support for RTL9300/RTL9310 I2C controller - -This adds support for the RTL9300 and RTL9310 I2C controller. -The controller implements the SMBus protocol for SMBus transfers -over an I2C bus. The driver supports selecting one of the 2 possible -SCL pins and any of the 8 possible SDA pins. Bus speeds of -100kHz (standard speed) and 400kHz (high speed I2C) are supported. - -Submitted-by: Birger Koblitz ---- - drivers/i2c/busses/Kconfig | 10 +++++++++ - drivers/i2c/busses/Makefile | 1 + - 2 files changed, 11 insertions(+) - ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -949,6 +949,16 @@ config I2C_RK3X - This driver can also be built as a module. If so, the module will - be called i2c-rk3x. - -+config I2C_RTL9300 -+ tristate "Realtek RTL9300 I2C adapter" -+ depends on OF -+ help -+ Say Y here to include support for the I2C adapter in Realtek RTL9300 -+ and RTL9310 SoCs. -+ -+ This driver can also be built as a module. If so, the module will -+ be called i2c-rtl9300. -+ - config HAVE_S3C2410_I2C - bool - help ---- a/drivers/i2c/busses/Makefile -+++ b/drivers/i2c/busses/Makefile -@@ -94,6 +94,7 @@ obj-$(CONFIG_I2C_QCOM_GENI) += i2c-qcom- - obj-$(CONFIG_I2C_QUP) += i2c-qup.o - obj-$(CONFIG_I2C_RIIC) += i2c-riic.o - obj-$(CONFIG_I2C_RK3X) += i2c-rk3x.o -+obj-$(CONFIG_I2C_RTL9300) += i2c-rtl9300.o - obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o - obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o - obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o diff --git a/target/linux/realtek/patches-5.15/311-add-i2c-mux-rtl9300-support.patch b/target/linux/realtek/patches-5.15/311-add-i2c-mux-rtl9300-support.patch deleted file mode 100644 index d0bfba45381f5c..00000000000000 --- a/target/linux/realtek/patches-5.15/311-add-i2c-mux-rtl9300-support.patch +++ /dev/null @@ -1,46 +0,0 @@ -From f4bdb7fdccdfe3fa382abe77f72a16c2f2e6add0 Mon Sep 17 00:00:00 2001 -From: Birger Koblitz -Date: Sat, 11 Dec 2021 20:25:37 +0100 -Subject: [PATCH] realtek: Add support for RTL9300/RTL9310 I2C multiplexing - -The RTL9300/RTL9310 I2C controllers have support for 2 independent I2C -masters, each with a fixed SCL pin, that cannot be changed. Each of these -masters can use 8 (RTL9300) or 16 (RTL9310) different pins for SDA. -This multiplexer directly controls the two masters and their shared -IO configuration registers to allow multiplexing between any of these -busses. The two masters cannot be used in parallel as the multiplex -is protected by a standard multiplex lock. - -Submitted-by: Birger Koblitz ---- - drivers/i2c/muxes/Kconfig | 9 +++++++ - drivers/i2c/muxes/Makefile | 1 + - 2 files changed, 10 insertions(+) - ---- a/drivers/i2c/muxes/Kconfig -+++ b/drivers/i2c/muxes/Kconfig -@@ -99,6 +99,15 @@ config I2C_MUX_REG - This driver can also be built as a module. If so, the module - will be called i2c-mux-reg. - -+config I2C_MUX_RTL9300 -+ tristate "RTL9300 based I2C multiplexer" -+ help -+ If you say yes to this option, support will be included for a -+ RTL9300 based I2C multiplexer. -+ -+ This driver can also be built as a module. If so, the module -+ will be called i2c-mux-reg. -+ - config I2C_DEMUX_PINCTRL - tristate "pinctrl-based I2C demultiplexer" - depends on PINCTRL && OF ---- a/drivers/i2c/muxes/Makefile -+++ b/drivers/i2c/muxes/Makefile -@@ -14,5 +14,6 @@ obj-$(CONFIG_I2C_MUX_PCA9541) += i2c-mux - obj-$(CONFIG_I2C_MUX_PCA954x) += i2c-mux-pca954x.o - obj-$(CONFIG_I2C_MUX_PINCTRL) += i2c-mux-pinctrl.o - obj-$(CONFIG_I2C_MUX_REG) += i2c-mux-reg.o -+obj-$(CONFIG_I2C_MUX_RTL9300) += i2c-mux-rtl9300.o - - ccflags-$(CONFIG_I2C_DEBUG_BUS) := -DDEBUG diff --git a/target/linux/realtek/patches-5.15/315-irqchip-irq-realtek-rtl-add-VPE-support.patch b/target/linux/realtek/patches-5.15/315-irqchip-irq-realtek-rtl-add-VPE-support.patch deleted file mode 100644 index 102c9850ce4413..00000000000000 --- a/target/linux/realtek/patches-5.15/315-irqchip-irq-realtek-rtl-add-VPE-support.patch +++ /dev/null @@ -1,402 +0,0 @@ -From 6c18e9c491959ac0674ebe36b09f9ddc3f2c9bce Mon Sep 17 00:00:00 2001 -From: Birger Koblitz -Date: Fri, 31 Dec 2021 11:56:49 +0100 -Subject: [PATCH] realtek: Add VPE support for the IRQ driver - -In order to support VSMP, enable support for both VPEs -of the RTL839X and RTL930X SoCs in the irq-realtek-rtl -driver. Add support for IRQ affinity setting. - -Submitted-by: Birger Koblitz ---- - drivers/irqchip/irq-realtek-rtl.c | 152 +++++++++++++++--- - 1 file changed, 73 insertions(+), 76 deletions(-) - ---- a/drivers/irqchip/irq-realtek-rtl.c -+++ b/drivers/irqchip/irq-realtek-rtl.c -@@ -21,21 +21,63 @@ - #define RTL_ICTL_IRR2 0x10 - #define RTL_ICTL_IRR3 0x14 - --#define REG(x) (realtek_ictl_base + x) -+#define RTL_ICTL_NUM_INPUTS 32 -+#define RTL_ICTL_NUM_OUTPUTS 15 - - static DEFINE_RAW_SPINLOCK(irq_lock); --static void __iomem *realtek_ictl_base; -+ -+#define REG(offset, cpu) (realtek_ictl_base[cpu] + offset) -+ -+static void __iomem *realtek_ictl_base[NR_CPUS]; -+static cpumask_t realtek_ictl_cpu_configurable; -+ -+struct realtek_ictl_output { -+ /* IRQ controller data */ -+ struct fwnode_handle *fwnode; -+ /* Output specific data */ -+ unsigned int output_index; -+ struct irq_domain *domain; -+ u32 child_mask; -+}; -+ -+/* -+ * IRR0-IRR3 store 4 bits per interrupt, but Realtek uses inverted numbering, -+ * placing IRQ 31 in the first four bits. A routing value of '0' means the -+ * interrupt is left disconnected. Routing values {1..15} connect to output -+ * lines {0..14}. -+ */ -+#define IRR_OFFSET(idx) (4 * (3 - (idx * 4) / 32)) -+#define IRR_SHIFT(idx) ((idx * 4) % 32) -+ -+static inline u32 read_irr(void __iomem *irr0, int idx) -+{ -+ return (readl(irr0 + IRR_OFFSET(idx)) >> IRR_SHIFT(idx)) & 0xf; -+} -+ -+static inline void write_irr(void __iomem *irr0, int idx, u32 value) -+{ -+ unsigned int offset = IRR_OFFSET(idx); -+ unsigned int shift = IRR_SHIFT(idx); -+ u32 irr; -+ -+ irr = readl(irr0 + offset) & ~(0xf << shift); -+ irr |= (value & 0xf) << shift; -+ writel(irr, irr0 + offset); -+} - - static void realtek_ictl_unmask_irq(struct irq_data *i) - { - unsigned long flags; - u32 value; -+ int cpu; - - raw_spin_lock_irqsave(&irq_lock, flags); - -- value = readl(REG(RTL_ICTL_GIMR)); -- value |= BIT(i->hwirq); -- writel(value, REG(RTL_ICTL_GIMR)); -+ for_each_cpu(cpu, &realtek_ictl_cpu_configurable) { -+ value = readl(REG(RTL_ICTL_GIMR, cpu)); -+ value |= BIT(i->hwirq); -+ writel(value, REG(RTL_ICTL_GIMR, cpu)); -+ } - - raw_spin_unlock_irqrestore(&irq_lock, flags); - } -@@ -44,52 +86,137 @@ static void realtek_ictl_mask_irq(struct - { - unsigned long flags; - u32 value; -+ int cpu; - - raw_spin_lock_irqsave(&irq_lock, flags); - -- value = readl(REG(RTL_ICTL_GIMR)); -- value &= ~BIT(i->hwirq); -- writel(value, REG(RTL_ICTL_GIMR)); -+ for_each_cpu(cpu, &realtek_ictl_cpu_configurable) { -+ value = readl(REG(RTL_ICTL_GIMR, cpu)); -+ value &= ~BIT(i->hwirq); -+ writel(value, REG(RTL_ICTL_GIMR, cpu)); -+ } - - raw_spin_unlock_irqrestore(&irq_lock, flags); - } - -+static int __maybe_unused realtek_ictl_irq_affinity(struct irq_data *i, -+ const struct cpumask *dest, bool force) -+{ -+ struct realtek_ictl_output *output = i->domain->host_data; -+ cpumask_t cpu_configure; -+ cpumask_t cpu_disable; -+ cpumask_t cpu_enable; -+ unsigned long flags; -+ int cpu; -+ -+ raw_spin_lock_irqsave(&irq_lock, flags); -+ -+ cpumask_and(&cpu_configure, cpu_present_mask, &realtek_ictl_cpu_configurable); -+ -+ cpumask_and(&cpu_enable, &cpu_configure, dest); -+ cpumask_andnot(&cpu_disable, &cpu_configure, dest); -+ -+ for_each_cpu(cpu, &cpu_disable) -+ write_irr(REG(RTL_ICTL_IRR0, cpu), i->hwirq, 0); -+ -+ for_each_cpu(cpu, &cpu_enable) -+ write_irr(REG(RTL_ICTL_IRR0, cpu), i->hwirq, output->output_index + 1); -+ -+ irq_data_update_effective_affinity(i, &cpu_enable); -+ -+ raw_spin_unlock_irqrestore(&irq_lock, flags); -+ -+ return IRQ_SET_MASK_OK; -+} -+ - static struct irq_chip realtek_ictl_irq = { - .name = "realtek-rtl-intc", - .irq_mask = realtek_ictl_mask_irq, - .irq_unmask = realtek_ictl_unmask_irq, -+#ifdef CONFIG_SMP -+ .irq_set_affinity = realtek_ictl_irq_affinity, -+#endif - }; - - static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) - { -+ struct realtek_ictl_output *output = d->host_data; -+ unsigned long flags; -+ - irq_set_chip_and_handler(irq, &realtek_ictl_irq, handle_level_irq); - -+ raw_spin_lock_irqsave(&irq_lock, flags); -+ -+ output->child_mask |= BIT(hw); -+ write_irr(REG(RTL_ICTL_IRR0, 0), hw, output->output_index + 1); -+ -+ raw_spin_unlock_irqrestore(&irq_lock, flags); -+ - return 0; - } - -+static int intc_select(struct irq_domain *d, struct irq_fwspec *fwspec, -+ enum irq_domain_bus_token bus_token) -+{ -+ struct realtek_ictl_output *output = d->host_data; -+ bool routed_elsewhere; -+ unsigned long flags; -+ u32 routing_old; -+ int cpu; -+ -+ if (fwspec->fwnode != output->fwnode) -+ return false; -+ -+ /* Original specifiers had only one parameter */ -+ if (fwspec->param_count < 2) -+ return true; -+ -+ raw_spin_lock_irqsave(&irq_lock, flags); -+ -+ /* -+ * Inputs can only be routed to one output, so they shouldn't be -+ * allowed to end up in multiple domains. -+ */ -+ for_each_cpu(cpu, &realtek_ictl_cpu_configurable) { -+ routing_old = read_irr(REG(RTL_ICTL_IRR0, cpu), fwspec->param[0]); -+ routed_elsewhere = routing_old && fwspec->param[1] != routing_old - 1; -+ if (routed_elsewhere) { -+ pr_warn("soc int %d already routed to output %d\n", -+ fwspec->param[0], routing_old - 1); -+ break; -+ } -+ } -+ -+ raw_spin_unlock_irqrestore(&irq_lock, flags); -+ -+ return !routed_elsewhere && fwspec->param[1] == output->output_index; -+} -+ - static const struct irq_domain_ops irq_domain_ops = { - .map = intc_map, -+ .select = intc_select, - .xlate = irq_domain_xlate_onecell, - }; - - static void realtek_irq_dispatch(struct irq_desc *desc) - { -+ struct realtek_ictl_output *output = irq_desc_get_handler_data(desc); - struct irq_chip *chip = irq_desc_get_chip(desc); -- struct irq_domain *domain; -+ int cpu = smp_processor_id(); - unsigned long pending; - unsigned int soc_int; - - chained_irq_enter(chip, desc); -- pending = readl(REG(RTL_ICTL_GIMR)) & readl(REG(RTL_ICTL_GISR)); -+ pending = readl(REG(RTL_ICTL_GIMR, cpu)) & readl(REG(RTL_ICTL_GISR, cpu)) -+ & output->child_mask; - - if (unlikely(!pending)) { - spurious_interrupt(); - goto out; - } - -- domain = irq_desc_get_handler_data(desc); -- for_each_set_bit(soc_int, &pending, 32) -- generic_handle_domain_irq(domain, soc_int); -+ for_each_set_bit(soc_int, &pending, RTL_ICTL_NUM_INPUTS) -+ generic_handle_domain_irq(output->domain, soc_int); - - out: - chained_irq_exit(chip, desc); -@@ -102,85 +229,110 @@ out: - * thus go into 4 IRRs. A routing value of '0' means the interrupt is left - * disconnected. Routing values {1..15} connect to output lines {0..14}. - */ --static int __init map_interrupts(struct device_node *node, struct irq_domain *domain) -+static int __init setup_parent_interrupts(struct device_node *node, int *parents, -+ unsigned int num_parents) - { -- struct device_node *cpu_ictl; -- const __be32 *imap; -- u32 imaplen, soc_int, cpu_int, tmp, regs[4]; -- int ret, i, irr_regs[] = { -- RTL_ICTL_IRR3, -- RTL_ICTL_IRR2, -- RTL_ICTL_IRR1, -- RTL_ICTL_IRR0, -- }; -- u8 mips_irqs_set; -+ struct realtek_ictl_output *outputs; -+ struct realtek_ictl_output *output; -+ struct irq_domain *domain; -+ unsigned int p; - -- ret = of_property_read_u32(node, "#address-cells", &tmp); -- if (ret || tmp) -- return -EINVAL; -+ outputs = kcalloc(num_parents, sizeof(*outputs), GFP_KERNEL); -+ if (!outputs) -+ return -ENOMEM; - -- imap = of_get_property(node, "interrupt-map", &imaplen); -- if (!imap || imaplen % 3) -- return -EINVAL; -+ for (p = 0; p < num_parents; p++) { -+ output = outputs + p; - -- mips_irqs_set = 0; -- memset(regs, 0, sizeof(regs)); -- for (i = 0; i < imaplen; i += 3 * sizeof(u32)) { -- soc_int = be32_to_cpup(imap); -- if (soc_int > 31) -- return -EINVAL; -- -- cpu_ictl = of_find_node_by_phandle(be32_to_cpup(imap + 1)); -- if (!cpu_ictl) -- return -EINVAL; -- ret = of_property_read_u32(cpu_ictl, "#interrupt-cells", &tmp); -- of_node_put(cpu_ictl); -- if (ret || tmp != 1) -- return -EINVAL; -- -- cpu_int = be32_to_cpup(imap + 2); -- if (cpu_int > 7 || cpu_int < 2) -- return -EINVAL; -- -- if (!(mips_irqs_set & BIT(cpu_int))) { -- irq_set_chained_handler_and_data(cpu_int, realtek_irq_dispatch, -- domain); -- mips_irqs_set |= BIT(cpu_int); -- } -+ domain = irq_domain_add_linear(node, RTL_ICTL_NUM_INPUTS, &irq_domain_ops, output); -+ if (!domain) -+ goto domain_err; - -- /* Use routing values (1..6) for CPU interrupts (2..7) */ -- regs[(soc_int * 4) / 32] |= (cpu_int - 1) << (soc_int * 4) % 32; -- imap += 3; -- } -+ output->fwnode = of_node_to_fwnode(node); -+ output->output_index = p; -+ output->domain = domain; - -- for (i = 0; i < 4; i++) -- writel(regs[i], REG(irr_regs[i])); -+ irq_set_chained_handler_and_data(parents[p], realtek_irq_dispatch, output); -+ } - - return 0; -+ -+domain_err: -+ while (p--) { -+ irq_set_chained_handler_and_data(parents[p], NULL, NULL); -+ irq_domain_remove(outputs[p].domain); -+ } -+ -+ kfree(outputs); -+ -+ return -ENOMEM; - } - - static int __init realtek_rtl_of_init(struct device_node *node, struct device_node *parent) - { -- struct irq_domain *domain; -- int ret; -+ int parent_irqs[RTL_ICTL_NUM_OUTPUTS]; -+ struct of_phandle_args oirq; -+ unsigned int num_parents; -+ unsigned int soc_irq; -+ unsigned int p; -+ int cpu; -+ -+ cpumask_clear(&realtek_ictl_cpu_configurable); -+ -+ for (cpu = 0; cpu < NR_CPUS; cpu++) { -+ realtek_ictl_base[cpu] = of_iomap(node, cpu); -+ if (realtek_ictl_base[cpu]) { -+ cpumask_set_cpu(cpu, &realtek_ictl_cpu_configurable); -+ -+ /* Disable all cascaded interrupts and clear routing */ -+ writel(0, REG(RTL_ICTL_GIMR, cpu)); -+ for (soc_irq = 0; soc_irq < RTL_ICTL_NUM_INPUTS; soc_irq++) -+ write_irr(REG(RTL_ICTL_IRR0, cpu), soc_irq, 0); -+ } -+ } - -- realtek_ictl_base = of_iomap(node, 0); -- if (!realtek_ictl_base) -+ if (cpumask_empty(&realtek_ictl_cpu_configurable)) - return -ENXIO; - -- /* Disable all cascaded interrupts */ -- writel(0, REG(RTL_ICTL_GIMR)); -+ num_parents = of_irq_count(node); -+ if (num_parents > RTL_ICTL_NUM_OUTPUTS) { -+ pr_err("too many parent interrupts\n"); -+ return -EINVAL; -+ } - -- domain = irq_domain_add_simple(node, 32, 0, -- &irq_domain_ops, NULL); -+ for (p = 0; p < num_parents; p++) -+ parent_irqs[p] = of_irq_get(node, p); - -- ret = map_interrupts(node, domain); -- if (ret) { -- pr_err("invalid interrupt map\n"); -- return ret; -+ if (WARN_ON(!num_parents)) { -+ /* -+ * If DT contains no parent interrupts, assume MIPS CPU IRQ 2 -+ * (HW0) is connected to the first output. This is the case for -+ * all known hardware anyway. "interrupt-map" is deprecated, so -+ * don't bother trying to parse that. -+ * Since this is to account for old devicetrees with one-cell -+ * interrupt specifiers, only one output domain is needed. -+ */ -+ oirq.np = of_find_compatible_node(NULL, NULL, "mti,cpu-interrupt-controller"); -+ if (oirq.np) { -+ oirq.args_count = 1; -+ oirq.args[0] = 2; -+ -+ parent_irqs[0] = irq_create_of_mapping(&oirq); -+ num_parents = 1; -+ } -+ -+ of_node_put(oirq.np); - } - -- return 0; -+ /* Ensure we haven't collected any errors before proceeding */ -+ for (p = 0; p < num_parents; p++) { -+ if (parent_irqs[p] < 0) -+ return parent_irqs[p]; -+ if (!parent_irqs[p]) -+ return -ENODEV; -+ } -+ -+ return setup_parent_interrupts(node, &parent_irqs[0], num_parents); - } - - IRQCHIP_DECLARE(realtek_rtl_intc, "realtek,rtl-intc", realtek_rtl_of_init); diff --git a/target/linux/realtek/patches-5.15/316-otto-gpio-uniprocessor-irq-mask.patch b/target/linux/realtek/patches-5.15/316-otto-gpio-uniprocessor-irq-mask.patch deleted file mode 100644 index a13d70d6335e0b..00000000000000 --- a/target/linux/realtek/patches-5.15/316-otto-gpio-uniprocessor-irq-mask.patch +++ /dev/null @@ -1,51 +0,0 @@ -From bde6311569ef25a00c3beaeabfd6b78b19651872 Mon Sep 17 00:00:00 2001 -From: Sander Vanheule -Date: Sun, 29 May 2022 19:38:09 +0200 -Subject: [PATCH] realtek: don't unmask non-maskable GPIO IRQs - -On uniprocessor builds, for_each_cpu(cpu, mask) will assume 'mask' -always contains exactly one CPU, and ignore the actual mask contents. -This causes the loop to run, even when it shouldn't on an empty mask, -and tries to access an uninitialised pointer. - -Fix this by wrapping the loop in a cpumask_empty() check, to ensure it -will not run on uniprocessor builds if the CPU mask is empty. - -Fixes: af6cd37f42f3 ("realtek: replace RTL93xx GPIO patches") -Reported-by: INAGAKI Hiroshi -Reported-by: Robert Marko -Tested-by: Robert Marko -Submitted-by: Sander Vanheule ---- - drivers/gpio/gpio-realtek-otto.c | 9 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - ---- a/drivers/gpio/gpio-realtek-otto.c -+++ b/drivers/gpio/gpio-realtek-otto.c -@@ -301,6 +301,7 @@ static int realtek_gpio_irq_set_affinity - static int realtek_gpio_irq_init(struct gpio_chip *gc) - { - struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc); -+ void __iomem *irq_cpu_mask; - unsigned int port; - int cpu; - -@@ -308,8 +309,16 @@ static int realtek_gpio_irq_init(struct - realtek_gpio_write_imr(ctrl, port, 0, 0); - realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0)); - -- for_each_cpu(cpu, &ctrl->cpu_irq_maskable) -- iowrite8(GENMASK(7, 0), realtek_gpio_irq_cpu_mask(ctrl, port, cpu)); -+ /* -+ * Uniprocessor builds assume a mask always contains one CPU, -+ * so only start the loop if we have at least one maskable CPU. -+ */ -+ if(!cpumask_empty(&ctrl->cpu_irq_maskable)) { -+ for_each_cpu(cpu, &ctrl->cpu_irq_maskable) { -+ irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu); -+ iowrite8(GENMASK(7, 0), irq_cpu_mask); -+ } -+ } - } - - return 0; diff --git a/target/linux/realtek/patches-5.15/317-gpio-realtek-otto-switch-to-32-bit-I-O.patch b/target/linux/realtek/patches-5.15/317-gpio-realtek-otto-switch-to-32-bit-I-O.patch deleted file mode 100644 index 9f2c3b50b6116a..00000000000000 --- a/target/linux/realtek/patches-5.15/317-gpio-realtek-otto-switch-to-32-bit-I-O.patch +++ /dev/null @@ -1,368 +0,0 @@ -From ee0175b3b44288c74d5292c2a9c2c154f6c0317e Mon Sep 17 00:00:00 2001 -From: Sander Vanheule -Date: Sun, 7 Aug 2022 21:21:15 +0200 -Subject: [PATCH] gpio: realtek-otto: switch to 32-bit I/O - -By using 16-bit I/O on the GPIO peripheral, which is apparently not safe -on MIPS, the IMR can end up containing garbage. This then results in -interrupt triggers for lines that don't have an interrupt handler -associated. The irq_desc lookup fails, and the ISR will not be cleared, -keeping the CPU busy until reboot, or until another IMR operation -restores the correct value. This situation appears to happen very -rarely, for < 0.5% of IMR writes. - -Instead of using 8-bit or 16-bit I/O operations on the 32-bit memory -mapped peripheral registers, switch to using 32-bit I/O only, operating -on the entire bank for all single bit line settings. For 2-bit line -settings, with 16-bit port values, stick to manual (un)packing. - -This issue has been seen on RTL8382M (HPE 1920-16G), RTL8391M (Netgear -GS728TP v2), and RTL8393M (D-Link DGS-1210-52 F3, Zyxel GS1900-48). - -Reported-by: Luiz Angelo Daros de Luca # DGS-1210-52 -Reported-by: Birger Koblitz # GS728TP -Reported-by: Jan Hoffmann # 1920-16G -Fixes: 0d82fb1127fb ("gpio: Add Realtek Otto GPIO support") -Signed-off-by: Sander Vanheule -Cc: Paul Cercueil -Reviewed-by: Linus Walleij -Signed-off-by: Bartosz Golaszewski - -Update patch for missing upstream changes: - - commit a01a40e33499 ("gpio: realtek-otto: Make the irqchip immutable") -Signed-off-by: Sander Vanheule - ---- - drivers/gpio/gpio-realtek-otto.c | 166 ++++++++++++++++--------------- - 1 file changed, 85 insertions(+), 81 deletions(-) - ---- a/drivers/gpio/gpio-realtek-otto.c -+++ b/drivers/gpio/gpio-realtek-otto.c -@@ -46,10 +46,20 @@ - * @lock: Lock for accessing the IRQ registers and values - * @intr_mask: Mask for interrupts lines - * @intr_type: Interrupt type selection -+ * @bank_read: Read a bank setting as a single 32-bit value -+ * @bank_write: Write a bank setting as a single 32-bit value -+ * @imr_line_pos: Bit shift of an IRQ line's IMR value. -+ * -+ * The DIR, DATA, and ISR registers consist of four 8-bit port values, packed -+ * into a single 32-bit register. Use @bank_read (@bank_write) to get (assign) -+ * a value from (to) these registers. The IMR register consists of four 16-bit -+ * port values, packed into two 32-bit registers. Use @imr_line_pos to get the -+ * bit shift of the 2-bit field for a line's IMR settings. Shifts larger than -+ * 32 overflow into the second register. - * - * Because the interrupt mask register (IMR) combines the function of IRQ type - * selection and masking, two extra values are stored. @intr_mask is used to -- * mask/unmask the interrupts for a GPIO port, and @intr_type is used to store -+ * mask/unmask the interrupts for a GPIO line, and @intr_type is used to store - * the selected interrupt types. The logical AND of these values is written to - * IMR on changes. - */ -@@ -59,10 +69,11 @@ struct realtek_gpio_ctrl { - void __iomem *cpumask_base; - struct cpumask cpu_irq_maskable; - raw_spinlock_t lock; -- u16 intr_mask[REALTEK_GPIO_PORTS_PER_BANK]; -- u16 intr_type[REALTEK_GPIO_PORTS_PER_BANK]; -- unsigned int (*port_offset_u8)(unsigned int port); -- unsigned int (*port_offset_u16)(unsigned int port); -+ u8 intr_mask[REALTEK_GPIO_MAX]; -+ u8 intr_type[REALTEK_GPIO_MAX]; -+ u32 (*bank_read)(void __iomem *reg); -+ void (*bank_write)(void __iomem *reg, u32 value); -+ unsigned int (*line_imr_pos)(unsigned int line); - }; - - /* Expand with more flags as devices with other quirks are added */ -@@ -101,14 +112,22 @@ static struct realtek_gpio_ctrl *irq_dat - * port. The two interrupt mask registers store two bits per GPIO, so use u16 - * values. - */ --static unsigned int realtek_gpio_port_offset_u8(unsigned int port) -+static u32 realtek_gpio_bank_read_swapped(void __iomem *reg) -+{ -+ return ioread32be(reg); -+} -+ -+static void realtek_gpio_bank_write_swapped(void __iomem *reg, u32 value) - { -- return port; -+ iowrite32be(value, reg); - } - --static unsigned int realtek_gpio_port_offset_u16(unsigned int port) -+static unsigned int realtek_gpio_line_imr_pos_swapped(unsigned int line) - { -- return 2 * port; -+ unsigned int port_pin = line % 8; -+ unsigned int port = line / 8; -+ -+ return 2 * (8 * (port ^ 1) + port_pin); - } - - /* -@@ -119,64 +138,65 @@ static unsigned int realtek_gpio_port_of - * per GPIO, so use u16 values. The first register contains ports 1 and 0, the - * second ports 3 and 2. - */ --static unsigned int realtek_gpio_port_offset_u8_rev(unsigned int port) -+static u32 realtek_gpio_bank_read(void __iomem *reg) - { -- return 3 - port; -+ return ioread32(reg); - } - --static unsigned int realtek_gpio_port_offset_u16_rev(unsigned int port) -+static void realtek_gpio_bank_write(void __iomem *reg, u32 value) - { -- return 2 * (port ^ 1); -+ iowrite32(value, reg); - } - --static void realtek_gpio_write_imr(struct realtek_gpio_ctrl *ctrl, -- unsigned int port, u16 irq_type, u16 irq_mask) -+static unsigned int realtek_gpio_line_imr_pos(unsigned int line) - { -- iowrite16(irq_type & irq_mask, -- ctrl->base + REALTEK_GPIO_REG_IMR + ctrl->port_offset_u16(port)); -+ return 2 * line; - } - --static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl, -- unsigned int port, u8 mask) -+static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl, u32 mask) - { -- iowrite8(mask, ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port)); -+ ctrl->bank_write(ctrl->base + REALTEK_GPIO_REG_ISR, mask); - } - --static u8 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl, unsigned int port) -+static u32 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl) - { -- return ioread8(ctrl->base + REALTEK_GPIO_REG_ISR + ctrl->port_offset_u8(port)); -+ return ctrl->bank_read(ctrl->base + REALTEK_GPIO_REG_ISR); - } - --/* Set the rising and falling edge mask bits for a GPIO port pin */ --static u16 realtek_gpio_imr_bits(unsigned int pin, u16 value) -+/* Set the rising and falling edge mask bits for a GPIO pin */ -+static void realtek_gpio_update_line_imr(struct realtek_gpio_ctrl *ctrl, unsigned int line) - { -- return (value & REALTEK_GPIO_IMR_LINE_MASK) << 2 * pin; -+ void __iomem *reg = ctrl->base + REALTEK_GPIO_REG_IMR; -+ unsigned int line_shift = ctrl->line_imr_pos(line); -+ unsigned int shift = line_shift % 32; -+ u32 irq_type = ctrl->intr_type[line]; -+ u32 irq_mask = ctrl->intr_mask[line]; -+ u32 reg_val; -+ -+ reg += 4 * (line_shift / 32); -+ reg_val = ioread32(reg); -+ reg_val &= ~(REALTEK_GPIO_IMR_LINE_MASK << shift); -+ reg_val |= (irq_type & irq_mask & REALTEK_GPIO_IMR_LINE_MASK) << shift; -+ iowrite32(reg_val, reg); - } - - static void realtek_gpio_irq_ack(struct irq_data *data) - { - struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); - irq_hw_number_t line = irqd_to_hwirq(data); -- unsigned int port = line / 8; -- unsigned int port_pin = line % 8; - -- realtek_gpio_clear_isr(ctrl, port, BIT(port_pin)); -+ realtek_gpio_clear_isr(ctrl, BIT(line)); - } - - static void realtek_gpio_irq_unmask(struct irq_data *data) - { - struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); - unsigned int line = irqd_to_hwirq(data); -- unsigned int port = line / 8; -- unsigned int port_pin = line % 8; - unsigned long flags; -- u16 m; - - raw_spin_lock_irqsave(&ctrl->lock, flags); -- m = ctrl->intr_mask[port]; -- m |= realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK); -- ctrl->intr_mask[port] = m; -- realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m); -+ ctrl->intr_mask[line] = REALTEK_GPIO_IMR_LINE_MASK; -+ realtek_gpio_update_line_imr(ctrl, line); - raw_spin_unlock_irqrestore(&ctrl->lock, flags); - } - -@@ -184,16 +204,11 @@ static void realtek_gpio_irq_mask(struct - { - struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); - unsigned int line = irqd_to_hwirq(data); -- unsigned int port = line / 8; -- unsigned int port_pin = line % 8; - unsigned long flags; -- u16 m; - - raw_spin_lock_irqsave(&ctrl->lock, flags); -- m = ctrl->intr_mask[port]; -- m &= ~realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK); -- ctrl->intr_mask[port] = m; -- realtek_gpio_write_imr(ctrl, port, ctrl->intr_type[port], m); -+ ctrl->intr_mask[line] = 0; -+ realtek_gpio_update_line_imr(ctrl, line); - raw_spin_unlock_irqrestore(&ctrl->lock, flags); - } - -@@ -201,10 +216,8 @@ static int realtek_gpio_irq_set_type(str - { - struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); - unsigned int line = irqd_to_hwirq(data); -- unsigned int port = line / 8; -- unsigned int port_pin = line % 8; - unsigned long flags; -- u16 type, t; -+ u8 type; - - switch (flow_type & IRQ_TYPE_SENSE_MASK) { - case IRQ_TYPE_EDGE_FALLING: -@@ -223,11 +236,8 @@ static int realtek_gpio_irq_set_type(str - irq_set_handler_locked(data, handle_edge_irq); - - raw_spin_lock_irqsave(&ctrl->lock, flags); -- t = ctrl->intr_type[port]; -- t &= ~realtek_gpio_imr_bits(port_pin, REALTEK_GPIO_IMR_LINE_MASK); -- t |= realtek_gpio_imr_bits(port_pin, type); -- ctrl->intr_type[port] = t; -- realtek_gpio_write_imr(ctrl, port, t, ctrl->intr_mask[port]); -+ ctrl->intr_type[line] = type; -+ realtek_gpio_update_line_imr(ctrl, line); - raw_spin_unlock_irqrestore(&ctrl->lock, flags); - - return 0; -@@ -238,28 +248,21 @@ static void realtek_gpio_irq_handler(str - struct gpio_chip *gc = irq_desc_get_handler_data(desc); - struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc); - struct irq_chip *irq_chip = irq_desc_get_chip(desc); -- unsigned int lines_done; -- unsigned int port_pin_count; - unsigned long status; - int offset; - - chained_irq_enter(irq_chip, desc); - -- for (lines_done = 0; lines_done < gc->ngpio; lines_done += 8) { -- status = realtek_gpio_read_isr(ctrl, lines_done / 8); -- port_pin_count = min(gc->ngpio - lines_done, 8U); -- for_each_set_bit(offset, &status, port_pin_count) -- generic_handle_domain_irq(gc->irq.domain, offset + lines_done); -- } -+ status = realtek_gpio_read_isr(ctrl); -+ for_each_set_bit(offset, &status, gc->ngpio) -+ generic_handle_domain_irq(gc->irq.domain, offset); - - chained_irq_exit(irq_chip, desc); - } - --static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl, -- unsigned int port, int cpu) -+static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl, int cpu) - { -- return ctrl->cpumask_base + ctrl->port_offset_u8(port) + -- REALTEK_GPIO_PORTS_PER_BANK * cpu; -+ return ctrl->cpumask_base + REALTEK_GPIO_PORTS_PER_BANK * cpu; - } - - static int realtek_gpio_irq_set_affinity(struct irq_data *data, -@@ -267,12 +270,10 @@ static int realtek_gpio_irq_set_affinity - { - struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data); - unsigned int line = irqd_to_hwirq(data); -- unsigned int port = line / 8; -- unsigned int port_pin = line % 8; - void __iomem *irq_cpu_mask; - unsigned long flags; - int cpu; -- u8 v; -+ u32 v; - - if (!ctrl->cpumask_base) - return -ENXIO; -@@ -280,15 +281,15 @@ static int realtek_gpio_irq_set_affinity - raw_spin_lock_irqsave(&ctrl->lock, flags); - - for_each_cpu(cpu, &ctrl->cpu_irq_maskable) { -- irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu); -- v = ioread8(irq_cpu_mask); -+ irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, cpu); -+ v = ctrl->bank_read(irq_cpu_mask); - - if (cpumask_test_cpu(cpu, dest)) -- v |= BIT(port_pin); -+ v |= BIT(line); - else -- v &= ~BIT(port_pin); -+ v &= ~BIT(line); - -- iowrite8(v, irq_cpu_mask); -+ ctrl->bank_write(irq_cpu_mask, v); - } - - raw_spin_unlock_irqrestore(&ctrl->lock, flags); -@@ -302,22 +303,23 @@ static int realtek_gpio_irq_init(struct - { - struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc); - void __iomem *irq_cpu_mask; -- unsigned int port; -+ u32 mask_all = GENMASK(gc->ngpio - 1, 0); -+ unsigned int line; - int cpu; - -- for (port = 0; (port * 8) < gc->ngpio; port++) { -- realtek_gpio_write_imr(ctrl, port, 0, 0); -- realtek_gpio_clear_isr(ctrl, port, GENMASK(7, 0)); -- -- /* -- * Uniprocessor builds assume a mask always contains one CPU, -- * so only start the loop if we have at least one maskable CPU. -- */ -- if(!cpumask_empty(&ctrl->cpu_irq_maskable)) { -- for_each_cpu(cpu, &ctrl->cpu_irq_maskable) { -- irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, port, cpu); -- iowrite8(GENMASK(7, 0), irq_cpu_mask); -- } -+ for (line = 0; line < gc->ngpio; line++) -+ realtek_gpio_update_line_imr(ctrl, line); -+ -+ realtek_gpio_clear_isr(ctrl, mask_all); -+ -+ /* -+ * Uniprocessor builds assume a mask always contains one CPU, -+ * so only start the loop if we have at least one maskable CPU. -+ */ -+ if(!cpumask_empty(&ctrl->cpu_irq_maskable)) { -+ for_each_cpu(cpu, &ctrl->cpu_irq_maskable) { -+ irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, cpu); -+ ctrl->bank_write(irq_cpu_mask, mask_all); - } - } - -@@ -390,12 +392,14 @@ static int realtek_gpio_probe(struct pla - - if (dev_flags & GPIO_PORTS_REVERSED) { - bgpio_flags = 0; -- ctrl->port_offset_u8 = realtek_gpio_port_offset_u8_rev; -- ctrl->port_offset_u16 = realtek_gpio_port_offset_u16_rev; -+ ctrl->bank_read = realtek_gpio_bank_read; -+ ctrl->bank_write = realtek_gpio_bank_write; -+ ctrl->line_imr_pos = realtek_gpio_line_imr_pos; - } else { - bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER; -- ctrl->port_offset_u8 = realtek_gpio_port_offset_u8; -- ctrl->port_offset_u16 = realtek_gpio_port_offset_u16; -+ ctrl->bank_read = realtek_gpio_bank_read_swapped; -+ ctrl->bank_write = realtek_gpio_bank_write_swapped; -+ ctrl->line_imr_pos = realtek_gpio_line_imr_pos_swapped; - } - - err = bgpio_init(&ctrl->gc, dev, 4, diff --git a/target/linux/realtek/patches-5.15/318-add-rtl83xx-clk-support.patch b/target/linux/realtek/patches-5.15/318-add-rtl83xx-clk-support.patch deleted file mode 100644 index 7d063d4faaa3df..00000000000000 --- a/target/linux/realtek/patches-5.15/318-add-rtl83xx-clk-support.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 800d5fb3c6a16661932c932bacd660e38d06b727 Mon Sep 17 00:00:00 2001 -From: Markus Stockhausen -Date: Thu, 25 Aug 2022 08:22:36 +0200 -Subject: [PATCH] realtek: add patch to enable new clock driver in kernel - -Allow building the clock driver with kernel config options. - -Submitted-by: Markus Stockhausen ---- - drivers/clk/Kconfig | 1 + - drivers/clk/Makefile | 1 + - 2 files changed, 2 insertions(+) - ---- a/drivers/clk/Kconfig -+++ b/drivers/clk/Kconfig -@@ -406,6 +406,7 @@ source "drivers/clk/mstar/Kconfig" - source "drivers/clk/mvebu/Kconfig" - source "drivers/clk/pistachio/Kconfig" - source "drivers/clk/qcom/Kconfig" -+source "drivers/clk/realtek/Kconfig" - source "drivers/clk/ralink/Kconfig" - source "drivers/clk/renesas/Kconfig" - source "drivers/clk/rockchip/Kconfig" ---- a/drivers/clk/Makefile -+++ b/drivers/clk/Makefile -@@ -101,6 +101,7 @@ obj-$(CONFIG_COMMON_CLK_PISTACHIO) += pi - obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ - obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ - obj-y += ralink/ -+obj-$(CONFIG_COMMON_CLK_REALTEK) += realtek/ - obj-y += renesas/ - obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ - obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ diff --git a/target/linux/realtek/patches-5.15/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch b/target/linux/realtek/patches-5.15/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch deleted file mode 100644 index 0c29b7739e188b..00000000000000 --- a/target/linux/realtek/patches-5.15/319-irqchip-irq-realtek-rtl-fix-VPE-affinity.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 2cd00b51470a30198b048a5fca48a04db77e29cc Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Fri, 21 May 2021 23:16:37 +0900 -Subject: [PATCH] realtek: backport irq-realtek-rtl driver from 5.12 to 5.10 - -This patch backports "irq-realtek-rtl" driver to Kernel 5.10 from 5.12. -"MACH_REALTEK_RTL" is used as a platform name in upstream, but "RTL838X" -is used in OpenWrt, so update the dependency by the additional patch. - -Submitted-by: INAGAKI Hiroshi ---- - drivers/irqchip/irq-realtek-rtl.c | 38 +++++++++++------ - 1 files changed, 58 insertions(+), 20 deletions(-) - ---- a/drivers/irqchip/irq-realtek-rtl.c -+++ b/drivers/irqchip/irq-realtek-rtl.c -@@ -28,6 +28,7 @@ static DEFINE_RAW_SPINLOCK(irq_lock); - - #define REG(offset, cpu) (realtek_ictl_base[cpu] + offset) - -+static u32 realtek_ictl_unmask[NR_CPUS]; - static void __iomem *realtek_ictl_base[NR_CPUS]; - static cpumask_t realtek_ictl_cpu_configurable; - -@@ -41,11 +42,29 @@ struct realtek_ictl_output { - }; - - /* -- * IRR0-IRR3 store 4 bits per interrupt, but Realtek uses inverted numbering, -- * placing IRQ 31 in the first four bits. A routing value of '0' means the -- * interrupt is left disconnected. Routing values {1..15} connect to output -- * lines {0..14}. -+ * Per CPU we have a set of 5 registers that determine interrupt handling for -+ * 32 external interrupts. GIMR (enable/disable interrupt) plus IRR0-IRR3 that -+ * contain "routing" or "priority" values. GIMR uses one bit for each interrupt -+ * and IRRx store 4 bits per interrupt. Realtek uses inverted numbering, -+ * placing IRQ 31 in the first four bits. The register combinations give the -+ * following results for a single interrupt in the wild: -+ * -+ * a) GIMR = 0 / IRRx > 0 -> no interrupts -+ * b) GIMR = 0 / IRRx = 0 -> no interrupts -+ * c) GIMR = 1 / IRRx > 0 -> interrupts -+ * d) GIMR = 1 / IRRx = 0 -> rare interrupts in SMP environment -+ * -+ * Combination d) seems to trigger interrupts only on a VPE if the other VPE -+ * has GIMR = 0 and IRRx > 0. E.g. busy without interrupts allowed. To provide -+ * IRQ balancing features in SMP this driver will handle the registers as -+ * follows: -+ * -+ * 1) set IRRx > 0 for VPE where the interrupt is desired -+ * 2) set IRRx = 0 for VPE where the interrupt is not desired -+ * 3) set both GIMR = 0 to mask (disabled) interrupt -+ * 4) set GIMR = 1 to unmask (enable) interrupt but only for VPE where IRRx > 0 - */ -+ - #define IRR_OFFSET(idx) (4 * (3 - (idx * 4) / 32)) - #define IRR_SHIFT(idx) ((idx * 4) % 32) - -@@ -65,19 +84,33 @@ static inline void write_irr(void __iome - writel(irr, irr0 + offset); - } - -+static inline void enable_gimr(int hwirq, int cpu) -+{ -+ u32 value; -+ -+ value = readl(REG(RTL_ICTL_GIMR, cpu)); -+ value |= (BIT(hwirq) & realtek_ictl_unmask[cpu]); -+ writel(value, REG(RTL_ICTL_GIMR, cpu)); -+} -+ -+static inline void disable_gimr(int hwirq, int cpu) -+{ -+ u32 value; -+ -+ value = readl(REG(RTL_ICTL_GIMR, cpu)); -+ value &= ~BIT(hwirq); -+ writel(value, REG(RTL_ICTL_GIMR, cpu)); -+} -+ - static void realtek_ictl_unmask_irq(struct irq_data *i) - { - unsigned long flags; -- u32 value; - int cpu; - - raw_spin_lock_irqsave(&irq_lock, flags); - -- for_each_cpu(cpu, &realtek_ictl_cpu_configurable) { -- value = readl(REG(RTL_ICTL_GIMR, cpu)); -- value |= BIT(i->hwirq); -- writel(value, REG(RTL_ICTL_GIMR, cpu)); -- } -+ for_each_cpu(cpu, &realtek_ictl_cpu_configurable) -+ enable_gimr(i->hwirq, cpu); - - raw_spin_unlock_irqrestore(&irq_lock, flags); - } -@@ -85,16 +118,12 @@ static void realtek_ictl_unmask_irq(stru - static void realtek_ictl_mask_irq(struct irq_data *i) - { - unsigned long flags; -- u32 value; - int cpu; - - raw_spin_lock_irqsave(&irq_lock, flags); - -- for_each_cpu(cpu, &realtek_ictl_cpu_configurable) { -- value = readl(REG(RTL_ICTL_GIMR, cpu)); -- value &= ~BIT(i->hwirq); -- writel(value, REG(RTL_ICTL_GIMR, cpu)); -- } -+ for_each_cpu(cpu, &realtek_ictl_cpu_configurable) -+ disable_gimr(i->hwirq, cpu); - - raw_spin_unlock_irqrestore(&irq_lock, flags); - } -@@ -116,11 +145,17 @@ static int __maybe_unused realtek_ictl_i - cpumask_and(&cpu_enable, &cpu_configure, dest); - cpumask_andnot(&cpu_disable, &cpu_configure, dest); - -- for_each_cpu(cpu, &cpu_disable) -+ for_each_cpu(cpu, &cpu_disable) { - write_irr(REG(RTL_ICTL_IRR0, cpu), i->hwirq, 0); -+ realtek_ictl_unmask[cpu] &= ~BIT(i->hwirq); -+ disable_gimr(i->hwirq, cpu); -+ } - -- for_each_cpu(cpu, &cpu_enable) -+ for_each_cpu(cpu, &cpu_enable) { - write_irr(REG(RTL_ICTL_IRR0, cpu), i->hwirq, output->output_index + 1); -+ realtek_ictl_unmask[cpu] |= BIT(i->hwirq); -+ enable_gimr(i->hwirq, cpu); -+ } - - irq_data_update_effective_affinity(i, &cpu_enable); - -@@ -149,6 +184,7 @@ static int intc_map(struct irq_domain *d - - output->child_mask |= BIT(hw); - write_irr(REG(RTL_ICTL_IRR0, 0), hw, output->output_index + 1); -+ realtek_ictl_unmask[0] |= BIT(hw); - - raw_spin_unlock_irqrestore(&irq_lock, flags); - -@@ -285,9 +321,11 @@ static int __init realtek_rtl_of_init(st - cpumask_set_cpu(cpu, &realtek_ictl_cpu_configurable); - - /* Disable all cascaded interrupts and clear routing */ -- writel(0, REG(RTL_ICTL_GIMR, cpu)); -- for (soc_irq = 0; soc_irq < RTL_ICTL_NUM_INPUTS; soc_irq++) -+ for (soc_irq = 0; soc_irq < RTL_ICTL_NUM_INPUTS; soc_irq++) { - write_irr(REG(RTL_ICTL_IRR0, cpu), soc_irq, 0); -+ realtek_ictl_unmask[cpu] &= ~BIT(soc_irq); -+ disable_gimr(soc_irq, cpu); -+ } - } - } - diff --git a/target/linux/realtek/patches-5.15/700-net-dsa-add-support-for-rtl838x-switch.patch b/target/linux/realtek/patches-5.15/700-net-dsa-add-support-for-rtl838x-switch.patch deleted file mode 100644 index 8c6a4c36393f5f..00000000000000 --- a/target/linux/realtek/patches-5.15/700-net-dsa-add-support-for-rtl838x-switch.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 26 Nov 2020 12:02:21 +0100 -Subject: net: dsa: Add support for rtl838x switch - -* rename the target to realtek -* add refactored DSA driver -* add latest gpio driver -* lots of arch cleanups -* new irq driver -* additional boards - -Submitted-by: Bert Vermeulen -Submitted-by: Birger Koblitz -Submitted-by: Sander Vanheule -Submitted-by: Bjørn Mork -Submitted-by: John Crispin ---- - drivers/net/dsa/rtl83xx/Kconfig | 2 ++ - drivers/net/dsa/rtl83xx/Makefile | 1 + - 2 files changed, 3 insertions(+) - ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -85,6 +85,8 @@ source "drivers/net/dsa/sja1105/Kconfig" - - source "drivers/net/dsa/xrs700x/Kconfig" - -+source "drivers/net/dsa/rtl83xx/Kconfig" -+ - config NET_DSA_REALTEK_SMI - tristate "Realtek SMI Ethernet switch family support" - select NET_DSA_TAG_RTL4_A ---- a/drivers/net/dsa/Makefile -+++ b/drivers/net/dsa/Makefile -@@ -24,5 +24,6 @@ obj-y += microchip/ - obj-y += mv88e6xxx/ - obj-y += ocelot/ - obj-y += qca/ -+obj-y += rtl83xx/ - obj-y += sja1105/ - obj-y += xrs700x/ diff --git a/target/linux/realtek/patches-5.15/701-net-dsa-add-rtl838x-support-for-tag-trailer.patch b/target/linux/realtek/patches-5.15/701-net-dsa-add-rtl838x-support-for-tag-trailer.patch deleted file mode 100644 index 0cb784fcbfa43d..00000000000000 --- a/target/linux/realtek/patches-5.15/701-net-dsa-add-rtl838x-support-for-tag-trailer.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 26 Nov 2020 12:02:21 +0100 -Subject: net: dsa: Add rtl838x support for tag trailer - -* rename the target to realtek -* add refactored DSA driver -* add latest gpio driver -* lots of arch cleanups -* new irq driver -* additional boards - -Submitted-by: Bert Vermeulen -Submitted-by: Birger Koblitz -Submitted-by: Sander Vanheule -Submitted-by: Bjørn Mork -Submitted-by: John Crispin ---- - net/dsa/tag_trailer.c | 16 +++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - ---- a/net/dsa/tag_trailer.c -+++ b/net/dsa/tag_trailer.c -@@ -17,7 +17,12 @@ static struct sk_buff *trailer_xmit(stru - - trailer = skb_put(skb, 4); - trailer[0] = 0x80; -+ -+#ifdef CONFIG_NET_DSA_RTL83XX -+ trailer[1] = dp->index; -+#else - trailer[1] = 1 << dp->index; -+#endif /* CONFIG_NET_DSA_RTL838X */ - trailer[2] = 0x10; - trailer[3] = 0x00; - -@@ -33,12 +38,23 @@ static struct sk_buff *trailer_rcv(struc - return NULL; - - trailer = skb_tail_pointer(skb) - 4; -+ -+#ifdef CONFIG_NET_DSA_RTL83XX -+ if (trailer[0] != 0x80 || (trailer[1] & 0x80) != 0x00 || -+ (trailer[2] & 0xef) != 0x00 || trailer[3] != 0x00) -+ return NULL; -+ -+ if (trailer[1] & 0x40) -+ skb->offload_fwd_mark = 1; -+ -+ source_port = trailer[1] & 0x3f; -+#else - if (trailer[0] != 0x80 || (trailer[1] & 0xf8) != 0x00 || - (trailer[2] & 0xef) != 0x00 || trailer[3] != 0x00) - return NULL; - - source_port = trailer[1] & 7; -- -+#endif - skb->dev = dsa_master_find_slave(dev, 0, source_port); - if (!skb->dev) - return NULL; diff --git a/target/linux/realtek/patches-5.15/702-net-dsa-increase-dsa-max-ports-for-rtl838x.patch b/target/linux/realtek/patches-5.15/702-net-dsa-increase-dsa-max-ports-for-rtl838x.patch deleted file mode 100644 index 63991d373cd3d5..00000000000000 --- a/target/linux/realtek/patches-5.15/702-net-dsa-increase-dsa-max-ports-for-rtl838x.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 26 Nov 2020 12:02:21 +0100 -Subject: net: dsa: Increase max ports for rtl838x - -* rename the target to realtek -* add refactored DSA driver -* add latest gpio driver -* lots of arch cleanups -* new irq driver -* additional boards - -Submitted-by: Bert Vermeulen -Submitted-by: Birger Koblitz -Submitted-by: Sander Vanheule -Submitted-by: Bjørn Mork -Submitted-by: John Crispin ---- - include/linux/platform_data/dsa.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/include/linux/platform_data/dsa.h -+++ b/include/linux/platform_data/dsa.h -@@ -6,7 +6,7 @@ struct device; - struct net_device; - - #define DSA_MAX_SWITCHES 4 --#define DSA_MAX_PORTS 12 -+#define DSA_MAX_PORTS 54 - #define DSA_RTABLE_NONE -1 - - struct dsa_chip_data { diff --git a/target/linux/realtek/patches-5.15/702-net-ethernet-add-support-for-rtl838x-ethernet.patch b/target/linux/realtek/patches-5.15/702-net-ethernet-add-support-for-rtl838x-ethernet.patch deleted file mode 100644 index 1c25c42b911099..00000000000000 --- a/target/linux/realtek/patches-5.15/702-net-ethernet-add-support-for-rtl838x-ethernet.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 26 Nov 2020 12:02:21 +0100 -Subject: net: ethernet: Add support for RTL838x ethernet - -* rename the target to realtek -* add refactored DSA driver -* add latest gpio driver -* lots of arch cleanups -* new irq driver -* additional boards - -Submitted-by: Bert Vermeulen -Submitted-by: Birger Koblitz -Submitted-by: Sander Vanheule -Submitted-by: Bjørn Mork -Submitted-by: John Crispin ---- - drivers/net/ethernet/Kconfig | 7 +- - drivers/net/ethernet/Makefile | 1 + - 2 files changed, 8 insertions(+) - ---- a/drivers/net/ethernet/Kconfig -+++ b/drivers/net/ethernet/Kconfig -@@ -166,6 +166,13 @@ source "drivers/net/ethernet/rdc/Kconfig - source "drivers/net/ethernet/realtek/Kconfig" - source "drivers/net/ethernet/renesas/Kconfig" - source "drivers/net/ethernet/rocker/Kconfig" -+ -+config NET_RTL838X -+ tristate "Realtek rtl838x Ethernet MAC support" -+ depends on RTL83XX -+ help -+ Say Y here if you want to use the Realtek rtl838x Gbps Ethernet MAC. -+ - source "drivers/net/ethernet/samsung/Kconfig" - source "drivers/net/ethernet/seeq/Kconfig" - source "drivers/net/ethernet/sgi/Kconfig" ---- a/drivers/net/ethernet/Makefile -+++ b/drivers/net/ethernet/Makefile -@@ -77,6 +77,7 @@ obj-$(CONFIG_NET_VENDOR_REALTEK) += real - obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/ - obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ - obj-$(CONFIG_NET_VENDOR_ROCKER) += rocker/ -+obj-$(CONFIG_NET_RTL838X) += rtl838x_eth.o - obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/ - obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/ - obj-$(CONFIG_NET_VENDOR_SILAN) += silan/ diff --git a/target/linux/realtek/patches-5.15/703-include-linux-add-phy-ops-for-rtl838x.patch b/target/linux/realtek/patches-5.15/703-include-linux-add-phy-ops-for-rtl838x.patch deleted file mode 100644 index bf4d35764e221a..00000000000000 --- a/target/linux/realtek/patches-5.15/703-include-linux-add-phy-ops-for-rtl838x.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 26 Nov 2020 12:02:21 +0100 -Subject: phy: Add PHY ops for rtl838x EEE - -* rename the target to realtek -* add refactored DSA driver -* add latest gpio driver -* lots of arch cleanups -* new irq driver -* additional boards - -Submitted-by: Bert Vermeulen -Submitted-by: Birger Koblitz -Submitted-by: Sander Vanheule -Submitted-by: Bjørn Mork -Submitted-by: John Crispin ---- - include/linux/phy.h | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -1009,6 +1009,10 @@ struct phy_driver { - int (*led_blink_set)(struct phy_device *dev, u8 index, - unsigned long *delay_on, - unsigned long *delay_off); -+ int (*get_port)(struct phy_device *dev); -+ int (*set_port)(struct phy_device *dev, int port); -+ int (*get_eee)(struct phy_device *dev, struct ethtool_eee *e); -+ int (*set_eee)(struct phy_device *dev, struct ethtool_eee *e); - }; - #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ - struct phy_driver, mdiodrv) diff --git a/target/linux/realtek/patches-5.15/704-drivers-net-phy-eee-support-for-rtl838x.patch b/target/linux/realtek/patches-5.15/704-drivers-net-phy-eee-support-for-rtl838x.patch deleted file mode 100644 index bf6e517cfb9282..00000000000000 --- a/target/linux/realtek/patches-5.15/704-drivers-net-phy-eee-support-for-rtl838x.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 26 Nov 2020 12:02:21 +0100 -Subject: net: phy: EEE support for rtl838x - -* rename the target to realtek -* add refactored DSA driver -* add latest gpio driver -* lots of arch cleanups -* new irq driver -* additional boards - -Submitted-by: Bert Vermeulen -Submitted-by: Birger Koblitz -Submitted-by: Sander Vanheule -Submitted-by: Bjørn Mork -Submitted-by: John Crispin ---- - drivers/net/phy/phylink. | 14 +++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1994,6 +1994,11 @@ int phylink_ethtool_ksettings_set(struct - * the presence of a PHY, this should not be changed as that - * should be determined from the media side advertisement. - */ -+ if (pl->phydev->drv->get_port && pl->phydev->drv->set_port) { -+ if(pl->phydev->drv->get_port(pl->phydev) != kset->base.port) { -+ pl->phydev->drv->set_port(pl->phydev, kset->base.port); -+ } -+ } - return phy_ethtool_ksettings_set(pl->phydev, kset); - } - -@@ -2297,8 +2302,11 @@ int phylink_ethtool_get_eee(struct phyli - - ASSERT_RTNL(); - -- if (pl->phydev) -+ if (pl->phydev) { -+ if (pl->phydev->drv->get_eee) -+ return pl->phydev->drv->get_eee(pl->phydev, eee); - ret = phy_ethtool_get_eee(pl->phydev, eee); -+ } - - return ret; - } -@@ -2315,8 +2323,11 @@ int phylink_ethtool_set_eee(struct phyli - - ASSERT_RTNL(); - -- if (pl->phydev) -+ if (pl->phydev) { -+ if (pl->phydev->drv->set_eee) -+ return pl->phydev->drv->set_eee(pl->phydev, eee); - ret = phy_ethtool_set_eee(pl->phydev, eee); -+ } - - return ret; - } diff --git a/target/linux/realtek/patches-5.15/704-include-linux-add-phy-hsgmii-mode.patch b/target/linux/realtek/patches-5.15/704-include-linux-add-phy-hsgmii-mode.patch deleted file mode 100644 index 700ec97be86e17..00000000000000 --- a/target/linux/realtek/patches-5.15/704-include-linux-add-phy-hsgmii-mode.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 9d9bf16aa8d966834ac1280f96c37d22552c33d1 Mon Sep 17 00:00:00 2001 -From: Birger Koblitz -Date: Wed, 8 Sep 2021 16:13:18 +0200 -Subject: phy: Add PHY hsgmii mode - -This adds RTL93xx-specific MAC configuration routines that allow also configuration -of 10GBit links for phylink. There is support for the Realtek-specific HISGMI -protocol. - -Submitted-by: Birger Koblitz ---- - drivers/net/phy/phylink.c | 2 ++ - include/linux/phy.h | 3 +++ - 2 file changed, 5 insertions(+) - ---- a/drivers/net/phy/phy-core.c -+++ b/drivers/net/phy/phy-core.c -@@ -124,6 +124,7 @@ int phy_interface_num_ports(phy_interfac - case PHY_INTERFACE_MODE_MOCA: - case PHY_INTERFACE_MODE_TRGMII: - case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_HSGMII: - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_SMII: - case PHY_INTERFACE_MODE_1000BASEX: ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -410,6 +410,7 @@ void phylink_get_linkmodes(unsigned long - - case PHY_INTERFACE_MODE_XGMII: - case PHY_INTERFACE_MODE_RXAUI: -+ case PHY_INTERFACE_MODE_HSGMII: - case PHY_INTERFACE_MODE_XAUI: - case PHY_INTERFACE_MODE_10GBASER: - case PHY_INTERFACE_MODE_10GKR: -@@ -665,6 +666,7 @@ static int phylink_parse_mode(struct phy - fallthrough; - case PHY_INTERFACE_MODE_USXGMII: - case PHY_INTERFACE_MODE_10GKR: -+ case PHY_INTERFACE_MODE_HSGMII: - case PHY_INTERFACE_MODE_10GBASER: - phylink_set(pl->supported, 10baseT_Half); - phylink_set(pl->supported, 10baseT_Full); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -141,6 +141,7 @@ typedef enum { - PHY_INTERFACE_MODE_XGMII, - PHY_INTERFACE_MODE_XLGMII, - PHY_INTERFACE_MODE_MOCA, -+ PHY_INTERFACE_MODE_HSGMII, - PHY_INTERFACE_MODE_QSGMII, - PHY_INTERFACE_MODE_TRGMII, - PHY_INTERFACE_MODE_100BASEX, -@@ -248,6 +249,8 @@ static inline const char *phy_modes(phy_ - return "xlgmii"; - case PHY_INTERFACE_MODE_MOCA: - return "moca"; -+ case PHY_INTERFACE_MODE_HSGMII: -+ return "hsgmii"; - case PHY_INTERFACE_MODE_QSGMII: - return "qsgmii"; - case PHY_INTERFACE_MODE_TRGMII: diff --git a/target/linux/realtek/patches-5.15/705-add-rtl-phy.patch b/target/linux/realtek/patches-5.15/705-add-rtl-phy.patch deleted file mode 100644 index c6f8e6508b4481..00000000000000 --- a/target/linux/realtek/patches-5.15/705-add-rtl-phy.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 89f71ebb355c624320c2b0ace8ae9488ff53cbeb Mon Sep 17 00:00:00 2001 -From: Birger Koblitz -Date: Tue, 5 Jan 2021 20:40:52 +0100 -Subject: PHY: Add realtek PHY - -This fixes the build problems for the REALTEK target by adding a proper -configuration option for the phy module. - -Submitted-by: Birger Koblitz ---- - drivers/net/phy/Kconfig | 6 ++++++ - drivers/net/phy/Makefile | 1 + - 2 files changed, 7 insertions(+) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -354,6 +354,12 @@ config REALTEK_PHY - help - Supports the Realtek 821x PHY. - -+config REALTEK_SOC_PHY -+ tristate "Realtek SoC PHYs" -+ depends on RTL83XX -+ help -+ Supports the PHYs found in combination with Realtek Switch SoCs -+ - config RENESAS_PHY - tristate "Renesas PHYs" - help ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -89,6 +89,7 @@ obj-$(CONFIG_NXP_C45_TJA11XX_PHY) += nxp - obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o - obj-$(CONFIG_QSEMI_PHY) += qsemi.o - obj-$(CONFIG_REALTEK_PHY) += realtek.o -+obj-$(CONFIG_REALTEK_SOC_PHY) += rtl83xx-phy.o - obj-$(CONFIG_RENESAS_PHY) += uPD60620.o - obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o - obj-$(CONFIG_SMSC_PHY) += smsc.o diff --git a/target/linux/realtek/patches-5.15/705-include-linux-phy-increase-phy-address-number-for-rtl839x.patch b/target/linux/realtek/patches-5.15/705-include-linux-phy-increase-phy-address-number-for-rtl839x.patch deleted file mode 100644 index 9a6b00d7c0e185..00000000000000 --- a/target/linux/realtek/patches-5.15/705-include-linux-phy-increase-phy-address-number-for-rtl839x.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 2b88563ee5aafd9571d965b7f2093a0f58d98a31 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Thu, 26 Nov 2020 12:02:21 +0100 -Subject: PHY: Increase max PHY adddress number - -* rename the target to realtek -* add refactored DSA driver -* add latest gpio driver -* lots of arch cleanups -* new irq driver -* additional boards - -Submitted-by: Bert Vermeulen -Submitted-by: Birger Koblitz -Submitted-by: Sander Vanheule -Submitted-by: Bjørn Mork -Submitted-by: John Crispin ---- - include/linux/phy.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -287,7 +287,7 @@ static inline const char *phy_modes(phy_ - #define PHY_INIT_TIMEOUT 100000 - #define PHY_FORCE_TIMEOUT 10 - --#define PHY_MAX_ADDR 32 -+#define PHY_MAX_ADDR 64 - - /* Used when trying to connect to a specific phy (mii bus id:phy device id) */ - #define PHY_ID_FMT "%s:%02x" diff --git a/target/linux/realtek/patches-5.15/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch b/target/linux/realtek/patches-5.15/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch deleted file mode 100644 index 378563a9e33bdd..00000000000000 --- a/target/linux/realtek/patches-5.15/710-net-phy-sfp-re-probe-modules-on-DEV_UP-event.patch +++ /dev/null @@ -1,26 +0,0 @@ -From a381ac0aa281fdb0b41a39d8a2bc08fd88f6db92 Mon Sep 17 00:00:00 2001 -From: Antoine Tenart -Date: Tue, 25 Feb 2020 16:32:37 +0100 -Subject: [PATCH 1/3] net: phy: sfp: re-probe modules on DEV_UP event - -Signed-off-by: Antoine Tenart ---- - drivers/net/phy/sfp.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -2160,6 +2160,13 @@ static void sfp_sm_module(struct sfp *sf - return; - } - -+ /* Re-probe the SFP modules when an interface is brought up, as the MAC -+ * do not report its link status (This means Phylink wouldn't be -+ * triggered if the PHY had a link before a MAC is brought up). -+ */ -+ if (event == SFP_E_DEV_UP && sfp->sm_mod_state == SFP_MOD_PRESENT) -+ sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL); -+ - switch (sfp->sm_mod_state) { - default: - if (event == SFP_E_INSERT) { diff --git a/target/linux/realtek/patches-5.15/711-net-phy-add-an-MDIO-SMBus-library.patch b/target/linux/realtek/patches-5.15/711-net-phy-add-an-MDIO-SMBus-library.patch deleted file mode 100644 index 767a5d8ec56b02..00000000000000 --- a/target/linux/realtek/patches-5.15/711-net-phy-add-an-MDIO-SMBus-library.patch +++ /dev/null @@ -1,148 +0,0 @@ -From d585c55b9f70cf9e8c66820d7efe7130c683f19e Mon Sep 17 00:00:00 2001 -From: Antoine Tenart -Date: Fri, 21 Feb 2020 11:51:27 +0100 -Subject: [PATCH 2/3] net: phy: add an MDIO SMBus library - -Signed-off-by: Antoine Tenart ---- - drivers/net/mdio/Kconfig | 11 +++++++ - drivers/net/mdio/Makefile | 1 + - drivers/net/mdio/mdio-smbus.c | 62 +++++++++++++++++++++++++++++++++++ - drivers/net/phy/Kconfig | 1 + - include/linux/mdio/mdio-i2c.h | 16 +++++++++ - 5 files changed, 91 insertions(+) - create mode 100644 drivers/net/mdio/mdio-smbus.c - ---- a/drivers/net/mdio/Kconfig -+++ b/drivers/net/mdio/Kconfig -@@ -54,6 +54,17 @@ config MDIO_SUN4I - interface units of the Allwinner SoC that have an EMAC (A10, - A12, A10s, etc.) - -+config MDIO_SMBUS -+ tristate -+ depends on I2C_SMBUS -+ help -+ Support SMBus based PHYs. This provides a MDIO bus bridged -+ to SMBus to allow PHYs connected in SMBus mode to be accessed -+ using the existing infrastructure. -+ -+ This is library mode. -+ -+ - config MDIO_XGENE - tristate "APM X-Gene SoC MDIO bus controller" - depends on ARCH_XGENE || COMPILE_TEST ---- a/drivers/net/mdio/Makefile -+++ b/drivers/net/mdio/Makefile -@@ -19,6 +19,7 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxar - obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o - obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o - obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o -+obj-$(CONFIG_MDIO_SMBUS) += mdio-smbus.o - obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o - obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o - obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o ---- /dev/null -+++ b/drivers/net/mdio/mdio-smbus.c -@@ -0,0 +1,62 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * MDIO SMBus bridge -+ * -+ * Copyright (C) 2020 Antoine Tenart -+ * -+ * Network PHYs can appear on SMBus when they are part of SFP modules. -+ */ -+#include -+#include -+#include -+ -+static int smbus_mii_read(struct mii_bus *mii, int phy_id, int reg) -+{ -+ struct i2c_adapter *i2c = mii->priv; -+ union i2c_smbus_data data; -+ int ret; -+ -+ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_READ, -+ reg, I2C_SMBUS_BYTE_DATA, &data); -+ if (ret < 0) -+ return 0xff; -+ -+ return data.byte; -+} -+ -+static int smbus_mii_write(struct mii_bus *mii, int phy_id, int reg, u16 val) -+{ -+ struct i2c_adapter *i2c = mii->priv; -+ union i2c_smbus_data data; -+ int ret; -+ -+ data.byte = val; -+ -+ ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_WRITE, -+ reg, I2C_SMBUS_BYTE_DATA, &data); -+ return ret < 0 ? ret : 0; -+} -+ -+struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c) -+{ -+ struct mii_bus *mii; -+ -+ if (!i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) -+ return ERR_PTR(-EINVAL); -+ -+ mii = mdiobus_alloc(); -+ if (!mii) -+ return ERR_PTR(-ENOMEM); -+ -+ snprintf(mii->id, MII_BUS_ID_SIZE, "smbus:%s", dev_name(parent)); -+ mii->parent = parent; -+ mii->read = smbus_mii_read; -+ mii->write = smbus_mii_write; -+ mii->priv = i2c; -+ -+ return mii; -+} -+ -+MODULE_AUTHOR("Antoine Tenart"); -+MODULE_DESCRIPTION("MDIO SMBus bridge library"); -+MODULE_LICENSE("GPL"); ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -61,6 +61,7 @@ config SFP - depends on I2C && PHYLINK - depends on HWMON || HWMON=n - select MDIO_I2C -+ select MDIO_SMBUS - - comment "Switch configuration API + drivers" - ---- a/include/linux/mdio/mdio-i2c.h -+++ b/include/linux/mdio/mdio-i2c.h -@@ -12,5 +12,8 @@ struct i2c_adapter; - struct mii_bus; - - struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c); -+struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c); -+bool i2c_mii_valid_phy_id(int phy_id); -+unsigned int i2c_mii_phy_addr(int phy_id); - - #endif ---- a/drivers/net/mdio/mdio-i2c.c -+++ b/drivers/net/mdio/mdio-i2c.c -@@ -18,12 +18,12 @@ - * specified to be present in SFP modules. These correspond with PHY - * addresses 16 and 17. Disallow access to these "phy" addresses. - */ --static bool i2c_mii_valid_phy_id(int phy_id) -+bool i2c_mii_valid_phy_id(int phy_id) - { - return phy_id != 0x10 && phy_id != 0x11; - } - --static unsigned int i2c_mii_phy_addr(int phy_id) -+unsigned int i2c_mii_phy_addr(int phy_id) - { - return phy_id + 0x40; - } diff --git a/target/linux/realtek/patches-5.15/712-net-phy-sfp-add-support-for-SMBus.patch b/target/linux/realtek/patches-5.15/712-net-phy-sfp-add-support-for-SMBus.patch deleted file mode 100644 index 53ec0fa1da5208..00000000000000 --- a/target/linux/realtek/patches-5.15/712-net-phy-sfp-add-support-for-SMBus.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 3cb0bde365d913c484d20224367a54a0eac780a7 Mon Sep 17 00:00:00 2001 -From: Antoine Tenart -Date: Fri, 21 Feb 2020 11:55:29 +0100 -Subject: [PATCH 3/3] net: phy: sfp: add support for SMBus - -Signed-off-by: Antoine Tenart ---- - drivers/net/phy/sfp.c | 68 ++++++++++++++++++++++++++++++++++--------- - 1 file changed, 54 insertions(+), 14 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -556,32 +556,72 @@ static int sfp_i2c_write(struct sfp *sfp - return ret == ARRAY_SIZE(msgs) ? len : 0; - } - -+static int sfp_smbus_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf, -+ size_t len) -+{ -+ u8 bus_addr = a2 ? 0x51 : 0x50, *val = buf; -+ -+ bus_addr -= 0x40; -+ -+ while (len > 0) { -+ *val = sfp->i2c_mii->read(sfp->i2c_mii, bus_addr, dev_addr); -+ -+ val++; -+ dev_addr++; -+ len--; -+ } -+ -+ return val - (u8 *)buf; -+} -+ -+static int sfp_smbus_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf, -+ size_t len) -+{ -+ u8 bus_addr = a2 ? 0x51 : 0x50; -+ u16 val; -+ -+ memcpy(&val, buf, len); -+ -+ return sfp->i2c_mii->write(sfp->i2c_mii, bus_addr, dev_addr, val); -+} -+ - static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) - { -- struct mii_bus *i2c_mii; -+ struct mii_bus *mii; - int ret; - -- if (!i2c_check_functionality(i2c, I2C_FUNC_I2C)) -- return -EINVAL; -- - sfp->i2c = i2c; -- sfp->read = sfp_i2c_read; -- sfp->write = sfp_i2c_write; - -- i2c_mii = mdio_i2c_alloc(sfp->dev, i2c); -- if (IS_ERR(i2c_mii)) -- return PTR_ERR(i2c_mii); -+ if (i2c_check_functionality(i2c, I2C_FUNC_I2C)) { -+ sfp->read = sfp_i2c_read; -+ sfp->write = sfp_i2c_write; -+ -+ mii = mdio_i2c_alloc(sfp->dev, i2c); -+ if (IS_ERR(mii)) -+ return PTR_ERR(mii); -+ -+ mii->name = "SFP I2C Bus"; -+ } else if (i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA)) { -+ sfp->read = sfp_smbus_read; -+ sfp->write = sfp_smbus_write; -+ -+ mii = mdio_smbus_alloc(sfp->dev, i2c); -+ if (IS_ERR(mii)) -+ return PTR_ERR(mii); - -- i2c_mii->name = "SFP I2C Bus"; -- i2c_mii->phy_mask = ~0; -+ mii->name = "SFP SMBus"; -+ } else { -+ return -EINVAL; -+ } - -- ret = mdiobus_register(i2c_mii); -+ mii->phy_mask = ~0; -+ ret = mdiobus_register(mii); - if (ret < 0) { -- mdiobus_free(i2c_mii); -+ mdiobus_free(mii); - return ret; - } - -- sfp->i2c_mii = i2c_mii; -+ sfp->i2c_mii = mii; - - return 0; - } diff --git a/target/linux/realtek/rtl838x/config-5.15 b/target/linux/realtek/rtl838x/config-5.15 deleted file mode 100644 index ad2c1b43cce8d7..00000000000000 --- a/target/linux/realtek/rtl838x/config-5.15 +++ /dev/null @@ -1,224 +0,0 @@ -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MMAP_RND_BITS_MAX=15 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BMIPS_CPUFREQ is not set -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_REALTEK=y -CONFIG_COMMON_CLK_RTL83XX=y -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_BIG_ENDIAN=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_GENERIC_DUMP_TLB=y -CONFIG_CPU_HAS_DIEI=y -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_CPU_HAS_RIXI=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_CPU_MIPS32=y -# CONFIG_CPU_MIPS32_R1 is not set -CONFIG_CPU_MIPS32_R2=y -CONFIG_CPU_MIPSR2=y -CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y -CONFIG_CPU_R4K_CACHE_TLB=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_CPUFREQ=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_CPU_SUPPORTS_MSA=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 -CONFIG_CRYPTO_RNG2=y -CONFIG_DEBUG_SECTION_MISMATCH=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DTC=y -CONFIG_EARLY_PRINTK=y -CONFIG_EARLY_PRINTK_8250=y -CONFIG_EXTRA_FIRMWARE="rtl838x_phy/rtl838x_8214fc.fw rtl838x_phy/rtl838x_8218b.fw rtl838x_phy/rtl838x_8380.fw" -CONFIG_EXTRA_FIRMWARE_DIR="firmware" -CONFIG_FIXED_PHY=y -CONFIG_FORCE_MAX_ZONEORDER=13 -CONFIG_FWNODE_MDIO=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ATOMIC64=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IOMAP=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_LIB_ASHLDI3=y -CONFIG_GENERIC_LIB_ASHRDI3=y -CONFIG_GENERIC_LIB_CMPDI2=y -CONFIG_GENERIC_LIB_LSHRDI3=y -CONFIG_GENERIC_LIB_UCMPDI2=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_PCA953X=y -CONFIG_GPIO_PCA953X_IRQ=y -CONFIG_GPIO_REALTEK_OTTO=y -CONFIG_GPIO_RTL8231=y -CONFIG_GPIO_WATCHDOG=y -# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set -CONFIG_GRO_CELLS=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDWARE_WATCHPOINTS=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HWMON=y -CONFIG_HZ_PERIODIC=y -CONFIG_I2C=y -CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_I2C_MUX=y -# CONFIG_I2C_MUX_RTL9300 is not set -# CONFIG_I2C_RTL9300 is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_MIPS_CPU=y -CONFIG_IRQ_WORK=y -CONFIG_JFFS2_ZLIB=y -CONFIG_LEDS_GPIO=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_MARVELL_PHY=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MDIO_I2C=y -CONFIG_MDIO_SMBUS=y -CONFIG_MEMFD_CREATE=y -CONFIG_MFD_SYSCON=y -CONFIG_MIGRATION=y -CONFIG_MIPS=y -CONFIG_MIPS_ASID_BITS=8 -CONFIG_MIPS_ASID_SHIFT=0 -# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set -CONFIG_MIPS_CMDLINE_FROM_DTB=y -CONFIG_MIPS_EBPF_JIT=y -CONFIG_MIPS_EXTERNAL_TIMER=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 -CONFIG_MIPS_LD_CAN_LINK_VDSO=y -# CONFIG_MIPS_NO_APPENDED_DTB is not set -CONFIG_MIPS_RAW_APPENDED_DTB=y -CONFIG_MIPS_SPRAM=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPLIT_BRNIMAGE_FW=y -CONFIG_MTD_SPLIT_EVA_FW=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_H3C_VFS=y -CONFIG_MTD_SPLIT_TPLINK_FW=y -CONFIG_MTD_SPLIT_UIMAGE_FW=y -CONFIG_MTD_VIRT_CONCAT=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_PER_CPU_KM=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_RTL83XX=y -CONFIG_NET_DSA_TAG_TRAILER=y -CONFIG_NET_RTL838X=y -CONFIG_NET_SELFTESTS=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NO_EXCEPT_FILL=y -CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y -CONFIG_NVMEM=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_PCI_DRIVERS_LEGACY=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLINK=y -CONFIG_PINCTRL=y -CONFIG_PM_OPP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_GPIO_RESTART=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_RATIONAL=y -CONFIG_REALTEK_OTTO_TIMER=y -CONFIG_REALTEK_OTTO_WDT=y -CONFIG_REALTEK_PHY=y -CONFIG_REALTEK_SOC_PHY=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RTL838X=y -# CONFIG_RTL839X is not set -CONFIG_RTL83XX=y -# CONFIG_RTL930X is not set -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SFP=y -CONFIG_SPI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SRAM=y -CONFIG_SRCU=y -CONFIG_SWPHY=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_SYS_HAS_CPU_MIPS32_R1=y -CONFIG_SYS_HAS_CPU_MIPS32_R2=y -CONFIG_SYS_HAS_EARLY_PRINTK=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_SYS_SUPPORTS_HIGHMEM=y -CONFIG_SYS_SUPPORTS_MIPS16=y -CONFIG_TARGET_ISA_REV=2 -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TINY_SRCU=y -CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y -CONFIG_USE_OF=y -CONFIG_WATCHDOG_CORE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y diff --git a/target/linux/realtek/rtl839x/config-5.15 b/target/linux/realtek/rtl839x/config-5.15 deleted file mode 100644 index c8d841c01e92e1..00000000000000 --- a/target/linux/realtek/rtl839x/config-5.15 +++ /dev/null @@ -1,244 +0,0 @@ -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MMAP_RND_BITS_MAX=15 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BMIPS_CPUFREQ is not set -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_REALTEK=y -CONFIG_COMMON_CLK_RTL83XX=y -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_BIG_ENDIAN=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_GENERIC_DUMP_TLB=y -CONFIG_CPU_HAS_DIEI=y -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_CPU_HAS_RIXI=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_CPU_MIPS32=y -# CONFIG_CPU_MIPS32_R1 is not set -CONFIG_CPU_MIPS32_R2=y -CONFIG_CPU_MIPSR2=y -CONFIG_CPU_MIPSR2_IRQ_EI=y -CONFIG_CPU_MIPSR2_IRQ_VI=y -CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y -CONFIG_CPU_R4K_CACHE_TLB=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_CPUFREQ=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_CPU_SUPPORTS_MSA=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 -CONFIG_CRYPTO_RNG2=y -CONFIG_DEBUG_SECTION_MISMATCH=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DTC=y -CONFIG_EARLY_PRINTK=y -CONFIG_EARLY_PRINTK_8250=y -CONFIG_FIXED_PHY=y -CONFIG_FORCE_MAX_ZONEORDER=13 -CONFIG_FWNODE_MDIO=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ATOMIC64=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IOMAP=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_LIB_ASHLDI3=y -CONFIG_GENERIC_LIB_ASHRDI3=y -CONFIG_GENERIC_LIB_CMPDI2=y -CONFIG_GENERIC_LIB_LSHRDI3=y -CONFIG_GENERIC_LIB_UCMPDI2=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_PCA953X=y -CONFIG_GPIO_PCA953X_IRQ=y -CONFIG_GPIO_REALTEK_OTTO=y -CONFIG_GPIO_RTL8231=y -CONFIG_GPIO_WATCHDOG=y -# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set -CONFIG_GRO_CELLS=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDWARE_WATCHPOINTS=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HWMON=y -CONFIG_HZ_PERIODIC=y -CONFIG_I2C=y -CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_GPIO=y -# CONFIG_I2C_RTL9300 is not set -# CONFIG_I2C_MUX_RTL9300 is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_MIPS_CPU=y -CONFIG_IRQ_WORK=y -CONFIG_JFFS2_ZLIB=y -CONFIG_LEDS_GPIO=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_MARVELL_PHY=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MDIO_I2C=y -CONFIG_MDIO_SMBUS=y -CONFIG_MEMFD_CREATE=y -CONFIG_MFD_SYSCON=y -CONFIG_MIGRATION=y -CONFIG_MIPS=y -CONFIG_MIPS_ASID_BITS=8 -CONFIG_MIPS_ASID_SHIFT=0 -CONFIG_MIPS_CLOCK_VSYSCALL=y -# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set -# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set -CONFIG_MIPS_CMDLINE_FROM_DTB=y -CONFIG_MIPS_EBPF_JIT=y -CONFIG_MIPS_EXTERNAL_TIMER=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 -CONFIG_MIPS_LD_CAN_LINK_VDSO=y -CONFIG_MIPS_MT=y -# CONFIG_MIPS_MT_FPAFF is not set -CONFIG_MIPS_MT_SMP=y -# CONFIG_MIPS_NO_APPENDED_DTB is not set -CONFIG_MIPS_NR_CPU_NR_MAP=2 -CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y -CONFIG_MIPS_RAW_APPENDED_DTB=y -CONFIG_MIPS_SPRAM=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPLIT_BRNIMAGE_FW=y -CONFIG_MTD_SPLIT_EVA_FW=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_H3C_VFS=y -CONFIG_MTD_SPLIT_TPLINK_FW=y -CONFIG_MTD_SPLIT_UIMAGE_FW=y -CONFIG_MTD_VIRT_CONCAT=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_RTL83XX=y -CONFIG_NET_DSA_TAG_TRAILER=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_RTL838X=y -CONFIG_NET_SELFTESTS=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NO_EXCEPT_FILL=y -CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y -CONFIG_NR_CPUS=2 -CONFIG_NVMEM=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_PADATA=y -CONFIG_PCI_DRIVERS_LEGACY=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLINK=y -CONFIG_PINCTRL=y -CONFIG_PM_OPP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_GPIO_RESTART=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -CONFIG_RATIONAL=y -CONFIG_REALTEK_OTTO_TIMER=y -CONFIG_REALTEK_OTTO_WDT=y -CONFIG_REALTEK_PHY=y -CONFIG_REALTEK_SOC_PHY=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -# CONFIG_RTL838X is not set -CONFIG_RTL839X=y -CONFIG_RTL83XX=y -# CONFIG_RTL930X is not set -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SFP=y -CONFIG_SMP=y -CONFIG_SMP_UP=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_SPI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SRAM=y -CONFIG_SRCU=y -CONFIG_SWPHY=y -CONFIG_SYNC_R4K=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_SYS_HAS_CPU_MIPS32_R1=y -CONFIG_SYS_HAS_CPU_MIPS32_R2=y -CONFIG_SYS_HAS_EARLY_PRINTK=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_SYS_SUPPORTS_HIGHMEM=y -CONFIG_SYS_SUPPORTS_MIPS16=y -CONFIG_SYS_SUPPORTS_MULTITHREADING=y -CONFIG_SYS_SUPPORTS_SCHED_SMT=y -CONFIG_SYS_SUPPORTS_SMP=y -CONFIG_TARGET_ISA_REV=2 -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TINY_SRCU=y -CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y -CONFIG_USE_OF=y -CONFIG_WATCHDOG_CORE=y -CONFIG_XPS=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y diff --git a/target/linux/realtek/rtl930x/config-5.15 b/target/linux/realtek/rtl930x/config-5.15 deleted file mode 100644 index af5f2ca7a313b4..00000000000000 --- a/target/linux/realtek/rtl930x/config-5.15 +++ /dev/null @@ -1,205 +0,0 @@ -CONFIG_AQUANTIA_PHY=y -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MMAP_RND_BITS_MAX=15 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BOARD_SCACHE=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -# CONFIG_COMMON_CLK_REALTEK is not set -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 -CONFIG_CPU_BIG_ENDIAN=y -CONFIG_CPU_GENERIC_DUMP_TLB=y -CONFIG_CPU_HAS_DIEI=y -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_CPU_HAS_RIXI=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_CPU_MIPS32=y -# CONFIG_CPU_MIPS32_R1 is not set -CONFIG_CPU_MIPS32_R2=y -CONFIG_CPU_MIPSR2=y -CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y -CONFIG_CPU_R4K_CACHE_TLB=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_CPU_SUPPORTS_MSA=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 -CONFIG_CRYPTO_RNG2=y -CONFIG_DEBUG_SECTION_MISMATCH=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DTC=y -CONFIG_EARLY_PRINTK=y -CONFIG_EARLY_PRINTK_8250=y -CONFIG_FIXED_PHY=y -CONFIG_FORCE_MAX_ZONEORDER=13 -CONFIG_FWNODE_MDIO=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_GENERIC_ATOMIC64=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IOMAP=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_LIB_ASHLDI3=y -CONFIG_GENERIC_LIB_ASHRDI3=y -CONFIG_GENERIC_LIB_CMPDI2=y -CONFIG_GENERIC_LIB_LSHRDI3=y -CONFIG_GENERIC_LIB_UCMPDI2=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_PCA953X=y -CONFIG_GPIO_REALTEK_OTTO=y -CONFIG_GPIO_RTL8231=y -CONFIG_GRO_CELLS=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDWARE_WATCHPOINTS=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HWMON=y -CONFIG_HZ_PERIODIC=y -CONFIG_I2C=y -CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_I2C_MUX=y -CONFIG_I2C_MUX_RTL9300=y -CONFIG_I2C_RTL9300=y -CONFIG_I2C_SMBUS=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_MIPS_CPU=y -CONFIG_IRQ_WORK=y -CONFIG_JFFS2_ZLIB=y -CONFIG_LEDS_GPIO=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_MARVELL_PHY=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MDIO_I2C=y -CONFIG_MDIO_SMBUS=y -CONFIG_MEMFD_CREATE=y -CONFIG_MFD_SYSCON=y -CONFIG_MIGRATION=y -CONFIG_MIPS=y -CONFIG_MIPS_ASID_BITS=8 -CONFIG_MIPS_ASID_SHIFT=0 -# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set -CONFIG_MIPS_CMDLINE_FROM_DTB=y -CONFIG_MIPS_CPU_SCACHE=y -CONFIG_MIPS_EBPF_JIT=y -CONFIG_MIPS_EXTERNAL_TIMER=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 -CONFIG_MIPS_LD_CAN_LINK_VDSO=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_NO_APPENDED_DTB is not set -CONFIG_MIPS_RAW_APPENDED_DTB=y -CONFIG_MIPS_SPRAM=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPLIT_BRNIMAGE_FW=y -CONFIG_MTD_SPLIT_EVA_FW=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_TPLINK_FW=y -CONFIG_MTD_SPLIT_UIMAGE_FW=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_PER_CPU_KM=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_RTL83XX=y -CONFIG_NET_DSA_TAG_TRAILER=y -CONFIG_NET_RTL838X=y -CONFIG_NET_SELFTESTS=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NO_EXCEPT_FILL=y -CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y -CONFIG_NVMEM=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_PCI_DRIVERS_LEGACY=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLINK=y -CONFIG_PINCTRL=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_GPIO_RESTART=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_RATIONAL=y -CONFIG_REALTEK_OTTO_TIMER=y -CONFIG_REALTEK_OTTO_WDT=y -CONFIG_REALTEK_PHY=y -CONFIG_REALTEK_SOC_PHY=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_RESET_CONTROLLER=y -# CONFIG_RTL838X is not set -# CONFIG_RTL839X is not set -CONFIG_RTL83XX=y -CONFIG_RTL930X=y -# CONFIG_RTL931X is not set -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SFP=y -CONFIG_SPI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SRCU=y -CONFIG_SWPHY=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_SYS_HAS_CPU_MIPS32_R1=y -CONFIG_SYS_HAS_CPU_MIPS32_R2=y -CONFIG_SYS_HAS_EARLY_PRINTK=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_SYS_SUPPORTS_HIGHMEM=y -CONFIG_SYS_SUPPORTS_MIPS16=y -CONFIG_SYS_SUPPORTS_MULTITHREADING=y -CONFIG_TARGET_ISA_REV=2 -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TINY_SRCU=y -CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y -CONFIG_USE_OF=y -CONFIG_WATCHDOG_CORE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y diff --git a/target/linux/realtek/rtl931x/config-5.15 b/target/linux/realtek/rtl931x/config-5.15 deleted file mode 100644 index 2da27941c74c39..00000000000000 --- a/target/linux/realtek/rtl931x/config-5.15 +++ /dev/null @@ -1,241 +0,0 @@ -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MMAP_RND_BITS_MAX=15 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BOARD_SCACHE=y -CONFIG_CEVT_RTL9300=y -CONFIG_CLKSRC_MIPS_GIC=y -CONFIG_CLOCKSOURCE_WATCHDOG=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -# CONFIG_COMMON_CLK_REALTEK is not set -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 -CONFIG_CPU_BIG_ENDIAN=y -CONFIG_CPU_GENERIC_DUMP_TLB=y -CONFIG_CPU_HAS_DIEI=y -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_CPU_HAS_RIXI=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_CPU_MIPS32=y -# CONFIG_CPU_MIPS32_R1 is not set -CONFIG_CPU_MIPS32_R2=y -CONFIG_CPU_MIPSR2=y -CONFIG_CPU_MIPSR2_IRQ_EI=y -CONFIG_CPU_MIPSR2_IRQ_VI=y -CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y -CONFIG_CPU_R4K_CACHE_TLB=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_CPU_SUPPORTS_MSA=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 -CONFIG_CRYPTO_RNG2=y -CONFIG_CSRC_R4K=y -CONFIG_DEBUG_SECTION_MISMATCH=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DTC=y -CONFIG_EARLY_PRINTK=y -CONFIG_EARLY_PRINTK_8250=y -CONFIG_FIXED_PHY=y -CONFIG_FORCE_MAX_ZONEORDER=13 -CONFIG_FWNODE_MDIO=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_GENERIC_ATOMIC64=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IOMAP=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_LIB_ASHLDI3=y -CONFIG_GENERIC_LIB_ASHRDI3=y -CONFIG_GENERIC_LIB_CMPDI2=y -CONFIG_GENERIC_LIB_LSHRDI3=y -CONFIG_GENERIC_LIB_UCMPDI2=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_REALTEK_OTTO=y -CONFIG_GPIO_RTL8231=y -CONFIG_GRO_CELLS=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDWARE_WATCHPOINTS=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HIGHMEM=y -CONFIG_HWMON=y -CONFIG_HZ_PERIODIC=y -CONFIG_I2C=y -CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_GPIO=y -CONFIG_I2C_MUX=y -CONFIG_I2C_MUX_RTL9300=y -CONFIG_I2C_RTL9300=y -CONFIG_I2C_SMBUS=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_MIPS_CPU=y -CONFIG_IRQ_WORK=y -CONFIG_JFFS2_ZLIB=y -CONFIG_KMAP_LOCAL=y -CONFIG_LEDS_GPIO=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_MARVELL_PHY=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MDIO_I2C=y -CONFIG_MDIO_SMBUS=y -CONFIG_MEMFD_CREATE=y -CONFIG_MFD_SYSCON=y -CONFIG_MIGRATION=y -CONFIG_MIPS=y -CONFIG_MIPS_ASID_BITS=8 -CONFIG_MIPS_ASID_SHIFT=0 -CONFIG_MIPS_CLOCK_VSYSCALL=y -CONFIG_MIPS_CM=y -# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set -CONFIG_MIPS_CMDLINE_FROM_DTB=y -CONFIG_MIPS_CPC=y -CONFIG_MIPS_CPS=y -# CONFIG_MIPS_CPS_NS16550_BOOL is not set -CONFIG_MIPS_CPU_SCACHE=y -CONFIG_MIPS_EBPF_JIT=y -CONFIG_MIPS_GIC=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 -CONFIG_MIPS_LD_CAN_LINK_VDSO=y -CONFIG_MIPS_MT=y -CONFIG_MIPS_MT_FPAFF=y -CONFIG_MIPS_MT_SMP=y -# CONFIG_MIPS_NO_APPENDED_DTB is not set -CONFIG_MIPS_NR_CPU_NR_MAP=2 -CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y -CONFIG_MIPS_RAW_APPENDED_DTB=y -CONFIG_MIPS_SPRAM=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPLIT_BRNIMAGE_FW=y -CONFIG_MTD_SPLIT_EVA_FW=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_TPLINK_FW=y -CONFIG_MTD_SPLIT_UIMAGE_FW=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_RTL83XX=y -CONFIG_NET_DSA_TAG_TRAILER=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_RTL838X=y -CONFIG_NET_SELFTESTS=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NO_EXCEPT_FILL=y -CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y -CONFIG_NR_CPUS=2 -CONFIG_NVMEM=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_PADATA=y -CONFIG_PCI_DRIVERS_LEGACY=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLINK=y -CONFIG_PINCTRL=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -CONFIG_RATIONAL=y -# CONFIG_REALTEK_OTTO_TIMER is not set -CONFIG_REALTEK_OTTO_WDT=y -# CONFIG_REALTEK_PHY is not set -CONFIG_REALTEK_SOC_PHY=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -# CONFIG_RTL838X is not set -# CONFIG_RTL839X is not set -CONFIG_RTL83XX=y -CONFIG_RTL930X=y -CONFIG_RTL931X=y -CONFIG_SENSORS_GPIO_FAN=y -CONFIG_SENSORS_LM75=y -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SFP=y -CONFIG_SMP=y -CONFIG_SMP_UP=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_SPI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SRCU=y -CONFIG_SWPHY=y -CONFIG_SYNC_R4K=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_SYS_HAS_CPU_MIPS32_R1=y -CONFIG_SYS_HAS_CPU_MIPS32_R2=y -CONFIG_SYS_HAS_EARLY_PRINTK=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_SYS_SUPPORTS_HIGHMEM=y -CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y -CONFIG_SYS_SUPPORTS_MIPS16=y -CONFIG_SYS_SUPPORTS_MIPS_CPS=y -CONFIG_SYS_SUPPORTS_MULTITHREADING=y -CONFIG_SYS_SUPPORTS_SCHED_SMT=y -CONFIG_SYS_SUPPORTS_SMP=y -CONFIG_SYS_SUPPORTS_VPE_LOADER=y -CONFIG_TARGET_ISA_REV=2 -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y -CONFIG_USE_OF=y -CONFIG_WATCHDOG_CORE=y -CONFIG_WEAK_ORDERING=y -CONFIG_XPS=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y From 82a5971688769c06efe4f91e102cb9738476fe1d Mon Sep 17 00:00:00 2001 From: Mieczyslaw Nalewaj Date: Tue, 17 Sep 2024 22:02:06 +0200 Subject: [PATCH 02/23] generic: drop 5.15 support Drop config and files for Linux 5.15. Signed-off-by: Mieczyslaw Nalewaj Link: https://github.com/openwrt/openwrt/pull/16417 Signed-off-by: Robert Marko --- include/kernel-5.15 | 2 - ...ild-use-Wdeclaration-after-statement.patch | 73 - ...05-v5.17-02-Kbuild-move-to-std-gnu11.patch | 60 - ...-use-std-gnu11-for-KBUILD_USERCFLAGS.patch | 43 - ...-x86-arm64-add-arch_has_hw_pte_young.patch | 425 - ...dd-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch | 153 - ...-03-mm-vmscan.c-refactor-shrink_node.patch | 275 - ...inux-mm_inline.h-fold-__update_lru_s.patch | 82 - ...-v6.1-05-mm-multi-gen-LRU-groundwork.patch | 807 -- ...multi-gen-LRU-minimal-implementation.patch | 1447 ---- ...lti-gen-LRU-exploit-locality-in-rmap.patch | 491 -- ...lti-gen-LRU-support-page-table-walks.patch | 1687 ---- ...lti-gen-LRU-optimize-multiple-memcgs.patch | 315 - ...v6.1-10-mm-multi-gen-LRU-kill-switch.patch | 498 -- ...m-multi-gen-LRU-thrashing-prevention.patch | 226 - ...2-mm-multi-gen-LRU-debugfs-interface.patch | 579 -- ...don-t-sync-disk-for-each-aging-cycle.patch | 32 - ...-retry-pages-written-back-while-isol.patch | 124 - ...-move-lru_gen_add_mm-out-of-IRQ-off-.patch | 49 - ..._young-for-architectures-not-having-.patch | 96 - ...roduce-arch_has_hw_nonleaf_pmd_young.patch | 113 - ...RU-fix-crash-during-cgroup-migration.patch | 56 - .../020-v6.3-19-mm-add-vma_has_recency.patch | 196 - ...6.3-20-mm-support-POSIX_FADV_NOREUSE.patch | 125 - ...-rename-lru_gen_struct-to-lru_gen_pa.patch | 348 - ...-rename-lrugen-lists-to-lrugen-pages.patch | 162 - ...U-remove-eviction-fairness-safeguard.patch | 188 - ...-LRU-remove-aging-fairness-safeguard.patch | 287 - ...lti-gen-LRU-shuffle-should_run_aging.patch | 161 - ...-gen-LRU-per-node-lru_gen_page-lists.patch | 868 -- ...i-gen-LRU-clarify-scan_control-flags.patch | 196 - ...-simplify-arch_has_hw_pte_young-chec.patch | 34 - ...m-multi-gen-LRU-avoid-futile-retries.patch | 88 - ...i-gen-LRU-remove-wait_event_killable.patch | 266 - ...-uasm-Enable-muhu-opcode-for-MIPS-R6.patch | 65 - ...rkaround-for-Loongson-2F-nop-CPU-err.patch | 31 - ...ips-bpf-Add-eBPF-JIT-for-32-bit-MIPS.patch | 3078 ------- ...bpf-Add-new-eBPF-JIT-for-64-bit-MIPS.patch | 1005 --- ...f-Add-JIT-workarounds-for-CPU-errata.patch | 120 - ...0-v5.16-05-mips-bpf-Enable-eBPF-JITs.patch | 61 - ...f-Remove-old-BPF-JIT-implementations.patch | 387 - ...d-helpers-to-directly-use-the-capget.patch | 123 - ...move-libcap-usage-from-test_verifier.patch | 188 - ...-Remove-libcap-usage-from-test_progs.patch | 122 - ...k-gate-Add-devm_clk_hw_register_gate.patch | 105 - ...63xx-use-more-precise-Kconfig-symbol.patch | 37 - ...resolve_btfids-Build-with-host-flags.patch | 49 - ...te-to-upstream-version-v1.6.1-19-g0a.patch | 997 --- ...-kallsyms-support-big-kernel-symbols.patch | 128 - ...or-setting-affinity-if-no-IRQ-parent.patch | 48 - ...-Support-reserved-memory-description.patch | 166 - ...-bcm63xx_wdt-fix-fallthrough-warning.patch | 33 - ...-some-linker-warnings-in-recent-link.patch | 63 - ...kernel-proc-add-CPU-option-reporting.patch | 162 - ...mp_processor_id-in-preemptible-in-sh.patch | 62 - ...spinand-Add-support-for-XTX-XT26G0xA.patch | 186 - ...mvebu-a3700-comphy-Remove-port-from-.patch | 219 - ...mvebu-a3700-comphy-Add-native-kernel.patch | 1552 ---- ...l-armada-37xx-Add-xtal-clock-to-comp.patch | 32 - ...mvebu-Make-SATA-PHY-optional-for-Arm.patch | 64 - ...xhci-mvebu-make-USB-3.0-PHY-optional.patch | 166 - ...ark-Fix-initialization-with-old-Marv.patch | 39 - ...mvebu-a3700-comphy-Remove-broken-res.patch | 194 - ...configurable-downshift-for-addresses.patch | 90 - ...efined-reg_base-to-be-added-to-every.patch | 95 - ..._base-and-reg_downshift-for-single-r.patch | 57 - ...powerpc-vdso-link-with-z-noexecstack.patch | 49 - ...platform_populate-for-MTD-partitions.patch | 72 - ...s-add-support-for-Sercomm-partitions.patch | 302 - ...ce-of-support-for-dynamic-partitions.patch | 106 - ...g-MTD-device-associated-with-a-speci.patch | 72 - ...e-check-partition-before-dereference.patch | 30 - ...sing-of_node_get-in-dynamic-partitio.patch | 101 - ...y-a-bit-code-find-partition-matching.patch | 65 - ...find-OF-node-for-every-MTD-partition.patch | 84 - ...-Don-t-print-error-message-on-EPROBE.patch | 32 - ...T_DEV-for-partitions-marked-as-rootf.patch | 47 - ...t-create-platform-device-that-ll-nev.patch | 54 - ...x-allow-to-use-on-MediaTek-MIPS-SoCs.patch | 33 - ...nand-Support-write-protection-settin.patch | 36 - ...ilicon-Labs-EM3581-device-compatible.patch | 32 - ...ilicon-Labs-SI3210-device-compatible.patch | 32 - ...device-add-support-for-GD5FxGQ4xExxG.patch | 58 - ...device-add-support-for-GD5F1GQ5RExxG.patch | 33 - ...device-add-support-for-GD5F-2-4-GQ5x.patch | 84 - ...device-add-support-for-GD5FxGM7xExxG.patch | 91 - ...TP-Link-SafeLoader-partitions-table-.patch | 229 - ...9-mtd-spi-nor-support-eon-en25qh256a.patch | 49 - ...m-number-of-bitflips-for-each-read-r.patch | 73 - ...itialize-stats-in-struct-mtd_oob_ops.patch | 325 - ...ror-accounting-for-each-read-request.patch | 172 - ...-v6.1-0004-mtdchar-add-MEMREAD-ioctl.patch | 321 - ...onix-use-scratch-buffer-for-DMA-oper.patch | 35 - ...-mtd_otp_nvmem_add-to-handle-EPROBE_.patch | 47 - ...v5.18-page_pool-Add-allocation-stats.patch | 165 - ...01-v5.18-page_pool-Add-recycle-stats.patch | 140 - ...d-function-to-batch-and-return-stats.patch | 77 - ...cycle-stats-to-page_pool_put_page_bu.patch | 55 - ...et-page_pool-introduce-ethtool-stats.patch | 147 - ...ce-flags-field-in-xdp_buff-xdp_frame.patch | 99 - ...gs-support-to-xdp_return_-buff-frame.patch | 137 - ...ize-metadata-to-skb_shared_info-for-.patch | 31 - ...-total-xdp_frame-len-running-ndo_xdp.patch | 65 - ...-veth-Allow-jumbo-frames-in-xdp-mode.patch | 40 - ...611-v6.3-net-add-helper-eth_addr_add.patch | 41 - ...uce-tagger-owned-storage-for-private.patch | 279 - ...ocols-connect-to-individual-switches.patch | 274 - ..._eth_soc-add-support-for-coherent-DM.patch | 327 - ..._eth_soc-add-support-for-Wireless-Et.patch | 1679 ---- ..._eth_soc-implement-flow-offloading-t.patch | 269 - ..._eth_soc-add-ipv6-flow-offload-suppo.patch | 79 - ..._eth_soc-support-TC_SETUP_BLOCK-for-.patch | 29 - ..._eth_soc-allocate-struct-mtk_ppe-sep.patch | 159 - ..._eth_soc-rework-hardware-flow-table-.patch | 424 - ..._eth_soc-remove-bridge-flow-offload-.patch | 44 - ..._eth_soc-support-creating-mac-addres.patch | 553 -- ..._eth_soc-wed-fix-sparse-endian-warni.patch | 56 - ..._eth_soc-fix-return-value-check-in-m.patch | 25 - ..._eth_soc-use-standard-property-for-c.patch | 35 - ..._eth_soc-use-after-free-in-__mtk_ppe.patch | 33 - ..._eth_soc-add-check-for-allocation-fa.patch | 22 - ...silence-the-GCC-12-array-bounds-warn.patch | 26 - ..._eth_soc-rely-on-GFP_KERNEL-for-dma_.patch | 52 - ..._eth_soc-move-tx-dma-desc-configurat.patch | 206 - ..._eth_soc-add-txd_size-to-mtk_soc_dat.patch | 167 - ..._eth_soc-rely-on-txd_size-in-mtk_tx_.patch | 78 - ..._eth_soc-rely-on-txd_size-in-mtk_des.patch | 109 - ..._eth_soc-rely-on-txd_size-in-txd_to_.patch | 39 - ..._eth_soc-add-rxd_size-to-mtk_soc_dat.patch | 102 - ..._eth_soc-rely-on-txd_size-field-in-m.patch | 46 - ..._eth_soc-rely-on-rxd_size-field-in-m.patch | 68 - ..._eth_soc-introduce-device-register-m.patch | 814 -- ..._eth_soc-introduce-MTK_NETSYS_V2-sup.patch | 917 -- ..._eth_soc-convert-ring-dma-pointer-to.patch | 135 - ..._eth_soc-convert-scratch_ring-pointe.patch | 33 - ..._eth_soc-introduce-support-for-mt798.patch | 138 - ..._eth_soc-fix-error-code-in-mtk_flow_.patch | 25 - ..._eth_soc-enable-rx-cksum-offload-for.patch | 47 - ...19-34-eth-mtk_ppe-fix-up-after-merge.patch | 28 - ...-users-of-bitmap_foo-to-linkmode_foo.patch | 948 -- ...ylink-add-MAC-phy_interface_t-bitmap.patch | 24 - ...supported_interfaces-for-phylink-val.patch | 98 - ...populate-supported_interfaces-member.patch | 63 - ...net-dsa-consolidate-phylink-creation.patch | 149 - ...phylink_get_interfaces-with-phylink_.patch | 51 - ...d-support-for-phylink-mac_select_pcs.patch | 59 - ...y-add-phy_interface_t-bitmap-support.patch | 61 - ...mac_select_pcs-method-to-phylink_mac.patch | 197 - ...-add-generic-validate-implementation.patch | 341 - ...-net-phylink-add-pcs_validate-method.patch | 106 - ...k-add-legacy_pre_march2020-indicator.patch | 43 - ...-DSA-phylink-as-legacy_pre_march2020.patch | 36 - ...net-phylink-use-legacy_pre_march2020.patch | 115 - ...-fix-DSA-mac_select_pcs-introduction.patch | 88 - ...populate-supported_interfaces-member.patch | 48 - ...e-interface-checks-in-mvneta_validat.patch | 35 - ...op-use-of-phylink_helper_basex_speed.patch | 55 - ...-mvneta-use-phylink_generic_validate.patch | 72 - ...ark-as-a-legacy_pre_march2020-driver.patch | 29 - ...populate-supported_interfaces-member.patch | 43 - ...remove-interface-checks-in-mtk_valid.patch | 75 - ...drop-use-of-phylink_helper_basex_spe.patch | 42 - ...eth_soc-use-phylink_generic_validate.patch | 84 - ...mark-as-a-legacy_pre_march2020-drive.patch | 29 - ...remove-a-copy-of-the-NAPI_POLL_WEIGH.patch | 40 - ...9-mtk_eth_soc-remove-unused-mac-mode.patch | 35 - ...tk_eth_soc-remove-unused-sgmii-flags.patch | 40 - ...add-mask-and-update-PCS-speed-defini.patch | 40 - ...eth_soc-correct-802.3z-speed-setting.patch | 60 - ...th_soc-correct-802.3z-duplex-setting.patch | 101 - ...stop-passing-phylink-state-to-sgmii-.patch | 60 - ...mtk_eth_soc-provide-mtk_sgmii_config.patch | 89 - ...add-fixme-comment-for-state-speed-us.patch | 38 - ...move-restoration-of-SYSCFG0-to-mac_f.patch | 57 - ...convert-code-structure-to-suit-split.patch | 254 - ...soc-partially-convert-to-phylink_pcs.patch | 262 - ...terate-using-dsa_switch_for_each_use.patch | 106 - ...opulate-supported_interfaces-and-mac.patch | 166 - ...t-dsa-mt7530-remove-interface-checks.patch | 172 - ...rop-use-of-phylink_helper_basex_spee.patch | 34 - ...nly-indicate-linkmodes-that-can-be-s.patch | 86 - ...-switch-to-use-phylink_get_linkmodes.patch | 131 - ...530-partially-convert-to-phylink_pcs.patch | 385 - ...ove-autoneg-handling-to-PCS-validati.patch | 80 - ...19-net-dsa-mt7530-mark-as-non-legacy.patch | 34 - ...mt753x-fix-pcs-conversion-regression.patch | 116 - ...t7530-rework-mt7530_hw_vlan_-add-del.patch | 87 - ...et-cpu-port-via-dp-cpu_dp-instead-of.patch | 117 - ..._eth_soc-rely-on-page_pool-for-singl.patch | 330 - ...et-mtk_eth_soc-add-basic-XDP-support.patch | 291 - ..._eth_soc-introduce-xdp-ethtool-count.patch | 110 - ...net-mtk_eth_soc-add-xmit-XDP-support.patch | 340 - ..._eth_soc-add-support-for-page_pool_g.patch | 95 - ..._eth_soc-introduce-mtk_xdp_frame_map.patch | 113 - ..._eth_soc-introduce-xdp-multi-frag-su.patch | 218 - ...cs-add-driver-for-MediaTek-SGMII-PCS.patch | 394 - ...16-net-mvneta-Delete-unused-variable.patch | 62 - ...otential-double-frees-in-mvneta_txq_.patch | 37 - ..._eth_soc-fix-hw-hash-reporting-for-M.patch | 74 - ..._eth_soc-fix-off-by-one-check-of-ARR.patch | 31 - ..._ppe-fix-possible-NULL-pointer-deref.patch | 27 - ...-ppe-fix-traffic-offload-with-bridge.patch | 64 - ..._eth_soc-remove-mtk_foe_entry_timest.patch | 33 - ..._eth_soc-enable-XDP-support-just-for.patch | 35 - ..._eth_soc-move-gdma_to_ppe-and-ppe_ba.patch | 127 - ..._eth_soc-move-ppe-table-hash-offset-.patch | 199 - ..._eth_soc-add-the-capability-to-run-m.patch | 318 - ..._eth_soc-move-wdma_base-definitions-.patch | 80 - ..._eth_soc-add-foe_entry_size-to-mtk_e.patch | 251 - ..._eth_soc-fix-typo-in-__mtk_foe_entry.patch | 27 - ..._eth_soc-check-max-allowed-value-in-.patch | 28 - ..._eth_wed-add-mtk_wed_configure_irq-a.patch | 189 - ..._eth_wed-add-wed-support-for-mt7986-.patch | 942 -- ...rnet-mtk_eth_wed-add-axi-bus-support.patch | 230 - ..._eth_soc-introduce-flow-offloading-s.patch | 882 -- ..._eth_soc-fix-wrong-use-of-new-helper.patch | 46 - ..._eth_soc-enable-flow-offloading-supp.patch | 26 - ..._eth_soc-fix-usage-of-foe_entry_size.patch | 49 - ..._eth_soc-fix-mask-of-RX_DMA_GET_SPOR.patch | 32 - ..._eth_soc-fix-state-in-__mtk_foe_entr.patch | 37 - ..._eth_soc-fix-possible-memory-leak-in.patch | 73 - ..._eth_wed-add-missing-put_device-in-m.patch | 47 - ...-mtk_eth_wed-add-missing-of_node_put.patch | 43 - ..._eth_soc-fix-resource-leak-in-error-.patch | 35 - ..._eth_soc-fix-memory-leak-in-error-pa.patch | 107 - ...et-mtk_wed-introduce-wed-mcu-support.patch | 591 -- ...net-mtk_wed-introduce-wed-wo-support.patch | 737 -- ..._wed-rename-tx_wdma-array-in-rx_wdma.patch | 79 - ...mtk_wed-add-configure-wed-wo-support.patch | 1521 ---- ...ethernet-mtk_wed-add-rx-mib-counters.patch | 149 - ..._eth_soc-do-not-overwrite-mtu-config.patch | 98 - ..._eth_soc-remove-cpu_relax-in-mtk_pen.patch | 36 - ..._eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch | 63 - ..._wed-add-wcid-overwritten-support-fo.patch | 80 - ..._wed-return-status-value-in-mtk_wdma.patch | 85 - ..._wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch | 52 - ...ethernet-mtk_wed-update-mtk_wed_stop.patch | 98 - ...mtk_wed-add-mtk_wed_rx_reset-routine.patch | 309 - ..._wed-add-reset-to-tx_ring_setup-call.patch | 103 - ..._wed-fix-sleep-while-atomic-in-mtk_w.patch | 103 - ..._wed-get-rid-of-queue-lock-for-rx-qu.patch | 52 - ..._wed-get-rid-of-queue-lock-for-tx-qu.patch | 75 - ..._eth_soc-introduce-mtk_hw_reset-util.patch | 70 - ..._eth_soc-introduce-mtk_hw_warm_reset.patch | 107 - ..._eth_soc-align-reset-procedure-to-ve.patch | 262 - ..._eth_soc-add-dma-checks-to-mtk_hw_re.patch | 249 - ..._wed-add-reset-reset_complete-callba.patch | 124 - ..._wed-add-reset-to-rx_ring_setup-call.patch | 106 - ..._eth_soc-account-for-vlan-in-rx-head.patch | 22 - ..._eth_soc-increase-tx-ring-side-for-Q.patch | 143 - ..._eth_soc-avoid-port_mg-assignment-on.patch | 52 - ..._eth_soc-implement-multi-queue-suppo.patch | 654 -- ...t-dsa-tag_mtk-assign-per-port-queues.patch | 20 - ...iatek-ppe-assign-per-port-queues-for.patch | 93 - ...ort-for-DSA-rx-offloading-via-metada.patch | 72 - ..._eth_soc-fix-VLAN-rx-hardware-accele.patch | 192 - ..._eth_soc-drop-packets-to-WDMA-if-the.patch | 37 - ..._eth_soc-disable-hardware-DSA-untagg.patch | 42 - ..._eth_soc-enable-special-tag-when-any.patch | 54 - ..._eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch | 129 - ..._wed-No-need-to-clear-memory-after-a.patch | 26 - ..._wed-fix-some-possible-NULL-pointer-.patch | 61 - ..._wed-fix-possible-deadlock-if-mtk_we.patch | 58 - ..._eth_soc-fix-tx-throughput-regressio.patch | 31 - ...1-net-phy-Introduce-QUSGMII-PHY-mode.patch | 99 - ...er-to-derive-the-number-of-ports-fro.patch | 93 - ...t-phy-Add-1000BASE-KX-interface-mode.patch | 96 - ...et-phy-Add-support-for-rate-matching.patch | 294 - ..._eth_soc-Avoid-truncating-allocation.patch | 60 - ...-mtk_eth_soc-add-definitions-for-PCS.patch | 55 - ...eliminate-unnecessary-error-handling.patch | 74 - ...soc-add-pcs_get_state-implementation.patch | 46 - ...convert-mtk_sgmii-to-use-regmap_upda.patch | 130 - ...add-out-of-band-forcing-of-speed-and.patch | 52 - ...07-net-mtk_eth_soc-move-PHY-power-up.patch | 48 - ...h_soc-move-interface-speed-selection.patch | 48 - ...th_soc-add-advertisement-programming.patch | 52 - ...move-and-correct-link-timer-programm.patch | 63 - ...add-support-for-in-band-802.3z-negot.patch | 132 - ...ii-ensure-the-SGMII-PHY-is-powered-d.patch | 119 - ...iatek-sgmii-fix-duplex-configuration.patch | 52 - ...enable-PCS-polling-to-allow-SFP-work.patch | 33 - ...ethernet-mtk_eth_soc-reset-PCS-state.patch | 48 - ..._eth_soc-only-write-values-if-needed.patch | 103 - ...t-mtk_eth_soc-add-support-for-MT7981.patch | 200 - ..._eth_soc-set-MDIO-bus-clock-frequenc.patch | 76 - ..._eth_soc-switch-to-external-PCS-driv.patch | 512 -- ..._eth_soc-add-missing-ppe-cache-flush.patch | 21 - ...k_eth_soc-use-WO-firmware-for-MT7981.patch | 46 - ..._eth_soc-fix-NULL-pointer-dereferenc.patch | 28 - ..._eth_soc-ppe-add-support-for-flow-ac.patch | 428 - ...iatek-fix-ppe-flow-accounting-for-v1.patch | 51 - ..._eth_soc-drop-generic-vlan-rx-offloa.patch | 201 - ..._eth_soc-always-mtk_get_ib1_pkt_type.patch | 31 - ...-0001-net-bgmac-improve-handling-PHY.patch | 84 - ...t-bgmac-support-MDIO-described-in-DT.patch | 54 - ...net-phy-Add-support-for-AQR113C-EPHY.patch | 58 - ...a-Add-some-additional-phy-interfaces.patch | 71 - ...uantia-Add-support-for-rate-matching.patch | 148 - ...-aquantia-move-to-separate-directory.patch | 2310 ----- ...antia-move-MMD_VEND-define-to-header.patch | 183 - ...y-aquantia-add-firmware-load-support.patch | 504 -- ...antia-add-AQR111-and-AQR111B0-PHY-ID.patch | 100 - ...9-net-phy-aquantia-add-AQR113-PHY-ID.patch | 59 - ...9-net-phy-aquantia-add-AQR813-PHY-ID.patch | 58 - ...dd-support-for-qca-8327-internal-phy.patch | 48 - ...3-Include-all-ports-in-enabled_ports.patch | 131 - ...-BCM5301x-workaround-for-a-wrong-CPU.patch | 42 - ...prove-flow-control-setup-on-BCM5301x.patch | 32 - ...t-dsa-b53-Drop-unused-cpu_port-field.patch | 205 - ...x-add-support-for-qca-8327-A-variant.patch | 65 - ...dd-resume-suspend-function-to-qca83x.patch | 45 - ...ix-spacing-and-improve-name-for-83xx.patch | 95 - ...hy-at803x-fix-resume-for-QCA8327-phy.patch | 131 - ...x-add-DAC-amplitude-fix-for-8327-phy.patch | 91 - ...nable-prefer-master-for-83xx-interna.patch | 27 - ...hy-at803x-better-describe-debug-regs.patch | 127 - ...-dsa-qca8k-add-mac-power-sel-support.patch | 80 - ...dsa-qca8k-Add-SGMII-clock-phase-prop.patch | 30 - ...k-add-support-for-sgmii-falling-edge.patch | 127 - ...dsa-qca8k-Document-support-for-CPU-p.patch | 29 - ...dsa-qca8k-add-support-for-cpu-port-6.patch | 153 - ...work-rgmii-delay-logic-and-scan-for-.patch | 295 - ...dsa-qca8k-Document-qca-sgmii-enable-.patch | 33 - ...-qca8k-add-explicit-SGMII-PLL-enable.patch | 65 - ...dsa-qca8k-Document-qca-led-open-drai.patch | 37 - ...qca8k-add-support-for-pws-config-reg.patch | 92 - ...dsa-qca8k-document-support-for-qca83.patch | 32 - ...et-dsa-qca8k-add-support-for-QCA8328.patch | 78 - ...8k-set-internal-delay-also-for-sgmii.patch | 159 - ...move-port-config-to-dedicated-struct.patch | 124 - ...ipq8064-mdio-fix-warning-with-new-qc.patch | 26 - ...net-dsa-qca8k-convert-to-YAML-schema.patch | 631 -- ...elay-applied-to-wrong-cpu-in-parse-p.patch | 28 - ...for-loop-in-setup-and-add-cpu-port-c.patch | 151 - ...sure-pad0-mac06-exchange-is-disabled.patch | 47 - ..._ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch | 78 - ..._eth_soc-remove-incorrect-PLL-config.patch | 141 - ..._eth_soc-remove-mac_pcs_get_state-an.patch | 81 - ..._eth_soc-add-version-in-mtk_soc_data.patch | 550 -- ...t-mtk_eth_soc-increase-MAX_DEVS-to-3.patch | 29 - ..._eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch | 186 - ..._eth_soc-add-NETSYS_V3-version-suppo.patch | 307 - ..._eth_soc-convert-caps-in-mtk_soc_dat.patch | 193 - ..._eth_soc-convert-clock-bitmap-to-u64.patch | 132 - ..._eth_soc-add-basic-support-for-MT798.patch | 477 -- ..._eth_soc-enable-page_pool-support-fo.patch | 27 - ..._eth_soc-enable-nft-hw-flowtable_off.patch | 135 - ..._eth_soc-support-per-flow-accounting.patch | 78 - ..._eth_soc-fix-NULL-pointer-on-hw-rese.patch | 52 - ..._eth_soc-fix-register-definitions-fo.patch | 44 - ...tk_eth_soc-add-reset-bits-for-MT7988.patch | 188 - ..._eth_soc-add-support-for-in-SoC-SRAM.patch | 254 - ..._eth_soc-support-36-bit-DMA-addressi.patch | 166 - ...k_eth_soc-fix-uninitialized-variable.patch | 44 - ..._eth_soc-fix-pse_port-configuration-.patch | 33 - ..._eth_soc-add-code-for-offloading-flo.patch | 271 - ...iatek-mtk_ppe-prefer-newly-added-l2-.patch | 37 - ..._eth_soc-improve-keeping-track-of-of.patch | 334 - ...iatek-fix-ppe-flow-accounting-for-L2.patch | 342 - ..._wed-add-some-more-info-in-wed_txinf.patch | 45 - ..._wed-minor-change-in-wed_-tx-rx-info.patch | 47 - ..._eth_soc-rely-on-mtk_pse_port-defini.patch | 29 - ..._wed-check-update_wo_rx_stats-in-mtk.patch | 26 - ..._wed-do-not-assume-offload-callbacks.patch | 68 - ..._wed-introduce-versioning-utility-ro.patch | 232 - ..._wed-do-not-configure-rx-offload-if-.patch | 234 - ..._wed-rename-mtk_rxbm_desc-in-mtk_wed.patch | 52 - ..._wed-introduce-mtk_wed_buf-structure.patch | 87 - ..._wed-move-mem_region-array-out-of-mt.patch | 88 - ...-mtk_wed-make-memory-region-optional.patch | 71 - ..._wed-fix-EXT_INT_STATUS_RX_FBUF-defi.patch | 27 - ...k_wed-add-mtk_wed_soc_data-structure.patch | 217 - ..._wed-introduce-WED-support-for-MT798.patch | 1280 --- ..._wed-refactor-mtk_wed_check_wfdma_rx.patch | 95 - ..._wed-introduce-partial-AMSDU-offload.patch | 465 - ..._wed-introduce-hw_rro-support-for-MT.patch | 483 -- ..._wed-debugfs-move-wed_v2-specific-re.patch | 78 - ..._wed-debugfs-add-WED-3.0-debugfs-ent.patch | 432 - ...et-mtk_wed-add-wed-3.0-reset-support.patch | 587 -- ...ernal-delay-applied-to-the-wrong-PAD.patch | 48 - ...16-net-dsa-qca8k-fix-MTU-calculation.patch | 46 - ...redundant-check-in-parse_port_config.patch | 29 - ...vert-to-GENMASK_FIELD_PREP_FIELD_GET.patch | 507 -- ...move-extra-mutex_init-in-qca8k_setup.patch | 25 - ...move-regmap-init-in-probe-and-set-it.patch | 46 - ...k-initial-conversion-to-regmap-heper.patch | 249 - ...ca8k-add-additional-MIB-counter-and-.patch | 120 - ...ca8k-add-support-for-port-fast-aging.patch | 53 - ...sa-qca8k-add-set_ageing_time-support.patch | 78 - ...sa-qca8k-add-support-for-mdb_add-del.patch | 142 - ...sa-qca8k-add-support-for-mirror-mode.patch | 155 - ...t-next-net-dsa-qca8k-add-LAG-support.patch | 288 - ...dsa-qca8k-fix-warning-in-LAG-feature.patch | 40 - ...PHY-initialization-with-MTU-setup-in.patch | 52 - ...nl_lock-sections-in-dsa_slave_create.patch | 34 - ...op-updating-master-MTU-from-master.c.patch | 91 - ...l_mutex-when-calling-dsa_master_-set.patch | 78 - ...t-up-shared-ports-then-non-shared-po.patch | 118 - ...xt-net-dsa-setup-master-before-ports.patch | 115 - ...switch-operations-for-tracking-the-m.patch | 254 - ...aster-state-events-in-dsa_tree_-setu.patch | 89 - ...t-dsa-tag_qca-convert-to-FIELD-macro.patch | 86 - ...qca-move-define-to-include-linux-dsa.patch | 71 - ...ag_qca-enable-promisc_on_master-flag.patch | 27 - ...add-define-for-handling-mgmt-Etherne.patch | 110 - ...a-add-define-for-handling-MIB-packet.patch | 45 - ...add-support-for-handling-mgmt-and-MI.patch | 116 - ...8k-add-tracking-state-of-master-port.patch | 67 - ...d-support-for-mgmt-read-write-in-Eth.patch | 363 - ...d-support-for-mib-autocast-in-Ethern.patch | 226 - ...d-support-for-phy-read-write-with-mg.patch | 287 - ...qca8k-move-page-cache-to-driver-priv.patch | 208 - ...qca8k-cache-lo-and-hi-for-mdio-write.patch | 164 - ...d-support-for-larger-read-write-size.patch | 206 - ...troduce-qca8k_bulk_read-write-functi.patch | 104 - ...eck-correct-variable-in-qca8k_phy_et.patch | 28 - ...dsa-qca8k-fix-noderef.cocci-warnings.patch | 34 - ...8k-drop-MTU-tracking-from-qca8k_priv.patch | 79 - ...-qca8k-drop-port_sts-from-qca8k_priv.patch | 116 - ...8k-rework-and-simplify-mdiobus-logic.patch | 173 - ...-drop-dsa_switch_ops-from-qca8k_priv.patch | 39 - ...a8k-correctly-handle-mdio-read-error.patch | 33 - ...ify-bus-id-naming-with-legacy-and-OF.patch | 44 - ...net-dsa-qca8k-move-driver-to-qca-dir.patch | 7389 ---------------- ...-cache-match-data-to-speed-up-access.patch | 157 - ...k-make-mib-autocast-feature-optional.patch | 77 - ...qca8k-move-mib-struct-to-common-code.patch | 6532 -------------- ...ve-qca8k-read-write-rmw-and-reg-tabl.patch | 135 - ...ve-qca8k-bulk-read-write-helper-to-c.patch | 145 - ...ove-mib-init-function-to-common-code.patch | 137 - ...ve-port-set-status-eee-ethtool-stats.patch | 281 - ...move-bridge-functions-to-common-code.patch | 237 - ...ve-set-age-MTU-port-enable-disable-f.patch | 227 - ...ve-port-FDB-MDB-function-to-common-c.patch | 704 -- ...ve-port-mirror-functions-to-common-c.patch | 232 - ...ve-port-VLAN-functions-to-common-cod.patch | 448 - ...ve-port-LAG-functions-to-common-code.patch | 384 - ...ve-read_switch_id-function-to-common.patch | 102 - ...x-NULL-pointer-dereference-for-of_de.patch | 29 - ...N-filtering-syncing-out-of-dsa_switc.patch | 77 - ...cross-chip-syncing-of-VLAN-filtering.patch | 52 - ...-rtl8366rb-Support-bridge-offloading.patch | 141 - ...-dsa-rtl8366-Drop-custom-VLAN-set-up.patch | 118 - ...b-Rewrite-weird-VLAN-filering-enable.patch | 270 - ...-Drop-and-depromote-pointless-prints.patch | 51 - ...tl8366rb-Use-core-filtering-tracking.patch | 61 - ...rtl8366rb-Support-disabling-learning.patch | 115 - ...net-dsa-rtl8366rb-Support-fast-aging.patch | 57 - ...-rtl8366rb-Support-setting-STP-state.patch | 107 - ...icro-stmmac-move-queue-reset-to-dedi.patch | 142 - ...icro-stmmac-first-disable-all-queues.patch | 37 - ...icro-stmmac-move-dma-conf-to-dedicat.patch | 1289 --- ...icro-stmmac-generate-stmmac-dma-conf.patch | 1161 --- ...icro-stmmac-permit-MTU-change-with-i.patch | 73 - ...x-inband-mgmt-for-big-endian-systems.patch | 156 - ...x-ethtool-autocast-mib-for-big-endia.patch | 81 - ...x-wrong-length-value-for-mgmt-eth-pa.patch | 102 - ...sa-tag_qca-fix-wrong-MGMT_DATA2-size.patch | 34 - ...qca8k-cache-lo-and-hi-for-mdio-write.patch | 172 - ...ntroduce-single-mii-read-write-lo-hi.patch | 150 - ...prove-mdio-master-read-write-by-usin.patch | 73 - ...-01-net-phy-at803x-add-fiber-support.patch | 193 - ...y-at803x-support-downstream-SFP-cage.patch | 95 - ...LL-pointer-dereference-on-AR9331-PHY.patch | 56 - ...ix-error-return-code-in-at803x_probe.patch | 31 - ...eric-Introduce-Sierra-EM919X-support.patch | 80 - ...ost-always-print-detected-modem-name.patch | 37 - ...-add-support-for-in-band-link-status.patch | 130 - ...e-implement-soft-state-polling-setup.patch | 98 - ...t-sfp-move-quirk-handling-into-sfp.c.patch | 291 - ...move-Alcatel-Lucent-3FE46541AA-fixup.patch | 69 - ....1-net-sfp-move-Huawei-MA5671A-fixup.patch | 48 - ...t-sfp-add-support-for-HALNy-GPON-SFP.patch | 79 - ...t-dsa-mt7530-use-external-PCS-driver.patch | 514 -- ...k-enabling-2500Base-x-for-HG-MXPD-48.patch | 37 - ....0-net-mii-add-mii_bmcr_encode_fixed.patch | 55 - ...ake-some-noise-if-register-read-fail.patch | 32 - ...a-mt7530-refactor-SGMII-PCS-creation.patch | 111 - ...mt7530-use-unlocked-regmap-accessors.patch | 74 - ...se-regmap-to-access-switch-register-.patch | 224 - ...ove-SGMII-PCS-creation-to-mt7530_pro.patch | 54 - ...t-dsa-mt7530-introduce-mutex-helpers.patch | 273 - ...ove-p5_intf_modes-function-to-mt7530.patch | 75 - ...ntroduce-mt7530_probe_common-helper-.patch | 155 - ...ntroduce-mt7530_remove_common-helper.patch | 55 - ...t7530-introduce-separate-MDIO-driver.patch | 692 -- ...kip-locking-if-MDIO-bus-isn-t-presen.patch | 47 - ...ntroduce-driver-for-MT7988-built-in-.patch | 421 - ...-dsa-mt7530-fix-support-for-MT7531BE.patch | 118 - ...or-Motorcomm-yt8521-gigabit-ethernet.patch | 1724 ---- ...fix-yt8521-duplicated-argument-to-or.patch | 49 - ...net-phy-add-Motorcomm-YT8531S-phy-id.patch | 140 - ...fix-the-spelling-problem-of-Sentinel.patch | 26 - ...nge-the-phy-id-of-yt8521-and-yt8531s.patch | 29 - ...-for-Motorcomm-yt8521-yt8531-gigabit.patch | 107 - ...support-for-Motorcomm-yt8521-gigabit.patch | 343 - ...upport-for-Motorcomm-yt8531s-gigabit.patch | 100 - ...or-Motorcomm-yt8531-gigabit-ethernet.patch | 302 - ...motorcomm-uninitialized-variables-in.patch | 34 - ...m-Add-pad-drive-strength-cfg-support.patch | 170 - ...ble-PCS-polling-over-major-configura.patch | 81 - ...NULL-pl-pcs-dereference-during-phyli.patch | 38 - ...k-add-pcs_enable-pcs_disable-methods.patch | 172 - ...t-pcs-lynxi-implement-pcs_disable-op.patch | 44 - ...ive-renaming-when-an-interface-is-up.patch | 136 - ...-need-to-blacklist-any-r8152-devices.patch | 158 - ...-control-transfer-of-rtl8152_get_ver.patch | 46 - ...-Add-__GFP_NOWARN-to-big-allocations.patch | 55 - ...52-adjust-generic_ocp_write-function.patch | 70 - .../795-v6.6-09-r8152-set-bp-in-bulk.patch | 129 - ...re-register-access-if-register-acces.patch | 398 - ...he-loop-when-the-budget-is-exhausted.patch | 83 - ..._ether-add-u-blox-0x1313-composition.patch | 47 - ...ix-risk-of-NULL-pointer-deallocation.patch | 30 - ...ansmit-URBs-without-trailing-padding.patch | 35 - ...03-usbnet-ipheth-add-CDC-NCM-support.patch | 326 - ...et-ipheth-update-Kconfig-description.patch | 36 - ...net-usb-ax88179_178a-add-TSO-feature.patch | 68 - ...uirk-for-Fiberstone-GPON-ONU-34-20BI.patch | 34 - ...s-add-Broadcom-s-BCM63138-controller.patch | 125 - ...-add-support-for-BCM63138-controller.patch | 356 - ...-leds-bcm63138-unify-full-stops-in-d.patch | 30 - ...help-info-about-BCM63138-module-name.patch | 28 - ...eds-leds-bcm63138-get-rid-of-LED_OFF.patch | 30 - ...-rework-nvmem-cell-instance-creation.patch | 456 - ...-nvmem-cell-post-processing-callback.patch | 82 - ...cotp-add-support-for-post-processing.patch | 92 - ...support-minimum-one-byte-access-stri.patch | 47 - ...-Remove-unused-devm_nvmem_unregister.patch | 72 - ...em-core-Use-devm_add_action_or_reset.patch | 58 - ...-input-parameter-for-NULL-in-nvmem_u.patch | 30 - ...4-nvmem-qfprom-fix-kerneldoc-warning.patch | 29 - ...sunxi_sid-Add-support-for-D1-variant.patch | 38 - ...fuse-replace-unnecessary-devm_kstrdu.patch | 28 - ...-for-Layerscape-SFP-Security-Fuse-Pr.patch | 139 - ...rease-fuse-blow-timeout-to-prevent-w.patch | 32 - ...d-driver-for-OCOTP-in-Sunplus-SP7021.patch | 291 - ...-parse-NVRAM-content-into-NVMEM-cell.patch | 146 - ...mark-ACPI-device-ID-table-as-maybe-u.patch | 32 - ...em-sunplus-ocotp-staticize-sp_otp_v0.patch | 30 - ...cotp-drop-useless-probe-confirmation.patch | 27 - ...support-passing-DT-node-in-cell-info.patch | 41 - ...-find-Device-Tree-nodes-for-NVMEM-ce.patch | 38 - ...19-0006-nvmem-Add-Apple-eFuse-driver.patch | 130 - ...ng-pm_runtime_resume_and_get-instead.patch | 31 - .../805-v5.19-0008-nvmem-sfp-Use-regmap.patch | 109 - ...m-sfp-Add-support-for-TA-2.1-devices.patch | 38 - ...001-nvmem-microchip-otpc-add-support.patch | 389 - ...Simplify-with-devm_platform_get_and_.patch | 32 - ...-handling-U-Boot-environment-variabl.patch | 286 - ...-Use-kzalloc-for-allocating-only-one.patch | 29 - ...nvmem-prefix-all-symbols-with-NVMEM_.patch | 281 - ...m-sort-config-symbols-alphabetically.patch | 535 -- ...-find-Device-Tree-nodes-for-NVMEM-ce.patch | 31 - ...1-0008-nvmem-lan9662-otp-add-support.patch | 274 - ...em-u-boot-env-fix-crc32-casting-type.patch | 32 - ...em-lan9662-otp-Fix-compatible-string.patch | 34 - ...-fix-crc32_data_offset-on-redundant-.patch | 59 - ...p-Change-return-type-of-lan9662_otp_.patch | 35 - ...e-STM32MP15_BSEC_NUM_LOWER-in-config.patch | 82 - ...-warning-when-upper-OTPs-are-updated.patch | 34 - ...nvmem-stm32-add-nvmem-type-attribute.patch | 26 - ...m-stm32-fix-spelling-typo-in-comment.patch | 27 - ...x-spelling-mistake-controlls-control.patch | 27 - ...boot-env-add-Broadcom-format-support.patch | 67 - ...mem-brcm_nvram-Add-check-for-kzalloc.patch | 30 - ...nxi_sid-Always-use-32-bit-MMIO-reads.patch | 55 - ...mem-core-fix-device-node-refcounting.patch | 48 - ...mem-core-remove-spurious-white-space.patch | 26 - ...e-add-an-index-parameter-to-the-cell.patch | 180 - ...struct-nvmem_cell_info-to-nvmem-prov.patch | 78 - ...the-removal-of-the-cells-in-nvmem_ad.patch | 65 - ...05-nvmem-core-add-nvmem_add_one_cell.patch | 122 - ...vmem_add_one_cell-in-nvmem_add_cells.patch | 93 - ...32-add-OP-TEE-support-for-STM32MP13x.patch | 562 -- ...ect-bsec-pta-presence-for-STM32MP15x.patch | 85 - ...eprm-fix-kernel-doc-bad-line-warning.patch | 32 - ...mi-sdam-register-at-device-init-time.patch | 43 - ...011-nvmem-stm32-fix-OPTEE-dependency.patch | 46 - ..._wwan-add-ZTE-MF286D-modem-19d2-1485.patch | 59 - ...001-nvmem-xilinx-zynqmp-make-modular.patch | 35 - ...2-nvmem-core-introduce-NVMEM-layouts.patch | 387 - ...ndle-the-absence-of-expected-layouts.patch | 61 - ...-core-request-layout-modules-loading.patch | 52 - ...em-core-add-per-cell-post-processing.patch | 86 - ...ow-to-modify-a-cell-before-adding-it.patch | 59 - ...replace-global-post-processing-with-.patch | 81 - ...m-cell-drop-global-cell_post_process.patch | 68 - ...de-own-priv-pointer-in-post-process-.patch | 76 - ...ayouts-sl28vpd-Add-new-layout-driver.patch | 215 - ...youts-onie-tlv-Add-new-layout-driver.patch | 306 - ...m-mark-OF-related-data-as-maybe-unus.patch | 32 - ...Support-postprocessing-for-GPU-speed.patch | 120 - ...p-Use-devm_platform_ioremap_resource.patch | 39 - ...tp-Use-devm_platform_ioremap_resourc.patch | 39 - ...p-Use-devm_platform_get_and_ioremap_.patch | 32 - ...rt-specifying-both-cell-raw-data-pos.patch | 115 - ...nv-post-process-ethaddr-env-variable.patch | 81 - ...cro-to-register-nvmem-layout-drivers.patch | 42 - ...28vpd-Use-module_nvmem_layout_driver.patch | 39 - ...ie-tlv-Use-module_nvmem_layout_drive.patch | 39 - ...uts-onie-tlv-Drop-wrong-module-alias.patch | 24 - ...28vpd-set-varaiable-sl28vpd_layout-s.patch | 31 - ...-bcm47xx-support-init-from-IO-memory.patch | 100 - ...set-varaiable-imx_ocotp_layout-stora.patch | 31 - ...Reverse-MAC-addresses-on-all-i.MX-de.patch | 71 - ...vram-add-.read_post_process-for-MACs.patch | 81 - ...tp-Add-clks-and-reg_read-to-rockchip.patch | 166 - ...tp-Generalize-rockchip_otp_wait_stat.patch | 62 - ...tp-Use-devm_reset_control_array_get_.patch | 31 - ...hip-otp-Improve-probe-error-handling.patch | 71 - ...-rockchip-otp-Add-support-for-RK3588.patch | 129 - ...-Switch-xilinx.com-emails-to-amd.com.patch | 26 - ...-0010-nvmem-imx-support-i.MX93-OCOTP.patch | 230 - ...e-add-support-for-fixed-cells-layout.patch | 96 - ...it_default_state_get-to-the-global-h.patch | 39 - ...a8k-move-qca8k_port_to_phy-to-header.patch | 67 - ...net-dsa-qca8k-add-LEDs-basic-support.patch | 435 - ...dsa-qca8k-add-LEDs-blink_set-support.patch | 74 - ...bs-for-when-CLASS_LED-NEW_LEDS-are-d.patch | 59 - ...5-net-phy-Add-a-binding-for-PHY-LEDs.patch | 191 - ...ce-Call-into-the-PHY-driver-to-set-L.patch | 97 - ...ell-Add-software-control-of-the-LEDs.patch | 112 - ...ce-Call-into-the-PHY-driver-to-set-L.patch | 73 - ...-phy-marvell-Implement-led_blink_set.patch | 104 - ...Fix-inconsistent-indenting-in-led_bl.patch | 38 - ...dev-Drop-NETDEV_LED_MODE_LINKUP-from.patch | 87 - ...dev-Rename-add-namespace-to-netdev-t.patch | 149 - ...-netdev-Convert-device-attr-to-macro.patch | 82 - ...etdev-Use-mutex-instead-of-spinlocks.patch | 106 - ...01-leds-add-APIs-for-LEDs-hw-control.patch | 74 - ...get-attached-device-for-LED-hw-contr.patch | 37 - ...ds-leds-class-Document-new-Hardware-.patch | 113 - ...dev-refactor-code-setting-device-nam.patch | 69 - ...dev-introduce-check-for-possible-hw-.patch | 54 - ...dev-add-basic-check-for-hw-control-s.patch | 42 - ...dev-reject-interval-store-for-hw_con.patch | 28 - ...etdev-add-support-for-LED-hw-control.patch | 107 - ...er-netdev-validate-configured-netdev.patch | 58 - ...dev-init-mode-if-hw-control-already-.patch | 53 - ...dev-expose-netdev-trigger-modes-in-l.patch | 54 - ...t-dsa-qca8k-implement-hw_control-ops.patch | 200 - ...dsa-qca8k-add-op-to-get-ports-netdev.patch | 70 - ...Convert-to-devm_platform_ioremap_res.patch | 36 - ...-Use-devm_platform_get_and_ioremap_r.patch | 30 - ...p-Convert-to-devm_platform_ioremap_r.patch | 34 - ...fuse-Convert-to-devm_platform_iorema.patch | 36 - ...fuse-Use-devm_platform_get_and_iorem.patch | 31 - ...m-Use-devm_platform_get_and_ioremap_.patch | 30 - ....6-0007-nvmem-qfprom-do-some-cleanup.patch | 59 - ...se-devm_platform_get_and_ioremap_res.patch | 29 - ...nvmem-add-new-NXP-QorIQ-eFuse-driver.patch | 133 - ...-nvmem-Kconfig-Fix-typo-drive-driver.patch | 37 - ...m-Add-Qualcomm-secure-QFPROM-support.patch | 152 - ...-Replace-zero-length-array-with-DECL.patch | 30 - ...e-all-cells-before-adding-the-nvmem-.patch | 40 - ...n-NULL-when-no-nvmem-layout-is-found.patch | 35 - ...-Do-not-open-code-existing-functions.patch | 29 - ...tify-when-a-new-layout-is-registered.patch | 44 - ...mem-qfprom-Mark-core-clk-as-optional.patch | 37 - ...it-config-option-to-read-old-syntax-.patch | 330 - ...0003-nvmem-Use-device_get_match_data.patch | 77 - ...4-Revert-nvmem-add-new-config-option.patch | 77 - ...ect-fixed-layouts-to-grab-a-layout-d.patch | 45 - ..._nvram-store-a-copy-of-NVRAM-content.patch | 261 - ...Support-public-address-configuration.patch | 51 - ...Fix-application-of-sizeof-to-pointer.patch | 29 - ...Add-a-new-PID-VID-13d3-3567-for-MT79.patch | 70 - ...Add-a-new-PID-VID-0489-e0c8-for-MT79.patch | 68 - ...Add-a-new-VID-PID-0e8d-0608-for-MT79.patch | 66 - ...ll-of_parse_phandle-variants-static-.patch | 359 - ...-of_parse_phandle_with_optional_args.patch | 58 - ...ke-.-cells-optional-for-simple-props.patch | 34 - ...operty-add-nvmem-cell-cells-property.patch | 30 - ...vice-Ignore-modalias-of-reused-nodes.patch | 37 - ...-ignore-error-code-in-of_device_ueve.patch | 29 - ...002-of-Update-of_device_get_modalias.patch | 103 - ...v6.4-0003-of-Rename-of_modalias_node.patch | 173 - ...0004-of-Move-of_modalias-to-module.c.patch | 160 - ...uest-module-helper-logic-to-module.c.patch | 131 - ...ount-to-list.h-as-list_count_nodes-f.patch | 75 - ...rris-omnia-convert-to-use-dev_groups.patch | 45 - ...ia-Use-sysfs_emit-instead-of-sprintf.patch | 31 - ...a-Make-set_brightness-more-efficient.patch | 207 - ...a-Support-HW-controlled-mode-via-pri.patch | 201 - ...a-Add-support-for-enabling-disabling.patch | 244 - ...a-Fix-brightness-setting-and-trigger.patch | 167 - ...leds-Expand-LED_COLOR_ID-definitions.patch | 47 - ...-device-Export-of_device_make_bus_id.patch | 128 - ...ors-from-DT-bindings-to-led_co.patch.patch | 29 - ...mem_layout_get_container-in-another-.patch | 95 - ...Create-a-header-for-internal-sharing.patch | 91 - ...03-nvmem-Simplify-the-add_cells-hook.patch | 79 - ...vmem-Move-and-rename-fixup_cell_info.patch | 169 - ...rk-layouts-to-become-regular-devices.patch | 763 -- ...vmem-core-Expose-cells-through-sysfs.patch | 240 - ...support-for-STM32MP25-BSEC-to-contro.patch | 65 - ...factor-.add_cells-callback-arguments.patch | 94 - ...mem-drop-nvmem_layout_get_match_data.patch | 72 - ...nvmem-core-add-nvmem_dev_size-helper.patch | 53 - ...-use-nvmem_add_one_cell-nvmem-subsys.patch | 126 - ...-u-boot-env-use-nvmem-device-helpers.patch | 81 - ...vmem-u-boot-env-improve-coding-style.patch | 62 - ...-Add-FUNCTION-defines-for-per-band-W.patch | 34 - ...-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch | 35 - ...Register-MediaTek-socinfo-driver-fro.patch | 69 - ...qmp_nvmem-zynqmp_nvmem_probe-cleanup.patch | 97 - ...mp_nvmem-Add-support-to-access-efuse.patch | 243 - ...mem-mtk-efuse-Drop-NVMEM-device-name.patch | 35 - ...rint-error-on-wrong-bits-DT-property.patch | 32 - ...ore-owner-from-modules-with-nvmem_la.patch | 61 - ...ie-tlv-drop-driver-owner-initializat.patch | 28 - ...28vpd-drop-driver-owner-initializati.patch | 28 - ...-nvmem-sc27xx-fix-module-autoloading.patch | 26 - ...05-nvmem-sprd-fix-module-autoloading.patch | 26 - ...core-switch-to-use-device_add_groups.patch | 32 - ...prom-Convert-to-platform-remove-call.patch | 57 - ...fuse-Remove-nvmem_device-from-efuse-.patch | 50 - ...m-rmem-Fix-return-value-of-rmem_read.patch | 42 - ...e-Fix-return-value-of-nvmem-callback.patch | 59 - ...change-name-to-fram-for-current-attr.patch | 39 - ...-cell-sysfs-permissions-to-main-attr.patch | 37 - ...dd-missing-MODULE_DESCRIPTION-macros.patch | 48 - ...e-Replacing-the-use-of-of_node_put-t.patch | 48 - ...tp-set-add_legacy_fixed_of_cells-con.patch | 28 - ...4-nvmem-rockchip-otp-Set-type-to-OTP.patch | 25 - ...nvmem-rockchip-efuse-set-type-to-OTP.patch | 26 - ...06-nvmem-core-add-single-sysfs-group.patch | 42 - ...core-remove-global-nvmem_cells_group.patch | 83 - ...unnecessary-range-checks-in-sysfs-ca.patch | 61 - ...em-Use-sysfs_emit-for-type-attribute.patch | 30 - ...e-Implement-force_ro-sysfs-attribute.patch | 122 - ...v-error-if-NVMEM-device-is-too-small.patch | 40 - ...-type-of-devm_nvmem_device_get-in-ke.patch | 37 - ...1-nvmem-imx-ocotp-ele-support-i.MX95.patch | 73 - ...otp-Use-devm_platform_ioremap_resour.patch | 44 - ...-nvmem-layouts-add-U-Boot-env-layout.patch | 515 -- ...PS-ath79-drop-_machine_restart-again.patch | 49 - ....18-hwmon-lm70-Add-ti-tmp125-support.patch | 71 - ...ether-export-usbnet_cdc_zte_rx_fixup.patch | 58 - ...e-the-bogus-MAC-fixup-for-ZTE-device.patch | 118 - ...-scope-of-bogus-MAC-address-detectio.patch | 63 - ...-spinand-winbond-fix-flash-detection.patch | 40 - ...6.2-mtd-spinand-winbond-add-W25N02KV.patch | 106 - ...d-spinand-winbond-Fix-ecc_get_status.patch | 49 - ...x-pass-directly-chip-structure-to-mv.patch | 46 - ...x-use-mv88e6xxx_phy_is_internal-in-m.patch | 31 - ...x-add-field-to-specify-internal-phys.patch | 69 - ...x-fix-88E6393X-family-internal-phys-.patch | 52 - ...x-pass-mv88e6xxx_chip-structure-to-p.patch | 113 - ...xx-enable-support-for-88E6361-switch.patch | 165 - ...8-net-ethtool-implement-ethtool_puts.patch | 139 - target/linux/generic/config-5.15 | 7622 ----------------- .../generic/hack-5.15/204-module_strip.patch | 212 - ...-abort-configuration-on-unset-symbol.patch | 41 - .../210-darwin_scripts_include.patch | 3053 ------- .../211-darwin-uuid-typedef-clash.patch | 22 - .../hack-5.15/212-tools_portability.patch | 110 - .../hack-5.15/214-spidev_h_portability.patch | 24 - .../hack-5.15/220-arm-gc_sections.patch | 123 - .../hack-5.15/221-module_exports.patch | 126 - .../hack-5.15/230-openwrt_lzma_options.patch | 34 - .../hack-5.15/250-netfilter_depends.patch | 27 - .../linux/generic/hack-5.15/251-kconfig.patch | 157 - .../generic/hack-5.15/253-ksmbd-config.patch | 32 - .../hack-5.15/259-regmap_dynamic.patch | 144 - .../260-crypto_test_dependencies.patch | 52 - .../hack-5.15/261-lib-arc4-unhide.patch | 24 - .../generic/hack-5.15/280-rfkill-stubs.patch | 84 - ...cache-use-more-efficient-cache-blast.patch | 64 - ...rans-call-add-disks-after-mtd-device.patch | 98 - ...upport-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch | 24 - ...ers-add-nvmem-support-to-cmdlinepart.patch | 120 - .../hack-5.15/430-mtk-bmt-support.patch | 33 - ...lter-connmark-introduce-set-dscpmark.patch | 214 - ...-netfilter-add-xt_FLOWOFFLOAD-target.patch | 865 -- .../hack-5.15/651-wireless_mesh_header.patch | 24 - .../hack-5.15/660-fq_codel_defaults.patch | 27 - ...t-size-the-hashtable-more-adequately.patch | 25 - .../700-swconfig_switch_drivers.patch | 131 - ...-dsa-mv88e6xxx-disable-ATU-violation.patch | 21 - .../721-net-add-packet-mangeling.patch | 178 - ...hy-aquantia-enable-AQR112-and-AQR412.patch | 148 - ...aquantia-fix-system-side-protocol-mi.patch | 34 - ...ntia-add-PHY_IDs-for-AQR112-variants.patch | 63 - ...mtk-lynxi-workaround-2500BaseX-no-an.patch | 53 - ...-r8152-add-LED-configuration-from-OF.patch | 74 - ...et-add-RTL8152-binding-documentation.patch | 54 - .../765-mxl-gpy-control-LED-reg-from-DT.patch | 105 - ...k-ge-add-LED-configuration-interface.patch | 72 - .../hack-5.15/773-bgmac-add-srab-switch.patch | 98 - .../780-usb-net-MeigLink_modem_support.patch | 69 - .../781-usb-net-rndis-support-asr.patch | 69 - .../790-SFP-GE-T-ignore-TX_FAULT.patch | 65 - .../795-backport-phylink_pcs-helpers.patch | 167 - .../800-GPIO-add-named-gpio-exports.patch | 190 - .../810-bcma-ssb-fallback-sprom.patch | 187 - .../hack-5.15/901-debloat_sock_diag.patch | 172 - .../generic/hack-5.15/902-debloat_proc.patch | 408 - .../hack-5.15/904-debloat_dma_buf.patch | 92 - .../hack-5.15/910-kobject_uevent.patch | 32 - .../911-kobject_add_broadcast_uevent.patch | 76 - .../hack-5.15/920-device_tree_cmdline.patch | 21 - ...vert-driver-core-Set-fw_devlink-on-b.patch | 30 - ...include-asm-rwonce.h-for-kernel-code.patch | 29 - ...s-negative-stack-offsets-on-stack-tr.patch | 57 - .../103-kbuild-export-SUBARCH.patch | 21 - ..._wdt-Add-support-for-specifying-WDI-.patch | 75 - ...e_mem_map-with-ARCH_PFN_OFFSET-calcu.patch | 82 - ...ame2-and-add-RENAME_WHITEOUT-support.patch | 81 - ...41-jffs2-add-RENAME_EXCHANGE-support.patch | 73 - .../142-jffs2-add-splice-ops.patch | 20 - ...ge_allow_receiption_on_disabled_port.patch | 45 - ...t-send-arp-replies-if-src-and-target.patch | 37 - ...-rs5c372-support_alarms_up_to_1_week.patch | 94 - ...he_alarm_to_be_used_as_wakeup_source.patch | 70 - .../203-kallsyms_uncompressed.patch | 119 - .../205-backtrace_module_info.patch | 41 - ...e-filenames-from-deps_initramfs-list.patch | 30 - ...able_wilink_platform_without_drivers.patch | 20 - .../270-platform-mikrotik-build-bits.patch | 31 - .../300-mips_expose_boot_raw.patch | 40 - ...rriers-between-dcache-icache-flushes.patch | 71 - .../302-mips_no_branch_likely.patch | 22 - .../pending-5.15/305-mips_module_reloc.patch | 370 - .../pending-5.15/308-mips32r2_tune.patch | 22 - .../310-arm_module_unresolved_weak_sym.patch | 22 - ...t-command-line-parameters-from-users.patch | 282 - .../332-arc-add-OWRTDTB-section.patch | 84 - ...able-unaligned-access-in-kernel-mode.patch | 24 - ...ernel-XZ-compression-option-on-PPC_8.patch | 25 - ...ip-bcm-6345-l1-request-memory-region.patch | 113 - .../400-mtd-mtdsplit-support.patch | 328 - ...er-NVMEM-devices-for-partitions-with.patch | 48 - ...support-for-minor-aligned-partitions.patch | 245 - ...or-Add-support-for-BoHong-bh25q128as.patch | 75 - .../pending-5.15/420-mtd-redboot_space.patch | 41 - ...30-mtd-add-myloader-partition-parser.patch | 229 - ...check-for-bad-blocks-when-calculatin.patch | 68 - ...bcm47xxpart-detect-T_Meter-partition.patch | 37 - ...mtd-add-routerbootpart-parser-config.patch | 38 - ...mtd-cfi_cmdset_0002-no-erase_suspend.patch | 25 - ...et_0002-add-buffer-write-cmd-timeout.patch | 17 - ...25p80-mx-disable-software-protection.patch | 18 - .../476-mtd-spi-nor-add-eon-en25q128.patch | 18 - .../477-mtd-spi-nor-add-eon-en25qx128a.patch | 21 - .../479-mtd-spi-nor-add-xtx-xt25f128b.patch | 79 - ...r-add-support-for-Gigadevice-GD25D05.patch | 22 - .../482-mtd-spi-nor-add-gd25q512.patch | 21 - .../484-mtd-spi-nor-add-esmt-f25l16pa.patch | 23 - .../485-mtd-spi-nor-add-xmc-xm25qh128c.patch | 24 - ...nand-add-support-for-ESMT-F50x1G41LB.patch | 143 - ...nd-Add-support-for-Etron-EM73D044VCx.patch | 168 - .../488-mtd-spi-nor-add-xmc-xm25qh64c.patch | 22 - ...mtd-device-named-ubi-or-data-on-boot.patch | 97 - ...to-create-ubiblock-device-for-rootfs.patch | 69 - ...ting-ubi0-rootfs-in-init-do_mounts.c.patch | 53 - ...ROOT_DEV-to-ubiblock-rootfs-if-unset.patch | 34 - .../494-mtd-ubi-add-EOF-marker-support.patch | 60 - ...-add-bindings-for-mtd-concat-devices.patch | 52 - ...cat-add-dt-driver-for-concat-devices.patch | 216 - ...i-nor-locking-support-for-MX25L6405D.patch | 34 - ...i-nor-disable-16-bit-sr-for-macronix.patch | 30 - .../500-fs_cdrom_dependencies.patch | 52 - .../530-jffs2_make_lzma_available.patch | 4581 ---------- .../pending-5.15/532-jffs2_eofdetect.patch | 65 - .../600-netfilter_conntrack_flush.patch | 88 - ...etfilter_match_bypass_default_checks.patch | 110 - ...netfilter_match_bypass_default_table.patch | 106 - ...netfilter_match_reduce_memory_access.patch | 22 - ...del-do-not-defer-queue-length-update.patch | 86 - .../pending-5.15/630-packet_socket_type.patch | 138 - .../pending-5.15/655-increase_skb_pad.patch | 20 - ...Add-support-for-MAP-E-FMRs-mesh-mode.patch | 511 -- ...ng-with-source-address-failed-policy.patch | 263 - ...nes-for-_POLICY_FAILED-until-all-cod.patch | 50 - ...T-skip-GRO-for-foreign-MAC-addresses.patch | 149 - ...83-of_net-add-mac-address-to-of-tree.patch | 75 - ...ow_offload-handle-netdevice-events-f.patch | 110 - ...les-ignore-EOPNOTSUPP-on-flowtable-d.patch | 29 - ...net-mtk_eth_soc-enable-threaded-NAPI.patch | 41 - ...detach-callback-to-struct-phy_driver.patch | 38 - ...transmit-path-dma-unmapping-on-error.patch | 111 - ...rk-mapped-and-tso-buffers-separately.patch | 42 - ...uf-type-to-determine-whether-to-dma-.patch | 59 - ...tso_build_hdr-into-mvneta_tso_put_hd.patch | 65 - ...cate-TSO-header-DMA-memory-in-chunks.patch | 179 - ...a-tag_mtk-add-padding-for-tx-packets.patch | 28 - ...d-knob-for-filtering-rx-tx-BPDU-pack.patch | 174 - ...rtl8221-allow-to-configure-SERDES-mo.patch | 106 - ...support-switching-between-SGMII-and-.patch | 61 - ...e-all-MACs-are-powered-down-before-r.patch | 28 - ...-use-genphy_soft_reset-for-2.5G-PHYs.patch | 65 - ...sable-SGMII-in-band-AN-for-2-5G-PHYs.patch | 43 - ...make-sure-paged-read-is-protected-by.patch | 35 - ...use-inline-functions-for-10GbE-adver.patch | 60 - ...check-validity-of-10GbE-link-partner.patch | 28 - ...-phy-realtek-introduce-rtl822x_probe.patch | 84 - ...tek-detect-early-version-of-RTL8221B.patch | 71 - ...ealtek-support-interrupt-of-RTL8221B.patch | 75 - ..._eth_soc-compile-out-netsys-v2-code-.patch | 44 - ..._eth_soc-work-around-issue-with-send.patch | 94 - ...rnet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch | 21 - ..._eth_soc-fix-remaining-throughput-re.patch | 42 - ..._eth_soc-ppe-fix-L2-offloading-with-.patch | 33 - ..._eth_soc-add-paths-and-SerDes-modes-.patch | 1605 ---- ..._eth_soc-set-coherent-mask-to-get-PP.patch | 46 - ...et-phy-motorcomm-Add-missing-include.patch | 22 - ...pool-and-page-referenced-frags-in-GR.patch | 35 - ...ional-threading-for-backlog-processi.patch | 232 - ...equest-assisted-learning-on-CPU-port.patch | 27 - ...a-b53-add-support-for-BCM63xx-RGMIIs.patch | 174 - ...-net-dsa-b53-mmap-add-more-63xx-SoCs.patch | 108 - ...dsa-b53-mmap-allow-passing-a-chip-ID.patch | 195 - ...b53-add-BCM63268-RGMII-configuration.patch | 123 - ...sa-b53-mdio-add-support-for-BCM53134.patch | 189 - ...-t-learn-non-unicast-L2-destinations.patch | 30 - ...-missing-linux-if_ether.h-for-ETH_AL.patch | 61 - ...-bus-mhi-core-add-SBL-state-callback.patch | 48 - ...gister-OF-node-for-internal-MDIO-bus.patch | 43 - ...-fix-10M-100M-speed-on-MT7988-switch.patch | 45 - ...ice-struct-copy-its-DMA-params-to-th.patch | 73 - ...pio-cascade-add-generic-GPIO-cascade.patch | 222 - ...env-align-endianness-of-crc32-values.patch | 45 - ...-support-mac-base-fixed-layout-cells.patch | 124 - .../810-pci_disable_common_quirks.patch | 62 - .../811-pci_disable_usb_common_quirks.patch | 115 - ...problem-with-platfom-data-in-w1-gpio.patch | 26 - .../pending-5.15/834-ledtrig-libata.patch | 149 - ...40-hwrng-bcm2835-set-quality-to-1000.patch | 26 - ...e-main-irq_chip-structure-a-static-d.patch | 102 - ...add-BCM63268-timer-clock-definitions.patch | 114 - ...add-BCM63268-timer-reset-definitions.patch | 107 - ...CM63268-timer-clock-and-reset-driver.patch | 345 - ...rack-busclk-state-to-avoid-bus-error.patch | 61 - ...-nxp-imx7d-pico-add-cpu-supply-nodes.patch | 43 - ...-add-LED_FUNCTION_MOBILE-for-mobile-.patch | 37 - ...-add-LED_FUNCTION_SPEED_-for-link-sp.patch | 37 - .../pending-5.15/920-mangle_bootargs.patch | 71 - ...on-Fix-compilation-warning-for-wrong.patch | 51 - 941 files changed, 159791 deletions(-) delete mode 100644 include/kernel-5.15 delete mode 100644 target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch delete mode 100644 target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch delete mode 100644 target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-01-mm-x86-arm64-add-arch_has_hw_pte_young.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-03-mm-vmscan.c-refactor-shrink_node.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-04-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-06-mm-multi-gen-LRU-minimal-implementation.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-07-mm-multi-gen-LRU-exploit-locality-in-rmap.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-08-mm-multi-gen-LRU-support-page-table-walks.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-09-mm-multi-gen-LRU-optimize-multiple-memcgs.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-10-mm-multi-gen-LRU-kill-switch.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-11-mm-multi-gen-LRU-thrashing-prevention.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-12-mm-multi-gen-LRU-debugfs-interface.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-13-mm-mglru-don-t-sync-disk-for-each-aging-cycle.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-14-mm-multi-gen-LRU-retry-pages-written-back-while-isol.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-15-mm-multi-gen-LRU-move-lru_gen_add_mm-out-of-IRQ-off-.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-17-mm-add-dummy-pmd_young-for-architectures-not-having-.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.1-18-mm-introduce-arch_has_hw_nonleaf_pmd_young.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.2-16-mm-multi-gen-LRU-fix-crash-during-cgroup-migration.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-19-mm-add-vma_has_recency.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-20-mm-support-POSIX_FADV_NOREUSE.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-21-mm-multi-gen-LRU-rename-lru_gen_struct-to-lru_gen_pa.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-22-mm-multi-gen-LRU-rename-lrugen-lists-to-lrugen-pages.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-23-mm-multi-gen-LRU-remove-eviction-fairness-safeguard.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-24-mm-multi-gen-LRU-remove-aging-fairness-safeguard.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-25-mm-multi-gen-LRU-shuffle-should_run_aging.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-26-mm-multi-gen-LRU-per-node-lru_gen_page-lists.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-27-mm-multi-gen-LRU-clarify-scan_control-flags.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-28-mm-multi-gen-LRU-simplify-arch_has_hw_pte_young-chec.patch delete mode 100644 target/linux/generic/backport-5.15/020-v6.3-29-mm-multi-gen-LRU-avoid-futile-retries.patch delete mode 100644 target/linux/generic/backport-5.15/021-v6.4-mm-Multi-gen-LRU-remove-wait_event_killable.patch delete mode 100644 target/linux/generic/backport-5.15/050-v5.16-00-MIPS-uasm-Enable-muhu-opcode-for-MIPS-R6.patch delete mode 100644 target/linux/generic/backport-5.15/050-v5.16-01-mips-uasm-Add-workaround-for-Loongson-2F-nop-CPU-err.patch delete mode 100644 target/linux/generic/backport-5.15/050-v5.16-02-mips-bpf-Add-eBPF-JIT-for-32-bit-MIPS.patch delete mode 100644 target/linux/generic/backport-5.15/050-v5.16-03-mips-bpf-Add-new-eBPF-JIT-for-64-bit-MIPS.patch delete mode 100644 target/linux/generic/backport-5.15/050-v5.16-04-mips-bpf-Add-JIT-workarounds-for-CPU-errata.patch delete mode 100644 target/linux/generic/backport-5.15/050-v5.16-05-mips-bpf-Enable-eBPF-JITs.patch delete mode 100644 target/linux/generic/backport-5.15/050-v5.16-06-mips-bpf-Remove-old-BPF-JIT-implementations.patch delete mode 100644 target/linux/generic/backport-5.15/060-v5.18-01-bpf-selftests-Add-helpers-to-directly-use-the-capget.patch delete mode 100644 target/linux/generic/backport-5.15/060-v5.18-02-bpf-selftests-Remove-libcap-usage-from-test_verifier.patch delete mode 100644 target/linux/generic/backport-5.15/060-v5.18-03-bpf-selftests-Remove-libcap-usage-from-test_progs.patch delete mode 100644 target/linux/generic/backport-5.15/080-v5.17-clk-gate-Add-devm_clk_hw_register_gate.patch delete mode 100644 target/linux/generic/backport-5.15/100-v5.18-tty-serial-bcm63xx-use-more-precise-Kconfig-symbol.patch delete mode 100644 target/linux/generic/backport-5.15/200-v5.18-tools-resolve_btfids-Build-with-host-flags.patch delete mode 100644 target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch delete mode 100644 target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch delete mode 100644 target/linux/generic/backport-5.15/300-v5.18-pinctrl-qcom-Return--EINVAL-for-setting-affinity-if-no-IRQ-parent.patch delete mode 100644 target/linux/generic/backport-5.15/301-v5.16-soc-qcom-smem-Support-reserved-memory-description.patch delete mode 100644 target/linux/generic/backport-5.15/302-v5.16-watchdog-bcm63xx_wdt-fix-fallthrough-warning.patch delete mode 100644 target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch delete mode 100644 target/linux/generic/backport-5.15/330-v5.16-01-MIPS-kernel-proc-add-CPU-option-reporting.patch delete mode 100644 target/linux/generic/backport-5.15/330-v5.16-02-MIPS-Fix-using-smp_processor_id-in-preemptible-in-sh.patch delete mode 100644 target/linux/generic/backport-5.15/331-v5.19-mtd-spinand-Add-support-for-XTX-XT26G0xA.patch delete mode 100644 target/linux/generic/backport-5.15/344-v5.18-01-phy-marvell-phy-mvebu-a3700-comphy-Remove-port-from-.patch delete mode 100644 target/linux/generic/backport-5.15/344-v5.18-02-phy-marvell-phy-mvebu-a3700-comphy-Add-native-kernel.patch delete mode 100644 target/linux/generic/backport-5.15/345-v5.17-arm64-dts-marvell-armada-37xx-Add-xtal-clock-to-comp.patch delete mode 100644 target/linux/generic/backport-5.15/346-v5.18-01-Revert-ata-ahci-mvebu-Make-SATA-PHY-optional-for-Arm.patch delete mode 100644 target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch delete mode 100644 target/linux/generic/backport-5.15/346-v5.18-03-Revert-PCI-aardvark-Fix-initialization-with-old-Marv.patch delete mode 100644 target/linux/generic/backport-5.15/347-v6.0-phy-marvell-phy-mvebu-a3700-comphy-Remove-broken-res.patch delete mode 100644 target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch delete mode 100644 target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch delete mode 100644 target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch delete mode 100644 target/linux/generic/backport-5.15/360-v6.1-powerpc-vdso-link-with-z-noexecstack.patch delete mode 100644 target/linux/generic/backport-5.15/400-v5.19-mtd-call-of_platform_populate-for-MTD-partitions.patch delete mode 100644 target/linux/generic/backport-5.15/401-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch delete mode 100644 target/linux/generic/backport-5.15/402-v6.0-mtd-next-mtd-core-introduce-of-support-for-dynamic-partitions.patch delete mode 100644 target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch delete mode 100644 target/linux/generic/backport-5.15/404-v6.0-mtd-core-check-partition-before-dereference.patch delete mode 100644 target/linux/generic/backport-5.15/405-v6.1-mtd-core-add-missing-of_node_get-in-dynamic-partitio.patch delete mode 100644 target/linux/generic/backport-5.15/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch delete mode 100644 target/linux/generic/backport-5.15/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch delete mode 100644 target/linux/generic/backport-5.15/407-v5.17-mtd-parsers-qcom-Don-t-print-error-message-on-EPROBE.patch delete mode 100644 target/linux/generic/backport-5.15/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch delete mode 100644 target/linux/generic/backport-5.15/409-v6.3-mtd-mtdpart-Don-t-create-platform-device-that-ll-nev.patch delete mode 100644 target/linux/generic/backport-5.15/410-v5.18-mtd-parsers-trx-allow-to-use-on-MediaTek-MIPS-SoCs.patch delete mode 100644 target/linux/generic/backport-5.15/411-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch delete mode 100644 target/linux/generic/backport-5.15/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch delete mode 100644 target/linux/generic/backport-5.15/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch delete mode 100644 target/linux/generic/backport-5.15/420-v5.19-02-mtd-spinand-gigadevice-add-support-for-GD5FxGQ4xExxG.patch delete mode 100644 target/linux/generic/backport-5.15/420-v5.19-03-mtd-spinand-gigadevice-add-support-for-GD5F1GQ5RExxG.patch delete mode 100644 target/linux/generic/backport-5.15/420-v5.19-04-mtd-spinand-gigadevice-add-support-for-GD5F-2-4-GQ5x.patch delete mode 100644 target/linux/generic/backport-5.15/420-v5.19-05-mtd-spinand-gigadevice-add-support-for-GD5FxGM7xExxG.patch delete mode 100644 target/linux/generic/backport-5.15/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch delete mode 100644 target/linux/generic/backport-5.15/422-v5.19-mtd-spi-nor-support-eon-en25qh256a.patch delete mode 100644 target/linux/generic/backport-5.15/423-v6.1-0001-mtd-track-maximum-number-of-bitflips-for-each-read-r.patch delete mode 100644 target/linux/generic/backport-5.15/423-v6.1-0002-mtd-always-initialize-stats-in-struct-mtd_oob_ops.patch delete mode 100644 target/linux/generic/backport-5.15/423-v6.1-0003-mtd-add-ECC-error-accounting-for-each-read-request.patch delete mode 100644 target/linux/generic/backport-5.15/423-v6.1-0004-mtdchar-add-MEMREAD-ioctl.patch delete mode 100644 target/linux/generic/backport-5.15/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch delete mode 100644 target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch delete mode 100644 target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch delete mode 100644 target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch delete mode 100644 target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch delete mode 100644 target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch delete mode 100644 target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch delete mode 100644 target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch delete mode 100644 target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch delete mode 100644 target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch delete mode 100644 target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch delete mode 100644 target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch delete mode 100644 target/linux/generic/backport-5.15/611-v6.3-net-add-helper-eth_addr_add.patch delete mode 100644 target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch delete mode 100644 target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-00-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-02-net-ethernet-mtk_eth_soc-add-support-for-Wireless-Et.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-03-net-ethernet-mtk_eth_soc-implement-flow-offloading-t.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-05-net-ethernet-mtk_eth_soc-add-ipv6-flow-offload-suppo.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-06-net-ethernet-mtk_eth_soc-support-TC_SETUP_BLOCK-for-.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-07-net-ethernet-mtk_eth_soc-allocate-struct-mtk_ppe-sep.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-08-net-ethernet-mtk_eth_soc-rework-hardware-flow-table-.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-09-net-ethernet-mtk_eth_soc-remove-bridge-flow-offload-.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-10-net-ethernet-mtk_eth_soc-support-creating-mac-addres.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-11-net-ethernet-mtk_eth_soc-wed-fix-sparse-endian-warni.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-12-net-ethernet-mtk_eth_soc-fix-return-value-check-in-m.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-14-net-ethernet-mtk_eth_soc-use-after-free-in-__mtk_ppe.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-15-net-ethernet-mtk_eth_soc-add-check-for-allocation-fa.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-16-eth-mtk_eth_soc-silence-the-GCC-12-array-bounds-warn.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-17-net-ethernet-mtk_eth_soc-rely-on-GFP_KERNEL-for-dma_.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-18-net-ethernet-mtk_eth_soc-move-tx-dma-desc-configurat.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-19-net-ethernet-mtk_eth_soc-add-txd_size-to-mtk_soc_dat.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-20-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_tx_.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-21-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_des.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-22-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-txd_to_.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-23-net-ethernet-mtk_eth_soc-add-rxd_size-to-mtk_soc_dat.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-24-net-ethernet-mtk_eth_soc-rely-on-txd_size-field-in-m.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-25-net-ethernet-mtk_eth_soc-rely-on-rxd_size-field-in-m.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-26-net-ethernet-mtk_eth_soc-introduce-device-register-m.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-27-net-ethernet-mtk_eth_soc-introduce-MTK_NETSYS_V2-sup.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-28-net-ethernet-mtk_eth_soc-convert-ring-dma-pointer-to.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-29-net-ethernet-mtk_eth_soc-convert-scratch_ring-pointe.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-30-net-ethernet-mtk_eth_soc-introduce-support-for-mt798.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-31-net-ethernet-mtk_eth_soc-fix-error-code-in-mtk_flow_.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-33-net-ethernet-mtk_eth_soc-enable-rx-cksum-offload-for.patch delete mode 100644 target/linux/generic/backport-5.15/702-v5.19-34-eth-mtk_ppe-fix-up-after-merge.patch delete mode 100644 target/linux/generic/backport-5.15/703-00-v5.16-net-convert-users-of-bitmap_foo-to-linkmode_foo.patch delete mode 100644 target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch delete mode 100644 target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch delete mode 100644 target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch delete mode 100644 target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch delete mode 100644 target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch delete mode 100644 target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch delete mode 100644 target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch delete mode 100644 target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch delete mode 100644 target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch delete mode 100644 target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch delete mode 100644 target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch delete mode 100644 target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch delete mode 100644 target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch delete mode 100644 target/linux/generic/backport-5.15/703-15-v5.18-net-phy-phylink-fix-DSA-mac_select_pcs-introduction.patch delete mode 100644 target/linux/generic/backport-5.15/703-16-v5.16-net-mvneta-populate-supported_interfaces-member.patch delete mode 100644 target/linux/generic/backport-5.15/703-17-v5.16-net-mvneta-remove-interface-checks-in-mvneta_validat.patch delete mode 100644 target/linux/generic/backport-5.15/703-18-v5.16-net-mvneta-drop-use-of-phylink_helper_basex_speed.patch delete mode 100644 target/linux/generic/backport-5.15/703-19-v5.17-net-mvneta-use-phylink_generic_validate.patch delete mode 100644 target/linux/generic/backport-5.15/703-20-v5.17-net-mvneta-mark-as-a-legacy_pre_march2020-driver.patch delete mode 100644 target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch delete mode 100644 target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch delete mode 100644 target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch delete mode 100644 target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch delete mode 100644 target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch delete mode 100644 target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch delete mode 100644 target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch delete mode 100644 target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch delete mode 100644 target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch delete mode 100644 target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch delete mode 100644 target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch delete mode 100644 target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch delete mode 100644 target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch delete mode 100644 target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch delete mode 100644 target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch delete mode 100644 target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch delete mode 100644 target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch delete mode 100644 target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch delete mode 100644 target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch delete mode 100644 target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch delete mode 100644 target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch delete mode 100644 target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch delete mode 100644 target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch delete mode 100644 target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch delete mode 100644 target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch delete mode 100644 target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch delete mode 100644 target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch delete mode 100644 target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch delete mode 100644 target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch delete mode 100644 target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch delete mode 100644 target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch delete mode 100644 target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch delete mode 100644 target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch delete mode 100644 target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch delete mode 100644 target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch delete mode 100644 target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch delete mode 100644 target/linux/generic/backport-5.15/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch delete mode 100644 target/linux/generic/backport-5.15/708-01-v5.16-net-mvneta-Delete-unused-variable.patch delete mode 100644 target/linux/generic/backport-5.15/708-02-v6.3-net-mvneta-fix-potential-double-frees-in-mvneta_txq_.patch delete mode 100644 target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch delete mode 100644 target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch delete mode 100644 target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch delete mode 100644 target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch delete mode 100644 target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch delete mode 100644 target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch delete mode 100644 target/linux/generic/backport-5.15/713-v6.0-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch delete mode 100644 target/linux/generic/backport-5.15/714-v6.0-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch delete mode 100644 target/linux/generic/backport-5.15/715-v6.0-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch delete mode 100644 target/linux/generic/backport-5.15/716-v6.0-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch delete mode 100644 target/linux/generic/backport-5.15/717-v6.0-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch delete mode 100644 target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch delete mode 100644 target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch delete mode 100644 target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch delete mode 100644 target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch delete mode 100644 target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch delete mode 100644 target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch delete mode 100644 target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-fix-wrong-use-of-new-helper.patch delete mode 100644 target/linux/generic/backport-5.15/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch delete mode 100644 target/linux/generic/backport-5.15/725-v6.0-net-ethernet-mtk_eth_soc-fix-usage-of-foe_entry_size.patch delete mode 100644 target/linux/generic/backport-5.15/726-v6.0-net-ethernet-mtk_eth_soc-fix-mask-of-RX_DMA_GET_SPOR.patch delete mode 100644 target/linux/generic/backport-5.15/727-v6.1-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch delete mode 100644 target/linux/generic/backport-5.15/728-v6.1-01-net-ethernet-mtk_eth_soc-fix-possible-memory-leak-in.patch delete mode 100644 target/linux/generic/backport-5.15/728-v6.1-02-net-ethernet-mtk_eth_wed-add-missing-put_device-in-m.patch delete mode 100644 target/linux/generic/backport-5.15/728-v6.1-03-net-ethernet-mtk_eth_wed-add-missing-of_node_put.patch delete mode 100644 target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch delete mode 100644 target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch delete mode 100644 target/linux/generic/backport-5.15/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch delete mode 100644 target/linux/generic/backport-5.15/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch delete mode 100644 target/linux/generic/backport-5.15/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch delete mode 100644 target/linux/generic/backport-5.15/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch delete mode 100644 target/linux/generic/backport-5.15/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch delete mode 100644 target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch delete mode 100644 target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch delete mode 100644 target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch delete mode 100644 target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch delete mode 100644 target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch delete mode 100644 target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch delete mode 100644 target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch delete mode 100644 target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch delete mode 100644 target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch delete mode 100644 target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch delete mode 100644 target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch delete mode 100644 target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch delete mode 100644 target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch delete mode 100644 target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch delete mode 100644 target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch delete mode 100644 target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch delete mode 100644 target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch delete mode 100644 target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch delete mode 100644 target/linux/generic/backport-5.15/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch delete mode 100644 target/linux/generic/backport-5.15/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch delete mode 100644 target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch delete mode 100644 target/linux/generic/backport-5.15/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch delete mode 100644 target/linux/generic/backport-5.15/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch delete mode 100644 target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch delete mode 100644 target/linux/generic/backport-5.15/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch delete mode 100644 target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch delete mode 100644 target/linux/generic/backport-5.15/730-10-v6.3-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch delete mode 100644 target/linux/generic/backport-5.15/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch delete mode 100644 target/linux/generic/backport-5.15/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch delete mode 100644 target/linux/generic/backport-5.15/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch delete mode 100644 target/linux/generic/backport-5.15/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch delete mode 100644 target/linux/generic/backport-5.15/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch delete mode 100644 target/linux/generic/backport-5.15/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch delete mode 100644 target/linux/generic/backport-5.15/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch delete mode 100644 target/linux/generic/backport-5.15/731-v6.1-0001-net-phy-Introduce-QUSGMII-PHY-mode.patch delete mode 100644 target/linux/generic/backport-5.15/731-v6.1-0002-net-phy-Add-helper-to-derive-the-number-of-ports-fro.patch delete mode 100644 target/linux/generic/backport-5.15/731-v6.1-0003-net-phy-Add-1000BASE-KX-interface-mode.patch delete mode 100644 target/linux/generic/backport-5.15/731-v6.1-0004-net-phy-Add-support-for-rate-matching.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-01-net-ethernet-mtk_eth_soc-Avoid-truncating-allocation.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch delete mode 100644 target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch delete mode 100644 target/linux/generic/backport-5.15/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch delete mode 100644 target/linux/generic/backport-5.15/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch delete mode 100644 target/linux/generic/backport-5.15/735-v6.0-0001-net-phy-Add-support-for-AQR113C-EPHY.patch delete mode 100644 target/linux/generic/backport-5.15/736-v6.1-0001-net-phy-aquantia-Add-some-additional-phy-interfaces.patch delete mode 100644 target/linux/generic/backport-5.15/736-v6.1-0002-net-phy-aquantia-Add-support-for-rate-matching.patch delete mode 100644 target/linux/generic/backport-5.15/737-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch delete mode 100644 target/linux/generic/backport-5.15/737-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch delete mode 100644 target/linux/generic/backport-5.15/737-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch delete mode 100644 target/linux/generic/backport-5.15/738-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch delete mode 100644 target/linux/generic/backport-5.15/739-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch delete mode 100644 target/linux/generic/backport-5.15/740-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch delete mode 100644 target/linux/generic/backport-5.15/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch delete mode 100644 target/linux/generic/backport-5.15/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch delete mode 100644 target/linux/generic/backport-5.15/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch delete mode 100644 target/linux/generic/backport-5.15/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch delete mode 100644 target/linux/generic/backport-5.15/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch delete mode 100644 target/linux/generic/backport-5.15/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch delete mode 100644 target/linux/generic/backport-5.15/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch delete mode 100644 target/linux/generic/backport-5.15/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch delete mode 100644 target/linux/generic/backport-5.15/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch delete mode 100644 target/linux/generic/backport-5.15/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch delete mode 100644 target/linux/generic/backport-5.15/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch delete mode 100644 target/linux/generic/backport-5.15/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch delete mode 100644 target/linux/generic/backport-5.15/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch delete mode 100644 target/linux/generic/backport-5.15/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch delete mode 100644 target/linux/generic/backport-5.15/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch delete mode 100644 target/linux/generic/backport-5.15/750-v5.16-net-dsa-qca8k-make-sure-pad0-mac06-exchange-is-disabled.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch delete mode 100644 target/linux/generic/backport-5.15/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch delete mode 100644 target/linux/generic/backport-5.15/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch delete mode 100644 target/linux/generic/backport-5.15/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch delete mode 100644 target/linux/generic/backport-5.15/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch delete mode 100644 target/linux/generic/backport-5.15/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch delete mode 100644 target/linux/generic/backport-5.15/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch delete mode 100644 target/linux/generic/backport-5.15/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch delete mode 100644 target/linux/generic/backport-5.15/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch delete mode 100644 target/linux/generic/backport-5.15/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch delete mode 100644 target/linux/generic/backport-5.15/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch delete mode 100644 target/linux/generic/backport-5.15/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch delete mode 100644 target/linux/generic/backport-5.15/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch delete mode 100644 target/linux/generic/backport-5.15/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch delete mode 100644 target/linux/generic/backport-5.15/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch delete mode 100644 target/linux/generic/backport-5.15/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch delete mode 100644 target/linux/generic/backport-5.15/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch delete mode 100644 target/linux/generic/backport-5.15/752-12-v6.7-net-ethernet-mtk_wed-fix-EXT_INT_STATUS_RX_FBUF-defi.patch delete mode 100644 target/linux/generic/backport-5.15/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch delete mode 100644 target/linux/generic/backport-5.15/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch delete mode 100644 target/linux/generic/backport-5.15/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch delete mode 100644 target/linux/generic/backport-5.15/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch delete mode 100644 target/linux/generic/backport-5.15/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch delete mode 100644 target/linux/generic/backport-5.15/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch delete mode 100644 target/linux/generic/backport-5.15/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch delete mode 100644 target/linux/generic/backport-5.15/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch delete mode 100644 target/linux/generic/backport-5.15/764-01-v5.16-net-dsa-qca8k-fix-internal-delay-applied-to-the-wrong-PAD.patch delete mode 100644 target/linux/generic/backport-5.15/764-02-v5.16-net-dsa-qca8k-fix-MTU-calculation.patch delete mode 100644 target/linux/generic/backport-5.15/764-03-v5.17-net-next-net-dsa-qca8k-remove-redundant-check-in-parse_port_config.patch delete mode 100644 target/linux/generic/backport-5.15/764-04-v5.17-net-next-net-dsa-qca8k-convert-to-GENMASK_FIELD_PREP_FIELD_GET.patch delete mode 100644 target/linux/generic/backport-5.15/764-05-v5.17-net-next-net-dsa-qca8k-remove-extra-mutex_init-in-qca8k_setup.patch delete mode 100644 target/linux/generic/backport-5.15/764-06-v5.17-net-next-net-dsa-qca8k-move-regmap-init-in-probe-and-set-it.patch delete mode 100644 target/linux/generic/backport-5.15/764-07-v5.17-net-next-net-dsa-qca8k-initial-conversion-to-regmap-heper.patch delete mode 100644 target/linux/generic/backport-5.15/764-08-v5.17-net-next-net-dsa-qca8k-add-additional-MIB-counter-and-.patch delete mode 100644 target/linux/generic/backport-5.15/764-09-v5.17-net-next-net-dsa-qca8k-add-support-for-port-fast-aging.patch delete mode 100644 target/linux/generic/backport-5.15/764-10-v5.17-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch delete mode 100644 target/linux/generic/backport-5.15/764-11-v5.17-net-next-net-dsa-qca8k-add-support-for-mdb_add-del.patch delete mode 100644 target/linux/generic/backport-5.15/764-12-v5.17-net-next-net-dsa-qca8k-add-support-for-mirror-mode.patch delete mode 100644 target/linux/generic/backport-5.15/764-13-v5.17-net-next-net-dsa-qca8k-add-LAG-support.patch delete mode 100644 target/linux/generic/backport-5.15/764-14-v5.17-net-next-net-dsa-qca8k-fix-warning-in-LAG-feature.patch delete mode 100644 target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch delete mode 100644 target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch delete mode 100644 target/linux/generic/backport-5.15/765-v5.17-03-net-next-net-dsa-stop-updating-master-MTU-from-master.c.patch delete mode 100644 target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch delete mode 100644 target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch delete mode 100644 target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-03-net-dsa-tag_qca-convert-to-FIELD-macro.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-04-net-dsa-tag_qca-move-define-to-include-linux-dsa.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-05-net-dsa-tag_qca-enable-promisc_on_master-flag.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-06-net-dsa-tag_qca-add-define-for-handling-mgmt-Etherne.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-07-net-dsa-tag_qca-add-define-for-handling-MIB-packet.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-08-net-dsa-tag_qca-add-support-for-handling-mgmt-and-MI.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-09-net-dsa-qca8k-add-tracking-state-of-master-port.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-10-net-dsa-qca8k-add-support-for-mgmt-read-write-in-Eth.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-11-net-dsa-qca8k-add-support-for-mib-autocast-in-Ethern.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-12-net-dsa-qca8k-add-support-for-phy-read-write-with-mg.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-13-net-dsa-qca8k-move-page-cache-to-driver-priv.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-14-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-15-net-dsa-qca8k-add-support-for-larger-read-write-size.patch delete mode 100644 target/linux/generic/backport-5.15/766-v5.18-16-net-dsa-qca8k-introduce-qca8k_bulk_read-write-functi.patch delete mode 100644 target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch delete mode 100644 target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch delete mode 100644 target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch delete mode 100644 target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch delete mode 100644 target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch delete mode 100644 target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch delete mode 100644 target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch delete mode 100644 target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch delete mode 100644 target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch delete mode 100644 target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch delete mode 100644 target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch delete mode 100644 target/linux/generic/backport-5.15/773-v5.18-1-net-dsa-Move-VLAN-filtering-syncing-out-of-dsa_switc.patch delete mode 100644 target/linux/generic/backport-5.15/773-v5.18-2-net-dsa-Avoid-cross-chip-syncing-of-VLAN-filtering.patch delete mode 100644 target/linux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch delete mode 100644 target/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch delete mode 100644 target/linux/generic/backport-5.15/774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch delete mode 100644 target/linux/generic/backport-5.15/774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch delete mode 100644 target/linux/generic/backport-5.15/774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch delete mode 100644 target/linux/generic/backport-5.15/774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch delete mode 100644 target/linux/generic/backport-5.15/774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch delete mode 100644 target/linux/generic/backport-5.15/774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch delete mode 100644 target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch delete mode 100644 target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch delete mode 100644 target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch delete mode 100644 target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch delete mode 100644 target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch delete mode 100644 target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch delete mode 100644 target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch delete mode 100644 target/linux/generic/backport-5.15/777-v6.2-01-net-dsa-qca8k-fix-wrong-length-value-for-mgmt-eth-pa.patch delete mode 100644 target/linux/generic/backport-5.15/777-v6.2-02-net-dsa-tag_qca-fix-wrong-MGMT_DATA2-size.patch delete mode 100644 target/linux/generic/backport-5.15/777-v6.2-03-Revert-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch delete mode 100644 target/linux/generic/backport-5.15/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch delete mode 100644 target/linux/generic/backport-5.15/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch delete mode 100644 target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch delete mode 100644 target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch delete mode 100644 target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch delete mode 100644 target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch delete mode 100644 target/linux/generic/backport-5.15/780-v5.16-bus-mhi-pci_generic-Introduce-Sierra-EM919X-support.patch delete mode 100644 target/linux/generic/backport-5.15/781-v6.1-bus-mhi-host-always-print-detected-modem-name.patch delete mode 100644 target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch delete mode 100644 target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch delete mode 100644 target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch delete mode 100644 target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch delete mode 100644 target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch delete mode 100644 target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch delete mode 100644 target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch delete mode 100644 target/linux/generic/backport-5.15/789-v6.3-net-sfp-add-quirk-enabling-2500Base-x-for-HG-MXPD-48.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.0-net-mii-add-mii_bmcr_encode_fixed.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0001-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0012-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch delete mode 100644 target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch delete mode 100644 target/linux/generic/backport-5.15/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch delete mode 100644 target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch delete mode 100644 target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch delete mode 100644 target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch delete mode 100644 target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch delete mode 100644 target/linux/generic/backport-5.15/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch delete mode 100644 target/linux/generic/backport-5.15/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch delete mode 100644 target/linux/generic/backport-5.15/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch delete mode 100644 target/linux/generic/backport-5.15/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch delete mode 100644 target/linux/generic/backport-5.15/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch delete mode 100644 target/linux/generic/backport-5.15/795-v6.6-09-r8152-set-bp-in-bulk.patch delete mode 100644 target/linux/generic/backport-5.15/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch delete mode 100644 target/linux/generic/backport-5.15/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch delete mode 100644 target/linux/generic/backport-5.15/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch delete mode 100644 target/linux/generic/backport-5.15/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch delete mode 100644 target/linux/generic/backport-5.15/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch delete mode 100644 target/linux/generic/backport-5.15/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch delete mode 100644 target/linux/generic/backport-5.15/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch delete mode 100644 target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch delete mode 100644 target/linux/generic/backport-5.15/798-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch delete mode 100644 target/linux/generic/backport-5.15/800-v6.0-0001-dt-bindings-leds-add-Broadcom-s-BCM63138-controller.patch delete mode 100644 target/linux/generic/backport-5.15/800-v6.0-0002-leds-bcm63138-add-support-for-BCM63138-controller.patch delete mode 100644 target/linux/generic/backport-5.15/801-v6.0-0001-dt-bindings-leds-leds-bcm63138-unify-full-stops-in-d.patch delete mode 100644 target/linux/generic/backport-5.15/801-v6.0-0002-leds-add-help-info-about-BCM63138-module-name.patch delete mode 100644 target/linux/generic/backport-5.15/801-v6.0-0003-leds-leds-bcm63138-get-rid-of-LED_OFF.patch delete mode 100644 target/linux/generic/backport-5.15/802-v5.16-0001-nvmem-core-rework-nvmem-cell-instance-creation.patch delete mode 100644 target/linux/generic/backport-5.15/802-v5.16-0002-nvmem-core-add-nvmem-cell-post-processing-callback.patch delete mode 100644 target/linux/generic/backport-5.15/802-v5.16-0003-nvmem-imx-ocotp-add-support-for-post-processing.patch delete mode 100644 target/linux/generic/backport-5.15/803-v5.17-0002-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch delete mode 100644 target/linux/generic/backport-5.15/804-v5.18-0001-nvmem-core-Remove-unused-devm_nvmem_unregister.patch delete mode 100644 target/linux/generic/backport-5.15/804-v5.18-0002-nvmem-core-Use-devm_add_action_or_reset.patch delete mode 100644 target/linux/generic/backport-5.15/804-v5.18-0003-nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch delete mode 100644 target/linux/generic/backport-5.15/804-v5.18-0004-nvmem-qfprom-fix-kerneldoc-warning.patch delete mode 100644 target/linux/generic/backport-5.15/804-v5.18-0005-nvmem-sunxi_sid-Add-support-for-D1-variant.patch delete mode 100644 target/linux/generic/backport-5.15/804-v5.18-0006-nvmem-meson-mx-efuse-replace-unnecessary-devm_kstrdu.patch delete mode 100644 target/linux/generic/backport-5.15/804-v5.18-0007-nvmem-add-driver-for-Layerscape-SFP-Security-Fuse-Pr.patch delete mode 100644 target/linux/generic/backport-5.15/804-v5.18-0008-nvmem-qfprom-Increase-fuse-blow-timeout-to-prevent-w.patch delete mode 100644 target/linux/generic/backport-5.15/804-v5.18-0009-nvmem-Add-driver-for-OCOTP-in-Sunplus-SP7021.patch delete mode 100644 target/linux/generic/backport-5.15/804-v5.18-0010-nvmem-brcm_nvram-parse-NVRAM-content-into-NVMEM-cell.patch delete mode 100644 target/linux/generic/backport-5.15/805-v5.19-0001-nvmem-bcm-ocotp-mark-ACPI-device-ID-table-as-maybe-u.patch delete mode 100644 target/linux/generic/backport-5.15/805-v5.19-0002-nvmem-sunplus-ocotp-staticize-sp_otp_v0.patch delete mode 100644 target/linux/generic/backport-5.15/805-v5.19-0003-nvmem-sunplus-ocotp-drop-useless-probe-confirmation.patch delete mode 100644 target/linux/generic/backport-5.15/805-v5.19-0004-nvmem-core-support-passing-DT-node-in-cell-info.patch delete mode 100644 target/linux/generic/backport-5.15/805-v5.19-0005-nvmem-brcm_nvram-find-Device-Tree-nodes-for-NVMEM-ce.patch delete mode 100644 target/linux/generic/backport-5.15/805-v5.19-0006-nvmem-Add-Apple-eFuse-driver.patch delete mode 100644 target/linux/generic/backport-5.15/805-v5.19-0007-nvmem-qfprom-using-pm_runtime_resume_and_get-instead.patch delete mode 100644 target/linux/generic/backport-5.15/805-v5.19-0008-nvmem-sfp-Use-regmap.patch delete mode 100644 target/linux/generic/backport-5.15/805-v5.19-0009-nvmem-sfp-Add-support-for-TA-2.1-devices.patch delete mode 100644 target/linux/generic/backport-5.15/806-v6.0-0001-nvmem-microchip-otpc-add-support.patch delete mode 100644 target/linux/generic/backport-5.15/806-v6.0-0002-nvmem-mtk-efuse-Simplify-with-devm_platform_get_and_.patch delete mode 100644 target/linux/generic/backport-5.15/807-v6.1-0002-nvmem-add-driver-handling-U-Boot-environment-variabl.patch delete mode 100644 target/linux/generic/backport-5.15/807-v6.1-0004-nvmem-brcm_nvram-Use-kzalloc-for-allocating-only-one.patch delete mode 100644 target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch delete mode 100644 target/linux/generic/backport-5.15/807-v6.1-0006-nvmem-sort-config-symbols-alphabetically.patch delete mode 100644 target/linux/generic/backport-5.15/807-v6.1-0007-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch delete mode 100644 target/linux/generic/backport-5.15/807-v6.1-0008-nvmem-lan9662-otp-add-support.patch delete mode 100644 target/linux/generic/backport-5.15/807-v6.1-0009-nvmem-u-boot-env-fix-crc32-casting-type.patch delete mode 100644 target/linux/generic/backport-5.15/807-v6.1-0010-nvmem-lan9662-otp-Fix-compatible-string.patch delete mode 100644 target/linux/generic/backport-5.15/807-v6.1-0011-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch delete mode 100644 target/linux/generic/backport-5.15/807-v6.1-0013-nvmem-lan9662-otp-Change-return-type-of-lan9662_otp_.patch delete mode 100644 target/linux/generic/backport-5.15/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch delete mode 100644 target/linux/generic/backport-5.15/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch delete mode 100644 target/linux/generic/backport-5.15/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch delete mode 100644 target/linux/generic/backport-5.15/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch delete mode 100644 target/linux/generic/backport-5.15/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch delete mode 100644 target/linux/generic/backport-5.15/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch delete mode 100644 target/linux/generic/backport-5.15/808-v6.2-0007-nvmem-brcm_nvram-Add-check-for-kzalloc.patch delete mode 100644 target/linux/generic/backport-5.15/808-v6.2-0008-nvmem-sunxi_sid-Always-use-32-bit-MMIO-reads.patch delete mode 100644 target/linux/generic/backport-5.15/808-v6.2-0013-nvmem-core-fix-device-node-refcounting.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch delete mode 100644 target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch delete mode 100644 target/linux/generic/backport-5.15/810-v5.17-net-qmi_wwan-add-ZTE-MF286D-modem-19d2-1485.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch delete mode 100644 target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch delete mode 100644 target/linux/generic/backport-5.15/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch delete mode 100644 target/linux/generic/backport-5.15/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch delete mode 100644 target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch delete mode 100644 target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch delete mode 100644 target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch delete mode 100644 target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch delete mode 100644 target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch delete mode 100644 target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch delete mode 100644 target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch delete mode 100644 target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch delete mode 100644 target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch delete mode 100644 target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch delete mode 100644 target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch delete mode 100644 target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch delete mode 100644 target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch delete mode 100644 target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch delete mode 100644 target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch delete mode 100644 target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch delete mode 100644 target/linux/generic/backport-5.15/819-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch delete mode 100644 target/linux/generic/backport-5.15/820-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch delete mode 100644 target/linux/generic/backport-5.15/820-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch delete mode 100644 target/linux/generic/backport-5.15/820-v6.7-0003-nvmem-Use-device_get_match_data.patch delete mode 100644 target/linux/generic/backport-5.15/820-v6.7-0004-Revert-nvmem-add-new-config-option.patch delete mode 100644 target/linux/generic/backport-5.15/820-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch delete mode 100644 target/linux/generic/backport-5.15/820-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch delete mode 100644 target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch delete mode 100644 target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch delete mode 100644 target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch delete mode 100644 target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch delete mode 100644 target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch delete mode 100644 target/linux/generic/backport-5.15/826-v5.17-of-base-make-small-of_parse_phandle-variants-static-.patch delete mode 100644 target/linux/generic/backport-5.15/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch delete mode 100644 target/linux/generic/backport-5.15/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch delete mode 100644 target/linux/generic/backport-5.15/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch delete mode 100644 target/linux/generic/backport-5.15/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch delete mode 100644 target/linux/generic/backport-5.15/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch delete mode 100644 target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch delete mode 100644 target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch delete mode 100644 target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch delete mode 100644 target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch delete mode 100644 target/linux/generic/backport-5.15/829-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch delete mode 100644 target/linux/generic/backport-5.15/830-v6.0-leds-turris-omnia-convert-to-use-dev_groups.patch delete mode 100644 target/linux/generic/backport-5.15/830-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch delete mode 100644 target/linux/generic/backport-5.15/830-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch delete mode 100644 target/linux/generic/backport-5.15/830-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch delete mode 100644 target/linux/generic/backport-5.15/830-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch delete mode 100644 target/linux/generic/backport-5.15/830-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch delete mode 100644 target/linux/generic/backport-5.15/831-v6.1-dt-bindings-leds-Expand-LED_COLOR_ID-definitions.patch delete mode 100644 target/linux/generic/backport-5.15/832-v6.8-of-device-Export-of_device_make_bus_id.patch delete mode 100644 target/linux/generic/backport-5.15/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch delete mode 100644 target/linux/generic/backport-5.15/834-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch delete mode 100644 target/linux/generic/backport-5.15/835-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch delete mode 100644 target/linux/generic/backport-5.15/835-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch delete mode 100644 target/linux/generic/backport-5.15/836-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch delete mode 100644 target/linux/generic/backport-5.15/836-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch delete mode 100644 target/linux/generic/backport-5.15/836-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch delete mode 100644 target/linux/generic/backport-5.15/836-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch delete mode 100644 target/linux/generic/backport-5.15/836-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0009-nvmem-rmem-Fix-return-value-of-rmem_read.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0010-nvmem-meson-efuse-Fix-return-value-of-nvmem-callback.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0011-nvmem-core-only-change-name-to-fram-for-current-attr.patch delete mode 100644 target/linux/generic/backport-5.15/837-v6.10-0012-nvmem-core-limit-cell-sysfs-permissions-to-main-attr.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0006-nvmem-core-add-single-sysfs-group.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch delete mode 100644 target/linux/generic/backport-5.15/838-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch delete mode 100644 target/linux/generic/backport-5.15/839-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch delete mode 100644 target/linux/generic/backport-5.15/839-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch delete mode 100644 target/linux/generic/backport-5.15/839-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch delete mode 100644 target/linux/generic/backport-5.15/860-v5.17-MIPS-ath79-drop-_machine_restart-again.patch delete mode 100644 target/linux/generic/backport-5.15/870-v5.18-hwmon-lm70-Add-ti-tmp125-support.patch delete mode 100644 target/linux/generic/backport-5.15/880-v5.19-cdc_ether-export-usbnet_cdc_zte_rx_fixup.patch delete mode 100644 target/linux/generic/backport-5.15/881-v5.19-rndis_host-enable-the-bogus-MAC-fixup-for-ZTE-device.patch delete mode 100644 target/linux/generic/backport-5.15/882-v5.19-rndis_host-limit-scope-of-bogus-MAC-address-detectio.patch delete mode 100644 target/linux/generic/backport-5.15/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch delete mode 100644 target/linux/generic/backport-5.15/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch delete mode 100644 target/linux/generic/backport-5.15/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch delete mode 100644 target/linux/generic/backport-5.15/893-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch delete mode 100644 target/linux/generic/backport-5.15/893-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch delete mode 100644 target/linux/generic/backport-5.15/893-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch delete mode 100644 target/linux/generic/backport-5.15/893-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch delete mode 100644 target/linux/generic/backport-5.15/893-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch delete mode 100644 target/linux/generic/backport-5.15/893-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch delete mode 100644 target/linux/generic/backport-5.15/894-v6.8-net-ethtool-implement-ethtool_puts.patch delete mode 100644 target/linux/generic/config-5.15 delete mode 100644 target/linux/generic/hack-5.15/204-module_strip.patch delete mode 100644 target/linux/generic/hack-5.15/205-kconfig-abort-configuration-on-unset-symbol.patch delete mode 100644 target/linux/generic/hack-5.15/210-darwin_scripts_include.patch delete mode 100644 target/linux/generic/hack-5.15/211-darwin-uuid-typedef-clash.patch delete mode 100644 target/linux/generic/hack-5.15/212-tools_portability.patch delete mode 100644 target/linux/generic/hack-5.15/214-spidev_h_portability.patch delete mode 100644 target/linux/generic/hack-5.15/220-arm-gc_sections.patch delete mode 100644 target/linux/generic/hack-5.15/221-module_exports.patch delete mode 100644 target/linux/generic/hack-5.15/230-openwrt_lzma_options.patch delete mode 100644 target/linux/generic/hack-5.15/250-netfilter_depends.patch delete mode 100644 target/linux/generic/hack-5.15/251-kconfig.patch delete mode 100644 target/linux/generic/hack-5.15/253-ksmbd-config.patch delete mode 100644 target/linux/generic/hack-5.15/259-regmap_dynamic.patch delete mode 100644 target/linux/generic/hack-5.15/260-crypto_test_dependencies.patch delete mode 100644 target/linux/generic/hack-5.15/261-lib-arc4-unhide.patch delete mode 100644 target/linux/generic/hack-5.15/280-rfkill-stubs.patch delete mode 100644 target/linux/generic/hack-5.15/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch delete mode 100644 target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch delete mode 100644 target/linux/generic/hack-5.15/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch delete mode 100644 target/linux/generic/hack-5.15/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch delete mode 100644 target/linux/generic/hack-5.15/430-mtk-bmt-support.patch delete mode 100644 target/linux/generic/hack-5.15/645-netfilter-connmark-introduce-set-dscpmark.patch delete mode 100644 target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch delete mode 100644 target/linux/generic/hack-5.15/651-wireless_mesh_header.patch delete mode 100644 target/linux/generic/hack-5.15/660-fq_codel_defaults.patch delete mode 100644 target/linux/generic/hack-5.15/661-kernel-ct-size-the-hashtable-more-adequately.patch delete mode 100644 target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch delete mode 100644 target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch delete mode 100644 target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch delete mode 100644 target/linux/generic/hack-5.15/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch delete mode 100644 target/linux/generic/hack-5.15/723-net-phy-aquantia-fix-system-side-protocol-mi.patch delete mode 100644 target/linux/generic/hack-5.15/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch delete mode 100644 target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch delete mode 100644 target/linux/generic/hack-5.15/760-net-usb-r8152-add-LED-configuration-from-OF.patch delete mode 100644 target/linux/generic/hack-5.15/761-dt-bindings-net-add-RTL8152-binding-documentation.patch delete mode 100644 target/linux/generic/hack-5.15/765-mxl-gpy-control-LED-reg-from-DT.patch delete mode 100644 target/linux/generic/hack-5.15/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch delete mode 100644 target/linux/generic/hack-5.15/773-bgmac-add-srab-switch.patch delete mode 100644 target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch delete mode 100644 target/linux/generic/hack-5.15/781-usb-net-rndis-support-asr.patch delete mode 100644 target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch delete mode 100644 target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch delete mode 100644 target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch delete mode 100644 target/linux/generic/hack-5.15/810-bcma-ssb-fallback-sprom.patch delete mode 100644 target/linux/generic/hack-5.15/901-debloat_sock_diag.patch delete mode 100644 target/linux/generic/hack-5.15/902-debloat_proc.patch delete mode 100644 target/linux/generic/hack-5.15/904-debloat_dma_buf.patch delete mode 100644 target/linux/generic/hack-5.15/910-kobject_uevent.patch delete mode 100644 target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch delete mode 100644 target/linux/generic/hack-5.15/920-device_tree_cmdline.patch delete mode 100644 target/linux/generic/hack-5.15/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch delete mode 100644 target/linux/generic/pending-5.15/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch delete mode 100644 target/linux/generic/pending-5.15/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch delete mode 100644 target/linux/generic/pending-5.15/103-kbuild-export-SUBARCH.patch delete mode 100644 target/linux/generic/pending-5.15/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch delete mode 100644 target/linux/generic/pending-5.15/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch delete mode 100644 target/linux/generic/pending-5.15/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch delete mode 100644 target/linux/generic/pending-5.15/141-jffs2-add-RENAME_EXCHANGE-support.patch delete mode 100644 target/linux/generic/pending-5.15/142-jffs2-add-splice-ops.patch delete mode 100644 target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch delete mode 100644 target/linux/generic/pending-5.15/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch delete mode 100644 target/linux/generic/pending-5.15/190-rtc-rs5c372-support_alarms_up_to_1_week.patch delete mode 100644 target/linux/generic/pending-5.15/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch delete mode 100644 target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch delete mode 100644 target/linux/generic/pending-5.15/205-backtrace_module_info.patch delete mode 100644 target/linux/generic/pending-5.15/240-remove-unsane-filenames-from-deps_initramfs-list.patch delete mode 100644 target/linux/generic/pending-5.15/261-enable_wilink_platform_without_drivers.patch delete mode 100644 target/linux/generic/pending-5.15/270-platform-mikrotik-build-bits.patch delete mode 100644 target/linux/generic/pending-5.15/300-mips_expose_boot_raw.patch delete mode 100644 target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch delete mode 100644 target/linux/generic/pending-5.15/302-mips_no_branch_likely.patch delete mode 100644 target/linux/generic/pending-5.15/305-mips_module_reloc.patch delete mode 100644 target/linux/generic/pending-5.15/308-mips32r2_tune.patch delete mode 100644 target/linux/generic/pending-5.15/310-arm_module_unresolved_weak_sym.patch delete mode 100644 target/linux/generic/pending-5.15/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch delete mode 100644 target/linux/generic/pending-5.15/332-arc-add-OWRTDTB-section.patch delete mode 100644 target/linux/generic/pending-5.15/333-arc-enable-unaligned-access-in-kernel-mode.patch delete mode 100644 target/linux/generic/pending-5.15/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch delete mode 100644 target/linux/generic/pending-5.15/351-irqchip-bcm-6345-l1-request-memory-region.patch delete mode 100644 target/linux/generic/pending-5.15/400-mtd-mtdsplit-support.patch delete mode 100644 target/linux/generic/pending-5.15/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch delete mode 100644 target/linux/generic/pending-5.15/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch delete mode 100644 target/linux/generic/pending-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch delete mode 100644 target/linux/generic/pending-5.15/420-mtd-redboot_space.patch delete mode 100644 target/linux/generic/pending-5.15/430-mtd-add-myloader-partition-parser.patch delete mode 100644 target/linux/generic/pending-5.15/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch delete mode 100644 target/linux/generic/pending-5.15/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch delete mode 100644 target/linux/generic/pending-5.15/435-mtd-add-routerbootpart-parser-config.patch delete mode 100644 target/linux/generic/pending-5.15/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch delete mode 100644 target/linux/generic/pending-5.15/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch delete mode 100644 target/linux/generic/pending-5.15/465-m25p80-mx-disable-software-protection.patch delete mode 100644 target/linux/generic/pending-5.15/476-mtd-spi-nor-add-eon-en25q128.patch delete mode 100644 target/linux/generic/pending-5.15/477-mtd-spi-nor-add-eon-en25qx128a.patch delete mode 100644 target/linux/generic/pending-5.15/479-mtd-spi-nor-add-xtx-xt25f128b.patch delete mode 100644 target/linux/generic/pending-5.15/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch delete mode 100644 target/linux/generic/pending-5.15/482-mtd-spi-nor-add-gd25q512.patch delete mode 100644 target/linux/generic/pending-5.15/484-mtd-spi-nor-add-esmt-f25l16pa.patch delete mode 100644 target/linux/generic/pending-5.15/485-mtd-spi-nor-add-xmc-xm25qh128c.patch delete mode 100644 target/linux/generic/pending-5.15/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch delete mode 100644 target/linux/generic/pending-5.15/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch delete mode 100644 target/linux/generic/pending-5.15/488-mtd-spi-nor-add-xmc-xm25qh64c.patch delete mode 100644 target/linux/generic/pending-5.15/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch delete mode 100644 target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch delete mode 100644 target/linux/generic/pending-5.15/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch delete mode 100644 target/linux/generic/pending-5.15/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch delete mode 100644 target/linux/generic/pending-5.15/494-mtd-ubi-add-EOF-marker-support.patch delete mode 100644 target/linux/generic/pending-5.15/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch delete mode 100644 target/linux/generic/pending-5.15/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch delete mode 100644 target/linux/generic/pending-5.15/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch delete mode 100644 target/linux/generic/pending-5.15/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch delete mode 100644 target/linux/generic/pending-5.15/500-fs_cdrom_dependencies.patch delete mode 100644 target/linux/generic/pending-5.15/530-jffs2_make_lzma_available.patch delete mode 100644 target/linux/generic/pending-5.15/532-jffs2_eofdetect.patch delete mode 100644 target/linux/generic/pending-5.15/600-netfilter_conntrack_flush.patch delete mode 100644 target/linux/generic/pending-5.15/610-netfilter_match_bypass_default_checks.patch delete mode 100644 target/linux/generic/pending-5.15/611-netfilter_match_bypass_default_table.patch delete mode 100644 target/linux/generic/pending-5.15/612-netfilter_match_reduce_memory_access.patch delete mode 100644 target/linux/generic/pending-5.15/620-net_sched-codel-do-not-defer-queue-length-update.patch delete mode 100644 target/linux/generic/pending-5.15/630-packet_socket_type.patch delete mode 100644 target/linux/generic/pending-5.15/655-increase_skb_pad.patch delete mode 100644 target/linux/generic/pending-5.15/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch delete mode 100644 target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch delete mode 100644 target/linux/generic/pending-5.15/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch delete mode 100644 target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch delete mode 100644 target/linux/generic/pending-5.15/683-of_net-add-mac-address-to-of-tree.patch delete mode 100644 target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch delete mode 100644 target/linux/generic/pending-5.15/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch delete mode 100644 target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch delete mode 100644 target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch delete mode 100644 target/linux/generic/pending-5.15/704-01-v6.4-net-mvneta-fix-transmit-path-dma-unmapping-on-error.patch delete mode 100644 target/linux/generic/pending-5.15/704-02-v6.4-net-mvneta-mark-mapped-and-tso-buffers-separately.patch delete mode 100644 target/linux/generic/pending-5.15/704-03-v6.4-net-mvneta-use-buf-type-to-determine-whether-to-dma-.patch delete mode 100644 target/linux/generic/pending-5.15/704-04-v6.4-net-mvneta-move-tso_build_hdr-into-mvneta_tso_put_hd.patch delete mode 100644 target/linux/generic/pending-5.15/704-05-v6.4-net-mvneta-allocate-TSO-header-DMA-memory-in-chunks.patch delete mode 100644 target/linux/generic/pending-5.15/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch delete mode 100644 target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch delete mode 100644 target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch delete mode 100644 target/linux/generic/pending-5.15/722-net-phy-realtek-support-switching-between-SGMII-and-.patch delete mode 100644 target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch delete mode 100644 target/linux/generic/pending-5.15/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch delete mode 100644 target/linux/generic/pending-5.15/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch delete mode 100644 target/linux/generic/pending-5.15/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch delete mode 100644 target/linux/generic/pending-5.15/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch delete mode 100644 target/linux/generic/pending-5.15/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch delete mode 100644 target/linux/generic/pending-5.15/729-net-phy-realtek-introduce-rtl822x_probe.patch delete mode 100644 target/linux/generic/pending-5.15/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch delete mode 100644 target/linux/generic/pending-5.15/731-net-phy-realtek-support-interrupt-of-RTL8221B.patch delete mode 100644 target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch delete mode 100644 target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch delete mode 100644 target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch delete mode 100644 target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch delete mode 100644 target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch delete mode 100644 target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch delete mode 100644 target/linux/generic/pending-5.15/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch delete mode 100644 target/linux/generic/pending-5.15/740-net-phy-motorcomm-Add-missing-include.patch delete mode 100644 target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch delete mode 100644 target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch delete mode 100644 target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch delete mode 100644 target/linux/generic/pending-5.15/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch delete mode 100644 target/linux/generic/pending-5.15/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch delete mode 100644 target/linux/generic/pending-5.15/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch delete mode 100644 target/linux/generic/pending-5.15/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch delete mode 100644 target/linux/generic/pending-5.15/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch delete mode 100644 target/linux/generic/pending-5.15/779-net-vxlan-don-t-learn-non-unicast-L2-destinations.patch delete mode 100644 target/linux/generic/pending-5.15/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch delete mode 100644 target/linux/generic/pending-5.15/790-bus-mhi-core-add-SBL-state-callback.patch delete mode 100644 target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch delete mode 100644 target/linux/generic/pending-5.15/796-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch delete mode 100644 target/linux/generic/pending-5.15/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch delete mode 100644 target/linux/generic/pending-5.15/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch delete mode 100644 target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch delete mode 100644 target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch delete mode 100644 target/linux/generic/pending-5.15/810-pci_disable_common_quirks.patch delete mode 100644 target/linux/generic/pending-5.15/811-pci_disable_usb_common_quirks.patch delete mode 100644 target/linux/generic/pending-5.15/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch delete mode 100644 target/linux/generic/pending-5.15/834-ledtrig-libata.patch delete mode 100644 target/linux/generic/pending-5.15/840-hwrng-bcm2835-set-quality-to-1000.patch delete mode 100644 target/linux/generic/pending-5.15/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch delete mode 100644 target/linux/generic/pending-5.15/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch delete mode 100644 target/linux/generic/pending-5.15/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch delete mode 100644 target/linux/generic/pending-5.15/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch delete mode 100644 target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch delete mode 100644 target/linux/generic/pending-5.15/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch delete mode 100644 target/linux/generic/pending-5.15/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch delete mode 100644 target/linux/generic/pending-5.15/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch delete mode 100644 target/linux/generic/pending-5.15/920-mangle_bootargs.patch delete mode 100644 target/linux/generic/pending-5.15/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch diff --git a/include/kernel-5.15 b/include/kernel-5.15 deleted file mode 100644 index a03ed80f9f5f86..00000000000000 --- a/include/kernel-5.15 +++ /dev/null @@ -1,2 +0,0 @@ -LINUX_VERSION-5.15 = .161 -LINUX_KERNEL_HASH-5.15.161 = d629f78680dc4b65e3d78b61406fb7757b960c83c206e63ad8c2606b3e3c474c diff --git a/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch b/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch deleted file mode 100644 index b481dd306179cd..00000000000000 --- a/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 2fd7e7f9317d3048a14026816d081b08ba98ea8e Mon Sep 17 00:00:00 2001 -From: Mark Rutland -Date: Tue, 8 Mar 2022 22:56:13 +0100 -Subject: [PATCH 1/3] Kbuild: use -Wdeclaration-after-statement - -The kernel is moving from using `-std=gnu89` to `-std=gnu11`, permitting -the use of additional C11 features such as for-loop initial declarations. - -One contentious aspect of C99 is that it permits mixed declarations and -code, and for now at least, it seems preferable to enforce that -declarations must come first. - -These warnings were already enabled in the kernel itself, but not -for KBUILD_USERCFLAGS or the compat VDSO on arch/arm64, which uses -a separate set of CFLAGS. - -This patch fixes an existing violation in modpost.c, which is not -reported because of the missing flag in KBUILD_USERCFLAGS: - -| scripts/mod/modpost.c: In function ‘match’: -| scripts/mod/modpost.c:837:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] -| 837 | const char *endp = p + strlen(p) - 1; -| | ^~~~~ - -Signed-off-by: Mark Rutland -[arnd: don't add a duplicate flag to the default set, update changelog] -Signed-off-by: Arnd Bergmann -Reviewed-by: Nathan Chancellor -Reviewed-by: Nick Desaulniers -Tested-by: Sedat Dilek # LLVM/Clang v13.0.0 (x86-64) -Signed-off-by: Masahiro Yamada ---- - Makefile | 3 ++- - arch/arm64/kernel/vdso32/Makefile | 1 + - scripts/mod/modpost.c | 4 +++- - 3 files changed, 6 insertions(+), 2 deletions(-) - ---- a/Makefile -+++ b/Makefile -@@ -440,7 +440,8 @@ endif - HOSTPKG_CONFIG = pkg-config - - export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ -- -O2 -fomit-frame-pointer -std=gnu89 -+ -O2 -fomit-frame-pointer -std=gnu89 \ -+ -Wdeclaration-after-statement - export KBUILD_USERLDFLAGS := - - KBUILD_HOSTCFLAGS := $(KBUILD_USERCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) ---- a/arch/arm64/kernel/vdso32/Makefile -+++ b/arch/arm64/kernel/vdso32/Makefile -@@ -76,6 +76,7 @@ VDSO_CFLAGS += -Wall -Wundef -Wstrict-pr - -fno-strict-aliasing -fno-common \ - -Werror-implicit-function-declaration \ - -Wno-format-security \ -+ -Wdeclaration-after-statement \ - -std=gnu89 - VDSO_CFLAGS += -O2 - # Some useful compiler-dependent flags from top-level Makefile ---- a/scripts/mod/modpost.c -+++ b/scripts/mod/modpost.c -@@ -833,8 +833,10 @@ static int match(const char *sym, const - { - const char *p; - while (*pat) { -+ const char *endp; -+ - p = *pat++; -- const char *endp = p + strlen(p) - 1; -+ endp = p + strlen(p) - 1; - - /* "*foo*" */ - if (*p == '*' && *endp == '*') { diff --git a/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch b/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch deleted file mode 100644 index 94fc52fd8e039a..00000000000000 --- a/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch +++ /dev/null @@ -1,60 +0,0 @@ -From b810c8e719ea082e47c7a8f7cf878bc84fa2455d Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Tue, 8 Mar 2022 22:56:14 +0100 -Subject: [PATCH 2/3] Kbuild: move to -std=gnu11 - -During a patch discussion, Linus brought up the option of changing -the C standard version from gnu89 to gnu99, which allows using variable -declaration inside of a for() loop. While the C99, C11 and later standards -introduce many other features, most of these are already available in -gnu89 as GNU extensions as well. - -An earlier attempt to do this when gcc-5 started defaulting to --std=gnu11 failed because at the time that caused warnings about -designated initializers with older compilers. Now that gcc-5.1 is -the minimum compiler version used for building kernels, that is no -longer a concern. Similarly, the behavior of 'inline' functions changes -between gnu89 using gnu_inline behavior and gnu11 using standard c99+ -behavior, but this was taken care of by defining 'inline' to include -__attribute__((gnu_inline)) in order to allow building with clang a -while ago. - -Nathan Chancellor reported a new -Wdeclaration-after-statement -warning that appears in a system header on arm, this still needs a -workaround. - -The differences between gnu99, gnu11, gnu1x and gnu17 are fairly -minimal and mainly impact warnings at the -Wpedantic level that the -kernel never enables. Between these, gnu11 is the newest version -that is supported by all supported compiler versions, though it is -only the default on gcc-5, while all other supported versions of -gcc or clang default to gnu1x/gnu17. - -Link: https://lore.kernel.org/lkml/CAHk-=wiyCH7xeHcmiFJ-YgXUy2Jaj7pnkdKpcovt8fYbVFW3TA@mail.gmail.com/ -Link: https://github.com/ClangBuiltLinux/linux/issues/1603 -Suggested-by: Linus Torvalds -Acked-by: Marco Elver -Acked-by: Jani Nikula -Acked-by: David Sterba -Tested-by: Sedat Dilek -Reviewed-by: Alex Shi -Reviewed-by: Nick Desaulniers -Reviewed-by: Miguel Ojeda -Signed-off-by: Arnd Bergmann -Reviewed-by: Nathan Chancellor -Signed-off-by: Masahiro Yamada ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/Makefile -+++ b/Makefile -@@ -524,7 +524,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror - -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \ - -Werror=implicit-function-declaration -Werror=implicit-int \ - -Werror=return-type -Wno-format-security \ -- -std=gnu89 -+ -std=gnu11 - KBUILD_CPPFLAGS := -D__KERNEL__ - KBUILD_AFLAGS_KERNEL := - KBUILD_CFLAGS_KERNEL := diff --git a/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch b/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch deleted file mode 100644 index e34acbba171635..00000000000000 --- a/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 40337d6f3d677aee7ad3052ae662d3f53dd4d5cb Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Tue, 8 Mar 2022 22:56:15 +0100 -Subject: [PATCH 3/3] Kbuild: use -std=gnu11 for KBUILD_USERCFLAGS - -As we change the C language standard for the kernel from gnu89 to -gnu11, it makes sense to also update the version for user space -compilation. - -Some users have older native compilers than what they use for -kernel builds, so I considered using gnu99 as the default version -for wider compatibility with gcc-4.6 and earlier. - -However, testing with older compilers showed that we already require -HOSTCC version 5.1 as well because a lot of host tools include -linux/compiler.h that uses __has_attribute(): - - CC tools/objtool/exec-cmd.o -In file included from tools/include/linux/compiler_types.h:36:0, - from tools/include/linux/compiler.h:5, - from exec-cmd.c:2: -tools/include/linux/compiler-gcc.h:19:5: error: "__has_attribute" is not defined [-Werror=undef] - -Signed-off-by: Arnd Bergmann -Reviewed-by: Nathan Chancellor -Reviewed-by: Nick Desaulniers -Tested-by: Sedat Dilek -Signed-off-by: Masahiro Yamada ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/Makefile -+++ b/Makefile -@@ -440,7 +440,7 @@ endif - HOSTPKG_CONFIG = pkg-config - - export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ -- -O2 -fomit-frame-pointer -std=gnu89 \ -+ -O2 -fomit-frame-pointer -std=gnu11 \ - -Wdeclaration-after-statement - export KBUILD_USERLDFLAGS := - diff --git a/target/linux/generic/backport-5.15/020-v6.1-01-mm-x86-arm64-add-arch_has_hw_pte_young.patch b/target/linux/generic/backport-5.15/020-v6.1-01-mm-x86-arm64-add-arch_has_hw_pte_young.patch deleted file mode 100644 index 865da6b18284dd..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-01-mm-x86-arm64-add-arch_has_hw_pte_young.patch +++ /dev/null @@ -1,425 +0,0 @@ -From a4103262b01a1b8704b37c01c7c813df91b7b119 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 01:59:58 -0600 -Subject: [PATCH 01/29] mm: x86, arm64: add arch_has_hw_pte_young() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Patch series "Multi-Gen LRU Framework", v14. - -What's new -========== -1. OpenWrt, in addition to Android, Arch Linux Zen, Armbian, ChromeOS, - Liquorix, post-factum and XanMod, is now shipping MGLRU on 5.15. -2. Fixed long-tailed direct reclaim latency seen on high-memory (TBs) - machines. The old direct reclaim backoff, which tries to enforce a - minimum fairness among all eligible memcgs, over-swapped by about - (total_mem>>DEF_PRIORITY)-nr_to_reclaim. The new backoff, which - pulls the plug on swapping once the target is met, trades some - fairness for curtailed latency: - https://lore.kernel.org/r/20220918080010.2920238-10-yuzhao@google.com/ -3. Fixed minior build warnings and conflicts. More comments and nits. - -TLDR -==== -The current page reclaim is too expensive in terms of CPU usage and it -often makes poor choices about what to evict. This patchset offers an -alternative solution that is performant, versatile and -straightforward. - -Patchset overview -================= -The design and implementation overview is in patch 14: -https://lore.kernel.org/r/20220918080010.2920238-15-yuzhao@google.com/ - -01. mm: x86, arm64: add arch_has_hw_pte_young() -02. mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG -Take advantage of hardware features when trying to clear the accessed -bit in many PTEs. - -03. mm/vmscan.c: refactor shrink_node() -04. Revert "include/linux/mm_inline.h: fold __update_lru_size() into - its sole caller" -Minor refactors to improve readability for the following patches. - -05. mm: multi-gen LRU: groundwork -Adds the basic data structure and the functions that insert pages to -and remove pages from the multi-gen LRU (MGLRU) lists. - -06. mm: multi-gen LRU: minimal implementation -A minimal implementation without optimizations. - -07. mm: multi-gen LRU: exploit locality in rmap -Exploits spatial locality to improve efficiency when using the rmap. - -08. mm: multi-gen LRU: support page table walks -Further exploits spatial locality by optionally scanning page tables. - -09. mm: multi-gen LRU: optimize multiple memcgs -Optimizes the overall performance for multiple memcgs running mixed -types of workloads. - -10. mm: multi-gen LRU: kill switch -Adds a kill switch to enable or disable MGLRU at runtime. - -11. mm: multi-gen LRU: thrashing prevention -12. mm: multi-gen LRU: debugfs interface -Provide userspace with features like thrashing prevention, working set -estimation and proactive reclaim. - -13. mm: multi-gen LRU: admin guide -14. mm: multi-gen LRU: design doc -Add an admin guide and a design doc. - -Benchmark results -================= -Independent lab results ------------------------ -Based on the popularity of searches [01] and the memory usage in -Google's public cloud, the most popular open-source memory-hungry -applications, in alphabetical order, are: - Apache Cassandra Memcached - Apache Hadoop MongoDB - Apache Spark PostgreSQL - MariaDB (MySQL) Redis - -An independent lab evaluated MGLRU with the most widely used benchmark -suites for the above applications. They posted 960 data points along -with kernel metrics and perf profiles collected over more than 500 -hours of total benchmark time. Their final reports show that, with 95% -confidence intervals (CIs), the above applications all performed -significantly better for at least part of their benchmark matrices. - -On 5.14: -1. Apache Spark [02] took 95% CIs [9.28, 11.19]% and [12.20, 14.93]% - less wall time to sort three billion random integers, respectively, - under the medium- and the high-concurrency conditions, when - overcommitting memory. There were no statistically significant - changes in wall time for the rest of the benchmark matrix. -2. MariaDB [03] achieved 95% CIs [5.24, 10.71]% and [20.22, 25.97]% - more transactions per minute (TPM), respectively, under the medium- - and the high-concurrency conditions, when overcommitting memory. - There were no statistically significant changes in TPM for the rest - of the benchmark matrix. -3. Memcached [04] achieved 95% CIs [23.54, 32.25]%, [20.76, 41.61]% - and [21.59, 30.02]% more operations per second (OPS), respectively, - for sequential access, random access and Gaussian (distribution) - access, when THP=always; 95% CIs [13.85, 15.97]% and - [23.94, 29.92]% more OPS, respectively, for random access and - Gaussian access, when THP=never. There were no statistically - significant changes in OPS for the rest of the benchmark matrix. -4. MongoDB [05] achieved 95% CIs [2.23, 3.44]%, [6.97, 9.73]% and - [2.16, 3.55]% more operations per second (OPS), respectively, for - exponential (distribution) access, random access and Zipfian - (distribution) access, when underutilizing memory; 95% CIs - [8.83, 10.03]%, [21.12, 23.14]% and [5.53, 6.46]% more OPS, - respectively, for exponential access, random access and Zipfian - access, when overcommitting memory. - -On 5.15: -5. Apache Cassandra [06] achieved 95% CIs [1.06, 4.10]%, [1.94, 5.43]% - and [4.11, 7.50]% more operations per second (OPS), respectively, - for exponential (distribution) access, random access and Zipfian - (distribution) access, when swap was off; 95% CIs [0.50, 2.60]%, - [6.51, 8.77]% and [3.29, 6.75]% more OPS, respectively, for - exponential access, random access and Zipfian access, when swap was - on. -6. Apache Hadoop [07] took 95% CIs [5.31, 9.69]% and [2.02, 7.86]% - less average wall time to finish twelve parallel TeraSort jobs, - respectively, under the medium- and the high-concurrency - conditions, when swap was on. There were no statistically - significant changes in average wall time for the rest of the - benchmark matrix. -7. PostgreSQL [08] achieved 95% CI [1.75, 6.42]% more transactions per - minute (TPM) under the high-concurrency condition, when swap was - off; 95% CIs [12.82, 18.69]% and [22.70, 46.86]% more TPM, - respectively, under the medium- and the high-concurrency - conditions, when swap was on. There were no statistically - significant changes in TPM for the rest of the benchmark matrix. -8. Redis [09] achieved 95% CIs [0.58, 5.94]%, [6.55, 14.58]% and - [11.47, 19.36]% more total operations per second (OPS), - respectively, for sequential access, random access and Gaussian - (distribution) access, when THP=always; 95% CIs [1.27, 3.54]%, - [10.11, 14.81]% and [8.75, 13.64]% more total OPS, respectively, - for sequential access, random access and Gaussian access, when - THP=never. - -Our lab results ---------------- -To supplement the above results, we ran the following benchmark suites -on 5.16-rc7 and found no regressions [10]. - fs_fio_bench_hdd_mq pft - fs_lmbench pgsql-hammerdb - fs_parallelio redis - fs_postmark stream - hackbench sysbenchthread - kernbench tpcc_spark - memcached unixbench - multichase vm-scalability - mutilate will-it-scale - nginx - -[01] https://trends.google.com -[02] https://lore.kernel.org/r/20211102002002.92051-1-bot@edi.works/ -[03] https://lore.kernel.org/r/20211009054315.47073-1-bot@edi.works/ -[04] https://lore.kernel.org/r/20211021194103.65648-1-bot@edi.works/ -[05] https://lore.kernel.org/r/20211109021346.50266-1-bot@edi.works/ -[06] https://lore.kernel.org/r/20211202062806.80365-1-bot@edi.works/ -[07] https://lore.kernel.org/r/20211209072416.33606-1-bot@edi.works/ -[08] https://lore.kernel.org/r/20211218071041.24077-1-bot@edi.works/ -[09] https://lore.kernel.org/r/20211122053248.57311-1-bot@edi.works/ -[10] https://lore.kernel.org/r/20220104202247.2903702-1-yuzhao@google.com/ - -Read-world applications -======================= -Third-party testimonials ------------------------- -Konstantin reported [11]: - I have Archlinux with 8G RAM + zswap + swap. While developing, I - have lots of apps opened such as multiple LSP-servers for different - langs, chats, two browsers, etc... Usually, my system gets quickly - to a point of SWAP-storms, where I have to kill LSP-servers, - restart browsers to free memory, etc, otherwise the system lags - heavily and is barely usable. - - 1.5 day ago I migrated from 5.11.15 kernel to 5.12 + the LRU - patchset, and I started up by opening lots of apps to create memory - pressure, and worked for a day like this. Till now I had not a - single SWAP-storm, and mind you I got 3.4G in SWAP. I was never - getting to the point of 3G in SWAP before without a single - SWAP-storm. - -Vaibhav from IBM reported [12]: - In a synthetic MongoDB Benchmark, seeing an average of ~19% - throughput improvement on POWER10(Radix MMU + 64K Page Size) with - MGLRU patches on top of 5.16 kernel for MongoDB + YCSB across - three different request distributions, namely, Exponential, Uniform - and Zipfan. - -Shuang from U of Rochester reported [13]: - With the MGLRU, fio achieved 95% CIs [38.95, 40.26]%, [4.12, 6.64]% - and [9.26, 10.36]% higher throughput, respectively, for random - access, Zipfian (distribution) access and Gaussian (distribution) - access, when the average number of jobs per CPU is 1; 95% CIs - [42.32, 49.15]%, [9.44, 9.89]% and [20.99, 22.86]% higher - throughput, respectively, for random access, Zipfian access and - Gaussian access, when the average number of jobs per CPU is 2. - -Daniel from Michigan Tech reported [14]: - With Memcached allocating ~100GB of byte-addressable Optante, - performance improvement in terms of throughput (measured as queries - per second) was about 10% for a series of workloads. - -Large-scale deployments ------------------------ -We've rolled out MGLRU to tens of millions of ChromeOS users and -about a million Android users. Google's fleetwide profiling [15] shows -an overall 40% decrease in kswapd CPU usage, in addition to -improvements in other UX metrics, e.g., an 85% decrease in the number -of low-memory kills at the 75th percentile and an 18% decrease in -app launch time at the 50th percentile. - -The downstream kernels that have been using MGLRU include: -1. Android [16] -2. Arch Linux Zen [17] -3. Armbian [18] -4. ChromeOS [19] -5. Liquorix [20] -6. OpenWrt [21] -7. post-factum [22] -8. XanMod [23] - -[11] https://lore.kernel.org/r/140226722f2032c86301fbd326d91baefe3d7d23.camel@yandex.ru/ -[12] https://lore.kernel.org/r/87czj3mux0.fsf@vajain21.in.ibm.com/ -[13] https://lore.kernel.org/r/20220105024423.26409-1-szhai2@cs.rochester.edu/ -[14] https://lore.kernel.org/r/CA+4-3vksGvKd18FgRinxhqHetBS1hQekJE2gwco8Ja-bJWKtFw@mail.gmail.com/ -[15] https://dl.acm.org/doi/10.1145/2749469.2750392 -[16] https://android.com -[17] https://archlinux.org -[18] https://armbian.com -[19] https://chromium.org -[20] https://liquorix.net -[21] https://openwrt.org -[22] https://codeberg.org/pf-kernel -[23] https://xanmod.org - -Summary -======= -The facts are: -1. The independent lab results and the real-world applications - indicate substantial improvements; there are no known regressions. -2. Thrashing prevention, working set estimation and proactive reclaim - work out of the box; there are no equivalent solutions. -3. There is a lot of new code; no smaller changes have been - demonstrated similar effects. - -Our options, accordingly, are: -1. Given the amount of evidence, the reported improvements will likely - materialize for a wide range of workloads. -2. Gauging the interest from the past discussions, the new features - will likely be put to use for both personal computers and data - centers. -3. Based on Google's track record, the new code will likely be well - maintained in the long term. It'd be more difficult if not - impossible to achieve similar effects with other approaches. - -This patch (of 14): - -Some architectures automatically set the accessed bit in PTEs, e.g., x86 -and arm64 v8.2. On architectures that do not have this capability, -clearing the accessed bit in a PTE usually triggers a page fault following -the TLB miss of this PTE (to emulate the accessed bit). - -Being aware of this capability can help make better decisions, e.g., -whether to spread the work out over a period of time to reduce bursty page -faults when trying to clear the accessed bit in many PTEs. - -Note that theoretically this capability can be unreliable, e.g., -hotplugged CPUs might be different from builtin ones. Therefore it should -not be used in architecture-independent code that involves correctness, -e.g., to determine whether TLB flushes are required (in combination with -the accessed bit). - -Link: https://lkml.kernel.org/r/20220918080010.2920238-1-yuzhao@google.com -Link: https://lkml.kernel.org/r/20220918080010.2920238-2-yuzhao@google.com -Signed-off-by: Yu Zhao -Reviewed-by: Barry Song -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Acked-by: Will Deacon -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: linux-arm-kernel@lists.infradead.org -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Miaohe Lin -Cc: Mike Rapoport -Cc: Qi Zheng -Signed-off-by: Andrew Morton ---- - arch/arm64/include/asm/pgtable.h | 14 ++------------ - arch/x86/include/asm/pgtable.h | 6 +++--- - include/linux/pgtable.h | 13 +++++++++++++ - mm/memory.c | 14 +------------- - 4 files changed, 19 insertions(+), 28 deletions(-) - ---- a/arch/arm64/include/asm/pgtable.h -+++ b/arch/arm64/include/asm/pgtable.h -@@ -1005,23 +1005,13 @@ static inline void update_mmu_cache(stru - * page after fork() + CoW for pfn mappings. We don't always have a - * hardware-managed access flag on arm64. - */ --static inline bool arch_faults_on_old_pte(void) --{ -- WARN_ON(preemptible()); -- -- return !cpu_has_hw_af(); --} --#define arch_faults_on_old_pte arch_faults_on_old_pte -+#define arch_has_hw_pte_young cpu_has_hw_af - - /* - * Experimentally, it's cheap to set the access flag in hardware and we - * benefit from prefaulting mappings as 'old' to start with. - */ --static inline bool arch_wants_old_prefaulted_pte(void) --{ -- return !arch_faults_on_old_pte(); --} --#define arch_wants_old_prefaulted_pte arch_wants_old_prefaulted_pte -+#define arch_wants_old_prefaulted_pte cpu_has_hw_af - - #endif /* !__ASSEMBLY__ */ - ---- a/arch/x86/include/asm/pgtable.h -+++ b/arch/x86/include/asm/pgtable.h -@@ -1397,10 +1397,10 @@ static inline bool arch_has_pfn_modify_c - return boot_cpu_has_bug(X86_BUG_L1TF); - } - --#define arch_faults_on_old_pte arch_faults_on_old_pte --static inline bool arch_faults_on_old_pte(void) -+#define arch_has_hw_pte_young arch_has_hw_pte_young -+static inline bool arch_has_hw_pte_young(void) - { -- return false; -+ return true; - } - - #endif /* __ASSEMBLY__ */ ---- a/include/linux/pgtable.h -+++ b/include/linux/pgtable.h -@@ -259,6 +259,19 @@ static inline int pmdp_clear_flush_young - #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ - #endif - -+#ifndef arch_has_hw_pte_young -+/* -+ * Return whether the accessed bit is supported on the local CPU. -+ * -+ * This stub assumes accessing through an old PTE triggers a page fault. -+ * Architectures that automatically set the access bit should overwrite it. -+ */ -+static inline bool arch_has_hw_pte_young(void) -+{ -+ return false; -+} -+#endif -+ - #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR - static inline pte_t ptep_get_and_clear(struct mm_struct *mm, - unsigned long address, ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -121,18 +121,6 @@ int randomize_va_space __read_mostly = - 2; - #endif - --#ifndef arch_faults_on_old_pte --static inline bool arch_faults_on_old_pte(void) --{ -- /* -- * Those arches which don't have hw access flag feature need to -- * implement their own helper. By default, "true" means pagefault -- * will be hit on old pte. -- */ -- return true; --} --#endif -- - #ifndef arch_wants_old_prefaulted_pte - static inline bool arch_wants_old_prefaulted_pte(void) - { -@@ -2791,7 +2779,7 @@ static inline int cow_user_page(struct p - * On architectures with software "accessed" bits, we would - * take a double page fault, so mark it accessed here. - */ -- if (arch_faults_on_old_pte() && !pte_young(vmf->orig_pte)) { -+ if (!arch_has_hw_pte_young() && !pte_young(vmf->orig_pte)) { - pte_t entry; - - vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl); diff --git a/target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch b/target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch deleted file mode 100644 index 8e4de36db07c6f..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-02-mm-x86-add-CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 493de1c4b0f2cd909169401da8c445f6c8a7e29d Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 01:59:59 -0600 -Subject: [PATCH 02/29] mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some architectures support the accessed bit in non-leaf PMD entries, e.g., -x86 sets the accessed bit in a non-leaf PMD entry when using it as part of -linear address translation [1]. Page table walkers that clear the -accessed bit may use this capability to reduce their search space. - -Note that: -1. Although an inline function is preferable, this capability is added - as a configuration option for consistency with the existing macros. -2. Due to the little interest in other varieties, this capability was - only tested on Intel and AMD CPUs. - -Thanks to the following developers for their efforts [2][3]. - Randy Dunlap - Stephen Rothwell - -[1]: Intel 64 and IA-32 Architectures Software Developer's Manual - Volume 3 (June 2021), section 4.8 -[2] https://lore.kernel.org/r/bfdcc7c8-922f-61a9-aa15-7e7250f04af7@infradead.org/ -[3] https://lore.kernel.org/r/20220413151513.5a0d7a7e@canb.auug.org.au/ - -Link: https://lkml.kernel.org/r/20220918080010.2920238-3-yuzhao@google.com -Signed-off-by: Yu Zhao -Reviewed-by: Barry Song -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Miaohe Lin -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Qi Zheng -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - arch/Kconfig | 8 ++++++++ - arch/x86/Kconfig | 1 + - arch/x86/include/asm/pgtable.h | 3 ++- - arch/x86/mm/pgtable.c | 5 ++++- - include/linux/pgtable.h | 4 ++-- - 5 files changed, 17 insertions(+), 4 deletions(-) - ---- a/arch/Kconfig -+++ b/arch/Kconfig -@@ -1307,6 +1307,14 @@ config ARCH_HAS_ELFCORE_COMPAT - config ARCH_HAS_PARANOID_L1D_FLUSH - bool - -+config ARCH_HAS_NONLEAF_PMD_YOUNG -+ bool -+ help -+ Architectures that select this option are capable of setting the -+ accessed bit in non-leaf PMD entries when using them as part of linear -+ address translations. Page table walkers that clear the accessed bit -+ may use this capability to reduce their search space. -+ - source "kernel/gcov/Kconfig" - - source "scripts/gcc-plugins/Kconfig" ---- a/arch/x86/Kconfig -+++ b/arch/x86/Kconfig -@@ -86,6 +86,7 @@ config X86 - select ARCH_HAS_PMEM_API if X86_64 - select ARCH_HAS_PTE_DEVMAP if X86_64 - select ARCH_HAS_PTE_SPECIAL -+ select ARCH_HAS_NONLEAF_PMD_YOUNG if PGTABLE_LEVELS > 2 - select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 - select ARCH_HAS_COPY_MC if X86_64 - select ARCH_HAS_SET_MEMORY ---- a/arch/x86/include/asm/pgtable.h -+++ b/arch/x86/include/asm/pgtable.h -@@ -817,7 +817,8 @@ static inline unsigned long pmd_page_vad - - static inline int pmd_bad(pmd_t pmd) - { -- return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE; -+ return (pmd_flags(pmd) & ~(_PAGE_USER | _PAGE_ACCESSED)) != -+ (_KERNPG_TABLE & ~_PAGE_ACCESSED); - } - - static inline unsigned long pages_to_mb(unsigned long npg) ---- a/arch/x86/mm/pgtable.c -+++ b/arch/x86/mm/pgtable.c -@@ -550,7 +550,7 @@ int ptep_test_and_clear_young(struct vm_ - return ret; - } - --#ifdef CONFIG_TRANSPARENT_HUGEPAGE -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) - int pmdp_test_and_clear_young(struct vm_area_struct *vma, - unsigned long addr, pmd_t *pmdp) - { -@@ -562,6 +562,9 @@ int pmdp_test_and_clear_young(struct vm_ - - return ret; - } -+#endif -+ -+#ifdef CONFIG_TRANSPARENT_HUGEPAGE - int pudp_test_and_clear_young(struct vm_area_struct *vma, - unsigned long addr, pud_t *pudp) - { ---- a/include/linux/pgtable.h -+++ b/include/linux/pgtable.h -@@ -212,7 +212,7 @@ static inline int ptep_test_and_clear_yo - #endif - - #ifndef __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG --#ifdef CONFIG_TRANSPARENT_HUGEPAGE -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) - static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, - unsigned long address, - pmd_t *pmdp) -@@ -233,7 +233,7 @@ static inline int pmdp_test_and_clear_yo - BUILD_BUG(); - return 0; - } --#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ -+#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG */ - #endif - - #ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH diff --git a/target/linux/generic/backport-5.15/020-v6.1-03-mm-vmscan.c-refactor-shrink_node.patch b/target/linux/generic/backport-5.15/020-v6.1-03-mm-vmscan.c-refactor-shrink_node.patch deleted file mode 100644 index b8d2917d26cea8..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-03-mm-vmscan.c-refactor-shrink_node.patch +++ /dev/null @@ -1,275 +0,0 @@ -From 9e17efd11450d3d2069adaa3c58db9ac8ebd1c66 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 02:00:00 -0600 -Subject: [PATCH 03/29] mm/vmscan.c: refactor shrink_node() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch refactors shrink_node() to improve readability for the upcoming -changes to mm/vmscan.c. - -Link: https://lkml.kernel.org/r/20220918080010.2920238-4-yuzhao@google.com -Signed-off-by: Yu Zhao -Reviewed-by: Barry Song -Reviewed-by: Miaohe Lin -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Qi Zheng -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 198 +++++++++++++++++++++++++++------------------------- - 1 file changed, 104 insertions(+), 94 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -2497,6 +2497,109 @@ enum scan_balance { - SCAN_FILE, - }; - -+static void prepare_scan_count(pg_data_t *pgdat, struct scan_control *sc) -+{ -+ unsigned long file; -+ struct lruvec *target_lruvec; -+ -+ target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); -+ -+ /* -+ * Flush the memory cgroup stats, so that we read accurate per-memcg -+ * lruvec stats for heuristics. -+ */ -+ mem_cgroup_flush_stats(); -+ -+ /* -+ * Determine the scan balance between anon and file LRUs. -+ */ -+ spin_lock_irq(&target_lruvec->lru_lock); -+ sc->anon_cost = target_lruvec->anon_cost; -+ sc->file_cost = target_lruvec->file_cost; -+ spin_unlock_irq(&target_lruvec->lru_lock); -+ -+ /* -+ * Target desirable inactive:active list ratios for the anon -+ * and file LRU lists. -+ */ -+ if (!sc->force_deactivate) { -+ unsigned long refaults; -+ -+ refaults = lruvec_page_state(target_lruvec, -+ WORKINGSET_ACTIVATE_ANON); -+ if (refaults != target_lruvec->refaults[0] || -+ inactive_is_low(target_lruvec, LRU_INACTIVE_ANON)) -+ sc->may_deactivate |= DEACTIVATE_ANON; -+ else -+ sc->may_deactivate &= ~DEACTIVATE_ANON; -+ -+ /* -+ * When refaults are being observed, it means a new -+ * workingset is being established. Deactivate to get -+ * rid of any stale active pages quickly. -+ */ -+ refaults = lruvec_page_state(target_lruvec, -+ WORKINGSET_ACTIVATE_FILE); -+ if (refaults != target_lruvec->refaults[1] || -+ inactive_is_low(target_lruvec, LRU_INACTIVE_FILE)) -+ sc->may_deactivate |= DEACTIVATE_FILE; -+ else -+ sc->may_deactivate &= ~DEACTIVATE_FILE; -+ } else -+ sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE; -+ -+ /* -+ * If we have plenty of inactive file pages that aren't -+ * thrashing, try to reclaim those first before touching -+ * anonymous pages. -+ */ -+ file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE); -+ if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE)) -+ sc->cache_trim_mode = 1; -+ else -+ sc->cache_trim_mode = 0; -+ -+ /* -+ * Prevent the reclaimer from falling into the cache trap: as -+ * cache pages start out inactive, every cache fault will tip -+ * the scan balance towards the file LRU. And as the file LRU -+ * shrinks, so does the window for rotation from references. -+ * This means we have a runaway feedback loop where a tiny -+ * thrashing file LRU becomes infinitely more attractive than -+ * anon pages. Try to detect this based on file LRU size. -+ */ -+ if (!cgroup_reclaim(sc)) { -+ unsigned long total_high_wmark = 0; -+ unsigned long free, anon; -+ int z; -+ -+ free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES); -+ file = node_page_state(pgdat, NR_ACTIVE_FILE) + -+ node_page_state(pgdat, NR_INACTIVE_FILE); -+ -+ for (z = 0; z < MAX_NR_ZONES; z++) { -+ struct zone *zone = &pgdat->node_zones[z]; -+ -+ if (!managed_zone(zone)) -+ continue; -+ -+ total_high_wmark += high_wmark_pages(zone); -+ } -+ -+ /* -+ * Consider anon: if that's low too, this isn't a -+ * runaway file reclaim problem, but rather just -+ * extreme pressure. Reclaim as per usual then. -+ */ -+ anon = node_page_state(pgdat, NR_INACTIVE_ANON); -+ -+ sc->file_is_tiny = -+ file + free <= total_high_wmark && -+ !(sc->may_deactivate & DEACTIVATE_ANON) && -+ anon >> sc->priority; -+ } -+} -+ - /* - * Determine how aggressively the anon and file LRU lists should be - * scanned. The relative value of each set of LRU lists is determined -@@ -2965,109 +3068,16 @@ static void shrink_node(pg_data_t *pgdat - unsigned long nr_reclaimed, nr_scanned; - struct lruvec *target_lruvec; - bool reclaimable = false; -- unsigned long file; - - target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); - - again: -- /* -- * Flush the memory cgroup stats, so that we read accurate per-memcg -- * lruvec stats for heuristics. -- */ -- mem_cgroup_flush_stats(); -- - memset(&sc->nr, 0, sizeof(sc->nr)); - - nr_reclaimed = sc->nr_reclaimed; - nr_scanned = sc->nr_scanned; - -- /* -- * Determine the scan balance between anon and file LRUs. -- */ -- spin_lock_irq(&target_lruvec->lru_lock); -- sc->anon_cost = target_lruvec->anon_cost; -- sc->file_cost = target_lruvec->file_cost; -- spin_unlock_irq(&target_lruvec->lru_lock); -- -- /* -- * Target desirable inactive:active list ratios for the anon -- * and file LRU lists. -- */ -- if (!sc->force_deactivate) { -- unsigned long refaults; -- -- refaults = lruvec_page_state(target_lruvec, -- WORKINGSET_ACTIVATE_ANON); -- if (refaults != target_lruvec->refaults[0] || -- inactive_is_low(target_lruvec, LRU_INACTIVE_ANON)) -- sc->may_deactivate |= DEACTIVATE_ANON; -- else -- sc->may_deactivate &= ~DEACTIVATE_ANON; -- -- /* -- * When refaults are being observed, it means a new -- * workingset is being established. Deactivate to get -- * rid of any stale active pages quickly. -- */ -- refaults = lruvec_page_state(target_lruvec, -- WORKINGSET_ACTIVATE_FILE); -- if (refaults != target_lruvec->refaults[1] || -- inactive_is_low(target_lruvec, LRU_INACTIVE_FILE)) -- sc->may_deactivate |= DEACTIVATE_FILE; -- else -- sc->may_deactivate &= ~DEACTIVATE_FILE; -- } else -- sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE; -- -- /* -- * If we have plenty of inactive file pages that aren't -- * thrashing, try to reclaim those first before touching -- * anonymous pages. -- */ -- file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE); -- if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE)) -- sc->cache_trim_mode = 1; -- else -- sc->cache_trim_mode = 0; -- -- /* -- * Prevent the reclaimer from falling into the cache trap: as -- * cache pages start out inactive, every cache fault will tip -- * the scan balance towards the file LRU. And as the file LRU -- * shrinks, so does the window for rotation from references. -- * This means we have a runaway feedback loop where a tiny -- * thrashing file LRU becomes infinitely more attractive than -- * anon pages. Try to detect this based on file LRU size. -- */ -- if (!cgroup_reclaim(sc)) { -- unsigned long total_high_wmark = 0; -- unsigned long free, anon; -- int z; -- -- free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES); -- file = node_page_state(pgdat, NR_ACTIVE_FILE) + -- node_page_state(pgdat, NR_INACTIVE_FILE); -- -- for (z = 0; z < MAX_NR_ZONES; z++) { -- struct zone *zone = &pgdat->node_zones[z]; -- if (!managed_zone(zone)) -- continue; -- -- total_high_wmark += high_wmark_pages(zone); -- } -- -- /* -- * Consider anon: if that's low too, this isn't a -- * runaway file reclaim problem, but rather just -- * extreme pressure. Reclaim as per usual then. -- */ -- anon = node_page_state(pgdat, NR_INACTIVE_ANON); -- -- sc->file_is_tiny = -- file + free <= total_high_wmark && -- !(sc->may_deactivate & DEACTIVATE_ANON) && -- anon >> sc->priority; -- } -+ prepare_scan_count(pgdat, sc); - - shrink_node_memcgs(pgdat, sc); - diff --git a/target/linux/generic/backport-5.15/020-v6.1-04-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch b/target/linux/generic/backport-5.15/020-v6.1-04-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch deleted file mode 100644 index 2f277a56e1c83f..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-04-Revert-include-linux-mm_inline.h-fold-__update_lru_s.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 03705be42114db7cc5bd6eb7bf7e8703c94d4880 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 02:00:01 -0600 -Subject: [PATCH 04/29] Revert "include/linux/mm_inline.h: fold - __update_lru_size() into its sole caller" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch undoes the following refactor: commit 289ccba18af4 -("include/linux/mm_inline.h: fold __update_lru_size() into its sole -caller") - -The upcoming changes to include/linux/mm_inline.h will reuse -__update_lru_size(). - -Link: https://lkml.kernel.org/r/20220918080010.2920238-5-yuzhao@google.com -Signed-off-by: Yu Zhao -Reviewed-by: Miaohe Lin -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Barry Song -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Qi Zheng -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - include/linux/mm_inline.h | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -24,7 +24,7 @@ static inline int page_is_file_lru(struc - return !PageSwapBacked(page); - } - --static __always_inline void update_lru_size(struct lruvec *lruvec, -+static __always_inline void __update_lru_size(struct lruvec *lruvec, - enum lru_list lru, enum zone_type zid, - int nr_pages) - { -@@ -33,6 +33,13 @@ static __always_inline void update_lru_s - __mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages); - __mod_zone_page_state(&pgdat->node_zones[zid], - NR_ZONE_LRU_BASE + lru, nr_pages); -+} -+ -+static __always_inline void update_lru_size(struct lruvec *lruvec, -+ enum lru_list lru, enum zone_type zid, -+ long nr_pages) -+{ -+ __update_lru_size(lruvec, lru, zid, nr_pages); - #ifdef CONFIG_MEMCG - mem_cgroup_update_lru_size(lruvec, lru, zid, nr_pages); - #endif diff --git a/target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch b/target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch deleted file mode 100644 index ff4bb4df3e7ea0..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-05-mm-multi-gen-LRU-groundwork.patch +++ /dev/null @@ -1,807 +0,0 @@ -From a9b328add8422921a0dbbef162730800e16e8cfd Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 02:00:02 -0600 -Subject: [PATCH 05/29] mm: multi-gen LRU: groundwork -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Evictable pages are divided into multiple generations for each lruvec. -The youngest generation number is stored in lrugen->max_seq for both -anon and file types as they are aged on an equal footing. The oldest -generation numbers are stored in lrugen->min_seq[] separately for anon -and file types as clean file pages can be evicted regardless of swap -constraints. These three variables are monotonically increasing. - -Generation numbers are truncated into order_base_2(MAX_NR_GENS+1) bits -in order to fit into the gen counter in page->flags. Each truncated -generation number is an index to lrugen->lists[]. The sliding window -technique is used to track at least MIN_NR_GENS and at most -MAX_NR_GENS generations. The gen counter stores a value within [1, -MAX_NR_GENS] while a page is on one of lrugen->lists[]. Otherwise it -stores 0. - -There are two conceptually independent procedures: "the aging", which -produces young generations, and "the eviction", which consumes old -generations. They form a closed-loop system, i.e., "the page reclaim". -Both procedures can be invoked from userspace for the purposes of working -set estimation and proactive reclaim. These techniques are commonly used -to optimize job scheduling (bin packing) in data centers [1][2]. - -To avoid confusion, the terms "hot" and "cold" will be applied to the -multi-gen LRU, as a new convention; the terms "active" and "inactive" will -be applied to the active/inactive LRU, as usual. - -The protection of hot pages and the selection of cold pages are based -on page access channels and patterns. There are two access channels: -one through page tables and the other through file descriptors. The -protection of the former channel is by design stronger because: -1. The uncertainty in determining the access patterns of the former - channel is higher due to the approximation of the accessed bit. -2. The cost of evicting the former channel is higher due to the TLB - flushes required and the likelihood of encountering the dirty bit. -3. The penalty of underprotecting the former channel is higher because - applications usually do not prepare themselves for major page - faults like they do for blocked I/O. E.g., GUI applications - commonly use dedicated I/O threads to avoid blocking rendering - threads. - -There are also two access patterns: one with temporal locality and the -other without. For the reasons listed above, the former channel is -assumed to follow the former pattern unless VM_SEQ_READ or VM_RAND_READ is -present; the latter channel is assumed to follow the latter pattern unless -outlying refaults have been observed [3][4]. - -The next patch will address the "outlying refaults". Three macros, i.e., -LRU_REFS_WIDTH, LRU_REFS_PGOFF and LRU_REFS_MASK, used later are added in -this patch to make the entire patchset less diffy. - -A page is added to the youngest generation on faulting. The aging needs -to check the accessed bit at least twice before handing this page over to -the eviction. The first check takes care of the accessed bit set on the -initial fault; the second check makes sure this page has not been used -since then. This protocol, AKA second chance, requires a minimum of two -generations, hence MIN_NR_GENS. - -[1] https://dl.acm.org/doi/10.1145/3297858.3304053 -[2] https://dl.acm.org/doi/10.1145/3503222.3507731 -[3] https://lwn.net/Articles/495543/ -[4] https://lwn.net/Articles/815342/ - -Link: https://lkml.kernel.org/r/20220918080010.2920238-6-yuzhao@google.com -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Barry Song -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Miaohe Lin -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Qi Zheng -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - fs/fuse/dev.c | 3 +- - include/linux/mm.h | 2 + - include/linux/mm_inline.h | 177 +++++++++++++++++++++++++++++- - include/linux/mmzone.h | 100 +++++++++++++++++ - include/linux/page-flags-layout.h | 13 ++- - include/linux/page-flags.h | 4 +- - include/linux/sched.h | 4 + - kernel/bounds.c | 5 + - mm/Kconfig | 8 ++ - mm/huge_memory.c | 3 +- - mm/memcontrol.c | 2 + - mm/memory.c | 25 +++++ - mm/mm_init.c | 6 +- - mm/mmzone.c | 2 + - mm/swap.c | 10 +- - mm/vmscan.c | 75 +++++++++++++ - 16 files changed, 425 insertions(+), 14 deletions(-) - ---- a/fs/fuse/dev.c -+++ b/fs/fuse/dev.c -@@ -785,7 +785,8 @@ static int fuse_check_page(struct page * - 1 << PG_active | - 1 << PG_workingset | - 1 << PG_reclaim | -- 1 << PG_waiters))) { -+ 1 << PG_waiters | -+ LRU_GEN_MASK | LRU_REFS_MASK))) { - dump_page(page, "fuse: trying to steal weird page"); - return 1; - } ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1093,6 +1093,8 @@ vm_fault_t finish_mkwrite_fault(struct v - #define ZONES_PGOFF (NODES_PGOFF - ZONES_WIDTH) - #define LAST_CPUPID_PGOFF (ZONES_PGOFF - LAST_CPUPID_WIDTH) - #define KASAN_TAG_PGOFF (LAST_CPUPID_PGOFF - KASAN_TAG_WIDTH) -+#define LRU_GEN_PGOFF (KASAN_TAG_PGOFF - LRU_GEN_WIDTH) -+#define LRU_REFS_PGOFF (LRU_GEN_PGOFF - LRU_REFS_WIDTH) - - /* - * Define the bit shifts to access each section. For non-existent ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -26,10 +26,13 @@ static inline int page_is_file_lru(struc - - static __always_inline void __update_lru_size(struct lruvec *lruvec, - enum lru_list lru, enum zone_type zid, -- int nr_pages) -+ long nr_pages) - { - struct pglist_data *pgdat = lruvec_pgdat(lruvec); - -+ lockdep_assert_held(&lruvec->lru_lock); -+ WARN_ON_ONCE(nr_pages != (int)nr_pages); -+ - __mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages); - __mod_zone_page_state(&pgdat->node_zones[zid], - NR_ZONE_LRU_BASE + lru, nr_pages); -@@ -86,11 +89,177 @@ static __always_inline enum lru_list pag - return lru; - } - -+#ifdef CONFIG_LRU_GEN -+ -+static inline bool lru_gen_enabled(void) -+{ -+ return true; -+} -+ -+static inline bool lru_gen_in_fault(void) -+{ -+ return current->in_lru_fault; -+} -+ -+static inline int lru_gen_from_seq(unsigned long seq) -+{ -+ return seq % MAX_NR_GENS; -+} -+ -+static inline int page_lru_gen(struct page *page) -+{ -+ unsigned long flags = READ_ONCE(page->flags); -+ -+ return ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+} -+ -+static inline bool lru_gen_is_active(struct lruvec *lruvec, int gen) -+{ -+ unsigned long max_seq = lruvec->lrugen.max_seq; -+ -+ VM_WARN_ON_ONCE(gen >= MAX_NR_GENS); -+ -+ /* see the comment on MIN_NR_GENS */ -+ return gen == lru_gen_from_seq(max_seq) || gen == lru_gen_from_seq(max_seq - 1); -+} -+ -+static inline void lru_gen_update_size(struct lruvec *lruvec, struct page *page, -+ int old_gen, int new_gen) -+{ -+ int type = page_is_file_lru(page); -+ int zone = page_zonenum(page); -+ int delta = thp_nr_pages(page); -+ enum lru_list lru = type * LRU_INACTIVE_FILE; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS); -+ VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS); -+ VM_WARN_ON_ONCE(old_gen == -1 && new_gen == -1); -+ -+ if (old_gen >= 0) -+ WRITE_ONCE(lrugen->nr_pages[old_gen][type][zone], -+ lrugen->nr_pages[old_gen][type][zone] - delta); -+ if (new_gen >= 0) -+ WRITE_ONCE(lrugen->nr_pages[new_gen][type][zone], -+ lrugen->nr_pages[new_gen][type][zone] + delta); -+ -+ /* addition */ -+ if (old_gen < 0) { -+ if (lru_gen_is_active(lruvec, new_gen)) -+ lru += LRU_ACTIVE; -+ __update_lru_size(lruvec, lru, zone, delta); -+ return; -+ } -+ -+ /* deletion */ -+ if (new_gen < 0) { -+ if (lru_gen_is_active(lruvec, old_gen)) -+ lru += LRU_ACTIVE; -+ __update_lru_size(lruvec, lru, zone, -delta); -+ return; -+ } -+} -+ -+static inline bool lru_gen_add_page(struct lruvec *lruvec, struct page *page, bool reclaiming) -+{ -+ unsigned long seq; -+ unsigned long flags; -+ int gen = page_lru_gen(page); -+ int type = page_is_file_lru(page); -+ int zone = page_zonenum(page); -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ VM_WARN_ON_ONCE_PAGE(gen != -1, page); -+ -+ if (PageUnevictable(page)) -+ return false; -+ /* -+ * There are three common cases for this page: -+ * 1. If it's hot, e.g., freshly faulted in or previously hot and -+ * migrated, add it to the youngest generation. -+ * 2. If it's cold but can't be evicted immediately, i.e., an anon page -+ * not in swapcache or a dirty page pending writeback, add it to the -+ * second oldest generation. -+ * 3. Everything else (clean, cold) is added to the oldest generation. -+ */ -+ if (PageActive(page)) -+ seq = lrugen->max_seq; -+ else if ((type == LRU_GEN_ANON && !PageSwapCache(page)) || -+ (PageReclaim(page) && -+ (PageDirty(page) || PageWriteback(page)))) -+ seq = lrugen->min_seq[type] + 1; -+ else -+ seq = lrugen->min_seq[type]; -+ -+ gen = lru_gen_from_seq(seq); -+ flags = (gen + 1UL) << LRU_GEN_PGOFF; -+ /* see the comment on MIN_NR_GENS about PG_active */ -+ set_mask_bits(&page->flags, LRU_GEN_MASK | BIT(PG_active), flags); -+ -+ lru_gen_update_size(lruvec, page, -1, gen); -+ /* for rotate_reclaimable_page() */ -+ if (reclaiming) -+ list_add_tail(&page->lru, &lrugen->lists[gen][type][zone]); -+ else -+ list_add(&page->lru, &lrugen->lists[gen][type][zone]); -+ -+ return true; -+} -+ -+static inline bool lru_gen_del_page(struct lruvec *lruvec, struct page *page, bool reclaiming) -+{ -+ unsigned long flags; -+ int gen = page_lru_gen(page); -+ -+ if (gen < 0) -+ return false; -+ -+ VM_WARN_ON_ONCE_PAGE(PageActive(page), page); -+ VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page); -+ -+ /* for migrate_page_states() */ -+ flags = !reclaiming && lru_gen_is_active(lruvec, gen) ? BIT(PG_active) : 0; -+ flags = set_mask_bits(&page->flags, LRU_GEN_MASK, flags); -+ gen = ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+ -+ lru_gen_update_size(lruvec, page, gen, -1); -+ list_del(&page->lru); -+ -+ return true; -+} -+ -+#else /* !CONFIG_LRU_GEN */ -+ -+static inline bool lru_gen_enabled(void) -+{ -+ return false; -+} -+ -+static inline bool lru_gen_in_fault(void) -+{ -+ return false; -+} -+ -+static inline bool lru_gen_add_page(struct lruvec *lruvec, struct page *page, bool reclaiming) -+{ -+ return false; -+} -+ -+static inline bool lru_gen_del_page(struct lruvec *lruvec, struct page *page, bool reclaiming) -+{ -+ return false; -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - static __always_inline void add_page_to_lru_list(struct page *page, - struct lruvec *lruvec) - { - enum lru_list lru = page_lru(page); - -+ if (lru_gen_add_page(lruvec, page, false)) -+ return; -+ - update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page)); - list_add(&page->lru, &lruvec->lists[lru]); - } -@@ -100,6 +269,9 @@ static __always_inline void add_page_to_ - { - enum lru_list lru = page_lru(page); - -+ if (lru_gen_add_page(lruvec, page, true)) -+ return; -+ - update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page)); - list_add_tail(&page->lru, &lruvec->lists[lru]); - } -@@ -107,6 +279,9 @@ static __always_inline void add_page_to_ - static __always_inline void del_page_from_lru_list(struct page *page, - struct lruvec *lruvec) - { -+ if (lru_gen_del_page(lruvec, page, false)) -+ return; -+ - list_del(&page->lru); - update_lru_size(lruvec, page_lru(page), page_zonenum(page), - -thp_nr_pages(page)); ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -294,6 +294,102 @@ enum lruvec_flags { - */ - }; - -+#endif /* !__GENERATING_BOUNDS_H */ -+ -+/* -+ * Evictable pages are divided into multiple generations. The youngest and the -+ * oldest generation numbers, max_seq and min_seq, are monotonically increasing. -+ * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An -+ * offset within MAX_NR_GENS, i.e., gen, indexes the LRU list of the -+ * corresponding generation. The gen counter in page->flags stores gen+1 while -+ * a page is on one of lrugen->lists[]. Otherwise it stores 0. -+ * -+ * A page is added to the youngest generation on faulting. The aging needs to -+ * check the accessed bit at least twice before handing this page over to the -+ * eviction. The first check takes care of the accessed bit set on the initial -+ * fault; the second check makes sure this page hasn't been used since then. -+ * This process, AKA second chance, requires a minimum of two generations, -+ * hence MIN_NR_GENS. And to maintain ABI compatibility with the active/inactive -+ * LRU, e.g., /proc/vmstat, these two generations are considered active; the -+ * rest of generations, if they exist, are considered inactive. See -+ * lru_gen_is_active(). -+ * -+ * PG_active is always cleared while a page is on one of lrugen->lists[] so that -+ * the aging needs not to worry about it. And it's set again when a page -+ * considered active is isolated for non-reclaiming purposes, e.g., migration. -+ * See lru_gen_add_page() and lru_gen_del_page(). -+ * -+ * MAX_NR_GENS is set to 4 so that the multi-gen LRU can support twice the -+ * number of categories of the active/inactive LRU when keeping track of -+ * accesses through page tables. This requires order_base_2(MAX_NR_GENS+1) bits -+ * in page->flags. -+ */ -+#define MIN_NR_GENS 2U -+#define MAX_NR_GENS 4U -+ -+#ifndef __GENERATING_BOUNDS_H -+ -+struct lruvec; -+ -+#define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF) -+#define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF) -+ -+#ifdef CONFIG_LRU_GEN -+ -+enum { -+ LRU_GEN_ANON, -+ LRU_GEN_FILE, -+}; -+ -+/* -+ * The youngest generation number is stored in max_seq for both anon and file -+ * types as they are aged on an equal footing. The oldest generation numbers are -+ * stored in min_seq[] separately for anon and file types as clean file pages -+ * can be evicted regardless of swap constraints. -+ * -+ * Normally anon and file min_seq are in sync. But if swapping is constrained, -+ * e.g., out of swap space, file min_seq is allowed to advance and leave anon -+ * min_seq behind. -+ * -+ * The number of pages in each generation is eventually consistent and therefore -+ * can be transiently negative. -+ */ -+struct lru_gen_struct { -+ /* the aging increments the youngest generation number */ -+ unsigned long max_seq; -+ /* the eviction increments the oldest generation numbers */ -+ unsigned long min_seq[ANON_AND_FILE]; -+ /* the multi-gen LRU lists, lazily sorted on eviction */ -+ struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ /* the multi-gen LRU sizes, eventually consistent */ -+ long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+}; -+ -+void lru_gen_init_lruvec(struct lruvec *lruvec); -+ -+#ifdef CONFIG_MEMCG -+void lru_gen_init_memcg(struct mem_cgroup *memcg); -+void lru_gen_exit_memcg(struct mem_cgroup *memcg); -+#endif -+ -+#else /* !CONFIG_LRU_GEN */ -+ -+static inline void lru_gen_init_lruvec(struct lruvec *lruvec) -+{ -+} -+ -+#ifdef CONFIG_MEMCG -+static inline void lru_gen_init_memcg(struct mem_cgroup *memcg) -+{ -+} -+ -+static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg) -+{ -+} -+#endif -+ -+#endif /* CONFIG_LRU_GEN */ -+ - struct lruvec { - struct list_head lists[NR_LRU_LISTS]; - /* per lruvec lru_lock for memcg */ -@@ -311,6 +407,10 @@ struct lruvec { - unsigned long refaults[ANON_AND_FILE]; - /* Various lruvec state flags (enum lruvec_flags) */ - unsigned long flags; -+#ifdef CONFIG_LRU_GEN -+ /* evictable pages divided into generations */ -+ struct lru_gen_struct lrugen; -+#endif - #ifdef CONFIG_MEMCG - struct pglist_data *pgdat; - #endif ---- a/include/linux/page-flags-layout.h -+++ b/include/linux/page-flags-layout.h -@@ -55,7 +55,8 @@ - #define SECTIONS_WIDTH 0 - #endif - --#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS -+#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_SHIFT \ -+ <= BITS_PER_LONG - NR_PAGEFLAGS - #define NODES_WIDTH NODES_SHIFT - #elif defined(CONFIG_SPARSEMEM_VMEMMAP) - #error "Vmemmap: No space for nodes field in page flags" -@@ -89,8 +90,8 @@ - #define LAST_CPUPID_SHIFT 0 - #endif - --#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT \ -- <= BITS_PER_LONG - NR_PAGEFLAGS -+#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \ -+ KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS - #define LAST_CPUPID_WIDTH LAST_CPUPID_SHIFT - #else - #define LAST_CPUPID_WIDTH 0 -@@ -100,10 +101,12 @@ - #define LAST_CPUPID_NOT_IN_PAGE_FLAGS - #endif - --#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH \ -- > BITS_PER_LONG - NR_PAGEFLAGS -+#if ZONES_WIDTH + LRU_GEN_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \ -+ KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH > BITS_PER_LONG - NR_PAGEFLAGS - #error "Not enough bits in page flags" - #endif - -+#define LRU_REFS_WIDTH 0 -+ - #endif - #endif /* _LINUX_PAGE_FLAGS_LAYOUT */ ---- a/include/linux/page-flags.h -+++ b/include/linux/page-flags.h -@@ -845,7 +845,7 @@ static inline void ClearPageSlabPfmemall - 1UL << PG_private | 1UL << PG_private_2 | \ - 1UL << PG_writeback | 1UL << PG_reserved | \ - 1UL << PG_slab | 1UL << PG_active | \ -- 1UL << PG_unevictable | __PG_MLOCKED) -+ 1UL << PG_unevictable | __PG_MLOCKED | LRU_GEN_MASK) - - /* - * Flags checked when a page is prepped for return by the page allocator. -@@ -856,7 +856,7 @@ static inline void ClearPageSlabPfmemall - * alloc-free cycle to prevent from reusing the page. - */ - #define PAGE_FLAGS_CHECK_AT_PREP \ -- (PAGEFLAGS_MASK & ~__PG_HWPOISON) -+ ((PAGEFLAGS_MASK & ~__PG_HWPOISON) | LRU_GEN_MASK | LRU_REFS_MASK) - - #define PAGE_FLAGS_PRIVATE \ - (1UL << PG_private | 1UL << PG_private_2) ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -907,6 +907,10 @@ struct task_struct { - #ifdef CONFIG_MEMCG - unsigned in_user_fault:1; - #endif -+#ifdef CONFIG_LRU_GEN -+ /* whether the LRU algorithm may apply to this access */ -+ unsigned in_lru_fault:1; -+#endif - #ifdef CONFIG_COMPAT_BRK - unsigned brk_randomized:1; - #endif ---- a/kernel/bounds.c -+++ b/kernel/bounds.c -@@ -22,6 +22,11 @@ int main(void) - DEFINE(NR_CPUS_BITS, order_base_2(CONFIG_NR_CPUS)); - #endif - DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t)); -+#ifdef CONFIG_LRU_GEN -+ DEFINE(LRU_GEN_WIDTH, order_base_2(MAX_NR_GENS + 1)); -+#else -+ DEFINE(LRU_GEN_WIDTH, 0); -+#endif - /* End of constants */ - - return 0; ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -897,6 +897,14 @@ config IO_MAPPING - config SECRETMEM - def_bool ARCH_HAS_SET_DIRECT_MAP && !EMBEDDED - -+config LRU_GEN -+ bool "Multi-Gen LRU" -+ depends on MMU -+ # make sure page->flags has enough spare bits -+ depends on 64BIT || !SPARSEMEM || SPARSEMEM_VMEMMAP -+ help -+ A high performance LRU implementation to overcommit memory. -+ - source "mm/damon/Kconfig" - - endmenu ---- a/mm/huge_memory.c -+++ b/mm/huge_memory.c -@@ -2366,7 +2366,8 @@ static void __split_huge_page_tail(struc - #ifdef CONFIG_64BIT - (1L << PG_arch_2) | - #endif -- (1L << PG_dirty))); -+ (1L << PG_dirty) | -+ LRU_GEN_MASK | LRU_REFS_MASK)); - - /* ->mapping in first tail page is compound_mapcount */ - VM_BUG_ON_PAGE(tail > 2 && page_tail->mapping != TAIL_MAPPING, ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -5179,6 +5179,7 @@ static void __mem_cgroup_free(struct mem - - static void mem_cgroup_free(struct mem_cgroup *memcg) - { -+ lru_gen_exit_memcg(memcg); - memcg_wb_domain_exit(memcg); - __mem_cgroup_free(memcg); - } -@@ -5242,6 +5243,7 @@ static struct mem_cgroup *mem_cgroup_all - memcg->deferred_split_queue.split_queue_len = 0; - #endif - idr_replace(&mem_cgroup_idr, memcg, memcg->id.id); -+ lru_gen_init_memcg(memcg); - return memcg; - fail: - mem_cgroup_id_remove(memcg); ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -4805,6 +4805,27 @@ static inline void mm_account_fault(stru - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); - } - -+#ifdef CONFIG_LRU_GEN -+static void lru_gen_enter_fault(struct vm_area_struct *vma) -+{ -+ /* the LRU algorithm doesn't apply to sequential or random reads */ -+ current->in_lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)); -+} -+ -+static void lru_gen_exit_fault(void) -+{ -+ current->in_lru_fault = false; -+} -+#else -+static void lru_gen_enter_fault(struct vm_area_struct *vma) -+{ -+} -+ -+static void lru_gen_exit_fault(void) -+{ -+} -+#endif /* CONFIG_LRU_GEN */ -+ - /* - * By the time we get here, we already hold the mm semaphore - * -@@ -4836,11 +4857,15 @@ vm_fault_t handle_mm_fault(struct vm_are - if (flags & FAULT_FLAG_USER) - mem_cgroup_enter_user_fault(); - -+ lru_gen_enter_fault(vma); -+ - if (unlikely(is_vm_hugetlb_page(vma))) - ret = hugetlb_fault(vma->vm_mm, vma, address, flags); - else - ret = __handle_mm_fault(vma, address, flags); - -+ lru_gen_exit_fault(); -+ - if (flags & FAULT_FLAG_USER) { - mem_cgroup_exit_user_fault(); - /* ---- a/mm/mm_init.c -+++ b/mm/mm_init.c -@@ -65,14 +65,16 @@ void __init mminit_verify_pageflags_layo - - shift = 8 * sizeof(unsigned long); - width = shift - SECTIONS_WIDTH - NODES_WIDTH - ZONES_WIDTH -- - LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH; -+ - LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH - LRU_GEN_WIDTH - LRU_REFS_WIDTH; - mminit_dprintk(MMINIT_TRACE, "pageflags_layout_widths", -- "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Flags %d\n", -+ "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Gen %d Tier %d Flags %d\n", - SECTIONS_WIDTH, - NODES_WIDTH, - ZONES_WIDTH, - LAST_CPUPID_WIDTH, - KASAN_TAG_WIDTH, -+ LRU_GEN_WIDTH, -+ LRU_REFS_WIDTH, - NR_PAGEFLAGS); - mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts", - "Section %d Node %d Zone %d Lastcpupid %d Kasantag %d\n", ---- a/mm/mmzone.c -+++ b/mm/mmzone.c -@@ -81,6 +81,8 @@ void lruvec_init(struct lruvec *lruvec) - - for_each_lru(lru) - INIT_LIST_HEAD(&lruvec->lists[lru]); -+ -+ lru_gen_init_lruvec(lruvec); - } - - #if defined(CONFIG_NUMA_BALANCING) && !defined(LAST_CPUPID_NOT_IN_PAGE_FLAGS) ---- a/mm/swap.c -+++ b/mm/swap.c -@@ -446,6 +446,11 @@ void lru_cache_add(struct page *page) - VM_BUG_ON_PAGE(PageActive(page) && PageUnevictable(page), page); - VM_BUG_ON_PAGE(PageLRU(page), page); - -+ /* see the comment in lru_gen_add_page() */ -+ if (lru_gen_enabled() && !PageUnevictable(page) && -+ lru_gen_in_fault() && !(current->flags & PF_MEMALLOC)) -+ SetPageActive(page); -+ - get_page(page); - local_lock(&lru_pvecs.lock); - pvec = this_cpu_ptr(&lru_pvecs.lru_add); -@@ -547,7 +552,7 @@ static void lru_deactivate_file_fn(struc - - static void lru_deactivate_fn(struct page *page, struct lruvec *lruvec) - { -- if (PageActive(page) && !PageUnevictable(page)) { -+ if (!PageUnevictable(page) && (PageActive(page) || lru_gen_enabled())) { - int nr_pages = thp_nr_pages(page); - - del_page_from_lru_list(page, lruvec); -@@ -661,7 +666,8 @@ void deactivate_file_page(struct page *p - */ - void deactivate_page(struct page *page) - { -- if (PageLRU(page) && PageActive(page) && !PageUnevictable(page)) { -+ if (PageLRU(page) && !PageUnevictable(page) && -+ (PageActive(page) || lru_gen_enabled())) { - struct pagevec *pvec; - - local_lock(&lru_pvecs.lock); ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -2821,6 +2821,81 @@ static bool can_age_anon_pages(struct pg - return can_demote(pgdat->node_id, sc); - } - -+#ifdef CONFIG_LRU_GEN -+ -+/****************************************************************************** -+ * shorthand helpers -+ ******************************************************************************/ -+ -+#define for_each_gen_type_zone(gen, type, zone) \ -+ for ((gen) = 0; (gen) < MAX_NR_GENS; (gen)++) \ -+ for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ -+ for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++) -+ -+static struct lruvec __maybe_unused *get_lruvec(struct mem_cgroup *memcg, int nid) -+{ -+ struct pglist_data *pgdat = NODE_DATA(nid); -+ -+#ifdef CONFIG_MEMCG -+ if (memcg) { -+ struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec; -+ -+ /* for hotadd_new_pgdat() */ -+ if (!lruvec->pgdat) -+ lruvec->pgdat = pgdat; -+ -+ return lruvec; -+ } -+#endif -+ VM_WARN_ON_ONCE(!mem_cgroup_disabled()); -+ -+ return pgdat ? &pgdat->__lruvec : NULL; -+} -+ -+/****************************************************************************** -+ * initialization -+ ******************************************************************************/ -+ -+void lru_gen_init_lruvec(struct lruvec *lruvec) -+{ -+ int gen, type, zone; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ lrugen->max_seq = MIN_NR_GENS + 1; -+ -+ for_each_gen_type_zone(gen, type, zone) -+ INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); -+} -+ -+#ifdef CONFIG_MEMCG -+void lru_gen_init_memcg(struct mem_cgroup *memcg) -+{ -+} -+ -+void lru_gen_exit_memcg(struct mem_cgroup *memcg) -+{ -+ int nid; -+ -+ for_each_node(nid) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0, -+ sizeof(lruvec->lrugen.nr_pages))); -+ } -+} -+#endif -+ -+static int __init init_lru_gen(void) -+{ -+ BUILD_BUG_ON(MIN_NR_GENS + 1 >= MAX_NR_GENS); -+ BUILD_BUG_ON(BIT(LRU_GEN_WIDTH) <= MAX_NR_GENS); -+ -+ return 0; -+}; -+late_initcall(init_lru_gen); -+ -+#endif /* CONFIG_LRU_GEN */ -+ - static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { - unsigned long nr[NR_LRU_LISTS]; diff --git a/target/linux/generic/backport-5.15/020-v6.1-06-mm-multi-gen-LRU-minimal-implementation.patch b/target/linux/generic/backport-5.15/020-v6.1-06-mm-multi-gen-LRU-minimal-implementation.patch deleted file mode 100644 index 14fc73f84de4c1..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-06-mm-multi-gen-LRU-minimal-implementation.patch +++ /dev/null @@ -1,1447 +0,0 @@ -From b564b9471cd60ef1ee3961a224898ce4a9620d84 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 02:00:03 -0600 -Subject: [PATCH 06/29] mm: multi-gen LRU: minimal implementation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -To avoid confusion, the terms "promotion" and "demotion" will be applied -to the multi-gen LRU, as a new convention; the terms "activation" and -"deactivation" will be applied to the active/inactive LRU, as usual. - -The aging produces young generations. Given an lruvec, it increments -max_seq when max_seq-min_seq+1 approaches MIN_NR_GENS. The aging promotes -hot pages to the youngest generation when it finds them accessed through -page tables; the demotion of cold pages happens consequently when it -increments max_seq. Promotion in the aging path does not involve any LRU -list operations, only the updates of the gen counter and -lrugen->nr_pages[]; demotion, unless as the result of the increment of -max_seq, requires LRU list operations, e.g., lru_deactivate_fn(). The -aging has the complexity O(nr_hot_pages), since it is only interested in -hot pages. - -The eviction consumes old generations. Given an lruvec, it increments -min_seq when lrugen->lists[] indexed by min_seq%MAX_NR_GENS becomes empty. -A feedback loop modeled after the PID controller monitors refaults over -anon and file types and decides which type to evict when both types are -available from the same generation. - -The protection of pages accessed multiple times through file descriptors -takes place in the eviction path. Each generation is divided into -multiple tiers. A page accessed N times through file descriptors is in -tier order_base_2(N). Tiers do not have dedicated lrugen->lists[], only -bits in page->flags. The aforementioned feedback loop also monitors -refaults over all tiers and decides when to protect pages in which tiers -(N>1), using the first tier (N=0,1) as a baseline. The first tier -contains single-use unmapped clean pages, which are most likely the best -choices. In contrast to promotion in the aging path, the protection of a -page in the eviction path is achieved by moving this page to the next -generation, i.e., min_seq+1, if the feedback loop decides so. This -approach has the following advantages: - -1. It removes the cost of activation in the buffered access path by - inferring whether pages accessed multiple times through file - descriptors are statistically hot and thus worth protecting in the - eviction path. -2. It takes pages accessed through page tables into account and avoids - overprotecting pages accessed multiple times through file - descriptors. (Pages accessed through page tables are in the first - tier, since N=0.) -3. More tiers provide better protection for pages accessed more than - twice through file descriptors, when under heavy buffered I/O - workloads. - -Server benchmark results: - Single workload: - fio (buffered I/O): +[30, 32]% - IOPS BW - 5.19-rc1: 2673k 10.2GiB/s - patch1-6: 3491k 13.3GiB/s - - Single workload: - memcached (anon): -[4, 6]% - Ops/sec KB/sec - 5.19-rc1: 1161501.04 45177.25 - patch1-6: 1106168.46 43025.04 - - Configurations: - CPU: two Xeon 6154 - Mem: total 256G - - Node 1 was only used as a ram disk to reduce the variance in the - results. - - patch drivers/block/brd.c < gfp_flags = GFP_NOIO | __GFP_ZERO | __GFP_HIGHMEM | __GFP_THISNODE; - > page = alloc_pages_node(1, gfp_flags, 0); - EOF - - cat >>/etc/systemd/system.conf <>/etc/memcached.conf </sys/fs/cgroup/user.slice/test/memory.max - echo $$ >/sys/fs/cgroup/user.slice/test/cgroup.procs - fio -name=mglru --numjobs=72 --directory=/mnt --size=1408m \ - --buffered=1 --ioengine=io_uring --iodepth=128 \ - --iodepth_batch_submit=32 --iodepth_batch_complete=32 \ - --rw=randread --random_distribution=random --norandommap \ - --time_based --ramp_time=10m --runtime=5m --group_reporting - - cat memcached.sh - modprobe brd rd_nr=1 rd_size=113246208 - swapoff -a - mkswap /dev/ram0 - swapon /dev/ram0 - - memtier_benchmark -S /var/run/memcached/memcached.sock \ - -P memcache_binary -n allkeys --key-minimum=1 \ - --key-maximum=65000000 --key-pattern=P:P -c 1 -t 36 \ - --ratio 1:0 --pipeline 8 -d 2000 - - memtier_benchmark -S /var/run/memcached/memcached.sock \ - -P memcache_binary -n allkeys --key-minimum=1 \ - --key-maximum=65000000 --key-pattern=R:R -c 1 -t 36 \ - --ratio 0:1 --pipeline 8 --randomize --distinct-client-seed - -Client benchmark results: - kswapd profiles: - 5.19-rc1 - 40.33% page_vma_mapped_walk (overhead) - 21.80% lzo1x_1_do_compress (real work) - 7.53% do_raw_spin_lock - 3.95% _raw_spin_unlock_irq - 2.52% vma_interval_tree_iter_next - 2.37% page_referenced_one - 2.28% vma_interval_tree_subtree_search - 1.97% anon_vma_interval_tree_iter_first - 1.60% ptep_clear_flush - 1.06% __zram_bvec_write - - patch1-6 - 39.03% lzo1x_1_do_compress (real work) - 18.47% page_vma_mapped_walk (overhead) - 6.74% _raw_spin_unlock_irq - 3.97% do_raw_spin_lock - 2.49% ptep_clear_flush - 2.48% anon_vma_interval_tree_iter_first - 1.92% page_referenced_one - 1.88% __zram_bvec_write - 1.48% memmove - 1.31% vma_interval_tree_iter_next - - Configurations: - CPU: single Snapdragon 7c - Mem: total 4G - - ChromeOS MemoryPressure [1] - -[1] https://chromium.googlesource.com/chromiumos/platform/tast-tests/ - -Link: https://lkml.kernel.org/r/20220918080010.2920238-7-yuzhao@google.com -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Barry Song -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Miaohe Lin -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Qi Zheng -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - include/linux/mm_inline.h | 36 ++ - include/linux/mmzone.h | 41 ++ - include/linux/page-flags-layout.h | 5 +- - kernel/bounds.c | 2 + - mm/Kconfig | 11 + - mm/swap.c | 39 ++ - mm/vmscan.c | 792 +++++++++++++++++++++++++++++- - mm/workingset.c | 110 ++++- - 8 files changed, 1025 insertions(+), 11 deletions(-) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -106,6 +106,33 @@ static inline int lru_gen_from_seq(unsig - return seq % MAX_NR_GENS; - } - -+static inline int lru_hist_from_seq(unsigned long seq) -+{ -+ return seq % NR_HIST_GENS; -+} -+ -+static inline int lru_tier_from_refs(int refs) -+{ -+ VM_WARN_ON_ONCE(refs > BIT(LRU_REFS_WIDTH)); -+ -+ /* see the comment in page_lru_refs() */ -+ return order_base_2(refs + 1); -+} -+ -+static inline int page_lru_refs(struct page *page) -+{ -+ unsigned long flags = READ_ONCE(page->flags); -+ bool workingset = flags & BIT(PG_workingset); -+ -+ /* -+ * Return the number of accesses beyond PG_referenced, i.e., N-1 if the -+ * total number of accesses is N>1, since N=0,1 both map to the first -+ * tier. lru_tier_from_refs() will account for this off-by-one. Also see -+ * the comment on MAX_NR_TIERS. -+ */ -+ return ((flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF) + workingset; -+} -+ - static inline int page_lru_gen(struct page *page) - { - unsigned long flags = READ_ONCE(page->flags); -@@ -158,6 +185,15 @@ static inline void lru_gen_update_size(s - __update_lru_size(lruvec, lru, zone, -delta); - return; - } -+ -+ /* promotion */ -+ if (!lru_gen_is_active(lruvec, old_gen) && lru_gen_is_active(lruvec, new_gen)) { -+ __update_lru_size(lruvec, lru, zone, -delta); -+ __update_lru_size(lruvec, lru + LRU_ACTIVE, zone, delta); -+ } -+ -+ /* demotion requires isolation, e.g., lru_deactivate_fn() */ -+ VM_WARN_ON_ONCE(lru_gen_is_active(lruvec, old_gen) && !lru_gen_is_active(lruvec, new_gen)); - } - - static inline bool lru_gen_add_page(struct lruvec *lruvec, struct page *page, bool reclaiming) ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -327,6 +327,28 @@ enum lruvec_flags { - #define MIN_NR_GENS 2U - #define MAX_NR_GENS 4U - -+/* -+ * Each generation is divided into multiple tiers. A page accessed N times -+ * through file descriptors is in tier order_base_2(N). A page in the first tier -+ * (N=0,1) is marked by PG_referenced unless it was faulted in through page -+ * tables or read ahead. A page in any other tier (N>1) is marked by -+ * PG_referenced and PG_workingset. This implies a minimum of two tiers is -+ * supported without using additional bits in page->flags. -+ * -+ * In contrast to moving across generations which requires the LRU lock, moving -+ * across tiers only involves atomic operations on page->flags and therefore -+ * has a negligible cost in the buffered access path. In the eviction path, -+ * comparisons of refaulted/(evicted+protected) from the first tier and the -+ * rest infer whether pages accessed multiple times through file descriptors -+ * are statistically hot and thus worth protecting. -+ * -+ * MAX_NR_TIERS is set to 4 so that the multi-gen LRU can support twice the -+ * number of categories of the active/inactive LRU when keeping track of -+ * accesses through file descriptors. This uses MAX_NR_TIERS-2 spare bits in -+ * page->flags. -+ */ -+#define MAX_NR_TIERS 4U -+ - #ifndef __GENERATING_BOUNDS_H - - struct lruvec; -@@ -341,6 +363,16 @@ enum { - LRU_GEN_FILE, - }; - -+#define MIN_LRU_BATCH BITS_PER_LONG -+#define MAX_LRU_BATCH (MIN_LRU_BATCH * 64) -+ -+/* whether to keep historical stats from evicted generations */ -+#ifdef CONFIG_LRU_GEN_STATS -+#define NR_HIST_GENS MAX_NR_GENS -+#else -+#define NR_HIST_GENS 1U -+#endif -+ - /* - * The youngest generation number is stored in max_seq for both anon and file - * types as they are aged on an equal footing. The oldest generation numbers are -@@ -363,6 +395,15 @@ struct lru_gen_struct { - struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; - /* the multi-gen LRU sizes, eventually consistent */ - long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ /* the exponential moving average of refaulted */ -+ unsigned long avg_refaulted[ANON_AND_FILE][MAX_NR_TIERS]; -+ /* the exponential moving average of evicted+protected */ -+ unsigned long avg_total[ANON_AND_FILE][MAX_NR_TIERS]; -+ /* the first tier doesn't need protection, hence the minus one */ -+ unsigned long protected[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS - 1]; -+ /* can be modified without holding the LRU lock */ -+ atomic_long_t evicted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; -+ atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; - }; - - void lru_gen_init_lruvec(struct lruvec *lruvec); ---- a/include/linux/page-flags-layout.h -+++ b/include/linux/page-flags-layout.h -@@ -106,7 +106,10 @@ - #error "Not enough bits in page flags" - #endif - --#define LRU_REFS_WIDTH 0 -+/* see the comment on MAX_NR_TIERS */ -+#define LRU_REFS_WIDTH min(__LRU_REFS_WIDTH, BITS_PER_LONG - NR_PAGEFLAGS - \ -+ ZONES_WIDTH - LRU_GEN_WIDTH - SECTIONS_WIDTH - \ -+ NODES_WIDTH - KASAN_TAG_WIDTH - LAST_CPUPID_WIDTH) - - #endif - #endif /* _LINUX_PAGE_FLAGS_LAYOUT */ ---- a/kernel/bounds.c -+++ b/kernel/bounds.c -@@ -24,8 +24,10 @@ int main(void) - DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t)); - #ifdef CONFIG_LRU_GEN - DEFINE(LRU_GEN_WIDTH, order_base_2(MAX_NR_GENS + 1)); -+ DEFINE(__LRU_REFS_WIDTH, MAX_NR_TIERS - 2); - #else - DEFINE(LRU_GEN_WIDTH, 0); -+ DEFINE(__LRU_REFS_WIDTH, 0); - #endif - /* End of constants */ - ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -897,6 +897,7 @@ config IO_MAPPING - config SECRETMEM - def_bool ARCH_HAS_SET_DIRECT_MAP && !EMBEDDED - -+# multi-gen LRU { - config LRU_GEN - bool "Multi-Gen LRU" - depends on MMU -@@ -905,6 +906,16 @@ config LRU_GEN - help - A high performance LRU implementation to overcommit memory. - -+config LRU_GEN_STATS -+ bool "Full stats for debugging" -+ depends on LRU_GEN -+ help -+ Do not enable this option unless you plan to look at historical stats -+ from evicted generations for debugging purpose. -+ -+ This option has a per-memcg and per-node memory overhead. -+# } -+ - source "mm/damon/Kconfig" - - endmenu ---- a/mm/swap.c -+++ b/mm/swap.c -@@ -389,6 +389,40 @@ static void __lru_cache_activate_page(st - local_unlock(&lru_pvecs.lock); - } - -+#ifdef CONFIG_LRU_GEN -+static void page_inc_refs(struct page *page) -+{ -+ unsigned long new_flags, old_flags = READ_ONCE(page->flags); -+ -+ if (PageUnevictable(page)) -+ return; -+ -+ if (!PageReferenced(page)) { -+ SetPageReferenced(page); -+ return; -+ } -+ -+ if (!PageWorkingset(page)) { -+ SetPageWorkingset(page); -+ return; -+ } -+ -+ /* see the comment on MAX_NR_TIERS */ -+ do { -+ new_flags = old_flags & LRU_REFS_MASK; -+ if (new_flags == LRU_REFS_MASK) -+ break; -+ -+ new_flags += BIT(LRU_REFS_PGOFF); -+ new_flags |= old_flags & ~LRU_REFS_MASK; -+ } while (!try_cmpxchg(&page->flags, &old_flags, new_flags)); -+} -+#else -+static void page_inc_refs(struct page *page) -+{ -+} -+#endif /* CONFIG_LRU_GEN */ -+ - /* - * Mark a page as having seen activity. - * -@@ -403,6 +437,11 @@ void mark_page_accessed(struct page *pag - { - page = compound_head(page); - -+ if (lru_gen_enabled()) { -+ page_inc_refs(page); -+ return; -+ } -+ - if (!PageReferenced(page)) { - SetPageReferenced(page); - } else if (PageUnevictable(page)) { ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -1142,9 +1142,11 @@ static int __remove_mapping(struct addre - - if (PageSwapCache(page)) { - swp_entry_t swap = { .val = page_private(page) }; -- mem_cgroup_swapout(page, swap); -+ -+ /* get a shadow entry before mem_cgroup_swapout() clears page_memcg() */ - if (reclaimed && !mapping_exiting(mapping)) - shadow = workingset_eviction(page, target_memcg); -+ mem_cgroup_swapout(page, swap); - __delete_from_swap_cache(page, swap, shadow); - xa_unlock_irq(&mapping->i_pages); - put_swap_page(page, swap); -@@ -2502,6 +2504,9 @@ static void prepare_scan_count(pg_data_t - unsigned long file; - struct lruvec *target_lruvec; - -+ if (lru_gen_enabled()) -+ return; -+ - target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); - - /* -@@ -2827,6 +2832,17 @@ static bool can_age_anon_pages(struct pg - * shorthand helpers - ******************************************************************************/ - -+#define LRU_REFS_FLAGS (BIT(PG_referenced) | BIT(PG_workingset)) -+ -+#define DEFINE_MAX_SEQ(lruvec) \ -+ unsigned long max_seq = READ_ONCE((lruvec)->lrugen.max_seq) -+ -+#define DEFINE_MIN_SEQ(lruvec) \ -+ unsigned long min_seq[ANON_AND_FILE] = { \ -+ READ_ONCE((lruvec)->lrugen.min_seq[LRU_GEN_ANON]), \ -+ READ_ONCE((lruvec)->lrugen.min_seq[LRU_GEN_FILE]), \ -+ } -+ - #define for_each_gen_type_zone(gen, type, zone) \ - for ((gen) = 0; (gen) < MAX_NR_GENS; (gen)++) \ - for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ -@@ -2852,6 +2868,745 @@ static struct lruvec __maybe_unused *get - return pgdat ? &pgdat->__lruvec : NULL; - } - -+static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ -+ if (!can_demote(pgdat->node_id, sc) && -+ mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH) -+ return 0; -+ -+ return mem_cgroup_swappiness(memcg); -+} -+ -+static int get_nr_gens(struct lruvec *lruvec, int type) -+{ -+ return lruvec->lrugen.max_seq - lruvec->lrugen.min_seq[type] + 1; -+} -+ -+static bool __maybe_unused seq_is_valid(struct lruvec *lruvec) -+{ -+ /* see the comment on lru_gen_struct */ -+ return get_nr_gens(lruvec, LRU_GEN_FILE) >= MIN_NR_GENS && -+ get_nr_gens(lruvec, LRU_GEN_FILE) <= get_nr_gens(lruvec, LRU_GEN_ANON) && -+ get_nr_gens(lruvec, LRU_GEN_ANON) <= MAX_NR_GENS; -+} -+ -+/****************************************************************************** -+ * refault feedback loop -+ ******************************************************************************/ -+ -+/* -+ * A feedback loop based on Proportional-Integral-Derivative (PID) controller. -+ * -+ * The P term is refaulted/(evicted+protected) from a tier in the generation -+ * currently being evicted; the I term is the exponential moving average of the -+ * P term over the generations previously evicted, using the smoothing factor -+ * 1/2; the D term isn't supported. -+ * -+ * The setpoint (SP) is always the first tier of one type; the process variable -+ * (PV) is either any tier of the other type or any other tier of the same -+ * type. -+ * -+ * The error is the difference between the SP and the PV; the correction is to -+ * turn off protection when SP>PV or turn on protection when SPlrugen; -+ int hist = lru_hist_from_seq(lrugen->min_seq[type]); -+ -+ pos->refaulted = lrugen->avg_refaulted[type][tier] + -+ atomic_long_read(&lrugen->refaulted[hist][type][tier]); -+ pos->total = lrugen->avg_total[type][tier] + -+ atomic_long_read(&lrugen->evicted[hist][type][tier]); -+ if (tier) -+ pos->total += lrugen->protected[hist][type][tier - 1]; -+ pos->gain = gain; -+} -+ -+static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover) -+{ -+ int hist, tier; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1; -+ unsigned long seq = carryover ? lrugen->min_seq[type] : lrugen->max_seq + 1; -+ -+ lockdep_assert_held(&lruvec->lru_lock); -+ -+ if (!carryover && !clear) -+ return; -+ -+ hist = lru_hist_from_seq(seq); -+ -+ for (tier = 0; tier < MAX_NR_TIERS; tier++) { -+ if (carryover) { -+ unsigned long sum; -+ -+ sum = lrugen->avg_refaulted[type][tier] + -+ atomic_long_read(&lrugen->refaulted[hist][type][tier]); -+ WRITE_ONCE(lrugen->avg_refaulted[type][tier], sum / 2); -+ -+ sum = lrugen->avg_total[type][tier] + -+ atomic_long_read(&lrugen->evicted[hist][type][tier]); -+ if (tier) -+ sum += lrugen->protected[hist][type][tier - 1]; -+ WRITE_ONCE(lrugen->avg_total[type][tier], sum / 2); -+ } -+ -+ if (clear) { -+ atomic_long_set(&lrugen->refaulted[hist][type][tier], 0); -+ atomic_long_set(&lrugen->evicted[hist][type][tier], 0); -+ if (tier) -+ WRITE_ONCE(lrugen->protected[hist][type][tier - 1], 0); -+ } -+ } -+} -+ -+static bool positive_ctrl_err(struct ctrl_pos *sp, struct ctrl_pos *pv) -+{ -+ /* -+ * Return true if the PV has a limited number of refaults or a lower -+ * refaulted/total than the SP. -+ */ -+ return pv->refaulted < MIN_LRU_BATCH || -+ pv->refaulted * (sp->total + MIN_LRU_BATCH) * sp->gain <= -+ (sp->refaulted + 1) * pv->total * pv->gain; -+} -+ -+/****************************************************************************** -+ * the aging -+ ******************************************************************************/ -+ -+/* protect pages accessed multiple times through file descriptors */ -+static int page_inc_gen(struct lruvec *lruvec, struct page *page, bool reclaiming) -+{ -+ int type = page_is_file_lru(page); -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ unsigned long new_flags, old_flags = READ_ONCE(page->flags); -+ -+ VM_WARN_ON_ONCE_PAGE(!(old_flags & LRU_GEN_MASK), page); -+ -+ do { -+ new_gen = (old_gen + 1) % MAX_NR_GENS; -+ -+ new_flags = old_flags & ~(LRU_GEN_MASK | LRU_REFS_MASK | LRU_REFS_FLAGS); -+ new_flags |= (new_gen + 1UL) << LRU_GEN_PGOFF; -+ /* for end_page_writeback() */ -+ if (reclaiming) -+ new_flags |= BIT(PG_reclaim); -+ } while (!try_cmpxchg(&page->flags, &old_flags, new_flags)); -+ -+ lru_gen_update_size(lruvec, page, old_gen, new_gen); -+ -+ return new_gen; -+} -+ -+static void inc_min_seq(struct lruvec *lruvec, int type) -+{ -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ reset_ctrl_pos(lruvec, type, true); -+ WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1); -+} -+ -+static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap) -+{ -+ int gen, type, zone; -+ bool success = false; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ DEFINE_MIN_SEQ(lruvec); -+ -+ VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); -+ -+ /* find the oldest populated generation */ -+ for (type = !can_swap; type < ANON_AND_FILE; type++) { -+ while (min_seq[type] + MIN_NR_GENS <= lrugen->max_seq) { -+ gen = lru_gen_from_seq(min_seq[type]); -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) { -+ if (!list_empty(&lrugen->lists[gen][type][zone])) -+ goto next; -+ } -+ -+ min_seq[type]++; -+ } -+next: -+ ; -+ } -+ -+ /* see the comment on lru_gen_struct */ -+ if (can_swap) { -+ min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]); -+ min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]); -+ } -+ -+ for (type = !can_swap; type < ANON_AND_FILE; type++) { -+ if (min_seq[type] == lrugen->min_seq[type]) -+ continue; -+ -+ reset_ctrl_pos(lruvec, type, true); -+ WRITE_ONCE(lrugen->min_seq[type], min_seq[type]); -+ success = true; -+ } -+ -+ return success; -+} -+ -+static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, bool can_swap) -+{ -+ int prev, next; -+ int type, zone; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); -+ -+ if (max_seq != lrugen->max_seq) -+ goto unlock; -+ -+ for (type = ANON_AND_FILE - 1; type >= 0; type--) { -+ if (get_nr_gens(lruvec, type) != MAX_NR_GENS) -+ continue; -+ -+ VM_WARN_ON_ONCE(type == LRU_GEN_FILE || can_swap); -+ -+ inc_min_seq(lruvec, type); -+ } -+ -+ /* -+ * Update the active/inactive LRU sizes for compatibility. Both sides of -+ * the current max_seq need to be covered, since max_seq+1 can overlap -+ * with min_seq[LRU_GEN_ANON] if swapping is constrained. And if they do -+ * overlap, cold/hot inversion happens. -+ */ -+ prev = lru_gen_from_seq(lrugen->max_seq - 1); -+ next = lru_gen_from_seq(lrugen->max_seq + 1); -+ -+ for (type = 0; type < ANON_AND_FILE; type++) { -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) { -+ enum lru_list lru = type * LRU_INACTIVE_FILE; -+ long delta = lrugen->nr_pages[prev][type][zone] - -+ lrugen->nr_pages[next][type][zone]; -+ -+ if (!delta) -+ continue; -+ -+ __update_lru_size(lruvec, lru, zone, delta); -+ __update_lru_size(lruvec, lru + LRU_ACTIVE, zone, -delta); -+ } -+ } -+ -+ for (type = 0; type < ANON_AND_FILE; type++) -+ reset_ctrl_pos(lruvec, type, false); -+ -+ /* make sure preceding modifications appear */ -+ smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1); -+unlock: -+ spin_unlock_irq(&lruvec->lru_lock); -+} -+ -+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq, -+ struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) -+{ -+ int gen, type, zone; -+ unsigned long old = 0; -+ unsigned long young = 0; -+ unsigned long total = 0; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ -+ for (type = !can_swap; type < ANON_AND_FILE; type++) { -+ unsigned long seq; -+ -+ for (seq = min_seq[type]; seq <= max_seq; seq++) { -+ unsigned long size = 0; -+ -+ gen = lru_gen_from_seq(seq); -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) -+ size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); -+ -+ total += size; -+ if (seq == max_seq) -+ young += size; -+ else if (seq + MIN_NR_GENS == max_seq) -+ old += size; -+ } -+ } -+ -+ /* try to scrape all its memory if this memcg was deleted */ -+ *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total; -+ -+ /* -+ * The aging tries to be lazy to reduce the overhead, while the eviction -+ * stalls when the number of generations reaches MIN_NR_GENS. Hence, the -+ * ideal number of generations is MIN_NR_GENS+1. -+ */ -+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) -+ return true; -+ if (min_seq[!can_swap] + MIN_NR_GENS < max_seq) -+ return false; -+ -+ /* -+ * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1) -+ * of the total number of pages for each generation. A reasonable range -+ * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The -+ * aging cares about the upper bound of hot pages, while the eviction -+ * cares about the lower bound of cold pages. -+ */ -+ if (young * MIN_NR_GENS > total) -+ return true; -+ if (old * (MIN_NR_GENS + 2) < total) -+ return true; -+ -+ return false; -+} -+ -+static void age_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ bool need_aging; -+ unsigned long nr_to_scan; -+ int swappiness = get_swappiness(lruvec, sc); -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ VM_WARN_ON_ONCE(sc->memcg_low_reclaim); -+ -+ mem_cgroup_calculate_protection(NULL, memcg); -+ -+ if (mem_cgroup_below_min(memcg)) -+ return; -+ -+ need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan); -+ if (need_aging) -+ inc_max_seq(lruvec, max_seq, swappiness); -+} -+ -+static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ struct mem_cgroup *memcg; -+ -+ VM_WARN_ON_ONCE(!current_is_kswapd()); -+ -+ memcg = mem_cgroup_iter(NULL, NULL, NULL); -+ do { -+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ -+ age_lruvec(lruvec, sc); -+ -+ cond_resched(); -+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+} -+ -+/****************************************************************************** -+ * the eviction -+ ******************************************************************************/ -+ -+static bool sort_page(struct lruvec *lruvec, struct page *page, int tier_idx) -+{ -+ bool success; -+ int gen = page_lru_gen(page); -+ int type = page_is_file_lru(page); -+ int zone = page_zonenum(page); -+ int delta = thp_nr_pages(page); -+ int refs = page_lru_refs(page); -+ int tier = lru_tier_from_refs(refs); -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ VM_WARN_ON_ONCE_PAGE(gen >= MAX_NR_GENS, page); -+ -+ /* unevictable */ -+ if (!page_evictable(page)) { -+ success = lru_gen_del_page(lruvec, page, true); -+ VM_WARN_ON_ONCE_PAGE(!success, page); -+ SetPageUnevictable(page); -+ add_page_to_lru_list(page, lruvec); -+ __count_vm_events(UNEVICTABLE_PGCULLED, delta); -+ return true; -+ } -+ -+ /* dirty lazyfree */ -+ if (type == LRU_GEN_FILE && PageAnon(page) && PageDirty(page)) { -+ success = lru_gen_del_page(lruvec, page, true); -+ VM_WARN_ON_ONCE_PAGE(!success, page); -+ SetPageSwapBacked(page); -+ add_page_to_lru_list_tail(page, lruvec); -+ return true; -+ } -+ -+ /* protected */ -+ if (tier > tier_idx) { -+ int hist = lru_hist_from_seq(lrugen->min_seq[type]); -+ -+ gen = page_inc_gen(lruvec, page, false); -+ list_move_tail(&page->lru, &lrugen->lists[gen][type][zone]); -+ -+ WRITE_ONCE(lrugen->protected[hist][type][tier - 1], -+ lrugen->protected[hist][type][tier - 1] + delta); -+ __mod_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + type, delta); -+ return true; -+ } -+ -+ /* waiting for writeback */ -+ if (PageLocked(page) || PageWriteback(page) || -+ (type == LRU_GEN_FILE && PageDirty(page))) { -+ gen = page_inc_gen(lruvec, page, true); -+ list_move(&page->lru, &lrugen->lists[gen][type][zone]); -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool isolate_page(struct lruvec *lruvec, struct page *page, struct scan_control *sc) -+{ -+ bool success; -+ -+ /* unmapping inhibited */ -+ if (!sc->may_unmap && page_mapped(page)) -+ return false; -+ -+ /* swapping inhibited */ -+ if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) && -+ (PageDirty(page) || -+ (PageAnon(page) && !PageSwapCache(page)))) -+ return false; -+ -+ /* raced with release_pages() */ -+ if (!get_page_unless_zero(page)) -+ return false; -+ -+ /* raced with another isolation */ -+ if (!TestClearPageLRU(page)) { -+ put_page(page); -+ return false; -+ } -+ -+ /* see the comment on MAX_NR_TIERS */ -+ if (!PageReferenced(page)) -+ set_mask_bits(&page->flags, LRU_REFS_MASK | LRU_REFS_FLAGS, 0); -+ -+ /* for shrink_page_list() */ -+ ClearPageReclaim(page); -+ ClearPageReferenced(page); -+ -+ success = lru_gen_del_page(lruvec, page, true); -+ VM_WARN_ON_ONCE_PAGE(!success, page); -+ -+ return true; -+} -+ -+static int scan_pages(struct lruvec *lruvec, struct scan_control *sc, -+ int type, int tier, struct list_head *list) -+{ -+ int gen, zone; -+ enum vm_event_item item; -+ int sorted = 0; -+ int scanned = 0; -+ int isolated = 0; -+ int remaining = MAX_LRU_BATCH; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ -+ VM_WARN_ON_ONCE(!list_empty(list)); -+ -+ if (get_nr_gens(lruvec, type) == MIN_NR_GENS) -+ return 0; -+ -+ gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ -+ for (zone = sc->reclaim_idx; zone >= 0; zone--) { -+ LIST_HEAD(moved); -+ int skipped = 0; -+ struct list_head *head = &lrugen->lists[gen][type][zone]; -+ -+ while (!list_empty(head)) { -+ struct page *page = lru_to_page(head); -+ int delta = thp_nr_pages(page); -+ -+ VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page); -+ VM_WARN_ON_ONCE_PAGE(PageActive(page), page); -+ VM_WARN_ON_ONCE_PAGE(page_is_file_lru(page) != type, page); -+ VM_WARN_ON_ONCE_PAGE(page_zonenum(page) != zone, page); -+ -+ scanned += delta; -+ -+ if (sort_page(lruvec, page, tier)) -+ sorted += delta; -+ else if (isolate_page(lruvec, page, sc)) { -+ list_add(&page->lru, list); -+ isolated += delta; -+ } else { -+ list_move(&page->lru, &moved); -+ skipped += delta; -+ } -+ -+ if (!--remaining || max(isolated, skipped) >= MIN_LRU_BATCH) -+ break; -+ } -+ -+ if (skipped) { -+ list_splice(&moved, head); -+ __count_zid_vm_events(PGSCAN_SKIP, zone, skipped); -+ } -+ -+ if (!remaining || isolated >= MIN_LRU_BATCH) -+ break; -+ } -+ -+ item = current_is_kswapd() ? PGSCAN_KSWAPD : PGSCAN_DIRECT; -+ if (!cgroup_reclaim(sc)) { -+ __count_vm_events(item, isolated); -+ __count_vm_events(PGREFILL, sorted); -+ } -+ __count_memcg_events(memcg, item, isolated); -+ __count_memcg_events(memcg, PGREFILL, sorted); -+ __count_vm_events(PGSCAN_ANON + type, isolated); -+ -+ /* -+ * There might not be eligible pages due to reclaim_idx, may_unmap and -+ * may_writepage. Check the remaining to prevent livelock if it's not -+ * making progress. -+ */ -+ return isolated || !remaining ? scanned : 0; -+} -+ -+static int get_tier_idx(struct lruvec *lruvec, int type) -+{ -+ int tier; -+ struct ctrl_pos sp, pv; -+ -+ /* -+ * To leave a margin for fluctuations, use a larger gain factor (1:2). -+ * This value is chosen because any other tier would have at least twice -+ * as many refaults as the first tier. -+ */ -+ read_ctrl_pos(lruvec, type, 0, 1, &sp); -+ for (tier = 1; tier < MAX_NR_TIERS; tier++) { -+ read_ctrl_pos(lruvec, type, tier, 2, &pv); -+ if (!positive_ctrl_err(&sp, &pv)) -+ break; -+ } -+ -+ return tier - 1; -+} -+ -+static int get_type_to_scan(struct lruvec *lruvec, int swappiness, int *tier_idx) -+{ -+ int type, tier; -+ struct ctrl_pos sp, pv; -+ int gain[ANON_AND_FILE] = { swappiness, 200 - swappiness }; -+ -+ /* -+ * Compare the first tier of anon with that of file to determine which -+ * type to scan. Also need to compare other tiers of the selected type -+ * with the first tier of the other type to determine the last tier (of -+ * the selected type) to evict. -+ */ -+ read_ctrl_pos(lruvec, LRU_GEN_ANON, 0, gain[LRU_GEN_ANON], &sp); -+ read_ctrl_pos(lruvec, LRU_GEN_FILE, 0, gain[LRU_GEN_FILE], &pv); -+ type = positive_ctrl_err(&sp, &pv); -+ -+ read_ctrl_pos(lruvec, !type, 0, gain[!type], &sp); -+ for (tier = 1; tier < MAX_NR_TIERS; tier++) { -+ read_ctrl_pos(lruvec, type, tier, gain[type], &pv); -+ if (!positive_ctrl_err(&sp, &pv)) -+ break; -+ } -+ -+ *tier_idx = tier - 1; -+ -+ return type; -+} -+ -+static int isolate_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness, -+ int *type_scanned, struct list_head *list) -+{ -+ int i; -+ int type; -+ int scanned; -+ int tier = -1; -+ DEFINE_MIN_SEQ(lruvec); -+ -+ /* -+ * Try to make the obvious choice first. When anon and file are both -+ * available from the same generation, interpret swappiness 1 as file -+ * first and 200 as anon first. -+ */ -+ if (!swappiness) -+ type = LRU_GEN_FILE; -+ else if (min_seq[LRU_GEN_ANON] < min_seq[LRU_GEN_FILE]) -+ type = LRU_GEN_ANON; -+ else if (swappiness == 1) -+ type = LRU_GEN_FILE; -+ else if (swappiness == 200) -+ type = LRU_GEN_ANON; -+ else -+ type = get_type_to_scan(lruvec, swappiness, &tier); -+ -+ for (i = !swappiness; i < ANON_AND_FILE; i++) { -+ if (tier < 0) -+ tier = get_tier_idx(lruvec, type); -+ -+ scanned = scan_pages(lruvec, sc, type, tier, list); -+ if (scanned) -+ break; -+ -+ type = !type; -+ tier = -1; -+ } -+ -+ *type_scanned = type; -+ -+ return scanned; -+} -+ -+static int evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness) -+{ -+ int type; -+ int scanned; -+ int reclaimed; -+ LIST_HEAD(list); -+ struct page *page; -+ enum vm_event_item item; -+ struct reclaim_stat stat; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ scanned = isolate_pages(lruvec, sc, swappiness, &type, &list); -+ -+ scanned += try_to_inc_min_seq(lruvec, swappiness); -+ -+ if (get_nr_gens(lruvec, !swappiness) == MIN_NR_GENS) -+ scanned = 0; -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ -+ if (list_empty(&list)) -+ return scanned; -+ -+ reclaimed = shrink_page_list(&list, pgdat, sc, &stat, false); -+ -+ list_for_each_entry(page, &list, lru) { -+ /* restore LRU_REFS_FLAGS cleared by isolate_page() */ -+ if (PageWorkingset(page)) -+ SetPageReferenced(page); -+ -+ /* don't add rejected pages to the oldest generation */ -+ if (PageReclaim(page) && -+ (PageDirty(page) || PageWriteback(page))) -+ ClearPageActive(page); -+ else -+ SetPageActive(page); -+ } -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ move_pages_to_lru(lruvec, &list); -+ -+ item = current_is_kswapd() ? PGSTEAL_KSWAPD : PGSTEAL_DIRECT; -+ if (!cgroup_reclaim(sc)) -+ __count_vm_events(item, reclaimed); -+ __count_memcg_events(memcg, item, reclaimed); -+ __count_vm_events(PGSTEAL_ANON + type, reclaimed); -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ -+ mem_cgroup_uncharge_list(&list); -+ free_unref_page_list(&list); -+ -+ sc->nr_reclaimed += reclaimed; -+ -+ return scanned; -+} -+ -+static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, -+ bool can_swap) -+{ -+ bool need_aging; -+ unsigned long nr_to_scan; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (mem_cgroup_below_min(memcg) || -+ (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) -+ return 0; -+ -+ need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan); -+ if (!need_aging) -+ return nr_to_scan; -+ -+ /* skip the aging path at the default priority */ -+ if (sc->priority == DEF_PRIORITY) -+ goto done; -+ -+ /* leave the work to lru_gen_age_node() */ -+ if (current_is_kswapd()) -+ return 0; -+ -+ inc_max_seq(lruvec, max_seq, can_swap); -+done: -+ return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; -+} -+ -+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ struct blk_plug plug; -+ unsigned long scanned = 0; -+ -+ lru_add_drain(); -+ -+ blk_start_plug(&plug); -+ -+ while (true) { -+ int delta; -+ int swappiness; -+ unsigned long nr_to_scan; -+ -+ if (sc->may_swap) -+ swappiness = get_swappiness(lruvec, sc); -+ else if (!cgroup_reclaim(sc) && get_swappiness(lruvec, sc)) -+ swappiness = 1; -+ else -+ swappiness = 0; -+ -+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); -+ if (!nr_to_scan) -+ break; -+ -+ delta = evict_pages(lruvec, sc, swappiness); -+ if (!delta) -+ break; -+ -+ scanned += delta; -+ if (scanned >= nr_to_scan) -+ break; -+ -+ cond_resched(); -+ } -+ -+ blk_finish_plug(&plug); -+} -+ - /****************************************************************************** - * initialization - ******************************************************************************/ -@@ -2894,6 +3649,16 @@ static int __init init_lru_gen(void) - }; - late_initcall(init_lru_gen); - -+#else /* !CONFIG_LRU_GEN */ -+ -+static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+} -+ -+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+} -+ - #endif /* CONFIG_LRU_GEN */ - - static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -@@ -2907,6 +3672,11 @@ static void shrink_lruvec(struct lruvec - bool proportional_reclaim; - struct blk_plug plug; - -+ if (lru_gen_enabled()) { -+ lru_gen_shrink_lruvec(lruvec, sc); -+ return; -+ } -+ - get_scan_count(lruvec, sc, nr); - - /* Record the original scan target for proportional adjustments later */ -@@ -3375,6 +4145,9 @@ static void snapshot_refaults(struct mem - struct lruvec *target_lruvec; - unsigned long refaults; - -+ if (lru_gen_enabled()) -+ return; -+ - target_lruvec = mem_cgroup_lruvec(target_memcg, pgdat); - refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE_ANON); - target_lruvec->refaults[0] = refaults; -@@ -3739,12 +4512,16 @@ unsigned long try_to_free_mem_cgroup_pag - } - #endif - --static void age_active_anon(struct pglist_data *pgdat, -- struct scan_control *sc) -+static void kswapd_age_node(struct pglist_data *pgdat, struct scan_control *sc) - { - struct mem_cgroup *memcg; - struct lruvec *lruvec; - -+ if (lru_gen_enabled()) { -+ lru_gen_age_node(pgdat, sc); -+ return; -+ } -+ - if (!can_age_anon_pages(pgdat, sc)) - return; - -@@ -4061,12 +4838,11 @@ restart: - sc.may_swap = !nr_boost_reclaim; - - /* -- * Do some background aging of the anon list, to give -- * pages a chance to be referenced before reclaiming. All -- * pages are rotated regardless of classzone as this is -- * about consistent aging. -+ * Do some background aging, to give pages a chance to be -+ * referenced before reclaiming. All pages are rotated -+ * regardless of classzone as this is about consistent aging. - */ -- age_active_anon(pgdat, &sc); -+ kswapd_age_node(pgdat, &sc); - - /* - * If we're getting trouble reclaiming, start doing writepage ---- a/mm/workingset.c -+++ b/mm/workingset.c -@@ -187,7 +187,6 @@ static unsigned int bucket_order __read_ - static void *pack_shadow(int memcgid, pg_data_t *pgdat, unsigned long eviction, - bool workingset) - { -- eviction >>= bucket_order; - eviction &= EVICTION_MASK; - eviction = (eviction << MEM_CGROUP_ID_SHIFT) | memcgid; - eviction = (eviction << NODES_SHIFT) | pgdat->node_id; -@@ -212,10 +211,107 @@ static void unpack_shadow(void *shadow, - - *memcgidp = memcgid; - *pgdat = NODE_DATA(nid); -- *evictionp = entry << bucket_order; -+ *evictionp = entry; - *workingsetp = workingset; - } - -+#ifdef CONFIG_LRU_GEN -+ -+static void *lru_gen_eviction(struct page *page) -+{ -+ int hist; -+ unsigned long token; -+ unsigned long min_seq; -+ struct lruvec *lruvec; -+ struct lru_gen_struct *lrugen; -+ int type = page_is_file_lru(page); -+ int delta = thp_nr_pages(page); -+ int refs = page_lru_refs(page); -+ int tier = lru_tier_from_refs(refs); -+ struct mem_cgroup *memcg = page_memcg(page); -+ struct pglist_data *pgdat = page_pgdat(page); -+ -+ BUILD_BUG_ON(LRU_GEN_WIDTH + LRU_REFS_WIDTH > BITS_PER_LONG - EVICTION_SHIFT); -+ -+ lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ lrugen = &lruvec->lrugen; -+ min_seq = READ_ONCE(lrugen->min_seq[type]); -+ token = (min_seq << LRU_REFS_WIDTH) | max(refs - 1, 0); -+ -+ hist = lru_hist_from_seq(min_seq); -+ atomic_long_add(delta, &lrugen->evicted[hist][type][tier]); -+ -+ return pack_shadow(mem_cgroup_id(memcg), pgdat, token, refs); -+} -+ -+static void lru_gen_refault(struct page *page, void *shadow) -+{ -+ int hist, tier, refs; -+ int memcg_id; -+ bool workingset; -+ unsigned long token; -+ unsigned long min_seq; -+ struct lruvec *lruvec; -+ struct lru_gen_struct *lrugen; -+ struct mem_cgroup *memcg; -+ struct pglist_data *pgdat; -+ int type = page_is_file_lru(page); -+ int delta = thp_nr_pages(page); -+ -+ unpack_shadow(shadow, &memcg_id, &pgdat, &token, &workingset); -+ -+ if (pgdat != page_pgdat(page)) -+ return; -+ -+ rcu_read_lock(); -+ -+ memcg = page_memcg_rcu(page); -+ if (memcg_id != mem_cgroup_id(memcg)) -+ goto unlock; -+ -+ lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ lrugen = &lruvec->lrugen; -+ -+ min_seq = READ_ONCE(lrugen->min_seq[type]); -+ if ((token >> LRU_REFS_WIDTH) != (min_seq & (EVICTION_MASK >> LRU_REFS_WIDTH))) -+ goto unlock; -+ -+ hist = lru_hist_from_seq(min_seq); -+ /* see the comment in page_lru_refs() */ -+ refs = (token & (BIT(LRU_REFS_WIDTH) - 1)) + workingset; -+ tier = lru_tier_from_refs(refs); -+ -+ atomic_long_add(delta, &lrugen->refaulted[hist][type][tier]); -+ mod_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + type, delta); -+ -+ /* -+ * Count the following two cases as stalls: -+ * 1. For pages accessed through page tables, hotter pages pushed out -+ * hot pages which refaulted immediately. -+ * 2. For pages accessed multiple times through file descriptors, -+ * numbers of accesses might have been out of the range. -+ */ -+ if (lru_gen_in_fault() || refs == BIT(LRU_REFS_WIDTH)) { -+ SetPageWorkingset(page); -+ mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type, delta); -+ } -+unlock: -+ rcu_read_unlock(); -+} -+ -+#else /* !CONFIG_LRU_GEN */ -+ -+static void *lru_gen_eviction(struct page *page) -+{ -+ return NULL; -+} -+ -+static void lru_gen_refault(struct page *page, void *shadow) -+{ -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - /** - * workingset_age_nonresident - age non-resident entries as LRU ages - * @lruvec: the lruvec that was aged -@@ -264,10 +360,14 @@ void *workingset_eviction(struct page *p - VM_BUG_ON_PAGE(page_count(page), page); - VM_BUG_ON_PAGE(!PageLocked(page), page); - -+ if (lru_gen_enabled()) -+ return lru_gen_eviction(page); -+ - lruvec = mem_cgroup_lruvec(target_memcg, pgdat); - /* XXX: target_memcg can be NULL, go through lruvec */ - memcgid = mem_cgroup_id(lruvec_memcg(lruvec)); - eviction = atomic_long_read(&lruvec->nonresident_age); -+ eviction >>= bucket_order; - workingset_age_nonresident(lruvec, thp_nr_pages(page)); - return pack_shadow(memcgid, pgdat, eviction, PageWorkingset(page)); - } -@@ -296,7 +396,13 @@ void workingset_refault(struct page *pag - bool workingset; - int memcgid; - -+ if (lru_gen_enabled()) { -+ lru_gen_refault(page, shadow); -+ return; -+ } -+ - unpack_shadow(shadow, &memcgid, &pgdat, &eviction, &workingset); -+ eviction <<= bucket_order; - - rcu_read_lock(); - /* diff --git a/target/linux/generic/backport-5.15/020-v6.1-07-mm-multi-gen-LRU-exploit-locality-in-rmap.patch b/target/linux/generic/backport-5.15/020-v6.1-07-mm-multi-gen-LRU-exploit-locality-in-rmap.patch deleted file mode 100644 index 40e51b4294a75a..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-07-mm-multi-gen-LRU-exploit-locality-in-rmap.patch +++ /dev/null @@ -1,491 +0,0 @@ -From e4277535f6d6708bb19b88c4bad155832671d69b Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 02:00:04 -0600 -Subject: [PATCH 07/29] mm: multi-gen LRU: exploit locality in rmap -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Searching the rmap for PTEs mapping each page on an LRU list (to test and -clear the accessed bit) can be expensive because pages from different VMAs -(PA space) are not cache friendly to the rmap (VA space). For workloads -mostly using mapped pages, searching the rmap can incur the highest CPU -cost in the reclaim path. - -This patch exploits spatial locality to reduce the trips into the rmap. -When shrink_page_list() walks the rmap and finds a young PTE, a new -function lru_gen_look_around() scans at most BITS_PER_LONG-1 adjacent -PTEs. On finding another young PTE, it clears the accessed bit and -updates the gen counter of the page mapped by this PTE to -(max_seq%MAX_NR_GENS)+1. - -Server benchmark results: - Single workload: - fio (buffered I/O): no change - - Single workload: - memcached (anon): +[3, 5]% - Ops/sec KB/sec - patch1-6: 1106168.46 43025.04 - patch1-7: 1147696.57 44640.29 - - Configurations: - no change - -Client benchmark results: - kswapd profiles: - patch1-6 - 39.03% lzo1x_1_do_compress (real work) - 18.47% page_vma_mapped_walk (overhead) - 6.74% _raw_spin_unlock_irq - 3.97% do_raw_spin_lock - 2.49% ptep_clear_flush - 2.48% anon_vma_interval_tree_iter_first - 1.92% page_referenced_one - 1.88% __zram_bvec_write - 1.48% memmove - 1.31% vma_interval_tree_iter_next - - patch1-7 - 48.16% lzo1x_1_do_compress (real work) - 8.20% page_vma_mapped_walk (overhead) - 7.06% _raw_spin_unlock_irq - 2.92% ptep_clear_flush - 2.53% __zram_bvec_write - 2.11% do_raw_spin_lock - 2.02% memmove - 1.93% lru_gen_look_around - 1.56% free_unref_page_list - 1.40% memset - - Configurations: - no change - -Link: https://lkml.kernel.org/r/20220918080010.2920238-8-yuzhao@google.com -Signed-off-by: Yu Zhao -Acked-by: Barry Song -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Miaohe Lin -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Qi Zheng -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - include/linux/memcontrol.h | 31 +++++++ - include/linux/mmzone.h | 6 ++ - mm/internal.h | 1 + - mm/memcontrol.c | 1 + - mm/rmap.c | 7 ++ - mm/swap.c | 4 +- - mm/vmscan.c | 184 +++++++++++++++++++++++++++++++++++++ - 7 files changed, 232 insertions(+), 2 deletions(-) - ---- a/include/linux/memcontrol.h -+++ b/include/linux/memcontrol.h -@@ -447,6 +447,7 @@ static inline struct obj_cgroup *__page_ - * - LRU isolation - * - lock_page_memcg() - * - exclusive reference -+ * - mem_cgroup_trylock_pages() - * - * For a kmem page a caller should hold an rcu read lock to protect memcg - * associated with a kmem page from being released. -@@ -502,6 +503,7 @@ static inline struct mem_cgroup *page_me - * - LRU isolation - * - lock_page_memcg() - * - exclusive reference -+ * - mem_cgroup_trylock_pages() - * - * For a kmem page a caller should hold an rcu read lock to protect memcg - * associated with a kmem page from being released. -@@ -958,6 +960,23 @@ void unlock_page_memcg(struct page *page - - void __mod_memcg_state(struct mem_cgroup *memcg, int idx, int val); - -+/* try to stablize page_memcg() for all the pages in a memcg */ -+static inline bool mem_cgroup_trylock_pages(struct mem_cgroup *memcg) -+{ -+ rcu_read_lock(); -+ -+ if (mem_cgroup_disabled() || !atomic_read(&memcg->moving_account)) -+ return true; -+ -+ rcu_read_unlock(); -+ return false; -+} -+ -+static inline void mem_cgroup_unlock_pages(void) -+{ -+ rcu_read_unlock(); -+} -+ - /* idx can be of type enum memcg_stat_item or node_stat_item */ - static inline void mod_memcg_state(struct mem_cgroup *memcg, - int idx, int val) -@@ -1374,6 +1393,18 @@ static inline void unlock_page_memcg(str - { - } - -+static inline bool mem_cgroup_trylock_pages(struct mem_cgroup *memcg) -+{ -+ /* to match page_memcg_rcu() */ -+ rcu_read_lock(); -+ return true; -+} -+ -+static inline void mem_cgroup_unlock_pages(void) -+{ -+ rcu_read_unlock(); -+} -+ - static inline void mem_cgroup_handle_over_high(void) - { - } ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -352,6 +352,7 @@ enum lruvec_flags { - #ifndef __GENERATING_BOUNDS_H - - struct lruvec; -+struct page_vma_mapped_walk; - - #define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF) - #define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF) -@@ -407,6 +408,7 @@ struct lru_gen_struct { - }; - - void lru_gen_init_lruvec(struct lruvec *lruvec); -+void lru_gen_look_around(struct page_vma_mapped_walk *pvmw); - - #ifdef CONFIG_MEMCG - void lru_gen_init_memcg(struct mem_cgroup *memcg); -@@ -419,6 +421,10 @@ static inline void lru_gen_init_lruvec(s - { - } - -+static inline void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) -+{ -+} -+ - #ifdef CONFIG_MEMCG - static inline void lru_gen_init_memcg(struct mem_cgroup *memcg) - { ---- a/mm/internal.h -+++ b/mm/internal.h -@@ -35,6 +35,7 @@ - void page_writeback_init(void); - - vm_fault_t do_swap_page(struct vm_fault *vmf); -+void activate_page(struct page *page); - - void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma, - unsigned long floor, unsigned long ceiling); ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -2798,6 +2798,7 @@ static void commit_charge(struct page *p - * - LRU isolation - * - lock_page_memcg() - * - exclusive reference -+ * - mem_cgroup_trylock_pages() - */ - page->memcg_data = (unsigned long)memcg; - } ---- a/mm/rmap.c -+++ b/mm/rmap.c -@@ -73,6 +73,7 @@ - #include - #include - #include -+#include - - #include - -@@ -793,6 +794,12 @@ static bool page_referenced_one(struct p - } - - if (pvmw.pte) { -+ if (lru_gen_enabled() && pte_young(*pvmw.pte) && -+ !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))) { -+ lru_gen_look_around(&pvmw); -+ referenced++; -+ } -+ - if (ptep_clear_flush_young_notify(vma, address, - pvmw.pte)) { - /* ---- a/mm/swap.c -+++ b/mm/swap.c -@@ -325,7 +325,7 @@ static bool need_activate_page_drain(int - return pagevec_count(&per_cpu(lru_pvecs.activate_page, cpu)) != 0; - } - --static void activate_page(struct page *page) -+void activate_page(struct page *page) - { - page = compound_head(page); - if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) { -@@ -345,7 +345,7 @@ static inline void activate_page_drain(i - { - } - --static void activate_page(struct page *page) -+void activate_page(struct page *page) - { - struct lruvec *lruvec; - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -1409,6 +1409,11 @@ retry: - if (!sc->may_unmap && page_mapped(page)) - goto keep_locked; - -+ /* page_update_gen() tried to promote this page? */ -+ if (lru_gen_enabled() && !ignore_references && -+ page_mapped(page) && PageReferenced(page)) -+ goto keep_locked; -+ - may_enter_fs = (sc->gfp_mask & __GFP_FS) || - (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO)); - -@@ -2990,6 +2995,29 @@ static bool positive_ctrl_err(struct ctr - * the aging - ******************************************************************************/ - -+/* promote pages accessed through page tables */ -+static int page_update_gen(struct page *page, int gen) -+{ -+ unsigned long new_flags, old_flags = READ_ONCE(page->flags); -+ -+ VM_WARN_ON_ONCE(gen >= MAX_NR_GENS); -+ VM_WARN_ON_ONCE(!rcu_read_lock_held()); -+ -+ do { -+ /* lru_gen_del_page() has isolated this page? */ -+ if (!(old_flags & LRU_GEN_MASK)) { -+ /* for shrink_page_list() */ -+ new_flags = old_flags | BIT(PG_referenced); -+ continue; -+ } -+ -+ new_flags = old_flags & ~(LRU_GEN_MASK | LRU_REFS_MASK | LRU_REFS_FLAGS); -+ new_flags |= (gen + 1UL) << LRU_GEN_PGOFF; -+ } while (!try_cmpxchg(&page->flags, &old_flags, new_flags)); -+ -+ return ((old_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+} -+ - /* protect pages accessed multiple times through file descriptors */ - static int page_inc_gen(struct lruvec *lruvec, struct page *page, bool reclaiming) - { -@@ -3001,6 +3029,11 @@ static int page_inc_gen(struct lruvec *l - VM_WARN_ON_ONCE_PAGE(!(old_flags & LRU_GEN_MASK), page); - - do { -+ new_gen = ((old_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1; -+ /* page_update_gen() has promoted this page? */ -+ if (new_gen >= 0 && new_gen != old_gen) -+ return new_gen; -+ - new_gen = (old_gen + 1) % MAX_NR_GENS; - - new_flags = old_flags & ~(LRU_GEN_MASK | LRU_REFS_MASK | LRU_REFS_FLAGS); -@@ -3015,6 +3048,43 @@ static int page_inc_gen(struct lruvec *l - return new_gen; - } - -+static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned long addr) -+{ -+ unsigned long pfn = pte_pfn(pte); -+ -+ VM_WARN_ON_ONCE(addr < vma->vm_start || addr >= vma->vm_end); -+ -+ if (!pte_present(pte) || is_zero_pfn(pfn)) -+ return -1; -+ -+ if (WARN_ON_ONCE(pte_devmap(pte) || pte_special(pte))) -+ return -1; -+ -+ if (WARN_ON_ONCE(!pfn_valid(pfn))) -+ return -1; -+ -+ return pfn; -+} -+ -+static struct page *get_pfn_page(unsigned long pfn, struct mem_cgroup *memcg, -+ struct pglist_data *pgdat) -+{ -+ struct page *page; -+ -+ /* try to avoid unnecessary memory loads */ -+ if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) -+ return NULL; -+ -+ page = compound_head(pfn_to_page(pfn)); -+ if (page_to_nid(page) != pgdat->node_id) -+ return NULL; -+ -+ if (page_memcg_rcu(page) != memcg) -+ return NULL; -+ -+ return page; -+} -+ - static void inc_min_seq(struct lruvec *lruvec, int type) - { - struct lru_gen_struct *lrugen = &lruvec->lrugen; -@@ -3214,6 +3284,114 @@ static void lru_gen_age_node(struct pgli - } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); - } - -+/* -+ * This function exploits spatial locality when shrink_page_list() walks the -+ * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. -+ */ -+void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) -+{ -+ int i; -+ pte_t *pte; -+ unsigned long start; -+ unsigned long end; -+ unsigned long addr; -+ unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {}; -+ struct page *page = pvmw->page; -+ struct mem_cgroup *memcg = page_memcg(page); -+ struct pglist_data *pgdat = page_pgdat(page); -+ struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); -+ DEFINE_MAX_SEQ(lruvec); -+ int old_gen, new_gen = lru_gen_from_seq(max_seq); -+ -+ lockdep_assert_held(pvmw->ptl); -+ VM_WARN_ON_ONCE_PAGE(PageLRU(page), page); -+ -+ if (spin_is_contended(pvmw->ptl)) -+ return; -+ -+ start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start); -+ end = min(pvmw->address | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1; -+ -+ if (end - start > MIN_LRU_BATCH * PAGE_SIZE) { -+ if (pvmw->address - start < MIN_LRU_BATCH * PAGE_SIZE / 2) -+ end = start + MIN_LRU_BATCH * PAGE_SIZE; -+ else if (end - pvmw->address < MIN_LRU_BATCH * PAGE_SIZE / 2) -+ start = end - MIN_LRU_BATCH * PAGE_SIZE; -+ else { -+ start = pvmw->address - MIN_LRU_BATCH * PAGE_SIZE / 2; -+ end = pvmw->address + MIN_LRU_BATCH * PAGE_SIZE / 2; -+ } -+ } -+ -+ pte = pvmw->pte - (pvmw->address - start) / PAGE_SIZE; -+ -+ rcu_read_lock(); -+ arch_enter_lazy_mmu_mode(); -+ -+ for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) { -+ unsigned long pfn; -+ -+ pfn = get_pte_pfn(pte[i], pvmw->vma, addr); -+ if (pfn == -1) -+ continue; -+ -+ if (!pte_young(pte[i])) -+ continue; -+ -+ page = get_pfn_page(pfn, memcg, pgdat); -+ if (!page) -+ continue; -+ -+ if (!ptep_test_and_clear_young(pvmw->vma, addr, pte + i)) -+ VM_WARN_ON_ONCE(true); -+ -+ if (pte_dirty(pte[i]) && !PageDirty(page) && -+ !(PageAnon(page) && PageSwapBacked(page) && -+ !PageSwapCache(page))) -+ set_page_dirty(page); -+ -+ old_gen = page_lru_gen(page); -+ if (old_gen < 0) -+ SetPageReferenced(page); -+ else if (old_gen != new_gen) -+ __set_bit(i, bitmap); -+ } -+ -+ arch_leave_lazy_mmu_mode(); -+ rcu_read_unlock(); -+ -+ if (bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) { -+ for_each_set_bit(i, bitmap, MIN_LRU_BATCH) { -+ page = pte_page(pte[i]); -+ activate_page(page); -+ } -+ return; -+ } -+ -+ /* page_update_gen() requires stable page_memcg() */ -+ if (!mem_cgroup_trylock_pages(memcg)) -+ return; -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq); -+ -+ for_each_set_bit(i, bitmap, MIN_LRU_BATCH) { -+ page = compound_head(pte_page(pte[i])); -+ if (page_memcg_rcu(page) != memcg) -+ continue; -+ -+ old_gen = page_update_gen(page, new_gen); -+ if (old_gen < 0 || old_gen == new_gen) -+ continue; -+ -+ lru_gen_update_size(lruvec, page, old_gen, new_gen); -+ } -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ -+ mem_cgroup_unlock_pages(); -+} -+ - /****************************************************************************** - * the eviction - ******************************************************************************/ -@@ -3250,6 +3428,12 @@ static bool sort_page(struct lruvec *lru - return true; - } - -+ /* promoted */ -+ if (gen != lru_gen_from_seq(lrugen->min_seq[type])) { -+ list_move(&page->lru, &lrugen->lists[gen][type][zone]); -+ return true; -+ } -+ - /* protected */ - if (tier > tier_idx) { - int hist = lru_hist_from_seq(lrugen->min_seq[type]); diff --git a/target/linux/generic/backport-5.15/020-v6.1-08-mm-multi-gen-LRU-support-page-table-walks.patch b/target/linux/generic/backport-5.15/020-v6.1-08-mm-multi-gen-LRU-support-page-table-walks.patch deleted file mode 100644 index 4cfd24717815bc..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-08-mm-multi-gen-LRU-support-page-table-walks.patch +++ /dev/null @@ -1,1687 +0,0 @@ -From 05223c4e80b34e29f2255c04ffebc2c4475e7593 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 02:00:05 -0600 -Subject: [PATCH 08/29] mm: multi-gen LRU: support page table walks -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -To further exploit spatial locality, the aging prefers to walk page tables -to search for young PTEs and promote hot pages. A kill switch will be -added in the next patch to disable this behavior. When disabled, the -aging relies on the rmap only. - -NB: this behavior has nothing similar with the page table scanning in the -2.4 kernel [1], which searches page tables for old PTEs, adds cold pages -to swapcache and unmaps them. - -To avoid confusion, the term "iteration" specifically means the traversal -of an entire mm_struct list; the term "walk" will be applied to page -tables and the rmap, as usual. - -An mm_struct list is maintained for each memcg, and an mm_struct follows -its owner task to the new memcg when this task is migrated. Given an -lruvec, the aging iterates lruvec_memcg()->mm_list and calls -walk_page_range() with each mm_struct on this list to promote hot pages -before it increments max_seq. - -When multiple page table walkers iterate the same list, each of them gets -a unique mm_struct; therefore they can run concurrently. Page table -walkers ignore any misplaced pages, e.g., if an mm_struct was migrated, -pages it left in the previous memcg will not be promoted when its current -memcg is under reclaim. Similarly, page table walkers will not promote -pages from nodes other than the one under reclaim. - -This patch uses the following optimizations when walking page tables: -1. It tracks the usage of mm_struct's between context switches so that - page table walkers can skip processes that have been sleeping since - the last iteration. -2. It uses generational Bloom filters to record populated branches so - that page table walkers can reduce their search space based on the - query results, e.g., to skip page tables containing mostly holes or - misplaced pages. -3. It takes advantage of the accessed bit in non-leaf PMD entries when - CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y. -4. It does not zigzag between a PGD table and the same PMD table - spanning multiple VMAs. IOW, it finishes all the VMAs within the - range of the same PMD table before it returns to a PGD table. This - improves the cache performance for workloads that have large - numbers of tiny VMAs [2], especially when CONFIG_PGTABLE_LEVELS=5. - -Server benchmark results: - Single workload: - fio (buffered I/O): no change - - Single workload: - memcached (anon): +[8, 10]% - Ops/sec KB/sec - patch1-7: 1147696.57 44640.29 - patch1-8: 1245274.91 48435.66 - - Configurations: - no change - -Client benchmark results: - kswapd profiles: - patch1-7 - 48.16% lzo1x_1_do_compress (real work) - 8.20% page_vma_mapped_walk (overhead) - 7.06% _raw_spin_unlock_irq - 2.92% ptep_clear_flush - 2.53% __zram_bvec_write - 2.11% do_raw_spin_lock - 2.02% memmove - 1.93% lru_gen_look_around - 1.56% free_unref_page_list - 1.40% memset - - patch1-8 - 49.44% lzo1x_1_do_compress (real work) - 6.19% page_vma_mapped_walk (overhead) - 5.97% _raw_spin_unlock_irq - 3.13% get_pfn_page - 2.85% ptep_clear_flush - 2.42% __zram_bvec_write - 2.08% do_raw_spin_lock - 1.92% memmove - 1.44% alloc_zspage - 1.36% memset - - Configurations: - no change - -Thanks to the following developers for their efforts [3]. - kernel test robot - -[1] https://lwn.net/Articles/23732/ -[2] https://llvm.org/docs/ScudoHardenedAllocator.html -[3] https://lore.kernel.org/r/202204160827.ekEARWQo-lkp@intel.com/ - -Link: https://lkml.kernel.org/r/20220918080010.2920238-9-yuzhao@google.com -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Barry Song -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Miaohe Lin -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Qi Zheng -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - fs/exec.c | 2 + - include/linux/memcontrol.h | 5 + - include/linux/mm_types.h | 76 +++ - include/linux/mmzone.h | 56 +- - include/linux/swap.h | 4 + - kernel/exit.c | 1 + - kernel/fork.c | 9 + - kernel/sched/core.c | 1 + - mm/memcontrol.c | 25 + - mm/vmscan.c | 1010 +++++++++++++++++++++++++++++++++++- - 10 files changed, 1172 insertions(+), 17 deletions(-) - ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1014,6 +1014,7 @@ static int exec_mmap(struct mm_struct *m - active_mm = tsk->active_mm; - tsk->active_mm = mm; - tsk->mm = mm; -+ lru_gen_add_mm(mm); - /* - * This prevents preemption while active_mm is being loaded and - * it and mm are being updated, which could cause problems for -@@ -1029,6 +1030,7 @@ static int exec_mmap(struct mm_struct *m - tsk->mm->vmacache_seqnum = 0; - vmacache_flush(tsk); - task_unlock(tsk); -+ lru_gen_use_mm(mm); - if (old_mm) { - mmap_read_unlock(old_mm); - BUG_ON(active_mm != old_mm); ---- a/include/linux/memcontrol.h -+++ b/include/linux/memcontrol.h -@@ -353,6 +353,11 @@ struct mem_cgroup { - struct deferred_split deferred_split_queue; - #endif - -+#ifdef CONFIG_LRU_GEN -+ /* per-memcg mm_struct list */ -+ struct lru_gen_mm_list mm_list; -+#endif -+ - struct mem_cgroup_per_node *nodeinfo[]; - }; - ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -580,6 +580,22 @@ struct mm_struct { - #ifdef CONFIG_IOMMU_SUPPORT - u32 pasid; - #endif -+#ifdef CONFIG_LRU_GEN -+ struct { -+ /* this mm_struct is on lru_gen_mm_list */ -+ struct list_head list; -+ /* -+ * Set when switching to this mm_struct, as a hint of -+ * whether it has been used since the last time per-node -+ * page table walkers cleared the corresponding bits. -+ */ -+ unsigned long bitmap; -+#ifdef CONFIG_MEMCG -+ /* points to the memcg of "owner" above */ -+ struct mem_cgroup *memcg; -+#endif -+ } lru_gen; -+#endif /* CONFIG_LRU_GEN */ - } __randomize_layout; - - /* -@@ -606,6 +622,66 @@ static inline cpumask_t *mm_cpumask(stru - return (struct cpumask *)&mm->cpu_bitmap; - } - -+#ifdef CONFIG_LRU_GEN -+ -+struct lru_gen_mm_list { -+ /* mm_struct list for page table walkers */ -+ struct list_head fifo; -+ /* protects the list above */ -+ spinlock_t lock; -+}; -+ -+void lru_gen_add_mm(struct mm_struct *mm); -+void lru_gen_del_mm(struct mm_struct *mm); -+#ifdef CONFIG_MEMCG -+void lru_gen_migrate_mm(struct mm_struct *mm); -+#endif -+ -+static inline void lru_gen_init_mm(struct mm_struct *mm) -+{ -+ INIT_LIST_HEAD(&mm->lru_gen.list); -+ mm->lru_gen.bitmap = 0; -+#ifdef CONFIG_MEMCG -+ mm->lru_gen.memcg = NULL; -+#endif -+} -+ -+static inline void lru_gen_use_mm(struct mm_struct *mm) -+{ -+ /* -+ * When the bitmap is set, page reclaim knows this mm_struct has been -+ * used since the last time it cleared the bitmap. So it might be worth -+ * walking the page tables of this mm_struct to clear the accessed bit. -+ */ -+ WRITE_ONCE(mm->lru_gen.bitmap, -1); -+} -+ -+#else /* !CONFIG_LRU_GEN */ -+ -+static inline void lru_gen_add_mm(struct mm_struct *mm) -+{ -+} -+ -+static inline void lru_gen_del_mm(struct mm_struct *mm) -+{ -+} -+ -+#ifdef CONFIG_MEMCG -+static inline void lru_gen_migrate_mm(struct mm_struct *mm) -+{ -+} -+#endif -+ -+static inline void lru_gen_init_mm(struct mm_struct *mm) -+{ -+} -+ -+static inline void lru_gen_use_mm(struct mm_struct *mm) -+{ -+} -+ -+#endif /* CONFIG_LRU_GEN */ -+ - struct mmu_gather; - extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm); - extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm); ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -385,7 +385,7 @@ enum { - * min_seq behind. - * - * The number of pages in each generation is eventually consistent and therefore -- * can be transiently negative. -+ * can be transiently negative when reset_batch_size() is pending. - */ - struct lru_gen_struct { - /* the aging increments the youngest generation number */ -@@ -407,6 +407,53 @@ struct lru_gen_struct { - atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; - }; - -+enum { -+ MM_LEAF_TOTAL, /* total leaf entries */ -+ MM_LEAF_OLD, /* old leaf entries */ -+ MM_LEAF_YOUNG, /* young leaf entries */ -+ MM_NONLEAF_TOTAL, /* total non-leaf entries */ -+ MM_NONLEAF_FOUND, /* non-leaf entries found in Bloom filters */ -+ MM_NONLEAF_ADDED, /* non-leaf entries added to Bloom filters */ -+ NR_MM_STATS -+}; -+ -+/* double-buffering Bloom filters */ -+#define NR_BLOOM_FILTERS 2 -+ -+struct lru_gen_mm_state { -+ /* set to max_seq after each iteration */ -+ unsigned long seq; -+ /* where the current iteration continues (inclusive) */ -+ struct list_head *head; -+ /* where the last iteration ended (exclusive) */ -+ struct list_head *tail; -+ /* to wait for the last page table walker to finish */ -+ struct wait_queue_head wait; -+ /* Bloom filters flip after each iteration */ -+ unsigned long *filters[NR_BLOOM_FILTERS]; -+ /* the mm stats for debugging */ -+ unsigned long stats[NR_HIST_GENS][NR_MM_STATS]; -+ /* the number of concurrent page table walkers */ -+ int nr_walkers; -+}; -+ -+struct lru_gen_mm_walk { -+ /* the lruvec under reclaim */ -+ struct lruvec *lruvec; -+ /* unstable max_seq from lru_gen_struct */ -+ unsigned long max_seq; -+ /* the next address within an mm to scan */ -+ unsigned long next_addr; -+ /* to batch promoted pages */ -+ int nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ /* to batch the mm stats */ -+ int mm_stats[NR_MM_STATS]; -+ /* total batched items */ -+ int batched; -+ bool can_swap; -+ bool force_scan; -+}; -+ - void lru_gen_init_lruvec(struct lruvec *lruvec); - void lru_gen_look_around(struct page_vma_mapped_walk *pvmw); - -@@ -457,6 +504,8 @@ struct lruvec { - #ifdef CONFIG_LRU_GEN - /* evictable pages divided into generations */ - struct lru_gen_struct lrugen; -+ /* to concurrently iterate lru_gen_mm_list */ -+ struct lru_gen_mm_state mm_state; - #endif - #ifdef CONFIG_MEMCG - struct pglist_data *pgdat; -@@ -1042,6 +1091,11 @@ typedef struct pglist_data { - - unsigned long flags; - -+#ifdef CONFIG_LRU_GEN -+ /* kswap mm walk data */ -+ struct lru_gen_mm_walk mm_walk; -+#endif -+ - ZONE_PADDING(_pad2_) - - /* Per-node vmstats */ ---- a/include/linux/swap.h -+++ b/include/linux/swap.h -@@ -137,6 +137,10 @@ union swap_header { - */ - struct reclaim_state { - unsigned long reclaimed_slab; -+#ifdef CONFIG_LRU_GEN -+ /* per-thread mm walk data */ -+ struct lru_gen_mm_walk *mm_walk; -+#endif - }; - - #ifdef __KERNEL__ ---- a/kernel/exit.c -+++ b/kernel/exit.c -@@ -469,6 +469,7 @@ assign_new_owner: - goto retry; - } - WRITE_ONCE(mm->owner, c); -+ lru_gen_migrate_mm(mm); - task_unlock(c); - put_task_struct(c); - } ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -1091,6 +1091,7 @@ static struct mm_struct *mm_init(struct - goto fail_nocontext; - - mm->user_ns = get_user_ns(user_ns); -+ lru_gen_init_mm(mm); - return mm; - - fail_nocontext: -@@ -1133,6 +1134,7 @@ static inline void __mmput(struct mm_str - } - if (mm->binfmt) - module_put(mm->binfmt->module); -+ lru_gen_del_mm(mm); - mmdrop(mm); - } - -@@ -2625,6 +2627,13 @@ pid_t kernel_clone(struct kernel_clone_a - get_task_struct(p); - } - -+ if (IS_ENABLED(CONFIG_LRU_GEN) && !(clone_flags & CLONE_VM)) { -+ /* lock the task to synchronize with memcg migration */ -+ task_lock(p); -+ lru_gen_add_mm(p->mm); -+ task_unlock(p); -+ } -+ - wake_up_new_task(p); - - /* forking complete and child started to run, tell ptracer */ ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -5014,6 +5014,7 @@ context_switch(struct rq *rq, struct tas - * finish_task_switch()'s mmdrop(). - */ - switch_mm_irqs_off(prev->active_mm, next->mm, next); -+ lru_gen_use_mm(next->mm); - - if (!prev->mm) { // from kernel - /* will mmdrop() in finish_task_switch(). */ ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -6213,6 +6213,30 @@ static void mem_cgroup_move_task(void) - } - #endif - -+#ifdef CONFIG_LRU_GEN -+static void mem_cgroup_attach(struct cgroup_taskset *tset) -+{ -+ struct task_struct *task; -+ struct cgroup_subsys_state *css; -+ -+ /* find the first leader if there is any */ -+ cgroup_taskset_for_each_leader(task, css, tset) -+ break; -+ -+ if (!task) -+ return; -+ -+ task_lock(task); -+ if (task->mm && READ_ONCE(task->mm->owner) == task) -+ lru_gen_migrate_mm(task->mm); -+ task_unlock(task); -+} -+#else -+static void mem_cgroup_attach(struct cgroup_taskset *tset) -+{ -+} -+#endif /* CONFIG_LRU_GEN */ -+ - static int seq_puts_memcg_tunable(struct seq_file *m, unsigned long value) - { - if (value == PAGE_COUNTER_MAX) -@@ -6556,6 +6580,7 @@ struct cgroup_subsys memory_cgrp_subsys - .css_reset = mem_cgroup_css_reset, - .css_rstat_flush = mem_cgroup_css_rstat_flush, - .can_attach = mem_cgroup_can_attach, -+ .attach = mem_cgroup_attach, - .cancel_attach = mem_cgroup_cancel_attach, - .post_attach = mem_cgroup_move_task, - .dfl_cftypes = memory_files, ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -50,6 +50,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -2853,7 +2855,7 @@ static bool can_age_anon_pages(struct pg - for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ - for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++) - --static struct lruvec __maybe_unused *get_lruvec(struct mem_cgroup *memcg, int nid) -+static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid) - { - struct pglist_data *pgdat = NODE_DATA(nid); - -@@ -2899,6 +2901,371 @@ static bool __maybe_unused seq_is_valid( - } - - /****************************************************************************** -+ * mm_struct list -+ ******************************************************************************/ -+ -+static struct lru_gen_mm_list *get_mm_list(struct mem_cgroup *memcg) -+{ -+ static struct lru_gen_mm_list mm_list = { -+ .fifo = LIST_HEAD_INIT(mm_list.fifo), -+ .lock = __SPIN_LOCK_UNLOCKED(mm_list.lock), -+ }; -+ -+#ifdef CONFIG_MEMCG -+ if (memcg) -+ return &memcg->mm_list; -+#endif -+ VM_WARN_ON_ONCE(!mem_cgroup_disabled()); -+ -+ return &mm_list; -+} -+ -+void lru_gen_add_mm(struct mm_struct *mm) -+{ -+ int nid; -+ struct mem_cgroup *memcg = get_mem_cgroup_from_mm(mm); -+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg); -+ -+ VM_WARN_ON_ONCE(!list_empty(&mm->lru_gen.list)); -+#ifdef CONFIG_MEMCG -+ VM_WARN_ON_ONCE(mm->lru_gen.memcg); -+ mm->lru_gen.memcg = memcg; -+#endif -+ spin_lock(&mm_list->lock); -+ -+ for_each_node_state(nid, N_MEMORY) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ if (!lruvec) -+ continue; -+ -+ /* the first addition since the last iteration */ -+ if (lruvec->mm_state.tail == &mm_list->fifo) -+ lruvec->mm_state.tail = &mm->lru_gen.list; -+ } -+ -+ list_add_tail(&mm->lru_gen.list, &mm_list->fifo); -+ -+ spin_unlock(&mm_list->lock); -+} -+ -+void lru_gen_del_mm(struct mm_struct *mm) -+{ -+ int nid; -+ struct lru_gen_mm_list *mm_list; -+ struct mem_cgroup *memcg = NULL; -+ -+ if (list_empty(&mm->lru_gen.list)) -+ return; -+ -+#ifdef CONFIG_MEMCG -+ memcg = mm->lru_gen.memcg; -+#endif -+ mm_list = get_mm_list(memcg); -+ -+ spin_lock(&mm_list->lock); -+ -+ for_each_node(nid) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ if (!lruvec) -+ continue; -+ -+ /* where the last iteration ended (exclusive) */ -+ if (lruvec->mm_state.tail == &mm->lru_gen.list) -+ lruvec->mm_state.tail = lruvec->mm_state.tail->next; -+ -+ /* where the current iteration continues (inclusive) */ -+ if (lruvec->mm_state.head != &mm->lru_gen.list) -+ continue; -+ -+ lruvec->mm_state.head = lruvec->mm_state.head->next; -+ /* the deletion ends the current iteration */ -+ if (lruvec->mm_state.head == &mm_list->fifo) -+ WRITE_ONCE(lruvec->mm_state.seq, lruvec->mm_state.seq + 1); -+ } -+ -+ list_del_init(&mm->lru_gen.list); -+ -+ spin_unlock(&mm_list->lock); -+ -+#ifdef CONFIG_MEMCG -+ mem_cgroup_put(mm->lru_gen.memcg); -+ mm->lru_gen.memcg = NULL; -+#endif -+} -+ -+#ifdef CONFIG_MEMCG -+void lru_gen_migrate_mm(struct mm_struct *mm) -+{ -+ struct mem_cgroup *memcg; -+ struct task_struct *task = rcu_dereference_protected(mm->owner, true); -+ -+ VM_WARN_ON_ONCE(task->mm != mm); -+ lockdep_assert_held(&task->alloc_lock); -+ -+ /* for mm_update_next_owner() */ -+ if (mem_cgroup_disabled()) -+ return; -+ -+ rcu_read_lock(); -+ memcg = mem_cgroup_from_task(task); -+ rcu_read_unlock(); -+ if (memcg == mm->lru_gen.memcg) -+ return; -+ -+ VM_WARN_ON_ONCE(!mm->lru_gen.memcg); -+ VM_WARN_ON_ONCE(list_empty(&mm->lru_gen.list)); -+ -+ lru_gen_del_mm(mm); -+ lru_gen_add_mm(mm); -+} -+#endif -+ -+/* -+ * Bloom filters with m=1<<15, k=2 and the false positive rates of ~1/5 when -+ * n=10,000 and ~1/2 when n=20,000, where, conventionally, m is the number of -+ * bits in a bitmap, k is the number of hash functions and n is the number of -+ * inserted items. -+ * -+ * Page table walkers use one of the two filters to reduce their search space. -+ * To get rid of non-leaf entries that no longer have enough leaf entries, the -+ * aging uses the double-buffering technique to flip to the other filter each -+ * time it produces a new generation. For non-leaf entries that have enough -+ * leaf entries, the aging carries them over to the next generation in -+ * walk_pmd_range(); the eviction also report them when walking the rmap -+ * in lru_gen_look_around(). -+ * -+ * For future optimizations: -+ * 1. It's not necessary to keep both filters all the time. The spare one can be -+ * freed after the RCU grace period and reallocated if needed again. -+ * 2. And when reallocating, it's worth scaling its size according to the number -+ * of inserted entries in the other filter, to reduce the memory overhead on -+ * small systems and false positives on large systems. -+ * 3. Jenkins' hash function is an alternative to Knuth's. -+ */ -+#define BLOOM_FILTER_SHIFT 15 -+ -+static inline int filter_gen_from_seq(unsigned long seq) -+{ -+ return seq % NR_BLOOM_FILTERS; -+} -+ -+static void get_item_key(void *item, int *key) -+{ -+ u32 hash = hash_ptr(item, BLOOM_FILTER_SHIFT * 2); -+ -+ BUILD_BUG_ON(BLOOM_FILTER_SHIFT * 2 > BITS_PER_TYPE(u32)); -+ -+ key[0] = hash & (BIT(BLOOM_FILTER_SHIFT) - 1); -+ key[1] = hash >> BLOOM_FILTER_SHIFT; -+} -+ -+static void reset_bloom_filter(struct lruvec *lruvec, unsigned long seq) -+{ -+ unsigned long *filter; -+ int gen = filter_gen_from_seq(seq); -+ -+ filter = lruvec->mm_state.filters[gen]; -+ if (filter) { -+ bitmap_clear(filter, 0, BIT(BLOOM_FILTER_SHIFT)); -+ return; -+ } -+ -+ filter = bitmap_zalloc(BIT(BLOOM_FILTER_SHIFT), -+ __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); -+ WRITE_ONCE(lruvec->mm_state.filters[gen], filter); -+} -+ -+static void update_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item) -+{ -+ int key[2]; -+ unsigned long *filter; -+ int gen = filter_gen_from_seq(seq); -+ -+ filter = READ_ONCE(lruvec->mm_state.filters[gen]); -+ if (!filter) -+ return; -+ -+ get_item_key(item, key); -+ -+ if (!test_bit(key[0], filter)) -+ set_bit(key[0], filter); -+ if (!test_bit(key[1], filter)) -+ set_bit(key[1], filter); -+} -+ -+static bool test_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item) -+{ -+ int key[2]; -+ unsigned long *filter; -+ int gen = filter_gen_from_seq(seq); -+ -+ filter = READ_ONCE(lruvec->mm_state.filters[gen]); -+ if (!filter) -+ return true; -+ -+ get_item_key(item, key); -+ -+ return test_bit(key[0], filter) && test_bit(key[1], filter); -+} -+ -+static void reset_mm_stats(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, bool last) -+{ -+ int i; -+ int hist; -+ -+ lockdep_assert_held(&get_mm_list(lruvec_memcg(lruvec))->lock); -+ -+ if (walk) { -+ hist = lru_hist_from_seq(walk->max_seq); -+ -+ for (i = 0; i < NR_MM_STATS; i++) { -+ WRITE_ONCE(lruvec->mm_state.stats[hist][i], -+ lruvec->mm_state.stats[hist][i] + walk->mm_stats[i]); -+ walk->mm_stats[i] = 0; -+ } -+ } -+ -+ if (NR_HIST_GENS > 1 && last) { -+ hist = lru_hist_from_seq(lruvec->mm_state.seq + 1); -+ -+ for (i = 0; i < NR_MM_STATS; i++) -+ WRITE_ONCE(lruvec->mm_state.stats[hist][i], 0); -+ } -+} -+ -+static bool should_skip_mm(struct mm_struct *mm, struct lru_gen_mm_walk *walk) -+{ -+ int type; -+ unsigned long size = 0; -+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); -+ int key = pgdat->node_id % BITS_PER_TYPE(mm->lru_gen.bitmap); -+ -+ if (!walk->force_scan && !test_bit(key, &mm->lru_gen.bitmap)) -+ return true; -+ -+ clear_bit(key, &mm->lru_gen.bitmap); -+ -+ for (type = !walk->can_swap; type < ANON_AND_FILE; type++) { -+ size += type ? get_mm_counter(mm, MM_FILEPAGES) : -+ get_mm_counter(mm, MM_ANONPAGES) + -+ get_mm_counter(mm, MM_SHMEMPAGES); -+ } -+ -+ if (size < MIN_LRU_BATCH) -+ return true; -+ -+ return !mmget_not_zero(mm); -+} -+ -+static bool iterate_mm_list(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, -+ struct mm_struct **iter) -+{ -+ bool first = false; -+ bool last = true; -+ struct mm_struct *mm = NULL; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg); -+ struct lru_gen_mm_state *mm_state = &lruvec->mm_state; -+ -+ /* -+ * There are four interesting cases for this page table walker: -+ * 1. It tries to start a new iteration of mm_list with a stale max_seq; -+ * there is nothing left to do. -+ * 2. It's the first of the current generation, and it needs to reset -+ * the Bloom filter for the next generation. -+ * 3. It reaches the end of mm_list, and it needs to increment -+ * mm_state->seq; the iteration is done. -+ * 4. It's the last of the current generation, and it needs to reset the -+ * mm stats counters for the next generation. -+ */ -+ spin_lock(&mm_list->lock); -+ -+ VM_WARN_ON_ONCE(mm_state->seq + 1 < walk->max_seq); -+ VM_WARN_ON_ONCE(*iter && mm_state->seq > walk->max_seq); -+ VM_WARN_ON_ONCE(*iter && !mm_state->nr_walkers); -+ -+ if (walk->max_seq <= mm_state->seq) { -+ if (!*iter) -+ last = false; -+ goto done; -+ } -+ -+ if (!mm_state->nr_walkers) { -+ VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo); -+ -+ mm_state->head = mm_list->fifo.next; -+ first = true; -+ } -+ -+ while (!mm && mm_state->head != &mm_list->fifo) { -+ mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list); -+ -+ mm_state->head = mm_state->head->next; -+ -+ /* force scan for those added after the last iteration */ -+ if (!mm_state->tail || mm_state->tail == &mm->lru_gen.list) { -+ mm_state->tail = mm_state->head; -+ walk->force_scan = true; -+ } -+ -+ if (should_skip_mm(mm, walk)) -+ mm = NULL; -+ } -+ -+ if (mm_state->head == &mm_list->fifo) -+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1); -+done: -+ if (*iter && !mm) -+ mm_state->nr_walkers--; -+ if (!*iter && mm) -+ mm_state->nr_walkers++; -+ -+ if (mm_state->nr_walkers) -+ last = false; -+ -+ if (*iter || last) -+ reset_mm_stats(lruvec, walk, last); -+ -+ spin_unlock(&mm_list->lock); -+ -+ if (mm && first) -+ reset_bloom_filter(lruvec, walk->max_seq + 1); -+ -+ if (*iter) -+ mmput_async(*iter); -+ -+ *iter = mm; -+ -+ return last; -+} -+ -+static bool iterate_mm_list_nowalk(struct lruvec *lruvec, unsigned long max_seq) -+{ -+ bool success = false; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct lru_gen_mm_list *mm_list = get_mm_list(memcg); -+ struct lru_gen_mm_state *mm_state = &lruvec->mm_state; -+ -+ spin_lock(&mm_list->lock); -+ -+ VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq); -+ -+ if (max_seq > mm_state->seq && !mm_state->nr_walkers) { -+ VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo); -+ -+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1); -+ reset_mm_stats(lruvec, NULL, true); -+ success = true; -+ } -+ -+ spin_unlock(&mm_list->lock); -+ -+ return success; -+} -+ -+/****************************************************************************** - * refault feedback loop - ******************************************************************************/ - -@@ -3048,6 +3415,118 @@ static int page_inc_gen(struct lruvec *l - return new_gen; - } - -+static void update_batch_size(struct lru_gen_mm_walk *walk, struct page *page, -+ int old_gen, int new_gen) -+{ -+ int type = page_is_file_lru(page); -+ int zone = page_zonenum(page); -+ int delta = thp_nr_pages(page); -+ -+ VM_WARN_ON_ONCE(old_gen >= MAX_NR_GENS); -+ VM_WARN_ON_ONCE(new_gen >= MAX_NR_GENS); -+ -+ walk->batched++; -+ -+ walk->nr_pages[old_gen][type][zone] -= delta; -+ walk->nr_pages[new_gen][type][zone] += delta; -+} -+ -+static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk) -+{ -+ int gen, type, zone; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ walk->batched = 0; -+ -+ for_each_gen_type_zone(gen, type, zone) { -+ enum lru_list lru = type * LRU_INACTIVE_FILE; -+ int delta = walk->nr_pages[gen][type][zone]; -+ -+ if (!delta) -+ continue; -+ -+ walk->nr_pages[gen][type][zone] = 0; -+ WRITE_ONCE(lrugen->nr_pages[gen][type][zone], -+ lrugen->nr_pages[gen][type][zone] + delta); -+ -+ if (lru_gen_is_active(lruvec, gen)) -+ lru += LRU_ACTIVE; -+ __update_lru_size(lruvec, lru, zone, delta); -+ } -+} -+ -+static int should_skip_vma(unsigned long start, unsigned long end, struct mm_walk *args) -+{ -+ struct address_space *mapping; -+ struct vm_area_struct *vma = args->vma; -+ struct lru_gen_mm_walk *walk = args->private; -+ -+ if (!vma_is_accessible(vma)) -+ return true; -+ -+ if (is_vm_hugetlb_page(vma)) -+ return true; -+ -+ if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ | VM_RAND_READ)) -+ return true; -+ -+ if (vma == get_gate_vma(vma->vm_mm)) -+ return true; -+ -+ if (vma_is_anonymous(vma)) -+ return !walk->can_swap; -+ -+ if (WARN_ON_ONCE(!vma->vm_file || !vma->vm_file->f_mapping)) -+ return true; -+ -+ mapping = vma->vm_file->f_mapping; -+ if (mapping_unevictable(mapping)) -+ return true; -+ -+ if (shmem_mapping(mapping)) -+ return !walk->can_swap; -+ -+ /* to exclude special mappings like dax, etc. */ -+ return !mapping->a_ops->readpage; -+} -+ -+/* -+ * Some userspace memory allocators map many single-page VMAs. Instead of -+ * returning back to the PGD table for each of such VMAs, finish an entire PMD -+ * table to reduce zigzags and improve cache performance. -+ */ -+static bool get_next_vma(unsigned long mask, unsigned long size, struct mm_walk *args, -+ unsigned long *vm_start, unsigned long *vm_end) -+{ -+ unsigned long start = round_up(*vm_end, size); -+ unsigned long end = (start | ~mask) + 1; -+ -+ VM_WARN_ON_ONCE(mask & size); -+ VM_WARN_ON_ONCE((start & mask) != (*vm_start & mask)); -+ -+ while (args->vma) { -+ if (start >= args->vma->vm_end) { -+ args->vma = args->vma->vm_next; -+ continue; -+ } -+ -+ if (end && end <= args->vma->vm_start) -+ return false; -+ -+ if (should_skip_vma(args->vma->vm_start, args->vma->vm_end, args)) { -+ args->vma = args->vma->vm_next; -+ continue; -+ } -+ -+ *vm_start = max(start, args->vma->vm_start); -+ *vm_end = min(end - 1, args->vma->vm_end - 1) + 1; -+ -+ return true; -+ } -+ -+ return false; -+} -+ - static unsigned long get_pte_pfn(pte_t pte, struct vm_area_struct *vma, unsigned long addr) - { - unsigned long pfn = pte_pfn(pte); -@@ -3066,8 +3545,28 @@ static unsigned long get_pte_pfn(pte_t p - return pfn; - } - -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) -+static unsigned long get_pmd_pfn(pmd_t pmd, struct vm_area_struct *vma, unsigned long addr) -+{ -+ unsigned long pfn = pmd_pfn(pmd); -+ -+ VM_WARN_ON_ONCE(addr < vma->vm_start || addr >= vma->vm_end); -+ -+ if (!pmd_present(pmd) || is_huge_zero_pmd(pmd)) -+ return -1; -+ -+ if (WARN_ON_ONCE(pmd_devmap(pmd))) -+ return -1; -+ -+ if (WARN_ON_ONCE(!pfn_valid(pfn))) -+ return -1; -+ -+ return pfn; -+} -+#endif -+ - static struct page *get_pfn_page(unsigned long pfn, struct mem_cgroup *memcg, -- struct pglist_data *pgdat) -+ struct pglist_data *pgdat, bool can_swap) - { - struct page *page; - -@@ -3082,9 +3581,375 @@ static struct page *get_pfn_page(unsigne - if (page_memcg_rcu(page) != memcg) - return NULL; - -+ /* file VMAs can contain anon pages from COW */ -+ if (!page_is_file_lru(page) && !can_swap) -+ return NULL; -+ - return page; - } - -+static bool suitable_to_scan(int total, int young) -+{ -+ int n = clamp_t(int, cache_line_size() / sizeof(pte_t), 2, 8); -+ -+ /* suitable if the average number of young PTEs per cacheline is >=1 */ -+ return young * n >= total; -+} -+ -+static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end, -+ struct mm_walk *args) -+{ -+ int i; -+ pte_t *pte; -+ spinlock_t *ptl; -+ unsigned long addr; -+ int total = 0; -+ int young = 0; -+ struct lru_gen_mm_walk *walk = args->private; -+ struct mem_cgroup *memcg = lruvec_memcg(walk->lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); -+ int old_gen, new_gen = lru_gen_from_seq(walk->max_seq); -+ -+ VM_WARN_ON_ONCE(pmd_leaf(*pmd)); -+ -+ ptl = pte_lockptr(args->mm, pmd); -+ if (!spin_trylock(ptl)) -+ return false; -+ -+ arch_enter_lazy_mmu_mode(); -+ -+ pte = pte_offset_map(pmd, start & PMD_MASK); -+restart: -+ for (i = pte_index(start), addr = start; addr != end; i++, addr += PAGE_SIZE) { -+ unsigned long pfn; -+ struct page *page; -+ -+ total++; -+ walk->mm_stats[MM_LEAF_TOTAL]++; -+ -+ pfn = get_pte_pfn(pte[i], args->vma, addr); -+ if (pfn == -1) -+ continue; -+ -+ if (!pte_young(pte[i])) { -+ walk->mm_stats[MM_LEAF_OLD]++; -+ continue; -+ } -+ -+ page = get_pfn_page(pfn, memcg, pgdat, walk->can_swap); -+ if (!page) -+ continue; -+ -+ if (!ptep_test_and_clear_young(args->vma, addr, pte + i)) -+ VM_WARN_ON_ONCE(true); -+ -+ young++; -+ walk->mm_stats[MM_LEAF_YOUNG]++; -+ -+ if (pte_dirty(pte[i]) && !PageDirty(page) && -+ !(PageAnon(page) && PageSwapBacked(page) && -+ !PageSwapCache(page))) -+ set_page_dirty(page); -+ -+ old_gen = page_update_gen(page, new_gen); -+ if (old_gen >= 0 && old_gen != new_gen) -+ update_batch_size(walk, page, old_gen, new_gen); -+ } -+ -+ if (i < PTRS_PER_PTE && get_next_vma(PMD_MASK, PAGE_SIZE, args, &start, &end)) -+ goto restart; -+ -+ pte_unmap(pte); -+ -+ arch_leave_lazy_mmu_mode(); -+ spin_unlock(ptl); -+ -+ return suitable_to_scan(total, young); -+} -+ -+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) -+static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma, -+ struct mm_walk *args, unsigned long *bitmap, unsigned long *start) -+{ -+ int i; -+ pmd_t *pmd; -+ spinlock_t *ptl; -+ struct lru_gen_mm_walk *walk = args->private; -+ struct mem_cgroup *memcg = lruvec_memcg(walk->lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); -+ int old_gen, new_gen = lru_gen_from_seq(walk->max_seq); -+ -+ VM_WARN_ON_ONCE(pud_leaf(*pud)); -+ -+ /* try to batch at most 1+MIN_LRU_BATCH+1 entries */ -+ if (*start == -1) { -+ *start = next; -+ return; -+ } -+ -+ i = next == -1 ? 0 : pmd_index(next) - pmd_index(*start); -+ if (i && i <= MIN_LRU_BATCH) { -+ __set_bit(i - 1, bitmap); -+ return; -+ } -+ -+ pmd = pmd_offset(pud, *start); -+ -+ ptl = pmd_lockptr(args->mm, pmd); -+ if (!spin_trylock(ptl)) -+ goto done; -+ -+ arch_enter_lazy_mmu_mode(); -+ -+ do { -+ unsigned long pfn; -+ struct page *page; -+ unsigned long addr = i ? (*start & PMD_MASK) + i * PMD_SIZE : *start; -+ -+ pfn = get_pmd_pfn(pmd[i], vma, addr); -+ if (pfn == -1) -+ goto next; -+ -+ if (!pmd_trans_huge(pmd[i])) { -+ if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)) -+ pmdp_test_and_clear_young(vma, addr, pmd + i); -+ goto next; -+ } -+ -+ page = get_pfn_page(pfn, memcg, pgdat, walk->can_swap); -+ if (!page) -+ goto next; -+ -+ if (!pmdp_test_and_clear_young(vma, addr, pmd + i)) -+ goto next; -+ -+ walk->mm_stats[MM_LEAF_YOUNG]++; -+ -+ if (pmd_dirty(pmd[i]) && !PageDirty(page) && -+ !(PageAnon(page) && PageSwapBacked(page) && -+ !PageSwapCache(page))) -+ set_page_dirty(page); -+ -+ old_gen = page_update_gen(page, new_gen); -+ if (old_gen >= 0 && old_gen != new_gen) -+ update_batch_size(walk, page, old_gen, new_gen); -+next: -+ i = i > MIN_LRU_BATCH ? 0 : find_next_bit(bitmap, MIN_LRU_BATCH, i) + 1; -+ } while (i <= MIN_LRU_BATCH); -+ -+ arch_leave_lazy_mmu_mode(); -+ spin_unlock(ptl); -+done: -+ *start = -1; -+ bitmap_zero(bitmap, MIN_LRU_BATCH); -+} -+#else -+static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma, -+ struct mm_walk *args, unsigned long *bitmap, unsigned long *start) -+{ -+} -+#endif -+ -+static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end, -+ struct mm_walk *args) -+{ -+ int i; -+ pmd_t *pmd; -+ unsigned long next; -+ unsigned long addr; -+ struct vm_area_struct *vma; -+ unsigned long pos = -1; -+ struct lru_gen_mm_walk *walk = args->private; -+ unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {}; -+ -+ VM_WARN_ON_ONCE(pud_leaf(*pud)); -+ -+ /* -+ * Finish an entire PMD in two passes: the first only reaches to PTE -+ * tables to avoid taking the PMD lock; the second, if necessary, takes -+ * the PMD lock to clear the accessed bit in PMD entries. -+ */ -+ pmd = pmd_offset(pud, start & PUD_MASK); -+restart: -+ /* walk_pte_range() may call get_next_vma() */ -+ vma = args->vma; -+ for (i = pmd_index(start), addr = start; addr != end; i++, addr = next) { -+ pmd_t val = pmd_read_atomic(pmd + i); -+ -+ /* for pmd_read_atomic() */ -+ barrier(); -+ -+ next = pmd_addr_end(addr, end); -+ -+ if (!pmd_present(val) || is_huge_zero_pmd(val)) { -+ walk->mm_stats[MM_LEAF_TOTAL]++; -+ continue; -+ } -+ -+#ifdef CONFIG_TRANSPARENT_HUGEPAGE -+ if (pmd_trans_huge(val)) { -+ unsigned long pfn = pmd_pfn(val); -+ struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec); -+ -+ walk->mm_stats[MM_LEAF_TOTAL]++; -+ -+ if (!pmd_young(val)) { -+ walk->mm_stats[MM_LEAF_OLD]++; -+ continue; -+ } -+ -+ /* try to avoid unnecessary memory loads */ -+ if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) -+ continue; -+ -+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); -+ continue; -+ } -+#endif -+ walk->mm_stats[MM_NONLEAF_TOTAL]++; -+ -+#ifdef CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG -+ if (!pmd_young(val)) -+ continue; -+ -+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); -+#endif -+ if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i)) -+ continue; -+ -+ walk->mm_stats[MM_NONLEAF_FOUND]++; -+ -+ if (!walk_pte_range(&val, addr, next, args)) -+ continue; -+ -+ walk->mm_stats[MM_NONLEAF_ADDED]++; -+ -+ /* carry over to the next generation */ -+ update_bloom_filter(walk->lruvec, walk->max_seq + 1, pmd + i); -+ } -+ -+ walk_pmd_range_locked(pud, -1, vma, args, bitmap, &pos); -+ -+ if (i < PTRS_PER_PMD && get_next_vma(PUD_MASK, PMD_SIZE, args, &start, &end)) -+ goto restart; -+} -+ -+static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end, -+ struct mm_walk *args) -+{ -+ int i; -+ pud_t *pud; -+ unsigned long addr; -+ unsigned long next; -+ struct lru_gen_mm_walk *walk = args->private; -+ -+ VM_WARN_ON_ONCE(p4d_leaf(*p4d)); -+ -+ pud = pud_offset(p4d, start & P4D_MASK); -+restart: -+ for (i = pud_index(start), addr = start; addr != end; i++, addr = next) { -+ pud_t val = READ_ONCE(pud[i]); -+ -+ next = pud_addr_end(addr, end); -+ -+ if (!pud_present(val) || WARN_ON_ONCE(pud_leaf(val))) -+ continue; -+ -+ walk_pmd_range(&val, addr, next, args); -+ -+ /* a racy check to curtail the waiting time */ -+ if (wq_has_sleeper(&walk->lruvec->mm_state.wait)) -+ return 1; -+ -+ if (need_resched() || walk->batched >= MAX_LRU_BATCH) { -+ end = (addr | ~PUD_MASK) + 1; -+ goto done; -+ } -+ } -+ -+ if (i < PTRS_PER_PUD && get_next_vma(P4D_MASK, PUD_SIZE, args, &start, &end)) -+ goto restart; -+ -+ end = round_up(end, P4D_SIZE); -+done: -+ if (!end || !args->vma) -+ return 1; -+ -+ walk->next_addr = max(end, args->vma->vm_start); -+ -+ return -EAGAIN; -+} -+ -+static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk) -+{ -+ static const struct mm_walk_ops mm_walk_ops = { -+ .test_walk = should_skip_vma, -+ .p4d_entry = walk_pud_range, -+ }; -+ -+ int err; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ -+ walk->next_addr = FIRST_USER_ADDRESS; -+ -+ do { -+ err = -EBUSY; -+ -+ /* page_update_gen() requires stable page_memcg() */ -+ if (!mem_cgroup_trylock_pages(memcg)) -+ break; -+ -+ /* the caller might be holding the lock for write */ -+ if (mmap_read_trylock(mm)) { -+ err = walk_page_range(mm, walk->next_addr, ULONG_MAX, &mm_walk_ops, walk); -+ -+ mmap_read_unlock(mm); -+ } -+ -+ mem_cgroup_unlock_pages(); -+ -+ if (walk->batched) { -+ spin_lock_irq(&lruvec->lru_lock); -+ reset_batch_size(lruvec, walk); -+ spin_unlock_irq(&lruvec->lru_lock); -+ } -+ -+ cond_resched(); -+ } while (err == -EAGAIN); -+} -+ -+static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat) -+{ -+ struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk; -+ -+ if (pgdat && current_is_kswapd()) { -+ VM_WARN_ON_ONCE(walk); -+ -+ walk = &pgdat->mm_walk; -+ } else if (!pgdat && !walk) { -+ VM_WARN_ON_ONCE(current_is_kswapd()); -+ -+ walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); -+ } -+ -+ current->reclaim_state->mm_walk = walk; -+ -+ return walk; -+} -+ -+static void clear_mm_walk(void) -+{ -+ struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk; -+ -+ VM_WARN_ON_ONCE(walk && memchr_inv(walk->nr_pages, 0, sizeof(walk->nr_pages))); -+ VM_WARN_ON_ONCE(walk && memchr_inv(walk->mm_stats, 0, sizeof(walk->mm_stats))); -+ -+ current->reclaim_state->mm_walk = NULL; -+ -+ if (!current_is_kswapd()) -+ kfree(walk); -+} -+ - static void inc_min_seq(struct lruvec *lruvec, int type) - { - struct lru_gen_struct *lrugen = &lruvec->lrugen; -@@ -3136,7 +4001,7 @@ next: - return success; - } - --static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, bool can_swap) -+static void inc_max_seq(struct lruvec *lruvec, bool can_swap) - { - int prev, next; - int type, zone; -@@ -3146,9 +4011,6 @@ static void inc_max_seq(struct lruvec *l - - VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); - -- if (max_seq != lrugen->max_seq) -- goto unlock; -- - for (type = ANON_AND_FILE - 1; type >= 0; type--) { - if (get_nr_gens(lruvec, type) != MAX_NR_GENS) - continue; -@@ -3186,10 +4048,76 @@ static void inc_max_seq(struct lruvec *l - - /* make sure preceding modifications appear */ - smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1); --unlock: -+ - spin_unlock_irq(&lruvec->lru_lock); - } - -+static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, -+ struct scan_control *sc, bool can_swap) -+{ -+ bool success; -+ struct lru_gen_mm_walk *walk; -+ struct mm_struct *mm = NULL; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq)); -+ -+ /* see the comment in iterate_mm_list() */ -+ if (max_seq <= READ_ONCE(lruvec->mm_state.seq)) { -+ success = false; -+ goto done; -+ } -+ -+ /* -+ * If the hardware doesn't automatically set the accessed bit, fallback -+ * to lru_gen_look_around(), which only clears the accessed bit in a -+ * handful of PTEs. Spreading the work out over a period of time usually -+ * is less efficient, but it avoids bursty page faults. -+ */ -+ if (!arch_has_hw_pte_young()) { -+ success = iterate_mm_list_nowalk(lruvec, max_seq); -+ goto done; -+ } -+ -+ walk = set_mm_walk(NULL); -+ if (!walk) { -+ success = iterate_mm_list_nowalk(lruvec, max_seq); -+ goto done; -+ } -+ -+ walk->lruvec = lruvec; -+ walk->max_seq = max_seq; -+ walk->can_swap = can_swap; -+ walk->force_scan = false; -+ -+ do { -+ success = iterate_mm_list(lruvec, walk, &mm); -+ if (mm) -+ walk_mm(lruvec, mm, walk); -+ -+ cond_resched(); -+ } while (mm); -+done: -+ if (!success) { -+ if (sc->priority <= DEF_PRIORITY - 2) -+ wait_event_killable(lruvec->mm_state.wait, -+ max_seq < READ_ONCE(lrugen->max_seq)); -+ -+ return max_seq < READ_ONCE(lrugen->max_seq); -+ } -+ -+ VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq)); -+ -+ inc_max_seq(lruvec, can_swap); -+ /* either this sees any waiters or they will see updated max_seq */ -+ if (wq_has_sleeper(&lruvec->mm_state.wait)) -+ wake_up_all(&lruvec->mm_state.wait); -+ -+ wakeup_flusher_threads(WB_REASON_VMSCAN); -+ -+ return true; -+} -+ - static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq, - struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) - { -@@ -3265,7 +4193,7 @@ static void age_lruvec(struct lruvec *lr - - need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan); - if (need_aging) -- inc_max_seq(lruvec, max_seq, swappiness); -+ try_to_inc_max_seq(lruvec, max_seq, sc, swappiness); - } - - static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) -@@ -3274,6 +4202,8 @@ static void lru_gen_age_node(struct pgli - - VM_WARN_ON_ONCE(!current_is_kswapd()); - -+ set_mm_walk(pgdat); -+ - memcg = mem_cgroup_iter(NULL, NULL, NULL); - do { - struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); -@@ -3282,11 +4212,16 @@ static void lru_gen_age_node(struct pgli - - cond_resched(); - } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+ -+ clear_mm_walk(); - } - - /* - * This function exploits spatial locality when shrink_page_list() walks the -- * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. -+ * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. If -+ * the scan was done cacheline efficiently, it adds the PMD entry pointing to -+ * the PTE table to the Bloom filter. This forms a feedback loop between the -+ * eviction and the aging. - */ - void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) - { -@@ -3295,6 +4230,8 @@ void lru_gen_look_around(struct page_vma - unsigned long start; - unsigned long end; - unsigned long addr; -+ struct lru_gen_mm_walk *walk; -+ int young = 0; - unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {}; - struct page *page = pvmw->page; - struct mem_cgroup *memcg = page_memcg(page); -@@ -3309,6 +4246,9 @@ void lru_gen_look_around(struct page_vma - if (spin_is_contended(pvmw->ptl)) - return; - -+ /* avoid taking the LRU lock under the PTL when possible */ -+ walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL; -+ - start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start); - end = min(pvmw->address | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1; - -@@ -3338,13 +4278,15 @@ void lru_gen_look_around(struct page_vma - if (!pte_young(pte[i])) - continue; - -- page = get_pfn_page(pfn, memcg, pgdat); -+ page = get_pfn_page(pfn, memcg, pgdat, !walk || walk->can_swap); - if (!page) - continue; - - if (!ptep_test_and_clear_young(pvmw->vma, addr, pte + i)) - VM_WARN_ON_ONCE(true); - -+ young++; -+ - if (pte_dirty(pte[i]) && !PageDirty(page) && - !(PageAnon(page) && PageSwapBacked(page) && - !PageSwapCache(page))) -@@ -3360,7 +4302,11 @@ void lru_gen_look_around(struct page_vma - arch_leave_lazy_mmu_mode(); - rcu_read_unlock(); - -- if (bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) { -+ /* feedback from rmap walkers to page table walkers */ -+ if (suitable_to_scan(i, young)) -+ update_bloom_filter(lruvec, max_seq, pvmw->pmd); -+ -+ if (!walk && bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) { - for_each_set_bit(i, bitmap, MIN_LRU_BATCH) { - page = pte_page(pte[i]); - activate_page(page); -@@ -3372,8 +4318,10 @@ void lru_gen_look_around(struct page_vma - if (!mem_cgroup_trylock_pages(memcg)) - return; - -- spin_lock_irq(&lruvec->lru_lock); -- new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq); -+ if (!walk) { -+ spin_lock_irq(&lruvec->lru_lock); -+ new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq); -+ } - - for_each_set_bit(i, bitmap, MIN_LRU_BATCH) { - page = compound_head(pte_page(pte[i])); -@@ -3384,10 +4332,14 @@ void lru_gen_look_around(struct page_vma - if (old_gen < 0 || old_gen == new_gen) - continue; - -- lru_gen_update_size(lruvec, page, old_gen, new_gen); -+ if (walk) -+ update_batch_size(walk, page, old_gen, new_gen); -+ else -+ lru_gen_update_size(lruvec, page, old_gen, new_gen); - } - -- spin_unlock_irq(&lruvec->lru_lock); -+ if (!walk) -+ spin_unlock_irq(&lruvec->lru_lock); - - mem_cgroup_unlock_pages(); - } -@@ -3670,6 +4622,7 @@ static int evict_pages(struct lruvec *lr - struct page *page; - enum vm_event_item item; - struct reclaim_stat stat; -+ struct lru_gen_mm_walk *walk; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - struct pglist_data *pgdat = lruvec_pgdat(lruvec); - -@@ -3706,6 +4659,10 @@ static int evict_pages(struct lruvec *lr - - move_pages_to_lru(lruvec, &list); - -+ walk = current->reclaim_state->mm_walk; -+ if (walk && walk->batched) -+ reset_batch_size(lruvec, walk); -+ - item = current_is_kswapd() ? PGSTEAL_KSWAPD : PGSTEAL_DIRECT; - if (!cgroup_reclaim(sc)) - __count_vm_events(item, reclaimed); -@@ -3722,6 +4679,11 @@ static int evict_pages(struct lruvec *lr - return scanned; - } - -+/* -+ * For future optimizations: -+ * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg -+ * reclaim. -+ */ - static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, - bool can_swap) - { -@@ -3747,7 +4709,8 @@ static unsigned long get_nr_to_scan(stru - if (current_is_kswapd()) - return 0; - -- inc_max_seq(lruvec, max_seq, can_swap); -+ if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap)) -+ return nr_to_scan; - done: - return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; - } -@@ -3761,6 +4724,8 @@ static void lru_gen_shrink_lruvec(struct - - blk_start_plug(&plug); - -+ set_mm_walk(lruvec_pgdat(lruvec)); -+ - while (true) { - int delta; - int swappiness; -@@ -3788,6 +4753,8 @@ static void lru_gen_shrink_lruvec(struct - cond_resched(); - } - -+ clear_mm_walk(); -+ - blk_finish_plug(&plug); - } - -@@ -3804,15 +4771,21 @@ void lru_gen_init_lruvec(struct lruvec * - - for_each_gen_type_zone(gen, type, zone) - INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); -+ -+ lruvec->mm_state.seq = MIN_NR_GENS; -+ init_waitqueue_head(&lruvec->mm_state.wait); - } - - #ifdef CONFIG_MEMCG - void lru_gen_init_memcg(struct mem_cgroup *memcg) - { -+ INIT_LIST_HEAD(&memcg->mm_list.fifo); -+ spin_lock_init(&memcg->mm_list.lock); - } - - void lru_gen_exit_memcg(struct mem_cgroup *memcg) - { -+ int i; - int nid; - - for_each_node(nid) { -@@ -3820,6 +4793,11 @@ void lru_gen_exit_memcg(struct mem_cgrou - - VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0, - sizeof(lruvec->lrugen.nr_pages))); -+ -+ for (i = 0; i < NR_BLOOM_FILTERS; i++) { -+ bitmap_free(lruvec->mm_state.filters[i]); -+ lruvec->mm_state.filters[i] = NULL; -+ } - } - } - #endif diff --git a/target/linux/generic/backport-5.15/020-v6.1-09-mm-multi-gen-LRU-optimize-multiple-memcgs.patch b/target/linux/generic/backport-5.15/020-v6.1-09-mm-multi-gen-LRU-optimize-multiple-memcgs.patch deleted file mode 100644 index b5fb1951514d00..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-09-mm-multi-gen-LRU-optimize-multiple-memcgs.patch +++ /dev/null @@ -1,315 +0,0 @@ -From 36a18a68ea458e8f4db2ca86b00091daf32c6c74 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 02:00:06 -0600 -Subject: [PATCH 09/29] mm: multi-gen LRU: optimize multiple memcgs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When multiple memcgs are available, it is possible to use generations as a -frame of reference to make better choices and improve overall performance -under global memory pressure. This patch adds a basic optimization to -select memcgs that can drop single-use unmapped clean pages first. Doing -so reduces the chance of going into the aging path or swapping, which can -be costly. - -A typical example that benefits from this optimization is a server running -mixed types of workloads, e.g., heavy anon workload in one memcg and heavy -buffered I/O workload in the other. - -Though this optimization can be applied to both kswapd and direct reclaim, -it is only added to kswapd to keep the patchset manageable. Later -improvements may cover the direct reclaim path. - -While ensuring certain fairness to all eligible memcgs, proportional scans -of individual memcgs also require proper backoff to avoid overshooting -their aggregate reclaim target by too much. Otherwise it can cause high -direct reclaim latency. The conditions for backoff are: - -1. At low priorities, for direct reclaim, if aging fairness or direct - reclaim latency is at risk, i.e., aging one memcg multiple times or - swapping after the target is met. -2. At high priorities, for global reclaim, if per-zone free pages are - above respective watermarks. - -Server benchmark results: - Mixed workloads: - fio (buffered I/O): +[19, 21]% - IOPS BW - patch1-8: 1880k 7343MiB/s - patch1-9: 2252k 8796MiB/s - - memcached (anon): +[119, 123]% - Ops/sec KB/sec - patch1-8: 862768.65 33514.68 - patch1-9: 1911022.12 74234.54 - - Mixed workloads: - fio (buffered I/O): +[75, 77]% - IOPS BW - 5.19-rc1: 1279k 4996MiB/s - patch1-9: 2252k 8796MiB/s - - memcached (anon): +[13, 15]% - Ops/sec KB/sec - 5.19-rc1: 1673524.04 65008.87 - patch1-9: 1911022.12 74234.54 - - Configurations: - (changes since patch 6) - - cat mixed.sh - modprobe brd rd_nr=2 rd_size=56623104 - - swapoff -a - mkswap /dev/ram0 - swapon /dev/ram0 - - mkfs.ext4 /dev/ram1 - mount -t ext4 /dev/ram1 /mnt - - memtier_benchmark -S /var/run/memcached/memcached.sock \ - -P memcache_binary -n allkeys --key-minimum=1 \ - --key-maximum=50000000 --key-pattern=P:P -c 1 -t 36 \ - --ratio 1:0 --pipeline 8 -d 2000 - - fio -name=mglru --numjobs=36 --directory=/mnt --size=1408m \ - --buffered=1 --ioengine=io_uring --iodepth=128 \ - --iodepth_batch_submit=32 --iodepth_batch_complete=32 \ - --rw=randread --random_distribution=random --norandommap \ - --time_based --ramp_time=10m --runtime=90m --group_reporting & - pid=$! - - sleep 200 - - memtier_benchmark -S /var/run/memcached/memcached.sock \ - -P memcache_binary -n allkeys --key-minimum=1 \ - --key-maximum=50000000 --key-pattern=R:R -c 1 -t 36 \ - --ratio 0:1 --pipeline 8 --randomize --distinct-client-seed - - kill -INT $pid - wait - -Client benchmark results: - no change (CONFIG_MEMCG=n) - -Link: https://lkml.kernel.org/r/20220918080010.2920238-10-yuzhao@google.com -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Barry Song -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Miaohe Lin -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Qi Zheng -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 96 insertions(+), 9 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -127,6 +127,12 @@ struct scan_control { - /* Always discard instead of demoting to lower tier memory */ - unsigned int no_demotion:1; - -+#ifdef CONFIG_LRU_GEN -+ /* help kswapd make better choices among multiple memcgs */ -+ unsigned int memcgs_need_aging:1; -+ unsigned long last_reclaimed; -+#endif -+ - /* Allocation order */ - s8 order; - -@@ -4202,6 +4208,19 @@ static void lru_gen_age_node(struct pgli - - VM_WARN_ON_ONCE(!current_is_kswapd()); - -+ sc->last_reclaimed = sc->nr_reclaimed; -+ -+ /* -+ * To reduce the chance of going into the aging path, which can be -+ * costly, optimistically skip it if the flag below was cleared in the -+ * eviction path. This improves the overall performance when multiple -+ * memcgs are available. -+ */ -+ if (!sc->memcgs_need_aging) { -+ sc->memcgs_need_aging = true; -+ return; -+ } -+ - set_mm_walk(pgdat); - - memcg = mem_cgroup_iter(NULL, NULL, NULL); -@@ -4613,7 +4632,8 @@ static int isolate_pages(struct lruvec * - return scanned; - } - --static int evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness) -+static int evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness, -+ bool *need_swapping) - { - int type; - int scanned; -@@ -4676,6 +4696,9 @@ static int evict_pages(struct lruvec *lr - - sc->nr_reclaimed += reclaimed; - -+ if (need_swapping && type == LRU_GEN_ANON) -+ *need_swapping = true; -+ - return scanned; - } - -@@ -4685,9 +4708,8 @@ static int evict_pages(struct lruvec *lr - * reclaim. - */ - static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, -- bool can_swap) -+ bool can_swap, bool *need_aging) - { -- bool need_aging; - unsigned long nr_to_scan; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MAX_SEQ(lruvec); -@@ -4697,8 +4719,8 @@ static unsigned long get_nr_to_scan(stru - (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) - return 0; - -- need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan); -- if (!need_aging) -+ *need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan); -+ if (!*need_aging) - return nr_to_scan; - - /* skip the aging path at the default priority */ -@@ -4715,10 +4737,68 @@ done: - return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; - } - -+static bool should_abort_scan(struct lruvec *lruvec, unsigned long seq, -+ struct scan_control *sc, bool need_swapping) -+{ -+ int i; -+ DEFINE_MAX_SEQ(lruvec); -+ -+ if (!current_is_kswapd()) { -+ /* age each memcg once to ensure fairness */ -+ if (max_seq - seq > 1) -+ return true; -+ -+ /* over-swapping can increase allocation latency */ -+ if (sc->nr_reclaimed >= sc->nr_to_reclaim && need_swapping) -+ return true; -+ -+ /* give this thread a chance to exit and free its memory */ -+ if (fatal_signal_pending(current)) { -+ sc->nr_reclaimed += MIN_LRU_BATCH; -+ return true; -+ } -+ -+ if (cgroup_reclaim(sc)) -+ return false; -+ } else if (sc->nr_reclaimed - sc->last_reclaimed < sc->nr_to_reclaim) -+ return false; -+ -+ /* keep scanning at low priorities to ensure fairness */ -+ if (sc->priority > DEF_PRIORITY - 2) -+ return false; -+ -+ /* -+ * A minimum amount of work was done under global memory pressure. For -+ * kswapd, it may be overshooting. For direct reclaim, the target isn't -+ * met, and yet the allocation may still succeed, since kswapd may have -+ * caught up. In either case, it's better to stop now, and restart if -+ * necessary. -+ */ -+ for (i = 0; i <= sc->reclaim_idx; i++) { -+ unsigned long wmark; -+ struct zone *zone = lruvec_pgdat(lruvec)->node_zones + i; -+ -+ if (!managed_zone(zone)) -+ continue; -+ -+ wmark = current_is_kswapd() ? high_wmark_pages(zone) : low_wmark_pages(zone); -+ if (wmark > zone_page_state(zone, NR_FREE_PAGES)) -+ return false; -+ } -+ -+ sc->nr_reclaimed += MIN_LRU_BATCH; -+ -+ return true; -+} -+ - static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { - struct blk_plug plug; -+ bool need_aging = false; -+ bool need_swapping = false; - unsigned long scanned = 0; -+ unsigned long reclaimed = sc->nr_reclaimed; -+ DEFINE_MAX_SEQ(lruvec); - - lru_add_drain(); - -@@ -4738,21 +4818,28 @@ static void lru_gen_shrink_lruvec(struct - else - swappiness = 0; - -- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); -+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness, &need_aging); - if (!nr_to_scan) -- break; -+ goto done; - -- delta = evict_pages(lruvec, sc, swappiness); -+ delta = evict_pages(lruvec, sc, swappiness, &need_swapping); - if (!delta) -- break; -+ goto done; - - scanned += delta; - if (scanned >= nr_to_scan) - break; - -+ if (should_abort_scan(lruvec, max_seq, sc, need_swapping)) -+ break; -+ - cond_resched(); - } - -+ /* see the comment in lru_gen_age_node() */ -+ if (sc->nr_reclaimed - reclaimed >= MIN_LRU_BATCH && !need_aging) -+ sc->memcgs_need_aging = false; -+done: - clear_mm_walk(); - - blk_finish_plug(&plug); diff --git a/target/linux/generic/backport-5.15/020-v6.1-10-mm-multi-gen-LRU-kill-switch.patch b/target/linux/generic/backport-5.15/020-v6.1-10-mm-multi-gen-LRU-kill-switch.patch deleted file mode 100644 index 8ee032fb0f0c35..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-10-mm-multi-gen-LRU-kill-switch.patch +++ /dev/null @@ -1,498 +0,0 @@ -From 640db3a029dca909af47157ca18f52b29d34a1b9 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 02:00:07 -0600 -Subject: [PATCH 10/29] mm: multi-gen LRU: kill switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add /sys/kernel/mm/lru_gen/enabled as a kill switch. Components that -can be disabled include: - 0x0001: the multi-gen LRU core - 0x0002: walking page table, when arch_has_hw_pte_young() returns - true - 0x0004: clearing the accessed bit in non-leaf PMD entries, when - CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y - [yYnN]: apply to all the components above -E.g., - echo y >/sys/kernel/mm/lru_gen/enabled - cat /sys/kernel/mm/lru_gen/enabled - 0x0007 - echo 5 >/sys/kernel/mm/lru_gen/enabled - cat /sys/kernel/mm/lru_gen/enabled - 0x0005 - -NB: the page table walks happen on the scale of seconds under heavy memory -pressure, in which case the mmap_lock contention is a lesser concern, -compared with the LRU lock contention and the I/O congestion. So far the -only well-known case of the mmap_lock contention happens on Android, due -to Scudo [1] which allocates several thousand VMAs for merely a few -hundred MBs. The SPF and the Maple Tree also have provided their own -assessments [2][3]. However, if walking page tables does worsen the -mmap_lock contention, the kill switch can be used to disable it. In this -case the multi-gen LRU will suffer a minor performance degradation, as -shown previously. - -Clearing the accessed bit in non-leaf PMD entries can also be disabled, -since this behavior was not tested on x86 varieties other than Intel and -AMD. - -[1] https://source.android.com/devices/tech/debug/scudo -[2] https://lore.kernel.org/r/20220128131006.67712-1-michel@lespinasse.org/ -[3] https://lore.kernel.org/r/20220426150616.3937571-1-Liam.Howlett@oracle.com/ - -Link: https://lkml.kernel.org/r/20220918080010.2920238-11-yuzhao@google.com -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Barry Song -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Miaohe Lin -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Qi Zheng -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - include/linux/cgroup.h | 15 ++- - include/linux/mm_inline.h | 15 ++- - include/linux/mmzone.h | 9 ++ - kernel/cgroup/cgroup-internal.h | 1 - - mm/Kconfig | 6 + - mm/vmscan.c | 228 +++++++++++++++++++++++++++++++- - 6 files changed, 265 insertions(+), 9 deletions(-) - ---- a/include/linux/cgroup.h -+++ b/include/linux/cgroup.h -@@ -433,6 +433,18 @@ static inline void cgroup_put(struct cgr - css_put(&cgrp->self); - } - -+extern struct mutex cgroup_mutex; -+ -+static inline void cgroup_lock(void) -+{ -+ mutex_lock(&cgroup_mutex); -+} -+ -+static inline void cgroup_unlock(void) -+{ -+ mutex_unlock(&cgroup_mutex); -+} -+ - /** - * task_css_set_check - obtain a task's css_set with extra access conditions - * @task: the task to obtain css_set for -@@ -447,7 +459,6 @@ static inline void cgroup_put(struct cgr - * as locks used during the cgroup_subsys::attach() methods. - */ - #ifdef CONFIG_PROVE_RCU --extern struct mutex cgroup_mutex; - extern spinlock_t css_set_lock; - #define task_css_set_check(task, __c) \ - rcu_dereference_check((task)->cgroups, \ -@@ -709,6 +720,8 @@ struct cgroup; - static inline u64 cgroup_id(const struct cgroup *cgrp) { return 1; } - static inline void css_get(struct cgroup_subsys_state *css) {} - static inline void css_put(struct cgroup_subsys_state *css) {} -+static inline void cgroup_lock(void) {} -+static inline void cgroup_unlock(void) {} - static inline int cgroup_attach_task_all(struct task_struct *from, - struct task_struct *t) { return 0; } - static inline int cgroupstats_build(struct cgroupstats *stats, ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -91,10 +91,21 @@ static __always_inline enum lru_list pag - - #ifdef CONFIG_LRU_GEN - -+#ifdef CONFIG_LRU_GEN_ENABLED - static inline bool lru_gen_enabled(void) - { -- return true; -+ DECLARE_STATIC_KEY_TRUE(lru_gen_caps[NR_LRU_GEN_CAPS]); -+ -+ return static_branch_likely(&lru_gen_caps[LRU_GEN_CORE]); -+} -+#else -+static inline bool lru_gen_enabled(void) -+{ -+ DECLARE_STATIC_KEY_FALSE(lru_gen_caps[NR_LRU_GEN_CAPS]); -+ -+ return static_branch_unlikely(&lru_gen_caps[LRU_GEN_CORE]); - } -+#endif - - static inline bool lru_gen_in_fault(void) - { -@@ -207,7 +218,7 @@ static inline bool lru_gen_add_page(stru - - VM_WARN_ON_ONCE_PAGE(gen != -1, page); - -- if (PageUnevictable(page)) -+ if (PageUnevictable(page) || !lrugen->enabled) - return false; - /* - * There are three common cases for this page: ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -364,6 +364,13 @@ enum { - LRU_GEN_FILE, - }; - -+enum { -+ LRU_GEN_CORE, -+ LRU_GEN_MM_WALK, -+ LRU_GEN_NONLEAF_YOUNG, -+ NR_LRU_GEN_CAPS -+}; -+ - #define MIN_LRU_BATCH BITS_PER_LONG - #define MAX_LRU_BATCH (MIN_LRU_BATCH * 64) - -@@ -405,6 +412,8 @@ struct lru_gen_struct { - /* can be modified without holding the LRU lock */ - atomic_long_t evicted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; - atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; -+ /* whether the multi-gen LRU is enabled */ -+ bool enabled; - }; - - enum { ---- a/kernel/cgroup/cgroup-internal.h -+++ b/kernel/cgroup/cgroup-internal.h -@@ -165,7 +165,6 @@ struct cgroup_mgctx { - #define DEFINE_CGROUP_MGCTX(name) \ - struct cgroup_mgctx name = CGROUP_MGCTX_INIT(name) - --extern struct mutex cgroup_mutex; - extern spinlock_t css_set_lock; - extern struct cgroup_subsys *cgroup_subsys[]; - extern struct list_head cgroup_roots; ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -906,6 +906,12 @@ config LRU_GEN - help - A high performance LRU implementation to overcommit memory. - -+config LRU_GEN_ENABLED -+ bool "Enable by default" -+ depends on LRU_GEN -+ help -+ This option enables the multi-gen LRU by default. -+ - config LRU_GEN_STATS - bool "Full stats for debugging" - depends on LRU_GEN ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -52,6 +52,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -2841,6 +2842,14 @@ static bool can_age_anon_pages(struct pg - - #ifdef CONFIG_LRU_GEN - -+#ifdef CONFIG_LRU_GEN_ENABLED -+DEFINE_STATIC_KEY_ARRAY_TRUE(lru_gen_caps, NR_LRU_GEN_CAPS); -+#define get_cap(cap) static_branch_likely(&lru_gen_caps[cap]) -+#else -+DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_caps, NR_LRU_GEN_CAPS); -+#define get_cap(cap) static_branch_unlikely(&lru_gen_caps[cap]) -+#endif -+ - /****************************************************************************** - * shorthand helpers - ******************************************************************************/ -@@ -3717,7 +3726,8 @@ static void walk_pmd_range_locked(pud_t - goto next; - - if (!pmd_trans_huge(pmd[i])) { -- if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)) -+ if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) && -+ get_cap(LRU_GEN_NONLEAF_YOUNG)) - pmdp_test_and_clear_young(vma, addr, pmd + i); - goto next; - } -@@ -3815,10 +3825,12 @@ restart: - walk->mm_stats[MM_NONLEAF_TOTAL]++; - - #ifdef CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG -- if (!pmd_young(val)) -- continue; -+ if (get_cap(LRU_GEN_NONLEAF_YOUNG)) { -+ if (!pmd_young(val)) -+ continue; - -- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); -+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); -+ } - #endif - if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i)) - continue; -@@ -4080,7 +4092,7 @@ static bool try_to_inc_max_seq(struct lr - * handful of PTEs. Spreading the work out over a period of time usually - * is less efficient, but it avoids bursty page faults. - */ -- if (!arch_has_hw_pte_young()) { -+ if (!(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) { - success = iterate_mm_list_nowalk(lruvec, max_seq); - goto done; - } -@@ -4846,6 +4858,208 @@ done: - } - - /****************************************************************************** -+ * state change -+ ******************************************************************************/ -+ -+static bool __maybe_unused state_is_valid(struct lruvec *lruvec) -+{ -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ if (lrugen->enabled) { -+ enum lru_list lru; -+ -+ for_each_evictable_lru(lru) { -+ if (!list_empty(&lruvec->lists[lru])) -+ return false; -+ } -+ } else { -+ int gen, type, zone; -+ -+ for_each_gen_type_zone(gen, type, zone) { -+ if (!list_empty(&lrugen->lists[gen][type][zone])) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+static bool fill_evictable(struct lruvec *lruvec) -+{ -+ enum lru_list lru; -+ int remaining = MAX_LRU_BATCH; -+ -+ for_each_evictable_lru(lru) { -+ int type = is_file_lru(lru); -+ bool active = is_active_lru(lru); -+ struct list_head *head = &lruvec->lists[lru]; -+ -+ while (!list_empty(head)) { -+ bool success; -+ struct page *page = lru_to_page(head); -+ -+ VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page); -+ VM_WARN_ON_ONCE_PAGE(PageActive(page) != active, page); -+ VM_WARN_ON_ONCE_PAGE(page_is_file_lru(page) != type, page); -+ VM_WARN_ON_ONCE_PAGE(page_lru_gen(page) != -1, page); -+ -+ del_page_from_lru_list(page, lruvec); -+ success = lru_gen_add_page(lruvec, page, false); -+ VM_WARN_ON_ONCE(!success); -+ -+ if (!--remaining) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+static bool drain_evictable(struct lruvec *lruvec) -+{ -+ int gen, type, zone; -+ int remaining = MAX_LRU_BATCH; -+ -+ for_each_gen_type_zone(gen, type, zone) { -+ struct list_head *head = &lruvec->lrugen.lists[gen][type][zone]; -+ -+ while (!list_empty(head)) { -+ bool success; -+ struct page *page = lru_to_page(head); -+ -+ VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page); -+ VM_WARN_ON_ONCE_PAGE(PageActive(page), page); -+ VM_WARN_ON_ONCE_PAGE(page_is_file_lru(page) != type, page); -+ VM_WARN_ON_ONCE_PAGE(page_zonenum(page) != zone, page); -+ -+ success = lru_gen_del_page(lruvec, page, false); -+ VM_WARN_ON_ONCE(!success); -+ add_page_to_lru_list(page, lruvec); -+ -+ if (!--remaining) -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+static void lru_gen_change_state(bool enabled) -+{ -+ static DEFINE_MUTEX(state_mutex); -+ -+ struct mem_cgroup *memcg; -+ -+ cgroup_lock(); -+ cpus_read_lock(); -+ get_online_mems(); -+ mutex_lock(&state_mutex); -+ -+ if (enabled == lru_gen_enabled()) -+ goto unlock; -+ -+ if (enabled) -+ static_branch_enable_cpuslocked(&lru_gen_caps[LRU_GEN_CORE]); -+ else -+ static_branch_disable_cpuslocked(&lru_gen_caps[LRU_GEN_CORE]); -+ -+ memcg = mem_cgroup_iter(NULL, NULL, NULL); -+ do { -+ int nid; -+ -+ for_each_node(nid) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ if (!lruvec) -+ continue; -+ -+ spin_lock_irq(&lruvec->lru_lock); -+ -+ VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); -+ VM_WARN_ON_ONCE(!state_is_valid(lruvec)); -+ -+ lruvec->lrugen.enabled = enabled; -+ -+ while (!(enabled ? fill_evictable(lruvec) : drain_evictable(lruvec))) { -+ spin_unlock_irq(&lruvec->lru_lock); -+ cond_resched(); -+ spin_lock_irq(&lruvec->lru_lock); -+ } -+ -+ spin_unlock_irq(&lruvec->lru_lock); -+ } -+ -+ cond_resched(); -+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+unlock: -+ mutex_unlock(&state_mutex); -+ put_online_mems(); -+ cpus_read_unlock(); -+ cgroup_unlock(); -+} -+ -+/****************************************************************************** -+ * sysfs interface -+ ******************************************************************************/ -+ -+static ssize_t show_enabled(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -+{ -+ unsigned int caps = 0; -+ -+ if (get_cap(LRU_GEN_CORE)) -+ caps |= BIT(LRU_GEN_CORE); -+ -+ if (arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK)) -+ caps |= BIT(LRU_GEN_MM_WALK); -+ -+ if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) && get_cap(LRU_GEN_NONLEAF_YOUNG)) -+ caps |= BIT(LRU_GEN_NONLEAF_YOUNG); -+ -+ return snprintf(buf, PAGE_SIZE, "0x%04x\n", caps); -+} -+ -+static ssize_t store_enabled(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t len) -+{ -+ int i; -+ unsigned int caps; -+ -+ if (tolower(*buf) == 'n') -+ caps = 0; -+ else if (tolower(*buf) == 'y') -+ caps = -1; -+ else if (kstrtouint(buf, 0, &caps)) -+ return -EINVAL; -+ -+ for (i = 0; i < NR_LRU_GEN_CAPS; i++) { -+ bool enabled = caps & BIT(i); -+ -+ if (i == LRU_GEN_CORE) -+ lru_gen_change_state(enabled); -+ else if (enabled) -+ static_branch_enable(&lru_gen_caps[i]); -+ else -+ static_branch_disable(&lru_gen_caps[i]); -+ } -+ -+ return len; -+} -+ -+static struct kobj_attribute lru_gen_enabled_attr = __ATTR( -+ enabled, 0644, show_enabled, store_enabled -+); -+ -+static struct attribute *lru_gen_attrs[] = { -+ &lru_gen_enabled_attr.attr, -+ NULL -+}; -+ -+static struct attribute_group lru_gen_attr_group = { -+ .name = "lru_gen", -+ .attrs = lru_gen_attrs, -+}; -+ -+/****************************************************************************** - * initialization - ******************************************************************************/ - -@@ -4855,6 +5069,7 @@ void lru_gen_init_lruvec(struct lruvec * - struct lru_gen_struct *lrugen = &lruvec->lrugen; - - lrugen->max_seq = MIN_NR_GENS + 1; -+ lrugen->enabled = lru_gen_enabled(); - - for_each_gen_type_zone(gen, type, zone) - INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); -@@ -4894,6 +5109,9 @@ static int __init init_lru_gen(void) - BUILD_BUG_ON(MIN_NR_GENS + 1 >= MAX_NR_GENS); - BUILD_BUG_ON(BIT(LRU_GEN_WIDTH) <= MAX_NR_GENS); - -+ if (sysfs_create_group(mm_kobj, &lru_gen_attr_group)) -+ pr_err("lru_gen: failed to create sysfs group\n"); -+ - return 0; - }; - late_initcall(init_lru_gen); diff --git a/target/linux/generic/backport-5.15/020-v6.1-11-mm-multi-gen-LRU-thrashing-prevention.patch b/target/linux/generic/backport-5.15/020-v6.1-11-mm-multi-gen-LRU-thrashing-prevention.patch deleted file mode 100644 index 30e20aff6edce7..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-11-mm-multi-gen-LRU-thrashing-prevention.patch +++ /dev/null @@ -1,226 +0,0 @@ -From 73d1ff551760f0c79c47ab70faa4c2ca91413f5c Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 02:00:08 -0600 -Subject: [PATCH 11/29] mm: multi-gen LRU: thrashing prevention -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add /sys/kernel/mm/lru_gen/min_ttl_ms for thrashing prevention, as -requested by many desktop users [1]. - -When set to value N, it prevents the working set of N milliseconds from -getting evicted. The OOM killer is triggered if this working set cannot -be kept in memory. Based on the average human detectable lag (~100ms), -N=1000 usually eliminates intolerable lags due to thrashing. Larger -values like N=3000 make lags less noticeable at the risk of premature OOM -kills. - -Compared with the size-based approach [2], this time-based approach -has the following advantages: - -1. It is easier to configure because it is agnostic to applications - and memory sizes. -2. It is more reliable because it is directly wired to the OOM killer. - -[1] https://lore.kernel.org/r/Ydza%2FzXKY9ATRoh6@google.com/ -[2] https://lore.kernel.org/r/20101028191523.GA14972@google.com/ - -Link: https://lkml.kernel.org/r/20220918080010.2920238-12-yuzhao@google.com -Signed-off-by: Yu Zhao -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Barry Song -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Miaohe Lin -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Qi Zheng -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - include/linux/mmzone.h | 2 ++ - mm/vmscan.c | 74 ++++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 73 insertions(+), 3 deletions(-) - ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -399,6 +399,8 @@ struct lru_gen_struct { - unsigned long max_seq; - /* the eviction increments the oldest generation numbers */ - unsigned long min_seq[ANON_AND_FILE]; -+ /* the birth time of each generation in jiffies */ -+ unsigned long timestamps[MAX_NR_GENS]; - /* the multi-gen LRU lists, lazily sorted on eviction */ - struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; - /* the multi-gen LRU sizes, eventually consistent */ ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4064,6 +4064,7 @@ static void inc_max_seq(struct lruvec *l - for (type = 0; type < ANON_AND_FILE; type++) - reset_ctrl_pos(lruvec, type, false); - -+ WRITE_ONCE(lrugen->timestamps[next], jiffies); - /* make sure preceding modifications appear */ - smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1); - -@@ -4193,7 +4194,7 @@ static bool should_run_aging(struct lruv - return false; - } - --static void age_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc, unsigned long min_ttl) - { - bool need_aging; - unsigned long nr_to_scan; -@@ -4207,16 +4208,36 @@ static void age_lruvec(struct lruvec *lr - mem_cgroup_calculate_protection(NULL, memcg); - - if (mem_cgroup_below_min(memcg)) -- return; -+ return false; - - need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan); -+ -+ if (min_ttl) { -+ int gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); -+ unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); -+ -+ if (time_is_after_jiffies(birth + min_ttl)) -+ return false; -+ -+ /* the size is likely too small to be helpful */ -+ if (!nr_to_scan && sc->priority != DEF_PRIORITY) -+ return false; -+ } -+ - if (need_aging) - try_to_inc_max_seq(lruvec, max_seq, sc, swappiness); -+ -+ return true; - } - -+/* to protect the working set of the last N jiffies */ -+static unsigned long lru_gen_min_ttl __read_mostly; -+ - static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) - { - struct mem_cgroup *memcg; -+ bool success = false; -+ unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl); - - VM_WARN_ON_ONCE(!current_is_kswapd()); - -@@ -4239,12 +4260,32 @@ static void lru_gen_age_node(struct pgli - do { - struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); - -- age_lruvec(lruvec, sc); -+ if (age_lruvec(lruvec, sc, min_ttl)) -+ success = true; - - cond_resched(); - } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); - - clear_mm_walk(); -+ -+ /* check the order to exclude compaction-induced reclaim */ -+ if (success || !min_ttl || sc->order) -+ return; -+ -+ /* -+ * The main goal is to OOM kill if every generation from all memcgs is -+ * younger than min_ttl. However, another possibility is all memcgs are -+ * either below min or empty. -+ */ -+ if (mutex_trylock(&oom_lock)) { -+ struct oom_control oc = { -+ .gfp_mask = sc->gfp_mask, -+ }; -+ -+ out_of_memory(&oc); -+ -+ mutex_unlock(&oom_lock); -+ } - } - - /* -@@ -5002,6 +5043,28 @@ unlock: - * sysfs interface - ******************************************************************************/ - -+static ssize_t show_min_ttl(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%u\n", jiffies_to_msecs(READ_ONCE(lru_gen_min_ttl))); -+} -+ -+static ssize_t store_min_ttl(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t len) -+{ -+ unsigned int msecs; -+ -+ if (kstrtouint(buf, 0, &msecs)) -+ return -EINVAL; -+ -+ WRITE_ONCE(lru_gen_min_ttl, msecs_to_jiffies(msecs)); -+ -+ return len; -+} -+ -+static struct kobj_attribute lru_gen_min_ttl_attr = __ATTR( -+ min_ttl_ms, 0644, show_min_ttl, store_min_ttl -+); -+ - static ssize_t show_enabled(struct kobject *kobj, struct kobj_attribute *attr, char *buf) - { - unsigned int caps = 0; -@@ -5050,6 +5113,7 @@ static struct kobj_attribute lru_gen_ena - ); - - static struct attribute *lru_gen_attrs[] = { -+ &lru_gen_min_ttl_attr.attr, - &lru_gen_enabled_attr.attr, - NULL - }; -@@ -5065,12 +5129,16 @@ static struct attribute_group lru_gen_at - - void lru_gen_init_lruvec(struct lruvec *lruvec) - { -+ int i; - int gen, type, zone; - struct lru_gen_struct *lrugen = &lruvec->lrugen; - - lrugen->max_seq = MIN_NR_GENS + 1; - lrugen->enabled = lru_gen_enabled(); - -+ for (i = 0; i <= MIN_NR_GENS + 1; i++) -+ lrugen->timestamps[i] = jiffies; -+ - for_each_gen_type_zone(gen, type, zone) - INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); - diff --git a/target/linux/generic/backport-5.15/020-v6.1-12-mm-multi-gen-LRU-debugfs-interface.patch b/target/linux/generic/backport-5.15/020-v6.1-12-mm-multi-gen-LRU-debugfs-interface.patch deleted file mode 100644 index 482e714bb6aace..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-12-mm-multi-gen-LRU-debugfs-interface.patch +++ /dev/null @@ -1,579 +0,0 @@ -From 530716d008ca26315f246cd70dc1cefc636beaa4 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 18 Sep 2022 02:00:09 -0600 -Subject: [PATCH 12/29] mm: multi-gen LRU: debugfs interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add /sys/kernel/debug/lru_gen for working set estimation and proactive -reclaim. These techniques are commonly used to optimize job scheduling -(bin packing) in data centers [1][2]. - -Compared with the page table-based approach and the PFN-based -approach, this lruvec-based approach has the following advantages: -1. It offers better choices because it is aware of memcgs, NUMA nodes, - shared mappings and unmapped page cache. -2. It is more scalable because it is O(nr_hot_pages), whereas the - PFN-based approach is O(nr_total_pages). - -Add /sys/kernel/debug/lru_gen_full for debugging. - -[1] https://dl.acm.org/doi/10.1145/3297858.3304053 -[2] https://dl.acm.org/doi/10.1145/3503222.3507731 - -Link: https://lkml.kernel.org/r/20220918080010.2920238-13-yuzhao@google.com -Signed-off-by: Yu Zhao -Reviewed-by: Qi Zheng -Acked-by: Brian Geffon -Acked-by: Jan Alexander Steffens (heftig) -Acked-by: Oleksandr Natalenko -Acked-by: Steven Barrett -Acked-by: Suleiman Souhlal -Tested-by: Daniel Byrne -Tested-by: Donald Carr -Tested-by: Holger Hoffstätte -Tested-by: Konstantin Kharlamov -Tested-by: Shuang Zhai -Tested-by: Sofia Trinh -Tested-by: Vaibhav Jain -Cc: Andi Kleen -Cc: Aneesh Kumar K.V -Cc: Barry Song -Cc: Catalin Marinas -Cc: Dave Hansen -Cc: Hillf Danton -Cc: Jens Axboe -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Linus Torvalds -Cc: Matthew Wilcox -Cc: Mel Gorman -Cc: Miaohe Lin -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Mike Rapoport -Cc: Peter Zijlstra -Cc: Tejun Heo -Cc: Vlastimil Babka -Cc: Will Deacon -Signed-off-by: Andrew Morton ---- - include/linux/nodemask.h | 1 + - mm/vmscan.c | 411 ++++++++++++++++++++++++++++++++++++++- - 2 files changed, 402 insertions(+), 10 deletions(-) - ---- a/include/linux/nodemask.h -+++ b/include/linux/nodemask.h -@@ -485,6 +485,7 @@ static inline int num_node_state(enum no - #define first_online_node 0 - #define first_memory_node 0 - #define next_online_node(nid) (MAX_NUMNODES) -+#define next_memory_node(nid) (MAX_NUMNODES) - #define nr_node_ids 1U - #define nr_online_nodes 1U - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -53,6 +53,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -3968,12 +3969,40 @@ static void clear_mm_walk(void) - kfree(walk); - } - --static void inc_min_seq(struct lruvec *lruvec, int type) -+static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap) - { -+ int zone; -+ int remaining = MAX_LRU_BATCH; - struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]); -+ -+ if (type == LRU_GEN_ANON && !can_swap) -+ goto done; -+ -+ /* prevent cold/hot inversion if force_scan is true */ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) { -+ struct list_head *head = &lrugen->lists[old_gen][type][zone]; -+ -+ while (!list_empty(head)) { -+ struct page *page = lru_to_page(head); -+ -+ VM_WARN_ON_ONCE_PAGE(PageUnevictable(page), page); -+ VM_WARN_ON_ONCE_PAGE(PageActive(page), page); -+ VM_WARN_ON_ONCE_PAGE(page_is_file_lru(page) != type, page); -+ VM_WARN_ON_ONCE_PAGE(page_zonenum(page) != zone, page); - -+ new_gen = page_inc_gen(lruvec, page, false); -+ list_move_tail(&page->lru, &lrugen->lists[new_gen][type][zone]); -+ -+ if (!--remaining) -+ return false; -+ } -+ } -+done: - reset_ctrl_pos(lruvec, type, true); - WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1); -+ -+ return true; - } - - static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap) -@@ -4019,7 +4048,7 @@ next: - return success; - } - --static void inc_max_seq(struct lruvec *lruvec, bool can_swap) -+static void inc_max_seq(struct lruvec *lruvec, bool can_swap, bool force_scan) - { - int prev, next; - int type, zone; -@@ -4033,9 +4062,13 @@ static void inc_max_seq(struct lruvec *l - if (get_nr_gens(lruvec, type) != MAX_NR_GENS) - continue; - -- VM_WARN_ON_ONCE(type == LRU_GEN_FILE || can_swap); -+ VM_WARN_ON_ONCE(!force_scan && (type == LRU_GEN_FILE || can_swap)); - -- inc_min_seq(lruvec, type); -+ while (!inc_min_seq(lruvec, type, can_swap)) { -+ spin_unlock_irq(&lruvec->lru_lock); -+ cond_resched(); -+ spin_lock_irq(&lruvec->lru_lock); -+ } - } - - /* -@@ -4072,7 +4105,7 @@ static void inc_max_seq(struct lruvec *l - } - - static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq, -- struct scan_control *sc, bool can_swap) -+ struct scan_control *sc, bool can_swap, bool force_scan) - { - bool success; - struct lru_gen_mm_walk *walk; -@@ -4093,7 +4126,7 @@ static bool try_to_inc_max_seq(struct lr - * handful of PTEs. Spreading the work out over a period of time usually - * is less efficient, but it avoids bursty page faults. - */ -- if (!(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) { -+ if (!force_scan && !(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) { - success = iterate_mm_list_nowalk(lruvec, max_seq); - goto done; - } -@@ -4107,7 +4140,7 @@ static bool try_to_inc_max_seq(struct lr - walk->lruvec = lruvec; - walk->max_seq = max_seq; - walk->can_swap = can_swap; -- walk->force_scan = false; -+ walk->force_scan = force_scan; - - do { - success = iterate_mm_list(lruvec, walk, &mm); -@@ -4127,7 +4160,7 @@ done: - - VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq)); - -- inc_max_seq(lruvec, can_swap); -+ inc_max_seq(lruvec, can_swap, force_scan); - /* either this sees any waiters or they will see updated max_seq */ - if (wq_has_sleeper(&lruvec->mm_state.wait)) - wake_up_all(&lruvec->mm_state.wait); -@@ -4225,7 +4258,7 @@ static bool age_lruvec(struct lruvec *lr - } - - if (need_aging) -- try_to_inc_max_seq(lruvec, max_seq, sc, swappiness); -+ try_to_inc_max_seq(lruvec, max_seq, sc, swappiness, false); - - return true; - } -@@ -4784,7 +4817,7 @@ static unsigned long get_nr_to_scan(stru - if (current_is_kswapd()) - return 0; - -- if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap)) -+ if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false)) - return nr_to_scan; - done: - return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; -@@ -5124,6 +5157,361 @@ static struct attribute_group lru_gen_at - }; - - /****************************************************************************** -+ * debugfs interface -+ ******************************************************************************/ -+ -+static void *lru_gen_seq_start(struct seq_file *m, loff_t *pos) -+{ -+ struct mem_cgroup *memcg; -+ loff_t nr_to_skip = *pos; -+ -+ m->private = kvmalloc(PATH_MAX, GFP_KERNEL); -+ if (!m->private) -+ return ERR_PTR(-ENOMEM); -+ -+ memcg = mem_cgroup_iter(NULL, NULL, NULL); -+ do { -+ int nid; -+ -+ for_each_node_state(nid, N_MEMORY) { -+ if (!nr_to_skip--) -+ return get_lruvec(memcg, nid); -+ } -+ } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); -+ -+ return NULL; -+} -+ -+static void lru_gen_seq_stop(struct seq_file *m, void *v) -+{ -+ if (!IS_ERR_OR_NULL(v)) -+ mem_cgroup_iter_break(NULL, lruvec_memcg(v)); -+ -+ kvfree(m->private); -+ m->private = NULL; -+} -+ -+static void *lru_gen_seq_next(struct seq_file *m, void *v, loff_t *pos) -+{ -+ int nid = lruvec_pgdat(v)->node_id; -+ struct mem_cgroup *memcg = lruvec_memcg(v); -+ -+ ++*pos; -+ -+ nid = next_memory_node(nid); -+ if (nid == MAX_NUMNODES) { -+ memcg = mem_cgroup_iter(NULL, memcg, NULL); -+ if (!memcg) -+ return NULL; -+ -+ nid = first_memory_node; -+ } -+ -+ return get_lruvec(memcg, nid); -+} -+ -+static void lru_gen_seq_show_full(struct seq_file *m, struct lruvec *lruvec, -+ unsigned long max_seq, unsigned long *min_seq, -+ unsigned long seq) -+{ -+ int i; -+ int type, tier; -+ int hist = lru_hist_from_seq(seq); -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ -+ for (tier = 0; tier < MAX_NR_TIERS; tier++) { -+ seq_printf(m, " %10d", tier); -+ for (type = 0; type < ANON_AND_FILE; type++) { -+ const char *s = " "; -+ unsigned long n[3] = {}; -+ -+ if (seq == max_seq) { -+ s = "RT "; -+ n[0] = READ_ONCE(lrugen->avg_refaulted[type][tier]); -+ n[1] = READ_ONCE(lrugen->avg_total[type][tier]); -+ } else if (seq == min_seq[type] || NR_HIST_GENS > 1) { -+ s = "rep"; -+ n[0] = atomic_long_read(&lrugen->refaulted[hist][type][tier]); -+ n[1] = atomic_long_read(&lrugen->evicted[hist][type][tier]); -+ if (tier) -+ n[2] = READ_ONCE(lrugen->protected[hist][type][tier - 1]); -+ } -+ -+ for (i = 0; i < 3; i++) -+ seq_printf(m, " %10lu%c", n[i], s[i]); -+ } -+ seq_putc(m, '\n'); -+ } -+ -+ seq_puts(m, " "); -+ for (i = 0; i < NR_MM_STATS; i++) { -+ const char *s = " "; -+ unsigned long n = 0; -+ -+ if (seq == max_seq && NR_HIST_GENS == 1) { -+ s = "LOYNFA"; -+ n = READ_ONCE(lruvec->mm_state.stats[hist][i]); -+ } else if (seq != max_seq && NR_HIST_GENS > 1) { -+ s = "loynfa"; -+ n = READ_ONCE(lruvec->mm_state.stats[hist][i]); -+ } -+ -+ seq_printf(m, " %10lu%c", n, s[i]); -+ } -+ seq_putc(m, '\n'); -+} -+ -+static int lru_gen_seq_show(struct seq_file *m, void *v) -+{ -+ unsigned long seq; -+ bool full = !debugfs_real_fops(m->file)->write; -+ struct lruvec *lruvec = v; -+ struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ int nid = lruvec_pgdat(lruvec)->node_id; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (nid == first_memory_node) { -+ const char *path = memcg ? m->private : ""; -+ -+#ifdef CONFIG_MEMCG -+ if (memcg) -+ cgroup_path(memcg->css.cgroup, m->private, PATH_MAX); -+#endif -+ seq_printf(m, "memcg %5hu %s\n", mem_cgroup_id(memcg), path); -+ } -+ -+ seq_printf(m, " node %5d\n", nid); -+ -+ if (!full) -+ seq = min_seq[LRU_GEN_ANON]; -+ else if (max_seq >= MAX_NR_GENS) -+ seq = max_seq - MAX_NR_GENS + 1; -+ else -+ seq = 0; -+ -+ for (; seq <= max_seq; seq++) { -+ int type, zone; -+ int gen = lru_gen_from_seq(seq); -+ unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); -+ -+ seq_printf(m, " %10lu %10u", seq, jiffies_to_msecs(jiffies - birth)); -+ -+ for (type = 0; type < ANON_AND_FILE; type++) { -+ unsigned long size = 0; -+ char mark = full && seq < min_seq[type] ? 'x' : ' '; -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) -+ size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); -+ -+ seq_printf(m, " %10lu%c", size, mark); -+ } -+ -+ seq_putc(m, '\n'); -+ -+ if (full) -+ lru_gen_seq_show_full(m, lruvec, max_seq, min_seq, seq); -+ } -+ -+ return 0; -+} -+ -+static const struct seq_operations lru_gen_seq_ops = { -+ .start = lru_gen_seq_start, -+ .stop = lru_gen_seq_stop, -+ .next = lru_gen_seq_next, -+ .show = lru_gen_seq_show, -+}; -+ -+static int run_aging(struct lruvec *lruvec, unsigned long seq, struct scan_control *sc, -+ bool can_swap, bool force_scan) -+{ -+ DEFINE_MAX_SEQ(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (seq < max_seq) -+ return 0; -+ -+ if (seq > max_seq) -+ return -EINVAL; -+ -+ if (!force_scan && min_seq[!can_swap] + MAX_NR_GENS - 1 <= max_seq) -+ return -ERANGE; -+ -+ try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, force_scan); -+ -+ return 0; -+} -+ -+static int run_eviction(struct lruvec *lruvec, unsigned long seq, struct scan_control *sc, -+ int swappiness, unsigned long nr_to_reclaim) -+{ -+ DEFINE_MAX_SEQ(lruvec); -+ -+ if (seq + MIN_NR_GENS > max_seq) -+ return -EINVAL; -+ -+ sc->nr_reclaimed = 0; -+ -+ while (!signal_pending(current)) { -+ DEFINE_MIN_SEQ(lruvec); -+ -+ if (seq < min_seq[!swappiness]) -+ return 0; -+ -+ if (sc->nr_reclaimed >= nr_to_reclaim) -+ return 0; -+ -+ if (!evict_pages(lruvec, sc, swappiness, NULL)) -+ return 0; -+ -+ cond_resched(); -+ } -+ -+ return -EINTR; -+} -+ -+static int run_cmd(char cmd, int memcg_id, int nid, unsigned long seq, -+ struct scan_control *sc, int swappiness, unsigned long opt) -+{ -+ struct lruvec *lruvec; -+ int err = -EINVAL; -+ struct mem_cgroup *memcg = NULL; -+ -+ if (nid < 0 || nid >= MAX_NUMNODES || !node_state(nid, N_MEMORY)) -+ return -EINVAL; -+ -+ if (!mem_cgroup_disabled()) { -+ rcu_read_lock(); -+ memcg = mem_cgroup_from_id(memcg_id); -+#ifdef CONFIG_MEMCG -+ if (memcg && !css_tryget(&memcg->css)) -+ memcg = NULL; -+#endif -+ rcu_read_unlock(); -+ -+ if (!memcg) -+ return -EINVAL; -+ } -+ -+ if (memcg_id != mem_cgroup_id(memcg)) -+ goto done; -+ -+ lruvec = get_lruvec(memcg, nid); -+ -+ if (swappiness < 0) -+ swappiness = get_swappiness(lruvec, sc); -+ else if (swappiness > 200) -+ goto done; -+ -+ switch (cmd) { -+ case '+': -+ err = run_aging(lruvec, seq, sc, swappiness, opt); -+ break; -+ case '-': -+ err = run_eviction(lruvec, seq, sc, swappiness, opt); -+ break; -+ } -+done: -+ mem_cgroup_put(memcg); -+ -+ return err; -+} -+ -+static ssize_t lru_gen_seq_write(struct file *file, const char __user *src, -+ size_t len, loff_t *pos) -+{ -+ void *buf; -+ char *cur, *next; -+ unsigned int flags; -+ struct blk_plug plug; -+ int err = -EINVAL; -+ struct scan_control sc = { -+ .may_writepage = true, -+ .may_unmap = true, -+ .may_swap = true, -+ .reclaim_idx = MAX_NR_ZONES - 1, -+ .gfp_mask = GFP_KERNEL, -+ }; -+ -+ buf = kvmalloc(len + 1, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ if (copy_from_user(buf, src, len)) { -+ kvfree(buf); -+ return -EFAULT; -+ } -+ -+ set_task_reclaim_state(current, &sc.reclaim_state); -+ flags = memalloc_noreclaim_save(); -+ blk_start_plug(&plug); -+ if (!set_mm_walk(NULL)) { -+ err = -ENOMEM; -+ goto done; -+ } -+ -+ next = buf; -+ next[len] = '\0'; -+ -+ while ((cur = strsep(&next, ",;\n"))) { -+ int n; -+ int end; -+ char cmd; -+ unsigned int memcg_id; -+ unsigned int nid; -+ unsigned long seq; -+ unsigned int swappiness = -1; -+ unsigned long opt = -1; -+ -+ cur = skip_spaces(cur); -+ if (!*cur) -+ continue; -+ -+ n = sscanf(cur, "%c %u %u %lu %n %u %n %lu %n", &cmd, &memcg_id, &nid, -+ &seq, &end, &swappiness, &end, &opt, &end); -+ if (n < 4 || cur[end]) { -+ err = -EINVAL; -+ break; -+ } -+ -+ err = run_cmd(cmd, memcg_id, nid, seq, &sc, swappiness, opt); -+ if (err) -+ break; -+ } -+done: -+ clear_mm_walk(); -+ blk_finish_plug(&plug); -+ memalloc_noreclaim_restore(flags); -+ set_task_reclaim_state(current, NULL); -+ -+ kvfree(buf); -+ -+ return err ? : len; -+} -+ -+static int lru_gen_seq_open(struct inode *inode, struct file *file) -+{ -+ return seq_open(file, &lru_gen_seq_ops); -+} -+ -+static const struct file_operations lru_gen_rw_fops = { -+ .open = lru_gen_seq_open, -+ .read = seq_read, -+ .write = lru_gen_seq_write, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ -+static const struct file_operations lru_gen_ro_fops = { -+ .open = lru_gen_seq_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ -+/****************************************************************************** - * initialization - ******************************************************************************/ - -@@ -5180,6 +5568,9 @@ static int __init init_lru_gen(void) - if (sysfs_create_group(mm_kobj, &lru_gen_attr_group)) - pr_err("lru_gen: failed to create sysfs group\n"); - -+ debugfs_create_file("lru_gen", 0644, NULL, NULL, &lru_gen_rw_fops); -+ debugfs_create_file("lru_gen_full", 0444, NULL, NULL, &lru_gen_ro_fops); -+ - return 0; - }; - late_initcall(init_lru_gen); diff --git a/target/linux/generic/backport-5.15/020-v6.1-13-mm-mglru-don-t-sync-disk-for-each-aging-cycle.patch b/target/linux/generic/backport-5.15/020-v6.1-13-mm-mglru-don-t-sync-disk-for-each-aging-cycle.patch deleted file mode 100644 index fd4aa72747320f..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-13-mm-mglru-don-t-sync-disk-for-each-aging-cycle.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 92d430e8955c976eacb7cc91d7ff849c0dd009af Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 28 Sep 2022 13:36:58 -0600 -Subject: [PATCH 13/29] mm/mglru: don't sync disk for each aging cycle - -wakeup_flusher_threads() was added under the assumption that if a system -runs out of clean cold pages, it might want to write back dirty pages more -aggressively so that they can become clean and be dropped. - -However, doing so can breach the rate limit a system wants to impose on -writeback, resulting in early SSD wearout. - -Link: https://lkml.kernel.org/r/YzSiWq9UEER5LKup@google.com -Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks") -Signed-off-by: Yu Zhao -Reported-by: Axel Rasmussen -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4165,8 +4165,6 @@ done: - if (wq_has_sleeper(&lruvec->mm_state.wait)) - wake_up_all(&lruvec->mm_state.wait); - -- wakeup_flusher_threads(WB_REASON_VMSCAN); -- - return true; - } - diff --git a/target/linux/generic/backport-5.15/020-v6.1-14-mm-multi-gen-LRU-retry-pages-written-back-while-isol.patch b/target/linux/generic/backport-5.15/020-v6.1-14-mm-multi-gen-LRU-retry-pages-written-back-while-isol.patch deleted file mode 100644 index 31b35cbc4b69fb..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-14-mm-multi-gen-LRU-retry-pages-written-back-while-isol.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 6f315879ad750391a0b1fab8c9170bc054a5f5d7 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Tue, 15 Nov 2022 18:38:07 -0700 -Subject: [PATCH 14/29] mm: multi-gen LRU: retry pages written back while - isolated - -The page reclaim isolates a batch of pages from the tail of one of the -LRU lists and works on those pages one by one. For a suitable -swap-backed page, if the swap device is async, it queues that page for -writeback. After the page reclaim finishes an entire batch, it puts back -the pages it queued for writeback to the head of the original LRU list. - -In the meantime, the page writeback flushes the queued pages also by -batches. Its batching logic is independent from that of the page reclaim. -For each of the pages it writes back, the page writeback calls -rotate_reclaimable_page() which tries to rotate a page to the tail. - -rotate_reclaimable_page() only works for a page after the page reclaim -has put it back. If an async swap device is fast enough, the page -writeback can finish with that page while the page reclaim is still -working on the rest of the batch containing it. In this case, that page -will remain at the head and the page reclaim will not retry it before -reaching there. - -This patch adds a retry to evict_pages(). After evict_pages() has -finished an entire batch and before it puts back pages it cannot free -immediately, it retries those that may have missed the rotation. - -Before this patch, ~60% of pages swapped to an Intel Optane missed -rotate_reclaimable_page(). After this patch, ~99% of missed pages were -reclaimed upon retry. - -This problem affects relatively slow async swap devices like Samsung 980 -Pro much less and does not affect sync swap devices like zram or zswap at -all. - -Link: https://lkml.kernel.org/r/20221116013808.3995280-1-yuzhao@google.com -Fixes: ac35a4902374 ("mm: multi-gen LRU: minimal implementation") -Signed-off-by: Yu Zhao -Cc: "Yin, Fengwei" -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 48 +++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 37 insertions(+), 11 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4723,10 +4723,13 @@ static int evict_pages(struct lruvec *lr - int scanned; - int reclaimed; - LIST_HEAD(list); -+ LIST_HEAD(clean); - struct page *page; -+ struct page *next; - enum vm_event_item item; - struct reclaim_stat stat; - struct lru_gen_mm_walk *walk; -+ bool skip_retry = false; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - struct pglist_data *pgdat = lruvec_pgdat(lruvec); - -@@ -4743,20 +4746,37 @@ static int evict_pages(struct lruvec *lr - - if (list_empty(&list)) - return scanned; -- -+retry: - reclaimed = shrink_page_list(&list, pgdat, sc, &stat, false); -+ sc->nr_reclaimed += reclaimed; - -- list_for_each_entry(page, &list, lru) { -- /* restore LRU_REFS_FLAGS cleared by isolate_page() */ -- if (PageWorkingset(page)) -- SetPageReferenced(page); -+ list_for_each_entry_safe_reverse(page, next, &list, lru) { -+ if (!page_evictable(page)) { -+ list_del(&page->lru); -+ putback_lru_page(page); -+ continue; -+ } - -- /* don't add rejected pages to the oldest generation */ - if (PageReclaim(page) && -- (PageDirty(page) || PageWriteback(page))) -- ClearPageActive(page); -- else -- SetPageActive(page); -+ (PageDirty(page) || PageWriteback(page))) { -+ /* restore LRU_REFS_FLAGS cleared by isolate_page() */ -+ if (PageWorkingset(page)) -+ SetPageReferenced(page); -+ continue; -+ } -+ -+ if (skip_retry || PageActive(page) || PageReferenced(page) || -+ page_mapped(page) || PageLocked(page) || -+ PageDirty(page) || PageWriteback(page)) { -+ /* don't add rejected pages to the oldest generation */ -+ set_mask_bits(&page->flags, LRU_REFS_MASK | LRU_REFS_FLAGS, -+ BIT(PG_active)); -+ continue; -+ } -+ -+ /* retry pages that may have missed rotate_reclaimable_page() */ -+ list_move(&page->lru, &clean); -+ sc->nr_scanned -= thp_nr_pages(page); - } - - spin_lock_irq(&lruvec->lru_lock); -@@ -4778,7 +4798,13 @@ static int evict_pages(struct lruvec *lr - mem_cgroup_uncharge_list(&list); - free_unref_page_list(&list); - -- sc->nr_reclaimed += reclaimed; -+ INIT_LIST_HEAD(&list); -+ list_splice_init(&clean, &list); -+ -+ if (!list_empty(&list)) { -+ skip_retry = true; -+ goto retry; -+ } - - if (need_swapping && type == LRU_GEN_ANON) - *need_swapping = true; diff --git a/target/linux/generic/backport-5.15/020-v6.1-15-mm-multi-gen-LRU-move-lru_gen_add_mm-out-of-IRQ-off-.patch b/target/linux/generic/backport-5.15/020-v6.1-15-mm-multi-gen-LRU-move-lru_gen_add_mm-out-of-IRQ-off-.patch deleted file mode 100644 index b1319d98a3cb1f..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-15-mm-multi-gen-LRU-move-lru_gen_add_mm-out-of-IRQ-off-.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 255bb0ac393f1c2818cd75af45a9226300ab3daf Mon Sep 17 00:00:00 2001 -From: Sebastian Andrzej Siewior -Date: Wed, 26 Oct 2022 15:48:30 +0200 -Subject: [PATCH 15/29] mm: multi-gen LRU: move lru_gen_add_mm() out of IRQ-off - region - -lru_gen_add_mm() has been added within an IRQ-off region in the commit -mentioned below. The other invocations of lru_gen_add_mm() are not within -an IRQ-off region. - -The invocation within IRQ-off region is problematic on PREEMPT_RT because -the function is using a spin_lock_t which must not be used within -IRQ-disabled regions. - -The other invocations of lru_gen_add_mm() occur while -task_struct::alloc_lock is acquired. Move lru_gen_add_mm() after -interrupts are enabled and before task_unlock(). - -Link: https://lkml.kernel.org/r/20221026134830.711887-1-bigeasy@linutronix.de -Fixes: bd74fdaea1460 ("mm: multi-gen LRU: support page table walks") -Signed-off-by: Sebastian Andrzej Siewior -Acked-by: Yu Zhao -Cc: Al Viro -Cc: "Eric W . Biederman" -Cc: Kees Cook -Cc: Thomas Gleixner -Signed-off-by: Andrew Morton ---- - fs/exec.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1014,7 +1014,6 @@ static int exec_mmap(struct mm_struct *m - active_mm = tsk->active_mm; - tsk->active_mm = mm; - tsk->mm = mm; -- lru_gen_add_mm(mm); - /* - * This prevents preemption while active_mm is being loaded and - * it and mm are being updated, which could cause problems for -@@ -1029,6 +1028,7 @@ static int exec_mmap(struct mm_struct *m - local_irq_enable(); - tsk->mm->vmacache_seqnum = 0; - vmacache_flush(tsk); -+ lru_gen_add_mm(mm); - task_unlock(tsk); - lru_gen_use_mm(mm); - if (old_mm) { diff --git a/target/linux/generic/backport-5.15/020-v6.1-17-mm-add-dummy-pmd_young-for-architectures-not-having-.patch b/target/linux/generic/backport-5.15/020-v6.1-17-mm-add-dummy-pmd_young-for-architectures-not-having-.patch deleted file mode 100644 index 1c10c168a50c18..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-17-mm-add-dummy-pmd_young-for-architectures-not-having-.patch +++ /dev/null @@ -1,96 +0,0 @@ -From c5ec455ebd2b488d91de9d8915a0c8036a2a04dd Mon Sep 17 00:00:00 2001 -From: Juergen Gross -Date: Wed, 30 Nov 2022 14:49:41 -0800 -Subject: [PATCH 17/29] mm: add dummy pmd_young() for architectures not having - it - -In order to avoid #ifdeffery add a dummy pmd_young() implementation as a -fallback. This is required for the later patch "mm: introduce -arch_has_hw_nonleaf_pmd_young()". - -Link: https://lkml.kernel.org/r/fd3ac3cd-7349-6bbd-890a-71a9454ca0b3@suse.com -Signed-off-by: Juergen Gross -Acked-by: Yu Zhao -Cc: Borislav Petkov -Cc: Dave Hansen -Cc: Geert Uytterhoeven -Cc: "H. Peter Anvin" -Cc: Ingo Molnar -Cc: Sander Eikelenboom -Cc: Thomas Gleixner -Signed-off-by: Andrew Morton ---- - arch/mips/include/asm/pgtable.h | 1 + - arch/riscv/include/asm/pgtable.h | 1 + - arch/s390/include/asm/pgtable.h | 1 + - arch/sparc/include/asm/pgtable_64.h | 1 + - arch/x86/include/asm/pgtable.h | 1 + - include/linux/pgtable.h | 7 +++++++ - 6 files changed, 12 insertions(+) - ---- a/arch/mips/include/asm/pgtable.h -+++ b/arch/mips/include/asm/pgtable.h -@@ -632,6 +632,7 @@ static inline pmd_t pmd_mkdirty(pmd_t pm - return pmd; - } - -+#define pmd_young pmd_young - static inline int pmd_young(pmd_t pmd) - { - return !!(pmd_val(pmd) & _PAGE_ACCESSED); ---- a/arch/riscv/include/asm/pgtable.h -+++ b/arch/riscv/include/asm/pgtable.h -@@ -535,6 +535,7 @@ static inline int pmd_dirty(pmd_t pmd) - return pte_dirty(pmd_pte(pmd)); - } - -+#define pmd_young pmd_young - static inline int pmd_young(pmd_t pmd) - { - return pte_young(pmd_pte(pmd)); ---- a/arch/s390/include/asm/pgtable.h -+++ b/arch/s390/include/asm/pgtable.h -@@ -748,6 +748,7 @@ static inline int pmd_dirty(pmd_t pmd) - return (pmd_val(pmd) & _SEGMENT_ENTRY_DIRTY) != 0; - } - -+#define pmd_young pmd_young - static inline int pmd_young(pmd_t pmd) - { - return (pmd_val(pmd) & _SEGMENT_ENTRY_YOUNG) != 0; ---- a/arch/sparc/include/asm/pgtable_64.h -+++ b/arch/sparc/include/asm/pgtable_64.h -@@ -712,6 +712,7 @@ static inline unsigned long pmd_dirty(pm - return pte_dirty(pte); - } - -+#define pmd_young pmd_young - static inline unsigned long pmd_young(pmd_t pmd) - { - pte_t pte = __pte(pmd_val(pmd)); ---- a/arch/x86/include/asm/pgtable.h -+++ b/arch/x86/include/asm/pgtable.h -@@ -136,6 +136,7 @@ static inline int pmd_dirty(pmd_t pmd) - return pmd_flags(pmd) & _PAGE_DIRTY; - } - -+#define pmd_young pmd_young - static inline int pmd_young(pmd_t pmd) - { - return pmd_flags(pmd) & _PAGE_ACCESSED; ---- a/include/linux/pgtable.h -+++ b/include/linux/pgtable.h -@@ -164,6 +164,13 @@ static inline pte_t *virt_to_kpte(unsign - return pmd_none(*pmd) ? NULL : pte_offset_kernel(pmd, vaddr); - } - -+#ifndef pmd_young -+static inline int pmd_young(pmd_t pmd) -+{ -+ return 0; -+} -+#endif -+ - #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS - extern int ptep_set_access_flags(struct vm_area_struct *vma, - unsigned long address, pte_t *ptep, diff --git a/target/linux/generic/backport-5.15/020-v6.1-18-mm-introduce-arch_has_hw_nonleaf_pmd_young.patch b/target/linux/generic/backport-5.15/020-v6.1-18-mm-introduce-arch_has_hw_nonleaf_pmd_young.patch deleted file mode 100644 index 9a1f9bead6cbc4..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.1-18-mm-introduce-arch_has_hw_nonleaf_pmd_young.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 46cbda7b65998a5af4493f745d94417af697bd68 Mon Sep 17 00:00:00 2001 -From: Juergen Gross -Date: Wed, 23 Nov 2022 07:45:10 +0100 -Subject: [PATCH 18/29] mm: introduce arch_has_hw_nonleaf_pmd_young() - -When running as a Xen PV guests commit eed9a328aa1a ("mm: x86: add -CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG") can cause a protection violation in -pmdp_test_and_clear_young(): - - BUG: unable to handle page fault for address: ffff8880083374d0 - #PF: supervisor write access in kernel mode - #PF: error_code(0x0003) - permissions violation - PGD 3026067 P4D 3026067 PUD 3027067 PMD 7fee5067 PTE 8010000008337065 - Oops: 0003 [#1] PREEMPT SMP NOPTI - CPU: 7 PID: 158 Comm: kswapd0 Not tainted 6.1.0-rc5-20221118-doflr+ #1 - RIP: e030:pmdp_test_and_clear_young+0x25/0x40 - -This happens because the Xen hypervisor can't emulate direct writes to -page table entries other than PTEs. - -This can easily be fixed by introducing arch_has_hw_nonleaf_pmd_young() -similar to arch_has_hw_pte_young() and test that instead of -CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG. - -Link: https://lkml.kernel.org/r/20221123064510.16225-1-jgross@suse.com -Fixes: eed9a328aa1a ("mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG") -Signed-off-by: Juergen Gross -Reported-by: Sander Eikelenboom -Acked-by: Yu Zhao -Tested-by: Sander Eikelenboom -Acked-by: David Hildenbrand [core changes] -Signed-off-by: Andrew Morton ---- - arch/x86/include/asm/pgtable.h | 8 ++++++++ - include/linux/pgtable.h | 11 +++++++++++ - mm/vmscan.c | 10 +++++----- - 3 files changed, 24 insertions(+), 5 deletions(-) - ---- a/arch/x86/include/asm/pgtable.h -+++ b/arch/x86/include/asm/pgtable.h -@@ -1405,6 +1405,14 @@ static inline bool arch_has_hw_pte_young - return true; - } - -+#ifdef CONFIG_XEN_PV -+#define arch_has_hw_nonleaf_pmd_young arch_has_hw_nonleaf_pmd_young -+static inline bool arch_has_hw_nonleaf_pmd_young(void) -+{ -+ return !cpu_feature_enabled(X86_FEATURE_XENPV); -+} -+#endif -+ - #endif /* __ASSEMBLY__ */ - - #endif /* _ASM_X86_PGTABLE_H */ ---- a/include/linux/pgtable.h -+++ b/include/linux/pgtable.h -@@ -266,6 +266,17 @@ static inline int pmdp_clear_flush_young - #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ - #endif - -+#ifndef arch_has_hw_nonleaf_pmd_young -+/* -+ * Return whether the accessed bit in non-leaf PMD entries is supported on the -+ * local CPU. -+ */ -+static inline bool arch_has_hw_nonleaf_pmd_young(void) -+{ -+ return IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG); -+} -+#endif -+ - #ifndef arch_has_hw_pte_young - /* - * Return whether the accessed bit is supported on the local CPU. ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3727,7 +3727,7 @@ static void walk_pmd_range_locked(pud_t - goto next; - - if (!pmd_trans_huge(pmd[i])) { -- if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) && -+ if (arch_has_hw_nonleaf_pmd_young() && - get_cap(LRU_GEN_NONLEAF_YOUNG)) - pmdp_test_and_clear_young(vma, addr, pmd + i); - goto next; -@@ -3825,14 +3825,14 @@ restart: - #endif - walk->mm_stats[MM_NONLEAF_TOTAL]++; - --#ifdef CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG -- if (get_cap(LRU_GEN_NONLEAF_YOUNG)) { -+ if (arch_has_hw_nonleaf_pmd_young() && -+ get_cap(LRU_GEN_NONLEAF_YOUNG)) { - if (!pmd_young(val)) - continue; - - walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); - } --#endif -+ - if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i)) - continue; - -@@ -5132,7 +5132,7 @@ static ssize_t show_enabled(struct kobje - if (arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK)) - caps |= BIT(LRU_GEN_MM_WALK); - -- if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) && get_cap(LRU_GEN_NONLEAF_YOUNG)) -+ if (arch_has_hw_nonleaf_pmd_young() && get_cap(LRU_GEN_NONLEAF_YOUNG)) - caps |= BIT(LRU_GEN_NONLEAF_YOUNG); - - return snprintf(buf, PAGE_SIZE, "0x%04x\n", caps); diff --git a/target/linux/generic/backport-5.15/020-v6.2-16-mm-multi-gen-LRU-fix-crash-during-cgroup-migration.patch b/target/linux/generic/backport-5.15/020-v6.2-16-mm-multi-gen-LRU-fix-crash-during-cgroup-migration.patch deleted file mode 100644 index e37386abdf1967..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.2-16-mm-multi-gen-LRU-fix-crash-during-cgroup-migration.patch +++ /dev/null @@ -1,56 +0,0 @@ -From c7dfefd4bdfba3d5171038d1cc2d4160288e6ee4 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Sun, 15 Jan 2023 20:44:05 -0700 -Subject: [PATCH 16/29] mm: multi-gen LRU: fix crash during cgroup migration - -lru_gen_migrate_mm() assumes lru_gen_add_mm() runs prior to itself. This -isn't true for the following scenario: - - CPU 1 CPU 2 - - clone() - cgroup_can_fork() - cgroup_procs_write() - cgroup_post_fork() - task_lock() - lru_gen_migrate_mm() - task_unlock() - task_lock() - lru_gen_add_mm() - task_unlock() - -And when the above happens, kernel crashes because of linked list -corruption (mm_struct->lru_gen.list). - -Link: https://lore.kernel.org/r/20230115134651.30028-1-msizanoen@qtmlabs.xyz/ -Link: https://lkml.kernel.org/r/20230116034405.2960276-1-yuzhao@google.com -Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks") -Signed-off-by: Yu Zhao -Reported-by: msizanoen -Tested-by: msizanoen -Cc: [6.1+] -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3024,13 +3024,16 @@ void lru_gen_migrate_mm(struct mm_struct - if (mem_cgroup_disabled()) - return; - -+ /* migration can happen before addition */ -+ if (!mm->lru_gen.memcg) -+ return; -+ - rcu_read_lock(); - memcg = mem_cgroup_from_task(task); - rcu_read_unlock(); - if (memcg == mm->lru_gen.memcg) - return; - -- VM_WARN_ON_ONCE(!mm->lru_gen.memcg); - VM_WARN_ON_ONCE(list_empty(&mm->lru_gen.list)); - - lru_gen_del_mm(mm); diff --git a/target/linux/generic/backport-5.15/020-v6.3-19-mm-add-vma_has_recency.patch b/target/linux/generic/backport-5.15/020-v6.3-19-mm-add-vma_has_recency.patch deleted file mode 100644 index 0e9ed9a7eb2d05..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-19-mm-add-vma_has_recency.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 6c7f552a48b49a8612786a28a2239fbc24fac289 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Fri, 30 Dec 2022 14:52:51 -0700 -Subject: [PATCH 19/29] mm: add vma_has_recency() - -Add vma_has_recency() to indicate whether a VMA may exhibit temporal -locality that the LRU algorithm relies on. - -This function returns false for VMAs marked by VM_SEQ_READ or -VM_RAND_READ. While the former flag indicates linear access, i.e., a -special case of spatial locality, both flags indicate a lack of temporal -locality, i.e., the reuse of an area within a relatively small duration. - -"Recency" is chosen over "locality" to avoid confusion between temporal -and spatial localities. - -Before this patch, the active/inactive LRU only ignored the accessed bit -from VMAs marked by VM_SEQ_READ. After this patch, the active/inactive -LRU and MGLRU share the same logic: they both ignore the accessed bit if -vma_has_recency() returns false. - -For the active/inactive LRU, the following fio test showed a [6, 8]% -increase in IOPS when randomly accessing mapped files under memory -pressure. - - kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo) - kb=$((kb - 8*1024*1024)) - - modprobe brd rd_nr=1 rd_size=$kb - dd if=/dev/zero of=/dev/ram0 bs=1M - - mkfs.ext4 /dev/ram0 - mount /dev/ram0 /mnt/ - swapoff -a - - fio --name=test --directory=/mnt/ --ioengine=mmap --numjobs=8 \ - --size=8G --rw=randrw --time_based --runtime=10m \ - --group_reporting - -The discussion that led to this patch is here [1]. Additional test -results are available in that thread. - -[1] https://lore.kernel.org/r/Y31s%2FK8T85jh05wH@google.com/ - -Link: https://lkml.kernel.org/r/20221230215252.2628425-1-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Alexander Viro -Cc: Andrea Righi -Cc: Johannes Weiner -Cc: Michael Larabel -Signed-off-by: Andrew Morton ---- - include/linux/mm_inline.h | 9 +++++++++ - mm/memory.c | 8 ++++---- - mm/rmap.c | 42 +++++++++++++++++---------------------- - mm/vmscan.c | 5 ++++- - 4 files changed, 35 insertions(+), 29 deletions(-) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -333,4 +333,13 @@ static __always_inline void del_page_fro - update_lru_size(lruvec, page_lru(page), page_zonenum(page), - -thp_nr_pages(page)); - } -+ -+static inline bool vma_has_recency(struct vm_area_struct *vma) -+{ -+ if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)) -+ return false; -+ -+ return true; -+} -+ - #endif ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -41,6 +41,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -1353,8 +1354,7 @@ again: - force_flush = 1; - set_page_dirty(page); - } -- if (pte_young(ptent) && -- likely(!(vma->vm_flags & VM_SEQ_READ))) -+ if (pte_young(ptent) && likely(vma_has_recency(vma))) - mark_page_accessed(page); - } - rss[mm_counter(page)]--; -@@ -4808,8 +4808,8 @@ static inline void mm_account_fault(stru - #ifdef CONFIG_LRU_GEN - static void lru_gen_enter_fault(struct vm_area_struct *vma) - { -- /* the LRU algorithm doesn't apply to sequential or random reads */ -- current->in_lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)); -+ /* the LRU algorithm only applies to accesses with recency */ -+ current->in_lru_fault = vma_has_recency(vma); - } - - static void lru_gen_exit_fault(void) ---- a/mm/rmap.c -+++ b/mm/rmap.c -@@ -794,25 +794,14 @@ static bool page_referenced_one(struct p - } - - if (pvmw.pte) { -- if (lru_gen_enabled() && pte_young(*pvmw.pte) && -- !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))) { -+ if (lru_gen_enabled() && pte_young(*pvmw.pte)) { - lru_gen_look_around(&pvmw); - referenced++; - } - - if (ptep_clear_flush_young_notify(vma, address, -- pvmw.pte)) { -- /* -- * Don't treat a reference through -- * a sequentially read mapping as such. -- * If the page has been used in another mapping, -- * we will catch it; if this other mapping is -- * already gone, the unmap path will have set -- * PG_referenced or activated the page. -- */ -- if (likely(!(vma->vm_flags & VM_SEQ_READ))) -- referenced++; -- } -+ pvmw.pte)) -+ referenced++; - } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { - if (pmdp_clear_flush_young_notify(vma, address, - pvmw.pmd)) -@@ -846,7 +835,20 @@ static bool invalid_page_referenced_vma( - struct page_referenced_arg *pra = arg; - struct mem_cgroup *memcg = pra->memcg; - -- if (!mm_match_cgroup(vma->vm_mm, memcg)) -+ /* -+ * Ignore references from this mapping if it has no recency. If the -+ * page has been used in another mapping, we will catch it; if this -+ * other mapping is already gone, the unmap path will have set the -+ * referenced flag or activated the page in zap_pte_range(). -+ */ -+ if (!vma_has_recency(vma)) -+ return true; -+ -+ /* -+ * If we are reclaiming on behalf of a cgroup, skip counting on behalf -+ * of references from different cgroups. -+ */ -+ if (memcg && !mm_match_cgroup(vma->vm_mm, memcg)) - return true; - - return false; -@@ -876,6 +878,7 @@ int page_referenced(struct page *page, - .rmap_one = page_referenced_one, - .arg = (void *)&pra, - .anon_lock = page_lock_anon_vma_read, -+ .invalid_vma = invalid_page_referenced_vma, - }; - - *vm_flags = 0; -@@ -891,15 +894,6 @@ int page_referenced(struct page *page, - return 1; - } - -- /* -- * If we are reclaiming on behalf of a cgroup, skip -- * counting on behalf of references from different -- * cgroups -- */ -- if (memcg) { -- rwc.invalid_vma = invalid_page_referenced_vma; -- } -- - rmap_walk(page, &rwc); - *vm_flags = pra.vm_flags; - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3486,7 +3486,10 @@ static int should_skip_vma(unsigned long - if (is_vm_hugetlb_page(vma)) - return true; - -- if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ | VM_RAND_READ)) -+ if (!vma_has_recency(vma)) -+ return true; -+ -+ if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL)) - return true; - - if (vma == get_gate_vma(vma->vm_mm)) diff --git a/target/linux/generic/backport-5.15/020-v6.3-20-mm-support-POSIX_FADV_NOREUSE.patch b/target/linux/generic/backport-5.15/020-v6.3-20-mm-support-POSIX_FADV_NOREUSE.patch deleted file mode 100644 index 3bb075bf367a91..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-20-mm-support-POSIX_FADV_NOREUSE.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 686c3d4f71de9e0e7a27f03a5617a712385f90cd Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Fri, 30 Dec 2022 14:52:52 -0700 -Subject: [PATCH 20/29] mm: support POSIX_FADV_NOREUSE - -This patch adds POSIX_FADV_NOREUSE to vma_has_recency() so that the LRU -algorithm can ignore access to mapped files marked by this flag. - -The advantages of POSIX_FADV_NOREUSE are: -1. Unlike MADV_SEQUENTIAL and MADV_RANDOM, it does not alter the - default readahead behavior. -2. Unlike MADV_SEQUENTIAL and MADV_RANDOM, it does not split VMAs and - therefore does not take mmap_lock. -3. Unlike MADV_COLD, setting it has a negligible cost, regardless of - how many pages it affects. - -Its limitations are: -1. Like POSIX_FADV_RANDOM and POSIX_FADV_SEQUENTIAL, it currently does - not support range. IOW, its scope is the entire file. -2. It currently does not ignore access through file descriptors. - Specifically, for the active/inactive LRU, given a file page shared - by two users and one of them having set POSIX_FADV_NOREUSE on the - file, this page will be activated upon the second user accessing - it. This corner case can be covered by checking POSIX_FADV_NOREUSE - before calling mark_page_accessed() on the read path. But it is - considered not worth the effort. - -There have been a few attempts to support POSIX_FADV_NOREUSE, e.g., [1]. -This time the goal is to fill a niche: a few desktop applications, e.g., -large file transferring and video encoding/decoding, want fast file -streaming with mmap() rather than direct IO. Among those applications, an -SVT-AV1 regression was reported when running with MGLRU [2]. The -following test can reproduce that regression. - - kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo) - kb=$((kb - 8*1024*1024)) - - modprobe brd rd_nr=1 rd_size=$kb - dd if=/dev/zero of=/dev/ram0 bs=1M - - mkfs.ext4 /dev/ram0 - mount /dev/ram0 /mnt/ - swapoff -a - - fallocate -l 8G /mnt/swapfile - mkswap /mnt/swapfile - swapon /mnt/swapfile - - wget http://ultravideo.cs.tut.fi/video/Bosphorus_3840x2160_120fps_420_8bit_YUV_Y4M.7z - 7z e -o/mnt/ Bosphorus_3840x2160_120fps_420_8bit_YUV_Y4M.7z - SvtAv1EncApp --preset 12 -w 3840 -h 2160 \ - -i /mnt/Bosphorus_3840x2160.y4m - -For MGLRU, the following change showed a [9-11]% increase in FPS, -which makes it on par with the active/inactive LRU. - - patch Source/App/EncApp/EbAppMain.c < #include - 35d35 - < #include /* _O_BINARY */ - 117a118 - > posix_fadvise(config->mmap.fd, 0, 0, POSIX_FADV_NOREUSE); - EOF - -[1] https://lore.kernel.org/r/1308923350-7932-1-git-send-email-andrea@betterlinux.com/ -[2] https://openbenchmarking.org/result/2209259-PTS-MGLRU8GB57 - -Link: https://lkml.kernel.org/r/20221230215252.2628425-2-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Alexander Viro -Cc: Andrea Righi -Cc: Johannes Weiner -Cc: Michael Larabel -Signed-off-by: Andrew Morton ---- - include/linux/fs.h | 2 ++ - include/linux/mm_inline.h | 3 +++ - mm/fadvise.c | 5 ++++- - 3 files changed, 9 insertions(+), 1 deletion(-) - ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -167,6 +167,8 @@ typedef int (dio_iodone_t)(struct kiocb - /* File is stream-like */ - #define FMODE_STREAM ((__force fmode_t)0x200000) - -+#define FMODE_NOREUSE ((__force fmode_t)0x400000) -+ - /* File was opened by fanotify and shouldn't generate fanotify events */ - #define FMODE_NONOTIFY ((__force fmode_t)0x4000000) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -339,6 +339,9 @@ static inline bool vma_has_recency(struc - if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)) - return false; - -+ if (vma->vm_file && (vma->vm_file->f_mode & FMODE_NOREUSE)) -+ return false; -+ - return true; - } - ---- a/mm/fadvise.c -+++ b/mm/fadvise.c -@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, l - case POSIX_FADV_NORMAL: - file->f_ra.ra_pages = bdi->ra_pages; - spin_lock(&file->f_lock); -- file->f_mode &= ~FMODE_RANDOM; -+ file->f_mode &= ~(FMODE_RANDOM | FMODE_NOREUSE); - spin_unlock(&file->f_lock); - break; - case POSIX_FADV_RANDOM: -@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, l - force_page_cache_readahead(mapping, file, start_index, nrpages); - break; - case POSIX_FADV_NOREUSE: -+ spin_lock(&file->f_lock); -+ file->f_mode |= FMODE_NOREUSE; -+ spin_unlock(&file->f_lock); - break; - case POSIX_FADV_DONTNEED: - if (!inode_write_congested(mapping->host)) diff --git a/target/linux/generic/backport-5.15/020-v6.3-21-mm-multi-gen-LRU-rename-lru_gen_struct-to-lru_gen_pa.patch b/target/linux/generic/backport-5.15/020-v6.3-21-mm-multi-gen-LRU-rename-lru_gen_struct-to-lru_gen_pa.patch deleted file mode 100644 index 4e09173681fbe1..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-21-mm-multi-gen-LRU-rename-lru_gen_struct-to-lru_gen_pa.patch +++ /dev/null @@ -1,348 +0,0 @@ -From 348fdbada9fb3f0bf1a53651be46319105af187f Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:18:59 -0700 -Subject: [PATCH 21/29] mm: multi-gen LRU: rename lru_gen_struct to - lru_gen_page - -Patch series "mm: multi-gen LRU: memcg LRU", v3. - -Overview -======== - -An memcg LRU is a per-node LRU of memcgs. It is also an LRU of LRUs, -since each node and memcg combination has an LRU of pages (see -mem_cgroup_lruvec()). - -Its goal is to improve the scalability of global reclaim, which is -critical to system-wide memory overcommit in data centers. Note that -memcg reclaim is currently out of scope. - -Its memory bloat is a pointer to each lruvec and negligible to each -pglist_data. In terms of traversing memcgs during global reclaim, it -improves the best-case complexity from O(n) to O(1) and does not affect -the worst-case complexity O(n). Therefore, on average, it has a sublinear -complexity in contrast to the current linear complexity. - -The basic structure of an memcg LRU can be understood by an analogy to -the active/inactive LRU (of pages): -1. It has the young and the old (generations), i.e., the counterparts - to the active and the inactive; -2. The increment of max_seq triggers promotion, i.e., the counterpart - to activation; -3. Other events trigger similar operations, e.g., offlining an memcg - triggers demotion, i.e., the counterpart to deactivation. - -In terms of global reclaim, it has two distinct features: -1. Sharding, which allows each thread to start at a random memcg (in - the old generation) and improves parallelism; -2. Eventual fairness, which allows direct reclaim to bail out at will - and reduces latency without affecting fairness over some time. - -The commit message in patch 6 details the workflow: -https://lore.kernel.org/r/20221222041905.2431096-7-yuzhao@google.com/ - -The following is a simple test to quickly verify its effectiveness. - - Test design: - 1. Create multiple memcgs. - 2. Each memcg contains a job (fio). - 3. All jobs access the same amount of memory randomly. - 4. The system does not experience global memory pressure. - 5. Periodically write to the root memory.reclaim. - - Desired outcome: - 1. All memcgs have similar pgsteal counts, i.e., stddev(pgsteal) - over mean(pgsteal) is close to 0%. - 2. The total pgsteal is close to the total requested through - memory.reclaim, i.e., sum(pgsteal) over sum(requested) is close - to 100%. - - Actual outcome [1]: - MGLRU off MGLRU on - stddev(pgsteal) / mean(pgsteal) 75% 20% - sum(pgsteal) / sum(requested) 425% 95% - - #################################################################### - MEMCGS=128 - - for ((memcg = 0; memcg < $MEMCGS; memcg++)); do - mkdir /sys/fs/cgroup/memcg$memcg - done - - start() { - echo $BASHPID > /sys/fs/cgroup/memcg$memcg/cgroup.procs - - fio -name=memcg$memcg --numjobs=1 --ioengine=mmap \ - --filename=/dev/zero --size=1920M --rw=randrw \ - --rate=64m,64m --random_distribution=random \ - --fadvise_hint=0 --time_based --runtime=10h \ - --group_reporting --minimal - } - - for ((memcg = 0; memcg < $MEMCGS; memcg++)); do - start & - done - - sleep 600 - - for ((i = 0; i < 600; i++)); do - echo 256m >/sys/fs/cgroup/memory.reclaim - sleep 6 - done - - for ((memcg = 0; memcg < $MEMCGS; memcg++)); do - grep "pgsteal " /sys/fs/cgroup/memcg$memcg/memory.stat - done - #################################################################### - -[1]: This was obtained from running the above script (touches less - than 256GB memory) on an EPYC 7B13 with 512GB DRAM for over an - hour. - -This patch (of 8): - -The new name lru_gen_page will be more distinct from the coming -lru_gen_memcg. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-1-yuzhao@google.com -Link: https://lkml.kernel.org/r/20221222041905.2431096-2-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton ---- - include/linux/mm_inline.h | 4 ++-- - include/linux/mmzone.h | 6 +++--- - mm/vmscan.c | 34 +++++++++++++++++----------------- - mm/workingset.c | 4 ++-- - 4 files changed, 24 insertions(+), 24 deletions(-) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -168,7 +168,7 @@ static inline void lru_gen_update_size(s - int zone = page_zonenum(page); - int delta = thp_nr_pages(page); - enum lru_list lru = type * LRU_INACTIVE_FILE; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - - VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS); - VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS); -@@ -214,7 +214,7 @@ static inline bool lru_gen_add_page(stru - int gen = page_lru_gen(page); - int type = page_is_file_lru(page); - int zone = page_zonenum(page); -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - - VM_WARN_ON_ONCE_PAGE(gen != -1, page); - ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -394,7 +394,7 @@ enum { - * The number of pages in each generation is eventually consistent and therefore - * can be transiently negative when reset_batch_size() is pending. - */ --struct lru_gen_struct { -+struct lru_gen_page { - /* the aging increments the youngest generation number */ - unsigned long max_seq; - /* the eviction increments the oldest generation numbers */ -@@ -451,7 +451,7 @@ struct lru_gen_mm_state { - struct lru_gen_mm_walk { - /* the lruvec under reclaim */ - struct lruvec *lruvec; -- /* unstable max_seq from lru_gen_struct */ -+ /* unstable max_seq from lru_gen_page */ - unsigned long max_seq; - /* the next address within an mm to scan */ - unsigned long next_addr; -@@ -514,7 +514,7 @@ struct lruvec { - unsigned long flags; - #ifdef CONFIG_LRU_GEN - /* evictable pages divided into generations */ -- struct lru_gen_struct lrugen; -+ struct lru_gen_page lrugen; - /* to concurrently iterate lru_gen_mm_list */ - struct lru_gen_mm_state mm_state; - #endif ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -2910,7 +2910,7 @@ static int get_nr_gens(struct lruvec *lr - - static bool __maybe_unused seq_is_valid(struct lruvec *lruvec) - { -- /* see the comment on lru_gen_struct */ -+ /* see the comment on lru_gen_page */ - return get_nr_gens(lruvec, LRU_GEN_FILE) >= MIN_NR_GENS && - get_nr_gens(lruvec, LRU_GEN_FILE) <= get_nr_gens(lruvec, LRU_GEN_ANON) && - get_nr_gens(lruvec, LRU_GEN_ANON) <= MAX_NR_GENS; -@@ -3316,7 +3316,7 @@ struct ctrl_pos { - static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain, - struct ctrl_pos *pos) - { -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - int hist = lru_hist_from_seq(lrugen->min_seq[type]); - - pos->refaulted = lrugen->avg_refaulted[type][tier] + -@@ -3331,7 +3331,7 @@ static void read_ctrl_pos(struct lruvec - static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover) - { - int hist, tier; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1; - unsigned long seq = carryover ? lrugen->min_seq[type] : lrugen->max_seq + 1; - -@@ -3408,7 +3408,7 @@ static int page_update_gen(struct page * - static int page_inc_gen(struct lruvec *lruvec, struct page *page, bool reclaiming) - { - int type = page_is_file_lru(page); -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]); - unsigned long new_flags, old_flags = READ_ONCE(page->flags); - -@@ -3453,7 +3453,7 @@ static void update_batch_size(struct lru - static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk) - { - int gen, type, zone; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - - walk->batched = 0; - -@@ -3979,7 +3979,7 @@ static bool inc_min_seq(struct lruvec *l - { - int zone; - int remaining = MAX_LRU_BATCH; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]); - - if (type == LRU_GEN_ANON && !can_swap) -@@ -4015,7 +4015,7 @@ static bool try_to_inc_min_seq(struct lr - { - int gen, type, zone; - bool success = false; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - DEFINE_MIN_SEQ(lruvec); - - VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); -@@ -4036,7 +4036,7 @@ next: - ; - } - -- /* see the comment on lru_gen_struct */ -+ /* see the comment on lru_gen_page */ - if (can_swap) { - min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]); - min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]); -@@ -4058,7 +4058,7 @@ static void inc_max_seq(struct lruvec *l - { - int prev, next; - int type, zone; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - - spin_lock_irq(&lruvec->lru_lock); - -@@ -4116,7 +4116,7 @@ static bool try_to_inc_max_seq(struct lr - bool success; - struct lru_gen_mm_walk *walk; - struct mm_struct *mm = NULL; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - - VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq)); - -@@ -4181,7 +4181,7 @@ static bool should_run_aging(struct lruv - unsigned long old = 0; - unsigned long young = 0; - unsigned long total = 0; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - - for (type = !can_swap; type < ANON_AND_FILE; type++) { -@@ -4466,7 +4466,7 @@ static bool sort_page(struct lruvec *lru - int delta = thp_nr_pages(page); - int refs = page_lru_refs(page); - int tier = lru_tier_from_refs(refs); -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - - VM_WARN_ON_ONCE_PAGE(gen >= MAX_NR_GENS, page); - -@@ -4566,7 +4566,7 @@ static int scan_pages(struct lruvec *lru - int scanned = 0; - int isolated = 0; - int remaining = MAX_LRU_BATCH; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - - VM_WARN_ON_ONCE(!list_empty(list)); -@@ -4967,7 +4967,7 @@ done: - - static bool __maybe_unused state_is_valid(struct lruvec *lruvec) - { -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - - if (lrugen->enabled) { - enum lru_list lru; -@@ -5247,7 +5247,7 @@ static void lru_gen_seq_show_full(struct - int i; - int type, tier; - int hist = lru_hist_from_seq(seq); -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - - for (tier = 0; tier < MAX_NR_TIERS; tier++) { - seq_printf(m, " %10d", tier); -@@ -5296,7 +5296,7 @@ static int lru_gen_seq_show(struct seq_f - unsigned long seq; - bool full = !debugfs_real_fops(m->file)->write; - struct lruvec *lruvec = v; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - int nid = lruvec_pgdat(lruvec)->node_id; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MAX_SEQ(lruvec); -@@ -5549,7 +5549,7 @@ void lru_gen_init_lruvec(struct lruvec * - { - int i; - int gen, type, zone; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - - lrugen->max_seq = MIN_NR_GENS + 1; - lrugen->enabled = lru_gen_enabled(); ---- a/mm/workingset.c -+++ b/mm/workingset.c -@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct pag - unsigned long token; - unsigned long min_seq; - struct lruvec *lruvec; -- struct lru_gen_struct *lrugen; -+ struct lru_gen_page *lrugen; - int type = page_is_file_lru(page); - int delta = thp_nr_pages(page); - int refs = page_lru_refs(page); -@@ -252,7 +252,7 @@ static void lru_gen_refault(struct page - unsigned long token; - unsigned long min_seq; - struct lruvec *lruvec; -- struct lru_gen_struct *lrugen; -+ struct lru_gen_page *lrugen; - struct mem_cgroup *memcg; - struct pglist_data *pgdat; - int type = page_is_file_lru(page); diff --git a/target/linux/generic/backport-5.15/020-v6.3-22-mm-multi-gen-LRU-rename-lrugen-lists-to-lrugen-pages.patch b/target/linux/generic/backport-5.15/020-v6.3-22-mm-multi-gen-LRU-rename-lrugen-lists-to-lrugen-pages.patch deleted file mode 100644 index b548c1c8b3de67..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-22-mm-multi-gen-LRU-rename-lrugen-lists-to-lrugen-pages.patch +++ /dev/null @@ -1,162 +0,0 @@ -From afd37e73db04c7e6b47411120ac5f6a7eca51fec Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:00 -0700 -Subject: [PATCH 22/29] mm: multi-gen LRU: rename lrugen->lists[] to - lrugen->pages[] - -lru_gen_page will be chained into per-node lists by the coming -lrugen->list. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-3-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton ---- - include/linux/mm_inline.h | 4 ++-- - include/linux/mmzone.h | 8 ++++---- - mm/vmscan.c | 20 ++++++++++---------- - 3 files changed, 16 insertions(+), 16 deletions(-) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -246,9 +246,9 @@ static inline bool lru_gen_add_page(stru - lru_gen_update_size(lruvec, page, -1, gen); - /* for rotate_reclaimable_page() */ - if (reclaiming) -- list_add_tail(&page->lru, &lrugen->lists[gen][type][zone]); -+ list_add_tail(&page->lru, &lrugen->pages[gen][type][zone]); - else -- list_add(&page->lru, &lrugen->lists[gen][type][zone]); -+ list_add(&page->lru, &lrugen->pages[gen][type][zone]); - - return true; - } ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -302,7 +302,7 @@ enum lruvec_flags { - * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An - * offset within MAX_NR_GENS, i.e., gen, indexes the LRU list of the - * corresponding generation. The gen counter in page->flags stores gen+1 while -- * a page is on one of lrugen->lists[]. Otherwise it stores 0. -+ * a page is on one of lrugen->pages[]. Otherwise it stores 0. - * - * A page is added to the youngest generation on faulting. The aging needs to - * check the accessed bit at least twice before handing this page over to the -@@ -314,8 +314,8 @@ enum lruvec_flags { - * rest of generations, if they exist, are considered inactive. See - * lru_gen_is_active(). - * -- * PG_active is always cleared while a page is on one of lrugen->lists[] so that -- * the aging needs not to worry about it. And it's set again when a page -+ * PG_active is always cleared while a page is on one of lrugen->pages[] so -+ * that the aging needs not to worry about it. And it's set again when a page - * considered active is isolated for non-reclaiming purposes, e.g., migration. - * See lru_gen_add_page() and lru_gen_del_page(). - * -@@ -402,7 +402,7 @@ struct lru_gen_page { - /* the birth time of each generation in jiffies */ - unsigned long timestamps[MAX_NR_GENS]; - /* the multi-gen LRU lists, lazily sorted on eviction */ -- struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; -+ struct list_head pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; - /* the multi-gen LRU sizes, eventually consistent */ - long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; - /* the exponential moving average of refaulted */ ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3987,7 +3987,7 @@ static bool inc_min_seq(struct lruvec *l - - /* prevent cold/hot inversion if force_scan is true */ - for (zone = 0; zone < MAX_NR_ZONES; zone++) { -- struct list_head *head = &lrugen->lists[old_gen][type][zone]; -+ struct list_head *head = &lrugen->pages[old_gen][type][zone]; - - while (!list_empty(head)) { - struct page *page = lru_to_page(head); -@@ -3998,7 +3998,7 @@ static bool inc_min_seq(struct lruvec *l - VM_WARN_ON_ONCE_PAGE(page_zonenum(page) != zone, page); - - new_gen = page_inc_gen(lruvec, page, false); -- list_move_tail(&page->lru, &lrugen->lists[new_gen][type][zone]); -+ list_move_tail(&page->lru, &lrugen->pages[new_gen][type][zone]); - - if (!--remaining) - return false; -@@ -4026,7 +4026,7 @@ static bool try_to_inc_min_seq(struct lr - gen = lru_gen_from_seq(min_seq[type]); - - for (zone = 0; zone < MAX_NR_ZONES; zone++) { -- if (!list_empty(&lrugen->lists[gen][type][zone])) -+ if (!list_empty(&lrugen->pages[gen][type][zone])) - goto next; - } - -@@ -4491,7 +4491,7 @@ static bool sort_page(struct lruvec *lru - - /* promoted */ - if (gen != lru_gen_from_seq(lrugen->min_seq[type])) { -- list_move(&page->lru, &lrugen->lists[gen][type][zone]); -+ list_move(&page->lru, &lrugen->pages[gen][type][zone]); - return true; - } - -@@ -4500,7 +4500,7 @@ static bool sort_page(struct lruvec *lru - int hist = lru_hist_from_seq(lrugen->min_seq[type]); - - gen = page_inc_gen(lruvec, page, false); -- list_move_tail(&page->lru, &lrugen->lists[gen][type][zone]); -+ list_move_tail(&page->lru, &lrugen->pages[gen][type][zone]); - - WRITE_ONCE(lrugen->protected[hist][type][tier - 1], - lrugen->protected[hist][type][tier - 1] + delta); -@@ -4512,7 +4512,7 @@ static bool sort_page(struct lruvec *lru - if (PageLocked(page) || PageWriteback(page) || - (type == LRU_GEN_FILE && PageDirty(page))) { - gen = page_inc_gen(lruvec, page, true); -- list_move(&page->lru, &lrugen->lists[gen][type][zone]); -+ list_move(&page->lru, &lrugen->pages[gen][type][zone]); - return true; - } - -@@ -4579,7 +4579,7 @@ static int scan_pages(struct lruvec *lru - for (zone = sc->reclaim_idx; zone >= 0; zone--) { - LIST_HEAD(moved); - int skipped = 0; -- struct list_head *head = &lrugen->lists[gen][type][zone]; -+ struct list_head *head = &lrugen->pages[gen][type][zone]; - - while (!list_empty(head)) { - struct page *page = lru_to_page(head); -@@ -4980,7 +4980,7 @@ static bool __maybe_unused state_is_vali - int gen, type, zone; - - for_each_gen_type_zone(gen, type, zone) { -- if (!list_empty(&lrugen->lists[gen][type][zone])) -+ if (!list_empty(&lrugen->pages[gen][type][zone])) - return false; - } - } -@@ -5025,7 +5025,7 @@ static bool drain_evictable(struct lruve - int remaining = MAX_LRU_BATCH; - - for_each_gen_type_zone(gen, type, zone) { -- struct list_head *head = &lruvec->lrugen.lists[gen][type][zone]; -+ struct list_head *head = &lruvec->lrugen.pages[gen][type][zone]; - - while (!list_empty(head)) { - bool success; -@@ -5558,7 +5558,7 @@ void lru_gen_init_lruvec(struct lruvec * - lrugen->timestamps[i] = jiffies; - - for_each_gen_type_zone(gen, type, zone) -- INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); -+ INIT_LIST_HEAD(&lrugen->pages[gen][type][zone]); - - lruvec->mm_state.seq = MIN_NR_GENS; - init_waitqueue_head(&lruvec->mm_state.wait); diff --git a/target/linux/generic/backport-5.15/020-v6.3-23-mm-multi-gen-LRU-remove-eviction-fairness-safeguard.patch b/target/linux/generic/backport-5.15/020-v6.3-23-mm-multi-gen-LRU-remove-eviction-fairness-safeguard.patch deleted file mode 100644 index 2bb6e12a5ae163..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-23-mm-multi-gen-LRU-remove-eviction-fairness-safeguard.patch +++ /dev/null @@ -1,188 +0,0 @@ -From ce45f1c4b32cf69b166f56ef5bc6c761e06ed4e5 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:01 -0700 -Subject: [PATCH 23/29] mm: multi-gen LRU: remove eviction fairness safeguard - -Recall that the eviction consumes the oldest generation: first it -bucket-sorts pages whose gen counters were updated by the aging and -reclaims the rest; then it increments lrugen->min_seq. - -The current eviction fairness safeguard for global reclaim has a -dilemma: when there are multiple eligible memcgs, should it continue -or stop upon meeting the reclaim goal? If it continues, it overshoots -and increases direct reclaim latency; if it stops, it loses fairness -between memcgs it has taken memory away from and those it has yet to. - -With memcg LRU, the eviction, while ensuring eventual fairness, will -stop upon meeting its goal. Therefore the current eviction fairness -safeguard for global reclaim will not be needed. - -Note that memcg LRU only applies to global reclaim. For memcg reclaim, -the eviction will continue, even if it is overshooting. This becomes -unconditional due to code simplification. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-4-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 82 +++++++++++++++-------------------------------------- - 1 file changed, 23 insertions(+), 59 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -443,6 +443,11 @@ static bool cgroup_reclaim(struct scan_c - return sc->target_mem_cgroup; - } - -+static bool global_reclaim(struct scan_control *sc) -+{ -+ return !sc->target_mem_cgroup || mem_cgroup_is_root(sc->target_mem_cgroup); -+} -+ - /** - * writeback_throttling_sane - is the usual dirty throttling mechanism available? - * @sc: scan_control in question -@@ -493,6 +498,11 @@ static bool cgroup_reclaim(struct scan_c - return false; - } - -+static bool global_reclaim(struct scan_control *sc) -+{ -+ return true; -+} -+ - static bool writeback_throttling_sane(struct scan_control *sc) - { - return true; -@@ -4722,8 +4732,7 @@ static int isolate_pages(struct lruvec * - return scanned; - } - --static int evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness, -- bool *need_swapping) -+static int evict_pages(struct lruvec *lruvec, struct scan_control *sc, int swappiness) - { - int type; - int scanned; -@@ -4812,9 +4821,6 @@ retry: - goto retry; - } - -- if (need_swapping && type == LRU_GEN_ANON) -- *need_swapping = true; -- - return scanned; - } - -@@ -4853,68 +4859,26 @@ done: - return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; - } - --static bool should_abort_scan(struct lruvec *lruvec, unsigned long seq, -- struct scan_control *sc, bool need_swapping) -+static unsigned long get_nr_to_reclaim(struct scan_control *sc) - { -- int i; -- DEFINE_MAX_SEQ(lruvec); -- -- if (!current_is_kswapd()) { -- /* age each memcg once to ensure fairness */ -- if (max_seq - seq > 1) -- return true; -- -- /* over-swapping can increase allocation latency */ -- if (sc->nr_reclaimed >= sc->nr_to_reclaim && need_swapping) -- return true; -- -- /* give this thread a chance to exit and free its memory */ -- if (fatal_signal_pending(current)) { -- sc->nr_reclaimed += MIN_LRU_BATCH; -- return true; -- } -- -- if (cgroup_reclaim(sc)) -- return false; -- } else if (sc->nr_reclaimed - sc->last_reclaimed < sc->nr_to_reclaim) -- return false; -- -- /* keep scanning at low priorities to ensure fairness */ -- if (sc->priority > DEF_PRIORITY - 2) -- return false; -- -- /* -- * A minimum amount of work was done under global memory pressure. For -- * kswapd, it may be overshooting. For direct reclaim, the target isn't -- * met, and yet the allocation may still succeed, since kswapd may have -- * caught up. In either case, it's better to stop now, and restart if -- * necessary. -- */ -- for (i = 0; i <= sc->reclaim_idx; i++) { -- unsigned long wmark; -- struct zone *zone = lruvec_pgdat(lruvec)->node_zones + i; -- -- if (!managed_zone(zone)) -- continue; -- -- wmark = current_is_kswapd() ? high_wmark_pages(zone) : low_wmark_pages(zone); -- if (wmark > zone_page_state(zone, NR_FREE_PAGES)) -- return false; -- } -+ /* don't abort memcg reclaim to ensure fairness */ -+ if (!global_reclaim(sc)) -+ return -1; - -- sc->nr_reclaimed += MIN_LRU_BATCH; -+ /* discount the previous progress for kswapd */ -+ if (current_is_kswapd()) -+ return sc->nr_to_reclaim + sc->last_reclaimed; - -- return true; -+ return max(sc->nr_to_reclaim, compact_gap(sc->order)); - } - - static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { - struct blk_plug plug; - bool need_aging = false; -- bool need_swapping = false; - unsigned long scanned = 0; - unsigned long reclaimed = sc->nr_reclaimed; -- DEFINE_MAX_SEQ(lruvec); -+ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); - - lru_add_drain(); - -@@ -4938,7 +4902,7 @@ static void lru_gen_shrink_lruvec(struct - if (!nr_to_scan) - goto done; - -- delta = evict_pages(lruvec, sc, swappiness, &need_swapping); -+ delta = evict_pages(lruvec, sc, swappiness); - if (!delta) - goto done; - -@@ -4946,7 +4910,7 @@ static void lru_gen_shrink_lruvec(struct - if (scanned >= nr_to_scan) - break; - -- if (should_abort_scan(lruvec, max_seq, sc, need_swapping)) -+ if (sc->nr_reclaimed >= nr_to_reclaim) - break; - - cond_resched(); -@@ -5393,7 +5357,7 @@ static int run_eviction(struct lruvec *l - if (sc->nr_reclaimed >= nr_to_reclaim) - return 0; - -- if (!evict_pages(lruvec, sc, swappiness, NULL)) -+ if (!evict_pages(lruvec, sc, swappiness)) - return 0; - - cond_resched(); diff --git a/target/linux/generic/backport-5.15/020-v6.3-24-mm-multi-gen-LRU-remove-aging-fairness-safeguard.patch b/target/linux/generic/backport-5.15/020-v6.3-24-mm-multi-gen-LRU-remove-aging-fairness-safeguard.patch deleted file mode 100644 index 316217ed028d25..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-24-mm-multi-gen-LRU-remove-aging-fairness-safeguard.patch +++ /dev/null @@ -1,287 +0,0 @@ -From e20b7386fccc18c791796eb1dc1a91eee3ccf801 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:02 -0700 -Subject: [PATCH 24/29] mm: multi-gen LRU: remove aging fairness safeguard - -Recall that the aging produces the youngest generation: first it scans -for accessed pages and updates their gen counters; then it increments -lrugen->max_seq. - -The current aging fairness safeguard for kswapd uses two passes to -ensure the fairness to multiple eligible memcgs. On the first pass, -which is shared with the eviction, it checks whether all eligible -memcgs are low on cold pages. If so, it requires a second pass, on -which it ages all those memcgs at the same time. - -With memcg LRU, the aging, while ensuring eventual fairness, will run -when necessary. Therefore the current aging fairness safeguard for -kswapd will not be needed. - -Note that memcg LRU only applies to global reclaim. For memcg reclaim, -the aging can be unfair to different memcgs, i.e., their -lrugen->max_seq can be incremented at different paces. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-5-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 126 ++++++++++++++++++++++++---------------------------- - 1 file changed, 59 insertions(+), 67 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -131,7 +131,6 @@ struct scan_control { - - #ifdef CONFIG_LRU_GEN - /* help kswapd make better choices among multiple memcgs */ -- unsigned int memcgs_need_aging:1; - unsigned long last_reclaimed; - #endif - -@@ -4184,7 +4183,7 @@ done: - return true; - } - --static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq, -+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, - struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) - { - int gen, type, zone; -@@ -4193,6 +4192,13 @@ static bool should_run_aging(struct lruv - unsigned long total = 0; - struct lru_gen_page *lrugen = &lruvec->lrugen; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ /* whether this lruvec is completely out of cold pages */ -+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) { -+ *nr_to_scan = 0; -+ return true; -+ } - - for (type = !can_swap; type < ANON_AND_FILE; type++) { - unsigned long seq; -@@ -4221,8 +4227,6 @@ static bool should_run_aging(struct lruv - * stalls when the number of generations reaches MIN_NR_GENS. Hence, the - * ideal number of generations is MIN_NR_GENS+1. - */ -- if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) -- return true; - if (min_seq[!can_swap] + MIN_NR_GENS < max_seq) - return false; - -@@ -4241,40 +4245,54 @@ static bool should_run_aging(struct lruv - return false; - } - --static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc, unsigned long min_ttl) -+static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc) - { -- bool need_aging; -- unsigned long nr_to_scan; -- int swappiness = get_swappiness(lruvec, sc); -+ int gen, type, zone; -+ unsigned long total = 0; -+ bool can_swap = get_swappiness(lruvec, sc); -+ struct lru_gen_page *lrugen = &lruvec->lrugen; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MAX_SEQ(lruvec); - DEFINE_MIN_SEQ(lruvec); - -- VM_WARN_ON_ONCE(sc->memcg_low_reclaim); -+ for (type = !can_swap; type < ANON_AND_FILE; type++) { -+ unsigned long seq; - -- mem_cgroup_calculate_protection(NULL, memcg); -+ for (seq = min_seq[type]; seq <= max_seq; seq++) { -+ gen = lru_gen_from_seq(seq); - -- if (mem_cgroup_below_min(memcg)) -- return false; -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) -+ total += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); -+ } -+ } - -- need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan); -+ /* whether the size is big enough to be helpful */ -+ return mem_cgroup_online(memcg) ? (total >> sc->priority) : total; -+} - -- if (min_ttl) { -- int gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); -- unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); -+static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc, -+ unsigned long min_ttl) -+{ -+ int gen; -+ unsigned long birth; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MIN_SEQ(lruvec); - -- if (time_is_after_jiffies(birth + min_ttl)) -- return false; -+ VM_WARN_ON_ONCE(sc->memcg_low_reclaim); - -- /* the size is likely too small to be helpful */ -- if (!nr_to_scan && sc->priority != DEF_PRIORITY) -- return false; -- } -+ /* see the comment on lru_gen_page */ -+ gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); -+ birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); - -- if (need_aging) -- try_to_inc_max_seq(lruvec, max_seq, sc, swappiness, false); -+ if (time_is_after_jiffies(birth + min_ttl)) -+ return false; - -- return true; -+ if (!lruvec_is_sizable(lruvec, sc)) -+ return false; -+ -+ mem_cgroup_calculate_protection(NULL, memcg); -+ -+ return !mem_cgroup_below_min(memcg); - } - - /* to protect the working set of the last N jiffies */ -@@ -4283,46 +4301,32 @@ static unsigned long lru_gen_min_ttl __r - static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) - { - struct mem_cgroup *memcg; -- bool success = false; - unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl); - - VM_WARN_ON_ONCE(!current_is_kswapd()); - - sc->last_reclaimed = sc->nr_reclaimed; - -- /* -- * To reduce the chance of going into the aging path, which can be -- * costly, optimistically skip it if the flag below was cleared in the -- * eviction path. This improves the overall performance when multiple -- * memcgs are available. -- */ -- if (!sc->memcgs_need_aging) { -- sc->memcgs_need_aging = true; -+ /* check the order to exclude compaction-induced reclaim */ -+ if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY) - return; -- } -- -- set_mm_walk(pgdat); - - memcg = mem_cgroup_iter(NULL, NULL, NULL); - do { - struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); - -- if (age_lruvec(lruvec, sc, min_ttl)) -- success = true; -+ if (lruvec_is_reclaimable(lruvec, sc, min_ttl)) { -+ mem_cgroup_iter_break(NULL, memcg); -+ return; -+ } - - cond_resched(); - } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); - -- clear_mm_walk(); -- -- /* check the order to exclude compaction-induced reclaim */ -- if (success || !min_ttl || sc->order) -- return; -- - /* - * The main goal is to OOM kill if every generation from all memcgs is - * younger than min_ttl. However, another possibility is all memcgs are -- * either below min or empty. -+ * either too small or below min. - */ - if (mutex_trylock(&oom_lock)) { - struct oom_control oc = { -@@ -4830,33 +4834,27 @@ retry: - * reclaim. - */ - static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, -- bool can_swap, bool *need_aging) -+ bool can_swap) - { - unsigned long nr_to_scan; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MAX_SEQ(lruvec); -- DEFINE_MIN_SEQ(lruvec); - - if (mem_cgroup_below_min(memcg) || - (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) - return 0; - -- *need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan); -- if (!*need_aging) -+ if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan)) - return nr_to_scan; - - /* skip the aging path at the default priority */ - if (sc->priority == DEF_PRIORITY) -- goto done; -+ return nr_to_scan; - -- /* leave the work to lru_gen_age_node() */ -- if (current_is_kswapd()) -- return 0; -+ try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false); - -- if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false)) -- return nr_to_scan; --done: -- return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; -+ /* skip this lruvec as it's low on cold pages */ -+ return 0; - } - - static unsigned long get_nr_to_reclaim(struct scan_control *sc) -@@ -4875,9 +4873,7 @@ static unsigned long get_nr_to_reclaim(s - static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { - struct blk_plug plug; -- bool need_aging = false; - unsigned long scanned = 0; -- unsigned long reclaimed = sc->nr_reclaimed; - unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); - - lru_add_drain(); -@@ -4898,13 +4894,13 @@ static void lru_gen_shrink_lruvec(struct - else - swappiness = 0; - -- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness, &need_aging); -+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); - if (!nr_to_scan) -- goto done; -+ break; - - delta = evict_pages(lruvec, sc, swappiness); - if (!delta) -- goto done; -+ break; - - scanned += delta; - if (scanned >= nr_to_scan) -@@ -4916,10 +4912,6 @@ static void lru_gen_shrink_lruvec(struct - cond_resched(); - } - -- /* see the comment in lru_gen_age_node() */ -- if (sc->nr_reclaimed - reclaimed >= MIN_LRU_BATCH && !need_aging) -- sc->memcgs_need_aging = false; --done: - clear_mm_walk(); - - blk_finish_plug(&plug); diff --git a/target/linux/generic/backport-5.15/020-v6.3-25-mm-multi-gen-LRU-shuffle-should_run_aging.patch b/target/linux/generic/backport-5.15/020-v6.3-25-mm-multi-gen-LRU-shuffle-should_run_aging.patch deleted file mode 100644 index 391ee6e67cea48..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-25-mm-multi-gen-LRU-shuffle-should_run_aging.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 107d54931df3c28d81648122e219bf0034ef4e99 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:03 -0700 -Subject: [PATCH 25/29] mm: multi-gen LRU: shuffle should_run_aging() - -Move should_run_aging() next to its only caller left. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-6-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 124 ++++++++++++++++++++++++++-------------------------- - 1 file changed, 62 insertions(+), 62 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4183,68 +4183,6 @@ done: - return true; - } - --static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, -- struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) --{ -- int gen, type, zone; -- unsigned long old = 0; -- unsigned long young = 0; -- unsigned long total = 0; -- struct lru_gen_page *lrugen = &lruvec->lrugen; -- struct mem_cgroup *memcg = lruvec_memcg(lruvec); -- DEFINE_MIN_SEQ(lruvec); -- -- /* whether this lruvec is completely out of cold pages */ -- if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) { -- *nr_to_scan = 0; -- return true; -- } -- -- for (type = !can_swap; type < ANON_AND_FILE; type++) { -- unsigned long seq; -- -- for (seq = min_seq[type]; seq <= max_seq; seq++) { -- unsigned long size = 0; -- -- gen = lru_gen_from_seq(seq); -- -- for (zone = 0; zone < MAX_NR_ZONES; zone++) -- size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); -- -- total += size; -- if (seq == max_seq) -- young += size; -- else if (seq + MIN_NR_GENS == max_seq) -- old += size; -- } -- } -- -- /* try to scrape all its memory if this memcg was deleted */ -- *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total; -- -- /* -- * The aging tries to be lazy to reduce the overhead, while the eviction -- * stalls when the number of generations reaches MIN_NR_GENS. Hence, the -- * ideal number of generations is MIN_NR_GENS+1. -- */ -- if (min_seq[!can_swap] + MIN_NR_GENS < max_seq) -- return false; -- -- /* -- * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1) -- * of the total number of pages for each generation. A reasonable range -- * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The -- * aging cares about the upper bound of hot pages, while the eviction -- * cares about the lower bound of cold pages. -- */ -- if (young * MIN_NR_GENS > total) -- return true; -- if (old * (MIN_NR_GENS + 2) < total) -- return true; -- -- return false; --} -- - static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc) - { - int gen, type, zone; -@@ -4828,6 +4766,68 @@ retry: - return scanned; - } - -+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, -+ struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) -+{ -+ int gen, type, zone; -+ unsigned long old = 0; -+ unsigned long young = 0; -+ unsigned long total = 0; -+ struct lru_gen_page *lrugen = &lruvec->lrugen; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ /* whether this lruvec is completely out of cold pages */ -+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) { -+ *nr_to_scan = 0; -+ return true; -+ } -+ -+ for (type = !can_swap; type < ANON_AND_FILE; type++) { -+ unsigned long seq; -+ -+ for (seq = min_seq[type]; seq <= max_seq; seq++) { -+ unsigned long size = 0; -+ -+ gen = lru_gen_from_seq(seq); -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) -+ size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); -+ -+ total += size; -+ if (seq == max_seq) -+ young += size; -+ else if (seq + MIN_NR_GENS == max_seq) -+ old += size; -+ } -+ } -+ -+ /* try to scrape all its memory if this memcg was deleted */ -+ *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total; -+ -+ /* -+ * The aging tries to be lazy to reduce the overhead, while the eviction -+ * stalls when the number of generations reaches MIN_NR_GENS. Hence, the -+ * ideal number of generations is MIN_NR_GENS+1. -+ */ -+ if (min_seq[!can_swap] + MIN_NR_GENS < max_seq) -+ return false; -+ -+ /* -+ * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1) -+ * of the total number of pages for each generation. A reasonable range -+ * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The -+ * aging cares about the upper bound of hot pages, while the eviction -+ * cares about the lower bound of cold pages. -+ */ -+ if (young * MIN_NR_GENS > total) -+ return true; -+ if (old * (MIN_NR_GENS + 2) < total) -+ return true; -+ -+ return false; -+} -+ - /* - * For future optimizations: - * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg diff --git a/target/linux/generic/backport-5.15/020-v6.3-26-mm-multi-gen-LRU-per-node-lru_gen_page-lists.patch b/target/linux/generic/backport-5.15/020-v6.3-26-mm-multi-gen-LRU-per-node-lru_gen_page-lists.patch deleted file mode 100644 index cfeeaa662a0b1f..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-26-mm-multi-gen-LRU-per-node-lru_gen_page-lists.patch +++ /dev/null @@ -1,868 +0,0 @@ -From fa6363828d314e837c5f79e97ea5e8c0d2f7f062 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:04 -0700 -Subject: [PATCH 26/29] mm: multi-gen LRU: per-node lru_gen_page lists - -For each node, memcgs are divided into two generations: the old and -the young. For each generation, memcgs are randomly sharded into -multiple bins to improve scalability. For each bin, an RCU hlist_nulls -is virtually divided into three segments: the head, the tail and the -default. - -An onlining memcg is added to the tail of a random bin in the old -generation. The eviction starts at the head of a random bin in the old -generation. The per-node memcg generation counter, whose reminder (mod -2) indexes the old generation, is incremented when all its bins become -empty. - -There are four operations: -1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in - its current generation (old or young) and updates its "seg" to - "head"; -2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in - its current generation (old or young) and updates its "seg" to - "tail"; -3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in - the old generation, updates its "gen" to "old" and resets its "seg" - to "default"; -4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin - in the young generation, updates its "gen" to "young" and resets - its "seg" to "default". - -The events that trigger the above operations are: -1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD; -2. The first attempt to reclaim an memcg below low, which triggers - MEMCG_LRU_TAIL; -3. The first attempt to reclaim an memcg below reclaimable size - threshold, which triggers MEMCG_LRU_TAIL; -4. The second attempt to reclaim an memcg below reclaimable size - threshold, which triggers MEMCG_LRU_YOUNG; -5. Attempting to reclaim an memcg below min, which triggers - MEMCG_LRU_YOUNG; -6. Finishing the aging on the eviction path, which triggers - MEMCG_LRU_YOUNG; -7. Offlining an memcg, which triggers MEMCG_LRU_OLD. - -Note that memcg LRU only applies to global reclaim, and the -round-robin incrementing of their max_seq counters ensures the -eventual fairness to all eligible memcgs. For memcg reclaim, it still -relies on mem_cgroup_iter(). - -Link: https://lkml.kernel.org/r/20221222041905.2431096-7-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton ---- - include/linux/memcontrol.h | 10 + - include/linux/mm_inline.h | 17 ++ - include/linux/mmzone.h | 117 +++++++++++- - mm/memcontrol.c | 16 ++ - mm/page_alloc.c | 1 + - mm/vmscan.c | 373 +++++++++++++++++++++++++++++++++---- - 6 files changed, 499 insertions(+), 35 deletions(-) - ---- a/include/linux/memcontrol.h -+++ b/include/linux/memcontrol.h -@@ -823,6 +823,11 @@ static inline void obj_cgroup_put(struct - percpu_ref_put(&objcg->refcnt); - } - -+static inline bool mem_cgroup_tryget(struct mem_cgroup *memcg) -+{ -+ return !memcg || css_tryget(&memcg->css); -+} -+ - static inline void mem_cgroup_put(struct mem_cgroup *memcg) - { - if (memcg) -@@ -1288,6 +1293,11 @@ struct mem_cgroup *mem_cgroup_from_css(s - return NULL; - } - -+static inline bool mem_cgroup_tryget(struct mem_cgroup *memcg) -+{ -+ return true; -+} -+ - static inline void mem_cgroup_put(struct mem_cgroup *memcg) - { - } ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -112,6 +112,18 @@ static inline bool lru_gen_in_fault(void - return current->in_lru_fault; - } - -+#ifdef CONFIG_MEMCG -+static inline int lru_gen_memcg_seg(struct lruvec *lruvec) -+{ -+ return READ_ONCE(lruvec->lrugen.seg); -+} -+#else -+static inline int lru_gen_memcg_seg(struct lruvec *lruvec) -+{ -+ return 0; -+} -+#endif -+ - static inline int lru_gen_from_seq(unsigned long seq) - { - return seq % MAX_NR_GENS; -@@ -287,6 +299,11 @@ static inline bool lru_gen_in_fault(void - return false; - } - -+static inline int lru_gen_memcg_seg(struct lruvec *lruvec) -+{ -+ return 0; -+} -+ - static inline bool lru_gen_add_page(struct lruvec *lruvec, struct page *page, bool reclaiming) - { - return false; ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -7,6 +7,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -357,6 +358,15 @@ struct page_vma_mapped_walk; - #define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF) - #define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF) - -+/* see the comment on MEMCG_NR_GENS */ -+enum { -+ MEMCG_LRU_NOP, -+ MEMCG_LRU_HEAD, -+ MEMCG_LRU_TAIL, -+ MEMCG_LRU_OLD, -+ MEMCG_LRU_YOUNG, -+}; -+ - #ifdef CONFIG_LRU_GEN - - enum { -@@ -416,6 +426,14 @@ struct lru_gen_page { - atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; - /* whether the multi-gen LRU is enabled */ - bool enabled; -+#ifdef CONFIG_MEMCG -+ /* the memcg generation this lru_gen_page belongs to */ -+ u8 gen; -+ /* the list segment this lru_gen_page belongs to */ -+ u8 seg; -+ /* per-node lru_gen_page list for global reclaim */ -+ struct hlist_nulls_node list; -+#endif - }; - - enum { -@@ -469,12 +487,87 @@ void lru_gen_init_lruvec(struct lruvec * - void lru_gen_look_around(struct page_vma_mapped_walk *pvmw); - - #ifdef CONFIG_MEMCG -+ -+/* -+ * For each node, memcgs are divided into two generations: the old and the -+ * young. For each generation, memcgs are randomly sharded into multiple bins -+ * to improve scalability. For each bin, the hlist_nulls is virtually divided -+ * into three segments: the head, the tail and the default. -+ * -+ * An onlining memcg is added to the tail of a random bin in the old generation. -+ * The eviction starts at the head of a random bin in the old generation. The -+ * per-node memcg generation counter, whose reminder (mod MEMCG_NR_GENS) indexes -+ * the old generation, is incremented when all its bins become empty. -+ * -+ * There are four operations: -+ * 1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in its -+ * current generation (old or young) and updates its "seg" to "head"; -+ * 2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in its -+ * current generation (old or young) and updates its "seg" to "tail"; -+ * 3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in the old -+ * generation, updates its "gen" to "old" and resets its "seg" to "default"; -+ * 4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin in the -+ * young generation, updates its "gen" to "young" and resets its "seg" to -+ * "default". -+ * -+ * The events that trigger the above operations are: -+ * 1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD; -+ * 2. The first attempt to reclaim an memcg below low, which triggers -+ * MEMCG_LRU_TAIL; -+ * 3. The first attempt to reclaim an memcg below reclaimable size threshold, -+ * which triggers MEMCG_LRU_TAIL; -+ * 4. The second attempt to reclaim an memcg below reclaimable size threshold, -+ * which triggers MEMCG_LRU_YOUNG; -+ * 5. Attempting to reclaim an memcg below min, which triggers MEMCG_LRU_YOUNG; -+ * 6. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG; -+ * 7. Offlining an memcg, which triggers MEMCG_LRU_OLD. -+ * -+ * Note that memcg LRU only applies to global reclaim, and the round-robin -+ * incrementing of their max_seq counters ensures the eventual fairness to all -+ * eligible memcgs. For memcg reclaim, it still relies on mem_cgroup_iter(). -+ */ -+#define MEMCG_NR_GENS 2 -+#define MEMCG_NR_BINS 8 -+ -+struct lru_gen_memcg { -+ /* the per-node memcg generation counter */ -+ unsigned long seq; -+ /* each memcg has one lru_gen_page per node */ -+ unsigned long nr_memcgs[MEMCG_NR_GENS]; -+ /* per-node lru_gen_page list for global reclaim */ -+ struct hlist_nulls_head fifo[MEMCG_NR_GENS][MEMCG_NR_BINS]; -+ /* protects the above */ -+ spinlock_t lock; -+}; -+ -+void lru_gen_init_pgdat(struct pglist_data *pgdat); -+ - void lru_gen_init_memcg(struct mem_cgroup *memcg); - void lru_gen_exit_memcg(struct mem_cgroup *memcg); --#endif -+void lru_gen_online_memcg(struct mem_cgroup *memcg); -+void lru_gen_offline_memcg(struct mem_cgroup *memcg); -+void lru_gen_release_memcg(struct mem_cgroup *memcg); -+void lru_gen_rotate_memcg(struct lruvec *lruvec, int op); -+ -+#else /* !CONFIG_MEMCG */ -+ -+#define MEMCG_NR_GENS 1 -+ -+struct lru_gen_memcg { -+}; -+ -+static inline void lru_gen_init_pgdat(struct pglist_data *pgdat) -+{ -+} -+ -+#endif /* CONFIG_MEMCG */ - - #else /* !CONFIG_LRU_GEN */ - -+static inline void lru_gen_init_pgdat(struct pglist_data *pgdat) -+{ -+} -+ - static inline void lru_gen_init_lruvec(struct lruvec *lruvec) - { - } -@@ -484,6 +577,7 @@ static inline void lru_gen_look_around(s - } - - #ifdef CONFIG_MEMCG -+ - static inline void lru_gen_init_memcg(struct mem_cgroup *memcg) - { - } -@@ -491,7 +585,24 @@ static inline void lru_gen_init_memcg(st - static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg) - { - } --#endif -+ -+static inline void lru_gen_online_memcg(struct mem_cgroup *memcg) -+{ -+} -+ -+static inline void lru_gen_offline_memcg(struct mem_cgroup *memcg) -+{ -+} -+ -+static inline void lru_gen_release_memcg(struct mem_cgroup *memcg) -+{ -+} -+ -+static inline void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) -+{ -+} -+ -+#endif /* CONFIG_MEMCG */ - - #endif /* CONFIG_LRU_GEN */ - -@@ -1105,6 +1216,8 @@ typedef struct pglist_data { - #ifdef CONFIG_LRU_GEN - /* kswap mm walk data */ - struct lru_gen_mm_walk mm_walk; -+ /* lru_gen_page list */ -+ struct lru_gen_memcg memcg_lru; - #endif - - ZONE_PADDING(_pad2_) ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -549,6 +549,16 @@ static void mem_cgroup_update_tree(struc - struct mem_cgroup_per_node *mz; - struct mem_cgroup_tree_per_node *mctz; - -+ if (lru_gen_enabled()) { -+ struct lruvec *lruvec = &mem_cgroup_page_nodeinfo(memcg, page)->lruvec; -+ -+ /* see the comment on MEMCG_NR_GENS */ -+ if (soft_limit_excess(memcg) && lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD) -+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD); -+ -+ return; -+ } -+ - mctz = soft_limit_tree_from_page(page); - if (!mctz) - return; -@@ -3434,6 +3444,9 @@ unsigned long mem_cgroup_soft_limit_recl - unsigned long excess; - unsigned long nr_scanned; - -+ if (lru_gen_enabled()) -+ return 0; -+ - if (order > 0) - return 0; - -@@ -5322,6 +5335,7 @@ static int mem_cgroup_css_online(struct - if (unlikely(mem_cgroup_is_root(memcg))) - queue_delayed_work(system_unbound_wq, &stats_flush_dwork, - 2UL*HZ); -+ lru_gen_online_memcg(memcg); - return 0; - } - -@@ -5348,6 +5362,7 @@ static void mem_cgroup_css_offline(struc - memcg_offline_kmem(memcg); - reparent_shrinker_deferred(memcg); - wb_memcg_offline(memcg); -+ lru_gen_offline_memcg(memcg); - - drain_all_stock(memcg); - -@@ -5359,6 +5374,7 @@ static void mem_cgroup_css_released(stru - struct mem_cgroup *memcg = mem_cgroup_from_css(css); - - invalidate_reclaim_iterators(memcg); -+ lru_gen_release_memcg(memcg); - } - - static void mem_cgroup_css_free(struct cgroup_subsys_state *css) ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -7663,6 +7663,7 @@ static void __init free_area_init_node(i - pgdat_set_deferred_range(pgdat); - - free_area_init_core(pgdat); -+ lru_gen_init_pgdat(pgdat); - } - - void __init free_area_init_memoryless_node(int nid) ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -54,6 +54,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -129,11 +131,6 @@ struct scan_control { - /* Always discard instead of demoting to lower tier memory */ - unsigned int no_demotion:1; - --#ifdef CONFIG_LRU_GEN -- /* help kswapd make better choices among multiple memcgs */ -- unsigned long last_reclaimed; --#endif -- - /* Allocation order */ - s8 order; - -@@ -2880,6 +2877,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_ca - for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ - for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++) - -+#define get_memcg_gen(seq) ((seq) % MEMCG_NR_GENS) -+#define get_memcg_bin(bin) ((bin) % MEMCG_NR_BINS) -+ - static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid) - { - struct pglist_data *pgdat = NODE_DATA(nid); -@@ -4169,8 +4169,7 @@ done: - if (sc->priority <= DEF_PRIORITY - 2) - wait_event_killable(lruvec->mm_state.wait, - max_seq < READ_ONCE(lrugen->max_seq)); -- -- return max_seq < READ_ONCE(lrugen->max_seq); -+ return false; - } - - VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq)); -@@ -4243,8 +4242,6 @@ static void lru_gen_age_node(struct pgli - - VM_WARN_ON_ONCE(!current_is_kswapd()); - -- sc->last_reclaimed = sc->nr_reclaimed; -- - /* check the order to exclude compaction-induced reclaim */ - if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY) - return; -@@ -4833,8 +4830,7 @@ static bool should_run_aging(struct lruv - * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg - * reclaim. - */ --static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, -- bool can_swap) -+static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool can_swap) - { - unsigned long nr_to_scan; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); -@@ -4851,10 +4847,8 @@ static unsigned long get_nr_to_scan(stru - if (sc->priority == DEF_PRIORITY) - return nr_to_scan; - -- try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false); -- - /* skip this lruvec as it's low on cold pages */ -- return 0; -+ return try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false) ? -1 : 0; - } - - static unsigned long get_nr_to_reclaim(struct scan_control *sc) -@@ -4863,29 +4857,18 @@ static unsigned long get_nr_to_reclaim(s - if (!global_reclaim(sc)) - return -1; - -- /* discount the previous progress for kswapd */ -- if (current_is_kswapd()) -- return sc->nr_to_reclaim + sc->last_reclaimed; -- - return max(sc->nr_to_reclaim, compact_gap(sc->order)); - } - --static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { -- struct blk_plug plug; -+ long nr_to_scan; - unsigned long scanned = 0; - unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); - -- lru_add_drain(); -- -- blk_start_plug(&plug); -- -- set_mm_walk(lruvec_pgdat(lruvec)); -- - while (true) { - int delta; - int swappiness; -- unsigned long nr_to_scan; - - if (sc->may_swap) - swappiness = get_swappiness(lruvec, sc); -@@ -4895,7 +4878,7 @@ static void lru_gen_shrink_lruvec(struct - swappiness = 0; - - nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); -- if (!nr_to_scan) -+ if (nr_to_scan <= 0) - break; - - delta = evict_pages(lruvec, sc, swappiness); -@@ -4912,10 +4895,250 @@ static void lru_gen_shrink_lruvec(struct - cond_resched(); - } - -+ /* whether try_to_inc_max_seq() was successful */ -+ return nr_to_scan < 0; -+} -+ -+static int shrink_one(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ bool success; -+ unsigned long scanned = sc->nr_scanned; -+ unsigned long reclaimed = sc->nr_reclaimed; -+ int seg = lru_gen_memcg_seg(lruvec); -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ -+ /* see the comment on MEMCG_NR_GENS */ -+ if (!lruvec_is_sizable(lruvec, sc)) -+ return seg != MEMCG_LRU_TAIL ? MEMCG_LRU_TAIL : MEMCG_LRU_YOUNG; -+ -+ mem_cgroup_calculate_protection(NULL, memcg); -+ -+ if (mem_cgroup_below_min(memcg)) -+ return MEMCG_LRU_YOUNG; -+ -+ if (mem_cgroup_below_low(memcg)) { -+ /* see the comment on MEMCG_NR_GENS */ -+ if (seg != MEMCG_LRU_TAIL) -+ return MEMCG_LRU_TAIL; -+ -+ memcg_memory_event(memcg, MEMCG_LOW); -+ } -+ -+ success = try_to_shrink_lruvec(lruvec, sc); -+ -+ shrink_slab(sc->gfp_mask, pgdat->node_id, memcg, sc->priority); -+ -+ vmpressure(sc->gfp_mask, memcg, false, sc->nr_scanned - scanned, -+ sc->nr_reclaimed - reclaimed); -+ -+ sc->nr_reclaimed += current->reclaim_state->reclaimed_slab; -+ current->reclaim_state->reclaimed_slab = 0; -+ -+ return success ? MEMCG_LRU_YOUNG : 0; -+} -+ -+#ifdef CONFIG_MEMCG -+ -+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ int gen; -+ int bin; -+ int first_bin; -+ struct lruvec *lruvec; -+ struct lru_gen_page *lrugen; -+ const struct hlist_nulls_node *pos; -+ int op = 0; -+ struct mem_cgroup *memcg = NULL; -+ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); -+ -+ bin = first_bin = prandom_u32_max(MEMCG_NR_BINS); -+restart: -+ gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq)); -+ -+ rcu_read_lock(); -+ -+ hlist_nulls_for_each_entry_rcu(lrugen, pos, &pgdat->memcg_lru.fifo[gen][bin], list) { -+ if (op) -+ lru_gen_rotate_memcg(lruvec, op); -+ -+ mem_cgroup_put(memcg); -+ -+ lruvec = container_of(lrugen, struct lruvec, lrugen); -+ memcg = lruvec_memcg(lruvec); -+ -+ if (!mem_cgroup_tryget(memcg)) { -+ op = 0; -+ memcg = NULL; -+ continue; -+ } -+ -+ rcu_read_unlock(); -+ -+ op = shrink_one(lruvec, sc); -+ -+ if (sc->nr_reclaimed >= nr_to_reclaim) -+ goto success; -+ -+ rcu_read_lock(); -+ } -+ -+ rcu_read_unlock(); -+ -+ /* restart if raced with lru_gen_rotate_memcg() */ -+ if (gen != get_nulls_value(pos)) -+ goto restart; -+ -+ /* try the rest of the bins of the current generation */ -+ bin = get_memcg_bin(bin + 1); -+ if (bin != first_bin) -+ goto restart; -+success: -+ if (op) -+ lru_gen_rotate_memcg(lruvec, op); -+ -+ mem_cgroup_put(memcg); -+} -+ -+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ struct blk_plug plug; -+ -+ VM_WARN_ON_ONCE(global_reclaim(sc)); -+ -+ lru_add_drain(); -+ -+ blk_start_plug(&plug); -+ -+ set_mm_walk(lruvec_pgdat(lruvec)); -+ -+ if (try_to_shrink_lruvec(lruvec, sc)) -+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG); -+ -+ clear_mm_walk(); -+ -+ blk_finish_plug(&plug); -+} -+ -+#else /* !CONFIG_MEMCG */ -+ -+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ BUILD_BUG(); -+} -+ -+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ BUILD_BUG(); -+} -+ -+#endif -+ -+static void set_initial_priority(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ int priority; -+ unsigned long reclaimable; -+ struct lruvec *lruvec = mem_cgroup_lruvec(NULL, pgdat); -+ -+ if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH) -+ return; -+ /* -+ * Determine the initial priority based on ((total / MEMCG_NR_GENS) >> -+ * priority) * reclaimed_to_scanned_ratio = nr_to_reclaim, where the -+ * estimated reclaimed_to_scanned_ratio = inactive / total. -+ */ -+ reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE); -+ if (get_swappiness(lruvec, sc)) -+ reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON); -+ -+ reclaimable /= MEMCG_NR_GENS; -+ -+ /* round down reclaimable and round up sc->nr_to_reclaim */ -+ priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1); -+ -+ sc->priority = clamp(priority, 0, DEF_PRIORITY); -+} -+ -+static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ struct blk_plug plug; -+ unsigned long reclaimed = sc->nr_reclaimed; -+ -+ VM_WARN_ON_ONCE(!global_reclaim(sc)); -+ -+ lru_add_drain(); -+ -+ blk_start_plug(&plug); -+ -+ set_mm_walk(pgdat); -+ -+ set_initial_priority(pgdat, sc); -+ -+ if (current_is_kswapd()) -+ sc->nr_reclaimed = 0; -+ -+ if (mem_cgroup_disabled()) -+ shrink_one(&pgdat->__lruvec, sc); -+ else -+ shrink_many(pgdat, sc); -+ -+ if (current_is_kswapd()) -+ sc->nr_reclaimed += reclaimed; -+ - clear_mm_walk(); - - blk_finish_plug(&plug); -+ -+ /* kswapd should never fail */ -+ pgdat->kswapd_failures = 0; -+} -+ -+#ifdef CONFIG_MEMCG -+void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) -+{ -+ int seg; -+ int old, new; -+ int bin = prandom_u32_max(MEMCG_NR_BINS); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ -+ spin_lock(&pgdat->memcg_lru.lock); -+ -+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); -+ -+ seg = 0; -+ new = old = lruvec->lrugen.gen; -+ -+ /* see the comment on MEMCG_NR_GENS */ -+ if (op == MEMCG_LRU_HEAD) -+ seg = MEMCG_LRU_HEAD; -+ else if (op == MEMCG_LRU_TAIL) -+ seg = MEMCG_LRU_TAIL; -+ else if (op == MEMCG_LRU_OLD) -+ new = get_memcg_gen(pgdat->memcg_lru.seq); -+ else if (op == MEMCG_LRU_YOUNG) -+ new = get_memcg_gen(pgdat->memcg_lru.seq + 1); -+ else -+ VM_WARN_ON_ONCE(true); -+ -+ hlist_nulls_del_rcu(&lruvec->lrugen.list); -+ -+ if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD) -+ hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); -+ else -+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); -+ -+ pgdat->memcg_lru.nr_memcgs[old]--; -+ pgdat->memcg_lru.nr_memcgs[new]++; -+ -+ lruvec->lrugen.gen = new; -+ WRITE_ONCE(lruvec->lrugen.seg, seg); -+ -+ if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq)) -+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); -+ -+ spin_unlock(&pgdat->memcg_lru.lock); - } -+#endif - - /****************************************************************************** - * state change -@@ -5370,11 +5593,11 @@ static int run_cmd(char cmd, int memcg_i - - if (!mem_cgroup_disabled()) { - rcu_read_lock(); -+ - memcg = mem_cgroup_from_id(memcg_id); --#ifdef CONFIG_MEMCG -- if (memcg && !css_tryget(&memcg->css)) -+ if (!mem_cgroup_tryget(memcg)) - memcg = NULL; --#endif -+ - rcu_read_unlock(); - - if (!memcg) -@@ -5521,6 +5744,19 @@ void lru_gen_init_lruvec(struct lruvec * - } - - #ifdef CONFIG_MEMCG -+ -+void lru_gen_init_pgdat(struct pglist_data *pgdat) -+{ -+ int i, j; -+ -+ spin_lock_init(&pgdat->memcg_lru.lock); -+ -+ for (i = 0; i < MEMCG_NR_GENS; i++) { -+ for (j = 0; j < MEMCG_NR_BINS; j++) -+ INIT_HLIST_NULLS_HEAD(&pgdat->memcg_lru.fifo[i][j], i); -+ } -+} -+ - void lru_gen_init_memcg(struct mem_cgroup *memcg) - { - INIT_LIST_HEAD(&memcg->mm_list.fifo); -@@ -5544,7 +5780,69 @@ void lru_gen_exit_memcg(struct mem_cgrou - } - } - } --#endif -+ -+void lru_gen_online_memcg(struct mem_cgroup *memcg) -+{ -+ int gen; -+ int nid; -+ int bin = prandom_u32_max(MEMCG_NR_BINS); -+ -+ for_each_node(nid) { -+ struct pglist_data *pgdat = NODE_DATA(nid); -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ spin_lock(&pgdat->memcg_lru.lock); -+ -+ VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list)); -+ -+ gen = get_memcg_gen(pgdat->memcg_lru.seq); -+ -+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]); -+ pgdat->memcg_lru.nr_memcgs[gen]++; -+ -+ lruvec->lrugen.gen = gen; -+ -+ spin_unlock(&pgdat->memcg_lru.lock); -+ } -+} -+ -+void lru_gen_offline_memcg(struct mem_cgroup *memcg) -+{ -+ int nid; -+ -+ for_each_node(nid) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD); -+ } -+} -+ -+void lru_gen_release_memcg(struct mem_cgroup *memcg) -+{ -+ int gen; -+ int nid; -+ -+ for_each_node(nid) { -+ struct pglist_data *pgdat = NODE_DATA(nid); -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ spin_lock(&pgdat->memcg_lru.lock); -+ -+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); -+ -+ gen = lruvec->lrugen.gen; -+ -+ hlist_nulls_del_rcu(&lruvec->lrugen.list); -+ pgdat->memcg_lru.nr_memcgs[gen]--; -+ -+ if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq)) -+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); -+ -+ spin_unlock(&pgdat->memcg_lru.lock); -+ } -+} -+ -+#endif /* CONFIG_MEMCG */ - - static int __init init_lru_gen(void) - { -@@ -5571,6 +5869,10 @@ static void lru_gen_shrink_lruvec(struct - { - } - -+static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+} -+ - #endif /* CONFIG_LRU_GEN */ - - static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -@@ -5584,7 +5886,7 @@ static void shrink_lruvec(struct lruvec - bool proportional_reclaim; - struct blk_plug plug; - -- if (lru_gen_enabled()) { -+ if (lru_gen_enabled() && !global_reclaim(sc)) { - lru_gen_shrink_lruvec(lruvec, sc); - return; - } -@@ -5826,6 +6128,11 @@ static void shrink_node(pg_data_t *pgdat - struct lruvec *target_lruvec; - bool reclaimable = false; - -+ if (lru_gen_enabled() && global_reclaim(sc)) { -+ lru_gen_shrink_node(pgdat, sc); -+ return; -+ } -+ - target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); - - again: diff --git a/target/linux/generic/backport-5.15/020-v6.3-27-mm-multi-gen-LRU-clarify-scan_control-flags.patch b/target/linux/generic/backport-5.15/020-v6.3-27-mm-multi-gen-LRU-clarify-scan_control-flags.patch deleted file mode 100644 index 882f29e98922d4..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-27-mm-multi-gen-LRU-clarify-scan_control-flags.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 93147736b5b3a21bea24313bfc7a696829932009 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:05 -0700 -Subject: [PATCH 27/29] mm: multi-gen LRU: clarify scan_control flags - -Among the flags in scan_control: -1. sc->may_swap, which indicates swap constraint due to memsw.max, is - supported as usual. -2. sc->proactive, which indicates reclaim by memory.reclaim, may not - opportunistically skip the aging path, since it is considered less - latency sensitive. -3. !(sc->gfp_mask & __GFP_IO), which indicates IO constraint, lowers - swappiness to prioritize file LRU, since clean file pages are more - likely to exist. -4. sc->may_writepage and sc->may_unmap, which indicates opportunistic - reclaim, are rejected, since unmapped clean pages are already - prioritized. Scanning for more of them is likely futile and can - cause high reclaim latency when there is a large number of memcgs. - -The rest are handled by the existing code. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-8-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 55 +++++++++++++++++++++++++++-------------------------- - 1 file changed, 28 insertions(+), 27 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -2905,6 +2905,9 @@ static int get_swappiness(struct lruvec - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - struct pglist_data *pgdat = lruvec_pgdat(lruvec); - -+ if (!sc->may_swap) -+ return 0; -+ - if (!can_demote(pgdat->node_id, sc) && - mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH) - return 0; -@@ -3952,7 +3955,7 @@ static void walk_mm(struct lruvec *lruve - } while (err == -EAGAIN); - } - --static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat) -+static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat, bool force_alloc) - { - struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk; - -@@ -3960,7 +3963,7 @@ static struct lru_gen_mm_walk *set_mm_wa - VM_WARN_ON_ONCE(walk); - - walk = &pgdat->mm_walk; -- } else if (!pgdat && !walk) { -+ } else if (!walk && force_alloc) { - VM_WARN_ON_ONCE(current_is_kswapd()); - - walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); -@@ -4146,7 +4149,7 @@ static bool try_to_inc_max_seq(struct lr - goto done; - } - -- walk = set_mm_walk(NULL); -+ walk = set_mm_walk(NULL, true); - if (!walk) { - success = iterate_mm_list_nowalk(lruvec, max_seq); - goto done; -@@ -4215,8 +4218,6 @@ static bool lruvec_is_reclaimable(struct - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MIN_SEQ(lruvec); - -- VM_WARN_ON_ONCE(sc->memcg_low_reclaim); -- - /* see the comment on lru_gen_page */ - gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); - birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); -@@ -4472,12 +4473,8 @@ static bool isolate_page(struct lruvec * - { - bool success; - -- /* unmapping inhibited */ -- if (!sc->may_unmap && page_mapped(page)) -- return false; -- - /* swapping inhibited */ -- if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) && -+ if (!(sc->gfp_mask & __GFP_IO) && - (PageDirty(page) || - (PageAnon(page) && !PageSwapCache(page)))) - return false; -@@ -4574,9 +4571,8 @@ static int scan_pages(struct lruvec *lru - __count_vm_events(PGSCAN_ANON + type, isolated); - - /* -- * There might not be eligible pages due to reclaim_idx, may_unmap and -- * may_writepage. Check the remaining to prevent livelock if it's not -- * making progress. -+ * There might not be eligible pages due to reclaim_idx. Check the -+ * remaining to prevent livelock if it's not making progress. - */ - return isolated || !remaining ? scanned : 0; - } -@@ -4836,8 +4832,7 @@ static long get_nr_to_scan(struct lruvec - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MAX_SEQ(lruvec); - -- if (mem_cgroup_below_min(memcg) || -- (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) -+ if (mem_cgroup_below_min(memcg)) - return 0; - - if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan)) -@@ -4865,17 +4860,14 @@ static bool try_to_shrink_lruvec(struct - long nr_to_scan; - unsigned long scanned = 0; - unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); -+ int swappiness = get_swappiness(lruvec, sc); -+ -+ /* clean file pages are more likely to exist */ -+ if (swappiness && !(sc->gfp_mask & __GFP_IO)) -+ swappiness = 1; - - while (true) { - int delta; -- int swappiness; -- -- if (sc->may_swap) -- swappiness = get_swappiness(lruvec, sc); -- else if (!cgroup_reclaim(sc) && get_swappiness(lruvec, sc)) -- swappiness = 1; -- else -- swappiness = 0; - - nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); - if (nr_to_scan <= 0) -@@ -5005,12 +4997,13 @@ static void lru_gen_shrink_lruvec(struct - struct blk_plug plug; - - VM_WARN_ON_ONCE(global_reclaim(sc)); -+ VM_WARN_ON_ONCE(!sc->may_writepage || !sc->may_unmap); - - lru_add_drain(); - - blk_start_plug(&plug); - -- set_mm_walk(lruvec_pgdat(lruvec)); -+ set_mm_walk(NULL, false); - - if (try_to_shrink_lruvec(lruvec, sc)) - lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG); -@@ -5066,11 +5059,19 @@ static void lru_gen_shrink_node(struct p - - VM_WARN_ON_ONCE(!global_reclaim(sc)); - -+ /* -+ * Unmapped clean pages are already prioritized. Scanning for more of -+ * them is likely futile and can cause high reclaim latency when there -+ * is a large number of memcgs. -+ */ -+ if (!sc->may_writepage || !sc->may_unmap) -+ goto done; -+ - lru_add_drain(); - - blk_start_plug(&plug); - -- set_mm_walk(pgdat); -+ set_mm_walk(pgdat, false); - - set_initial_priority(pgdat, sc); - -@@ -5088,7 +5089,7 @@ static void lru_gen_shrink_node(struct p - clear_mm_walk(); - - blk_finish_plug(&plug); -- -+done: - /* kswapd should never fail */ - pgdat->kswapd_failures = 0; - } -@@ -5656,7 +5657,7 @@ static ssize_t lru_gen_seq_write(struct - set_task_reclaim_state(current, &sc.reclaim_state); - flags = memalloc_noreclaim_save(); - blk_start_plug(&plug); -- if (!set_mm_walk(NULL)) { -+ if (!set_mm_walk(NULL, true)) { - err = -ENOMEM; - goto done; - } diff --git a/target/linux/generic/backport-5.15/020-v6.3-28-mm-multi-gen-LRU-simplify-arch_has_hw_pte_young-chec.patch b/target/linux/generic/backport-5.15/020-v6.3-28-mm-multi-gen-LRU-simplify-arch_has_hw_pte_young-chec.patch deleted file mode 100644 index 38d0e5496ccf92..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-28-mm-multi-gen-LRU-simplify-arch_has_hw_pte_young-chec.patch +++ /dev/null @@ -1,34 +0,0 @@ -From cf3297e4c7a928da8b2b2f0baff2f9c69ea57952 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:06 -0700 -Subject: [PATCH 28/29] mm: multi-gen LRU: simplify arch_has_hw_pte_young() - check - -Scanning page tables when hardware does not set the accessed bit has -no real use cases. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-9-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4144,7 +4144,7 @@ static bool try_to_inc_max_seq(struct lr - * handful of PTEs. Spreading the work out over a period of time usually - * is less efficient, but it avoids bursty page faults. - */ -- if (!force_scan && !(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) { -+ if (!arch_has_hw_pte_young() || !get_cap(LRU_GEN_MM_WALK)) { - success = iterate_mm_list_nowalk(lruvec, max_seq); - goto done; - } diff --git a/target/linux/generic/backport-5.15/020-v6.3-29-mm-multi-gen-LRU-avoid-futile-retries.patch b/target/linux/generic/backport-5.15/020-v6.3-29-mm-multi-gen-LRU-avoid-futile-retries.patch deleted file mode 100644 index 2d19d0d7da1871..00000000000000 --- a/target/linux/generic/backport-5.15/020-v6.3-29-mm-multi-gen-LRU-avoid-futile-retries.patch +++ /dev/null @@ -1,88 +0,0 @@ -From cc67f962cc53f6e1dfa92eb85b7b26fe83a3c66f Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Mon, 13 Feb 2023 00:53:22 -0700 -Subject: [PATCH 29/29] mm: multi-gen LRU: avoid futile retries - -Recall that the per-node memcg LRU has two generations and they alternate -when the last memcg (of a given node) is moved from one to the other. -Each generation is also sharded into multiple bins to improve scalability. -A reclaimer starts with a random bin (in the old generation) and, if it -fails, it will retry, i.e., to try the rest of the bins. - -If a reclaimer fails with the last memcg, it should move this memcg to the -young generation first, which causes the generations to alternate, and -then retry. Otherwise, the retries will be futile because all other bins -are empty. - -Link: https://lkml.kernel.org/r/20230213075322.1416966-1-yuzhao@google.com -Fixes: e4dde56cd208 ("mm: multi-gen LRU: per-node lru_gen_folio lists") -Signed-off-by: Yu Zhao -Reported-by: T.J. Mercier -Signed-off-by: Andrew Morton ---- - mm/vmscan.c | 25 +++++++++++++++---------- - 1 file changed, 15 insertions(+), 10 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4934,18 +4934,20 @@ static int shrink_one(struct lruvec *lru - - static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) - { -+ int op; - int gen; - int bin; - int first_bin; - struct lruvec *lruvec; - struct lru_gen_page *lrugen; -+ struct mem_cgroup *memcg; - const struct hlist_nulls_node *pos; -- int op = 0; -- struct mem_cgroup *memcg = NULL; - unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); - - bin = first_bin = prandom_u32_max(MEMCG_NR_BINS); - restart: -+ op = 0; -+ memcg = NULL; - gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq)); - - rcu_read_lock(); -@@ -4969,14 +4971,22 @@ restart: - - op = shrink_one(lruvec, sc); - -- if (sc->nr_reclaimed >= nr_to_reclaim) -- goto success; -- - rcu_read_lock(); -+ -+ if (sc->nr_reclaimed >= nr_to_reclaim) -+ break; - } - - rcu_read_unlock(); - -+ if (op) -+ lru_gen_rotate_memcg(lruvec, op); -+ -+ mem_cgroup_put(memcg); -+ -+ if (sc->nr_reclaimed >= nr_to_reclaim) -+ return; -+ - /* restart if raced with lru_gen_rotate_memcg() */ - if (gen != get_nulls_value(pos)) - goto restart; -@@ -4985,11 +4995,6 @@ restart: - bin = get_memcg_bin(bin + 1); - if (bin != first_bin) - goto restart; --success: -- if (op) -- lru_gen_rotate_memcg(lruvec, op); -- -- mem_cgroup_put(memcg); - } - - static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) diff --git a/target/linux/generic/backport-5.15/021-v6.4-mm-Multi-gen-LRU-remove-wait_event_killable.patch b/target/linux/generic/backport-5.15/021-v6.4-mm-Multi-gen-LRU-remove-wait_event_killable.patch deleted file mode 100644 index e154494a51e06c..00000000000000 --- a/target/linux/generic/backport-5.15/021-v6.4-mm-Multi-gen-LRU-remove-wait_event_killable.patch +++ /dev/null @@ -1,266 +0,0 @@ -From 087ed25eaf5a78a678508e893f80addab9b1c103 Mon Sep 17 00:00:00 2001 -From: Kalesh Singh -Date: Thu, 13 Apr 2023 14:43:26 -0700 -Subject: [PATCH] mm: Multi-gen LRU: remove wait_event_killable() - -Android 14 and later default to MGLRU [1] and field telemetry showed -occasional long tail latency (>100ms) in the reclaim path. - -Tracing revealed priority inversion in the reclaim path. In -try_to_inc_max_seq(), when high priority tasks were blocked on -wait_event_killable(), the preemption of the low priority task to call -wake_up_all() caused those high priority tasks to wait longer than -necessary. In general, this problem is not different from others of its -kind, e.g., one caused by mutex_lock(). However, it is specific to MGLRU -because it introduced the new wait queue lruvec->mm_state.wait. - -The purpose of this new wait queue is to avoid the thundering herd -problem. If many direct reclaimers rush into try_to_inc_max_seq(), only -one can succeed, i.e., the one to wake up the rest, and the rest who -failed might cause premature OOM kills if they do not wait. So far there -is no evidence supporting this scenario, based on how often the wait has -been hit. And this begs the question how useful the wait queue is in -practice. - -Based on Minchan's recommendation, which is in line with his commit -6d4675e60135 ("mm: don't be stuck to rmap lock on reclaim path") and the -rest of the MGLRU code which also uses trylock when possible, remove the -wait queue. - -[1] https://android-review.googlesource.com/q/I7ed7fbfd6ef9ce10053347528125dd98c39e50bf - -Link: https://lkml.kernel.org/r/20230413214326.2147568-1-kaleshsingh@google.com -Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks") -Change-Id: I911f3968fd1adb25171279cc5b6f48ccb7efc8de -Signed-off-by: Kalesh Singh -Suggested-by: Minchan Kim -Reported-by: Wei Wang -Acked-by: Yu Zhao -Cc: Minchan Kim -Cc: Jan Alexander Steffens (heftig) -Cc: Oleksandr Natalenko -Cc: Suleiman Souhlal -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton ---- - include/linux/mmzone.h | 8 +-- - mm/vmscan.c | 111 +++++++++++++++-------------------------- - 2 files changed, 42 insertions(+), 77 deletions(-) - ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -452,18 +452,14 @@ enum { - struct lru_gen_mm_state { - /* set to max_seq after each iteration */ - unsigned long seq; -- /* where the current iteration continues (inclusive) */ -+ /* where the current iteration continues after */ - struct list_head *head; -- /* where the last iteration ended (exclusive) */ -+ /* where the last iteration ended before */ - struct list_head *tail; -- /* to wait for the last page table walker to finish */ -- struct wait_queue_head wait; - /* Bloom filters flip after each iteration */ - unsigned long *filters[NR_BLOOM_FILTERS]; - /* the mm stats for debugging */ - unsigned long stats[NR_HIST_GENS][NR_MM_STATS]; -- /* the number of concurrent page table walkers */ -- int nr_walkers; - }; - - struct lru_gen_mm_walk { ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -2999,18 +2999,13 @@ void lru_gen_del_mm(struct mm_struct *mm - if (!lruvec) - continue; - -- /* where the last iteration ended (exclusive) */ -+ /* where the current iteration continues after */ -+ if (lruvec->mm_state.head == &mm->lru_gen.list) -+ lruvec->mm_state.head = lruvec->mm_state.head->prev; -+ -+ /* where the last iteration ended before */ - if (lruvec->mm_state.tail == &mm->lru_gen.list) - lruvec->mm_state.tail = lruvec->mm_state.tail->next; -- -- /* where the current iteration continues (inclusive) */ -- if (lruvec->mm_state.head != &mm->lru_gen.list) -- continue; -- -- lruvec->mm_state.head = lruvec->mm_state.head->next; -- /* the deletion ends the current iteration */ -- if (lruvec->mm_state.head == &mm_list->fifo) -- WRITE_ONCE(lruvec->mm_state.seq, lruvec->mm_state.seq + 1); - } - - list_del_init(&mm->lru_gen.list); -@@ -3194,68 +3189,54 @@ static bool iterate_mm_list(struct lruve - struct mm_struct **iter) - { - bool first = false; -- bool last = true; -+ bool last = false; - struct mm_struct *mm = NULL; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - struct lru_gen_mm_list *mm_list = get_mm_list(memcg); - struct lru_gen_mm_state *mm_state = &lruvec->mm_state; - - /* -- * There are four interesting cases for this page table walker: -- * 1. It tries to start a new iteration of mm_list with a stale max_seq; -- * there is nothing left to do. -- * 2. It's the first of the current generation, and it needs to reset -- * the Bloom filter for the next generation. -- * 3. It reaches the end of mm_list, and it needs to increment -- * mm_state->seq; the iteration is done. -- * 4. It's the last of the current generation, and it needs to reset the -- * mm stats counters for the next generation. -+ * mm_state->seq is incremented after each iteration of mm_list. There -+ * are three interesting cases for this page table walker: -+ * 1. It tries to start a new iteration with a stale max_seq: there is -+ * nothing left to do. -+ * 2. It started the next iteration: it needs to reset the Bloom filter -+ * so that a fresh set of PTE tables can be recorded. -+ * 3. It ended the current iteration: it needs to reset the mm stats -+ * counters and tell its caller to increment max_seq. - */ - spin_lock(&mm_list->lock); - - VM_WARN_ON_ONCE(mm_state->seq + 1 < walk->max_seq); -- VM_WARN_ON_ONCE(*iter && mm_state->seq > walk->max_seq); -- VM_WARN_ON_ONCE(*iter && !mm_state->nr_walkers); - -- if (walk->max_seq <= mm_state->seq) { -- if (!*iter) -- last = false; -+ if (walk->max_seq <= mm_state->seq) - goto done; -- } - -- if (!mm_state->nr_walkers) { -- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo); -+ if (!mm_state->head) -+ mm_state->head = &mm_list->fifo; - -- mm_state->head = mm_list->fifo.next; -+ if (mm_state->head == &mm_list->fifo) - first = true; -- } -- -- while (!mm && mm_state->head != &mm_list->fifo) { -- mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list); - -+ do { - mm_state->head = mm_state->head->next; -+ if (mm_state->head == &mm_list->fifo) { -+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1); -+ last = true; -+ break; -+ } - - /* force scan for those added after the last iteration */ -- if (!mm_state->tail || mm_state->tail == &mm->lru_gen.list) { -- mm_state->tail = mm_state->head; -+ if (!mm_state->tail || mm_state->tail == mm_state->head) { -+ mm_state->tail = mm_state->head->next; - walk->force_scan = true; - } - -+ mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list); - if (should_skip_mm(mm, walk)) - mm = NULL; -- } -- -- if (mm_state->head == &mm_list->fifo) -- WRITE_ONCE(mm_state->seq, mm_state->seq + 1); -+ } while (!mm); - done: -- if (*iter && !mm) -- mm_state->nr_walkers--; -- if (!*iter && mm) -- mm_state->nr_walkers++; -- -- if (mm_state->nr_walkers) -- last = false; -- - if (*iter || last) - reset_mm_stats(lruvec, walk, last); - -@@ -3283,9 +3264,9 @@ static bool iterate_mm_list_nowalk(struc - - VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq); - -- if (max_seq > mm_state->seq && !mm_state->nr_walkers) { -- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo); -- -+ if (max_seq > mm_state->seq) { -+ mm_state->head = NULL; -+ mm_state->tail = NULL; - WRITE_ONCE(mm_state->seq, mm_state->seq + 1); - reset_mm_stats(lruvec, NULL, true); - success = true; -@@ -3894,10 +3875,6 @@ restart: - - walk_pmd_range(&val, addr, next, args); - -- /* a racy check to curtail the waiting time */ -- if (wq_has_sleeper(&walk->lruvec->mm_state.wait)) -- return 1; -- - if (need_resched() || walk->batched >= MAX_LRU_BATCH) { - end = (addr | ~PUD_MASK) + 1; - goto done; -@@ -3930,8 +3907,14 @@ static void walk_mm(struct lruvec *lruve - walk->next_addr = FIRST_USER_ADDRESS; - - do { -+ DEFINE_MAX_SEQ(lruvec); -+ - err = -EBUSY; - -+ /* another thread might have called inc_max_seq() */ -+ if (walk->max_seq != max_seq) -+ break; -+ - /* page_update_gen() requires stable page_memcg() */ - if (!mem_cgroup_trylock_pages(memcg)) - break; -@@ -4164,25 +4147,12 @@ static bool try_to_inc_max_seq(struct lr - success = iterate_mm_list(lruvec, walk, &mm); - if (mm) - walk_mm(lruvec, mm, walk); -- -- cond_resched(); - } while (mm); - done: -- if (!success) { -- if (sc->priority <= DEF_PRIORITY - 2) -- wait_event_killable(lruvec->mm_state.wait, -- max_seq < READ_ONCE(lrugen->max_seq)); -- return false; -- } -+ if (success) -+ inc_max_seq(lruvec, can_swap, force_scan); - -- VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq)); -- -- inc_max_seq(lruvec, can_swap, force_scan); -- /* either this sees any waiters or they will see updated max_seq */ -- if (wq_has_sleeper(&lruvec->mm_state.wait)) -- wake_up_all(&lruvec->mm_state.wait); -- -- return true; -+ return success; - } - - static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc) -@@ -5746,7 +5716,6 @@ void lru_gen_init_lruvec(struct lruvec * - INIT_LIST_HEAD(&lrugen->pages[gen][type][zone]); - - lruvec->mm_state.seq = MIN_NR_GENS; -- init_waitqueue_head(&lruvec->mm_state.wait); - } - - #ifdef CONFIG_MEMCG diff --git a/target/linux/generic/backport-5.15/050-v5.16-00-MIPS-uasm-Enable-muhu-opcode-for-MIPS-R6.patch b/target/linux/generic/backport-5.15/050-v5.16-00-MIPS-uasm-Enable-muhu-opcode-for-MIPS-R6.patch deleted file mode 100644 index 82feb7421d5fe0..00000000000000 --- a/target/linux/generic/backport-5.15/050-v5.16-00-MIPS-uasm-Enable-muhu-opcode-for-MIPS-R6.patch +++ /dev/null @@ -1,65 +0,0 @@ -From: Johan Almbladh -Date: Tue, 5 Oct 2021 18:54:02 +0200 -Subject: [PATCH] MIPS: uasm: Enable muhu opcode for MIPS R6 - -Enable the 'muhu' instruction, complementing the existing 'mulu', needed -to implement a MIPS32 BPF JIT. - -Also fix a typo in the existing definition of 'dmulu'. - -Signed-off-by: Tony Ambardar - -This patch is a dependency for my 32-bit MIPS eBPF JIT. - -Signed-off-by: Johan Almbladh ---- - ---- a/arch/mips/include/asm/uasm.h -+++ b/arch/mips/include/asm/uasm.h -@@ -145,6 +145,7 @@ Ip_u1(_mtlo); - Ip_u3u1u2(_mul); - Ip_u1u2(_multu); - Ip_u3u1u2(_mulu); -+Ip_u3u1u2(_muhu); - Ip_u3u1u2(_nor); - Ip_u3u1u2(_or); - Ip_u2u1u3(_ori); ---- a/arch/mips/mm/uasm-mips.c -+++ b/arch/mips/mm/uasm-mips.c -@@ -90,7 +90,7 @@ static const struct insn insn_table[insn - RS | RT | RD}, - [insn_dmtc0] = {M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET}, - [insn_dmultu] = {M(spec_op, 0, 0, 0, 0, dmultu_op), RS | RT}, -- [insn_dmulu] = {M(spec_op, 0, 0, 0, dmult_dmul_op, dmultu_op), -+ [insn_dmulu] = {M(spec_op, 0, 0, 0, dmultu_dmulu_op, dmultu_op), - RS | RT | RD}, - [insn_drotr] = {M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE}, - [insn_drotr32] = {M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE}, -@@ -150,6 +150,8 @@ static const struct insn insn_table[insn - [insn_mtlo] = {M(spec_op, 0, 0, 0, 0, mtlo_op), RS}, - [insn_mulu] = {M(spec_op, 0, 0, 0, multu_mulu_op, multu_op), - RS | RT | RD}, -+ [insn_muhu] = {M(spec_op, 0, 0, 0, multu_muhu_op, multu_op), -+ RS | RT | RD}, - #ifndef CONFIG_CPU_MIPSR6 - [insn_mul] = {M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD}, - #else ---- a/arch/mips/mm/uasm.c -+++ b/arch/mips/mm/uasm.c -@@ -59,7 +59,7 @@ enum opcode { - insn_lddir, insn_ldpte, insn_ldx, insn_lh, insn_lhu, insn_ll, insn_lld, - insn_lui, insn_lw, insn_lwu, insn_lwx, insn_mfc0, insn_mfhc0, insn_mfhi, - insn_mflo, insn_modu, insn_movn, insn_movz, insn_mtc0, insn_mthc0, -- insn_mthi, insn_mtlo, insn_mul, insn_multu, insn_mulu, insn_nor, -+ insn_mthi, insn_mtlo, insn_mul, insn_multu, insn_mulu, insn_muhu, insn_nor, - insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sb, insn_sc, - insn_scd, insn_seleqz, insn_selnez, insn_sd, insn_sh, insn_sll, - insn_sllv, insn_slt, insn_slti, insn_sltiu, insn_sltu, insn_sra, -@@ -344,6 +344,7 @@ I_u1(_mtlo) - I_u3u1u2(_mul) - I_u1u2(_multu) - I_u3u1u2(_mulu) -+I_u3u1u2(_muhu) - I_u3u1u2(_nor) - I_u3u1u2(_or) - I_u2u1u3(_ori) diff --git a/target/linux/generic/backport-5.15/050-v5.16-01-mips-uasm-Add-workaround-for-Loongson-2F-nop-CPU-err.patch b/target/linux/generic/backport-5.15/050-v5.16-01-mips-uasm-Add-workaround-for-Loongson-2F-nop-CPU-err.patch deleted file mode 100644 index 3a4d573f80af28..00000000000000 --- a/target/linux/generic/backport-5.15/050-v5.16-01-mips-uasm-Add-workaround-for-Loongson-2F-nop-CPU-err.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Johan Almbladh -Date: Tue, 5 Oct 2021 18:54:03 +0200 -Subject: [PATCH] mips: uasm: Add workaround for Loongson-2F nop CPU errata - -This patch implements a workaround for the Loongson-2F nop in generated, -code, if the existing option CONFIG_CPU_NOP_WORKAROUND is set. Before, -the binutils option -mfix-loongson2f-nop was enabled, but no workaround -was done when emitting MIPS code. Now, the nop pseudo instruction is -emitted as "or ax,ax,zero" instead of the default "sll zero,zero,0". This -is consistent with the workaround implemented by binutils. - -Link: https://sourceware.org/legacy-ml/binutils/2009-11/msg00387.html - -Signed-off-by: Johan Almbladh -Reviewed-by: Jiaxun Yang ---- - ---- a/arch/mips/include/asm/uasm.h -+++ b/arch/mips/include/asm/uasm.h -@@ -249,7 +249,11 @@ static inline void uasm_l##lb(struct uas - #define uasm_i_bnezl(buf, rs, off) uasm_i_bnel(buf, rs, 0, off) - #define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3) - #define uasm_i_move(buf, a, b) UASM_i_ADDU(buf, a, 0, b) -+#ifdef CONFIG_CPU_NOP_WORKAROUNDS -+#define uasm_i_nop(buf) uasm_i_or(buf, 1, 1, 0) -+#else - #define uasm_i_nop(buf) uasm_i_sll(buf, 0, 0, 0) -+#endif - #define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1) - - static inline void uasm_i_drotr_safe(u32 **p, unsigned int a1, diff --git a/target/linux/generic/backport-5.15/050-v5.16-02-mips-bpf-Add-eBPF-JIT-for-32-bit-MIPS.patch b/target/linux/generic/backport-5.15/050-v5.16-02-mips-bpf-Add-eBPF-JIT-for-32-bit-MIPS.patch deleted file mode 100644 index 7980659961244f..00000000000000 --- a/target/linux/generic/backport-5.15/050-v5.16-02-mips-bpf-Add-eBPF-JIT-for-32-bit-MIPS.patch +++ /dev/null @@ -1,3078 +0,0 @@ -From: Johan Almbladh -Date: Tue, 5 Oct 2021 18:54:04 +0200 -Subject: [PATCH] mips: bpf: Add eBPF JIT for 32-bit MIPS - -This is an implementation of an eBPF JIT for 32-bit MIPS I-V and MIPS32. -The implementation supports all 32-bit and 64-bit ALU and JMP operations, -including the recently-added atomics. 64-bit div/mod and 64-bit atomics -are implemented using function calls to math64 and atomic64 functions, -respectively. All 32-bit operations are implemented natively by the JIT, -except if the CPU lacks ll/sc instructions. - -Register mapping -================ -All 64-bit eBPF registers are mapped to native 32-bit MIPS register pairs, -and does not use any stack scratch space for register swapping. This means -that all eBPF register data is kept in CPU registers all the time, and -this simplifies the register management a lot. It also reduces the JIT's -pressure on temporary registers since we do not have to move data around. - -Native register pairs are ordered according to CPU endiannes, following -the O32 calling convention for passing 64-bit arguments and return values. -The eBPF return value, arguments and callee-saved registers are mapped to -their native MIPS equivalents. - -Since the 32 highest bits in the eBPF FP (frame pointer) register are -always zero, only one general-purpose register is actually needed for the -mapping. The MIPS fp register is used for this purpose. The high bits are -mapped to MIPS register r0. This saves us one CPU register, which is much -needed for temporaries, while still allowing us to treat the R10 (FP) -register just like any other eBPF register in the JIT. - -The MIPS gp (global pointer) and at (assembler temporary) registers are -used as internal temporary registers for constant blinding. CPU registers -t6-t9 are used internally by the JIT when constructing more complex 64-bit -operations. This is precisely what is needed - two registers to store an -operand value, and two more as scratch registers when performing the -operation. - -The register mapping is shown below. - - R0 - $v1, $v0 return value - R1 - $a1, $a0 argument 1, passed in registers - R2 - $a3, $a2 argument 2, passed in registers - R3 - $t1, $t0 argument 3, passed on stack - R4 - $t3, $t2 argument 4, passed on stack - R5 - $t4, $t3 argument 5, passed on stack - R6 - $s1, $s0 callee-saved - R7 - $s3, $s2 callee-saved - R8 - $s5, $s4 callee-saved - R9 - $s7, $s6 callee-saved - FP - $r0, $fp 32-bit frame pointer - AX - $gp, $at constant-blinding - $t6 - $t9 unallocated, JIT temporaries - -Jump offsets -============ -The JIT tries to map all conditional JMP operations to MIPS conditional -PC-relative branches. The MIPS branch offset field is 18 bits, in bytes, -which is equivalent to the eBPF 16-bit instruction offset. However, since -the JIT may emit more than one CPU instruction per eBPF instruction, the -field width may overflow. If that happens, the JIT converts the long -conditional jump to a short PC-relative branch with the condition -inverted, jumping over a long unconditional absolute jmp (j). - -This conversion will change the instruction offset mapping used for jumps, -and may in turn result in more branch offset overflows. The JIT therefore -dry-runs the translation until no more branches are converted and the -offsets do not change anymore. There is an upper bound on this of course, -and if the JIT hits that limit, the last two iterations are run with all -branches being converted. - -Tail call count -=============== -The current tail call count is stored in the 16-byte area of the caller's -stack frame that is reserved for the callee in the o32 ABI. The value is -initialized in the prologue, and propagated to the tail-callee by skipping -the initialization instructions when emitting the tail call. - -Signed-off-by: Johan Almbladh ---- - create mode 100644 arch/mips/net/bpf_jit_comp.c - create mode 100644 arch/mips/net/bpf_jit_comp.h - create mode 100644 arch/mips/net/bpf_jit_comp32.c - ---- a/arch/mips/net/Makefile -+++ b/arch/mips/net/Makefile -@@ -2,4 +2,9 @@ - # MIPS networking code - - obj-$(CONFIG_MIPS_CBPF_JIT) += bpf_jit.o bpf_jit_asm.o --obj-$(CONFIG_MIPS_EBPF_JIT) += ebpf_jit.o -+ -+ifeq ($(CONFIG_32BIT),y) -+ obj-$(CONFIG_MIPS_EBPF_JIT) += bpf_jit_comp.o bpf_jit_comp32.o -+else -+ obj-$(CONFIG_MIPS_EBPF_JIT) += ebpf_jit.o -+endif ---- /dev/null -+++ b/arch/mips/net/bpf_jit_comp.c -@@ -0,0 +1,1020 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Just-In-Time compiler for eBPF bytecode on MIPS. -+ * Implementation of JIT functions common to 32-bit and 64-bit CPUs. -+ * -+ * Copyright (c) 2021 Anyfi Networks AB. -+ * Author: Johan Almbladh -+ * -+ * Based on code and ideas from -+ * Copyright (c) 2017 Cavium, Inc. -+ * Copyright (c) 2017 Shubham Bansal -+ * Copyright (c) 2011 Mircea Gherzan -+ */ -+ -+/* -+ * Code overview -+ * ============= -+ * -+ * - bpf_jit_comp.h -+ * Common definitions and utilities. -+ * -+ * - bpf_jit_comp.c -+ * Implementation of JIT top-level logic and exported JIT API functions. -+ * Implementation of internal operations shared by 32-bit and 64-bit code. -+ * JMP and ALU JIT control code, register control code, shared ALU and -+ * JMP/JMP32 JIT operations. -+ * -+ * - bpf_jit_comp32.c -+ * Implementation of functions to JIT prologue, epilogue and a single eBPF -+ * instruction for 32-bit MIPS CPUs. The functions use shared operations -+ * where possible, and implement the rest for 32-bit MIPS such as ALU64 -+ * operations. -+ * -+ * - bpf_jit_comp64.c -+ * Ditto, for 64-bit MIPS CPUs. -+ * -+ * Zero and sign extension -+ * ======================== -+ * 32-bit MIPS instructions on 64-bit MIPS registers use sign extension, -+ * but the eBPF instruction set mandates zero extension. We let the verifier -+ * insert explicit zero-extensions after 32-bit ALU operations, both for -+ * 32-bit and 64-bit MIPS JITs. Conditional JMP32 operations on 64-bit MIPs -+ * are JITed with sign extensions inserted when so expected. -+ * -+ * ALU operations -+ * ============== -+ * ALU operations on 32/64-bit MIPS and ALU64 operations on 64-bit MIPS are -+ * JITed in the following steps. ALU64 operations on 32-bit MIPS are more -+ * complicated and therefore only processed by special implementations in -+ * step (3). -+ * -+ * 1) valid_alu_i: -+ * Determine if an immediate operation can be emitted as such, or if -+ * we must fall back to the register version. -+ * -+ * 2) rewrite_alu_i: -+ * Convert BPF operation and immediate value to a canonical form for -+ * JITing. In some degenerate cases this form may be a no-op. -+ * -+ * 3) emit_alu_{i,i64,r,64}: -+ * Emit instructions for an ALU or ALU64 immediate or register operation. -+ * -+ * JMP operations -+ * ============== -+ * JMP and JMP32 operations require an JIT instruction offset table for -+ * translating the jump offset. This table is computed by dry-running the -+ * JIT without actually emitting anything. However, the computed PC-relative -+ * offset may overflow the 18-bit offset field width of the native MIPS -+ * branch instruction. In such cases, the long jump is converted into the -+ * following sequence. -+ * -+ * ! +2 Inverted PC-relative branch -+ * nop Delay slot -+ * j Unconditional absolute long jump -+ * nop Delay slot -+ * -+ * Since this converted sequence alters the offset table, all offsets must -+ * be re-calculated. This may in turn trigger new branch conversions, so -+ * the process is repeated until no further changes are made. Normally it -+ * completes in 1-2 iterations. If JIT_MAX_ITERATIONS should reached, we -+ * fall back to converting every remaining jump operation. The branch -+ * conversion is independent of how the JMP or JMP32 condition is JITed. -+ * -+ * JMP32 and JMP operations are JITed as follows. -+ * -+ * 1) setup_jmp_{i,r}: -+ * Convert jump conditional and offset into a form that can be JITed. -+ * This form may be a no-op, a canonical form, or an inverted PC-relative -+ * jump if branch conversion is necessary. -+ * -+ * 2) valid_jmp_i: -+ * Determine if an immediate operations can be emitted as such, or if -+ * we must fall back to the register version. Applies to JMP32 for 32-bit -+ * MIPS, and both JMP and JMP32 for 64-bit MIPS. -+ * -+ * 3) emit_jmp_{i,i64,r,r64}: -+ * Emit instructions for an JMP or JMP32 immediate or register operation. -+ * -+ * 4) finish_jmp_{i,r}: -+ * Emit any instructions needed to finish the jump. This includes a nop -+ * for the delay slot if a branch was emitted, and a long absolute jump -+ * if the branch was converted. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "bpf_jit_comp.h" -+ -+/* Convenience macros for descriptor access */ -+#define CONVERTED(desc) ((desc) & JIT_DESC_CONVERT) -+#define INDEX(desc) ((desc) & ~JIT_DESC_CONVERT) -+ -+/* -+ * Push registers on the stack, starting at a given depth from the stack -+ * pointer and increasing. The next depth to be written is returned. -+ */ -+int push_regs(struct jit_context *ctx, u32 mask, u32 excl, int depth) -+{ -+ int reg; -+ -+ for (reg = 0; reg < BITS_PER_BYTE * sizeof(mask); reg++) -+ if (mask & BIT(reg)) { -+ if ((excl & BIT(reg)) == 0) { -+ if (sizeof(long) == 4) -+ emit(ctx, sw, reg, depth, MIPS_R_SP); -+ else /* sizeof(long) == 8 */ -+ emit(ctx, sd, reg, depth, MIPS_R_SP); -+ } -+ depth += sizeof(long); -+ } -+ -+ ctx->stack_used = max((int)ctx->stack_used, depth); -+ return depth; -+} -+ -+/* -+ * Pop registers from the stack, starting at a given depth from the stack -+ * pointer and increasing. The next depth to be read is returned. -+ */ -+int pop_regs(struct jit_context *ctx, u32 mask, u32 excl, int depth) -+{ -+ int reg; -+ -+ for (reg = 0; reg < BITS_PER_BYTE * sizeof(mask); reg++) -+ if (mask & BIT(reg)) { -+ if ((excl & BIT(reg)) == 0) { -+ if (sizeof(long) == 4) -+ emit(ctx, lw, reg, depth, MIPS_R_SP); -+ else /* sizeof(long) == 8 */ -+ emit(ctx, ld, reg, depth, MIPS_R_SP); -+ } -+ depth += sizeof(long); -+ } -+ -+ return depth; -+} -+ -+/* Compute the 28-bit jump target address from a BPF program location */ -+int get_target(struct jit_context *ctx, u32 loc) -+{ -+ u32 index = INDEX(ctx->descriptors[loc]); -+ unsigned long pc = (unsigned long)&ctx->target[ctx->jit_index]; -+ unsigned long addr = (unsigned long)&ctx->target[index]; -+ -+ if (!ctx->target) -+ return 0; -+ -+ if ((addr ^ pc) & ~MIPS_JMP_MASK) -+ return -1; -+ -+ return addr & MIPS_JMP_MASK; -+} -+ -+/* Compute the PC-relative offset to relative BPF program offset */ -+int get_offset(const struct jit_context *ctx, int off) -+{ -+ return (INDEX(ctx->descriptors[ctx->bpf_index + off]) - -+ ctx->jit_index - 1) * sizeof(u32); -+} -+ -+/* dst = imm (register width) */ -+void emit_mov_i(struct jit_context *ctx, u8 dst, s32 imm) -+{ -+ if (imm >= -0x8000 && imm <= 0x7fff) { -+ emit(ctx, addiu, dst, MIPS_R_ZERO, imm); -+ } else { -+ emit(ctx, lui, dst, (s16)((u32)imm >> 16)); -+ emit(ctx, ori, dst, dst, (u16)(imm & 0xffff)); -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* dst = src (register width) */ -+void emit_mov_r(struct jit_context *ctx, u8 dst, u8 src) -+{ -+ emit(ctx, ori, dst, src, 0); -+ clobber_reg(ctx, dst); -+} -+ -+/* Validate ALU immediate range */ -+bool valid_alu_i(u8 op, s32 imm) -+{ -+ switch (BPF_OP(op)) { -+ case BPF_NEG: -+ case BPF_LSH: -+ case BPF_RSH: -+ case BPF_ARSH: -+ /* All legal eBPF values are valid */ -+ return true; -+ case BPF_ADD: -+ /* imm must be 16 bits */ -+ return imm >= -0x8000 && imm <= 0x7fff; -+ case BPF_SUB: -+ /* -imm must be 16 bits */ -+ return imm >= -0x7fff && imm <= 0x8000; -+ case BPF_AND: -+ case BPF_OR: -+ case BPF_XOR: -+ /* imm must be 16 bits unsigned */ -+ return imm >= 0 && imm <= 0xffff; -+ case BPF_MUL: -+ /* imm must be zero or a positive power of two */ -+ return imm == 0 || (imm > 0 && is_power_of_2(imm)); -+ case BPF_DIV: -+ case BPF_MOD: -+ /* imm must be an 17-bit power of two */ -+ return (u32)imm <= 0x10000 && is_power_of_2((u32)imm); -+ } -+ return false; -+} -+ -+/* Rewrite ALU immediate operation */ -+bool rewrite_alu_i(u8 op, s32 imm, u8 *alu, s32 *val) -+{ -+ bool act = true; -+ -+ switch (BPF_OP(op)) { -+ case BPF_LSH: -+ case BPF_RSH: -+ case BPF_ARSH: -+ case BPF_ADD: -+ case BPF_SUB: -+ case BPF_OR: -+ case BPF_XOR: -+ /* imm == 0 is a no-op */ -+ act = imm != 0; -+ break; -+ case BPF_MUL: -+ if (imm == 1) { -+ /* dst * 1 is a no-op */ -+ act = false; -+ } else if (imm == 0) { -+ /* dst * 0 is dst & 0 */ -+ op = BPF_AND; -+ } else { -+ /* dst * (1 << n) is dst << n */ -+ op = BPF_LSH; -+ imm = ilog2(abs(imm)); -+ } -+ break; -+ case BPF_DIV: -+ if (imm == 1) { -+ /* dst / 1 is a no-op */ -+ act = false; -+ } else { -+ /* dst / (1 << n) is dst >> n */ -+ op = BPF_RSH; -+ imm = ilog2(imm); -+ } -+ break; -+ case BPF_MOD: -+ /* dst % (1 << n) is dst & ((1 << n) - 1) */ -+ op = BPF_AND; -+ imm--; -+ break; -+ } -+ -+ *alu = op; -+ *val = imm; -+ return act; -+} -+ -+/* ALU immediate operation (32-bit) */ -+void emit_alu_i(struct jit_context *ctx, u8 dst, s32 imm, u8 op) -+{ -+ switch (BPF_OP(op)) { -+ /* dst = -dst */ -+ case BPF_NEG: -+ emit(ctx, subu, dst, MIPS_R_ZERO, dst); -+ break; -+ /* dst = dst & imm */ -+ case BPF_AND: -+ emit(ctx, andi, dst, dst, (u16)imm); -+ break; -+ /* dst = dst | imm */ -+ case BPF_OR: -+ emit(ctx, ori, dst, dst, (u16)imm); -+ break; -+ /* dst = dst ^ imm */ -+ case BPF_XOR: -+ emit(ctx, xori, dst, dst, (u16)imm); -+ break; -+ /* dst = dst << imm */ -+ case BPF_LSH: -+ emit(ctx, sll, dst, dst, imm); -+ break; -+ /* dst = dst >> imm */ -+ case BPF_RSH: -+ emit(ctx, srl, dst, dst, imm); -+ break; -+ /* dst = dst >> imm (arithmetic) */ -+ case BPF_ARSH: -+ emit(ctx, sra, dst, dst, imm); -+ break; -+ /* dst = dst + imm */ -+ case BPF_ADD: -+ emit(ctx, addiu, dst, dst, imm); -+ break; -+ /* dst = dst - imm */ -+ case BPF_SUB: -+ emit(ctx, addiu, dst, dst, -imm); -+ break; -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* ALU register operation (32-bit) */ -+void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op) -+{ -+ switch (BPF_OP(op)) { -+ /* dst = dst & src */ -+ case BPF_AND: -+ emit(ctx, and, dst, dst, src); -+ break; -+ /* dst = dst | src */ -+ case BPF_OR: -+ emit(ctx, or, dst, dst, src); -+ break; -+ /* dst = dst ^ src */ -+ case BPF_XOR: -+ emit(ctx, xor, dst, dst, src); -+ break; -+ /* dst = dst << src */ -+ case BPF_LSH: -+ emit(ctx, sllv, dst, dst, src); -+ break; -+ /* dst = dst >> src */ -+ case BPF_RSH: -+ emit(ctx, srlv, dst, dst, src); -+ break; -+ /* dst = dst >> src (arithmetic) */ -+ case BPF_ARSH: -+ emit(ctx, srav, dst, dst, src); -+ break; -+ /* dst = dst + src */ -+ case BPF_ADD: -+ emit(ctx, addu, dst, dst, src); -+ break; -+ /* dst = dst - src */ -+ case BPF_SUB: -+ emit(ctx, subu, dst, dst, src); -+ break; -+ /* dst = dst * src */ -+ case BPF_MUL: -+ if (cpu_has_mips32r1 || cpu_has_mips32r6) { -+ emit(ctx, mul, dst, dst, src); -+ } else { -+ emit(ctx, multu, dst, src); -+ emit(ctx, mflo, dst); -+ } -+ break; -+ /* dst = dst / src */ -+ case BPF_DIV: -+ if (cpu_has_mips32r6) { -+ emit(ctx, divu_r6, dst, dst, src); -+ } else { -+ emit(ctx, divu, dst, src); -+ emit(ctx, mflo, dst); -+ } -+ break; -+ /* dst = dst % src */ -+ case BPF_MOD: -+ if (cpu_has_mips32r6) { -+ emit(ctx, modu, dst, dst, src); -+ } else { -+ emit(ctx, divu, dst, src); -+ emit(ctx, mfhi, dst); -+ } -+ break; -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* Atomic read-modify-write (32-bit) */ -+void emit_atomic_r(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 code) -+{ -+ emit(ctx, ll, MIPS_R_T9, off, dst); -+ switch (code) { -+ case BPF_ADD: -+ emit(ctx, addu, MIPS_R_T8, MIPS_R_T9, src); -+ break; -+ case BPF_AND: -+ emit(ctx, and, MIPS_R_T8, MIPS_R_T9, src); -+ break; -+ case BPF_OR: -+ emit(ctx, or, MIPS_R_T8, MIPS_R_T9, src); -+ break; -+ case BPF_XOR: -+ emit(ctx, xor, MIPS_R_T8, MIPS_R_T9, src); -+ break; -+ } -+ emit(ctx, sc, MIPS_R_T8, off, dst); -+ emit(ctx, beqz, MIPS_R_T8, -16); -+ emit(ctx, nop); /* Delay slot */ -+} -+ -+/* Atomic compare-and-exchange (32-bit) */ -+void emit_cmpxchg_r(struct jit_context *ctx, u8 dst, u8 src, u8 res, s16 off) -+{ -+ emit(ctx, ll, MIPS_R_T9, off, dst); -+ emit(ctx, bne, MIPS_R_T9, res, 12); -+ emit(ctx, move, MIPS_R_T8, src); /* Delay slot */ -+ emit(ctx, sc, MIPS_R_T8, off, dst); -+ emit(ctx, beqz, MIPS_R_T8, -20); -+ emit(ctx, move, res, MIPS_R_T9); /* Delay slot */ -+ clobber_reg(ctx, res); -+} -+ -+/* Swap bytes and truncate a register word or half word */ -+void emit_bswap_r(struct jit_context *ctx, u8 dst, u32 width) -+{ -+ u8 tmp = MIPS_R_T8; -+ u8 msk = MIPS_R_T9; -+ -+ switch (width) { -+ /* Swap bytes in a word */ -+ case 32: -+ if (cpu_has_mips32r2 || cpu_has_mips32r6) { -+ emit(ctx, wsbh, dst, dst); -+ emit(ctx, rotr, dst, dst, 16); -+ } else { -+ emit(ctx, sll, tmp, dst, 16); /* tmp = dst << 16 */ -+ emit(ctx, srl, dst, dst, 16); /* dst = dst >> 16 */ -+ emit(ctx, or, dst, dst, tmp); /* dst = dst | tmp */ -+ -+ emit(ctx, lui, msk, 0xff); /* msk = 0x00ff0000 */ -+ emit(ctx, ori, msk, msk, 0xff); /* msk = msk | 0xff */ -+ -+ emit(ctx, and, tmp, dst, msk); /* tmp = dst & msk */ -+ emit(ctx, sll, tmp, tmp, 8); /* tmp = tmp << 8 */ -+ emit(ctx, srl, dst, dst, 8); /* dst = dst >> 8 */ -+ emit(ctx, and, dst, dst, msk); /* dst = dst & msk */ -+ emit(ctx, or, dst, dst, tmp); /* reg = dst | tmp */ -+ } -+ break; -+ /* Swap bytes in a half word */ -+ case 16: -+ if (cpu_has_mips32r2 || cpu_has_mips32r6) { -+ emit(ctx, wsbh, dst, dst); -+ emit(ctx, andi, dst, dst, 0xffff); -+ } else { -+ emit(ctx, andi, tmp, dst, 0xff00); /* t = d & 0xff00 */ -+ emit(ctx, srl, tmp, tmp, 8); /* t = t >> 8 */ -+ emit(ctx, andi, dst, dst, 0x00ff); /* d = d & 0x00ff */ -+ emit(ctx, sll, dst, dst, 8); /* d = d << 8 */ -+ emit(ctx, or, dst, dst, tmp); /* d = d | t */ -+ } -+ break; -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* Validate jump immediate range */ -+bool valid_jmp_i(u8 op, s32 imm) -+{ -+ switch (op) { -+ case JIT_JNOP: -+ /* Immediate value not used */ -+ return true; -+ case BPF_JEQ: -+ case BPF_JNE: -+ /* No immediate operation */ -+ return false; -+ case BPF_JSET: -+ case JIT_JNSET: -+ /* imm must be 16 bits unsigned */ -+ return imm >= 0 && imm <= 0xffff; -+ case BPF_JGE: -+ case BPF_JLT: -+ case BPF_JSGE: -+ case BPF_JSLT: -+ /* imm must be 16 bits */ -+ return imm >= -0x8000 && imm <= 0x7fff; -+ case BPF_JGT: -+ case BPF_JLE: -+ case BPF_JSGT: -+ case BPF_JSLE: -+ /* imm + 1 must be 16 bits */ -+ return imm >= -0x8001 && imm <= 0x7ffe; -+ } -+ return false; -+} -+ -+/* Invert a conditional jump operation */ -+static u8 invert_jmp(u8 op) -+{ -+ switch (op) { -+ case BPF_JA: return JIT_JNOP; -+ case BPF_JEQ: return BPF_JNE; -+ case BPF_JNE: return BPF_JEQ; -+ case BPF_JSET: return JIT_JNSET; -+ case BPF_JGT: return BPF_JLE; -+ case BPF_JGE: return BPF_JLT; -+ case BPF_JLT: return BPF_JGE; -+ case BPF_JLE: return BPF_JGT; -+ case BPF_JSGT: return BPF_JSLE; -+ case BPF_JSGE: return BPF_JSLT; -+ case BPF_JSLT: return BPF_JSGE; -+ case BPF_JSLE: return BPF_JSGT; -+ } -+ return 0; -+} -+ -+/* Prepare a PC-relative jump operation */ -+static void setup_jmp(struct jit_context *ctx, u8 bpf_op, -+ s16 bpf_off, u8 *jit_op, s32 *jit_off) -+{ -+ u32 *descp = &ctx->descriptors[ctx->bpf_index]; -+ int op = bpf_op; -+ int offset = 0; -+ -+ /* Do not compute offsets on the first pass */ -+ if (INDEX(*descp) == 0) -+ goto done; -+ -+ /* Skip jumps never taken */ -+ if (bpf_op == JIT_JNOP) -+ goto done; -+ -+ /* Convert jumps always taken */ -+ if (bpf_op == BPF_JA) -+ *descp |= JIT_DESC_CONVERT; -+ -+ /* -+ * Current ctx->jit_index points to the start of the branch preamble. -+ * Since the preamble differs among different branch conditionals, -+ * the current index cannot be used to compute the branch offset. -+ * Instead, we use the offset table value for the next instruction, -+ * which gives the index immediately after the branch delay slot. -+ */ -+ if (!CONVERTED(*descp)) { -+ int target = ctx->bpf_index + bpf_off + 1; -+ int origin = ctx->bpf_index + 1; -+ -+ offset = (INDEX(ctx->descriptors[target]) - -+ INDEX(ctx->descriptors[origin]) + 1) * sizeof(u32); -+ } -+ -+ /* -+ * The PC-relative branch offset field on MIPS is 18 bits signed, -+ * so if the computed offset is larger than this we generate a an -+ * absolute jump that we skip with an inverted conditional branch. -+ */ -+ if (CONVERTED(*descp) || offset < -0x20000 || offset > 0x1ffff) { -+ offset = 3 * sizeof(u32); -+ op = invert_jmp(bpf_op); -+ ctx->changes += !CONVERTED(*descp); -+ *descp |= JIT_DESC_CONVERT; -+ } -+ -+done: -+ *jit_off = offset; -+ *jit_op = op; -+} -+ -+/* Prepare a PC-relative jump operation with immediate conditional */ -+void setup_jmp_i(struct jit_context *ctx, s32 imm, u8 width, -+ u8 bpf_op, s16 bpf_off, u8 *jit_op, s32 *jit_off) -+{ -+ bool always = false; -+ bool never = false; -+ -+ switch (bpf_op) { -+ case BPF_JEQ: -+ case BPF_JNE: -+ break; -+ case BPF_JSET: -+ case BPF_JLT: -+ never = imm == 0; -+ break; -+ case BPF_JGE: -+ always = imm == 0; -+ break; -+ case BPF_JGT: -+ never = (u32)imm == U32_MAX; -+ break; -+ case BPF_JLE: -+ always = (u32)imm == U32_MAX; -+ break; -+ case BPF_JSGT: -+ never = imm == S32_MAX && width == 32; -+ break; -+ case BPF_JSGE: -+ always = imm == S32_MIN && width == 32; -+ break; -+ case BPF_JSLT: -+ never = imm == S32_MIN && width == 32; -+ break; -+ case BPF_JSLE: -+ always = imm == S32_MAX && width == 32; -+ break; -+ } -+ -+ if (never) -+ bpf_op = JIT_JNOP; -+ if (always) -+ bpf_op = BPF_JA; -+ setup_jmp(ctx, bpf_op, bpf_off, jit_op, jit_off); -+} -+ -+/* Prepare a PC-relative jump operation with register conditional */ -+void setup_jmp_r(struct jit_context *ctx, bool same_reg, -+ u8 bpf_op, s16 bpf_off, u8 *jit_op, s32 *jit_off) -+{ -+ switch (bpf_op) { -+ case BPF_JSET: -+ break; -+ case BPF_JEQ: -+ case BPF_JGE: -+ case BPF_JLE: -+ case BPF_JSGE: -+ case BPF_JSLE: -+ if (same_reg) -+ bpf_op = BPF_JA; -+ break; -+ case BPF_JNE: -+ case BPF_JLT: -+ case BPF_JGT: -+ case BPF_JSGT: -+ case BPF_JSLT: -+ if (same_reg) -+ bpf_op = JIT_JNOP; -+ break; -+ } -+ setup_jmp(ctx, bpf_op, bpf_off, jit_op, jit_off); -+} -+ -+/* Finish a PC-relative jump operation */ -+int finish_jmp(struct jit_context *ctx, u8 jit_op, s16 bpf_off) -+{ -+ /* Emit conditional branch delay slot */ -+ if (jit_op != JIT_JNOP) -+ emit(ctx, nop); -+ /* -+ * Emit an absolute long jump with delay slot, -+ * if the PC-relative branch was converted. -+ */ -+ if (CONVERTED(ctx->descriptors[ctx->bpf_index])) { -+ int target = get_target(ctx, ctx->bpf_index + bpf_off + 1); -+ -+ if (target < 0) -+ return -1; -+ emit(ctx, j, target); -+ emit(ctx, nop); -+ } -+ return 0; -+} -+ -+/* Jump immediate (32-bit) */ -+void emit_jmp_i(struct jit_context *ctx, u8 dst, s32 imm, s32 off, u8 op) -+{ -+ switch (op) { -+ /* No-op, used internally for branch optimization */ -+ case JIT_JNOP: -+ break; -+ /* PC += off if dst & imm */ -+ case BPF_JSET: -+ emit(ctx, andi, MIPS_R_T9, dst, (u16)imm); -+ emit(ctx, bnez, MIPS_R_T9, off); -+ break; -+ /* PC += off if (dst & imm) == 0 (not in BPF, used for long jumps) */ -+ case JIT_JNSET: -+ emit(ctx, andi, MIPS_R_T9, dst, (u16)imm); -+ emit(ctx, beqz, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst > imm */ -+ case BPF_JGT: -+ emit(ctx, sltiu, MIPS_R_T9, dst, imm + 1); -+ emit(ctx, beqz, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst >= imm */ -+ case BPF_JGE: -+ emit(ctx, sltiu, MIPS_R_T9, dst, imm); -+ emit(ctx, beqz, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst < imm */ -+ case BPF_JLT: -+ emit(ctx, sltiu, MIPS_R_T9, dst, imm); -+ emit(ctx, bnez, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst <= imm */ -+ case BPF_JLE: -+ emit(ctx, sltiu, MIPS_R_T9, dst, imm + 1); -+ emit(ctx, bnez, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst > imm (signed) */ -+ case BPF_JSGT: -+ emit(ctx, slti, MIPS_R_T9, dst, imm + 1); -+ emit(ctx, beqz, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst >= imm (signed) */ -+ case BPF_JSGE: -+ emit(ctx, slti, MIPS_R_T9, dst, imm); -+ emit(ctx, beqz, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst < imm (signed) */ -+ case BPF_JSLT: -+ emit(ctx, slti, MIPS_R_T9, dst, imm); -+ emit(ctx, bnez, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst <= imm (signed) */ -+ case BPF_JSLE: -+ emit(ctx, slti, MIPS_R_T9, dst, imm + 1); -+ emit(ctx, bnez, MIPS_R_T9, off); -+ break; -+ } -+} -+ -+/* Jump register (32-bit) */ -+void emit_jmp_r(struct jit_context *ctx, u8 dst, u8 src, s32 off, u8 op) -+{ -+ switch (op) { -+ /* No-op, used internally for branch optimization */ -+ case JIT_JNOP: -+ break; -+ /* PC += off if dst == src */ -+ case BPF_JEQ: -+ emit(ctx, beq, dst, src, off); -+ break; -+ /* PC += off if dst != src */ -+ case BPF_JNE: -+ emit(ctx, bne, dst, src, off); -+ break; -+ /* PC += off if dst & src */ -+ case BPF_JSET: -+ emit(ctx, and, MIPS_R_T9, dst, src); -+ emit(ctx, bnez, MIPS_R_T9, off); -+ break; -+ /* PC += off if (dst & imm) == 0 (not in BPF, used for long jumps) */ -+ case JIT_JNSET: -+ emit(ctx, and, MIPS_R_T9, dst, src); -+ emit(ctx, beqz, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst > src */ -+ case BPF_JGT: -+ emit(ctx, sltu, MIPS_R_T9, src, dst); -+ emit(ctx, bnez, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst >= src */ -+ case BPF_JGE: -+ emit(ctx, sltu, MIPS_R_T9, dst, src); -+ emit(ctx, beqz, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst < src */ -+ case BPF_JLT: -+ emit(ctx, sltu, MIPS_R_T9, dst, src); -+ emit(ctx, bnez, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst <= src */ -+ case BPF_JLE: -+ emit(ctx, sltu, MIPS_R_T9, src, dst); -+ emit(ctx, beqz, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst > src (signed) */ -+ case BPF_JSGT: -+ emit(ctx, slt, MIPS_R_T9, src, dst); -+ emit(ctx, bnez, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst >= src (signed) */ -+ case BPF_JSGE: -+ emit(ctx, slt, MIPS_R_T9, dst, src); -+ emit(ctx, beqz, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst < src (signed) */ -+ case BPF_JSLT: -+ emit(ctx, slt, MIPS_R_T9, dst, src); -+ emit(ctx, bnez, MIPS_R_T9, off); -+ break; -+ /* PC += off if dst <= src (signed) */ -+ case BPF_JSLE: -+ emit(ctx, slt, MIPS_R_T9, src, dst); -+ emit(ctx, beqz, MIPS_R_T9, off); -+ break; -+ } -+} -+ -+/* Jump always */ -+int emit_ja(struct jit_context *ctx, s16 off) -+{ -+ int target = get_target(ctx, ctx->bpf_index + off + 1); -+ -+ if (target < 0) -+ return -1; -+ emit(ctx, j, target); -+ emit(ctx, nop); -+ return 0; -+} -+ -+/* Jump to epilogue */ -+int emit_exit(struct jit_context *ctx) -+{ -+ int target = get_target(ctx, ctx->program->len); -+ -+ if (target < 0) -+ return -1; -+ emit(ctx, j, target); -+ emit(ctx, nop); -+ return 0; -+} -+ -+/* Build the program body from eBPF bytecode */ -+static int build_body(struct jit_context *ctx) -+{ -+ const struct bpf_prog *prog = ctx->program; -+ unsigned int i; -+ -+ ctx->stack_used = 0; -+ for (i = 0; i < prog->len; i++) { -+ const struct bpf_insn *insn = &prog->insnsi[i]; -+ u32 *descp = &ctx->descriptors[i]; -+ int ret; -+ -+ access_reg(ctx, insn->src_reg); -+ access_reg(ctx, insn->dst_reg); -+ -+ ctx->bpf_index = i; -+ if (ctx->target == NULL) { -+ ctx->changes += INDEX(*descp) != ctx->jit_index; -+ *descp &= JIT_DESC_CONVERT; -+ *descp |= ctx->jit_index; -+ } -+ -+ ret = build_insn(insn, ctx); -+ if (ret < 0) -+ return ret; -+ -+ if (ret > 0) { -+ i++; -+ if (ctx->target == NULL) -+ descp[1] = ctx->jit_index; -+ } -+ } -+ -+ /* Store the end offset, where the epilogue begins */ -+ ctx->descriptors[prog->len] = ctx->jit_index; -+ return 0; -+} -+ -+/* Set the branch conversion flag on all instructions */ -+static void set_convert_flag(struct jit_context *ctx, bool enable) -+{ -+ const struct bpf_prog *prog = ctx->program; -+ u32 flag = enable ? JIT_DESC_CONVERT : 0; -+ unsigned int i; -+ -+ for (i = 0; i <= prog->len; i++) -+ ctx->descriptors[i] = INDEX(ctx->descriptors[i]) | flag; -+} -+ -+static void jit_fill_hole(void *area, unsigned int size) -+{ -+ u32 *p; -+ -+ /* We are guaranteed to have aligned memory. */ -+ for (p = area; size >= sizeof(u32); size -= sizeof(u32)) -+ uasm_i_break(&p, BRK_BUG); /* Increments p */ -+} -+ -+bool bpf_jit_needs_zext(void) -+{ -+ return true; -+} -+ -+struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) -+{ -+ struct bpf_prog *tmp, *orig_prog = prog; -+ struct bpf_binary_header *header = NULL; -+ struct jit_context ctx; -+ bool tmp_blinded = false; -+ unsigned int tmp_idx; -+ unsigned int image_size; -+ u8 *image_ptr; -+ int tries; -+ -+ /* -+ * If BPF JIT was not enabled then we must fall back to -+ * the interpreter. -+ */ -+ if (!prog->jit_requested) -+ return orig_prog; -+ /* -+ * If constant blinding was enabled and we failed during blinding -+ * then we must fall back to the interpreter. Otherwise, we save -+ * the new JITed code. -+ */ -+ tmp = bpf_jit_blind_constants(prog); -+ if (IS_ERR(tmp)) -+ return orig_prog; -+ if (tmp != prog) { -+ tmp_blinded = true; -+ prog = tmp; -+ } -+ -+ memset(&ctx, 0, sizeof(ctx)); -+ ctx.program = prog; -+ -+ /* -+ * Not able to allocate memory for descriptors[], then -+ * we must fall back to the interpreter -+ */ -+ ctx.descriptors = kcalloc(prog->len + 1, sizeof(*ctx.descriptors), -+ GFP_KERNEL); -+ if (ctx.descriptors == NULL) -+ goto out_err; -+ -+ /* First pass discovers used resources */ -+ if (build_body(&ctx) < 0) -+ goto out_err; -+ /* -+ * Second pass computes instruction offsets. -+ * If any PC-relative branches are out of range, a sequence of -+ * a PC-relative branch + a jump is generated, and we have to -+ * try again from the beginning to generate the new offsets. -+ * This is done until no additional conversions are necessary. -+ * The last two iterations are done with all branches being -+ * converted, to guarantee offset table convergence within a -+ * fixed number of iterations. -+ */ -+ ctx.jit_index = 0; -+ build_prologue(&ctx); -+ tmp_idx = ctx.jit_index; -+ -+ tries = JIT_MAX_ITERATIONS; -+ do { -+ ctx.jit_index = tmp_idx; -+ ctx.changes = 0; -+ if (tries == 2) -+ set_convert_flag(&ctx, true); -+ if (build_body(&ctx) < 0) -+ goto out_err; -+ } while (ctx.changes > 0 && --tries > 0); -+ -+ if (WARN_ONCE(ctx.changes > 0, "JIT offsets failed to converge")) -+ goto out_err; -+ -+ build_epilogue(&ctx, MIPS_R_RA); -+ -+ /* Now we know the size of the structure to make */ -+ image_size = sizeof(u32) * ctx.jit_index; -+ header = bpf_jit_binary_alloc(image_size, &image_ptr, -+ sizeof(u32), jit_fill_hole); -+ /* -+ * Not able to allocate memory for the structure then -+ * we must fall back to the interpretation -+ */ -+ if (header == NULL) -+ goto out_err; -+ -+ /* Actual pass to generate final JIT code */ -+ ctx.target = (u32 *)image_ptr; -+ ctx.jit_index = 0; -+ -+ /* -+ * If building the JITed code fails somehow, -+ * we fall back to the interpretation. -+ */ -+ build_prologue(&ctx); -+ if (build_body(&ctx) < 0) -+ goto out_err; -+ build_epilogue(&ctx, MIPS_R_RA); -+ -+ /* Populate line info meta data */ -+ set_convert_flag(&ctx, false); -+ bpf_prog_fill_jited_linfo(prog, &ctx.descriptors[1]); -+ -+ /* Set as read-only exec and flush instruction cache */ -+ bpf_jit_binary_lock_ro(header); -+ flush_icache_range((unsigned long)header, -+ (unsigned long)&ctx.target[ctx.jit_index]); -+ -+ if (bpf_jit_enable > 1) -+ bpf_jit_dump(prog->len, image_size, 2, ctx.target); -+ -+ prog->bpf_func = (void *)ctx.target; -+ prog->jited = 1; -+ prog->jited_len = image_size; -+ -+out: -+ if (tmp_blinded) -+ bpf_jit_prog_release_other(prog, prog == orig_prog ? -+ tmp : orig_prog); -+ kfree(ctx.descriptors); -+ return prog; -+ -+out_err: -+ prog = orig_prog; -+ if (header) -+ bpf_jit_binary_free(header); -+ goto out; -+} ---- /dev/null -+++ b/arch/mips/net/bpf_jit_comp.h -@@ -0,0 +1,211 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Just-In-Time compiler for eBPF bytecode on 32-bit and 64-bit MIPS. -+ * -+ * Copyright (c) 2021 Anyfi Networks AB. -+ * Author: Johan Almbladh -+ * -+ * Based on code and ideas from -+ * Copyright (c) 2017 Cavium, Inc. -+ * Copyright (c) 2017 Shubham Bansal -+ * Copyright (c) 2011 Mircea Gherzan -+ */ -+ -+#ifndef _BPF_JIT_COMP_H -+#define _BPF_JIT_COMP_H -+ -+/* MIPS registers */ -+#define MIPS_R_ZERO 0 /* Const zero */ -+#define MIPS_R_AT 1 /* Asm temp */ -+#define MIPS_R_V0 2 /* Result */ -+#define MIPS_R_V1 3 /* Result */ -+#define MIPS_R_A0 4 /* Argument */ -+#define MIPS_R_A1 5 /* Argument */ -+#define MIPS_R_A2 6 /* Argument */ -+#define MIPS_R_A3 7 /* Argument */ -+#define MIPS_R_A4 8 /* Arg (n64) */ -+#define MIPS_R_A5 9 /* Arg (n64) */ -+#define MIPS_R_A6 10 /* Arg (n64) */ -+#define MIPS_R_A7 11 /* Arg (n64) */ -+#define MIPS_R_T0 8 /* Temp (o32) */ -+#define MIPS_R_T1 9 /* Temp (o32) */ -+#define MIPS_R_T2 10 /* Temp (o32) */ -+#define MIPS_R_T3 11 /* Temp (o32) */ -+#define MIPS_R_T4 12 /* Temporary */ -+#define MIPS_R_T5 13 /* Temporary */ -+#define MIPS_R_T6 14 /* Temporary */ -+#define MIPS_R_T7 15 /* Temporary */ -+#define MIPS_R_S0 16 /* Saved */ -+#define MIPS_R_S1 17 /* Saved */ -+#define MIPS_R_S2 18 /* Saved */ -+#define MIPS_R_S3 19 /* Saved */ -+#define MIPS_R_S4 20 /* Saved */ -+#define MIPS_R_S5 21 /* Saved */ -+#define MIPS_R_S6 22 /* Saved */ -+#define MIPS_R_S7 23 /* Saved */ -+#define MIPS_R_T8 24 /* Temporary */ -+#define MIPS_R_T9 25 /* Temporary */ -+/* MIPS_R_K0 26 Reserved */ -+/* MIPS_R_K1 27 Reserved */ -+#define MIPS_R_GP 28 /* Global ptr */ -+#define MIPS_R_SP 29 /* Stack ptr */ -+#define MIPS_R_FP 30 /* Frame ptr */ -+#define MIPS_R_RA 31 /* Return */ -+ -+/* -+ * Jump address mask for immediate jumps. The four most significant bits -+ * must be equal to PC. -+ */ -+#define MIPS_JMP_MASK 0x0fffffffUL -+ -+/* Maximum number of iterations in offset table computation */ -+#define JIT_MAX_ITERATIONS 8 -+ -+/* -+ * Jump pseudo-instructions used internally -+ * for branch conversion and branch optimization. -+ */ -+#define JIT_JNSET 0xe0 -+#define JIT_JNOP 0xf0 -+ -+/* Descriptor flag for PC-relative branch conversion */ -+#define JIT_DESC_CONVERT BIT(31) -+ -+/* JIT context for an eBPF program */ -+struct jit_context { -+ struct bpf_prog *program; /* The eBPF program being JITed */ -+ u32 *descriptors; /* eBPF to JITed CPU insn descriptors */ -+ u32 *target; /* JITed code buffer */ -+ u32 bpf_index; /* Index of current BPF program insn */ -+ u32 jit_index; /* Index of current JIT target insn */ -+ u32 changes; /* Number of PC-relative branch conv */ -+ u32 accessed; /* Bit mask of read eBPF registers */ -+ u32 clobbered; /* Bit mask of modified CPU registers */ -+ u32 stack_size; /* Total allocated stack size in bytes */ -+ u32 saved_size; /* Size of callee-saved registers */ -+ u32 stack_used; /* Stack size used for function calls */ -+}; -+ -+/* Emit the instruction if the JIT memory space has been allocated */ -+#define emit(ctx, func, ...) \ -+do { \ -+ if ((ctx)->target != NULL) { \ -+ u32 *p = &(ctx)->target[ctx->jit_index]; \ -+ uasm_i_##func(&p, ##__VA_ARGS__); \ -+ } \ -+ (ctx)->jit_index++; \ -+} while (0) -+ -+/* -+ * Mark a BPF register as accessed, it needs to be -+ * initialized by the program if expected, e.g. FP. -+ */ -+static inline void access_reg(struct jit_context *ctx, u8 reg) -+{ -+ ctx->accessed |= BIT(reg); -+} -+ -+/* -+ * Mark a CPU register as clobbered, it needs to be -+ * saved/restored by the program if callee-saved. -+ */ -+static inline void clobber_reg(struct jit_context *ctx, u8 reg) -+{ -+ ctx->clobbered |= BIT(reg); -+} -+ -+/* -+ * Push registers on the stack, starting at a given depth from the stack -+ * pointer and increasing. The next depth to be written is returned. -+ */ -+int push_regs(struct jit_context *ctx, u32 mask, u32 excl, int depth); -+ -+/* -+ * Pop registers from the stack, starting at a given depth from the stack -+ * pointer and increasing. The next depth to be read is returned. -+ */ -+int pop_regs(struct jit_context *ctx, u32 mask, u32 excl, int depth); -+ -+/* Compute the 28-bit jump target address from a BPF program location */ -+int get_target(struct jit_context *ctx, u32 loc); -+ -+/* Compute the PC-relative offset to relative BPF program offset */ -+int get_offset(const struct jit_context *ctx, int off); -+ -+/* dst = imm (32-bit) */ -+void emit_mov_i(struct jit_context *ctx, u8 dst, s32 imm); -+ -+/* dst = src (32-bit) */ -+void emit_mov_r(struct jit_context *ctx, u8 dst, u8 src); -+ -+/* Validate ALU/ALU64 immediate range */ -+bool valid_alu_i(u8 op, s32 imm); -+ -+/* Rewrite ALU/ALU64 immediate operation */ -+bool rewrite_alu_i(u8 op, s32 imm, u8 *alu, s32 *val); -+ -+/* ALU immediate operation (32-bit) */ -+void emit_alu_i(struct jit_context *ctx, u8 dst, s32 imm, u8 op); -+ -+/* ALU register operation (32-bit) */ -+void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op); -+ -+/* Atomic read-modify-write (32-bit) */ -+void emit_atomic_r(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 code); -+ -+/* Atomic compare-and-exchange (32-bit) */ -+void emit_cmpxchg_r(struct jit_context *ctx, u8 dst, u8 src, u8 res, s16 off); -+ -+/* Swap bytes and truncate a register word or half word */ -+void emit_bswap_r(struct jit_context *ctx, u8 dst, u32 width); -+ -+/* Validate JMP/JMP32 immediate range */ -+bool valid_jmp_i(u8 op, s32 imm); -+ -+/* Prepare a PC-relative jump operation with immediate conditional */ -+void setup_jmp_i(struct jit_context *ctx, s32 imm, u8 width, -+ u8 bpf_op, s16 bpf_off, u8 *jit_op, s32 *jit_off); -+ -+/* Prepare a PC-relative jump operation with register conditional */ -+void setup_jmp_r(struct jit_context *ctx, bool same_reg, -+ u8 bpf_op, s16 bpf_off, u8 *jit_op, s32 *jit_off); -+ -+/* Finish a PC-relative jump operation */ -+int finish_jmp(struct jit_context *ctx, u8 jit_op, s16 bpf_off); -+ -+/* Conditional JMP/JMP32 immediate */ -+void emit_jmp_i(struct jit_context *ctx, u8 dst, s32 imm, s32 off, u8 op); -+ -+/* Conditional JMP/JMP32 register */ -+void emit_jmp_r(struct jit_context *ctx, u8 dst, u8 src, s32 off, u8 op); -+ -+/* Jump always */ -+int emit_ja(struct jit_context *ctx, s16 off); -+ -+/* Jump to epilogue */ -+int emit_exit(struct jit_context *ctx); -+ -+/* -+ * Build program prologue to set up the stack and registers. -+ * This function is implemented separately for 32-bit and 64-bit JITs. -+ */ -+void build_prologue(struct jit_context *ctx); -+ -+/* -+ * Build the program epilogue to restore the stack and registers. -+ * This function is implemented separately for 32-bit and 64-bit JITs. -+ */ -+void build_epilogue(struct jit_context *ctx, int dest_reg); -+ -+/* -+ * Convert an eBPF instruction to native instruction, i.e -+ * JITs an eBPF instruction. -+ * Returns : -+ * 0 - Successfully JITed an 8-byte eBPF instruction -+ * >0 - Successfully JITed a 16-byte eBPF instruction -+ * <0 - Failed to JIT. -+ * This function is implemented separately for 32-bit and 64-bit JITs. -+ */ -+int build_insn(const struct bpf_insn *insn, struct jit_context *ctx); -+ -+#endif /* _BPF_JIT_COMP_H */ ---- /dev/null -+++ b/arch/mips/net/bpf_jit_comp32.c -@@ -0,0 +1,1741 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Just-In-Time compiler for eBPF bytecode on MIPS. -+ * Implementation of JIT functions for 32-bit CPUs. -+ * -+ * Copyright (c) 2021 Anyfi Networks AB. -+ * Author: Johan Almbladh -+ * -+ * Based on code and ideas from -+ * Copyright (c) 2017 Cavium, Inc. -+ * Copyright (c) 2017 Shubham Bansal -+ * Copyright (c) 2011 Mircea Gherzan -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "bpf_jit_comp.h" -+ -+/* MIPS a4-a7 are not available in the o32 ABI */ -+#undef MIPS_R_A4 -+#undef MIPS_R_A5 -+#undef MIPS_R_A6 -+#undef MIPS_R_A7 -+ -+/* Stack is 8-byte aligned in o32 ABI */ -+#define MIPS_STACK_ALIGNMENT 8 -+ -+/* -+ * The top 16 bytes of a stack frame is reserved for the callee in O32 ABI. -+ * This corresponds to stack space for register arguments a0-a3. -+ */ -+#define JIT_RESERVED_STACK 16 -+ -+/* Temporary 64-bit register used by JIT */ -+#define JIT_REG_TMP MAX_BPF_JIT_REG -+ -+/* -+ * Number of prologue bytes to skip when doing a tail call. -+ * Tail call count (TCC) initialization (8 bytes) always, plus -+ * R0-to-v0 assignment (4 bytes) if big endian. -+ */ -+#ifdef __BIG_ENDIAN -+#define JIT_TCALL_SKIP 12 -+#else -+#define JIT_TCALL_SKIP 8 -+#endif -+ -+/* CPU registers holding the callee return value */ -+#define JIT_RETURN_REGS \ -+ (BIT(MIPS_R_V0) | \ -+ BIT(MIPS_R_V1)) -+ -+/* CPU registers arguments passed to callee directly */ -+#define JIT_ARG_REGS \ -+ (BIT(MIPS_R_A0) | \ -+ BIT(MIPS_R_A1) | \ -+ BIT(MIPS_R_A2) | \ -+ BIT(MIPS_R_A3)) -+ -+/* CPU register arguments passed to callee on stack */ -+#define JIT_STACK_REGS \ -+ (BIT(MIPS_R_T0) | \ -+ BIT(MIPS_R_T1) | \ -+ BIT(MIPS_R_T2) | \ -+ BIT(MIPS_R_T3) | \ -+ BIT(MIPS_R_T4) | \ -+ BIT(MIPS_R_T5)) -+ -+/* Caller-saved CPU registers */ -+#define JIT_CALLER_REGS \ -+ (JIT_RETURN_REGS | \ -+ JIT_ARG_REGS | \ -+ JIT_STACK_REGS) -+ -+/* Callee-saved CPU registers */ -+#define JIT_CALLEE_REGS \ -+ (BIT(MIPS_R_S0) | \ -+ BIT(MIPS_R_S1) | \ -+ BIT(MIPS_R_S2) | \ -+ BIT(MIPS_R_S3) | \ -+ BIT(MIPS_R_S4) | \ -+ BIT(MIPS_R_S5) | \ -+ BIT(MIPS_R_S6) | \ -+ BIT(MIPS_R_S7) | \ -+ BIT(MIPS_R_GP) | \ -+ BIT(MIPS_R_FP) | \ -+ BIT(MIPS_R_RA)) -+ -+/* -+ * Mapping of 64-bit eBPF registers to 32-bit native MIPS registers. -+ * -+ * 1) Native register pairs are ordered according to CPU endiannes, following -+ * the MIPS convention for passing 64-bit arguments and return values. -+ * 2) The eBPF return value, arguments and callee-saved registers are mapped -+ * to their native MIPS equivalents. -+ * 3) Since the 32 highest bits in the eBPF FP register are always zero, -+ * only one general-purpose register is actually needed for the mapping. -+ * We use the fp register for this purpose, and map the highest bits to -+ * the MIPS register r0 (zero). -+ * 4) We use the MIPS gp and at registers as internal temporary registers -+ * for constant blinding. The gp register is callee-saved. -+ * 5) One 64-bit temporary register is mapped for use when sign-extending -+ * immediate operands. MIPS registers t6-t9 are available to the JIT -+ * for as temporaries when implementing complex 64-bit operations. -+ * -+ * With this scheme all eBPF registers are being mapped to native MIPS -+ * registers without having to use any stack scratch space. The direct -+ * register mapping (2) simplifies the handling of function calls. -+ */ -+static const u8 bpf2mips32[][2] = { -+ /* Return value from in-kernel function, and exit value from eBPF */ -+ [BPF_REG_0] = {MIPS_R_V1, MIPS_R_V0}, -+ /* Arguments from eBPF program to in-kernel function */ -+ [BPF_REG_1] = {MIPS_R_A1, MIPS_R_A0}, -+ [BPF_REG_2] = {MIPS_R_A3, MIPS_R_A2}, -+ /* Remaining arguments, to be passed on the stack per O32 ABI */ -+ [BPF_REG_3] = {MIPS_R_T1, MIPS_R_T0}, -+ [BPF_REG_4] = {MIPS_R_T3, MIPS_R_T2}, -+ [BPF_REG_5] = {MIPS_R_T5, MIPS_R_T4}, -+ /* Callee-saved registers that in-kernel function will preserve */ -+ [BPF_REG_6] = {MIPS_R_S1, MIPS_R_S0}, -+ [BPF_REG_7] = {MIPS_R_S3, MIPS_R_S2}, -+ [BPF_REG_8] = {MIPS_R_S5, MIPS_R_S4}, -+ [BPF_REG_9] = {MIPS_R_S7, MIPS_R_S6}, -+ /* Read-only frame pointer to access the eBPF stack */ -+#ifdef __BIG_ENDIAN -+ [BPF_REG_FP] = {MIPS_R_FP, MIPS_R_ZERO}, -+#else -+ [BPF_REG_FP] = {MIPS_R_ZERO, MIPS_R_FP}, -+#endif -+ /* Temporary register for blinding constants */ -+ [BPF_REG_AX] = {MIPS_R_GP, MIPS_R_AT}, -+ /* Temporary register for internal JIT use */ -+ [JIT_REG_TMP] = {MIPS_R_T7, MIPS_R_T6}, -+}; -+ -+/* Get low CPU register for a 64-bit eBPF register mapping */ -+static inline u8 lo(const u8 reg[]) -+{ -+#ifdef __BIG_ENDIAN -+ return reg[0]; -+#else -+ return reg[1]; -+#endif -+} -+ -+/* Get high CPU register for a 64-bit eBPF register mapping */ -+static inline u8 hi(const u8 reg[]) -+{ -+#ifdef __BIG_ENDIAN -+ return reg[1]; -+#else -+ return reg[0]; -+#endif -+} -+ -+/* -+ * Mark a 64-bit CPU register pair as clobbered, it needs to be -+ * saved/restored by the program if callee-saved. -+ */ -+static void clobber_reg64(struct jit_context *ctx, const u8 reg[]) -+{ -+ clobber_reg(ctx, reg[0]); -+ clobber_reg(ctx, reg[1]); -+} -+ -+/* dst = imm (sign-extended) */ -+static void emit_mov_se_i64(struct jit_context *ctx, const u8 dst[], s32 imm) -+{ -+ emit_mov_i(ctx, lo(dst), imm); -+ if (imm < 0) -+ emit(ctx, addiu, hi(dst), MIPS_R_ZERO, -1); -+ else -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); -+ clobber_reg64(ctx, dst); -+} -+ -+/* Zero extension, if verifier does not do it for us */ -+static void emit_zext_ver(struct jit_context *ctx, const u8 dst[]) -+{ -+ if (!ctx->program->aux->verifier_zext) { -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); -+ clobber_reg(ctx, hi(dst)); -+ } -+} -+ -+/* Load delay slot, if ISA mandates it */ -+static void emit_load_delay(struct jit_context *ctx) -+{ -+ if (!cpu_has_mips_2_3_4_5_r) -+ emit(ctx, nop); -+} -+ -+/* ALU immediate operation (64-bit) */ -+static void emit_alu_i64(struct jit_context *ctx, -+ const u8 dst[], s32 imm, u8 op) -+{ -+ u8 src = MIPS_R_T6; -+ -+ /* -+ * ADD/SUB with all but the max negative imm can be handled by -+ * inverting the operation and the imm value, saving one insn. -+ */ -+ if (imm > S32_MIN && imm < 0) -+ switch (op) { -+ case BPF_ADD: -+ op = BPF_SUB; -+ imm = -imm; -+ break; -+ case BPF_SUB: -+ op = BPF_ADD; -+ imm = -imm; -+ break; -+ } -+ -+ /* Move immediate to temporary register */ -+ emit_mov_i(ctx, src, imm); -+ -+ switch (op) { -+ /* dst = dst + imm */ -+ case BPF_ADD: -+ emit(ctx, addu, lo(dst), lo(dst), src); -+ emit(ctx, sltu, MIPS_R_T9, lo(dst), src); -+ emit(ctx, addu, hi(dst), hi(dst), MIPS_R_T9); -+ if (imm < 0) -+ emit(ctx, addiu, hi(dst), hi(dst), -1); -+ break; -+ /* dst = dst - imm */ -+ case BPF_SUB: -+ emit(ctx, sltu, MIPS_R_T9, lo(dst), src); -+ emit(ctx, subu, lo(dst), lo(dst), src); -+ emit(ctx, subu, hi(dst), hi(dst), MIPS_R_T9); -+ if (imm < 0) -+ emit(ctx, addiu, hi(dst), hi(dst), 1); -+ break; -+ /* dst = dst | imm */ -+ case BPF_OR: -+ emit(ctx, or, lo(dst), lo(dst), src); -+ if (imm < 0) -+ emit(ctx, addiu, hi(dst), MIPS_R_ZERO, -1); -+ break; -+ /* dst = dst & imm */ -+ case BPF_AND: -+ emit(ctx, and, lo(dst), lo(dst), src); -+ if (imm >= 0) -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); -+ break; -+ /* dst = dst ^ imm */ -+ case BPF_XOR: -+ emit(ctx, xor, lo(dst), lo(dst), src); -+ if (imm < 0) { -+ emit(ctx, subu, hi(dst), MIPS_R_ZERO, hi(dst)); -+ emit(ctx, addiu, hi(dst), hi(dst), -1); -+ } -+ break; -+ } -+ clobber_reg64(ctx, dst); -+} -+ -+/* ALU register operation (64-bit) */ -+static void emit_alu_r64(struct jit_context *ctx, -+ const u8 dst[], const u8 src[], u8 op) -+{ -+ switch (BPF_OP(op)) { -+ /* dst = dst + src */ -+ case BPF_ADD: -+ if (src == dst) { -+ emit(ctx, srl, MIPS_R_T9, lo(dst), 31); -+ emit(ctx, addu, lo(dst), lo(dst), lo(dst)); -+ } else { -+ emit(ctx, addu, lo(dst), lo(dst), lo(src)); -+ emit(ctx, sltu, MIPS_R_T9, lo(dst), lo(src)); -+ } -+ emit(ctx, addu, hi(dst), hi(dst), hi(src)); -+ emit(ctx, addu, hi(dst), hi(dst), MIPS_R_T9); -+ break; -+ /* dst = dst - src */ -+ case BPF_SUB: -+ emit(ctx, sltu, MIPS_R_T9, lo(dst), lo(src)); -+ emit(ctx, subu, lo(dst), lo(dst), lo(src)); -+ emit(ctx, subu, hi(dst), hi(dst), hi(src)); -+ emit(ctx, subu, hi(dst), hi(dst), MIPS_R_T9); -+ break; -+ /* dst = dst | src */ -+ case BPF_OR: -+ emit(ctx, or, lo(dst), lo(dst), lo(src)); -+ emit(ctx, or, hi(dst), hi(dst), hi(src)); -+ break; -+ /* dst = dst & src */ -+ case BPF_AND: -+ emit(ctx, and, lo(dst), lo(dst), lo(src)); -+ emit(ctx, and, hi(dst), hi(dst), hi(src)); -+ break; -+ /* dst = dst ^ src */ -+ case BPF_XOR: -+ emit(ctx, xor, lo(dst), lo(dst), lo(src)); -+ emit(ctx, xor, hi(dst), hi(dst), hi(src)); -+ break; -+ } -+ clobber_reg64(ctx, dst); -+} -+ -+/* ALU invert (64-bit) */ -+static void emit_neg_i64(struct jit_context *ctx, const u8 dst[]) -+{ -+ emit(ctx, sltu, MIPS_R_T9, MIPS_R_ZERO, lo(dst)); -+ emit(ctx, subu, lo(dst), MIPS_R_ZERO, lo(dst)); -+ emit(ctx, subu, hi(dst), MIPS_R_ZERO, hi(dst)); -+ emit(ctx, subu, hi(dst), hi(dst), MIPS_R_T9); -+ -+ clobber_reg64(ctx, dst); -+} -+ -+/* ALU shift immediate (64-bit) */ -+static void emit_shift_i64(struct jit_context *ctx, -+ const u8 dst[], u32 imm, u8 op) -+{ -+ switch (BPF_OP(op)) { -+ /* dst = dst << imm */ -+ case BPF_LSH: -+ if (imm < 32) { -+ emit(ctx, srl, MIPS_R_T9, lo(dst), 32 - imm); -+ emit(ctx, sll, lo(dst), lo(dst), imm); -+ emit(ctx, sll, hi(dst), hi(dst), imm); -+ emit(ctx, or, hi(dst), hi(dst), MIPS_R_T9); -+ } else { -+ emit(ctx, sll, hi(dst), lo(dst), imm - 32); -+ emit(ctx, move, lo(dst), MIPS_R_ZERO); -+ } -+ break; -+ /* dst = dst >> imm */ -+ case BPF_RSH: -+ if (imm < 32) { -+ emit(ctx, sll, MIPS_R_T9, hi(dst), 32 - imm); -+ emit(ctx, srl, lo(dst), lo(dst), imm); -+ emit(ctx, srl, hi(dst), hi(dst), imm); -+ emit(ctx, or, lo(dst), lo(dst), MIPS_R_T9); -+ } else { -+ emit(ctx, srl, lo(dst), hi(dst), imm - 32); -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); -+ } -+ break; -+ /* dst = dst >> imm (arithmetic) */ -+ case BPF_ARSH: -+ if (imm < 32) { -+ emit(ctx, sll, MIPS_R_T9, hi(dst), 32 - imm); -+ emit(ctx, srl, lo(dst), lo(dst), imm); -+ emit(ctx, sra, hi(dst), hi(dst), imm); -+ emit(ctx, or, lo(dst), lo(dst), MIPS_R_T9); -+ } else { -+ emit(ctx, sra, lo(dst), hi(dst), imm - 32); -+ emit(ctx, sra, hi(dst), hi(dst), 31); -+ } -+ break; -+ } -+ clobber_reg64(ctx, dst); -+} -+ -+/* ALU shift register (64-bit) */ -+static void emit_shift_r64(struct jit_context *ctx, -+ const u8 dst[], u8 src, u8 op) -+{ -+ u8 t1 = MIPS_R_T8; -+ u8 t2 = MIPS_R_T9; -+ -+ emit(ctx, andi, t1, src, 32); /* t1 = src & 32 */ -+ emit(ctx, beqz, t1, 16); /* PC += 16 if t1 == 0 */ -+ emit(ctx, nor, t2, src, MIPS_R_ZERO); /* t2 = ~src (delay slot) */ -+ -+ switch (BPF_OP(op)) { -+ /* dst = dst << src */ -+ case BPF_LSH: -+ /* Next: shift >= 32 */ -+ emit(ctx, sllv, hi(dst), lo(dst), src); /* dh = dl << src */ -+ emit(ctx, move, lo(dst), MIPS_R_ZERO); /* dl = 0 */ -+ emit(ctx, b, 20); /* PC += 20 */ -+ /* +16: shift < 32 */ -+ emit(ctx, srl, t1, lo(dst), 1); /* t1 = dl >> 1 */ -+ emit(ctx, srlv, t1, t1, t2); /* t1 = t1 >> t2 */ -+ emit(ctx, sllv, lo(dst), lo(dst), src); /* dl = dl << src */ -+ emit(ctx, sllv, hi(dst), hi(dst), src); /* dh = dh << src */ -+ emit(ctx, or, hi(dst), hi(dst), t1); /* dh = dh | t1 */ -+ break; -+ /* dst = dst >> src */ -+ case BPF_RSH: -+ /* Next: shift >= 32 */ -+ emit(ctx, srlv, lo(dst), hi(dst), src); /* dl = dh >> src */ -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); /* dh = 0 */ -+ emit(ctx, b, 20); /* PC += 20 */ -+ /* +16: shift < 32 */ -+ emit(ctx, sll, t1, hi(dst), 1); /* t1 = dl << 1 */ -+ emit(ctx, sllv, t1, t1, t2); /* t1 = t1 << t2 */ -+ emit(ctx, srlv, lo(dst), lo(dst), src); /* dl = dl >> src */ -+ emit(ctx, srlv, hi(dst), hi(dst), src); /* dh = dh >> src */ -+ emit(ctx, or, lo(dst), lo(dst), t1); /* dl = dl | t1 */ -+ break; -+ /* dst = dst >> src (arithmetic) */ -+ case BPF_ARSH: -+ /* Next: shift >= 32 */ -+ emit(ctx, srav, lo(dst), hi(dst), src); /* dl = dh >>a src */ -+ emit(ctx, sra, hi(dst), hi(dst), 31); /* dh = dh >>a 31 */ -+ emit(ctx, b, 20); /* PC += 20 */ -+ /* +16: shift < 32 */ -+ emit(ctx, sll, t1, hi(dst), 1); /* t1 = dl << 1 */ -+ emit(ctx, sllv, t1, t1, t2); /* t1 = t1 << t2 */ -+ emit(ctx, srlv, lo(dst), lo(dst), src); /* dl = dl >>a src */ -+ emit(ctx, srav, hi(dst), hi(dst), src); /* dh = dh >> src */ -+ emit(ctx, or, lo(dst), lo(dst), t1); /* dl = dl | t1 */ -+ break; -+ } -+ -+ /* +20: Done */ -+ clobber_reg64(ctx, dst); -+} -+ -+/* ALU mul immediate (64x32-bit) */ -+static void emit_mul_i64(struct jit_context *ctx, const u8 dst[], s32 imm) -+{ -+ u8 src = MIPS_R_T6; -+ u8 tmp = MIPS_R_T9; -+ -+ switch (imm) { -+ /* dst = dst * 1 is a no-op */ -+ case 1: -+ break; -+ /* dst = dst * -1 */ -+ case -1: -+ emit_neg_i64(ctx, dst); -+ break; -+ case 0: -+ emit_mov_r(ctx, lo(dst), MIPS_R_ZERO); -+ emit_mov_r(ctx, hi(dst), MIPS_R_ZERO); -+ break; -+ /* Full 64x32 multiply */ -+ default: -+ /* hi(dst) = hi(dst) * src(imm) */ -+ emit_mov_i(ctx, src, imm); -+ if (cpu_has_mips32r1 || cpu_has_mips32r6) { -+ emit(ctx, mul, hi(dst), hi(dst), src); -+ } else { -+ emit(ctx, multu, hi(dst), src); -+ emit(ctx, mflo, hi(dst)); -+ } -+ -+ /* hi(dst) = hi(dst) - lo(dst) */ -+ if (imm < 0) -+ emit(ctx, subu, hi(dst), hi(dst), lo(dst)); -+ -+ /* tmp = lo(dst) * src(imm) >> 32 */ -+ /* lo(dst) = lo(dst) * src(imm) */ -+ if (cpu_has_mips32r6) { -+ emit(ctx, muhu, tmp, lo(dst), src); -+ emit(ctx, mulu, lo(dst), lo(dst), src); -+ } else { -+ emit(ctx, multu, lo(dst), src); -+ emit(ctx, mflo, lo(dst)); -+ emit(ctx, mfhi, tmp); -+ } -+ -+ /* hi(dst) += tmp */ -+ emit(ctx, addu, hi(dst), hi(dst), tmp); -+ clobber_reg64(ctx, dst); -+ break; -+ } -+} -+ -+/* ALU mul register (64x64-bit) */ -+static void emit_mul_r64(struct jit_context *ctx, -+ const u8 dst[], const u8 src[]) -+{ -+ u8 acc = MIPS_R_T8; -+ u8 tmp = MIPS_R_T9; -+ -+ /* acc = hi(dst) * lo(src) */ -+ if (cpu_has_mips32r1 || cpu_has_mips32r6) { -+ emit(ctx, mul, acc, hi(dst), lo(src)); -+ } else { -+ emit(ctx, multu, hi(dst), lo(src)); -+ emit(ctx, mflo, acc); -+ } -+ -+ /* tmp = lo(dst) * hi(src) */ -+ if (cpu_has_mips32r1 || cpu_has_mips32r6) { -+ emit(ctx, mul, tmp, lo(dst), hi(src)); -+ } else { -+ emit(ctx, multu, lo(dst), hi(src)); -+ emit(ctx, mflo, tmp); -+ } -+ -+ /* acc += tmp */ -+ emit(ctx, addu, acc, acc, tmp); -+ -+ /* tmp = lo(dst) * lo(src) >> 32 */ -+ /* lo(dst) = lo(dst) * lo(src) */ -+ if (cpu_has_mips32r6) { -+ emit(ctx, muhu, tmp, lo(dst), lo(src)); -+ emit(ctx, mulu, lo(dst), lo(dst), lo(src)); -+ } else { -+ emit(ctx, multu, lo(dst), lo(src)); -+ emit(ctx, mflo, lo(dst)); -+ emit(ctx, mfhi, tmp); -+ } -+ -+ /* hi(dst) = acc + tmp */ -+ emit(ctx, addu, hi(dst), acc, tmp); -+ clobber_reg64(ctx, dst); -+} -+ -+/* Helper function for 64-bit modulo */ -+static u64 jit_mod64(u64 a, u64 b) -+{ -+ u64 rem; -+ -+ div64_u64_rem(a, b, &rem); -+ return rem; -+} -+ -+/* ALU div/mod register (64-bit) */ -+static void emit_divmod_r64(struct jit_context *ctx, -+ const u8 dst[], const u8 src[], u8 op) -+{ -+ const u8 *r0 = bpf2mips32[BPF_REG_0]; /* Mapped to v0-v1 */ -+ const u8 *r1 = bpf2mips32[BPF_REG_1]; /* Mapped to a0-a1 */ -+ const u8 *r2 = bpf2mips32[BPF_REG_2]; /* Mapped to a2-a3 */ -+ int exclude, k; -+ u32 addr = 0; -+ -+ /* Push caller-saved registers on stack */ -+ push_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, -+ 0, JIT_RESERVED_STACK); -+ -+ /* Put 64-bit arguments 1 and 2 in registers a0-a3 */ -+ for (k = 0; k < 2; k++) { -+ emit(ctx, move, MIPS_R_T9, src[k]); -+ emit(ctx, move, r1[k], dst[k]); -+ emit(ctx, move, r2[k], MIPS_R_T9); -+ } -+ -+ /* Emit function call */ -+ switch (BPF_OP(op)) { -+ /* dst = dst / src */ -+ case BPF_DIV: -+ addr = (u32)&div64_u64; -+ break; -+ /* dst = dst % src */ -+ case BPF_MOD: -+ addr = (u32)&jit_mod64; -+ break; -+ } -+ emit_mov_i(ctx, MIPS_R_T9, addr); -+ emit(ctx, jalr, MIPS_R_RA, MIPS_R_T9); -+ emit(ctx, nop); /* Delay slot */ -+ -+ /* Store the 64-bit result in dst */ -+ emit(ctx, move, dst[0], r0[0]); -+ emit(ctx, move, dst[1], r0[1]); -+ -+ /* Restore caller-saved registers, excluding the computed result */ -+ exclude = BIT(lo(dst)) | BIT(hi(dst)); -+ pop_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, -+ exclude, JIT_RESERVED_STACK); -+ emit_load_delay(ctx); -+ -+ clobber_reg64(ctx, dst); -+ clobber_reg(ctx, MIPS_R_V0); -+ clobber_reg(ctx, MIPS_R_V1); -+ clobber_reg(ctx, MIPS_R_RA); -+} -+ -+/* Swap bytes in a register word */ -+static void emit_swap8_r(struct jit_context *ctx, u8 dst, u8 src, u8 mask) -+{ -+ u8 tmp = MIPS_R_T9; -+ -+ emit(ctx, and, tmp, src, mask); /* tmp = src & 0x00ff00ff */ -+ emit(ctx, sll, tmp, tmp, 8); /* tmp = tmp << 8 */ -+ emit(ctx, srl, dst, src, 8); /* dst = src >> 8 */ -+ emit(ctx, and, dst, dst, mask); /* dst = dst & 0x00ff00ff */ -+ emit(ctx, or, dst, dst, tmp); /* dst = dst | tmp */ -+} -+ -+/* Swap half words in a register word */ -+static void emit_swap16_r(struct jit_context *ctx, u8 dst, u8 src) -+{ -+ u8 tmp = MIPS_R_T9; -+ -+ emit(ctx, sll, tmp, src, 16); /* tmp = src << 16 */ -+ emit(ctx, srl, dst, src, 16); /* dst = src >> 16 */ -+ emit(ctx, or, dst, dst, tmp); /* dst = dst | tmp */ -+} -+ -+/* Swap bytes and truncate a register double word, word or half word */ -+static void emit_bswap_r64(struct jit_context *ctx, const u8 dst[], u32 width) -+{ -+ u8 tmp = MIPS_R_T8; -+ -+ switch (width) { -+ /* Swap bytes in a double word */ -+ case 64: -+ if (cpu_has_mips32r2 || cpu_has_mips32r6) { -+ emit(ctx, rotr, tmp, hi(dst), 16); -+ emit(ctx, rotr, hi(dst), lo(dst), 16); -+ emit(ctx, wsbh, lo(dst), tmp); -+ emit(ctx, wsbh, hi(dst), hi(dst)); -+ } else { -+ emit_swap16_r(ctx, tmp, lo(dst)); -+ emit_swap16_r(ctx, lo(dst), hi(dst)); -+ emit(ctx, move, hi(dst), tmp); -+ -+ emit(ctx, lui, tmp, 0xff); /* tmp = 0x00ff0000 */ -+ emit(ctx, ori, tmp, tmp, 0xff); /* tmp = 0x00ff00ff */ -+ emit_swap8_r(ctx, lo(dst), lo(dst), tmp); -+ emit_swap8_r(ctx, hi(dst), hi(dst), tmp); -+ } -+ break; -+ /* Swap bytes in a word */ -+ /* Swap bytes in a half word */ -+ case 32: -+ case 16: -+ emit_bswap_r(ctx, lo(dst), width); -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); -+ break; -+ } -+ clobber_reg64(ctx, dst); -+} -+ -+/* Truncate a register double word, word or half word */ -+static void emit_trunc_r64(struct jit_context *ctx, const u8 dst[], u32 width) -+{ -+ switch (width) { -+ case 64: -+ break; -+ /* Zero-extend a word */ -+ case 32: -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); -+ clobber_reg(ctx, hi(dst)); -+ break; -+ /* Zero-extend a half word */ -+ case 16: -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); -+ emit(ctx, andi, lo(dst), lo(dst), 0xffff); -+ clobber_reg64(ctx, dst); -+ break; -+ } -+} -+ -+/* Load operation: dst = *(size*)(src + off) */ -+static void emit_ldx(struct jit_context *ctx, -+ const u8 dst[], u8 src, s16 off, u8 size) -+{ -+ switch (size) { -+ /* Load a byte */ -+ case BPF_B: -+ emit(ctx, lbu, lo(dst), off, src); -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); -+ break; -+ /* Load a half word */ -+ case BPF_H: -+ emit(ctx, lhu, lo(dst), off, src); -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); -+ break; -+ /* Load a word */ -+ case BPF_W: -+ emit(ctx, lw, lo(dst), off, src); -+ emit(ctx, move, hi(dst), MIPS_R_ZERO); -+ break; -+ /* Load a double word */ -+ case BPF_DW: -+ if (dst[1] == src) { -+ emit(ctx, lw, dst[0], off + 4, src); -+ emit(ctx, lw, dst[1], off, src); -+ } else { -+ emit(ctx, lw, dst[1], off, src); -+ emit(ctx, lw, dst[0], off + 4, src); -+ } -+ emit_load_delay(ctx); -+ break; -+ } -+ clobber_reg64(ctx, dst); -+} -+ -+/* Store operation: *(size *)(dst + off) = src */ -+static void emit_stx(struct jit_context *ctx, -+ const u8 dst, const u8 src[], s16 off, u8 size) -+{ -+ switch (size) { -+ /* Store a byte */ -+ case BPF_B: -+ emit(ctx, sb, lo(src), off, dst); -+ break; -+ /* Store a half word */ -+ case BPF_H: -+ emit(ctx, sh, lo(src), off, dst); -+ break; -+ /* Store a word */ -+ case BPF_W: -+ emit(ctx, sw, lo(src), off, dst); -+ break; -+ /* Store a double word */ -+ case BPF_DW: -+ emit(ctx, sw, src[1], off, dst); -+ emit(ctx, sw, src[0], off + 4, dst); -+ break; -+ } -+} -+ -+/* Atomic read-modify-write (32-bit, non-ll/sc fallback) */ -+static void emit_atomic_r32(struct jit_context *ctx, -+ u8 dst, u8 src, s16 off, u8 code) -+{ -+ u32 exclude = 0; -+ u32 addr = 0; -+ -+ /* Push caller-saved registers on stack */ -+ push_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, -+ 0, JIT_RESERVED_STACK); -+ /* -+ * Argument 1: dst+off if xchg, otherwise src, passed in register a0 -+ * Argument 2: src if xchg, othersize dst+off, passed in register a1 -+ */ -+ emit(ctx, move, MIPS_R_T9, dst); -+ emit(ctx, move, MIPS_R_A0, src); -+ emit(ctx, addiu, MIPS_R_A1, MIPS_R_T9, off); -+ -+ /* Emit function call */ -+ switch (code) { -+ case BPF_ADD: -+ addr = (u32)&atomic_add; -+ break; -+ case BPF_SUB: -+ addr = (u32)&atomic_sub; -+ break; -+ case BPF_OR: -+ addr = (u32)&atomic_or; -+ break; -+ case BPF_AND: -+ addr = (u32)&atomic_and; -+ break; -+ case BPF_XOR: -+ addr = (u32)&atomic_xor; -+ break; -+ } -+ emit_mov_i(ctx, MIPS_R_T9, addr); -+ emit(ctx, jalr, MIPS_R_RA, MIPS_R_T9); -+ emit(ctx, nop); /* Delay slot */ -+ -+ /* Restore caller-saved registers, except any fetched value */ -+ pop_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, -+ exclude, JIT_RESERVED_STACK); -+ emit_load_delay(ctx); -+ clobber_reg(ctx, MIPS_R_RA); -+} -+ -+/* Atomic read-modify-write (64-bit) */ -+static void emit_atomic_r64(struct jit_context *ctx, -+ u8 dst, const u8 src[], s16 off, u8 code) -+{ -+ const u8 *r1 = bpf2mips32[BPF_REG_1]; /* Mapped to a0-a1 */ -+ u32 exclude = 0; -+ u32 addr = 0; -+ -+ /* Push caller-saved registers on stack */ -+ push_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, -+ 0, JIT_RESERVED_STACK); -+ /* -+ * Argument 1: 64-bit src, passed in registers a0-a1 -+ * Argument 2: 32-bit dst+off, passed in register a2 -+ */ -+ emit(ctx, move, MIPS_R_T9, dst); -+ emit(ctx, move, r1[0], src[0]); -+ emit(ctx, move, r1[1], src[1]); -+ emit(ctx, addiu, MIPS_R_A2, MIPS_R_T9, off); -+ -+ /* Emit function call */ -+ switch (code) { -+ case BPF_ADD: -+ addr = (u32)&atomic64_add; -+ break; -+ case BPF_SUB: -+ addr = (u32)&atomic64_sub; -+ break; -+ case BPF_OR: -+ addr = (u32)&atomic64_or; -+ break; -+ case BPF_AND: -+ addr = (u32)&atomic64_and; -+ break; -+ case BPF_XOR: -+ addr = (u32)&atomic64_xor; -+ break; -+ } -+ emit_mov_i(ctx, MIPS_R_T9, addr); -+ emit(ctx, jalr, MIPS_R_RA, MIPS_R_T9); -+ emit(ctx, nop); /* Delay slot */ -+ -+ /* Restore caller-saved registers, except any fetched value */ -+ pop_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, -+ exclude, JIT_RESERVED_STACK); -+ emit_load_delay(ctx); -+ clobber_reg(ctx, MIPS_R_RA); -+} -+ -+/* -+ * Conditional movz or an emulated equivalent. -+ * Note that the rs register may be modified. -+ */ -+static void emit_movz_r(struct jit_context *ctx, u8 rd, u8 rs, u8 rt) -+{ -+ if (cpu_has_mips_2) { -+ emit(ctx, movz, rd, rs, rt); /* rd = rt ? rd : rs */ -+ } else if (cpu_has_mips32r6) { -+ if (rs != MIPS_R_ZERO) -+ emit(ctx, seleqz, rs, rs, rt); /* rs = 0 if rt == 0 */ -+ emit(ctx, selnez, rd, rd, rt); /* rd = 0 if rt != 0 */ -+ if (rs != MIPS_R_ZERO) -+ emit(ctx, or, rd, rd, rs); /* rd = rd | rs */ -+ } else { -+ emit(ctx, bnez, rt, 8); /* PC += 8 if rd != 0 */ -+ emit(ctx, nop); /* +0: delay slot */ -+ emit(ctx, or, rd, rs, MIPS_R_ZERO); /* +4: rd = rs */ -+ } -+ clobber_reg(ctx, rd); -+ clobber_reg(ctx, rs); -+} -+ -+/* -+ * Conditional movn or an emulated equivalent. -+ * Note that the rs register may be modified. -+ */ -+static void emit_movn_r(struct jit_context *ctx, u8 rd, u8 rs, u8 rt) -+{ -+ if (cpu_has_mips_2) { -+ emit(ctx, movn, rd, rs, rt); /* rd = rt ? rs : rd */ -+ } else if (cpu_has_mips32r6) { -+ if (rs != MIPS_R_ZERO) -+ emit(ctx, selnez, rs, rs, rt); /* rs = 0 if rt == 0 */ -+ emit(ctx, seleqz, rd, rd, rt); /* rd = 0 if rt != 0 */ -+ if (rs != MIPS_R_ZERO) -+ emit(ctx, or, rd, rd, rs); /* rd = rd | rs */ -+ } else { -+ emit(ctx, beqz, rt, 8); /* PC += 8 if rd == 0 */ -+ emit(ctx, nop); /* +0: delay slot */ -+ emit(ctx, or, rd, rs, MIPS_R_ZERO); /* +4: rd = rs */ -+ } -+ clobber_reg(ctx, rd); -+ clobber_reg(ctx, rs); -+} -+ -+/* Emulation of 64-bit sltiu rd, rs, imm, where imm may be S32_MAX + 1 */ -+static void emit_sltiu_r64(struct jit_context *ctx, u8 rd, -+ const u8 rs[], s64 imm) -+{ -+ u8 tmp = MIPS_R_T9; -+ -+ if (imm < 0) { -+ emit_mov_i(ctx, rd, imm); /* rd = imm */ -+ emit(ctx, sltu, rd, lo(rs), rd); /* rd = rsl < rd */ -+ emit(ctx, sltiu, tmp, hi(rs), -1); /* tmp = rsh < ~0U */ -+ emit(ctx, or, rd, rd, tmp); /* rd = rd | tmp */ -+ } else { /* imm >= 0 */ -+ if (imm > 0x7fff) { -+ emit_mov_i(ctx, rd, (s32)imm); /* rd = imm */ -+ emit(ctx, sltu, rd, lo(rs), rd); /* rd = rsl < rd */ -+ } else { -+ emit(ctx, sltiu, rd, lo(rs), imm); /* rd = rsl < imm */ -+ } -+ emit_movn_r(ctx, rd, MIPS_R_ZERO, hi(rs)); /* rd = 0 if rsh */ -+ } -+} -+ -+/* Emulation of 64-bit sltu rd, rs, rt */ -+static void emit_sltu_r64(struct jit_context *ctx, u8 rd, -+ const u8 rs[], const u8 rt[]) -+{ -+ u8 tmp = MIPS_R_T9; -+ -+ emit(ctx, sltu, rd, lo(rs), lo(rt)); /* rd = rsl < rtl */ -+ emit(ctx, subu, tmp, hi(rs), hi(rt)); /* tmp = rsh - rth */ -+ emit_movn_r(ctx, rd, MIPS_R_ZERO, tmp); /* rd = 0 if tmp != 0 */ -+ emit(ctx, sltu, tmp, hi(rs), hi(rt)); /* tmp = rsh < rth */ -+ emit(ctx, or, rd, rd, tmp); /* rd = rd | tmp */ -+} -+ -+/* Emulation of 64-bit slti rd, rs, imm, where imm may be S32_MAX + 1 */ -+static void emit_slti_r64(struct jit_context *ctx, u8 rd, -+ const u8 rs[], s64 imm) -+{ -+ u8 t1 = MIPS_R_T8; -+ u8 t2 = MIPS_R_T9; -+ u8 cmp; -+ -+ /* -+ * if ((rs < 0) ^ (imm < 0)) t1 = imm >u rsl -+ * else t1 = rsl > 31 */ -+ if (imm < 0) -+ emit_movz_r(ctx, t1, t2, rd); /* t1 = rd ? t1 : t2 */ -+ else -+ emit_movn_r(ctx, t1, t2, rd); /* t1 = rd ? t2 : t1 */ -+ /* -+ * if ((imm < 0 && rsh != 0xffffffff) || -+ * (imm >= 0 && rsh != 0)) -+ * t1 = 0 -+ */ -+ if (imm < 0) { -+ emit(ctx, addiu, rd, hi(rs), 1); /* rd = rsh + 1 */ -+ cmp = rd; -+ } else { /* imm >= 0 */ -+ cmp = hi(rs); -+ } -+ emit_movn_r(ctx, t1, MIPS_R_ZERO, cmp); /* t1 = 0 if cmp != 0 */ -+ -+ /* -+ * if (imm < 0) rd = rsh < -1 -+ * else rd = rsh != 0 -+ * rd = rd | t1 -+ */ -+ emit(ctx, slti, rd, hi(rs), imm < 0 ? -1 : 0); /* rd = rsh < hi(imm) */ -+ emit(ctx, or, rd, rd, t1); /* rd = rd | t1 */ -+} -+ -+/* Emulation of 64-bit(slt rd, rs, rt) */ -+static void emit_slt_r64(struct jit_context *ctx, u8 rd, -+ const u8 rs[], const u8 rt[]) -+{ -+ u8 t1 = MIPS_R_T7; -+ u8 t2 = MIPS_R_T8; -+ u8 t3 = MIPS_R_T9; -+ -+ /* -+ * if ((rs < 0) ^ (rt < 0)) t1 = rtl > 31 */ -+ emit_movn_r(ctx, t1, t2, rd); /* t1 = rd ? t2 : t1 */ -+ emit_movn_r(ctx, t1, MIPS_R_ZERO, t3); /* t1 = 0 if t3 != 0 */ -+ -+ /* rd = (rsh < rth) | t1 */ -+ emit(ctx, slt, rd, hi(rs), hi(rt)); /* rd = rsh = -0x7fff && imm <= 0x8000) { -+ emit(ctx, addiu, tmp, lo(dst), -imm); -+ } else if ((u32)imm <= 0xffff) { -+ emit(ctx, xori, tmp, lo(dst), imm); -+ } else { /* Register fallback */ -+ emit_mov_i(ctx, tmp, imm); -+ emit(ctx, xor, tmp, lo(dst), tmp); -+ } -+ if (imm < 0) { /* Compare sign extension */ -+ emit(ctx, addu, MIPS_R_T9, hi(dst), 1); -+ emit(ctx, or, tmp, tmp, MIPS_R_T9); -+ } else { /* Compare zero extension */ -+ emit(ctx, or, tmp, tmp, hi(dst)); -+ } -+ if (op == BPF_JEQ) -+ emit(ctx, beqz, tmp, off); -+ else /* BPF_JNE */ -+ emit(ctx, bnez, tmp, off); -+ break; -+ /* PC += off if dst & imm */ -+ /* PC += off if (dst & imm) == 0 (not in BPF, used for long jumps) */ -+ case BPF_JSET: -+ case JIT_JNSET: -+ if ((u32)imm <= 0xffff) { -+ emit(ctx, andi, tmp, lo(dst), imm); -+ } else { /* Register fallback */ -+ emit_mov_i(ctx, tmp, imm); -+ emit(ctx, and, tmp, lo(dst), tmp); -+ } -+ if (imm < 0) /* Sign-extension pulls in high word */ -+ emit(ctx, or, tmp, tmp, hi(dst)); -+ if (op == BPF_JSET) -+ emit(ctx, bnez, tmp, off); -+ else /* JIT_JNSET */ -+ emit(ctx, beqz, tmp, off); -+ break; -+ /* PC += off if dst > imm */ -+ case BPF_JGT: -+ emit_sltiu_r64(ctx, tmp, dst, (s64)imm + 1); -+ emit(ctx, beqz, tmp, off); -+ break; -+ /* PC += off if dst >= imm */ -+ case BPF_JGE: -+ emit_sltiu_r64(ctx, tmp, dst, imm); -+ emit(ctx, beqz, tmp, off); -+ break; -+ /* PC += off if dst < imm */ -+ case BPF_JLT: -+ emit_sltiu_r64(ctx, tmp, dst, imm); -+ emit(ctx, bnez, tmp, off); -+ break; -+ /* PC += off if dst <= imm */ -+ case BPF_JLE: -+ emit_sltiu_r64(ctx, tmp, dst, (s64)imm + 1); -+ emit(ctx, bnez, tmp, off); -+ break; -+ /* PC += off if dst > imm (signed) */ -+ case BPF_JSGT: -+ emit_slti_r64(ctx, tmp, dst, (s64)imm + 1); -+ emit(ctx, beqz, tmp, off); -+ break; -+ /* PC += off if dst >= imm (signed) */ -+ case BPF_JSGE: -+ emit_slti_r64(ctx, tmp, dst, imm); -+ emit(ctx, beqz, tmp, off); -+ break; -+ /* PC += off if dst < imm (signed) */ -+ case BPF_JSLT: -+ emit_slti_r64(ctx, tmp, dst, imm); -+ emit(ctx, bnez, tmp, off); -+ break; -+ /* PC += off if dst <= imm (signed) */ -+ case BPF_JSLE: -+ emit_slti_r64(ctx, tmp, dst, (s64)imm + 1); -+ emit(ctx, bnez, tmp, off); -+ break; -+ } -+} -+ -+/* Jump register (64-bit) */ -+static void emit_jmp_r64(struct jit_context *ctx, -+ const u8 dst[], const u8 src[], s32 off, u8 op) -+{ -+ u8 t1 = MIPS_R_T6; -+ u8 t2 = MIPS_R_T7; -+ -+ switch (op) { -+ /* No-op, used internally for branch optimization */ -+ case JIT_JNOP: -+ break; -+ /* PC += off if dst == src */ -+ /* PC += off if dst != src */ -+ case BPF_JEQ: -+ case BPF_JNE: -+ emit(ctx, subu, t1, lo(dst), lo(src)); -+ emit(ctx, subu, t2, hi(dst), hi(src)); -+ emit(ctx, or, t1, t1, t2); -+ if (op == BPF_JEQ) -+ emit(ctx, beqz, t1, off); -+ else /* BPF_JNE */ -+ emit(ctx, bnez, t1, off); -+ break; -+ /* PC += off if dst & src */ -+ /* PC += off if (dst & imm) == 0 (not in BPF, used for long jumps) */ -+ case BPF_JSET: -+ case JIT_JNSET: -+ emit(ctx, and, t1, lo(dst), lo(src)); -+ emit(ctx, and, t2, hi(dst), hi(src)); -+ emit(ctx, or, t1, t1, t2); -+ if (op == BPF_JSET) -+ emit(ctx, bnez, t1, off); -+ else /* JIT_JNSET */ -+ emit(ctx, beqz, t1, off); -+ break; -+ /* PC += off if dst > src */ -+ case BPF_JGT: -+ emit_sltu_r64(ctx, t1, src, dst); -+ emit(ctx, bnez, t1, off); -+ break; -+ /* PC += off if dst >= src */ -+ case BPF_JGE: -+ emit_sltu_r64(ctx, t1, dst, src); -+ emit(ctx, beqz, t1, off); -+ break; -+ /* PC += off if dst < src */ -+ case BPF_JLT: -+ emit_sltu_r64(ctx, t1, dst, src); -+ emit(ctx, bnez, t1, off); -+ break; -+ /* PC += off if dst <= src */ -+ case BPF_JLE: -+ emit_sltu_r64(ctx, t1, src, dst); -+ emit(ctx, beqz, t1, off); -+ break; -+ /* PC += off if dst > src (signed) */ -+ case BPF_JSGT: -+ emit_slt_r64(ctx, t1, src, dst); -+ emit(ctx, bnez, t1, off); -+ break; -+ /* PC += off if dst >= src (signed) */ -+ case BPF_JSGE: -+ emit_slt_r64(ctx, t1, dst, src); -+ emit(ctx, beqz, t1, off); -+ break; -+ /* PC += off if dst < src (signed) */ -+ case BPF_JSLT: -+ emit_slt_r64(ctx, t1, dst, src); -+ emit(ctx, bnez, t1, off); -+ break; -+ /* PC += off if dst <= src (signed) */ -+ case BPF_JSLE: -+ emit_slt_r64(ctx, t1, src, dst); -+ emit(ctx, beqz, t1, off); -+ break; -+ } -+} -+ -+/* Function call */ -+static int emit_call(struct jit_context *ctx, const struct bpf_insn *insn) -+{ -+ bool fixed; -+ u64 addr; -+ -+ /* Decode the call address */ -+ if (bpf_jit_get_func_addr(ctx->program, insn, false, -+ &addr, &fixed) < 0) -+ return -1; -+ if (!fixed) -+ return -1; -+ -+ /* Push stack arguments */ -+ push_regs(ctx, JIT_STACK_REGS, 0, JIT_RESERVED_STACK); -+ -+ /* Emit function call */ -+ emit_mov_i(ctx, MIPS_R_T9, addr); -+ emit(ctx, jalr, MIPS_R_RA, MIPS_R_T9); -+ emit(ctx, nop); /* Delay slot */ -+ -+ clobber_reg(ctx, MIPS_R_RA); -+ clobber_reg(ctx, MIPS_R_V0); -+ clobber_reg(ctx, MIPS_R_V1); -+ return 0; -+} -+ -+/* Function tail call */ -+static int emit_tail_call(struct jit_context *ctx) -+{ -+ u8 ary = lo(bpf2mips32[BPF_REG_2]); -+ u8 ind = lo(bpf2mips32[BPF_REG_3]); -+ u8 t1 = MIPS_R_T8; -+ u8 t2 = MIPS_R_T9; -+ int off; -+ -+ /* -+ * Tail call: -+ * eBPF R1 - function argument (context ptr), passed in a0-a1 -+ * eBPF R2 - ptr to object with array of function entry points -+ * eBPF R3 - array index of function to be called -+ * stack[sz] - remaining tail call count, initialized in prologue -+ */ -+ -+ /* if (ind >= ary->map.max_entries) goto out */ -+ off = offsetof(struct bpf_array, map.max_entries); -+ if (off > 0x7fff) -+ return -1; -+ emit(ctx, lw, t1, off, ary); /* t1 = ary->map.max_entries*/ -+ emit_load_delay(ctx); /* Load delay slot */ -+ emit(ctx, sltu, t1, ind, t1); /* t1 = ind < t1 */ -+ emit(ctx, beqz, t1, get_offset(ctx, 1)); /* PC += off(1) if t1 == 0 */ -+ /* (next insn delay slot) */ -+ /* if (TCC-- <= 0) goto out */ -+ emit(ctx, lw, t2, ctx->stack_size, MIPS_R_SP); /* t2 = *(SP + size) */ -+ emit_load_delay(ctx); /* Load delay slot */ -+ emit(ctx, blez, t2, get_offset(ctx, 1)); /* PC += off(1) if t2 < 0 */ -+ emit(ctx, addiu, t2, t2, -1); /* t2-- (delay slot) */ -+ emit(ctx, sw, t2, ctx->stack_size, MIPS_R_SP); /* *(SP + size) = t2 */ -+ -+ /* prog = ary->ptrs[ind] */ -+ off = offsetof(struct bpf_array, ptrs); -+ if (off > 0x7fff) -+ return -1; -+ emit(ctx, sll, t1, ind, 2); /* t1 = ind << 2 */ -+ emit(ctx, addu, t1, t1, ary); /* t1 += ary */ -+ emit(ctx, lw, t2, off, t1); /* t2 = *(t1 + off) */ -+ emit_load_delay(ctx); /* Load delay slot */ -+ -+ /* if (prog == 0) goto out */ -+ emit(ctx, beqz, t2, get_offset(ctx, 1)); /* PC += off(1) if t2 == 0 */ -+ emit(ctx, nop); /* Delay slot */ -+ -+ /* func = prog->bpf_func + 8 (prologue skip offset) */ -+ off = offsetof(struct bpf_prog, bpf_func); -+ if (off > 0x7fff) -+ return -1; -+ emit(ctx, lw, t1, off, t2); /* t1 = *(t2 + off) */ -+ emit_load_delay(ctx); /* Load delay slot */ -+ emit(ctx, addiu, t1, t1, JIT_TCALL_SKIP); /* t1 += skip (8 or 12) */ -+ -+ /* goto func */ -+ build_epilogue(ctx, t1); -+ return 0; -+} -+ -+/* -+ * Stack frame layout for a JITed program (stack grows down). -+ * -+ * Higher address : Caller's stack frame : -+ * :----------------------------: -+ * : 64-bit eBPF args r3-r5 : -+ * :----------------------------: -+ * : Reserved / tail call count : -+ * +============================+ <--- MIPS sp before call -+ * | Callee-saved registers, | -+ * | including RA and FP | -+ * +----------------------------+ <--- eBPF FP (MIPS zero,fp) -+ * | Local eBPF variables | -+ * | allocated by program | -+ * +----------------------------+ -+ * | Reserved for caller-saved | -+ * | registers | -+ * +----------------------------+ -+ * | Reserved for 64-bit eBPF | -+ * | args r3-r5 & args passed | -+ * | on stack in kernel calls | -+ * Lower address +============================+ <--- MIPS sp -+ */ -+ -+/* Build program prologue to set up the stack and registers */ -+void build_prologue(struct jit_context *ctx) -+{ -+ const u8 *r1 = bpf2mips32[BPF_REG_1]; -+ const u8 *fp = bpf2mips32[BPF_REG_FP]; -+ int stack, saved, locals, reserved; -+ -+ /* -+ * The first two instructions initialize TCC in the reserved (for us) -+ * 16-byte area in the parent's stack frame. On a tail call, the -+ * calling function jumps into the prologue after these instructions. -+ */ -+ emit(ctx, ori, MIPS_R_T9, MIPS_R_ZERO, -+ min(MAX_TAIL_CALL_CNT + 1, 0xffff)); -+ emit(ctx, sw, MIPS_R_T9, 0, MIPS_R_SP); -+ -+ /* -+ * Register eBPF R1 contains the 32-bit context pointer argument. -+ * A 32-bit argument is always passed in MIPS register a0, regardless -+ * of CPU endianness. Initialize R1 accordingly and zero-extend. -+ */ -+#ifdef __BIG_ENDIAN -+ emit(ctx, move, lo(r1), MIPS_R_A0); -+#endif -+ -+ /* === Entry-point for tail calls === */ -+ -+ /* Zero-extend the 32-bit argument */ -+ emit(ctx, move, hi(r1), MIPS_R_ZERO); -+ -+ /* If the eBPF frame pointer was accessed it must be saved */ -+ if (ctx->accessed & BIT(BPF_REG_FP)) -+ clobber_reg64(ctx, fp); -+ -+ /* Compute the stack space needed for callee-saved registers */ -+ saved = hweight32(ctx->clobbered & JIT_CALLEE_REGS) * sizeof(u32); -+ saved = ALIGN(saved, MIPS_STACK_ALIGNMENT); -+ -+ /* Stack space used by eBPF program local data */ -+ locals = ALIGN(ctx->program->aux->stack_depth, MIPS_STACK_ALIGNMENT); -+ -+ /* -+ * If we are emitting function calls, reserve extra stack space for -+ * caller-saved registers and function arguments passed on the stack. -+ * The required space is computed automatically during resource -+ * usage discovery (pass 1). -+ */ -+ reserved = ctx->stack_used; -+ -+ /* Allocate the stack frame */ -+ stack = ALIGN(saved + locals + reserved, MIPS_STACK_ALIGNMENT); -+ emit(ctx, addiu, MIPS_R_SP, MIPS_R_SP, -stack); -+ -+ /* Store callee-saved registers on stack */ -+ push_regs(ctx, ctx->clobbered & JIT_CALLEE_REGS, 0, stack - saved); -+ -+ /* Initialize the eBPF frame pointer if accessed */ -+ if (ctx->accessed & BIT(BPF_REG_FP)) -+ emit(ctx, addiu, lo(fp), MIPS_R_SP, stack - saved); -+ -+ ctx->saved_size = saved; -+ ctx->stack_size = stack; -+} -+ -+/* Build the program epilogue to restore the stack and registers */ -+void build_epilogue(struct jit_context *ctx, int dest_reg) -+{ -+ /* Restore callee-saved registers from stack */ -+ pop_regs(ctx, ctx->clobbered & JIT_CALLEE_REGS, 0, -+ ctx->stack_size - ctx->saved_size); -+ /* -+ * A 32-bit return value is always passed in MIPS register v0, -+ * but on big-endian targets the low part of R0 is mapped to v1. -+ */ -+#ifdef __BIG_ENDIAN -+ emit(ctx, move, MIPS_R_V0, MIPS_R_V1); -+#endif -+ -+ /* Jump to the return address and adjust the stack pointer */ -+ emit(ctx, jr, dest_reg); -+ emit(ctx, addiu, MIPS_R_SP, MIPS_R_SP, ctx->stack_size); -+} -+ -+/* Build one eBPF instruction */ -+int build_insn(const struct bpf_insn *insn, struct jit_context *ctx) -+{ -+ const u8 *dst = bpf2mips32[insn->dst_reg]; -+ const u8 *src = bpf2mips32[insn->src_reg]; -+ const u8 *tmp = bpf2mips32[JIT_REG_TMP]; -+ u8 code = insn->code; -+ s16 off = insn->off; -+ s32 imm = insn->imm; -+ s32 val, rel; -+ u8 alu, jmp; -+ -+ switch (code) { -+ /* ALU operations */ -+ /* dst = imm */ -+ case BPF_ALU | BPF_MOV | BPF_K: -+ emit_mov_i(ctx, lo(dst), imm); -+ emit_zext_ver(ctx, dst); -+ break; -+ /* dst = src */ -+ case BPF_ALU | BPF_MOV | BPF_X: -+ if (imm == 1) { -+ /* Special mov32 for zext */ -+ emit_mov_i(ctx, hi(dst), 0); -+ } else { -+ emit_mov_r(ctx, lo(dst), lo(src)); -+ emit_zext_ver(ctx, dst); -+ } -+ break; -+ /* dst = -dst */ -+ case BPF_ALU | BPF_NEG: -+ emit_alu_i(ctx, lo(dst), 0, BPF_NEG); -+ emit_zext_ver(ctx, dst); -+ break; -+ /* dst = dst & imm */ -+ /* dst = dst | imm */ -+ /* dst = dst ^ imm */ -+ /* dst = dst << imm */ -+ /* dst = dst >> imm */ -+ /* dst = dst >> imm (arithmetic) */ -+ /* dst = dst + imm */ -+ /* dst = dst - imm */ -+ /* dst = dst * imm */ -+ /* dst = dst / imm */ -+ /* dst = dst % imm */ -+ case BPF_ALU | BPF_OR | BPF_K: -+ case BPF_ALU | BPF_AND | BPF_K: -+ case BPF_ALU | BPF_XOR | BPF_K: -+ case BPF_ALU | BPF_LSH | BPF_K: -+ case BPF_ALU | BPF_RSH | BPF_K: -+ case BPF_ALU | BPF_ARSH | BPF_K: -+ case BPF_ALU | BPF_ADD | BPF_K: -+ case BPF_ALU | BPF_SUB | BPF_K: -+ case BPF_ALU | BPF_MUL | BPF_K: -+ case BPF_ALU | BPF_DIV | BPF_K: -+ case BPF_ALU | BPF_MOD | BPF_K: -+ if (!valid_alu_i(BPF_OP(code), imm)) { -+ emit_mov_i(ctx, MIPS_R_T6, imm); -+ emit_alu_r(ctx, lo(dst), MIPS_R_T6, BPF_OP(code)); -+ } else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) { -+ emit_alu_i(ctx, lo(dst), val, alu); -+ } -+ emit_zext_ver(ctx, dst); -+ break; -+ /* dst = dst & src */ -+ /* dst = dst | src */ -+ /* dst = dst ^ src */ -+ /* dst = dst << src */ -+ /* dst = dst >> src */ -+ /* dst = dst >> src (arithmetic) */ -+ /* dst = dst + src */ -+ /* dst = dst - src */ -+ /* dst = dst * src */ -+ /* dst = dst / src */ -+ /* dst = dst % src */ -+ case BPF_ALU | BPF_AND | BPF_X: -+ case BPF_ALU | BPF_OR | BPF_X: -+ case BPF_ALU | BPF_XOR | BPF_X: -+ case BPF_ALU | BPF_LSH | BPF_X: -+ case BPF_ALU | BPF_RSH | BPF_X: -+ case BPF_ALU | BPF_ARSH | BPF_X: -+ case BPF_ALU | BPF_ADD | BPF_X: -+ case BPF_ALU | BPF_SUB | BPF_X: -+ case BPF_ALU | BPF_MUL | BPF_X: -+ case BPF_ALU | BPF_DIV | BPF_X: -+ case BPF_ALU | BPF_MOD | BPF_X: -+ emit_alu_r(ctx, lo(dst), lo(src), BPF_OP(code)); -+ emit_zext_ver(ctx, dst); -+ break; -+ /* dst = imm (64-bit) */ -+ case BPF_ALU64 | BPF_MOV | BPF_K: -+ emit_mov_se_i64(ctx, dst, imm); -+ break; -+ /* dst = src (64-bit) */ -+ case BPF_ALU64 | BPF_MOV | BPF_X: -+ emit_mov_r(ctx, lo(dst), lo(src)); -+ emit_mov_r(ctx, hi(dst), hi(src)); -+ break; -+ /* dst = -dst (64-bit) */ -+ case BPF_ALU64 | BPF_NEG: -+ emit_neg_i64(ctx, dst); -+ break; -+ /* dst = dst & imm (64-bit) */ -+ case BPF_ALU64 | BPF_AND | BPF_K: -+ emit_alu_i64(ctx, dst, imm, BPF_OP(code)); -+ break; -+ /* dst = dst | imm (64-bit) */ -+ /* dst = dst ^ imm (64-bit) */ -+ /* dst = dst + imm (64-bit) */ -+ /* dst = dst - imm (64-bit) */ -+ case BPF_ALU64 | BPF_OR | BPF_K: -+ case BPF_ALU64 | BPF_XOR | BPF_K: -+ case BPF_ALU64 | BPF_ADD | BPF_K: -+ case BPF_ALU64 | BPF_SUB | BPF_K: -+ if (imm) -+ emit_alu_i64(ctx, dst, imm, BPF_OP(code)); -+ break; -+ /* dst = dst << imm (64-bit) */ -+ /* dst = dst >> imm (64-bit) */ -+ /* dst = dst >> imm (64-bit, arithmetic) */ -+ case BPF_ALU64 | BPF_LSH | BPF_K: -+ case BPF_ALU64 | BPF_RSH | BPF_K: -+ case BPF_ALU64 | BPF_ARSH | BPF_K: -+ if (imm) -+ emit_shift_i64(ctx, dst, imm, BPF_OP(code)); -+ break; -+ /* dst = dst * imm (64-bit) */ -+ case BPF_ALU64 | BPF_MUL | BPF_K: -+ emit_mul_i64(ctx, dst, imm); -+ break; -+ /* dst = dst / imm (64-bit) */ -+ /* dst = dst % imm (64-bit) */ -+ case BPF_ALU64 | BPF_DIV | BPF_K: -+ case BPF_ALU64 | BPF_MOD | BPF_K: -+ /* -+ * Sign-extend the immediate value into a temporary register, -+ * and then do the operation on this register. -+ */ -+ emit_mov_se_i64(ctx, tmp, imm); -+ emit_divmod_r64(ctx, dst, tmp, BPF_OP(code)); -+ break; -+ /* dst = dst & src (64-bit) */ -+ /* dst = dst | src (64-bit) */ -+ /* dst = dst ^ src (64-bit) */ -+ /* dst = dst + src (64-bit) */ -+ /* dst = dst - src (64-bit) */ -+ case BPF_ALU64 | BPF_AND | BPF_X: -+ case BPF_ALU64 | BPF_OR | BPF_X: -+ case BPF_ALU64 | BPF_XOR | BPF_X: -+ case BPF_ALU64 | BPF_ADD | BPF_X: -+ case BPF_ALU64 | BPF_SUB | BPF_X: -+ emit_alu_r64(ctx, dst, src, BPF_OP(code)); -+ break; -+ /* dst = dst << src (64-bit) */ -+ /* dst = dst >> src (64-bit) */ -+ /* dst = dst >> src (64-bit, arithmetic) */ -+ case BPF_ALU64 | BPF_LSH | BPF_X: -+ case BPF_ALU64 | BPF_RSH | BPF_X: -+ case BPF_ALU64 | BPF_ARSH | BPF_X: -+ emit_shift_r64(ctx, dst, lo(src), BPF_OP(code)); -+ break; -+ /* dst = dst * src (64-bit) */ -+ case BPF_ALU64 | BPF_MUL | BPF_X: -+ emit_mul_r64(ctx, dst, src); -+ break; -+ /* dst = dst / src (64-bit) */ -+ /* dst = dst % src (64-bit) */ -+ case BPF_ALU64 | BPF_DIV | BPF_X: -+ case BPF_ALU64 | BPF_MOD | BPF_X: -+ emit_divmod_r64(ctx, dst, src, BPF_OP(code)); -+ break; -+ /* dst = htole(dst) */ -+ /* dst = htobe(dst) */ -+ case BPF_ALU | BPF_END | BPF_FROM_LE: -+ case BPF_ALU | BPF_END | BPF_FROM_BE: -+ if (BPF_SRC(code) == -+#ifdef __BIG_ENDIAN -+ BPF_FROM_LE -+#else -+ BPF_FROM_BE -+#endif -+ ) -+ emit_bswap_r64(ctx, dst, imm); -+ else -+ emit_trunc_r64(ctx, dst, imm); -+ break; -+ /* dst = imm64 */ -+ case BPF_LD | BPF_IMM | BPF_DW: -+ emit_mov_i(ctx, lo(dst), imm); -+ emit_mov_i(ctx, hi(dst), insn[1].imm); -+ return 1; -+ /* LDX: dst = *(size *)(src + off) */ -+ case BPF_LDX | BPF_MEM | BPF_W: -+ case BPF_LDX | BPF_MEM | BPF_H: -+ case BPF_LDX | BPF_MEM | BPF_B: -+ case BPF_LDX | BPF_MEM | BPF_DW: -+ emit_ldx(ctx, dst, lo(src), off, BPF_SIZE(code)); -+ break; -+ /* ST: *(size *)(dst + off) = imm */ -+ case BPF_ST | BPF_MEM | BPF_W: -+ case BPF_ST | BPF_MEM | BPF_H: -+ case BPF_ST | BPF_MEM | BPF_B: -+ case BPF_ST | BPF_MEM | BPF_DW: -+ switch (BPF_SIZE(code)) { -+ case BPF_DW: -+ /* Sign-extend immediate value into temporary reg */ -+ emit_mov_se_i64(ctx, tmp, imm); -+ break; -+ case BPF_W: -+ case BPF_H: -+ case BPF_B: -+ emit_mov_i(ctx, lo(tmp), imm); -+ break; -+ } -+ emit_stx(ctx, lo(dst), tmp, off, BPF_SIZE(code)); -+ break; -+ /* STX: *(size *)(dst + off) = src */ -+ case BPF_STX | BPF_MEM | BPF_W: -+ case BPF_STX | BPF_MEM | BPF_H: -+ case BPF_STX | BPF_MEM | BPF_B: -+ case BPF_STX | BPF_MEM | BPF_DW: -+ emit_stx(ctx, lo(dst), src, off, BPF_SIZE(code)); -+ break; -+ /* Speculation barrier */ -+ case BPF_ST | BPF_NOSPEC: -+ break; -+ /* Atomics */ -+ case BPF_STX | BPF_XADD | BPF_W: -+ switch (imm) { -+ case BPF_ADD: -+ case BPF_AND: -+ case BPF_OR: -+ case BPF_XOR: -+ if (cpu_has_llsc) -+ emit_atomic_r(ctx, lo(dst), lo(src), off, imm); -+ else /* Non-ll/sc fallback */ -+ emit_atomic_r32(ctx, lo(dst), lo(src), -+ off, imm); -+ break; -+ default: -+ goto notyet; -+ } -+ break; -+ /* Atomics (64-bit) */ -+ case BPF_STX | BPF_XADD | BPF_DW: -+ switch (imm) { -+ case BPF_ADD: -+ case BPF_AND: -+ case BPF_OR: -+ case BPF_XOR: -+ emit_atomic_r64(ctx, lo(dst), src, off, imm); -+ break; -+ default: -+ goto notyet; -+ } -+ break; -+ /* PC += off if dst == src */ -+ /* PC += off if dst != src */ -+ /* PC += off if dst & src */ -+ /* PC += off if dst > src */ -+ /* PC += off if dst >= src */ -+ /* PC += off if dst < src */ -+ /* PC += off if dst <= src */ -+ /* PC += off if dst > src (signed) */ -+ /* PC += off if dst >= src (signed) */ -+ /* PC += off if dst < src (signed) */ -+ /* PC += off if dst <= src (signed) */ -+ case BPF_JMP32 | BPF_JEQ | BPF_X: -+ case BPF_JMP32 | BPF_JNE | BPF_X: -+ case BPF_JMP32 | BPF_JSET | BPF_X: -+ case BPF_JMP32 | BPF_JGT | BPF_X: -+ case BPF_JMP32 | BPF_JGE | BPF_X: -+ case BPF_JMP32 | BPF_JLT | BPF_X: -+ case BPF_JMP32 | BPF_JLE | BPF_X: -+ case BPF_JMP32 | BPF_JSGT | BPF_X: -+ case BPF_JMP32 | BPF_JSGE | BPF_X: -+ case BPF_JMP32 | BPF_JSLT | BPF_X: -+ case BPF_JMP32 | BPF_JSLE | BPF_X: -+ if (off == 0) -+ break; -+ setup_jmp_r(ctx, dst == src, BPF_OP(code), off, &jmp, &rel); -+ emit_jmp_r(ctx, lo(dst), lo(src), rel, jmp); -+ if (finish_jmp(ctx, jmp, off) < 0) -+ goto toofar; -+ break; -+ /* PC += off if dst == imm */ -+ /* PC += off if dst != imm */ -+ /* PC += off if dst & imm */ -+ /* PC += off if dst > imm */ -+ /* PC += off if dst >= imm */ -+ /* PC += off if dst < imm */ -+ /* PC += off if dst <= imm */ -+ /* PC += off if dst > imm (signed) */ -+ /* PC += off if dst >= imm (signed) */ -+ /* PC += off if dst < imm (signed) */ -+ /* PC += off if dst <= imm (signed) */ -+ case BPF_JMP32 | BPF_JEQ | BPF_K: -+ case BPF_JMP32 | BPF_JNE | BPF_K: -+ case BPF_JMP32 | BPF_JSET | BPF_K: -+ case BPF_JMP32 | BPF_JGT | BPF_K: -+ case BPF_JMP32 | BPF_JGE | BPF_K: -+ case BPF_JMP32 | BPF_JLT | BPF_K: -+ case BPF_JMP32 | BPF_JLE | BPF_K: -+ case BPF_JMP32 | BPF_JSGT | BPF_K: -+ case BPF_JMP32 | BPF_JSGE | BPF_K: -+ case BPF_JMP32 | BPF_JSLT | BPF_K: -+ case BPF_JMP32 | BPF_JSLE | BPF_K: -+ if (off == 0) -+ break; -+ setup_jmp_i(ctx, imm, 32, BPF_OP(code), off, &jmp, &rel); -+ if (valid_jmp_i(jmp, imm)) { -+ emit_jmp_i(ctx, lo(dst), imm, rel, jmp); -+ } else { -+ /* Move large immediate to register */ -+ emit_mov_i(ctx, MIPS_R_T6, imm); -+ emit_jmp_r(ctx, lo(dst), MIPS_R_T6, rel, jmp); -+ } -+ if (finish_jmp(ctx, jmp, off) < 0) -+ goto toofar; -+ break; -+ /* PC += off if dst == src */ -+ /* PC += off if dst != src */ -+ /* PC += off if dst & src */ -+ /* PC += off if dst > src */ -+ /* PC += off if dst >= src */ -+ /* PC += off if dst < src */ -+ /* PC += off if dst <= src */ -+ /* PC += off if dst > src (signed) */ -+ /* PC += off if dst >= src (signed) */ -+ /* PC += off if dst < src (signed) */ -+ /* PC += off if dst <= src (signed) */ -+ case BPF_JMP | BPF_JEQ | BPF_X: -+ case BPF_JMP | BPF_JNE | BPF_X: -+ case BPF_JMP | BPF_JSET | BPF_X: -+ case BPF_JMP | BPF_JGT | BPF_X: -+ case BPF_JMP | BPF_JGE | BPF_X: -+ case BPF_JMP | BPF_JLT | BPF_X: -+ case BPF_JMP | BPF_JLE | BPF_X: -+ case BPF_JMP | BPF_JSGT | BPF_X: -+ case BPF_JMP | BPF_JSGE | BPF_X: -+ case BPF_JMP | BPF_JSLT | BPF_X: -+ case BPF_JMP | BPF_JSLE | BPF_X: -+ if (off == 0) -+ break; -+ setup_jmp_r(ctx, dst == src, BPF_OP(code), off, &jmp, &rel); -+ emit_jmp_r64(ctx, dst, src, rel, jmp); -+ if (finish_jmp(ctx, jmp, off) < 0) -+ goto toofar; -+ break; -+ /* PC += off if dst == imm */ -+ /* PC += off if dst != imm */ -+ /* PC += off if dst & imm */ -+ /* PC += off if dst > imm */ -+ /* PC += off if dst >= imm */ -+ /* PC += off if dst < imm */ -+ /* PC += off if dst <= imm */ -+ /* PC += off if dst > imm (signed) */ -+ /* PC += off if dst >= imm (signed) */ -+ /* PC += off if dst < imm (signed) */ -+ /* PC += off if dst <= imm (signed) */ -+ case BPF_JMP | BPF_JEQ | BPF_K: -+ case BPF_JMP | BPF_JNE | BPF_K: -+ case BPF_JMP | BPF_JSET | BPF_K: -+ case BPF_JMP | BPF_JGT | BPF_K: -+ case BPF_JMP | BPF_JGE | BPF_K: -+ case BPF_JMP | BPF_JLT | BPF_K: -+ case BPF_JMP | BPF_JLE | BPF_K: -+ case BPF_JMP | BPF_JSGT | BPF_K: -+ case BPF_JMP | BPF_JSGE | BPF_K: -+ case BPF_JMP | BPF_JSLT | BPF_K: -+ case BPF_JMP | BPF_JSLE | BPF_K: -+ if (off == 0) -+ break; -+ setup_jmp_i(ctx, imm, 64, BPF_OP(code), off, &jmp, &rel); -+ emit_jmp_i64(ctx, dst, imm, rel, jmp); -+ if (finish_jmp(ctx, jmp, off) < 0) -+ goto toofar; -+ break; -+ /* PC += off */ -+ case BPF_JMP | BPF_JA: -+ if (off == 0) -+ break; -+ if (emit_ja(ctx, off) < 0) -+ goto toofar; -+ break; -+ /* Tail call */ -+ case BPF_JMP | BPF_TAIL_CALL: -+ if (emit_tail_call(ctx) < 0) -+ goto invalid; -+ break; -+ /* Function call */ -+ case BPF_JMP | BPF_CALL: -+ if (emit_call(ctx, insn) < 0) -+ goto invalid; -+ break; -+ /* Function return */ -+ case BPF_JMP | BPF_EXIT: -+ /* -+ * Optimization: when last instruction is EXIT -+ * simply continue to epilogue. -+ */ -+ if (ctx->bpf_index == ctx->program->len - 1) -+ break; -+ if (emit_exit(ctx) < 0) -+ goto toofar; -+ break; -+ -+ default: -+invalid: -+ pr_err_once("unknown opcode %02x\n", code); -+ return -EINVAL; -+notyet: -+ pr_info_once("*** NOT YET: opcode %02x ***\n", code); -+ return -EFAULT; -+toofar: -+ pr_info_once("*** TOO FAR: jump at %u opcode %02x ***\n", -+ ctx->bpf_index, code); -+ return -E2BIG; -+ } -+ return 0; -+} diff --git a/target/linux/generic/backport-5.15/050-v5.16-03-mips-bpf-Add-new-eBPF-JIT-for-64-bit-MIPS.patch b/target/linux/generic/backport-5.15/050-v5.16-03-mips-bpf-Add-new-eBPF-JIT-for-64-bit-MIPS.patch deleted file mode 100644 index 38b46c0b765b97..00000000000000 --- a/target/linux/generic/backport-5.15/050-v5.16-03-mips-bpf-Add-new-eBPF-JIT-for-64-bit-MIPS.patch +++ /dev/null @@ -1,1005 +0,0 @@ -From: Johan Almbladh -Date: Tue, 5 Oct 2021 18:54:05 +0200 -Subject: [PATCH] mips: bpf: Add new eBPF JIT for 64-bit MIPS - -This is an implementation on of an eBPF JIT for 64-bit MIPS III-V and -MIPS64r1-r6. It uses the same framework introduced by the 32-bit JIT. - -Signed-off-by: Johan Almbladh ---- - create mode 100644 arch/mips/net/bpf_jit_comp64.c - ---- /dev/null -+++ b/arch/mips/net/bpf_jit_comp64.c -@@ -0,0 +1,991 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Just-In-Time compiler for eBPF bytecode on MIPS. -+ * Implementation of JIT functions for 64-bit CPUs. -+ * -+ * Copyright (c) 2021 Anyfi Networks AB. -+ * Author: Johan Almbladh -+ * -+ * Based on code and ideas from -+ * Copyright (c) 2017 Cavium, Inc. -+ * Copyright (c) 2017 Shubham Bansal -+ * Copyright (c) 2011 Mircea Gherzan -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "bpf_jit_comp.h" -+ -+/* MIPS t0-t3 are not available in the n64 ABI */ -+#undef MIPS_R_T0 -+#undef MIPS_R_T1 -+#undef MIPS_R_T2 -+#undef MIPS_R_T3 -+ -+/* Stack is 16-byte aligned in n64 ABI */ -+#define MIPS_STACK_ALIGNMENT 16 -+ -+/* Extra 64-bit eBPF registers used by JIT */ -+#define JIT_REG_TC (MAX_BPF_JIT_REG + 0) -+#define JIT_REG_ZX (MAX_BPF_JIT_REG + 1) -+ -+/* Number of prologue bytes to skip when doing a tail call */ -+#define JIT_TCALL_SKIP 4 -+ -+/* Callee-saved CPU registers that the JIT must preserve */ -+#define JIT_CALLEE_REGS \ -+ (BIT(MIPS_R_S0) | \ -+ BIT(MIPS_R_S1) | \ -+ BIT(MIPS_R_S2) | \ -+ BIT(MIPS_R_S3) | \ -+ BIT(MIPS_R_S4) | \ -+ BIT(MIPS_R_S5) | \ -+ BIT(MIPS_R_S6) | \ -+ BIT(MIPS_R_S7) | \ -+ BIT(MIPS_R_GP) | \ -+ BIT(MIPS_R_FP) | \ -+ BIT(MIPS_R_RA)) -+ -+/* Caller-saved CPU registers available for JIT use */ -+#define JIT_CALLER_REGS \ -+ (BIT(MIPS_R_A5) | \ -+ BIT(MIPS_R_A6) | \ -+ BIT(MIPS_R_A7)) -+/* -+ * Mapping of 64-bit eBPF registers to 64-bit native MIPS registers. -+ * MIPS registers t4 - t7 may be used by the JIT as temporary registers. -+ * MIPS registers t8 - t9 are reserved for single-register common functions. -+ */ -+static const u8 bpf2mips64[] = { -+ /* Return value from in-kernel function, and exit value from eBPF */ -+ [BPF_REG_0] = MIPS_R_V0, -+ /* Arguments from eBPF program to in-kernel function */ -+ [BPF_REG_1] = MIPS_R_A0, -+ [BPF_REG_2] = MIPS_R_A1, -+ [BPF_REG_3] = MIPS_R_A2, -+ [BPF_REG_4] = MIPS_R_A3, -+ [BPF_REG_5] = MIPS_R_A4, -+ /* Callee-saved registers that in-kernel function will preserve */ -+ [BPF_REG_6] = MIPS_R_S0, -+ [BPF_REG_7] = MIPS_R_S1, -+ [BPF_REG_8] = MIPS_R_S2, -+ [BPF_REG_9] = MIPS_R_S3, -+ /* Read-only frame pointer to access the eBPF stack */ -+ [BPF_REG_FP] = MIPS_R_FP, -+ /* Temporary register for blinding constants */ -+ [BPF_REG_AX] = MIPS_R_AT, -+ /* Tail call count register, caller-saved */ -+ [JIT_REG_TC] = MIPS_R_A5, -+ /* Constant for register zero-extension */ -+ [JIT_REG_ZX] = MIPS_R_V1, -+}; -+ -+/* -+ * MIPS 32-bit operations on 64-bit registers generate a sign-extended -+ * result. However, the eBPF ISA mandates zero-extension, so we rely on the -+ * verifier to add that for us (emit_zext_ver). In addition, ALU arithmetic -+ * operations, right shift and byte swap require properly sign-extended -+ * operands or the result is unpredictable. We emit explicit sign-extensions -+ * in those cases. -+ */ -+ -+/* Sign extension */ -+static void emit_sext(struct jit_context *ctx, u8 dst, u8 src) -+{ -+ emit(ctx, sll, dst, src, 0); -+ clobber_reg(ctx, dst); -+} -+ -+/* Zero extension */ -+static void emit_zext(struct jit_context *ctx, u8 dst) -+{ -+ if (cpu_has_mips64r2 || cpu_has_mips64r6) { -+ emit(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32); -+ } else { -+ emit(ctx, and, dst, dst, bpf2mips64[JIT_REG_ZX]); -+ access_reg(ctx, JIT_REG_ZX); /* We need the ZX register */ -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* Zero extension, if verifier does not do it for us */ -+static void emit_zext_ver(struct jit_context *ctx, u8 dst) -+{ -+ if (!ctx->program->aux->verifier_zext) -+ emit_zext(ctx, dst); -+} -+ -+/* dst = imm (64-bit) */ -+static void emit_mov_i64(struct jit_context *ctx, u8 dst, u64 imm64) -+{ -+ if (imm64 >= 0xffffffffffff8000ULL || imm64 < 0x8000ULL) { -+ emit(ctx, daddiu, dst, MIPS_R_ZERO, (s16)imm64); -+ } else if (imm64 >= 0xffffffff80000000ULL || -+ (imm64 < 0x80000000 && imm64 > 0xffff)) { -+ emit(ctx, lui, dst, (s16)(imm64 >> 16)); -+ emit(ctx, ori, dst, dst, (u16)imm64 & 0xffff); -+ } else { -+ u8 acc = MIPS_R_ZERO; -+ int k; -+ -+ for (k = 0; k < 4; k++) { -+ u16 half = imm64 >> (48 - 16 * k); -+ -+ if (acc == dst) -+ emit(ctx, dsll, dst, dst, 16); -+ -+ if (half) { -+ emit(ctx, ori, dst, acc, half); -+ acc = dst; -+ } -+ } -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* ALU immediate operation (64-bit) */ -+static void emit_alu_i64(struct jit_context *ctx, u8 dst, s32 imm, u8 op) -+{ -+ switch (BPF_OP(op)) { -+ /* dst = dst | imm */ -+ case BPF_OR: -+ emit(ctx, ori, dst, dst, (u16)imm); -+ break; -+ /* dst = dst ^ imm */ -+ case BPF_XOR: -+ emit(ctx, xori, dst, dst, (u16)imm); -+ break; -+ /* dst = -dst */ -+ case BPF_NEG: -+ emit(ctx, dsubu, dst, MIPS_R_ZERO, dst); -+ break; -+ /* dst = dst << imm */ -+ case BPF_LSH: -+ emit(ctx, dsll_safe, dst, dst, imm); -+ break; -+ /* dst = dst >> imm */ -+ case BPF_RSH: -+ emit(ctx, dsrl_safe, dst, dst, imm); -+ break; -+ /* dst = dst >> imm (arithmetic) */ -+ case BPF_ARSH: -+ emit(ctx, dsra_safe, dst, dst, imm); -+ break; -+ /* dst = dst + imm */ -+ case BPF_ADD: -+ emit(ctx, daddiu, dst, dst, imm); -+ break; -+ /* dst = dst - imm */ -+ case BPF_SUB: -+ emit(ctx, daddiu, dst, dst, -imm); -+ break; -+ default: -+ /* Width-generic operations */ -+ emit_alu_i(ctx, dst, imm, op); -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* ALU register operation (64-bit) */ -+static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op) -+{ -+ switch (BPF_OP(op)) { -+ /* dst = dst << src */ -+ case BPF_LSH: -+ emit(ctx, dsllv, dst, dst, src); -+ break; -+ /* dst = dst >> src */ -+ case BPF_RSH: -+ emit(ctx, dsrlv, dst, dst, src); -+ break; -+ /* dst = dst >> src (arithmetic) */ -+ case BPF_ARSH: -+ emit(ctx, dsrav, dst, dst, src); -+ break; -+ /* dst = dst + src */ -+ case BPF_ADD: -+ emit(ctx, daddu, dst, dst, src); -+ break; -+ /* dst = dst - src */ -+ case BPF_SUB: -+ emit(ctx, dsubu, dst, dst, src); -+ break; -+ /* dst = dst * src */ -+ case BPF_MUL: -+ if (cpu_has_mips64r6) { -+ emit(ctx, dmulu, dst, dst, src); -+ } else { -+ emit(ctx, dmultu, dst, src); -+ emit(ctx, mflo, dst); -+ } -+ break; -+ /* dst = dst / src */ -+ case BPF_DIV: -+ if (cpu_has_mips64r6) { -+ emit(ctx, ddivu_r6, dst, dst, src); -+ } else { -+ emit(ctx, ddivu, dst, src); -+ emit(ctx, mflo, dst); -+ } -+ break; -+ /* dst = dst % src */ -+ case BPF_MOD: -+ if (cpu_has_mips64r6) { -+ emit(ctx, dmodu, dst, dst, src); -+ } else { -+ emit(ctx, ddivu, dst, src); -+ emit(ctx, mfhi, dst); -+ } -+ break; -+ default: -+ /* Width-generic operations */ -+ emit_alu_r(ctx, dst, src, op); -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* Swap sub words in a register double word */ -+static void emit_swap_r64(struct jit_context *ctx, u8 dst, u8 mask, u32 bits) -+{ -+ u8 tmp = MIPS_R_T9; -+ -+ emit(ctx, and, tmp, dst, mask); /* tmp = dst & mask */ -+ emit(ctx, dsll, tmp, tmp, bits); /* tmp = tmp << bits */ -+ emit(ctx, dsrl, dst, dst, bits); /* dst = dst >> bits */ -+ emit(ctx, and, dst, dst, mask); /* dst = dst & mask */ -+ emit(ctx, or, dst, dst, tmp); /* dst = dst | tmp */ -+} -+ -+/* Swap bytes and truncate a register double word, word or half word */ -+static void emit_bswap_r64(struct jit_context *ctx, u8 dst, u32 width) -+{ -+ switch (width) { -+ /* Swap bytes in a double word */ -+ case 64: -+ if (cpu_has_mips64r2 || cpu_has_mips64r6) { -+ emit(ctx, dsbh, dst, dst); -+ emit(ctx, dshd, dst, dst); -+ } else { -+ u8 t1 = MIPS_R_T6; -+ u8 t2 = MIPS_R_T7; -+ -+ emit(ctx, dsll32, t2, dst, 0); /* t2 = dst << 32 */ -+ emit(ctx, dsrl32, dst, dst, 0); /* dst = dst >> 32 */ -+ emit(ctx, or, dst, dst, t2); /* dst = dst | t2 */ -+ -+ emit(ctx, ori, t2, MIPS_R_ZERO, 0xffff); -+ emit(ctx, dsll32, t1, t2, 0); /* t1 = t2 << 32 */ -+ emit(ctx, or, t1, t1, t2); /* t1 = t1 | t2 */ -+ emit_swap_r64(ctx, dst, t1, 16);/* dst = swap16(dst) */ -+ -+ emit(ctx, lui, t2, 0xff); /* t2 = 0x00ff0000 */ -+ emit(ctx, ori, t2, t2, 0xff); /* t2 = t2 | 0x00ff */ -+ emit(ctx, dsll32, t1, t2, 0); /* t1 = t2 << 32 */ -+ emit(ctx, or, t1, t1, t2); /* t1 = t1 | t2 */ -+ emit_swap_r64(ctx, dst, t1, 8); /* dst = swap8(dst) */ -+ } -+ break; -+ /* Swap bytes in a half word */ -+ /* Swap bytes in a word */ -+ case 32: -+ case 16: -+ emit_sext(ctx, dst, dst); -+ emit_bswap_r(ctx, dst, width); -+ if (cpu_has_mips64r2 || cpu_has_mips64r6) -+ emit_zext(ctx, dst); -+ break; -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* Truncate a register double word, word or half word */ -+static void emit_trunc_r64(struct jit_context *ctx, u8 dst, u32 width) -+{ -+ switch (width) { -+ case 64: -+ break; -+ /* Zero-extend a word */ -+ case 32: -+ emit_zext(ctx, dst); -+ break; -+ /* Zero-extend a half word */ -+ case 16: -+ emit(ctx, andi, dst, dst, 0xffff); -+ break; -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* Load operation: dst = *(size*)(src + off) */ -+static void emit_ldx(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 size) -+{ -+ switch (size) { -+ /* Load a byte */ -+ case BPF_B: -+ emit(ctx, lbu, dst, off, src); -+ break; -+ /* Load a half word */ -+ case BPF_H: -+ emit(ctx, lhu, dst, off, src); -+ break; -+ /* Load a word */ -+ case BPF_W: -+ emit(ctx, lwu, dst, off, src); -+ break; -+ /* Load a double word */ -+ case BPF_DW: -+ emit(ctx, ld, dst, off, src); -+ break; -+ } -+ clobber_reg(ctx, dst); -+} -+ -+/* Store operation: *(size *)(dst + off) = src */ -+static void emit_stx(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 size) -+{ -+ switch (size) { -+ /* Store a byte */ -+ case BPF_B: -+ emit(ctx, sb, src, off, dst); -+ break; -+ /* Store a half word */ -+ case BPF_H: -+ emit(ctx, sh, src, off, dst); -+ break; -+ /* Store a word */ -+ case BPF_W: -+ emit(ctx, sw, src, off, dst); -+ break; -+ /* Store a double word */ -+ case BPF_DW: -+ emit(ctx, sd, src, off, dst); -+ break; -+ } -+} -+ -+/* Atomic read-modify-write */ -+static void emit_atomic_r64(struct jit_context *ctx, -+ u8 dst, u8 src, s16 off, u8 code) -+{ -+ u8 t1 = MIPS_R_T6; -+ u8 t2 = MIPS_R_T7; -+ -+ emit(ctx, lld, t1, off, dst); -+ switch (code) { -+ case BPF_ADD: -+ emit(ctx, daddu, t2, t1, src); -+ break; -+ case BPF_AND: -+ emit(ctx, and, t2, t1, src); -+ break; -+ case BPF_OR: -+ emit(ctx, or, t2, t1, src); -+ break; -+ case BPF_XOR: -+ emit(ctx, xor, t2, t1, src); -+ break; -+ } -+ emit(ctx, scd, t2, off, dst); -+ emit(ctx, beqz, t2, -16); -+ emit(ctx, nop); /* Delay slot */ -+} -+ -+/* Function call */ -+static int emit_call(struct jit_context *ctx, const struct bpf_insn *insn) -+{ -+ u8 zx = bpf2mips64[JIT_REG_ZX]; -+ u8 tmp = MIPS_R_T6; -+ bool fixed; -+ u64 addr; -+ -+ /* Decode the call address */ -+ if (bpf_jit_get_func_addr(ctx->program, insn, false, -+ &addr, &fixed) < 0) -+ return -1; -+ if (!fixed) -+ return -1; -+ -+ /* Push caller-saved registers on stack */ -+ push_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, 0, 0); -+ -+ /* Emit function call */ -+ emit_mov_i64(ctx, tmp, addr); -+ emit(ctx, jalr, MIPS_R_RA, tmp); -+ emit(ctx, nop); /* Delay slot */ -+ -+ /* Restore caller-saved registers */ -+ pop_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, 0, 0); -+ -+ /* Re-initialize the JIT zero-extension register if accessed */ -+ if (ctx->accessed & BIT(JIT_REG_ZX)) { -+ emit(ctx, daddiu, zx, MIPS_R_ZERO, -1); -+ emit(ctx, dsrl32, zx, zx, 0); -+ } -+ -+ clobber_reg(ctx, MIPS_R_RA); -+ clobber_reg(ctx, MIPS_R_V0); -+ clobber_reg(ctx, MIPS_R_V1); -+ return 0; -+} -+ -+/* Function tail call */ -+static int emit_tail_call(struct jit_context *ctx) -+{ -+ u8 ary = bpf2mips64[BPF_REG_2]; -+ u8 ind = bpf2mips64[BPF_REG_3]; -+ u8 tcc = bpf2mips64[JIT_REG_TC]; -+ u8 tmp = MIPS_R_T6; -+ int off; -+ -+ /* -+ * Tail call: -+ * eBPF R1 - function argument (context ptr), passed in a0-a1 -+ * eBPF R2 - ptr to object with array of function entry points -+ * eBPF R3 - array index of function to be called -+ */ -+ -+ /* if (ind >= ary->map.max_entries) goto out */ -+ off = offsetof(struct bpf_array, map.max_entries); -+ if (off > 0x7fff) -+ return -1; -+ emit(ctx, lwu, tmp, off, ary); /* tmp = ary->map.max_entrs*/ -+ emit(ctx, sltu, tmp, ind, tmp); /* tmp = ind < t1 */ -+ emit(ctx, beqz, tmp, get_offset(ctx, 1)); /* PC += off(1) if tmp == 0*/ -+ -+ /* if (--TCC < 0) goto out */ -+ emit(ctx, daddiu, tcc, tcc, -1); /* tcc-- (delay slot) */ -+ emit(ctx, bltz, tcc, get_offset(ctx, 1)); /* PC += off(1) if tcc < 0 */ -+ /* (next insn delay slot) */ -+ /* prog = ary->ptrs[ind] */ -+ off = offsetof(struct bpf_array, ptrs); -+ if (off > 0x7fff) -+ return -1; -+ emit(ctx, dsll, tmp, ind, 3); /* tmp = ind << 3 */ -+ emit(ctx, daddu, tmp, tmp, ary); /* tmp += ary */ -+ emit(ctx, ld, tmp, off, tmp); /* tmp = *(tmp + off) */ -+ -+ /* if (prog == 0) goto out */ -+ emit(ctx, beqz, tmp, get_offset(ctx, 1)); /* PC += off(1) if tmp == 0*/ -+ emit(ctx, nop); /* Delay slot */ -+ -+ /* func = prog->bpf_func + 8 (prologue skip offset) */ -+ off = offsetof(struct bpf_prog, bpf_func); -+ if (off > 0x7fff) -+ return -1; -+ emit(ctx, ld, tmp, off, tmp); /* tmp = *(tmp + off) */ -+ emit(ctx, daddiu, tmp, tmp, JIT_TCALL_SKIP); /* tmp += skip (4) */ -+ -+ /* goto func */ -+ build_epilogue(ctx, tmp); -+ access_reg(ctx, JIT_REG_TC); -+ return 0; -+} -+ -+/* -+ * Stack frame layout for a JITed program (stack grows down). -+ * -+ * Higher address : Previous stack frame : -+ * +===========================+ <--- MIPS sp before call -+ * | Callee-saved registers, | -+ * | including RA and FP | -+ * +---------------------------+ <--- eBPF FP (MIPS fp) -+ * | Local eBPF variables | -+ * | allocated by program | -+ * +---------------------------+ -+ * | Reserved for caller-saved | -+ * | registers | -+ * Lower address +===========================+ <--- MIPS sp -+ */ -+ -+/* Build program prologue to set up the stack and registers */ -+void build_prologue(struct jit_context *ctx) -+{ -+ u8 fp = bpf2mips64[BPF_REG_FP]; -+ u8 tc = bpf2mips64[JIT_REG_TC]; -+ u8 zx = bpf2mips64[JIT_REG_ZX]; -+ int stack, saved, locals, reserved; -+ -+ /* -+ * The first instruction initializes the tail call count register. -+ * On a tail call, the calling function jumps into the prologue -+ * after this instruction. -+ */ -+ emit(ctx, addiu, tc, MIPS_R_ZERO, min(MAX_TAIL_CALL_CNT + 1, 0xffff)); -+ -+ /* === Entry-point for tail calls === */ -+ -+ /* -+ * If the eBPF frame pointer and tail call count registers were -+ * accessed they must be preserved. Mark them as clobbered here -+ * to save and restore them on the stack as needed. -+ */ -+ if (ctx->accessed & BIT(BPF_REG_FP)) -+ clobber_reg(ctx, fp); -+ if (ctx->accessed & BIT(JIT_REG_TC)) -+ clobber_reg(ctx, tc); -+ if (ctx->accessed & BIT(JIT_REG_ZX)) -+ clobber_reg(ctx, zx); -+ -+ /* Compute the stack space needed for callee-saved registers */ -+ saved = hweight32(ctx->clobbered & JIT_CALLEE_REGS) * sizeof(u64); -+ saved = ALIGN(saved, MIPS_STACK_ALIGNMENT); -+ -+ /* Stack space used by eBPF program local data */ -+ locals = ALIGN(ctx->program->aux->stack_depth, MIPS_STACK_ALIGNMENT); -+ -+ /* -+ * If we are emitting function calls, reserve extra stack space for -+ * caller-saved registers needed by the JIT. The required space is -+ * computed automatically during resource usage discovery (pass 1). -+ */ -+ reserved = ctx->stack_used; -+ -+ /* Allocate the stack frame */ -+ stack = ALIGN(saved + locals + reserved, MIPS_STACK_ALIGNMENT); -+ if (stack) -+ emit(ctx, daddiu, MIPS_R_SP, MIPS_R_SP, -stack); -+ -+ /* Store callee-saved registers on stack */ -+ push_regs(ctx, ctx->clobbered & JIT_CALLEE_REGS, 0, stack - saved); -+ -+ /* Initialize the eBPF frame pointer if accessed */ -+ if (ctx->accessed & BIT(BPF_REG_FP)) -+ emit(ctx, daddiu, fp, MIPS_R_SP, stack - saved); -+ -+ /* Initialize the ePF JIT zero-extension register if accessed */ -+ if (ctx->accessed & BIT(JIT_REG_ZX)) { -+ emit(ctx, daddiu, zx, MIPS_R_ZERO, -1); -+ emit(ctx, dsrl32, zx, zx, 0); -+ } -+ -+ ctx->saved_size = saved; -+ ctx->stack_size = stack; -+} -+ -+/* Build the program epilogue to restore the stack and registers */ -+void build_epilogue(struct jit_context *ctx, int dest_reg) -+{ -+ /* Restore callee-saved registers from stack */ -+ pop_regs(ctx, ctx->clobbered & JIT_CALLEE_REGS, 0, -+ ctx->stack_size - ctx->saved_size); -+ -+ /* Release the stack frame */ -+ if (ctx->stack_size) -+ emit(ctx, daddiu, MIPS_R_SP, MIPS_R_SP, ctx->stack_size); -+ -+ /* Jump to return address and sign-extend the 32-bit return value */ -+ emit(ctx, jr, dest_reg); -+ emit(ctx, sll, MIPS_R_V0, MIPS_R_V0, 0); /* Delay slot */ -+} -+ -+/* Build one eBPF instruction */ -+int build_insn(const struct bpf_insn *insn, struct jit_context *ctx) -+{ -+ u8 dst = bpf2mips64[insn->dst_reg]; -+ u8 src = bpf2mips64[insn->src_reg]; -+ u8 code = insn->code; -+ s16 off = insn->off; -+ s32 imm = insn->imm; -+ s32 val, rel; -+ u8 alu, jmp; -+ -+ switch (code) { -+ /* ALU operations */ -+ /* dst = imm */ -+ case BPF_ALU | BPF_MOV | BPF_K: -+ emit_mov_i(ctx, dst, imm); -+ emit_zext_ver(ctx, dst); -+ break; -+ /* dst = src */ -+ case BPF_ALU | BPF_MOV | BPF_X: -+ if (imm == 1) { -+ /* Special mov32 for zext */ -+ emit_zext(ctx, dst); -+ } else { -+ emit_mov_r(ctx, dst, src); -+ emit_zext_ver(ctx, dst); -+ } -+ break; -+ /* dst = -dst */ -+ case BPF_ALU | BPF_NEG: -+ emit_sext(ctx, dst, dst); -+ emit_alu_i(ctx, dst, 0, BPF_NEG); -+ emit_zext_ver(ctx, dst); -+ break; -+ /* dst = dst & imm */ -+ /* dst = dst | imm */ -+ /* dst = dst ^ imm */ -+ /* dst = dst << imm */ -+ case BPF_ALU | BPF_OR | BPF_K: -+ case BPF_ALU | BPF_AND | BPF_K: -+ case BPF_ALU | BPF_XOR | BPF_K: -+ case BPF_ALU | BPF_LSH | BPF_K: -+ if (!valid_alu_i(BPF_OP(code), imm)) { -+ emit_mov_i(ctx, MIPS_R_T4, imm); -+ emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code)); -+ } else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) { -+ emit_alu_i(ctx, dst, val, alu); -+ } -+ emit_zext_ver(ctx, dst); -+ break; -+ /* dst = dst >> imm */ -+ /* dst = dst >> imm (arithmetic) */ -+ /* dst = dst + imm */ -+ /* dst = dst - imm */ -+ /* dst = dst * imm */ -+ /* dst = dst / imm */ -+ /* dst = dst % imm */ -+ case BPF_ALU | BPF_RSH | BPF_K: -+ case BPF_ALU | BPF_ARSH | BPF_K: -+ case BPF_ALU | BPF_ADD | BPF_K: -+ case BPF_ALU | BPF_SUB | BPF_K: -+ case BPF_ALU | BPF_MUL | BPF_K: -+ case BPF_ALU | BPF_DIV | BPF_K: -+ case BPF_ALU | BPF_MOD | BPF_K: -+ if (!valid_alu_i(BPF_OP(code), imm)) { -+ emit_sext(ctx, dst, dst); -+ emit_mov_i(ctx, MIPS_R_T4, imm); -+ emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code)); -+ } else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) { -+ emit_sext(ctx, dst, dst); -+ emit_alu_i(ctx, dst, val, alu); -+ } -+ emit_zext_ver(ctx, dst); -+ break; -+ /* dst = dst & src */ -+ /* dst = dst | src */ -+ /* dst = dst ^ src */ -+ /* dst = dst << src */ -+ case BPF_ALU | BPF_AND | BPF_X: -+ case BPF_ALU | BPF_OR | BPF_X: -+ case BPF_ALU | BPF_XOR | BPF_X: -+ case BPF_ALU | BPF_LSH | BPF_X: -+ emit_alu_r(ctx, dst, src, BPF_OP(code)); -+ emit_zext_ver(ctx, dst); -+ break; -+ /* dst = dst >> src */ -+ /* dst = dst >> src (arithmetic) */ -+ /* dst = dst + src */ -+ /* dst = dst - src */ -+ /* dst = dst * src */ -+ /* dst = dst / src */ -+ /* dst = dst % src */ -+ case BPF_ALU | BPF_RSH | BPF_X: -+ case BPF_ALU | BPF_ARSH | BPF_X: -+ case BPF_ALU | BPF_ADD | BPF_X: -+ case BPF_ALU | BPF_SUB | BPF_X: -+ case BPF_ALU | BPF_MUL | BPF_X: -+ case BPF_ALU | BPF_DIV | BPF_X: -+ case BPF_ALU | BPF_MOD | BPF_X: -+ emit_sext(ctx, dst, dst); -+ emit_sext(ctx, MIPS_R_T4, src); -+ emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code)); -+ emit_zext_ver(ctx, dst); -+ break; -+ /* dst = imm (64-bit) */ -+ case BPF_ALU64 | BPF_MOV | BPF_K: -+ emit_mov_i(ctx, dst, imm); -+ break; -+ /* dst = src (64-bit) */ -+ case BPF_ALU64 | BPF_MOV | BPF_X: -+ emit_mov_r(ctx, dst, src); -+ break; -+ /* dst = -dst (64-bit) */ -+ case BPF_ALU64 | BPF_NEG: -+ emit_alu_i64(ctx, dst, 0, BPF_NEG); -+ break; -+ /* dst = dst & imm (64-bit) */ -+ /* dst = dst | imm (64-bit) */ -+ /* dst = dst ^ imm (64-bit) */ -+ /* dst = dst << imm (64-bit) */ -+ /* dst = dst >> imm (64-bit) */ -+ /* dst = dst >> imm ((64-bit, arithmetic) */ -+ /* dst = dst + imm (64-bit) */ -+ /* dst = dst - imm (64-bit) */ -+ /* dst = dst * imm (64-bit) */ -+ /* dst = dst / imm (64-bit) */ -+ /* dst = dst % imm (64-bit) */ -+ case BPF_ALU64 | BPF_AND | BPF_K: -+ case BPF_ALU64 | BPF_OR | BPF_K: -+ case BPF_ALU64 | BPF_XOR | BPF_K: -+ case BPF_ALU64 | BPF_LSH | BPF_K: -+ case BPF_ALU64 | BPF_RSH | BPF_K: -+ case BPF_ALU64 | BPF_ARSH | BPF_K: -+ case BPF_ALU64 | BPF_ADD | BPF_K: -+ case BPF_ALU64 | BPF_SUB | BPF_K: -+ case BPF_ALU64 | BPF_MUL | BPF_K: -+ case BPF_ALU64 | BPF_DIV | BPF_K: -+ case BPF_ALU64 | BPF_MOD | BPF_K: -+ if (!valid_alu_i(BPF_OP(code), imm)) { -+ emit_mov_i(ctx, MIPS_R_T4, imm); -+ emit_alu_r64(ctx, dst, MIPS_R_T4, BPF_OP(code)); -+ } else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) { -+ emit_alu_i64(ctx, dst, val, alu); -+ } -+ break; -+ /* dst = dst & src (64-bit) */ -+ /* dst = dst | src (64-bit) */ -+ /* dst = dst ^ src (64-bit) */ -+ /* dst = dst << src (64-bit) */ -+ /* dst = dst >> src (64-bit) */ -+ /* dst = dst >> src (64-bit, arithmetic) */ -+ /* dst = dst + src (64-bit) */ -+ /* dst = dst - src (64-bit) */ -+ /* dst = dst * src (64-bit) */ -+ /* dst = dst / src (64-bit) */ -+ /* dst = dst % src (64-bit) */ -+ case BPF_ALU64 | BPF_AND | BPF_X: -+ case BPF_ALU64 | BPF_OR | BPF_X: -+ case BPF_ALU64 | BPF_XOR | BPF_X: -+ case BPF_ALU64 | BPF_LSH | BPF_X: -+ case BPF_ALU64 | BPF_RSH | BPF_X: -+ case BPF_ALU64 | BPF_ARSH | BPF_X: -+ case BPF_ALU64 | BPF_ADD | BPF_X: -+ case BPF_ALU64 | BPF_SUB | BPF_X: -+ case BPF_ALU64 | BPF_MUL | BPF_X: -+ case BPF_ALU64 | BPF_DIV | BPF_X: -+ case BPF_ALU64 | BPF_MOD | BPF_X: -+ emit_alu_r64(ctx, dst, src, BPF_OP(code)); -+ break; -+ /* dst = htole(dst) */ -+ /* dst = htobe(dst) */ -+ case BPF_ALU | BPF_END | BPF_FROM_LE: -+ case BPF_ALU | BPF_END | BPF_FROM_BE: -+ if (BPF_SRC(code) == -+#ifdef __BIG_ENDIAN -+ BPF_FROM_LE -+#else -+ BPF_FROM_BE -+#endif -+ ) -+ emit_bswap_r64(ctx, dst, imm); -+ else -+ emit_trunc_r64(ctx, dst, imm); -+ break; -+ /* dst = imm64 */ -+ case BPF_LD | BPF_IMM | BPF_DW: -+ emit_mov_i64(ctx, dst, (u32)imm | ((u64)insn[1].imm << 32)); -+ return 1; -+ /* LDX: dst = *(size *)(src + off) */ -+ case BPF_LDX | BPF_MEM | BPF_W: -+ case BPF_LDX | BPF_MEM | BPF_H: -+ case BPF_LDX | BPF_MEM | BPF_B: -+ case BPF_LDX | BPF_MEM | BPF_DW: -+ emit_ldx(ctx, dst, src, off, BPF_SIZE(code)); -+ break; -+ /* ST: *(size *)(dst + off) = imm */ -+ case BPF_ST | BPF_MEM | BPF_W: -+ case BPF_ST | BPF_MEM | BPF_H: -+ case BPF_ST | BPF_MEM | BPF_B: -+ case BPF_ST | BPF_MEM | BPF_DW: -+ emit_mov_i(ctx, MIPS_R_T4, imm); -+ emit_stx(ctx, dst, MIPS_R_T4, off, BPF_SIZE(code)); -+ break; -+ /* STX: *(size *)(dst + off) = src */ -+ case BPF_STX | BPF_MEM | BPF_W: -+ case BPF_STX | BPF_MEM | BPF_H: -+ case BPF_STX | BPF_MEM | BPF_B: -+ case BPF_STX | BPF_MEM | BPF_DW: -+ emit_stx(ctx, dst, src, off, BPF_SIZE(code)); -+ break; -+ /* Speculation barrier */ -+ case BPF_ST | BPF_NOSPEC: -+ break; -+ /* Atomics */ -+ case BPF_STX | BPF_XADD | BPF_W: -+ case BPF_STX | BPF_XADD | BPF_DW: -+ switch (imm) { -+ case BPF_ADD: -+ case BPF_AND: -+ case BPF_OR: -+ case BPF_XOR: -+ if (BPF_SIZE(code) == BPF_DW) { -+ emit_atomic_r64(ctx, dst, src, off, imm); -+ } else { /* 32-bit, no fetch */ -+ emit_sext(ctx, MIPS_R_T4, src); -+ emit_atomic_r(ctx, dst, MIPS_R_T4, off, imm); -+ } -+ break; -+ default: -+ goto notyet; -+ } -+ break; -+ /* PC += off if dst == src */ -+ /* PC += off if dst != src */ -+ /* PC += off if dst & src */ -+ /* PC += off if dst > src */ -+ /* PC += off if dst >= src */ -+ /* PC += off if dst < src */ -+ /* PC += off if dst <= src */ -+ /* PC += off if dst > src (signed) */ -+ /* PC += off if dst >= src (signed) */ -+ /* PC += off if dst < src (signed) */ -+ /* PC += off if dst <= src (signed) */ -+ case BPF_JMP32 | BPF_JEQ | BPF_X: -+ case BPF_JMP32 | BPF_JNE | BPF_X: -+ case BPF_JMP32 | BPF_JSET | BPF_X: -+ case BPF_JMP32 | BPF_JGT | BPF_X: -+ case BPF_JMP32 | BPF_JGE | BPF_X: -+ case BPF_JMP32 | BPF_JLT | BPF_X: -+ case BPF_JMP32 | BPF_JLE | BPF_X: -+ case BPF_JMP32 | BPF_JSGT | BPF_X: -+ case BPF_JMP32 | BPF_JSGE | BPF_X: -+ case BPF_JMP32 | BPF_JSLT | BPF_X: -+ case BPF_JMP32 | BPF_JSLE | BPF_X: -+ if (off == 0) -+ break; -+ setup_jmp_r(ctx, dst == src, BPF_OP(code), off, &jmp, &rel); -+ emit_sext(ctx, MIPS_R_T4, dst); /* Sign-extended dst */ -+ emit_sext(ctx, MIPS_R_T5, src); /* Sign-extended src */ -+ emit_jmp_r(ctx, MIPS_R_T4, MIPS_R_T5, rel, jmp); -+ if (finish_jmp(ctx, jmp, off) < 0) -+ goto toofar; -+ break; -+ /* PC += off if dst == imm */ -+ /* PC += off if dst != imm */ -+ /* PC += off if dst & imm */ -+ /* PC += off if dst > imm */ -+ /* PC += off if dst >= imm */ -+ /* PC += off if dst < imm */ -+ /* PC += off if dst <= imm */ -+ /* PC += off if dst > imm (signed) */ -+ /* PC += off if dst >= imm (signed) */ -+ /* PC += off if dst < imm (signed) */ -+ /* PC += off if dst <= imm (signed) */ -+ case BPF_JMP32 | BPF_JEQ | BPF_K: -+ case BPF_JMP32 | BPF_JNE | BPF_K: -+ case BPF_JMP32 | BPF_JSET | BPF_K: -+ case BPF_JMP32 | BPF_JGT | BPF_K: -+ case BPF_JMP32 | BPF_JGE | BPF_K: -+ case BPF_JMP32 | BPF_JLT | BPF_K: -+ case BPF_JMP32 | BPF_JLE | BPF_K: -+ case BPF_JMP32 | BPF_JSGT | BPF_K: -+ case BPF_JMP32 | BPF_JSGE | BPF_K: -+ case BPF_JMP32 | BPF_JSLT | BPF_K: -+ case BPF_JMP32 | BPF_JSLE | BPF_K: -+ if (off == 0) -+ break; -+ setup_jmp_i(ctx, imm, 32, BPF_OP(code), off, &jmp, &rel); -+ emit_sext(ctx, MIPS_R_T4, dst); /* Sign-extended dst */ -+ if (valid_jmp_i(jmp, imm)) { -+ emit_jmp_i(ctx, MIPS_R_T4, imm, rel, jmp); -+ } else { -+ /* Move large immediate to register, sign-extended */ -+ emit_mov_i(ctx, MIPS_R_T5, imm); -+ emit_jmp_r(ctx, MIPS_R_T4, MIPS_R_T5, rel, jmp); -+ } -+ if (finish_jmp(ctx, jmp, off) < 0) -+ goto toofar; -+ break; -+ /* PC += off if dst == src */ -+ /* PC += off if dst != src */ -+ /* PC += off if dst & src */ -+ /* PC += off if dst > src */ -+ /* PC += off if dst >= src */ -+ /* PC += off if dst < src */ -+ /* PC += off if dst <= src */ -+ /* PC += off if dst > src (signed) */ -+ /* PC += off if dst >= src (signed) */ -+ /* PC += off if dst < src (signed) */ -+ /* PC += off if dst <= src (signed) */ -+ case BPF_JMP | BPF_JEQ | BPF_X: -+ case BPF_JMP | BPF_JNE | BPF_X: -+ case BPF_JMP | BPF_JSET | BPF_X: -+ case BPF_JMP | BPF_JGT | BPF_X: -+ case BPF_JMP | BPF_JGE | BPF_X: -+ case BPF_JMP | BPF_JLT | BPF_X: -+ case BPF_JMP | BPF_JLE | BPF_X: -+ case BPF_JMP | BPF_JSGT | BPF_X: -+ case BPF_JMP | BPF_JSGE | BPF_X: -+ case BPF_JMP | BPF_JSLT | BPF_X: -+ case BPF_JMP | BPF_JSLE | BPF_X: -+ if (off == 0) -+ break; -+ setup_jmp_r(ctx, dst == src, BPF_OP(code), off, &jmp, &rel); -+ emit_jmp_r(ctx, dst, src, rel, jmp); -+ if (finish_jmp(ctx, jmp, off) < 0) -+ goto toofar; -+ break; -+ /* PC += off if dst == imm */ -+ /* PC += off if dst != imm */ -+ /* PC += off if dst & imm */ -+ /* PC += off if dst > imm */ -+ /* PC += off if dst >= imm */ -+ /* PC += off if dst < imm */ -+ /* PC += off if dst <= imm */ -+ /* PC += off if dst > imm (signed) */ -+ /* PC += off if dst >= imm (signed) */ -+ /* PC += off if dst < imm (signed) */ -+ /* PC += off if dst <= imm (signed) */ -+ case BPF_JMP | BPF_JEQ | BPF_K: -+ case BPF_JMP | BPF_JNE | BPF_K: -+ case BPF_JMP | BPF_JSET | BPF_K: -+ case BPF_JMP | BPF_JGT | BPF_K: -+ case BPF_JMP | BPF_JGE | BPF_K: -+ case BPF_JMP | BPF_JLT | BPF_K: -+ case BPF_JMP | BPF_JLE | BPF_K: -+ case BPF_JMP | BPF_JSGT | BPF_K: -+ case BPF_JMP | BPF_JSGE | BPF_K: -+ case BPF_JMP | BPF_JSLT | BPF_K: -+ case BPF_JMP | BPF_JSLE | BPF_K: -+ if (off == 0) -+ break; -+ setup_jmp_i(ctx, imm, 64, BPF_OP(code), off, &jmp, &rel); -+ if (valid_jmp_i(jmp, imm)) { -+ emit_jmp_i(ctx, dst, imm, rel, jmp); -+ } else { -+ /* Move large immediate to register */ -+ emit_mov_i(ctx, MIPS_R_T4, imm); -+ emit_jmp_r(ctx, dst, MIPS_R_T4, rel, jmp); -+ } -+ if (finish_jmp(ctx, jmp, off) < 0) -+ goto toofar; -+ break; -+ /* PC += off */ -+ case BPF_JMP | BPF_JA: -+ if (off == 0) -+ break; -+ if (emit_ja(ctx, off) < 0) -+ goto toofar; -+ break; -+ /* Tail call */ -+ case BPF_JMP | BPF_TAIL_CALL: -+ if (emit_tail_call(ctx) < 0) -+ goto invalid; -+ break; -+ /* Function call */ -+ case BPF_JMP | BPF_CALL: -+ if (emit_call(ctx, insn) < 0) -+ goto invalid; -+ break; -+ /* Function return */ -+ case BPF_JMP | BPF_EXIT: -+ /* -+ * Optimization: when last instruction is EXIT -+ * simply continue to epilogue. -+ */ -+ if (ctx->bpf_index == ctx->program->len - 1) -+ break; -+ if (emit_exit(ctx) < 0) -+ goto toofar; -+ break; -+ -+ default: -+invalid: -+ pr_err_once("unknown opcode %02x\n", code); -+ return -EINVAL; -+notyet: -+ pr_info_once("*** NOT YET: opcode %02x ***\n", code); -+ return -EFAULT; -+toofar: -+ pr_info_once("*** TOO FAR: jump at %u opcode %02x ***\n", -+ ctx->bpf_index, code); -+ return -E2BIG; -+ } -+ return 0; -+} diff --git a/target/linux/generic/backport-5.15/050-v5.16-04-mips-bpf-Add-JIT-workarounds-for-CPU-errata.patch b/target/linux/generic/backport-5.15/050-v5.16-04-mips-bpf-Add-JIT-workarounds-for-CPU-errata.patch deleted file mode 100644 index 63553ebe58423c..00000000000000 --- a/target/linux/generic/backport-5.15/050-v5.16-04-mips-bpf-Add-JIT-workarounds-for-CPU-errata.patch +++ /dev/null @@ -1,120 +0,0 @@ -From: Johan Almbladh -Date: Tue, 5 Oct 2021 18:54:06 +0200 -Subject: [PATCH] mips: bpf: Add JIT workarounds for CPU errata - -This patch adds workarounds for the following CPU errata to the MIPS -eBPF JIT, if enabled in the kernel configuration. - - - R10000 ll/sc weak ordering - - Loongson-3 ll/sc weak ordering - - Loongson-2F jump hang - -The Loongson-2F nop errata is implemented in uasm, which the JIT uses, -so no additional mitigations are needed for that. - -Signed-off-by: Johan Almbladh -Reviewed-by: Jiaxun Yang ---- - ---- a/arch/mips/net/bpf_jit_comp.c -+++ b/arch/mips/net/bpf_jit_comp.c -@@ -404,6 +404,7 @@ void emit_alu_r(struct jit_context *ctx, - /* Atomic read-modify-write (32-bit) */ - void emit_atomic_r(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 code) - { -+ LLSC_sync(ctx); - emit(ctx, ll, MIPS_R_T9, off, dst); - switch (code) { - case BPF_ADD: -@@ -420,18 +421,19 @@ void emit_atomic_r(struct jit_context *c - break; - } - emit(ctx, sc, MIPS_R_T8, off, dst); -- emit(ctx, beqz, MIPS_R_T8, -16); -+ emit(ctx, LLSC_beqz, MIPS_R_T8, -16 - LLSC_offset); - emit(ctx, nop); /* Delay slot */ - } - - /* Atomic compare-and-exchange (32-bit) */ - void emit_cmpxchg_r(struct jit_context *ctx, u8 dst, u8 src, u8 res, s16 off) - { -+ LLSC_sync(ctx); - emit(ctx, ll, MIPS_R_T9, off, dst); - emit(ctx, bne, MIPS_R_T9, res, 12); - emit(ctx, move, MIPS_R_T8, src); /* Delay slot */ - emit(ctx, sc, MIPS_R_T8, off, dst); -- emit(ctx, beqz, MIPS_R_T8, -20); -+ emit(ctx, LLSC_beqz, MIPS_R_T8, -20 - LLSC_offset); - emit(ctx, move, res, MIPS_R_T9); /* Delay slot */ - clobber_reg(ctx, res); - } ---- a/arch/mips/net/bpf_jit_comp.h -+++ b/arch/mips/net/bpf_jit_comp.h -@@ -87,7 +87,7 @@ struct jit_context { - }; - - /* Emit the instruction if the JIT memory space has been allocated */ --#define emit(ctx, func, ...) \ -+#define __emit(ctx, func, ...) \ - do { \ - if ((ctx)->target != NULL) { \ - u32 *p = &(ctx)->target[ctx->jit_index]; \ -@@ -95,6 +95,30 @@ do { \ - } \ - (ctx)->jit_index++; \ - } while (0) -+#define emit(...) __emit(__VA_ARGS__) -+ -+/* Workaround for R10000 ll/sc errata */ -+#ifdef CONFIG_WAR_R10000 -+#define LLSC_beqz beqzl -+#else -+#define LLSC_beqz beqz -+#endif -+ -+/* Workaround for Loongson-3 ll/sc errata */ -+#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS -+#define LLSC_sync(ctx) emit(ctx, sync, 0) -+#define LLSC_offset 4 -+#else -+#define LLSC_sync(ctx) -+#define LLSC_offset 0 -+#endif -+ -+/* Workaround for Loongson-2F jump errata */ -+#ifdef CONFIG_CPU_JUMP_WORKAROUNDS -+#define JALR_MASK 0xffffffffcfffffffULL -+#else -+#define JALR_MASK (~0ULL) -+#endif - - /* - * Mark a BPF register as accessed, it needs to be ---- a/arch/mips/net/bpf_jit_comp64.c -+++ b/arch/mips/net/bpf_jit_comp64.c -@@ -375,6 +375,7 @@ static void emit_atomic_r64(struct jit_c - u8 t1 = MIPS_R_T6; - u8 t2 = MIPS_R_T7; - -+ LLSC_sync(ctx); - emit(ctx, lld, t1, off, dst); - switch (code) { - case BPF_ADD: -@@ -391,7 +392,7 @@ static void emit_atomic_r64(struct jit_c - break; - } - emit(ctx, scd, t2, off, dst); -- emit(ctx, beqz, t2, -16); -+ emit(ctx, LLSC_beqz, t2, -16 - LLSC_offset); - emit(ctx, nop); /* Delay slot */ - } - -@@ -414,7 +415,7 @@ static int emit_call(struct jit_context - push_regs(ctx, ctx->clobbered & JIT_CALLER_REGS, 0, 0); - - /* Emit function call */ -- emit_mov_i64(ctx, tmp, addr); -+ emit_mov_i64(ctx, tmp, addr & JALR_MASK); - emit(ctx, jalr, MIPS_R_RA, tmp); - emit(ctx, nop); /* Delay slot */ - diff --git a/target/linux/generic/backport-5.15/050-v5.16-05-mips-bpf-Enable-eBPF-JITs.patch b/target/linux/generic/backport-5.15/050-v5.16-05-mips-bpf-Enable-eBPF-JITs.patch deleted file mode 100644 index 24e4e9052b39eb..00000000000000 --- a/target/linux/generic/backport-5.15/050-v5.16-05-mips-bpf-Enable-eBPF-JITs.patch +++ /dev/null @@ -1,61 +0,0 @@ -From: Johan Almbladh -Date: Tue, 5 Oct 2021 18:54:07 +0200 -Subject: [PATCH] mips: bpf: Enable eBPF JITs - -This patch enables the new eBPF JITs for 32-bit and 64-bit MIPS. It also -disables the old cBPF JIT to so cBPF programs are converted to use the -new JIT. - -Workarounds for R4000 CPU errata are not implemented by the JIT, so the -JIT is disabled if any of those workarounds are configured. - -Signed-off-by: Johan Almbladh ---- - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -3431,6 +3431,7 @@ S: Supported - F: arch/arm64/net/ - - BPF JIT for MIPS (32-BIT AND 64-BIT) -+M: Johan Almbladh - M: Paul Burton - L: netdev@vger.kernel.org - L: bpf@vger.kernel.org ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -58,7 +58,6 @@ config MIPS - select HAVE_ARCH_TRACEHOOK - select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES - select HAVE_ASM_MODVERSIONS -- select HAVE_CBPF_JIT if !64BIT && !CPU_MICROMIPS - select HAVE_CONTEXT_TRACKING - select HAVE_TIF_NOHZ - select HAVE_C_RECORDMCOUNT -@@ -66,7 +65,10 @@ config MIPS - select HAVE_DEBUG_STACKOVERFLOW - select HAVE_DMA_CONTIGUOUS - select HAVE_DYNAMIC_FTRACE -- select HAVE_EBPF_JIT if 64BIT && !CPU_MICROMIPS && TARGET_ISA_REV >= 2 -+ select HAVE_EBPF_JIT if !CPU_MICROMIPS && \ -+ !CPU_DADDI_WORKAROUNDS && \ -+ !CPU_R4000_WORKAROUNDS && \ -+ !CPU_R4400_WORKAROUNDS - select HAVE_EXIT_THREAD - select HAVE_FAST_GUP - select HAVE_FTRACE_MCOUNT_RECORD ---- a/arch/mips/net/Makefile -+++ b/arch/mips/net/Makefile -@@ -2,9 +2,10 @@ - # MIPS networking code - - obj-$(CONFIG_MIPS_CBPF_JIT) += bpf_jit.o bpf_jit_asm.o -+obj-$(CONFIG_MIPS_EBPF_JIT) += bpf_jit_comp.o - - ifeq ($(CONFIG_32BIT),y) -- obj-$(CONFIG_MIPS_EBPF_JIT) += bpf_jit_comp.o bpf_jit_comp32.o -+ obj-$(CONFIG_MIPS_EBPF_JIT) += bpf_jit_comp32.o - else -- obj-$(CONFIG_MIPS_EBPF_JIT) += ebpf_jit.o -+ obj-$(CONFIG_MIPS_EBPF_JIT) += bpf_jit_comp64.o - endif diff --git a/target/linux/generic/backport-5.15/050-v5.16-06-mips-bpf-Remove-old-BPF-JIT-implementations.patch b/target/linux/generic/backport-5.15/050-v5.16-06-mips-bpf-Remove-old-BPF-JIT-implementations.patch deleted file mode 100644 index e25c336831dcbb..00000000000000 --- a/target/linux/generic/backport-5.15/050-v5.16-06-mips-bpf-Remove-old-BPF-JIT-implementations.patch +++ /dev/null @@ -1,387 +0,0 @@ -From: Johan Almbladh -Date: Tue, 5 Oct 2021 18:54:08 +0200 -Subject: [PATCH] mips: bpf: Remove old BPF JIT implementations - -This patch removes the old 32-bit cBPF and 64-bit eBPF JIT implementations. -They are replaced by a new eBPF implementation that supports both 32-bit -and 64-bit MIPS CPUs. - -Signed-off-by: Johan Almbladh ---- - delete mode 100644 arch/mips/net/bpf_jit.c - delete mode 100644 arch/mips/net/bpf_jit.h - delete mode 100644 arch/mips/net/bpf_jit_asm.S - delete mode 100644 arch/mips/net/ebpf_jit.c - ---- a/arch/mips/net/bpf_jit.h -+++ /dev/null -@@ -1,81 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-only */ --/* -- * Just-In-Time compiler for BPF filters on MIPS -- * -- * Copyright (c) 2014 Imagination Technologies Ltd. -- * Author: Markos Chandras -- */ -- --#ifndef BPF_JIT_MIPS_OP_H --#define BPF_JIT_MIPS_OP_H -- --/* Registers used by JIT */ --#define MIPS_R_ZERO 0 --#define MIPS_R_V0 2 --#define MIPS_R_A0 4 --#define MIPS_R_A1 5 --#define MIPS_R_T4 12 --#define MIPS_R_T5 13 --#define MIPS_R_T6 14 --#define MIPS_R_T7 15 --#define MIPS_R_S0 16 --#define MIPS_R_S1 17 --#define MIPS_R_S2 18 --#define MIPS_R_S3 19 --#define MIPS_R_S4 20 --#define MIPS_R_S5 21 --#define MIPS_R_S6 22 --#define MIPS_R_S7 23 --#define MIPS_R_SP 29 --#define MIPS_R_RA 31 -- --/* Conditional codes */ --#define MIPS_COND_EQ 0x1 --#define MIPS_COND_GE (0x1 << 1) --#define MIPS_COND_GT (0x1 << 2) --#define MIPS_COND_NE (0x1 << 3) --#define MIPS_COND_ALL (0x1 << 4) --/* Conditionals on X register or K immediate */ --#define MIPS_COND_X (0x1 << 5) --#define MIPS_COND_K (0x1 << 6) -- --#define r_ret MIPS_R_V0 -- --/* -- * Use 2 scratch registers to avoid pipeline interlocks. -- * There is no overhead during epilogue and prologue since -- * any of the $s0-$s6 registers will only be preserved if -- * they are going to actually be used. -- */ --#define r_skb_hl MIPS_R_S0 /* skb header length */ --#define r_skb_data MIPS_R_S1 /* skb actual data */ --#define r_off MIPS_R_S2 --#define r_A MIPS_R_S3 --#define r_X MIPS_R_S4 --#define r_skb MIPS_R_S5 --#define r_M MIPS_R_S6 --#define r_skb_len MIPS_R_S7 --#define r_s0 MIPS_R_T4 /* scratch reg 1 */ --#define r_s1 MIPS_R_T5 /* scratch reg 2 */ --#define r_tmp_imm MIPS_R_T6 /* No need to preserve this */ --#define r_tmp MIPS_R_T7 /* No need to preserve this */ --#define r_zero MIPS_R_ZERO --#define r_sp MIPS_R_SP --#define r_ra MIPS_R_RA -- --#ifndef __ASSEMBLY__ -- --/* Declare ASM helpers */ -- --#define DECLARE_LOAD_FUNC(func) \ -- extern u8 func(unsigned long *skb, int offset); \ -- extern u8 func##_negative(unsigned long *skb, int offset); \ -- extern u8 func##_positive(unsigned long *skb, int offset) -- --DECLARE_LOAD_FUNC(sk_load_word); --DECLARE_LOAD_FUNC(sk_load_half); --DECLARE_LOAD_FUNC(sk_load_byte); -- --#endif -- --#endif /* BPF_JIT_MIPS_OP_H */ ---- a/arch/mips/net/bpf_jit_asm.S -+++ /dev/null -@@ -1,285 +0,0 @@ --/* -- * bpf_jib_asm.S: Packet/header access helper functions for MIPS/MIPS64 BPF -- * compiler. -- * -- * Copyright (C) 2015 Imagination Technologies Ltd. -- * Author: Markos Chandras -- * -- * This program is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License as published by the -- * Free Software Foundation; version 2 of the License. -- */ -- --#include --#include --#include --#include "bpf_jit.h" -- --/* ABI -- * -- * r_skb_hl skb header length -- * r_skb_data skb data -- * r_off(a1) offset register -- * r_A BPF register A -- * r_X PF register X -- * r_skb(a0) *skb -- * r_M *scratch memory -- * r_skb_le skb length -- * r_s0 Scratch register 0 -- * r_s1 Scratch register 1 -- * -- * On entry: -- * a0: *skb -- * a1: offset (imm or imm + X) -- * -- * All non-BPF-ABI registers are free for use. On return, we only -- * care about r_ret. The BPF-ABI registers are assumed to remain -- * unmodified during the entire filter operation. -- */ -- --#define skb a0 --#define offset a1 --#define SKF_LL_OFF (-0x200000) /* Can't include linux/filter.h in assembly */ -- -- /* We know better :) so prevent assembler reordering etc */ -- .set noreorder -- --#define is_offset_negative(TYPE) \ -- /* If offset is negative we have more work to do */ \ -- slti t0, offset, 0; \ -- bgtz t0, bpf_slow_path_##TYPE##_neg; \ -- /* Be careful what follows in DS. */ -- --#define is_offset_in_header(SIZE, TYPE) \ -- /* Reading from header? */ \ -- addiu $r_s0, $r_skb_hl, -SIZE; \ -- slt t0, $r_s0, offset; \ -- bgtz t0, bpf_slow_path_##TYPE; \ -- --LEAF(sk_load_word) -- is_offset_negative(word) --FEXPORT(sk_load_word_positive) -- is_offset_in_header(4, word) -- /* Offset within header boundaries */ -- PTR_ADDU t1, $r_skb_data, offset -- .set reorder -- lw $r_A, 0(t1) -- .set noreorder --#ifdef CONFIG_CPU_LITTLE_ENDIAN --# if MIPS_ISA_REV >= 2 -- wsbh t0, $r_A -- rotr $r_A, t0, 16 --# else -- sll t0, $r_A, 24 -- srl t1, $r_A, 24 -- srl t2, $r_A, 8 -- or t0, t0, t1 -- andi t2, t2, 0xff00 -- andi t1, $r_A, 0xff00 -- or t0, t0, t2 -- sll t1, t1, 8 -- or $r_A, t0, t1 --# endif --#endif -- jr $r_ra -- move $r_ret, zero -- END(sk_load_word) -- --LEAF(sk_load_half) -- is_offset_negative(half) --FEXPORT(sk_load_half_positive) -- is_offset_in_header(2, half) -- /* Offset within header boundaries */ -- PTR_ADDU t1, $r_skb_data, offset -- lhu $r_A, 0(t1) --#ifdef CONFIG_CPU_LITTLE_ENDIAN --# if MIPS_ISA_REV >= 2 -- wsbh $r_A, $r_A --# else -- sll t0, $r_A, 8 -- srl t1, $r_A, 8 -- andi t0, t0, 0xff00 -- or $r_A, t0, t1 --# endif --#endif -- jr $r_ra -- move $r_ret, zero -- END(sk_load_half) -- --LEAF(sk_load_byte) -- is_offset_negative(byte) --FEXPORT(sk_load_byte_positive) -- is_offset_in_header(1, byte) -- /* Offset within header boundaries */ -- PTR_ADDU t1, $r_skb_data, offset -- lbu $r_A, 0(t1) -- jr $r_ra -- move $r_ret, zero -- END(sk_load_byte) -- --/* -- * call skb_copy_bits: -- * (prototype in linux/skbuff.h) -- * -- * int skb_copy_bits(sk_buff *skb, int offset, void *to, int len) -- * -- * o32 mandates we leave 4 spaces for argument registers in case -- * the callee needs to use them. Even though we don't care about -- * the argument registers ourselves, we need to allocate that space -- * to remain ABI compliant since the callee may want to use that space. -- * We also allocate 2 more spaces for $r_ra and our return register (*to). -- * -- * n64 is a bit different. The *caller* will allocate the space to preserve -- * the arguments. So in 64-bit kernels, we allocate the 4-arg space for no -- * good reason but it does not matter that much really. -- * -- * (void *to) is returned in r_s0 -- * -- */ --#ifdef CONFIG_CPU_LITTLE_ENDIAN --#define DS_OFFSET(SIZE) (4 * SZREG) --#else --#define DS_OFFSET(SIZE) ((4 * SZREG) + (4 - SIZE)) --#endif --#define bpf_slow_path_common(SIZE) \ -- /* Quick check. Are we within reasonable boundaries? */ \ -- LONG_ADDIU $r_s1, $r_skb_len, -SIZE; \ -- sltu $r_s0, offset, $r_s1; \ -- beqz $r_s0, fault; \ -- /* Load 4th argument in DS */ \ -- LONG_ADDIU a3, zero, SIZE; \ -- PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \ -- PTR_LA t0, skb_copy_bits; \ -- PTR_S $r_ra, (5 * SZREG)($r_sp); \ -- /* Assign low slot to a2 */ \ -- PTR_ADDIU a2, $r_sp, DS_OFFSET(SIZE); \ -- jalr t0; \ -- /* Reset our destination slot (DS but it's ok) */ \ -- INT_S zero, (4 * SZREG)($r_sp); \ -- /* \ -- * skb_copy_bits returns 0 on success and -EFAULT \ -- * on error. Our data live in a2. Do not bother with \ -- * our data if an error has been returned. \ -- */ \ -- /* Restore our frame */ \ -- PTR_L $r_ra, (5 * SZREG)($r_sp); \ -- INT_L $r_s0, (4 * SZREG)($r_sp); \ -- bltz v0, fault; \ -- PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \ -- move $r_ret, zero; \ -- --NESTED(bpf_slow_path_word, (6 * SZREG), $r_sp) -- bpf_slow_path_common(4) --#ifdef CONFIG_CPU_LITTLE_ENDIAN --# if MIPS_ISA_REV >= 2 -- wsbh t0, $r_s0 -- jr $r_ra -- rotr $r_A, t0, 16 --# else -- sll t0, $r_s0, 24 -- srl t1, $r_s0, 24 -- srl t2, $r_s0, 8 -- or t0, t0, t1 -- andi t2, t2, 0xff00 -- andi t1, $r_s0, 0xff00 -- or t0, t0, t2 -- sll t1, t1, 8 -- jr $r_ra -- or $r_A, t0, t1 --# endif --#else -- jr $r_ra -- move $r_A, $r_s0 --#endif -- -- END(bpf_slow_path_word) -- --NESTED(bpf_slow_path_half, (6 * SZREG), $r_sp) -- bpf_slow_path_common(2) --#ifdef CONFIG_CPU_LITTLE_ENDIAN --# if MIPS_ISA_REV >= 2 -- jr $r_ra -- wsbh $r_A, $r_s0 --# else -- sll t0, $r_s0, 8 -- andi t1, $r_s0, 0xff00 -- andi t0, t0, 0xff00 -- srl t1, t1, 8 -- jr $r_ra -- or $r_A, t0, t1 --# endif --#else -- jr $r_ra -- move $r_A, $r_s0 --#endif -- -- END(bpf_slow_path_half) -- --NESTED(bpf_slow_path_byte, (6 * SZREG), $r_sp) -- bpf_slow_path_common(1) -- jr $r_ra -- move $r_A, $r_s0 -- -- END(bpf_slow_path_byte) -- --/* -- * Negative entry points -- */ -- .macro bpf_is_end_of_data -- li t0, SKF_LL_OFF -- /* Reading link layer data? */ -- slt t1, offset, t0 -- bgtz t1, fault -- /* Be careful what follows in DS. */ -- .endm --/* -- * call skb_copy_bits: -- * (prototype in linux/filter.h) -- * -- * void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, -- * int k, unsigned int size) -- * -- * see above (bpf_slow_path_common) for ABI restrictions -- */ --#define bpf_negative_common(SIZE) \ -- PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \ -- PTR_LA t0, bpf_internal_load_pointer_neg_helper; \ -- PTR_S $r_ra, (5 * SZREG)($r_sp); \ -- jalr t0; \ -- li a2, SIZE; \ -- PTR_L $r_ra, (5 * SZREG)($r_sp); \ -- /* Check return pointer */ \ -- beqz v0, fault; \ -- PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \ -- /* Preserve our pointer */ \ -- move $r_s0, v0; \ -- /* Set return value */ \ -- move $r_ret, zero; \ -- --bpf_slow_path_word_neg: -- bpf_is_end_of_data --NESTED(sk_load_word_negative, (6 * SZREG), $r_sp) -- bpf_negative_common(4) -- jr $r_ra -- lw $r_A, 0($r_s0) -- END(sk_load_word_negative) -- --bpf_slow_path_half_neg: -- bpf_is_end_of_data --NESTED(sk_load_half_negative, (6 * SZREG), $r_sp) -- bpf_negative_common(2) -- jr $r_ra -- lhu $r_A, 0($r_s0) -- END(sk_load_half_negative) -- --bpf_slow_path_byte_neg: -- bpf_is_end_of_data --NESTED(sk_load_byte_negative, (6 * SZREG), $r_sp) -- bpf_negative_common(1) -- jr $r_ra -- lbu $r_A, 0($r_s0) -- END(sk_load_byte_negative) -- --fault: -- jr $r_ra -- addiu $r_ret, zero, 1 diff --git a/target/linux/generic/backport-5.15/060-v5.18-01-bpf-selftests-Add-helpers-to-directly-use-the-capget.patch b/target/linux/generic/backport-5.15/060-v5.18-01-bpf-selftests-Add-helpers-to-directly-use-the-capget.patch deleted file mode 100644 index 4d544a30f59774..00000000000000 --- a/target/linux/generic/backport-5.15/060-v5.18-01-bpf-selftests-Add-helpers-to-directly-use-the-capget.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 5287acc6f097c0c18e54401b611a877a3083b68c Mon Sep 17 00:00:00 2001 -From: Martin KaFai Lau -Date: Wed, 16 Mar 2022 10:38:23 -0700 -Subject: [PATCH 1/3] bpf: selftests: Add helpers to directly use the capget - and capset syscall - -After upgrading to the newer libcap (>= 2.60), -the libcap commit aca076443591 ("Make cap_t operations thread safe.") -added a "__u8 mutex;" to the "struct _cap_struct". It caused a few byte -shift that breaks the assumption made in the "struct libcap" definition -in test_verifier.c. - -The bpf selftest usage only needs to enable and disable the effective -caps of the running task. It is easier to directly syscall the -capget and capset instead. It can also remove the libcap -library dependency. - -The cap_helpers.{c,h} is added. One __u64 is used for all CAP_* -bits instead of two __u32. - -Signed-off-by: Martin KaFai Lau -Signed-off-by: Alexei Starovoitov -Acked-by: John Fastabend -Link: https://lore.kernel.org/bpf/20220316173823.2036955-1-kafai@fb.com ---- - tools/testing/selftests/bpf/cap_helpers.c | 67 +++++++++++++++++++++++ - tools/testing/selftests/bpf/cap_helpers.h | 19 +++++++ - 2 files changed, 86 insertions(+) - create mode 100644 tools/testing/selftests/bpf/cap_helpers.c - create mode 100644 tools/testing/selftests/bpf/cap_helpers.h - ---- /dev/null -+++ b/tools/testing/selftests/bpf/cap_helpers.c -@@ -0,0 +1,67 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include "cap_helpers.h" -+ -+/* Avoid including from the libcap-devel package, -+ * so directly declare them here and use them from glibc. -+ */ -+int capget(cap_user_header_t header, cap_user_data_t data); -+int capset(cap_user_header_t header, const cap_user_data_t data); -+ -+int cap_enable_effective(__u64 caps, __u64 *old_caps) -+{ -+ struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3]; -+ struct __user_cap_header_struct hdr = { -+ .version = _LINUX_CAPABILITY_VERSION_3, -+ }; -+ __u32 cap0 = caps; -+ __u32 cap1 = caps >> 32; -+ int err; -+ -+ err = capget(&hdr, data); -+ if (err) -+ return err; -+ -+ if (old_caps) -+ *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective; -+ -+ if ((data[0].effective & cap0) == cap0 && -+ (data[1].effective & cap1) == cap1) -+ return 0; -+ -+ data[0].effective |= cap0; -+ data[1].effective |= cap1; -+ err = capset(&hdr, data); -+ if (err) -+ return err; -+ -+ return 0; -+} -+ -+int cap_disable_effective(__u64 caps, __u64 *old_caps) -+{ -+ struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3]; -+ struct __user_cap_header_struct hdr = { -+ .version = _LINUX_CAPABILITY_VERSION_3, -+ }; -+ __u32 cap0 = caps; -+ __u32 cap1 = caps >> 32; -+ int err; -+ -+ err = capget(&hdr, data); -+ if (err) -+ return err; -+ -+ if (old_caps) -+ *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective; -+ -+ if (!(data[0].effective & cap0) && !(data[1].effective & cap1)) -+ return 0; -+ -+ data[0].effective &= ~cap0; -+ data[1].effective &= ~cap1; -+ err = capset(&hdr, data); -+ if (err) -+ return err; -+ -+ return 0; -+} ---- /dev/null -+++ b/tools/testing/selftests/bpf/cap_helpers.h -@@ -0,0 +1,19 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __CAP_HELPERS_H -+#define __CAP_HELPERS_H -+ -+#include -+#include -+ -+#ifndef CAP_PERFMON -+#define CAP_PERFMON 38 -+#endif -+ -+#ifndef CAP_BPF -+#define CAP_BPF 39 -+#endif -+ -+int cap_enable_effective(__u64 caps, __u64 *old_caps); -+int cap_disable_effective(__u64 caps, __u64 *old_caps); -+ -+#endif diff --git a/target/linux/generic/backport-5.15/060-v5.18-02-bpf-selftests-Remove-libcap-usage-from-test_verifier.patch b/target/linux/generic/backport-5.15/060-v5.18-02-bpf-selftests-Remove-libcap-usage-from-test_verifier.patch deleted file mode 100644 index cc60b54340156e..00000000000000 --- a/target/linux/generic/backport-5.15/060-v5.18-02-bpf-selftests-Remove-libcap-usage-from-test_verifier.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 847a6b7ee906be874f0cae279c8de902a7d3f092 Mon Sep 17 00:00:00 2001 -From: Martin KaFai Lau -Date: Wed, 16 Mar 2022 10:38:29 -0700 -Subject: [PATCH 2/3] bpf: selftests: Remove libcap usage from test_verifier - -This patch removes the libcap usage from test_verifier. -The cap_*_effective() helpers added in the earlier patch are -used instead. - -Signed-off-by: Martin KaFai Lau -Signed-off-by: Alexei Starovoitov -Acked-by: John Fastabend -Link: https://lore.kernel.org/bpf/20220316173829.2038682-1-kafai@fb.com ---- - tools/testing/selftests/bpf/Makefile | 31 +++++--- - tools/testing/selftests/bpf/test_verifier.c | 88 ++++++--------------- - 2 files changed, 46 insertions(+), 73 deletions(-) - ---- a/tools/testing/selftests/bpf/Makefile -+++ b/tools/testing/selftests/bpf/Makefile -@@ -189,16 +189,27 @@ TEST_GEN_PROGS_EXTENDED += $(DEFAULT_BPF - - $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/test_stub.o $(BPFOBJ) - --$(OUTPUT)/test_dev_cgroup: cgroup_helpers.c --$(OUTPUT)/test_skb_cgroup_id_user: cgroup_helpers.c --$(OUTPUT)/test_sock: cgroup_helpers.c --$(OUTPUT)/test_sock_addr: cgroup_helpers.c --$(OUTPUT)/test_sockmap: cgroup_helpers.c --$(OUTPUT)/test_tcpnotify_user: cgroup_helpers.c trace_helpers.c --$(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c --$(OUTPUT)/test_cgroup_storage: cgroup_helpers.c --$(OUTPUT)/test_sock_fields: cgroup_helpers.c --$(OUTPUT)/test_sysctl: cgroup_helpers.c -+CGROUP_HELPERS := $(OUTPUT)/cgroup_helpers.o -+TESTING_HELPERS := $(OUTPUT)/testing_helpers.o -+TRACE_HELPERS := $(OUTPUT)/trace_helpers.o -+CAP_HELPERS := $(OUTPUT)/cap_helpers.o -+ -+$(OUTPUT)/test_dev_cgroup: $(CGROUP_HELPERS) $(TESTING_HELPERS) -+$(OUTPUT)/test_skb_cgroup_id_user: $(CGROUP_HELPERS) $(TESTING_HELPERS) -+$(OUTPUT)/test_sock: $(CGROUP_HELPERS) $(TESTING_HELPERS) -+$(OUTPUT)/test_sock_addr: $(CGROUP_HELPERS) $(TESTING_HELPERS) -+$(OUTPUT)/test_sockmap: $(CGROUP_HELPERS) $(TESTING_HELPERS) -+$(OUTPUT)/test_tcpnotify_user: $(CGROUP_HELPERS) $(TESTING_HELPERS) $(TRACE_HELPERS) -+$(OUTPUT)/get_cgroup_id_user: $(CGROUP_HELPERS) $(TESTING_HELPERS) -+$(OUTPUT)/test_cgroup_storage: $(CGROUP_HELPERS) $(TESTING_HELPERS) -+$(OUTPUT)/test_sock_fields: $(CGROUP_HELPERS) $(TESTING_HELPERS) -+$(OUTPUT)/test_sysctl: $(CGROUP_HELPERS) $(TESTING_HELPERS) -+$(OUTPUT)/test_tag: $(TESTING_HELPERS) -+$(OUTPUT)/test_lirc_mode2_user: $(TESTING_HELPERS) -+$(OUTPUT)/xdping: $(TESTING_HELPERS) -+$(OUTPUT)/flow_dissector_load: $(TESTING_HELPERS) -+$(OUTPUT)/test_maps: $(TESTING_HELPERS) -+$(OUTPUT)/test_verifier: $(TESTING_HELPERS) $(CAP_HELPERS) - - BPFTOOL ?= $(DEFAULT_BPFTOOL) - $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \ ---- a/tools/testing/selftests/bpf/test_verifier.c -+++ b/tools/testing/selftests/bpf/test_verifier.c -@@ -22,8 +22,6 @@ - #include - #include - --#include -- - #include - #include - #include -@@ -43,6 +41,7 @@ - # endif - #endif - #include "bpf_rlimit.h" -+#include "cap_helpers.h" - #include "bpf_rand.h" - #include "bpf_util.h" - #include "test_btf.h" -@@ -59,6 +58,10 @@ - #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0) - #define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1) - -+/* need CAP_BPF, CAP_NET_ADMIN, CAP_PERFMON to load progs */ -+#define ADMIN_CAPS (1ULL << CAP_NET_ADMIN | \ -+ 1ULL << CAP_PERFMON | \ -+ 1ULL << CAP_BPF) - #define UNPRIV_SYSCTL "kernel/unprivileged_bpf_disabled" - static bool unpriv_disabled = false; - static int skips; -@@ -940,47 +943,19 @@ struct libcap { - - static int set_admin(bool admin) - { -- cap_t caps; -- /* need CAP_BPF, CAP_NET_ADMIN, CAP_PERFMON to load progs */ -- const cap_value_t cap_net_admin = CAP_NET_ADMIN; -- const cap_value_t cap_sys_admin = CAP_SYS_ADMIN; -- struct libcap *cap; -- int ret = -1; -- -- caps = cap_get_proc(); -- if (!caps) { -- perror("cap_get_proc"); -- return -1; -- } -- cap = (struct libcap *)caps; -- if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_sys_admin, CAP_CLEAR)) { -- perror("cap_set_flag clear admin"); -- goto out; -- } -- if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_net_admin, -- admin ? CAP_SET : CAP_CLEAR)) { -- perror("cap_set_flag set_or_clear net"); -- goto out; -- } -- /* libcap is likely old and simply ignores CAP_BPF and CAP_PERFMON, -- * so update effective bits manually -- */ -+ int err; -+ - if (admin) { -- cap->data[1].effective |= 1 << (38 /* CAP_PERFMON */ - 32); -- cap->data[1].effective |= 1 << (39 /* CAP_BPF */ - 32); -+ err = cap_enable_effective(ADMIN_CAPS, NULL); -+ if (err) -+ perror("cap_enable_effective(ADMIN_CAPS)"); - } else { -- cap->data[1].effective &= ~(1 << (38 - 32)); -- cap->data[1].effective &= ~(1 << (39 - 32)); -+ err = cap_disable_effective(ADMIN_CAPS, NULL); -+ if (err) -+ perror("cap_disable_effective(ADMIN_CAPS)"); - } -- if (cap_set_proc(caps)) { -- perror("cap_set_proc"); -- goto out; -- } -- ret = 0; --out: -- if (cap_free(caps)) -- perror("cap_free"); -- return ret; -+ -+ return err; - } - - static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val, -@@ -1246,31 +1221,18 @@ fail_log: - - static bool is_admin(void) - { -- cap_flag_value_t net_priv = CAP_CLEAR; -- bool perfmon_priv = false; -- bool bpf_priv = false; -- struct libcap *cap; -- cap_t caps; -- --#ifdef CAP_IS_SUPPORTED -- if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) { -- perror("cap_get_flag"); -- return false; -- } --#endif -- caps = cap_get_proc(); -- if (!caps) { -- perror("cap_get_proc"); -+ __u64 caps; -+ -+ /* The test checks for finer cap as CAP_NET_ADMIN, -+ * CAP_PERFMON, and CAP_BPF instead of CAP_SYS_ADMIN. -+ * Thus, disable CAP_SYS_ADMIN at the beginning. -+ */ -+ if (cap_disable_effective(1ULL << CAP_SYS_ADMIN, &caps)) { -+ perror("cap_disable_effective(CAP_SYS_ADMIN)"); - return false; - } -- cap = (struct libcap *)caps; -- bpf_priv = cap->data[1].effective & (1 << (39/* CAP_BPF */ - 32)); -- perfmon_priv = cap->data[1].effective & (1 << (38/* CAP_PERFMON */ - 32)); -- if (cap_get_flag(caps, CAP_NET_ADMIN, CAP_EFFECTIVE, &net_priv)) -- perror("cap_get_flag NET"); -- if (cap_free(caps)) -- perror("cap_free"); -- return bpf_priv && perfmon_priv && net_priv == CAP_SET; -+ -+ return (caps & ADMIN_CAPS) == ADMIN_CAPS; - } - - static void get_unpriv_disabled() diff --git a/target/linux/generic/backport-5.15/060-v5.18-03-bpf-selftests-Remove-libcap-usage-from-test_progs.patch b/target/linux/generic/backport-5.15/060-v5.18-03-bpf-selftests-Remove-libcap-usage-from-test_progs.patch deleted file mode 100644 index 9badba7f8eaa36..00000000000000 --- a/target/linux/generic/backport-5.15/060-v5.18-03-bpf-selftests-Remove-libcap-usage-from-test_progs.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 1ac00fea13c576e2b13dabf9a72ad3034e3bb804 Mon Sep 17 00:00:00 2001 -From: Martin KaFai Lau -Date: Wed, 16 Mar 2022 10:38:35 -0700 -Subject: [PATCH 3/3] bpf: selftests: Remove libcap usage from test_progs - -This patch removes the libcap usage from test_progs. -bind_perm.c is the only user. cap_*_effective() helpers added in the -earlier patch are directly used instead. - -No other selftest binary is using libcap, so '-lcap' is also removed -from the Makefile. - -Signed-off-by: Martin KaFai Lau -Signed-off-by: Alexei Starovoitov -Reviewed-by: Stanislav Fomichev -Acked-by: John Fastabend -Link: https://lore.kernel.org/bpf/20220316173835.2039334-1-kafai@fb.com ---- - tools/testing/selftests/bpf/Makefile | 5 ++- - .../selftests/bpf/prog_tests/bind_perm.c | 44 ++++--------------- - 2 files changed, 11 insertions(+), 38 deletions(-) - ---- a/tools/testing/selftests/bpf/Makefile -+++ b/tools/testing/selftests/bpf/Makefile -@@ -26,7 +26,7 @@ CFLAGS += -g -O0 -rdynamic -Wall $(GENFL - -I$(TOOLSINCDIR) -I$(APIDIR) -I$(OUTPUT) \ - -Dbpf_prog_load=bpf_prog_test_load \ - -Dbpf_load_program=bpf_test_load_program --LDLIBS += -lcap -lelf -lz -lrt -lpthread -+LDLIBS += -lelf -lz -lrt -lpthread - - # Silence some warnings when compiled with clang - ifneq ($(LLVM),) -@@ -471,7 +471,8 @@ TRUNNER_TESTS_DIR := prog_tests - TRUNNER_BPF_PROGS_DIR := progs - TRUNNER_EXTRA_SOURCES := test_progs.c cgroup_helpers.c trace_helpers.c \ - network_helpers.c testing_helpers.c \ -- btf_helpers.c flow_dissector_load.h -+ btf_helpers.c flow_dissector_load.h \ -+ cap_helpers.c - TRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read $(OUTPUT)/bpf_testmod.ko \ - ima_setup.sh \ - $(wildcard progs/btf_dump_test_case_*.c) ---- a/tools/testing/selftests/bpf/prog_tests/bind_perm.c -+++ b/tools/testing/selftests/bpf/prog_tests/bind_perm.c -@@ -4,9 +4,9 @@ - #include - #include - #include --#include - - #include "test_progs.h" -+#include "cap_helpers.h" - #include "bind_perm.skel.h" - - static int duration; -@@ -49,41 +49,11 @@ close_socket: - close(fd); - } - --bool cap_net_bind_service(cap_flag_value_t flag) --{ -- const cap_value_t cap_net_bind_service = CAP_NET_BIND_SERVICE; -- cap_flag_value_t original_value; -- bool was_effective = false; -- cap_t caps; -- -- caps = cap_get_proc(); -- if (CHECK(!caps, "cap_get_proc", "errno %d", errno)) -- goto free_caps; -- -- if (CHECK(cap_get_flag(caps, CAP_NET_BIND_SERVICE, CAP_EFFECTIVE, -- &original_value), -- "cap_get_flag", "errno %d", errno)) -- goto free_caps; -- -- was_effective = (original_value == CAP_SET); -- -- if (CHECK(cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_net_bind_service, -- flag), -- "cap_set_flag", "errno %d", errno)) -- goto free_caps; -- -- if (CHECK(cap_set_proc(caps), "cap_set_proc", "errno %d", errno)) -- goto free_caps; -- --free_caps: -- CHECK(cap_free(caps), "cap_free", "errno %d", errno); -- return was_effective; --} -- - void test_bind_perm(void) - { -- bool cap_was_effective; -+ const __u64 net_bind_svc_cap = 1ULL << CAP_NET_BIND_SERVICE; - struct bind_perm *skel; -+ __u64 old_caps = 0; - int cgroup_fd; - - if (create_netns()) -@@ -105,7 +75,8 @@ void test_bind_perm(void) - if (!ASSERT_OK_PTR(skel, "bind_v6_prog")) - goto close_skeleton; - -- cap_was_effective = cap_net_bind_service(CAP_CLEAR); -+ ASSERT_OK(cap_disable_effective(net_bind_svc_cap, &old_caps), -+ "cap_disable_effective"); - - try_bind(AF_INET, 110, EACCES); - try_bind(AF_INET6, 110, EACCES); -@@ -113,8 +84,9 @@ void test_bind_perm(void) - try_bind(AF_INET, 111, 0); - try_bind(AF_INET6, 111, 0); - -- if (cap_was_effective) -- cap_net_bind_service(CAP_SET); -+ if (old_caps & net_bind_svc_cap) -+ ASSERT_OK(cap_enable_effective(net_bind_svc_cap, NULL), -+ "cap_enable_effective"); - - close_skeleton: - bind_perm__destroy(skel); diff --git a/target/linux/generic/backport-5.15/080-v5.17-clk-gate-Add-devm_clk_hw_register_gate.patch b/target/linux/generic/backport-5.15/080-v5.17-clk-gate-Add-devm_clk_hw_register_gate.patch deleted file mode 100644 index 819cc292e860ee..00000000000000 --- a/target/linux/generic/backport-5.15/080-v5.17-clk-gate-Add-devm_clk_hw_register_gate.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 815f0e738a8d5663a02350e2580706829144a722 Mon Sep 17 00:00:00 2001 -From: Horatiu Vultur -Date: Wed, 3 Nov 2021 09:50:59 +0100 -Subject: [PATCH] clk: gate: Add devm_clk_hw_register_gate() - -Add devm_clk_hw_register_gate() - devres-managed version of -clk_hw_register_gate() - -Suggested-by: Stephen Boyd -Signed-off-by: Horatiu Vultur -Acked-by: Nicolas Ferre -Signed-off-by: Nicolas Ferre -Link: https://lore.kernel.org/r/20211103085102.1656081-2-horatiu.vultur@microchip.com ---- - drivers/clk/clk-gate.c | 35 +++++++++++++++++++++++++++++++++++ - include/linux/clk-provider.h | 23 +++++++++++++++++++++++ - 2 files changed, 58 insertions(+) - ---- a/drivers/clk/clk-gate.c -+++ b/drivers/clk/clk-gate.c -@@ -7,6 +7,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -222,3 +223,37 @@ void clk_hw_unregister_gate(struct clk_h - kfree(gate); - } - EXPORT_SYMBOL_GPL(clk_hw_unregister_gate); -+ -+static void devm_clk_hw_release_gate(struct device *dev, void *res) -+{ -+ clk_hw_unregister_gate(*(struct clk_hw **)res); -+} -+ -+struct clk_hw *__devm_clk_hw_register_gate(struct device *dev, -+ struct device_node *np, const char *name, -+ const char *parent_name, const struct clk_hw *parent_hw, -+ const struct clk_parent_data *parent_data, -+ unsigned long flags, -+ void __iomem *reg, u8 bit_idx, -+ u8 clk_gate_flags, spinlock_t *lock) -+{ -+ struct clk_hw **ptr, *hw; -+ -+ ptr = devres_alloc(devm_clk_hw_release_gate, sizeof(*ptr), GFP_KERNEL); -+ if (!ptr) -+ return ERR_PTR(-ENOMEM); -+ -+ hw = __clk_hw_register_gate(dev, np, name, parent_name, parent_hw, -+ parent_data, flags, reg, bit_idx, -+ clk_gate_flags, lock); -+ -+ if (!IS_ERR(hw)) { -+ *ptr = hw; -+ devres_add(dev, ptr); -+ } else { -+ devres_free(ptr); -+ } -+ -+ return hw; -+} -+EXPORT_SYMBOL_GPL(__devm_clk_hw_register_gate); ---- a/include/linux/clk-provider.h -+++ b/include/linux/clk-provider.h -@@ -517,6 +517,13 @@ struct clk_hw *__clk_hw_register_gate(st - unsigned long flags, - void __iomem *reg, u8 bit_idx, - u8 clk_gate_flags, spinlock_t *lock); -+struct clk_hw *__devm_clk_hw_register_gate(struct device *dev, -+ struct device_node *np, const char *name, -+ const char *parent_name, const struct clk_hw *parent_hw, -+ const struct clk_parent_data *parent_data, -+ unsigned long flags, -+ void __iomem *reg, u8 bit_idx, -+ u8 clk_gate_flags, spinlock_t *lock); - struct clk *clk_register_gate(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, - void __iomem *reg, u8 bit_idx, -@@ -571,6 +578,22 @@ struct clk *clk_register_gate(struct dev - __clk_hw_register_gate((dev), NULL, (name), NULL, NULL, (parent_data), \ - (flags), (reg), (bit_idx), \ - (clk_gate_flags), (lock)) -+/** -+ * devm_clk_hw_register_gate - register a gate clock with the clock framework -+ * @dev: device that is registering this clock -+ * @name: name of this clock -+ * @parent_name: name of this clock's parent -+ * @flags: framework-specific flags for this clock -+ * @reg: register address to control gating of this clock -+ * @bit_idx: which bit in the register controls gating of this clock -+ * @clk_gate_flags: gate-specific flags for this clock -+ * @lock: shared register lock for this clock -+ */ -+#define devm_clk_hw_register_gate(dev, name, parent_name, flags, reg, bit_idx,\ -+ clk_gate_flags, lock) \ -+ __devm_clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL, \ -+ NULL, (flags), (reg), (bit_idx), \ -+ (clk_gate_flags), (lock)) - void clk_unregister_gate(struct clk *clk); - void clk_hw_unregister_gate(struct clk_hw *hw); - int clk_gate_is_enabled(struct clk_hw *hw); diff --git a/target/linux/generic/backport-5.15/100-v5.18-tty-serial-bcm63xx-use-more-precise-Kconfig-symbol.patch b/target/linux/generic/backport-5.15/100-v5.18-tty-serial-bcm63xx-use-more-precise-Kconfig-symbol.patch deleted file mode 100644 index 7de3cbbda0758c..00000000000000 --- a/target/linux/generic/backport-5.15/100-v5.18-tty-serial-bcm63xx-use-more-precise-Kconfig-symbol.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0dc0da881b4574d1e04a079ab2ea75da61f5ad2e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 11 Mar 2022 10:32:33 +0100 -Subject: [PATCH] tty: serial: bcm63xx: use more precise Kconfig symbol -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Patches lowering SERIAL_BCM63XX dependencies led to a discussion and -documentation change regarding "depends" usage. Adjust Kconfig entry to -match current guidelines. Make this symbol available for relevant -architectures only. - -Cc: Geert Uytterhoeven -Reviewed-by: Geert Uytterhoeven -Acked-by: Florian Fainelli -Signed-off-by: Rafał Miłecki -Ref: f35a07f92616 ("tty: serial: bcm63xx: lower driver dependencies") -Ref: 18084e435ff6 ("Documentation/kbuild: Document platform dependency practises") -Link: https://lore.kernel.org/r/20220311093233.10012-1-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/tty/serial/Kconfig | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/tty/serial/Kconfig -+++ b/drivers/tty/serial/Kconfig -@@ -1098,7 +1098,8 @@ config SERIAL_TIMBERDALE - config SERIAL_BCM63XX - tristate "Broadcom BCM63xx/BCM33xx UART support" - select SERIAL_CORE -- depends on COMMON_CLK -+ depends on ARCH_BCM4908 || ARCH_BCM_63XX || BCM63XX || BMIPS_GENERIC || COMPILE_TEST -+ default ARCH_BCM4908 || ARCH_BCM_63XX || BCM63XX || BMIPS_GENERIC - help - This enables the driver for the onchip UART core found on - the following chipsets: diff --git a/target/linux/generic/backport-5.15/200-v5.18-tools-resolve_btfids-Build-with-host-flags.patch b/target/linux/generic/backport-5.15/200-v5.18-tools-resolve_btfids-Build-with-host-flags.patch deleted file mode 100644 index caec8db5d692b0..00000000000000 --- a/target/linux/generic/backport-5.15/200-v5.18-tools-resolve_btfids-Build-with-host-flags.patch +++ /dev/null @@ -1,49 +0,0 @@ -From cdbc4e3399ed8cdcf234a85f7a2482b622379e82 Mon Sep 17 00:00:00 2001 -From: Connor O'Brien -Date: Wed, 12 Jan 2022 00:25:03 +0000 -Subject: [PATCH] tools/resolve_btfids: Build with host flags - -resolve_btfids is built using $(HOSTCC) and $(HOSTLD) but does not -pick up the corresponding flags. As a result, host-specific settings -(such as a sysroot specified via HOSTCFLAGS=--sysroot=..., or a linker -specified via HOSTLDFLAGS=-fuse-ld=...) will not be respected. - -Fix this by setting CFLAGS to KBUILD_HOSTCFLAGS and LDFLAGS to -KBUILD_HOSTLDFLAGS. - -Also pass the cflags through to libbpf via EXTRA_CFLAGS to ensure that -the host libbpf is built with flags consistent with resolve_btfids. - -Signed-off-by: Connor O'Brien -Signed-off-by: Andrii Nakryiko -Acked-by: Song Liu -Link: https://lore.kernel.org/bpf/20220112002503.115968-1-connoro@google.com -(cherry picked from commit 0e3a1c902ffb56e9fe4416f0cd382c97b09ecbf6) -Signed-off-by: Stijn Tintel ---- - tools/bpf/resolve_btfids/Makefile | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/tools/bpf/resolve_btfids/Makefile -+++ b/tools/bpf/resolve_btfids/Makefile -@@ -23,6 +23,8 @@ CC = $(HOSTCC) - LD = $(HOSTLD) - ARCH = $(HOSTARCH) - RM ?= rm -+CFLAGS := $(KBUILD_HOSTCFLAGS) -+LDFLAGS := $(KBUILD_HOSTLDFLAGS) - - OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/ - -@@ -45,9 +47,9 @@ $(SUBCMDOBJ): fixdep FORCE | $(OUTPUT)/l - $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(abspath $(dir $@))/ $(abspath $@) - - $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)/libbpf -- $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) OUTPUT=$(abspath $(dir $@))/ $(abspath $@) -+ $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) OUTPUT=$(abspath $(dir $@))/ EXTRA_CFLAGS="$(CFLAGS)" $(abspath $@) - --CFLAGS := -g \ -+CFLAGS += -g \ - -I$(srctree)/tools/include \ - -I$(srctree)/tools/include/uapi \ - -I$(LIBBPF_SRC) \ diff --git a/target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch b/target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch deleted file mode 100644 index d1bef74f327aee..00000000000000 --- a/target/linux/generic/backport-5.15/201-v5.16-scripts-dtc-Update-to-upstream-version-v1.6.1-19-g0a.patch +++ /dev/null @@ -1,997 +0,0 @@ -From a77725a9a3c5924e2fd4cd5b3557dd92a8e46f87 Mon Sep 17 00:00:00 2001 -From: Rob Herring -Date: Mon, 25 Oct 2021 11:05:45 -0500 -Subject: [PATCH 1/1] scripts/dtc: Update to upstream version - v1.6.1-19-g0a3a9d3449c8 - -This adds the following commits from upstream: - -0a3a9d3449c8 checks: Add an interrupt-map check -8fd24744e361 checks: Ensure '#interrupt-cells' only exists in interrupt providers -d8d1a9a77863 checks: Drop interrupt provider '#address-cells' check -52a16fd72824 checks: Make interrupt_provider check dependent on interrupts_extended_is_cell -37fd700685da treesource: Maintain phandle label/path on output -e33ce1d6a8c7 flattree: Use '\n', not ';' to separate asm pseudo-ops -d24cc189dca6 asm: Use assembler macros instead of cpp macros -ff3a30c115ad asm: Use .asciz and .ascii instead of .string -5eb5927d81ee fdtdump: fix -Werror=int-to-pointer-cast -0869f8269161 libfdt: Add ALIGNMENT error string -69595a167f06 checks: Fix bus-range check -72d09e2682a4 Makefile: add -Wsign-compare to warning options -b587787ef388 checks: Fix signedness comparisons warnings -69bed6c2418f dtc: Wrap phandle validity check -910221185560 fdtget: Fix signedness comparisons warnings -d966f08fcd21 tests: Fix signedness comparisons warnings -ecfb438c07fa dtc: Fix signedness comparisons warnings: pointer diff -5bec74a6d135 dtc: Fix signedness comparisons warnings: reservednum -24e7f511fd4a fdtdump: Fix signedness comparisons warnings -b6910bec1161 Bump version to v1.6.1 -21d61d18f968 Fix CID 1461557 -4c2ef8f4d14c checks: Introduce is_multiple_of() -e59ca36fb70e Make handling of cpp line information more tolerant -0c3fd9b6aceb checks: Drop interrupt_cells_is_cell check -6b3081abc4ac checks: Add check_is_cell() for all phandle+arg properties -2dffc192a77f yamltree: Remove marker ordering dependency -61e513439e40 pylibfdt: Rework "avoid unused variable warning" lines -c8bddd106095 tests: add a positive gpio test case -ad4abfadb687 checks: replace strstr and strrchr with strends -09c6a6e88718 dtc.h: add strends for suffix matching -9bb9b8d0b4a0 checks: tigthen up nr-gpios prop exception -b07b62ee3342 libfdt: Add FDT alignment check to fdt_check_header() -a2def5479950 libfdt: Check that the root-node name is empty -4ca61f84dc21 libfdt: Check that there is only one root node -34d708249a91 dtc: Remove -O dtbo support -8e7ff260f755 libfdt: Fix a possible "unchecked return value" warning -88875268c05c checks: Warn on node-name and property name being the same -9d2279e7e6ee checks: Change node-name check to match devicetree spec -f527c867a8c6 util: limit gnu_printf format attribute to gcc >= 4.4.0 - -Reviewed-by: Frank Rowand -Tested-by: Frank Rowand -Signed-off-by: Rob Herring ---- - scripts/dtc/checks.c | 222 ++++++++++++++++++++++-------- - scripts/dtc/dtc-lexer.l | 2 +- - scripts/dtc/dtc.c | 6 +- - scripts/dtc/dtc.h | 40 +++++- - scripts/dtc/flattree.c | 11 +- - scripts/dtc/libfdt/fdt.c | 4 + - scripts/dtc/libfdt/fdt_rw.c | 18 ++- - scripts/dtc/libfdt/fdt_strerror.c | 1 + - scripts/dtc/libfdt/libfdt.h | 7 + - scripts/dtc/livetree.c | 6 +- - scripts/dtc/treesource.c | 48 +++---- - scripts/dtc/util.h | 6 +- - scripts/dtc/version_gen.h | 2 +- - scripts/dtc/yamltree.c | 16 ++- - 14 files changed, 275 insertions(+), 114 deletions(-) - ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -143,6 +143,14 @@ static void check_nodes_props(struct che - check_nodes_props(c, dti, child); - } - -+static bool is_multiple_of(int multiple, int divisor) -+{ -+ if (divisor == 0) -+ return multiple == 0; -+ else -+ return (multiple % divisor) == 0; -+} -+ - static bool run_check(struct check *c, struct dt_info *dti) - { - struct node *dt = dti->dt; -@@ -297,19 +305,20 @@ ERROR(duplicate_property_names, check_du - #define LOWERCASE "abcdefghijklmnopqrstuvwxyz" - #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - #define DIGITS "0123456789" --#define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" -+#define NODECHARS LOWERCASE UPPERCASE DIGITS ",._+-@" -+#define PROPCHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" - #define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-" - - static void check_node_name_chars(struct check *c, struct dt_info *dti, - struct node *node) - { -- int n = strspn(node->name, c->data); -+ size_t n = strspn(node->name, c->data); - - if (n < strlen(node->name)) - FAIL(c, dti, node, "Bad character '%c' in node name", - node->name[n]); - } --ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); -+ERROR(node_name_chars, check_node_name_chars, NODECHARS); - - static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, - struct node *node) -@@ -330,6 +339,20 @@ static void check_node_name_format(struc - } - ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); - -+static void check_node_name_vs_property_name(struct check *c, -+ struct dt_info *dti, -+ struct node *node) -+{ -+ if (!node->parent) -+ return; -+ -+ if (get_property(node->parent, node->name)) { -+ FAIL(c, dti, node, "node name and property name conflict"); -+ } -+} -+WARNING(node_name_vs_property_name, check_node_name_vs_property_name, -+ NULL, &node_name_chars); -+ - static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, - struct node *node) - { -@@ -363,14 +386,14 @@ static void check_property_name_chars(st - struct property *prop; - - for_each_property(node, prop) { -- int n = strspn(prop->name, c->data); -+ size_t n = strspn(prop->name, c->data); - - if (n < strlen(prop->name)) - FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name", - prop->name[n]); - } - } --ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); -+ERROR(property_name_chars, check_property_name_chars, PROPCHARS); - - static void check_property_name_chars_strict(struct check *c, - struct dt_info *dti, -@@ -380,7 +403,7 @@ static void check_property_name_chars_st - - for_each_property(node, prop) { - const char *name = prop->name; -- int n = strspn(name, c->data); -+ size_t n = strspn(name, c->data); - - if (n == strlen(prop->name)) - continue; -@@ -497,7 +520,7 @@ static cell_t check_phandle_prop(struct - - phandle = propval_cell(prop); - -- if ((phandle == 0) || (phandle == -1)) { -+ if (!phandle_is_valid(phandle)) { - FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property", - phandle, prop->name); - return 0; -@@ -556,7 +579,7 @@ static void check_name_properties(struct - if (!prop) - return; /* No name property, that's fine */ - -- if ((prop->val.len != node->basenamelen+1) -+ if ((prop->val.len != node->basenamelen + 1U) - || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { - FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead" - " of base node name)", prop->val.val); -@@ -657,7 +680,6 @@ ERROR(omit_unused_nodes, fixup_omit_unus - */ - WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells"); - WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells"); --WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells"); - - WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); - WARNING_IF_NOT_STRING(model_is_string, "model"); -@@ -672,8 +694,7 @@ static void check_names_is_string_list(s - struct property *prop; - - for_each_property(node, prop) { -- const char *s = strrchr(prop->name, '-'); -- if (!s || !streq(s, "-names")) -+ if (!strends(prop->name, "-names")) - continue; - - c->data = prop->name; -@@ -753,7 +774,7 @@ static void check_reg_format(struct chec - size_cells = node_size_cells(node->parent); - entrylen = (addr_cells + size_cells) * sizeof(cell_t); - -- if (!entrylen || (prop->val.len % entrylen) != 0) -+ if (!is_multiple_of(prop->val.len, entrylen)) - FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) " - "(#address-cells == %d, #size-cells == %d)", - prop->val.len, addr_cells, size_cells); -@@ -794,7 +815,7 @@ static void check_ranges_format(struct c - "#size-cells (%d) differs from %s (%d)", - ranges, c_size_cells, node->parent->fullpath, - p_size_cells); -- } else if ((prop->val.len % entrylen) != 0) { -+ } else if (!is_multiple_of(prop->val.len, entrylen)) { - FAIL_PROP(c, dti, node, prop, "\"%s\" property has invalid length (%d bytes) " - "(parent #address-cells == %d, child #address-cells == %d, " - "#size-cells == %d)", ranges, prop->val.len, -@@ -871,7 +892,7 @@ static void check_pci_device_bus_num(str - } else { - cells = (cell_t *)prop->val.val; - min_bus = fdt32_to_cpu(cells[0]); -- max_bus = fdt32_to_cpu(cells[0]); -+ max_bus = fdt32_to_cpu(cells[1]); - } - if ((bus_num < min_bus) || (bus_num > max_bus)) - FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)", -@@ -1367,9 +1388,9 @@ static void check_property_phandle_args( - const struct provider *provider) - { - struct node *root = dti->dt; -- int cell, cellsize = 0; -+ unsigned int cell, cellsize = 0; - -- if (prop->val.len % sizeof(cell_t)) { -+ if (!is_multiple_of(prop->val.len, sizeof(cell_t))) { - FAIL_PROP(c, dti, node, prop, - "property size (%d) is invalid, expected multiple of %zu", - prop->val.len, sizeof(cell_t)); -@@ -1379,14 +1400,14 @@ static void check_property_phandle_args( - for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) { - struct node *provider_node; - struct property *cellprop; -- int phandle; -+ cell_t phandle; - - phandle = propval_cell_n(prop, cell); - /* - * Some bindings use a cell value 0 or -1 to skip over optional - * entries when each index position has a specific definition. - */ -- if (phandle == 0 || phandle == -1) { -+ if (!phandle_is_valid(phandle)) { - /* Give up if this is an overlay with external references */ - if (dti->dtsflags & DTSF_PLUGIN) - break; -@@ -1452,7 +1473,8 @@ static void check_provider_cells_propert - } - #define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \ - static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \ -- WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references); -+ WARNING_IF_NOT_CELL(nm##_is_cell, cells_name); \ -+ WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &nm##_is_cell, &phandle_references); - - WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells"); - WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells"); -@@ -1473,24 +1495,17 @@ WARNING_PROPERTY_PHANDLE_CELLS(thermal_s - - static bool prop_is_gpio(struct property *prop) - { -- char *str; -- - /* - * *-gpios and *-gpio can appear in property names, - * so skip over any false matches (only one known ATM) - */ -- if (strstr(prop->name, "nr-gpio")) -+ if (strends(prop->name, ",nr-gpios")) - return false; - -- str = strrchr(prop->name, '-'); -- if (str) -- str++; -- else -- str = prop->name; -- if (!(streq(str, "gpios") || streq(str, "gpio"))) -- return false; -- -- return true; -+ return strends(prop->name, "-gpios") || -+ streq(prop->name, "gpios") || -+ strends(prop->name, "-gpio") || -+ streq(prop->name, "gpio"); - } - - static void check_gpios_property(struct check *c, -@@ -1525,13 +1540,10 @@ static void check_deprecated_gpio_proper - struct property *prop; - - for_each_property(node, prop) { -- char *str; -- - if (!prop_is_gpio(prop)) - continue; - -- str = strstr(prop->name, "gpio"); -- if (!streq(str, "gpio")) -+ if (!strends(prop->name, "gpio")) - continue; - - FAIL_PROP(c, dti, node, prop, -@@ -1561,21 +1573,106 @@ static void check_interrupt_provider(str - struct node *node) - { - struct property *prop; -+ bool irq_provider = node_is_interrupt_provider(node); - -- if (!node_is_interrupt_provider(node)) -+ prop = get_property(node, "#interrupt-cells"); -+ if (irq_provider && !prop) { -+ FAIL(c, dti, node, -+ "Missing '#interrupt-cells' in interrupt provider"); - return; -+ } - -- prop = get_property(node, "#interrupt-cells"); -- if (!prop) -+ if (!irq_provider && prop) { - FAIL(c, dti, node, -- "Missing #interrupt-cells in interrupt provider"); -+ "'#interrupt-cells' found, but node is not an interrupt provider"); -+ return; -+ } -+} -+WARNING(interrupt_provider, check_interrupt_provider, NULL, &interrupts_extended_is_cell); - -- prop = get_property(node, "#address-cells"); -- if (!prop) -+static void check_interrupt_map(struct check *c, -+ struct dt_info *dti, -+ struct node *node) -+{ -+ struct node *root = dti->dt; -+ struct property *prop, *irq_map_prop; -+ size_t cellsize, cell, map_cells; -+ -+ irq_map_prop = get_property(node, "interrupt-map"); -+ if (!irq_map_prop) -+ return; -+ -+ if (node->addr_cells < 0) { - FAIL(c, dti, node, -- "Missing #address-cells in interrupt provider"); -+ "Missing '#address-cells' in interrupt-map provider"); -+ return; -+ } -+ cellsize = node_addr_cells(node); -+ cellsize += propval_cell(get_property(node, "#interrupt-cells")); -+ -+ prop = get_property(node, "interrupt-map-mask"); -+ if (prop && (prop->val.len != (cellsize * sizeof(cell_t)))) -+ FAIL_PROP(c, dti, node, prop, -+ "property size (%d) is invalid, expected %zu", -+ prop->val.len, cellsize * sizeof(cell_t)); -+ -+ if (!is_multiple_of(irq_map_prop->val.len, sizeof(cell_t))) { -+ FAIL_PROP(c, dti, node, irq_map_prop, -+ "property size (%d) is invalid, expected multiple of %zu", -+ irq_map_prop->val.len, sizeof(cell_t)); -+ return; -+ } -+ -+ map_cells = irq_map_prop->val.len / sizeof(cell_t); -+ for (cell = 0; cell < map_cells; ) { -+ struct node *provider_node; -+ struct property *cellprop; -+ int phandle; -+ size_t parent_cellsize; -+ -+ if ((cell + cellsize) >= map_cells) { -+ FAIL_PROP(c, dti, node, irq_map_prop, -+ "property size (%d) too small, expected > %zu", -+ irq_map_prop->val.len, (cell + cellsize) * sizeof(cell_t)); -+ break; -+ } -+ cell += cellsize; -+ -+ phandle = propval_cell_n(irq_map_prop, cell); -+ if (!phandle_is_valid(phandle)) { -+ /* Give up if this is an overlay with external references */ -+ if (!(dti->dtsflags & DTSF_PLUGIN)) -+ FAIL_PROP(c, dti, node, irq_map_prop, -+ "Cell %zu is not a phandle(%d)", -+ cell, phandle); -+ break; -+ } -+ -+ provider_node = get_node_by_phandle(root, phandle); -+ if (!provider_node) { -+ FAIL_PROP(c, dti, node, irq_map_prop, -+ "Could not get phandle(%d) node for (cell %zu)", -+ phandle, cell); -+ break; -+ } -+ -+ cellprop = get_property(provider_node, "#interrupt-cells"); -+ if (cellprop) { -+ parent_cellsize = propval_cell(cellprop); -+ } else { -+ FAIL(c, dti, node, "Missing property '#interrupt-cells' in node %s or bad phandle (referred from interrupt-map[%zu])", -+ provider_node->fullpath, cell); -+ break; -+ } -+ -+ cellprop = get_property(provider_node, "#address-cells"); -+ if (cellprop) -+ parent_cellsize += propval_cell(cellprop); -+ -+ cell += 1 + parent_cellsize; -+ } - } --WARNING(interrupt_provider, check_interrupt_provider, NULL); -+WARNING(interrupt_map, check_interrupt_map, NULL, &phandle_references, &addr_size_cells, &interrupt_provider); - - static void check_interrupts_property(struct check *c, - struct dt_info *dti, -@@ -1584,13 +1681,13 @@ static void check_interrupts_property(st - struct node *root = dti->dt; - struct node *irq_node = NULL, *parent = node; - struct property *irq_prop, *prop = NULL; -- int irq_cells, phandle; -+ cell_t irq_cells, phandle; - - irq_prop = get_property(node, "interrupts"); - if (!irq_prop) - return; - -- if (irq_prop->val.len % sizeof(cell_t)) -+ if (!is_multiple_of(irq_prop->val.len, sizeof(cell_t))) - FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu", - irq_prop->val.len, sizeof(cell_t)); - -@@ -1603,7 +1700,7 @@ static void check_interrupts_property(st - prop = get_property(parent, "interrupt-parent"); - if (prop) { - phandle = propval_cell(prop); -- if ((phandle == 0) || (phandle == -1)) { -+ if (!phandle_is_valid(phandle)) { - /* Give up if this is an overlay with - * external references */ - if (dti->dtsflags & DTSF_PLUGIN) -@@ -1639,7 +1736,7 @@ static void check_interrupts_property(st - } - - irq_cells = propval_cell(prop); -- if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) { -+ if (!is_multiple_of(irq_prop->val.len, irq_cells * sizeof(cell_t))) { - FAIL_PROP(c, dti, node, prop, - "size is (%d), expected multiple of %d", - irq_prop->val.len, (int)(irq_cells * sizeof(cell_t))); -@@ -1750,7 +1847,7 @@ WARNING(graph_port, check_graph_port, NU - static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti, - struct node *endpoint) - { -- int phandle; -+ cell_t phandle; - struct node *node; - struct property *prop; - -@@ -1760,7 +1857,7 @@ static struct node *get_remote_endpoint( - - phandle = propval_cell(prop); - /* Give up if this is an overlay with external references */ -- if (phandle == 0 || phandle == -1) -+ if (!phandle_is_valid(phandle)) - return NULL; - - node = get_node_by_phandle(dti->dt, phandle); -@@ -1796,7 +1893,7 @@ WARNING(graph_endpoint, check_graph_endp - static struct check *check_table[] = { - &duplicate_node_names, &duplicate_property_names, - &node_name_chars, &node_name_format, &property_name_chars, -- &name_is_string, &name_properties, -+ &name_is_string, &name_properties, &node_name_vs_property_name, - - &duplicate_label, - -@@ -1804,7 +1901,7 @@ static struct check *check_table[] = { - &phandle_references, &path_references, - &omit_unused_nodes, - -- &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, -+ &address_cells_is_cell, &size_cells_is_cell, - &device_type_is_string, &model_is_string, &status_is_string, - &label_is_string, - -@@ -1839,26 +1936,43 @@ static struct check *check_table[] = { - &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path, - - &clocks_property, -+ &clocks_is_cell, - &cooling_device_property, -+ &cooling_device_is_cell, - &dmas_property, -+ &dmas_is_cell, - &hwlocks_property, -+ &hwlocks_is_cell, - &interrupts_extended_property, -+ &interrupts_extended_is_cell, - &io_channels_property, -+ &io_channels_is_cell, - &iommus_property, -+ &iommus_is_cell, - &mboxes_property, -+ &mboxes_is_cell, - &msi_parent_property, -+ &msi_parent_is_cell, - &mux_controls_property, -+ &mux_controls_is_cell, - &phys_property, -+ &phys_is_cell, - &power_domains_property, -+ &power_domains_is_cell, - &pwms_property, -+ &pwms_is_cell, - &resets_property, -+ &resets_is_cell, - &sound_dai_property, -+ &sound_dai_is_cell, - &thermal_sensors_property, -+ &thermal_sensors_is_cell, - - &deprecated_gpio_property, - &gpios_property, - &interrupts_property, - &interrupt_provider, -+ &interrupt_map, - - &alias_paths, - -@@ -1882,7 +1996,7 @@ static void enable_warning_error(struct - - static void disable_warning_error(struct check *c, bool warn, bool error) - { -- int i; -+ unsigned int i; - - /* Lowering level, also lower it for things this is the prereq - * for */ -@@ -1903,7 +2017,7 @@ static void disable_warning_error(struct - - void parse_checks_option(bool warn, bool error, const char *arg) - { -- int i; -+ unsigned int i; - const char *name = arg; - bool enable = true; - -@@ -1930,7 +2044,7 @@ void parse_checks_option(bool warn, bool - - void process_checks(bool force, struct dt_info *dti) - { -- int i; -+ unsigned int i; - int error = 0; - - for (i = 0; i < ARRAY_SIZE(check_table); i++) { ---- a/scripts/dtc/dtc-lexer.l -+++ b/scripts/dtc/dtc-lexer.l -@@ -57,7 +57,7 @@ static void PRINTF(1, 2) lexical_error(c - push_input_file(name); - } - --<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { -+<*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)* { - char *line, *fnstart, *fnend; - struct data fn; - /* skip text before line # */ ---- a/scripts/dtc/dtc.c -+++ b/scripts/dtc/dtc.c -@@ -12,7 +12,7 @@ - * Command line options - */ - int quiet; /* Level of quietness */ --int reservenum; /* Number of memory reservation slots */ -+unsigned int reservenum;/* Number of memory reservation slots */ - int minsize; /* Minimum blob size */ - int padsize; /* Additional padding to blob */ - int alignsize; /* Additional padding to blob accroding to the alignsize */ -@@ -197,7 +197,7 @@ int main(int argc, char *argv[]) - depname = optarg; - break; - case 'R': -- reservenum = strtol(optarg, NULL, 0); -+ reservenum = strtoul(optarg, NULL, 0); - break; - case 'S': - minsize = strtol(optarg, NULL, 0); -@@ -359,8 +359,6 @@ int main(int argc, char *argv[]) - #endif - } else if (streq(outform, "dtb")) { - dt_to_blob(outf, dti, outversion); -- } else if (streq(outform, "dtbo")) { -- dt_to_blob(outf, dti, outversion); - } else if (streq(outform, "asm")) { - dt_to_asm(outf, dti, outversion); - } else if (streq(outform, "null")) { ---- a/scripts/dtc/dtc.h -+++ b/scripts/dtc/dtc.h -@@ -35,7 +35,7 @@ - * Command line options - */ - extern int quiet; /* Level of quietness */ --extern int reservenum; /* Number of memory reservation slots */ -+extern unsigned int reservenum; /* Number of memory reservation slots */ - extern int minsize; /* Minimum blob size */ - extern int padsize; /* Additional padding to blob */ - extern int alignsize; /* Additional padding to blob accroding to the alignsize */ -@@ -51,6 +51,11 @@ extern int annotate; /* annotate .dts w - - typedef uint32_t cell_t; - -+static inline bool phandle_is_valid(cell_t phandle) -+{ -+ return phandle != 0 && phandle != ~0U; -+} -+ - static inline uint16_t dtb_ld16(const void *p) - { - const uint8_t *bp = (const uint8_t *)p; -@@ -86,6 +91,16 @@ static inline uint64_t dtb_ld64(const vo - #define streq(a, b) (strcmp((a), (b)) == 0) - #define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0) - #define strprefixeq(a, n, b) (strlen(b) == (n) && (memcmp(a, b, n) == 0)) -+static inline bool strends(const char *str, const char *suffix) -+{ -+ unsigned int len, suffix_len; -+ -+ len = strlen(str); -+ suffix_len = strlen(suffix); -+ if (len < suffix_len) -+ return false; -+ return streq(str + len - suffix_len, suffix); -+} - - #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) - -@@ -101,6 +116,12 @@ enum markertype { - TYPE_UINT64, - TYPE_STRING, - }; -+ -+static inline bool is_type_marker(enum markertype type) -+{ -+ return type >= TYPE_UINT8; -+} -+ - extern const char *markername(enum markertype markertype); - - struct marker { -@@ -125,7 +146,22 @@ struct data { - for_each_marker(m) \ - if ((m)->type == (t)) - --size_t type_marker_length(struct marker *m); -+static inline struct marker *next_type_marker(struct marker *m) -+{ -+ for_each_marker(m) -+ if (is_type_marker(m->type)) -+ break; -+ return m; -+} -+ -+static inline size_t type_marker_length(struct marker *m) -+{ -+ struct marker *next = next_type_marker(m->next); -+ -+ if (next) -+ return next->offset - m->offset; -+ return 0; -+} - - void data_free(struct data d); - ---- a/scripts/dtc/flattree.c -+++ b/scripts/dtc/flattree.c -@@ -124,7 +124,8 @@ static void asm_emit_cell(void *e, cell_ - { - FILE *f = e; - -- fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n", -+ fprintf(f, "\t.byte\t0x%02x\n" "\t.byte\t0x%02x\n" -+ "\t.byte\t0x%02x\n" "\t.byte\t0x%02x\n", - (val >> 24) & 0xff, (val >> 16) & 0xff, - (val >> 8) & 0xff, val & 0xff); - } -@@ -134,9 +135,9 @@ static void asm_emit_string(void *e, con - FILE *f = e; - - if (len != 0) -- fprintf(f, "\t.string\t\"%.*s\"\n", len, str); -+ fprintf(f, "\t.asciz\t\"%.*s\"\n", len, str); - else -- fprintf(f, "\t.string\t\"%s\"\n", str); -+ fprintf(f, "\t.asciz\t\"%s\"\n", str); - } - - static void asm_emit_align(void *e, int a) -@@ -295,7 +296,7 @@ static struct data flatten_reserve_list( - { - struct reserve_info *re; - struct data d = empty_data; -- int j; -+ unsigned int j; - - for (re = reservelist; re; re = re->next) { - d = data_append_re(d, re->address, re->size); -@@ -438,7 +439,7 @@ static void dump_stringtable_asm(FILE *f - - while (p < (strbuf.val + strbuf.len)) { - len = strlen(p); -- fprintf(f, "\t.string \"%s\"\n", p); -+ fprintf(f, "\t.asciz \"%s\"\n", p); - p += len+1; - } - } ---- a/scripts/dtc/libfdt/fdt.c -+++ b/scripts/dtc/libfdt/fdt.c -@@ -90,6 +90,10 @@ int fdt_check_header(const void *fdt) - { - size_t hdrsize; - -+ /* The device tree must be at an 8-byte aligned address */ -+ if ((uintptr_t)fdt & 7) -+ return -FDT_ERR_ALIGNMENT; -+ - if (fdt_magic(fdt) != FDT_MAGIC) - return -FDT_ERR_BADMAGIC; - if (!can_assume(LATEST)) { ---- a/scripts/dtc/libfdt/fdt_rw.c -+++ b/scripts/dtc/libfdt/fdt_rw.c -@@ -349,7 +349,10 @@ int fdt_add_subnode_namelen(void *fdt, i - return offset; - - /* Try to place the new node after the parent's properties */ -- fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */ -+ tag = fdt_next_tag(fdt, parentoffset, &nextoffset); -+ /* the fdt_subnode_offset_namelen() should ensure this never hits */ -+ if (!can_assume(LIBFDT_FLAWLESS) && (tag != FDT_BEGIN_NODE)) -+ return -FDT_ERR_INTERNAL; - do { - offset = nextoffset; - tag = fdt_next_tag(fdt, offset, &nextoffset); -@@ -391,7 +394,9 @@ int fdt_del_node(void *fdt, int nodeoffs - } - - static void fdt_packblocks_(const char *old, char *new, -- int mem_rsv_size, int struct_size) -+ int mem_rsv_size, -+ int struct_size, -+ int strings_size) - { - int mem_rsv_off, struct_off, strings_off; - -@@ -406,8 +411,7 @@ static void fdt_packblocks_(const char * - fdt_set_off_dt_struct(new, struct_off); - fdt_set_size_dt_struct(new, struct_size); - -- memmove(new + strings_off, old + fdt_off_dt_strings(old), -- fdt_size_dt_strings(old)); -+ memmove(new + strings_off, old + fdt_off_dt_strings(old), strings_size); - fdt_set_off_dt_strings(new, strings_off); - fdt_set_size_dt_strings(new, fdt_size_dt_strings(old)); - } -@@ -467,7 +471,8 @@ int fdt_open_into(const void *fdt, void - return -FDT_ERR_NOSPACE; - } - -- fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size); -+ fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size, -+ fdt_size_dt_strings(fdt)); - memmove(buf, tmp, newsize); - - fdt_set_magic(buf, FDT_MAGIC); -@@ -487,7 +492,8 @@ int fdt_pack(void *fdt) - - mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) - * sizeof(struct fdt_reserve_entry); -- fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); -+ fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt), -+ fdt_size_dt_strings(fdt)); - fdt_set_totalsize(fdt, fdt_data_size_(fdt)); - - return 0; ---- a/scripts/dtc/libfdt/fdt_strerror.c -+++ b/scripts/dtc/libfdt/fdt_strerror.c -@@ -39,6 +39,7 @@ static struct fdt_errtabent fdt_errtable - FDT_ERRTABENT(FDT_ERR_BADOVERLAY), - FDT_ERRTABENT(FDT_ERR_NOPHANDLES), - FDT_ERRTABENT(FDT_ERR_BADFLAGS), -+ FDT_ERRTABENT(FDT_ERR_ALIGNMENT), - }; - #define FDT_ERRTABSIZE ((int)(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))) - ---- a/scripts/dtc/libfdt/libfdt.h -+++ b/scripts/dtc/libfdt/libfdt.h -@@ -131,6 +131,13 @@ uint32_t fdt_next_tag(const void *fdt, i - * to work even with unaligned pointers on platforms (such as ARMv5) that don't - * like unaligned loads and stores. - */ -+static inline uint16_t fdt16_ld(const fdt16_t *p) -+{ -+ const uint8_t *bp = (const uint8_t *)p; -+ -+ return ((uint16_t)bp[0] << 8) | bp[1]; -+} -+ - static inline uint32_t fdt32_ld(const fdt32_t *p) - { - const uint8_t *bp = (const uint8_t *)p; ---- a/scripts/dtc/livetree.c -+++ b/scripts/dtc/livetree.c -@@ -526,7 +526,7 @@ struct node *get_node_by_path(struct nod - p = strchr(path, '/'); - - for_each_child(tree, child) { -- if (p && strprefixeq(path, p - path, child->name)) -+ if (p && strprefixeq(path, (size_t)(p - path), child->name)) - return get_node_by_path(child, p+1); - else if (!p && streq(path, child->name)) - return child; -@@ -559,7 +559,7 @@ struct node *get_node_by_phandle(struct - { - struct node *child, *node; - -- if ((phandle == 0) || (phandle == -1)) { -+ if (!phandle_is_valid(phandle)) { - assert(generate_fixups); - return NULL; - } -@@ -594,7 +594,7 @@ cell_t get_node_phandle(struct node *roo - static cell_t phandle = 1; /* FIXME: ick, static local */ - struct data d = empty_data; - -- if ((node->phandle != 0) && (node->phandle != -1)) -+ if (phandle_is_valid(node->phandle)) - return node->phandle; - - while (get_node_by_phandle(root, phandle)) ---- a/scripts/dtc/treesource.c -+++ b/scripts/dtc/treesource.c -@@ -124,27 +124,6 @@ static void write_propval_int(FILE *f, c - } - } - --static bool has_data_type_information(struct marker *m) --{ -- return m->type >= TYPE_UINT8; --} -- --static struct marker *next_type_marker(struct marker *m) --{ -- while (m && !has_data_type_information(m)) -- m = m->next; -- return m; --} -- --size_t type_marker_length(struct marker *m) --{ -- struct marker *next = next_type_marker(m->next); -- -- if (next) -- return next->offset - m->offset; -- return 0; --} -- - static const char *delim_start[] = { - [TYPE_UINT8] = "[", - [TYPE_UINT16] = "/bits/ 16 <", -@@ -229,26 +208,39 @@ static void write_propval(FILE *f, struc - size_t chunk_len = (m->next ? m->next->offset : len) - m->offset; - size_t data_len = type_marker_length(m) ? : len - m->offset; - const char *p = &prop->val.val[m->offset]; -+ struct marker *m_phandle; - -- if (has_data_type_information(m)) { -+ if (is_type_marker(m->type)) { - emit_type = m->type; - fprintf(f, " %s", delim_start[emit_type]); - } else if (m->type == LABEL) - fprintf(f, " %s:", m->ref); -- else if (m->offset) -- fputc(' ', f); - -- if (emit_type == TYPE_NONE) { -- assert(chunk_len == 0); -+ if (emit_type == TYPE_NONE || chunk_len == 0) - continue; -- } - - switch(emit_type) { - case TYPE_UINT16: - write_propval_int(f, p, chunk_len, 2); - break; - case TYPE_UINT32: -- write_propval_int(f, p, chunk_len, 4); -+ m_phandle = prop->val.markers; -+ for_each_marker_of_type(m_phandle, REF_PHANDLE) -+ if (m->offset == m_phandle->offset) -+ break; -+ -+ if (m_phandle) { -+ if (m_phandle->ref[0] == '/') -+ fprintf(f, "&{%s}", m_phandle->ref); -+ else -+ fprintf(f, "&%s", m_phandle->ref); -+ if (chunk_len > 4) { -+ fputc(' ', f); -+ write_propval_int(f, p + 4, chunk_len - 4, 4); -+ } -+ } else { -+ write_propval_int(f, p, chunk_len, 4); -+ } - break; - case TYPE_UINT64: - write_propval_int(f, p, chunk_len, 8); ---- a/scripts/dtc/util.h -+++ b/scripts/dtc/util.h -@@ -13,10 +13,10 @@ - */ - - #ifdef __GNUC__ --#ifdef __clang__ --#define PRINTF(i, j) __attribute__((format (printf, i, j))) --#else -+#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) - #define PRINTF(i, j) __attribute__((format (gnu_printf, i, j))) -+#else -+#define PRINTF(i, j) __attribute__((format (printf, i, j))) - #endif - #define NORETURN __attribute__((noreturn)) - #else ---- a/scripts/dtc/version_gen.h -+++ b/scripts/dtc/version_gen.h -@@ -1 +1 @@ --#define DTC_VERSION "DTC 1.6.0-g183df9e9" -+#define DTC_VERSION "DTC 1.6.1-g0a3a9d34" ---- a/scripts/dtc/yamltree.c -+++ b/scripts/dtc/yamltree.c -@@ -29,11 +29,12 @@ char *yaml_error_name[] = { - (emitter)->problem, __func__, __LINE__); \ - }) - --static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, char *data, unsigned int len, int width) -+static void yaml_propval_int(yaml_emitter_t *emitter, struct marker *markers, -+ char *data, unsigned int seq_offset, unsigned int len, int width) - { - yaml_event_t event; - void *tag; -- unsigned int off, start_offset = markers->offset; -+ unsigned int off; - - switch(width) { - case 1: tag = "!u8"; break; -@@ -66,7 +67,7 @@ static void yaml_propval_int(yaml_emitte - m = markers; - is_phandle = false; - for_each_marker_of_type(m, REF_PHANDLE) { -- if (m->offset == (start_offset + off)) { -+ if (m->offset == (seq_offset + off)) { - is_phandle = true; - break; - } -@@ -114,6 +115,7 @@ static void yaml_propval(yaml_emitter_t - yaml_event_t event; - unsigned int len = prop->val.len; - struct marker *m = prop->val.markers; -+ struct marker *markers = prop->val.markers; - - /* Emit the property name */ - yaml_scalar_event_initialize(&event, NULL, -@@ -151,19 +153,19 @@ static void yaml_propval(yaml_emitter_t - - switch(m->type) { - case TYPE_UINT16: -- yaml_propval_int(emitter, m, data, chunk_len, 2); -+ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 2); - break; - case TYPE_UINT32: -- yaml_propval_int(emitter, m, data, chunk_len, 4); -+ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 4); - break; - case TYPE_UINT64: -- yaml_propval_int(emitter, m, data, chunk_len, 8); -+ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 8); - break; - case TYPE_STRING: - yaml_propval_string(emitter, data, chunk_len); - break; - default: -- yaml_propval_int(emitter, m, data, chunk_len, 1); -+ yaml_propval_int(emitter, markers, data, m->offset, chunk_len, 1); - break; - } - } diff --git a/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch b/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch deleted file mode 100644 index 786a2d93b50d5e..00000000000000 --- a/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 73bbb94466fd3f8b313eeb0b0467314a262dddb3 Mon Sep 17 00:00:00 2001 -From: Miguel Ojeda -Date: Mon, 5 Apr 2021 04:58:39 +0200 -Subject: [PATCH] kallsyms: support "big" kernel symbols - -Rust symbols can become quite long due to namespacing introduced -by modules, types, traits, generics, etc. - -Increasing to 255 is not enough in some cases, therefore -introduce longer lengths to the symbol table. - -In order to avoid increasing all lengths to 2 bytes (since most -of them are small, including many Rust ones), use ULEB128 to -keep smaller symbols in 1 byte, with the rest in 2 bytes. - -Reviewed-by: Kees Cook -Reviewed-by: Greg Kroah-Hartman -Co-developed-by: Alex Gaynor -Signed-off-by: Alex Gaynor -Co-developed-by: Wedson Almeida Filho -Signed-off-by: Wedson Almeida Filho -Co-developed-by: Gary Guo -Signed-off-by: Gary Guo -Co-developed-by: Boqun Feng -Signed-off-by: Boqun Feng -Co-developed-by: Matthew Wilcox -Signed-off-by: Matthew Wilcox -Signed-off-by: Miguel Ojeda ---- - kernel/kallsyms.c | 26 ++++++++++++++++++++++---- - scripts/kallsyms.c | 29 ++++++++++++++++++++++++++--- - 2 files changed, 48 insertions(+), 7 deletions(-) - ---- a/kernel/kallsyms.c -+++ b/kernel/kallsyms.c -@@ -69,12 +69,20 @@ static unsigned int kallsyms_expand_symb - data = &kallsyms_names[off]; - len = *data; - data++; -+ off++; -+ -+ /* If MSB is 1, it is a "big" symbol, so needs an additional byte. */ -+ if ((len & 0x80) != 0) { -+ len = (len & 0x7F) | (*data << 7); -+ data++; -+ off++; -+ } - - /* - * Update the offset to return the offset for the next symbol on - * the compressed stream. - */ -- off += len + 1; -+ off += len; - - /* - * For every byte on the compressed symbol data, copy the table -@@ -127,7 +135,7 @@ static char kallsyms_get_symbol_type(uns - static unsigned int get_symbol_offset(unsigned long pos) - { - const u8 *name; -- int i; -+ int i, len; - - /* - * Use the closest marker we have. We have markers every 256 positions, -@@ -141,8 +149,18 @@ static unsigned int get_symbol_offset(un - * so we just need to add the len to the current pointer for every - * symbol we wish to skip. - */ -- for (i = 0; i < (pos & 0xFF); i++) -- name = name + (*name) + 1; -+ for (i = 0; i < (pos & 0xFF); i++) { -+ len = *name; -+ -+ /* -+ * If MSB is 1, it is a "big" symbol, so we need to look into -+ * the next byte (and skip it, too). -+ */ -+ if ((len & 0x80) != 0) -+ len = ((len & 0x7F) | (name[1] << 7)) + 1; -+ -+ name = name + len + 1; -+ } - - return name - kallsyms_names; - } ---- a/scripts/kallsyms.c -+++ b/scripts/kallsyms.c -@@ -470,12 +470,35 @@ static void write_src(void) - if ((i & 0xFF) == 0) - markers[i >> 8] = off; - -- printf("\t.byte 0x%02x", table[i]->len); -+ /* There cannot be any symbol of length zero. */ -+ if (table[i]->len == 0) { -+ fprintf(stderr, "kallsyms failure: " -+ "unexpected zero symbol length\n"); -+ exit(EXIT_FAILURE); -+ } -+ -+ /* Only lengths that fit in up-to-two-byte ULEB128 are supported. */ -+ if (table[i]->len > 0x3FFF) { -+ fprintf(stderr, "kallsyms failure: " -+ "unexpected huge symbol length\n"); -+ exit(EXIT_FAILURE); -+ } -+ -+ /* Encode length with ULEB128. */ -+ if (table[i]->len <= 0x7F) { -+ /* Most symbols use a single byte for the length. */ -+ printf("\t.byte 0x%02x", table[i]->len); -+ off += table[i]->len + 1; -+ } else { -+ /* "Big" symbols use two bytes. */ -+ printf("\t.byte 0x%02x, 0x%02x", -+ (table[i]->len & 0x7F) | 0x80, -+ (table[i]->len >> 7) & 0x7F); -+ off += table[i]->len + 2; -+ } - for (k = 0; k < table[i]->len; k++) - printf(", 0x%02x", table[i]->sym[k]); - printf("\n"); -- -- off += table[i]->len + 1; - } - printf("\n"); - diff --git a/target/linux/generic/backport-5.15/300-v5.18-pinctrl-qcom-Return--EINVAL-for-setting-affinity-if-no-IRQ-parent.patch b/target/linux/generic/backport-5.15/300-v5.18-pinctrl-qcom-Return--EINVAL-for-setting-affinity-if-no-IRQ-parent.patch deleted file mode 100644 index 18a8752a18f49c..00000000000000 --- a/target/linux/generic/backport-5.15/300-v5.18-pinctrl-qcom-Return--EINVAL-for-setting-affinity-if-no-IRQ-parent.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: Manivannan Sadhasivam -To: linus.walleij@linaro.org -Cc: bjorn.andersson@linaro.org, dianders@chromium.org, - linux-arm-msm@vger.kernel.org, linux-gpio@vger.kernel.org, - linux-kernel@vger.kernel.org, - Manivannan Sadhasivam -Subject: [PATCH] pinctrl: qcom: Return -EINVAL for setting affinity if no IRQ - parent -Date: Thu, 13 Jan 2022 21:56:17 +0530 -Message-Id: <20220113162617.131697-1-manivannan.sadhasivam@linaro.org> - -The MSM GPIO IRQ controller relies on the parent IRQ controller to set the -CPU affinity for the IRQ. And this is only valid if there is any wakeup -parent available and defined in DT. - -For the case of no parent IRQ controller defined in DT, -msm_gpio_irq_set_affinity() and msm_gpio_irq_set_vcpu_affinity() should -return -EINVAL instead of 0 as the affinity can't be set. - -Otherwise, below warning will be printed by genirq: - -genirq: irq_chip msmgpio did not update eff. affinity mask of irq 70 - -Signed-off-by: Manivannan Sadhasivam ---- - drivers/pinctrl/qcom/pinctrl-msm.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/pinctrl/qcom/pinctrl-msm.c -+++ b/drivers/pinctrl/qcom/pinctrl-msm.c -@@ -1157,7 +1157,7 @@ static int msm_gpio_irq_set_affinity(str - if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) - return irq_chip_set_affinity_parent(d, dest, force); - -- return 0; -+ return -EINVAL; - } - - static int msm_gpio_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info) -@@ -1168,7 +1168,7 @@ static int msm_gpio_irq_set_vcpu_affinit - if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs)) - return irq_chip_set_vcpu_affinity_parent(d, vcpu_info); - -- return 0; -+ return -EINVAL; - } - - static void msm_gpio_irq_handler(struct irq_desc *desc) diff --git a/target/linux/generic/backport-5.15/301-v5.16-soc-qcom-smem-Support-reserved-memory-description.patch b/target/linux/generic/backport-5.15/301-v5.16-soc-qcom-smem-Support-reserved-memory-description.patch deleted file mode 100644 index ee0bf9309ff841..00000000000000 --- a/target/linux/generic/backport-5.15/301-v5.16-soc-qcom-smem-Support-reserved-memory-description.patch +++ /dev/null @@ -1,166 +0,0 @@ -From b5af64fceb04dc298c5e69c517b4d83893ff060b Mon Sep 17 00:00:00 2001 -From: Bjorn Andersson -Date: Thu, 30 Sep 2021 11:21:10 -0700 -Subject: [PATCH 1/1] soc: qcom: smem: Support reserved-memory description - -Practically all modern Qualcomm platforms has a single reserved-memory -region for SMEM. So rather than having to describe SMEM in the form of a -node with a reference to a reserved-memory node, allow the SMEM device -to be instantiated directly from the reserved-memory node. - -The current means of falling back to dereferencing the "memory-region" -is kept as a fallback, if it's determined that the SMEM node is a -reserved-memory node. - -The "qcom,smem" compatible is added to the reserved_mem_matches list, to -allow the reserved-memory device to be probed. - -In order to retain the readability of the code, the resolution of -resources is split from the actual ioremapping. - -Signed-off-by: Bjorn Andersson -Acked-by: Rob Herring -Reviewed-by: Vladimir Zapolskiy -Link: https://lore.kernel.org/r/20210930182111.57353-4-bjorn.andersson@linaro.org ---- - drivers/of/platform.c | 1 + - drivers/soc/qcom/smem.c | 57 ++++++++++++++++++++++++++++------------- - 2 files changed, 40 insertions(+), 18 deletions(-) - ---- a/drivers/of/platform.c -+++ b/drivers/of/platform.c -@@ -509,6 +509,7 @@ EXPORT_SYMBOL_GPL(of_platform_default_po - static const struct of_device_id reserved_mem_matches[] = { - { .compatible = "qcom,rmtfs-mem" }, - { .compatible = "qcom,cmd-db" }, -+ { .compatible = "qcom,smem" }, - { .compatible = "ramoops" }, - { .compatible = "nvmem-rmem" }, - {} ---- a/drivers/soc/qcom/smem.c -+++ b/drivers/soc/qcom/smem.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -240,7 +241,7 @@ static const u8 SMEM_INFO_MAGIC[] = { 0x - * @size: size of the memory region - */ - struct smem_region { -- u32 aux_base; -+ phys_addr_t aux_base; - void __iomem *virt_base; - size_t size; - }; -@@ -499,7 +500,7 @@ static void *qcom_smem_get_global(struct - for (i = 0; i < smem->num_regions; i++) { - region = &smem->regions[i]; - -- if (region->aux_base == aux_base || !aux_base) { -+ if ((u32)region->aux_base == aux_base || !aux_base) { - if (size != NULL) - *size = le32_to_cpu(entry->size); - return region->virt_base + le32_to_cpu(entry->offset); -@@ -664,7 +665,7 @@ phys_addr_t qcom_smem_virt_to_phys(void - if (p < region->virt_base + region->size) { - u64 offset = p - region->virt_base; - -- return (phys_addr_t)region->aux_base + offset; -+ return region->aux_base + offset; - } - } - -@@ -863,12 +864,12 @@ qcom_smem_enumerate_partitions(struct qc - return 0; - } - --static int qcom_smem_map_memory(struct qcom_smem *smem, struct device *dev, -- const char *name, int i) -+static int qcom_smem_resolve_mem(struct qcom_smem *smem, const char *name, -+ struct smem_region *region) - { -+ struct device *dev = smem->dev; - struct device_node *np; - struct resource r; -- resource_size_t size; - int ret; - - np = of_parse_phandle(dev->of_node, name, 0); -@@ -881,13 +882,9 @@ static int qcom_smem_map_memory(struct q - of_node_put(np); - if (ret) - return ret; -- size = resource_size(&r); - -- smem->regions[i].virt_base = devm_ioremap_wc(dev, r.start, size); -- if (!smem->regions[i].virt_base) -- return -ENOMEM; -- smem->regions[i].aux_base = (u32)r.start; -- smem->regions[i].size = size; -+ region->aux_base = r.start; -+ region->size = resource_size(&r); - - return 0; - } -@@ -895,12 +892,14 @@ static int qcom_smem_map_memory(struct q - static int qcom_smem_probe(struct platform_device *pdev) - { - struct smem_header *header; -+ struct reserved_mem *rmem; - struct qcom_smem *smem; - size_t array_size; - int num_regions; - int hwlock_id; - u32 version; - int ret; -+ int i; - - num_regions = 1; - if (of_find_property(pdev->dev.of_node, "qcom,rpm-msg-ram", NULL)) -@@ -914,13 +913,35 @@ static int qcom_smem_probe(struct platfo - smem->dev = &pdev->dev; - smem->num_regions = num_regions; - -- ret = qcom_smem_map_memory(smem, &pdev->dev, "memory-region", 0); -- if (ret) -- return ret; -- -- if (num_regions > 1 && (ret = qcom_smem_map_memory(smem, &pdev->dev, -- "qcom,rpm-msg-ram", 1))) -- return ret; -+ rmem = of_reserved_mem_lookup(pdev->dev.of_node); -+ if (rmem) { -+ smem->regions[0].aux_base = rmem->base; -+ smem->regions[0].size = rmem->size; -+ } else { -+ /* -+ * Fall back to the memory-region reference, if we're not a -+ * reserved-memory node. -+ */ -+ ret = qcom_smem_resolve_mem(smem, "memory-region", &smem->regions[0]); -+ if (ret) -+ return ret; -+ } -+ -+ if (num_regions > 1) { -+ ret = qcom_smem_resolve_mem(smem, "qcom,rpm-msg-ram", &smem->regions[1]); -+ if (ret) -+ return ret; -+ } -+ -+ for (i = 0; i < num_regions; i++) { -+ smem->regions[i].virt_base = devm_ioremap_wc(&pdev->dev, -+ smem->regions[i].aux_base, -+ smem->regions[i].size); -+ if (!smem->regions[i].virt_base) { -+ dev_err(&pdev->dev, "failed to remap %pa\n", &smem->regions[i].aux_base); -+ return -ENOMEM; -+ } -+ } - - header = smem->regions[0].virt_base; - if (le32_to_cpu(header->initialized) != 1 || diff --git a/target/linux/generic/backport-5.15/302-v5.16-watchdog-bcm63xx_wdt-fix-fallthrough-warning.patch b/target/linux/generic/backport-5.15/302-v5.16-watchdog-bcm63xx_wdt-fix-fallthrough-warning.patch deleted file mode 100644 index 84ae5a7fc73b13..00000000000000 --- a/target/linux/generic/backport-5.15/302-v5.16-watchdog-bcm63xx_wdt-fix-fallthrough-warning.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ee1a0696934a8b77a6a2098f92832c46d34ec5da Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 27 Oct 2021 14:31:35 +0200 -Subject: [PATCH] watchdog: bcm63xx_wdt: fix fallthrough warning -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes: -drivers/watchdog/bcm63xx_wdt.c: In function 'bcm63xx_wdt_ioctl': -drivers/watchdog/bcm63xx_wdt.c:208:17: warning: this statement may fall through [-Wimplicit-fallthrough=] - -Signed-off-by: Rafał Miłecki -Reviewed-by: Florian Fainelli -Reviewed-by: Guenter Roeck -Link: https://lore.kernel.org/r/20211027123135.27458-1-zajec5@gmail.com -Signed-off-by: Guenter Roeck -Signed-off-by: Wim Van Sebroeck ---- - drivers/watchdog/bcm63xx_wdt.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/watchdog/bcm63xx_wdt.c -+++ b/drivers/watchdog/bcm63xx_wdt.c -@@ -207,6 +207,8 @@ static long bcm63xx_wdt_ioctl(struct fil - - bcm63xx_wdt_pet(); - -+ fallthrough; -+ - case WDIOC_GETTIMEOUT: - return put_user(wdt_time, p); - diff --git a/target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch b/target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch deleted file mode 100644 index 7c1507bba7e8ca..00000000000000 --- a/target/linux/generic/backport-5.15/303-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 579aee9fc594af94c242068c011b0233563d4bbf Mon Sep 17 00:00:00 2001 -From: Stephen Rothwell -Date: Mon, 10 Oct 2022 16:57:21 +1100 -Subject: [PATCH] powerpc: suppress some linker warnings in recent linker - versions - -This is a follow on from commit - - 0d362be5b142 ("Makefile: link with -z noexecstack --no-warn-rwx-segments") - -for arch/powerpc/boot to address wanrings like: - - ld: warning: opal-calls.o: missing .note.GNU-stack section implies executable stack - ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker - ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions - -This fixes issue https://github.com/linuxppc/issues/issues/417 - -Signed-off-by: Stephen Rothwell -Signed-off-by: Michael Ellerman -Link: https://lore.kernel.org/r/20221010165721.106267e6@canb.auug.org.au ---- - arch/powerpc/boot/wrapper | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - ---- a/arch/powerpc/boot/wrapper -+++ b/arch/powerpc/boot/wrapper -@@ -213,6 +213,11 @@ ld_version() - }' - } - -+ld_is_lld() -+{ -+ ${CROSS}ld -V 2>&1 | grep -q LLD -+} -+ - # Do not include PT_INTERP segment when linking pie. Non-pie linking - # just ignores this option. - LD_VERSION=$(${CROSS}ld --version | ld_version) -@@ -221,6 +226,14 @@ if [ "$LD_VERSION" -ge "$LD_NO_DL_MIN_VE - nodl="--no-dynamic-linker" - fi - -+# suppress some warnings in recent ld versions -+nowarn="-z noexecstack" -+if ! ld_is_lld; then -+ if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then -+ nowarn="$nowarn --no-warn-rwx-segments" -+ fi -+fi -+ - platformo=$object/"$platform".o - lds=$object/zImage.lds - ext=strip -@@ -502,7 +515,7 @@ if [ "$platform" != "miboot" ]; then - text_start="-Ttext $link_address" - fi - #link everything -- ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $rodynamic $notext -o "$ofile" $map \ -+ ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $nowarn $rodynamic $notext -o "$ofile" $map \ - $platformo $tmp $object/wrapper.a - rm $tmp - fi diff --git a/target/linux/generic/backport-5.15/330-v5.16-01-MIPS-kernel-proc-add-CPU-option-reporting.patch b/target/linux/generic/backport-5.15/330-v5.16-01-MIPS-kernel-proc-add-CPU-option-reporting.patch deleted file mode 100644 index c66a3f11b4b489..00000000000000 --- a/target/linux/generic/backport-5.15/330-v5.16-01-MIPS-kernel-proc-add-CPU-option-reporting.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 626bfa03729959ea9917181fb3d8ffaa1594d02a Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Wed, 13 Oct 2021 22:40:18 -0700 -Subject: [PATCH 1/1] MIPS: kernel: proc: add CPU option reporting - -Many MIPS CPUs have optional CPU features which are not activated for -all CPU cores. Print the CPU options, which are implemented in the core, -in /proc/cpuinfo. This makes it possible to see which features are -supported and which are not supported. This should cover all standard -MIPS extensions. Before, it only printed information about the main MIPS -ASEs. - -Signed-off-by: Hauke Mehrtens - -Changes from original patch[0]: -- Remove cpu_has_6k_cache and cpu_has_8k_cache due to commit 6ce91ba8589a - ("MIPS: Remove cpu_has_6k_cache and cpu_has_8k_cache in cpu_cache_init()") -- Add new options: mac2008_only, ftlbparex, gsexcex, mmid, mm_sysad, - mm_full -- Use seq_puts instead of seq_printf as suggested by checkpatch -- Minor commit message reword - -[0]: https://lore.kernel.org/linux-mips/20181223225224.23042-1-hauke@hauke-m.de/ - -Signed-off-by: Ilya Lipnitskiy -Acked-by: Hauke Mehrtens -Signed-off-by: Thomas Bogendoerfer ---- - arch/mips/kernel/proc.c | 122 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 122 insertions(+) - ---- a/arch/mips/kernel/proc.c -+++ b/arch/mips/kernel/proc.c -@@ -138,6 +138,128 @@ static int show_cpuinfo(struct seq_file - seq_printf(m, "micromips kernel\t: %s\n", - (read_c0_config3() & MIPS_CONF3_ISA_OE) ? "yes" : "no"); - } -+ -+ seq_puts(m, "Options implemented\t:"); -+ if (cpu_has_tlb) -+ seq_puts(m, " tlb"); -+ if (cpu_has_ftlb) -+ seq_puts(m, " ftlb"); -+ if (cpu_has_tlbinv) -+ seq_puts(m, " tlbinv"); -+ if (cpu_has_segments) -+ seq_puts(m, " segments"); -+ if (cpu_has_rixiex) -+ seq_puts(m, " rixiex"); -+ if (cpu_has_ldpte) -+ seq_puts(m, " ldpte"); -+ if (cpu_has_maar) -+ seq_puts(m, " maar"); -+ if (cpu_has_rw_llb) -+ seq_puts(m, " rw_llb"); -+ if (cpu_has_4kex) -+ seq_puts(m, " 4kex"); -+ if (cpu_has_3k_cache) -+ seq_puts(m, " 3k_cache"); -+ if (cpu_has_4k_cache) -+ seq_puts(m, " 4k_cache"); -+ if (cpu_has_tx39_cache) -+ seq_puts(m, " tx39_cache"); -+ if (cpu_has_octeon_cache) -+ seq_puts(m, " octeon_cache"); -+ if (cpu_has_fpu) -+ seq_puts(m, " fpu"); -+ if (cpu_has_32fpr) -+ seq_puts(m, " 32fpr"); -+ if (cpu_has_cache_cdex_p) -+ seq_puts(m, " cache_cdex_p"); -+ if (cpu_has_cache_cdex_s) -+ seq_puts(m, " cache_cdex_s"); -+ if (cpu_has_prefetch) -+ seq_puts(m, " prefetch"); -+ if (cpu_has_mcheck) -+ seq_puts(m, " mcheck"); -+ if (cpu_has_ejtag) -+ seq_puts(m, " ejtag"); -+ if (cpu_has_llsc) -+ seq_puts(m, " llsc"); -+ if (cpu_has_guestctl0ext) -+ seq_puts(m, " guestctl0ext"); -+ if (cpu_has_guestctl1) -+ seq_puts(m, " guestctl1"); -+ if (cpu_has_guestctl2) -+ seq_puts(m, " guestctl2"); -+ if (cpu_has_guestid) -+ seq_puts(m, " guestid"); -+ if (cpu_has_drg) -+ seq_puts(m, " drg"); -+ if (cpu_has_rixi) -+ seq_puts(m, " rixi"); -+ if (cpu_has_lpa) -+ seq_puts(m, " lpa"); -+ if (cpu_has_mvh) -+ seq_puts(m, " mvh"); -+ if (cpu_has_vtag_icache) -+ seq_puts(m, " vtag_icache"); -+ if (cpu_has_dc_aliases) -+ seq_puts(m, " dc_aliases"); -+ if (cpu_has_ic_fills_f_dc) -+ seq_puts(m, " ic_fills_f_dc"); -+ if (cpu_has_pindexed_dcache) -+ seq_puts(m, " pindexed_dcache"); -+ if (cpu_has_userlocal) -+ seq_puts(m, " userlocal"); -+ if (cpu_has_nofpuex) -+ seq_puts(m, " nofpuex"); -+ if (cpu_has_vint) -+ seq_puts(m, " vint"); -+ if (cpu_has_veic) -+ seq_puts(m, " veic"); -+ if (cpu_has_inclusive_pcaches) -+ seq_puts(m, " inclusive_pcaches"); -+ if (cpu_has_perf_cntr_intr_bit) -+ seq_puts(m, " perf_cntr_intr_bit"); -+ if (cpu_has_ufr) -+ seq_puts(m, " ufr"); -+ if (cpu_has_fre) -+ seq_puts(m, " fre"); -+ if (cpu_has_cdmm) -+ seq_puts(m, " cdmm"); -+ if (cpu_has_small_pages) -+ seq_puts(m, " small_pages"); -+ if (cpu_has_nan_legacy) -+ seq_puts(m, " nan_legacy"); -+ if (cpu_has_nan_2008) -+ seq_puts(m, " nan_2008"); -+ if (cpu_has_ebase_wg) -+ seq_puts(m, " ebase_wg"); -+ if (cpu_has_badinstr) -+ seq_puts(m, " badinstr"); -+ if (cpu_has_badinstrp) -+ seq_puts(m, " badinstrp"); -+ if (cpu_has_contextconfig) -+ seq_puts(m, " contextconfig"); -+ if (cpu_has_perf) -+ seq_puts(m, " perf"); -+ if (cpu_has_mac2008_only) -+ seq_puts(m, " mac2008_only"); -+ if (cpu_has_ftlbparex) -+ seq_puts(m, " ftlbparex"); -+ if (cpu_has_gsexcex) -+ seq_puts(m, " gsexcex"); -+ if (cpu_has_shared_ftlb_ram) -+ seq_puts(m, " shared_ftlb_ram"); -+ if (cpu_has_shared_ftlb_entries) -+ seq_puts(m, " shared_ftlb_entries"); -+ if (cpu_has_mipsmt_pertccounters) -+ seq_puts(m, " mipsmt_pertccounters"); -+ if (cpu_has_mmid) -+ seq_puts(m, " mmid"); -+ if (cpu_has_mm_sysad) -+ seq_puts(m, " mm_sysad"); -+ if (cpu_has_mm_full) -+ seq_puts(m, " mm_full"); -+ seq_puts(m, "\n"); -+ - seq_printf(m, "shadow register sets\t: %d\n", - cpu_data[n].srsets); - seq_printf(m, "kscratch registers\t: %d\n", diff --git a/target/linux/generic/backport-5.15/330-v5.16-02-MIPS-Fix-using-smp_processor_id-in-preemptible-in-sh.patch b/target/linux/generic/backport-5.15/330-v5.16-02-MIPS-Fix-using-smp_processor_id-in-preemptible-in-sh.patch deleted file mode 100644 index 6caf7d06d4ec8a..00000000000000 --- a/target/linux/generic/backport-5.15/330-v5.16-02-MIPS-Fix-using-smp_processor_id-in-preemptible-in-sh.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 1cab5bd69eb1f995ced2d7576cb15f8a8941fd85 Mon Sep 17 00:00:00 2001 -From: Tiezhu Yang -Date: Thu, 25 Nov 2021 19:39:32 +0800 -Subject: [PATCH 1/1] MIPS: Fix using smp_processor_id() in preemptible in - show_cpuinfo() - -There exists the following issue under DEBUG_PREEMPT: - - BUG: using smp_processor_id() in preemptible [00000000] code: systemd/1 - caller is show_cpuinfo+0x460/0xea0 - ... - Call Trace: - [] show_stack+0x94/0x128 - [] dump_stack_lvl+0x94/0xd8 - [] check_preemption_disabled+0x104/0x110 - [] show_cpuinfo+0x460/0xea0 - [] seq_read_iter+0xfc/0x4f8 - [] new_sync_read+0x110/0x1b8 - [] vfs_read+0x1b4/0x1d0 - [] ksys_read+0xd0/0x110 - [] syscall_common+0x34/0x58 - -We can see the following call trace: - show_cpuinfo() - cpu_has_fpu - current_cpu_data - smp_processor_id() - - $ addr2line -f -e vmlinux 0xffffffff802209c8 - show_cpuinfo - arch/mips/kernel/proc.c:188 - - $ head -188 arch/mips/kernel/proc.c | tail -1 - if (cpu_has_fpu) - - arch/mips/include/asm/cpu-features.h - # define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU) - - arch/mips/include/asm/cpu-info.h - #define current_cpu_data cpu_data[smp_processor_id()] - -Based on the above analysis, fix the issue by using raw_cpu_has_fpu -which calls raw_smp_processor_id() in show_cpuinfo(). - -Fixes: 626bfa037299 ("MIPS: kernel: proc: add CPU option reporting") -Signed-off-by: Tiezhu Yang -Signed-off-by: Thomas Bogendoerfer ---- - arch/mips/kernel/proc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/mips/kernel/proc.c -+++ b/arch/mips/kernel/proc.c -@@ -166,7 +166,7 @@ static int show_cpuinfo(struct seq_file - seq_puts(m, " tx39_cache"); - if (cpu_has_octeon_cache) - seq_puts(m, " octeon_cache"); -- if (cpu_has_fpu) -+ if (raw_cpu_has_fpu) - seq_puts(m, " fpu"); - if (cpu_has_32fpr) - seq_puts(m, " 32fpr"); diff --git a/target/linux/generic/backport-5.15/331-v5.19-mtd-spinand-Add-support-for-XTX-XT26G0xA.patch b/target/linux/generic/backport-5.15/331-v5.19-mtd-spinand-Add-support-for-XTX-XT26G0xA.patch deleted file mode 100644 index 541d247542b678..00000000000000 --- a/target/linux/generic/backport-5.15/331-v5.19-mtd-spinand-Add-support-for-XTX-XT26G0xA.patch +++ /dev/null @@ -1,186 +0,0 @@ -From f4c5c7f9d2e5ab005d57826b740b694b042a737c Mon Sep 17 00:00:00 2001 -From: Felix Matouschek -Date: Mon, 18 Apr 2022 15:28:03 +0200 -Subject: [PATCH 1/1] mtd: spinand: Add support for XTX XT26G0xA - -Add support for XTX Technology XT26G01AXXXXX, XTX26G02AXXXXX and -XTX26G04AXXXXX SPI NAND. - -These are 3V, 1G/2G/4Gbit serial SLC NAND flash devices with on-die ECC -(8bit strength per 512bytes). - -Tested on Teltonika RUTX10 flashed with OpenWrt. - -Links: - - http://www.xtxtech.com/download/?AId=225 - - https://datasheet.lcsc.com/szlcsc/2005251034_XTX-XT26G01AWSEGA_C558841.pdf -Signed-off-by: Felix Matouschek -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220418132803.664103-1-felix@matouschek.org ---- - drivers/mtd/nand/spi/Makefile | 2 +- - drivers/mtd/nand/spi/core.c | 1 + - drivers/mtd/nand/spi/xtx.c | 129 ++++++++++++++++++++++++++++++++++ - include/linux/mtd/spinand.h | 1 + - 4 files changed, 132 insertions(+), 1 deletion(-) - create mode 100644 drivers/mtd/nand/spi/xtx.c - ---- a/drivers/mtd/nand/spi/Makefile -+++ b/drivers/mtd/nand/spi/Makefile -@@ -1,3 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 --spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o -+spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o - obj-$(CONFIG_MTD_SPI_NAND) += spinand.o ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -902,6 +902,7 @@ static const struct spinand_manufacturer - ¶gon_spinand_manufacturer, - &toshiba_spinand_manufacturer, - &winbond_spinand_manufacturer, -+ &xtx_spinand_manufacturer, - }; - - static int spinand_manufacturer_match(struct spinand_device *spinand, ---- /dev/null -+++ b/drivers/mtd/nand/spi/xtx.c -@@ -0,0 +1,129 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Author: -+ * Felix Matouschek -+ */ -+ -+#include -+#include -+#include -+ -+#define SPINAND_MFR_XTX 0x0B -+ -+#define XT26G0XA_STATUS_ECC_MASK GENMASK(5, 2) -+#define XT26G0XA_STATUS_ECC_NO_DETECTED (0 << 2) -+#define XT26G0XA_STATUS_ECC_8_CORRECTED (3 << 4) -+#define XT26G0XA_STATUS_ECC_UNCOR_ERROR (2 << 4) -+ -+static SPINAND_OP_VARIANTS(read_cache_variants, -+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(write_cache_variants, -+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), -+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(update_cache_variants, -+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), -+ SPINAND_PROG_LOAD(false, 0, NULL, 0)); -+ -+static int xt26g0xa_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section) -+ return -ERANGE; -+ -+ region->offset = 48; -+ region->length = 16; -+ -+ return 0; -+} -+ -+static int xt26g0xa_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section) -+ return -ERANGE; -+ -+ region->offset = 1; -+ region->length = 47; -+ -+ return 0; -+} -+ -+static const struct mtd_ooblayout_ops xt26g0xa_ooblayout = { -+ .ecc = xt26g0xa_ooblayout_ecc, -+ .free = xt26g0xa_ooblayout_free, -+}; -+ -+static int xt26g0xa_ecc_get_status(struct spinand_device *spinand, -+ u8 status) -+{ -+ status = status & XT26G0XA_STATUS_ECC_MASK; -+ -+ switch (status) { -+ case XT26G0XA_STATUS_ECC_NO_DETECTED: -+ return 0; -+ case XT26G0XA_STATUS_ECC_8_CORRECTED: -+ return 8; -+ case XT26G0XA_STATUS_ECC_UNCOR_ERROR: -+ return -EBADMSG; -+ default: -+ break; -+ } -+ -+ /* At this point values greater than (2 << 4) are invalid */ -+ if (status > XT26G0XA_STATUS_ECC_UNCOR_ERROR) -+ return -EINVAL; -+ -+ /* (1 << 2) through (7 << 2) are 1-7 corrected errors */ -+ return status >> 2; -+} -+ -+static const struct spinand_info xtx_spinand_table[] = { -+ SPINAND_INFO("XT26G01A", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE1), -+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&xt26g0xa_ooblayout, -+ xt26g0xa_ecc_get_status)), -+ SPINAND_INFO("XT26G02A", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE2), -+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&xt26g0xa_ooblayout, -+ xt26g0xa_ecc_get_status)), -+ SPINAND_INFO("XT26G04A", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE3), -+ NAND_MEMORG(1, 2048, 64, 128, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&xt26g0xa_ooblayout, -+ xt26g0xa_ecc_get_status)), -+}; -+ -+static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = { -+}; -+ -+const struct spinand_manufacturer xtx_spinand_manufacturer = { -+ .id = SPINAND_MFR_XTX, -+ .name = "XTX", -+ .chips = xtx_spinand_table, -+ .nchips = ARRAY_SIZE(xtx_spinand_table), -+ .ops = &xtx_spinand_manuf_ops, -+}; ---- a/include/linux/mtd/spinand.h -+++ b/include/linux/mtd/spinand.h -@@ -266,6 +266,7 @@ extern const struct spinand_manufacturer - extern const struct spinand_manufacturer paragon_spinand_manufacturer; - extern const struct spinand_manufacturer toshiba_spinand_manufacturer; - extern const struct spinand_manufacturer winbond_spinand_manufacturer; -+extern const struct spinand_manufacturer xtx_spinand_manufacturer; - - /** - * struct spinand_op_variants - SPI NAND operation variants diff --git a/target/linux/generic/backport-5.15/344-v5.18-01-phy-marvell-phy-mvebu-a3700-comphy-Remove-port-from-.patch b/target/linux/generic/backport-5.15/344-v5.18-01-phy-marvell-phy-mvebu-a3700-comphy-Remove-port-from-.patch deleted file mode 100644 index d6c4b4fd1ee2fc..00000000000000 --- a/target/linux/generic/backport-5.15/344-v5.18-01-phy-marvell-phy-mvebu-a3700-comphy-Remove-port-from-.patch +++ /dev/null @@ -1,219 +0,0 @@ -From 4bf18d5a2dd02db8c5b16a2cfae513510506df5b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Thu, 3 Feb 2022 22:44:40 +0100 -Subject: [PATCH 1/2] phy: marvell: phy-mvebu-a3700-comphy: Remove port from - driver configuration -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Port number is encoded into argument for SMC call. It is zero for SATA, -PCIe and also both USB 3.0 PHYs. It is non-zero only for Ethernet PHY -(incorrectly called SGMII) on lane 0. Ethernet PHY on lane 1 also uses zero -port number. - -So construct "port" bits for SMC call argument can be constructed directly -from PHY type and lane number. - -Change driver code to always pass zero port number for non-ethernet PHYs -and for ethernet PHYs determinate port number from lane number. This -simplifies the driver. - -As port number from DT PHY configuration is not used anymore, remove whole -driver code which parses it. This also simplifies the driver. - -Signed-off-by: Pali Rohár -Signed-off-by: Marek Behún -Reviewed-by: Miquel Raynal -Link: https://lore.kernel.org/r/20220203214444.1508-2-kabel@kernel.org -Signed-off-by: Vinod Koul ---- - drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 62 +++++++++----------- - 1 file changed, 29 insertions(+), 33 deletions(-) - ---- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c -+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c -@@ -20,7 +20,6 @@ - #include - - #define MVEBU_A3700_COMPHY_LANES 3 --#define MVEBU_A3700_COMPHY_PORTS 2 - - /* COMPHY Fast SMC function identifiers */ - #define COMPHY_SIP_POWER_ON 0x82000001 -@@ -45,51 +44,47 @@ - #define COMPHY_FW_NET(mode, idx, speed) (COMPHY_FW_MODE(mode) | \ - ((idx) << 8) | \ - ((speed) << 2)) --#define COMPHY_FW_PCIE(mode, idx, speed, width) (COMPHY_FW_NET(mode, idx, speed) | \ -+#define COMPHY_FW_PCIE(mode, speed, width) (COMPHY_FW_NET(mode, 0, speed) | \ - ((width) << 18)) - - struct mvebu_a3700_comphy_conf { - unsigned int lane; - enum phy_mode mode; - int submode; -- unsigned int port; - u32 fw_mode; - }; - --#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _port, _fw) \ -+#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _fw) \ - { \ - .lane = _lane, \ - .mode = _mode, \ - .submode = _smode, \ -- .port = _port, \ - .fw_mode = _fw, \ - } - --#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _port, _fw) \ -- MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _port, _fw) -+#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _fw) \ -+ MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _fw) - --#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _port, _fw) \ -- MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _port, _fw) -+#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _fw) \ -+ MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _fw) - - static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = { - /* lane 0 */ -- MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS, 0, -+ MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS, - COMPHY_FW_MODE_USB3H), -- MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII, 1, -+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII, - COMPHY_FW_MODE_SGMII), -- MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX, 1, -+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX, - COMPHY_FW_MODE_2500BASEX), - /* lane 1 */ -- MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, 0, -- COMPHY_FW_MODE_PCIE), -- MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, 0, -+ MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), -+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, - COMPHY_FW_MODE_SGMII), -- MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX, 0, -+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX, - COMPHY_FW_MODE_2500BASEX), - /* lane 2 */ -- MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, 0, -- COMPHY_FW_MODE_SATA), -- MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS, 0, -+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), -+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS, - COMPHY_FW_MODE_USB3H), - }; - -@@ -98,7 +93,6 @@ struct mvebu_a3700_comphy_lane { - unsigned int id; - enum phy_mode mode; - int submode; -- int port; - }; - - static int mvebu_a3700_comphy_smc(unsigned long function, unsigned long lane, -@@ -120,7 +114,7 @@ static int mvebu_a3700_comphy_smc(unsign - } - } - --static int mvebu_a3700_comphy_get_fw_mode(int lane, int port, -+static int mvebu_a3700_comphy_get_fw_mode(int lane, - enum phy_mode mode, - int submode) - { -@@ -132,7 +126,6 @@ static int mvebu_a3700_comphy_get_fw_mod - - for (i = 0; i < n; i++) { - if (mvebu_a3700_comphy_modes[i].lane == lane && -- mvebu_a3700_comphy_modes[i].port == port && - mvebu_a3700_comphy_modes[i].mode == mode && - mvebu_a3700_comphy_modes[i].submode == submode) - break; -@@ -153,7 +146,7 @@ static int mvebu_a3700_comphy_set_mode(s - if (submode == PHY_INTERFACE_MODE_1000BASEX) - submode = PHY_INTERFACE_MODE_SGMII; - -- fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, mode, -+ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, mode, - submode); - if (fw_mode < 0) { - dev_err(lane->dev, "invalid COMPHY mode\n"); -@@ -172,9 +165,10 @@ static int mvebu_a3700_comphy_power_on(s - struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); - u32 fw_param; - int fw_mode; -+ int fw_port; - int ret; - -- fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, -+ fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, - lane->mode, lane->submode); - if (fw_mode < 0) { - dev_err(lane->dev, "invalid COMPHY mode\n"); -@@ -191,17 +185,18 @@ static int mvebu_a3700_comphy_power_on(s - fw_param = COMPHY_FW_MODE(fw_mode); - break; - case PHY_MODE_ETHERNET: -+ fw_port = (lane->id == 0) ? 1 : 0; - switch (lane->submode) { - case PHY_INTERFACE_MODE_SGMII: - dev_dbg(lane->dev, "set lane %d to SGMII mode\n", - lane->id); -- fw_param = COMPHY_FW_NET(fw_mode, lane->port, -+ fw_param = COMPHY_FW_NET(fw_mode, fw_port, - COMPHY_FW_SPEED_1_25G); - break; - case PHY_INTERFACE_MODE_2500BASEX: - dev_dbg(lane->dev, "set lane %d to 2500BASEX mode\n", - lane->id); -- fw_param = COMPHY_FW_NET(fw_mode, lane->port, -+ fw_param = COMPHY_FW_NET(fw_mode, fw_port, - COMPHY_FW_SPEED_3_125G); - break; - default: -@@ -212,8 +207,7 @@ static int mvebu_a3700_comphy_power_on(s - break; - case PHY_MODE_PCIE: - dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id); -- fw_param = COMPHY_FW_PCIE(fw_mode, lane->port, -- COMPHY_FW_SPEED_5G, -+ fw_param = COMPHY_FW_PCIE(fw_mode, COMPHY_FW_SPEED_5G, - phy->attrs.bus_width); - break; - default: -@@ -247,17 +241,20 @@ static struct phy *mvebu_a3700_comphy_xl - struct of_phandle_args *args) - { - struct mvebu_a3700_comphy_lane *lane; -+ unsigned int port; - struct phy *phy; - -- if (WARN_ON(args->args[0] >= MVEBU_A3700_COMPHY_PORTS)) -- return ERR_PTR(-EINVAL); -- - phy = of_phy_simple_xlate(dev, args); - if (IS_ERR(phy)) - return phy; - - lane = phy_get_drvdata(phy); -- lane->port = args->args[0]; -+ -+ port = args->args[0]; -+ if (port != 0 && (port != 1 || lane->id != 0)) { -+ dev_err(lane->dev, "invalid port number %u\n", port); -+ return ERR_PTR(-EINVAL); -+ } - - return phy; - } -@@ -302,7 +299,6 @@ static int mvebu_a3700_comphy_probe(stru - lane->mode = PHY_MODE_INVALID; - lane->submode = PHY_INTERFACE_MODE_NA; - lane->id = lane_id; -- lane->port = -1; - phy_set_drvdata(phy, lane); - } - diff --git a/target/linux/generic/backport-5.15/344-v5.18-02-phy-marvell-phy-mvebu-a3700-comphy-Add-native-kernel.patch b/target/linux/generic/backport-5.15/344-v5.18-02-phy-marvell-phy-mvebu-a3700-comphy-Add-native-kernel.patch deleted file mode 100644 index 4593d14bfe6aef..00000000000000 --- a/target/linux/generic/backport-5.15/344-v5.18-02-phy-marvell-phy-mvebu-a3700-comphy-Add-native-kernel.patch +++ /dev/null @@ -1,1552 +0,0 @@ -From 934337080c6c59b75db76b180b509f218640ad48 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Thu, 3 Feb 2022 22:44:41 +0100 -Subject: [PATCH 2/2] phy: marvell: phy-mvebu-a3700-comphy: Add native kernel - implementation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Remove old RPC implementation and add a new native kernel implementation. - -The old implementation uses ARM SMC API to issue RPC calls to ARM Trusted -Firmware which provides real implementation of PHY configuration. - -But older versions of ARM Trusted Firmware do not provide this PHY -configuration functionality, simply returning: operation not supported; or -worse, some versions provide the configuration functionality incorrectly. - -For example the firmware shipped in ESPRESSObin board has this older -version of ARM Trusted Firmware and therefore SATA, USB 3.0 and PCIe -functionality do not work with newer versions of Linux kernel. - -Due to the above reasons, the following commits were introduced into Linux, -to workaround these issues by ignoring -EOPNOTSUPP error code from -phy-mvebu-a3700-comphy driver function phy_power_on(): - -commit 45aefe3d2251 ("ata: ahci: mvebu: Make SATA PHY optional for Armada -3720") -commit 3241929b67d2 ("usb: host: xhci: mvebu: make USB 3.0 PHY optional for -Armada 3720") -commit b0c6ae0f8948 ("PCI: aardvark: Fix initialization with old Marvell's -Arm Trusted Firmware") - -Replace this RPC implementation with proper native kernel implementation, -which is independent on the firmware. Never return -EOPNOTSUPP for proper -arguments. - -This should solve multiple issues with real-world boards, where it is not -possible or really inconvenient to change the firmware. Let's eliminate -these issues. - -This implementation is ported directly from Armada 3720 comphy driver found -in newest version of ARM Trusted Firmware source code, but with various -fixes of register names, some added comments, some refactoring due to the -original code not conforming to kernel standards. Also PCIe mode poweroff -support was added here, and PHY reset support. These changes are also going -to be sent to ARM Trusted Firmware. - -[ Pali did the porting from ATF. - I (Marek) then fixed some register names, some various other things, - added some comments and refactored the code to kernel standards. Also - fixed PHY poweroff and added PHY reset. ] - -Signed-off-by: Pali Rohár -Acked-by: Miquel Raynal -Signed-off-by: Marek Behún -Link: https://lore.kernel.org/r/20220203214444.1508-3-kabel@kernel.org -Signed-off-by: Vinod Koul ---- - drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 1332 ++++++++++++++++-- - 1 file changed, 1215 insertions(+), 117 deletions(-) - ---- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c -+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c -@@ -5,12 +5,16 @@ - * Authors: - * Evan Wang - * Miquèl Raynal -+ * Pali Rohár -+ * Marek Behún - * - * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart. -- * SMC call initial support done by Grzegorz Jaszczyk. -+ * Comphy code from ARM Trusted Firmware ported by Pali Rohár -+ * and Marek Behún . - */ - --#include -+#include -+#include - #include - #include - #include -@@ -18,103 +22,1118 @@ - #include - #include - #include -+#include - --#define MVEBU_A3700_COMPHY_LANES 3 -+#define PLL_SET_DELAY_US 600 -+#define COMPHY_PLL_SLEEP 1000 -+#define COMPHY_PLL_TIMEOUT 150000 -+ -+/* Comphy lane2 indirect access register offset */ -+#define COMPHY_LANE2_INDIR_ADDR 0x0 -+#define COMPHY_LANE2_INDIR_DATA 0x4 -+ -+/* SATA and USB3 PHY offset compared to SATA PHY */ -+#define COMPHY_LANE2_REGS_BASE 0x200 -+ -+/* -+ * When accessing common PHY lane registers directly, we need to shift by 1, -+ * since the registers are 16-bit. -+ */ -+#define COMPHY_LANE_REG_DIRECT(reg) (((reg) & 0x7FF) << 1) -+ -+/* COMPHY registers */ -+#define COMPHY_POWER_PLL_CTRL 0x01 -+#define PU_IVREF_BIT BIT(15) -+#define PU_PLL_BIT BIT(14) -+#define PU_RX_BIT BIT(13) -+#define PU_TX_BIT BIT(12) -+#define PU_TX_INTP_BIT BIT(11) -+#define PU_DFE_BIT BIT(10) -+#define RESET_DTL_RX_BIT BIT(9) -+#define PLL_LOCK_BIT BIT(8) -+#define REF_FREF_SEL_MASK GENMASK(4, 0) -+#define REF_FREF_SEL_SERDES_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x1) -+#define REF_FREF_SEL_SERDES_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3) -+#define REF_FREF_SEL_SERDES_50MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x4) -+#define REF_FREF_SEL_PCIE_USB3_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x2) -+#define REF_FREF_SEL_PCIE_USB3_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3) -+#define COMPHY_MODE_MASK GENMASK(7, 5) -+#define COMPHY_MODE_SATA FIELD_PREP(COMPHY_MODE_MASK, 0x0) -+#define COMPHY_MODE_PCIE FIELD_PREP(COMPHY_MODE_MASK, 0x3) -+#define COMPHY_MODE_SERDES FIELD_PREP(COMPHY_MODE_MASK, 0x4) -+#define COMPHY_MODE_USB3 FIELD_PREP(COMPHY_MODE_MASK, 0x5) -+ -+#define COMPHY_KVCO_CAL_CTRL 0x02 -+#define USE_MAX_PLL_RATE_BIT BIT(12) -+#define SPEED_PLL_MASK GENMASK(7, 2) -+#define SPEED_PLL_VALUE_16 FIELD_PREP(SPEED_PLL_MASK, 0x10) -+ -+#define COMPHY_DIG_LOOPBACK_EN 0x23 -+#define SEL_DATA_WIDTH_MASK GENMASK(11, 10) -+#define DATA_WIDTH_10BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x0) -+#define DATA_WIDTH_20BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x1) -+#define DATA_WIDTH_40BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x2) -+#define PLL_READY_TX_BIT BIT(4) -+ -+#define COMPHY_SYNC_PATTERN 0x24 -+#define TXD_INVERT_BIT BIT(10) -+#define RXD_INVERT_BIT BIT(11) -+ -+#define COMPHY_SYNC_MASK_GEN 0x25 -+#define PHY_GEN_MAX_MASK GENMASK(11, 10) -+#define PHY_GEN_MAX_USB3_5G FIELD_PREP(PHY_GEN_MAX_MASK, 0x1) -+ -+#define COMPHY_ISOLATION_CTRL 0x26 -+#define PHY_ISOLATE_MODE BIT(15) -+ -+#define COMPHY_GEN2_SET2 0x3e -+#define GS2_TX_SSC_AMP_MASK GENMASK(15, 9) -+#define GS2_TX_SSC_AMP_4128 FIELD_PREP(GS2_TX_SSC_AMP_MASK, 0x20) -+#define GS2_VREG_RXTX_MAS_ISET_MASK GENMASK(8, 7) -+#define GS2_VREG_RXTX_MAS_ISET_60U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ -+ 0x0) -+#define GS2_VREG_RXTX_MAS_ISET_80U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ -+ 0x1) -+#define GS2_VREG_RXTX_MAS_ISET_100U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ -+ 0x2) -+#define GS2_VREG_RXTX_MAS_ISET_120U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\ -+ 0x3) -+#define GS2_RSVD_6_0_MASK GENMASK(6, 0) -+ -+#define COMPHY_GEN3_SET2 0x3f -+ -+#define COMPHY_IDLE_SYNC_EN 0x48 -+#define IDLE_SYNC_EN BIT(12) -+ -+#define COMPHY_MISC_CTRL0 0x4F -+#define CLK100M_125M_EN BIT(4) -+#define TXDCLK_2X_SEL BIT(6) -+#define CLK500M_EN BIT(7) -+#define PHY_REF_CLK_SEL BIT(10) -+ -+#define COMPHY_SFT_RESET 0x52 -+#define SFT_RST BIT(9) -+#define SFT_RST_NO_REG BIT(10) -+ -+#define COMPHY_MISC_CTRL1 0x73 -+#define SEL_BITS_PCIE_FORCE BIT(15) -+ -+#define COMPHY_GEN2_SET3 0x112 -+#define GS3_FFE_CAP_SEL_MASK GENMASK(3, 0) -+#define GS3_FFE_CAP_SEL_VALUE FIELD_PREP(GS3_FFE_CAP_SEL_MASK, 0xF) -+ -+/* PIPE registers */ -+#define COMPHY_PIPE_LANE_CFG0 0x180 -+#define PRD_TXDEEMPH0_MASK BIT(0) -+#define PRD_TXMARGIN_MASK GENMASK(3, 1) -+#define PRD_TXSWING_MASK BIT(4) -+#define CFG_TX_ALIGN_POS_MASK GENMASK(8, 5) -+ -+#define COMPHY_PIPE_LANE_CFG1 0x181 -+#define PRD_TXDEEMPH1_MASK BIT(15) -+#define USE_MAX_PLL_RATE_EN BIT(9) -+#define TX_DET_RX_MODE BIT(6) -+#define GEN2_TX_DATA_DLY_MASK GENMASK(4, 3) -+#define GEN2_TX_DATA_DLY_DEFT FIELD_PREP(GEN2_TX_DATA_DLY_MASK, 2) -+#define TX_ELEC_IDLE_MODE_EN BIT(0) -+ -+#define COMPHY_PIPE_LANE_STAT1 0x183 -+#define TXDCLK_PCLK_EN BIT(0) -+ -+#define COMPHY_PIPE_LANE_CFG4 0x188 -+#define SPREAD_SPECTRUM_CLK_EN BIT(7) -+ -+#define COMPHY_PIPE_RST_CLK_CTRL 0x1C1 -+#define PIPE_SOFT_RESET BIT(0) -+#define PIPE_REG_RESET BIT(1) -+#define MODE_CORE_CLK_FREQ_SEL BIT(9) -+#define MODE_PIPE_WIDTH_32 BIT(3) -+#define MODE_REFDIV_MASK GENMASK(5, 4) -+#define MODE_REFDIV_BY_4 FIELD_PREP(MODE_REFDIV_MASK, 0x2) -+ -+#define COMPHY_PIPE_TEST_MODE_CTRL 0x1C2 -+#define MODE_MARGIN_OVERRIDE BIT(2) -+ -+#define COMPHY_PIPE_CLK_SRC_LO 0x1C3 -+#define MODE_CLK_SRC BIT(0) -+#define BUNDLE_PERIOD_SEL BIT(1) -+#define BUNDLE_PERIOD_SCALE_MASK GENMASK(3, 2) -+#define BUNDLE_SAMPLE_CTRL BIT(4) -+#define PLL_READY_DLY_MASK GENMASK(7, 5) -+#define CFG_SEL_20B BIT(15) -+ -+#define COMPHY_PIPE_PWR_MGM_TIM1 0x1D0 -+#define CFG_PM_OSCCLK_WAIT_MASK GENMASK(15, 12) -+#define CFG_PM_RXDEN_WAIT_MASK GENMASK(11, 8) -+#define CFG_PM_RXDEN_WAIT_1_UNIT FIELD_PREP(CFG_PM_RXDEN_WAIT_MASK, 0x1) -+#define CFG_PM_RXDLOZ_WAIT_MASK GENMASK(7, 0) -+#define CFG_PM_RXDLOZ_WAIT_7_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0x7) -+#define CFG_PM_RXDLOZ_WAIT_12_UNIT FIELD_PREP(CFG_PM_RXDLOZ_WAIT_MASK, 0xC) -+ -+/* -+ * This register is not from PHY lane register space. It only exists in the -+ * indirect register space, before the actual PHY lane 2 registers. So the -+ * offset is absolute, not relative to COMPHY_LANE2_REGS_BASE. -+ * It is used only for SATA PHY initialization. -+ */ -+#define COMPHY_RESERVED_REG 0x0E -+#define PHYCTRL_FRM_PIN_BIT BIT(13) - --/* COMPHY Fast SMC function identifiers */ --#define COMPHY_SIP_POWER_ON 0x82000001 --#define COMPHY_SIP_POWER_OFF 0x82000002 --#define COMPHY_SIP_PLL_LOCK 0x82000003 -- --#define COMPHY_FW_MODE_SATA 0x1 --#define COMPHY_FW_MODE_SGMII 0x2 --#define COMPHY_FW_MODE_2500BASEX 0x3 --#define COMPHY_FW_MODE_USB3H 0x4 --#define COMPHY_FW_MODE_USB3D 0x5 --#define COMPHY_FW_MODE_PCIE 0x6 --#define COMPHY_FW_MODE_USB3 0xa -- --#define COMPHY_FW_SPEED_1_25G 0 /* SGMII 1G */ --#define COMPHY_FW_SPEED_2_5G 1 --#define COMPHY_FW_SPEED_3_125G 2 /* 2500BASE-X */ --#define COMPHY_FW_SPEED_5G 3 --#define COMPHY_FW_SPEED_MAX 0x3F -- --#define COMPHY_FW_MODE(mode) ((mode) << 12) --#define COMPHY_FW_NET(mode, idx, speed) (COMPHY_FW_MODE(mode) | \ -- ((idx) << 8) | \ -- ((speed) << 2)) --#define COMPHY_FW_PCIE(mode, speed, width) (COMPHY_FW_NET(mode, 0, speed) | \ -- ((width) << 18)) -+/* South Bridge PHY Configuration Registers */ -+#define COMPHY_PHY_REG(lane, reg) (((1 - (lane)) * 0x28) + ((reg) & 0x3f)) -+ -+/* -+ * lane0: USB3/GbE1 PHY Configuration 1 -+ * lane1: PCIe/GbE0 PHY Configuration 1 -+ * (used only by SGMII code) -+ */ -+#define COMPHY_PHY_CFG1 0x0 -+#define PIN_PU_IVREF_BIT BIT(1) -+#define PIN_RESET_CORE_BIT BIT(11) -+#define PIN_RESET_COMPHY_BIT BIT(12) -+#define PIN_PU_PLL_BIT BIT(16) -+#define PIN_PU_RX_BIT BIT(17) -+#define PIN_PU_TX_BIT BIT(18) -+#define PIN_TX_IDLE_BIT BIT(19) -+#define GEN_RX_SEL_MASK GENMASK(25, 22) -+#define GEN_RX_SEL_VALUE(val) FIELD_PREP(GEN_RX_SEL_MASK, (val)) -+#define GEN_TX_SEL_MASK GENMASK(29, 26) -+#define GEN_TX_SEL_VALUE(val) FIELD_PREP(GEN_TX_SEL_MASK, (val)) -+#define SERDES_SPEED_1_25_G 0x6 -+#define SERDES_SPEED_3_125_G 0x8 -+#define PHY_RX_INIT_BIT BIT(30) -+ -+/* -+ * lane0: USB3/GbE1 PHY Status 1 -+ * lane1: PCIe/GbE0 PHY Status 1 -+ * (used only by SGMII code) -+ */ -+#define COMPHY_PHY_STAT1 0x18 -+#define PHY_RX_INIT_DONE_BIT BIT(0) -+#define PHY_PLL_READY_RX_BIT BIT(2) -+#define PHY_PLL_READY_TX_BIT BIT(3) -+ -+/* PHY Selector */ -+#define COMPHY_SELECTOR_PHY_REG 0xFC -+/* bit0: 0: Lane1 is GbE0; 1: Lane1 is PCIe */ -+#define COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT BIT(0) -+/* bit4: 0: Lane0 is GbE1; 1: Lane0 is USB3 */ -+#define COMPHY_SELECTOR_USB3_GBE1_SEL_BIT BIT(4) -+/* bit8: 0: Lane0 is USB3 instead of GbE1, Lane2 is SATA; 1: Lane2 is USB3 */ -+#define COMPHY_SELECTOR_USB3_PHY_SEL_BIT BIT(8) - - struct mvebu_a3700_comphy_conf { - unsigned int lane; - enum phy_mode mode; - int submode; -- u32 fw_mode; - }; - --#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _fw) \ -+#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode) \ - { \ - .lane = _lane, \ - .mode = _mode, \ - .submode = _smode, \ -- .fw_mode = _fw, \ - } - --#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _fw) \ -- MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _fw) -+#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode) \ -+ MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA) - --#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _fw) \ -- MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _fw) -+#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode) \ -+ MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode) - - static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = { - /* lane 0 */ -- MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS, -- COMPHY_FW_MODE_USB3H), -- MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII, -- COMPHY_FW_MODE_SGMII), -- MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX, -- COMPHY_FW_MODE_2500BASEX), -+ MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS), -+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII), -+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_1000BASEX), -+ MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX), - /* lane 1 */ -- MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, COMPHY_FW_MODE_PCIE), -- MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, -- COMPHY_FW_MODE_SGMII), -- MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX, -- COMPHY_FW_MODE_2500BASEX), -+ MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE), -+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII), -+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_1000BASEX), -+ MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX), - /* lane 2 */ -- MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, COMPHY_FW_MODE_SATA), -- MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS, -- COMPHY_FW_MODE_USB3H), -+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA), -+ MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS), -+}; -+ -+struct mvebu_a3700_comphy_priv { -+ void __iomem *comphy_regs; -+ void __iomem *lane0_phy_regs; /* USB3 and GbE1 */ -+ void __iomem *lane1_phy_regs; /* PCIe and GbE0 */ -+ void __iomem *lane2_phy_indirect; /* SATA and USB3 */ -+ spinlock_t lock; /* for PHY selector access */ -+ bool xtal_is_40m; - }; - - struct mvebu_a3700_comphy_lane { -+ struct mvebu_a3700_comphy_priv *priv; - struct device *dev; - unsigned int id; - enum phy_mode mode; - int submode; -+ bool invert_tx; -+ bool invert_rx; -+ bool needs_reset; -+}; -+ -+struct gbe_phy_init_data_fix { -+ u16 addr; -+ u16 value; -+}; -+ -+/* Changes to 40M1G25 mode data required for running 40M3G125 init mode */ -+static struct gbe_phy_init_data_fix gbe_phy_init_fix[] = { -+ { 0x005, 0x07CC }, { 0x015, 0x0000 }, { 0x01B, 0x0000 }, -+ { 0x01D, 0x0000 }, { 0x01E, 0x0000 }, { 0x01F, 0x0000 }, -+ { 0x020, 0x0000 }, { 0x021, 0x0030 }, { 0x026, 0x0888 }, -+ { 0x04D, 0x0152 }, { 0x04F, 0xA020 }, { 0x050, 0x07CC }, -+ { 0x053, 0xE9CA }, { 0x055, 0xBD97 }, { 0x071, 0x3015 }, -+ { 0x076, 0x03AA }, { 0x07C, 0x0FDF }, { 0x0C2, 0x3030 }, -+ { 0x0C3, 0x8000 }, { 0x0E2, 0x5550 }, { 0x0E3, 0x12A4 }, -+ { 0x0E4, 0x7D00 }, { 0x0E6, 0x0C83 }, { 0x101, 0xFCC0 }, -+ { 0x104, 0x0C10 } - }; - --static int mvebu_a3700_comphy_smc(unsigned long function, unsigned long lane, -- unsigned long mode) -+/* 40M1G25 mode init data */ -+static u16 gbe_phy_init[512] = { -+ /* 0 1 2 3 4 5 6 7 */ -+ /*-----------------------------------------------------------*/ -+ /* 8 9 A B C D E F */ -+ 0x3110, 0xFD83, 0x6430, 0x412F, 0x82C0, 0x06FA, 0x4500, 0x6D26, /* 00 */ -+ 0xAFC0, 0x8000, 0xC000, 0x0000, 0x2000, 0x49CC, 0x0BC9, 0x2A52, /* 08 */ -+ 0x0BD2, 0x0CDE, 0x13D2, 0x0CE8, 0x1149, 0x10E0, 0x0000, 0x0000, /* 10 */ -+ 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x4134, 0x0D2D, 0xFFFF, /* 18 */ -+ 0xFFE0, 0x4030, 0x1016, 0x0030, 0x0000, 0x0800, 0x0866, 0x0000, /* 20 */ -+ 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, /* 28 */ -+ 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 30 */ -+ 0x0000, 0x0000, 0x000F, 0x6A62, 0x1988, 0x3100, 0x3100, 0x3100, /* 38 */ -+ 0x3100, 0xA708, 0x2430, 0x0830, 0x1030, 0x4610, 0xFF00, 0xFF00, /* 40 */ -+ 0x0060, 0x1000, 0x0400, 0x0040, 0x00F0, 0x0155, 0x1100, 0xA02A, /* 48 */ -+ 0x06FA, 0x0080, 0xB008, 0xE3ED, 0x5002, 0xB592, 0x7A80, 0x0001, /* 50 */ -+ 0x020A, 0x8820, 0x6014, 0x8054, 0xACAA, 0xFC88, 0x2A02, 0x45CF, /* 58 */ -+ 0x000F, 0x1817, 0x2860, 0x064F, 0x0000, 0x0204, 0x1800, 0x6000, /* 60 */ -+ 0x810F, 0x4F23, 0x4000, 0x4498, 0x0850, 0x0000, 0x000E, 0x1002, /* 68 */ -+ 0x9D3A, 0x3009, 0xD066, 0x0491, 0x0001, 0x6AB0, 0x0399, 0x3780, /* 70 */ -+ 0x0040, 0x5AC0, 0x4A80, 0x0000, 0x01DF, 0x0000, 0x0007, 0x0000, /* 78 */ -+ 0x2D54, 0x00A1, 0x4000, 0x0100, 0xA20A, 0x0000, 0x0000, 0x0000, /* 80 */ -+ 0x0000, 0x0000, 0x0000, 0x7400, 0x0E81, 0x1000, 0x1242, 0x0210, /* 88 */ -+ 0x80DF, 0x0F1F, 0x2F3F, 0x4F5F, 0x6F7F, 0x0F1F, 0x2F3F, 0x4F5F, /* 90 */ -+ 0x6F7F, 0x4BAD, 0x0000, 0x0000, 0x0800, 0x0000, 0x2400, 0xB651, /* 98 */ -+ 0xC9E0, 0x4247, 0x0A24, 0x0000, 0xAF19, 0x1004, 0x0000, 0x0000, /* A0 */ -+ 0x0000, 0x0013, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* A8 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* B0 */ -+ 0x0000, 0x0000, 0x0000, 0x0060, 0x0000, 0x0000, 0x0000, 0x0000, /* B8 */ -+ 0x0000, 0x0000, 0x3010, 0xFA00, 0x0000, 0x0000, 0x0000, 0x0003, /* C0 */ -+ 0x1618, 0x8200, 0x8000, 0x0400, 0x050F, 0x0000, 0x0000, 0x0000, /* C8 */ -+ 0x4C93, 0x0000, 0x1000, 0x1120, 0x0010, 0x1242, 0x1242, 0x1E00, /* D0 */ -+ 0x0000, 0x0000, 0x0000, 0x00F8, 0x0000, 0x0041, 0x0800, 0x0000, /* D8 */ -+ 0x82A0, 0x572E, 0x2490, 0x14A9, 0x4E00, 0x0000, 0x0803, 0x0541, /* E0 */ -+ 0x0C15, 0x0000, 0x0000, 0x0400, 0x2626, 0x0000, 0x0000, 0x4200, /* E8 */ -+ 0x0000, 0xAA55, 0x1020, 0x0000, 0x0000, 0x5010, 0x0000, 0x0000, /* F0 */ -+ 0x0000, 0x0000, 0x5000, 0x0000, 0x0000, 0x0000, 0x02F2, 0x0000, /* F8 */ -+ 0x101F, 0xFDC0, 0x4000, 0x8010, 0x0110, 0x0006, 0x0000, 0x0000, /*100 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*108 */ -+ 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04C6, 0x0000, /*110 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*118 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*120 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*128 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*130 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*138 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*140 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*148 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*150 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*158 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*160 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*168 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*170 */ -+ 0x0000, 0x0000, 0x0000, 0x00F0, 0x08A2, 0x3112, 0x0A14, 0x0000, /*178 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*180 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*188 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*190 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*198 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A0 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A8 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B0 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B8 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C0 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C8 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D0 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D8 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E0 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E8 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1F0 */ -+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /*1F8 */ -+}; -+ -+static inline void comphy_reg_set(void __iomem *addr, u32 data, u32 mask) - { -- struct arm_smccc_res res; -- s32 ret; -+ u32 val; -+ -+ val = readl(addr); -+ val = (val & ~mask) | (data & mask); -+ writel(val, addr); -+} - -- arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res); -- ret = res.a0; -+static inline void comphy_reg_set16(void __iomem *addr, u16 data, u16 mask) -+{ -+ u16 val; - -- switch (ret) { -- case SMCCC_RET_SUCCESS: -- return 0; -- case SMCCC_RET_NOT_SUPPORTED: -- return -EOPNOTSUPP; -+ val = readw(addr); -+ val = (val & ~mask) | (data & mask); -+ writew(val, addr); -+} -+ -+/* Used for accessing lane 2 registers (SATA/USB3 PHY) */ -+static void comphy_set_indirect(struct mvebu_a3700_comphy_priv *priv, -+ u32 offset, u16 data, u16 mask) -+{ -+ writel(offset, -+ priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_ADDR); -+ comphy_reg_set(priv->lane2_phy_indirect + COMPHY_LANE2_INDIR_DATA, -+ data, mask); -+} -+ -+static void comphy_lane_reg_set(struct mvebu_a3700_comphy_lane *lane, -+ u16 reg, u16 data, u16 mask) -+{ -+ if (lane->id == 2) { -+ /* lane 2 PHY registers are accessed indirectly */ -+ comphy_set_indirect(lane->priv, -+ reg + COMPHY_LANE2_REGS_BASE, -+ data, mask); -+ } else { -+ void __iomem *base = lane->id == 1 ? -+ lane->priv->lane1_phy_regs : -+ lane->priv->lane0_phy_regs; -+ -+ comphy_reg_set16(base + COMPHY_LANE_REG_DIRECT(reg), -+ data, mask); -+ } -+} -+ -+static int comphy_lane_reg_poll(struct mvebu_a3700_comphy_lane *lane, -+ u16 reg, u16 bits, -+ ulong sleep_us, ulong timeout_us) -+{ -+ int ret; -+ -+ if (lane->id == 2) { -+ u32 data; -+ -+ /* lane 2 PHY registers are accessed indirectly */ -+ writel(reg + COMPHY_LANE2_REGS_BASE, -+ lane->priv->lane2_phy_indirect + -+ COMPHY_LANE2_INDIR_ADDR); -+ -+ ret = readl_poll_timeout(lane->priv->lane2_phy_indirect + -+ COMPHY_LANE2_INDIR_DATA, -+ data, (data & bits) == bits, -+ sleep_us, timeout_us); -+ } else { -+ void __iomem *base = lane->id == 1 ? -+ lane->priv->lane1_phy_regs : -+ lane->priv->lane0_phy_regs; -+ u16 data; -+ -+ ret = readw_poll_timeout(base + COMPHY_LANE_REG_DIRECT(reg), -+ data, (data & bits) == bits, -+ sleep_us, timeout_us); -+ } -+ -+ return ret; -+} -+ -+static void comphy_periph_reg_set(struct mvebu_a3700_comphy_lane *lane, -+ u8 reg, u32 data, u32 mask) -+{ -+ comphy_reg_set(lane->priv->comphy_regs + COMPHY_PHY_REG(lane->id, reg), -+ data, mask); -+} -+ -+static int comphy_periph_reg_poll(struct mvebu_a3700_comphy_lane *lane, -+ u8 reg, u32 bits, -+ ulong sleep_us, ulong timeout_us) -+{ -+ u32 data; -+ -+ return readl_poll_timeout(lane->priv->comphy_regs + -+ COMPHY_PHY_REG(lane->id, reg), -+ data, (data & bits) == bits, -+ sleep_us, timeout_us); -+} -+ -+/* PHY selector configures with corresponding modes */ -+static int -+mvebu_a3700_comphy_set_phy_selector(struct mvebu_a3700_comphy_lane *lane) -+{ -+ u32 old, new, clr = 0, set = 0; -+ unsigned long flags; -+ -+ switch (lane->mode) { -+ case PHY_MODE_SATA: -+ /* SATA must be in Lane2 */ -+ if (lane->id == 2) -+ clr = COMPHY_SELECTOR_USB3_PHY_SEL_BIT; -+ else -+ goto error; -+ break; -+ -+ case PHY_MODE_ETHERNET: -+ if (lane->id == 0) -+ clr = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT; -+ else if (lane->id == 1) -+ clr = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT; -+ else -+ goto error; -+ break; -+ -+ case PHY_MODE_USB_HOST_SS: -+ if (lane->id == 2) -+ set = COMPHY_SELECTOR_USB3_PHY_SEL_BIT; -+ else if (lane->id == 0) -+ set = COMPHY_SELECTOR_USB3_GBE1_SEL_BIT; -+ else -+ goto error; -+ break; -+ -+ case PHY_MODE_PCIE: -+ /* PCIE must be in Lane1 */ -+ if (lane->id == 1) -+ set = COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT; -+ else -+ goto error; -+ break; -+ -+ default: -+ goto error; -+ } -+ -+ spin_lock_irqsave(&lane->priv->lock, flags); -+ -+ old = readl(lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG); -+ new = (old & ~clr) | set; -+ writel(new, lane->priv->comphy_regs + COMPHY_SELECTOR_PHY_REG); -+ -+ spin_unlock_irqrestore(&lane->priv->lock, flags); -+ -+ dev_dbg(lane->dev, -+ "COMPHY[%d] mode[%d] changed PHY selector 0x%08x -> 0x%08x\n", -+ lane->id, lane->mode, old, new); -+ -+ return 0; -+error: -+ dev_err(lane->dev, "COMPHY[%d] mode[%d] is invalid\n", lane->id, -+ lane->mode); -+ return -EINVAL; -+} -+ -+static int -+mvebu_a3700_comphy_sata_power_on(struct mvebu_a3700_comphy_lane *lane) -+{ -+ u32 mask, data, ref_clk; -+ int ret; -+ -+ /* Configure phy selector for SATA */ -+ ret = mvebu_a3700_comphy_set_phy_selector(lane); -+ if (ret) -+ return ret; -+ -+ /* Clear phy isolation mode to make it work in normal mode */ -+ comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL, -+ 0x0, PHY_ISOLATE_MODE); -+ -+ /* 0. Check the Polarity invert bits */ -+ data = 0x0; -+ if (lane->invert_tx) -+ data |= TXD_INVERT_BIT; -+ if (lane->invert_rx) -+ data |= RXD_INVERT_BIT; -+ mask = TXD_INVERT_BIT | RXD_INVERT_BIT; -+ comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); -+ -+ /* 1. Select 40-bit data width */ -+ comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, -+ DATA_WIDTH_40BIT, SEL_DATA_WIDTH_MASK); -+ -+ /* 2. Select reference clock(25M) and PHY mode (SATA) */ -+ if (lane->priv->xtal_is_40m) -+ ref_clk = REF_FREF_SEL_SERDES_40MHZ; -+ else -+ ref_clk = REF_FREF_SEL_SERDES_25MHZ; -+ -+ data = ref_clk | COMPHY_MODE_SATA; -+ mask = REF_FREF_SEL_MASK | COMPHY_MODE_MASK; -+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); -+ -+ /* 3. Use maximum PLL rate (no power save) */ -+ comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, -+ USE_MAX_PLL_RATE_BIT, USE_MAX_PLL_RATE_BIT); -+ -+ /* 4. Reset reserved bit */ -+ comphy_set_indirect(lane->priv, COMPHY_RESERVED_REG, -+ 0x0, PHYCTRL_FRM_PIN_BIT); -+ -+ /* 5. Set vendor-specific configuration (It is done in sata driver) */ -+ /* XXX: in U-Boot below sequence was executed in this place, in Linux -+ * not. Now it is done only in U-Boot before this comphy -+ * initialization - tests shows that it works ok, but in case of any -+ * future problem it is left for reference. -+ * reg_set(MVEBU_REGS_BASE + 0xe00a0, 0, 0xffffffff); -+ * reg_set(MVEBU_REGS_BASE + 0xe00a4, BIT(6), BIT(6)); -+ */ -+ -+ /* Wait for > 55 us to allow PLL be enabled */ -+ udelay(PLL_SET_DELAY_US); -+ -+ /* Polling status */ -+ ret = comphy_lane_reg_poll(lane, COMPHY_DIG_LOOPBACK_EN, -+ PLL_READY_TX_BIT, COMPHY_PLL_SLEEP, -+ COMPHY_PLL_TIMEOUT); -+ if (ret) -+ dev_err(lane->dev, "Failed to lock SATA PLL\n"); -+ -+ return ret; -+} -+ -+static void comphy_gbe_phy_init(struct mvebu_a3700_comphy_lane *lane, -+ bool is_1gbps) -+{ -+ int addr, fix_idx; -+ u16 val; -+ -+ fix_idx = 0; -+ for (addr = 0; addr < 512; addr++) { -+ /* -+ * All PHY register values are defined in full for 3.125Gbps -+ * SERDES speed. The values required for 1.25 Gbps are almost -+ * the same and only few registers should be "fixed" in -+ * comparison to 3.125 Gbps values. These register values are -+ * stored in "gbe_phy_init_fix" array. -+ */ -+ if (!is_1gbps && gbe_phy_init_fix[fix_idx].addr == addr) { -+ /* Use new value */ -+ val = gbe_phy_init_fix[fix_idx].value; -+ if (fix_idx < ARRAY_SIZE(gbe_phy_init_fix)) -+ fix_idx++; -+ } else { -+ val = gbe_phy_init[addr]; -+ } -+ -+ comphy_lane_reg_set(lane, addr, val, 0xFFFF); -+ } -+} -+ -+static int -+mvebu_a3700_comphy_ethernet_power_on(struct mvebu_a3700_comphy_lane *lane) -+{ -+ u32 mask, data, speed_sel; -+ int ret; -+ -+ /* Set selector */ -+ ret = mvebu_a3700_comphy_set_phy_selector(lane); -+ if (ret) -+ return ret; -+ -+ /* -+ * 1. Reset PHY by setting PHY input port PIN_RESET=1. -+ * 2. Set PHY input port PIN_TX_IDLE=1, PIN_PU_IVREF=1 to keep -+ * PHY TXP/TXN output to idle state during PHY initialization -+ * 3. Set PHY input port PIN_PU_PLL=0, PIN_PU_RX=0, PIN_PU_TX=0. -+ */ -+ data = PIN_PU_IVREF_BIT | PIN_TX_IDLE_BIT | PIN_RESET_COMPHY_BIT; -+ mask = data | PIN_RESET_CORE_BIT | PIN_PU_PLL_BIT | PIN_PU_RX_BIT | -+ PIN_PU_TX_BIT | PHY_RX_INIT_BIT; -+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); -+ -+ /* 4. Release reset to the PHY by setting PIN_RESET=0. */ -+ data = 0x0; -+ mask = PIN_RESET_COMPHY_BIT; -+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); -+ -+ /* -+ * 5. Set PIN_PHY_GEN_TX[3:0] and PIN_PHY_GEN_RX[3:0] to decide COMPHY -+ * bit rate -+ */ -+ switch (lane->submode) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ /* SGMII 1G, SerDes speed 1.25G */ -+ speed_sel = SERDES_SPEED_1_25_G; -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ /* 2500Base-X, SerDes speed 3.125G */ -+ speed_sel = SERDES_SPEED_3_125_G; -+ break; - default: -+ /* Other rates are not supported */ -+ dev_err(lane->dev, -+ "unsupported phy speed %d on comphy lane%d\n", -+ lane->submode, lane->id); - return -EINVAL; - } -+ data = GEN_RX_SEL_VALUE(speed_sel) | GEN_TX_SEL_VALUE(speed_sel); -+ mask = GEN_RX_SEL_MASK | GEN_TX_SEL_MASK; -+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); -+ -+ /* -+ * 6. Wait 10mS for bandgap and reference clocks to stabilize; then -+ * start SW programming. -+ */ -+ mdelay(10); -+ -+ /* 7. Program COMPHY register PHY_MODE */ -+ data = COMPHY_MODE_SERDES; -+ mask = COMPHY_MODE_MASK; -+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); -+ -+ /* -+ * 8. Set COMPHY register REFCLK_SEL to select the correct REFCLK -+ * source -+ */ -+ data = 0x0; -+ mask = PHY_REF_CLK_SEL; -+ comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask); -+ -+ /* -+ * 9. Set correct reference clock frequency in COMPHY register -+ * REF_FREF_SEL. -+ */ -+ if (lane->priv->xtal_is_40m) -+ data = REF_FREF_SEL_SERDES_50MHZ; -+ else -+ data = REF_FREF_SEL_SERDES_25MHZ; -+ -+ mask = REF_FREF_SEL_MASK; -+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); -+ -+ /* -+ * 10. Program COMPHY register PHY_GEN_MAX[1:0] -+ * This step is mentioned in the flow received from verification team. -+ * However the PHY_GEN_MAX value is only meaningful for other interfaces -+ * (not SERDES). For instance, it selects SATA speed 1.5/3/6 Gbps or -+ * PCIe speed 2.5/5 Gbps -+ */ -+ -+ /* -+ * 11. Program COMPHY register SEL_BITS to set correct parallel data -+ * bus width -+ */ -+ data = DATA_WIDTH_10BIT; -+ mask = SEL_DATA_WIDTH_MASK; -+ comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, data, mask); -+ -+ /* -+ * 12. As long as DFE function needs to be enabled in any mode, -+ * COMPHY register DFE_UPDATE_EN[5:0] shall be programmed to 0x3F -+ * for real chip during COMPHY power on. -+ * The value of the DFE_UPDATE_EN already is 0x3F, because it is the -+ * default value after reset of the PHY. -+ */ -+ -+ /* -+ * 13. Program COMPHY GEN registers. -+ * These registers should be programmed based on the lab testing result -+ * to achieve optimal performance. Please contact the CEA group to get -+ * the related GEN table during real chip bring-up. We only required to -+ * run though the entire registers programming flow defined by -+ * "comphy_gbe_phy_init" when the REF clock is 40 MHz. For REF clock -+ * 25 MHz the default values stored in PHY registers are OK. -+ */ -+ dev_dbg(lane->dev, "Running C-DPI phy init %s mode\n", -+ lane->submode == PHY_INTERFACE_MODE_2500BASEX ? "2G5" : "1G"); -+ if (lane->priv->xtal_is_40m) -+ comphy_gbe_phy_init(lane, -+ lane->submode != PHY_INTERFACE_MODE_2500BASEX); -+ -+ /* -+ * 14. Check the PHY Polarity invert bit -+ */ -+ data = 0x0; -+ if (lane->invert_tx) -+ data |= TXD_INVERT_BIT; -+ if (lane->invert_rx) -+ data |= RXD_INVERT_BIT; -+ mask = TXD_INVERT_BIT | RXD_INVERT_BIT; -+ comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); -+ -+ /* -+ * 15. Set PHY input ports PIN_PU_PLL, PIN_PU_TX and PIN_PU_RX to 1 to -+ * start PHY power up sequence. All the PHY register programming should -+ * be done before PIN_PU_PLL=1. There should be no register programming -+ * for normal PHY operation from this point. -+ */ -+ data = PIN_PU_PLL_BIT | PIN_PU_RX_BIT | PIN_PU_TX_BIT; -+ mask = data; -+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); -+ -+ /* -+ * 16. Wait for PHY power up sequence to finish by checking output ports -+ * PIN_PLL_READY_TX=1 and PIN_PLL_READY_RX=1. -+ */ -+ ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1, -+ PHY_PLL_READY_TX_BIT | -+ PHY_PLL_READY_RX_BIT, -+ COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); -+ if (ret) { -+ dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n", -+ lane->id); -+ return ret; -+ } -+ -+ /* -+ * 17. Set COMPHY input port PIN_TX_IDLE=0 -+ */ -+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, 0x0, PIN_TX_IDLE_BIT); -+ -+ /* -+ * 18. After valid data appear on PIN_RXDATA bus, set PIN_RX_INIT=1. To -+ * start RX initialization. PIN_RX_INIT_DONE will be cleared to 0 by the -+ * PHY After RX initialization is done, PIN_RX_INIT_DONE will be set to -+ * 1 by COMPHY Set PIN_RX_INIT=0 after PIN_RX_INIT_DONE= 1. Please -+ * refer to RX initialization part for details. -+ */ -+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, -+ PHY_RX_INIT_BIT, PHY_RX_INIT_BIT); -+ -+ ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1, -+ PHY_PLL_READY_TX_BIT | -+ PHY_PLL_READY_RX_BIT, -+ COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); -+ if (ret) { -+ dev_err(lane->dev, "Failed to lock PLL for SERDES PHY %d\n", -+ lane->id); -+ return ret; -+ } -+ -+ ret = comphy_periph_reg_poll(lane, COMPHY_PHY_STAT1, -+ PHY_RX_INIT_DONE_BIT, -+ COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); -+ if (ret) -+ dev_err(lane->dev, "Failed to init RX of SERDES PHY %d\n", -+ lane->id); -+ -+ return ret; - } - --static int mvebu_a3700_comphy_get_fw_mode(int lane, -+static int -+mvebu_a3700_comphy_usb3_power_on(struct mvebu_a3700_comphy_lane *lane) -+{ -+ u32 mask, data, cfg, ref_clk; -+ int ret; -+ -+ /* Set phy seclector */ -+ ret = mvebu_a3700_comphy_set_phy_selector(lane); -+ if (ret) -+ return ret; -+ -+ /* -+ * 0. Set PHY OTG Control(0x5d034), bit 4, Power up OTG module The -+ * register belong to UTMI module, so it is set in UTMI phy driver. -+ */ -+ -+ /* -+ * 1. Set PRD_TXDEEMPH (3.5db de-emph) -+ */ -+ data = PRD_TXDEEMPH0_MASK; -+ mask = PRD_TXDEEMPH0_MASK | PRD_TXMARGIN_MASK | PRD_TXSWING_MASK | -+ CFG_TX_ALIGN_POS_MASK; -+ comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG0, data, mask); -+ -+ /* -+ * 2. Set BIT0: enable transmitter in high impedance mode -+ * Set BIT[3:4]: delay 2 clock cycles for HiZ off latency -+ * Set BIT6: Tx detect Rx at HiZ mode -+ * Unset BIT15: set to 0 to set USB3 De-emphasize level to -3.5db -+ * together with bit 0 of COMPHY_PIPE_LANE_CFG0 register -+ */ -+ data = TX_DET_RX_MODE | GEN2_TX_DATA_DLY_DEFT | TX_ELEC_IDLE_MODE_EN; -+ mask = PRD_TXDEEMPH1_MASK | TX_DET_RX_MODE | GEN2_TX_DATA_DLY_MASK | -+ TX_ELEC_IDLE_MODE_EN; -+ comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1, data, mask); -+ -+ /* -+ * 3. Set Spread Spectrum Clock Enabled -+ */ -+ comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG4, -+ SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN); -+ -+ /* -+ * 4. Set Override Margining Controls From the MAC: -+ * Use margining signals from lane configuration -+ */ -+ comphy_lane_reg_set(lane, COMPHY_PIPE_TEST_MODE_CTRL, -+ MODE_MARGIN_OVERRIDE, 0xFFFF); -+ -+ /* -+ * 5. Set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles -+ * set Mode Clock Source = PCLK is generated from REFCLK -+ */ -+ data = 0x0; -+ mask = MODE_CLK_SRC | BUNDLE_PERIOD_SEL | BUNDLE_PERIOD_SCALE_MASK | -+ BUNDLE_SAMPLE_CTRL | PLL_READY_DLY_MASK; -+ comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO, data, mask); -+ -+ /* -+ * 6. Set G2 Spread Spectrum Clock Amplitude at 4K -+ */ -+ comphy_lane_reg_set(lane, COMPHY_GEN2_SET2, -+ GS2_TX_SSC_AMP_4128, GS2_TX_SSC_AMP_MASK); -+ -+ /* -+ * 7. Unset G3 Spread Spectrum Clock Amplitude -+ * set G3 TX and RX Register Master Current Select -+ */ -+ data = GS2_VREG_RXTX_MAS_ISET_60U; -+ mask = GS2_TX_SSC_AMP_MASK | GS2_VREG_RXTX_MAS_ISET_MASK | -+ GS2_RSVD_6_0_MASK; -+ comphy_lane_reg_set(lane, COMPHY_GEN3_SET2, data, mask); -+ -+ /* -+ * 8. Check crystal jumper setting and program the Power and PLL Control -+ * accordingly Change RX wait -+ */ -+ if (lane->priv->xtal_is_40m) { -+ ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ; -+ cfg = CFG_PM_RXDLOZ_WAIT_12_UNIT; -+ } else { -+ ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ; -+ cfg = CFG_PM_RXDLOZ_WAIT_7_UNIT; -+ } -+ -+ data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT | -+ PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_USB3 | ref_clk; -+ mask = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT | -+ PU_TX_INTP_BIT | PU_DFE_BIT | PLL_LOCK_BIT | COMPHY_MODE_MASK | -+ REF_FREF_SEL_MASK; -+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); -+ -+ data = CFG_PM_RXDEN_WAIT_1_UNIT | cfg; -+ mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK | -+ CFG_PM_RXDLOZ_WAIT_MASK; -+ comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask); -+ -+ /* -+ * 9. Enable idle sync -+ */ -+ comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN, -+ IDLE_SYNC_EN, IDLE_SYNC_EN); -+ -+ /* -+ * 10. Enable the output of 500M clock -+ */ -+ comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, CLK500M_EN, CLK500M_EN); -+ -+ /* -+ * 11. Set 20-bit data width -+ */ -+ comphy_lane_reg_set(lane, COMPHY_DIG_LOOPBACK_EN, -+ DATA_WIDTH_20BIT, 0xFFFF); -+ -+ /* -+ * 12. Override Speed_PLL value and use MAC PLL -+ */ -+ data = SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT; -+ mask = 0xFFFF; -+ comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, data, mask); -+ -+ /* -+ * 13. Check the Polarity invert bit -+ */ -+ data = 0x0; -+ if (lane->invert_tx) -+ data |= TXD_INVERT_BIT; -+ if (lane->invert_rx) -+ data |= RXD_INVERT_BIT; -+ mask = TXD_INVERT_BIT | RXD_INVERT_BIT; -+ comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); -+ -+ /* -+ * 14. Set max speed generation to USB3.0 5Gbps -+ */ -+ comphy_lane_reg_set(lane, COMPHY_SYNC_MASK_GEN, -+ PHY_GEN_MAX_USB3_5G, PHY_GEN_MAX_MASK); -+ -+ /* -+ * 15. Set capacitor value for FFE gain peaking to 0xF -+ */ -+ comphy_lane_reg_set(lane, COMPHY_GEN2_SET3, -+ GS3_FFE_CAP_SEL_VALUE, GS3_FFE_CAP_SEL_MASK); -+ -+ /* -+ * 16. Release SW reset -+ */ -+ data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32 | MODE_REFDIV_BY_4; -+ mask = 0xFFFF; -+ comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask); -+ -+ /* Wait for > 55 us to allow PCLK be enabled */ -+ udelay(PLL_SET_DELAY_US); -+ -+ ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN, -+ COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); -+ if (ret) -+ dev_err(lane->dev, "Failed to lock USB3 PLL\n"); -+ -+ return ret; -+} -+ -+static int -+mvebu_a3700_comphy_pcie_power_on(struct mvebu_a3700_comphy_lane *lane) -+{ -+ u32 mask, data, ref_clk; -+ int ret; -+ -+ /* Configure phy selector for PCIe */ -+ ret = mvebu_a3700_comphy_set_phy_selector(lane); -+ if (ret) -+ return ret; -+ -+ /* 1. Enable max PLL. */ -+ comphy_lane_reg_set(lane, COMPHY_PIPE_LANE_CFG1, -+ USE_MAX_PLL_RATE_EN, USE_MAX_PLL_RATE_EN); -+ -+ /* 2. Select 20 bit SERDES interface. */ -+ comphy_lane_reg_set(lane, COMPHY_PIPE_CLK_SRC_LO, -+ CFG_SEL_20B, CFG_SEL_20B); -+ -+ /* 3. Force to use reg setting for PCIe mode */ -+ comphy_lane_reg_set(lane, COMPHY_MISC_CTRL1, -+ SEL_BITS_PCIE_FORCE, SEL_BITS_PCIE_FORCE); -+ -+ /* 4. Change RX wait */ -+ data = CFG_PM_RXDEN_WAIT_1_UNIT | CFG_PM_RXDLOZ_WAIT_12_UNIT; -+ mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK | -+ CFG_PM_RXDLOZ_WAIT_MASK; -+ comphy_lane_reg_set(lane, COMPHY_PIPE_PWR_MGM_TIM1, data, mask); -+ -+ /* 5. Enable idle sync */ -+ comphy_lane_reg_set(lane, COMPHY_IDLE_SYNC_EN, -+ IDLE_SYNC_EN, IDLE_SYNC_EN); -+ -+ /* 6. Enable the output of 100M/125M/500M clock */ -+ data = CLK500M_EN | TXDCLK_2X_SEL | CLK100M_125M_EN; -+ mask = data; -+ comphy_lane_reg_set(lane, COMPHY_MISC_CTRL0, data, mask); -+ -+ /* -+ * 7. Enable TX, PCIE global register, 0xd0074814, it is done in -+ * PCI-E driver -+ */ -+ -+ /* -+ * 8. Check crystal jumper setting and program the Power and PLL -+ * Control accordingly -+ */ -+ -+ if (lane->priv->xtal_is_40m) -+ ref_clk = REF_FREF_SEL_PCIE_USB3_40MHZ; -+ else -+ ref_clk = REF_FREF_SEL_PCIE_USB3_25MHZ; -+ -+ data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT | -+ PU_TX_INTP_BIT | PU_DFE_BIT | COMPHY_MODE_PCIE | ref_clk; -+ mask = 0xFFFF; -+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, data, mask); -+ -+ /* 9. Override Speed_PLL value and use MAC PLL */ -+ comphy_lane_reg_set(lane, COMPHY_KVCO_CAL_CTRL, -+ SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT, -+ 0xFFFF); -+ -+ /* 10. Check the Polarity invert bit */ -+ data = 0x0; -+ if (lane->invert_tx) -+ data |= TXD_INVERT_BIT; -+ if (lane->invert_rx) -+ data |= RXD_INVERT_BIT; -+ mask = TXD_INVERT_BIT | RXD_INVERT_BIT; -+ comphy_lane_reg_set(lane, COMPHY_SYNC_PATTERN, data, mask); -+ -+ /* 11. Release SW reset */ -+ data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32; -+ mask = data | PIPE_SOFT_RESET | MODE_REFDIV_MASK; -+ comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask); -+ -+ /* Wait for > 55 us to allow PCLK be enabled */ -+ udelay(PLL_SET_DELAY_US); -+ -+ ret = comphy_lane_reg_poll(lane, COMPHY_PIPE_LANE_STAT1, TXDCLK_PCLK_EN, -+ COMPHY_PLL_SLEEP, COMPHY_PLL_TIMEOUT); -+ if (ret) -+ dev_err(lane->dev, "Failed to lock PCIE PLL\n"); -+ -+ return ret; -+} -+ -+static void -+mvebu_a3700_comphy_sata_power_off(struct mvebu_a3700_comphy_lane *lane) -+{ -+ /* Set phy isolation mode */ -+ comphy_lane_reg_set(lane, COMPHY_ISOLATION_CTRL, -+ PHY_ISOLATE_MODE, PHY_ISOLATE_MODE); -+ -+ /* Power off PLL, Tx, Rx */ -+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, -+ 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT); -+} -+ -+static void -+mvebu_a3700_comphy_ethernet_power_off(struct mvebu_a3700_comphy_lane *lane) -+{ -+ u32 mask, data; -+ -+ data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT | PIN_PU_IVREF_BIT | -+ PHY_RX_INIT_BIT; -+ mask = data; -+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); -+} -+ -+static void -+mvebu_a3700_comphy_pcie_power_off(struct mvebu_a3700_comphy_lane *lane) -+{ -+ /* Power off PLL, Tx, Rx */ -+ comphy_lane_reg_set(lane, COMPHY_POWER_PLL_CTRL, -+ 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT); -+} -+ -+static int mvebu_a3700_comphy_reset(struct phy *phy) -+{ -+ struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); -+ u16 mask, data; -+ -+ dev_dbg(lane->dev, "resetting lane %d\n", lane->id); -+ -+ /* COMPHY reset for internal logic */ -+ comphy_lane_reg_set(lane, COMPHY_SFT_RESET, -+ SFT_RST_NO_REG, SFT_RST_NO_REG); -+ -+ /* COMPHY register reset (cleared automatically) */ -+ comphy_lane_reg_set(lane, COMPHY_SFT_RESET, SFT_RST, SFT_RST); -+ -+ /* PIPE soft and register reset */ -+ data = PIPE_SOFT_RESET | PIPE_REG_RESET; -+ mask = data; -+ comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask); -+ -+ /* Release PIPE register reset */ -+ comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, -+ 0x0, PIPE_REG_RESET); -+ -+ /* Reset SB configuration register (only for lanes 0 and 1) */ -+ if (lane->id == 0 || lane->id == 1) { -+ u32 mask, data; -+ -+ data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT | -+ PIN_PU_PLL_BIT | PIN_PU_RX_BIT | PIN_PU_TX_BIT; -+ mask = data | PIN_PU_IVREF_BIT | PIN_TX_IDLE_BIT; -+ comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); -+ } -+ -+ return 0; -+} -+ -+static bool mvebu_a3700_comphy_check_mode(int lane, - enum phy_mode mode, - int submode) - { -@@ -122,7 +1141,7 @@ static int mvebu_a3700_comphy_get_fw_mod - - /* Unused PHY mux value is 0x0 */ - if (mode == PHY_MODE_INVALID) -- return -EINVAL; -+ return false; - - for (i = 0; i < n; i++) { - if (mvebu_a3700_comphy_modes[i].lane == lane && -@@ -132,27 +1151,30 @@ static int mvebu_a3700_comphy_get_fw_mod - } - - if (i == n) -- return -EINVAL; -+ return false; - -- return mvebu_a3700_comphy_modes[i].fw_mode; -+ return true; - } - - static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode, - int submode) - { - struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); -- int fw_mode; - -- if (submode == PHY_INTERFACE_MODE_1000BASEX) -- submode = PHY_INTERFACE_MODE_SGMII; -- -- fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, mode, -- submode); -- if (fw_mode < 0) { -+ if (!mvebu_a3700_comphy_check_mode(lane->id, mode, submode)) { - dev_err(lane->dev, "invalid COMPHY mode\n"); -- return fw_mode; -+ return -EINVAL; - } - -+ /* Mode cannot be changed while the PHY is powered on */ -+ if (phy->power_count && -+ (lane->mode != mode || lane->submode != submode)) -+ return -EBUSY; -+ -+ /* If changing mode, ensure reset is called */ -+ if (lane->mode != PHY_MODE_INVALID && lane->mode != mode) -+ lane->needs_reset = true; -+ - /* Just remember the mode, ->power_on() will do the real setup */ - lane->mode = mode; - lane->submode = submode; -@@ -163,76 +1185,77 @@ static int mvebu_a3700_comphy_set_mode(s - static int mvebu_a3700_comphy_power_on(struct phy *phy) - { - struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); -- u32 fw_param; -- int fw_mode; -- int fw_port; - int ret; - -- fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, -- lane->mode, lane->submode); -- if (fw_mode < 0) { -+ if (!mvebu_a3700_comphy_check_mode(lane->id, lane->mode, -+ lane->submode)) { - dev_err(lane->dev, "invalid COMPHY mode\n"); -- return fw_mode; -+ return -EINVAL; -+ } -+ -+ if (lane->needs_reset) { -+ ret = mvebu_a3700_comphy_reset(phy); -+ if (ret) -+ return ret; -+ -+ lane->needs_reset = false; - } - - switch (lane->mode) { - case PHY_MODE_USB_HOST_SS: - dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id); -- fw_param = COMPHY_FW_MODE(fw_mode); -- break; -+ return mvebu_a3700_comphy_usb3_power_on(lane); - case PHY_MODE_SATA: - dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id); -- fw_param = COMPHY_FW_MODE(fw_mode); -- break; -+ return mvebu_a3700_comphy_sata_power_on(lane); - case PHY_MODE_ETHERNET: -- fw_port = (lane->id == 0) ? 1 : 0; -- switch (lane->submode) { -- case PHY_INTERFACE_MODE_SGMII: -- dev_dbg(lane->dev, "set lane %d to SGMII mode\n", -- lane->id); -- fw_param = COMPHY_FW_NET(fw_mode, fw_port, -- COMPHY_FW_SPEED_1_25G); -- break; -- case PHY_INTERFACE_MODE_2500BASEX: -- dev_dbg(lane->dev, "set lane %d to 2500BASEX mode\n", -- lane->id); -- fw_param = COMPHY_FW_NET(fw_mode, fw_port, -- COMPHY_FW_SPEED_3_125G); -- break; -- default: -- dev_err(lane->dev, "unsupported PHY submode (%d)\n", -- lane->submode); -- return -ENOTSUPP; -- } -- break; -+ dev_dbg(lane->dev, "set lane %d to Ethernet mode\n", lane->id); -+ return mvebu_a3700_comphy_ethernet_power_on(lane); - case PHY_MODE_PCIE: - dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id); -- fw_param = COMPHY_FW_PCIE(fw_mode, COMPHY_FW_SPEED_5G, -- phy->attrs.bus_width); -- break; -+ return mvebu_a3700_comphy_pcie_power_on(lane); - default: - dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode); -- return -ENOTSUPP; -+ return -EOPNOTSUPP; - } -- -- ret = mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param); -- if (ret == -EOPNOTSUPP) -- dev_err(lane->dev, -- "unsupported SMC call, try updating your firmware\n"); -- -- return ret; - } - - static int mvebu_a3700_comphy_power_off(struct phy *phy) - { - struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); - -- return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_OFF, lane->id, 0); -+ switch (lane->mode) { -+ case PHY_MODE_USB_HOST_SS: -+ /* -+ * The USB3 MAC sets the USB3 PHY to low state, so we do not -+ * need to power off USB3 PHY again. -+ */ -+ break; -+ -+ case PHY_MODE_SATA: -+ mvebu_a3700_comphy_sata_power_off(lane); -+ break; -+ -+ case PHY_MODE_ETHERNET: -+ mvebu_a3700_comphy_ethernet_power_off(lane); -+ break; -+ -+ case PHY_MODE_PCIE: -+ mvebu_a3700_comphy_pcie_power_off(lane); -+ break; -+ -+ default: -+ dev_err(lane->dev, "invalid COMPHY mode\n"); -+ return -EINVAL; -+ } -+ -+ return 0; - } - - static const struct phy_ops mvebu_a3700_comphy_ops = { - .power_on = mvebu_a3700_comphy_power_on, - .power_off = mvebu_a3700_comphy_power_off, -+ .reset = mvebu_a3700_comphy_reset, - .set_mode = mvebu_a3700_comphy_set_mode, - .owner = THIS_MODULE, - }; -@@ -256,13 +1279,75 @@ static struct phy *mvebu_a3700_comphy_xl - return ERR_PTR(-EINVAL); - } - -+ lane->invert_tx = args->args[1] & BIT(0); -+ lane->invert_rx = args->args[1] & BIT(1); -+ - return phy; - } - - static int mvebu_a3700_comphy_probe(struct platform_device *pdev) - { -+ struct mvebu_a3700_comphy_priv *priv; - struct phy_provider *provider; - struct device_node *child; -+ struct resource *res; -+ struct clk *clk; -+ int ret; -+ -+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ spin_lock_init(&priv->lock); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "comphy"); -+ priv->comphy_regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(priv->comphy_regs)) -+ return PTR_ERR(priv->comphy_regs); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -+ "lane1_pcie_gbe"); -+ priv->lane1_phy_regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(priv->lane1_phy_regs)) -+ return PTR_ERR(priv->lane1_phy_regs); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -+ "lane0_usb3_gbe"); -+ priv->lane0_phy_regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(priv->lane0_phy_regs)) -+ return PTR_ERR(priv->lane0_phy_regs); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -+ "lane2_sata_usb3"); -+ priv->lane2_phy_indirect = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(priv->lane2_phy_indirect)) -+ return PTR_ERR(priv->lane2_phy_indirect); -+ -+ /* -+ * Driver needs to know if reference xtal clock is 40MHz or 25MHz. -+ * Old DT bindings do not have xtal clk present. So do not fail here -+ * and expects that default 25MHz reference clock is used. -+ */ -+ clk = clk_get(&pdev->dev, "xtal"); -+ if (IS_ERR(clk)) { -+ if (PTR_ERR(clk) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ dev_warn(&pdev->dev, "missing 'xtal' clk (%ld)\n", -+ PTR_ERR(clk)); -+ } else { -+ ret = clk_prepare_enable(clk); -+ if (ret) { -+ dev_warn(&pdev->dev, "enabling xtal clk failed (%d)\n", -+ ret); -+ } else { -+ if (clk_get_rate(clk) == 40000000) -+ priv->xtal_is_40m = true; -+ clk_disable_unprepare(clk); -+ } -+ clk_put(clk); -+ } -+ -+ dev_set_drvdata(&pdev->dev, priv); - - for_each_available_child_of_node(pdev->dev.of_node, child) { - struct mvebu_a3700_comphy_lane *lane; -@@ -277,7 +1362,7 @@ static int mvebu_a3700_comphy_probe(stru - continue; - } - -- if (lane_id >= MVEBU_A3700_COMPHY_LANES) { -+ if (lane_id >= 3) { - dev_err(&pdev->dev, "invalid 'reg' property\n"); - continue; - } -@@ -295,15 +1380,26 @@ static int mvebu_a3700_comphy_probe(stru - return PTR_ERR(phy); - } - -+ lane->priv = priv; - lane->dev = &pdev->dev; - lane->mode = PHY_MODE_INVALID; - lane->submode = PHY_INTERFACE_MODE_NA; - lane->id = lane_id; -+ lane->invert_tx = false; -+ lane->invert_rx = false; - phy_set_drvdata(phy, lane); -+ -+ /* -+ * To avoid relying on the bootloader/firmware configuration, -+ * power off all comphys. -+ */ -+ mvebu_a3700_comphy_reset(phy); -+ lane->needs_reset = false; - } - - provider = devm_of_phy_provider_register(&pdev->dev, - mvebu_a3700_comphy_xlate); -+ - return PTR_ERR_OR_ZERO(provider); - } - -@@ -323,5 +1419,7 @@ static struct platform_driver mvebu_a370 - module_platform_driver(mvebu_a3700_comphy_driver); - - MODULE_AUTHOR("Miquèl Raynal "); -+MODULE_AUTHOR("Pali Rohár "); -+MODULE_AUTHOR("Marek Behún "); - MODULE_DESCRIPTION("Common PHY driver for A3700"); - MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/backport-5.15/345-v5.17-arm64-dts-marvell-armada-37xx-Add-xtal-clock-to-comp.patch b/target/linux/generic/backport-5.15/345-v5.17-arm64-dts-marvell-armada-37xx-Add-xtal-clock-to-comp.patch deleted file mode 100644 index 03b6a5754d96fc..00000000000000 --- a/target/linux/generic/backport-5.15/345-v5.17-arm64-dts-marvell-armada-37xx-Add-xtal-clock-to-comp.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 73a78b6130d9e13daca22b86ad52f063b9403e03 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Wed, 8 Dec 2021 03:40:35 +0100 -Subject: [PATCH 1/1] arm64: dts: marvell: armada-37xx: Add xtal clock to - comphy node -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Kernel driver phy-mvebu-a3700-comphy.c needs to know the rate of the -reference xtal clock. So add missing xtal clock source into comphy device -tree node. If the property is not present, the driver defaults to 25 MHz -xtal rate (which, as far as we know, is used by all the existing boards). - -Signed-off-by: Pali Rohár -Signed-off-by: Marek Behún -Signed-off-by: Gregory CLEMENT ---- - arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi -@@ -265,6 +265,8 @@ - "lane2_sata_usb3"; - #address-cells = <1>; - #size-cells = <0>; -+ clocks = <&xtalclk>; -+ clock-names = "xtal"; - - comphy0: phy@0 { - reg = <0>; diff --git a/target/linux/generic/backport-5.15/346-v5.18-01-Revert-ata-ahci-mvebu-Make-SATA-PHY-optional-for-Arm.patch b/target/linux/generic/backport-5.15/346-v5.18-01-Revert-ata-ahci-mvebu-Make-SATA-PHY-optional-for-Arm.patch deleted file mode 100644 index 35bc19c1ef5d6c..00000000000000 --- a/target/linux/generic/backport-5.15/346-v5.18-01-Revert-ata-ahci-mvebu-Make-SATA-PHY-optional-for-Arm.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ee995101fde67f85a3cd4c74f4f92fc4592e726b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Thu, 3 Feb 2022 22:44:42 +0100 -Subject: [PATCH 1/3] Revert "ata: ahci: mvebu: Make SATA PHY optional for - Armada 3720" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit 45aefe3d2251e4e229d7662052739f96ad1d08d9. - -Armada 3720 PHY driver (phy-mvebu-a3700-comphy.c) does not return --EOPNOTSUPP from phy_power_on() callback anymore. - -So remove AHCI_HFLAG_IGN_NOTSUPP_POWER_ON flag from Armada 3720 plat data. - -AHCI_HFLAG_IGN_NOTSUPP_POWER_ON is not used by any other ahci driver, so -remove this flag completely. - -Signed-off-by: Pali Rohár -Signed-off-by: Marek Behún -Acked-by: Miquel Raynal -Acked-by: Damien Le Moal -Link: https://lore.kernel.org/r/20220203214444.1508-4-kabel@kernel.org -Signed-off-by: Vinod Koul ---- - drivers/ata/ahci.h | 2 -- - drivers/ata/ahci_mvebu.c | 2 +- - drivers/ata/libahci_platform.c | 2 +- - 3 files changed, 2 insertions(+), 4 deletions(-) - ---- a/drivers/ata/ahci.h -+++ b/drivers/ata/ahci.h -@@ -240,8 +240,6 @@ enum { - as default lpm_policy */ - AHCI_HFLAG_SUSPEND_PHYS = BIT(26), /* handle PHYs during - suspend/resume */ -- AHCI_HFLAG_IGN_NOTSUPP_POWER_ON = BIT(27), /* ignore -EOPNOTSUPP -- from phy_power_on() */ - AHCI_HFLAG_NO_SXS = BIT(28), /* SXS not supported */ - AHCI_HFLAG_43BIT_ONLY = BIT(29), /* 43bit DMA addr limit */ - ---- a/drivers/ata/ahci_mvebu.c -+++ b/drivers/ata/ahci_mvebu.c -@@ -227,7 +227,7 @@ static const struct ahci_mvebu_plat_data - - static const struct ahci_mvebu_plat_data ahci_mvebu_armada_3700_plat_data = { - .plat_config = ahci_mvebu_armada_3700_config, -- .flags = AHCI_HFLAG_SUSPEND_PHYS | AHCI_HFLAG_IGN_NOTSUPP_POWER_ON, -+ .flags = AHCI_HFLAG_SUSPEND_PHYS, - }; - - static const struct of_device_id ahci_mvebu_of_match[] = { ---- a/drivers/ata/libahci_platform.c -+++ b/drivers/ata/libahci_platform.c -@@ -59,7 +59,7 @@ int ahci_platform_enable_phys(struct ahc - } - - rc = phy_power_on(hpriv->phys[i]); -- if (rc && !(rc == -EOPNOTSUPP && (hpriv->flags & AHCI_HFLAG_IGN_NOTSUPP_POWER_ON))) { -+ if (rc) { - phy_exit(hpriv->phys[i]); - goto disable_phys; - } diff --git a/target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch b/target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch deleted file mode 100644 index 0c28221460668e..00000000000000 --- a/target/linux/generic/backport-5.15/346-v5.18-02-Revert-usb-host-xhci-mvebu-make-USB-3.0-PHY-optional.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 8e10548f7f4814e530857d2049d6af6bc78add53 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Thu, 3 Feb 2022 22:44:43 +0100 -Subject: [PATCH 2/3] Revert "usb: host: xhci: mvebu: make USB 3.0 PHY optional - for Armada 3720" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit 3241929b67d28c83945d3191c6816a3271fd6b85. - -Armada 3720 phy driver (phy-mvebu-a3700-comphy.c) does not return --EOPNOTSUPP from phy_power_on() callback anymore. - -So remove XHCI_SKIP_PHY_INIT flag from xhci_mvebu_a3700_plat_setup() and -then also whole xhci_mvebu_a3700_plat_setup() function which is there just -to handle -EOPNOTSUPP for XHCI_SKIP_PHY_INIT. - -xhci plat_setup callback is not used by any other xhci plat driver, so -remove this callback completely. - -Signed-off-by: Pali Rohár -Signed-off-by: Marek Behún -Acked-by: Miquel Raynal -Acked-by: Greg Kroah-Hartman -Link: https://lore.kernel.org/r/20220203214444.1508-5-kabel@kernel.org -Signed-off-by: Vinod Koul ---- - drivers/usb/host/xhci-mvebu.c | 42 ----------------------------------- - drivers/usb/host/xhci-mvebu.h | 6 ----- - drivers/usb/host/xhci-plat.c | 20 +---------------- - drivers/usb/host/xhci-plat.h | 1 - - 4 files changed, 1 insertion(+), 68 deletions(-) - ---- a/drivers/usb/host/xhci-mvebu.c -+++ b/drivers/usb/host/xhci-mvebu.c -@@ -8,7 +8,6 @@ - #include - #include - #include --#include - - #include - #include -@@ -74,47 +73,6 @@ int xhci_mvebu_mbus_init_quirk(struct us - - return 0; - } -- --int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd) --{ -- struct xhci_hcd *xhci = hcd_to_xhci(hcd); -- struct device *dev = hcd->self.controller; -- struct phy *phy; -- int ret; -- -- /* Old bindings miss the PHY handle */ -- phy = of_phy_get(dev->of_node, "usb3-phy"); -- if (IS_ERR(phy) && PTR_ERR(phy) == -EPROBE_DEFER) -- return -EPROBE_DEFER; -- else if (IS_ERR(phy)) -- goto phy_out; -- -- ret = phy_init(phy); -- if (ret) -- goto phy_put; -- -- ret = phy_set_mode(phy, PHY_MODE_USB_HOST_SS); -- if (ret) -- goto phy_exit; -- -- ret = phy_power_on(phy); -- if (ret == -EOPNOTSUPP) { -- /* Skip initializatin of XHCI PHY when it is unsupported by firmware */ -- dev_warn(dev, "PHY unsupported by firmware\n"); -- xhci->quirks |= XHCI_SKIP_PHY_INIT; -- } -- if (ret) -- goto phy_exit; -- -- phy_power_off(phy); --phy_exit: -- phy_exit(phy); --phy_put: -- of_phy_put(phy); --phy_out: -- -- return 0; --} - - int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) - { ---- a/drivers/usb/host/xhci-mvebu.h -+++ b/drivers/usb/host/xhci-mvebu.h -@@ -12,18 +12,12 @@ struct usb_hcd; - - #if IS_ENABLED(CONFIG_USB_XHCI_MVEBU) - int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd); --int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd); - int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd); - #else - static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) - { - return 0; - } -- --static inline int xhci_mvebu_a3700_plat_setup(struct usb_hcd *hcd) --{ -- return 0; --} - - static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) - { ---- a/drivers/usb/host/xhci-plat.c -+++ b/drivers/usb/host/xhci-plat.c -@@ -44,16 +44,6 @@ static void xhci_priv_plat_start(struct - priv->plat_start(hcd); - } - --static int xhci_priv_plat_setup(struct usb_hcd *hcd) --{ -- struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); -- -- if (!priv->plat_setup) -- return 0; -- -- return priv->plat_setup(hcd); --} -- - static int xhci_priv_init_quirk(struct usb_hcd *hcd) - { - struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); -@@ -121,7 +111,6 @@ static const struct xhci_plat_priv xhci_ - }; - - static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = { -- .plat_setup = xhci_mvebu_a3700_plat_setup, - .init_quirk = xhci_mvebu_a3700_init_quirk, - }; - -@@ -344,14 +333,7 @@ static int xhci_plat_probe(struct platfo - - hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node); - xhci->shared_hcd->tpl_support = hcd->tpl_support; -- -- if (priv) { -- ret = xhci_priv_plat_setup(hcd); -- if (ret) -- goto disable_usb_phy; -- } -- -- if ((xhci->quirks & XHCI_SKIP_PHY_INIT) || (priv && (priv->quirks & XHCI_SKIP_PHY_INIT))) -+ if (priv && (priv->quirks & XHCI_SKIP_PHY_INIT)) - hcd->skip_phy_initialization = 1; - - if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK)) ---- a/drivers/usb/host/xhci-plat.h -+++ b/drivers/usb/host/xhci-plat.h -@@ -15,7 +15,6 @@ struct usb_hcd; - struct xhci_plat_priv { - const char *firmware_name; - unsigned long long quirks; -- int (*plat_setup)(struct usb_hcd *); - void (*plat_start)(struct usb_hcd *); - int (*init_quirk)(struct usb_hcd *); - int (*suspend_quirk)(struct usb_hcd *); diff --git a/target/linux/generic/backport-5.15/346-v5.18-03-Revert-PCI-aardvark-Fix-initialization-with-old-Marv.patch b/target/linux/generic/backport-5.15/346-v5.18-03-Revert-PCI-aardvark-Fix-initialization-with-old-Marv.patch deleted file mode 100644 index fcfb02d35a1f22..00000000000000 --- a/target/linux/generic/backport-5.15/346-v5.18-03-Revert-PCI-aardvark-Fix-initialization-with-old-Marv.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 9a4556dad7bd0a6b8339cb72e169f5c76f2af6f1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Thu, 3 Feb 2022 22:44:44 +0100 -Subject: [PATCH 3/3] Revert "PCI: aardvark: Fix initialization with old - Marvell's Arm Trusted Firmware" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit b0c6ae0f8948a2be6bf4e8b4bbab9ca1343289b6. - -Armada 3720 phy driver (phy-mvebu-a3700-comphy.c) does not return --EOPNOTSUPP from phy_power_on() callback anymore. - -So remove dead code which handles -EOPNOTSUPP return value. - -Signed-off-by: Pali Rohár -Signed-off-by: Marek Behún -Acked-by: Miquel Raynal -Acked-by: Lorenzo Pieralisi -Link: https://lore.kernel.org/r/20220203214444.1508-6-kabel@kernel.org -Signed-off-by: Vinod Koul ---- - drivers/pci/controller/pci-aardvark.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/pci/controller/pci-aardvark.c -+++ b/drivers/pci/controller/pci-aardvark.c -@@ -1642,9 +1642,7 @@ static int advk_pcie_enable_phy(struct a - } - - ret = phy_power_on(pcie->phy); -- if (ret == -EOPNOTSUPP) { -- dev_warn(&pcie->pdev->dev, "PHY unsupported by firmware\n"); -- } else if (ret) { -+ if (ret) { - phy_exit(pcie->phy); - return ret; - } diff --git a/target/linux/generic/backport-5.15/347-v6.0-phy-marvell-phy-mvebu-a3700-comphy-Remove-broken-res.patch b/target/linux/generic/backport-5.15/347-v6.0-phy-marvell-phy-mvebu-a3700-comphy-Remove-broken-res.patch deleted file mode 100644 index a2c897b7a9aada..00000000000000 --- a/target/linux/generic/backport-5.15/347-v6.0-phy-marvell-phy-mvebu-a3700-comphy-Remove-broken-res.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 0a6fc70d76bddf98278af2ac000379c82aec8f11 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Mon, 29 Aug 2022 10:30:46 +0200 -Subject: [PATCH] phy: marvell: phy-mvebu-a3700-comphy: Remove broken reset - support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Reset support for SATA PHY is somehow broken and after calling it, kernel -is not able to detect and initialize SATA disk Samsung SSD 850 EMT0 [1]. - -Reset support was introduced in commit 934337080c6c ("phy: marvell: -phy-mvebu-a3700-comphy: Add native kernel implementation") as part of -complete rewrite of this driver. v1 patch series of that commit [2] did -not contain reset support and was tested that is working fine with -Ethernet, SATA and USB PHYs without issues too. - -So for now remove broken reset support and change implementation of -power_off callback to power off all functions on specified lane (and not -only selected function) because during startup kernel does not know which -function was selected and configured by bootloader. Same logic was used -also in v1 patch series of that commit. - -This change fixes issues with initialization of SATA disk Samsung SSD 850 -and disk is working again, like before mentioned commit. - -Once problem with PHY reset callback is solved its functionality could be -re-introduced. But for now it is unknown why it does not work. - -[1] - https://lore.kernel.org/r/20220531124159.3e4lgn2v462irbtz@shindev/ -[2] - https://lore.kernel.org/r/20211028184242.22105-1-kabel@kernel.org/ - -Reported-by: Shinichiro Kawasaki -Fixes: 934337080c6c ("phy: marvell: phy-mvebu-a3700-comphy: Add native kernel implementation") -Cc: stable@vger.kernel.org # v5.18+ -Signed-off-by: Pali Rohár -Tested-by: Shinichiro Kawasaki -Link: https://lore.kernel.org/r/20220829083046.15082-1-pali@kernel.org -Signed-off-by: Vinod Koul ---- - drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 87 ++++---------------- - 1 file changed, 17 insertions(+), 70 deletions(-) - ---- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c -+++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c -@@ -274,7 +274,6 @@ struct mvebu_a3700_comphy_lane { - int submode; - bool invert_tx; - bool invert_rx; -- bool needs_reset; - }; - - struct gbe_phy_init_data_fix { -@@ -1097,40 +1096,12 @@ mvebu_a3700_comphy_pcie_power_off(struct - 0x0, PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT); - } - --static int mvebu_a3700_comphy_reset(struct phy *phy) -+static void mvebu_a3700_comphy_usb3_power_off(struct mvebu_a3700_comphy_lane *lane) - { -- struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); -- u16 mask, data; -- -- dev_dbg(lane->dev, "resetting lane %d\n", lane->id); -- -- /* COMPHY reset for internal logic */ -- comphy_lane_reg_set(lane, COMPHY_SFT_RESET, -- SFT_RST_NO_REG, SFT_RST_NO_REG); -- -- /* COMPHY register reset (cleared automatically) */ -- comphy_lane_reg_set(lane, COMPHY_SFT_RESET, SFT_RST, SFT_RST); -- -- /* PIPE soft and register reset */ -- data = PIPE_SOFT_RESET | PIPE_REG_RESET; -- mask = data; -- comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, data, mask); -- -- /* Release PIPE register reset */ -- comphy_lane_reg_set(lane, COMPHY_PIPE_RST_CLK_CTRL, -- 0x0, PIPE_REG_RESET); -- -- /* Reset SB configuration register (only for lanes 0 and 1) */ -- if (lane->id == 0 || lane->id == 1) { -- u32 mask, data; -- -- data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT | -- PIN_PU_PLL_BIT | PIN_PU_RX_BIT | PIN_PU_TX_BIT; -- mask = data | PIN_PU_IVREF_BIT | PIN_TX_IDLE_BIT; -- comphy_periph_reg_set(lane, COMPHY_PHY_CFG1, data, mask); -- } -- -- return 0; -+ /* -+ * The USB3 MAC sets the USB3 PHY to low state, so we do not -+ * need to power off USB3 PHY again. -+ */ - } - - static bool mvebu_a3700_comphy_check_mode(int lane, -@@ -1171,10 +1142,6 @@ static int mvebu_a3700_comphy_set_mode(s - (lane->mode != mode || lane->submode != submode)) - return -EBUSY; - -- /* If changing mode, ensure reset is called */ -- if (lane->mode != PHY_MODE_INVALID && lane->mode != mode) -- lane->needs_reset = true; -- - /* Just remember the mode, ->power_on() will do the real setup */ - lane->mode = mode; - lane->submode = submode; -@@ -1185,7 +1152,6 @@ static int mvebu_a3700_comphy_set_mode(s - static int mvebu_a3700_comphy_power_on(struct phy *phy) - { - struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); -- int ret; - - if (!mvebu_a3700_comphy_check_mode(lane->id, lane->mode, - lane->submode)) { -@@ -1193,14 +1159,6 @@ static int mvebu_a3700_comphy_power_on(s - return -EINVAL; - } - -- if (lane->needs_reset) { -- ret = mvebu_a3700_comphy_reset(phy); -- if (ret) -- return ret; -- -- lane->needs_reset = false; -- } -- - switch (lane->mode) { - case PHY_MODE_USB_HOST_SS: - dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id); -@@ -1224,38 +1182,28 @@ static int mvebu_a3700_comphy_power_off( - { - struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); - -- switch (lane->mode) { -- case PHY_MODE_USB_HOST_SS: -- /* -- * The USB3 MAC sets the USB3 PHY to low state, so we do not -- * need to power off USB3 PHY again. -- */ -- break; -- -- case PHY_MODE_SATA: -- mvebu_a3700_comphy_sata_power_off(lane); -- break; -- -- case PHY_MODE_ETHERNET: -+ switch (lane->id) { -+ case 0: -+ mvebu_a3700_comphy_usb3_power_off(lane); - mvebu_a3700_comphy_ethernet_power_off(lane); -- break; -- -- case PHY_MODE_PCIE: -+ return 0; -+ case 1: - mvebu_a3700_comphy_pcie_power_off(lane); -- break; -- -+ mvebu_a3700_comphy_ethernet_power_off(lane); -+ return 0; -+ case 2: -+ mvebu_a3700_comphy_usb3_power_off(lane); -+ mvebu_a3700_comphy_sata_power_off(lane); -+ return 0; - default: - dev_err(lane->dev, "invalid COMPHY mode\n"); - return -EINVAL; - } -- -- return 0; - } - - static const struct phy_ops mvebu_a3700_comphy_ops = { - .power_on = mvebu_a3700_comphy_power_on, - .power_off = mvebu_a3700_comphy_power_off, -- .reset = mvebu_a3700_comphy_reset, - .set_mode = mvebu_a3700_comphy_set_mode, - .owner = THIS_MODULE, - }; -@@ -1393,8 +1341,7 @@ static int mvebu_a3700_comphy_probe(stru - * To avoid relying on the bootloader/firmware configuration, - * power off all comphys. - */ -- mvebu_a3700_comphy_reset(phy); -- lane->needs_reset = false; -+ mvebu_a3700_comphy_power_off(phy); - } - - provider = devm_of_phy_provider_register(&pdev->dev, diff --git a/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch b/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch deleted file mode 100644 index 175df150cccdfd..00000000000000 --- a/target/linux/generic/backport-5.15/350-v5.18-regmap-add-configurable-downshift-for-addresses.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 86fc59ef818beb0e1945d17f8e734898baba7e4e Mon Sep 17 00:00:00 2001 -From: Colin Foster -Date: Sun, 13 Mar 2022 15:45:23 -0700 -Subject: [PATCH 1/2] regmap: add configurable downshift for addresses - -Add an additional reg_downshift to be applied to register addresses before -any register accesses. An example of a device that uses this is a VSC7514 -chip, which require each register address to be downshifted by two if the -access is performed over a SPI bus. - -Signed-off-by: Colin Foster -Link: https://lore.kernel.org/r/20220313224524.399947-2-colin.foster@in-advantage.com -Signed-off-by: Mark Brown ---- - drivers/base/regmap/internal.h | 1 + - drivers/base/regmap/regmap.c | 5 +++++ - include/linux/regmap.h | 3 +++ - 3 files changed, 9 insertions(+) - ---- a/drivers/base/regmap/internal.h -+++ b/drivers/base/regmap/internal.h -@@ -31,6 +31,7 @@ struct regmap_format { - size_t buf_size; - size_t reg_bytes; - size_t pad_bytes; -+ size_t reg_downshift; - size_t val_bytes; - void (*format_write)(struct regmap *map, - unsigned int reg, unsigned int val); ---- a/drivers/base/regmap/regmap.c -+++ b/drivers/base/regmap/regmap.c -@@ -823,6 +823,7 @@ struct regmap *__regmap_init(struct devi - - map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); - map->format.pad_bytes = config->pad_bits / 8; -+ map->format.reg_downshift = config->reg_downshift; - map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); - map->format.buf_size = DIV_ROUND_UP(config->reg_bits + - config->val_bits + config->pad_bits, 8); -@@ -1750,6 +1751,7 @@ static int _regmap_raw_write_impl(struct - return ret; - } - -+ reg >>= map->format.reg_downshift; - map->format.format_reg(map->work_buf, reg, map->reg_shift); - regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, - map->write_flag_mask); -@@ -1920,6 +1922,7 @@ static int _regmap_bus_formatted_write(v - return ret; - } - -+ reg >>= map->format.reg_downshift; - map->format.format_write(map, reg, val); - - trace_regmap_hw_write_start(map, reg, 1); -@@ -2360,6 +2363,7 @@ static int _regmap_raw_multi_reg_write(s - unsigned int reg = regs[i].reg; - unsigned int val = regs[i].def; - trace_regmap_hw_write_start(map, reg, 1); -+ reg >>= map->format.reg_downshift; - map->format.format_reg(u8, reg, map->reg_shift); - u8 += reg_bytes + pad_bytes; - map->format.format_val(u8, val, 0); -@@ -2685,6 +2689,7 @@ static int _regmap_raw_read(struct regma - return ret; - } - -+ reg >>= map->format.reg_downshift; - map->format.format_reg(map->work_buf, reg, map->reg_shift); - regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, - map->read_flag_mask); ---- a/include/linux/regmap.h -+++ b/include/linux/regmap.h -@@ -237,6 +237,8 @@ typedef void (*regmap_unlock)(void *); - * @reg_stride: The register address stride. Valid register addresses are a - * multiple of this value. If set to 0, a value of 1 will be - * used. -+ * @reg_downshift: The number of bits to downshift the register before -+ * performing any operations. - * @pad_bits: Number of bits of padding between register and value. - * @val_bits: Number of bits in a register value, mandatory. - * -@@ -366,6 +368,7 @@ struct regmap_config { - - int reg_bits; - int reg_stride; -+ int reg_downshift; - int pad_bits; - int val_bits; - diff --git a/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch b/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch deleted file mode 100644 index df716c4b651c26..00000000000000 --- a/target/linux/generic/backport-5.15/351-v5.18-regmap-allow-a-defined-reg_base-to-be-added-to-every.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0074f3f2b1e43d3cedd97e47fb6980db6d2ba79e Mon Sep 17 00:00:00 2001 -From: Colin Foster -Date: Sun, 13 Mar 2022 15:45:24 -0700 -Subject: [PATCH 2/2] regmap: allow a defined reg_base to be added to every - address - -There's an inconsistency that arises when a register set can be accessed -internally via MMIO, or externally via SPI. The VSC7514 chip allows both -modes of operation. When internally accessed, the system utilizes __iomem, -devm_ioremap_resource, and devm_regmap_init_mmio. - -For SPI it isn't possible to utilize memory-mapped IO. To properly operate, -the resource base must be added to the register before every operation. - -Signed-off-by: Colin Foster -Link: https://lore.kernel.org/r/20220313224524.399947-3-colin.foster@in-advantage.com -Signed-off-by: Mark Brown ---- - drivers/base/regmap/internal.h | 1 + - drivers/base/regmap/regmap.c | 6 ++++++ - include/linux/regmap.h | 3 +++ - 3 files changed, 10 insertions(+) - ---- a/drivers/base/regmap/internal.h -+++ b/drivers/base/regmap/internal.h -@@ -63,6 +63,7 @@ struct regmap { - regmap_unlock unlock; - void *lock_arg; /* This is passed to lock/unlock functions */ - gfp_t alloc_flags; -+ unsigned int reg_base; - - struct device *dev; /* Device we do I/O on */ - void *work_buf; /* Scratch buffer used to format I/O */ ---- a/drivers/base/regmap/regmap.c -+++ b/drivers/base/regmap/regmap.c -@@ -821,6 +821,8 @@ struct regmap *__regmap_init(struct devi - else - map->alloc_flags = GFP_KERNEL; - -+ map->reg_base = config->reg_base; -+ - map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); - map->format.pad_bytes = config->pad_bits / 8; - map->format.reg_downshift = config->reg_downshift; -@@ -1751,6 +1753,7 @@ static int _regmap_raw_write_impl(struct - return ret; - } - -+ reg += map->reg_base; - reg >>= map->format.reg_downshift; - map->format.format_reg(map->work_buf, reg, map->reg_shift); - regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, -@@ -1922,6 +1925,7 @@ static int _regmap_bus_formatted_write(v - return ret; - } - -+ reg += map->reg_base; - reg >>= map->format.reg_downshift; - map->format.format_write(map, reg, val); - -@@ -2363,6 +2367,7 @@ static int _regmap_raw_multi_reg_write(s - unsigned int reg = regs[i].reg; - unsigned int val = regs[i].def; - trace_regmap_hw_write_start(map, reg, 1); -+ reg += map->reg_base; - reg >>= map->format.reg_downshift; - map->format.format_reg(u8, reg, map->reg_shift); - u8 += reg_bytes + pad_bytes; -@@ -2689,6 +2694,7 @@ static int _regmap_raw_read(struct regma - return ret; - } - -+ reg += map->reg_base; - reg >>= map->format.reg_downshift; - map->format.format_reg(map->work_buf, reg, map->reg_shift); - regmap_set_work_buf_flag_mask(map, map->format.reg_bytes, ---- a/include/linux/regmap.h -+++ b/include/linux/regmap.h -@@ -239,6 +239,8 @@ typedef void (*regmap_unlock)(void *); - * used. - * @reg_downshift: The number of bits to downshift the register before - * performing any operations. -+ * @reg_base: Value to be added to every register address before performing any -+ * operation. - * @pad_bits: Number of bits of padding between register and value. - * @val_bits: Number of bits in a register value, mandatory. - * -@@ -369,6 +371,7 @@ struct regmap_config { - int reg_bits; - int reg_stride; - int reg_downshift; -+ unsigned int reg_base; - int pad_bits; - int val_bits; - diff --git a/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch b/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch deleted file mode 100644 index 33de94cb17b25e..00000000000000 --- a/target/linux/generic/backport-5.15/352-v6.3-regmap-apply-reg_base-and-reg_downshift-for-single-r.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 697c3892d825fb78f42ec8e53bed065dd728db3e Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 30 Jan 2023 02:04:57 +0000 -Subject: [PATCH] regmap: apply reg_base and reg_downshift for single register - ops - -reg_base and reg_downshift currently don't have any effect if used with -a regmap_bus or regmap_config which only offers single register -operations (ie. reg_read, reg_write and optionally reg_update_bits). - -Fix that and take them into account also for regmap_bus with only -reg_read and read_write operations by applying reg_base and -reg_downshift in _regmap_bus_reg_write, _regmap_bus_reg_read. - -Also apply reg_base and reg_downshift in _regmap_update_bits, but only -in case the operation is carried out with a reg_update_bits call -defined in either regmap_bus or regmap_config. - -Fixes: 0074f3f2b1e43d ("regmap: allow a defined reg_base to be added to every address") -Fixes: 86fc59ef818beb ("regmap: add configurable downshift for addresses") -Signed-off-by: Daniel Golle -Tested-by: Colin Foster -Link: https://lore.kernel.org/r/Y9clyVS3tQEHlUhA@makrotopia.org -Signed-off-by: Mark Brown ---- - drivers/base/regmap/regmap.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/base/regmap/regmap.c -+++ b/drivers/base/regmap/regmap.c -@@ -1943,6 +1943,8 @@ static int _regmap_bus_reg_write(void *c - { - struct regmap *map = context; - -+ reg += map->reg_base; -+ reg >>= map->format.reg_downshift; - return map->bus->reg_write(map->bus_context, reg, val); - } - -@@ -2715,6 +2717,8 @@ static int _regmap_bus_reg_read(void *co - { - struct regmap *map = context; - -+ reg += map->reg_base; -+ reg >>= map->format.reg_downshift; - return map->bus->reg_read(map->bus_context, reg, val); - } - -@@ -3084,6 +3088,8 @@ static int _regmap_update_bits(struct re - *change = false; - - if (regmap_volatile(map, reg) && map->reg_update_bits) { -+ reg += map->reg_base; -+ reg >>= map->format.reg_downshift; - ret = map->reg_update_bits(map->bus_context, reg, mask, val); - if (ret == 0 && change) - *change = true; diff --git a/target/linux/generic/backport-5.15/360-v6.1-powerpc-vdso-link-with-z-noexecstack.patch b/target/linux/generic/backport-5.15/360-v6.1-powerpc-vdso-link-with-z-noexecstack.patch deleted file mode 100644 index 82e712e20a53b2..00000000000000 --- a/target/linux/generic/backport-5.15/360-v6.1-powerpc-vdso-link-with-z-noexecstack.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 78391fb5b1b5318900725c72f1db25b2ae92894f Mon Sep 17 00:00:00 2001 -From: Christophe Leroy -Date: Wed, 7 Jun 2023 09:50:52 +0200 -Subject: [PATCH] powerpc/vdso: link with -z noexecstack - -With recent binutils, the following warning appears: - - VDSO32L arch/powerpc/kernel/vdso/vdso32.so.dbg -/opt/gcc-12.2.0-nolibc/powerpc64-linux/bin/../lib/gcc/powerpc64-linux/12.2.0/../../../../powerpc64-linux/bin/ld: warning: arch/powerpc/kernel/vdso/getcpu-32.o: missing .note.GNU-stack section implies executable stack -/opt/gcc-12.2.0-nolibc/powerpc64-linux/bin/../lib/gcc/powerpc64-linux/12.2.0/../../../../powerpc64-linux/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker - -To avoid that, explicitly tell the linker we don't want executable -stack. - -For more explanations, see commit ffcf9c5700e4 ("x86: link vdso -and boot with -z noexecstack --no-warn-rwx-segments") - -Commit was adapted for 5.15 as VDSO32 and VDSO64 were merged later so it -does not directly apply. - -Signed-off-by: Christophe Leroy -Signed-off-by: Michael Ellerman -Link: https://lore.kernel.org/r/b95f2e3216a574837dd61208444e9515c3423da4.1662132312.git.christophe.leroy@csgroup.eu -Signed-off-by: Robert Marko -[Adapt to 5.15 as it has VDSO split for 32 and 64bit] ---- - arch/powerpc/kernel/vdso32/Makefile | 2 +- - arch/powerpc/kernel/vdso64/Makefile | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/powerpc/kernel/vdso32/Makefile -+++ b/arch/powerpc/kernel/vdso32/Makefile -@@ -66,7 +66,7 @@ include/generated/vdso32-offsets.h: $(ob - - # actual build commands - quiet_cmd_vdso32ld_and_check = VDSO32L $@ -- cmd_vdso32ld_and_check = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) ; $(cmd_vdso_check) -+ cmd_vdso32ld_and_check = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) -z noexecstack ; $(cmd_vdso_check) - quiet_cmd_vdso32as = VDSO32A $@ - cmd_vdso32as = $(VDSOCC) $(a_flags) $(CC32FLAGS) -c -o $@ $< - quiet_cmd_vdso32cc = VDSO32C $@ ---- a/arch/powerpc/kernel/vdso64/Makefile -+++ b/arch/powerpc/kernel/vdso64/Makefile -@@ -53,4 +53,4 @@ include/generated/vdso64-offsets.h: $(ob - - # actual build commands - quiet_cmd_vdso64ld_and_check = VDSO64L $@ -- cmd_vdso64ld_and_check = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^); $(cmd_vdso_check) -+ cmd_vdso64ld_and_check = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) -z noexecstack ; $(cmd_vdso_check) diff --git a/target/linux/generic/backport-5.15/400-v5.19-mtd-call-of_platform_populate-for-MTD-partitions.patch b/target/linux/generic/backport-5.15/400-v5.19-mtd-call-of_platform_populate-for-MTD-partitions.patch deleted file mode 100644 index 1f3aae13b4d9f6..00000000000000 --- a/target/linux/generic/backport-5.15/400-v5.19-mtd-call-of_platform_populate-for-MTD-partitions.patch +++ /dev/null @@ -1,72 +0,0 @@ -From bcdf0315a61a29eb753a607d3a85a4032de72d94 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 10 May 2022 15:12:59 +0200 -Subject: [PATCH] mtd: call of_platform_populate() for MTD partitions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Until this change MTD subsystem supported handling partitions only with -MTD partitions parsers. That's a specific / limited API designed around -partitions. - -Some MTD partitions may however require different handling. They may -contain specific data that needs to be parsed and somehow extracted. For -that purpose MTD subsystem should allow binding of standard platform -drivers. - -An example can be U-Boot (sub)partition with environment variables. -There exist a "u-boot,env" DT binding for MTD (sub)partition that -requires an NVMEM driver. - -Ref: 5db1c2dbc04c ("dt-bindings: nvmem: add U-Boot environment variables binding") -Signed-off-by: Rafał Miłecki -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220510131259.555-1-zajec5@gmail.com ---- - drivers/mtd/mtdpart.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - #include "mtdcore.h" - -@@ -577,10 +578,16 @@ static int mtd_part_of_parse(struct mtd_ - struct mtd_part_parser *parser; - struct device_node *np; - struct property *prop; -+ struct device *dev; - const char *compat; - const char *fixed = "fixed-partitions"; - int ret, err = 0; - -+ dev = &master->dev; -+ /* Use parent device (controller) if the top level MTD is not registered */ -+ if (!IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) && !mtd_is_partition(master)) -+ dev = master->dev.parent; -+ - np = mtd_get_of_node(master); - if (mtd_is_partition(master)) - of_node_get(np); -@@ -593,6 +600,7 @@ static int mtd_part_of_parse(struct mtd_ - continue; - ret = mtd_part_do_parse(parser, master, pparts, NULL); - if (ret > 0) { -+ of_platform_populate(np, NULL, NULL, dev); - of_node_put(np); - return ret; - } -@@ -600,6 +608,7 @@ static int mtd_part_of_parse(struct mtd_ - if (ret < 0 && !err) - err = ret; - } -+ of_platform_populate(np, NULL, NULL, dev); - of_node_put(np); - - /* diff --git a/target/linux/generic/backport-5.15/401-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch b/target/linux/generic/backport-5.15/401-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch deleted file mode 100644 index 113a96ad42ea40..00000000000000 --- a/target/linux/generic/backport-5.15/401-v6.0-mtd-parsers-add-support-for-Sercomm-partitions.patch +++ /dev/null @@ -1,302 +0,0 @@ -From 9b78ef0c7997052e9eaa0f7a4513d546fa17358c Mon Sep 17 00:00:00 2001 -From: Mikhail Zhilkin -Date: Sun, 29 May 2022 11:07:14 +0000 -Subject: [PATCH] mtd: parsers: add support for Sercomm partitions - -This adds an MTD partition parser for the Sercomm partition table that -is used in some Beeline, Netgear and Sercomm routers. - -The Sercomm partition map table contains real partition offsets, which -may differ from device to device depending on the number and location of -bad blocks on NAND. - -Original patch (proposed by NOGUCHI Hiroshi): -Link: https://github.com/openwrt/openwrt/pull/1318#issuecomment-420607394 - -Signed-off-by: NOGUCHI Hiroshi -Signed-off-by: Mikhail Zhilkin -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220529110714.189732-1-csharper2005@gmail.com ---- - drivers/mtd/parsers/Kconfig | 9 ++ - drivers/mtd/parsers/Makefile | 1 + - drivers/mtd/parsers/scpart.c | 248 +++++++++++++++++++++++++++++++++++ - 3 files changed, 258 insertions(+) - create mode 100644 drivers/mtd/parsers/scpart.c - ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -186,3 +186,12 @@ config MTD_QCOMSMEM_PARTS - help - This provides support for parsing partitions from Shared Memory (SMEM) - for NAND and SPI flash on Qualcomm platforms. -+ -+config MTD_SERCOMM_PARTS -+ tristate "Sercomm partition table parser" -+ depends on MTD && RALINK -+ help -+ This provides partitions table parser for devices with Sercomm -+ partition map. This partition table contains real partition -+ offsets, which may differ from device to device depending on the -+ number and location of bad blocks on NAND. ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -10,6 +10,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS) - obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o - obj-$(CONFIG_MTD_AFS_PARTS) += afs.o - obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o -+obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o - obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o - obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o - obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o ---- /dev/null -+++ b/drivers/mtd/parsers/scpart.c -@@ -0,0 +1,248 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * drivers/mtd/scpart.c: Sercomm Partition Parser -+ * -+ * Copyright (C) 2018 NOGUCHI Hiroshi -+ * Copyright (C) 2022 Mikhail Zhilkin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define MOD_NAME "scpart" -+ -+#ifdef pr_fmt -+#undef pr_fmt -+#endif -+ -+#define pr_fmt(fmt) MOD_NAME ": " fmt -+ -+#define ID_ALREADY_FOUND 0xffffffffUL -+ -+#define MAP_OFFS_IN_BLK 0x800 -+#define MAP_MIRROR_NUM 2 -+ -+static const char sc_part_magic[] = { -+ 'S', 'C', 'F', 'L', 'M', 'A', 'P', 'O', 'K', '\0', -+}; -+#define PART_MAGIC_LEN sizeof(sc_part_magic) -+ -+/* assumes that all fields are set by CPU native endian */ -+struct sc_part_desc { -+ uint32_t part_id; -+ uint32_t part_offs; -+ uint32_t part_bytes; -+}; -+ -+static uint32_t scpart_desc_is_valid(struct sc_part_desc *pdesc) -+{ -+ return ((pdesc->part_id != 0xffffffffUL) && -+ (pdesc->part_offs != 0xffffffffUL) && -+ (pdesc->part_bytes != 0xffffffffUL)); -+} -+ -+static int scpart_scan_partmap(struct mtd_info *master, loff_t partmap_offs, -+ struct sc_part_desc **ppdesc) -+{ -+ int cnt = 0; -+ int res = 0; -+ int res2; -+ loff_t offs; -+ size_t retlen; -+ struct sc_part_desc *pdesc = NULL; -+ struct sc_part_desc *tmpdesc; -+ uint8_t *buf; -+ -+ buf = kzalloc(master->erasesize, GFP_KERNEL); -+ if (!buf) { -+ res = -ENOMEM; -+ goto out; -+ } -+ -+ res2 = mtd_read(master, partmap_offs, master->erasesize, &retlen, buf); -+ if (res2 || retlen != master->erasesize) { -+ res = -EIO; -+ goto free; -+ } -+ -+ for (offs = MAP_OFFS_IN_BLK; -+ offs < master->erasesize - sizeof(*tmpdesc); -+ offs += sizeof(*tmpdesc)) { -+ tmpdesc = (struct sc_part_desc *)&buf[offs]; -+ if (!scpart_desc_is_valid(tmpdesc)) -+ break; -+ cnt++; -+ } -+ -+ if (cnt > 0) { -+ int bytes = cnt * sizeof(*pdesc); -+ -+ pdesc = kcalloc(cnt, sizeof(*pdesc), GFP_KERNEL); -+ if (!pdesc) { -+ res = -ENOMEM; -+ goto free; -+ } -+ memcpy(pdesc, &(buf[MAP_OFFS_IN_BLK]), bytes); -+ -+ *ppdesc = pdesc; -+ res = cnt; -+ } -+ -+free: -+ kfree(buf); -+ -+out: -+ return res; -+} -+ -+static int scpart_find_partmap(struct mtd_info *master, -+ struct sc_part_desc **ppdesc) -+{ -+ int magic_found = 0; -+ int res = 0; -+ int res2; -+ loff_t offs = 0; -+ size_t retlen; -+ uint8_t rdbuf[PART_MAGIC_LEN]; -+ -+ while ((magic_found < MAP_MIRROR_NUM) && -+ (offs < master->size) && -+ !mtd_block_isbad(master, offs)) { -+ res2 = mtd_read(master, offs, PART_MAGIC_LEN, &retlen, rdbuf); -+ if (res2 || retlen != PART_MAGIC_LEN) { -+ res = -EIO; -+ goto out; -+ } -+ if (!memcmp(rdbuf, sc_part_magic, PART_MAGIC_LEN)) { -+ pr_debug("Signature found at 0x%llx\n", offs); -+ magic_found++; -+ res = scpart_scan_partmap(master, offs, ppdesc); -+ if (res > 0) -+ goto out; -+ } -+ offs += master->erasesize; -+ } -+ -+out: -+ if (res > 0) -+ pr_info("Valid 'SC PART MAP' (%d partitions) found at 0x%llx\n", res, offs); -+ else -+ pr_info("No valid 'SC PART MAP' was found\n"); -+ -+ return res; -+} -+ -+static int scpart_parse(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ const char *partname; -+ int n; -+ int nr_scparts; -+ int nr_parts = 0; -+ int res = 0; -+ struct sc_part_desc *scpart_map = NULL; -+ struct mtd_partition *parts = NULL; -+ struct device_node *mtd_node; -+ struct device_node *ofpart_node; -+ struct device_node *pp; -+ -+ mtd_node = mtd_get_of_node(master); -+ if (!mtd_node) { -+ res = -ENOENT; -+ goto out; -+ } -+ -+ ofpart_node = of_get_child_by_name(mtd_node, "partitions"); -+ if (!ofpart_node) { -+ pr_info("%s: 'partitions' subnode not found on %pOF.\n", -+ master->name, mtd_node); -+ res = -ENOENT; -+ goto out; -+ } -+ -+ nr_scparts = scpart_find_partmap(master, &scpart_map); -+ if (nr_scparts <= 0) { -+ pr_info("No any partitions was found in 'SC PART MAP'.\n"); -+ res = -ENOENT; -+ goto free; -+ } -+ -+ parts = kcalloc(of_get_child_count(ofpart_node), sizeof(*parts), -+ GFP_KERNEL); -+ if (!parts) { -+ res = -ENOMEM; -+ goto free; -+ } -+ -+ for_each_child_of_node(ofpart_node, pp) { -+ u32 scpart_id; -+ -+ if (of_property_read_u32(pp, "sercomm,scpart-id", &scpart_id)) -+ continue; -+ -+ for (n = 0 ; n < nr_scparts ; n++) -+ if ((scpart_map[n].part_id != ID_ALREADY_FOUND) && -+ (scpart_id == scpart_map[n].part_id)) -+ break; -+ if (n >= nr_scparts) -+ /* not match */ -+ continue; -+ -+ /* add the partition found in OF into MTD partition array */ -+ parts[nr_parts].offset = scpart_map[n].part_offs; -+ parts[nr_parts].size = scpart_map[n].part_bytes; -+ parts[nr_parts].of_node = pp; -+ -+ if (!of_property_read_string(pp, "label", &partname)) -+ parts[nr_parts].name = partname; -+ if (of_property_read_bool(pp, "read-only")) -+ parts[nr_parts].mask_flags |= MTD_WRITEABLE; -+ if (of_property_read_bool(pp, "lock")) -+ parts[nr_parts].mask_flags |= MTD_POWERUP_LOCK; -+ -+ /* mark as 'done' */ -+ scpart_map[n].part_id = ID_ALREADY_FOUND; -+ -+ nr_parts++; -+ } -+ -+ if (nr_parts > 0) { -+ *pparts = parts; -+ res = nr_parts; -+ } else -+ pr_info("No partition in OF matches partition ID with 'SC PART MAP'.\n"); -+ -+ of_node_put(pp); -+ -+free: -+ kfree(scpart_map); -+ if (res <= 0) -+ kfree(parts); -+ -+out: -+ return res; -+} -+ -+static const struct of_device_id scpart_parser_of_match_table[] = { -+ { .compatible = "sercomm,sc-partitions" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, scpart_parser_of_match_table); -+ -+static struct mtd_part_parser scpart_parser = { -+ .parse_fn = scpart_parse, -+ .name = "scpart", -+ .of_match_table = scpart_parser_of_match_table, -+}; -+module_mtd_part_parser(scpart_parser); -+ -+/* mtd parsers will request the module by parser name */ -+MODULE_ALIAS("scpart"); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("NOGUCHI Hiroshi "); -+MODULE_AUTHOR("Mikhail Zhilkin "); -+MODULE_DESCRIPTION("Sercomm partition parser"); diff --git a/target/linux/generic/backport-5.15/402-v6.0-mtd-next-mtd-core-introduce-of-support-for-dynamic-partitions.patch b/target/linux/generic/backport-5.15/402-v6.0-mtd-next-mtd-core-introduce-of-support-for-dynamic-partitions.patch deleted file mode 100644 index ee385416d1d0f4..00000000000000 --- a/target/linux/generic/backport-5.15/402-v6.0-mtd-next-mtd-core-introduce-of-support-for-dynamic-partitions.patch +++ /dev/null @@ -1,106 +0,0 @@ -From ad9b10d1eaada169bd764abcab58f08538877e26 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 22 Jun 2022 03:06:28 +0200 -Subject: mtd: core: introduce of support for dynamic partitions - -We have many parser that register mtd partitions at runtime. One example -is the cmdlinepart or the smem-part parser where the compatible is defined -in the dts and the partitions gets detected and registered by the -parser. This is problematic for the NVMEM subsystem that requires an OF -node to detect NVMEM cells. - -To fix this problem, introduce an additional logic that will try to -assign an OF node to the MTD if declared. - -On MTD addition, it will be checked if the MTD has an OF node and if -not declared will check if a partition with the same label / node name is -declared in DTS. If an exact match is found, the partition dynamically -allocated by the parser will have a connected OF node. - -The NVMEM subsystem will detect the OF node and register any NVMEM cells -declared statically in the DTS. - -Signed-off-by: Christian Marangi -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220622010628.30414-4-ansuelsmth@gmail.com ---- - drivers/mtd/mtdcore.c | 61 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 61 insertions(+) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -564,6 +564,66 @@ static int mtd_nvmem_add(struct mtd_info - return 0; - } - -+static void mtd_check_of_node(struct mtd_info *mtd) -+{ -+ struct device_node *partitions, *parent_dn, *mtd_dn = NULL; -+ const char *pname, *prefix = "partition-"; -+ int plen, mtd_name_len, offset, prefix_len; -+ struct mtd_info *parent; -+ bool found = false; -+ -+ /* Check if MTD already has a device node */ -+ if (dev_of_node(&mtd->dev)) -+ return; -+ -+ /* Check if a partitions node exist */ -+ parent = mtd->parent; -+ parent_dn = dev_of_node(&parent->dev); -+ if (!parent_dn) -+ return; -+ -+ partitions = of_get_child_by_name(parent_dn, "partitions"); -+ if (!partitions) -+ goto exit_parent; -+ -+ prefix_len = strlen(prefix); -+ mtd_name_len = strlen(mtd->name); -+ -+ /* Search if a partition is defined with the same name */ -+ for_each_child_of_node(partitions, mtd_dn) { -+ offset = 0; -+ -+ /* Skip partition with no/wrong prefix */ -+ if (!of_node_name_prefix(mtd_dn, "partition-")) -+ continue; -+ -+ /* Label have priority. Check that first */ -+ if (of_property_read_string(mtd_dn, "label", &pname)) { -+ of_property_read_string(mtd_dn, "name", &pname); -+ offset = prefix_len; -+ } -+ -+ plen = strlen(pname) - offset; -+ if (plen == mtd_name_len && -+ !strncmp(mtd->name, pname + offset, plen)) { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ goto exit_partitions; -+ -+ /* Set of_node only for nvmem */ -+ if (of_device_is_compatible(mtd_dn, "nvmem-cells")) -+ mtd_set_of_node(mtd, mtd_dn); -+ -+exit_partitions: -+ of_node_put(partitions); -+exit_parent: -+ of_node_put(parent_dn); -+} -+ - /** - * add_mtd_device - register an MTD device - * @mtd: pointer to new MTD device info structure -@@ -669,6 +729,7 @@ int add_mtd_device(struct mtd_info *mtd) - mtd->dev.devt = MTD_DEVT(i); - dev_set_name(&mtd->dev, "mtd%d", i); - dev_set_drvdata(&mtd->dev, mtd); -+ mtd_check_of_node(mtd); - of_node_get(mtd_get_of_node(mtd)); - error = device_register(&mtd->dev); - if (error) { diff --git a/target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch b/target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch deleted file mode 100644 index c8a7d282185406..00000000000000 --- a/target/linux/generic/backport-5.15/403-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch +++ /dev/null @@ -1,72 +0,0 @@ -From b0321721be50b80c03a51866a94fde4f94690e18 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 15 Jun 2022 21:42:59 +0200 -Subject: [PATCH] mtd: allow getting MTD device associated with a specific DT - node -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -MTD subsystem API allows interacting with MTD devices (e.g. reading, -writing, handling bad blocks). So far a random driver could get MTD -device only by its name (get_mtd_device_nm()). This change allows -getting them also by a DT node. - -This API is required for drivers handling DT defined MTD partitions in a -specific way (e.g. U-Boot (sub)partition with environment variables). - -Signed-off-by: Rafał Miłecki -Acked-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla ---- - drivers/mtd/mtdcore.c | 28 ++++++++++++++++++++++++++++ - include/linux/mtd/mtd.h | 1 + - 2 files changed, 29 insertions(+) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -1238,6 +1238,34 @@ int __get_mtd_device(struct mtd_info *mt - EXPORT_SYMBOL_GPL(__get_mtd_device); - - /** -+ * of_get_mtd_device_by_node - obtain an MTD device associated with a given node -+ * -+ * @np: device tree node -+ */ -+struct mtd_info *of_get_mtd_device_by_node(struct device_node *np) -+{ -+ struct mtd_info *mtd = NULL; -+ struct mtd_info *tmp; -+ int err; -+ -+ mutex_lock(&mtd_table_mutex); -+ -+ err = -EPROBE_DEFER; -+ mtd_for_each_device(tmp) { -+ if (mtd_get_of_node(tmp) == np) { -+ mtd = tmp; -+ err = __get_mtd_device(mtd); -+ break; -+ } -+ } -+ -+ mutex_unlock(&mtd_table_mutex); -+ -+ return err ? ERR_PTR(err) : mtd; -+} -+EXPORT_SYMBOL_GPL(of_get_mtd_device_by_node); -+ -+/** - * get_mtd_device_nm - obtain a validated handle for an MTD device by - * device name - * @name: MTD device name to open ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -682,6 +682,7 @@ extern int mtd_device_unregister(struct - extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); - extern int __get_mtd_device(struct mtd_info *mtd); - extern void __put_mtd_device(struct mtd_info *mtd); -+extern struct mtd_info *of_get_mtd_device_by_node(struct device_node *np); - extern struct mtd_info *get_mtd_device_nm(const char *name); - extern void put_mtd_device(struct mtd_info *mtd); - diff --git a/target/linux/generic/backport-5.15/404-v6.0-mtd-core-check-partition-before-dereference.patch b/target/linux/generic/backport-5.15/404-v6.0-mtd-core-check-partition-before-dereference.patch deleted file mode 100644 index e45e2ab48e394b..00000000000000 --- a/target/linux/generic/backport-5.15/404-v6.0-mtd-core-check-partition-before-dereference.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7ec4cdb321738d44ae5d405e7b6ac73dfbf99caa Mon Sep 17 00:00:00 2001 -From: Tetsuo Handa -Date: Mon, 25 Jul 2022 22:49:25 +0900 -Subject: [PATCH] mtd: core: check partition before dereference - -syzbot is reporting NULL pointer dereference at mtd_check_of_node() [1], -for mtdram test device (CONFIG_MTD_MTDRAM) is not partition. - -Link: https://syzkaller.appspot.com/bug?extid=fe013f55a2814a9e8cfd [1] -Reported-by: syzbot -Reported-by: kernel test robot -Fixes: ad9b10d1eaada169 ("mtd: core: introduce of support for dynamic partitions") -Signed-off-by: Tetsuo Handa -CC: stable@vger.kernel.org -Signed-off-by: Richard Weinberger ---- - drivers/mtd/mtdcore.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -577,6 +577,8 @@ static void mtd_check_of_node(struct mtd - return; - - /* Check if a partitions node exist */ -+ if (!mtd_is_partition(mtd)) -+ return; - parent = mtd->parent; - parent_dn = dev_of_node(&parent->dev); - if (!parent_dn) diff --git a/target/linux/generic/backport-5.15/405-v6.1-mtd-core-add-missing-of_node_get-in-dynamic-partitio.patch b/target/linux/generic/backport-5.15/405-v6.1-mtd-core-add-missing-of_node_get-in-dynamic-partitio.patch deleted file mode 100644 index 9399a00aa165cc..00000000000000 --- a/target/linux/generic/backport-5.15/405-v6.1-mtd-core-add-missing-of_node_get-in-dynamic-partitio.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 12b58961de0bd88b3c7dfa5d21f6d67f4678b780 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 18 Oct 2022 07:18:22 +0200 -Subject: [PATCH] mtd: core: add missing of_node_get() in dynamic partitions - code -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes unbalanced of_node_put(): -[ 1.078910] 6 cmdlinepart partitions found on MTD device gpmi-nand -[ 1.085116] Creating 6 MTD partitions on "gpmi-nand": -[ 1.090181] 0x000000000000-0x000008000000 : "nandboot" -[ 1.096952] 0x000008000000-0x000009000000 : "nandfit" -[ 1.103547] 0x000009000000-0x00000b000000 : "nandkernel" -[ 1.110317] 0x00000b000000-0x00000c000000 : "nanddtb" -[ 1.115525] ------------[ cut here ]------------ -[ 1.120141] refcount_t: addition on 0; use-after-free. -[ 1.125328] WARNING: CPU: 0 PID: 1 at lib/refcount.c:25 refcount_warn_saturate+0xdc/0x148 -[ 1.133528] Modules linked in: -[ 1.136589] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc7-next-20220930-04543-g8cf3f7 -[ 1.146342] Hardware name: Freescale i.MX8DXL DDR3L EVK (DT) -[ 1.151999] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) -[ 1.158965] pc : refcount_warn_saturate+0xdc/0x148 -[ 1.163760] lr : refcount_warn_saturate+0xdc/0x148 -[ 1.168556] sp : ffff800009ddb080 -[ 1.171866] x29: ffff800009ddb080 x28: ffff800009ddb35a x27: 0000000000000002 -[ 1.179015] x26: ffff8000098b06ad x25: ffffffffffffffff x24: ffff0a00ffffff05 -[ 1.186165] x23: ffff00001fdf6470 x22: ffff800009ddb367 x21: 0000000000000000 -[ 1.193314] x20: ffff00001fdfebe8 x19: ffff00001fdfec50 x18: ffffffffffffffff -[ 1.200464] x17: 0000000000000000 x16: 0000000000000118 x15: 0000000000000004 -[ 1.207614] x14: 0000000000000fff x13: ffff800009bca248 x12: 0000000000000003 -[ 1.214764] x11: 00000000ffffefff x10: c0000000ffffefff x9 : 4762cb2ccb52de00 -[ 1.221914] x8 : 4762cb2ccb52de00 x7 : 205d313431303231 x6 : 312e31202020205b -[ 1.229063] x5 : ffff800009d55c1f x4 : 0000000000000001 x3 : 0000000000000000 -[ 1.236213] x2 : 0000000000000000 x1 : ffff800009954be6 x0 : 000000000000002a -[ 1.243365] Call trace: -[ 1.245806] refcount_warn_saturate+0xdc/0x148 -[ 1.250253] kobject_get+0x98/0x9c -[ 1.253658] of_node_get+0x20/0x34 -[ 1.257072] of_fwnode_get+0x3c/0x54 -[ 1.260652] fwnode_get_nth_parent+0xd8/0xf4 -[ 1.264926] fwnode_full_name_string+0x3c/0xb4 -[ 1.269373] device_node_string+0x498/0x5b4 -[ 1.273561] pointer+0x41c/0x5d0 -[ 1.276793] vsnprintf+0x4d8/0x694 -[ 1.280198] vprintk_store+0x164/0x528 -[ 1.283951] vprintk_emit+0x98/0x164 -[ 1.287530] vprintk_default+0x44/0x6c -[ 1.291284] vprintk+0xf0/0x134 -[ 1.294428] _printk+0x54/0x7c -[ 1.297486] of_node_release+0xe8/0x128 -[ 1.301326] kobject_put+0x98/0xfc -[ 1.304732] of_node_put+0x1c/0x28 -[ 1.308137] add_mtd_device+0x484/0x6d4 -[ 1.311977] add_mtd_partitions+0xf0/0x1d0 -[ 1.316078] parse_mtd_partitions+0x45c/0x518 -[ 1.320439] mtd_device_parse_register+0xb0/0x274 -[ 1.325147] gpmi_nand_probe+0x51c/0x650 -[ 1.329074] platform_probe+0xa8/0xd0 -[ 1.332740] really_probe+0x130/0x334 -[ 1.336406] __driver_probe_device+0xb4/0xe0 -[ 1.340681] driver_probe_device+0x3c/0x1f8 -[ 1.344869] __driver_attach+0xdc/0x1a4 -[ 1.348708] bus_for_each_dev+0x80/0xcc -[ 1.352548] driver_attach+0x24/0x30 -[ 1.356127] bus_add_driver+0x108/0x1f4 -[ 1.359967] driver_register+0x78/0x114 -[ 1.363807] __platform_driver_register+0x24/0x30 -[ 1.368515] gpmi_nand_driver_init+0x1c/0x28 -[ 1.372798] do_one_initcall+0xbc/0x238 -[ 1.376638] do_initcall_level+0x94/0xb4 -[ 1.380565] do_initcalls+0x54/0x94 -[ 1.384058] do_basic_setup+0x1c/0x28 -[ 1.387724] kernel_init_freeable+0x110/0x188 -[ 1.392084] kernel_init+0x20/0x1a0 -[ 1.395578] ret_from_fork+0x10/0x20 -[ 1.399157] ---[ end trace 0000000000000000 ]--- -[ 1.403782] ------------[ cut here ]------------ - -Reported-by: Han Xu -Fixes: ad9b10d1eaada169 ("mtd: core: introduce of support for dynamic partitions") -Signed-off-by: Rafał Miłecki -Tested-by: Han Xu -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221018051822.28685-1-zajec5@gmail.com ---- - drivers/mtd/mtdcore.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -580,7 +580,7 @@ static void mtd_check_of_node(struct mtd - if (!mtd_is_partition(mtd)) - return; - parent = mtd->parent; -- parent_dn = dev_of_node(&parent->dev); -+ parent_dn = of_node_get(dev_of_node(&parent->dev)); - if (!parent_dn) - return; - diff --git a/target/linux/generic/backport-5.15/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch b/target/linux/generic/backport-5.15/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch deleted file mode 100644 index 7e9645ea98d6a9..00000000000000 --- a/target/linux/generic/backport-5.15/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 63db0cb35e1cb3b3c134906d1062f65513fdda2d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 4 Oct 2022 10:37:09 +0200 -Subject: [PATCH] mtd: core: simplify (a bit) code find partition-matching - dynamic OF node -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -1. Don't hardcode "partition-" string twice -2. Use simpler logic & use ->name to avoid of_property_read_string() -3. Use mtd_get_of_node() helper - -Cc: Christian Marangi -Signed-off-by: Rafał Miłecki -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-1-zajec5@gmail.com ---- - drivers/mtd/mtdcore.c | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -569,18 +569,16 @@ static void mtd_check_of_node(struct mtd - struct device_node *partitions, *parent_dn, *mtd_dn = NULL; - const char *pname, *prefix = "partition-"; - int plen, mtd_name_len, offset, prefix_len; -- struct mtd_info *parent; - bool found = false; - - /* Check if MTD already has a device node */ -- if (dev_of_node(&mtd->dev)) -+ if (mtd_get_of_node(mtd)) - return; - - /* Check if a partitions node exist */ - if (!mtd_is_partition(mtd)) - return; -- parent = mtd->parent; -- parent_dn = of_node_get(dev_of_node(&parent->dev)); -+ parent_dn = of_node_get(mtd_get_of_node(mtd->parent)); - if (!parent_dn) - return; - -@@ -593,15 +591,15 @@ static void mtd_check_of_node(struct mtd - - /* Search if a partition is defined with the same name */ - for_each_child_of_node(partitions, mtd_dn) { -- offset = 0; -- - /* Skip partition with no/wrong prefix */ -- if (!of_node_name_prefix(mtd_dn, "partition-")) -+ if (!of_node_name_prefix(mtd_dn, prefix)) - continue; - - /* Label have priority. Check that first */ -- if (of_property_read_string(mtd_dn, "label", &pname)) { -- of_property_read_string(mtd_dn, "name", &pname); -+ if (!of_property_read_string(mtd_dn, "label", &pname)) { -+ offset = 0; -+ } else { -+ pname = mtd_dn->name; - offset = prefix_len; - } - diff --git a/target/linux/generic/backport-5.15/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch b/target/linux/generic/backport-5.15/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch deleted file mode 100644 index 48a7c13cd013a3..00000000000000 --- a/target/linux/generic/backport-5.15/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch +++ /dev/null @@ -1,84 +0,0 @@ -From ddb8cefb7af288950447ca6eeeafb09977dab56f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 4 Oct 2022 10:37:10 +0200 -Subject: [PATCH] mtd: core: try to find OF node for every MTD partition -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -So far this feature was limited to the top-level "nvmem-cells" node. -There are multiple parsers creating partitions and subpartitions -dynamically. Extend that code to handle them too. - -This allows finding partition-* node for every MTD (sub)partition. - -Random example: - -partitions { - compatible = "brcm,bcm947xx-cfe-partitions"; - - partition-firmware { - compatible = "brcm,trx"; - - partition-loader { - }; - }; -}; - -Cc: Christian Marangi -Signed-off-by: Rafał Miłecki -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-2-zajec5@gmail.com ---- - drivers/mtd/mtdcore.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -569,20 +569,22 @@ static void mtd_check_of_node(struct mtd - struct device_node *partitions, *parent_dn, *mtd_dn = NULL; - const char *pname, *prefix = "partition-"; - int plen, mtd_name_len, offset, prefix_len; -- bool found = false; - - /* Check if MTD already has a device node */ - if (mtd_get_of_node(mtd)) - return; - -- /* Check if a partitions node exist */ - if (!mtd_is_partition(mtd)) - return; -+ - parent_dn = of_node_get(mtd_get_of_node(mtd->parent)); - if (!parent_dn) - return; - -- partitions = of_get_child_by_name(parent_dn, "partitions"); -+ if (mtd_is_partition(mtd->parent)) -+ partitions = of_node_get(parent_dn); -+ else -+ partitions = of_get_child_by_name(parent_dn, "partitions"); - if (!partitions) - goto exit_parent; - -@@ -606,19 +608,11 @@ static void mtd_check_of_node(struct mtd - plen = strlen(pname) - offset; - if (plen == mtd_name_len && - !strncmp(mtd->name, pname + offset, plen)) { -- found = true; -+ mtd_set_of_node(mtd, mtd_dn); - break; - } - } - -- if (!found) -- goto exit_partitions; -- -- /* Set of_node only for nvmem */ -- if (of_device_is_compatible(mtd_dn, "nvmem-cells")) -- mtd_set_of_node(mtd, mtd_dn); -- --exit_partitions: - of_node_put(partitions); - exit_parent: - of_node_put(parent_dn); diff --git a/target/linux/generic/backport-5.15/407-v5.17-mtd-parsers-qcom-Don-t-print-error-message-on-EPROBE.patch b/target/linux/generic/backport-5.15/407-v5.17-mtd-parsers-qcom-Don-t-print-error-message-on-EPROBE.patch deleted file mode 100644 index 0efad99157a621..00000000000000 --- a/target/linux/generic/backport-5.15/407-v5.17-mtd-parsers-qcom-Don-t-print-error-message-on-EPROBE.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 26bccc9671ba5e01f7153addbe94e7dc3f677375 Mon Sep 17 00:00:00 2001 -From: Bryan O'Donoghue -Date: Mon, 3 Jan 2022 03:03:16 +0000 -Subject: [PATCH 13/14] mtd: parsers: qcom: Don't print error message on - -EPROBE_DEFER - -Its possible for the main smem driver to not be loaded by the time we come -along to parse the smem partition description but, this is a perfectly -normal thing. - -No need to print out an error message in this case. - -Signed-off-by: Bryan O'Donoghue -Reviewed-by: Manivannan Sadhasivam -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220103030316.58301-3-bryan.odonoghue@linaro.org ---- - drivers/mtd/parsers/qcomsmempart.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/parsers/qcomsmempart.c -+++ b/drivers/mtd/parsers/qcomsmempart.c -@@ -75,7 +75,8 @@ static int parse_qcomsmem_part(struct mt - pr_debug("Parsing partition table info from SMEM\n"); - ptable = qcom_smem_get(SMEM_APPS, SMEM_AARM_PARTITION_TABLE, &len); - if (IS_ERR(ptable)) { -- pr_err("Error reading partition table header\n"); -+ if (PTR_ERR(ptable) != -EPROBE_DEFER) -+ pr_err("Error reading partition table header\n"); - return PTR_ERR(ptable); - } - diff --git a/target/linux/generic/backport-5.15/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch b/target/linux/generic/backport-5.15/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch deleted file mode 100644 index 505e347e40ebcb..00000000000000 --- a/target/linux/generic/backport-5.15/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 26422ac78e9d8767bd4aabfbae616b15edbf6a1b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 22 Oct 2022 23:13:18 +0200 -Subject: [PATCH] mtd: core: set ROOT_DEV for partitions marked as rootfs in DT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This adds support for "linux,rootfs" binding that is used to mark flash -partition containing rootfs. It's useful for devices using device tree -that don't have bootloader passing root info in cmdline. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221022211318.32009-2-zajec5@gmail.com ---- - drivers/mtd/mtdcore.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -748,6 +749,17 @@ int add_mtd_device(struct mtd_info *mtd) - not->add(mtd); - - mutex_unlock(&mtd_table_mutex); -+ -+ if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) { -+ if (IS_BUILTIN(CONFIG_MTD)) { -+ pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name); -+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); -+ } else { -+ pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n", -+ mtd->index, mtd->name); -+ } -+ } -+ - /* We _know_ we aren't being removed, because - our caller is still holding us here. So none - of this try_ nonsense, and no bitching about it diff --git a/target/linux/generic/backport-5.15/409-v6.3-mtd-mtdpart-Don-t-create-platform-device-that-ll-nev.patch b/target/linux/generic/backport-5.15/409-v6.3-mtd-mtdpart-Don-t-create-platform-device-that-ll-nev.patch deleted file mode 100644 index ba14ae01785a7b..00000000000000 --- a/target/linux/generic/backport-5.15/409-v6.3-mtd-mtdpart-Don-t-create-platform-device-that-ll-nev.patch +++ /dev/null @@ -1,54 +0,0 @@ -From fb42378dcc7f247df56f0ecddfdae85487495fbc Mon Sep 17 00:00:00 2001 -From: Saravana Kannan -Date: Mon, 6 Feb 2023 17:42:04 -0800 -Subject: [PATCH] mtd: mtdpart: Don't create platform device that'll never - probe - -These "nvmem-cells" platform devices never get probed because there's no -platform driver for it and it's never used anywhere else. So it's a -waste of memory. These devices also cause fw_devlink to block nvmem -consumers of "nvmem-cells" partition from probing because the supplier -device never probes. - -So stop creating platform devices for nvmem-cells partitions to avoid -wasting memory and to avoid blocking probing of consumers. - -Reported-by: Maxim Kiselev -Fixes: bcdf0315a61a ("mtd: call of_platform_populate() for MTD partitions") -Signed-off-by: Saravana Kannan -Tested-by: Maksim Kiselev -Tested-by: Douglas Anderson -Tested-by: Geert Uytterhoeven -Tested-by: Luca Weiss # qcom/sm7225-fairphone-fp4 -Link: https://lore.kernel.org/r/20230207014207.1678715-13-saravanak@google.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/mtd/mtdpart.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -577,6 +577,7 @@ static int mtd_part_of_parse(struct mtd_ - { - struct mtd_part_parser *parser; - struct device_node *np; -+ struct device_node *child; - struct property *prop; - struct device *dev; - const char *compat; -@@ -594,6 +595,15 @@ static int mtd_part_of_parse(struct mtd_ - else - np = of_get_child_by_name(np, "partitions"); - -+ /* -+ * Don't create devices that are added to a bus but will never get -+ * probed. That'll cause fw_devlink to block probing of consumers of -+ * this partition until the partition device is probed. -+ */ -+ for_each_child_of_node(np, child) -+ if (of_device_is_compatible(child, "nvmem-cells")) -+ of_node_set_flag(child, OF_POPULATED); -+ - of_property_for_each_string(np, "compatible", prop, compat) { - parser = mtd_part_get_compatible_parser(compat); - if (!parser) diff --git a/target/linux/generic/backport-5.15/410-v5.18-mtd-parsers-trx-allow-to-use-on-MediaTek-MIPS-SoCs.patch b/target/linux/generic/backport-5.15/410-v5.18-mtd-parsers-trx-allow-to-use-on-MediaTek-MIPS-SoCs.patch deleted file mode 100644 index 5c49841760f16f..00000000000000 --- a/target/linux/generic/backport-5.15/410-v5.18-mtd-parsers-trx-allow-to-use-on-MediaTek-MIPS-SoCs.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 2365f91c861cbfeef7141c69842848c7b2d3c2db Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Sun, 13 Feb 2022 15:40:44 +0900 -Subject: [PATCH] mtd: parsers: trx: allow to use on MediaTek MIPS SoCs - -Buffalo sells some router devices which have trx-formatted firmware, -based on MediaTek MIPS SoCs. To use parser_trx on those devices, add -"RALINK" to dependency and allow to compile for MediaTek MIPS SoCs. - -examples: - -- WCR-1166DS (MT7628) -- WSR-1166DHP (MT7621) -- WSR-2533DHP (MT7621) - -Signed-off-by: INAGAKI Hiroshi -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220213064045.1781-1-musashino.open@gmail.com ---- - drivers/mtd/parsers/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -115,7 +115,7 @@ config MTD_AFS_PARTS - - config MTD_PARSER_TRX - tristate "Parser for TRX format partitions" -- depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || COMPILE_TEST) -+ depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST) - help - TRX is a firmware format used by Broadcom on their devices. It - may contain up to 3/4 partitions (depending on the version). diff --git a/target/linux/generic/backport-5.15/411-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch b/target/linux/generic/backport-5.15/411-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch deleted file mode 100644 index dce2c91fd37d0f..00000000000000 --- a/target/linux/generic/backport-5.15/411-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 8e7daa85641c9559c113f6b217bdc923397de77c Mon Sep 17 00:00:00 2001 -From: William Zhang -Date: Thu, 22 Feb 2024 19:47:58 -0800 -Subject: [PATCH] mtd: rawnand: brcmnand: Support write protection setting from - dts - -The write protection feature is controlled by the module parameter wp_on -with default set to enabled. But not all the board use this feature -especially in BCMBCA broadband board. And module parameter is not -sufficient as different board can have different option. Add a device -tree property and allow this feature to be configured through the board -dts on per board basis. - -Signed-off-by: William Zhang -Reviewed-by: Florian Fainelli -Reviewed-by: Kamal Dasu -Reviewed-by: David Regan -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20240223034758.13753-14-william.zhang@broadcom.com ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -3184,6 +3184,10 @@ int brcmnand_probe(struct platform_devic - /* Disable XOR addressing */ - brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0); - -+ /* Check if the board connects the WP pin */ -+ if (of_property_read_bool(dn, "brcm,wp-not-connected")) -+ wp_on = 0; -+ - if (ctrl->features & BRCMNAND_HAS_WP) { - /* Permanently disable write protection */ - if (wp_on == 2) diff --git a/target/linux/generic/backport-5.15/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch b/target/linux/generic/backport-5.15/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch deleted file mode 100644 index 153191529c19a4..00000000000000 --- a/target/linux/generic/backport-5.15/412-v6.3-01-spidev-Add-Silicon-Labs-EM3581-device-compatible.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c67d90e058550403a3e6f9b05bfcdcfa12b1815c Mon Sep 17 00:00:00 2001 -From: Vincent Tremblay -Date: Mon, 26 Dec 2022 21:35:48 -0500 -Subject: [PATCH] spidev: Add Silicon Labs EM3581 device compatible - -Add compatible string for Silicon Labs EM3581 device. - -Signed-off-by: Vincent Tremblay -Link: https://lore.kernel.org/r/20221227023550.569547-2-vincent@vtremblay.dev -Signed-off-by: Mark Brown ---- - drivers/spi/spidev.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/spi/spidev.c -+++ b/drivers/spi/spidev.c -@@ -691,6 +691,7 @@ static const struct spi_device_id spidev - { .name = "m53cpld" }, - { .name = "spi-petra" }, - { .name = "spi-authenta" }, -+ { .name = "em3581" }, - {}, - }; - MODULE_DEVICE_TABLE(spi, spidev_spi_ids); -@@ -705,6 +706,7 @@ static const struct of_device_id spidev_ - { .compatible = "menlo,m53cpld" }, - { .compatible = "cisco,spi-petra" }, - { .compatible = "micron,spi-authenta" }, -+ { .compatible = "silabs,em3581" }, - {}, - }; - MODULE_DEVICE_TABLE(of, spidev_dt_ids); diff --git a/target/linux/generic/backport-5.15/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch b/target/linux/generic/backport-5.15/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch deleted file mode 100644 index ef36c82a6c6160..00000000000000 --- a/target/linux/generic/backport-5.15/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 6c9d1fd52956c3148e847a214bae9102b1811de5 Mon Sep 17 00:00:00 2001 -From: Vincent Tremblay -Date: Tue, 27 Dec 2022 09:10:08 -0500 -Subject: [PATCH] spidev: Add Silicon Labs SI3210 device compatible - -Add compatible string for Silicon Labs SI3210 device. - -Signed-off-by: Vincent Tremblay -Link: https://lore.kernel.org/r/20221227141011.111410-2-vincent@vtremblay.dev -Signed-off-by: Mark Brown ---- - drivers/spi/spidev.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/spi/spidev.c -+++ b/drivers/spi/spidev.c -@@ -692,6 +692,7 @@ static const struct spi_device_id spidev - { .name = "spi-petra" }, - { .name = "spi-authenta" }, - { .name = "em3581" }, -+ { .name = "si3210" }, - {}, - }; - MODULE_DEVICE_TABLE(spi, spidev_spi_ids); -@@ -707,6 +708,7 @@ static const struct of_device_id spidev_ - { .compatible = "cisco,spi-petra" }, - { .compatible = "micron,spi-authenta" }, - { .compatible = "silabs,em3581" }, -+ { .compatible = "silabs,si3210" }, - {}, - }; - MODULE_DEVICE_TABLE(of, spidev_dt_ids); diff --git a/target/linux/generic/backport-5.15/420-v5.19-02-mtd-spinand-gigadevice-add-support-for-GD5FxGQ4xExxG.patch b/target/linux/generic/backport-5.15/420-v5.19-02-mtd-spinand-gigadevice-add-support-for-GD5FxGQ4xExxG.patch deleted file mode 100644 index 94863b891c6c26..00000000000000 --- a/target/linux/generic/backport-5.15/420-v5.19-02-mtd-spinand-gigadevice-add-support-for-GD5FxGQ4xExxG.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 573eec222bc82fb5e724586267fbbb1aed9ffd03 Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo -Date: Sun, 20 Mar 2022 17:59:58 +0800 -Subject: [PATCH 2/5] mtd: spinand: gigadevice: add support for GD5FxGQ4xExxG - -Add support for: - GD5F1GQ4RExxG - GD5F2GQ4{U,R}ExxG - -These chips differ from GD5F1GQ4UExxG only in chip ID, voltage -and capacity. - -Signed-off-by: Chuanhong Guo -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220320100001.247905-3-gch981213@gmail.com ---- - drivers/mtd/nand/spi/gigadevice.c | 30 ++++++++++++++++++++++++++++++ - 1 file changed, 30 insertions(+) - ---- a/drivers/mtd/nand/spi/gigadevice.c -+++ b/drivers/mtd/nand/spi/gigadevice.c -@@ -335,6 +335,36 @@ static const struct spinand_info gigadev - SPINAND_HAS_QE_BIT, - SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, - gd5fxgq4uexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F1GQ4RExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1), -+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq4uexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F2GQ4UExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2), -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq4uexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F2GQ4RExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2), -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq4uexxg_ecc_get_status)), - SPINAND_INFO("GD5F1GQ4UFxxG", - SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48), - NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), diff --git a/target/linux/generic/backport-5.15/420-v5.19-03-mtd-spinand-gigadevice-add-support-for-GD5F1GQ5RExxG.patch b/target/linux/generic/backport-5.15/420-v5.19-03-mtd-spinand-gigadevice-add-support-for-GD5F1GQ5RExxG.patch deleted file mode 100644 index 287a062aaca8cc..00000000000000 --- a/target/linux/generic/backport-5.15/420-v5.19-03-mtd-spinand-gigadevice-add-support-for-GD5F1GQ5RExxG.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 620a988813403318023296b61228ee8f3fcdb8e0 Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo -Date: Sun, 20 Mar 2022 17:59:59 +0800 -Subject: [PATCH 3/5] mtd: spinand: gigadevice: add support for GD5F1GQ5RExxG - -This chip is the 1.8v version of GD5F1GQ5UExxG. - -Signed-off-by: Chuanhong Guo -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220320100001.247905-4-gch981213@gmail.com ---- - drivers/mtd/nand/spi/gigadevice.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/mtd/nand/spi/gigadevice.c -+++ b/drivers/mtd/nand/spi/gigadevice.c -@@ -385,6 +385,16 @@ static const struct spinand_info gigadev - SPINAND_HAS_QE_BIT, - SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, - gd5fxgq5xexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F1GQ5RExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41), -+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(4, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq5xexxg_ecc_get_status)), - }; - - static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = { diff --git a/target/linux/generic/backport-5.15/420-v5.19-04-mtd-spinand-gigadevice-add-support-for-GD5F-2-4-GQ5x.patch b/target/linux/generic/backport-5.15/420-v5.19-04-mtd-spinand-gigadevice-add-support-for-GD5F-2-4-GQ5x.patch deleted file mode 100644 index b1cf47678e014a..00000000000000 --- a/target/linux/generic/backport-5.15/420-v5.19-04-mtd-spinand-gigadevice-add-support-for-GD5F-2-4-GQ5x.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 194ec04b3a9e7fa97d1fbef296410631bc3cf1c8 Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo -Date: Sun, 20 Mar 2022 18:00:00 +0800 -Subject: [PATCH 4/5] mtd: spinand: gigadevice: add support for GD5F{2, - 4}GQ5xExxG - -Add support for: - GD5F2GQ5{U,R}ExxG - GD5F4GQ6{U,R}ExxG - -These chips uses 4 dummy bytes for quad io and 2 dummy bytes for dual io. -Besides that and memory layout, they are identical to their 1G variant. - -Signed-off-by: Chuanhong Guo -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220320100001.247905-5-gch981213@gmail.com ---- - drivers/mtd/nand/spi/gigadevice.c | 48 +++++++++++++++++++++++++++++++ - 1 file changed, 48 insertions(+) - ---- a/drivers/mtd/nand/spi/gigadevice.c -+++ b/drivers/mtd/nand/spi/gigadevice.c -@@ -47,6 +47,14 @@ static SPINAND_OP_VARIANTS(read_cache_va - SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), - SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); - -+static SPINAND_OP_VARIANTS(read_cache_variants_2gq5, -+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); -+ - static SPINAND_OP_VARIANTS(write_cache_variants, - SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), - SPINAND_PROG_LOAD(true, 0, NULL, 0)); -@@ -393,6 +401,46 @@ static const struct spinand_info gigadev - &write_cache_variants, - &update_cache_variants), - SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq5xexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F2GQ5UExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52), -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(4, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq5xexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F2GQ5RExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42), -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(4, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq5xexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F4GQ6UExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55), -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1), -+ NAND_ECCREQ(4, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq5xexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F4GQ6RExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45), -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1), -+ NAND_ECCREQ(4, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, - SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, - gd5fxgq5xexxg_ecc_get_status)), - }; diff --git a/target/linux/generic/backport-5.15/420-v5.19-05-mtd-spinand-gigadevice-add-support-for-GD5FxGM7xExxG.patch b/target/linux/generic/backport-5.15/420-v5.19-05-mtd-spinand-gigadevice-add-support-for-GD5FxGM7xExxG.patch deleted file mode 100644 index 5e342a29fbf51d..00000000000000 --- a/target/linux/generic/backport-5.15/420-v5.19-05-mtd-spinand-gigadevice-add-support-for-GD5FxGM7xExxG.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 54647cd003c08b714474a5b599a147ec6a160486 Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo -Date: Sun, 20 Mar 2022 18:00:01 +0800 -Subject: [PATCH 5/5] mtd: spinand: gigadevice: add support for GD5FxGM7xExxG - -Add support for: - GD5F{1,2}GM7{U,R}ExxG - GD5F4GM8{U,R}ExxG - -These are new 27nm counterparts for the GD5FxGQ4 chips from GigaDevice -with 8b/512b on-die ECC capability. -These chips (and currently supported GD5FxGQ5 chips) have QIO DTR -instruction for reading page cache. It isn't added in this patch because -I don't have a DTR spi controller for testing. - -Signed-off-by: Chuanhong Guo -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220320100001.247905-6-gch981213@gmail.com ---- - drivers/mtd/nand/spi/gigadevice.c | 60 +++++++++++++++++++++++++++++++ - 1 file changed, 60 insertions(+) - ---- a/drivers/mtd/nand/spi/gigadevice.c -+++ b/drivers/mtd/nand/spi/gigadevice.c -@@ -443,6 +443,66 @@ static const struct spinand_info gigadev - SPINAND_HAS_QE_BIT, - SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, - gd5fxgq5xexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F1GM7UExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91), -+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq4uexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F1GM7RExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81), -+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq4uexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F2GM7UExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92), -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq4uexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F2GM7RExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82), -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq4uexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F4GM8UExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95), -+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq4uexxg_ecc_get_status)), -+ SPINAND_INFO("GD5F4GM8RExxG", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85), -+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, -+ gd5fxgq4uexxg_ecc_get_status)), - }; - - static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = { diff --git a/target/linux/generic/backport-5.15/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch b/target/linux/generic/backport-5.15/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch deleted file mode 100644 index 9f543365a572fa..00000000000000 --- a/target/linux/generic/backport-5.15/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch +++ /dev/null @@ -1,229 +0,0 @@ -From aec4d5f5ffd0f0092bd9dc21ea90e0bc237d4b74 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 15 Oct 2022 11:29:50 +0200 -Subject: [PATCH] mtd: parsers: add TP-Link SafeLoader partitions table parser -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This parser deals with most TP-Link home routers. It reads info about -partitions and registers them in the MTD subsystem. - -Example from TP-Link Archer C5 V2: - -spi-nor spi0.0: s25fl128s1 (16384 Kbytes) -15 tplink-safeloader partitions found on MTD device spi0.0 -Creating 15 MTD partitions on "spi0.0": -0x000000000000-0x000000040000 : "fs-uboot" -0x000000040000-0x000000440000 : "os-image" -0x000000440000-0x000000e40000 : "rootfs" -0x000000e40000-0x000000e40200 : "default-mac" -0x000000e40200-0x000000e40400 : "pin" -0x000000e40400-0x000000e40600 : "product-info" -0x000000e50000-0x000000e60000 : "partition-table" -0x000000e60000-0x000000e60200 : "soft-version" -0x000000e61000-0x000000e70000 : "support-list" -0x000000e70000-0x000000e80000 : "profile" -0x000000e80000-0x000000e90000 : "default-config" -0x000000e90000-0x000000ee0000 : "user-config" -0x000000ee0000-0x000000fe0000 : "log" -0x000000fe0000-0x000000ff0000 : "radio_bk" -0x000000ff0000-0x000001000000 : "radio" - -Signed-off-by: Rafał Miłecki -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221015092950.27467-2-zajec5@gmail.com ---- - drivers/mtd/parsers/Kconfig | 15 +++ - drivers/mtd/parsers/Makefile | 1 + - drivers/mtd/parsers/tplink_safeloader.c | 150 ++++++++++++++++++++++++ - 3 files changed, 166 insertions(+) - create mode 100644 drivers/mtd/parsers/tplink_safeloader.c - ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -113,6 +113,21 @@ config MTD_AFS_PARTS - for your particular device. It won't happen automatically. The - 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. - -+config MTD_PARSER_TPLINK_SAFELOADER -+ tristate "TP-Link Safeloader partitions parser" -+ depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST) -+ help -+ TP-Link home routers use flash partitions to store various data. Info -+ about flash space layout is stored in a partitions table using a -+ custom ASCII-based format. -+ -+ That format was first found in devices with SafeLoader bootloader and -+ was named after it. Later it was adapted to CFE and U-Boot -+ bootloaders. -+ -+ This driver reads partitions table, parses it and creates MTD -+ partitions. -+ - config MTD_PARSER_TRX - tristate "Parser for TRX format partitions" - depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST) ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -9,6 +9,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += - ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o - obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o - obj-$(CONFIG_MTD_AFS_PARTS) += afs.o -+obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o - obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o - obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o - obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o ---- /dev/null -+++ b/drivers/mtd/parsers/tplink_safeloader.c -@@ -0,0 +1,150 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright © 2022 Rafał Miłecki -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define TPLINK_SAFELOADER_DATA_OFFSET 4 -+#define TPLINK_SAFELOADER_MAX_PARTS 32 -+ -+struct safeloader_cmn_header { -+ __be32 size; -+ uint32_t unused; -+} __packed; -+ -+static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd) -+{ -+ struct safeloader_cmn_header hdr; -+ struct device_node *np; -+ size_t bytes_read; -+ size_t offset; -+ size_t size; -+ char *buf; -+ int err; -+ -+ np = mtd_get_of_node(mtd); -+ if (mtd_is_partition(mtd)) -+ of_node_get(np); -+ else -+ np = of_get_child_by_name(np, "partitions"); -+ -+ if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) { -+ pr_err("Failed to get partitions table offset\n"); -+ goto err_put; -+ } -+ -+ err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr); -+ if (err && !mtd_is_bitflip(err)) { -+ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset); -+ goto err_put; -+ } -+ -+ size = be32_to_cpu(hdr.size); -+ -+ buf = kmalloc(size + 1, GFP_KERNEL); -+ if (!buf) -+ goto err_put; -+ -+ err = mtd_read(mtd, offset + sizeof(hdr), size, &bytes_read, buf); -+ if (err && !mtd_is_bitflip(err)) { -+ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset + sizeof(hdr)); -+ goto err_kfree; -+ } -+ -+ buf[size] = '\0'; -+ -+ of_node_put(np); -+ -+ return buf; -+ -+err_kfree: -+ kfree(buf); -+err_put: -+ of_node_put(np); -+ return NULL; -+} -+ -+static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_partition *parts; -+ char name[65]; -+ size_t offset; -+ size_t bytes; -+ char *buf; -+ int idx; -+ int err; -+ -+ parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL); -+ if (!parts) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ buf = mtd_parser_tplink_safeloader_read_table(mtd); -+ if (!buf) { -+ err = -ENOENT; -+ goto err_out; -+ } -+ -+ for (idx = 0, offset = TPLINK_SAFELOADER_DATA_OFFSET; -+ idx < TPLINK_SAFELOADER_MAX_PARTS && -+ sscanf(buf + offset, "partition %64s base 0x%llx size 0x%llx%zn\n", -+ name, &parts[idx].offset, &parts[idx].size, &bytes) == 3; -+ idx++, offset += bytes + 1) { -+ parts[idx].name = kstrdup(name, GFP_KERNEL); -+ if (!parts[idx].name) { -+ err = -ENOMEM; -+ goto err_free; -+ } -+ } -+ -+ if (idx == TPLINK_SAFELOADER_MAX_PARTS) -+ pr_warn("Reached maximum number of partitions!\n"); -+ -+ kfree(buf); -+ -+ *pparts = parts; -+ -+ return idx; -+ -+err_free: -+ for (idx -= 1; idx >= 0; idx--) -+ kfree(parts[idx].name); -+err_out: -+ return err; -+}; -+ -+static void mtd_parser_tplink_safeloader_cleanup(const struct mtd_partition *pparts, -+ int nr_parts) -+{ -+ int i; -+ -+ for (i = 0; i < nr_parts; i++) -+ kfree(pparts[i].name); -+ -+ kfree(pparts); -+} -+ -+static const struct of_device_id mtd_parser_tplink_safeloader_of_match_table[] = { -+ { .compatible = "tplink,safeloader-partitions" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtd_parser_tplink_safeloader_of_match_table); -+ -+static struct mtd_part_parser mtd_parser_tplink_safeloader = { -+ .parse_fn = mtd_parser_tplink_safeloader_parse, -+ .cleanup = mtd_parser_tplink_safeloader_cleanup, -+ .name = "tplink-safeloader", -+ .of_match_table = mtd_parser_tplink_safeloader_of_match_table, -+}; -+module_mtd_part_parser(mtd_parser_tplink_safeloader); -+ -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-5.15/422-v5.19-mtd-spi-nor-support-eon-en25qh256a.patch b/target/linux/generic/backport-5.15/422-v5.19-mtd-spi-nor-support-eon-en25qh256a.patch deleted file mode 100644 index 2358352e93c914..00000000000000 --- a/target/linux/generic/backport-5.15/422-v5.19-mtd-spi-nor-support-eon-en25qh256a.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 6abef37d16d0c570ef5a149e63762fba2a30804b Mon Sep 17 00:00:00 2001 -From: "Leon M. George" -Date: Wed, 30 Mar 2022 16:16:56 +0200 -Subject: [PATCH] mtd: spi-nor: support eon en25qh256a variant - -The EN25QH256A variant of the EN25QH256 doesn't initialize correctly from SFDP -alone and only accesses memory below 8m (addr_width is 4 but read_opcode takes -only 3 bytes). - -Set SNOR_F_4B_OPCODES if the flash chip variant was detected using hwcaps. - -The fix submitted upstream uses the PARSE_SFDP initializer that is not -available in the kernel used with Openwrt. - -Signed-off-by: Leon M. George ---- - drivers/mtd/spi-nor/eon.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/mtd/spi-nor/eon.c -+++ b/drivers/mtd/spi-nor/eon.c -@@ -8,6 +8,16 @@ - - #include "core.h" - -+static void en25qh256_post_sfdp_fixups(struct spi_nor *nor) -+{ -+ if (nor->params->hwcaps.mask & SNOR_HWCAPS_READ_1_1_4) -+ nor->flags |= SNOR_F_4B_OPCODES; -+} -+ -+static const struct spi_nor_fixups en25qh256_fixups = { -+ .post_sfdp = en25qh256_post_sfdp_fixups, -+}; -+ - static const struct flash_info eon_parts[] = { - /* EON -- en25xxx */ - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, -@@ -23,7 +33,9 @@ static const struct flash_info eon_parts - { "en25qh64", INFO(0x1c7017, 0, 64 * 1024, 128, - SECT_4K | SPI_NOR_DUAL_READ) }, - { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, -- { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, -+ { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, -+ SPI_NOR_DUAL_READ) -+ .fixups = &en25qh256_fixups }, - { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, - }; - diff --git a/target/linux/generic/backport-5.15/423-v6.1-0001-mtd-track-maximum-number-of-bitflips-for-each-read-r.patch b/target/linux/generic/backport-5.15/423-v6.1-0001-mtd-track-maximum-number-of-bitflips-for-each-read-r.patch deleted file mode 100644 index c17dd5bf8c0cab..00000000000000 --- a/target/linux/generic/backport-5.15/423-v6.1-0001-mtd-track-maximum-number-of-bitflips-for-each-read-r.patch +++ /dev/null @@ -1,73 +0,0 @@ -From e237285113963bd1dd2e925770aa8b3aa8a1894c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= -Date: Wed, 29 Jun 2022 14:57:34 +0200 -Subject: [PATCH 1/4] mtd: track maximum number of bitflips for each read - request -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mtd_read_oob() callers are currently oblivious to the details of ECC -errors detected during the read operation - they only learn (through the -return value) whether any corrected bitflips or uncorrectable errors -occurred. More detailed ECC information can be useful to user-space -applications for making better-informed choices about moving data -around. - -Extend struct mtd_oob_ops with a pointer to a newly-introduced struct -mtd_req_stats and set its 'max_bitflips' field to the maximum number of -bitflips found in a single ECC step during the read operation performed -by mtd_read_oob(). This is a prerequisite for ultimately passing that -value back to user space. - -Suggested-by: Boris Brezillon -Signed-off-by: Michał Kępień -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220629125737.14418-2-kernel@kempniu.pl ---- - drivers/mtd/mtdcore.c | 5 +++++ - include/linux/mtd/mtd.h | 5 +++++ - 2 files changed, 10 insertions(+) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -1678,6 +1678,9 @@ int mtd_read_oob(struct mtd_info *mtd, l - if (!master->_read_oob && (!master->_read || ops->oobbuf)) - return -EOPNOTSUPP; - -+ if (ops->stats) -+ memset(ops->stats, 0, sizeof(*ops->stats)); -+ - if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) - ret_code = mtd_io_emulated_slc(mtd, from, true, ops); - else -@@ -1695,6 +1698,8 @@ int mtd_read_oob(struct mtd_info *mtd, l - return ret_code; - if (mtd->ecc_strength == 0) - return 0; /* device lacks ecc */ -+ if (ops->stats) -+ ops->stats->max_bitflips = ret_code; - return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0; - } - EXPORT_SYMBOL_GPL(mtd_read_oob); ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -40,6 +40,10 @@ struct mtd_erase_region_info { - unsigned long *lockmap; /* If keeping bitmap of locks */ - }; - -+struct mtd_req_stats { -+ unsigned int max_bitflips; -+}; -+ - /** - * struct mtd_oob_ops - oob operation operands - * @mode: operation mode -@@ -70,6 +74,7 @@ struct mtd_oob_ops { - uint32_t ooboffs; - uint8_t *datbuf; - uint8_t *oobbuf; -+ struct mtd_req_stats *stats; - }; - - #define MTD_MAX_OOBFREE_ENTRIES_LARGE 32 diff --git a/target/linux/generic/backport-5.15/423-v6.1-0002-mtd-always-initialize-stats-in-struct-mtd_oob_ops.patch b/target/linux/generic/backport-5.15/423-v6.1-0002-mtd-always-initialize-stats-in-struct-mtd_oob_ops.patch deleted file mode 100644 index 1484624e4e5194..00000000000000 --- a/target/linux/generic/backport-5.15/423-v6.1-0002-mtd-always-initialize-stats-in-struct-mtd_oob_ops.patch +++ /dev/null @@ -1,325 +0,0 @@ -From e97709c9d18903f5acd5fbe2985dd054da0432b1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= -Date: Wed, 29 Jun 2022 14:57:35 +0200 -Subject: [PATCH 2/4] mtd: always initialize 'stats' in struct mtd_oob_ops -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -As the 'stats' field in struct mtd_oob_ops is used in conditional -expressions, ensure it is always zero-initialized in all such structures -to prevent random stack garbage from being interpreted as a pointer. - -Strictly speaking, this problem currently only needs to be fixed for -struct mtd_oob_ops structures subsequently passed to mtd_read_oob(). -However, this commit goes a step further and makes all instances of -struct mtd_oob_ops in the tree zero-initialized, in hope of preventing -future problems, e.g. if struct mtd_req_stats gets extended with write -statistics at some point. - -Signed-off-by: Michał Kępień -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220629125737.14418-3-kernel@kempniu.pl ---- - drivers/mtd/inftlcore.c | 6 +++--- - drivers/mtd/mtdswap.c | 6 +++--- - drivers/mtd/nand/onenand/onenand_base.c | 4 ++-- - drivers/mtd/nand/onenand/onenand_bbt.c | 2 +- - drivers/mtd/nand/raw/nand_bbt.c | 8 ++++---- - drivers/mtd/nand/raw/sm_common.c | 2 +- - drivers/mtd/nftlcore.c | 6 +++--- - drivers/mtd/sm_ftl.c | 4 ++-- - drivers/mtd/ssfdc.c | 2 +- - drivers/mtd/tests/nandbiterrs.c | 2 +- - drivers/mtd/tests/oobtest.c | 8 ++++---- - drivers/mtd/tests/readtest.c | 2 +- - fs/jffs2/wbuf.c | 6 +++--- - 13 files changed, 29 insertions(+), 29 deletions(-) - ---- a/drivers/mtd/inftlcore.c -+++ b/drivers/mtd/inftlcore.c -@@ -136,7 +136,7 @@ static void inftl_remove_dev(struct mtd_ - int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len, - size_t *retlen, uint8_t *buf) - { -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int res; - - ops.mode = MTD_OPS_PLACE_OOB; -@@ -156,7 +156,7 @@ int inftl_read_oob(struct mtd_info *mtd, - int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len, - size_t *retlen, uint8_t *buf) - { -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int res; - - ops.mode = MTD_OPS_PLACE_OOB; -@@ -176,7 +176,7 @@ int inftl_write_oob(struct mtd_info *mtd - static int inftl_write(struct mtd_info *mtd, loff_t offs, size_t len, - size_t *retlen, uint8_t *buf, uint8_t *oob) - { -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int res; - - ops.mode = MTD_OPS_PLACE_OOB; ---- a/drivers/mtd/mtdswap.c -+++ b/drivers/mtd/mtdswap.c -@@ -323,7 +323,7 @@ static int mtdswap_read_markers(struct m - struct mtdswap_oobdata *data, *data2; - int ret; - loff_t offset; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - - offset = mtdswap_eb_offset(d, eb); - -@@ -370,7 +370,7 @@ static int mtdswap_write_marker(struct m - struct mtdswap_oobdata n; - int ret; - loff_t offset; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - - ops.ooboffs = 0; - ops.oobbuf = (uint8_t *)&n; -@@ -879,7 +879,7 @@ static unsigned int mtdswap_eblk_passes( - loff_t base, pos; - unsigned int *p1 = (unsigned int *)d->page_buf; - unsigned char *p2 = (unsigned char *)d->oob_buf; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int ret; - - ops.mode = MTD_OPS_AUTO_OOB; ---- a/drivers/mtd/nand/onenand/onenand_base.c -+++ b/drivers/mtd/nand/onenand/onenand_base.c -@@ -2935,7 +2935,7 @@ static int do_otp_write(struct mtd_info - struct onenand_chip *this = mtd->priv; - unsigned char *pbuf = buf; - int ret; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - - /* Force buffer page aligned */ - if (len < mtd->writesize) { -@@ -2977,7 +2977,7 @@ static int do_otp_lock(struct mtd_info * - size_t *retlen, u_char *buf) - { - struct onenand_chip *this = mtd->priv; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int ret; - - if (FLEXONENAND(this)) { ---- a/drivers/mtd/nand/onenand/onenand_bbt.c -+++ b/drivers/mtd/nand/onenand/onenand_bbt.c -@@ -61,7 +61,7 @@ static int create_bbt(struct mtd_info *m - int startblock; - loff_t from; - size_t readlen, ooblen; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int rgn; - - printk(KERN_INFO "Scanning device for bad blocks\n"); ---- a/drivers/mtd/nand/raw/nand_bbt.c -+++ b/drivers/mtd/nand/raw/nand_bbt.c -@@ -313,7 +313,7 @@ static int scan_read_oob(struct nand_chi - size_t len) - { - struct mtd_info *mtd = nand_to_mtd(this); -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int res, ret = 0; - - ops.mode = MTD_OPS_PLACE_OOB; -@@ -354,7 +354,7 @@ static int scan_write_bbt(struct nand_ch - uint8_t *buf, uint8_t *oob) - { - struct mtd_info *mtd = nand_to_mtd(this); -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - - ops.mode = MTD_OPS_PLACE_OOB; - ops.ooboffs = 0; -@@ -416,7 +416,7 @@ static int scan_block_fast(struct nand_c - { - struct mtd_info *mtd = nand_to_mtd(this); - -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int ret, page_offset; - - ops.ooblen = mtd->oobsize; -@@ -756,7 +756,7 @@ static int write_bbt(struct nand_chip *t - uint8_t rcode = td->reserved_block_code; - size_t retlen, len = 0; - loff_t to; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - - ops.ooblen = mtd->oobsize; - ops.ooboffs = 0; ---- a/drivers/mtd/nand/raw/sm_common.c -+++ b/drivers/mtd/nand/raw/sm_common.c -@@ -99,7 +99,7 @@ static const struct mtd_ooblayout_ops oo - static int sm_block_markbad(struct nand_chip *chip, loff_t ofs) - { - struct mtd_info *mtd = nand_to_mtd(chip); -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - struct sm_oob oob; - int ret; - ---- a/drivers/mtd/nftlcore.c -+++ b/drivers/mtd/nftlcore.c -@@ -124,7 +124,7 @@ int nftl_read_oob(struct mtd_info *mtd, - size_t *retlen, uint8_t *buf) - { - loff_t mask = mtd->writesize - 1; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int res; - - ops.mode = MTD_OPS_PLACE_OOB; -@@ -145,7 +145,7 @@ int nftl_write_oob(struct mtd_info *mtd, - size_t *retlen, uint8_t *buf) - { - loff_t mask = mtd->writesize - 1; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int res; - - ops.mode = MTD_OPS_PLACE_OOB; -@@ -168,7 +168,7 @@ static int nftl_write(struct mtd_info *m - size_t *retlen, uint8_t *buf, uint8_t *oob) - { - loff_t mask = mtd->writesize - 1; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int res; - - ops.mode = MTD_OPS_PLACE_OOB; ---- a/drivers/mtd/sm_ftl.c -+++ b/drivers/mtd/sm_ftl.c -@@ -239,7 +239,7 @@ static int sm_read_sector(struct sm_ftl - uint8_t *buffer, struct sm_oob *oob) - { - struct mtd_info *mtd = ftl->trans->mtd; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - struct sm_oob tmp_oob; - int ret = -EIO; - int try = 0; -@@ -323,7 +323,7 @@ static int sm_write_sector(struct sm_ftl - int zone, int block, int boffset, - uint8_t *buffer, struct sm_oob *oob) - { -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - struct mtd_info *mtd = ftl->trans->mtd; - int ret; - ---- a/drivers/mtd/ssfdc.c -+++ b/drivers/mtd/ssfdc.c -@@ -163,7 +163,7 @@ static int read_physical_sector(struct m - /* Read redundancy area (wrapper to MTD_READ_OOB */ - static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf) - { -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int ret; - - ops.mode = MTD_OPS_RAW; ---- a/drivers/mtd/tests/nandbiterrs.c -+++ b/drivers/mtd/tests/nandbiterrs.c -@@ -99,7 +99,7 @@ static int write_page(int log) - static int rewrite_page(int log) - { - int err = 0; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - - if (log) - pr_info("rewrite page\n"); ---- a/drivers/mtd/tests/oobtest.c -+++ b/drivers/mtd/tests/oobtest.c -@@ -56,7 +56,7 @@ static void do_vary_offset(void) - static int write_eraseblock(int ebnum) - { - int i; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int err = 0; - loff_t addr = (loff_t)ebnum * mtd->erasesize; - -@@ -165,7 +165,7 @@ static size_t memffshow(loff_t addr, lof - static int verify_eraseblock(int ebnum) - { - int i; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int err = 0; - loff_t addr = (loff_t)ebnum * mtd->erasesize; - size_t bitflips; -@@ -260,7 +260,7 @@ static int verify_eraseblock(int ebnum) - - static int verify_eraseblock_in_one_go(int ebnum) - { -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int err = 0; - loff_t addr = (loff_t)ebnum * mtd->erasesize; - size_t len = mtd->oobavail * pgcnt; -@@ -338,7 +338,7 @@ static int __init mtd_oobtest_init(void) - int err = 0; - unsigned int i; - uint64_t tmp; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - loff_t addr = 0, addr0; - - printk(KERN_INFO "\n"); ---- a/drivers/mtd/tests/readtest.c -+++ b/drivers/mtd/tests/readtest.c -@@ -47,7 +47,7 @@ static int read_eraseblock_by_page(int e - err = ret; - } - if (mtd->oobsize) { -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - - ops.mode = MTD_OPS_PLACE_OOB; - ops.len = 0; ---- a/fs/jffs2/wbuf.c -+++ b/fs/jffs2/wbuf.c -@@ -1035,7 +1035,7 @@ int jffs2_check_oob_empty(struct jffs2_s - { - int i, ret; - int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - - ops.mode = MTD_OPS_AUTO_OOB; - ops.ooblen = NR_OOB_SCAN_PAGES * c->oobavail; -@@ -1076,7 +1076,7 @@ int jffs2_check_oob_empty(struct jffs2_s - int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb) - { -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); - - ops.mode = MTD_OPS_AUTO_OOB; -@@ -1101,7 +1101,7 @@ int jffs2_write_nand_cleanmarker(struct - struct jffs2_eraseblock *jeb) - { - int ret; -- struct mtd_oob_ops ops; -+ struct mtd_oob_ops ops = { }; - int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE); - - ops.mode = MTD_OPS_AUTO_OOB; diff --git a/target/linux/generic/backport-5.15/423-v6.1-0003-mtd-add-ECC-error-accounting-for-each-read-request.patch b/target/linux/generic/backport-5.15/423-v6.1-0003-mtd-add-ECC-error-accounting-for-each-read-request.patch deleted file mode 100644 index f2f45eb7bc7ad9..00000000000000 --- a/target/linux/generic/backport-5.15/423-v6.1-0003-mtd-add-ECC-error-accounting-for-each-read-request.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 2ed18d818d1f7492172f8dd5904344c7d367e8ed Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= -Date: Wed, 29 Jun 2022 14:57:36 +0200 -Subject: [PATCH 3/4] mtd: add ECC error accounting for each read request -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Extend struct mtd_req_stats with two new fields holding the number of -corrected bitflips and uncorrectable errors detected during a read -operation. This is a prerequisite for ultimately passing those counters -to user space, where they can be useful to applications for making -better-informed choices about moving data around. - -Unlike 'max_bitflips' (which is set - in a common code path - to the -return value of a function called while the MTD device's mutex is held), -these counters have to be maintained in each MTD driver which defines -the '_read_oob' callback because the statistics need to be calculated -while the MTD device's mutex is held. - -Suggested-by: Boris Brezillon -Signed-off-by: Michał Kępień -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220629125737.14418-4-kernel@kempniu.pl ---- - drivers/mtd/devices/docg3.c | 8 ++++++++ - drivers/mtd/nand/onenand/onenand_base.c | 12 ++++++++++++ - drivers/mtd/nand/raw/nand_base.c | 10 ++++++++++ - drivers/mtd/nand/spi/core.c | 10 ++++++++++ - include/linux/mtd/mtd.h | 2 ++ - 5 files changed, 42 insertions(+) - ---- a/drivers/mtd/devices/docg3.c -+++ b/drivers/mtd/devices/docg3.c -@@ -871,6 +871,7 @@ static int doc_read_oob(struct mtd_info - u8 *buf = ops->datbuf; - size_t len, ooblen, nbdata, nboob; - u8 hwecc[DOC_ECC_BCH_SIZE], eccconf1; -+ struct mtd_ecc_stats old_stats; - int max_bitflips = 0; - - if (buf) -@@ -895,6 +896,7 @@ static int doc_read_oob(struct mtd_info - ret = 0; - skip = from % DOC_LAYOUT_PAGE_SIZE; - mutex_lock(&docg3->cascade->lock); -+ old_stats = mtd->ecc_stats; - while (ret >= 0 && (len > 0 || ooblen > 0)) { - calc_block_sector(from - skip, &block0, &block1, &page, &ofs, - docg3->reliable); -@@ -966,6 +968,12 @@ static int doc_read_oob(struct mtd_info - } - - out: -+ if (ops->stats) { -+ ops->stats->uncorrectable_errors += -+ mtd->ecc_stats.failed - old_stats.failed; -+ ops->stats->corrected_bitflips += -+ mtd->ecc_stats.corrected - old_stats.corrected; -+ } - mutex_unlock(&docg3->cascade->lock); - return ret; - err_in_read: ---- a/drivers/mtd/nand/onenand/onenand_base.c -+++ b/drivers/mtd/nand/onenand/onenand_base.c -@@ -1440,6 +1440,7 @@ static int onenand_read_oob(struct mtd_i - struct mtd_oob_ops *ops) - { - struct onenand_chip *this = mtd->priv; -+ struct mtd_ecc_stats old_stats; - int ret; - - switch (ops->mode) { -@@ -1453,12 +1454,23 @@ static int onenand_read_oob(struct mtd_i - } - - onenand_get_device(mtd, FL_READING); -+ -+ old_stats = mtd->ecc_stats; -+ - if (ops->datbuf) - ret = ONENAND_IS_4KB_PAGE(this) ? - onenand_mlc_read_ops_nolock(mtd, from, ops) : - onenand_read_ops_nolock(mtd, from, ops); - else - ret = onenand_read_oob_nolock(mtd, from, ops); -+ -+ if (ops->stats) { -+ ops->stats->uncorrectable_errors += -+ mtd->ecc_stats.failed - old_stats.failed; -+ ops->stats->corrected_bitflips += -+ mtd->ecc_stats.corrected - old_stats.corrected; -+ } -+ - onenand_release_device(mtd); - - return ret; ---- a/drivers/mtd/nand/raw/nand_base.c -+++ b/drivers/mtd/nand/raw/nand_base.c -@@ -3815,6 +3815,7 @@ static int nand_read_oob(struct mtd_info - struct mtd_oob_ops *ops) - { - struct nand_chip *chip = mtd_to_nand(mtd); -+ struct mtd_ecc_stats old_stats; - int ret; - - ops->retlen = 0; -@@ -3826,11 +3827,20 @@ static int nand_read_oob(struct mtd_info - - nand_get_device(chip); - -+ old_stats = mtd->ecc_stats; -+ - if (!ops->datbuf) - ret = nand_do_read_oob(chip, from, ops); - else - ret = nand_do_read_ops(chip, from, ops); - -+ if (ops->stats) { -+ ops->stats->uncorrectable_errors += -+ mtd->ecc_stats.failed - old_stats.failed; -+ ops->stats->corrected_bitflips += -+ mtd->ecc_stats.corrected - old_stats.corrected; -+ } -+ - nand_release_device(chip); - return ret; - } ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -629,6 +629,7 @@ static int spinand_mtd_read(struct mtd_i - { - struct spinand_device *spinand = mtd_to_spinand(mtd); - struct nand_device *nand = mtd_to_nanddev(mtd); -+ struct mtd_ecc_stats old_stats; - unsigned int max_bitflips = 0; - struct nand_io_iter iter; - bool disable_ecc = false; -@@ -640,6 +641,8 @@ static int spinand_mtd_read(struct mtd_i - - mutex_lock(&spinand->lock); - -+ old_stats = mtd->ecc_stats; -+ - nanddev_io_for_each_page(nand, NAND_PAGE_READ, from, ops, &iter) { - if (disable_ecc) - iter.req.mode = MTD_OPS_RAW; -@@ -662,6 +665,13 @@ static int spinand_mtd_read(struct mtd_i - ops->oobretlen += iter.req.ooblen; - } - -+ if (ops->stats) { -+ ops->stats->uncorrectable_errors += -+ mtd->ecc_stats.failed - old_stats.failed; -+ ops->stats->corrected_bitflips += -+ mtd->ecc_stats.corrected - old_stats.corrected; -+ } -+ - mutex_unlock(&spinand->lock); - - if (ecc_failed && !ret) ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -41,6 +41,8 @@ struct mtd_erase_region_info { - }; - - struct mtd_req_stats { -+ unsigned int uncorrectable_errors; -+ unsigned int corrected_bitflips; - unsigned int max_bitflips; - }; - diff --git a/target/linux/generic/backport-5.15/423-v6.1-0004-mtdchar-add-MEMREAD-ioctl.patch b/target/linux/generic/backport-5.15/423-v6.1-0004-mtdchar-add-MEMREAD-ioctl.patch deleted file mode 100644 index 182e4f6ab5685c..00000000000000 --- a/target/linux/generic/backport-5.15/423-v6.1-0004-mtdchar-add-MEMREAD-ioctl.patch +++ /dev/null @@ -1,321 +0,0 @@ -From 2c9745d36e04ac27161acd78514f647b9b587ad4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= -Date: Wed, 29 Jun 2022 14:57:37 +0200 -Subject: [PATCH 4/4] mtdchar: add MEMREAD ioctl -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -User-space applications making use of MTD devices via /dev/mtd* -character devices currently have limited capabilities for reading data: - - - only deprecated methods of accessing OOB layout information exist, - - - there is no way to explicitly specify MTD operation mode to use; it - is auto-selected based on the MTD file mode (MTD_FILE_MODE_*) set - for the character device; in particular, this prevents using - MTD_OPS_AUTO_OOB for reads, - - - all existing user-space interfaces which cause mtd_read() or - mtd_read_oob() to be called (via mtdchar_read() and - mtdchar_read_oob(), respectively) return success even when those - functions return -EUCLEAN or -EBADMSG; this renders user-space - applications using these interfaces unaware of any corrected - bitflips or uncorrectable ECC errors detected during reads. - -Note that the existing MEMWRITE ioctl allows the MTD operation mode to -be explicitly set, allowing user-space applications to write page data -and OOB data without requiring them to know anything about the OOB -layout of the MTD device they are writing to (MTD_OPS_AUTO_OOB). Also, -the MEMWRITE ioctl does not mangle the return value of mtd_write_oob(). - -Add a new ioctl, MEMREAD, which addresses the above issues. It is -intended to be a read-side counterpart of the existing MEMWRITE ioctl. -Similarly to the latter, the read operation is performed in a loop which -processes at most mtd->erasesize bytes in each iteration. This is done -to prevent unbounded memory allocations caused by calling kmalloc() with -the 'size' argument taken directly from the struct mtd_read_req provided -by user space. However, the new ioctl is implemented so that the values -it returns match those that would have been returned if just a single -mtd_read_oob() call was issued to handle the entire read operation in -one go. - -Note that while just returning -EUCLEAN or -EBADMSG to user space would -already be a valid and useful indication of the ECC algorithm detecting -errors during a read operation, that signal would not be granular enough -to cover all use cases. For example, knowing the maximum number of -bitflips detected in a single ECC step during a read operation performed -on a given page may be useful when dealing with an MTD partition whose -ECC layout varies across pages (e.g. a partition consisting of a -bootloader area using a "custom" ECC layout followed by data pages using -a "standard" ECC layout). To address that, include ECC statistics in -the structure returned to user space by the new MEMREAD ioctl. - -Link: https://www.infradead.org/pipermail/linux-mtd/2016-April/067085.html - -Suggested-by: Boris Brezillon -Signed-off-by: Michał Kępień -Acked-by: Richard Weinberger -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20220629125737.14418-5-kernel@kempniu.pl ---- - drivers/mtd/mtdchar.c | 139 +++++++++++++++++++++++++++++++++++++ - include/uapi/mtd/mtd-abi.h | 64 +++++++++++++++-- - 2 files changed, 198 insertions(+), 5 deletions(-) - ---- a/drivers/mtd/mtdchar.c -+++ b/drivers/mtd/mtdchar.c -@@ -621,6 +621,137 @@ static int mtdchar_write_ioctl(struct mt - return ret; - } - -+static int mtdchar_read_ioctl(struct mtd_info *mtd, -+ struct mtd_read_req __user *argp) -+{ -+ struct mtd_info *master = mtd_get_master(mtd); -+ struct mtd_read_req req; -+ void __user *usr_data, *usr_oob; -+ uint8_t *datbuf = NULL, *oobbuf = NULL; -+ size_t datbuf_len, oobbuf_len; -+ size_t orig_len, orig_ooblen; -+ int ret = 0; -+ -+ if (copy_from_user(&req, argp, sizeof(req))) -+ return -EFAULT; -+ -+ orig_len = req.len; -+ orig_ooblen = req.ooblen; -+ -+ usr_data = (void __user *)(uintptr_t)req.usr_data; -+ usr_oob = (void __user *)(uintptr_t)req.usr_oob; -+ -+ if (!master->_read_oob) -+ return -EOPNOTSUPP; -+ -+ if (!usr_data) -+ req.len = 0; -+ -+ if (!usr_oob) -+ req.ooblen = 0; -+ -+ req.ecc_stats.uncorrectable_errors = 0; -+ req.ecc_stats.corrected_bitflips = 0; -+ req.ecc_stats.max_bitflips = 0; -+ -+ req.len &= 0xffffffff; -+ req.ooblen &= 0xffffffff; -+ -+ if (req.start + req.len > mtd->size) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ datbuf_len = min_t(size_t, req.len, mtd->erasesize); -+ if (datbuf_len > 0) { -+ datbuf = kvmalloc(datbuf_len, GFP_KERNEL); -+ if (!datbuf) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ } -+ -+ oobbuf_len = min_t(size_t, req.ooblen, mtd->erasesize); -+ if (oobbuf_len > 0) { -+ oobbuf = kvmalloc(oobbuf_len, GFP_KERNEL); -+ if (!oobbuf) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ } -+ -+ while (req.len > 0 || (!usr_data && req.ooblen > 0)) { -+ struct mtd_req_stats stats; -+ struct mtd_oob_ops ops = { -+ .mode = req.mode, -+ .len = min_t(size_t, req.len, datbuf_len), -+ .ooblen = min_t(size_t, req.ooblen, oobbuf_len), -+ .datbuf = datbuf, -+ .oobbuf = oobbuf, -+ .stats = &stats, -+ }; -+ -+ /* -+ * Shorten non-page-aligned, eraseblock-sized reads so that the -+ * read ends on an eraseblock boundary. This is necessary in -+ * order to prevent OOB data for some pages from being -+ * duplicated in the output of non-page-aligned reads requiring -+ * multiple mtd_read_oob() calls to be completed. -+ */ -+ if (ops.len == mtd->erasesize) -+ ops.len -= mtd_mod_by_ws(req.start + ops.len, mtd); -+ -+ ret = mtd_read_oob(mtd, (loff_t)req.start, &ops); -+ -+ req.ecc_stats.uncorrectable_errors += -+ stats.uncorrectable_errors; -+ req.ecc_stats.corrected_bitflips += stats.corrected_bitflips; -+ req.ecc_stats.max_bitflips = -+ max(req.ecc_stats.max_bitflips, stats.max_bitflips); -+ -+ if (ret && !mtd_is_bitflip_or_eccerr(ret)) -+ break; -+ -+ if (copy_to_user(usr_data, ops.datbuf, ops.retlen) || -+ copy_to_user(usr_oob, ops.oobbuf, ops.oobretlen)) { -+ ret = -EFAULT; -+ break; -+ } -+ -+ req.start += ops.retlen; -+ req.len -= ops.retlen; -+ usr_data += ops.retlen; -+ -+ req.ooblen -= ops.oobretlen; -+ usr_oob += ops.oobretlen; -+ } -+ -+ /* -+ * As multiple iterations of the above loop (and therefore multiple -+ * mtd_read_oob() calls) may be necessary to complete the read request, -+ * adjust the final return code to ensure it accounts for all detected -+ * ECC errors. -+ */ -+ if (!ret || mtd_is_bitflip(ret)) { -+ if (req.ecc_stats.uncorrectable_errors > 0) -+ ret = -EBADMSG; -+ else if (req.ecc_stats.corrected_bitflips > 0) -+ ret = -EUCLEAN; -+ } -+ -+out: -+ req.len = orig_len - req.len; -+ req.ooblen = orig_ooblen - req.ooblen; -+ -+ if (copy_to_user(argp, &req, sizeof(req))) -+ ret = -EFAULT; -+ -+ kvfree(datbuf); -+ kvfree(oobbuf); -+ -+ return ret; -+} -+ - static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg) - { - struct mtd_file_info *mfi = file->private_data; -@@ -643,6 +774,7 @@ static int mtdchar_ioctl(struct file *fi - case MEMGETINFO: - case MEMREADOOB: - case MEMREADOOB64: -+ case MEMREAD: - case MEMISLOCKED: - case MEMGETOOBSEL: - case MEMGETBADBLOCK: -@@ -817,6 +949,13 @@ static int mtdchar_ioctl(struct file *fi - break; - } - -+ case MEMREAD: -+ { -+ ret = mtdchar_read_ioctl(mtd, -+ (struct mtd_read_req __user *)arg); -+ break; -+ } -+ - case MEMLOCK: - { - struct erase_info_user einfo; ---- a/include/uapi/mtd/mtd-abi.h -+++ b/include/uapi/mtd/mtd-abi.h -@@ -55,9 +55,9 @@ struct mtd_oob_buf64 { - * @MTD_OPS_RAW: data are transferred as-is, with no error correction; - * this mode implies %MTD_OPS_PLACE_OOB - * -- * These modes can be passed to ioctl(MEMWRITE) and are also used internally. -- * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs. -- * %MTD_FILE_MODE_RAW. -+ * These modes can be passed to ioctl(MEMWRITE) and ioctl(MEMREAD); they are -+ * also used internally. See notes on "MTD file modes" for discussion on -+ * %MTD_OPS_RAW vs. %MTD_FILE_MODE_RAW. - */ - enum { - MTD_OPS_PLACE_OOB = 0, -@@ -91,6 +91,53 @@ struct mtd_write_req { - __u8 padding[7]; - }; - -+/** -+ * struct mtd_read_req_ecc_stats - ECC statistics for a read operation -+ * -+ * @uncorrectable_errors: the number of uncorrectable errors that happened -+ * during the read operation -+ * @corrected_bitflips: the number of bitflips corrected during the read -+ * operation -+ * @max_bitflips: the maximum number of bitflips detected in any single ECC -+ * step for the data read during the operation; this information -+ * can be used to decide whether the data stored in a specific -+ * region of the MTD device should be moved somewhere else to -+ * avoid data loss. -+ */ -+struct mtd_read_req_ecc_stats { -+ __u32 uncorrectable_errors; -+ __u32 corrected_bitflips; -+ __u32 max_bitflips; -+}; -+ -+/** -+ * struct mtd_read_req - data structure for requesting a read operation -+ * -+ * @start: start address -+ * @len: length of data buffer (only lower 32 bits are used) -+ * @ooblen: length of OOB buffer (only lower 32 bits are used) -+ * @usr_data: user-provided data buffer -+ * @usr_oob: user-provided OOB buffer -+ * @mode: MTD mode (see "MTD operation modes") -+ * @padding: reserved, must be set to 0 -+ * @ecc_stats: ECC statistics for the read operation -+ * -+ * This structure supports ioctl(MEMREAD) operations, allowing data and/or OOB -+ * reads in various modes. To read from OOB-only, set @usr_data == NULL, and to -+ * read data-only, set @usr_oob == NULL. However, setting both @usr_data and -+ * @usr_oob to NULL is not allowed. -+ */ -+struct mtd_read_req { -+ __u64 start; -+ __u64 len; -+ __u64 ooblen; -+ __u64 usr_data; -+ __u64 usr_oob; -+ __u8 mode; -+ __u8 padding[7]; -+ struct mtd_read_req_ecc_stats ecc_stats; -+}; -+ - #define MTD_ABSENT 0 - #define MTD_RAM 1 - #define MTD_ROM 2 -@@ -207,6 +254,12 @@ struct otp_info { - #define MEMWRITE _IOWR('M', 24, struct mtd_write_req) - /* Erase a given range of user data (must be in mode %MTD_FILE_MODE_OTP_USER) */ - #define OTPERASE _IOW('M', 25, struct otp_info) -+/* -+ * Most generic read interface; can read in-band and/or out-of-band in various -+ * modes (see "struct mtd_read_req"). This ioctl is not supported for flashes -+ * without OOB, e.g., NOR flash. -+ */ -+#define MEMREAD _IOWR('M', 26, struct mtd_read_req) - - /* - * Obsolete legacy interface. Keep it in order not to break userspace -@@ -270,8 +323,9 @@ struct mtd_ecc_stats { - * Note: %MTD_FILE_MODE_RAW provides the same functionality as %MTD_OPS_RAW - - * raw access to the flash, without error correction or autoplacement schemes. - * Wherever possible, the MTD_OPS_* mode will override the MTD_FILE_MODE_* mode -- * (e.g., when using ioctl(MEMWRITE)), but in some cases, the MTD_FILE_MODE is -- * used out of necessity (e.g., `write()', ioctl(MEMWRITEOOB64)). -+ * (e.g., when using ioctl(MEMWRITE) or ioctl(MEMREAD)), but in some cases, the -+ * MTD_FILE_MODE is used out of necessity (e.g., `write()', -+ * ioctl(MEMWRITEOOB64)). - */ - enum mtd_file_modes { - MTD_FILE_MODE_NORMAL = MTD_OTP_OFF, diff --git a/target/linux/generic/backport-5.15/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch b/target/linux/generic/backport-5.15/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch deleted file mode 100644 index 7dbc2717250bfc..00000000000000 --- a/target/linux/generic/backport-5.15/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch +++ /dev/null @@ -1,35 +0,0 @@ -From ebed787a0becb9354f0a23620a5130cccd6c730c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 19 Jan 2023 03:45:43 +0000 -Subject: [PATCH] mtd: spinand: macronix: use scratch buffer for DMA operation - -The mx35lf1ge4ab_get_eccsr() function uses an SPI DMA operation to -read the eccsr, hence the buffer should not be on stack. Since commit -380583227c0c7f ("spi: spi-mem: Add extra sanity checks on the op param") -the kernel emmits a warning and blocks such operations. - -Use the scratch buffer to get eccsr instead of trying to directly read -into a stack-allocated variable. - -Signed-off-by: Daniel Golle -Reviewed-by: Dhruva Gole -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/Y8i85zM0u4XdM46z@makrotopia.org ---- - drivers/mtd/nand/spi/macronix.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/nand/spi/macronix.c -+++ b/drivers/mtd/nand/spi/macronix.c -@@ -83,9 +83,10 @@ static int mx35lf1ge4ab_ecc_get_status(s - * in order to avoid forcing the wear-leveling layer to move - * data around if it's not necessary. - */ -- if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr)) -+ if (mx35lf1ge4ab_get_eccsr(spinand, spinand->scratchbuf)) - return nanddev_get_ecc_conf(nand)->strength; - -+ eccsr = *spinand->scratchbuf; - if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength || - !eccsr)) - return nanddev_get_ecc_conf(nand)->strength; diff --git a/target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch b/target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch deleted file mode 100644 index 001b55653f8443..00000000000000 --- a/target/linux/generic/backport-5.15/424-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 281f7a6c1a33fffcde32001bacbb4f672140fbf9 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Wed, 8 Mar 2023 09:20:21 +0100 -Subject: [PATCH] mtd: core: prepare mtd_otp_nvmem_add() to handle - -EPROBE_DEFER - -NVMEM soon will get the ability for nvmem layouts and these might -not be ready when nvmem_register() is called and thus it might -return -EPROBE_DEFER. Don't print the error message in this case. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc ---- - drivers/mtd/mtdcore.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -962,8 +962,8 @@ static int mtd_otp_nvmem_add(struct mtd_ - nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size, - mtd_nvmem_user_otp_reg_read); - if (IS_ERR(nvmem)) { -- dev_err(dev, "Failed to register OTP NVMEM device\n"); -- return PTR_ERR(nvmem); -+ err = PTR_ERR(nvmem); -+ goto err; - } - mtd->otp_user_nvmem = nvmem; - } -@@ -980,7 +980,6 @@ static int mtd_otp_nvmem_add(struct mtd_ - nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size, - mtd_nvmem_fact_otp_reg_read); - if (IS_ERR(nvmem)) { -- dev_err(dev, "Failed to register OTP NVMEM device\n"); - err = PTR_ERR(nvmem); - goto err; - } -@@ -993,7 +992,7 @@ static int mtd_otp_nvmem_add(struct mtd_ - err: - if (mtd->otp_user_nvmem) - nvmem_unregister(mtd->otp_user_nvmem); -- return err; -+ return dev_err_probe(dev, err, "Failed to register OTP NVMEM device\n"); - } - - /** diff --git a/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch b/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch deleted file mode 100644 index dca1062be9c95b..00000000000000 --- a/target/linux/generic/backport-5.15/600-v5.18-page_pool-Add-allocation-stats.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 8610037e8106b48c79cfe0afb92b2b2466e51c3d Mon Sep 17 00:00:00 2001 -From: Joe Damato -Date: Tue, 1 Mar 2022 23:55:47 -0800 -Subject: [PATCH] page_pool: Add allocation stats - -Add per-pool statistics counters for the allocation path of a page pool. -These stats are incremented in softirq context, so no locking or per-cpu -variables are needed. - -This code is disabled by default and a kernel config option is provided for -users who wish to enable them. - -The statistics added are: - - fast: successful fast path allocations - - slow: slow path order-0 allocations - - slow_high_order: slow path high order allocations - - empty: ptr ring is empty, so a slow path allocation was forced. - - refill: an allocation which triggered a refill of the cache - - waive: pages obtained from the ptr ring that cannot be added to - the cache due to a NUMA mismatch. - -Signed-off-by: Joe Damato -Acked-by: Jesper Dangaard Brouer -Reviewed-by: Ilias Apalodimas -Signed-off-by: David S. Miller ---- - include/net/page_pool.h | 18 ++++++++++++++++++ - net/Kconfig | 13 +++++++++++++ - net/core/page_pool.c | 24 ++++++++++++++++++++---- - 3 files changed, 51 insertions(+), 4 deletions(-) - ---- a/include/net/page_pool.h -+++ b/include/net/page_pool.h -@@ -82,6 +82,19 @@ struct page_pool_params { - unsigned int offset; /* DMA addr offset */ - }; - -+#ifdef CONFIG_PAGE_POOL_STATS -+struct page_pool_alloc_stats { -+ u64 fast; /* fast path allocations */ -+ u64 slow; /* slow-path order 0 allocations */ -+ u64 slow_high_order; /* slow-path high order allocations */ -+ u64 empty; /* failed refills due to empty ptr ring, forcing -+ * slow path allocation -+ */ -+ u64 refill; /* allocations via successful refill */ -+ u64 waive; /* failed refills due to numa zone mismatch */ -+}; -+#endif -+ - struct page_pool { - struct page_pool_params p; - -@@ -132,6 +145,11 @@ struct page_pool { - refcount_t user_cnt; - - u64 destroy_cnt; -+ -+#ifdef CONFIG_PAGE_POOL_STATS -+ /* these stats are incremented while in softirq context */ -+ struct page_pool_alloc_stats alloc_stats; -+#endif - }; - - struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp); ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -432,6 +432,19 @@ config NET_DEVLINK - config PAGE_POOL - bool - -+config PAGE_POOL_STATS -+ default n -+ bool "Page pool stats" -+ depends on PAGE_POOL -+ help -+ Enable page pool statistics to track page allocation and recycling -+ in page pools. This option incurs additional CPU cost in allocation -+ and recycle paths and additional memory cost to store the statistics. -+ These statistics are only available if this option is enabled and if -+ the driver using the page pool supports exporting this data. -+ -+ If unsure, say N. -+ - config FAILOVER - tristate "Generic failover module" - help ---- a/net/core/page_pool.c -+++ b/net/core/page_pool.c -@@ -49,6 +49,13 @@ static void page_pool_producer_unlock(st - spin_unlock_bh(&pool->ring.producer_lock); - } - -+#ifdef CONFIG_PAGE_POOL_STATS -+/* alloc_stat_inc is intended to be used in softirq context */ -+#define alloc_stat_inc(pool, __stat) (pool->alloc_stats.__stat++) -+#else -+#define alloc_stat_inc(pool, __stat) -+#endif -+ - static int page_pool_init(struct page_pool *pool, - const struct page_pool_params *params) - { -@@ -140,8 +147,10 @@ static struct page *page_pool_refill_all - int pref_nid; /* preferred NUMA node */ - - /* Quicker fallback, avoid locks when ring is empty */ -- if (__ptr_ring_empty(r)) -+ if (__ptr_ring_empty(r)) { -+ alloc_stat_inc(pool, empty); - return NULL; -+ } - - /* Softirq guarantee CPU and thus NUMA node is stable. This, - * assumes CPU refilling driver RX-ring will also run RX-NAPI. -@@ -171,14 +180,17 @@ static struct page *page_pool_refill_all - * This limit stress on page buddy alloactor. - */ - page_pool_return_page(pool, page); -+ alloc_stat_inc(pool, waive); - page = NULL; - break; - } - } while (pool->alloc.count < PP_ALLOC_CACHE_REFILL); - - /* Return last page */ -- if (likely(pool->alloc.count > 0)) -+ if (likely(pool->alloc.count > 0)) { - page = pool->alloc.cache[--pool->alloc.count]; -+ alloc_stat_inc(pool, refill); -+ } - - spin_unlock(&r->consumer_lock); - return page; -@@ -193,6 +205,7 @@ static struct page *__page_pool_get_cach - if (likely(pool->alloc.count)) { - /* Fast-path */ - page = pool->alloc.cache[--pool->alloc.count]; -+ alloc_stat_inc(pool, fast); - } else { - page = page_pool_refill_alloc_cache(pool); - } -@@ -264,6 +277,7 @@ static struct page *__page_pool_alloc_pa - return NULL; - } - -+ alloc_stat_inc(pool, slow_high_order); - page_pool_set_pp_info(pool, page); - - /* Track how many pages are held 'in-flight' */ -@@ -318,10 +332,12 @@ static struct page *__page_pool_alloc_pa - } - - /* Return last page */ -- if (likely(pool->alloc.count > 0)) -+ if (likely(pool->alloc.count > 0)) { - page = pool->alloc.cache[--pool->alloc.count]; -- else -+ alloc_stat_inc(pool, slow); -+ } else { - page = NULL; -+ } - - /* When page just alloc'ed is should/must have refcnt 1. */ - return page; diff --git a/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch b/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch deleted file mode 100644 index b425b78c7530c5..00000000000000 --- a/target/linux/generic/backport-5.15/601-v5.18-page_pool-Add-recycle-stats.patch +++ /dev/null @@ -1,140 +0,0 @@ -From ad6fa1e1ab1b8164f1ba296b1b4dc556a483bcad Mon Sep 17 00:00:00 2001 -From: Joe Damato -Date: Tue, 1 Mar 2022 23:55:48 -0800 -Subject: [PATCH 2/3] page_pool: Add recycle stats - -Add per-cpu stats tracking page pool recycling events: - - cached: recycling placed page in the page pool cache - - cache_full: page pool cache was full - - ring: page placed into the ptr ring - - ring_full: page released from page pool because the ptr ring was full - - released_refcnt: page released (and not recycled) because refcnt > 1 - -Signed-off-by: Joe Damato -Acked-by: Jesper Dangaard Brouer -Reviewed-by: Ilias Apalodimas -Signed-off-by: David S. Miller ---- - include/net/page_pool.h | 16 ++++++++++++++++ - net/core/page_pool.c | 30 ++++++++++++++++++++++++++++-- - 2 files changed, 44 insertions(+), 2 deletions(-) - ---- a/include/net/page_pool.h -+++ b/include/net/page_pool.h -@@ -93,6 +93,18 @@ struct page_pool_alloc_stats { - u64 refill; /* allocations via successful refill */ - u64 waive; /* failed refills due to numa zone mismatch */ - }; -+ -+struct page_pool_recycle_stats { -+ u64 cached; /* recycling placed page in the cache. */ -+ u64 cache_full; /* cache was full */ -+ u64 ring; /* recycling placed page back into ptr ring */ -+ u64 ring_full; /* page was released from page-pool because -+ * PTR ring was full. -+ */ -+ u64 released_refcnt; /* page released because of elevated -+ * refcnt -+ */ -+}; - #endif - - struct page_pool { -@@ -136,6 +148,10 @@ struct page_pool { - */ - struct ptr_ring ring; - -+#ifdef CONFIG_PAGE_POOL_STATS -+ /* recycle stats are per-cpu to avoid locking */ -+ struct page_pool_recycle_stats __percpu *recycle_stats; -+#endif - atomic_t pages_state_release_cnt; - - /* A page_pool is strictly tied to a single RX-queue being ---- a/net/core/page_pool.c -+++ b/net/core/page_pool.c -@@ -52,8 +52,15 @@ static void page_pool_producer_unlock(st - #ifdef CONFIG_PAGE_POOL_STATS - /* alloc_stat_inc is intended to be used in softirq context */ - #define alloc_stat_inc(pool, __stat) (pool->alloc_stats.__stat++) -+/* recycle_stat_inc is safe to use when preemption is possible. */ -+#define recycle_stat_inc(pool, __stat) \ -+ do { \ -+ struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \ -+ this_cpu_inc(s->__stat); \ -+ } while (0) - #else - #define alloc_stat_inc(pool, __stat) -+#define recycle_stat_inc(pool, __stat) - #endif - - static int page_pool_init(struct page_pool *pool, -@@ -103,6 +110,12 @@ static int page_pool_init(struct page_po - pool->p.flags & PP_FLAG_PAGE_FRAG) - return -EINVAL; - -+#ifdef CONFIG_PAGE_POOL_STATS -+ pool->recycle_stats = alloc_percpu(struct page_pool_recycle_stats); -+ if (!pool->recycle_stats) -+ return -ENOMEM; -+#endif -+ - if (ptr_ring_init(&pool->ring, ring_qsize, GFP_KERNEL) < 0) - return -ENOMEM; - -@@ -435,7 +448,12 @@ static bool page_pool_recycle_in_ring(st - else - ret = ptr_ring_produce_bh(&pool->ring, page); - -- return (ret == 0) ? true : false; -+ if (!ret) { -+ recycle_stat_inc(pool, ring); -+ return true; -+ } -+ -+ return false; - } - - /* Only allow direct recycling in special circumstances, into the -@@ -446,11 +464,14 @@ static bool page_pool_recycle_in_ring(st - static bool page_pool_recycle_in_cache(struct page *page, - struct page_pool *pool) - { -- if (unlikely(pool->alloc.count == PP_ALLOC_CACHE_SIZE)) -+ if (unlikely(pool->alloc.count == PP_ALLOC_CACHE_SIZE)) { -+ recycle_stat_inc(pool, cache_full); - return false; -+ } - - /* Caller MUST have verified/know (page_ref_count(page) == 1) */ - pool->alloc.cache[pool->alloc.count++] = page; -+ recycle_stat_inc(pool, cached); - return true; - } - -@@ -505,6 +526,7 @@ __page_pool_put_page(struct page_pool *p - * doing refcnt based recycle tricks, meaning another process - * will be invoking put_page. - */ -+ recycle_stat_inc(pool, released_refcnt); - /* Do not replace this with page_pool_return_page() */ - page_pool_release_page(pool, page); - put_page(page); -@@ -518,6 +540,7 @@ void page_pool_put_page(struct page_pool - page = __page_pool_put_page(pool, page, dma_sync_size, allow_direct); - if (page && !page_pool_recycle_in_ring(pool, page)) { - /* Cache full, fallback to free pages */ -+ recycle_stat_inc(pool, ring_full); - page_pool_return_page(pool, page); - } - } -@@ -665,6 +688,9 @@ static void page_pool_free(struct page_p - if (pool->p.flags & PP_FLAG_DMA_MAP) - put_device(pool->p.dev); - -+#ifdef CONFIG_PAGE_POOL_STATS -+ free_percpu(pool->recycle_stats); -+#endif - kfree(pool); - } - diff --git a/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch b/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch deleted file mode 100644 index e1a7635133cd15..00000000000000 --- a/target/linux/generic/backport-5.15/602-v5.18-page_pool-Add-function-to-batch-and-return-stats.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 6b95e3388b1ea0ca63500c5a6e39162dbf828433 Mon Sep 17 00:00:00 2001 -From: Joe Damato -Date: Tue, 1 Mar 2022 23:55:49 -0800 -Subject: [PATCH 3/3] page_pool: Add function to batch and return stats - -Adds a function page_pool_get_stats which can be used by drivers to obtain -stats for a specified page_pool. - -Signed-off-by: Joe Damato -Acked-by: Jesper Dangaard Brouer -Reviewed-by: Ilias Apalodimas -Signed-off-by: David S. Miller ---- - include/net/page_pool.h | 17 +++++++++++++++++ - net/core/page_pool.c | 25 +++++++++++++++++++++++++ - 2 files changed, 42 insertions(+) - ---- a/include/net/page_pool.h -+++ b/include/net/page_pool.h -@@ -105,6 +105,23 @@ struct page_pool_recycle_stats { - * refcnt - */ - }; -+ -+/* This struct wraps the above stats structs so users of the -+ * page_pool_get_stats API can pass a single argument when requesting the -+ * stats for the page pool. -+ */ -+struct page_pool_stats { -+ struct page_pool_alloc_stats alloc_stats; -+ struct page_pool_recycle_stats recycle_stats; -+}; -+ -+/* -+ * Drivers that wish to harvest page pool stats and report them to users -+ * (perhaps via ethtool, debugfs, or another mechanism) can allocate a -+ * struct page_pool_stats call page_pool_get_stats to get stats for the specified pool. -+ */ -+bool page_pool_get_stats(struct page_pool *pool, -+ struct page_pool_stats *stats); - #endif - - struct page_pool { ---- a/net/core/page_pool.c -+++ b/net/core/page_pool.c -@@ -58,6 +58,31 @@ static void page_pool_producer_unlock(st - struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \ - this_cpu_inc(s->__stat); \ - } while (0) -+ -+bool page_pool_get_stats(struct page_pool *pool, -+ struct page_pool_stats *stats) -+{ -+ int cpu = 0; -+ -+ if (!stats) -+ return false; -+ -+ memcpy(&stats->alloc_stats, &pool->alloc_stats, sizeof(pool->alloc_stats)); -+ -+ for_each_possible_cpu(cpu) { -+ const struct page_pool_recycle_stats *pcpu = -+ per_cpu_ptr(pool->recycle_stats, cpu); -+ -+ stats->recycle_stats.cached += pcpu->cached; -+ stats->recycle_stats.cache_full += pcpu->cache_full; -+ stats->recycle_stats.ring += pcpu->ring; -+ stats->recycle_stats.ring_full += pcpu->ring_full; -+ stats->recycle_stats.released_refcnt += pcpu->released_refcnt; -+ } -+ -+ return true; -+} -+EXPORT_SYMBOL(page_pool_get_stats); - #else - #define alloc_stat_inc(pool, __stat) - #define recycle_stat_inc(pool, __stat) diff --git a/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch b/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch deleted file mode 100644 index f438ef3a599794..00000000000000 --- a/target/linux/generic/backport-5.15/603-v5.19-page_pool-Add-recycle-stats-to-page_pool_put_page_bu.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 590032a4d2133ecc10d3078a8db1d85a4842f12c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 11 Apr 2022 16:05:26 +0200 -Subject: [PATCH] page_pool: Add recycle stats to page_pool_put_page_bulk - -Add missing recycle stats to page_pool_put_page_bulk routine. - -Reviewed-by: Joe Damato -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Ilias Apalodimas -Link: https://lore.kernel.org/r/3712178b51c007cfaed910ea80e68f00c916b1fa.1649685634.git.lorenzo@kernel.org -Signed-off-by: Paolo Abeni ---- - net/core/page_pool.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - ---- a/net/core/page_pool.c -+++ b/net/core/page_pool.c -@@ -59,6 +59,12 @@ static void page_pool_producer_unlock(st - this_cpu_inc(s->__stat); \ - } while (0) - -+#define recycle_stat_add(pool, __stat, val) \ -+ do { \ -+ struct page_pool_recycle_stats __percpu *s = pool->recycle_stats; \ -+ this_cpu_add(s->__stat, val); \ -+ } while (0) -+ - bool page_pool_get_stats(struct page_pool *pool, - struct page_pool_stats *stats) - { -@@ -86,6 +92,7 @@ EXPORT_SYMBOL(page_pool_get_stats); - #else - #define alloc_stat_inc(pool, __stat) - #define recycle_stat_inc(pool, __stat) -+#define recycle_stat_add(pool, __stat, val) - #endif - - static int page_pool_init(struct page_pool *pool, -@@ -593,9 +600,13 @@ void page_pool_put_page_bulk(struct page - /* Bulk producer into ptr_ring page_pool cache */ - in_softirq = page_pool_producer_lock(pool); - for (i = 0; i < bulk_len; i++) { -- if (__ptr_ring_produce(&pool->ring, data[i])) -- break; /* ring full */ -+ if (__ptr_ring_produce(&pool->ring, data[i])) { -+ /* ring full */ -+ recycle_stat_inc(pool, ring_full); -+ break; -+ } - } -+ recycle_stat_add(pool, ring, i); - page_pool_producer_unlock(pool, in_softirq); - - /* Hopefully all pages was return into ptr_ring */ diff --git a/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch b/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch deleted file mode 100644 index 3ff136b084265a..00000000000000 --- a/target/linux/generic/backport-5.15/604-v5.19-net-page_pool-introduce-ethtool-stats.patch +++ /dev/null @@ -1,147 +0,0 @@ -From f3c5264f452a5b0ac1de1f2f657efbabdea3c76a Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 12 Apr 2022 18:31:58 +0200 -Subject: [PATCH] net: page_pool: introduce ethtool stats - -Introduce page_pool APIs to report stats through ethtool and reduce -duplicated code in each driver. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Jakub Kicinski -Reviewed-by: Ilias Apalodimas -Signed-off-by: David S. Miller ---- - include/net/page_pool.h | 21 ++++++++++++++ - net/core/page_pool.c | 63 ++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 83 insertions(+), 1 deletion(-) - ---- a/include/net/page_pool.h -+++ b/include/net/page_pool.h -@@ -115,6 +115,10 @@ struct page_pool_stats { - struct page_pool_recycle_stats recycle_stats; - }; - -+int page_pool_ethtool_stats_get_count(void); -+u8 *page_pool_ethtool_stats_get_strings(u8 *data); -+u64 *page_pool_ethtool_stats_get(u64 *data, void *stats); -+ - /* - * Drivers that wish to harvest page pool stats and report them to users - * (perhaps via ethtool, debugfs, or another mechanism) can allocate a -@@ -122,6 +126,23 @@ struct page_pool_stats { - */ - bool page_pool_get_stats(struct page_pool *pool, - struct page_pool_stats *stats); -+#else -+ -+static inline int page_pool_ethtool_stats_get_count(void) -+{ -+ return 0; -+} -+ -+static inline u8 *page_pool_ethtool_stats_get_strings(u8 *data) -+{ -+ return data; -+} -+ -+static inline u64 *page_pool_ethtool_stats_get(u64 *data, void *stats) -+{ -+ return data; -+} -+ - #endif - - struct page_pool { ---- a/net/core/page_pool.c -+++ b/net/core/page_pool.c -@@ -18,6 +18,7 @@ - #include - #include /* for __put_page() */ - #include -+#include - - #include - -@@ -65,6 +66,20 @@ static void page_pool_producer_unlock(st - this_cpu_add(s->__stat, val); \ - } while (0) - -+static const char pp_stats[][ETH_GSTRING_LEN] = { -+ "rx_pp_alloc_fast", -+ "rx_pp_alloc_slow", -+ "rx_pp_alloc_slow_ho", -+ "rx_pp_alloc_empty", -+ "rx_pp_alloc_refill", -+ "rx_pp_alloc_waive", -+ "rx_pp_recycle_cached", -+ "rx_pp_recycle_cache_full", -+ "rx_pp_recycle_ring", -+ "rx_pp_recycle_ring_full", -+ "rx_pp_recycle_released_ref", -+}; -+ - bool page_pool_get_stats(struct page_pool *pool, - struct page_pool_stats *stats) - { -@@ -73,7 +88,13 @@ bool page_pool_get_stats(struct page_poo - if (!stats) - return false; - -- memcpy(&stats->alloc_stats, &pool->alloc_stats, sizeof(pool->alloc_stats)); -+ /* The caller is responsible to initialize stats. */ -+ stats->alloc_stats.fast += pool->alloc_stats.fast; -+ stats->alloc_stats.slow += pool->alloc_stats.slow; -+ stats->alloc_stats.slow_high_order += pool->alloc_stats.slow_high_order; -+ stats->alloc_stats.empty += pool->alloc_stats.empty; -+ stats->alloc_stats.refill += pool->alloc_stats.refill; -+ stats->alloc_stats.waive += pool->alloc_stats.waive; - - for_each_possible_cpu(cpu) { - const struct page_pool_recycle_stats *pcpu = -@@ -89,6 +110,46 @@ bool page_pool_get_stats(struct page_poo - return true; - } - EXPORT_SYMBOL(page_pool_get_stats); -+ -+u8 *page_pool_ethtool_stats_get_strings(u8 *data) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(pp_stats); i++) { -+ memcpy(data, pp_stats[i], ETH_GSTRING_LEN); -+ data += ETH_GSTRING_LEN; -+ } -+ -+ return data; -+} -+EXPORT_SYMBOL(page_pool_ethtool_stats_get_strings); -+ -+int page_pool_ethtool_stats_get_count(void) -+{ -+ return ARRAY_SIZE(pp_stats); -+} -+EXPORT_SYMBOL(page_pool_ethtool_stats_get_count); -+ -+u64 *page_pool_ethtool_stats_get(u64 *data, void *stats) -+{ -+ struct page_pool_stats *pool_stats = stats; -+ -+ *data++ = pool_stats->alloc_stats.fast; -+ *data++ = pool_stats->alloc_stats.slow; -+ *data++ = pool_stats->alloc_stats.slow_high_order; -+ *data++ = pool_stats->alloc_stats.empty; -+ *data++ = pool_stats->alloc_stats.refill; -+ *data++ = pool_stats->alloc_stats.waive; -+ *data++ = pool_stats->recycle_stats.cached; -+ *data++ = pool_stats->recycle_stats.cache_full; -+ *data++ = pool_stats->recycle_stats.ring; -+ *data++ = pool_stats->recycle_stats.ring_full; -+ *data++ = pool_stats->recycle_stats.released_refcnt; -+ -+ return data; -+} -+EXPORT_SYMBOL(page_pool_ethtool_stats_get); -+ - #else - #define alloc_stat_inc(pool, __stat) - #define recycle_stat_inc(pool, __stat) diff --git a/target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch b/target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch deleted file mode 100644 index 4a914404a2f9ec..00000000000000 --- a/target/linux/generic/backport-5.15/605-v5.18-xdp-introduce-flags-field-in-xdp_buff-xdp_frame.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 2e88d4ff03013937028f5397268b21e10cf68713 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 21 Jan 2022 11:09:45 +0100 -Subject: [PATCH] xdp: introduce flags field in xdp_buff/xdp_frame - -Introduce flags field in xdp_frame and xdp_buffer data structures -to define additional buffer features. At the moment the only -supported buffer feature is frags bit (XDP_FLAGS_HAS_FRAGS). -frags bit is used to specify if this is a linear buffer -(XDP_FLAGS_HAS_FRAGS not set) or a frags frame (XDP_FLAGS_HAS_FRAGS -set). In the latter case the driver is expected to initialize the -skb_shared_info structure at the end of the first buffer to link together -subsequent buffers belonging to the same frame. - -Acked-by: Toke Hoiland-Jorgensen -Acked-by: John Fastabend -Acked-by: Jesper Dangaard Brouer -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/e389f14f3a162c0a5bc6a2e1aa8dd01a90be117d.1642758637.git.lorenzo@kernel.org -Signed-off-by: Alexei Starovoitov ---- - include/net/xdp.h | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - ---- a/include/net/xdp.h -+++ b/include/net/xdp.h -@@ -66,6 +66,10 @@ struct xdp_txq_info { - struct net_device *dev; - }; - -+enum xdp_buff_flags { -+ XDP_FLAGS_HAS_FRAGS = BIT(0), /* non-linear xdp buff */ -+}; -+ - struct xdp_buff { - void *data; - void *data_end; -@@ -74,13 +78,30 @@ struct xdp_buff { - struct xdp_rxq_info *rxq; - struct xdp_txq_info *txq; - u32 frame_sz; /* frame size to deduce data_hard_end/reserved tailroom*/ -+ u32 flags; /* supported values defined in xdp_buff_flags */ - }; - -+static __always_inline bool xdp_buff_has_frags(struct xdp_buff *xdp) -+{ -+ return !!(xdp->flags & XDP_FLAGS_HAS_FRAGS); -+} -+ -+static __always_inline void xdp_buff_set_frags_flag(struct xdp_buff *xdp) -+{ -+ xdp->flags |= XDP_FLAGS_HAS_FRAGS; -+} -+ -+static __always_inline void xdp_buff_clear_frags_flag(struct xdp_buff *xdp) -+{ -+ xdp->flags &= ~XDP_FLAGS_HAS_FRAGS; -+} -+ - static __always_inline void - xdp_init_buff(struct xdp_buff *xdp, u32 frame_sz, struct xdp_rxq_info *rxq) - { - xdp->frame_sz = frame_sz; - xdp->rxq = rxq; -+ xdp->flags = 0; - } - - static __always_inline void -@@ -122,8 +143,14 @@ struct xdp_frame { - */ - struct xdp_mem_info mem; - struct net_device *dev_rx; /* used by cpumap */ -+ u32 flags; /* supported values defined in xdp_buff_flags */ - }; - -+static __always_inline bool xdp_frame_has_frags(struct xdp_frame *frame) -+{ -+ return !!(frame->flags & XDP_FLAGS_HAS_FRAGS); -+} -+ - #define XDP_BULK_QUEUE_SIZE 16 - struct xdp_frame_bulk { - int count; -@@ -180,6 +207,7 @@ void xdp_convert_frame_to_buff(struct xd - xdp->data_end = frame->data + frame->len; - xdp->data_meta = frame->data - frame->metasize; - xdp->frame_sz = frame->frame_sz; -+ xdp->flags = frame->flags; - } - - static inline -@@ -206,6 +234,7 @@ int xdp_update_frame_from_buff(struct xd - xdp_frame->headroom = headroom - sizeof(*xdp_frame); - xdp_frame->metasize = metasize; - xdp_frame->frame_sz = xdp->frame_sz; -+ xdp_frame->flags = xdp->flags; - - return 0; - } diff --git a/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch b/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch deleted file mode 100644 index e126b21417f192..00000000000000 --- a/target/linux/generic/backport-5.15/606-v5.18-xdp-add-frags-support-to-xdp_return_-buff-frame.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 7c48cb0176c6d6d3b55029f7ff4ffa05faee6446 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 21 Jan 2022 11:09:50 +0100 -Subject: [PATCH] xdp: add frags support to xdp_return_{buff/frame} - -Take into account if the received xdp_buff/xdp_frame is non-linear -recycling/returning the frame memory to the allocator or into -xdp_frame_bulk. - -Acked-by: Toke Hoiland-Jorgensen -Acked-by: John Fastabend -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/a961069febc868508ce1bdf5e53a343eb4e57cb2.1642758637.git.lorenzo@kernel.org -Signed-off-by: Alexei Starovoitov ---- - include/net/xdp.h | 18 ++++++++++++++-- - net/core/xdp.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 69 insertions(+), 3 deletions(-) - ---- a/include/net/xdp.h -+++ b/include/net/xdp.h -@@ -275,10 +275,24 @@ void __xdp_release_frame(void *data, str - static inline void xdp_release_frame(struct xdp_frame *xdpf) - { - struct xdp_mem_info *mem = &xdpf->mem; -+ struct skb_shared_info *sinfo; -+ int i; - - /* Curr only page_pool needs this */ -- if (mem->type == MEM_TYPE_PAGE_POOL) -- __xdp_release_frame(xdpf->data, mem); -+ if (mem->type != MEM_TYPE_PAGE_POOL) -+ return; -+ -+ if (likely(!xdp_frame_has_frags(xdpf))) -+ goto out; -+ -+ sinfo = xdp_get_shared_info_from_frame(xdpf); -+ for (i = 0; i < sinfo->nr_frags; i++) { -+ struct page *page = skb_frag_page(&sinfo->frags[i]); -+ -+ __xdp_release_frame(page_address(page), mem); -+ } -+out: -+ __xdp_release_frame(xdpf->data, mem); - } - - int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq, ---- a/net/core/xdp.c -+++ b/net/core/xdp.c -@@ -409,12 +409,38 @@ static void __xdp_return(void *data, str - - void xdp_return_frame(struct xdp_frame *xdpf) - { -+ struct skb_shared_info *sinfo; -+ int i; -+ -+ if (likely(!xdp_frame_has_frags(xdpf))) -+ goto out; -+ -+ sinfo = xdp_get_shared_info_from_frame(xdpf); -+ for (i = 0; i < sinfo->nr_frags; i++) { -+ struct page *page = skb_frag_page(&sinfo->frags[i]); -+ -+ __xdp_return(page_address(page), &xdpf->mem, false, NULL); -+ } -+out: - __xdp_return(xdpf->data, &xdpf->mem, false, NULL); - } - EXPORT_SYMBOL_GPL(xdp_return_frame); - - void xdp_return_frame_rx_napi(struct xdp_frame *xdpf) - { -+ struct skb_shared_info *sinfo; -+ int i; -+ -+ if (likely(!xdp_frame_has_frags(xdpf))) -+ goto out; -+ -+ sinfo = xdp_get_shared_info_from_frame(xdpf); -+ for (i = 0; i < sinfo->nr_frags; i++) { -+ struct page *page = skb_frag_page(&sinfo->frags[i]); -+ -+ __xdp_return(page_address(page), &xdpf->mem, true, NULL); -+ } -+out: - __xdp_return(xdpf->data, &xdpf->mem, true, NULL); - } - EXPORT_SYMBOL_GPL(xdp_return_frame_rx_napi); -@@ -450,7 +476,7 @@ void xdp_return_frame_bulk(struct xdp_fr - struct xdp_mem_allocator *xa; - - if (mem->type != MEM_TYPE_PAGE_POOL) { -- __xdp_return(xdpf->data, &xdpf->mem, false, NULL); -+ xdp_return_frame(xdpf); - return; - } - -@@ -469,12 +495,38 @@ void xdp_return_frame_bulk(struct xdp_fr - bq->xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); - } - -+ if (unlikely(xdp_frame_has_frags(xdpf))) { -+ struct skb_shared_info *sinfo; -+ int i; -+ -+ sinfo = xdp_get_shared_info_from_frame(xdpf); -+ for (i = 0; i < sinfo->nr_frags; i++) { -+ skb_frag_t *frag = &sinfo->frags[i]; -+ -+ bq->q[bq->count++] = skb_frag_address(frag); -+ if (bq->count == XDP_BULK_QUEUE_SIZE) -+ xdp_flush_frame_bulk(bq); -+ } -+ } - bq->q[bq->count++] = xdpf->data; - } - EXPORT_SYMBOL_GPL(xdp_return_frame_bulk); - - void xdp_return_buff(struct xdp_buff *xdp) - { -+ struct skb_shared_info *sinfo; -+ int i; -+ -+ if (likely(!xdp_buff_has_frags(xdp))) -+ goto out; -+ -+ sinfo = xdp_get_shared_info_from_buff(xdp); -+ for (i = 0; i < sinfo->nr_frags; i++) { -+ struct page *page = skb_frag_page(&sinfo->frags[i]); -+ -+ __xdp_return(page_address(page), &xdp->rxq->mem, true, xdp); -+ } -+out: - __xdp_return(xdp->data, &xdp->rxq->mem, true, xdp); - } - diff --git a/target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch b/target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch deleted file mode 100644 index 36f55d511ad92a..00000000000000 --- a/target/linux/generic/backport-5.15/607-v5.18-net-skbuff-add-size-metadata-to-skb_shared_info-for-.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d16697cb6261d4cc23422e6b1cb2759df8aa76d0 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 21 Jan 2022 11:09:44 +0100 -Subject: [PATCH] net: skbuff: add size metadata to skb_shared_info for xdp - -Introduce xdp_frags_size field in skb_shared_info data structure -to store xdp_buff/xdp_frame frame paged size (xdp_frags_size will -be used in xdp frags support). In order to not increase -skb_shared_info size we will use a hole due to skb_shared_info -alignment. - -Acked-by: Toke Hoiland-Jorgensen -Acked-by: John Fastabend -Acked-by: Jesper Dangaard Brouer -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/8a849819a3e0a143d540f78a3a5add76e17e980d.1642758637.git.lorenzo@kernel.org -Signed-off-by: Alexei Starovoitov ---- - include/linux/skbuff.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -568,6 +568,7 @@ struct skb_shared_info { - * Warning : all fields before dataref are cleared in __alloc_skb() - */ - atomic_t dataref; -+ unsigned int xdp_frags_size; - - /* Intermediate layers must ensure that destructor_arg - * remains valid until skb destructor */ diff --git a/target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch b/target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch deleted file mode 100644 index 1ec260a2e6a750..00000000000000 --- a/target/linux/generic/backport-5.15/608-v5.18-net-veth-Account-total-xdp_frame-len-running-ndo_xdp.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 5142239a22219921a7863cf00c9ab853c00689d8 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 11 Mar 2022 10:14:18 +0100 -Subject: [PATCH] net: veth: Account total xdp_frame len running ndo_xdp_xmit - -Even if this is a theoretical issue since it is not possible to perform -XDP_REDIRECT on a non-linear xdp_frame, veth driver does not account -paged area in ndo_xdp_xmit function pointer. -Introduce xdp_get_frame_len utility routine to get the xdp_frame full -length and account total frame size running XDP_REDIRECT of a -non-linear xdp frame into a veth device. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Borkmann -Acked-by: Toke Hoiland-Jorgensen -Acked-by: John Fastabend -Link: https://lore.kernel.org/bpf/54f9fd3bb65d190daf2c0bbae2f852ff16cfbaa0.1646989407.git.lorenzo@kernel.org ---- - drivers/net/veth.c | 4 ++-- - include/net/xdp.h | 14 ++++++++++++++ - 2 files changed, 16 insertions(+), 2 deletions(-) - ---- a/drivers/net/veth.c -+++ b/drivers/net/veth.c -@@ -503,7 +503,7 @@ static int veth_xdp_xmit(struct net_devi - struct xdp_frame *frame = frames[i]; - void *ptr = veth_xdp_to_ptr(frame); - -- if (unlikely(frame->len > max_len || -+ if (unlikely(xdp_get_frame_len(frame) > max_len || - __ptr_ring_produce(&rq->xdp_ring, ptr))) - break; - nxmit++; -@@ -864,7 +864,7 @@ static int veth_xdp_rcv(struct veth_rq * - /* ndo_xdp_xmit */ - struct xdp_frame *frame = veth_ptr_to_xdp(ptr); - -- stats->xdp_bytes += frame->len; -+ stats->xdp_bytes += xdp_get_frame_len(frame); - frame = veth_xdp_rcv_one(rq, frame, bq, stats); - if (frame) { - /* XDP_PASS */ ---- a/include/net/xdp.h -+++ b/include/net/xdp.h -@@ -295,6 +295,20 @@ out: - __xdp_release_frame(xdpf->data, mem); - } - -+static __always_inline unsigned int xdp_get_frame_len(struct xdp_frame *xdpf) -+{ -+ struct skb_shared_info *sinfo; -+ unsigned int len = xdpf->len; -+ -+ if (likely(!xdp_frame_has_frags(xdpf))) -+ goto out; -+ -+ sinfo = xdp_get_shared_info_from_frame(xdpf); -+ len += sinfo->xdp_frags_size; -+out: -+ return len; -+} -+ - int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq, - struct net_device *dev, u32 queue_index, unsigned int napi_id); - void xdp_rxq_info_unreg(struct xdp_rxq_info *xdp_rxq); diff --git a/target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch b/target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch deleted file mode 100644 index fd583e80f4eb61..00000000000000 --- a/target/linux/generic/backport-5.15/609-v5.18-veth-Allow-jumbo-frames-in-xdp-mode.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 7cda76d858a4e71ac4a04066c093679a12e1312c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 11 Mar 2022 10:14:20 +0100 -Subject: [PATCH] veth: Allow jumbo frames in xdp mode -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Allow increasing the MTU over page boundaries on veth devices -if the attached xdp program declares to support xdp fragments. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Borkmann -Acked-by: Toke Høiland-Jørgensen -Acked-by: John Fastabend -Link: https://lore.kernel.org/bpf/d5dc039c3d4123426e7023a488c449181a7bc57f.1646989407.git.lorenzo@kernel.org ---- - drivers/net/veth.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - ---- a/drivers/net/veth.c -+++ b/drivers/net/veth.c -@@ -1455,9 +1455,14 @@ static int veth_xdp_set(struct net_devic - goto err; - } - -- max_mtu = PAGE_SIZE - VETH_XDP_HEADROOM - -- peer->hard_header_len - -- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ max_mtu = SKB_WITH_OVERHEAD(PAGE_SIZE - VETH_XDP_HEADROOM) - -+ peer->hard_header_len; -+ /* Allow increasing the max_mtu if the program supports -+ * XDP fragments. -+ */ -+ //if (prog->aux->xdp_has_frags) -+ max_mtu += PAGE_SIZE * MAX_SKB_FRAGS; -+ - if (peer->mtu > max_mtu) { - NL_SET_ERR_MSG_MOD(extack, "Peer MTU is too large to set XDP"); - err = -ERANGE; diff --git a/target/linux/generic/backport-5.15/611-v6.3-net-add-helper-eth_addr_add.patch b/target/linux/generic/backport-5.15/611-v6.3-net-add-helper-eth_addr_add.patch deleted file mode 100644 index c5d5d2c3a9c6ad..00000000000000 --- a/target/linux/generic/backport-5.15/611-v6.3-net-add-helper-eth_addr_add.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7390609b0121a1b982c5ecdfcd72dc328e5784ee Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:42 +0000 -Subject: [PATCH] net: add helper eth_addr_add() - -Add a helper to add an offset to a ethernet address. This comes in handy -if you have a base ethernet address for multiple interfaces. - -Signed-off-by: Michael Walle -Reviewed-by: Andrew Lunn -Acked-by: Jakub Kicinski -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - include/linux/etherdevice.h | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/include/linux/etherdevice.h -+++ b/include/linux/etherdevice.h -@@ -478,6 +478,20 @@ static inline void eth_addr_inc(u8 *addr - } - - /** -+ * eth_addr_add() - Add (or subtract) an offset to/from the given MAC address. -+ * -+ * @offset: Offset to add. -+ * @addr: Pointer to a six-byte array containing Ethernet address to increment. -+ */ -+static inline void eth_addr_add(u8 *addr, long offset) -+{ -+ u64 u = ether_addr_to_u64(addr); -+ -+ u += offset; -+ u64_to_ether_addr(u, addr); -+} -+ -+/** - * is_etherdev_addr - Tell if given Ethernet address belongs to the device. - * @dev: Pointer to a device structure - * @addr: Pointer to a six-byte array containing the Ethernet address diff --git a/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch b/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch deleted file mode 100644 index 8e5c7180424eeb..00000000000000 --- a/target/linux/generic/backport-5.15/700-v5.17-net-dsa-introduce-tagger-owned-storage-for-private.patch +++ /dev/null @@ -1,279 +0,0 @@ -From dc452a471dbae8aca8257c565174212620880093 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 10 Dec 2021 01:34:37 +0200 -Subject: net: dsa: introduce tagger-owned storage for private and shared data - -Ansuel is working on register access over Ethernet for the qca8k switch -family. This requires the qca8k tagging protocol driver to receive -frames which aren't intended for the network stack, but instead for the -qca8k switch driver itself. - -The dp->priv is currently the prevailing method for passing data back -and forth between the tagging protocol driver and the switch driver. -However, this method is riddled with caveats. - -The DSA design allows in principle for any switch driver to return any -protocol it desires in ->get_tag_protocol(). The dsa_loop driver can be -modified to do just that. But in the current design, the memory behind -dp->priv has to be allocated by the switch driver, so if the tagging -protocol is paired to an unexpected switch driver, we may end up in NULL -pointer dereferences inside the kernel, or worse (a switch driver may -allocate dp->priv according to the expectations of a different tagger). - -The latter possibility is even more plausible considering that DSA -switches can dynamically change tagging protocols in certain cases -(dsa <-> edsa, ocelot <-> ocelot-8021q), and the current design lends -itself to mistakes that are all too easy to make. - -This patch proposes that the tagging protocol driver should manage its -own memory, instead of relying on the switch driver to do so. -After analyzing the different in-tree needs, it can be observed that the -required tagger storage is per switch, therefore a ds->tagger_data -pointer is introduced. In principle, per-port storage could also be -introduced, although there is no need for it at the moment. Future -changes will replace the current usage of dp->priv with ds->tagger_data. - -We define a "binding" event between the DSA switch tree and the tagging -protocol. During this binding event, the tagging protocol's ->connect() -method is called first, and this may allocate some memory for each -switch of the tree. Then a cross-chip notifier is emitted for the -switches within that tree, and they are given the opportunity to fix up -the tagger's memory (for example, they might set up some function -pointers that represent virtual methods for consuming packets). -Because the memory is owned by the tagger, there exists a ->disconnect() -method for the tagger (which is the place to free the resources), but -there doesn't exist a ->disconnect() method for the switch driver. -This is part of the design. The switch driver should make minimal use of -the public part of the tagger data, and only after type-checking it -using the supplied "proto" argument. - -In the code there are in fact two binding events, one is the initial -event in dsa_switch_setup_tag_protocol(). At this stage, the cross chip -notifier chains aren't initialized, so we call each switch's connect() -method by hand. Then there is dsa_tree_bind_tag_proto() during -dsa_tree_change_tag_proto(), and here we have an old protocol and a new -one. We first connect to the new one before disconnecting from the old -one, to simplify error handling a bit and to ensure we remain in a valid -state at all times. - -Co-developed-by: Ansuel Smith -Signed-off-by: Ansuel Smith -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - include/net/dsa.h | 12 +++++++++ - net/dsa/dsa2.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++--- - net/dsa/dsa_priv.h | 1 + - net/dsa/switch.c | 14 +++++++++++ - 4 files changed, 96 insertions(+), 4 deletions(-) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -80,12 +80,15 @@ enum dsa_tag_protocol { - }; - - struct dsa_switch; -+struct dsa_switch_tree; - - struct dsa_device_ops { - struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); - struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev); - void (*flow_dissect)(const struct sk_buff *skb, __be16 *proto, - int *offset); -+ int (*connect)(struct dsa_switch_tree *dst); -+ void (*disconnect)(struct dsa_switch_tree *dst); - unsigned int needed_headroom; - unsigned int needed_tailroom; - const char *name; -@@ -329,6 +332,8 @@ struct dsa_switch { - */ - void *priv; - -+ void *tagger_data; -+ - /* - * Configuration data for this switch. - */ -@@ -612,6 +617,13 @@ struct dsa_switch_ops { - enum dsa_tag_protocol mprot); - int (*change_tag_protocol)(struct dsa_switch *ds, int port, - enum dsa_tag_protocol proto); -+ /* -+ * Method for switch drivers to connect to the tagging protocol driver -+ * in current use. The switch driver can provide handlers for certain -+ * types of packets for switch management. -+ */ -+ int (*connect_tag_protocol)(struct dsa_switch *ds, -+ enum dsa_tag_protocol proto); - - /* Optional switch-wide initialization and destruction methods */ - int (*setup)(struct dsa_switch *ds); ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -230,8 +230,12 @@ static struct dsa_switch_tree *dsa_tree_ - - static void dsa_tree_free(struct dsa_switch_tree *dst) - { -- if (dst->tag_ops) -+ if (dst->tag_ops) { -+ if (dst->tag_ops->disconnect) -+ dst->tag_ops->disconnect(dst); -+ - dsa_tag_driver_put(dst->tag_ops); -+ } - list_del(&dst->list); - kfree(dst); - } -@@ -827,7 +831,7 @@ static int dsa_switch_setup_tag_protocol - int port, err; - - if (tag_ops->proto == dst->default_proto) -- return 0; -+ goto connect; - - for (port = 0; port < ds->num_ports; port++) { - if (!dsa_is_cpu_port(ds, port)) -@@ -843,6 +847,17 @@ static int dsa_switch_setup_tag_protocol - } - } - -+connect: -+ if (ds->ops->connect_tag_protocol) { -+ err = ds->ops->connect_tag_protocol(ds, tag_ops->proto); -+ if (err) { -+ dev_err(ds->dev, -+ "Unable to connect to tag protocol \"%s\": %pe\n", -+ tag_ops->name, ERR_PTR(err)); -+ return err; -+ } -+ } -+ - return 0; - } - -@@ -1154,6 +1169,46 @@ static void dsa_tree_teardown(struct dsa - dst->setup = false; - } - -+static int dsa_tree_bind_tag_proto(struct dsa_switch_tree *dst, -+ const struct dsa_device_ops *tag_ops) -+{ -+ const struct dsa_device_ops *old_tag_ops = dst->tag_ops; -+ struct dsa_notifier_tag_proto_info info; -+ int err; -+ -+ dst->tag_ops = tag_ops; -+ -+ /* Notify the new tagger about the connection to this tree */ -+ if (tag_ops->connect) { -+ err = tag_ops->connect(dst); -+ if (err) -+ goto out_revert; -+ } -+ -+ /* Notify the switches from this tree about the connection -+ * to the new tagger -+ */ -+ info.tag_ops = tag_ops; -+ err = dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO_CONNECT, &info); -+ if (err && err != -EOPNOTSUPP) -+ goto out_disconnect; -+ -+ /* Notify the old tagger about the disconnection from this tree */ -+ if (old_tag_ops->disconnect) -+ old_tag_ops->disconnect(dst); -+ -+ return 0; -+ -+out_disconnect: -+ /* Revert the new tagger's connection to this tree */ -+ if (tag_ops->disconnect) -+ tag_ops->disconnect(dst); -+out_revert: -+ dst->tag_ops = old_tag_ops; -+ -+ return err; -+} -+ - /* Since the dsa/tagging sysfs device attribute is per master, the assumption - * is that all DSA switches within a tree share the same tagger, otherwise - * they would have formed disjoint trees (different "dsa,member" values). -@@ -1186,12 +1241,15 @@ int dsa_tree_change_tag_proto(struct dsa - goto out_unlock; - } - -+ /* Notify the tag protocol change */ - info.tag_ops = tag_ops; - err = dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO, &info); - if (err) -- goto out_unwind_tagger; -+ return err; - -- dst->tag_ops = tag_ops; -+ err = dsa_tree_bind_tag_proto(dst, tag_ops); -+ if (err) -+ goto out_unwind_tagger; - - rtnl_unlock(); - -@@ -1279,6 +1337,7 @@ static int dsa_port_parse_cpu(struct dsa - struct dsa_switch *ds = dp->ds; - struct dsa_switch_tree *dst = ds->dst; - enum dsa_tag_protocol default_proto; -+ int err; - - /* Find out which protocol the switch would prefer. */ - default_proto = dsa_get_tag_protocol(dp, master); -@@ -1333,6 +1392,12 @@ static int dsa_port_parse_cpu(struct dsa - */ - dsa_tag_driver_put(tag_ops); - } else { -+ if (tag_ops->connect) { -+ err = tag_ops->connect(dst); -+ if (err) -+ return err; -+ } -+ - dst->tag_ops = tag_ops; - } - ---- a/net/dsa/dsa_priv.h -+++ b/net/dsa/dsa_priv.h -@@ -37,6 +37,7 @@ enum { - DSA_NOTIFIER_VLAN_DEL, - DSA_NOTIFIER_MTU, - DSA_NOTIFIER_TAG_PROTO, -+ DSA_NOTIFIER_TAG_PROTO_CONNECT, - DSA_NOTIFIER_MRP_ADD, - DSA_NOTIFIER_MRP_DEL, - DSA_NOTIFIER_MRP_ADD_RING_ROLE, ---- a/net/dsa/switch.c -+++ b/net/dsa/switch.c -@@ -616,6 +616,17 @@ static int dsa_switch_change_tag_proto(s - return 0; - } - -+static int dsa_switch_connect_tag_proto(struct dsa_switch *ds, -+ struct dsa_notifier_tag_proto_info *info) -+{ -+ const struct dsa_device_ops *tag_ops = info->tag_ops; -+ -+ if (!ds->ops->connect_tag_protocol) -+ return -EOPNOTSUPP; -+ -+ return ds->ops->connect_tag_protocol(ds, tag_ops->proto); -+} -+ - static int dsa_switch_mrp_add(struct dsa_switch *ds, - struct dsa_notifier_mrp_info *info) - { -@@ -735,6 +746,9 @@ static int dsa_switch_event(struct notif - case DSA_NOTIFIER_TAG_PROTO: - err = dsa_switch_change_tag_proto(ds, info); - break; -+ case DSA_NOTIFIER_TAG_PROTO_CONNECT: -+ err = dsa_switch_connect_tag_proto(ds, info); -+ break; - case DSA_NOTIFIER_MRP_ADD: - err = dsa_switch_mrp_add(ds, info); - break; diff --git a/target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch b/target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch deleted file mode 100644 index 8c81ebc7f50e08..00000000000000 --- a/target/linux/generic/backport-5.15/701-v5.17-dsa-make-tagging-protocols-connect-to-individual-switches.patch +++ /dev/null @@ -1,274 +0,0 @@ -From 7f2973149c22e7a6fee4c0c9fa6b8e4108e9c208 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 14 Dec 2021 03:45:36 +0200 -Subject: net: dsa: make tagging protocols connect to individual switches from - a tree - -On the NXP Bluebox 3 board which uses a multi-switch setup with sja1105, -the mechanism through which the tagger connects to the switch tree is -broken, due to improper DSA code design. At the time when tag_ops->connect() -is called in dsa_port_parse_cpu(), DSA hasn't finished "touching" all -the ports, so it doesn't know how large the tree is and how many ports -it has. It has just seen the first CPU port by this time. As a result, -this function will call the tagger's ->connect method too early, and the -tagger will connect only to the first switch from the tree. - -This could be perhaps addressed a bit more simply by just moving the -tag_ops->connect(dst) call a bit later (for example in dsa_tree_setup), -but there is already a design inconsistency at present: on the switch -side, the notification is on a per-switch basis, but on the tagger side, -it is on a per-tree basis. Furthermore, the persistent storage itself is -per switch (ds->tagger_data). And the tagger connect and disconnect -procedures (at least the ones that exist currently) could see a fair bit -of simplification if they didn't have to iterate through the switches of -a tree. - -To fix the issue, this change transforms tag_ops->connect(dst) into -tag_ops->connect(ds) and moves it somewhere where we already iterate -over all switches of a tree. That is in dsa_switch_setup_tag_protocol(), -which is a good placement because we already have there the connection -call to the switch side of things. - -As for the dsa_tree_bind_tag_proto() method (called from the code path -that changes the tag protocol), things are a bit more complicated -because we receive the tree as argument, yet when we unwind on errors, -it would be nice to not call tag_ops->disconnect(ds) where we didn't -previously call tag_ops->connect(ds). We didn't have this problem before -because the tag_ops connection operations passed the entire dst before, -and this is more fine grained now. To solve the error rewind case using -the new API, we have to create yet one more cross-chip notifier for -disconnection, and stay connected with the old tag protocol to all the -switches in the tree until we've succeeded to connect with the new one -as well. So if something fails half way, the whole tree is still -connected to the old tagger. But there may still be leaks if the tagger -fails to connect to the 2nd out of 3 switches in a tree: somebody needs -to tell the tagger to disconnect from the first switch. Nothing comes -for free, and this was previously handled privately by the tagging -protocol driver before, but now we need to emit a disconnect cross-chip -notifier for that, because DSA has to take care of the unwind path. We -assume that the tagging protocol has connected to a switch if it has set -ds->tagger_data to something, otherwise we avoid calling its -disconnection method in the error rewind path. - -The rest of the changes are in the tagging protocol drivers, and have to -do with the replacement of dst with ds. The iteration is removed and the -error unwind path is simplified, as mentioned above. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - include/net/dsa.h | 5 ++-- - net/dsa/dsa2.c | 44 +++++++++++++----------------- - net/dsa/dsa_priv.h | 1 + - net/dsa/switch.c | 52 ++++++++++++++++++++++++++++++++--- - net/dsa/tag_ocelot_8021q.c | 53 +++++++++++------------------------- - net/dsa/tag_sja1105.c | 67 ++++++++++++++++------------------------------ - 6 files changed, 109 insertions(+), 113 deletions(-) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -80,15 +80,14 @@ enum dsa_tag_protocol { - }; - - struct dsa_switch; --struct dsa_switch_tree; - - struct dsa_device_ops { - struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); - struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev); - void (*flow_dissect)(const struct sk_buff *skb, __be16 *proto, - int *offset); -- int (*connect)(struct dsa_switch_tree *dst); -- void (*disconnect)(struct dsa_switch_tree *dst); -+ int (*connect)(struct dsa_switch *ds); -+ void (*disconnect)(struct dsa_switch *ds); - unsigned int needed_headroom; - unsigned int needed_tailroom; - const char *name; ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -230,12 +230,8 @@ static struct dsa_switch_tree *dsa_tree_ - - static void dsa_tree_free(struct dsa_switch_tree *dst) - { -- if (dst->tag_ops) { -- if (dst->tag_ops->disconnect) -- dst->tag_ops->disconnect(dst); -- -+ if (dst->tag_ops) - dsa_tag_driver_put(dst->tag_ops); -- } - list_del(&dst->list); - kfree(dst); - } -@@ -848,17 +844,29 @@ static int dsa_switch_setup_tag_protocol - } - - connect: -+ if (tag_ops->connect) { -+ err = tag_ops->connect(ds); -+ if (err) -+ return err; -+ } -+ - if (ds->ops->connect_tag_protocol) { - err = ds->ops->connect_tag_protocol(ds, tag_ops->proto); - if (err) { - dev_err(ds->dev, - "Unable to connect to tag protocol \"%s\": %pe\n", - tag_ops->name, ERR_PTR(err)); -- return err; -+ goto disconnect; - } - } - - return 0; -+ -+disconnect: -+ if (tag_ops->disconnect) -+ tag_ops->disconnect(ds); -+ -+ return err; - } - - static int dsa_switch_setup(struct dsa_switch *ds) -@@ -1178,13 +1186,6 @@ static int dsa_tree_bind_tag_proto(struc - - dst->tag_ops = tag_ops; - -- /* Notify the new tagger about the connection to this tree */ -- if (tag_ops->connect) { -- err = tag_ops->connect(dst); -- if (err) -- goto out_revert; -- } -- - /* Notify the switches from this tree about the connection - * to the new tagger - */ -@@ -1194,16 +1195,14 @@ static int dsa_tree_bind_tag_proto(struc - goto out_disconnect; - - /* Notify the old tagger about the disconnection from this tree */ -- if (old_tag_ops->disconnect) -- old_tag_ops->disconnect(dst); -+ info.tag_ops = old_tag_ops; -+ dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO_DISCONNECT, &info); - - return 0; - - out_disconnect: -- /* Revert the new tagger's connection to this tree */ -- if (tag_ops->disconnect) -- tag_ops->disconnect(dst); --out_revert: -+ info.tag_ops = tag_ops; -+ dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO_DISCONNECT, &info); - dst->tag_ops = old_tag_ops; - - return err; -@@ -1337,7 +1336,6 @@ static int dsa_port_parse_cpu(struct dsa - struct dsa_switch *ds = dp->ds; - struct dsa_switch_tree *dst = ds->dst; - enum dsa_tag_protocol default_proto; -- int err; - - /* Find out which protocol the switch would prefer. */ - default_proto = dsa_get_tag_protocol(dp, master); -@@ -1392,12 +1390,6 @@ static int dsa_port_parse_cpu(struct dsa - */ - dsa_tag_driver_put(tag_ops); - } else { -- if (tag_ops->connect) { -- err = tag_ops->connect(dst); -- if (err) -- return err; -- } -- - dst->tag_ops = tag_ops; - } - ---- a/net/dsa/dsa_priv.h -+++ b/net/dsa/dsa_priv.h -@@ -38,6 +38,7 @@ enum { - DSA_NOTIFIER_MTU, - DSA_NOTIFIER_TAG_PROTO, - DSA_NOTIFIER_TAG_PROTO_CONNECT, -+ DSA_NOTIFIER_TAG_PROTO_DISCONNECT, - DSA_NOTIFIER_MRP_ADD, - DSA_NOTIFIER_MRP_DEL, - DSA_NOTIFIER_MRP_ADD_RING_ROLE, ---- a/net/dsa/switch.c -+++ b/net/dsa/switch.c -@@ -616,15 +616,58 @@ static int dsa_switch_change_tag_proto(s - return 0; - } - --static int dsa_switch_connect_tag_proto(struct dsa_switch *ds, -- struct dsa_notifier_tag_proto_info *info) -+/* We use the same cross-chip notifiers to inform both the tagger side, as well -+ * as the switch side, of connection and disconnection events. -+ * Since ds->tagger_data is owned by the tagger, it isn't a hard error if the -+ * switch side doesn't support connecting to this tagger, and therefore, the -+ * fact that we don't disconnect the tagger side doesn't constitute a memory -+ * leak: the tagger will still operate with persistent per-switch memory, just -+ * with the switch side unconnected to it. What does constitute a hard error is -+ * when the switch side supports connecting but fails. -+ */ -+static int -+dsa_switch_connect_tag_proto(struct dsa_switch *ds, -+ struct dsa_notifier_tag_proto_info *info) - { - const struct dsa_device_ops *tag_ops = info->tag_ops; -+ int err; -+ -+ /* Notify the new tagger about the connection to this switch */ -+ if (tag_ops->connect) { -+ err = tag_ops->connect(ds); -+ if (err) -+ return err; -+ } - - if (!ds->ops->connect_tag_protocol) - return -EOPNOTSUPP; - -- return ds->ops->connect_tag_protocol(ds, tag_ops->proto); -+ /* Notify the switch about the connection to the new tagger */ -+ err = ds->ops->connect_tag_protocol(ds, tag_ops->proto); -+ if (err) { -+ /* Revert the new tagger's connection to this tree */ -+ if (tag_ops->disconnect) -+ tag_ops->disconnect(ds); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int -+dsa_switch_disconnect_tag_proto(struct dsa_switch *ds, -+ struct dsa_notifier_tag_proto_info *info) -+{ -+ const struct dsa_device_ops *tag_ops = info->tag_ops; -+ -+ /* Notify the tagger about the disconnection from this switch */ -+ if (tag_ops->disconnect && ds->tagger_data) -+ tag_ops->disconnect(ds); -+ -+ /* No need to notify the switch, since it shouldn't have any -+ * resources to tear down -+ */ -+ return 0; - } - - static int dsa_switch_mrp_add(struct dsa_switch *ds, -@@ -749,6 +792,9 @@ static int dsa_switch_event(struct notif - case DSA_NOTIFIER_TAG_PROTO_CONNECT: - err = dsa_switch_connect_tag_proto(ds, info); - break; -+ case DSA_NOTIFIER_TAG_PROTO_DISCONNECT: -+ err = dsa_switch_disconnect_tag_proto(ds, info); -+ break; - case DSA_NOTIFIER_MRP_ADD: - err = dsa_switch_mrp_add(ds, info); - break; diff --git a/target/linux/generic/backport-5.15/702-v5.19-00-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch b/target/linux/generic/backport-5.15/702-v5.19-00-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch deleted file mode 100644 index 2bace3baac87b3..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-00-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch +++ /dev/null @@ -1,327 +0,0 @@ -From: Felix Fietkau -Date: Sat, 5 Feb 2022 17:59:07 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for coherent - DMA - -It improves performance by eliminating the need for a cache flush on rx and tx -In preparation for supporting WED (Wireless Ethernet Dispatch), also add a -function for disabling coherent DMA at runtime. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -850,7 +851,7 @@ static int mtk_init_fq_dma(struct mtk_et - dma_addr_t dma_addr; - int i; - -- eth->scratch_ring = dma_alloc_coherent(eth->dev, -+ eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, - cnt * sizeof(struct mtk_tx_dma), - ð->phy_scratch_ring, - GFP_ATOMIC); -@@ -862,10 +863,10 @@ static int mtk_init_fq_dma(struct mtk_et - if (unlikely(!eth->scratch_head)) - return -ENOMEM; - -- dma_addr = dma_map_single(eth->dev, -+ dma_addr = dma_map_single(eth->dma_dev, - eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE, - DMA_FROM_DEVICE); -- if (unlikely(dma_mapping_error(eth->dev, dma_addr))) -+ if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) - return -ENOMEM; - - phy_ring_tail = eth->phy_scratch_ring + -@@ -919,26 +920,26 @@ static void mtk_tx_unmap(struct mtk_eth - { - if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { - if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) { -- dma_unmap_single(eth->dev, -+ dma_unmap_single(eth->dma_dev, - dma_unmap_addr(tx_buf, dma_addr0), - dma_unmap_len(tx_buf, dma_len0), - DMA_TO_DEVICE); - } else if (tx_buf->flags & MTK_TX_FLAGS_PAGE0) { -- dma_unmap_page(eth->dev, -+ dma_unmap_page(eth->dma_dev, - dma_unmap_addr(tx_buf, dma_addr0), - dma_unmap_len(tx_buf, dma_len0), - DMA_TO_DEVICE); - } - } else { - if (dma_unmap_len(tx_buf, dma_len0)) { -- dma_unmap_page(eth->dev, -+ dma_unmap_page(eth->dma_dev, - dma_unmap_addr(tx_buf, dma_addr0), - dma_unmap_len(tx_buf, dma_len0), - DMA_TO_DEVICE); - } - - if (dma_unmap_len(tx_buf, dma_len1)) { -- dma_unmap_page(eth->dev, -+ dma_unmap_page(eth->dma_dev, - dma_unmap_addr(tx_buf, dma_addr1), - dma_unmap_len(tx_buf, dma_len1), - DMA_TO_DEVICE); -@@ -1016,9 +1017,9 @@ static int mtk_tx_map(struct sk_buff *sk - if (skb_vlan_tag_present(skb)) - txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb); - -- mapped_addr = dma_map_single(eth->dev, skb->data, -+ mapped_addr = dma_map_single(eth->dma_dev, skb->data, - skb_headlen(skb), DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(eth->dev, mapped_addr))) -+ if (unlikely(dma_mapping_error(eth->dma_dev, mapped_addr))) - return -ENOMEM; - - WRITE_ONCE(itxd->txd1, mapped_addr); -@@ -1057,10 +1058,10 @@ static int mtk_tx_map(struct sk_buff *sk - - - frag_map_size = min(frag_size, MTK_TX_DMA_BUF_LEN); -- mapped_addr = skb_frag_dma_map(eth->dev, frag, offset, -+ mapped_addr = skb_frag_dma_map(eth->dma_dev, frag, offset, - frag_map_size, - DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(eth->dev, mapped_addr))) -+ if (unlikely(dma_mapping_error(eth->dma_dev, mapped_addr))) - goto err_dma; - - if (i == nr_frags - 1 && -@@ -1341,18 +1342,18 @@ static int mtk_poll_rx(struct napi_struc - netdev->stats.rx_dropped++; - goto release_desc; - } -- dma_addr = dma_map_single(eth->dev, -+ dma_addr = dma_map_single(eth->dma_dev, - new_data + NET_SKB_PAD + - eth->ip_align, - ring->buf_size, - DMA_FROM_DEVICE); -- if (unlikely(dma_mapping_error(eth->dev, dma_addr))) { -+ if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) { - skb_free_frag(new_data); - netdev->stats.rx_dropped++; - goto release_desc; - } - -- dma_unmap_single(eth->dev, trxd.rxd1, -+ dma_unmap_single(eth->dma_dev, trxd.rxd1, - ring->buf_size, DMA_FROM_DEVICE); - - /* receive data */ -@@ -1625,7 +1626,7 @@ static int mtk_tx_alloc(struct mtk_eth * - if (!ring->buf) - goto no_tx_mem; - -- ring->dma = dma_alloc_coherent(eth->dev, MTK_DMA_SIZE * sz, -+ ring->dma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, - &ring->phys, GFP_ATOMIC); - if (!ring->dma) - goto no_tx_mem; -@@ -1643,7 +1644,7 @@ static int mtk_tx_alloc(struct mtk_eth * - * descriptors in ring->dma_pdma. - */ - if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -- ring->dma_pdma = dma_alloc_coherent(eth->dev, MTK_DMA_SIZE * sz, -+ ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, - &ring->phys_pdma, - GFP_ATOMIC); - if (!ring->dma_pdma) -@@ -1702,7 +1703,7 @@ static void mtk_tx_clean(struct mtk_eth - } - - if (ring->dma) { -- dma_free_coherent(eth->dev, -+ dma_free_coherent(eth->dma_dev, - MTK_DMA_SIZE * sizeof(*ring->dma), - ring->dma, - ring->phys); -@@ -1710,7 +1711,7 @@ static void mtk_tx_clean(struct mtk_eth - } - - if (ring->dma_pdma) { -- dma_free_coherent(eth->dev, -+ dma_free_coherent(eth->dma_dev, - MTK_DMA_SIZE * sizeof(*ring->dma_pdma), - ring->dma_pdma, - ring->phys_pdma); -@@ -1758,18 +1759,18 @@ static int mtk_rx_alloc(struct mtk_eth * - return -ENOMEM; - } - -- ring->dma = dma_alloc_coherent(eth->dev, -+ ring->dma = dma_alloc_coherent(eth->dma_dev, - rx_dma_size * sizeof(*ring->dma), - &ring->phys, GFP_ATOMIC); - if (!ring->dma) - return -ENOMEM; - - for (i = 0; i < rx_dma_size; i++) { -- dma_addr_t dma_addr = dma_map_single(eth->dev, -+ dma_addr_t dma_addr = dma_map_single(eth->dma_dev, - ring->data[i] + NET_SKB_PAD + eth->ip_align, - ring->buf_size, - DMA_FROM_DEVICE); -- if (unlikely(dma_mapping_error(eth->dev, dma_addr))) -+ if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) - return -ENOMEM; - ring->dma[i].rxd1 = (unsigned int)dma_addr; - -@@ -1805,7 +1806,7 @@ static void mtk_rx_clean(struct mtk_eth - continue; - if (!ring->dma[i].rxd1) - continue; -- dma_unmap_single(eth->dev, -+ dma_unmap_single(eth->dma_dev, - ring->dma[i].rxd1, - ring->buf_size, - DMA_FROM_DEVICE); -@@ -1816,7 +1817,7 @@ static void mtk_rx_clean(struct mtk_eth - } - - if (ring->dma) { -- dma_free_coherent(eth->dev, -+ dma_free_coherent(eth->dma_dev, - ring->dma_size * sizeof(*ring->dma), - ring->dma, - ring->phys); -@@ -2175,7 +2176,7 @@ static void mtk_dma_free(struct mtk_eth - if (eth->netdev[i]) - netdev_reset_queue(eth->netdev[i]); - if (eth->scratch_ring) { -- dma_free_coherent(eth->dev, -+ dma_free_coherent(eth->dma_dev, - MTK_DMA_SIZE * sizeof(struct mtk_tx_dma), - eth->scratch_ring, - eth->phy_scratch_ring); -@@ -2527,6 +2528,8 @@ static void mtk_dim_tx(struct work_struc - - static int mtk_hw_init(struct mtk_eth *eth) - { -+ u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | -+ ETHSYS_DMA_AG_MAP_PPE; - int i, val, ret; - - if (test_and_set_bit(MTK_HW_INIT, ð->state)) -@@ -2539,6 +2542,10 @@ static int mtk_hw_init(struct mtk_eth *e - if (ret) - goto err_disable_pm; - -+ if (eth->ethsys) -+ regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask, -+ of_dma_is_coherent(eth->dma_dev->of_node) * dma_mask); -+ - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { - ret = device_reset(eth->dev); - if (ret) { -@@ -3085,6 +3092,35 @@ free_netdev: - return err; - } - -+void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev) -+{ -+ struct net_device *dev, *tmp; -+ LIST_HEAD(dev_list); -+ int i; -+ -+ rtnl_lock(); -+ -+ for (i = 0; i < MTK_MAC_COUNT; i++) { -+ dev = eth->netdev[i]; -+ -+ if (!dev || !(dev->flags & IFF_UP)) -+ continue; -+ -+ list_add_tail(&dev->close_list, &dev_list); -+ } -+ -+ dev_close_many(&dev_list, false); -+ -+ eth->dma_dev = dma_dev; -+ -+ list_for_each_entry_safe(dev, tmp, &dev_list, close_list) { -+ list_del_init(&dev->close_list); -+ dev_open(dev, NULL); -+ } -+ -+ rtnl_unlock(); -+} -+ - static int mtk_probe(struct platform_device *pdev) - { - struct device_node *mac_np; -@@ -3098,6 +3134,7 @@ static int mtk_probe(struct platform_dev - eth->soc = of_device_get_match_data(&pdev->dev); - - eth->dev = &pdev->dev; -+ eth->dma_dev = &pdev->dev; - eth->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(eth->base)) - return PTR_ERR(eth->base); -@@ -3146,6 +3183,16 @@ static int mtk_probe(struct platform_dev - } - } - -+ if (of_dma_is_coherent(pdev->dev.of_node)) { -+ struct regmap *cci; -+ -+ cci = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, -+ "mediatek,cci-control"); -+ /* enable CPU/bus coherency */ -+ if (!IS_ERR(cci)) -+ regmap_write(cci, 0, 3); -+ } -+ - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { - eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii), - GFP_KERNEL); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -463,6 +463,12 @@ - #define RSTCTRL_FE BIT(6) - #define RSTCTRL_PPE BIT(31) - -+/* ethernet dma channel agent map */ -+#define ETHSYS_DMA_AG_MAP 0x408 -+#define ETHSYS_DMA_AG_MAP_PDMA BIT(0) -+#define ETHSYS_DMA_AG_MAP_QDMA BIT(1) -+#define ETHSYS_DMA_AG_MAP_PPE BIT(2) -+ - /* SGMII subsystem config registers */ - /* Register to auto-negotiation restart */ - #define SGMSYS_PCS_CONTROL_1 0x0 -@@ -880,6 +886,7 @@ struct mtk_sgmii { - /* struct mtk_eth - This is the main datasructure for holding the state - * of the driver - * @dev: The device pointer -+ * @dev: The device pointer used for dma mapping/alloc - * @base: The mapped register i/o base - * @page_lock: Make sure that register operations are atomic - * @tx_irq__lock: Make sure that IRQ register operations are atomic -@@ -923,6 +930,7 @@ struct mtk_sgmii { - - struct mtk_eth { - struct device *dev; -+ struct device *dma_dev; - void __iomem *base; - spinlock_t page_lock; - spinlock_t tx_irq_lock; -@@ -1021,6 +1029,7 @@ int mtk_gmac_rgmii_path_setup(struct mtk - int mtk_eth_offload_init(struct mtk_eth *eth); - int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, - void *type_data); -+void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev); - - - #endif /* MTK_ETH_H */ diff --git a/target/linux/generic/backport-5.15/702-v5.19-02-net-ethernet-mtk_eth_soc-add-support-for-Wireless-Et.patch b/target/linux/generic/backport-5.15/702-v5.19-02-net-ethernet-mtk_eth_soc-add-support-for-Wireless-Et.patch deleted file mode 100644 index 85dc9ad6fc6139..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-02-net-ethernet-mtk_eth_soc-add-support-for-Wireless-Et.patch +++ /dev/null @@ -1,1679 +0,0 @@ -From: Felix Fietkau -Date: Sat, 5 Feb 2022 17:56:08 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for Wireless - Ethernet Dispatch (WED) - -The Wireless Ethernet Dispatch subsystem on the MT7622 SoC can be -configured to intercept and handle access to the DMA queues and -PCIe interrupts for a MT7615/MT7915 wireless card. -It can manage the internal WDMA (Wireless DMA) controller, which allows -ethernet packets to be passed from the packet switch engine (PSE) to the -wireless card, bypassing the CPU entirely. -This can be used to implement hardware flow offloading from ethernet to -WLAN. - -Signed-off-by: Felix Fietkau ---- - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed.c - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed.h - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_debugfs.c - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_ops.c - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_regs.h - create mode 100644 include/linux/soc/mediatek/mtk_wed.h - ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -7,6 +7,10 @@ config NET_VENDOR_MEDIATEK - - if NET_VENDOR_MEDIATEK - -+config NET_MEDIATEK_SOC_WED -+ depends on ARCH_MEDIATEK || COMPILE_TEST -+ def_bool NET_MEDIATEK_SOC != n -+ - config NET_MEDIATEK_SOC - tristate "MediaTek SoC Gigabit Ethernet support" - depends on NET_DSA || !NET_DSA ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -5,4 +5,9 @@ - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o - mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o -+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o -+ifdef CONFIG_DEBUG_FS -+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o -+endif -+obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o - obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -24,6 +24,7 @@ - #include - - #include "mtk_eth_soc.h" -+#include "mtk_wed.h" - - static int mtk_msg_level = -1; - module_param_named(msg_level, mtk_msg_level, int, 0); -@@ -3215,6 +3216,22 @@ static int mtk_probe(struct platform_dev - } - } - -+ for (i = 0;; i++) { -+ struct device_node *np = of_parse_phandle(pdev->dev.of_node, -+ "mediatek,wed", i); -+ static const u32 wdma_regs[] = { -+ MTK_WDMA0_BASE, -+ MTK_WDMA1_BASE -+ }; -+ void __iomem *wdma; -+ -+ if (!np || i >= ARRAY_SIZE(wdma_regs)) -+ break; -+ -+ wdma = eth->base + wdma_regs[i]; -+ mtk_wed_add_hw(np, eth, wdma, i); -+ } -+ - for (i = 0; i < 3; i++) { - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT) && i > 0) - eth->irq[i] = eth->irq[0]; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -295,6 +295,9 @@ - #define MTK_GDM1_TX_GPCNT 0x2438 - #define MTK_STAT_OFFSET 0x40 - -+#define MTK_WDMA0_BASE 0x2800 -+#define MTK_WDMA1_BASE 0x2c00 -+ - /* QDMA descriptor txd4 */ - #define TX_DMA_CHKSUM (0x7 << 29) - #define TX_DMA_TSO BIT(28) ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -0,0 +1,875 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* Copyright (C) 2021 Felix Fietkau */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "mtk_eth_soc.h" -+#include "mtk_wed_regs.h" -+#include "mtk_wed.h" -+#include "mtk_ppe.h" -+ -+#define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000) -+ -+#define MTK_WED_PKT_SIZE 1900 -+#define MTK_WED_BUF_SIZE 2048 -+#define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048) -+ -+#define MTK_WED_TX_RING_SIZE 2048 -+#define MTK_WED_WDMA_RING_SIZE 1024 -+ -+static struct mtk_wed_hw *hw_list[2]; -+static DEFINE_MUTEX(hw_lock); -+ -+static void -+wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) -+{ -+ regmap_update_bits(dev->hw->regs, reg, mask | val, val); -+} -+ -+static void -+wed_set(struct mtk_wed_device *dev, u32 reg, u32 mask) -+{ -+ return wed_m32(dev, reg, 0, mask); -+} -+ -+static void -+wed_clr(struct mtk_wed_device *dev, u32 reg, u32 mask) -+{ -+ return wed_m32(dev, reg, mask, 0); -+} -+ -+static void -+wdma_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) -+{ -+ wdma_w32(dev, reg, (wdma_r32(dev, reg) & ~mask) | val); -+} -+ -+static void -+wdma_set(struct mtk_wed_device *dev, u32 reg, u32 mask) -+{ -+ wdma_m32(dev, reg, 0, mask); -+} -+ -+static u32 -+mtk_wed_read_reset(struct mtk_wed_device *dev) -+{ -+ return wed_r32(dev, MTK_WED_RESET); -+} -+ -+static void -+mtk_wed_reset(struct mtk_wed_device *dev, u32 mask) -+{ -+ u32 status; -+ -+ wed_w32(dev, MTK_WED_RESET, mask); -+ if (readx_poll_timeout(mtk_wed_read_reset, dev, status, -+ !(status & mask), 0, 1000)) -+ WARN_ON_ONCE(1); -+} -+ -+static struct mtk_wed_hw * -+mtk_wed_assign(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_hw *hw; -+ -+ hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)]; -+ if (!hw || hw->wed_dev) -+ return NULL; -+ -+ hw->wed_dev = dev; -+ return hw; -+} -+ -+static int -+mtk_wed_buffer_alloc(struct mtk_wed_device *dev) -+{ -+ struct mtk_wdma_desc *desc; -+ dma_addr_t desc_phys; -+ void **page_list; -+ int token = dev->wlan.token_start; -+ int ring_size; -+ int n_pages; -+ int i, page_idx; -+ -+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1); -+ n_pages = ring_size / MTK_WED_BUF_PER_PAGE; -+ -+ page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL); -+ if (!page_list) -+ return -ENOMEM; -+ -+ dev->buf_ring.size = ring_size; -+ dev->buf_ring.pages = page_list; -+ -+ desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc), -+ &desc_phys, GFP_KERNEL); -+ if (!desc) -+ return -ENOMEM; -+ -+ dev->buf_ring.desc = desc; -+ dev->buf_ring.desc_phys = desc_phys; -+ -+ for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) { -+ dma_addr_t page_phys, buf_phys; -+ struct page *page; -+ void *buf; -+ int s; -+ -+ page = __dev_alloc_pages(GFP_KERNEL, 0); -+ if (!page) -+ return -ENOMEM; -+ -+ page_phys = dma_map_page(dev->hw->dev, page, 0, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ if (dma_mapping_error(dev->hw->dev, page_phys)) { -+ __free_page(page); -+ return -ENOMEM; -+ } -+ -+ page_list[page_idx++] = page; -+ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ -+ buf = page_to_virt(page); -+ buf_phys = page_phys; -+ -+ for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) { -+ u32 txd_size; -+ -+ txd_size = dev->wlan.init_buf(buf, buf_phys, token++); -+ -+ desc->buf0 = buf_phys; -+ desc->buf1 = buf_phys + txd_size; -+ desc->ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, -+ txd_size) | -+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -+ MTK_WED_BUF_SIZE - txd_size) | -+ MTK_WDMA_DESC_CTRL_LAST_SEG1; -+ desc->info = 0; -+ desc++; -+ -+ buf += MTK_WED_BUF_SIZE; -+ buf_phys += MTK_WED_BUF_SIZE; -+ } -+ -+ dma_sync_single_for_device(dev->hw->dev, page_phys, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ } -+ -+ return 0; -+} -+ -+static void -+mtk_wed_free_buffer(struct mtk_wed_device *dev) -+{ -+ struct mtk_wdma_desc *desc = dev->buf_ring.desc; -+ void **page_list = dev->buf_ring.pages; -+ int page_idx; -+ int i; -+ -+ if (!page_list) -+ return; -+ -+ if (!desc) -+ goto free_pagelist; -+ -+ for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) { -+ void *page = page_list[page_idx++]; -+ -+ if (!page) -+ break; -+ -+ dma_unmap_page(dev->hw->dev, desc[i].buf0, -+ PAGE_SIZE, DMA_BIDIRECTIONAL); -+ __free_page(page); -+ } -+ -+ dma_free_coherent(dev->hw->dev, dev->buf_ring.size * sizeof(*desc), -+ desc, dev->buf_ring.desc_phys); -+ -+free_pagelist: -+ kfree(page_list); -+} -+ -+static void -+mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring) -+{ -+ if (!ring->desc) -+ return; -+ -+ dma_free_coherent(dev->hw->dev, ring->size * sizeof(*ring->desc), -+ ring->desc, ring->desc_phys); -+} -+ -+static void -+mtk_wed_free_tx_rings(struct mtk_wed_device *dev) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) -+ mtk_wed_free_ring(dev, &dev->tx_ring[i]); -+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -+ mtk_wed_free_ring(dev, &dev->tx_wdma[i]); -+} -+ -+static void -+mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en) -+{ -+ u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; -+ -+ if (!dev->hw->num_flows) -+ mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; -+ -+ wed_w32(dev, MTK_WED_EXT_INT_MASK, en ? mask : 0); -+ wed_r32(dev, MTK_WED_EXT_INT_MASK); -+} -+ -+static void -+mtk_wed_stop(struct mtk_wed_device *dev) -+{ -+ regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); -+ mtk_wed_set_ext_int(dev, false); -+ -+ wed_clr(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WDMA_INT_AGENT_EN | -+ MTK_WED_CTRL_WPDMA_INT_AGENT_EN | -+ MTK_WED_CTRL_WED_TX_BM_EN | -+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0); -+ wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0); -+ wdma_w32(dev, MTK_WDMA_INT_MASK, 0); -+ wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); -+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); -+ -+ wed_clr(dev, MTK_WED_GLO_CFG, -+ MTK_WED_GLO_CFG_TX_DMA_EN | -+ MTK_WED_GLO_CFG_RX_DMA_EN); -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); -+} -+ -+static void -+mtk_wed_detach(struct mtk_wed_device *dev) -+{ -+ struct device_node *wlan_node = dev->wlan.pci_dev->dev.of_node; -+ struct mtk_wed_hw *hw = dev->hw; -+ -+ mutex_lock(&hw_lock); -+ -+ mtk_wed_stop(dev); -+ -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -+ -+ mtk_wed_reset(dev, MTK_WED_RESET_WED); -+ -+ mtk_wed_free_buffer(dev); -+ mtk_wed_free_tx_rings(dev); -+ -+ if (of_dma_is_coherent(wlan_node)) -+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, -+ BIT(hw->index), BIT(hw->index)); -+ -+ if (!hw_list[!hw->index]->wed_dev && -+ hw->eth->dma_dev != hw->eth->dev) -+ mtk_eth_set_dma_device(hw->eth, hw->eth->dev); -+ -+ memset(dev, 0, sizeof(*dev)); -+ module_put(THIS_MODULE); -+ -+ hw->wed_dev = NULL; -+ mutex_unlock(&hw_lock); -+} -+ -+static void -+mtk_wed_hw_init_early(struct mtk_wed_device *dev) -+{ -+ u32 mask, set; -+ u32 offset; -+ -+ mtk_wed_stop(dev); -+ mtk_wed_reset(dev, MTK_WED_RESET_WED); -+ -+ mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE | -+ MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE | -+ MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE; -+ set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) | -+ MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP | -+ MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; -+ wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); -+ -+ wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO_PRERES); -+ -+ offset = dev->hw->index ? 0x04000400 : 0; -+ wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); -+ wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset); -+ -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, MTK_PCIE_BASE(dev->hw->index)); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); -+} -+ -+static void -+mtk_wed_hw_init(struct mtk_wed_device *dev) -+{ -+ if (dev->init_done) -+ return; -+ -+ dev->init_done = true; -+ mtk_wed_set_ext_int(dev, false); -+ wed_w32(dev, MTK_WED_TX_BM_CTRL, -+ MTK_WED_TX_BM_CTRL_PAUSE | -+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, -+ dev->buf_ring.size / 128) | -+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, -+ MTK_WED_TX_RING_SIZE / 256)); -+ -+ wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys); -+ -+ wed_w32(dev, MTK_WED_TX_BM_TKID, -+ FIELD_PREP(MTK_WED_TX_BM_TKID_START, -+ dev->wlan.token_start) | -+ FIELD_PREP(MTK_WED_TX_BM_TKID_END, -+ dev->wlan.token_start + dev->wlan.nbuf - 1)); -+ -+ wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); -+ -+ wed_w32(dev, MTK_WED_TX_BM_DYN_THR, -+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | -+ MTK_WED_TX_BM_DYN_THR_HI); -+ -+ mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); -+ -+ wed_set(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WED_TX_BM_EN | -+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ -+ wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); -+} -+ -+static void -+mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size) -+{ -+ int i; -+ -+ for (i = 0; i < size; i++) { -+ desc[i].buf0 = 0; -+ desc[i].ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ desc[i].buf1 = 0; -+ desc[i].info = 0; -+ } -+} -+ -+static u32 -+mtk_wed_check_busy(struct mtk_wed_device *dev) -+{ -+ if (wed_r32(dev, MTK_WED_GLO_CFG) & MTK_WED_GLO_CFG_TX_DMA_BUSY) -+ return true; -+ -+ if (wed_r32(dev, MTK_WED_WPDMA_GLO_CFG) & -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY) -+ return true; -+ -+ if (wed_r32(dev, MTK_WED_CTRL) & MTK_WED_CTRL_WDMA_INT_AGENT_BUSY) -+ return true; -+ -+ if (wed_r32(dev, MTK_WED_WDMA_GLO_CFG) & -+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY) -+ return true; -+ -+ if (wdma_r32(dev, MTK_WDMA_GLO_CFG) & -+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY) -+ return true; -+ -+ if (wed_r32(dev, MTK_WED_CTRL) & -+ (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY)) -+ return true; -+ -+ return false; -+} -+ -+static int -+mtk_wed_poll_busy(struct mtk_wed_device *dev) -+{ -+ int sleep = 15000; -+ int timeout = 100 * sleep; -+ u32 val; -+ -+ return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep, -+ timeout, false, dev); -+} -+ -+static void -+mtk_wed_reset_dma(struct mtk_wed_device *dev) -+{ -+ bool busy = false; -+ u32 val; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) { -+ struct mtk_wdma_desc *desc = dev->tx_ring[i].desc; -+ -+ if (!desc) -+ continue; -+ -+ mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE); -+ } -+ -+ if (mtk_wed_poll_busy(dev)) -+ busy = mtk_wed_check_busy(dev); -+ -+ if (busy) { -+ mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA); -+ } else { -+ wed_w32(dev, MTK_WED_RESET_IDX, -+ MTK_WED_RESET_IDX_TX | -+ MTK_WED_RESET_IDX_RX); -+ wed_w32(dev, MTK_WED_RESET_IDX, 0); -+ } -+ -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -+ -+ if (busy) { -+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); -+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV); -+ } else { -+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX, -+ MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV); -+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0); -+ -+ wed_set(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE); -+ -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE); -+ } -+ -+ for (i = 0; i < 100; i++) { -+ val = wed_r32(dev, MTK_WED_TX_BM_INTF); -+ if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40) -+ break; -+ } -+ -+ mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT); -+ mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); -+ -+ if (busy) { -+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); -+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV); -+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV); -+ } else { -+ wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, -+ MTK_WED_WPDMA_RESET_IDX_TX | -+ MTK_WED_WPDMA_RESET_IDX_RX); -+ wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0); -+ } -+ -+} -+ -+static int -+mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, -+ int size) -+{ -+ ring->desc = dma_alloc_coherent(dev->hw->dev, -+ size * sizeof(*ring->desc), -+ &ring->desc_phys, GFP_KERNEL); -+ if (!ring->desc) -+ return -ENOMEM; -+ -+ ring->size = size; -+ mtk_wed_ring_reset(ring->desc, size); -+ -+ return 0; -+} -+ -+static int -+mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size) -+{ -+ struct mtk_wed_ring *wdma = &dev->tx_wdma[idx]; -+ -+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE)) -+ return -ENOMEM; -+ -+ wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -+ wdma->desc_phys); -+ wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_COUNT, -+ size); -+ wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0); -+ -+ wed_w32(dev, MTK_WED_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -+ wdma->desc_phys); -+ wed_w32(dev, MTK_WED_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_COUNT, -+ size); -+ -+ return 0; -+} -+ -+static void -+mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) -+{ -+ u32 wdma_mask; -+ u32 val; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -+ if (!dev->tx_wdma[i].desc) -+ mtk_wed_wdma_ring_setup(dev, i, 16); -+ -+ wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0)); -+ -+ mtk_wed_hw_init(dev); -+ -+ wed_set(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WDMA_INT_AGENT_EN | -+ MTK_WED_CTRL_WPDMA_INT_AGENT_EN | -+ MTK_WED_CTRL_WED_TX_BM_EN | -+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, MTK_WED_PCIE_INT_TRIGGER_STATUS); -+ -+ wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, -+ MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | -+ MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); -+ -+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, -+ MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); -+ -+ wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask); -+ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); -+ -+ wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask); -+ wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask); -+ -+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask); -+ wed_w32(dev, MTK_WED_INT_MASK, irq_mask); -+ -+ wed_set(dev, MTK_WED_GLO_CFG, -+ MTK_WED_GLO_CFG_TX_DMA_EN | -+ MTK_WED_GLO_CFG_RX_DMA_EN); -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -+ wed_set(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); -+ -+ mtk_wed_set_ext_int(dev, true); -+ val = dev->wlan.wpdma_phys | -+ MTK_PCIE_MIRROR_MAP_EN | -+ FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, dev->hw->index); -+ -+ if (dev->hw->index) -+ val |= BIT(1); -+ val |= BIT(0); -+ regmap_write(dev->hw->mirror, dev->hw->index * 4, val); -+ -+ dev->running = true; -+} -+ -+static int -+mtk_wed_attach(struct mtk_wed_device *dev) -+ __releases(RCU) -+{ -+ struct mtk_wed_hw *hw; -+ int ret = 0; -+ -+ RCU_LOCKDEP_WARN(!rcu_read_lock_held(), -+ "mtk_wed_attach without holding the RCU read lock"); -+ -+ if (pci_domain_nr(dev->wlan.pci_dev->bus) > 1 || -+ !try_module_get(THIS_MODULE)) -+ ret = -ENODEV; -+ -+ rcu_read_unlock(); -+ -+ if (ret) -+ return ret; -+ -+ mutex_lock(&hw_lock); -+ -+ hw = mtk_wed_assign(dev); -+ if (!hw) { -+ module_put(THIS_MODULE); -+ ret = -ENODEV; -+ goto out; -+ } -+ -+ dev_info(&dev->wlan.pci_dev->dev, "attaching wed device %d\n", hw->index); -+ -+ dev->hw = hw; -+ dev->dev = hw->dev; -+ dev->irq = hw->irq; -+ dev->wdma_idx = hw->index; -+ -+ if (hw->eth->dma_dev == hw->eth->dev && -+ of_dma_is_coherent(hw->eth->dev->of_node)) -+ mtk_eth_set_dma_device(hw->eth, hw->dev); -+ -+ ret = mtk_wed_buffer_alloc(dev); -+ if (ret) { -+ mtk_wed_detach(dev); -+ goto out; -+ } -+ -+ mtk_wed_hw_init_early(dev); -+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, BIT(hw->index), 0); -+ -+out: -+ mutex_unlock(&hw_lock); -+ -+ return ret; -+} -+ -+static int -+mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) -+{ -+ struct mtk_wed_ring *ring = &dev->tx_ring[idx]; -+ -+ /* -+ * Tx ring redirection: -+ * Instead of configuring the WLAN PDMA TX ring directly, the WLAN -+ * driver allocated DMA ring gets configured into WED MTK_WED_RING_TX(n) -+ * registers. -+ * -+ * WED driver posts its own DMA ring as WLAN PDMA TX and configures it -+ * into MTK_WED_WPDMA_RING_TX(n) registers. -+ * It gets filled with packets picked up from WED TX ring and from -+ * WDMA RX. -+ */ -+ -+ BUG_ON(idx > ARRAY_SIZE(dev->tx_ring)); -+ -+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE)) -+ return -ENOMEM; -+ -+ if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -+ return -ENOMEM; -+ -+ ring->reg_base = MTK_WED_RING_TX(idx); -+ ring->wpdma = regs; -+ -+ /* WED -> WPDMA */ -+ wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys); -+ wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_TX_RING_SIZE); -+ wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_CPU_IDX, 0); -+ -+ wed_w32(dev, MTK_WED_WPDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, -+ ring->desc_phys); -+ wed_w32(dev, MTK_WED_WPDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT, -+ MTK_WED_TX_RING_SIZE); -+ wed_w32(dev, MTK_WED_WPDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0); -+ -+ return 0; -+} -+ -+static int -+mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs) -+{ -+ struct mtk_wed_ring *ring = &dev->txfree_ring; -+ int i; -+ -+ /* -+ * For txfree event handling, the same DMA ring is shared between WED -+ * and WLAN. The WLAN driver accesses the ring index registers through -+ * WED -+ */ -+ ring->reg_base = MTK_WED_RING_RX(1); -+ ring->wpdma = regs; -+ -+ for (i = 0; i < 12; i += 4) { -+ u32 val = readl(regs + i); -+ -+ wed_w32(dev, MTK_WED_RING_RX(1) + i, val); -+ wed_w32(dev, MTK_WED_WPDMA_RING_RX(1) + i, val); -+ } -+ -+ return 0; -+} -+ -+static u32 -+mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) -+{ -+ u32 val; -+ -+ val = wed_r32(dev, MTK_WED_EXT_INT_STATUS); -+ wed_w32(dev, MTK_WED_EXT_INT_STATUS, val); -+ val &= MTK_WED_EXT_INT_STATUS_ERROR_MASK; -+ if (!dev->hw->num_flows) -+ val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; -+ if (val && net_ratelimit()) -+ pr_err("mtk_wed%d: error status=%08x\n", dev->hw->index, val); -+ -+ val = wed_r32(dev, MTK_WED_INT_STATUS); -+ val &= mask; -+ wed_w32(dev, MTK_WED_INT_STATUS, val); /* ACK */ -+ -+ return val; -+} -+ -+static void -+mtk_wed_irq_set_mask(struct mtk_wed_device *dev, u32 mask) -+{ -+ if (!dev->running) -+ return; -+ -+ mtk_wed_set_ext_int(dev, !!mask); -+ wed_w32(dev, MTK_WED_INT_MASK, mask); -+} -+ -+int mtk_wed_flow_add(int index) -+{ -+ struct mtk_wed_hw *hw = hw_list[index]; -+ int ret; -+ -+ if (!hw || !hw->wed_dev) -+ return -ENODEV; -+ -+ if (hw->num_flows) { -+ hw->num_flows++; -+ return 0; -+ } -+ -+ mutex_lock(&hw_lock); -+ if (!hw->wed_dev) { -+ ret = -ENODEV; -+ goto out; -+ } -+ -+ ret = hw->wed_dev->wlan.offload_enable(hw->wed_dev); -+ if (!ret) -+ hw->num_flows++; -+ mtk_wed_set_ext_int(hw->wed_dev, true); -+ -+out: -+ mutex_unlock(&hw_lock); -+ -+ return ret; -+} -+ -+void mtk_wed_flow_remove(int index) -+{ -+ struct mtk_wed_hw *hw = hw_list[index]; -+ -+ if (!hw) -+ return; -+ -+ if (--hw->num_flows) -+ return; -+ -+ mutex_lock(&hw_lock); -+ if (!hw->wed_dev) -+ goto out; -+ -+ hw->wed_dev->wlan.offload_disable(hw->wed_dev); -+ mtk_wed_set_ext_int(hw->wed_dev, true); -+ -+out: -+ mutex_unlock(&hw_lock); -+} -+ -+void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -+ void __iomem *wdma, int index) -+{ -+ static const struct mtk_wed_ops wed_ops = { -+ .attach = mtk_wed_attach, -+ .tx_ring_setup = mtk_wed_tx_ring_setup, -+ .txfree_ring_setup = mtk_wed_txfree_ring_setup, -+ .start = mtk_wed_start, -+ .stop = mtk_wed_stop, -+ .reset_dma = mtk_wed_reset_dma, -+ .reg_read = wed_r32, -+ .reg_write = wed_w32, -+ .irq_get = mtk_wed_irq_get, -+ .irq_set_mask = mtk_wed_irq_set_mask, -+ .detach = mtk_wed_detach, -+ }; -+ struct device_node *eth_np = eth->dev->of_node; -+ struct platform_device *pdev; -+ struct mtk_wed_hw *hw; -+ struct regmap *regs; -+ int irq; -+ -+ if (!np) -+ return; -+ -+ pdev = of_find_device_by_node(np); -+ if (!pdev) -+ return; -+ -+ get_device(&pdev->dev); -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return; -+ -+ regs = syscon_regmap_lookup_by_phandle(np, NULL); -+ if (!regs) -+ return; -+ -+ rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops); -+ -+ mutex_lock(&hw_lock); -+ -+ if (WARN_ON(hw_list[index])) -+ goto unlock; -+ -+ hw = kzalloc(sizeof(*hw), GFP_KERNEL); -+ hw->node = np; -+ hw->regs = regs; -+ hw->eth = eth; -+ hw->dev = &pdev->dev; -+ hw->wdma = wdma; -+ hw->index = index; -+ hw->irq = irq; -+ hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, -+ "mediatek,pcie-mirror"); -+ hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, -+ "mediatek,hifsys"); -+ if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) { -+ kfree(hw); -+ goto unlock; -+ } -+ -+ if (!index) { -+ regmap_write(hw->mirror, 0, 0); -+ regmap_write(hw->mirror, 4, 0); -+ } -+ mtk_wed_hw_add_debugfs(hw); -+ -+ hw_list[index] = hw; -+ -+unlock: -+ mutex_unlock(&hw_lock); -+} -+ -+void mtk_wed_exit(void) -+{ -+ int i; -+ -+ rcu_assign_pointer(mtk_soc_wed_ops, NULL); -+ -+ synchronize_rcu(); -+ -+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { -+ struct mtk_wed_hw *hw; -+ -+ hw = hw_list[i]; -+ if (!hw) -+ continue; -+ -+ hw_list[i] = NULL; -+ debugfs_remove(hw->debugfs_dir); -+ put_device(hw->dev); -+ kfree(hw); -+ } -+} ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -0,0 +1,128 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* Copyright (C) 2021 Felix Fietkau */ -+ -+#ifndef __MTK_WED_PRIV_H -+#define __MTK_WED_PRIV_H -+ -+#include -+#include -+#include -+ -+struct mtk_eth; -+ -+struct mtk_wed_hw { -+ struct device_node *node; -+ struct mtk_eth *eth; -+ struct regmap *regs; -+ struct regmap *hifsys; -+ struct device *dev; -+ void __iomem *wdma; -+ struct regmap *mirror; -+ struct dentry *debugfs_dir; -+ struct mtk_wed_device *wed_dev; -+ u32 debugfs_reg; -+ u32 num_flows; -+ char dirname[5]; -+ int irq; -+ int index; -+}; -+ -+ -+#ifdef CONFIG_NET_MEDIATEK_SOC_WED -+static inline void -+wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val) -+{ -+ regmap_write(dev->hw->regs, reg, val); -+} -+ -+static inline u32 -+wed_r32(struct mtk_wed_device *dev, u32 reg) -+{ -+ unsigned int val; -+ -+ regmap_read(dev->hw->regs, reg, &val); -+ -+ return val; -+} -+ -+static inline void -+wdma_w32(struct mtk_wed_device *dev, u32 reg, u32 val) -+{ -+ writel(val, dev->hw->wdma + reg); -+} -+ -+static inline u32 -+wdma_r32(struct mtk_wed_device *dev, u32 reg) -+{ -+ return readl(dev->hw->wdma + reg); -+} -+ -+static inline u32 -+wpdma_tx_r32(struct mtk_wed_device *dev, int ring, u32 reg) -+{ -+ if (!dev->tx_ring[ring].wpdma) -+ return 0; -+ -+ return readl(dev->tx_ring[ring].wpdma + reg); -+} -+ -+static inline void -+wpdma_tx_w32(struct mtk_wed_device *dev, int ring, u32 reg, u32 val) -+{ -+ if (!dev->tx_ring[ring].wpdma) -+ return; -+ -+ writel(val, dev->tx_ring[ring].wpdma + reg); -+} -+ -+static inline u32 -+wpdma_txfree_r32(struct mtk_wed_device *dev, u32 reg) -+{ -+ if (!dev->txfree_ring.wpdma) -+ return 0; -+ -+ return readl(dev->txfree_ring.wpdma + reg); -+} -+ -+static inline void -+wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val) -+{ -+ if (!dev->txfree_ring.wpdma) -+ return; -+ -+ writel(val, dev->txfree_ring.wpdma + reg); -+} -+ -+void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -+ void __iomem *wdma, int index); -+void mtk_wed_exit(void); -+int mtk_wed_flow_add(int index); -+void mtk_wed_flow_remove(int index); -+#else -+static inline void -+mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -+ void __iomem *wdma, int index) -+{ -+} -+static inline void -+mtk_wed_exit(void) -+{ -+} -+static inline int mtk_wed_flow_add(int index) -+{ -+ return -EINVAL; -+} -+static inline void mtk_wed_flow_remove(int index) -+{ -+} -+#endif -+ -+#ifdef CONFIG_DEBUG_FS -+void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw); -+#else -+static inline void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw) -+{ -+} -+#endif -+ -+#endif ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -0,0 +1,175 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* Copyright (C) 2021 Felix Fietkau */ -+ -+#include -+#include "mtk_wed.h" -+#include "mtk_wed_regs.h" -+ -+struct reg_dump { -+ const char *name; -+ u16 offset; -+ u8 type; -+ u8 base; -+}; -+ -+enum { -+ DUMP_TYPE_STRING, -+ DUMP_TYPE_WED, -+ DUMP_TYPE_WDMA, -+ DUMP_TYPE_WPDMA_TX, -+ DUMP_TYPE_WPDMA_TXFREE, -+}; -+ -+#define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING } -+#define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ } -+#define DUMP_RING(_prefix, _base, ...) \ -+ { _prefix " BASE", _base, __VA_ARGS__ }, \ -+ { _prefix " CNT", _base + 0x4, __VA_ARGS__ }, \ -+ { _prefix " CIDX", _base + 0x8, __VA_ARGS__ }, \ -+ { _prefix " DIDX", _base + 0xc, __VA_ARGS__ } -+ -+#define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED) -+#define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED) -+ -+#define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA) -+#define DUMP_WDMA_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WDMA) -+ -+#define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n) -+#define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE) -+ -+static void -+print_reg_val(struct seq_file *s, const char *name, u32 val) -+{ -+ seq_printf(s, "%-32s %08x\n", name, val); -+} -+ -+static void -+dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev, -+ const struct reg_dump *regs, int n_regs) -+{ -+ const struct reg_dump *cur; -+ u32 val; -+ -+ for (cur = regs; cur < ®s[n_regs]; cur++) { -+ switch (cur->type) { -+ case DUMP_TYPE_STRING: -+ seq_printf(s, "%s======== %s:\n", -+ cur > regs ? "\n" : "", -+ cur->name); -+ continue; -+ case DUMP_TYPE_WED: -+ val = wed_r32(dev, cur->offset); -+ break; -+ case DUMP_TYPE_WDMA: -+ val = wdma_r32(dev, cur->offset); -+ break; -+ case DUMP_TYPE_WPDMA_TX: -+ val = wpdma_tx_r32(dev, cur->base, cur->offset); -+ break; -+ case DUMP_TYPE_WPDMA_TXFREE: -+ val = wpdma_txfree_r32(dev, cur->offset); -+ break; -+ } -+ print_reg_val(s, cur->name, val); -+ } -+} -+ -+ -+static int -+wed_txinfo_show(struct seq_file *s, void *data) -+{ -+ static const struct reg_dump regs[] = { -+ DUMP_STR("WED TX"), -+ DUMP_WED(WED_TX_MIB(0)), -+ DUMP_WED_RING(WED_RING_TX(0)), -+ -+ DUMP_WED(WED_TX_MIB(1)), -+ DUMP_WED_RING(WED_RING_TX(1)), -+ -+ DUMP_STR("WPDMA TX"), -+ DUMP_WED(WED_WPDMA_TX_MIB(0)), -+ DUMP_WED_RING(WED_WPDMA_RING_TX(0)), -+ DUMP_WED(WED_WPDMA_TX_COHERENT_MIB(0)), -+ -+ DUMP_WED(WED_WPDMA_TX_MIB(1)), -+ DUMP_WED_RING(WED_WPDMA_RING_TX(1)), -+ DUMP_WED(WED_WPDMA_TX_COHERENT_MIB(1)), -+ -+ DUMP_STR("WPDMA TX"), -+ DUMP_WPDMA_TX_RING(0), -+ DUMP_WPDMA_TX_RING(1), -+ -+ DUMP_STR("WED WDMA RX"), -+ DUMP_WED(WED_WDMA_RX_MIB(0)), -+ DUMP_WED_RING(WED_WDMA_RING_RX(0)), -+ DUMP_WED(WED_WDMA_RX_THRES(0)), -+ DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(0)), -+ DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(0)), -+ -+ DUMP_WED(WED_WDMA_RX_MIB(1)), -+ DUMP_WED_RING(WED_WDMA_RING_RX(1)), -+ DUMP_WED(WED_WDMA_RX_THRES(1)), -+ DUMP_WED(WED_WDMA_RX_RECYCLE_MIB(1)), -+ DUMP_WED(WED_WDMA_RX_PROCESSED_MIB(1)), -+ -+ DUMP_STR("WDMA RX"), -+ DUMP_WDMA(WDMA_GLO_CFG), -+ DUMP_WDMA_RING(WDMA_RING_RX(0)), -+ DUMP_WDMA_RING(WDMA_RING_RX(1)), -+ }; -+ struct mtk_wed_hw *hw = s->private; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (!dev) -+ return 0; -+ -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(wed_txinfo); -+ -+ -+static int -+mtk_wed_reg_set(void *data, u64 val) -+{ -+ struct mtk_wed_hw *hw = data; -+ -+ regmap_write(hw->regs, hw->debugfs_reg, val); -+ -+ return 0; -+} -+ -+static int -+mtk_wed_reg_get(void *data, u64 *val) -+{ -+ struct mtk_wed_hw *hw = data; -+ unsigned int regval; -+ int ret; -+ -+ ret = regmap_read(hw->regs, hw->debugfs_reg, ®val); -+ if (ret) -+ return ret; -+ -+ *val = regval; -+ -+ return 0; -+} -+ -+DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mtk_wed_reg_get, mtk_wed_reg_set, -+ "0x%08llx\n"); -+ -+void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw) -+{ -+ struct dentry *dir; -+ -+ snprintf(hw->dirname, sizeof(hw->dirname), "wed%d", hw->index); -+ dir = debugfs_create_dir(hw->dirname, NULL); -+ if (!dir) -+ return; -+ -+ hw->debugfs_dir = dir; -+ debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg); -+ debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval); -+ debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops); -+} ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed_ops.c -@@ -0,0 +1,8 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* Copyright (C) 2020 Felix Fietkau */ -+ -+#include -+#include -+ -+const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; -+EXPORT_SYMBOL_GPL(mtk_soc_wed_ops); ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -0,0 +1,251 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* Copyright (C) 2020 Felix Fietkau */ -+ -+#ifndef __MTK_WED_REGS_H -+#define __MTK_WED_REGS_H -+ -+#define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0) -+#define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15) -+#define MTK_WDMA_DESC_CTRL_BURST BIT(16) -+#define MTK_WDMA_DESC_CTRL_LEN0 GENMASK(29, 16) -+#define MTK_WDMA_DESC_CTRL_LAST_SEG0 BIT(30) -+#define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31) -+ -+struct mtk_wdma_desc { -+ __le32 buf0; -+ __le32 ctrl; -+ __le32 buf1; -+ __le32 info; -+} __packed __aligned(4); -+ -+#define MTK_WED_RESET 0x008 -+#define MTK_WED_RESET_TX_BM BIT(0) -+#define MTK_WED_RESET_TX_FREE_AGENT BIT(4) -+#define MTK_WED_RESET_WPDMA_TX_DRV BIT(8) -+#define MTK_WED_RESET_WPDMA_RX_DRV BIT(9) -+#define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11) -+#define MTK_WED_RESET_WED_TX_DMA BIT(12) -+#define MTK_WED_RESET_WDMA_RX_DRV BIT(17) -+#define MTK_WED_RESET_WDMA_INT_AGENT BIT(19) -+#define MTK_WED_RESET_WED BIT(31) -+ -+#define MTK_WED_CTRL 0x00c -+#define MTK_WED_CTRL_WPDMA_INT_AGENT_EN BIT(0) -+#define MTK_WED_CTRL_WPDMA_INT_AGENT_BUSY BIT(1) -+#define MTK_WED_CTRL_WDMA_INT_AGENT_EN BIT(2) -+#define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3) -+#define MTK_WED_CTRL_WED_TX_BM_EN BIT(8) -+#define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9) -+#define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10) -+#define MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY BIT(11) -+#define MTK_WED_CTRL_RESERVE_EN BIT(12) -+#define MTK_WED_CTRL_RESERVE_BUSY BIT(13) -+#define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24) -+#define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28) -+ -+#define MTK_WED_EXT_INT_STATUS 0x020 -+#define MTK_WED_EXT_INT_STATUS_TF_LEN_ERR BIT(0) -+#define MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD BIT(1) -+#define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID BIT(4) -+#define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH BIT(8) -+#define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH BIT(9) -+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12) -+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13) -+#define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16) -+#define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17) -+#define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18) -+#define MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN BIT(19) -+#define MTK_WED_EXT_INT_STATUS_RX_DRV_BM_DMAD_COHERENT BIT(20) -+#define MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR BIT(21) -+#define MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR BIT(22) -+#define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24) -+#define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \ -+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \ -+ MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \ -+ MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR | \ -+ MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR | \ -+ MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN | \ -+ MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR | \ -+ MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR) -+ -+#define MTK_WED_EXT_INT_MASK 0x028 -+ -+#define MTK_WED_STATUS 0x060 -+#define MTK_WED_STATUS_TX GENMASK(15, 8) -+ -+#define MTK_WED_TX_BM_CTRL 0x080 -+#define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0) -+#define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16) -+#define MTK_WED_TX_BM_CTRL_PAUSE BIT(28) -+ -+#define MTK_WED_TX_BM_BASE 0x084 -+ -+#define MTK_WED_TX_BM_TKID 0x088 -+#define MTK_WED_TX_BM_TKID_START GENMASK(15, 0) -+#define MTK_WED_TX_BM_TKID_END GENMASK(31, 16) -+ -+#define MTK_WED_TX_BM_BUF_LEN 0x08c -+ -+#define MTK_WED_TX_BM_INTF 0x09c -+#define MTK_WED_TX_BM_INTF_TKID GENMASK(15, 0) -+#define MTK_WED_TX_BM_INTF_TKFIFO_FDEP GENMASK(23, 16) -+#define MTK_WED_TX_BM_INTF_TKID_VALID BIT(28) -+#define MTK_WED_TX_BM_INTF_TKID_READ BIT(29) -+ -+#define MTK_WED_TX_BM_DYN_THR 0x0a0 -+#define MTK_WED_TX_BM_DYN_THR_LO GENMASK(6, 0) -+#define MTK_WED_TX_BM_DYN_THR_HI GENMASK(22, 16) -+ -+#define MTK_WED_INT_STATUS 0x200 -+#define MTK_WED_INT_MASK 0x204 -+ -+#define MTK_WED_GLO_CFG 0x208 -+#define MTK_WED_GLO_CFG_TX_DMA_EN BIT(0) -+#define MTK_WED_GLO_CFG_TX_DMA_BUSY BIT(1) -+#define MTK_WED_GLO_CFG_RX_DMA_EN BIT(2) -+#define MTK_WED_GLO_CFG_RX_DMA_BUSY BIT(3) -+#define MTK_WED_GLO_CFG_RX_BT_SIZE GENMASK(5, 4) -+#define MTK_WED_GLO_CFG_TX_WB_DDONE BIT(6) -+#define MTK_WED_GLO_CFG_BIG_ENDIAN BIT(7) -+#define MTK_WED_GLO_CFG_DIS_BT_SIZE_ALIGN BIT(8) -+#define MTK_WED_GLO_CFG_TX_BT_SIZE_LO BIT(9) -+#define MTK_WED_GLO_CFG_MULTI_DMA_EN GENMASK(11, 10) -+#define MTK_WED_GLO_CFG_FIFO_LITTLE_ENDIAN BIT(12) -+#define MTK_WED_GLO_CFG_MI_DEPTH_RD GENMASK(21, 13) -+#define MTK_WED_GLO_CFG_TX_BT_SIZE_HI GENMASK(23, 22) -+#define MTK_WED_GLO_CFG_SW_RESET BIT(24) -+#define MTK_WED_GLO_CFG_FIRST_TOKEN_ONLY BIT(26) -+#define MTK_WED_GLO_CFG_OMIT_RX_INFO BIT(27) -+#define MTK_WED_GLO_CFG_OMIT_TX_INFO BIT(28) -+#define MTK_WED_GLO_CFG_BYTE_SWAP BIT(29) -+#define MTK_WED_GLO_CFG_RX_2B_OFFSET BIT(31) -+ -+#define MTK_WED_RESET_IDX 0x20c -+#define MTK_WED_RESET_IDX_TX GENMASK(3, 0) -+#define MTK_WED_RESET_IDX_RX GENMASK(17, 16) -+ -+#define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) -+ -+#define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10) -+ -+#define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10) -+ -+#define MTK_WED_WPDMA_INT_TRIGGER 0x504 -+#define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1) -+#define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4) -+ -+#define MTK_WED_WPDMA_GLO_CFG 0x508 -+#define MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN BIT(0) -+#define MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY BIT(1) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN BIT(2) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY BIT(3) -+#define MTK_WED_WPDMA_GLO_CFG_RX_BT_SIZE GENMASK(5, 4) -+#define MTK_WED_WPDMA_GLO_CFG_TX_WB_DDONE BIT(6) -+#define MTK_WED_WPDMA_GLO_CFG_BIG_ENDIAN BIT(7) -+#define MTK_WED_WPDMA_GLO_CFG_DIS_BT_SIZE_ALIGN BIT(8) -+#define MTK_WED_WPDMA_GLO_CFG_TX_BT_SIZE_LO BIT(9) -+#define MTK_WED_WPDMA_GLO_CFG_MULTI_DMA_EN GENMASK(11, 10) -+#define MTK_WED_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN BIT(12) -+#define MTK_WED_WPDMA_GLO_CFG_MI_DEPTH_RD GENMASK(21, 13) -+#define MTK_WED_WPDMA_GLO_CFG_TX_BT_SIZE_HI GENMASK(23, 22) -+#define MTK_WED_WPDMA_GLO_CFG_SW_RESET BIT(24) -+#define MTK_WED_WPDMA_GLO_CFG_FIRST_TOKEN_ONLY BIT(26) -+#define MTK_WED_WPDMA_GLO_CFG_OMIT_RX_INFO BIT(27) -+#define MTK_WED_WPDMA_GLO_CFG_OMIT_TX_INFO BIT(28) -+#define MTK_WED_WPDMA_GLO_CFG_BYTE_SWAP BIT(29) -+#define MTK_WED_WPDMA_GLO_CFG_RX_2B_OFFSET BIT(31) -+ -+#define MTK_WED_WPDMA_RESET_IDX 0x50c -+#define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0) -+#define MTK_WED_WPDMA_RESET_IDX_RX GENMASK(17, 16) -+ -+#define MTK_WED_WPDMA_INT_CTRL 0x520 -+#define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21) -+ -+#define MTK_WED_WPDMA_INT_MASK 0x524 -+ -+#define MTK_WED_PCIE_CFG_BASE 0x560 -+ -+#define MTK_WED_PCIE_INT_TRIGGER 0x570 -+#define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16) -+ -+#define MTK_WED_WPDMA_CFG_BASE 0x580 -+ -+#define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4) -+#define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4) -+ -+#define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10) -+#define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10) -+#define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10) -+#define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4) -+ -+#define MTK_WED_WDMA_GLO_CFG 0xa04 -+#define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0) -+#define MTK_WED_WDMA_GLO_CFG_RX_DRV_EN BIT(2) -+#define MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY BIT(3) -+#define MTK_WED_WDMA_GLO_CFG_BT_SIZE GENMASK(5, 4) -+#define MTK_WED_WDMA_GLO_CFG_TX_WB_DDONE BIT(6) -+#define MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE BIT(13) -+#define MTK_WED_WDMA_GLO_CFG_WCOMPLETE_SEL BIT(16) -+#define MTK_WED_WDMA_GLO_CFG_INIT_PHASE_RXDMA_BYPASS BIT(17) -+#define MTK_WED_WDMA_GLO_CFG_INIT_PHASE_BYPASS BIT(18) -+#define MTK_WED_WDMA_GLO_CFG_FSM_RETURN_IDLE BIT(19) -+#define MTK_WED_WDMA_GLO_CFG_WAIT_COHERENT BIT(20) -+#define MTK_WED_WDMA_GLO_CFG_AXI_W_AFTER_AW BIT(21) -+#define MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY_SINGLE_W BIT(22) -+#define MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY BIT(23) -+#define MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP BIT(24) -+#define MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE BIT(25) -+#define MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE BIT(26) -+#define MTK_WED_WDMA_GLO_CFG_RXDRV_CLKGATE_BYPASS BIT(30) -+ -+#define MTK_WED_WDMA_RESET_IDX 0xa08 -+#define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16) -+#define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24) -+ -+#define MTK_WED_WDMA_INT_TRIGGER 0xa28 -+#define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16) -+ -+#define MTK_WED_WDMA_INT_CTRL 0xa2c -+#define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16) -+ -+#define MTK_WED_WDMA_OFFSET0 0xaa4 -+#define MTK_WED_WDMA_OFFSET1 0xaa8 -+ -+#define MTK_WED_WDMA_RX_MIB(_n) (0xae0 + (_n) * 4) -+#define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4) -+#define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4) -+ -+#define MTK_WED_RING_OFS_BASE 0x00 -+#define MTK_WED_RING_OFS_COUNT 0x04 -+#define MTK_WED_RING_OFS_CPU_IDX 0x08 -+#define MTK_WED_RING_OFS_DMA_IDX 0x0c -+ -+#define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10) -+ -+#define MTK_WDMA_GLO_CFG 0x204 -+#define MTK_WDMA_GLO_CFG_RX_INFO_PRERES GENMASK(28, 26) -+ -+#define MTK_WDMA_RESET_IDX 0x208 -+#define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0) -+#define MTK_WDMA_RESET_IDX_RX GENMASK(17, 16) -+ -+#define MTK_WDMA_INT_MASK 0x228 -+#define MTK_WDMA_INT_MASK_TX_DONE GENMASK(3, 0) -+#define MTK_WDMA_INT_MASK_RX_DONE GENMASK(17, 16) -+#define MTK_WDMA_INT_MASK_TX_DELAY BIT(28) -+#define MTK_WDMA_INT_MASK_TX_COHERENT BIT(29) -+#define MTK_WDMA_INT_MASK_RX_DELAY BIT(30) -+#define MTK_WDMA_INT_MASK_RX_COHERENT BIT(31) -+ -+#define MTK_WDMA_INT_GRP1 0x250 -+#define MTK_WDMA_INT_GRP2 0x254 -+ -+#define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0) -+#define MTK_PCIE_MIRROR_MAP_EN BIT(0) -+#define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1) -+ -+/* DMA channel mapping */ -+#define HIFSYS_DMA_AG_MAP 0x008 -+ -+#endif ---- /dev/null -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -0,0 +1,131 @@ -+#ifndef __MTK_WED_H -+#define __MTK_WED_H -+ -+#include -+#include -+#include -+#include -+ -+#define MTK_WED_TX_QUEUES 2 -+ -+struct mtk_wed_hw; -+struct mtk_wdma_desc; -+ -+struct mtk_wed_ring { -+ struct mtk_wdma_desc *desc; -+ dma_addr_t desc_phys; -+ int size; -+ -+ u32 reg_base; -+ void __iomem *wpdma; -+}; -+ -+struct mtk_wed_device { -+#ifdef CONFIG_NET_MEDIATEK_SOC_WED -+ const struct mtk_wed_ops *ops; -+ struct device *dev; -+ struct mtk_wed_hw *hw; -+ bool init_done, running; -+ int wdma_idx; -+ int irq; -+ -+ struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; -+ struct mtk_wed_ring txfree_ring; -+ struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; -+ -+ struct { -+ int size; -+ void **pages; -+ struct mtk_wdma_desc *desc; -+ dma_addr_t desc_phys; -+ } buf_ring; -+ -+ /* filled by driver: */ -+ struct { -+ struct pci_dev *pci_dev; -+ -+ u32 wpdma_phys; -+ -+ u16 token_start; -+ unsigned int nbuf; -+ -+ u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); -+ int (*offload_enable)(struct mtk_wed_device *wed); -+ void (*offload_disable)(struct mtk_wed_device *wed); -+ } wlan; -+#endif -+}; -+ -+struct mtk_wed_ops { -+ int (*attach)(struct mtk_wed_device *dev); -+ int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, -+ void __iomem *regs); -+ int (*txfree_ring_setup)(struct mtk_wed_device *dev, -+ void __iomem *regs); -+ void (*detach)(struct mtk_wed_device *dev); -+ -+ void (*stop)(struct mtk_wed_device *dev); -+ void (*start)(struct mtk_wed_device *dev, u32 irq_mask); -+ void (*reset_dma)(struct mtk_wed_device *dev); -+ -+ u32 (*reg_read)(struct mtk_wed_device *dev, u32 reg); -+ void (*reg_write)(struct mtk_wed_device *dev, u32 reg, u32 val); -+ -+ u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask); -+ void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); -+}; -+ -+extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; -+ -+static inline int -+mtk_wed_device_attach(struct mtk_wed_device *dev) -+{ -+ int ret = -ENODEV; -+ -+#ifdef CONFIG_NET_MEDIATEK_SOC_WED -+ rcu_read_lock(); -+ dev->ops = rcu_dereference(mtk_soc_wed_ops); -+ if (dev->ops) -+ ret = dev->ops->attach(dev); -+ else -+ rcu_read_unlock(); -+ -+ if (ret) -+ dev->ops = NULL; -+#endif -+ -+ return ret; -+} -+ -+#ifdef CONFIG_NET_MEDIATEK_SOC_WED -+#define mtk_wed_device_active(_dev) !!(_dev)->ops -+#define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) -+#define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask) -+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \ -+ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_txfree_ring_setup(_dev, _regs) \ -+ (_dev)->ops->txfree_ring_setup(_dev, _regs) -+#define mtk_wed_device_reg_read(_dev, _reg) \ -+ (_dev)->ops->reg_read(_dev, _reg) -+#define mtk_wed_device_reg_write(_dev, _reg, _val) \ -+ (_dev)->ops->reg_write(_dev, _reg, _val) -+#define mtk_wed_device_irq_get(_dev, _mask) \ -+ (_dev)->ops->irq_get(_dev, _mask) -+#define mtk_wed_device_irq_set_mask(_dev, _mask) \ -+ (_dev)->ops->irq_set_mask(_dev, _mask) -+#else -+static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) -+{ -+ return false; -+} -+#define mtk_wed_device_detach(_dev) do {} while (0) -+#define mtk_wed_device_start(_dev, _mask) do {} while (0) -+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_reg_read(_dev, _reg) 0 -+#define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) -+#define mtk_wed_device_irq_get(_dev, _mask) 0 -+#define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0) -+#endif -+ -+#endif diff --git a/target/linux/generic/backport-5.15/702-v5.19-03-net-ethernet-mtk_eth_soc-implement-flow-offloading-t.patch b/target/linux/generic/backport-5.15/702-v5.19-03-net-ethernet-mtk_eth_soc-implement-flow-offloading-t.patch deleted file mode 100644 index 69113c2ffafc6f..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-03-net-ethernet-mtk_eth_soc-implement-flow-offloading-t.patch +++ /dev/null @@ -1,269 +0,0 @@ -From: Felix Fietkau -Date: Sat, 5 Feb 2022 18:29:22 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: implement flow offloading - to WED devices - -This allows hardware flow offloading from Ethernet to WLAN on MT7622 SoC - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -329,6 +329,24 @@ int mtk_foe_entry_set_pppoe(struct mtk_f - return 0; - } - -+int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, -+ int bss, int wcid) -+{ -+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); -+ u32 *ib2 = mtk_foe_entry_ib2(entry); -+ -+ *ib2 &= ~MTK_FOE_IB2_PORT_MG; -+ *ib2 |= MTK_FOE_IB2_WDMA_WINFO; -+ if (wdma_idx) -+ *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX; -+ -+ l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | -+ FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | -+ FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); -+ -+ return 0; -+} -+ - static inline bool mtk_foe_entry_usable(struct mtk_foe_entry *entry) - { - return !(entry->ib1 & MTK_FOE_IB1_STATIC) && ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -48,9 +48,9 @@ enum { - #define MTK_FOE_IB2_DEST_PORT GENMASK(7, 5) - #define MTK_FOE_IB2_MULTICAST BIT(8) - --#define MTK_FOE_IB2_WHNAT_QID2 GENMASK(13, 12) --#define MTK_FOE_IB2_WHNAT_DEVIDX BIT(16) --#define MTK_FOE_IB2_WHNAT_NAT BIT(17) -+#define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12) -+#define MTK_FOE_IB2_WDMA_DEVIDX BIT(16) -+#define MTK_FOE_IB2_WDMA_WINFO BIT(17) - - #define MTK_FOE_IB2_PORT_MG GENMASK(17, 12) - -@@ -58,9 +58,9 @@ enum { - - #define MTK_FOE_IB2_DSCP GENMASK(31, 24) - --#define MTK_FOE_VLAN2_WHNAT_BSS GEMMASK(5, 0) --#define MTK_FOE_VLAN2_WHNAT_WCID GENMASK(13, 6) --#define MTK_FOE_VLAN2_WHNAT_RING GENMASK(15, 14) -+#define MTK_FOE_VLAN2_WINFO_BSS GENMASK(5, 0) -+#define MTK_FOE_VLAN2_WINFO_WCID GENMASK(13, 6) -+#define MTK_FOE_VLAN2_WINFO_RING GENMASK(15, 14) - - enum { - MTK_FOE_STATE_INVALID, -@@ -281,6 +281,8 @@ int mtk_foe_entry_set_ipv6_tuple(struct - int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port); - int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid); - int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid); -+int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, -+ int bss, int wcid); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - u16 timestamp); - int mtk_ppe_debugfs_init(struct mtk_ppe *ppe); ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -10,6 +10,7 @@ - #include - #include - #include "mtk_eth_soc.h" -+#include "mtk_wed.h" - - struct mtk_flow_data { - struct ethhdr eth; -@@ -39,6 +40,7 @@ struct mtk_flow_entry { - struct rhash_head node; - unsigned long cookie; - u16 hash; -+ s8 wed_index; - }; - - static const struct rhashtable_params mtk_flow_ht_params = { -@@ -80,6 +82,35 @@ mtk_flow_offload_mangle_eth(const struct - memcpy(dest, src, act->mangle.mask ? 2 : 4); - } - -+static int -+mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_info *info) -+{ -+ struct net_device_path_ctx ctx = { -+ .dev = dev, -+ .daddr = addr, -+ }; -+ struct net_device_path path = {}; -+ -+ if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)) -+ return -1; -+ -+ if (!dev->netdev_ops->ndo_fill_forward_path) -+ return -1; -+ -+ if (dev->netdev_ops->ndo_fill_forward_path(&ctx, &path)) -+ return -1; -+ -+ if (path.type != DEV_PATH_MTK_WDMA) -+ return -1; -+ -+ info->wdma_idx = path.mtk_wdma.wdma_idx; -+ info->queue = path.mtk_wdma.queue; -+ info->bss = path.mtk_wdma.bss; -+ info->wcid = path.mtk_wdma.wcid; -+ -+ return 0; -+} -+ - - static int - mtk_flow_mangle_ports(const struct flow_action_entry *act, -@@ -149,10 +180,20 @@ mtk_flow_get_dsa_port(struct net_device - - static int - mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe, -- struct net_device *dev) -+ struct net_device *dev, const u8 *dest_mac, -+ int *wed_index) - { -+ struct mtk_wdma_info info = {}; - int pse_port, dsa_port; - -+ if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { -+ mtk_foe_entry_set_wdma(foe, info.wdma_idx, info.queue, info.bss, -+ info.wcid); -+ pse_port = 3; -+ *wed_index = info.wdma_idx; -+ goto out; -+ } -+ - dsa_port = mtk_flow_get_dsa_port(&dev); - if (dsa_port >= 0) - mtk_foe_entry_set_dsa(foe, dsa_port); -@@ -164,6 +205,7 @@ mtk_flow_set_output_device(struct mtk_et - else - return -EOPNOTSUPP; - -+out: - mtk_foe_entry_set_pse_port(foe, pse_port); - - return 0; -@@ -179,6 +221,7 @@ mtk_flow_offload_replace(struct mtk_eth - struct net_device *odev = NULL; - struct mtk_flow_entry *entry; - int offload_type = 0; -+ int wed_index = -1; - u16 addr_type = 0; - u32 timestamp; - u8 l4proto = 0; -@@ -326,10 +369,14 @@ mtk_flow_offload_replace(struct mtk_eth - if (data.pppoe.num == 1) - mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid); - -- err = mtk_flow_set_output_device(eth, &foe, odev); -+ err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest, -+ &wed_index); - if (err) - return err; - -+ if (wed_index >= 0 && (err = mtk_wed_flow_add(wed_index)) < 0) -+ return err; -+ - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - return -ENOMEM; -@@ -343,6 +390,7 @@ mtk_flow_offload_replace(struct mtk_eth - } - - entry->hash = hash; -+ entry->wed_index = wed_index; - err = rhashtable_insert_fast(ð->flow_table, &entry->node, - mtk_flow_ht_params); - if (err < 0) -@@ -353,6 +401,8 @@ clear_flow: - mtk_foe_entry_clear(ð->ppe, hash); - free: - kfree(entry); -+ if (wed_index >= 0) -+ mtk_wed_flow_remove(wed_index); - return err; - } - -@@ -369,6 +419,8 @@ mtk_flow_offload_destroy(struct mtk_eth - mtk_foe_entry_clear(ð->ppe, entry->hash); - rhashtable_remove_fast(ð->flow_table, &entry->node, - mtk_flow_ht_params); -+ if (entry->wed_index >= 0) -+ mtk_wed_flow_remove(entry->wed_index); - kfree(entry); - - return 0; ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - - struct mtk_eth; - -@@ -27,6 +28,12 @@ struct mtk_wed_hw { - int index; - }; - -+struct mtk_wdma_info { -+ u8 wdma_idx; -+ u8 queue; -+ u16 wcid; -+ u8 bss; -+}; - - #ifdef CONFIG_NET_MEDIATEK_SOC_WED - static inline void ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -875,6 +875,7 @@ enum net_device_path_type { - DEV_PATH_BRIDGE, - DEV_PATH_PPPOE, - DEV_PATH_DSA, -+ DEV_PATH_MTK_WDMA, - }; - - struct net_device_path { -@@ -900,6 +901,12 @@ struct net_device_path { - int port; - u16 proto; - } dsa; -+ struct { -+ u8 wdma_idx; -+ u8 queue; -+ u16 wcid; -+ u8 bss; -+ } mtk_wdma; - }; - }; - ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -769,6 +769,10 @@ int dev_fill_forward_path(const struct n - if (WARN_ON_ONCE(last_dev == ctx.dev)) - return -1; - } -+ -+ if (!ctx.dev) -+ return ret; -+ - path = dev_fwd_path(stack); - if (!path) - return -1; diff --git a/target/linux/generic/backport-5.15/702-v5.19-05-net-ethernet-mtk_eth_soc-add-ipv6-flow-offload-suppo.patch b/target/linux/generic/backport-5.15/702-v5.19-05-net-ethernet-mtk_eth_soc-add-ipv6-flow-offload-suppo.patch deleted file mode 100644 index 9adb067015ee95..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-05-net-ethernet-mtk_eth_soc-add-ipv6-flow-offload-suppo.patch +++ /dev/null @@ -1,79 +0,0 @@ -From: David Bentham -Date: Mon, 21 Feb 2022 15:36:16 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add ipv6 flow offload - support - -Add the missing IPv6 flow offloading support for routing only. -Hardware flow offloading is done by the packet processing engine (PPE) -of the Ethernet MAC and as it doesn't support mangling of IPv6 packets, -IPv6 NAT cannot be supported. - -Signed-off-by: David Bentham -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -20,6 +21,11 @@ struct mtk_flow_data { - __be32 src_addr; - __be32 dst_addr; - } v4; -+ -+ struct { -+ struct in6_addr src_addr; -+ struct in6_addr dst_addr; -+ } v6; - }; - - __be16 src_port; -@@ -65,6 +71,14 @@ mtk_flow_set_ipv4_addr(struct mtk_foe_en - data->v4.dst_addr, data->dst_port); - } - -+static int -+mtk_flow_set_ipv6_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data) -+{ -+ return mtk_foe_entry_set_ipv6_tuple(foe, -+ data->v6.src_addr.s6_addr32, data->src_port, -+ data->v6.dst_addr.s6_addr32, data->dst_port); -+} -+ - static void - mtk_flow_offload_mangle_eth(const struct flow_action_entry *act, void *eth) - { -@@ -296,6 +310,9 @@ mtk_flow_offload_replace(struct mtk_eth - case FLOW_DISSECTOR_KEY_IPV4_ADDRS: - offload_type = MTK_PPE_PKT_TYPE_IPV4_HNAPT; - break; -+ case FLOW_DISSECTOR_KEY_IPV6_ADDRS: -+ offload_type = MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T; -+ break; - default: - return -EOPNOTSUPP; - } -@@ -331,6 +348,17 @@ mtk_flow_offload_replace(struct mtk_eth - mtk_flow_set_ipv4_addr(&foe, &data, false); - } - -+ if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { -+ struct flow_match_ipv6_addrs addrs; -+ -+ flow_rule_match_ipv6_addrs(rule, &addrs); -+ -+ data.v6.src_addr = addrs.key->src; -+ data.v6.dst_addr = addrs.key->dst; -+ -+ mtk_flow_set_ipv6_addr(&foe, &data); -+ } -+ - flow_action_for_each(i, act, &rule->action) { - if (act->id != FLOW_ACTION_MANGLE) - continue; diff --git a/target/linux/generic/backport-5.15/702-v5.19-06-net-ethernet-mtk_eth_soc-support-TC_SETUP_BLOCK-for-.patch b/target/linux/generic/backport-5.15/702-v5.19-06-net-ethernet-mtk_eth_soc-support-TC_SETUP_BLOCK-for-.patch deleted file mode 100644 index 1950d81ebbacfd..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-06-net-ethernet-mtk_eth_soc-support-TC_SETUP_BLOCK-for-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Felix Fietkau -Date: Mon, 21 Feb 2022 15:37:21 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: support TC_SETUP_BLOCK for - PPE offload - -This allows offload entries to be created from user space - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -564,10 +564,13 @@ mtk_eth_setup_tc_block(struct net_device - int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, - void *type_data) - { -- if (type == TC_SETUP_FT) -+ switch (type) { -+ case TC_SETUP_BLOCK: -+ case TC_SETUP_FT: - return mtk_eth_setup_tc_block(dev, type_data); -- -- return -EOPNOTSUPP; -+ default: -+ return -EOPNOTSUPP; -+ } - } - - int mtk_eth_offload_init(struct mtk_eth *eth) diff --git a/target/linux/generic/backport-5.15/702-v5.19-07-net-ethernet-mtk_eth_soc-allocate-struct-mtk_ppe-sep.patch b/target/linux/generic/backport-5.15/702-v5.19-07-net-ethernet-mtk_eth_soc-allocate-struct-mtk_ppe-sep.patch deleted file mode 100644 index 488a79924f15e5..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-07-net-ethernet-mtk_eth_soc-allocate-struct-mtk_ppe-sep.patch +++ /dev/null @@ -1,159 +0,0 @@ -From: Felix Fietkau -Date: Mon, 21 Feb 2022 15:38:20 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: allocate struct mtk_ppe - separately - -Preparation for adding more data to it, which will increase its size. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2348,7 +2348,7 @@ static int mtk_open(struct net_device *d - return err; - } - -- if (eth->soc->offload_version && mtk_ppe_start(ð->ppe) == 0) -+ if (eth->soc->offload_version && mtk_ppe_start(eth->ppe) == 0) - gdm_config = MTK_GDMA_TO_PPE; - - mtk_gdm_config(eth, gdm_config); -@@ -2422,7 +2422,7 @@ static int mtk_stop(struct net_device *d - mtk_dma_free(eth); - - if (eth->soc->offload_version) -- mtk_ppe_stop(ð->ppe); -+ mtk_ppe_stop(eth->ppe); - - return 0; - } -@@ -3307,10 +3307,11 @@ static int mtk_probe(struct platform_dev - } - - if (eth->soc->offload_version) { -- err = mtk_ppe_init(ð->ppe, eth->dev, -- eth->base + MTK_ETH_PPE_BASE, 2); -- if (err) -+ eth->ppe = mtk_ppe_init(eth->dev, eth->base + MTK_ETH_PPE_BASE, 2); -+ if (!eth->ppe) { -+ err = -ENOMEM; - goto err_free_dev; -+ } - - err = mtk_eth_offload_init(eth); - if (err) ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -983,7 +983,7 @@ struct mtk_eth { - u32 rx_dma_l4_valid; - int ip_align; - -- struct mtk_ppe ppe; -+ struct mtk_ppe *ppe; - struct rhashtable flow_table; - }; - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -384,10 +384,15 @@ int mtk_foe_entry_commit(struct mtk_ppe - return hash; - } - --int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base, -+struct mtk_ppe *mtk_ppe_init(struct device *dev, void __iomem *base, - int version) - { - struct mtk_foe_entry *foe; -+ struct mtk_ppe *ppe; -+ -+ ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL); -+ if (!ppe) -+ return NULL; - - /* need to allocate a separate device, since it PPE DMA access is - * not coherent. -@@ -399,13 +404,13 @@ int mtk_ppe_init(struct mtk_ppe *ppe, st - foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe), - &ppe->foe_phys, GFP_KERNEL); - if (!foe) -- return -ENOMEM; -+ return NULL; - - ppe->foe_table = foe; - - mtk_ppe_debugfs_init(ppe); - -- return 0; -+ return ppe; - } - - static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe) ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -246,8 +246,7 @@ struct mtk_ppe { - void *acct_table; - }; - --int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base, -- int version); -+struct mtk_ppe *mtk_ppe_init(struct device *dev, void __iomem *base, int version); - int mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -411,7 +411,7 @@ mtk_flow_offload_replace(struct mtk_eth - - entry->cookie = f->cookie; - timestamp = mtk_eth_timestamp(eth); -- hash = mtk_foe_entry_commit(ð->ppe, &foe, timestamp); -+ hash = mtk_foe_entry_commit(eth->ppe, &foe, timestamp); - if (hash < 0) { - err = hash; - goto free; -@@ -426,7 +426,7 @@ mtk_flow_offload_replace(struct mtk_eth - - return 0; - clear_flow: -- mtk_foe_entry_clear(ð->ppe, hash); -+ mtk_foe_entry_clear(eth->ppe, hash); - free: - kfree(entry); - if (wed_index >= 0) -@@ -444,7 +444,7 @@ mtk_flow_offload_destroy(struct mtk_eth - if (!entry) - return -ENOENT; - -- mtk_foe_entry_clear(ð->ppe, entry->hash); -+ mtk_foe_entry_clear(eth->ppe, entry->hash); - rhashtable_remove_fast(ð->flow_table, &entry->node, - mtk_flow_ht_params); - if (entry->wed_index >= 0) -@@ -466,7 +466,7 @@ mtk_flow_offload_stats(struct mtk_eth *e - if (!entry) - return -ENOENT; - -- timestamp = mtk_foe_entry_timestamp(ð->ppe, entry->hash); -+ timestamp = mtk_foe_entry_timestamp(eth->ppe, entry->hash); - if (timestamp < 0) - return -ETIMEDOUT; - -@@ -522,7 +522,7 @@ mtk_eth_setup_tc_block(struct net_device - struct flow_block_cb *block_cb; - flow_setup_cb_t *cb; - -- if (!eth->ppe.foe_table) -+ if (!eth->ppe || !eth->ppe->foe_table) - return -EOPNOTSUPP; - - if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) -@@ -575,7 +575,7 @@ int mtk_eth_setup_tc(struct net_device * - - int mtk_eth_offload_init(struct mtk_eth *eth) - { -- if (!eth->ppe.foe_table) -+ if (!eth->ppe || !eth->ppe->foe_table) - return 0; - - return rhashtable_init(ð->flow_table, &mtk_flow_ht_params); diff --git a/target/linux/generic/backport-5.15/702-v5.19-08-net-ethernet-mtk_eth_soc-rework-hardware-flow-table-.patch b/target/linux/generic/backport-5.15/702-v5.19-08-net-ethernet-mtk_eth_soc-rework-hardware-flow-table-.patch deleted file mode 100644 index 182c6afb78d3a8..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-08-net-ethernet-mtk_eth_soc-rework-hardware-flow-table-.patch +++ /dev/null @@ -1,424 +0,0 @@ -From: Felix Fietkau -Date: Mon, 21 Feb 2022 15:39:18 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: rework hardware flow table - management - -The hardware was designed to handle flow detection and creation of flow entries -by itself, relying on the software primarily for filling in egress routing -information. -When there is a hash collision between multiple flows, this allows the hardware -to maintain the entry for the most active flow. -Additionally, the hardware only keeps offloading active for entries with at -least 30 packets per second. - -With this rework, the code no longer creates a hardware entries directly. -Instead, the hardware entry is only created when the PPE reports a matching -unbound flow with the minimum target rate. -In order to reduce CPU overhead, looking for flows belonging to a hash entry -is rate limited to once every 100ms. - -This rework is also used as preparation for emulating bridge offload by -managing L4 offload entries on demand. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - - #include "mtk_eth_soc.h" -@@ -1303,7 +1304,7 @@ static int mtk_poll_rx(struct napi_struc - struct net_device *netdev; - unsigned int pktlen; - dma_addr_t dma_addr; -- u32 hash; -+ u32 hash, reason; - int mac; - - ring = mtk_get_rx_ring(eth); -@@ -1382,6 +1383,11 @@ static int mtk_poll_rx(struct napi_struc - skb_set_hash(skb, hash, PKT_HASH_TYPE_L4); - } - -+ reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); -+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -+ mtk_ppe_check_skb(eth->ppe, skb, -+ trxd.rxd4 & MTK_RXD4_FOE_ENTRY); -+ - if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX && - (trxd.rxd2 & RX_DMA_VTAG)) - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), -@@ -3307,7 +3313,7 @@ static int mtk_probe(struct platform_dev - } - - if (eth->soc->offload_version) { -- eth->ppe = mtk_ppe_init(eth->dev, eth->base + MTK_ETH_PPE_BASE, 2); -+ eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2); - if (!eth->ppe) { - err = -ENOMEM; - goto err_free_dev; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -6,9 +6,12 @@ - #include - #include - #include -+#include "mtk_eth_soc.h" - #include "mtk_ppe.h" - #include "mtk_ppe_regs.h" - -+static DEFINE_SPINLOCK(ppe_lock); -+ - static void ppe_w32(struct mtk_ppe *ppe, u32 reg, u32 val) - { - writel(val, ppe->base + reg); -@@ -41,6 +44,11 @@ static u32 ppe_clear(struct mtk_ppe *ppe - return ppe_m32(ppe, reg, val, 0); - } - -+static u32 mtk_eth_timestamp(struct mtk_eth *eth) -+{ -+ return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP; -+} -+ - static int mtk_ppe_wait_busy(struct mtk_ppe *ppe) - { - int ret; -@@ -353,26 +361,59 @@ static inline bool mtk_foe_entry_usable( - FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1) != MTK_FOE_STATE_BIND; - } - --int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, -- u16 timestamp) -+static bool -+mtk_flow_entry_match(struct mtk_flow_entry *entry, struct mtk_foe_entry *data) -+{ -+ int type, len; -+ -+ if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP) -+ return false; -+ -+ type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); -+ if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) -+ len = offsetof(struct mtk_foe_entry, ipv6._rsv); -+ else -+ len = offsetof(struct mtk_foe_entry, ipv4.ib2); -+ -+ return !memcmp(&entry->data.data, &data->data, len - 4); -+} -+ -+static void -+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - struct mtk_foe_entry *hwe; -- u32 hash; -+ struct mtk_foe_entry foe; - -+ spin_lock_bh(&ppe_lock); -+ if (entry->hash == 0xffff) -+ goto out; -+ -+ hwe = &ppe->foe_table[entry->hash]; -+ memcpy(&foe, hwe, sizeof(foe)); -+ if (!mtk_flow_entry_match(entry, &foe)) { -+ entry->hash = 0xffff; -+ goto out; -+ } -+ -+ entry->data.ib1 = foe.ib1; -+ -+out: -+ spin_unlock_bh(&ppe_lock); -+} -+ -+static void -+__mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, -+ u16 hash) -+{ -+ struct mtk_foe_entry *hwe; -+ u16 timestamp; -+ -+ timestamp = mtk_eth_timestamp(ppe->eth); - timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP; - entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; - entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp); - -- hash = mtk_ppe_hash_entry(entry); - hwe = &ppe->foe_table[hash]; -- if (!mtk_foe_entry_usable(hwe)) { -- hwe++; -- hash++; -- -- if (!mtk_foe_entry_usable(hwe)) -- return -ENOSPC; -- } -- - memcpy(&hwe->data, &entry->data, sizeof(hwe->data)); - wmb(); - hwe->ib1 = entry->ib1; -@@ -380,13 +421,77 @@ int mtk_foe_entry_commit(struct mtk_ppe - dma_wmb(); - - mtk_ppe_cache_clear(ppe); -+} - -- return hash; -+void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+{ -+ spin_lock_bh(&ppe_lock); -+ hlist_del_init(&entry->list); -+ if (entry->hash != 0xffff) { -+ ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE; -+ ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, -+ MTK_FOE_STATE_BIND); -+ dma_wmb(); -+ } -+ entry->hash = 0xffff; -+ spin_unlock_bh(&ppe_lock); -+} -+ -+int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+{ -+ u32 hash = mtk_ppe_hash_entry(&entry->data); -+ -+ entry->hash = 0xffff; -+ spin_lock_bh(&ppe_lock); -+ hlist_add_head(&entry->list, &ppe->foe_flow[hash / 2]); -+ spin_unlock_bh(&ppe_lock); -+ -+ return 0; -+} -+ -+void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) -+{ -+ struct hlist_head *head = &ppe->foe_flow[hash / 2]; -+ struct mtk_flow_entry *entry; -+ struct mtk_foe_entry *hwe = &ppe->foe_table[hash]; -+ bool found = false; -+ -+ if (hlist_empty(head)) -+ return; -+ -+ spin_lock_bh(&ppe_lock); -+ hlist_for_each_entry(entry, head, list) { -+ if (found || !mtk_flow_entry_match(entry, hwe)) { -+ if (entry->hash != 0xffff) -+ entry->hash = 0xffff; -+ continue; -+ } -+ -+ entry->hash = hash; -+ __mtk_foe_entry_commit(ppe, &entry->data, hash); -+ found = true; -+ } -+ spin_unlock_bh(&ppe_lock); -+} -+ -+int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+{ -+ u16 now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP; -+ u16 timestamp; -+ -+ mtk_flow_entry_update(ppe, entry); -+ timestamp = entry->data.ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; -+ -+ if (timestamp > now) -+ return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now; -+ else -+ return now - timestamp; - } - --struct mtk_ppe *mtk_ppe_init(struct device *dev, void __iomem *base, -+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, - int version) - { -+ struct device *dev = eth->dev; - struct mtk_foe_entry *foe; - struct mtk_ppe *ppe; - -@@ -398,6 +503,7 @@ struct mtk_ppe *mtk_ppe_init(struct devi - * not coherent. - */ - ppe->base = base; -+ ppe->eth = eth; - ppe->dev = dev; - ppe->version = version; - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -235,7 +235,17 @@ enum { - MTK_PPE_CPU_REASON_INVALID = 0x1f, - }; - -+struct mtk_flow_entry { -+ struct rhash_head node; -+ struct hlist_node list; -+ unsigned long cookie; -+ struct mtk_foe_entry data; -+ u16 hash; -+ s8 wed_index; -+}; -+ - struct mtk_ppe { -+ struct mtk_eth *eth; - struct device *dev; - void __iomem *base; - int version; -@@ -243,18 +253,33 @@ struct mtk_ppe { - struct mtk_foe_entry *foe_table; - dma_addr_t foe_phys; - -+ u16 foe_check_time[MTK_PPE_ENTRIES]; -+ struct hlist_head foe_flow[MTK_PPE_ENTRIES / 2]; -+ - void *acct_table; - }; - --struct mtk_ppe *mtk_ppe_init(struct device *dev, void __iomem *base, int version); -+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version); - int mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); - -+void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); -+ - static inline void --mtk_foe_entry_clear(struct mtk_ppe *ppe, u16 hash) -+mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - { -- ppe->foe_table[hash].ib1 = 0; -- dma_wmb(); -+ u16 now, diff; -+ -+ if (!ppe) -+ return; -+ -+ now = (u16)jiffies; -+ diff = now - ppe->foe_check_time[hash]; -+ if (diff < HZ / 10) -+ return; -+ -+ ppe->foe_check_time[hash] = now; -+ __mtk_ppe_check_skb(ppe, skb, hash); - } - - static inline int -@@ -282,8 +307,9 @@ int mtk_foe_entry_set_vlan(struct mtk_fo - int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid); - int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, - int bss, int wcid); --int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, -- u16 timestamp); -+int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); -+void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); -+int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_ppe_debugfs_init(struct mtk_ppe *ppe); - - #endif ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -42,13 +42,6 @@ struct mtk_flow_data { - } pppoe; - }; - --struct mtk_flow_entry { -- struct rhash_head node; -- unsigned long cookie; -- u16 hash; -- s8 wed_index; --}; -- - static const struct rhashtable_params mtk_flow_ht_params = { - .head_offset = offsetof(struct mtk_flow_entry, node), - .key_offset = offsetof(struct mtk_flow_entry, cookie), -@@ -56,12 +49,6 @@ static const struct rhashtable_params mt - .automatic_shrinking = true, - }; - --static u32 --mtk_eth_timestamp(struct mtk_eth *eth) --{ -- return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP; --} -- - static int - mtk_flow_set_ipv4_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data, - bool egress) -@@ -237,10 +224,8 @@ mtk_flow_offload_replace(struct mtk_eth - int offload_type = 0; - int wed_index = -1; - u16 addr_type = 0; -- u32 timestamp; - u8 l4proto = 0; - int err = 0; -- int hash; - int i; - - if (rhashtable_lookup(ð->flow_table, &f->cookie, mtk_flow_ht_params)) -@@ -410,23 +395,21 @@ mtk_flow_offload_replace(struct mtk_eth - return -ENOMEM; - - entry->cookie = f->cookie; -- timestamp = mtk_eth_timestamp(eth); -- hash = mtk_foe_entry_commit(eth->ppe, &foe, timestamp); -- if (hash < 0) { -- err = hash; -+ memcpy(&entry->data, &foe, sizeof(entry->data)); -+ entry->wed_index = wed_index; -+ -+ if (mtk_foe_entry_commit(eth->ppe, entry) < 0) - goto free; -- } - -- entry->hash = hash; -- entry->wed_index = wed_index; - err = rhashtable_insert_fast(ð->flow_table, &entry->node, - mtk_flow_ht_params); - if (err < 0) -- goto clear_flow; -+ goto clear; - - return 0; --clear_flow: -- mtk_foe_entry_clear(eth->ppe, hash); -+ -+clear: -+ mtk_foe_entry_clear(eth->ppe, entry); - free: - kfree(entry); - if (wed_index >= 0) -@@ -444,7 +427,7 @@ mtk_flow_offload_destroy(struct mtk_eth - if (!entry) - return -ENOENT; - -- mtk_foe_entry_clear(eth->ppe, entry->hash); -+ mtk_foe_entry_clear(eth->ppe, entry); - rhashtable_remove_fast(ð->flow_table, &entry->node, - mtk_flow_ht_params); - if (entry->wed_index >= 0) -@@ -458,7 +441,6 @@ static int - mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) - { - struct mtk_flow_entry *entry; -- int timestamp; - u32 idle; - - entry = rhashtable_lookup(ð->flow_table, &f->cookie, -@@ -466,11 +448,7 @@ mtk_flow_offload_stats(struct mtk_eth *e - if (!entry) - return -ENOENT; - -- timestamp = mtk_foe_entry_timestamp(eth->ppe, entry->hash); -- if (timestamp < 0) -- return -ETIMEDOUT; -- -- idle = mtk_eth_timestamp(eth) - timestamp; -+ idle = mtk_foe_entry_idle_time(eth->ppe, entry); - f->stats.lastused = jiffies - idle * HZ; - - return 0; diff --git a/target/linux/generic/backport-5.15/702-v5.19-09-net-ethernet-mtk_eth_soc-remove-bridge-flow-offload-.patch b/target/linux/generic/backport-5.15/702-v5.19-09-net-ethernet-mtk_eth_soc-remove-bridge-flow-offload-.patch deleted file mode 100644 index 2ff0b341f9156a..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-09-net-ethernet-mtk_eth_soc-remove-bridge-flow-offload-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From: Felix Fietkau -Date: Mon, 21 Feb 2022 15:55:19 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: remove bridge flow offload - type entry support - -According to MediaTek, this feature is not supported in current hardware - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -84,13 +84,6 @@ static u32 mtk_ppe_hash_entry(struct mtk - u32 hash; - - switch (FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, e->ib1)) { -- case MTK_PPE_PKT_TYPE_BRIDGE: -- hv1 = e->bridge.src_mac_lo; -- hv1 ^= ((e->bridge.src_mac_hi & 0xffff) << 16); -- hv2 = e->bridge.src_mac_hi >> 16; -- hv2 ^= e->bridge.dest_mac_lo; -- hv3 = e->bridge.dest_mac_hi; -- break; - case MTK_PPE_PKT_TYPE_IPV4_ROUTE: - case MTK_PPE_PKT_TYPE_IPV4_HNAPT: - hv1 = e->ipv4.orig.ports; -@@ -572,7 +565,6 @@ int mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_FLOW_CFG_IP4_NAT | - MTK_PPE_FLOW_CFG_IP4_NAPT | - MTK_PPE_FLOW_CFG_IP4_DSLITE | -- MTK_PPE_FLOW_CFG_L2_BRIDGE | - MTK_PPE_FLOW_CFG_IP4_NAT_FRAG; - ppe_w32(ppe, MTK_PPE_FLOW_CFG, val); - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -32,7 +32,6 @@ static const char *mtk_foe_pkt_type_str( - static const char * const type_str[] = { - [MTK_PPE_PKT_TYPE_IPV4_HNAPT] = "IPv4 5T", - [MTK_PPE_PKT_TYPE_IPV4_ROUTE] = "IPv4 3T", -- [MTK_PPE_PKT_TYPE_BRIDGE] = "L2", - [MTK_PPE_PKT_TYPE_IPV4_DSLITE] = "DS-LITE", - [MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T] = "IPv6 3T", - [MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T] = "IPv6 5T", diff --git a/target/linux/generic/backport-5.15/702-v5.19-10-net-ethernet-mtk_eth_soc-support-creating-mac-addres.patch b/target/linux/generic/backport-5.15/702-v5.19-10-net-ethernet-mtk_eth_soc-support-creating-mac-addres.patch deleted file mode 100644 index 209c65e66aa039..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-10-net-ethernet-mtk_eth_soc-support-creating-mac-addres.patch +++ /dev/null @@ -1,553 +0,0 @@ -From: Felix Fietkau -Date: Wed, 23 Feb 2022 10:56:34 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: support creating mac - address based offload entries - -This will be used to implement a limited form of bridge offloading. -Since the hardware does not support flow table entries with just source -and destination MAC address, the driver has to emulate it. - -The hardware automatically creates entries entries for incoming flows, even -when they are bridged instead of routed, and reports when packets for these -flows have reached the minimum PPS rate for offloading. - -After this happens, we look up the L2 flow offload entry based on the MAC -header and fill in the output routing information in the flow table. -The dynamically created per-flow entries are automatically removed when -either the hardware flowtable entry expires, is replaced, or if the offload -rule they belong to is removed - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -6,12 +6,22 @@ - #include - #include - #include -+#include -+#include -+#include - #include "mtk_eth_soc.h" - #include "mtk_ppe.h" - #include "mtk_ppe_regs.h" - - static DEFINE_SPINLOCK(ppe_lock); - -+static const struct rhashtable_params mtk_flow_l2_ht_params = { -+ .head_offset = offsetof(struct mtk_flow_entry, l2_node), -+ .key_offset = offsetof(struct mtk_flow_entry, data.bridge), -+ .key_len = offsetof(struct mtk_foe_bridge, key_end), -+ .automatic_shrinking = true, -+}; -+ - static void ppe_w32(struct mtk_ppe *ppe, u32 reg, u32 val) - { - writel(val, ppe->base + reg); -@@ -123,6 +133,9 @@ mtk_foe_entry_l2(struct mtk_foe_entry *e - { - int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); - -+ if (type == MTK_PPE_PKT_TYPE_BRIDGE) -+ return &entry->bridge.l2; -+ - if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) - return &entry->ipv6.l2; - -@@ -134,6 +147,9 @@ mtk_foe_entry_ib2(struct mtk_foe_entry * - { - int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); - -+ if (type == MTK_PPE_PKT_TYPE_BRIDGE) -+ return &entry->bridge.ib2; -+ - if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) - return &entry->ipv6.ib2; - -@@ -168,7 +184,12 @@ int mtk_foe_entry_prepare(struct mtk_foe - if (type == MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T) - entry->ipv6.ports = ports_pad; - -- if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) { -+ if (type == MTK_PPE_PKT_TYPE_BRIDGE) { -+ ether_addr_copy(entry->bridge.src_mac, src_mac); -+ ether_addr_copy(entry->bridge.dest_mac, dest_mac); -+ entry->bridge.ib2 = val; -+ l2 = &entry->bridge.l2; -+ } else if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) { - entry->ipv6.ib2 = val; - l2 = &entry->ipv6.l2; - } else { -@@ -372,12 +393,96 @@ mtk_flow_entry_match(struct mtk_flow_ent - } - - static void -+__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+{ -+ struct hlist_head *head; -+ struct hlist_node *tmp; -+ -+ if (entry->type == MTK_FLOW_TYPE_L2) { -+ rhashtable_remove_fast(&ppe->l2_flows, &entry->l2_node, -+ mtk_flow_l2_ht_params); -+ -+ head = &entry->l2_flows; -+ hlist_for_each_entry_safe(entry, tmp, head, l2_data.list) -+ __mtk_foe_entry_clear(ppe, entry); -+ return; -+ } -+ -+ hlist_del_init(&entry->list); -+ if (entry->hash != 0xffff) { -+ ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE; -+ ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, -+ MTK_FOE_STATE_BIND); -+ dma_wmb(); -+ } -+ entry->hash = 0xffff; -+ -+ if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW) -+ return; -+ -+ hlist_del_init(&entry->l2_data.list); -+ kfree(entry); -+} -+ -+static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1) -+{ -+ u16 timestamp; -+ u16 now; -+ -+ now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP; -+ timestamp = ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; -+ -+ if (timestamp > now) -+ return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now; -+ else -+ return now - timestamp; -+} -+ -+static void -+mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+{ -+ struct mtk_flow_entry *cur; -+ struct mtk_foe_entry *hwe; -+ struct hlist_node *tmp; -+ int idle; -+ -+ idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_data.list) { -+ int cur_idle; -+ u32 ib1; -+ -+ hwe = &ppe->foe_table[cur->hash]; -+ ib1 = READ_ONCE(hwe->ib1); -+ -+ if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) { -+ cur->hash = 0xffff; -+ __mtk_foe_entry_clear(ppe, cur); -+ continue; -+ } -+ -+ cur_idle = __mtk_foe_entry_idle_time(ppe, ib1); -+ if (cur_idle >= idle) -+ continue; -+ -+ idle = cur_idle; -+ entry->data.ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; -+ entry->data.ib1 |= hwe->ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; -+ } -+} -+ -+static void - mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - struct mtk_foe_entry *hwe; - struct mtk_foe_entry foe; - - spin_lock_bh(&ppe_lock); -+ -+ if (entry->type == MTK_FLOW_TYPE_L2) { -+ mtk_flow_entry_update_l2(ppe, entry); -+ goto out; -+ } -+ - if (entry->hash == 0xffff) - goto out; - -@@ -419,21 +524,28 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - spin_lock_bh(&ppe_lock); -- hlist_del_init(&entry->list); -- if (entry->hash != 0xffff) { -- ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE; -- ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, -- MTK_FOE_STATE_BIND); -- dma_wmb(); -- } -- entry->hash = 0xffff; -+ __mtk_foe_entry_clear(ppe, entry); - spin_unlock_bh(&ppe_lock); - } - -+static int -+mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+{ -+ entry->type = MTK_FLOW_TYPE_L2; -+ -+ return rhashtable_insert_fast(&ppe->l2_flows, &entry->l2_node, -+ mtk_flow_l2_ht_params); -+} -+ - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -- u32 hash = mtk_ppe_hash_entry(&entry->data); -+ int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); -+ u32 hash; -+ -+ if (type == MTK_PPE_PKT_TYPE_BRIDGE) -+ return mtk_foe_entry_commit_l2(ppe, entry); - -+ hash = mtk_ppe_hash_entry(&entry->data); - entry->hash = 0xffff; - spin_lock_bh(&ppe_lock); - hlist_add_head(&entry->list, &ppe->foe_flow[hash / 2]); -@@ -442,18 +554,72 @@ int mtk_foe_entry_commit(struct mtk_ppe - return 0; - } - -+static void -+mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ u16 hash) -+{ -+ struct mtk_flow_entry *flow_info; -+ struct mtk_foe_entry foe, *hwe; -+ struct mtk_foe_mac_info *l2; -+ u32 ib1_mask = MTK_FOE_IB1_PACKET_TYPE | MTK_FOE_IB1_UDP; -+ int type; -+ -+ flow_info = kzalloc(offsetof(struct mtk_flow_entry, l2_data.end), -+ GFP_ATOMIC); -+ if (!flow_info) -+ return; -+ -+ flow_info->l2_data.base_flow = entry; -+ flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW; -+ flow_info->hash = hash; -+ hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / 2]); -+ hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows); -+ -+ hwe = &ppe->foe_table[hash]; -+ memcpy(&foe, hwe, sizeof(foe)); -+ foe.ib1 &= ib1_mask; -+ foe.ib1 |= entry->data.ib1 & ~ib1_mask; -+ -+ l2 = mtk_foe_entry_l2(&foe); -+ memcpy(l2, &entry->data.bridge.l2, sizeof(*l2)); -+ -+ type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, foe.ib1); -+ if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT) -+ memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new)); -+ else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP) -+ l2->etype = ETH_P_IPV6; -+ -+ *mtk_foe_entry_ib2(&foe) = entry->data.bridge.ib2; -+ -+ __mtk_foe_entry_commit(ppe, &foe, hash); -+} -+ - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - { - struct hlist_head *head = &ppe->foe_flow[hash / 2]; -- struct mtk_flow_entry *entry; - struct mtk_foe_entry *hwe = &ppe->foe_table[hash]; -+ struct mtk_flow_entry *entry; -+ struct mtk_foe_bridge key = {}; -+ struct ethhdr *eh; - bool found = false; -- -- if (hlist_empty(head)) -- return; -+ u8 *tag; - - spin_lock_bh(&ppe_lock); -+ -+ if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND) -+ goto out; -+ - hlist_for_each_entry(entry, head, list) { -+ if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) { -+ if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == -+ MTK_FOE_STATE_BIND)) -+ continue; -+ -+ entry->hash = 0xffff; -+ __mtk_foe_entry_clear(ppe, entry); -+ continue; -+ } -+ - if (found || !mtk_flow_entry_match(entry, hwe)) { - if (entry->hash != 0xffff) - entry->hash = 0xffff; -@@ -464,21 +630,50 @@ void __mtk_ppe_check_skb(struct mtk_ppe - __mtk_foe_entry_commit(ppe, &entry->data, hash); - found = true; - } -+ -+ if (found) -+ goto out; -+ -+ eh = eth_hdr(skb); -+ ether_addr_copy(key.dest_mac, eh->h_dest); -+ ether_addr_copy(key.src_mac, eh->h_source); -+ tag = skb->data - 2; -+ key.vlan = 0; -+ switch (skb->protocol) { -+#if IS_ENABLED(CONFIG_NET_DSA) -+ case htons(ETH_P_XDSA): -+ if (!netdev_uses_dsa(skb->dev) || -+ skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK) -+ goto out; -+ -+ tag += 4; -+ if (get_unaligned_be16(tag) != ETH_P_8021Q) -+ break; -+ -+ fallthrough; -+#endif -+ case htons(ETH_P_8021Q): -+ key.vlan = get_unaligned_be16(tag + 2) & VLAN_VID_MASK; -+ break; -+ default: -+ break; -+ } -+ -+ entry = rhashtable_lookup_fast(&ppe->l2_flows, &key, mtk_flow_l2_ht_params); -+ if (!entry) -+ goto out; -+ -+ mtk_foe_entry_commit_subflow(ppe, entry, hash); -+ -+out: - spin_unlock_bh(&ppe_lock); - } - - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -- u16 now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP; -- u16 timestamp; -- - mtk_flow_entry_update(ppe, entry); -- timestamp = entry->data.ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; - -- if (timestamp > now) -- return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now; -- else -- return now - timestamp; -+ return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); - } - - struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, -@@ -492,6 +687,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - if (!ppe) - return NULL; - -+ rhashtable_init(&ppe->l2_flows, &mtk_flow_l2_ht_params); -+ - /* need to allocate a separate device, since it PPE DMA access is - * not coherent. - */ ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -6,6 +6,7 @@ - - #include - #include -+#include - - #define MTK_ETH_PPE_BASE 0xc00 - -@@ -84,19 +85,16 @@ struct mtk_foe_mac_info { - u16 src_mac_lo; - }; - -+/* software-only entry type */ - struct mtk_foe_bridge { -- u32 dest_mac_hi; -- -- u16 src_mac_lo; -- u16 dest_mac_lo; -+ u8 dest_mac[ETH_ALEN]; -+ u8 src_mac[ETH_ALEN]; -+ u16 vlan; - -- u32 src_mac_hi; -+ struct {} key_end; - - u32 ib2; - -- u32 _rsv[5]; -- -- u32 udf_tsid; - struct mtk_foe_mac_info l2; - }; - -@@ -235,13 +233,33 @@ enum { - MTK_PPE_CPU_REASON_INVALID = 0x1f, - }; - -+enum { -+ MTK_FLOW_TYPE_L4, -+ MTK_FLOW_TYPE_L2, -+ MTK_FLOW_TYPE_L2_SUBFLOW, -+}; -+ - struct mtk_flow_entry { -+ union { -+ struct hlist_node list; -+ struct { -+ struct rhash_head l2_node; -+ struct hlist_head l2_flows; -+ }; -+ }; -+ u8 type; -+ s8 wed_index; -+ u16 hash; -+ union { -+ struct mtk_foe_entry data; -+ struct { -+ struct mtk_flow_entry *base_flow; -+ struct hlist_node list; -+ struct {} end; -+ } l2_data; -+ }; - struct rhash_head node; -- struct hlist_node list; - unsigned long cookie; -- struct mtk_foe_entry data; -- u16 hash; -- s8 wed_index; - }; - - struct mtk_ppe { -@@ -256,6 +274,8 @@ struct mtk_ppe { - u16 foe_check_time[MTK_PPE_ENTRIES]; - struct hlist_head foe_flow[MTK_PPE_ENTRIES / 2]; - -+ struct rhashtable l2_flows; -+ - void *acct_table; - }; - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -31,6 +31,8 @@ struct mtk_flow_data { - __be16 src_port; - __be16 dst_port; - -+ u16 vlan_in; -+ - struct { - u16 id; - __be16 proto; -@@ -257,9 +259,45 @@ mtk_flow_offload_replace(struct mtk_eth - return -EOPNOTSUPP; - } - -+ switch (addr_type) { -+ case 0: -+ offload_type = MTK_PPE_PKT_TYPE_BRIDGE; -+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { -+ struct flow_match_eth_addrs match; -+ -+ flow_rule_match_eth_addrs(rule, &match); -+ memcpy(data.eth.h_dest, match.key->dst, ETH_ALEN); -+ memcpy(data.eth.h_source, match.key->src, ETH_ALEN); -+ } else { -+ return -EOPNOTSUPP; -+ } -+ -+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) { -+ struct flow_match_vlan match; -+ -+ flow_rule_match_vlan(rule, &match); -+ -+ if (match.key->vlan_tpid != cpu_to_be16(ETH_P_8021Q)) -+ return -EOPNOTSUPP; -+ -+ data.vlan_in = match.key->vlan_id; -+ } -+ break; -+ case FLOW_DISSECTOR_KEY_IPV4_ADDRS: -+ offload_type = MTK_PPE_PKT_TYPE_IPV4_HNAPT; -+ break; -+ case FLOW_DISSECTOR_KEY_IPV6_ADDRS: -+ offload_type = MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T; -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ - flow_action_for_each(i, act, &rule->action) { - switch (act->id) { - case FLOW_ACTION_MANGLE: -+ if (offload_type == MTK_PPE_PKT_TYPE_BRIDGE) -+ return -EOPNOTSUPP; - if (act->mangle.htype == FLOW_ACT_MANGLE_HDR_TYPE_ETH) - mtk_flow_offload_mangle_eth(act, &data.eth); - break; -@@ -291,17 +329,6 @@ mtk_flow_offload_replace(struct mtk_eth - } - } - -- switch (addr_type) { -- case FLOW_DISSECTOR_KEY_IPV4_ADDRS: -- offload_type = MTK_PPE_PKT_TYPE_IPV4_HNAPT; -- break; -- case FLOW_DISSECTOR_KEY_IPV6_ADDRS: -- offload_type = MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T; -- break; -- default: -- return -EOPNOTSUPP; -- } -- - if (!is_valid_ether_addr(data.eth.h_source) || - !is_valid_ether_addr(data.eth.h_dest)) - return -EINVAL; -@@ -315,10 +342,13 @@ mtk_flow_offload_replace(struct mtk_eth - if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { - struct flow_match_ports ports; - -+ if (offload_type == MTK_PPE_PKT_TYPE_BRIDGE) -+ return -EOPNOTSUPP; -+ - flow_rule_match_ports(rule, &ports); - data.src_port = ports.key->src; - data.dst_port = ports.key->dst; -- } else { -+ } else if (offload_type != MTK_PPE_PKT_TYPE_BRIDGE) { - return -EOPNOTSUPP; - } - -@@ -348,6 +378,9 @@ mtk_flow_offload_replace(struct mtk_eth - if (act->id != FLOW_ACTION_MANGLE) - continue; - -+ if (offload_type == MTK_PPE_PKT_TYPE_BRIDGE) -+ return -EOPNOTSUPP; -+ - switch (act->mangle.htype) { - case FLOW_ACT_MANGLE_HDR_TYPE_TCP: - case FLOW_ACT_MANGLE_HDR_TYPE_UDP: -@@ -373,6 +406,9 @@ mtk_flow_offload_replace(struct mtk_eth - return err; - } - -+ if (offload_type == MTK_PPE_PKT_TYPE_BRIDGE) -+ foe.bridge.vlan = data.vlan_in; -+ - if (data.vlan.num == 1) { - if (data.vlan.proto != htons(ETH_P_8021Q)) - return -EOPNOTSUPP; diff --git a/target/linux/generic/backport-5.15/702-v5.19-11-net-ethernet-mtk_eth_soc-wed-fix-sparse-endian-warni.patch b/target/linux/generic/backport-5.15/702-v5.19-11-net-ethernet-mtk_eth_soc-wed-fix-sparse-endian-warni.patch deleted file mode 100644 index 8f3dfe82399f82..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-11-net-ethernet-mtk_eth_soc-wed-fix-sparse-endian-warni.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: Felix Fietkau -Date: Fri, 8 Apr 2022 10:59:45 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc/wed: fix sparse endian warnings - -Descriptor fields are little-endian - -Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)") -Reported-by: kernel test robot -Signed-off-by: Felix Fietkau -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -144,16 +144,17 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi - - for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) { - u32 txd_size; -+ u32 ctrl; - - txd_size = dev->wlan.init_buf(buf, buf_phys, token++); - -- desc->buf0 = buf_phys; -- desc->buf1 = buf_phys + txd_size; -- desc->ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, -- txd_size) | -- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -- MTK_WED_BUF_SIZE - txd_size) | -- MTK_WDMA_DESC_CTRL_LAST_SEG1; -+ desc->buf0 = cpu_to_le32(buf_phys); -+ desc->buf1 = cpu_to_le32(buf_phys + txd_size); -+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -+ MTK_WED_BUF_SIZE - txd_size) | -+ MTK_WDMA_DESC_CTRL_LAST_SEG1; -+ desc->ctrl = cpu_to_le32(ctrl); - desc->info = 0; - desc++; - -@@ -184,12 +185,14 @@ mtk_wed_free_buffer(struct mtk_wed_devic - - for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) { - void *page = page_list[page_idx++]; -+ dma_addr_t buf_addr; - - if (!page) - break; - -- dma_unmap_page(dev->hw->dev, desc[i].buf0, -- PAGE_SIZE, DMA_BIDIRECTIONAL); -+ buf_addr = le32_to_cpu(desc[i].buf0); -+ dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); - __free_page(page); - } - diff --git a/target/linux/generic/backport-5.15/702-v5.19-12-net-ethernet-mtk_eth_soc-fix-return-value-check-in-m.patch b/target/linux/generic/backport-5.15/702-v5.19-12-net-ethernet-mtk_eth_soc-fix-return-value-check-in-m.patch deleted file mode 100644 index 4ec8fe74bc7d7a..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-12-net-ethernet-mtk_eth_soc-fix-return-value-check-in-m.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Yang Yingliang -Date: Fri, 8 Apr 2022 11:22:46 +0800 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix return value check in - mtk_wed_add_hw() - -If syscon_regmap_lookup_by_phandle() fails, it never return NULL pointer, -change the check to IS_ERR(). - -Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)") -Reported-by: Hulk Robot -Signed-off-by: Yang Yingliang -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -816,7 +816,7 @@ void mtk_wed_add_hw(struct device_node * - return; - - regs = syscon_regmap_lookup_by_phandle(np, NULL); -- if (!regs) -+ if (IS_ERR(regs)) - return; - - rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops); diff --git a/target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch b/target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch deleted file mode 100644 index 22125a454624fe..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-13-net-ethernet-mtk_eth_soc-use-standard-property-for-c.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 11 Apr 2022 12:13:25 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: use standard property for - cci-control-port - -Rely on standard cci-control-port property to identify CCI port -reference. -Update mt7622 dts binding. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi -+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi -@@ -957,7 +957,7 @@ - power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; - mediatek,ethsys = <ðsys>; - mediatek,sgmiisys = <&sgmiisys>; -- mediatek,cci-control = <&cci_control2>; -+ cci-control-port = <&cci_control2>; - mediatek,wed = <&wed0>, <&wed1>; - mediatek,pcie-mirror = <&pcie_mirror>; - mediatek,hifsys = <&hifsys>; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3194,7 +3194,7 @@ static int mtk_probe(struct platform_dev - struct regmap *cci; - - cci = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, -- "mediatek,cci-control"); -+ "cci-control-port"); - /* enable CPU/bus coherency */ - if (!IS_ERR(cci)) - regmap_write(cci, 0, 3); diff --git a/target/linux/generic/backport-5.15/702-v5.19-14-net-ethernet-mtk_eth_soc-use-after-free-in-__mtk_ppe.patch b/target/linux/generic/backport-5.15/702-v5.19-14-net-ethernet-mtk_eth_soc-use-after-free-in-__mtk_ppe.patch deleted file mode 100644 index 656b3a159e8d16..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-14-net-ethernet-mtk_eth_soc-use-after-free-in-__mtk_ppe.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Dan Carpenter -Date: Tue, 12 Apr 2022 12:24:19 +0300 -Subject: [PATCH] net: ethernet: mtk_eth_soc: use after free in - __mtk_ppe_check_skb() - -The __mtk_foe_entry_clear() function frees "entry" so we have to use -the _safe() version of hlist_for_each_entry() to prevent a use after -free. - -Fixes: 33fc42de3327 ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries") -Signed-off-by: Dan Carpenter -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -600,6 +600,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe - struct mtk_foe_entry *hwe = &ppe->foe_table[hash]; - struct mtk_flow_entry *entry; - struct mtk_foe_bridge key = {}; -+ struct hlist_node *n; - struct ethhdr *eh; - bool found = false; - u8 *tag; -@@ -609,7 +610,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe - if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND) - goto out; - -- hlist_for_each_entry(entry, head, list) { -+ hlist_for_each_entry_safe(entry, n, head, list) { - if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) { - if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == - MTK_FOE_STATE_BIND)) diff --git a/target/linux/generic/backport-5.15/702-v5.19-15-net-ethernet-mtk_eth_soc-add-check-for-allocation-fa.patch b/target/linux/generic/backport-5.15/702-v5.19-15-net-ethernet-mtk_eth_soc-add-check-for-allocation-fa.patch deleted file mode 100644 index 714163c86bb048..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-15-net-ethernet-mtk_eth_soc-add-check-for-allocation-fa.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Dan Carpenter -Date: Thu, 21 Apr 2022 18:49:02 +0300 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add check for allocation failure - -Check if the kzalloc() failed. - -Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)") -Signed-off-by: Dan Carpenter -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -827,6 +827,8 @@ void mtk_wed_add_hw(struct device_node * - goto unlock; - - hw = kzalloc(sizeof(*hw), GFP_KERNEL); -+ if (!hw) -+ goto unlock; - hw->node = np; - hw->regs = regs; - hw->eth = eth; diff --git a/target/linux/generic/backport-5.15/702-v5.19-16-eth-mtk_eth_soc-silence-the-GCC-12-array-bounds-warn.patch b/target/linux/generic/backport-5.15/702-v5.19-16-eth-mtk_eth_soc-silence-the-GCC-12-array-bounds-warn.patch deleted file mode 100644 index aa98745ac60e5b..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-16-eth-mtk_eth_soc-silence-the-GCC-12-array-bounds-warn.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Jakub Kicinski -Date: Fri, 20 May 2022 12:56:03 -0700 -Subject: [PATCH] eth: mtk_eth_soc: silence the GCC 12 array-bounds warning - -GCC 12 gets upset because in mtk_foe_entry_commit_subflow() -this driver allocates a partial structure. The writes are -within bounds. - -Silence these warnings for now, our build bot runs GCC 12 -so we won't allow any new instances. - -Signed-off-by: Jakub Kicinski -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -11,3 +11,8 @@ mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) + - endif - obj-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_ops.o - obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o -+ -+# FIXME: temporarily silence -Warray-bounds on non W=1+ builds -+ifndef KBUILD_EXTRA_WARN -+CFLAGS_mtk_ppe.o += -Wno-array-bounds -+endif diff --git a/target/linux/generic/backport-5.15/702-v5.19-17-net-ethernet-mtk_eth_soc-rely-on-GFP_KERNEL-for-dma_.patch b/target/linux/generic/backport-5.15/702-v5.19-17-net-ethernet-mtk_eth_soc-rely-on-GFP_KERNEL-for-dma_.patch deleted file mode 100644 index 268b372388f98e..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-17-net-ethernet-mtk_eth_soc-rely-on-GFP_KERNEL-for-dma_.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:26 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on GFP_KERNEL for - dma_alloc_coherent whenever possible - -Rely on GFP_KERNEL for dma descriptors mappings in mtk_tx_alloc(), -mtk_rx_alloc() and mtk_init_fq_dma() since they are run in non-irq -context. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -856,7 +856,7 @@ static int mtk_init_fq_dma(struct mtk_et - eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, - cnt * sizeof(struct mtk_tx_dma), - ð->phy_scratch_ring, -- GFP_ATOMIC); -+ GFP_KERNEL); - if (unlikely(!eth->scratch_ring)) - return -ENOMEM; - -@@ -1634,7 +1634,7 @@ static int mtk_tx_alloc(struct mtk_eth * - goto no_tx_mem; - - ring->dma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, -- &ring->phys, GFP_ATOMIC); -+ &ring->phys, GFP_KERNEL); - if (!ring->dma) - goto no_tx_mem; - -@@ -1652,8 +1652,7 @@ static int mtk_tx_alloc(struct mtk_eth * - */ - if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { - ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, -- &ring->phys_pdma, -- GFP_ATOMIC); -+ &ring->phys_pdma, GFP_KERNEL); - if (!ring->dma_pdma) - goto no_tx_mem; - -@@ -1768,7 +1767,7 @@ static int mtk_rx_alloc(struct mtk_eth * - - ring->dma = dma_alloc_coherent(eth->dma_dev, - rx_dma_size * sizeof(*ring->dma), -- &ring->phys, GFP_ATOMIC); -+ &ring->phys, GFP_KERNEL); - if (!ring->dma) - return -ENOMEM; - diff --git a/target/linux/generic/backport-5.15/702-v5.19-18-net-ethernet-mtk_eth_soc-move-tx-dma-desc-configurat.patch b/target/linux/generic/backport-5.15/702-v5.19-18-net-ethernet-mtk_eth_soc-move-tx-dma-desc-configurat.patch deleted file mode 100644 index dc85786be29470..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-18-net-ethernet-mtk_eth_soc-move-tx-dma-desc-configurat.patch +++ /dev/null @@ -1,206 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:27 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: move tx dma desc configuration in - mtk_tx_set_dma_desc - -Move tx dma descriptor configuration in mtk_tx_set_dma_desc routine. -This is a preliminary patch to introduce mt7986 ethernet support since -it relies on a different tx dma descriptor layout. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -982,18 +982,51 @@ static void setup_tx_buf(struct mtk_eth - } - } - -+static void mtk_tx_set_dma_desc(struct net_device *dev, struct mtk_tx_dma *desc, -+ struct mtk_tx_dma_desc_info *info) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ u32 data; -+ -+ WRITE_ONCE(desc->txd1, info->addr); -+ -+ data = TX_DMA_SWC | TX_DMA_PLEN0(info->size); -+ if (info->last) -+ data |= TX_DMA_LS0; -+ WRITE_ONCE(desc->txd3, data); -+ -+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT; /* forward port */ -+ if (info->first) { -+ if (info->gso) -+ data |= TX_DMA_TSO; -+ /* tx checksum offload */ -+ if (info->csum) -+ data |= TX_DMA_CHKSUM; -+ /* vlan header offload */ -+ if (info->vlan) -+ data |= TX_DMA_INS_VLAN | info->vlan_tci; -+ } -+ WRITE_ONCE(desc->txd4, data); -+} -+ - static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - int tx_num, struct mtk_tx_ring *ring, bool gso) - { -+ struct mtk_tx_dma_desc_info txd_info = { -+ .size = skb_headlen(skb), -+ .gso = gso, -+ .csum = skb->ip_summed == CHECKSUM_PARTIAL, -+ .vlan = skb_vlan_tag_present(skb), -+ .vlan_tci = skb_vlan_tag_get(skb), -+ .first = true, -+ .last = !skb_is_nonlinear(skb), -+ }; - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - struct mtk_tx_dma *itxd, *txd; - struct mtk_tx_dma *itxd_pdma, *txd_pdma; - struct mtk_tx_buf *itx_buf, *tx_buf; -- dma_addr_t mapped_addr; -- unsigned int nr_frags; - int i, n_desc = 1; -- u32 txd4 = 0, fport; - int k = 0; - - itxd = ring->next_free; -@@ -1001,49 +1034,32 @@ static int mtk_tx_map(struct sk_buff *sk - if (itxd == ring->last_free) - return -ENOMEM; - -- /* set the forward port */ -- fport = (mac->id + 1) << TX_DMA_FPORT_SHIFT; -- txd4 |= fport; -- - itx_buf = mtk_desc_to_tx_buf(ring, itxd); - memset(itx_buf, 0, sizeof(*itx_buf)); - -- if (gso) -- txd4 |= TX_DMA_TSO; -- -- /* TX Checksum offload */ -- if (skb->ip_summed == CHECKSUM_PARTIAL) -- txd4 |= TX_DMA_CHKSUM; -- -- /* VLAN header offload */ -- if (skb_vlan_tag_present(skb)) -- txd4 |= TX_DMA_INS_VLAN | skb_vlan_tag_get(skb); -- -- mapped_addr = dma_map_single(eth->dma_dev, skb->data, -- skb_headlen(skb), DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(eth->dma_dev, mapped_addr))) -+ txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size, -+ DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) - return -ENOMEM; - -- WRITE_ONCE(itxd->txd1, mapped_addr); -+ mtk_tx_set_dma_desc(dev, itxd, &txd_info); -+ - itx_buf->flags |= MTK_TX_FLAGS_SINGLE0; - itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : - MTK_TX_FLAGS_FPORT1; -- setup_tx_buf(eth, itx_buf, itxd_pdma, mapped_addr, skb_headlen(skb), -+ setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, - k++); - - /* TX SG offload */ - txd = itxd; - txd_pdma = qdma_to_pdma(ring, txd); -- nr_frags = skb_shinfo(skb)->nr_frags; - -- for (i = 0; i < nr_frags; i++) { -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - unsigned int offset = 0; - int frag_size = skb_frag_size(frag); - - while (frag_size) { -- bool last_frag = false; -- unsigned int frag_map_size; - bool new_desc = true; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA) || -@@ -1058,23 +1074,17 @@ static int mtk_tx_map(struct sk_buff *sk - new_desc = false; - } - -- -- frag_map_size = min(frag_size, MTK_TX_DMA_BUF_LEN); -- mapped_addr = skb_frag_dma_map(eth->dma_dev, frag, offset, -- frag_map_size, -- DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(eth->dma_dev, mapped_addr))) -+ memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); -+ txd_info.size = min(frag_size, MTK_TX_DMA_BUF_LEN); -+ txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 && -+ !(frag_size - txd_info.size); -+ txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, -+ offset, txd_info.size, -+ DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) - goto err_dma; - -- if (i == nr_frags - 1 && -- (frag_size - frag_map_size) == 0) -- last_frag = true; -- -- WRITE_ONCE(txd->txd1, mapped_addr); -- WRITE_ONCE(txd->txd3, (TX_DMA_SWC | -- TX_DMA_PLEN0(frag_map_size) | -- last_frag * TX_DMA_LS0)); -- WRITE_ONCE(txd->txd4, fport); -+ mtk_tx_set_dma_desc(dev, txd, &txd_info); - - tx_buf = mtk_desc_to_tx_buf(ring, txd); - if (new_desc) -@@ -1084,20 +1094,17 @@ static int mtk_tx_map(struct sk_buff *sk - tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : - MTK_TX_FLAGS_FPORT1; - -- setup_tx_buf(eth, tx_buf, txd_pdma, mapped_addr, -- frag_map_size, k++); -+ setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, -+ txd_info.size, k++); - -- frag_size -= frag_map_size; -- offset += frag_map_size; -+ frag_size -= txd_info.size; -+ offset += txd_info.size; - } - } - - /* store skb to cleanup */ - itx_buf->skb = skb; - -- WRITE_ONCE(itxd->txd4, txd4); -- WRITE_ONCE(itxd->txd3, (TX_DMA_SWC | TX_DMA_PLEN0(skb_headlen(skb)) | -- (!nr_frags * TX_DMA_LS0))); - if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { - if (k & 0x1) - txd_pdma->txd2 |= TX_DMA_LS0; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -843,6 +843,17 @@ enum mkt_eth_capabilities { - MTK_MUX_U3_GMAC2_TO_QPHY | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) - -+struct mtk_tx_dma_desc_info { -+ dma_addr_t addr; -+ u32 size; -+ u16 vlan_tci; -+ u8 gso:1; -+ u8 csum:1; -+ u8 vlan:1; -+ u8 first:1; -+ u8 last:1; -+}; -+ - /* struct mtk_eth_data - This is the structure holding all differences - * among various plaforms - * @ana_rgc3: The offset for register ANA_RGC3 related to diff --git a/target/linux/generic/backport-5.15/702-v5.19-19-net-ethernet-mtk_eth_soc-add-txd_size-to-mtk_soc_dat.patch b/target/linux/generic/backport-5.15/702-v5.19-19-net-ethernet-mtk_eth_soc-add-txd_size-to-mtk_soc_dat.patch deleted file mode 100644 index 7e05181b5e39e5..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-19-net-ethernet-mtk_eth_soc-add-txd_size-to-mtk_soc_dat.patch +++ /dev/null @@ -1,167 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:28 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add txd_size to mtk_soc_data - -In order to remove mtk_tx_dma size dependency, introduce txd_size in -mtk_soc_data data structure. Rely on txd_size in mtk_init_fq_dma() and -mtk_dma_free() routines. -This is a preliminary patch to add mt7986 ethernet support. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -848,20 +848,20 @@ static void *mtk_max_lro_buf_alloc(gfp_t - /* the qdma core needs scratch memory to be setup */ - static int mtk_init_fq_dma(struct mtk_eth *eth) - { -+ const struct mtk_soc_data *soc = eth->soc; - dma_addr_t phy_ring_tail; - int cnt = MTK_DMA_SIZE; - dma_addr_t dma_addr; - int i; - - eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, -- cnt * sizeof(struct mtk_tx_dma), -+ cnt * soc->txrx.txd_size, - ð->phy_scratch_ring, - GFP_KERNEL); - if (unlikely(!eth->scratch_ring)) - return -ENOMEM; - -- eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE, -- GFP_KERNEL); -+ eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE, GFP_KERNEL); - if (unlikely(!eth->scratch_head)) - return -ENOMEM; - -@@ -871,16 +871,19 @@ static int mtk_init_fq_dma(struct mtk_et - if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) - return -ENOMEM; - -- phy_ring_tail = eth->phy_scratch_ring + -- (sizeof(struct mtk_tx_dma) * (cnt - 1)); -+ phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt - 1); - - for (i = 0; i < cnt; i++) { -- eth->scratch_ring[i].txd1 = -- (dma_addr + (i * MTK_QDMA_PAGE_SIZE)); -+ struct mtk_tx_dma *txd; -+ -+ txd = (void *)eth->scratch_ring + i * soc->txrx.txd_size; -+ txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE; - if (i < cnt - 1) -- eth->scratch_ring[i].txd2 = (eth->phy_scratch_ring + -- ((i + 1) * sizeof(struct mtk_tx_dma))); -- eth->scratch_ring[i].txd3 = TX_DMA_SDL(MTK_QDMA_PAGE_SIZE); -+ txd->txd2 = eth->phy_scratch_ring + -+ (i + 1) * soc->txrx.txd_size; -+ -+ txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE); -+ txd->txd4 = 0; - } - - mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD); -@@ -2183,6 +2186,7 @@ static int mtk_dma_init(struct mtk_eth * - - static void mtk_dma_free(struct mtk_eth *eth) - { -+ const struct mtk_soc_data *soc = eth->soc; - int i; - - for (i = 0; i < MTK_MAC_COUNT; i++) -@@ -2190,9 +2194,8 @@ static void mtk_dma_free(struct mtk_eth - netdev_reset_queue(eth->netdev[i]); - if (eth->scratch_ring) { - dma_free_coherent(eth->dma_dev, -- MTK_DMA_SIZE * sizeof(struct mtk_tx_dma), -- eth->scratch_ring, -- eth->phy_scratch_ring); -+ MTK_DMA_SIZE * soc->txrx.txd_size, -+ eth->scratch_ring, eth->phy_scratch_ring); - eth->scratch_ring = NULL; - eth->phy_scratch_ring = 0; - } -@@ -3397,6 +3400,9 @@ static const struct mtk_soc_data mt2701_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma), -+ }, - }; - - static const struct mtk_soc_data mt7621_data = { -@@ -3405,6 +3411,9 @@ static const struct mtk_soc_data mt7621_ - .required_clks = MT7621_CLKS_BITMAP, - .required_pctl = false, - .offload_version = 2, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma), -+ }, - }; - - static const struct mtk_soc_data mt7622_data = { -@@ -3414,6 +3423,9 @@ static const struct mtk_soc_data mt7622_ - .required_clks = MT7622_CLKS_BITMAP, - .required_pctl = false, - .offload_version = 2, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma), -+ }, - }; - - static const struct mtk_soc_data mt7623_data = { -@@ -3422,6 +3434,9 @@ static const struct mtk_soc_data mt7623_ - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, - .offload_version = 2, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma), -+ }, - }; - - static const struct mtk_soc_data mt7629_data = { -@@ -3430,6 +3445,9 @@ static const struct mtk_soc_data mt7629_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7629_CLKS_BITMAP, - .required_pctl = false, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma), -+ }, - }; - - static const struct mtk_soc_data rt5350_data = { -@@ -3437,6 +3455,9 @@ static const struct mtk_soc_data rt5350_ - .hw_features = MTK_HW_FEATURES_MT7628, - .required_clks = MT7628_CLKS_BITMAP, - .required_pctl = false, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma), -+ }, - }; - - const struct of_device_id of_mtk_match[] = { ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -864,6 +864,7 @@ struct mtk_tx_dma_desc_info { - * the target SoC - * @required_pctl A bool value to show whether the SoC requires - * the extra setup for those pins used by GMAC. -+ * @txd_size Tx DMA descriptor size. - */ - struct mtk_soc_data { - u32 ana_rgc3; -@@ -872,6 +873,9 @@ struct mtk_soc_data { - bool required_pctl; - u8 offload_version; - netdev_features_t hw_features; -+ struct { -+ u32 txd_size; -+ } txrx; - }; - - /* currently no SoC has more than 2 macs */ diff --git a/target/linux/generic/backport-5.15/702-v5.19-20-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_tx_.patch b/target/linux/generic/backport-5.15/702-v5.19-20-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_tx_.patch deleted file mode 100644 index 0547d7874f3d10..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-20-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_tx_.patch +++ /dev/null @@ -1,78 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:29 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on txd_size in - mtk_tx_alloc/mtk_tx_clean - -This is a preliminary patch to add mt7986 ethernet support. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1635,8 +1635,10 @@ static int mtk_napi_rx(struct napi_struc - - static int mtk_tx_alloc(struct mtk_eth *eth) - { -+ const struct mtk_soc_data *soc = eth->soc; - struct mtk_tx_ring *ring = ð->tx_ring; -- int i, sz = sizeof(*ring->dma); -+ int i, sz = soc->txrx.txd_size; -+ struct mtk_tx_dma *txd; - - ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf), - GFP_KERNEL); -@@ -1652,8 +1654,10 @@ static int mtk_tx_alloc(struct mtk_eth * - int next = (i + 1) % MTK_DMA_SIZE; - u32 next_ptr = ring->phys + next * sz; - -- ring->dma[i].txd2 = next_ptr; -- ring->dma[i].txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; -+ txd = (void *)ring->dma + i * sz; -+ txd->txd2 = next_ptr; -+ txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; -+ txd->txd4 = 0; - } - - /* On MT7688 (PDMA only) this driver uses the ring->dma structs -@@ -1675,7 +1679,7 @@ static int mtk_tx_alloc(struct mtk_eth * - ring->dma_size = MTK_DMA_SIZE; - atomic_set(&ring->free_count, MTK_DMA_SIZE - 2); - ring->next_free = &ring->dma[0]; -- ring->last_free = &ring->dma[MTK_DMA_SIZE - 1]; -+ ring->last_free = (void *)txd; - ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz)); - ring->thresh = MAX_SKB_FRAGS; - -@@ -1708,6 +1712,7 @@ no_tx_mem: - - static void mtk_tx_clean(struct mtk_eth *eth) - { -+ const struct mtk_soc_data *soc = eth->soc; - struct mtk_tx_ring *ring = ð->tx_ring; - int i; - -@@ -1720,17 +1725,15 @@ static void mtk_tx_clean(struct mtk_eth - - if (ring->dma) { - dma_free_coherent(eth->dma_dev, -- MTK_DMA_SIZE * sizeof(*ring->dma), -- ring->dma, -- ring->phys); -+ MTK_DMA_SIZE * soc->txrx.txd_size, -+ ring->dma, ring->phys); - ring->dma = NULL; - } - - if (ring->dma_pdma) { - dma_free_coherent(eth->dma_dev, -- MTK_DMA_SIZE * sizeof(*ring->dma_pdma), -- ring->dma_pdma, -- ring->phys_pdma); -+ MTK_DMA_SIZE * soc->txrx.txd_size, -+ ring->dma_pdma, ring->phys_pdma); - ring->dma_pdma = NULL; - } - } diff --git a/target/linux/generic/backport-5.15/702-v5.19-21-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_des.patch b/target/linux/generic/backport-5.15/702-v5.19-21-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_des.patch deleted file mode 100644 index b76d69c50e4da2..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-21-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-mtk_des.patch +++ /dev/null @@ -1,109 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:30 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on txd_size in - mtk_desc_to_tx_buf - -This is a preliminary patch to add mt7986 ethernet support. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -901,10 +901,11 @@ static inline void *mtk_qdma_phys_to_vir - return ret + (desc - ring->phys); - } - --static inline struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring, -- struct mtk_tx_dma *txd) -+static struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring, -+ struct mtk_tx_dma *txd, -+ u32 txd_size) - { -- int idx = txd - ring->dma; -+ int idx = ((void *)txd - (void *)ring->dma) / txd_size; - - return &ring->buf[idx]; - } -@@ -1026,6 +1027,7 @@ static int mtk_tx_map(struct sk_buff *sk - }; - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; -+ const struct mtk_soc_data *soc = eth->soc; - struct mtk_tx_dma *itxd, *txd; - struct mtk_tx_dma *itxd_pdma, *txd_pdma; - struct mtk_tx_buf *itx_buf, *tx_buf; -@@ -1037,7 +1039,7 @@ static int mtk_tx_map(struct sk_buff *sk - if (itxd == ring->last_free) - return -ENOMEM; - -- itx_buf = mtk_desc_to_tx_buf(ring, itxd); -+ itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size); - memset(itx_buf, 0, sizeof(*itx_buf)); - - txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size, -@@ -1065,7 +1067,7 @@ static int mtk_tx_map(struct sk_buff *sk - while (frag_size) { - bool new_desc = true; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA) || -+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) || - (i & 0x1)) { - txd = mtk_qdma_phys_to_virt(ring, txd->txd2); - txd_pdma = qdma_to_pdma(ring, txd); -@@ -1089,7 +1091,8 @@ static int mtk_tx_map(struct sk_buff *sk - - mtk_tx_set_dma_desc(dev, txd, &txd_info); - -- tx_buf = mtk_desc_to_tx_buf(ring, txd); -+ tx_buf = mtk_desc_to_tx_buf(ring, txd, -+ soc->txrx.txd_size); - if (new_desc) - memset(tx_buf, 0, sizeof(*tx_buf)); - tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC; -@@ -1108,7 +1111,7 @@ static int mtk_tx_map(struct sk_buff *sk - /* store skb to cleanup */ - itx_buf->skb = skb; - -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { - if (k & 0x1) - txd_pdma->txd2 |= TX_DMA_LS0; - else -@@ -1126,7 +1129,7 @@ static int mtk_tx_map(struct sk_buff *sk - */ - wmb(); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { - if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || - !netdev_xmit_more()) - mtk_w32(eth, txd->txd2, MTK_QTX_CTX_PTR); -@@ -1140,13 +1143,13 @@ static int mtk_tx_map(struct sk_buff *sk - - err_dma: - do { -- tx_buf = mtk_desc_to_tx_buf(ring, itxd); -+ tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size); - - /* unmap dma */ - mtk_tx_unmap(eth, tx_buf, false); - - itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) - itxd_pdma->txd2 = TX_DMA_DESP2_DEF; - - itxd = mtk_qdma_phys_to_virt(ring, itxd->txd2); -@@ -1460,7 +1463,8 @@ static int mtk_poll_tx_qdma(struct mtk_e - if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0) - break; - -- tx_buf = mtk_desc_to_tx_buf(ring, desc); -+ tx_buf = mtk_desc_to_tx_buf(ring, desc, -+ eth->soc->txrx.txd_size); - if (tx_buf->flags & MTK_TX_FLAGS_FPORT1) - mac = 1; - diff --git a/target/linux/generic/backport-5.15/702-v5.19-22-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-txd_to_.patch b/target/linux/generic/backport-5.15/702-v5.19-22-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-txd_to_.patch deleted file mode 100644 index 99ee2c5cf913b0..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-22-net-ethernet-mtk_eth_soc-rely-on-txd_size-in-txd_to_.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:31 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on txd_size in txd_to_idx - -This is a preliminary patch to add mt7986 ethernet support. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -916,9 +916,10 @@ static struct mtk_tx_dma *qdma_to_pdma(s - return ring->dma_pdma - ring->dma + dma; - } - --static int txd_to_idx(struct mtk_tx_ring *ring, struct mtk_tx_dma *dma) -+static int txd_to_idx(struct mtk_tx_ring *ring, struct mtk_tx_dma *dma, -+ u32 txd_size) - { -- return ((void *)dma - (void *)ring->dma) / sizeof(*dma); -+ return ((void *)dma - (void *)ring->dma) / txd_size; - } - - static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, -@@ -1134,8 +1135,10 @@ static int mtk_tx_map(struct sk_buff *sk - !netdev_xmit_more()) - mtk_w32(eth, txd->txd2, MTK_QTX_CTX_PTR); - } else { -- int next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd), -- ring->dma_size); -+ int next_idx; -+ -+ next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->txrx.txd_size), -+ ring->dma_size); - mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0); - } - diff --git a/target/linux/generic/backport-5.15/702-v5.19-23-net-ethernet-mtk_eth_soc-add-rxd_size-to-mtk_soc_dat.patch b/target/linux/generic/backport-5.15/702-v5.19-23-net-ethernet-mtk_eth_soc-add-rxd_size-to-mtk_soc_dat.patch deleted file mode 100644 index 27bf69b58c14e1..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-23-net-ethernet-mtk_eth_soc-add-rxd_size-to-mtk_soc_dat.patch +++ /dev/null @@ -1,102 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:32 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add rxd_size to mtk_soc_data - -Similar to tx counterpart, introduce rxd_size in mtk_soc_data data -structure. -This is a preliminary patch to add mt7986 ethernet support. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1786,7 +1786,7 @@ static int mtk_rx_alloc(struct mtk_eth * - } - - ring->dma = dma_alloc_coherent(eth->dma_dev, -- rx_dma_size * sizeof(*ring->dma), -+ rx_dma_size * eth->soc->txrx.rxd_size, - &ring->phys, GFP_KERNEL); - if (!ring->dma) - return -ENOMEM; -@@ -1844,9 +1844,8 @@ static void mtk_rx_clean(struct mtk_eth - - if (ring->dma) { - dma_free_coherent(eth->dma_dev, -- ring->dma_size * sizeof(*ring->dma), -- ring->dma, -- ring->phys); -+ ring->dma_size * eth->soc->txrx.rxd_size, -+ ring->dma, ring->phys); - ring->dma = NULL; - } - } -@@ -3412,6 +3411,7 @@ static const struct mtk_soc_data mt2701_ - .required_pctl = true, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -+ .rxd_size = sizeof(struct mtk_rx_dma), - }, - }; - -@@ -3423,6 +3423,7 @@ static const struct mtk_soc_data mt7621_ - .offload_version = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -+ .rxd_size = sizeof(struct mtk_rx_dma), - }, - }; - -@@ -3435,6 +3436,7 @@ static const struct mtk_soc_data mt7622_ - .offload_version = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -+ .rxd_size = sizeof(struct mtk_rx_dma), - }, - }; - -@@ -3446,6 +3448,7 @@ static const struct mtk_soc_data mt7623_ - .offload_version = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -+ .rxd_size = sizeof(struct mtk_rx_dma), - }, - }; - -@@ -3457,6 +3460,7 @@ static const struct mtk_soc_data mt7629_ - .required_pctl = false, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -+ .rxd_size = sizeof(struct mtk_rx_dma), - }, - }; - -@@ -3467,6 +3471,7 @@ static const struct mtk_soc_data rt5350_ - .required_pctl = false, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -+ .rxd_size = sizeof(struct mtk_rx_dma), - }, - }; - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -865,6 +865,7 @@ struct mtk_tx_dma_desc_info { - * @required_pctl A bool value to show whether the SoC requires - * the extra setup for those pins used by GMAC. - * @txd_size Tx DMA descriptor size. -+ * @rxd_size Rx DMA descriptor size. - */ - struct mtk_soc_data { - u32 ana_rgc3; -@@ -875,6 +876,7 @@ struct mtk_soc_data { - netdev_features_t hw_features; - struct { - u32 txd_size; -+ u32 rxd_size; - } txrx; - }; - diff --git a/target/linux/generic/backport-5.15/702-v5.19-24-net-ethernet-mtk_eth_soc-rely-on-txd_size-field-in-m.patch b/target/linux/generic/backport-5.15/702-v5.19-24-net-ethernet-mtk_eth_soc-rely-on-txd_size-field-in-m.patch deleted file mode 100644 index 393faf65534583..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-24-net-ethernet-mtk_eth_soc-rely-on-txd_size-field-in-m.patch +++ /dev/null @@ -1,46 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:33 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on txd_size field in - mtk_poll_tx/mtk_poll_rx - -This is a preliminary to ad mt7986 ethernet support. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1275,9 +1275,12 @@ static struct mtk_rx_ring *mtk_get_rx_ri - return ð->rx_ring[0]; - - for (i = 0; i < MTK_MAX_RX_RING_NUM; i++) { -+ struct mtk_rx_dma *rxd; -+ - ring = ð->rx_ring[i]; - idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size); -- if (ring->dma[idx].rxd2 & RX_DMA_DONE) { -+ rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size; -+ if (rxd->rxd2 & RX_DMA_DONE) { - ring->calc_idx_update = true; - return ring; - } -@@ -1328,7 +1331,7 @@ static int mtk_poll_rx(struct napi_struc - goto rx_done; - - idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size); -- rxd = &ring->dma[idx]; -+ rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size; - data = ring->data[idx]; - - if (!mtk_rx_get_desc(&trxd, rxd)) -@@ -1520,7 +1523,7 @@ static int mtk_poll_tx_pdma(struct mtk_e - - mtk_tx_unmap(eth, tx_buf, true); - -- desc = &ring->dma[cpu]; -+ desc = (void *)ring->dma + cpu * eth->soc->txrx.txd_size; - ring->last_free = desc; - atomic_inc(&ring->free_count); - diff --git a/target/linux/generic/backport-5.15/702-v5.19-25-net-ethernet-mtk_eth_soc-rely-on-rxd_size-field-in-m.patch b/target/linux/generic/backport-5.15/702-v5.19-25-net-ethernet-mtk_eth_soc-rely-on-rxd_size-field-in-m.patch deleted file mode 100644 index fdfa8b99c0abbc..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-25-net-ethernet-mtk_eth_soc-rely-on-rxd_size-field-in-m.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:34 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on rxd_size field in - mtk_rx_alloc/mtk_rx_clean - -Remove mtk_rx_dma structure layout dependency in mtk_rx_alloc/mtk_rx_clean. -Initialize to 0 rxd3 and rxd4 in mtk_rx_alloc. -This is a preliminary patch to add mt7986 ethernet support. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1795,18 +1795,25 @@ static int mtk_rx_alloc(struct mtk_eth * - return -ENOMEM; - - for (i = 0; i < rx_dma_size; i++) { -+ struct mtk_rx_dma *rxd; -+ - dma_addr_t dma_addr = dma_map_single(eth->dma_dev, - ring->data[i] + NET_SKB_PAD + eth->ip_align, - ring->buf_size, - DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) - return -ENOMEM; -- ring->dma[i].rxd1 = (unsigned int)dma_addr; -+ -+ rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size; -+ rxd->rxd1 = (unsigned int)dma_addr; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) -- ring->dma[i].rxd2 = RX_DMA_LSO; -+ rxd->rxd2 = RX_DMA_LSO; - else -- ring->dma[i].rxd2 = RX_DMA_PLEN0(ring->buf_size); -+ rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size); -+ -+ rxd->rxd3 = 0; -+ rxd->rxd4 = 0; - } - ring->dma_size = rx_dma_size; - ring->calc_idx_update = false; -@@ -1831,14 +1838,17 @@ static void mtk_rx_clean(struct mtk_eth - - if (ring->data && ring->dma) { - for (i = 0; i < ring->dma_size; i++) { -+ struct mtk_rx_dma *rxd; -+ - if (!ring->data[i]) - continue; -- if (!ring->dma[i].rxd1) -+ -+ rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size; -+ if (!rxd->rxd1) - continue; -- dma_unmap_single(eth->dma_dev, -- ring->dma[i].rxd1, -- ring->buf_size, -- DMA_FROM_DEVICE); -+ -+ dma_unmap_single(eth->dma_dev, rxd->rxd1, -+ ring->buf_size, DMA_FROM_DEVICE); - skb_free_frag(ring->data[i]); - } - kfree(ring->data); diff --git a/target/linux/generic/backport-5.15/702-v5.19-26-net-ethernet-mtk_eth_soc-introduce-device-register-m.patch b/target/linux/generic/backport-5.15/702-v5.19-26-net-ethernet-mtk_eth_soc-introduce-device-register-m.patch deleted file mode 100644 index c4c337a3ceb8d9..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-26-net-ethernet-mtk_eth_soc-introduce-device-register-m.patch +++ /dev/null @@ -1,814 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:35 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce device register map - -Introduce reg_map structure to add the capability to support different -register definitions. Move register definitions in mtk_regmap structure. -This is a preliminary patch to introduce mt7986 ethernet support. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -34,6 +34,59 @@ MODULE_PARM_DESC(msg_level, "Message lev - #define MTK_ETHTOOL_STAT(x) { #x, \ - offsetof(struct mtk_hw_stats, x) / sizeof(u64) } - -+static const struct mtk_reg_map mtk_reg_map = { -+ .tx_irq_mask = 0x1a1c, -+ .tx_irq_status = 0x1a18, -+ .pdma = { -+ .rx_ptr = 0x0900, -+ .rx_cnt_cfg = 0x0904, -+ .pcrx_ptr = 0x0908, -+ .glo_cfg = 0x0a04, -+ .rst_idx = 0x0a08, -+ .delay_irq = 0x0a0c, -+ .irq_status = 0x0a20, -+ .irq_mask = 0x0a28, -+ .int_grp = 0x0a50, -+ }, -+ .qdma = { -+ .qtx_cfg = 0x1800, -+ .rx_ptr = 0x1900, -+ .rx_cnt_cfg = 0x1904, -+ .qcrx_ptr = 0x1908, -+ .glo_cfg = 0x1a04, -+ .rst_idx = 0x1a08, -+ .delay_irq = 0x1a0c, -+ .fc_th = 0x1a10, -+ .int_grp = 0x1a20, -+ .hred = 0x1a44, -+ .ctx_ptr = 0x1b00, -+ .dtx_ptr = 0x1b04, -+ .crx_ptr = 0x1b10, -+ .drx_ptr = 0x1b14, -+ .fq_head = 0x1b20, -+ .fq_tail = 0x1b24, -+ .fq_count = 0x1b28, -+ .fq_blen = 0x1b2c, -+ }, -+ .gdm1_cnt = 0x2400, -+}; -+ -+static const struct mtk_reg_map mt7628_reg_map = { -+ .tx_irq_mask = 0x0a28, -+ .tx_irq_status = 0x0a20, -+ .pdma = { -+ .rx_ptr = 0x0900, -+ .rx_cnt_cfg = 0x0904, -+ .pcrx_ptr = 0x0908, -+ .glo_cfg = 0x0a04, -+ .rst_idx = 0x0a08, -+ .delay_irq = 0x0a0c, -+ .irq_status = 0x0a20, -+ .irq_mask = 0x0a28, -+ .int_grp = 0x0a50, -+ }, -+}; -+ - /* strings used by ethtool */ - static const struct mtk_ethtool_stats { - char str[ETH_GSTRING_LEN]; -@@ -629,8 +682,8 @@ static inline void mtk_tx_irq_disable(st - u32 val; - - spin_lock_irqsave(ð->tx_irq_lock, flags); -- val = mtk_r32(eth, eth->tx_int_mask_reg); -- mtk_w32(eth, val & ~mask, eth->tx_int_mask_reg); -+ val = mtk_r32(eth, eth->soc->reg_map->tx_irq_mask); -+ mtk_w32(eth, val & ~mask, eth->soc->reg_map->tx_irq_mask); - spin_unlock_irqrestore(ð->tx_irq_lock, flags); - } - -@@ -640,8 +693,8 @@ static inline void mtk_tx_irq_enable(str - u32 val; - - spin_lock_irqsave(ð->tx_irq_lock, flags); -- val = mtk_r32(eth, eth->tx_int_mask_reg); -- mtk_w32(eth, val | mask, eth->tx_int_mask_reg); -+ val = mtk_r32(eth, eth->soc->reg_map->tx_irq_mask); -+ mtk_w32(eth, val | mask, eth->soc->reg_map->tx_irq_mask); - spin_unlock_irqrestore(ð->tx_irq_lock, flags); - } - -@@ -651,8 +704,8 @@ static inline void mtk_rx_irq_disable(st - u32 val; - - spin_lock_irqsave(ð->rx_irq_lock, flags); -- val = mtk_r32(eth, MTK_PDMA_INT_MASK); -- mtk_w32(eth, val & ~mask, MTK_PDMA_INT_MASK); -+ val = mtk_r32(eth, eth->soc->reg_map->pdma.irq_mask); -+ mtk_w32(eth, val & ~mask, eth->soc->reg_map->pdma.irq_mask); - spin_unlock_irqrestore(ð->rx_irq_lock, flags); - } - -@@ -662,8 +715,8 @@ static inline void mtk_rx_irq_enable(str - u32 val; - - spin_lock_irqsave(ð->rx_irq_lock, flags); -- val = mtk_r32(eth, MTK_PDMA_INT_MASK); -- mtk_w32(eth, val | mask, MTK_PDMA_INT_MASK); -+ val = mtk_r32(eth, eth->soc->reg_map->pdma.irq_mask); -+ mtk_w32(eth, val | mask, eth->soc->reg_map->pdma.irq_mask); - spin_unlock_irqrestore(ð->rx_irq_lock, flags); - } - -@@ -714,39 +767,39 @@ void mtk_stats_update_mac(struct mtk_mac - hw_stats->rx_checksum_errors += - mtk_r32(mac->hw, MT7628_SDM_CS_ERR); - } else { -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; - unsigned int offs = hw_stats->reg_offset; - u64 stats; - -- hw_stats->rx_bytes += mtk_r32(mac->hw, -- MTK_GDM1_RX_GBCNT_L + offs); -- stats = mtk_r32(mac->hw, MTK_GDM1_RX_GBCNT_H + offs); -+ hw_stats->rx_bytes += mtk_r32(mac->hw, reg_map->gdm1_cnt + offs); -+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x4 + offs); - if (stats) - hw_stats->rx_bytes += (stats << 32); - hw_stats->rx_packets += -- mtk_r32(mac->hw, MTK_GDM1_RX_GPCNT + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x8 + offs); - hw_stats->rx_overflow += -- mtk_r32(mac->hw, MTK_GDM1_RX_OERCNT + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x10 + offs); - hw_stats->rx_fcs_errors += -- mtk_r32(mac->hw, MTK_GDM1_RX_FERCNT + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x14 + offs); - hw_stats->rx_short_errors += -- mtk_r32(mac->hw, MTK_GDM1_RX_SERCNT + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x18 + offs); - hw_stats->rx_long_errors += -- mtk_r32(mac->hw, MTK_GDM1_RX_LENCNT + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x1c + offs); - hw_stats->rx_checksum_errors += -- mtk_r32(mac->hw, MTK_GDM1_RX_CERCNT + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs); - hw_stats->rx_flow_control_packets += -- mtk_r32(mac->hw, MTK_GDM1_RX_FCCNT + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs); - hw_stats->tx_skip += -- mtk_r32(mac->hw, MTK_GDM1_TX_SKIPCNT + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs); - hw_stats->tx_collisions += -- mtk_r32(mac->hw, MTK_GDM1_TX_COLCNT + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs); - hw_stats->tx_bytes += -- mtk_r32(mac->hw, MTK_GDM1_TX_GBCNT_L + offs); -- stats = mtk_r32(mac->hw, MTK_GDM1_TX_GBCNT_H + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs); -+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs); - if (stats) - hw_stats->tx_bytes += (stats << 32); - hw_stats->tx_packets += -- mtk_r32(mac->hw, MTK_GDM1_TX_GPCNT + offs); -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs); - } - - u64_stats_update_end(&hw_stats->syncp); -@@ -886,10 +939,10 @@ static int mtk_init_fq_dma(struct mtk_et - txd->txd4 = 0; - } - -- mtk_w32(eth, eth->phy_scratch_ring, MTK_QDMA_FQ_HEAD); -- mtk_w32(eth, phy_ring_tail, MTK_QDMA_FQ_TAIL); -- mtk_w32(eth, (cnt << 16) | cnt, MTK_QDMA_FQ_CNT); -- mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, MTK_QDMA_FQ_BLEN); -+ mtk_w32(eth, eth->phy_scratch_ring, soc->reg_map->qdma.fq_head); -+ mtk_w32(eth, phy_ring_tail, soc->reg_map->qdma.fq_tail); -+ mtk_w32(eth, (cnt << 16) | cnt, soc->reg_map->qdma.fq_count); -+ mtk_w32(eth, MTK_QDMA_PAGE_SIZE << 16, soc->reg_map->qdma.fq_blen); - - return 0; - } -@@ -1133,7 +1186,7 @@ static int mtk_tx_map(struct sk_buff *sk - if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { - if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || - !netdev_xmit_more()) -- mtk_w32(eth, txd->txd2, MTK_QTX_CTX_PTR); -+ mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr); - } else { - int next_idx; - -@@ -1450,6 +1503,7 @@ rx_done: - static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, - unsigned int *done, unsigned int *bytes) - { -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; - struct mtk_tx_ring *ring = ð->tx_ring; - struct mtk_tx_dma *desc; - struct sk_buff *skb; -@@ -1457,7 +1511,7 @@ static int mtk_poll_tx_qdma(struct mtk_e - u32 cpu, dma; - - cpu = ring->last_free_ptr; -- dma = mtk_r32(eth, MTK_QTX_DRX_PTR); -+ dma = mtk_r32(eth, reg_map->qdma.drx_ptr); - - desc = mtk_qdma_phys_to_virt(ring, cpu); - -@@ -1492,7 +1546,7 @@ static int mtk_poll_tx_qdma(struct mtk_e - } - - ring->last_free_ptr = cpu; -- mtk_w32(eth, cpu, MTK_QTX_CRX_PTR); -+ mtk_w32(eth, cpu, reg_map->qdma.crx_ptr); - - return budget; - } -@@ -1585,24 +1639,25 @@ static void mtk_handle_status_irq(struct - static int mtk_napi_tx(struct napi_struct *napi, int budget) - { - struct mtk_eth *eth = container_of(napi, struct mtk_eth, tx_napi); -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; - int tx_done = 0; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) - mtk_handle_status_irq(eth); -- mtk_w32(eth, MTK_TX_DONE_INT, eth->tx_int_status_reg); -+ mtk_w32(eth, MTK_TX_DONE_INT, reg_map->tx_irq_status); - tx_done = mtk_poll_tx(eth, budget); - - if (unlikely(netif_msg_intr(eth))) { - dev_info(eth->dev, - "done tx %d, intr 0x%08x/0x%x\n", tx_done, -- mtk_r32(eth, eth->tx_int_status_reg), -- mtk_r32(eth, eth->tx_int_mask_reg)); -+ mtk_r32(eth, reg_map->tx_irq_status), -+ mtk_r32(eth, reg_map->tx_irq_mask)); - } - - if (tx_done == budget) - return budget; - -- if (mtk_r32(eth, eth->tx_int_status_reg) & MTK_TX_DONE_INT) -+ if (mtk_r32(eth, reg_map->tx_irq_status) & MTK_TX_DONE_INT) - return budget; - - if (napi_complete_done(napi, tx_done)) -@@ -1614,6 +1669,7 @@ static int mtk_napi_tx(struct napi_struc - static int mtk_napi_rx(struct napi_struct *napi, int budget) - { - struct mtk_eth *eth = container_of(napi, struct mtk_eth, rx_napi); -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; - int rx_done_total = 0; - - mtk_handle_status_irq(eth); -@@ -1621,21 +1677,21 @@ static int mtk_napi_rx(struct napi_struc - do { - int rx_done; - -- mtk_w32(eth, MTK_RX_DONE_INT, MTK_PDMA_INT_STATUS); -+ mtk_w32(eth, MTK_RX_DONE_INT, reg_map->pdma.irq_status); - rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth); - rx_done_total += rx_done; - - if (unlikely(netif_msg_intr(eth))) { - dev_info(eth->dev, - "done rx %d, intr 0x%08x/0x%x\n", rx_done, -- mtk_r32(eth, MTK_PDMA_INT_STATUS), -- mtk_r32(eth, MTK_PDMA_INT_MASK)); -+ mtk_r32(eth, reg_map->pdma.irq_status), -+ mtk_r32(eth, reg_map->pdma.irq_mask)); - } - - if (rx_done_total == budget) - return budget; - -- } while (mtk_r32(eth, MTK_PDMA_INT_STATUS) & MTK_RX_DONE_INT); -+ } while (mtk_r32(eth, reg_map->pdma.irq_status) & MTK_RX_DONE_INT); - - if (napi_complete_done(napi, rx_done_total)) - mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); -@@ -1698,20 +1754,20 @@ static int mtk_tx_alloc(struct mtk_eth * - */ - wmb(); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -- mtk_w32(eth, ring->phys, MTK_QTX_CTX_PTR); -- mtk_w32(eth, ring->phys, MTK_QTX_DTX_PTR); -+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { -+ mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr); -+ mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr); - mtk_w32(eth, - ring->phys + ((MTK_DMA_SIZE - 1) * sz), -- MTK_QTX_CRX_PTR); -- mtk_w32(eth, ring->last_free_ptr, MTK_QTX_DRX_PTR); -+ soc->reg_map->qdma.crx_ptr); -+ mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr); - mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, -- MTK_QTX_CFG(0)); -+ soc->reg_map->qdma.qtx_cfg); - } else { - mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); - mtk_w32(eth, MTK_DMA_SIZE, MT7628_TX_MAX_CNT0); - mtk_w32(eth, 0, MT7628_TX_CTX_IDX0); -- mtk_w32(eth, MT7628_PST_DTX_IDX0, MTK_PDMA_RST_IDX); -+ mtk_w32(eth, MT7628_PST_DTX_IDX0, soc->reg_map->pdma.rst_idx); - } - - return 0; -@@ -1750,6 +1806,7 @@ static void mtk_tx_clean(struct mtk_eth - - static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag) - { -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; - struct mtk_rx_ring *ring; - int rx_data_len, rx_dma_size; - int i; -@@ -1818,16 +1875,18 @@ static int mtk_rx_alloc(struct mtk_eth * - ring->dma_size = rx_dma_size; - ring->calc_idx_update = false; - ring->calc_idx = rx_dma_size - 1; -- ring->crx_idx_reg = MTK_PRX_CRX_IDX_CFG(ring_no); -+ ring->crx_idx_reg = reg_map->pdma.pcrx_ptr + ring_no * MTK_QRX_OFFSET; - /* make sure that all changes to the dma ring are flushed before we - * continue - */ - wmb(); - -- mtk_w32(eth, ring->phys, MTK_PRX_BASE_PTR_CFG(ring_no) + offset); -- mtk_w32(eth, rx_dma_size, MTK_PRX_MAX_CNT_CFG(ring_no) + offset); -+ mtk_w32(eth, ring->phys, -+ reg_map->pdma.rx_ptr + ring_no * MTK_QRX_OFFSET + offset); -+ mtk_w32(eth, rx_dma_size, -+ reg_map->pdma.rx_cnt_cfg + ring_no * MTK_QRX_OFFSET + offset); - mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg + offset); -- mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), MTK_PDMA_RST_IDX + offset); -+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), reg_map->pdma.rst_idx + offset); - - return 0; - } -@@ -2139,9 +2198,9 @@ static int mtk_dma_busy_wait(struct mtk_ - u32 val; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -- reg = MTK_QDMA_GLO_CFG; -+ reg = eth->soc->reg_map->qdma.glo_cfg; - else -- reg = MTK_PDMA_GLO_CFG; -+ reg = eth->soc->reg_map->pdma.glo_cfg; - - ret = readx_poll_timeout_atomic(__raw_readl, eth->base + reg, val, - !(val & (MTK_RX_DMA_BUSY | MTK_TX_DMA_BUSY)), -@@ -2199,8 +2258,8 @@ static int mtk_dma_init(struct mtk_eth * - * automatically - */ - mtk_w32(eth, FC_THRES_DROP_MODE | FC_THRES_DROP_EN | -- FC_THRES_MIN, MTK_QDMA_FC_THRES); -- mtk_w32(eth, 0x0, MTK_QDMA_HRED2); -+ FC_THRES_MIN, eth->soc->reg_map->qdma.fc_th); -+ mtk_w32(eth, 0x0, eth->soc->reg_map->qdma.hred); - } - - return 0; -@@ -2274,13 +2333,14 @@ static irqreturn_t mtk_handle_irq_tx(int - static irqreturn_t mtk_handle_irq(int irq, void *_eth) - { - struct mtk_eth *eth = _eth; -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; - -- if (mtk_r32(eth, MTK_PDMA_INT_MASK) & MTK_RX_DONE_INT) { -- if (mtk_r32(eth, MTK_PDMA_INT_STATUS) & MTK_RX_DONE_INT) -+ if (mtk_r32(eth, reg_map->pdma.irq_mask) & MTK_RX_DONE_INT) { -+ if (mtk_r32(eth, reg_map->pdma.irq_status) & MTK_RX_DONE_INT) - mtk_handle_irq_rx(irq, _eth); - } -- if (mtk_r32(eth, eth->tx_int_mask_reg) & MTK_TX_DONE_INT) { -- if (mtk_r32(eth, eth->tx_int_status_reg) & MTK_TX_DONE_INT) -+ if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) { -+ if (mtk_r32(eth, reg_map->tx_irq_status) & MTK_TX_DONE_INT) - mtk_handle_irq_tx(irq, _eth); - } - -@@ -2304,6 +2364,7 @@ static void mtk_poll_controller(struct n - static int mtk_start_dma(struct mtk_eth *eth) - { - u32 rx_2b_offset = (NET_IP_ALIGN == 2) ? MTK_RX_2B_OFFSET : 0; -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; - int err; - - err = mtk_dma_init(eth); -@@ -2318,16 +2379,15 @@ static int mtk_start_dma(struct mtk_eth - MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | - MTK_RX_DMA_EN | MTK_RX_2B_OFFSET | - MTK_RX_BT_32DWORDS, -- MTK_QDMA_GLO_CFG); -- -+ reg_map->qdma.glo_cfg); - mtk_w32(eth, - MTK_RX_DMA_EN | rx_2b_offset | - MTK_RX_BT_32DWORDS | MTK_MULTI_EN, -- MTK_PDMA_GLO_CFG); -+ reg_map->pdma.glo_cfg); - } else { - mtk_w32(eth, MTK_TX_WB_DDONE | MTK_TX_DMA_EN | MTK_RX_DMA_EN | - MTK_MULTI_EN | MTK_PDMA_SIZE_8DWORDS, -- MTK_PDMA_GLO_CFG); -+ reg_map->pdma.glo_cfg); - } - - return 0; -@@ -2453,8 +2513,8 @@ static int mtk_stop(struct net_device *d - cancel_work_sync(ð->tx_dim.work); - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -- mtk_stop_dma(eth, MTK_QDMA_GLO_CFG); -- mtk_stop_dma(eth, MTK_PDMA_GLO_CFG); -+ mtk_stop_dma(eth, eth->soc->reg_map->qdma.glo_cfg); -+ mtk_stop_dma(eth, eth->soc->reg_map->pdma.glo_cfg); - - mtk_dma_free(eth); - -@@ -2508,6 +2568,7 @@ static void mtk_dim_rx(struct work_struc - { - struct dim *dim = container_of(work, struct dim, work); - struct mtk_eth *eth = container_of(dim, struct mtk_eth, rx_dim); -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; - struct dim_cq_moder cur_profile; - u32 val, cur; - -@@ -2515,7 +2576,7 @@ static void mtk_dim_rx(struct work_struc - dim->profile_ix); - spin_lock_bh(ð->dim_lock); - -- val = mtk_r32(eth, MTK_PDMA_DELAY_INT); -+ val = mtk_r32(eth, reg_map->pdma.delay_irq); - val &= MTK_PDMA_DELAY_TX_MASK; - val |= MTK_PDMA_DELAY_RX_EN; - -@@ -2525,9 +2586,9 @@ static void mtk_dim_rx(struct work_struc - cur = min_t(u32, cur_profile.pkts, MTK_PDMA_DELAY_PINT_MASK); - val |= cur << MTK_PDMA_DELAY_RX_PINT_SHIFT; - -- mtk_w32(eth, val, MTK_PDMA_DELAY_INT); -+ mtk_w32(eth, val, reg_map->pdma.delay_irq); - if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -- mtk_w32(eth, val, MTK_QDMA_DELAY_INT); -+ mtk_w32(eth, val, reg_map->qdma.delay_irq); - - spin_unlock_bh(ð->dim_lock); - -@@ -2538,6 +2599,7 @@ static void mtk_dim_tx(struct work_struc - { - struct dim *dim = container_of(work, struct dim, work); - struct mtk_eth *eth = container_of(dim, struct mtk_eth, tx_dim); -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; - struct dim_cq_moder cur_profile; - u32 val, cur; - -@@ -2545,7 +2607,7 @@ static void mtk_dim_tx(struct work_struc - dim->profile_ix); - spin_lock_bh(ð->dim_lock); - -- val = mtk_r32(eth, MTK_PDMA_DELAY_INT); -+ val = mtk_r32(eth, reg_map->pdma.delay_irq); - val &= MTK_PDMA_DELAY_RX_MASK; - val |= MTK_PDMA_DELAY_TX_EN; - -@@ -2555,9 +2617,9 @@ static void mtk_dim_tx(struct work_struc - cur = min_t(u32, cur_profile.pkts, MTK_PDMA_DELAY_PINT_MASK); - val |= cur << MTK_PDMA_DELAY_TX_PINT_SHIFT; - -- mtk_w32(eth, val, MTK_PDMA_DELAY_INT); -+ mtk_w32(eth, val, reg_map->pdma.delay_irq); - if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -- mtk_w32(eth, val, MTK_QDMA_DELAY_INT); -+ mtk_w32(eth, val, reg_map->qdma.delay_irq); - - spin_unlock_bh(ð->dim_lock); - -@@ -2568,6 +2630,7 @@ static int mtk_hw_init(struct mtk_eth *e - { - u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | - ETHSYS_DMA_AG_MAP_PPE; -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; - int i, val, ret; - - if (test_and_set_bit(MTK_HW_INIT, ð->state)) -@@ -2642,10 +2705,10 @@ static int mtk_hw_init(struct mtk_eth *e - mtk_rx_irq_disable(eth, ~0); - - /* FE int grouping */ -- mtk_w32(eth, MTK_TX_DONE_INT, MTK_PDMA_INT_GRP1); -- mtk_w32(eth, MTK_RX_DONE_INT, MTK_PDMA_INT_GRP2); -- mtk_w32(eth, MTK_TX_DONE_INT, MTK_QDMA_INT_GRP1); -- mtk_w32(eth, MTK_RX_DONE_INT, MTK_QDMA_INT_GRP2); -+ mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp); -+ mtk_w32(eth, MTK_RX_DONE_INT, reg_map->pdma.int_grp + 4); -+ mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp); -+ mtk_w32(eth, MTK_RX_DONE_INT, reg_map->qdma.int_grp + 4); - mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); - - return 0; -@@ -3177,14 +3240,6 @@ static int mtk_probe(struct platform_dev - if (IS_ERR(eth->base)) - return PTR_ERR(eth->base); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -- eth->tx_int_mask_reg = MTK_QDMA_INT_MASK; -- eth->tx_int_status_reg = MTK_QDMA_INT_STATUS; -- } else { -- eth->tx_int_mask_reg = MTK_PDMA_INT_MASK; -- eth->tx_int_status_reg = MTK_PDMA_INT_STATUS; -- } -- - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { - eth->rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA; - eth->ip_align = NET_IP_ALIGN; -@@ -3418,6 +3473,7 @@ static int mtk_remove(struct platform_de - } - - static const struct mtk_soc_data mt2701_data = { -+ .reg_map = &mtk_reg_map, - .caps = MT7623_CAPS | MTK_HWLRO, - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, -@@ -3429,6 +3485,7 @@ static const struct mtk_soc_data mt2701_ - }; - - static const struct mtk_soc_data mt7621_data = { -+ .reg_map = &mtk_reg_map, - .caps = MT7621_CAPS, - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7621_CLKS_BITMAP, -@@ -3441,6 +3498,7 @@ static const struct mtk_soc_data mt7621_ - }; - - static const struct mtk_soc_data mt7622_data = { -+ .reg_map = &mtk_reg_map, - .ana_rgc3 = 0x2028, - .caps = MT7622_CAPS | MTK_HWLRO, - .hw_features = MTK_HW_FEATURES, -@@ -3454,6 +3512,7 @@ static const struct mtk_soc_data mt7622_ - }; - - static const struct mtk_soc_data mt7623_data = { -+ .reg_map = &mtk_reg_map, - .caps = MT7623_CAPS | MTK_HWLRO, - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, -@@ -3466,6 +3525,7 @@ static const struct mtk_soc_data mt7623_ - }; - - static const struct mtk_soc_data mt7629_data = { -+ .reg_map = &mtk_reg_map, - .ana_rgc3 = 0x128, - .caps = MT7629_CAPS | MTK_HWLRO, - .hw_features = MTK_HW_FEATURES, -@@ -3478,6 +3538,7 @@ static const struct mtk_soc_data mt7629_ - }; - - static const struct mtk_soc_data rt5350_data = { -+ .reg_map = &mt7628_reg_map, - .caps = MT7628_CAPS, - .hw_features = MTK_HW_FEATURES_MT7628, - .required_clks = MT7628_CLKS_BITMAP, ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -48,6 +48,8 @@ - #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM) - #define NEXT_DESP_IDX(X, Y) (((X) + 1) & ((Y) - 1)) - -+#define MTK_QRX_OFFSET 0x10 -+ - #define MTK_MAX_RX_RING_NUM 4 - #define MTK_HW_LRO_DMA_SIZE 8 - -@@ -100,18 +102,6 @@ - /* Unicast Filter MAC Address Register - High */ - #define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000)) - --/* PDMA RX Base Pointer Register */ --#define MTK_PRX_BASE_PTR0 0x900 --#define MTK_PRX_BASE_PTR_CFG(x) (MTK_PRX_BASE_PTR0 + (x * 0x10)) -- --/* PDMA RX Maximum Count Register */ --#define MTK_PRX_MAX_CNT0 0x904 --#define MTK_PRX_MAX_CNT_CFG(x) (MTK_PRX_MAX_CNT0 + (x * 0x10)) -- --/* PDMA RX CPU Pointer Register */ --#define MTK_PRX_CRX_IDX0 0x908 --#define MTK_PRX_CRX_IDX_CFG(x) (MTK_PRX_CRX_IDX0 + (x * 0x10)) -- - /* PDMA HW LRO Control Registers */ - #define MTK_PDMA_LRO_CTRL_DW0 0x980 - #define MTK_LRO_EN BIT(0) -@@ -126,18 +116,19 @@ - #define MTK_ADMA_MODE BIT(15) - #define MTK_LRO_MIN_RXD_SDL (MTK_HW_LRO_SDL_REMAIN_ROOM << 16) - --/* PDMA Global Configuration Register */ --#define MTK_PDMA_GLO_CFG 0xa04 -+#define MTK_RX_DMA_LRO_EN BIT(8) - #define MTK_MULTI_EN BIT(10) - #define MTK_PDMA_SIZE_8DWORDS (1 << 4) - -+/* PDMA Global Configuration Register */ -+#define MTK_PDMA_LRO_SDL 0x3000 -+#define MTK_RX_CFG_SDL_OFFSET 16 -+ - /* PDMA Reset Index Register */ --#define MTK_PDMA_RST_IDX 0xa08 - #define MTK_PST_DRX_IDX0 BIT(16) - #define MTK_PST_DRX_IDX_CFG(x) (MTK_PST_DRX_IDX0 << (x)) - - /* PDMA Delay Interrupt Register */ --#define MTK_PDMA_DELAY_INT 0xa0c - #define MTK_PDMA_DELAY_RX_MASK GENMASK(15, 0) - #define MTK_PDMA_DELAY_RX_EN BIT(15) - #define MTK_PDMA_DELAY_RX_PINT_SHIFT 8 -@@ -151,19 +142,9 @@ - #define MTK_PDMA_DELAY_PINT_MASK 0x7f - #define MTK_PDMA_DELAY_PTIME_MASK 0xff - --/* PDMA Interrupt Status Register */ --#define MTK_PDMA_INT_STATUS 0xa20 -- --/* PDMA Interrupt Mask Register */ --#define MTK_PDMA_INT_MASK 0xa28 -- - /* PDMA HW LRO Alter Flow Delta Register */ - #define MTK_PDMA_LRO_ALT_SCORE_DELTA 0xa4c - --/* PDMA Interrupt grouping registers */ --#define MTK_PDMA_INT_GRP1 0xa50 --#define MTK_PDMA_INT_GRP2 0xa54 -- - /* PDMA HW LRO IP Setting Registers */ - #define MTK_LRO_RX_RING0_DIP_DW0 0xb04 - #define MTK_LRO_DIP_DW0_CFG(x) (MTK_LRO_RX_RING0_DIP_DW0 + (x * 0x40)) -@@ -185,26 +166,9 @@ - #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3) - - /* QDMA TX Queue Configuration Registers */ --#define MTK_QTX_CFG(x) (0x1800 + (x * 0x10)) - #define QDMA_RES_THRES 4 - --/* QDMA TX Queue Scheduler Registers */ --#define MTK_QTX_SCH(x) (0x1804 + (x * 0x10)) -- --/* QDMA RX Base Pointer Register */ --#define MTK_QRX_BASE_PTR0 0x1900 -- --/* QDMA RX Maximum Count Register */ --#define MTK_QRX_MAX_CNT0 0x1904 -- --/* QDMA RX CPU Pointer Register */ --#define MTK_QRX_CRX_IDX0 0x1908 -- --/* QDMA RX DMA Pointer Register */ --#define MTK_QRX_DRX_IDX0 0x190C -- - /* QDMA Global Configuration Register */ --#define MTK_QDMA_GLO_CFG 0x1A04 - #define MTK_RX_2B_OFFSET BIT(31) - #define MTK_RX_BT_32DWORDS (3 << 11) - #define MTK_NDP_CO_PRO BIT(10) -@@ -216,20 +180,12 @@ - #define MTK_TX_DMA_EN BIT(0) - #define MTK_DMA_BUSY_TIMEOUT_US 1000000 - --/* QDMA Reset Index Register */ --#define MTK_QDMA_RST_IDX 0x1A08 -- --/* QDMA Delay Interrupt Register */ --#define MTK_QDMA_DELAY_INT 0x1A0C -- - /* QDMA Flow Control Register */ --#define MTK_QDMA_FC_THRES 0x1A10 - #define FC_THRES_DROP_MODE BIT(20) - #define FC_THRES_DROP_EN (7 << 16) - #define FC_THRES_MIN 0x4444 - - /* QDMA Interrupt Status Register */ --#define MTK_QDMA_INT_STATUS 0x1A18 - #define MTK_RX_DONE_DLY BIT(30) - #define MTK_TX_DONE_DLY BIT(28) - #define MTK_RX_DONE_INT3 BIT(19) -@@ -244,55 +200,8 @@ - #define MTK_TX_DONE_INT MTK_TX_DONE_DLY - - /* QDMA Interrupt grouping registers */ --#define MTK_QDMA_INT_GRP1 0x1a20 --#define MTK_QDMA_INT_GRP2 0x1a24 - #define MTK_RLS_DONE_INT BIT(0) - --/* QDMA Interrupt Status Register */ --#define MTK_QDMA_INT_MASK 0x1A1C -- --/* QDMA Interrupt Mask Register */ --#define MTK_QDMA_HRED2 0x1A44 -- --/* QDMA TX Forward CPU Pointer Register */ --#define MTK_QTX_CTX_PTR 0x1B00 -- --/* QDMA TX Forward DMA Pointer Register */ --#define MTK_QTX_DTX_PTR 0x1B04 -- --/* QDMA TX Release CPU Pointer Register */ --#define MTK_QTX_CRX_PTR 0x1B10 -- --/* QDMA TX Release DMA Pointer Register */ --#define MTK_QTX_DRX_PTR 0x1B14 -- --/* QDMA FQ Head Pointer Register */ --#define MTK_QDMA_FQ_HEAD 0x1B20 -- --/* QDMA FQ Head Pointer Register */ --#define MTK_QDMA_FQ_TAIL 0x1B24 -- --/* QDMA FQ Free Page Counter Register */ --#define MTK_QDMA_FQ_CNT 0x1B28 -- --/* QDMA FQ Free Page Buffer Length Register */ --#define MTK_QDMA_FQ_BLEN 0x1B2C -- --/* GMA1 counter / statics register */ --#define MTK_GDM1_RX_GBCNT_L 0x2400 --#define MTK_GDM1_RX_GBCNT_H 0x2404 --#define MTK_GDM1_RX_GPCNT 0x2408 --#define MTK_GDM1_RX_OERCNT 0x2410 --#define MTK_GDM1_RX_FERCNT 0x2414 --#define MTK_GDM1_RX_SERCNT 0x2418 --#define MTK_GDM1_RX_LENCNT 0x241c --#define MTK_GDM1_RX_CERCNT 0x2420 --#define MTK_GDM1_RX_FCCNT 0x2424 --#define MTK_GDM1_TX_SKIPCNT 0x2428 --#define MTK_GDM1_TX_COLCNT 0x242c --#define MTK_GDM1_TX_GBCNT_L 0x2430 --#define MTK_GDM1_TX_GBCNT_H 0x2434 --#define MTK_GDM1_TX_GPCNT 0x2438 - #define MTK_STAT_OFFSET 0x40 - - #define MTK_WDMA0_BASE 0x2800 -@@ -854,8 +763,46 @@ struct mtk_tx_dma_desc_info { - u8 last:1; - }; - -+struct mtk_reg_map { -+ u32 tx_irq_mask; -+ u32 tx_irq_status; -+ struct { -+ u32 rx_ptr; /* rx base pointer */ -+ u32 rx_cnt_cfg; /* rx max count configuration */ -+ u32 pcrx_ptr; /* rx cpu pointer */ -+ u32 glo_cfg; /* global configuration */ -+ u32 rst_idx; /* reset index */ -+ u32 delay_irq; /* delay interrupt */ -+ u32 irq_status; /* interrupt status */ -+ u32 irq_mask; /* interrupt mask */ -+ u32 int_grp; -+ } pdma; -+ struct { -+ u32 qtx_cfg; /* tx queue configuration */ -+ u32 rx_ptr; /* rx base pointer */ -+ u32 rx_cnt_cfg; /* rx max count configuration */ -+ u32 qcrx_ptr; /* rx cpu pointer */ -+ u32 glo_cfg; /* global configuration */ -+ u32 rst_idx; /* reset index */ -+ u32 delay_irq; /* delay interrupt */ -+ u32 fc_th; /* flow control */ -+ u32 int_grp; -+ u32 hred; /* interrupt mask */ -+ u32 ctx_ptr; /* tx acquire cpu pointer */ -+ u32 dtx_ptr; /* tx acquire dma pointer */ -+ u32 crx_ptr; /* tx release cpu pointer */ -+ u32 drx_ptr; /* tx release dma pointer */ -+ u32 fq_head; /* fq head pointer */ -+ u32 fq_tail; /* fq tail pointer */ -+ u32 fq_count; /* fq free page count */ -+ u32 fq_blen; /* fq free page buffer length */ -+ } qdma; -+ u32 gdm1_cnt; -+}; -+ - /* struct mtk_eth_data - This is the structure holding all differences - * among various plaforms -+ * @reg_map Soc register map. - * @ana_rgc3: The offset for register ANA_RGC3 related to - * sgmiisys syscon - * @caps Flags shown the extra capability for the SoC -@@ -868,6 +815,7 @@ struct mtk_tx_dma_desc_info { - * @rxd_size Rx DMA descriptor size. - */ - struct mtk_soc_data { -+ const struct mtk_reg_map *reg_map; - u32 ana_rgc3; - u32 caps; - u32 required_clks; -@@ -995,8 +943,6 @@ struct mtk_eth { - u32 tx_bytes; - struct dim tx_dim; - -- u32 tx_int_mask_reg; -- u32 tx_int_status_reg; - u32 rx_dma_l4_valid; - int ip_align; - diff --git a/target/linux/generic/backport-5.15/702-v5.19-27-net-ethernet-mtk_eth_soc-introduce-MTK_NETSYS_V2-sup.patch b/target/linux/generic/backport-5.15/702-v5.19-27-net-ethernet-mtk_eth_soc-introduce-MTK_NETSYS_V2-sup.patch deleted file mode 100644 index d55ab772119013..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-27-net-ethernet-mtk_eth_soc-introduce-MTK_NETSYS_V2-sup.patch +++ /dev/null @@ -1,917 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:36 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support - -Introduce MTK_NETSYS_V2 support. MTK_NETSYS_V2 defines 32B TX/RX DMA -descriptors. -This is a preliminary patch to add mt7986 ethernet support. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -873,8 +873,8 @@ static inline int mtk_max_buf_size(int f - return buf_size; - } - --static inline bool mtk_rx_get_desc(struct mtk_rx_dma *rxd, -- struct mtk_rx_dma *dma_rxd) -+static bool mtk_rx_get_desc(struct mtk_eth *eth, struct mtk_rx_dma_v2 *rxd, -+ struct mtk_rx_dma_v2 *dma_rxd) - { - rxd->rxd2 = READ_ONCE(dma_rxd->rxd2); - if (!(rxd->rxd2 & RX_DMA_DONE)) -@@ -883,6 +883,10 @@ static inline bool mtk_rx_get_desc(struc - rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); - rxd->rxd3 = READ_ONCE(dma_rxd->rxd3); - rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ rxd->rxd5 = READ_ONCE(dma_rxd->rxd5); -+ rxd->rxd6 = READ_ONCE(dma_rxd->rxd6); -+ } - - return true; - } -@@ -927,7 +931,7 @@ static int mtk_init_fq_dma(struct mtk_et - phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt - 1); - - for (i = 0; i < cnt; i++) { -- struct mtk_tx_dma *txd; -+ struct mtk_tx_dma_v2 *txd; - - txd = (void *)eth->scratch_ring + i * soc->txrx.txd_size; - txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE; -@@ -937,6 +941,12 @@ static int mtk_init_fq_dma(struct mtk_et - - txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE); - txd->txd4 = 0; -+ if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { -+ txd->txd5 = 0; -+ txd->txd6 = 0; -+ txd->txd7 = 0; -+ txd->txd8 = 0; -+ } - } - - mtk_w32(eth, eth->phy_scratch_ring, soc->reg_map->qdma.fq_head); -@@ -1040,10 +1050,12 @@ static void setup_tx_buf(struct mtk_eth - } - } - --static void mtk_tx_set_dma_desc(struct net_device *dev, struct mtk_tx_dma *desc, -- struct mtk_tx_dma_desc_info *info) -+static void mtk_tx_set_dma_desc_v1(struct net_device *dev, void *txd, -+ struct mtk_tx_dma_desc_info *info) - { - struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ struct mtk_tx_dma *desc = txd; - u32 data; - - WRITE_ONCE(desc->txd1, info->addr); -@@ -1067,6 +1079,59 @@ static void mtk_tx_set_dma_desc(struct n - WRITE_ONCE(desc->txd4, data); - } - -+static void mtk_tx_set_dma_desc_v2(struct net_device *dev, void *txd, -+ struct mtk_tx_dma_desc_info *info) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_tx_dma_v2 *desc = txd; -+ struct mtk_eth *eth = mac->hw; -+ u32 data; -+ -+ WRITE_ONCE(desc->txd1, info->addr); -+ -+ data = TX_DMA_PLEN0(info->size); -+ if (info->last) -+ data |= TX_DMA_LS0; -+ WRITE_ONCE(desc->txd3, data); -+ -+ if (!info->qid && mac->id) -+ info->qid = MTK_QDMA_GMAC2_QID; -+ -+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ -+ data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); -+ WRITE_ONCE(desc->txd4, data); -+ -+ data = 0; -+ if (info->first) { -+ if (info->gso) -+ data |= TX_DMA_TSO_V2; -+ /* tx checksum offload */ -+ if (info->csum) -+ data |= TX_DMA_CHKSUM_V2; -+ } -+ WRITE_ONCE(desc->txd5, data); -+ -+ data = 0; -+ if (info->first && info->vlan) -+ data |= TX_DMA_INS_VLAN_V2 | info->vlan_tci; -+ WRITE_ONCE(desc->txd6, data); -+ -+ WRITE_ONCE(desc->txd7, 0); -+ WRITE_ONCE(desc->txd8, 0); -+} -+ -+static void mtk_tx_set_dma_desc(struct net_device *dev, void *txd, -+ struct mtk_tx_dma_desc_info *info) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ mtk_tx_set_dma_desc_v2(dev, txd, info); -+ else -+ mtk_tx_set_dma_desc_v1(dev, txd, info); -+} -+ - static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev, - int tx_num, struct mtk_tx_ring *ring, bool gso) - { -@@ -1075,6 +1140,7 @@ static int mtk_tx_map(struct sk_buff *sk - .gso = gso, - .csum = skb->ip_summed == CHECKSUM_PARTIAL, - .vlan = skb_vlan_tag_present(skb), -+ .qid = skb->mark & MTK_QDMA_TX_MASK, - .vlan_tci = skb_vlan_tag_get(skb), - .first = true, - .last = !skb_is_nonlinear(skb), -@@ -1134,7 +1200,9 @@ static int mtk_tx_map(struct sk_buff *sk - } - - memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); -- txd_info.size = min(frag_size, MTK_TX_DMA_BUF_LEN); -+ txd_info.size = min_t(unsigned int, frag_size, -+ soc->txrx.dma_max_len); -+ txd_info.qid = skb->mark & MTK_QDMA_TX_MASK; - txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 && - !(frag_size - txd_info.size); - txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, -@@ -1215,17 +1283,16 @@ err_dma: - return -ENOMEM; - } - --static inline int mtk_cal_txd_req(struct sk_buff *skb) -+static int mtk_cal_txd_req(struct mtk_eth *eth, struct sk_buff *skb) - { -- int i, nfrags; -+ int i, nfrags = 1; - skb_frag_t *frag; - -- nfrags = 1; - if (skb_is_gso(skb)) { - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - frag = &skb_shinfo(skb)->frags[i]; - nfrags += DIV_ROUND_UP(skb_frag_size(frag), -- MTK_TX_DMA_BUF_LEN); -+ eth->soc->txrx.dma_max_len); - } - } else { - nfrags += skb_shinfo(skb)->nr_frags; -@@ -1277,7 +1344,7 @@ static netdev_tx_t mtk_start_xmit(struct - if (unlikely(test_bit(MTK_RESETTING, ð->state))) - goto drop; - -- tx_num = mtk_cal_txd_req(skb); -+ tx_num = mtk_cal_txd_req(eth, skb); - if (unlikely(atomic_read(&ring->free_count) <= tx_num)) { - netif_stop_queue(dev); - netif_err(eth, tx_queued, dev, -@@ -1369,7 +1436,7 @@ static int mtk_poll_rx(struct napi_struc - int idx; - struct sk_buff *skb; - u8 *data, *new_data; -- struct mtk_rx_dma *rxd, trxd; -+ struct mtk_rx_dma_v2 *rxd, trxd; - int done = 0, bytes = 0; - - while (done < budget) { -@@ -1377,7 +1444,7 @@ static int mtk_poll_rx(struct napi_struc - unsigned int pktlen; - dma_addr_t dma_addr; - u32 hash, reason; -- int mac; -+ int mac = 0; - - ring = mtk_get_rx_ring(eth); - if (unlikely(!ring)) -@@ -1387,16 +1454,15 @@ static int mtk_poll_rx(struct napi_struc - rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size; - data = ring->data[idx]; - -- if (!mtk_rx_get_desc(&trxd, rxd)) -+ if (!mtk_rx_get_desc(eth, &trxd, rxd)) - break; - - /* find out which mac the packet come from. values start at 1 */ -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) || -- (trxd.rxd4 & RX_DMA_SPECIAL_TAG)) -- mac = 0; -- else -- mac = ((trxd.rxd4 >> RX_DMA_FPORT_SHIFT) & -- RX_DMA_FPORT_MASK) - 1; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; -+ else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && -+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) -+ mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1; - - if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT || - !eth->netdev[mac])) -@@ -1442,7 +1508,7 @@ static int mtk_poll_rx(struct napi_struc - pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); - skb->dev = netdev; - skb_put(skb, pktlen); -- if (trxd.rxd4 & eth->rx_dma_l4_valid) -+ if (trxd.rxd4 & eth->soc->txrx.rx_dma_l4_valid) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else - skb_checksum_none_assert(skb); -@@ -1460,10 +1526,25 @@ static int mtk_poll_rx(struct napi_struc - mtk_ppe_check_skb(eth->ppe, skb, - trxd.rxd4 & MTK_RXD4_FOE_ENTRY); - -- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX && -- (trxd.rxd2 & RX_DMA_VTAG)) -- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), -- RX_DMA_VID(trxd.rxd3)); -+ if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (trxd.rxd3 & RX_DMA_VTAG_V2) -+ __vlan_hwaccel_put_tag(skb, -+ htons(RX_DMA_VPID(trxd.rxd4)), -+ RX_DMA_VID(trxd.rxd4)); -+ } else if (trxd.rxd2 & RX_DMA_VTAG) { -+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), -+ RX_DMA_VID(trxd.rxd3)); -+ } -+ -+ /* If the device is attached to a dsa switch, the special -+ * tag inserted in VLAN field by hw switch can * be offloaded -+ * by RX HW VLAN offload. Clear vlan info. -+ */ -+ if (netdev_uses_dsa(netdev)) -+ __vlan_hwaccel_clear_tag(skb); -+ } -+ - skb_record_rx_queue(skb, 0); - napi_gro_receive(napi, skb); - -@@ -1475,7 +1556,7 @@ release_desc: - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - rxd->rxd2 = RX_DMA_LSO; - else -- rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size); -+ rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); - - ring->calc_idx = idx; - -@@ -1677,7 +1758,8 @@ static int mtk_napi_rx(struct napi_struc - do { - int rx_done; - -- mtk_w32(eth, MTK_RX_DONE_INT, reg_map->pdma.irq_status); -+ mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, -+ reg_map->pdma.irq_status); - rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth); - rx_done_total += rx_done; - -@@ -1691,10 +1773,11 @@ static int mtk_napi_rx(struct napi_struc - if (rx_done_total == budget) - return budget; - -- } while (mtk_r32(eth, reg_map->pdma.irq_status) & MTK_RX_DONE_INT); -+ } while (mtk_r32(eth, reg_map->pdma.irq_status) & -+ eth->soc->txrx.rx_irq_done_mask); - - if (napi_complete_done(napi, rx_done_total)) -- mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); -+ mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask); - - return rx_done_total; - } -@@ -1704,7 +1787,7 @@ static int mtk_tx_alloc(struct mtk_eth * - const struct mtk_soc_data *soc = eth->soc; - struct mtk_tx_ring *ring = ð->tx_ring; - int i, sz = soc->txrx.txd_size; -- struct mtk_tx_dma *txd; -+ struct mtk_tx_dma_v2 *txd; - - ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf), - GFP_KERNEL); -@@ -1724,13 +1807,19 @@ static int mtk_tx_alloc(struct mtk_eth * - txd->txd2 = next_ptr; - txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; - txd->txd4 = 0; -+ if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { -+ txd->txd5 = 0; -+ txd->txd6 = 0; -+ txd->txd7 = 0; -+ txd->txd8 = 0; -+ } - } - - /* On MT7688 (PDMA only) this driver uses the ring->dma structs - * only as the framework. The real HW descriptors are the PDMA - * descriptors in ring->dma_pdma. - */ -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { - ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, - &ring->phys_pdma, GFP_KERNEL); - if (!ring->dma_pdma) -@@ -1810,13 +1899,11 @@ static int mtk_rx_alloc(struct mtk_eth * - struct mtk_rx_ring *ring; - int rx_data_len, rx_dma_size; - int i; -- u32 offset = 0; - - if (rx_flag == MTK_RX_FLAGS_QDMA) { - if (ring_no) - return -EINVAL; - ring = ð->rx_ring_qdma; -- offset = 0x1000; - } else { - ring = ð->rx_ring[ring_no]; - } -@@ -1852,7 +1939,7 @@ static int mtk_rx_alloc(struct mtk_eth * - return -ENOMEM; - - for (i = 0; i < rx_dma_size; i++) { -- struct mtk_rx_dma *rxd; -+ struct mtk_rx_dma_v2 *rxd; - - dma_addr_t dma_addr = dma_map_single(eth->dma_dev, - ring->data[i] + NET_SKB_PAD + eth->ip_align, -@@ -1867,26 +1954,47 @@ static int mtk_rx_alloc(struct mtk_eth * - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - rxd->rxd2 = RX_DMA_LSO; - else -- rxd->rxd2 = RX_DMA_PLEN0(ring->buf_size); -+ rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); - - rxd->rxd3 = 0; - rxd->rxd4 = 0; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ rxd->rxd5 = 0; -+ rxd->rxd6 = 0; -+ rxd->rxd7 = 0; -+ rxd->rxd8 = 0; -+ } - } - ring->dma_size = rx_dma_size; - ring->calc_idx_update = false; - ring->calc_idx = rx_dma_size - 1; -- ring->crx_idx_reg = reg_map->pdma.pcrx_ptr + ring_no * MTK_QRX_OFFSET; -+ if (rx_flag == MTK_RX_FLAGS_QDMA) -+ ring->crx_idx_reg = reg_map->qdma.qcrx_ptr + -+ ring_no * MTK_QRX_OFFSET; -+ else -+ ring->crx_idx_reg = reg_map->pdma.pcrx_ptr + -+ ring_no * MTK_QRX_OFFSET; - /* make sure that all changes to the dma ring are flushed before we - * continue - */ - wmb(); - -- mtk_w32(eth, ring->phys, -- reg_map->pdma.rx_ptr + ring_no * MTK_QRX_OFFSET + offset); -- mtk_w32(eth, rx_dma_size, -- reg_map->pdma.rx_cnt_cfg + ring_no * MTK_QRX_OFFSET + offset); -- mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg + offset); -- mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), reg_map->pdma.rst_idx + offset); -+ if (rx_flag == MTK_RX_FLAGS_QDMA) { -+ mtk_w32(eth, ring->phys, -+ reg_map->qdma.rx_ptr + ring_no * MTK_QRX_OFFSET); -+ mtk_w32(eth, rx_dma_size, -+ reg_map->qdma.rx_cnt_cfg + ring_no * MTK_QRX_OFFSET); -+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), -+ reg_map->qdma.rst_idx); -+ } else { -+ mtk_w32(eth, ring->phys, -+ reg_map->pdma.rx_ptr + ring_no * MTK_QRX_OFFSET); -+ mtk_w32(eth, rx_dma_size, -+ reg_map->pdma.rx_cnt_cfg + ring_no * MTK_QRX_OFFSET); -+ mtk_w32(eth, MTK_PST_DRX_IDX_CFG(ring_no), -+ reg_map->pdma.rst_idx); -+ } -+ mtk_w32(eth, ring->calc_idx, ring->crx_idx_reg); - - return 0; - } -@@ -2311,7 +2419,7 @@ static irqreturn_t mtk_handle_irq_rx(int - eth->rx_events++; - if (likely(napi_schedule_prep(ð->rx_napi))) { - __napi_schedule(ð->rx_napi); -- mtk_rx_irq_disable(eth, MTK_RX_DONE_INT); -+ mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); - } - - return IRQ_HANDLED; -@@ -2335,8 +2443,10 @@ static irqreturn_t mtk_handle_irq(int ir - struct mtk_eth *eth = _eth; - const struct mtk_reg_map *reg_map = eth->soc->reg_map; - -- if (mtk_r32(eth, reg_map->pdma.irq_mask) & MTK_RX_DONE_INT) { -- if (mtk_r32(eth, reg_map->pdma.irq_status) & MTK_RX_DONE_INT) -+ if (mtk_r32(eth, reg_map->pdma.irq_mask) & -+ eth->soc->txrx.rx_irq_done_mask) { -+ if (mtk_r32(eth, reg_map->pdma.irq_status) & -+ eth->soc->txrx.rx_irq_done_mask) - mtk_handle_irq_rx(irq, _eth); - } - if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) { -@@ -2354,16 +2464,16 @@ static void mtk_poll_controller(struct n - struct mtk_eth *eth = mac->hw; - - mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); -- mtk_rx_irq_disable(eth, MTK_RX_DONE_INT); -+ mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); - mtk_handle_irq_rx(eth->irq[2], dev); - mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); -- mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); -+ mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask); - } - #endif - - static int mtk_start_dma(struct mtk_eth *eth) - { -- u32 rx_2b_offset = (NET_IP_ALIGN == 2) ? MTK_RX_2B_OFFSET : 0; -+ u32 val, rx_2b_offset = (NET_IP_ALIGN == 2) ? MTK_RX_2B_OFFSET : 0; - const struct mtk_reg_map *reg_map = eth->soc->reg_map; - int err; - -@@ -2374,12 +2484,19 @@ static int mtk_start_dma(struct mtk_eth - } - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -- mtk_w32(eth, -- MTK_TX_WB_DDONE | MTK_TX_DMA_EN | -- MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | -- MTK_RX_DMA_EN | MTK_RX_2B_OFFSET | -- MTK_RX_BT_32DWORDS, -- reg_map->qdma.glo_cfg); -+ val = mtk_r32(eth, reg_map->qdma.glo_cfg); -+ val |= MTK_TX_DMA_EN | MTK_RX_DMA_EN | -+ MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | -+ MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ val |= MTK_MUTLI_CNT | MTK_RESV_BUF | -+ MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | -+ MTK_CHK_DDONE_EN; -+ else -+ val |= MTK_RX_BT_32DWORDS; -+ mtk_w32(eth, val, reg_map->qdma.glo_cfg); -+ - mtk_w32(eth, - MTK_RX_DMA_EN | rx_2b_offset | - MTK_RX_BT_32DWORDS | MTK_MULTI_EN, -@@ -2453,7 +2570,7 @@ static int mtk_open(struct net_device *d - napi_enable(ð->tx_napi); - napi_enable(ð->rx_napi); - mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); -- mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); -+ mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask); - refcount_set(ð->dma_refcnt, 1); - } - else -@@ -2505,7 +2622,7 @@ static int mtk_stop(struct net_device *d - mtk_gdm_config(eth, MTK_GDMA_DROP_ALL); - - mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); -- mtk_rx_irq_disable(eth, MTK_RX_DONE_INT); -+ mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); - napi_disable(ð->tx_napi); - napi_disable(ð->rx_napi); - -@@ -2665,9 +2782,25 @@ static int mtk_hw_init(struct mtk_eth *e - return 0; - } - -- /* Non-MT7628 handling... */ -- ethsys_reset(eth, RSTCTRL_FE); -- ethsys_reset(eth, RSTCTRL_PPE); -+ val = RSTCTRL_FE | RSTCTRL_PPE; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); -+ -+ val |= RSTCTRL_ETH; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= RSTCTRL_PPE1; -+ } -+ -+ ethsys_reset(eth, val); -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, -+ 0x3ffffff); -+ -+ /* Set FE to PDMAv2 if necessary */ -+ val = mtk_r32(eth, MTK_FE_GLO_MISC); -+ mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); -+ } - - if (eth->pctl) { - /* Set GE2 driving and slew rate */ -@@ -2706,11 +2839,47 @@ static int mtk_hw_init(struct mtk_eth *e - - /* FE int grouping */ - mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp); -- mtk_w32(eth, MTK_RX_DONE_INT, reg_map->pdma.int_grp + 4); -+ mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->pdma.int_grp + 4); - mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp); -- mtk_w32(eth, MTK_RX_DONE_INT, reg_map->qdma.int_grp + 4); -+ mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); - mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ /* PSE should not drop port8 and port9 packets */ -+ mtk_w32(eth, 0x00000300, PSE_DROP_CFG); -+ -+ /* PSE Free Queue Flow Control */ -+ mtk_w32(eth, 0x01fa01f4, PSE_FQFC_CFG2); -+ -+ /* PSE config input queue threshold */ -+ mtk_w32(eth, 0x001a000e, PSE_IQ_REV(1)); -+ mtk_w32(eth, 0x01ff001a, PSE_IQ_REV(2)); -+ mtk_w32(eth, 0x000e01ff, PSE_IQ_REV(3)); -+ mtk_w32(eth, 0x000e000e, PSE_IQ_REV(4)); -+ mtk_w32(eth, 0x000e000e, PSE_IQ_REV(5)); -+ mtk_w32(eth, 0x000e000e, PSE_IQ_REV(6)); -+ mtk_w32(eth, 0x000e000e, PSE_IQ_REV(7)); -+ mtk_w32(eth, 0x000e000e, PSE_IQ_REV(8)); -+ -+ /* PSE config output queue threshold */ -+ mtk_w32(eth, 0x000f000a, PSE_OQ_TH(1)); -+ mtk_w32(eth, 0x001a000f, PSE_OQ_TH(2)); -+ mtk_w32(eth, 0x000f001a, PSE_OQ_TH(3)); -+ mtk_w32(eth, 0x01ff000f, PSE_OQ_TH(4)); -+ mtk_w32(eth, 0x000f000f, PSE_OQ_TH(5)); -+ mtk_w32(eth, 0x0006000f, PSE_OQ_TH(6)); -+ mtk_w32(eth, 0x00060006, PSE_OQ_TH(7)); -+ mtk_w32(eth, 0x00060006, PSE_OQ_TH(8)); -+ -+ /* GDM and CDM Threshold */ -+ mtk_w32(eth, 0x00000004, MTK_GDM2_THRES); -+ mtk_w32(eth, 0x00000004, MTK_CDMW0_THRES); -+ mtk_w32(eth, 0x00000004, MTK_CDMW1_THRES); -+ mtk_w32(eth, 0x00000004, MTK_CDME0_THRES); -+ mtk_w32(eth, 0x00000004, MTK_CDME1_THRES); -+ mtk_w32(eth, 0x00000004, MTK_CDMM_THRES); -+ } -+ - return 0; - - err_disable_pm: -@@ -3240,12 +3409,8 @@ static int mtk_probe(struct platform_dev - if (IS_ERR(eth->base)) - return PTR_ERR(eth->base); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { -- eth->rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - eth->ip_align = NET_IP_ALIGN; -- } else { -- eth->rx_dma_l4_valid = RX_DMA_L4_VALID; -- } - - spin_lock_init(ð->page_lock); - spin_lock_init(ð->tx_irq_lock); -@@ -3481,6 +3646,10 @@ static const struct mtk_soc_data mt2701_ - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -+ .rx_irq_done_mask = MTK_RX_DONE_INT, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN, -+ .dma_len_offset = 16, - }, - }; - -@@ -3494,6 +3663,10 @@ static const struct mtk_soc_data mt7621_ - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -+ .rx_irq_done_mask = MTK_RX_DONE_INT, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN, -+ .dma_len_offset = 16, - }, - }; - -@@ -3508,6 +3681,10 @@ static const struct mtk_soc_data mt7622_ - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -+ .rx_irq_done_mask = MTK_RX_DONE_INT, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN, -+ .dma_len_offset = 16, - }, - }; - -@@ -3521,6 +3698,10 @@ static const struct mtk_soc_data mt7623_ - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -+ .rx_irq_done_mask = MTK_RX_DONE_INT, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN, -+ .dma_len_offset = 16, - }, - }; - -@@ -3534,6 +3715,10 @@ static const struct mtk_soc_data mt7629_ - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -+ .rx_irq_done_mask = MTK_RX_DONE_INT, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN, -+ .dma_len_offset = 16, - }, - }; - -@@ -3546,6 +3731,10 @@ static const struct mtk_soc_data rt5350_ - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -+ .rx_irq_done_mask = MTK_RX_DONE_INT, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN, -+ .dma_len_offset = 16, - }, - }; - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -23,6 +23,7 @@ - #define MTK_MAX_RX_LENGTH 1536 - #define MTK_MAX_RX_LENGTH_2K 2048 - #define MTK_TX_DMA_BUF_LEN 0x3fff -+#define MTK_TX_DMA_BUF_LEN_V2 0xffff - #define MTK_DMA_SIZE 512 - #define MTK_NAPI_WEIGHT 64 - #define MTK_MAC_COUNT 2 -@@ -83,6 +84,10 @@ - #define MTK_CDMQ_IG_CTRL 0x1400 - #define MTK_CDMQ_STAG_EN BIT(0) - -+/* CDMP Ingress Control Register */ -+#define MTK_CDMP_IG_CTRL 0x400 -+#define MTK_CDMP_STAG_EN BIT(0) -+ - /* CDMP Exgress Control Register */ - #define MTK_CDMP_EG_CTRL 0x404 - -@@ -102,13 +107,38 @@ - /* Unicast Filter MAC Address Register - High */ - #define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000)) - -+/* FE global misc reg*/ -+#define MTK_FE_GLO_MISC 0x124 -+ -+/* PSE Free Queue Flow Control */ -+#define PSE_FQFC_CFG1 0x100 -+#define PSE_FQFC_CFG2 0x104 -+#define PSE_DROP_CFG 0x108 -+ -+/* PSE Input Queue Reservation Register*/ -+#define PSE_IQ_REV(x) (0x140 + (((x) - 1) << 2)) -+ -+/* PSE Output Queue Threshold Register*/ -+#define PSE_OQ_TH(x) (0x160 + (((x) - 1) << 2)) -+ -+/* GDM and CDM Threshold */ -+#define MTK_GDM2_THRES 0x1530 -+#define MTK_CDMW0_THRES 0x164c -+#define MTK_CDMW1_THRES 0x1650 -+#define MTK_CDME0_THRES 0x1654 -+#define MTK_CDME1_THRES 0x1658 -+#define MTK_CDMM_THRES 0x165c -+ - /* PDMA HW LRO Control Registers */ - #define MTK_PDMA_LRO_CTRL_DW0 0x980 - #define MTK_LRO_EN BIT(0) - #define MTK_L3_CKS_UPD_EN BIT(7) -+#define MTK_L3_CKS_UPD_EN_V2 BIT(19) - #define MTK_LRO_ALT_PKT_CNT_MODE BIT(21) - #define MTK_LRO_RING_RELINQUISH_REQ (0x7 << 26) -+#define MTK_LRO_RING_RELINQUISH_REQ_V2 (0xf << 24) - #define MTK_LRO_RING_RELINQUISH_DONE (0x7 << 29) -+#define MTK_LRO_RING_RELINQUISH_DONE_V2 (0xf << 28) - - #define MTK_PDMA_LRO_CTRL_DW1 0x984 - #define MTK_PDMA_LRO_CTRL_DW2 0x988 -@@ -180,6 +210,13 @@ - #define MTK_TX_DMA_EN BIT(0) - #define MTK_DMA_BUSY_TIMEOUT_US 1000000 - -+/* QDMA V2 Global Configuration Register */ -+#define MTK_CHK_DDONE_EN BIT(28) -+#define MTK_DMAD_WR_WDONE BIT(26) -+#define MTK_WCOMP_EN BIT(24) -+#define MTK_RESV_BUF (0x40 << 16) -+#define MTK_MUTLI_CNT (0x4 << 12) -+ - /* QDMA Flow Control Register */ - #define FC_THRES_DROP_MODE BIT(20) - #define FC_THRES_DROP_EN (7 << 16) -@@ -199,11 +236,32 @@ - #define MTK_RX_DONE_INT MTK_RX_DONE_DLY - #define MTK_TX_DONE_INT MTK_TX_DONE_DLY - -+#define MTK_RX_DONE_INT_V2 BIT(14) -+ - /* QDMA Interrupt grouping registers */ - #define MTK_RLS_DONE_INT BIT(0) - - #define MTK_STAT_OFFSET 0x40 - -+/* QDMA TX NUM */ -+#define MTK_QDMA_TX_NUM 16 -+#define MTK_QDMA_TX_MASK (MTK_QDMA_TX_NUM - 1) -+#define QID_BITS_V2(x) (((x) & 0x3f) << 16) -+#define MTK_QDMA_GMAC2_QID 8 -+ -+#define MTK_TX_DMA_BUF_SHIFT 8 -+ -+/* QDMA V2 descriptor txd6 */ -+#define TX_DMA_INS_VLAN_V2 BIT(16) -+/* QDMA V2 descriptor txd5 */ -+#define TX_DMA_CHKSUM_V2 (0x7 << 28) -+#define TX_DMA_TSO_V2 BIT(31) -+ -+/* QDMA V2 descriptor txd4 */ -+#define TX_DMA_FPORT_SHIFT_V2 8 -+#define TX_DMA_FPORT_MASK_V2 0xf -+#define TX_DMA_SWC_V2 BIT(30) -+ - #define MTK_WDMA0_BASE 0x2800 - #define MTK_WDMA1_BASE 0x2c00 - -@@ -217,10 +275,9 @@ - /* QDMA descriptor txd3 */ - #define TX_DMA_OWNER_CPU BIT(31) - #define TX_DMA_LS0 BIT(30) --#define TX_DMA_PLEN0(_x) (((_x) & MTK_TX_DMA_BUF_LEN) << 16) --#define TX_DMA_PLEN1(_x) ((_x) & MTK_TX_DMA_BUF_LEN) -+#define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) -+#define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) - #define TX_DMA_SWC BIT(14) --#define TX_DMA_SDL(_x) (((_x) & 0x3fff) << 16) - - /* PDMA on MT7628 */ - #define TX_DMA_DONE BIT(31) -@@ -230,12 +287,14 @@ - /* QDMA descriptor rxd2 */ - #define RX_DMA_DONE BIT(31) - #define RX_DMA_LSO BIT(30) --#define RX_DMA_PLEN0(_x) (((_x) & 0x3fff) << 16) --#define RX_DMA_GET_PLEN0(_x) (((_x) >> 16) & 0x3fff) -+#define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) -+#define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len) - #define RX_DMA_VTAG BIT(15) - - /* QDMA descriptor rxd3 */ --#define RX_DMA_VID(_x) ((_x) & 0xfff) -+#define RX_DMA_VID(x) ((x) & VLAN_VID_MASK) -+#define RX_DMA_TCI(x) ((x) & (VLAN_PRIO_MASK | VLAN_VID_MASK)) -+#define RX_DMA_VPID(x) (((x) >> 16) & 0xffff) - - /* QDMA descriptor rxd4 */ - #define MTK_RXD4_FOE_ENTRY GENMASK(13, 0) -@@ -246,10 +305,15 @@ - /* QDMA descriptor rxd4 */ - #define RX_DMA_L4_VALID BIT(24) - #define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */ --#define RX_DMA_FPORT_SHIFT 19 --#define RX_DMA_FPORT_MASK 0x7 - #define RX_DMA_SPECIAL_TAG BIT(22) - -+#define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0xf) -+#define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0x7) -+ -+/* PDMA V2 descriptor rxd3 */ -+#define RX_DMA_VTAG_V2 BIT(0) -+#define RX_DMA_L4_VALID_V2 BIT(2) -+ - /* PHY Indirect Access Control registers */ - #define MTK_PHY_IAC 0x10004 - #define PHY_IAC_ACCESS BIT(31) -@@ -371,6 +435,16 @@ - #define ETHSYS_TRGMII_MT7621_DDR_PLL BIT(5) - - /* ethernet reset control register */ -+#define ETHSYS_RSTCTRL 0x34 -+#define RSTCTRL_FE BIT(6) -+#define RSTCTRL_PPE BIT(31) -+#define RSTCTRL_PPE1 BIT(30) -+#define RSTCTRL_ETH BIT(23) -+ -+/* ethernet reset check idle register */ -+#define ETHSYS_FE_RST_CHK_IDLE_EN 0x28 -+ -+/* ethernet reset control register */ - #define ETHSYS_RSTCTRL 0x34 - #define RSTCTRL_FE BIT(6) - #define RSTCTRL_PPE BIT(31) -@@ -454,6 +528,17 @@ struct mtk_rx_dma { - unsigned int rxd4; - } __packed __aligned(4); - -+struct mtk_rx_dma_v2 { -+ unsigned int rxd1; -+ unsigned int rxd2; -+ unsigned int rxd3; -+ unsigned int rxd4; -+ unsigned int rxd5; -+ unsigned int rxd6; -+ unsigned int rxd7; -+ unsigned int rxd8; -+} __packed __aligned(4); -+ - struct mtk_tx_dma { - unsigned int txd1; - unsigned int txd2; -@@ -461,6 +546,17 @@ struct mtk_tx_dma { - unsigned int txd4; - } __packed __aligned(4); - -+struct mtk_tx_dma_v2 { -+ unsigned int txd1; -+ unsigned int txd2; -+ unsigned int txd3; -+ unsigned int txd4; -+ unsigned int txd5; -+ unsigned int txd6; -+ unsigned int txd7; -+ unsigned int txd8; -+} __packed __aligned(4); -+ - struct mtk_eth; - struct mtk_mac; - -@@ -647,7 +743,9 @@ enum mkt_eth_capabilities { - MTK_SHARED_INT_BIT, - MTK_TRGMII_MT7621_CLK_BIT, - MTK_QDMA_BIT, -+ MTK_NETSYS_V2_BIT, - MTK_SOC_MT7628_BIT, -+ MTK_RSTCTRL_PPE1_BIT, - - /* MUX BITS*/ - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, -@@ -679,7 +777,9 @@ enum mkt_eth_capabilities { - #define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) - #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) - #define MTK_QDMA BIT(MTK_QDMA_BIT) -+#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) - #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) -+#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ - BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -@@ -756,6 +856,7 @@ struct mtk_tx_dma_desc_info { - dma_addr_t addr; - u32 size; - u16 vlan_tci; -+ u16 qid; - u8 gso:1; - u8 csum:1; - u8 vlan:1; -@@ -813,6 +914,10 @@ struct mtk_reg_map { - * the extra setup for those pins used by GMAC. - * @txd_size Tx DMA descriptor size. - * @rxd_size Rx DMA descriptor size. -+ * @rx_irq_done_mask Rx irq done register mask. -+ * @rx_dma_l4_valid Rx DMA valid register mask. -+ * @dma_max_len Max DMA tx/rx buffer length. -+ * @dma_len_offset Tx/Rx DMA length field offset. - */ - struct mtk_soc_data { - const struct mtk_reg_map *reg_map; -@@ -825,6 +930,10 @@ struct mtk_soc_data { - struct { - u32 txd_size; - u32 rxd_size; -+ u32 rx_irq_done_mask; -+ u32 rx_dma_l4_valid; -+ u32 dma_max_len; -+ u32 dma_len_offset; - } txrx; - }; - -@@ -943,7 +1052,6 @@ struct mtk_eth { - u32 tx_bytes; - struct dim tx_dim; - -- u32 rx_dma_l4_valid; - int ip_align; - - struct mtk_ppe *ppe; diff --git a/target/linux/generic/backport-5.15/702-v5.19-28-net-ethernet-mtk_eth_soc-convert-ring-dma-pointer-to.patch b/target/linux/generic/backport-5.15/702-v5.19-28-net-ethernet-mtk_eth_soc-convert-ring-dma-pointer-to.patch deleted file mode 100644 index 1ee9bb52a77695..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-28-net-ethernet-mtk_eth_soc-convert-ring-dma-pointer-to.patch +++ /dev/null @@ -1,135 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:37 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: convert ring dma pointer to void - -Simplify the code converting {tx,rx} ring dma pointer to void - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -957,18 +957,15 @@ static int mtk_init_fq_dma(struct mtk_et - return 0; - } - --static inline void *mtk_qdma_phys_to_virt(struct mtk_tx_ring *ring, u32 desc) -+static void *mtk_qdma_phys_to_virt(struct mtk_tx_ring *ring, u32 desc) - { -- void *ret = ring->dma; -- -- return ret + (desc - ring->phys); -+ return ring->dma + (desc - ring->phys); - } - - static struct mtk_tx_buf *mtk_desc_to_tx_buf(struct mtk_tx_ring *ring, -- struct mtk_tx_dma *txd, -- u32 txd_size) -+ void *txd, u32 txd_size) - { -- int idx = ((void *)txd - (void *)ring->dma) / txd_size; -+ int idx = (txd - ring->dma) / txd_size; - - return &ring->buf[idx]; - } -@@ -976,13 +973,12 @@ static struct mtk_tx_buf *mtk_desc_to_tx - static struct mtk_tx_dma *qdma_to_pdma(struct mtk_tx_ring *ring, - struct mtk_tx_dma *dma) - { -- return ring->dma_pdma - ring->dma + dma; -+ return ring->dma_pdma - (struct mtk_tx_dma *)ring->dma + dma; - } - --static int txd_to_idx(struct mtk_tx_ring *ring, struct mtk_tx_dma *dma, -- u32 txd_size) -+static int txd_to_idx(struct mtk_tx_ring *ring, void *dma, u32 txd_size) - { -- return ((void *)dma - (void *)ring->dma) / txd_size; -+ return (dma - ring->dma) / txd_size; - } - - static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, -@@ -1399,7 +1395,7 @@ static struct mtk_rx_ring *mtk_get_rx_ri - - ring = ð->rx_ring[i]; - idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size); -- rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size; -+ rxd = ring->dma + idx * eth->soc->txrx.rxd_size; - if (rxd->rxd2 & RX_DMA_DONE) { - ring->calc_idx_update = true; - return ring; -@@ -1451,7 +1447,7 @@ static int mtk_poll_rx(struct napi_struc - goto rx_done; - - idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size); -- rxd = (void *)ring->dma + idx * eth->soc->txrx.rxd_size; -+ rxd = ring->dma + idx * eth->soc->txrx.rxd_size; - data = ring->data[idx]; - - if (!mtk_rx_get_desc(eth, &trxd, rxd)) -@@ -1658,7 +1654,7 @@ static int mtk_poll_tx_pdma(struct mtk_e - - mtk_tx_unmap(eth, tx_buf, true); - -- desc = (void *)ring->dma + cpu * eth->soc->txrx.txd_size; -+ desc = ring->dma + cpu * eth->soc->txrx.txd_size; - ring->last_free = desc; - atomic_inc(&ring->free_count); - -@@ -1803,7 +1799,7 @@ static int mtk_tx_alloc(struct mtk_eth * - int next = (i + 1) % MTK_DMA_SIZE; - u32 next_ptr = ring->phys + next * sz; - -- txd = (void *)ring->dma + i * sz; -+ txd = ring->dma + i * sz; - txd->txd2 = next_ptr; - txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; - txd->txd4 = 0; -@@ -1833,7 +1829,7 @@ static int mtk_tx_alloc(struct mtk_eth * - - ring->dma_size = MTK_DMA_SIZE; - atomic_set(&ring->free_count, MTK_DMA_SIZE - 2); -- ring->next_free = &ring->dma[0]; -+ ring->next_free = ring->dma; - ring->last_free = (void *)txd; - ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz)); - ring->thresh = MAX_SKB_FRAGS; -@@ -1948,7 +1944,7 @@ static int mtk_rx_alloc(struct mtk_eth * - if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) - return -ENOMEM; - -- rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size; -+ rxd = ring->dma + i * eth->soc->txrx.rxd_size; - rxd->rxd1 = (unsigned int)dma_addr; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) -@@ -2010,7 +2006,7 @@ static void mtk_rx_clean(struct mtk_eth - if (!ring->data[i]) - continue; - -- rxd = (void *)ring->dma + i * eth->soc->txrx.rxd_size; -+ rxd = ring->dma + i * eth->soc->txrx.rxd_size; - if (!rxd->rxd1) - continue; - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -689,7 +689,7 @@ struct mtk_tx_buf { - * are present - */ - struct mtk_tx_ring { -- struct mtk_tx_dma *dma; -+ void *dma; - struct mtk_tx_buf *buf; - dma_addr_t phys; - struct mtk_tx_dma *next_free; -@@ -719,7 +719,7 @@ enum mtk_rx_flags { - * @calc_idx: The current head of ring - */ - struct mtk_rx_ring { -- struct mtk_rx_dma *dma; -+ void *dma; - u8 **data; - dma_addr_t phys; - u16 frag_size; diff --git a/target/linux/generic/backport-5.15/702-v5.19-29-net-ethernet-mtk_eth_soc-convert-scratch_ring-pointe.patch b/target/linux/generic/backport-5.15/702-v5.19-29-net-ethernet-mtk_eth_soc-convert-scratch_ring-pointe.patch deleted file mode 100644 index af77ee39e1afaa..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-29-net-ethernet-mtk_eth_soc-convert-scratch_ring-pointe.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:38 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: convert scratch_ring pointer to - void - -Simplify the code converting scratch_ring pointer to void - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -933,7 +933,7 @@ static int mtk_init_fq_dma(struct mtk_et - for (i = 0; i < cnt; i++) { - struct mtk_tx_dma_v2 *txd; - -- txd = (void *)eth->scratch_ring + i * soc->txrx.txd_size; -+ txd = eth->scratch_ring + i * soc->txrx.txd_size; - txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE; - if (i < cnt - 1) - txd->txd2 = eth->phy_scratch_ring + ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1029,7 +1029,7 @@ struct mtk_eth { - struct mtk_rx_ring rx_ring_qdma; - struct napi_struct tx_napi; - struct napi_struct rx_napi; -- struct mtk_tx_dma *scratch_ring; -+ void *scratch_ring; - dma_addr_t phy_scratch_ring; - void *scratch_head; - struct clk *clks[MTK_CLK_MAX]; diff --git a/target/linux/generic/backport-5.15/702-v5.19-30-net-ethernet-mtk_eth_soc-introduce-support-for-mt798.patch b/target/linux/generic/backport-5.15/702-v5.19-30-net-ethernet-mtk_eth_soc-introduce-support-for-mt798.patch deleted file mode 100644 index cceb79ba27f3ad..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-30-net-ethernet-mtk_eth_soc-introduce-support-for-mt798.patch +++ /dev/null @@ -1,138 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 20 May 2022 20:11:39 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce support for mt7986 - chipset - -Add support for mt7986-eth driver available on mt7986 soc. - -Tested-by: Sam Shih -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -87,6 +87,43 @@ static const struct mtk_reg_map mt7628_r - }, - }; - -+static const struct mtk_reg_map mt7986_reg_map = { -+ .tx_irq_mask = 0x461c, -+ .tx_irq_status = 0x4618, -+ .pdma = { -+ .rx_ptr = 0x6100, -+ .rx_cnt_cfg = 0x6104, -+ .pcrx_ptr = 0x6108, -+ .glo_cfg = 0x6204, -+ .rst_idx = 0x6208, -+ .delay_irq = 0x620c, -+ .irq_status = 0x6220, -+ .irq_mask = 0x6228, -+ .int_grp = 0x6250, -+ }, -+ .qdma = { -+ .qtx_cfg = 0x4400, -+ .rx_ptr = 0x4500, -+ .rx_cnt_cfg = 0x4504, -+ .qcrx_ptr = 0x4508, -+ .glo_cfg = 0x4604, -+ .rst_idx = 0x4608, -+ .delay_irq = 0x460c, -+ .fc_th = 0x4610, -+ .int_grp = 0x4620, -+ .hred = 0x4644, -+ .ctx_ptr = 0x4700, -+ .dtx_ptr = 0x4704, -+ .crx_ptr = 0x4710, -+ .drx_ptr = 0x4714, -+ .fq_head = 0x4720, -+ .fq_tail = 0x4724, -+ .fq_count = 0x4728, -+ .fq_blen = 0x472c, -+ }, -+ .gdm1_cnt = 0x1c00, -+}; -+ - /* strings used by ethtool */ - static const struct mtk_ethtool_stats { - char str[ETH_GSTRING_LEN]; -@@ -110,7 +147,7 @@ static const char * const mtk_clks_sourc - "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll", - "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb", - "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb", -- "sgmii_ck", "eth2pll", -+ "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1" - }; - - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg) -@@ -3718,6 +3755,21 @@ static const struct mtk_soc_data mt7629_ - }, - }; - -+static const struct mtk_soc_data mt7986_data = { -+ .reg_map = &mt7986_reg_map, -+ .ana_rgc3 = 0x128, -+ .caps = MT7986_CAPS, -+ .required_clks = MT7986_CLKS_BITMAP, -+ .required_pctl = false, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma_v2), -+ .rxd_size = sizeof(struct mtk_rx_dma_v2), -+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, -+ .dma_len_offset = 8, -+ }, -+}; -+ - static const struct mtk_soc_data rt5350_data = { - .reg_map = &mt7628_reg_map, - .caps = MT7628_CAPS, -@@ -3740,6 +3792,7 @@ const struct of_device_id of_mtk_match[] - { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, - { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, - { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, -+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, - { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, - {}, - }; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -624,6 +624,10 @@ enum mtk_clks_map { - MTK_CLK_SGMII2_CDR_FB, - MTK_CLK_SGMII_CK, - MTK_CLK_ETH2PLL, -+ MTK_CLK_WOCPU0, -+ MTK_CLK_WOCPU1, -+ MTK_CLK_NETSYS0, -+ MTK_CLK_NETSYS1, - MTK_CLK_MAX - }; - -@@ -654,6 +658,16 @@ enum mtk_clks_map { - BIT(MTK_CLK_SGMII2_CDR_FB) | \ - BIT(MTK_CLK_SGMII_CK) | \ - BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) -+#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -+ BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ -+ BIT(MTK_CLK_SGMII_TX_250M) | \ -+ BIT(MTK_CLK_SGMII_RX_250M) | \ -+ BIT(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT(MTK_CLK_SGMII2_CDR_FB)) - - enum mtk_dev_state { - MTK_HW_INIT, -@@ -852,6 +866,10 @@ enum mkt_eth_capabilities { - MTK_MUX_U3_GMAC2_TO_QPHY | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) - -+#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ -+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ -+ MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -+ - struct mtk_tx_dma_desc_info { - dma_addr_t addr; - u32 size; diff --git a/target/linux/generic/backport-5.15/702-v5.19-31-net-ethernet-mtk_eth_soc-fix-error-code-in-mtk_flow_.patch b/target/linux/generic/backport-5.15/702-v5.19-31-net-ethernet-mtk_eth_soc-fix-error-code-in-mtk_flow_.patch deleted file mode 100644 index e490333a9bbf02..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-31-net-ethernet-mtk_eth_soc-fix-error-code-in-mtk_flow_.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Dan Carpenter -Date: Thu, 19 May 2022 17:08:00 +0300 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix error code in - mtk_flow_offload_replace() - -Preserve the error code from mtk_foe_entry_commit(). Do not return -success. - -Fixes: c4f033d9e03e ("net: ethernet: mtk_eth_soc: rework hardware flow table management") -Signed-off-by: Dan Carpenter -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -434,7 +434,8 @@ mtk_flow_offload_replace(struct mtk_eth - memcpy(&entry->data, &foe, sizeof(entry->data)); - entry->wed_index = wed_index; - -- if (mtk_foe_entry_commit(eth->ppe, entry) < 0) -+ err = mtk_foe_entry_commit(eth->ppe, entry); -+ if (err < 0) - goto free; - - err = rhashtable_insert_fast(ð->flow_table, &entry->node, diff --git a/target/linux/generic/backport-5.15/702-v5.19-33-net-ethernet-mtk_eth_soc-enable-rx-cksum-offload-for.patch b/target/linux/generic/backport-5.15/702-v5.19-33-net-ethernet-mtk_eth_soc-enable-rx-cksum-offload-for.patch deleted file mode 100644 index cfb6ca48661f08..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-33-net-ethernet-mtk_eth_soc-enable-rx-cksum-offload-for.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 6 Jun 2022 21:49:00 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: enable rx cksum offload for - MTK_NETSYS_V2 - -Enable rx checksum offload for mt7986 chipset. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/c8699805c18f7fd38315fcb8da2787676d83a32c.1654544585.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1473,8 +1473,8 @@ static int mtk_poll_rx(struct napi_struc - int done = 0, bytes = 0; - - while (done < budget) { -+ unsigned int pktlen, *rxdcsum; - struct net_device *netdev; -- unsigned int pktlen; - dma_addr_t dma_addr; - u32 hash, reason; - int mac = 0; -@@ -1541,7 +1541,13 @@ static int mtk_poll_rx(struct napi_struc - pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); - skb->dev = netdev; - skb_put(skb, pktlen); -- if (trxd.rxd4 & eth->soc->txrx.rx_dma_l4_valid) -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ rxdcsum = &trxd.rxd3; -+ else -+ rxdcsum = &trxd.rxd4; -+ -+ if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else - skb_checksum_none_assert(skb); -@@ -3765,6 +3771,7 @@ static const struct mtk_soc_data mt7986_ - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), - .rx_irq_done_mask = MTK_RX_DONE_INT_V2, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, - .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, - .dma_len_offset = 8, - }, diff --git a/target/linux/generic/backport-5.15/702-v5.19-34-eth-mtk_ppe-fix-up-after-merge.patch b/target/linux/generic/backport-5.15/702-v5.19-34-eth-mtk_ppe-fix-up-after-merge.patch deleted file mode 100644 index 5303ca48a7e32b..00000000000000 --- a/target/linux/generic/backport-5.15/702-v5.19-34-eth-mtk_ppe-fix-up-after-merge.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Jakub Kicinski -Date: Thu, 19 May 2022 18:25:55 -0700 -Subject: [PATCH] eth: mtk_ppe: fix up after merge - -I missed this in the barrage of GCC 12 warnings. Commit cf2df74e202d -("net: fix dev_fill_forward_path with pppoe + bridge") changed -the pointer into an array. - -Fixes: d7e6f5836038 ("Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net") -Link: https://lore.kernel.org/r/20220520012555.2262461-1-kuba@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -90,10 +90,11 @@ mtk_flow_get_wdma_info(struct net_device - { - struct net_device_path_ctx ctx = { - .dev = dev, -- .daddr = addr, - }; - struct net_device_path path = {}; - -+ memcpy(ctx.daddr, addr, sizeof(ctx.daddr)); -+ - if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)) - return -1; - diff --git a/target/linux/generic/backport-5.15/703-00-v5.16-net-convert-users-of-bitmap_foo-to-linkmode_foo.patch b/target/linux/generic/backport-5.15/703-00-v5.16-net-convert-users-of-bitmap_foo-to-linkmode_foo.patch deleted file mode 100644 index 5737da6e10f97c..00000000000000 --- a/target/linux/generic/backport-5.15/703-00-v5.16-net-convert-users-of-bitmap_foo-to-linkmode_foo.patch +++ /dev/null @@ -1,948 +0,0 @@ -From 4973056cceacc70966396039fae99867dfafd796 Mon Sep 17 00:00:00 2001 -From: Sean Anderson -Date: Fri, 22 Oct 2021 18:41:04 -0400 -Subject: [PATCH] net: convert users of bitmap_foo() to linkmode_foo() - -This converts instances of - bitmap_foo(args..., __ETHTOOL_LINK_MODE_MASK_NBITS) -to - linkmode_foo(args...) - -I manually fixed up some lines to prevent them from being excessively -long. Otherwise, this change was generated with the following semantic -patch: - -// Generated with -// echo linux/linkmode.h > includes -// git grep -Flf includes include/ | cut -f 2- -d / | cat includes - \ -// | sort | uniq | tee new_includes | wc -l && mv new_includes includes -// and repeating until the number stopped going up -@i@ -@@ - -( - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -| - #include -) - -@depends on i@ -expression list args; -@@ - -( -- bitmap_zero(args, __ETHTOOL_LINK_MODE_MASK_NBITS) -+ linkmode_zero(args) -| -- bitmap_copy(args, __ETHTOOL_LINK_MODE_MASK_NBITS) -+ linkmode_copy(args) -| -- bitmap_and(args, __ETHTOOL_LINK_MODE_MASK_NBITS) -+ linkmode_and(args) -| -- bitmap_or(args, __ETHTOOL_LINK_MODE_MASK_NBITS) -+ linkmode_or(args) -| -- bitmap_empty(args, ETHTOOL_LINK_MODE_MASK_NBITS) -+ linkmode_empty(args) -| -- bitmap_andnot(args, __ETHTOOL_LINK_MODE_MASK_NBITS) -+ linkmode_andnot(args) -| -- bitmap_equal(args, __ETHTOOL_LINK_MODE_MASK_NBITS) -+ linkmode_equal(args) -| -- bitmap_intersects(args, __ETHTOOL_LINK_MODE_MASK_NBITS) -+ linkmode_intersects(args) -| -- bitmap_subset(args, __ETHTOOL_LINK_MODE_MASK_NBITS) -+ linkmode_subset(args) -) - -Add missing linux/mii.h include to mellanox. -DaveM - -Signed-off-by: Sean Anderson -Signed-off-by: David S. Miller ---- - drivers/net/dsa/b53/b53_common.c | 6 ++---- - drivers/net/dsa/bcm_sf2.c | 8 +++---- - drivers/net/dsa/hirschmann/hellcreek.c | 6 ++---- - drivers/net/dsa/lantiq_gswip.c | 14 ++++++------- - drivers/net/dsa/microchip/ksz8795.c | 8 +++---- - drivers/net/dsa/mv88e6xxx/chip.c | 5 ++--- - drivers/net/dsa/ocelot/felix_vsc9959.c | 8 +++---- - drivers/net/dsa/ocelot/seville_vsc9953.c | 8 +++---- - drivers/net/dsa/qca/ar9331.c | 10 ++++----- - drivers/net/dsa/sja1105/sja1105_main.c | 7 +++---- - drivers/net/dsa/xrs700x/xrs700x.c | 8 +++---- - drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c | 8 +++---- - drivers/net/ethernet/atheros/ag71xx.c | 8 +++---- - drivers/net/ethernet/cadence/macb_main.c | 11 +++++----- - .../net/ethernet/freescale/enetc/enetc_pf.c | 8 +++---- - .../net/ethernet/huawei/hinic/hinic_ethtool.c | 10 ++++----- - .../net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 5 ++--- - drivers/net/ethernet/marvell/mvneta.c | 10 ++++----- - .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 7 +++---- - .../marvell/octeontx2/nic/otx2_ethtool.c | 5 ++--- - drivers/net/ethernet/marvell/pxa168_eth.c | 3 +-- - .../net/ethernet/mellanox/mlx4/en_ethtool.c | 21 +++++++------------ - .../microchip/sparx5/sparx5_phylink.c | 7 +++---- - drivers/net/ethernet/mscc/ocelot_net.c | 7 +++---- - .../ethernet/pensando/ionic/ionic_ethtool.c | 3 +-- - .../net/ethernet/xilinx/xilinx_axienet_main.c | 8 +++---- - drivers/net/pcs/pcs-xpcs.c | 2 +- - drivers/net/phy/sfp-bus.c | 2 +- - net/ethtool/ioctl.c | 7 +++---- - 29 files changed, 87 insertions(+), 133 deletions(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -1349,10 +1349,8 @@ void b53_phylink_validate(struct dsa_swi - phylink_set(mask, 100baseT_Full); - } - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - - phylink_helper_basex_speed(state); - } ---- a/drivers/net/dsa/bcm_sf2.c -+++ b/drivers/net/dsa/bcm_sf2.c -@@ -692,7 +692,7 @@ static void bcm_sf2_sw_validate(struct d - state->interface != PHY_INTERFACE_MODE_GMII && - state->interface != PHY_INTERFACE_MODE_INTERNAL && - state->interface != PHY_INTERFACE_MODE_MOCA) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - if (port != core_readl(priv, CORE_IMP0_PRT_ID)) - dev_err(ds->dev, - "Unsupported interface: %d for port %d\n", -@@ -720,10 +720,8 @@ static void bcm_sf2_sw_validate(struct d - phylink_set(mask, 100baseT_Half); - phylink_set(mask, 100baseT_Full); - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port, ---- a/drivers/net/dsa/hirschmann/hellcreek.c -+++ b/drivers/net/dsa/hirschmann/hellcreek.c -@@ -1476,10 +1476,8 @@ static void hellcreek_phylink_validate(s - else - phylink_set(mask, 1000baseT_Full); - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static int ---- a/drivers/net/dsa/lantiq_gswip.c -+++ b/drivers/net/dsa/lantiq_gswip.c -@@ -1452,10 +1452,8 @@ static void gswip_phylink_set_capab(unsi - phylink_set(mask, 100baseT_Half); - phylink_set(mask, 100baseT_Full); - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port, -@@ -1483,7 +1481,7 @@ static void gswip_xrx200_phylink_validat - goto unsupported; - break; - default: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - dev_err(ds->dev, "Unsupported port: %i\n", port); - return; - } -@@ -1493,7 +1491,7 @@ static void gswip_xrx200_phylink_validat - return; - - unsupported: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - dev_err(ds->dev, "Unsupported interface '%s' for port %d\n", - phy_modes(state->interface), port); - } -@@ -1523,7 +1521,7 @@ static void gswip_xrx300_phylink_validat - goto unsupported; - break; - default: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - dev_err(ds->dev, "Unsupported port: %i\n", port); - return; - } -@@ -1533,7 +1531,7 @@ static void gswip_xrx300_phylink_validat - return; - - unsupported: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - dev_err(ds->dev, "Unsupported interface '%s' for port %d\n", - phy_modes(state->interface), port); - } ---- a/drivers/net/dsa/microchip/ksz8795.c -+++ b/drivers/net/dsa/microchip/ksz8795.c -@@ -1542,15 +1542,13 @@ static void ksz8_validate(struct dsa_swi - phylink_set(mask, 100baseT_Half); - phylink_set(mask, 100baseT_Full); - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - - return; - - unsupported: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - dev_err(ds->dev, "Unsupported interface: %s, port: %d\n", - phy_modes(state->interface), port); - } ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -683,9 +683,8 @@ static void mv88e6xxx_validate(struct ds - if (chip->info->ops->phylink_validate) - chip->info->ops->phylink_validate(chip, port, mask, state); - -- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - - /* We can only operate at 2500BaseX or 1000BaseX. If requested - * to advertise both, only report advertising at 2500BaseX. ---- a/drivers/net/dsa/ocelot/felix_vsc9959.c -+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c -@@ -944,7 +944,7 @@ static void vsc9959_phylink_validate(str - - if (state->interface != PHY_INTERFACE_MODE_NA && - state->interface != ocelot_port->phy_mode) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - -@@ -966,10 +966,8 @@ static void vsc9959_phylink_validate(str - phylink_set(mask, 2500baseX_Full); - } - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port, ---- a/drivers/net/dsa/ocelot/seville_vsc9953.c -+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c -@@ -1000,7 +1000,7 @@ static void vsc9953_phylink_validate(str - - if (state->interface != PHY_INTERFACE_MODE_NA && - state->interface != ocelot_port->phy_mode) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - -@@ -1019,10 +1019,8 @@ static void vsc9953_phylink_validate(str - phylink_set(mask, 2500baseX_Full); - } - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static int vsc9953_prevalidate_phy_mode(struct ocelot *ocelot, int port, ---- a/drivers/net/dsa/qca/ar9331.c -+++ b/drivers/net/dsa/qca/ar9331.c -@@ -522,7 +522,7 @@ static void ar9331_sw_phylink_validate(s - goto unsupported; - break; - default: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - dev_err(ds->dev, "Unsupported port: %i\n", port); - return; - } -@@ -536,15 +536,13 @@ static void ar9331_sw_phylink_validate(s - phylink_set(mask, 100baseT_Half); - phylink_set(mask, 100baseT_Full); - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - - return; - - unsupported: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - dev_err(ds->dev, "Unsupported interface: %d, port: %d\n", - state->interface, port); - } ---- a/drivers/net/dsa/sja1105/sja1105_main.c -+++ b/drivers/net/dsa/sja1105/sja1105_main.c -@@ -1360,7 +1360,7 @@ static void sja1105_phylink_validate(str - */ - if (state->interface != PHY_INTERFACE_MODE_NA && - sja1105_phy_mode_mismatch(priv, port, state->interface)) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - -@@ -1380,9 +1380,8 @@ static void sja1105_phylink_validate(str - phylink_set(mask, 2500baseX_Full); - } - -- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static int ---- a/drivers/net/dsa/xrs700x/xrs700x.c -+++ b/drivers/net/dsa/xrs700x/xrs700x.c -@@ -457,7 +457,7 @@ static void xrs700x_phylink_validate(str - phylink_set(mask, 1000baseT_Full); - break; - default: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - dev_err(ds->dev, "Unsupported port: %i\n", port); - return; - } -@@ -468,10 +468,8 @@ static void xrs700x_phylink_validate(str - phylink_set(mask, 10baseT_Full); - phylink_set(mask, 100baseT_Full); - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static void xrs700x_mac_link_up(struct dsa_switch *ds, int port, ---- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c -+++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c -@@ -374,9 +374,8 @@ static int xgbe_set_link_ksettings(struc - __ETHTOOL_LINK_MODE_MASK_NBITS, cmd->link_modes.advertising, - __ETHTOOL_LINK_MODE_MASK_NBITS, lks->link_modes.supported); - -- bitmap_and(advertising, -- cmd->link_modes.advertising, lks->link_modes.supported, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(advertising, cmd->link_modes.advertising, -+ lks->link_modes.supported); - - if ((cmd->base.autoneg == AUTONEG_ENABLE) && - bitmap_empty(advertising, __ETHTOOL_LINK_MODE_MASK_NBITS)) { -@@ -389,8 +388,7 @@ static int xgbe_set_link_ksettings(struc - pdata->phy.autoneg = cmd->base.autoneg; - pdata->phy.speed = speed; - pdata->phy.duplex = cmd->base.duplex; -- bitmap_copy(lks->link_modes.advertising, advertising, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_copy(lks->link_modes.advertising, advertising); - - if (cmd->base.autoneg == AUTONEG_ENABLE) - XGBE_SET_ADV(lks, Autoneg); ---- a/drivers/net/ethernet/atheros/ag71xx.c -+++ b/drivers/net/ethernet/atheros/ag71xx.c -@@ -1082,14 +1082,12 @@ static void ag71xx_mac_validate(struct p - phylink_set(mask, 1000baseX_Full); - } - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - - return; - unsupported: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - } - - static void ag71xx_mac_pcs_get_state(struct phylink_config *config, ---- a/drivers/net/ethernet/cadence/macb_main.c -+++ b/drivers/net/ethernet/cadence/macb_main.c -@@ -523,21 +523,21 @@ static void macb_validate(struct phylink - state->interface != PHY_INTERFACE_MODE_SGMII && - state->interface != PHY_INTERFACE_MODE_10GBASER && - !phy_interface_mode_is_rgmii(state->interface)) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - - if (!macb_is_gem(bp) && - (state->interface == PHY_INTERFACE_MODE_GMII || - phy_interface_mode_is_rgmii(state->interface))) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - - if (state->interface == PHY_INTERFACE_MODE_10GBASER && - !(bp->caps & MACB_CAPS_HIGH_SPEED && - bp->caps & MACB_CAPS_PCS)) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - -@@ -576,9 +576,8 @@ static void macb_validate(struct phylink - phylink_set(mask, 1000baseT_Half); - } - out: -- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -965,7 +965,7 @@ static void enetc_pl_mac_validate(struct - state->interface != PHY_INTERFACE_MODE_2500BASEX && - state->interface != PHY_INTERFACE_MODE_USXGMII && - !phy_interface_mode_is_rgmii(state->interface)) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - -@@ -988,10 +988,8 @@ static void enetc_pl_mac_validate(struct - phylink_set(mask, 2500baseX_Full); - } - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static void enetc_pl_mac_config(struct phylink_config *config, ---- a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c -+++ b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c -@@ -322,12 +322,10 @@ static int hinic_get_link_ksettings(stru - } - } - -- bitmap_copy(link_ksettings->link_modes.supported, -- (unsigned long *)&settings.supported, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_copy(link_ksettings->link_modes.advertising, -- (unsigned long *)&settings.advertising, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_copy(link_ksettings->link_modes.supported, -+ (unsigned long *)&settings.supported); -+ linkmode_copy(link_ksettings->link_modes.advertising, -+ (unsigned long *)&settings.advertising); - - return 0; - } ---- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c -+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c -@@ -467,9 +467,8 @@ static int ixgbe_set_link_ksettings(stru - * this function does not support duplex forcing, but can - * limit the advertising of the adapter to the specified speed - */ -- if (!bitmap_subset(cmd->link_modes.advertising, -- cmd->link_modes.supported, -- __ETHTOOL_LINK_MODE_MASK_NBITS)) -+ if (!linkmode_subset(cmd->link_modes.advertising, -+ cmd->link_modes.supported)) - return -EINVAL; - - /* only allow one speed at a time if no autoneg */ ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3835,14 +3835,14 @@ static void mvneta_validate(struct phyli - */ - if (phy_interface_mode_is_8023z(state->interface)) { - if (!phylink_test(state->advertising, Autoneg)) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - } else if (state->interface != PHY_INTERFACE_MODE_NA && - state->interface != PHY_INTERFACE_MODE_QSGMII && - state->interface != PHY_INTERFACE_MODE_SGMII && - !phy_interface_mode_is_rgmii(state->interface)) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - -@@ -3871,10 +3871,8 @@ static void mvneta_validate(struct phyli - phylink_set(mask, 100baseT_Full); - } - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - - /* We can only operate at 2500BaseX or 1000BaseX. If requested - * to advertise both, only report advertising at 2500BaseX. ---- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -@@ -6377,15 +6377,14 @@ static void mvpp2_phylink_validate(struc - goto empty_set; - } - -- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - - phylink_helper_basex_speed(state); - return; - - empty_set: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - } - - static void mvpp2_xlg_config(struct mvpp2_port *port, unsigned int mode, ---- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c -+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c -@@ -1172,9 +1172,8 @@ static int otx2_set_link_ksettings(struc - otx2_get_link_ksettings(netdev, &cur_ks); - - /* Check requested modes against supported modes by hardware */ -- if (!bitmap_subset(cmd->link_modes.advertising, -- cur_ks.link_modes.supported, -- __ETHTOOL_LINK_MODE_MASK_NBITS)) -+ if (!linkmode_subset(cmd->link_modes.advertising, -+ cur_ks.link_modes.supported)) - return -EINVAL; - - mutex_lock(&mbox->lock); ---- a/drivers/net/ethernet/marvell/pxa168_eth.c -+++ b/drivers/net/ethernet/marvell/pxa168_eth.c -@@ -977,8 +977,7 @@ static int pxa168_init_phy(struct net_de - cmd.base.phy_address = pep->phy_addr; - cmd.base.speed = pep->phy_speed; - cmd.base.duplex = pep->phy_duplex; -- bitmap_copy(cmd.link_modes.advertising, PHY_BASIC_FEATURES, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_copy(cmd.link_modes.advertising, PHY_BASIC_FEATURES); - cmd.base.autoneg = AUTONEG_ENABLE; - - if (cmd.base.speed != 0) ---- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c -+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c -@@ -39,6 +39,7 @@ - #include - #include - #include -+#include - - #include "mlx4_en.h" - #include "en_port.h" -@@ -643,10 +644,8 @@ static unsigned long *ptys2ethtool_link_ - unsigned int i; \ - cfg = &ptys2ethtool_map[reg_]; \ - cfg->speed = speed_; \ -- bitmap_zero(cfg->supported, \ -- __ETHTOOL_LINK_MODE_MASK_NBITS); \ -- bitmap_zero(cfg->advertised, \ -- __ETHTOOL_LINK_MODE_MASK_NBITS); \ -+ linkmode_zero(cfg->supported); \ -+ linkmode_zero(cfg->advertised); \ - for (i = 0 ; i < ARRAY_SIZE(modes) ; ++i) { \ - __set_bit(modes[i], cfg->supported); \ - __set_bit(modes[i], cfg->advertised); \ -@@ -702,10 +701,8 @@ static void ptys2ethtool_update_link_mod - int i; - for (i = 0; i < MLX4_LINK_MODES_SZ; i++) { - if (eth_proto & MLX4_PROT_MASK(i)) -- bitmap_or(link_modes, link_modes, -- ptys2ethtool_link_mode(&ptys2ethtool_map[i], -- report), -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_or(link_modes, link_modes, -+ ptys2ethtool_link_mode(&ptys2ethtool_map[i], report)); - } - } - -@@ -716,11 +713,9 @@ static u32 ethtool2ptys_link_modes(const - u32 ptys_modes = 0; - - for (i = 0; i < MLX4_LINK_MODES_SZ; i++) { -- if (bitmap_intersects( -- ptys2ethtool_link_mode(&ptys2ethtool_map[i], -- report), -- link_modes, -- __ETHTOOL_LINK_MODE_MASK_NBITS)) -+ ulong *map_mode = ptys2ethtool_link_mode(&ptys2ethtool_map[i], -+ report); -+ if (linkmode_intersects(map_mode, link_modes)) - ptys_modes |= 1 << i; - } - return ptys_modes; ---- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c -+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c -@@ -92,12 +92,11 @@ static void sparx5_phylink_validate(stru - } - break; - default: -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } -- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static void sparx5_phylink_mac_config(struct phylink_config *config, ---- a/drivers/net/ethernet/mscc/ocelot_net.c -+++ b/drivers/net/ethernet/mscc/ocelot_net.c -@@ -1509,7 +1509,7 @@ static void vsc7514_phylink_validate(str - - if (state->interface != PHY_INTERFACE_MODE_NA && - state->interface != ocelot_port->phy_mode) { -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - -@@ -1528,9 +1528,8 @@ static void vsc7514_phylink_validate(str - phylink_set(mask, 2500baseT_Full); - phylink_set(mask, 2500baseX_Full); - -- bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static void vsc7514_phylink_mac_config(struct phylink_config *config, ---- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c -+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c -@@ -228,8 +228,7 @@ static int ionic_get_link_ksettings(stru - break; - } - -- bitmap_copy(ks->link_modes.advertising, ks->link_modes.supported, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_copy(ks->link_modes.advertising, ks->link_modes.supported); - - ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER); - ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS); ---- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -@@ -1565,7 +1565,7 @@ static void axienet_validate(struct phyl - netdev_warn(ndev, "Cannot use PHY mode %s, supported: %s\n", - phy_modes(state->interface), - phy_modes(lp->phy_mode)); -- bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(supported); - return; - } - } -@@ -1598,10 +1598,8 @@ static void axienet_validate(struct phyl - break; - } - -- bitmap_and(supported, supported, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -- bitmap_and(state->advertising, state->advertising, mask, -- __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - - static void axienet_mac_pcs_get_state(struct phylink_config *config, ---- a/drivers/net/pcs/pcs-xpcs.c -+++ b/drivers/net/pcs/pcs-xpcs.c -@@ -637,7 +637,7 @@ void xpcs_validate(struct dw_xpcs *xpcs, - if (state->interface == PHY_INTERFACE_MODE_NA) - return; - -- bitmap_zero(xpcs_supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(xpcs_supported); - - compat = xpcs_find_compat(xpcs->id, state->interface); - ---- a/drivers/net/phy/sfp-bus.c -+++ b/drivers/net/phy/sfp-bus.c -@@ -379,7 +379,7 @@ void sfp_parse_support(struct sfp_bus *b - if (bus->sfp_quirk) - bus->sfp_quirk->modes(id, modes); - -- bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_or(support, support, modes); - - phylink_set(support, Autoneg); - phylink_set(support, Pause); ---- a/net/ethtool/ioctl.c -+++ b/net/ethtool/ioctl.c -@@ -335,7 +335,7 @@ EXPORT_SYMBOL(ethtool_intersect_link_mas - void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst, - u32 legacy_u32) - { -- bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(dst); - dst[0] = legacy_u32; - } - EXPORT_SYMBOL(ethtool_convert_legacy_u32_to_link_mode); -@@ -350,11 +350,10 @@ bool ethtool_convert_link_mode_to_legacy - if (__ETHTOOL_LINK_MODE_MASK_NBITS > 32) { - __ETHTOOL_DECLARE_LINK_MODE_MASK(ext); - -- bitmap_zero(ext, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ linkmode_zero(ext); - bitmap_fill(ext, 32); - bitmap_complement(ext, ext, __ETHTOOL_LINK_MODE_MASK_NBITS); -- if (bitmap_intersects(ext, src, -- __ETHTOOL_LINK_MODE_MASK_NBITS)) { -+ if (linkmode_intersects(ext, src)) { - /* src mask goes beyond bit 31 */ - retval = false; - } diff --git a/target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch b/target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch deleted file mode 100644 index 885c2fcf25272c..00000000000000 --- a/target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 38c310eb46f5f80213a92093af11af270c209a76 Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Tue, 26 Oct 2021 11:06:06 +0100 -Subject: [PATCH] net: phylink: add MAC phy_interface_t bitmap - -Add a phy_interface_t bitmap so the MAC driver can specifiy which PHY -interface modes it supports. - -Signed-off-by: Russell King -Signed-off-by: David S. Miller ---- - include/linux/phylink.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -78,6 +78,7 @@ struct phylink_config { - bool ovr_an_inband; - void (*get_fixed_state)(struct phylink_config *config, - struct phylink_link_state *state); -+ DECLARE_PHY_INTERFACE_MASK(supported_interfaces); - }; - - /** diff --git a/target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch b/target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch deleted file mode 100644 index 9800884f6e9a1e..00000000000000 --- a/target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch +++ /dev/null @@ -1,98 +0,0 @@ -From d25f3a74f30aace819163dfa54f2a4b8ca1dc932 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 26 Oct 2021 11:06:11 +0100 -Subject: [PATCH] net: phylink: use supported_interfaces for phylink - validation - -If the network device supplies a supported interface bitmap, we can use -that during phylink's validation to simplify MAC drivers in two ways by -using the supported_interfaces bitmap to: - -1. reject unsupported interfaces before calling into the MAC driver. -2. generate the set of all supported link modes across all supported - interfaces (used mainly for SFP, but also some 10G PHYs.) - -Suggested-by: Sean Anderson -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/phylink.c | 36 ++++++++++++++++++++++++++++++++++++ - include/linux/phylink.h | 12 ++++++++++-- - 2 files changed, 46 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -155,9 +155,45 @@ static const char *phylink_an_mode_str(u - return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown"; - } - -+static int phylink_validate_any(struct phylink *pl, unsigned long *supported, -+ struct phylink_link_state *state) -+{ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(all_adv) = { 0, }; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(all_s) = { 0, }; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(s); -+ struct phylink_link_state t; -+ int intf; -+ -+ for (intf = 0; intf < PHY_INTERFACE_MODE_MAX; intf++) { -+ if (test_bit(intf, pl->config->supported_interfaces)) { -+ linkmode_copy(s, supported); -+ -+ t = *state; -+ t.interface = intf; -+ pl->mac_ops->validate(pl->config, s, &t); -+ linkmode_or(all_s, all_s, s); -+ linkmode_or(all_adv, all_adv, t.advertising); -+ } -+ } -+ -+ linkmode_copy(supported, all_s); -+ linkmode_copy(state->advertising, all_adv); -+ -+ return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; -+} -+ - static int phylink_validate(struct phylink *pl, unsigned long *supported, - struct phylink_link_state *state) - { -+ if (!phy_interface_empty(pl->config->supported_interfaces)) { -+ if (state->interface == PHY_INTERFACE_MODE_NA) -+ return phylink_validate_any(pl, supported, state); -+ -+ if (!test_bit(state->interface, -+ pl->config->supported_interfaces)) -+ return -EINVAL; -+ } -+ - pl->mac_ops->validate(pl->config, supported, state); - - return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -68,6 +68,8 @@ enum phylink_op_type { - * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND - * @get_fixed_state: callback to execute to determine the fixed link state, - * if MAC link is at %MLO_AN_FIXED mode. -+ * @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx -+ * are supported by the MAC/PCS. - */ - struct phylink_config { - struct device *dev; -@@ -136,8 +138,14 @@ struct phylink_mac_ops { - * based on @state->advertising and/or @state->speed and update - * @state->interface accordingly. See phylink_helper_basex_speed(). - * -- * When @state->interface is %PHY_INTERFACE_MODE_NA, phylink expects the -- * MAC driver to return all supported link modes. -+ * When @config->supported_interfaces has been set, phylink will iterate -+ * over the supported interfaces to determine the full capability of the -+ * MAC. The validation function must not print errors if @state->interface -+ * is set to an unexpected value. -+ * -+ * When @config->supported_interfaces is empty, phylink will call this -+ * function with @state->interface set to %PHY_INTERFACE_MODE_NA, and -+ * expects the MAC driver to return all supported link modes. - * - * If the @state->interface mode is not supported, then the @supported - * mask must be cleared. diff --git a/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch b/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch deleted file mode 100644 index b4387865363f71..00000000000000 --- a/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch +++ /dev/null @@ -1,63 +0,0 @@ -From c07c6e8eb4b38bae921f9e2f108d1e7f8e14226e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Thu, 28 Oct 2021 18:00:14 +0100 -Subject: [PATCH] net: dsa: populate supported_interfaces member -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add a new DSA switch operation, phylink_get_interfaces, which should -fill in which PHY_INTERFACE_MODE_* are supported by given port. - -Use this before phylink_create() to fill phylinks supported_interfaces -member, allowing phylink to determine which PHY_INTERFACE_MODEs are -supported. - -Signed-off-by: Marek Behún -[tweaked patch and description to add more complete support -- rmk] -Signed-off-by: Russell King -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - include/net/dsa.h | 2 ++ - net/dsa/port.c | 4 ++++ - net/dsa/slave.c | 4 ++++ - 3 files changed, 10 insertions(+) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -654,6 +654,8 @@ struct dsa_switch_ops { - /* - * PHYLINK integration - */ -+ void (*phylink_get_interfaces)(struct dsa_switch *ds, int port, -+ unsigned long *supported_interfaces); - void (*phylink_validate)(struct dsa_switch *ds, int port, - unsigned long *supported, - struct phylink_link_state *state); ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -1188,6 +1188,10 @@ static int dsa_port_phylink_register(str - dp->pl_config.type = PHYLINK_DEV; - dp->pl_config.pcs_poll = ds->pcs_poll; - -+ if (ds->ops->phylink_get_interfaces) -+ ds->ops->phylink_get_interfaces(ds, dp->index, -+ dp->pl_config.supported_interfaces); -+ - dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), - mode, &dsa_port_phylink_mac_ops); - if (IS_ERR(dp->pl)) { ---- a/net/dsa/slave.c -+++ b/net/dsa/slave.c -@@ -1837,6 +1837,10 @@ static int dsa_slave_phy_setup(struct ne - dp->pl_config.poll_fixed_state = true; - } - -+ if (ds->ops->phylink_get_interfaces) -+ ds->ops->phylink_get_interfaces(ds, dp->index, -+ dp->pl_config.supported_interfaces); -+ - dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode, - &dsa_port_phylink_mac_ops); - if (IS_ERR(dp->pl)) { diff --git a/target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch b/target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch deleted file mode 100644 index 9b67a8a5185781..00000000000000 --- a/target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 21bd64bd717dedac96f53b668144cbe37d3c12d4 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 30 Nov 2021 13:09:55 +0000 -Subject: [PATCH] net: dsa: consolidate phylink creation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The code in port.c and slave.c creating the phylink instance is very -similar - let's consolidate this into a single function. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Marek Behún -Reviewed-by: Andrew Lunn -Signed-off-by: Jakub Kicinski ---- - net/dsa/dsa_priv.h | 2 +- - net/dsa/port.c | 44 ++++++++++++++++++++++++++++---------------- - net/dsa/slave.c | 19 +++---------------- - 3 files changed, 32 insertions(+), 33 deletions(-) - ---- a/net/dsa/dsa_priv.h -+++ b/net/dsa/dsa_priv.h -@@ -261,13 +261,13 @@ int dsa_port_mrp_add_ring_role(const str - const struct switchdev_obj_ring_role_mrp *mrp); - int dsa_port_mrp_del_ring_role(const struct dsa_port *dp, - const struct switchdev_obj_ring_role_mrp *mrp); -+int dsa_port_phylink_create(struct dsa_port *dp); - int dsa_port_link_register_of(struct dsa_port *dp); - void dsa_port_link_unregister_of(struct dsa_port *dp); - int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr); - void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr); - int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast); - void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast); --extern const struct phylink_mac_ops dsa_port_phylink_mac_ops; - - static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp, - const struct net_device *dev) ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -1092,7 +1092,7 @@ static void dsa_port_phylink_mac_link_up - speed, duplex, tx_pause, rx_pause); - } - --const struct phylink_mac_ops dsa_port_phylink_mac_ops = { -+static const struct phylink_mac_ops dsa_port_phylink_mac_ops = { - .validate = dsa_port_phylink_validate, - .mac_pcs_get_state = dsa_port_phylink_mac_pcs_get_state, - .mac_config = dsa_port_phylink_mac_config, -@@ -1101,6 +1101,30 @@ const struct phylink_mac_ops dsa_port_ph - .mac_link_up = dsa_port_phylink_mac_link_up, - }; - -+int dsa_port_phylink_create(struct dsa_port *dp) -+{ -+ struct dsa_switch *ds = dp->ds; -+ phy_interface_t mode; -+ int err; -+ -+ err = of_get_phy_mode(dp->dn, &mode); -+ if (err) -+ mode = PHY_INTERFACE_MODE_NA; -+ -+ if (ds->ops->phylink_get_interfaces) -+ ds->ops->phylink_get_interfaces(ds, dp->index, -+ dp->pl_config.supported_interfaces); -+ -+ dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), -+ mode, &dsa_port_phylink_mac_ops); -+ if (IS_ERR(dp->pl)) { -+ pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl)); -+ return PTR_ERR(dp->pl); -+ } -+ -+ return 0; -+} -+ - static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable) - { - struct dsa_switch *ds = dp->ds; -@@ -1177,27 +1201,15 @@ static int dsa_port_phylink_register(str - { - struct dsa_switch *ds = dp->ds; - struct device_node *port_dn = dp->dn; -- phy_interface_t mode; - int err; - -- err = of_get_phy_mode(port_dn, &mode); -- if (err) -- mode = PHY_INTERFACE_MODE_NA; -- - dp->pl_config.dev = ds->dev; - dp->pl_config.type = PHYLINK_DEV; - dp->pl_config.pcs_poll = ds->pcs_poll; - -- if (ds->ops->phylink_get_interfaces) -- ds->ops->phylink_get_interfaces(ds, dp->index, -- dp->pl_config.supported_interfaces); -- -- dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), -- mode, &dsa_port_phylink_mac_ops); -- if (IS_ERR(dp->pl)) { -- pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl)); -- return PTR_ERR(dp->pl); -- } -+ err = dsa_port_phylink_create(dp); -+ if (err) -+ return err; - - err = phylink_of_phy_connect(dp->pl, port_dn, 0); - if (err && err != -ENODEV) { ---- a/net/dsa/slave.c -+++ b/net/dsa/slave.c -@@ -1817,14 +1817,9 @@ static int dsa_slave_phy_setup(struct ne - struct dsa_port *dp = dsa_slave_to_port(slave_dev); - struct device_node *port_dn = dp->dn; - struct dsa_switch *ds = dp->ds; -- phy_interface_t mode; - u32 phy_flags = 0; - int ret; - -- ret = of_get_phy_mode(port_dn, &mode); -- if (ret) -- mode = PHY_INTERFACE_MODE_NA; -- - dp->pl_config.dev = &slave_dev->dev; - dp->pl_config.type = PHYLINK_NETDEV; - -@@ -1837,17 +1832,9 @@ static int dsa_slave_phy_setup(struct ne - dp->pl_config.poll_fixed_state = true; - } - -- if (ds->ops->phylink_get_interfaces) -- ds->ops->phylink_get_interfaces(ds, dp->index, -- dp->pl_config.supported_interfaces); -- -- dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode, -- &dsa_port_phylink_mac_ops); -- if (IS_ERR(dp->pl)) { -- netdev_err(slave_dev, -- "error creating PHYLINK: %ld\n", PTR_ERR(dp->pl)); -- return PTR_ERR(dp->pl); -- } -+ ret = dsa_port_phylink_create(dp); -+ if (ret) -+ return ret; - - if (ds->ops->get_phy_flags) - phy_flags = ds->ops->get_phy_flags(ds, dp->index); diff --git a/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch b/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch deleted file mode 100644 index 1d9616c0db7f7b..00000000000000 --- a/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 072eea6c22b2af680c3949e64f9adde278c71e68 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 30 Nov 2021 13:10:01 +0000 -Subject: [PATCH] net: dsa: replace phylink_get_interfaces() with - phylink_get_caps() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Phylink needs slightly more information than phylink_get_interfaces() -allows us to get from the DSA drivers - we need the MAC capabilities. -Replace the phylink_get_interfaces() method with phylink_get_caps() to -allow DSA drivers to fill in the phylink_config MAC capabilities field -as well. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Marek Behún -Reviewed-by: Andrew Lunn -Signed-off-by: Jakub Kicinski ---- - include/net/dsa.h | 4 ++-- - net/dsa/port.c | 5 ++--- - 2 files changed, 4 insertions(+), 5 deletions(-) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -654,8 +654,8 @@ struct dsa_switch_ops { - /* - * PHYLINK integration - */ -- void (*phylink_get_interfaces)(struct dsa_switch *ds, int port, -- unsigned long *supported_interfaces); -+ void (*phylink_get_caps)(struct dsa_switch *ds, int port, -+ struct phylink_config *config); - void (*phylink_validate)(struct dsa_switch *ds, int port, - unsigned long *supported, - struct phylink_link_state *state); ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -1111,9 +1111,8 @@ int dsa_port_phylink_create(struct dsa_p - if (err) - mode = PHY_INTERFACE_MODE_NA; - -- if (ds->ops->phylink_get_interfaces) -- ds->ops->phylink_get_interfaces(ds, dp->index, -- dp->pl_config.supported_interfaces); -+ if (ds->ops->phylink_get_caps) -+ ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config); - - dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), - mode, &dsa_port_phylink_mac_ops); diff --git a/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch b/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch deleted file mode 100644 index 9791ad2ac9189a..00000000000000 --- a/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch +++ /dev/null @@ -1,59 +0,0 @@ -From bde018222c6b084ac32933a9f933581dd83da18e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 17 Feb 2022 18:30:35 +0000 -Subject: [PATCH] net: dsa: add support for phylink mac_select_pcs() - -Add DSA support for the phylink mac_select_pcs() method so DSA drivers -can return provide phylink with the appropriate PCS for the PHY -interface mode. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - include/net/dsa.h | 3 +++ - net/dsa/port.c | 15 +++++++++++++++ - 2 files changed, 18 insertions(+) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -659,6 +659,9 @@ struct dsa_switch_ops { - void (*phylink_validate)(struct dsa_switch *ds, int port, - unsigned long *supported, - struct phylink_link_state *state); -+ struct phylink_pcs *(*phylink_mac_select_pcs)(struct dsa_switch *ds, -+ int port, -+ phy_interface_t iface); - int (*phylink_mac_link_state)(struct dsa_switch *ds, int port, - struct phylink_link_state *state); - void (*phylink_mac_config)(struct dsa_switch *ds, int port, ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -1028,6 +1028,20 @@ static void dsa_port_phylink_mac_pcs_get - } - } - -+static struct phylink_pcs * -+dsa_port_phylink_mac_select_pcs(struct phylink_config *config, -+ phy_interface_t interface) -+{ -+ struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); -+ struct dsa_switch *ds = dp->ds; -+ struct phylink_pcs *pcs = NULL; -+ -+ if (ds->ops->phylink_mac_select_pcs) -+ pcs = ds->ops->phylink_mac_select_pcs(ds, dp->index, interface); -+ -+ return pcs; -+} -+ - static void dsa_port_phylink_mac_config(struct phylink_config *config, - unsigned int mode, - const struct phylink_link_state *state) -@@ -1094,6 +1108,7 @@ static void dsa_port_phylink_mac_link_up - - static const struct phylink_mac_ops dsa_port_phylink_mac_ops = { - .validate = dsa_port_phylink_validate, -+ .mac_select_pcs = dsa_port_phylink_mac_select_pcs, - .mac_pcs_get_state = dsa_port_phylink_mac_pcs_get_state, - .mac_config = dsa_port_phylink_mac_config, - .mac_an_restart = dsa_port_phylink_mac_an_restart, diff --git a/target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch b/target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch deleted file mode 100644 index 1a7817b0f96db0..00000000000000 --- a/target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 8e20f591f204f8db7f1182918f8e2285d3f589e0 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 26 Oct 2021 11:06:01 +0100 -Subject: [PATCH] net: phy: add phy_interface_t bitmap support - -Add support for a bitmap for phy interface modes, which includes: -- a macro to declare the interface bitmap -- an inline helper to zero the interface bitmap -- an inline helper to detect an empty interface bitmap -- inline helpers to do a bitwise AND and OR operations on two interface - bitmaps - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - include/linux/phy.h | 34 ++++++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -155,6 +155,40 @@ typedef enum { - PHY_INTERFACE_MODE_MAX, - } phy_interface_t; - -+/* PHY interface mode bitmap handling */ -+#define DECLARE_PHY_INTERFACE_MASK(name) \ -+ DECLARE_BITMAP(name, PHY_INTERFACE_MODE_MAX) -+ -+static inline void phy_interface_zero(unsigned long *intf) -+{ -+ bitmap_zero(intf, PHY_INTERFACE_MODE_MAX); -+} -+ -+static inline bool phy_interface_empty(const unsigned long *intf) -+{ -+ return bitmap_empty(intf, PHY_INTERFACE_MODE_MAX); -+} -+ -+static inline void phy_interface_and(unsigned long *dst, const unsigned long *a, -+ const unsigned long *b) -+{ -+ bitmap_and(dst, a, b, PHY_INTERFACE_MODE_MAX); -+} -+ -+static inline void phy_interface_or(unsigned long *dst, const unsigned long *a, -+ const unsigned long *b) -+{ -+ bitmap_or(dst, a, b, PHY_INTERFACE_MODE_MAX); -+} -+ -+static inline void phy_interface_set_rgmii(unsigned long *intf) -+{ -+ __set_bit(PHY_INTERFACE_MODE_RGMII, intf); -+ __set_bit(PHY_INTERFACE_MODE_RGMII_ID, intf); -+ __set_bit(PHY_INTERFACE_MODE_RGMII_RXID, intf); -+ __set_bit(PHY_INTERFACE_MODE_RGMII_TXID, intf); -+} -+ - /* - * phy_supported_speeds - return all speeds currently supported by a PHY device - */ diff --git a/target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch b/target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch deleted file mode 100644 index 5d5ac4b0094887..00000000000000 --- a/target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch +++ /dev/null @@ -1,197 +0,0 @@ -From d1e86325af377129adb7fc6f34eb044ca6068b47 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 15 Dec 2021 15:34:15 +0000 -Subject: [PATCH] net: phylink: add mac_select_pcs() method to phylink_mac_ops - -mac_select_pcs() allows us to have an explicit point to query which -PCS the MAC wishes to use for a particular PHY interface mode, thereby -allowing us to add support to validate the link settings with the PCS. - -Phylink will also use this to select the PCS to be used during a major -configuration event without the MAC driver needing to call -phylink_set_pcs(). - -Note that if mac_select_pcs() is present, the supported_interfaces -bitmap must be filled in; this avoids mac_select_pcs() being called -with PHY_INTERFACE_MODE_NA when we want to get support for all -interface types. Phylink will return an error in phylink_create() -unless this condition is satisfied. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/phylink.c | 68 +++++++++++++++++++++++++++++++++------ - include/linux/phylink.h | 18 +++++++++++ - 2 files changed, 77 insertions(+), 9 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -155,6 +155,23 @@ static const char *phylink_an_mode_str(u - return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown"; - } - -+static int phylink_validate_mac_and_pcs(struct phylink *pl, -+ unsigned long *supported, -+ struct phylink_link_state *state) -+{ -+ struct phylink_pcs *pcs; -+ -+ if (pl->mac_ops->mac_select_pcs) { -+ pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); -+ if (IS_ERR(pcs)) -+ return PTR_ERR(pcs); -+ } -+ -+ pl->mac_ops->validate(pl->config, supported, state); -+ -+ return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; -+} -+ - static int phylink_validate_any(struct phylink *pl, unsigned long *supported, - struct phylink_link_state *state) - { -@@ -170,9 +187,10 @@ static int phylink_validate_any(struct p - - t = *state; - t.interface = intf; -- pl->mac_ops->validate(pl->config, s, &t); -- linkmode_or(all_s, all_s, s); -- linkmode_or(all_adv, all_adv, t.advertising); -+ if (!phylink_validate_mac_and_pcs(pl, s, &t)) { -+ linkmode_or(all_s, all_s, s); -+ linkmode_or(all_adv, all_adv, t.advertising); -+ } - } - } - -@@ -194,9 +212,7 @@ static int phylink_validate(struct phyli - return -EINVAL; - } - -- pl->mac_ops->validate(pl->config, supported, state); -- -- return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; -+ return phylink_validate_mac_and_pcs(pl, supported, state); - } - - static int phylink_parse_fixedlink(struct phylink *pl, -@@ -486,10 +502,21 @@ static void phylink_mac_pcs_an_restart(s - static void phylink_major_config(struct phylink *pl, bool restart, - const struct phylink_link_state *state) - { -+ struct phylink_pcs *pcs = NULL; - int err; - - phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); - -+ if (pl->mac_ops->mac_select_pcs) { -+ pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); -+ if (IS_ERR(pcs)) { -+ phylink_err(pl, -+ "mac_select_pcs unexpectedly failed: %pe\n", -+ pcs); -+ return; -+ } -+ } -+ - if (pl->mac_ops->mac_prepare) { - err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode, - state->interface); -@@ -500,6 +527,12 @@ static void phylink_major_config(struct - } - } - -+ /* If we have a new PCS, switch to the new PCS after preparing the MAC -+ * for the change. -+ */ -+ if (pcs) -+ phylink_set_pcs(pl, pcs); -+ - phylink_mac_config(pl, state); - - if (pl->pcs_ops) { -@@ -879,6 +912,14 @@ struct phylink *phylink_create(struct ph - struct phylink *pl; - int ret; - -+ /* Validate the supplied configuration */ -+ if (mac_ops->mac_select_pcs && -+ phy_interface_empty(config->supported_interfaces)) { -+ dev_err(config->dev, -+ "phylink: error: empty supported_interfaces but mac_select_pcs() method present\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ - pl = kzalloc(sizeof(*pl), GFP_KERNEL); - if (!pl) - return ERR_PTR(-ENOMEM); -@@ -947,9 +988,10 @@ EXPORT_SYMBOL_GPL(phylink_create); - * @pl: a pointer to a &struct phylink returned from phylink_create() - * @pcs: a pointer to the &struct phylink_pcs - * -- * Bind the MAC PCS to phylink. This may be called after phylink_create(), -- * in mac_prepare() or mac_config() methods if it is desired to dynamically -- * change the PCS. -+ * Bind the MAC PCS to phylink. This may be called after phylink_create(). -+ * If it is desired to dynamically change the PCS, then the preferred method -+ * is to use mac_select_pcs(), but it may also be called in mac_prepare() -+ * or mac_config(). - * - * Please note that there are behavioural changes with the mac_config() - * callback if a PCS is present (denoting a newer setup) so removing a PCS -@@ -960,6 +1002,14 @@ void phylink_set_pcs(struct phylink *pl, - { - pl->pcs = pcs; - pl->pcs_ops = pcs->ops; -+ -+ if (!pl->phylink_disable_state && -+ pl->cfg_link_an_mode == MLO_AN_INBAND) { -+ if (pl->config->pcs_poll || pcs->poll) -+ mod_timer(&pl->link_poll, jiffies + HZ); -+ else -+ del_timer(&pl->link_poll); -+ } - } - EXPORT_SYMBOL_GPL(phylink_set_pcs); - ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -86,6 +86,7 @@ struct phylink_config { - /** - * struct phylink_mac_ops - MAC operations structure. - * @validate: Validate and update the link configuration. -+ * @mac_select_pcs: Select a PCS for the interface mode. - * @mac_pcs_get_state: Read the current link state from the hardware. - * @mac_prepare: prepare for a major reconfiguration of the interface. - * @mac_config: configure the MAC for the selected mode and state. -@@ -100,6 +101,8 @@ struct phylink_mac_ops { - void (*validate)(struct phylink_config *config, - unsigned long *supported, - struct phylink_link_state *state); -+ struct phylink_pcs *(*mac_select_pcs)(struct phylink_config *config, -+ phy_interface_t interface); - void (*mac_pcs_get_state)(struct phylink_config *config, - struct phylink_link_state *state); - int (*mac_prepare)(struct phylink_config *config, unsigned int mode, -@@ -152,6 +155,21 @@ struct phylink_mac_ops { - */ - void validate(struct phylink_config *config, unsigned long *supported, - struct phylink_link_state *state); -+/** -+ * mac_select_pcs: Select a PCS for the interface mode. -+ * @config: a pointer to a &struct phylink_config. -+ * @interface: PHY interface mode for PCS -+ * -+ * Return the &struct phylink_pcs for the specified interface mode, or -+ * NULL if none is required, or an error pointer on error. -+ * -+ * This must not modify any state. It is used to query which PCS should -+ * be used. Phylink will use this during validation to ensure that the -+ * configuration is valid, and when setting a configuration to internally -+ * set the PCS that will be used. -+ */ -+struct phylink_pcs *mac_select_pcs(struct phylink_config *config, -+ phy_interface_t interface); - - /** - * mac_pcs_get_state() - Read the current inband link state from the hardware diff --git a/target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch b/target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch deleted file mode 100644 index f30a566c81e906..00000000000000 --- a/target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch +++ /dev/null @@ -1,341 +0,0 @@ -From 34ae2c09d46a2d0abd907e139b466f798e4095a8 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 15 Nov 2021 10:00:27 +0000 -Subject: [PATCH] net: phylink: add generic validate implementation - -Add a generic validate() implementation using the supported_interfaces -and a bitmask of MAC pause/speed/duplex capabilities. This allows us -to entirely eliminate many driver private validate() implementations. - -We expose the underlying phylink_get_linkmodes() function so that -drivers which have special needs can still benefit from conversion. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/phylink.c | 252 ++++++++++++++++++++++++++++++++++++++ - include/linux/phylink.h | 31 +++++ - 2 files changed, 283 insertions(+) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -172,6 +172,258 @@ static int phylink_validate_mac_and_pcs( - return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; - } - -+static void phylink_caps_to_linkmodes(unsigned long *linkmodes, -+ unsigned long caps) -+{ -+ if (caps & MAC_SYM_PAUSE) -+ __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes); -+ -+ if (caps & MAC_ASYM_PAUSE) -+ __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes); -+ -+ if (caps & MAC_10HD) -+ __set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, linkmodes); -+ -+ if (caps & MAC_10FD) -+ __set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, linkmodes); -+ -+ if (caps & MAC_100HD) { -+ __set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_100FD) { -+ __set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_1000HD) -+ __set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, linkmodes); -+ -+ if (caps & MAC_1000FD) { -+ __set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_1000baseT1_Full_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_2500FD) { -+ __set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_5000FD) -+ __set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, linkmodes); -+ -+ if (caps & MAC_10000FD) { -+ __set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_25000FD) { -+ __set_bit(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_40000FD) { -+ __set_bit(ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_50000FD) { -+ __set_bit(ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT, -+ linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_56000FD) { -+ __set_bit(ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_100000FD) { -+ __set_bit(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, -+ linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, -+ linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseKR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseSR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT, -+ linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseCR_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_100000baseDR_Full_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_200000FD) { -+ __set_bit(ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, -+ linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT, -+ linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT, linkmodes); -+ } -+ -+ if (caps & MAC_400000FD) { -+ __set_bit(ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT, -+ linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT, -+ linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT, linkmodes); -+ __set_bit(ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT, linkmodes); -+ } -+} -+ -+/** -+ * phylink_get_linkmodes() - get acceptable link modes -+ * @linkmodes: ethtool linkmode mask (must be already initialised) -+ * @interface: phy interface mode defined by &typedef phy_interface_t -+ * @mac_capabilities: bitmask of MAC capabilities -+ * -+ * Set all possible pause, speed and duplex linkmodes in @linkmodes that -+ * are supported by the @interface mode and @mac_capabilities. @linkmodes -+ * must have been initialised previously. -+ */ -+void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface, -+ unsigned long mac_capabilities) -+{ -+ unsigned long caps = MAC_SYM_PAUSE | MAC_ASYM_PAUSE; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_USXGMII: -+ caps |= MAC_10000FD | MAC_5000FD | MAC_2500FD; -+ fallthrough; -+ -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_GMII: -+ caps |= MAC_1000HD | MAC_1000FD; -+ fallthrough; -+ -+ case PHY_INTERFACE_MODE_REVRMII: -+ case PHY_INTERFACE_MODE_RMII: -+ case PHY_INTERFACE_MODE_REVMII: -+ case PHY_INTERFACE_MODE_MII: -+ caps |= MAC_10HD | MAC_10FD; -+ fallthrough; -+ -+ case PHY_INTERFACE_MODE_100BASEX: -+ caps |= MAC_100HD | MAC_100FD; -+ break; -+ -+ case PHY_INTERFACE_MODE_TBI: -+ case PHY_INTERFACE_MODE_MOCA: -+ case PHY_INTERFACE_MODE_RTBI: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ caps |= MAC_1000HD; -+ fallthrough; -+ case PHY_INTERFACE_MODE_TRGMII: -+ caps |= MAC_1000FD; -+ break; -+ -+ case PHY_INTERFACE_MODE_2500BASEX: -+ caps |= MAC_2500FD; -+ break; -+ -+ case PHY_INTERFACE_MODE_5GBASER: -+ caps |= MAC_5000FD; -+ break; -+ -+ case PHY_INTERFACE_MODE_XGMII: -+ case PHY_INTERFACE_MODE_RXAUI: -+ case PHY_INTERFACE_MODE_XAUI: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_10GKR: -+ caps |= MAC_10000FD; -+ break; -+ -+ case PHY_INTERFACE_MODE_25GBASER: -+ caps |= MAC_25000FD; -+ break; -+ -+ case PHY_INTERFACE_MODE_XLGMII: -+ caps |= MAC_40000FD; -+ break; -+ -+ case PHY_INTERFACE_MODE_INTERNAL: -+ caps |= ~0; -+ break; -+ -+ case PHY_INTERFACE_MODE_NA: -+ case PHY_INTERFACE_MODE_MAX: -+ case PHY_INTERFACE_MODE_SMII: -+ break; -+ } -+ -+ phylink_caps_to_linkmodes(linkmodes, caps & mac_capabilities); -+} -+EXPORT_SYMBOL_GPL(phylink_get_linkmodes); -+ -+/** -+ * phylink_generic_validate() - generic validate() callback implementation -+ * @config: a pointer to a &struct phylink_config. -+ * @supported: ethtool bitmask for supported link modes. -+ * @state: a pointer to a &struct phylink_link_state. -+ * -+ * Generic implementation of the validate() callback that MAC drivers can -+ * use when they pass the range of supported interfaces and MAC capabilities. -+ * This makes use of phylink_get_linkmodes(). -+ */ -+void phylink_generic_validate(struct phylink_config *config, -+ unsigned long *supported, -+ struct phylink_link_state *state) -+{ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -+ -+ phylink_set_port_modes(mask); -+ phylink_set(mask, Autoneg); -+ phylink_get_linkmodes(mask, state->interface, config->mac_capabilities); -+ -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); -+} -+EXPORT_SYMBOL_GPL(phylink_generic_validate); -+ - static int phylink_validate_any(struct phylink *pl, unsigned long *supported, - struct phylink_link_state *state) - { ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -20,6 +20,29 @@ enum { - MLO_AN_PHY = 0, /* Conventional PHY */ - MLO_AN_FIXED, /* Fixed-link mode */ - MLO_AN_INBAND, /* In-band protocol */ -+ -+ MAC_SYM_PAUSE = BIT(0), -+ MAC_ASYM_PAUSE = BIT(1), -+ MAC_10HD = BIT(2), -+ MAC_10FD = BIT(3), -+ MAC_10 = MAC_10HD | MAC_10FD, -+ MAC_100HD = BIT(4), -+ MAC_100FD = BIT(5), -+ MAC_100 = MAC_100HD | MAC_100FD, -+ MAC_1000HD = BIT(6), -+ MAC_1000FD = BIT(7), -+ MAC_1000 = MAC_1000HD | MAC_1000FD, -+ MAC_2500FD = BIT(8), -+ MAC_5000FD = BIT(9), -+ MAC_10000FD = BIT(10), -+ MAC_20000FD = BIT(11), -+ MAC_25000FD = BIT(12), -+ MAC_40000FD = BIT(13), -+ MAC_50000FD = BIT(14), -+ MAC_56000FD = BIT(15), -+ MAC_100000FD = BIT(16), -+ MAC_200000FD = BIT(17), -+ MAC_400000FD = BIT(18), - }; - - static inline bool phylink_autoneg_inband(unsigned int mode) -@@ -70,6 +93,7 @@ enum phylink_op_type { - * if MAC link is at %MLO_AN_FIXED mode. - * @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx - * are supported by the MAC/PCS. -+ * @mac_capabilities: MAC pause/speed/duplex capabilities. - */ - struct phylink_config { - struct device *dev; -@@ -81,6 +105,7 @@ struct phylink_config { - void (*get_fixed_state)(struct phylink_config *config, - struct phylink_link_state *state); - DECLARE_PHY_INTERFACE_MASK(supported_interfaces); -+ unsigned long mac_capabilities; - }; - - /** -@@ -462,6 +487,12 @@ void pcs_link_up(struct phylink_pcs *pcs - phy_interface_t interface, int speed, int duplex); - #endif - -+void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface, -+ unsigned long mac_capabilities); -+void phylink_generic_validate(struct phylink_config *config, -+ unsigned long *supported, -+ struct phylink_link_state *state); -+ - struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *, - phy_interface_t iface, - const struct phylink_mac_ops *mac_ops); diff --git a/target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch b/target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch deleted file mode 100644 index 524ce9bd92656a..00000000000000 --- a/target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0d22d4b626a4eaa3196019092eb6c1919e9f8caa Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 15 Dec 2021 15:34:20 +0000 -Subject: [PATCH] net: phylink: add pcs_validate() method - -Add a hook for PCS to validate the link parameters. This avoids MAC -drivers having to have knowledge of their PCS in their validate() -method, thereby allowing several MAC drivers to be simplfied. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/phylink.c | 31 +++++++++++++++++++++++++++++++ - include/linux/phylink.h | 20 ++++++++++++++++++++ - 2 files changed, 51 insertions(+) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -160,13 +160,44 @@ static int phylink_validate_mac_and_pcs( - struct phylink_link_state *state) - { - struct phylink_pcs *pcs; -+ int ret; - -+ /* Get the PCS for this interface mode */ - if (pl->mac_ops->mac_select_pcs) { - pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); - if (IS_ERR(pcs)) - return PTR_ERR(pcs); -+ } else { -+ pcs = pl->pcs; - } - -+ if (pcs) { -+ /* The PCS, if present, must be setup before phylink_create() -+ * has been called. If the ops is not initialised, print an -+ * error and backtrace rather than oopsing the kernel. -+ */ -+ if (!pcs->ops) { -+ phylink_err(pl, "interface %s: uninitialised PCS\n", -+ phy_modes(state->interface)); -+ dump_stack(); -+ return -EINVAL; -+ } -+ -+ /* Validate the link parameters with the PCS */ -+ if (pcs->ops->pcs_validate) { -+ ret = pcs->ops->pcs_validate(pcs, supported, state); -+ if (ret < 0 || phylink_is_empty_linkmode(supported)) -+ return -EINVAL; -+ -+ /* Ensure the advertising mask is a subset of the -+ * supported mask. -+ */ -+ linkmode_and(state->advertising, state->advertising, -+ supported); -+ } -+ } -+ -+ /* Then validate the link parameters with the MAC */ - pl->mac_ops->validate(pl->config, supported, state); - - return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -398,6 +398,7 @@ struct phylink_pcs { - - /** - * struct phylink_pcs_ops - MAC PCS operations structure. -+ * @pcs_validate: validate the link configuration. - * @pcs_get_state: read the current MAC PCS link state from the hardware. - * @pcs_config: configure the MAC PCS for the selected mode and state. - * @pcs_an_restart: restart 802.3z BaseX autonegotiation. -@@ -405,6 +406,8 @@ struct phylink_pcs { - * (where necessary). - */ - struct phylink_pcs_ops { -+ int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported, -+ const struct phylink_link_state *state); - void (*pcs_get_state)(struct phylink_pcs *pcs, - struct phylink_link_state *state); - int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode, -@@ -418,6 +421,23 @@ struct phylink_pcs_ops { - - #if 0 /* For kernel-doc purposes only. */ - /** -+ * pcs_validate() - validate the link configuration. -+ * @pcs: a pointer to a &struct phylink_pcs. -+ * @supported: ethtool bitmask for supported link modes. -+ * @state: a const pointer to a &struct phylink_link_state. -+ * -+ * Validate the interface mode, and advertising's autoneg bit, removing any -+ * media ethtool link modes that would not be supportable from the supported -+ * mask. Phylink will propagate the changes to the advertising mask. See the -+ * &struct phylink_mac_ops validate() method. -+ * -+ * Returns -EINVAL if the interface mode/autoneg mode is not supported. -+ * Returns non-zero positive if the link state can be supported. -+ */ -+int pcs_validate(struct phylink_pcs *pcs, unsigned long *supported, -+ const struct phylink_link_state *state); -+ -+/** - * pcs_get_state() - Read the current inband link state from the hardware - * @pcs: a pointer to a &struct phylink_pcs. - * @state: a pointer to a &struct phylink_link_state. diff --git a/target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch b/target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch deleted file mode 100644 index 16d5da9c70e3b5..00000000000000 --- a/target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 3e5b1feccea7db576353ffc302f78d522e4116e6 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 9 Dec 2021 13:11:32 +0000 -Subject: [PATCH] net: phylink: add legacy_pre_march2020 indicator - -Add a boolean to phylink_config to indicate whether a driver has not -been updated for the changes in commit 7cceb599d15d ("net: phylink: -avoid mac_config calls"), and thus are reliant on the old behaviour. - -We were currently keying the phylink behaviour on the presence of a -PCS, but this is sub-optimal for modern drivers that may not have a -PCS. - -This commit merely introduces the new flag, but does not add any use, -since we need all legacy drivers to set this flag before it can be -used. Once these legacy drivers have been updated, we can remove this -flag. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - include/linux/phylink.h | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -84,6 +84,8 @@ enum phylink_op_type { - * struct phylink_config - PHYLINK configuration structure - * @dev: a pointer to a struct device associated with the MAC - * @type: operation type of PHYLINK instance -+ * @legacy_pre_march2020: driver has not been updated for March 2020 updates -+ * (See commit 7cceb599d15d ("net: phylink: avoid mac_config calls") - * @pcs_poll: MAC PCS cannot provide link change interrupt - * @poll_fixed_state: if true, starts link_poll, - * if MAC link is at %MLO_AN_FIXED mode. -@@ -98,6 +100,7 @@ enum phylink_op_type { - struct phylink_config { - struct device *dev; - enum phylink_op_type type; -+ bool legacy_pre_march2020; - bool pcs_poll; - bool poll_fixed_state; - bool mac_managed_pm; diff --git a/target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch b/target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch deleted file mode 100644 index 849881942e1a03..00000000000000 --- a/target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0a9f0794d9bd67e590a9488afe87fbb0419d9539 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 9 Dec 2021 13:11:38 +0000 -Subject: [PATCH] net: dsa: mark DSA phylink as legacy_pre_march2020 - -The majority of DSA drivers do not make use of the PCS support, and -thus operate in legacy mode. In order to preserve this behaviour in -future, we need to set the legacy_pre_march2020 flag so phylink knows -this may require the legacy calls. - -There are some DSA drivers that do make use of PCS support, and these -will continue operating as before - legacy_pre_march2020 will not -prevent split-PCS support enabling the newer phylink behaviour. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - net/dsa/port.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -1126,6 +1126,13 @@ int dsa_port_phylink_create(struct dsa_p - if (err) - mode = PHY_INTERFACE_MODE_NA; - -+ /* Presence of phylink_mac_link_state or phylink_mac_an_restart is -+ * an indicator of a legacy phylink driver. -+ */ -+ if (ds->ops->phylink_mac_link_state || -+ ds->ops->phylink_mac_an_restart) -+ dp->pl_config.legacy_pre_march2020 = true; -+ - if (ds->ops->phylink_get_caps) - ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config); - diff --git a/target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch b/target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch deleted file mode 100644 index 73e53068b8a1c0..00000000000000 --- a/target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 001f4261fe4d5ae710cf1f445b6cae6d9d3ae26e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 9 Dec 2021 13:11:48 +0000 -Subject: [PATCH] net: phylink: use legacy_pre_march2020 - -Use the legacy flag to indicate whether we should operate in legacy -mode. This allows us to stop using the presence of a PCS as an -indicator to the age of the phylink user, and make PCS presence -optional. - -Legacy mode involves: -1) calling mac_config() whenever the link comes up -2) calling mac_config() whenever the inband advertisement changes, - possibly followed by a call to mac_an_restart() -3) making use of mac_an_restart() -4) making use of mac_pcs_get_state() - -All the above functionality was moved to a seperate "PCS" block of -operations in March 2020. - -Update the documents to indicate that the differences that this flag -makes. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 12 ++++++------ - include/linux/phylink.h | 17 +++++++++++++++++ - 2 files changed, 23 insertions(+), 6 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -777,7 +777,7 @@ static void phylink_mac_pcs_an_restart(s - phylink_autoneg_inband(pl->cur_link_an_mode)) { - if (pl->pcs_ops) - pl->pcs_ops->pcs_an_restart(pl->pcs); -- else -+ else if (pl->config->legacy_pre_march2020) - pl->mac_ops->mac_an_restart(pl->config); - } - } -@@ -855,7 +855,7 @@ static int phylink_change_inband_advert( - if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) - return 0; - -- if (!pl->pcs_ops) { -+ if (!pl->pcs_ops && pl->config->legacy_pre_march2020) { - /* Legacy method */ - phylink_mac_config(pl, &pl->link_config); - phylink_mac_pcs_an_restart(pl); -@@ -900,7 +900,8 @@ static void phylink_mac_pcs_get_state(st - - if (pl->pcs_ops) - pl->pcs_ops->pcs_get_state(pl->pcs, state); -- else if (pl->mac_ops->mac_pcs_get_state) -+ else if (pl->mac_ops->mac_pcs_get_state && -+ pl->config->legacy_pre_march2020) - pl->mac_ops->mac_pcs_get_state(pl->config, state); - else - state->link = 0; -@@ -1094,12 +1095,11 @@ static void phylink_resolve(struct work_ - } - phylink_major_config(pl, false, &link_state); - pl->link_config.interface = link_state.interface; -- } else if (!pl->pcs_ops) { -+ } else if (!pl->pcs_ops && pl->config->legacy_pre_march2020) { - /* The interface remains unchanged, only the speed, - * duplex or pause settings have changed. Call the - * old mac_config() method to configure the MAC/PCS -- * only if we do not have a PCS installed (an -- * unconverted user.) -+ * only if we do not have a legacy MAC driver. - */ - phylink_mac_config(pl, &link_state); - } ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -210,6 +210,10 @@ struct phylink_pcs *mac_select_pcs(struc - * negotiation completion state in @state->an_complete, and link up state - * in @state->link. If possible, @state->lp_advertising should also be - * populated. -+ * -+ * Note: This is a legacy method. This function will not be called unless -+ * legacy_pre_march2020 is set in &struct phylink_config and there is no -+ * PCS attached. - */ - void mac_pcs_get_state(struct phylink_config *config, - struct phylink_link_state *state); -@@ -250,6 +254,15 @@ int mac_prepare(struct phylink_config *c - * guaranteed to be correct, and so any mac_config() implementation must - * never reference these fields. - * -+ * Note: For legacy March 2020 drivers (drivers with legacy_pre_march2020 set -+ * in their &phylnk_config and which don't have a PCS), this function will be -+ * called on each link up event, and to also change the in-band advert. For -+ * non-legacy drivers, it will only be called to reconfigure the MAC for a -+ * "major" change in e.g. interface mode. It will not be called for changes -+ * in speed, duplex or pause modes or to change the in-band advertisement. -+ * In any case, it is strongly preferred that speed, duplex and pause settings -+ * are handled in the mac_link_up() method and not in this method. -+ * - * (this requires a rewrite - please refer to mac_link_up() for situations - * where the PCS and MAC are not tightly integrated.) - * -@@ -334,6 +347,10 @@ int mac_finish(struct phylink_config *co - /** - * mac_an_restart() - restart 802.3z BaseX autonegotiation - * @config: a pointer to a &struct phylink_config. -+ * -+ * Note: This is a legacy method. This function will not be called unless -+ * legacy_pre_march2020 is set in &struct phylink_config and there is no -+ * PCS attached. - */ - void mac_an_restart(struct phylink_config *config); - diff --git a/target/linux/generic/backport-5.15/703-15-v5.18-net-phy-phylink-fix-DSA-mac_select_pcs-introduction.patch b/target/linux/generic/backport-5.15/703-15-v5.18-net-phy-phylink-fix-DSA-mac_select_pcs-introduction.patch deleted file mode 100644 index 924d0e954a9079..00000000000000 --- a/target/linux/generic/backport-5.15/703-15-v5.18-net-phy-phylink-fix-DSA-mac_select_pcs-introduction.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 1054457006d4a14de4ae4132030e33d7eedaeba1 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 21 Feb 2022 17:10:52 +0000 -Subject: [PATCH] net: phy: phylink: fix DSA mac_select_pcs() introduction - -Vladimir Oltean reports that probing on DSA drivers that aren't yet -populating supported_interfaces now fails. Fix this by allowing -phylink to detect whether DSA actually provides an underlying -mac_select_pcs() implementation. - -Reported-by: Vladimir Oltean -Fixes: bde018222c6b ("net: dsa: add support for phylink mac_select_pcs()") -Signed-off-by: Russell King (Oracle) -Tested-by: Vladimir Oltean -Link: https://lore.kernel.org/r/E1nMCD6-00A0wC-FG@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 14 +++++++++++--- - net/dsa/port.c | 2 +- - 2 files changed, 12 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -74,6 +74,7 @@ struct phylink { - struct work_struct resolve; - - bool mac_link_dropped; -+ bool using_mac_select_pcs; - - struct sfp_bus *sfp_bus; - bool sfp_may_have_phy; -@@ -163,7 +164,7 @@ static int phylink_validate_mac_and_pcs( - int ret; - - /* Get the PCS for this interface mode */ -- if (pl->mac_ops->mac_select_pcs) { -+ if (pl->using_mac_select_pcs) { - pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); - if (IS_ERR(pcs)) - return PTR_ERR(pcs); -@@ -790,7 +791,7 @@ static void phylink_major_config(struct - - phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); - -- if (pl->mac_ops->mac_select_pcs) { -+ if (pl->using_mac_select_pcs) { - pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); - if (IS_ERR(pcs)) { - phylink_err(pl, -@@ -1192,11 +1193,17 @@ struct phylink *phylink_create(struct ph - phy_interface_t iface, - const struct phylink_mac_ops *mac_ops) - { -+ bool using_mac_select_pcs = false; - struct phylink *pl; - int ret; - -- /* Validate the supplied configuration */ - if (mac_ops->mac_select_pcs && -+ mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) != -+ ERR_PTR(-EOPNOTSUPP)) -+ using_mac_select_pcs = true; -+ -+ /* Validate the supplied configuration */ -+ if (using_mac_select_pcs && - phy_interface_empty(config->supported_interfaces)) { - dev_err(config->dev, - "phylink: error: empty supported_interfaces but mac_select_pcs() method present\n"); -@@ -1221,6 +1228,7 @@ struct phylink *phylink_create(struct ph - return ERR_PTR(-EINVAL); - } - -+ pl->using_mac_select_pcs = using_mac_select_pcs; - pl->phy_state.interface = iface; - pl->link_interface = iface; - if (iface == PHY_INTERFACE_MODE_MOCA) ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -1033,8 +1033,8 @@ dsa_port_phylink_mac_select_pcs(struct p - phy_interface_t interface) - { - struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); -+ struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP); - struct dsa_switch *ds = dp->ds; -- struct phylink_pcs *pcs = NULL; - - if (ds->ops->phylink_mac_select_pcs) - pcs = ds->ops->phylink_mac_select_pcs(ds, dp->index, interface); diff --git a/target/linux/generic/backport-5.15/703-16-v5.16-net-mvneta-populate-supported_interfaces-member.patch b/target/linux/generic/backport-5.15/703-16-v5.16-net-mvneta-populate-supported_interfaces-member.patch deleted file mode 100644 index f21fa4b2778ec7..00000000000000 --- a/target/linux/generic/backport-5.15/703-16-v5.16-net-mvneta-populate-supported_interfaces-member.patch +++ /dev/null @@ -1,48 +0,0 @@ -From fdedb695e6a8657302341cda81d519ef04f9acaa Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Wed, 27 Oct 2021 10:03:43 +0100 -Subject: [PATCH] net: mvneta: populate supported_interfaces member - -Populate the phy_interface_t bitmap for the Marvell mvneta driver with -interfaces modes supported by the MAC. - -Signed-off-by: Russell King -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/marvell/mvneta.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -5180,6 +5180,31 @@ static int mvneta_probe(struct platform_ - - pp->phylink_config.dev = &dev->dev; - pp->phylink_config.type = PHYLINK_NETDEV; -+ phy_interface_set_rgmii(pp->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_QSGMII, -+ pp->phylink_config.supported_interfaces); -+ if (comphy) { -+ /* If a COMPHY is present, we can support any of the serdes -+ * modes and switch between them. -+ */ -+ __set_bit(PHY_INTERFACE_MODE_SGMII, -+ pp->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, -+ pp->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, -+ pp->phylink_config.supported_interfaces); -+ } else if (phy_mode == PHY_INTERFACE_MODE_2500BASEX) { -+ /* No COMPHY, with only 2500BASE-X mode supported */ -+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, -+ pp->phylink_config.supported_interfaces); -+ } else if (phy_mode == PHY_INTERFACE_MODE_1000BASEX || -+ phy_mode == PHY_INTERFACE_MODE_SGMII) { -+ /* No COMPHY, we can switch between 1000BASE-X and SGMII */ -+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, -+ pp->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_SGMII, -+ pp->phylink_config.supported_interfaces); -+ } - - phylink = phylink_create(&pp->phylink_config, pdev->dev.fwnode, - phy_mode, &mvneta_phylink_ops); diff --git a/target/linux/generic/backport-5.15/703-17-v5.16-net-mvneta-remove-interface-checks-in-mvneta_validat.patch b/target/linux/generic/backport-5.15/703-17-v5.16-net-mvneta-remove-interface-checks-in-mvneta_validat.patch deleted file mode 100644 index e287e39d6a4ea7..00000000000000 --- a/target/linux/generic/backport-5.15/703-17-v5.16-net-mvneta-remove-interface-checks-in-mvneta_validat.patch +++ /dev/null @@ -1,35 +0,0 @@ -From d9ca72807ecb236f679b960c70ef5b7d4a5f0222 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 27 Oct 2021 10:03:48 +0100 -Subject: [PATCH] net: mvneta: remove interface checks in mvneta_validate() - -As phylink checks the interface mode against the supported_interfaces -bitmap, we no longer need to validate the interface mode in the -validation function. Remove this to simplify it. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/marvell/mvneta.c | 11 ++--------- - 1 file changed, 2 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3833,15 +3833,8 @@ static void mvneta_validate(struct phyli - * "Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... - * When = 1 (1000BASE-X) this field must be set to 1." - */ -- if (phy_interface_mode_is_8023z(state->interface)) { -- if (!phylink_test(state->advertising, Autoneg)) { -- linkmode_zero(supported); -- return; -- } -- } else if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_QSGMII && -- state->interface != PHY_INTERFACE_MODE_SGMII && -- !phy_interface_mode_is_rgmii(state->interface)) { -+ if (phy_interface_mode_is_8023z(state->interface) && -+ !phylink_test(state->advertising, Autoneg)) { - linkmode_zero(supported); - return; - } diff --git a/target/linux/generic/backport-5.15/703-18-v5.16-net-mvneta-drop-use-of-phylink_helper_basex_speed.patch b/target/linux/generic/backport-5.15/703-18-v5.16-net-mvneta-drop-use-of-phylink_helper_basex_speed.patch deleted file mode 100644 index 9121612bf82942..00000000000000 --- a/target/linux/generic/backport-5.15/703-18-v5.16-net-mvneta-drop-use-of-phylink_helper_basex_speed.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 099cbfa286ab937d8213c2dc5c0b401969b78042 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 27 Oct 2021 10:03:53 +0100 -Subject: [PATCH] net: mvneta: drop use of phylink_helper_basex_speed() - -Now that we have a better method to select SFP interface modes, we -no longer need to use phylink_helper_basex_speed() in a driver's -validation function, and we can also get rid of our hack to indicate -both 1000base-X and 2500base-X if the comphy is present to make that -work. Remove this hack and use of phylink_helper_basex_speed(). - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/marvell/mvneta.c | 12 +++--------- - 1 file changed, 3 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3824,8 +3824,6 @@ static void mvneta_validate(struct phyli - unsigned long *supported, - struct phylink_link_state *state) - { -- struct net_device *ndev = to_net_dev(config->dev); -- struct mvneta_port *pp = netdev_priv(ndev); - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - - /* We only support QSGMII, SGMII, 802.3z and RGMII modes. -@@ -3847,11 +3845,12 @@ static void mvneta_validate(struct phyli - phylink_set(mask, Pause); - - /* Half-duplex at speeds higher than 100Mbit is unsupported */ -- if (pp->comphy || state->interface != PHY_INTERFACE_MODE_2500BASEX) { -+ if (state->interface != PHY_INTERFACE_MODE_2500BASEX) { - phylink_set(mask, 1000baseT_Full); - phylink_set(mask, 1000baseX_Full); - } -- if (pp->comphy || state->interface == PHY_INTERFACE_MODE_2500BASEX) { -+ -+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { - phylink_set(mask, 2500baseT_Full); - phylink_set(mask, 2500baseX_Full); - } -@@ -3866,11 +3865,6 @@ static void mvneta_validate(struct phyli - - linkmode_and(supported, supported, mask); - linkmode_and(state->advertising, state->advertising, mask); -- -- /* We can only operate at 2500BaseX or 1000BaseX. If requested -- * to advertise both, only report advertising at 2500BaseX. -- */ -- phylink_helper_basex_speed(state); - } - - static void mvneta_mac_pcs_get_state(struct phylink_config *config, diff --git a/target/linux/generic/backport-5.15/703-19-v5.17-net-mvneta-use-phylink_generic_validate.patch b/target/linux/generic/backport-5.15/703-19-v5.17-net-mvneta-use-phylink_generic_validate.patch deleted file mode 100644 index 209dfbc0de93f3..00000000000000 --- a/target/linux/generic/backport-5.15/703-19-v5.17-net-mvneta-use-phylink_generic_validate.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 02a0988b98930491db95966fb8086072e47dabb6 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 15 Nov 2021 10:00:32 +0000 -Subject: [PATCH] net: mvneta: use phylink_generic_validate() - -Convert mvneta to use phylink_generic_validate() for the bulk of its -validate() implementation. This network adapter has a restriction -that for 802.3z links, autonegotiation must be enabled. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/marvell/mvneta.c | 34 ++++----------------------- - 1 file changed, 4 insertions(+), 30 deletions(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3824,8 +3824,6 @@ static void mvneta_validate(struct phyli - unsigned long *supported, - struct phylink_link_state *state) - { -- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -- - /* We only support QSGMII, SGMII, 802.3z and RGMII modes. - * When in 802.3z mode, we must have AN enabled: - * "Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... -@@ -3837,34 +3835,7 @@ static void mvneta_validate(struct phyli - return; - } - -- /* Allow all the expected bits */ -- phylink_set(mask, Autoneg); -- phylink_set_port_modes(mask); -- -- /* Asymmetric pause is unsupported */ -- phylink_set(mask, Pause); -- -- /* Half-duplex at speeds higher than 100Mbit is unsupported */ -- if (state->interface != PHY_INTERFACE_MODE_2500BASEX) { -- phylink_set(mask, 1000baseT_Full); -- phylink_set(mask, 1000baseX_Full); -- } -- -- if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { -- phylink_set(mask, 2500baseT_Full); -- phylink_set(mask, 2500baseX_Full); -- } -- -- if (!phy_interface_mode_is_8023z(state->interface)) { -- /* 10M and 100M are only supported in non-802.3z mode */ -- phylink_set(mask, 10baseT_Half); -- phylink_set(mask, 10baseT_Full); -- phylink_set(mask, 100baseT_Half); -- phylink_set(mask, 100baseT_Full); -- } -- -- linkmode_and(supported, supported, mask); -- linkmode_and(state->advertising, state->advertising, mask); -+ phylink_generic_validate(config, supported, state); - } - - static void mvneta_mac_pcs_get_state(struct phylink_config *config, -@@ -5167,6 +5138,9 @@ static int mvneta_probe(struct platform_ - - pp->phylink_config.dev = &dev->dev; - pp->phylink_config.type = PHYLINK_NETDEV; -+ pp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_10 | -+ MAC_100 | MAC_1000FD | MAC_2500FD; -+ - phy_interface_set_rgmii(pp->phylink_config.supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_QSGMII, - pp->phylink_config.supported_interfaces); diff --git a/target/linux/generic/backport-5.15/703-20-v5.17-net-mvneta-mark-as-a-legacy_pre_march2020-driver.patch b/target/linux/generic/backport-5.15/703-20-v5.17-net-mvneta-mark-as-a-legacy_pre_march2020-driver.patch deleted file mode 100644 index 31717565bf175c..00000000000000 --- a/target/linux/generic/backport-5.15/703-20-v5.17-net-mvneta-mark-as-a-legacy_pre_march2020-driver.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 2106be4fdf3223d9c5bd485e6ef094139e3197ba Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Sun, 12 Dec 2021 13:01:21 +0000 -Subject: [PATCH] net: mvneta: mark as a legacy_pre_march2020 driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mvneta provides mac_an_restart and mac_pcs_get_state methods, so needs -to be marked as a legacy driver. Marek spotted that mvneta had stopped -working in 2500base-X mode - thanks for reporting. - -Reported-by: Marek Behún -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/marvell/mvneta.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -5138,6 +5138,7 @@ static int mvneta_probe(struct platform_ - - pp->phylink_config.dev = &dev->dev; - pp->phylink_config.type = PHYLINK_NETDEV; -+ pp->phylink_config.legacy_pre_march2020 = true; - pp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_10 | - MAC_100 | MAC_1000FD | MAC_2500FD; - diff --git a/target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch b/target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch deleted file mode 100644 index affb87b47bc2f0..00000000000000 --- a/target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 83800d29f0c578e82554e7d4c6bfdbdf9b6cf428 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 16 Nov 2021 10:06:43 +0000 -Subject: [PATCH] net: mtk_eth_soc: populate supported_interfaces member - -Populate the phy interface mode bitmap for the Mediatek driver with -interfaces modes supported by the MAC. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3361,6 +3361,26 @@ static int mtk_add_mac(struct mtk_eth *e - - mac->phylink_config.dev = ð->netdev[id]->dev; - mac->phylink_config.type = PHYLINK_NETDEV; -+ __set_bit(PHY_INTERFACE_MODE_MII, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_GMII, -+ mac->phylink_config.supported_interfaces); -+ -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) -+ phy_interface_set_rgmii(mac->phylink_config.supported_interfaces); -+ -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id) -+ __set_bit(PHY_INTERFACE_MODE_TRGMII, -+ mac->phylink_config.supported_interfaces); -+ -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) { -+ __set_bit(PHY_INTERFACE_MODE_SGMII, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, -+ mac->phylink_config.supported_interfaces); -+ } - - phylink = phylink_create(&mac->phylink_config, - of_fwnode_handle(mac->of_node), diff --git a/target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch b/target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch deleted file mode 100644 index 432e23d0a0c5a0..00000000000000 --- a/target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch +++ /dev/null @@ -1,75 +0,0 @@ -From db81ca153814475d7e07365d46a4d1134bd122e2 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 16 Nov 2021 10:06:48 +0000 -Subject: [PATCH] net: mtk_eth_soc: remove interface checks in mtk_validate() - -As phylink checks the interface mode against the supported_interfaces -bitmap, we no longer need to validate the interface mode, nor handle -PHY_INTERFACE_MODE_NA in the validation function. Remove these to -simplify the implementation. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 --------------------- - 1 file changed, 34 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -577,24 +577,8 @@ static void mtk_validate(struct phylink_ - unsigned long *supported, - struct phylink_link_state *state) - { -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_MII && -- state->interface != PHY_INTERFACE_MODE_GMII && -- !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII) && -- phy_interface_mode_is_rgmii(state->interface)) && -- !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && -- !mac->id && state->interface == PHY_INTERFACE_MODE_TRGMII) && -- !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII) && -- (state->interface == PHY_INTERFACE_MODE_SGMII || -- phy_interface_mode_is_8023z(state->interface)))) { -- linkmode_zero(supported); -- return; -- } -- - phylink_set_port_modes(mask); - phylink_set(mask, Autoneg); - -@@ -621,7 +605,6 @@ static void mtk_validate(struct phylink_ - case PHY_INTERFACE_MODE_MII: - case PHY_INTERFACE_MODE_RMII: - case PHY_INTERFACE_MODE_REVMII: -- case PHY_INTERFACE_MODE_NA: - default: - phylink_set(mask, 10baseT_Half); - phylink_set(mask, 10baseT_Full); -@@ -630,23 +613,6 @@ static void mtk_validate(struct phylink_ - break; - } - -- if (state->interface == PHY_INTERFACE_MODE_NA) { -- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) { -- phylink_set(mask, 1000baseT_Full); -- phylink_set(mask, 1000baseX_Full); -- phylink_set(mask, 2500baseX_Full); -- } -- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) { -- phylink_set(mask, 1000baseT_Full); -- phylink_set(mask, 1000baseT_Half); -- phylink_set(mask, 1000baseX_Full); -- } -- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_GEPHY)) { -- phylink_set(mask, 1000baseT_Full); -- phylink_set(mask, 1000baseT_Half); -- } -- } -- - phylink_set(mask, Pause); - phylink_set(mask, Asym_Pause); - diff --git a/target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch b/target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch deleted file mode 100644 index 7585f7c1eb8d3c..00000000000000 --- a/target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 71d927494463c4f016d828e1134da26b7e961af5 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 16 Nov 2021 10:06:53 +0000 -Subject: [PATCH] net: mtk_eth_soc: drop use of phylink_helper_basex_speed() - -Now that we have a better method to select SFP interface modes, we -no longer need to use phylink_helper_basex_speed() in a driver's -validation function, and we can also get rid of our hack to indicate -both 1000base-X and 2500base-X if the comphy is present to make that -work. Remove this hack and use of phylink_helper_basex_speed(). - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -587,8 +587,9 @@ static void mtk_validate(struct phylink_ - phylink_set(mask, 1000baseT_Full); - break; - case PHY_INTERFACE_MODE_1000BASEX: -- case PHY_INTERFACE_MODE_2500BASEX: - phylink_set(mask, 1000baseX_Full); -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: - phylink_set(mask, 2500baseX_Full); - break; - case PHY_INTERFACE_MODE_GMII: -@@ -618,11 +619,6 @@ static void mtk_validate(struct phylink_ - - linkmode_and(supported, supported, mask); - linkmode_and(state->advertising, state->advertising, mask); -- -- /* We can only operate at 2500BaseX or 1000BaseX. If requested -- * to advertise both, only report advertising at 2500BaseX. -- */ -- phylink_helper_basex_speed(state); - } - - static const struct phylink_mac_ops mtk_phylink_ops = { diff --git a/target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch b/target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch deleted file mode 100644 index 69b6906b7a5af1..00000000000000 --- a/target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch +++ /dev/null @@ -1,84 +0,0 @@ -From a4238f6ce151afa331375d74a5033b76da637644 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 16 Nov 2021 10:06:58 +0000 -Subject: [PATCH] net: mtk_eth_soc: use phylink_generic_validate() - -mtk_eth_soc has no special behaviour in its validation implementation, -so can be switched to phylink_generic_validate(). - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 53 ++------------------- - 1 file changed, 4 insertions(+), 49 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -573,56 +573,8 @@ static void mtk_mac_link_up(struct phyli - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - --static void mtk_validate(struct phylink_config *config, -- unsigned long *supported, -- struct phylink_link_state *state) --{ -- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -- -- phylink_set_port_modes(mask); -- phylink_set(mask, Autoneg); -- -- switch (state->interface) { -- case PHY_INTERFACE_MODE_TRGMII: -- phylink_set(mask, 1000baseT_Full); -- break; -- case PHY_INTERFACE_MODE_1000BASEX: -- phylink_set(mask, 1000baseX_Full); -- break; -- case PHY_INTERFACE_MODE_2500BASEX: -- phylink_set(mask, 2500baseX_Full); -- break; -- case PHY_INTERFACE_MODE_GMII: -- case PHY_INTERFACE_MODE_RGMII: -- case PHY_INTERFACE_MODE_RGMII_ID: -- case PHY_INTERFACE_MODE_RGMII_RXID: -- case PHY_INTERFACE_MODE_RGMII_TXID: -- phylink_set(mask, 1000baseT_Half); -- fallthrough; -- case PHY_INTERFACE_MODE_SGMII: -- phylink_set(mask, 1000baseT_Full); -- phylink_set(mask, 1000baseX_Full); -- fallthrough; -- case PHY_INTERFACE_MODE_MII: -- case PHY_INTERFACE_MODE_RMII: -- case PHY_INTERFACE_MODE_REVMII: -- default: -- phylink_set(mask, 10baseT_Half); -- phylink_set(mask, 10baseT_Full); -- phylink_set(mask, 100baseT_Half); -- phylink_set(mask, 100baseT_Full); -- break; -- } -- -- phylink_set(mask, Pause); -- phylink_set(mask, Asym_Pause); -- -- linkmode_and(supported, supported, mask); -- linkmode_and(state->advertising, state->advertising, mask); --} -- - static const struct phylink_mac_ops mtk_phylink_ops = { -- .validate = mtk_validate, -+ .validate = phylink_generic_validate, - .mac_pcs_get_state = mtk_mac_pcs_get_state, - .mac_an_restart = mtk_mac_an_restart, - .mac_config = mtk_mac_config, -@@ -3323,6 +3275,9 @@ static int mtk_add_mac(struct mtk_eth *e - - mac->phylink_config.dev = ð->netdev[id]->dev; - mac->phylink_config.type = PHYLINK_NETDEV; -+ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -+ MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; -+ - __set_bit(PHY_INTERFACE_MODE_MII, - mac->phylink_config.supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_GMII, diff --git a/target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch b/target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch deleted file mode 100644 index 680d20b9437553..00000000000000 --- a/target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch +++ /dev/null @@ -1,29 +0,0 @@ -From b06515367facfadcf5e70cf6f39db749cf4eb5e3 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 9 Dec 2021 13:11:43 +0000 -Subject: [PATCH] net: mtk_eth_soc: mark as a legacy_pre_march2020 driver - -mtk_eth_soc has not been updated for commit 7cceb599d15d ("net: phylink: -avoid mac_config calls"), and makes use of state->speed and -state->duplex in contravention of the phylink documentation. This makes -reliant on the legacy behaviours, so mark it as a legacy driver. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3275,6 +3275,10 @@ static int mtk_add_mac(struct mtk_eth *e - - mac->phylink_config.dev = ð->netdev[id]->dev; - mac->phylink_config.type = PHYLINK_NETDEV; -+ /* This driver makes use of state->speed/state->duplex in -+ * mac_config -+ */ -+ mac->phylink_config.legacy_pre_march2020 = true; - mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; - diff --git a/target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch b/target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch deleted file mode 100644 index 4cdd03aa0542c3..00000000000000 --- a/target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 889e3691b9d6573de133da1f5e78f590e52152cd Mon Sep 17 00:00:00 2001 -From: Jakub Kicinski -Date: Thu, 28 Apr 2022 14:23:13 -0700 -Subject: [PATCH] eth: mtk_eth_soc: remove a copy of the NAPI_POLL_WEIGHT - define - -Defining local versions of NAPI_POLL_WEIGHT with the same -values in the drivers just makes refactoring harder. - -Signed-off-by: Jakub Kicinski -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 - - 2 files changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3574,9 +3574,9 @@ static int mtk_probe(struct platform_dev - */ - init_dummy_netdev(ð->dummy_dev); - netif_napi_add(ð->dummy_dev, ð->tx_napi, mtk_napi_tx, -- MTK_NAPI_WEIGHT); -+ NAPI_POLL_WEIGHT); - netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx, -- MTK_NAPI_WEIGHT); -+ NAPI_POLL_WEIGHT); - - platform_set_drvdata(pdev, eth); - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -25,7 +25,6 @@ - #define MTK_TX_DMA_BUF_LEN 0x3fff - #define MTK_TX_DMA_BUF_LEN_V2 0xffff - #define MTK_DMA_SIZE 512 --#define MTK_NAPI_WEIGHT 64 - #define MTK_MAC_COUNT 2 - #define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN) - #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN) diff --git a/target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch b/target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch deleted file mode 100644 index fd6bd1b87dd85c..00000000000000 --- a/target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0600bdde1fae75fb9bad72033d28edddc72b44b2 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 18 May 2022 15:54:31 +0100 -Subject: [PATCH 01/12] net: mtk_eth_soc: remove unused mac->mode - -mac->mode is only ever written to in one location, and is thus -superflous. Remove it. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 - - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 - - 2 files changed, 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3270,7 +3270,6 @@ static int mtk_add_mac(struct mtk_eth *e - - /* mac config is not set */ - mac->interface = PHY_INTERFACE_MODE_NA; -- mac->mode = MLO_AN_PHY; - mac->speed = SPEED_UNKNOWN; - - mac->phylink_config.dev = ð->netdev[id]->dev; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1086,7 +1086,6 @@ struct mtk_eth { - struct mtk_mac { - int id; - phy_interface_t interface; -- unsigned int mode; - int speed; - struct device_node *of_node; - struct phylink *phylink; diff --git a/target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch b/target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch deleted file mode 100644 index a15914bd553157..00000000000000 --- a/target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 5a7a2f4b29d7546244da7d8bbc1962fce5b230f2 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 18 May 2022 15:54:36 +0100 -Subject: [PATCH 02/12] net: mtk_eth_soc: remove unused sgmii flags - -The "flags" member of struct mtk_sgmii appears to be unused, as are -the MTK_SGMII_PHYSPEED_* and MTK_HAS_FLAGS() macros. Remove them. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 -------- - 1 file changed, 8 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -957,23 +957,15 @@ struct mtk_soc_data { - /* currently no SoC has more than 2 macs */ - #define MTK_MAX_DEVS 2 - --#define MTK_SGMII_PHYSPEED_AN BIT(31) --#define MTK_SGMII_PHYSPEED_MASK GENMASK(2, 0) --#define MTK_SGMII_PHYSPEED_1000 BIT(0) --#define MTK_SGMII_PHYSPEED_2500 BIT(1) --#define MTK_HAS_FLAGS(flags, _x) (((flags) & (_x)) == (_x)) -- - /* struct mtk_sgmii - This is the structure holding sgmii regmap and its - * characteristics - * @regmap: The register map pointing at the range used to setup - * SGMII modes -- * @flags: The enum refers to which mode the sgmii wants to run on - * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap - */ - - struct mtk_sgmii { - struct regmap *regmap[MTK_MAX_DEVS]; -- u32 flags[MTK_MAX_DEVS]; - u32 ana_rgc3; - }; - diff --git a/target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch b/target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch deleted file mode 100644 index e16bc875e52333..00000000000000 --- a/target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch +++ /dev/null @@ -1,40 +0,0 @@ -From bc5e93e0cd22e360eda23859b939280205567580 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 18 May 2022 15:54:42 +0100 -Subject: [PATCH 03/12] net: mtk_eth_soc: add mask and update PCS speed - definitions - -The PCS speed setting is a two bit field, but it is defined as two -separate bits. Add a bitfield mask for the speed definitions, an - use the FIELD_PREP() macro to define each PCS speed. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include "mtk_ppe.h" - - #define MTK_QDMA_PAGE_SIZE 2048 -@@ -474,9 +475,10 @@ - #define SGMSYS_SGMII_MODE 0x20 - #define SGMII_IF_MODE_BIT0 BIT(0) - #define SGMII_SPEED_DUPLEX_AN BIT(1) --#define SGMII_SPEED_10 0x0 --#define SGMII_SPEED_100 BIT(2) --#define SGMII_SPEED_1000 BIT(3) -+#define SGMII_SPEED_MASK GENMASK(3, 2) -+#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) -+#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) -+#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) - #define SGMII_DUPLEX_FULL BIT(4) - #define SGMII_IF_MODE_BIT5 BIT(5) - #define SGMII_REMOTE_FAULT_DIS BIT(8) diff --git a/target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch b/target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch deleted file mode 100644 index fb1ee4e310eb58..00000000000000 --- a/target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 7da3f901f8ecb425105fad39a0f5de73306abe52 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 18 May 2022 15:54:47 +0100 -Subject: [PATCH 04/12] net: mtk_eth_soc: correct 802.3z speed setting - -Phylink does not guarantee that state->speed will be set correctly in -the mac_config() call, so it's a bug that the driver makes use of it. -Moreover, it is making use of it in a function that is only ever called -for 1000BASE-X and 2500BASE-X which operate at a fixed speed which -happens to be the same setting irrespective of the interface mode. We -can simply remove the switch statement and just set the SGMII interface -speed. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 +++++------------- - 1 file changed, 5 insertions(+), 13 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -34,6 +34,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - return 0; - } - -+/* For SGMII interface mode */ - int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id) - { - unsigned int val; -@@ -60,6 +61,9 @@ int mtk_sgmii_setup_mode_an(struct mtk_s - return 0; - } - -+/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a -+ * fixed speed. -+ */ - int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id, - const struct phylink_link_state *state) - { -@@ -82,19 +86,7 @@ int mtk_sgmii_setup_mode_force(struct mt - /* SGMII force mode setting */ - regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val); - val &= ~SGMII_IF_MODE_MASK; -- -- switch (state->speed) { -- case SPEED_10: -- val |= SGMII_SPEED_10; -- break; -- case SPEED_100: -- val |= SGMII_SPEED_100; -- break; -- case SPEED_2500: -- case SPEED_1000: -- val |= SGMII_SPEED_1000; -- break; -- } -+ val |= SGMII_SPEED_1000; - - if (state->duplex == DUPLEX_FULL) - val |= SGMII_DUPLEX_FULL; diff --git a/target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch b/target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch deleted file mode 100644 index 93743ad3ffca02..00000000000000 --- a/target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch +++ /dev/null @@ -1,101 +0,0 @@ -From a459187390bb221827f9c07866c3a5ffbdf9622b Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Wed, 18 May 2022 15:54:52 +0100 -Subject: [PATCH 05/12] net: mtk_eth_soc: correct 802.3z duplex setting - -Phylink does not guarantee that state->duplex will be set correctly in -the mac_config() call, so it's a bug that the driver makes use of it. - -Move the 802.3z PCS duplex configuration to mac_link_up(). - -Signed-off-by: Russell King -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 +++++++++++---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - drivers/net/ethernet/mediatek/mtk_sgmii.c | 22 +++++++++++++++------ - 3 files changed, 29 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -542,8 +542,18 @@ static void mtk_mac_link_up(struct phyli - { - struct mtk_mac *mac = container_of(config, struct mtk_mac, - phylink_config); -- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -+ u32 mcr; - -+ if (phy_interface_mode_is_8023z(interface)) { -+ struct mtk_eth *eth = mac->hw; -+ -+ /* Decide how GMAC and SGMIISYS be mapped */ -+ int sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? -+ 0 : mac->id; -+ mtk_sgmii_link_up(eth->sgmii, sid, speed, duplex); -+ } -+ -+ mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 | - MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC | - MAC_MCR_FORCE_RX_FC); -@@ -3274,9 +3284,7 @@ static int mtk_add_mac(struct mtk_eth *e - - mac->phylink_config.dev = ð->netdev[id]->dev; - mac->phylink_config.type = PHYLINK_NETDEV; -- /* This driver makes use of state->speed/state->duplex in -- * mac_config -- */ -+ /* This driver makes use of state->speed in mac_config */ - mac->phylink_config.legacy_pre_march2020 = true; - mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1104,6 +1104,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id); - int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id, - const struct phylink_link_state *state); -+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex); - void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id); - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -83,14 +83,10 @@ int mtk_sgmii_setup_mode_force(struct mt - val &= ~SGMII_AN_ENABLE; - regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val); - -- /* SGMII force mode setting */ -+ /* Set the speed etc but leave the duplex unchanged */ - regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val); -- val &= ~SGMII_IF_MODE_MASK; -+ val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK; - val |= SGMII_SPEED_1000; -- -- if (state->duplex == DUPLEX_FULL) -- val |= SGMII_DUPLEX_FULL; -- - regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val); - - /* Release PHYA power down state */ -@@ -101,6 +97,20 @@ int mtk_sgmii_setup_mode_force(struct mt - return 0; - } - -+/* For 1000BASE-X and 2500BASE-X interface modes */ -+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex) -+{ -+ unsigned int val; -+ -+ /* SGMII force duplex setting */ -+ regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val); -+ val &= ~SGMII_DUPLEX_FULL; -+ if (duplex == DUPLEX_FULL) -+ val |= SGMII_DUPLEX_FULL; -+ -+ regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val); -+} -+ - void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id) - { - struct mtk_sgmii *ss = eth->sgmii; diff --git a/target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch b/target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch deleted file mode 100644 index 6556bb7d07d6dd..00000000000000 --- a/target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 4ce5a0bd3958ed248f0325bfcb95339f7c74feb2 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 18 May 2022 15:54:57 +0100 -Subject: [PATCH 06/12] net: mtk_eth_soc: stop passing phylink state to sgmii - setup - -Now that mtk_sgmii_setup_mode_force() only uses the interface mode -from the phylink state, pass just the interface mode into this -function. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++-- - 3 files changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -437,7 +437,7 @@ static void mtk_mac_config(struct phylin - /* Setup SGMIISYS with the determined property */ - if (state->interface != PHY_INTERFACE_MODE_SGMII) - err = mtk_sgmii_setup_mode_force(eth->sgmii, sid, -- state); -+ state->interface); - else if (phylink_autoneg_inband(mode)) - err = mtk_sgmii_setup_mode_an(eth->sgmii, sid); - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1103,7 +1103,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - u32 ana_rgc3); - int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id); - int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id, -- const struct phylink_link_state *state); -+ phy_interface_t interface); - void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex); - void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id); - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -65,7 +65,7 @@ int mtk_sgmii_setup_mode_an(struct mtk_s - * fixed speed. - */ - int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id, -- const struct phylink_link_state *state) -+ phy_interface_t interface) - { - unsigned int val; - -@@ -74,7 +74,7 @@ int mtk_sgmii_setup_mode_force(struct mt - - regmap_read(ss->regmap[id], ss->ana_rgc3, &val); - val &= ~RG_PHY_SPEED_MASK; -- if (state->interface == PHY_INTERFACE_MODE_2500BASEX) -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) - val |= RG_PHY_SPEED_3_125G; - regmap_write(ss->regmap[id], ss->ana_rgc3, val); - diff --git a/target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch b/target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch deleted file mode 100644 index 0e22c7fd674109..00000000000000 --- a/target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 1ec619ee4a052fb9ac48b57554ac2722a0bfe73c Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 18 May 2022 15:55:02 +0100 -Subject: [PATCH 07/12] net: mtk_eth_soc: provide mtk_sgmii_config() - -Provide mtk_sgmii_config() to wrap up the decisions about which SGMII -configuration will be called. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +------ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 ++--- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 20 +++++++++++++++++--- - 3 files changed, 20 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -435,12 +435,7 @@ static void mtk_mac_config(struct phylin - 0 : mac->id; - - /* Setup SGMIISYS with the determined property */ -- if (state->interface != PHY_INTERFACE_MODE_SGMII) -- err = mtk_sgmii_setup_mode_force(eth->sgmii, sid, -- state->interface); -- else if (phylink_autoneg_inband(mode)) -- err = mtk_sgmii_setup_mode_an(eth->sgmii, sid); -- -+ err = mtk_sgmii_config(eth->sgmii, sid, mode, state->interface); - if (err) - goto init_err; - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1101,9 +1101,8 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne - - int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np, - u32 ana_rgc3); --int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id); --int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id, -- phy_interface_t interface); -+int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode, -+ phy_interface_t interface); - void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex); - void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id); - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -35,7 +35,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - } - - /* For SGMII interface mode */ --int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id) -+static int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id) - { - unsigned int val; - -@@ -64,8 +64,8 @@ int mtk_sgmii_setup_mode_an(struct mtk_s - /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a - * fixed speed. - */ --int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id, -- phy_interface_t interface) -+static int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id, -+ phy_interface_t interface) - { - unsigned int val; - -@@ -97,6 +97,20 @@ int mtk_sgmii_setup_mode_force(struct mt - return 0; - } - -+int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode, -+ phy_interface_t interface) -+{ -+ int err = 0; -+ -+ /* Setup SGMIISYS with the determined property */ -+ if (interface != PHY_INTERFACE_MODE_SGMII) -+ err = mtk_sgmii_setup_mode_force(ss, id, interface); -+ else if (phylink_autoneg_inband(mode)) -+ err = mtk_sgmii_setup_mode_an(ss, id); -+ -+ return err; -+} -+ - /* For 1000BASE-X and 2500BASE-X interface modes */ - void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex) - { diff --git a/target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch b/target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch deleted file mode 100644 index 8080a2ca441e0b..00000000000000 --- a/target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 650a49bc65df6b0e0051a8f62d7c22d95a8f350d Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 18 May 2022 15:55:07 +0100 -Subject: [PATCH 08/12] net: mtk_eth_soc: add fixme comment for state->speed - use - -Add a fixme comment for the last remaining incorrect usage of -state->speed in the mac_config() method, which is strangely in a code -path which is only run when the PHY interface mode changes. - -This means if we are in RGMII mode, changes in state->speed will not -cause the INTF_MODE, TRGMII_RCK_CTRL and TRGMII_TCK_CTRL registers to -be set according to the speed, nor will the TRGPLL clock be set to the -correct value. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -374,6 +374,14 @@ static void mtk_mac_config(struct phylin - state->interface)) - goto err_phy; - } else { -+ /* FIXME: this is incorrect. Not only does it -+ * use state->speed (which is not guaranteed -+ * to be correct) but it also makes use of it -+ * in a code path that will only be reachable -+ * when the PHY interface mode changes, not -+ * when the speed changes. Consequently, RGMII -+ * is probably broken. -+ */ - mtk_gmac0_rgmii_adjust(mac->hw, - state->interface, - state->speed); diff --git a/target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch b/target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch deleted file mode 100644 index b03ef436bdbb57..00000000000000 --- a/target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 21089867278deb2a110b685e3cd33f64f9ce41e2 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 18 May 2022 15:55:17 +0100 -Subject: [PATCH 10/12] net: mtk_eth_soc: move restoration of SYSCFG0 to - mac_finish() - -The SGMIISYS configuration is performed while ETHSYS_SYSCFG0 is in a -disabled state. In order to preserve this when we switch to phylink_pcs -we need to move the restoration of this register to the mac_finish() -callback. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - 2 files changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -447,8 +447,8 @@ static void mtk_mac_config(struct phylin - if (err) - goto init_err; - -- regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, -- SYSCFG0_SGMII_MASK, val); -+ /* Save the syscfg0 value for mac_finish */ -+ mac->syscfg0 = val; - } else if (phylink_autoneg_inband(mode)) { - dev_err(eth->dev, - "In-band mode not supported in non SGMII mode!\n"); -@@ -472,8 +472,15 @@ static int mtk_mac_finish(struct phylink - { - struct mtk_mac *mac = container_of(config, struct mtk_mac, - phylink_config); -+ struct mtk_eth *eth = mac->hw; - u32 mcr_cur, mcr_new; - -+ /* Enable SGMII */ -+ if (interface == PHY_INTERFACE_MODE_SGMII || -+ phy_interface_mode_is_8023z(interface)) -+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, -+ SYSCFG0_SGMII_MASK, mac->syscfg0); -+ - /* Setup gmac */ - mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - mcr_new = mcr_cur; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1088,6 +1088,7 @@ struct mtk_mac { - struct mtk_hw_stats *hw_stats; - __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; - int hwlro_ip_cnt; -+ unsigned int syscfg0; - }; - - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ diff --git a/target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch b/target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch deleted file mode 100644 index 4c84703cd94c07..00000000000000 --- a/target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 901f3fbe13c3e56f0742e02717ccbfabbc95c463 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 18 May 2022 15:55:22 +0100 -Subject: [PATCH 11/12] net: mtk_eth_soc: convert code structure to suit split - PCS support - -Provide a mtk_pcs structure which encapsulates everything that the PCS -functions need (the regmap and ana_rgc3 offset), and use this in the -PCS functions. Provide shim functions to convert from the existing -"mtk_sgmii_*" interface to the converted PCS functions. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 15 ++- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 123 +++++++++++--------- - 2 files changed, 79 insertions(+), 59 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -959,16 +959,23 @@ struct mtk_soc_data { - /* currently no SoC has more than 2 macs */ - #define MTK_MAX_DEVS 2 - --/* struct mtk_sgmii - This is the structure holding sgmii regmap and its -- * characteristics -+/* struct mtk_pcs - This structure holds each sgmii regmap and associated -+ * data - * @regmap: The register map pointing at the range used to setup - * SGMII modes - * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap - */ -+struct mtk_pcs { -+ struct regmap *regmap; -+ u32 ana_rgc3; -+}; - -+/* struct mtk_sgmii - This is the structure holding sgmii regmap and its -+ * characteristics -+ * @pcs Array of individual PCS structures -+ */ - struct mtk_sgmii { -- struct regmap *regmap[MTK_MAX_DEVS]; -- u32 ana_rgc3; -+ struct mtk_pcs pcs[MTK_MAX_DEVS]; - }; - - /* struct mtk_eth - This is the main datasructure for holding the state ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -9,90 +9,71 @@ - - #include - #include -+#include - #include - - #include "mtk_eth_soc.h" - --int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) --{ -- struct device_node *np; -- int i; -- -- ss->ana_rgc3 = ana_rgc3; -- -- for (i = 0; i < MTK_MAX_DEVS; i++) { -- np = of_parse_phandle(r, "mediatek,sgmiisys", i); -- if (!np) -- break; -- -- ss->regmap[i] = syscon_node_to_regmap(np); -- of_node_put(np); -- if (IS_ERR(ss->regmap[i])) -- return PTR_ERR(ss->regmap[i]); -- } -- -- return 0; --} -- - /* For SGMII interface mode */ --static int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id) -+static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) - { - unsigned int val; - -- if (!ss->regmap[id]) -+ if (!mpcs->regmap) - return -EINVAL; - - /* Setup the link timer and QPHY power up inside SGMIISYS */ -- regmap_write(ss->regmap[id], SGMSYS_PCS_LINK_TIMER, -+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, - SGMII_LINK_TIMER_DEFAULT); - -- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val); -+ regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); - val |= SGMII_REMOTE_FAULT_DIS; -- regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val); -+ regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); - -- regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val); -+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); - val |= SGMII_AN_RESTART; -- regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val); -+ regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); - -- regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val); -+ regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); - val &= ~SGMII_PHYA_PWD; -- regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val); -+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); - - return 0; -+ - } - - /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a - * fixed speed. - */ --static int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id, -- phy_interface_t interface) -+static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, -+ phy_interface_t interface) - { - unsigned int val; - -- if (!ss->regmap[id]) -+ if (!mpcs->regmap) - return -EINVAL; - -- regmap_read(ss->regmap[id], ss->ana_rgc3, &val); -+ regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val); - val &= ~RG_PHY_SPEED_MASK; - if (interface == PHY_INTERFACE_MODE_2500BASEX) - val |= RG_PHY_SPEED_3_125G; -- regmap_write(ss->regmap[id], ss->ana_rgc3, val); -+ regmap_write(mpcs->regmap, mpcs->ana_rgc3, val); - - /* Disable SGMII AN */ -- regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val); -+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); - val &= ~SGMII_AN_ENABLE; -- regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val); -+ regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); - - /* Set the speed etc but leave the duplex unchanged */ -- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val); -+ regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); - val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK; - val |= SGMII_SPEED_1000; -- regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val); -+ regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); - - /* Release PHYA power down state */ -- regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val); -+ regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); - val &= ~SGMII_PHYA_PWD; -- regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val); -+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); - - return 0; - } -@@ -100,44 +81,76 @@ static int mtk_sgmii_setup_mode_force(st - int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode, - phy_interface_t interface) - { -+ struct mtk_pcs *mpcs = &ss->pcs[id]; - int err = 0; - - /* Setup SGMIISYS with the determined property */ - if (interface != PHY_INTERFACE_MODE_SGMII) -- err = mtk_sgmii_setup_mode_force(ss, id, interface); -+ err = mtk_pcs_setup_mode_force(mpcs, interface); - else if (phylink_autoneg_inband(mode)) -- err = mtk_sgmii_setup_mode_an(ss, id); -+ err = mtk_pcs_setup_mode_an(mpcs); - - return err; - } - --/* For 1000BASE-X and 2500BASE-X interface modes */ --void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex) -+static void mtk_pcs_restart_an(struct mtk_pcs *mpcs) -+{ -+ unsigned int val; -+ -+ if (!mpcs->regmap) -+ return; -+ -+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); -+ val |= SGMII_AN_RESTART; -+ regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); -+} -+ -+static void mtk_pcs_link_up(struct mtk_pcs *mpcs, int speed, int duplex) - { - unsigned int val; - - /* SGMII force duplex setting */ -- regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val); -+ regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); - val &= ~SGMII_DUPLEX_FULL; - if (duplex == DUPLEX_FULL) - val |= SGMII_DUPLEX_FULL; - -- regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val); -+ regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); -+} -+ -+/* For 1000BASE-X and 2500BASE-X interface modes */ -+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex) -+{ -+ mtk_pcs_link_up(&ss->pcs[id], speed, duplex); -+} -+ -+int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) -+{ -+ struct device_node *np; -+ int i; -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ np = of_parse_phandle(r, "mediatek,sgmiisys", i); -+ if (!np) -+ break; -+ -+ ss->pcs[i].ana_rgc3 = ana_rgc3; -+ ss->pcs[i].regmap = syscon_node_to_regmap(np); -+ of_node_put(np); -+ if (IS_ERR(ss->pcs[i].regmap)) -+ return PTR_ERR(ss->pcs[i].regmap); -+ } -+ -+ return 0; - } - - void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id) - { -- struct mtk_sgmii *ss = eth->sgmii; -- unsigned int val, sid; -+ unsigned int sid; - - /* Decide how GMAC and SGMIISYS be mapped */ - sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? - 0 : mac_id; - -- if (!ss->regmap[sid]) -- return; -- -- regmap_read(ss->regmap[sid], SGMSYS_PCS_CONTROL_1, &val); -- val |= SGMII_AN_RESTART; -- regmap_write(ss->regmap[sid], SGMSYS_PCS_CONTROL_1, val); -+ mtk_pcs_restart_an(ð->sgmii->pcs[sid]); - } diff --git a/target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch b/target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch deleted file mode 100644 index 0f7e451245907a..00000000000000 --- a/target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch +++ /dev/null @@ -1,262 +0,0 @@ -From 14a44ab0330d290fade1403a920e299cc56d7300 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 18 May 2022 15:55:28 +0100 -Subject: [PATCH 12/12] net: mtk_eth_soc: partially convert to phylink_pcs - -Partially convert mtk_eth_soc to phylink_pcs, moving the configuration, -link up and AN restart over. However, it seems mac_pcs_get_state() -doesn't actually get the state from the PCS, so we can't convert that -over without a better understanding of the hardware. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++---------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 ++- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 55 +++++++++++---------- - 3 files changed, 53 insertions(+), 58 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -310,6 +310,25 @@ static void mtk_gmac0_rgmii_adjust(struc - mtk_w32(eth, val, TRGMII_TCK_CTRL); - } - -+static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, -+ phy_interface_t interface) -+{ -+ struct mtk_mac *mac = container_of(config, struct mtk_mac, -+ phylink_config); -+ struct mtk_eth *eth = mac->hw; -+ unsigned int sid; -+ -+ if (interface == PHY_INTERFACE_MODE_SGMII || -+ phy_interface_mode_is_8023z(interface)) { -+ sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? -+ 0 : mac->id; -+ -+ return mtk_sgmii_select_pcs(eth->sgmii, sid); -+ } -+ -+ return NULL; -+} -+ - static void mtk_mac_config(struct phylink_config *config, unsigned int mode, - const struct phylink_link_state *state) - { -@@ -317,7 +336,7 @@ static void mtk_mac_config(struct phylin - phylink_config); - struct mtk_eth *eth = mac->hw; - int val, ge_mode, err = 0; -- u32 sid, i; -+ u32 i; - - /* MT76x8 has no hardware settings between for the MAC */ - if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && -@@ -438,15 +457,6 @@ static void mtk_mac_config(struct phylin - SYSCFG0_SGMII_MASK, - ~(u32)SYSCFG0_SGMII_MASK); - -- /* Decide how GMAC and SGMIISYS be mapped */ -- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? -- 0 : mac->id; -- -- /* Setup SGMIISYS with the determined property */ -- err = mtk_sgmii_config(eth->sgmii, sid, mode, state->interface); -- if (err) -- goto init_err; -- - /* Save the syscfg0 value for mac_finish */ - mac->syscfg0 = val; - } else if (phylink_autoneg_inband(mode)) { -@@ -526,14 +536,6 @@ static void mtk_mac_pcs_get_state(struct - state->pause |= MLO_PAUSE_TX; - } - --static void mtk_mac_an_restart(struct phylink_config *config) --{ -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); -- -- mtk_sgmii_restart_an(mac->hw, mac->id); --} -- - static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, - phy_interface_t interface) - { -@@ -554,15 +556,6 @@ static void mtk_mac_link_up(struct phyli - phylink_config); - u32 mcr; - -- if (phy_interface_mode_is_8023z(interface)) { -- struct mtk_eth *eth = mac->hw; -- -- /* Decide how GMAC and SGMIISYS be mapped */ -- int sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? -- 0 : mac->id; -- mtk_sgmii_link_up(eth->sgmii, sid, speed, duplex); -- } -- - mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 | - MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC | -@@ -595,8 +588,8 @@ static void mtk_mac_link_up(struct phyli - - static const struct phylink_mac_ops mtk_phylink_ops = { - .validate = phylink_generic_validate, -+ .mac_select_pcs = mtk_mac_select_pcs, - .mac_pcs_get_state = mtk_mac_pcs_get_state, -- .mac_an_restart = mtk_mac_an_restart, - .mac_config = mtk_mac_config, - .mac_finish = mtk_mac_finish, - .mac_link_down = mtk_mac_link_down, ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -964,10 +964,12 @@ struct mtk_soc_data { - * @regmap: The register map pointing at the range used to setup - * SGMII modes - * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap -+ * @pcs: Phylink PCS structure - */ - struct mtk_pcs { - struct regmap *regmap; - u32 ana_rgc3; -+ struct phylink_pcs pcs; - }; - - /* struct mtk_sgmii - This is the structure holding sgmii regmap and its -@@ -1107,12 +1109,9 @@ void mtk_stats_update_mac(struct mtk_mac - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); - u32 mtk_r32(struct mtk_eth *eth, unsigned reg); - -+struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id); - int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np, - u32 ana_rgc3); --int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode, -- phy_interface_t interface); --void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex); --void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id); - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -14,14 +14,16 @@ - - #include "mtk_eth_soc.h" - -+static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs) -+{ -+ return container_of(pcs, struct mtk_pcs, pcs); -+} -+ - /* For SGMII interface mode */ - static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) - { - unsigned int val; - -- if (!mpcs->regmap) -- return -EINVAL; -- - /* Setup the link timer and QPHY power up inside SGMIISYS */ - regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, - SGMII_LINK_TIMER_DEFAULT); -@@ -50,9 +52,6 @@ static int mtk_pcs_setup_mode_force(stru - { - unsigned int val; - -- if (!mpcs->regmap) -- return -EINVAL; -- - regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val); - val &= ~RG_PHY_SPEED_MASK; - if (interface == PHY_INTERFACE_MODE_2500BASEX) -@@ -78,10 +77,12 @@ static int mtk_pcs_setup_mode_force(stru - return 0; - } - --int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode, -- phy_interface_t interface) -+static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) - { -- struct mtk_pcs *mpcs = &ss->pcs[id]; -+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - int err = 0; - - /* Setup SGMIISYS with the determined property */ -@@ -93,22 +94,25 @@ int mtk_sgmii_config(struct mtk_sgmii *s - return err; - } - --static void mtk_pcs_restart_an(struct mtk_pcs *mpcs) -+static void mtk_pcs_restart_an(struct phylink_pcs *pcs) - { -+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - unsigned int val; - -- if (!mpcs->regmap) -- return; -- - regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); - val |= SGMII_AN_RESTART; - regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); - } - --static void mtk_pcs_link_up(struct mtk_pcs *mpcs, int speed, int duplex) -+static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, int speed, int duplex) - { -+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - unsigned int val; - -+ if (!phy_interface_mode_is_8023z(interface)) -+ return; -+ - /* SGMII force duplex setting */ - regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); - val &= ~SGMII_DUPLEX_FULL; -@@ -118,11 +122,11 @@ static void mtk_pcs_link_up(struct mtk_p - regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); - } - --/* For 1000BASE-X and 2500BASE-X interface modes */ --void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex) --{ -- mtk_pcs_link_up(&ss->pcs[id], speed, duplex); --} -+static const struct phylink_pcs_ops mtk_pcs_ops = { -+ .pcs_config = mtk_pcs_config, -+ .pcs_an_restart = mtk_pcs_restart_an, -+ .pcs_link_up = mtk_pcs_link_up, -+}; - - int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) - { -@@ -139,18 +143,17 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - of_node_put(np); - if (IS_ERR(ss->pcs[i].regmap)) - return PTR_ERR(ss->pcs[i].regmap); -+ -+ ss->pcs[i].pcs.ops = &mtk_pcs_ops; - } - - return 0; - } - --void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id) -+struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id) - { -- unsigned int sid; -- -- /* Decide how GMAC and SGMIISYS be mapped */ -- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? -- 0 : mac_id; -+ if (!ss->pcs[id].regmap) -+ return NULL; - -- mtk_pcs_restart_an(ð->sgmii->pcs[sid]); -+ return &ss->pcs[id].pcs; - } diff --git a/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch b/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch deleted file mode 100644 index f65b0cafa858bf..00000000000000 --- a/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 505560028b6deb9b4385cf6100f05ca6f4aacaf8 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Mon, 6 Dec 2021 18:57:49 +0200 -Subject: [PATCH 01/13] net: dsa: mt7530: iterate using - dsa_switch_for_each_user_port in bridging ops - -Avoid repeated calls to dsa_to_port() (some hidden behind dsa_is_user_port -and some in plain sight) by keeping two struct dsa_port references: one -to the port passed as argument, and another to the other ports of the -switch that we're iterating over. - -dsa_to_port(ds, i) gets replaced by other_dp, i gets replaced by -other_port which is derived from other_dp->index, dsa_is_user_port is -handled by the DSA iterator. - -Signed-off-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 52 +++++++++++++++++++++++----------------- - 1 file changed, 30 insertions(+), 22 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1425,27 +1425,31 @@ static int - mt7530_port_bridge_join(struct dsa_switch *ds, int port, - struct net_device *bridge) - { -- struct mt7530_priv *priv = ds->priv; -+ struct dsa_port *dp = dsa_to_port(ds, port), *other_dp; - u32 port_bitmap = BIT(MT7530_CPU_PORT); -- int i; -+ struct mt7530_priv *priv = ds->priv; - - mutex_lock(&priv->reg_mutex); - -- for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ dsa_switch_for_each_user_port(other_dp, ds) { -+ int other_port = other_dp->index; -+ -+ if (dp == other_dp) -+ continue; -+ - /* Add this port to the port matrix of the other ports in the - * same bridge. If the port is disabled, port matrix is kept - * and not being setup until the port becomes enabled. - */ -- if (dsa_is_user_port(ds, i) && i != port) { -- if (dsa_to_port(ds, i)->bridge_dev != bridge) -- continue; -- if (priv->ports[i].enable) -- mt7530_set(priv, MT7530_PCR_P(i), -- PCR_MATRIX(BIT(port))); -- priv->ports[i].pm |= PCR_MATRIX(BIT(port)); -+ if (other_dp->bridge_dev != bridge) -+ continue; - -- port_bitmap |= BIT(i); -- } -+ if (priv->ports[other_port].enable) -+ mt7530_set(priv, MT7530_PCR_P(other_port), -+ PCR_MATRIX(BIT(port))); -+ priv->ports[other_port].pm |= PCR_MATRIX(BIT(port)); -+ -+ port_bitmap |= BIT(other_port); - } - - /* Add the all other ports to this port matrix. */ -@@ -1550,24 +1554,28 @@ static void - mt7530_port_bridge_leave(struct dsa_switch *ds, int port, - struct net_device *bridge) - { -+ struct dsa_port *dp = dsa_to_port(ds, port), *other_dp; - struct mt7530_priv *priv = ds->priv; -- int i; - - mutex_lock(&priv->reg_mutex); - -- for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ dsa_switch_for_each_user_port(other_dp, ds) { -+ int other_port = other_dp->index; -+ -+ if (dp == other_dp) -+ continue; -+ - /* Remove this port from the port matrix of the other ports - * in the same bridge. If the port is disabled, port matrix - * is kept and not being setup until the port becomes enabled. - */ -- if (dsa_is_user_port(ds, i) && i != port) { -- if (dsa_to_port(ds, i)->bridge_dev != bridge) -- continue; -- if (priv->ports[i].enable) -- mt7530_clear(priv, MT7530_PCR_P(i), -- PCR_MATRIX(BIT(port))); -- priv->ports[i].pm &= ~PCR_MATRIX(BIT(port)); -- } -+ if (other_dp->bridge_dev != bridge) -+ continue; -+ -+ if (priv->ports[other_port].enable) -+ mt7530_clear(priv, MT7530_PCR_P(other_port), -+ PCR_MATRIX(BIT(port))); -+ priv->ports[other_port].pm &= ~PCR_MATRIX(BIT(port)); - } - - /* Set the cpu port to be the only one in the port matrix of diff --git a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch b/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch deleted file mode 100644 index e04bb11e80a6fe..00000000000000 --- a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch +++ /dev/null @@ -1,166 +0,0 @@ -From a1da54bcd664fc27169386db966575675ac3ccb0 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 11 Apr 2022 10:46:01 +0100 -Subject: [PATCH 02/13] net: dsa: mt7530: populate supported_interfaces and - mac_capabilities -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Populate the supported interfaces and MAC capabilities for mt7530, -mt7531 and mt7621 DSA switches. Filling this in will enable phylink -to pre-check the PHY interface mode against the the supported -interfaces bitmap prior to calling the validate function, and will -eventually allow us to convert to using the generic validation. - -Tested-by: Marek Behún -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 74 ++++++++++++++++++++++++++++++++++++++++ - drivers/net/dsa/mt7530.h | 2 ++ - 2 files changed, 76 insertions(+) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2687,6 +2687,32 @@ mt7531_setup(struct dsa_switch *ds) - return 0; - } - -+static void mt7530_mac_port_get_caps(struct dsa_switch *ds, int port, -+ struct phylink_config *config) -+{ -+ switch (port) { -+ case 0 ... 4: /* Internal phy */ -+ __set_bit(PHY_INTERFACE_MODE_GMII, -+ config->supported_interfaces); -+ break; -+ -+ case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -+ phy_interface_set_rgmii(config->supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_MII, -+ config->supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_GMII, -+ config->supported_interfaces); -+ break; -+ -+ case 6: /* 1st cpu port */ -+ __set_bit(PHY_INTERFACE_MODE_RGMII, -+ config->supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_TRGMII, -+ config->supported_interfaces); -+ break; -+ } -+} -+ - static bool - mt7530_phy_mode_supported(struct dsa_switch *ds, int port, - const struct phylink_link_state *state) -@@ -2723,6 +2749,37 @@ static bool mt7531_is_rgmii_port(struct - return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII); - } - -+static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port, -+ struct phylink_config *config) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ switch (port) { -+ case 0 ... 4: /* Internal phy */ -+ __set_bit(PHY_INTERFACE_MODE_GMII, -+ config->supported_interfaces); -+ break; -+ -+ case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */ -+ if (mt7531_is_rgmii_port(priv, port)) { -+ phy_interface_set_rgmii(config->supported_interfaces); -+ break; -+ } -+ fallthrough; -+ -+ case 6: /* 1st cpu port supports sgmii/8023z only */ -+ __set_bit(PHY_INTERFACE_MODE_SGMII, -+ config->supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, -+ config->supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, -+ config->supported_interfaces); -+ -+ config->mac_capabilities |= MAC_2500FD; -+ break; -+ } -+} -+ - static bool - mt7531_phy_mode_supported(struct dsa_switch *ds, int port, - const struct phylink_link_state *state) -@@ -3199,6 +3256,18 @@ mt7531_cpu_port_config(struct dsa_switch - return 0; - } - -+static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, -+ struct phylink_config *config) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ /* This switch only supports full-duplex at 1Gbps */ -+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -+ MAC_10 | MAC_100 | MAC_1000FD; -+ -+ priv->info->mac_port_get_caps(ds, port, config); -+} -+ - static void - mt7530_mac_port_validate(struct dsa_switch *ds, int port, - unsigned long *supported) -@@ -3435,6 +3504,7 @@ static const struct dsa_switch_ops mt753 - .port_vlan_del = mt7530_port_vlan_del, - .port_mirror_add = mt753x_port_mirror_add, - .port_mirror_del = mt753x_port_mirror_del, -+ .phylink_get_caps = mt753x_phylink_get_caps, - .phylink_validate = mt753x_phylink_validate, - .phylink_mac_link_state = mt753x_phylink_mac_link_state, - .phylink_mac_config = mt753x_phylink_mac_config, -@@ -3452,6 +3522,7 @@ static const struct mt753x_info mt753x_t - .phy_read = mt7530_phy_read, - .phy_write = mt7530_phy_write, - .pad_setup = mt7530_pad_clk_setup, -+ .mac_port_get_caps = mt7530_mac_port_get_caps, - .phy_mode_supported = mt7530_phy_mode_supported, - .mac_port_validate = mt7530_mac_port_validate, - .mac_port_get_state = mt7530_phylink_mac_link_state, -@@ -3463,6 +3534,7 @@ static const struct mt753x_info mt753x_t - .phy_read = mt7530_phy_read, - .phy_write = mt7530_phy_write, - .pad_setup = mt7530_pad_clk_setup, -+ .mac_port_get_caps = mt7530_mac_port_get_caps, - .phy_mode_supported = mt7530_phy_mode_supported, - .mac_port_validate = mt7530_mac_port_validate, - .mac_port_get_state = mt7530_phylink_mac_link_state, -@@ -3475,6 +3547,7 @@ static const struct mt753x_info mt753x_t - .phy_write = mt7531_ind_phy_write, - .pad_setup = mt7531_pad_setup, - .cpu_port_config = mt7531_cpu_port_config, -+ .mac_port_get_caps = mt7531_mac_port_get_caps, - .phy_mode_supported = mt7531_phy_mode_supported, - .mac_port_validate = mt7531_mac_port_validate, - .mac_port_get_state = mt7531_phylink_mac_link_state, -@@ -3537,6 +3610,7 @@ mt7530_probe(struct mdio_device *mdiodev - */ - if (!priv->info->sw_setup || !priv->info->pad_setup || - !priv->info->phy_read || !priv->info->phy_write || -+ !priv->info->mac_port_get_caps || - !priv->info->phy_mode_supported || - !priv->info->mac_port_validate || - !priv->info->mac_port_get_state || !priv->info->mac_port_config) ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -807,6 +807,8 @@ struct mt753x_info { - int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val); - int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface); - int (*cpu_port_config)(struct dsa_switch *ds, int port); -+ void (*mac_port_get_caps)(struct dsa_switch *ds, int port, -+ struct phylink_config *config); - bool (*phy_mode_supported)(struct dsa_switch *ds, int port, - const struct phylink_link_state *state); - void (*mac_port_validate)(struct dsa_switch *ds, int port, diff --git a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch b/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch deleted file mode 100644 index 31be0e7be346df..00000000000000 --- a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch +++ /dev/null @@ -1,172 +0,0 @@ -From e3f6719e2269868ca129b05da50cd55786848954 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 11 Apr 2022 10:46:06 +0100 -Subject: [PATCH 03/13] net: dsa: mt7530: remove interface checks -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -As phylink checks the interface mode against the supported_interfaces -bitmap, we no longer need to validate the interface mode, nor handle -PHY_INTERFACE_MODE_NA in the validation function. Remove these to -simplify the implementation. - -Tested-by: Marek Behún -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 82 ---------------------------------------- - drivers/net/dsa/mt7530.h | 2 - - 2 files changed, 84 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2713,37 +2713,6 @@ static void mt7530_mac_port_get_caps(str - } - } - --static bool --mt7530_phy_mode_supported(struct dsa_switch *ds, int port, -- const struct phylink_link_state *state) --{ -- struct mt7530_priv *priv = ds->priv; -- -- switch (port) { -- case 0 ... 4: /* Internal phy */ -- if (state->interface != PHY_INTERFACE_MODE_GMII) -- return false; -- break; -- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -- if (!phy_interface_mode_is_rgmii(state->interface) && -- state->interface != PHY_INTERFACE_MODE_MII && -- state->interface != PHY_INTERFACE_MODE_GMII) -- return false; -- break; -- case 6: /* 1st cpu port */ -- if (state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_TRGMII) -- return false; -- break; -- default: -- dev_err(priv->dev, "%s: unsupported port: %i\n", __func__, -- port); -- return false; -- } -- -- return true; --} -- - static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port) - { - return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII); -@@ -2780,44 +2749,6 @@ static void mt7531_mac_port_get_caps(str - } - } - --static bool --mt7531_phy_mode_supported(struct dsa_switch *ds, int port, -- const struct phylink_link_state *state) --{ -- struct mt7530_priv *priv = ds->priv; -- -- switch (port) { -- case 0 ... 4: /* Internal phy */ -- if (state->interface != PHY_INTERFACE_MODE_GMII) -- return false; -- break; -- case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */ -- if (mt7531_is_rgmii_port(priv, port)) -- return phy_interface_mode_is_rgmii(state->interface); -- fallthrough; -- case 6: /* 1st cpu port supports sgmii/8023z only */ -- if (state->interface != PHY_INTERFACE_MODE_SGMII && -- !phy_interface_mode_is_8023z(state->interface)) -- return false; -- break; -- default: -- dev_err(priv->dev, "%s: unsupported port: %i\n", __func__, -- port); -- return false; -- } -- -- return true; --} -- --static bool --mt753x_phy_mode_supported(struct dsa_switch *ds, int port, -- const struct phylink_link_state *state) --{ -- struct mt7530_priv *priv = ds->priv; -- -- return priv->info->phy_mode_supported(ds, port, state); --} -- - static int - mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) - { -@@ -3072,9 +3003,6 @@ mt753x_phylink_mac_config(struct dsa_swi - struct mt7530_priv *priv = ds->priv; - u32 mcr_cur, mcr_new; - -- if (!mt753x_phy_mode_supported(ds, port, state)) -- goto unsupported; -- - switch (port) { - case 0 ... 4: /* Internal phy */ - if (state->interface != PHY_INTERFACE_MODE_GMII) -@@ -3290,12 +3218,6 @@ mt753x_phylink_validate(struct dsa_switc - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - struct mt7530_priv *priv = ds->priv; - -- if (state->interface != PHY_INTERFACE_MODE_NA && -- !mt753x_phy_mode_supported(ds, port, state)) { -- linkmode_zero(supported); -- return; -- } -- - phylink_set_port_modes(mask); - - if (state->interface != PHY_INTERFACE_MODE_TRGMII && -@@ -3523,7 +3445,6 @@ static const struct mt753x_info mt753x_t - .phy_write = mt7530_phy_write, - .pad_setup = mt7530_pad_clk_setup, - .mac_port_get_caps = mt7530_mac_port_get_caps, -- .phy_mode_supported = mt7530_phy_mode_supported, - .mac_port_validate = mt7530_mac_port_validate, - .mac_port_get_state = mt7530_phylink_mac_link_state, - .mac_port_config = mt7530_mac_config, -@@ -3535,7 +3456,6 @@ static const struct mt753x_info mt753x_t - .phy_write = mt7530_phy_write, - .pad_setup = mt7530_pad_clk_setup, - .mac_port_get_caps = mt7530_mac_port_get_caps, -- .phy_mode_supported = mt7530_phy_mode_supported, - .mac_port_validate = mt7530_mac_port_validate, - .mac_port_get_state = mt7530_phylink_mac_link_state, - .mac_port_config = mt7530_mac_config, -@@ -3548,7 +3468,6 @@ static const struct mt753x_info mt753x_t - .pad_setup = mt7531_pad_setup, - .cpu_port_config = mt7531_cpu_port_config, - .mac_port_get_caps = mt7531_mac_port_get_caps, -- .phy_mode_supported = mt7531_phy_mode_supported, - .mac_port_validate = mt7531_mac_port_validate, - .mac_port_get_state = mt7531_phylink_mac_link_state, - .mac_port_config = mt7531_mac_config, -@@ -3611,7 +3530,6 @@ mt7530_probe(struct mdio_device *mdiodev - if (!priv->info->sw_setup || !priv->info->pad_setup || - !priv->info->phy_read || !priv->info->phy_write || - !priv->info->mac_port_get_caps || -- !priv->info->phy_mode_supported || - !priv->info->mac_port_validate || - !priv->info->mac_port_get_state || !priv->info->mac_port_config) - return -EINVAL; ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -809,8 +809,6 @@ struct mt753x_info { - int (*cpu_port_config)(struct dsa_switch *ds, int port); - void (*mac_port_get_caps)(struct dsa_switch *ds, int port, - struct phylink_config *config); -- bool (*phy_mode_supported)(struct dsa_switch *ds, int port, -- const struct phylink_link_state *state); - void (*mac_port_validate)(struct dsa_switch *ds, int port, - unsigned long *supported); - int (*mac_port_get_state)(struct dsa_switch *ds, int port, diff --git a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch b/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch deleted file mode 100644 index 2a5d5ae9d909cb..00000000000000 --- a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 58344a3b85f1bd5ffddfc2c11f6f2bf688b5f990 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 11 Apr 2022 10:46:12 +0100 -Subject: [PATCH 04/13] net: dsa: mt7530: drop use of - phylink_helper_basex_speed() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Now that we have a better method to select SFP interface modes, we -no longer need to use phylink_helper_basex_speed() in a driver's -validation function. - -Tested-by: Marek Behún -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 5 ----- - 1 file changed, 5 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3242,11 +3242,6 @@ mt753x_phylink_validate(struct dsa_switc - - linkmode_and(supported, supported, mask); - linkmode_and(state->advertising, state->advertising, mask); -- -- /* We can only operate at 2500BaseX or 1000BaseX. If requested -- * to advertise both, only report advertising at 2500BaseX. -- */ -- phylink_helper_basex_speed(state); - } - - static int diff --git a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch b/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch deleted file mode 100644 index ad672312e4835c..00000000000000 --- a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 3c1d788a62dc648d1846049b66119ebb69dedd52 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 11 Apr 2022 10:46:17 +0100 -Subject: [PATCH 05/13] net: dsa: mt7530: only indicate linkmodes that can be - supported -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Now that mt7530 is not using the basex helper, it becomes unnecessary to -indicate support for both 1000baseX and 2500baseX when one of the 803.3z -PHY interface modes is being selected. Ensure that the driver indicates -only those linkmodes that can actually be supported by the PHY interface -mode. - -Tested-by: Marek Behún -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 12 ++++++++---- - drivers/net/dsa/mt7530.h | 1 + - 2 files changed, 9 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2820,12 +2820,13 @@ static int mt7531_rgmii_setup(struct mt7 - } - - static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port, -+ phy_interface_t interface, - unsigned long *supported) - { - /* Port5 supports ethier RGMII or SGMII. - * Port6 supports SGMII only. - */ -- if (port == 6) { -+ if (port == 6 && interface == PHY_INTERFACE_MODE_2500BASEX) { - phylink_set(supported, 2500baseX_Full); - phylink_set(supported, 2500baseT_Full); - } -@@ -3198,16 +3199,18 @@ static void mt753x_phylink_get_caps(stru - - static void - mt7530_mac_port_validate(struct dsa_switch *ds, int port, -+ phy_interface_t interface, - unsigned long *supported) - { - } - - static void mt7531_mac_port_validate(struct dsa_switch *ds, int port, -+ phy_interface_t interface, - unsigned long *supported) - { - struct mt7530_priv *priv = ds->priv; - -- mt7531_sgmii_validate(priv, port, supported); -+ mt7531_sgmii_validate(priv, port, interface, supported); - } - - static void -@@ -3230,12 +3233,13 @@ mt753x_phylink_validate(struct dsa_switc - } - - /* This switch only supports 1G full-duplex. */ -- if (state->interface != PHY_INTERFACE_MODE_MII) { -+ if (state->interface != PHY_INTERFACE_MODE_MII && -+ state->interface != PHY_INTERFACE_MODE_2500BASEX) { - phylink_set(mask, 1000baseT_Full); - phylink_set(mask, 1000baseX_Full); - } - -- priv->info->mac_port_validate(ds, port, mask); -+ priv->info->mac_port_validate(ds, port, state->interface, mask); - - phylink_set(mask, Pause); - phylink_set(mask, Asym_Pause); ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -810,6 +810,7 @@ struct mt753x_info { - void (*mac_port_get_caps)(struct dsa_switch *ds, int port, - struct phylink_config *config); - void (*mac_port_validate)(struct dsa_switch *ds, int port, -+ phy_interface_t interface, - unsigned long *supported); - int (*mac_port_get_state)(struct dsa_switch *ds, int port, - struct phylink_link_state *state); diff --git a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch b/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch deleted file mode 100644 index 8d9802f1ee450e..00000000000000 --- a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 1c2211cb15dd3957fb26c0e1615eceb5db851ad6 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 11 Apr 2022 10:46:22 +0100 -Subject: [PATCH 06/13] net: dsa: mt7530: switch to use phylink_get_linkmodes() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Switch mt7530 to use phylink_get_linkmodes() to generate the ethtool -linkmodes that can be supported. We are unable to use the generic -helper for this as pause modes are dependent on the interface as -the Autoneg bit depends on the interface mode. - -Tested-by: Marek Behún -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 57 ++++------------------------------------ - 1 file changed, 5 insertions(+), 52 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2819,19 +2819,6 @@ static int mt7531_rgmii_setup(struct mt7 - return 0; - } - --static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port, -- phy_interface_t interface, -- unsigned long *supported) --{ -- /* Port5 supports ethier RGMII or SGMII. -- * Port6 supports SGMII only. -- */ -- if (port == 6 && interface == PHY_INTERFACE_MODE_2500BASEX) { -- phylink_set(supported, 2500baseX_Full); -- phylink_set(supported, 2500baseT_Full); -- } --} -- - static void - mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port, - unsigned int mode, phy_interface_t interface, -@@ -3198,51 +3185,21 @@ static void mt753x_phylink_get_caps(stru - } - - static void --mt7530_mac_port_validate(struct dsa_switch *ds, int port, -- phy_interface_t interface, -- unsigned long *supported) --{ --} -- --static void mt7531_mac_port_validate(struct dsa_switch *ds, int port, -- phy_interface_t interface, -- unsigned long *supported) --{ -- struct mt7530_priv *priv = ds->priv; -- -- mt7531_sgmii_validate(priv, port, interface, supported); --} -- --static void - mt753x_phylink_validate(struct dsa_switch *ds, int port, - unsigned long *supported, - struct phylink_link_state *state) - { - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -- struct mt7530_priv *priv = ds->priv; -+ u32 caps; -+ -+ caps = dsa_to_port(ds, port)->pl_config.mac_capabilities; - - phylink_set_port_modes(mask); -+ phylink_get_linkmodes(mask, state->interface, caps); - - if (state->interface != PHY_INTERFACE_MODE_TRGMII && -- !phy_interface_mode_is_8023z(state->interface)) { -- phylink_set(mask, 10baseT_Half); -- phylink_set(mask, 10baseT_Full); -- phylink_set(mask, 100baseT_Half); -- phylink_set(mask, 100baseT_Full); -+ !phy_interface_mode_is_8023z(state->interface)) - phylink_set(mask, Autoneg); -- } -- -- /* This switch only supports 1G full-duplex. */ -- if (state->interface != PHY_INTERFACE_MODE_MII && -- state->interface != PHY_INTERFACE_MODE_2500BASEX) { -- phylink_set(mask, 1000baseT_Full); -- phylink_set(mask, 1000baseX_Full); -- } -- -- priv->info->mac_port_validate(ds, port, state->interface, mask); -- -- phylink_set(mask, Pause); -- phylink_set(mask, Asym_Pause); - - linkmode_and(supported, supported, mask); - linkmode_and(state->advertising, state->advertising, mask); -@@ -3444,7 +3401,6 @@ static const struct mt753x_info mt753x_t - .phy_write = mt7530_phy_write, - .pad_setup = mt7530_pad_clk_setup, - .mac_port_get_caps = mt7530_mac_port_get_caps, -- .mac_port_validate = mt7530_mac_port_validate, - .mac_port_get_state = mt7530_phylink_mac_link_state, - .mac_port_config = mt7530_mac_config, - }, -@@ -3455,7 +3411,6 @@ static const struct mt753x_info mt753x_t - .phy_write = mt7530_phy_write, - .pad_setup = mt7530_pad_clk_setup, - .mac_port_get_caps = mt7530_mac_port_get_caps, -- .mac_port_validate = mt7530_mac_port_validate, - .mac_port_get_state = mt7530_phylink_mac_link_state, - .mac_port_config = mt7530_mac_config, - }, -@@ -3467,7 +3422,6 @@ static const struct mt753x_info mt753x_t - .pad_setup = mt7531_pad_setup, - .cpu_port_config = mt7531_cpu_port_config, - .mac_port_get_caps = mt7531_mac_port_get_caps, -- .mac_port_validate = mt7531_mac_port_validate, - .mac_port_get_state = mt7531_phylink_mac_link_state, - .mac_port_config = mt7531_mac_config, - .mac_pcs_an_restart = mt7531_sgmii_restart_an, -@@ -3529,7 +3483,6 @@ mt7530_probe(struct mdio_device *mdiodev - if (!priv->info->sw_setup || !priv->info->pad_setup || - !priv->info->phy_read || !priv->info->phy_write || - !priv->info->mac_port_get_caps || -- !priv->info->mac_port_validate || - !priv->info->mac_port_get_state || !priv->info->mac_port_config) - return -EINVAL; - diff --git a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch b/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch deleted file mode 100644 index 149c12c1fb7697..00000000000000 --- a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch +++ /dev/null @@ -1,385 +0,0 @@ -From fd993fd59d96d5e2d5972ec4ca1f9651025c987b Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 11 Apr 2022 10:46:27 +0100 -Subject: [PATCH 07/13] net: dsa: mt7530: partially convert to phylink_pcs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Partially convert the mt7530 driver to use phylink's PCS support. This -is a partial implementation as we don't move anything into the -pcs_config method yet - this driver supports SGMII or 1000BASE-X -without in-band. - -Tested-by: Marek Behún -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 144 +++++++++++++++++++++++---------------- - drivers/net/dsa/mt7530.h | 21 +++--- - 2 files changed, 95 insertions(+), 70 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -25,6 +25,11 @@ - - #include "mt7530.h" - -+static struct mt753x_pcs *pcs_to_mt753x_pcs(struct phylink_pcs *pcs) -+{ -+ return container_of(pcs, struct mt753x_pcs, pcs); -+} -+ - /* String, offset, and register size in bytes if different from 4 bytes */ - static const struct mt7530_mib_desc mt7530_mib[] = { - MIB_DESC(1, 0x00, "TxDrop"), -@@ -2819,12 +2824,11 @@ static int mt7531_rgmii_setup(struct mt7 - return 0; - } - --static void --mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port, -- unsigned int mode, phy_interface_t interface, -- int speed, int duplex) -+static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, int speed, int duplex) - { -- struct mt7530_priv *priv = ds->priv; -+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; -+ int port = pcs_to_mt753x_pcs(pcs)->port; - unsigned int val; - - /* For adjusting speed and duplex of SGMII force mode. */ -@@ -2850,6 +2854,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw - - /* MT7531 SGMII 1G force mode can only work in full duplex mode, - * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. -+ * -+ * The speed check is unnecessary as the MAC capabilities apply -+ * this restriction. --rmk - */ - if ((speed == SPEED_10 || speed == SPEED_100) && - duplex != DUPLEX_FULL) -@@ -2925,9 +2932,10 @@ static int mt7531_sgmii_setup_mode_an(st - return 0; - } - --static void mt7531_sgmii_restart_an(struct dsa_switch *ds, int port) -+static void mt7531_pcs_an_restart(struct phylink_pcs *pcs) - { -- struct mt7530_priv *priv = ds->priv; -+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; -+ int port = pcs_to_mt753x_pcs(pcs)->port; - u32 val; - - /* Only restart AN when AN is enabled */ -@@ -2984,6 +2992,24 @@ mt753x_mac_config(struct dsa_switch *ds, - return priv->info->mac_port_config(ds, port, mode, state->interface); - } - -+static struct phylink_pcs * -+mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port, -+ phy_interface_t interface) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_TRGMII: -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ return &priv->pcs[port].pcs; -+ -+ default: -+ return NULL; -+ } -+} -+ - static void - mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - const struct phylink_link_state *state) -@@ -3045,17 +3071,6 @@ unsupported: - mt7530_write(priv, MT7530_PMCR_P(port), mcr_new); - } - --static void --mt753x_phylink_mac_an_restart(struct dsa_switch *ds, int port) --{ -- struct mt7530_priv *priv = ds->priv; -- -- if (!priv->info->mac_pcs_an_restart) -- return; -- -- priv->info->mac_pcs_an_restart(ds, port); --} -- - static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port, - unsigned int mode, - phy_interface_t interface) -@@ -3065,16 +3080,13 @@ static void mt753x_phylink_mac_link_down - mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); - } - --static void mt753x_mac_pcs_link_up(struct dsa_switch *ds, int port, -- unsigned int mode, phy_interface_t interface, -- int speed, int duplex) -+static void mt753x_phylink_pcs_link_up(struct phylink_pcs *pcs, -+ unsigned int mode, -+ phy_interface_t interface, -+ int speed, int duplex) - { -- struct mt7530_priv *priv = ds->priv; -- -- if (!priv->info->mac_pcs_link_up) -- return; -- -- priv->info->mac_pcs_link_up(ds, port, mode, interface, speed, duplex); -+ if (pcs->ops->pcs_link_up) -+ pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex); - } - - static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, -@@ -3087,8 +3099,6 @@ static void mt753x_phylink_mac_link_up(s - struct mt7530_priv *priv = ds->priv; - u32 mcr; - -- mt753x_mac_pcs_link_up(ds, port, mode, interface, speed, duplex); -- - mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK; - - /* MT753x MAC works in 1G full duplex mode for all up-clocked -@@ -3166,6 +3176,8 @@ mt7531_cpu_port_config(struct dsa_switch - return ret; - mt7530_write(priv, MT7530_PMCR_P(port), - PMCR_CPU_PORT_SETTING(priv->id)); -+ mt753x_phylink_pcs_link_up(&priv->pcs[port].pcs, MLO_AN_FIXED, -+ interface, speed, DUPLEX_FULL); - mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL, - speed, DUPLEX_FULL, true, true); - -@@ -3205,16 +3217,13 @@ mt753x_phylink_validate(struct dsa_switc - linkmode_and(state->advertising, state->advertising, mask); - } - --static int --mt7530_phylink_mac_link_state(struct dsa_switch *ds, int port, -- struct phylink_link_state *state) -+static void mt7530_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) - { -- struct mt7530_priv *priv = ds->priv; -+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; -+ int port = pcs_to_mt753x_pcs(pcs)->port; - u32 pmsr; - -- if (port < 0 || port >= MT7530_NUM_PORTS) -- return -EINVAL; -- - pmsr = mt7530_read(priv, MT7530_PMSR_P(port)); - - state->link = (pmsr & PMSR_LINK); -@@ -3241,8 +3250,6 @@ mt7530_phylink_mac_link_state(struct dsa - state->pause |= MLO_PAUSE_RX; - if (pmsr & PMSR_TX_FC) - state->pause |= MLO_PAUSE_TX; -- -- return 1; - } - - static int -@@ -3284,32 +3291,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 - return 0; - } - --static int --mt7531_phylink_mac_link_state(struct dsa_switch *ds, int port, -- struct phylink_link_state *state) -+static void mt7531_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) - { -- struct mt7530_priv *priv = ds->priv; -+ struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; -+ int port = pcs_to_mt753x_pcs(pcs)->port; - - if (state->interface == PHY_INTERFACE_MODE_SGMII) -- return mt7531_sgmii_pcs_get_state_an(priv, port, state); -- -- return -EOPNOTSUPP; -+ mt7531_sgmii_pcs_get_state_an(priv, port, state); -+ else -+ state->link = false; - } - --static int --mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port, -- struct phylink_link_state *state) -+static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) - { -- struct mt7530_priv *priv = ds->priv; -+ return 0; -+} - -- return priv->info->mac_port_get_state(ds, port, state); -+static void mt7530_pcs_an_restart(struct phylink_pcs *pcs) -+{ - } - -+static const struct phylink_pcs_ops mt7530_pcs_ops = { -+ .pcs_get_state = mt7530_pcs_get_state, -+ .pcs_config = mt753x_pcs_config, -+ .pcs_an_restart = mt7530_pcs_an_restart, -+}; -+ -+static const struct phylink_pcs_ops mt7531_pcs_ops = { -+ .pcs_get_state = mt7531_pcs_get_state, -+ .pcs_config = mt753x_pcs_config, -+ .pcs_an_restart = mt7531_pcs_an_restart, -+ .pcs_link_up = mt7531_pcs_link_up, -+}; -+ - static int - mt753x_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; - int ret = priv->info->sw_setup(ds); -+ int i; - - if (ret) - return ret; -@@ -3322,6 +3346,13 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -+ /* Initialise the PCS devices */ -+ for (i = 0; i < priv->ds->num_ports; i++) { -+ priv->pcs[i].pcs.ops = priv->info->pcs_ops; -+ priv->pcs[i].priv = priv; -+ priv->pcs[i].port = i; -+ } -+ - return ret; - } - -@@ -3384,9 +3415,8 @@ static const struct dsa_switch_ops mt753 - .port_mirror_del = mt753x_port_mirror_del, - .phylink_get_caps = mt753x_phylink_get_caps, - .phylink_validate = mt753x_phylink_validate, -- .phylink_mac_link_state = mt753x_phylink_mac_link_state, -+ .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs, - .phylink_mac_config = mt753x_phylink_mac_config, -- .phylink_mac_an_restart = mt753x_phylink_mac_an_restart, - .phylink_mac_link_down = mt753x_phylink_mac_link_down, - .phylink_mac_link_up = mt753x_phylink_mac_link_up, - .get_mac_eee = mt753x_get_mac_eee, -@@ -3396,36 +3426,34 @@ static const struct dsa_switch_ops mt753 - static const struct mt753x_info mt753x_table[] = { - [ID_MT7621] = { - .id = ID_MT7621, -+ .pcs_ops = &mt7530_pcs_ops, - .sw_setup = mt7530_setup, - .phy_read = mt7530_phy_read, - .phy_write = mt7530_phy_write, - .pad_setup = mt7530_pad_clk_setup, - .mac_port_get_caps = mt7530_mac_port_get_caps, -- .mac_port_get_state = mt7530_phylink_mac_link_state, - .mac_port_config = mt7530_mac_config, - }, - [ID_MT7530] = { - .id = ID_MT7530, -+ .pcs_ops = &mt7530_pcs_ops, - .sw_setup = mt7530_setup, - .phy_read = mt7530_phy_read, - .phy_write = mt7530_phy_write, - .pad_setup = mt7530_pad_clk_setup, - .mac_port_get_caps = mt7530_mac_port_get_caps, -- .mac_port_get_state = mt7530_phylink_mac_link_state, - .mac_port_config = mt7530_mac_config, - }, - [ID_MT7531] = { - .id = ID_MT7531, -+ .pcs_ops = &mt7531_pcs_ops, - .sw_setup = mt7531_setup, - .phy_read = mt7531_ind_phy_read, - .phy_write = mt7531_ind_phy_write, - .pad_setup = mt7531_pad_setup, - .cpu_port_config = mt7531_cpu_port_config, - .mac_port_get_caps = mt7531_mac_port_get_caps, -- .mac_port_get_state = mt7531_phylink_mac_link_state, - .mac_port_config = mt7531_mac_config, -- .mac_pcs_an_restart = mt7531_sgmii_restart_an, -- .mac_pcs_link_up = mt7531_sgmii_link_up_force, - }, - }; - -@@ -3483,7 +3511,7 @@ mt7530_probe(struct mdio_device *mdiodev - if (!priv->info->sw_setup || !priv->info->pad_setup || - !priv->info->phy_read || !priv->info->phy_write || - !priv->info->mac_port_get_caps || -- !priv->info->mac_port_get_state || !priv->info->mac_port_config) -+ !priv->info->mac_port_config) - return -EINVAL; - - priv->id = priv->info->id; ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -779,6 +779,12 @@ static const char *p5_intf_modes(unsigne - - struct mt7530_priv; - -+struct mt753x_pcs { -+ struct phylink_pcs pcs; -+ struct mt7530_priv *priv; -+ int port; -+}; -+ - /* struct mt753x_info - This is the main data structure for holding the specific - * part for each supported device - * @sw_setup: Holding the handler to a device initialization -@@ -790,18 +796,14 @@ struct mt7530_priv; - * port - * @mac_port_validate: Holding the way to set addition validate type for a - * certan MAC port -- * @mac_port_get_state: Holding the way getting the MAC/PCS state for a certain -- * MAC port - * @mac_port_config: Holding the way setting up the PHY attribute to a - * certain MAC port -- * @mac_pcs_an_restart Holding the way restarting PCS autonegotiation for a -- * certain MAC port -- * @mac_pcs_link_up: Holding the way setting up the PHY attribute to the pcs -- * of the certain MAC port - */ - struct mt753x_info { - enum mt753x_id id; - -+ const struct phylink_pcs_ops *pcs_ops; -+ - int (*sw_setup)(struct dsa_switch *ds); - int (*phy_read)(struct mt7530_priv *priv, int port, int regnum); - int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val); -@@ -812,15 +814,9 @@ struct mt753x_info { - void (*mac_port_validate)(struct dsa_switch *ds, int port, - phy_interface_t interface, - unsigned long *supported); -- int (*mac_port_get_state)(struct dsa_switch *ds, int port, -- struct phylink_link_state *state); - int (*mac_port_config)(struct dsa_switch *ds, int port, - unsigned int mode, - phy_interface_t interface); -- void (*mac_pcs_an_restart)(struct dsa_switch *ds, int port); -- void (*mac_pcs_link_up)(struct dsa_switch *ds, int port, -- unsigned int mode, phy_interface_t interface, -- int speed, int duplex); - }; - - /* struct mt7530_priv - This is the main data structure for holding the state -@@ -862,6 +858,7 @@ struct mt7530_priv { - u8 mirror_tx; - - struct mt7530_port ports[MT7530_NUM_PORTS]; -+ struct mt753x_pcs pcs[MT7530_NUM_PORTS]; - /* protect among processes for registers access*/ - struct mutex reg_mutex; - int irq; diff --git a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch b/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch deleted file mode 100644 index 6e406ace0d8e54..00000000000000 --- a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 2b0ee6768f3ac09072e5fd60b36580924e1cfa1c Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 11 Apr 2022 10:46:32 +0100 -Subject: [PATCH 08/13] net: dsa: mt7530: move autoneg handling to PCS - validation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Move the autoneg bit handling to the PCS validation, which allows us to -get rid of mt753x_phylink_validate() and rely on the default -phylink_generic_validate() implementation for the MAC side. - -Tested-by: Marek Behún -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 28 ++++++++++------------------ - 1 file changed, 10 insertions(+), 18 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3196,25 +3196,16 @@ static void mt753x_phylink_get_caps(stru - priv->info->mac_port_get_caps(ds, port, config); - } - --static void --mt753x_phylink_validate(struct dsa_switch *ds, int port, -- unsigned long *supported, -- struct phylink_link_state *state) --{ -- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -- u32 caps; -- -- caps = dsa_to_port(ds, port)->pl_config.mac_capabilities; -- -- phylink_set_port_modes(mask); -- phylink_get_linkmodes(mask, state->interface, caps); -+static int mt753x_pcs_validate(struct phylink_pcs *pcs, -+ unsigned long *supported, -+ const struct phylink_link_state *state) -+{ -+ /* Autonegotiation is not supported in TRGMII nor 802.3z modes */ -+ if (state->interface == PHY_INTERFACE_MODE_TRGMII || -+ phy_interface_mode_is_8023z(state->interface)) -+ phylink_clear(supported, Autoneg); - -- if (state->interface != PHY_INTERFACE_MODE_TRGMII && -- !phy_interface_mode_is_8023z(state->interface)) -- phylink_set(mask, Autoneg); -- -- linkmode_and(supported, supported, mask); -- linkmode_and(state->advertising, state->advertising, mask); -+ return 0; - } - - static void mt7530_pcs_get_state(struct phylink_pcs *pcs, -@@ -3316,12 +3307,14 @@ static void mt7530_pcs_an_restart(struct - } - - static const struct phylink_pcs_ops mt7530_pcs_ops = { -+ .pcs_validate = mt753x_pcs_validate, - .pcs_get_state = mt7530_pcs_get_state, - .pcs_config = mt753x_pcs_config, - .pcs_an_restart = mt7530_pcs_an_restart, - }; - - static const struct phylink_pcs_ops mt7531_pcs_ops = { -+ .pcs_validate = mt753x_pcs_validate, - .pcs_get_state = mt7531_pcs_get_state, - .pcs_config = mt753x_pcs_config, - .pcs_an_restart = mt7531_pcs_an_restart, -@@ -3414,7 +3407,6 @@ static const struct dsa_switch_ops mt753 - .port_mirror_add = mt753x_port_mirror_add, - .port_mirror_del = mt753x_port_mirror_del, - .phylink_get_caps = mt753x_phylink_get_caps, -- .phylink_validate = mt753x_phylink_validate, - .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs, - .phylink_mac_config = mt753x_phylink_mac_config, - .phylink_mac_link_down = mt753x_phylink_mac_link_down, diff --git a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch b/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch deleted file mode 100644 index afcfcaba34aa63..00000000000000 --- a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5bc26de9bfaa6bb5539c09d4435dced98f429cfc Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 11 Apr 2022 10:46:37 +0100 -Subject: [PATCH 09/13] net: dsa: mt7530: mark as non-legacy -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The mt7530 driver does not make use of the speed, duplex, pause or -advertisement in its phylink_mac_config() implementation, so it can be -marked as a non-legacy driver. - -Tested-by: Marek Behún -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3193,6 +3193,12 @@ static void mt753x_phylink_get_caps(stru - config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000FD; - -+ /* This driver does not make use of the speed, duplex, pause or the -+ * advertisement in its mac_config, so it is safe to mark this driver -+ * as non-legacy. -+ */ -+ config->legacy_pre_march2020 = false; -+ - priv->info->mac_port_get_caps(ds, port, config); - } - diff --git a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch b/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch deleted file mode 100644 index bf2938d03b21bb..00000000000000 --- a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 1f15b5e8733115cee65342bcaafeaf0368809fae Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 25 Apr 2022 22:28:02 +0100 -Subject: [PATCH 10/13] net: dsa: mt753x: fix pcs conversion regression - -Daniel Golle reports that the conversion of mt753x to phylink PCS caused -an oops as below. - -The problem is with the placement of the PCS initialisation, which -occurs after mt7531_setup() has been called. However, burited in this -function is a call to setup the CPU port, which requires the PCS -structure to be already setup. - -Fix this by changing the initialisation order. - -Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020 -Mem abort info: - ESR = 0x96000005 - EC = 0x25: DABT (current EL), IL = 32 bits - SET = 0, FnV = 0 - EA = 0, S1PTW = 0 - FSC = 0x05: level 1 translation fault -Data abort info: - ISV = 0, ISS = 0x00000005 - CM = 0, WnR = 0 -user pgtable: 4k pages, 39-bit VAs, pgdp=0000000046057000 -[0000000000000020] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 -Internal error: Oops: 96000005 [#1] SMP -Modules linked in: -CPU: 0 PID: 32 Comm: kworker/u4:1 Tainted: G S 5.18.0-rc3-next-20220422+ #0 -Hardware name: Bananapi BPI-R64 (DT) -Workqueue: events_unbound deferred_probe_work_func -pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) -pc : mt7531_cpu_port_config+0xcc/0x1b0 -lr : mt7531_cpu_port_config+0xc0/0x1b0 -sp : ffffffc008d5b980 -x29: ffffffc008d5b990 x28: ffffff80060562c8 x27: 00000000f805633b -x26: ffffff80001a8880 x25: 00000000000009c4 x24: 0000000000000016 -x23: ffffff8005eb6470 x22: 0000000000003600 x21: ffffff8006948080 -x20: 0000000000000000 x19: 0000000000000006 x18: 0000000000000000 -x17: 0000000000000001 x16: 0000000000000001 x15: 02963607fcee069e -x14: 0000000000000000 x13: 0000000000000030 x12: 0101010101010101 -x11: ffffffc037302000 x10: 0000000000000870 x9 : ffffffc008d5b800 -x8 : ffffff800028f950 x7 : 0000000000000001 x6 : 00000000662b3000 -x5 : 00000000000002f0 x4 : 0000000000000000 x3 : ffffff800028f080 -x2 : 0000000000000000 x1 : ffffff800028f080 x0 : 0000000000000000 -Call trace: - mt7531_cpu_port_config+0xcc/0x1b0 - mt753x_cpu_port_enable+0x24/0x1f0 - mt7531_setup+0x49c/0x5c0 - mt753x_setup+0x20/0x31c - dsa_register_switch+0x8bc/0x1020 - mt7530_probe+0x118/0x200 - mdio_probe+0x30/0x64 - really_probe.part.0+0x98/0x280 - __driver_probe_device+0x94/0x140 - driver_probe_device+0x40/0x114 - __device_attach_driver+0xb0/0x10c - bus_for_each_drv+0x64/0xa0 - __device_attach+0xa8/0x16c - device_initial_probe+0x10/0x20 - bus_probe_device+0x94/0x9c - deferred_probe_work_func+0x80/0xb4 - process_one_work+0x200/0x3a0 - worker_thread+0x260/0x4c0 - kthread+0xd4/0xe0 - ret_from_fork+0x10/0x20 -Code: 9409e911 937b7e60 8b0002a0 f9405800 (f9401005) ----[ end trace 0000000000000000 ]--- - -Reported-by: Daniel Golle -Tested-by: Daniel Golle -Fixes: cbd1f243bc41 ("net: dsa: mt7530: partially convert to phylink_pcs") -Signed-off-by: Russell King (Oracle) -Reviewed-by: Florian Fainelli -Link: https://lore.kernel.org/r/E1nj6FW-007WZB-5Y@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3331,9 +3331,16 @@ static int - mt753x_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; -- int ret = priv->info->sw_setup(ds); -- int i; -+ int i, ret; - -+ /* Initialise the PCS devices */ -+ for (i = 0; i < priv->ds->num_ports; i++) { -+ priv->pcs[i].pcs.ops = priv->info->pcs_ops; -+ priv->pcs[i].priv = priv; -+ priv->pcs[i].port = i; -+ } -+ -+ ret = priv->info->sw_setup(ds); - if (ret) - return ret; - -@@ -3345,13 +3352,6 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -- /* Initialise the PCS devices */ -- for (i = 0; i < priv->ds->num_ports; i++) { -- priv->pcs[i].pcs.ops = priv->info->pcs_ops; -- priv->pcs[i].priv = priv; -- priv->pcs[i].port = i; -- } -- - return ret; - } - diff --git a/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch b/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch deleted file mode 100644 index 320b5c1ef9792e..00000000000000 --- a/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch +++ /dev/null @@ -1,87 +0,0 @@ -From e26be16262e1fc1e9f1798c12762663bd9c265c6 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 10 Jun 2022 19:05:37 +0200 -Subject: [PATCH 11/13] net: dsa: mt7530: rework mt7530_hw_vlan_{add,del} - -Rework vlan_add/vlan_del functions in preparation for dynamic cpu port. - -Currently BIT(MT7530_CPU_PORT) is added to new_members, even though -mt7530_port_vlan_add() will be called on the CPU port too. - -Let DSA core decide when to call port_vlan_add for the CPU port, rather -than doing it implicitly. - -We can do autonomous forwarding in a certain VLAN, but not add br0 to that -VLAN and avoid flooding the CPU with those packets, if software knows it -doesn't need to process them. - -Suggested-by: Vladimir Oltean -Signed-off-by: Frank Wunderlich -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 30 ++++++++++++------------------ - 1 file changed, 12 insertions(+), 18 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1771,11 +1771,11 @@ static void - mt7530_hw_vlan_add(struct mt7530_priv *priv, - struct mt7530_hw_vlan_entry *entry) - { -+ struct dsa_port *dp = dsa_to_port(priv->ds, entry->port); - u8 new_members; - u32 val; - -- new_members = entry->old_members | BIT(entry->port) | -- BIT(MT7530_CPU_PORT); -+ new_members = entry->old_members | BIT(entry->port); - - /* Validate the entry with independent learning, create egress tag per - * VLAN and joining the port as one of the port members. -@@ -1786,22 +1786,20 @@ mt7530_hw_vlan_add(struct mt7530_priv *p - - /* Decide whether adding tag or not for those outgoing packets from the - * port inside the VLAN. -- */ -- val = entry->untagged ? MT7530_VLAN_EGRESS_UNTAG : -- MT7530_VLAN_EGRESS_TAG; -- mt7530_rmw(priv, MT7530_VAWD2, -- ETAG_CTRL_P_MASK(entry->port), -- ETAG_CTRL_P(entry->port, val)); -- -- /* CPU port is always taken as a tagged port for serving more than one -+ * CPU port is always taken as a tagged port for serving more than one - * VLANs across and also being applied with egress type stack mode for - * that VLAN tags would be appended after hardware special tag used as - * DSA tag. - */ -+ if (dsa_port_is_cpu(dp)) -+ val = MT7530_VLAN_EGRESS_STACK; -+ else if (entry->untagged) -+ val = MT7530_VLAN_EGRESS_UNTAG; -+ else -+ val = MT7530_VLAN_EGRESS_TAG; - mt7530_rmw(priv, MT7530_VAWD2, -- ETAG_CTRL_P_MASK(MT7530_CPU_PORT), -- ETAG_CTRL_P(MT7530_CPU_PORT, -- MT7530_VLAN_EGRESS_STACK)); -+ ETAG_CTRL_P_MASK(entry->port), -+ ETAG_CTRL_P(entry->port, val)); - } - - static void -@@ -1820,11 +1818,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *p - return; - } - -- /* If certain member apart from CPU port is still alive in the VLAN, -- * the entry would be kept valid. Otherwise, the entry is got to be -- * disabled. -- */ -- if (new_members && new_members != BIT(MT7530_CPU_PORT)) { -+ if (new_members) { - val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) | - VLAN_VALID; - mt7530_write(priv, MT7530_VAWD1, val); diff --git a/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch b/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch deleted file mode 100644 index eef19b4cb53330..00000000000000 --- a/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch +++ /dev/null @@ -1,117 +0,0 @@ -From ad2606f6fafae3a7d41c4f2af5554c8f6adecbc7 Mon Sep 17 00:00:00 2001 -From: Frank Wunderlich -Date: Fri, 10 Jun 2022 19:05:39 +0200 -Subject: [PATCH 13/13] net: dsa: mt7530: get cpu-port via dp->cpu_dp instead - of constant - -Replace last occurences of hardcoded cpu-port by cpu_dp member of -dsa_port struct. - -Now the constant can be dropped. - -Suggested-by: Vladimir Oltean -Signed-off-by: Frank Wunderlich -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 27 ++++++++++++++++++++------- - drivers/net/dsa/mt7530.h | 1 - - 2 files changed, 20 insertions(+), 8 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1275,6 +1275,7 @@ static int - mt7530_port_enable(struct dsa_switch *ds, int port, - struct phy_device *phy) - { -+ struct dsa_port *dp = dsa_to_port(ds, port); - struct mt7530_priv *priv = ds->priv; - - mutex_lock(&priv->reg_mutex); -@@ -1283,7 +1284,11 @@ mt7530_port_enable(struct dsa_switch *ds - * restore the port matrix if the port is the member of a certain - * bridge. - */ -- priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT)); -+ if (dsa_port_is_user(dp)) { -+ struct dsa_port *cpu_dp = dp->cpu_dp; -+ -+ priv->ports[port].pm |= PCR_MATRIX(BIT(cpu_dp->index)); -+ } - priv->ports[port].enable = true; - mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, - priv->ports[port].pm); -@@ -1431,7 +1436,8 @@ mt7530_port_bridge_join(struct dsa_switc - struct net_device *bridge) - { - struct dsa_port *dp = dsa_to_port(ds, port), *other_dp; -- u32 port_bitmap = BIT(MT7530_CPU_PORT); -+ struct dsa_port *cpu_dp = dp->cpu_dp; -+ u32 port_bitmap = BIT(cpu_dp->index); - struct mt7530_priv *priv = ds->priv; - - mutex_lock(&priv->reg_mutex); -@@ -1508,9 +1514,12 @@ mt7530_port_set_vlan_unaware(struct dsa_ - * the CPU port get out of VLAN filtering mode. - */ - if (all_user_ports_removed) { -- mt7530_write(priv, MT7530_PCR_P(MT7530_CPU_PORT), -+ struct dsa_port *dp = dsa_to_port(ds, port); -+ struct dsa_port *cpu_dp = dp->cpu_dp; -+ -+ mt7530_write(priv, MT7530_PCR_P(cpu_dp->index), - PCR_MATRIX(dsa_user_ports(priv->ds))); -- mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT), PORT_SPEC_TAG -+ mt7530_write(priv, MT7530_PVC_P(cpu_dp->index), PORT_SPEC_TAG - | PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); - } - } -@@ -1560,6 +1569,7 @@ mt7530_port_bridge_leave(struct dsa_swit - struct net_device *bridge) - { - struct dsa_port *dp = dsa_to_port(ds, port), *other_dp; -+ struct dsa_port *cpu_dp = dp->cpu_dp; - struct mt7530_priv *priv = ds->priv; - - mutex_lock(&priv->reg_mutex); -@@ -1588,8 +1598,8 @@ mt7530_port_bridge_leave(struct dsa_swit - */ - if (priv->ports[port].enable) - mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, -- PCR_MATRIX(BIT(MT7530_CPU_PORT))); -- priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT)); -+ PCR_MATRIX(BIT(cpu_dp->index))); -+ priv->ports[port].pm = PCR_MATRIX(BIT(cpu_dp->index)); - - /* When a port is removed from the bridge, the port would be set up - * back to the default as is at initial boot which is a VLAN-unaware -@@ -1752,6 +1762,9 @@ static int - mt7530_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, - struct netlink_ext_ack *extack) - { -+ struct dsa_port *dp = dsa_to_port(ds, port); -+ struct dsa_port *cpu_dp = dp->cpu_dp; -+ - if (vlan_filtering) { - /* The port is being kept as VLAN-unaware port when bridge is - * set up with vlan_filtering not being set, Otherwise, the -@@ -1759,7 +1772,7 @@ mt7530_port_vlan_filtering(struct dsa_sw - * for becoming a VLAN-aware port. - */ - mt7530_port_set_vlan_aware(ds, port); -- mt7530_port_set_vlan_aware(ds, MT7530_CPU_PORT); -+ mt7530_port_set_vlan_aware(ds, cpu_dp->index); - } else { - mt7530_port_set_vlan_unaware(ds, port); - } ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -8,7 +8,6 @@ - - #define MT7530_NUM_PORTS 7 - #define MT7530_NUM_PHYS 5 --#define MT7530_CPU_PORT 6 - #define MT7530_NUM_FDB_RECORDS 2048 - #define MT7530_ALL_MEMBERS 0xff - diff --git a/target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch b/target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch deleted file mode 100644 index f022f7bf540f57..00000000000000 --- a/target/linux/generic/backport-5.15/706-00-v6.0-net-ethernet-mtk_eth_soc-rely-on-page_pool-for-singl.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 23233e577ef973c2c5d0dd757a0a4605e34ecb57 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 22 Jul 2022 09:19:36 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on page_pool for single page - buffers - -Rely on page_pool allocator for single page buffers in order to keep -them dma mapped and add skb recycling support. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/Kconfig | 1 + - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 185 +++++++++++++++----- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 ++ - 3 files changed, 156 insertions(+), 40 deletions(-) - ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -16,6 +16,7 @@ config NET_MEDIATEK_SOC - depends on NET_DSA || !NET_DSA - select PHYLINK - select DIMLIB -+ select PAGE_POOL - help - This driver supports the gigabit ethernet MACs in the - MediaTek SoC family. ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1388,6 +1388,68 @@ static void mtk_update_rx_cpu_idx(struct - } - } - -+static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, -+ struct xdp_rxq_info *xdp_q, -+ int id, int size) -+{ -+ struct page_pool_params pp_params = { -+ .order = 0, -+ .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, -+ .pool_size = size, -+ .nid = NUMA_NO_NODE, -+ .dev = eth->dma_dev, -+ .dma_dir = DMA_FROM_DEVICE, -+ .offset = MTK_PP_HEADROOM, -+ .max_len = MTK_PP_MAX_BUF_SIZE, -+ }; -+ struct page_pool *pp; -+ int err; -+ -+ pp = page_pool_create(&pp_params); -+ if (IS_ERR(pp)) -+ return pp; -+ -+ err = xdp_rxq_info_reg(xdp_q, ð->dummy_dev, id, -+ eth->rx_napi.napi_id); -+ if (err < 0) -+ goto err_free_pp; -+ -+ err = xdp_rxq_info_reg_mem_model(xdp_q, MEM_TYPE_PAGE_POOL, pp); -+ if (err) -+ goto err_unregister_rxq; -+ -+ return pp; -+ -+err_unregister_rxq: -+ xdp_rxq_info_unreg(xdp_q); -+err_free_pp: -+ page_pool_destroy(pp); -+ -+ return ERR_PTR(err); -+} -+ -+static void *mtk_page_pool_get_buff(struct page_pool *pp, dma_addr_t *dma_addr, -+ gfp_t gfp_mask) -+{ -+ struct page *page; -+ -+ page = page_pool_alloc_pages(pp, gfp_mask | __GFP_NOWARN); -+ if (!page) -+ return NULL; -+ -+ *dma_addr = page_pool_get_dma_addr(page) + MTK_PP_HEADROOM; -+ return page_address(page); -+} -+ -+static void mtk_rx_put_buff(struct mtk_rx_ring *ring, void *data, bool napi) -+{ -+ if (ring->page_pool) -+ page_pool_put_full_page(ring->page_pool, -+ virt_to_head_page(data), napi); -+ else -+ skb_free_frag(data); -+} -+ - static int mtk_poll_rx(struct napi_struct *napi, int budget, - struct mtk_eth *eth) - { -@@ -1401,9 +1463,9 @@ static int mtk_poll_rx(struct napi_struc - - while (done < budget) { - unsigned int pktlen, *rxdcsum; -+ u32 hash, reason, reserve_len; - struct net_device *netdev; - dma_addr_t dma_addr; -- u32 hash, reason; - int mac = 0; - - ring = mtk_get_rx_ring(eth); -@@ -1434,36 +1496,54 @@ static int mtk_poll_rx(struct napi_struc - goto release_desc; - - /* alloc new buffer */ -- if (ring->frag_size <= PAGE_SIZE) -- new_data = napi_alloc_frag(ring->frag_size); -- else -- new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC); -- if (unlikely(!new_data)) { -- netdev->stats.rx_dropped++; -- goto release_desc; -- } -- dma_addr = dma_map_single(eth->dma_dev, -- new_data + NET_SKB_PAD + -- eth->ip_align, -- ring->buf_size, -- DMA_FROM_DEVICE); -- if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) { -- skb_free_frag(new_data); -- netdev->stats.rx_dropped++; -- goto release_desc; -- } -+ if (ring->page_pool) { -+ new_data = mtk_page_pool_get_buff(ring->page_pool, -+ &dma_addr, -+ GFP_ATOMIC); -+ if (unlikely(!new_data)) { -+ netdev->stats.rx_dropped++; -+ goto release_desc; -+ } -+ } else { -+ if (ring->frag_size <= PAGE_SIZE) -+ new_data = napi_alloc_frag(ring->frag_size); -+ else -+ new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC); -+ -+ if (unlikely(!new_data)) { -+ netdev->stats.rx_dropped++; -+ goto release_desc; -+ } - -- dma_unmap_single(eth->dma_dev, trxd.rxd1, -- ring->buf_size, DMA_FROM_DEVICE); -+ dma_addr = dma_map_single(eth->dma_dev, -+ new_data + NET_SKB_PAD + eth->ip_align, -+ ring->buf_size, DMA_FROM_DEVICE); -+ if (unlikely(dma_mapping_error(eth->dma_dev, -+ dma_addr))) { -+ skb_free_frag(new_data); -+ netdev->stats.rx_dropped++; -+ goto release_desc; -+ } -+ -+ dma_unmap_single(eth->dma_dev, trxd.rxd1, -+ ring->buf_size, DMA_FROM_DEVICE); -+ } - - /* receive data */ - skb = build_skb(data, ring->frag_size); - if (unlikely(!skb)) { -- skb_free_frag(data); -+ mtk_rx_put_buff(ring, data, true); - netdev->stats.rx_dropped++; - goto skip_rx; - } -- skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); -+ -+ if (ring->page_pool) { -+ reserve_len = MTK_PP_HEADROOM; -+ skb_mark_for_recycle(skb); -+ } else { -+ reserve_len = NET_SKB_PAD + NET_IP_ALIGN; -+ } -+ skb_reserve(skb, reserve_len); - - pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); - skb->dev = netdev; -@@ -1517,7 +1597,6 @@ static int mtk_poll_rx(struct napi_struc - skip_rx: - ring->data[idx] = new_data; - rxd->rxd1 = (unsigned int)dma_addr; -- - release_desc: - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - rxd->rxd2 = RX_DMA_LSO; -@@ -1525,7 +1604,6 @@ release_desc: - rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); - - ring->calc_idx = idx; -- - done++; - } - -@@ -1889,13 +1967,15 @@ static int mtk_rx_alloc(struct mtk_eth * - if (!ring->data) - return -ENOMEM; - -- for (i = 0; i < rx_dma_size; i++) { -- if (ring->frag_size <= PAGE_SIZE) -- ring->data[i] = netdev_alloc_frag(ring->frag_size); -- else -- ring->data[i] = mtk_max_lro_buf_alloc(GFP_KERNEL); -- if (!ring->data[i]) -- return -ENOMEM; -+ if (!eth->hwlro) { -+ struct page_pool *pp; -+ -+ pp = mtk_create_page_pool(eth, &ring->xdp_q, ring_no, -+ rx_dma_size); -+ if (IS_ERR(pp)) -+ return PTR_ERR(pp); -+ -+ ring->page_pool = pp; - } - - ring->dma = dma_alloc_coherent(eth->dma_dev, -@@ -1906,16 +1986,33 @@ static int mtk_rx_alloc(struct mtk_eth * - - for (i = 0; i < rx_dma_size; i++) { - struct mtk_rx_dma_v2 *rxd; -- -- dma_addr_t dma_addr = dma_map_single(eth->dma_dev, -- ring->data[i] + NET_SKB_PAD + eth->ip_align, -- ring->buf_size, -- DMA_FROM_DEVICE); -- if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) -- return -ENOMEM; -+ dma_addr_t dma_addr; -+ void *data; - - rxd = ring->dma + i * eth->soc->txrx.rxd_size; -+ if (ring->page_pool) { -+ data = mtk_page_pool_get_buff(ring->page_pool, -+ &dma_addr, GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ } else { -+ if (ring->frag_size <= PAGE_SIZE) -+ data = netdev_alloc_frag(ring->frag_size); -+ else -+ data = mtk_max_lro_buf_alloc(GFP_KERNEL); -+ -+ if (!data) -+ return -ENOMEM; -+ -+ dma_addr = dma_map_single(eth->dma_dev, -+ data + NET_SKB_PAD + eth->ip_align, -+ ring->buf_size, DMA_FROM_DEVICE); -+ if (unlikely(dma_mapping_error(eth->dma_dev, -+ dma_addr))) -+ return -ENOMEM; -+ } - rxd->rxd1 = (unsigned int)dma_addr; -+ ring->data[i] = data; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - rxd->rxd2 = RX_DMA_LSO; -@@ -1931,6 +2028,7 @@ static int mtk_rx_alloc(struct mtk_eth * - rxd->rxd8 = 0; - } - } -+ - ring->dma_size = rx_dma_size; - ring->calc_idx_update = false; - ring->calc_idx = rx_dma_size - 1; -@@ -1982,7 +2080,7 @@ static void mtk_rx_clean(struct mtk_eth - - dma_unmap_single(eth->dma_dev, rxd->rxd1, - ring->buf_size, DMA_FROM_DEVICE); -- skb_free_frag(ring->data[i]); -+ mtk_rx_put_buff(ring, ring->data[i], false); - } - kfree(ring->data); - ring->data = NULL; -@@ -1994,6 +2092,13 @@ static void mtk_rx_clean(struct mtk_eth - ring->dma, ring->phys); - ring->dma = NULL; - } -+ -+ if (ring->page_pool) { -+ if (xdp_rxq_info_is_reg(&ring->xdp_q)) -+ xdp_rxq_info_unreg(&ring->xdp_q); -+ page_pool_destroy(ring->page_pool); -+ ring->page_pool = NULL; -+ } - } - - static int mtk_hwlro_rx_init(struct mtk_eth *eth) ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -18,6 +18,8 @@ - #include - #include - #include -+#include -+#include - #include "mtk_ppe.h" - - #define MTK_QDMA_PAGE_SIZE 2048 -@@ -49,6 +51,11 @@ - #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM) - #define NEXT_DESP_IDX(X, Y) (((X) + 1) & ((Y) - 1)) - -+#define MTK_PP_HEADROOM XDP_PACKET_HEADROOM -+#define MTK_PP_PAD (MTK_PP_HEADROOM + \ -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) -+#define MTK_PP_MAX_BUF_SIZE (PAGE_SIZE - MTK_PP_PAD) -+ - #define MTK_QRX_OFFSET 0x10 - - #define MTK_MAX_RX_RING_NUM 4 -@@ -743,6 +750,9 @@ struct mtk_rx_ring { - bool calc_idx_update; - u16 calc_idx; - u32 crx_idx_reg; -+ /* page_pool */ -+ struct page_pool *page_pool; -+ struct xdp_rxq_info xdp_q; - }; - - enum mkt_eth_capabilities { diff --git a/target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch b/target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch deleted file mode 100644 index 94efa929860025..00000000000000 --- a/target/linux/generic/backport-5.15/706-01-v6.0-net-ethernet-mtk_eth_soc-add-basic-XDP-support.patch +++ /dev/null @@ -1,291 +0,0 @@ -From 7c26c20da5d420cde55618263be4aa2f6de53056 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 22 Jul 2022 09:19:37 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add basic XDP support - -Introduce basic XDP support to mtk_eth_soc driver. -Supported XDP verdicts: -- XDP_PASS -- XDP_DROP -- XDP_REDIRECT - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 162 +++++++++++++++++--- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 + - 2 files changed, 145 insertions(+), 19 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1388,6 +1388,11 @@ static void mtk_update_rx_cpu_idx(struct - } - } - -+static bool mtk_page_pool_enabled(struct mtk_eth *eth) -+{ -+ return !eth->hwlro; -+} -+ - static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, - struct xdp_rxq_info *xdp_q, - int id, int size) -@@ -1450,11 +1455,52 @@ static void mtk_rx_put_buff(struct mtk_r - skb_free_frag(data); - } - -+static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring, -+ struct xdp_buff *xdp, struct net_device *dev) -+{ -+ struct bpf_prog *prog; -+ u32 act = XDP_PASS; -+ -+ rcu_read_lock(); -+ -+ prog = rcu_dereference(eth->prog); -+ if (!prog) -+ goto out; -+ -+ act = bpf_prog_run_xdp(prog, xdp); -+ switch (act) { -+ case XDP_PASS: -+ goto out; -+ case XDP_REDIRECT: -+ if (unlikely(xdp_do_redirect(dev, xdp, prog))) { -+ act = XDP_DROP; -+ break; -+ } -+ goto out; -+ default: -+ bpf_warn_invalid_xdp_action(act); -+ fallthrough; -+ case XDP_ABORTED: -+ trace_xdp_exception(dev, prog, act); -+ fallthrough; -+ case XDP_DROP: -+ break; -+ } -+ -+ page_pool_put_full_page(ring->page_pool, -+ virt_to_head_page(xdp->data), true); -+out: -+ rcu_read_unlock(); -+ -+ return act; -+} -+ - static int mtk_poll_rx(struct napi_struct *napi, int budget, - struct mtk_eth *eth) - { - struct dim_sample dim_sample = {}; - struct mtk_rx_ring *ring; -+ bool xdp_flush = false; - int idx; - struct sk_buff *skb; - u8 *data, *new_data; -@@ -1463,9 +1509,9 @@ static int mtk_poll_rx(struct napi_struc - - while (done < budget) { - unsigned int pktlen, *rxdcsum; -- u32 hash, reason, reserve_len; - struct net_device *netdev; - dma_addr_t dma_addr; -+ u32 hash, reason; - int mac = 0; - - ring = mtk_get_rx_ring(eth); -@@ -1495,8 +1541,14 @@ static int mtk_poll_rx(struct napi_struc - if (unlikely(test_bit(MTK_RESETTING, ð->state))) - goto release_desc; - -+ pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); -+ - /* alloc new buffer */ - if (ring->page_pool) { -+ struct page *page = virt_to_head_page(data); -+ struct xdp_buff xdp; -+ u32 ret; -+ - new_data = mtk_page_pool_get_buff(ring->page_pool, - &dma_addr, - GFP_ATOMIC); -@@ -1504,6 +1556,34 @@ static int mtk_poll_rx(struct napi_struc - netdev->stats.rx_dropped++; - goto release_desc; - } -+ -+ dma_sync_single_for_cpu(eth->dma_dev, -+ page_pool_get_dma_addr(page) + MTK_PP_HEADROOM, -+ pktlen, page_pool_get_dma_dir(ring->page_pool)); -+ -+ xdp_init_buff(&xdp, PAGE_SIZE, &ring->xdp_q); -+ xdp_prepare_buff(&xdp, data, MTK_PP_HEADROOM, pktlen, -+ false); -+ xdp_buff_clear_frags_flag(&xdp); -+ -+ ret = mtk_xdp_run(eth, ring, &xdp, netdev); -+ if (ret == XDP_REDIRECT) -+ xdp_flush = true; -+ -+ if (ret != XDP_PASS) -+ goto skip_rx; -+ -+ skb = build_skb(data, PAGE_SIZE); -+ if (unlikely(!skb)) { -+ page_pool_put_full_page(ring->page_pool, -+ page, true); -+ netdev->stats.rx_dropped++; -+ goto skip_rx; -+ } -+ -+ skb_reserve(skb, xdp.data - xdp.data_hard_start); -+ skb_put(skb, xdp.data_end - xdp.data); -+ skb_mark_for_recycle(skb); - } else { - if (ring->frag_size <= PAGE_SIZE) - new_data = napi_alloc_frag(ring->frag_size); -@@ -1527,27 +1607,20 @@ static int mtk_poll_rx(struct napi_struc - - dma_unmap_single(eth->dma_dev, trxd.rxd1, - ring->buf_size, DMA_FROM_DEVICE); -- } - -- /* receive data */ -- skb = build_skb(data, ring->frag_size); -- if (unlikely(!skb)) { -- mtk_rx_put_buff(ring, data, true); -- netdev->stats.rx_dropped++; -- goto skip_rx; -- } -+ skb = build_skb(data, ring->frag_size); -+ if (unlikely(!skb)) { -+ netdev->stats.rx_dropped++; -+ skb_free_frag(data); -+ goto skip_rx; -+ } - -- if (ring->page_pool) { -- reserve_len = MTK_PP_HEADROOM; -- skb_mark_for_recycle(skb); -- } else { -- reserve_len = NET_SKB_PAD + NET_IP_ALIGN; -+ skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); -+ skb_put(skb, pktlen); - } -- skb_reserve(skb, reserve_len); - -- pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); - skb->dev = netdev; -- skb_put(skb, pktlen); -+ bytes += skb->len; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) - rxdcsum = &trxd.rxd3; -@@ -1559,7 +1632,6 @@ static int mtk_poll_rx(struct napi_struc - else - skb_checksum_none_assert(skb); - skb->protocol = eth_type_trans(skb, netdev); -- bytes += pktlen; - - hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; - if (hash != MTK_RXD4_FOE_ENTRY) { -@@ -1622,6 +1694,9 @@ rx_done: - &dim_sample); - net_dim(ð->rx_dim, dim_sample); - -+ if (xdp_flush) -+ xdp_do_flush_map(); -+ - return done; - } - -@@ -1967,7 +2042,7 @@ static int mtk_rx_alloc(struct mtk_eth * - if (!ring->data) - return -ENOMEM; - -- if (!eth->hwlro) { -+ if (mtk_page_pool_enabled(eth)) { - struct page_pool *pp; - - pp = mtk_create_page_pool(eth, &ring->xdp_q, ring_no, -@@ -2712,6 +2787,48 @@ static int mtk_stop(struct net_device *d - return 0; - } - -+static int mtk_xdp_setup(struct net_device *dev, struct bpf_prog *prog, -+ struct netlink_ext_ack *extack) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ struct bpf_prog *old_prog; -+ bool need_update; -+ -+ if (eth->hwlro) { -+ NL_SET_ERR_MSG_MOD(extack, "XDP not supported with HWLRO"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (dev->mtu > MTK_PP_MAX_BUF_SIZE) { -+ NL_SET_ERR_MSG_MOD(extack, "MTU too large for XDP"); -+ return -EOPNOTSUPP; -+ } -+ -+ need_update = !!eth->prog != !!prog; -+ if (netif_running(dev) && need_update) -+ mtk_stop(dev); -+ -+ old_prog = rcu_replace_pointer(eth->prog, prog, lockdep_rtnl_is_held()); -+ if (old_prog) -+ bpf_prog_put(old_prog); -+ -+ if (netif_running(dev) && need_update) -+ return mtk_open(dev); -+ -+ return 0; -+} -+ -+static int mtk_xdp(struct net_device *dev, struct netdev_bpf *xdp) -+{ -+ switch (xdp->command) { -+ case XDP_SETUP_PROG: -+ return mtk_xdp_setup(dev, xdp->prog, xdp->extack); -+ default: -+ return -EINVAL; -+ } -+} -+ - static void ethsys_reset(struct mtk_eth *eth, u32 reset_bits) - { - regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, -@@ -2990,6 +3107,12 @@ static int mtk_change_mtu(struct net_dev - struct mtk_eth *eth = mac->hw; - u32 mcr_cur, mcr_new; - -+ if (rcu_access_pointer(eth->prog) && -+ length > MTK_PP_MAX_BUF_SIZE) { -+ netdev_err(dev, "Invalid MTU for XDP mode\n"); -+ return -EINVAL; -+ } -+ - if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { - mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK; -@@ -3316,6 +3439,7 @@ static const struct net_device_ops mtk_n - .ndo_poll_controller = mtk_poll_controller, - #endif - .ndo_setup_tc = mtk_eth_setup_tc, -+ .ndo_bpf = mtk_xdp, - }; - - static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1086,6 +1086,8 @@ struct mtk_eth { - - struct mtk_ppe *ppe; - struct rhashtable flow_table; -+ -+ struct bpf_prog __rcu *prog; - }; - - /* struct mtk_mac - the structure that holds the info about the MACs of the diff --git a/target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch b/target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch deleted file mode 100644 index 7bb4222fef5413..00000000000000 --- a/target/linux/generic/backport-5.15/706-02-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-ethtool-count.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 916a6ee836d6b7b8ef1ed5f0515e256ca60e9968 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 22 Jul 2022 09:19:38 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce xdp ethtool counters - -Report xdp stats through ethtool - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 26 +++++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++++++++++ - 2 files changed, 36 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -34,6 +34,10 @@ MODULE_PARM_DESC(msg_level, "Message lev - #define MTK_ETHTOOL_STAT(x) { #x, \ - offsetof(struct mtk_hw_stats, x) / sizeof(u64) } - -+#define MTK_ETHTOOL_XDP_STAT(x) { #x, \ -+ offsetof(struct mtk_hw_stats, xdp_stats.x) / \ -+ sizeof(u64) } -+ - static const struct mtk_reg_map mtk_reg_map = { - .tx_irq_mask = 0x1a1c, - .tx_irq_status = 0x1a18, -@@ -141,6 +145,13 @@ static const struct mtk_ethtool_stats { - MTK_ETHTOOL_STAT(rx_long_errors), - MTK_ETHTOOL_STAT(rx_checksum_errors), - MTK_ETHTOOL_STAT(rx_flow_control_packets), -+ MTK_ETHTOOL_XDP_STAT(rx_xdp_redirect), -+ MTK_ETHTOOL_XDP_STAT(rx_xdp_pass), -+ MTK_ETHTOOL_XDP_STAT(rx_xdp_drop), -+ MTK_ETHTOOL_XDP_STAT(rx_xdp_tx), -+ MTK_ETHTOOL_XDP_STAT(rx_xdp_tx_errors), -+ MTK_ETHTOOL_XDP_STAT(tx_xdp_xmit), -+ MTK_ETHTOOL_XDP_STAT(tx_xdp_xmit_errors), - }; - - static const char * const mtk_clks_source_name[] = { -@@ -1458,6 +1469,9 @@ static void mtk_rx_put_buff(struct mtk_r - static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring, - struct xdp_buff *xdp, struct net_device *dev) - { -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_hw_stats *hw_stats = mac->hw_stats; -+ u64 *count = &hw_stats->xdp_stats.rx_xdp_drop; - struct bpf_prog *prog; - u32 act = XDP_PASS; - -@@ -1470,13 +1484,16 @@ static u32 mtk_xdp_run(struct mtk_eth *e - act = bpf_prog_run_xdp(prog, xdp); - switch (act) { - case XDP_PASS: -- goto out; -+ count = &hw_stats->xdp_stats.rx_xdp_pass; -+ goto update_stats; - case XDP_REDIRECT: - if (unlikely(xdp_do_redirect(dev, xdp, prog))) { - act = XDP_DROP; - break; - } -- goto out; -+ -+ count = &hw_stats->xdp_stats.rx_xdp_redirect; -+ goto update_stats; - default: - bpf_warn_invalid_xdp_action(act); - fallthrough; -@@ -1489,6 +1506,11 @@ static u32 mtk_xdp_run(struct mtk_eth *e - - page_pool_put_full_page(ring->page_pool, - virt_to_head_page(xdp->data), true); -+ -+update_stats: -+ u64_stats_update_begin(&hw_stats->syncp); -+ *count = *count + 1; -+ u64_stats_update_end(&hw_stats->syncp); - out: - rcu_read_unlock(); - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -568,6 +568,16 @@ struct mtk_tx_dma_v2 { - struct mtk_eth; - struct mtk_mac; - -+struct mtk_xdp_stats { -+ u64 rx_xdp_redirect; -+ u64 rx_xdp_pass; -+ u64 rx_xdp_drop; -+ u64 rx_xdp_tx; -+ u64 rx_xdp_tx_errors; -+ u64 tx_xdp_xmit; -+ u64 tx_xdp_xmit_errors; -+}; -+ - /* struct mtk_hw_stats - the structure that holds the traffic statistics. - * @stats_lock: make sure that stats operations are atomic - * @reg_offset: the status register offset of the SoC -@@ -591,6 +601,8 @@ struct mtk_hw_stats { - u64 rx_checksum_errors; - u64 rx_flow_control_packets; - -+ struct mtk_xdp_stats xdp_stats; -+ - spinlock_t stats_lock; - u32 reg_offset; - struct u64_stats_sync syncp; diff --git a/target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch b/target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch deleted file mode 100644 index deb06d489265b4..00000000000000 --- a/target/linux/generic/backport-5.15/706-03-v6.0-net-ethernet-mtk_eth_soc-add-xmit-XDP-support.patch +++ /dev/null @@ -1,340 +0,0 @@ -From 5886d26fd25bbe26130e3e5f7474b9b3e98a3469 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 22 Jul 2022 09:19:39 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add xmit XDP support - -Introduce XDP support for XDP_TX verdict and ndo_xdp_xmit function -pointer. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 192 +++++++++++++++++--- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 +- - 2 files changed, 180 insertions(+), 22 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -987,15 +987,26 @@ static void mtk_tx_unmap(struct mtk_eth - } - } - -- tx_buf->flags = 0; -- if (tx_buf->skb && -- (tx_buf->skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC)) { -- if (napi) -- napi_consume_skb(tx_buf->skb, napi); -+ if (tx_buf->type == MTK_TYPE_SKB) { -+ if (tx_buf->data && -+ tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -+ struct sk_buff *skb = tx_buf->data; -+ -+ if (napi) -+ napi_consume_skb(skb, napi); -+ else -+ dev_kfree_skb_any(skb); -+ } -+ } else if (tx_buf->data) { -+ struct xdp_frame *xdpf = tx_buf->data; -+ -+ if (napi && tx_buf->type == MTK_TYPE_XDP_TX) -+ xdp_return_frame_rx_napi(xdpf); - else -- dev_kfree_skb_any(tx_buf->skb); -+ xdp_return_frame(xdpf); - } -- tx_buf->skb = NULL; -+ tx_buf->flags = 0; -+ tx_buf->data = NULL; - } - - static void setup_tx_buf(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, -@@ -1012,7 +1023,7 @@ static void setup_tx_buf(struct mtk_eth - dma_unmap_addr_set(tx_buf, dma_addr1, mapped_addr); - dma_unmap_len_set(tx_buf, dma_len1, size); - } else { -- tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC; -+ tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; - txd->txd1 = mapped_addr; - txd->txd2 = TX_DMA_PLEN0(size); - dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr); -@@ -1188,7 +1199,7 @@ static int mtk_tx_map(struct sk_buff *sk - soc->txrx.txd_size); - if (new_desc) - memset(tx_buf, 0, sizeof(*tx_buf)); -- tx_buf->skb = (struct sk_buff *)MTK_DMA_DUMMY_DESC; -+ tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; - tx_buf->flags |= MTK_TX_FLAGS_PAGE0; - tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : - MTK_TX_FLAGS_FPORT1; -@@ -1202,7 +1213,8 @@ static int mtk_tx_map(struct sk_buff *sk - } - - /* store skb to cleanup */ -- itx_buf->skb = skb; -+ itx_buf->type = MTK_TYPE_SKB; -+ itx_buf->data = skb; - - if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { - if (k & 0x1) -@@ -1414,13 +1426,14 @@ static struct page_pool *mtk_create_page - .pool_size = size, - .nid = NUMA_NO_NODE, - .dev = eth->dma_dev, -- .dma_dir = DMA_FROM_DEVICE, - .offset = MTK_PP_HEADROOM, - .max_len = MTK_PP_MAX_BUF_SIZE, - }; - struct page_pool *pp; - int err; - -+ pp_params.dma_dir = rcu_access_pointer(eth->prog) ? DMA_BIDIRECTIONAL -+ : DMA_FROM_DEVICE; - pp = page_pool_create(&pp_params); - if (IS_ERR(pp)) - return pp; -@@ -1466,6 +1479,122 @@ static void mtk_rx_put_buff(struct mtk_r - skb_free_frag(data); - } - -+static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, -+ struct net_device *dev, bool dma_map) -+{ -+ const struct mtk_soc_data *soc = eth->soc; -+ struct mtk_tx_ring *ring = ð->tx_ring; -+ struct mtk_tx_dma_desc_info txd_info = { -+ .size = xdpf->len, -+ .first = true, -+ .last = true, -+ }; -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_tx_dma *txd, *txd_pdma; -+ int err = 0, index = 0, n_desc = 1; -+ struct mtk_tx_buf *tx_buf; -+ -+ if (unlikely(test_bit(MTK_RESETTING, ð->state))) -+ return -EBUSY; -+ -+ if (unlikely(atomic_read(&ring->free_count) <= 1)) -+ return -EBUSY; -+ -+ spin_lock(ð->page_lock); -+ -+ txd = ring->next_free; -+ if (txd == ring->last_free) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size); -+ memset(tx_buf, 0, sizeof(*tx_buf)); -+ -+ if (dma_map) { /* ndo_xdp_xmit */ -+ txd_info.addr = dma_map_single(eth->dma_dev, xdpf->data, -+ txd_info.size, DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) { -+ err = -ENOMEM; -+ goto out; -+ } -+ tx_buf->flags |= MTK_TX_FLAGS_SINGLE0; -+ } else { -+ struct page *page = virt_to_head_page(xdpf->data); -+ -+ txd_info.addr = page_pool_get_dma_addr(page) + -+ sizeof(*xdpf) + xdpf->headroom; -+ dma_sync_single_for_device(eth->dma_dev, txd_info.addr, -+ txd_info.size, -+ DMA_BIDIRECTIONAL); -+ } -+ mtk_tx_set_dma_desc(dev, txd, &txd_info); -+ -+ tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; -+ -+ txd_pdma = qdma_to_pdma(ring, txd); -+ setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, txd_info.size, -+ index++); -+ -+ /* store xdpf for cleanup */ -+ tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; -+ tx_buf->data = xdpf; -+ -+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { -+ if (index & 1) -+ txd_pdma->txd2 |= TX_DMA_LS0; -+ else -+ txd_pdma->txd2 |= TX_DMA_LS1; -+ } -+ -+ ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); -+ atomic_sub(n_desc, &ring->free_count); -+ -+ /* make sure that all changes to the dma ring are flushed before we -+ * continue -+ */ -+ wmb(); -+ -+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { -+ mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr); -+ } else { -+ int idx; -+ -+ idx = txd_to_idx(ring, txd, soc->txrx.txd_size); -+ mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size), -+ MT7628_TX_CTX_IDX0); -+ } -+out: -+ spin_unlock(ð->page_lock); -+ -+ return err; -+} -+ -+static int mtk_xdp_xmit(struct net_device *dev, int num_frame, -+ struct xdp_frame **frames, u32 flags) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_hw_stats *hw_stats = mac->hw_stats; -+ struct mtk_eth *eth = mac->hw; -+ int i, nxmit = 0; -+ -+ if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) -+ return -EINVAL; -+ -+ for (i = 0; i < num_frame; i++) { -+ if (mtk_xdp_submit_frame(eth, frames[i], dev, true)) -+ break; -+ nxmit++; -+ } -+ -+ u64_stats_update_begin(&hw_stats->syncp); -+ hw_stats->xdp_stats.tx_xdp_xmit += nxmit; -+ hw_stats->xdp_stats.tx_xdp_xmit_errors += num_frame - nxmit; -+ u64_stats_update_end(&hw_stats->syncp); -+ -+ return nxmit; -+} -+ - static u32 mtk_xdp_run(struct mtk_eth *eth, struct mtk_rx_ring *ring, - struct xdp_buff *xdp, struct net_device *dev) - { -@@ -1494,6 +1623,18 @@ static u32 mtk_xdp_run(struct mtk_eth *e - - count = &hw_stats->xdp_stats.rx_xdp_redirect; - goto update_stats; -+ case XDP_TX: { -+ struct xdp_frame *xdpf = xdp_convert_buff_to_frame(xdp); -+ -+ if (mtk_xdp_submit_frame(eth, xdpf, dev, false)) { -+ count = &hw_stats->xdp_stats.rx_xdp_tx_errors; -+ act = XDP_DROP; -+ break; -+ } -+ -+ count = &hw_stats->xdp_stats.rx_xdp_tx; -+ goto update_stats; -+ } - default: - bpf_warn_invalid_xdp_action(act); - fallthrough; -@@ -1727,9 +1868,8 @@ static int mtk_poll_tx_qdma(struct mtk_e - { - const struct mtk_reg_map *reg_map = eth->soc->reg_map; - struct mtk_tx_ring *ring = ð->tx_ring; -- struct mtk_tx_dma *desc; -- struct sk_buff *skb; - struct mtk_tx_buf *tx_buf; -+ struct mtk_tx_dma *desc; - u32 cpu, dma; - - cpu = ring->last_free_ptr; -@@ -1750,15 +1890,21 @@ static int mtk_poll_tx_qdma(struct mtk_e - if (tx_buf->flags & MTK_TX_FLAGS_FPORT1) - mac = 1; - -- skb = tx_buf->skb; -- if (!skb) -+ if (!tx_buf->data) - break; - -- if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) { -+ if (tx_buf->type == MTK_TYPE_SKB && -+ tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -+ struct sk_buff *skb = tx_buf->data; -+ - bytes[mac] += skb->len; - done[mac]++; - budget--; -+ } else if (tx_buf->type == MTK_TYPE_XDP_TX || -+ tx_buf->type == MTK_TYPE_XDP_NDO) { -+ budget--; - } -+ - mtk_tx_unmap(eth, tx_buf, true); - - ring->last_free = desc; -@@ -1777,9 +1923,8 @@ static int mtk_poll_tx_pdma(struct mtk_e - unsigned int *done, unsigned int *bytes) - { - struct mtk_tx_ring *ring = ð->tx_ring; -- struct mtk_tx_dma *desc; -- struct sk_buff *skb; - struct mtk_tx_buf *tx_buf; -+ struct mtk_tx_dma *desc; - u32 cpu, dma; - - cpu = ring->cpu_idx; -@@ -1787,14 +1932,18 @@ static int mtk_poll_tx_pdma(struct mtk_e - - while ((cpu != dma) && budget) { - tx_buf = &ring->buf[cpu]; -- skb = tx_buf->skb; -- if (!skb) -+ if (!tx_buf->data) - break; - -- if (skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC) { -+ if (tx_buf->type == MTK_TYPE_SKB && -+ tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -+ struct sk_buff *skb = tx_buf->data; - bytes[0] += skb->len; - done[0]++; - budget--; -+ } else if (tx_buf->type == MTK_TYPE_XDP_TX || -+ tx_buf->type == MTK_TYPE_XDP_NDO) { -+ budget--; - } - - mtk_tx_unmap(eth, tx_buf, true); -@@ -3462,6 +3611,7 @@ static const struct net_device_ops mtk_n - #endif - .ndo_setup_tc = mtk_eth_setup_tc, - .ndo_bpf = mtk_xdp, -+ .ndo_xdp_xmit = mtk_xdp_xmit, - }; - - static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -694,6 +694,12 @@ enum mtk_dev_state { - MTK_RESETTING - }; - -+enum mtk_tx_buf_type { -+ MTK_TYPE_SKB, -+ MTK_TYPE_XDP_TX, -+ MTK_TYPE_XDP_NDO, -+}; -+ - /* struct mtk_tx_buf - This struct holds the pointers to the memory pointed at - * by the TX descriptor s - * @skb: The SKB pointer of the packet being sent -@@ -703,7 +709,9 @@ enum mtk_dev_state { - * @dma_len1: The length of the second segment - */ - struct mtk_tx_buf { -- struct sk_buff *skb; -+ enum mtk_tx_buf_type type; -+ void *data; -+ - u32 flags; - DEFINE_DMA_UNMAP_ADDR(dma_addr0); - DEFINE_DMA_UNMAP_LEN(dma_len0); diff --git a/target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch b/target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch deleted file mode 100644 index 4707aacd9d3269..00000000000000 --- a/target/linux/generic/backport-5.15/706-04-v6.0-net-ethernet-mtk_eth_soc-add-support-for-page_pool_g.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 84b9cd389036d4a262d8cee794d56c04095358a7 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 22 Jul 2022 09:19:40 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for - page_pool_get_stats - -Introduce support for the page_pool stats API into mtk_eth_soc driver. -Report page_pool stats through ethtool. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/Kconfig | 1 + - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 37 +++++++++++++++++++-- - 2 files changed, 35 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -17,6 +17,7 @@ config NET_MEDIATEK_SOC - select PHYLINK - select DIMLIB - select PAGE_POOL -+ select PAGE_POOL_STATS - help - This driver supports the gigabit ethernet MACs in the - MediaTek SoC family. ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3473,11 +3473,18 @@ static void mtk_get_strings(struct net_d - int i; - - switch (stringset) { -- case ETH_SS_STATS: -+ case ETH_SS_STATS: { -+ struct mtk_mac *mac = netdev_priv(dev); -+ - for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) { - memcpy(data, mtk_ethtool_stats[i].str, ETH_GSTRING_LEN); - data += ETH_GSTRING_LEN; - } -+ if (mtk_page_pool_enabled(mac->hw)) -+ page_pool_ethtool_stats_get_strings(data); -+ break; -+ } -+ default: - break; - } - } -@@ -3485,13 +3492,35 @@ static void mtk_get_strings(struct net_d - static int mtk_get_sset_count(struct net_device *dev, int sset) - { - switch (sset) { -- case ETH_SS_STATS: -- return ARRAY_SIZE(mtk_ethtool_stats); -+ case ETH_SS_STATS: { -+ int count = ARRAY_SIZE(mtk_ethtool_stats); -+ struct mtk_mac *mac = netdev_priv(dev); -+ -+ if (mtk_page_pool_enabled(mac->hw)) -+ count += page_pool_ethtool_stats_get_count(); -+ return count; -+ } - default: - return -EOPNOTSUPP; - } - } - -+static void mtk_ethtool_pp_stats(struct mtk_eth *eth, u64 *data) -+{ -+ struct page_pool_stats stats = {}; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(eth->rx_ring); i++) { -+ struct mtk_rx_ring *ring = ð->rx_ring[i]; -+ -+ if (!ring->page_pool) -+ continue; -+ -+ page_pool_get_stats(ring->page_pool, &stats); -+ } -+ page_pool_ethtool_stats_get(data, &stats); -+} -+ - static void mtk_get_ethtool_stats(struct net_device *dev, - struct ethtool_stats *stats, u64 *data) - { -@@ -3519,6 +3548,8 @@ static void mtk_get_ethtool_stats(struct - - for (i = 0; i < ARRAY_SIZE(mtk_ethtool_stats); i++) - *data_dst++ = *(data_src + mtk_ethtool_stats[i].offset); -+ if (mtk_page_pool_enabled(mac->hw)) -+ mtk_ethtool_pp_stats(mac->hw, data_dst); - } while (u64_stats_fetch_retry_irq(&hwstats->syncp, start)); - } - diff --git a/target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch b/target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch deleted file mode 100644 index 33a76166521af7..00000000000000 --- a/target/linux/generic/backport-5.15/706-05-v6.0-net-ethernet-mtk_eth_soc-introduce-mtk_xdp_frame_map.patch +++ /dev/null @@ -1,113 +0,0 @@ -From b16fe6d82b71fa0dd5c957bc22d66a694976d6eb Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 27 Jul 2022 23:20:50 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_xdp_frame_map - utility routine - -This is a preliminary patch to add xdp multi-frag support to mtk_eth_soc -driver - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 68 +++++++++++++-------- - 1 file changed, 42 insertions(+), 26 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1479,6 +1479,41 @@ static void mtk_rx_put_buff(struct mtk_r - skb_free_frag(data); - } - -+static int mtk_xdp_frame_map(struct mtk_eth *eth, struct net_device *dev, -+ struct mtk_tx_dma_desc_info *txd_info, -+ struct mtk_tx_dma *txd, struct mtk_tx_buf *tx_buf, -+ void *data, u16 headroom, int index, bool dma_map) -+{ -+ struct mtk_tx_ring *ring = ð->tx_ring; -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_tx_dma *txd_pdma; -+ -+ if (dma_map) { /* ndo_xdp_xmit */ -+ txd_info->addr = dma_map_single(eth->dma_dev, data, -+ txd_info->size, DMA_TO_DEVICE); -+ if (unlikely(dma_mapping_error(eth->dma_dev, txd_info->addr))) -+ return -ENOMEM; -+ -+ tx_buf->flags |= MTK_TX_FLAGS_SINGLE0; -+ } else { -+ struct page *page = virt_to_head_page(data); -+ -+ txd_info->addr = page_pool_get_dma_addr(page) + -+ sizeof(struct xdp_frame) + headroom; -+ dma_sync_single_for_device(eth->dma_dev, txd_info->addr, -+ txd_info->size, DMA_BIDIRECTIONAL); -+ } -+ mtk_tx_set_dma_desc(dev, txd, txd_info); -+ -+ tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; -+ -+ txd_pdma = qdma_to_pdma(ring, txd); -+ setup_tx_buf(eth, tx_buf, txd_pdma, txd_info->addr, txd_info->size, -+ index); -+ -+ return 0; -+} -+ - static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, - struct net_device *dev, bool dma_map) - { -@@ -1489,9 +1524,8 @@ static int mtk_xdp_submit_frame(struct m - .first = true, - .last = true, - }; -- struct mtk_mac *mac = netdev_priv(dev); -- struct mtk_tx_dma *txd, *txd_pdma; - int err = 0, index = 0, n_desc = 1; -+ struct mtk_tx_dma *txd, *txd_pdma; - struct mtk_tx_buf *tx_buf; - - if (unlikely(test_bit(MTK_RESETTING, ð->state))) -@@ -1511,36 +1545,18 @@ static int mtk_xdp_submit_frame(struct m - tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size); - memset(tx_buf, 0, sizeof(*tx_buf)); - -- if (dma_map) { /* ndo_xdp_xmit */ -- txd_info.addr = dma_map_single(eth->dma_dev, xdpf->data, -- txd_info.size, DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(eth->dma_dev, txd_info.addr))) { -- err = -ENOMEM; -- goto out; -- } -- tx_buf->flags |= MTK_TX_FLAGS_SINGLE0; -- } else { -- struct page *page = virt_to_head_page(xdpf->data); -- -- txd_info.addr = page_pool_get_dma_addr(page) + -- sizeof(*xdpf) + xdpf->headroom; -- dma_sync_single_for_device(eth->dma_dev, txd_info.addr, -- txd_info.size, -- DMA_BIDIRECTIONAL); -- } -- mtk_tx_set_dma_desc(dev, txd, &txd_info); -- -- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; -- -- txd_pdma = qdma_to_pdma(ring, txd); -- setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, txd_info.size, -- index++); -+ err = mtk_xdp_frame_map(eth, dev, &txd_info, txd, tx_buf, -+ xdpf->data, xdpf->headroom, index, -+ dma_map); -+ if (err < 0) -+ goto out; - - /* store xdpf for cleanup */ - tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; - tx_buf->data = xdpf; - - if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { -+ txd_pdma = qdma_to_pdma(ring, txd); - if (index & 1) - txd_pdma->txd2 |= TX_DMA_LS0; - else diff --git a/target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch b/target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch deleted file mode 100644 index e75861bc829344..00000000000000 --- a/target/linux/generic/backport-5.15/706-06-v6.0-net-ethernet-mtk_eth_soc-introduce-xdp-multi-frag-su.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 155738a4f319538a09f734ce1f5a2eac3ada1de2 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 27 Jul 2022 23:20:51 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce xdp multi-frag support - -Add the capability to map non-linear xdp frames in XDP_TX and -ndo_xdp_xmit callback. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 125 +++++++++++++------- - 1 file changed, 82 insertions(+), 43 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -987,23 +987,22 @@ static void mtk_tx_unmap(struct mtk_eth - } - } - -- if (tx_buf->type == MTK_TYPE_SKB) { -- if (tx_buf->data && -- tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -+ if (tx_buf->data && tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -+ if (tx_buf->type == MTK_TYPE_SKB) { - struct sk_buff *skb = tx_buf->data; - - if (napi) - napi_consume_skb(skb, napi); - else - dev_kfree_skb_any(skb); -- } -- } else if (tx_buf->data) { -- struct xdp_frame *xdpf = tx_buf->data; -+ } else { -+ struct xdp_frame *xdpf = tx_buf->data; - -- if (napi && tx_buf->type == MTK_TYPE_XDP_TX) -- xdp_return_frame_rx_napi(xdpf); -- else -- xdp_return_frame(xdpf); -+ if (napi && tx_buf->type == MTK_TYPE_XDP_TX) -+ xdp_return_frame_rx_napi(xdpf); -+ else -+ xdp_return_frame(xdpf); -+ } - } - tx_buf->flags = 0; - tx_buf->data = NULL; -@@ -1506,6 +1505,8 @@ static int mtk_xdp_frame_map(struct mtk_ - mtk_tx_set_dma_desc(dev, txd, txd_info); - - tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; -+ tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; -+ tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; - - txd_pdma = qdma_to_pdma(ring, txd); - setup_tx_buf(eth, tx_buf, txd_pdma, txd_info->addr, txd_info->size, -@@ -1517,43 +1518,69 @@ static int mtk_xdp_frame_map(struct mtk_ - static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf, - struct net_device *dev, bool dma_map) - { -+ struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf); - const struct mtk_soc_data *soc = eth->soc; - struct mtk_tx_ring *ring = ð->tx_ring; - struct mtk_tx_dma_desc_info txd_info = { - .size = xdpf->len, - .first = true, -- .last = true, -+ .last = !xdp_frame_has_frags(xdpf), - }; -- int err = 0, index = 0, n_desc = 1; -- struct mtk_tx_dma *txd, *txd_pdma; -- struct mtk_tx_buf *tx_buf; -+ int err, index = 0, n_desc = 1, nr_frags; -+ struct mtk_tx_dma *htxd, *txd, *txd_pdma; -+ struct mtk_tx_buf *htx_buf, *tx_buf; -+ void *data = xdpf->data; - - if (unlikely(test_bit(MTK_RESETTING, ð->state))) - return -EBUSY; - -- if (unlikely(atomic_read(&ring->free_count) <= 1)) -+ nr_frags = unlikely(xdp_frame_has_frags(xdpf)) ? sinfo->nr_frags : 0; -+ if (unlikely(atomic_read(&ring->free_count) <= 1 + nr_frags)) - return -EBUSY; - - spin_lock(ð->page_lock); - - txd = ring->next_free; - if (txd == ring->last_free) { -- err = -ENOMEM; -- goto out; -+ spin_unlock(ð->page_lock); -+ return -ENOMEM; - } -+ htxd = txd; - - tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size); - memset(tx_buf, 0, sizeof(*tx_buf)); -+ htx_buf = tx_buf; - -- err = mtk_xdp_frame_map(eth, dev, &txd_info, txd, tx_buf, -- xdpf->data, xdpf->headroom, index, -- dma_map); -- if (err < 0) -- goto out; -+ for (;;) { -+ err = mtk_xdp_frame_map(eth, dev, &txd_info, txd, tx_buf, -+ data, xdpf->headroom, index, dma_map); -+ if (err < 0) -+ goto unmap; -+ -+ if (txd_info.last) -+ break; - -+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA) || (index & 0x1)) { -+ txd = mtk_qdma_phys_to_virt(ring, txd->txd2); -+ txd_pdma = qdma_to_pdma(ring, txd); -+ if (txd == ring->last_free) -+ goto unmap; -+ -+ tx_buf = mtk_desc_to_tx_buf(ring, txd, -+ soc->txrx.txd_size); -+ memset(tx_buf, 0, sizeof(*tx_buf)); -+ n_desc++; -+ } -+ -+ memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); -+ txd_info.size = skb_frag_size(&sinfo->frags[index]); -+ txd_info.last = index + 1 == nr_frags; -+ data = skb_frag_address(&sinfo->frags[index]); -+ -+ index++; -+ } - /* store xdpf for cleanup */ -- tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; -- tx_buf->data = xdpf; -+ htx_buf->data = xdpf; - - if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { - txd_pdma = qdma_to_pdma(ring, txd); -@@ -1580,7 +1607,24 @@ static int mtk_xdp_submit_frame(struct m - mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size), - MT7628_TX_CTX_IDX0); - } --out: -+ -+ spin_unlock(ð->page_lock); -+ -+ return 0; -+ -+unmap: -+ while (htxd != txd) { -+ txd_pdma = qdma_to_pdma(ring, htxd); -+ tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->txrx.txd_size); -+ mtk_tx_unmap(eth, tx_buf, false); -+ -+ htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; -+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) -+ txd_pdma->txd2 = TX_DMA_DESP2_DEF; -+ -+ htxd = mtk_qdma_phys_to_virt(ring, htxd->txd2); -+ } -+ - spin_unlock(ð->page_lock); - - return err; -@@ -1909,18 +1953,15 @@ static int mtk_poll_tx_qdma(struct mtk_e - if (!tx_buf->data) - break; - -- if (tx_buf->type == MTK_TYPE_SKB && -- tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -- struct sk_buff *skb = tx_buf->data; -+ if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -+ if (tx_buf->type == MTK_TYPE_SKB) { -+ struct sk_buff *skb = tx_buf->data; - -- bytes[mac] += skb->len; -- done[mac]++; -- budget--; -- } else if (tx_buf->type == MTK_TYPE_XDP_TX || -- tx_buf->type == MTK_TYPE_XDP_NDO) { -+ bytes[mac] += skb->len; -+ done[mac]++; -+ } - budget--; - } -- - mtk_tx_unmap(eth, tx_buf, true); - - ring->last_free = desc; -@@ -1951,17 +1992,15 @@ static int mtk_poll_tx_pdma(struct mtk_e - if (!tx_buf->data) - break; - -- if (tx_buf->type == MTK_TYPE_SKB && -- tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -- struct sk_buff *skb = tx_buf->data; -- bytes[0] += skb->len; -- done[0]++; -- budget--; -- } else if (tx_buf->type == MTK_TYPE_XDP_TX || -- tx_buf->type == MTK_TYPE_XDP_NDO) { -+ if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -+ if (tx_buf->type == MTK_TYPE_SKB) { -+ struct sk_buff *skb = tx_buf->data; -+ -+ bytes[0] += skb->len; -+ done[0]++; -+ } - budget--; - } -- - mtk_tx_unmap(eth, tx_buf, true); - - desc = ring->dma + cpu * eth->soc->txrx.txd_size; diff --git a/target/linux/generic/backport-5.15/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch b/target/linux/generic/backport-5.15/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch deleted file mode 100644 index 1f2a3ee140fb85..00000000000000 --- a/target/linux/generic/backport-5.15/707-v6.3-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch +++ /dev/null @@ -1,394 +0,0 @@ -From 4765a9722e09765866e131ec31f7b9cf4c1f4854 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 19 Mar 2023 12:57:50 +0000 -Subject: [PATCH] net: pcs: add driver for MediaTek SGMII PCS - -The SGMII core found in several MediaTek SoCs is identical to what can -also be found in MediaTek's MT7531 Ethernet switch IC. -As this has not always been clear, both drivers developed different -implementations to deal with the PCS. -Recently Alexander Couzens pointed out this fact which lead to the -development of this shared driver. - -Add a dedicated driver, mostly by copying the code now found in the -Ethernet driver. The now redundant code will be removed by a follow-up -commit. - -Suggested-by: Alexander Couzens -Suggested-by: Russell King (Oracle) -Signed-off-by: Daniel Golle -Tested-by: Frank Wunderlich -Reviewed-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - MAINTAINERS | 8 + - drivers/net/pcs/Kconfig | 7 + - drivers/net/pcs/Makefile | 1 + - drivers/net/pcs/pcs-mtk-lynxi.c | 305 ++++++++++++++++++++++++++++++ - include/linux/pcs/pcs-mtk-lynxi.h | 13 ++ - 5 files changed, 334 insertions(+) - create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c - create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -11790,6 +11790,14 @@ L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/ethernet/mediatek/ - -+MEDIATEK ETHERNET PCS DRIVER -+M: Alexander Couzens -+M: Daniel Golle -+L: netdev@vger.kernel.org -+S: Maintained -+F: drivers/net/pcs/pcs-mtk-lynxi.c -+F: include/linux/pcs/pcs-mtk-lynxi.h -+ - MEDIATEK I2C CONTROLLER DRIVER - M: Qii Wang - L: linux-i2c@vger.kernel.org ---- a/drivers/net/pcs/Kconfig -+++ b/drivers/net/pcs/Kconfig -@@ -18,4 +18,11 @@ config PCS_LYNX - This module provides helpers to phylink for managing the Lynx PCS - which is part of the Layerscape and QorIQ Ethernet SERDES. - -+config PCS_MTK_LYNXI -+ tristate -+ select REGMAP -+ help -+ This module provides helpers to phylink for managing the LynxI PCS -+ which is part of MediaTek's SoC and Ethernet switch ICs. -+ - endmenu ---- a/drivers/net/pcs/Makefile -+++ b/drivers/net/pcs/Makefile -@@ -5,3 +5,4 @@ pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs. - - obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o - obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o -+obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o ---- /dev/null -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -0,0 +1,305 @@ -+// SPDX-License-Identifier: GPL-2.0 -+// Copyright (c) 2018-2019 MediaTek Inc. -+/* A library for MediaTek SGMII circuit -+ * -+ * Author: Sean Wang -+ * Author: Alexander Couzens -+ * Author: Daniel Golle -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/* SGMII subsystem config registers */ -+/* BMCR (low 16) BMSR (high 16) */ -+#define SGMSYS_PCS_CONTROL_1 0x0 -+#define SGMII_BMCR GENMASK(15, 0) -+#define SGMII_BMSR GENMASK(31, 16) -+ -+#define SGMSYS_PCS_DEVICE_ID 0x4 -+#define SGMII_LYNXI_DEV_ID 0x4d544950 -+ -+#define SGMSYS_PCS_ADVERTISE 0x8 -+#define SGMII_ADVERTISE GENMASK(15, 0) -+#define SGMII_LPA GENMASK(31, 16) -+ -+#define SGMSYS_PCS_SCRATCH 0x14 -+#define SGMII_DEV_VERSION GENMASK(31, 16) -+ -+/* Register to programmable link timer, the unit in 2 * 8ns */ -+#define SGMSYS_PCS_LINK_TIMER 0x18 -+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0) -+#define SGMII_LINK_TIMER_VAL(ns) FIELD_PREP(SGMII_LINK_TIMER_MASK, \ -+ ((ns) / 2 / 8)) -+ -+/* Register to control remote fault */ -+#define SGMSYS_SGMII_MODE 0x20 -+#define SGMII_IF_MODE_SGMII BIT(0) -+#define SGMII_SPEED_DUPLEX_AN BIT(1) -+#define SGMII_SPEED_MASK GENMASK(3, 2) -+#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) -+#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) -+#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) -+#define SGMII_DUPLEX_HALF BIT(4) -+#define SGMII_REMOTE_FAULT_DIS BIT(8) -+ -+/* Register to reset SGMII design */ -+#define SGMSYS_RESERVED_0 0x34 -+#define SGMII_SW_RESET BIT(0) -+ -+/* Register to set SGMII speed, ANA RG_ Control Signals III */ -+#define SGMII_PHY_SPEED_MASK GENMASK(3, 2) -+#define SGMII_PHY_SPEED_1_25G FIELD_PREP(SGMII_PHY_SPEED_MASK, 0) -+#define SGMII_PHY_SPEED_3_125G FIELD_PREP(SGMII_PHY_SPEED_MASK, 1) -+ -+/* Register to power up QPHY */ -+#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 -+#define SGMII_PHYA_PWD BIT(4) -+ -+/* Register to QPHY wrapper control */ -+#define SGMSYS_QPHY_WRAP_CTRL 0xec -+#define SGMII_PN_SWAP_MASK GENMASK(1, 0) -+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) -+ -+/* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated -+ * data -+ * @regmap: The register map pointing at the range used to setup -+ * SGMII modes -+ * @dev: Pointer to device owning the PCS -+ * @ana_rgc3: The offset of register ANA_RGC3 relative to regmap -+ * @interface: Currently configured interface mode -+ * @pcs: Phylink PCS structure -+ * @flags: Flags indicating hardware properties -+ */ -+struct mtk_pcs_lynxi { -+ struct regmap *regmap; -+ u32 ana_rgc3; -+ phy_interface_t interface; -+ struct phylink_pcs pcs; -+ u32 flags; -+}; -+ -+static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs) -+{ -+ return container_of(pcs, struct mtk_pcs_lynxi, pcs); -+} -+ -+static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ unsigned int bm, adv; -+ -+ /* Read the BMSR and LPA */ -+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); -+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -+ -+ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), -+ FIELD_GET(SGMII_LPA, adv)); -+} -+ -+static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ bool mode_changed = false, changed, use_an; -+ unsigned int rgc3, sgm_mode, bmcr; -+ int advertise, link_timer; -+ -+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface, -+ advertising); -+ if (advertise < 0) -+ return advertise; -+ -+ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and -+ * we assume that fixes it's speed at bitrate = line rate (in -+ * other words, 1000Mbps or 2500Mbps). -+ */ -+ if (interface == PHY_INTERFACE_MODE_SGMII) { -+ sgm_mode = SGMII_IF_MODE_SGMII; -+ if (phylink_autoneg_inband(mode)) { -+ sgm_mode |= SGMII_REMOTE_FAULT_DIS | -+ SGMII_SPEED_DUPLEX_AN; -+ use_an = true; -+ } else { -+ use_an = false; -+ } -+ } else if (phylink_autoneg_inband(mode)) { -+ /* 1000base-X or 2500base-X autoneg */ -+ sgm_mode = SGMII_REMOTE_FAULT_DIS; -+ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ advertising); -+ } else { -+ /* 1000base-X or 2500base-X without autoneg */ -+ sgm_mode = 0; -+ use_an = false; -+ } -+ -+ if (use_an) -+ bmcr = BMCR_ANENABLE; -+ else -+ bmcr = 0; -+ -+ if (mpcs->interface != interface) { -+ link_timer = phylink_get_link_timer_ns(interface); -+ if (link_timer < 0) -+ return link_timer; -+ -+ /* PHYA power down */ -+ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -+ SGMII_PHYA_PWD); -+ -+ /* Reset SGMII PCS state */ -+ regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0, -+ SGMII_SW_RESET); -+ -+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP) -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, -+ SGMII_PN_SWAP_MASK, -+ SGMII_PN_SWAP_TX_RX); -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ rgc3 = SGMII_PHY_SPEED_3_125G; -+ else -+ rgc3 = SGMII_PHY_SPEED_1_25G; -+ -+ /* Configure the underlying interface speed */ -+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -+ SGMII_PHY_SPEED_MASK, rgc3); -+ -+ /* Setup the link timer */ -+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, -+ SGMII_LINK_TIMER_VAL(link_timer)); -+ -+ mpcs->interface = interface; -+ mode_changed = true; -+ } -+ -+ /* Update the advertisement, noting whether it has changed */ -+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, -+ SGMII_ADVERTISE, advertise, &changed); -+ -+ /* Update the sgmsys mode register */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | -+ SGMII_IF_MODE_SGMII, sgm_mode); -+ -+ /* Update the BMCR */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -+ BMCR_ANENABLE, bmcr); -+ -+ /* Release PHYA power down state -+ * Only removing bit SGMII_PHYA_PWD isn't enough. -+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which -+ * prevents SGMII from working. The SGMII still shows link but no traffic -+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was -+ * taken from a good working state of the SGMII interface. -+ * Unknown how much the QPHY needs but it is racy without a sleep. -+ * Tested on mt7622 & mt7986. -+ */ -+ usleep_range(50, 100); -+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); -+ -+ return changed || mode_changed; -+} -+ -+static void mtk_pcs_lynxi_restart_an(struct phylink_pcs *pcs) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ -+ regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART); -+} -+ -+static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, int speed, -+ int duplex) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ unsigned int sgm_mode; -+ -+ if (!phylink_autoneg_inband(mode)) { -+ /* Force the speed and duplex setting */ -+ if (speed == SPEED_10) -+ sgm_mode = SGMII_SPEED_10; -+ else if (speed == SPEED_100) -+ sgm_mode = SGMII_SPEED_100; -+ else -+ sgm_mode = SGMII_SPEED_1000; -+ -+ if (duplex != DUPLEX_FULL) -+ sgm_mode |= SGMII_DUPLEX_HALF; -+ -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, -+ sgm_mode); -+ } -+} -+ -+static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { -+ .pcs_get_state = mtk_pcs_lynxi_get_state, -+ .pcs_config = mtk_pcs_lynxi_config, -+ .pcs_an_restart = mtk_pcs_lynxi_restart_an, -+ .pcs_link_up = mtk_pcs_lynxi_link_up, -+}; -+ -+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, -+ struct regmap *regmap, u32 ana_rgc3, -+ u32 flags) -+{ -+ struct mtk_pcs_lynxi *mpcs; -+ u32 id, ver; -+ int ret; -+ -+ ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id); -+ if (ret < 0) -+ return NULL; -+ -+ if (id != SGMII_LYNXI_DEV_ID) { -+ dev_err(dev, "unknown PCS device id %08x\n", id); -+ return NULL; -+ } -+ -+ ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver); -+ if (ret < 0) -+ return NULL; -+ -+ ver = FIELD_GET(SGMII_DEV_VERSION, ver); -+ if (ver != 0x1) { -+ dev_err(dev, "unknown PCS device version %04x\n", ver); -+ return NULL; -+ } -+ -+ dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id, -+ ver); -+ -+ mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); -+ if (!mpcs) -+ return NULL; -+ -+ mpcs->ana_rgc3 = ana_rgc3; -+ mpcs->regmap = regmap; -+ mpcs->flags = flags; -+ mpcs->pcs.ops = &mtk_pcs_lynxi_ops; -+ mpcs->pcs.poll = true; -+ mpcs->interface = PHY_INTERFACE_MODE_NA; -+ -+ return &mpcs->pcs; -+} -+EXPORT_SYMBOL(mtk_pcs_lynxi_create); -+ -+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs) -+{ -+ if (!pcs) -+ return; -+ -+ kfree(pcs_to_mtk_pcs_lynxi(pcs)); -+} -+EXPORT_SYMBOL(mtk_pcs_lynxi_destroy); -+ -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/include/linux/pcs/pcs-mtk-lynxi.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __LINUX_PCS_MTK_LYNXI_H -+#define __LINUX_PCS_MTK_LYNXI_H -+ -+#include -+#include -+ -+#define MTK_SGMII_FLAG_PN_SWAP BIT(0) -+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, -+ struct regmap *regmap, -+ u32 ana_rgc3, u32 flags); -+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs); -+#endif diff --git a/target/linux/generic/backport-5.15/708-01-v5.16-net-mvneta-Delete-unused-variable.patch b/target/linux/generic/backport-5.15/708-01-v5.16-net-mvneta-Delete-unused-variable.patch deleted file mode 100644 index 421563ef08cf9d..00000000000000 --- a/target/linux/generic/backport-5.15/708-01-v5.16-net-mvneta-Delete-unused-variable.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 43ed6fff01333868a1d0e19876f67c22d9939952 Mon Sep 17 00:00:00 2001 -From: Yuval Shaia -Date: Wed, 13 Oct 2021 09:49:21 +0300 -Subject: [PATCH] net: mvneta: Delete unused variable - -The variable pp is not in use - delete it. - -Signed-off-by: Yuval Shaia -Link: https://lore.kernel.org/r/20211013064921.26346-1-yshaia@marvell.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/marvell/mvneta.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -1914,7 +1914,7 @@ static int mvneta_rx_refill(struct mvnet - } - - /* Handle tx checksum */ --static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb) -+static u32 mvneta_skb_tx_csum(struct sk_buff *skb) - { - if (skb->ip_summed == CHECKSUM_PARTIAL) { - int ip_hdr_len = 0; -@@ -2595,8 +2595,7 @@ err_drop_frame: - } - - static inline void --mvneta_tso_put_hdr(struct sk_buff *skb, -- struct mvneta_port *pp, struct mvneta_tx_queue *txq) -+mvneta_tso_put_hdr(struct sk_buff *skb, struct mvneta_tx_queue *txq) - { - int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); - struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index]; -@@ -2604,7 +2603,7 @@ mvneta_tso_put_hdr(struct sk_buff *skb, - - tx_desc = mvneta_txq_next_desc_get(txq); - tx_desc->data_size = hdr_len; -- tx_desc->command = mvneta_skb_tx_csum(pp, skb); -+ tx_desc->command = mvneta_skb_tx_csum(skb); - tx_desc->command |= MVNETA_TXD_F_DESC; - tx_desc->buf_phys_addr = txq->tso_hdrs_phys + - txq->txq_put_index * TSO_HEADER_SIZE; -@@ -2681,7 +2680,7 @@ static int mvneta_tx_tso(struct sk_buff - hdr = txq->tso_hdrs + txq->txq_put_index * TSO_HEADER_SIZE; - tso_build_hdr(skb, hdr, &tso, data_left, total_len == 0); - -- mvneta_tso_put_hdr(skb, pp, txq); -+ mvneta_tso_put_hdr(skb, txq); - - while (data_left > 0) { - int size; -@@ -2799,7 +2798,7 @@ static netdev_tx_t mvneta_tx(struct sk_b - /* Get a descriptor for the first part of the packet */ - tx_desc = mvneta_txq_next_desc_get(txq); - -- tx_cmd = mvneta_skb_tx_csum(pp, skb); -+ tx_cmd = mvneta_skb_tx_csum(skb); - - tx_desc->data_size = skb_headlen(skb); - diff --git a/target/linux/generic/backport-5.15/708-02-v6.3-net-mvneta-fix-potential-double-frees-in-mvneta_txq_.patch b/target/linux/generic/backport-5.15/708-02-v6.3-net-mvneta-fix-potential-double-frees-in-mvneta_txq_.patch deleted file mode 100644 index a16e68ee4fd9c5..00000000000000 --- a/target/linux/generic/backport-5.15/708-02-v6.3-net-mvneta-fix-potential-double-frees-in-mvneta_txq_.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0cf39c6543469aae4a30cba354243125514ed568 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 29 Mar 2023 13:11:17 +0100 -Subject: [PATCH] net: mvneta: fix potential double-frees in - mvneta_txq_sw_deinit() - -Reported on the Turris forum, mvneta provokes kernel warnings in the -architecture DMA mapping code when mvneta_setup_txqs() fails to -allocate memory. This happens because when mvneta_cleanup_txqs() is -called in the mvneta_stop() path, we leave pointers in the structure -that have been freed. - -Then on mvneta_open(), we call mvneta_setup_txqs(), which starts -allocating memory. On memory allocation failure, mvneta_cleanup_txqs() -will walk all the queues freeing any non-NULL pointers - which includes -pointers that were previously freed in mvneta_stop(). - -Fix this by setting these pointers to NULL to prevent double-freeing -of the same memory. - -Link: https://forum.turris.cz/t/random-kernel-exceptions-on-hbl-tos-7-0/18865/8 -Signed-off-by: Russell King (Oracle) ---- - drivers/net/ethernet/marvell/mvneta.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -3481,6 +3481,8 @@ static void mvneta_txq_sw_deinit(struct - - netdev_tx_reset_queue(nq); - -+ txq->buf = NULL; -+ txq->tso_hdrs = NULL; - txq->descs = NULL; - txq->last_desc = 0; - txq->next_desc_to_proc = 0; diff --git a/target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch b/target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch deleted file mode 100644 index a3842d35f56e95..00000000000000 --- a/target/linux/generic/backport-5.15/710-v6.0-net-ethernet-mtk_eth_soc-fix-hw-hash-reporting-for-M.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0cf731f9ebb5bf6f252055bebf4463a5c0bd490b Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 23 Aug 2022 14:24:07 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix hw hash reporting for - MTK_NETSYS_V2 - -Properly report hw rx hash for mt7986 chipset accroding to the new dma -descriptor layout. - -Fixes: 197c9e9b17b11 ("net: ethernet: mtk_eth_soc: introduce support for mt7986 chipset") -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/091394ea4e705fbb35f828011d98d0ba33808f69.1661257293.git.lorenzo@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 +++++++++++---------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 +++++ - 2 files changed, 17 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1845,10 +1845,19 @@ static int mtk_poll_rx(struct napi_struc - skb->dev = netdev; - bytes += skb->len; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; -+ if (hash != MTK_RXD5_FOE_ENTRY) -+ skb_set_hash(skb, jhash_1word(hash, 0), -+ PKT_HASH_TYPE_L4); - rxdcsum = &trxd.rxd3; -- else -+ } else { -+ hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; -+ if (hash != MTK_RXD4_FOE_ENTRY) -+ skb_set_hash(skb, jhash_1word(hash, 0), -+ PKT_HASH_TYPE_L4); - rxdcsum = &trxd.rxd4; -+ } - - if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid) - skb->ip_summed = CHECKSUM_UNNECESSARY; -@@ -1856,16 +1865,9 @@ static int mtk_poll_rx(struct napi_struc - skb_checksum_none_assert(skb); - skb->protocol = eth_type_trans(skb, netdev); - -- hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; -- if (hash != MTK_RXD4_FOE_ENTRY) { -- hash = jhash_1word(hash, 0); -- skb_set_hash(skb, hash, PKT_HASH_TYPE_L4); -- } -- - reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); - if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -- mtk_ppe_check_skb(eth->ppe, skb, -- trxd.rxd4 & MTK_RXD4_FOE_ENTRY); -+ mtk_ppe_check_skb(eth->ppe, skb, hash); - - if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -314,6 +314,11 @@ - #define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */ - #define RX_DMA_SPECIAL_TAG BIT(22) - -+/* PDMA descriptor rxd5 */ -+#define MTK_RXD5_FOE_ENTRY GENMASK(14, 0) -+#define MTK_RXD5_PPE_CPU_REASON GENMASK(22, 18) -+#define MTK_RXD5_SRC_PORT GENMASK(29, 26) -+ - #define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0xf) - #define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0x7) - diff --git a/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch b/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch deleted file mode 100644 index 0de8ab4376c066..00000000000000 --- a/target/linux/generic/backport-5.15/711-v6.0-01-net-ethernet-mtk_eth_soc-fix-off-by-one-check-of-ARR.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Tom Rix -Date: Sat, 16 Jul 2022 17:46:54 -0400 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix off by one check of - ARRAY_SIZE - -In mtk_wed_tx_ring_setup(.., int idx, ..), idx is used as an index here - struct mtk_wed_ring *ring = &dev->tx_ring[idx]; - -The bounds of idx are checked here - BUG_ON(idx > ARRAY_SIZE(dev->tx_ring)); - -If idx is the size of the array, it will pass this check and overflow. -So change the check to >= . - -Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)") -Signed-off-by: Tom Rix -Link: https://lore.kernel.org/r/20220716214654.1540240-1-trix@redhat.com -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -651,7 +651,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - * WDMA RX. - */ - -- BUG_ON(idx > ARRAY_SIZE(dev->tx_ring)); -+ BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring)); - - if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE)) - return -ENOMEM; diff --git a/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch b/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch deleted file mode 100644 index fc6e2464688cc3..00000000000000 --- a/target/linux/generic/backport-5.15/711-v6.0-02-net-ethernet-mtk_ppe-fix-possible-NULL-pointer-deref.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Jul 2022 11:51:53 +0200 -Subject: [PATCH] net: ethernet: mtk_ppe: fix possible NULL pointer dereference - in mtk_flow_get_wdma_info - -odev pointer can be NULL in mtk_flow_offload_replace routine according -to the flower action rules. Fix possible NULL pointer dereference in -mtk_flow_get_wdma_info. - -Fixes: a333215e10cb5 ("net: ethernet: mtk_eth_soc: implement flow offloading to WED devices") -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/4e1685bc4976e21e364055f6bee86261f8f9ee93.1658137753.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -93,6 +93,9 @@ mtk_flow_get_wdma_info(struct net_device - }; - struct net_device_path path = {}; - -+ if (!ctx.dev) -+ return -ENODEV; -+ - memcpy(ctx.daddr, addr, sizeof(ctx.daddr)); - - if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)) diff --git a/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch b/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch deleted file mode 100644 index c0720152d65ddf..00000000000000 --- a/target/linux/generic/backport-5.15/711-v6.0-03-net-ethernet-mtk-ppe-fix-traffic-offload-with-bridge.patch +++ /dev/null @@ -1,64 +0,0 @@ -From: Lorenzo Bianconi -Date: Fri, 22 Jul 2022 09:06:19 +0200 -Subject: [PATCH] net: ethernet: mtk-ppe: fix traffic offload with bridged wlan - -A typical flow offload scenario for OpenWrt users is routed traffic -received by the wan interface that is redirected to a wlan device -belonging to the lan bridge. Current implementation fails to -fill wdma offload info in mtk_flow_get_wdma_info() since odev device is -the local bridge. Fix the issue running dev_fill_forward_path routine in -mtk_flow_get_wdma_info in order to identify the wlan device. - -Tested-by: Paolo Valerio -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -88,32 +88,28 @@ mtk_flow_offload_mangle_eth(const struct - static int - mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_info *info) - { -- struct net_device_path_ctx ctx = { -- .dev = dev, -- }; -- struct net_device_path path = {}; -+ struct net_device_path_stack stack; -+ struct net_device_path *path; -+ int err; - -- if (!ctx.dev) -+ if (!dev) - return -ENODEV; - -- memcpy(ctx.daddr, addr, sizeof(ctx.daddr)); -- - if (!IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED)) - return -1; - -- if (!dev->netdev_ops->ndo_fill_forward_path) -- return -1; -- -- if (dev->netdev_ops->ndo_fill_forward_path(&ctx, &path)) -- return -1; -+ err = dev_fill_forward_path(dev, addr, &stack); -+ if (err) -+ return err; - -- if (path.type != DEV_PATH_MTK_WDMA) -+ path = &stack.path[stack.num_paths - 1]; -+ if (path->type != DEV_PATH_MTK_WDMA) - return -1; - -- info->wdma_idx = path.mtk_wdma.wdma_idx; -- info->queue = path.mtk_wdma.queue; -- info->bss = path.mtk_wdma.bss; -- info->wcid = path.mtk_wdma.wcid; -+ info->wdma_idx = path->mtk_wdma.wdma_idx; -+ info->queue = path->mtk_wdma.queue; -+ info->bss = path->mtk_wdma.bss; -+ info->wcid = path->mtk_wdma.wcid; - - return 0; - } diff --git a/target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch b/target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch deleted file mode 100644 index 3c28e835518243..00000000000000 --- a/target/linux/generic/backport-5.15/711-v6.0-04-net-ethernet-mtk_eth_soc-remove-mtk_foe_entry_timest.patch +++ /dev/null @@ -1,33 +0,0 @@ -From c9daab322313087afde8c46f41df3c628410ae20 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Mon, 5 Sep 2022 14:46:01 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: remove mtk_foe_entry_timestamp - -Get rid of mtk_foe_entry_timestamp routine since it is no longer used. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_ppe.h | 11 ----------- - 1 file changed, 11 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -302,17 +302,6 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s - __mtk_ppe_check_skb(ppe, skb, hash); - } - --static inline int --mtk_foe_entry_timestamp(struct mtk_ppe *ppe, u16 hash) --{ -- u32 ib1 = READ_ONCE(ppe->foe_table[hash].ib1); -- -- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) -- return -1; -- -- return FIELD_GET(MTK_FOE_IB1_BIND_TIMESTAMP, ib1); --} -- - int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, - u8 pse_port, u8 *src_mac, u8 *dest_mac); - int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port); diff --git a/target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch b/target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch deleted file mode 100644 index f4eb030ef69462..00000000000000 --- a/target/linux/generic/backport-5.15/712-v6.0-net-ethernet-mtk_eth_soc-enable-XDP-support-just-for.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 5e69163d3b9931098922b3fc2f8e786af8c1f37e Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 13 Sep 2022 15:03:05 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: enable XDP support just for - MT7986 SoC -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Disable page_pool/XDP support for MT7621 SoC in order fix a regression -introduce adding XDP for MT7986 SoC. There is no a real use case for XDP -on MT7621 since it is a low-end cpu. Moreover this patch reduces the -memory footprint. - -Tested-by: Sergio Paracuellos -Tested-by: Arınç ÜNAL -Fixes: 23233e577ef9 ("net: ethernet: mtk_eth_soc: rely on page_pool for single page buffers") -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/2bf31e27b888c43228b0d84dd2ef5033338269e2.1663074002.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1412,7 +1412,7 @@ static void mtk_update_rx_cpu_idx(struct - - static bool mtk_page_pool_enabled(struct mtk_eth *eth) - { -- return !eth->hwlro; -+ return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2); - } - - static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, diff --git a/target/linux/generic/backport-5.15/713-v6.0-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch b/target/linux/generic/backport-5.15/713-v6.0-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch deleted file mode 100644 index be6da9b4af0207..00000000000000 --- a/target/linux/generic/backport-5.15/713-v6.0-net-ethernet-mtk_eth_soc-move-gdma_to_ppe-and-ppe_ba.patch +++ /dev/null @@ -1,127 +0,0 @@ -From patchwork Thu Sep 8 19:33:38 2022 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Lorenzo Bianconi -X-Patchwork-Id: 12970556 -X-Patchwork-Delegate: kuba@kernel.org -From: Lorenzo Bianconi -To: netdev@vger.kernel.org -Cc: nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, - Mark-MC.Lee@mediatek.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com, - linux-mediatek@lists.infradead.org, lorenzo.bianconi@redhat.com, - Bo.Jiao@mediatek.com, sujuan.chen@mediatek.com, - ryder.Lee@mediatek.com, evelyn.tsai@mediatek.com, - devicetree@vger.kernel.org, robh@kernel.org -Subject: [PATCH net-next 03/12] net: ethernet: mtk_eth_soc: move gdma_to_ppe - and ppe_base definitions in mtk register map -Date: Thu, 8 Sep 2022 21:33:37 +0200 -Message-Id: - <95938fc9cbe0223714be2658a49ca58e9baace00.1662661555.git.lorenzo@kernel.org> -X-Mailer: git-send-email 2.37.3 -In-Reply-To: -References: -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -This is a preliminary patch to introduce mt7986 hw packet engine. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 15 +++++++++++---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 ++- - drivers/net/ethernet/mediatek/mtk_ppe.h | 2 -- - 3 files changed, 13 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -73,6 +73,8 @@ static const struct mtk_reg_map mtk_reg_ - .fq_blen = 0x1b2c, - }, - .gdm1_cnt = 0x2400, -+ .gdma_to_ppe0 = 0x4444, -+ .ppe_base = 0x0c00, - }; - - static const struct mtk_reg_map mt7628_reg_map = { -@@ -126,6 +128,8 @@ static const struct mtk_reg_map mt7986_r - .fq_blen = 0x472c, - }, - .gdm1_cnt = 0x1c00, -+ .gdma_to_ppe0 = 0x3333, -+ .ppe_base = 0x2000, - }; - - /* strings used by ethtool */ -@@ -2927,6 +2931,7 @@ static int mtk_open(struct net_device *d - - /* we run 2 netdevs on the same dma ring so we only bring it up once */ - if (!refcount_read(ð->dma_refcnt)) { -+ const struct mtk_soc_data *soc = eth->soc; - u32 gdm_config = MTK_GDMA_TO_PDMA; - int err; - -@@ -2936,15 +2941,15 @@ static int mtk_open(struct net_device *d - return err; - } - -- if (eth->soc->offload_version && mtk_ppe_start(eth->ppe) == 0) -- gdm_config = MTK_GDMA_TO_PPE; -+ if (soc->offload_version && mtk_ppe_start(eth->ppe) == 0) -+ gdm_config = soc->reg_map->gdma_to_ppe0; - - mtk_gdm_config(eth, gdm_config); - - napi_enable(ð->tx_napi); - napi_enable(ð->rx_napi); - mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); -- mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask); -+ mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask); - refcount_set(ð->dma_refcnt, 1); - } - else -@@ -4043,7 +4048,9 @@ static int mtk_probe(struct platform_dev - } - - if (eth->soc->offload_version) { -- eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2); -+ u32 ppe_addr = eth->soc->reg_map->ppe_base; -+ -+ eth->ppe = mtk_ppe_init(eth, eth->base + ppe_addr, 2); - if (!eth->ppe) { - err = -ENOMEM; - goto err_free_dev; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -105,7 +105,6 @@ - #define MTK_GDMA_TCS_EN BIT(21) - #define MTK_GDMA_UCS_EN BIT(20) - #define MTK_GDMA_TO_PDMA 0x0 --#define MTK_GDMA_TO_PPE 0x4444 - #define MTK_GDMA_DROP_ALL 0x7777 - - /* Unicast Filter MAC Address Register - Low */ -@@ -953,6 +952,8 @@ struct mtk_reg_map { - u32 fq_blen; /* fq free page buffer length */ - } qdma; - u32 gdm1_cnt; -+ u32 gdma_to_ppe0; -+ u32 ppe_base; - }; - - /* struct mtk_eth_data - This is the structure holding all differences ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -8,8 +8,6 @@ - #include - #include - --#define MTK_ETH_PPE_BASE 0xc00 -- - #define MTK_PPE_ENTRIES_SHIFT 3 - #define MTK_PPE_ENTRIES (1024 << MTK_PPE_ENTRIES_SHIFT) - #define MTK_PPE_HASH_MASK (MTK_PPE_ENTRIES - 1) diff --git a/target/linux/generic/backport-5.15/714-v6.0-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch b/target/linux/generic/backport-5.15/714-v6.0-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch deleted file mode 100644 index 76f954f6266407..00000000000000 --- a/target/linux/generic/backport-5.15/714-v6.0-net-ethernet-mtk_eth_soc-move-ppe-table-hash-offset-.patch +++ /dev/null @@ -1,199 +0,0 @@ -From patchwork Thu Sep 8 19:33:38 2022 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Lorenzo Bianconi -X-Patchwork-Id: 12970557 -X-Patchwork-Delegate: kuba@kernel.org -From: Lorenzo Bianconi -To: netdev@vger.kernel.org -Cc: nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, - Mark-MC.Lee@mediatek.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com, - linux-mediatek@lists.infradead.org, lorenzo.bianconi@redhat.com, - Bo.Jiao@mediatek.com, sujuan.chen@mediatek.com, - ryder.Lee@mediatek.com, evelyn.tsai@mediatek.com, - devicetree@vger.kernel.org, robh@kernel.org -Subject: [PATCH net-next 04/12] net: ethernet: mtk_eth_soc: move ppe table - hash offset to mtk_soc_data structure -Date: Thu, 8 Sep 2022 21:33:38 +0200 -Message-Id: - -X-Mailer: git-send-email 2.37.3 -In-Reply-To: -References: -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -This is a preliminary patch to introduce mt7986 hw packet engine. - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++ - drivers/net/ethernet/mediatek/mtk_ppe.c | 24 +++++++++++++++------ - drivers/net/ethernet/mediatek/mtk_ppe.h | 2 +- - 4 files changed, 25 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4146,6 +4146,7 @@ static const struct mtk_soc_data mt7621_ - .required_clks = MT7621_CLKS_BITMAP, - .required_pctl = false, - .offload_version = 2, -+ .hash_offset = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4164,6 +4165,7 @@ static const struct mtk_soc_data mt7622_ - .required_clks = MT7622_CLKS_BITMAP, - .required_pctl = false, - .offload_version = 2, -+ .hash_offset = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4181,6 +4183,7 @@ static const struct mtk_soc_data mt7623_ - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, - .offload_version = 2, -+ .hash_offset = 2, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4214,6 +4217,7 @@ static const struct mtk_soc_data mt7986_ - .caps = MT7986_CAPS, - .required_clks = MT7986_CLKS_BITMAP, - .required_pctl = false, -+ .hash_offset = 4, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -967,6 +967,7 @@ struct mtk_reg_map { - * the target SoC - * @required_pctl A bool value to show whether the SoC requires - * the extra setup for those pins used by GMAC. -+ * @hash_offset Flow table hash offset. - * @txd_size Tx DMA descriptor size. - * @rxd_size Rx DMA descriptor size. - * @rx_irq_done_mask Rx irq done register mask. -@@ -981,6 +982,7 @@ struct mtk_soc_data { - u32 required_clks; - bool required_pctl; - u8 offload_version; -+ u8 hash_offset; - netdev_features_t hw_features; - struct { - u32 txd_size; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -88,7 +88,7 @@ static void mtk_ppe_cache_enable(struct - enable * MTK_PPE_CACHE_CTL_EN); - } - --static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e) -+static u32 mtk_ppe_hash_entry(struct mtk_eth *eth, struct mtk_foe_entry *e) - { - u32 hv1, hv2, hv3; - u32 hash; -@@ -122,7 +122,7 @@ static u32 mtk_ppe_hash_entry(struct mtk - hash = (hash >> 24) | ((hash & 0xffffff) << 8); - hash ^= hv1 ^ hv2 ^ hv3; - hash ^= hash >> 16; -- hash <<= 1; -+ hash <<= (ffs(eth->soc->hash_offset) - 1); - hash &= MTK_PPE_ENTRIES - 1; - - return hash; -@@ -540,15 +540,16 @@ mtk_foe_entry_commit_l2(struct mtk_ppe * - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); -+ const struct mtk_soc_data *soc = ppe->eth->soc; - u32 hash; - - if (type == MTK_PPE_PKT_TYPE_BRIDGE) - return mtk_foe_entry_commit_l2(ppe, entry); - -- hash = mtk_ppe_hash_entry(&entry->data); -+ hash = mtk_ppe_hash_entry(ppe->eth, &entry->data); - entry->hash = 0xffff; - spin_lock_bh(&ppe_lock); -- hlist_add_head(&entry->list, &ppe->foe_flow[hash / 2]); -+ hlist_add_head(&entry->list, &ppe->foe_flow[hash / soc->hash_offset]); - spin_unlock_bh(&ppe_lock); - - return 0; -@@ -558,6 +559,7 @@ static void - mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, - u16 hash) - { -+ const struct mtk_soc_data *soc = ppe->eth->soc; - struct mtk_flow_entry *flow_info; - struct mtk_foe_entry foe, *hwe; - struct mtk_foe_mac_info *l2; -@@ -572,7 +574,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ - flow_info->l2_data.base_flow = entry; - flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW; - flow_info->hash = hash; -- hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / 2]); -+ hlist_add_head(&flow_info->list, -+ &ppe->foe_flow[hash / soc->hash_offset]); - hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows); - - hwe = &ppe->foe_table[hash]; -@@ -596,7 +599,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) - { -- struct hlist_head *head = &ppe->foe_flow[hash / 2]; -+ const struct mtk_soc_data *soc = ppe->eth->soc; -+ struct hlist_head *head = &ppe->foe_flow[hash / soc->hash_offset]; - struct mtk_foe_entry *hwe = &ppe->foe_table[hash]; - struct mtk_flow_entry *entry; - struct mtk_foe_bridge key = {}; -@@ -680,9 +684,11 @@ int mtk_foe_entry_idle_time(struct mtk_p - struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, - int version) - { -+ const struct mtk_soc_data *soc = eth->soc; - struct device *dev = eth->dev; - struct mtk_foe_entry *foe; - struct mtk_ppe *ppe; -+ u32 foe_flow_size; - - ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL); - if (!ppe) -@@ -705,6 +711,12 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - - ppe->foe_table = foe; - -+ foe_flow_size = (MTK_PPE_ENTRIES / soc->hash_offset) * -+ sizeof(*ppe->foe_flow); -+ ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL); -+ if (!ppe->foe_flow) -+ return NULL; -+ - mtk_ppe_debugfs_init(ppe); - - return ppe; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -270,7 +270,7 @@ struct mtk_ppe { - dma_addr_t foe_phys; - - u16 foe_check_time[MTK_PPE_ENTRIES]; -- struct hlist_head foe_flow[MTK_PPE_ENTRIES / 2]; -+ struct hlist_head *foe_flow; - - struct rhashtable l2_flows; - diff --git a/target/linux/generic/backport-5.15/715-v6.0-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch b/target/linux/generic/backport-5.15/715-v6.0-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch deleted file mode 100644 index fb64da3d7a6a40..00000000000000 --- a/target/linux/generic/backport-5.15/715-v6.0-net-ethernet-mtk_eth_soc-add-the-capability-to-run-m.patch +++ /dev/null @@ -1,318 +0,0 @@ -From patchwork Thu Sep 8 19:33:39 2022 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Lorenzo Bianconi -X-Patchwork-Id: 12970559 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -From: Lorenzo Bianconi -To: netdev@vger.kernel.org -Cc: nbd@nbd.name, john@phrozen.org, sean.wang@mediatek.com, - Mark-MC.Lee@mediatek.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, matthias.bgg@gmail.com, - linux-mediatek@lists.infradead.org, lorenzo.bianconi@redhat.com, - Bo.Jiao@mediatek.com, sujuan.chen@mediatek.com, - ryder.Lee@mediatek.com, evelyn.tsai@mediatek.com, - devicetree@vger.kernel.org, robh@kernel.org -Subject: [PATCH net-next 05/12] net: ethernet: mtk_eth_soc: add the capability - to run multiple ppe -Date: Thu, 8 Sep 2022 21:33:39 +0200 -Message-Id: - -X-Mailer: git-send-email 2.37.3 -In-Reply-To: -References: -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -mt7986 chipset support multiple packet engines for wlan <-> eth -packet forwarding. - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 ++++++++++++------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +- - drivers/net/ethernet/mediatek/mtk_ppe.c | 14 +++++--- - drivers/net/ethernet/mediatek/mtk_ppe.h | 9 +++-- - .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 8 ++--- - .../net/ethernet/mediatek/mtk_ppe_offload.c | 13 +++---- - 6 files changed, 48 insertions(+), 33 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1871,7 +1871,7 @@ static int mtk_poll_rx(struct napi_struc - - reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); - if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -- mtk_ppe_check_skb(eth->ppe, skb, hash); -+ mtk_ppe_check_skb(eth->ppe[0], skb, hash); - - if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -@@ -2932,7 +2932,8 @@ static int mtk_open(struct net_device *d - /* we run 2 netdevs on the same dma ring so we only bring it up once */ - if (!refcount_read(ð->dma_refcnt)) { - const struct mtk_soc_data *soc = eth->soc; -- u32 gdm_config = MTK_GDMA_TO_PDMA; -+ u32 gdm_config; -+ int i; - int err; - - err = mtk_start_dma(eth); -@@ -2941,8 +2942,11 @@ static int mtk_open(struct net_device *d - return err; - } - -- if (soc->offload_version && mtk_ppe_start(eth->ppe) == 0) -- gdm_config = soc->reg_map->gdma_to_ppe0; -+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) -+ mtk_ppe_start(eth->ppe[i]); -+ -+ gdm_config = soc->offload_version ? soc->reg_map->gdma_to_ppe0 -+ : MTK_GDMA_TO_PDMA; - - mtk_gdm_config(eth, gdm_config); - -@@ -2987,6 +2991,7 @@ static int mtk_stop(struct net_device *d - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; -+ int i; - - phylink_stop(mac->phylink); - -@@ -3014,8 +3019,8 @@ static int mtk_stop(struct net_device *d - - mtk_dma_free(eth); - -- if (eth->soc->offload_version) -- mtk_ppe_stop(eth->ppe); -+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) -+ mtk_ppe_stop(eth->ppe[i]); - - return 0; - } -@@ -4048,12 +4053,19 @@ static int mtk_probe(struct platform_dev - } - - if (eth->soc->offload_version) { -- u32 ppe_addr = eth->soc->reg_map->ppe_base; -+ u32 num_ppe; - -- eth->ppe = mtk_ppe_init(eth, eth->base + ppe_addr, 2); -- if (!eth->ppe) { -- err = -ENOMEM; -- goto err_free_dev; -+ num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; -+ num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe); -+ for (i = 0; i < num_ppe; i++) { -+ u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; -+ -+ eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, -+ eth->soc->offload_version, i); -+ if (!eth->ppe[i]) { -+ err = -ENOMEM; -+ goto err_free_dev; -+ } - } - - err = mtk_eth_offload_init(eth); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1112,7 +1112,7 @@ struct mtk_eth { - - int ip_align; - -- struct mtk_ppe *ppe; -+ struct mtk_ppe *ppe[2]; - struct rhashtable flow_table; - - struct bpf_prog __rcu *prog; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -682,7 +682,7 @@ int mtk_foe_entry_idle_time(struct mtk_p - } - - struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, -- int version) -+ int version, int index) - { - const struct mtk_soc_data *soc = eth->soc; - struct device *dev = eth->dev; -@@ -717,7 +717,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - if (!ppe->foe_flow) - return NULL; - -- mtk_ppe_debugfs_init(ppe); -+ mtk_ppe_debugfs_init(ppe, index); - - return ppe; - } -@@ -738,10 +738,13 @@ static void mtk_ppe_init_foe_table(struc - ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC; - } - --int mtk_ppe_start(struct mtk_ppe *ppe) -+void mtk_ppe_start(struct mtk_ppe *ppe) - { - u32 val; - -+ if (!ppe) -+ return; -+ - mtk_ppe_init_foe_table(ppe); - ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys); - -@@ -809,8 +812,6 @@ int mtk_ppe_start(struct mtk_ppe *ppe) - ppe_w32(ppe, MTK_PPE_GLO_CFG, val); - - ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); -- -- return 0; - } - - int mtk_ppe_stop(struct mtk_ppe *ppe) -@@ -818,6 +819,9 @@ int mtk_ppe_stop(struct mtk_ppe *ppe) - u32 val; - int i; - -+ if (!ppe) -+ return 0; -+ - for (i = 0; i < MTK_PPE_ENTRIES; i++) - ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE, - MTK_FOE_STATE_INVALID); ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -247,6 +247,7 @@ struct mtk_flow_entry { - }; - u8 type; - s8 wed_index; -+ u8 ppe_index; - u16 hash; - union { - struct mtk_foe_entry data; -@@ -265,6 +266,7 @@ struct mtk_ppe { - struct device *dev; - void __iomem *base; - int version; -+ char dirname[5]; - - struct mtk_foe_entry *foe_table; - dma_addr_t foe_phys; -@@ -277,8 +279,9 @@ struct mtk_ppe { - void *acct_table; - }; - --struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version); --int mtk_ppe_start(struct mtk_ppe *ppe); -+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, -+ int version, int index); -+void mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); -@@ -317,6 +320,6 @@ int mtk_foe_entry_set_wdma(struct mtk_fo - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); --int mtk_ppe_debugfs_init(struct mtk_ppe *ppe); -+int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); - - #endif ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -187,7 +187,7 @@ mtk_ppe_debugfs_foe_open_bind(struct ino - inode->i_private); - } - --int mtk_ppe_debugfs_init(struct mtk_ppe *ppe) -+int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index) - { - static const struct file_operations fops_all = { - .open = mtk_ppe_debugfs_foe_open_all, -@@ -195,17 +195,17 @@ int mtk_ppe_debugfs_init(struct mtk_ppe - .llseek = seq_lseek, - .release = single_release, - }; -- - static const struct file_operations fops_bind = { - .open = mtk_ppe_debugfs_foe_open_bind, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - }; -- - struct dentry *root; - -- root = debugfs_create_dir("mtk_ppe", NULL); -+ snprintf(ppe->dirname, sizeof(ppe->dirname), "ppe%d", index); -+ -+ root = debugfs_create_dir(ppe->dirname, NULL); - if (!root) - return -ENOMEM; - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -434,7 +434,7 @@ mtk_flow_offload_replace(struct mtk_eth - memcpy(&entry->data, &foe, sizeof(entry->data)); - entry->wed_index = wed_index; - -- err = mtk_foe_entry_commit(eth->ppe, entry); -+ err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry); - if (err < 0) - goto free; - -@@ -446,7 +446,7 @@ mtk_flow_offload_replace(struct mtk_eth - return 0; - - clear: -- mtk_foe_entry_clear(eth->ppe, entry); -+ mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry); - free: - kfree(entry); - if (wed_index >= 0) -@@ -464,7 +464,7 @@ mtk_flow_offload_destroy(struct mtk_eth - if (!entry) - return -ENOENT; - -- mtk_foe_entry_clear(eth->ppe, entry); -+ mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry); - rhashtable_remove_fast(ð->flow_table, &entry->node, - mtk_flow_ht_params); - if (entry->wed_index >= 0) -@@ -485,7 +485,7 @@ mtk_flow_offload_stats(struct mtk_eth *e - if (!entry) - return -ENOENT; - -- idle = mtk_foe_entry_idle_time(eth->ppe, entry); -+ idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); - f->stats.lastused = jiffies - idle * HZ; - - return 0; -@@ -537,7 +537,7 @@ mtk_eth_setup_tc_block(struct net_device - struct flow_block_cb *block_cb; - flow_setup_cb_t *cb; - -- if (!eth->ppe || !eth->ppe->foe_table) -+ if (!eth->soc->offload_version) - return -EOPNOTSUPP; - - if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) -@@ -590,8 +590,5 @@ int mtk_eth_setup_tc(struct net_device * - - int mtk_eth_offload_init(struct mtk_eth *eth) - { -- if (!eth->ppe || !eth->ppe->foe_table) -- return 0; -- - return rhashtable_init(ð->flow_table, &mtk_flow_ht_params); - } diff --git a/target/linux/generic/backport-5.15/716-v6.0-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch b/target/linux/generic/backport-5.15/716-v6.0-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch deleted file mode 100644 index 6a58334c328ece..00000000000000 --- a/target/linux/generic/backport-5.15/716-v6.0-net-ethernet-mtk_eth_soc-move-wdma_base-definitions-.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0dcbe607cec32ccae23b02a641b8bd6191a328ae Mon Sep 17 00:00:00 2001 -Message-Id: <0dcbe607cec32ccae23b02a641b8bd6191a328ae.1662243796.git.lorenzo@kernel.org> -In-Reply-To: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org> -References: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org> -From: Lorenzo Bianconi -Date: Tue, 23 Aug 2022 23:09:05 +0200 -Subject: [PATCH net-next 2/4] net: ethernet: mtk_eth_soc: move wdma_base - definitions in mtk register map - -This is a preliminary patch to introduce mt7986 wed support. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 ++++++++++------ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 +--- - 2 files changed, 11 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -75,6 +75,10 @@ static const struct mtk_reg_map mtk_reg_ - .gdm1_cnt = 0x2400, - .gdma_to_ppe0 = 0x4444, - .ppe_base = 0x0c00, -+ .wdma_base = { -+ [0] = 0x2800, -+ [1] = 0x2c00, -+ }, - }; - - static const struct mtk_reg_map mt7628_reg_map = { -@@ -130,6 +134,10 @@ static const struct mtk_reg_map mt7986_r - .gdm1_cnt = 0x1c00, - .gdma_to_ppe0 = 0x3333, - .ppe_base = 0x2000, -+ .wdma_base = { -+ [0] = 0x4800, -+ [1] = 0x4c00, -+ }, - }; - - /* strings used by ethtool */ -@@ -3965,16 +3973,12 @@ static int mtk_probe(struct platform_dev - for (i = 0;; i++) { - struct device_node *np = of_parse_phandle(pdev->dev.of_node, - "mediatek,wed", i); -- static const u32 wdma_regs[] = { -- MTK_WDMA0_BASE, -- MTK_WDMA1_BASE -- }; - void __iomem *wdma; - -- if (!np || i >= ARRAY_SIZE(wdma_regs)) -+ if (!np || i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base)) - break; - -- wdma = eth->base + wdma_regs[i]; -+ wdma = eth->base + eth->soc->reg_map->wdma_base[i]; - mtk_wed_add_hw(np, eth, wdma, i); - } - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -268,9 +268,6 @@ - #define TX_DMA_FPORT_MASK_V2 0xf - #define TX_DMA_SWC_V2 BIT(30) - --#define MTK_WDMA0_BASE 0x2800 --#define MTK_WDMA1_BASE 0x2c00 -- - /* QDMA descriptor txd4 */ - #define TX_DMA_CHKSUM (0x7 << 29) - #define TX_DMA_TSO BIT(28) -@@ -954,6 +951,7 @@ struct mtk_reg_map { - u32 gdm1_cnt; - u32 gdma_to_ppe0; - u32 ppe_base; -+ u32 wdma_base[2]; - }; - - /* struct mtk_eth_data - This is the structure holding all differences diff --git a/target/linux/generic/backport-5.15/717-v6.0-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch b/target/linux/generic/backport-5.15/717-v6.0-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch deleted file mode 100644 index de1f21727204b5..00000000000000 --- a/target/linux/generic/backport-5.15/717-v6.0-net-ethernet-mtk_eth_soc-add-foe_entry_size-to-mtk_e.patch +++ /dev/null @@ -1,251 +0,0 @@ -From e3c27d869fccc1f2b8d0b4cde4763ab223874e8c Mon Sep 17 00:00:00 2001 -Message-Id: -In-Reply-To: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org> -References: <43a21841ce0175d29f23c34a65ceaaf9dd7eb8b7.1662243796.git.lorenzo@kernel.org> -From: Lorenzo Bianconi -Date: Sun, 21 Aug 2022 17:51:17 +0200 -Subject: [PATCH net-next 3/4] net: ethernet: mtk_eth_soc: add foe_entry_size - to mtk_eth_soc - -Introduce foe_entry_size to mtk_eth_soc data structure since mt7986 -relies on a bigger mtk_foe_entry data structure. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 + - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 ++++ - drivers/net/ethernet/mediatek/mtk_ppe.c | 55 +++++++++++-------- - drivers/net/ethernet/mediatek/mtk_ppe.h | 2 +- - .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +- - 5 files changed, 48 insertions(+), 24 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4163,6 +4163,7 @@ static const struct mtk_soc_data mt7621_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 2, -+ .foe_entry_size = sizeof(struct mtk_foe_entry), - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4182,6 +4183,7 @@ static const struct mtk_soc_data mt7622_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 2, -+ .foe_entry_size = sizeof(struct mtk_foe_entry), - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4200,6 +4202,7 @@ static const struct mtk_soc_data mt7623_ - .required_pctl = true, - .offload_version = 2, - .hash_offset = 2, -+ .foe_entry_size = sizeof(struct mtk_foe_entry), - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -966,6 +966,7 @@ struct mtk_reg_map { - * @required_pctl A bool value to show whether the SoC requires - * the extra setup for those pins used by GMAC. - * @hash_offset Flow table hash offset. -+ * @foe_entry_size Foe table entry size. - * @txd_size Tx DMA descriptor size. - * @rxd_size Rx DMA descriptor size. - * @rx_irq_done_mask Rx irq done register mask. -@@ -981,6 +982,7 @@ struct mtk_soc_data { - bool required_pctl; - u8 offload_version; - u8 hash_offset; -+ u16 foe_entry_size; - netdev_features_t hw_features; - struct { - u32 txd_size; -@@ -1141,6 +1143,14 @@ struct mtk_mac { - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ - extern const struct of_device_id of_mtk_match[]; - -+static inline struct mtk_foe_entry * -+mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) -+{ -+ const struct mtk_soc_data *soc = ppe->eth->soc; -+ -+ return ppe->foe_table + hash * soc->foe_entry_size; -+} -+ - /* read the hardware status register */ - void mtk_stats_update_mac(struct mtk_mac *mac); - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -410,9 +410,10 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - - hlist_del_init(&entry->list); - if (entry->hash != 0xffff) { -- ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE; -- ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, -- MTK_FOE_STATE_BIND); -+ struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); -+ -+ hwe->ib1 &= ~MTK_FOE_IB1_STATE; -+ hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND); - dma_wmb(); - } - entry->hash = 0xffff; -@@ -451,7 +452,7 @@ mtk_flow_entry_update_l2(struct mtk_ppe - int cur_idle; - u32 ib1; - -- hwe = &ppe->foe_table[cur->hash]; -+ hwe = mtk_foe_get_entry(ppe, cur->hash); - ib1 = READ_ONCE(hwe->ib1); - - if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) { -@@ -473,8 +474,8 @@ mtk_flow_entry_update_l2(struct mtk_ppe - static void - mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -+ struct mtk_foe_entry foe = {}; - struct mtk_foe_entry *hwe; -- struct mtk_foe_entry foe; - - spin_lock_bh(&ppe_lock); - -@@ -486,8 +487,8 @@ mtk_flow_entry_update(struct mtk_ppe *pp - if (entry->hash == 0xffff) - goto out; - -- hwe = &ppe->foe_table[entry->hash]; -- memcpy(&foe, hwe, sizeof(foe)); -+ hwe = mtk_foe_get_entry(ppe, entry->hash); -+ memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); - if (!mtk_flow_entry_match(entry, &foe)) { - entry->hash = 0xffff; - goto out; -@@ -511,8 +512,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; - entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp); - -- hwe = &ppe->foe_table[hash]; -- memcpy(&hwe->data, &entry->data, sizeof(hwe->data)); -+ hwe = mtk_foe_get_entry(ppe, hash); -+ memcpy(&hwe->data, &entry->data, ppe->eth->soc->foe_entry_size); - wmb(); - hwe->ib1 = entry->ib1; - -@@ -561,7 +562,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ - { - const struct mtk_soc_data *soc = ppe->eth->soc; - struct mtk_flow_entry *flow_info; -- struct mtk_foe_entry foe, *hwe; -+ struct mtk_foe_entry foe = {}, *hwe; - struct mtk_foe_mac_info *l2; - u32 ib1_mask = MTK_FOE_IB1_PACKET_TYPE | MTK_FOE_IB1_UDP; - int type; -@@ -578,8 +579,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ - &ppe->foe_flow[hash / soc->hash_offset]); - hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows); - -- hwe = &ppe->foe_table[hash]; -- memcpy(&foe, hwe, sizeof(foe)); -+ hwe = mtk_foe_get_entry(ppe, hash); -+ memcpy(&foe, hwe, soc->foe_entry_size); - foe.ib1 &= ib1_mask; - foe.ib1 |= entry->data.ib1 & ~ib1_mask; - -@@ -601,7 +602,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe - { - const struct mtk_soc_data *soc = ppe->eth->soc; - struct hlist_head *head = &ppe->foe_flow[hash / soc->hash_offset]; -- struct mtk_foe_entry *hwe = &ppe->foe_table[hash]; -+ struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash); - struct mtk_flow_entry *entry; - struct mtk_foe_bridge key = {}; - struct hlist_node *n; -@@ -686,9 +687,9 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - { - const struct mtk_soc_data *soc = eth->soc; - struct device *dev = eth->dev; -- struct mtk_foe_entry *foe; - struct mtk_ppe *ppe; - u32 foe_flow_size; -+ void *foe; - - ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL); - if (!ppe) -@@ -704,7 +705,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - ppe->dev = dev; - ppe->version = version; - -- foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe), -+ foe = dmam_alloc_coherent(ppe->dev, -+ MTK_PPE_ENTRIES * soc->foe_entry_size, - &ppe->foe_phys, GFP_KERNEL); - if (!foe) - return NULL; -@@ -727,15 +729,21 @@ static void mtk_ppe_init_foe_table(struc - static const u8 skip[] = { 12, 25, 38, 51, 76, 89, 102 }; - int i, k; - -- memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(*ppe->foe_table)); -+ memset(ppe->foe_table, 0, -+ MTK_PPE_ENTRIES * ppe->eth->soc->foe_entry_size); - - if (!IS_ENABLED(CONFIG_SOC_MT7621)) - return; - - /* skip all entries that cross the 1024 byte boundary */ -- for (i = 0; i < MTK_PPE_ENTRIES; i += 128) -- for (k = 0; k < ARRAY_SIZE(skip); k++) -- ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC; -+ for (i = 0; i < MTK_PPE_ENTRIES; i += 128) { -+ for (k = 0; k < ARRAY_SIZE(skip); k++) { -+ struct mtk_foe_entry *hwe; -+ -+ hwe = mtk_foe_get_entry(ppe, i + skip[k]); -+ hwe->ib1 |= MTK_FOE_IB1_STATIC; -+ } -+ } - } - - void mtk_ppe_start(struct mtk_ppe *ppe) -@@ -822,9 +830,12 @@ int mtk_ppe_stop(struct mtk_ppe *ppe) - if (!ppe) - return 0; - -- for (i = 0; i < MTK_PPE_ENTRIES; i++) -- ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE, -- MTK_FOE_STATE_INVALID); -+ for (i = 0; i < MTK_PPE_ENTRIES; i++) { -+ struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, i); -+ -+ hwe->ib1 = FIELD_PREP(MTK_FOE_IB1_STATE, -+ MTK_FOE_STATE_INVALID); -+ } - - mtk_ppe_cache_enable(ppe, false); - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -268,7 +268,7 @@ struct mtk_ppe { - int version; - char dirname[5]; - -- struct mtk_foe_entry *foe_table; -+ void *foe_table; - dma_addr_t foe_phys; - - u16 foe_check_time[MTK_PPE_ENTRIES]; ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -79,7 +79,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file - int i; - - for (i = 0; i < MTK_PPE_ENTRIES; i++) { -- struct mtk_foe_entry *entry = &ppe->foe_table[i]; -+ struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i); - struct mtk_foe_mac_info *l2; - struct mtk_flow_addr_info ai = {}; - unsigned char h_source[ETH_ALEN]; diff --git a/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch b/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch deleted file mode 100644 index 77daf6c8bfe4b0..00000000000000 --- a/target/linux/generic/backport-5.15/718-v6.0-net-ethernet-mtk_eth_soc-fix-typo-in-__mtk_foe_entry.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 12ff69304c83c679ca01ef3db963ab0db9de19fb Mon Sep 17 00:00:00 2001 -Message-Id: <12ff69304c83c679ca01ef3db963ab0db9de19fb.1662332102.git.lorenzo@kernel.org> -In-Reply-To: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> -References: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> -From: Lorenzo Bianconi -Date: Mon, 5 Sep 2022 00:43:43 +0200 -Subject: [PATCH net-next 2/6] net: ethernet: mtk_eth_soc: fix typo in - __mtk_foe_entry_clear - -Set ib1 state to MTK_FOE_STATE_UNBIND in __mtk_foe_entry_clear routine. - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -413,7 +413,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); - - hwe->ib1 &= ~MTK_FOE_IB1_STATE; -- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND); -+ hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_UNBIND); - dma_wmb(); - } - entry->hash = 0xffff; diff --git a/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch b/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch deleted file mode 100644 index 7ab6d486b2256e..00000000000000 --- a/target/linux/generic/backport-5.15/719-v6.0-net-ethernet-mtk_eth_soc-check-max-allowed-value-in-.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 4253e6e2b795a18ab534adcd5c313d3fc4150975 Mon Sep 17 00:00:00 2001 -Message-Id: <4253e6e2b795a18ab534adcd5c313d3fc4150975.1662332102.git.lorenzo@kernel.org> -In-Reply-To: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> -References: <2a60545635c2705312299384f4e9fec2f2a3acd6.1662332102.git.lorenzo@kernel.org> -From: Lorenzo Bianconi -Date: Mon, 5 Sep 2022 00:48:52 +0200 -Subject: [PATCH net-next 3/6] net: ethernet: mtk_eth_soc: check max allowed - value in mtk_ppe_check_skb - -Check theoretical OOB accesses in mtk_ppe_check_skb routine - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -294,6 +294,9 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s - if (!ppe) - return; - -+ if (hash > MTK_PPE_HASH_MASK) -+ return; -+ - now = (u16)jiffies; - diff = now - ppe->foe_check_time[hash]; - if (diff < HZ / 10) diff --git a/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch b/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch deleted file mode 100644 index a8c88daf1ffc7d..00000000000000 --- a/target/linux/generic/backport-5.15/720-v6.0-net-ethernet-mtk_eth_wed-add-mtk_wed_configure_irq-a.patch +++ /dev/null @@ -1,189 +0,0 @@ -From e5ecb4f619197b93fa682d722452dc8412864cdb Mon Sep 17 00:00:00 2001 -Message-Id: -From: Lorenzo Bianconi -Date: Fri, 26 Aug 2022 01:12:57 +0200 -Subject: [PATCH net-next 1/5] net: ethernet: mtk_eth_wed: add - mtk_wed_configure_irq and mtk_wed_dma_{enable/disable} - -Introduce mtk_wed_configure_irq, mtk_wed_dma_enable and mtk_wed_dma_disable -utility routines. -This is a preliminary patch to introduce mt7986 wed support. - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 87 +++++++++++++------- - drivers/net/ethernet/mediatek/mtk_wed_regs.h | 6 +- - 2 files changed, 64 insertions(+), 29 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -237,9 +237,30 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - } - - static void --mtk_wed_stop(struct mtk_wed_device *dev) -+mtk_wed_dma_disable(struct mtk_wed_device *dev) - { -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -+ -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); -+ -+ wed_clr(dev, MTK_WED_GLO_CFG, -+ MTK_WED_GLO_CFG_TX_DMA_EN | -+ MTK_WED_GLO_CFG_RX_DMA_EN); -+ - regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); -+ wdma_m32(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_TX_DMA_EN | -+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); -+} -+ -+static void -+mtk_wed_stop(struct mtk_wed_device *dev) -+{ -+ mtk_wed_dma_disable(dev); - mtk_wed_set_ext_int(dev, false); - - wed_clr(dev, MTK_WED_CTRL, -@@ -252,15 +273,6 @@ mtk_wed_stop(struct mtk_wed_device *dev) - wdma_w32(dev, MTK_WDMA_INT_MASK, 0); - wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); -- -- wed_clr(dev, MTK_WED_GLO_CFG, -- MTK_WED_GLO_CFG_TX_DMA_EN | -- MTK_WED_GLO_CFG_RX_DMA_EN); -- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, -- MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); - } - - static void -@@ -313,7 +325,10 @@ mtk_wed_hw_init_early(struct mtk_wed_dev - MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; - wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); - -- wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO_PRERES); -+ wdma_set(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); - - offset = dev->hw->index ? 0x04000400 : 0; - wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); -@@ -520,43 +535,38 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_d - } - - static void --mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) -+mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask) - { -- u32 wdma_mask; -- u32 val; -- int i; -- -- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -- if (!dev->tx_wdma[i].desc) -- mtk_wed_wdma_ring_setup(dev, i, 16); -- -- wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0)); -- -- mtk_wed_hw_init(dev); -+ u32 wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0)); - -+ /* wed control cr set */ - wed_set(dev, MTK_WED_CTRL, - MTK_WED_CTRL_WDMA_INT_AGENT_EN | - MTK_WED_CTRL_WPDMA_INT_AGENT_EN | - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - -- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, MTK_WED_PCIE_INT_TRIGGER_STATUS); -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, -+ MTK_WED_PCIE_INT_TRIGGER_STATUS); - - wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, - MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | - MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); - -- wed_set(dev, MTK_WED_WPDMA_INT_CTRL, -- MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); -- -+ /* initail wdma interrupt agent */ - wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask); - wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); - - wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask); - wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask); -- - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask); - wed_w32(dev, MTK_WED_INT_MASK, irq_mask); -+} -+ -+static void -+mtk_wed_dma_enable(struct mtk_wed_device *dev) -+{ -+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); - - wed_set(dev, MTK_WED_GLO_CFG, - MTK_WED_GLO_CFG_TX_DMA_EN | -@@ -567,6 +577,26 @@ mtk_wed_start(struct mtk_wed_device *dev - wed_set(dev, MTK_WED_WDMA_GLO_CFG, - MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); - -+ wdma_set(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_TX_DMA_EN | -+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -+} -+ -+static void -+mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) -+{ -+ u32 val; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -+ if (!dev->tx_wdma[i].desc) -+ mtk_wed_wdma_ring_setup(dev, i, 16); -+ -+ mtk_wed_hw_init(dev); -+ mtk_wed_configure_irq(dev, irq_mask); -+ - mtk_wed_set_ext_int(dev, true); - val = dev->wlan.wpdma_phys | - MTK_PCIE_MIRROR_MAP_EN | -@@ -577,6 +607,7 @@ mtk_wed_start(struct mtk_wed_device *dev - val |= BIT(0); - regmap_write(dev->hw->mirror, dev->hw->index * 4, val); - -+ mtk_wed_dma_enable(dev); - dev->running = true; - } - ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -224,7 +224,11 @@ struct mtk_wdma_desc { - #define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10) - - #define MTK_WDMA_GLO_CFG 0x204 --#define MTK_WDMA_GLO_CFG_RX_INFO_PRERES GENMASK(28, 26) -+#define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0) -+#define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2) -+#define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26) -+#define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27) -+#define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28) - - #define MTK_WDMA_RESET_IDX 0x208 - #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0) diff --git a/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch b/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch deleted file mode 100644 index 00255cdcf6d7ac..00000000000000 --- a/target/linux/generic/backport-5.15/721-v6.0-net-ethernet-mtk_eth_wed-add-wed-support-for-mt7986-.patch +++ /dev/null @@ -1,942 +0,0 @@ -From 463a71af080fbc77339bee2037fb1e081e3824f7 Mon Sep 17 00:00:00 2001 -Message-Id: <463a71af080fbc77339bee2037fb1e081e3824f7.1662886034.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Sat, 27 Aug 2022 16:15:14 +0200 -Subject: [PATCH net-next 2/5] net: ethernet: mtk_eth_wed: add wed support for - mt7986 chipset - -Introduce Wireless Etherne Dispatcher support on transmission side -for mt7986 chipset - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +- - drivers/net/ethernet/mediatek/mtk_wed.c | 371 ++++++++++++++---- - drivers/net/ethernet/mediatek/mtk_wed.h | 8 +- - .../net/ethernet/mediatek/mtk_wed_debugfs.c | 3 + - drivers/net/ethernet/mediatek/mtk_wed_regs.h | 81 +++- - include/linux/soc/mediatek/mtk_wed.h | 8 + - 6 files changed, 408 insertions(+), 97 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3890,6 +3890,7 @@ void mtk_eth_set_dma_device(struct mtk_e - - static int mtk_probe(struct platform_device *pdev) - { -+ struct resource *res = NULL; - struct device_node *mac_np; - struct mtk_eth *eth; - int err, i; -@@ -3970,16 +3971,31 @@ static int mtk_probe(struct platform_dev - } - } - -- for (i = 0;; i++) { -- struct device_node *np = of_parse_phandle(pdev->dev.of_node, -- "mediatek,wed", i); -- void __iomem *wdma; -- -- if (!np || i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base)) -- break; -- -- wdma = eth->base + eth->soc->reg_map->wdma_base[i]; -- mtk_wed_add_hw(np, eth, wdma, i); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -EINVAL; -+ } -+ -+ if (eth->soc->offload_version) { -+ for (i = 0;; i++) { -+ struct device_node *np; -+ phys_addr_t wdma_phy; -+ u32 wdma_base; -+ -+ if (i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base)) -+ break; -+ -+ np = of_parse_phandle(pdev->dev.of_node, -+ "mediatek,wed", i); -+ if (!np) -+ break; -+ -+ wdma_base = eth->soc->reg_map->wdma_base[i]; -+ wdma_phy = res ? res->start + wdma_base : 0; -+ mtk_wed_add_hw(np, eth, eth->base + wdma_base, -+ wdma_phy, i); -+ } - } - - for (i = 0; i < 3; i++) { ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -25,6 +25,11 @@ - - #define MTK_WED_TX_RING_SIZE 2048 - #define MTK_WED_WDMA_RING_SIZE 1024 -+#define MTK_WED_MAX_GROUP_SIZE 0x100 -+#define MTK_WED_VLD_GROUP_SIZE 0x40 -+#define MTK_WED_PER_GROUP_PKT 128 -+ -+#define MTK_WED_FBUF_SIZE 128 - - static struct mtk_wed_hw *hw_list[2]; - static DEFINE_MUTEX(hw_lock); -@@ -150,10 +155,17 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi - - desc->buf0 = cpu_to_le32(buf_phys); - desc->buf1 = cpu_to_le32(buf_phys + txd_size); -- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -- MTK_WED_BUF_SIZE - txd_size) | -- MTK_WDMA_DESC_CTRL_LAST_SEG1; -+ -+ if (dev->hw->version == 1) -+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -+ MTK_WED_BUF_SIZE - txd_size) | -+ MTK_WDMA_DESC_CTRL_LAST_SEG1; -+ else -+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2, -+ MTK_WED_BUF_SIZE - txd_size) | -+ MTK_WDMA_DESC_CTRL_LAST_SEG0; - desc->ctrl = cpu_to_le32(ctrl); - desc->info = 0; - desc++; -@@ -209,7 +221,7 @@ mtk_wed_free_ring(struct mtk_wed_device - if (!ring->desc) - return; - -- dma_free_coherent(dev->hw->dev, ring->size * sizeof(*ring->desc), -+ dma_free_coherent(dev->hw->dev, ring->size * ring->desc_size, - ring->desc, ring->desc_phys); - } - -@@ -229,6 +241,14 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - { - u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; - -+ if (dev->hw->version == 1) -+ mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; -+ else -+ mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -+ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | -+ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | -+ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; -+ - if (!dev->hw->num_flows) - mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; - -@@ -237,6 +257,20 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - } - - static void -+mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable) -+{ -+ if (enable) { -+ wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR); -+ wed_w32(dev, MTK_WED_TXP_DW1, -+ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0103)); -+ } else { -+ wed_w32(dev, MTK_WED_TXP_DW1, -+ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0100)); -+ wed_clr(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR); -+ } -+} -+ -+static void - mtk_wed_dma_disable(struct mtk_wed_device *dev) - { - wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -@@ -249,12 +283,22 @@ mtk_wed_dma_disable(struct mtk_wed_devic - MTK_WED_GLO_CFG_TX_DMA_EN | - MTK_WED_GLO_CFG_RX_DMA_EN); - -- regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); - wdma_m32(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_TX_DMA_EN | - MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0); -+ -+ if (dev->hw->version == 1) { -+ regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); -+ wdma_m32(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); -+ } else { -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -+ -+ mtk_wed_set_512_support(dev, false); -+ } - } - - static void -@@ -293,7 +337,7 @@ mtk_wed_detach(struct mtk_wed_device *de - mtk_wed_free_buffer(dev); - mtk_wed_free_tx_rings(dev); - -- if (of_dma_is_coherent(wlan_node)) -+ if (of_dma_is_coherent(wlan_node) && hw->hifsys) - regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, - BIT(hw->index), BIT(hw->index)); - -@@ -308,14 +352,69 @@ mtk_wed_detach(struct mtk_wed_device *de - mutex_unlock(&hw_lock); - } - -+#define PCIE_BASE_ADDR0 0x11280000 -+static void -+mtk_wed_bus_init(struct mtk_wed_device *dev) -+{ -+ struct device_node *np = dev->hw->eth->dev->of_node; -+ struct regmap *regs; -+ u32 val; -+ -+ regs = syscon_regmap_lookup_by_phandle(np, "mediatek,wed-pcie"); -+ if (IS_ERR(regs)) -+ return; -+ -+ regmap_update_bits(regs, 0, BIT(0), BIT(0)); -+ -+ wed_w32(dev, MTK_WED_PCIE_INT_CTRL, -+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); -+ -+ /* pcie interrupt control: pola/source selection */ -+ wed_set(dev, MTK_WED_PCIE_INT_CTRL, -+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | -+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); -+ wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -+ -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); -+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); -+ -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); -+ val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); -+ -+ /* pcie interrupt status trigger register */ -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); -+ wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); -+ -+ /* pola setting */ -+ val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -+ wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); -+} -+ -+static void -+mtk_wed_set_wpdma(struct mtk_wed_device *dev) -+{ -+ if (dev->hw->version == 1) { -+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); -+ } else { -+ mtk_wed_bus_init(dev); -+ -+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); -+ } -+} -+ - static void - mtk_wed_hw_init_early(struct mtk_wed_device *dev) - { - u32 mask, set; -- u32 offset; - - mtk_wed_stop(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); -+ mtk_wed_set_wpdma(dev); - - mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE | - MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE | -@@ -325,17 +424,33 @@ mtk_wed_hw_init_early(struct mtk_wed_dev - MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; - wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); - -- wdma_set(dev, MTK_WDMA_GLO_CFG, -- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -- -- offset = dev->hw->index ? 0x04000400 : 0; -- wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); -- wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset); -+ if (dev->hw->version == 1) { -+ u32 offset = dev->hw->index ? 0x04000400 : 0; - -- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, MTK_PCIE_BASE(dev->hw->index)); -- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); -+ wdma_set(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -+ -+ wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset); -+ wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset); -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, -+ MTK_PCIE_BASE(dev->hw->index)); -+ } else { -+ wed_w32(dev, MTK_WED_WDMA_CFG_BASE, dev->hw->wdma_phy); -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_ETH_DMAD_FMT); -+ wed_w32(dev, MTK_WED_WDMA_OFFSET0, -+ FIELD_PREP(MTK_WED_WDMA_OFST0_GLO_INTS, -+ MTK_WDMA_INT_STATUS) | -+ FIELD_PREP(MTK_WED_WDMA_OFST0_GLO_CFG, -+ MTK_WDMA_GLO_CFG)); -+ -+ wed_w32(dev, MTK_WED_WDMA_OFFSET1, -+ FIELD_PREP(MTK_WED_WDMA_OFST1_TX_CTRL, -+ MTK_WDMA_RING_TX(0)) | -+ FIELD_PREP(MTK_WED_WDMA_OFST1_RX_CTRL, -+ MTK_WDMA_RING_RX(0))); -+ } - } - - static void -@@ -355,37 +470,65 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys); - -- wed_w32(dev, MTK_WED_TX_BM_TKID, -- FIELD_PREP(MTK_WED_TX_BM_TKID_START, -- dev->wlan.token_start) | -- FIELD_PREP(MTK_WED_TX_BM_TKID_END, -- dev->wlan.token_start + dev->wlan.nbuf - 1)); -- - wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); - -- wed_w32(dev, MTK_WED_TX_BM_DYN_THR, -- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | -- MTK_WED_TX_BM_DYN_THR_HI); -+ if (dev->hw->version == 1) { -+ wed_w32(dev, MTK_WED_TX_BM_TKID, -+ FIELD_PREP(MTK_WED_TX_BM_TKID_START, -+ dev->wlan.token_start) | -+ FIELD_PREP(MTK_WED_TX_BM_TKID_END, -+ dev->wlan.token_start + -+ dev->wlan.nbuf - 1)); -+ wed_w32(dev, MTK_WED_TX_BM_DYN_THR, -+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | -+ MTK_WED_TX_BM_DYN_THR_HI); -+ } else { -+ wed_w32(dev, MTK_WED_TX_BM_TKID_V2, -+ FIELD_PREP(MTK_WED_TX_BM_TKID_START, -+ dev->wlan.token_start) | -+ FIELD_PREP(MTK_WED_TX_BM_TKID_END, -+ dev->wlan.token_start + -+ dev->wlan.nbuf - 1)); -+ wed_w32(dev, MTK_WED_TX_BM_DYN_THR, -+ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) | -+ MTK_WED_TX_BM_DYN_THR_HI_V2); -+ wed_w32(dev, MTK_WED_TX_TKID_CTRL, -+ MTK_WED_TX_TKID_CTRL_PAUSE | -+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM, -+ dev->buf_ring.size / 128) | -+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM, -+ dev->buf_ring.size / 128)); -+ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, -+ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | -+ MTK_WED_TX_TKID_DYN_THR_HI); -+ } - - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - -- wed_set(dev, MTK_WED_CTRL, -- MTK_WED_CTRL_WED_TX_BM_EN | -- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ if (dev->hw->version == 1) -+ wed_set(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WED_TX_BM_EN | -+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ else -+ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); - - wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); - } - - static void --mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size) -+mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size) - { -+ void *head = (void *)ring->desc; - int i; - - for (i = 0; i < size; i++) { -- desc[i].buf0 = 0; -- desc[i].ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -- desc[i].buf1 = 0; -- desc[i].info = 0; -+ struct mtk_wdma_desc *desc; -+ -+ desc = (struct mtk_wdma_desc *)(head + i * ring->desc_size); -+ desc->buf0 = 0; -+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ desc->buf1 = 0; -+ desc->info = 0; - } - } - -@@ -436,12 +579,10 @@ mtk_wed_reset_dma(struct mtk_wed_device - int i; - - for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) { -- struct mtk_wdma_desc *desc = dev->tx_ring[i].desc; -- -- if (!desc) -+ if (!dev->tx_ring[i].desc) - continue; - -- mtk_wed_ring_reset(desc, MTK_WED_TX_RING_SIZE); -+ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE); - } - - if (mtk_wed_poll_busy(dev)) -@@ -498,16 +639,16 @@ mtk_wed_reset_dma(struct mtk_wed_device - - static int - mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, -- int size) -+ int size, u32 desc_size) - { -- ring->desc = dma_alloc_coherent(dev->hw->dev, -- size * sizeof(*ring->desc), -+ ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size, - &ring->desc_phys, GFP_KERNEL); - if (!ring->desc) - return -ENOMEM; - -+ ring->desc_size = desc_size; - ring->size = size; -- mtk_wed_ring_reset(ring->desc, size); -+ mtk_wed_ring_reset(ring, size); - - return 0; - } -@@ -515,9 +656,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device - static int - mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size) - { -+ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; - struct mtk_wed_ring *wdma = &dev->tx_wdma[idx]; - -- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE)) -+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -@@ -546,16 +688,41 @@ mtk_wed_configure_irq(struct mtk_wed_dev - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - -- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, -- MTK_WED_PCIE_INT_TRIGGER_STATUS); -+ if (dev->hw->version == 1) { -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, -+ MTK_WED_PCIE_INT_TRIGGER_STATUS); -+ -+ wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, -+ MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | -+ MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); - -- wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, -- MTK_WED_WPDMA_INT_TRIGGER_RX_DONE | -- MTK_WED_WPDMA_INT_TRIGGER_TX_DONE); -+ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); -+ } else { -+ /* initail tx interrupt trigger */ -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, -+ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | -+ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR | -+ MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN | -+ MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG, -+ dev->wlan.tx_tbit[0]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG, -+ dev->wlan.tx_tbit[1])); -+ -+ /* initail txfree interrupt trigger */ -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX_FREE, -+ MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN | -+ MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG, -+ dev->wlan.txfree_tbit)); -+ -+ wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask); -+ wed_set(dev, MTK_WED_WDMA_INT_CTRL, -+ FIELD_PREP(MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL, -+ dev->wdma_idx)); -+ } - -- /* initail wdma interrupt agent */ - wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask); -- wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); - - wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask); - wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask); -@@ -580,14 +747,28 @@ mtk_wed_dma_enable(struct mtk_wed_device - wdma_set(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_TX_DMA_EN | - MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); -+ -+ if (dev->hw->version == 1) { -+ wdma_set(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -+ } else { -+ wed_set(dev, MTK_WED_WPDMA_CTRL, -+ MTK_WED_WPDMA_CTRL_SDL1_FIXED); -+ -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -+ -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | -+ MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); -+ } - } - - static void - mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) - { -- u32 val; - int i; - - for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -@@ -598,14 +779,17 @@ mtk_wed_start(struct mtk_wed_device *dev - mtk_wed_configure_irq(dev, irq_mask); - - mtk_wed_set_ext_int(dev, true); -- val = dev->wlan.wpdma_phys | -- MTK_PCIE_MIRROR_MAP_EN | -- FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, dev->hw->index); -- -- if (dev->hw->index) -- val |= BIT(1); -- val |= BIT(0); -- regmap_write(dev->hw->mirror, dev->hw->index * 4, val); -+ -+ if (dev->hw->version == 1) { -+ u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN | -+ FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, -+ dev->hw->index); -+ -+ val |= BIT(0) | (BIT(1) * !!dev->hw->index); -+ regmap_write(dev->hw->mirror, dev->hw->index * 4, val); -+ } else { -+ mtk_wed_set_512_support(dev, true); -+ } - - mtk_wed_dma_enable(dev); - dev->running = true; -@@ -639,7 +823,9 @@ mtk_wed_attach(struct mtk_wed_device *de - goto out; - } - -- dev_info(&dev->wlan.pci_dev->dev, "attaching wed device %d\n", hw->index); -+ dev_info(&dev->wlan.pci_dev->dev, -+ "attaching wed device %d version %d\n", -+ hw->index, hw->version); - - dev->hw = hw; - dev->dev = hw->dev; -@@ -657,7 +843,9 @@ mtk_wed_attach(struct mtk_wed_device *de - } - - mtk_wed_hw_init_early(dev); -- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, BIT(hw->index), 0); -+ if (hw->hifsys) -+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, -+ BIT(hw->index), 0); - - out: - mutex_unlock(&hw_lock); -@@ -684,7 +872,8 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - - BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring)); - -- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE)) -+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, -+ sizeof(*ring->desc))) - return -ENOMEM; - - if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -@@ -711,21 +900,21 @@ static int - mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs) - { - struct mtk_wed_ring *ring = &dev->txfree_ring; -- int i; -+ int i, index = dev->hw->version == 1; - - /* - * For txfree event handling, the same DMA ring is shared between WED - * and WLAN. The WLAN driver accesses the ring index registers through - * WED - */ -- ring->reg_base = MTK_WED_RING_RX(1); -+ ring->reg_base = MTK_WED_RING_RX(index); - ring->wpdma = regs; - - for (i = 0; i < 12; i += 4) { - u32 val = readl(regs + i); - -- wed_w32(dev, MTK_WED_RING_RX(1) + i, val); -- wed_w32(dev, MTK_WED_WPDMA_RING_RX(1) + i, val); -+ wed_w32(dev, MTK_WED_RING_RX(index) + i, val); -+ wed_w32(dev, MTK_WED_WPDMA_RING_RX(index) + i, val); - } - - return 0; -@@ -734,11 +923,19 @@ mtk_wed_txfree_ring_setup(struct mtk_wed - static u32 - mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) - { -- u32 val; -+ u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; -+ -+ if (dev->hw->version == 1) -+ ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; -+ else -+ ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -+ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | -+ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | -+ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; - - val = wed_r32(dev, MTK_WED_EXT_INT_STATUS); - wed_w32(dev, MTK_WED_EXT_INT_STATUS, val); -- val &= MTK_WED_EXT_INT_STATUS_ERROR_MASK; -+ val &= ext_mask; - if (!dev->hw->num_flows) - val &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; - if (val && net_ratelimit()) -@@ -813,7 +1010,8 @@ out: - } - - void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -- void __iomem *wdma, int index) -+ void __iomem *wdma, phys_addr_t wdma_phy, -+ int index) - { - static const struct mtk_wed_ops wed_ops = { - .attach = mtk_wed_attach, -@@ -860,26 +1058,33 @@ void mtk_wed_add_hw(struct device_node * - hw = kzalloc(sizeof(*hw), GFP_KERNEL); - if (!hw) - goto unlock; -+ - hw->node = np; - hw->regs = regs; - hw->eth = eth; - hw->dev = &pdev->dev; -+ hw->wdma_phy = wdma_phy; - hw->wdma = wdma; - hw->index = index; - hw->irq = irq; -- hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, -- "mediatek,pcie-mirror"); -- hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, -- "mediatek,hifsys"); -- if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) { -- kfree(hw); -- goto unlock; -- } -+ hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; - -- if (!index) { -- regmap_write(hw->mirror, 0, 0); -- regmap_write(hw->mirror, 4, 0); -+ if (hw->version == 1) { -+ hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, -+ "mediatek,pcie-mirror"); -+ hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, -+ "mediatek,hifsys"); -+ if (IS_ERR(hw->mirror) || IS_ERR(hw->hifsys)) { -+ kfree(hw); -+ goto unlock; -+ } -+ -+ if (!index) { -+ regmap_write(hw->mirror, 0, 0); -+ regmap_write(hw->mirror, 4, 0); -+ } - } -+ - mtk_wed_hw_add_debugfs(hw); - - hw_list[index] = hw; ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -18,11 +18,13 @@ struct mtk_wed_hw { - struct regmap *hifsys; - struct device *dev; - void __iomem *wdma; -+ phys_addr_t wdma_phy; - struct regmap *mirror; - struct dentry *debugfs_dir; - struct mtk_wed_device *wed_dev; - u32 debugfs_reg; - u32 num_flows; -+ u8 version; - char dirname[5]; - int irq; - int index; -@@ -101,14 +103,16 @@ wpdma_txfree_w32(struct mtk_wed_device * - } - - void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -- void __iomem *wdma, int index); -+ void __iomem *wdma, phys_addr_t wdma_phy, -+ int index); - void mtk_wed_exit(void); - int mtk_wed_flow_add(int index); - void mtk_wed_flow_remove(int index); - #else - static inline void - mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -- void __iomem *wdma, int index) -+ void __iomem *wdma, phys_addr_t wdma_phy, -+ int index) - { - } - static inline void ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -116,6 +116,9 @@ wed_txinfo_show(struct seq_file *s, void - DUMP_WDMA(WDMA_GLO_CFG), - DUMP_WDMA_RING(WDMA_RING_RX(0)), - DUMP_WDMA_RING(WDMA_RING_RX(1)), -+ -+ DUMP_STR("TX FREE"), -+ DUMP_WED(WED_RX_MIB(0)), - }; - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -5,6 +5,7 @@ - #define __MTK_WED_REGS_H - - #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0) -+#define MTK_WDMA_DESC_CTRL_LEN1_V2 GENMASK(13, 0) - #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15) - #define MTK_WDMA_DESC_CTRL_BURST BIT(16) - #define MTK_WDMA_DESC_CTRL_LEN0 GENMASK(29, 16) -@@ -41,6 +42,7 @@ struct mtk_wdma_desc { - #define MTK_WED_CTRL_RESERVE_EN BIT(12) - #define MTK_WED_CTRL_RESERVE_BUSY BIT(13) - #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24) -+#define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25) - #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28) - - #define MTK_WED_EXT_INT_STATUS 0x020 -@@ -57,7 +59,8 @@ struct mtk_wdma_desc { - #define MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN BIT(19) - #define MTK_WED_EXT_INT_STATUS_RX_DRV_BM_DMAD_COHERENT BIT(20) - #define MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR BIT(21) --#define MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR BIT(22) -+#define MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR BIT(22) -+#define MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR BIT(23) - #define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24) - #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \ - MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \ -@@ -65,8 +68,7 @@ struct mtk_wdma_desc { - MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR | \ - MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR | \ - MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN | \ -- MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR | \ -- MTK_WED_EXT_INT_STATUS_TX_DRV_W_RESP_ERR) -+ MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR) - - #define MTK_WED_EXT_INT_MASK 0x028 - -@@ -81,6 +83,7 @@ struct mtk_wdma_desc { - #define MTK_WED_TX_BM_BASE 0x084 - - #define MTK_WED_TX_BM_TKID 0x088 -+#define MTK_WED_TX_BM_TKID_V2 0x0c8 - #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0) - #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16) - -@@ -94,7 +97,25 @@ struct mtk_wdma_desc { - - #define MTK_WED_TX_BM_DYN_THR 0x0a0 - #define MTK_WED_TX_BM_DYN_THR_LO GENMASK(6, 0) -+#define MTK_WED_TX_BM_DYN_THR_LO_V2 GENMASK(8, 0) - #define MTK_WED_TX_BM_DYN_THR_HI GENMASK(22, 16) -+#define MTK_WED_TX_BM_DYN_THR_HI_V2 GENMASK(24, 16) -+ -+#define MTK_WED_TX_TKID_CTRL 0x0c0 -+#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM GENMASK(6, 0) -+#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16) -+#define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28) -+ -+#define MTK_WED_TX_TKID_DYN_THR 0x0e0 -+#define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0) -+#define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16) -+ -+#define MTK_WED_TXP_DW0 0x120 -+#define MTK_WED_TXP_DW1 0x124 -+#define MTK_WED_WPDMA_WRITE_TXP GENMASK(31, 16) -+#define MTK_WED_TXDP_CTRL 0x130 -+#define MTK_WED_TXDP_DW9_OVERWR BIT(9) -+#define MTK_WED_RX_BM_TKID_MIB 0x1cc - - #define MTK_WED_INT_STATUS 0x200 - #define MTK_WED_INT_MASK 0x204 -@@ -125,6 +146,7 @@ struct mtk_wdma_desc { - #define MTK_WED_RESET_IDX_RX GENMASK(17, 16) - - #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) -+#define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4) - - #define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10) - -@@ -155,21 +177,62 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_GLO_CFG_BYTE_SWAP BIT(29) - #define MTK_WED_WPDMA_GLO_CFG_RX_2B_OFFSET BIT(31) - -+/* CONFIG_MEDIATEK_NETSYS_V2 */ -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC BIT(4) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_PKT_PROC BIT(5) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC BIT(6) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_CRX_SYNC BIT(7) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(18, 16) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNSUPPORT_FMT BIT(19) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UEVENT_PKT_FMT_CHK BIT(20) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR BIT(21) -+#define MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP BIT(24) -+#define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28) -+ - #define MTK_WED_WPDMA_RESET_IDX 0x50c - #define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0) - #define MTK_WED_WPDMA_RESET_IDX_RX GENMASK(17, 16) - -+#define MTK_WED_WPDMA_CTRL 0x518 -+#define MTK_WED_WPDMA_CTRL_SDL1_FIXED BIT(31) -+ - #define MTK_WED_WPDMA_INT_CTRL 0x520 - #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21) - - #define MTK_WED_WPDMA_INT_MASK 0x524 - -+#define MTK_WED_WPDMA_INT_CTRL_TX 0x530 -+#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN BIT(0) -+#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_CLR BIT(1) -+#define MTK_WED_WPDMA_INT_CTRL_TX0_DONE_TRIG GENMASK(6, 2) -+#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_EN BIT(8) -+#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_CLR BIT(9) -+#define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10) -+ -+#define MTK_WED_WPDMA_INT_CTRL_RX 0x534 -+ -+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538 -+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0) -+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_CLR BIT(1) -+#define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG GENMASK(6, 2) -+ - #define MTK_WED_PCIE_CFG_BASE 0x560 - -+#define MTK_WED_PCIE_CFG_BASE 0x560 -+#define MTK_WED_PCIE_CFG_INTM 0x564 -+#define MTK_WED_PCIE_CFG_MSIS 0x568 - #define MTK_WED_PCIE_INT_TRIGGER 0x570 - #define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16) - -+#define MTK_WED_PCIE_INT_CTRL 0x57c -+#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20) -+#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16) -+#define MTK_WED_PCIE_INT_CTRL_POLL_EN GENMASK(13, 12) -+ - #define MTK_WED_WPDMA_CFG_BASE 0x580 -+#define MTK_WED_WPDMA_CFG_INT_MASK 0x584 -+#define MTK_WED_WPDMA_CFG_TX 0x588 -+#define MTK_WED_WPDMA_CFG_TX_FREE 0x58c - - #define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4) - #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4) -@@ -203,15 +266,24 @@ struct mtk_wdma_desc { - #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16) - #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24) - -+#define MTK_WED_WDMA_INT_CLR 0xa24 -+#define MTK_WED_WDMA_INT_CLR_RX_DONE GENMASK(17, 16) -+ - #define MTK_WED_WDMA_INT_TRIGGER 0xa28 - #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16) - - #define MTK_WED_WDMA_INT_CTRL 0xa2c - #define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16) - -+#define MTK_WED_WDMA_CFG_BASE 0xaa0 - #define MTK_WED_WDMA_OFFSET0 0xaa4 - #define MTK_WED_WDMA_OFFSET1 0xaa8 - -+#define MTK_WED_WDMA_OFST0_GLO_INTS GENMASK(15, 0) -+#define MTK_WED_WDMA_OFST0_GLO_CFG GENMASK(31, 16) -+#define MTK_WED_WDMA_OFST1_TX_CTRL GENMASK(15, 0) -+#define MTK_WED_WDMA_OFST1_RX_CTRL GENMASK(31, 16) -+ - #define MTK_WED_WDMA_RX_MIB(_n) (0xae0 + (_n) * 4) - #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4) - #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4) -@@ -221,6 +293,7 @@ struct mtk_wdma_desc { - #define MTK_WED_RING_OFS_CPU_IDX 0x08 - #define MTK_WED_RING_OFS_DMA_IDX 0x0c - -+#define MTK_WDMA_RING_TX(_n) (0x000 + (_n) * 0x10) - #define MTK_WDMA_RING_RX(_n) (0x100 + (_n) * 0x10) - - #define MTK_WDMA_GLO_CFG 0x204 -@@ -234,6 +307,8 @@ struct mtk_wdma_desc { - #define MTK_WDMA_RESET_IDX_TX GENMASK(3, 0) - #define MTK_WDMA_RESET_IDX_RX GENMASK(17, 16) - -+#define MTK_WDMA_INT_STATUS 0x220 -+ - #define MTK_WDMA_INT_MASK 0x228 - #define MTK_WDMA_INT_MASK_TX_DONE GENMASK(3, 0) - #define MTK_WDMA_INT_MASK_RX_DONE GENMASK(17, 16) ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -14,6 +14,7 @@ struct mtk_wdma_desc; - struct mtk_wed_ring { - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -+ u32 desc_size; - int size; - - u32 reg_base; -@@ -45,10 +46,17 @@ struct mtk_wed_device { - struct pci_dev *pci_dev; - - u32 wpdma_phys; -+ u32 wpdma_int; -+ u32 wpdma_mask; -+ u32 wpdma_tx; -+ u32 wpdma_txfree; - - u16 token_start; - unsigned int nbuf; - -+ u8 tx_tbit[MTK_WED_TX_QUEUES]; -+ u8 txfree_tbit; -+ - u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); - int (*offload_enable)(struct mtk_wed_device *wed); - void (*offload_disable)(struct mtk_wed_device *wed); diff --git a/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch b/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch deleted file mode 100644 index f4b78a279891a6..00000000000000 --- a/target/linux/generic/backport-5.15/722-v6.0-net-ethernet-mtk_eth_wed-add-axi-bus-support.patch +++ /dev/null @@ -1,230 +0,0 @@ -From 6e1df49f330dce7c58a39d6772f1385b6887bb03 Mon Sep 17 00:00:00 2001 -Message-Id: <6e1df49f330dce7c58a39d6772f1385b6887bb03.1662990860.git.lorenzo@kernel.org> -From: Lorenzo Bianconi -Date: Thu, 8 Sep 2022 11:26:10 +0200 -Subject: [PATCH net-next] net: ethernet: mtk_eth_wed: add axi bus support - -Other than pcie bus, introduce support for axi bus to mtk wed driver. -Axi bus is used to connect mt7986-wmac soc chip available on mt7986 -device. - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 116 +++++++++++++------ - drivers/net/ethernet/mediatek/mtk_wed_regs.h | 2 + - include/linux/soc/mediatek/mtk_wed.h | 11 +- - 3 files changed, 91 insertions(+), 38 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -85,11 +85,31 @@ static struct mtk_wed_hw * - mtk_wed_assign(struct mtk_wed_device *dev) - { - struct mtk_wed_hw *hw; -+ int i; -+ -+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { -+ hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)]; -+ if (!hw) -+ return NULL; -+ -+ if (!hw->wed_dev) -+ goto out; -+ -+ if (hw->version == 1) -+ return NULL; -+ -+ /* MT7986 WED devices do not have any pcie slot restrictions */ -+ } -+ /* MT7986 PCIE or AXI */ -+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { -+ hw = hw_list[i]; -+ if (hw && !hw->wed_dev) -+ goto out; -+ } - -- hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)]; -- if (!hw || hw->wed_dev) -- return NULL; -+ return NULL; - -+out: - hw->wed_dev = dev; - return hw; - } -@@ -322,7 +342,6 @@ mtk_wed_stop(struct mtk_wed_device *dev) - static void - mtk_wed_detach(struct mtk_wed_device *dev) - { -- struct device_node *wlan_node = dev->wlan.pci_dev->dev.of_node; - struct mtk_wed_hw *hw = dev->hw; - - mutex_lock(&hw_lock); -@@ -337,9 +356,14 @@ mtk_wed_detach(struct mtk_wed_device *de - mtk_wed_free_buffer(dev); - mtk_wed_free_tx_rings(dev); - -- if (of_dma_is_coherent(wlan_node) && hw->hifsys) -- regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, -- BIT(hw->index), BIT(hw->index)); -+ if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { -+ struct device_node *wlan_node; -+ -+ wlan_node = dev->wlan.pci_dev->dev.of_node; -+ if (of_dma_is_coherent(wlan_node) && hw->hifsys) -+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, -+ BIT(hw->index), BIT(hw->index)); -+ } - - if (!hw_list[!hw->index]->wed_dev && - hw->eth->dma_dev != hw->eth->dev) -@@ -356,40 +380,47 @@ mtk_wed_detach(struct mtk_wed_device *de - static void - mtk_wed_bus_init(struct mtk_wed_device *dev) - { -- struct device_node *np = dev->hw->eth->dev->of_node; -- struct regmap *regs; -- u32 val; -- -- regs = syscon_regmap_lookup_by_phandle(np, "mediatek,wed-pcie"); -- if (IS_ERR(regs)) -- return; -+ switch (dev->wlan.bus_type) { -+ case MTK_WED_BUS_PCIE: { -+ struct device_node *np = dev->hw->eth->dev->of_node; -+ struct regmap *regs; -+ -+ regs = syscon_regmap_lookup_by_phandle(np, -+ "mediatek,wed-pcie"); -+ if (IS_ERR(regs)) -+ break; - -- regmap_update_bits(regs, 0, BIT(0), BIT(0)); -+ regmap_update_bits(regs, 0, BIT(0), BIT(0)); - -- wed_w32(dev, MTK_WED_PCIE_INT_CTRL, -- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); -+ wed_w32(dev, MTK_WED_PCIE_INT_CTRL, -+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); - -- /* pcie interrupt control: pola/source selection */ -- wed_set(dev, MTK_WED_PCIE_INT_CTRL, -- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | -- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); -- wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -- -- val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); -- val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); -- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); -- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); -- -- val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM); -- val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE); -- -- /* pcie interrupt status trigger register */ -- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); -- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); -- -- /* pola setting */ -- val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -- wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); -+ /* pcie interrupt control: pola/source selection */ -+ wed_set(dev, MTK_WED_PCIE_INT_CTRL, -+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | -+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); -+ wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -+ -+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); -+ -+ /* pcie interrupt status trigger register */ -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); -+ wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); -+ -+ /* pola setting */ -+ wed_set(dev, MTK_WED_PCIE_INT_CTRL, -+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); -+ break; -+ } -+ case MTK_WED_BUS_AXI: -+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, -+ MTK_WED_WPDMA_INT_CTRL_SIG_SRC | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_SRC_SEL, 0)); -+ break; -+ default: -+ break; -+ } - } - - static void -@@ -800,12 +831,14 @@ mtk_wed_attach(struct mtk_wed_device *de - __releases(RCU) - { - struct mtk_wed_hw *hw; -+ struct device *device; - int ret = 0; - - RCU_LOCKDEP_WARN(!rcu_read_lock_held(), - "mtk_wed_attach without holding the RCU read lock"); - -- if (pci_domain_nr(dev->wlan.pci_dev->bus) > 1 || -+ if ((dev->wlan.bus_type == MTK_WED_BUS_PCIE && -+ pci_domain_nr(dev->wlan.pci_dev->bus) > 1) || - !try_module_get(THIS_MODULE)) - ret = -ENODEV; - -@@ -823,8 +856,10 @@ mtk_wed_attach(struct mtk_wed_device *de - goto out; - } - -- dev_info(&dev->wlan.pci_dev->dev, -- "attaching wed device %d version %d\n", -+ device = dev->wlan.bus_type == MTK_WED_BUS_PCIE -+ ? &dev->wlan.pci_dev->dev -+ : &dev->wlan.platform_dev->dev; -+ dev_info(device, "attaching wed device %d version %d\n", - hw->index, hw->version); - - dev->hw = hw; ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -198,6 +198,8 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_INT_CTRL 0x520 - #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV BIT(21) -+#define MTK_WED_WPDMA_INT_CTRL_SIG_SRC BIT(22) -+#define MTK_WED_WPDMA_INT_CTRL_SRC_SEL GENMASK(17, 16) - - #define MTK_WED_WPDMA_INT_MASK 0x524 - ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -11,6 +11,11 @@ - struct mtk_wed_hw; - struct mtk_wdma_desc; - -+enum mtk_wed_bus_tye { -+ MTK_WED_BUS_PCIE, -+ MTK_WED_BUS_AXI, -+}; -+ - struct mtk_wed_ring { - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -@@ -43,7 +48,11 @@ struct mtk_wed_device { - - /* filled by driver: */ - struct { -- struct pci_dev *pci_dev; -+ union { -+ struct platform_device *platform_dev; -+ struct pci_dev *pci_dev; -+ }; -+ enum mtk_wed_bus_tye bus_type; - - u32 wpdma_phys; - u32 wpdma_int; diff --git a/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch b/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch deleted file mode 100644 index 56d63b1e3502ae..00000000000000 --- a/target/linux/generic/backport-5.15/723-v6.0-net-ethernet-mtk_eth_soc-introduce-flow-offloading-s.patch +++ /dev/null @@ -1,882 +0,0 @@ -From 93408c858e5dc01d97c55efa721268f63fde2ae5 Mon Sep 17 00:00:00 2001 -Message-Id: <93408c858e5dc01d97c55efa721268f63fde2ae5.1662886034.git.lorenzo@kernel.org> -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Sat, 3 Sep 2022 18:34:09 +0200 -Subject: [PATCH net-next 4/5] net: ethernet: mtk_eth_soc: introduce flow - offloading support for mt7986 - -Introduce hw flow offload support for mt7986 chipset. PPE is not enabled -yet in mt7986 since mt76 support is not available yet. - -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 72 ++++++ - drivers/net/ethernet/mediatek/mtk_ppe.c | 213 +++++++++++------- - drivers/net/ethernet/mediatek/mtk_ppe.h | 52 ++++- - .../net/ethernet/mediatek/mtk_ppe_offload.c | 49 ++-- - drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 8 + - 6 files changed, 289 insertions(+), 116 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1858,12 +1858,14 @@ static int mtk_poll_rx(struct napi_struc - bytes += skb->len; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); - hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; - if (hash != MTK_RXD5_FOE_ENTRY) - skb_set_hash(skb, jhash_1word(hash, 0), - PKT_HASH_TYPE_L4); - rxdcsum = &trxd.rxd3; - } else { -+ reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); - hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY; - if (hash != MTK_RXD4_FOE_ENTRY) - skb_set_hash(skb, jhash_1word(hash, 0), -@@ -1877,7 +1879,6 @@ static int mtk_poll_rx(struct napi_struc - skb_checksum_none_assert(skb); - skb->protocol = eth_type_trans(skb, netdev); - -- reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4); - if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) - mtk_ppe_check_skb(eth->ppe[0], skb, hash); - -@@ -4179,7 +4180,7 @@ static const struct mtk_soc_data mt7621_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 2, -- .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4199,7 +4200,7 @@ static const struct mtk_soc_data mt7622_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 2, -- .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4218,7 +4219,7 @@ static const struct mtk_soc_data mt7623_ - .required_pctl = true, - .offload_version = 2, - .hash_offset = 2, -- .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4250,9 +4251,11 @@ static const struct mtk_soc_data mt7986_ - .reg_map = &mt7986_reg_map, - .ana_rgc3 = 0x128, - .caps = MT7986_CAPS, -+ .hw_features = MTK_HW_FEATURES, - .required_clks = MT7986_CLKS_BITMAP, - .required_pctl = false, - .hash_offset = 4, -+ .foe_entry_size = sizeof(struct mtk_foe_entry), - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1151,6 +1151,78 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u - return ppe->foe_table + hash * soc->foe_entry_size; - } - -+static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB1_BIND_TIMESTAMP_V2; -+ -+ return MTK_FOE_IB1_BIND_TIMESTAMP; -+} -+ -+static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB1_BIND_PPPOE_V2; -+ -+ return MTK_FOE_IB1_BIND_PPPOE; -+} -+ -+static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB1_BIND_VLAN_TAG_V2; -+ -+ return MTK_FOE_IB1_BIND_VLAN_TAG; -+} -+ -+static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB1_BIND_VLAN_LAYER_V2; -+ -+ return MTK_FOE_IB1_BIND_VLAN_LAYER; -+} -+ -+static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); -+ -+ return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val); -+} -+ -+static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); -+ -+ return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val); -+} -+ -+static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB1_PACKET_TYPE_V2; -+ -+ return MTK_FOE_IB1_PACKET_TYPE; -+} -+ -+static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val); -+ -+ return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val); -+} -+ -+static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth) -+{ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return MTK_FOE_IB2_MULTICAST_V2; -+ -+ return MTK_FOE_IB2_MULTICAST; -+} -+ - /* read the hardware status register */ - void mtk_stats_update_mac(struct mtk_mac *mac); - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -56,7 +56,7 @@ static u32 ppe_clear(struct mtk_ppe *ppe - - static u32 mtk_eth_timestamp(struct mtk_eth *eth) - { -- return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP; -+ return mtk_r32(eth, 0x0010) & mtk_get_ib1_ts_mask(eth); - } - - static int mtk_ppe_wait_busy(struct mtk_ppe *ppe) -@@ -93,7 +93,7 @@ static u32 mtk_ppe_hash_entry(struct mtk - u32 hv1, hv2, hv3; - u32 hash; - -- switch (FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, e->ib1)) { -+ switch (mtk_get_ib1_pkt_type(eth, e->ib1)) { - case MTK_PPE_PKT_TYPE_IPV4_ROUTE: - case MTK_PPE_PKT_TYPE_IPV4_HNAPT: - hv1 = e->ipv4.orig.ports; -@@ -129,9 +129,9 @@ static u32 mtk_ppe_hash_entry(struct mtk - } - - static inline struct mtk_foe_mac_info * --mtk_foe_entry_l2(struct mtk_foe_entry *entry) -+mtk_foe_entry_l2(struct mtk_eth *eth, struct mtk_foe_entry *entry) - { -- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); - - if (type == MTK_PPE_PKT_TYPE_BRIDGE) - return &entry->bridge.l2; -@@ -143,9 +143,9 @@ mtk_foe_entry_l2(struct mtk_foe_entry *e - } - - static inline u32 * --mtk_foe_entry_ib2(struct mtk_foe_entry *entry) -+mtk_foe_entry_ib2(struct mtk_eth *eth, struct mtk_foe_entry *entry) - { -- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); - - if (type == MTK_PPE_PKT_TYPE_BRIDGE) - return &entry->bridge.ib2; -@@ -156,27 +156,38 @@ mtk_foe_entry_ib2(struct mtk_foe_entry * - return &entry->ipv4.ib2; - } - --int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, -- u8 pse_port, u8 *src_mac, u8 *dest_mac) -+int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int type, int l4proto, u8 pse_port, u8 *src_mac, -+ u8 *dest_mac) - { - struct mtk_foe_mac_info *l2; - u32 ports_pad, val; - - memset(entry, 0, sizeof(*entry)); - -- val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | -- FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | -- FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | -- MTK_FOE_IB1_BIND_TTL | -- MTK_FOE_IB1_BIND_CACHE; -- entry->ib1 = val; -- -- val = FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | -- FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f) | -- FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | -+ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) | -+ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | -+ MTK_FOE_IB1_BIND_CACHE_V2 | MTK_FOE_IB1_BIND_TTL_V2; -+ entry->ib1 = val; -+ -+ val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, pse_port) | -+ FIELD_PREP(MTK_FOE_IB2_PORT_AG_V2, 0xf); -+ } else { -+ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | -+ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | -+ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | -+ MTK_FOE_IB1_BIND_CACHE | MTK_FOE_IB1_BIND_TTL; -+ entry->ib1 = val; -+ -+ val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port) | -+ FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | -+ FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f); -+ } - - if (is_multicast_ether_addr(dest_mac)) -- val |= MTK_FOE_IB2_MULTICAST; -+ val |= mtk_get_ib2_multicast_mask(eth); - - ports_pad = 0xa5a5a500 | (l4proto & 0xff); - if (type == MTK_PPE_PKT_TYPE_IPV4_ROUTE) -@@ -210,24 +221,30 @@ int mtk_foe_entry_prepare(struct mtk_foe - return 0; - } - --int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port) -+int mtk_foe_entry_set_pse_port(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, u8 port) - { -- u32 *ib2 = mtk_foe_entry_ib2(entry); -- u32 val; -+ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); -+ u32 val = *ib2; - -- val = *ib2; -- val &= ~MTK_FOE_IB2_DEST_PORT; -- val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ val &= ~MTK_FOE_IB2_DEST_PORT_V2; -+ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port); -+ } else { -+ val &= ~MTK_FOE_IB2_DEST_PORT; -+ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port); -+ } - *ib2 = val; - - return 0; - } - --int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool egress, -+int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, bool egress, - __be32 src_addr, __be16 src_port, - __be32 dest_addr, __be16 dest_port) - { -- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); - struct mtk_ipv4_tuple *t; - - switch (type) { -@@ -262,11 +279,12 @@ int mtk_foe_entry_set_ipv4_tuple(struct - return 0; - } - --int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry, -+int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, - __be32 *src_addr, __be16 src_port, - __be32 *dest_addr, __be16 dest_port) - { -- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); - u32 *src, *dest; - int i; - -@@ -297,39 +315,41 @@ int mtk_foe_entry_set_ipv6_tuple(struct - return 0; - } - --int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port) -+int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int port) - { -- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); -+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - - l2->etype = BIT(port); - -- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER)) -- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); -+ if (!(entry->ib1 & mtk_get_ib1_vlan_layer_mask(eth))) -+ entry->ib1 |= mtk_prep_ib1_vlan_layer(eth, 1); - else - l2->etype |= BIT(8); - -- entry->ib1 &= ~MTK_FOE_IB1_BIND_VLAN_TAG; -+ entry->ib1 &= ~mtk_get_ib1_vlan_tag_mask(eth); - - return 0; - } - --int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid) -+int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int vid) - { -- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); -+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - -- switch (FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, entry->ib1)) { -+ switch (mtk_prep_ib1_vlan_layer(eth, entry->ib1)) { - case 0: -- entry->ib1 |= MTK_FOE_IB1_BIND_VLAN_TAG | -- FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); -+ entry->ib1 |= mtk_get_ib1_vlan_tag_mask(eth) | -+ mtk_prep_ib1_vlan_layer(eth, 1); - l2->vlan1 = vid; - return 0; - case 1: -- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) { -+ if (!(entry->ib1 & mtk_get_ib1_vlan_tag_mask(eth))) { - l2->vlan1 = vid; - l2->etype |= BIT(8); - } else { - l2->vlan2 = vid; -- entry->ib1 += FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); -+ entry->ib1 += mtk_prep_ib1_vlan_layer(eth, 1); - } - return 0; - default: -@@ -337,34 +357,42 @@ int mtk_foe_entry_set_vlan(struct mtk_fo - } - } - --int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid) -+int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int sid) - { -- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); -+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - -- if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER) || -- (entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) -+ if (!(entry->ib1 & mtk_get_ib1_vlan_layer_mask(eth)) || -+ (entry->ib1 & mtk_get_ib1_vlan_tag_mask(eth))) - l2->etype = ETH_P_PPP_SES; - -- entry->ib1 |= MTK_FOE_IB1_BIND_PPPOE; -+ entry->ib1 |= mtk_get_ib1_ppoe_mask(eth); - l2->pppoe_id = sid; - - return 0; - } - --int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, -- int bss, int wcid) -+int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int wdma_idx, int txq, int bss, int wcid) - { -- struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); -- u32 *ib2 = mtk_foe_entry_ib2(entry); -+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); -+ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); - -- *ib2 &= ~MTK_FOE_IB2_PORT_MG; -- *ib2 |= MTK_FOE_IB2_WDMA_WINFO; -- if (wdma_idx) -- *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX; -- -- l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | -- FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | -- FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; -+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | -+ MTK_FOE_IB2_WDMA_WINFO_V2; -+ l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) | -+ FIELD_PREP(MTK_FOE_WINFO_BSS, bss); -+ } else { -+ *ib2 &= ~MTK_FOE_IB2_PORT_MG; -+ *ib2 |= MTK_FOE_IB2_WDMA_WINFO; -+ if (wdma_idx) -+ *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX; -+ l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | -+ FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | -+ FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); -+ } - - return 0; - } -@@ -376,14 +404,15 @@ static inline bool mtk_foe_entry_usable( - } - - static bool --mtk_flow_entry_match(struct mtk_flow_entry *entry, struct mtk_foe_entry *data) -+mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, -+ struct mtk_foe_entry *data) - { - int type, len; - - if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP) - return false; - -- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); -+ type = mtk_get_ib1_pkt_type(eth, entry->data.ib1); - if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) - len = offsetof(struct mtk_foe_entry, ipv6._rsv); - else -@@ -427,14 +456,12 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - - static int __mtk_foe_entry_idle_time(struct mtk_ppe *ppe, u32 ib1) - { -- u16 timestamp; -- u16 now; -- -- now = mtk_eth_timestamp(ppe->eth) & MTK_FOE_IB1_BIND_TIMESTAMP; -- timestamp = ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; -+ u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); -+ u16 now = mtk_eth_timestamp(ppe->eth); -+ u16 timestamp = ib1 & ib1_ts_mask; - - if (timestamp > now) -- return MTK_FOE_IB1_BIND_TIMESTAMP + 1 - timestamp + now; -+ return ib1_ts_mask + 1 - timestamp + now; - else - return now - timestamp; - } -@@ -442,6 +469,7 @@ static int __mtk_foe_entry_idle_time(str - static void - mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -+ u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); - struct mtk_flow_entry *cur; - struct mtk_foe_entry *hwe; - struct hlist_node *tmp; -@@ -466,8 +494,8 @@ mtk_flow_entry_update_l2(struct mtk_ppe - continue; - - idle = cur_idle; -- entry->data.ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; -- entry->data.ib1 |= hwe->ib1 & MTK_FOE_IB1_BIND_TIMESTAMP; -+ entry->data.ib1 &= ~ib1_ts_mask; -+ entry->data.ib1 |= hwe->ib1 & ib1_ts_mask; - } - } - -@@ -489,7 +517,7 @@ mtk_flow_entry_update(struct mtk_ppe *pp - - hwe = mtk_foe_get_entry(ppe, entry->hash); - memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); -- if (!mtk_flow_entry_match(entry, &foe)) { -+ if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) { - entry->hash = 0xffff; - goto out; - } -@@ -504,16 +532,22 @@ static void - __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - u16 hash) - { -+ struct mtk_eth *eth = ppe->eth; -+ u16 timestamp = mtk_eth_timestamp(eth); - struct mtk_foe_entry *hwe; -- u16 timestamp; - -- timestamp = mtk_eth_timestamp(ppe->eth); -- timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP; -- entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; -- entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; -+ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2, -+ timestamp); -+ } else { -+ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; -+ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, -+ timestamp); -+ } - - hwe = mtk_foe_get_entry(ppe, hash); -- memcpy(&hwe->data, &entry->data, ppe->eth->soc->foe_entry_size); -+ memcpy(&hwe->data, &entry->data, eth->soc->foe_entry_size); - wmb(); - hwe->ib1 = entry->ib1; - -@@ -540,8 +574,8 @@ mtk_foe_entry_commit_l2(struct mtk_ppe * - - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -- int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1); - const struct mtk_soc_data *soc = ppe->eth->soc; -+ int type = mtk_get_ib1_pkt_type(ppe->eth, entry->data.ib1); - u32 hash; - - if (type == MTK_PPE_PKT_TYPE_BRIDGE) -@@ -564,7 +598,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ - struct mtk_flow_entry *flow_info; - struct mtk_foe_entry foe = {}, *hwe; - struct mtk_foe_mac_info *l2; -- u32 ib1_mask = MTK_FOE_IB1_PACKET_TYPE | MTK_FOE_IB1_UDP; -+ u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; - int type; - - flow_info = kzalloc(offsetof(struct mtk_flow_entry, l2_data.end), -@@ -584,16 +618,16 @@ mtk_foe_entry_commit_subflow(struct mtk_ - foe.ib1 &= ib1_mask; - foe.ib1 |= entry->data.ib1 & ~ib1_mask; - -- l2 = mtk_foe_entry_l2(&foe); -+ l2 = mtk_foe_entry_l2(ppe->eth, &foe); - memcpy(l2, &entry->data.bridge.l2, sizeof(*l2)); - -- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, foe.ib1); -+ type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1); - if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT) - memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new)); - else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP) - l2->etype = ETH_P_IPV6; - -- *mtk_foe_entry_ib2(&foe) = entry->data.bridge.ib2; -+ *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2; - - __mtk_foe_entry_commit(ppe, &foe, hash); - } -@@ -626,7 +660,7 @@ void __mtk_ppe_check_skb(struct mtk_ppe - continue; - } - -- if (found || !mtk_flow_entry_match(entry, hwe)) { -+ if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) { - if (entry->hash != 0xffff) - entry->hash = 0xffff; - continue; -@@ -771,6 +805,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_SCAN_MODE_CHECK_AGE) | - FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, - MTK_PPE_ENTRIES_SHIFT); -+ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) -+ val |= MTK_PPE_TB_CFG_INFO_SEL; - ppe_w32(ppe, MTK_PPE_TB_CFG, val); - - ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK, -@@ -778,15 +814,21 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - - mtk_ppe_cache_enable(ppe, true); - -- val = MTK_PPE_FLOW_CFG_IP4_TCP_FRAG | -- MTK_PPE_FLOW_CFG_IP4_UDP_FRAG | -- MTK_PPE_FLOW_CFG_IP6_3T_ROUTE | -+ val = MTK_PPE_FLOW_CFG_IP6_3T_ROUTE | - MTK_PPE_FLOW_CFG_IP6_5T_ROUTE | - MTK_PPE_FLOW_CFG_IP6_6RD | - MTK_PPE_FLOW_CFG_IP4_NAT | - MTK_PPE_FLOW_CFG_IP4_NAPT | - MTK_PPE_FLOW_CFG_IP4_DSLITE | - MTK_PPE_FLOW_CFG_IP4_NAT_FRAG; -+ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) -+ val |= MTK_PPE_MD_TOAP_BYP_CRSN0 | -+ MTK_PPE_MD_TOAP_BYP_CRSN1 | -+ MTK_PPE_MD_TOAP_BYP_CRSN2 | -+ MTK_PPE_FLOW_CFG_IP4_HASH_GRE_KEY; -+ else -+ val |= MTK_PPE_FLOW_CFG_IP4_TCP_FRAG | -+ MTK_PPE_FLOW_CFG_IP4_UDP_FRAG; - ppe_w32(ppe, MTK_PPE_FLOW_CFG, val); - - val = FIELD_PREP(MTK_PPE_UNBIND_AGE_MIN_PACKETS, 1000) | -@@ -820,6 +862,11 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - ppe_w32(ppe, MTK_PPE_GLO_CFG, val); - - ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); -+ -+ if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) { -+ ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); -+ ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); -+ } - } - - int mtk_ppe_stop(struct mtk_ppe *ppe) ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -32,6 +32,15 @@ - #define MTK_FOE_IB1_UDP BIT(30) - #define MTK_FOE_IB1_STATIC BIT(31) - -+/* CONFIG_MEDIATEK_NETSYS_V2 */ -+#define MTK_FOE_IB1_BIND_TIMESTAMP_V2 GENMASK(7, 0) -+#define MTK_FOE_IB1_BIND_VLAN_LAYER_V2 GENMASK(16, 14) -+#define MTK_FOE_IB1_BIND_PPPOE_V2 BIT(17) -+#define MTK_FOE_IB1_BIND_VLAN_TAG_V2 BIT(18) -+#define MTK_FOE_IB1_BIND_CACHE_V2 BIT(20) -+#define MTK_FOE_IB1_BIND_TTL_V2 BIT(22) -+#define MTK_FOE_IB1_PACKET_TYPE_V2 GENMASK(27, 23) -+ - enum { - MTK_PPE_PKT_TYPE_IPV4_HNAPT = 0, - MTK_PPE_PKT_TYPE_IPV4_ROUTE = 1, -@@ -53,14 +62,25 @@ enum { - - #define MTK_FOE_IB2_PORT_MG GENMASK(17, 12) - -+#define MTK_FOE_IB2_RX_IDX GENMASK(18, 17) - #define MTK_FOE_IB2_PORT_AG GENMASK(23, 18) - - #define MTK_FOE_IB2_DSCP GENMASK(31, 24) - -+/* CONFIG_MEDIATEK_NETSYS_V2 */ -+#define MTK_FOE_IB2_PORT_MG_V2 BIT(7) -+#define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9) -+#define MTK_FOE_IB2_MULTICAST_V2 BIT(13) -+#define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19) -+#define MTK_FOE_IB2_PORT_AG_V2 GENMASK(23, 20) -+ - #define MTK_FOE_VLAN2_WINFO_BSS GENMASK(5, 0) - #define MTK_FOE_VLAN2_WINFO_WCID GENMASK(13, 6) - #define MTK_FOE_VLAN2_WINFO_RING GENMASK(15, 14) - -+#define MTK_FOE_WINFO_BSS GENMASK(5, 0) -+#define MTK_FOE_WINFO_WCID GENMASK(15, 6) -+ - enum { - MTK_FOE_STATE_INVALID, - MTK_FOE_STATE_UNBIND, -@@ -81,6 +101,9 @@ struct mtk_foe_mac_info { - - u16 pppoe_id; - u16 src_mac_lo; -+ -+ u16 minfo; -+ u16 winfo; - }; - - /* software-only entry type */ -@@ -198,7 +221,7 @@ struct mtk_foe_entry { - struct mtk_foe_ipv4_dslite dslite; - struct mtk_foe_ipv6 ipv6; - struct mtk_foe_ipv6_6rd ipv6_6rd; -- u32 data[19]; -+ u32 data[23]; - }; - }; - -@@ -306,20 +329,27 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, s - __mtk_ppe_check_skb(ppe, skb, hash); - } - --int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, -- u8 pse_port, u8 *src_mac, u8 *dest_mac); --int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port); --int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool orig, -+int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int type, int l4proto, u8 pse_port, u8 *src_mac, -+ u8 *dest_mac); -+int mtk_foe_entry_set_pse_port(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, u8 port); -+int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, bool orig, - __be32 src_addr, __be16 src_port, - __be32 dest_addr, __be16 dest_port); --int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry, -+int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth, -+ struct mtk_foe_entry *entry, - __be32 *src_addr, __be16 src_port, - __be32 *dest_addr, __be16 dest_port); --int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port); --int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid); --int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid); --int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq, -- int bss, int wcid); -+int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int port); -+int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int vid); -+int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int sid); -+int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ int wdma_idx, int txq, int bss, int wcid); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -52,18 +52,19 @@ static const struct rhashtable_params mt - }; - - static int --mtk_flow_set_ipv4_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data, -- bool egress) -+mtk_flow_set_ipv4_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe, -+ struct mtk_flow_data *data, bool egress) - { -- return mtk_foe_entry_set_ipv4_tuple(foe, egress, -+ return mtk_foe_entry_set_ipv4_tuple(eth, foe, egress, - data->v4.src_addr, data->src_port, - data->v4.dst_addr, data->dst_port); - } - - static int --mtk_flow_set_ipv6_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data) -+mtk_flow_set_ipv6_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe, -+ struct mtk_flow_data *data) - { -- return mtk_foe_entry_set_ipv6_tuple(foe, -+ return mtk_foe_entry_set_ipv6_tuple(eth, foe, - data->v6.src_addr.s6_addr32, data->src_port, - data->v6.dst_addr.s6_addr32, data->dst_port); - } -@@ -190,16 +191,29 @@ mtk_flow_set_output_device(struct mtk_et - int pse_port, dsa_port; - - if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { -- mtk_foe_entry_set_wdma(foe, info.wdma_idx, info.queue, info.bss, -- info.wcid); -- pse_port = 3; -+ mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, -+ info.bss, info.wcid); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ switch (info.wdma_idx) { -+ case 0: -+ pse_port = 8; -+ break; -+ case 1: -+ pse_port = 9; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } else { -+ pse_port = 3; -+ } - *wed_index = info.wdma_idx; - goto out; - } - - dsa_port = mtk_flow_get_dsa_port(&dev); - if (dsa_port >= 0) -- mtk_foe_entry_set_dsa(foe, dsa_port); -+ mtk_foe_entry_set_dsa(eth, foe, dsa_port); - - if (dev == eth->netdev[0]) - pse_port = 1; -@@ -209,7 +223,7 @@ mtk_flow_set_output_device(struct mtk_et - return -EOPNOTSUPP; - - out: -- mtk_foe_entry_set_pse_port(foe, pse_port); -+ mtk_foe_entry_set_pse_port(eth, foe, pse_port); - - return 0; - } -@@ -333,9 +347,8 @@ mtk_flow_offload_replace(struct mtk_eth - !is_valid_ether_addr(data.eth.h_dest)) - return -EINVAL; - -- err = mtk_foe_entry_prepare(&foe, offload_type, l4proto, 0, -- data.eth.h_source, -- data.eth.h_dest); -+ err = mtk_foe_entry_prepare(eth, &foe, offload_type, l4proto, 0, -+ data.eth.h_source, data.eth.h_dest); - if (err) - return err; - -@@ -360,7 +373,7 @@ mtk_flow_offload_replace(struct mtk_eth - data.v4.src_addr = addrs.key->src; - data.v4.dst_addr = addrs.key->dst; - -- mtk_flow_set_ipv4_addr(&foe, &data, false); -+ mtk_flow_set_ipv4_addr(eth, &foe, &data, false); - } - - if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { -@@ -371,7 +384,7 @@ mtk_flow_offload_replace(struct mtk_eth - data.v6.src_addr = addrs.key->src; - data.v6.dst_addr = addrs.key->dst; - -- mtk_flow_set_ipv6_addr(&foe, &data); -+ mtk_flow_set_ipv6_addr(eth, &foe, &data); - } - - flow_action_for_each(i, act, &rule->action) { -@@ -401,7 +414,7 @@ mtk_flow_offload_replace(struct mtk_eth - } - - if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { -- err = mtk_flow_set_ipv4_addr(&foe, &data, true); -+ err = mtk_flow_set_ipv4_addr(eth, &foe, &data, true); - if (err) - return err; - } -@@ -413,10 +426,10 @@ mtk_flow_offload_replace(struct mtk_eth - if (data.vlan.proto != htons(ETH_P_8021Q)) - return -EOPNOTSUPP; - -- mtk_foe_entry_set_vlan(&foe, data.vlan.id); -+ mtk_foe_entry_set_vlan(eth, &foe, data.vlan.id); - } - if (data.pppoe.num == 1) -- mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid); -+ mtk_foe_entry_set_pppoe(eth, &foe, data.pppoe.sid); - - err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest, - &wed_index); ---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -@@ -21,6 +21,9 @@ - #define MTK_PPE_GLO_CFG_BUSY BIT(31) - - #define MTK_PPE_FLOW_CFG 0x204 -+#define MTK_PPE_MD_TOAP_BYP_CRSN0 BIT(1) -+#define MTK_PPE_MD_TOAP_BYP_CRSN1 BIT(2) -+#define MTK_PPE_MD_TOAP_BYP_CRSN2 BIT(3) - #define MTK_PPE_FLOW_CFG_IP4_TCP_FRAG BIT(6) - #define MTK_PPE_FLOW_CFG_IP4_UDP_FRAG BIT(7) - #define MTK_PPE_FLOW_CFG_IP6_3T_ROUTE BIT(8) -@@ -54,6 +57,7 @@ - #define MTK_PPE_TB_CFG_HASH_MODE GENMASK(15, 14) - #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16) - #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18) -+#define MTK_PPE_TB_CFG_INFO_SEL BIT(20) - - enum { - MTK_PPE_SCAN_MODE_DISABLED, -@@ -112,6 +116,8 @@ enum { - #define MTK_PPE_DEFAULT_CPU_PORT 0x248 - #define MTK_PPE_DEFAULT_CPU_PORT_MASK(_n) (GENMASK(2, 0) << ((_n) * 4)) - -+#define MTK_PPE_DEFAULT_CPU_PORT1 0x24c -+ - #define MTK_PPE_MTU_DROP 0x308 - - #define MTK_PPE_VLAN_MTU0 0x30c -@@ -141,4 +147,6 @@ enum { - #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) - #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) - -+#define MTK_PPE_SBW_CTRL 0x374 -+ - #endif diff --git a/target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-fix-wrong-use-of-new-helper.patch b/target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-fix-wrong-use-of-new-helper.patch deleted file mode 100644 index c4bd29365c7ad3..00000000000000 --- a/target/linux/generic/backport-5.15/724-v6.0-net-ethernet-mtk_eth_soc-fix-wrong-use-of-new-helper.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 40350ce3ae8701146aafd79c5f7b5582d9955e58 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 25 Sep 2022 15:12:35 +0100 -Subject: [PATCH 1/2] net: ethernet: mtk_eth_soc: fix wrong use of new helper - function -To: linux-mediatek@lists.infradead.org, - netdev@vger.kernel.org, - Lorenzo Bianconi -Cc: Sujuan Chen , - Bo Jiao , - Felix Fietkau , - John Crispin , - Sean Wang , - Mark Lee , - David S. Miller , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Matthias Brugger , - Chen Minqiang - -In function mtk_foe_entry_set_vlan() the call to field accessor macro -FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, entry->ib1) -has been wrongly replaced by -mtk_prep_ib1_vlan_layer(eth, entry->ib1) - -Use correct helper function mtk_get_ib1_vlan_layer instead. - -Reported-by: Chen Minqiang -Fixes: 03a3180e5c09e1 ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986") -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -337,7 +337,7 @@ int mtk_foe_entry_set_vlan(struct mtk_et - { - struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - -- switch (mtk_prep_ib1_vlan_layer(eth, entry->ib1)) { -+ switch (mtk_get_ib1_vlan_layer(eth, entry->ib1)) { - case 0: - entry->ib1 |= mtk_get_ib1_vlan_tag_mask(eth) | - mtk_prep_ib1_vlan_layer(eth, 1); diff --git a/target/linux/generic/backport-5.15/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch b/target/linux/generic/backport-5.15/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch deleted file mode 100644 index 58314a8fc0d214..00000000000000 --- a/target/linux/generic/backport-5.15/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b94b02a270471337bef73c44fa3493a521e31a61 Mon Sep 17 00:00:00 2001 -Message-Id: -In-Reply-To: -References: -From: Lorenzo Bianconi -Date: Mon, 5 Sep 2022 13:56:13 +0200 -Subject: [PATCH net-next 5/5] net: ethernet: mtk_eth_soc: enable flow - offloading support for mt7986 - -Enable hw packet engine and wireless packet dispatcher for mt7986 - -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4254,6 +4254,7 @@ static const struct mtk_soc_data mt7986_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7986_CLKS_BITMAP, - .required_pctl = false, -+ .offload_version = 2, - .hash_offset = 4, - .foe_entry_size = sizeof(struct mtk_foe_entry), - .txrx = { diff --git a/target/linux/generic/backport-5.15/725-v6.0-net-ethernet-mtk_eth_soc-fix-usage-of-foe_entry_size.patch b/target/linux/generic/backport-5.15/725-v6.0-net-ethernet-mtk_eth_soc-fix-usage-of-foe_entry_size.patch deleted file mode 100644 index bb02f401a2d6fa..00000000000000 --- a/target/linux/generic/backport-5.15/725-v6.0-net-ethernet-mtk_eth_soc-fix-usage-of-foe_entry_size.patch +++ /dev/null @@ -1,49 +0,0 @@ -From fcf14c2c5deae8f8c3d25530bab10856f63f8a63 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 25 Sep 2022 15:18:54 +0100 -Subject: [PATCH 2/2] net: ethernet: mtk_eth_soc: fix usage of foe_entry_size -To: linux-mediatek@lists.infradead.org, - netdev@vger.kernel.org, - Lorenzo Bianconi -Cc: Sujuan Chen , - Bo Jiao , - Felix Fietkau , - John Crispin , - Sean Wang , - Mark Lee , - David S. Miller , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Matthias Brugger , - Chen Minqiang - -As sizeof(hwe->data) can now longer be used as the actual size depends -on foe_entry_size, in commit 9d8cb4c096ab02 -("net: ethernet: mtk_eth_soc: add foe_entry_size to mtk_eth_soc") the -use of sizeof(hwe->data) is hence replaced. -However, replacing it with ppe->eth->soc->foe_entry_size is wrong as -foe_entry_size represents the size of the whole descriptor and not just -the 'data' field. -Fix this by subtracing the size of the only other field in the struct -'ib1', so we actually end up with the correct size to be copied to the -data field. - -Reported-by: Chen Minqiang -Fixes: 9d8cb4c096ab02 ("net: ethernet: mtk_eth_soc: add foe_entry_size to mtk_eth_soc") -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -547,7 +547,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - } - - hwe = mtk_foe_get_entry(ppe, hash); -- memcpy(&hwe->data, &entry->data, eth->soc->foe_entry_size); -+ memcpy(&hwe->data, &entry->data, eth->soc->foe_entry_size - sizeof(hwe->ib1)); - wmb(); - hwe->ib1 = entry->ib1; - diff --git a/target/linux/generic/backport-5.15/726-v6.0-net-ethernet-mtk_eth_soc-fix-mask-of-RX_DMA_GET_SPOR.patch b/target/linux/generic/backport-5.15/726-v6.0-net-ethernet-mtk_eth_soc-fix-mask-of-RX_DMA_GET_SPOR.patch deleted file mode 100644 index 27c719b66353fe..00000000000000 --- a/target/linux/generic/backport-5.15/726-v6.0-net-ethernet-mtk_eth_soc-fix-mask-of-RX_DMA_GET_SPOR.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c9da02bfb1112461e048d3b736afb1873f6f4ccf Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 27 Sep 2022 16:30:02 +0100 -Subject: [PATCH 1/1] net: ethernet: mtk_eth_soc: fix mask of - RX_DMA_GET_SPORT{,_V2} - -The bitmasks applied in RX_DMA_GET_SPORT and RX_DMA_GET_SPORT_V2 macros -were swapped. Fix that. - -Reported-by: Chen Minqiang -Fixes: 160d3a9b192985 ("net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support") -Acked-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/YzMW+mg9UsaCdKRQ@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -315,8 +315,8 @@ - #define MTK_RXD5_PPE_CPU_REASON GENMASK(22, 18) - #define MTK_RXD5_SRC_PORT GENMASK(29, 26) - --#define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0xf) --#define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0x7) -+#define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0x7) -+#define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0xf) - - /* PDMA V2 descriptor rxd3 */ - #define RX_DMA_VTAG_V2 BIT(0) diff --git a/target/linux/generic/backport-5.15/727-v6.1-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch b/target/linux/generic/backport-5.15/727-v6.1-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch deleted file mode 100644 index 11465c1c5b71c9..00000000000000 --- a/target/linux/generic/backport-5.15/727-v6.1-net-ethernet-mtk_eth_soc-fix-state-in-__mtk_foe_entr.patch +++ /dev/null @@ -1,37 +0,0 @@ -From ae3ed15da5889263de372ff9df2e83e16acca4cb Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 30 Sep 2022 01:56:53 +0100 -Subject: [PATCH 1/1] net: ethernet: mtk_eth_soc: fix state in - __mtk_foe_entry_clear - -Setting ib1 state to MTK_FOE_STATE_UNBIND in __mtk_foe_entry_clear -routine as done by commit 0e80707d94e4c8 ("net: ethernet: mtk_eth_soc: -fix typo in __mtk_foe_entry_clear") breaks flow offloading, at least -on older MTK_NETSYS_V1 SoCs, OpenWrt users have confirmed the bug on -MT7622 and MT7621 systems. -Felix Fietkau suggested to use MTK_FOE_STATE_INVALID instead which -works well on both, MTK_NETSYS_V1 and MTK_NETSYS_V2. - -Tested on MT7622 (Linksys E8450) and MT7986 (BananaPi BPI-R3). - -Suggested-by: Felix Fietkau -Fixes: 0e80707d94e4c8 ("net: ethernet: mtk_eth_soc: fix typo in __mtk_foe_entry_clear") -Fixes: 33fc42de33278b ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries") -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/YzY+1Yg0FBXcnrtc@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -442,7 +442,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); - - hwe->ib1 &= ~MTK_FOE_IB1_STATE; -- hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_UNBIND); -+ hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); - dma_wmb(); - } - entry->hash = 0xffff; diff --git a/target/linux/generic/backport-5.15/728-v6.1-01-net-ethernet-mtk_eth_soc-fix-possible-memory-leak-in.patch b/target/linux/generic/backport-5.15/728-v6.1-01-net-ethernet-mtk_eth_soc-fix-possible-memory-leak-in.patch deleted file mode 100644 index cad32043541ebc..00000000000000 --- a/target/linux/generic/backport-5.15/728-v6.1-01-net-ethernet-mtk_eth_soc-fix-possible-memory-leak-in.patch +++ /dev/null @@ -1,73 +0,0 @@ -From b3d0d98179d62f9d55635a600679c4fa362baf8d Mon Sep 17 00:00:00 2001 -From: Yang Yingliang -Date: Mon, 17 Oct 2022 11:51:54 +0800 -Subject: [PATCH 1/3] net: ethernet: mtk_eth_soc: fix possible memory leak in - mtk_probe() - -If mtk_wed_add_hw() has been called, mtk_wed_exit() needs be called -in error path or removing module to free the memory allocated in -mtk_wed_add_hw(). - -Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)") -Signed-off-by: Yang Yingliang -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4006,19 +4006,23 @@ static int mtk_probe(struct platform_dev - eth->irq[i] = platform_get_irq(pdev, i); - if (eth->irq[i] < 0) { - dev_err(&pdev->dev, "no IRQ%d resource found\n", i); -- return -ENXIO; -+ err = -ENXIO; -+ goto err_wed_exit; - } - } - for (i = 0; i < ARRAY_SIZE(eth->clks); i++) { - eth->clks[i] = devm_clk_get(eth->dev, - mtk_clks_source_name[i]); - if (IS_ERR(eth->clks[i])) { -- if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER) -- return -EPROBE_DEFER; -+ if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER) { -+ err = -EPROBE_DEFER; -+ goto err_wed_exit; -+ } - if (eth->soc->required_clks & BIT(i)) { - dev_err(&pdev->dev, "clock %s not found\n", - mtk_clks_source_name[i]); -- return -EINVAL; -+ err = -EINVAL; -+ goto err_wed_exit; - } - eth->clks[i] = NULL; - } -@@ -4029,7 +4033,7 @@ static int mtk_probe(struct platform_dev - - err = mtk_hw_init(eth); - if (err) -- return err; -+ goto err_wed_exit; - - eth->hwlro = MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO); - -@@ -4127,6 +4131,8 @@ err_free_dev: - mtk_free_dev(eth); - err_deinit_hw: - mtk_hw_deinit(eth); -+err_wed_exit: -+ mtk_wed_exit(); - - return err; - } -@@ -4146,6 +4152,7 @@ static int mtk_remove(struct platform_de - phylink_disconnect_phy(mac->phylink); - } - -+ mtk_wed_exit(); - mtk_hw_deinit(eth); - - netif_napi_del(ð->tx_napi); diff --git a/target/linux/generic/backport-5.15/728-v6.1-02-net-ethernet-mtk_eth_wed-add-missing-put_device-in-m.patch b/target/linux/generic/backport-5.15/728-v6.1-02-net-ethernet-mtk_eth_wed-add-missing-put_device-in-m.patch deleted file mode 100644 index 4f0b78f1107458..00000000000000 --- a/target/linux/generic/backport-5.15/728-v6.1-02-net-ethernet-mtk_eth_wed-add-missing-put_device-in-m.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 9d4f20a476ca57e4c9246eb1fa2a61bea2354720 Mon Sep 17 00:00:00 2001 -From: Yang Yingliang -Date: Mon, 17 Oct 2022 11:51:55 +0800 -Subject: [PATCH 2/3] net: ethernet: mtk_eth_wed: add missing put_device() in - mtk_wed_add_hw() - -After calling get_device() in mtk_wed_add_hw(), in error path, put_device() -needs be called. - -Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)") -Signed-off-by: Yang Yingliang -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1077,11 +1077,11 @@ void mtk_wed_add_hw(struct device_node * - get_device(&pdev->dev); - irq = platform_get_irq(pdev, 0); - if (irq < 0) -- return; -+ goto err_put_device; - - regs = syscon_regmap_lookup_by_phandle(np, NULL); - if (IS_ERR(regs)) -- return; -+ goto err_put_device; - - rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops); - -@@ -1124,8 +1124,14 @@ void mtk_wed_add_hw(struct device_node * - - hw_list[index] = hw; - -+ mutex_unlock(&hw_lock); -+ -+ return; -+ - unlock: - mutex_unlock(&hw_lock); -+err_put_device: -+ put_device(&pdev->dev); - } - - void mtk_wed_exit(void) diff --git a/target/linux/generic/backport-5.15/728-v6.1-03-net-ethernet-mtk_eth_wed-add-missing-of_node_put.patch b/target/linux/generic/backport-5.15/728-v6.1-03-net-ethernet-mtk_eth_wed-add-missing-of_node_put.patch deleted file mode 100644 index 32f62aaed29135..00000000000000 --- a/target/linux/generic/backport-5.15/728-v6.1-03-net-ethernet-mtk_eth_wed-add-missing-of_node_put.patch +++ /dev/null @@ -1,43 +0,0 @@ -From e0bb4659e235770e6f53b3692e958591f49448f5 Mon Sep 17 00:00:00 2001 -From: Yang Yingliang -Date: Mon, 17 Oct 2022 11:51:56 +0800 -Subject: [PATCH 3/3] net: ethernet: mtk_eth_wed: add missing of_node_put() - -The device_node pointer returned by of_parse_phandle() with refcount -incremented, when finish using it, the refcount need be decreased. - -Fixes: 804775dfc288 ("net: ethernet: mtk_eth_soc: add support for Wireless Ethernet Dispatch (WED)") -Signed-off-by: Yang Yingliang -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1072,7 +1072,7 @@ void mtk_wed_add_hw(struct device_node * - - pdev = of_find_device_by_node(np); - if (!pdev) -- return; -+ goto err_of_node_put; - - get_device(&pdev->dev); - irq = platform_get_irq(pdev, 0); -@@ -1132,6 +1132,8 @@ unlock: - mutex_unlock(&hw_lock); - err_put_device: - put_device(&pdev->dev); -+err_of_node_put: -+ of_node_put(np); - } - - void mtk_wed_exit(void) -@@ -1152,6 +1154,7 @@ void mtk_wed_exit(void) - hw_list[i] = NULL; - debugfs_remove(hw->debugfs_dir); - put_device(hw->dev); -+ of_node_put(hw->node); - kfree(hw); - } - } diff --git a/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch b/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch deleted file mode 100644 index e2a2046442ebc5..00000000000000 --- a/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 8110437e59616293228cd781c486d8495a61e36a Mon Sep 17 00:00:00 2001 -From: Yan Cangang -Date: Sun, 20 Nov 2022 13:52:58 +0800 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix resource leak in error path - -In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() failed, -mtk_mdio_cleanup() isn't called. Fix it. - -Fixes: ba37b7caf1ed ("net: ethernet: mtk_eth_soc: add support for initializing the PPE") -Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support") -Signed-off-by: Yan Cangang -Reviewed-by: Leon Romanovsky -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4089,13 +4089,13 @@ static int mtk_probe(struct platform_dev - eth->soc->offload_version, i); - if (!eth->ppe[i]) { - err = -ENOMEM; -- goto err_free_dev; -+ goto err_deinit_mdio; - } - } - - err = mtk_eth_offload_init(eth); - if (err) -- goto err_free_dev; -+ goto err_deinit_mdio; - } - - for (i = 0; i < MTK_MAX_DEVS; i++) { diff --git a/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch b/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch deleted file mode 100644 index 13f0ed5a5d9973..00000000000000 --- a/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 603ea5e7ffa73c7fac07d8713d97285990695213 Mon Sep 17 00:00:00 2001 -From: Yan Cangang -Date: Sun, 20 Nov 2022 13:52:59 +0800 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix memory leak in error path - -In mtk_ppe_init(), when dmam_alloc_coherent() or devm_kzalloc() failed, -the rhashtable ppe->l2_flows isn't destroyed. Fix it. - -In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() or -register_netdev() failed, have the same problem. Fix it. - -Fixes: 33fc42de3327 ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries") -Signed-off-by: Yan Cangang -Reviewed-by: Leon Romanovsky -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 9 +++++---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_ppe.h | 1 + - 3 files changed, 23 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4089,13 +4089,13 @@ static int mtk_probe(struct platform_dev - eth->soc->offload_version, i); - if (!eth->ppe[i]) { - err = -ENOMEM; -- goto err_deinit_mdio; -+ goto err_deinit_ppe; - } - } - - err = mtk_eth_offload_init(eth); - if (err) -- goto err_deinit_mdio; -+ goto err_deinit_ppe; - } - - for (i = 0; i < MTK_MAX_DEVS; i++) { -@@ -4105,7 +4105,7 @@ static int mtk_probe(struct platform_dev - err = register_netdev(eth->netdev[i]); - if (err) { - dev_err(eth->dev, "error bringing up device\n"); -- goto err_deinit_mdio; -+ goto err_deinit_ppe; - } else - netif_info(eth, probe, eth->netdev[i], - "mediatek frame engine at 0x%08lx, irq %d\n", -@@ -4125,7 +4125,8 @@ static int mtk_probe(struct platform_dev - - return 0; - --err_deinit_mdio: -+err_deinit_ppe: -+ mtk_ppe_deinit(eth); - mtk_mdio_cleanup(eth); - err_free_dev: - mtk_free_dev(eth); ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -743,7 +743,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - MTK_PPE_ENTRIES * soc->foe_entry_size, - &ppe->foe_phys, GFP_KERNEL); - if (!foe) -- return NULL; -+ goto err_free_l2_flows; - - ppe->foe_table = foe; - -@@ -751,11 +751,26 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - sizeof(*ppe->foe_flow); - ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL); - if (!ppe->foe_flow) -- return NULL; -+ goto err_free_l2_flows; - - mtk_ppe_debugfs_init(ppe, index); - - return ppe; -+ -+err_free_l2_flows: -+ rhashtable_destroy(&ppe->l2_flows); -+ return NULL; -+} -+ -+void mtk_ppe_deinit(struct mtk_eth *eth) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) { -+ if (!eth->ppe[i]) -+ return; -+ rhashtable_destroy(ð->ppe[i]->l2_flows); -+ } - } - - static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe) ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -304,6 +304,7 @@ struct mtk_ppe { - - struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, - int version, int index); -+void mtk_ppe_deinit(struct mtk_eth *eth); - void mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); - diff --git a/target/linux/generic/backport-5.15/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch b/target/linux/generic/backport-5.15/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch deleted file mode 100644 index c48613929d1272..00000000000000 --- a/target/linux/generic/backport-5.15/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch +++ /dev/null @@ -1,591 +0,0 @@ -From: Sujuan Chen -Date: Sat, 5 Nov 2022 23:36:18 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: introduce wed mcu support - -Introduce WED mcu support used to configure WED WO chip. -This is a preliminary patch in order to add RX Wireless -Ethernet Dispatch available on MT7986 SoC. - -Tested-by: Daniel Golle -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: David S. Miller ---- - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_mcu.c - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.h - ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -5,7 +5,7 @@ - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o - mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o --mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o -+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o - ifdef CONFIG_DEBUG_FS - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o - endif ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -0,0 +1,359 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* Copyright (C) 2022 MediaTek Inc. -+ * -+ * Author: Lorenzo Bianconi -+ * Sujuan Chen -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtk_wed_regs.h" -+#include "mtk_wed_wo.h" -+#include "mtk_wed.h" -+ -+static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg) -+{ -+ return readl(wo->boot.addr + reg); -+} -+ -+static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val) -+{ -+ writel(val, wo->boot.addr + reg); -+} -+ -+static struct sk_buff * -+mtk_wed_mcu_msg_alloc(const void *data, int data_len) -+{ -+ int length = sizeof(struct mtk_wed_mcu_hdr) + data_len; -+ struct sk_buff *skb; -+ -+ skb = alloc_skb(length, GFP_KERNEL); -+ if (!skb) -+ return NULL; -+ -+ memset(skb->head, 0, length); -+ skb_reserve(skb, sizeof(struct mtk_wed_mcu_hdr)); -+ if (data && data_len) -+ skb_put_data(skb, data, data_len); -+ -+ return skb; -+} -+ -+static struct sk_buff * -+mtk_wed_mcu_get_response(struct mtk_wed_wo *wo, unsigned long expires) -+{ -+ if (!time_is_after_jiffies(expires)) -+ return NULL; -+ -+ wait_event_timeout(wo->mcu.wait, !skb_queue_empty(&wo->mcu.res_q), -+ expires - jiffies); -+ return skb_dequeue(&wo->mcu.res_q); -+} -+ -+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb) -+{ -+ skb_queue_tail(&wo->mcu.res_q, skb); -+ wake_up(&wo->mcu.wait); -+} -+ -+void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, -+ struct sk_buff *skb) -+{ -+ struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data; -+ -+ switch (hdr->cmd) { -+ case MTK_WED_WO_EVT_LOG_DUMP: { -+ const char *msg = (const char *)(skb->data + sizeof(*hdr)); -+ -+ dev_notice(wo->hw->dev, "%s\n", msg); -+ break; -+ } -+ case MTK_WED_WO_EVT_PROFILING: { -+ struct mtk_wed_wo_log_info *info; -+ u32 count = (skb->len - sizeof(*hdr)) / sizeof(*info); -+ int i; -+ -+ info = (struct mtk_wed_wo_log_info *)(skb->data + sizeof(*hdr)); -+ for (i = 0 ; i < count ; i++) -+ dev_notice(wo->hw->dev, -+ "SN:%u latency: total=%u, rro:%u, mod:%u\n", -+ le32_to_cpu(info[i].sn), -+ le32_to_cpu(info[i].total), -+ le32_to_cpu(info[i].rro), -+ le32_to_cpu(info[i].mod)); -+ break; -+ } -+ case MTK_WED_WO_EVT_RXCNT_INFO: -+ break; -+ default: -+ break; -+ } -+ -+ dev_kfree_skb(skb); -+} -+ -+static int -+mtk_wed_mcu_skb_send_msg(struct mtk_wed_wo *wo, struct sk_buff *skb, -+ int id, int cmd, u16 *wait_seq, bool wait_resp) -+{ -+ struct mtk_wed_mcu_hdr *hdr; -+ -+ /* TODO: make it dynamic based on cmd */ -+ wo->mcu.timeout = 20 * HZ; -+ -+ hdr = (struct mtk_wed_mcu_hdr *)skb_push(skb, sizeof(*hdr)); -+ hdr->cmd = cmd; -+ hdr->length = cpu_to_le16(skb->len); -+ -+ if (wait_resp && wait_seq) { -+ u16 seq = ++wo->mcu.seq; -+ -+ if (!seq) -+ seq = ++wo->mcu.seq; -+ *wait_seq = seq; -+ -+ hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_NEED_RSP); -+ hdr->seq = cpu_to_le16(seq); -+ } -+ if (id == MTK_WED_MODULE_ID_WO) -+ hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_FROM_TO_WO); -+ -+ dev_kfree_skb(skb); -+ return 0; -+} -+ -+static int -+mtk_wed_mcu_parse_response(struct mtk_wed_wo *wo, struct sk_buff *skb, -+ int cmd, int seq) -+{ -+ struct mtk_wed_mcu_hdr *hdr; -+ -+ if (!skb) { -+ dev_err(wo->hw->dev, "Message %08x (seq %d) timeout\n", -+ cmd, seq); -+ return -ETIMEDOUT; -+ } -+ -+ hdr = (struct mtk_wed_mcu_hdr *)skb->data; -+ if (le16_to_cpu(hdr->seq) != seq) -+ return -EAGAIN; -+ -+ skb_pull(skb, sizeof(*hdr)); -+ switch (cmd) { -+ case MTK_WED_WO_CMD_RXCNT_INFO: -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, -+ const void *data, int len, bool wait_resp) -+{ -+ unsigned long expires; -+ struct sk_buff *skb; -+ u16 seq; -+ int ret; -+ -+ skb = mtk_wed_mcu_msg_alloc(data, len); -+ if (!skb) -+ return -ENOMEM; -+ -+ mutex_lock(&wo->mcu.mutex); -+ -+ ret = mtk_wed_mcu_skb_send_msg(wo, skb, id, cmd, &seq, wait_resp); -+ if (ret || !wait_resp) -+ goto unlock; -+ -+ expires = jiffies + wo->mcu.timeout; -+ do { -+ skb = mtk_wed_mcu_get_response(wo, expires); -+ ret = mtk_wed_mcu_parse_response(wo, skb, cmd, seq); -+ dev_kfree_skb(skb); -+ } while (ret == -EAGAIN); -+ -+unlock: -+ mutex_unlock(&wo->mcu.mutex); -+ -+ return ret; -+} -+ -+static int -+mtk_wed_get_memory_region(struct mtk_wed_wo *wo, -+ struct mtk_wed_wo_memory_region *region) -+{ -+ struct reserved_mem *rmem; -+ struct device_node *np; -+ int index; -+ -+ index = of_property_match_string(wo->hw->node, "memory-region-names", -+ region->name); -+ if (index < 0) -+ return index; -+ -+ np = of_parse_phandle(wo->hw->node, "memory-region", index); -+ if (!np) -+ return -ENODEV; -+ -+ rmem = of_reserved_mem_lookup(np); -+ of_node_put(np); -+ -+ if (!rmem) -+ return -ENODEV; -+ -+ region->phy_addr = rmem->base; -+ region->size = rmem->size; -+ region->addr = devm_ioremap(wo->hw->dev, region->phy_addr, region->size); -+ -+ return !region->addr ? -EINVAL : 0; -+} -+ -+static int -+mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw, -+ struct mtk_wed_wo_memory_region *region) -+{ -+ const u8 *first_region_ptr, *region_ptr, *trailer_ptr, *ptr = fw->data; -+ const struct mtk_wed_fw_trailer *trailer; -+ const struct mtk_wed_fw_region *fw_region; -+ -+ trailer_ptr = fw->data + fw->size - sizeof(*trailer); -+ trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr; -+ region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region); -+ first_region_ptr = region_ptr; -+ -+ while (region_ptr < trailer_ptr) { -+ u32 length; -+ -+ fw_region = (const struct mtk_wed_fw_region *)region_ptr; -+ length = le32_to_cpu(fw_region->len); -+ -+ if (region->phy_addr != le32_to_cpu(fw_region->addr)) -+ goto next; -+ -+ if (region->size < length) -+ goto next; -+ -+ if (first_region_ptr < ptr + length) -+ goto next; -+ -+ if (region->shared && region->consumed) -+ return 0; -+ -+ if (!region->shared || !region->consumed) { -+ memcpy_toio(region->addr, ptr, length); -+ region->consumed = true; -+ return 0; -+ } -+next: -+ region_ptr += sizeof(*fw_region); -+ ptr += length; -+ } -+ -+ return -EINVAL; -+} -+ -+static int -+mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) -+{ -+ static struct mtk_wed_wo_memory_region mem_region[] = { -+ [MTK_WED_WO_REGION_EMI] = { -+ .name = "wo-emi", -+ }, -+ [MTK_WED_WO_REGION_ILM] = { -+ .name = "wo-ilm", -+ }, -+ [MTK_WED_WO_REGION_DATA] = { -+ .name = "wo-data", -+ .shared = true, -+ }, -+ }; -+ const struct mtk_wed_fw_trailer *trailer; -+ const struct firmware *fw; -+ const char *fw_name; -+ u32 val, boot_cr; -+ int ret, i; -+ -+ /* load firmware region metadata */ -+ for (i = 0; i < ARRAY_SIZE(mem_region); i++) { -+ ret = mtk_wed_get_memory_region(wo, &mem_region[i]); -+ if (ret) -+ return ret; -+ } -+ -+ wo->boot.name = "wo-boot"; -+ ret = mtk_wed_get_memory_region(wo, &wo->boot); -+ if (ret) -+ return ret; -+ -+ /* set dummy cr */ -+ wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL, -+ wo->hw->index + 1); -+ -+ /* load firmware */ -+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; -+ ret = request_firmware(&fw, fw_name, wo->hw->dev); -+ if (ret) -+ return ret; -+ -+ trailer = (void *)(fw->data + fw->size - -+ sizeof(struct mtk_wed_fw_trailer)); -+ dev_info(wo->hw->dev, -+ "MTK WED WO Firmware Version: %.10s, Build Time: %.15s\n", -+ trailer->fw_ver, trailer->build_date); -+ dev_info(wo->hw->dev, "MTK WED WO Chip ID %02x Region %d\n", -+ trailer->chip_id, trailer->num_region); -+ -+ for (i = 0; i < ARRAY_SIZE(mem_region); i++) { -+ ret = mtk_wed_mcu_run_firmware(wo, fw, &mem_region[i]); -+ if (ret) -+ goto out; -+ } -+ -+ /* set the start address */ -+ boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR -+ : MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR; -+ wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16); -+ /* wo firmware reset */ -+ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00); -+ -+ val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR); -+ val |= wo->hw->index ? MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK -+ : MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK; -+ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val); -+out: -+ release_firmware(fw); -+ -+ return ret; -+} -+ -+static u32 -+mtk_wed_mcu_read_fw_dl(struct mtk_wed_wo *wo) -+{ -+ return wed_r32(wo->hw->wed_dev, -+ MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL); -+} -+ -+int mtk_wed_mcu_init(struct mtk_wed_wo *wo) -+{ -+ u32 val; -+ int ret; -+ -+ skb_queue_head_init(&wo->mcu.res_q); -+ init_waitqueue_head(&wo->mcu.wait); -+ mutex_init(&wo->mcu.mutex); -+ -+ ret = mtk_wed_mcu_load_firmware(wo); -+ if (ret) -+ return ret; -+ -+ return readx_poll_timeout(mtk_wed_mcu_read_fw_dl, wo, val, !val, -+ 100, MTK_FW_DL_TIMEOUT); -+} -+ -+MODULE_FIRMWARE(MT7986_FIRMWARE_WO0); -+MODULE_FIRMWARE(MT7986_FIRMWARE_WO1); ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -152,6 +152,7 @@ struct mtk_wdma_desc { - - #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10) - -+#define MTK_WED_SCR0 0x3c0 - #define MTK_WED_WPDMA_INT_TRIGGER 0x504 - #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1) - #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4) ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -0,0 +1,150 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* Copyright (C) 2022 Lorenzo Bianconi */ -+ -+#ifndef __MTK_WED_WO_H -+#define __MTK_WED_WO_H -+ -+#include -+#include -+ -+struct mtk_wed_hw; -+ -+struct mtk_wed_mcu_hdr { -+ /* DW0 */ -+ u8 version; -+ u8 cmd; -+ __le16 length; -+ -+ /* DW1 */ -+ __le16 seq; -+ __le16 flag; -+ -+ /* DW2 */ -+ __le32 status; -+ -+ /* DW3 */ -+ u8 rsv[20]; -+}; -+ -+struct mtk_wed_wo_log_info { -+ __le32 sn; -+ __le32 total; -+ __le32 rro; -+ __le32 mod; -+}; -+ -+enum mtk_wed_wo_event { -+ MTK_WED_WO_EVT_LOG_DUMP = 0x1, -+ MTK_WED_WO_EVT_PROFILING = 0x2, -+ MTK_WED_WO_EVT_RXCNT_INFO = 0x3, -+}; -+ -+#define MTK_WED_MODULE_ID_WO 1 -+#define MTK_FW_DL_TIMEOUT 4000000 /* us */ -+#define MTK_WOCPU_TIMEOUT 2000000 /* us */ -+ -+enum { -+ MTK_WED_WARP_CMD_FLAG_RSP = BIT(0), -+ MTK_WED_WARP_CMD_FLAG_NEED_RSP = BIT(1), -+ MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2), -+}; -+ -+enum { -+ MTK_WED_WO_REGION_EMI, -+ MTK_WED_WO_REGION_ILM, -+ MTK_WED_WO_REGION_DATA, -+ MTK_WED_WO_REGION_BOOT, -+ __MTK_WED_WO_REGION_MAX, -+}; -+ -+enum mtk_wed_dummy_cr_idx { -+ MTK_WED_DUMMY_CR_FWDL, -+ MTK_WED_DUMMY_CR_WO_STATUS, -+}; -+ -+#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" -+#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" -+ -+#define MTK_WO_MCU_CFG_LS_BASE 0 -+#define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000) -+#define MTK_WO_MCU_CFG_LS_FW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x004) -+#define MTK_WO_MCU_CFG_LS_CFG_DBG1_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x00c) -+#define MTK_WO_MCU_CFG_LS_CFG_DBG2_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x010) -+#define MTK_WO_MCU_CFG_LS_WF_MCCR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x014) -+#define MTK_WO_MCU_CFG_LS_WF_MCCR_SET_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x018) -+#define MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x01c) -+#define MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x050) -+#define MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x060) -+#define MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x064) -+ -+#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5) -+#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0) -+ -+struct mtk_wed_wo_memory_region { -+ const char *name; -+ void __iomem *addr; -+ phys_addr_t phy_addr; -+ u32 size; -+ bool shared:1; -+ bool consumed:1; -+}; -+ -+struct mtk_wed_fw_region { -+ __le32 decomp_crc; -+ __le32 decomp_len; -+ __le32 decomp_blk_sz; -+ u8 rsv0[4]; -+ __le32 addr; -+ __le32 len; -+ u8 feature_set; -+ u8 rsv1[15]; -+} __packed; -+ -+struct mtk_wed_fw_trailer { -+ u8 chip_id; -+ u8 eco_code; -+ u8 num_region; -+ u8 format_ver; -+ u8 format_flag; -+ u8 rsv[2]; -+ char fw_ver[10]; -+ char build_date[15]; -+ u32 crc; -+}; -+ -+struct mtk_wed_wo { -+ struct mtk_wed_hw *hw; -+ struct mtk_wed_wo_memory_region boot; -+ -+ struct { -+ struct mutex mutex; -+ int timeout; -+ u16 seq; -+ -+ struct sk_buff_head res_q; -+ wait_queue_head_t wait; -+ } mcu; -+}; -+ -+static inline int -+mtk_wed_mcu_check_msg(struct mtk_wed_wo *wo, struct sk_buff *skb) -+{ -+ struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data; -+ -+ if (hdr->version) -+ return -EINVAL; -+ -+ if (skb->len < sizeof(*hdr) || skb->len != le16_to_cpu(hdr->length)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb); -+void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, -+ struct sk_buff *skb); -+int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, -+ const void *data, int len, bool wait_resp); -+int mtk_wed_mcu_init(struct mtk_wed_wo *wo); -+ -+#endif /* __MTK_WED_WO_H */ ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -11,6 +11,35 @@ - struct mtk_wed_hw; - struct mtk_wdma_desc; - -+enum mtk_wed_wo_cmd { -+ MTK_WED_WO_CMD_WED_CFG, -+ MTK_WED_WO_CMD_WED_RX_STAT, -+ MTK_WED_WO_CMD_RRO_SER, -+ MTK_WED_WO_CMD_DBG_INFO, -+ MTK_WED_WO_CMD_DEV_INFO, -+ MTK_WED_WO_CMD_BSS_INFO, -+ MTK_WED_WO_CMD_STA_REC, -+ MTK_WED_WO_CMD_DEV_INFO_DUMP, -+ MTK_WED_WO_CMD_BSS_INFO_DUMP, -+ MTK_WED_WO_CMD_STA_REC_DUMP, -+ MTK_WED_WO_CMD_BA_INFO_DUMP, -+ MTK_WED_WO_CMD_FBCMD_Q_DUMP, -+ MTK_WED_WO_CMD_FW_LOG_CTRL, -+ MTK_WED_WO_CMD_LOG_FLUSH, -+ MTK_WED_WO_CMD_CHANGE_STATE, -+ MTK_WED_WO_CMD_CPU_STATS_ENABLE, -+ MTK_WED_WO_CMD_CPU_STATS_DUMP, -+ MTK_WED_WO_CMD_EXCEPTION_INIT, -+ MTK_WED_WO_CMD_PROF_CTRL, -+ MTK_WED_WO_CMD_STA_BA_DUMP, -+ MTK_WED_WO_CMD_BA_CTRL_DUMP, -+ MTK_WED_WO_CMD_RXCNT_CTRL, -+ MTK_WED_WO_CMD_RXCNT_INFO, -+ MTK_WED_WO_CMD_SET_CAP, -+ MTK_WED_WO_CMD_CCIF_RING_DUMP, -+ MTK_WED_WO_CMD_WED_END -+}; -+ - enum mtk_wed_bus_tye { - MTK_WED_BUS_PCIE, - MTK_WED_BUS_AXI, diff --git a/target/linux/generic/backport-5.15/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch b/target/linux/generic/backport-5.15/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch deleted file mode 100644 index fd5f45df2aaa27..00000000000000 --- a/target/linux/generic/backport-5.15/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch +++ /dev/null @@ -1,737 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 5 Nov 2022 23:36:19 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: introduce wed wo support - -Introduce WO chip support to mtk wed driver. MTK WED WO is used to -implement RX Wireless Ethernet Dispatch and offload traffic received by -wlan nic to the wired interface. - -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.c - ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -5,7 +5,7 @@ - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o - mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o --mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o -+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o - ifdef CONFIG_DEBUG_FS - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o - endif ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -16,6 +16,7 @@ - #include "mtk_wed_regs.h" - #include "mtk_wed.h" - #include "mtk_ppe.h" -+#include "mtk_wed_wo.h" - - #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000) - -@@ -355,6 +356,8 @@ mtk_wed_detach(struct mtk_wed_device *de - - mtk_wed_free_buffer(dev); - mtk_wed_free_tx_rings(dev); -+ if (hw->version != 1) -+ mtk_wed_wo_deinit(hw); - - if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { - struct device_node *wlan_node; -@@ -878,9 +881,11 @@ mtk_wed_attach(struct mtk_wed_device *de - } - - mtk_wed_hw_init_early(dev); -- if (hw->hifsys) -+ if (hw->version == 1) - regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, - BIT(hw->index), 0); -+ else -+ ret = mtk_wed_wo_init(hw); - - out: - mutex_unlock(&hw_lock); ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -10,6 +10,7 @@ - #include - - struct mtk_eth; -+struct mtk_wed_wo; - - struct mtk_wed_hw { - struct device_node *node; -@@ -22,6 +23,7 @@ struct mtk_wed_hw { - struct regmap *mirror; - struct dentry *debugfs_dir; - struct mtk_wed_device *wed_dev; -+ struct mtk_wed_wo *wed_wo; - u32 debugfs_reg; - u32 num_flows; - u8 version; ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -122,8 +122,7 @@ mtk_wed_mcu_skb_send_msg(struct mtk_wed_ - if (id == MTK_WED_MODULE_ID_WO) - hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_FROM_TO_WO); - -- dev_kfree_skb(skb); -- return 0; -+ return mtk_wed_wo_queue_tx_skb(wo, &wo->q_tx, skb); - } - - static int ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c -@@ -0,0 +1,508 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* Copyright (C) 2022 MediaTek Inc. -+ * -+ * Author: Lorenzo Bianconi -+ * Sujuan Chen -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtk_wed.h" -+#include "mtk_wed_regs.h" -+#include "mtk_wed_wo.h" -+ -+static u32 -+mtk_wed_mmio_r32(struct mtk_wed_wo *wo, u32 reg) -+{ -+ u32 val; -+ -+ if (regmap_read(wo->mmio.regs, reg, &val)) -+ val = ~0; -+ -+ return val; -+} -+ -+static void -+mtk_wed_mmio_w32(struct mtk_wed_wo *wo, u32 reg, u32 val) -+{ -+ regmap_write(wo->mmio.regs, reg, val); -+} -+ -+static u32 -+mtk_wed_wo_get_isr(struct mtk_wed_wo *wo) -+{ -+ u32 val = mtk_wed_mmio_r32(wo, MTK_WED_WO_CCIF_RCHNUM); -+ -+ return val & MTK_WED_WO_CCIF_RCHNUM_MASK; -+} -+ -+static void -+mtk_wed_wo_set_isr(struct mtk_wed_wo *wo, u32 mask) -+{ -+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_IRQ0_MASK, mask); -+} -+ -+static void -+mtk_wed_wo_set_ack(struct mtk_wed_wo *wo, u32 mask) -+{ -+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_ACK, mask); -+} -+ -+static void -+mtk_wed_wo_set_isr_mask(struct mtk_wed_wo *wo, u32 mask, u32 val, bool set) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&wo->mmio.lock, flags); -+ wo->mmio.irq_mask &= ~mask; -+ wo->mmio.irq_mask |= val; -+ if (set) -+ mtk_wed_wo_set_isr(wo, wo->mmio.irq_mask); -+ spin_unlock_irqrestore(&wo->mmio.lock, flags); -+} -+ -+static void -+mtk_wed_wo_irq_enable(struct mtk_wed_wo *wo, u32 mask) -+{ -+ mtk_wed_wo_set_isr_mask(wo, 0, mask, false); -+ tasklet_schedule(&wo->mmio.irq_tasklet); -+} -+ -+static void -+mtk_wed_wo_irq_disable(struct mtk_wed_wo *wo, u32 mask) -+{ -+ mtk_wed_wo_set_isr_mask(wo, mask, 0, true); -+} -+ -+static void -+mtk_wed_wo_kickout(struct mtk_wed_wo *wo) -+{ -+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_BUSY, 1 << MTK_WED_WO_TXCH_NUM); -+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_TCHNUM, MTK_WED_WO_TXCH_NUM); -+} -+ -+static void -+mtk_wed_wo_queue_kick(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, -+ u32 val) -+{ -+ wmb(); -+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, val); -+} -+ -+static void * -+mtk_wed_wo_dequeue(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, u32 *len, -+ bool flush) -+{ -+ int buf_len = SKB_WITH_OVERHEAD(q->buf_size); -+ int index = (q->tail + 1) % q->n_desc; -+ struct mtk_wed_wo_queue_entry *entry; -+ struct mtk_wed_wo_queue_desc *desc; -+ void *buf; -+ -+ if (!q->queued) -+ return NULL; -+ -+ if (flush) -+ q->desc[index].ctrl |= cpu_to_le32(MTK_WED_WO_CTL_DMA_DONE); -+ else if (!(q->desc[index].ctrl & cpu_to_le32(MTK_WED_WO_CTL_DMA_DONE))) -+ return NULL; -+ -+ q->tail = index; -+ q->queued--; -+ -+ desc = &q->desc[index]; -+ entry = &q->entry[index]; -+ buf = entry->buf; -+ if (len) -+ *len = FIELD_GET(MTK_WED_WO_CTL_SD_LEN0, -+ le32_to_cpu(READ_ONCE(desc->ctrl))); -+ if (buf) -+ dma_unmap_single(wo->hw->dev, entry->addr, buf_len, -+ DMA_FROM_DEVICE); -+ entry->buf = NULL; -+ -+ return buf; -+} -+ -+static int -+mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, -+ gfp_t gfp, bool rx) -+{ -+ enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE; -+ int n_buf = 0; -+ -+ spin_lock_bh(&q->lock); -+ while (q->queued < q->n_desc) { -+ void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp); -+ struct mtk_wed_wo_queue_entry *entry; -+ dma_addr_t addr; -+ -+ if (!buf) -+ break; -+ -+ addr = dma_map_single(wo->hw->dev, buf, q->buf_size, dir); -+ if (unlikely(dma_mapping_error(wo->hw->dev, addr))) { -+ skb_free_frag(buf); -+ break; -+ } -+ -+ q->head = (q->head + 1) % q->n_desc; -+ entry = &q->entry[q->head]; -+ entry->addr = addr; -+ entry->len = q->buf_size; -+ q->entry[q->head].buf = buf; -+ -+ if (rx) { -+ struct mtk_wed_wo_queue_desc *desc = &q->desc[q->head]; -+ u32 ctrl = MTK_WED_WO_CTL_LAST_SEC0 | -+ FIELD_PREP(MTK_WED_WO_CTL_SD_LEN0, -+ entry->len); -+ -+ WRITE_ONCE(desc->buf0, cpu_to_le32(addr)); -+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); -+ } -+ q->queued++; -+ n_buf++; -+ } -+ spin_unlock_bh(&q->lock); -+ -+ return n_buf; -+} -+ -+static void -+mtk_wed_wo_rx_complete(struct mtk_wed_wo *wo) -+{ -+ mtk_wed_wo_set_ack(wo, MTK_WED_WO_RXCH_INT_MASK); -+ mtk_wed_wo_irq_enable(wo, MTK_WED_WO_RXCH_INT_MASK); -+} -+ -+static void -+mtk_wed_wo_rx_run_queue(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) -+{ -+ for (;;) { -+ struct mtk_wed_mcu_hdr *hdr; -+ struct sk_buff *skb; -+ void *data; -+ u32 len; -+ -+ data = mtk_wed_wo_dequeue(wo, q, &len, false); -+ if (!data) -+ break; -+ -+ skb = build_skb(data, q->buf_size); -+ if (!skb) { -+ skb_free_frag(data); -+ continue; -+ } -+ -+ __skb_put(skb, len); -+ if (mtk_wed_mcu_check_msg(wo, skb)) { -+ dev_kfree_skb(skb); -+ continue; -+ } -+ -+ hdr = (struct mtk_wed_mcu_hdr *)skb->data; -+ if (hdr->flag & cpu_to_le16(MTK_WED_WARP_CMD_FLAG_RSP)) -+ mtk_wed_mcu_rx_event(wo, skb); -+ else -+ mtk_wed_mcu_rx_unsolicited_event(wo, skb); -+ } -+ -+ if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) { -+ u32 index = (q->head - 1) % q->n_desc; -+ -+ mtk_wed_wo_queue_kick(wo, q, index); -+ } -+} -+ -+static irqreturn_t -+mtk_wed_wo_irq_handler(int irq, void *data) -+{ -+ struct mtk_wed_wo *wo = data; -+ -+ mtk_wed_wo_set_isr(wo, 0); -+ tasklet_schedule(&wo->mmio.irq_tasklet); -+ -+ return IRQ_HANDLED; -+} -+ -+static void mtk_wed_wo_irq_tasklet(struct tasklet_struct *t) -+{ -+ struct mtk_wed_wo *wo = from_tasklet(wo, t, mmio.irq_tasklet); -+ u32 intr, mask; -+ -+ /* disable interrupts */ -+ mtk_wed_wo_set_isr(wo, 0); -+ -+ intr = mtk_wed_wo_get_isr(wo); -+ intr &= wo->mmio.irq_mask; -+ mask = intr & (MTK_WED_WO_RXCH_INT_MASK | MTK_WED_WO_EXCEPTION_INT_MASK); -+ mtk_wed_wo_irq_disable(wo, mask); -+ -+ if (intr & MTK_WED_WO_RXCH_INT_MASK) { -+ mtk_wed_wo_rx_run_queue(wo, &wo->q_rx); -+ mtk_wed_wo_rx_complete(wo); -+ } -+} -+ -+/* mtk wed wo hw queues */ -+ -+static int -+mtk_wed_wo_queue_alloc(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, -+ int n_desc, int buf_size, int index, -+ struct mtk_wed_wo_queue_regs *regs) -+{ -+ spin_lock_init(&q->lock); -+ q->regs = *regs; -+ q->n_desc = n_desc; -+ q->buf_size = buf_size; -+ -+ q->desc = dmam_alloc_coherent(wo->hw->dev, n_desc * sizeof(*q->desc), -+ &q->desc_dma, GFP_KERNEL); -+ if (!q->desc) -+ return -ENOMEM; -+ -+ q->entry = devm_kzalloc(wo->hw->dev, n_desc * sizeof(*q->entry), -+ GFP_KERNEL); -+ if (!q->entry) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+static void -+mtk_wed_wo_queue_free(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) -+{ -+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, 0); -+ dma_free_coherent(wo->hw->dev, q->n_desc * sizeof(*q->desc), q->desc, -+ q->desc_dma); -+} -+ -+static void -+mtk_wed_wo_queue_tx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) -+{ -+ struct page *page; -+ int i; -+ -+ spin_lock_bh(&q->lock); -+ for (i = 0; i < q->n_desc; i++) { -+ struct mtk_wed_wo_queue_entry *entry = &q->entry[i]; -+ -+ dma_unmap_single(wo->hw->dev, entry->addr, entry->len, -+ DMA_TO_DEVICE); -+ skb_free_frag(entry->buf); -+ entry->buf = NULL; -+ } -+ spin_unlock_bh(&q->lock); -+ -+ if (!q->cache.va) -+ return; -+ -+ page = virt_to_page(q->cache.va); -+ __page_frag_cache_drain(page, q->cache.pagecnt_bias); -+ memset(&q->cache, 0, sizeof(q->cache)); -+} -+ -+static void -+mtk_wed_wo_queue_rx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) -+{ -+ struct page *page; -+ -+ spin_lock_bh(&q->lock); -+ for (;;) { -+ void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true); -+ -+ if (!buf) -+ break; -+ -+ skb_free_frag(buf); -+ } -+ spin_unlock_bh(&q->lock); -+ -+ if (!q->cache.va) -+ return; -+ -+ page = virt_to_page(q->cache.va); -+ __page_frag_cache_drain(page, q->cache.pagecnt_bias); -+ memset(&q->cache, 0, sizeof(q->cache)); -+} -+ -+static void -+mtk_wed_wo_queue_reset(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) -+{ -+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, 0); -+ mtk_wed_mmio_w32(wo, q->regs.desc_base, q->desc_dma); -+ mtk_wed_mmio_w32(wo, q->regs.ring_size, q->n_desc); -+} -+ -+int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, -+ struct sk_buff *skb) -+{ -+ struct mtk_wed_wo_queue_entry *entry; -+ struct mtk_wed_wo_queue_desc *desc; -+ int ret = 0, index; -+ u32 ctrl; -+ -+ spin_lock_bh(&q->lock); -+ -+ q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx); -+ index = (q->head + 1) % q->n_desc; -+ if (q->tail == index) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ entry = &q->entry[index]; -+ if (skb->len > entry->len) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ desc = &q->desc[index]; -+ q->head = index; -+ -+ dma_sync_single_for_cpu(wo->hw->dev, entry->addr, skb->len, -+ DMA_TO_DEVICE); -+ memcpy(entry->buf, skb->data, skb->len); -+ dma_sync_single_for_device(wo->hw->dev, entry->addr, skb->len, -+ DMA_TO_DEVICE); -+ -+ ctrl = FIELD_PREP(MTK_WED_WO_CTL_SD_LEN0, skb->len) | -+ MTK_WED_WO_CTL_LAST_SEC0 | MTK_WED_WO_CTL_DMA_DONE; -+ WRITE_ONCE(desc->buf0, cpu_to_le32(entry->addr)); -+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); -+ -+ mtk_wed_wo_queue_kick(wo, q, q->head); -+ mtk_wed_wo_kickout(wo); -+out: -+ spin_unlock_bh(&q->lock); -+ -+ dev_kfree_skb(skb); -+ -+ return ret; -+} -+ -+static int -+mtk_wed_wo_exception_init(struct mtk_wed_wo *wo) -+{ -+ return 0; -+} -+ -+static int -+mtk_wed_wo_hardware_init(struct mtk_wed_wo *wo) -+{ -+ struct mtk_wed_wo_queue_regs regs; -+ struct device_node *np; -+ int ret; -+ -+ np = of_parse_phandle(wo->hw->node, "mediatek,wo-ccif", 0); -+ if (!np) -+ return -ENODEV; -+ -+ wo->mmio.regs = syscon_regmap_lookup_by_phandle(np, NULL); -+ if (IS_ERR_OR_NULL(wo->mmio.regs)) -+ return PTR_ERR(wo->mmio.regs); -+ -+ wo->mmio.irq = irq_of_parse_and_map(np, 0); -+ wo->mmio.irq_mask = MTK_WED_WO_ALL_INT_MASK; -+ spin_lock_init(&wo->mmio.lock); -+ tasklet_setup(&wo->mmio.irq_tasklet, mtk_wed_wo_irq_tasklet); -+ -+ ret = devm_request_irq(wo->hw->dev, wo->mmio.irq, -+ mtk_wed_wo_irq_handler, IRQF_TRIGGER_HIGH, -+ KBUILD_MODNAME, wo); -+ if (ret) -+ goto error; -+ -+ regs.desc_base = MTK_WED_WO_CCIF_DUMMY1; -+ regs.ring_size = MTK_WED_WO_CCIF_DUMMY2; -+ regs.dma_idx = MTK_WED_WO_CCIF_SHADOW4; -+ regs.cpu_idx = MTK_WED_WO_CCIF_DUMMY3; -+ -+ ret = mtk_wed_wo_queue_alloc(wo, &wo->q_tx, MTK_WED_WO_RING_SIZE, -+ MTK_WED_WO_CMD_LEN, MTK_WED_WO_TXCH_NUM, -+ ®s); -+ if (ret) -+ goto error; -+ -+ mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false); -+ mtk_wed_wo_queue_reset(wo, &wo->q_tx); -+ -+ regs.desc_base = MTK_WED_WO_CCIF_DUMMY5; -+ regs.ring_size = MTK_WED_WO_CCIF_DUMMY6; -+ regs.dma_idx = MTK_WED_WO_CCIF_SHADOW8; -+ regs.cpu_idx = MTK_WED_WO_CCIF_DUMMY7; -+ -+ ret = mtk_wed_wo_queue_alloc(wo, &wo->q_rx, MTK_WED_WO_RING_SIZE, -+ MTK_WED_WO_CMD_LEN, MTK_WED_WO_RXCH_NUM, -+ ®s); -+ if (ret) -+ goto error; -+ -+ mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true); -+ mtk_wed_wo_queue_reset(wo, &wo->q_rx); -+ -+ /* rx queue irqmask */ -+ mtk_wed_wo_set_isr(wo, wo->mmio.irq_mask); -+ -+ return 0; -+ -+error: -+ devm_free_irq(wo->hw->dev, wo->mmio.irq, wo); -+ -+ return ret; -+} -+ -+static void -+mtk_wed_wo_hw_deinit(struct mtk_wed_wo *wo) -+{ -+ /* disable interrupts */ -+ mtk_wed_wo_set_isr(wo, 0); -+ -+ tasklet_disable(&wo->mmio.irq_tasklet); -+ -+ disable_irq(wo->mmio.irq); -+ devm_free_irq(wo->hw->dev, wo->mmio.irq, wo); -+ -+ mtk_wed_wo_queue_tx_clean(wo, &wo->q_tx); -+ mtk_wed_wo_queue_rx_clean(wo, &wo->q_rx); -+ mtk_wed_wo_queue_free(wo, &wo->q_tx); -+ mtk_wed_wo_queue_free(wo, &wo->q_rx); -+} -+ -+int mtk_wed_wo_init(struct mtk_wed_hw *hw) -+{ -+ struct mtk_wed_wo *wo; -+ int ret; -+ -+ wo = devm_kzalloc(hw->dev, sizeof(*wo), GFP_KERNEL); -+ if (!wo) -+ return -ENOMEM; -+ -+ hw->wed_wo = wo; -+ wo->hw = hw; -+ -+ ret = mtk_wed_wo_hardware_init(wo); -+ if (ret) -+ return ret; -+ -+ ret = mtk_wed_mcu_init(wo); -+ if (ret) -+ return ret; -+ -+ return mtk_wed_wo_exception_init(wo); -+} -+ -+void mtk_wed_wo_deinit(struct mtk_wed_hw *hw) -+{ -+ struct mtk_wed_wo *wo = hw->wed_wo; -+ -+ mtk_wed_wo_hw_deinit(wo); -+} ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -80,6 +80,54 @@ enum mtk_wed_dummy_cr_idx { - #define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5) - #define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0) - -+#define MTK_WED_WO_RING_SIZE 256 -+#define MTK_WED_WO_CMD_LEN 1504 -+ -+#define MTK_WED_WO_TXCH_NUM 0 -+#define MTK_WED_WO_RXCH_NUM 1 -+#define MTK_WED_WO_RXCH_WO_EXCEPTION 7 -+ -+#define MTK_WED_WO_TXCH_INT_MASK BIT(0) -+#define MTK_WED_WO_RXCH_INT_MASK BIT(1) -+#define MTK_WED_WO_EXCEPTION_INT_MASK BIT(7) -+#define MTK_WED_WO_ALL_INT_MASK (MTK_WED_WO_RXCH_INT_MASK | \ -+ MTK_WED_WO_EXCEPTION_INT_MASK) -+ -+#define MTK_WED_WO_CCIF_BUSY 0x004 -+#define MTK_WED_WO_CCIF_START 0x008 -+#define MTK_WED_WO_CCIF_TCHNUM 0x00c -+#define MTK_WED_WO_CCIF_RCHNUM 0x010 -+#define MTK_WED_WO_CCIF_RCHNUM_MASK GENMASK(7, 0) -+ -+#define MTK_WED_WO_CCIF_ACK 0x014 -+#define MTK_WED_WO_CCIF_IRQ0_MASK 0x018 -+#define MTK_WED_WO_CCIF_IRQ1_MASK 0x01c -+#define MTK_WED_WO_CCIF_DUMMY1 0x020 -+#define MTK_WED_WO_CCIF_DUMMY2 0x024 -+#define MTK_WED_WO_CCIF_DUMMY3 0x028 -+#define MTK_WED_WO_CCIF_DUMMY4 0x02c -+#define MTK_WED_WO_CCIF_SHADOW1 0x030 -+#define MTK_WED_WO_CCIF_SHADOW2 0x034 -+#define MTK_WED_WO_CCIF_SHADOW3 0x038 -+#define MTK_WED_WO_CCIF_SHADOW4 0x03c -+#define MTK_WED_WO_CCIF_DUMMY5 0x050 -+#define MTK_WED_WO_CCIF_DUMMY6 0x054 -+#define MTK_WED_WO_CCIF_DUMMY7 0x058 -+#define MTK_WED_WO_CCIF_DUMMY8 0x05c -+#define MTK_WED_WO_CCIF_SHADOW5 0x060 -+#define MTK_WED_WO_CCIF_SHADOW6 0x064 -+#define MTK_WED_WO_CCIF_SHADOW7 0x068 -+#define MTK_WED_WO_CCIF_SHADOW8 0x06c -+ -+#define MTK_WED_WO_CTL_SD_LEN1 GENMASK(13, 0) -+#define MTK_WED_WO_CTL_LAST_SEC1 BIT(14) -+#define MTK_WED_WO_CTL_BURST BIT(15) -+#define MTK_WED_WO_CTL_SD_LEN0_SHIFT 16 -+#define MTK_WED_WO_CTL_SD_LEN0 GENMASK(29, 16) -+#define MTK_WED_WO_CTL_LAST_SEC0 BIT(30) -+#define MTK_WED_WO_CTL_DMA_DONE BIT(31) -+#define MTK_WED_WO_INFO_WINFO GENMASK(15, 0) -+ - struct mtk_wed_wo_memory_region { - const char *name; - void __iomem *addr; -@@ -112,10 +160,53 @@ struct mtk_wed_fw_trailer { - u32 crc; - }; - -+struct mtk_wed_wo_queue_regs { -+ u32 desc_base; -+ u32 ring_size; -+ u32 cpu_idx; -+ u32 dma_idx; -+}; -+ -+struct mtk_wed_wo_queue_desc { -+ __le32 buf0; -+ __le32 ctrl; -+ __le32 buf1; -+ __le32 info; -+ __le32 reserved[4]; -+} __packed __aligned(32); -+ -+struct mtk_wed_wo_queue_entry { -+ dma_addr_t addr; -+ void *buf; -+ u32 len; -+}; -+ -+struct mtk_wed_wo_queue { -+ struct mtk_wed_wo_queue_regs regs; -+ -+ struct page_frag_cache cache; -+ spinlock_t lock; -+ -+ struct mtk_wed_wo_queue_desc *desc; -+ dma_addr_t desc_dma; -+ -+ struct mtk_wed_wo_queue_entry *entry; -+ -+ u16 head; -+ u16 tail; -+ int n_desc; -+ int queued; -+ int buf_size; -+ -+}; -+ - struct mtk_wed_wo { - struct mtk_wed_hw *hw; - struct mtk_wed_wo_memory_region boot; - -+ struct mtk_wed_wo_queue q_tx; -+ struct mtk_wed_wo_queue q_rx; -+ - struct { - struct mutex mutex; - int timeout; -@@ -124,6 +215,15 @@ struct mtk_wed_wo { - struct sk_buff_head res_q; - wait_queue_head_t wait; - } mcu; -+ -+ struct { -+ struct regmap *regs; -+ -+ spinlock_t lock; -+ struct tasklet_struct irq_tasklet; -+ int irq; -+ u32 irq_mask; -+ } mmio; - }; - - static inline int -@@ -146,5 +246,9 @@ void mtk_wed_mcu_rx_unsolicited_event(st - int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, - const void *data, int len, bool wait_resp); - int mtk_wed_mcu_init(struct mtk_wed_wo *wo); -+int mtk_wed_wo_init(struct mtk_wed_hw *hw); -+void mtk_wed_wo_deinit(struct mtk_wed_hw *hw); -+int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *dev, struct mtk_wed_wo_queue *q, -+ struct sk_buff *skb); - - #endif /* __MTK_WED_WO_H */ diff --git a/target/linux/generic/backport-5.15/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch b/target/linux/generic/backport-5.15/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch deleted file mode 100644 index a002a5f85163d4..00000000000000 --- a/target/linux/generic/backport-5.15/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch +++ /dev/null @@ -1,79 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 5 Nov 2022 23:36:20 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: rename tx_wdma array in rx_wdma - -Rename tx_wdma queue array in rx_wdma since this is rx side of wdma soc. -Moreover rename mtk_wed_wdma_ring_setup routine in -mtk_wed_wdma_rx_ring_setup() - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -253,8 +253,8 @@ mtk_wed_free_tx_rings(struct mtk_wed_dev - - for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) - mtk_wed_free_ring(dev, &dev->tx_ring[i]); -- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -- mtk_wed_free_ring(dev, &dev->tx_wdma[i]); -+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) -+ mtk_wed_free_ring(dev, &dev->rx_wdma[i]); - } - - static void -@@ -688,10 +688,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device - } - - static int --mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size) -+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size) - { - u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; -- struct mtk_wed_ring *wdma = &dev->tx_wdma[idx]; -+ struct mtk_wed_ring *wdma = &dev->rx_wdma[idx]; - - if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size)) - return -ENOMEM; -@@ -805,9 +805,9 @@ mtk_wed_start(struct mtk_wed_device *dev - { - int i; - -- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -- if (!dev->tx_wdma[i].desc) -- mtk_wed_wdma_ring_setup(dev, i, 16); -+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) -+ if (!dev->rx_wdma[i].desc) -+ mtk_wed_wdma_rx_ring_setup(dev, i, 16); - - mtk_wed_hw_init(dev); - mtk_wed_configure_irq(dev, irq_mask); -@@ -916,7 +916,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - sizeof(*ring->desc))) - return -ENOMEM; - -- if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) - return -ENOMEM; - - ring->reg_base = MTK_WED_RING_TX(idx); ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -7,6 +7,7 @@ - #include - - #define MTK_WED_TX_QUEUES 2 -+#define MTK_WED_RX_QUEUES 2 - - struct mtk_wed_hw; - struct mtk_wdma_desc; -@@ -66,7 +67,7 @@ struct mtk_wed_device { - - struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; - struct mtk_wed_ring txfree_ring; -- struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; -+ struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES]; - - struct { - int size; diff --git a/target/linux/generic/backport-5.15/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch b/target/linux/generic/backport-5.15/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch deleted file mode 100644 index eca29739b4ae38..00000000000000 --- a/target/linux/generic/backport-5.15/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch +++ /dev/null @@ -1,1521 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 5 Nov 2022 23:36:21 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add configure wed wo support - -Enable RX Wireless Ethernet Dispatch available on MT7986 Soc. - -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -23,6 +24,7 @@ - #define MTK_WED_PKT_SIZE 1900 - #define MTK_WED_BUF_SIZE 2048 - #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048) -+#define MTK_WED_RX_RING_SIZE 1536 - - #define MTK_WED_TX_RING_SIZE 2048 - #define MTK_WED_WDMA_RING_SIZE 1024 -@@ -31,6 +33,10 @@ - #define MTK_WED_PER_GROUP_PKT 128 - - #define MTK_WED_FBUF_SIZE 128 -+#define MTK_WED_MIOD_CNT 16 -+#define MTK_WED_FB_CMD_CNT 1024 -+#define MTK_WED_RRO_QUE_CNT 8192 -+#define MTK_WED_MIOD_ENTRY_CNT 128 - - static struct mtk_wed_hw *hw_list[2]; - static DEFINE_MUTEX(hw_lock); -@@ -65,12 +71,76 @@ wdma_set(struct mtk_wed_device *dev, u32 - wdma_m32(dev, reg, 0, mask); - } - -+static void -+wdma_clr(struct mtk_wed_device *dev, u32 reg, u32 mask) -+{ -+ wdma_m32(dev, reg, mask, 0); -+} -+ -+static u32 -+wifi_r32(struct mtk_wed_device *dev, u32 reg) -+{ -+ return readl(dev->wlan.base + reg); -+} -+ -+static void -+wifi_w32(struct mtk_wed_device *dev, u32 reg, u32 val) -+{ -+ writel(val, dev->wlan.base + reg); -+} -+ - static u32 - mtk_wed_read_reset(struct mtk_wed_device *dev) - { - return wed_r32(dev, MTK_WED_RESET); - } - -+static u32 -+mtk_wdma_read_reset(struct mtk_wed_device *dev) -+{ -+ return wdma_r32(dev, MTK_WDMA_GLO_CFG); -+} -+ -+static void -+mtk_wdma_rx_reset(struct mtk_wed_device *dev) -+{ -+ u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY; -+ int i; -+ -+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN); -+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, -+ !(status & mask), 0, 1000)) -+ dev_err(dev->hw->dev, "rx reset failed\n"); -+ -+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) { -+ if (dev->rx_wdma[i].desc) -+ continue; -+ -+ wdma_w32(dev, -+ MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); -+ } -+} -+ -+static void -+mtk_wdma_tx_reset(struct mtk_wed_device *dev) -+{ -+ u32 status, mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY; -+ int i; -+ -+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); -+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, -+ !(status & mask), 0, 1000)) -+ dev_err(dev->hw->dev, "tx reset failed\n"); -+ -+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) { -+ if (dev->tx_wdma[i].desc) -+ continue; -+ -+ wdma_w32(dev, -+ MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); -+ } -+} -+ - static void - mtk_wed_reset(struct mtk_wed_device *dev, u32 mask) - { -@@ -82,6 +152,54 @@ mtk_wed_reset(struct mtk_wed_device *dev - WARN_ON_ONCE(1); - } - -+static u32 -+mtk_wed_wo_read_status(struct mtk_wed_device *dev) -+{ -+ return wed_r32(dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_WO_STATUS); -+} -+ -+static void -+mtk_wed_wo_reset(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_wo *wo = dev->hw->wed_wo; -+ u8 state = MTK_WED_WO_STATE_DISABLE; -+ void __iomem *reg; -+ u32 val; -+ -+ mtk_wdma_tx_reset(dev); -+ mtk_wed_reset(dev, MTK_WED_RESET_WED); -+ -+ mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -+ MTK_WED_WO_CMD_CHANGE_STATE, &state, -+ sizeof(state), false); -+ -+ if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val, -+ val == MTK_WED_WOIF_DISABLE_DONE, -+ 100, MTK_WOCPU_TIMEOUT)) -+ dev_err(dev->hw->dev, "failed to disable wed-wo\n"); -+ -+ reg = ioremap(MTK_WED_WO_CPU_MCUSYS_RESET_ADDR, 4); -+ -+ val = readl(reg); -+ switch (dev->hw->index) { -+ case 0: -+ val |= MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK; -+ writel(val, reg); -+ val &= ~MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK; -+ writel(val, reg); -+ break; -+ case 1: -+ val |= MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK; -+ writel(val, reg); -+ val &= ~MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK; -+ writel(val, reg); -+ break; -+ default: -+ break; -+ } -+ iounmap(reg); -+} -+ - static struct mtk_wed_hw * - mtk_wed_assign(struct mtk_wed_device *dev) - { -@@ -116,7 +234,7 @@ out: - } - - static int --mtk_wed_buffer_alloc(struct mtk_wed_device *dev) -+mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) - { - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -@@ -133,16 +251,16 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi - if (!page_list) - return -ENOMEM; - -- dev->buf_ring.size = ring_size; -- dev->buf_ring.pages = page_list; -+ dev->tx_buf_ring.size = ring_size; -+ dev->tx_buf_ring.pages = page_list; - - desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc), - &desc_phys, GFP_KERNEL); - if (!desc) - return -ENOMEM; - -- dev->buf_ring.desc = desc; -- dev->buf_ring.desc_phys = desc_phys; -+ dev->tx_buf_ring.desc = desc; -+ dev->tx_buf_ring.desc_phys = desc_phys; - - for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) { - dma_addr_t page_phys, buf_phys; -@@ -203,10 +321,10 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi - } - - static void --mtk_wed_free_buffer(struct mtk_wed_device *dev) -+mtk_wed_free_tx_buffer(struct mtk_wed_device *dev) - { -- struct mtk_wdma_desc *desc = dev->buf_ring.desc; -- void **page_list = dev->buf_ring.pages; -+ struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc; -+ void **page_list = dev->tx_buf_ring.pages; - int page_idx; - int i; - -@@ -216,7 +334,8 @@ mtk_wed_free_buffer(struct mtk_wed_devic - if (!desc) - goto free_pagelist; - -- for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) { -+ for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size; -+ i += MTK_WED_BUF_PER_PAGE) { - void *page = page_list[page_idx++]; - dma_addr_t buf_addr; - -@@ -229,13 +348,59 @@ mtk_wed_free_buffer(struct mtk_wed_devic - __free_page(page); - } - -- dma_free_coherent(dev->hw->dev, dev->buf_ring.size * sizeof(*desc), -- desc, dev->buf_ring.desc_phys); -+ dma_free_coherent(dev->hw->dev, dev->tx_buf_ring.size * sizeof(*desc), -+ desc, dev->tx_buf_ring.desc_phys); - - free_pagelist: - kfree(page_list); - } - -+static int -+mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev) -+{ -+ struct mtk_rxbm_desc *desc; -+ dma_addr_t desc_phys; -+ -+ dev->rx_buf_ring.size = dev->wlan.rx_nbuf; -+ desc = dma_alloc_coherent(dev->hw->dev, -+ dev->wlan.rx_nbuf * sizeof(*desc), -+ &desc_phys, GFP_KERNEL); -+ if (!desc) -+ return -ENOMEM; -+ -+ dev->rx_buf_ring.desc = desc; -+ dev->rx_buf_ring.desc_phys = desc_phys; -+ dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt); -+ -+ return 0; -+} -+ -+static void -+mtk_wed_free_rx_buffer(struct mtk_wed_device *dev) -+{ -+ struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc; -+ -+ if (!desc) -+ return; -+ -+ dev->wlan.release_rx_buf(dev); -+ dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc), -+ desc, dev->rx_buf_ring.desc_phys); -+} -+ -+static void -+mtk_wed_rx_buffer_hw_init(struct mtk_wed_device *dev) -+{ -+ wed_w32(dev, MTK_WED_RX_BM_RX_DMAD, -+ FIELD_PREP(MTK_WED_RX_BM_RX_DMAD_SDL0, dev->wlan.rx_size)); -+ wed_w32(dev, MTK_WED_RX_BM_BASE, dev->rx_buf_ring.desc_phys); -+ wed_w32(dev, MTK_WED_RX_BM_INIT_PTR, MTK_WED_RX_BM_INIT_SW_TAIL | -+ FIELD_PREP(MTK_WED_RX_BM_SW_TAIL, dev->wlan.rx_npkt)); -+ wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH, -+ FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff)); -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); -+} -+ - static void - mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring) - { -@@ -247,6 +412,13 @@ mtk_wed_free_ring(struct mtk_wed_device - } - - static void -+mtk_wed_free_rx_rings(struct mtk_wed_device *dev) -+{ -+ mtk_wed_free_rx_buffer(dev); -+ mtk_wed_free_ring(dev, &dev->rro.ring); -+} -+ -+static void - mtk_wed_free_tx_rings(struct mtk_wed_device *dev) - { - int i; -@@ -291,6 +463,38 @@ mtk_wed_set_512_support(struct mtk_wed_d - } - } - -+#define MTK_WFMDA_RX_DMA_EN BIT(2) -+static void -+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx) -+{ -+ u32 val; -+ int i; -+ -+ if (!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED)) -+ return; /* queue is not configured by mt76 */ -+ -+ for (i = 0; i < 3; i++) { -+ u32 cur_idx; -+ -+ cur_idx = wed_r32(dev, -+ MTK_WED_WPDMA_RING_RX_DATA(idx) + -+ MTK_WED_RING_OFS_CPU_IDX); -+ if (cur_idx == MTK_WED_RX_RING_SIZE - 1) -+ break; -+ -+ usleep_range(100000, 200000); -+ } -+ -+ if (i == 3) { -+ dev_err(dev->hw->dev, "rx dma enable failed\n"); -+ return; -+ } -+ -+ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) | -+ MTK_WFMDA_RX_DMA_EN; -+ wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val); -+} -+ - static void - mtk_wed_dma_disable(struct mtk_wed_device *dev) - { -@@ -304,20 +508,25 @@ mtk_wed_dma_disable(struct mtk_wed_devic - MTK_WED_GLO_CFG_TX_DMA_EN | - MTK_WED_GLO_CFG_RX_DMA_EN); - -- wdma_m32(dev, MTK_WDMA_GLO_CFG, -+ wdma_clr(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_TX_DMA_EN | - MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0); -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); - - if (dev->hw->version == 1) { - regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); -- wdma_m32(dev, MTK_WDMA_GLO_CFG, -- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); -+ wdma_clr(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); - } else { - wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); - -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RX_DRV_EN); -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); -+ - mtk_wed_set_512_support(dev, false); - } - } -@@ -338,6 +547,13 @@ mtk_wed_stop(struct mtk_wed_device *dev) - wdma_w32(dev, MTK_WDMA_INT_MASK, 0); - wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); -+ -+ if (dev->hw->version == 1) -+ return; -+ -+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); -+ wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0); -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); - } - - static void -@@ -353,11 +569,21 @@ mtk_wed_detach(struct mtk_wed_device *de - wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); - - mtk_wed_reset(dev, MTK_WED_RESET_WED); -+ if (mtk_wed_get_rx_capa(dev)) { -+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -+ } - -- mtk_wed_free_buffer(dev); -+ mtk_wed_free_tx_buffer(dev); - mtk_wed_free_tx_rings(dev); -- if (hw->version != 1) -+ -+ if (mtk_wed_get_rx_capa(dev)) { -+ mtk_wed_wo_reset(dev); -+ mtk_wed_free_rx_rings(dev); - mtk_wed_wo_deinit(hw); -+ mtk_wdma_rx_reset(dev); -+ } - - if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { - struct device_node *wlan_node; -@@ -434,10 +660,12 @@ mtk_wed_set_wpdma(struct mtk_wed_device - } else { - mtk_wed_bus_init(dev); - -- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); -- wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); -- wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); -- wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); -+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); -+ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx); - } - } - -@@ -487,6 +715,132 @@ mtk_wed_hw_init_early(struct mtk_wed_dev - } - } - -+static int -+mtk_wed_rro_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, -+ int size) -+{ -+ ring->desc = dma_alloc_coherent(dev->hw->dev, -+ size * sizeof(*ring->desc), -+ &ring->desc_phys, GFP_KERNEL); -+ if (!ring->desc) -+ return -ENOMEM; -+ -+ ring->desc_size = sizeof(*ring->desc); -+ ring->size = size; -+ memset(ring->desc, 0, size); -+ -+ return 0; -+} -+ -+#define MTK_WED_MIOD_COUNT (MTK_WED_MIOD_ENTRY_CNT * MTK_WED_MIOD_CNT) -+static int -+mtk_wed_rro_alloc(struct mtk_wed_device *dev) -+{ -+ struct reserved_mem *rmem; -+ struct device_node *np; -+ int index; -+ -+ index = of_property_match_string(dev->hw->node, "memory-region-names", -+ "wo-dlm"); -+ if (index < 0) -+ return index; -+ -+ np = of_parse_phandle(dev->hw->node, "memory-region", index); -+ if (!np) -+ return -ENODEV; -+ -+ rmem = of_reserved_mem_lookup(np); -+ of_node_put(np); -+ -+ if (!rmem) -+ return -ENODEV; -+ -+ dev->rro.miod_phys = rmem->base; -+ dev->rro.fdbk_phys = MTK_WED_MIOD_COUNT + dev->rro.miod_phys; -+ -+ return mtk_wed_rro_ring_alloc(dev, &dev->rro.ring, -+ MTK_WED_RRO_QUE_CNT); -+} -+ -+static int -+mtk_wed_rro_cfg(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_wo *wo = dev->hw->wed_wo; -+ struct { -+ struct { -+ __le32 base; -+ __le32 cnt; -+ __le32 unit; -+ } ring[2]; -+ __le32 wed; -+ u8 version; -+ } req = { -+ .ring[0] = { -+ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE), -+ .cnt = cpu_to_le32(MTK_WED_MIOD_CNT), -+ .unit = cpu_to_le32(MTK_WED_MIOD_ENTRY_CNT), -+ }, -+ .ring[1] = { -+ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE + -+ MTK_WED_MIOD_COUNT), -+ .cnt = cpu_to_le32(MTK_WED_FB_CMD_CNT), -+ .unit = cpu_to_le32(4), -+ }, -+ }; -+ -+ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -+ MTK_WED_WO_CMD_WED_CFG, -+ &req, sizeof(req), true); -+} -+ -+static void -+mtk_wed_rro_hw_init(struct mtk_wed_device *dev) -+{ -+ wed_w32(dev, MTK_WED_RROQM_MIOD_CFG, -+ FIELD_PREP(MTK_WED_RROQM_MIOD_MID_DW, 0x70 >> 2) | -+ FIELD_PREP(MTK_WED_RROQM_MIOD_MOD_DW, 0x10 >> 2) | -+ FIELD_PREP(MTK_WED_RROQM_MIOD_ENTRY_DW, -+ MTK_WED_MIOD_ENTRY_CNT >> 2)); -+ -+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL0, dev->rro.miod_phys); -+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL1, -+ FIELD_PREP(MTK_WED_RROQM_MIOD_CNT, MTK_WED_MIOD_CNT)); -+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL0, dev->rro.fdbk_phys); -+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL1, -+ FIELD_PREP(MTK_WED_RROQM_FDBK_CNT, MTK_WED_FB_CMD_CNT)); -+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL2, 0); -+ wed_w32(dev, MTK_WED_RROQ_BASE_L, dev->rro.ring.desc_phys); -+ -+ wed_set(dev, MTK_WED_RROQM_RST_IDX, -+ MTK_WED_RROQM_RST_IDX_MIOD | -+ MTK_WED_RROQM_RST_IDX_FDBK); -+ -+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0); -+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL2, MTK_WED_MIOD_CNT - 1); -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN); -+} -+ -+static void -+mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev) -+{ -+ wed_w32(dev, MTK_WED_RESET, MTK_WED_RESET_RX_ROUTE_QM); -+ -+ for (;;) { -+ usleep_range(100, 200); -+ if (!(wed_r32(dev, MTK_WED_RESET) & MTK_WED_RESET_RX_ROUTE_QM)) -+ break; -+ } -+ -+ /* configure RX_ROUTE_QM */ -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT); -+ wed_set(dev, MTK_WED_RTQM_GLO_CFG, -+ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index)); -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ /* enable RX_ROUTE_QM */ -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); -+} -+ - static void - mtk_wed_hw_init(struct mtk_wed_device *dev) - { -@@ -498,11 +852,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d - wed_w32(dev, MTK_WED_TX_BM_CTRL, - MTK_WED_TX_BM_CTRL_PAUSE | - FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, -- dev->buf_ring.size / 128) | -+ dev->tx_buf_ring.size / 128) | - FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, - MTK_WED_TX_RING_SIZE / 256)); - -- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys); -+ wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys); - - wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); - -@@ -529,9 +883,9 @@ mtk_wed_hw_init(struct mtk_wed_device *d - wed_w32(dev, MTK_WED_TX_TKID_CTRL, - MTK_WED_TX_TKID_CTRL_PAUSE | - FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM, -- dev->buf_ring.size / 128) | -+ dev->tx_buf_ring.size / 128) | - FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM, -- dev->buf_ring.size / 128)); -+ dev->tx_buf_ring.size / 128)); - wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, - FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | - MTK_WED_TX_TKID_DYN_THR_HI); -@@ -539,18 +893,28 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - -- if (dev->hw->version == 1) -+ if (dev->hw->version == 1) { - wed_set(dev, MTK_WED_CTRL, - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -- else -+ } else { - wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); -+ /* rx hw init */ -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -+ -+ mtk_wed_rx_buffer_hw_init(dev); -+ mtk_wed_rro_hw_init(dev); -+ mtk_wed_route_qm_hw_init(dev); -+ } - - wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); - } - - static void --mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size) -+mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size, bool tx) - { - void *head = (void *)ring->desc; - int i; -@@ -560,7 +924,10 @@ mtk_wed_ring_reset(struct mtk_wed_ring * - - desc = (struct mtk_wdma_desc *)(head + i * ring->desc_size); - desc->buf0 = 0; -- desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ if (tx) -+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ else -+ desc->ctrl = cpu_to_le32(MTK_WFDMA_DESC_CTRL_TO_HOST); - desc->buf1 = 0; - desc->info = 0; - } -@@ -616,7 +983,8 @@ mtk_wed_reset_dma(struct mtk_wed_device - if (!dev->tx_ring[i].desc) - continue; - -- mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE); -+ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE, -+ true); - } - - if (mtk_wed_poll_busy(dev)) -@@ -634,6 +1002,9 @@ mtk_wed_reset_dma(struct mtk_wed_device - wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); - wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); - -+ if (mtk_wed_get_rx_capa(dev)) -+ mtk_wdma_rx_reset(dev); -+ - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV); -@@ -668,12 +1039,11 @@ mtk_wed_reset_dma(struct mtk_wed_device - MTK_WED_WPDMA_RESET_IDX_RX); - wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0); - } -- - } - - static int - mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, -- int size, u32 desc_size) -+ int size, u32 desc_size, bool tx) - { - ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size, - &ring->desc_phys, GFP_KERNEL); -@@ -682,7 +1052,7 @@ mtk_wed_ring_alloc(struct mtk_wed_device - - ring->desc_size = desc_size; - ring->size = size; -- mtk_wed_ring_reset(ring, size); -+ mtk_wed_ring_reset(ring, size, tx); - - return 0; - } -@@ -691,9 +1061,14 @@ static int - mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size) - { - u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; -- struct mtk_wed_ring *wdma = &dev->rx_wdma[idx]; -+ struct mtk_wed_ring *wdma; - -- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size)) -+ if (idx >= ARRAY_SIZE(dev->rx_wdma)) -+ return -EINVAL; -+ -+ wdma = &dev->rx_wdma[idx]; -+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, -+ true)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -@@ -710,6 +1085,60 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we - return 0; - } - -+static int -+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size) -+{ -+ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; -+ struct mtk_wed_ring *wdma; -+ -+ if (idx >= ARRAY_SIZE(dev->tx_wdma)) -+ return -EINVAL; -+ -+ wdma = &dev->tx_wdma[idx]; -+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, -+ true)) -+ return -ENOMEM; -+ -+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, -+ wdma->desc_phys); -+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT, -+ size); -+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0); -+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0); -+ -+ if (!idx) { -+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE, -+ wdma->desc_phys); -+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_COUNT, -+ size); -+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_CPU_IDX, -+ 0); -+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_DMA_IDX, -+ 0); -+ } -+ -+ return 0; -+} -+ -+static void -+mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb, -+ u32 reason, u32 hash) -+{ -+ struct mtk_eth *eth = dev->hw->eth; -+ struct ethhdr *eh; -+ -+ if (!skb) -+ return; -+ -+ if (reason != MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -+ return; -+ -+ skb_set_mac_header(skb, 0); -+ eh = eth_hdr(skb); -+ skb->protocol = eh->h_proto; -+ mtk_ppe_check_skb(eth->ppe[dev->hw->index], skb, hash); -+} -+ - static void - mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask) - { -@@ -732,6 +1161,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev - - wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); - } else { -+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE, -+ GENMASK(1, 0)); - /* initail tx interrupt trigger */ - wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, - MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | -@@ -750,6 +1181,16 @@ mtk_wed_configure_irq(struct mtk_wed_dev - FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG, - dev->wlan.txfree_tbit)); - -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX, -+ MTK_WED_WPDMA_INT_CTRL_RX0_EN | -+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR | -+ MTK_WED_WPDMA_INT_CTRL_RX1_EN | -+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG, -+ dev->wlan.rx_tbit[0]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG, -+ dev->wlan.rx_tbit[1])); -+ - wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask); - wed_set(dev, MTK_WED_WDMA_INT_CTRL, - FIELD_PREP(MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL, -@@ -787,9 +1228,15 @@ mtk_wed_dma_enable(struct mtk_wed_device - wdma_set(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); - } else { -+ int i; -+ - wed_set(dev, MTK_WED_WPDMA_CTRL, - MTK_WED_WPDMA_CTRL_SDL1_FIXED); - -+ wed_set(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); -+ - wed_set(dev, MTK_WED_WPDMA_GLO_CFG, - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -@@ -797,6 +1244,15 @@ mtk_wed_dma_enable(struct mtk_wed_device - wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, - MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | - MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); -+ -+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RX_DRV_EN | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, -+ 0x2)); -+ -+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) -+ mtk_wed_check_wfdma_rx_fill(dev, i); - } - } - -@@ -822,7 +1278,19 @@ mtk_wed_start(struct mtk_wed_device *dev - val |= BIT(0) | (BIT(1) * !!dev->hw->index); - regmap_write(dev->hw->mirror, dev->hw->index * 4, val); - } else { -- mtk_wed_set_512_support(dev, true); -+ /* driver set mid ready and only once */ -+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, -+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); -+ wed_w32(dev, MTK_WED_EXT_INT_MASK2, -+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); -+ -+ wed_r32(dev, MTK_WED_EXT_INT_MASK1); -+ wed_r32(dev, MTK_WED_EXT_INT_MASK2); -+ -+ if (mtk_wed_rro_cfg(dev)) -+ return; -+ -+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512); - } - - mtk_wed_dma_enable(dev); -@@ -856,7 +1324,7 @@ mtk_wed_attach(struct mtk_wed_device *de - if (!hw) { - module_put(THIS_MODULE); - ret = -ENODEV; -- goto out; -+ goto unlock; - } - - device = dev->wlan.bus_type == MTK_WED_BUS_PCIE -@@ -869,15 +1337,24 @@ mtk_wed_attach(struct mtk_wed_device *de - dev->dev = hw->dev; - dev->irq = hw->irq; - dev->wdma_idx = hw->index; -+ dev->version = hw->version; - - if (hw->eth->dma_dev == hw->eth->dev && - of_dma_is_coherent(hw->eth->dev->of_node)) - mtk_eth_set_dma_device(hw->eth, hw->dev); - -- ret = mtk_wed_buffer_alloc(dev); -- if (ret) { -- mtk_wed_detach(dev); -+ ret = mtk_wed_tx_buffer_alloc(dev); -+ if (ret) - goto out; -+ -+ if (mtk_wed_get_rx_capa(dev)) { -+ ret = mtk_wed_rx_buffer_alloc(dev); -+ if (ret) -+ goto out; -+ -+ ret = mtk_wed_rro_alloc(dev); -+ if (ret) -+ goto out; - } - - mtk_wed_hw_init_early(dev); -@@ -886,8 +1363,10 @@ mtk_wed_attach(struct mtk_wed_device *de - BIT(hw->index), 0); - else - ret = mtk_wed_wo_init(hw); -- - out: -+ if (ret) -+ mtk_wed_detach(dev); -+unlock: - mutex_unlock(&hw_lock); - - return ret; -@@ -910,10 +1389,11 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - * WDMA RX. - */ - -- BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring)); -+ if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring))) -+ return -EINVAL; - - if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, -- sizeof(*ring->desc))) -+ sizeof(*ring->desc), true)) - return -ENOMEM; - - if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -@@ -960,6 +1440,37 @@ mtk_wed_txfree_ring_setup(struct mtk_wed - return 0; - } - -+static int -+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) -+{ -+ struct mtk_wed_ring *ring = &dev->rx_ring[idx]; -+ -+ if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring))) -+ return -EINVAL; -+ -+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, -+ sizeof(*ring->desc), false)) -+ return -ENOMEM; -+ -+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -+ return -ENOMEM; -+ -+ ring->reg_base = MTK_WED_RING_RX_DATA(idx); -+ ring->wpdma = regs; -+ ring->flags |= MTK_WED_RING_CONFIGURED; -+ -+ /* WPDMA -> WED */ -+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys); -+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_RX_RING_SIZE); -+ -+ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_BASE, -+ ring->desc_phys); -+ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_COUNT, -+ MTK_WED_RX_RING_SIZE); -+ -+ return 0; -+} -+ - static u32 - mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) - { -@@ -1056,7 +1567,9 @@ void mtk_wed_add_hw(struct device_node * - static const struct mtk_wed_ops wed_ops = { - .attach = mtk_wed_attach, - .tx_ring_setup = mtk_wed_tx_ring_setup, -+ .rx_ring_setup = mtk_wed_rx_ring_setup, - .txfree_ring_setup = mtk_wed_txfree_ring_setup, -+ .msg_update = mtk_wed_mcu_msg_update, - .start = mtk_wed_start, - .stop = mtk_wed_stop, - .reset_dma = mtk_wed_reset_dma, -@@ -1065,6 +1578,7 @@ void mtk_wed_add_hw(struct device_node * - .irq_get = mtk_wed_irq_get, - .irq_set_mask = mtk_wed_irq_set_mask, - .detach = mtk_wed_detach, -+ .ppe_check = mtk_wed_ppe_check, - }; - struct device_node *eth_np = eth->dev->of_node; - struct platform_device *pdev; ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -87,6 +87,24 @@ wpdma_tx_w32(struct mtk_wed_device *dev, - } - - static inline u32 -+wpdma_rx_r32(struct mtk_wed_device *dev, int ring, u32 reg) -+{ -+ if (!dev->rx_ring[ring].wpdma) -+ return 0; -+ -+ return readl(dev->rx_ring[ring].wpdma + reg); -+} -+ -+static inline void -+wpdma_rx_w32(struct mtk_wed_device *dev, int ring, u32 reg, u32 val) -+{ -+ if (!dev->rx_ring[ring].wpdma) -+ return; -+ -+ writel(val, dev->rx_ring[ring].wpdma + reg); -+} -+ -+static inline u32 - wpdma_txfree_r32(struct mtk_wed_device *dev, u32 reg) - { - if (!dev->txfree_ring.wpdma) -@@ -128,6 +146,7 @@ static inline int mtk_wed_flow_add(int i - static inline void mtk_wed_flow_remove(int index) - { - } -+ - #endif - - #ifdef CONFIG_DEBUG_FS ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #include "mtk_wed_regs.h" - #include "mtk_wed_wo.h" -@@ -60,24 +61,37 @@ void mtk_wed_mcu_rx_event(struct mtk_wed - wake_up(&wo->mcu.wait); - } - -+static void -+mtk_wed_update_rx_stats(struct mtk_wed_device *wed, struct sk_buff *skb) -+{ -+ u32 count = get_unaligned_le32(skb->data); -+ struct mtk_wed_wo_rx_stats *stats; -+ int i; -+ -+ if (count * sizeof(*stats) > skb->len - sizeof(u32)) -+ return; -+ -+ stats = (struct mtk_wed_wo_rx_stats *)(skb->data + sizeof(u32)); -+ for (i = 0 ; i < count ; i++) -+ wed->wlan.update_wo_rx_stats(wed, &stats[i]); -+} -+ - void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, - struct sk_buff *skb) - { - struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data; - -- switch (hdr->cmd) { -- case MTK_WED_WO_EVT_LOG_DUMP: { -- const char *msg = (const char *)(skb->data + sizeof(*hdr)); -+ skb_pull(skb, sizeof(*hdr)); - -- dev_notice(wo->hw->dev, "%s\n", msg); -+ switch (hdr->cmd) { -+ case MTK_WED_WO_EVT_LOG_DUMP: -+ dev_notice(wo->hw->dev, "%s\n", skb->data); - break; -- } - case MTK_WED_WO_EVT_PROFILING: { -- struct mtk_wed_wo_log_info *info; -- u32 count = (skb->len - sizeof(*hdr)) / sizeof(*info); -+ struct mtk_wed_wo_log_info *info = (void *)skb->data; -+ u32 count = skb->len / sizeof(*info); - int i; - -- info = (struct mtk_wed_wo_log_info *)(skb->data + sizeof(*hdr)); - for (i = 0 ; i < count ; i++) - dev_notice(wo->hw->dev, - "SN:%u latency: total=%u, rro:%u, mod:%u\n", -@@ -88,6 +102,7 @@ void mtk_wed_mcu_rx_unsolicited_event(st - break; - } - case MTK_WED_WO_EVT_RXCNT_INFO: -+ mtk_wed_update_rx_stats(wo->hw->wed_dev, skb); - break; - default: - break; -@@ -144,6 +159,8 @@ mtk_wed_mcu_parse_response(struct mtk_we - skb_pull(skb, sizeof(*hdr)); - switch (cmd) { - case MTK_WED_WO_CMD_RXCNT_INFO: -+ mtk_wed_update_rx_stats(wo->hw->wed_dev, skb); -+ break; - default: - break; - } -@@ -182,6 +199,18 @@ unlock: - return ret; - } - -+int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, -+ int len) -+{ -+ struct mtk_wed_wo *wo = dev->hw->wed_wo; -+ -+ if (dev->hw->version == 1) -+ return 0; -+ -+ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len, -+ true); -+} -+ - static int - mtk_wed_get_memory_region(struct mtk_wed_wo *wo, - struct mtk_wed_wo_memory_region *region) ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -4,6 +4,7 @@ - #ifndef __MTK_WED_REGS_H - #define __MTK_WED_REGS_H - -+#define MTK_WFDMA_DESC_CTRL_TO_HOST BIT(8) - #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0) - #define MTK_WDMA_DESC_CTRL_LEN1_V2 GENMASK(13, 0) - #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15) -@@ -28,6 +29,8 @@ struct mtk_wdma_desc { - #define MTK_WED_RESET_WED_TX_DMA BIT(12) - #define MTK_WED_RESET_WDMA_RX_DRV BIT(17) - #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19) -+#define MTK_WED_RESET_RX_RRO_QM BIT(20) -+#define MTK_WED_RESET_RX_ROUTE_QM BIT(21) - #define MTK_WED_RESET_WED BIT(31) - - #define MTK_WED_CTRL 0x00c -@@ -39,8 +42,12 @@ struct mtk_wdma_desc { - #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9) - #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10) - #define MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY BIT(11) --#define MTK_WED_CTRL_RESERVE_EN BIT(12) --#define MTK_WED_CTRL_RESERVE_BUSY BIT(13) -+#define MTK_WED_CTRL_WED_RX_BM_EN BIT(12) -+#define MTK_WED_CTRL_WED_RX_BM_BUSY BIT(13) -+#define MTK_WED_CTRL_RX_RRO_QM_EN BIT(14) -+#define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15) -+#define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16) -+#define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17) - #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24) - #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25) - #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28) -@@ -62,6 +69,9 @@ struct mtk_wdma_desc { - #define MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR BIT(22) - #define MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR BIT(23) - #define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24) -+#define MTK_WED_EXT_INT_STATUS_RX_DRV_GET_BM_DMAD_SKIP BIT(25) -+#define MTK_WED_EXT_INT_STATUS_WPDMA_RX_D_DRV_ERR BIT(26) -+#define MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY BIT(27) - #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \ - MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \ - MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \ -@@ -71,6 +81,8 @@ struct mtk_wdma_desc { - MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR) - - #define MTK_WED_EXT_INT_MASK 0x028 -+#define MTK_WED_EXT_INT_MASK1 0x02c -+#define MTK_WED_EXT_INT_MASK2 0x030 - - #define MTK_WED_STATUS 0x060 - #define MTK_WED_STATUS_TX GENMASK(15, 8) -@@ -151,6 +163,7 @@ struct mtk_wdma_desc { - #define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10) - - #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10) -+#define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10) - - #define MTK_WED_SCR0 0x3c0 - #define MTK_WED_WPDMA_INT_TRIGGER 0x504 -@@ -213,6 +226,12 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10) - - #define MTK_WED_WPDMA_INT_CTRL_RX 0x534 -+#define MTK_WED_WPDMA_INT_CTRL_RX0_EN BIT(0) -+#define MTK_WED_WPDMA_INT_CTRL_RX0_CLR BIT(1) -+#define MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG GENMASK(6, 2) -+#define MTK_WED_WPDMA_INT_CTRL_RX1_EN BIT(8) -+#define MTK_WED_WPDMA_INT_CTRL_RX1_CLR BIT(9) -+#define MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG GENMASK(14, 10) - - #define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538 - #define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0) -@@ -242,11 +261,34 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10) - #define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10) -+#define MTK_WED_WPDMA_RING_RX_DATA(_n) (0x730 + (_n) * 0x10) -+ -+#define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c -+#define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0) -+#define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7) -+#define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24) -+ -+#define MTK_WED_WPDMA_RX_D_RST_IDX 0x760 -+#define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16) -+#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24) -+ -+#define MTK_WED_WPDMA_RX_GLO_CFG 0x76c -+#define MTK_WED_WPDMA_RX_RING 0x770 -+ -+#define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4) -+#define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4) -+#define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c -+ -+#define MTK_WED_WDMA_RING_TX 0x800 -+ -+#define MTK_WED_WDMA_TX_MIB 0x810 -+ - #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10) - #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4) - - #define MTK_WED_WDMA_GLO_CFG 0xa04 - #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0) -+#define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1) - #define MTK_WED_WDMA_GLO_CFG_RX_DRV_EN BIT(2) - #define MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY BIT(3) - #define MTK_WED_WDMA_GLO_CFG_BT_SIZE GENMASK(5, 4) -@@ -291,6 +333,20 @@ struct mtk_wdma_desc { - #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4) - #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4) - -+#define MTK_WED_RX_BM_RX_DMAD 0xd80 -+#define MTK_WED_RX_BM_RX_DMAD_SDL0 GENMASK(13, 0) -+ -+#define MTK_WED_RX_BM_BASE 0xd84 -+#define MTK_WED_RX_BM_INIT_PTR 0xd88 -+#define MTK_WED_RX_BM_SW_TAIL GENMASK(15, 0) -+#define MTK_WED_RX_BM_INIT_SW_TAIL BIT(16) -+ -+#define MTK_WED_RX_PTR 0xd8c -+ -+#define MTK_WED_RX_BM_DYN_ALLOC_TH 0xdb4 -+#define MTK_WED_RX_BM_DYN_ALLOC_TH_H GENMASK(31, 16) -+#define MTK_WED_RX_BM_DYN_ALLOC_TH_L GENMASK(15, 0) -+ - #define MTK_WED_RING_OFS_BASE 0x00 - #define MTK_WED_RING_OFS_COUNT 0x04 - #define MTK_WED_RING_OFS_CPU_IDX 0x08 -@@ -301,7 +357,9 @@ struct mtk_wdma_desc { - - #define MTK_WDMA_GLO_CFG 0x204 - #define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0) -+#define MTK_WDMA_GLO_CFG_TX_DMA_BUSY BIT(1) - #define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2) -+#define MTK_WDMA_GLO_CFG_RX_DMA_BUSY BIT(3) - #define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26) - #define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27) - #define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28) -@@ -330,4 +388,70 @@ struct mtk_wdma_desc { - /* DMA channel mapping */ - #define HIFSYS_DMA_AG_MAP 0x008 - -+#define MTK_WED_RTQM_GLO_CFG 0xb00 -+#define MTK_WED_RTQM_BUSY BIT(1) -+#define MTK_WED_RTQM_Q_RST BIT(2) -+#define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5) -+#define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20) -+ -+#define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4) -+#define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4) -+#define MTK_WED_RTQM_Q2N_MIB 0xb80 -+#define MTK_WED_RTQM_Q2H_MIB(_n) (0xb84 + (_n) * 0x4) -+ -+#define MTK_WED_RTQM_Q2B_MIB 0xb8c -+#define MTK_WED_RTQM_PFDBK_MIB 0xb90 -+ -+#define MTK_WED_RROQM_GLO_CFG 0xc04 -+#define MTK_WED_RROQM_RST_IDX 0xc08 -+#define MTK_WED_RROQM_RST_IDX_MIOD BIT(0) -+#define MTK_WED_RROQM_RST_IDX_FDBK BIT(4) -+ -+#define MTK_WED_RROQM_MIOD_CTRL0 0xc40 -+#define MTK_WED_RROQM_MIOD_CTRL1 0xc44 -+#define MTK_WED_RROQM_MIOD_CNT GENMASK(11, 0) -+ -+#define MTK_WED_RROQM_MIOD_CTRL2 0xc48 -+#define MTK_WED_RROQM_MIOD_CTRL3 0xc4c -+ -+#define MTK_WED_RROQM_FDBK_CTRL0 0xc50 -+#define MTK_WED_RROQM_FDBK_CTRL1 0xc54 -+#define MTK_WED_RROQM_FDBK_CNT GENMASK(11, 0) -+ -+#define MTK_WED_RROQM_FDBK_CTRL2 0xc58 -+ -+#define MTK_WED_RROQ_BASE_L 0xc80 -+#define MTK_WED_RROQ_BASE_H 0xc84 -+ -+#define MTK_WED_RROQM_MIOD_CFG 0xc8c -+#define MTK_WED_RROQM_MIOD_MID_DW GENMASK(5, 0) -+#define MTK_WED_RROQM_MIOD_MOD_DW GENMASK(13, 8) -+#define MTK_WED_RROQM_MIOD_ENTRY_DW GENMASK(22, 16) -+ -+#define MTK_WED_RROQM_MID_MIB 0xcc0 -+#define MTK_WED_RROQM_MOD_MIB 0xcc4 -+#define MTK_WED_RROQM_MOD_COHERENT_MIB 0xcc8 -+#define MTK_WED_RROQM_FDBK_MIB 0xcd0 -+#define MTK_WED_RROQM_FDBK_COHERENT_MIB 0xcd4 -+#define MTK_WED_RROQM_FDBK_IND_MIB 0xce0 -+#define MTK_WED_RROQM_FDBK_ENQ_MIB 0xce4 -+#define MTK_WED_RROQM_FDBK_ANC_MIB 0xce8 -+#define MTK_WED_RROQM_FDBK_ANC2H_MIB 0xcec -+ -+#define MTK_WED_RX_BM_RX_DMAD 0xd80 -+#define MTK_WED_RX_BM_BASE 0xd84 -+#define MTK_WED_RX_BM_INIT_PTR 0xd88 -+#define MTK_WED_RX_BM_PTR 0xd8c -+#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16) -+#define MTK_WED_RX_BM_PTR_TAIL GENMASK(15, 0) -+ -+#define MTK_WED_RX_BM_BLEN 0xd90 -+#define MTK_WED_RX_BM_STS 0xd94 -+#define MTK_WED_RX_BM_INTF2 0xd98 -+#define MTK_WED_RX_BM_INTF 0xd9c -+#define MTK_WED_RX_BM_ERR_STS 0xda8 -+ -+#define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000 -+#define MTK_WED_PCIE_INT_MASK 0x0 -+ - #endif ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -49,6 +49,10 @@ enum { - MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2), - }; - -+#define MTK_WED_WO_CPU_MCUSYS_RESET_ADDR 0x15194050 -+#define MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK 0x20 -+#define MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK 0x1 -+ - enum { - MTK_WED_WO_REGION_EMI, - MTK_WED_WO_REGION_ILM, -@@ -57,6 +61,28 @@ enum { - __MTK_WED_WO_REGION_MAX, - }; - -+enum mtk_wed_wo_state { -+ MTK_WED_WO_STATE_UNDEFINED, -+ MTK_WED_WO_STATE_INIT, -+ MTK_WED_WO_STATE_ENABLE, -+ MTK_WED_WO_STATE_DISABLE, -+ MTK_WED_WO_STATE_HALT, -+ MTK_WED_WO_STATE_GATING, -+ MTK_WED_WO_STATE_SER_RESET, -+ MTK_WED_WO_STATE_WF_RESET, -+}; -+ -+enum mtk_wed_wo_done_state { -+ MTK_WED_WOIF_UNDEFINED, -+ MTK_WED_WOIF_DISABLE_DONE, -+ MTK_WED_WOIF_TRIGGER_ENABLE, -+ MTK_WED_WOIF_ENABLE_DONE, -+ MTK_WED_WOIF_TRIGGER_GATING, -+ MTK_WED_WOIF_GATING_DONE, -+ MTK_WED_WOIF_TRIGGER_HALT, -+ MTK_WED_WOIF_HALT_DONE, -+}; -+ - enum mtk_wed_dummy_cr_idx { - MTK_WED_DUMMY_CR_FWDL, - MTK_WED_DUMMY_CR_WO_STATUS, -@@ -245,6 +271,8 @@ void mtk_wed_mcu_rx_unsolicited_event(st - struct sk_buff *skb); - int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, - const void *data, int len, bool wait_resp); -+int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, -+ int len); - int mtk_wed_mcu_init(struct mtk_wed_wo *wo); - int mtk_wed_wo_init(struct mtk_wed_hw *hw); - void mtk_wed_wo_deinit(struct mtk_wed_hw *hw); ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -5,10 +5,13 @@ - #include - #include - #include -+#include - - #define MTK_WED_TX_QUEUES 2 - #define MTK_WED_RX_QUEUES 2 - -+#define WED_WO_STA_REC 0x6 -+ - struct mtk_wed_hw; - struct mtk_wdma_desc; - -@@ -41,21 +44,37 @@ enum mtk_wed_wo_cmd { - MTK_WED_WO_CMD_WED_END - }; - -+struct mtk_rxbm_desc { -+ __le32 buf0; -+ __le32 token; -+} __packed __aligned(4); -+ - enum mtk_wed_bus_tye { - MTK_WED_BUS_PCIE, - MTK_WED_BUS_AXI, - }; - -+#define MTK_WED_RING_CONFIGURED BIT(0) - struct mtk_wed_ring { - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; - u32 desc_size; - int size; -+ u32 flags; - - u32 reg_base; - void __iomem *wpdma; - }; - -+struct mtk_wed_wo_rx_stats { -+ __le16 wlan_idx; -+ __le16 tid; -+ __le32 rx_pkt_cnt; -+ __le32 rx_byte_cnt; -+ __le32 rx_err_cnt; -+ __le32 rx_drop_cnt; -+}; -+ - struct mtk_wed_device { - #ifdef CONFIG_NET_MEDIATEK_SOC_WED - const struct mtk_wed_ops *ops; -@@ -64,9 +83,12 @@ struct mtk_wed_device { - bool init_done, running; - int wdma_idx; - int irq; -+ u8 version; - - struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; -+ struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES]; - struct mtk_wed_ring txfree_ring; -+ struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; - struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES]; - - struct { -@@ -74,7 +96,20 @@ struct mtk_wed_device { - void **pages; - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -- } buf_ring; -+ } tx_buf_ring; -+ -+ struct { -+ int size; -+ struct page_frag_cache rx_page; -+ struct mtk_rxbm_desc *desc; -+ dma_addr_t desc_phys; -+ } rx_buf_ring; -+ -+ struct { -+ struct mtk_wed_ring ring; -+ dma_addr_t miod_phys; -+ dma_addr_t fdbk_phys; -+ } rro; - - /* filled by driver: */ - struct { -@@ -83,22 +118,36 @@ struct mtk_wed_device { - struct pci_dev *pci_dev; - }; - enum mtk_wed_bus_tye bus_type; -+ void __iomem *base; -+ u32 phy_base; - - u32 wpdma_phys; - u32 wpdma_int; - u32 wpdma_mask; - u32 wpdma_tx; - u32 wpdma_txfree; -+ u32 wpdma_rx_glo; -+ u32 wpdma_rx; -+ -+ bool wcid_512; - - u16 token_start; - unsigned int nbuf; -+ unsigned int rx_nbuf; -+ unsigned int rx_npkt; -+ unsigned int rx_size; - - u8 tx_tbit[MTK_WED_TX_QUEUES]; -+ u8 rx_tbit[MTK_WED_RX_QUEUES]; - u8 txfree_tbit; - - u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); - int (*offload_enable)(struct mtk_wed_device *wed); - void (*offload_disable)(struct mtk_wed_device *wed); -+ u32 (*init_rx_buf)(struct mtk_wed_device *wed, int size); -+ void (*release_rx_buf)(struct mtk_wed_device *wed); -+ void (*update_wo_rx_stats)(struct mtk_wed_device *wed, -+ struct mtk_wed_wo_rx_stats *stats); - } wlan; - #endif - }; -@@ -107,9 +156,15 @@ struct mtk_wed_ops { - int (*attach)(struct mtk_wed_device *dev); - int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, - void __iomem *regs); -+ int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, -+ void __iomem *regs); - int (*txfree_ring_setup)(struct mtk_wed_device *dev, - void __iomem *regs); -+ int (*msg_update)(struct mtk_wed_device *dev, int cmd_id, -+ void *data, int len); - void (*detach)(struct mtk_wed_device *dev); -+ void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb, -+ u32 reason, u32 hash); - - void (*stop)(struct mtk_wed_device *dev); - void (*start)(struct mtk_wed_device *dev, u32 irq_mask); -@@ -144,6 +199,16 @@ mtk_wed_device_attach(struct mtk_wed_dev - return ret; - } - -+static inline bool -+mtk_wed_get_rx_capa(struct mtk_wed_device *dev) -+{ -+#ifdef CONFIG_NET_MEDIATEK_SOC_WED -+ return dev->version != 1; -+#else -+ return false; -+#endif -+} -+ - #ifdef CONFIG_NET_MEDIATEK_SOC_WED - #define mtk_wed_device_active(_dev) !!(_dev)->ops - #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) -@@ -160,6 +225,12 @@ mtk_wed_device_attach(struct mtk_wed_dev - (_dev)->ops->irq_get(_dev, _mask) - #define mtk_wed_device_irq_set_mask(_dev, _mask) \ - (_dev)->ops->irq_set_mask(_dev, _mask) -+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \ -+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \ -+ (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) -+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ -+ (_dev)->ops->msg_update(_dev, _id, _msg, _len) - #else - static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) - { -@@ -173,6 +244,9 @@ static inline bool mtk_wed_device_active - #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) - #define mtk_wed_device_irq_get(_dev, _mask) 0 - #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0) -+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) -+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV - #endif - - #endif diff --git a/target/linux/generic/backport-5.15/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch b/target/linux/generic/backport-5.15/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch deleted file mode 100644 index bb1066deceaa46..00000000000000 --- a/target/linux/generic/backport-5.15/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch +++ /dev/null @@ -1,149 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 5 Nov 2022 23:36:22 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add rx mib counters - -Introduce WED RX MIB counters support available on MT7986a SoC. - -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -2,6 +2,7 @@ - /* Copyright (C) 2021 Felix Fietkau */ - - #include -+#include - #include "mtk_wed.h" - #include "mtk_wed_regs.h" - -@@ -18,6 +19,8 @@ enum { - DUMP_TYPE_WDMA, - DUMP_TYPE_WPDMA_TX, - DUMP_TYPE_WPDMA_TXFREE, -+ DUMP_TYPE_WPDMA_RX, -+ DUMP_TYPE_WED_RRO, - }; - - #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING } -@@ -36,6 +39,9 @@ enum { - - #define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n) - #define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE) -+#define DUMP_WPDMA_RX_RING(_n) DUMP_RING("WPDMA_RX" #_n, 0, DUMP_TYPE_WPDMA_RX, _n) -+#define DUMP_WED_RRO_RING(_base)DUMP_RING("WED_RRO_MIOD", MTK_##_base, DUMP_TYPE_WED_RRO) -+#define DUMP_WED_RRO_FDBK(_base)DUMP_RING("WED_RRO_FDBK", MTK_##_base, DUMP_TYPE_WED_RRO) - - static void - print_reg_val(struct seq_file *s, const char *name, u32 val) -@@ -57,6 +63,7 @@ dump_wed_regs(struct seq_file *s, struct - cur > regs ? "\n" : "", - cur->name); - continue; -+ case DUMP_TYPE_WED_RRO: - case DUMP_TYPE_WED: - val = wed_r32(dev, cur->offset); - break; -@@ -69,6 +76,9 @@ dump_wed_regs(struct seq_file *s, struct - case DUMP_TYPE_WPDMA_TXFREE: - val = wpdma_txfree_r32(dev, cur->offset); - break; -+ case DUMP_TYPE_WPDMA_RX: -+ val = wpdma_rx_r32(dev, cur->base, cur->offset); -+ break; - } - print_reg_val(s, cur->name, val); - } -@@ -132,6 +142,80 @@ wed_txinfo_show(struct seq_file *s, void - } - DEFINE_SHOW_ATTRIBUTE(wed_txinfo); - -+static int -+wed_rxinfo_show(struct seq_file *s, void *data) -+{ -+ static const struct reg_dump regs[] = { -+ DUMP_STR("WPDMA RX"), -+ DUMP_WPDMA_RX_RING(0), -+ DUMP_WPDMA_RX_RING(1), -+ -+ DUMP_STR("WPDMA RX"), -+ DUMP_WED(WED_WPDMA_RX_D_MIB(0)), -+ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(0)), -+ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(0)), -+ DUMP_WED(WED_WPDMA_RX_D_MIB(1)), -+ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(1)), -+ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(1)), -+ DUMP_WED(WED_WPDMA_RX_D_COHERENT_MIB), -+ -+ DUMP_STR("WED RX"), -+ DUMP_WED_RING(WED_RING_RX_DATA(0)), -+ DUMP_WED_RING(WED_RING_RX_DATA(1)), -+ -+ DUMP_STR("WED RRO"), -+ DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0), -+ DUMP_WED(WED_RROQM_MID_MIB), -+ DUMP_WED(WED_RROQM_MOD_MIB), -+ DUMP_WED(WED_RROQM_MOD_COHERENT_MIB), -+ DUMP_WED_RRO_FDBK(WED_RROQM_FDBK_CTRL0), -+ DUMP_WED(WED_RROQM_FDBK_IND_MIB), -+ DUMP_WED(WED_RROQM_FDBK_ENQ_MIB), -+ DUMP_WED(WED_RROQM_FDBK_ANC_MIB), -+ DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB), -+ -+ DUMP_STR("WED Route QM"), -+ DUMP_WED(WED_RTQM_R2H_MIB(0)), -+ DUMP_WED(WED_RTQM_R2Q_MIB(0)), -+ DUMP_WED(WED_RTQM_Q2H_MIB(0)), -+ DUMP_WED(WED_RTQM_R2H_MIB(1)), -+ DUMP_WED(WED_RTQM_R2Q_MIB(1)), -+ DUMP_WED(WED_RTQM_Q2H_MIB(1)), -+ DUMP_WED(WED_RTQM_Q2N_MIB), -+ DUMP_WED(WED_RTQM_Q2B_MIB), -+ DUMP_WED(WED_RTQM_PFDBK_MIB), -+ -+ DUMP_STR("WED WDMA TX"), -+ DUMP_WED(WED_WDMA_TX_MIB), -+ DUMP_WED_RING(WED_WDMA_RING_TX), -+ -+ DUMP_STR("WDMA TX"), -+ DUMP_WDMA(WDMA_GLO_CFG), -+ DUMP_WDMA_RING(WDMA_RING_TX(0)), -+ DUMP_WDMA_RING(WDMA_RING_TX(1)), -+ -+ DUMP_STR("WED RX BM"), -+ DUMP_WED(WED_RX_BM_BASE), -+ DUMP_WED(WED_RX_BM_RX_DMAD), -+ DUMP_WED(WED_RX_BM_PTR), -+ DUMP_WED(WED_RX_BM_TKID_MIB), -+ DUMP_WED(WED_RX_BM_BLEN), -+ DUMP_WED(WED_RX_BM_STS), -+ DUMP_WED(WED_RX_BM_INTF2), -+ DUMP_WED(WED_RX_BM_INTF), -+ DUMP_WED(WED_RX_BM_ERR_STS), -+ }; -+ struct mtk_wed_hw *hw = s->private; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (!dev) -+ return 0; -+ -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(wed_rxinfo); - - static int - mtk_wed_reg_set(void *data, u64 val) -@@ -175,4 +259,7 @@ void mtk_wed_hw_add_debugfs(struct mtk_w - debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg); - debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval); - debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops); -+ if (hw->version != 1) -+ debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, -+ &wed_rxinfo_fops); - } diff --git a/target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch b/target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch deleted file mode 100644 index 7f76e9b4975cc3..00000000000000 --- a/target/linux/generic/backport-5.15/729-06-v6.1-net-ethernet-mtk_eth_soc-do-not-overwrite-mtu-config.patch +++ /dev/null @@ -1,98 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 17 Nov 2022 00:35:04 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: do not overwrite mtu - configuration running reset routine - -Restore user configured MTU running mtk_hw_init() during tx timeout routine -since it will be overwritten after a hw reset. - -Reported-by: Felix Fietkau -Fixes: 9ea4d311509f ("net: ethernet: mediatek: add the whole ethernet reset into the reset process") -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3178,6 +3178,30 @@ static void mtk_dim_tx(struct work_struc - dim->state = DIM_START_MEASURE; - } - -+static void mtk_set_mcr_max_rx(struct mtk_mac *mac, u32 val) -+{ -+ struct mtk_eth *eth = mac->hw; -+ u32 mcr_cur, mcr_new; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) -+ return; -+ -+ mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -+ mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK; -+ -+ if (val <= 1518) -+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518); -+ else if (val <= 1536) -+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536); -+ else if (val <= 1552) -+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552); -+ else -+ mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048); -+ -+ if (mcr_new != mcr_cur) -+ mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); -+} -+ - static int mtk_hw_init(struct mtk_eth *eth) - { - u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | -@@ -3252,8 +3276,16 @@ static int mtk_hw_init(struct mtk_eth *e - * up with the more appropriate value when mtk_mac_config call is being - * invoked. - */ -- for (i = 0; i < MTK_MAC_COUNT; i++) -+ for (i = 0; i < MTK_MAC_COUNT; i++) { -+ struct net_device *dev = eth->netdev[i]; -+ - mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); -+ if (dev) { -+ struct mtk_mac *mac = netdev_priv(dev); -+ -+ mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN); -+ } -+ } - - /* Indicates CDM to parse the MTK special tag from CPU - * which also is working out for untag packets. -@@ -3352,7 +3384,6 @@ static int mtk_change_mtu(struct net_dev - int length = new_mtu + MTK_RX_ETH_HLEN; - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; -- u32 mcr_cur, mcr_new; - - if (rcu_access_pointer(eth->prog) && - length > MTK_PP_MAX_BUF_SIZE) { -@@ -3360,23 +3391,7 @@ static int mtk_change_mtu(struct net_dev - return -EINVAL; - } - -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { -- mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -- mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK; -- -- if (length <= 1518) -- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518); -- else if (length <= 1536) -- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536); -- else if (length <= 1552) -- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552); -- else -- mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048); -- -- if (mcr_new != mcr_cur) -- mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); -- } -- -+ mtk_set_mcr_max_rx(mac, length); - dev->mtu = new_mtu; - - return 0; diff --git a/target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch b/target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch deleted file mode 100644 index 65d9621e2fdfea..00000000000000 --- a/target/linux/generic/backport-5.15/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 17 Nov 2022 00:58:46 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: remove cpu_relax in - mtk_pending_work - -Get rid of cpu_relax in mtk_pending_work routine since MTK_RESETTING is -set only in mtk_pending_work() and it runs holding rtnl lock - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3422,11 +3422,8 @@ static void mtk_pending_work(struct work - rtnl_lock(); - - dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__); -+ set_bit(MTK_RESETTING, ð->state); - -- while (test_and_set_bit_lock(MTK_RESETTING, ð->state)) -- cpu_relax(); -- -- dev_dbg(eth->dev, "[%s][%d] mtk_stop starts\n", __func__, __LINE__); - /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { - if (!eth->netdev[i]) -@@ -3460,7 +3457,7 @@ static void mtk_pending_work(struct work - - dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__); - -- clear_bit_unlock(MTK_RESETTING, ð->state); -+ clear_bit(MTK_RESETTING, ð->state); - - rtnl_unlock(); - } diff --git a/target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch b/target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch deleted file mode 100644 index 4eca30dbfd80c9..00000000000000 --- a/target/linux/generic/backport-5.15/729-08-v6.2-net-ethernet-mtk_eth_soc-fix-RSTCTRL_PPE-0-1-definit.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 17 Nov 2022 15:29:53 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix RSTCTRL_PPE{0,1} definitions - -Fix RSTCTRL_PPE0 and RSTCTRL_PPE1 register mask definitions for -MTK_NETSYS_V2. -Remove duplicated definitions. - -Fixes: 160d3a9b1929 ("net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support") -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3241,16 +3241,17 @@ static int mtk_hw_init(struct mtk_eth *e - return 0; - } - -- val = RSTCTRL_FE | RSTCTRL_PPE; - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); -- -- val |= RSTCTRL_ETH; -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- val |= RSTCTRL_PPE1; -+ val = RSTCTRL_PPE0_V2; -+ } else { -+ val = RSTCTRL_PPE0; - } - -- ethsys_reset(eth, val); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= RSTCTRL_PPE1; -+ -+ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -445,18 +445,14 @@ - /* ethernet reset control register */ - #define ETHSYS_RSTCTRL 0x34 - #define RSTCTRL_FE BIT(6) --#define RSTCTRL_PPE BIT(31) --#define RSTCTRL_PPE1 BIT(30) -+#define RSTCTRL_PPE0 BIT(31) -+#define RSTCTRL_PPE0_V2 BIT(30) -+#define RSTCTRL_PPE1 BIT(31) - #define RSTCTRL_ETH BIT(23) - - /* ethernet reset check idle register */ - #define ETHSYS_FE_RST_CHK_IDLE_EN 0x28 - --/* ethernet reset control register */ --#define ETHSYS_RSTCTRL 0x34 --#define RSTCTRL_FE BIT(6) --#define RSTCTRL_PPE BIT(31) -- - /* ethernet dma channel agent map */ - #define ETHSYS_DMA_AG_MAP 0x408 - #define ETHSYS_DMA_AG_MAP_PDMA BIT(0) diff --git a/target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch b/target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch deleted file mode 100644 index 117ccc090258ea..00000000000000 --- a/target/linux/generic/backport-5.15/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch +++ /dev/null @@ -1,80 +0,0 @@ -From: Sujuan Chen -Date: Thu, 24 Nov 2022 11:18:14 +0800 -Subject: [PATCH] net: ethernet: mtk_wed: add wcid overwritten support for wed - v1 - -All wed versions should enable the wcid overwritten feature, -since the wcid size is controlled by the wlan driver. - -Tested-by: Sujuan Chen -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Signed-off-by: Sujuan Chen -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -526,9 +526,9 @@ mtk_wed_dma_disable(struct mtk_wed_devic - MTK_WED_WPDMA_RX_D_RX_DRV_EN); - wed_clr(dev, MTK_WED_WDMA_GLO_CFG, - MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); -- -- mtk_wed_set_512_support(dev, false); - } -+ -+ mtk_wed_set_512_support(dev, false); - } - - static void -@@ -1290,9 +1290,10 @@ mtk_wed_start(struct mtk_wed_device *dev - if (mtk_wed_rro_cfg(dev)) - return; - -- mtk_wed_set_512_support(dev, dev->wlan.wcid_512); - } - -+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512); -+ - mtk_wed_dma_enable(dev); - dev->running = true; - } -@@ -1358,11 +1359,13 @@ mtk_wed_attach(struct mtk_wed_device *de - } - - mtk_wed_hw_init_early(dev); -- if (hw->version == 1) -+ if (hw->version == 1) { - regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, - BIT(hw->index), 0); -- else -+ } else { -+ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID); - ret = mtk_wed_wo_init(hw); -+ } - out: - if (ret) - mtk_wed_detach(dev); ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -20,6 +20,8 @@ struct mtk_wdma_desc { - __le32 info; - } __packed __aligned(4); - -+#define MTK_WED_REV_ID 0x004 -+ - #define MTK_WED_RESET 0x008 - #define MTK_WED_RESET_TX_BM BIT(0) - #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -85,6 +85,9 @@ struct mtk_wed_device { - int irq; - u8 version; - -+ /* used by wlan driver */ -+ u32 rev_id; -+ - struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; - struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES]; - struct mtk_wed_ring txfree_ring; diff --git a/target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch b/target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch deleted file mode 100644 index ec58c3fc572400..00000000000000 --- a/target/linux/generic/backport-5.15/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch +++ /dev/null @@ -1,85 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Nov 2022 16:22:51 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: return status value in - mtk_wdma_rx_reset - -Move MTK_WDMA_RESET_IDX configuration in mtk_wdma_rx_reset routine. -Increase poll timeout to 10ms in order to be aligned with vendor sdk. -This is a preliminary patch to add Wireless Ethernet Dispatcher reset -support. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_devic - return wdma_r32(dev, MTK_WDMA_GLO_CFG); - } - --static void -+static int - mtk_wdma_rx_reset(struct mtk_wed_device *dev) - { - u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY; -- int i; -+ int i, ret; - - wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN); -- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, -- !(status & mask), 0, 1000)) -+ ret = readx_poll_timeout(mtk_wdma_read_reset, dev, status, -+ !(status & mask), 0, 10000); -+ if (ret) - dev_err(dev->hw->dev, "rx reset failed\n"); - -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -+ - for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) { - if (dev->rx_wdma[i].desc) - continue; -@@ -119,6 +123,8 @@ mtk_wdma_rx_reset(struct mtk_wed_device - wdma_w32(dev, - MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); - } -+ -+ return ret; - } - - static void -@@ -565,9 +571,7 @@ mtk_wed_detach(struct mtk_wed_device *de - - mtk_wed_stop(dev); - -- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); -- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -- -+ mtk_wdma_rx_reset(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); - if (mtk_wed_get_rx_capa(dev)) { - wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); -@@ -582,7 +586,6 @@ mtk_wed_detach(struct mtk_wed_device *de - mtk_wed_wo_reset(dev); - mtk_wed_free_rx_rings(dev); - mtk_wed_wo_deinit(hw); -- mtk_wdma_rx_reset(dev); - } - - if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { -@@ -999,11 +1002,7 @@ mtk_wed_reset_dma(struct mtk_wed_device - wed_w32(dev, MTK_WED_RESET_IDX, 0); - } - -- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); -- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -- -- if (mtk_wed_get_rx_capa(dev)) -- mtk_wdma_rx_reset(dev); -+ mtk_wdma_rx_reset(dev); - - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); diff --git a/target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch b/target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch deleted file mode 100644 index 10c1732c969a9b..00000000000000 --- a/target/linux/generic/backport-5.15/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Nov 2022 16:22:52 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: move MTK_WDMA_RESET_IDX_TX - configuration in mtk_wdma_tx_reset - -Remove duplicated code. Increase poll timeout to 10ms in order to be -aligned with vendor sdk. -This is a preliminary patch to add Wireless Ethernet Dispatcher reset -support. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -135,16 +135,15 @@ mtk_wdma_tx_reset(struct mtk_wed_device - - wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); - if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, -- !(status & mask), 0, 1000)) -+ !(status & mask), 0, 10000)) - dev_err(dev->hw->dev, "tx reset failed\n"); - -- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) { -- if (dev->tx_wdma[i].desc) -- continue; -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); - -+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) - wdma_w32(dev, - MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); -- } - } - - static void -@@ -573,12 +572,6 @@ mtk_wed_detach(struct mtk_wed_device *de - - mtk_wdma_rx_reset(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); -- if (mtk_wed_get_rx_capa(dev)) { -- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); -- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); -- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -- } -- - mtk_wed_free_tx_buffer(dev); - mtk_wed_free_tx_rings(dev); - diff --git a/target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch b/target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch deleted file mode 100644 index f4e842d515a8e1..00000000000000 --- a/target/linux/generic/backport-5.15/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch +++ /dev/null @@ -1,98 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Nov 2022 16:22:53 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: update mtk_wed_stop - -Update mtk_wed_stop routine and rename old mtk_wed_stop() to -mtk_wed_deinit(). This is a preliminary patch to add Wireless Ethernet -Dispatcher reset support. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -539,14 +539,8 @@ mtk_wed_dma_disable(struct mtk_wed_devic - static void - mtk_wed_stop(struct mtk_wed_device *dev) - { -- mtk_wed_dma_disable(dev); - mtk_wed_set_ext_int(dev, false); - -- wed_clr(dev, MTK_WED_CTRL, -- MTK_WED_CTRL_WDMA_INT_AGENT_EN | -- MTK_WED_CTRL_WPDMA_INT_AGENT_EN | -- MTK_WED_CTRL_WED_TX_BM_EN | -- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0); - wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0); - wdma_w32(dev, MTK_WDMA_INT_MASK, 0); -@@ -558,7 +552,27 @@ mtk_wed_stop(struct mtk_wed_device *dev) - - wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); - wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0); -- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); -+} -+ -+static void -+mtk_wed_deinit(struct mtk_wed_device *dev) -+{ -+ mtk_wed_stop(dev); -+ mtk_wed_dma_disable(dev); -+ -+ wed_clr(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WDMA_INT_AGENT_EN | -+ MTK_WED_CTRL_WPDMA_INT_AGENT_EN | -+ MTK_WED_CTRL_WED_TX_BM_EN | -+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ -+ if (dev->hw->version == 1) -+ return; -+ -+ wed_clr(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_RX_ROUTE_QM_EN | -+ MTK_WED_CTRL_WED_RX_BM_EN | -+ MTK_WED_CTRL_RX_RRO_QM_EN); - } - - static void -@@ -568,7 +582,7 @@ mtk_wed_detach(struct mtk_wed_device *de - - mutex_lock(&hw_lock); - -- mtk_wed_stop(dev); -+ mtk_wed_deinit(dev); - - mtk_wdma_rx_reset(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); -@@ -670,7 +684,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev - { - u32 mask, set; - -- mtk_wed_stop(dev); -+ mtk_wed_deinit(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); - mtk_wed_set_wpdma(dev); - ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -234,6 +234,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic - (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) - #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ - (_dev)->ops->msg_update(_dev, _id, _msg, _len) -+#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) -+#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) - #else - static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) - { -@@ -250,6 +252,8 @@ static inline bool mtk_wed_device_active - #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV - #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) - #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV -+#define mtk_wed_device_stop(_dev) do {} while (0) -+#define mtk_wed_device_dma_reset(_dev) do {} while (0) - #endif - - #endif diff --git a/target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch b/target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch deleted file mode 100644 index a0fc9da99e7fd5..00000000000000 --- a/target/linux/generic/backport-5.15/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch +++ /dev/null @@ -1,309 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Nov 2022 16:22:54 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_rx_reset routine - -Introduce mtk_wed_rx_reset routine in order to reset rx DMA for Wireless -Ethernet Dispatcher available on MT7986 SoC. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -944,42 +944,130 @@ mtk_wed_ring_reset(struct mtk_wed_ring * - } - - static u32 --mtk_wed_check_busy(struct mtk_wed_device *dev) -+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) - { -- if (wed_r32(dev, MTK_WED_GLO_CFG) & MTK_WED_GLO_CFG_TX_DMA_BUSY) -- return true; -- -- if (wed_r32(dev, MTK_WED_WPDMA_GLO_CFG) & -- MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY) -- return true; -- -- if (wed_r32(dev, MTK_WED_CTRL) & MTK_WED_CTRL_WDMA_INT_AGENT_BUSY) -- return true; -- -- if (wed_r32(dev, MTK_WED_WDMA_GLO_CFG) & -- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY) -- return true; -- -- if (wdma_r32(dev, MTK_WDMA_GLO_CFG) & -- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY) -- return true; -- -- if (wed_r32(dev, MTK_WED_CTRL) & -- (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY)) -- return true; -- -- return false; -+ return !!(wed_r32(dev, reg) & mask); - } - - static int --mtk_wed_poll_busy(struct mtk_wed_device *dev) -+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) - { - int sleep = 15000; - int timeout = 100 * sleep; - u32 val; - - return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep, -- timeout, false, dev); -+ timeout, false, dev, reg, mask); -+} -+ -+static int -+mtk_wed_rx_reset(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_wo *wo = dev->hw->wed_wo; -+ u8 val = MTK_WED_WO_STATE_SER_RESET; -+ int i, ret; -+ -+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -+ MTK_WED_WO_CMD_CHANGE_STATE, &val, -+ sizeof(val), true); -+ if (ret) -+ return ret; -+ -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN); -+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY); -+ if (ret) { -+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); -+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV); -+ } else { -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -+ -+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE | -+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE); -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE | -+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE); -+ -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -+ } -+ -+ /* reset rro qm */ -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN); -+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_RX_RRO_QM_BUSY); -+ if (ret) { -+ mtk_wed_reset(dev, MTK_WED_RESET_RX_RRO_QM); -+ } else { -+ wed_set(dev, MTK_WED_RROQM_RST_IDX, -+ MTK_WED_RROQM_RST_IDX_MIOD | -+ MTK_WED_RROQM_RST_IDX_FDBK); -+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0); -+ } -+ -+ /* reset route qm */ -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); -+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_RX_ROUTE_QM_BUSY); -+ if (ret) -+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM); -+ else -+ wed_set(dev, MTK_WED_RTQM_GLO_CFG, -+ MTK_WED_RTQM_Q_RST); -+ -+ /* reset tx wdma */ -+ mtk_wdma_tx_reset(dev); -+ -+ /* reset tx wdma drv */ -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY); -+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV); -+ -+ /* reset wed rx dma */ -+ ret = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG, -+ MTK_WED_GLO_CFG_RX_DMA_BUSY); -+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_RX_DMA_EN); -+ if (ret) { -+ mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA); -+ } else { -+ struct mtk_eth *eth = dev->hw->eth; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ wed_set(dev, MTK_WED_RESET_IDX, -+ MTK_WED_RESET_IDX_RX_V2); -+ else -+ wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX); -+ wed_w32(dev, MTK_WED_RESET_IDX, 0); -+ } -+ -+ /* reset rx bm */ -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WED_RX_BM_BUSY); -+ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM); -+ -+ /* wo change to enable state */ -+ val = MTK_WED_WO_STATE_ENABLE; -+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -+ MTK_WED_WO_CMD_CHANGE_STATE, &val, -+ sizeof(val), true); -+ if (ret) -+ return ret; -+ -+ /* wed_rx_ring_reset */ -+ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++) { -+ if (!dev->rx_ring[i].desc) -+ continue; -+ -+ mtk_wed_ring_reset(&dev->rx_ring[i], MTK_WED_RX_RING_SIZE, -+ false); -+ } -+ mtk_wed_free_rx_buffer(dev); -+ -+ return 0; - } - - static void -@@ -997,19 +1085,23 @@ mtk_wed_reset_dma(struct mtk_wed_device - true); - } - -- if (mtk_wed_poll_busy(dev)) -- busy = mtk_wed_check_busy(dev); -- -+ /* 1. reset WED tx DMA */ -+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_TX_DMA_EN); -+ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG, -+ MTK_WED_GLO_CFG_TX_DMA_BUSY); - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA); - } else { -- wed_w32(dev, MTK_WED_RESET_IDX, -- MTK_WED_RESET_IDX_TX | -- MTK_WED_RESET_IDX_RX); -+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX); - wed_w32(dev, MTK_WED_RESET_IDX, 0); - } - -- mtk_wdma_rx_reset(dev); -+ /* 2. reset WDMA rx DMA */ -+ busy = !!mtk_wdma_rx_reset(dev); -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); -+ if (!busy) -+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY); - - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); -@@ -1026,6 +1118,9 @@ mtk_wed_reset_dma(struct mtk_wed_device - MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE); - } - -+ /* 3. reset WED WPDMA tx */ -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ - for (i = 0; i < 100; i++) { - val = wed_r32(dev, MTK_WED_TX_BM_INTF); - if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40) -@@ -1033,8 +1128,19 @@ mtk_wed_reset_dma(struct mtk_wed_device - } - - mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT); -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_BM_EN); - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - -+ /* 4. reset WED WPDMA tx */ -+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY); -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -+ if (!busy) -+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY); -+ - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV); -@@ -1045,6 +1151,17 @@ mtk_wed_reset_dma(struct mtk_wed_device - MTK_WED_WPDMA_RESET_IDX_RX); - wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0); - } -+ -+ dev->init_done = false; -+ if (dev->hw->version == 1) -+ return; -+ -+ if (!busy) { -+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_WPDMA_IDX_RX); -+ wed_w32(dev, MTK_WED_RESET_IDX, 0); -+ } -+ -+ mtk_wed_rx_reset(dev); - } - - static int -@@ -1267,6 +1384,9 @@ mtk_wed_start(struct mtk_wed_device *dev - { - int i; - -+ if (mtk_wed_get_rx_capa(dev) && mtk_wed_rx_buffer_alloc(dev)) -+ return; -+ - for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) - if (!dev->rx_wdma[i].desc) - mtk_wed_wdma_rx_ring_setup(dev, i, 16); -@@ -1355,10 +1475,6 @@ mtk_wed_attach(struct mtk_wed_device *de - goto out; - - if (mtk_wed_get_rx_capa(dev)) { -- ret = mtk_wed_rx_buffer_alloc(dev); -- if (ret) -- goto out; -- - ret = mtk_wed_rro_alloc(dev); - if (ret) - goto out; ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -24,11 +24,15 @@ struct mtk_wdma_desc { - - #define MTK_WED_RESET 0x008 - #define MTK_WED_RESET_TX_BM BIT(0) -+#define MTK_WED_RESET_RX_BM BIT(1) - #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) - #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8) - #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9) -+#define MTK_WED_RESET_WPDMA_RX_D_DRV BIT(10) - #define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11) - #define MTK_WED_RESET_WED_TX_DMA BIT(12) -+#define MTK_WED_RESET_WED_RX_DMA BIT(13) -+#define MTK_WED_RESET_WDMA_TX_DRV BIT(16) - #define MTK_WED_RESET_WDMA_RX_DRV BIT(17) - #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19) - #define MTK_WED_RESET_RX_RRO_QM BIT(20) -@@ -158,6 +162,8 @@ struct mtk_wdma_desc { - #define MTK_WED_RESET_IDX 0x20c - #define MTK_WED_RESET_IDX_TX GENMASK(3, 0) - #define MTK_WED_RESET_IDX_RX GENMASK(17, 16) -+#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6) -+#define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30) - - #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) - #define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4) -@@ -267,6 +273,9 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c - #define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0) -+#define MTK_WED_WPDMA_RX_D_RX_DRV_BUSY BIT(1) -+#define MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE BIT(3) -+#define MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE BIT(4) - #define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7) - #define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24) - diff --git a/target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch b/target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch deleted file mode 100644 index 4404971cc74dde..00000000000000 --- a/target/linux/generic/backport-5.15/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch +++ /dev/null @@ -1,103 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Nov 2022 16:22:55 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add reset to tx_ring_setup callback - -Introduce reset parameter to mtk_wed_tx_ring_setup signature. -This is a preliminary patch to add Wireless Ethernet Dispatcher reset -support. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1181,7 +1181,8 @@ mtk_wed_ring_alloc(struct mtk_wed_device - } - - static int --mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size) -+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size, -+ bool reset) - { - u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; - struct mtk_wed_ring *wdma; -@@ -1190,8 +1191,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we - return -EINVAL; - - wdma = &dev->rx_wdma[idx]; -- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, -- true)) -+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, -+ desc_size, true)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -@@ -1389,7 +1390,7 @@ mtk_wed_start(struct mtk_wed_device *dev - - for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) - if (!dev->rx_wdma[i].desc) -- mtk_wed_wdma_rx_ring_setup(dev, i, 16); -+ mtk_wed_wdma_rx_ring_setup(dev, i, 16, false); - - mtk_wed_hw_init(dev); - mtk_wed_configure_irq(dev, irq_mask); -@@ -1498,7 +1499,8 @@ unlock: - } - - static int --mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) -+mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs, -+ bool reset) - { - struct mtk_wed_ring *ring = &dev->tx_ring[idx]; - -@@ -1517,11 +1519,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring))) - return -EINVAL; - -- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, -- sizeof(*ring->desc), true)) -+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, -+ sizeof(*ring->desc), true)) - return -ENOMEM; - -- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, -+ reset)) - return -ENOMEM; - - ring->reg_base = MTK_WED_RING_TX(idx); ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -158,7 +158,7 @@ struct mtk_wed_device { - struct mtk_wed_ops { - int (*attach)(struct mtk_wed_device *dev); - int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, -- void __iomem *regs); -+ void __iomem *regs, bool reset); - int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, - void __iomem *regs); - int (*txfree_ring_setup)(struct mtk_wed_device *dev, -@@ -216,8 +216,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic - #define mtk_wed_device_active(_dev) !!(_dev)->ops - #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) - #define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask) --#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \ -- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \ -+ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset) - #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \ - (_dev)->ops->txfree_ring_setup(_dev, _regs) - #define mtk_wed_device_reg_read(_dev, _reg) \ -@@ -243,7 +243,7 @@ static inline bool mtk_wed_device_active - } - #define mtk_wed_device_detach(_dev) do {} while (0) - #define mtk_wed_device_start(_dev, _mask) do {} while (0) --#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV - #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV - #define mtk_wed_device_reg_read(_dev, _reg) 0 - #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) diff --git a/target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch b/target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch deleted file mode 100644 index f9b11326b1c88e..00000000000000 --- a/target/linux/generic/backport-5.15/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch +++ /dev/null @@ -1,103 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 1 Dec 2022 16:26:53 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: fix sleep while atomic in - mtk_wed_wo_queue_refill - -In order to fix the following sleep while atomic bug always alloc pages -with GFP_ATOMIC in mtk_wed_wo_queue_refill since page_frag_alloc runs in -spin_lock critical section. - -[ 9.049719] Hardware name: MediaTek MT7986a RFB (DT) -[ 9.054665] Call trace: -[ 9.057096] dump_backtrace+0x0/0x154 -[ 9.060751] show_stack+0x14/0x1c -[ 9.064052] dump_stack_lvl+0x64/0x7c -[ 9.067702] dump_stack+0x14/0x2c -[ 9.071001] ___might_sleep+0xec/0x120 -[ 9.074736] __might_sleep+0x4c/0x9c -[ 9.078296] __alloc_pages+0x184/0x2e4 -[ 9.082030] page_frag_alloc_align+0x98/0x1ac -[ 9.086369] mtk_wed_wo_queue_refill+0x134/0x234 -[ 9.090974] mtk_wed_wo_init+0x174/0x2c0 -[ 9.094881] mtk_wed_attach+0x7c8/0x7e0 -[ 9.098701] mt7915_mmio_wed_init+0x1f0/0x3a0 [mt7915e] -[ 9.103940] mt7915_pci_probe+0xec/0x3bc [mt7915e] -[ 9.108727] pci_device_probe+0xac/0x13c -[ 9.112638] really_probe.part.0+0x98/0x2f4 -[ 9.116807] __driver_probe_device+0x94/0x13c -[ 9.121147] driver_probe_device+0x40/0x114 -[ 9.125314] __driver_attach+0x7c/0x180 -[ 9.129133] bus_for_each_dev+0x5c/0x90 -[ 9.132953] driver_attach+0x20/0x2c -[ 9.136513] bus_add_driver+0x104/0x1fc -[ 9.140333] driver_register+0x74/0x120 -[ 9.144153] __pci_register_driver+0x40/0x50 -[ 9.148407] mt7915_init+0x5c/0x1000 [mt7915e] -[ 9.152848] do_one_initcall+0x40/0x25c -[ 9.156669] do_init_module+0x44/0x230 -[ 9.160403] load_module+0x1f30/0x2750 -[ 9.164135] __do_sys_init_module+0x150/0x200 -[ 9.168475] __arm64_sys_init_module+0x18/0x20 -[ 9.172901] invoke_syscall.constprop.0+0x4c/0xe0 -[ 9.177589] do_el0_svc+0x48/0xe0 -[ 9.180889] el0_svc+0x14/0x50 -[ 9.183929] el0t_64_sync_handler+0x9c/0x120 -[ 9.188183] el0t_64_sync+0x158/0x15c - -Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Pavan Chebbi -Link: https://lore.kernel.org/r/67ca94bdd3d9eaeb86e52b3050fbca0bcf7bb02f.1669908312.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c -@@ -133,17 +133,18 @@ mtk_wed_wo_dequeue(struct mtk_wed_wo *wo - - static int - mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, -- gfp_t gfp, bool rx) -+ bool rx) - { - enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - int n_buf = 0; - - spin_lock_bh(&q->lock); - while (q->queued < q->n_desc) { -- void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp); - struct mtk_wed_wo_queue_entry *entry; - dma_addr_t addr; -+ void *buf; - -+ buf = page_frag_alloc(&q->cache, q->buf_size, GFP_ATOMIC); - if (!buf) - break; - -@@ -215,7 +216,7 @@ mtk_wed_wo_rx_run_queue(struct mtk_wed_w - mtk_wed_mcu_rx_unsolicited_event(wo, skb); - } - -- if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) { -+ if (mtk_wed_wo_queue_refill(wo, q, true)) { - u32 index = (q->head - 1) % q->n_desc; - - mtk_wed_wo_queue_kick(wo, q, index); -@@ -432,7 +433,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_ - if (ret) - goto error; - -- mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false); -+ mtk_wed_wo_queue_refill(wo, &wo->q_tx, false); - mtk_wed_wo_queue_reset(wo, &wo->q_tx); - - regs.desc_base = MTK_WED_WO_CCIF_DUMMY5; -@@ -446,7 +447,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_ - if (ret) - goto error; - -- mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true); -+ mtk_wed_wo_queue_refill(wo, &wo->q_rx, true); - mtk_wed_wo_queue_reset(wo, &wo->q_rx); - - /* rx queue irqmask */ diff --git a/target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch b/target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch deleted file mode 100644 index fa6f56dbe7249d..00000000000000 --- a/target/linux/generic/backport-5.15/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Lorenzo Bianconi -Date: Tue, 10 Jan 2023 10:31:26 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for rx queue - -Queue spinlock is currently held in mtk_wed_wo_queue_rx_clean and -mtk_wed_wo_queue_refill routines for MTK Wireless Ethernet Dispatcher -MCU rx queue. mtk_wed_wo_queue_refill() is running during initialization -and in rx tasklet while mtk_wed_wo_queue_rx_clean() is running in -mtk_wed_wo_hw_deinit() during hw de-init phase after rx tasklet has been -disabled. Since mtk_wed_wo_queue_rx_clean and mtk_wed_wo_queue_refill -routines can't run concurrently get rid of spinlock for mcu rx queue. - -Reviewed-by: Alexander Duyck -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/36ec3b729542ea60898471d890796f745479ba32.1673342990.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c -@@ -138,7 +138,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w - enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - int n_buf = 0; - -- spin_lock_bh(&q->lock); - while (q->queued < q->n_desc) { - struct mtk_wed_wo_queue_entry *entry; - dma_addr_t addr; -@@ -172,7 +171,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w - q->queued++; - n_buf++; - } -- spin_unlock_bh(&q->lock); - - return n_buf; - } -@@ -316,7 +314,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed - { - struct page *page; - -- spin_lock_bh(&q->lock); - for (;;) { - void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true); - -@@ -325,7 +322,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed - - skb_free_frag(buf); - } -- spin_unlock_bh(&q->lock); - - if (!q->cache.va) - return; diff --git a/target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch b/target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch deleted file mode 100644 index 9b1e4c3250705f..00000000000000 --- a/target/linux/generic/backport-5.15/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch +++ /dev/null @@ -1,75 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 12 Jan 2023 10:21:29 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for tx queue - -Similar to MTK Wireless Ethernet Dispatcher (WED) MCU rx queue, -we do not need to protect WED MCU tx queue with a spin lock since -the tx queue is accessed in the two following routines: -- mtk_wed_wo_queue_tx_skb(): - it is run at initialization and during mt7915 normal operation. - Moreover MCU messages are serialized through MCU mutex. -- mtk_wed_wo_queue_tx_clean(): - it runs just at mt7915 driver module unload when no more messages - are sent to the MCU. - -Remove tx queue spinlock. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/7bd0337b2a13ab1a63673b7c03fd35206b3b284e.1673515140.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c -@@ -258,7 +258,6 @@ mtk_wed_wo_queue_alloc(struct mtk_wed_wo - int n_desc, int buf_size, int index, - struct mtk_wed_wo_queue_regs *regs) - { -- spin_lock_init(&q->lock); - q->regs = *regs; - q->n_desc = n_desc; - q->buf_size = buf_size; -@@ -290,7 +289,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed - struct page *page; - int i; - -- spin_lock_bh(&q->lock); - for (i = 0; i < q->n_desc; i++) { - struct mtk_wed_wo_queue_entry *entry = &q->entry[i]; - -@@ -299,7 +297,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed - skb_free_frag(entry->buf); - entry->buf = NULL; - } -- spin_unlock_bh(&q->lock); - - if (!q->cache.va) - return; -@@ -347,8 +344,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w - int ret = 0, index; - u32 ctrl; - -- spin_lock_bh(&q->lock); -- - q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx); - index = (q->head + 1) % q->n_desc; - if (q->tail == index) { -@@ -379,8 +374,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w - mtk_wed_wo_queue_kick(wo, q, q->head); - mtk_wed_wo_kickout(wo); - out: -- spin_unlock_bh(&q->lock); -- - dev_kfree_skb(skb); - - return ret; ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -211,7 +211,6 @@ struct mtk_wed_wo_queue { - struct mtk_wed_wo_queue_regs regs; - - struct page_frag_cache cache; -- spinlock_t lock; - - struct mtk_wed_wo_queue_desc *desc; - dma_addr_t desc_dma; diff --git a/target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch b/target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch deleted file mode 100644 index 33f2b5b0a5ecb0..00000000000000 --- a/target/linux/generic/backport-5.15/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch +++ /dev/null @@ -1,70 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 14 Jan 2023 18:01:28 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_reset utility - routine - -This is a preliminary patch to add Wireless Ethernet Dispatcher reset -support. - -Reviewed-by: Leon Romanovsky -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3202,6 +3202,27 @@ static void mtk_set_mcr_max_rx(struct mt - mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_hw_reset(struct mtk_eth *eth) -+{ -+ u32 val; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); -+ val = RSTCTRL_PPE0_V2; -+ } else { -+ val = RSTCTRL_PPE0; -+ } -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= RSTCTRL_PPE1; -+ -+ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, -+ 0x3ffffff); -+} -+ - static int mtk_hw_init(struct mtk_eth *eth) - { - u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | -@@ -3241,22 +3262,9 @@ static int mtk_hw_init(struct mtk_eth *e - return 0; - } - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); -- val = RSTCTRL_PPE0_V2; -- } else { -- val = RSTCTRL_PPE0; -- } -- -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- val |= RSTCTRL_PPE1; -- -- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); -+ mtk_hw_reset(eth); - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, -- 0x3ffffff); -- - /* Set FE to PDMAv2 if necessary */ - val = mtk_r32(eth, MTK_FE_GLO_MISC); - mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); diff --git a/target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch b/target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch deleted file mode 100644 index 84209fccd55e0e..00000000000000 --- a/target/linux/generic/backport-5.15/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch +++ /dev/null @@ -1,107 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 14 Jan 2023 18:01:29 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_warm_reset - support - -Introduce mtk_hw_warm_reset utility routine. This is a preliminary patch -to align reset procedure to vendor sdk and avoid to power down the chip -during hw reset. - -Reviewed-by: Leon Romanovsky -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3223,7 +3223,54 @@ static void mtk_hw_reset(struct mtk_eth - 0x3ffffff); - } - --static int mtk_hw_init(struct mtk_eth *eth) -+static u32 mtk_hw_reset_read(struct mtk_eth *eth) -+{ -+ u32 val; -+ -+ regmap_read(eth->ethsys, ETHSYS_RSTCTRL, &val); -+ return val; -+} -+ -+static void mtk_hw_warm_reset(struct mtk_eth *eth) -+{ -+ u32 rst_mask, val; -+ -+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, RSTCTRL_FE, -+ RSTCTRL_FE); -+ if (readx_poll_timeout_atomic(mtk_hw_reset_read, eth, val, -+ val & RSTCTRL_FE, 1, 1000)) { -+ dev_err(eth->dev, "warm reset failed\n"); -+ mtk_hw_reset(eth); -+ return; -+ } -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; -+ else -+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ rst_mask |= RSTCTRL_PPE1; -+ -+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask); -+ -+ udelay(1); -+ val = mtk_hw_reset_read(eth); -+ if (!(val & rst_mask)) -+ dev_err(eth->dev, "warm reset stage0 failed %08x (%08x)\n", -+ val, rst_mask); -+ -+ rst_mask |= RSTCTRL_FE; -+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, ~rst_mask); -+ -+ udelay(1); -+ val = mtk_hw_reset_read(eth); -+ if (val & rst_mask) -+ dev_err(eth->dev, "warm reset stage1 failed %08x (%08x)\n", -+ val, rst_mask); -+} -+ -+static int mtk_hw_init(struct mtk_eth *eth, bool reset) - { - u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | - ETHSYS_DMA_AG_MAP_PPE; -@@ -3262,7 +3309,12 @@ static int mtk_hw_init(struct mtk_eth *e - return 0; - } - -- mtk_hw_reset(eth); -+ msleep(100); -+ -+ if (reset) -+ mtk_hw_warm_reset(eth); -+ else -+ mtk_hw_reset(eth); - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - /* Set FE to PDMAv2 if necessary */ -@@ -3450,7 +3502,7 @@ static void mtk_pending_work(struct work - if (eth->dev->pins) - pinctrl_select_state(eth->dev->pins->p, - eth->dev->pins->default_state); -- mtk_hw_init(eth); -+ mtk_hw_init(eth, true); - - /* restart DMA and enable IRQs */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -@@ -4052,7 +4104,7 @@ static int mtk_probe(struct platform_dev - eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE); - INIT_WORK(ð->pending_work, mtk_pending_work); - -- err = mtk_hw_init(eth); -+ err = mtk_hw_init(eth, false); - if (err) - goto err_wed_exit; - diff --git a/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch b/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch deleted file mode 100644 index e75a4cc0d060e7..00000000000000 --- a/target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch +++ /dev/null @@ -1,262 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 14 Jan 2023 18:01:30 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: align reset procedure to vendor - sdk - -Avoid to power-down the ethernet chip during hw reset and align reset -procedure to vendor sdk. - -Reviewed-by: Leon Romanovsky -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2788,14 +2788,29 @@ static void mtk_dma_free(struct mtk_eth - kfree(eth->scratch_head); - } - -+static bool mtk_hw_reset_check(struct mtk_eth *eth) -+{ -+ u32 val = mtk_r32(eth, MTK_INT_STATUS2); -+ -+ return (val & MTK_FE_INT_FQ_EMPTY) || (val & MTK_FE_INT_RFIFO_UF) || -+ (val & MTK_FE_INT_RFIFO_OV) || (val & MTK_FE_INT_TSO_FAIL) || -+ (val & MTK_FE_INT_TSO_ALIGN) || (val & MTK_FE_INT_TSO_ILLEGAL); -+} -+ - static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue) - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - -+ if (test_bit(MTK_RESETTING, ð->state)) -+ return; -+ -+ if (!mtk_hw_reset_check(eth)) -+ return; -+ - eth->netdev[mac->id]->stats.tx_errors++; -- netif_err(eth, tx_err, dev, -- "transmit timed out\n"); -+ netif_err(eth, tx_err, dev, "transmit timed out\n"); -+ - schedule_work(ð->pending_work); - } - -@@ -3277,15 +3292,17 @@ static int mtk_hw_init(struct mtk_eth *e - const struct mtk_reg_map *reg_map = eth->soc->reg_map; - int i, val, ret; - -- if (test_and_set_bit(MTK_HW_INIT, ð->state)) -+ if (!reset && test_and_set_bit(MTK_HW_INIT, ð->state)) - return 0; - -- pm_runtime_enable(eth->dev); -- pm_runtime_get_sync(eth->dev); -+ if (!reset) { -+ pm_runtime_enable(eth->dev); -+ pm_runtime_get_sync(eth->dev); - -- ret = mtk_clk_enable(eth); -- if (ret) -- goto err_disable_pm; -+ ret = mtk_clk_enable(eth); -+ if (ret) -+ goto err_disable_pm; -+ } - - if (eth->ethsys) - regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask, -@@ -3411,8 +3428,10 @@ static int mtk_hw_init(struct mtk_eth *e - return 0; - - err_disable_pm: -- pm_runtime_put_sync(eth->dev); -- pm_runtime_disable(eth->dev); -+ if (!reset) { -+ pm_runtime_put_sync(eth->dev); -+ pm_runtime_disable(eth->dev); -+ } - - return ret; - } -@@ -3474,30 +3493,53 @@ static int mtk_do_ioctl(struct net_devic - return -EOPNOTSUPP; - } - -+static void mtk_prepare_for_reset(struct mtk_eth *eth) -+{ -+ u32 val; -+ int i; -+ -+ /* disabe FE P3 and P4 */ -+ val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= MTK_FE_LINK_DOWN_P4; -+ mtk_w32(eth, val, MTK_FE_GLO_CFG); -+ -+ /* adjust PPE configurations to prepare for reset */ -+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) -+ mtk_ppe_prepare_reset(eth->ppe[i]); -+ -+ /* disable NETSYS interrupts */ -+ mtk_w32(eth, 0, MTK_FE_INT_ENABLE); -+ -+ /* force link down GMAC */ -+ for (i = 0; i < 2; i++) { -+ val = mtk_r32(eth, MTK_MAC_MCR(i)) & ~MAC_MCR_FORCE_LINK; -+ mtk_w32(eth, val, MTK_MAC_MCR(i)); -+ } -+} -+ - static void mtk_pending_work(struct work_struct *work) - { - struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work); -- int err, i; - unsigned long restart = 0; -+ u32 val; -+ int i; - - rtnl_lock(); -- -- dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__); - set_bit(MTK_RESETTING, ð->state); - -+ mtk_prepare_for_reset(eth); -+ - /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!eth->netdev[i]) -+ if (!eth->netdev[i] || !netif_running(eth->netdev[i])) - continue; -+ - mtk_stop(eth->netdev[i]); - __set_bit(i, &restart); - } -- dev_dbg(eth->dev, "[%s][%d] mtk_stop ends\n", __func__, __LINE__); - -- /* restart underlying hardware such as power, clock, pin mux -- * and the connected phy -- */ -- mtk_hw_deinit(eth); -+ usleep_range(15000, 16000); - - if (eth->dev->pins) - pinctrl_select_state(eth->dev->pins->p, -@@ -3508,15 +3550,19 @@ static void mtk_pending_work(struct work - for (i = 0; i < MTK_MAC_COUNT; i++) { - if (!test_bit(i, &restart)) - continue; -- err = mtk_open(eth->netdev[i]); -- if (err) { -+ -+ if (mtk_open(eth->netdev[i])) { - netif_alert(eth, ifup, eth->netdev[i], -- "Driver up/down cycle failed, closing device.\n"); -+ "Driver up/down cycle failed\n"); - dev_close(eth->netdev[i]); - } - } - -- dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__); -+ /* enabe FE P3 and P4 */ -+ val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val &= ~MTK_FE_LINK_DOWN_P4; -+ mtk_w32(eth, val, MTK_FE_GLO_CFG); - - clear_bit(MTK_RESETTING, ð->state); - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -72,12 +72,24 @@ - #define MTK_HW_LRO_REPLACE_DELTA 1000 - #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 - -+/* Frame Engine Global Configuration */ -+#define MTK_FE_GLO_CFG 0x00 -+#define MTK_FE_LINK_DOWN_P3 BIT(11) -+#define MTK_FE_LINK_DOWN_P4 BIT(12) -+ - /* Frame Engine Global Reset Register */ - #define MTK_RST_GL 0x04 - #define RST_GL_PSE BIT(0) - - /* Frame Engine Interrupt Status Register */ - #define MTK_INT_STATUS2 0x08 -+#define MTK_FE_INT_ENABLE 0x0c -+#define MTK_FE_INT_FQ_EMPTY BIT(8) -+#define MTK_FE_INT_TSO_FAIL BIT(12) -+#define MTK_FE_INT_TSO_ILLEGAL BIT(13) -+#define MTK_FE_INT_TSO_ALIGN BIT(14) -+#define MTK_FE_INT_RFIFO_OV BIT(18) -+#define MTK_FE_INT_RFIFO_UF BIT(19) - #define MTK_GDM1_AF BIT(28) - #define MTK_GDM2_AF BIT(29) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -716,6 +716,33 @@ int mtk_foe_entry_idle_time(struct mtk_p - return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); - } - -+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) -+{ -+ if (!ppe) -+ return -EINVAL; -+ -+ /* disable KA */ -+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE); -+ ppe_clear(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE); -+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0); -+ usleep_range(10000, 11000); -+ -+ /* set KA timer to maximum */ -+ ppe_set(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE); -+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0xffffffff); -+ -+ /* set KA tick select */ -+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_TICK_SEL); -+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE); -+ usleep_range(10000, 11000); -+ -+ /* disable scan mode */ -+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_SCAN_MODE); -+ usleep_range(10000, 11000); -+ -+ return mtk_ppe_wait_busy(ppe); -+} -+ - struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, - int version, int index) - { ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -307,6 +307,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - void mtk_ppe_deinit(struct mtk_eth *eth); - void mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); -+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -@@ -58,6 +58,12 @@ - #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16) - #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18) - #define MTK_PPE_TB_CFG_INFO_SEL BIT(20) -+#define MTK_PPE_TB_TICK_SEL BIT(24) -+ -+#define MTK_PPE_BIND_LMT1 0x230 -+#define MTK_PPE_NTU_KEEPALIVE GENMASK(23, 16) -+ -+#define MTK_PPE_KEEPALIVE 0x234 - - enum { - MTK_PPE_SCAN_MODE_DISABLED, diff --git a/target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch b/target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch deleted file mode 100644 index 898785ece2c7cb..00000000000000 --- a/target/linux/generic/backport-5.15/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch +++ /dev/null @@ -1,249 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 14 Jan 2023 18:01:31 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add dma checks to - mtk_hw_reset_check - -Introduce mtk_hw_check_dma_hang routine to monitor possible dma hangs. - -Reviewed-by: Leon Romanovsky -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -50,6 +50,7 @@ static const struct mtk_reg_map mtk_reg_ - .delay_irq = 0x0a0c, - .irq_status = 0x0a20, - .irq_mask = 0x0a28, -+ .adma_rx_dbg0 = 0x0a38, - .int_grp = 0x0a50, - }, - .qdma = { -@@ -79,6 +80,8 @@ static const struct mtk_reg_map mtk_reg_ - [0] = 0x2800, - [1] = 0x2c00, - }, -+ .pse_iq_sta = 0x0110, -+ .pse_oq_sta = 0x0118, - }; - - static const struct mtk_reg_map mt7628_reg_map = { -@@ -109,6 +112,7 @@ static const struct mtk_reg_map mt7986_r - .delay_irq = 0x620c, - .irq_status = 0x6220, - .irq_mask = 0x6228, -+ .adma_rx_dbg0 = 0x6238, - .int_grp = 0x6250, - }, - .qdma = { -@@ -138,6 +142,8 @@ static const struct mtk_reg_map mt7986_r - [0] = 0x4800, - [1] = 0x4c00, - }, -+ .pse_iq_sta = 0x0180, -+ .pse_oq_sta = 0x01a0, - }; - - /* strings used by ethtool */ -@@ -3285,6 +3291,102 @@ static void mtk_hw_warm_reset(struct mtk - val, rst_mask); - } - -+static bool mtk_hw_check_dma_hang(struct mtk_eth *eth) -+{ -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; -+ bool gmac1_tx, gmac2_tx, gdm1_tx, gdm2_tx; -+ bool oq_hang, cdm1_busy, adma_busy; -+ bool wtx_busy, cdm_full, oq_free; -+ u32 wdidx, val, gdm1_fc, gdm2_fc; -+ bool qfsm_hang, qfwd_hang; -+ bool ret = false; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) -+ return false; -+ -+ /* WDMA sanity checks */ -+ wdidx = mtk_r32(eth, reg_map->wdma_base[0] + 0xc); -+ -+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x204); -+ wtx_busy = FIELD_GET(MTK_TX_DMA_BUSY, val); -+ -+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x230); -+ cdm_full = !FIELD_GET(MTK_CDM_TXFIFO_RDY, val); -+ -+ oq_free = (!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(24, 16)) && -+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x4) & GENMASK(8, 0)) && -+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x10) & GENMASK(24, 16))); -+ -+ if (wdidx == eth->reset.wdidx && wtx_busy && cdm_full && oq_free) { -+ if (++eth->reset.wdma_hang_count > 2) { -+ eth->reset.wdma_hang_count = 0; -+ ret = true; -+ } -+ goto out; -+ } -+ -+ /* QDMA sanity checks */ -+ qfsm_hang = !!mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x234); -+ qfwd_hang = !mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x308); -+ -+ gdm1_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM1_FSM)) > 0; -+ gdm2_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM2_FSM)) > 0; -+ gmac1_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(0))) != 1; -+ gmac2_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(1))) != 1; -+ gdm1_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x24); -+ gdm2_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x64); -+ -+ if (qfsm_hang && qfwd_hang && -+ ((gdm1_tx && gmac1_tx && gdm1_fc < 1) || -+ (gdm2_tx && gmac2_tx && gdm2_fc < 1))) { -+ if (++eth->reset.qdma_hang_count > 2) { -+ eth->reset.qdma_hang_count = 0; -+ ret = true; -+ } -+ goto out; -+ } -+ -+ /* ADMA sanity checks */ -+ oq_hang = !!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(8, 0)); -+ cdm1_busy = !!(mtk_r32(eth, MTK_FE_CDM1_FSM) & GENMASK(31, 16)); -+ adma_busy = !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & GENMASK(4, 0)) && -+ !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & BIT(6)); -+ -+ if (oq_hang && cdm1_busy && adma_busy) { -+ if (++eth->reset.adma_hang_count > 2) { -+ eth->reset.adma_hang_count = 0; -+ ret = true; -+ } -+ goto out; -+ } -+ -+ eth->reset.wdma_hang_count = 0; -+ eth->reset.qdma_hang_count = 0; -+ eth->reset.adma_hang_count = 0; -+out: -+ eth->reset.wdidx = wdidx; -+ -+ return ret; -+} -+ -+static void mtk_hw_reset_monitor_work(struct work_struct *work) -+{ -+ struct delayed_work *del_work = to_delayed_work(work); -+ struct mtk_eth *eth = container_of(del_work, struct mtk_eth, -+ reset.monitor_work); -+ -+ if (test_bit(MTK_RESETTING, ð->state)) -+ goto out; -+ -+ /* DMA stuck checks */ -+ if (mtk_hw_check_dma_hang(eth)) -+ schedule_work(ð->pending_work); -+ -+out: -+ schedule_delayed_work(ð->reset.monitor_work, -+ MTK_DMA_MONITOR_TIMEOUT); -+} -+ - static int mtk_hw_init(struct mtk_eth *eth, bool reset) - { - u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | -@@ -3600,6 +3702,7 @@ static int mtk_cleanup(struct mtk_eth *e - mtk_unreg_dev(eth); - mtk_free_dev(eth); - cancel_work_sync(ð->pending_work); -+ cancel_delayed_work_sync(ð->reset.monitor_work); - - return 0; - } -@@ -4037,6 +4140,7 @@ static int mtk_probe(struct platform_dev - - eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; - INIT_WORK(ð->rx_dim.work, mtk_dim_rx); -+ INIT_DELAYED_WORK(ð->reset.monitor_work, mtk_hw_reset_monitor_work); - - eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; - INIT_WORK(ð->tx_dim.work, mtk_dim_tx); -@@ -4241,6 +4345,8 @@ static int mtk_probe(struct platform_dev - NAPI_POLL_WEIGHT); - - platform_set_drvdata(pdev, eth); -+ schedule_delayed_work(ð->reset.monitor_work, -+ MTK_DMA_MONITOR_TIMEOUT); - - return 0; - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -256,6 +256,8 @@ - - #define MTK_RX_DONE_INT_V2 BIT(14) - -+#define MTK_CDM_TXFIFO_RDY BIT(7) -+ - /* QDMA Interrupt grouping registers */ - #define MTK_RLS_DONE_INT BIT(0) - -@@ -538,6 +540,17 @@ - #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) - #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) - -+#define MTK_FE_CDM1_FSM 0x220 -+#define MTK_FE_CDM2_FSM 0x224 -+#define MTK_FE_CDM3_FSM 0x238 -+#define MTK_FE_CDM4_FSM 0x298 -+#define MTK_FE_CDM5_FSM 0x318 -+#define MTK_FE_CDM6_FSM 0x328 -+#define MTK_FE_GDM1_FSM 0x228 -+#define MTK_FE_GDM2_FSM 0x22C -+ -+#define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) -+ - struct mtk_rx_dma { - unsigned int rxd1; - unsigned int rxd2; -@@ -934,6 +947,7 @@ struct mtk_reg_map { - u32 delay_irq; /* delay interrupt */ - u32 irq_status; /* interrupt status */ - u32 irq_mask; /* interrupt mask */ -+ u32 adma_rx_dbg0; - u32 int_grp; - } pdma; - struct { -@@ -960,6 +974,8 @@ struct mtk_reg_map { - u32 gdma_to_ppe0; - u32 ppe_base; - u32 wdma_base[2]; -+ u32 pse_iq_sta; -+ u32 pse_oq_sta; - }; - - /* struct mtk_eth_data - This is the structure holding all differences -@@ -1002,6 +1018,8 @@ struct mtk_soc_data { - } txrx; - }; - -+#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) -+ - /* currently no SoC has more than 2 macs */ - #define MTK_MAX_DEVS 2 - -@@ -1124,6 +1142,14 @@ struct mtk_eth { - struct rhashtable flow_table; - - struct bpf_prog __rcu *prog; -+ -+ struct { -+ struct delayed_work monitor_work; -+ u32 wdidx; -+ u8 wdma_hang_count; -+ u8 qdma_hang_count; -+ u8 adma_hang_count; -+ } reset; - }; - - /* struct mtk_mac - the structure that holds the info about the MACs of the diff --git a/target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch b/target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch deleted file mode 100644 index cc9aaaf0b84142..00000000000000 --- a/target/linux/generic/backport-5.15/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch +++ /dev/null @@ -1,124 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 14 Jan 2023 18:01:32 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add reset/reset_complete callbacks - -Introduce reset and reset_complete wlan callback to schedule WLAN driver -reset when ethernet/wed driver is resetting. - -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3631,6 +3631,11 @@ static void mtk_pending_work(struct work - set_bit(MTK_RESETTING, ð->state); - - mtk_prepare_for_reset(eth); -+ mtk_wed_fe_reset(); -+ /* Run again reset preliminary configuration in order to avoid any -+ * possible race during FE reset since it can run releasing RTNL lock. -+ */ -+ mtk_prepare_for_reset(eth); - - /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -@@ -3668,6 +3673,8 @@ static void mtk_pending_work(struct work - - clear_bit(MTK_RESETTING, ð->state); - -+ mtk_wed_fe_reset_complete(); -+ - rtnl_unlock(); - } - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -205,6 +205,48 @@ mtk_wed_wo_reset(struct mtk_wed_device * - iounmap(reg); - } - -+void mtk_wed_fe_reset(void) -+{ -+ int i; -+ -+ mutex_lock(&hw_lock); -+ -+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { -+ struct mtk_wed_hw *hw = hw_list[i]; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ int err; -+ -+ if (!dev || !dev->wlan.reset) -+ continue; -+ -+ /* reset callback blocks until WLAN reset is completed */ -+ err = dev->wlan.reset(dev); -+ if (err) -+ dev_err(dev->dev, "wlan reset failed: %d\n", err); -+ } -+ -+ mutex_unlock(&hw_lock); -+} -+ -+void mtk_wed_fe_reset_complete(void) -+{ -+ int i; -+ -+ mutex_lock(&hw_lock); -+ -+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { -+ struct mtk_wed_hw *hw = hw_list[i]; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (!dev || !dev->wlan.reset_complete) -+ continue; -+ -+ dev->wlan.reset_complete(dev); -+ } -+ -+ mutex_unlock(&hw_lock); -+} -+ - static struct mtk_wed_hw * - mtk_wed_assign(struct mtk_wed_device *dev) - { ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -128,6 +128,8 @@ void mtk_wed_add_hw(struct device_node * - void mtk_wed_exit(void); - int mtk_wed_flow_add(int index); - void mtk_wed_flow_remove(int index); -+void mtk_wed_fe_reset(void); -+void mtk_wed_fe_reset_complete(void); - #else - static inline void - mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -@@ -147,6 +149,13 @@ static inline void mtk_wed_flow_remove(i - { - } - -+static inline void mtk_wed_fe_reset(void) -+{ -+} -+ -+static inline void mtk_wed_fe_reset_complete(void) -+{ -+} - #endif - - #ifdef CONFIG_DEBUG_FS ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -151,6 +151,8 @@ struct mtk_wed_device { - void (*release_rx_buf)(struct mtk_wed_device *wed); - void (*update_wo_rx_stats)(struct mtk_wed_device *wed, - struct mtk_wed_wo_rx_stats *stats); -+ int (*reset)(struct mtk_wed_device *wed); -+ void (*reset_complete)(struct mtk_wed_device *wed); - } wlan; - #endif - }; diff --git a/target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch b/target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch deleted file mode 100644 index c63628da99da81..00000000000000 --- a/target/linux/generic/backport-5.15/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch +++ /dev/null @@ -1,106 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 5 Dec 2022 12:34:42 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add reset to rx_ring_setup callback - -This patch adds reset parameter to mtk_wed_rx_ring_setup signature -in order to align rx_ring_setup callback to tx_ring_setup one introduced -in 'commit 23dca7a90017 ("net: ethernet: mtk_wed: add reset to -tx_ring_setup callback")' - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Leon Romanovsky -Link: https://lore.kernel.org/r/29c6e7a5469e784406cf3e2920351d1207713d05.1670239984.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1252,7 +1252,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we - } - - static int --mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size) -+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size, -+ bool reset) - { - u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; - struct mtk_wed_ring *wdma; -@@ -1261,8 +1262,8 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we - return -EINVAL; - - wdma = &dev->tx_wdma[idx]; -- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, -- true)) -+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, -+ desc_size, true)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, -@@ -1272,6 +1273,9 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0); - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0); - -+ if (reset) -+ mtk_wed_ring_reset(wdma, MTK_WED_WDMA_RING_SIZE, true); -+ - if (!idx) { - wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE, - wdma->desc_phys); -@@ -1611,18 +1615,20 @@ mtk_wed_txfree_ring_setup(struct mtk_wed - } - - static int --mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) -+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs, -+ bool reset) - { - struct mtk_wed_ring *ring = &dev->rx_ring[idx]; - - if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring))) - return -EINVAL; - -- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, -- sizeof(*ring->desc), false)) -+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, -+ sizeof(*ring->desc), false)) - return -ENOMEM; - -- if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, -+ reset)) - return -ENOMEM; - - ring->reg_base = MTK_WED_RING_RX_DATA(idx); ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -162,7 +162,7 @@ struct mtk_wed_ops { - int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, - void __iomem *regs, bool reset); - int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, -- void __iomem *regs); -+ void __iomem *regs, bool reset); - int (*txfree_ring_setup)(struct mtk_wed_device *dev, - void __iomem *regs); - int (*msg_update)(struct mtk_wed_device *dev, int cmd_id, -@@ -230,8 +230,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic - (_dev)->ops->irq_get(_dev, _mask) - #define mtk_wed_device_irq_set_mask(_dev, _mask) \ - (_dev)->ops->irq_set_mask(_dev, _mask) --#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \ -- (_dev)->ops->rx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \ -+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset) - #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \ - (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) - #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ -@@ -251,7 +251,7 @@ static inline bool mtk_wed_device_active - #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) - #define mtk_wed_device_irq_get(_dev, _mask) 0 - #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0) --#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV - #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) - #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV - #define mtk_wed_device_stop(_dev) do {} while (0) diff --git a/target/linux/generic/backport-5.15/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch b/target/linux/generic/backport-5.15/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch deleted file mode 100644 index 45af898cf003b8..00000000000000 --- a/target/linux/generic/backport-5.15/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Date: Thu, 27 Oct 2022 19:50:31 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: account for vlan in rx - header length - -The network stack assumes that devices can handle an extra VLAN tag without -increasing the MTU - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -29,7 +29,7 @@ - #define MTK_TX_DMA_BUF_LEN_V2 0xffff - #define MTK_DMA_SIZE 512 - #define MTK_MAC_COUNT 2 --#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN) -+#define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN) - #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN) - #define MTK_DMA_DUMMY_DESC 0xffffffff - #define MTK_DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | \ diff --git a/target/linux/generic/backport-5.15/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch b/target/linux/generic/backport-5.15/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch deleted file mode 100644 index 908b2d88f3ca05..00000000000000 --- a/target/linux/generic/backport-5.15/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch +++ /dev/null @@ -1,143 +0,0 @@ -From: Felix Fietkau -Date: Thu, 27 Oct 2022 19:53:57 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: increase tx ring side for - QDMA devices - -In order to use the hardware traffic shaper feature, a larger tx ring is -needed, especially for the scratch ring, which the hardware shaper uses to -reorder packets. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -900,7 +900,7 @@ static int mtk_init_fq_dma(struct mtk_et - { - const struct mtk_soc_data *soc = eth->soc; - dma_addr_t phy_ring_tail; -- int cnt = MTK_DMA_SIZE; -+ int cnt = MTK_QDMA_RING_SIZE; - dma_addr_t dma_addr; - int i; - -@@ -2154,19 +2154,25 @@ static int mtk_tx_alloc(struct mtk_eth * - struct mtk_tx_ring *ring = ð->tx_ring; - int i, sz = soc->txrx.txd_size; - struct mtk_tx_dma_v2 *txd; -+ int ring_size; - -- ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf), -+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) -+ ring_size = MTK_QDMA_RING_SIZE; -+ else -+ ring_size = MTK_DMA_SIZE; -+ -+ ring->buf = kcalloc(ring_size, sizeof(*ring->buf), - GFP_KERNEL); - if (!ring->buf) - goto no_tx_mem; - -- ring->dma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, -+ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, - &ring->phys, GFP_KERNEL); - if (!ring->dma) - goto no_tx_mem; - -- for (i = 0; i < MTK_DMA_SIZE; i++) { -- int next = (i + 1) % MTK_DMA_SIZE; -+ for (i = 0; i < ring_size; i++) { -+ int next = (i + 1) % ring_size; - u32 next_ptr = ring->phys + next * sz; - - txd = ring->dma + i * sz; -@@ -2186,22 +2192,22 @@ static int mtk_tx_alloc(struct mtk_eth * - * descriptors in ring->dma_pdma. - */ - if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { -- ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, -+ ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, - &ring->phys_pdma, GFP_KERNEL); - if (!ring->dma_pdma) - goto no_tx_mem; - -- for (i = 0; i < MTK_DMA_SIZE; i++) { -+ for (i = 0; i < ring_size; i++) { - ring->dma_pdma[i].txd2 = TX_DMA_DESP2_DEF; - ring->dma_pdma[i].txd4 = 0; - } - } - -- ring->dma_size = MTK_DMA_SIZE; -- atomic_set(&ring->free_count, MTK_DMA_SIZE - 2); -+ ring->dma_size = ring_size; -+ atomic_set(&ring->free_count, ring_size - 2); - ring->next_free = ring->dma; - ring->last_free = (void *)txd; -- ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz)); -+ ring->last_free_ptr = (u32)(ring->phys + ((ring_size - 1) * sz)); - ring->thresh = MAX_SKB_FRAGS; - - /* make sure that all changes to the dma ring are flushed before we -@@ -2213,14 +2219,14 @@ static int mtk_tx_alloc(struct mtk_eth * - mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr); - mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr); - mtk_w32(eth, -- ring->phys + ((MTK_DMA_SIZE - 1) * sz), -+ ring->phys + ((ring_size - 1) * sz), - soc->reg_map->qdma.crx_ptr); - mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr); - mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, - soc->reg_map->qdma.qtx_cfg); - } else { - mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); -- mtk_w32(eth, MTK_DMA_SIZE, MT7628_TX_MAX_CNT0); -+ mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0); - mtk_w32(eth, 0, MT7628_TX_CTX_IDX0); - mtk_w32(eth, MT7628_PST_DTX_IDX0, soc->reg_map->pdma.rst_idx); - } -@@ -2238,7 +2244,7 @@ static void mtk_tx_clean(struct mtk_eth - int i; - - if (ring->buf) { -- for (i = 0; i < MTK_DMA_SIZE; i++) -+ for (i = 0; i < ring->dma_size; i++) - mtk_tx_unmap(eth, &ring->buf[i], false); - kfree(ring->buf); - ring->buf = NULL; -@@ -2246,14 +2252,14 @@ static void mtk_tx_clean(struct mtk_eth - - if (ring->dma) { - dma_free_coherent(eth->dma_dev, -- MTK_DMA_SIZE * soc->txrx.txd_size, -+ ring->dma_size * soc->txrx.txd_size, - ring->dma, ring->phys); - ring->dma = NULL; - } - - if (ring->dma_pdma) { - dma_free_coherent(eth->dma_dev, -- MTK_DMA_SIZE * soc->txrx.txd_size, -+ ring->dma_size * soc->txrx.txd_size, - ring->dma_pdma, ring->phys_pdma); - ring->dma_pdma = NULL; - } -@@ -2776,7 +2782,7 @@ static void mtk_dma_free(struct mtk_eth - netdev_reset_queue(eth->netdev[i]); - if (eth->scratch_ring) { - dma_free_coherent(eth->dma_dev, -- MTK_DMA_SIZE * soc->txrx.txd_size, -+ MTK_QDMA_RING_SIZE * soc->txrx.txd_size, - eth->scratch_ring, eth->phy_scratch_ring); - eth->scratch_ring = NULL; - eth->phy_scratch_ring = 0; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -27,6 +27,7 @@ - #define MTK_MAX_RX_LENGTH_2K 2048 - #define MTK_TX_DMA_BUF_LEN 0x3fff - #define MTK_TX_DMA_BUF_LEN_V2 0xffff -+#define MTK_QDMA_RING_SIZE 2048 - #define MTK_DMA_SIZE 512 - #define MTK_MAC_COUNT 2 - #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN) diff --git a/target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch b/target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch deleted file mode 100644 index 34aa7b14cdf2ef..00000000000000 --- a/target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Felix Fietkau -Date: Fri, 4 Nov 2022 19:49:08 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: avoid port_mg assignment on - MT7622 and newer - -On newer chips, this field is unused and contains some bits related to queue -assignment. Initialize it to 0 in those cases. -Fix offload_version on MT7621 and MT7623, which still need the previous value. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4424,7 +4424,7 @@ static const struct mtk_soc_data mt7621_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7621_CLKS_BITMAP, - .required_pctl = false, -- .offload_version = 2, -+ .offload_version = 1, - .hash_offset = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { -@@ -4463,7 +4463,7 @@ static const struct mtk_soc_data mt7623_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, -- .offload_version = 2, -+ .offload_version = 1, - .hash_offset = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -175,6 +175,8 @@ int mtk_foe_entry_prepare(struct mtk_eth - val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, pse_port) | - FIELD_PREP(MTK_FOE_IB2_PORT_AG_V2, 0xf); - } else { -+ int port_mg = eth->soc->offload_version > 1 ? 0 : 0x3f; -+ - val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | - FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | - FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | -@@ -182,7 +184,7 @@ int mtk_foe_entry_prepare(struct mtk_eth - entry->ib1 = val; - - val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port) | -- FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | -+ FIELD_PREP(MTK_FOE_IB2_PORT_MG, port_mg) | - FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f); - } - diff --git a/target/linux/generic/backport-5.15/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch b/target/linux/generic/backport-5.15/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch deleted file mode 100644 index 765666602e4afe..00000000000000 --- a/target/linux/generic/backport-5.15/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch +++ /dev/null @@ -1,654 +0,0 @@ -From: Felix Fietkau -Date: Thu, 27 Oct 2022 20:17:27 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: implement multi-queue - support for per-port queues - -When sending traffic to multiple ports with different link speeds, queued -packets to one port can drown out tx to other ports. -In order to better handle transmission to multiple ports, use the hardware -shaper feature to implement weighted fair queueing between ports. -Weight and maximum rate are automatically adjusted based on the link speed -of the port. -The first 3 queues are unrestricted and reserved for non-DSA direct tx on -GMAC ports. The following queues are automatically assigned by the MTK DSA -tag driver based on the target port number. -The PPE offload code configures the queues for offloaded traffic in the same -way. -This feature is only supported on devices supporting QDMA. All queues still -share the same DMA ring and descriptor pool. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -55,6 +55,7 @@ static const struct mtk_reg_map mtk_reg_ - }, - .qdma = { - .qtx_cfg = 0x1800, -+ .qtx_sch = 0x1804, - .rx_ptr = 0x1900, - .rx_cnt_cfg = 0x1904, - .qcrx_ptr = 0x1908, -@@ -62,6 +63,7 @@ static const struct mtk_reg_map mtk_reg_ - .rst_idx = 0x1a08, - .delay_irq = 0x1a0c, - .fc_th = 0x1a10, -+ .tx_sch_rate = 0x1a14, - .int_grp = 0x1a20, - .hred = 0x1a44, - .ctx_ptr = 0x1b00, -@@ -117,6 +119,7 @@ static const struct mtk_reg_map mt7986_r - }, - .qdma = { - .qtx_cfg = 0x4400, -+ .qtx_sch = 0x4404, - .rx_ptr = 0x4500, - .rx_cnt_cfg = 0x4504, - .qcrx_ptr = 0x4508, -@@ -134,6 +137,7 @@ static const struct mtk_reg_map mt7986_r - .fq_tail = 0x4724, - .fq_count = 0x4728, - .fq_blen = 0x472c, -+ .tx_sch_rate = 0x4798, - }, - .gdm1_cnt = 0x1c00, - .gdma_to_ppe0 = 0x3333, -@@ -576,6 +580,75 @@ static void mtk_mac_link_down(struct phy - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, -+ int speed) -+{ -+ const struct mtk_soc_data *soc = eth->soc; -+ u32 ofs, val; -+ -+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) -+ return; -+ -+ val = MTK_QTX_SCH_MIN_RATE_EN | -+ /* minimum: 10 Mbps */ -+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | -+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | -+ MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; -+ -+ if (IS_ENABLED(CONFIG_SOC_MT7621)) { -+ switch (speed) { -+ case SPEED_10: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 2) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); -+ break; -+ case SPEED_100: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 3); -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); -+ break; -+ case SPEED_1000: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 105) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10); -+ break; -+ default: -+ break; -+ } -+ } else { -+ switch (speed) { -+ case SPEED_10: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); -+ break; -+ case SPEED_100: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5); -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); -+ break; -+ case SPEED_1000: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 10) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10); -+ break; -+ default: -+ break; -+ } -+ } -+ -+ ofs = MTK_QTX_OFFSET * idx; -+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); -+} -+ - static void mtk_mac_link_up(struct phylink_config *config, - struct phy_device *phy, - unsigned int mode, phy_interface_t interface, -@@ -601,6 +674,8 @@ static void mtk_mac_link_up(struct phyli - break; - } - -+ mtk_set_queue_speed(mac->hw, mac->id, speed); -+ - /* Configure duplex */ - if (duplex == DUPLEX_FULL) - mcr |= MAC_MCR_FORCE_DPX; -@@ -1059,7 +1134,8 @@ static void mtk_tx_set_dma_desc_v1(struc - - WRITE_ONCE(desc->txd1, info->addr); - -- data = TX_DMA_SWC | TX_DMA_PLEN0(info->size); -+ data = TX_DMA_SWC | TX_DMA_PLEN0(info->size) | -+ FIELD_PREP(TX_DMA_PQID, info->qid); - if (info->last) - data |= TX_DMA_LS0; - WRITE_ONCE(desc->txd3, data); -@@ -1093,9 +1169,6 @@ static void mtk_tx_set_dma_desc_v2(struc - data |= TX_DMA_LS0; - WRITE_ONCE(desc->txd3, data); - -- if (!info->qid && mac->id) -- info->qid = MTK_QDMA_GMAC2_QID; -- - data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ - data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); - WRITE_ONCE(desc->txd4, data); -@@ -1139,11 +1212,12 @@ static int mtk_tx_map(struct sk_buff *sk - .gso = gso, - .csum = skb->ip_summed == CHECKSUM_PARTIAL, - .vlan = skb_vlan_tag_present(skb), -- .qid = skb->mark & MTK_QDMA_TX_MASK, -+ .qid = skb_get_queue_mapping(skb), - .vlan_tci = skb_vlan_tag_get(skb), - .first = true, - .last = !skb_is_nonlinear(skb), - }; -+ struct netdev_queue *txq; - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - const struct mtk_soc_data *soc = eth->soc; -@@ -1151,8 +1225,10 @@ static int mtk_tx_map(struct sk_buff *sk - struct mtk_tx_dma *itxd_pdma, *txd_pdma; - struct mtk_tx_buf *itx_buf, *tx_buf; - int i, n_desc = 1; -+ int queue = skb_get_queue_mapping(skb); - int k = 0; - -+ txq = netdev_get_tx_queue(dev, queue); - itxd = ring->next_free; - itxd_pdma = qdma_to_pdma(ring, itxd); - if (itxd == ring->last_free) -@@ -1201,7 +1277,7 @@ static int mtk_tx_map(struct sk_buff *sk - memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); - txd_info.size = min_t(unsigned int, frag_size, - soc->txrx.dma_max_len); -- txd_info.qid = skb->mark & MTK_QDMA_TX_MASK; -+ txd_info.qid = queue; - txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 && - !(frag_size - txd_info.size); - txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, -@@ -1240,7 +1316,7 @@ static int mtk_tx_map(struct sk_buff *sk - txd_pdma->txd2 |= TX_DMA_LS1; - } - -- netdev_sent_queue(dev, skb->len); -+ netdev_tx_sent_queue(txq, skb->len); - skb_tx_timestamp(skb); - - ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); -@@ -1252,8 +1328,7 @@ static int mtk_tx_map(struct sk_buff *sk - wmb(); - - if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { -- if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || -- !netdev_xmit_more()) -+ if (netif_xmit_stopped(txq) || !netdev_xmit_more()) - mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr); - } else { - int next_idx; -@@ -1322,7 +1397,7 @@ static void mtk_wake_queue(struct mtk_et - for (i = 0; i < MTK_MAC_COUNT; i++) { - if (!eth->netdev[i]) - continue; -- netif_wake_queue(eth->netdev[i]); -+ netif_tx_wake_all_queues(eth->netdev[i]); - } - } - -@@ -1346,7 +1421,7 @@ static netdev_tx_t mtk_start_xmit(struct - - tx_num = mtk_cal_txd_req(eth, skb); - if (unlikely(atomic_read(&ring->free_count) <= tx_num)) { -- netif_stop_queue(dev); -+ netif_tx_stop_all_queues(dev); - netif_err(eth, tx_queued, dev, - "Tx Ring full when queue awake!\n"); - spin_unlock(ð->page_lock); -@@ -1372,7 +1447,7 @@ static netdev_tx_t mtk_start_xmit(struct - goto drop; - - if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) -- netif_stop_queue(dev); -+ netif_tx_stop_all_queues(dev); - - spin_unlock(ð->page_lock); - -@@ -1539,10 +1614,12 @@ static int mtk_xdp_submit_frame(struct m - struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf); - const struct mtk_soc_data *soc = eth->soc; - struct mtk_tx_ring *ring = ð->tx_ring; -+ struct mtk_mac *mac = netdev_priv(dev); - struct mtk_tx_dma_desc_info txd_info = { - .size = xdpf->len, - .first = true, - .last = !xdp_frame_has_frags(xdpf), -+ .qid = mac->id, - }; - int err, index = 0, n_desc = 1, nr_frags; - struct mtk_tx_dma *htxd, *txd, *txd_pdma; -@@ -1593,6 +1670,7 @@ static int mtk_xdp_submit_frame(struct m - memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); - txd_info.size = skb_frag_size(&sinfo->frags[index]); - txd_info.last = index + 1 == nr_frags; -+ txd_info.qid = mac->id; - data = skb_frag_address(&sinfo->frags[index]); - - index++; -@@ -1944,8 +2022,46 @@ rx_done: - return done; - } - -+struct mtk_poll_state { -+ struct netdev_queue *txq; -+ unsigned int total; -+ unsigned int done; -+ unsigned int bytes; -+}; -+ -+static void -+mtk_poll_tx_done(struct mtk_eth *eth, struct mtk_poll_state *state, u8 mac, -+ struct sk_buff *skb) -+{ -+ struct netdev_queue *txq; -+ struct net_device *dev; -+ unsigned int bytes = skb->len; -+ -+ state->total++; -+ eth->tx_packets++; -+ eth->tx_bytes += bytes; -+ -+ dev = eth->netdev[mac]; -+ if (!dev) -+ return; -+ -+ txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); -+ if (state->txq == txq) { -+ state->done++; -+ state->bytes += bytes; -+ return; -+ } -+ -+ if (state->txq) -+ netdev_tx_completed_queue(state->txq, state->done, state->bytes); -+ -+ state->txq = txq; -+ state->done = 1; -+ state->bytes = bytes; -+} -+ - static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, -- unsigned int *done, unsigned int *bytes) -+ struct mtk_poll_state *state) - { - const struct mtk_reg_map *reg_map = eth->soc->reg_map; - struct mtk_tx_ring *ring = ð->tx_ring; -@@ -1975,12 +2091,9 @@ static int mtk_poll_tx_qdma(struct mtk_e - break; - - if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -- if (tx_buf->type == MTK_TYPE_SKB) { -- struct sk_buff *skb = tx_buf->data; -+ if (tx_buf->type == MTK_TYPE_SKB) -+ mtk_poll_tx_done(eth, state, mac, tx_buf->data); - -- bytes[mac] += skb->len; -- done[mac]++; -- } - budget--; - } - mtk_tx_unmap(eth, tx_buf, true); -@@ -1998,7 +2111,7 @@ static int mtk_poll_tx_qdma(struct mtk_e - } - - static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget, -- unsigned int *done, unsigned int *bytes) -+ struct mtk_poll_state *state) - { - struct mtk_tx_ring *ring = ð->tx_ring; - struct mtk_tx_buf *tx_buf; -@@ -2014,12 +2127,8 @@ static int mtk_poll_tx_pdma(struct mtk_e - break; - - if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -- if (tx_buf->type == MTK_TYPE_SKB) { -- struct sk_buff *skb = tx_buf->data; -- -- bytes[0] += skb->len; -- done[0]++; -- } -+ if (tx_buf->type == MTK_TYPE_SKB) -+ mtk_poll_tx_done(eth, state, 0, tx_buf->data); - budget--; - } - mtk_tx_unmap(eth, tx_buf, true); -@@ -2040,26 +2149,15 @@ static int mtk_poll_tx(struct mtk_eth *e - { - struct mtk_tx_ring *ring = ð->tx_ring; - struct dim_sample dim_sample = {}; -- unsigned int done[MTK_MAX_DEVS]; -- unsigned int bytes[MTK_MAX_DEVS]; -- int total = 0, i; -- -- memset(done, 0, sizeof(done)); -- memset(bytes, 0, sizeof(bytes)); -+ struct mtk_poll_state state = {}; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -- budget = mtk_poll_tx_qdma(eth, budget, done, bytes); -+ budget = mtk_poll_tx_qdma(eth, budget, &state); - else -- budget = mtk_poll_tx_pdma(eth, budget, done, bytes); -+ budget = mtk_poll_tx_pdma(eth, budget, &state); - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!eth->netdev[i] || !done[i]) -- continue; -- netdev_completed_queue(eth->netdev[i], done[i], bytes[i]); -- total += done[i]; -- eth->tx_packets += done[i]; -- eth->tx_bytes += bytes[i]; -- } -+ if (state.txq) -+ netdev_tx_completed_queue(state.txq, state.done, state.bytes); - - dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes, - &dim_sample); -@@ -2069,7 +2167,7 @@ static int mtk_poll_tx(struct mtk_eth *e - (atomic_read(&ring->free_count) > ring->thresh)) - mtk_wake_queue(eth); - -- return total; -+ return state.total; - } - - static void mtk_handle_status_irq(struct mtk_eth *eth) -@@ -2155,6 +2253,7 @@ static int mtk_tx_alloc(struct mtk_eth * - int i, sz = soc->txrx.txd_size; - struct mtk_tx_dma_v2 *txd; - int ring_size; -+ u32 ofs, val; - - if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) - ring_size = MTK_QDMA_RING_SIZE; -@@ -2222,8 +2321,25 @@ static int mtk_tx_alloc(struct mtk_eth * - ring->phys + ((ring_size - 1) * sz), - soc->reg_map->qdma.crx_ptr); - mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr); -- mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, -- soc->reg_map->qdma.qtx_cfg); -+ -+ for (i = 0, ofs = 0; i < MTK_QDMA_NUM_QUEUES; i++) { -+ val = (QDMA_RES_THRES << 8) | QDMA_RES_THRES; -+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_cfg + ofs); -+ -+ val = MTK_QTX_SCH_MIN_RATE_EN | -+ /* minimum: 10 Mbps */ -+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | -+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | -+ MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; -+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); -+ ofs += MTK_QTX_OFFSET; -+ } -+ val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16); -+ mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4); - } else { - mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); - mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0); -@@ -2906,7 +3022,7 @@ static int mtk_start_dma(struct mtk_eth - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) - val |= MTK_MUTLI_CNT | MTK_RESV_BUF | - MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | -- MTK_CHK_DDONE_EN; -+ MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; - else - val |= MTK_RX_BT_32DWORDS; - mtk_w32(eth, val, reg_map->qdma.glo_cfg); -@@ -2952,6 +3068,45 @@ static void mtk_gdm_config(struct mtk_et - mtk_w32(eth, 0, MTK_RST_GL); - } - -+static int mtk_device_event(struct notifier_block *n, unsigned long event, void *ptr) -+{ -+ struct mtk_mac *mac = container_of(n, struct mtk_mac, device_notifier); -+ struct mtk_eth *eth = mac->hw; -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ struct ethtool_link_ksettings s; -+ struct net_device *ldev; -+ struct list_head *iter; -+ struct dsa_port *dp; -+ -+ if (event != NETDEV_CHANGE) -+ return NOTIFY_DONE; -+ -+ netdev_for_each_lower_dev(dev, ldev, iter) { -+ if (netdev_priv(ldev) == mac) -+ goto found; -+ } -+ -+ return NOTIFY_DONE; -+ -+found: -+ if (!dsa_slave_dev_check(dev)) -+ return NOTIFY_DONE; -+ -+ if (__ethtool_get_link_ksettings(dev, &s)) -+ return NOTIFY_DONE; -+ -+ if (s.base.speed == 0 || s.base.speed == ((__u32)-1)) -+ return NOTIFY_DONE; -+ -+ dp = dsa_port_from_netdev(dev); -+ if (dp->index >= MTK_QDMA_NUM_QUEUES) -+ return NOTIFY_DONE; -+ -+ mtk_set_queue_speed(eth, dp->index + 3, s.base.speed); -+ -+ return NOTIFY_DONE; -+} -+ - static int mtk_open(struct net_device *dev) - { - struct mtk_mac *mac = netdev_priv(dev); -@@ -2996,7 +3151,8 @@ static int mtk_open(struct net_device *d - refcount_inc(ð->dma_refcnt); - - phylink_start(mac->phylink); -- netif_start_queue(dev); -+ netif_tx_start_all_queues(dev); -+ - return 0; - } - -@@ -3702,8 +3858,12 @@ static int mtk_unreg_dev(struct mtk_eth - int i; - - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ struct mtk_mac *mac; - if (!eth->netdev[i]) - continue; -+ mac = netdev_priv(eth->netdev[i]); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -+ unregister_netdevice_notifier(&mac->device_notifier); - unregister_netdev(eth->netdev[i]); - } - -@@ -3920,6 +4080,23 @@ static int mtk_set_rxnfc(struct net_devi - return ret; - } - -+static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb, -+ struct net_device *sb_dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ unsigned int queue = 0; -+ -+ if (netdev_uses_dsa(dev)) -+ queue = skb_get_queue_mapping(skb) + 3; -+ else -+ queue = mac->id; -+ -+ if (queue >= dev->num_tx_queues) -+ queue = 0; -+ -+ return queue; -+} -+ - static const struct ethtool_ops mtk_ethtool_ops = { - .get_link_ksettings = mtk_get_link_ksettings, - .set_link_ksettings = mtk_set_link_ksettings, -@@ -3954,6 +4131,7 @@ static const struct net_device_ops mtk_n - .ndo_setup_tc = mtk_eth_setup_tc, - .ndo_bpf = mtk_xdp, - .ndo_xdp_xmit = mtk_xdp_xmit, -+ .ndo_select_queue = mtk_select_queue, - }; - - static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) -@@ -3963,6 +4141,7 @@ static int mtk_add_mac(struct mtk_eth *e - struct phylink *phylink; - struct mtk_mac *mac; - int id, err; -+ int txqs = 1; - - if (!_id) { - dev_err(eth->dev, "missing mac id\n"); -@@ -3980,7 +4159,10 @@ static int mtk_add_mac(struct mtk_eth *e - return -EINVAL; - } - -- eth->netdev[id] = alloc_etherdev(sizeof(*mac)); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -+ txqs = MTK_QDMA_NUM_QUEUES; -+ -+ eth->netdev[id] = alloc_etherdev_mqs(sizeof(*mac), txqs, 1); - if (!eth->netdev[id]) { - dev_err(eth->dev, "alloc_etherdev failed\n"); - return -ENOMEM; -@@ -4088,6 +4270,11 @@ static int mtk_add_mac(struct mtk_eth *e - else - eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN; - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -+ mac->device_notifier.notifier_call = mtk_device_event; -+ register_netdevice_notifier(&mac->device_notifier); -+ } -+ - return 0; - - free_netdev: ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -22,6 +22,7 @@ - #include - #include "mtk_ppe.h" - -+#define MTK_QDMA_NUM_QUEUES 16 - #define MTK_QDMA_PAGE_SIZE 2048 - #define MTK_MAX_RX_LENGTH 1536 - #define MTK_MAX_RX_LENGTH_2K 2048 -@@ -215,8 +216,26 @@ - #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3) - - /* QDMA TX Queue Configuration Registers */ -+#define MTK_QTX_OFFSET 0x10 - #define QDMA_RES_THRES 4 - -+/* QDMA Tx Queue Scheduler Configuration Registers */ -+#define MTK_QTX_SCH_TX_SEL BIT(31) -+#define MTK_QTX_SCH_TX_SEL_V2 GENMASK(31, 30) -+ -+#define MTK_QTX_SCH_LEAKY_BUCKET_EN BIT(30) -+#define MTK_QTX_SCH_LEAKY_BUCKET_SIZE GENMASK(29, 28) -+#define MTK_QTX_SCH_MIN_RATE_EN BIT(27) -+#define MTK_QTX_SCH_MIN_RATE_MAN GENMASK(26, 20) -+#define MTK_QTX_SCH_MIN_RATE_EXP GENMASK(19, 16) -+#define MTK_QTX_SCH_MAX_RATE_WEIGHT GENMASK(15, 12) -+#define MTK_QTX_SCH_MAX_RATE_EN BIT(11) -+#define MTK_QTX_SCH_MAX_RATE_MAN GENMASK(10, 4) -+#define MTK_QTX_SCH_MAX_RATE_EXP GENMASK(3, 0) -+ -+/* QDMA TX Scheduler Rate Control Register */ -+#define MTK_QDMA_TX_SCH_MAX_WFQ BIT(15) -+ - /* QDMA Global Configuration Register */ - #define MTK_RX_2B_OFFSET BIT(31) - #define MTK_RX_BT_32DWORDS (3 << 11) -@@ -235,6 +254,7 @@ - #define MTK_WCOMP_EN BIT(24) - #define MTK_RESV_BUF (0x40 << 16) - #define MTK_MUTLI_CNT (0x4 << 12) -+#define MTK_LEAKY_BUCKET_EN BIT(11) - - /* QDMA Flow Control Register */ - #define FC_THRES_DROP_MODE BIT(20) -@@ -265,8 +285,6 @@ - #define MTK_STAT_OFFSET 0x40 - - /* QDMA TX NUM */ --#define MTK_QDMA_TX_NUM 16 --#define MTK_QDMA_TX_MASK (MTK_QDMA_TX_NUM - 1) - #define QID_BITS_V2(x) (((x) & 0x3f) << 16) - #define MTK_QDMA_GMAC2_QID 8 - -@@ -296,6 +314,7 @@ - #define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) - #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) - #define TX_DMA_SWC BIT(14) -+#define TX_DMA_PQID GENMASK(3, 0) - - /* PDMA on MT7628 */ - #define TX_DMA_DONE BIT(31) -@@ -953,6 +972,7 @@ struct mtk_reg_map { - } pdma; - struct { - u32 qtx_cfg; /* tx queue configuration */ -+ u32 qtx_sch; /* tx queue scheduler configuration */ - u32 rx_ptr; /* rx base pointer */ - u32 rx_cnt_cfg; /* rx max count configuration */ - u32 qcrx_ptr; /* rx cpu pointer */ -@@ -970,6 +990,7 @@ struct mtk_reg_map { - u32 fq_tail; /* fq tail pointer */ - u32 fq_count; /* fq free page count */ - u32 fq_blen; /* fq free page buffer length */ -+ u32 tx_sch_rate; /* tx scheduler rate control registers */ - } qdma; - u32 gdm1_cnt; - u32 gdma_to_ppe0; -@@ -1173,6 +1194,7 @@ struct mtk_mac { - __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; - int hwlro_ip_cnt; - unsigned int syscfg0; -+ struct notifier_block device_notifier; - }; - - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ diff --git a/target/linux/generic/backport-5.15/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch b/target/linux/generic/backport-5.15/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch deleted file mode 100644 index 186df4bdc924d4..00000000000000 --- a/target/linux/generic/backport-5.15/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Felix Fietkau -Date: Fri, 28 Oct 2022 18:16:03 +0200 -Subject: [PATCH] net: dsa: tag_mtk: assign per-port queues - -Keeps traffic sent to the switch within link speed limits - -Signed-off-by: Felix Fietkau ---- - ---- a/net/dsa/tag_mtk.c -+++ b/net/dsa/tag_mtk.c -@@ -25,6 +25,8 @@ static struct sk_buff *mtk_tag_xmit(stru - u8 xmit_tpid; - u8 *mtk_tag; - -+ skb_set_queue_mapping(skb, dp->index); -+ - /* 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 diff --git a/target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch b/target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch deleted file mode 100644 index e05042c2047d0d..00000000000000 --- a/target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch +++ /dev/null @@ -1,93 +0,0 @@ -From: Felix Fietkau -Date: Thu, 3 Nov 2022 17:49:44 +0100 -Subject: [PATCH] net: ethernet: mediatek: ppe: assign per-port queues - for offloaded traffic - -Keeps traffic sent to the switch within link speed limits - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -405,6 +405,24 @@ static inline bool mtk_foe_entry_usable( - FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1) != MTK_FOE_STATE_BIND; - } - -+int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ unsigned int queue) -+{ -+ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ *ib2 &= ~MTK_FOE_IB2_QID_V2; -+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue); -+ *ib2 |= MTK_FOE_IB2_PSE_QOS_V2; -+ } else { -+ *ib2 &= ~MTK_FOE_IB2_QID; -+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID, queue); -+ *ib2 |= MTK_FOE_IB2_PSE_QOS; -+ } -+ -+ return 0; -+} -+ - static bool - mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, - struct mtk_foe_entry *data) ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -68,7 +68,9 @@ enum { - #define MTK_FOE_IB2_DSCP GENMASK(31, 24) - - /* CONFIG_MEDIATEK_NETSYS_V2 */ -+#define MTK_FOE_IB2_QID_V2 GENMASK(6, 0) - #define MTK_FOE_IB2_PORT_MG_V2 BIT(7) -+#define MTK_FOE_IB2_PSE_QOS_V2 BIT(8) - #define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9) - #define MTK_FOE_IB2_MULTICAST_V2 BIT(13) - #define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19) -@@ -352,6 +354,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e - int sid); - int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, - int wdma_idx, int txq, int bss, int wcid); -+int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ unsigned int queue); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -188,7 +188,7 @@ mtk_flow_set_output_device(struct mtk_et - int *wed_index) - { - struct mtk_wdma_info info = {}; -- int pse_port, dsa_port; -+ int pse_port, dsa_port, queue; - - if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { - mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, -@@ -212,8 +212,6 @@ mtk_flow_set_output_device(struct mtk_et - } - - dsa_port = mtk_flow_get_dsa_port(&dev); -- if (dsa_port >= 0) -- mtk_foe_entry_set_dsa(eth, foe, dsa_port); - - if (dev == eth->netdev[0]) - pse_port = 1; -@@ -222,6 +220,14 @@ mtk_flow_set_output_device(struct mtk_et - else - return -EOPNOTSUPP; - -+ if (dsa_port >= 0) { -+ mtk_foe_entry_set_dsa(eth, foe, dsa_port); -+ queue = 3 + dsa_port; -+ } else { -+ queue = pse_port - 1; -+ } -+ mtk_foe_entry_set_queue(eth, foe, queue); -+ - out: - mtk_foe_entry_set_pse_port(eth, foe, pse_port); - diff --git a/target/linux/generic/backport-5.15/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch b/target/linux/generic/backport-5.15/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch deleted file mode 100644 index 0478cb528e2d1c..00000000000000 --- a/target/linux/generic/backport-5.15/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch +++ /dev/null @@ -1,72 +0,0 @@ -From: Felix Fietkau -Date: Tue, 8 Nov 2022 15:03:15 +0100 -Subject: [PATCH] net: dsa: add support for DSA rx offloading via - metadata dst - -If a metadata dst is present with the type METADATA_HW_PORT_MUX on a dsa cpu -port netdev, assume that it carries the port number and that there is no DSA -tag present in the skb data. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/core/flow_dissector.c -+++ b/net/core/flow_dissector.c -@@ -940,12 +940,14 @@ bool __skb_flow_dissect(const struct net - #if IS_ENABLED(CONFIG_NET_DSA) - if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) && - proto == htons(ETH_P_XDSA))) { -+ struct metadata_dst *md_dst = skb_metadata_dst(skb); - const struct dsa_device_ops *ops; - int offset = 0; - - ops = skb->dev->dsa_ptr->tag_ops; - /* Only DSA header taggers break flow dissection */ -- if (ops->needed_headroom) { -+ if (ops->needed_headroom && -+ (!md_dst || md_dst->type != METADATA_HW_PORT_MUX)) { - if (ops->flow_dissect) - ops->flow_dissect(skb, &proto, &offset); - else ---- a/net/dsa/dsa.c -+++ b/net/dsa/dsa.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - #include "dsa_priv.h" - -@@ -225,6 +226,7 @@ static bool dsa_skb_defer_rx_timestamp(s - static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *unused) - { -+ struct metadata_dst *md_dst = skb_metadata_dst(skb); - struct dsa_port *cpu_dp = dev->dsa_ptr; - struct sk_buff *nskb = NULL; - struct dsa_slave_priv *p; -@@ -238,7 +240,22 @@ static int dsa_switch_rcv(struct sk_buff - if (!skb) - return 0; - -- nskb = cpu_dp->rcv(skb, dev); -+ if (md_dst && md_dst->type == METADATA_HW_PORT_MUX) { -+ unsigned int port = md_dst->u.port_info.port_id; -+ -+ skb_dst_drop(skb); -+ if (!skb_has_extensions(skb)) -+ skb->slow_gro = 0; -+ -+ skb->dev = dsa_master_find_slave(dev, 0, port); -+ if (likely(skb->dev)) { -+ dsa_default_offload_fwd_mark(skb); -+ nskb = skb; -+ } -+ } else { -+ nskb = cpu_dp->rcv(skb, dev); -+ } -+ - if (!nskb) { - kfree_skb(skb); - return 0; diff --git a/target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch b/target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch deleted file mode 100644 index b64f434365f68b..00000000000000 --- a/target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch +++ /dev/null @@ -1,192 +0,0 @@ -From: Felix Fietkau -Date: Fri, 28 Oct 2022 11:01:12 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix VLAN rx hardware - acceleration - -- enable VLAN untagging for PDMA rx -- make it possible to disable the feature via ethtool -- pass VLAN tag to the DSA driver -- untag special tag on PDMA only if no non-DSA devices are in use -- disable special tag untagging on 7986 for now, since it's not working yet - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include "mtk_eth_soc.h" - #include "mtk_wed.h" -@@ -1973,16 +1974,22 @@ static int mtk_poll_rx(struct napi_struc - htons(RX_DMA_VPID(trxd.rxd4)), - RX_DMA_VID(trxd.rxd4)); - } else if (trxd.rxd2 & RX_DMA_VTAG) { -- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), -+ __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)), - RX_DMA_VID(trxd.rxd3)); - } -+ } -+ -+ /* When using VLAN untagging in combination with DSA, the -+ * hardware treats the MTK special tag as a VLAN and untags it. -+ */ -+ if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) { -+ unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0); - -- /* If the device is attached to a dsa switch, the special -- * tag inserted in VLAN field by hw switch can * be offloaded -- * by RX HW VLAN offload. Clear vlan info. -- */ -- if (netdev_uses_dsa(netdev)) -- __vlan_hwaccel_clear_tag(skb); -+ if (port < ARRAY_SIZE(eth->dsa_meta) && -+ eth->dsa_meta[port]) -+ skb_dst_set_noref(skb, ð->dsa_meta[port]->dst); -+ -+ __vlan_hwaccel_clear_tag(skb); - } - - skb_record_rx_queue(skb, 0); -@@ -2802,15 +2809,30 @@ static netdev_features_t mtk_fix_feature - - static int mtk_set_features(struct net_device *dev, netdev_features_t features) - { -- int err = 0; -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ netdev_features_t diff = dev->features ^ features; -+ int i; -+ -+ if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO)) -+ mtk_hwlro_netdev_disable(dev); - -- if (!((dev->features ^ features) & NETIF_F_LRO)) -+ /* Set RX VLAN offloading */ -+ if (!(diff & NETIF_F_HW_VLAN_CTAG_RX)) - return 0; - -- if (!(features & NETIF_F_LRO)) -- mtk_hwlro_netdev_disable(dev); -+ mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX), -+ MTK_CDMP_EG_CTRL); - -- return err; -+ /* sync features with other MAC */ -+ for (i = 0; i < MTK_MAC_COUNT; i++) { -+ if (!eth->netdev[i] || eth->netdev[i] == dev) -+ continue; -+ eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX; -+ eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX; -+ } -+ -+ return 0; - } - - /* wait for DMA to finish whatever it is doing before we start using it again */ -@@ -3107,11 +3129,45 @@ found: - return NOTIFY_DONE; - } - -+static bool mtk_uses_dsa(struct net_device *dev) -+{ -+#if IS_ENABLED(CONFIG_NET_DSA) -+ return netdev_uses_dsa(dev) && -+ dev->dsa_ptr->tag_ops->proto == DSA_TAG_PROTO_MTK; -+#else -+ return false; -+#endif -+} -+ - static int mtk_open(struct net_device *dev) - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; -- int err; -+ int i, err; -+ -+ if (mtk_uses_dsa(dev) && !eth->prog) { -+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { -+ struct metadata_dst *md_dst = eth->dsa_meta[i]; -+ -+ if (md_dst) -+ continue; -+ -+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, -+ GFP_KERNEL); -+ if (!md_dst) -+ return -ENOMEM; -+ -+ md_dst->u.port_info.port_id = i; -+ eth->dsa_meta[i] = md_dst; -+ } -+ } else { -+ /* Hardware special tag parsing needs to be disabled if at least -+ * one MAC does not use DSA. -+ */ -+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); -+ val &= ~MTK_CDMP_STAG_EN; -+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL); -+ } - - err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); - if (err) { -@@ -3634,6 +3690,10 @@ static int mtk_hw_init(struct mtk_eth *e - */ - val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); - mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ val = mtk_r32(eth, MTK_CDMP_IG_CTRL); -+ mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); -+ } - - /* Enable RX VLan Offloading */ - mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -@@ -3850,6 +3910,12 @@ static int mtk_free_dev(struct mtk_eth * - free_netdev(eth->netdev[i]); - } - -+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { -+ if (!eth->dsa_meta[i]) -+ break; -+ metadata_dst_free(eth->dsa_meta[i]); -+ } -+ - return 0; - } - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -22,6 +22,9 @@ - #include - #include "mtk_ppe.h" - -+#define MTK_MAX_DSA_PORTS 7 -+#define MTK_DSA_PORT_MASK GENMASK(2, 0) -+ - #define MTK_QDMA_NUM_QUEUES 16 - #define MTK_QDMA_PAGE_SIZE 2048 - #define MTK_MAX_RX_LENGTH 1536 -@@ -105,6 +108,9 @@ - #define MTK_CDMQ_IG_CTRL 0x1400 - #define MTK_CDMQ_STAG_EN BIT(0) - -+/* CDMQ Exgress Control Register */ -+#define MTK_CDMQ_EG_CTRL 0x1404 -+ - /* CDMP Ingress Control Register */ - #define MTK_CDMP_IG_CTRL 0x400 - #define MTK_CDMP_STAG_EN BIT(0) -@@ -1160,6 +1166,8 @@ struct mtk_eth { - - int ip_align; - -+ struct metadata_dst *dsa_meta[MTK_MAX_DSA_PORTS]; -+ - struct mtk_ppe *ppe[2]; - struct rhashtable flow_table; - diff --git a/target/linux/generic/backport-5.15/730-10-v6.3-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch b/target/linux/generic/backport-5.15/730-10-v6.3-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch deleted file mode 100644 index b8c786505f419a..00000000000000 --- a/target/linux/generic/backport-5.15/730-10-v6.3-net-ethernet-mtk_eth_soc-drop-packets-to-WDMA-if-the.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Felix Fietkau -Date: Thu, 3 Nov 2022 17:46:25 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: drop packets to WDMA if the - ring is full - -Improves handling of DMA ring overflow. -Clarify other WDMA drop related comment. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3714,9 +3714,12 @@ static int mtk_hw_init(struct mtk_eth *e - mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -- /* PSE should not drop port8 and port9 packets */ -+ /* PSE should not drop port8 and port9 packets from WDMA Tx */ - mtk_w32(eth, 0x00000300, PSE_DROP_CFG); - -+ /* PSE should drop packets to port 8/9 on WDMA Rx ring full */ -+ mtk_w32(eth, 0x00000300, PSE_PPE0_DROP); -+ - /* PSE Free Queue Flow Control */ - mtk_w32(eth, 0x01fa01f4, PSE_FQFC_CFG2); - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -140,6 +140,7 @@ - #define PSE_FQFC_CFG1 0x100 - #define PSE_FQFC_CFG2 0x104 - #define PSE_DROP_CFG 0x108 -+#define PSE_PPE0_DROP 0x110 - - /* PSE Input Queue Reservation Register*/ - #define PSE_IQ_REV(x) (0x140 + (((x) - 1) << 2)) diff --git a/target/linux/generic/backport-5.15/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch b/target/linux/generic/backport-5.15/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch deleted file mode 100644 index 346db89911ec12..00000000000000 --- a/target/linux/generic/backport-5.15/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Sat, 28 Jan 2023 12:42:32 +0300 -Subject: [PATCH] net: ethernet: mtk_eth_soc: disable hardware DSA untagging - for second MAC -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -According to my tests on MT7621AT and MT7623NI SoCs, hardware DSA untagging -won't work on the second MAC. Therefore, disable this feature when the -second MAC of the MT7621 and MT7623 SoCs is being used. - -Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging") -Link: https://lore.kernel.org/netdev/6249fc14-b38a-c770-36b4-5af6d41c21d3@arinc9.com/ -Tested-by: Arınç ÜNAL -Signed-off-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/20230128094232.2451947-1-arinc.unal@arinc9.com -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3145,7 +3145,8 @@ static int mtk_open(struct net_device *d - struct mtk_eth *eth = mac->hw; - int i, err; - -- if (mtk_uses_dsa(dev) && !eth->prog) { -+ if ((mtk_uses_dsa(dev) && !eth->prog) && -+ !(mac->id == 1 && MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC1_TRGMII))) { - for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { - struct metadata_dst *md_dst = eth->dsa_meta[i]; - -@@ -3162,7 +3163,8 @@ static int mtk_open(struct net_device *d - } - } else { - /* Hardware special tag parsing needs to be disabled if at least -- * one MAC does not use DSA. -+ * one MAC does not use DSA, or the second MAC of the MT7621 and -+ * MT7623 SoCs is being used. - */ - u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - val &= ~MTK_CDMP_STAG_EN; diff --git a/target/linux/generic/backport-5.15/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch b/target/linux/generic/backport-5.15/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch deleted file mode 100644 index ec5dc49f5e5fac..00000000000000 --- a/target/linux/generic/backport-5.15/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch +++ /dev/null @@ -1,54 +0,0 @@ -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Sun, 5 Feb 2023 20:53:31 +0300 -Subject: [PATCH] net: ethernet: mtk_eth_soc: enable special tag when any MAC - uses DSA -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The special tag is only enabled when the first MAC uses DSA. However, it -must be enabled when any MAC uses DSA. Change the check accordingly. - -This fixes hardware DSA untagging not working on the second MAC of the -MT7621 and MT7623 SoCs, and likely other SoCs too. Therefore, remove the -check that disables hardware DSA untagging for the second MAC of the MT7621 -and MT7623 SoCs. - -Fixes: a1f47752fd62 ("net: ethernet: mtk_eth_soc: disable hardware DSA untagging for second MAC") -Co-developed-by: Richard van Schagen -Signed-off-by: Richard van Schagen -Signed-off-by: Arınç ÜNAL -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3080,7 +3080,7 @@ static void mtk_gdm_config(struct mtk_et - - val |= config; - -- if (!i && eth->netdev[0] && netdev_uses_dsa(eth->netdev[0])) -+ if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i])) - val |= MTK_GDMA_SPECIAL_TAG; - - mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); -@@ -3145,8 +3145,7 @@ static int mtk_open(struct net_device *d - struct mtk_eth *eth = mac->hw; - int i, err; - -- if ((mtk_uses_dsa(dev) && !eth->prog) && -- !(mac->id == 1 && MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC1_TRGMII))) { -+ if (mtk_uses_dsa(dev) && !eth->prog) { - for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { - struct metadata_dst *md_dst = eth->dsa_meta[i]; - -@@ -3163,8 +3162,7 @@ static int mtk_open(struct net_device *d - } - } else { - /* Hardware special tag parsing needs to be disabled if at least -- * one MAC does not use DSA, or the second MAC of the MT7621 and -- * MT7623 SoCs is being used. -+ * one MAC does not use DSA. - */ - u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - val &= ~MTK_CDMP_STAG_EN; diff --git a/target/linux/generic/backport-5.15/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch b/target/linux/generic/backport-5.15/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch deleted file mode 100644 index e75459696b6c95..00000000000000 --- a/target/linux/generic/backport-5.15/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch +++ /dev/null @@ -1,129 +0,0 @@ -From: Vladimir Oltean -Date: Tue, 7 Feb 2023 12:30:27 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix DSA TX tag hwaccel for switch - port 0 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Arınç reports that on his MT7621AT Unielec U7621-06 board and MT7623NI -Bananapi BPI-R2, packets received by the CPU over mt7530 switch port 0 -(of which this driver acts as the DSA master) are not processed -correctly by software. More precisely, they arrive without a DSA tag -(in packet or in the hwaccel area - skb_metadata_dst()), so DSA cannot -demux them towards the switch's interface for port 0. Traffic from other -ports receives a skb_metadata_dst() with the correct port and is demuxed -properly. - -Looking at mtk_poll_rx(), it becomes apparent that this driver uses the -skb vlan hwaccel area: - - union { - u32 vlan_all; - struct { - __be16 vlan_proto; - __u16 vlan_tci; - }; - }; - -as a temporary storage for the VLAN hwaccel tag, or the DSA hwaccel tag. -If this is a DSA master it's a DSA hwaccel tag, and finally clears up -the skb VLAN hwaccel header. - -I'm guessing that the problem is the (mis)use of API. -skb_vlan_tag_present() looks like this: - - #define skb_vlan_tag_present(__skb) (!!(__skb)->vlan_all) - -So if both vlan_proto and vlan_tci are zeroes, skb_vlan_tag_present() -returns precisely false. I don't know for sure what is the format of the -DSA hwaccel tag, but I surely know that lowermost 3 bits of vlan_proto -are 0 when receiving from port 0: - - unsigned int port = vlan_proto & GENMASK(2, 0); - -If the RX descriptor has no other bits set to non-zero values in -RX_DMA_VTAG, then the call to __vlan_hwaccel_put_tag() will not, in -fact, make the subsequent skb_vlan_tag_present() return true, because -it's implemented like this: - -static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb, - __be16 vlan_proto, u16 vlan_tci) -{ - skb->vlan_proto = vlan_proto; - skb->vlan_tci = vlan_tci; -} - -What we need to do to fix this problem (assuming this is the problem) is -to stop using skb->vlan_all as temporary storage for driver affairs, and -just create some local variables that serve the same purpose, but -hopefully better. Instead of calling skb_vlan_tag_present(), let's look -at a boolean has_hwaccel_tag which we set to true when the RX DMA -descriptors have something. Disambiguate based on netdev_uses_dsa() -whether this is a VLAN or DSA hwaccel tag, and only call -__vlan_hwaccel_put_tag() if we're certain it's a VLAN tag. - -Arınç confirms that the treatment works, so this validates the -assumption. - -Link: https://lore.kernel.org/netdev/704f3a72-fc9e-714a-db54-272e17612637@arinc9.com/ -Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging") -Reported-by: Arınç ÜNAL -Tested-by: Arınç ÜNAL -Signed-off-by: Vladimir Oltean -Reviewed-by: Felix Fietkau -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1829,7 +1829,9 @@ static int mtk_poll_rx(struct napi_struc - - while (done < budget) { - unsigned int pktlen, *rxdcsum; -+ bool has_hwaccel_tag = false; - struct net_device *netdev; -+ u16 vlan_proto, vlan_tci; - dma_addr_t dma_addr; - u32 hash, reason; - int mac = 0; -@@ -1969,27 +1971,29 @@ static int mtk_poll_rx(struct napi_struc - - if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -- if (trxd.rxd3 & RX_DMA_VTAG_V2) -- __vlan_hwaccel_put_tag(skb, -- htons(RX_DMA_VPID(trxd.rxd4)), -- RX_DMA_VID(trxd.rxd4)); -+ if (trxd.rxd3 & RX_DMA_VTAG_V2) { -+ vlan_proto = RX_DMA_VPID(trxd.rxd4); -+ vlan_tci = RX_DMA_VID(trxd.rxd4); -+ has_hwaccel_tag = true; -+ } - } else if (trxd.rxd2 & RX_DMA_VTAG) { -- __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)), -- RX_DMA_VID(trxd.rxd3)); -+ vlan_proto = RX_DMA_VPID(trxd.rxd3); -+ vlan_tci = RX_DMA_VID(trxd.rxd3); -+ has_hwaccel_tag = true; - } - } - - /* When using VLAN untagging in combination with DSA, the - * hardware treats the MTK special tag as a VLAN and untags it. - */ -- if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) { -- unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0); -+ if (has_hwaccel_tag && netdev_uses_dsa(netdev)) { -+ unsigned int port = vlan_proto & GENMASK(2, 0); - - if (port < ARRAY_SIZE(eth->dsa_meta) && - eth->dsa_meta[port]) - skb_dst_set_noref(skb, ð->dsa_meta[port]->dst); -- -- __vlan_hwaccel_clear_tag(skb); -+ } else if (has_hwaccel_tag) { -+ __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci); - } - - skb_record_rx_queue(skb, 0); diff --git a/target/linux/generic/backport-5.15/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch b/target/linux/generic/backport-5.15/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch deleted file mode 100644 index a3bb1c5db77ed1..00000000000000 --- a/target/linux/generic/backport-5.15/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Christophe JAILLET -Date: Sun, 12 Feb 2023 07:51:51 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: No need to clear memory after a - dma_alloc_coherent() call - -dma_alloc_coherent() already clears the allocated memory, there is no need -to explicitly call memset(). - -Moreover, it is likely that the size in the memset() is incorrect and -should be "size * sizeof(*ring->desc)". - -Signed-off-by: Christophe JAILLET -Link: https://lore.kernel.org/r/d5acce7dd108887832c9719f62c7201b4c83b3fb.1676184599.git.christophe.jaillet@wanadoo.fr -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -779,7 +779,6 @@ mtk_wed_rro_ring_alloc(struct mtk_wed_de - - ring->desc_size = sizeof(*ring->desc); - ring->size = size; -- memset(ring->desc, 0, size); - - return 0; - } diff --git a/target/linux/generic/backport-5.15/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch b/target/linux/generic/backport-5.15/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch deleted file mode 100644 index e043a681da40f6..00000000000000 --- a/target/linux/generic/backport-5.15/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch +++ /dev/null @@ -1,61 +0,0 @@ -From: Lorenzo Bianconi -Date: Wed, 7 Dec 2022 15:04:54 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: fix some possible NULL pointer - dereferences - -Fix possible NULL pointer dereference in mtk_wed_detach routine checking -wo pointer is properly allocated before running mtk_wed_wo_reset() and -mtk_wed_wo_deinit(). -Even if it is just a theoretical issue at the moment check wo pointer is -not NULL in mtk_wed_mcu_msg_update. -Moreover, honor mtk_wed_mcu_send_msg return value in mtk_wed_wo_reset() - -Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support") -Fixes: 4c5de09eb0d0 ("net: ethernet: mtk_wed: add configure wed wo support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Leon Romanovsky -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -174,9 +174,10 @@ mtk_wed_wo_reset(struct mtk_wed_device * - mtk_wdma_tx_reset(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); - -- mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -- MTK_WED_WO_CMD_CHANGE_STATE, &state, -- sizeof(state), false); -+ if (mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -+ MTK_WED_WO_CMD_CHANGE_STATE, &state, -+ sizeof(state), false)) -+ return; - - if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val, - val == MTK_WED_WOIF_DISABLE_DONE, -@@ -632,9 +633,11 @@ mtk_wed_detach(struct mtk_wed_device *de - mtk_wed_free_tx_rings(dev); - - if (mtk_wed_get_rx_capa(dev)) { -- mtk_wed_wo_reset(dev); -+ if (hw->wed_wo) -+ mtk_wed_wo_reset(dev); - mtk_wed_free_rx_rings(dev); -- mtk_wed_wo_deinit(hw); -+ if (hw->wed_wo) -+ mtk_wed_wo_deinit(hw); - } - - if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -207,6 +207,9 @@ int mtk_wed_mcu_msg_update(struct mtk_we - if (dev->hw->version == 1) - return 0; - -+ if (WARN_ON(!wo)) -+ return -ENODEV; -+ - return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len, - true); - } diff --git a/target/linux/generic/backport-5.15/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch b/target/linux/generic/backport-5.15/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch deleted file mode 100644 index 0afe7106e5478b..00000000000000 --- a/target/linux/generic/backport-5.15/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Lorenzo Bianconi -Date: Wed, 7 Dec 2022 15:04:55 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: fix possible deadlock if - mtk_wed_wo_init fails - -Introduce __mtk_wed_detach() in order to avoid a deadlock in -mtk_wed_attach routine if mtk_wed_wo_init fails since both -mtk_wed_attach and mtk_wed_detach run holding hw_lock mutex. - -Fixes: 4c5de09eb0d0 ("net: ethernet: mtk_wed: add configure wed wo support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Leon Romanovsky -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -619,12 +619,10 @@ mtk_wed_deinit(struct mtk_wed_device *de - } - - static void --mtk_wed_detach(struct mtk_wed_device *dev) -+__mtk_wed_detach(struct mtk_wed_device *dev) - { - struct mtk_wed_hw *hw = dev->hw; - -- mutex_lock(&hw_lock); -- - mtk_wed_deinit(dev); - - mtk_wdma_rx_reset(dev); -@@ -657,6 +655,13 @@ mtk_wed_detach(struct mtk_wed_device *de - module_put(THIS_MODULE); - - hw->wed_dev = NULL; -+} -+ -+static void -+mtk_wed_detach(struct mtk_wed_device *dev) -+{ -+ mutex_lock(&hw_lock); -+ __mtk_wed_detach(dev); - mutex_unlock(&hw_lock); - } - -@@ -1538,8 +1543,10 @@ mtk_wed_attach(struct mtk_wed_device *de - ret = mtk_wed_wo_init(hw); - } - out: -- if (ret) -- mtk_wed_detach(dev); -+ if (ret) { -+ dev_err(dev->hw->dev, "failed to attach wed device\n"); -+ __mtk_wed_detach(dev); -+ } - unlock: - mutex_unlock(&hw_lock); - diff --git a/target/linux/generic/backport-5.15/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch b/target/linux/generic/backport-5.15/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch deleted file mode 100644 index 4ba492014a5f56..00000000000000 --- a/target/linux/generic/backport-5.15/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Felix Fietkau -Date: Fri, 24 Mar 2023 14:56:58 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix tx throughput regression with - direct 1G links - -Using the QDMA tx scheduler to throttle tx to line speed works fine for -switch ports, but apparently caused a regression on non-switch ports. - -Based on a number of tests, it seems that this throttling can be safely -dropped without re-introducing the issues on switch ports that the -tx scheduling changes resolved. - -Link: https://lore.kernel.org/netdev/trinity-92c3826f-c2c8-40af-8339-bc6d0d3ffea4-1678213958520@3c-app-gmx-bs16/ -Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues") -Reported-by: Frank Wunderlich -Reported-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -675,8 +675,6 @@ static void mtk_mac_link_up(struct phyli - break; - } - -- mtk_set_queue_speed(mac->hw, mac->id, speed); -- - /* Configure duplex */ - if (duplex == DUPLEX_FULL) - mcr |= MAC_MCR_FORCE_DPX; diff --git a/target/linux/generic/backport-5.15/731-v6.1-0001-net-phy-Introduce-QUSGMII-PHY-mode.patch b/target/linux/generic/backport-5.15/731-v6.1-0001-net-phy-Introduce-QUSGMII-PHY-mode.patch deleted file mode 100644 index 40b14fc36ae3c7..00000000000000 --- a/target/linux/generic/backport-5.15/731-v6.1-0001-net-phy-Introduce-QUSGMII-PHY-mode.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 5e61fe157a27afc7c0d4f7bcbceefdca536c015f Mon Sep 17 00:00:00 2001 -From: Maxime Chevallier -Date: Wed, 17 Aug 2022 14:32:52 +0200 -Subject: [PATCH] net: phy: Introduce QUSGMII PHY mode - -The QUSGMII mode is a derivative of Cisco's USXGMII standard. This -standard is pretty similar to SGMII, but allows for faster speeds, and -has the build-in bits for Quad and Octa variants (like QSGMII). - -The main difference with SGMII/QSGMII is that USXGMII/QUSGMII re-uses -the preamble to carry various information, named 'Extensions'. - -As of today, the USXGMII standard only mentions the "PCH" extension, -which is used to convey timestamps, allowing in-band signaling of PTP -timestamps without having to modify the frame itself. - -This commit adds support for that mode. When no extension is in use, it -behaves exactly like QSGMII, although it's not compatible with QSGMII. - -Signed-off-by: Maxime Chevallier -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - Documentation/networking/phy.rst | 9 +++++++++ - drivers/net/phy/phylink.c | 3 +++ - include/linux/phy.h | 4 ++++ - 3 files changed, 16 insertions(+) - ---- a/Documentation/networking/phy.rst -+++ b/Documentation/networking/phy.rst -@@ -303,6 +303,15 @@ Some of the interface modes are describe - rate of 125Mpbs using a 4B/5B encoding scheme, resulting in an underlying - data rate of 100Mpbs. - -+``PHY_INTERFACE_MODE_QUSGMII`` -+ This defines the Cisco the Quad USGMII mode, which is the Quad variant of -+ the USGMII (Universal SGMII) link. It's very similar to QSGMII, but uses -+ a Packet Control Header (PCH) instead of the 7 bytes preamble to carry not -+ only the port id, but also so-called "extensions". The only documented -+ extension so-far in the specification is the inclusion of timestamps, for -+ PTP-enabled PHYs. This mode isn't compatible with QSGMII, but offers the -+ same capabilities in terms of link speed and negociation. -+ - Pause frames / flow control - =========================== - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -367,6 +367,7 @@ void phylink_get_linkmodes(unsigned long - case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII: - case PHY_INTERFACE_MODE_QSGMII: -+ case PHY_INTERFACE_MODE_QUSGMII: - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_GMII: - caps |= MAC_1000HD | MAC_1000FD; -@@ -630,6 +631,7 @@ static int phylink_parse_mode(struct phy - switch (pl->link_config.interface) { - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_QSGMII: -+ case PHY_INTERFACE_MODE_QUSGMII: - phylink_set(pl->supported, 10baseT_Half); - phylink_set(pl->supported, 10baseT_Full); - phylink_set(pl->supported, 100baseT_Half); -@@ -2956,6 +2958,7 @@ void phylink_mii_c22_pcs_get_state(struc - - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_QSGMII: -+ case PHY_INTERFACE_MODE_QUSGMII: - phylink_decode_sgmii_word(state, lpa); - break; - ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -115,6 +115,7 @@ extern const int phy_10gbit_features_arr - * @PHY_INTERFACE_MODE_25GBASER: 25G BaseR - * @PHY_INTERFACE_MODE_USXGMII: Universal Serial 10GE MII - * @PHY_INTERFACE_MODE_10GKR: 10GBASE-KR - with Clause 73 AN -+ * @PHY_INTERFACE_MODE_QUSGMII: Quad Universal SGMII - * @PHY_INTERFACE_MODE_MAX: Book keeping - * - * Describes the interface between the MAC and PHY. -@@ -152,6 +153,7 @@ typedef enum { - PHY_INTERFACE_MODE_USXGMII, - /* 10GBASE-KR - with Clause 73 AN */ - PHY_INTERFACE_MODE_10GKR, -+ PHY_INTERFACE_MODE_QUSGMII, - PHY_INTERFACE_MODE_MAX, - } phy_interface_t; - -@@ -267,6 +269,8 @@ static inline const char *phy_modes(phy_ - return "10gbase-kr"; - case PHY_INTERFACE_MODE_100BASEX: - return "100base-x"; -+ case PHY_INTERFACE_MODE_QUSGMII: -+ return "qusgmii"; - default: - return "unknown"; - } diff --git a/target/linux/generic/backport-5.15/731-v6.1-0002-net-phy-Add-helper-to-derive-the-number-of-ports-fro.patch b/target/linux/generic/backport-5.15/731-v6.1-0002-net-phy-Add-helper-to-derive-the-number-of-ports-fro.patch deleted file mode 100644 index a9706af8937466..00000000000000 --- a/target/linux/generic/backport-5.15/731-v6.1-0002-net-phy-Add-helper-to-derive-the-number-of-ports-fro.patch +++ /dev/null @@ -1,93 +0,0 @@ -From c04ade27cb7b952b6b9b9a0efa0a6129cc63f2ae Mon Sep 17 00:00:00 2001 -From: Maxime Chevallier -Date: Wed, 17 Aug 2022 14:32:54 +0200 -Subject: [PATCH] net: phy: Add helper to derive the number of ports from a phy - mode - -Some phy modes such as QSGMII multiplex several MAC<->PHY links on one -single physical interface. QSGMII used to be the only one supported, but -other modes such as QUSGMII also carry multiple links. - -This helper allows getting the number of links that are multiplexed -on a given interface. - -Signed-off-by: Maxime Chevallier -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/phy-core.c | 52 ++++++++++++++++++++++++++++++++++++++ - include/linux/phy.h | 2 ++ - 2 files changed, 54 insertions(+) - ---- a/drivers/net/phy/phy-core.c -+++ b/drivers/net/phy/phy-core.c -@@ -74,6 +74,58 @@ const char *phy_duplex_to_str(unsigned i - } - EXPORT_SYMBOL_GPL(phy_duplex_to_str); - -+/** -+ * phy_interface_num_ports - Return the number of links that can be carried by -+ * a given MAC-PHY physical link. Returns 0 if this is -+ * unknown, the number of links else. -+ * -+ * @interface: The interface mode we want to get the number of ports -+ */ -+int phy_interface_num_ports(phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_NA: -+ return 0; -+ case PHY_INTERFACE_MODE_INTERNAL: -+ case PHY_INTERFACE_MODE_MII: -+ case PHY_INTERFACE_MODE_GMII: -+ case PHY_INTERFACE_MODE_TBI: -+ case PHY_INTERFACE_MODE_REVMII: -+ case PHY_INTERFACE_MODE_RMII: -+ case PHY_INTERFACE_MODE_REVRMII: -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ case PHY_INTERFACE_MODE_RTBI: -+ case PHY_INTERFACE_MODE_XGMII: -+ case PHY_INTERFACE_MODE_XLGMII: -+ case PHY_INTERFACE_MODE_MOCA: -+ case PHY_INTERFACE_MODE_TRGMII: -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_SMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ case PHY_INTERFACE_MODE_5GBASER: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_25GBASER: -+ case PHY_INTERFACE_MODE_10GKR: -+ case PHY_INTERFACE_MODE_100BASEX: -+ case PHY_INTERFACE_MODE_RXAUI: -+ case PHY_INTERFACE_MODE_XAUI: -+ return 1; -+ case PHY_INTERFACE_MODE_QSGMII: -+ case PHY_INTERFACE_MODE_QUSGMII: -+ return 4; -+ case PHY_INTERFACE_MODE_MAX: -+ WARN_ONCE(1, "PHY_INTERFACE_MODE_MAX isn't a valid interface mode"); -+ return 0; -+ } -+ return 0; -+} -+EXPORT_SYMBOL_GPL(phy_interface_num_ports); -+ - /* A mapping of all SUPPORTED settings to speed/duplex. This table - * must be grouped by speed and sorted in descending match priority - * - iow, descending speed. ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -964,6 +964,8 @@ struct phy_fixup { - const char *phy_speed_to_str(int speed); - const char *phy_duplex_to_str(unsigned int duplex); - -+int phy_interface_num_ports(phy_interface_t interface); -+ - /* A structure for mapping a particular speed and duplex - * combination to a particular SUPPORTED and ADVERTISED value - */ diff --git a/target/linux/generic/backport-5.15/731-v6.1-0003-net-phy-Add-1000BASE-KX-interface-mode.patch b/target/linux/generic/backport-5.15/731-v6.1-0003-net-phy-Add-1000BASE-KX-interface-mode.patch deleted file mode 100644 index 70669dde3a37c9..00000000000000 --- a/target/linux/generic/backport-5.15/731-v6.1-0003-net-phy-Add-1000BASE-KX-interface-mode.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 05ad5d4581c3c1cc724fe50d4652833fb9f3037b Mon Sep 17 00:00:00 2001 -From: Sean Anderson -Date: Fri, 2 Sep 2022 18:02:39 -0400 -Subject: [PATCH] net: phy: Add 1000BASE-KX interface mode - -Add 1000BASE-KX interface mode. This 1G backplane ethernet as described in -clause 70. Clause 73 autonegotiation is mandatory, and only full duplex -operation is supported. - -Although at the PMA level this interface mode is identical to -1000BASE-X, it uses a different form of in-band autonegation. This -justifies a separate interface mode, since the interface mode (along -with the MLO_AN_* autonegotiation mode) sets the type of autonegotiation -which will be used on a link. This results in more than just electrical -differences between the link modes. - -With regard to 1000BASE-X, 1000BASE-KX holds a similar position to -SGMII: same signaling, but different autonegotiation. PCS drivers -(which typically handle in-band autonegotiation) may only support -1000BASE-X, and not 1000BASE-KX. Similarly, the phy mode is used to -configure serdes phys with phy_set_mode_ext. Due to the different -electrical standards (SFI or XFI vs Clause 70), they will likely want to -use different configuration. Adding a phy interface mode for -1000BASE-KX helps simplify configuration in these areas. - -Signed-off-by: Sean Anderson -Signed-off-by: David S. Miller ---- - Documentation/networking/phy.rst | 6 ++++++ - drivers/net/phy/phy-core.c | 1 + - drivers/net/phy/phylink.c | 1 + - include/linux/phy.h | 4 ++++ - 4 files changed, 12 insertions(+) - ---- a/Documentation/networking/phy.rst -+++ b/Documentation/networking/phy.rst -@@ -312,6 +312,12 @@ Some of the interface modes are describe - PTP-enabled PHYs. This mode isn't compatible with QSGMII, but offers the - same capabilities in terms of link speed and negociation. - -+``PHY_INTERFACE_MODE_1000BASEKX`` -+ This is 1000BASE-X as defined by IEEE 802.3 Clause 36 with Clause 73 -+ autonegotiation. Generally, it will be used with a Clause 70 PMD. To -+ contrast with the 1000BASE-X phy mode used for Clause 38 and 39 PMDs, this -+ interface mode has different autonegotiation and only supports full duplex. -+ - Pause frames / flow control - =========================== - ---- a/drivers/net/phy/phy-core.c -+++ b/drivers/net/phy/phy-core.c -@@ -114,6 +114,7 @@ int phy_interface_num_ports(phy_interfac - case PHY_INTERFACE_MODE_100BASEX: - case PHY_INTERFACE_MODE_RXAUI: - case PHY_INTERFACE_MODE_XAUI: -+ case PHY_INTERFACE_MODE_1000BASEKX: - return 1; - case PHY_INTERFACE_MODE_QSGMII: - case PHY_INTERFACE_MODE_QUSGMII: ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -390,6 +390,7 @@ void phylink_get_linkmodes(unsigned long - case PHY_INTERFACE_MODE_1000BASEX: - caps |= MAC_1000HD; - fallthrough; -+ case PHY_INTERFACE_MODE_1000BASEKX: - case PHY_INTERFACE_MODE_TRGMII: - caps |= MAC_1000FD; - break; ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -116,6 +116,7 @@ extern const int phy_10gbit_features_arr - * @PHY_INTERFACE_MODE_USXGMII: Universal Serial 10GE MII - * @PHY_INTERFACE_MODE_10GKR: 10GBASE-KR - with Clause 73 AN - * @PHY_INTERFACE_MODE_QUSGMII: Quad Universal SGMII -+ * @PHY_INTERFACE_MODE_1000BASEKX: 1000Base-KX - with Clause 73 AN - * @PHY_INTERFACE_MODE_MAX: Book keeping - * - * Describes the interface between the MAC and PHY. -@@ -154,6 +155,7 @@ typedef enum { - /* 10GBASE-KR - with Clause 73 AN */ - PHY_INTERFACE_MODE_10GKR, - PHY_INTERFACE_MODE_QUSGMII, -+ PHY_INTERFACE_MODE_1000BASEKX, - PHY_INTERFACE_MODE_MAX, - } phy_interface_t; - -@@ -251,6 +253,8 @@ static inline const char *phy_modes(phy_ - return "trgmii"; - case PHY_INTERFACE_MODE_1000BASEX: - return "1000base-x"; -+ case PHY_INTERFACE_MODE_1000BASEKX: -+ return "1000base-kx"; - case PHY_INTERFACE_MODE_2500BASEX: - return "2500base-x"; - case PHY_INTERFACE_MODE_5GBASER: diff --git a/target/linux/generic/backport-5.15/731-v6.1-0004-net-phy-Add-support-for-rate-matching.patch b/target/linux/generic/backport-5.15/731-v6.1-0004-net-phy-Add-support-for-rate-matching.patch deleted file mode 100644 index fc02d7a4eab595..00000000000000 --- a/target/linux/generic/backport-5.15/731-v6.1-0004-net-phy-Add-support-for-rate-matching.patch +++ /dev/null @@ -1,294 +0,0 @@ -From 0c3e10cb44232833a50cb8e3e784c432906a60c1 Mon Sep 17 00:00:00 2001 -From: Sean Anderson -Date: Tue, 20 Sep 2022 18:12:31 -0400 -Subject: [PATCH] net: phy: Add support for rate matching - -This adds support for rate matching (also known as rate adaptation) to -the phy subsystem. The general idea is that the phy interface runs at -one speed, and the MAC throttles the rate at which it sends packets to -the link speed. There's a good overview of several techniques for -achieving this at [1]. This patch adds support for three: pause-frame -based (such as in Aquantia phys), CRS-based (such as in 10PASS-TS and -2BASE-TL), and open-loop-based (such as in 10GBASE-W). - -This patch makes a few assumptions and a few non assumptions about the -types of rate matching available. First, it assumes that different phys -may use different forms of rate matching. Second, it assumes that phys -can use rate matching for any of their supported link speeds (e.g. if a -phy supports 10BASE-T and XGMII, then it can adapt XGMII to 10BASE-T). -Third, it does not assume that all interface modes will use the same -form of rate matching. Fourth, it does not assume that all phy devices -will support rate matching (even if some do). Relaxing or strengthening -these (non-)assumptions could result in a different API. For example, if -all interface modes were assumed to use the same form of rate matching, -then a bitmask of interface modes supportting rate matching would -suffice. - -For some better visibility into the process, the current rate matching -mode is exposed as part of the ethtool ksettings. For the moment, only -read access is supported. I'm not sure what userspace might want to -configure yet (disable it altogether, disable just one mode, specify the -mode to use, etc.). For the moment, since only pause-based rate -adaptation support is added in the next few commits, rate matching can -be disabled altogether by adjusting the advertisement. - -802.3 calls this feature "rate adaptation" in clause 49 (10GBASE-R) and -"rate matching" in clause 61 (10PASS-TL and 2BASE-TS). Aquantia also calls -this feature "rate adaptation". I chose "rate matching" because it is -shorter, and because Russell doesn't think "adaptation" is correct in this -context. - -Signed-off-by: Sean Anderson -Signed-off-by: David S. Miller ---- - Documentation/networking/ethtool-netlink.rst | 2 ++ - drivers/net/phy/phy-core.c | 21 +++++++++++++++ - drivers/net/phy/phy.c | 28 ++++++++++++++++++++ - include/linux/phy.h | 22 ++++++++++++++- - include/uapi/linux/ethtool.h | 18 +++++++++++-- - include/uapi/linux/ethtool_netlink.h | 1 + - net/ethtool/ioctl.c | 1 + - net/ethtool/linkmodes.c | 5 ++++ - 8 files changed, 95 insertions(+), 3 deletions(-) - ---- a/Documentation/networking/ethtool-netlink.rst -+++ b/Documentation/networking/ethtool-netlink.rst -@@ -418,6 +418,7 @@ Kernel response contents: - ``ETHTOOL_A_LINKMODES_DUPLEX`` u8 duplex mode - ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG`` u8 Master/slave port mode - ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE`` u8 Master/slave port state -+ ``ETHTOOL_A_LINKMODES_RATE_MATCHING`` u8 PHY rate matching - ========================================== ====== ========================== - - For ``ETHTOOL_A_LINKMODES_OURS``, value represents advertised modes and mask -@@ -441,6 +442,7 @@ Request contents: - ``ETHTOOL_A_LINKMODES_SPEED`` u32 link speed (Mb/s) - ``ETHTOOL_A_LINKMODES_DUPLEX`` u8 duplex mode - ``ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG`` u8 Master/slave port mode -+ ``ETHTOOL_A_LINKMODES_RATE_MATCHING`` u8 PHY rate matching - ``ETHTOOL_A_LINKMODES_LANES`` u32 lanes - ========================================== ====== ========================== - ---- a/drivers/net/phy/phy-core.c -+++ b/drivers/net/phy/phy-core.c -@@ -75,6 +75,27 @@ const char *phy_duplex_to_str(unsigned i - EXPORT_SYMBOL_GPL(phy_duplex_to_str); - - /** -+ * phy_rate_matching_to_str - Return a string describing the rate matching -+ * -+ * @rate_matching: Type of rate matching to describe -+ */ -+const char *phy_rate_matching_to_str(int rate_matching) -+{ -+ switch (rate_matching) { -+ case RATE_MATCH_NONE: -+ return "none"; -+ case RATE_MATCH_PAUSE: -+ return "pause"; -+ case RATE_MATCH_CRS: -+ return "crs"; -+ case RATE_MATCH_OPEN_LOOP: -+ return "open-loop"; -+ } -+ return "Unsupported (update phy-core.c)"; -+} -+EXPORT_SYMBOL_GPL(phy_rate_matching_to_str); -+ -+/** - * phy_interface_num_ports - Return the number of links that can be carried by - * a given MAC-PHY physical link. Returns 0 if this is - * unknown, the number of links else. ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -127,6 +127,33 @@ void phy_print_status(struct phy_device - EXPORT_SYMBOL(phy_print_status); - - /** -+ * phy_get_rate_matching - determine if rate matching is supported -+ * @phydev: The phy device to return rate matching for -+ * @iface: The interface mode to use -+ * -+ * This determines the type of rate matching (if any) that @phy supports -+ * using @iface. @iface may be %PHY_INTERFACE_MODE_NA to determine if any -+ * interface supports rate matching. -+ * -+ * Return: The type of rate matching @phy supports for @iface, or -+ * %RATE_MATCH_NONE. -+ */ -+int phy_get_rate_matching(struct phy_device *phydev, -+ phy_interface_t iface) -+{ -+ int ret = RATE_MATCH_NONE; -+ -+ if (phydev->drv->get_rate_matching) { -+ mutex_lock(&phydev->lock); -+ ret = phydev->drv->get_rate_matching(phydev, iface); -+ mutex_unlock(&phydev->lock); -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(phy_get_rate_matching); -+ -+/** - * phy_config_interrupt - configure the PHY device for the requested interrupts - * @phydev: the phy_device struct - * @interrupts: interrupt flags to configure for this @phydev -@@ -268,6 +295,7 @@ void phy_ethtool_ksettings_get(struct ph - cmd->base.duplex = phydev->duplex; - cmd->base.master_slave_cfg = phydev->master_slave_get; - cmd->base.master_slave_state = phydev->master_slave_state; -+ cmd->base.rate_matching = phydev->rate_matching; - if (phydev->interface == PHY_INTERFACE_MODE_MOCA) - cmd->base.port = PORT_BNC; - else ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -280,7 +280,6 @@ static inline const char *phy_modes(phy_ - } - } - -- - #define PHY_INIT_TIMEOUT 100000 - #define PHY_FORCE_TIMEOUT 10 - -@@ -573,6 +572,7 @@ struct macsec_ops; - * @lp_advertising: Current link partner advertised linkmodes - * @eee_broken_modes: Energy efficient ethernet modes which should be prohibited - * @autoneg: Flag autoneg being used -+ * @rate_matching: Current rate matching mode - * @link: Current link state - * @autoneg_complete: Flag auto negotiation of the link has completed - * @mdix: Current crossover -@@ -639,6 +639,8 @@ struct phy_device { - unsigned irq_suspended:1; - unsigned irq_rerun:1; - -+ int rate_matching; -+ - enum phy_state state; - - u32 dev_flags; -@@ -801,6 +803,21 @@ struct phy_driver { - */ - int (*get_features)(struct phy_device *phydev); - -+ /** -+ * @get_rate_matching: Get the supported type of rate matching for a -+ * particular phy interface. This is used by phy consumers to determine -+ * whether to advertise lower-speed modes for that interface. It is -+ * assumed that if a rate matching mode is supported on an interface, -+ * then that interface's rate can be adapted to all slower link speeds -+ * supported by the phy. If iface is %PHY_INTERFACE_MODE_NA, and the phy -+ * supports any kind of rate matching for any interface, then it must -+ * return that rate matching mode (preferring %RATE_MATCH_PAUSE to -+ * %RATE_MATCH_CRS). If the interface is not supported, this should -+ * return %RATE_MATCH_NONE. -+ */ -+ int (*get_rate_matching)(struct phy_device *phydev, -+ phy_interface_t iface); -+ - /* PHY Power Management */ - /** @suspend: Suspend the hardware, saving state if needed */ - int (*suspend)(struct phy_device *phydev); -@@ -967,6 +984,7 @@ struct phy_fixup { - - const char *phy_speed_to_str(int speed); - const char *phy_duplex_to_str(unsigned int duplex); -+const char *phy_rate_matching_to_str(int rate_matching); - - int phy_interface_num_ports(phy_interface_t interface); - -@@ -1675,6 +1693,8 @@ int phy_disable_interrupts(struct phy_de - void phy_request_interrupt(struct phy_device *phydev); - void phy_free_interrupt(struct phy_device *phydev); - void phy_print_status(struct phy_device *phydev); -+int phy_get_rate_matching(struct phy_device *phydev, -+ phy_interface_t iface); - int phy_set_max_speed(struct phy_device *phydev, u32 max_speed); - void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode); - void phy_advertise_supported(struct phy_device *phydev); ---- a/include/uapi/linux/ethtool.h -+++ b/include/uapi/linux/ethtool.h -@@ -1809,6 +1809,20 @@ static inline int ethtool_validate_duple - #define MASTER_SLAVE_STATE_SLAVE 3 - #define MASTER_SLAVE_STATE_ERR 4 - -+/* These are used to throttle the rate of data on the phy interface when the -+ * native speed of the interface is higher than the link speed. These should -+ * not be used for phy interfaces which natively support multiple speeds (e.g. -+ * MII or SGMII). -+ */ -+/* No rate matching performed. */ -+#define RATE_MATCH_NONE 0 -+/* The phy sends pause frames to throttle the MAC. */ -+#define RATE_MATCH_PAUSE 1 -+/* The phy asserts CRS to prevent the MAC from transmitting. */ -+#define RATE_MATCH_CRS 2 -+/* The MAC is programmed with a sufficiently-large IPG. */ -+#define RATE_MATCH_OPEN_LOOP 3 -+ - /* Which connector port. */ - #define PORT_TP 0x00 - #define PORT_AUI 0x01 -@@ -2002,8 +2016,8 @@ enum ethtool_reset_flags { - * reported consistently by PHYLIB. Read-only. - * @master_slave_cfg: Master/slave port mode. - * @master_slave_state: Master/slave port state. -+ * @rate_matching: Rate adaptation performed by the PHY - * @reserved: Reserved for future use; see the note on reserved space. -- * @reserved1: Reserved for future use; see the note on reserved space. - * @link_mode_masks: Variable length bitmaps. - * - * If autonegotiation is disabled, the speed and @duplex represent the -@@ -2054,7 +2068,7 @@ struct ethtool_link_settings { - __u8 transceiver; - __u8 master_slave_cfg; - __u8 master_slave_state; -- __u8 reserved1[1]; -+ __u8 rate_matching; - __u32 reserved[7]; - __u32 link_mode_masks[0]; - /* layout of link_mode_masks fields: ---- a/include/uapi/linux/ethtool_netlink.h -+++ b/include/uapi/linux/ethtool_netlink.h -@@ -238,6 +238,7 @@ enum { - ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, /* u8 */ - ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE, /* u8 */ - ETHTOOL_A_LINKMODES_LANES, /* u32 */ -+ ETHTOOL_A_LINKMODES_RATE_MATCHING, /* u8 */ - - /* add new constants above here */ - __ETHTOOL_A_LINKMODES_CNT, ---- a/net/ethtool/ioctl.c -+++ b/net/ethtool/ioctl.c -@@ -559,6 +559,7 @@ static int ethtool_get_link_ksettings(st - = __ETHTOOL_LINK_MODE_MASK_NU32; - link_ksettings.base.master_slave_cfg = MASTER_SLAVE_CFG_UNSUPPORTED; - link_ksettings.base.master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED; -+ link_ksettings.base.rate_matching = RATE_MATCH_NONE; - - return store_link_ksettings_for_user(useraddr, &link_ksettings); - } ---- a/net/ethtool/linkmodes.c -+++ b/net/ethtool/linkmodes.c -@@ -70,6 +70,7 @@ static int linkmodes_reply_size(const st - + nla_total_size(sizeof(u32)) /* LINKMODES_SPEED */ - + nla_total_size(sizeof(u32)) /* LINKMODES_LANES */ - + nla_total_size(sizeof(u8)) /* LINKMODES_DUPLEX */ -+ + nla_total_size(sizeof(u8)) /* LINKMODES_RATE_MATCHING */ - + 0; - ret = ethnl_bitset_size(ksettings->link_modes.advertising, - ksettings->link_modes.supported, -@@ -143,6 +144,10 @@ static int linkmodes_fill_reply(struct s - lsettings->master_slave_state)) - return -EMSGSIZE; - -+ if (nla_put_u8(skb, ETHTOOL_A_LINKMODES_RATE_MATCHING, -+ lsettings->rate_matching)) -+ return -EMSGSIZE; -+ - return 0; - } - diff --git a/target/linux/generic/backport-5.15/733-v6.2-01-net-ethernet-mtk_eth_soc-Avoid-truncating-allocation.patch b/target/linux/generic/backport-5.15/733-v6.2-01-net-ethernet-mtk_eth_soc-Avoid-truncating-allocation.patch deleted file mode 100644 index 460c5c23178991..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-01-net-ethernet-mtk_eth_soc-Avoid-truncating-allocation.patch +++ /dev/null @@ -1,60 +0,0 @@ -From f3eceaed9edd7c0e0d9fb057613131f92973626f Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Fri, 27 Jan 2023 14:38:54 -0800 -Subject: [PATCH] net: ethernet: mtk_eth_soc: Avoid truncating allocation - -There doesn't appear to be a reason to truncate the allocation used for -flow_info, so do a full allocation and remove the unused empty struct. -GCC does not like having a reference to an object that has been -partially allocated, as bounds checking may become impossible when -such an object is passed to other code. Seen with GCC 13: - -../drivers/net/ethernet/mediatek/mtk_ppe.c: In function 'mtk_foe_entry_commit_subflow': -../drivers/net/ethernet/mediatek/mtk_ppe.c:623:18: warning: array subscript 'struct mtk_flow_entry[0]' is partly outside array bounds of 'unsigned char[48]' [-Warray-bounds=] - 623 | flow_info->l2_data.base_flow = entry; - | ^~ - -Cc: Felix Fietkau -Cc: John Crispin -Cc: Sean Wang -Cc: Mark Lee -Cc: Lorenzo Bianconi -Cc: "David S. Miller" -Cc: Eric Dumazet -Cc: Jakub Kicinski -Cc: Paolo Abeni -Cc: Matthias Brugger -Cc: netdev@vger.kernel.org -Cc: linux-arm-kernel@lists.infradead.org -Cc: linux-mediatek@lists.infradead.org -Signed-off-by: Kees Cook -Reviewed-by: Simon Horman -Link: https://lore.kernel.org/r/20230127223853.never.014-kees@kernel.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 3 +-- - drivers/net/ethernet/mediatek/mtk_ppe.h | 1 - - 2 files changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -621,8 +621,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ - u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; - int type; - -- flow_info = kzalloc(offsetof(struct mtk_flow_entry, l2_data.end), -- GFP_ATOMIC); -+ flow_info = kzalloc(sizeof(*flow_info), GFP_ATOMIC); - if (!flow_info) - return; - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -279,7 +279,6 @@ struct mtk_flow_entry { - struct { - struct mtk_flow_entry *base_flow; - struct hlist_node list; -- struct {} end; - } l2_data; - }; - struct rhash_head node; diff --git a/target/linux/generic/backport-5.15/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch b/target/linux/generic/backport-5.15/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch deleted file mode 100644 index 68f3659367a32e..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch +++ /dev/null @@ -1,55 +0,0 @@ -From b6a709cb51f7bdc55c01cec886098a9753ce8c28 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:10:42 +0100 -Subject: [PATCH 01/10] net: mtk_eth_soc: add definitions for PCS - -As a result of help from Frank Wunderlich to investigate and test, we -know a bit more about the PCS on the Mediatek platforms. Update the -definitions from this investigation. - -This PCS appears similar, but not identical to the Lynx PCS. - -Although not included in this patch, but for future reference, the PHY -ID registers at offset 4 read as 0x4d544950 'MTIP'. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -501,8 +501,10 @@ - #define ETHSYS_DMA_AG_MAP_PPE BIT(2) - - /* SGMII subsystem config registers */ --/* Register to auto-negotiation restart */ -+/* BMCR (low 16) BMSR (high 16) */ - #define SGMSYS_PCS_CONTROL_1 0x0 -+#define SGMII_BMCR GENMASK(15, 0) -+#define SGMII_BMSR GENMASK(31, 16) - #define SGMII_AN_RESTART BIT(9) - #define SGMII_ISOLATE BIT(10) - #define SGMII_AN_ENABLE BIT(12) -@@ -512,13 +514,18 @@ - #define SGMII_PCS_FAULT BIT(23) - #define SGMII_AN_EXPANSION_CLR BIT(30) - -+#define SGMSYS_PCS_ADVERTISE 0x8 -+#define SGMII_ADVERTISE GENMASK(15, 0) -+#define SGMII_LPA GENMASK(31, 16) -+ - /* Register to programmable link timer, the unit in 2 * 8ns */ - #define SGMSYS_PCS_LINK_TIMER 0x18 --#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & GENMASK(19, 0)) -+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0) -+#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK) - - /* Register to control remote fault */ - #define SGMSYS_SGMII_MODE 0x20 --#define SGMII_IF_MODE_BIT0 BIT(0) -+#define SGMII_IF_MODE_SGMII BIT(0) - #define SGMII_SPEED_DUPLEX_AN BIT(1) - #define SGMII_SPEED_MASK GENMASK(3, 2) - #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) diff --git a/target/linux/generic/backport-5.15/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch b/target/linux/generic/backport-5.15/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch deleted file mode 100644 index 4ea428c9d6b1c2..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 5cf7797526ee81bea0f627bccaa3d887f48f53e0 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:10:47 +0100 -Subject: [PATCH 02/10] net: mtk_eth_soc: eliminate unnecessary error handling - -The functions called by the pcs_config() method always return zero, so -there is no point trying to handle an error from these functions. Make -these functions void, eliminate the "err" variable and simply return -zero from the pcs_config() function itself. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -20,7 +20,7 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st - } - - /* For SGMII interface mode */ --static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) -+static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) - { - unsigned int val; - -@@ -39,16 +39,13 @@ static int mtk_pcs_setup_mode_an(struct - regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); - val &= ~SGMII_PHYA_PWD; - regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); -- -- return 0; -- - } - - /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a - * fixed speed. - */ --static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, -- phy_interface_t interface) -+static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, -+ phy_interface_t interface) - { - unsigned int val; - -@@ -73,8 +70,6 @@ static int mtk_pcs_setup_mode_force(stru - regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); - val &= ~SGMII_PHYA_PWD; - regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); -- -- return 0; - } - - static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -83,15 +78,14 @@ static int mtk_pcs_config(struct phylink - bool permit_pause_to_mac) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- int err = 0; - - /* Setup SGMIISYS with the determined property */ - if (interface != PHY_INTERFACE_MODE_SGMII) -- err = mtk_pcs_setup_mode_force(mpcs, interface); -+ mtk_pcs_setup_mode_force(mpcs, interface); - else if (phylink_autoneg_inband(mode)) -- err = mtk_pcs_setup_mode_an(mpcs); -+ mtk_pcs_setup_mode_an(mpcs); - -- return err; -+ return 0; - } - - static void mtk_pcs_restart_an(struct phylink_pcs *pcs) diff --git a/target/linux/generic/backport-5.15/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch b/target/linux/generic/backport-5.15/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch deleted file mode 100644 index 64a4a72fa6ae96..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch +++ /dev/null @@ -1,46 +0,0 @@ -From c000dca098002da193b98099df051c9ead0cacb4 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:10:52 +0100 -Subject: [PATCH 03/10] net: mtk_eth_soc: add pcs_get_state() implementation - -Add a pcs_get_state() implementation which uses the advertisements -to compute the resulting link modes, and BMSR contents to determine -negotiation and link status. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -19,6 +19,20 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st - return container_of(pcs, struct mtk_pcs, pcs); - } - -+static void mtk_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -+ unsigned int bm, adv; -+ -+ /* Read the BMSR and LPA */ -+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); -+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -+ -+ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), -+ FIELD_GET(SGMII_LPA, adv)); -+} -+ - /* For SGMII interface mode */ - static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) - { -@@ -117,6 +131,7 @@ static void mtk_pcs_link_up(struct phyli - } - - static const struct phylink_pcs_ops mtk_pcs_ops = { -+ .pcs_get_state = mtk_pcs_get_state, - .pcs_config = mtk_pcs_config, - .pcs_an_restart = mtk_pcs_restart_an, - .pcs_link_up = mtk_pcs_link_up, diff --git a/target/linux/generic/backport-5.15/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch b/target/linux/generic/backport-5.15/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch deleted file mode 100644 index 24610fe11e1f4d..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 0d2351dc2768061689abd4de1529fa206bbd574e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:10:58 +0100 -Subject: [PATCH 04/10] net: mtk_eth_soc: convert mtk_sgmii to use - regmap_update_bits() - -mtk_sgmii does a lot of read-modify-write operations, for which there -is a specific regmap function. Use this function instead of open-coding -the operations. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 61 ++++++++++------------- - 1 file changed, 26 insertions(+), 35 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -36,23 +36,18 @@ static void mtk_pcs_get_state(struct phy - /* For SGMII interface mode */ - static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) - { -- unsigned int val; -- - /* Setup the link timer and QPHY power up inside SGMIISYS */ - regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, - SGMII_LINK_TIMER_DEFAULT); - -- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); -- val |= SGMII_REMOTE_FAULT_DIS; -- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); -- -- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); -- val |= SGMII_AN_RESTART; -- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); -- -- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); -- val &= ~SGMII_PHYA_PWD; -- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS); -+ -+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -+ SGMII_AN_RESTART, SGMII_AN_RESTART); -+ -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -+ SGMII_PHYA_PWD, 0); - } - - /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a -@@ -61,29 +56,26 @@ static void mtk_pcs_setup_mode_an(struct - static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, - phy_interface_t interface) - { -- unsigned int val; -+ unsigned int rgc3; - -- regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val); -- val &= ~RG_PHY_SPEED_MASK; - if (interface == PHY_INTERFACE_MODE_2500BASEX) -- val |= RG_PHY_SPEED_3_125G; -- regmap_write(mpcs->regmap, mpcs->ana_rgc3, val); -+ rgc3 = RG_PHY_SPEED_3_125G; -+ -+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -+ RG_PHY_SPEED_3_125G, rgc3); - - /* Disable SGMII AN */ -- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); -- val &= ~SGMII_AN_ENABLE; -- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -+ SGMII_AN_ENABLE, 0); - - /* Set the speed etc but leave the duplex unchanged */ -- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); -- val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK; -- val |= SGMII_SPEED_1000; -- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL, -+ SGMII_SPEED_1000); - - /* Release PHYA power down state */ -- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); -- val &= ~SGMII_PHYA_PWD; -- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -+ SGMII_PHYA_PWD, 0); - } - - static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -105,29 +97,28 @@ static int mtk_pcs_config(struct phylink - static void mtk_pcs_restart_an(struct phylink_pcs *pcs) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- unsigned int val; - -- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); -- val |= SGMII_AN_RESTART; -- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -+ SGMII_AN_RESTART, SGMII_AN_RESTART); - } - - static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, - phy_interface_t interface, int speed, int duplex) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- unsigned int val; -+ unsigned int sgm_mode; - - if (!phy_interface_mode_is_8023z(interface)) - return; - - /* SGMII force duplex setting */ -- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); -- val &= ~SGMII_DUPLEX_FULL; - if (duplex == DUPLEX_FULL) -- val |= SGMII_DUPLEX_FULL; -+ sgm_mode = SGMII_DUPLEX_FULL; -+ else -+ sgm_mode = 0; - -- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_DUPLEX_FULL, sgm_mode); - } - - static const struct phylink_pcs_ops mtk_pcs_ops = { diff --git a/target/linux/generic/backport-5.15/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch b/target/linux/generic/backport-5.15/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch deleted file mode 100644 index ba76ca40ffaaa8..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 12198c3a410fe69843e335c1bbf6d4c2a4d48e4e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:03 +0100 -Subject: [PATCH 05/10] net: mtk_eth_soc: add out of band forcing of speed and - duplex in pcs_link_up - -Add support for forcing the link speed and duplex setting in the -pcs_link_up() method for out of band modes, which will be useful when -we finish converting the pcs_config() method. Until then, we still have -to force duplex for 802.3z modes to work correctly. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 28 ++++++++++++++--------- - 1 file changed, 17 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -108,17 +108,23 @@ static void mtk_pcs_link_up(struct phyli - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - unsigned int sgm_mode; - -- if (!phy_interface_mode_is_8023z(interface)) -- return; -+ if (!phylink_autoneg_inband(mode) || -+ phy_interface_mode_is_8023z(interface)) { -+ /* Force the speed and duplex setting */ -+ if (speed == SPEED_10) -+ sgm_mode = SGMII_SPEED_10; -+ else if (speed == SPEED_100) -+ sgm_mode = SGMII_SPEED_100; -+ else -+ sgm_mode = SGMII_SPEED_1000; - -- /* SGMII force duplex setting */ -- if (duplex == DUPLEX_FULL) -- sgm_mode = SGMII_DUPLEX_FULL; -- else -- sgm_mode = 0; -+ if (duplex == DUPLEX_FULL) -+ sgm_mode |= SGMII_DUPLEX_FULL; - -- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_DUPLEX_FULL, sgm_mode); -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_DUPLEX_FULL | SGMII_SPEED_MASK, -+ sgm_mode); -+ } - } - - static const struct phylink_pcs_ops mtk_pcs_ops = { diff --git a/target/linux/generic/backport-5.15/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch b/target/linux/generic/backport-5.15/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch deleted file mode 100644 index b76e15927505cb..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 6f38fffe2179dd29612aea2c67c46ed6682b4e46 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:08 +0100 -Subject: [PATCH 06/10] net: mtk_eth_soc: move PHY power up - -The PHY power up is common to both configuration paths, so move it into -the parent function. We need to do this for all serdes modes. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -45,9 +45,6 @@ static void mtk_pcs_setup_mode_an(struct - - regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, - SGMII_AN_RESTART, SGMII_AN_RESTART); -- -- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -- SGMII_PHYA_PWD, 0); - } - - /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a -@@ -72,10 +69,6 @@ static void mtk_pcs_setup_mode_force(str - regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, - SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL, - SGMII_SPEED_1000); -- -- /* Release PHYA power down state */ -- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -- SGMII_PHYA_PWD, 0); - } - - static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -91,6 +84,10 @@ static int mtk_pcs_config(struct phylink - else if (phylink_autoneg_inband(mode)) - mtk_pcs_setup_mode_an(mpcs); - -+ /* Release PHYA power down state */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -+ SGMII_PHYA_PWD, 0); -+ - return 0; - } - diff --git a/target/linux/generic/backport-5.15/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch b/target/linux/generic/backport-5.15/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch deleted file mode 100644 index cd9f0699b3ebc7..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch +++ /dev/null @@ -1,48 +0,0 @@ -From f752c0df13dfeb721c11d3debb79f08cf437344f Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:13 +0100 -Subject: [PATCH 07/10] net: mtk_eth_soc: move interface speed selection - -Move the selection of the underlying interface speed to the pcs_config -function, so we always program the interface speed. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -53,14 +53,6 @@ static void mtk_pcs_setup_mode_an(struct - static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, - phy_interface_t interface) - { -- unsigned int rgc3; -- -- if (interface == PHY_INTERFACE_MODE_2500BASEX) -- rgc3 = RG_PHY_SPEED_3_125G; -- -- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -- RG_PHY_SPEED_3_125G, rgc3); -- - /* Disable SGMII AN */ - regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, - SGMII_AN_ENABLE, 0); -@@ -77,6 +69,16 @@ static int mtk_pcs_config(struct phylink - bool permit_pause_to_mac) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -+ unsigned int rgc3; -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ rgc3 = RG_PHY_SPEED_3_125G; -+ else -+ rgc3 = 0; -+ -+ /* Configure the underlying interface speed */ -+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -+ RG_PHY_SPEED_3_125G, rgc3); - - /* Setup SGMIISYS with the determined property */ - if (interface != PHY_INTERFACE_MODE_SGMII) diff --git a/target/linux/generic/backport-5.15/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch b/target/linux/generic/backport-5.15/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch deleted file mode 100644 index f08358e963d53a..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch +++ /dev/null @@ -1,52 +0,0 @@ -From c125c66ea71b9377ae2478c4f1b87b180cc5c6ef Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:18 +0100 -Subject: [PATCH 08/10] net: mtk_eth_soc: add advertisement programming - -Program the advertisement into the mtk PCS block. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -70,16 +70,27 @@ static int mtk_pcs_config(struct phylink - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - unsigned int rgc3; -+ int advertise; -+ bool changed; - - if (interface == PHY_INTERFACE_MODE_2500BASEX) - rgc3 = RG_PHY_SPEED_3_125G; - else - rgc3 = 0; - -+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface, -+ advertising); -+ if (advertise < 0) -+ return advertise; -+ - /* Configure the underlying interface speed */ - regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, - RG_PHY_SPEED_3_125G, rgc3); - -+ /* Update the advertisement, noting whether it has changed */ -+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, -+ SGMII_ADVERTISE, advertise, &changed); -+ - /* Setup SGMIISYS with the determined property */ - if (interface != PHY_INTERFACE_MODE_SGMII) - mtk_pcs_setup_mode_force(mpcs, interface); -@@ -90,7 +101,7 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, - SGMII_PHYA_PWD, 0); - -- return 0; -+ return changed; - } - - static void mtk_pcs_restart_an(struct phylink_pcs *pcs) diff --git a/target/linux/generic/backport-5.15/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch b/target/linux/generic/backport-5.15/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch deleted file mode 100644 index 602d52c6f46a3a..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3027d89f87707e7f3e5b683e0d37a32afb5bde96 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:23 +0100 -Subject: [PATCH 09/10] net: mtk_eth_soc: move and correct link timer - programming - -Program the link timer appropriately for the interface mode being -used, using the newly introduced phylink helper that provides the -nanosecond link timer interval. - -The intervals are 1.6ms for SGMII based protocols and 10ms for -802.3z based protocols. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -36,10 +36,6 @@ static void mtk_pcs_get_state(struct phy - /* For SGMII interface mode */ - static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) - { -- /* Setup the link timer and QPHY power up inside SGMIISYS */ -- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, -- SGMII_LINK_TIMER_DEFAULT); -- - regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, - SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS); - -@@ -69,8 +65,8 @@ static int mtk_pcs_config(struct phylink - bool permit_pause_to_mac) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -+ int advertise, link_timer; - unsigned int rgc3; -- int advertise; - bool changed; - - if (interface == PHY_INTERFACE_MODE_2500BASEX) -@@ -83,6 +79,10 @@ static int mtk_pcs_config(struct phylink - if (advertise < 0) - return advertise; - -+ link_timer = phylink_get_link_timer_ns(interface); -+ if (link_timer < 0) -+ return link_timer; -+ - /* Configure the underlying interface speed */ - regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, - RG_PHY_SPEED_3_125G, rgc3); -@@ -91,6 +91,9 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, - SGMII_ADVERTISE, advertise, &changed); - -+ /* Setup the link timer and QPHY power up inside SGMIISYS */ -+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); -+ - /* Setup SGMIISYS with the determined property */ - if (interface != PHY_INTERFACE_MODE_SGMII) - mtk_pcs_setup_mode_force(mpcs, interface); diff --git a/target/linux/generic/backport-5.15/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch b/target/linux/generic/backport-5.15/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch deleted file mode 100644 index 0e9a0535a7b260..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 81b0f12a2a8a1699a7d49c3995e5f71e4ec018e6 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:28 +0100 -Subject: [PATCH 10/10] net: mtk_eth_soc: add support for in-band 802.3z - negotiation - -As a result of help from Frank Wunderlich to investigate and test, we -now know how to program this PCS for in-band 802.3z negotiation. Add -support for this by moving the contents of the two functions into the -common mtk_pcs_config() function and adding the register settings for -802.3z negotiation. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 77 ++++++++++++----------- - 1 file changed, 42 insertions(+), 35 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -33,41 +33,15 @@ static void mtk_pcs_get_state(struct phy - FIELD_GET(SGMII_LPA, adv)); - } - --/* For SGMII interface mode */ --static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) --{ -- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS); -- -- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -- SGMII_AN_RESTART, SGMII_AN_RESTART); --} -- --/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a -- * fixed speed. -- */ --static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, -- phy_interface_t interface) --{ -- /* Disable SGMII AN */ -- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -- SGMII_AN_ENABLE, 0); -- -- /* Set the speed etc but leave the duplex unchanged */ -- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL, -- SGMII_SPEED_1000); --} -- - static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, - phy_interface_t interface, - const unsigned long *advertising, - bool permit_pause_to_mac) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -+ unsigned int rgc3, sgm_mode, bmcr; - int advertise, link_timer; -- unsigned int rgc3; -- bool changed; -+ bool changed, use_an; - - if (interface == PHY_INTERFACE_MODE_2500BASEX) - rgc3 = RG_PHY_SPEED_3_125G; -@@ -83,6 +57,37 @@ static int mtk_pcs_config(struct phylink - if (link_timer < 0) - return link_timer; - -+ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and -+ * we assume that fixes it's speed at bitrate = line rate (in -+ * other words, 1000Mbps or 2500Mbps). -+ */ -+ if (interface == PHY_INTERFACE_MODE_SGMII) { -+ sgm_mode = SGMII_IF_MODE_SGMII; -+ if (phylink_autoneg_inband(mode)) { -+ sgm_mode |= SGMII_REMOTE_FAULT_DIS | -+ SGMII_SPEED_DUPLEX_AN; -+ use_an = true; -+ } else { -+ use_an = false; -+ } -+ } else if (phylink_autoneg_inband(mode)) { -+ /* 1000base-X or 2500base-X autoneg */ -+ sgm_mode = SGMII_REMOTE_FAULT_DIS; -+ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ advertising); -+ } else { -+ /* 1000base-X or 2500base-X without autoneg */ -+ sgm_mode = 0; -+ use_an = false; -+ } -+ -+ if (use_an) { -+ /* FIXME: Do we need to set AN_RESTART here? */ -+ bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE; -+ } else { -+ bmcr = 0; -+ } -+ - /* Configure the underlying interface speed */ - regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, - RG_PHY_SPEED_3_125G, rgc3); -@@ -94,11 +99,14 @@ static int mtk_pcs_config(struct phylink - /* Setup the link timer and QPHY power up inside SGMIISYS */ - regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); - -- /* Setup SGMIISYS with the determined property */ -- if (interface != PHY_INTERFACE_MODE_SGMII) -- mtk_pcs_setup_mode_force(mpcs, interface); -- else if (phylink_autoneg_inband(mode)) -- mtk_pcs_setup_mode_an(mpcs); -+ /* Update the sgmsys mode register */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | -+ SGMII_IF_MODE_SGMII, sgm_mode); -+ -+ /* Update the BMCR */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -+ SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr); - - /* Release PHYA power down state */ - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -@@ -121,8 +129,7 @@ static void mtk_pcs_link_up(struct phyli - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - unsigned int sgm_mode; - -- if (!phylink_autoneg_inband(mode) || -- phy_interface_mode_is_8023z(interface)) { -+ if (!phylink_autoneg_inband(mode)) { - /* Force the speed and duplex setting */ - if (speed == SPEED_10) - sgm_mode = SGMII_SPEED_10; diff --git a/target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch b/target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch deleted file mode 100644 index 598788d99846bf..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 7ff82416de8295c61423ef6fd75f052d3837d2f7 Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Wed, 1 Feb 2023 19:23:29 +0100 -Subject: [PATCH 11/13] net: mediatek: sgmii: ensure the SGMII PHY is powered - down on configuration -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The code expect the PHY to be in power down which is only true after reset. -Allow changes of the SGMII parameters more than once. - -Only power down when reconfiguring to avoid bouncing the link when there's -no reason to - based on code from Russell King. - -There are cases when the SGMII_PHYA_PWD register contains 0x9 which -prevents SGMII from working. The SGMII still shows link but no traffic -can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was -taken from a good working state of the SGMII interface. - -Fixes: 42c03844e93d ("net-next: mediatek: add support for MediaTek MT7622 SoC") -Suggested-by: Russell King (Oracle) -Signed-off-by: Alexander Couzens -[ bmork: rebased and squashed into one patch ] -Reviewed-by: Russell King (Oracle) -Signed-off-by: Bjørn Mork -Acked-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++ - drivers/net/ethernet/mediatek/mtk_sgmii.c | 39 +++++++++++++++------ - 2 files changed, 30 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1064,11 +1064,13 @@ struct mtk_soc_data { - * @regmap: The register map pointing at the range used to setup - * SGMII modes - * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap -+ * @interface: Currently configured interface mode - * @pcs: Phylink PCS structure - */ - struct mtk_pcs { - struct regmap *regmap; - u32 ana_rgc3; -+ phy_interface_t interface; - struct phylink_pcs pcs; - }; - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -43,11 +43,6 @@ static int mtk_pcs_config(struct phylink - int advertise, link_timer; - bool changed, use_an; - -- if (interface == PHY_INTERFACE_MODE_2500BASEX) -- rgc3 = RG_PHY_SPEED_3_125G; -- else -- rgc3 = 0; -- - advertise = phylink_mii_c22_pcs_encode_advertisement(interface, - advertising); - if (advertise < 0) -@@ -88,9 +83,22 @@ static int mtk_pcs_config(struct phylink - bmcr = 0; - } - -- /* Configure the underlying interface speed */ -- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -- RG_PHY_SPEED_3_125G, rgc3); -+ if (mpcs->interface != interface) { -+ /* PHYA power down */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -+ SGMII_PHYA_PWD, SGMII_PHYA_PWD); -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ rgc3 = RG_PHY_SPEED_3_125G; -+ else -+ rgc3 = 0; -+ -+ /* Configure the underlying interface speed */ -+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -+ RG_PHY_SPEED_3_125G, rgc3); -+ -+ mpcs->interface = interface; -+ } - - /* Update the advertisement, noting whether it has changed */ - regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, -@@ -108,9 +116,17 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, - SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr); - -- /* Release PHYA power down state */ -- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -- SGMII_PHYA_PWD, 0); -+ /* Release PHYA power down state -+ * Only removing bit SGMII_PHYA_PWD isn't enough. -+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which -+ * prevents SGMII from working. The SGMII still shows link but no traffic -+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was -+ * taken from a good working state of the SGMII interface. -+ * Unknown how much the QPHY needs but it is racy without a sleep. -+ * Tested on mt7622 & mt7986. -+ */ -+ usleep_range(50, 100); -+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); - - return changed; - } -@@ -171,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - return PTR_ERR(ss->pcs[i].regmap); - - ss->pcs[i].pcs.ops = &mtk_pcs_ops; -+ ss->pcs[i].interface = PHY_INTERFACE_MODE_NA; - } - - return 0; diff --git a/target/linux/generic/backport-5.15/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch b/target/linux/generic/backport-5.15/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch deleted file mode 100644 index 79e5ad147ced77..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 9d32637122de88f1ef614c29703f0e050cad342e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= -Date: Wed, 1 Feb 2023 19:23:30 +0100 -Subject: [PATCH 12/13] net: mediatek: sgmii: fix duplex configuration -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The logic of the duplex bit is inverted. Setting it means half -duplex, not full duplex. - -Fix and rename macro to avoid confusion. - -Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII") -Reviewed-by: Russell King (Oracle) -Signed-off-by: Bjørn Mork -Acked-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 6 +++--- - 2 files changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -531,7 +531,7 @@ - #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) - #define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) - #define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) --#define SGMII_DUPLEX_FULL BIT(4) -+#define SGMII_DUPLEX_HALF BIT(4) - #define SGMII_IF_MODE_BIT5 BIT(5) - #define SGMII_REMOTE_FAULT_DIS BIT(8) - #define SGMII_CODE_SYNC_SET_VAL BIT(9) ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -154,11 +154,11 @@ static void mtk_pcs_link_up(struct phyli - else - sgm_mode = SGMII_SPEED_1000; - -- if (duplex == DUPLEX_FULL) -- sgm_mode |= SGMII_DUPLEX_FULL; -+ if (duplex != DUPLEX_FULL) -+ sgm_mode |= SGMII_DUPLEX_HALF; - - regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_DUPLEX_FULL | SGMII_SPEED_MASK, -+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, - sgm_mode); - } - } diff --git a/target/linux/generic/backport-5.15/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch b/target/linux/generic/backport-5.15/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch deleted file mode 100644 index 56d7a1348fb17d..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 3337a6e04ddf2923a1bdcf3d31b3b52412bf82dd Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Wed, 1 Feb 2023 19:23:31 +0100 -Subject: [PATCH 13/13] mtk_sgmii: enable PCS polling to allow SFP work -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently there is no IRQ handling (even the SGMII supports it). -Enable polling to support SFP ports. - -Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs") -Reviewed-by: Russell King (Oracle) -Signed-off-by: Alexander Couzens -[ bmork: changed "1" => "true" ] -Signed-off-by: Bjørn Mork -Acked-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -187,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - return PTR_ERR(ss->pcs[i].regmap); - - ss->pcs[i].pcs.ops = &mtk_pcs_ops; -+ ss->pcs[i].pcs.poll = true; - ss->pcs[i].interface = PHY_INTERFACE_MODE_NA; - } - diff --git a/target/linux/generic/backport-5.15/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch b/target/linux/generic/backport-5.15/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch deleted file mode 100644 index a63b110914b08f..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 611e2dabb4b3243d176739fd6a5a34d007fa3f86 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 14 Mar 2023 00:34:26 +0000 -Subject: [PATCH 1/2] net: ethernet: mtk_eth_soc: reset PCS state -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Reset the internal PCS state machine when changing interface mode. -This prevents confusing the state machine when changing interface -modes, e.g. from SGMII to 2500Base-X or vice-versa. - -Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII") -Reviewed-by: Russell King (Oracle) -Tested-by: Bjørn Mork -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++ - drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++++ - 2 files changed, 8 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -539,6 +539,10 @@ - #define SGMII_SEND_AN_ERROR_EN BIT(11) - #define SGMII_IF_MODE_MASK GENMASK(5, 1) - -+/* Register to reset SGMII design */ -+#define SGMII_RESERVED_0 0x34 -+#define SGMII_SW_RESET BIT(0) -+ - /* Register to set SGMII speed, ANA RG_ Control Signals III*/ - #define SGMSYS_ANA_RG_CS3 0x2028 - #define RG_PHY_SPEED_MASK (BIT(2) | BIT(3)) ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -88,6 +88,10 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, - SGMII_PHYA_PWD, SGMII_PHYA_PWD); - -+ /* Reset SGMII PCS state */ -+ regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0, -+ SGMII_SW_RESET, SGMII_SW_RESET); -+ - if (interface == PHY_INTERFACE_MODE_2500BASEX) - rgc3 = RG_PHY_SPEED_3_125G; - else diff --git a/target/linux/generic/backport-5.15/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch b/target/linux/generic/backport-5.15/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch deleted file mode 100644 index 0fabeea20c07ae..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 6e933a804c7db8be64f367f33e63cd7dcc302ebb Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 14 Mar 2023 00:34:45 +0000 -Subject: [PATCH 2/2] net: ethernet: mtk_eth_soc: only write values if needed -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Only restart auto-negotiation and write link timer if actually -necessary. This prevents losing the link in case of minor -changes. - -Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII") -Reviewed-by: Russell King (Oracle) -Tested-by: Bjørn Mork -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++++++++------------ - 1 file changed, 12 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink - const unsigned long *advertising, - bool permit_pause_to_mac) - { -+ bool mode_changed = false, changed, use_an; - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - unsigned int rgc3, sgm_mode, bmcr; - int advertise, link_timer; -- bool changed, use_an; - - advertise = phylink_mii_c22_pcs_encode_advertisement(interface, - advertising); - if (advertise < 0) - return advertise; - -- link_timer = phylink_get_link_timer_ns(interface); -- if (link_timer < 0) -- return link_timer; -- - /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and - * we assume that fixes it's speed at bitrate = line rate (in - * other words, 1000Mbps or 2500Mbps). -@@ -77,13 +73,16 @@ static int mtk_pcs_config(struct phylink - } - - if (use_an) { -- /* FIXME: Do we need to set AN_RESTART here? */ -- bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE; -+ bmcr = SGMII_AN_ENABLE; - } else { - bmcr = 0; - } - - if (mpcs->interface != interface) { -+ link_timer = phylink_get_link_timer_ns(interface); -+ if (link_timer < 0) -+ return link_timer; -+ - /* PHYA power down */ - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, - SGMII_PHYA_PWD, SGMII_PHYA_PWD); -@@ -101,16 +100,17 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, - RG_PHY_SPEED_3_125G, rgc3); - -+ /* Setup the link timer */ -+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); -+ - mpcs->interface = interface; -+ mode_changed = true; - } - - /* Update the advertisement, noting whether it has changed */ - regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, - SGMII_ADVERTISE, advertise, &changed); - -- /* Setup the link timer and QPHY power up inside SGMIISYS */ -- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); -- - /* Update the sgmsys mode register */ - regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, - SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | -@@ -118,7 +118,7 @@ static int mtk_pcs_config(struct phylink - - /* Update the BMCR */ - regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -- SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr); -+ SGMII_AN_ENABLE, bmcr); - - /* Release PHYA power down state - * Only removing bit SGMII_PHYA_PWD isn't enough. -@@ -132,7 +132,7 @@ static int mtk_pcs_config(struct phylink - usleep_range(50, 100); - regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); - -- return changed; -+ return changed || mode_changed; - } - - static void mtk_pcs_restart_an(struct phylink_pcs *pcs) diff --git a/target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch b/target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch deleted file mode 100644 index 741831f6967f8a..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch +++ /dev/null @@ -1,200 +0,0 @@ -From f5d43ddd334b7c32fcaed9ba46afbd85cb467f1f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 19 Mar 2023 12:56:28 +0000 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for MT7981 SoC - -The MediaTek MT7981 SoC comes with two 1G/2.5G SGMII ports, just like -MT7986. - -In addition MT7981 is equipped with a built-in 1000Base-T PHY which can -be used with GMAC1. - -As many MT7981 boards make use of inverting SGMII signal polarity, add -new device-tree attribute 'mediatek,pn_swap' to support them. - -Signed-off-by: Daniel Golle -Signed-off-by: Jakub Kicinski - ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -96,12 +96,20 @@ static int set_mux_gmac2_gmac0_to_gephy( - - static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path) - { -- unsigned int val = 0; -+ unsigned int val = 0, mask = 0, reg = 0; - bool updated = true; - - switch (path) { - case MTK_ETH_PATH_GMAC2_SGMII: -- val = CO_QPHY_SEL; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_U3_COPHY_V2)) { -+ reg = USB_PHY_SWITCH_REG; -+ val = SGMII_QPHY_SEL; -+ mask = QPHY_SEL_MASK; -+ } else { -+ reg = INFRA_MISC2; -+ val = CO_QPHY_SEL; -+ mask = val; -+ } - break; - default: - updated = false; -@@ -109,7 +117,7 @@ static int set_mux_u3_gmac2_to_qphy(stru - } - - if (updated) -- regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val); -+ regmap_update_bits(eth->infra, reg, mask, val); - - dev_dbg(eth->dev, "path %s in %s updated = %d\n", - mtk_eth_path_name(path), __func__, updated); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4751,6 +4751,26 @@ static const struct mtk_soc_data mt7629_ - }, - }; - -+static const struct mtk_soc_data mt7981_data = { -+ .reg_map = &mt7986_reg_map, -+ .ana_rgc3 = 0x128, -+ .caps = MT7981_CAPS, -+ .hw_features = MTK_HW_FEATURES, -+ .required_clks = MT7981_CLKS_BITMAP, -+ .required_pctl = false, -+ .offload_version = 2, -+ .hash_offset = 4, -+ .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma_v2), -+ .rxd_size = sizeof(struct mtk_rx_dma_v2), -+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, -+ .dma_len_offset = 8, -+ }, -+}; -+ - static const struct mtk_soc_data mt7986_data = { - .reg_map = &mt7986_reg_map, - .ana_rgc3 = 0x128, -@@ -4793,6 +4813,7 @@ const struct of_device_id of_mtk_match[] - { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, - { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, - { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, -+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data}, - { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, - { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, - {}, ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -553,11 +553,22 @@ - #define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 - #define SGMII_PHYA_PWD BIT(4) - -+/* Register to QPHY wrapper control */ -+#define SGMSYS_QPHY_WRAP_CTRL 0xec -+#define SGMII_PN_SWAP_MASK GENMASK(1, 0) -+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) -+#define MTK_SGMII_FLAG_PN_SWAP BIT(0) -+ - /* Infrasys subsystem config registers */ - #define INFRA_MISC2 0x70c - #define CO_QPHY_SEL BIT(0) - #define GEPHY_MAC_SEL BIT(1) - -+/* Top misc registers */ -+#define USB_PHY_SWITCH_REG 0x218 -+#define QPHY_SEL_MASK GENMASK(1, 0) -+#define SGMII_QPHY_SEL 0x2 -+ - /* MT7628/88 specific stuff */ - #define MT7628_PDMA_OFFSET 0x0800 - #define MT7628_SDM_OFFSET 0x0c00 -@@ -738,6 +749,17 @@ enum mtk_clks_map { - BIT(MTK_CLK_SGMII2_CDR_FB) | \ - BIT(MTK_CLK_SGMII_CK) | \ - BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) -+#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -+ BIT(MTK_CLK_WOCPU0) | \ -+ BIT(MTK_CLK_SGMII_TX_250M) | \ -+ BIT(MTK_CLK_SGMII_RX_250M) | \ -+ BIT(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT(MTK_CLK_SGMII2_CDR_FB) | \ -+ BIT(MTK_CLK_SGMII_CK)) - #define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ - BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ - BIT(MTK_CLK_SGMII_TX_250M) | \ -@@ -851,6 +873,7 @@ enum mkt_eth_capabilities { - MTK_NETSYS_V2_BIT, - MTK_SOC_MT7628_BIT, - MTK_RSTCTRL_PPE1_BIT, -+ MTK_U3_COPHY_V2_BIT, - - /* MUX BITS*/ - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, -@@ -885,6 +908,7 @@ enum mkt_eth_capabilities { - #define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) - #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) - #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) -+#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ - BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -@@ -957,6 +981,11 @@ enum mkt_eth_capabilities { - MTK_MUX_U3_GMAC2_TO_QPHY | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) - -+#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ -+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ -+ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ -+ MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -+ - #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -@@ -1070,12 +1099,14 @@ struct mtk_soc_data { - * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap - * @interface: Currently configured interface mode - * @pcs: Phylink PCS structure -+ * @flags: Flags indicating hardware properties - */ - struct mtk_pcs { - struct regmap *regmap; - u32 ana_rgc3; - phy_interface_t interface; - struct phylink_pcs pcs; -+ u32 flags; - }; - - /* struct mtk_sgmii - This is the structure holding sgmii regmap and its ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -87,6 +87,11 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, - SGMII_PHYA_PWD, SGMII_PHYA_PWD); - -+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP) -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, -+ SGMII_PN_SWAP_MASK, -+ SGMII_PN_SWAP_TX_RX); -+ - /* Reset SGMII PCS state */ - regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0, - SGMII_SW_RESET, SGMII_SW_RESET); -@@ -186,6 +191,11 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - - ss->pcs[i].ana_rgc3 = ana_rgc3; - ss->pcs[i].regmap = syscon_node_to_regmap(np); -+ -+ ss->pcs[i].flags = 0; -+ if (of_property_read_bool(np, "mediatek,pnswap")) -+ ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP; -+ - of_node_put(np); - if (IS_ERR(ss->pcs[i].regmap)) - return PTR_ERR(ss->pcs[i].regmap); diff --git a/target/linux/generic/backport-5.15/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch b/target/linux/generic/backport-5.15/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch deleted file mode 100644 index d4c1ecf22cc86a..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch +++ /dev/null @@ -1,76 +0,0 @@ -From c0a440031d4314d1023c1b87f43a4233634eebdb Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 19 Mar 2023 12:57:15 +0000 -Subject: [PATCH] net: ethernet: mtk_eth_soc: set MDIO bus clock frequency -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Set MDIO bus clock frequency and allow setting a custom maximum -frequency from device tree. - -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Tested-by: Bjørn Mork -Signed-off-by: Daniel Golle -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++++++++++ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 +++++++ - 2 files changed, 28 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -701,8 +701,10 @@ static const struct phylink_mac_ops mtk_ - - static int mtk_mdio_init(struct mtk_eth *eth) - { -+ unsigned int max_clk = 2500000, divider; - struct device_node *mii_np; - int ret; -+ u32 val; - - mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus"); - if (!mii_np) { -@@ -728,6 +730,25 @@ static int mtk_mdio_init(struct mtk_eth - eth->mii_bus->parent = eth->dev; - - snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np); -+ -+ if (!of_property_read_u32(mii_np, "clock-frequency", &val)) { -+ if (val > MDC_MAX_FREQ || val < MDC_MAX_FREQ / MDC_MAX_DIVIDER) { -+ dev_err(eth->dev, "MDIO clock frequency out of range"); -+ ret = -EINVAL; -+ goto err_put_node; -+ } -+ max_clk = val; -+ } -+ divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63); -+ -+ /* Configure MDC Divider */ -+ val = mtk_r32(eth, MTK_PPSC); -+ val &= ~PPSC_MDC_CFG; -+ val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO; -+ mtk_w32(eth, val, MTK_PPSC); -+ -+ dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider); -+ - ret = of_mdiobus_register(eth->mii_bus, mii_np); - - err_put_node: ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -363,6 +363,13 @@ - #define RX_DMA_VTAG_V2 BIT(0) - #define RX_DMA_L4_VALID_V2 BIT(2) - -+/* PHY Polling and SMI Master Control registers */ -+#define MTK_PPSC 0x10000 -+#define PPSC_MDC_CFG GENMASK(29, 24) -+#define PPSC_MDC_TURBO BIT(20) -+#define MDC_MAX_FREQ 25000000 -+#define MDC_MAX_DIVIDER 63 -+ - /* PHY Indirect Access Control registers */ - #define MTK_PHY_IAC 0x10004 - #define PHY_IAC_ACCESS BIT(31) diff --git a/target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch b/target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch deleted file mode 100644 index 8f7620616756c1..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch +++ /dev/null @@ -1,512 +0,0 @@ -From 2a3ec7ae313310c1092e4256208cc04d1958e469 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 19 Mar 2023 12:58:02 +0000 -Subject: [PATCH] net: ethernet: mtk_eth_soc: switch to external PCS driver - -Now that we got a PCS driver, use it and remove the now redundant -PCS code and it's header macros from the Ethernet driver. - -Signed-off-by: Daniel Golle -Tested-by: Frank Wunderlich -Reviewed-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/Kconfig | 2 + - drivers/net/ethernet/mediatek/Makefile | 2 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 61 +++++- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 93 +-------- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 217 -------------------- - 5 files changed, 56 insertions(+), 319 deletions(-) - delete mode 100644 drivers/net/ethernet/mediatek/mtk_sgmii.c - ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -18,6 +18,8 @@ config NET_MEDIATEK_SOC - select DIMLIB - select PAGE_POOL - select PAGE_POOL_STATS -+ select PCS_MTK_LYNXI -+ select REGMAP_MMIO - help - This driver supports the gigabit ethernet MACs in the - MediaTek SoC family. ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -4,7 +4,7 @@ - # - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o --mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o -+mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o - ifdef CONFIG_DEBUG_FS - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -357,7 +358,7 @@ static struct phylink_pcs *mtk_mac_selec - sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? - 0 : mac->id; - -- return mtk_sgmii_select_pcs(eth->sgmii, sid); -+ return eth->sgmii_pcs[sid]; - } - - return NULL; -@@ -3962,8 +3963,17 @@ static int mtk_unreg_dev(struct mtk_eth - return 0; - } - -+static void mtk_sgmii_destroy(struct mtk_eth *eth) -+{ -+ int i; -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) -+ mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]); -+} -+ - static int mtk_cleanup(struct mtk_eth *eth) - { -+ mtk_sgmii_destroy(eth); - mtk_unreg_dev(eth); - mtk_free_dev(eth); - cancel_work_sync(ð->pending_work); -@@ -4403,6 +4413,36 @@ void mtk_eth_set_dma_device(struct mtk_e - rtnl_unlock(); - } - -+static int mtk_sgmii_init(struct mtk_eth *eth) -+{ -+ struct device_node *np; -+ struct regmap *regmap; -+ u32 flags; -+ int i; -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i); -+ if (!np) -+ break; -+ -+ regmap = syscon_node_to_regmap(np); -+ flags = 0; -+ if (of_property_read_bool(np, "mediatek,pnswap")) -+ flags |= MTK_SGMII_FLAG_PN_SWAP; -+ -+ of_node_put(np); -+ -+ if (IS_ERR(regmap)) -+ return PTR_ERR(regmap); -+ -+ eth->sgmii_pcs[i] = mtk_pcs_lynxi_create(eth->dev, regmap, -+ eth->soc->ana_rgc3, -+ flags); -+ } -+ -+ return 0; -+} -+ - static int mtk_probe(struct platform_device *pdev) - { - struct resource *res = NULL; -@@ -4466,13 +4506,7 @@ static int mtk_probe(struct platform_dev - } - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { -- eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii), -- GFP_KERNEL); -- if (!eth->sgmii) -- return -ENOMEM; -- -- err = mtk_sgmii_init(eth->sgmii, pdev->dev.of_node, -- eth->soc->ana_rgc3); -+ err = mtk_sgmii_init(eth); - - if (err) - return err; -@@ -4483,14 +4517,17 @@ static int mtk_probe(struct platform_dev - "mediatek,pctl"); - if (IS_ERR(eth->pctl)) { - dev_err(&pdev->dev, "no pctl regmap found\n"); -- return PTR_ERR(eth->pctl); -+ err = PTR_ERR(eth->pctl); -+ goto err_destroy_sgmii; - } - } - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (!res) -- return -EINVAL; -+ if (!res) { -+ err = -EINVAL; -+ goto err_destroy_sgmii; -+ } - } - - if (eth->soc->offload_version) { -@@ -4651,6 +4688,8 @@ err_deinit_hw: - mtk_hw_deinit(eth); - err_wed_exit: - mtk_wed_exit(); -+err_destroy_sgmii: -+ mtk_sgmii_destroy(eth); - - return err; - } ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -507,65 +507,6 @@ - #define ETHSYS_DMA_AG_MAP_QDMA BIT(1) - #define ETHSYS_DMA_AG_MAP_PPE BIT(2) - --/* SGMII subsystem config registers */ --/* BMCR (low 16) BMSR (high 16) */ --#define SGMSYS_PCS_CONTROL_1 0x0 --#define SGMII_BMCR GENMASK(15, 0) --#define SGMII_BMSR GENMASK(31, 16) --#define SGMII_AN_RESTART BIT(9) --#define SGMII_ISOLATE BIT(10) --#define SGMII_AN_ENABLE BIT(12) --#define SGMII_LINK_STATYS BIT(18) --#define SGMII_AN_ABILITY BIT(19) --#define SGMII_AN_COMPLETE BIT(21) --#define SGMII_PCS_FAULT BIT(23) --#define SGMII_AN_EXPANSION_CLR BIT(30) -- --#define SGMSYS_PCS_ADVERTISE 0x8 --#define SGMII_ADVERTISE GENMASK(15, 0) --#define SGMII_LPA GENMASK(31, 16) -- --/* Register to programmable link timer, the unit in 2 * 8ns */ --#define SGMSYS_PCS_LINK_TIMER 0x18 --#define SGMII_LINK_TIMER_MASK GENMASK(19, 0) --#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK) -- --/* Register to control remote fault */ --#define SGMSYS_SGMII_MODE 0x20 --#define SGMII_IF_MODE_SGMII BIT(0) --#define SGMII_SPEED_DUPLEX_AN BIT(1) --#define SGMII_SPEED_MASK GENMASK(3, 2) --#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) --#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) --#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) --#define SGMII_DUPLEX_HALF BIT(4) --#define SGMII_IF_MODE_BIT5 BIT(5) --#define SGMII_REMOTE_FAULT_DIS BIT(8) --#define SGMII_CODE_SYNC_SET_VAL BIT(9) --#define SGMII_CODE_SYNC_SET_EN BIT(10) --#define SGMII_SEND_AN_ERROR_EN BIT(11) --#define SGMII_IF_MODE_MASK GENMASK(5, 1) -- --/* Register to reset SGMII design */ --#define SGMII_RESERVED_0 0x34 --#define SGMII_SW_RESET BIT(0) -- --/* Register to set SGMII speed, ANA RG_ Control Signals III*/ --#define SGMSYS_ANA_RG_CS3 0x2028 --#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3)) --#define RG_PHY_SPEED_1_25G 0x0 --#define RG_PHY_SPEED_3_125G BIT(2) -- --/* Register to power up QPHY */ --#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 --#define SGMII_PHYA_PWD BIT(4) -- --/* Register to QPHY wrapper control */ --#define SGMSYS_QPHY_WRAP_CTRL 0xec --#define SGMII_PN_SWAP_MASK GENMASK(1, 0) --#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) --#define MTK_SGMII_FLAG_PN_SWAP BIT(0) -- - /* Infrasys subsystem config registers */ - #define INFRA_MISC2 0x70c - #define CO_QPHY_SEL BIT(0) -@@ -1099,31 +1040,6 @@ struct mtk_soc_data { - /* currently no SoC has more than 2 macs */ - #define MTK_MAX_DEVS 2 - --/* struct mtk_pcs - This structure holds each sgmii regmap and associated -- * data -- * @regmap: The register map pointing at the range used to setup -- * SGMII modes -- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap -- * @interface: Currently configured interface mode -- * @pcs: Phylink PCS structure -- * @flags: Flags indicating hardware properties -- */ --struct mtk_pcs { -- struct regmap *regmap; -- u32 ana_rgc3; -- phy_interface_t interface; -- struct phylink_pcs pcs; -- u32 flags; --}; -- --/* struct mtk_sgmii - This is the structure holding sgmii regmap and its -- * characteristics -- * @pcs Array of individual PCS structures -- */ --struct mtk_sgmii { -- struct mtk_pcs pcs[MTK_MAX_DEVS]; --}; -- - /* struct mtk_eth - This is the main datasructure for holding the state - * of the driver - * @dev: The device pointer -@@ -1143,6 +1059,7 @@ struct mtk_sgmii { - * MII modes - * @infra: The register map pointing at the range used to setup - * SGMII and GePHY path -+ * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances - * @pctl: The register map pointing at the range used to setup - * GMAC port drive/slew values - * @dma_refcnt: track how many netdevs are using the DMA engine -@@ -1183,8 +1100,8 @@ struct mtk_eth { - u32 msg_enable; - unsigned long sysclk; - struct regmap *ethsys; -- struct regmap *infra; -- struct mtk_sgmii *sgmii; -+ struct regmap *infra; -+ struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS]; - struct regmap *pctl; - bool hwlro; - refcount_t dma_refcnt; -@@ -1346,10 +1263,6 @@ void mtk_stats_update_mac(struct mtk_mac - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); - u32 mtk_r32(struct mtk_eth *eth, unsigned reg); - --struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id); --int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np, -- u32 ana_rgc3); -- - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ /dev/null -@@ -1,217 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --// Copyright (c) 2018-2019 MediaTek Inc. -- --/* A library for MediaTek SGMII circuit -- * -- * Author: Sean Wang -- * -- */ -- --#include --#include --#include --#include -- --#include "mtk_eth_soc.h" -- --static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs) --{ -- return container_of(pcs, struct mtk_pcs, pcs); --} -- --static void mtk_pcs_get_state(struct phylink_pcs *pcs, -- struct phylink_link_state *state) --{ -- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- unsigned int bm, adv; -- -- /* Read the BMSR and LPA */ -- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); -- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -- -- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), -- FIELD_GET(SGMII_LPA, adv)); --} -- --static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -- phy_interface_t interface, -- const unsigned long *advertising, -- bool permit_pause_to_mac) --{ -- bool mode_changed = false, changed, use_an; -- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- unsigned int rgc3, sgm_mode, bmcr; -- int advertise, link_timer; -- -- advertise = phylink_mii_c22_pcs_encode_advertisement(interface, -- advertising); -- if (advertise < 0) -- return advertise; -- -- /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and -- * we assume that fixes it's speed at bitrate = line rate (in -- * other words, 1000Mbps or 2500Mbps). -- */ -- if (interface == PHY_INTERFACE_MODE_SGMII) { -- sgm_mode = SGMII_IF_MODE_SGMII; -- if (phylink_autoneg_inband(mode)) { -- sgm_mode |= SGMII_REMOTE_FAULT_DIS | -- SGMII_SPEED_DUPLEX_AN; -- use_an = true; -- } else { -- use_an = false; -- } -- } else if (phylink_autoneg_inband(mode)) { -- /* 1000base-X or 2500base-X autoneg */ -- sgm_mode = SGMII_REMOTE_FAULT_DIS; -- use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -- advertising); -- } else { -- /* 1000base-X or 2500base-X without autoneg */ -- sgm_mode = 0; -- use_an = false; -- } -- -- if (use_an) { -- bmcr = SGMII_AN_ENABLE; -- } else { -- bmcr = 0; -- } -- -- if (mpcs->interface != interface) { -- link_timer = phylink_get_link_timer_ns(interface); -- if (link_timer < 0) -- return link_timer; -- -- /* PHYA power down */ -- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -- SGMII_PHYA_PWD, SGMII_PHYA_PWD); -- -- if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP) -- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, -- SGMII_PN_SWAP_MASK, -- SGMII_PN_SWAP_TX_RX); -- -- /* Reset SGMII PCS state */ -- regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0, -- SGMII_SW_RESET, SGMII_SW_RESET); -- -- if (interface == PHY_INTERFACE_MODE_2500BASEX) -- rgc3 = RG_PHY_SPEED_3_125G; -- else -- rgc3 = 0; -- -- /* Configure the underlying interface speed */ -- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -- RG_PHY_SPEED_3_125G, rgc3); -- -- /* Setup the link timer */ -- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); -- -- mpcs->interface = interface; -- mode_changed = true; -- } -- -- /* Update the advertisement, noting whether it has changed */ -- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, -- SGMII_ADVERTISE, advertise, &changed); -- -- /* Update the sgmsys mode register */ -- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | -- SGMII_IF_MODE_SGMII, sgm_mode); -- -- /* Update the BMCR */ -- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -- SGMII_AN_ENABLE, bmcr); -- -- /* Release PHYA power down state -- * Only removing bit SGMII_PHYA_PWD isn't enough. -- * There are cases when the SGMII_PHYA_PWD register contains 0x9 which -- * prevents SGMII from working. The SGMII still shows link but no traffic -- * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was -- * taken from a good working state of the SGMII interface. -- * Unknown how much the QPHY needs but it is racy without a sleep. -- * Tested on mt7622 & mt7986. -- */ -- usleep_range(50, 100); -- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); -- -- return changed || mode_changed; --} -- --static void mtk_pcs_restart_an(struct phylink_pcs *pcs) --{ -- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- -- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -- SGMII_AN_RESTART, SGMII_AN_RESTART); --} -- --static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -- phy_interface_t interface, int speed, int duplex) --{ -- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- unsigned int sgm_mode; -- -- if (!phylink_autoneg_inband(mode)) { -- /* Force the speed and duplex setting */ -- if (speed == SPEED_10) -- sgm_mode = SGMII_SPEED_10; -- else if (speed == SPEED_100) -- sgm_mode = SGMII_SPEED_100; -- else -- sgm_mode = SGMII_SPEED_1000; -- -- if (duplex != DUPLEX_FULL) -- sgm_mode |= SGMII_DUPLEX_HALF; -- -- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, -- sgm_mode); -- } --} -- --static const struct phylink_pcs_ops mtk_pcs_ops = { -- .pcs_get_state = mtk_pcs_get_state, -- .pcs_config = mtk_pcs_config, -- .pcs_an_restart = mtk_pcs_restart_an, -- .pcs_link_up = mtk_pcs_link_up, --}; -- --int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) --{ -- struct device_node *np; -- int i; -- -- for (i = 0; i < MTK_MAX_DEVS; i++) { -- np = of_parse_phandle(r, "mediatek,sgmiisys", i); -- if (!np) -- break; -- -- ss->pcs[i].ana_rgc3 = ana_rgc3; -- ss->pcs[i].regmap = syscon_node_to_regmap(np); -- -- ss->pcs[i].flags = 0; -- if (of_property_read_bool(np, "mediatek,pnswap")) -- ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP; -- -- of_node_put(np); -- if (IS_ERR(ss->pcs[i].regmap)) -- return PTR_ERR(ss->pcs[i].regmap); -- -- ss->pcs[i].pcs.ops = &mtk_pcs_ops; -- ss->pcs[i].pcs.poll = true; -- ss->pcs[i].interface = PHY_INTERFACE_MODE_NA; -- } -- -- return 0; --} -- --struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id) --{ -- if (!ss->pcs[id].regmap) -- return NULL; -- -- return &ss->pcs[id].pcs; --} diff --git a/target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch b/target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch deleted file mode 100644 index 7742b0925bc3c9..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Felix Fietkau -Date: Thu, 23 Mar 2023 11:19:14 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add missing ppe cache flush when - deleting a flow - -The cache needs to be flushed to ensure that the hardware stops offloading -the flow immediately. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -464,6 +464,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - hwe->ib1 &= ~MTK_FOE_IB1_STATE; - hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); - dma_wmb(); -+ mtk_ppe_cache_clear(ppe); - } - entry->hash = 0xffff; - diff --git a/target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch b/target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch deleted file mode 100644 index 9ce2735951c897..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch +++ /dev/null @@ -1,46 +0,0 @@ -From f5af7931d2a2cae66d0f9dad4ba517b1b00620b3 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 19 Apr 2023 19:07:23 +0100 -Subject: [PATCH] net: mtk_eth_soc: use WO firmware for MT7981 - -In order to support wireless offloading on MT7981 we need to load the -appropriate firmware. Recognize MT7981 and load mt7981_wo.bin. - -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 7 ++++++- - drivers/net/ethernet/mediatek/mtk_wed_wo.h | 1 + - 2 files changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -326,7 +326,11 @@ mtk_wed_mcu_load_firmware(struct mtk_wed - wo->hw->index + 1); - - /* load firmware */ -- fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; -+ if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed")) -+ fw_name = MT7981_FIRMWARE_WO; -+ else -+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; -+ - ret = request_firmware(&fw, fw_name, wo->hw->dev); - if (ret) - return ret; -@@ -386,5 +390,6 @@ int mtk_wed_mcu_init(struct mtk_wed_wo * - 100, MTK_FW_DL_TIMEOUT); - } - -+MODULE_FIRMWARE(MT7981_FIRMWARE_WO); - MODULE_FIRMWARE(MT7986_FIRMWARE_WO0); - MODULE_FIRMWARE(MT7986_FIRMWARE_WO1); ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -88,6 +88,7 @@ enum mtk_wed_dummy_cr_idx { - MTK_WED_DUMMY_CR_WO_STATUS, - }; - -+#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin" - #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" - #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" - diff --git a/target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch b/target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch deleted file mode 100644 index d715c4aa6867b9..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 7c83e28f10830aa5105c25eaabe890e3adac36aa Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 9 May 2023 03:20:06 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix NULL pointer dereference - -Check for NULL pointer to avoid kernel crashing in case of missing WO -firmware in case only a single WEDv2 device has been initialized, e.g. on -MT7981 which can connect just one wireless frontend. - -Fixes: 86ce0d09e424 ("net: ethernet: mtk_eth_soc: use WO firmware for MT7981") -Signed-off-by: Daniel Golle -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -647,7 +647,7 @@ __mtk_wed_detach(struct mtk_wed_device * - BIT(hw->index), BIT(hw->index)); - } - -- if (!hw_list[!hw->index]->wed_dev && -+ if ((!hw_list[!hw->index] || !hw_list[!hw->index]->wed_dev) && - hw->eth->dma_dev != hw->eth->dev) - mtk_eth_set_dma_device(hw->eth, hw->eth->dev); - diff --git a/target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch b/target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch deleted file mode 100644 index e4022ffbdf7c18..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch +++ /dev/null @@ -1,428 +0,0 @@ -From patchwork Wed Nov 2 00:58:01 2022 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 13027653 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -Date: Wed, 2 Nov 2022 00:58:01 +0000 -From: Daniel Golle -To: Felix Fietkau , John Crispin , - Sean Wang , - Mark Lee , - "David S. Miller" , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Matthias Brugger , - netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org -Subject: [PATCH v4] net: ethernet: mediatek: ppe: add support for flow - accounting -Message-ID: -MIME-Version: 1.0 -Content-Disposition: inline -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -The PPE units found in MT7622 and newer support packet and byte -accounting of hw-offloaded flows. Add support for reading those -counters as found in MediaTek's SDK[1]. - -[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92 -Signed-off-by: Daniel Golle ---- -v4: declare function mtk_mib_entry_read as static -v3: don't bother to set 'false' values in any zero-initialized struct - use mtk_foe_entry_ib2 - both changes were requested by Felix Fietkau - -v2: fix wrong variable name in return value check spotted by Denis Kirjanov - - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 7 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - drivers/net/ethernet/mediatek/mtk_ppe.c | 110 +++++++++++++++++- - drivers/net/ethernet/mediatek/mtk_ppe.h | 23 +++- - .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 9 +- - .../net/ethernet/mediatek/mtk_ppe_offload.c | 7 ++ - drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 14 +++ - 7 files changed, 166 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4637,8 +4637,8 @@ static int mtk_probe(struct platform_dev - for (i = 0; i < num_ppe; i++) { - u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; - -- eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, -- eth->soc->offload_version, i); -+ eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i); -+ - if (!eth->ppe[i]) { - err = -ENOMEM; - goto err_deinit_ppe; -@@ -4764,6 +4764,7 @@ static const struct mtk_soc_data mt7622_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 2, -+ .has_accounting = true, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -@@ -4801,6 +4802,7 @@ static const struct mtk_soc_data mt7629_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7629_CLKS_BITMAP, - .required_pctl = false, -+ .has_accounting = true, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4821,6 +4823,7 @@ static const struct mtk_soc_data mt7981_ - .offload_version = 2, - .hash_offset = 4, - .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .has_accounting = true, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), -@@ -4841,6 +4844,7 @@ static const struct mtk_soc_data mt7986_ - .offload_version = 2, - .hash_offset = 4, - .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .has_accounting = true, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1008,6 +1008,8 @@ struct mtk_reg_map { - * the extra setup for those pins used by GMAC. - * @hash_offset Flow table hash offset. - * @foe_entry_size Foe table entry size. -+ * @has_accounting Bool indicating support for accounting of -+ * offloaded flows. - * @txd_size Tx DMA descriptor size. - * @rxd_size Rx DMA descriptor size. - * @rx_irq_done_mask Rx irq done register mask. -@@ -1025,6 +1027,7 @@ struct mtk_soc_data { - u8 hash_offset; - u16 foe_entry_size; - netdev_features_t hw_features; -+ bool has_accounting; - struct { - u32 txd_size; - u32 rxd_size; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_ - return ret; - } - -+static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe) -+{ -+ int ret; -+ u32 val; -+ -+ ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val, -+ !(val & MTK_PPE_MIB_SER_CR_ST), -+ 20, MTK_PPE_WAIT_TIMEOUT_US); -+ -+ if (ret) -+ dev_err(ppe->dev, "MIB table busy"); -+ -+ return ret; -+} -+ -+static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) -+{ -+ u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high; -+ u32 val, cnt_r0, cnt_r1, cnt_r2; -+ int ret; -+ -+ val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST; -+ ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val); -+ -+ ret = mtk_ppe_mib_wait_busy(ppe); -+ if (ret) -+ return ret; -+ -+ cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0); -+ cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); -+ cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2); -+ -+ byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); -+ byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); -+ pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); -+ pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -+ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -+ *packets = (pkt_cnt_high << 16) | pkt_cnt_low; -+ -+ return 0; -+} -+ - static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) - { - ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR); -@@ -465,6 +507,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); - dma_wmb(); - mtk_ppe_cache_clear(ppe); -+ if (ppe->accounting) { -+ struct mtk_foe_accounting *acct; -+ -+ acct = ppe->acct_table + entry->hash * sizeof(*acct); -+ acct->packets = 0; -+ acct->bytes = 0; -+ } - } - entry->hash = 0xffff; - -@@ -572,6 +621,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - wmb(); - hwe->ib1 = entry->ib1; - -+ if (ppe->accounting) -+ *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT; -+ - dma_wmb(); - - mtk_ppe_cache_clear(ppe); -@@ -763,11 +815,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe - return mtk_ppe_wait_busy(ppe); - } - --struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, -- int version, int index) -+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -+ struct mtk_foe_accounting *diff) -+{ -+ struct mtk_foe_accounting *acct; -+ int size = sizeof(struct mtk_foe_accounting); -+ u64 bytes, packets; -+ -+ if (!ppe->accounting) -+ return NULL; -+ -+ if (mtk_mib_entry_read(ppe, index, &bytes, &packets)) -+ return NULL; -+ -+ acct = ppe->acct_table + index * size; -+ -+ acct->bytes += bytes; -+ acct->packets += packets; -+ -+ if (diff) { -+ diff->bytes = bytes; -+ diff->packets = packets; -+ } -+ -+ return acct; -+} -+ -+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) - { -+ bool accounting = eth->soc->has_accounting; - const struct mtk_soc_data *soc = eth->soc; -+ struct mtk_foe_accounting *acct; - struct device *dev = eth->dev; -+ struct mtk_mib_entry *mib; - struct mtk_ppe *ppe; - u32 foe_flow_size; - void *foe; -@@ -784,7 +864,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - ppe->base = base; - ppe->eth = eth; - ppe->dev = dev; -- ppe->version = version; -+ ppe->version = eth->soc->offload_version; -+ ppe->accounting = accounting; - - foe = dmam_alloc_coherent(ppe->dev, - MTK_PPE_ENTRIES * soc->foe_entry_size, -@@ -800,6 +881,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - if (!ppe->foe_flow) - goto err_free_l2_flows; - -+ if (accounting) { -+ mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib), -+ &ppe->mib_phys, GFP_KERNEL); -+ if (!mib) -+ return NULL; -+ -+ ppe->mib_table = mib; -+ -+ acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct), -+ GFP_KERNEL); -+ -+ if (!acct) -+ return NULL; -+ -+ ppe->acct_table = acct; -+ } -+ - mtk_ppe_debugfs_init(ppe, index); - - return ppe; -@@ -929,6 +1027,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); - ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); - } -+ -+ if (ppe->accounting && ppe->mib_phys) { -+ ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys); -+ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN, -+ MTK_PPE_MIB_CFG_EN); -+ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR, -+ MTK_PPE_MIB_CFG_RD_CLR); -+ ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN, -+ MTK_PPE_MIB_CFG_RD_CLR); -+ } - } - - int mtk_ppe_stop(struct mtk_ppe *ppe) ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -57,6 +57,7 @@ enum { - #define MTK_FOE_IB2_MULTICAST BIT(8) - - #define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12) -+#define MTK_FOE_IB2_MIB_CNT BIT(15) - #define MTK_FOE_IB2_WDMA_DEVIDX BIT(16) - #define MTK_FOE_IB2_WDMA_WINFO BIT(17) - -@@ -285,16 +286,34 @@ struct mtk_flow_entry { - unsigned long cookie; - }; - -+struct mtk_mib_entry { -+ u32 byt_cnt_l; -+ u16 byt_cnt_h; -+ u32 pkt_cnt_l; -+ u8 pkt_cnt_h; -+ u8 _rsv0; -+ u32 _rsv1; -+} __packed; -+ -+struct mtk_foe_accounting { -+ u64 bytes; -+ u64 packets; -+}; -+ - struct mtk_ppe { - struct mtk_eth *eth; - struct device *dev; - void __iomem *base; - int version; - char dirname[5]; -+ bool accounting; - - void *foe_table; - dma_addr_t foe_phys; - -+ struct mtk_mib_entry *mib_table; -+ dma_addr_t mib_phys; -+ - u16 foe_check_time[MTK_PPE_ENTRIES]; - struct hlist_head *foe_flow; - -@@ -303,8 +322,7 @@ struct mtk_ppe { - void *acct_table; - }; - --struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, -- int version, int index); -+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index); - void mtk_ppe_deinit(struct mtk_eth *eth); - void mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); -@@ -359,5 +377,7 @@ int mtk_foe_entry_commit(struct mtk_ppe - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); -+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -+ struct mtk_foe_accounting *diff); - - #endif ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file - struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i); - struct mtk_foe_mac_info *l2; - struct mtk_flow_addr_info ai = {}; -+ struct mtk_foe_accounting *acct; - unsigned char h_source[ETH_ALEN]; - unsigned char h_dest[ETH_ALEN]; - int type, state; -@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file - if (bind && state != MTK_FOE_STATE_BIND) - continue; - -+ acct = mtk_foe_entry_get_mib(ppe, i, NULL); -+ - type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); - seq_printf(m, "%05x %s %7s", i, - mtk_foe_entry_state_str(state), -@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file - *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo); - - seq_printf(m, " eth=%pM->%pM etype=%04x" -- " vlan=%d,%d ib1=%08x ib2=%08x\n", -+ " vlan=%d,%d ib1=%08x ib2=%08x" -+ " packets=%llu bytes=%llu\n", - h_source, h_dest, ntohs(l2->etype), -- l2->vlan1, l2->vlan2, entry->ib1, ib2); -+ l2->vlan1, l2->vlan2, entry->ib1, ib2, -+ acct ? acct->packets : 0, acct ? acct->bytes : 0); - } - - return 0; ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -497,6 +497,7 @@ static int - mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) - { - struct mtk_flow_entry *entry; -+ struct mtk_foe_accounting diff; - u32 idle; - - entry = rhashtable_lookup(ð->flow_table, &f->cookie, -@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *e - idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); - f->stats.lastused = jiffies - idle * HZ; - -+ if (entry->hash != 0xFFFF && -+ mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash, -+ &diff)) { -+ f->stats.pkts += diff.packets; -+ f->stats.bytes += diff.bytes; -+ } -+ - return 0; - } - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -@@ -149,6 +149,20 @@ enum { - - #define MTK_PPE_MIB_TB_BASE 0x338 - -+#define MTK_PPE_MIB_SER_CR 0x33C -+#define MTK_PPE_MIB_SER_CR_ST BIT(16) -+#define MTK_PPE_MIB_SER_CR_ADDR GENMASK(13, 0) -+ -+#define MTK_PPE_MIB_SER_R0 0x340 -+#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW GENMASK(31, 0) -+ -+#define MTK_PPE_MIB_SER_R1 0x344 -+#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW GENMASK(31, 16) -+#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH GENMASK(15, 0) -+ -+#define MTK_PPE_MIB_SER_R2 0x348 -+#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0) -+ - #define MTK_PPE_MIB_CACHE_CTL 0x350 - #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) - #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) diff --git a/target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch deleted file mode 100644 index 3a02c3a718f40f..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: Felix Fietkau -Date: Thu, 23 Mar 2023 21:45:43 +0100 -Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for v1 - hardware - -Older chips (like MT7622) use a different bit in ib2 to enable hardware -counter support. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -605,6 +605,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - struct mtk_eth *eth = ppe->eth; - u16 timestamp = mtk_eth_timestamp(eth); - struct mtk_foe_entry *hwe; -+ u32 val; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; -@@ -621,8 +622,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - wmb(); - hwe->ib1 = entry->ib1; - -- if (ppe->accounting) -- *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT; -+ if (ppe->accounting) { -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ val = MTK_FOE_IB2_MIB_CNT_V2; -+ else -+ val = MTK_FOE_IB2_MIB_CNT; -+ *mtk_foe_entry_ib2(eth, hwe) |= val; -+ } - - dma_wmb(); - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -55,9 +55,10 @@ enum { - #define MTK_FOE_IB2_PSE_QOS BIT(4) - #define MTK_FOE_IB2_DEST_PORT GENMASK(7, 5) - #define MTK_FOE_IB2_MULTICAST BIT(8) -+#define MTK_FOE_IB2_MIB_CNT BIT(10) - - #define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12) --#define MTK_FOE_IB2_MIB_CNT BIT(15) -+#define MTK_FOE_IB2_MIB_CNT_V2 BIT(15) - #define MTK_FOE_IB2_WDMA_DEVIDX BIT(16) - #define MTK_FOE_IB2_WDMA_WINFO BIT(17) - diff --git a/target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch deleted file mode 100644 index 8be6a699214e4b..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch +++ /dev/null @@ -1,201 +0,0 @@ -From: Felix Fietkau -Date: Sun, 20 Nov 2022 23:01:00 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: drop generic vlan rx offload, - only use DSA untagging - -Through testing I found out that hardware vlan rx offload support seems to -have some hardware issues. At least when using multiple MACs and when receiving -tagged packets on the secondary MAC, the hardware can sometimes start to emit -wrong tags on the first MAC as well. - -In order to avoid such issues, drop the feature configuration and use the -offload feature only for DSA hardware untagging on MT7621/MT7622 devices which -only use one MAC. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1849,9 +1849,7 @@ static int mtk_poll_rx(struct napi_struc - - while (done < budget) { - unsigned int pktlen, *rxdcsum; -- bool has_hwaccel_tag = false; - struct net_device *netdev; -- u16 vlan_proto, vlan_tci; - dma_addr_t dma_addr; - u32 hash, reason; - int mac = 0; -@@ -1986,36 +1984,21 @@ static int mtk_poll_rx(struct napi_struc - skb_checksum_none_assert(skb); - skb->protocol = eth_type_trans(skb, netdev); - -- if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -- mtk_ppe_check_skb(eth->ppe[0], skb, hash); -- -- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -- if (trxd.rxd3 & RX_DMA_VTAG_V2) { -- vlan_proto = RX_DMA_VPID(trxd.rxd4); -- vlan_tci = RX_DMA_VID(trxd.rxd4); -- has_hwaccel_tag = true; -- } -- } else if (trxd.rxd2 & RX_DMA_VTAG) { -- vlan_proto = RX_DMA_VPID(trxd.rxd3); -- vlan_tci = RX_DMA_VID(trxd.rxd3); -- has_hwaccel_tag = true; -- } -- } -- - /* When using VLAN untagging in combination with DSA, the - * hardware treats the MTK special tag as a VLAN and untags it. - */ -- if (has_hwaccel_tag && netdev_uses_dsa(netdev)) { -- unsigned int port = vlan_proto & GENMASK(2, 0); -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && -+ (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) { -+ unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0); - - if (port < ARRAY_SIZE(eth->dsa_meta) && - eth->dsa_meta[port]) - skb_dst_set_noref(skb, ð->dsa_meta[port]->dst); -- } else if (has_hwaccel_tag) { -- __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci); - } - -+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -+ mtk_ppe_check_skb(eth->ppe[0], skb, hash); -+ - skb_record_rx_queue(skb, 0); - napi_gro_receive(napi, skb); - -@@ -2833,29 +2816,11 @@ static netdev_features_t mtk_fix_feature - - static int mtk_set_features(struct net_device *dev, netdev_features_t features) - { -- struct mtk_mac *mac = netdev_priv(dev); -- struct mtk_eth *eth = mac->hw; - netdev_features_t diff = dev->features ^ features; -- int i; - - if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO)) - mtk_hwlro_netdev_disable(dev); - -- /* Set RX VLAN offloading */ -- if (!(diff & NETIF_F_HW_VLAN_CTAG_RX)) -- return 0; -- -- mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX), -- MTK_CDMP_EG_CTRL); -- -- /* sync features with other MAC */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!eth->netdev[i] || eth->netdev[i] == dev) -- continue; -- eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX; -- eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX; -- } -- - return 0; - } - -@@ -3169,30 +3134,6 @@ static int mtk_open(struct net_device *d - struct mtk_eth *eth = mac->hw; - int i, err; - -- if (mtk_uses_dsa(dev) && !eth->prog) { -- for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { -- struct metadata_dst *md_dst = eth->dsa_meta[i]; -- -- if (md_dst) -- continue; -- -- md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, -- GFP_KERNEL); -- if (!md_dst) -- return -ENOMEM; -- -- md_dst->u.port_info.port_id = i; -- eth->dsa_meta[i] = md_dst; -- } -- } else { -- /* Hardware special tag parsing needs to be disabled if at least -- * one MAC does not use DSA. -- */ -- u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); -- val &= ~MTK_CDMP_STAG_EN; -- mtk_w32(eth, val, MTK_CDMP_IG_CTRL); -- } -- - err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); - if (err) { - netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -@@ -3233,6 +3174,35 @@ static int mtk_open(struct net_device *d - phylink_start(mac->phylink); - netif_tx_start_all_queues(dev); - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return 0; -+ -+ if (mtk_uses_dsa(dev) && !eth->prog) { -+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { -+ struct metadata_dst *md_dst = eth->dsa_meta[i]; -+ -+ if (md_dst) -+ continue; -+ -+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, -+ GFP_KERNEL); -+ if (!md_dst) -+ return -ENOMEM; -+ -+ md_dst->u.port_info.port_id = i; -+ eth->dsa_meta[i] = md_dst; -+ } -+ } else { -+ /* Hardware special tag parsing needs to be disabled if at least -+ * one MAC does not use DSA. -+ */ -+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); -+ val &= ~MTK_CDMP_STAG_EN; -+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL); -+ -+ mtk_w32(eth, 0, MTK_CDMP_EG_CTRL); -+ } -+ - return 0; - } - -@@ -3717,10 +3687,9 @@ static int mtk_hw_init(struct mtk_eth *e - if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); -- } - -- /* Enable RX VLan Offloading */ -- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -+ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -+ } - - /* set interrupt delays based on current Net DIM sample */ - mtk_dim_rx(ð->rx_dim.work); -@@ -4360,7 +4329,7 @@ static int mtk_add_mac(struct mtk_eth *e - eth->netdev[id]->hw_features |= NETIF_F_LRO; - - eth->netdev[id]->vlan_features = eth->soc->hw_features & -- ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX); -+ ~NETIF_F_HW_VLAN_CTAG_TX; - eth->netdev[id]->features |= eth->soc->hw_features; - eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops; - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -48,7 +48,6 @@ - #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \ - NETIF_F_RXCSUM | \ - NETIF_F_HW_VLAN_CTAG_TX | \ -- NETIF_F_HW_VLAN_CTAG_RX | \ - NETIF_F_SG | NETIF_F_TSO | \ - NETIF_F_TSO6 | \ - NETIF_F_IPV6_CSUM |\ diff --git a/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch b/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch deleted file mode 100644 index 2704faec12b011..00000000000000 --- a/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b804f765485109f9644cc05d1e8fc79ca6c6e4aa Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 19 Jul 2023 01:39:36 +0100 -Subject: [PATCH 094/250] net: ethernet: mtk_eth_soc: always - mtk_get_ib1_pkt_type - -entries and bind debugfs files would display wrong data on NETSYS_V2 and -later because instead of using mtk_get_ib1_pkt_type the driver would use -MTK_FOE_IB1_PACKET_TYPE which corresponds to NETSYS_V1(.x) SoCs. -Use mtk_get_ib1_pkt_type so entries and bind records display correctly. - -Fixes: 03a3180e5c09e ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986") -Signed-off-by: Daniel Golle -Acked-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/c0ae03d0182f4d27b874cbdf0059bc972c317f3c.1689727134.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file - - acct = mtk_foe_entry_get_mib(ppe, i, NULL); - -- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); -+ type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); - seq_printf(m, "%05x %s %7s", i, - mtk_foe_entry_state_str(state), - mtk_foe_pkt_type_str(type)); diff --git a/target/linux/generic/backport-5.15/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch b/target/linux/generic/backport-5.15/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch deleted file mode 100644 index 6788a2ec350e2f..00000000000000 --- a/target/linux/generic/backport-5.15/734-v5.16-0001-net-bgmac-improve-handling-PHY.patch +++ /dev/null @@ -1,84 +0,0 @@ -From b5375509184dc23d2b7fa0c5ed8763899ccc9674 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 2 Oct 2021 19:58:11 +0200 -Subject: [PATCH] net: bgmac: improve handling PHY -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -1. Use info from DT if available - -It allows describing for example a fixed link. It's more accurate than -just guessing there may be one (depending on a chipset). - -2. Verify PHY ID before trying to connect PHY - -PHY addr 0x1e (30) is special in Broadcom routers and means a switch -connected as MDIO devices instead of a real PHY. Don't try connecting to -it. - -Signed-off-by: Rafał Miłecki -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/broadcom/bgmac-bcma.c | 33 ++++++++++++++-------- - 1 file changed, 21 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c -+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include "bgmac.h" - -@@ -86,17 +87,28 @@ static int bcma_phy_connect(struct bgmac - struct phy_device *phy_dev; - char bus_id[MII_BUS_ID_SIZE + 3]; - -+ /* DT info should be the most accurate */ -+ phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, -+ bgmac_adjust_link); -+ if (phy_dev) -+ return 0; -+ - /* Connect to the PHY */ -- snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id, -- bgmac->phyaddr); -- phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link, -- PHY_INTERFACE_MODE_MII); -- if (IS_ERR(phy_dev)) { -- dev_err(bgmac->dev, "PHY connection failed\n"); -- return PTR_ERR(phy_dev); -+ if (bgmac->mii_bus && bgmac->phyaddr != BGMAC_PHY_NOREGS) { -+ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, bgmac->mii_bus->id, -+ bgmac->phyaddr); -+ phy_dev = phy_connect(bgmac->net_dev, bus_id, bgmac_adjust_link, -+ PHY_INTERFACE_MODE_MII); -+ if (IS_ERR(phy_dev)) { -+ dev_err(bgmac->dev, "PHY connection failed\n"); -+ return PTR_ERR(phy_dev); -+ } -+ -+ return 0; - } - -- return 0; -+ /* Assume a fixed link to the switch port */ -+ return bgmac_phy_connect_direct(bgmac); - } - - static const struct bcma_device_id bgmac_bcma_tbl[] = { -@@ -297,10 +309,7 @@ static int bgmac_probe(struct bcma_devic - bgmac->cco_ctl_maskset = bcma_bgmac_cco_ctl_maskset; - bgmac->get_bus_clock = bcma_bgmac_get_bus_clock; - bgmac->cmn_maskset32 = bcma_bgmac_cmn_maskset32; -- if (bgmac->mii_bus) -- bgmac->phy_connect = bcma_phy_connect; -- else -- bgmac->phy_connect = bgmac_phy_connect_direct; -+ bgmac->phy_connect = bcma_phy_connect; - - err = bgmac_enet_probe(bgmac); - if (err) diff --git a/target/linux/generic/backport-5.15/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch b/target/linux/generic/backport-5.15/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch deleted file mode 100644 index f1348282739df0..00000000000000 --- a/target/linux/generic/backport-5.15/734-v5.16-0002-net-bgmac-support-MDIO-described-in-DT.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 45c9d966688e7fad7f24bfc450547d91e4304d0b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 2 Oct 2021 19:58:12 +0200 -Subject: [PATCH] net: bgmac: support MDIO described in DT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Check ethernet controller DT node for "mdio" subnode and use it with -of_mdiobus_register() when present. That allows specifying MDIO and its -PHY devices in a standard DT based way. - -This is required for BCM53573 SoC support. That family is sometimes -called Northstar (by marketing?) but is quite different from it. It uses -different CPU(s) and many different hw blocks. - -One of shared blocks in BCM53573 is Ethernet controller. Switch however -is not SRAB accessible (as it Northstar) but is MDIO attached. - -Signed-off-by: Rafał Miłecki -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c -+++ b/drivers/net/ethernet/broadcom/bgmac-bcma-mdio.c -@@ -10,6 +10,7 @@ - - #include - #include -+#include - #include "bgmac.h" - - static bool bcma_mdio_wait_value(struct bcma_device *core, u16 reg, u32 mask, -@@ -211,6 +212,7 @@ struct mii_bus *bcma_mdio_mii_register(s - { - struct bcma_device *core = bgmac->bcma.core; - struct mii_bus *mii_bus; -+ struct device_node *np; - int err; - - mii_bus = mdiobus_alloc(); -@@ -229,7 +231,9 @@ struct mii_bus *bcma_mdio_mii_register(s - mii_bus->parent = &core->dev; - mii_bus->phy_mask = ~(1 << bgmac->phyaddr); - -- err = mdiobus_register(mii_bus); -+ np = of_get_child_by_name(core->dev.of_node, "mdio"); -+ -+ err = of_mdiobus_register(mii_bus, np); - if (err) { - dev_err(&core->dev, "Registration of mii bus failed\n"); - goto err_free_bus; diff --git a/target/linux/generic/backport-5.15/735-v6.0-0001-net-phy-Add-support-for-AQR113C-EPHY.patch b/target/linux/generic/backport-5.15/735-v6.0-0001-net-phy-Add-support-for-AQR113C-EPHY.patch deleted file mode 100644 index 6090a40eaee41e..00000000000000 --- a/target/linux/generic/backport-5.15/735-v6.0-0001-net-phy-Add-support-for-AQR113C-EPHY.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 12cf1b89a66828719b2135891b65bd5d03eedea9 Mon Sep 17 00:00:00 2001 -From: Bhadram Varka -Date: Tue, 21 Jun 2022 09:10:27 +0530 -Subject: [PATCH] net: phy: Add support for AQR113C EPHY - -Add support multi-gigabit and single-port Ethernet -PHY transceiver (AQR113C). - -Signed-off-by: Bhadram Varka -Link: https://lore.kernel.org/r/20220621034027.56508-1-vbhadram@nvidia.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/aquantia_main.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - ---- a/drivers/net/phy/aquantia_main.c -+++ b/drivers/net/phy/aquantia_main.c -@@ -22,6 +22,7 @@ - #define PHY_ID_AQR107 0x03a1b4e0 - #define PHY_ID_AQCS109 0x03a1b5c2 - #define PHY_ID_AQR405 0x03a1b4b0 -+#define PHY_ID_AQR113C 0x31c31c12 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -@@ -744,6 +745,24 @@ static struct phy_driver aqr_driver[] = - .handle_interrupt = aqr_handle_interrupt, - .read_status = aqr_read_status, - }, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C), -+ .name = "Aquantia AQR113C", -+ .probe = aqr107_probe, -+ .config_init = aqr107_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, - }; - - module_phy_driver(aqr_driver); -@@ -756,6 +775,7 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, - { } - }; - diff --git a/target/linux/generic/backport-5.15/736-v6.1-0001-net-phy-aquantia-Add-some-additional-phy-interfaces.patch b/target/linux/generic/backport-5.15/736-v6.1-0001-net-phy-aquantia-Add-some-additional-phy-interfaces.patch deleted file mode 100644 index ec8485e0a74370..00000000000000 --- a/target/linux/generic/backport-5.15/736-v6.1-0001-net-phy-aquantia-Add-some-additional-phy-interfaces.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 7de26bf144f6a72858ab60afb2bd2b43265ee0ad Mon Sep 17 00:00:00 2001 -From: Sean Anderson -Date: Tue, 20 Sep 2022 18:12:34 -0400 -Subject: [PATCH] net: phy: aquantia: Add some additional phy interfaces - -These are documented in the AQR115 register reference. I haven't tested -them, but perhaps they'll be useful to someone. - -Signed-off-by: Sean Anderson -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/aquantia_main.c | 17 ++++++++++++++++- - 1 file changed, 16 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/aquantia_main.c -+++ b/drivers/net/phy/aquantia_main.c -@@ -27,9 +27,12 @@ - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 1 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 3 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10 - - #define MDIO_AN_VEND_PROV 0xc400 -@@ -401,15 +404,24 @@ static int aqr107_read_status(struct phy - case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR: - phydev->interface = PHY_INTERFACE_MODE_10GKR; - break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX: -+ phydev->interface = PHY_INTERFACE_MODE_1000BASEKX; -+ break; - case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI: - phydev->interface = PHY_INTERFACE_MODE_10GBASER; - break; - case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII: - phydev->interface = PHY_INTERFACE_MODE_USXGMII; - break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI: -+ phydev->interface = PHY_INTERFACE_MODE_XAUI; -+ break; - case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII: - phydev->interface = PHY_INTERFACE_MODE_SGMII; - break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI: -+ phydev->interface = PHY_INTERFACE_MODE_RXAUI; -+ break; - case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII: - phydev->interface = PHY_INTERFACE_MODE_2500BASEX; - break; -@@ -522,11 +534,14 @@ static int aqr107_config_init(struct phy - - /* Check that the PHY interface type is compatible */ - if (phydev->interface != PHY_INTERFACE_MODE_SGMII && -+ phydev->interface != PHY_INTERFACE_MODE_1000BASEKX && - phydev->interface != PHY_INTERFACE_MODE_2500BASEX && - phydev->interface != PHY_INTERFACE_MODE_XGMII && - phydev->interface != PHY_INTERFACE_MODE_USXGMII && - phydev->interface != PHY_INTERFACE_MODE_10GKR && -- phydev->interface != PHY_INTERFACE_MODE_10GBASER) -+ phydev->interface != PHY_INTERFACE_MODE_10GBASER && -+ phydev->interface != PHY_INTERFACE_MODE_XAUI && -+ phydev->interface != PHY_INTERFACE_MODE_RXAUI) - return -ENODEV; - - WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII, diff --git a/target/linux/generic/backport-5.15/736-v6.1-0002-net-phy-aquantia-Add-support-for-rate-matching.patch b/target/linux/generic/backport-5.15/736-v6.1-0002-net-phy-aquantia-Add-support-for-rate-matching.patch deleted file mode 100644 index d5d58762ce377b..00000000000000 --- a/target/linux/generic/backport-5.15/736-v6.1-0002-net-phy-aquantia-Add-support-for-rate-matching.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 3c42563b30417afc8855a3b4c1b38c2f36f78657 Mon Sep 17 00:00:00 2001 -From: Sean Anderson -Date: Tue, 20 Sep 2022 18:12:35 -0400 -Subject: [PATCH] net: phy: aquantia: Add support for rate matching - -This adds support for rate matching for phys similar to the AQR107. We -assume that all phys using aqr107_read_status support rate matching. -However, it could be possible to determine support based on the firmware -revision if there are phys discovered which do not support rate -matching. However, as rate matching is advertised in the datasheets for -these phys, I suspect it is supported most boards. - -Despite the name, the "config" registers are updated with the current -rate matching method (if any). Because they appear to be updated -automatically, I don't know if these registers can be used to disable -rate matching. - -Signed-off-by: Sean Anderson -Signed-off-by: David S. Miller ---- - drivers/net/phy/aquantia_main.c | 51 ++++++++++++++++++++++++++++++--- - 1 file changed, 47 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/aquantia_main.c -+++ b/drivers/net/phy/aquantia_main.c -@@ -97,6 +97,19 @@ - #define VEND1_GLOBAL_GEN_STAT2 0xc831 - #define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15) - -+/* The following registers all have similar layouts; first the registers... */ -+#define VEND1_GLOBAL_CFG_10M 0x0310 -+#define VEND1_GLOBAL_CFG_100M 0x031b -+#define VEND1_GLOBAL_CFG_1G 0x031c -+#define VEND1_GLOBAL_CFG_2_5G 0x031d -+#define VEND1_GLOBAL_CFG_5G 0x031e -+#define VEND1_GLOBAL_CFG_10G 0x031f -+/* ...and now the fields */ -+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7) -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0 -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1 -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 -+ - #define VEND1_GLOBAL_RSVD_STAT1 0xc885 - #define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4) - #define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0) -@@ -347,40 +360,57 @@ static int aqr_read_status(struct phy_de - - static int aqr107_read_rate(struct phy_device *phydev) - { -+ u32 config_reg; - int val; - - val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1); - if (val < 0) - return val; - -+ if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX) -+ phydev->duplex = DUPLEX_FULL; -+ else -+ phydev->duplex = DUPLEX_HALF; -+ - switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) { - case MDIO_AN_TX_VEND_STATUS1_10BASET: - phydev->speed = SPEED_10; -+ config_reg = VEND1_GLOBAL_CFG_10M; - break; - case MDIO_AN_TX_VEND_STATUS1_100BASETX: - phydev->speed = SPEED_100; -+ config_reg = VEND1_GLOBAL_CFG_100M; - break; - case MDIO_AN_TX_VEND_STATUS1_1000BASET: - phydev->speed = SPEED_1000; -+ config_reg = VEND1_GLOBAL_CFG_1G; - break; - case MDIO_AN_TX_VEND_STATUS1_2500BASET: - phydev->speed = SPEED_2500; -+ config_reg = VEND1_GLOBAL_CFG_2_5G; - break; - case MDIO_AN_TX_VEND_STATUS1_5000BASET: - phydev->speed = SPEED_5000; -+ config_reg = VEND1_GLOBAL_CFG_5G; - break; - case MDIO_AN_TX_VEND_STATUS1_10GBASET: - phydev->speed = SPEED_10000; -+ config_reg = VEND1_GLOBAL_CFG_10G; - break; - default: - phydev->speed = SPEED_UNKNOWN; -- break; -+ return 0; - } - -- if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX) -- phydev->duplex = DUPLEX_FULL; -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg); -+ if (val < 0) -+ return val; -+ -+ if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) == -+ VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE) -+ phydev->rate_matching = RATE_MATCH_PAUSE; - else -- phydev->duplex = DUPLEX_HALF; -+ phydev->rate_matching = RATE_MATCH_NONE; - - return 0; - } -@@ -647,6 +677,16 @@ static int aqr107_wait_processor_intensi - return 0; - } - -+static int aqr107_get_rate_matching(struct phy_device *phydev, -+ phy_interface_t iface) -+{ -+ if (iface == PHY_INTERFACE_MODE_10GBASER || -+ iface == PHY_INTERFACE_MODE_2500BASEX || -+ iface == PHY_INTERFACE_MODE_NA) -+ return RATE_MATCH_PAUSE; -+ return RATE_MATCH_NONE; -+} -+ - static int aqr107_suspend(struct phy_device *phydev) - { - int err; -@@ -720,6 +760,7 @@ static struct phy_driver aqr_driver[] = - PHY_ID_MATCH_MODEL(PHY_ID_AQR107), - .name = "Aquantia AQR107", - .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, - .config_init = aqr107_config_init, - .config_aneg = aqr_config_aneg, - .config_intr = aqr_config_intr, -@@ -738,6 +779,7 @@ static struct phy_driver aqr_driver[] = - PHY_ID_MATCH_MODEL(PHY_ID_AQCS109), - .name = "Aquantia AQCS109", - .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, - .config_init = aqcs109_config_init, - .config_aneg = aqr_config_aneg, - .config_intr = aqr_config_intr, -@@ -764,6 +806,7 @@ static struct phy_driver aqr_driver[] = - PHY_ID_MATCH_MODEL(PHY_ID_AQR113C), - .name = "Aquantia AQR113C", - .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, - .config_init = aqr107_config_init, - .config_aneg = aqr_config_aneg, - .config_intr = aqr_config_intr, diff --git a/target/linux/generic/backport-5.15/737-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch b/target/linux/generic/backport-5.15/737-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch deleted file mode 100644 index 4bb786e7901020..00000000000000 --- a/target/linux/generic/backport-5.15/737-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch +++ /dev/null @@ -1,2310 +0,0 @@ -From d2213db3f49bce8e7a87c8de05b9a091f78f654e Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 14 Nov 2023 15:08:41 +0100 -Subject: [PATCH 1/3] net: phy: aquantia: move to separate directory - -Move aquantia PHY driver to separate driectory in preparation for -firmware loading support to keep things tidy. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/Kconfig | 5 +---- - drivers/net/phy/Makefile | 6 +----- - drivers/net/phy/aquantia/Kconfig | 5 +++++ - drivers/net/phy/aquantia/Makefile | 6 ++++++ - drivers/net/phy/{ => aquantia}/aquantia.h | 0 - drivers/net/phy/{ => aquantia}/aquantia_hwmon.c | 0 - drivers/net/phy/{ => aquantia}/aquantia_main.c | 0 - 7 files changed, 13 insertions(+), 9 deletions(-) - create mode 100644 drivers/net/phy/aquantia/Kconfig - create mode 100644 drivers/net/phy/aquantia/Makefile - rename drivers/net/phy/{ => aquantia}/aquantia.h (100%) - rename drivers/net/phy/{ => aquantia}/aquantia_hwmon.c (100%) - rename drivers/net/phy/{ => aquantia}/aquantia_main.c (100%) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -83,10 +83,7 @@ config ADIN_PHY - - ADIN1300 - Robust,Industrial, Low Latency 10/100/1000 Gigabit - Ethernet PHY - --config AQUANTIA_PHY -- tristate "Aquantia PHYs" -- help -- Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405 -+source "drivers/net/phy/aquantia/Kconfig" - - config AX88796B_PHY - tristate "Asix PHYs" ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -32,11 +32,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m) - - obj-$(CONFIG_ADIN_PHY) += adin.o - obj-$(CONFIG_AMD_PHY) += amd.o --aquantia-objs += aquantia_main.o --ifdef CONFIG_HWMON --aquantia-objs += aquantia_hwmon.o --endif --obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o -+obj-$(CONFIG_AQUANTIA_PHY) += aquantia/ - obj-$(CONFIG_AT803X_PHY) += at803x.o - obj-$(CONFIG_AX88796B_PHY) += ax88796b.o - obj-$(CONFIG_BCM54140_PHY) += bcm54140.o ---- /dev/null -+++ b/drivers/net/phy/aquantia/Kconfig -@@ -0,0 +1,5 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+config AQUANTIA_PHY -+ tristate "Aquantia PHYs" -+ help -+ Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405 ---- /dev/null -+++ b/drivers/net/phy/aquantia/Makefile -@@ -0,0 +1,6 @@ -+# SPDX-License-Identifier: GPL-2.0 -+aquantia-objs += aquantia_main.o -+ifdef CONFIG_HWMON -+aquantia-objs += aquantia_hwmon.o -+endif -+obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o ---- a/drivers/net/phy/aquantia.h -+++ /dev/null -@@ -1,16 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* HWMON driver for Aquantia PHY -- * -- * Author: Nikita Yushchenko -- * Author: Andrew Lunn -- * Author: Heiner Kallweit -- */ -- --#include --#include -- --#if IS_REACHABLE(CONFIG_HWMON) --int aqr_hwmon_probe(struct phy_device *phydev); --#else --static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; } --#endif ---- /dev/null -+++ b/drivers/net/phy/aquantia/aquantia.h -@@ -0,0 +1,16 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* HWMON driver for Aquantia PHY -+ * -+ * Author: Nikita Yushchenko -+ * Author: Andrew Lunn -+ * Author: Heiner Kallweit -+ */ -+ -+#include -+#include -+ -+#if IS_REACHABLE(CONFIG_HWMON) -+int aqr_hwmon_probe(struct phy_device *phydev); -+#else -+static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; } -+#endif ---- /dev/null -+++ b/drivers/net/phy/aquantia/aquantia_hwmon.c -@@ -0,0 +1,250 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* HWMON driver for Aquantia PHY -+ * -+ * Author: Nikita Yushchenko -+ * Author: Andrew Lunn -+ * Author: Heiner Kallweit -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "aquantia.h" -+ -+/* Vendor specific 1, MDIO_MMD_VEND2 */ -+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421 -+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422 -+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423 -+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424 -+#define VEND1_THERMAL_STAT1 0xc820 -+#define VEND1_THERMAL_STAT2 0xc821 -+#define VEND1_THERMAL_STAT2_VALID BIT(0) -+#define VEND1_GENERAL_STAT1 0xc830 -+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14) -+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13) -+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12) -+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11) -+ -+#if IS_REACHABLE(CONFIG_HWMON) -+ -+static umode_t aqr_hwmon_is_visible(const void *data, -+ enum hwmon_sensor_types type, -+ u32 attr, int channel) -+{ -+ if (type != hwmon_temp) -+ return 0; -+ -+ switch (attr) { -+ case hwmon_temp_input: -+ case hwmon_temp_min_alarm: -+ case hwmon_temp_max_alarm: -+ case hwmon_temp_lcrit_alarm: -+ case hwmon_temp_crit_alarm: -+ return 0444; -+ case hwmon_temp_min: -+ case hwmon_temp_max: -+ case hwmon_temp_lcrit: -+ case hwmon_temp_crit: -+ return 0644; -+ default: -+ return 0; -+ } -+} -+ -+static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value) -+{ -+ int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg); -+ -+ if (temp < 0) -+ return temp; -+ -+ /* 16 bit value is 2's complement with LSB = 1/256th degree Celsius */ -+ *value = (s16)temp * 1000 / 256; -+ -+ return 0; -+} -+ -+static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value) -+{ -+ int temp; -+ -+ if (value >= 128000 || value < -128000) -+ return -ERANGE; -+ -+ temp = value * 256 / 1000; -+ -+ /* temp is in s16 range and we're interested in lower 16 bits only */ -+ return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, (u16)temp); -+} -+ -+static int aqr_hwmon_test_bit(struct phy_device *phydev, int reg, int bit) -+{ -+ int val = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg); -+ -+ if (val < 0) -+ return val; -+ -+ return !!(val & bit); -+} -+ -+static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value) -+{ -+ int val = aqr_hwmon_test_bit(phydev, VEND1_GENERAL_STAT1, bit); -+ -+ if (val < 0) -+ return val; -+ -+ *value = val; -+ -+ return 0; -+} -+ -+static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type, -+ u32 attr, int channel, long *value) -+{ -+ struct phy_device *phydev = dev_get_drvdata(dev); -+ int reg; -+ -+ if (type != hwmon_temp) -+ return -EOPNOTSUPP; -+ -+ switch (attr) { -+ case hwmon_temp_input: -+ reg = aqr_hwmon_test_bit(phydev, VEND1_THERMAL_STAT2, -+ VEND1_THERMAL_STAT2_VALID); -+ if (reg < 0) -+ return reg; -+ if (!reg) -+ return -EBUSY; -+ -+ return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value); -+ -+ case hwmon_temp_lcrit: -+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL, -+ value); -+ case hwmon_temp_min: -+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN, -+ value); -+ case hwmon_temp_max: -+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN, -+ value); -+ case hwmon_temp_crit: -+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL, -+ value); -+ case hwmon_temp_lcrit_alarm: -+ return aqr_hwmon_status1(phydev, -+ VEND1_GENERAL_STAT1_LOW_TEMP_FAIL, -+ value); -+ case hwmon_temp_min_alarm: -+ return aqr_hwmon_status1(phydev, -+ VEND1_GENERAL_STAT1_LOW_TEMP_WARN, -+ value); -+ case hwmon_temp_max_alarm: -+ return aqr_hwmon_status1(phydev, -+ VEND1_GENERAL_STAT1_HIGH_TEMP_WARN, -+ value); -+ case hwmon_temp_crit_alarm: -+ return aqr_hwmon_status1(phydev, -+ VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL, -+ value); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type, -+ u32 attr, int channel, long value) -+{ -+ struct phy_device *phydev = dev_get_drvdata(dev); -+ -+ if (type != hwmon_temp) -+ return -EOPNOTSUPP; -+ -+ switch (attr) { -+ case hwmon_temp_lcrit: -+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL, -+ value); -+ case hwmon_temp_min: -+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN, -+ value); -+ case hwmon_temp_max: -+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN, -+ value); -+ case hwmon_temp_crit: -+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL, -+ value); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static const struct hwmon_ops aqr_hwmon_ops = { -+ .is_visible = aqr_hwmon_is_visible, -+ .read = aqr_hwmon_read, -+ .write = aqr_hwmon_write, -+}; -+ -+static u32 aqr_hwmon_chip_config[] = { -+ HWMON_C_REGISTER_TZ, -+ 0, -+}; -+ -+static const struct hwmon_channel_info aqr_hwmon_chip = { -+ .type = hwmon_chip, -+ .config = aqr_hwmon_chip_config, -+}; -+ -+static u32 aqr_hwmon_temp_config[] = { -+ HWMON_T_INPUT | -+ HWMON_T_MAX | HWMON_T_MIN | -+ HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM | -+ HWMON_T_CRIT | HWMON_T_LCRIT | -+ HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM, -+ 0, -+}; -+ -+static const struct hwmon_channel_info aqr_hwmon_temp = { -+ .type = hwmon_temp, -+ .config = aqr_hwmon_temp_config, -+}; -+ -+static const struct hwmon_channel_info *aqr_hwmon_info[] = { -+ &aqr_hwmon_chip, -+ &aqr_hwmon_temp, -+ NULL, -+}; -+ -+static const struct hwmon_chip_info aqr_hwmon_chip_info = { -+ .ops = &aqr_hwmon_ops, -+ .info = aqr_hwmon_info, -+}; -+ -+int aqr_hwmon_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct device *hwmon_dev; -+ char *hwmon_name; -+ int i, j; -+ -+ hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); -+ if (!hwmon_name) -+ return -ENOMEM; -+ -+ for (i = j = 0; hwmon_name[i]; i++) { -+ if (isalnum(hwmon_name[i])) { -+ if (i != j) -+ hwmon_name[j] = hwmon_name[i]; -+ j++; -+ } -+ } -+ hwmon_name[j] = '\0'; -+ -+ hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name, -+ phydev, &aqr_hwmon_chip_info, NULL); -+ -+ return PTR_ERR_OR_ZERO(hwmon_dev); -+} -+ -+#endif ---- /dev/null -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -0,0 +1,844 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Driver for Aquantia PHY -+ * -+ * Author: Shaohui Xie -+ * -+ * Copyright 2015 Freescale Semiconductor, Inc. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "aquantia.h" -+ -+#define PHY_ID_AQ1202 0x03a1b445 -+#define PHY_ID_AQ2104 0x03a1b460 -+#define PHY_ID_AQR105 0x03a1b4a2 -+#define PHY_ID_AQR106 0x03a1b4d0 -+#define PHY_ID_AQR107 0x03a1b4e0 -+#define PHY_ID_AQCS109 0x03a1b5c2 -+#define PHY_ID_AQR405 0x03a1b4b0 -+#define PHY_ID_AQR113C 0x31c31c12 -+ -+#define MDIO_PHYXS_VEND_IF_STATUS 0xe812 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 1 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 3 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10 -+ -+#define MDIO_AN_VEND_PROV 0xc400 -+#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) -+#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) -+#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11) -+#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10) -+#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4) -+#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0) -+#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4 -+ -+#define MDIO_AN_TX_VEND_STATUS1 0xc800 -+#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1) -+#define MDIO_AN_TX_VEND_STATUS1_10BASET 0 -+#define MDIO_AN_TX_VEND_STATUS1_100BASETX 1 -+#define MDIO_AN_TX_VEND_STATUS1_1000BASET 2 -+#define MDIO_AN_TX_VEND_STATUS1_10GBASET 3 -+#define MDIO_AN_TX_VEND_STATUS1_2500BASET 4 -+#define MDIO_AN_TX_VEND_STATUS1_5000BASET 5 -+#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX BIT(0) -+ -+#define MDIO_AN_TX_VEND_INT_STATUS1 0xcc00 -+#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT BIT(1) -+ -+#define MDIO_AN_TX_VEND_INT_STATUS2 0xcc01 -+#define MDIO_AN_TX_VEND_INT_STATUS2_MASK BIT(0) -+ -+#define MDIO_AN_TX_VEND_INT_MASK2 0xd401 -+#define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0) -+ -+#define MDIO_AN_RX_LP_STAT1 0xe820 -+#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15) -+#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14) -+#define MDIO_AN_RX_LP_STAT1_SHORT_REACH BIT(13) -+#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT BIT(12) -+#define MDIO_AN_RX_LP_STAT1_AQ_PHY BIT(2) -+ -+#define MDIO_AN_RX_LP_STAT4 0xe823 -+#define MDIO_AN_RX_LP_STAT4_FW_MAJOR GENMASK(15, 8) -+#define MDIO_AN_RX_LP_STAT4_FW_MINOR GENMASK(7, 0) -+ -+#define MDIO_AN_RX_VEND_STAT3 0xe832 -+#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0) -+ -+/* MDIO_MMD_C22EXT */ -+#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292 -+#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294 -+#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297 -+#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313 -+#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315 -+#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317 -+#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318 -+#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319 -+#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a -+#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b -+ -+/* Vendor specific 1, MDIO_MMD_VEND1 */ -+#define VEND1_GLOBAL_FW_ID 0x0020 -+#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) -+#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) -+ -+#define VEND1_GLOBAL_GEN_STAT2 0xc831 -+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15) -+ -+/* The following registers all have similar layouts; first the registers... */ -+#define VEND1_GLOBAL_CFG_10M 0x0310 -+#define VEND1_GLOBAL_CFG_100M 0x031b -+#define VEND1_GLOBAL_CFG_1G 0x031c -+#define VEND1_GLOBAL_CFG_2_5G 0x031d -+#define VEND1_GLOBAL_CFG_5G 0x031e -+#define VEND1_GLOBAL_CFG_10G 0x031f -+/* ...and now the fields */ -+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7) -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0 -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1 -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 -+ -+#define VEND1_GLOBAL_RSVD_STAT1 0xc885 -+#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4) -+#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0) -+ -+#define VEND1_GLOBAL_RSVD_STAT9 0xc88d -+#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0) -+#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23 -+ -+#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00 -+#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01 -+ -+#define VEND1_GLOBAL_INT_STD_MASK 0xff00 -+#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15) -+#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11) -+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10) -+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9) -+#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8) -+#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7) -+#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6) -+#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0) -+ -+#define VEND1_GLOBAL_INT_VEND_MASK 0xff01 -+#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15) -+#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14) -+#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13) -+#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12) -+#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0) -+ -+/* Sleep and timeout for checking if the Processor-Intensive -+ * MDIO operation is finished -+ */ -+#define AQR107_OP_IN_PROG_SLEEP 1000 -+#define AQR107_OP_IN_PROG_TIMEOUT 100000 -+ -+struct aqr107_hw_stat { -+ const char *name; -+ int reg; -+ int size; -+}; -+ -+#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s } -+static const struct aqr107_hw_stat aqr107_hw_stats[] = { -+ SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26), -+ SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26), -+ SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8), -+ SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26), -+ SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26), -+ SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8), -+ SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8), -+ SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8), -+ SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16), -+ SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22), -+}; -+#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats) -+ -+struct aqr107_priv { -+ u64 sgmii_stats[AQR107_SGMII_STAT_SZ]; -+}; -+ -+static int aqr107_get_sset_count(struct phy_device *phydev) -+{ -+ return AQR107_SGMII_STAT_SZ; -+} -+ -+static void aqr107_get_strings(struct phy_device *phydev, u8 *data) -+{ -+ int i; -+ -+ for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) -+ strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name, -+ ETH_GSTRING_LEN); -+} -+ -+static u64 aqr107_get_stat(struct phy_device *phydev, int index) -+{ -+ const struct aqr107_hw_stat *stat = aqr107_hw_stats + index; -+ int len_l = min(stat->size, 16); -+ int len_h = stat->size - len_l; -+ u64 ret; -+ int val; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg); -+ if (val < 0) -+ return U64_MAX; -+ -+ ret = val & GENMASK(len_l - 1, 0); -+ if (len_h) { -+ val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1); -+ if (val < 0) -+ return U64_MAX; -+ -+ ret += (val & GENMASK(len_h - 1, 0)) << 16; -+ } -+ -+ return ret; -+} -+ -+static void aqr107_get_stats(struct phy_device *phydev, -+ struct ethtool_stats *stats, u64 *data) -+{ -+ struct aqr107_priv *priv = phydev->priv; -+ u64 val; -+ int i; -+ -+ for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) { -+ val = aqr107_get_stat(phydev, i); -+ if (val == U64_MAX) -+ phydev_err(phydev, "Reading HW Statistics failed for %s\n", -+ aqr107_hw_stats[i].name); -+ else -+ priv->sgmii_stats[i] += val; -+ -+ data[i] = priv->sgmii_stats[i]; -+ } -+} -+ -+static int aqr_config_aneg(struct phy_device *phydev) -+{ -+ bool changed = false; -+ u16 reg; -+ int ret; -+ -+ if (phydev->autoneg == AUTONEG_DISABLE) -+ return genphy_c45_pma_setup_forced(phydev); -+ -+ ret = genphy_c45_an_config_aneg(phydev); -+ if (ret < 0) -+ return ret; -+ if (ret > 0) -+ changed = true; -+ -+ /* Clause 45 has no standardized support for 1000BaseT, therefore -+ * use vendor registers for this mode. -+ */ -+ reg = 0; -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ phydev->advertising)) -+ reg |= MDIO_AN_VEND_PROV_1000BASET_FULL; -+ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -+ phydev->advertising)) -+ reg |= MDIO_AN_VEND_PROV_1000BASET_HALF; -+ -+ /* Handle the case when the 2.5G and 5G speeds are not advertised */ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ phydev->advertising)) -+ reg |= MDIO_AN_VEND_PROV_2500BASET_FULL; -+ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, -+ phydev->advertising)) -+ reg |= MDIO_AN_VEND_PROV_5000BASET_FULL; -+ -+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, -+ MDIO_AN_VEND_PROV_1000BASET_HALF | -+ MDIO_AN_VEND_PROV_1000BASET_FULL | -+ MDIO_AN_VEND_PROV_2500BASET_FULL | -+ MDIO_AN_VEND_PROV_5000BASET_FULL, reg); -+ if (ret < 0) -+ return ret; -+ if (ret > 0) -+ changed = true; -+ -+ return genphy_c45_check_and_restart_aneg(phydev, changed); -+} -+ -+static int aqr_config_intr(struct phy_device *phydev) -+{ -+ bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED; -+ int err; -+ -+ if (en) { -+ /* Clear any pending interrupts before enabling them */ -+ err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2); -+ if (err < 0) -+ return err; -+ } -+ -+ err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2, -+ en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0); -+ if (err < 0) -+ return err; -+ -+ err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK, -+ en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0); -+ if (err < 0) -+ return err; -+ -+ err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK, -+ en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 | -+ VEND1_GLOBAL_INT_VEND_MASK_AN : 0); -+ if (err < 0) -+ return err; -+ -+ if (!en) { -+ /* Clear any pending interrupts after we have disabled them */ -+ err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2); -+ if (err < 0) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev) -+{ -+ int irq_status; -+ -+ irq_status = phy_read_mmd(phydev, MDIO_MMD_AN, -+ MDIO_AN_TX_VEND_INT_STATUS2); -+ if (irq_status < 0) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK)) -+ return IRQ_NONE; -+ -+ phy_trigger_machine(phydev); -+ -+ return IRQ_HANDLED; -+} -+ -+static int aqr_read_status(struct phy_device *phydev) -+{ -+ int val; -+ -+ if (phydev->autoneg == AUTONEG_ENABLE) { -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1); -+ if (val < 0) -+ return val; -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ phydev->lp_advertising, -+ val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -+ phydev->lp_advertising, -+ val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF); -+ } -+ -+ return genphy_c45_read_status(phydev); -+} -+ -+static int aqr107_read_rate(struct phy_device *phydev) -+{ -+ u32 config_reg; -+ int val; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1); -+ if (val < 0) -+ return val; -+ -+ if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX) -+ phydev->duplex = DUPLEX_FULL; -+ else -+ phydev->duplex = DUPLEX_HALF; -+ -+ switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) { -+ case MDIO_AN_TX_VEND_STATUS1_10BASET: -+ phydev->speed = SPEED_10; -+ config_reg = VEND1_GLOBAL_CFG_10M; -+ break; -+ case MDIO_AN_TX_VEND_STATUS1_100BASETX: -+ phydev->speed = SPEED_100; -+ config_reg = VEND1_GLOBAL_CFG_100M; -+ break; -+ case MDIO_AN_TX_VEND_STATUS1_1000BASET: -+ phydev->speed = SPEED_1000; -+ config_reg = VEND1_GLOBAL_CFG_1G; -+ break; -+ case MDIO_AN_TX_VEND_STATUS1_2500BASET: -+ phydev->speed = SPEED_2500; -+ config_reg = VEND1_GLOBAL_CFG_2_5G; -+ break; -+ case MDIO_AN_TX_VEND_STATUS1_5000BASET: -+ phydev->speed = SPEED_5000; -+ config_reg = VEND1_GLOBAL_CFG_5G; -+ break; -+ case MDIO_AN_TX_VEND_STATUS1_10GBASET: -+ phydev->speed = SPEED_10000; -+ config_reg = VEND1_GLOBAL_CFG_10G; -+ break; -+ default: -+ phydev->speed = SPEED_UNKNOWN; -+ return 0; -+ } -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg); -+ if (val < 0) -+ return val; -+ -+ if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) == -+ VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE) -+ phydev->rate_matching = RATE_MATCH_PAUSE; -+ else -+ phydev->rate_matching = RATE_MATCH_NONE; -+ -+ return 0; -+} -+ -+static int aqr107_read_status(struct phy_device *phydev) -+{ -+ int val, ret; -+ -+ ret = aqr_read_status(phydev); -+ if (ret) -+ return ret; -+ -+ if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE) -+ return 0; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS); -+ if (val < 0) -+ return val; -+ -+ switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) { -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR: -+ phydev->interface = PHY_INTERFACE_MODE_10GKR; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX: -+ phydev->interface = PHY_INTERFACE_MODE_1000BASEKX; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI: -+ phydev->interface = PHY_INTERFACE_MODE_10GBASER; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII: -+ phydev->interface = PHY_INTERFACE_MODE_USXGMII; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI: -+ phydev->interface = PHY_INTERFACE_MODE_XAUI; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII: -+ phydev->interface = PHY_INTERFACE_MODE_SGMII; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI: -+ phydev->interface = PHY_INTERFACE_MODE_RXAUI; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII: -+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -+ break; -+ default: -+ phydev->interface = PHY_INTERFACE_MODE_NA; -+ break; -+ } -+ -+ /* Read possibly downshifted rate from vendor register */ -+ return aqr107_read_rate(phydev); -+} -+ -+static int aqr107_get_downshift(struct phy_device *phydev, u8 *data) -+{ -+ int val, cnt, enable; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV); -+ if (val < 0) -+ return val; -+ -+ enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val); -+ cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val); -+ -+ *data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE; -+ -+ return 0; -+} -+ -+static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt) -+{ -+ int val = 0; -+ -+ if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt)) -+ return -E2BIG; -+ -+ if (cnt != DOWNSHIFT_DEV_DISABLE) { -+ val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN; -+ val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt); -+ } -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, -+ MDIO_AN_VEND_PROV_DOWNSHIFT_EN | -+ MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val); -+} -+ -+static int aqr107_get_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, void *data) -+{ -+ switch (tuna->id) { -+ case ETHTOOL_PHY_DOWNSHIFT: -+ return aqr107_get_downshift(phydev, data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int aqr107_set_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, const void *data) -+{ -+ switch (tuna->id) { -+ case ETHTOOL_PHY_DOWNSHIFT: -+ return aqr107_set_downshift(phydev, *(const u8 *)data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+/* If we configure settings whilst firmware is still initializing the chip, -+ * then these settings may be overwritten. Therefore make sure chip -+ * initialization has completed. Use presence of the firmware ID as -+ * indicator for initialization having completed. -+ * The chip also provides a "reset completed" bit, but it's cleared after -+ * read. Therefore function would time out if called again. -+ */ -+static int aqr107_wait_reset_complete(struct phy_device *phydev) -+{ -+ int val; -+ -+ return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_FW_ID, val, val != 0, -+ 20000, 2000000, false); -+} -+ -+static void aqr107_chip_info(struct phy_device *phydev) -+{ -+ u8 fw_major, fw_minor, build_id, prov_id; -+ int val; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID); -+ if (val < 0) -+ return; -+ -+ fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val); -+ fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1); -+ if (val < 0) -+ return; -+ -+ build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val); -+ prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val); -+ -+ phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n", -+ fw_major, fw_minor, build_id, prov_id); -+} -+ -+static int aqr107_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Check that the PHY interface type is compatible */ -+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII && -+ phydev->interface != PHY_INTERFACE_MODE_1000BASEKX && -+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX && -+ phydev->interface != PHY_INTERFACE_MODE_XGMII && -+ phydev->interface != PHY_INTERFACE_MODE_USXGMII && -+ phydev->interface != PHY_INTERFACE_MODE_10GKR && -+ phydev->interface != PHY_INTERFACE_MODE_10GBASER && -+ phydev->interface != PHY_INTERFACE_MODE_XAUI && -+ phydev->interface != PHY_INTERFACE_MODE_RXAUI) -+ return -ENODEV; -+ -+ WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII, -+ "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n"); -+ -+ ret = aqr107_wait_reset_complete(phydev); -+ if (!ret) -+ aqr107_chip_info(phydev); -+ -+ return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); -+} -+ -+static int aqcs109_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Check that the PHY interface type is compatible */ -+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII && -+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX) -+ return -ENODEV; -+ -+ ret = aqr107_wait_reset_complete(phydev); -+ if (!ret) -+ aqr107_chip_info(phydev); -+ -+ /* AQCS109 belongs to a chip family partially supporting 10G and 5G. -+ * PMA speed ability bits are the same for all members of the family, -+ * AQCS109 however supports speeds up to 2.5G only. -+ */ -+ ret = phy_set_max_speed(phydev, SPEED_2500); -+ if (ret) -+ return ret; -+ -+ return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); -+} -+ -+static void aqr107_link_change_notify(struct phy_device *phydev) -+{ -+ u8 fw_major, fw_minor; -+ bool downshift, short_reach, afr; -+ int mode, val; -+ -+ if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE) -+ return; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1); -+ /* call failed or link partner is no Aquantia PHY */ -+ if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY)) -+ return; -+ -+ short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH; -+ downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4); -+ if (val < 0) -+ return; -+ -+ fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val); -+ fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3); -+ if (val < 0) -+ return; -+ -+ afr = val & MDIO_AN_RX_VEND_STAT3_AFR; -+ -+ phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n", -+ fw_major, fw_minor, -+ short_reach ? ", short reach mode" : "", -+ downshift ? ", fast-retrain downshift advertised" : "", -+ afr ? ", fast reframe advertised" : ""); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT9); -+ if (val < 0) -+ return; -+ -+ mode = FIELD_GET(VEND1_GLOBAL_RSVD_STAT9_MODE, val); -+ if (mode == VEND1_GLOBAL_RSVD_STAT9_1000BT2) -+ phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n"); -+} -+ -+static int aqr107_wait_processor_intensive_op(struct phy_device *phydev) -+{ -+ int val, err; -+ -+ /* The datasheet notes to wait at least 1ms after issuing a -+ * processor intensive operation before checking. -+ * We cannot use the 'sleep_before_read' parameter of read_poll_timeout -+ * because that just determines the maximum time slept, not the minimum. -+ */ -+ usleep_range(1000, 5000); -+ -+ err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_GEN_STAT2, val, -+ !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG), -+ AQR107_OP_IN_PROG_SLEEP, -+ AQR107_OP_IN_PROG_TIMEOUT, false); -+ if (err) { -+ phydev_err(phydev, "timeout: processor-intensive MDIO operation\n"); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int aqr107_get_rate_matching(struct phy_device *phydev, -+ phy_interface_t iface) -+{ -+ if (iface == PHY_INTERFACE_MODE_10GBASER || -+ iface == PHY_INTERFACE_MODE_2500BASEX || -+ iface == PHY_INTERFACE_MODE_NA) -+ return RATE_MATCH_PAUSE; -+ return RATE_MATCH_NONE; -+} -+ -+static int aqr107_suspend(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, -+ MDIO_CTRL1_LPOWER); -+ if (err) -+ return err; -+ -+ return aqr107_wait_processor_intensive_op(phydev); -+} -+ -+static int aqr107_resume(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, -+ MDIO_CTRL1_LPOWER); -+ if (err) -+ return err; -+ -+ return aqr107_wait_processor_intensive_op(phydev); -+} -+ -+static int aqr107_probe(struct phy_device *phydev) -+{ -+ phydev->priv = devm_kzalloc(&phydev->mdio.dev, -+ sizeof(struct aqr107_priv), GFP_KERNEL); -+ if (!phydev->priv) -+ return -ENOMEM; -+ -+ return aqr_hwmon_probe(phydev); -+} -+ -+static struct phy_driver aqr_driver[] = { -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQ1202), -+ .name = "Aquantia AQ1202", -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr_read_status, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQ2104), -+ .name = "Aquantia AQ2104", -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr_read_status, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR105), -+ .name = "Aquantia AQR105", -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr_read_status, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR106), -+ .name = "Aquantia AQR106", -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr_read_status, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR107), -+ .name = "Aquantia AQR107", -+ .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, -+ .config_init = aqr107_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQCS109), -+ .name = "Aquantia AQCS109", -+ .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, -+ .config_init = aqcs109_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR405), -+ .name = "Aquantia AQR405", -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr_read_status, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C), -+ .name = "Aquantia AQR113C", -+ .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, -+ .config_init = aqr107_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+}; -+ -+module_phy_driver(aqr_driver); -+ -+static struct mdio_device_id __maybe_unused aqr_tbl[] = { -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(mdio, aqr_tbl); -+ -+MODULE_DESCRIPTION("Aquantia PHY driver"); -+MODULE_AUTHOR("Shaohui Xie "); -+MODULE_LICENSE("GPL v2"); ---- a/drivers/net/phy/aquantia_hwmon.c -+++ /dev/null -@@ -1,250 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* HWMON driver for Aquantia PHY -- * -- * Author: Nikita Yushchenko -- * Author: Andrew Lunn -- * Author: Heiner Kallweit -- */ -- --#include --#include --#include --#include -- --#include "aquantia.h" -- --/* Vendor specific 1, MDIO_MMD_VEND2 */ --#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421 --#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422 --#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423 --#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424 --#define VEND1_THERMAL_STAT1 0xc820 --#define VEND1_THERMAL_STAT2 0xc821 --#define VEND1_THERMAL_STAT2_VALID BIT(0) --#define VEND1_GENERAL_STAT1 0xc830 --#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14) --#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13) --#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12) --#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11) -- --#if IS_REACHABLE(CONFIG_HWMON) -- --static umode_t aqr_hwmon_is_visible(const void *data, -- enum hwmon_sensor_types type, -- u32 attr, int channel) --{ -- if (type != hwmon_temp) -- return 0; -- -- switch (attr) { -- case hwmon_temp_input: -- case hwmon_temp_min_alarm: -- case hwmon_temp_max_alarm: -- case hwmon_temp_lcrit_alarm: -- case hwmon_temp_crit_alarm: -- return 0444; -- case hwmon_temp_min: -- case hwmon_temp_max: -- case hwmon_temp_lcrit: -- case hwmon_temp_crit: -- return 0644; -- default: -- return 0; -- } --} -- --static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value) --{ -- int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg); -- -- if (temp < 0) -- return temp; -- -- /* 16 bit value is 2's complement with LSB = 1/256th degree Celsius */ -- *value = (s16)temp * 1000 / 256; -- -- return 0; --} -- --static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value) --{ -- int temp; -- -- if (value >= 128000 || value < -128000) -- return -ERANGE; -- -- temp = value * 256 / 1000; -- -- /* temp is in s16 range and we're interested in lower 16 bits only */ -- return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, (u16)temp); --} -- --static int aqr_hwmon_test_bit(struct phy_device *phydev, int reg, int bit) --{ -- int val = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg); -- -- if (val < 0) -- return val; -- -- return !!(val & bit); --} -- --static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value) --{ -- int val = aqr_hwmon_test_bit(phydev, VEND1_GENERAL_STAT1, bit); -- -- if (val < 0) -- return val; -- -- *value = val; -- -- return 0; --} -- --static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type, -- u32 attr, int channel, long *value) --{ -- struct phy_device *phydev = dev_get_drvdata(dev); -- int reg; -- -- if (type != hwmon_temp) -- return -EOPNOTSUPP; -- -- switch (attr) { -- case hwmon_temp_input: -- reg = aqr_hwmon_test_bit(phydev, VEND1_THERMAL_STAT2, -- VEND1_THERMAL_STAT2_VALID); -- if (reg < 0) -- return reg; -- if (!reg) -- return -EBUSY; -- -- return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value); -- -- case hwmon_temp_lcrit: -- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL, -- value); -- case hwmon_temp_min: -- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN, -- value); -- case hwmon_temp_max: -- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN, -- value); -- case hwmon_temp_crit: -- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL, -- value); -- case hwmon_temp_lcrit_alarm: -- return aqr_hwmon_status1(phydev, -- VEND1_GENERAL_STAT1_LOW_TEMP_FAIL, -- value); -- case hwmon_temp_min_alarm: -- return aqr_hwmon_status1(phydev, -- VEND1_GENERAL_STAT1_LOW_TEMP_WARN, -- value); -- case hwmon_temp_max_alarm: -- return aqr_hwmon_status1(phydev, -- VEND1_GENERAL_STAT1_HIGH_TEMP_WARN, -- value); -- case hwmon_temp_crit_alarm: -- return aqr_hwmon_status1(phydev, -- VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL, -- value); -- default: -- return -EOPNOTSUPP; -- } --} -- --static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type, -- u32 attr, int channel, long value) --{ -- struct phy_device *phydev = dev_get_drvdata(dev); -- -- if (type != hwmon_temp) -- return -EOPNOTSUPP; -- -- switch (attr) { -- case hwmon_temp_lcrit: -- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL, -- value); -- case hwmon_temp_min: -- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN, -- value); -- case hwmon_temp_max: -- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN, -- value); -- case hwmon_temp_crit: -- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL, -- value); -- default: -- return -EOPNOTSUPP; -- } --} -- --static const struct hwmon_ops aqr_hwmon_ops = { -- .is_visible = aqr_hwmon_is_visible, -- .read = aqr_hwmon_read, -- .write = aqr_hwmon_write, --}; -- --static u32 aqr_hwmon_chip_config[] = { -- HWMON_C_REGISTER_TZ, -- 0, --}; -- --static const struct hwmon_channel_info aqr_hwmon_chip = { -- .type = hwmon_chip, -- .config = aqr_hwmon_chip_config, --}; -- --static u32 aqr_hwmon_temp_config[] = { -- HWMON_T_INPUT | -- HWMON_T_MAX | HWMON_T_MIN | -- HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM | -- HWMON_T_CRIT | HWMON_T_LCRIT | -- HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM, -- 0, --}; -- --static const struct hwmon_channel_info aqr_hwmon_temp = { -- .type = hwmon_temp, -- .config = aqr_hwmon_temp_config, --}; -- --static const struct hwmon_channel_info *aqr_hwmon_info[] = { -- &aqr_hwmon_chip, -- &aqr_hwmon_temp, -- NULL, --}; -- --static const struct hwmon_chip_info aqr_hwmon_chip_info = { -- .ops = &aqr_hwmon_ops, -- .info = aqr_hwmon_info, --}; -- --int aqr_hwmon_probe(struct phy_device *phydev) --{ -- struct device *dev = &phydev->mdio.dev; -- struct device *hwmon_dev; -- char *hwmon_name; -- int i, j; -- -- hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); -- if (!hwmon_name) -- return -ENOMEM; -- -- for (i = j = 0; hwmon_name[i]; i++) { -- if (isalnum(hwmon_name[i])) { -- if (i != j) -- hwmon_name[j] = hwmon_name[i]; -- j++; -- } -- } -- hwmon_name[j] = '\0'; -- -- hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name, -- phydev, &aqr_hwmon_chip_info, NULL); -- -- return PTR_ERR_OR_ZERO(hwmon_dev); --} -- --#endif ---- a/drivers/net/phy/aquantia_main.c -+++ /dev/null -@@ -1,844 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Driver for Aquantia PHY -- * -- * Author: Shaohui Xie -- * -- * Copyright 2015 Freescale Semiconductor, Inc. -- */ -- --#include --#include --#include --#include --#include -- --#include "aquantia.h" -- --#define PHY_ID_AQ1202 0x03a1b445 --#define PHY_ID_AQ2104 0x03a1b460 --#define PHY_ID_AQR105 0x03a1b4a2 --#define PHY_ID_AQR106 0x03a1b4d0 --#define PHY_ID_AQR107 0x03a1b4e0 --#define PHY_ID_AQCS109 0x03a1b5c2 --#define PHY_ID_AQR405 0x03a1b4b0 --#define PHY_ID_AQR113C 0x31c31c12 -- --#define MDIO_PHYXS_VEND_IF_STATUS 0xe812 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 1 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 3 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10 -- --#define MDIO_AN_VEND_PROV 0xc400 --#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) --#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) --#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11) --#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10) --#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4) --#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0) --#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4 -- --#define MDIO_AN_TX_VEND_STATUS1 0xc800 --#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1) --#define MDIO_AN_TX_VEND_STATUS1_10BASET 0 --#define MDIO_AN_TX_VEND_STATUS1_100BASETX 1 --#define MDIO_AN_TX_VEND_STATUS1_1000BASET 2 --#define MDIO_AN_TX_VEND_STATUS1_10GBASET 3 --#define MDIO_AN_TX_VEND_STATUS1_2500BASET 4 --#define MDIO_AN_TX_VEND_STATUS1_5000BASET 5 --#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX BIT(0) -- --#define MDIO_AN_TX_VEND_INT_STATUS1 0xcc00 --#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT BIT(1) -- --#define MDIO_AN_TX_VEND_INT_STATUS2 0xcc01 --#define MDIO_AN_TX_VEND_INT_STATUS2_MASK BIT(0) -- --#define MDIO_AN_TX_VEND_INT_MASK2 0xd401 --#define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0) -- --#define MDIO_AN_RX_LP_STAT1 0xe820 --#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15) --#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14) --#define MDIO_AN_RX_LP_STAT1_SHORT_REACH BIT(13) --#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT BIT(12) --#define MDIO_AN_RX_LP_STAT1_AQ_PHY BIT(2) -- --#define MDIO_AN_RX_LP_STAT4 0xe823 --#define MDIO_AN_RX_LP_STAT4_FW_MAJOR GENMASK(15, 8) --#define MDIO_AN_RX_LP_STAT4_FW_MINOR GENMASK(7, 0) -- --#define MDIO_AN_RX_VEND_STAT3 0xe832 --#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0) -- --/* MDIO_MMD_C22EXT */ --#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292 --#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294 --#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297 --#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313 --#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315 --#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317 --#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318 --#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319 --#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a --#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b -- --/* Vendor specific 1, MDIO_MMD_VEND1 */ --#define VEND1_GLOBAL_FW_ID 0x0020 --#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) --#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) -- --#define VEND1_GLOBAL_GEN_STAT2 0xc831 --#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15) -- --/* The following registers all have similar layouts; first the registers... */ --#define VEND1_GLOBAL_CFG_10M 0x0310 --#define VEND1_GLOBAL_CFG_100M 0x031b --#define VEND1_GLOBAL_CFG_1G 0x031c --#define VEND1_GLOBAL_CFG_2_5G 0x031d --#define VEND1_GLOBAL_CFG_5G 0x031e --#define VEND1_GLOBAL_CFG_10G 0x031f --/* ...and now the fields */ --#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7) --#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0 --#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1 --#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 -- --#define VEND1_GLOBAL_RSVD_STAT1 0xc885 --#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4) --#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0) -- --#define VEND1_GLOBAL_RSVD_STAT9 0xc88d --#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0) --#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23 -- --#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00 --#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01 -- --#define VEND1_GLOBAL_INT_STD_MASK 0xff00 --#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15) --#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14) --#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13) --#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12) --#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11) --#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10) --#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9) --#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8) --#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7) --#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6) --#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0) -- --#define VEND1_GLOBAL_INT_VEND_MASK 0xff01 --#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15) --#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14) --#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13) --#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12) --#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0) -- --/* Sleep and timeout for checking if the Processor-Intensive -- * MDIO operation is finished -- */ --#define AQR107_OP_IN_PROG_SLEEP 1000 --#define AQR107_OP_IN_PROG_TIMEOUT 100000 -- --struct aqr107_hw_stat { -- const char *name; -- int reg; -- int size; --}; -- --#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s } --static const struct aqr107_hw_stat aqr107_hw_stats[] = { -- SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26), -- SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26), -- SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8), -- SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26), -- SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26), -- SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8), -- SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8), -- SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8), -- SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16), -- SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22), --}; --#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats) -- --struct aqr107_priv { -- u64 sgmii_stats[AQR107_SGMII_STAT_SZ]; --}; -- --static int aqr107_get_sset_count(struct phy_device *phydev) --{ -- return AQR107_SGMII_STAT_SZ; --} -- --static void aqr107_get_strings(struct phy_device *phydev, u8 *data) --{ -- int i; -- -- for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) -- strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name, -- ETH_GSTRING_LEN); --} -- --static u64 aqr107_get_stat(struct phy_device *phydev, int index) --{ -- const struct aqr107_hw_stat *stat = aqr107_hw_stats + index; -- int len_l = min(stat->size, 16); -- int len_h = stat->size - len_l; -- u64 ret; -- int val; -- -- val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg); -- if (val < 0) -- return U64_MAX; -- -- ret = val & GENMASK(len_l - 1, 0); -- if (len_h) { -- val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1); -- if (val < 0) -- return U64_MAX; -- -- ret += (val & GENMASK(len_h - 1, 0)) << 16; -- } -- -- return ret; --} -- --static void aqr107_get_stats(struct phy_device *phydev, -- struct ethtool_stats *stats, u64 *data) --{ -- struct aqr107_priv *priv = phydev->priv; -- u64 val; -- int i; -- -- for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) { -- val = aqr107_get_stat(phydev, i); -- if (val == U64_MAX) -- phydev_err(phydev, "Reading HW Statistics failed for %s\n", -- aqr107_hw_stats[i].name); -- else -- priv->sgmii_stats[i] += val; -- -- data[i] = priv->sgmii_stats[i]; -- } --} -- --static int aqr_config_aneg(struct phy_device *phydev) --{ -- bool changed = false; -- u16 reg; -- int ret; -- -- if (phydev->autoneg == AUTONEG_DISABLE) -- return genphy_c45_pma_setup_forced(phydev); -- -- ret = genphy_c45_an_config_aneg(phydev); -- if (ret < 0) -- return ret; -- if (ret > 0) -- changed = true; -- -- /* Clause 45 has no standardized support for 1000BaseT, therefore -- * use vendor registers for this mode. -- */ -- reg = 0; -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -- phydev->advertising)) -- reg |= MDIO_AN_VEND_PROV_1000BASET_FULL; -- -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -- phydev->advertising)) -- reg |= MDIO_AN_VEND_PROV_1000BASET_HALF; -- -- /* Handle the case when the 2.5G and 5G speeds are not advertised */ -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -- phydev->advertising)) -- reg |= MDIO_AN_VEND_PROV_2500BASET_FULL; -- -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, -- phydev->advertising)) -- reg |= MDIO_AN_VEND_PROV_5000BASET_FULL; -- -- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, -- MDIO_AN_VEND_PROV_1000BASET_HALF | -- MDIO_AN_VEND_PROV_1000BASET_FULL | -- MDIO_AN_VEND_PROV_2500BASET_FULL | -- MDIO_AN_VEND_PROV_5000BASET_FULL, reg); -- if (ret < 0) -- return ret; -- if (ret > 0) -- changed = true; -- -- return genphy_c45_check_and_restart_aneg(phydev, changed); --} -- --static int aqr_config_intr(struct phy_device *phydev) --{ -- bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED; -- int err; -- -- if (en) { -- /* Clear any pending interrupts before enabling them */ -- err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2); -- if (err < 0) -- return err; -- } -- -- err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2, -- en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0); -- if (err < 0) -- return err; -- -- err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK, -- en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0); -- if (err < 0) -- return err; -- -- err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK, -- en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 | -- VEND1_GLOBAL_INT_VEND_MASK_AN : 0); -- if (err < 0) -- return err; -- -- if (!en) { -- /* Clear any pending interrupts after we have disabled them */ -- err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2); -- if (err < 0) -- return err; -- } -- -- return 0; --} -- --static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev) --{ -- int irq_status; -- -- irq_status = phy_read_mmd(phydev, MDIO_MMD_AN, -- MDIO_AN_TX_VEND_INT_STATUS2); -- if (irq_status < 0) { -- phy_error(phydev); -- return IRQ_NONE; -- } -- -- if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK)) -- return IRQ_NONE; -- -- phy_trigger_machine(phydev); -- -- return IRQ_HANDLED; --} -- --static int aqr_read_status(struct phy_device *phydev) --{ -- int val; -- -- if (phydev->autoneg == AUTONEG_ENABLE) { -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1); -- if (val < 0) -- return val; -- -- linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -- phydev->lp_advertising, -- val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL); -- linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -- phydev->lp_advertising, -- val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF); -- } -- -- return genphy_c45_read_status(phydev); --} -- --static int aqr107_read_rate(struct phy_device *phydev) --{ -- u32 config_reg; -- int val; -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1); -- if (val < 0) -- return val; -- -- if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX) -- phydev->duplex = DUPLEX_FULL; -- else -- phydev->duplex = DUPLEX_HALF; -- -- switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) { -- case MDIO_AN_TX_VEND_STATUS1_10BASET: -- phydev->speed = SPEED_10; -- config_reg = VEND1_GLOBAL_CFG_10M; -- break; -- case MDIO_AN_TX_VEND_STATUS1_100BASETX: -- phydev->speed = SPEED_100; -- config_reg = VEND1_GLOBAL_CFG_100M; -- break; -- case MDIO_AN_TX_VEND_STATUS1_1000BASET: -- phydev->speed = SPEED_1000; -- config_reg = VEND1_GLOBAL_CFG_1G; -- break; -- case MDIO_AN_TX_VEND_STATUS1_2500BASET: -- phydev->speed = SPEED_2500; -- config_reg = VEND1_GLOBAL_CFG_2_5G; -- break; -- case MDIO_AN_TX_VEND_STATUS1_5000BASET: -- phydev->speed = SPEED_5000; -- config_reg = VEND1_GLOBAL_CFG_5G; -- break; -- case MDIO_AN_TX_VEND_STATUS1_10GBASET: -- phydev->speed = SPEED_10000; -- config_reg = VEND1_GLOBAL_CFG_10G; -- break; -- default: -- phydev->speed = SPEED_UNKNOWN; -- return 0; -- } -- -- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg); -- if (val < 0) -- return val; -- -- if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) == -- VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE) -- phydev->rate_matching = RATE_MATCH_PAUSE; -- else -- phydev->rate_matching = RATE_MATCH_NONE; -- -- return 0; --} -- --static int aqr107_read_status(struct phy_device *phydev) --{ -- int val, ret; -- -- ret = aqr_read_status(phydev); -- if (ret) -- return ret; -- -- if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE) -- return 0; -- -- val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS); -- if (val < 0) -- return val; -- -- switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) { -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR: -- phydev->interface = PHY_INTERFACE_MODE_10GKR; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX: -- phydev->interface = PHY_INTERFACE_MODE_1000BASEKX; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI: -- phydev->interface = PHY_INTERFACE_MODE_10GBASER; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII: -- phydev->interface = PHY_INTERFACE_MODE_USXGMII; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI: -- phydev->interface = PHY_INTERFACE_MODE_XAUI; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII: -- phydev->interface = PHY_INTERFACE_MODE_SGMII; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI: -- phydev->interface = PHY_INTERFACE_MODE_RXAUI; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII: -- phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -- break; -- default: -- phydev->interface = PHY_INTERFACE_MODE_NA; -- break; -- } -- -- /* Read possibly downshifted rate from vendor register */ -- return aqr107_read_rate(phydev); --} -- --static int aqr107_get_downshift(struct phy_device *phydev, u8 *data) --{ -- int val, cnt, enable; -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV); -- if (val < 0) -- return val; -- -- enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val); -- cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val); -- -- *data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE; -- -- return 0; --} -- --static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt) --{ -- int val = 0; -- -- if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt)) -- return -E2BIG; -- -- if (cnt != DOWNSHIFT_DEV_DISABLE) { -- val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN; -- val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt); -- } -- -- return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, -- MDIO_AN_VEND_PROV_DOWNSHIFT_EN | -- MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val); --} -- --static int aqr107_get_tunable(struct phy_device *phydev, -- struct ethtool_tunable *tuna, void *data) --{ -- switch (tuna->id) { -- case ETHTOOL_PHY_DOWNSHIFT: -- return aqr107_get_downshift(phydev, data); -- default: -- return -EOPNOTSUPP; -- } --} -- --static int aqr107_set_tunable(struct phy_device *phydev, -- struct ethtool_tunable *tuna, const void *data) --{ -- switch (tuna->id) { -- case ETHTOOL_PHY_DOWNSHIFT: -- return aqr107_set_downshift(phydev, *(const u8 *)data); -- default: -- return -EOPNOTSUPP; -- } --} -- --/* If we configure settings whilst firmware is still initializing the chip, -- * then these settings may be overwritten. Therefore make sure chip -- * initialization has completed. Use presence of the firmware ID as -- * indicator for initialization having completed. -- * The chip also provides a "reset completed" bit, but it's cleared after -- * read. Therefore function would time out if called again. -- */ --static int aqr107_wait_reset_complete(struct phy_device *phydev) --{ -- int val; -- -- return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -- VEND1_GLOBAL_FW_ID, val, val != 0, -- 20000, 2000000, false); --} -- --static void aqr107_chip_info(struct phy_device *phydev) --{ -- u8 fw_major, fw_minor, build_id, prov_id; -- int val; -- -- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID); -- if (val < 0) -- return; -- -- fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val); -- fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val); -- -- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1); -- if (val < 0) -- return; -- -- build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val); -- prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val); -- -- phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n", -- fw_major, fw_minor, build_id, prov_id); --} -- --static int aqr107_config_init(struct phy_device *phydev) --{ -- int ret; -- -- /* Check that the PHY interface type is compatible */ -- if (phydev->interface != PHY_INTERFACE_MODE_SGMII && -- phydev->interface != PHY_INTERFACE_MODE_1000BASEKX && -- phydev->interface != PHY_INTERFACE_MODE_2500BASEX && -- phydev->interface != PHY_INTERFACE_MODE_XGMII && -- phydev->interface != PHY_INTERFACE_MODE_USXGMII && -- phydev->interface != PHY_INTERFACE_MODE_10GKR && -- phydev->interface != PHY_INTERFACE_MODE_10GBASER && -- phydev->interface != PHY_INTERFACE_MODE_XAUI && -- phydev->interface != PHY_INTERFACE_MODE_RXAUI) -- return -ENODEV; -- -- WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII, -- "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n"); -- -- ret = aqr107_wait_reset_complete(phydev); -- if (!ret) -- aqr107_chip_info(phydev); -- -- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); --} -- --static int aqcs109_config_init(struct phy_device *phydev) --{ -- int ret; -- -- /* Check that the PHY interface type is compatible */ -- if (phydev->interface != PHY_INTERFACE_MODE_SGMII && -- phydev->interface != PHY_INTERFACE_MODE_2500BASEX) -- return -ENODEV; -- -- ret = aqr107_wait_reset_complete(phydev); -- if (!ret) -- aqr107_chip_info(phydev); -- -- /* AQCS109 belongs to a chip family partially supporting 10G and 5G. -- * PMA speed ability bits are the same for all members of the family, -- * AQCS109 however supports speeds up to 2.5G only. -- */ -- ret = phy_set_max_speed(phydev, SPEED_2500); -- if (ret) -- return ret; -- -- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); --} -- --static void aqr107_link_change_notify(struct phy_device *phydev) --{ -- u8 fw_major, fw_minor; -- bool downshift, short_reach, afr; -- int mode, val; -- -- if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE) -- return; -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1); -- /* call failed or link partner is no Aquantia PHY */ -- if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY)) -- return; -- -- short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH; -- downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT; -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4); -- if (val < 0) -- return; -- -- fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val); -- fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val); -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3); -- if (val < 0) -- return; -- -- afr = val & MDIO_AN_RX_VEND_STAT3_AFR; -- -- phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n", -- fw_major, fw_minor, -- short_reach ? ", short reach mode" : "", -- downshift ? ", fast-retrain downshift advertised" : "", -- afr ? ", fast reframe advertised" : ""); -- -- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT9); -- if (val < 0) -- return; -- -- mode = FIELD_GET(VEND1_GLOBAL_RSVD_STAT9_MODE, val); -- if (mode == VEND1_GLOBAL_RSVD_STAT9_1000BT2) -- phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n"); --} -- --static int aqr107_wait_processor_intensive_op(struct phy_device *phydev) --{ -- int val, err; -- -- /* The datasheet notes to wait at least 1ms after issuing a -- * processor intensive operation before checking. -- * We cannot use the 'sleep_before_read' parameter of read_poll_timeout -- * because that just determines the maximum time slept, not the minimum. -- */ -- usleep_range(1000, 5000); -- -- err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -- VEND1_GLOBAL_GEN_STAT2, val, -- !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG), -- AQR107_OP_IN_PROG_SLEEP, -- AQR107_OP_IN_PROG_TIMEOUT, false); -- if (err) { -- phydev_err(phydev, "timeout: processor-intensive MDIO operation\n"); -- return err; -- } -- -- return 0; --} -- --static int aqr107_get_rate_matching(struct phy_device *phydev, -- phy_interface_t iface) --{ -- if (iface == PHY_INTERFACE_MODE_10GBASER || -- iface == PHY_INTERFACE_MODE_2500BASEX || -- iface == PHY_INTERFACE_MODE_NA) -- return RATE_MATCH_PAUSE; -- return RATE_MATCH_NONE; --} -- --static int aqr107_suspend(struct phy_device *phydev) --{ -- int err; -- -- err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, -- MDIO_CTRL1_LPOWER); -- if (err) -- return err; -- -- return aqr107_wait_processor_intensive_op(phydev); --} -- --static int aqr107_resume(struct phy_device *phydev) --{ -- int err; -- -- err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, -- MDIO_CTRL1_LPOWER); -- if (err) -- return err; -- -- return aqr107_wait_processor_intensive_op(phydev); --} -- --static int aqr107_probe(struct phy_device *phydev) --{ -- phydev->priv = devm_kzalloc(&phydev->mdio.dev, -- sizeof(struct aqr107_priv), GFP_KERNEL); -- if (!phydev->priv) -- return -ENOMEM; -- -- return aqr_hwmon_probe(phydev); --} -- --static struct phy_driver aqr_driver[] = { --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQ1202), -- .name = "Aquantia AQ1202", -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr_read_status, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQ2104), -- .name = "Aquantia AQ2104", -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr_read_status, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQR105), -- .name = "Aquantia AQR105", -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr_read_status, -- .suspend = aqr107_suspend, -- .resume = aqr107_resume, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQR106), -- .name = "Aquantia AQR106", -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr_read_status, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQR107), -- .name = "Aquantia AQR107", -- .probe = aqr107_probe, -- .get_rate_matching = aqr107_get_rate_matching, -- .config_init = aqr107_config_init, -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr107_read_status, -- .get_tunable = aqr107_get_tunable, -- .set_tunable = aqr107_set_tunable, -- .suspend = aqr107_suspend, -- .resume = aqr107_resume, -- .get_sset_count = aqr107_get_sset_count, -- .get_strings = aqr107_get_strings, -- .get_stats = aqr107_get_stats, -- .link_change_notify = aqr107_link_change_notify, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQCS109), -- .name = "Aquantia AQCS109", -- .probe = aqr107_probe, -- .get_rate_matching = aqr107_get_rate_matching, -- .config_init = aqcs109_config_init, -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr107_read_status, -- .get_tunable = aqr107_get_tunable, -- .set_tunable = aqr107_set_tunable, -- .suspend = aqr107_suspend, -- .resume = aqr107_resume, -- .get_sset_count = aqr107_get_sset_count, -- .get_strings = aqr107_get_strings, -- .get_stats = aqr107_get_stats, -- .link_change_notify = aqr107_link_change_notify, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQR405), -- .name = "Aquantia AQR405", -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr_read_status, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQR113C), -- .name = "Aquantia AQR113C", -- .probe = aqr107_probe, -- .get_rate_matching = aqr107_get_rate_matching, -- .config_init = aqr107_config_init, -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr107_read_status, -- .get_tunable = aqr107_get_tunable, -- .set_tunable = aqr107_set_tunable, -- .suspend = aqr107_suspend, -- .resume = aqr107_resume, -- .get_sset_count = aqr107_get_sset_count, -- .get_strings = aqr107_get_strings, -- .get_stats = aqr107_get_stats, -- .link_change_notify = aqr107_link_change_notify, --}, --}; -- --module_phy_driver(aqr_driver); -- --static struct mdio_device_id __maybe_unused aqr_tbl[] = { -- { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, -- { } --}; -- --MODULE_DEVICE_TABLE(mdio, aqr_tbl); -- --MODULE_DESCRIPTION("Aquantia PHY driver"); --MODULE_AUTHOR("Shaohui Xie "); --MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/backport-5.15/737-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch b/target/linux/generic/backport-5.15/737-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch deleted file mode 100644 index 2b945227237762..00000000000000 --- a/target/linux/generic/backport-5.15/737-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch +++ /dev/null @@ -1,183 +0,0 @@ -From e1fbfa4a995d42e02e22b0dff2f8b4fdee1504b3 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 14 Nov 2023 15:08:42 +0100 -Subject: [PATCH 2/3] net: phy: aquantia: move MMD_VEND define to header - -Move MMD_VEND define to header to clean things up and in preparation for -firmware loading support that require some define placed in -aquantia_main. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/aquantia/aquantia.h | 69 +++++++++++++++++++++++ - drivers/net/phy/aquantia/aquantia_hwmon.c | 14 ----- - drivers/net/phy/aquantia/aquantia_main.c | 55 ------------------ - 3 files changed, 69 insertions(+), 69 deletions(-) - ---- a/drivers/net/phy/aquantia/aquantia.h -+++ b/drivers/net/phy/aquantia/aquantia.h -@@ -9,6 +9,75 @@ - #include - #include - -+/* Vendor specific 1, MDIO_MMD_VEND1 */ -+#define VEND1_GLOBAL_FW_ID 0x0020 -+#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) -+#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) -+ -+/* The following registers all have similar layouts; first the registers... */ -+#define VEND1_GLOBAL_CFG_10M 0x0310 -+#define VEND1_GLOBAL_CFG_100M 0x031b -+#define VEND1_GLOBAL_CFG_1G 0x031c -+#define VEND1_GLOBAL_CFG_2_5G 0x031d -+#define VEND1_GLOBAL_CFG_5G 0x031e -+#define VEND1_GLOBAL_CFG_10G 0x031f -+/* ...and now the fields */ -+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7) -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0 -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1 -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 -+ -+/* Vendor specific 1, MDIO_MMD_VEND2 */ -+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421 -+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422 -+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423 -+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424 -+#define VEND1_THERMAL_STAT1 0xc820 -+#define VEND1_THERMAL_STAT2 0xc821 -+#define VEND1_THERMAL_STAT2_VALID BIT(0) -+#define VEND1_GENERAL_STAT1 0xc830 -+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14) -+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13) -+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12) -+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11) -+ -+#define VEND1_GLOBAL_GEN_STAT2 0xc831 -+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15) -+ -+#define VEND1_GLOBAL_RSVD_STAT1 0xc885 -+#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4) -+#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0) -+ -+#define VEND1_GLOBAL_RSVD_STAT9 0xc88d -+#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0) -+#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23 -+ -+#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00 -+#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01 -+ -+#define VEND1_GLOBAL_INT_STD_MASK 0xff00 -+#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15) -+#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11) -+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10) -+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9) -+#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8) -+#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7) -+#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6) -+#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0) -+ -+#define VEND1_GLOBAL_INT_VEND_MASK 0xff01 -+#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15) -+#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14) -+#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13) -+#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12) -+#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0) -+ - #if IS_REACHABLE(CONFIG_HWMON) - int aqr_hwmon_probe(struct phy_device *phydev); - #else ---- a/drivers/net/phy/aquantia/aquantia_hwmon.c -+++ b/drivers/net/phy/aquantia/aquantia_hwmon.c -@@ -13,20 +13,6 @@ - - #include "aquantia.h" - --/* Vendor specific 1, MDIO_MMD_VEND2 */ --#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421 --#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422 --#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423 --#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424 --#define VEND1_THERMAL_STAT1 0xc820 --#define VEND1_THERMAL_STAT2 0xc821 --#define VEND1_THERMAL_STAT2_VALID BIT(0) --#define VEND1_GENERAL_STAT1 0xc830 --#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14) --#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13) --#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12) --#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11) -- - #if IS_REACHABLE(CONFIG_HWMON) - - static umode_t aqr_hwmon_is_visible(const void *data, ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -89,61 +89,6 @@ - #define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a - #define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b - --/* Vendor specific 1, MDIO_MMD_VEND1 */ --#define VEND1_GLOBAL_FW_ID 0x0020 --#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) --#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) -- --#define VEND1_GLOBAL_GEN_STAT2 0xc831 --#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15) -- --/* The following registers all have similar layouts; first the registers... */ --#define VEND1_GLOBAL_CFG_10M 0x0310 --#define VEND1_GLOBAL_CFG_100M 0x031b --#define VEND1_GLOBAL_CFG_1G 0x031c --#define VEND1_GLOBAL_CFG_2_5G 0x031d --#define VEND1_GLOBAL_CFG_5G 0x031e --#define VEND1_GLOBAL_CFG_10G 0x031f --/* ...and now the fields */ --#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7) --#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0 --#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1 --#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 -- --#define VEND1_GLOBAL_RSVD_STAT1 0xc885 --#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4) --#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0) -- --#define VEND1_GLOBAL_RSVD_STAT9 0xc88d --#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0) --#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23 -- --#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00 --#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01 -- --#define VEND1_GLOBAL_INT_STD_MASK 0xff00 --#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15) --#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14) --#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13) --#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12) --#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11) --#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10) --#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9) --#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8) --#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7) --#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6) --#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0) -- --#define VEND1_GLOBAL_INT_VEND_MASK 0xff01 --#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15) --#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14) --#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13) --#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12) --#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0) -- - /* Sleep and timeout for checking if the Processor-Intensive - * MDIO operation is finished - */ diff --git a/target/linux/generic/backport-5.15/737-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch b/target/linux/generic/backport-5.15/737-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch deleted file mode 100644 index 1ae5966df6cede..00000000000000 --- a/target/linux/generic/backport-5.15/737-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch +++ /dev/null @@ -1,504 +0,0 @@ -From e93984ebc1c82bd34f7a1b3391efaceee0a8ae96 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Tue, 14 Nov 2023 15:08:43 +0100 -Subject: [PATCH 3/3] net: phy: aquantia: add firmware load support - -Aquantia PHY-s require firmware to be loaded before they start operating. -It can be automatically loaded in case when there is a SPI-NOR connected -to Aquantia PHY-s or can be loaded from the host via MDIO. - -This patch adds support for loading the firmware via MDIO as in most cases -there is no SPI-NOR being used to save on cost. -Firmware loading code itself is ported from mainline U-boot with cleanups. - -The firmware has mixed values both in big and little endian. -PHY core itself is big-endian but it expects values to be in little-endian. -The firmware is little-endian but CRC-16 value for it is stored at the end -of firmware in big-endian. - -It seems the PHY does the conversion internally from firmware that is -little-endian to the PHY that is big-endian on using the mailbox -but mailbox returns a big-endian CRC-16 to verify the written data -integrity. - -Co-developed-by: Christian Marangi -Signed-off-by: Robert Marko -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/aquantia/Kconfig | 1 + - drivers/net/phy/aquantia/Makefile | 2 +- - drivers/net/phy/aquantia/aquantia.h | 32 ++ - drivers/net/phy/aquantia/aquantia_firmware.c | 370 +++++++++++++++++++ - drivers/net/phy/aquantia/aquantia_main.c | 6 + - 5 files changed, 410 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/phy/aquantia/aquantia_firmware.c - ---- a/drivers/net/phy/aquantia/Kconfig -+++ b/drivers/net/phy/aquantia/Kconfig -@@ -1,5 +1,6 @@ - # SPDX-License-Identifier: GPL-2.0-only - config AQUANTIA_PHY - tristate "Aquantia PHYs" -+ select CRC_CCITT - help - Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405 ---- a/drivers/net/phy/aquantia/Makefile -+++ b/drivers/net/phy/aquantia/Makefile -@@ -1,5 +1,5 @@ - # SPDX-License-Identifier: GPL-2.0 --aquantia-objs += aquantia_main.o -+aquantia-objs += aquantia_main.o aquantia_firmware.o - ifdef CONFIG_HWMON - aquantia-objs += aquantia_hwmon.o - endif ---- a/drivers/net/phy/aquantia/aquantia.h -+++ b/drivers/net/phy/aquantia/aquantia.h -@@ -10,10 +10,35 @@ - #include - - /* Vendor specific 1, MDIO_MMD_VEND1 */ -+#define VEND1_GLOBAL_SC 0x0 -+#define VEND1_GLOBAL_SC_SOFT_RESET BIT(15) -+#define VEND1_GLOBAL_SC_LOW_POWER BIT(11) -+ - #define VEND1_GLOBAL_FW_ID 0x0020 - #define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) - #define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) - -+#define VEND1_GLOBAL_MAILBOX_INTERFACE1 0x0200 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE BIT(15) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE BIT(14) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET BIT(12) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_BUSY BIT(8) -+ -+#define VEND1_GLOBAL_MAILBOX_INTERFACE2 0x0201 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE3 0x0202 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK GENMASK(15, 0) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK, (u16)((x) >> 16)) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE4 0x0203 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK GENMASK(15, 2) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK, (u16)(x)) -+ -+#define VEND1_GLOBAL_MAILBOX_INTERFACE5 0x0204 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK GENMASK(15, 0) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK, (u16)((x) >> 16)) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE6 0x0205 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK GENMASK(15, 0) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK, (u16)(x)) -+ - /* The following registers all have similar layouts; first the registers... */ - #define VEND1_GLOBAL_CFG_10M 0x0310 - #define VEND1_GLOBAL_CFG_100M 0x031b -@@ -28,6 +53,11 @@ - #define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 - - /* Vendor specific 1, MDIO_MMD_VEND2 */ -+#define VEND1_GLOBAL_CONTROL2 0xc001 -+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST BIT(15) -+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD BIT(6) -+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL BIT(0) -+ - #define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421 - #define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422 - #define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423 -@@ -83,3 +113,5 @@ int aqr_hwmon_probe(struct phy_device *p - #else - static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; } - #endif -+ -+int aqr_firmware_load(struct phy_device *phydev); ---- /dev/null -+++ b/drivers/net/phy/aquantia/aquantia_firmware.c -@@ -0,0 +1,370 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "aquantia.h" -+ -+#define UP_RESET_SLEEP 100 -+ -+/* addresses of memory segments in the phy */ -+#define DRAM_BASE_ADDR 0x3FFE0000 -+#define IRAM_BASE_ADDR 0x40000000 -+ -+/* firmware image format constants */ -+#define VERSION_STRING_SIZE 0x40 -+#define VERSION_STRING_OFFSET 0x0200 -+/* primary offset is written at an offset from the start of the fw blob */ -+#define PRIMARY_OFFSET_OFFSET 0x8 -+/* primary offset needs to be then added to a base offset */ -+#define PRIMARY_OFFSET_SHIFT 12 -+#define PRIMARY_OFFSET(x) ((x) << PRIMARY_OFFSET_SHIFT) -+#define HEADER_OFFSET 0x300 -+ -+struct aqr_fw_header { -+ u32 padding; -+ u8 iram_offset[3]; -+ u8 iram_size[3]; -+ u8 dram_offset[3]; -+ u8 dram_size[3]; -+} __packed; -+ -+enum aqr_fw_src { -+ AQR_FW_SRC_NVMEM = 0, -+ AQR_FW_SRC_FS, -+}; -+ -+static const char * const aqr_fw_src_string[] = { -+ [AQR_FW_SRC_NVMEM] = "NVMEM", -+ [AQR_FW_SRC_FS] = "FS", -+}; -+ -+/* AQR firmware doesn't have fixed offsets for iram and dram section -+ * but instead provide an header with the offset to use on reading -+ * and parsing the firmware. -+ * -+ * AQR firmware can't be trusted and each offset is validated to be -+ * not negative and be in the size of the firmware itself. -+ */ -+static bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size) -+{ -+ return offset + get_size <= size; -+} -+ -+static int aqr_fw_get_be16(const u8 *data, size_t offset, size_t size, u16 *value) -+{ -+ if (!aqr_fw_validate_get(size, offset, sizeof(u16))) -+ return -EINVAL; -+ -+ *value = get_unaligned_be16(data + offset); -+ -+ return 0; -+} -+ -+static int aqr_fw_get_le16(const u8 *data, size_t offset, size_t size, u16 *value) -+{ -+ if (!aqr_fw_validate_get(size, offset, sizeof(u16))) -+ return -EINVAL; -+ -+ *value = get_unaligned_le16(data + offset); -+ -+ return 0; -+} -+ -+static int aqr_fw_get_le24(const u8 *data, size_t offset, size_t size, u32 *value) -+{ -+ if (!aqr_fw_validate_get(size, offset, sizeof(u8) * 3)) -+ return -EINVAL; -+ -+ *value = get_unaligned_le24(data + offset); -+ -+ return 0; -+} -+ -+/* load data into the phy's memory */ -+static int aqr_fw_load_memory(struct phy_device *phydev, u32 addr, -+ const u8 *data, size_t len) -+{ -+ u16 crc = 0, up_crc; -+ size_t pos; -+ -+ /* PHY expect addr in LE */ -+ addr = (__force u32)cpu_to_le32(addr); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_MAILBOX_INTERFACE1, -+ VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET); -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_MAILBOX_INTERFACE3, -+ VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(addr)); -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_MAILBOX_INTERFACE4, -+ VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(addr)); -+ -+ /* We assume and enforce the size to be word aligned. -+ * If a firmware that is not word aligned is found, please report upstream. -+ */ -+ for (pos = 0; pos < len; pos += sizeof(u32)) { -+ u32 word; -+ -+ /* FW data is always stored in little-endian */ -+ word = get_unaligned((const u32 *)(data + pos)); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE5, -+ VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(word)); -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE6, -+ VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(word)); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE1, -+ VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE | -+ VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE); -+ -+ /* calculate CRC as we load data to the mailbox. -+ * We convert word to big-endian as PHY is BE and mailbox will -+ * return a BE CRC. -+ */ -+ word = (__force u32)cpu_to_be32(word); -+ crc = crc_ccitt_false(crc, (u8 *)&word, sizeof(word)); -+ } -+ -+ up_crc = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE2); -+ if (crc != up_crc) { -+ phydev_err(phydev, "CRC mismatch: calculated 0x%04x PHY 0x%04x\n", -+ crc, up_crc); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size, -+ enum aqr_fw_src fw_src) -+{ -+ u16 calculated_crc, read_crc, read_primary_offset; -+ u32 iram_offset = 0, iram_size = 0; -+ u32 dram_offset = 0, dram_size = 0; -+ char version[VERSION_STRING_SIZE]; -+ u32 primary_offset = 0; -+ int ret; -+ -+ /* extract saved CRC at the end of the fw -+ * CRC is saved in big-endian as PHY is BE -+ */ -+ ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc); -+ if (ret) { -+ phydev_err(phydev, "bad firmware CRC in firmware\n"); -+ return ret; -+ } -+ calculated_crc = crc_ccitt_false(0, data, size - sizeof(u16)); -+ if (read_crc != calculated_crc) { -+ phydev_err(phydev, "bad firmware CRC: file 0x%04x calculated 0x%04x\n", -+ read_crc, calculated_crc); -+ return -EINVAL; -+ } -+ -+ /* Get the primary offset to extract DRAM and IRAM sections. */ -+ ret = aqr_fw_get_le16(data, PRIMARY_OFFSET_OFFSET, size, &read_primary_offset); -+ if (ret) { -+ phydev_err(phydev, "bad primary offset in firmware\n"); -+ return ret; -+ } -+ primary_offset = PRIMARY_OFFSET(read_primary_offset); -+ -+ /* Find the DRAM and IRAM sections within the firmware file. -+ * Make sure the fw_header is correctly in the firmware. -+ */ -+ if (!aqr_fw_validate_get(size, primary_offset + HEADER_OFFSET, -+ sizeof(struct aqr_fw_header))) { -+ phydev_err(phydev, "bad fw_header in firmware\n"); -+ return -EINVAL; -+ } -+ -+ /* offset are in LE and values needs to be converted to cpu endian */ -+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET + -+ offsetof(struct aqr_fw_header, iram_offset), -+ size, &iram_offset); -+ if (ret) { -+ phydev_err(phydev, "bad iram offset in firmware\n"); -+ return ret; -+ } -+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET + -+ offsetof(struct aqr_fw_header, iram_size), -+ size, &iram_size); -+ if (ret) { -+ phydev_err(phydev, "invalid iram size in firmware\n"); -+ return ret; -+ } -+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET + -+ offsetof(struct aqr_fw_header, dram_offset), -+ size, &dram_offset); -+ if (ret) { -+ phydev_err(phydev, "bad dram offset in firmware\n"); -+ return ret; -+ } -+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET + -+ offsetof(struct aqr_fw_header, dram_size), -+ size, &dram_size); -+ if (ret) { -+ phydev_err(phydev, "invalid dram size in firmware\n"); -+ return ret; -+ } -+ -+ /* Increment the offset with the primary offset. -+ * Validate iram/dram offset and size. -+ */ -+ iram_offset += primary_offset; -+ if (iram_size % sizeof(u32)) { -+ phydev_err(phydev, "iram size if not aligned to word size. Please report this upstream!\n"); -+ return -EINVAL; -+ } -+ if (!aqr_fw_validate_get(size, iram_offset, iram_size)) { -+ phydev_err(phydev, "invalid iram offset for iram size\n"); -+ return -EINVAL; -+ } -+ -+ dram_offset += primary_offset; -+ if (dram_size % sizeof(u32)) { -+ phydev_err(phydev, "dram size if not aligned to word size. Please report this upstream!\n"); -+ return -EINVAL; -+ } -+ if (!aqr_fw_validate_get(size, dram_offset, dram_size)) { -+ phydev_err(phydev, "invalid iram offset for iram size\n"); -+ return -EINVAL; -+ } -+ -+ phydev_dbg(phydev, "primary %d IRAM offset=%d size=%d DRAM offset=%d size=%d\n", -+ primary_offset, iram_offset, iram_size, dram_offset, dram_size); -+ -+ if (!aqr_fw_validate_get(size, dram_offset + VERSION_STRING_OFFSET, -+ VERSION_STRING_SIZE)) { -+ phydev_err(phydev, "invalid version in firmware\n"); -+ return -EINVAL; -+ } -+ strscpy(version, (char *)data + dram_offset + VERSION_STRING_OFFSET, -+ VERSION_STRING_SIZE); -+ if (version[0] == '\0') { -+ phydev_err(phydev, "invalid version in firmware\n"); -+ return -EINVAL; -+ } -+ phydev_info(phydev, "loading firmware version '%s' from '%s'\n", version, -+ aqr_fw_src_string[fw_src]); -+ -+ /* stall the microcprocessor */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2, -+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL | VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD); -+ -+ phydev_dbg(phydev, "loading DRAM 0x%08x from offset=%d size=%d\n", -+ DRAM_BASE_ADDR, dram_offset, dram_size); -+ ret = aqr_fw_load_memory(phydev, DRAM_BASE_ADDR, data + dram_offset, -+ dram_size); -+ if (ret) -+ return ret; -+ -+ phydev_dbg(phydev, "loading IRAM 0x%08x from offset=%d size=%d\n", -+ IRAM_BASE_ADDR, iram_offset, iram_size); -+ ret = aqr_fw_load_memory(phydev, IRAM_BASE_ADDR, data + iram_offset, -+ iram_size); -+ if (ret) -+ return ret; -+ -+ /* make sure soft reset and low power mode are clear */ -+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_SC, -+ VEND1_GLOBAL_SC_SOFT_RESET | VEND1_GLOBAL_SC_LOW_POWER); -+ -+ /* Release the microprocessor. UP_RESET must be held for 100 usec. */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2, -+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL | -+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD | -+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST); -+ usleep_range(UP_RESET_SLEEP, UP_RESET_SLEEP * 2); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2, -+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD); -+ -+ return 0; -+} -+ -+static int aqr_firmware_load_nvmem(struct phy_device *phydev) -+{ -+ struct nvmem_cell *cell; -+ size_t size; -+ u8 *buf; -+ int ret; -+ -+ cell = nvmem_cell_get(&phydev->mdio.dev, "firmware"); -+ if (IS_ERR(cell)) -+ return PTR_ERR(cell); -+ -+ buf = nvmem_cell_read(cell, &size); -+ if (IS_ERR(buf)) { -+ ret = PTR_ERR(buf); -+ goto exit; -+ } -+ -+ ret = aqr_fw_boot(phydev, buf, size, AQR_FW_SRC_NVMEM); -+ if (ret) -+ phydev_err(phydev, "firmware loading failed: %d\n", ret); -+ -+ kfree(buf); -+exit: -+ nvmem_cell_put(cell); -+ -+ return ret; -+} -+ -+static int aqr_firmware_load_fs(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ const struct firmware *fw; -+ const char *fw_name; -+ int ret; -+ -+ ret = of_property_read_string(dev->of_node, "firmware-name", -+ &fw_name); -+ if (ret) -+ return ret; -+ -+ ret = request_firmware(&fw, fw_name, dev); -+ if (ret) { -+ phydev_err(phydev, "failed to find FW file %s (%d)\n", -+ fw_name, ret); -+ return ret; -+ } -+ -+ ret = aqr_fw_boot(phydev, fw->data, fw->size, AQR_FW_SRC_FS); -+ if (ret) -+ phydev_err(phydev, "firmware loading failed: %d\n", ret); -+ -+ release_firmware(fw); -+ -+ return ret; -+} -+ -+int aqr_firmware_load(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Check if the firmware is not already loaded by pooling -+ * the current version returned by the PHY. If 0 is returned, -+ * no firmware is loaded. -+ */ -+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID); -+ if (ret > 0) -+ goto exit; -+ -+ ret = aqr_firmware_load_nvmem(phydev); -+ if (!ret) -+ goto exit; -+ -+ ret = aqr_firmware_load_fs(phydev); -+ if (ret) -+ return ret; -+ -+exit: -+ return 0; -+} ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -658,11 +658,17 @@ static int aqr107_resume(struct phy_devi - - static int aqr107_probe(struct phy_device *phydev) - { -+ int ret; -+ - phydev->priv = devm_kzalloc(&phydev->mdio.dev, - sizeof(struct aqr107_priv), GFP_KERNEL); - if (!phydev->priv) - return -ENOMEM; - -+ ret = aqr_firmware_load(phydev); -+ if (ret) -+ return ret; -+ - return aqr_hwmon_probe(phydev); - } - diff --git a/target/linux/generic/backport-5.15/738-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch b/target/linux/generic/backport-5.15/738-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch deleted file mode 100644 index d130794c08403e..00000000000000 --- a/target/linux/generic/backport-5.15/738-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 038ba1dc4e54d51d953f5618d8eb5dd39bd9de25 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 13 Feb 2024 14:35:51 +0100 -Subject: [PATCH] net: phy: aquantia: add AQR111 and AQR111B0 PHY ID - -Add Aquantia AQR111 and AQR111B0 PHY ID. These PHY advertise 10G speed -but actually supports up to 5G speed, hence some manual fixup is needed. - -The Aquantia AQR111B0 PHY is just a variant of the AQR111 with smaller -chip size. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240213133558.1836-1-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/aquantia/aquantia_main.c | 52 ++++++++++++++++++++++++ - 1 file changed, 52 insertions(+) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -22,6 +22,8 @@ - #define PHY_ID_AQR107 0x03a1b4e0 - #define PHY_ID_AQCS109 0x03a1b5c2 - #define PHY_ID_AQR405 0x03a1b4b0 -+#define PHY_ID_AQR111 0x03a1b610 -+#define PHY_ID_AQR111B0 0x03a1b612 - #define PHY_ID_AQR113C 0x31c31c12 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 -@@ -672,6 +674,16 @@ static int aqr107_probe(struct phy_devic - return aqr_hwmon_probe(phydev); - } - -+static int aqr111_config_init(struct phy_device *phydev) -+{ -+ /* AQR111 reports supporting speed up to 10G, -+ * however only speeds up to 5G are supported. -+ */ -+ phy_set_max_speed(phydev, SPEED_5000); -+ -+ return aqr107_config_init(phydev); -+} -+ - static struct phy_driver aqr_driver[] = { - { - PHY_ID_MATCH_MODEL(PHY_ID_AQ1202), -@@ -746,6 +758,42 @@ static struct phy_driver aqr_driver[] = - .link_change_notify = aqr107_link_change_notify, - }, - { -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR111), -+ .name = "Aquantia AQR111", -+ .probe = aqr107_probe, -+ .config_init = aqr111_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0), -+ .name = "Aquantia AQR111B0", -+ .probe = aqr107_probe, -+ .config_init = aqr111_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+{ - PHY_ID_MATCH_MODEL(PHY_ID_AQR405), - .name = "Aquantia AQR405", - .config_aneg = aqr_config_aneg, -@@ -784,6 +832,8 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR111) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, - { } - }; diff --git a/target/linux/generic/backport-5.15/739-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch b/target/linux/generic/backport-5.15/739-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch deleted file mode 100644 index 5a46ab39cf061a..00000000000000 --- a/target/linux/generic/backport-5.15/739-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 71b605d32017e5b8d257db7344bc2f8e8fcc973e Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 15 Feb 2024 16:30:05 +0100 -Subject: [PATCH] net: phy: aquantia: add AQR113 PHY ID - -Add Aquantia AQR113 PHY ID. Aquantia AQR113 is just a chip size variant of -the already supported AQR133C where the only difference is the PHY ID -and the hw chip size. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/aquantia/aquantia_main.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -24,6 +24,7 @@ - #define PHY_ID_AQR405 0x03a1b4b0 - #define PHY_ID_AQR111 0x03a1b610 - #define PHY_ID_AQR111B0 0x03a1b612 -+#define PHY_ID_AQR113 0x31c31c40 - #define PHY_ID_AQR113C 0x31c31c12 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 -@@ -802,6 +803,24 @@ static struct phy_driver aqr_driver[] = - .read_status = aqr_read_status, - }, - { -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113), -+ .name = "Aquantia AQR113", -+ .probe = aqr107_probe, -+ .config_init = aqr107_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+{ - PHY_ID_MATCH_MODEL(PHY_ID_AQR113C), - .name = "Aquantia AQR113C", - .probe = aqr107_probe, -@@ -834,6 +853,7 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR111) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, - { } - }; diff --git a/target/linux/generic/backport-5.15/740-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch b/target/linux/generic/backport-5.15/740-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch deleted file mode 100644 index 49651a5e4f474c..00000000000000 --- a/target/linux/generic/backport-5.15/740-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 6d47302a3f0ba31445478d518d98bd55918bc8ab Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 15 Feb 2024 22:43:30 +0100 -Subject: [PATCH] net: phy: aquantia: add AQR813 PHY ID - -Aquantia AQR813 is the Octal Port variant of the AQR113. Add PHY ID for -it to provide support for it. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/aquantia/aquantia_main.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -26,6 +26,7 @@ - #define PHY_ID_AQR111B0 0x03a1b612 - #define PHY_ID_AQR113 0x31c31c40 - #define PHY_ID_AQR113C 0x31c31c12 -+#define PHY_ID_AQR813 0x31c31cb2 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -@@ -839,6 +840,24 @@ static struct phy_driver aqr_driver[] = - .get_stats = aqr107_get_stats, - .link_change_notify = aqr107_link_change_notify, - }, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR813), -+ .name = "Aquantia AQR813", -+ .probe = aqr107_probe, -+ .config_init = aqr107_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, - }; - - module_phy_driver(aqr_driver); -@@ -855,6 +874,7 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, - { } - }; - diff --git a/target/linux/generic/backport-5.15/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch b/target/linux/generic/backport-5.15/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch deleted file mode 100644 index 03171d72cc7882..00000000000000 --- a/target/linux/generic/backport-5.15/742-v5.16-net-phy-at803x-add-support-for-qca-8327-internal-phy.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0ccf8511182436183c031e8a2f740ae91a02c625 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 14 Sep 2021 14:33:45 +0200 -Subject: net: phy: at803x: add support for qca 8327 internal phy - -Add support for qca8327 internal phy needed for correct init of the -switch port. It does use the same qca8337 function and reg just with a -different id. - -Signed-off-by: Ansuel Smith -Tested-by: Rosen Penev -Tested-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1410,6 +1410,19 @@ static struct phy_driver at803x_driver[] - .get_sset_count = at803x_get_sset_count, - .get_strings = at803x_get_strings, - .get_stats = at803x_get_stats, -+}, { -+ /* QCA8327 */ -+ .phy_id = QCA8327_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "QCA PHY 8327", -+ /* PHY_GBIT_FEATURES */ -+ .probe = at803x_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca83xx_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = at803x_get_sset_count, -+ .get_strings = at803x_get_strings, -+ .get_stats = at803x_get_stats, - }, }; - - module_phy_driver(at803x_driver); -@@ -1420,6 +1433,8 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) }, - { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) }, - { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA8327_PHY_ID) }, - { } - }; - diff --git a/target/linux/generic/backport-5.15/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch b/target/linux/generic/backport-5.15/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch deleted file mode 100644 index dc149a742b1af4..00000000000000 --- a/target/linux/generic/backport-5.15/743-v5.16-0001-net-dsa-b53-Include-all-ports-in-enabled_ports.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 983d96a9116a328668601555d96736261d33170c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 16 Sep 2021 14:03:51 +0200 -Subject: [PATCH] net: dsa: b53: Include all ports in "enabled_ports" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make "enabled_ports" bitfield contain all available switch ports -including a CPU port. This way there is no need for fixup during -initialization. - -For BCM53010, BCM53018 and BCM53019 include also other available ports. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Florian Fainelli -Tested-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 23 +++++++++++------------ - 1 file changed, 11 insertions(+), 12 deletions(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -2300,7 +2300,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM5325_DEVICE_ID, - .dev_name = "BCM5325", - .vlans = 16, -- .enabled_ports = 0x1f, -+ .enabled_ports = 0x3f, - .arl_bins = 2, - .arl_buckets = 1024, - .imp_port = 5, -@@ -2311,7 +2311,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM5365_DEVICE_ID, - .dev_name = "BCM5365", - .vlans = 256, -- .enabled_ports = 0x1f, -+ .enabled_ports = 0x3f, - .arl_bins = 2, - .arl_buckets = 1024, - .imp_port = 5, -@@ -2322,7 +2322,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM5389_DEVICE_ID, - .dev_name = "BCM5389", - .vlans = 4096, -- .enabled_ports = 0x1f, -+ .enabled_ports = 0x11f, - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -@@ -2336,7 +2336,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM5395_DEVICE_ID, - .dev_name = "BCM5395", - .vlans = 4096, -- .enabled_ports = 0x1f, -+ .enabled_ports = 0x11f, - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -@@ -2350,7 +2350,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM5397_DEVICE_ID, - .dev_name = "BCM5397", - .vlans = 4096, -- .enabled_ports = 0x1f, -+ .enabled_ports = 0x11f, - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -@@ -2364,7 +2364,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM5398_DEVICE_ID, - .dev_name = "BCM5398", - .vlans = 4096, -- .enabled_ports = 0x7f, -+ .enabled_ports = 0x17f, - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -@@ -2378,7 +2378,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM53115_DEVICE_ID, - .dev_name = "BCM53115", - .vlans = 4096, -- .enabled_ports = 0x1f, -+ .enabled_ports = 0x11f, - .arl_bins = 4, - .arl_buckets = 1024, - .vta_regs = B53_VTA_REGS, -@@ -2392,7 +2392,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM53125_DEVICE_ID, - .dev_name = "BCM53125", - .vlans = 4096, -- .enabled_ports = 0xff, -+ .enabled_ports = 0x1ff, - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -@@ -2434,7 +2434,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM53010_DEVICE_ID, - .dev_name = "BCM53010", - .vlans = 4096, -- .enabled_ports = 0x1f, -+ .enabled_ports = 0x1bf, - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -@@ -2476,7 +2476,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM53018_DEVICE_ID, - .dev_name = "BCM53018", - .vlans = 4096, -- .enabled_ports = 0x1f, -+ .enabled_ports = 0x1bf, - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -@@ -2490,7 +2490,7 @@ static const struct b53_chip_data b53_sw - .chip_id = BCM53019_DEVICE_ID, - .dev_name = "BCM53019", - .vlans = 4096, -- .enabled_ports = 0x1f, -+ .enabled_ports = 0x1bf, - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -@@ -2632,7 +2632,6 @@ static int b53_switch_init(struct b53_de - dev->cpu_port = 5; - } - -- dev->enabled_ports |= BIT(dev->cpu_port); - dev->num_ports = fls(dev->enabled_ports); - - dev->ds->num_ports = min_t(unsigned int, dev->num_ports, DSA_MAX_PORTS); diff --git a/target/linux/generic/backport-5.15/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch b/target/linux/generic/backport-5.15/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch deleted file mode 100644 index 23805a9027b3bb..00000000000000 --- a/target/linux/generic/backport-5.15/743-v5.16-0002-net-dsa-b53-Drop-BCM5301x-workaround-for-a-wrong-CPU.patch +++ /dev/null @@ -1,42 +0,0 @@ -From b290c6384afabbca5ae6e2af72fb1b2bc37922be Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 16 Sep 2021 14:03:52 +0200 -Subject: [PATCH] net: dsa: b53: Drop BCM5301x workaround for a wrong CPU/IMP - port -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On BCM5301x port 8 requires a fixed link when used. - -Years ago when b53 was an OpenWrt downstream driver (with configuration -based on sometimes bugged NVRAM) there was a need for a fixup. In case -of forcing fixed link for (incorrectly specified) port 5 the code had to -actually setup port 8 link. - -For upstream b53 driver with setup based on DT there is no need for that -workaround. In DT we have and require correct ports setup. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Florian Fainelli -Tested-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 6 ------ - 1 file changed, 6 deletions(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -1291,12 +1291,6 @@ static void b53_adjust_link(struct dsa_s - return; - } - } -- } else if (is5301x(dev)) { -- if (port != dev->cpu_port) { -- b53_force_port_config(dev, dev->cpu_port, 2000, -- DUPLEX_FULL, true, true); -- b53_force_link(dev, dev->cpu_port, 1); -- } - } - - /* Re-negotiate EEE if it was enabled already */ diff --git a/target/linux/generic/backport-5.15/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch b/target/linux/generic/backport-5.15/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch deleted file mode 100644 index 941fa23eb4c669..00000000000000 --- a/target/linux/generic/backport-5.15/743-v5.16-0003-net-dsa-b53-Improve-flow-control-setup-on-BCM5301x.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3ff26b29230c54fea2353b63124c589b61953e14 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 16 Sep 2021 14:03:53 +0200 -Subject: [PATCH] net: dsa: b53: Improve flow control setup on BCM5301x -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -According to the Broadcom's reference driver flow control needs to be -enabled for any CPU switch port (5, 7 or 8 - depending on which one is -used). Current code makes it work only for the port 5. Use -dsa_is_cpu_port() which solved that problem. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Florian Fainelli -Tested-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -1222,7 +1222,7 @@ static void b53_adjust_link(struct dsa_s - return; - - /* Enable flow control on BCM5301x's CPU port */ -- if (is5301x(dev) && port == dev->cpu_port) -+ if (is5301x(dev) && dsa_is_cpu_port(ds, port)) - tx_pause = rx_pause = true; - - if (phydev->pause) { diff --git a/target/linux/generic/backport-5.15/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch b/target/linux/generic/backport-5.15/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch deleted file mode 100644 index 07d0ec03cf1792..00000000000000 --- a/target/linux/generic/backport-5.15/743-v5.16-0004-net-dsa-b53-Drop-unused-cpu_port-field.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 7d5af56418d7d01e43247a33b6fe6492ea871923 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 16 Sep 2021 14:03:54 +0200 -Subject: [PATCH] net: dsa: b53: Drop unused "cpu_port" field -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It's set but never used anymore. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Florian Fainelli -Tested-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/b53/b53_common.c | 28 ---------------------------- - drivers/net/dsa/b53/b53_priv.h | 1 - - 2 files changed, 29 deletions(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -2298,7 +2298,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 2, - .arl_buckets = 1024, - .imp_port = 5, -- .cpu_port = B53_CPU_PORT_25, - .duplex_reg = B53_DUPLEX_STAT_FE, - }, - { -@@ -2309,7 +2308,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 2, - .arl_buckets = 1024, - .imp_port = 5, -- .cpu_port = B53_CPU_PORT_25, - .duplex_reg = B53_DUPLEX_STAT_FE, - }, - { -@@ -2320,7 +2318,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2334,7 +2331,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2348,7 +2344,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS_9798, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2362,7 +2357,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS_9798, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2377,7 +2371,6 @@ static const struct b53_chip_data b53_sw - .arl_buckets = 1024, - .vta_regs = B53_VTA_REGS, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, - .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -@@ -2390,7 +2383,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2404,7 +2396,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2418,7 +2409,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS_63XX, - .duplex_reg = B53_DUPLEX_STAT_63XX, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, -@@ -2432,7 +2422,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2446,7 +2435,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2460,7 +2448,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2474,7 +2461,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2488,7 +2474,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2502,7 +2487,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2516,7 +2500,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2545,7 +2528,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 1024, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2559,7 +2541,6 @@ static const struct b53_chip_data b53_sw - .arl_bins = 4, - .arl_buckets = 256, - .imp_port = 8, -- .cpu_port = B53_CPU_PORT, - .vta_regs = B53_VTA_REGS, - .duplex_reg = B53_DUPLEX_STAT_GE, - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -@@ -2585,7 +2566,6 @@ static int b53_switch_init(struct b53_de - dev->vta_regs[2] = chip->vta_regs[2]; - dev->jumbo_pm_reg = chip->jumbo_pm_reg; - dev->imp_port = chip->imp_port; -- dev->cpu_port = chip->cpu_port; - dev->num_vlans = chip->vlans; - dev->num_arl_bins = chip->arl_bins; - dev->num_arl_buckets = chip->arl_buckets; -@@ -2617,13 +2597,6 @@ static int b53_switch_init(struct b53_de - break; - #endif - } -- } else if (dev->chip_id == BCM53115_DEVICE_ID) { -- u64 strap_value; -- -- b53_read48(dev, B53_STAT_PAGE, B53_STRAP_VALUE, &strap_value); -- /* use second IMP port if GMII is enabled */ -- if (strap_value & SV_GMII_CTRL_115) -- dev->cpu_port = 5; - } - - dev->num_ports = fls(dev->enabled_ports); ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -124,7 +124,6 @@ struct b53_device { - /* used ports mask */ - u16 enabled_ports; - unsigned int imp_port; -- unsigned int cpu_port; - - /* connect specific data */ - u8 current_page; diff --git a/target/linux/generic/backport-5.15/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch b/target/linux/generic/backport-5.15/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch deleted file mode 100644 index 7e4e9462e85ad7..00000000000000 --- a/target/linux/generic/backport-5.15/745-v5.16-01-net-phy-at803x-add-support-for-qca-8327-A-variant.patch +++ /dev/null @@ -1,65 +0,0 @@ -From b4df02b562f4aa14ff6811f30e1b4d2159585c59 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sun, 19 Sep 2021 18:28:15 +0200 -Subject: net: phy: at803x: add support for qca 8327 A variant internal phy - -For qca8327 internal phy there are 2 different switch variant with 2 -different phy id. Add this missing variant so the internal phy can be -correctly identified and fixed. - -Signed-off-by: Ansuel Smith -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 25 ++++++++++++++++++++----- - 1 file changed, 20 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -150,7 +150,8 @@ - #define ATH8035_PHY_ID 0x004dd072 - #define AT8030_PHY_ID_MASK 0xffffffef - --#define QCA8327_PHY_ID 0x004dd034 -+#define QCA8327_A_PHY_ID 0x004dd033 -+#define QCA8327_B_PHY_ID 0x004dd034 - #define QCA8337_PHY_ID 0x004dd036 - #define QCA8K_PHY_ID_MASK 0xffffffff - -@@ -1411,10 +1412,23 @@ static struct phy_driver at803x_driver[] - .get_strings = at803x_get_strings, - .get_stats = at803x_get_stats, - }, { -- /* QCA8327 */ -- .phy_id = QCA8327_PHY_ID, -+ /* QCA8327-A from switch QCA8327-AL1A */ -+ .phy_id = QCA8327_A_PHY_ID, - .phy_id_mask = QCA8K_PHY_ID_MASK, -- .name = "QCA PHY 8327", -+ .name = "QCA PHY 8327-A", -+ /* PHY_GBIT_FEATURES */ -+ .probe = at803x_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca83xx_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = at803x_get_sset_count, -+ .get_strings = at803x_get_strings, -+ .get_stats = at803x_get_stats, -+}, { -+ /* QCA8327-B from switch QCA8327-BL1A */ -+ .phy_id = QCA8327_B_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "QCA PHY 8327-B", - /* PHY_GBIT_FEATURES */ - .probe = at803x_probe, - .flags = PHY_IS_INTERNAL, -@@ -1434,7 +1448,8 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) }, - { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) }, - { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(QCA8327_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) }, - { } - }; - diff --git a/target/linux/generic/backport-5.15/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch b/target/linux/generic/backport-5.15/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch deleted file mode 100644 index 89aca23194dfa2..00000000000000 --- a/target/linux/generic/backport-5.15/745-v5.16-02-net-phy-at803x-add-resume-suspend-function-to-qca83x.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 15b9df4ece17d084f14eb0ca1cf05f2ad497e425 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sun, 19 Sep 2021 18:28:16 +0200 -Subject: net: phy: at803x: add resume/suspend function to qca83xx phy - -Add resume/suspend function to qca83xx internal phy. -We can't use the at803x generic function as the documentation lacks of -any support for WoL regs. - -Signed-off-by: Ansuel Smith -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1411,6 +1411,8 @@ static struct phy_driver at803x_driver[] - .get_sset_count = at803x_get_sset_count, - .get_strings = at803x_get_strings, - .get_stats = at803x_get_stats, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, - }, { - /* QCA8327-A from switch QCA8327-AL1A */ - .phy_id = QCA8327_A_PHY_ID, -@@ -1424,6 +1426,8 @@ static struct phy_driver at803x_driver[] - .get_sset_count = at803x_get_sset_count, - .get_strings = at803x_get_strings, - .get_stats = at803x_get_stats, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, - }, { - /* QCA8327-B from switch QCA8327-BL1A */ - .phy_id = QCA8327_B_PHY_ID, -@@ -1437,6 +1441,8 @@ static struct phy_driver at803x_driver[] - .get_sset_count = at803x_get_sset_count, - .get_strings = at803x_get_strings, - .get_stats = at803x_get_stats, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, - }, }; - - module_phy_driver(at803x_driver); diff --git a/target/linux/generic/backport-5.15/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch b/target/linux/generic/backport-5.15/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch deleted file mode 100644 index 920bef24fd68bb..00000000000000 --- a/target/linux/generic/backport-5.15/745-v5.16-03-net-phy-at803x-fix-spacing-and-improve-name-for-83xx.patch +++ /dev/null @@ -1,95 +0,0 @@ -From d44fd8604a4ab92119adb35f05fd87612af722b5 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sun, 19 Sep 2021 18:28:17 +0200 -Subject: net: phy: at803x: fix spacing and improve name for 83xx phy - -Fix spacing and improve name for 83xx phy following other phy in the -same driver. - -Signed-off-by: Ansuel Smith -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 60 ++++++++++++++++++++++++------------------------ - 1 file changed, 30 insertions(+), 30 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1400,47 +1400,47 @@ static struct phy_driver at803x_driver[] - .config_aneg = at803x_config_aneg, - }, { - /* QCA8337 */ -- .phy_id = QCA8337_PHY_ID, -- .phy_id_mask = QCA8K_PHY_ID_MASK, -- .name = "QCA PHY 8337", -+ .phy_id = QCA8337_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "Qualcomm Atheros 8337 internal PHY", - /* PHY_GBIT_FEATURES */ -- .probe = at803x_probe, -- .flags = PHY_IS_INTERNAL, -- .config_init = qca83xx_config_init, -- .soft_reset = genphy_soft_reset, -- .get_sset_count = at803x_get_sset_count, -- .get_strings = at803x_get_strings, -- .get_stats = at803x_get_stats, -+ .probe = at803x_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca83xx_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = at803x_get_sset_count, -+ .get_strings = at803x_get_strings, -+ .get_stats = at803x_get_stats, - .suspend = genphy_suspend, - .resume = genphy_resume, - }, { - /* QCA8327-A from switch QCA8327-AL1A */ -- .phy_id = QCA8327_A_PHY_ID, -- .phy_id_mask = QCA8K_PHY_ID_MASK, -- .name = "QCA PHY 8327-A", -+ .phy_id = QCA8327_A_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "Qualcomm Atheros 8327-A internal PHY", - /* PHY_GBIT_FEATURES */ -- .probe = at803x_probe, -- .flags = PHY_IS_INTERNAL, -- .config_init = qca83xx_config_init, -- .soft_reset = genphy_soft_reset, -- .get_sset_count = at803x_get_sset_count, -- .get_strings = at803x_get_strings, -- .get_stats = at803x_get_stats, -+ .probe = at803x_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca83xx_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = at803x_get_sset_count, -+ .get_strings = at803x_get_strings, -+ .get_stats = at803x_get_stats, - .suspend = genphy_suspend, - .resume = genphy_resume, - }, { - /* QCA8327-B from switch QCA8327-BL1A */ -- .phy_id = QCA8327_B_PHY_ID, -- .phy_id_mask = QCA8K_PHY_ID_MASK, -- .name = "QCA PHY 8327-B", -+ .phy_id = QCA8327_B_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "Qualcomm Atheros 8327-B internal PHY", - /* PHY_GBIT_FEATURES */ -- .probe = at803x_probe, -- .flags = PHY_IS_INTERNAL, -- .config_init = qca83xx_config_init, -- .soft_reset = genphy_soft_reset, -- .get_sset_count = at803x_get_sset_count, -- .get_strings = at803x_get_strings, -- .get_stats = at803x_get_stats, -+ .probe = at803x_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca83xx_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = at803x_get_sset_count, -+ .get_strings = at803x_get_strings, -+ .get_stats = at803x_get_stats, - .suspend = genphy_suspend, - .resume = genphy_resume, - }, }; diff --git a/target/linux/generic/backport-5.15/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch b/target/linux/generic/backport-5.15/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch deleted file mode 100644 index 1029420ea9b3e7..00000000000000 --- a/target/linux/generic/backport-5.15/746-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch +++ /dev/null @@ -1,131 +0,0 @@ -From ba3c01ee02ed0d821c9f241f179bbc9457542b8f Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sun, 10 Oct 2021 00:46:15 +0200 -Subject: net: phy: at803x: fix resume for QCA8327 phy - -From Documentation phy resume triggers phy reset and restart -auto-negotiation. Add a dedicated function to wait reset to finish as -it was notice a regression where port sometime are not reliable after a -suspend/resume session. The reset wait logic is copied from phy_poll_reset. -Add dedicated suspend function to use genphy_suspend only with QCA8337 -phy and set only additional debug settings for QCA8327. With more test -it was reported that QCA8327 doesn't proprely support this mode and -using this cause the unreliability of the switch ports, especially the -malfunction of the port0. - -Fixes: 15b9df4ece17 ("net: phy: at803x: add resume/suspend function to qca83xx phy") -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 69 +++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 63 insertions(+), 6 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -92,9 +92,14 @@ - #define AT803X_DEBUG_REG_5 0x05 - #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) - -+#define AT803X_DEBUG_REG_HIB_CTRL 0x0b -+#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10) -+#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13) -+ - #define AT803X_DEBUG_REG_3C 0x3C - - #define AT803X_DEBUG_REG_3D 0x3D -+#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6) - - #define AT803X_DEBUG_REG_1F 0x1F - #define AT803X_DEBUG_PLL_ON BIT(2) -@@ -1304,6 +1309,58 @@ static int qca83xx_config_init(struct ph - return 0; - } - -+static int qca83xx_resume(struct phy_device *phydev) -+{ -+ int ret, val; -+ -+ /* Skip reset if not suspended */ -+ if (!phydev->suspended) -+ return 0; -+ -+ /* Reinit the port, reset values set by suspend */ -+ qca83xx_config_init(phydev); -+ -+ /* Reset the port on port resume */ -+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); -+ -+ /* On resume from suspend the switch execute a reset and -+ * restart auto-negotiation. Wait for reset to complete. -+ */ -+ ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET), -+ 50000, 600000, true); -+ if (ret) -+ return ret; -+ -+ msleep(1); -+ -+ return 0; -+} -+ -+static int qca83xx_suspend(struct phy_device *phydev) -+{ -+ u16 mask = 0; -+ -+ /* Only QCA8337 support actual suspend. -+ * QCA8327 cause port unreliability when phy suspend -+ * is set. -+ */ -+ if (phydev->drv->phy_id == QCA8337_PHY_ID) { -+ genphy_suspend(phydev); -+ } else { -+ mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX); -+ phy_modify(phydev, MII_BMCR, mask, 0); -+ } -+ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_3D, -+ AT803X_DEBUG_GATE_CLK_IN1000, 0); -+ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL, -+ AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE | -+ AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0); -+ -+ return 0; -+} -+ - static struct phy_driver at803x_driver[] = { - { - /* Qualcomm Atheros AR8035 */ -@@ -1411,8 +1468,8 @@ static struct phy_driver at803x_driver[] - .get_sset_count = at803x_get_sset_count, - .get_strings = at803x_get_strings, - .get_stats = at803x_get_stats, -- .suspend = genphy_suspend, -- .resume = genphy_resume, -+ .suspend = qca83xx_suspend, -+ .resume = qca83xx_resume, - }, { - /* QCA8327-A from switch QCA8327-AL1A */ - .phy_id = QCA8327_A_PHY_ID, -@@ -1426,8 +1483,8 @@ static struct phy_driver at803x_driver[] - .get_sset_count = at803x_get_sset_count, - .get_strings = at803x_get_strings, - .get_stats = at803x_get_stats, -- .suspend = genphy_suspend, -- .resume = genphy_resume, -+ .suspend = qca83xx_suspend, -+ .resume = qca83xx_resume, - }, { - /* QCA8327-B from switch QCA8327-BL1A */ - .phy_id = QCA8327_B_PHY_ID, -@@ -1441,8 +1498,8 @@ static struct phy_driver at803x_driver[] - .get_sset_count = at803x_get_sset_count, - .get_strings = at803x_get_strings, - .get_stats = at803x_get_stats, -- .suspend = genphy_suspend, -- .resume = genphy_resume, -+ .suspend = qca83xx_suspend, -+ .resume = qca83xx_resume, - }, }; - - module_phy_driver(at803x_driver); diff --git a/target/linux/generic/backport-5.15/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch b/target/linux/generic/backport-5.15/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch deleted file mode 100644 index 5813619c5c4a90..00000000000000 --- a/target/linux/generic/backport-5.15/746-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 1ca8311949aec5c9447645731ef1c6bc5bd71350 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sun, 10 Oct 2021 00:46:16 +0200 -Subject: net: phy: at803x: add DAC amplitude fix for 8327 phy - -QCA8327 internal phy require DAC amplitude adjustement set to +6% with -100m speed. Also add additional define to report a change of the same -reg in QCA8337. (different scope it does set 1000m voltage) -Add link_change_notify function to set the proper amplitude adjustement -on PHY_RUNNING state and disable on any other state. - -Fixes: b4df02b562f4 ("net: phy: at803x: add support for qca 8327 A variant internal phy") -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 33 +++++++++++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -87,6 +87,8 @@ - #define AT803X_PSSR_MR_AN_COMPLETE 0x0200 - - #define AT803X_DEBUG_REG_0 0x00 -+#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2) -+#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2) - #define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) - - #define AT803X_DEBUG_REG_5 0x05 -@@ -1306,9 +1308,37 @@ static int qca83xx_config_init(struct ph - break; - } - -+ /* QCA8327 require DAC amplitude adjustment for 100m set to +6%. -+ * Disable on init and enable only with 100m speed following -+ * qca original source code. -+ */ -+ if (phydev->drv->phy_id == QCA8327_A_PHY_ID || -+ phydev->drv->phy_id == QCA8327_B_PHY_ID) -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, -+ QCA8327_DEBUG_MANU_CTRL_EN, 0); -+ - return 0; - } - -+static void qca83xx_link_change_notify(struct phy_device *phydev) -+{ -+ /* QCA8337 doesn't require DAC Amplitude adjustement */ -+ if (phydev->drv->phy_id == QCA8337_PHY_ID) -+ return; -+ -+ /* Set DAC Amplitude adjustment to +6% for 100m on link running */ -+ if (phydev->state == PHY_RUNNING) { -+ if (phydev->speed == SPEED_100) -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, -+ QCA8327_DEBUG_MANU_CTRL_EN, -+ QCA8327_DEBUG_MANU_CTRL_EN); -+ } else { -+ /* Reset DAC Amplitude adjustment */ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, -+ QCA8327_DEBUG_MANU_CTRL_EN, 0); -+ } -+} -+ - static int qca83xx_resume(struct phy_device *phydev) - { - int ret, val; -@@ -1461,6 +1491,7 @@ static struct phy_driver at803x_driver[] - .phy_id_mask = QCA8K_PHY_ID_MASK, - .name = "Qualcomm Atheros 8337 internal PHY", - /* PHY_GBIT_FEATURES */ -+ .link_change_notify = qca83xx_link_change_notify, - .probe = at803x_probe, - .flags = PHY_IS_INTERNAL, - .config_init = qca83xx_config_init, -@@ -1476,6 +1507,7 @@ static struct phy_driver at803x_driver[] - .phy_id_mask = QCA8K_PHY_ID_MASK, - .name = "Qualcomm Atheros 8327-A internal PHY", - /* PHY_GBIT_FEATURES */ -+ .link_change_notify = qca83xx_link_change_notify, - .probe = at803x_probe, - .flags = PHY_IS_INTERNAL, - .config_init = qca83xx_config_init, -@@ -1491,6 +1523,7 @@ static struct phy_driver at803x_driver[] - .phy_id_mask = QCA8K_PHY_ID_MASK, - .name = "Qualcomm Atheros 8327-B internal PHY", - /* PHY_GBIT_FEATURES */ -+ .link_change_notify = qca83xx_link_change_notify, - .probe = at803x_probe, - .flags = PHY_IS_INTERNAL, - .config_init = qca83xx_config_init, diff --git a/target/linux/generic/backport-5.15/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch b/target/linux/generic/backport-5.15/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch deleted file mode 100644 index 9f880593f12c5e..00000000000000 --- a/target/linux/generic/backport-5.15/746-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 9d1c29b4028557a496be9c5eb2b4b86063700636 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sun, 10 Oct 2021 00:46:17 +0200 -Subject: net: phy: at803x: enable prefer master for 83xx internal phy - -From original QCA source code the port was set to prefer master as port -type in 1000BASE-T mode. Apply the same settings also here. - -Signed-off-by: Ansuel Smith -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1317,6 +1317,9 @@ static int qca83xx_config_init(struct ph - at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, - QCA8327_DEBUG_MANU_CTRL_EN, 0); - -+ /* Following original QCA sourcecode set port to prefer master */ -+ phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER); -+ - return 0; - } - diff --git a/target/linux/generic/backport-5.15/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch b/target/linux/generic/backport-5.15/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch deleted file mode 100644 index 89e9b3f66231e1..00000000000000 --- a/target/linux/generic/backport-5.15/746-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 67999555ff42e91de7654488d9a7735bd9e84555 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sun, 10 Oct 2021 00:46:18 +0200 -Subject: net: phy: at803x: better describe debug regs - -Give a name to known debug regs from Documentation instead of using -unknown hex values. - -Signed-off-by: Ansuel Smith -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 30 +++++++++++++++--------------- - 1 file changed, 15 insertions(+), 15 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -86,12 +86,12 @@ - #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/ - #define AT803X_PSSR_MR_AN_COMPLETE 0x0200 - --#define AT803X_DEBUG_REG_0 0x00 -+#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00 - #define QCA8327_DEBUG_MANU_CTRL_EN BIT(2) - #define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2) - #define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) - --#define AT803X_DEBUG_REG_5 0x05 -+#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05 - #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) - - #define AT803X_DEBUG_REG_HIB_CTRL 0x0b -@@ -100,7 +100,7 @@ - - #define AT803X_DEBUG_REG_3C 0x3C - --#define AT803X_DEBUG_REG_3D 0x3D -+#define AT803X_DEBUG_REG_GREEN 0x3D - #define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6) - - #define AT803X_DEBUG_REG_1F 0x1F -@@ -284,25 +284,25 @@ static int at803x_read_page(struct phy_d - - static int at803x_enable_rx_delay(struct phy_device *phydev) - { -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0, -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0, - AT803X_DEBUG_RX_CLK_DLY_EN); - } - - static int at803x_enable_tx_delay(struct phy_device *phydev) - { -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0, -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0, - AT803X_DEBUG_TX_CLK_DLY_EN); - } - - static int at803x_disable_rx_delay(struct phy_device *phydev) - { -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, - AT803X_DEBUG_RX_CLK_DLY_EN, 0); - } - - static int at803x_disable_tx_delay(struct phy_device *phydev) - { -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, - AT803X_DEBUG_TX_CLK_DLY_EN, 0); - } - -@@ -1292,9 +1292,9 @@ static int qca83xx_config_init(struct ph - switch (switch_revision) { - case 1: - /* For 100M waveform */ -- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_0, 0x02ea); -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea); - /* Turn on Gigabit clock */ -- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x68a0); -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0); - break; - - case 2: -@@ -1302,8 +1302,8 @@ static int qca83xx_config_init(struct ph - fallthrough; - case 4: - phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f); -- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x6860); -- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_5, 0x2c46); -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860); -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46); - at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000); - break; - } -@@ -1314,7 +1314,7 @@ static int qca83xx_config_init(struct ph - */ - if (phydev->drv->phy_id == QCA8327_A_PHY_ID || - phydev->drv->phy_id == QCA8327_B_PHY_ID) -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, - QCA8327_DEBUG_MANU_CTRL_EN, 0); - - /* Following original QCA sourcecode set port to prefer master */ -@@ -1332,12 +1332,12 @@ static void qca83xx_link_change_notify(s - /* Set DAC Amplitude adjustment to +6% for 100m on link running */ - if (phydev->state == PHY_RUNNING) { - if (phydev->speed == SPEED_100) -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, - QCA8327_DEBUG_MANU_CTRL_EN, - QCA8327_DEBUG_MANU_CTRL_EN); - } else { - /* Reset DAC Amplitude adjustment */ -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, - QCA8327_DEBUG_MANU_CTRL_EN, 0); - } - } -@@ -1384,7 +1384,7 @@ static int qca83xx_suspend(struct phy_de - phy_modify(phydev, MII_BMCR, mask, 0); - } - -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_3D, -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN, - AT803X_DEBUG_GATE_CLK_IN1000, 0); - - at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL, diff --git a/target/linux/generic/backport-5.15/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch b/target/linux/generic/backport-5.15/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch deleted file mode 100644 index c8d424de38c518..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-01-dsa-qca8k-add-mac-power-sel-support.patch +++ /dev/null @@ -1,80 +0,0 @@ -From d8b6f5bae6d3b648a67b6958cb98e4e97256d652 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:06 +0200 -Subject: dsa: qca8k: add mac_power_sel support - -Add missing mac power sel support needed for ipq8064/5 SoC that require -1.8v for the internal regulator port instead of the default 1.5v. -If other device needs this, consider adding a dedicated binding to -support this. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 31 +++++++++++++++++++++++++++++++ - drivers/net/dsa/qca8k.h | 5 +++++ - 2 files changed, 36 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -951,6 +951,33 @@ qca8k_setup_of_rgmii_delay(struct qca8k_ - } - - static int -+qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) -+{ -+ u32 mask = 0; -+ int ret = 0; -+ -+ /* SoC specific settings for ipq8064. -+ * If more device require this consider adding -+ * a dedicated binding. -+ */ -+ if (of_machine_is_compatible("qcom,ipq8064")) -+ mask |= QCA8K_MAC_PWR_RGMII0_1_8V; -+ -+ /* SoC specific settings for ipq8065 */ -+ if (of_machine_is_compatible("qcom,ipq8065")) -+ mask |= QCA8K_MAC_PWR_RGMII1_1_8V; -+ -+ if (mask) { -+ ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, -+ QCA8K_MAC_PWR_RGMII0_1_8V | -+ QCA8K_MAC_PWR_RGMII1_1_8V, -+ mask); -+ } -+ -+ return ret; -+} -+ -+static int - qca8k_setup(struct dsa_switch *ds) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -@@ -979,6 +1006,10 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -+ ret = qca8k_setup_mac_pwr_sel(priv); -+ if (ret) -+ return ret; -+ - /* Enable CPU Port */ - ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0, - QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -100,6 +100,11 @@ - #define QCA8K_SGMII_MODE_CTRL_PHY (1 << 22) - #define QCA8K_SGMII_MODE_CTRL_MAC (2 << 22) - -+/* MAC_PWR_SEL registers */ -+#define QCA8K_REG_MAC_PWR_SEL 0x0e4 -+#define QCA8K_MAC_PWR_RGMII1_1_8V BIT(18) -+#define QCA8K_MAC_PWR_RGMII0_1_8V BIT(19) -+ - /* EEE control registers */ - #define QCA8K_REG_EEE_CTRL 0x100 - #define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2) diff --git a/target/linux/generic/backport-5.15/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch b/target/linux/generic/backport-5.15/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch deleted file mode 100644 index bd768ec27d4d4a..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-02-dt-bindings-net-dsa-qca8k-Add-SGMII-clock-phase-prop.patch +++ /dev/null @@ -1,30 +0,0 @@ -From fdbf35df9c091db9c46e57e9938e3f7a4f603a7c Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:07 +0200 -Subject: dt-bindings: net: dsa: qca8k: Add SGMII clock phase properties - -Add names and descriptions of additional PORT0_PAD_CTRL properties. -qca,sgmii-(rx|tx)clk-falling-edge are for setting the respective clock -phase to failling edge. - -Co-developed-by: Matthew Hagan -Signed-off-by: Matthew Hagan -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - Documentation/devicetree/bindings/net/dsa/qca8k.txt | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt -+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt -@@ -37,6 +37,10 @@ A CPU port node has the following option - managed entity. See - Documentation/devicetree/bindings/net/fixed-link.txt - for details. -+- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge. -+ Mostly used in qca8327 with CPU port 0 set to -+ sgmii. -+- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge. - - For QCA8K the 'fixed-link' sub-node supports only the following properties: - diff --git a/target/linux/generic/backport-5.15/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch b/target/linux/generic/backport-5.15/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch deleted file mode 100644 index e464452d82c10a..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-03-net-dsa-qca8k-add-support-for-sgmii-falling-edge.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 6c43809bf1bee76c434e365a26546a92a5fbec14 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:08 +0200 -Subject: net: dsa: qca8k: add support for sgmii falling edge - -Add support for this in the qca8k driver. Also add support for SGMII -rx/tx clock falling edge. This is only present for pad0, pad5 and -pad6 have these bit reserved from Documentation. Add a comment that this -is hardcoded to PAD0 as qca8327/28/34/37 have an unique sgmii line and -setting falling in port0 applies to both configuration with sgmii used -for port0 or port6. - -Co-developed-by: Matthew Hagan -Signed-off-by: Matthew Hagan -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ - drivers/net/dsa/qca8k.h | 4 ++++ - 2 files changed, 67 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -978,6 +978,42 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri - } - - static int -+qca8k_parse_port_config(struct qca8k_priv *priv) -+{ -+ struct device_node *port_dn; -+ phy_interface_t mode; -+ struct dsa_port *dp; -+ int port, ret; -+ -+ /* We have 2 CPU port. Check them */ -+ for (port = 0; port < QCA8K_NUM_PORTS; port++) { -+ /* Skip every other port */ -+ if (port != 0 && port != 6) -+ continue; -+ -+ dp = dsa_to_port(priv->ds, port); -+ port_dn = dp->dn; -+ -+ if (!of_device_is_available(port_dn)) -+ continue; -+ -+ ret = of_get_phy_mode(port_dn, &mode); -+ if (ret) -+ continue; -+ -+ if (mode == PHY_INTERFACE_MODE_SGMII) { -+ if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) -+ priv->sgmii_tx_clk_falling_edge = true; -+ -+ if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) -+ priv->sgmii_rx_clk_falling_edge = true; -+ } -+ } -+ -+ return 0; -+} -+ -+static int - qca8k_setup(struct dsa_switch *ds) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -@@ -990,6 +1026,11 @@ qca8k_setup(struct dsa_switch *ds) - return -EINVAL; - } - -+ /* Parse CPU port config to be later used in phy_link mac_config */ -+ ret = qca8k_parse_port_config(priv); -+ if (ret) -+ return ret; -+ - mutex_init(&priv->reg_mutex); - - /* Start by setting up the register mapping */ -@@ -1274,6 +1315,28 @@ qca8k_phylink_mac_config(struct dsa_swit - } - - qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); -+ -+ /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and -+ * falling edge is set writing in the PORT0 PAD reg -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8327 || -+ priv->switch_id == QCA8K_ID_QCA8337) -+ reg = QCA8K_REG_PORT0_PAD_CTRL; -+ -+ val = 0; -+ -+ /* SGMII Clock phase configuration */ -+ if (priv->sgmii_rx_clk_falling_edge) -+ val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; -+ -+ if (priv->sgmii_tx_clk_falling_edge) -+ val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; -+ -+ if (val) -+ ret = qca8k_rmw(priv, reg, -+ QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | -+ QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, -+ val); - break; - default: - dev_err(ds->dev, "xMII mode %s not supported for port %d\n", ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -35,6 +35,8 @@ - #define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8) - #define QCA8K_MASK_CTRL_DEVICE_ID(x) ((x) >> 8) - #define QCA8K_REG_PORT0_PAD_CTRL 0x004 -+#define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19) -+#define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18) - #define QCA8K_REG_PORT5_PAD_CTRL 0x008 - #define QCA8K_REG_PORT6_PAD_CTRL 0x00c - #define QCA8K_PORT_PAD_RGMII_EN BIT(26) -@@ -260,6 +262,8 @@ struct qca8k_priv { - u8 switch_revision; - u8 rgmii_tx_delay; - u8 rgmii_rx_delay; -+ bool sgmii_rx_clk_falling_edge; -+ bool sgmii_tx_clk_falling_edge; - bool legacy_phy_port_mapping; - struct regmap *regmap; - struct mii_bus *bus; diff --git a/target/linux/generic/backport-5.15/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch b/target/linux/generic/backport-5.15/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch deleted file mode 100644 index 606ac0af3da220..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-04-dt-bindings-net-dsa-qca8k-Document-support-for-CPU-p.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 731d613338ec6de482053ffa3f71be2325b0f8eb Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:09 +0200 -Subject: dt-bindings: net: dsa: qca8k: Document support for CPU port 6 - -The switch now support CPU port to be set 6 instead of be hardcoded to -0. Document support for it and describe logic selection. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - Documentation/devicetree/bindings/net/dsa/qca8k.txt | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt -+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt -@@ -29,7 +29,11 @@ the mdio MASTER is used as communication - Don't use mixed external and internal mdio-bus configurations, as this is - not supported by the hardware. - --The CPU port of this switch is always port 0. -+This switch support 2 CPU port. Normally and advised configuration is with -+CPU port set to port 0. It is also possible to set the CPU port to port 6 -+if the device requires it. The driver will configure the switch to the defined -+port. With both CPU port declared the first CPU port is selected as primary -+and the secondary CPU ignored. - - A CPU port node has the following optional node: - diff --git a/target/linux/generic/backport-5.15/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch b/target/linux/generic/backport-5.15/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch deleted file mode 100644 index 320db8fa9f9f8e..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-05-net-dsa-qca8k-add-support-for-cpu-port-6.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 3fcf734aa482487df83cf8f18608438fcf59127f Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:10 +0200 -Subject: net: dsa: qca8k: add support for cpu port 6 - -Currently CPU port is always hardcoded to port 0. This switch have 2 CPU -ports. The original intention of this driver seems to be use the -mac06_exchange bit to swap MAC0 with MAC6 in the strange configuration -where device have connected only the CPU port 6. To skip the -introduction of a new binding, rework the driver to address the -secondary CPU port as primary and drop any reference of hardcoded port. -With configuration of mac06 exchange, just skip the definition of port0 -and define the CPU port as a secondary. The driver will autoconfigure -the switch to use that as the primary CPU port. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 51 ++++++++++++++++++++++++++++++++++--------------- - drivers/net/dsa/qca8k.h | 2 -- - 2 files changed, 36 insertions(+), 17 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -977,6 +977,22 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri - return ret; - } - -+static int qca8k_find_cpu_port(struct dsa_switch *ds) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ /* Find the connected cpu port. Valid port are 0 or 6 */ -+ if (dsa_is_cpu_port(ds, 0)) -+ return 0; -+ -+ dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6"); -+ -+ if (dsa_is_cpu_port(ds, 6)) -+ return 6; -+ -+ return -EINVAL; -+} -+ - static int - qca8k_parse_port_config(struct qca8k_priv *priv) - { -@@ -1017,13 +1033,13 @@ static int - qca8k_setup(struct dsa_switch *ds) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int ret, i; -+ int cpu_port, ret, i; - u32 mask; - -- /* Make sure that port 0 is the cpu port */ -- if (!dsa_is_cpu_port(ds, 0)) { -- dev_err(priv->dev, "port 0 is not the CPU port"); -- return -EINVAL; -+ cpu_port = qca8k_find_cpu_port(ds); -+ if (cpu_port < 0) { -+ dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6"); -+ return cpu_port; - } - - /* Parse CPU port config to be later used in phy_link mac_config */ -@@ -1065,7 +1081,7 @@ qca8k_setup(struct dsa_switch *ds) - dev_warn(priv->dev, "mib init failed"); - - /* Enable QCA header mode on the cpu port */ -- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT), -+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port), - QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S | - QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S); - if (ret) { -@@ -1087,10 +1103,10 @@ qca8k_setup(struct dsa_switch *ds) - - /* Forward all unknown frames to CPU port for Linux processing */ - ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, -- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S | -- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S | -- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S | -- BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S); -+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S | -+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S | -+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S | -+ BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S); - if (ret) - return ret; - -@@ -1098,7 +1114,7 @@ qca8k_setup(struct dsa_switch *ds) - for (i = 0; i < QCA8K_NUM_PORTS; i++) { - /* CPU port gets connected to all user ports of the switch */ - if (dsa_is_cpu_port(ds, i)) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT), -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port), - QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); - if (ret) - return ret; -@@ -1110,7 +1126,7 @@ qca8k_setup(struct dsa_switch *ds) - - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), - QCA8K_PORT_LOOKUP_MEMBER, -- BIT(QCA8K_CPU_PORT)); -+ BIT(cpu_port)); - if (ret) - return ret; - -@@ -1616,9 +1632,12 @@ static int - qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int port_mask = BIT(QCA8K_CPU_PORT); -+ int port_mask, cpu_port; - int i, ret; - -+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -+ port_mask = BIT(cpu_port); -+ - for (i = 1; i < QCA8K_NUM_PORTS; i++) { - if (dsa_to_port(ds, i)->bridge_dev != br) - continue; -@@ -1645,7 +1664,9 @@ static void - qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int i; -+ int cpu_port, i; -+ -+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; - - for (i = 1; i < QCA8K_NUM_PORTS; i++) { - if (dsa_to_port(ds, i)->bridge_dev != br) -@@ -1662,7 +1683,7 @@ qca8k_port_bridge_leave(struct dsa_switc - * this port - */ - qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_MEMBER, BIT(QCA8K_CPU_PORT)); -+ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); - } - - static int ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -24,8 +24,6 @@ - - #define QCA8K_NUM_FDB_RECORDS 2048 - --#define QCA8K_CPU_PORT 0 -- - #define QCA8K_PORT_VID_DEF 1 - - /* Global control registers */ diff --git a/target/linux/generic/backport-5.15/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch b/target/linux/generic/backport-5.15/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch deleted file mode 100644 index de201764f98782..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-06-net-dsa-qca8k-rework-rgmii-delay-logic-and-scan-for-.patch +++ /dev/null @@ -1,295 +0,0 @@ -From 5654ec78dd7e64b1e04777b24007344329e6a63b Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:11 +0200 -Subject: net: dsa: qca8k: rework rgmii delay logic and scan for cpu port 6 - -Future proof commit. This switch have 2 CPU ports and one valid -configuration is first CPU port set to sgmii and second CPU port set to -rgmii-id. The current implementation detects delay only for CPU port -zero set to rgmii and doesn't count any delay set in a secondary CPU -port. Drop the current delay scan function and move it to the sgmii -parser function to generalize and implicitly add support for secondary -CPU port set to rgmii-id. Introduce new logic where delay is enabled -also with internal delay binding declared and rgmii set as PHY mode. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 165 ++++++++++++++++++++++++------------------------ - drivers/net/dsa/qca8k.h | 10 ++- - 2 files changed, 89 insertions(+), 86 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -889,68 +889,6 @@ qca8k_setup_mdio_bus(struct qca8k_priv * - } - - static int --qca8k_setup_of_rgmii_delay(struct qca8k_priv *priv) --{ -- struct device_node *port_dn; -- phy_interface_t mode; -- struct dsa_port *dp; -- u32 val; -- -- /* CPU port is already checked */ -- dp = dsa_to_port(priv->ds, 0); -- -- port_dn = dp->dn; -- -- /* Check if port 0 is set to the correct type */ -- of_get_phy_mode(port_dn, &mode); -- if (mode != PHY_INTERFACE_MODE_RGMII_ID && -- mode != PHY_INTERFACE_MODE_RGMII_RXID && -- mode != PHY_INTERFACE_MODE_RGMII_TXID) { -- return 0; -- } -- -- switch (mode) { -- case PHY_INTERFACE_MODE_RGMII_ID: -- case PHY_INTERFACE_MODE_RGMII_RXID: -- if (of_property_read_u32(port_dn, "rx-internal-delay-ps", &val)) -- val = 2; -- else -- /* Switch regs accept value in ns, convert ps to ns */ -- val = val / 1000; -- -- if (val > QCA8K_MAX_DELAY) { -- dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); -- val = 3; -- } -- -- priv->rgmii_rx_delay = val; -- /* Stop here if we need to check only for rx delay */ -- if (mode != PHY_INTERFACE_MODE_RGMII_ID) -- break; -- -- fallthrough; -- case PHY_INTERFACE_MODE_RGMII_TXID: -- if (of_property_read_u32(port_dn, "tx-internal-delay-ps", &val)) -- val = 1; -- else -- /* Switch regs accept value in ns, convert ps to ns */ -- val = val / 1000; -- -- if (val > QCA8K_MAX_DELAY) { -- dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); -- val = 3; -- } -- -- priv->rgmii_tx_delay = val; -- break; -- default: -- return 0; -- } -- -- return 0; --} -- --static int - qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) - { - u32 mask = 0; -@@ -996,19 +934,21 @@ static int qca8k_find_cpu_port(struct ds - static int - qca8k_parse_port_config(struct qca8k_priv *priv) - { -+ int port, cpu_port_index = 0, ret; - struct device_node *port_dn; - phy_interface_t mode; - struct dsa_port *dp; -- int port, ret; -+ u32 delay; - - /* We have 2 CPU port. Check them */ -- for (port = 0; port < QCA8K_NUM_PORTS; port++) { -+ for (port = 0; port < QCA8K_NUM_PORTS && cpu_port_index < QCA8K_NUM_CPU_PORTS; port++) { - /* Skip every other port */ - if (port != 0 && port != 6) - continue; - - dp = dsa_to_port(priv->ds, port); - port_dn = dp->dn; -+ cpu_port_index++; - - if (!of_device_is_available(port_dn)) - continue; -@@ -1017,12 +957,54 @@ qca8k_parse_port_config(struct qca8k_pri - if (ret) - continue; - -- if (mode == PHY_INTERFACE_MODE_SGMII) { -+ switch (mode) { -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ delay = 0; -+ -+ if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay)) -+ /* Switch regs accept value in ns, convert ps to ns */ -+ delay = delay / 1000; -+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID || -+ mode == PHY_INTERFACE_MODE_RGMII_TXID) -+ delay = 1; -+ -+ if (delay > QCA8K_MAX_DELAY) { -+ dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); -+ delay = 3; -+ } -+ -+ priv->rgmii_tx_delay[cpu_port_index] = delay; -+ -+ delay = 0; -+ -+ if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay)) -+ /* Switch regs accept value in ns, convert ps to ns */ -+ delay = delay / 1000; -+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID || -+ mode == PHY_INTERFACE_MODE_RGMII_RXID) -+ delay = 2; -+ -+ if (delay > QCA8K_MAX_DELAY) { -+ dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); -+ delay = 3; -+ } -+ -+ priv->rgmii_rx_delay[cpu_port_index] = delay; -+ -+ break; -+ case PHY_INTERFACE_MODE_SGMII: - if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) - priv->sgmii_tx_clk_falling_edge = true; - - if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) - priv->sgmii_rx_clk_falling_edge = true; -+ -+ break; -+ default: -+ continue; - } - } - -@@ -1059,10 +1041,6 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -- ret = qca8k_setup_of_rgmii_delay(priv); -- if (ret) -- return ret; -- - ret = qca8k_setup_mac_pwr_sel(priv); - if (ret) - return ret; -@@ -1229,8 +1207,8 @@ qca8k_phylink_mac_config(struct dsa_swit - const struct phylink_link_state *state) - { - struct qca8k_priv *priv = ds->priv; -- u32 reg, val; -- int ret; -+ int cpu_port_index, ret; -+ u32 reg, val, delay; - - switch (port) { - case 0: /* 1st CPU port */ -@@ -1242,6 +1220,7 @@ qca8k_phylink_mac_config(struct dsa_swit - return; - - reg = QCA8K_REG_PORT0_PAD_CTRL; -+ cpu_port_index = QCA8K_CPU_PORT0; - break; - case 1: - case 2: -@@ -1260,6 +1239,7 @@ qca8k_phylink_mac_config(struct dsa_swit - return; - - reg = QCA8K_REG_PORT6_PAD_CTRL; -+ cpu_port_index = QCA8K_CPU_PORT6; - break; - default: - dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); -@@ -1274,23 +1254,40 @@ qca8k_phylink_mac_config(struct dsa_swit - - switch (state->interface) { - case PHY_INTERFACE_MODE_RGMII: -- /* RGMII mode means no delay so don't enable the delay */ -- qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); -- break; - case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_TXID: - case PHY_INTERFACE_MODE_RGMII_RXID: -- /* RGMII_ID needs internal delay. This is enabled through -- * PORT5_PAD_CTRL for all ports, rather than individual port -- * registers -+ val = QCA8K_PORT_PAD_RGMII_EN; -+ -+ /* Delay can be declared in 3 different way. -+ * Mode to rgmii and internal-delay standard binding defined -+ * rgmii-id or rgmii-tx/rx phy mode set. -+ * The parse logic set a delay different than 0 only when one -+ * of the 3 different way is used. In all other case delay is -+ * not enabled. With ID or TX/RXID delay is enabled and set -+ * to the default and recommended value. -+ */ -+ if (priv->rgmii_tx_delay[cpu_port_index]) { -+ delay = priv->rgmii_tx_delay[cpu_port_index]; -+ -+ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | -+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; -+ } -+ -+ if (priv->rgmii_rx_delay[cpu_port_index]) { -+ delay = priv->rgmii_rx_delay[cpu_port_index]; -+ -+ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; -+ } -+ -+ /* Set RGMII delay based on the selected values */ -+ qca8k_write(priv, reg, val); -+ -+ /* QCA8337 requires to set rgmii rx delay for all ports. -+ * This is enabled through PORT5_PAD_CTRL for all ports, -+ * rather than individual port registers. - */ -- qca8k_write(priv, reg, -- QCA8K_PORT_PAD_RGMII_EN | -- QCA8K_PORT_PAD_RGMII_TX_DELAY(priv->rgmii_tx_delay) | -- QCA8K_PORT_PAD_RGMII_RX_DELAY(priv->rgmii_rx_delay) | -- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | -- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); -- /* QCA8337 requires to set rgmii rx delay */ - if (priv->switch_id == QCA8K_ID_QCA8337) - qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, - QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -13,6 +13,7 @@ - #include - - #define QCA8K_NUM_PORTS 7 -+#define QCA8K_NUM_CPU_PORTS 2 - #define QCA8K_MAX_MTU 9000 - - #define PHY_ID_QCA8327 0x004dd034 -@@ -255,13 +256,18 @@ struct qca8k_match_data { - u8 id; - }; - -+enum { -+ QCA8K_CPU_PORT0, -+ QCA8K_CPU_PORT6, -+}; -+ - struct qca8k_priv { - u8 switch_id; - u8 switch_revision; -- u8 rgmii_tx_delay; -- u8 rgmii_rx_delay; - bool sgmii_rx_clk_falling_edge; - bool sgmii_tx_clk_falling_edge; -+ u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ -+ u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ - bool legacy_phy_port_mapping; - struct regmap *regmap; - struct mii_bus *bus; diff --git a/target/linux/generic/backport-5.15/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch b/target/linux/generic/backport-5.15/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch deleted file mode 100644 index 8abd264e794fbf..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-07-dt-bindings-net-dsa-qca8k-Document-qca-sgmii-enable-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 13ad5ccc093ff448b99ac7e138e91e78796adb48 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:12 +0200 -Subject: dt-bindings: net: dsa: qca8k: Document qca,sgmii-enable-pll - -Document qca,sgmii-enable-pll binding used in the CPU nodes to -enable SGMII PLL on MAC config. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - Documentation/devicetree/bindings/net/dsa/qca8k.txt | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt -+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt -@@ -45,6 +45,16 @@ A CPU port node has the following option - Mostly used in qca8327 with CPU port 0 set to - sgmii. - - qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge. -+- qca,sgmii-enable-pll : For SGMII CPU port, explicitly enable PLL, TX and RX -+ chain along with Signal Detection. -+ This should NOT be enabled for qca8327. If enabled with -+ qca8327 the sgmii port won't correctly init and an err -+ is printed. -+ This can be required for qca8337 switch with revision 2. -+ A warning is displayed when used with revision greater -+ 2. -+ With CPU port set to sgmii and qca8337 it is advised -+ to set this unless a communication problem is observed. - - For QCA8K the 'fixed-link' sub-node supports only the following properties: - diff --git a/target/linux/generic/backport-5.15/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch b/target/linux/generic/backport-5.15/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch deleted file mode 100644 index 2b5a84a1b0e854..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-08-net-dsa-qca8k-add-explicit-SGMII-PLL-enable.patch +++ /dev/null @@ -1,65 +0,0 @@ -From bbc4799e8bb6c397e3b3fec13de68e179f5db9ff Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:13 +0200 -Subject: net: dsa: qca8k: add explicit SGMII PLL enable - -Support enabling PLL on the SGMII CPU port. Some device require this -special configuration or no traffic is transmitted and the switch -doesn't work at all. A dedicated binding is added to the CPU node -port to apply the correct reg on mac config. -Fail to correctly configure sgmii with qca8327 switch and warn if pll is -used on qca8337 with a revision greater than 1. - -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 19 +++++++++++++++++-- - drivers/net/dsa/qca8k.h | 1 + - 2 files changed, 18 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1002,6 +1002,18 @@ qca8k_parse_port_config(struct qca8k_pri - if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) - priv->sgmii_rx_clk_falling_edge = true; - -+ if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) { -+ priv->sgmii_enable_pll = true; -+ -+ if (priv->switch_id == QCA8K_ID_QCA8327) { -+ dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling"); -+ priv->sgmii_enable_pll = false; -+ } -+ -+ if (priv->switch_revision < 2) -+ dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more."); -+ } -+ - break; - default: - continue; -@@ -1312,8 +1324,11 @@ qca8k_phylink_mac_config(struct dsa_swit - if (ret) - return; - -- val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | -- QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD; -+ val |= QCA8K_SGMII_EN_SD; -+ -+ if (priv->sgmii_enable_pll) -+ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | -+ QCA8K_SGMII_EN_TX; - - if (dsa_is_cpu_port(ds, port)) { - /* CPU port, we're talking to the CPU MAC, be a PHY */ ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -266,6 +266,7 @@ struct qca8k_priv { - u8 switch_revision; - bool sgmii_rx_clk_falling_edge; - bool sgmii_tx_clk_falling_edge; -+ bool sgmii_enable_pll; - u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ - u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ - bool legacy_phy_port_mapping; diff --git a/target/linux/generic/backport-5.15/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch b/target/linux/generic/backport-5.15/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch deleted file mode 100644 index 38dc954e8cb527..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-09-dt-bindings-net-dsa-qca8k-Document-qca-led-open-drai.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 924087c5c3d41553700b0eb83ca2a53b91643dca Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:14 +0200 -Subject: dt-bindings: net: dsa: qca8k: Document qca,led-open-drain binding - -Document new binding qca,ignore-power-on-sel used to ignore -power on strapping and use sw regs instead. -Document qca,led-open.drain to set led to open drain mode, the -qca,ignore-power-on-sel is mandatory with this enabled or an error will -be reported. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - Documentation/devicetree/bindings/net/dsa/qca8k.txt | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt -+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt -@@ -13,6 +13,17 @@ Required properties: - Optional properties: - - - reset-gpios: GPIO to be used to reset the whole device -+- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open -+ drain or eeprom presence. This is needed for broken -+ devices that have wrong configuration or when the oem -+ decided to not use pin strapping and fallback to sw -+ regs. -+- qca,led-open-drain: Set leds to open-drain mode. This requires the -+ qca,ignore-power-on-sel to be set or the driver will fail -+ to probe. This is needed if the oem doesn't use pin -+ strapping to set this mode and prefers to set it using sw -+ regs. The pin strapping related to led open drain mode is -+ the pin B68 for QCA832x and B49 for QCA833x - - Subnodes: - diff --git a/target/linux/generic/backport-5.15/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch b/target/linux/generic/backport-5.15/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch deleted file mode 100644 index aa5d92a4fdeca2..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-10-net-dsa-qca8k-add-support-for-pws-config-reg.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 362bb238d8bf1470424214a8a5968d9c6cce68fa Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:15 +0200 -Subject: net: dsa: qca8k: add support for pws config reg - -Some qca8327 switch require to force the ignore of power on sel -strapping. Some switch require to set the led open drain mode in regs -instead of using strapping. While most of the device implements this -using the correct way using pin strapping, there are still some broken -device that require to be set using sw regs. -Introduce a new binding and support these special configuration. -As led open drain require to ignore pin strapping to work, the probe -fails with EINVAL error with incorrect configuration. - -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 39 +++++++++++++++++++++++++++++++++++++++ - drivers/net/dsa/qca8k.h | 6 ++++++ - 2 files changed, 45 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -932,6 +932,41 @@ static int qca8k_find_cpu_port(struct ds - } - - static int -+qca8k_setup_of_pws_reg(struct qca8k_priv *priv) -+{ -+ struct device_node *node = priv->dev->of_node; -+ u32 val = 0; -+ int ret; -+ -+ /* QCA8327 require to set to the correct mode. -+ * His bigger brother QCA8328 have the 172 pin layout. -+ * Should be applied by default but we set this just to make sure. -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8327) { -+ ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, -+ QCA8327_PWS_PACKAGE148_EN); -+ if (ret) -+ return ret; -+ } -+ -+ if (of_property_read_bool(node, "qca,ignore-power-on-sel")) -+ val |= QCA8K_PWS_POWER_ON_SEL; -+ -+ if (of_property_read_bool(node, "qca,led-open-drain")) { -+ if (!(val & QCA8K_PWS_POWER_ON_SEL)) { -+ dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set."); -+ return -EINVAL; -+ } -+ -+ val |= QCA8K_PWS_LED_OPEN_EN_CSR; -+ } -+ -+ return qca8k_rmw(priv, QCA8K_REG_PWS, -+ QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, -+ val); -+} -+ -+static int - qca8k_parse_port_config(struct qca8k_priv *priv) - { - int port, cpu_port_index = 0, ret; -@@ -1053,6 +1088,10 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -+ ret = qca8k_setup_of_pws_reg(priv); -+ if (ret) -+ return ret; -+ - ret = qca8k_setup_mac_pwr_sel(priv); - if (ret) - return ret; ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -46,6 +46,12 @@ - #define QCA8K_MAX_DELAY 3 - #define QCA8K_PORT_PAD_SGMII_EN BIT(7) - #define QCA8K_REG_PWS 0x010 -+#define QCA8K_PWS_POWER_ON_SEL BIT(31) -+/* This reg is only valid for QCA832x and toggle the package -+ * type from 176 pin (by default) to 148 pin used on QCA8327 -+ */ -+#define QCA8327_PWS_PACKAGE148_EN BIT(30) -+#define QCA8K_PWS_LED_OPEN_EN_CSR BIT(24) - #define QCA8K_PWS_SERDES_AEN_DIS BIT(7) - #define QCA8K_REG_MODULE_EN 0x030 - #define QCA8K_MODULE_EN_MIB BIT(0) diff --git a/target/linux/generic/backport-5.15/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch b/target/linux/generic/backport-5.15/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch deleted file mode 100644 index 1bfb00c5b2c656..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-11-dt-bindings-net-dsa-qca8k-document-support-for-qca83.patch +++ /dev/null @@ -1,32 +0,0 @@ -From ed7988d77fbfb79366b68f9e7fa60a6080da23d4 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:16 +0200 -Subject: dt-bindings: net: dsa: qca8k: document support for qca8328 - -QCA8328 is the bigger brother of qca8327. Document the new compatible -binding and add some information to understand the various switch -compatible. - -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - Documentation/devicetree/bindings/net/dsa/qca8k.txt | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - ---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt -+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt -@@ -3,9 +3,10 @@ - Required properties: - - - compatible: should be one of: -- "qca,qca8327" -- "qca,qca8334" -- "qca,qca8337" -+ "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package -+ "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package -+ "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package -+ "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package - - - #size-cells: must be 0 - - #address-cells: must be 1 diff --git a/target/linux/generic/backport-5.15/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch b/target/linux/generic/backport-5.15/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch deleted file mode 100644 index b300621e63e893..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-12-net-dsa-qca8k-add-support-for-QCA8328.patch +++ /dev/null @@ -1,78 +0,0 @@ -From f477d1c8bdbef4f400718238e350f16f521d2a3e Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:17 +0200 -Subject: net: dsa: qca8k: add support for QCA8328 - -QCA8328 switch is the bigger brother of the qca8327. Same regs different -chip. Change the function to set the correct pin layout and introduce a -new match_data to differentiate the 2 switch as they have the same ID -and their internal PHY have the same ID. - -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 19 ++++++++++++++++--- - drivers/net/dsa/qca8k.h | 1 + - 2 files changed, 17 insertions(+), 3 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -935,6 +935,7 @@ static int - qca8k_setup_of_pws_reg(struct qca8k_priv *priv) - { - struct device_node *node = priv->dev->of_node; -+ const struct qca8k_match_data *data; - u32 val = 0; - int ret; - -@@ -943,8 +944,14 @@ qca8k_setup_of_pws_reg(struct qca8k_priv - * Should be applied by default but we set this just to make sure. - */ - if (priv->switch_id == QCA8K_ID_QCA8327) { -+ data = of_device_get_match_data(priv->dev); -+ -+ /* Set the correct package of 148 pin for QCA8327 */ -+ if (data->reduced_package) -+ val |= QCA8327_PWS_PACKAGE148_EN; -+ - ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, -- QCA8327_PWS_PACKAGE148_EN); -+ val); - if (ret) - return ret; - } -@@ -2124,7 +2131,12 @@ static int qca8k_resume(struct device *d - static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, - qca8k_suspend, qca8k_resume); - --static const struct qca8k_match_data qca832x = { -+static const struct qca8k_match_data qca8327 = { -+ .id = QCA8K_ID_QCA8327, -+ .reduced_package = true, -+}; -+ -+static const struct qca8k_match_data qca8328 = { - .id = QCA8K_ID_QCA8327, - }; - -@@ -2133,7 +2145,8 @@ static const struct qca8k_match_data qca - }; - - static const struct of_device_id qca8k_of_match[] = { -- { .compatible = "qca,qca8327", .data = &qca832x }, -+ { .compatible = "qca,qca8327", .data = &qca8327 }, -+ { .compatible = "qca,qca8328", .data = &qca8328 }, - { .compatible = "qca,qca8334", .data = &qca833x }, - { .compatible = "qca,qca8337", .data = &qca833x }, - { /* sentinel */ }, ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -260,6 +260,7 @@ struct ar8xxx_port_status { - - struct qca8k_match_data { - u8 id; -+ bool reduced_package; - }; - - enum { diff --git a/target/linux/generic/backport-5.15/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch b/target/linux/generic/backport-5.15/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch deleted file mode 100644 index 27f94dca0270e6..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-13-net-dsa-qca8k-set-internal-delay-also-for-sgmii.patch +++ /dev/null @@ -1,159 +0,0 @@ -From cef08115846e581f80ff99abf7bf218da1840616 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:18 +0200 -Subject: net: dsa: qca8k: set internal delay also for sgmii - -QCA original code report port instability and sa that SGMII also require -to set internal delay. Generalize the rgmii delay function and apply the -advised value if they are not defined in DT. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 88 +++++++++++++++++++++++++++++++++---------------- - drivers/net/dsa/qca8k.h | 2 ++ - 2 files changed, 62 insertions(+), 28 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1004,6 +1004,7 @@ qca8k_parse_port_config(struct qca8k_pri - case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_TXID: - case PHY_INTERFACE_MODE_RGMII_RXID: -+ case PHY_INTERFACE_MODE_SGMII: - delay = 0; - - if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay)) -@@ -1036,8 +1037,13 @@ qca8k_parse_port_config(struct qca8k_pri - - priv->rgmii_rx_delay[cpu_port_index] = delay; - -- break; -- case PHY_INTERFACE_MODE_SGMII: -+ /* Skip sgmii parsing for rgmii* mode */ -+ if (mode == PHY_INTERFACE_MODE_RGMII || -+ mode == PHY_INTERFACE_MODE_RGMII_ID || -+ mode == PHY_INTERFACE_MODE_RGMII_TXID || -+ mode == PHY_INTERFACE_MODE_RGMII_RXID) -+ break; -+ - if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) - priv->sgmii_tx_clk_falling_edge = true; - -@@ -1261,12 +1267,53 @@ qca8k_setup(struct dsa_switch *ds) - } - - static void -+qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index, -+ u32 reg) -+{ -+ u32 delay, val = 0; -+ int ret; -+ -+ /* Delay can be declared in 3 different way. -+ * Mode to rgmii and internal-delay standard binding defined -+ * rgmii-id or rgmii-tx/rx phy mode set. -+ * The parse logic set a delay different than 0 only when one -+ * of the 3 different way is used. In all other case delay is -+ * not enabled. With ID or TX/RXID delay is enabled and set -+ * to the default and recommended value. -+ */ -+ if (priv->rgmii_tx_delay[cpu_port_index]) { -+ delay = priv->rgmii_tx_delay[cpu_port_index]; -+ -+ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | -+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; -+ } -+ -+ if (priv->rgmii_rx_delay[cpu_port_index]) { -+ delay = priv->rgmii_rx_delay[cpu_port_index]; -+ -+ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; -+ } -+ -+ /* Set RGMII delay based on the selected values */ -+ ret = qca8k_rmw(priv, reg, -+ QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | -+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, -+ val); -+ if (ret) -+ dev_err(priv->dev, "Failed to set internal delay for CPU port%d", -+ cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); -+} -+ -+static void - qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - const struct phylink_link_state *state) - { - struct qca8k_priv *priv = ds->priv; - int cpu_port_index, ret; -- u32 reg, val, delay; -+ u32 reg, val; - - switch (port) { - case 0: /* 1st CPU port */ -@@ -1315,32 +1362,10 @@ qca8k_phylink_mac_config(struct dsa_swit - case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_TXID: - case PHY_INTERFACE_MODE_RGMII_RXID: -- val = QCA8K_PORT_PAD_RGMII_EN; -- -- /* Delay can be declared in 3 different way. -- * Mode to rgmii and internal-delay standard binding defined -- * rgmii-id or rgmii-tx/rx phy mode set. -- * The parse logic set a delay different than 0 only when one -- * of the 3 different way is used. In all other case delay is -- * not enabled. With ID or TX/RXID delay is enabled and set -- * to the default and recommended value. -- */ -- if (priv->rgmii_tx_delay[cpu_port_index]) { -- delay = priv->rgmii_tx_delay[cpu_port_index]; -- -- val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | -- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; -- } -- -- if (priv->rgmii_rx_delay[cpu_port_index]) { -- delay = priv->rgmii_rx_delay[cpu_port_index]; -- -- val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | -- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; -- } -+ qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); - -- /* Set RGMII delay based on the selected values */ -- qca8k_write(priv, reg, val); -+ /* Configure rgmii delay */ -+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); - - /* QCA8337 requires to set rgmii rx delay for all ports. - * This is enabled through PORT5_PAD_CTRL for all ports, -@@ -1411,6 +1436,13 @@ qca8k_phylink_mac_config(struct dsa_swit - QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | - QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, - val); -+ -+ /* From original code is reported port instability as SGMII also -+ * require delay set. Apply advised values here or take them from DT. -+ */ -+ if (state->interface == PHY_INTERFACE_MODE_SGMII) -+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -+ - break; - default: - dev_err(ds->dev, "xMII mode %s not supported for port %d\n", ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -39,7 +39,9 @@ - #define QCA8K_REG_PORT5_PAD_CTRL 0x008 - #define QCA8K_REG_PORT6_PAD_CTRL 0x00c - #define QCA8K_PORT_PAD_RGMII_EN BIT(26) -+#define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22) - #define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) ((x) << 22) -+#define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20) - #define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) ((x) << 20) - #define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25) - #define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24) diff --git a/target/linux/generic/backport-5.15/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch b/target/linux/generic/backport-5.15/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch deleted file mode 100644 index b991798c87fe06..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-14-net-dsa-qca8k-move-port-config-to-dedicated-struct.patch +++ /dev/null @@ -1,124 +0,0 @@ -From fd0bb28c547f7c8affb1691128cece38f5b626a1 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:19 +0200 -Subject: net: dsa: qca8k: move port config to dedicated struct - -Move ports related config to dedicated struct to keep things organized. - -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 26 +++++++++++++------------- - drivers/net/dsa/qca8k.h | 10 +++++++--- - 2 files changed, 20 insertions(+), 16 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1019,7 +1019,7 @@ qca8k_parse_port_config(struct qca8k_pri - delay = 3; - } - -- priv->rgmii_tx_delay[cpu_port_index] = delay; -+ priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay; - - delay = 0; - -@@ -1035,7 +1035,7 @@ qca8k_parse_port_config(struct qca8k_pri - delay = 3; - } - -- priv->rgmii_rx_delay[cpu_port_index] = delay; -+ priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay; - - /* Skip sgmii parsing for rgmii* mode */ - if (mode == PHY_INTERFACE_MODE_RGMII || -@@ -1045,17 +1045,17 @@ qca8k_parse_port_config(struct qca8k_pri - break; - - if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) -- priv->sgmii_tx_clk_falling_edge = true; -+ priv->ports_config.sgmii_tx_clk_falling_edge = true; - - if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) -- priv->sgmii_rx_clk_falling_edge = true; -+ priv->ports_config.sgmii_rx_clk_falling_edge = true; - - if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) { -- priv->sgmii_enable_pll = true; -+ priv->ports_config.sgmii_enable_pll = true; - - if (priv->switch_id == QCA8K_ID_QCA8327) { - dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling"); -- priv->sgmii_enable_pll = false; -+ priv->ports_config.sgmii_enable_pll = false; - } - - if (priv->switch_revision < 2) -@@ -1281,15 +1281,15 @@ qca8k_mac_config_setup_internal_delay(st - * not enabled. With ID or TX/RXID delay is enabled and set - * to the default and recommended value. - */ -- if (priv->rgmii_tx_delay[cpu_port_index]) { -- delay = priv->rgmii_tx_delay[cpu_port_index]; -+ if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) { -+ delay = priv->ports_config.rgmii_tx_delay[cpu_port_index]; - - val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | - QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; - } - -- if (priv->rgmii_rx_delay[cpu_port_index]) { -- delay = priv->rgmii_rx_delay[cpu_port_index]; -+ if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) { -+ delay = priv->ports_config.rgmii_rx_delay[cpu_port_index]; - - val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | - QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; -@@ -1397,7 +1397,7 @@ qca8k_phylink_mac_config(struct dsa_swit - - val |= QCA8K_SGMII_EN_SD; - -- if (priv->sgmii_enable_pll) -+ if (priv->ports_config.sgmii_enable_pll) - val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | - QCA8K_SGMII_EN_TX; - -@@ -1425,10 +1425,10 @@ qca8k_phylink_mac_config(struct dsa_swit - val = 0; - - /* SGMII Clock phase configuration */ -- if (priv->sgmii_rx_clk_falling_edge) -+ if (priv->ports_config.sgmii_rx_clk_falling_edge) - val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; - -- if (priv->sgmii_tx_clk_falling_edge) -+ if (priv->ports_config.sgmii_tx_clk_falling_edge) - val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; - - if (val) ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -270,15 +270,19 @@ enum { - QCA8K_CPU_PORT6, - }; - --struct qca8k_priv { -- u8 switch_id; -- u8 switch_revision; -+struct qca8k_ports_config { - bool sgmii_rx_clk_falling_edge; - bool sgmii_tx_clk_falling_edge; - bool sgmii_enable_pll; - u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ - u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ -+}; -+ -+struct qca8k_priv { -+ u8 switch_id; -+ u8 switch_revision; - bool legacy_phy_port_mapping; -+ struct qca8k_ports_config ports_config; - struct regmap *regmap; - struct mii_bus *bus; - struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS]; diff --git a/target/linux/generic/backport-5.15/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch b/target/linux/generic/backport-5.15/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch deleted file mode 100644 index f7cb5141763381..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-15-dt-bindings-net-ipq8064-mdio-fix-warning-with-new-qc.patch +++ /dev/null @@ -1,26 +0,0 @@ -From e52073a8e3086046a098b8a7cbeb282ff0cdb424 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Thu, 14 Oct 2021 00:39:20 +0200 -Subject: dt-bindings: net: ipq8064-mdio: fix warning with new qca8k switch - -Fix warning now that we have qca8k switch Documentation using yaml. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml -+++ b/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml -@@ -51,6 +51,9 @@ examples: - switch@10 { - compatible = "qca,qca8337"; - reg = <0x10>; -- /* ... */ -+ -+ ports { -+ /* ... */ -+ }; - }; - }; diff --git a/target/linux/generic/backport-5.15/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch b/target/linux/generic/backport-5.15/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch deleted file mode 100644 index b9bce97dd3dace..00000000000000 --- a/target/linux/generic/backport-5.15/747-v5.16-16-dt-bindings-net-dsa-qca8k-convert-to-YAML-schema.patch +++ /dev/null @@ -1,631 +0,0 @@ -From d291fbb8245d5ba04979fed85575860a5cea7196 Mon Sep 17 00:00:00 2001 -From: Matthew Hagan -Date: Thu, 14 Oct 2021 00:39:21 +0200 -Subject: dt-bindings: net: dsa: qca8k: convert to YAML schema - -Convert the qca8k bindings to YAML format. - -Signed-off-by: Matthew Hagan -Co-developed-by: Ansuel Smith -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - .../devicetree/bindings/net/dsa/qca8k.txt | 245 -------------- - .../devicetree/bindings/net/dsa/qca8k.yaml | 362 +++++++++++++++++++++ - 2 files changed, 362 insertions(+), 245 deletions(-) - delete mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.txt - create mode 100644 Documentation/devicetree/bindings/net/dsa/qca8k.yaml - ---- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt -+++ /dev/null -@@ -1,245 +0,0 @@ --* Qualcomm Atheros QCA8xxx switch family -- --Required properties: -- --- compatible: should be one of: -- "qca,qca8328": referenced as AR8328(N)-AK1(A/B) QFN 176 pin package -- "qca,qca8327": referenced as AR8327(N)-AL1A DR-QFN 148 pin package -- "qca,qca8334": referenced as QCA8334-AL3C QFN 88 pin package -- "qca,qca8337": referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package -- --- #size-cells: must be 0 --- #address-cells: must be 1 -- --Optional properties: -- --- reset-gpios: GPIO to be used to reset the whole device --- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open -- drain or eeprom presence. This is needed for broken -- devices that have wrong configuration or when the oem -- decided to not use pin strapping and fallback to sw -- regs. --- qca,led-open-drain: Set leds to open-drain mode. This requires the -- qca,ignore-power-on-sel to be set or the driver will fail -- to probe. This is needed if the oem doesn't use pin -- strapping to set this mode and prefers to set it using sw -- regs. The pin strapping related to led open drain mode is -- the pin B68 for QCA832x and B49 for QCA833x -- --Subnodes: -- --The integrated switch subnode should be specified according to the binding --described in dsa/dsa.txt. If the QCA8K switch is connect to a SoC's external --mdio-bus each subnode describing a port needs to have a valid phandle --referencing the internal PHY it is connected to. This is because there's no --N:N mapping of port and PHY id. --To declare the internal mdio-bus configuration, declare a mdio node in the --switch node and declare the phandle for the port referencing the internal --PHY is connected to. In this config a internal mdio-bus is registered and --the mdio MASTER is used as communication. -- --Don't use mixed external and internal mdio-bus configurations, as this is --not supported by the hardware. -- --This switch support 2 CPU port. Normally and advised configuration is with --CPU port set to port 0. It is also possible to set the CPU port to port 6 --if the device requires it. The driver will configure the switch to the defined --port. With both CPU port declared the first CPU port is selected as primary --and the secondary CPU ignored. -- --A CPU port node has the following optional node: -- --- fixed-link : Fixed-link subnode describing a link to a non-MDIO -- managed entity. See -- Documentation/devicetree/bindings/net/fixed-link.txt -- for details. --- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge. -- Mostly used in qca8327 with CPU port 0 set to -- sgmii. --- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge. --- qca,sgmii-enable-pll : For SGMII CPU port, explicitly enable PLL, TX and RX -- chain along with Signal Detection. -- This should NOT be enabled for qca8327. If enabled with -- qca8327 the sgmii port won't correctly init and an err -- is printed. -- This can be required for qca8337 switch with revision 2. -- A warning is displayed when used with revision greater -- 2. -- With CPU port set to sgmii and qca8337 it is advised -- to set this unless a communication problem is observed. -- --For QCA8K the 'fixed-link' sub-node supports only the following properties: -- --- 'speed' (integer, mandatory), to indicate the link speed. Accepted -- values are 10, 100 and 1000 --- 'full-duplex' (boolean, optional), to indicate that full duplex is -- used. When absent, half duplex is assumed. -- --Examples: -- --for the external mdio-bus configuration: -- -- &mdio0 { -- phy_port1: phy@0 { -- reg = <0>; -- }; -- -- phy_port2: phy@1 { -- reg = <1>; -- }; -- -- phy_port3: phy@2 { -- reg = <2>; -- }; -- -- phy_port4: phy@3 { -- reg = <3>; -- }; -- -- phy_port5: phy@4 { -- reg = <4>; -- }; -- -- switch@10 { -- compatible = "qca,qca8337"; -- #address-cells = <1>; -- #size-cells = <0>; -- -- reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>; -- reg = <0x10>; -- -- ports { -- #address-cells = <1>; -- #size-cells = <0>; -- port@0 { -- reg = <0>; -- label = "cpu"; -- ethernet = <&gmac1>; -- phy-mode = "rgmii"; -- fixed-link { -- speed = 1000; -- full-duplex; -- }; -- }; -- -- port@1 { -- reg = <1>; -- label = "lan1"; -- phy-handle = <&phy_port1>; -- }; -- -- port@2 { -- reg = <2>; -- label = "lan2"; -- phy-handle = <&phy_port2>; -- }; -- -- port@3 { -- reg = <3>; -- label = "lan3"; -- phy-handle = <&phy_port3>; -- }; -- -- port@4 { -- reg = <4>; -- label = "lan4"; -- phy-handle = <&phy_port4>; -- }; -- -- port@5 { -- reg = <5>; -- label = "wan"; -- phy-handle = <&phy_port5>; -- }; -- }; -- }; -- }; -- --for the internal master mdio-bus configuration: -- -- &mdio0 { -- switch@10 { -- compatible = "qca,qca8337"; -- #address-cells = <1>; -- #size-cells = <0>; -- -- reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>; -- reg = <0x10>; -- -- ports { -- #address-cells = <1>; -- #size-cells = <0>; -- -- port@0 { -- reg = <0>; -- label = "cpu"; -- ethernet = <&gmac1>; -- phy-mode = "rgmii"; -- fixed-link { -- speed = 1000; -- full-duplex; -- }; -- }; -- -- port@1 { -- reg = <1>; -- label = "lan1"; -- phy-mode = "internal"; -- phy-handle = <&phy_port1>; -- }; -- -- port@2 { -- reg = <2>; -- label = "lan2"; -- phy-mode = "internal"; -- phy-handle = <&phy_port2>; -- }; -- -- port@3 { -- reg = <3>; -- label = "lan3"; -- phy-mode = "internal"; -- phy-handle = <&phy_port3>; -- }; -- -- port@4 { -- reg = <4>; -- label = "lan4"; -- phy-mode = "internal"; -- phy-handle = <&phy_port4>; -- }; -- -- port@5 { -- reg = <5>; -- label = "wan"; -- phy-mode = "internal"; -- phy-handle = <&phy_port5>; -- }; -- }; -- -- mdio { -- #address-cells = <1>; -- #size-cells = <0>; -- -- phy_port1: phy@0 { -- reg = <0>; -- }; -- -- phy_port2: phy@1 { -- reg = <1>; -- }; -- -- phy_port3: phy@2 { -- reg = <2>; -- }; -- -- phy_port4: phy@3 { -- reg = <3>; -- }; -- -- phy_port5: phy@4 { -- reg = <4>; -- }; -- }; -- }; -- }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.yaml -@@ -0,0 +1,362 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/net/dsa/qca8k.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Qualcomm Atheros QCA83xx switch family -+ -+maintainers: -+ - John Crispin -+ -+description: -+ If the QCA8K switch is connect to an SoC's external mdio-bus, each subnode -+ describing a port needs to have a valid phandle referencing the internal PHY -+ it is connected to. This is because there is no N:N mapping of port and PHY -+ ID. To declare the internal mdio-bus configuration, declare an MDIO node in -+ the switch node and declare the phandle for the port, referencing the internal -+ PHY it is connected to. In this config, an internal mdio-bus is registered and -+ the MDIO master is used for communication. Mixed external and internal -+ mdio-bus configurations are not supported by the hardware. -+ -+properties: -+ compatible: -+ oneOf: -+ - enum: -+ - qca,qca8327 -+ - qca,qca8328 -+ - qca,qca8334 -+ - qca,qca8337 -+ description: | -+ qca,qca8328: referenced as AR8328(N)-AK1(A/B) QFN 176 pin package -+ qca,qca8327: referenced as AR8327(N)-AL1A DR-QFN 148 pin package -+ qca,qca8334: referenced as QCA8334-AL3C QFN 88 pin package -+ qca,qca8337: referenced as QCA8337N-AL3(B/C) DR-QFN 148 pin package -+ -+ reg: -+ maxItems: 1 -+ -+ reset-gpios: -+ description: -+ GPIO to be used to reset the whole device -+ maxItems: 1 -+ -+ qca,ignore-power-on-sel: -+ $ref: /schemas/types.yaml#/definitions/flag -+ description: -+ Ignore power-on pin strapping to configure LED open-drain or EEPROM -+ presence. This is needed for devices with incorrect configuration or when -+ the OEM has decided not to use pin strapping and falls back to SW regs. -+ -+ qca,led-open-drain: -+ $ref: /schemas/types.yaml#/definitions/flag -+ description: -+ Set LEDs to open-drain mode. This requires the qca,ignore-power-on-sel to -+ be set, otherwise the driver will fail at probe. This is required if the -+ OEM does not use pin strapping to set this mode and prefers to set it -+ using SW regs. The pin strappings related to LED open-drain mode are -+ B68 on the QCA832x and B49 on the QCA833x. -+ -+ mdio: -+ type: object -+ description: Qca8k switch have an internal mdio to access switch port. -+ If this is not present, the legacy mapping is used and the -+ internal mdio access is used. -+ With the legacy mapping the reg corresponding to the internal -+ mdio is the switch reg with an offset of -1. -+ -+ properties: -+ '#address-cells': -+ const: 1 -+ '#size-cells': -+ const: 0 -+ -+ patternProperties: -+ "^(ethernet-)?phy@[0-4]$": -+ type: object -+ -+ allOf: -+ - $ref: "http://devicetree.org/schemas/net/mdio.yaml#" -+ -+ properties: -+ reg: -+ maxItems: 1 -+ -+ required: -+ - reg -+ -+patternProperties: -+ "^(ethernet-)?ports$": -+ type: object -+ properties: -+ '#address-cells': -+ const: 1 -+ '#size-cells': -+ const: 0 -+ -+ patternProperties: -+ "^(ethernet-)?port@[0-6]$": -+ type: object -+ description: Ethernet switch ports -+ -+ properties: -+ reg: -+ description: Port number -+ -+ label: -+ description: -+ Describes the label associated with this port, which will become -+ the netdev name -+ $ref: /schemas/types.yaml#/definitions/string -+ -+ link: -+ description: -+ Should be a list of phandles to other switch's DSA port. This -+ port is used as the outgoing port towards the phandle ports. The -+ full routing information must be given, not just the one hop -+ routes to neighbouring switches -+ $ref: /schemas/types.yaml#/definitions/phandle-array -+ -+ ethernet: -+ description: -+ Should be a phandle to a valid Ethernet device node. This host -+ device is what the switch port is connected to -+ $ref: /schemas/types.yaml#/definitions/phandle -+ -+ phy-handle: true -+ -+ phy-mode: true -+ -+ fixed-link: true -+ -+ mac-address: true -+ -+ sfp: true -+ -+ qca,sgmii-rxclk-falling-edge: -+ $ref: /schemas/types.yaml#/definitions/flag -+ description: -+ Set the receive clock phase to falling edge. Mostly commonly used on -+ the QCA8327 with CPU port 0 set to SGMII. -+ -+ qca,sgmii-txclk-falling-edge: -+ $ref: /schemas/types.yaml#/definitions/flag -+ description: -+ Set the transmit clock phase to falling edge. -+ -+ qca,sgmii-enable-pll: -+ $ref: /schemas/types.yaml#/definitions/flag -+ description: -+ For SGMII CPU port, explicitly enable PLL, TX and RX chain along with -+ Signal Detection. On the QCA8327 this should not be enabled, otherwise -+ the SGMII port will not initialize. When used on the QCA8337, revision 3 -+ or greater, a warning will be displayed. When the CPU port is set to -+ SGMII on the QCA8337, it is advised to set this unless a communication -+ issue is observed. -+ -+ required: -+ - reg -+ -+ additionalProperties: false -+ -+oneOf: -+ - required: -+ - ports -+ - required: -+ - ethernet-ports -+ -+required: -+ - compatible -+ - reg -+ -+additionalProperties: true -+ -+examples: -+ - | -+ #include -+ -+ mdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ external_phy_port1: ethernet-phy@0 { -+ reg = <0>; -+ }; -+ -+ external_phy_port2: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ -+ external_phy_port3: ethernet-phy@2 { -+ reg = <2>; -+ }; -+ -+ external_phy_port4: ethernet-phy@3 { -+ reg = <3>; -+ }; -+ -+ external_phy_port5: ethernet-phy@4 { -+ reg = <4>; -+ }; -+ -+ switch@10 { -+ compatible = "qca,qca8337"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>; -+ reg = <0x10>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ label = "cpu"; -+ ethernet = <&gmac1>; -+ phy-mode = "rgmii"; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ label = "lan1"; -+ phy-handle = <&external_phy_port1>; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ label = "lan2"; -+ phy-handle = <&external_phy_port2>; -+ }; -+ -+ port@3 { -+ reg = <3>; -+ label = "lan3"; -+ phy-handle = <&external_phy_port3>; -+ }; -+ -+ port@4 { -+ reg = <4>; -+ label = "lan4"; -+ phy-handle = <&external_phy_port4>; -+ }; -+ -+ port@5 { -+ reg = <5>; -+ label = "wan"; -+ phy-handle = <&external_phy_port5>; -+ }; -+ }; -+ }; -+ }; -+ - | -+ #include -+ -+ mdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ switch@10 { -+ compatible = "qca,qca8337"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>; -+ reg = <0x10>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ port@0 { -+ reg = <0>; -+ label = "cpu"; -+ ethernet = <&gmac1>; -+ phy-mode = "rgmii"; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ -+ port@1 { -+ reg = <1>; -+ label = "lan1"; -+ phy-mode = "internal"; -+ phy-handle = <&internal_phy_port1>; -+ }; -+ -+ port@2 { -+ reg = <2>; -+ label = "lan2"; -+ phy-mode = "internal"; -+ phy-handle = <&internal_phy_port2>; -+ }; -+ -+ port@3 { -+ reg = <3>; -+ label = "lan3"; -+ phy-mode = "internal"; -+ phy-handle = <&internal_phy_port3>; -+ }; -+ -+ port@4 { -+ reg = <4>; -+ label = "lan4"; -+ phy-mode = "internal"; -+ phy-handle = <&internal_phy_port4>; -+ }; -+ -+ port@5 { -+ reg = <5>; -+ label = "wan"; -+ phy-mode = "internal"; -+ phy-handle = <&internal_phy_port5>; -+ }; -+ -+ port@6 { -+ reg = <0>; -+ label = "cpu"; -+ ethernet = <&gmac1>; -+ phy-mode = "sgmii"; -+ -+ qca,sgmii-rxclk-falling-edge; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ }; -+ -+ mdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ internal_phy_port1: ethernet-phy@0 { -+ reg = <0>; -+ }; -+ -+ internal_phy_port2: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ -+ internal_phy_port3: ethernet-phy@2 { -+ reg = <2>; -+ }; -+ -+ internal_phy_port4: ethernet-phy@3 { -+ reg = <3>; -+ }; -+ -+ internal_phy_port5: ethernet-phy@4 { -+ reg = <4>; -+ }; -+ }; -+ }; -+ }; diff --git a/target/linux/generic/backport-5.15/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch b/target/linux/generic/backport-5.15/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch deleted file mode 100644 index a510cfdc1831e6..00000000000000 --- a/target/linux/generic/backport-5.15/748-v5.16-net-dsa-qca8k-fix-delay-applied-to-wrong-cpu-in-parse-p.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 06dd34a628ae5b6a839b757e746de165d6789ca8 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sun, 17 Oct 2021 16:56:46 +0200 -Subject: net: dsa: qca8k: fix delay applied to wrong cpu in parse_port_config - -Fix delay settings applied to wrong cpu in parse_port_config. The delay -values is set to the wrong index as the cpu_port_index is incremented -too early. Start the cpu_port_index to -1 so the correct value is -applied to address also the case with invalid phy mode and not available -port. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -976,7 +976,7 @@ qca8k_setup_of_pws_reg(struct qca8k_priv - static int - qca8k_parse_port_config(struct qca8k_priv *priv) - { -- int port, cpu_port_index = 0, ret; -+ int port, cpu_port_index = -1, ret; - struct device_node *port_dn; - phy_interface_t mode; - struct dsa_port *dp; diff --git a/target/linux/generic/backport-5.15/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch b/target/linux/generic/backport-5.15/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch deleted file mode 100644 index 71fa3022d55814..00000000000000 --- a/target/linux/generic/backport-5.15/749-v5.16-net-dsa-qca8k-tidy-for-loop-in-setup-and-add-cpu-port-c.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 040e926f5813a5f4cc18dbff7c942d1e52f368f2 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 19 Oct 2021 02:08:50 +0200 -Subject: net: dsa: qca8k: tidy for loop in setup and add cpu port check - -Tidy and organize qca8k setup function from multiple for loop. -Change for loop in bridge leave/join to scan all port and skip cpu port. -No functional change intended. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 74 +++++++++++++++++++++++++++++-------------------- - 1 file changed, 44 insertions(+), 30 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1122,28 +1122,34 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - dev_warn(priv->dev, "mib init failed"); - -- /* Enable QCA header mode on the cpu port */ -- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port), -- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S | -- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S); -- if (ret) { -- dev_err(priv->dev, "failed enabling QCA header mode"); -- return ret; -- } -- -- /* Disable forwarding by default on all ports */ -+ /* Initial setup of all ports */ - for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ /* Disable forwarding by default on all ports */ - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), - QCA8K_PORT_LOOKUP_MEMBER, 0); - if (ret) - return ret; -- } - -- /* Disable MAC by default on all ports */ -- for (i = 1; i < QCA8K_NUM_PORTS; i++) -- qca8k_port_set_status(priv, i, 0); -+ /* Enable QCA header mode on all cpu ports */ -+ if (dsa_is_cpu_port(ds, i)) { -+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), -+ QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S | -+ QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S); -+ if (ret) { -+ dev_err(priv->dev, "failed enabling QCA header mode"); -+ return ret; -+ } -+ } -+ -+ /* Disable MAC by default on all user ports */ -+ if (dsa_is_user_port(ds, i)) -+ qca8k_port_set_status(priv, i, 0); -+ } - -- /* Forward all unknown frames to CPU port for Linux processing */ -+ /* Forward all unknown frames to CPU port for Linux processing -+ * Notice that in multi-cpu config only one port should be set -+ * for igmp, unknown, multicast and broadcast packet -+ */ - ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, - BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S | - BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S | -@@ -1152,11 +1158,13 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -- /* Setup connection between CPU port & user ports */ -+ /* Setup connection between CPU port & user ports -+ * Configure specific switch configuration for ports -+ */ - for (i = 0; i < QCA8K_NUM_PORTS; i++) { - /* CPU port gets connected to all user ports of the switch */ - if (dsa_is_cpu_port(ds, i)) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port), -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), - QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); - if (ret) - return ret; -@@ -1193,16 +1201,14 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - } -- } - -- /* The port 5 of the qca8337 have some problem in flood condition. The -- * original legacy driver had some specific buffer and priority settings -- * for the different port suggested by the QCA switch team. Add this -- * missing settings to improve switch stability under load condition. -- * This problem is limited to qca8337 and other qca8k switch are not affected. -- */ -- if (priv->switch_id == QCA8K_ID_QCA8337) { -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ /* The port 5 of the qca8337 have some problem in flood condition. The -+ * original legacy driver had some specific buffer and priority settings -+ * for the different port suggested by the QCA switch team. Add this -+ * missing settings to improve switch stability under load condition. -+ * This problem is limited to qca8337 and other qca8k switch are not affected. -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8337) { - switch (i) { - /* The 2 CPU port and port 5 requires some different - * priority than any other ports. -@@ -1238,6 +1244,12 @@ qca8k_setup(struct dsa_switch *ds) - QCA8K_PORT_HOL_CTRL1_WRED_EN, - mask); - } -+ -+ /* Set initial MTU for every port. -+ * We have only have a general MTU setting. So track -+ * every port and set the max across all port. -+ */ -+ priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN; - } - - /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ -@@ -1251,8 +1263,6 @@ qca8k_setup(struct dsa_switch *ds) - } - - /* Setup our port MTUs to match power on defaults */ -- for (i = 0; i < QCA8K_NUM_PORTS; i++) -- priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN; - ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); - if (ret) - dev_warn(priv->dev, "failed setting MTU settings"); -@@ -1728,7 +1738,9 @@ qca8k_port_bridge_join(struct dsa_switch - cpu_port = dsa_to_port(ds, port)->cpu_dp->index; - port_mask = BIT(cpu_port); - -- for (i = 1; i < QCA8K_NUM_PORTS; i++) { -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ if (dsa_is_cpu_port(ds, i)) -+ continue; - if (dsa_to_port(ds, i)->bridge_dev != br) - continue; - /* Add this port to the portvlan mask of the other ports -@@ -1758,7 +1770,9 @@ qca8k_port_bridge_leave(struct dsa_switc - - cpu_port = dsa_to_port(ds, port)->cpu_dp->index; - -- for (i = 1; i < QCA8K_NUM_PORTS; i++) { -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ if (dsa_is_cpu_port(ds, i)) -+ continue; - if (dsa_to_port(ds, i)->bridge_dev != br) - continue; - /* Remove this port to the portvlan mask of the other ports diff --git a/target/linux/generic/backport-5.15/750-v5.16-net-dsa-qca8k-make-sure-pad0-mac06-exchange-is-disabled.patch b/target/linux/generic/backport-5.15/750-v5.16-net-dsa-qca8k-make-sure-pad0-mac06-exchange-is-disabled.patch deleted file mode 100644 index 4a61703c527495..00000000000000 --- a/target/linux/generic/backport-5.15/750-v5.16-net-dsa-qca8k-make-sure-pad0-mac06-exchange-is-disabled.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 5f15d392dcb4aa250a63d6f2c5adfc26c0aedc78 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 2 Nov 2021 19:30:41 +0100 -Subject: net: dsa: qca8k: make sure PAD0 MAC06 exchange is disabled - -Some device set MAC06 exchange in the bootloader. This cause some -problem as we don't support this strange mode and we just set the port6 -as the primary CPU port. With MAC06 exchange, PAD0 reg configure port6 -instead of port0. Add an extra check and explicitly disable MAC06 exchange -to correctly configure the port PAD config. - -Signed-off-by: Ansuel Smith -Fixes: 3fcf734aa482 ("net: dsa: qca8k: add support for cpu port 6") -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 8 ++++++++ - drivers/net/dsa/qca8k.h | 1 + - 2 files changed, 9 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1109,6 +1109,14 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -+ /* Make sure MAC06 is disabled */ -+ ret = qca8k_reg_clear(priv, QCA8K_REG_PORT0_PAD_CTRL, -+ QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); -+ if (ret) { -+ dev_err(priv->dev, "failed disabling MAC06 exchange"); -+ return ret; -+ } -+ - /* Enable CPU Port */ - ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0, - QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -34,6 +34,7 @@ - #define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8) - #define QCA8K_MASK_CTRL_DEVICE_ID(x) ((x) >> 8) - #define QCA8K_REG_PORT0_PAD_CTRL 0x004 -+#define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31) - #define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19) - #define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18) - #define QCA8K_REG_PORT5_PAD_CTRL 0x008 diff --git a/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch b/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch deleted file mode 100644 index 25ac8db9124494..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 5ea0e1312bcfebc06b5f91d1bb82b823d6395125 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 19 Jul 2023 12:29:49 +0200 -Subject: [PATCH 095/250] net: ethernet: mtk_ppe: add MTK_FOE_ENTRY_V{1,2}_SIZE - macros - -Introduce MTK_FOE_ENTRY_V{1,2}_SIZE macros in order to make more -explicit foe_entry size for different chipset revisions. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +++++----- - drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++ - 2 files changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4713,7 +4713,7 @@ static const struct mtk_soc_data mt7621_ - .required_pctl = false, - .offload_version = 1, - .hash_offset = 2, -- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, -+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4734,7 +4734,7 @@ static const struct mtk_soc_data mt7622_ - .offload_version = 2, - .hash_offset = 2, - .has_accounting = true, -- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, -+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4753,7 +4753,7 @@ static const struct mtk_soc_data mt7623_ - .required_pctl = true, - .offload_version = 1, - .hash_offset = 2, -- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, -+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4791,8 +4791,8 @@ static const struct mtk_soc_data mt7981_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 4, -- .foe_entry_size = sizeof(struct mtk_foe_entry), - .has_accounting = true, -+ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), -@@ -4812,8 +4812,8 @@ static const struct mtk_soc_data mt7986_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 4, -- .foe_entry_size = sizeof(struct mtk_foe_entry), - .has_accounting = true, -+ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -216,6 +216,9 @@ struct mtk_foe_ipv6_6rd { - struct mtk_foe_mac_info l2; - }; - -+#define MTK_FOE_ENTRY_V1_SIZE 80 -+#define MTK_FOE_ENTRY_V2_SIZE 96 -+ - struct mtk_foe_entry { - u32 ib1; - diff --git a/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch b/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch deleted file mode 100644 index 97209958afcdc3..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 8cfa2576d79f9379d167a8994f0fca935c07a8bc Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Sat, 22 Jul 2023 21:32:49 +0100 -Subject: [PATCH 096/250] net: ethernet: mtk_eth_soc: remove incorrect PLL - configuration - -MT7623 GMAC0 attempts to configure the system clocking according to the -required speed in the .mac_config callback for non-SGMII, non-baseX and -non-TRGMII modes. - -state->speed setting has never been reliable in the .mac_config -callback - there are cases where this is not the link speed, -particularly via ethtool paths, so this has always been unreliable (as -detailed in phylink's documentation.) - -There is the additional issue that mtk_gmac0_rgmii_adjust() will only -be called if state->interface changes, which means it only configures -the system clocking on the very first .mac_config call, which will be -made when the network device is first brought up before any link is -established. - -Essentially, this code is incredibly buggy, and probably never worked. - -Moreover, checking the in-kernel DT files, it seems no platform makes -use of this code path. - -Therefore, let's remove it, and disable interface modes for port 0 that -are not SGMII, 1000base-X, 2500base-X or TRGMII on the MT7623. - -Reviewed-by: Daniel Golle -Tested-by: Daniel Golle -Tested-by: Frank Wunderlich -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 54 ++++++--------------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - 2 files changed, 17 insertions(+), 38 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -309,7 +309,7 @@ static int mt7621_gmac0_rgmii_adjust(str - } - - static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth, -- phy_interface_t interface, int speed) -+ phy_interface_t interface) - { - u32 val; - int ret; -@@ -323,26 +323,7 @@ static void mtk_gmac0_rgmii_adjust(struc - return; - } - -- val = (speed == SPEED_1000) ? -- INTF_MODE_RGMII_1000 : INTF_MODE_RGMII_10_100; -- mtk_w32(eth, val, INTF_MODE); -- -- regmap_update_bits(eth->ethsys, ETHSYS_CLKCFG0, -- ETHSYS_TRGMII_CLK_SEL362_5, -- ETHSYS_TRGMII_CLK_SEL362_5); -- -- val = (speed == SPEED_1000) ? 250000000 : 500000000; -- ret = clk_set_rate(eth->clks[MTK_CLK_TRGPLL], val); -- if (ret) -- dev_err(eth->dev, "Failed to set trgmii pll: %d\n", ret); -- -- val = (speed == SPEED_1000) ? -- RCK_CTRL_RGMII_1000 : RCK_CTRL_RGMII_10_100; -- mtk_w32(eth, val, TRGMII_RCK_CTRL); -- -- val = (speed == SPEED_1000) ? -- TCK_CTRL_RGMII_1000 : TCK_CTRL_RGMII_10_100; -- mtk_w32(eth, val, TRGMII_TCK_CTRL); -+ dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n"); - } - - static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, -@@ -428,17 +409,8 @@ static void mtk_mac_config(struct phylin - state->interface)) - goto err_phy; - } else { -- /* FIXME: this is incorrect. Not only does it -- * use state->speed (which is not guaranteed -- * to be correct) but it also makes use of it -- * in a code path that will only be reachable -- * when the PHY interface mode changes, not -- * when the speed changes. Consequently, RGMII -- * is probably broken. -- */ - mtk_gmac0_rgmii_adjust(mac->hw, -- state->interface, -- state->speed); -+ state->interface); - - /* mt7623_pad_clk_setup */ - for (i = 0 ; i < NUM_TRGMII_CTRL; i++) -@@ -4288,13 +4260,19 @@ static int mtk_add_mac(struct mtk_eth *e - mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; - -- __set_bit(PHY_INTERFACE_MODE_MII, -- mac->phylink_config.supported_interfaces); -- __set_bit(PHY_INTERFACE_MODE_GMII, -- mac->phylink_config.supported_interfaces); -+ /* MT7623 gmac0 is now missing its speed-specific PLL configuration -+ * in its .mac_config method (since state->speed is not valid there. -+ * Disable support for MII, GMII and RGMII. -+ */ -+ if (!mac->hw->soc->disable_pll_modes || mac->id != 0) { -+ __set_bit(PHY_INTERFACE_MODE_MII, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_GMII, -+ mac->phylink_config.supported_interfaces); - -- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) -- phy_interface_set_rgmii(mac->phylink_config.supported_interfaces); -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) -+ phy_interface_set_rgmii(mac->phylink_config.supported_interfaces); -+ } - - if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id) - __set_bit(PHY_INTERFACE_MODE_TRGMII, -@@ -4754,6 +4732,7 @@ static const struct mtk_soc_data mt7623_ - .offload_version = 1, - .hash_offset = 2, - .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, -+ .disable_pll_modes = true, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1027,6 +1027,7 @@ struct mtk_soc_data { - u16 foe_entry_size; - netdev_features_t hw_features; - bool has_accounting; -+ bool disable_pll_modes; - struct { - u32 txd_size; - u32 rxd_size; diff --git a/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch b/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch deleted file mode 100644 index e1b12725b50a07..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch +++ /dev/null @@ -1,81 +0,0 @@ -From a4c2233b1e4359b6c64b6f9ba98c8718a11fffee Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Sat, 22 Jul 2023 21:32:54 +0100 -Subject: [PATCH 097/250] net: ethernet: mtk_eth_soc: remove mac_pcs_get_state - and modernise - -Remove the .mac_pcs_get_state function, since as far as I can tell is -never called - no DT appears to specify an in-band-status management -nor SFP support for this driver. - -Removal of this, along with the previous patch to remove the incorrect -clocking configuration, means that the driver becomes non-legacy, so -we can remove the "legacy_pre_march2020" status from this driver. - -Reviewed-by: Daniel Golle -Tested-by: Daniel Golle -Tested-by: Frank Wunderlich -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 --------------------- - 1 file changed, 35 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -511,38 +511,6 @@ static int mtk_mac_finish(struct phylink - return 0; - } - --static void mtk_mac_pcs_get_state(struct phylink_config *config, -- struct phylink_link_state *state) --{ -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); -- u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id)); -- -- state->link = (pmsr & MAC_MSR_LINK); -- state->duplex = (pmsr & MAC_MSR_DPX) >> 1; -- -- switch (pmsr & (MAC_MSR_SPEED_1000 | MAC_MSR_SPEED_100)) { -- case 0: -- state->speed = SPEED_10; -- break; -- case MAC_MSR_SPEED_100: -- state->speed = SPEED_100; -- break; -- case MAC_MSR_SPEED_1000: -- state->speed = SPEED_1000; -- break; -- default: -- state->speed = SPEED_UNKNOWN; -- break; -- } -- -- state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX); -- if (pmsr & MAC_MSR_RX_FC) -- state->pause |= MLO_PAUSE_RX; -- if (pmsr & MAC_MSR_TX_FC) -- state->pause |= MLO_PAUSE_TX; --} -- - static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, - phy_interface_t interface) - { -@@ -665,7 +633,6 @@ static void mtk_mac_link_up(struct phyli - static const struct phylink_mac_ops mtk_phylink_ops = { - .validate = phylink_generic_validate, - .mac_select_pcs = mtk_mac_select_pcs, -- .mac_pcs_get_state = mtk_mac_pcs_get_state, - .mac_config = mtk_mac_config, - .mac_finish = mtk_mac_finish, - .mac_link_down = mtk_mac_link_down, -@@ -4255,8 +4222,6 @@ static int mtk_add_mac(struct mtk_eth *e - - mac->phylink_config.dev = ð->netdev[id]->dev; - mac->phylink_config.type = PHYLINK_NETDEV; -- /* This driver makes use of state->speed in mac_config */ -- mac->phylink_config.legacy_pre_march2020 = true; - mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; - diff --git a/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch b/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch deleted file mode 100644 index e4be17c9cbcfe4..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch +++ /dev/null @@ -1,550 +0,0 @@ -From 5d8d05fbf804b4485646d39551ac27452e45afd3 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:52:02 +0100 -Subject: [PATCH 099/250] net: ethernet: mtk_eth_soc: add version in - mtk_soc_data - -Introduce version field in mtk_soc_data data structure in order to -make mtk_eth driver easier to maintain for chipset configuration -codebase. Get rid of MTK_NETSYS_V2 bit in chip capabilities. -This is a preliminary patch to introduce support for MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/e52fae302ca135436e5cdd26d38d87be2da63055.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++-------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 36 +++++++----- - drivers/net/ethernet/mediatek/mtk_ppe.c | 18 +++--- - .../net/ethernet/mediatek/mtk_ppe_offload.c | 2 +- - drivers/net/ethernet/mediatek/mtk_wed.c | 4 +- - 5 files changed, 66 insertions(+), 49 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -536,7 +536,7 @@ static void mtk_set_queue_speed(struct m - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | - MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v1(eth)) - val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; - - if (IS_ENABLED(CONFIG_SOC_MT7621)) { -@@ -911,7 +911,7 @@ static bool mtk_rx_get_desc(struct mtk_e - rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); - rxd->rxd3 = READ_ONCE(dma_rxd->rxd3); - rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - rxd->rxd5 = READ_ONCE(dma_rxd->rxd5); - rxd->rxd6 = READ_ONCE(dma_rxd->rxd6); - } -@@ -969,7 +969,7 @@ static int mtk_init_fq_dma(struct mtk_et - - txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE); - txd->txd4 = 0; -- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - txd->txd5 = 0; - txd->txd6 = 0; - txd->txd7 = 0; -@@ -1158,7 +1158,7 @@ static void mtk_tx_set_dma_desc(struct n - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - mtk_tx_set_dma_desc_v2(dev, txd, info); - else - mtk_tx_set_dma_desc_v1(dev, txd, info); -@@ -1465,7 +1465,7 @@ static void mtk_update_rx_cpu_idx(struct - - static bool mtk_page_pool_enabled(struct mtk_eth *eth) - { -- return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2); -+ return eth->soc->version == 2; - } - - static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, -@@ -1805,7 +1805,7 @@ static int mtk_poll_rx(struct napi_struc - break; - - /* find out which mac the packet come from. values start at 1 */ -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; - else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && - !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) -@@ -1901,7 +1901,7 @@ static int mtk_poll_rx(struct napi_struc - skb->dev = netdev; - bytes += skb->len; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); - hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; - if (hash != MTK_RXD5_FOE_ENTRY) -@@ -1926,8 +1926,8 @@ static int mtk_poll_rx(struct napi_struc - /* When using VLAN untagging in combination with DSA, the - * hardware treats the MTK special tag as a VLAN and untags it. - */ -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && -- (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) { -+ if (mtk_is_netsys_v1(eth) && (trxd.rxd2 & RX_DMA_VTAG) && -+ netdev_uses_dsa(netdev)) { - unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0); - - if (port < ARRAY_SIZE(eth->dsa_meta) && -@@ -2231,7 +2231,7 @@ static int mtk_tx_alloc(struct mtk_eth * - txd->txd2 = next_ptr; - txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; - txd->txd4 = 0; -- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - txd->txd5 = 0; - txd->txd6 = 0; - txd->txd7 = 0; -@@ -2284,14 +2284,14 @@ static int mtk_tx_alloc(struct mtk_eth * - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | - MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v1(eth)) - val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; - mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); - ofs += MTK_QTX_OFFSET; - } - val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16); - mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate); -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4); - } else { - mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); -@@ -2418,7 +2418,7 @@ static int mtk_rx_alloc(struct mtk_eth * - - rxd->rxd3 = 0; - rxd->rxd4 = 0; -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - rxd->rxd5 = 0; - rxd->rxd6 = 0; - rxd->rxd7 = 0; -@@ -2969,7 +2969,7 @@ static int mtk_start_dma(struct mtk_eth - MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | - MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - val |= MTK_MUTLI_CNT | MTK_RESV_BUF | - MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | - MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; -@@ -3113,7 +3113,7 @@ static int mtk_open(struct net_device *d - phylink_start(mac->phylink); - netif_tx_start_all_queues(dev); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return 0; - - if (mtk_uses_dsa(dev) && !eth->prog) { -@@ -3378,7 +3378,7 @@ static void mtk_hw_reset(struct mtk_eth - { - u32 val; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); - val = RSTCTRL_PPE0_V2; - } else { -@@ -3390,7 +3390,7 @@ static void mtk_hw_reset(struct mtk_eth - - ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, - 0x3ffffff); - } -@@ -3416,7 +3416,7 @@ static void mtk_hw_warm_reset(struct mtk - return; - } - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; - else - rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; -@@ -3586,7 +3586,7 @@ static int mtk_hw_init(struct mtk_eth *e - else - mtk_hw_reset(eth); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - /* Set FE to PDMAv2 if necessary */ - val = mtk_r32(eth, MTK_FE_GLO_MISC); - mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); -@@ -3623,7 +3623,7 @@ static int mtk_hw_init(struct mtk_eth *e - */ - val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); - mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v1(eth)) { - val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); - -@@ -3645,7 +3645,7 @@ static int mtk_hw_init(struct mtk_eth *e - mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); - mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - /* PSE should not drop port8 and port9 packets from WDMA Tx */ - mtk_w32(eth, 0x00000300, PSE_DROP_CFG); - -@@ -4434,7 +4434,7 @@ static int mtk_probe(struct platform_dev - } - } - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - err = -EINVAL; -@@ -4542,9 +4542,8 @@ static int mtk_probe(struct platform_dev - } - - if (eth->soc->offload_version) { -- u32 num_ppe; -+ u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1; - -- num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; - num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe); - for (i = 0; i < num_ppe; i++) { - u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; -@@ -4638,6 +4637,7 @@ static const struct mtk_soc_data mt2701_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, -+ .version = 1, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4654,6 +4654,7 @@ static const struct mtk_soc_data mt7621_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7621_CLKS_BITMAP, - .required_pctl = false, -+ .version = 1, - .offload_version = 1, - .hash_offset = 2, - .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, -@@ -4674,6 +4675,7 @@ static const struct mtk_soc_data mt7622_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7622_CLKS_BITMAP, - .required_pctl = false, -+ .version = 1, - .offload_version = 2, - .hash_offset = 2, - .has_accounting = true, -@@ -4694,6 +4696,7 @@ static const struct mtk_soc_data mt7623_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, -+ .version = 1, - .offload_version = 1, - .hash_offset = 2, - .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, -@@ -4716,6 +4719,7 @@ static const struct mtk_soc_data mt7629_ - .required_clks = MT7629_CLKS_BITMAP, - .required_pctl = false, - .has_accounting = true, -+ .version = 1, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4733,6 +4737,7 @@ static const struct mtk_soc_data mt7981_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7981_CLKS_BITMAP, - .required_pctl = false, -+ .version = 2, - .offload_version = 2, - .hash_offset = 4, - .has_accounting = true, -@@ -4754,6 +4759,7 @@ static const struct mtk_soc_data mt7986_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7986_CLKS_BITMAP, - .required_pctl = false, -+ .version = 2, - .offload_version = 2, - .hash_offset = 4, - .has_accounting = true, -@@ -4774,6 +4780,7 @@ static const struct mtk_soc_data rt5350_ - .hw_features = MTK_HW_FEATURES_MT7628, - .required_clks = MT7628_CLKS_BITMAP, - .required_pctl = false, -+ .version = 1, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -817,7 +817,6 @@ enum mkt_eth_capabilities { - MTK_SHARED_INT_BIT, - MTK_TRGMII_MT7621_CLK_BIT, - MTK_QDMA_BIT, -- MTK_NETSYS_V2_BIT, - MTK_SOC_MT7628_BIT, - MTK_RSTCTRL_PPE1_BIT, - MTK_U3_COPHY_V2_BIT, -@@ -852,7 +851,6 @@ enum mkt_eth_capabilities { - #define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) - #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) - #define MTK_QDMA BIT(MTK_QDMA_BIT) --#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) - #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) - #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) - #define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) -@@ -931,11 +929,11 @@ enum mkt_eth_capabilities { - #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ -- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -+ MTK_RSTCTRL_PPE1) - - #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ -- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -+ MTK_RSTCTRL_PPE1) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1006,6 +1004,7 @@ struct mtk_reg_map { - * @required_pctl A bool value to show whether the SoC requires - * the extra setup for those pins used by GMAC. - * @hash_offset Flow table hash offset. -+ * @version SoC version. - * @foe_entry_size Foe table entry size. - * @has_accounting Bool indicating support for accounting of - * offloaded flows. -@@ -1024,6 +1023,7 @@ struct mtk_soc_data { - bool required_pctl; - u8 offload_version; - u8 hash_offset; -+ u8 version; - u16 foe_entry_size; - netdev_features_t hw_features; - bool has_accounting; -@@ -1180,6 +1180,16 @@ struct mtk_mac { - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ - extern const struct of_device_id of_mtk_match[]; - -+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) -+{ -+ return eth->soc->version == 1; -+} -+ -+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) -+{ -+ return eth->soc->version > 1; -+} -+ - static inline struct mtk_foe_entry * - mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) - { -@@ -1190,7 +1200,7 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u - - static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB1_BIND_TIMESTAMP_V2; - - return MTK_FOE_IB1_BIND_TIMESTAMP; -@@ -1198,7 +1208,7 @@ static inline u32 mtk_get_ib1_ts_mask(st - - static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB1_BIND_PPPOE_V2; - - return MTK_FOE_IB1_BIND_PPPOE; -@@ -1206,7 +1216,7 @@ static inline u32 mtk_get_ib1_ppoe_mask( - - static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB1_BIND_VLAN_TAG_V2; - - return MTK_FOE_IB1_BIND_VLAN_TAG; -@@ -1214,7 +1224,7 @@ static inline u32 mtk_get_ib1_vlan_tag_m - - static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB1_BIND_VLAN_LAYER_V2; - - return MTK_FOE_IB1_BIND_VLAN_LAYER; -@@ -1222,7 +1232,7 @@ static inline u32 mtk_get_ib1_vlan_layer - - static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); - - return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val); -@@ -1230,7 +1240,7 @@ static inline u32 mtk_prep_ib1_vlan_laye - - static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); - - return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val); -@@ -1238,7 +1248,7 @@ static inline u32 mtk_get_ib1_vlan_layer - - static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB1_PACKET_TYPE_V2; - - return MTK_FOE_IB1_PACKET_TYPE; -@@ -1246,7 +1256,7 @@ static inline u32 mtk_get_ib1_pkt_type_m - - static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val); - - return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val); -@@ -1254,7 +1264,7 @@ static inline u32 mtk_get_ib1_pkt_type(s - - static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB2_MULTICAST_V2; - - return MTK_FOE_IB2_MULTICAST; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -207,7 +207,7 @@ int mtk_foe_entry_prepare(struct mtk_eth - - memset(entry, 0, sizeof(*entry)); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | - FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) | - FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | -@@ -271,7 +271,7 @@ int mtk_foe_entry_set_pse_port(struct mt - u32 *ib2 = mtk_foe_entry_ib2(eth, entry); - u32 val = *ib2; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - val &= ~MTK_FOE_IB2_DEST_PORT_V2; - val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port); - } else { -@@ -422,7 +422,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et - struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - u32 *ib2 = mtk_foe_entry_ib2(eth, entry); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; - *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | - MTK_FOE_IB2_WDMA_WINFO_V2; -@@ -452,7 +452,7 @@ int mtk_foe_entry_set_queue(struct mtk_e - { - u32 *ib2 = mtk_foe_entry_ib2(eth, entry); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - *ib2 &= ~MTK_FOE_IB2_QID_V2; - *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue); - *ib2 |= MTK_FOE_IB2_PSE_QOS_V2; -@@ -607,7 +607,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - struct mtk_foe_entry *hwe; - u32 val; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; - entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2, - timestamp); -@@ -623,7 +623,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - hwe->ib1 = entry->ib1; - - if (ppe->accounting) { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - val = MTK_FOE_IB2_MIB_CNT_V2; - else - val = MTK_FOE_IB2_MIB_CNT; -@@ -971,7 +971,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_SCAN_MODE_CHECK_AGE) | - FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, - MTK_PPE_ENTRIES_SHIFT); -- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(ppe->eth)) - val |= MTK_PPE_TB_CFG_INFO_SEL; - ppe_w32(ppe, MTK_PPE_TB_CFG, val); - -@@ -987,7 +987,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_FLOW_CFG_IP4_NAPT | - MTK_PPE_FLOW_CFG_IP4_DSLITE | - MTK_PPE_FLOW_CFG_IP4_NAT_FRAG; -- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(ppe->eth)) - val |= MTK_PPE_MD_TOAP_BYP_CRSN0 | - MTK_PPE_MD_TOAP_BYP_CRSN1 | - MTK_PPE_MD_TOAP_BYP_CRSN2 | -@@ -1029,7 +1029,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - - ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); - -- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(ppe->eth)) { - ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); - ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); - } ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -193,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et - if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { - mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, - info.bss, info.wcid); -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - switch (info.wdma_idx) { - case 0: - pse_port = 8; ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1084,7 +1084,7 @@ mtk_wed_rx_reset(struct mtk_wed_device * - } else { - struct mtk_eth *eth = dev->hw->eth; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - wed_set(dev, MTK_WED_RESET_IDX, - MTK_WED_RESET_IDX_RX_V2); - else -@@ -1806,7 +1806,7 @@ void mtk_wed_add_hw(struct device_node * - hw->wdma = wdma; - hw->index = index; - hw->irq = irq; -- hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; -+ hw->version = mtk_is_netsys_v1(eth) ? 1 : 2; - - if (hw->version == 1) { - hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, diff --git a/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch b/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch deleted file mode 100644 index 5a08b9dddf3703..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch +++ /dev/null @@ -1,29 +0,0 @@ -From f8fb8dbd158c585be7574faf92db7d614b6722ff Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:52:27 +0100 -Subject: [PATCH 100/250] net: ethernet: mtk_eth_soc: increase MAX_DEVS to 3 - -This is a preliminary patch to add MT7988 SoC support since it runs 3 -macs instead of 2. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/3563e5fab367e7d79a7f1296fabaa5c20f202d7a.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1040,8 +1040,8 @@ struct mtk_soc_data { - - #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) - --/* currently no SoC has more than 2 macs */ --#define MTK_MAX_DEVS 2 -+/* currently no SoC has more than 3 macs */ -+#define MTK_MAX_DEVS 3 - - /* struct mtk_eth - This is the main datasructure for holding the state - * of the driver diff --git a/target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch b/target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch deleted file mode 100644 index faa8734c24b4f0..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 856be974290f28d7943be2ac5a382c4139486196 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:52:44 +0100 -Subject: [PATCH 101/250] net: ethernet: mtk_eth_soc: rely on MTK_MAX_DEVS and - remove MTK_MAC_COUNT - -Get rid of MTK_MAC_COUNT since it is a duplicated of MTK_MAX_DEVS. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/1856f4266f2fc80677807b1bad867659e7b00c65.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++++++--------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 - - 2 files changed, 27 insertions(+), 23 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -837,7 +837,7 @@ static void mtk_stats_update(struct mtk_ - { - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->mac[i] || !eth->mac[i]->hw_stats) - continue; - if (spin_trylock(ð->mac[i]->hw_stats->stats_lock)) { -@@ -1340,7 +1340,7 @@ static int mtk_queue_stopped(struct mtk_ - { - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->netdev[i]) - continue; - if (netif_queue_stopped(eth->netdev[i])) -@@ -1354,7 +1354,7 @@ static void mtk_wake_queue(struct mtk_et - { - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->netdev[i]) - continue; - netif_tx_wake_all_queues(eth->netdev[i]); -@@ -1811,7 +1811,7 @@ static int mtk_poll_rx(struct napi_struc - !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) - mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1; - -- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT || -+ if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS || - !eth->netdev[mac])) - goto release_desc; - -@@ -2843,7 +2843,7 @@ static void mtk_dma_free(struct mtk_eth - const struct mtk_soc_data *soc = eth->soc; - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) -+ for (i = 0; i < MTK_MAX_DEVS; i++) - if (eth->netdev[i]) - netdev_reset_queue(eth->netdev[i]); - if (eth->scratch_ring) { -@@ -2997,8 +2997,13 @@ static void mtk_gdm_config(struct mtk_et - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - return; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -- u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ u32 val; -+ -+ if (!eth->netdev[i]) -+ continue; -+ -+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); - - /* default setup the forward port to send frame to PDMA */ - val &= ~0xffff; -@@ -3008,7 +3013,7 @@ static void mtk_gdm_config(struct mtk_et - - val |= config; - -- if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i])) -+ if (netdev_uses_dsa(eth->netdev[i])) - val |= MTK_GDMA_SPECIAL_TAG; - - mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); -@@ -3607,15 +3612,15 @@ static int mtk_hw_init(struct mtk_eth *e - * up with the more appropriate value when mtk_mac_config call is being - * invoked. - */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - struct net_device *dev = eth->netdev[i]; - -- mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); -- if (dev) { -- struct mtk_mac *mac = netdev_priv(dev); -+ if (!dev) -+ continue; - -- mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN); -- } -+ mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); -+ mtk_set_mcr_max_rx(netdev_priv(dev), -+ dev->mtu + MTK_RX_ETH_HLEN); - } - - /* Indicates CDM to parse the MTK special tag from CPU -@@ -3795,7 +3800,7 @@ static void mtk_pending_work(struct work - mtk_prepare_for_reset(eth); - - /* stop all devices to make sure that dma is properly shut down */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->netdev[i] || !netif_running(eth->netdev[i])) - continue; - -@@ -3811,8 +3816,8 @@ static void mtk_pending_work(struct work - mtk_hw_init(eth, true); - - /* restart DMA and enable IRQs */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!test_bit(i, &restart)) -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ if (!eth->netdev[i] || !test_bit(i, &restart)) - continue; - - if (mtk_open(eth->netdev[i])) { -@@ -3839,7 +3844,7 @@ static int mtk_free_dev(struct mtk_eth * - { - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->netdev[i]) - continue; - free_netdev(eth->netdev[i]); -@@ -3858,7 +3863,7 @@ static int mtk_unreg_dev(struct mtk_eth - { - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - struct mtk_mac *mac; - if (!eth->netdev[i]) - continue; -@@ -4159,7 +4164,7 @@ static int mtk_add_mac(struct mtk_eth *e - } - - id = be32_to_cpup(_id); -- if (id >= MTK_MAC_COUNT) { -+ if (id >= MTK_MAX_DEVS) { - dev_err(eth->dev, "%d is not a valid mac id\n", id); - return -EINVAL; - } -@@ -4304,7 +4309,7 @@ void mtk_eth_set_dma_device(struct mtk_e - - rtnl_lock(); - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - dev = eth->netdev[i]; - - if (!dev || !(dev->flags & IFF_UP)) -@@ -4612,7 +4617,7 @@ static int mtk_remove(struct platform_de - int i; - - /* stop all devices to make sure that dma is properly shut down */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->netdev[i]) - continue; - mtk_stop(eth->netdev[i]); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -33,7 +33,6 @@ - #define MTK_TX_DMA_BUF_LEN_V2 0xffff - #define MTK_QDMA_RING_SIZE 2048 - #define MTK_DMA_SIZE 512 --#define MTK_MAC_COUNT 2 - #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN) - #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN) - #define MTK_DMA_DUMMY_DESC 0xffffffff diff --git a/target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch b/target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch deleted file mode 100644 index c22b55c6f13ddb..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch +++ /dev/null @@ -1,307 +0,0 @@ -From a41d535855976838d246c079143c948dcf0f7931 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:52:59 +0100 -Subject: [PATCH 102/250] net: ethernet: mtk_eth_soc: add NETSYS_V3 version - support - -Introduce NETSYS_V3 chipset version support. -This is a preliminary patch to introduce support for MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 ++++++++++++++------ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 48 +++++++-- - 2 files changed, 116 insertions(+), 37 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -817,17 +817,32 @@ void mtk_stats_update_mac(struct mtk_mac - mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs); - hw_stats->rx_flow_control_packets += - mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs); -- hw_stats->tx_skip += -- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs); -- hw_stats->tx_collisions += -- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs); -- hw_stats->tx_bytes += -- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs); -- stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs); -- if (stats) -- hw_stats->tx_bytes += (stats << 32); -- hw_stats->tx_packets += -- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs); -+ -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ hw_stats->tx_skip += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs); -+ hw_stats->tx_collisions += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs); -+ hw_stats->tx_bytes += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs); -+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs); -+ if (stats) -+ hw_stats->tx_bytes += (stats << 32); -+ hw_stats->tx_packets += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs); -+ } else { -+ hw_stats->tx_skip += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs); -+ hw_stats->tx_collisions += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs); -+ hw_stats->tx_bytes += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs); -+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs); -+ if (stats) -+ hw_stats->tx_bytes += (stats << 32); -+ hw_stats->tx_packets += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs); -+ } - } - - u64_stats_update_end(&hw_stats->syncp); -@@ -1129,7 +1144,10 @@ static void mtk_tx_set_dma_desc_v2(struc - data |= TX_DMA_LS0; - WRITE_ONCE(desc->txd3, data); - -- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ -+ if (mac->id == MTK_GMAC3_ID) -+ data = PSE_GDM3_PORT; -+ else -+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ - data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); - WRITE_ONCE(desc->txd4, data); - -@@ -1140,6 +1158,8 @@ static void mtk_tx_set_dma_desc_v2(struc - /* tx checksum offload */ - if (info->csum) - data |= TX_DMA_CHKSUM_V2; -+ if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev)) -+ data |= TX_DMA_SPTAG_V3; - } - WRITE_ONCE(desc->txd5, data); - -@@ -1205,8 +1225,7 @@ static int mtk_tx_map(struct sk_buff *sk - mtk_tx_set_dma_desc(dev, itxd, &txd_info); - - itx_buf->flags |= MTK_TX_FLAGS_SINGLE0; -- itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : -- MTK_TX_FLAGS_FPORT1; -+ itx_buf->mac_id = mac->id; - setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, - k++); - -@@ -1254,8 +1273,7 @@ static int mtk_tx_map(struct sk_buff *sk - memset(tx_buf, 0, sizeof(*tx_buf)); - tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; - tx_buf->flags |= MTK_TX_FLAGS_PAGE0; -- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : -- MTK_TX_FLAGS_FPORT1; -+ tx_buf->mac_id = mac->id; - - setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, - txd_info.size, k++); -@@ -1557,7 +1575,7 @@ static int mtk_xdp_frame_map(struct mtk_ - } - mtk_tx_set_dma_desc(dev, txd, txd_info); - -- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; -+ tx_buf->mac_id = mac->id; - tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; - tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; - -@@ -1805,11 +1823,24 @@ static int mtk_poll_rx(struct napi_struc - break; - - /* find out which mac the packet come from. values start at 1 */ -- if (mtk_is_netsys_v2_or_greater(eth)) -- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; -- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && -- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) -+ if (mtk_is_netsys_v2_or_greater(eth)) { -+ u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5); -+ -+ switch (val) { -+ case PSE_GDM1_PORT: -+ case PSE_GDM2_PORT: -+ mac = val - 1; -+ break; -+ case PSE_GDM3_PORT: -+ mac = MTK_GMAC3_ID; -+ break; -+ default: -+ break; -+ } -+ } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && -+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) { - mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1; -+ } - - if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS || - !eth->netdev[mac])) -@@ -2029,7 +2060,6 @@ static int mtk_poll_tx_qdma(struct mtk_e - - while ((cpu != dma) && budget) { - u32 next_cpu = desc->txd2; -- int mac = 0; - - desc = mtk_qdma_phys_to_virt(ring, desc->txd2); - if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0) -@@ -2037,15 +2067,13 @@ static int mtk_poll_tx_qdma(struct mtk_e - - tx_buf = mtk_desc_to_tx_buf(ring, desc, - eth->soc->txrx.txd_size); -- if (tx_buf->flags & MTK_TX_FLAGS_FPORT1) -- mac = 1; -- - if (!tx_buf->data) - break; - - if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { - if (tx_buf->type == MTK_TYPE_SKB) -- mtk_poll_tx_done(eth, state, mac, tx_buf->data); -+ mtk_poll_tx_done(eth, state, tx_buf->mac_id, -+ tx_buf->data); - - budget--; - } -@@ -3650,7 +3678,24 @@ static int mtk_hw_init(struct mtk_eth *e - mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); - mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); - -- if (mtk_is_netsys_v2_or_greater(eth)) { -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ /* PSE should not drop port1, port8 and port9 packets */ -+ mtk_w32(eth, 0x00000302, PSE_DROP_CFG); -+ -+ /* GDM and CDM Threshold */ -+ mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES); -+ mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES); -+ -+ /* Disable GDM1 RX CRC stripping */ -+ mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0)); -+ -+ /* PSE GDM3 MIB counter has incorrect hw default values, -+ * so the driver ought to read clear the values beforehand -+ * in case ethtool retrieve wrong mib values. -+ */ -+ for (i = 0; i < 0x80; i += 0x4) -+ mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i); -+ } else if (!mtk_is_netsys_v1(eth)) { - /* PSE should not drop port8 and port9 packets from WDMA Tx */ - mtk_w32(eth, 0x00000300, PSE_DROP_CFG); - -@@ -4212,7 +4257,11 @@ static int mtk_add_mac(struct mtk_eth *e - } - spin_lock_init(&mac->hw_stats->stats_lock); - u64_stats_init(&mac->hw_stats->syncp); -- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET; -+ -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mac->hw_stats->reg_offset = id * 0x80; -+ else -+ mac->hw_stats->reg_offset = id * 0x40; - - /* phylink create */ - err = of_get_phy_mode(np, &phy_mode); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -122,6 +122,7 @@ - #define MTK_GDMA_ICS_EN BIT(22) - #define MTK_GDMA_TCS_EN BIT(21) - #define MTK_GDMA_UCS_EN BIT(20) -+#define MTK_GDMA_STRP_CRC BIT(16) - #define MTK_GDMA_TO_PDMA 0x0 - #define MTK_GDMA_DROP_ALL 0x7777 - -@@ -287,8 +288,6 @@ - /* QDMA Interrupt grouping registers */ - #define MTK_RLS_DONE_INT BIT(0) - --#define MTK_STAT_OFFSET 0x40 -- - /* QDMA TX NUM */ - #define QID_BITS_V2(x) (((x) & 0x3f) << 16) - #define MTK_QDMA_GMAC2_QID 8 -@@ -301,6 +300,8 @@ - #define TX_DMA_CHKSUM_V2 (0x7 << 28) - #define TX_DMA_TSO_V2 BIT(31) - -+#define TX_DMA_SPTAG_V3 BIT(27) -+ - /* QDMA V2 descriptor txd4 */ - #define TX_DMA_FPORT_SHIFT_V2 8 - #define TX_DMA_FPORT_MASK_V2 0xf -@@ -631,12 +632,6 @@ enum mtk_tx_flags { - */ - MTK_TX_FLAGS_SINGLE0 = 0x01, - MTK_TX_FLAGS_PAGE0 = 0x02, -- -- /* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted -- * SKB out instead of looking up through hardware TX descriptor. -- */ -- MTK_TX_FLAGS_FPORT0 = 0x04, -- MTK_TX_FLAGS_FPORT1 = 0x08, - }; - - /* This enum allows us to identify how the clock is defined on the array of the -@@ -722,6 +717,35 @@ enum mtk_dev_state { - MTK_RESETTING - }; - -+/* PSE Port Definition */ -+enum mtk_pse_port { -+ PSE_ADMA_PORT = 0, -+ PSE_GDM1_PORT, -+ PSE_GDM2_PORT, -+ PSE_PPE0_PORT, -+ PSE_PPE1_PORT, -+ PSE_QDMA_TX_PORT, -+ PSE_QDMA_RX_PORT, -+ PSE_DROP_PORT, -+ PSE_WDMA0_PORT, -+ PSE_WDMA1_PORT, -+ PSE_TDMA_PORT, -+ PSE_NONE_PORT, -+ PSE_PPE2_PORT, -+ PSE_WDMA2_PORT, -+ PSE_EIP197_PORT, -+ PSE_GDM3_PORT, -+ PSE_PORT_MAX -+}; -+ -+/* GMAC Identifier */ -+enum mtk_gmac_id { -+ MTK_GMAC1_ID = 0, -+ MTK_GMAC2_ID, -+ MTK_GMAC3_ID, -+ MTK_GMAC_ID_MAX -+}; -+ - enum mtk_tx_buf_type { - MTK_TYPE_SKB, - MTK_TYPE_XDP_TX, -@@ -740,7 +764,8 @@ struct mtk_tx_buf { - enum mtk_tx_buf_type type; - void *data; - -- u32 flags; -+ u16 mac_id; -+ u16 flags; - DEFINE_DMA_UNMAP_ADDR(dma_addr0); - DEFINE_DMA_UNMAP_LEN(dma_len0); - DEFINE_DMA_UNMAP_ADDR(dma_addr1); -@@ -1189,6 +1214,11 @@ static inline bool mtk_is_netsys_v2_or_g - return eth->soc->version > 1; - } - -+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) -+{ -+ return eth->soc->version > 2; -+} -+ - static inline struct mtk_foe_entry * - mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) - { diff --git a/target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch b/target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch deleted file mode 100644 index 0a72eec2fc16b7..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch +++ /dev/null @@ -1,193 +0,0 @@ -From db797ae0542220a98658229397da464c383c991c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:53:13 +0100 -Subject: [PATCH 103/250] net: ethernet: mtk_eth_soc: convert caps in - mtk_soc_data struct to u64 - -This is a preliminary patch to introduce support for MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/9499ac3670b2fc5b444404b84e8a4a169beabbf2.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 ++++---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 56 ++++++++++---------- - 2 files changed, 39 insertions(+), 39 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -15,10 +15,10 @@ - struct mtk_eth_muxc { - const char *name; - int cap_bit; -- int (*set_path)(struct mtk_eth *eth, int path); -+ int (*set_path)(struct mtk_eth *eth, u64 path); - }; - --static const char *mtk_eth_path_name(int path) -+static const char *mtk_eth_path_name(u64 path) - { - switch (path) { - case MTK_ETH_PATH_GMAC1_RGMII: -@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int - } - } - --static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path) -+static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path) - { - bool updated = true; - u32 val, mask, set; -@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str - return 0; - } - --static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path) -+static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy( - return 0; - } - --static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path) -+static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0, mask = 0, reg = 0; - bool updated = true; -@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru - return 0; - } - --static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path) -+static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_ - return 0; - } - --static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path) -+static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth - }, - }; - --static int mtk_eth_mux_setup(struct mtk_eth *eth, int path) -+static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path) - { - int i, err = 0; - -@@ -249,7 +249,7 @@ out: - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id) - { -- int path; -+ u64 path; - - path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII : - MTK_ETH_PATH_GMAC2_SGMII; -@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk - - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id) - { -- int path = 0; -+ u64 path = 0; - - if (mac_id == 1) - path = MTK_ETH_PATH_GMAC2_GEPHY; -@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk - - int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id) - { -- int path; -+ u64 path; - - path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_RGMII : - MTK_ETH_PATH_GMAC2_RGMII; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -863,41 +863,41 @@ enum mkt_eth_capabilities { - }; - - /* Supported hardware group on SoCs */ --#define MTK_RGMII BIT(MTK_RGMII_BIT) --#define MTK_TRGMII BIT(MTK_TRGMII_BIT) --#define MTK_SGMII BIT(MTK_SGMII_BIT) --#define MTK_ESW BIT(MTK_ESW_BIT) --#define MTK_GEPHY BIT(MTK_GEPHY_BIT) --#define MTK_MUX BIT(MTK_MUX_BIT) --#define MTK_INFRA BIT(MTK_INFRA_BIT) --#define MTK_SHARED_SGMII BIT(MTK_SHARED_SGMII_BIT) --#define MTK_HWLRO BIT(MTK_HWLRO_BIT) --#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) --#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) --#define MTK_QDMA BIT(MTK_QDMA_BIT) --#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) --#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) --#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) -+#define MTK_RGMII BIT_ULL(MTK_RGMII_BIT) -+#define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) -+#define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) -+#define MTK_ESW BIT_ULL(MTK_ESW_BIT) -+#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) -+#define MTK_MUX BIT_ULL(MTK_MUX_BIT) -+#define MTK_INFRA BIT_ULL(MTK_INFRA_BIT) -+#define MTK_SHARED_SGMII BIT_ULL(MTK_SHARED_SGMII_BIT) -+#define MTK_HWLRO BIT_ULL(MTK_HWLRO_BIT) -+#define MTK_SHARED_INT BIT_ULL(MTK_SHARED_INT_BIT) -+#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT) -+#define MTK_QDMA BIT_ULL(MTK_QDMA_BIT) -+#define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT) -+#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) -+#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ -- BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -+ BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) - #define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY \ -- BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) -+ BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) - #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \ -- BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) -+ BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) - #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \ -- BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) -+ BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) - #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ -- BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) -+ BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) - - /* Supported path present on SoCs */ --#define MTK_ETH_PATH_GMAC1_RGMII BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT) --#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT) --#define MTK_ETH_PATH_GMAC1_SGMII BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT) --#define MTK_ETH_PATH_GMAC2_RGMII BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT) --#define MTK_ETH_PATH_GMAC2_SGMII BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT) --#define MTK_ETH_PATH_GMAC2_GEPHY BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT) --#define MTK_ETH_PATH_GDM1_ESW BIT(MTK_ETH_PATH_GDM1_ESW_BIT) -+#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) -+#define MTK_ETH_PATH_GMAC1_TRGMII BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT) -+#define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) -+#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) - - #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) - #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) -@@ -1042,7 +1042,7 @@ struct mtk_reg_map { - struct mtk_soc_data { - const struct mtk_reg_map *reg_map; - u32 ana_rgc3; -- u32 caps; -+ u64 caps; - u32 required_clks; - bool required_pctl; - u8 offload_version; diff --git a/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch b/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch deleted file mode 100644 index 4e5b857d48b3df..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch +++ /dev/null @@ -1,132 +0,0 @@ -From a1c9f7d1d24e90294f6a6755b137fcf306851e93 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 25 Jul 2023 01:53:28 +0100 -Subject: [PATCH 104/250] net: ethernet: mtk_eth_soc: convert clock bitmap to - u64 - -The to-be-added MT7988 SoC adds many new clocks which need to be -controlled by the Ethernet driver, which will result in their total -number exceeding 32. -Prepare by converting clock bitmaps into 64-bit types. - -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/6960a39bb0078cf84d7642a9558e6a91c6cc9df3.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 96 +++++++++++---------- - 1 file changed, 49 insertions(+), 47 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -663,54 +663,56 @@ enum mtk_clks_map { - MTK_CLK_MAX - }; - --#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \ -- BIT(MTK_CLK_TRGPLL)) --#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_GP2) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK) | \ -- BIT(MTK_CLK_ETH2PLL)) -+#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_TRGPLL)) -+#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK) | \ -+ BIT_ULL(MTK_CLK_ETH2PLL)) - #define MT7621_CLKS_BITMAP (0) - #define MT7628_CLKS_BITMAP (0) --#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK) | \ -- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) --#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_WOCPU0) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK)) --#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB)) -+#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK) | \ -+ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP)) -+#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK)) -+#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB)) - - enum mtk_dev_state { - MTK_HW_INIT, -@@ -1043,7 +1045,7 @@ struct mtk_soc_data { - const struct mtk_reg_map *reg_map; - u32 ana_rgc3; - u64 caps; -- u32 required_clks; -+ u64 required_clks; - bool required_pctl; - u8 offload_version; - u8 hash_offset; diff --git a/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch b/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch deleted file mode 100644 index 58b9cec626a3f5..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch +++ /dev/null @@ -1,477 +0,0 @@ -From 94f825a7eadfc8b4c8828efdb7705d9703f9c73e Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:57:42 +0100 -Subject: [PATCH 105/250] net: ethernet: mtk_eth_soc: add basic support for - MT7988 SoC - -Introduce support for ethernet chip available in MT7988 SoC to -mtk_eth_soc driver. As a first step support only the first GMAC which -is hard-wired to the internal DSA switch having 4 built-in gigabit -Ethernet PHYs. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/25c8377095b95d186872eeda7aa055da83e8f0ca.1690246605.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 201 +++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 86 +++++++- - 3 files changed, 273 insertions(+), 28 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -43,7 +43,7 @@ static const char *mtk_eth_path_name(u64 - static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path) - { - bool updated = true; -- u32 val, mask, set; -+ u32 mask, set, reg; - - switch (path) { - case MTK_ETH_PATH_GMAC1_SGMII: -@@ -59,11 +59,13 @@ static int set_mux_gdm1_to_gmac1_esw(str - break; - } - -- if (updated) { -- val = mtk_r32(eth, MTK_MAC_MISC); -- val = (val & mask) | set; -- mtk_w32(eth, val, MTK_MAC_MISC); -- } -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ reg = MTK_MAC_MISC_V3; -+ else -+ reg = MTK_MAC_MISC; -+ -+ if (updated) -+ mtk_m32(eth, mask, set, reg); - - dev_dbg(eth->dev, "path %s in %s updated = %d\n", - mtk_eth_path_name(path), __func__, updated); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r - .pse_oq_sta = 0x01a0, - }; - -+static const struct mtk_reg_map mt7988_reg_map = { -+ .tx_irq_mask = 0x461c, -+ .tx_irq_status = 0x4618, -+ .pdma = { -+ .rx_ptr = 0x6900, -+ .rx_cnt_cfg = 0x6904, -+ .pcrx_ptr = 0x6908, -+ .glo_cfg = 0x6a04, -+ .rst_idx = 0x6a08, -+ .delay_irq = 0x6a0c, -+ .irq_status = 0x6a20, -+ .irq_mask = 0x6a28, -+ .adma_rx_dbg0 = 0x6a38, -+ .int_grp = 0x6a50, -+ }, -+ .qdma = { -+ .qtx_cfg = 0x4400, -+ .qtx_sch = 0x4404, -+ .rx_ptr = 0x4500, -+ .rx_cnt_cfg = 0x4504, -+ .qcrx_ptr = 0x4508, -+ .glo_cfg = 0x4604, -+ .rst_idx = 0x4608, -+ .delay_irq = 0x460c, -+ .fc_th = 0x4610, -+ .int_grp = 0x4620, -+ .hred = 0x4644, -+ .ctx_ptr = 0x4700, -+ .dtx_ptr = 0x4704, -+ .crx_ptr = 0x4710, -+ .drx_ptr = 0x4714, -+ .fq_head = 0x4720, -+ .fq_tail = 0x4724, -+ .fq_count = 0x4728, -+ .fq_blen = 0x472c, -+ .tx_sch_rate = 0x4798, -+ }, -+ .gdm1_cnt = 0x1c00, -+ .gdma_to_ppe0 = 0x3333, -+ .ppe_base = 0x2000, -+ .wdma_base = { -+ [0] = 0x4800, -+ [1] = 0x4c00, -+ }, -+ .pse_iq_sta = 0x0180, -+ .pse_oq_sta = 0x01a0, -+}; -+ - /* strings used by ethtool */ - static const struct mtk_ethtool_stats { - char str[ETH_GSTRING_LEN]; -@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats { - }; - - static const char * const mtk_clks_source_name[] = { -- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll", -- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb", -- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb", -- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1" -+ "ethif", -+ "sgmiitop", -+ "esw", -+ "gp0", -+ "gp1", -+ "gp2", -+ "gp3", -+ "xgp1", -+ "xgp2", -+ "xgp3", -+ "crypto", -+ "fe", -+ "trgpll", -+ "sgmii_tx250m", -+ "sgmii_rx250m", -+ "sgmii_cdr_ref", -+ "sgmii_cdr_fb", -+ "sgmii2_tx250m", -+ "sgmii2_rx250m", -+ "sgmii2_cdr_ref", -+ "sgmii2_cdr_fb", -+ "sgmii_ck", -+ "eth2pll", -+ "wocpu0", -+ "wocpu1", -+ "netsys0", -+ "netsys1", -+ "ethwarp_wocpu2", -+ "ethwarp_wocpu1", -+ "ethwarp_wocpu0", -+ "top_usxgmii0_sel", -+ "top_usxgmii1_sel", -+ "top_sgm0_sel", -+ "top_sgm1_sel", -+ "top_xfi_phy0_xtal_sel", -+ "top_xfi_phy1_xtal_sel", -+ "top_eth_gmii_sel", -+ "top_eth_refck_50m_sel", -+ "top_eth_sys_200m_sel", -+ "top_eth_sys_sel", -+ "top_eth_xgmii_sel", -+ "top_eth_mii_sel", -+ "top_netsys_sel", -+ "top_netsys_500m_sel", -+ "top_netsys_pao_2x_sel", -+ "top_netsys_sync_250m_sel", -+ "top_netsys_ppefb_250m_sel", -+ "top_netsys_warp_sel", - }; - - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg) -@@ -195,7 +287,7 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne - return __raw_readl(eth->base + reg); - } - --static u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg) -+u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg) - { - u32 val; - -@@ -326,6 +418,19 @@ static void mtk_gmac0_rgmii_adjust(struc - dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n"); - } - -+static void mtk_setup_bridge_switch(struct mtk_eth *eth) -+{ -+ /* Force Port1 XGMAC Link Up */ -+ mtk_m32(eth, 0, MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID), -+ MTK_XGMAC_STS(MTK_GMAC1_ID)); -+ -+ /* Adjust GSW bridge IPG to 11 */ -+ mtk_m32(eth, GSWTX_IPG_MASK | GSWRX_IPG_MASK, -+ (GSW_IPG_11 << GSWTX_IPG_SHIFT) | -+ (GSW_IPG_11 << GSWRX_IPG_SHIFT), -+ MTK_GSW_CFG); -+} -+ - static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, - phy_interface_t interface) - { -@@ -395,6 +500,8 @@ static void mtk_mac_config(struct phylin - goto init_err; - } - break; -+ case PHY_INTERFACE_MODE_INTERNAL: -+ break; - default: - goto err_phy; - } -@@ -472,6 +579,15 @@ static void mtk_mac_config(struct phylin - return; - } - -+ /* Setup gmac */ -+ if (mtk_is_netsys_v3_or_greater(eth) && -+ mac->interface == PHY_INTERFACE_MODE_INTERNAL) { -+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); -+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); -+ -+ mtk_setup_bridge_switch(eth); -+ } -+ - return; - - err_phy: -@@ -681,11 +797,15 @@ static int mtk_mdio_init(struct mtk_eth - } - divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63); - -+ /* Configure MDC Turbo Mode */ -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3); -+ - /* Configure MDC Divider */ -- val = mtk_r32(eth, MTK_PPSC); -- val &= ~PPSC_MDC_CFG; -- val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO; -- mtk_w32(eth, val, MTK_PPSC); -+ val = FIELD_PREP(PPSC_MDC_CFG, divider); -+ if (!mtk_is_netsys_v3_or_greater(eth)) -+ val |= PPSC_MDC_TURBO; -+ mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC); - - dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider); - -@@ -1144,10 +1264,19 @@ static void mtk_tx_set_dma_desc_v2(struc - data |= TX_DMA_LS0; - WRITE_ONCE(desc->txd3, data); - -- if (mac->id == MTK_GMAC3_ID) -- data = PSE_GDM3_PORT; -- else -- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ -+ /* set forward port */ -+ switch (mac->id) { -+ case MTK_GMAC1_ID: -+ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ case MTK_GMAC2_ID: -+ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ case MTK_GMAC3_ID: -+ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ } -+ - data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); - WRITE_ONCE(desc->txd4, data); - -@@ -4306,6 +4435,17 @@ static int mtk_add_mac(struct mtk_eth *e - mac->phylink_config.supported_interfaces); - } - -+ if (mtk_is_netsys_v3_or_greater(mac->hw) && -+ MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW_BIT) && -+ id == MTK_GMAC1_ID) { -+ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | -+ MAC_SYM_PAUSE | -+ MAC_10000FD; -+ phy_interface_zero(mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ mac->phylink_config.supported_interfaces); -+ } -+ - phylink = phylink_create(&mac->phylink_config, - of_fwnode_handle(mac->of_node), - phy_mode, &mtk_phylink_ops); -@@ -4828,6 +4968,24 @@ static const struct mtk_soc_data mt7986_ - }, - }; - -+static const struct mtk_soc_data mt7988_data = { -+ .reg_map = &mt7988_reg_map, -+ .ana_rgc3 = 0x128, -+ .caps = MT7988_CAPS, -+ .hw_features = MTK_HW_FEATURES, -+ .required_clks = MT7988_CLKS_BITMAP, -+ .required_pctl = false, -+ .version = 3, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma_v2), -+ .rxd_size = sizeof(struct mtk_rx_dma_v2), -+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, -+ .dma_len_offset = 8, -+ }, -+}; -+ - static const struct mtk_soc_data rt5350_data = { - .reg_map = &mt7628_reg_map, - .caps = MT7628_CAPS, -@@ -4846,14 +5004,15 @@ static const struct mtk_soc_data rt5350_ - }; - - const struct of_device_id of_mtk_match[] = { -- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data}, -- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data}, -- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, -- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, -- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, -- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data}, -- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, -- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, -+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data }, -+ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data }, -+ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data }, -+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data }, -+ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data }, -+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data }, -+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data }, -+ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data }, -+ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data }, - {}, - }; - MODULE_DEVICE_TABLE(of, of_mtk_match); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -117,7 +117,8 @@ - #define MTK_CDMP_EG_CTRL 0x404 - - /* GDM Exgress Control Register */ --#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000)) -+#define MTK_GDMA_FWD_CFG(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ -+ 0x540 : 0x500 + (_x * 0x1000); }) - #define MTK_GDMA_SPECIAL_TAG BIT(24) - #define MTK_GDMA_ICS_EN BIT(22) - #define MTK_GDMA_TCS_EN BIT(21) -@@ -126,6 +127,11 @@ - #define MTK_GDMA_TO_PDMA 0x0 - #define MTK_GDMA_DROP_ALL 0x7777 - -+/* GDM Egress Control Register */ -+#define MTK_GDMA_EG_CTRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ -+ 0x544 : 0x504 + (_x * 0x1000); }) -+#define MTK_GDMA_XGDM_SEL BIT(31) -+ - /* Unicast Filter MAC Address Register - Low */ - #define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) - -@@ -386,7 +392,26 @@ - #define PHY_IAC_TIMEOUT HZ - - #define MTK_MAC_MISC 0x1000c -+#define MTK_MAC_MISC_V3 0x10010 - #define MTK_MUX_TO_ESW BIT(0) -+#define MISC_MDC_TURBO BIT(4) -+ -+/* XMAC status registers */ -+#define MTK_XGMAC_STS(x) (((x) == MTK_GMAC3_ID) ? 0x1001C : 0x1000C) -+#define MTK_XGMAC_FORCE_LINK(x) (((x) == MTK_GMAC2_ID) ? BIT(31) : BIT(15)) -+#define MTK_USXGMII_PCS_LINK BIT(8) -+#define MTK_XGMAC_RX_FC BIT(5) -+#define MTK_XGMAC_TX_FC BIT(4) -+#define MTK_USXGMII_PCS_MODE GENMASK(3, 1) -+#define MTK_XGMAC_LINK_STS BIT(0) -+ -+/* GSW bridge registers */ -+#define MTK_GSW_CFG (0x10080) -+#define GSWTX_IPG_MASK GENMASK(19, 16) -+#define GSWTX_IPG_SHIFT 16 -+#define GSWRX_IPG_MASK GENMASK(3, 0) -+#define GSWRX_IPG_SHIFT 0 -+#define GSW_IPG_11 11 - - /* Mac control registers */ - #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100)) -@@ -644,6 +669,11 @@ enum mtk_clks_map { - MTK_CLK_GP0, - MTK_CLK_GP1, - MTK_CLK_GP2, -+ MTK_CLK_GP3, -+ MTK_CLK_XGP1, -+ MTK_CLK_XGP2, -+ MTK_CLK_XGP3, -+ MTK_CLK_CRYPTO, - MTK_CLK_FE, - MTK_CLK_TRGPLL, - MTK_CLK_SGMII_TX_250M, -@@ -660,6 +690,27 @@ enum mtk_clks_map { - MTK_CLK_WOCPU1, - MTK_CLK_NETSYS0, - MTK_CLK_NETSYS1, -+ MTK_CLK_ETHWARP_WOCPU2, -+ MTK_CLK_ETHWARP_WOCPU1, -+ MTK_CLK_ETHWARP_WOCPU0, -+ MTK_CLK_TOP_USXGMII_SBUS_0_SEL, -+ MTK_CLK_TOP_USXGMII_SBUS_1_SEL, -+ MTK_CLK_TOP_SGM_0_SEL, -+ MTK_CLK_TOP_SGM_1_SEL, -+ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL, -+ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL, -+ MTK_CLK_TOP_ETH_GMII_SEL, -+ MTK_CLK_TOP_ETH_REFCK_50M_SEL, -+ MTK_CLK_TOP_ETH_SYS_200M_SEL, -+ MTK_CLK_TOP_ETH_SYS_SEL, -+ MTK_CLK_TOP_ETH_XGMII_SEL, -+ MTK_CLK_TOP_ETH_MII_SEL, -+ MTK_CLK_TOP_NETSYS_SEL, -+ MTK_CLK_TOP_NETSYS_500M_SEL, -+ MTK_CLK_TOP_NETSYS_PAO_2X_SEL, -+ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL, -+ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL, -+ MTK_CLK_TOP_NETSYS_WARP_SEL, - MTK_CLK_MAX - }; - -@@ -713,6 +764,36 @@ enum mtk_clks_map { - BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ - BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ - BIT_ULL(MTK_CLK_SGMII2_CDR_FB)) -+#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \ -+ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \ -+ BIT_ULL(MTK_CLK_CRYPTO) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL)) - - enum mtk_dev_state { - MTK_HW_INIT, -@@ -961,6 +1042,8 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_RSTCTRL_PPE1) - -+#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1) -+ - struct mtk_tx_dma_desc_info { - dma_addr_t addr; - u32 size; -@@ -1306,6 +1389,7 @@ void mtk_stats_update_mac(struct mtk_mac - - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); - u32 mtk_r32(struct mtk_eth *eth, unsigned reg); -+u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); diff --git a/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch b/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch deleted file mode 100644 index 95bf60da808f0a..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 38a7eb76220731eff40602cf433f24880be0a6c2 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 27 Jul 2023 09:02:26 +0200 -Subject: [PATCH 106/250] net: ethernet: mtk_eth_soc: enable page_pool support - for MT7988 SoC - -In order to recycle pages, enable page_pool allocator for MT7988 SoC. - -Tested-by: Daniel Golle -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/fd4e8693980e47385a543e7b002eec0b88bd09df.1690440675.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1612,7 +1612,7 @@ static void mtk_update_rx_cpu_idx(struct - - static bool mtk_page_pool_enabled(struct mtk_eth *eth) - { -- return eth->soc->version == 2; -+ return mtk_is_netsys_v2_or_greater(eth); - } - - static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, diff --git a/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch b/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch deleted file mode 100644 index 5205914c4ff0d7..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 199e7d5a7f03dd377f3a7a458360dbedd71d50ba Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 27 Jul 2023 09:07:28 +0200 -Subject: [PATCH 107/250] net: ethernet: mtk_eth_soc: enable nft hw - flowtable_offload for MT7988 SoC - -Enable hw Packet Process Engine (PPE) for MT7988 SoC. - -Tested-by: Daniel Golle -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/5e86341b0220a49620dadc02d77970de5ded9efc.1690441576.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++ - drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++---- - drivers/net/ethernet/mediatek/mtk_ppe.h | 19 ++++++++++++++++++- - 3 files changed, 36 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4976,6 +4976,9 @@ static const struct mtk_soc_data mt7988_ - .required_clks = MT7988_CLKS_BITMAP, - .required_pctl = false, - .version = 3, -+ .offload_version = 2, -+ .hash_offset = 4, -+ .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -422,13 +422,22 @@ int mtk_foe_entry_set_wdma(struct mtk_et - struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - u32 *ib2 = mtk_foe_entry_ib2(eth, entry); - -- if (mtk_is_netsys_v2_or_greater(eth)) { -+ switch (eth->soc->version) { -+ case 3: -+ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; -+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | -+ MTK_FOE_IB2_WDMA_WINFO_V2; -+ l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) | -+ FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss); -+ break; -+ case 2: - *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; - *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | - MTK_FOE_IB2_WDMA_WINFO_V2; - l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) | - FIELD_PREP(MTK_FOE_WINFO_BSS, bss); -- } else { -+ break; -+ default: - *ib2 &= ~MTK_FOE_IB2_PORT_MG; - *ib2 |= MTK_FOE_IB2_WDMA_WINFO; - if (wdma_idx) -@@ -436,6 +445,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et - l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | - FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | - FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); -+ break; - } - - return 0; -@@ -956,8 +966,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - mtk_ppe_init_foe_table(ppe); - ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys); - -- val = MTK_PPE_TB_CFG_ENTRY_80B | -- MTK_PPE_TB_CFG_AGE_NON_L4 | -+ val = MTK_PPE_TB_CFG_AGE_NON_L4 | - MTK_PPE_TB_CFG_AGE_UNBIND | - MTK_PPE_TB_CFG_AGE_TCP | - MTK_PPE_TB_CFG_AGE_UDP | -@@ -973,6 +982,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_ENTRIES_SHIFT); - if (mtk_is_netsys_v2_or_greater(ppe->eth)) - val |= MTK_PPE_TB_CFG_INFO_SEL; -+ if (!mtk_is_netsys_v3_or_greater(ppe->eth)) -+ val |= MTK_PPE_TB_CFG_ENTRY_80B; - ppe_w32(ppe, MTK_PPE_TB_CFG, val); - - ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK, ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -85,6 +85,17 @@ enum { - #define MTK_FOE_WINFO_BSS GENMASK(5, 0) - #define MTK_FOE_WINFO_WCID GENMASK(15, 6) - -+#define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16) -+#define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0) -+ -+#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0) -+#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16) -+#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20) -+#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21) -+#define MTK_FOE_WINFO_PAO_IS_SP BIT(22) -+#define MTK_FOE_WINFO_PAO_HF BIT(23) -+#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24) -+ - enum { - MTK_FOE_STATE_INVALID, - MTK_FOE_STATE_UNBIND, -@@ -106,8 +117,13 @@ struct mtk_foe_mac_info { - u16 pppoe_id; - u16 src_mac_lo; - -+ /* netsys_v2 */ - u16 minfo; - u16 winfo; -+ -+ /* netsys_v3 */ -+ u32 w3info; -+ u32 wpao; - }; - - /* software-only entry type */ -@@ -218,6 +234,7 @@ struct mtk_foe_ipv6_6rd { - - #define MTK_FOE_ENTRY_V1_SIZE 80 - #define MTK_FOE_ENTRY_V2_SIZE 96 -+#define MTK_FOE_ENTRY_V3_SIZE 128 - - struct mtk_foe_entry { - u32 ib1; -@@ -228,7 +245,7 @@ struct mtk_foe_entry { - struct mtk_foe_ipv4_dslite dslite; - struct mtk_foe_ipv6 ipv6; - struct mtk_foe_ipv6_6rd ipv6_6rd; -- u32 data[23]; -+ u32 data[31]; - }; - }; - diff --git a/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch b/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch deleted file mode 100644 index 8a48976126a945..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0c024632c1e7ff69914329bfd87bec749b9c0aed Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 2 Aug 2023 04:31:09 +0100 -Subject: [PATCH 108/250] net: ethernet: mtk_eth_soc: support per-flow - accounting on MT7988 - -NETSYS_V3 uses 64 bits for each counters while older SoCs are using -48/40 bits for each counter. -Support reading per-flow byte and package counters on NETSYS_V3. - -Signed-off-by: Daniel Golle -Reviewed-by: Simon Horman -Link: https://lore.kernel.org/r/37a0928fa8c1253b197884c68ce1f54239421ac5.1690946442.git.daniel@makrotopia.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + - drivers/net/ethernet/mediatek/mtk_ppe.c | 21 +++++++++++++------- - drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 2 ++ - 3 files changed, 17 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4978,6 +4978,7 @@ static const struct mtk_soc_data mt7988_ - .version = 3, - .offload_version = 2, - .hash_offset = 4, -+ .has_accounting = true, - .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -91,7 +91,6 @@ static int mtk_ppe_mib_wait_busy(struct - - static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) - { -- u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high; - u32 val, cnt_r0, cnt_r1, cnt_r2; - int ret; - -@@ -106,12 +105,20 @@ static int mtk_mib_entry_read(struct mtk - cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); - cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2); - -- byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); -- byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); -- pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); -- pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; -+ if (mtk_is_netsys_v3_or_greater(ppe->eth)) { -+ /* 64 bit for each counter */ -+ u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3); -+ *bytes = ((u64)cnt_r1 << 32) | cnt_r0; -+ *packets = ((u64)cnt_r3 << 32) | cnt_r2; -+ } else { -+ /* 48 bit byte counter, 40 bit packet counter */ -+ u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); -+ u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); -+ u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); -+ u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -+ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -+ *packets = (pkt_cnt_high << 16) | pkt_cnt_low; -+ } - - return 0; - } ---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -@@ -163,6 +163,8 @@ enum { - #define MTK_PPE_MIB_SER_R2 0x348 - #define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0) - -+#define MTK_PPE_MIB_SER_R3 0x34c -+ - #define MTK_PPE_MIB_CACHE_CTL 0x350 - #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) - #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) diff --git a/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch b/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch deleted file mode 100644 index 6f1639a5720abc..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 3b12f42772c26869d60398c1710aa27b27cd945c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 21 Aug 2023 17:12:44 +0100 -Subject: [PATCH 109/250] net: ethernet: mtk_eth_soc: fix NULL pointer on hw - reset - -When a hardware reset is triggered on devices not initializing WED the -calls to mtk_wed_fe_reset and mtk_wed_fe_reset_complete dereference a -pointer on uninitialized stack memory. -Break out of both functions in case a hw_list entry is 0. - -Fixes: 08a764a7c51b ("net: ethernet: mtk_wed: add reset/reset_complete callbacks") -Signed-off-by: Daniel Golle -Reviewed-by: Simon Horman -Acked-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/5465c1609b464cc7407ae1530c40821dcdf9d3e6.1692634266.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -214,9 +214,13 @@ void mtk_wed_fe_reset(void) - - for (i = 0; i < ARRAY_SIZE(hw_list); i++) { - struct mtk_wed_hw *hw = hw_list[i]; -- struct mtk_wed_device *dev = hw->wed_dev; -+ struct mtk_wed_device *dev; - int err; - -+ if (!hw) -+ break; -+ -+ dev = hw->wed_dev; - if (!dev || !dev->wlan.reset) - continue; - -@@ -237,8 +241,12 @@ void mtk_wed_fe_reset_complete(void) - - for (i = 0; i < ARRAY_SIZE(hw_list); i++) { - struct mtk_wed_hw *hw = hw_list[i]; -- struct mtk_wed_device *dev = hw->wed_dev; -+ struct mtk_wed_device *dev; -+ -+ if (!hw) -+ break; - -+ dev = hw->wed_dev; - if (!dev || !dev->wlan.reset_complete) - continue; - diff --git a/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch b/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch deleted file mode 100644 index 35977946d369e6..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 489aea123d74a846ce746bfdb3efe1e7ad512e0d Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 22 Aug 2023 17:31:24 +0100 -Subject: [PATCH 110/250] net: ethernet: mtk_eth_soc: fix register definitions - for MT7988 - -More register macros need to be adjusted for the 3rd GMAC on MT7988. -Account for added bit in SYSCFG0_SGMII_MASK. - -Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC") -Signed-off-by: Daniel Golle -Reviewed-by: Simon Horman -Link: https://lore.kernel.org/r/1c8da012e2ca80939906d85f314138c552139f0f.1692721443.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -133,10 +133,12 @@ - #define MTK_GDMA_XGDM_SEL BIT(31) - - /* Unicast Filter MAC Address Register - Low */ --#define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) -+#define MTK_GDMA_MAC_ADRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ -+ 0x548 : 0x508 + (_x * 0x1000); }) - - /* Unicast Filter MAC Address Register - High */ --#define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000)) -+#define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ -+ 0x54C : 0x50C + (_x * 0x1000); }) - - /* FE global misc reg*/ - #define MTK_FE_GLO_MISC 0x124 -@@ -500,7 +502,7 @@ - #define ETHSYS_SYSCFG0 0x14 - #define SYSCFG0_GE_MASK 0x3 - #define SYSCFG0_GE_MODE(x, y) (x << (12 + (y * 2))) --#define SYSCFG0_SGMII_MASK GENMASK(9, 8) -+#define SYSCFG0_SGMII_MASK GENMASK(9, 7) - #define SYSCFG0_SGMII_GMAC1 ((2 << 8) & SYSCFG0_SGMII_MASK) - #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) - #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) diff --git a/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch b/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch deleted file mode 100644 index 963807aa45455c..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 15a84d1c44ae8c1451c265ee60500588a24e8cd6 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 22 Aug 2023 17:32:03 +0100 -Subject: [PATCH 111/250] net: ethernet: mtk_eth_soc: add reset bits for MT7988 - -Add bits needed to reset the frame engine on MT7988. - -Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC") -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/89b6c38380e7a3800c1362aa7575600717bc7543.1692721443.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 76 +++++++++++++++------ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++-- - 2 files changed, 68 insertions(+), 24 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3540,19 +3540,34 @@ static void mtk_hw_reset(struct mtk_eth - { - u32 val; - -- if (mtk_is_netsys_v2_or_greater(eth)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); -+ -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ val = RSTCTRL_PPE0_V3; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= RSTCTRL_PPE1_V3; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) -+ val |= RSTCTRL_PPE2; -+ -+ val |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2; -+ } else if (mtk_is_netsys_v2_or_greater(eth)) { - val = RSTCTRL_PPE0_V2; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= RSTCTRL_PPE1; - } else { - val = RSTCTRL_PPE0; - } - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- val |= RSTCTRL_PPE1; -- - ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); - -- if (mtk_is_netsys_v2_or_greater(eth)) -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, -+ 0x6f8ff); -+ else if (mtk_is_netsys_v2_or_greater(eth)) - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, - 0x3ffffff); - } -@@ -3578,13 +3593,21 @@ static void mtk_hw_warm_reset(struct mtk - return; - } - -- if (mtk_is_netsys_v2_or_greater(eth)) -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V3; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ rst_mask |= RSTCTRL_PPE1_V3; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) -+ rst_mask |= RSTCTRL_PPE2; -+ -+ rst_mask |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2; -+ } else if (mtk_is_netsys_v2_or_greater(eth)) { - rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; -- else -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ rst_mask |= RSTCTRL_PPE1; -+ } else { - rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; -- -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- rst_mask |= RSTCTRL_PPE1; -+ } - - regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask); - -@@ -3936,11 +3959,17 @@ static void mtk_prepare_for_reset(struct - u32 val; - int i; - -- /* disabe FE P3 and P4 */ -- val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3; -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- val |= MTK_FE_LINK_DOWN_P4; -- mtk_w32(eth, val, MTK_FE_GLO_CFG); -+ /* set FE PPE ports link down */ -+ for (i = MTK_GMAC1_ID; -+ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID); -+ i += 2) { -+ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) | MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) -+ val |= MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT); -+ mtk_w32(eth, val, MTK_FE_GLO_CFG(i)); -+ } - - /* adjust PPE configurations to prepare for reset */ - for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) -@@ -4001,11 +4030,18 @@ static void mtk_pending_work(struct work - } - } - -- /* enabe FE P3 and P4 */ -- val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3; -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- val &= ~MTK_FE_LINK_DOWN_P4; -- mtk_w32(eth, val, MTK_FE_GLO_CFG); -+ /* set FE PPE ports link up */ -+ for (i = MTK_GMAC1_ID; -+ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID); -+ i += 2) { -+ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) & ~MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) -+ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT); -+ -+ mtk_w32(eth, val, MTK_FE_GLO_CFG(i)); -+ } - - clear_bit(MTK_RESETTING, ð->state); - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -76,9 +76,8 @@ - #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 - - /* Frame Engine Global Configuration */ --#define MTK_FE_GLO_CFG 0x00 --#define MTK_FE_LINK_DOWN_P3 BIT(11) --#define MTK_FE_LINK_DOWN_P4 BIT(12) -+#define MTK_FE_GLO_CFG(x) (((x) == MTK_GMAC3_ID) ? 0x24 : 0x00) -+#define MTK_FE_LINK_DOWN_P(x) BIT(((x) + 8) % 16) - - /* Frame Engine Global Reset Register */ - #define MTK_RST_GL 0x04 -@@ -519,9 +518,15 @@ - /* ethernet reset control register */ - #define ETHSYS_RSTCTRL 0x34 - #define RSTCTRL_FE BIT(6) -+#define RSTCTRL_WDMA0 BIT(24) -+#define RSTCTRL_WDMA1 BIT(25) -+#define RSTCTRL_WDMA2 BIT(26) - #define RSTCTRL_PPE0 BIT(31) - #define RSTCTRL_PPE0_V2 BIT(30) - #define RSTCTRL_PPE1 BIT(31) -+#define RSTCTRL_PPE0_V3 BIT(29) -+#define RSTCTRL_PPE1_V3 BIT(30) -+#define RSTCTRL_PPE2 BIT(31) - #define RSTCTRL_ETH BIT(23) - - /* ethernet reset check idle register */ -@@ -928,6 +933,7 @@ enum mkt_eth_capabilities { - MTK_QDMA_BIT, - MTK_SOC_MT7628_BIT, - MTK_RSTCTRL_PPE1_BIT, -+ MTK_RSTCTRL_PPE2_BIT, - MTK_U3_COPHY_V2_BIT, - - /* MUX BITS*/ -@@ -962,6 +968,7 @@ enum mkt_eth_capabilities { - #define MTK_QDMA BIT_ULL(MTK_QDMA_BIT) - #define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT) - #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) -+#define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) - #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ -@@ -1044,7 +1051,8 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_RSTCTRL_PPE1) - --#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1) -+#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ -+ MTK_RSTCTRL_PPE2) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; diff --git a/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch b/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch deleted file mode 100644 index e224443e439538..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 25ce45fe40b574e5d7ffa407f7f2db03e7d5a910 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 22 Aug 2023 17:32:54 +0100 -Subject: [PATCH 112/250] net: ethernet: mtk_eth_soc: add support for in-SoC - SRAM - -MT7981, MT7986 and MT7988 come with in-SoC SRAM dedicated for Ethernet -DMA rings. Support using the SRAM without breaking existing device tree -bindings, ie. only new SoC starting from MT7988 will have the SRAM -declared as additional resource in device tree. For MT7981 and MT7986 -an offset on top of the main I/O base is used. - -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/e45e0f230c63ad58869e8fe35b95a2fb8925b625.1692721443.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 88 ++++++++++++++++----- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++- - 2 files changed, 78 insertions(+), 22 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1074,10 +1074,13 @@ static int mtk_init_fq_dma(struct mtk_et - dma_addr_t dma_addr; - int i; - -- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, -- cnt * soc->txrx.txd_size, -- ð->phy_scratch_ring, -- GFP_KERNEL); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) -+ eth->scratch_ring = eth->sram_base; -+ else -+ eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, -+ cnt * soc->txrx.txd_size, -+ ð->phy_scratch_ring, -+ GFP_KERNEL); - if (unlikely(!eth->scratch_ring)) - return -ENOMEM; - -@@ -2375,8 +2378,14 @@ static int mtk_tx_alloc(struct mtk_eth * - if (!ring->buf) - goto no_tx_mem; - -- ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, -- &ring->phys, GFP_KERNEL); -+ if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) { -+ ring->dma = eth->sram_base + ring_size * sz; -+ ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz; -+ } else { -+ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, -+ &ring->phys, GFP_KERNEL); -+ } -+ - if (!ring->dma) - goto no_tx_mem; - -@@ -2475,8 +2484,7 @@ static void mtk_tx_clean(struct mtk_eth - kfree(ring->buf); - ring->buf = NULL; - } -- -- if (ring->dma) { -+ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) { - dma_free_coherent(eth->dma_dev, - ring->dma_size * soc->txrx.txd_size, - ring->dma, ring->phys); -@@ -2495,9 +2503,14 @@ static int mtk_rx_alloc(struct mtk_eth * - { - const struct mtk_reg_map *reg_map = eth->soc->reg_map; - struct mtk_rx_ring *ring; -- int rx_data_len, rx_dma_size; -+ int rx_data_len, rx_dma_size, tx_ring_size; - int i; - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -+ tx_ring_size = MTK_QDMA_RING_SIZE; -+ else -+ tx_ring_size = MTK_DMA_SIZE; -+ - if (rx_flag == MTK_RX_FLAGS_QDMA) { - if (ring_no) - return -EINVAL; -@@ -2532,9 +2545,20 @@ static int mtk_rx_alloc(struct mtk_eth * - ring->page_pool = pp; - } - -- ring->dma = dma_alloc_coherent(eth->dma_dev, -- rx_dma_size * eth->soc->txrx.rxd_size, -- &ring->phys, GFP_KERNEL); -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) || -+ rx_flag != MTK_RX_FLAGS_NORMAL) { -+ ring->dma = dma_alloc_coherent(eth->dma_dev, -+ rx_dma_size * eth->soc->txrx.rxd_size, -+ &ring->phys, GFP_KERNEL); -+ } else { -+ struct mtk_tx_ring *tx_ring = ð->tx_ring; -+ -+ ring->dma = tx_ring->dma + tx_ring_size * -+ eth->soc->txrx.txd_size * (ring_no + 1); -+ ring->phys = tx_ring->phys + tx_ring_size * -+ eth->soc->txrx.txd_size * (ring_no + 1); -+ } -+ - if (!ring->dma) - return -ENOMEM; - -@@ -2617,7 +2641,7 @@ static int mtk_rx_alloc(struct mtk_eth * - return 0; - } - --static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring) -+static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram) - { - int i; - -@@ -2640,7 +2664,7 @@ static void mtk_rx_clean(struct mtk_eth - ring->data = NULL; - } - -- if (ring->dma) { -+ if (!in_sram && ring->dma) { - dma_free_coherent(eth->dma_dev, - ring->dma_size * eth->soc->txrx.rxd_size, - ring->dma, ring->phys); -@@ -3003,7 +3027,7 @@ static void mtk_dma_free(struct mtk_eth - for (i = 0; i < MTK_MAX_DEVS; i++) - if (eth->netdev[i]) - netdev_reset_queue(eth->netdev[i]); -- if (eth->scratch_ring) { -+ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) { - dma_free_coherent(eth->dma_dev, - MTK_QDMA_RING_SIZE * soc->txrx.txd_size, - eth->scratch_ring, eth->phy_scratch_ring); -@@ -3011,13 +3035,13 @@ static void mtk_dma_free(struct mtk_eth - eth->phy_scratch_ring = 0; - } - mtk_tx_clean(eth); -- mtk_rx_clean(eth, ð->rx_ring[0]); -- mtk_rx_clean(eth, ð->rx_ring_qdma); -+ mtk_rx_clean(eth, ð->rx_ring[0], MTK_HAS_CAPS(soc->caps, MTK_SRAM)); -+ mtk_rx_clean(eth, ð->rx_ring_qdma, false); - - if (eth->hwlro) { - mtk_hwlro_rx_uninit(eth); - for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) -- mtk_rx_clean(eth, ð->rx_ring[i]); -+ mtk_rx_clean(eth, ð->rx_ring[i], false); - } - - kfree(eth->scratch_head); -@@ -4587,7 +4611,7 @@ static int mtk_sgmii_init(struct mtk_eth - - static int mtk_probe(struct platform_device *pdev) - { -- struct resource *res = NULL; -+ struct resource *res = NULL, *res_sram; - struct device_node *mac_np; - struct mtk_eth *eth; - int err, i; -@@ -4607,6 +4631,20 @@ static int mtk_probe(struct platform_dev - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - eth->ip_align = NET_IP_ALIGN; - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) { -+ /* SRAM is actual memory and supports transparent access just like DRAM. -+ * Hence we don't require __iomem being set and don't need to use accessor -+ * functions to read from or write to SRAM. -+ */ -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ eth->sram_base = (void __force *)devm_platform_ioremap_resource(pdev, 1); -+ if (IS_ERR(eth->sram_base)) -+ return PTR_ERR(eth->sram_base); -+ } else { -+ eth->sram_base = (void __force *)eth->base + MTK_ETH_SRAM_OFFSET; -+ } -+ } -+ - spin_lock_init(ð->page_lock); - spin_lock_init(ð->tx_irq_lock); - spin_lock_init(ð->rx_irq_lock); -@@ -4670,6 +4708,18 @@ static int mtk_probe(struct platform_dev - err = -EINVAL; - goto err_destroy_sgmii; - } -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) { -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ res_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (!res_sram) { -+ err = -EINVAL; -+ goto err_destroy_sgmii; -+ } -+ eth->phy_scratch_ring = res_sram->start; -+ } else { -+ eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET; -+ } -+ } - } - - if (eth->soc->offload_version) { ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -139,6 +139,9 @@ - #define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ - 0x54C : 0x50C + (_x * 0x1000); }) - -+/* Internal SRAM offset */ -+#define MTK_ETH_SRAM_OFFSET 0x40000 -+ - /* FE global misc reg*/ - #define MTK_FE_GLO_MISC 0x124 - -@@ -935,6 +938,7 @@ enum mkt_eth_capabilities { - MTK_RSTCTRL_PPE1_BIT, - MTK_RSTCTRL_PPE2_BIT, - MTK_U3_COPHY_V2_BIT, -+ MTK_SRAM_BIT, - - /* MUX BITS*/ - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, -@@ -970,6 +974,7 @@ enum mkt_eth_capabilities { - #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) - #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) - #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) -+#define MTK_SRAM BIT_ULL(MTK_SRAM_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ - BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -@@ -1045,14 +1050,14 @@ enum mkt_eth_capabilities { - #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ -- MTK_RSTCTRL_PPE1) -+ MTK_RSTCTRL_PPE1 | MTK_SRAM) - - #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ -- MTK_RSTCTRL_PPE1) -+ MTK_RSTCTRL_PPE1 | MTK_SRAM) - - #define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ -- MTK_RSTCTRL_PPE2) -+ MTK_RSTCTRL_PPE2 | MTK_SRAM) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1212,6 +1217,7 @@ struct mtk_eth { - struct device *dev; - struct device *dma_dev; - void __iomem *base; -+ void *sram_base; - spinlock_t page_lock; - spinlock_t tx_irq_lock; - spinlock_t rx_irq_lock; diff --git a/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch b/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch deleted file mode 100644 index 528f9a3e5c6ebc..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 0b0d606eb9650fa01dd5621e072aa29a10544399 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 22 Aug 2023 17:33:12 +0100 -Subject: [PATCH 113/250] net: ethernet: mtk_eth_soc: support 36-bit DMA - addressing on MT7988 - -Systems having 4 GiB of RAM and more require DMA addressing beyond the -current 32-bit limit. Starting from MT7988 the hardware now supports -36-bit DMA addressing, let's use that new capability in the driver to -avoid running into swiotlb on systems with 4 GiB of RAM or more. - -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/95b919c98876c9e49761e44662e7c937479eecb8.1692721443.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 22 +++++++++++++-- - 2 files changed, 48 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1265,6 +1265,10 @@ static void mtk_tx_set_dma_desc_v2(struc - data = TX_DMA_PLEN0(info->size); - if (info->last) - data |= TX_DMA_LS0; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ data |= TX_DMA_PREP_ADDR64(info->addr); -+ - WRITE_ONCE(desc->txd3, data); - - /* set forward port */ -@@ -1932,6 +1936,7 @@ static int mtk_poll_rx(struct napi_struc - bool xdp_flush = false; - int idx; - struct sk_buff *skb; -+ u64 addr64 = 0; - u8 *data, *new_data; - struct mtk_rx_dma_v2 *rxd, trxd; - int done = 0, bytes = 0; -@@ -2047,7 +2052,10 @@ static int mtk_poll_rx(struct napi_struc - goto release_desc; - } - -- dma_unmap_single(eth->dma_dev, trxd.rxd1, -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ addr64 = RX_DMA_GET_ADDR64(trxd.rxd2); -+ -+ dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64), - ring->buf_size, DMA_FROM_DEVICE); - - skb = build_skb(data, ring->frag_size); -@@ -2113,6 +2121,9 @@ release_desc: - else - rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); -+ - ring->calc_idx = idx; - done++; - } -@@ -2597,6 +2608,9 @@ static int mtk_rx_alloc(struct mtk_eth * - else - rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); -+ - rxd->rxd3 = 0; - rxd->rxd4 = 0; - if (mtk_is_netsys_v2_or_greater(eth)) { -@@ -2643,6 +2657,7 @@ static int mtk_rx_alloc(struct mtk_eth * - - static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram) - { -+ u64 addr64 = 0; - int i; - - if (ring->data && ring->dma) { -@@ -2656,7 +2671,10 @@ static void mtk_rx_clean(struct mtk_eth - if (!rxd->rxd1) - continue; - -- dma_unmap_single(eth->dma_dev, rxd->rxd1, -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ addr64 = RX_DMA_GET_ADDR64(rxd->rxd2); -+ -+ dma_unmap_single(eth->dma_dev, ((u64)rxd->rxd1 | addr64), - ring->buf_size, DMA_FROM_DEVICE); - mtk_rx_put_buff(ring, ring->data[i], false); - } -@@ -4645,6 +4663,14 @@ static int mtk_probe(struct platform_dev - } - } - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { -+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); -+ if (err) { -+ dev_err(&pdev->dev, "Wrong DMA config\n"); -+ return -EINVAL; -+ } -+ } -+ - spin_lock_init(ð->page_lock); - spin_lock_init(ð->tx_irq_lock); - spin_lock_init(ð->rx_irq_lock); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -331,6 +331,14 @@ - #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) - #define TX_DMA_SWC BIT(14) - #define TX_DMA_PQID GENMASK(3, 0) -+#define TX_DMA_ADDR64_MASK GENMASK(3, 0) -+#if IS_ENABLED(CONFIG_64BIT) -+# define TX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(TX_DMA_ADDR64_MASK, (x))) << 32) -+# define TX_DMA_PREP_ADDR64(x) FIELD_PREP(TX_DMA_ADDR64_MASK, ((x) >> 32)) -+#else -+# define TX_DMA_GET_ADDR64(x) (0) -+# define TX_DMA_PREP_ADDR64(x) (0) -+#endif - - /* PDMA on MT7628 */ - #define TX_DMA_DONE BIT(31) -@@ -343,6 +351,14 @@ - #define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) - #define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len) - #define RX_DMA_VTAG BIT(15) -+#define RX_DMA_ADDR64_MASK GENMASK(3, 0) -+#if IS_ENABLED(CONFIG_64BIT) -+# define RX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(RX_DMA_ADDR64_MASK, (x))) << 32) -+# define RX_DMA_PREP_ADDR64(x) FIELD_PREP(RX_DMA_ADDR64_MASK, ((x) >> 32)) -+#else -+# define RX_DMA_GET_ADDR64(x) (0) -+# define RX_DMA_PREP_ADDR64(x) (0) -+#endif - - /* QDMA descriptor rxd3 */ - #define RX_DMA_VID(x) ((x) & VLAN_VID_MASK) -@@ -939,6 +955,7 @@ enum mkt_eth_capabilities { - MTK_RSTCTRL_PPE2_BIT, - MTK_U3_COPHY_V2_BIT, - MTK_SRAM_BIT, -+ MTK_36BIT_DMA_BIT, - - /* MUX BITS*/ - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, -@@ -975,6 +992,7 @@ enum mkt_eth_capabilities { - #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) - #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) - #define MTK_SRAM BIT_ULL(MTK_SRAM_BIT) -+#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ - BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -@@ -1056,8 +1074,8 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_RSTCTRL_PPE1 | MTK_SRAM) - --#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ -- MTK_RSTCTRL_PPE2 | MTK_SRAM) -+#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \ -+ MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; diff --git a/target/linux/generic/backport-5.15/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch b/target/linux/generic/backport-5.15/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch deleted file mode 100644 index 959add1954c98f..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch +++ /dev/null @@ -1,44 +0,0 @@ -From e10a35abb3da12b812cfb6fc6137926a0c81e39a Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 10 Sep 2023 22:40:30 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix uninitialized variable - -Variable dma_addr in function mtk_poll_rx can be uninitialized on -some of the error paths. In practise this doesn't matter, even random -data present in uninitialized stack memory can safely be used in the -way it happens in the error path. - -However, in order to make Smatch happy make sure the variable is -always initialized. - -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1940,11 +1940,11 @@ static int mtk_poll_rx(struct napi_struc - u8 *data, *new_data; - struct mtk_rx_dma_v2 *rxd, trxd; - int done = 0, bytes = 0; -+ dma_addr_t dma_addr = DMA_MAPPING_ERROR; - - while (done < budget) { - unsigned int pktlen, *rxdcsum; - struct net_device *netdev; -- dma_addr_t dma_addr; - u32 hash, reason; - int mac = 0; - -@@ -2121,7 +2121,8 @@ release_desc: - else - rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA) && -+ likely(dma_addr != DMA_MAPPING_ERROR)) - rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); - - ring->calc_idx = idx; diff --git a/target/linux/generic/backport-5.15/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch b/target/linux/generic/backport-5.15/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch deleted file mode 100644 index ac3e3a3e67691a..00000000000000 --- a/target/linux/generic/backport-5.15/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5a124b1fd3e6cb15a943f0cdfe96aa8f6d3d2f39 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 9 Sep 2023 20:41:56 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix pse_port configuration for - MT7988 - -MT7988 SoC support 3 NICs. Fix pse_port configuration in -mtk_flow_set_output_device routine if the traffic is offloaded to eth2. -Rely on mtk_pse_port definitions. - -Fixes: 88efedf517e6 ("net: ethernet: mtk_eth_soc: enable nft hw flowtable_offload for MT7988 SoC") -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -214,9 +214,11 @@ mtk_flow_set_output_device(struct mtk_et - dsa_port = mtk_flow_get_dsa_port(&dev); - - if (dev == eth->netdev[0]) -- pse_port = 1; -+ pse_port = PSE_GDM1_PORT; - else if (dev == eth->netdev[1]) -- pse_port = 2; -+ pse_port = PSE_GDM2_PORT; -+ else if (dev == eth->netdev[2]) -+ pse_port = PSE_GDM3_PORT; - else - return -EOPNOTSUPP; - diff --git a/target/linux/generic/backport-5.15/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch b/target/linux/generic/backport-5.15/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch deleted file mode 100644 index 21d0f045d9f5af..00000000000000 --- a/target/linux/generic/backport-5.15/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch +++ /dev/null @@ -1,271 +0,0 @@ -From: Felix Fietkau -Date: Mon, 20 Mar 2023 11:44:30 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add code for offloading flows - from wlan devices - -WED version 2 (on MT7986 and later) can offload flows originating from wireless -devices. In order to make that work, ndo_setup_tc needs to be implemented on -the netdevs. This adds the required code to offload flows coming in from WED, -while keeping track of the incoming wed index used for selecting the correct -PPE device. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 + - .../net/ethernet/mediatek/mtk_ppe_offload.c | 37 ++++--- - drivers/net/ethernet/mediatek/mtk_wed.c | 101 ++++++++++++++++++ - include/linux/soc/mediatek/mtk_wed.h | 6 ++ - 4 files changed, 133 insertions(+), 14 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1432,6 +1432,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk - int mtk_eth_offload_init(struct mtk_eth *eth); - int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, - void *type_data); -+int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls, -+ int ppe_index); -+void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list); - void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev); - - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -237,7 +237,8 @@ out: - } - - static int --mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f) -+mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f, -+ int ppe_index) - { - struct flow_rule *rule = flow_cls_offload_flow_rule(f); - struct flow_action_entry *act; -@@ -454,6 +455,7 @@ mtk_flow_offload_replace(struct mtk_eth - entry->cookie = f->cookie; - memcpy(&entry->data, &foe, sizeof(entry->data)); - entry->wed_index = wed_index; -+ entry->ppe_index = ppe_index; - - err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry); - if (err < 0) -@@ -522,25 +524,15 @@ mtk_flow_offload_stats(struct mtk_eth *e - - static DEFINE_MUTEX(mtk_flow_offload_mutex); - --static int --mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) -+int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls, -+ int ppe_index) - { -- struct flow_cls_offload *cls = type_data; -- struct net_device *dev = cb_priv; -- struct mtk_mac *mac = netdev_priv(dev); -- struct mtk_eth *eth = mac->hw; - int err; - -- if (!tc_can_offload(dev)) -- return -EOPNOTSUPP; -- -- if (type != TC_SETUP_CLSFLOWER) -- return -EOPNOTSUPP; -- - mutex_lock(&mtk_flow_offload_mutex); - switch (cls->command) { - case FLOW_CLS_REPLACE: -- err = mtk_flow_offload_replace(eth, cls); -+ err = mtk_flow_offload_replace(eth, cls, ppe_index); - break; - case FLOW_CLS_DESTROY: - err = mtk_flow_offload_destroy(eth, cls); -@@ -558,6 +550,23 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_ - } - - static int -+mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) -+{ -+ struct flow_cls_offload *cls = type_data; -+ struct net_device *dev = cb_priv; -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ -+ if (!tc_can_offload(dev)) -+ return -EOPNOTSUPP; -+ -+ if (type != TC_SETUP_CLSFLOWER) -+ return -EOPNOTSUPP; -+ -+ return mtk_flow_offload_cmd(eth, cls, 0); -+} -+ -+static int - mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f) - { - struct mtk_mac *mac = netdev_priv(dev); ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -13,6 +13,8 @@ - #include - #include - #include -+#include -+#include - #include "mtk_eth_soc.h" - #include "mtk_wed_regs.h" - #include "mtk_wed.h" -@@ -41,6 +43,11 @@ - static struct mtk_wed_hw *hw_list[2]; - static DEFINE_MUTEX(hw_lock); - -+struct mtk_wed_flow_block_priv { -+ struct mtk_wed_hw *hw; -+ struct net_device *dev; -+}; -+ - static void - wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) - { -@@ -1753,6 +1760,99 @@ out: - mutex_unlock(&hw_lock); - } - -+static int -+mtk_wed_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) -+{ -+ struct mtk_wed_flow_block_priv *priv = cb_priv; -+ struct flow_cls_offload *cls = type_data; -+ struct mtk_wed_hw *hw = priv->hw; -+ -+ if (!tc_can_offload(priv->dev)) -+ return -EOPNOTSUPP; -+ -+ if (type != TC_SETUP_CLSFLOWER) -+ return -EOPNOTSUPP; -+ -+ return mtk_flow_offload_cmd(hw->eth, cls, hw->index); -+} -+ -+static int -+mtk_wed_setup_tc_block(struct mtk_wed_hw *hw, struct net_device *dev, -+ struct flow_block_offload *f) -+{ -+ struct mtk_wed_flow_block_priv *priv; -+ static LIST_HEAD(block_cb_list); -+ struct flow_block_cb *block_cb; -+ struct mtk_eth *eth = hw->eth; -+ flow_setup_cb_t *cb; -+ -+ if (!eth->soc->offload_version) -+ return -EOPNOTSUPP; -+ -+ if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) -+ return -EOPNOTSUPP; -+ -+ cb = mtk_wed_setup_tc_block_cb; -+ f->driver_block_list = &block_cb_list; -+ -+ switch (f->command) { -+ case FLOW_BLOCK_BIND: -+ block_cb = flow_block_cb_lookup(f->block, cb, dev); -+ if (block_cb) { -+ flow_block_cb_incref(block_cb); -+ return 0; -+ } -+ -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->hw = hw; -+ priv->dev = dev; -+ block_cb = flow_block_cb_alloc(cb, dev, priv, NULL); -+ if (IS_ERR(block_cb)) { -+ kfree(priv); -+ return PTR_ERR(block_cb); -+ } -+ -+ flow_block_cb_incref(block_cb); -+ flow_block_cb_add(block_cb, f); -+ list_add_tail(&block_cb->driver_list, &block_cb_list); -+ return 0; -+ case FLOW_BLOCK_UNBIND: -+ block_cb = flow_block_cb_lookup(f->block, cb, dev); -+ if (!block_cb) -+ return -ENOENT; -+ -+ if (!flow_block_cb_decref(block_cb)) { -+ flow_block_cb_remove(block_cb, f); -+ list_del(&block_cb->driver_list); -+ kfree(block_cb->cb_priv); -+ } -+ return 0; -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int -+mtk_wed_setup_tc(struct mtk_wed_device *wed, struct net_device *dev, -+ enum tc_setup_type type, void *type_data) -+{ -+ struct mtk_wed_hw *hw = wed->hw; -+ -+ if (hw->version < 2) -+ return -EOPNOTSUPP; -+ -+ switch (type) { -+ case TC_SETUP_BLOCK: -+ case TC_SETUP_FT: -+ return mtk_wed_setup_tc_block(hw, dev, type_data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ - void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, - void __iomem *wdma, phys_addr_t wdma_phy, - int index) -@@ -1772,6 +1872,7 @@ void mtk_wed_add_hw(struct device_node * - .irq_set_mask = mtk_wed_irq_set_mask, - .detach = mtk_wed_detach, - .ppe_check = mtk_wed_ppe_check, -+ .setup_tc = mtk_wed_setup_tc, - }; - struct device_node *eth_np = eth->dev->of_node; - struct platform_device *pdev; ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - #define MTK_WED_TX_QUEUES 2 - #define MTK_WED_RX_QUEUES 2 -@@ -180,6 +181,8 @@ struct mtk_wed_ops { - - u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask); - void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); -+ int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev, -+ enum tc_setup_type type, void *type_data); - }; - - extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; -@@ -238,6 +241,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic - (_dev)->ops->msg_update(_dev, _id, _msg, _len) - #define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) - #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) -+#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \ -+ (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data) - #else - static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) - { -@@ -256,6 +261,7 @@ static inline bool mtk_wed_device_active - #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV - #define mtk_wed_device_stop(_dev) do {} while (0) - #define mtk_wed_device_dma_reset(_dev) do {} while (0) -+#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP - #endif - - #endif diff --git a/target/linux/generic/backport-5.15/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch b/target/linux/generic/backport-5.15/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch deleted file mode 100644 index 84b768bd79802a..00000000000000 --- a/target/linux/generic/backport-5.15/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Felix Fietkau -Date: Mon, 20 Mar 2023 15:37:55 +0100 -Subject: [PATCH] net: ethernet: mediatek: mtk_ppe: prefer newly added l2 - flows over existing ones - -When a device is roaming between interfaces and a new flow entry is created, -we should assume that its output device is more up to date than whatever -entry existed already. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -662,10 +662,20 @@ void mtk_foe_entry_clear(struct mtk_ppe - static int - mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -+ struct mtk_flow_entry *prev; -+ - entry->type = MTK_FLOW_TYPE_L2; - -- return rhashtable_insert_fast(&ppe->l2_flows, &entry->l2_node, -- mtk_flow_l2_ht_params); -+ prev = rhashtable_lookup_get_insert_fast(&ppe->l2_flows, &entry->l2_node, -+ mtk_flow_l2_ht_params); -+ if (likely(!prev)) -+ return 0; -+ -+ if (IS_ERR(prev)) -+ return PTR_ERR(prev); -+ -+ return rhashtable_replace_fast(&ppe->l2_flows, &prev->l2_node, -+ &entry->l2_node, mtk_flow_l2_ht_params); - } - - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) diff --git a/target/linux/generic/backport-5.15/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch b/target/linux/generic/backport-5.15/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch deleted file mode 100644 index a9f82ca3cb6a0e..00000000000000 --- a/target/linux/generic/backport-5.15/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch +++ /dev/null @@ -1,334 +0,0 @@ -From: Felix Fietkau -Date: Thu, 23 Mar 2023 10:24:11 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: improve keeping track of - offloaded flows - -Unify tracking of L2 and L3 flows. Use the generic list field in struct -mtk_foe_entry for tracking L2 subflows. Preparation for improving -flow accounting support. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 162 ++++++++++++------------ - drivers/net/ethernet/mediatek/mtk_ppe.h | 15 +-- - 2 files changed, 86 insertions(+), 91 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -482,42 +482,43 @@ int mtk_foe_entry_set_queue(struct mtk_e - return 0; - } - -+static int -+mtk_flow_entry_match_len(struct mtk_eth *eth, struct mtk_foe_entry *entry) -+{ -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); -+ -+ if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) -+ return offsetof(struct mtk_foe_entry, ipv6._rsv); -+ else -+ return offsetof(struct mtk_foe_entry, ipv4.ib2); -+} -+ - static bool - mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, -- struct mtk_foe_entry *data) -+ struct mtk_foe_entry *data, int len) - { -- int type, len; -- - if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP) - return false; - -- type = mtk_get_ib1_pkt_type(eth, entry->data.ib1); -- if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) -- len = offsetof(struct mtk_foe_entry, ipv6._rsv); -- else -- len = offsetof(struct mtk_foe_entry, ipv4.ib2); -- - return !memcmp(&entry->data.data, &data->data, len - 4); - } - - static void --__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ bool set_state) - { -- struct hlist_head *head; - struct hlist_node *tmp; - - if (entry->type == MTK_FLOW_TYPE_L2) { - rhashtable_remove_fast(&ppe->l2_flows, &entry->l2_node, - mtk_flow_l2_ht_params); - -- head = &entry->l2_flows; -- hlist_for_each_entry_safe(entry, tmp, head, l2_data.list) -- __mtk_foe_entry_clear(ppe, entry); -+ hlist_for_each_entry_safe(entry, tmp, &entry->l2_flows, l2_list) -+ __mtk_foe_entry_clear(ppe, entry, set_state); - return; - } - -- hlist_del_init(&entry->list); -- if (entry->hash != 0xffff) { -+ if (entry->hash != 0xffff && set_state) { - struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); - - hwe->ib1 &= ~MTK_FOE_IB1_STATE; -@@ -537,7 +538,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW) - return; - -- hlist_del_init(&entry->l2_data.list); -+ hlist_del_init(&entry->l2_list); -+ hlist_del_init(&entry->list); - kfree(entry); - } - -@@ -553,66 +555,55 @@ static int __mtk_foe_entry_idle_time(str - return now - timestamp; - } - -+static bool -+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+{ -+ struct mtk_foe_entry foe = {}; -+ struct mtk_foe_entry *hwe; -+ u16 hash = entry->hash; -+ int len; -+ -+ if (hash == 0xffff) -+ return false; -+ -+ hwe = mtk_foe_get_entry(ppe, hash); -+ len = mtk_flow_entry_match_len(ppe->eth, &entry->data); -+ memcpy(&foe, hwe, len); -+ -+ if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || -+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) -+ return false; -+ -+ entry->data.ib1 = foe.ib1; -+ -+ return true; -+} -+ - static void - mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); - struct mtk_flow_entry *cur; -- struct mtk_foe_entry *hwe; - struct hlist_node *tmp; - int idle; - - idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -- hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_data.list) { -+ hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { - int cur_idle; -- u32 ib1; -- -- hwe = mtk_foe_get_entry(ppe, cur->hash); -- ib1 = READ_ONCE(hwe->ib1); - -- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) { -- cur->hash = 0xffff; -- __mtk_foe_entry_clear(ppe, cur); -+ if (!mtk_flow_entry_update(ppe, cur)) { -+ __mtk_foe_entry_clear(ppe, entry, false); - continue; - } - -- cur_idle = __mtk_foe_entry_idle_time(ppe, ib1); -+ cur_idle = __mtk_foe_entry_idle_time(ppe, cur->data.ib1); - if (cur_idle >= idle) - continue; - - idle = cur_idle; - entry->data.ib1 &= ~ib1_ts_mask; -- entry->data.ib1 |= hwe->ib1 & ib1_ts_mask; -- } --} -- --static void --mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) --{ -- struct mtk_foe_entry foe = {}; -- struct mtk_foe_entry *hwe; -- -- spin_lock_bh(&ppe_lock); -- -- if (entry->type == MTK_FLOW_TYPE_L2) { -- mtk_flow_entry_update_l2(ppe, entry); -- goto out; -+ entry->data.ib1 |= cur->data.ib1 & ib1_ts_mask; - } -- -- if (entry->hash == 0xffff) -- goto out; -- -- hwe = mtk_foe_get_entry(ppe, entry->hash); -- memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); -- if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) { -- entry->hash = 0xffff; -- goto out; -- } -- -- entry->data.ib1 = foe.ib1; -- --out: -- spin_unlock_bh(&ppe_lock); - } - - static void -@@ -655,7 +646,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - spin_lock_bh(&ppe_lock); -- __mtk_foe_entry_clear(ppe, entry); -+ __mtk_foe_entry_clear(ppe, entry, true); -+ hlist_del_init(&entry->list); - spin_unlock_bh(&ppe_lock); - } - -@@ -702,8 +694,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ - { - const struct mtk_soc_data *soc = ppe->eth->soc; - struct mtk_flow_entry *flow_info; -- struct mtk_foe_entry foe = {}, *hwe; - struct mtk_foe_mac_info *l2; -+ struct mtk_foe_entry *hwe; - u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; - int type; - -@@ -711,30 +703,30 @@ mtk_foe_entry_commit_subflow(struct mtk_ - if (!flow_info) - return; - -- flow_info->l2_data.base_flow = entry; - flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW; - flow_info->hash = hash; - hlist_add_head(&flow_info->list, - &ppe->foe_flow[hash / soc->hash_offset]); -- hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows); -+ hlist_add_head(&flow_info->l2_list, &entry->l2_flows); - - hwe = mtk_foe_get_entry(ppe, hash); -- memcpy(&foe, hwe, soc->foe_entry_size); -- foe.ib1 &= ib1_mask; -- foe.ib1 |= entry->data.ib1 & ~ib1_mask; -+ memcpy(&flow_info->data, hwe, soc->foe_entry_size); -+ flow_info->data.ib1 &= ib1_mask; -+ flow_info->data.ib1 |= entry->data.ib1 & ~ib1_mask; - -- l2 = mtk_foe_entry_l2(ppe->eth, &foe); -+ l2 = mtk_foe_entry_l2(ppe->eth, &flow_info->data); - memcpy(l2, &entry->data.bridge.l2, sizeof(*l2)); - -- type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1); -+ type = mtk_get_ib1_pkt_type(ppe->eth, flow_info->data.ib1); - if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT) -- memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new)); -+ memcpy(&flow_info->data.ipv4.new, &flow_info->data.ipv4.orig, -+ sizeof(flow_info->data.ipv4.new)); - else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP) - l2->etype = ETH_P_IPV6; - -- *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2; -+ *mtk_foe_entry_ib2(ppe->eth, &flow_info->data) = entry->data.bridge.ib2; - -- __mtk_foe_entry_commit(ppe, &foe, hash); -+ __mtk_foe_entry_commit(ppe, &flow_info->data, hash); - } - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) -@@ -744,9 +736,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe - struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash); - struct mtk_flow_entry *entry; - struct mtk_foe_bridge key = {}; -+ struct mtk_foe_entry foe = {}; - struct hlist_node *n; - struct ethhdr *eh; - bool found = false; -+ int entry_len; - u8 *tag; - - spin_lock_bh(&ppe_lock); -@@ -754,20 +748,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe - if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND) - goto out; - -- hlist_for_each_entry_safe(entry, n, head, list) { -- if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) { -- if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == -- MTK_FOE_STATE_BIND)) -- continue; -- -- entry->hash = 0xffff; -- __mtk_foe_entry_clear(ppe, entry); -- continue; -- } -+ entry_len = mtk_flow_entry_match_len(ppe->eth, hwe); -+ memcpy(&foe, hwe, entry_len); - -- if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) { -+ hlist_for_each_entry_safe(entry, n, head, list) { -+ if (found || -+ !mtk_flow_entry_match(ppe->eth, entry, &foe, entry_len)) { - if (entry->hash != 0xffff) -- entry->hash = 0xffff; -+ __mtk_foe_entry_clear(ppe, entry, false); - continue; - } - -@@ -816,9 +804,17 @@ out: - - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -- mtk_flow_entry_update(ppe, entry); -+ int idle; -+ -+ spin_lock_bh(&ppe_lock); -+ if (entry->type == MTK_FLOW_TYPE_L2) -+ mtk_flow_entry_update_l2(ppe, entry); -+ else -+ mtk_flow_entry_update(ppe, entry); -+ idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ spin_unlock_bh(&ppe_lock); - -- return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ return idle; - } - - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -286,7 +286,12 @@ enum { - - struct mtk_flow_entry { - union { -- struct hlist_node list; -+ /* regular flows + L2 subflows */ -+ struct { -+ struct hlist_node list; -+ struct hlist_node l2_list; -+ }; -+ /* L2 flows */ - struct { - struct rhash_head l2_node; - struct hlist_head l2_flows; -@@ -296,13 +301,7 @@ struct mtk_flow_entry { - s8 wed_index; - u8 ppe_index; - u16 hash; -- union { -- struct mtk_foe_entry data; -- struct { -- struct mtk_flow_entry *base_flow; -- struct hlist_node list; -- } l2_data; -- }; -+ struct mtk_foe_entry data; - struct rhash_head node; - unsigned long cookie; - }; diff --git a/target/linux/generic/backport-5.15/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch b/target/linux/generic/backport-5.15/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch deleted file mode 100644 index 2ea6d341b06473..00000000000000 --- a/target/linux/generic/backport-5.15/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch +++ /dev/null @@ -1,342 +0,0 @@ -From: Felix Fietkau -Date: Thu, 23 Mar 2023 11:05:22 +0100 -Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for L2 - flows - -For L2 flows, the packet/byte counters should report the sum of the -counters of their subflows, both current and expired. -In order to make this work, change the way that accounting data is tracked. -Reset counters when a flow enters bind. Once it expires (or enters unbind), -store the last counter value in struct mtk_flow_entry. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -79,9 +79,9 @@ static int mtk_ppe_mib_wait_busy(struct - int ret; - u32 val; - -- ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val, -- !(val & MTK_PPE_MIB_SER_CR_ST), -- 20, MTK_PPE_WAIT_TIMEOUT_US); -+ ret = readl_poll_timeout_atomic(ppe->base + MTK_PPE_MIB_SER_CR, val, -+ !(val & MTK_PPE_MIB_SER_CR_ST), -+ 20, MTK_PPE_WAIT_TIMEOUT_US); - - if (ret) - dev_err(ppe->dev, "MIB table busy"); -@@ -89,17 +89,31 @@ static int mtk_ppe_mib_wait_busy(struct - return ret; - } - --static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) -+static inline struct mtk_foe_accounting * -+mtk_ppe_acct_data(struct mtk_ppe *ppe, u16 index) -+{ -+ if (!ppe->acct_table) -+ return NULL; -+ -+ return ppe->acct_table + index * sizeof(struct mtk_foe_accounting); -+} -+ -+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index) - { - u32 val, cnt_r0, cnt_r1, cnt_r2; -+ struct mtk_foe_accounting *acct; - int ret; - - val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST; - ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val); - -+ acct = mtk_ppe_acct_data(ppe, index); -+ if (!acct) -+ return NULL; -+ - ret = mtk_ppe_mib_wait_busy(ppe); - if (ret) -- return ret; -+ return acct; - - cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0); - cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); -@@ -108,19 +122,19 @@ static int mtk_mib_entry_read(struct mtk - if (mtk_is_netsys_v3_or_greater(ppe->eth)) { - /* 64 bit for each counter */ - u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3); -- *bytes = ((u64)cnt_r1 << 32) | cnt_r0; -- *packets = ((u64)cnt_r3 << 32) | cnt_r2; -+ acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0; -+ acct->packets += ((u64)cnt_r3 << 32) | cnt_r2; - } else { - /* 48 bit byte counter, 40 bit packet counter */ - u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); - u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); - u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); - u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; -+ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low; -+ acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low; - } - -- return 0; -+ return acct; - } - - static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) -@@ -525,13 +539,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); - dma_wmb(); - mtk_ppe_cache_clear(ppe); -- if (ppe->accounting) { -- struct mtk_foe_accounting *acct; -- -- acct = ppe->acct_table + entry->hash * sizeof(*acct); -- acct->packets = 0; -- acct->bytes = 0; -- } - } - entry->hash = 0xffff; - -@@ -556,11 +563,14 @@ static int __mtk_foe_entry_idle_time(str - } - - static bool --mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ u64 *packets, u64 *bytes) - { -+ struct mtk_foe_accounting *acct; - struct mtk_foe_entry foe = {}; - struct mtk_foe_entry *hwe; - u16 hash = entry->hash; -+ bool ret = false; - int len; - - if (hash == 0xffff) -@@ -571,18 +581,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp - memcpy(&foe, hwe, len); - - if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || -- FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) -- return false; -+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) { -+ acct = mtk_ppe_acct_data(ppe, hash); -+ if (acct) { -+ entry->prev_packets += acct->packets; -+ entry->prev_bytes += acct->bytes; -+ } -+ -+ goto out; -+ } - - entry->data.ib1 = foe.ib1; -+ acct = mtk_ppe_mib_entry_read(ppe, hash); -+ ret = true; -+ -+out: -+ if (acct) { -+ *packets += acct->packets; -+ *bytes += acct->bytes; -+ } - -- return true; -+ return ret; - } - - static void - mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); -+ u64 *packets = &entry->packets; -+ u64 *bytes = &entry->bytes; - struct mtk_flow_entry *cur; - struct hlist_node *tmp; - int idle; -@@ -591,7 +618,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe - hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { - int cur_idle; - -- if (!mtk_flow_entry_update(ppe, cur)) { -+ if (!mtk_flow_entry_update(ppe, cur, packets, bytes)) { -+ entry->prev_packets += cur->prev_packets; -+ entry->prev_bytes += cur->prev_bytes; - __mtk_foe_entry_clear(ppe, entry, false); - continue; - } -@@ -606,10 +635,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe - } - } - -+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ int *idle) -+{ -+ entry->packets = entry->prev_packets; -+ entry->bytes = entry->prev_bytes; -+ -+ spin_lock_bh(&ppe_lock); -+ -+ if (entry->type == MTK_FLOW_TYPE_L2) -+ mtk_flow_entry_update_l2(ppe, entry); -+ else -+ mtk_flow_entry_update(ppe, entry, &entry->packets, &entry->bytes); -+ -+ *idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ -+ spin_unlock_bh(&ppe_lock); -+} -+ - static void - __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - u16 hash) - { -+ struct mtk_foe_accounting *acct; - struct mtk_eth *eth = ppe->eth; - u16 timestamp = mtk_eth_timestamp(eth); - struct mtk_foe_entry *hwe; -@@ -640,6 +688,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - - dma_wmb(); - -+ acct = mtk_ppe_mib_entry_read(ppe, hash); -+ if (acct) { -+ acct->packets = 0; -+ acct->bytes = 0; -+ } -+ - mtk_ppe_cache_clear(ppe); - } - -@@ -802,21 +856,6 @@ out: - spin_unlock_bh(&ppe_lock); - } - --int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) --{ -- int idle; -- -- spin_lock_bh(&ppe_lock); -- if (entry->type == MTK_FLOW_TYPE_L2) -- mtk_flow_entry_update_l2(ppe, entry); -- else -- mtk_flow_entry_update(ppe, entry); -- idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -- spin_unlock_bh(&ppe_lock); -- -- return idle; --} -- - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) - { - if (!ppe) -@@ -844,32 +883,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe - return mtk_ppe_wait_busy(ppe); - } - --struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -- struct mtk_foe_accounting *diff) --{ -- struct mtk_foe_accounting *acct; -- int size = sizeof(struct mtk_foe_accounting); -- u64 bytes, packets; -- -- if (!ppe->accounting) -- return NULL; -- -- if (mtk_mib_entry_read(ppe, index, &bytes, &packets)) -- return NULL; -- -- acct = ppe->acct_table + index * size; -- -- acct->bytes += bytes; -- acct->packets += packets; -- -- if (diff) { -- diff->bytes = bytes; -- diff->packets = packets; -- } -- -- return acct; --} -- - struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) - { - bool accounting = eth->soc->has_accounting; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -304,6 +304,8 @@ struct mtk_flow_entry { - struct mtk_foe_entry data; - struct rhash_head node; - unsigned long cookie; -+ u64 prev_packets, prev_bytes; -+ u64 packets, bytes; - }; - - struct mtk_mib_entry { -@@ -347,6 +349,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth) - void mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); -+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index); - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); - -@@ -395,9 +398,8 @@ int mtk_foe_entry_set_queue(struct mtk_e - unsigned int queue); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); --int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); --struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -- struct mtk_foe_accounting *diff); -+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ int *idle); - - #endif ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -96,7 +96,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file - if (bind && state != MTK_FOE_STATE_BIND) - continue; - -- acct = mtk_foe_entry_get_mib(ppe, i, NULL); -+ acct = mtk_ppe_mib_entry_read(ppe, i); - - type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); - seq_printf(m, "%05x %s %7s", i, ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -501,24 +501,21 @@ static int - mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) - { - struct mtk_flow_entry *entry; -- struct mtk_foe_accounting diff; -- u32 idle; -+ u64 packets, bytes; -+ int idle; - - entry = rhashtable_lookup(ð->flow_table, &f->cookie, - mtk_flow_ht_params); - if (!entry) - return -ENOENT; - -- idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); -+ packets = entry->packets; -+ bytes = entry->bytes; -+ mtk_foe_entry_get_stats(eth->ppe[entry->ppe_index], entry, &idle); -+ f->stats.pkts += entry->packets - packets; -+ f->stats.bytes += entry->bytes - bytes; - f->stats.lastused = jiffies - idle * HZ; - -- if (entry->hash != 0xFFFF && -- mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash, -- &diff)) { -- f->stats.pkts += diff.packets; -- f->stats.bytes += diff.bytes; -- } -- - return 0; - } - diff --git a/target/linux/generic/backport-5.15/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch b/target/linux/generic/backport-5.15/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch deleted file mode 100644 index a224b626243c9c..00000000000000 --- a/target/linux/generic/backport-5.15/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Lorenzo Bianconi -Date: Sun, 27 Aug 2023 19:31:41 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: add some more info in wed_txinfo_show - handler - -Add some new info in Wireless Ethernet Dispatcher wed_txinfo_show -debugfs handler useful during debugging. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/3390292655d568180b73d2a25576f61aa63310e5.1693157377.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -127,8 +127,17 @@ wed_txinfo_show(struct seq_file *s, void - DUMP_WDMA_RING(WDMA_RING_RX(0)), - DUMP_WDMA_RING(WDMA_RING_RX(1)), - -- DUMP_STR("TX FREE"), -+ DUMP_STR("WED TX FREE"), - DUMP_WED(WED_RX_MIB(0)), -+ DUMP_WED_RING(WED_RING_RX(0)), -+ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(0)), -+ DUMP_WED(WED_RX_MIB(1)), -+ DUMP_WED_RING(WED_RING_RX(1)), -+ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(1)), -+ -+ DUMP_STR("WED WPDMA TX FREE"), -+ DUMP_WED_RING(WED_WPDMA_RING_RX(0)), -+ DUMP_WED_RING(WED_WPDMA_RING_RX(1)), - }; - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -266,6 +266,8 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4) - #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4) -+#define MTK_WED_WPDMA_RX_MIB(_n) (0x5e0 + (_n) * 4) -+#define MTK_WED_WPDMA_RX_COHERENT_MIB(_n) (0x5f0 + (_n) * 4) - - #define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10) - #define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10) diff --git a/target/linux/generic/backport-5.15/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch b/target/linux/generic/backport-5.15/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch deleted file mode 100644 index df6edfdf94333f..00000000000000 --- a/target/linux/generic/backport-5.15/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Lorenzo Bianconi -Date: Sun, 27 Aug 2023 19:33:47 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: minor change in wed_{tx,rx}info_show - -No functional changes, just cosmetic ones. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/71e046c72a978745f0435af265dda610aa9bfbcf.1693157578.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -84,7 +84,6 @@ dump_wed_regs(struct seq_file *s, struct - } - } - -- - static int - wed_txinfo_show(struct seq_file *s, void *data) - { -@@ -142,10 +141,8 @@ wed_txinfo_show(struct seq_file *s, void - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; - -- if (!dev) -- return 0; -- -- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ if (dev) -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); - - return 0; - } -@@ -217,10 +214,8 @@ wed_rxinfo_show(struct seq_file *s, void - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; - -- if (!dev) -- return 0; -- -- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ if (dev) -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); - - return 0; - } diff --git a/target/linux/generic/backport-5.15/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch b/target/linux/generic/backport-5.15/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch deleted file mode 100644 index 0bf9dea24f0a16..00000000000000 --- a/target/linux/generic/backport-5.15/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Lorenzo Bianconi -Date: Tue, 12 Sep 2023 10:22:56 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on mtk_pse_port definitions - in mtk_flow_set_output_device - -Similar to ethernet ports, rely on mtk_pse_port definitions for -pse wdma ports as well. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://lore.kernel.org/r/b86bdb717e963e3246c1dec5f736c810703cf056.1694506814.git.lorenzo@kernel.org -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -196,10 +196,10 @@ mtk_flow_set_output_device(struct mtk_et - if (mtk_is_netsys_v2_or_greater(eth)) { - switch (info.wdma_idx) { - case 0: -- pse_port = 8; -+ pse_port = PSE_WDMA0_PORT; - break; - case 1: -- pse_port = 9; -+ pse_port = PSE_WDMA1_PORT; - break; - default: - return -EINVAL; diff --git a/target/linux/generic/backport-5.15/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch b/target/linux/generic/backport-5.15/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch deleted file mode 100644 index c99e1334d41e00..00000000000000 --- a/target/linux/generic/backport-5.15/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Lorenzo Bianconi -Date: Tue, 12 Sep 2023 10:28:00 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: check update_wo_rx_stats in - mtk_wed_update_rx_stats() - -Check if update_wo_rx_stats function pointer is properly set in -mtk_wed_update_rx_stats routine before accessing it. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://lore.kernel.org/r/b0d233386e059bccb59f18f69afb79a7806e5ded.1694507226.git.lorenzo@kernel.org -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -68,6 +68,9 @@ mtk_wed_update_rx_stats(struct mtk_wed_d - struct mtk_wed_wo_rx_stats *stats; - int i; - -+ if (!wed->wlan.update_wo_rx_stats) -+ return; -+ - if (count * sizeof(*stats) > skb->len - sizeof(u32)) - return; - diff --git a/target/linux/generic/backport-5.15/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch b/target/linux/generic/backport-5.15/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch deleted file mode 100644 index cd7fb92e2090f5..00000000000000 --- a/target/linux/generic/backport-5.15/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Lorenzo Bianconi -Date: Wed, 13 Sep 2023 20:42:47 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: do not assume offload callbacks are - always set - -Check if wlan.offload_enable and wlan.offload_disable callbacks are set -in mtk_wed_flow_add/mtk_wed_flow_remove since mt7996 will not rely -on them. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1712,19 +1712,20 @@ mtk_wed_irq_set_mask(struct mtk_wed_devi - int mtk_wed_flow_add(int index) - { - struct mtk_wed_hw *hw = hw_list[index]; -- int ret; -+ int ret = 0; - -- if (!hw || !hw->wed_dev) -- return -ENODEV; -+ mutex_lock(&hw_lock); - -- if (hw->num_flows) { -- hw->num_flows++; -- return 0; -+ if (!hw || !hw->wed_dev) { -+ ret = -ENODEV; -+ goto out; - } - -- mutex_lock(&hw_lock); -- if (!hw->wed_dev) { -- ret = -ENODEV; -+ if (!hw->wed_dev->wlan.offload_enable) -+ goto out; -+ -+ if (hw->num_flows) { -+ hw->num_flows++; - goto out; - } - -@@ -1743,14 +1744,15 @@ void mtk_wed_flow_remove(int index) - { - struct mtk_wed_hw *hw = hw_list[index]; - -- if (!hw) -- return; -+ mutex_lock(&hw_lock); - -- if (--hw->num_flows) -- return; -+ if (!hw || !hw->wed_dev) -+ goto out; - -- mutex_lock(&hw_lock); -- if (!hw->wed_dev) -+ if (!hw->wed_dev->wlan.offload_disable) -+ goto out; -+ -+ if (--hw->num_flows) - goto out; - - hw->wed_dev->wlan.offload_disable(hw->wed_dev); diff --git a/target/linux/generic/backport-5.15/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch b/target/linux/generic/backport-5.15/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch deleted file mode 100644 index 29481886503363..00000000000000 --- a/target/linux/generic/backport-5.15/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch +++ /dev/null @@ -1,232 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:05 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: introduce versioning utility routines - -Similar to mtk_eth_soc, introduce the following wed versioning -utility routines: -- mtk_wed_is_v1 -- mtk_wed_is_v2 - -This is a preliminary patch to introduce WED support for MT7988 SoC - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -277,7 +277,7 @@ mtk_wed_assign(struct mtk_wed_device *de - if (!hw->wed_dev) - goto out; - -- if (hw->version == 1) -+ if (mtk_wed_is_v1(hw)) - return NULL; - - /* MT7986 WED devices do not have any pcie slot restrictions */ -@@ -358,7 +358,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d - desc->buf0 = cpu_to_le32(buf_phys); - desc->buf1 = cpu_to_le32(buf_phys + txd_size); - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | - FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, - MTK_WED_BUF_SIZE - txd_size) | -@@ -497,7 +497,7 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - { - u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; - else - mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -@@ -576,7 +576,7 @@ mtk_wed_dma_disable(struct mtk_wed_devic - MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | - MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); - wdma_clr(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -@@ -605,7 +605,7 @@ mtk_wed_stop(struct mtk_wed_device *dev) - wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - return; - - wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); -@@ -624,7 +624,7 @@ mtk_wed_deinit(struct mtk_wed_device *de - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - return; - - wed_clr(dev, MTK_WED_CTRL, -@@ -730,7 +730,7 @@ mtk_wed_bus_init(struct mtk_wed_device * - static void - mtk_wed_set_wpdma(struct mtk_wed_device *dev) - { -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); - } else { - mtk_wed_bus_init(dev); -@@ -761,7 +761,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev - MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; - wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - u32 offset = dev->hw->index ? 0x04000400 : 0; - - wdma_set(dev, MTK_WDMA_GLO_CFG, -@@ -934,7 +934,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - wed_w32(dev, MTK_WED_TX_BM_TKID, - FIELD_PREP(MTK_WED_TX_BM_TKID_START, - dev->wlan.token_start) | -@@ -967,7 +967,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - wed_set(dev, MTK_WED_CTRL, - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -@@ -1217,7 +1217,7 @@ mtk_wed_reset_dma(struct mtk_wed_device - } - - dev->init_done = false; -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - return; - - if (!busy) { -@@ -1343,7 +1343,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, - MTK_WED_PCIE_INT_TRIGGER_STATUS); - -@@ -1416,7 +1416,7 @@ mtk_wed_dma_enable(struct mtk_wed_device - MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | - MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - wdma_set(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); - } else { -@@ -1465,7 +1465,7 @@ mtk_wed_start(struct mtk_wed_device *dev - - mtk_wed_set_ext_int(dev, true); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN | - FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, - dev->hw->index); -@@ -1550,7 +1550,7 @@ mtk_wed_attach(struct mtk_wed_device *de - } - - mtk_wed_hw_init_early(dev); -- if (hw->version == 1) { -+ if (mtk_wed_is_v1(hw)) { - regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, - BIT(hw->index), 0); - } else { -@@ -1618,7 +1618,7 @@ static int - mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs) - { - struct mtk_wed_ring *ring = &dev->txfree_ring; -- int i, index = dev->hw->version == 1; -+ int i, index = mtk_wed_is_v1(dev->hw); - - /* - * For txfree event handling, the same DMA ring is shared between WED -@@ -1676,7 +1676,7 @@ mtk_wed_irq_get(struct mtk_wed_device *d - { - u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; - else - ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -@@ -1843,7 +1843,7 @@ mtk_wed_setup_tc(struct mtk_wed_device * - { - struct mtk_wed_hw *hw = wed->hw; - -- if (hw->version < 2) -+ if (mtk_wed_is_v1(hw)) - return -EOPNOTSUPP; - - switch (type) { -@@ -1917,9 +1917,9 @@ void mtk_wed_add_hw(struct device_node * - hw->wdma = wdma; - hw->index = index; - hw->irq = irq; -- hw->version = mtk_is_netsys_v1(eth) ? 1 : 2; -+ hw->version = eth->soc->version; - -- if (hw->version == 1) { -+ if (mtk_wed_is_v1(hw)) { - hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, - "mediatek,pcie-mirror"); - hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -40,6 +40,16 @@ struct mtk_wdma_info { - }; - - #ifdef CONFIG_NET_MEDIATEK_SOC_WED -+static inline bool mtk_wed_is_v1(struct mtk_wed_hw *hw) -+{ -+ return hw->version == 1; -+} -+ -+static inline bool mtk_wed_is_v2(struct mtk_wed_hw *hw) -+{ -+ return hw->version == 2; -+} -+ - static inline void - wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val) - { ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -263,7 +263,7 @@ void mtk_wed_hw_add_debugfs(struct mtk_w - debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg); - debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval); - debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops); -- if (hw->version != 1) -+ if (!mtk_wed_is_v1(hw)) - debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, - &wed_rxinfo_fops); - } ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -207,7 +207,7 @@ int mtk_wed_mcu_msg_update(struct mtk_we - { - struct mtk_wed_wo *wo = dev->hw->wed_wo; - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - return 0; - - if (WARN_ON(!wo)) diff --git a/target/linux/generic/backport-5.15/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch b/target/linux/generic/backport-5.15/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch deleted file mode 100644 index bc34aa33a9f2a0..00000000000000 --- a/target/linux/generic/backport-5.15/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch +++ /dev/null @@ -1,234 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:06 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: do not configure rx offload if not - supported - -Check if rx offload is supported running mtk_wed_get_rx_capa routine -before configuring it. This is a preliminary patch to introduce Wireless -Ethernet Dispatcher (WED) support for MT7988 SoC. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -605,7 +605,7 @@ mtk_wed_stop(struct mtk_wed_device *dev) - wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); - -- if (mtk_wed_is_v1(dev->hw)) -+ if (!mtk_wed_get_rx_capa(dev)) - return; - - wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); -@@ -732,16 +732,21 @@ mtk_wed_set_wpdma(struct mtk_wed_device - { - if (mtk_wed_is_v1(dev->hw)) { - wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); -- } else { -- mtk_wed_bus_init(dev); -- -- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); -- wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); -- wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); -- wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); -- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); -- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx); -+ return; - } -+ -+ mtk_wed_bus_init(dev); -+ -+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); -+ -+ if (!mtk_wed_get_rx_capa(dev)) -+ return; -+ -+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); -+ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx); - } - - static void -@@ -973,15 +978,17 @@ mtk_wed_hw_init(struct mtk_wed_device *d - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - } else { - wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); -- /* rx hw init */ -- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -- MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -- MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -- -- mtk_wed_rx_buffer_hw_init(dev); -- mtk_wed_rro_hw_init(dev); -- mtk_wed_route_qm_hw_init(dev); -+ if (mtk_wed_get_rx_capa(dev)) { -+ /* rx hw init */ -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -+ -+ mtk_wed_rx_buffer_hw_init(dev); -+ mtk_wed_rro_hw_init(dev); -+ mtk_wed_route_qm_hw_init(dev); -+ } - } - - wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); -@@ -1353,8 +1360,6 @@ mtk_wed_configure_irq(struct mtk_wed_dev - - wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); - } else { -- wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE, -- GENMASK(1, 0)); - /* initail tx interrupt trigger */ - wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, - MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | -@@ -1373,15 +1378,20 @@ mtk_wed_configure_irq(struct mtk_wed_dev - FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG, - dev->wlan.txfree_tbit)); - -- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX, -- MTK_WED_WPDMA_INT_CTRL_RX0_EN | -- MTK_WED_WPDMA_INT_CTRL_RX0_CLR | -- MTK_WED_WPDMA_INT_CTRL_RX1_EN | -- MTK_WED_WPDMA_INT_CTRL_RX1_CLR | -- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG, -- dev->wlan.rx_tbit[0]) | -- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG, -- dev->wlan.rx_tbit[1])); -+ if (mtk_wed_get_rx_capa(dev)) { -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX, -+ MTK_WED_WPDMA_INT_CTRL_RX0_EN | -+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR | -+ MTK_WED_WPDMA_INT_CTRL_RX1_EN | -+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG, -+ dev->wlan.rx_tbit[0]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG, -+ dev->wlan.rx_tbit[1])); -+ -+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE, -+ GENMASK(1, 0)); -+ } - - wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask); - wed_set(dev, MTK_WED_WDMA_INT_CTRL, -@@ -1400,6 +1410,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev - static void - mtk_wed_dma_enable(struct mtk_wed_device *dev) - { -+ int i; -+ - wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); - - wed_set(dev, MTK_WED_GLO_CFG, -@@ -1419,33 +1431,33 @@ mtk_wed_dma_enable(struct mtk_wed_device - if (mtk_wed_is_v1(dev->hw)) { - wdma_set(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -- } else { -- int i; -+ return; -+ } - -- wed_set(dev, MTK_WED_WPDMA_CTRL, -- MTK_WED_WPDMA_CTRL_SDL1_FIXED); -+ wed_set(dev, MTK_WED_WPDMA_CTRL, -+ MTK_WED_WPDMA_CTRL_SDL1_FIXED); -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | -+ MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); - -- wed_set(dev, MTK_WED_WDMA_GLO_CFG, -- MTK_WED_WDMA_GLO_CFG_TX_DRV_EN | -- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); -+ if (!mtk_wed_get_rx_capa(dev)) -+ return; - -- wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | -- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -- -- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -- MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | -- MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); -+ wed_set(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); - -- wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -- MTK_WED_WPDMA_RX_D_RX_DRV_EN | -- FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) | -- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, -- 0x2)); -+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RX_DRV_EN | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, -+ 0x2)); - -- for (i = 0; i < MTK_WED_RX_QUEUES; i++) -- mtk_wed_check_wfdma_rx_fill(dev, i); -- } -+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) -+ mtk_wed_check_wfdma_rx_fill(dev, i); - } - - static void -@@ -1472,7 +1484,7 @@ mtk_wed_start(struct mtk_wed_device *dev - - val |= BIT(0) | (BIT(1) * !!dev->hw->index); - regmap_write(dev->hw->mirror, dev->hw->index * 4, val); -- } else { -+ } else if (mtk_wed_get_rx_capa(dev)) { - /* driver set mid ready and only once */ - wed_w32(dev, MTK_WED_EXT_INT_MASK1, - MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); -@@ -1484,7 +1496,6 @@ mtk_wed_start(struct mtk_wed_device *dev - - if (mtk_wed_rro_cfg(dev)) - return; -- - } - - mtk_wed_set_512_support(dev, dev->wlan.wcid_512); -@@ -1550,13 +1561,14 @@ mtk_wed_attach(struct mtk_wed_device *de - } - - mtk_wed_hw_init_early(dev); -- if (mtk_wed_is_v1(hw)) { -+ if (mtk_wed_is_v1(hw)) - regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, - BIT(hw->index), 0); -- } else { -+ else - dev->rev_id = wed_r32(dev, MTK_WED_REV_ID); -+ -+ if (mtk_wed_get_rx_capa(dev)) - ret = mtk_wed_wo_init(hw); -- } - out: - if (ret) { - dev_err(dev->hw->dev, "failed to attach wed device\n"); ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -207,7 +207,7 @@ int mtk_wed_mcu_msg_update(struct mtk_we - { - struct mtk_wed_wo *wo = dev->hw->wed_wo; - -- if (mtk_wed_is_v1(dev->hw)) -+ if (!mtk_wed_get_rx_capa(dev)) - return 0; - - if (WARN_ON(!wo)) diff --git a/target/linux/generic/backport-5.15/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch b/target/linux/generic/backport-5.15/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch deleted file mode 100644 index d83434fb2c7d08..00000000000000 --- a/target/linux/generic/backport-5.15/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:07 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: rename mtk_rxbm_desc in - mtk_wed_bm_desc - -Rename mtk_rxbm_desc structure in mtk_wed_bm_desc since it will be used -even on tx side by MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -421,7 +421,7 @@ free_pagelist: - static int - mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev) - { -- struct mtk_rxbm_desc *desc; -+ struct mtk_wed_bm_desc *desc; - dma_addr_t desc_phys; - - dev->rx_buf_ring.size = dev->wlan.rx_nbuf; -@@ -441,7 +441,7 @@ mtk_wed_rx_buffer_alloc(struct mtk_wed_d - static void - mtk_wed_free_rx_buffer(struct mtk_wed_device *dev) - { -- struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc; -+ struct mtk_wed_bm_desc *desc = dev->rx_buf_ring.desc; - - if (!desc) - return; ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -45,7 +45,7 @@ enum mtk_wed_wo_cmd { - MTK_WED_WO_CMD_WED_END - }; - --struct mtk_rxbm_desc { -+struct mtk_wed_bm_desc { - __le32 buf0; - __le32 token; - } __packed __aligned(4); -@@ -105,7 +105,7 @@ struct mtk_wed_device { - struct { - int size; - struct page_frag_cache rx_page; -- struct mtk_rxbm_desc *desc; -+ struct mtk_wed_bm_desc *desc; - dma_addr_t desc_phys; - } rx_buf_ring; - diff --git a/target/linux/generic/backport-5.15/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch b/target/linux/generic/backport-5.15/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch deleted file mode 100644 index 8000a8759e5b50..00000000000000 --- a/target/linux/generic/backport-5.15/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:08 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: introduce mtk_wed_buf structure - -Introduce mtk_wed_buf structure to store both virtual and physical -addresses allocated in mtk_wed_tx_buffer_alloc() routine. This is a -preliminary patch to add WED support for MT7988 SoC since it relies on a -different dma descriptor layout not storing page dma addresses. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -299,9 +299,9 @@ out: - static int - mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) - { -+ struct mtk_wed_buf *page_list; - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -- void **page_list; - int token = dev->wlan.token_start; - int ring_size; - int n_pages; -@@ -342,7 +342,8 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d - return -ENOMEM; - } - -- page_list[page_idx++] = page; -+ page_list[page_idx].p = page; -+ page_list[page_idx++].phy_addr = page_phys; - dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE, - DMA_BIDIRECTIONAL); - -@@ -386,8 +387,8 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d - static void - mtk_wed_free_tx_buffer(struct mtk_wed_device *dev) - { -+ struct mtk_wed_buf *page_list = dev->tx_buf_ring.pages; - struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc; -- void **page_list = dev->tx_buf_ring.pages; - int page_idx; - int i; - -@@ -399,13 +400,12 @@ mtk_wed_free_tx_buffer(struct mtk_wed_de - - for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size; - i += MTK_WED_BUF_PER_PAGE) { -- void *page = page_list[page_idx++]; -- dma_addr_t buf_addr; -+ dma_addr_t buf_addr = page_list[page_idx].phy_addr; -+ void *page = page_list[page_idx++].p; - - if (!page) - break; - -- buf_addr = le32_to_cpu(desc[i].buf0); - dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE, - DMA_BIDIRECTIONAL); - __free_page(page); ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -76,6 +76,11 @@ struct mtk_wed_wo_rx_stats { - __le32 rx_drop_cnt; - }; - -+struct mtk_wed_buf { -+ void *p; -+ dma_addr_t phy_addr; -+}; -+ - struct mtk_wed_device { - #ifdef CONFIG_NET_MEDIATEK_SOC_WED - const struct mtk_wed_ops *ops; -@@ -97,7 +102,7 @@ struct mtk_wed_device { - - struct { - int size; -- void **pages; -+ struct mtk_wed_buf *pages; - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; - } tx_buf_ring; diff --git a/target/linux/generic/backport-5.15/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch b/target/linux/generic/backport-5.15/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch deleted file mode 100644 index 98d782b1d07409..00000000000000 --- a/target/linux/generic/backport-5.15/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch +++ /dev/null @@ -1,88 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:09 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: move mem_region array out of - mtk_wed_mcu_load_firmware - -Remove mtk_wed_wo_memory_region boot structure in mtk_wed_wo. -This is a preliminary patch to introduce WED support for MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -16,14 +16,30 @@ - #include "mtk_wed_wo.h" - #include "mtk_wed.h" - -+static struct mtk_wed_wo_memory_region mem_region[] = { -+ [MTK_WED_WO_REGION_EMI] = { -+ .name = "wo-emi", -+ }, -+ [MTK_WED_WO_REGION_ILM] = { -+ .name = "wo-ilm", -+ }, -+ [MTK_WED_WO_REGION_DATA] = { -+ .name = "wo-data", -+ .shared = true, -+ }, -+ [MTK_WED_WO_REGION_BOOT] = { -+ .name = "wo-boot", -+ }, -+}; -+ - static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg) - { -- return readl(wo->boot.addr + reg); -+ return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg); - } - - static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val) - { -- writel(val, wo->boot.addr + reg); -+ writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg); - } - - static struct sk_buff * -@@ -294,18 +310,6 @@ next: - static int - mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) - { -- static struct mtk_wed_wo_memory_region mem_region[] = { -- [MTK_WED_WO_REGION_EMI] = { -- .name = "wo-emi", -- }, -- [MTK_WED_WO_REGION_ILM] = { -- .name = "wo-ilm", -- }, -- [MTK_WED_WO_REGION_DATA] = { -- .name = "wo-data", -- .shared = true, -- }, -- }; - const struct mtk_wed_fw_trailer *trailer; - const struct firmware *fw; - const char *fw_name; -@@ -319,11 +323,6 @@ mtk_wed_mcu_load_firmware(struct mtk_wed - return ret; - } - -- wo->boot.name = "wo-boot"; -- ret = mtk_wed_get_memory_region(wo, &wo->boot); -- if (ret) -- return ret; -- - /* set dummy cr */ - wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL, - wo->hw->index + 1); ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -228,7 +228,6 @@ struct mtk_wed_wo_queue { - - struct mtk_wed_wo { - struct mtk_wed_hw *hw; -- struct mtk_wed_wo_memory_region boot; - - struct mtk_wed_wo_queue q_tx; - struct mtk_wed_wo_queue q_rx; diff --git a/target/linux/generic/backport-5.15/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch b/target/linux/generic/backport-5.15/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch deleted file mode 100644 index 48b0d02049194d..00000000000000 --- a/target/linux/generic/backport-5.15/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch +++ /dev/null @@ -1,71 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:10 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: make memory region optional - -Make mtk_wed_wo_memory_region optionals. -This is a preliminary patch to introduce Wireless Ethernet Dispatcher -support for MT7988 SoC since MT7988 WED fw image will have a different -layout. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -234,19 +234,13 @@ int mtk_wed_mcu_msg_update(struct mtk_we - } - - static int --mtk_wed_get_memory_region(struct mtk_wed_wo *wo, -+mtk_wed_get_memory_region(struct mtk_wed_hw *hw, int index, - struct mtk_wed_wo_memory_region *region) - { - struct reserved_mem *rmem; - struct device_node *np; -- int index; - -- index = of_property_match_string(wo->hw->node, "memory-region-names", -- region->name); -- if (index < 0) -- return index; -- -- np = of_parse_phandle(wo->hw->node, "memory-region", index); -+ np = of_parse_phandle(hw->node, "memory-region", index); - if (!np) - return -ENODEV; - -@@ -258,7 +252,7 @@ mtk_wed_get_memory_region(struct mtk_wed - - region->phy_addr = rmem->base; - region->size = rmem->size; -- region->addr = devm_ioremap(wo->hw->dev, region->phy_addr, region->size); -+ region->addr = devm_ioremap(hw->dev, region->phy_addr, region->size); - - return !region->addr ? -EINVAL : 0; - } -@@ -271,6 +265,9 @@ mtk_wed_mcu_run_firmware(struct mtk_wed_ - const struct mtk_wed_fw_trailer *trailer; - const struct mtk_wed_fw_region *fw_region; - -+ if (!region->phy_addr || !region->size) -+ return 0; -+ - trailer_ptr = fw->data + fw->size - sizeof(*trailer); - trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr; - region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region); -@@ -318,7 +315,13 @@ mtk_wed_mcu_load_firmware(struct mtk_wed - - /* load firmware region metadata */ - for (i = 0; i < ARRAY_SIZE(mem_region); i++) { -- ret = mtk_wed_get_memory_region(wo, &mem_region[i]); -+ int index = of_property_match_string(wo->hw->node, -+ "memory-region-names", -+ mem_region[i].name); -+ if (index < 0) -+ continue; -+ -+ ret = mtk_wed_get_memory_region(wo->hw, index, &mem_region[i]); - if (ret) - return ret; - } diff --git a/target/linux/generic/backport-5.15/752-12-v6.7-net-ethernet-mtk_wed-fix-EXT_INT_STATUS_RX_FBUF-defi.patch b/target/linux/generic/backport-5.15/752-12-v6.7-net-ethernet-mtk_wed-fix-EXT_INT_STATUS_RX_FBUF-defi.patch deleted file mode 100644 index 878e8fe996d093..00000000000000 --- a/target/linux/generic/backport-5.15/752-12-v6.7-net-ethernet-mtk_wed-fix-EXT_INT_STATUS_RX_FBUF-defi.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:11 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: fix EXT_INT_STATUS_RX_FBUF - definitions for MT7986 SoC - -Fix MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH and -MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH definitions for MT7986 (MT7986 is -the only SoC to use them). - -Fixes: de84a090d99a ("net: ethernet: mtk_eth_wed: add wed support for mt7986 chipset") -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -64,8 +64,8 @@ struct mtk_wdma_desc { - #define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID BIT(4) - #define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH BIT(8) - #define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH BIT(9) --#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12) --#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13) -+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(10) /* wed v2 */ -+#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(11) /* wed v2 */ - #define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16) - #define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17) - #define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18) diff --git a/target/linux/generic/backport-5.15/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch b/target/linux/generic/backport-5.15/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch deleted file mode 100644 index c43114fb5b15b4..00000000000000 --- a/target/linux/generic/backport-5.15/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch +++ /dev/null @@ -1,217 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:12 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_soc_data structure - -Introduce mtk_wed_soc_data utility structure to contain per-SoC -definitions. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -48,6 +48,26 @@ struct mtk_wed_flow_block_priv { - struct net_device *dev; - }; - -+static const struct mtk_wed_soc_data mt7622_data = { -+ .regmap = { -+ .tx_bm_tkid = 0x088, -+ .wpdma_rx_ring0 = 0x770, -+ .reset_idx_tx_mask = GENMASK(3, 0), -+ .reset_idx_rx_mask = GENMASK(17, 16), -+ }, -+ .wdma_desc_size = sizeof(struct mtk_wdma_desc), -+}; -+ -+static const struct mtk_wed_soc_data mt7986_data = { -+ .regmap = { -+ .tx_bm_tkid = 0x0c8, -+ .wpdma_rx_ring0 = 0x770, -+ .reset_idx_tx_mask = GENMASK(1, 0), -+ .reset_idx_rx_mask = GENMASK(7, 6), -+ }, -+ .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc), -+}; -+ - static void - wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) - { -@@ -746,7 +766,7 @@ mtk_wed_set_wpdma(struct mtk_wed_device - return; - - wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); -- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx); -+ wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx); - } - - static void -@@ -940,22 +960,10 @@ mtk_wed_hw_init(struct mtk_wed_device *d - wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); - - if (mtk_wed_is_v1(dev->hw)) { -- wed_w32(dev, MTK_WED_TX_BM_TKID, -- FIELD_PREP(MTK_WED_TX_BM_TKID_START, -- dev->wlan.token_start) | -- FIELD_PREP(MTK_WED_TX_BM_TKID_END, -- dev->wlan.token_start + -- dev->wlan.nbuf - 1)); - wed_w32(dev, MTK_WED_TX_BM_DYN_THR, - FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | - MTK_WED_TX_BM_DYN_THR_HI); - } else { -- wed_w32(dev, MTK_WED_TX_BM_TKID_V2, -- FIELD_PREP(MTK_WED_TX_BM_TKID_START, -- dev->wlan.token_start) | -- FIELD_PREP(MTK_WED_TX_BM_TKID_END, -- dev->wlan.token_start + -- dev->wlan.nbuf - 1)); - wed_w32(dev, MTK_WED_TX_BM_DYN_THR, - FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) | - MTK_WED_TX_BM_DYN_THR_HI_V2); -@@ -970,6 +978,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d - MTK_WED_TX_TKID_DYN_THR_HI); - } - -+ wed_w32(dev, dev->hw->soc->regmap.tx_bm_tkid, -+ FIELD_PREP(MTK_WED_TX_BM_TKID_START, dev->wlan.token_start) | -+ FIELD_PREP(MTK_WED_TX_BM_TKID_END, -+ dev->wlan.token_start + dev->wlan.nbuf - 1)); -+ - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - - if (mtk_wed_is_v1(dev->hw)) { -@@ -1104,13 +1117,8 @@ mtk_wed_rx_reset(struct mtk_wed_device * - if (ret) { - mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA); - } else { -- struct mtk_eth *eth = dev->hw->eth; -- -- if (mtk_is_netsys_v2_or_greater(eth)) -- wed_set(dev, MTK_WED_RESET_IDX, -- MTK_WED_RESET_IDX_RX_V2); -- else -- wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX); -+ wed_set(dev, MTK_WED_RESET_IDX, -+ dev->hw->soc->regmap.reset_idx_rx_mask); - wed_w32(dev, MTK_WED_RESET_IDX, 0); - } - -@@ -1163,7 +1171,8 @@ mtk_wed_reset_dma(struct mtk_wed_device - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA); - } else { -- wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX); -+ wed_w32(dev, MTK_WED_RESET_IDX, -+ dev->hw->soc->regmap.reset_idx_tx_mask); - wed_w32(dev, MTK_WED_RESET_IDX, 0); - } - -@@ -1255,7 +1264,6 @@ static int - mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size, - bool reset) - { -- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; - struct mtk_wed_ring *wdma; - - if (idx >= ARRAY_SIZE(dev->rx_wdma)) -@@ -1263,7 +1271,7 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we - - wdma = &dev->rx_wdma[idx]; - if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, -- desc_size, true)) -+ dev->hw->soc->wdma_desc_size, true)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -@@ -1284,7 +1292,6 @@ static int - mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size, - bool reset) - { -- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; - struct mtk_wed_ring *wdma; - - if (idx >= ARRAY_SIZE(dev->tx_wdma)) -@@ -1292,7 +1299,7 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we - - wdma = &dev->tx_wdma[idx]; - if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, -- desc_size, true)) -+ dev->hw->soc->wdma_desc_size, true)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, -@@ -1931,7 +1938,12 @@ void mtk_wed_add_hw(struct device_node * - hw->irq = irq; - hw->version = eth->soc->version; - -- if (mtk_wed_is_v1(hw)) { -+ switch (hw->version) { -+ case 2: -+ hw->soc = &mt7986_data; -+ break; -+ default: -+ case 1: - hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, - "mediatek,pcie-mirror"); - hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, -@@ -1945,6 +1957,8 @@ void mtk_wed_add_hw(struct device_node * - regmap_write(hw->mirror, 0, 0); - regmap_write(hw->mirror, 4, 0); - } -+ hw->soc = &mt7622_data; -+ break; - } - - mtk_wed_hw_add_debugfs(hw); ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -12,7 +12,18 @@ - struct mtk_eth; - struct mtk_wed_wo; - -+struct mtk_wed_soc_data { -+ struct { -+ u32 tx_bm_tkid; -+ u32 wpdma_rx_ring0; -+ u32 reset_idx_tx_mask; -+ u32 reset_idx_rx_mask; -+ } regmap; -+ u32 wdma_desc_size; -+}; -+ - struct mtk_wed_hw { -+ const struct mtk_wed_soc_data *soc; - struct device_node *node; - struct mtk_eth *eth; - struct regmap *regs; ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -100,8 +100,6 @@ struct mtk_wdma_desc { - - #define MTK_WED_TX_BM_BASE 0x084 - --#define MTK_WED_TX_BM_TKID 0x088 --#define MTK_WED_TX_BM_TKID_V2 0x0c8 - #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0) - #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16) - -@@ -160,9 +158,6 @@ struct mtk_wdma_desc { - #define MTK_WED_GLO_CFG_RX_2B_OFFSET BIT(31) - - #define MTK_WED_RESET_IDX 0x20c --#define MTK_WED_RESET_IDX_TX GENMASK(3, 0) --#define MTK_WED_RESET_IDX_RX GENMASK(17, 16) --#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6) - #define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30) - - #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) -@@ -286,7 +281,6 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24) - - #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c --#define MTK_WED_WPDMA_RX_RING 0x770 - - #define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4) - #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4) diff --git a/target/linux/generic/backport-5.15/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch b/target/linux/generic/backport-5.15/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch deleted file mode 100644 index f53b822224c143..00000000000000 --- a/target/linux/generic/backport-5.15/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch +++ /dev/null @@ -1,1280 +0,0 @@ -From: Sujuan Chen -Date: Mon, 18 Sep 2023 12:29:13 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: introduce WED support for MT7988 - -Similar to MT7986 and MT7622, enable Wireless Ethernet Ditpatcher for -MT7988 in order to offload traffic forwarded from LAN/WLAN to WLAN/LAN - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -195,6 +195,7 @@ static const struct mtk_reg_map mt7988_r - .wdma_base = { - [0] = 0x4800, - [1] = 0x4c00, -+ [2] = 0x5000, - }, - .pse_iq_sta = 0x0180, - .pse_oq_sta = 0x01a0, ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1129,7 +1129,7 @@ struct mtk_reg_map { - u32 gdm1_cnt; - u32 gdma_to_ppe0; - u32 ppe_base; -- u32 wdma_base[2]; -+ u32 wdma_base[3]; - u32 pse_iq_sta; - u32 pse_oq_sta; - }; ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -201,6 +201,9 @@ mtk_flow_set_output_device(struct mtk_et - case 1: - pse_port = PSE_WDMA1_PORT; - break; -+ case 2: -+ pse_port = PSE_WDMA2_PORT; -+ break; - default: - return -EINVAL; - } ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -16,17 +16,19 @@ - #include - #include - #include "mtk_eth_soc.h" --#include "mtk_wed_regs.h" - #include "mtk_wed.h" - #include "mtk_ppe.h" - #include "mtk_wed_wo.h" - - #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000) - --#define MTK_WED_PKT_SIZE 1900 -+#define MTK_WED_PKT_SIZE 1920 - #define MTK_WED_BUF_SIZE 2048 -+#define MTK_WED_PAGE_BUF_SIZE 128 - #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048) -+#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128) - #define MTK_WED_RX_RING_SIZE 1536 -+#define MTK_WED_RX_PG_BM_CNT 8192 - - #define MTK_WED_TX_RING_SIZE 2048 - #define MTK_WED_WDMA_RING_SIZE 1024 -@@ -40,7 +42,10 @@ - #define MTK_WED_RRO_QUE_CNT 8192 - #define MTK_WED_MIOD_ENTRY_CNT 128 - --static struct mtk_wed_hw *hw_list[2]; -+#define MTK_WED_TX_BM_DMA_SIZE 65536 -+#define MTK_WED_TX_BM_PKT_CNT 32768 -+ -+static struct mtk_wed_hw *hw_list[3]; - static DEFINE_MUTEX(hw_lock); - - struct mtk_wed_flow_block_priv { -@@ -55,6 +60,7 @@ static const struct mtk_wed_soc_data mt7 - .reset_idx_tx_mask = GENMASK(3, 0), - .reset_idx_rx_mask = GENMASK(17, 16), - }, -+ .tx_ring_desc_size = sizeof(struct mtk_wdma_desc), - .wdma_desc_size = sizeof(struct mtk_wdma_desc), - }; - -@@ -65,6 +71,18 @@ static const struct mtk_wed_soc_data mt7 - .reset_idx_tx_mask = GENMASK(1, 0), - .reset_idx_rx_mask = GENMASK(7, 6), - }, -+ .tx_ring_desc_size = sizeof(struct mtk_wdma_desc), -+ .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc), -+}; -+ -+static const struct mtk_wed_soc_data mt7988_data = { -+ .regmap = { -+ .tx_bm_tkid = 0x0c8, -+ .wpdma_rx_ring0 = 0x7d0, -+ .reset_idx_tx_mask = GENMASK(1, 0), -+ .reset_idx_rx_mask = GENMASK(7, 6), -+ }, -+ .tx_ring_desc_size = sizeof(struct mtk_wed_bm_desc), - .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc), - }; - -@@ -319,33 +337,38 @@ out: - static int - mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) - { -+ u32 desc_size = dev->hw->soc->tx_ring_desc_size; -+ int i, page_idx = 0, n_pages, ring_size; -+ int token = dev->wlan.token_start; - struct mtk_wed_buf *page_list; -- struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -- int token = dev->wlan.token_start; -- int ring_size; -- int n_pages; -- int i, page_idx; -+ void *desc_ptr; - -- ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1); -- n_pages = ring_size / MTK_WED_BUF_PER_PAGE; -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) { -+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1); -+ dev->tx_buf_ring.size = ring_size; -+ } else { -+ dev->tx_buf_ring.size = MTK_WED_TX_BM_DMA_SIZE; -+ ring_size = MTK_WED_TX_BM_PKT_CNT; -+ } -+ n_pages = dev->tx_buf_ring.size / MTK_WED_BUF_PER_PAGE; - - page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL); - if (!page_list) - return -ENOMEM; - -- dev->tx_buf_ring.size = ring_size; - dev->tx_buf_ring.pages = page_list; - -- desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc), -- &desc_phys, GFP_KERNEL); -- if (!desc) -+ desc_ptr = dma_alloc_coherent(dev->hw->dev, -+ dev->tx_buf_ring.size * desc_size, -+ &desc_phys, GFP_KERNEL); -+ if (!desc_ptr) - return -ENOMEM; - -- dev->tx_buf_ring.desc = desc; -+ dev->tx_buf_ring.desc = desc_ptr; - dev->tx_buf_ring.desc_phys = desc_phys; - -- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) { -+ for (i = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) { - dma_addr_t page_phys, buf_phys; - struct page *page; - void *buf; -@@ -371,28 +394,31 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d - buf_phys = page_phys; - - for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) { -- u32 txd_size; -- u32 ctrl; -- -- txd_size = dev->wlan.init_buf(buf, buf_phys, token++); -+ struct mtk_wdma_desc *desc = desc_ptr; - - desc->buf0 = cpu_to_le32(buf_phys); -- desc->buf1 = cpu_to_le32(buf_phys + txd_size); -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) { -+ u32 txd_size, ctrl; - -- if (mtk_wed_is_v1(dev->hw)) -- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -- MTK_WED_BUF_SIZE - txd_size) | -- MTK_WDMA_DESC_CTRL_LAST_SEG1; -- else -- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2, -- MTK_WED_BUF_SIZE - txd_size) | -- MTK_WDMA_DESC_CTRL_LAST_SEG0; -- desc->ctrl = cpu_to_le32(ctrl); -- desc->info = 0; -- desc++; -+ txd_size = dev->wlan.init_buf(buf, buf_phys, -+ token++); -+ desc->buf1 = cpu_to_le32(buf_phys + txd_size); -+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size); -+ if (mtk_wed_is_v1(dev->hw)) -+ ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG1 | -+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -+ MTK_WED_BUF_SIZE - txd_size); -+ else -+ ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG0 | -+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2, -+ MTK_WED_BUF_SIZE - txd_size); -+ desc->ctrl = cpu_to_le32(ctrl); -+ desc->info = 0; -+ } else { -+ desc->ctrl = cpu_to_le32(token << 16); -+ } - -+ desc_ptr += desc_size; - buf += MTK_WED_BUF_SIZE; - buf_phys += MTK_WED_BUF_SIZE; - } -@@ -408,31 +434,31 @@ static void - mtk_wed_free_tx_buffer(struct mtk_wed_device *dev) - { - struct mtk_wed_buf *page_list = dev->tx_buf_ring.pages; -- struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc; -- int page_idx; -- int i; -+ struct mtk_wed_hw *hw = dev->hw; -+ int i, page_idx = 0; - - if (!page_list) - return; - -- if (!desc) -+ if (!dev->tx_buf_ring.desc) - goto free_pagelist; - -- for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size; -- i += MTK_WED_BUF_PER_PAGE) { -- dma_addr_t buf_addr = page_list[page_idx].phy_addr; -+ for (i = 0; i < dev->tx_buf_ring.size; i += MTK_WED_BUF_PER_PAGE) { -+ dma_addr_t page_phy = page_list[page_idx].phy_addr; - void *page = page_list[page_idx++].p; - - if (!page) - break; - -- dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE, -+ dma_unmap_page(dev->hw->dev, page_phy, PAGE_SIZE, - DMA_BIDIRECTIONAL); - __free_page(page); - } - -- dma_free_coherent(dev->hw->dev, dev->tx_buf_ring.size * sizeof(*desc), -- desc, dev->tx_buf_ring.desc_phys); -+ dma_free_coherent(dev->hw->dev, -+ dev->tx_buf_ring.size * hw->soc->tx_ring_desc_size, -+ dev->tx_buf_ring.desc, -+ dev->tx_buf_ring.desc_phys); - - free_pagelist: - kfree(page_list); -@@ -517,13 +543,23 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - { - u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; - -- if (mtk_wed_is_v1(dev->hw)) -+ switch (dev->hw->version) { -+ case 1: - mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; -- else -+ break; -+ case 2: - mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | - MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | - MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | - MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; -+ break; -+ case 3: -+ mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | -+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; -+ break; -+ default: -+ break; -+ } - - if (!dev->hw->num_flows) - mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; -@@ -535,6 +571,9 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - static void - mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable) - { -+ if (!mtk_wed_is_v2(dev->hw)) -+ return; -+ - if (enable) { - wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR); - wed_w32(dev, MTK_WED_TXP_DW1, -@@ -609,6 +648,14 @@ mtk_wed_dma_disable(struct mtk_wed_devic - MTK_WED_WPDMA_RX_D_RX_DRV_EN); - wed_clr(dev, MTK_WED_WDMA_GLO_CFG, - MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); -+ -+ if (mtk_wed_is_v3_or_greater(dev->hw) && -+ mtk_wed_get_rx_capa(dev)) { -+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, -+ MTK_WDMA_PREF_TX_CFG_PREF_EN); -+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, -+ MTK_WDMA_PREF_RX_CFG_PREF_EN); -+ } - } - - mtk_wed_set_512_support(dev, false); -@@ -651,6 +698,14 @@ mtk_wed_deinit(struct mtk_wed_device *de - MTK_WED_CTRL_RX_ROUTE_QM_EN | - MTK_WED_CTRL_WED_RX_BM_EN | - MTK_WED_CTRL_RX_RRO_QM_EN); -+ -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN); -+ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_TX_AMSDU); -+ wed_clr(dev, MTK_WED_PCIE_INT_CTRL, -+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | -+ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER); -+ } - } - - static void -@@ -700,21 +755,37 @@ mtk_wed_detach(struct mtk_wed_device *de - mutex_unlock(&hw_lock); - } - --#define PCIE_BASE_ADDR0 0x11280000 - static void - mtk_wed_bus_init(struct mtk_wed_device *dev) - { - switch (dev->wlan.bus_type) { - case MTK_WED_BUS_PCIE: { - struct device_node *np = dev->hw->eth->dev->of_node; -- struct regmap *regs; - -- regs = syscon_regmap_lookup_by_phandle(np, -- "mediatek,wed-pcie"); -- if (IS_ERR(regs)) -- break; -+ if (mtk_wed_is_v2(dev->hw)) { -+ struct regmap *regs; -+ -+ regs = syscon_regmap_lookup_by_phandle(np, -+ "mediatek,wed-pcie"); -+ if (IS_ERR(regs)) -+ break; - -- regmap_update_bits(regs, 0, BIT(0), BIT(0)); -+ regmap_update_bits(regs, 0, BIT(0), BIT(0)); -+ } -+ -+ if (dev->wlan.msi) { -+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, -+ dev->hw->pcie_base | 0xc08); -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, -+ dev->hw->pcie_base | 0xc04); -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(8)); -+ } else { -+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, -+ dev->hw->pcie_base | 0x180); -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, -+ dev->hw->pcie_base | 0x184); -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); -+ } - - wed_w32(dev, MTK_WED_PCIE_INT_CTRL, - FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); -@@ -722,19 +793,9 @@ mtk_wed_bus_init(struct mtk_wed_device * - /* pcie interrupt control: pola/source selection */ - wed_set(dev, MTK_WED_PCIE_INT_CTRL, - MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | -- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); -- wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -- -- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); -- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); -- -- /* pcie interrupt status trigger register */ -- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); -- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); -- -- /* pola setting */ -- wed_set(dev, MTK_WED_PCIE_INT_CTRL, -- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); -+ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER | -+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, -+ dev->hw->index)); - break; - } - case MTK_WED_BUS_AXI: -@@ -772,18 +833,19 @@ mtk_wed_set_wpdma(struct mtk_wed_device - static void - mtk_wed_hw_init_early(struct mtk_wed_device *dev) - { -- u32 mask, set; -+ u32 set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2); -+ u32 mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE; - - mtk_wed_deinit(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); - mtk_wed_set_wpdma(dev); - -- mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE | -- MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE | -- MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE; -- set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) | -- MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP | -- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) { -+ mask |= MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE | -+ MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE; -+ set |= MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP | -+ MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; -+ } - wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); - - if (mtk_wed_is_v1(dev->hw)) { -@@ -931,11 +993,18 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_ - } - - /* configure RX_ROUTE_QM */ -- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT); -- wed_set(dev, MTK_WED_RTQM_GLO_CFG, -- FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index)); -- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ if (mtk_wed_is_v2(dev->hw)) { -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT); -+ wed_set(dev, MTK_WED_RTQM_GLO_CFG, -+ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, -+ 0x3 + dev->hw->index)); -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ } else { -+ wed_set(dev, MTK_WED_RTQM_ENQ_CFG0, -+ FIELD_PREP(MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT, -+ 0x3 + dev->hw->index)); -+ } - /* enable RX_ROUTE_QM */ - wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); - } -@@ -948,22 +1017,30 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - dev->init_done = true; - mtk_wed_set_ext_int(dev, false); -- wed_w32(dev, MTK_WED_TX_BM_CTRL, -- MTK_WED_TX_BM_CTRL_PAUSE | -- FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, -- dev->tx_buf_ring.size / 128) | -- FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, -- MTK_WED_TX_RING_SIZE / 256)); - - wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys); -- - wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); - - if (mtk_wed_is_v1(dev->hw)) { -+ wed_w32(dev, MTK_WED_TX_BM_CTRL, -+ MTK_WED_TX_BM_CTRL_PAUSE | -+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, -+ dev->tx_buf_ring.size / 128) | -+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, -+ MTK_WED_TX_RING_SIZE / 256)); - wed_w32(dev, MTK_WED_TX_BM_DYN_THR, - FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | - MTK_WED_TX_BM_DYN_THR_HI); -- } else { -+ } else if (mtk_wed_is_v2(dev->hw)) { -+ wed_w32(dev, MTK_WED_TX_BM_CTRL, -+ MTK_WED_TX_BM_CTRL_PAUSE | -+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, -+ dev->tx_buf_ring.size / 128) | -+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, -+ MTK_WED_TX_RING_SIZE / 256)); -+ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, -+ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | -+ MTK_WED_TX_TKID_DYN_THR_HI); - wed_w32(dev, MTK_WED_TX_BM_DYN_THR, - FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) | - MTK_WED_TX_BM_DYN_THR_HI_V2); -@@ -973,9 +1050,6 @@ mtk_wed_hw_init(struct mtk_wed_device *d - dev->tx_buf_ring.size / 128) | - FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM, - dev->tx_buf_ring.size / 128)); -- wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, -- FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | -- MTK_WED_TX_TKID_DYN_THR_HI); - } - - wed_w32(dev, dev->hw->soc->regmap.tx_bm_tkid, -@@ -985,26 +1059,62 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ /* switch to new bm architecture */ -+ wed_clr(dev, MTK_WED_TX_BM_CTRL, -+ MTK_WED_TX_BM_CTRL_LEGACY_EN); -+ -+ wed_w32(dev, MTK_WED_TX_TKID_CTRL, -+ MTK_WED_TX_TKID_CTRL_PAUSE | -+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3, -+ dev->wlan.nbuf / 128) | -+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3, -+ dev->wlan.nbuf / 128)); -+ /* return SKBID + SDP back to bm */ -+ wed_set(dev, MTK_WED_TX_TKID_CTRL, -+ MTK_WED_TX_TKID_CTRL_FREE_FORMAT); -+ -+ wed_w32(dev, MTK_WED_TX_BM_INIT_PTR, -+ MTK_WED_TX_BM_PKT_CNT | -+ MTK_WED_TX_BM_INIT_SW_TAIL_IDX); -+ } -+ - if (mtk_wed_is_v1(dev->hw)) { - wed_set(dev, MTK_WED_CTRL, - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -- } else { -- wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); -- if (mtk_wed_get_rx_capa(dev)) { -- /* rx hw init */ -- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -- MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -- MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -- -- mtk_wed_rx_buffer_hw_init(dev); -- mtk_wed_rro_hw_init(dev); -- mtk_wed_route_qm_hw_init(dev); -- } -+ } else if (mtk_wed_get_rx_capa(dev)) { -+ /* rx hw init */ -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -+ -+ /* reset prefetch index of ring */ -+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX, -+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR); -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX, -+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR); -+ -+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX, -+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR); -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX, -+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR); -+ -+ /* reset prefetch FIFO of ring */ -+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG, -+ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR | -+ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR); -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG, 0); -+ -+ mtk_wed_rx_buffer_hw_init(dev); -+ mtk_wed_rro_hw_init(dev); -+ mtk_wed_route_qm_hw_init(dev); - } - - wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); -+ if (!mtk_wed_is_v1(dev->hw)) -+ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); - } - - static void -@@ -1302,6 +1412,24 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we - dev->hw->soc->wdma_desc_size, true)) - return -ENOMEM; - -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ struct mtk_wdma_desc *desc = wdma->desc; -+ int i; -+ -+ for (i = 0; i < MTK_WED_WDMA_RING_SIZE; i++) { -+ desc->buf0 = 0; -+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ desc->buf1 = 0; -+ desc->info = cpu_to_le32(MTK_WDMA_TXD0_DESC_INFO_DMA_DONE); -+ desc++; -+ desc->buf0 = 0; -+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ desc->buf1 = 0; -+ desc->info = cpu_to_le32(MTK_WDMA_TXD1_DESC_INFO_DMA_DONE); -+ desc++; -+ } -+ } -+ - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, - wdma->desc_phys); - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT, -@@ -1367,6 +1495,9 @@ mtk_wed_configure_irq(struct mtk_wed_dev - - wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); - } else { -+ if (mtk_wed_is_v3_or_greater(dev->hw)) -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_TKID_ALI_EN); -+ - /* initail tx interrupt trigger */ - wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, - MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | -@@ -1419,33 +1550,60 @@ mtk_wed_dma_enable(struct mtk_wed_device - { - int i; - -- wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, -+ MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -+ wdma_set(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_TX_DMA_EN | -+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); -+ wed_set(dev, MTK_WED_WPDMA_CTRL, MTK_WED_WPDMA_CTRL_SDL1_FIXED); -+ } else { -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR); -+ wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); -+ } - - wed_set(dev, MTK_WED_GLO_CFG, - MTK_WED_GLO_CFG_TX_DMA_EN | - MTK_WED_GLO_CFG_RX_DMA_EN); -- wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -+ - wed_set(dev, MTK_WED_WDMA_GLO_CFG, - MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); - -- wdma_set(dev, MTK_WDMA_GLO_CFG, -- MTK_WDMA_GLO_CFG_TX_DMA_EN | -- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); -- - if (mtk_wed_is_v1(dev->hw)) { - wdma_set(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); - return; - } - -- wed_set(dev, MTK_WED_WPDMA_CTRL, -- MTK_WED_WPDMA_CTRL_SDL1_FIXED); - wed_set(dev, MTK_WED_WPDMA_GLO_CFG, - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -+ -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ FIELD_PREP(MTK_WED_WDMA_RX_PREF_BURST_SIZE, 0x10) | -+ FIELD_PREP(MTK_WED_WDMA_RX_PREF_LOW_THRES, 0x8)); -+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_DDONE2_EN); -+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN); -+ -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST); -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4); -+ -+ wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); -+ } -+ - wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, - MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | - MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); -@@ -1457,11 +1615,22 @@ mtk_wed_dma_enable(struct mtk_wed_device - MTK_WED_WDMA_GLO_CFG_TX_DRV_EN | - MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); - -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RXD_READ_LEN); - wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, - MTK_WED_WPDMA_RX_D_RX_DRV_EN | - FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) | -- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, -- 0x2)); -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, 0x2)); -+ -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, -+ MTK_WED_WPDMA_RX_D_PREF_EN | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE, 0x10) | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_LOW_THRES, 0x8)); -+ -+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN); -+ wdma_set(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN); -+ wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); -+ } - - for (i = 0; i < MTK_WED_RX_QUEUES; i++) - mtk_wed_check_wfdma_rx_fill(dev, i); -@@ -1501,6 +1670,12 @@ mtk_wed_start(struct mtk_wed_device *dev - wed_r32(dev, MTK_WED_EXT_INT_MASK1); - wed_r32(dev, MTK_WED_EXT_INT_MASK2); - -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_w32(dev, MTK_WED_EXT_INT_MASK3, -+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); -+ wed_r32(dev, MTK_WED_EXT_INT_MASK3); -+ } -+ - if (mtk_wed_rro_cfg(dev)) - return; - } -@@ -1552,6 +1727,7 @@ mtk_wed_attach(struct mtk_wed_device *de - dev->irq = hw->irq; - dev->wdma_idx = hw->index; - dev->version = hw->version; -+ dev->hw->pcie_base = mtk_wed_get_pcie_base(dev); - - if (hw->eth->dma_dev == hw->eth->dev && - of_dma_is_coherent(hw->eth->dev->of_node)) -@@ -1619,6 +1795,23 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - ring->reg_base = MTK_WED_RING_TX(idx); - ring->wpdma = regs; - -+ if (mtk_wed_is_v3_or_greater(dev->hw) && idx == 1) { -+ /* reset prefetch index */ -+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR | -+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR); -+ -+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR | -+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR); -+ -+ /* reset prefetch FIFO */ -+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, -+ MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR | -+ MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR); -+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, 0); -+ } -+ - /* WED -> WPDMA */ - wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys); - wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_TX_RING_SIZE); -@@ -1693,15 +1886,13 @@ mtk_wed_rx_ring_setup(struct mtk_wed_dev - static u32 - mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) - { -- u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; -+ u32 val, ext_mask; - -- if (mtk_wed_is_v1(dev->hw)) -- ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; -+ if (mtk_wed_is_v3_or_greater(dev->hw)) -+ ext_mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | -+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; - else -- ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -- MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | -- MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | -- MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; -+ ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; - - val = wed_r32(dev, MTK_WED_EXT_INT_STATUS); - wed_w32(dev, MTK_WED_EXT_INT_STATUS, val); -@@ -1942,6 +2133,9 @@ void mtk_wed_add_hw(struct device_node * - case 2: - hw->soc = &mt7986_data; - break; -+ case 3: -+ hw->soc = &mt7988_data; -+ break; - default: - case 1: - hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -9,6 +9,8 @@ - #include - #include - -+#include "mtk_wed_regs.h" -+ - struct mtk_eth; - struct mtk_wed_wo; - -@@ -19,6 +21,7 @@ struct mtk_wed_soc_data { - u32 reset_idx_tx_mask; - u32 reset_idx_rx_mask; - } regmap; -+ u32 tx_ring_desc_size; - u32 wdma_desc_size; - }; - -@@ -35,6 +38,7 @@ struct mtk_wed_hw { - struct dentry *debugfs_dir; - struct mtk_wed_device *wed_dev; - struct mtk_wed_wo *wed_wo; -+ u32 pcie_base; - u32 debugfs_reg; - u32 num_flows; - u8 version; -@@ -61,6 +65,16 @@ static inline bool mtk_wed_is_v2(struct - return hw->version == 2; - } - -+static inline bool mtk_wed_is_v3(struct mtk_wed_hw *hw) -+{ -+ return hw->version == 3; -+} -+ -+static inline bool mtk_wed_is_v3_or_greater(struct mtk_wed_hw *hw) -+{ -+ return hw->version > 2; -+} -+ - static inline void - wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val) - { -@@ -143,6 +157,21 @@ wpdma_txfree_w32(struct mtk_wed_device * - writel(val, dev->txfree_ring.wpdma + reg); - } - -+static inline u32 mtk_wed_get_pcie_base(struct mtk_wed_device *dev) -+{ -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) -+ return MTK_WED_PCIE_BASE; -+ -+ switch (dev->hw->index) { -+ case 1: -+ return MTK_WED_PCIE_BASE1; -+ case 2: -+ return MTK_WED_PCIE_BASE2; -+ default: -+ return MTK_WED_PCIE_BASE0; -+ } -+} -+ - void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, - void __iomem *wdma, phys_addr_t wdma_phy, - int index); ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -331,10 +331,22 @@ mtk_wed_mcu_load_firmware(struct mtk_wed - wo->hw->index + 1); - - /* load firmware */ -- if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed")) -- fw_name = MT7981_FIRMWARE_WO; -- else -- fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; -+ switch (wo->hw->version) { -+ case 2: -+ if (of_device_is_compatible(wo->hw->node, -+ "mediatek,mt7981-wed")) -+ fw_name = MT7981_FIRMWARE_WO; -+ else -+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 -+ : MT7986_FIRMWARE_WO0; -+ break; -+ case 3: -+ fw_name = wo->hw->index ? MT7988_FIRMWARE_WO1 -+ : MT7988_FIRMWARE_WO0; -+ break; -+ default: -+ return -EINVAL; -+ } - - ret = request_firmware(&fw, fw_name, wo->hw->dev); - if (ret) -@@ -355,15 +367,16 @@ mtk_wed_mcu_load_firmware(struct mtk_wed - } - - /* set the start address */ -- boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR -- : MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR; -+ if (!mtk_wed_is_v3_or_greater(wo->hw) && wo->hw->index) -+ boot_cr = MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR; -+ else -+ boot_cr = MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR; - wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16); - /* wo firmware reset */ - wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00); - -- val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR); -- val |= wo->hw->index ? MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK -- : MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK; -+ val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) | -+ MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK; - wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val); - out: - release_firmware(fw); -@@ -398,3 +411,5 @@ int mtk_wed_mcu_init(struct mtk_wed_wo * - MODULE_FIRMWARE(MT7981_FIRMWARE_WO); - MODULE_FIRMWARE(MT7986_FIRMWARE_WO0); - MODULE_FIRMWARE(MT7986_FIRMWARE_WO1); -+MODULE_FIRMWARE(MT7988_FIRMWARE_WO0); -+MODULE_FIRMWARE(MT7988_FIRMWARE_WO1); ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -13,6 +13,9 @@ - #define MTK_WDMA_DESC_CTRL_LAST_SEG0 BIT(30) - #define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31) - -+#define MTK_WDMA_TXD0_DESC_INFO_DMA_DONE BIT(29) -+#define MTK_WDMA_TXD1_DESC_INFO_DMA_DONE BIT(31) -+ - struct mtk_wdma_desc { - __le32 buf0; - __le32 ctrl; -@@ -37,6 +40,7 @@ struct mtk_wdma_desc { - #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19) - #define MTK_WED_RESET_RX_RRO_QM BIT(20) - #define MTK_WED_RESET_RX_ROUTE_QM BIT(21) -+#define MTK_WED_RESET_TX_AMSDU BIT(22) - #define MTK_WED_RESET_WED BIT(31) - - #define MTK_WED_CTRL 0x00c -@@ -44,6 +48,9 @@ struct mtk_wdma_desc { - #define MTK_WED_CTRL_WPDMA_INT_AGENT_BUSY BIT(1) - #define MTK_WED_CTRL_WDMA_INT_AGENT_EN BIT(2) - #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3) -+#define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5) -+#define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6) -+#define MTK_WED_CTRL_WED_RX_PG_BM_BUSY BIT(7) - #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8) - #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9) - #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10) -@@ -54,9 +61,14 @@ struct mtk_wdma_desc { - #define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15) - #define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16) - #define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17) -+#define MTK_WED_CTRL_TX_TKID_ALI_EN BIT(20) -+#define MTK_WED_CTRL_TX_TKID_ALI_BUSY BIT(21) -+#define MTK_WED_CTRL_TX_AMSDU_EN BIT(22) -+#define MTK_WED_CTRL_TX_AMSDU_BUSY BIT(23) - #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24) - #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25) - #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28) -+#define MTK_WED_CTRL_FLD_MIB_RD_CLR BIT(28) - - #define MTK_WED_EXT_INT_STATUS 0x020 - #define MTK_WED_EXT_INT_STATUS_TF_LEN_ERR BIT(0) -@@ -89,6 +101,7 @@ struct mtk_wdma_desc { - #define MTK_WED_EXT_INT_MASK 0x028 - #define MTK_WED_EXT_INT_MASK1 0x02c - #define MTK_WED_EXT_INT_MASK2 0x030 -+#define MTK_WED_EXT_INT_MASK3 0x034 - - #define MTK_WED_STATUS 0x060 - #define MTK_WED_STATUS_TX GENMASK(15, 8) -@@ -96,9 +109,14 @@ struct mtk_wdma_desc { - #define MTK_WED_TX_BM_CTRL 0x080 - #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0) - #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16) -+#define MTK_WED_TX_BM_CTRL_LEGACY_EN BIT(26) -+#define MTK_WED_TX_TKID_CTRL_FREE_FORMAT BIT(27) - #define MTK_WED_TX_BM_CTRL_PAUSE BIT(28) - - #define MTK_WED_TX_BM_BASE 0x084 -+#define MTK_WED_TX_BM_INIT_PTR 0x088 -+#define MTK_WED_TX_BM_SW_TAIL_IDX GENMASK(16, 0) -+#define MTK_WED_TX_BM_INIT_SW_TAIL_IDX BIT(16) - - #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0) - #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16) -@@ -122,6 +140,9 @@ struct mtk_wdma_desc { - #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16) - #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28) - -+#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3 GENMASK(7, 0) -+#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3 GENMASK(23, 16) -+ - #define MTK_WED_TX_TKID_DYN_THR 0x0e0 - #define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0) - #define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16) -@@ -199,12 +220,15 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_PKT_PROC BIT(5) - #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC BIT(6) - #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_CRX_SYNC BIT(7) --#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(18, 16) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(15, 12) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4 BIT(18) - #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNSUPPORT_FMT BIT(19) --#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UEVENT_PKT_FMT_CHK BIT(20) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK BIT(20) - #define MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR BIT(21) - #define MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP BIT(24) -+#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST BIT(25) - #define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28) -+#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK BIT(30) - - #define MTK_WED_WPDMA_RESET_IDX 0x50c - #define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0) -@@ -250,9 +274,10 @@ struct mtk_wdma_desc { - #define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16) - - #define MTK_WED_PCIE_INT_CTRL 0x57c --#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20) --#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16) - #define MTK_WED_PCIE_INT_CTRL_POLL_EN GENMASK(13, 12) -+#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16) -+#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20) -+#define MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER BIT(21) - - #define MTK_WED_WPDMA_CFG_BASE 0x580 - #define MTK_WED_WPDMA_CFG_INT_MASK 0x584 -@@ -286,6 +311,20 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4) - #define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c - -+#define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4 -+#define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0) -+#define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8) -+#define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16) -+ -+#define MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX 0x7b8 -+#define MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR BIT(15) -+ -+#define MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX 0x7bc -+ -+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG 0x7c0 -+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR BIT(0) -+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR BIT(16) -+ - #define MTK_WED_WDMA_RING_TX 0x800 - - #define MTK_WED_WDMA_TX_MIB 0x810 -@@ -293,6 +332,18 @@ struct mtk_wdma_desc { - #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10) - #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4) - -+#define MTK_WED_WDMA_RX_PREF_CFG 0x950 -+#define MTK_WED_WDMA_RX_PREF_EN BIT(0) -+#define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8) -+#define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16) -+#define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24) -+#define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25) -+#define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26) -+ -+#define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C -+#define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0) -+#define MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR BIT(16) -+ - #define MTK_WED_WDMA_GLO_CFG 0xa04 - #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0) - #define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1) -@@ -325,6 +376,7 @@ struct mtk_wdma_desc { - #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16) - - #define MTK_WED_WDMA_INT_CTRL 0xa2c -+#define MTK_WED_WDMA_INT_POLL_PRD GENMASK(7, 0) - #define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16) - - #define MTK_WED_WDMA_CFG_BASE 0xaa0 -@@ -388,6 +440,18 @@ struct mtk_wdma_desc { - #define MTK_WDMA_INT_GRP1 0x250 - #define MTK_WDMA_INT_GRP2 0x254 - -+#define MTK_WDMA_PREF_TX_CFG 0x2d0 -+#define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0) -+ -+#define MTK_WDMA_PREF_RX_CFG 0x2dc -+#define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0) -+ -+#define MTK_WDMA_WRBK_TX_CFG 0x300 -+#define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30) -+ -+#define MTK_WDMA_WRBK_RX_CFG 0x344 -+#define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30) -+ - #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0) - #define MTK_PCIE_MIRROR_MAP_EN BIT(0) - #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1) -@@ -401,6 +465,30 @@ struct mtk_wdma_desc { - #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5) - #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20) - -+#define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c -+#define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28 -+#define MTK_WED_RTQM_IGRS0_I2H_PKT_CNT(_n) (0xb2c + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS0_FDROP_CNT 0xb34 -+ -+#define MTK_WED_RTQM_IGRS1_I2HW_DMAD_CNT 0xb44 -+#define MTK_WED_RTQM_IGRS1_I2H_DMAD_CNT(_n) (0xb48 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS1_I2HW_PKT_CNT 0xb50 -+#define MTK_WED_RTQM_IGRS1_I2H_PKT_CNT(_n) (0xb54 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS1_FDROP_CNT 0xb5c -+ -+#define MTK_WED_RTQM_IGRS2_I2HW_DMAD_CNT 0xb6c -+#define MTK_WED_RTQM_IGRS2_I2H_DMAD_CNT(_n) (0xb70 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS2_I2HW_PKT_CNT 0xb78 -+#define MTK_WED_RTQM_IGRS2_I2H_PKT_CNT(_n) (0xb7c + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS2_FDROP_CNT 0xb84 -+ -+#define MTK_WED_RTQM_IGRS3_I2HW_DMAD_CNT 0xb94 -+#define MTK_WED_RTQM_IGRS3_I2H_DMAD_CNT(_n) (0xb98 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS3_I2HW_PKT_CNT 0xba0 -+#define MTK_WED_RTQM_IGRS3_I2H_PKT_CNT(_n) (0xba4 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS3_FDROP_CNT 0xbac -+ - #define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4) - #define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4) - #define MTK_WED_RTQM_Q2N_MIB 0xb80 -@@ -409,6 +497,24 @@ struct mtk_wdma_desc { - #define MTK_WED_RTQM_Q2B_MIB 0xb8c - #define MTK_WED_RTQM_PFDBK_MIB 0xb90 - -+#define MTK_WED_RTQM_ENQ_CFG0 0xbb8 -+#define MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT GENMASK(15, 12) -+ -+#define MTK_WED_RTQM_FDROP_MIB 0xb84 -+#define MTK_WED_RTQM_ENQ_I2Q_DMAD_CNT 0xbbc -+#define MTK_WED_RTQM_ENQ_I2N_DMAD_CNT 0xbc0 -+#define MTK_WED_RTQM_ENQ_I2Q_PKT_CNT 0xbc4 -+#define MTK_WED_RTQM_ENQ_I2N_PKT_CNT 0xbc8 -+#define MTK_WED_RTQM_ENQ_USED_ENTRY_CNT 0xbcc -+#define MTK_WED_RTQM_ENQ_ERR_CNT 0xbd0 -+ -+#define MTK_WED_RTQM_DEQ_DMAD_CNT 0xbd8 -+#define MTK_WED_RTQM_DEQ_Q2I_DMAD_CNT 0xbdc -+#define MTK_WED_RTQM_DEQ_PKT_CNT 0xbe0 -+#define MTK_WED_RTQM_DEQ_Q2I_PKT_CNT 0xbe4 -+#define MTK_WED_RTQM_DEQ_USED_PFDBK_CNT 0xbe8 -+#define MTK_WED_RTQM_DEQ_ERR_CNT 0xbec -+ - #define MTK_WED_RROQM_GLO_CFG 0xc04 - #define MTK_WED_RROQM_RST_IDX 0xc08 - #define MTK_WED_RROQM_RST_IDX_MIOD BIT(0) -@@ -458,7 +564,116 @@ struct mtk_wdma_desc { - #define MTK_WED_RX_BM_INTF 0xd9c - #define MTK_WED_RX_BM_ERR_STS 0xda8 - -+#define MTK_RRO_IND_CMD_SIGNATURE 0xe00 -+#define MTK_RRO_IND_CMD_DMA_IDX GENMASK(11, 0) -+#define MTK_RRO_IND_CMD_MAGIC_CNT GENMASK(30, 28) -+ -+#define MTK_WED_IND_CMD_RX_CTRL0 0xe04 -+#define MTK_WED_IND_CMD_PROC_IDX GENMASK(11, 0) -+#define MTK_WED_IND_CMD_PREFETCH_FREE_CNT GENMASK(19, 16) -+#define MTK_WED_IND_CMD_MAGIC_CNT GENMASK(30, 28) -+ -+#define MTK_WED_IND_CMD_RX_CTRL1 0xe08 -+#define MTK_WED_IND_CMD_RX_CTRL2 0xe0c -+#define MTK_WED_IND_CMD_MAX_CNT GENMASK(11, 0) -+#define MTK_WED_IND_CMD_BASE_M GENMASK(19, 16) -+ -+#define MTK_WED_RRO_CFG0 0xe10 -+#define MTK_WED_RRO_CFG1 0xe14 -+#define MTK_WED_RRO_CFG1_MAX_WIN_SZ GENMASK(31, 29) -+#define MTK_WED_RRO_CFG1_ACK_SN_BASE_M GENMASK(19, 16) -+#define MTK_WED_RRO_CFG1_PARTICL_SE_ID GENMASK(11, 0) -+ -+#define MTK_WED_ADDR_ELEM_CFG0 0xe18 -+#define MTK_WED_ADDR_ELEM_CFG1 0xe1c -+#define MTK_WED_ADDR_ELEM_PREFETCH_FREE_CNT GENMASK(19, 16) -+ -+#define MTK_WED_ADDR_ELEM_TBL_CFG 0xe20 -+#define MTK_WED_ADDR_ELEM_TBL_OFFSET GENMASK(6, 0) -+#define MTK_WED_ADDR_ELEM_TBL_RD_RDY BIT(28) -+#define MTK_WED_ADDR_ELEM_TBL_WR_RDY BIT(29) -+#define MTK_WED_ADDR_ELEM_TBL_RD BIT(30) -+#define MTK_WED_ADDR_ELEM_TBL_WR BIT(31) -+ -+#define MTK_WED_RADDR_ELEM_TBL_WDATA 0xe24 -+#define MTK_WED_RADDR_ELEM_TBL_RDATA 0xe28 -+ -+#define MTK_WED_PN_CHECK_CFG 0xe30 -+#define MTK_WED_PN_CHECK_SE_ID GENMASK(11, 0) -+#define MTK_WED_PN_CHECK_RD_RDY BIT(28) -+#define MTK_WED_PN_CHECK_WR_RDY BIT(29) -+#define MTK_WED_PN_CHECK_RD BIT(30) -+#define MTK_WED_PN_CHECK_WR BIT(31) -+ -+#define MTK_WED_PN_CHECK_WDATA_M 0xe38 -+#define MTK_WED_PN_CHECK_IS_FIRST BIT(17) -+ -+#define MTK_WED_RRO_MSDU_PG_RING_CFG(_n) (0xe44 + (_n) * 0x8) -+ -+#define MTK_WED_RRO_MSDU_PG_RING2_CFG 0xe58 -+#define MTK_WED_RRO_MSDU_PG_DRV_CLR BIT(26) -+#define MTK_WED_RRO_MSDU_PG_DRV_EN BIT(31) -+ -+#define MTK_WED_RRO_MSDU_PG_CTRL0(_n) (0xe5c + (_n) * 0xc) -+#define MTK_WED_RRO_MSDU_PG_CTRL1(_n) (0xe60 + (_n) * 0xc) -+#define MTK_WED_RRO_MSDU_PG_CTRL2(_n) (0xe64 + (_n) * 0xc) -+ -+#define MTK_WED_RRO_RX_D_RX(_n) (0xe80 + (_n) * 0x10) -+ -+#define MTK_WED_RRO_RX_MAGIC_CNT BIT(13) -+ -+#define MTK_WED_RRO_RX_D_CFG(_n) (0xea0 + (_n) * 0x4) -+#define MTK_WED_RRO_RX_D_DRV_CLR BIT(26) -+#define MTK_WED_RRO_RX_D_DRV_EN BIT(31) -+ -+#define MTK_WED_RRO_PG_BM_RX_DMAM 0xeb0 -+#define MTK_WED_RRO_PG_BM_RX_SDL0 GENMASK(13, 0) -+ -+#define MTK_WED_RRO_PG_BM_BASE 0xeb4 -+#define MTK_WED_RRO_PG_BM_INIT_PTR 0xeb8 -+#define MTK_WED_RRO_PG_BM_SW_TAIL_IDX GENMASK(15, 0) -+#define MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX BIT(16) -+ -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX 0xeec -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN BIT(0) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR BIT(1) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG GENMASK(6, 2) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN BIT(8) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR BIT(9) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG GENMASK(14, 10) -+ -+#define MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG 0xef4 -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN BIT(0) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR BIT(1) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG GENMASK(6, 2) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN BIT(8) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR BIT(9) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG GENMASK(14, 10) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN BIT(16) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18) -+ -+#define MTK_WED_RX_IND_CMD_CNT0 0xf20 -+#define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31) -+ -+#define MTK_WED_RX_IND_CMD_CNT(_n) (0xf20 + (_n) * 0x4) -+#define MTK_WED_IND_CMD_MAGIC_CNT_FAIL_CNT GENMASK(15, 0) -+ -+#define MTK_WED_RX_ADDR_ELEM_CNT(_n) (0xf48 + (_n) * 0x4) -+#define MTK_WED_ADDR_ELEM_SIG_FAIL_CNT GENMASK(15, 0) -+#define MTK_WED_ADDR_ELEM_FIRST_SIG_FAIL_CNT GENMASK(31, 16) -+#define MTK_WED_ADDR_ELEM_ACKSN_CNT GENMASK(27, 0) -+ -+#define MTK_WED_RX_MSDU_PG_CNT(_n) (0xf5c + (_n) * 0x4) -+ -+#define MTK_WED_RX_PN_CHK_CNT 0xf70 -+#define MTK_WED_PN_CHK_FAIL_CNT GENMASK(15, 0) -+ - #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000 - #define MTK_WED_PCIE_INT_MASK 0x0 - -+#define MTK_WED_PCIE_BASE 0x11280000 -+#define MTK_WED_PCIE_BASE0 0x11300000 -+#define MTK_WED_PCIE_BASE1 0x11310000 -+#define MTK_WED_PCIE_BASE2 0x11290000 - #endif ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -91,6 +91,8 @@ enum mtk_wed_dummy_cr_idx { - #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin" - #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" - #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" -+#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin" -+#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin" - - #define MTK_WO_MCU_CFG_LS_BASE 0 - #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000) ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -139,6 +139,8 @@ struct mtk_wed_device { - u32 wpdma_rx; - - bool wcid_512; -+ bool hw_rro; -+ bool msi; - - u16 token_start; - unsigned int nbuf; -@@ -212,10 +214,12 @@ mtk_wed_device_attach(struct mtk_wed_dev - return ret; - } - --static inline bool --mtk_wed_get_rx_capa(struct mtk_wed_device *dev) -+static inline bool mtk_wed_get_rx_capa(struct mtk_wed_device *dev) - { - #ifdef CONFIG_NET_MEDIATEK_SOC_WED -+ if (dev->version == 3) -+ return dev->wlan.hw_rro; -+ - return dev->version != 1; - #else - return false; diff --git a/target/linux/generic/backport-5.15/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch b/target/linux/generic/backport-5.15/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch deleted file mode 100644 index e91ae69d0811de..00000000000000 --- a/target/linux/generic/backport-5.15/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch +++ /dev/null @@ -1,95 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:14 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: refactor mtk_wed_check_wfdma_rx_fill - routine - -Refactor mtk_wed_check_wfdma_rx_fill() in order to be reused adding HW -receive offload support for MT7988 SoC. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -585,22 +585,15 @@ mtk_wed_set_512_support(struct mtk_wed_d - } - } - --#define MTK_WFMDA_RX_DMA_EN BIT(2) --static void --mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx) -+static int -+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, -+ struct mtk_wed_ring *ring) - { -- u32 val; - int i; - -- if (!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED)) -- return; /* queue is not configured by mt76 */ -- - for (i = 0; i < 3; i++) { -- u32 cur_idx; -+ u32 cur_idx = readl(ring->wpdma + MTK_WED_RING_OFS_CPU_IDX); - -- cur_idx = wed_r32(dev, -- MTK_WED_WPDMA_RING_RX_DATA(idx) + -- MTK_WED_RING_OFS_CPU_IDX); - if (cur_idx == MTK_WED_RX_RING_SIZE - 1) - break; - -@@ -609,12 +602,10 @@ mtk_wed_check_wfdma_rx_fill(struct mtk_w - - if (i == 3) { - dev_err(dev->hw->dev, "rx dma enable failed\n"); -- return; -+ return -ETIMEDOUT; - } - -- val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) | -- MTK_WFMDA_RX_DMA_EN; -- wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val); -+ return 0; - } - - static void -@@ -1545,6 +1536,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev - wed_w32(dev, MTK_WED_INT_MASK, irq_mask); - } - -+#define MTK_WFMDA_RX_DMA_EN BIT(2) - static void - mtk_wed_dma_enable(struct mtk_wed_device *dev) - { -@@ -1632,8 +1624,26 @@ mtk_wed_dma_enable(struct mtk_wed_device - wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); - } - -- for (i = 0; i < MTK_WED_RX_QUEUES; i++) -- mtk_wed_check_wfdma_rx_fill(dev, i); -+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) { -+ struct mtk_wed_ring *ring = &dev->rx_ring[i]; -+ u32 val; -+ -+ if (!(ring->flags & MTK_WED_RING_CONFIGURED)) -+ continue; /* queue is not configured by mt76 */ -+ -+ if (mtk_wed_check_wfdma_rx_fill(dev, ring)) { -+ dev_err(dev->hw->dev, -+ "rx_ring(%d) dma enable failed\n", i); -+ continue; -+ } -+ -+ val = wifi_r32(dev, -+ dev->wlan.wpdma_rx_glo - -+ dev->wlan.phy_base) | MTK_WFMDA_RX_DMA_EN; -+ wifi_w32(dev, -+ dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, -+ val); -+ } - } - - static void diff --git a/target/linux/generic/backport-5.15/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch b/target/linux/generic/backport-5.15/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch deleted file mode 100644 index 21a4e0759f0b90..00000000000000 --- a/target/linux/generic/backport-5.15/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch +++ /dev/null @@ -1,465 +0,0 @@ -From: Sujuan Chen -Date: Mon, 18 Sep 2023 12:29:15 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: introduce partial AMSDU offload - support for MT7988 - -Introduce partial AMSDU offload support for MT7988 SoC in order to merge -in hw packets belonging to the same AMSDU before passing them to the -WLAN nic. - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -438,7 +438,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e - } - - int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, -- int wdma_idx, int txq, int bss, int wcid) -+ int wdma_idx, int txq, int bss, int wcid, -+ bool amsdu_en) - { - struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - u32 *ib2 = mtk_foe_entry_ib2(eth, entry); -@@ -450,6 +451,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et - MTK_FOE_IB2_WDMA_WINFO_V2; - l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) | - FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss); -+ l2->amsdu = FIELD_PREP(MTK_FOE_WINFO_AMSDU_EN, amsdu_en); - break; - case 2: - *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -88,13 +88,13 @@ enum { - #define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16) - #define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0) - --#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0) --#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16) --#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20) --#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21) --#define MTK_FOE_WINFO_PAO_IS_SP BIT(22) --#define MTK_FOE_WINFO_PAO_HF BIT(23) --#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24) -+#define MTK_FOE_WINFO_AMSDU_USR_INFO GENMASK(15, 0) -+#define MTK_FOE_WINFO_AMSDU_TID GENMASK(19, 16) -+#define MTK_FOE_WINFO_AMSDU_IS_FIXEDRATE BIT(20) -+#define MTK_FOE_WINFO_AMSDU_IS_PRIOR BIT(21) -+#define MTK_FOE_WINFO_AMSDU_IS_SP BIT(22) -+#define MTK_FOE_WINFO_AMSDU_HF BIT(23) -+#define MTK_FOE_WINFO_AMSDU_EN BIT(24) - - enum { - MTK_FOE_STATE_INVALID, -@@ -123,7 +123,7 @@ struct mtk_foe_mac_info { - - /* netsys_v3 */ - u32 w3info; -- u32 wpao; -+ u32 amsdu; - }; - - /* software-only entry type */ -@@ -393,7 +393,8 @@ int mtk_foe_entry_set_vlan(struct mtk_et - int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, - int sid); - int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, -- int wdma_idx, int txq, int bss, int wcid); -+ int wdma_idx, int txq, int bss, int wcid, -+ bool amsdu_en); - int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, - unsigned int queue); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -111,6 +111,7 @@ mtk_flow_get_wdma_info(struct net_device - info->queue = path->mtk_wdma.queue; - info->bss = path->mtk_wdma.bss; - info->wcid = path->mtk_wdma.wcid; -+ info->amsdu = path->mtk_wdma.amsdu; - - return 0; - } -@@ -192,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et - - if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { - mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, -- info.bss, info.wcid); -+ info.bss, info.wcid, info.amsdu); - if (mtk_is_netsys_v2_or_greater(eth)) { - switch (info.wdma_idx) { - case 0: ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -29,6 +29,8 @@ - #define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128) - #define MTK_WED_RX_RING_SIZE 1536 - #define MTK_WED_RX_PG_BM_CNT 8192 -+#define MTK_WED_AMSDU_BUF_SIZE (PAGE_SIZE << 4) -+#define MTK_WED_AMSDU_NPAGES 32 - - #define MTK_WED_TX_RING_SIZE 2048 - #define MTK_WED_WDMA_RING_SIZE 1024 -@@ -172,6 +174,23 @@ mtk_wdma_rx_reset(struct mtk_wed_device - return ret; - } - -+static u32 -+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) -+{ -+ return !!(wed_r32(dev, reg) & mask); -+} -+ -+static int -+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) -+{ -+ int sleep = 15000; -+ int timeout = 100 * sleep; -+ u32 val; -+ -+ return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep, -+ timeout, false, dev, reg, mask); -+} -+ - static void - mtk_wdma_tx_reset(struct mtk_wed_device *dev) - { -@@ -335,6 +354,118 @@ out: - } - - static int -+mtk_wed_amsdu_buffer_alloc(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_hw *hw = dev->hw; -+ struct mtk_wed_amsdu *wed_amsdu; -+ int i; -+ -+ if (!mtk_wed_is_v3_or_greater(hw)) -+ return 0; -+ -+ wed_amsdu = devm_kcalloc(hw->dev, MTK_WED_AMSDU_NPAGES, -+ sizeof(*wed_amsdu), GFP_KERNEL); -+ if (!wed_amsdu) -+ return -ENOMEM; -+ -+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) { -+ void *ptr; -+ -+ /* each segment is 64K */ -+ ptr = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | -+ __GFP_ZERO | __GFP_COMP | -+ GFP_DMA32, -+ get_order(MTK_WED_AMSDU_BUF_SIZE)); -+ if (!ptr) -+ goto error; -+ -+ wed_amsdu[i].txd = ptr; -+ wed_amsdu[i].txd_phy = dma_map_single(hw->dev, ptr, -+ MTK_WED_AMSDU_BUF_SIZE, -+ DMA_TO_DEVICE); -+ if (dma_mapping_error(hw->dev, wed_amsdu[i].txd_phy)) -+ goto error; -+ } -+ dev->hw->wed_amsdu = wed_amsdu; -+ -+ return 0; -+ -+error: -+ for (i--; i >= 0; i--) -+ dma_unmap_single(hw->dev, wed_amsdu[i].txd_phy, -+ MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE); -+ return -ENOMEM; -+} -+ -+static void -+mtk_wed_amsdu_free_buffer(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu; -+ int i; -+ -+ if (!wed_amsdu) -+ return; -+ -+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) { -+ dma_unmap_single(dev->hw->dev, wed_amsdu[i].txd_phy, -+ MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE); -+ free_pages((unsigned long)wed_amsdu[i].txd, -+ get_order(MTK_WED_AMSDU_BUF_SIZE)); -+ } -+} -+ -+static int -+mtk_wed_amsdu_init(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu; -+ int i, ret; -+ -+ if (!wed_amsdu) -+ return 0; -+ -+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) -+ wed_w32(dev, MTK_WED_AMSDU_HIFTXD_BASE_L(i), -+ wed_amsdu[i].txd_phy); -+ -+ /* init all sta parameter */ -+ wed_w32(dev, MTK_WED_AMSDU_STA_INFO_INIT, MTK_WED_AMSDU_STA_RMVL | -+ MTK_WED_AMSDU_STA_WTBL_HDRT_MODE | -+ FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_LEN, -+ dev->wlan.amsdu_max_len >> 8) | -+ FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_NUM, -+ dev->wlan.amsdu_max_subframes)); -+ -+ wed_w32(dev, MTK_WED_AMSDU_STA_INFO, MTK_WED_AMSDU_STA_INFO_DO_INIT); -+ -+ ret = mtk_wed_poll_busy(dev, MTK_WED_AMSDU_STA_INFO, -+ MTK_WED_AMSDU_STA_INFO_DO_INIT); -+ if (ret) { -+ dev_err(dev->hw->dev, "amsdu initialization failed\n"); -+ return ret; -+ } -+ -+ /* init partial amsdu offload txd src */ -+ wed_set(dev, MTK_WED_AMSDU_HIFTXD_CFG, -+ FIELD_PREP(MTK_WED_AMSDU_HIFTXD_SRC, dev->hw->index)); -+ -+ /* init qmem */ -+ wed_set(dev, MTK_WED_AMSDU_PSE, MTK_WED_AMSDU_PSE_RESET); -+ ret = mtk_wed_poll_busy(dev, MTK_WED_MON_AMSDU_QMEM_STS1, BIT(29)); -+ if (ret) { -+ pr_info("%s: amsdu qmem initialization failed\n", __func__); -+ return ret; -+ } -+ -+ /* eagle E1 PCIE1 tx ring 22 flow control issue */ -+ if (dev->wlan.id == 0x7991) -+ wed_clr(dev, MTK_WED_AMSDU_FIFO, MTK_WED_AMSDU_IS_PRIOR0_RING); -+ -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN); -+ -+ return 0; -+} -+ -+static int - mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) - { - u32 desc_size = dev->hw->soc->tx_ring_desc_size; -@@ -708,6 +839,7 @@ __mtk_wed_detach(struct mtk_wed_device * - - mtk_wdma_rx_reset(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); -+ mtk_wed_amsdu_free_buffer(dev); - mtk_wed_free_tx_buffer(dev); - mtk_wed_free_tx_rings(dev); - -@@ -1128,23 +1260,6 @@ mtk_wed_ring_reset(struct mtk_wed_ring * - } - } - --static u32 --mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) --{ -- return !!(wed_r32(dev, reg) & mask); --} -- --static int --mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) --{ -- int sleep = 15000; -- int timeout = 100 * sleep; -- u32 val; -- -- return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep, -- timeout, false, dev, reg, mask); --} -- - static int - mtk_wed_rx_reset(struct mtk_wed_device *dev) - { -@@ -1691,6 +1806,7 @@ mtk_wed_start(struct mtk_wed_device *dev - } - - mtk_wed_set_512_support(dev, dev->wlan.wcid_512); -+ mtk_wed_amsdu_init(dev); - - mtk_wed_dma_enable(dev); - dev->running = true; -@@ -1747,6 +1863,10 @@ mtk_wed_attach(struct mtk_wed_device *de - if (ret) - goto out; - -+ ret = mtk_wed_amsdu_buffer_alloc(dev); -+ if (ret) -+ goto out; -+ - if (mtk_wed_get_rx_capa(dev)) { - ret = mtk_wed_rro_alloc(dev); - if (ret) ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -25,6 +25,11 @@ struct mtk_wed_soc_data { - u32 wdma_desc_size; - }; - -+struct mtk_wed_amsdu { -+ void *txd; -+ dma_addr_t txd_phy; -+}; -+ - struct mtk_wed_hw { - const struct mtk_wed_soc_data *soc; - struct device_node *node; -@@ -38,6 +43,7 @@ struct mtk_wed_hw { - struct dentry *debugfs_dir; - struct mtk_wed_device *wed_dev; - struct mtk_wed_wo *wed_wo; -+ struct mtk_wed_amsdu *wed_amsdu; - u32 pcie_base; - u32 debugfs_reg; - u32 num_flows; -@@ -52,6 +58,7 @@ struct mtk_wdma_info { - u8 queue; - u16 wcid; - u8 bss; -+ u8 amsdu; - }; - - #ifdef CONFIG_NET_MEDIATEK_SOC_WED ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -672,6 +672,82 @@ struct mtk_wdma_desc { - #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000 - #define MTK_WED_PCIE_INT_MASK 0x0 - -+#define MTK_WED_AMSDU_FIFO 0x1800 -+#define MTK_WED_AMSDU_IS_PRIOR0_RING BIT(10) -+ -+#define MTK_WED_AMSDU_STA_INFO 0x01810 -+#define MTK_WED_AMSDU_STA_INFO_DO_INIT BIT(0) -+#define MTK_WED_AMSDU_STA_INFO_SET_INIT BIT(1) -+ -+#define MTK_WED_AMSDU_STA_INFO_INIT 0x01814 -+#define MTK_WED_AMSDU_STA_WTBL_HDRT_MODE BIT(0) -+#define MTK_WED_AMSDU_STA_RMVL BIT(1) -+#define MTK_WED_AMSDU_STA_MAX_AMSDU_LEN GENMASK(7, 2) -+#define MTK_WED_AMSDU_STA_MAX_AMSDU_NUM GENMASK(11, 8) -+ -+#define MTK_WED_AMSDU_HIFTXD_BASE_L(_n) (0x1980 + (_n) * 0x4) -+ -+#define MTK_WED_AMSDU_PSE 0x1910 -+#define MTK_WED_AMSDU_PSE_RESET BIT(16) -+ -+#define MTK_WED_AMSDU_HIFTXD_CFG 0x1968 -+#define MTK_WED_AMSDU_HIFTXD_SRC GENMASK(16, 15) -+ -+#define MTK_WED_MON_AMSDU_FIFO_DMAD 0x1a34 -+ -+#define MTK_WED_MON_AMSDU_ENG_DMAD(_n) (0x1a80 + (_n) * 0x50) -+#define MTK_WED_MON_AMSDU_ENG_QFPL(_n) (0x1a84 + (_n) * 0x50) -+#define MTK_WED_MON_AMSDU_ENG_QENI(_n) (0x1a88 + (_n) * 0x50) -+#define MTK_WED_MON_AMSDU_ENG_QENO(_n) (0x1a8c + (_n) * 0x50) -+#define MTK_WED_MON_AMSDU_ENG_MERG(_n) (0x1a90 + (_n) * 0x50) -+ -+#define MTK_WED_MON_AMSDU_ENG_CNT8(_n) (0x1a94 + (_n) * 0x50) -+#define MTK_WED_AMSDU_ENG_MAX_QGPP_CNT GENMASK(10, 0) -+#define MTK_WED_AMSDU_ENG_MAX_PL_CNT GENMASK(27, 16) -+ -+#define MTK_WED_MON_AMSDU_ENG_CNT9(_n) (0x1a98 + (_n) * 0x50) -+#define MTK_WED_AMSDU_ENG_CUR_ENTRY GENMASK(10, 0) -+#define MTK_WED_AMSDU_ENG_MAX_BUF_MERGED GENMASK(20, 16) -+#define MTK_WED_AMSDU_ENG_MAX_MSDU_MERGED GENMASK(28, 24) -+ -+#define MTK_WED_MON_AMSDU_QMEM_STS1 0x1e04 -+ -+#define MTK_WED_MON_AMSDU_QMEM_CNT(_n) (0x1e0c + (_n) * 0x4) -+#define MTK_WED_AMSDU_QMEM_FQ_CNT GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_SP_QCNT GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID0_QCNT GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID1_QCNT GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID2_QCNT GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID3_QCNT GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID4_QCNT GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID5_QCNT GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID6_QCNT GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID7_QCNT GENMASK(11, 0) -+ -+#define MTK_WED_MON_AMSDU_QMEM_PTR(_n) (0x1e20 + (_n) * 0x4) -+#define MTK_WED_AMSDU_QMEM_FQ_HEAD GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_SP_QHEAD GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID0_QHEAD GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID1_QHEAD GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID2_QHEAD GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID3_QHEAD GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID4_QHEAD GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID5_QHEAD GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID6_QHEAD GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID7_QHEAD GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_FQ_TAIL GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_SP_QTAIL GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID0_QTAIL GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID1_QTAIL GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID2_QTAIL GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID3_QTAIL GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID4_QTAIL GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID5_QTAIL GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID6_QTAIL GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID7_QTAIL GENMASK(11, 0) -+ -+#define MTK_WED_MON_AMSDU_HIFTXD_FETCH_MSDU(_n) (0x1ec4 + (_n) * 0x4) -+ - #define MTK_WED_PCIE_BASE 0x11280000 - #define MTK_WED_PCIE_BASE0 0x11300000 - #define MTK_WED_PCIE_BASE1 0x11310000 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -906,6 +906,7 @@ struct net_device_path { - u8 queue; - u16 wcid; - u8 bss; -+ u8 amsdu; - } mtk_wdma; - }; - }; ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -129,6 +129,7 @@ struct mtk_wed_device { - enum mtk_wed_bus_tye bus_type; - void __iomem *base; - u32 phy_base; -+ u32 id; - - u32 wpdma_phys; - u32 wpdma_int; -@@ -147,10 +148,12 @@ struct mtk_wed_device { - unsigned int rx_nbuf; - unsigned int rx_npkt; - unsigned int rx_size; -+ unsigned int amsdu_max_len; - - u8 tx_tbit[MTK_WED_TX_QUEUES]; - u8 rx_tbit[MTK_WED_RX_QUEUES]; - u8 txfree_tbit; -+ u8 amsdu_max_subframes; - - u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); - int (*offload_enable)(struct mtk_wed_device *wed); -@@ -224,6 +227,15 @@ static inline bool mtk_wed_get_rx_capa(s - #else - return false; - #endif -+} -+ -+static inline bool mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev) -+{ -+#ifdef CONFIG_NET_MEDIATEK_SOC_WED -+ return dev->version == 3; -+#else -+ return false; -+#endif - } - - #ifdef CONFIG_NET_MEDIATEK_SOC_WED diff --git a/target/linux/generic/backport-5.15/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch b/target/linux/generic/backport-5.15/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch deleted file mode 100644 index 0cf4c188757ec7..00000000000000 --- a/target/linux/generic/backport-5.15/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch +++ /dev/null @@ -1,483 +0,0 @@ -From: Sujuan Chen -Date: Mon, 18 Sep 2023 12:29:16 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: introduce hw_rro support for MT7988 - -MT7988 SoC support 802.11 receive reordering offload in hw while -MT7986 SoC implements it through the firmware running on the mcu. - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -26,7 +26,7 @@ - #define MTK_WED_BUF_SIZE 2048 - #define MTK_WED_PAGE_BUF_SIZE 128 - #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048) --#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128) -+#define MTK_WED_RX_BUF_PER_PAGE (PAGE_SIZE / MTK_WED_PAGE_BUF_SIZE) - #define MTK_WED_RX_RING_SIZE 1536 - #define MTK_WED_RX_PG_BM_CNT 8192 - #define MTK_WED_AMSDU_BUF_SIZE (PAGE_SIZE << 4) -@@ -596,6 +596,68 @@ free_pagelist: - } - - static int -+mtk_wed_hwrro_buffer_alloc(struct mtk_wed_device *dev) -+{ -+ int n_pages = MTK_WED_RX_PG_BM_CNT / MTK_WED_RX_BUF_PER_PAGE; -+ struct mtk_wed_buf *page_list; -+ struct mtk_wed_bm_desc *desc; -+ dma_addr_t desc_phys; -+ int i, page_idx = 0; -+ -+ if (!dev->wlan.hw_rro) -+ return 0; -+ -+ page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL); -+ if (!page_list) -+ return -ENOMEM; -+ -+ dev->hw_rro.size = dev->wlan.rx_nbuf & ~(MTK_WED_BUF_PER_PAGE - 1); -+ dev->hw_rro.pages = page_list; -+ desc = dma_alloc_coherent(dev->hw->dev, -+ dev->wlan.rx_nbuf * sizeof(*desc), -+ &desc_phys, GFP_KERNEL); -+ if (!desc) -+ return -ENOMEM; -+ -+ dev->hw_rro.desc = desc; -+ dev->hw_rro.desc_phys = desc_phys; -+ -+ for (i = 0; i < MTK_WED_RX_PG_BM_CNT; i += MTK_WED_RX_BUF_PER_PAGE) { -+ dma_addr_t page_phys, buf_phys; -+ struct page *page; -+ int s; -+ -+ page = __dev_alloc_page(GFP_KERNEL); -+ if (!page) -+ return -ENOMEM; -+ -+ page_phys = dma_map_page(dev->hw->dev, page, 0, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ if (dma_mapping_error(dev->hw->dev, page_phys)) { -+ __free_page(page); -+ return -ENOMEM; -+ } -+ -+ page_list[page_idx].p = page; -+ page_list[page_idx++].phy_addr = page_phys; -+ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ -+ buf_phys = page_phys; -+ for (s = 0; s < MTK_WED_RX_BUF_PER_PAGE; s++) { -+ desc->buf0 = cpu_to_le32(buf_phys); -+ buf_phys += MTK_WED_PAGE_BUF_SIZE; -+ desc++; -+ } -+ -+ dma_sync_single_for_device(dev->hw->dev, page_phys, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ } -+ -+ return 0; -+} -+ -+static int - mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev) - { - struct mtk_wed_bm_desc *desc; -@@ -612,7 +674,42 @@ mtk_wed_rx_buffer_alloc(struct mtk_wed_d - dev->rx_buf_ring.desc_phys = desc_phys; - dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt); - -- return 0; -+ return mtk_wed_hwrro_buffer_alloc(dev); -+} -+ -+static void -+mtk_wed_hwrro_free_buffer(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_buf *page_list = dev->hw_rro.pages; -+ struct mtk_wed_bm_desc *desc = dev->hw_rro.desc; -+ int i, page_idx = 0; -+ -+ if (!dev->wlan.hw_rro) -+ return; -+ -+ if (!page_list) -+ return; -+ -+ if (!desc) -+ goto free_pagelist; -+ -+ for (i = 0; i < MTK_WED_RX_PG_BM_CNT; i += MTK_WED_RX_BUF_PER_PAGE) { -+ dma_addr_t buf_addr = page_list[page_idx].phy_addr; -+ void *page = page_list[page_idx++].p; -+ -+ if (!page) -+ break; -+ -+ dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ __free_page(page); -+ } -+ -+ dma_free_coherent(dev->hw->dev, dev->hw_rro.size * sizeof(*desc), -+ desc, dev->hw_rro.desc_phys); -+ -+free_pagelist: -+ kfree(page_list); - } - - static void -@@ -626,6 +723,28 @@ mtk_wed_free_rx_buffer(struct mtk_wed_de - dev->wlan.release_rx_buf(dev); - dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc), - desc, dev->rx_buf_ring.desc_phys); -+ -+ mtk_wed_hwrro_free_buffer(dev); -+} -+ -+static void -+mtk_wed_hwrro_init(struct mtk_wed_device *dev) -+{ -+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro) -+ return; -+ -+ wed_set(dev, MTK_WED_RRO_PG_BM_RX_DMAM, -+ FIELD_PREP(MTK_WED_RRO_PG_BM_RX_SDL0, 128)); -+ -+ wed_w32(dev, MTK_WED_RRO_PG_BM_BASE, dev->hw_rro.desc_phys); -+ -+ wed_w32(dev, MTK_WED_RRO_PG_BM_INIT_PTR, -+ MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX | -+ FIELD_PREP(MTK_WED_RRO_PG_BM_SW_TAIL_IDX, -+ MTK_WED_RX_PG_BM_CNT)); -+ -+ /* enable rx_page_bm to fetch dmad */ -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN); - } - - static void -@@ -639,6 +758,8 @@ mtk_wed_rx_buffer_hw_init(struct mtk_wed - wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH, - FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff)); - wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); -+ -+ mtk_wed_hwrro_init(dev); - } - - static void -@@ -934,6 +1055,8 @@ mtk_wed_bus_init(struct mtk_wed_device * - static void - mtk_wed_set_wpdma(struct mtk_wed_device *dev) - { -+ int i; -+ - if (mtk_wed_is_v1(dev->hw)) { - wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); - return; -@@ -951,6 +1074,15 @@ mtk_wed_set_wpdma(struct mtk_wed_device - - wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); - wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx); -+ -+ if (!dev->wlan.hw_rro) -+ return; -+ -+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(0), dev->wlan.wpdma_rx_rro[0]); -+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(1), dev->wlan.wpdma_rx_rro[1]); -+ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) -+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING_CFG(i), -+ dev->wlan.wpdma_rx_pg + i * 0x10); - } - - static void -@@ -1762,6 +1894,165 @@ mtk_wed_dma_enable(struct mtk_wed_device - } - - static void -+mtk_wed_start_hw_rro(struct mtk_wed_device *dev, u32 irq_mask, bool reset) -+{ -+ int i; -+ -+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask); -+ wed_w32(dev, MTK_WED_INT_MASK, irq_mask); -+ -+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro) -+ return; -+ -+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR); -+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_CLR); -+ -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_RX, -+ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN | -+ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR | -+ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN | -+ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG, -+ dev->wlan.rro_rx_tbit[0]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG, -+ dev->wlan.rro_rx_tbit[1])); -+ -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG, -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN | -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR | -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN | -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR | -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN | -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG, -+ dev->wlan.rx_pg_tbit[0]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG, -+ dev->wlan.rx_pg_tbit[1]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG, -+ dev->wlan.rx_pg_tbit[2])); -+ -+ /* RRO_MSDU_PG_RING2_CFG1_FLD_DRV_EN should be enabled after -+ * WM FWDL completed, otherwise RRO_MSDU_PG ring may broken -+ */ -+ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_EN); -+ -+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) { -+ struct mtk_wed_ring *ring = &dev->rx_rro_ring[i]; -+ -+ if (!(ring->flags & MTK_WED_RING_CONFIGURED)) -+ continue; -+ -+ if (mtk_wed_check_wfdma_rx_fill(dev, ring)) -+ dev_err(dev->hw->dev, -+ "rx_rro_ring(%d) initialization failed\n", i); -+ } -+ -+ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) { -+ struct mtk_wed_ring *ring = &dev->rx_page_ring[i]; -+ -+ if (!(ring->flags & MTK_WED_RING_CONFIGURED)) -+ continue; -+ -+ if (mtk_wed_check_wfdma_rx_fill(dev, ring)) -+ dev_err(dev->hw->dev, -+ "rx_page_ring(%d) initialization failed\n", i); -+ } -+} -+ -+static void -+mtk_wed_rro_rx_ring_setup(struct mtk_wed_device *dev, int idx, -+ void __iomem *regs) -+{ -+ struct mtk_wed_ring *ring = &dev->rx_rro_ring[idx]; -+ -+ ring->wpdma = regs; -+ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_BASE, -+ readl(regs)); -+ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_COUNT, -+ readl(regs + MTK_WED_RING_OFS_COUNT)); -+ ring->flags |= MTK_WED_RING_CONFIGURED; -+} -+ -+static void -+mtk_wed_msdu_pg_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) -+{ -+ struct mtk_wed_ring *ring = &dev->rx_page_ring[idx]; -+ -+ ring->wpdma = regs; -+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_BASE, -+ readl(regs)); -+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_COUNT, -+ readl(regs + MTK_WED_RING_OFS_COUNT)); -+ ring->flags |= MTK_WED_RING_CONFIGURED; -+} -+ -+static int -+mtk_wed_ind_rx_ring_setup(struct mtk_wed_device *dev, void __iomem *regs) -+{ -+ struct mtk_wed_ring *ring = &dev->ind_cmd_ring; -+ u32 val = readl(regs + MTK_WED_RING_OFS_COUNT); -+ int i, count = 0; -+ -+ ring->wpdma = regs; -+ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_BASE, -+ readl(regs) & 0xfffffff0); -+ -+ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_COUNT, -+ readl(regs + MTK_WED_RING_OFS_COUNT)); -+ -+ /* ack sn cr */ -+ wed_w32(dev, MTK_WED_RRO_CFG0, dev->wlan.phy_base + -+ dev->wlan.ind_cmd.ack_sn_addr); -+ wed_w32(dev, MTK_WED_RRO_CFG1, -+ FIELD_PREP(MTK_WED_RRO_CFG1_MAX_WIN_SZ, -+ dev->wlan.ind_cmd.win_size) | -+ FIELD_PREP(MTK_WED_RRO_CFG1_PARTICL_SE_ID, -+ dev->wlan.ind_cmd.particular_sid)); -+ -+ /* particular session addr element */ -+ wed_w32(dev, MTK_WED_ADDR_ELEM_CFG0, -+ dev->wlan.ind_cmd.particular_se_phys); -+ -+ for (i = 0; i < dev->wlan.ind_cmd.se_group_nums; i++) { -+ wed_w32(dev, MTK_WED_RADDR_ELEM_TBL_WDATA, -+ dev->wlan.ind_cmd.addr_elem_phys[i] >> 4); -+ wed_w32(dev, MTK_WED_ADDR_ELEM_TBL_CFG, -+ MTK_WED_ADDR_ELEM_TBL_WR | (i & 0x7f)); -+ -+ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG); -+ while (!(val & MTK_WED_ADDR_ELEM_TBL_WR_RDY) && count++ < 100) -+ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG); -+ if (count >= 100) -+ dev_err(dev->hw->dev, -+ "write ba session base failed\n"); -+ } -+ -+ /* pn check init */ -+ for (i = 0; i < dev->wlan.ind_cmd.particular_sid; i++) { -+ wed_w32(dev, MTK_WED_PN_CHECK_WDATA_M, -+ MTK_WED_PN_CHECK_IS_FIRST); -+ -+ wed_w32(dev, MTK_WED_PN_CHECK_CFG, MTK_WED_PN_CHECK_WR | -+ FIELD_PREP(MTK_WED_PN_CHECK_SE_ID, i)); -+ -+ count = 0; -+ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG); -+ while (!(val & MTK_WED_PN_CHECK_WR_RDY) && count++ < 100) -+ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG); -+ if (count >= 100) -+ dev_err(dev->hw->dev, -+ "session(%d) initialization failed\n", i); -+ } -+ -+ wed_w32(dev, MTK_WED_RX_IND_CMD_CNT0, MTK_WED_RX_IND_CMD_DBG_CNT_EN); -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN); -+ -+ return 0; -+} -+ -+static void - mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) - { - int i; -@@ -2215,6 +2506,10 @@ void mtk_wed_add_hw(struct device_node * - .detach = mtk_wed_detach, - .ppe_check = mtk_wed_ppe_check, - .setup_tc = mtk_wed_setup_tc, -+ .start_hw_rro = mtk_wed_start_hw_rro, -+ .rro_rx_ring_setup = mtk_wed_rro_rx_ring_setup, -+ .msdu_pg_rx_ring_setup = mtk_wed_msdu_pg_rx_ring_setup, -+ .ind_rx_ring_setup = mtk_wed_ind_rx_ring_setup, - }; - struct device_node *eth_np = eth->dev->of_node; - struct platform_device *pdev; ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -10,6 +10,7 @@ - - #define MTK_WED_TX_QUEUES 2 - #define MTK_WED_RX_QUEUES 2 -+#define MTK_WED_RX_PAGE_QUEUES 3 - - #define WED_WO_STA_REC 0x6 - -@@ -99,6 +100,9 @@ struct mtk_wed_device { - struct mtk_wed_ring txfree_ring; - struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; - struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES]; -+ struct mtk_wed_ring rx_rro_ring[MTK_WED_RX_QUEUES]; -+ struct mtk_wed_ring rx_page_ring[MTK_WED_RX_PAGE_QUEUES]; -+ struct mtk_wed_ring ind_cmd_ring; - - struct { - int size; -@@ -120,6 +124,13 @@ struct mtk_wed_device { - dma_addr_t fdbk_phys; - } rro; - -+ struct { -+ int size; -+ struct mtk_wed_buf *pages; -+ struct mtk_wed_bm_desc *desc; -+ dma_addr_t desc_phys; -+ } hw_rro; -+ - /* filled by driver: */ - struct { - union { -@@ -138,6 +149,8 @@ struct mtk_wed_device { - u32 wpdma_txfree; - u32 wpdma_rx_glo; - u32 wpdma_rx; -+ u32 wpdma_rx_rro[MTK_WED_RX_QUEUES]; -+ u32 wpdma_rx_pg; - - bool wcid_512; - bool hw_rro; -@@ -152,9 +165,20 @@ struct mtk_wed_device { - - u8 tx_tbit[MTK_WED_TX_QUEUES]; - u8 rx_tbit[MTK_WED_RX_QUEUES]; -+ u8 rro_rx_tbit[MTK_WED_RX_QUEUES]; -+ u8 rx_pg_tbit[MTK_WED_RX_PAGE_QUEUES]; - u8 txfree_tbit; - u8 amsdu_max_subframes; - -+ struct { -+ u8 se_group_nums; -+ u16 win_size; -+ u16 particular_sid; -+ u32 ack_sn_addr; -+ dma_addr_t particular_se_phys; -+ dma_addr_t addr_elem_phys[1024]; -+ } ind_cmd; -+ - u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); - int (*offload_enable)(struct mtk_wed_device *wed); - void (*offload_disable)(struct mtk_wed_device *wed); -@@ -193,6 +217,14 @@ struct mtk_wed_ops { - void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); - int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev, - enum tc_setup_type type, void *type_data); -+ void (*start_hw_rro)(struct mtk_wed_device *dev, u32 irq_mask, -+ bool reset); -+ void (*rro_rx_ring_setup)(struct mtk_wed_device *dev, int ring, -+ void __iomem *regs); -+ void (*msdu_pg_rx_ring_setup)(struct mtk_wed_device *dev, int ring, -+ void __iomem *regs); -+ int (*ind_rx_ring_setup)(struct mtk_wed_device *dev, -+ void __iomem *regs); - }; - - extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; -@@ -264,6 +296,15 @@ static inline bool mtk_wed_is_amsdu_supp - #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) - #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \ - (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data) -+#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) \ -+ (_dev)->ops->start_hw_rro(_dev, _mask, _reset) -+#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) \ -+ (_dev)->ops->rro_rx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) \ -+ (_dev)->ops->msdu_pg_rx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) \ -+ (_dev)->ops->ind_rx_ring_setup(_dev, _regs) -+ - #else - static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) - { -@@ -283,6 +324,10 @@ static inline bool mtk_wed_device_active - #define mtk_wed_device_stop(_dev) do {} while (0) - #define mtk_wed_device_dma_reset(_dev) do {} while (0) - #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP -+#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) do {} while (0) -+#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) -ENODEV - #endif - - #endif diff --git a/target/linux/generic/backport-5.15/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch b/target/linux/generic/backport-5.15/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch deleted file mode 100644 index 5ea43a444569a1..00000000000000 --- a/target/linux/generic/backport-5.15/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch +++ /dev/null @@ -1,78 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:17 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: debugfs: move wed_v2 specific regs - out of regs array - -Move specific WED2.0 debugfs entries out of regs array. This is a -preliminary patch to introduce WED 3.0 debugfs info. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -151,7 +151,7 @@ DEFINE_SHOW_ATTRIBUTE(wed_txinfo); - static int - wed_rxinfo_show(struct seq_file *s, void *data) - { -- static const struct reg_dump regs[] = { -+ static const struct reg_dump regs_common[] = { - DUMP_STR("WPDMA RX"), - DUMP_WPDMA_RX_RING(0), - DUMP_WPDMA_RX_RING(1), -@@ -169,7 +169,7 @@ wed_rxinfo_show(struct seq_file *s, void - DUMP_WED_RING(WED_RING_RX_DATA(0)), - DUMP_WED_RING(WED_RING_RX_DATA(1)), - -- DUMP_STR("WED RRO"), -+ DUMP_STR("WED WO RRO"), - DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0), - DUMP_WED(WED_RROQM_MID_MIB), - DUMP_WED(WED_RROQM_MOD_MIB), -@@ -180,17 +180,6 @@ wed_rxinfo_show(struct seq_file *s, void - DUMP_WED(WED_RROQM_FDBK_ANC_MIB), - DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB), - -- DUMP_STR("WED Route QM"), -- DUMP_WED(WED_RTQM_R2H_MIB(0)), -- DUMP_WED(WED_RTQM_R2Q_MIB(0)), -- DUMP_WED(WED_RTQM_Q2H_MIB(0)), -- DUMP_WED(WED_RTQM_R2H_MIB(1)), -- DUMP_WED(WED_RTQM_R2Q_MIB(1)), -- DUMP_WED(WED_RTQM_Q2H_MIB(1)), -- DUMP_WED(WED_RTQM_Q2N_MIB), -- DUMP_WED(WED_RTQM_Q2B_MIB), -- DUMP_WED(WED_RTQM_PFDBK_MIB), -- - DUMP_STR("WED WDMA TX"), - DUMP_WED(WED_WDMA_TX_MIB), - DUMP_WED_RING(WED_WDMA_RING_TX), -@@ -211,11 +200,25 @@ wed_rxinfo_show(struct seq_file *s, void - DUMP_WED(WED_RX_BM_INTF), - DUMP_WED(WED_RX_BM_ERR_STS), - }; -+ static const struct reg_dump regs_wed_v2[] = { -+ DUMP_STR("WED Route QM"), -+ DUMP_WED(WED_RTQM_R2H_MIB(0)), -+ DUMP_WED(WED_RTQM_R2Q_MIB(0)), -+ DUMP_WED(WED_RTQM_Q2H_MIB(0)), -+ DUMP_WED(WED_RTQM_R2H_MIB(1)), -+ DUMP_WED(WED_RTQM_R2Q_MIB(1)), -+ DUMP_WED(WED_RTQM_Q2H_MIB(1)), -+ DUMP_WED(WED_RTQM_Q2N_MIB), -+ DUMP_WED(WED_RTQM_Q2B_MIB), -+ DUMP_WED(WED_RTQM_PFDBK_MIB), -+ }; - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; - -- if (dev) -- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ if (dev) { -+ dump_wed_regs(s, dev, regs_common, ARRAY_SIZE(regs_common)); -+ dump_wed_regs(s, dev, regs_wed_v2, ARRAY_SIZE(regs_wed_v2)); -+ } - - return 0; - } diff --git a/target/linux/generic/backport-5.15/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch b/target/linux/generic/backport-5.15/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch deleted file mode 100644 index f491d2fd80cf35..00000000000000 --- a/target/linux/generic/backport-5.15/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch +++ /dev/null @@ -1,432 +0,0 @@ -From: Sujuan Chen -Date: Mon, 18 Sep 2023 12:29:18 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: debugfs: add WED 3.0 debugfs entries - -Introduce WED3.0 debugfs entries useful for debugging. - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -11,6 +11,7 @@ struct reg_dump { - u16 offset; - u8 type; - u8 base; -+ u32 mask; - }; - - enum { -@@ -25,6 +26,8 @@ enum { - - #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING } - #define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ } -+#define DUMP_REG_MASK(_reg, _mask) \ -+ { #_mask, MTK_##_reg, DUMP_TYPE_WED, 0, MTK_##_mask } - #define DUMP_RING(_prefix, _base, ...) \ - { _prefix " BASE", _base, __VA_ARGS__ }, \ - { _prefix " CNT", _base + 0x4, __VA_ARGS__ }, \ -@@ -32,6 +35,7 @@ enum { - { _prefix " DIDX", _base + 0xc, __VA_ARGS__ } - - #define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED) -+#define DUMP_WED_MASK(_reg, _mask) DUMP_REG_MASK(_reg, _mask) - #define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED) - - #define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA) -@@ -212,12 +216,58 @@ wed_rxinfo_show(struct seq_file *s, void - DUMP_WED(WED_RTQM_Q2B_MIB), - DUMP_WED(WED_RTQM_PFDBK_MIB), - }; -+ static const struct reg_dump regs_wed_v3[] = { -+ DUMP_STR("WED RX RRO DATA"), -+ DUMP_WED_RING(WED_RRO_RX_D_RX(0)), -+ DUMP_WED_RING(WED_RRO_RX_D_RX(1)), -+ -+ DUMP_STR("WED RX MSDU PAGE"), -+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(0)), -+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(1)), -+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(2)), -+ -+ DUMP_STR("WED RX IND CMD"), -+ DUMP_WED(WED_IND_CMD_RX_CTRL1), -+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_MAX_CNT), -+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_PROC_IDX), -+ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_DMA_IDX), -+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_MAGIC_CNT), -+ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_MAGIC_CNT), -+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, -+ WED_IND_CMD_PREFETCH_FREE_CNT), -+ DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_PARTICL_SE_ID), -+ -+ DUMP_STR("WED ADDR ELEM"), -+ DUMP_WED(WED_ADDR_ELEM_CFG0), -+ DUMP_WED_MASK(WED_ADDR_ELEM_CFG1, -+ WED_ADDR_ELEM_PREFETCH_FREE_CNT), -+ -+ DUMP_STR("WED Route QM"), -+ DUMP_WED(WED_RTQM_ENQ_I2Q_DMAD_CNT), -+ DUMP_WED(WED_RTQM_ENQ_I2N_DMAD_CNT), -+ DUMP_WED(WED_RTQM_ENQ_I2Q_PKT_CNT), -+ DUMP_WED(WED_RTQM_ENQ_I2N_PKT_CNT), -+ DUMP_WED(WED_RTQM_ENQ_USED_ENTRY_CNT), -+ DUMP_WED(WED_RTQM_ENQ_ERR_CNT), -+ -+ DUMP_WED(WED_RTQM_DEQ_DMAD_CNT), -+ DUMP_WED(WED_RTQM_DEQ_Q2I_DMAD_CNT), -+ DUMP_WED(WED_RTQM_DEQ_PKT_CNT), -+ DUMP_WED(WED_RTQM_DEQ_Q2I_PKT_CNT), -+ DUMP_WED(WED_RTQM_DEQ_USED_PFDBK_CNT), -+ DUMP_WED(WED_RTQM_DEQ_ERR_CNT), -+ }; - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; - - if (dev) { - dump_wed_regs(s, dev, regs_common, ARRAY_SIZE(regs_common)); -- dump_wed_regs(s, dev, regs_wed_v2, ARRAY_SIZE(regs_wed_v2)); -+ if (mtk_wed_is_v2(hw)) -+ dump_wed_regs(s, dev, -+ regs_wed_v2, ARRAY_SIZE(regs_wed_v2)); -+ else -+ dump_wed_regs(s, dev, -+ regs_wed_v3, ARRAY_SIZE(regs_wed_v3)); - } - - return 0; -@@ -225,6 +275,314 @@ wed_rxinfo_show(struct seq_file *s, void - DEFINE_SHOW_ATTRIBUTE(wed_rxinfo); - - static int -+wed_amsdu_show(struct seq_file *s, void *data) -+{ -+ static const struct reg_dump regs[] = { -+ DUMP_STR("WED AMDSU INFO"), -+ DUMP_WED(WED_MON_AMSDU_FIFO_DMAD), -+ -+ DUMP_STR("WED AMDSU ENG0 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(0)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(0)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(0)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(0)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(0)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG1 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(1)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(1)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(1)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(1)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(1)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(1), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG2 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(2)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(2)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(2)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(2)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(2)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG3 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(3)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(3)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(3)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(3)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(3)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG4 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(4)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(4)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(4)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(4)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(4)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG5 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(5)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(5)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(5)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(5)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(5)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG6 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(6)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(6)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(6)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(6)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(6)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG7 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(7)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(7)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(7)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(7)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(7)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG8 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(8)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(8)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(8)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(8)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(8)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED QMEM INFO"), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_FQ_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_SP_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID0_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID1_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID2_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID3_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID4_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID5_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID6_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID7_QCNT), -+ -+ DUMP_STR("WED QMEM HEAD INFO"), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_FQ_HEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_SP_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID0_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID1_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID2_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID3_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID4_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID5_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID6_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID7_QHEAD), -+ -+ DUMP_STR("WED QMEM TAIL INFO"), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_FQ_TAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_SP_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID0_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID1_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID2_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID3_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID4_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID5_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID6_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID7_QTAIL), -+ -+ DUMP_STR("WED HIFTXD MSDU INFO"), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(1)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(2)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(3)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(4)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(5)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(6)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(7)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(8)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(9)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(10)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(11)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(12)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(13)), -+ }; -+ struct mtk_wed_hw *hw = s->private; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (dev) -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(wed_amsdu); -+ -+static int -+wed_rtqm_show(struct seq_file *s, void *data) -+{ -+ static const struct reg_dump regs[] = { -+ DUMP_STR("WED Route QM IGRS0(N2H + Recycle)"), -+ DUMP_WED(WED_RTQM_IGRS0_I2HW_DMAD_CNT), -+ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS0_I2HW_PKT_CNT), -+ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS0_FDROP_CNT), -+ -+ DUMP_STR("WED Route QM IGRS1(Legacy)"), -+ DUMP_WED(WED_RTQM_IGRS1_I2HW_DMAD_CNT), -+ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS1_I2HW_PKT_CNT), -+ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS1_FDROP_CNT), -+ -+ DUMP_STR("WED Route QM IGRS2(RRO3.0)"), -+ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT), -+ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS2_I2HW_PKT_CNT), -+ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS2_FDROP_CNT), -+ -+ DUMP_STR("WED Route QM IGRS3(DEBUG)"), -+ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT), -+ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS3_I2HW_PKT_CNT), -+ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS3_FDROP_CNT), -+ }; -+ struct mtk_wed_hw *hw = s->private; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (dev) -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(wed_rtqm); -+ -+static int -+wed_rro_show(struct seq_file *s, void *data) -+{ -+ static const struct reg_dump regs[] = { -+ DUMP_STR("RRO/IND CMD CNT"), -+ DUMP_WED(WED_RX_IND_CMD_CNT(1)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(2)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(3)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(4)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(5)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(6)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(7)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(8)), -+ DUMP_WED_MASK(WED_RX_IND_CMD_CNT(9), -+ WED_IND_CMD_MAGIC_CNT_FAIL_CNT), -+ -+ DUMP_WED(WED_RX_ADDR_ELEM_CNT(0)), -+ DUMP_WED_MASK(WED_RX_ADDR_ELEM_CNT(1), -+ WED_ADDR_ELEM_SIG_FAIL_CNT), -+ DUMP_WED(WED_RX_MSDU_PG_CNT(1)), -+ DUMP_WED(WED_RX_MSDU_PG_CNT(2)), -+ DUMP_WED(WED_RX_MSDU_PG_CNT(3)), -+ DUMP_WED(WED_RX_MSDU_PG_CNT(4)), -+ DUMP_WED(WED_RX_MSDU_PG_CNT(5)), -+ DUMP_WED_MASK(WED_RX_PN_CHK_CNT, -+ WED_PN_CHK_FAIL_CNT), -+ }; -+ struct mtk_wed_hw *hw = s->private; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (dev) -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(wed_rro); -+ -+static int - mtk_wed_reg_set(void *data, u64 val) - { - struct mtk_wed_hw *hw = data; -@@ -266,7 +624,16 @@ void mtk_wed_hw_add_debugfs(struct mtk_w - debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg); - debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval); - debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops); -- if (!mtk_wed_is_v1(hw)) -+ if (!mtk_wed_is_v1(hw)) { - debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, - &wed_rxinfo_fops); -+ if (mtk_wed_is_v3_or_greater(hw)) { -+ debugfs_create_file_unsafe("amsdu", 0400, dir, hw, -+ &wed_amsdu_fops); -+ debugfs_create_file_unsafe("rtqm", 0400, dir, hw, -+ &wed_rtqm_fops); -+ debugfs_create_file_unsafe("rro", 0400, dir, hw, -+ &wed_rro_fops); -+ } -+ } - } diff --git a/target/linux/generic/backport-5.15/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch b/target/linux/generic/backport-5.15/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch deleted file mode 100644 index aaaabf05e8b276..00000000000000 --- a/target/linux/generic/backport-5.15/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch +++ /dev/null @@ -1,587 +0,0 @@ -From: Sujuan Chen -Date: Mon, 18 Sep 2023 12:29:19 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: add wed 3.0 reset support - -Introduce support for resetting Wireless Ethernet Dispatcher 3.0 -available on MT988 SoC. - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -148,6 +148,90 @@ mtk_wdma_read_reset(struct mtk_wed_devic - return wdma_r32(dev, MTK_WDMA_GLO_CFG); - } - -+static void -+mtk_wdma_v3_rx_reset(struct mtk_wed_device *dev) -+{ -+ u32 status; -+ -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) -+ return; -+ -+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN); -+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_PREF_TX_CFG)) -+ dev_err(dev->hw->dev, "rx reset failed\n"); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_PREF_RX_CFG)) -+ dev_err(dev->hw->dev, "rx reset failed\n"); -+ -+ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); -+ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_WRBK_TX_CFG)) -+ dev_err(dev->hw->dev, "rx reset failed\n"); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_WRBK_RX_CFG)) -+ dev_err(dev->hw->dev, "rx reset failed\n"); -+ -+ /* prefetch FIFO */ -+ wdma_w32(dev, MTK_WDMA_PREF_RX_FIFO_CFG, -+ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR | -+ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR); -+ wdma_clr(dev, MTK_WDMA_PREF_RX_FIFO_CFG, -+ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR | -+ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR); -+ -+ /* core FIFO */ -+ wdma_w32(dev, MTK_WDMA_XDMA_RX_FIFO_CFG, -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR); -+ wdma_clr(dev, MTK_WDMA_XDMA_RX_FIFO_CFG, -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR); -+ -+ /* writeback FIFO */ -+ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0), -+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); -+ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1), -+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); -+ -+ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0), -+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1), -+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); -+ -+ /* prefetch ring status */ -+ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG, -+ MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG, -+ MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR); -+ -+ /* writeback ring status */ -+ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG, -+ MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG, -+ MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR); -+} -+ - static int - mtk_wdma_rx_reset(struct mtk_wed_device *dev) - { -@@ -160,6 +244,7 @@ mtk_wdma_rx_reset(struct mtk_wed_device - if (ret) - dev_err(dev->hw->dev, "rx reset failed\n"); - -+ mtk_wdma_v3_rx_reset(dev); - wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); - wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); - -@@ -192,6 +277,84 @@ mtk_wed_poll_busy(struct mtk_wed_device - } - - static void -+mtk_wdma_v3_tx_reset(struct mtk_wed_device *dev) -+{ -+ u32 status; -+ -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) -+ return; -+ -+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN); -+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_PREF_TX_CFG)) -+ dev_err(dev->hw->dev, "tx reset failed\n"); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_PREF_RX_CFG)) -+ dev_err(dev->hw->dev, "tx reset failed\n"); -+ -+ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); -+ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_WRBK_TX_CFG)) -+ dev_err(dev->hw->dev, "tx reset failed\n"); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_WRBK_RX_CFG)) -+ dev_err(dev->hw->dev, "tx reset failed\n"); -+ -+ /* prefetch FIFO */ -+ wdma_w32(dev, MTK_WDMA_PREF_TX_FIFO_CFG, -+ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR | -+ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR); -+ wdma_clr(dev, MTK_WDMA_PREF_TX_FIFO_CFG, -+ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR | -+ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR); -+ -+ /* core FIFO */ -+ wdma_w32(dev, MTK_WDMA_XDMA_TX_FIFO_CFG, -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR); -+ wdma_clr(dev, MTK_WDMA_XDMA_TX_FIFO_CFG, -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR); -+ -+ /* writeback FIFO */ -+ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0), -+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); -+ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1), -+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); -+ -+ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0), -+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1), -+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); -+ -+ /* prefetch ring status */ -+ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG, -+ MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG, -+ MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR); -+ -+ /* writeback ring status */ -+ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG, -+ MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG, -+ MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR); -+} -+ -+static void - mtk_wdma_tx_reset(struct mtk_wed_device *dev) - { - u32 status, mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY; -@@ -202,6 +365,7 @@ mtk_wdma_tx_reset(struct mtk_wed_device - !(status & mask), 0, 10000)) - dev_err(dev->hw->dev, "tx reset failed\n"); - -+ mtk_wdma_v3_tx_reset(dev); - wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); - wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); - -@@ -1405,13 +1569,33 @@ mtk_wed_rx_reset(struct mtk_wed_device * - if (ret) - return ret; - -+ if (dev->wlan.hw_rro) { -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_HW_STS, -+ MTK_WED_RX_IND_CMD_BUSY); -+ mtk_wed_reset(dev, MTK_WED_RESET_RRO_RX_TO_PG); -+ } -+ - wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN); - ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, - MTK_WED_WPDMA_RX_D_RX_DRV_BUSY); -+ if (!ret && mtk_wed_is_v3_or_greater(dev->hw)) -+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, -+ MTK_WED_WPDMA_RX_D_PREF_BUSY); - if (ret) { - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV); - } else { -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ /* 1.a. disable prefetch HW */ -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, -+ MTK_WED_WPDMA_RX_D_PREF_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, -+ MTK_WED_WPDMA_RX_D_PREF_BUSY); -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL); -+ } -+ - wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, - MTK_WED_WPDMA_RX_D_RST_CRX_IDX | - MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -@@ -1439,23 +1623,52 @@ mtk_wed_rx_reset(struct mtk_wed_device * - wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0); - } - -+ if (dev->wlan.hw_rro) { -+ /* disable rro msdu page drv */ -+ wed_clr(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_EN); -+ -+ /* disable rro data drv */ -+ wed_clr(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN); -+ -+ /* rro msdu page drv reset */ -+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_CLR); -+ mtk_wed_poll_busy(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_CLR); -+ -+ /* rro data drv reset */ -+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(2), -+ MTK_WED_RRO_RX_D_DRV_CLR); -+ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_D_CFG(2), -+ MTK_WED_RRO_RX_D_DRV_CLR); -+ } -+ - /* reset route qm */ - wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); - ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL, - MTK_WED_CTRL_RX_ROUTE_QM_BUSY); -- if (ret) -+ if (ret) { - mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM); -- else -- wed_set(dev, MTK_WED_RTQM_GLO_CFG, -- MTK_WED_RTQM_Q_RST); -+ } else if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_set(dev, MTK_WED_RTQM_RST, BIT(0)); -+ wed_clr(dev, MTK_WED_RTQM_RST, BIT(0)); -+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM); -+ } else { -+ wed_set(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ } - - /* reset tx wdma */ - mtk_wdma_tx_reset(dev); - - /* reset tx wdma drv */ - wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN); -- mtk_wed_poll_busy(dev, MTK_WED_CTRL, -- MTK_WED_CTRL_WDMA_INT_AGENT_BUSY); -+ if (mtk_wed_is_v3_or_greater(dev->hw)) -+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_STATUS, -+ MTK_WED_WPDMA_STATUS_TX_DRV); -+ else -+ mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY); - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV); - - /* reset wed rx dma */ -@@ -1476,6 +1689,14 @@ mtk_wed_rx_reset(struct mtk_wed_device * - MTK_WED_CTRL_WED_RX_BM_BUSY); - mtk_wed_reset(dev, MTK_WED_RESET_RX_BM); - -+ if (dev->wlan.hw_rro) { -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WED_RX_PG_BM_BUSY); -+ wed_set(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM); -+ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM); -+ } -+ - /* wo change to enable state */ - val = MTK_WED_WO_STATE_ENABLE; - ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -@@ -1493,6 +1714,7 @@ mtk_wed_rx_reset(struct mtk_wed_device * - false); - } - mtk_wed_free_rx_buffer(dev); -+ mtk_wed_hwrro_free_buffer(dev); - - return 0; - } -@@ -1526,15 +1748,41 @@ mtk_wed_reset_dma(struct mtk_wed_device - - /* 2. reset WDMA rx DMA */ - busy = !!mtk_wdma_rx_reset(dev); -- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ val = MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE | -+ wed_r32(dev, MTK_WED_WDMA_GLO_CFG); -+ val &= ~MTK_WED_WDMA_GLO_CFG_RX_DRV_EN; -+ wed_w32(dev, MTK_WED_WDMA_GLO_CFG, val); -+ } else { -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); -+ } -+ - if (!busy) - busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG, - MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY); -+ if (!busy && mtk_wed_is_v3_or_greater(dev->hw)) -+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_BUSY); - - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV); - } else { -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ /* 1.a. disable prefetch HW */ -+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_BUSY); -+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_DDONE2_EN); -+ -+ /* 2. Reset dma index */ -+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX, -+ MTK_WED_WDMA_RESET_IDX_RX_ALL); -+ } -+ - wed_w32(dev, MTK_WED_WDMA_RESET_IDX, - MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV); - wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0); -@@ -1550,8 +1798,13 @@ mtk_wed_reset_dma(struct mtk_wed_device - wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - - for (i = 0; i < 100; i++) { -- val = wed_r32(dev, MTK_WED_TX_BM_INTF); -- if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40) -+ if (mtk_wed_is_v1(dev->hw)) -+ val = FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, -+ wed_r32(dev, MTK_WED_TX_BM_INTF)); -+ else -+ val = FIELD_GET(MTK_WED_TX_TKID_INTF_TKFIFO_FDEP, -+ wed_r32(dev, MTK_WED_TX_TKID_INTF)); -+ if (val == 0x40) - break; - } - -@@ -1573,6 +1826,8 @@ mtk_wed_reset_dma(struct mtk_wed_device - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV); - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV); -+ if (mtk_wed_is_v3_or_greater(dev->hw)) -+ wed_w32(dev, MTK_WED_RX1_CTRL2, 0); - } else { - wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, - MTK_WED_WPDMA_RESET_IDX_TX | -@@ -1589,7 +1844,14 @@ mtk_wed_reset_dma(struct mtk_wed_device - wed_w32(dev, MTK_WED_RESET_IDX, 0); - } - -- mtk_wed_rx_reset(dev); -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ /* reset amsdu engine */ -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN); -+ mtk_wed_reset(dev, MTK_WED_RESET_TX_AMSDU); -+ } -+ -+ if (mtk_wed_get_rx_capa(dev)) -+ mtk_wed_rx_reset(dev); - } - - static int -@@ -1841,6 +2103,7 @@ mtk_wed_dma_enable(struct mtk_wed_device - MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4); - - wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); -+ wdma_set(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN); - } - - wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -@@ -1904,6 +2167,12 @@ mtk_wed_start_hw_rro(struct mtk_wed_devi - if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro) - return; - -+ if (reset) { -+ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_EN); -+ return; -+ } -+ - wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR); - wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, - MTK_WED_RRO_MSDU_PG_DRV_CLR); ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -28,6 +28,8 @@ struct mtk_wdma_desc { - #define MTK_WED_RESET 0x008 - #define MTK_WED_RESET_TX_BM BIT(0) - #define MTK_WED_RESET_RX_BM BIT(1) -+#define MTK_WED_RESET_RX_PG_BM BIT(2) -+#define MTK_WED_RESET_RRO_RX_TO_PG BIT(3) - #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) - #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8) - #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9) -@@ -106,6 +108,9 @@ struct mtk_wdma_desc { - #define MTK_WED_STATUS 0x060 - #define MTK_WED_STATUS_TX GENMASK(15, 8) - -+#define MTK_WED_WPDMA_STATUS 0x068 -+#define MTK_WED_WPDMA_STATUS_TX_DRV GENMASK(15, 8) -+ - #define MTK_WED_TX_BM_CTRL 0x080 - #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0) - #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16) -@@ -140,6 +145,9 @@ struct mtk_wdma_desc { - #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16) - #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28) - -+#define MTK_WED_TX_TKID_INTF 0x0dc -+#define MTK_WED_TX_TKID_INTF_TKFIFO_FDEP GENMASK(25, 16) -+ - #define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3 GENMASK(7, 0) - #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3 GENMASK(23, 16) - -@@ -190,6 +198,7 @@ struct mtk_wdma_desc { - #define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10) - - #define MTK_WED_SCR0 0x3c0 -+#define MTK_WED_RX1_CTRL2 0x418 - #define MTK_WED_WPDMA_INT_TRIGGER 0x504 - #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1) - #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4) -@@ -303,6 +312,7 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_RX_D_RST_IDX 0x760 - #define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16) -+#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL BIT(20) - #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24) - - #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c -@@ -313,6 +323,7 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4 - #define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0) -+#define MTK_WED_WPDMA_RX_D_PREF_BUSY BIT(1) - #define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8) - #define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16) - -@@ -334,11 +345,13 @@ struct mtk_wdma_desc { - - #define MTK_WED_WDMA_RX_PREF_CFG 0x950 - #define MTK_WED_WDMA_RX_PREF_EN BIT(0) -+#define MTK_WED_WDMA_RX_PREF_BUSY BIT(1) - #define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8) - #define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16) - #define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24) - #define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25) - #define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26) -+#define MTK_WED_WDMA_RX_PREF_DDONE2_BUSY BIT(27) - - #define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C - #define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0) -@@ -367,6 +380,7 @@ struct mtk_wdma_desc { - - #define MTK_WED_WDMA_RESET_IDX 0xa08 - #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16) -+#define MTK_WED_WDMA_RESET_IDX_RX_ALL BIT(20) - #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24) - - #define MTK_WED_WDMA_INT_CLR 0xa24 -@@ -437,21 +451,62 @@ struct mtk_wdma_desc { - #define MTK_WDMA_INT_MASK_RX_DELAY BIT(30) - #define MTK_WDMA_INT_MASK_RX_COHERENT BIT(31) - -+#define MTK_WDMA_XDMA_TX_FIFO_CFG 0x238 -+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR BIT(0) -+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR BIT(4) -+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR BIT(8) -+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR BIT(12) -+ -+#define MTK_WDMA_XDMA_RX_FIFO_CFG 0x23c -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR BIT(0) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR BIT(4) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR BIT(8) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR BIT(12) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR BIT(15) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR BIT(18) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR BIT(21) -+ - #define MTK_WDMA_INT_GRP1 0x250 - #define MTK_WDMA_INT_GRP2 0x254 - - #define MTK_WDMA_PREF_TX_CFG 0x2d0 - #define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0) -+#define MTK_WDMA_PREF_TX_CFG_PREF_BUSY BIT(1) - - #define MTK_WDMA_PREF_RX_CFG 0x2dc - #define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0) -+#define MTK_WDMA_PREF_RX_CFG_PREF_BUSY BIT(1) -+ -+#define MTK_WDMA_PREF_RX_FIFO_CFG 0x2e0 -+#define MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR BIT(0) -+#define MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR BIT(16) -+ -+#define MTK_WDMA_PREF_TX_FIFO_CFG 0x2d4 -+#define MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR BIT(0) -+#define MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR BIT(16) -+ -+#define MTK_WDMA_PREF_SIDX_CFG 0x2e4 -+#define MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0) -+#define MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4) - - #define MTK_WDMA_WRBK_TX_CFG 0x300 -+#define MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY BIT(0) - #define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30) - -+#define MTK_WDMA_WRBK_TX_FIFO_CFG(_n) (0x304 + (_n) * 0x4) -+#define MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR BIT(0) -+ - #define MTK_WDMA_WRBK_RX_CFG 0x344 -+#define MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY BIT(0) - #define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30) - -+#define MTK_WDMA_WRBK_RX_FIFO_CFG(_n) (0x348 + (_n) * 0x4) -+#define MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR BIT(0) -+ -+#define MTK_WDMA_WRBK_SIDX_CFG 0x388 -+#define MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0) -+#define MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4) -+ - #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0) - #define MTK_PCIE_MIRROR_MAP_EN BIT(0) - #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1) -@@ -465,6 +520,8 @@ struct mtk_wdma_desc { - #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5) - #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20) - -+#define MTK_WED_RTQM_RST 0xb04 -+ - #define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c - #define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4) - #define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28 -@@ -653,6 +710,9 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17) - #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18) - -+#define MTK_WED_RRO_RX_HW_STS 0xf00 -+#define MTK_WED_RX_IND_CMD_BUSY GENMASK(31, 0) -+ - #define MTK_WED_RX_IND_CMD_CNT0 0xf20 - #define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31) - diff --git a/target/linux/generic/backport-5.15/764-01-v5.16-net-dsa-qca8k-fix-internal-delay-applied-to-the-wrong-PAD.patch b/target/linux/generic/backport-5.15/764-01-v5.16-net-dsa-qca8k-fix-internal-delay-applied-to-the-wrong-PAD.patch deleted file mode 100644 index df9518d86cd369..00000000000000 --- a/target/linux/generic/backport-5.15/764-01-v5.16-net-dsa-qca8k-fix-internal-delay-applied-to-the-wrong-PAD.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 3b00a07c2443745d62babfe08dbb2ad8e649526e Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Fri, 19 Nov 2021 03:03:49 +0100 -Subject: [PATCH] net: dsa: qca8k: fix internal delay applied to the wrong PAD - config - -With SGMII phy the internal delay is always applied to the PAD0 config. -This is caused by the falling edge configuration that hardcode the reg -to PAD0 (as the falling edge bits are present only in PAD0 reg) -Move the delay configuration before the reg overwrite to correctly apply -the delay. - -Fixes: cef08115846e ("net: dsa: qca8k: set internal delay also for sgmii") -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1433,6 +1433,12 @@ qca8k_phylink_mac_config(struct dsa_swit - - qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); - -+ /* From original code is reported port instability as SGMII also -+ * require delay set. Apply advised values here or take them from DT. -+ */ -+ if (state->interface == PHY_INTERFACE_MODE_SGMII) -+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -+ - /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and - * falling edge is set writing in the PORT0 PAD reg - */ -@@ -1455,12 +1461,6 @@ qca8k_phylink_mac_config(struct dsa_swit - QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, - val); - -- /* From original code is reported port instability as SGMII also -- * require delay set. Apply advised values here or take them from DT. -- */ -- if (state->interface == PHY_INTERFACE_MODE_SGMII) -- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -- - break; - default: - dev_err(ds->dev, "xMII mode %s not supported for port %d\n", diff --git a/target/linux/generic/backport-5.15/764-02-v5.16-net-dsa-qca8k-fix-MTU-calculation.patch b/target/linux/generic/backport-5.15/764-02-v5.16-net-dsa-qca8k-fix-MTU-calculation.patch deleted file mode 100644 index 7348d93ec44b57..00000000000000 --- a/target/linux/generic/backport-5.15/764-02-v5.16-net-dsa-qca8k-fix-MTU-calculation.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 65258b9d8cde45689bdc86ca39b50f01f983733b Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 19 Nov 2021 03:03:50 +0100 -Subject: [PATCH] net: dsa: qca8k: fix MTU calculation - -qca8k has a global MTU, so its tracking the MTU per port to make sure -that the largest MTU gets applied. -Since it uses the frame size instead of MTU the driver MTU change function -will then add the size of Ethernet header and checksum on top of MTU. - -The driver currently populates the per port MTU size as Ethernet frame -length + checksum which equals 1518. - -The issue is that then MTU change function will go through all of the -ports, find the largest MTU and apply the Ethernet header + checksum on -top of it again, so for a desired MTU of 1500 you will end up with 1536. - -This is obviously incorrect, so to correct it populate the per port struct -MTU with just the MTU and not include the Ethernet header + checksum size -as those will be added by the MTU change function. - -Fixes: f58d2598cf70 ("net: dsa: qca8k: implement the port MTU callbacks") -Signed-off-by: Robert Marko -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1256,8 +1256,12 @@ qca8k_setup(struct dsa_switch *ds) - /* Set initial MTU for every port. - * We have only have a general MTU setting. So track - * every port and set the max across all port. -+ * Set per port MTU to 1500 as the MTU change function -+ * will add the overhead and if its set to 1518 then it -+ * will apply the overhead again and we will end up with -+ * MTU of 1536 instead of 1518 - */ -- priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN; -+ priv->port_mtu[i] = ETH_DATA_LEN; - } - - /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ diff --git a/target/linux/generic/backport-5.15/764-03-v5.17-net-next-net-dsa-qca8k-remove-redundant-check-in-parse_port_config.patch b/target/linux/generic/backport-5.15/764-03-v5.17-net-next-net-dsa-qca8k-remove-redundant-check-in-parse_port_config.patch deleted file mode 100644 index f477b1b92985d9..00000000000000 --- a/target/linux/generic/backport-5.15/764-03-v5.17-net-next-net-dsa-qca8k-remove-redundant-check-in-parse_port_config.patch +++ /dev/null @@ -1,29 +0,0 @@ -From b9133f3ef5a2659730cf47a74bd0a9259f1cf8ff Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 22 Nov 2021 16:23:40 +0100 -Subject: net: dsa: qca8k: remove redundant check in parse_port_config - -The very next check for port 0 and 6 already makes sure we don't go out -of bounds with the ports_config delay table. -Remove the redundant check. - -Reported-by: kernel test robot -Reported-by: Dan Carpenter -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -983,7 +983,7 @@ qca8k_parse_port_config(struct qca8k_pri - u32 delay; - - /* We have 2 CPU port. Check them */ -- for (port = 0; port < QCA8K_NUM_PORTS && cpu_port_index < QCA8K_NUM_CPU_PORTS; port++) { -+ for (port = 0; port < QCA8K_NUM_PORTS; port++) { - /* Skip every other port */ - if (port != 0 && port != 6) - continue; diff --git a/target/linux/generic/backport-5.15/764-04-v5.17-net-next-net-dsa-qca8k-convert-to-GENMASK_FIELD_PREP_FIELD_GET.patch b/target/linux/generic/backport-5.15/764-04-v5.17-net-next-net-dsa-qca8k-convert-to-GENMASK_FIELD_PREP_FIELD_GET.patch deleted file mode 100644 index 2cea88089dbba5..00000000000000 --- a/target/linux/generic/backport-5.15/764-04-v5.17-net-next-net-dsa-qca8k-convert-to-GENMASK_FIELD_PREP_FIELD_GET.patch +++ /dev/null @@ -1,507 +0,0 @@ -From 90ae68bfc2ffcb54a4ba4f64edbeb84a80cbb57c Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 22 Nov 2021 16:23:41 +0100 -Subject: net: dsa: qca8k: convert to GENMASK/FIELD_PREP/FIELD_GET - -Convert and try to standardize bit fields using -GENMASK/FIELD_PREP/FIELD_GET macros. Rework some logic to support the -standard macro and tidy things up. No functional change intended. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 98 +++++++++++++++---------------- - drivers/net/dsa/qca8k.h | 153 ++++++++++++++++++++++++++---------------------- - 2 files changed, 130 insertions(+), 121 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -319,18 +320,18 @@ qca8k_fdb_read(struct qca8k_priv *priv, - } - - /* vid - 83:72 */ -- fdb->vid = (reg[2] >> QCA8K_ATU_VID_S) & QCA8K_ATU_VID_M; -+ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); - /* aging - 67:64 */ -- fdb->aging = reg[2] & QCA8K_ATU_STATUS_M; -+ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); - /* portmask - 54:48 */ -- fdb->port_mask = (reg[1] >> QCA8K_ATU_PORT_S) & QCA8K_ATU_PORT_M; -+ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); - /* mac - 47:0 */ -- fdb->mac[0] = (reg[1] >> QCA8K_ATU_ADDR0_S) & 0xff; -- fdb->mac[1] = reg[1] & 0xff; -- fdb->mac[2] = (reg[0] >> QCA8K_ATU_ADDR2_S) & 0xff; -- fdb->mac[3] = (reg[0] >> QCA8K_ATU_ADDR3_S) & 0xff; -- fdb->mac[4] = (reg[0] >> QCA8K_ATU_ADDR4_S) & 0xff; -- fdb->mac[5] = reg[0] & 0xff; -+ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); -+ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); -+ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); -+ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); -+ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); -+ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); - - return 0; - } -@@ -343,18 +344,18 @@ qca8k_fdb_write(struct qca8k_priv *priv, - int i; - - /* vid - 83:72 */ -- reg[2] = (vid & QCA8K_ATU_VID_M) << QCA8K_ATU_VID_S; -+ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); - /* aging - 67:64 */ -- reg[2] |= aging & QCA8K_ATU_STATUS_M; -+ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); - /* portmask - 54:48 */ -- reg[1] = (port_mask & QCA8K_ATU_PORT_M) << QCA8K_ATU_PORT_S; -+ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); - /* mac - 47:0 */ -- reg[1] |= mac[0] << QCA8K_ATU_ADDR0_S; -- reg[1] |= mac[1]; -- reg[0] |= mac[2] << QCA8K_ATU_ADDR2_S; -- reg[0] |= mac[3] << QCA8K_ATU_ADDR3_S; -- reg[0] |= mac[4] << QCA8K_ATU_ADDR4_S; -- reg[0] |= mac[5]; -+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); -+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); - - /* load the array into the ARL table */ - for (i = 0; i < 3; i++) -@@ -372,7 +373,7 @@ qca8k_fdb_access(struct qca8k_priv *priv - reg |= cmd; - if (port >= 0) { - reg |= QCA8K_ATU_FUNC_PORT_EN; -- reg |= (port & QCA8K_ATU_FUNC_PORT_M) << QCA8K_ATU_FUNC_PORT_S; -+ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); - } - - /* Write the function register triggering the table access */ -@@ -454,7 +455,7 @@ qca8k_vlan_access(struct qca8k_priv *pri - /* Set the command and VLAN index */ - reg = QCA8K_VTU_FUNC1_BUSY; - reg |= cmd; -- reg |= vid << QCA8K_VTU_FUNC1_VID_S; -+ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); - - /* Write the function register triggering the table access */ - ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); -@@ -500,13 +501,11 @@ qca8k_vlan_add(struct qca8k_priv *priv, - if (ret < 0) - goto out; - reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; -- reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << QCA8K_VTU_FUNC0_EG_MODE_S(port)); -+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); - if (untagged) -- reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG << -- QCA8K_VTU_FUNC0_EG_MODE_S(port); -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); - else -- reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG << -- QCA8K_VTU_FUNC0_EG_MODE_S(port); -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); - - ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); - if (ret) -@@ -534,15 +533,13 @@ qca8k_vlan_del(struct qca8k_priv *priv, - ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); - if (ret < 0) - goto out; -- reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port)); -- reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT << -- QCA8K_VTU_FUNC0_EG_MODE_S(port); -+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); - - /* Check if we're the last member to be removed */ - del = true; - for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- mask = QCA8K_VTU_FUNC0_EG_MODE_NOT; -- mask <<= QCA8K_VTU_FUNC0_EG_MODE_S(i); -+ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); - - if ((reg & mask) != mask) { - del = false; -@@ -1014,7 +1011,7 @@ qca8k_parse_port_config(struct qca8k_pri - mode == PHY_INTERFACE_MODE_RGMII_TXID) - delay = 1; - -- if (delay > QCA8K_MAX_DELAY) { -+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { - dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); - delay = 3; - } -@@ -1030,7 +1027,7 @@ qca8k_parse_port_config(struct qca8k_pri - mode == PHY_INTERFACE_MODE_RGMII_RXID) - delay = 2; - -- if (delay > QCA8K_MAX_DELAY) { -+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { - dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); - delay = 3; - } -@@ -1141,8 +1138,8 @@ qca8k_setup(struct dsa_switch *ds) - /* Enable QCA header mode on all cpu ports */ - if (dsa_is_cpu_port(ds, i)) { - ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), -- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S | -- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S); -+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | -+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); - if (ret) { - dev_err(priv->dev, "failed enabling QCA header mode"); - return ret; -@@ -1159,10 +1156,10 @@ qca8k_setup(struct dsa_switch *ds) - * for igmp, unknown, multicast and broadcast packet - */ - ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, -- BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S | -- BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S | -- BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S | -- BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S); -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); - if (ret) - return ret; - -@@ -1180,8 +1177,6 @@ qca8k_setup(struct dsa_switch *ds) - - /* Individual user ports get connected to CPU port only */ - if (dsa_is_user_port(ds, i)) { -- int shift = 16 * (i % 2); -- - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), - QCA8K_PORT_LOOKUP_MEMBER, - BIT(cpu_port)); -@@ -1198,8 +1193,8 @@ qca8k_setup(struct dsa_switch *ds) - * default egress vid - */ - ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), -- 0xfff << shift, -- QCA8K_PORT_VID_DEF << shift); -+ QCA8K_EGREES_VLAN_PORT_MASK(i), -+ QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); - if (ret) - return ret; - -@@ -1246,7 +1241,7 @@ qca8k_setup(struct dsa_switch *ds) - QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | - QCA8K_PORT_HOL_CTRL1_WRED_EN; - qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), -- QCA8K_PORT_HOL_CTRL1_ING_BUF | -+ QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | - QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | - QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | - QCA8K_PORT_HOL_CTRL1_WRED_EN, -@@ -1269,8 +1264,8 @@ qca8k_setup(struct dsa_switch *ds) - mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | - QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); - qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, -- QCA8K_GLOBAL_FC_GOL_XON_THRES_S | -- QCA8K_GLOBAL_FC_GOL_XOFF_THRES_S, -+ QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | -+ QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, - mask); - } - -@@ -1935,11 +1930,11 @@ qca8k_port_vlan_filtering(struct dsa_swi - - if (vlan_filtering) { - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_VLAN_MODE, -+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, - QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); - } else { - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_VLAN_MODE, -+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, - QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); - } - -@@ -1963,10 +1958,9 @@ qca8k_port_vlan_add(struct dsa_switch *d - } - - if (pvid) { -- int shift = 16 * (port % 2); -- - ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), -- 0xfff << shift, vlan->vid << shift); -+ QCA8K_EGREES_VLAN_PORT_MASK(port), -+ QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); - if (ret) - return ret; - -@@ -2060,7 +2054,7 @@ static int qca8k_read_switch_id(struct q - if (ret < 0) - return -ENODEV; - -- id = QCA8K_MASK_CTRL_DEVICE_ID(val & QCA8K_MASK_CTRL_DEVICE_ID_MASK); -+ id = QCA8K_MASK_CTRL_DEVICE_ID(val); - if (id != data->id) { - dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); - return -ENODEV; -@@ -2069,7 +2063,7 @@ static int qca8k_read_switch_id(struct q - priv->switch_id = id; - - /* Save revision to communicate to the internal PHY driver */ -- priv->switch_revision = (val & QCA8K_MASK_CTRL_REV_ID_MASK); -+ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); - - return 0; - } ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -30,9 +30,9 @@ - /* Global control registers */ - #define QCA8K_REG_MASK_CTRL 0x000 - #define QCA8K_MASK_CTRL_REV_ID_MASK GENMASK(7, 0) --#define QCA8K_MASK_CTRL_REV_ID(x) ((x) >> 0) -+#define QCA8K_MASK_CTRL_REV_ID(x) FIELD_GET(QCA8K_MASK_CTRL_REV_ID_MASK, x) - #define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8) --#define QCA8K_MASK_CTRL_DEVICE_ID(x) ((x) >> 8) -+#define QCA8K_MASK_CTRL_DEVICE_ID(x) FIELD_GET(QCA8K_MASK_CTRL_DEVICE_ID_MASK, x) - #define QCA8K_REG_PORT0_PAD_CTRL 0x004 - #define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31) - #define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19) -@@ -41,12 +41,11 @@ - #define QCA8K_REG_PORT6_PAD_CTRL 0x00c - #define QCA8K_PORT_PAD_RGMII_EN BIT(26) - #define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22) --#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) ((x) << 22) -+#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, x) - #define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20) --#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) ((x) << 20) -+#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, x) - #define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25) - #define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24) --#define QCA8K_MAX_DELAY 3 - #define QCA8K_PORT_PAD_SGMII_EN BIT(7) - #define QCA8K_REG_PWS 0x010 - #define QCA8K_PWS_POWER_ON_SEL BIT(31) -@@ -68,10 +67,12 @@ - #define QCA8K_MDIO_MASTER_READ BIT(27) - #define QCA8K_MDIO_MASTER_WRITE 0 - #define QCA8K_MDIO_MASTER_SUP_PRE BIT(26) --#define QCA8K_MDIO_MASTER_PHY_ADDR(x) ((x) << 21) --#define QCA8K_MDIO_MASTER_REG_ADDR(x) ((x) << 16) --#define QCA8K_MDIO_MASTER_DATA(x) (x) -+#define QCA8K_MDIO_MASTER_PHY_ADDR_MASK GENMASK(25, 21) -+#define QCA8K_MDIO_MASTER_PHY_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_PHY_ADDR_MASK, x) -+#define QCA8K_MDIO_MASTER_REG_ADDR_MASK GENMASK(20, 16) -+#define QCA8K_MDIO_MASTER_REG_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_REG_ADDR_MASK, x) - #define QCA8K_MDIO_MASTER_DATA_MASK GENMASK(15, 0) -+#define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) - #define QCA8K_MDIO_MASTER_MAX_PORTS 5 - #define QCA8K_MDIO_MASTER_MAX_REG 32 - #define QCA8K_GOL_MAC_ADDR0 0x60 -@@ -93,9 +94,7 @@ - #define QCA8K_PORT_STATUS_FLOW_AUTO BIT(12) - #define QCA8K_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4)) - #define QCA8K_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2) --#define QCA8K_PORT_HDR_CTRL_RX_S 2 - #define QCA8K_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0) --#define QCA8K_PORT_HDR_CTRL_TX_S 0 - #define QCA8K_PORT_HDR_CTRL_ALL 2 - #define QCA8K_PORT_HDR_CTRL_MGMT 1 - #define QCA8K_PORT_HDR_CTRL_NONE 0 -@@ -105,10 +104,11 @@ - #define QCA8K_SGMII_EN_TX BIT(3) - #define QCA8K_SGMII_EN_SD BIT(4) - #define QCA8K_SGMII_CLK125M_DELAY BIT(7) --#define QCA8K_SGMII_MODE_CTRL_MASK (BIT(22) | BIT(23)) --#define QCA8K_SGMII_MODE_CTRL_BASEX (0 << 22) --#define QCA8K_SGMII_MODE_CTRL_PHY (1 << 22) --#define QCA8K_SGMII_MODE_CTRL_MAC (2 << 22) -+#define QCA8K_SGMII_MODE_CTRL_MASK GENMASK(23, 22) -+#define QCA8K_SGMII_MODE_CTRL(x) FIELD_PREP(QCA8K_SGMII_MODE_CTRL_MASK, x) -+#define QCA8K_SGMII_MODE_CTRL_BASEX QCA8K_SGMII_MODE_CTRL(0x0) -+#define QCA8K_SGMII_MODE_CTRL_PHY QCA8K_SGMII_MODE_CTRL(0x1) -+#define QCA8K_SGMII_MODE_CTRL_MAC QCA8K_SGMII_MODE_CTRL(0x2) - - /* MAC_PWR_SEL registers */ - #define QCA8K_REG_MAC_PWR_SEL 0x0e4 -@@ -121,100 +121,115 @@ - - /* ACL registers */ - #define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8)) --#define QCA8K_PORT_VLAN_CVID(x) (x << 16) --#define QCA8K_PORT_VLAN_SVID(x) x -+#define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16) -+#define QCA8K_PORT_VLAN_CVID(x) FIELD_PREP(QCA8K_PORT_VLAN_CVID_MASK, x) -+#define QCA8K_PORT_VLAN_SVID_MASK GENMASK(11, 0) -+#define QCA8K_PORT_VLAN_SVID(x) FIELD_PREP(QCA8K_PORT_VLAN_SVID_MASK, x) - #define QCA8K_REG_PORT_VLAN_CTRL1(_i) (0x424 + (_i * 8)) - #define QCA8K_REG_IPV4_PRI_BASE_ADDR 0x470 - #define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474 - - /* Lookup registers */ - #define QCA8K_REG_ATU_DATA0 0x600 --#define QCA8K_ATU_ADDR2_S 24 --#define QCA8K_ATU_ADDR3_S 16 --#define QCA8K_ATU_ADDR4_S 8 -+#define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24) -+#define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16) -+#define QCA8K_ATU_ADDR4_MASK GENMASK(15, 8) -+#define QCA8K_ATU_ADDR5_MASK GENMASK(7, 0) - #define QCA8K_REG_ATU_DATA1 0x604 --#define QCA8K_ATU_PORT_M 0x7f --#define QCA8K_ATU_PORT_S 16 --#define QCA8K_ATU_ADDR0_S 8 -+#define QCA8K_ATU_PORT_MASK GENMASK(22, 16) -+#define QCA8K_ATU_ADDR0_MASK GENMASK(15, 8) -+#define QCA8K_ATU_ADDR1_MASK GENMASK(7, 0) - #define QCA8K_REG_ATU_DATA2 0x608 --#define QCA8K_ATU_VID_M 0xfff --#define QCA8K_ATU_VID_S 8 --#define QCA8K_ATU_STATUS_M 0xf -+#define QCA8K_ATU_VID_MASK GENMASK(19, 8) -+#define QCA8K_ATU_STATUS_MASK GENMASK(3, 0) - #define QCA8K_ATU_STATUS_STATIC 0xf - #define QCA8K_REG_ATU_FUNC 0x60c - #define QCA8K_ATU_FUNC_BUSY BIT(31) - #define QCA8K_ATU_FUNC_PORT_EN BIT(14) - #define QCA8K_ATU_FUNC_MULTI_EN BIT(13) - #define QCA8K_ATU_FUNC_FULL BIT(12) --#define QCA8K_ATU_FUNC_PORT_M 0xf --#define QCA8K_ATU_FUNC_PORT_S 8 -+#define QCA8K_ATU_FUNC_PORT_MASK GENMASK(11, 8) - #define QCA8K_REG_VTU_FUNC0 0x610 - #define QCA8K_VTU_FUNC0_VALID BIT(20) - #define QCA8K_VTU_FUNC0_IVL_EN BIT(19) --#define QCA8K_VTU_FUNC0_EG_MODE_S(_i) (4 + (_i) * 2) --#define QCA8K_VTU_FUNC0_EG_MODE_MASK 3 --#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD 0 --#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG 1 --#define QCA8K_VTU_FUNC0_EG_MODE_TAG 2 --#define QCA8K_VTU_FUNC0_EG_MODE_NOT 3 -+/* QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(17, 4) -+ * It does contain VLAN_MODE for each port [5:4] for port0, -+ * [7:6] for port1 ... [17:16] for port6. Use virtual port -+ * define to handle this. -+ */ -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i) (4 + (_i) * 2) -+#define QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(1, 0) -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(_i) (GENMASK(1, 0) << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) -+#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x0) -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNMOD(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNMOD << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) -+#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x1) -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNTAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) -+#define QCA8K_VTU_FUNC0_EG_MODE_TAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x2) -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_TAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) -+#define QCA8K_VTU_FUNC0_EG_MODE_NOT FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x3) -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(_i) (QCA8K_VTU_FUNC0_EG_MODE_NOT << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) - #define QCA8K_REG_VTU_FUNC1 0x614 - #define QCA8K_VTU_FUNC1_BUSY BIT(31) --#define QCA8K_VTU_FUNC1_VID_S 16 -+#define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16) - #define QCA8K_VTU_FUNC1_FULL BIT(4) - #define QCA8K_REG_GLOBAL_FW_CTRL0 0x620 - #define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) - #define QCA8K_REG_GLOBAL_FW_CTRL1 0x624 --#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S 24 --#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_S 16 --#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_S 8 --#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_S 0 -+#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24) -+#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16) -+#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8) -+#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0) - #define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc) - #define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0) --#define QCA8K_PORT_LOOKUP_VLAN_MODE GENMASK(9, 8) --#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE (0 << 8) --#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK (1 << 8) --#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK (2 << 8) --#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE (3 << 8) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE_MASK GENMASK(9, 8) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, x) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE QCA8K_PORT_LOOKUP_VLAN_MODE(0x0) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK QCA8K_PORT_LOOKUP_VLAN_MODE(0x1) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK QCA8K_PORT_LOOKUP_VLAN_MODE(0x2) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE QCA8K_PORT_LOOKUP_VLAN_MODE(0x3) - #define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16) --#define QCA8K_PORT_LOOKUP_STATE_DISABLED (0 << 16) --#define QCA8K_PORT_LOOKUP_STATE_BLOCKING (1 << 16) --#define QCA8K_PORT_LOOKUP_STATE_LISTENING (2 << 16) --#define QCA8K_PORT_LOOKUP_STATE_LEARNING (3 << 16) --#define QCA8K_PORT_LOOKUP_STATE_FORWARD (4 << 16) --#define QCA8K_PORT_LOOKUP_STATE GENMASK(18, 16) -+#define QCA8K_PORT_LOOKUP_STATE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_STATE_MASK, x) -+#define QCA8K_PORT_LOOKUP_STATE_DISABLED QCA8K_PORT_LOOKUP_STATE(0x0) -+#define QCA8K_PORT_LOOKUP_STATE_BLOCKING QCA8K_PORT_LOOKUP_STATE(0x1) -+#define QCA8K_PORT_LOOKUP_STATE_LISTENING QCA8K_PORT_LOOKUP_STATE(0x2) -+#define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3) -+#define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4) - #define QCA8K_PORT_LOOKUP_LEARN BIT(20) - - #define QCA8K_REG_GLOBAL_FC_THRESH 0x800 --#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) ((x) << 16) --#define QCA8K_GLOBAL_FC_GOL_XON_THRES_S GENMASK(24, 16) --#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) ((x) << 0) --#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_S GENMASK(8, 0) -+#define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16) -+#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x) -+#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK GENMASK(8, 0) -+#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, x) - - #define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF GENMASK(3, 0) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) ((x) << 0) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF GENMASK(7, 4) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) ((x) << 4) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF GENMASK(11, 8) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) ((x) << 8) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF GENMASK(15, 12) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) ((x) << 12) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF GENMASK(19, 16) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) ((x) << 16) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF GENMASK(23, 20) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) ((x) << 20) --#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF GENMASK(29, 24) --#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) ((x) << 24) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK GENMASK(3, 0) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK GENMASK(7, 4) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK GENMASK(11, 8) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK GENMASK(15, 12) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK GENMASK(19, 16) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK GENMASK(23, 20) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK GENMASK(29, 24) -+#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK, x) - - #define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8) --#define QCA8K_PORT_HOL_CTRL1_ING_BUF GENMASK(3, 0) --#define QCA8K_PORT_HOL_CTRL1_ING(x) ((x) << 0) -+#define QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK GENMASK(3, 0) -+#define QCA8K_PORT_HOL_CTRL1_ING(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK, x) - #define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6) - #define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7) - #define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8) - #define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16) - - /* Pkt edit registers */ -+#define QCA8K_EGREES_VLAN_PORT_SHIFT(_i) (16 * ((_i) % 2)) -+#define QCA8K_EGREES_VLAN_PORT_MASK(_i) (GENMASK(11, 0) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) -+#define QCA8K_EGREES_VLAN_PORT(_i, x) ((x) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) - #define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2))) - - /* L3 registers */ diff --git a/target/linux/generic/backport-5.15/764-05-v5.17-net-next-net-dsa-qca8k-remove-extra-mutex_init-in-qca8k_setup.patch b/target/linux/generic/backport-5.15/764-05-v5.17-net-next-net-dsa-qca8k-remove-extra-mutex_init-in-qca8k_setup.patch deleted file mode 100644 index 8c39b8ea295a43..00000000000000 --- a/target/linux/generic/backport-5.15/764-05-v5.17-net-next-net-dsa-qca8k-remove-extra-mutex_init-in-qca8k_setup.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 994c28b6f971fa5db8ae977daea37eee87d93d51 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 22 Nov 2021 16:23:42 +0100 -Subject: net: dsa: qca8k: remove extra mutex_init in qca8k_setup - -Mutex is already init in sw_probe. Remove the extra init in qca8k_setup. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1086,8 +1086,6 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -- mutex_init(&priv->reg_mutex); -- - /* Start by setting up the register mapping */ - priv->regmap = devm_regmap_init(ds->dev, NULL, priv, - &qca8k_regmap_config); diff --git a/target/linux/generic/backport-5.15/764-06-v5.17-net-next-net-dsa-qca8k-move-regmap-init-in-probe-and-set-it.patch b/target/linux/generic/backport-5.15/764-06-v5.17-net-next-net-dsa-qca8k-move-regmap-init-in-probe-and-set-it.patch deleted file mode 100644 index 44d938c53e85e0..00000000000000 --- a/target/linux/generic/backport-5.15/764-06-v5.17-net-next-net-dsa-qca8k-move-regmap-init-in-probe-and-set-it.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 36b8af12f424e7a7f60a935c60a0fd4aa0822378 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 22 Nov 2021 16:23:43 +0100 -Subject: net: dsa: qca8k: move regmap init in probe and set it mandatory - -In preparation for regmap conversion, move regmap init in the probe -function and make it mandatory as any read/write/rmw operation will be -converted to regmap API. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1086,12 +1086,6 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -- /* Start by setting up the register mapping */ -- priv->regmap = devm_regmap_init(ds->dev, NULL, priv, -- &qca8k_regmap_config); -- if (IS_ERR(priv->regmap)) -- dev_warn(priv->dev, "regmap initialization failed"); -- - ret = qca8k_setup_mdio_bus(priv); - if (ret) - return ret; -@@ -2096,6 +2090,14 @@ qca8k_sw_probe(struct mdio_device *mdiod - gpiod_set_value_cansleep(priv->reset_gpio, 0); - } - -+ /* Start by setting up the register mapping */ -+ priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv, -+ &qca8k_regmap_config); -+ if (IS_ERR(priv->regmap)) { -+ dev_err(priv->dev, "regmap initialization failed"); -+ return PTR_ERR(priv->regmap); -+ } -+ - /* Check the detected switch id */ - ret = qca8k_read_switch_id(priv); - if (ret) diff --git a/target/linux/generic/backport-5.15/764-07-v5.17-net-next-net-dsa-qca8k-initial-conversion-to-regmap-heper.patch b/target/linux/generic/backport-5.15/764-07-v5.17-net-next-net-dsa-qca8k-initial-conversion-to-regmap-heper.patch deleted file mode 100644 index 4ca9c8ba41d684..00000000000000 --- a/target/linux/generic/backport-5.15/764-07-v5.17-net-next-net-dsa-qca8k-initial-conversion-to-regmap-heper.patch +++ /dev/null @@ -1,249 +0,0 @@ -From 8b5f3f29a81a71934d004e21a1292c1148b05926 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 22 Nov 2021 16:23:44 +0100 -Subject: net: dsa: qca8k: initial conversion to regmap helper - -Convert any qca8k set/clear/pool to regmap helper and add -missing config to regmap_config struct. -Read/write/rmw operation are reworked to use the regmap helper -internally to keep the delta of this patch low. These additional -function will then be dropped when the code split will be proposed. - -Ipq40xx SoC have the internal switch based on the qca8k regmap but use -mmio for read/write/rmw operation instead of mdio. -In preparation for the support of this internal switch, convert the -driver to regmap API to later split the driver to common and specific -code. The overhead introduced by the use of regamp API is marginal as the -internal mdio will bypass it by using its direct access and regmap will be -used only by configuration functions or fdb access. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 107 +++++++++++++++++++++--------------------------- - 1 file changed, 47 insertions(+), 60 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -152,6 +153,25 @@ qca8k_set_page(struct mii_bus *bus, u16 - static int - qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) - { -+ return regmap_read(priv->regmap, reg, val); -+} -+ -+static int -+qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) -+{ -+ return regmap_write(priv->regmap, reg, val); -+} -+ -+static int -+qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) -+{ -+ return regmap_update_bits(priv->regmap, reg, mask, write_val); -+} -+ -+static int -+qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; - struct mii_bus *bus = priv->bus; - u16 r1, r2, page; - int ret; -@@ -172,8 +192,9 @@ exit: - } - - static int --qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) -+qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) - { -+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; - struct mii_bus *bus = priv->bus; - u16 r1, r2, page; - int ret; -@@ -194,8 +215,9 @@ exit: - } - - static int --qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) -+qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) - { -+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; - struct mii_bus *bus = priv->bus; - u16 r1, r2, page; - u32 val; -@@ -223,34 +245,6 @@ exit: - return ret; - } - --static int --qca8k_reg_set(struct qca8k_priv *priv, u32 reg, u32 val) --{ -- return qca8k_rmw(priv, reg, 0, val); --} -- --static int --qca8k_reg_clear(struct qca8k_priv *priv, u32 reg, u32 val) --{ -- return qca8k_rmw(priv, reg, val, 0); --} -- --static int --qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -- -- return qca8k_read(priv, reg, val); --} -- --static int --qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -- -- return qca8k_write(priv, reg, val); --} -- - static const struct regmap_range qca8k_readable_ranges[] = { - regmap_reg_range(0x0000, 0x00e4), /* Global control */ - regmap_reg_range(0x0100, 0x0168), /* EEE control */ -@@ -282,26 +276,19 @@ static struct regmap_config qca8k_regmap - .max_register = 0x16ac, /* end MIB - Port6 range */ - .reg_read = qca8k_regmap_read, - .reg_write = qca8k_regmap_write, -+ .reg_update_bits = qca8k_regmap_update_bits, - .rd_table = &qca8k_readable_table, -+ .disable_locking = true, /* Locking is handled by qca8k read/write */ -+ .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ - }; - - static int - qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) - { -- int ret, ret1; - u32 val; - -- ret = read_poll_timeout(qca8k_read, ret1, !(val & mask), -- 0, QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -- priv, reg, &val); -- -- /* Check if qca8k_read has failed for a different reason -- * before returning -ETIMEDOUT -- */ -- if (ret < 0 && ret1 < 0) -- return ret1; -- -- return ret; -+ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, -+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); - } - - static int -@@ -568,7 +555,7 @@ qca8k_mib_init(struct qca8k_priv *priv) - int ret; - - mutex_lock(&priv->reg_mutex); -- ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY); -+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY); - if (ret) - goto exit; - -@@ -576,7 +563,7 @@ qca8k_mib_init(struct qca8k_priv *priv) - if (ret) - goto exit; - -- ret = qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); -+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); - if (ret) - goto exit; - -@@ -597,9 +584,9 @@ qca8k_port_set_status(struct qca8k_priv - mask |= QCA8K_PORT_STATUS_LINK_AUTO; - - if (enable) -- qca8k_reg_set(priv, QCA8K_REG_PORT_STATUS(port), mask); -+ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); - else -- qca8k_reg_clear(priv, QCA8K_REG_PORT_STATUS(port), mask); -+ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); - } - - static u32 -@@ -861,8 +848,8 @@ qca8k_setup_mdio_bus(struct qca8k_priv * - * a dt-overlay and driver reload changed the configuration - */ - -- return qca8k_reg_clear(priv, QCA8K_MDIO_MASTER_CTRL, -- QCA8K_MDIO_MASTER_EN); -+ return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL, -+ QCA8K_MDIO_MASTER_EN); - } - - /* Check if the devicetree declare the port:phy mapping */ -@@ -1099,16 +1086,16 @@ qca8k_setup(struct dsa_switch *ds) - return ret; - - /* Make sure MAC06 is disabled */ -- ret = qca8k_reg_clear(priv, QCA8K_REG_PORT0_PAD_CTRL, -- QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); -+ ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, -+ QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); - if (ret) { - dev_err(priv->dev, "failed disabling MAC06 exchange"); - return ret; - } - - /* Enable CPU Port */ -- ret = qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0, -- QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); -+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); - if (ret) { - dev_err(priv->dev, "failed enabling CPU port"); - return ret; -@@ -1176,8 +1163,8 @@ qca8k_setup(struct dsa_switch *ds) - return ret; - - /* Enable ARP Auto-learning by default */ -- ret = qca8k_reg_set(priv, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_LEARN); -+ ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), -+ QCA8K_PORT_LOOKUP_LEARN); - if (ret) - return ret; - -@@ -1745,9 +1732,9 @@ qca8k_port_bridge_join(struct dsa_switch - /* Add this port to the portvlan mask of the other ports - * in the bridge - */ -- ret = qca8k_reg_set(priv, -- QCA8K_PORT_LOOKUP_CTRL(i), -- BIT(port)); -+ ret = regmap_set_bits(priv->regmap, -+ QCA8K_PORT_LOOKUP_CTRL(i), -+ BIT(port)); - if (ret) - return ret; - if (i != port) -@@ -1777,9 +1764,9 @@ qca8k_port_bridge_leave(struct dsa_switc - /* Remove this port to the portvlan mask of the other ports - * in the bridge - */ -- qca8k_reg_clear(priv, -- QCA8K_PORT_LOOKUP_CTRL(i), -- BIT(port)); -+ regmap_clear_bits(priv->regmap, -+ QCA8K_PORT_LOOKUP_CTRL(i), -+ BIT(port)); - } - - /* Set the cpu port to be the only one in the portvlan mask of diff --git a/target/linux/generic/backport-5.15/764-08-v5.17-net-next-net-dsa-qca8k-add-additional-MIB-counter-and-.patch b/target/linux/generic/backport-5.15/764-08-v5.17-net-next-net-dsa-qca8k-add-additional-MIB-counter-and-.patch deleted file mode 100644 index c8c050933b687b..00000000000000 --- a/target/linux/generic/backport-5.15/764-08-v5.17-net-next-net-dsa-qca8k-add-additional-MIB-counter-and-.patch +++ /dev/null @@ -1,120 +0,0 @@ -From c126f118b330ccf0db0dda4a4bd6c729865a205f Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 22 Nov 2021 16:23:45 +0100 -Subject: net: dsa: qca8k: add additional MIB counter and make it dynamic - -We are currently missing 2 additionals MIB counter present in QCA833x -switch. -QC832x switch have 39 MIB counter and QCA833X have 41 MIB counter. -Add the additional MIB counter and rework the MIB function to print the -correct supported counter from the match_data struct. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 23 ++++++++++++++++++++--- - drivers/net/dsa/qca8k.h | 4 ++++ - 2 files changed, 24 insertions(+), 3 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -70,6 +70,8 @@ static const struct qca8k_mib_desc ar832 - MIB_DESC(1, 0x9c, "TxExcDefer"), - MIB_DESC(1, 0xa0, "TxDefer"), - MIB_DESC(1, 0xa4, "TxLateCol"), -+ MIB_DESC(1, 0xa8, "RXUnicast"), -+ MIB_DESC(1, 0xac, "TXUnicast"), - }; - - /* The 32bit switch registers are accessed indirectly. To achieve this we need -@@ -1605,12 +1607,16 @@ qca8k_phylink_mac_link_up(struct dsa_swi - static void - qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) - { -+ const struct qca8k_match_data *match_data; -+ struct qca8k_priv *priv = ds->priv; - int i; - - if (stringset != ETH_SS_STATS) - return; - -- for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) -+ match_data = of_device_get_match_data(priv->dev); -+ -+ for (i = 0; i < match_data->mib_count; i++) - strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, - ETH_GSTRING_LEN); - } -@@ -1620,12 +1626,15 @@ qca8k_get_ethtool_stats(struct dsa_switc - uint64_t *data) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ const struct qca8k_match_data *match_data; - const struct qca8k_mib_desc *mib; - u32 reg, i, val; - u32 hi = 0; - int ret; - -- for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) { -+ match_data = of_device_get_match_data(priv->dev); -+ -+ for (i = 0; i < match_data->mib_count; i++) { - mib = &ar8327_mib[i]; - reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; - -@@ -1648,10 +1657,15 @@ qca8k_get_ethtool_stats(struct dsa_switc - static int - qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) - { -+ const struct qca8k_match_data *match_data; -+ struct qca8k_priv *priv = ds->priv; -+ - if (sset != ETH_SS_STATS) - return 0; - -- return ARRAY_SIZE(ar8327_mib); -+ match_data = of_device_get_match_data(priv->dev); -+ -+ return match_data->mib_count; - } - - static int -@@ -2173,14 +2187,17 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, - static const struct qca8k_match_data qca8327 = { - .id = QCA8K_ID_QCA8327, - .reduced_package = true, -+ .mib_count = QCA8K_QCA832X_MIB_COUNT, - }; - - static const struct qca8k_match_data qca8328 = { - .id = QCA8K_ID_QCA8327, -+ .mib_count = QCA8K_QCA832X_MIB_COUNT, - }; - - static const struct qca8k_match_data qca833x = { - .id = QCA8K_ID_QCA8337, -+ .mib_count = QCA8K_QCA833X_MIB_COUNT, - }; - - static const struct of_device_id qca8k_of_match[] = { ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -21,6 +21,9 @@ - #define PHY_ID_QCA8337 0x004dd036 - #define QCA8K_ID_QCA8337 0x13 - -+#define QCA8K_QCA832X_MIB_COUNT 39 -+#define QCA8K_QCA833X_MIB_COUNT 41 -+ - #define QCA8K_BUSY_WAIT_TIMEOUT 2000 - - #define QCA8K_NUM_FDB_RECORDS 2048 -@@ -279,6 +282,7 @@ struct ar8xxx_port_status { - struct qca8k_match_data { - u8 id; - bool reduced_package; -+ u8 mib_count; - }; - - enum { diff --git a/target/linux/generic/backport-5.15/764-09-v5.17-net-next-net-dsa-qca8k-add-support-for-port-fast-aging.patch b/target/linux/generic/backport-5.15/764-09-v5.17-net-next-net-dsa-qca8k-add-support-for-port-fast-aging.patch deleted file mode 100644 index 8ad7ab472d4f9a..00000000000000 --- a/target/linux/generic/backport-5.15/764-09-v5.17-net-next-net-dsa-qca8k-add-support-for-port-fast-aging.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 4592538bfb0d5d3c3c8a1d7071724d081412ac91 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 22 Nov 2021 16:23:46 +0100 -Subject: net: dsa: qca8k: add support for port fast aging - -The switch supports fast aging by flushing any rule in the ARL -table for a specific port. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 11 +++++++++++ - drivers/net/dsa/qca8k.h | 1 + - 2 files changed, 12 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1790,6 +1790,16 @@ qca8k_port_bridge_leave(struct dsa_switc - QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); - } - -+static void -+qca8k_port_fast_age(struct dsa_switch *ds, int port) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); -+ mutex_unlock(&priv->reg_mutex); -+} -+ - static int - qca8k_port_enable(struct dsa_switch *ds, int port, - struct phy_device *phy) -@@ -2017,6 +2027,7 @@ static const struct dsa_switch_ops qca8k - .port_stp_state_set = qca8k_port_stp_state_set, - .port_bridge_join = qca8k_port_bridge_join, - .port_bridge_leave = qca8k_port_bridge_leave, -+ .port_fast_age = qca8k_port_fast_age, - .port_fdb_add = qca8k_port_fdb_add, - .port_fdb_del = qca8k_port_fdb_del, - .port_fdb_dump = qca8k_port_fdb_dump, ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -262,6 +262,7 @@ enum qca8k_fdb_cmd { - QCA8K_FDB_FLUSH = 1, - QCA8K_FDB_LOAD = 2, - QCA8K_FDB_PURGE = 3, -+ QCA8K_FDB_FLUSH_PORT = 5, - QCA8K_FDB_NEXT = 6, - QCA8K_FDB_SEARCH = 7, - }; diff --git a/target/linux/generic/backport-5.15/764-10-v5.17-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch b/target/linux/generic/backport-5.15/764-10-v5.17-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch deleted file mode 100644 index 659e482405a55a..00000000000000 --- a/target/linux/generic/backport-5.15/764-10-v5.17-net-next-net-dsa-qca8k-add-set_ageing_time-support.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 6a3bdc5209f45d2af83aa92433ab6e5cf2297aa4 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 22 Nov 2021 16:23:47 +0100 -Subject: net: dsa: qca8k: add set_ageing_time support - -qca8k support setting ageing time in step of 7s. Add support for it and -set the max value accepted of 7645m. -Documentation talks about support for 10000m but that values doesn't -make sense as the value doesn't match the max value in the reg. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 25 +++++++++++++++++++++++++ - drivers/net/dsa/qca8k.h | 3 +++ - 2 files changed, 28 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1261,6 +1261,10 @@ qca8k_setup(struct dsa_switch *ds) - /* We don't have interrupts for link changes, so we need to poll */ - ds->pcs_poll = true; - -+ /* Set min a max ageing value supported */ -+ ds->ageing_time_min = 7000; -+ ds->ageing_time_max = 458745000; -+ - return 0; - } - -@@ -1801,6 +1805,26 @@ qca8k_port_fast_age(struct dsa_switch *d - } - - static int -+qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ unsigned int secs = msecs / 1000; -+ u32 val; -+ -+ /* AGE_TIME reg is set in 7s step */ -+ val = secs / 7; -+ -+ /* Handle case with 0 as val to NOT disable -+ * learning -+ */ -+ if (!val) -+ val = 1; -+ -+ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, -+ QCA8K_ATU_AGE_TIME(val)); -+} -+ -+static int - qca8k_port_enable(struct dsa_switch *ds, int port, - struct phy_device *phy) - { -@@ -2018,6 +2042,7 @@ static const struct dsa_switch_ops qca8k - .get_strings = qca8k_get_strings, - .get_ethtool_stats = qca8k_get_ethtool_stats, - .get_sset_count = qca8k_get_sset_count, -+ .set_ageing_time = qca8k_set_ageing_time, - .get_mac_eee = qca8k_get_mac_eee, - .set_mac_eee = qca8k_set_mac_eee, - .port_enable = qca8k_port_enable, ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -175,6 +175,9 @@ - #define QCA8K_VTU_FUNC1_BUSY BIT(31) - #define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16) - #define QCA8K_VTU_FUNC1_FULL BIT(4) -+#define QCA8K_REG_ATU_CTRL 0x618 -+#define QCA8K_ATU_AGE_TIME_MASK GENMASK(15, 0) -+#define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x)) - #define QCA8K_REG_GLOBAL_FW_CTRL0 0x620 - #define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) - #define QCA8K_REG_GLOBAL_FW_CTRL1 0x624 diff --git a/target/linux/generic/backport-5.15/764-11-v5.17-net-next-net-dsa-qca8k-add-support-for-mdb_add-del.patch b/target/linux/generic/backport-5.15/764-11-v5.17-net-next-net-dsa-qca8k-add-support-for-mdb_add-del.patch deleted file mode 100644 index 8b97939ecb290f..00000000000000 --- a/target/linux/generic/backport-5.15/764-11-v5.17-net-next-net-dsa-qca8k-add-support-for-mdb_add-del.patch +++ /dev/null @@ -1,142 +0,0 @@ -From ba8f870dfa635113ce6e8095a5eb1835ecde2e9e Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 22 Nov 2021 16:23:48 +0100 -Subject: net: dsa: qca8k: add support for mdb_add/del - -Add support for mdb add/del function. The ARL table is used to insert -the rule. The rule will be searched, deleted and reinserted with the -port mask updated. The function will check if the rule has to be updated -or insert directly with no deletion of the old rule. -If every port is removed from the port mask, the rule is removed. -The rule is set STATIC in the ARL table (aka it doesn't age) to not be -flushed by fast age function. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 99 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -436,6 +436,81 @@ qca8k_fdb_flush(struct qca8k_priv *priv) - } - - static int -+qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, -+ const u8 *mac, u16 vid) -+{ -+ struct qca8k_fdb fdb = { 0 }; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ qca8k_fdb_write(priv, vid, 0, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -+ if (ret < 0) -+ goto exit; -+ -+ ret = qca8k_fdb_read(priv, &fdb); -+ if (ret < 0) -+ goto exit; -+ -+ /* Rule exist. Delete first */ -+ if (!fdb.aging) { -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ if (ret) -+ goto exit; -+ } -+ -+ /* Add port to fdb portmask */ -+ fdb.port_mask |= port_mask; -+ -+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static int -+qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, -+ const u8 *mac, u16 vid) -+{ -+ struct qca8k_fdb fdb = { 0 }; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ qca8k_fdb_write(priv, vid, 0, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -+ if (ret < 0) -+ goto exit; -+ -+ /* Rule doesn't exist. Why delete? */ -+ if (!fdb.aging) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ if (ret) -+ goto exit; -+ -+ /* Only port in the rule is this port. Don't re insert */ -+ if (fdb.port_mask == port_mask) -+ goto exit; -+ -+ /* Remove port from port mask */ -+ fdb.port_mask &= ~port_mask; -+ -+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static int - qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) - { - u32 reg; -@@ -1949,6 +2024,28 @@ qca8k_port_fdb_dump(struct dsa_switch *d - } - - static int -+qca8k_port_mdb_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ const u8 *addr = mdb->addr; -+ u16 vid = mdb->vid; -+ -+ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); -+} -+ -+static int -+qca8k_port_mdb_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ const u8 *addr = mdb->addr; -+ u16 vid = mdb->vid; -+ -+ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); -+} -+ -+static int - qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, - struct netlink_ext_ack *extack) - { -@@ -2056,6 +2153,8 @@ static const struct dsa_switch_ops qca8k - .port_fdb_add = qca8k_port_fdb_add, - .port_fdb_del = qca8k_port_fdb_del, - .port_fdb_dump = qca8k_port_fdb_dump, -+ .port_mdb_add = qca8k_port_mdb_add, -+ .port_mdb_del = qca8k_port_mdb_del, - .port_vlan_filtering = qca8k_port_vlan_filtering, - .port_vlan_add = qca8k_port_vlan_add, - .port_vlan_del = qca8k_port_vlan_del, diff --git a/target/linux/generic/backport-5.15/764-12-v5.17-net-next-net-dsa-qca8k-add-support-for-mirror-mode.patch b/target/linux/generic/backport-5.15/764-12-v5.17-net-next-net-dsa-qca8k-add-support-for-mirror-mode.patch deleted file mode 100644 index dc5a22935f1da5..00000000000000 --- a/target/linux/generic/backport-5.15/764-12-v5.17-net-next-net-dsa-qca8k-add-support-for-mirror-mode.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 2c1bdbc7e7560d7de754cad277d968d56bb1899e Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 23 Nov 2021 03:59:10 +0100 -Subject: net: dsa: qca8k: add support for mirror mode - -The switch supports mirror mode. Only one port can set as mirror port and -every other port can set to both ingress and egress mode. The mirror -port is disabled and reverted to normal operation once every port is -removed from sending packet to it. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ - drivers/net/dsa/qca8k.h | 4 +++ - 2 files changed, 99 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -2046,6 +2046,99 @@ qca8k_port_mdb_del(struct dsa_switch *ds - } - - static int -+qca8k_port_mirror_add(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror, -+ bool ingress) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int monitor_port, ret; -+ u32 reg, val; -+ -+ /* Check for existent entry */ -+ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) -+ return -EEXIST; -+ -+ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); -+ if (ret) -+ return ret; -+ -+ /* QCA83xx can have only one port set to mirror mode. -+ * Check that the correct port is requested and return error otherwise. -+ * When no mirror port is set, the values is set to 0xF -+ */ -+ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (monitor_port != 0xF && monitor_port != mirror->to_local_port) -+ return -EEXIST; -+ -+ /* Set the monitor port */ -+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, -+ mirror->to_local_port); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (ret) -+ return ret; -+ -+ if (ingress) { -+ reg = QCA8K_PORT_LOOKUP_CTRL(port); -+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -+ } else { -+ reg = QCA8K_REG_PORT_HOL_CTRL1(port); -+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -+ } -+ -+ ret = regmap_update_bits(priv->regmap, reg, val, val); -+ if (ret) -+ return ret; -+ -+ /* Track mirror port for tx and rx to decide when the -+ * mirror port has to be disabled. -+ */ -+ if (ingress) -+ priv->mirror_rx |= BIT(port); -+ else -+ priv->mirror_tx |= BIT(port); -+ -+ return 0; -+} -+ -+static void -+qca8k_port_mirror_del(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ u32 reg, val; -+ int ret; -+ -+ if (mirror->ingress) { -+ reg = QCA8K_PORT_LOOKUP_CTRL(port); -+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -+ } else { -+ reg = QCA8K_REG_PORT_HOL_CTRL1(port); -+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -+ } -+ -+ ret = regmap_clear_bits(priv->regmap, reg, val); -+ if (ret) -+ goto err; -+ -+ if (mirror->ingress) -+ priv->mirror_rx &= ~BIT(port); -+ else -+ priv->mirror_tx &= ~BIT(port); -+ -+ /* No port set to send packet to mirror port. Disable mirror port */ -+ if (!priv->mirror_rx && !priv->mirror_tx) { -+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (ret) -+ goto err; -+ } -+err: -+ dev_err(priv->dev, "Failed to del mirror port from %d", port); -+} -+ -+static int - qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, - struct netlink_ext_ack *extack) - { -@@ -2155,6 +2248,8 @@ static const struct dsa_switch_ops qca8k - .port_fdb_dump = qca8k_port_fdb_dump, - .port_mdb_add = qca8k_port_mdb_add, - .port_mdb_del = qca8k_port_mdb_del, -+ .port_mirror_add = qca8k_port_mirror_add, -+ .port_mirror_del = qca8k_port_mirror_del, - .port_vlan_filtering = qca8k_port_vlan_filtering, - .port_vlan_add = qca8k_port_vlan_add, - .port_vlan_del = qca8k_port_vlan_del, ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -180,6 +180,7 @@ - #define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x)) - #define QCA8K_REG_GLOBAL_FW_CTRL0 0x620 - #define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) -+#define QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM GENMASK(7, 4) - #define QCA8K_REG_GLOBAL_FW_CTRL1 0x624 - #define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24) - #define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16) -@@ -201,6 +202,7 @@ - #define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3) - #define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4) - #define QCA8K_PORT_LOOKUP_LEARN BIT(20) -+#define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25) - - #define QCA8K_REG_GLOBAL_FC_THRESH 0x800 - #define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16) -@@ -305,6 +307,8 @@ struct qca8k_ports_config { - struct qca8k_priv { - u8 switch_id; - u8 switch_revision; -+ u8 mirror_rx; -+ u8 mirror_tx; - bool legacy_phy_port_mapping; - struct qca8k_ports_config ports_config; - struct regmap *regmap; diff --git a/target/linux/generic/backport-5.15/764-13-v5.17-net-next-net-dsa-qca8k-add-LAG-support.patch b/target/linux/generic/backport-5.15/764-13-v5.17-net-next-net-dsa-qca8k-add-LAG-support.patch deleted file mode 100644 index b53f1288d5a0ec..00000000000000 --- a/target/linux/generic/backport-5.15/764-13-v5.17-net-next-net-dsa-qca8k-add-LAG-support.patch +++ /dev/null @@ -1,288 +0,0 @@ -From def975307c01191b6f0170048c3724b0ed3348af Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 23 Nov 2021 03:59:11 +0100 -Subject: net: dsa: qca8k: add LAG support - -Add LAG support to this switch. In Documentation this is described as -trunk mode. A max of 4 LAGs are supported and each can support up to 4 -port. The current tx mode supported is Hash mode with both L2 and L2+3 -mode. -When no port are present in the trunk, the trunk is disabled in the -switch. -When a port is disconnected, the traffic is redirected to the other -available port. -The hash mode is global and each LAG require to have the same hash mode -set. To change the hash mode when multiple LAG are configured, it's -required to remove each LAG and set the desired hash mode to the last. -An error is printed when it's asked to set a not supported hadh mode. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++ - drivers/net/dsa/qca8k.h | 33 +++++++++ - 2 files changed, 210 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1340,6 +1340,9 @@ qca8k_setup(struct dsa_switch *ds) - ds->ageing_time_min = 7000; - ds->ageing_time_max = 458745000; - -+ /* Set max number of LAGs supported */ -+ ds->num_lag_ids = QCA8K_NUM_LAGS; -+ - return 0; - } - -@@ -2226,6 +2229,178 @@ qca8k_get_tag_protocol(struct dsa_switch - return DSA_TAG_PROTO_QCA; - } - -+static bool -+qca8k_lag_can_offload(struct dsa_switch *ds, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ struct dsa_port *dp; -+ int id, members = 0; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ if (id < 0 || id >= ds->num_lag_ids) -+ return false; -+ -+ dsa_lag_foreach_port(dp, ds->dst, lag) -+ /* Includes the port joining the LAG */ -+ members++; -+ -+ if (members > QCA8K_NUM_PORTS_FOR_LAG) -+ return false; -+ -+ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) -+ return false; -+ -+ if (info->hash_type != NETDEV_LAG_HASH_L2 || -+ info->hash_type != NETDEV_LAG_HASH_L23) -+ return false; -+ -+ return true; -+} -+ -+static int -+qca8k_lag_setup_hash(struct dsa_switch *ds, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ bool unique_lag = true; -+ int i, id; -+ u32 hash; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ -+ switch (info->hash_type) { -+ case NETDEV_LAG_HASH_L23: -+ hash |= QCA8K_TRUNK_HASH_SIP_EN; -+ hash |= QCA8K_TRUNK_HASH_DIP_EN; -+ fallthrough; -+ case NETDEV_LAG_HASH_L2: -+ hash |= QCA8K_TRUNK_HASH_SA_EN; -+ hash |= QCA8K_TRUNK_HASH_DA_EN; -+ break; -+ default: /* We should NEVER reach this */ -+ return -EOPNOTSUPP; -+ } -+ -+ /* Check if we are the unique configured LAG */ -+ dsa_lags_foreach_id(i, ds->dst) -+ if (i != id && dsa_lag_dev(ds->dst, i)) { -+ unique_lag = false; -+ break; -+ } -+ -+ /* Hash Mode is global. Make sure the same Hash Mode -+ * is set to all the 4 possible lag. -+ * If we are the unique LAG we can set whatever hash -+ * mode we want. -+ * To change hash mode it's needed to remove all LAG -+ * and change the mode with the latest. -+ */ -+ if (unique_lag) { -+ priv->lag_hash_mode = hash; -+ } else if (priv->lag_hash_mode != hash) { -+ netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, -+ QCA8K_TRUNK_HASH_MASK, hash); -+} -+ -+static int -+qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, -+ struct net_device *lag, bool delete) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret, id, i; -+ u32 val; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ -+ /* Read current port member */ -+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); -+ if (ret) -+ return ret; -+ -+ /* Shift val to the correct trunk */ -+ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); -+ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; -+ if (delete) -+ val &= ~BIT(port); -+ else -+ val |= BIT(port); -+ -+ /* Update port member. With empty portmap disable trunk */ -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, -+ QCA8K_REG_GOL_TRUNK_MEMBER(id) | -+ QCA8K_REG_GOL_TRUNK_EN(id), -+ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | -+ val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); -+ -+ /* Search empty member if adding or port on deleting */ -+ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { -+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); -+ if (ret) -+ return ret; -+ -+ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); -+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; -+ -+ if (delete) { -+ /* If port flagged to be disabled assume this member is -+ * empty -+ */ -+ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -+ continue; -+ -+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; -+ if (val != port) -+ continue; -+ } else { -+ /* If port flagged to be enabled assume this member is -+ * already set -+ */ -+ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -+ continue; -+ } -+ -+ /* We have found the member to add/remove */ -+ break; -+ } -+ -+ /* Set port in the correct port mask or disable port if in delete mode */ -+ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), -+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | -+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), -+ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | -+ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); -+} -+ -+static int -+qca8k_port_lag_join(struct dsa_switch *ds, int port, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ int ret; -+ -+ if (!qca8k_lag_can_offload(ds, lag, info)) -+ return -EOPNOTSUPP; -+ -+ ret = qca8k_lag_setup_hash(ds, lag, info); -+ if (ret) -+ return ret; -+ -+ return qca8k_lag_refresh_portmap(ds, port, lag, false); -+} -+ -+static int -+qca8k_port_lag_leave(struct dsa_switch *ds, int port, -+ struct net_device *lag) -+{ -+ return qca8k_lag_refresh_portmap(ds, port, lag, true); -+} -+ - static const struct dsa_switch_ops qca8k_switch_ops = { - .get_tag_protocol = qca8k_get_tag_protocol, - .setup = qca8k_setup, -@@ -2259,6 +2434,8 @@ static const struct dsa_switch_ops qca8k - .phylink_mac_link_down = qca8k_phylink_mac_link_down, - .phylink_mac_link_up = qca8k_phylink_mac_link_up, - .get_phy_flags = qca8k_get_phy_flags, -+ .port_lag_join = qca8k_port_lag_join, -+ .port_lag_leave = qca8k_port_lag_leave, - }; - - static int qca8k_read_switch_id(struct qca8k_priv *priv) ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -15,6 +15,8 @@ - #define QCA8K_NUM_PORTS 7 - #define QCA8K_NUM_CPU_PORTS 2 - #define QCA8K_MAX_MTU 9000 -+#define QCA8K_NUM_LAGS 4 -+#define QCA8K_NUM_PORTS_FOR_LAG 4 - - #define PHY_ID_QCA8327 0x004dd034 - #define QCA8K_ID_QCA8327 0x12 -@@ -122,6 +124,14 @@ - #define QCA8K_REG_EEE_CTRL 0x100 - #define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2) - -+/* TRUNK_HASH_EN registers */ -+#define QCA8K_TRUNK_HASH_EN_CTRL 0x270 -+#define QCA8K_TRUNK_HASH_SIP_EN BIT(3) -+#define QCA8K_TRUNK_HASH_DIP_EN BIT(2) -+#define QCA8K_TRUNK_HASH_SA_EN BIT(1) -+#define QCA8K_TRUNK_HASH_DA_EN BIT(0) -+#define QCA8K_TRUNK_HASH_MASK GENMASK(3, 0) -+ - /* ACL registers */ - #define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8)) - #define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16) -@@ -204,6 +214,28 @@ - #define QCA8K_PORT_LOOKUP_LEARN BIT(20) - #define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25) - -+#define QCA8K_REG_GOL_TRUNK_CTRL0 0x700 -+/* 4 max trunk first -+ * first 6 bit for member bitmap -+ * 7th bit is to enable trunk port -+ */ -+#define QCA8K_REG_GOL_TRUNK_SHIFT(_i) ((_i) * 8) -+#define QCA8K_REG_GOL_TRUNK_EN_MASK BIT(7) -+#define QCA8K_REG_GOL_TRUNK_EN(_i) (QCA8K_REG_GOL_TRUNK_EN_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) -+#define QCA8K_REG_GOL_TRUNK_MEMBER_MASK GENMASK(6, 0) -+#define QCA8K_REG_GOL_TRUNK_MEMBER(_i) (QCA8K_REG_GOL_TRUNK_MEMBER_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) -+/* 0x704 for TRUNK 0-1 --- 0x708 for TRUNK 2-3 */ -+#define QCA8K_REG_GOL_TRUNK_CTRL(_i) (0x704 + (((_i) / 2) * 4)) -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK GENMASK(3, 0) -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK BIT(3) -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK GENMASK(2, 0) -+#define QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i) (((_i) / 2) * 16) -+#define QCA8K_REG_GOL_MEM_ID_SHIFT(_i) ((_i) * 4) -+/* Complex shift: FIRST shift for port THEN shift for trunk */ -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j) (QCA8K_REG_GOL_MEM_ID_SHIFT(_j) + QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i)) -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) -+ - #define QCA8K_REG_GLOBAL_FC_THRESH 0x800 - #define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16) - #define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x) -@@ -309,6 +341,7 @@ struct qca8k_priv { - u8 switch_revision; - u8 mirror_rx; - u8 mirror_tx; -+ u8 lag_hash_mode; - bool legacy_phy_port_mapping; - struct qca8k_ports_config ports_config; - struct regmap *regmap; diff --git a/target/linux/generic/backport-5.15/764-14-v5.17-net-next-net-dsa-qca8k-fix-warning-in-LAG-feature.patch b/target/linux/generic/backport-5.15/764-14-v5.17-net-next-net-dsa-qca8k-fix-warning-in-LAG-feature.patch deleted file mode 100644 index 7d811be11ce9c4..00000000000000 --- a/target/linux/generic/backport-5.15/764-14-v5.17-net-next-net-dsa-qca8k-fix-warning-in-LAG-feature.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0898ca67b86e14207d4feb3f3fea8b87cec5aab1 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Tue, 23 Nov 2021 16:44:46 +0100 -Subject: net: dsa: qca8k: fix warning in LAG feature - -Fix warning reported by bot. -Make sure hash is init to 0 and fix wrong logic for hash_type in -qca8k_lag_can_offload. - -Reported-by: kernel test robot -Fixes: def975307c01 ("net: dsa: qca8k: add LAG support") -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Link: https://lore.kernel.org/r/20211123154446.31019-1-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca8k.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -2251,7 +2251,7 @@ qca8k_lag_can_offload(struct dsa_switch - if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) - return false; - -- if (info->hash_type != NETDEV_LAG_HASH_L2 || -+ if (info->hash_type != NETDEV_LAG_HASH_L2 && - info->hash_type != NETDEV_LAG_HASH_L23) - return false; - -@@ -2265,8 +2265,8 @@ qca8k_lag_setup_hash(struct dsa_switch * - { - struct qca8k_priv *priv = ds->priv; - bool unique_lag = true; -+ u32 hash = 0; - int i, id; -- u32 hash; - - id = dsa_lag_id(ds->dst, lag); - diff --git a/target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch b/target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch deleted file mode 100644 index 77cf63b809be20..00000000000000 --- a/target/linux/generic/backport-5.15/765-v5.17-01-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 904e112ad431492b34f235f59738e8312802bbf9 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 6 Jan 2022 01:11:12 +0200 -Subject: [PATCH 1/6] net: dsa: reorder PHY initialization with MTU setup in - slave.c - -In dsa_slave_create() there are 2 sections that take rtnl_lock(): -MTU change and netdev registration. They are separated by PHY -initialization. - -There isn't any strict ordering requirement except for the fact that -netdev registration should be last. Therefore, we can perform the MTU -change a bit later, after the PHY setup. A future change will then be -able to merge the two rtnl_lock sections into one. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - net/dsa/slave.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - ---- a/net/dsa/slave.c -+++ b/net/dsa/slave.c -@@ -1977,13 +1977,6 @@ int dsa_slave_create(struct dsa_port *po - port->slave = slave_dev; - dsa_slave_setup_tagger(slave_dev); - -- rtnl_lock(); -- ret = dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN); -- rtnl_unlock(); -- if (ret && ret != -EOPNOTSUPP) -- dev_warn(ds->dev, "nonfatal error %d setting MTU to %d on port %d\n", -- ret, ETH_DATA_LEN, port->index); -- - netif_carrier_off(slave_dev); - - ret = dsa_slave_phy_setup(slave_dev); -@@ -1995,6 +1988,13 @@ int dsa_slave_create(struct dsa_port *po - } - - rtnl_lock(); -+ ret = dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN); -+ rtnl_unlock(); -+ if (ret && ret != -EOPNOTSUPP) -+ dev_warn(ds->dev, "nonfatal error %d setting MTU to %d on port %d\n", -+ ret, ETH_DATA_LEN, port->index); -+ -+ rtnl_lock(); - - ret = register_netdevice(slave_dev); - if (ret) { diff --git a/target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch b/target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch deleted file mode 100644 index 50aa5d8f0dd534..00000000000000 --- a/target/linux/generic/backport-5.15/765-v5.17-02-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch +++ /dev/null @@ -1,34 +0,0 @@ -From e31dbd3b6aba585231cd84a87adeb22e7c6a8c19 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 6 Jan 2022 01:11:13 +0200 -Subject: [PATCH 2/6] net: dsa: merge rtnl_lock sections in dsa_slave_create - -Currently dsa_slave_create() has two sequences of rtnl_lock/rtnl_unlock -in a row. Remove the rtnl_unlock() and rtnl_lock() in between, such that -the operation can execute slighly faster. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - net/dsa/slave.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/net/dsa/slave.c -+++ b/net/dsa/slave.c -@@ -1988,14 +1988,12 @@ int dsa_slave_create(struct dsa_port *po - } - - rtnl_lock(); -+ - ret = dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN); -- rtnl_unlock(); - if (ret && ret != -EOPNOTSUPP) - dev_warn(ds->dev, "nonfatal error %d setting MTU to %d on port %d\n", - ret, ETH_DATA_LEN, port->index); - -- rtnl_lock(); -- - ret = register_netdevice(slave_dev); - if (ret) { - netdev_err(master, "error %d registering interface %s\n", diff --git a/target/linux/generic/backport-5.15/765-v5.17-03-net-next-net-dsa-stop-updating-master-MTU-from-master.c.patch b/target/linux/generic/backport-5.15/765-v5.17-03-net-next-net-dsa-stop-updating-master-MTU-from-master.c.patch deleted file mode 100644 index 6c7aad692885e7..00000000000000 --- a/target/linux/generic/backport-5.15/765-v5.17-03-net-next-net-dsa-stop-updating-master-MTU-from-master.c.patch +++ /dev/null @@ -1,91 +0,0 @@ -From a1ff94c2973c43bc1e2677ac63ebb15b1d1ff846 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 6 Jan 2022 01:11:14 +0200 -Subject: [PATCH 3/6] net: dsa: stop updating master MTU from master.c - -At present there are two paths for changing the MTU of the DSA master. - -The first is: - -dsa_tree_setup --> dsa_tree_setup_ports - -> dsa_port_setup - -> dsa_slave_create - -> dsa_slave_change_mtu - -> dev_set_mtu(master) - -The second is: - -dsa_tree_setup --> dsa_tree_setup_master - -> dsa_master_setup - -> dev_set_mtu(dev) - -So the dev_set_mtu() call from dsa_master_setup() has been effectively -superseded by the dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN) that is -done from dsa_slave_create() for each user port. The later function also -updates the master MTU according to the largest user port MTU from the -tree. Therefore, updating the master MTU through a separate code path -isn't needed. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - net/dsa/master.c | 25 +------------------------ - 1 file changed, 1 insertion(+), 24 deletions(-) - ---- a/net/dsa/master.c -+++ b/net/dsa/master.c -@@ -329,28 +329,13 @@ static const struct attribute_group dsa_ - .attrs = dsa_slave_attrs, - }; - --static void dsa_master_reset_mtu(struct net_device *dev) --{ -- int err; -- -- rtnl_lock(); -- err = dev_set_mtu(dev, ETH_DATA_LEN); -- if (err) -- netdev_dbg(dev, -- "Unable to reset MTU to exclude DSA overheads\n"); -- rtnl_unlock(); --} -- - static struct lock_class_key dsa_master_addr_list_lock_key; - - int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp) - { -- const struct dsa_device_ops *tag_ops = cpu_dp->tag_ops; - struct dsa_switch *ds = cpu_dp->ds; - struct device_link *consumer_link; -- int mtu, ret; -- -- mtu = ETH_DATA_LEN + dsa_tag_protocol_overhead(tag_ops); -+ int ret; - - /* The DSA master must use SET_NETDEV_DEV for this to work. */ - consumer_link = device_link_add(ds->dev, dev->dev.parent, -@@ -360,13 +345,6 @@ int dsa_master_setup(struct net_device * - "Failed to create a device link to DSA switch %s\n", - dev_name(ds->dev)); - -- rtnl_lock(); -- ret = dev_set_mtu(dev, mtu); -- rtnl_unlock(); -- if (ret) -- netdev_warn(dev, "error %d setting MTU to %d to include DSA overhead\n", -- ret, mtu); -- - /* If we use a tagging format that doesn't have an ethertype - * field, make sure that all packets from this point on get - * sent to the tag format's receive function. -@@ -404,7 +382,6 @@ void dsa_master_teardown(struct net_devi - sysfs_remove_group(&dev->dev.kobj, &dsa_group); - dsa_netdev_ops_set(dev, NULL); - dsa_master_ethtool_teardown(dev); -- dsa_master_reset_mtu(dev); - dsa_master_set_promiscuity(dev, -1); - - dev->dsa_ptr = NULL; diff --git a/target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch b/target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch deleted file mode 100644 index dbc28efc949bbb..00000000000000 --- a/target/linux/generic/backport-5.15/765-v5.17-04-net-next-net-dsa-hold-rtnl_mutex-when-calling-dsa_master_-set.patch +++ /dev/null @@ -1,78 +0,0 @@ -From c146f9bc195a9dc3ad7fd000a14540e7c9df952d Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 6 Jan 2022 01:11:15 +0200 -Subject: [PATCH 4/6] net: dsa: hold rtnl_mutex when calling - dsa_master_{setup,teardown} - -DSA needs to simulate master tracking events when a binding is first -with a DSA master established and torn down, in order to give drivers -the simplifying guarantee that ->master_state_change calls are made -only when the master's readiness state to pass traffic changes. -master_state_change() provide a operational bool that DSA driver can use -to understand if DSA master is operational or not. -To avoid races, we need to block the reception of -NETDEV_UP/NETDEV_CHANGE/NETDEV_GOING_DOWN events in the netdev notifier -chain while we are changing the master's dev->dsa_ptr (this changes what -netdev_uses_dsa(dev) reports). - -The dsa_master_setup() and dsa_master_teardown() functions optionally -require the rtnl_mutex to be held, if the tagger needs the master to be -promiscuous, these functions call dev_set_promiscuity(). Move the -rtnl_lock() from that function and make it top-level. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - net/dsa/dsa2.c | 8 ++++++++ - net/dsa/master.c | 4 ++-- - 2 files changed, 10 insertions(+), 2 deletions(-) - ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -1056,6 +1056,8 @@ static int dsa_tree_setup_master(struct - struct dsa_port *dp; - int err; - -+ rtnl_lock(); -+ - list_for_each_entry(dp, &dst->ports, list) { - if (dsa_port_is_cpu(dp)) { - err = dsa_master_setup(dp->master, dp); -@@ -1064,6 +1066,8 @@ static int dsa_tree_setup_master(struct - } - } - -+ rtnl_unlock(); -+ - return 0; - } - -@@ -1071,9 +1075,13 @@ static void dsa_tree_teardown_master(str - { - struct dsa_port *dp; - -+ rtnl_lock(); -+ - list_for_each_entry(dp, &dst->ports, list) - if (dsa_port_is_cpu(dp)) - dsa_master_teardown(dp->master); -+ -+ rtnl_unlock(); - } - - static int dsa_tree_setup_lags(struct dsa_switch_tree *dst) ---- a/net/dsa/master.c -+++ b/net/dsa/master.c -@@ -266,9 +266,9 @@ static void dsa_master_set_promiscuity(s - if (!ops->promisc_on_master) - return; - -- rtnl_lock(); -+ ASSERT_RTNL(); -+ - dev_set_promiscuity(dev, inc); -- rtnl_unlock(); - } - - static ssize_t tagging_show(struct device *d, struct device_attribute *attr, diff --git a/target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch b/target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch deleted file mode 100644 index fbb9c94ec14116..00000000000000 --- a/target/linux/generic/backport-5.15/765-v5.17-05-net-next-net-dsa-first-set-up-shared-ports-then-non-shared-po.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 1e3f407f3cacc5dcfe27166c412ed9bc263d82bf Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 6 Jan 2022 01:11:16 +0200 -Subject: [PATCH 5/6] net: dsa: first set up shared ports, then non-shared - ports - -After commit a57d8c217aad ("net: dsa: flush switchdev workqueue before -tearing down CPU/DSA ports"), the port setup and teardown procedure -became asymmetric. - -The fact of the matter is that user ports need the shared ports to be up -before they can be used for CPU-initiated termination. And since we -register net devices for the user ports, those won't be functional until -we also call the setup for the shared (CPU, DSA) ports. But we may do -that later, depending on the port numbering scheme of the hardware we -are dealing with. - -It just makes sense that all shared ports are brought up before any user -port is. I can't pinpoint any issue due to the current behavior, but -let's change it nonetheless, for consistency's sake. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - net/dsa/dsa2.c | 50 +++++++++++++++++++++++++++++++++++++------------- - 1 file changed, 37 insertions(+), 13 deletions(-) - ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -1021,23 +1021,28 @@ static void dsa_tree_teardown_switches(s - dsa_switch_teardown(dp->ds); - } - --static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) -+/* Bring shared ports up first, then non-shared ports */ -+static int dsa_tree_setup_ports(struct dsa_switch_tree *dst) - { - struct dsa_port *dp; -- int err; -+ int err = 0; - - list_for_each_entry(dp, &dst->ports, list) { -- err = dsa_switch_setup(dp->ds); -- if (err) -- goto teardown; -+ if (dsa_port_is_dsa(dp) || dsa_port_is_cpu(dp)) { -+ err = dsa_port_setup(dp); -+ if (err) -+ goto teardown; -+ } - } - - list_for_each_entry(dp, &dst->ports, list) { -- err = dsa_port_setup(dp); -- if (err) { -- err = dsa_port_reinit_as_unused(dp); -- if (err) -- goto teardown; -+ if (dsa_port_is_user(dp) || dsa_port_is_unused(dp)) { -+ err = dsa_port_setup(dp); -+ if (err) { -+ err = dsa_port_reinit_as_unused(dp); -+ if (err) -+ goto teardown; -+ } - } - } - -@@ -1046,7 +1051,21 @@ static int dsa_tree_setup_switches(struc - teardown: - dsa_tree_teardown_ports(dst); - -- dsa_tree_teardown_switches(dst); -+ return err; -+} -+ -+static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) -+{ -+ struct dsa_port *dp; -+ int err = 0; -+ -+ list_for_each_entry(dp, &dst->ports, list) { -+ err = dsa_switch_setup(dp->ds); -+ if (err) { -+ dsa_tree_teardown_switches(dst); -+ break; -+ } -+ } - - return err; - } -@@ -1133,10 +1152,14 @@ static int dsa_tree_setup(struct dsa_swi - if (err) - goto teardown_cpu_ports; - -- err = dsa_tree_setup_master(dst); -+ err = dsa_tree_setup_ports(dst); - if (err) - goto teardown_switches; - -+ err = dsa_tree_setup_master(dst); -+ if (err) -+ goto teardown_ports; -+ - err = dsa_tree_setup_lags(dst); - if (err) - goto teardown_master; -@@ -1149,8 +1172,9 @@ static int dsa_tree_setup(struct dsa_swi - - teardown_master: - dsa_tree_teardown_master(dst); --teardown_switches: -+teardown_ports: - dsa_tree_teardown_ports(dst); -+teardown_switches: - dsa_tree_teardown_switches(dst); - teardown_cpu_ports: - dsa_tree_teardown_cpu_ports(dst); diff --git a/target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch b/target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch deleted file mode 100644 index a46e06ef8b6c2d..00000000000000 --- a/target/linux/generic/backport-5.15/765-v5.17-06-net-next-net-dsa-setup-master-before-ports.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 11fd667dac315ea3f2469961f6d2869271a46cae Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 6 Jan 2022 01:11:17 +0200 -Subject: [PATCH 6/6] net: dsa: setup master before ports - -It is said that as soon as a network interface is registered, all its -resources should have already been prepared, so that it is available for -sending and receiving traffic. One of the resources needed by a DSA -slave interface is the master. - -dsa_tree_setup --> dsa_tree_setup_ports - -> dsa_port_setup - -> dsa_slave_create - -> register_netdevice --> dsa_tree_setup_master - -> dsa_master_setup - -> sets up master->dsa_ptr, which enables reception - -Therefore, there is a short period of time after register_netdevice() -during which the master isn't prepared to pass traffic to the DSA layer -(master->dsa_ptr is checked by eth_type_trans). Same thing during -unregistration, there is a time frame in which packets might be missed. - -Note that this change opens us to another race: dsa_master_find_slave() -will get invoked potentially earlier than the slave creation, and later -than the slave deletion. Since dp->slave starts off as a NULL pointer, -the earlier calls aren't a problem, but the later calls are. To avoid -use-after-free, we should zeroize dp->slave before calling -dsa_slave_destroy(). - -In practice I cannot really test real life improvements brought by this -change, since in my systems, netdevice creation races with PHY autoneg -which takes a few seconds to complete, and that masks quite a few races. -Effects might be noticeable in a setup with fixed links all the way to -an external system. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - net/dsa/dsa2.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -567,6 +567,7 @@ static void dsa_port_teardown(struct dsa - struct devlink_port *dlp = &dp->devlink_port; - struct dsa_switch *ds = dp->ds; - struct dsa_mac_addr *a, *tmp; -+ struct net_device *slave; - - if (!dp->setup) - return; -@@ -588,9 +589,11 @@ static void dsa_port_teardown(struct dsa - dsa_port_link_unregister_of(dp); - break; - case DSA_PORT_TYPE_USER: -- if (dp->slave) { -- dsa_slave_destroy(dp->slave); -+ slave = dp->slave; -+ -+ if (slave) { - dp->slave = NULL; -+ dsa_slave_destroy(slave); - } - break; - } -@@ -1152,17 +1155,17 @@ static int dsa_tree_setup(struct dsa_swi - if (err) - goto teardown_cpu_ports; - -- err = dsa_tree_setup_ports(dst); -+ err = dsa_tree_setup_master(dst); - if (err) - goto teardown_switches; - -- err = dsa_tree_setup_master(dst); -+ err = dsa_tree_setup_ports(dst); - if (err) -- goto teardown_ports; -+ goto teardown_master; - - err = dsa_tree_setup_lags(dst); - if (err) -- goto teardown_master; -+ goto teardown_ports; - - dst->setup = true; - -@@ -1170,10 +1173,10 @@ static int dsa_tree_setup(struct dsa_swi - - return 0; - --teardown_master: -- dsa_tree_teardown_master(dst); - teardown_ports: - dsa_tree_teardown_ports(dst); -+teardown_master: -+ dsa_tree_teardown_master(dst); - teardown_switches: - dsa_tree_teardown_switches(dst); - teardown_cpu_ports: -@@ -1191,10 +1194,10 @@ static void dsa_tree_teardown(struct dsa - - dsa_tree_teardown_lags(dst); - -- dsa_tree_teardown_master(dst); -- - dsa_tree_teardown_ports(dst); - -+ dsa_tree_teardown_master(dst); -+ - dsa_tree_teardown_switches(dst); - - dsa_tree_teardown_cpu_ports(dst); diff --git a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch b/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch deleted file mode 100644 index 15122950ced055..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 295ab96f478d0fa56393e85406f19a867e26ce22 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Wed, 2 Feb 2022 01:03:20 +0100 -Subject: [PATCH 01/16] net: dsa: provide switch operations for tracking the - master state - -Certain drivers may need to send management traffic to the switch for -things like register access, FDB dump, etc, to accelerate what their -slow bus (SPI, I2C, MDIO) can already do. - -Ethernet is faster (especially in bulk transactions) but is also more -unreliable, since the user may decide to bring the DSA master down (or -not bring it up), therefore severing the link between the host and the -attached switch. - -Drivers needing Ethernet-based register access already should have -fallback logic to the slow bus if the Ethernet method fails, but that -fallback may be based on a timeout, and the I/O to the switch may slow -down to a halt if the master is down, because every Ethernet packet will -have to time out. The driver also doesn't have the option to turn off -Ethernet-based I/O momentarily, because it wouldn't know when to turn it -back on. - -Which is where this change comes in. By tracking NETDEV_CHANGE, -NETDEV_UP and NETDEV_GOING_DOWN events on the DSA master, we should know -the exact interval of time during which this interface is reliably -available for traffic. Provide this information to switches so they can -use it as they wish. - -An helper is added dsa_port_master_is_operational() to check if a master -port is operational. - -Signed-off-by: Vladimir Oltean -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - include/net/dsa.h | 17 +++++++++++++++++ - net/dsa/dsa2.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ - net/dsa/dsa_priv.h | 13 +++++++++++++ - net/dsa/slave.c | 32 ++++++++++++++++++++++++++++++++ - net/dsa/switch.c | 15 +++++++++++++++ - 5 files changed, 123 insertions(+) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -291,6 +291,10 @@ struct dsa_port { - struct list_head mdbs; - - bool setup; -+ /* Master state bits, valid only on CPU ports */ -+ u8 master_admin_up:1; -+ u8 master_oper_up:1; -+ - }; - - /* TODO: ideally DSA ports would have a single dp->link_dp member, -@@ -456,6 +460,12 @@ static inline bool dsa_port_is_unused(st - return dp->type == DSA_PORT_TYPE_UNUSED; - } - -+static inline bool dsa_port_master_is_operational(struct dsa_port *dp) -+{ -+ return dsa_port_is_cpu(dp) && dp->master_admin_up && -+ dp->master_oper_up; -+} -+ - static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p) - { - return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED; -@@ -957,6 +967,13 @@ struct dsa_switch_ops { - int (*tag_8021q_vlan_add)(struct dsa_switch *ds, int port, u16 vid, - u16 flags); - int (*tag_8021q_vlan_del)(struct dsa_switch *ds, int port, u16 vid); -+ -+ /* -+ * DSA master tracking operations -+ */ -+ void (*master_state_change)(struct dsa_switch *ds, -+ const struct net_device *master, -+ bool operational); - }; - - #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \ ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -1297,6 +1297,52 @@ out_unlock: - return err; - } - -+static void dsa_tree_master_state_change(struct dsa_switch_tree *dst, -+ struct net_device *master) -+{ -+ struct dsa_notifier_master_state_info info; -+ struct dsa_port *cpu_dp = master->dsa_ptr; -+ -+ info.master = master; -+ info.operational = dsa_port_master_is_operational(cpu_dp); -+ -+ dsa_tree_notify(dst, DSA_NOTIFIER_MASTER_STATE_CHANGE, &info); -+} -+ -+void dsa_tree_master_admin_state_change(struct dsa_switch_tree *dst, -+ struct net_device *master, -+ bool up) -+{ -+ struct dsa_port *cpu_dp = master->dsa_ptr; -+ bool notify = false; -+ -+ if ((dsa_port_master_is_operational(cpu_dp)) != -+ (up && cpu_dp->master_oper_up)) -+ notify = true; -+ -+ cpu_dp->master_admin_up = up; -+ -+ if (notify) -+ dsa_tree_master_state_change(dst, master); -+} -+ -+void dsa_tree_master_oper_state_change(struct dsa_switch_tree *dst, -+ struct net_device *master, -+ bool up) -+{ -+ struct dsa_port *cpu_dp = master->dsa_ptr; -+ bool notify = false; -+ -+ if ((dsa_port_master_is_operational(cpu_dp)) != -+ (cpu_dp->master_admin_up && up)) -+ notify = true; -+ -+ cpu_dp->master_oper_up = up; -+ -+ if (notify) -+ dsa_tree_master_state_change(dst, master); -+} -+ - static struct dsa_port *dsa_port_touch(struct dsa_switch *ds, int index) - { - struct dsa_switch_tree *dst = ds->dst; ---- a/net/dsa/dsa_priv.h -+++ b/net/dsa/dsa_priv.h -@@ -45,6 +45,7 @@ enum { - DSA_NOTIFIER_MRP_DEL_RING_ROLE, - DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, - DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, -+ DSA_NOTIFIER_MASTER_STATE_CHANGE, - }; - - /* DSA_NOTIFIER_AGEING_TIME */ -@@ -127,6 +128,12 @@ struct dsa_notifier_tag_8021q_vlan_info - u16 vid; - }; - -+/* DSA_NOTIFIER_MASTER_STATE_CHANGE */ -+struct dsa_notifier_master_state_info { -+ const struct net_device *master; -+ bool operational; -+}; -+ - struct dsa_switchdev_event_work { - struct dsa_switch *ds; - int port; -@@ -549,6 +556,12 @@ int dsa_tree_change_tag_proto(struct dsa - struct net_device *master, - const struct dsa_device_ops *tag_ops, - const struct dsa_device_ops *old_tag_ops); -+void dsa_tree_master_admin_state_change(struct dsa_switch_tree *dst, -+ struct net_device *master, -+ bool up); -+void dsa_tree_master_oper_state_change(struct dsa_switch_tree *dst, -+ struct net_device *master, -+ bool up); - int dsa_bridge_num_get(const struct net_device *bridge_dev, int max); - void dsa_bridge_num_put(const struct net_device *bridge_dev, int bridge_num); - ---- a/net/dsa/slave.c -+++ b/net/dsa/slave.c -@@ -2311,6 +2311,36 @@ static int dsa_slave_netdevice_event(str - err = dsa_port_lag_change(dp, info->lower_state_info); - return notifier_from_errno(err); - } -+ case NETDEV_CHANGE: -+ case NETDEV_UP: { -+ /* Track state of master port. -+ * DSA driver may require the master port (and indirectly -+ * the tagger) to be available for some special operation. -+ */ -+ if (netdev_uses_dsa(dev)) { -+ struct dsa_port *cpu_dp = dev->dsa_ptr; -+ struct dsa_switch_tree *dst = cpu_dp->ds->dst; -+ -+ /* Track when the master port is UP */ -+ dsa_tree_master_oper_state_change(dst, dev, -+ netif_oper_up(dev)); -+ -+ /* Track when the master port is ready and can accept -+ * packet. -+ * NETDEV_UP event is not enough to flag a port as ready. -+ * We also have to wait for linkwatch_do_dev to dev_activate -+ * and emit a NETDEV_CHANGE event. -+ * We check if a master port is ready by checking if the dev -+ * have a qdisc assigned and is not noop. -+ */ -+ dsa_tree_master_admin_state_change(dst, dev, -+ !qdisc_tx_is_noop(dev)); -+ -+ return NOTIFY_OK; -+ } -+ -+ return NOTIFY_DONE; -+ } - case NETDEV_GOING_DOWN: { - struct dsa_port *dp, *cpu_dp; - struct dsa_switch_tree *dst; -@@ -2322,6 +2352,8 @@ static int dsa_slave_netdevice_event(str - cpu_dp = dev->dsa_ptr; - dst = cpu_dp->ds->dst; - -+ dsa_tree_master_admin_state_change(dst, dev, false); -+ - list_for_each_entry(dp, &dst->ports, list) { - if (!dsa_is_user_port(dp->ds, dp->index)) - continue; ---- a/net/dsa/switch.c -+++ b/net/dsa/switch.c -@@ -722,6 +722,18 @@ dsa_switch_mrp_del_ring_role(struct dsa_ - return 0; - } - -+static int -+dsa_switch_master_state_change(struct dsa_switch *ds, -+ struct dsa_notifier_master_state_info *info) -+{ -+ if (!ds->ops->master_state_change) -+ return 0; -+ -+ ds->ops->master_state_change(ds, info->master, info->operational); -+ -+ return 0; -+} -+ - static int dsa_switch_event(struct notifier_block *nb, - unsigned long event, void *info) - { -@@ -813,6 +825,9 @@ static int dsa_switch_event(struct notif - case DSA_NOTIFIER_TAG_8021Q_VLAN_DEL: - err = dsa_switch_tag_8021q_vlan_del(ds, info); - break; -+ case DSA_NOTIFIER_MASTER_STATE_CHANGE: -+ err = dsa_switch_master_state_change(ds, info); -+ break; - default: - err = -EOPNOTSUPP; - break; diff --git a/target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch b/target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch deleted file mode 100644 index c55c5271d4b3e9..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-02-net-dsa-replay-master-state-events-in-dsa_tree_-setu.patch +++ /dev/null @@ -1,89 +0,0 @@ -From e83d56537859849f2223b90749e554831b1f3c27 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Wed, 2 Feb 2022 01:03:21 +0100 -Subject: [PATCH 02/16] net: dsa: replay master state events in - dsa_tree_{setup,teardown}_master - -In order for switch driver to be able to make simple and reliable use of -the master tracking operations, they must also be notified of the -initial state of the DSA master, not just of the changes. This is -because they might enable certain features only during the time when -they know that the DSA master is up and running. - -Therefore, this change explicitly checks the state of the DSA master -under the same rtnl_mutex as we were holding during the -dsa_master_setup() and dsa_master_teardown() call. The idea being that -if the DSA master became operational in between the moment in which it -became a DSA master (dsa_master_setup set dev->dsa_ptr) and the moment -when we checked for the master being up, there is a chance that we -would emit a ->master_state_change() call with no actual state change. -We need to avoid that by serializing the concurrent netdevice event with -us. If the netdevice event started before, we force it to finish before -we begin, because we take rtnl_lock before making netdev_uses_dsa() -return true. So we also handle that early event and do nothing on it. -Similarly, if the dev_open() attempt is concurrent with us, it will -attempt to take the rtnl_mutex, but we're holding it. We'll see that -the master flag IFF_UP isn't set, then when we release the rtnl_mutex -we'll process the NETDEV_UP notifier. - -Signed-off-by: Vladimir Oltean -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - net/dsa/dsa2.c | 28 ++++++++++++++++++++++++---- - 1 file changed, 24 insertions(+), 4 deletions(-) - ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #include "dsa_priv.h" - -@@ -1082,9 +1083,18 @@ static int dsa_tree_setup_master(struct - - list_for_each_entry(dp, &dst->ports, list) { - if (dsa_port_is_cpu(dp)) { -- err = dsa_master_setup(dp->master, dp); -+ struct net_device *master = dp->master; -+ bool admin_up = (master->flags & IFF_UP) && -+ !qdisc_tx_is_noop(master); -+ -+ err = dsa_master_setup(master, dp); - if (err) - return err; -+ -+ /* Replay master state event */ -+ dsa_tree_master_admin_state_change(dst, master, admin_up); -+ dsa_tree_master_oper_state_change(dst, master, -+ netif_oper_up(master)); - } - } - -@@ -1099,9 +1109,19 @@ static void dsa_tree_teardown_master(str - - rtnl_lock(); - -- list_for_each_entry(dp, &dst->ports, list) -- if (dsa_port_is_cpu(dp)) -- dsa_master_teardown(dp->master); -+ list_for_each_entry(dp, &dst->ports, list) { -+ if (dsa_port_is_cpu(dp)) { -+ struct net_device *master = dp->master; -+ -+ /* Synthesizing an "admin down" state is sufficient for -+ * the switches to get a notification if the master is -+ * currently up and running. -+ */ -+ dsa_tree_master_admin_state_change(dst, master, false); -+ -+ dsa_master_teardown(master); -+ } -+ } - - rtnl_unlock(); - } diff --git a/target/linux/generic/backport-5.15/766-v5.18-03-net-dsa-tag_qca-convert-to-FIELD-macro.patch b/target/linux/generic/backport-5.15/766-v5.18-03-net-dsa-tag_qca-convert-to-FIELD-macro.patch deleted file mode 100644 index 82c94b385b5f53..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-03-net-dsa-tag_qca-convert-to-FIELD-macro.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 6b0458299297ca4ab6fb295800e29a4e501d50c1 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:22 +0100 -Subject: [PATCH 03/16] net: dsa: tag_qca: convert to FIELD macro - -Convert driver to FIELD macro to drop redundant define. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - net/dsa/tag_qca.c | 34 +++++++++++++++------------------- - 1 file changed, 15 insertions(+), 19 deletions(-) - ---- a/net/dsa/tag_qca.c -+++ b/net/dsa/tag_qca.c -@@ -4,29 +4,24 @@ - */ - - #include -+#include - - #include "dsa_priv.h" - - #define QCA_HDR_LEN 2 - #define QCA_HDR_VERSION 0x2 - --#define QCA_HDR_RECV_VERSION_MASK GENMASK(15, 14) --#define QCA_HDR_RECV_VERSION_S 14 --#define QCA_HDR_RECV_PRIORITY_MASK GENMASK(13, 11) --#define QCA_HDR_RECV_PRIORITY_S 11 --#define QCA_HDR_RECV_TYPE_MASK GENMASK(10, 6) --#define QCA_HDR_RECV_TYPE_S 6 -+#define QCA_HDR_RECV_VERSION GENMASK(15, 14) -+#define QCA_HDR_RECV_PRIORITY GENMASK(13, 11) -+#define QCA_HDR_RECV_TYPE GENMASK(10, 6) - #define QCA_HDR_RECV_FRAME_IS_TAGGED BIT(3) --#define QCA_HDR_RECV_SOURCE_PORT_MASK GENMASK(2, 0) -+#define QCA_HDR_RECV_SOURCE_PORT GENMASK(2, 0) - --#define QCA_HDR_XMIT_VERSION_MASK GENMASK(15, 14) --#define QCA_HDR_XMIT_VERSION_S 14 --#define QCA_HDR_XMIT_PRIORITY_MASK GENMASK(13, 11) --#define QCA_HDR_XMIT_PRIORITY_S 11 --#define QCA_HDR_XMIT_CONTROL_MASK GENMASK(10, 8) --#define QCA_HDR_XMIT_CONTROL_S 8 -+#define QCA_HDR_XMIT_VERSION GENMASK(15, 14) -+#define QCA_HDR_XMIT_PRIORITY GENMASK(13, 11) -+#define QCA_HDR_XMIT_CONTROL GENMASK(10, 8) - #define QCA_HDR_XMIT_FROM_CPU BIT(7) --#define QCA_HDR_XMIT_DP_BIT_MASK GENMASK(6, 0) -+#define QCA_HDR_XMIT_DP_BIT GENMASK(6, 0) - - static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev) - { -@@ -40,8 +35,9 @@ static struct sk_buff *qca_tag_xmit(stru - phdr = dsa_etype_header_pos_tx(skb); - - /* Set the version field, and set destination port information */ -- hdr = QCA_HDR_VERSION << QCA_HDR_XMIT_VERSION_S | -- QCA_HDR_XMIT_FROM_CPU | BIT(dp->index); -+ hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); -+ hdr |= QCA_HDR_XMIT_FROM_CPU; -+ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(dp->index)); - - *phdr = htons(hdr); - -@@ -62,7 +58,7 @@ static struct sk_buff *qca_tag_rcv(struc - hdr = ntohs(*phdr); - - /* Make sure the version is correct */ -- ver = (hdr & QCA_HDR_RECV_VERSION_MASK) >> QCA_HDR_RECV_VERSION_S; -+ ver = FIELD_GET(QCA_HDR_RECV_VERSION, hdr); - if (unlikely(ver != QCA_HDR_VERSION)) - return NULL; - -@@ -71,7 +67,7 @@ static struct sk_buff *qca_tag_rcv(struc - dsa_strip_etype_header(skb, QCA_HDR_LEN); - - /* Get source port information */ -- port = (hdr & QCA_HDR_RECV_SOURCE_PORT_MASK); -+ port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, hdr); - - skb->dev = dsa_master_find_slave(dev, 0, port); - if (!skb->dev) diff --git a/target/linux/generic/backport-5.15/766-v5.18-04-net-dsa-tag_qca-move-define-to-include-linux-dsa.patch b/target/linux/generic/backport-5.15/766-v5.18-04-net-dsa-tag_qca-move-define-to-include-linux-dsa.patch deleted file mode 100644 index c1e74ceeeb5bf9..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-04-net-dsa-tag_qca-move-define-to-include-linux-dsa.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 3ec762fb13c7e7273800b94c80db1c2cc37590d1 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:23 +0100 -Subject: [PATCH 04/16] net: dsa: tag_qca: move define to include linux/dsa - -Move tag_qca define to include dir linux/dsa as the qca8k require access -to the tagger define to support in-band mdio read/write using ethernet -packet. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - include/linux/dsa/tag_qca.h | 21 +++++++++++++++++++++ - net/dsa/tag_qca.c | 16 +--------------- - 2 files changed, 22 insertions(+), 15 deletions(-) - create mode 100644 include/linux/dsa/tag_qca.h - ---- /dev/null -+++ b/include/linux/dsa/tag_qca.h -@@ -0,0 +1,21 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+#ifndef __TAG_QCA_H -+#define __TAG_QCA_H -+ -+#define QCA_HDR_LEN 2 -+#define QCA_HDR_VERSION 0x2 -+ -+#define QCA_HDR_RECV_VERSION GENMASK(15, 14) -+#define QCA_HDR_RECV_PRIORITY GENMASK(13, 11) -+#define QCA_HDR_RECV_TYPE GENMASK(10, 6) -+#define QCA_HDR_RECV_FRAME_IS_TAGGED BIT(3) -+#define QCA_HDR_RECV_SOURCE_PORT GENMASK(2, 0) -+ -+#define QCA_HDR_XMIT_VERSION GENMASK(15, 14) -+#define QCA_HDR_XMIT_PRIORITY GENMASK(13, 11) -+#define QCA_HDR_XMIT_CONTROL GENMASK(10, 8) -+#define QCA_HDR_XMIT_FROM_CPU BIT(7) -+#define QCA_HDR_XMIT_DP_BIT GENMASK(6, 0) -+ -+#endif /* __TAG_QCA_H */ ---- a/net/dsa/tag_qca.c -+++ b/net/dsa/tag_qca.c -@@ -5,24 +5,10 @@ - - #include - #include -+#include - - #include "dsa_priv.h" - --#define QCA_HDR_LEN 2 --#define QCA_HDR_VERSION 0x2 -- --#define QCA_HDR_RECV_VERSION GENMASK(15, 14) --#define QCA_HDR_RECV_PRIORITY GENMASK(13, 11) --#define QCA_HDR_RECV_TYPE GENMASK(10, 6) --#define QCA_HDR_RECV_FRAME_IS_TAGGED BIT(3) --#define QCA_HDR_RECV_SOURCE_PORT GENMASK(2, 0) -- --#define QCA_HDR_XMIT_VERSION GENMASK(15, 14) --#define QCA_HDR_XMIT_PRIORITY GENMASK(13, 11) --#define QCA_HDR_XMIT_CONTROL GENMASK(10, 8) --#define QCA_HDR_XMIT_FROM_CPU BIT(7) --#define QCA_HDR_XMIT_DP_BIT GENMASK(6, 0) -- - static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev) - { - struct dsa_port *dp = dsa_slave_to_port(dev); diff --git a/target/linux/generic/backport-5.15/766-v5.18-05-net-dsa-tag_qca-enable-promisc_on_master-flag.patch b/target/linux/generic/backport-5.15/766-v5.18-05-net-dsa-tag_qca-enable-promisc_on_master-flag.patch deleted file mode 100644 index 9394a0dabbe6a9..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-05-net-dsa-tag_qca-enable-promisc_on_master-flag.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 101c04c3463b87061e6a3d4f72c1bc57670685a6 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:24 +0100 -Subject: [PATCH 05/16] net: dsa: tag_qca: enable promisc_on_master flag - -Ethernet MDIO packets are non-standard and DSA master expects the first -6 octets to be the MAC DA. To address these kind of packet, enable -promisc_on_master flag for the tagger. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - net/dsa/tag_qca.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/net/dsa/tag_qca.c -+++ b/net/dsa/tag_qca.c -@@ -68,6 +68,7 @@ static const struct dsa_device_ops qca_n - .xmit = qca_tag_xmit, - .rcv = qca_tag_rcv, - .needed_headroom = QCA_HDR_LEN, -+ .promisc_on_master = true, - }; - - MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-5.15/766-v5.18-06-net-dsa-tag_qca-add-define-for-handling-mgmt-Etherne.patch b/target/linux/generic/backport-5.15/766-v5.18-06-net-dsa-tag_qca-add-define-for-handling-mgmt-Etherne.patch deleted file mode 100644 index 459454e03ba50a..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-06-net-dsa-tag_qca-add-define-for-handling-mgmt-Etherne.patch +++ /dev/null @@ -1,110 +0,0 @@ -From c2ee8181fddb293d296477f60b3eb4fa3ce4e1a6 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:25 +0100 -Subject: [PATCH 06/16] net: dsa: tag_qca: add define for handling mgmt - Ethernet packet - -Add all the required define to prepare support for mgmt read/write in -Ethernet packet. Any packet of this type has to be dropped as the only -use of these special packet is receive ack for an mgmt write request or -receive data for an mgmt read request. -A struct is used that emulates the Ethernet header but is used for a -different purpose. - -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - include/linux/dsa/tag_qca.h | 44 +++++++++++++++++++++++++++++++++++++ - net/dsa/tag_qca.c | 15 ++++++++++--- - 2 files changed, 56 insertions(+), 3 deletions(-) - ---- a/include/linux/dsa/tag_qca.h -+++ b/include/linux/dsa/tag_qca.h -@@ -12,10 +12,54 @@ - #define QCA_HDR_RECV_FRAME_IS_TAGGED BIT(3) - #define QCA_HDR_RECV_SOURCE_PORT GENMASK(2, 0) - -+/* Packet type for recv */ -+#define QCA_HDR_RECV_TYPE_NORMAL 0x0 -+#define QCA_HDR_RECV_TYPE_MIB 0x1 -+#define QCA_HDR_RECV_TYPE_RW_REG_ACK 0x2 -+ - #define QCA_HDR_XMIT_VERSION GENMASK(15, 14) - #define QCA_HDR_XMIT_PRIORITY GENMASK(13, 11) - #define QCA_HDR_XMIT_CONTROL GENMASK(10, 8) - #define QCA_HDR_XMIT_FROM_CPU BIT(7) - #define QCA_HDR_XMIT_DP_BIT GENMASK(6, 0) - -+/* Packet type for xmit */ -+#define QCA_HDR_XMIT_TYPE_NORMAL 0x0 -+#define QCA_HDR_XMIT_TYPE_RW_REG 0x1 -+ -+/* Check code for a valid mgmt packet. Switch will ignore the packet -+ * with this wrong. -+ */ -+#define QCA_HDR_MGMT_CHECK_CODE_VAL 0x5 -+ -+/* Specific define for in-band MDIO read/write with Ethernet packet */ -+#define QCA_HDR_MGMT_SEQ_LEN 4 /* 4 byte for the seq */ -+#define QCA_HDR_MGMT_COMMAND_LEN 4 /* 4 byte for the command */ -+#define QCA_HDR_MGMT_DATA1_LEN 4 /* First 4 byte for the mdio data */ -+#define QCA_HDR_MGMT_HEADER_LEN (QCA_HDR_MGMT_SEQ_LEN + \ -+ QCA_HDR_MGMT_COMMAND_LEN + \ -+ QCA_HDR_MGMT_DATA1_LEN) -+ -+#define QCA_HDR_MGMT_DATA2_LEN 12 /* Other 12 byte for the mdio data */ -+#define QCA_HDR_MGMT_PADDING_LEN 34 /* Padding to reach the min Ethernet packet */ -+ -+#define QCA_HDR_MGMT_PKT_LEN (QCA_HDR_MGMT_HEADER_LEN + \ -+ QCA_HDR_LEN + \ -+ QCA_HDR_MGMT_DATA2_LEN + \ -+ QCA_HDR_MGMT_PADDING_LEN) -+ -+#define QCA_HDR_MGMT_SEQ_NUM GENMASK(31, 0) /* 63, 32 */ -+#define QCA_HDR_MGMT_CHECK_CODE GENMASK(31, 29) /* 31, 29 */ -+#define QCA_HDR_MGMT_CMD BIT(28) /* 28 */ -+#define QCA_HDR_MGMT_LENGTH GENMASK(23, 20) /* 23, 20 */ -+#define QCA_HDR_MGMT_ADDR GENMASK(18, 0) /* 18, 0 */ -+ -+/* Special struct emulating a Ethernet header */ -+struct qca_mgmt_ethhdr { -+ u32 command; /* command bit 31:0 */ -+ u32 seq; /* seq 63:32 */ -+ u32 mdio_data; /* first 4byte mdio */ -+ __be16 hdr; /* qca hdr */ -+} __packed; -+ - #endif /* __TAG_QCA_H */ ---- a/net/dsa/tag_qca.c -+++ b/net/dsa/tag_qca.c -@@ -32,10 +32,12 @@ static struct sk_buff *qca_tag_xmit(stru - - static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev) - { -- u8 ver; -- u16 hdr; -- int port; -+ u8 ver, pk_type; - __be16 *phdr; -+ int port; -+ u16 hdr; -+ -+ BUILD_BUG_ON(sizeof(struct qca_mgmt_ethhdr) != QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); - - if (unlikely(!pskb_may_pull(skb, QCA_HDR_LEN))) - return NULL; -@@ -48,6 +50,13 @@ static struct sk_buff *qca_tag_rcv(struc - if (unlikely(ver != QCA_HDR_VERSION)) - return NULL; - -+ /* Get pk type */ -+ pk_type = FIELD_GET(QCA_HDR_RECV_TYPE, hdr); -+ -+ /* Ethernet MDIO read/write packet */ -+ if (pk_type == QCA_HDR_RECV_TYPE_RW_REG_ACK) -+ return NULL; -+ - /* Remove QCA tag and recalculate checksum */ - skb_pull_rcsum(skb, QCA_HDR_LEN); - dsa_strip_etype_header(skb, QCA_HDR_LEN); diff --git a/target/linux/generic/backport-5.15/766-v5.18-07-net-dsa-tag_qca-add-define-for-handling-MIB-packet.patch b/target/linux/generic/backport-5.15/766-v5.18-07-net-dsa-tag_qca-add-define-for-handling-MIB-packet.patch deleted file mode 100644 index 7e5dc657306836..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-07-net-dsa-tag_qca-add-define-for-handling-MIB-packet.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 18be654a4345f7d937b4bfbad74bea8093e3a93c Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:26 +0100 -Subject: [PATCH 07/16] net: dsa: tag_qca: add define for handling MIB packet - -Add struct to correctly parse a mib Ethernet packet. - -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - include/linux/dsa/tag_qca.h | 10 ++++++++++ - net/dsa/tag_qca.c | 4 ++++ - 2 files changed, 14 insertions(+) - ---- a/include/linux/dsa/tag_qca.h -+++ b/include/linux/dsa/tag_qca.h -@@ -62,4 +62,14 @@ struct qca_mgmt_ethhdr { - __be16 hdr; /* qca hdr */ - } __packed; - -+enum mdio_cmd { -+ MDIO_WRITE = 0x0, -+ MDIO_READ -+}; -+ -+struct mib_ethhdr { -+ u32 data[3]; /* first 3 mib counter */ -+ __be16 hdr; /* qca hdr */ -+} __packed; -+ - #endif /* __TAG_QCA_H */ ---- a/net/dsa/tag_qca.c -+++ b/net/dsa/tag_qca.c -@@ -57,6 +57,10 @@ static struct sk_buff *qca_tag_rcv(struc - if (pk_type == QCA_HDR_RECV_TYPE_RW_REG_ACK) - return NULL; - -+ /* Ethernet MIB counter packet */ -+ if (pk_type == QCA_HDR_RECV_TYPE_MIB) -+ return NULL; -+ - /* Remove QCA tag and recalculate checksum */ - skb_pull_rcsum(skb, QCA_HDR_LEN); - dsa_strip_etype_header(skb, QCA_HDR_LEN); diff --git a/target/linux/generic/backport-5.15/766-v5.18-08-net-dsa-tag_qca-add-support-for-handling-mgmt-and-MI.patch b/target/linux/generic/backport-5.15/766-v5.18-08-net-dsa-tag_qca-add-support-for-handling-mgmt-and-MI.patch deleted file mode 100644 index ad25da30e6d884..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-08-net-dsa-tag_qca-add-support-for-handling-mgmt-and-MI.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 31eb6b4386ad91930417e3f5c8157a4b5e31cbd5 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:27 +0100 -Subject: [PATCH 08/16] net: dsa: tag_qca: add support for handling mgmt and - MIB Ethernet packet - -Add connect/disconnect helper to assign private struct to the DSA switch. -Add support for Ethernet mgmt and MIB if the DSA driver provide an handler -to correctly parse and elaborate the data. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - include/linux/dsa/tag_qca.h | 7 +++++++ - net/dsa/tag_qca.c | 39 ++++++++++++++++++++++++++++++++++--- - 2 files changed, 43 insertions(+), 3 deletions(-) - ---- a/include/linux/dsa/tag_qca.h -+++ b/include/linux/dsa/tag_qca.h -@@ -72,4 +72,11 @@ struct mib_ethhdr { - __be16 hdr; /* qca hdr */ - } __packed; - -+struct qca_tagger_data { -+ void (*rw_reg_ack_handler)(struct dsa_switch *ds, -+ struct sk_buff *skb); -+ void (*mib_autocast_handler)(struct dsa_switch *ds, -+ struct sk_buff *skb); -+}; -+ - #endif /* __TAG_QCA_H */ ---- a/net/dsa/tag_qca.c -+++ b/net/dsa/tag_qca.c -@@ -5,6 +5,7 @@ - - #include - #include -+#include - #include - - #include "dsa_priv.h" -@@ -32,6 +33,9 @@ static struct sk_buff *qca_tag_xmit(stru - - static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev) - { -+ struct qca_tagger_data *tagger_data; -+ struct dsa_port *dp = dev->dsa_ptr; -+ struct dsa_switch *ds = dp->ds; - u8 ver, pk_type; - __be16 *phdr; - int port; -@@ -39,6 +43,8 @@ static struct sk_buff *qca_tag_rcv(struc - - BUILD_BUG_ON(sizeof(struct qca_mgmt_ethhdr) != QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); - -+ tagger_data = ds->tagger_data; -+ - if (unlikely(!pskb_may_pull(skb, QCA_HDR_LEN))) - return NULL; - -@@ -53,13 +59,19 @@ static struct sk_buff *qca_tag_rcv(struc - /* Get pk type */ - pk_type = FIELD_GET(QCA_HDR_RECV_TYPE, hdr); - -- /* Ethernet MDIO read/write packet */ -- if (pk_type == QCA_HDR_RECV_TYPE_RW_REG_ACK) -+ /* Ethernet mgmt read/write packet */ -+ if (pk_type == QCA_HDR_RECV_TYPE_RW_REG_ACK) { -+ if (likely(tagger_data->rw_reg_ack_handler)) -+ tagger_data->rw_reg_ack_handler(ds, skb); - return NULL; -+ } - - /* Ethernet MIB counter packet */ -- if (pk_type == QCA_HDR_RECV_TYPE_MIB) -+ if (pk_type == QCA_HDR_RECV_TYPE_MIB) { -+ if (likely(tagger_data->mib_autocast_handler)) -+ tagger_data->mib_autocast_handler(ds, skb); - return NULL; -+ } - - /* Remove QCA tag and recalculate checksum */ - skb_pull_rcsum(skb, QCA_HDR_LEN); -@@ -75,9 +87,30 @@ static struct sk_buff *qca_tag_rcv(struc - return skb; - } - -+static int qca_tag_connect(struct dsa_switch *ds) -+{ -+ struct qca_tagger_data *tagger_data; -+ -+ tagger_data = kzalloc(sizeof(*tagger_data), GFP_KERNEL); -+ if (!tagger_data) -+ return -ENOMEM; -+ -+ ds->tagger_data = tagger_data; -+ -+ return 0; -+} -+ -+static void qca_tag_disconnect(struct dsa_switch *ds) -+{ -+ kfree(ds->tagger_data); -+ ds->tagger_data = NULL; -+} -+ - static const struct dsa_device_ops qca_netdev_ops = { - .name = "qca", - .proto = DSA_TAG_PROTO_QCA, -+ .connect = qca_tag_connect, -+ .disconnect = qca_tag_disconnect, - .xmit = qca_tag_xmit, - .rcv = qca_tag_rcv, - .needed_headroom = QCA_HDR_LEN, diff --git a/target/linux/generic/backport-5.15/766-v5.18-09-net-dsa-qca8k-add-tracking-state-of-master-port.patch b/target/linux/generic/backport-5.15/766-v5.18-09-net-dsa-qca8k-add-tracking-state-of-master-port.patch deleted file mode 100644 index eb21cc3912461c..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-09-net-dsa-qca8k-add-tracking-state-of-master-port.patch +++ /dev/null @@ -1,67 +0,0 @@ -From cddbec19466a1dfb4d45ddd507d9f09f991d54ae Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:28 +0100 -Subject: [PATCH 09/16] net: dsa: qca8k: add tracking state of master port - -MDIO/MIB Ethernet require the master port and the tagger availabale to -correctly work. Use the new api master_state_change to track when master -is operational or not and set a bool in qca8k_priv. -We cache the first cached master available and we check if other cpu -port are operational when the cached one goes down. -This cached master will later be used by mdio read/write and mib request to -correctly use the working function. - -qca8k implementation for MDIO/MIB Ethernet is bad. CPU port0 is the only -one that answers with the ack packet or sends MIB Ethernet packets. For -this reason the master_state_change ignore CPU port6 and only checks -CPU port0 if it's operational and enables this mode. - -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 15 +++++++++++++++ - drivers/net/dsa/qca8k.h | 1 + - 2 files changed, 16 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -2401,6 +2401,20 @@ qca8k_port_lag_leave(struct dsa_switch * - return qca8k_lag_refresh_portmap(ds, port, lag, true); - } - -+static void -+qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, -+ bool operational) -+{ -+ struct dsa_port *dp = master->dsa_ptr; -+ struct qca8k_priv *priv = ds->priv; -+ -+ /* Ethernet MIB/MDIO is only supported for CPU port 0 */ -+ if (dp->index != 0) -+ return; -+ -+ priv->mgmt_master = operational ? (struct net_device *)master : NULL; -+} -+ - static const struct dsa_switch_ops qca8k_switch_ops = { - .get_tag_protocol = qca8k_get_tag_protocol, - .setup = qca8k_setup, -@@ -2436,6 +2450,7 @@ static const struct dsa_switch_ops qca8k - .get_phy_flags = qca8k_get_phy_flags, - .port_lag_join = qca8k_port_lag_join, - .port_lag_leave = qca8k_port_lag_leave, -+ .master_state_change = qca8k_master_change, - }; - - static int qca8k_read_switch_id(struct qca8k_priv *priv) ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -353,6 +353,7 @@ struct qca8k_priv { - struct dsa_switch_ops ops; - struct gpio_desc *reset_gpio; - unsigned int port_mtu[QCA8K_NUM_PORTS]; -+ struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ - }; - - struct qca8k_mib_desc { diff --git a/target/linux/generic/backport-5.15/766-v5.18-10-net-dsa-qca8k-add-support-for-mgmt-read-write-in-Eth.patch b/target/linux/generic/backport-5.15/766-v5.18-10-net-dsa-qca8k-add-support-for-mgmt-read-write-in-Eth.patch deleted file mode 100644 index 07c5ba46210057..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-10-net-dsa-qca8k-add-support-for-mgmt-read-write-in-Eth.patch +++ /dev/null @@ -1,363 +0,0 @@ -From 5950c7c0a68c915b336c70f79388626e2d576ab7 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:29 +0100 -Subject: [PATCH 10/16] net: dsa: qca8k: add support for mgmt read/write in - Ethernet packet - -Add qca8k side support for mgmt read/write in Ethernet packet. -qca8k supports some specially crafted Ethernet packet that can be used -for mgmt read/write instead of the legacy method uart/internal mdio. -This add support for the qca8k side to craft the packet and enqueue it. -Each port and the qca8k_priv have a special struct to put data in it. -The completion API is used to wait for the packet to be received back -with the requested data. - -The various steps are: -1. Craft the special packet with the qca hdr set to mgmt read/write - mode. -2. Set the lock in the dedicated mgmt struct. -3. Increment the seq number and set it in the mgmt pkt -4. Reinit the completion. -5. Enqueue the packet. -6. Wait the packet to be received. -7. Use the data set by the tagger to complete the mdio operation. - -If the completion timeouts or the ack value is not true, the legacy -mdio way is used. - -It has to be considered that in the initial setup mdio is still used and -mdio is still used until DSA is ready to accept and tag packet. - -tag_proto_connect() is used to fill the required handler for the tagger -to correctly parse and elaborate the special Ethernet mdio packet. - -Locking is added to qca8k_master_change() to make sure no mgmt Ethernet -are in progress. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 225 ++++++++++++++++++++++++++++++++++++++++ - drivers/net/dsa/qca8k.h | 13 +++ - 2 files changed, 238 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - #include "qca8k.h" - -@@ -170,6 +171,194 @@ qca8k_rmw(struct qca8k_priv *priv, u32 r - return regmap_update_bits(priv->regmap, reg, mask, write_val); - } - -+static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) -+{ -+ struct qca8k_mgmt_eth_data *mgmt_eth_data; -+ struct qca8k_priv *priv = ds->priv; -+ struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ u8 len, cmd; -+ -+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); -+ mgmt_eth_data = &priv->mgmt_eth_data; -+ -+ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); -+ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); -+ -+ /* Make sure the seq match the requested packet */ -+ if (mgmt_ethhdr->seq == mgmt_eth_data->seq) -+ mgmt_eth_data->ack = true; -+ -+ if (cmd == MDIO_READ) { -+ mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; -+ -+ /* Get the rest of the 12 byte of data */ -+ if (len > QCA_HDR_MGMT_DATA1_LEN) -+ memcpy(mgmt_eth_data->data + 1, skb->data, -+ QCA_HDR_MGMT_DATA2_LEN); -+ } -+ -+ complete(&mgmt_eth_data->rw_done); -+} -+ -+static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val, -+ int priority) -+{ -+ struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ struct sk_buff *skb; -+ u16 hdr; -+ -+ skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); -+ if (!skb) -+ return NULL; -+ -+ skb_reset_mac_header(skb); -+ skb_set_network_header(skb, skb->len); -+ -+ mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); -+ -+ hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); -+ hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority); -+ hdr |= QCA_HDR_XMIT_FROM_CPU; -+ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); -+ hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); -+ -+ mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); -+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, 4); -+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); -+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, -+ QCA_HDR_MGMT_CHECK_CODE_VAL); -+ -+ if (cmd == MDIO_WRITE) -+ mgmt_ethhdr->mdio_data = *val; -+ -+ mgmt_ethhdr->hdr = htons(hdr); -+ -+ skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); -+ -+ return skb; -+} -+ -+static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) -+{ -+ struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ -+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; -+ mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); -+} -+ -+static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val) -+{ -+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; -+ struct sk_buff *skb; -+ bool ack; -+ int ret; -+ -+ skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL, -+ QCA8K_ETHERNET_MDIO_PRIORITY); -+ if (!skb) -+ return -ENOMEM; -+ -+ mutex_lock(&mgmt_eth_data->mutex); -+ -+ /* Check mgmt_master if is operational */ -+ if (!priv->mgmt_master) { -+ kfree_skb(skb); -+ mutex_unlock(&mgmt_eth_data->mutex); -+ return -EINVAL; -+ } -+ -+ skb->dev = priv->mgmt_master; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the mdio pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); -+ -+ *val = mgmt_eth_data->data[0]; -+ ack = mgmt_eth_data->ack; -+ -+ mutex_unlock(&mgmt_eth_data->mutex); -+ -+ if (ret <= 0) -+ return -ETIMEDOUT; -+ -+ if (!ack) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 val) -+{ -+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; -+ struct sk_buff *skb; -+ bool ack; -+ int ret; -+ -+ skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, &val, -+ QCA8K_ETHERNET_MDIO_PRIORITY); -+ if (!skb) -+ return -ENOMEM; -+ -+ mutex_lock(&mgmt_eth_data->mutex); -+ -+ /* Check mgmt_master if is operational */ -+ if (!priv->mgmt_master) { -+ kfree_skb(skb); -+ mutex_unlock(&mgmt_eth_data->mutex); -+ return -EINVAL; -+ } -+ -+ skb->dev = priv->mgmt_master; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the mdio pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); -+ -+ ack = mgmt_eth_data->ack; -+ -+ mutex_unlock(&mgmt_eth_data->mutex); -+ -+ if (ret <= 0) -+ return -ETIMEDOUT; -+ -+ if (!ack) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int -+qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) -+{ -+ u32 val = 0; -+ int ret; -+ -+ ret = qca8k_read_eth(priv, reg, &val); -+ if (ret) -+ return ret; -+ -+ val &= ~mask; -+ val |= write_val; -+ -+ return qca8k_write_eth(priv, reg, val); -+} -+ - static int - qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) - { -@@ -178,6 +367,9 @@ qca8k_regmap_read(void *ctx, uint32_t re - u16 r1, r2, page; - int ret; - -+ if (!qca8k_read_eth(priv, reg, val)) -+ return 0; -+ - qca8k_split_addr(reg, &r1, &r2, &page); - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -@@ -201,6 +393,9 @@ qca8k_regmap_write(void *ctx, uint32_t r - u16 r1, r2, page; - int ret; - -+ if (!qca8k_write_eth(priv, reg, val)) -+ return 0; -+ - qca8k_split_addr(reg, &r1, &r2, &page); - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -@@ -225,6 +420,9 @@ qca8k_regmap_update_bits(void *ctx, uint - u32 val; - int ret; - -+ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) -+ return 0; -+ - qca8k_split_addr(reg, &r1, &r2, &page); - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -@@ -2412,7 +2610,30 @@ qca8k_master_change(struct dsa_switch *d - if (dp->index != 0) - return; - -+ mutex_lock(&priv->mgmt_eth_data.mutex); -+ - priv->mgmt_master = operational ? (struct net_device *)master : NULL; -+ -+ mutex_unlock(&priv->mgmt_eth_data.mutex); -+} -+ -+static int qca8k_connect_tag_protocol(struct dsa_switch *ds, -+ enum dsa_tag_protocol proto) -+{ -+ struct qca_tagger_data *tagger_data; -+ -+ switch (proto) { -+ case DSA_TAG_PROTO_QCA: -+ tagger_data = ds->tagger_data; -+ -+ tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; -+ -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; - } - - static const struct dsa_switch_ops qca8k_switch_ops = { -@@ -2451,6 +2672,7 @@ static const struct dsa_switch_ops qca8k - .port_lag_join = qca8k_port_lag_join, - .port_lag_leave = qca8k_port_lag_leave, - .master_state_change = qca8k_master_change, -+ .connect_tag_protocol = qca8k_connect_tag_protocol, - }; - - static int qca8k_read_switch_id(struct qca8k_priv *priv) -@@ -2530,6 +2752,9 @@ qca8k_sw_probe(struct mdio_device *mdiod - if (!priv->ds) - return -ENOMEM; - -+ mutex_init(&priv->mgmt_eth_data.mutex); -+ init_completion(&priv->mgmt_eth_data.rw_done); -+ - priv->ds->dev = &mdiodev->dev; - priv->ds->num_ports = QCA8K_NUM_PORTS; - priv->ds->priv = priv; ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -11,6 +11,10 @@ - #include - #include - #include -+#include -+ -+#define QCA8K_ETHERNET_MDIO_PRIORITY 7 -+#define QCA8K_ETHERNET_TIMEOUT 100 - - #define QCA8K_NUM_PORTS 7 - #define QCA8K_NUM_CPU_PORTS 2 -@@ -328,6 +332,14 @@ enum { - QCA8K_CPU_PORT6, - }; - -+struct qca8k_mgmt_eth_data { -+ struct completion rw_done; -+ struct mutex mutex; /* Enforce one mdio read/write at time */ -+ bool ack; -+ u32 seq; -+ u32 data[4]; -+}; -+ - struct qca8k_ports_config { - bool sgmii_rx_clk_falling_edge; - bool sgmii_tx_clk_falling_edge; -@@ -354,6 +366,7 @@ struct qca8k_priv { - struct gpio_desc *reset_gpio; - unsigned int port_mtu[QCA8K_NUM_PORTS]; - struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ -+ struct qca8k_mgmt_eth_data mgmt_eth_data; - }; - - struct qca8k_mib_desc { diff --git a/target/linux/generic/backport-5.15/766-v5.18-11-net-dsa-qca8k-add-support-for-mib-autocast-in-Ethern.patch b/target/linux/generic/backport-5.15/766-v5.18-11-net-dsa-qca8k-add-support-for-mib-autocast-in-Ethern.patch deleted file mode 100644 index 0dcf279433837d..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-11-net-dsa-qca8k-add-support-for-mib-autocast-in-Ethern.patch +++ /dev/null @@ -1,226 +0,0 @@ -From 5c957c7ca78cce5e4b96866722b0115bd758d945 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:30 +0100 -Subject: [PATCH 11/16] net: dsa: qca8k: add support for mib autocast in - Ethernet packet - -The switch can autocast MIB counter using Ethernet packet. -Add support for this and provide a handler for the tagger. -The switch will send packet with MIB counter for each port, the switch -will use completion API to wait for the correct packet to be received -and will complete the task only when each packet is received. -Although the handler will drop all the other packet, we still have to -consume each MIB packet to complete the request. This is done to prevent -mixed data with concurrent ethtool request. - -connect_tag_protocol() is used to add the handler to the tag_qca tagger, -master_state_change() use the MIB lock to make sure no MIB Ethernet is -in progress. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 106 +++++++++++++++++++++++++++++++++++++++- - drivers/net/dsa/qca8k.h | 17 ++++++- - 2 files changed, 121 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -830,7 +830,10 @@ qca8k_mib_init(struct qca8k_priv *priv) - int ret; - - mutex_lock(&priv->reg_mutex); -- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | -+ QCA8K_MIB_BUSY); - if (ret) - goto exit; - -@@ -1901,6 +1904,97 @@ qca8k_get_strings(struct dsa_switch *ds, - ETH_GSTRING_LEN); - } - -+static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) -+{ -+ const struct qca8k_match_data *match_data; -+ struct qca8k_mib_eth_data *mib_eth_data; -+ struct qca8k_priv *priv = ds->priv; -+ const struct qca8k_mib_desc *mib; -+ struct mib_ethhdr *mib_ethhdr; -+ int i, mib_len, offset = 0; -+ u64 *data; -+ u8 port; -+ -+ mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); -+ mib_eth_data = &priv->mib_eth_data; -+ -+ /* The switch autocast every port. Ignore other packet and -+ * parse only the requested one. -+ */ -+ port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr)); -+ if (port != mib_eth_data->req_port) -+ goto exit; -+ -+ match_data = device_get_match_data(priv->dev); -+ data = mib_eth_data->data; -+ -+ for (i = 0; i < match_data->mib_count; i++) { -+ mib = &ar8327_mib[i]; -+ -+ /* First 3 mib are present in the skb head */ -+ if (i < 3) { -+ data[i] = mib_ethhdr->data[i]; -+ continue; -+ } -+ -+ mib_len = sizeof(uint32_t); -+ -+ /* Some mib are 64 bit wide */ -+ if (mib->size == 2) -+ mib_len = sizeof(uint64_t); -+ -+ /* Copy the mib value from packet to the */ -+ memcpy(data + i, skb->data + offset, mib_len); -+ -+ /* Set the offset for the next mib */ -+ offset += mib_len; -+ } -+ -+exit: -+ /* Complete on receiving all the mib packet */ -+ if (refcount_dec_and_test(&mib_eth_data->port_parsed)) -+ complete(&mib_eth_data->rw_done); -+} -+ -+static int -+qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data) -+{ -+ struct dsa_port *dp = dsa_to_port(ds, port); -+ struct qca8k_mib_eth_data *mib_eth_data; -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ mib_eth_data = &priv->mib_eth_data; -+ -+ mutex_lock(&mib_eth_data->mutex); -+ -+ reinit_completion(&mib_eth_data->rw_done); -+ -+ mib_eth_data->req_port = dp->index; -+ mib_eth_data->data = data; -+ refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS); -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ /* Send mib autocast request */ -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) | -+ QCA8K_MIB_BUSY); -+ -+ mutex_unlock(&priv->reg_mutex); -+ -+ if (ret) -+ goto exit; -+ -+ ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT); -+ -+exit: -+ mutex_unlock(&mib_eth_data->mutex); -+ -+ return ret; -+} -+ - static void - qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, - uint64_t *data) -@@ -1912,6 +2006,10 @@ qca8k_get_ethtool_stats(struct dsa_switc - u32 hi = 0; - int ret; - -+ if (priv->mgmt_master && -+ qca8k_get_ethtool_stats_eth(ds, port, data) > 0) -+ return; -+ - match_data = of_device_get_match_data(priv->dev); - - for (i = 0; i < match_data->mib_count; i++) { -@@ -2611,9 +2709,11 @@ qca8k_master_change(struct dsa_switch *d - return; - - mutex_lock(&priv->mgmt_eth_data.mutex); -+ mutex_lock(&priv->mib_eth_data.mutex); - - priv->mgmt_master = operational ? (struct net_device *)master : NULL; - -+ mutex_unlock(&priv->mib_eth_data.mutex); - mutex_unlock(&priv->mgmt_eth_data.mutex); - } - -@@ -2627,6 +2727,7 @@ static int qca8k_connect_tag_protocol(st - tagger_data = ds->tagger_data; - - tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; -+ tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler; - - break; - default: -@@ -2755,6 +2856,9 @@ qca8k_sw_probe(struct mdio_device *mdiod - mutex_init(&priv->mgmt_eth_data.mutex); - init_completion(&priv->mgmt_eth_data.rw_done); - -+ mutex_init(&priv->mib_eth_data.mutex); -+ init_completion(&priv->mib_eth_data.rw_done); -+ - priv->ds->dev = &mdiodev->dev; - priv->ds->num_ports = QCA8K_NUM_PORTS; - priv->ds->priv = priv; ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -67,7 +67,7 @@ - #define QCA8K_REG_MODULE_EN 0x030 - #define QCA8K_MODULE_EN_MIB BIT(0) - #define QCA8K_REG_MIB 0x034 --#define QCA8K_MIB_FLUSH BIT(24) -+#define QCA8K_MIB_FUNC GENMASK(26, 24) - #define QCA8K_MIB_CPU_KEEP BIT(20) - #define QCA8K_MIB_BUSY BIT(17) - #define QCA8K_MDIO_MASTER_CTRL 0x3c -@@ -317,6 +317,12 @@ enum qca8k_vlan_cmd { - QCA8K_VLAN_READ = 6, - }; - -+enum qca8k_mid_cmd { -+ QCA8K_MIB_FLUSH = 1, -+ QCA8K_MIB_FLUSH_PORT = 2, -+ QCA8K_MIB_CAST = 3, -+}; -+ - struct ar8xxx_port_status { - int enabled; - }; -@@ -340,6 +346,14 @@ struct qca8k_mgmt_eth_data { - u32 data[4]; - }; - -+struct qca8k_mib_eth_data { -+ struct completion rw_done; -+ struct mutex mutex; /* Process one command at time */ -+ refcount_t port_parsed; /* Counter to track parsed port */ -+ u8 req_port; -+ u64 *data; /* pointer to ethtool data */ -+}; -+ - struct qca8k_ports_config { - bool sgmii_rx_clk_falling_edge; - bool sgmii_tx_clk_falling_edge; -@@ -367,6 +381,7 @@ struct qca8k_priv { - unsigned int port_mtu[QCA8K_NUM_PORTS]; - struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ - struct qca8k_mgmt_eth_data mgmt_eth_data; -+ struct qca8k_mib_eth_data mib_eth_data; - }; - - struct qca8k_mib_desc { diff --git a/target/linux/generic/backport-5.15/766-v5.18-12-net-dsa-qca8k-add-support-for-phy-read-write-with-mg.patch b/target/linux/generic/backport-5.15/766-v5.18-12-net-dsa-qca8k-add-support-for-phy-read-write-with-mg.patch deleted file mode 100644 index f5899eb5901a19..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-12-net-dsa-qca8k-add-support-for-phy-read-write-with-mg.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 2cd5485663847d468dc207b3ff85fb1fab44d97f Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:31 +0100 -Subject: [PATCH 12/16] net: dsa: qca8k: add support for phy read/write with - mgmt Ethernet - -Use mgmt Ethernet also for phy read/write if availabale. Use a different -seq number to make sure we receive the correct packet. -On any error, we fallback to the legacy mdio read/write. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 216 ++++++++++++++++++++++++++++++++++++++++ - drivers/net/dsa/qca8k.h | 1 + - 2 files changed, 217 insertions(+) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -867,6 +867,199 @@ qca8k_port_set_status(struct qca8k_priv - regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); - } - -+static int -+qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, -+ struct sk_buff *read_skb, u32 *val) -+{ -+ struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL); -+ bool ack; -+ int ret; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the copy pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ ack = mgmt_eth_data->ack; -+ -+ if (ret <= 0) -+ return -ETIMEDOUT; -+ -+ if (!ack) -+ return -EINVAL; -+ -+ *val = mgmt_eth_data->data[0]; -+ -+ return 0; -+} -+ -+static int -+qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, -+ int regnum, u16 data) -+{ -+ struct sk_buff *write_skb, *clear_skb, *read_skb; -+ struct qca8k_mgmt_eth_data *mgmt_eth_data; -+ u32 write_val, clear_val = 0, val; -+ struct net_device *mgmt_master; -+ int ret, ret1; -+ bool ack; -+ -+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -+ return -EINVAL; -+ -+ mgmt_eth_data = &priv->mgmt_eth_data; -+ -+ write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -+ QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -+ QCA8K_MDIO_MASTER_REG_ADDR(regnum); -+ -+ if (read) { -+ write_val |= QCA8K_MDIO_MASTER_READ; -+ } else { -+ write_val |= QCA8K_MDIO_MASTER_WRITE; -+ write_val |= QCA8K_MDIO_MASTER_DATA(data); -+ } -+ -+ /* Prealloc all the needed skb before the lock */ -+ write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, -+ &write_val, QCA8K_ETHERNET_PHY_PRIORITY); -+ if (!write_skb) -+ return -ENOMEM; -+ -+ clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, -+ &clear_val, QCA8K_ETHERNET_PHY_PRIORITY); -+ if (!write_skb) { -+ ret = -ENOMEM; -+ goto err_clear_skb; -+ } -+ -+ read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, -+ &clear_val, QCA8K_ETHERNET_PHY_PRIORITY); -+ if (!write_skb) { -+ ret = -ENOMEM; -+ goto err_read_skb; -+ } -+ -+ /* Actually start the request: -+ * 1. Send mdio master packet -+ * 2. Busy Wait for mdio master command -+ * 3. Get the data if we are reading -+ * 4. Reset the mdio master (even with error) -+ */ -+ mutex_lock(&mgmt_eth_data->mutex); -+ -+ /* Check if mgmt_master is operational */ -+ mgmt_master = priv->mgmt_master; -+ if (!mgmt_master) { -+ mutex_unlock(&mgmt_eth_data->mutex); -+ ret = -EINVAL; -+ goto err_mgmt_master; -+ } -+ -+ read_skb->dev = mgmt_master; -+ clear_skb->dev = mgmt_master; -+ write_skb->dev = mgmt_master; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the write pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(write_skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ ack = mgmt_eth_data->ack; -+ -+ if (ret <= 0) { -+ ret = -ETIMEDOUT; -+ kfree_skb(read_skb); -+ goto exit; -+ } -+ -+ if (!ack) { -+ ret = -EINVAL; -+ kfree_skb(read_skb); -+ goto exit; -+ } -+ -+ ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1, -+ !(val & QCA8K_MDIO_MASTER_BUSY), 0, -+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -+ mgmt_eth_data, read_skb, &val); -+ -+ if (ret < 0 && ret1 < 0) { -+ ret = ret1; -+ goto exit; -+ } -+ -+ if (read) { -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the read pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(read_skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ ack = mgmt_eth_data->ack; -+ -+ if (ret <= 0) { -+ ret = -ETIMEDOUT; -+ goto exit; -+ } -+ -+ if (!ack) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK; -+ } else { -+ kfree_skb(read_skb); -+ } -+exit: -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the clear pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(clear_skb); -+ -+ wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ mutex_unlock(&mgmt_eth_data->mutex); -+ -+ return ret; -+ -+ /* Error handling before lock */ -+err_mgmt_master: -+ kfree_skb(read_skb); -+err_read_skb: -+ kfree_skb(clear_skb); -+err_clear_skb: -+ kfree_skb(write_skb); -+ -+ return ret; -+} -+ - static u32 - qca8k_port_to_phy(int port) - { -@@ -989,6 +1182,12 @@ qca8k_internal_mdio_write(struct mii_bus - { - struct qca8k_priv *priv = slave_bus->priv; - struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ /* Use mdio Ethernet when available, fallback to legacy one on error */ -+ ret = qca8k_phy_eth_command(priv, false, phy, regnum, data); -+ if (!ret) -+ return 0; - - return qca8k_mdio_write(bus, phy, regnum, data); - } -@@ -998,6 +1197,12 @@ qca8k_internal_mdio_read(struct mii_bus - { - struct qca8k_priv *priv = slave_bus->priv; - struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ /* Use mdio Ethernet when available, fallback to legacy one on error */ -+ ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0); -+ if (ret >= 0) -+ return ret; - - return qca8k_mdio_read(bus, phy, regnum); - } -@@ -1006,6 +1211,7 @@ static int - qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data) - { - struct qca8k_priv *priv = ds->priv; -+ int ret; - - /* Check if the legacy mapping should be used and the - * port is not correctly mapped to the right PHY in the -@@ -1014,6 +1220,11 @@ qca8k_phy_write(struct dsa_switch *ds, i - if (priv->legacy_phy_port_mapping) - port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; - -+ /* Use mdio Ethernet when available, fallback to legacy one on error */ -+ ret = qca8k_phy_eth_command(priv, false, port, regnum, 0); -+ if (!ret) -+ return ret; -+ - return qca8k_mdio_write(priv->bus, port, regnum, data); - } - -@@ -1030,6 +1241,11 @@ qca8k_phy_read(struct dsa_switch *ds, in - if (priv->legacy_phy_port_mapping) - port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; - -+ /* Use mdio Ethernet when available, fallback to legacy one on error */ -+ ret = qca8k_phy_eth_command(priv, true, port, regnum, 0); -+ if (ret >= 0) -+ return ret; -+ - ret = qca8k_mdio_read(priv->bus, port, regnum); - - if (ret < 0) ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -14,6 +14,7 @@ - #include - - #define QCA8K_ETHERNET_MDIO_PRIORITY 7 -+#define QCA8K_ETHERNET_PHY_PRIORITY 6 - #define QCA8K_ETHERNET_TIMEOUT 100 - - #define QCA8K_NUM_PORTS 7 diff --git a/target/linux/generic/backport-5.15/766-v5.18-13-net-dsa-qca8k-move-page-cache-to-driver-priv.patch b/target/linux/generic/backport-5.15/766-v5.18-13-net-dsa-qca8k-move-page-cache-to-driver-priv.patch deleted file mode 100644 index 4ac0bc32fdbead..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-13-net-dsa-qca8k-move-page-cache-to-driver-priv.patch +++ /dev/null @@ -1,208 +0,0 @@ -From 4264350acb75430d5021a1d7de56a33faf69a097 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:32 +0100 -Subject: [PATCH 13/16] net: dsa: qca8k: move page cache to driver priv - -There can be multiple qca8k switch on the same system. Move the static -qca8k_current_page to qca8k_priv and make it specific for each switch. - -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 42 ++++++++++++++++++++--------------------- - drivers/net/dsa/qca8k.h | 9 +++++++++ - 2 files changed, 29 insertions(+), 22 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -75,12 +75,6 @@ static const struct qca8k_mib_desc ar832 - MIB_DESC(1, 0xac, "TXUnicast"), - }; - --/* The 32bit switch registers are accessed indirectly. To achieve this we need -- * to set the page of the register. Track the last page that was set to reduce -- * mdio writes -- */ --static u16 qca8k_current_page = 0xffff; -- - static void - qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) - { -@@ -134,11 +128,13 @@ qca8k_mii_write32(struct mii_bus *bus, i - } - - static int --qca8k_set_page(struct mii_bus *bus, u16 page) -+qca8k_set_page(struct qca8k_priv *priv, u16 page) - { -+ u16 *cached_page = &priv->mdio_cache.page; -+ struct mii_bus *bus = priv->bus; - int ret; - -- if (page == qca8k_current_page) -+ if (page == *cached_page) - return 0; - - ret = bus->write(bus, 0x18, 0, page); -@@ -148,7 +144,7 @@ qca8k_set_page(struct mii_bus *bus, u16 - return ret; - } - -- qca8k_current_page = page; -+ *cached_page = page; - usleep_range(1000, 2000); - return 0; - } -@@ -374,7 +370,7 @@ qca8k_regmap_read(void *ctx, uint32_t re - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - -- ret = qca8k_set_page(bus, page); -+ ret = qca8k_set_page(priv, page); - if (ret < 0) - goto exit; - -@@ -400,7 +396,7 @@ qca8k_regmap_write(void *ctx, uint32_t r - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - -- ret = qca8k_set_page(bus, page); -+ ret = qca8k_set_page(priv, page); - if (ret < 0) - goto exit; - -@@ -427,7 +423,7 @@ qca8k_regmap_update_bits(void *ctx, uint - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - -- ret = qca8k_set_page(bus, page); -+ ret = qca8k_set_page(priv, page); - if (ret < 0) - goto exit; - -@@ -1098,8 +1094,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus - } - - static int --qca8k_mdio_write(struct mii_bus *bus, int phy, int regnum, u16 data) -+qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) - { -+ struct mii_bus *bus = priv->bus; - u16 r1, r2, page; - u32 val; - int ret; -@@ -1116,7 +1113,7 @@ qca8k_mdio_write(struct mii_bus *bus, in - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - -- ret = qca8k_set_page(bus, page); -+ ret = qca8k_set_page(priv, page); - if (ret) - goto exit; - -@@ -1135,8 +1132,9 @@ exit: - } - - static int --qca8k_mdio_read(struct mii_bus *bus, int phy, int regnum) -+qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) - { -+ struct mii_bus *bus = priv->bus; - u16 r1, r2, page; - u32 val; - int ret; -@@ -1152,7 +1150,7 @@ qca8k_mdio_read(struct mii_bus *bus, int - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - -- ret = qca8k_set_page(bus, page); -+ ret = qca8k_set_page(priv, page); - if (ret) - goto exit; - -@@ -1181,7 +1179,6 @@ static int - qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) - { - struct qca8k_priv *priv = slave_bus->priv; -- struct mii_bus *bus = priv->bus; - int ret; - - /* Use mdio Ethernet when available, fallback to legacy one on error */ -@@ -1189,14 +1186,13 @@ qca8k_internal_mdio_write(struct mii_bus - if (!ret) - return 0; - -- return qca8k_mdio_write(bus, phy, regnum, data); -+ return qca8k_mdio_write(priv, phy, regnum, data); - } - - static int - qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) - { - struct qca8k_priv *priv = slave_bus->priv; -- struct mii_bus *bus = priv->bus; - int ret; - - /* Use mdio Ethernet when available, fallback to legacy one on error */ -@@ -1204,7 +1200,7 @@ qca8k_internal_mdio_read(struct mii_bus - if (ret >= 0) - return ret; - -- return qca8k_mdio_read(bus, phy, regnum); -+ return qca8k_mdio_read(priv, phy, regnum); - } - - static int -@@ -1225,7 +1221,7 @@ qca8k_phy_write(struct dsa_switch *ds, i - if (!ret) - return ret; - -- return qca8k_mdio_write(priv->bus, port, regnum, data); -+ return qca8k_mdio_write(priv, port, regnum, data); - } - - static int -@@ -1246,7 +1242,7 @@ qca8k_phy_read(struct dsa_switch *ds, in - if (ret >= 0) - return ret; - -- ret = qca8k_mdio_read(priv->bus, port, regnum); -+ ret = qca8k_mdio_read(priv, port, regnum); - - if (ret < 0) - return 0xffff; -@@ -3060,6 +3056,8 @@ qca8k_sw_probe(struct mdio_device *mdiod - return PTR_ERR(priv->regmap); - } - -+ priv->mdio_cache.page = 0xffff; -+ - /* Check the detected switch id */ - ret = qca8k_read_switch_id(priv); - if (ret) ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -363,6 +363,14 @@ struct qca8k_ports_config { - u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ - }; - -+struct qca8k_mdio_cache { -+/* The 32bit switch registers are accessed indirectly. To achieve this we need -+ * to set the page of the register. Track the last page that was set to reduce -+ * mdio writes -+ */ -+ u16 page; -+}; -+ - struct qca8k_priv { - u8 switch_id; - u8 switch_revision; -@@ -383,6 +391,7 @@ struct qca8k_priv { - struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ - struct qca8k_mgmt_eth_data mgmt_eth_data; - struct qca8k_mib_eth_data mib_eth_data; -+ struct qca8k_mdio_cache mdio_cache; - }; - - struct qca8k_mib_desc { diff --git a/target/linux/generic/backport-5.15/766-v5.18-14-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch b/target/linux/generic/backport-5.15/766-v5.18-14-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch deleted file mode 100644 index e2cb2721ce92cb..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-14-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 2481d206fae7884cd07014fd1318e63af35e99eb Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:33 +0100 -Subject: [PATCH 14/16] net: dsa: qca8k: cache lo and hi for mdio write - -From Documentation, we can cache lo and hi the same way we do with the -page. This massively reduce the mdio write as 3/4 of the time as we only -require to write the lo or hi part for a mdio write. - -Signed-off-by: Ansuel Smith -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 61 +++++++++++++++++++++++++++++++++-------- - drivers/net/dsa/qca8k.h | 5 ++++ - 2 files changed, 54 insertions(+), 12 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -89,6 +89,44 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u - } - - static int -+qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo) -+{ -+ u16 *cached_lo = &priv->mdio_cache.lo; -+ struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ if (lo == *cached_lo) -+ return 0; -+ -+ ret = bus->write(bus, phy_id, regnum, lo); -+ if (ret < 0) -+ dev_err_ratelimited(&bus->dev, -+ "failed to write qca8k 32bit lo register\n"); -+ -+ *cached_lo = lo; -+ return 0; -+} -+ -+static int -+qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi) -+{ -+ u16 *cached_hi = &priv->mdio_cache.hi; -+ struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ if (hi == *cached_hi) -+ return 0; -+ -+ ret = bus->write(bus, phy_id, regnum, hi); -+ if (ret < 0) -+ dev_err_ratelimited(&bus->dev, -+ "failed to write qca8k 32bit hi register\n"); -+ -+ *cached_hi = hi; -+ return 0; -+} -+ -+static int - qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) - { - int ret; -@@ -111,7 +149,7 @@ qca8k_mii_read32(struct mii_bus *bus, in - } - - static void --qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) -+qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val) - { - u16 lo, hi; - int ret; -@@ -119,12 +157,9 @@ qca8k_mii_write32(struct mii_bus *bus, i - lo = val & 0xffff; - hi = (u16)(val >> 16); - -- ret = bus->write(bus, phy_id, regnum, lo); -+ ret = qca8k_set_lo(priv, phy_id, regnum, lo); - if (ret >= 0) -- ret = bus->write(bus, phy_id, regnum + 1, hi); -- if (ret < 0) -- dev_err_ratelimited(&bus->dev, -- "failed to write qca8k 32bit register\n"); -+ ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi); - } - - static int -@@ -400,7 +435,7 @@ qca8k_regmap_write(void *ctx, uint32_t r - if (ret < 0) - goto exit; - -- qca8k_mii_write32(bus, 0x10 | r2, r1, val); -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); - - exit: - mutex_unlock(&bus->mdio_lock); -@@ -433,7 +468,7 @@ qca8k_regmap_update_bits(void *ctx, uint - - val &= ~mask; - val |= write_val; -- qca8k_mii_write32(bus, 0x10 | r2, r1, val); -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); - - exit: - mutex_unlock(&bus->mdio_lock); -@@ -1117,14 +1152,14 @@ qca8k_mdio_write(struct qca8k_priv *priv - if (ret) - goto exit; - -- qca8k_mii_write32(bus, 0x10 | r2, r1, val); -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); - - ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, - QCA8K_MDIO_MASTER_BUSY); - - exit: - /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(bus, 0x10 | r2, r1, 0); -+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0); - - mutex_unlock(&bus->mdio_lock); - -@@ -1154,7 +1189,7 @@ qca8k_mdio_read(struct qca8k_priv *priv, - if (ret) - goto exit; - -- qca8k_mii_write32(bus, 0x10 | r2, r1, val); -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); - - ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, - QCA8K_MDIO_MASTER_BUSY); -@@ -1165,7 +1200,7 @@ qca8k_mdio_read(struct qca8k_priv *priv, - - exit: - /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(bus, 0x10 | r2, r1, 0); -+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0); - - mutex_unlock(&bus->mdio_lock); - -@@ -3057,6 +3092,8 @@ qca8k_sw_probe(struct mdio_device *mdiod - } - - priv->mdio_cache.page = 0xffff; -+ priv->mdio_cache.lo = 0xffff; -+ priv->mdio_cache.hi = 0xffff; - - /* Check the detected switch id */ - ret = qca8k_read_switch_id(priv); ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -369,6 +369,11 @@ struct qca8k_mdio_cache { - * mdio writes - */ - u16 page; -+/* lo and hi can also be cached and from Documentation we can skip one -+ * extra mdio write if lo or hi is didn't change. -+ */ -+ u16 lo; -+ u16 hi; - }; - - struct qca8k_priv { diff --git a/target/linux/generic/backport-5.15/766-v5.18-15-net-dsa-qca8k-add-support-for-larger-read-write-size.patch b/target/linux/generic/backport-5.15/766-v5.18-15-net-dsa-qca8k-add-support-for-larger-read-write-size.patch deleted file mode 100644 index 5acd13dbad8e84..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-15-net-dsa-qca8k-add-support-for-larger-read-write-size.patch +++ /dev/null @@ -1,206 +0,0 @@ -From 90386223f44e2a751d7e9e9ac8f78ea33358a891 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:34 +0100 -Subject: [PATCH 15/16] net: dsa: qca8k: add support for larger read/write size - with mgmt Ethernet - -mgmt Ethernet packet can read/write up to 16byte at times. The len reg -is limited to 15 (0xf). The switch actually sends and accepts data in 4 -different steps of len values. -Len steps: -- 0: nothing -- 1-4: first 4 byte -- 5-6: first 12 byte -- 7-15: all 16 byte - -In the alloc skb function we check if the len is 16 and we fix it to a -len of 15. It the read/write function interest to extract the real asked -data. The tagger handler will always copy the fully 16byte with a READ -command. This is useful for some big regs like the fdb reg that are -more than 4byte of data. This permits to introduce a bulk function that -will send and request the entire entry in one go. -Write function is changed and it does now require to pass the pointer to -val to also handle array val. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 61 +++++++++++++++++++++++++++-------------- - 1 file changed, 41 insertions(+), 20 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -222,7 +222,9 @@ static void qca8k_rw_reg_ack_handler(str - if (cmd == MDIO_READ) { - mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; - -- /* Get the rest of the 12 byte of data */ -+ /* Get the rest of the 12 byte of data. -+ * The read/write function will extract the requested data. -+ */ - if (len > QCA_HDR_MGMT_DATA1_LEN) - memcpy(mgmt_eth_data->data + 1, skb->data, - QCA_HDR_MGMT_DATA2_LEN); -@@ -232,16 +234,30 @@ static void qca8k_rw_reg_ack_handler(str - } - - static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val, -- int priority) -+ int priority, unsigned int len) - { - struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ unsigned int real_len; - struct sk_buff *skb; -+ u32 *data2; - u16 hdr; - - skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); - if (!skb) - return NULL; - -+ /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte -+ * Actually for some reason the steps are: -+ * 0: nothing -+ * 1-4: first 4 byte -+ * 5-6: first 12 byte -+ * 7-15: all 16 byte -+ */ -+ if (len == 16) -+ real_len = 15; -+ else -+ real_len = len; -+ - skb_reset_mac_header(skb); - skb_set_network_header(skb, skb->len); - -@@ -254,7 +270,7 @@ static struct sk_buff *qca8k_alloc_mdio_ - hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); - - mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); -- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, 4); -+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); - mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); - mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, - QCA_HDR_MGMT_CHECK_CODE_VAL); -@@ -264,7 +280,9 @@ static struct sk_buff *qca8k_alloc_mdio_ - - mgmt_ethhdr->hdr = htons(hdr); - -- skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); -+ data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); -+ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) -+ memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); - - return skb; - } -@@ -277,7 +295,7 @@ static void qca8k_mdio_header_fill_seq_n - mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); - } - --static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val) -+static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) - { - struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; - struct sk_buff *skb; -@@ -285,7 +303,7 @@ static int qca8k_read_eth(struct qca8k_p - int ret; - - skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL, -- QCA8K_ETHERNET_MDIO_PRIORITY); -+ QCA8K_ETHERNET_MDIO_PRIORITY, len); - if (!skb) - return -ENOMEM; - -@@ -313,6 +331,9 @@ static int qca8k_read_eth(struct qca8k_p - msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); - - *val = mgmt_eth_data->data[0]; -+ if (len > QCA_HDR_MGMT_DATA1_LEN) -+ memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN); -+ - ack = mgmt_eth_data->ack; - - mutex_unlock(&mgmt_eth_data->mutex); -@@ -326,15 +347,15 @@ static int qca8k_read_eth(struct qca8k_p - return 0; - } - --static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 val) -+static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) - { - struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; - struct sk_buff *skb; - bool ack; - int ret; - -- skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, &val, -- QCA8K_ETHERNET_MDIO_PRIORITY); -+ skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val, -+ QCA8K_ETHERNET_MDIO_PRIORITY, len); - if (!skb) - return -ENOMEM; - -@@ -380,14 +401,14 @@ qca8k_regmap_update_bits_eth(struct qca8 - u32 val = 0; - int ret; - -- ret = qca8k_read_eth(priv, reg, &val); -+ ret = qca8k_read_eth(priv, reg, &val, sizeof(val)); - if (ret) - return ret; - - val &= ~mask; - val |= write_val; - -- return qca8k_write_eth(priv, reg, val); -+ return qca8k_write_eth(priv, reg, &val, sizeof(val)); - } - - static int -@@ -398,7 +419,7 @@ qca8k_regmap_read(void *ctx, uint32_t re - u16 r1, r2, page; - int ret; - -- if (!qca8k_read_eth(priv, reg, val)) -+ if (!qca8k_read_eth(priv, reg, val, sizeof(val))) - return 0; - - qca8k_split_addr(reg, &r1, &r2, &page); -@@ -424,7 +445,7 @@ qca8k_regmap_write(void *ctx, uint32_t r - u16 r1, r2, page; - int ret; - -- if (!qca8k_write_eth(priv, reg, val)) -+ if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) - return 0; - - qca8k_split_addr(reg, &r1, &r2, &page); -@@ -959,21 +980,21 @@ qca8k_phy_eth_command(struct qca8k_priv - } - - /* Prealloc all the needed skb before the lock */ -- write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, -- &write_val, QCA8K_ETHERNET_PHY_PRIORITY); -+ write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val, -+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val)); - if (!write_skb) - return -ENOMEM; - -- clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, -- &clear_val, QCA8K_ETHERNET_PHY_PRIORITY); -+ clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, -+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); - if (!write_skb) { - ret = -ENOMEM; - goto err_clear_skb; - } - -- read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, -- &clear_val, QCA8K_ETHERNET_PHY_PRIORITY); -- if (!write_skb) { -+ read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val, -+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); -+ if (!read_skb) { - ret = -ENOMEM; - goto err_read_skb; - } diff --git a/target/linux/generic/backport-5.15/766-v5.18-16-net-dsa-qca8k-introduce-qca8k_bulk_read-write-functi.patch b/target/linux/generic/backport-5.15/766-v5.18-16-net-dsa-qca8k-introduce-qca8k_bulk_read-write-functi.patch deleted file mode 100644 index f26c6b91ac5998..00000000000000 --- a/target/linux/generic/backport-5.15/766-v5.18-16-net-dsa-qca8k-introduce-qca8k_bulk_read-write-functi.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 4f3701fc599820568ba4395070d34e4248800fc0 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Wed, 2 Feb 2022 01:03:35 +0100 -Subject: [PATCH 16/16] net: dsa: qca8k: introduce qca8k_bulk_read/write - function - -Introduce qca8k_bulk_read/write() function to use mgmt Ethernet way to -read/write packet in bulk. Make use of this new function in the fdb -function and while at it reduce the reg for fdb_read from 4 to 3 as the -max bit for the ARL(fdb) table is 83 bits. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 55 ++++++++++++++++++++++++++++++++--------- - 1 file changed, 43 insertions(+), 12 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -412,6 +412,43 @@ qca8k_regmap_update_bits_eth(struct qca8 - } - - static int -+qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ int i, count = len / sizeof(u32), ret; -+ -+ if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) -+ return 0; -+ -+ for (i = 0; i < count; i++) { -+ ret = regmap_read(priv->regmap, reg + (i * 4), val + i); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ int i, count = len / sizeof(u32), ret; -+ u32 tmp; -+ -+ if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) -+ return 0; -+ -+ for (i = 0; i < count; i++) { -+ tmp = val[i]; -+ -+ ret = regmap_write(priv->regmap, reg + (i * 4), tmp); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int - qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -@@ -546,17 +583,13 @@ qca8k_busy_wait(struct qca8k_priv *priv, - static int - qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) - { -- u32 reg[4], val; -- int i, ret; -+ u32 reg[3]; -+ int ret; - - /* load the ARL table into an array */ -- for (i = 0; i < 4; i++) { -- ret = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4), &val); -- if (ret < 0) -- return ret; -- -- reg[i] = val; -- } -+ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -+ if (ret) -+ return ret; - - /* vid - 83:72 */ - fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); -@@ -580,7 +613,6 @@ qca8k_fdb_write(struct qca8k_priv *priv, - u8 aging) - { - u32 reg[3] = { 0 }; -- int i; - - /* vid - 83:72 */ - reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); -@@ -597,8 +629,7 @@ qca8k_fdb_write(struct qca8k_priv *priv, - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); - - /* load the array into the ARL table */ -- for (i = 0; i < 3; i++) -- qca8k_write(priv, QCA8K_REG_ATU_DATA0 + (i * 4), reg[i]); -+ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); - } - - static int diff --git a/target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch b/target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch deleted file mode 100644 index 34607c223ce492..00000000000000 --- a/target/linux/generic/backport-5.15/767-v5.18-net-dsa-qca8k-check-correct-variable-in-qca8k_phy_et.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c3664d913dc115cab4a5fdb5634df4887048000e Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Fri, 4 Feb 2022 13:03:36 +0300 -Subject: [PATCH 1/1] net: dsa: qca8k: check correct variable in - qca8k_phy_eth_command() - -This is a copy and paste bug. It was supposed to check "clear_skb" -instead of "write_skb". - -Fixes: 2cd548566384 ("net: dsa: qca8k: add support for phy read/write with mgmt Ethernet") -Signed-off-by: Dan Carpenter -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1018,7 +1018,7 @@ qca8k_phy_eth_command(struct qca8k_priv - - clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, - QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); -- if (!write_skb) { -+ if (!clear_skb) { - ret = -ENOMEM; - goto err_clear_skb; - } diff --git a/target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch b/target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch deleted file mode 100644 index d8cf2663090622..00000000000000 --- a/target/linux/generic/backport-5.15/768-v5.18-net-dsa-qca8k-fix-noderef.cocci-warnings.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 4f5e483b8c7a644733db941a1ae00173baa7b463 Mon Sep 17 00:00:00 2001 -From: kernel test robot -Date: Thu, 10 Feb 2022 06:13:04 +0800 -Subject: [PATCH 1/1] net: dsa: qca8k: fix noderef.cocci warnings - -drivers/net/dsa/qca8k.c:422:37-43: ERROR: application of sizeof to pointer - - sizeof when applied to a pointer typed expression gives the size of - the pointer - -Generated by: scripts/coccinelle/misc/noderef.cocci - -Fixes: 90386223f44e ("net: dsa: qca8k: add support for larger read/write size with mgmt Ethernet") -CC: Ansuel Smith -Reported-by: kernel test robot -Signed-off-by: kernel test robot -Reviewed-by: Florian Fainelli -Link: https://lore.kernel.org/r/20220209221304.GA17529@d2214a582157 -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca8k.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -456,7 +456,7 @@ qca8k_regmap_read(void *ctx, uint32_t re - u16 r1, r2, page; - int ret; - -- if (!qca8k_read_eth(priv, reg, val, sizeof(val))) -+ if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) - return 0; - - qca8k_split_addr(reg, &r1, &r2, &page); diff --git a/target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch b/target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch deleted file mode 100644 index 57df4c126e4937..00000000000000 --- a/target/linux/generic/backport-5.15/769-v5.19-01-net-dsa-qca8k-drop-MTU-tracking-from-qca8k_priv.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 69fd055957a02309ffdc23d887a01988b6e5bab1 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sat, 16 Apr 2022 01:30:12 +0200 -Subject: [PATCH 1/6] net: dsa: qca8k: drop MTU tracking from qca8k_priv - -DSA set the CPU port based on the largest MTU of all the slave ports. -Based on this we can drop the MTU array from qca8k_priv and set the -port_change_mtu logic on DSA changing MTU of the CPU port as the switch -have a global MTU settingfor each port. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 26 +++++++++----------------- - drivers/net/dsa/qca8k.h | 1 - - 2 files changed, 9 insertions(+), 18 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1803,16 +1803,6 @@ qca8k_setup(struct dsa_switch *ds) - QCA8K_PORT_HOL_CTRL1_WRED_EN, - mask); - } -- -- /* Set initial MTU for every port. -- * We have only have a general MTU setting. So track -- * every port and set the max across all port. -- * Set per port MTU to 1500 as the MTU change function -- * will add the overhead and if its set to 1518 then it -- * will apply the overhead again and we will end up with -- * MTU of 1536 instead of 1518 -- */ -- priv->port_mtu[i] = ETH_DATA_LEN; - } - - /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ -@@ -2525,13 +2515,16 @@ static int - qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) - { - struct qca8k_priv *priv = ds->priv; -- int ret, i, mtu = 0; -- -- priv->port_mtu[port] = new_mtu; -+ int ret; - -- for (i = 0; i < QCA8K_NUM_PORTS; i++) -- if (priv->port_mtu[i] > mtu) -- mtu = priv->port_mtu[i]; -+ /* We have only have a general MTU setting. -+ * DSA always set the CPU port's MTU to the largest MTU of the slave -+ * ports. -+ * Setting MTU just for the CPU port is sufficient to correctly set a -+ * value for every port. -+ */ -+ if (!dsa_is_cpu_port(ds, port)) -+ return 0; - - /* To change the MAX_FRAME_SIZE the cpu ports must be off or - * the switch panics. -@@ -2545,7 +2538,7 @@ qca8k_port_change_mtu(struct dsa_switch - qca8k_port_set_status(priv, 6, 0); - - /* Include L2 header / FCS length */ -- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN); -+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); - - if (priv->port_sts[0].enabled) - qca8k_port_set_status(priv, 0, 1); ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -392,7 +392,6 @@ struct qca8k_priv { - struct device *dev; - struct dsa_switch_ops ops; - struct gpio_desc *reset_gpio; -- unsigned int port_mtu[QCA8K_NUM_PORTS]; - struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ - struct qca8k_mgmt_eth_data mgmt_eth_data; - struct qca8k_mib_eth_data mib_eth_data; diff --git a/target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch b/target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch deleted file mode 100644 index 3cacd7e4fdb7b0..00000000000000 --- a/target/linux/generic/backport-5.15/769-v5.19-02-net-dsa-qca8k-drop-port_sts-from-qca8k_priv.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 2b8fd87af7f156942971789abac8ee2bb60c03bc Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sat, 16 Apr 2022 01:30:13 +0200 -Subject: [PATCH 2/6] net: dsa: qca8k: drop port_sts from qca8k_priv - -Port_sts is a thing of the past for this driver. It was something -present on the initial implementation of this driver and parts of the -original struct were dropped over time. Using an array of int to store if -a port is enabled or not to handle PM operation seems overkill. Switch -and use a simple u8 to store the port status where each bit correspond -to a port. (bit is set port is enabled, bit is not set, port is disabled) -Also add some comments to better describe why we need to track port -status. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 15 +++++++++------ - drivers/net/dsa/qca8k.h | 9 ++++----- - 2 files changed, 13 insertions(+), 11 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -2494,7 +2494,7 @@ qca8k_port_enable(struct dsa_switch *ds, - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - - qca8k_port_set_status(priv, port, 1); -- priv->port_sts[port].enabled = 1; -+ priv->port_enabled_map |= BIT(port); - - if (dsa_is_user_port(ds, port)) - phy_support_asym_pause(phy); -@@ -2508,7 +2508,7 @@ qca8k_port_disable(struct dsa_switch *ds - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; - - qca8k_port_set_status(priv, port, 0); -- priv->port_sts[port].enabled = 0; -+ priv->port_enabled_map &= ~BIT(port); - } - - static int -@@ -2531,19 +2531,19 @@ qca8k_port_change_mtu(struct dsa_switch - * Turn off both cpu ports before applying the new value to prevent - * this. - */ -- if (priv->port_sts[0].enabled) -+ if (priv->port_enabled_map & BIT(0)) - qca8k_port_set_status(priv, 0, 0); - -- if (priv->port_sts[6].enabled) -+ if (priv->port_enabled_map & BIT(6)) - qca8k_port_set_status(priv, 6, 0); - - /* Include L2 header / FCS length */ - ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); - -- if (priv->port_sts[0].enabled) -+ if (priv->port_enabled_map & BIT(0)) - qca8k_port_set_status(priv, 0, 1); - -- if (priv->port_sts[6].enabled) -+ if (priv->port_enabled_map & BIT(6)) - qca8k_port_set_status(priv, 6, 1); - - return ret; -@@ -3199,13 +3199,16 @@ static void qca8k_sw_shutdown(struct mdi - static void - qca8k_set_pm(struct qca8k_priv *priv, int enable) - { -- int i; -+ int port; - -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- if (!priv->port_sts[i].enabled) -+ for (port = 0; port < QCA8K_NUM_PORTS; port++) { -+ /* Do not enable on resume if the port was -+ * disabled before. -+ */ -+ if (!(priv->port_enabled_map & BIT(port))) - continue; - -- qca8k_port_set_status(priv, i, enable); -+ qca8k_port_set_status(priv, port, enable); - } - } - ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -324,10 +324,6 @@ enum qca8k_mid_cmd { - QCA8K_MIB_CAST = 3, - }; - --struct ar8xxx_port_status { -- int enabled; --}; -- - struct qca8k_match_data { - u8 id; - bool reduced_package; -@@ -382,11 +378,14 @@ struct qca8k_priv { - u8 mirror_rx; - u8 mirror_tx; - u8 lag_hash_mode; -+ /* Each bit correspond to a port. This switch can support a max of 7 port. -+ * Bit 1: port enabled. Bit 0: port disabled. -+ */ -+ u8 port_enabled_map; - bool legacy_phy_port_mapping; - struct qca8k_ports_config ports_config; - struct regmap *regmap; - struct mii_bus *bus; -- struct ar8xxx_port_status port_sts[QCA8K_NUM_PORTS]; - struct dsa_switch *ds; - struct mutex reg_mutex; - struct device *dev; diff --git a/target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch b/target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch deleted file mode 100644 index 12c3221077ca7c..00000000000000 --- a/target/linux/generic/backport-5.15/769-v5.19-03-net-dsa-qca8k-rework-and-simplify-mdiobus-logic.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 8255212e4130bd2dc1463286a3dddb74797bbdc1 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sat, 16 Apr 2022 01:30:14 +0200 -Subject: [PATCH 3/6] net: dsa: qca8k: rework and simplify mdiobus logic - -In an attempt to reduce qca8k_priv space, rework and simplify mdiobus -logic. -We now declare a mdiobus instead of relying on DSA phy_read/write even -if a mdio node is not present. This is all to make the qca8k ops static -and not switch specific. With a legacy implementation where port doesn't -have a phy map declared in the dts with a mdio node, we declare a -'qca8k-legacy' mdiobus. The conversion logic is used as legacy read and -write ops are used instead of the internal one. -Also drop the legacy_phy_port_mapping as we now declare mdiobus with ops -that already address the workaround. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 95 +++++++++++++---------------------------- - drivers/net/dsa/qca8k.h | 1 - - 2 files changed, 29 insertions(+), 67 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1291,83 +1291,63 @@ qca8k_internal_mdio_read(struct mii_bus - } - - static int --qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data) -+qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) - { -- struct qca8k_priv *priv = ds->priv; -- int ret; -+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; - -- /* Check if the legacy mapping should be used and the -- * port is not correctly mapped to the right PHY in the -- * devicetree -- */ -- if (priv->legacy_phy_port_mapping) -- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; -- -- /* Use mdio Ethernet when available, fallback to legacy one on error */ -- ret = qca8k_phy_eth_command(priv, false, port, regnum, 0); -- if (!ret) -- return ret; -- -- return qca8k_mdio_write(priv, port, regnum, data); -+ return qca8k_internal_mdio_write(slave_bus, port, regnum, data); - } - - static int --qca8k_phy_read(struct dsa_switch *ds, int port, int regnum) -+qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) - { -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- /* Check if the legacy mapping should be used and the -- * port is not correctly mapped to the right PHY in the -- * devicetree -- */ -- if (priv->legacy_phy_port_mapping) -- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; -- -- /* Use mdio Ethernet when available, fallback to legacy one on error */ -- ret = qca8k_phy_eth_command(priv, true, port, regnum, 0); -- if (ret >= 0) -- return ret; -- -- ret = qca8k_mdio_read(priv, port, regnum); -- -- if (ret < 0) -- return 0xffff; -+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; - -- return ret; -+ return qca8k_internal_mdio_read(slave_bus, port, regnum); - } - - static int --qca8k_mdio_register(struct qca8k_priv *priv, struct device_node *mdio) -+qca8k_mdio_register(struct qca8k_priv *priv) - { - struct dsa_switch *ds = priv->ds; -+ struct device_node *mdio; - struct mii_bus *bus; - - bus = devm_mdiobus_alloc(ds->dev); -- - if (!bus) - return -ENOMEM; - - bus->priv = (void *)priv; -- bus->name = "qca8k slave mii"; -- bus->read = qca8k_internal_mdio_read; -- bus->write = qca8k_internal_mdio_write; -- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d", -- ds->index); -- - bus->parent = ds->dev; - bus->phy_mask = ~ds->phys_mii_mask; -- - ds->slave_mii_bus = bus; - -- return devm_of_mdiobus_register(priv->dev, bus, mdio); -+ /* Check if the devicetree declare the port:phy mapping */ -+ mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); -+ if (of_device_is_available(mdio)) { -+ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d", ds->index); -+ bus->name = "qca8k slave mii"; -+ bus->read = qca8k_internal_mdio_read; -+ bus->write = qca8k_internal_mdio_write; -+ return devm_of_mdiobus_register(priv->dev, bus, mdio); -+ } -+ -+ /* If a mapping can't be found the legacy mapping is used, -+ * using the qca8k_port_to_phy function -+ */ -+ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", -+ ds->dst->index, ds->index); -+ bus->name = "qca8k-legacy slave mii"; -+ bus->read = qca8k_legacy_mdio_read; -+ bus->write = qca8k_legacy_mdio_write; -+ return devm_mdiobus_register(priv->dev, bus); - } - - static int - qca8k_setup_mdio_bus(struct qca8k_priv *priv) - { - u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; -- struct device_node *ports, *port, *mdio; -+ struct device_node *ports, *port; - phy_interface_t mode; - int err; - -@@ -1429,24 +1409,7 @@ qca8k_setup_mdio_bus(struct qca8k_priv * - QCA8K_MDIO_MASTER_EN); - } - -- /* Check if the devicetree declare the port:phy mapping */ -- mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); -- if (of_device_is_available(mdio)) { -- err = qca8k_mdio_register(priv, mdio); -- if (err) -- of_node_put(mdio); -- -- return err; -- } -- -- /* If a mapping can't be found the legacy mapping is used, -- * using the qca8k_port_to_phy function -- */ -- priv->legacy_phy_port_mapping = true; -- priv->ops.phy_read = qca8k_phy_read; -- priv->ops.phy_write = qca8k_phy_write; -- -- return 0; -+ return qca8k_mdio_register(priv); - } - - static int ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -382,7 +382,6 @@ struct qca8k_priv { - * Bit 1: port enabled. Bit 0: port disabled. - */ - u8 port_enabled_map; -- bool legacy_phy_port_mapping; - struct qca8k_ports_config ports_config; - struct regmap *regmap; - struct mii_bus *bus; diff --git a/target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch b/target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch deleted file mode 100644 index 8641000abbc642..00000000000000 --- a/target/linux/generic/backport-5.15/769-v5.19-04-net-dsa-qca8k-drop-dsa_switch_ops-from-qca8k_priv.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 2349b83a2486c55b9dd225326f0172a84a43c5e4 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sat, 16 Apr 2022 01:30:15 +0200 -Subject: [PATCH 4/6] net: dsa: qca8k: drop dsa_switch_ops from qca8k_priv - -Now that dsa_switch_ops is not switch specific anymore, we can drop it -from qca8k_priv and use the static ops directly for the dsa_switch -pointer. - -Signed-off-by: Ansuel Smith -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 3 +-- - drivers/net/dsa/qca8k.h | 1 - - 2 files changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -3121,8 +3121,7 @@ qca8k_sw_probe(struct mdio_device *mdiod - priv->ds->dev = &mdiodev->dev; - priv->ds->num_ports = QCA8K_NUM_PORTS; - priv->ds->priv = priv; -- priv->ops = qca8k_switch_ops; -- priv->ds->ops = &priv->ops; -+ priv->ds->ops = &qca8k_switch_ops; - mutex_init(&priv->reg_mutex); - dev_set_drvdata(&mdiodev->dev, priv); - ---- a/drivers/net/dsa/qca8k.h -+++ b/drivers/net/dsa/qca8k.h -@@ -388,7 +388,6 @@ struct qca8k_priv { - struct dsa_switch *ds; - struct mutex reg_mutex; - struct device *dev; -- struct dsa_switch_ops ops; - struct gpio_desc *reset_gpio; - struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ - struct qca8k_mgmt_eth_data mgmt_eth_data; diff --git a/target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch b/target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch deleted file mode 100644 index b14b22091bc103..00000000000000 --- a/target/linux/generic/backport-5.15/769-v5.19-05-net-dsa-qca8k-correctly-handle-mdio-read-error.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6cfc03b602200c5cbbd8d906fd905547814e83df Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sat, 16 Apr 2022 01:30:16 +0200 -Subject: [PATCH 5/6] net: dsa: qca8k: correctly handle mdio read error - -Restore original way to handle mdio read error by returning 0xffff. -This was wrongly changed when the internal_mdio_read was introduced, -now that both legacy and internal use the same function, make sure that -they behave the same way. - -Fixes: ce062a0adbfe ("net: dsa: qca8k: fix kernel panic with legacy mdio mapping") -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1287,7 +1287,12 @@ qca8k_internal_mdio_read(struct mii_bus - if (ret >= 0) - return ret; - -- return qca8k_mdio_read(priv, phy, regnum); -+ ret = qca8k_mdio_read(priv, phy, regnum); -+ -+ if (ret < 0) -+ return 0xffff; -+ -+ return ret; - } - - static int diff --git a/target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch b/target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch deleted file mode 100644 index 094686f11bef54..00000000000000 --- a/target/linux/generic/backport-5.15/769-v5.19-06-net-dsa-qca8k-unify-bus-id-naming-with-legacy-and-OF.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 8d1af50842bf2774f4edc57054206e909117469b Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Sat, 16 Apr 2022 01:30:17 +0200 -Subject: [PATCH 6/6] net: dsa: qca8k: unify bus id naming with legacy and OF - mdio bus - -Add support for multiple switch with OF mdio bus declaration. -Unify the bus id naming and use the same logic for both legacy and OF -mdio bus. - -Signed-off-by: Ansuel Smith -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca8k.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/net/dsa/qca8k.c -+++ b/drivers/net/dsa/qca8k.c -@@ -1323,6 +1323,8 @@ qca8k_mdio_register(struct qca8k_priv *p - return -ENOMEM; - - bus->priv = (void *)priv; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", -+ ds->dst->index, ds->index); - bus->parent = ds->dev; - bus->phy_mask = ~ds->phys_mii_mask; - ds->slave_mii_bus = bus; -@@ -1330,7 +1332,6 @@ qca8k_mdio_register(struct qca8k_priv *p - /* Check if the devicetree declare the port:phy mapping */ - mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); - if (of_device_is_available(mdio)) { -- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d", ds->index); - bus->name = "qca8k slave mii"; - bus->read = qca8k_internal_mdio_read; - bus->write = qca8k_internal_mdio_write; -@@ -1340,8 +1341,6 @@ qca8k_mdio_register(struct qca8k_priv *p - /* If a mapping can't be found the legacy mapping is used, - * using the qca8k_port_to_phy function - */ -- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", -- ds->dst->index, ds->index); - bus->name = "qca8k-legacy slave mii"; - bus->read = qca8k_legacy_mdio_read; - bus->write = qca8k_legacy_mdio_write; diff --git a/target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch b/target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch deleted file mode 100644 index 1534113f1df603..00000000000000 --- a/target/linux/generic/backport-5.15/770-v6.0-net-dsa-qca8k-move-driver-to-qca-dir.patch +++ /dev/null @@ -1,7389 +0,0 @@ -From 4bbaf764e1e1786eb937fdb62172f656f512e116 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 13 Jul 2022 22:53:50 +0200 -Subject: [PATCH 1/1] net: dsa: qca8k: move driver to qca dir - -Move qca8k driver to qca dir in preparation for code split and -introduction of ipq4019 switch based on qca8k. - -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/Kconfig | 8 -------- - drivers/net/dsa/Makefile | 1 - - drivers/net/dsa/qca/Kconfig | 8 ++++++++ - drivers/net/dsa/qca/Makefile | 1 + - drivers/net/dsa/{ => qca}/qca8k.c | 0 - drivers/net/dsa/{ => qca}/qca8k.h | 0 - 6 files changed, 9 insertions(+), 9 deletions(-) - rename drivers/net/dsa/{ => qca}/qca8k.c (100%) - rename drivers/net/dsa/{ => qca}/qca8k.h (100%) - ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -60,14 +60,6 @@ source "drivers/net/dsa/sja1105/Kconfig" - - source "drivers/net/dsa/xrs700x/Kconfig" - --config NET_DSA_QCA8K -- tristate "Qualcomm Atheros QCA8K Ethernet switch family support" -- select NET_DSA_TAG_QCA -- select REGMAP -- help -- This enables support for the Qualcomm Atheros QCA8K Ethernet -- switch chips. -- - config NET_DSA_REALTEK_SMI - tristate "Realtek SMI Ethernet switch family support" - select NET_DSA_TAG_RTL4_A ---- a/drivers/net/dsa/Makefile -+++ b/drivers/net/dsa/Makefile -@@ -8,7 +8,6 @@ endif - obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o - obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o - obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o --obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o - obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o - realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o - obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o ---- a/drivers/net/dsa/qca/Kconfig -+++ b/drivers/net/dsa/qca/Kconfig -@@ -7,3 +7,11 @@ config NET_DSA_AR9331 - help - This enables support for the Qualcomm Atheros AR9331 built-in Ethernet - switch. -+ -+config NET_DSA_QCA8K -+ tristate "Qualcomm Atheros QCA8K Ethernet switch family support" -+ select NET_DSA_TAG_QCA -+ select REGMAP -+ help -+ This enables support for the Qualcomm Atheros QCA8K Ethernet -+ switch chips. ---- a/drivers/net/dsa/qca/Makefile -+++ b/drivers/net/dsa/qca/Makefile -@@ -1,2 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0-only - obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o -+obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o ---- /dev/null -+++ b/drivers/net/dsa/qca/qca8k.c -@@ -0,0 +1,3243 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2009 Felix Fietkau -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2016 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "qca8k.h" -+ -+#define MIB_DESC(_s, _o, _n) \ -+ { \ -+ .size = (_s), \ -+ .offset = (_o), \ -+ .name = (_n), \ -+ } -+ -+static const struct qca8k_mib_desc ar8327_mib[] = { -+ MIB_DESC(1, 0x00, "RxBroad"), -+ MIB_DESC(1, 0x04, "RxPause"), -+ MIB_DESC(1, 0x08, "RxMulti"), -+ MIB_DESC(1, 0x0c, "RxFcsErr"), -+ MIB_DESC(1, 0x10, "RxAlignErr"), -+ MIB_DESC(1, 0x14, "RxRunt"), -+ MIB_DESC(1, 0x18, "RxFragment"), -+ MIB_DESC(1, 0x1c, "Rx64Byte"), -+ MIB_DESC(1, 0x20, "Rx128Byte"), -+ MIB_DESC(1, 0x24, "Rx256Byte"), -+ MIB_DESC(1, 0x28, "Rx512Byte"), -+ MIB_DESC(1, 0x2c, "Rx1024Byte"), -+ MIB_DESC(1, 0x30, "Rx1518Byte"), -+ MIB_DESC(1, 0x34, "RxMaxByte"), -+ MIB_DESC(1, 0x38, "RxTooLong"), -+ MIB_DESC(2, 0x3c, "RxGoodByte"), -+ MIB_DESC(2, 0x44, "RxBadByte"), -+ MIB_DESC(1, 0x4c, "RxOverFlow"), -+ MIB_DESC(1, 0x50, "Filtered"), -+ MIB_DESC(1, 0x54, "TxBroad"), -+ MIB_DESC(1, 0x58, "TxPause"), -+ MIB_DESC(1, 0x5c, "TxMulti"), -+ MIB_DESC(1, 0x60, "TxUnderRun"), -+ MIB_DESC(1, 0x64, "Tx64Byte"), -+ MIB_DESC(1, 0x68, "Tx128Byte"), -+ MIB_DESC(1, 0x6c, "Tx256Byte"), -+ MIB_DESC(1, 0x70, "Tx512Byte"), -+ MIB_DESC(1, 0x74, "Tx1024Byte"), -+ MIB_DESC(1, 0x78, "Tx1518Byte"), -+ MIB_DESC(1, 0x7c, "TxMaxByte"), -+ MIB_DESC(1, 0x80, "TxOverSize"), -+ MIB_DESC(2, 0x84, "TxByte"), -+ MIB_DESC(1, 0x8c, "TxCollision"), -+ MIB_DESC(1, 0x90, "TxAbortCol"), -+ MIB_DESC(1, 0x94, "TxMultiCol"), -+ MIB_DESC(1, 0x98, "TxSingleCol"), -+ MIB_DESC(1, 0x9c, "TxExcDefer"), -+ MIB_DESC(1, 0xa0, "TxDefer"), -+ MIB_DESC(1, 0xa4, "TxLateCol"), -+ MIB_DESC(1, 0xa8, "RXUnicast"), -+ MIB_DESC(1, 0xac, "TXUnicast"), -+}; -+ -+static void -+qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) -+{ -+ regaddr >>= 1; -+ *r1 = regaddr & 0x1e; -+ -+ regaddr >>= 5; -+ *r2 = regaddr & 0x7; -+ -+ regaddr >>= 3; -+ *page = regaddr & 0x3ff; -+} -+ -+static int -+qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo) -+{ -+ u16 *cached_lo = &priv->mdio_cache.lo; -+ struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ if (lo == *cached_lo) -+ return 0; -+ -+ ret = bus->write(bus, phy_id, regnum, lo); -+ if (ret < 0) -+ dev_err_ratelimited(&bus->dev, -+ "failed to write qca8k 32bit lo register\n"); -+ -+ *cached_lo = lo; -+ return 0; -+} -+ -+static int -+qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi) -+{ -+ u16 *cached_hi = &priv->mdio_cache.hi; -+ struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ if (hi == *cached_hi) -+ return 0; -+ -+ ret = bus->write(bus, phy_id, regnum, hi); -+ if (ret < 0) -+ dev_err_ratelimited(&bus->dev, -+ "failed to write qca8k 32bit hi register\n"); -+ -+ *cached_hi = hi; -+ return 0; -+} -+ -+static int -+qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) -+{ -+ int ret; -+ -+ ret = bus->read(bus, phy_id, regnum); -+ if (ret >= 0) { -+ *val = ret; -+ ret = bus->read(bus, phy_id, regnum + 1); -+ *val |= ret << 16; -+ } -+ -+ if (ret < 0) { -+ dev_err_ratelimited(&bus->dev, -+ "failed to read qca8k 32bit register\n"); -+ *val = 0; -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void -+qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val) -+{ -+ u16 lo, hi; -+ int ret; -+ -+ lo = val & 0xffff; -+ hi = (u16)(val >> 16); -+ -+ ret = qca8k_set_lo(priv, phy_id, regnum, lo); -+ if (ret >= 0) -+ ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi); -+} -+ -+static int -+qca8k_set_page(struct qca8k_priv *priv, u16 page) -+{ -+ u16 *cached_page = &priv->mdio_cache.page; -+ struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ if (page == *cached_page) -+ return 0; -+ -+ ret = bus->write(bus, 0x18, 0, page); -+ if (ret < 0) { -+ dev_err_ratelimited(&bus->dev, -+ "failed to set qca8k page\n"); -+ return ret; -+ } -+ -+ *cached_page = page; -+ usleep_range(1000, 2000); -+ return 0; -+} -+ -+static int -+qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) -+{ -+ return regmap_read(priv->regmap, reg, val); -+} -+ -+static int -+qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) -+{ -+ return regmap_write(priv->regmap, reg, val); -+} -+ -+static int -+qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) -+{ -+ return regmap_update_bits(priv->regmap, reg, mask, write_val); -+} -+ -+static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) -+{ -+ struct qca8k_mgmt_eth_data *mgmt_eth_data; -+ struct qca8k_priv *priv = ds->priv; -+ struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ u8 len, cmd; -+ -+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); -+ mgmt_eth_data = &priv->mgmt_eth_data; -+ -+ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); -+ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); -+ -+ /* Make sure the seq match the requested packet */ -+ if (mgmt_ethhdr->seq == mgmt_eth_data->seq) -+ mgmt_eth_data->ack = true; -+ -+ if (cmd == MDIO_READ) { -+ mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; -+ -+ /* Get the rest of the 12 byte of data. -+ * The read/write function will extract the requested data. -+ */ -+ if (len > QCA_HDR_MGMT_DATA1_LEN) -+ memcpy(mgmt_eth_data->data + 1, skb->data, -+ QCA_HDR_MGMT_DATA2_LEN); -+ } -+ -+ complete(&mgmt_eth_data->rw_done); -+} -+ -+static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val, -+ int priority, unsigned int len) -+{ -+ struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ unsigned int real_len; -+ struct sk_buff *skb; -+ u32 *data2; -+ u16 hdr; -+ -+ skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); -+ if (!skb) -+ return NULL; -+ -+ /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte -+ * Actually for some reason the steps are: -+ * 0: nothing -+ * 1-4: first 4 byte -+ * 5-6: first 12 byte -+ * 7-15: all 16 byte -+ */ -+ if (len == 16) -+ real_len = 15; -+ else -+ real_len = len; -+ -+ skb_reset_mac_header(skb); -+ skb_set_network_header(skb, skb->len); -+ -+ mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); -+ -+ hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); -+ hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority); -+ hdr |= QCA_HDR_XMIT_FROM_CPU; -+ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); -+ hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); -+ -+ mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); -+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); -+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); -+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, -+ QCA_HDR_MGMT_CHECK_CODE_VAL); -+ -+ if (cmd == MDIO_WRITE) -+ mgmt_ethhdr->mdio_data = *val; -+ -+ mgmt_ethhdr->hdr = htons(hdr); -+ -+ data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); -+ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) -+ memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); -+ -+ return skb; -+} -+ -+static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) -+{ -+ struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ -+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; -+ mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); -+} -+ -+static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; -+ struct sk_buff *skb; -+ bool ack; -+ int ret; -+ -+ skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL, -+ QCA8K_ETHERNET_MDIO_PRIORITY, len); -+ if (!skb) -+ return -ENOMEM; -+ -+ mutex_lock(&mgmt_eth_data->mutex); -+ -+ /* Check mgmt_master if is operational */ -+ if (!priv->mgmt_master) { -+ kfree_skb(skb); -+ mutex_unlock(&mgmt_eth_data->mutex); -+ return -EINVAL; -+ } -+ -+ skb->dev = priv->mgmt_master; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the mdio pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); -+ -+ *val = mgmt_eth_data->data[0]; -+ if (len > QCA_HDR_MGMT_DATA1_LEN) -+ memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN); -+ -+ ack = mgmt_eth_data->ack; -+ -+ mutex_unlock(&mgmt_eth_data->mutex); -+ -+ if (ret <= 0) -+ return -ETIMEDOUT; -+ -+ if (!ack) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; -+ struct sk_buff *skb; -+ bool ack; -+ int ret; -+ -+ skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val, -+ QCA8K_ETHERNET_MDIO_PRIORITY, len); -+ if (!skb) -+ return -ENOMEM; -+ -+ mutex_lock(&mgmt_eth_data->mutex); -+ -+ /* Check mgmt_master if is operational */ -+ if (!priv->mgmt_master) { -+ kfree_skb(skb); -+ mutex_unlock(&mgmt_eth_data->mutex); -+ return -EINVAL; -+ } -+ -+ skb->dev = priv->mgmt_master; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the mdio pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); -+ -+ ack = mgmt_eth_data->ack; -+ -+ mutex_unlock(&mgmt_eth_data->mutex); -+ -+ if (ret <= 0) -+ return -ETIMEDOUT; -+ -+ if (!ack) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int -+qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) -+{ -+ u32 val = 0; -+ int ret; -+ -+ ret = qca8k_read_eth(priv, reg, &val, sizeof(val)); -+ if (ret) -+ return ret; -+ -+ val &= ~mask; -+ val |= write_val; -+ -+ return qca8k_write_eth(priv, reg, &val, sizeof(val)); -+} -+ -+static int -+qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ int i, count = len / sizeof(u32), ret; -+ -+ if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) -+ return 0; -+ -+ for (i = 0; i < count; i++) { -+ ret = regmap_read(priv->regmap, reg + (i * 4), val + i); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ int i, count = len / sizeof(u32), ret; -+ u32 tmp; -+ -+ if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) -+ return 0; -+ -+ for (i = 0; i < count; i++) { -+ tmp = val[i]; -+ -+ ret = regmap_write(priv->regmap, reg + (i * 4), tmp); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -+ struct mii_bus *bus = priv->bus; -+ u16 r1, r2, page; -+ int ret; -+ -+ if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) -+ return 0; -+ -+ qca8k_split_addr(reg, &r1, &r2, &page); -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = qca8k_set_page(priv, page); -+ if (ret < 0) -+ goto exit; -+ -+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val); -+ -+exit: -+ mutex_unlock(&bus->mdio_lock); -+ return ret; -+} -+ -+static int -+qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -+ struct mii_bus *bus = priv->bus; -+ u16 r1, r2, page; -+ int ret; -+ -+ if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) -+ return 0; -+ -+ qca8k_split_addr(reg, &r1, &r2, &page); -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = qca8k_set_page(priv, page); -+ if (ret < 0) -+ goto exit; -+ -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ -+exit: -+ mutex_unlock(&bus->mdio_lock); -+ return ret; -+} -+ -+static int -+qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -+ struct mii_bus *bus = priv->bus; -+ u16 r1, r2, page; -+ u32 val; -+ int ret; -+ -+ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) -+ return 0; -+ -+ qca8k_split_addr(reg, &r1, &r2, &page); -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = qca8k_set_page(priv, page); -+ if (ret < 0) -+ goto exit; -+ -+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); -+ if (ret < 0) -+ goto exit; -+ -+ val &= ~mask; -+ val |= write_val; -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ -+exit: -+ mutex_unlock(&bus->mdio_lock); -+ -+ return ret; -+} -+ -+static const struct regmap_range qca8k_readable_ranges[] = { -+ regmap_reg_range(0x0000, 0x00e4), /* Global control */ -+ regmap_reg_range(0x0100, 0x0168), /* EEE control */ -+ regmap_reg_range(0x0200, 0x0270), /* Parser control */ -+ regmap_reg_range(0x0400, 0x0454), /* ACL */ -+ regmap_reg_range(0x0600, 0x0718), /* Lookup */ -+ regmap_reg_range(0x0800, 0x0b70), /* QM */ -+ regmap_reg_range(0x0c00, 0x0c80), /* PKT */ -+ regmap_reg_range(0x0e00, 0x0e98), /* L3 */ -+ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ -+ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ -+ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ -+ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ -+ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ -+ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ -+ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ -+ -+}; -+ -+static const struct regmap_access_table qca8k_readable_table = { -+ .yes_ranges = qca8k_readable_ranges, -+ .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), -+}; -+ -+static struct regmap_config qca8k_regmap_config = { -+ .reg_bits = 16, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .max_register = 0x16ac, /* end MIB - Port6 range */ -+ .reg_read = qca8k_regmap_read, -+ .reg_write = qca8k_regmap_write, -+ .reg_update_bits = qca8k_regmap_update_bits, -+ .rd_table = &qca8k_readable_table, -+ .disable_locking = true, /* Locking is handled by qca8k read/write */ -+ .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ -+}; -+ -+static int -+qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) -+{ -+ u32 val; -+ -+ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, -+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); -+} -+ -+static int -+qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) -+{ -+ u32 reg[3]; -+ int ret; -+ -+ /* load the ARL table into an array */ -+ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -+ if (ret) -+ return ret; -+ -+ /* vid - 83:72 */ -+ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); -+ /* aging - 67:64 */ -+ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); -+ /* portmask - 54:48 */ -+ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); -+ /* mac - 47:0 */ -+ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); -+ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); -+ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); -+ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); -+ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); -+ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); -+ -+ return 0; -+} -+ -+static void -+qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, -+ u8 aging) -+{ -+ u32 reg[3] = { 0 }; -+ -+ /* vid - 83:72 */ -+ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); -+ /* aging - 67:64 */ -+ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); -+ /* portmask - 54:48 */ -+ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); -+ /* mac - 47:0 */ -+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); -+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); -+ -+ /* load the array into the ARL table */ -+ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -+} -+ -+static int -+qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) -+{ -+ u32 reg; -+ int ret; -+ -+ /* Set the command and FDB index */ -+ reg = QCA8K_ATU_FUNC_BUSY; -+ reg |= cmd; -+ if (port >= 0) { -+ reg |= QCA8K_ATU_FUNC_PORT_EN; -+ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); -+ } -+ -+ /* Write the function register triggering the table access */ -+ ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); -+ if (ret) -+ return ret; -+ -+ /* wait for completion */ -+ ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); -+ if (ret) -+ return ret; -+ -+ /* Check for table full violation when adding an entry */ -+ if (cmd == QCA8K_FDB_LOAD) { -+ ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); -+ if (ret < 0) -+ return ret; -+ if (reg & QCA8K_ATU_FUNC_FULL) -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) -+{ -+ int ret; -+ -+ qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); -+ if (ret < 0) -+ return ret; -+ -+ return qca8k_fdb_read(priv, fdb); -+} -+ -+static int -+qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, -+ u16 vid, u8 aging) -+{ -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_write(priv, vid, port_mask, mac, aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int -+qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) -+{ -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_write(priv, vid, port_mask, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static void -+qca8k_fdb_flush(struct qca8k_priv *priv) -+{ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); -+ mutex_unlock(&priv->reg_mutex); -+} -+ -+static int -+qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, -+ const u8 *mac, u16 vid) -+{ -+ struct qca8k_fdb fdb = { 0 }; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ qca8k_fdb_write(priv, vid, 0, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -+ if (ret < 0) -+ goto exit; -+ -+ ret = qca8k_fdb_read(priv, &fdb); -+ if (ret < 0) -+ goto exit; -+ -+ /* Rule exist. Delete first */ -+ if (!fdb.aging) { -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ if (ret) -+ goto exit; -+ } -+ -+ /* Add port to fdb portmask */ -+ fdb.port_mask |= port_mask; -+ -+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static int -+qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, -+ const u8 *mac, u16 vid) -+{ -+ struct qca8k_fdb fdb = { 0 }; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ qca8k_fdb_write(priv, vid, 0, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -+ if (ret < 0) -+ goto exit; -+ -+ /* Rule doesn't exist. Why delete? */ -+ if (!fdb.aging) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ if (ret) -+ goto exit; -+ -+ /* Only port in the rule is this port. Don't re insert */ -+ if (fdb.port_mask == port_mask) -+ goto exit; -+ -+ /* Remove port from port mask */ -+ fdb.port_mask &= ~port_mask; -+ -+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static int -+qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) -+{ -+ u32 reg; -+ int ret; -+ -+ /* Set the command and VLAN index */ -+ reg = QCA8K_VTU_FUNC1_BUSY; -+ reg |= cmd; -+ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); -+ -+ /* Write the function register triggering the table access */ -+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); -+ if (ret) -+ return ret; -+ -+ /* wait for completion */ -+ ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); -+ if (ret) -+ return ret; -+ -+ /* Check for table full violation when adding an entry */ -+ if (cmd == QCA8K_VLAN_LOAD) { -+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); -+ if (ret < 0) -+ return ret; -+ if (reg & QCA8K_VTU_FUNC1_FULL) -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) -+{ -+ u32 reg; -+ int ret; -+ -+ /* -+ We do the right thing with VLAN 0 and treat it as untagged while -+ preserving the tag on egress. -+ */ -+ if (vid == 0) -+ return 0; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -+ if (ret < 0) -+ goto out; -+ -+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -+ if (ret < 0) -+ goto out; -+ reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; -+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -+ if (untagged) -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); -+ else -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); -+ -+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -+ if (ret) -+ goto out; -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -+ -+out: -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int -+qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) -+{ -+ u32 reg, mask; -+ int ret, i; -+ bool del; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -+ if (ret < 0) -+ goto out; -+ -+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -+ if (ret < 0) -+ goto out; -+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); -+ -+ /* Check if we're the last member to be removed */ -+ del = true; -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); -+ -+ if ((reg & mask) != mask) { -+ del = false; -+ break; -+ } -+ } -+ -+ if (del) { -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); -+ } else { -+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -+ if (ret) -+ goto out; -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -+ } -+ -+out: -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int -+qca8k_mib_init(struct qca8k_priv *priv) -+{ -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | -+ QCA8K_MIB_BUSY); -+ if (ret) -+ goto exit; -+ -+ ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); -+ if (ret) -+ goto exit; -+ -+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); -+ if (ret) -+ goto exit; -+ -+ ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static void -+qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) -+{ -+ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; -+ -+ /* Port 0 and 6 have no internal PHY */ -+ if (port > 0 && port < 6) -+ mask |= QCA8K_PORT_STATUS_LINK_AUTO; -+ -+ if (enable) -+ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); -+ else -+ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); -+} -+ -+static int -+qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, -+ struct sk_buff *read_skb, u32 *val) -+{ -+ struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL); -+ bool ack; -+ int ret; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the copy pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ ack = mgmt_eth_data->ack; -+ -+ if (ret <= 0) -+ return -ETIMEDOUT; -+ -+ if (!ack) -+ return -EINVAL; -+ -+ *val = mgmt_eth_data->data[0]; -+ -+ return 0; -+} -+ -+static int -+qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, -+ int regnum, u16 data) -+{ -+ struct sk_buff *write_skb, *clear_skb, *read_skb; -+ struct qca8k_mgmt_eth_data *mgmt_eth_data; -+ u32 write_val, clear_val = 0, val; -+ struct net_device *mgmt_master; -+ int ret, ret1; -+ bool ack; -+ -+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -+ return -EINVAL; -+ -+ mgmt_eth_data = &priv->mgmt_eth_data; -+ -+ write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -+ QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -+ QCA8K_MDIO_MASTER_REG_ADDR(regnum); -+ -+ if (read) { -+ write_val |= QCA8K_MDIO_MASTER_READ; -+ } else { -+ write_val |= QCA8K_MDIO_MASTER_WRITE; -+ write_val |= QCA8K_MDIO_MASTER_DATA(data); -+ } -+ -+ /* Prealloc all the needed skb before the lock */ -+ write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val, -+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val)); -+ if (!write_skb) -+ return -ENOMEM; -+ -+ clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, -+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); -+ if (!clear_skb) { -+ ret = -ENOMEM; -+ goto err_clear_skb; -+ } -+ -+ read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val, -+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); -+ if (!read_skb) { -+ ret = -ENOMEM; -+ goto err_read_skb; -+ } -+ -+ /* Actually start the request: -+ * 1. Send mdio master packet -+ * 2. Busy Wait for mdio master command -+ * 3. Get the data if we are reading -+ * 4. Reset the mdio master (even with error) -+ */ -+ mutex_lock(&mgmt_eth_data->mutex); -+ -+ /* Check if mgmt_master is operational */ -+ mgmt_master = priv->mgmt_master; -+ if (!mgmt_master) { -+ mutex_unlock(&mgmt_eth_data->mutex); -+ ret = -EINVAL; -+ goto err_mgmt_master; -+ } -+ -+ read_skb->dev = mgmt_master; -+ clear_skb->dev = mgmt_master; -+ write_skb->dev = mgmt_master; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the write pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(write_skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ ack = mgmt_eth_data->ack; -+ -+ if (ret <= 0) { -+ ret = -ETIMEDOUT; -+ kfree_skb(read_skb); -+ goto exit; -+ } -+ -+ if (!ack) { -+ ret = -EINVAL; -+ kfree_skb(read_skb); -+ goto exit; -+ } -+ -+ ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1, -+ !(val & QCA8K_MDIO_MASTER_BUSY), 0, -+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -+ mgmt_eth_data, read_skb, &val); -+ -+ if (ret < 0 && ret1 < 0) { -+ ret = ret1; -+ goto exit; -+ } -+ -+ if (read) { -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the read pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(read_skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ ack = mgmt_eth_data->ack; -+ -+ if (ret <= 0) { -+ ret = -ETIMEDOUT; -+ goto exit; -+ } -+ -+ if (!ack) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK; -+ } else { -+ kfree_skb(read_skb); -+ } -+exit: -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the clear pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(clear_skb); -+ -+ wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ mutex_unlock(&mgmt_eth_data->mutex); -+ -+ return ret; -+ -+ /* Error handling before lock */ -+err_mgmt_master: -+ kfree_skb(read_skb); -+err_read_skb: -+ kfree_skb(clear_skb); -+err_clear_skb: -+ kfree_skb(write_skb); -+ -+ return ret; -+} -+ -+static u32 -+qca8k_port_to_phy(int port) -+{ -+ /* From Andrew Lunn: -+ * Port 0 has no internal phy. -+ * Port 1 has an internal PHY at MDIO address 0. -+ * Port 2 has an internal PHY at MDIO address 1. -+ * ... -+ * Port 5 has an internal PHY at MDIO address 4. -+ * Port 6 has no internal PHY. -+ */ -+ -+ return port - 1; -+} -+ -+static int -+qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) -+{ -+ u16 r1, r2, page; -+ u32 val; -+ int ret, ret1; -+ -+ qca8k_split_addr(reg, &r1, &r2, &page); -+ -+ ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, -+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -+ bus, 0x10 | r2, r1, &val); -+ -+ /* Check if qca8k_read has failed for a different reason -+ * before returnting -ETIMEDOUT -+ */ -+ if (ret < 0 && ret1 < 0) -+ return ret1; -+ -+ return ret; -+} -+ -+static int -+qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) -+{ -+ struct mii_bus *bus = priv->bus; -+ u16 r1, r2, page; -+ u32 val; -+ int ret; -+ -+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -+ return -EINVAL; -+ -+ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -+ QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -+ QCA8K_MDIO_MASTER_REG_ADDR(regnum) | -+ QCA8K_MDIO_MASTER_DATA(data); -+ -+ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = qca8k_set_page(priv, page); -+ if (ret) -+ goto exit; -+ -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ -+ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, -+ QCA8K_MDIO_MASTER_BUSY); -+ -+exit: -+ /* even if the busy_wait timeouts try to clear the MASTER_EN */ -+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0); -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ return ret; -+} -+ -+static int -+qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) -+{ -+ struct mii_bus *bus = priv->bus; -+ u16 r1, r2, page; -+ u32 val; -+ int ret; -+ -+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -+ return -EINVAL; -+ -+ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -+ QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -+ QCA8K_MDIO_MASTER_REG_ADDR(regnum); -+ -+ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = qca8k_set_page(priv, page); -+ if (ret) -+ goto exit; -+ -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ -+ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, -+ QCA8K_MDIO_MASTER_BUSY); -+ if (ret) -+ goto exit; -+ -+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); -+ -+exit: -+ /* even if the busy_wait timeouts try to clear the MASTER_EN */ -+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0); -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ if (ret >= 0) -+ ret = val & QCA8K_MDIO_MASTER_DATA_MASK; -+ -+ return ret; -+} -+ -+static int -+qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) -+{ -+ struct qca8k_priv *priv = slave_bus->priv; -+ int ret; -+ -+ /* Use mdio Ethernet when available, fallback to legacy one on error */ -+ ret = qca8k_phy_eth_command(priv, false, phy, regnum, data); -+ if (!ret) -+ return 0; -+ -+ return qca8k_mdio_write(priv, phy, regnum, data); -+} -+ -+static int -+qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) -+{ -+ struct qca8k_priv *priv = slave_bus->priv; -+ int ret; -+ -+ /* Use mdio Ethernet when available, fallback to legacy one on error */ -+ ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0); -+ if (ret >= 0) -+ return ret; -+ -+ ret = qca8k_mdio_read(priv, phy, regnum); -+ -+ if (ret < 0) -+ return 0xffff; -+ -+ return ret; -+} -+ -+static int -+qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) -+{ -+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; -+ -+ return qca8k_internal_mdio_write(slave_bus, port, regnum, data); -+} -+ -+static int -+qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) -+{ -+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; -+ -+ return qca8k_internal_mdio_read(slave_bus, port, regnum); -+} -+ -+static int -+qca8k_mdio_register(struct qca8k_priv *priv) -+{ -+ struct dsa_switch *ds = priv->ds; -+ struct device_node *mdio; -+ struct mii_bus *bus; -+ -+ bus = devm_mdiobus_alloc(ds->dev); -+ if (!bus) -+ return -ENOMEM; -+ -+ bus->priv = (void *)priv; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", -+ ds->dst->index, ds->index); -+ bus->parent = ds->dev; -+ bus->phy_mask = ~ds->phys_mii_mask; -+ ds->slave_mii_bus = bus; -+ -+ /* Check if the devicetree declare the port:phy mapping */ -+ mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); -+ if (of_device_is_available(mdio)) { -+ bus->name = "qca8k slave mii"; -+ bus->read = qca8k_internal_mdio_read; -+ bus->write = qca8k_internal_mdio_write; -+ return devm_of_mdiobus_register(priv->dev, bus, mdio); -+ } -+ -+ /* If a mapping can't be found the legacy mapping is used, -+ * using the qca8k_port_to_phy function -+ */ -+ bus->name = "qca8k-legacy slave mii"; -+ bus->read = qca8k_legacy_mdio_read; -+ bus->write = qca8k_legacy_mdio_write; -+ return devm_mdiobus_register(priv->dev, bus); -+} -+ -+static int -+qca8k_setup_mdio_bus(struct qca8k_priv *priv) -+{ -+ u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; -+ struct device_node *ports, *port; -+ phy_interface_t mode; -+ int err; -+ -+ ports = of_get_child_by_name(priv->dev->of_node, "ports"); -+ if (!ports) -+ ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports"); -+ -+ if (!ports) -+ return -EINVAL; -+ -+ for_each_available_child_of_node(ports, port) { -+ err = of_property_read_u32(port, "reg", ®); -+ if (err) { -+ of_node_put(port); -+ of_node_put(ports); -+ return err; -+ } -+ -+ if (!dsa_is_user_port(priv->ds, reg)) -+ continue; -+ -+ of_get_phy_mode(port, &mode); -+ -+ if (of_property_read_bool(port, "phy-handle") && -+ mode != PHY_INTERFACE_MODE_INTERNAL) -+ external_mdio_mask |= BIT(reg); -+ else -+ internal_mdio_mask |= BIT(reg); -+ } -+ -+ of_node_put(ports); -+ if (!external_mdio_mask && !internal_mdio_mask) { -+ dev_err(priv->dev, "no PHYs are defined.\n"); -+ return -EINVAL; -+ } -+ -+ /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through -+ * the MDIO_MASTER register also _disconnects_ the external MDC -+ * passthrough to the internal PHYs. It's not possible to use both -+ * configurations at the same time! -+ * -+ * Because this came up during the review process: -+ * If the external mdio-bus driver is capable magically disabling -+ * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's -+ * accessors for the time being, it would be possible to pull this -+ * off. -+ */ -+ if (!!external_mdio_mask && !!internal_mdio_mask) { -+ dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n"); -+ return -EINVAL; -+ } -+ -+ if (external_mdio_mask) { -+ /* Make sure to disable the internal mdio bus in cases -+ * a dt-overlay and driver reload changed the configuration -+ */ -+ -+ return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL, -+ QCA8K_MDIO_MASTER_EN); -+ } -+ -+ return qca8k_mdio_register(priv); -+} -+ -+static int -+qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) -+{ -+ u32 mask = 0; -+ int ret = 0; -+ -+ /* SoC specific settings for ipq8064. -+ * If more device require this consider adding -+ * a dedicated binding. -+ */ -+ if (of_machine_is_compatible("qcom,ipq8064")) -+ mask |= QCA8K_MAC_PWR_RGMII0_1_8V; -+ -+ /* SoC specific settings for ipq8065 */ -+ if (of_machine_is_compatible("qcom,ipq8065")) -+ mask |= QCA8K_MAC_PWR_RGMII1_1_8V; -+ -+ if (mask) { -+ ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, -+ QCA8K_MAC_PWR_RGMII0_1_8V | -+ QCA8K_MAC_PWR_RGMII1_1_8V, -+ mask); -+ } -+ -+ return ret; -+} -+ -+static int qca8k_find_cpu_port(struct dsa_switch *ds) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ /* Find the connected cpu port. Valid port are 0 or 6 */ -+ if (dsa_is_cpu_port(ds, 0)) -+ return 0; -+ -+ dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6"); -+ -+ if (dsa_is_cpu_port(ds, 6)) -+ return 6; -+ -+ return -EINVAL; -+} -+ -+static int -+qca8k_setup_of_pws_reg(struct qca8k_priv *priv) -+{ -+ struct device_node *node = priv->dev->of_node; -+ const struct qca8k_match_data *data; -+ u32 val = 0; -+ int ret; -+ -+ /* QCA8327 require to set to the correct mode. -+ * His bigger brother QCA8328 have the 172 pin layout. -+ * Should be applied by default but we set this just to make sure. -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8327) { -+ data = of_device_get_match_data(priv->dev); -+ -+ /* Set the correct package of 148 pin for QCA8327 */ -+ if (data->reduced_package) -+ val |= QCA8327_PWS_PACKAGE148_EN; -+ -+ ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, -+ val); -+ if (ret) -+ return ret; -+ } -+ -+ if (of_property_read_bool(node, "qca,ignore-power-on-sel")) -+ val |= QCA8K_PWS_POWER_ON_SEL; -+ -+ if (of_property_read_bool(node, "qca,led-open-drain")) { -+ if (!(val & QCA8K_PWS_POWER_ON_SEL)) { -+ dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set."); -+ return -EINVAL; -+ } -+ -+ val |= QCA8K_PWS_LED_OPEN_EN_CSR; -+ } -+ -+ return qca8k_rmw(priv, QCA8K_REG_PWS, -+ QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, -+ val); -+} -+ -+static int -+qca8k_parse_port_config(struct qca8k_priv *priv) -+{ -+ int port, cpu_port_index = -1, ret; -+ struct device_node *port_dn; -+ phy_interface_t mode; -+ struct dsa_port *dp; -+ u32 delay; -+ -+ /* We have 2 CPU port. Check them */ -+ for (port = 0; port < QCA8K_NUM_PORTS; port++) { -+ /* Skip every other port */ -+ if (port != 0 && port != 6) -+ continue; -+ -+ dp = dsa_to_port(priv->ds, port); -+ port_dn = dp->dn; -+ cpu_port_index++; -+ -+ if (!of_device_is_available(port_dn)) -+ continue; -+ -+ ret = of_get_phy_mode(port_dn, &mode); -+ if (ret) -+ continue; -+ -+ switch (mode) { -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ case PHY_INTERFACE_MODE_SGMII: -+ delay = 0; -+ -+ if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay)) -+ /* Switch regs accept value in ns, convert ps to ns */ -+ delay = delay / 1000; -+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID || -+ mode == PHY_INTERFACE_MODE_RGMII_TXID) -+ delay = 1; -+ -+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { -+ dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); -+ delay = 3; -+ } -+ -+ priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay; -+ -+ delay = 0; -+ -+ if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay)) -+ /* Switch regs accept value in ns, convert ps to ns */ -+ delay = delay / 1000; -+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID || -+ mode == PHY_INTERFACE_MODE_RGMII_RXID) -+ delay = 2; -+ -+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { -+ dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); -+ delay = 3; -+ } -+ -+ priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay; -+ -+ /* Skip sgmii parsing for rgmii* mode */ -+ if (mode == PHY_INTERFACE_MODE_RGMII || -+ mode == PHY_INTERFACE_MODE_RGMII_ID || -+ mode == PHY_INTERFACE_MODE_RGMII_TXID || -+ mode == PHY_INTERFACE_MODE_RGMII_RXID) -+ break; -+ -+ if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) -+ priv->ports_config.sgmii_tx_clk_falling_edge = true; -+ -+ if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) -+ priv->ports_config.sgmii_rx_clk_falling_edge = true; -+ -+ if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) { -+ priv->ports_config.sgmii_enable_pll = true; -+ -+ if (priv->switch_id == QCA8K_ID_QCA8327) { -+ dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling"); -+ priv->ports_config.sgmii_enable_pll = false; -+ } -+ -+ if (priv->switch_revision < 2) -+ dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more."); -+ } -+ -+ break; -+ default: -+ continue; -+ } -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_setup(struct dsa_switch *ds) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ int cpu_port, ret, i; -+ u32 mask; -+ -+ cpu_port = qca8k_find_cpu_port(ds); -+ if (cpu_port < 0) { -+ dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6"); -+ return cpu_port; -+ } -+ -+ /* Parse CPU port config to be later used in phy_link mac_config */ -+ ret = qca8k_parse_port_config(priv); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_setup_mdio_bus(priv); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_setup_of_pws_reg(priv); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_setup_mac_pwr_sel(priv); -+ if (ret) -+ return ret; -+ -+ /* Make sure MAC06 is disabled */ -+ ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, -+ QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); -+ if (ret) { -+ dev_err(priv->dev, "failed disabling MAC06 exchange"); -+ return ret; -+ } -+ -+ /* Enable CPU Port */ -+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); -+ if (ret) { -+ dev_err(priv->dev, "failed enabling CPU port"); -+ return ret; -+ } -+ -+ /* Enable MIB counters */ -+ ret = qca8k_mib_init(priv); -+ if (ret) -+ dev_warn(priv->dev, "mib init failed"); -+ -+ /* Initial setup of all ports */ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ /* Disable forwarding by default on all ports */ -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -+ QCA8K_PORT_LOOKUP_MEMBER, 0); -+ if (ret) -+ return ret; -+ -+ /* Enable QCA header mode on all cpu ports */ -+ if (dsa_is_cpu_port(ds, i)) { -+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), -+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | -+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); -+ if (ret) { -+ dev_err(priv->dev, "failed enabling QCA header mode"); -+ return ret; -+ } -+ } -+ -+ /* Disable MAC by default on all user ports */ -+ if (dsa_is_user_port(ds, i)) -+ qca8k_port_set_status(priv, i, 0); -+ } -+ -+ /* Forward all unknown frames to CPU port for Linux processing -+ * Notice that in multi-cpu config only one port should be set -+ * for igmp, unknown, multicast and broadcast packet -+ */ -+ ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); -+ if (ret) -+ return ret; -+ -+ /* Setup connection between CPU port & user ports -+ * Configure specific switch configuration for ports -+ */ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ /* CPU port gets connected to all user ports of the switch */ -+ if (dsa_is_cpu_port(ds, i)) { -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -+ QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); -+ if (ret) -+ return ret; -+ } -+ -+ /* Individual user ports get connected to CPU port only */ -+ if (dsa_is_user_port(ds, i)) { -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -+ QCA8K_PORT_LOOKUP_MEMBER, -+ BIT(cpu_port)); -+ if (ret) -+ return ret; -+ -+ /* Enable ARP Auto-learning by default */ -+ ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), -+ QCA8K_PORT_LOOKUP_LEARN); -+ if (ret) -+ return ret; -+ -+ /* For port based vlans to work we need to set the -+ * default egress vid -+ */ -+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), -+ QCA8K_EGREES_VLAN_PORT_MASK(i), -+ QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), -+ QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | -+ QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); -+ if (ret) -+ return ret; -+ } -+ -+ /* The port 5 of the qca8337 have some problem in flood condition. The -+ * original legacy driver had some specific buffer and priority settings -+ * for the different port suggested by the QCA switch team. Add this -+ * missing settings to improve switch stability under load condition. -+ * This problem is limited to qca8337 and other qca8k switch are not affected. -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8337) { -+ switch (i) { -+ /* The 2 CPU port and port 5 requires some different -+ * priority than any other ports. -+ */ -+ case 0: -+ case 5: -+ case 6: -+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | -+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); -+ break; -+ default: -+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | -+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); -+ } -+ qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask); -+ -+ mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | -+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_WRED_EN; -+ qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), -+ QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | -+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_WRED_EN, -+ mask); -+ } -+ } -+ -+ /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ -+ if (priv->switch_id == QCA8K_ID_QCA8327) { -+ mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | -+ QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); -+ qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, -+ QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | -+ QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, -+ mask); -+ } -+ -+ /* Setup our port MTUs to match power on defaults */ -+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); -+ if (ret) -+ dev_warn(priv->dev, "failed setting MTU settings"); -+ -+ /* Flush the FDB table */ -+ qca8k_fdb_flush(priv); -+ -+ /* We don't have interrupts for link changes, so we need to poll */ -+ ds->pcs_poll = true; -+ -+ /* Set min a max ageing value supported */ -+ ds->ageing_time_min = 7000; -+ ds->ageing_time_max = 458745000; -+ -+ /* Set max number of LAGs supported */ -+ ds->num_lag_ids = QCA8K_NUM_LAGS; -+ -+ return 0; -+} -+ -+static void -+qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index, -+ u32 reg) -+{ -+ u32 delay, val = 0; -+ int ret; -+ -+ /* Delay can be declared in 3 different way. -+ * Mode to rgmii and internal-delay standard binding defined -+ * rgmii-id or rgmii-tx/rx phy mode set. -+ * The parse logic set a delay different than 0 only when one -+ * of the 3 different way is used. In all other case delay is -+ * not enabled. With ID or TX/RXID delay is enabled and set -+ * to the default and recommended value. -+ */ -+ if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) { -+ delay = priv->ports_config.rgmii_tx_delay[cpu_port_index]; -+ -+ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | -+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; -+ } -+ -+ if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) { -+ delay = priv->ports_config.rgmii_rx_delay[cpu_port_index]; -+ -+ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; -+ } -+ -+ /* Set RGMII delay based on the selected values */ -+ ret = qca8k_rmw(priv, reg, -+ QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | -+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, -+ val); -+ if (ret) -+ dev_err(priv->dev, "Failed to set internal delay for CPU port%d", -+ cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); -+} -+ -+static void -+qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int cpu_port_index, ret; -+ u32 reg, val; -+ -+ switch (port) { -+ case 0: /* 1st CPU port */ -+ if (state->interface != PHY_INTERFACE_MODE_RGMII && -+ state->interface != PHY_INTERFACE_MODE_RGMII_ID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -+ state->interface != PHY_INTERFACE_MODE_SGMII) -+ return; -+ -+ reg = QCA8K_REG_PORT0_PAD_CTRL; -+ cpu_port_index = QCA8K_CPU_PORT0; -+ break; -+ case 1: -+ case 2: -+ case 3: -+ case 4: -+ case 5: -+ /* Internal PHY, nothing to do */ -+ return; -+ case 6: /* 2nd CPU port / external PHY */ -+ if (state->interface != PHY_INTERFACE_MODE_RGMII && -+ state->interface != PHY_INTERFACE_MODE_RGMII_ID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -+ state->interface != PHY_INTERFACE_MODE_SGMII && -+ state->interface != PHY_INTERFACE_MODE_1000BASEX) -+ return; -+ -+ reg = QCA8K_REG_PORT6_PAD_CTRL; -+ cpu_port_index = QCA8K_CPU_PORT6; -+ break; -+ default: -+ dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); -+ return; -+ } -+ -+ if (port != 6 && phylink_autoneg_inband(mode)) { -+ dev_err(ds->dev, "%s: in-band negotiation unsupported\n", -+ __func__); -+ return; -+ } -+ -+ switch (state->interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); -+ -+ /* Configure rgmii delay */ -+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -+ -+ /* QCA8337 requires to set rgmii rx delay for all ports. -+ * This is enabled through PORT5_PAD_CTRL for all ports, -+ * rather than individual port registers. -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8337) -+ qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); -+ break; -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ /* Enable SGMII on the port */ -+ qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); -+ -+ /* Enable/disable SerDes auto-negotiation as necessary */ -+ ret = qca8k_read(priv, QCA8K_REG_PWS, &val); -+ if (ret) -+ return; -+ if (phylink_autoneg_inband(mode)) -+ val &= ~QCA8K_PWS_SERDES_AEN_DIS; -+ else -+ val |= QCA8K_PWS_SERDES_AEN_DIS; -+ qca8k_write(priv, QCA8K_REG_PWS, val); -+ -+ /* Configure the SGMII parameters */ -+ ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val); -+ if (ret) -+ return; -+ -+ val |= QCA8K_SGMII_EN_SD; -+ -+ if (priv->ports_config.sgmii_enable_pll) -+ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | -+ QCA8K_SGMII_EN_TX; -+ -+ if (dsa_is_cpu_port(ds, port)) { -+ /* CPU port, we're talking to the CPU MAC, be a PHY */ -+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -+ val |= QCA8K_SGMII_MODE_CTRL_PHY; -+ } else if (state->interface == PHY_INTERFACE_MODE_SGMII) { -+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -+ val |= QCA8K_SGMII_MODE_CTRL_MAC; -+ } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { -+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -+ val |= QCA8K_SGMII_MODE_CTRL_BASEX; -+ } -+ -+ qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); -+ -+ /* From original code is reported port instability as SGMII also -+ * require delay set. Apply advised values here or take them from DT. -+ */ -+ if (state->interface == PHY_INTERFACE_MODE_SGMII) -+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -+ -+ /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and -+ * falling edge is set writing in the PORT0 PAD reg -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8327 || -+ priv->switch_id == QCA8K_ID_QCA8337) -+ reg = QCA8K_REG_PORT0_PAD_CTRL; -+ -+ val = 0; -+ -+ /* SGMII Clock phase configuration */ -+ if (priv->ports_config.sgmii_rx_clk_falling_edge) -+ val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; -+ -+ if (priv->ports_config.sgmii_tx_clk_falling_edge) -+ val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; -+ -+ if (val) -+ ret = qca8k_rmw(priv, reg, -+ QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | -+ QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, -+ val); -+ -+ break; -+ default: -+ dev_err(ds->dev, "xMII mode %s not supported for port %d\n", -+ phy_modes(state->interface), port); -+ return; -+ } -+} -+ -+static void -+qca8k_phylink_validate(struct dsa_switch *ds, int port, -+ unsigned long *supported, -+ struct phylink_link_state *state) -+{ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -+ -+ switch (port) { -+ case 0: /* 1st CPU port */ -+ if (state->interface != PHY_INTERFACE_MODE_NA && -+ state->interface != PHY_INTERFACE_MODE_RGMII && -+ state->interface != PHY_INTERFACE_MODE_RGMII_ID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -+ state->interface != PHY_INTERFACE_MODE_SGMII) -+ goto unsupported; -+ break; -+ case 1: -+ case 2: -+ case 3: -+ case 4: -+ case 5: -+ /* Internal PHY */ -+ if (state->interface != PHY_INTERFACE_MODE_NA && -+ state->interface != PHY_INTERFACE_MODE_GMII && -+ state->interface != PHY_INTERFACE_MODE_INTERNAL) -+ goto unsupported; -+ break; -+ case 6: /* 2nd CPU port / external PHY */ -+ if (state->interface != PHY_INTERFACE_MODE_NA && -+ state->interface != PHY_INTERFACE_MODE_RGMII && -+ state->interface != PHY_INTERFACE_MODE_RGMII_ID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -+ state->interface != PHY_INTERFACE_MODE_SGMII && -+ state->interface != PHY_INTERFACE_MODE_1000BASEX) -+ goto unsupported; -+ break; -+ default: -+unsupported: -+ linkmode_zero(supported); -+ return; -+ } -+ -+ phylink_set_port_modes(mask); -+ phylink_set(mask, Autoneg); -+ -+ phylink_set(mask, 1000baseT_Full); -+ phylink_set(mask, 10baseT_Half); -+ phylink_set(mask, 10baseT_Full); -+ phylink_set(mask, 100baseT_Half); -+ phylink_set(mask, 100baseT_Full); -+ -+ if (state->interface == PHY_INTERFACE_MODE_1000BASEX) -+ phylink_set(mask, 1000baseX_Full); -+ -+ phylink_set(mask, Pause); -+ phylink_set(mask, Asym_Pause); -+ -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); -+} -+ -+static int -+qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, -+ struct phylink_link_state *state) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ u32 reg; -+ int ret; -+ -+ ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), ®); -+ if (ret < 0) -+ return ret; -+ -+ state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); -+ state->an_complete = state->link; -+ state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO); -+ state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : -+ DUPLEX_HALF; -+ -+ switch (reg & QCA8K_PORT_STATUS_SPEED) { -+ case QCA8K_PORT_STATUS_SPEED_10: -+ state->speed = SPEED_10; -+ break; -+ case QCA8K_PORT_STATUS_SPEED_100: -+ state->speed = SPEED_100; -+ break; -+ case QCA8K_PORT_STATUS_SPEED_1000: -+ state->speed = SPEED_1000; -+ break; -+ default: -+ state->speed = SPEED_UNKNOWN; -+ break; -+ } -+ -+ state->pause = MLO_PAUSE_NONE; -+ if (reg & QCA8K_PORT_STATUS_RXFLOW) -+ state->pause |= MLO_PAUSE_RX; -+ if (reg & QCA8K_PORT_STATUS_TXFLOW) -+ state->pause |= MLO_PAUSE_TX; -+ -+ return 1; -+} -+ -+static void -+qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, -+ phy_interface_t interface) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ qca8k_port_set_status(priv, port, 0); -+} -+ -+static void -+qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, -+ phy_interface_t interface, struct phy_device *phydev, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ u32 reg; -+ -+ if (phylink_autoneg_inband(mode)) { -+ reg = QCA8K_PORT_STATUS_LINK_AUTO; -+ } else { -+ switch (speed) { -+ case SPEED_10: -+ reg = QCA8K_PORT_STATUS_SPEED_10; -+ break; -+ case SPEED_100: -+ reg = QCA8K_PORT_STATUS_SPEED_100; -+ break; -+ case SPEED_1000: -+ reg = QCA8K_PORT_STATUS_SPEED_1000; -+ break; -+ default: -+ reg = QCA8K_PORT_STATUS_LINK_AUTO; -+ break; -+ } -+ -+ if (duplex == DUPLEX_FULL) -+ reg |= QCA8K_PORT_STATUS_DUPLEX; -+ -+ if (rx_pause || dsa_is_cpu_port(ds, port)) -+ reg |= QCA8K_PORT_STATUS_RXFLOW; -+ -+ if (tx_pause || dsa_is_cpu_port(ds, port)) -+ reg |= QCA8K_PORT_STATUS_TXFLOW; -+ } -+ -+ reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; -+ -+ qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); -+} -+ -+static void -+qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) -+{ -+ const struct qca8k_match_data *match_data; -+ struct qca8k_priv *priv = ds->priv; -+ int i; -+ -+ if (stringset != ETH_SS_STATS) -+ return; -+ -+ match_data = of_device_get_match_data(priv->dev); -+ -+ for (i = 0; i < match_data->mib_count; i++) -+ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, -+ ETH_GSTRING_LEN); -+} -+ -+static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) -+{ -+ const struct qca8k_match_data *match_data; -+ struct qca8k_mib_eth_data *mib_eth_data; -+ struct qca8k_priv *priv = ds->priv; -+ const struct qca8k_mib_desc *mib; -+ struct mib_ethhdr *mib_ethhdr; -+ int i, mib_len, offset = 0; -+ u64 *data; -+ u8 port; -+ -+ mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); -+ mib_eth_data = &priv->mib_eth_data; -+ -+ /* The switch autocast every port. Ignore other packet and -+ * parse only the requested one. -+ */ -+ port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr)); -+ if (port != mib_eth_data->req_port) -+ goto exit; -+ -+ match_data = device_get_match_data(priv->dev); -+ data = mib_eth_data->data; -+ -+ for (i = 0; i < match_data->mib_count; i++) { -+ mib = &ar8327_mib[i]; -+ -+ /* First 3 mib are present in the skb head */ -+ if (i < 3) { -+ data[i] = mib_ethhdr->data[i]; -+ continue; -+ } -+ -+ mib_len = sizeof(uint32_t); -+ -+ /* Some mib are 64 bit wide */ -+ if (mib->size == 2) -+ mib_len = sizeof(uint64_t); -+ -+ /* Copy the mib value from packet to the */ -+ memcpy(data + i, skb->data + offset, mib_len); -+ -+ /* Set the offset for the next mib */ -+ offset += mib_len; -+ } -+ -+exit: -+ /* Complete on receiving all the mib packet */ -+ if (refcount_dec_and_test(&mib_eth_data->port_parsed)) -+ complete(&mib_eth_data->rw_done); -+} -+ -+static int -+qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data) -+{ -+ struct dsa_port *dp = dsa_to_port(ds, port); -+ struct qca8k_mib_eth_data *mib_eth_data; -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ mib_eth_data = &priv->mib_eth_data; -+ -+ mutex_lock(&mib_eth_data->mutex); -+ -+ reinit_completion(&mib_eth_data->rw_done); -+ -+ mib_eth_data->req_port = dp->index; -+ mib_eth_data->data = data; -+ refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS); -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ /* Send mib autocast request */ -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) | -+ QCA8K_MIB_BUSY); -+ -+ mutex_unlock(&priv->reg_mutex); -+ -+ if (ret) -+ goto exit; -+ -+ ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT); -+ -+exit: -+ mutex_unlock(&mib_eth_data->mutex); -+ -+ return ret; -+} -+ -+static void -+qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, -+ uint64_t *data) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ const struct qca8k_match_data *match_data; -+ const struct qca8k_mib_desc *mib; -+ u32 reg, i, val; -+ u32 hi = 0; -+ int ret; -+ -+ if (priv->mgmt_master && -+ qca8k_get_ethtool_stats_eth(ds, port, data) > 0) -+ return; -+ -+ match_data = of_device_get_match_data(priv->dev); -+ -+ for (i = 0; i < match_data->mib_count; i++) { -+ mib = &ar8327_mib[i]; -+ reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; -+ -+ ret = qca8k_read(priv, reg, &val); -+ if (ret < 0) -+ continue; -+ -+ if (mib->size == 2) { -+ ret = qca8k_read(priv, reg + 4, &hi); -+ if (ret < 0) -+ continue; -+ } -+ -+ data[i] = val; -+ if (mib->size == 2) -+ data[i] |= (u64)hi << 32; -+ } -+} -+ -+static int -+qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) -+{ -+ const struct qca8k_match_data *match_data; -+ struct qca8k_priv *priv = ds->priv; -+ -+ if (sset != ETH_SS_STATS) -+ return 0; -+ -+ match_data = of_device_get_match_data(priv->dev); -+ -+ return match_data->mib_count; -+} -+ -+static int -+qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); -+ u32 reg; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); -+ if (ret < 0) -+ goto exit; -+ -+ if (eee->eee_enabled) -+ reg |= lpi_en; -+ else -+ reg &= ~lpi_en; -+ ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static int -+qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) -+{ -+ /* Nothing to do on the port's MAC */ -+ return 0; -+} -+ -+static void -+qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ u32 stp_state; -+ -+ switch (state) { -+ case BR_STATE_DISABLED: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; -+ break; -+ case BR_STATE_BLOCKING: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; -+ break; -+ case BR_STATE_LISTENING: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; -+ break; -+ case BR_STATE_LEARNING: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; -+ break; -+ case BR_STATE_FORWARDING: -+ default: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; -+ break; -+ } -+ -+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); -+} -+ -+static int -+qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ int port_mask, cpu_port; -+ int i, ret; -+ -+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -+ port_mask = BIT(cpu_port); -+ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ if (dsa_is_cpu_port(ds, i)) -+ continue; -+ if (dsa_to_port(ds, i)->bridge_dev != br) -+ continue; -+ /* Add this port to the portvlan mask of the other ports -+ * in the bridge -+ */ -+ ret = regmap_set_bits(priv->regmap, -+ QCA8K_PORT_LOOKUP_CTRL(i), -+ BIT(port)); -+ if (ret) -+ return ret; -+ if (i != port) -+ port_mask |= BIT(i); -+ } -+ -+ /* Add all other ports to this ports portvlan mask */ -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_MEMBER, port_mask); -+ -+ return ret; -+} -+ -+static void -+qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ int cpu_port, i; -+ -+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -+ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ if (dsa_is_cpu_port(ds, i)) -+ continue; -+ if (dsa_to_port(ds, i)->bridge_dev != br) -+ continue; -+ /* Remove this port to the portvlan mask of the other ports -+ * in the bridge -+ */ -+ regmap_clear_bits(priv->regmap, -+ QCA8K_PORT_LOOKUP_CTRL(i), -+ BIT(port)); -+ } -+ -+ /* Set the cpu port to be the only one in the portvlan mask of -+ * this port -+ */ -+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); -+} -+ -+static void -+qca8k_port_fast_age(struct dsa_switch *ds, int port) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); -+ mutex_unlock(&priv->reg_mutex); -+} -+ -+static int -+qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ unsigned int secs = msecs / 1000; -+ u32 val; -+ -+ /* AGE_TIME reg is set in 7s step */ -+ val = secs / 7; -+ -+ /* Handle case with 0 as val to NOT disable -+ * learning -+ */ -+ if (!val) -+ val = 1; -+ -+ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, -+ QCA8K_ATU_AGE_TIME(val)); -+} -+ -+static int -+qca8k_port_enable(struct dsa_switch *ds, int port, -+ struct phy_device *phy) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ -+ qca8k_port_set_status(priv, port, 1); -+ priv->port_enabled_map |= BIT(port); -+ -+ if (dsa_is_user_port(ds, port)) -+ phy_support_asym_pause(phy); -+ -+ return 0; -+} -+ -+static void -+qca8k_port_disable(struct dsa_switch *ds, int port) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ -+ qca8k_port_set_status(priv, port, 0); -+ priv->port_enabled_map &= ~BIT(port); -+} -+ -+static int -+qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ /* We have only have a general MTU setting. -+ * DSA always set the CPU port's MTU to the largest MTU of the slave -+ * ports. -+ * Setting MTU just for the CPU port is sufficient to correctly set a -+ * value for every port. -+ */ -+ if (!dsa_is_cpu_port(ds, port)) -+ return 0; -+ -+ /* To change the MAX_FRAME_SIZE the cpu ports must be off or -+ * the switch panics. -+ * Turn off both cpu ports before applying the new value to prevent -+ * this. -+ */ -+ if (priv->port_enabled_map & BIT(0)) -+ qca8k_port_set_status(priv, 0, 0); -+ -+ if (priv->port_enabled_map & BIT(6)) -+ qca8k_port_set_status(priv, 6, 0); -+ -+ /* Include L2 header / FCS length */ -+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); -+ -+ if (priv->port_enabled_map & BIT(0)) -+ qca8k_port_set_status(priv, 0, 1); -+ -+ if (priv->port_enabled_map & BIT(6)) -+ qca8k_port_set_status(priv, 6, 1); -+ -+ return ret; -+} -+ -+static int -+qca8k_port_max_mtu(struct dsa_switch *ds, int port) -+{ -+ return QCA8K_MAX_MTU; -+} -+ -+static int -+qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, -+ u16 port_mask, u16 vid) -+{ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = QCA8K_PORT_VID_DEF; -+ -+ return qca8k_fdb_add(priv, addr, port_mask, vid, -+ QCA8K_ATU_STATUS_STATIC); -+} -+ -+static int -+qca8k_port_fdb_add(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ u16 port_mask = BIT(port); -+ -+ return qca8k_port_fdb_insert(priv, addr, port_mask, vid); -+} -+ -+static int -+qca8k_port_fdb_del(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ u16 port_mask = BIT(port); -+ -+ if (!vid) -+ vid = QCA8K_PORT_VID_DEF; -+ -+ return qca8k_fdb_del(priv, addr, port_mask, vid); -+} -+ -+static int -+qca8k_port_fdb_dump(struct dsa_switch *ds, int port, -+ dsa_fdb_dump_cb_t *cb, void *data) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ struct qca8k_fdb _fdb = { 0 }; -+ int cnt = QCA8K_NUM_FDB_RECORDS; -+ bool is_static; -+ int ret = 0; -+ -+ mutex_lock(&priv->reg_mutex); -+ while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { -+ if (!_fdb.aging) -+ break; -+ is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); -+ ret = cb(_fdb.mac, _fdb.vid, is_static, data); -+ if (ret) -+ break; -+ } -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+static int -+qca8k_port_mdb_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ const u8 *addr = mdb->addr; -+ u16 vid = mdb->vid; -+ -+ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); -+} -+ -+static int -+qca8k_port_mdb_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ const u8 *addr = mdb->addr; -+ u16 vid = mdb->vid; -+ -+ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); -+} -+ -+static int -+qca8k_port_mirror_add(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror, -+ bool ingress) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int monitor_port, ret; -+ u32 reg, val; -+ -+ /* Check for existent entry */ -+ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) -+ return -EEXIST; -+ -+ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); -+ if (ret) -+ return ret; -+ -+ /* QCA83xx can have only one port set to mirror mode. -+ * Check that the correct port is requested and return error otherwise. -+ * When no mirror port is set, the values is set to 0xF -+ */ -+ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (monitor_port != 0xF && monitor_port != mirror->to_local_port) -+ return -EEXIST; -+ -+ /* Set the monitor port */ -+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, -+ mirror->to_local_port); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (ret) -+ return ret; -+ -+ if (ingress) { -+ reg = QCA8K_PORT_LOOKUP_CTRL(port); -+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -+ } else { -+ reg = QCA8K_REG_PORT_HOL_CTRL1(port); -+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -+ } -+ -+ ret = regmap_update_bits(priv->regmap, reg, val, val); -+ if (ret) -+ return ret; -+ -+ /* Track mirror port for tx and rx to decide when the -+ * mirror port has to be disabled. -+ */ -+ if (ingress) -+ priv->mirror_rx |= BIT(port); -+ else -+ priv->mirror_tx |= BIT(port); -+ -+ return 0; -+} -+ -+static void -+qca8k_port_mirror_del(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ u32 reg, val; -+ int ret; -+ -+ if (mirror->ingress) { -+ reg = QCA8K_PORT_LOOKUP_CTRL(port); -+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -+ } else { -+ reg = QCA8K_REG_PORT_HOL_CTRL1(port); -+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -+ } -+ -+ ret = regmap_clear_bits(priv->regmap, reg, val); -+ if (ret) -+ goto err; -+ -+ if (mirror->ingress) -+ priv->mirror_rx &= ~BIT(port); -+ else -+ priv->mirror_tx &= ~BIT(port); -+ -+ /* No port set to send packet to mirror port. Disable mirror port */ -+ if (!priv->mirror_rx && !priv->mirror_tx) { -+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (ret) -+ goto err; -+ } -+err: -+ dev_err(priv->dev, "Failed to del mirror port from %d", port); -+} -+ -+static int -+qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, -+ struct netlink_ext_ack *extack) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ if (vlan_filtering) { -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -+ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); -+ } else { -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -+ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); -+ } -+ -+ return ret; -+} -+ -+static int -+qca8k_port_vlan_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan, -+ struct netlink_ext_ack *extack) -+{ -+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; -+ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); -+ if (ret) { -+ dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); -+ return ret; -+ } -+ -+ if (pvid) { -+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), -+ QCA8K_EGREES_VLAN_PORT_MASK(port), -+ QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), -+ QCA8K_PORT_VLAN_CVID(vlan->vid) | -+ QCA8K_PORT_VLAN_SVID(vlan->vid)); -+ } -+ -+ return ret; -+} -+ -+static int -+qca8k_port_vlan_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ ret = qca8k_vlan_del(priv, port, vlan->vid); -+ if (ret) -+ dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); -+ -+ return ret; -+} -+ -+static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ /* Communicate to the phy internal driver the switch revision. -+ * Based on the switch revision different values needs to be -+ * set to the dbg and mmd reg on the phy. -+ * The first 2 bit are used to communicate the switch revision -+ * to the phy driver. -+ */ -+ if (port > 0 && port < 6) -+ return priv->switch_revision; -+ -+ return 0; -+} -+ -+static enum dsa_tag_protocol -+qca8k_get_tag_protocol(struct dsa_switch *ds, int port, -+ enum dsa_tag_protocol mp) -+{ -+ return DSA_TAG_PROTO_QCA; -+} -+ -+static bool -+qca8k_lag_can_offload(struct dsa_switch *ds, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ struct dsa_port *dp; -+ int id, members = 0; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ if (id < 0 || id >= ds->num_lag_ids) -+ return false; -+ -+ dsa_lag_foreach_port(dp, ds->dst, lag) -+ /* Includes the port joining the LAG */ -+ members++; -+ -+ if (members > QCA8K_NUM_PORTS_FOR_LAG) -+ return false; -+ -+ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) -+ return false; -+ -+ if (info->hash_type != NETDEV_LAG_HASH_L2 && -+ info->hash_type != NETDEV_LAG_HASH_L23) -+ return false; -+ -+ return true; -+} -+ -+static int -+qca8k_lag_setup_hash(struct dsa_switch *ds, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ bool unique_lag = true; -+ u32 hash = 0; -+ int i, id; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ -+ switch (info->hash_type) { -+ case NETDEV_LAG_HASH_L23: -+ hash |= QCA8K_TRUNK_HASH_SIP_EN; -+ hash |= QCA8K_TRUNK_HASH_DIP_EN; -+ fallthrough; -+ case NETDEV_LAG_HASH_L2: -+ hash |= QCA8K_TRUNK_HASH_SA_EN; -+ hash |= QCA8K_TRUNK_HASH_DA_EN; -+ break; -+ default: /* We should NEVER reach this */ -+ return -EOPNOTSUPP; -+ } -+ -+ /* Check if we are the unique configured LAG */ -+ dsa_lags_foreach_id(i, ds->dst) -+ if (i != id && dsa_lag_dev(ds->dst, i)) { -+ unique_lag = false; -+ break; -+ } -+ -+ /* Hash Mode is global. Make sure the same Hash Mode -+ * is set to all the 4 possible lag. -+ * If we are the unique LAG we can set whatever hash -+ * mode we want. -+ * To change hash mode it's needed to remove all LAG -+ * and change the mode with the latest. -+ */ -+ if (unique_lag) { -+ priv->lag_hash_mode = hash; -+ } else if (priv->lag_hash_mode != hash) { -+ netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, -+ QCA8K_TRUNK_HASH_MASK, hash); -+} -+ -+static int -+qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, -+ struct net_device *lag, bool delete) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret, id, i; -+ u32 val; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ -+ /* Read current port member */ -+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); -+ if (ret) -+ return ret; -+ -+ /* Shift val to the correct trunk */ -+ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); -+ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; -+ if (delete) -+ val &= ~BIT(port); -+ else -+ val |= BIT(port); -+ -+ /* Update port member. With empty portmap disable trunk */ -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, -+ QCA8K_REG_GOL_TRUNK_MEMBER(id) | -+ QCA8K_REG_GOL_TRUNK_EN(id), -+ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | -+ val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); -+ -+ /* Search empty member if adding or port on deleting */ -+ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { -+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); -+ if (ret) -+ return ret; -+ -+ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); -+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; -+ -+ if (delete) { -+ /* If port flagged to be disabled assume this member is -+ * empty -+ */ -+ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -+ continue; -+ -+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; -+ if (val != port) -+ continue; -+ } else { -+ /* If port flagged to be enabled assume this member is -+ * already set -+ */ -+ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -+ continue; -+ } -+ -+ /* We have found the member to add/remove */ -+ break; -+ } -+ -+ /* Set port in the correct port mask or disable port if in delete mode */ -+ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), -+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | -+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), -+ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | -+ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); -+} -+ -+static int -+qca8k_port_lag_join(struct dsa_switch *ds, int port, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ int ret; -+ -+ if (!qca8k_lag_can_offload(ds, lag, info)) -+ return -EOPNOTSUPP; -+ -+ ret = qca8k_lag_setup_hash(ds, lag, info); -+ if (ret) -+ return ret; -+ -+ return qca8k_lag_refresh_portmap(ds, port, lag, false); -+} -+ -+static int -+qca8k_port_lag_leave(struct dsa_switch *ds, int port, -+ struct net_device *lag) -+{ -+ return qca8k_lag_refresh_portmap(ds, port, lag, true); -+} -+ -+static void -+qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, -+ bool operational) -+{ -+ struct dsa_port *dp = master->dsa_ptr; -+ struct qca8k_priv *priv = ds->priv; -+ -+ /* Ethernet MIB/MDIO is only supported for CPU port 0 */ -+ if (dp->index != 0) -+ return; -+ -+ mutex_lock(&priv->mgmt_eth_data.mutex); -+ mutex_lock(&priv->mib_eth_data.mutex); -+ -+ priv->mgmt_master = operational ? (struct net_device *)master : NULL; -+ -+ mutex_unlock(&priv->mib_eth_data.mutex); -+ mutex_unlock(&priv->mgmt_eth_data.mutex); -+} -+ -+static int qca8k_connect_tag_protocol(struct dsa_switch *ds, -+ enum dsa_tag_protocol proto) -+{ -+ struct qca_tagger_data *tagger_data; -+ -+ switch (proto) { -+ case DSA_TAG_PROTO_QCA: -+ tagger_data = ds->tagger_data; -+ -+ tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; -+ tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler; -+ -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static const struct dsa_switch_ops qca8k_switch_ops = { -+ .get_tag_protocol = qca8k_get_tag_protocol, -+ .setup = qca8k_setup, -+ .get_strings = qca8k_get_strings, -+ .get_ethtool_stats = qca8k_get_ethtool_stats, -+ .get_sset_count = qca8k_get_sset_count, -+ .set_ageing_time = qca8k_set_ageing_time, -+ .get_mac_eee = qca8k_get_mac_eee, -+ .set_mac_eee = qca8k_set_mac_eee, -+ .port_enable = qca8k_port_enable, -+ .port_disable = qca8k_port_disable, -+ .port_change_mtu = qca8k_port_change_mtu, -+ .port_max_mtu = qca8k_port_max_mtu, -+ .port_stp_state_set = qca8k_port_stp_state_set, -+ .port_bridge_join = qca8k_port_bridge_join, -+ .port_bridge_leave = qca8k_port_bridge_leave, -+ .port_fast_age = qca8k_port_fast_age, -+ .port_fdb_add = qca8k_port_fdb_add, -+ .port_fdb_del = qca8k_port_fdb_del, -+ .port_fdb_dump = qca8k_port_fdb_dump, -+ .port_mdb_add = qca8k_port_mdb_add, -+ .port_mdb_del = qca8k_port_mdb_del, -+ .port_mirror_add = qca8k_port_mirror_add, -+ .port_mirror_del = qca8k_port_mirror_del, -+ .port_vlan_filtering = qca8k_port_vlan_filtering, -+ .port_vlan_add = qca8k_port_vlan_add, -+ .port_vlan_del = qca8k_port_vlan_del, -+ .phylink_validate = qca8k_phylink_validate, -+ .phylink_mac_link_state = qca8k_phylink_mac_link_state, -+ .phylink_mac_config = qca8k_phylink_mac_config, -+ .phylink_mac_link_down = qca8k_phylink_mac_link_down, -+ .phylink_mac_link_up = qca8k_phylink_mac_link_up, -+ .get_phy_flags = qca8k_get_phy_flags, -+ .port_lag_join = qca8k_port_lag_join, -+ .port_lag_leave = qca8k_port_lag_leave, -+ .master_state_change = qca8k_master_change, -+ .connect_tag_protocol = qca8k_connect_tag_protocol, -+}; -+ -+static int qca8k_read_switch_id(struct qca8k_priv *priv) -+{ -+ const struct qca8k_match_data *data; -+ u32 val; -+ u8 id; -+ int ret; -+ -+ /* get the switches ID from the compatible */ -+ data = of_device_get_match_data(priv->dev); -+ if (!data) -+ return -ENODEV; -+ -+ ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); -+ if (ret < 0) -+ return -ENODEV; -+ -+ id = QCA8K_MASK_CTRL_DEVICE_ID(val); -+ if (id != data->id) { -+ dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); -+ return -ENODEV; -+ } -+ -+ priv->switch_id = id; -+ -+ /* Save revision to communicate to the internal PHY driver */ -+ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); -+ -+ return 0; -+} -+ -+static int -+qca8k_sw_probe(struct mdio_device *mdiodev) -+{ -+ struct qca8k_priv *priv; -+ int ret; -+ -+ /* allocate the private data struct so that we can probe the switches -+ * ID register -+ */ -+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->bus = mdiodev->bus; -+ priv->dev = &mdiodev->dev; -+ -+ priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", -+ GPIOD_ASIS); -+ if (IS_ERR(priv->reset_gpio)) -+ return PTR_ERR(priv->reset_gpio); -+ -+ if (priv->reset_gpio) { -+ gpiod_set_value_cansleep(priv->reset_gpio, 1); -+ /* The active low duration must be greater than 10 ms -+ * and checkpatch.pl wants 20 ms. -+ */ -+ msleep(20); -+ gpiod_set_value_cansleep(priv->reset_gpio, 0); -+ } -+ -+ /* Start by setting up the register mapping */ -+ priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv, -+ &qca8k_regmap_config); -+ if (IS_ERR(priv->regmap)) { -+ dev_err(priv->dev, "regmap initialization failed"); -+ return PTR_ERR(priv->regmap); -+ } -+ -+ priv->mdio_cache.page = 0xffff; -+ priv->mdio_cache.lo = 0xffff; -+ priv->mdio_cache.hi = 0xffff; -+ -+ /* Check the detected switch id */ -+ ret = qca8k_read_switch_id(priv); -+ if (ret) -+ return ret; -+ -+ priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); -+ if (!priv->ds) -+ return -ENOMEM; -+ -+ mutex_init(&priv->mgmt_eth_data.mutex); -+ init_completion(&priv->mgmt_eth_data.rw_done); -+ -+ mutex_init(&priv->mib_eth_data.mutex); -+ init_completion(&priv->mib_eth_data.rw_done); -+ -+ priv->ds->dev = &mdiodev->dev; -+ priv->ds->num_ports = QCA8K_NUM_PORTS; -+ priv->ds->priv = priv; -+ priv->ds->ops = &qca8k_switch_ops; -+ mutex_init(&priv->reg_mutex); -+ dev_set_drvdata(&mdiodev->dev, priv); -+ -+ return dsa_register_switch(priv->ds); -+} -+ -+static void -+qca8k_sw_remove(struct mdio_device *mdiodev) -+{ -+ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); -+ int i; -+ -+ if (!priv) -+ return; -+ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) -+ qca8k_port_set_status(priv, i, 0); -+ -+ dsa_unregister_switch(priv->ds); -+ -+ dev_set_drvdata(&mdiodev->dev, NULL); -+} -+ -+static void qca8k_sw_shutdown(struct mdio_device *mdiodev) -+{ -+ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); -+ -+ if (!priv) -+ return; -+ -+ dsa_switch_shutdown(priv->ds); -+ -+ dev_set_drvdata(&mdiodev->dev, NULL); -+} -+ -+#ifdef CONFIG_PM_SLEEP -+static void -+qca8k_set_pm(struct qca8k_priv *priv, int enable) -+{ -+ int port; -+ -+ for (port = 0; port < QCA8K_NUM_PORTS; port++) { -+ /* Do not enable on resume if the port was -+ * disabled before. -+ */ -+ if (!(priv->port_enabled_map & BIT(port))) -+ continue; -+ -+ qca8k_port_set_status(priv, port, enable); -+ } -+} -+ -+static int qca8k_suspend(struct device *dev) -+{ -+ struct qca8k_priv *priv = dev_get_drvdata(dev); -+ -+ qca8k_set_pm(priv, 0); -+ -+ return dsa_switch_suspend(priv->ds); -+} -+ -+static int qca8k_resume(struct device *dev) -+{ -+ struct qca8k_priv *priv = dev_get_drvdata(dev); -+ -+ qca8k_set_pm(priv, 1); -+ -+ return dsa_switch_resume(priv->ds); -+} -+#endif /* CONFIG_PM_SLEEP */ -+ -+static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, -+ qca8k_suspend, qca8k_resume); -+ -+static const struct qca8k_match_data qca8327 = { -+ .id = QCA8K_ID_QCA8327, -+ .reduced_package = true, -+ .mib_count = QCA8K_QCA832X_MIB_COUNT, -+}; -+ -+static const struct qca8k_match_data qca8328 = { -+ .id = QCA8K_ID_QCA8327, -+ .mib_count = QCA8K_QCA832X_MIB_COUNT, -+}; -+ -+static const struct qca8k_match_data qca833x = { -+ .id = QCA8K_ID_QCA8337, -+ .mib_count = QCA8K_QCA833X_MIB_COUNT, -+}; -+ -+static const struct of_device_id qca8k_of_match[] = { -+ { .compatible = "qca,qca8327", .data = &qca8327 }, -+ { .compatible = "qca,qca8328", .data = &qca8328 }, -+ { .compatible = "qca,qca8334", .data = &qca833x }, -+ { .compatible = "qca,qca8337", .data = &qca833x }, -+ { /* sentinel */ }, -+}; -+ -+static struct mdio_driver qca8kmdio_driver = { -+ .probe = qca8k_sw_probe, -+ .remove = qca8k_sw_remove, -+ .shutdown = qca8k_sw_shutdown, -+ .mdiodrv.driver = { -+ .name = "qca8k", -+ .of_match_table = qca8k_of_match, -+ .pm = &qca8k_pm_ops, -+ }, -+}; -+ -+mdio_module_driver(qca8kmdio_driver); -+ -+MODULE_AUTHOR("Mathieu Olivari, John Crispin "); -+MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:qca8k"); ---- /dev/null -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -0,0 +1,411 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (C) 2009 Felix Fietkau -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (c) 2015, The Linux Foundation. All rights reserved. -+ */ -+ -+#ifndef __QCA8K_H -+#define __QCA8K_H -+ -+#include -+#include -+#include -+#include -+ -+#define QCA8K_ETHERNET_MDIO_PRIORITY 7 -+#define QCA8K_ETHERNET_PHY_PRIORITY 6 -+#define QCA8K_ETHERNET_TIMEOUT 100 -+ -+#define QCA8K_NUM_PORTS 7 -+#define QCA8K_NUM_CPU_PORTS 2 -+#define QCA8K_MAX_MTU 9000 -+#define QCA8K_NUM_LAGS 4 -+#define QCA8K_NUM_PORTS_FOR_LAG 4 -+ -+#define PHY_ID_QCA8327 0x004dd034 -+#define QCA8K_ID_QCA8327 0x12 -+#define PHY_ID_QCA8337 0x004dd036 -+#define QCA8K_ID_QCA8337 0x13 -+ -+#define QCA8K_QCA832X_MIB_COUNT 39 -+#define QCA8K_QCA833X_MIB_COUNT 41 -+ -+#define QCA8K_BUSY_WAIT_TIMEOUT 2000 -+ -+#define QCA8K_NUM_FDB_RECORDS 2048 -+ -+#define QCA8K_PORT_VID_DEF 1 -+ -+/* Global control registers */ -+#define QCA8K_REG_MASK_CTRL 0x000 -+#define QCA8K_MASK_CTRL_REV_ID_MASK GENMASK(7, 0) -+#define QCA8K_MASK_CTRL_REV_ID(x) FIELD_GET(QCA8K_MASK_CTRL_REV_ID_MASK, x) -+#define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8) -+#define QCA8K_MASK_CTRL_DEVICE_ID(x) FIELD_GET(QCA8K_MASK_CTRL_DEVICE_ID_MASK, x) -+#define QCA8K_REG_PORT0_PAD_CTRL 0x004 -+#define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31) -+#define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19) -+#define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18) -+#define QCA8K_REG_PORT5_PAD_CTRL 0x008 -+#define QCA8K_REG_PORT6_PAD_CTRL 0x00c -+#define QCA8K_PORT_PAD_RGMII_EN BIT(26) -+#define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22) -+#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, x) -+#define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20) -+#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, x) -+#define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25) -+#define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24) -+#define QCA8K_PORT_PAD_SGMII_EN BIT(7) -+#define QCA8K_REG_PWS 0x010 -+#define QCA8K_PWS_POWER_ON_SEL BIT(31) -+/* This reg is only valid for QCA832x and toggle the package -+ * type from 176 pin (by default) to 148 pin used on QCA8327 -+ */ -+#define QCA8327_PWS_PACKAGE148_EN BIT(30) -+#define QCA8K_PWS_LED_OPEN_EN_CSR BIT(24) -+#define QCA8K_PWS_SERDES_AEN_DIS BIT(7) -+#define QCA8K_REG_MODULE_EN 0x030 -+#define QCA8K_MODULE_EN_MIB BIT(0) -+#define QCA8K_REG_MIB 0x034 -+#define QCA8K_MIB_FUNC GENMASK(26, 24) -+#define QCA8K_MIB_CPU_KEEP BIT(20) -+#define QCA8K_MIB_BUSY BIT(17) -+#define QCA8K_MDIO_MASTER_CTRL 0x3c -+#define QCA8K_MDIO_MASTER_BUSY BIT(31) -+#define QCA8K_MDIO_MASTER_EN BIT(30) -+#define QCA8K_MDIO_MASTER_READ BIT(27) -+#define QCA8K_MDIO_MASTER_WRITE 0 -+#define QCA8K_MDIO_MASTER_SUP_PRE BIT(26) -+#define QCA8K_MDIO_MASTER_PHY_ADDR_MASK GENMASK(25, 21) -+#define QCA8K_MDIO_MASTER_PHY_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_PHY_ADDR_MASK, x) -+#define QCA8K_MDIO_MASTER_REG_ADDR_MASK GENMASK(20, 16) -+#define QCA8K_MDIO_MASTER_REG_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_REG_ADDR_MASK, x) -+#define QCA8K_MDIO_MASTER_DATA_MASK GENMASK(15, 0) -+#define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) -+#define QCA8K_MDIO_MASTER_MAX_PORTS 5 -+#define QCA8K_MDIO_MASTER_MAX_REG 32 -+#define QCA8K_GOL_MAC_ADDR0 0x60 -+#define QCA8K_GOL_MAC_ADDR1 0x64 -+#define QCA8K_MAX_FRAME_SIZE 0x78 -+#define QCA8K_REG_PORT_STATUS(_i) (0x07c + (_i) * 4) -+#define QCA8K_PORT_STATUS_SPEED GENMASK(1, 0) -+#define QCA8K_PORT_STATUS_SPEED_10 0 -+#define QCA8K_PORT_STATUS_SPEED_100 0x1 -+#define QCA8K_PORT_STATUS_SPEED_1000 0x2 -+#define QCA8K_PORT_STATUS_TXMAC BIT(2) -+#define QCA8K_PORT_STATUS_RXMAC BIT(3) -+#define QCA8K_PORT_STATUS_TXFLOW BIT(4) -+#define QCA8K_PORT_STATUS_RXFLOW BIT(5) -+#define QCA8K_PORT_STATUS_DUPLEX BIT(6) -+#define QCA8K_PORT_STATUS_LINK_UP BIT(8) -+#define QCA8K_PORT_STATUS_LINK_AUTO BIT(9) -+#define QCA8K_PORT_STATUS_LINK_PAUSE BIT(10) -+#define QCA8K_PORT_STATUS_FLOW_AUTO BIT(12) -+#define QCA8K_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4)) -+#define QCA8K_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2) -+#define QCA8K_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0) -+#define QCA8K_PORT_HDR_CTRL_ALL 2 -+#define QCA8K_PORT_HDR_CTRL_MGMT 1 -+#define QCA8K_PORT_HDR_CTRL_NONE 0 -+#define QCA8K_REG_SGMII_CTRL 0x0e0 -+#define QCA8K_SGMII_EN_PLL BIT(1) -+#define QCA8K_SGMII_EN_RX BIT(2) -+#define QCA8K_SGMII_EN_TX BIT(3) -+#define QCA8K_SGMII_EN_SD BIT(4) -+#define QCA8K_SGMII_CLK125M_DELAY BIT(7) -+#define QCA8K_SGMII_MODE_CTRL_MASK GENMASK(23, 22) -+#define QCA8K_SGMII_MODE_CTRL(x) FIELD_PREP(QCA8K_SGMII_MODE_CTRL_MASK, x) -+#define QCA8K_SGMII_MODE_CTRL_BASEX QCA8K_SGMII_MODE_CTRL(0x0) -+#define QCA8K_SGMII_MODE_CTRL_PHY QCA8K_SGMII_MODE_CTRL(0x1) -+#define QCA8K_SGMII_MODE_CTRL_MAC QCA8K_SGMII_MODE_CTRL(0x2) -+ -+/* MAC_PWR_SEL registers */ -+#define QCA8K_REG_MAC_PWR_SEL 0x0e4 -+#define QCA8K_MAC_PWR_RGMII1_1_8V BIT(18) -+#define QCA8K_MAC_PWR_RGMII0_1_8V BIT(19) -+ -+/* EEE control registers */ -+#define QCA8K_REG_EEE_CTRL 0x100 -+#define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2) -+ -+/* TRUNK_HASH_EN registers */ -+#define QCA8K_TRUNK_HASH_EN_CTRL 0x270 -+#define QCA8K_TRUNK_HASH_SIP_EN BIT(3) -+#define QCA8K_TRUNK_HASH_DIP_EN BIT(2) -+#define QCA8K_TRUNK_HASH_SA_EN BIT(1) -+#define QCA8K_TRUNK_HASH_DA_EN BIT(0) -+#define QCA8K_TRUNK_HASH_MASK GENMASK(3, 0) -+ -+/* ACL registers */ -+#define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8)) -+#define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16) -+#define QCA8K_PORT_VLAN_CVID(x) FIELD_PREP(QCA8K_PORT_VLAN_CVID_MASK, x) -+#define QCA8K_PORT_VLAN_SVID_MASK GENMASK(11, 0) -+#define QCA8K_PORT_VLAN_SVID(x) FIELD_PREP(QCA8K_PORT_VLAN_SVID_MASK, x) -+#define QCA8K_REG_PORT_VLAN_CTRL1(_i) (0x424 + (_i * 8)) -+#define QCA8K_REG_IPV4_PRI_BASE_ADDR 0x470 -+#define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474 -+ -+/* Lookup registers */ -+#define QCA8K_REG_ATU_DATA0 0x600 -+#define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24) -+#define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16) -+#define QCA8K_ATU_ADDR4_MASK GENMASK(15, 8) -+#define QCA8K_ATU_ADDR5_MASK GENMASK(7, 0) -+#define QCA8K_REG_ATU_DATA1 0x604 -+#define QCA8K_ATU_PORT_MASK GENMASK(22, 16) -+#define QCA8K_ATU_ADDR0_MASK GENMASK(15, 8) -+#define QCA8K_ATU_ADDR1_MASK GENMASK(7, 0) -+#define QCA8K_REG_ATU_DATA2 0x608 -+#define QCA8K_ATU_VID_MASK GENMASK(19, 8) -+#define QCA8K_ATU_STATUS_MASK GENMASK(3, 0) -+#define QCA8K_ATU_STATUS_STATIC 0xf -+#define QCA8K_REG_ATU_FUNC 0x60c -+#define QCA8K_ATU_FUNC_BUSY BIT(31) -+#define QCA8K_ATU_FUNC_PORT_EN BIT(14) -+#define QCA8K_ATU_FUNC_MULTI_EN BIT(13) -+#define QCA8K_ATU_FUNC_FULL BIT(12) -+#define QCA8K_ATU_FUNC_PORT_MASK GENMASK(11, 8) -+#define QCA8K_REG_VTU_FUNC0 0x610 -+#define QCA8K_VTU_FUNC0_VALID BIT(20) -+#define QCA8K_VTU_FUNC0_IVL_EN BIT(19) -+/* QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(17, 4) -+ * It does contain VLAN_MODE for each port [5:4] for port0, -+ * [7:6] for port1 ... [17:16] for port6. Use virtual port -+ * define to handle this. -+ */ -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i) (4 + (_i) * 2) -+#define QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(1, 0) -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(_i) (GENMASK(1, 0) << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) -+#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x0) -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNMOD(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNMOD << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) -+#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x1) -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNTAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) -+#define QCA8K_VTU_FUNC0_EG_MODE_TAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x2) -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_TAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) -+#define QCA8K_VTU_FUNC0_EG_MODE_NOT FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x3) -+#define QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(_i) (QCA8K_VTU_FUNC0_EG_MODE_NOT << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) -+#define QCA8K_REG_VTU_FUNC1 0x614 -+#define QCA8K_VTU_FUNC1_BUSY BIT(31) -+#define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16) -+#define QCA8K_VTU_FUNC1_FULL BIT(4) -+#define QCA8K_REG_ATU_CTRL 0x618 -+#define QCA8K_ATU_AGE_TIME_MASK GENMASK(15, 0) -+#define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x)) -+#define QCA8K_REG_GLOBAL_FW_CTRL0 0x620 -+#define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) -+#define QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM GENMASK(7, 4) -+#define QCA8K_REG_GLOBAL_FW_CTRL1 0x624 -+#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24) -+#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16) -+#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8) -+#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0) -+#define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc) -+#define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE_MASK GENMASK(9, 8) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, x) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE QCA8K_PORT_LOOKUP_VLAN_MODE(0x0) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK QCA8K_PORT_LOOKUP_VLAN_MODE(0x1) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK QCA8K_PORT_LOOKUP_VLAN_MODE(0x2) -+#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE QCA8K_PORT_LOOKUP_VLAN_MODE(0x3) -+#define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16) -+#define QCA8K_PORT_LOOKUP_STATE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_STATE_MASK, x) -+#define QCA8K_PORT_LOOKUP_STATE_DISABLED QCA8K_PORT_LOOKUP_STATE(0x0) -+#define QCA8K_PORT_LOOKUP_STATE_BLOCKING QCA8K_PORT_LOOKUP_STATE(0x1) -+#define QCA8K_PORT_LOOKUP_STATE_LISTENING QCA8K_PORT_LOOKUP_STATE(0x2) -+#define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3) -+#define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4) -+#define QCA8K_PORT_LOOKUP_LEARN BIT(20) -+#define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25) -+ -+#define QCA8K_REG_GOL_TRUNK_CTRL0 0x700 -+/* 4 max trunk first -+ * first 6 bit for member bitmap -+ * 7th bit is to enable trunk port -+ */ -+#define QCA8K_REG_GOL_TRUNK_SHIFT(_i) ((_i) * 8) -+#define QCA8K_REG_GOL_TRUNK_EN_MASK BIT(7) -+#define QCA8K_REG_GOL_TRUNK_EN(_i) (QCA8K_REG_GOL_TRUNK_EN_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) -+#define QCA8K_REG_GOL_TRUNK_MEMBER_MASK GENMASK(6, 0) -+#define QCA8K_REG_GOL_TRUNK_MEMBER(_i) (QCA8K_REG_GOL_TRUNK_MEMBER_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) -+/* 0x704 for TRUNK 0-1 --- 0x708 for TRUNK 2-3 */ -+#define QCA8K_REG_GOL_TRUNK_CTRL(_i) (0x704 + (((_i) / 2) * 4)) -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK GENMASK(3, 0) -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK BIT(3) -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK GENMASK(2, 0) -+#define QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i) (((_i) / 2) * 16) -+#define QCA8K_REG_GOL_MEM_ID_SHIFT(_i) ((_i) * 4) -+/* Complex shift: FIRST shift for port THEN shift for trunk */ -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j) (QCA8K_REG_GOL_MEM_ID_SHIFT(_j) + QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i)) -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) -+#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) -+ -+#define QCA8K_REG_GLOBAL_FC_THRESH 0x800 -+#define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16) -+#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x) -+#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK GENMASK(8, 0) -+#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, x) -+ -+#define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK GENMASK(3, 0) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK GENMASK(7, 4) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK GENMASK(11, 8) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK GENMASK(15, 12) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK GENMASK(19, 16) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK GENMASK(23, 20) -+#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK GENMASK(29, 24) -+#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK, x) -+ -+#define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8) -+#define QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK GENMASK(3, 0) -+#define QCA8K_PORT_HOL_CTRL1_ING(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK, x) -+#define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6) -+#define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7) -+#define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8) -+#define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16) -+ -+/* Pkt edit registers */ -+#define QCA8K_EGREES_VLAN_PORT_SHIFT(_i) (16 * ((_i) % 2)) -+#define QCA8K_EGREES_VLAN_PORT_MASK(_i) (GENMASK(11, 0) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) -+#define QCA8K_EGREES_VLAN_PORT(_i, x) ((x) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) -+#define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2))) -+ -+/* L3 registers */ -+#define QCA8K_HROUTER_CONTROL 0xe00 -+#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_M GENMASK(17, 16) -+#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_S 16 -+#define QCA8K_HROUTER_CONTROL_ARP_AGE_MODE 1 -+#define QCA8K_HROUTER_PBASED_CONTROL1 0xe08 -+#define QCA8K_HROUTER_PBASED_CONTROL2 0xe0c -+#define QCA8K_HNAT_CONTROL 0xe38 -+ -+/* MIB registers */ -+#define QCA8K_PORT_MIB_COUNTER(_i) (0x1000 + (_i) * 0x100) -+ -+/* QCA specific MII registers */ -+#define MII_ATH_MMD_ADDR 0x0d -+#define MII_ATH_MMD_DATA 0x0e -+ -+enum { -+ QCA8K_PORT_SPEED_10M = 0, -+ QCA8K_PORT_SPEED_100M = 1, -+ QCA8K_PORT_SPEED_1000M = 2, -+ QCA8K_PORT_SPEED_ERR = 3, -+}; -+ -+enum qca8k_fdb_cmd { -+ QCA8K_FDB_FLUSH = 1, -+ QCA8K_FDB_LOAD = 2, -+ QCA8K_FDB_PURGE = 3, -+ QCA8K_FDB_FLUSH_PORT = 5, -+ QCA8K_FDB_NEXT = 6, -+ QCA8K_FDB_SEARCH = 7, -+}; -+ -+enum qca8k_vlan_cmd { -+ QCA8K_VLAN_FLUSH = 1, -+ QCA8K_VLAN_LOAD = 2, -+ QCA8K_VLAN_PURGE = 3, -+ QCA8K_VLAN_REMOVE_PORT = 4, -+ QCA8K_VLAN_NEXT = 5, -+ QCA8K_VLAN_READ = 6, -+}; -+ -+enum qca8k_mid_cmd { -+ QCA8K_MIB_FLUSH = 1, -+ QCA8K_MIB_FLUSH_PORT = 2, -+ QCA8K_MIB_CAST = 3, -+}; -+ -+struct qca8k_match_data { -+ u8 id; -+ bool reduced_package; -+ u8 mib_count; -+}; -+ -+enum { -+ QCA8K_CPU_PORT0, -+ QCA8K_CPU_PORT6, -+}; -+ -+struct qca8k_mgmt_eth_data { -+ struct completion rw_done; -+ struct mutex mutex; /* Enforce one mdio read/write at time */ -+ bool ack; -+ u32 seq; -+ u32 data[4]; -+}; -+ -+struct qca8k_mib_eth_data { -+ struct completion rw_done; -+ struct mutex mutex; /* Process one command at time */ -+ refcount_t port_parsed; /* Counter to track parsed port */ -+ u8 req_port; -+ u64 *data; /* pointer to ethtool data */ -+}; -+ -+struct qca8k_ports_config { -+ bool sgmii_rx_clk_falling_edge; -+ bool sgmii_tx_clk_falling_edge; -+ bool sgmii_enable_pll; -+ u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ -+ u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ -+}; -+ -+struct qca8k_mdio_cache { -+/* The 32bit switch registers are accessed indirectly. To achieve this we need -+ * to set the page of the register. Track the last page that was set to reduce -+ * mdio writes -+ */ -+ u16 page; -+/* lo and hi can also be cached and from Documentation we can skip one -+ * extra mdio write if lo or hi is didn't change. -+ */ -+ u16 lo; -+ u16 hi; -+}; -+ -+struct qca8k_priv { -+ u8 switch_id; -+ u8 switch_revision; -+ u8 mirror_rx; -+ u8 mirror_tx; -+ u8 lag_hash_mode; -+ /* Each bit correspond to a port. This switch can support a max of 7 port. -+ * Bit 1: port enabled. Bit 0: port disabled. -+ */ -+ u8 port_enabled_map; -+ struct qca8k_ports_config ports_config; -+ struct regmap *regmap; -+ struct mii_bus *bus; -+ struct dsa_switch *ds; -+ struct mutex reg_mutex; -+ struct device *dev; -+ struct gpio_desc *reset_gpio; -+ struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ -+ struct qca8k_mgmt_eth_data mgmt_eth_data; -+ struct qca8k_mib_eth_data mib_eth_data; -+ struct qca8k_mdio_cache mdio_cache; -+}; -+ -+struct qca8k_mib_desc { -+ unsigned int size; -+ unsigned int offset; -+ const char *name; -+}; -+ -+struct qca8k_fdb { -+ u16 vid; -+ u8 port_mask; -+ u8 aging; -+ u8 mac[6]; -+}; -+ -+#endif /* __QCA8K_H */ ---- a/drivers/net/dsa/qca8k.c -+++ /dev/null -@@ -1,3243 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2009 Felix Fietkau -- * Copyright (C) 2011-2012 Gabor Juhos -- * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. -- * Copyright (c) 2016 John Crispin -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "qca8k.h" -- --#define MIB_DESC(_s, _o, _n) \ -- { \ -- .size = (_s), \ -- .offset = (_o), \ -- .name = (_n), \ -- } -- --static const struct qca8k_mib_desc ar8327_mib[] = { -- MIB_DESC(1, 0x00, "RxBroad"), -- MIB_DESC(1, 0x04, "RxPause"), -- MIB_DESC(1, 0x08, "RxMulti"), -- MIB_DESC(1, 0x0c, "RxFcsErr"), -- MIB_DESC(1, 0x10, "RxAlignErr"), -- MIB_DESC(1, 0x14, "RxRunt"), -- MIB_DESC(1, 0x18, "RxFragment"), -- MIB_DESC(1, 0x1c, "Rx64Byte"), -- MIB_DESC(1, 0x20, "Rx128Byte"), -- MIB_DESC(1, 0x24, "Rx256Byte"), -- MIB_DESC(1, 0x28, "Rx512Byte"), -- MIB_DESC(1, 0x2c, "Rx1024Byte"), -- MIB_DESC(1, 0x30, "Rx1518Byte"), -- MIB_DESC(1, 0x34, "RxMaxByte"), -- MIB_DESC(1, 0x38, "RxTooLong"), -- MIB_DESC(2, 0x3c, "RxGoodByte"), -- MIB_DESC(2, 0x44, "RxBadByte"), -- MIB_DESC(1, 0x4c, "RxOverFlow"), -- MIB_DESC(1, 0x50, "Filtered"), -- MIB_DESC(1, 0x54, "TxBroad"), -- MIB_DESC(1, 0x58, "TxPause"), -- MIB_DESC(1, 0x5c, "TxMulti"), -- MIB_DESC(1, 0x60, "TxUnderRun"), -- MIB_DESC(1, 0x64, "Tx64Byte"), -- MIB_DESC(1, 0x68, "Tx128Byte"), -- MIB_DESC(1, 0x6c, "Tx256Byte"), -- MIB_DESC(1, 0x70, "Tx512Byte"), -- MIB_DESC(1, 0x74, "Tx1024Byte"), -- MIB_DESC(1, 0x78, "Tx1518Byte"), -- MIB_DESC(1, 0x7c, "TxMaxByte"), -- MIB_DESC(1, 0x80, "TxOverSize"), -- MIB_DESC(2, 0x84, "TxByte"), -- MIB_DESC(1, 0x8c, "TxCollision"), -- MIB_DESC(1, 0x90, "TxAbortCol"), -- MIB_DESC(1, 0x94, "TxMultiCol"), -- MIB_DESC(1, 0x98, "TxSingleCol"), -- MIB_DESC(1, 0x9c, "TxExcDefer"), -- MIB_DESC(1, 0xa0, "TxDefer"), -- MIB_DESC(1, 0xa4, "TxLateCol"), -- MIB_DESC(1, 0xa8, "RXUnicast"), -- MIB_DESC(1, 0xac, "TXUnicast"), --}; -- --static void --qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) --{ -- regaddr >>= 1; -- *r1 = regaddr & 0x1e; -- -- regaddr >>= 5; -- *r2 = regaddr & 0x7; -- -- regaddr >>= 3; -- *page = regaddr & 0x3ff; --} -- --static int --qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo) --{ -- u16 *cached_lo = &priv->mdio_cache.lo; -- struct mii_bus *bus = priv->bus; -- int ret; -- -- if (lo == *cached_lo) -- return 0; -- -- ret = bus->write(bus, phy_id, regnum, lo); -- if (ret < 0) -- dev_err_ratelimited(&bus->dev, -- "failed to write qca8k 32bit lo register\n"); -- -- *cached_lo = lo; -- return 0; --} -- --static int --qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi) --{ -- u16 *cached_hi = &priv->mdio_cache.hi; -- struct mii_bus *bus = priv->bus; -- int ret; -- -- if (hi == *cached_hi) -- return 0; -- -- ret = bus->write(bus, phy_id, regnum, hi); -- if (ret < 0) -- dev_err_ratelimited(&bus->dev, -- "failed to write qca8k 32bit hi register\n"); -- -- *cached_hi = hi; -- return 0; --} -- --static int --qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) --{ -- int ret; -- -- ret = bus->read(bus, phy_id, regnum); -- if (ret >= 0) { -- *val = ret; -- ret = bus->read(bus, phy_id, regnum + 1); -- *val |= ret << 16; -- } -- -- if (ret < 0) { -- dev_err_ratelimited(&bus->dev, -- "failed to read qca8k 32bit register\n"); -- *val = 0; -- return ret; -- } -- -- return 0; --} -- --static void --qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val) --{ -- u16 lo, hi; -- int ret; -- -- lo = val & 0xffff; -- hi = (u16)(val >> 16); -- -- ret = qca8k_set_lo(priv, phy_id, regnum, lo); -- if (ret >= 0) -- ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi); --} -- --static int --qca8k_set_page(struct qca8k_priv *priv, u16 page) --{ -- u16 *cached_page = &priv->mdio_cache.page; -- struct mii_bus *bus = priv->bus; -- int ret; -- -- if (page == *cached_page) -- return 0; -- -- ret = bus->write(bus, 0x18, 0, page); -- if (ret < 0) { -- dev_err_ratelimited(&bus->dev, -- "failed to set qca8k page\n"); -- return ret; -- } -- -- *cached_page = page; -- usleep_range(1000, 2000); -- return 0; --} -- --static int --qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) --{ -- return regmap_read(priv->regmap, reg, val); --} -- --static int --qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) --{ -- return regmap_write(priv->regmap, reg, val); --} -- --static int --qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) --{ -- return regmap_update_bits(priv->regmap, reg, mask, write_val); --} -- --static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) --{ -- struct qca8k_mgmt_eth_data *mgmt_eth_data; -- struct qca8k_priv *priv = ds->priv; -- struct qca_mgmt_ethhdr *mgmt_ethhdr; -- u8 len, cmd; -- -- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); -- mgmt_eth_data = &priv->mgmt_eth_data; -- -- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); -- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); -- -- /* Make sure the seq match the requested packet */ -- if (mgmt_ethhdr->seq == mgmt_eth_data->seq) -- mgmt_eth_data->ack = true; -- -- if (cmd == MDIO_READ) { -- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; -- -- /* Get the rest of the 12 byte of data. -- * The read/write function will extract the requested data. -- */ -- if (len > QCA_HDR_MGMT_DATA1_LEN) -- memcpy(mgmt_eth_data->data + 1, skb->data, -- QCA_HDR_MGMT_DATA2_LEN); -- } -- -- complete(&mgmt_eth_data->rw_done); --} -- --static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val, -- int priority, unsigned int len) --{ -- struct qca_mgmt_ethhdr *mgmt_ethhdr; -- unsigned int real_len; -- struct sk_buff *skb; -- u32 *data2; -- u16 hdr; -- -- skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); -- if (!skb) -- return NULL; -- -- /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte -- * Actually for some reason the steps are: -- * 0: nothing -- * 1-4: first 4 byte -- * 5-6: first 12 byte -- * 7-15: all 16 byte -- */ -- if (len == 16) -- real_len = 15; -- else -- real_len = len; -- -- skb_reset_mac_header(skb); -- skb_set_network_header(skb, skb->len); -- -- mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); -- -- hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); -- hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority); -- hdr |= QCA_HDR_XMIT_FROM_CPU; -- hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); -- hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); -- -- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); -- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); -- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); -- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, -- QCA_HDR_MGMT_CHECK_CODE_VAL); -- -- if (cmd == MDIO_WRITE) -- mgmt_ethhdr->mdio_data = *val; -- -- mgmt_ethhdr->hdr = htons(hdr); -- -- data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); -- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) -- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); -- -- return skb; --} -- --static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) --{ -- struct qca_mgmt_ethhdr *mgmt_ethhdr; -- -- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; -- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); --} -- --static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; -- struct sk_buff *skb; -- bool ack; -- int ret; -- -- skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL, -- QCA8K_ETHERNET_MDIO_PRIORITY, len); -- if (!skb) -- return -ENOMEM; -- -- mutex_lock(&mgmt_eth_data->mutex); -- -- /* Check mgmt_master if is operational */ -- if (!priv->mgmt_master) { -- kfree_skb(skb); -- mutex_unlock(&mgmt_eth_data->mutex); -- return -EINVAL; -- } -- -- skb->dev = priv->mgmt_master; -- -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the mdio pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(skb); -- -- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); -- -- *val = mgmt_eth_data->data[0]; -- if (len > QCA_HDR_MGMT_DATA1_LEN) -- memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN); -- -- ack = mgmt_eth_data->ack; -- -- mutex_unlock(&mgmt_eth_data->mutex); -- -- if (ret <= 0) -- return -ETIMEDOUT; -- -- if (!ack) -- return -EINVAL; -- -- return 0; --} -- --static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; -- struct sk_buff *skb; -- bool ack; -- int ret; -- -- skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val, -- QCA8K_ETHERNET_MDIO_PRIORITY, len); -- if (!skb) -- return -ENOMEM; -- -- mutex_lock(&mgmt_eth_data->mutex); -- -- /* Check mgmt_master if is operational */ -- if (!priv->mgmt_master) { -- kfree_skb(skb); -- mutex_unlock(&mgmt_eth_data->mutex); -- return -EINVAL; -- } -- -- skb->dev = priv->mgmt_master; -- -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the mdio pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(skb); -- -- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); -- -- ack = mgmt_eth_data->ack; -- -- mutex_unlock(&mgmt_eth_data->mutex); -- -- if (ret <= 0) -- return -ETIMEDOUT; -- -- if (!ack) -- return -EINVAL; -- -- return 0; --} -- --static int --qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) --{ -- u32 val = 0; -- int ret; -- -- ret = qca8k_read_eth(priv, reg, &val, sizeof(val)); -- if (ret) -- return ret; -- -- val &= ~mask; -- val |= write_val; -- -- return qca8k_write_eth(priv, reg, &val, sizeof(val)); --} -- --static int --qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- int i, count = len / sizeof(u32), ret; -- -- if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) -- return 0; -- -- for (i = 0; i < count; i++) { -- ret = regmap_read(priv->regmap, reg + (i * 4), val + i); -- if (ret < 0) -- return ret; -- } -- -- return 0; --} -- --static int --qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- int i, count = len / sizeof(u32), ret; -- u32 tmp; -- -- if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) -- return 0; -- -- for (i = 0; i < count; i++) { -- tmp = val[i]; -- -- ret = regmap_write(priv->regmap, reg + (i * 4), tmp); -- if (ret < 0) -- return ret; -- } -- -- return 0; --} -- --static int --qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -- struct mii_bus *bus = priv->bus; -- u16 r1, r2, page; -- int ret; -- -- if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) -- return 0; -- -- qca8k_split_addr(reg, &r1, &r2, &page); -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -- -- ret = qca8k_set_page(priv, page); -- if (ret < 0) -- goto exit; -- -- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val); -- --exit: -- mutex_unlock(&bus->mdio_lock); -- return ret; --} -- --static int --qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -- struct mii_bus *bus = priv->bus; -- u16 r1, r2, page; -- int ret; -- -- if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) -- return 0; -- -- qca8k_split_addr(reg, &r1, &r2, &page); -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -- -- ret = qca8k_set_page(priv, page); -- if (ret < 0) -- goto exit; -- -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -- --exit: -- mutex_unlock(&bus->mdio_lock); -- return ret; --} -- --static int --qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -- struct mii_bus *bus = priv->bus; -- u16 r1, r2, page; -- u32 val; -- int ret; -- -- if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) -- return 0; -- -- qca8k_split_addr(reg, &r1, &r2, &page); -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -- -- ret = qca8k_set_page(priv, page); -- if (ret < 0) -- goto exit; -- -- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); -- if (ret < 0) -- goto exit; -- -- val &= ~mask; -- val |= write_val; -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -- --exit: -- mutex_unlock(&bus->mdio_lock); -- -- return ret; --} -- --static const struct regmap_range qca8k_readable_ranges[] = { -- regmap_reg_range(0x0000, 0x00e4), /* Global control */ -- regmap_reg_range(0x0100, 0x0168), /* EEE control */ -- regmap_reg_range(0x0200, 0x0270), /* Parser control */ -- regmap_reg_range(0x0400, 0x0454), /* ACL */ -- regmap_reg_range(0x0600, 0x0718), /* Lookup */ -- regmap_reg_range(0x0800, 0x0b70), /* QM */ -- regmap_reg_range(0x0c00, 0x0c80), /* PKT */ -- regmap_reg_range(0x0e00, 0x0e98), /* L3 */ -- regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ -- regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ -- regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ -- regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ -- regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ -- regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ -- regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ -- --}; -- --static const struct regmap_access_table qca8k_readable_table = { -- .yes_ranges = qca8k_readable_ranges, -- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), --}; -- --static struct regmap_config qca8k_regmap_config = { -- .reg_bits = 16, -- .val_bits = 32, -- .reg_stride = 4, -- .max_register = 0x16ac, /* end MIB - Port6 range */ -- .reg_read = qca8k_regmap_read, -- .reg_write = qca8k_regmap_write, -- .reg_update_bits = qca8k_regmap_update_bits, -- .rd_table = &qca8k_readable_table, -- .disable_locking = true, /* Locking is handled by qca8k read/write */ -- .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ --}; -- --static int --qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) --{ -- u32 val; -- -- return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, -- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); --} -- --static int --qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) --{ -- u32 reg[3]; -- int ret; -- -- /* load the ARL table into an array */ -- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -- if (ret) -- return ret; -- -- /* vid - 83:72 */ -- fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); -- /* aging - 67:64 */ -- fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); -- /* portmask - 54:48 */ -- fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); -- /* mac - 47:0 */ -- fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); -- fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); -- fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); -- fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); -- fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); -- fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); -- -- return 0; --} -- --static void --qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, -- u8 aging) --{ -- u32 reg[3] = { 0 }; -- -- /* vid - 83:72 */ -- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); -- /* aging - 67:64 */ -- reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); -- /* portmask - 54:48 */ -- reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); -- /* mac - 47:0 */ -- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); -- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); -- -- /* load the array into the ARL table */ -- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); --} -- --static int --qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) --{ -- u32 reg; -- int ret; -- -- /* Set the command and FDB index */ -- reg = QCA8K_ATU_FUNC_BUSY; -- reg |= cmd; -- if (port >= 0) { -- reg |= QCA8K_ATU_FUNC_PORT_EN; -- reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); -- } -- -- /* Write the function register triggering the table access */ -- ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); -- if (ret) -- return ret; -- -- /* wait for completion */ -- ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); -- if (ret) -- return ret; -- -- /* Check for table full violation when adding an entry */ -- if (cmd == QCA8K_FDB_LOAD) { -- ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); -- if (ret < 0) -- return ret; -- if (reg & QCA8K_ATU_FUNC_FULL) -- return -1; -- } -- -- return 0; --} -- --static int --qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) --{ -- int ret; -- -- qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); -- if (ret < 0) -- return ret; -- -- return qca8k_fdb_read(priv, fdb); --} -- --static int --qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, -- u16 vid, u8 aging) --{ -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_write(priv, vid, port_mask, mac, aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static int --qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) --{ -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_write(priv, vid, port_mask, mac, 0); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static void --qca8k_fdb_flush(struct qca8k_priv *priv) --{ -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); -- mutex_unlock(&priv->reg_mutex); --} -- --static int --qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, -- const u8 *mac, u16 vid) --{ -- struct qca8k_fdb fdb = { 0 }; -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- -- qca8k_fdb_write(priv, vid, 0, mac, 0); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -- if (ret < 0) -- goto exit; -- -- ret = qca8k_fdb_read(priv, &fdb); -- if (ret < 0) -- goto exit; -- -- /* Rule exist. Delete first */ -- if (!fdb.aging) { -- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -- if (ret) -- goto exit; -- } -- -- /* Add port to fdb portmask */ -- fdb.port_mask |= port_mask; -- -- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static int --qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, -- const u8 *mac, u16 vid) --{ -- struct qca8k_fdb fdb = { 0 }; -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- -- qca8k_fdb_write(priv, vid, 0, mac, 0); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -- if (ret < 0) -- goto exit; -- -- /* Rule doesn't exist. Why delete? */ -- if (!fdb.aging) { -- ret = -EINVAL; -- goto exit; -- } -- -- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -- if (ret) -- goto exit; -- -- /* Only port in the rule is this port. Don't re insert */ -- if (fdb.port_mask == port_mask) -- goto exit; -- -- /* Remove port from port mask */ -- fdb.port_mask &= ~port_mask; -- -- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static int --qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) --{ -- u32 reg; -- int ret; -- -- /* Set the command and VLAN index */ -- reg = QCA8K_VTU_FUNC1_BUSY; -- reg |= cmd; -- reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); -- -- /* Write the function register triggering the table access */ -- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); -- if (ret) -- return ret; -- -- /* wait for completion */ -- ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); -- if (ret) -- return ret; -- -- /* Check for table full violation when adding an entry */ -- if (cmd == QCA8K_VLAN_LOAD) { -- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); -- if (ret < 0) -- return ret; -- if (reg & QCA8K_VTU_FUNC1_FULL) -- return -ENOMEM; -- } -- -- return 0; --} -- --static int --qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) --{ -- u32 reg; -- int ret; -- -- /* -- We do the right thing with VLAN 0 and treat it as untagged while -- preserving the tag on egress. -- */ -- if (vid == 0) -- return 0; -- -- mutex_lock(&priv->reg_mutex); -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -- if (ret < 0) -- goto out; -- -- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -- if (ret < 0) -- goto out; -- reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; -- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -- if (untagged) -- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); -- else -- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); -- -- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -- if (ret) -- goto out; -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -- --out: -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static int --qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) --{ -- u32 reg, mask; -- int ret, i; -- bool del; -- -- mutex_lock(&priv->reg_mutex); -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -- if (ret < 0) -- goto out; -- -- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -- if (ret < 0) -- goto out; -- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); -- -- /* Check if we're the last member to be removed */ -- del = true; -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); -- -- if ((reg & mask) != mask) { -- del = false; -- break; -- } -- } -- -- if (del) { -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); -- } else { -- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -- if (ret) -- goto out; -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -- } -- --out: -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static int --qca8k_mib_init(struct qca8k_priv *priv) --{ -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | -- QCA8K_MIB_BUSY); -- if (ret) -- goto exit; -- -- ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); -- if (ret) -- goto exit; -- -- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); -- if (ret) -- goto exit; -- -- ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static void --qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) --{ -- u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; -- -- /* Port 0 and 6 have no internal PHY */ -- if (port > 0 && port < 6) -- mask |= QCA8K_PORT_STATUS_LINK_AUTO; -- -- if (enable) -- regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); -- else -- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); --} -- --static int --qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, -- struct sk_buff *read_skb, u32 *val) --{ -- struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL); -- bool ack; -- int ret; -- -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the copy pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(skb); -- -- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- QCA8K_ETHERNET_TIMEOUT); -- -- ack = mgmt_eth_data->ack; -- -- if (ret <= 0) -- return -ETIMEDOUT; -- -- if (!ack) -- return -EINVAL; -- -- *val = mgmt_eth_data->data[0]; -- -- return 0; --} -- --static int --qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, -- int regnum, u16 data) --{ -- struct sk_buff *write_skb, *clear_skb, *read_skb; -- struct qca8k_mgmt_eth_data *mgmt_eth_data; -- u32 write_val, clear_val = 0, val; -- struct net_device *mgmt_master; -- int ret, ret1; -- bool ack; -- -- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -- return -EINVAL; -- -- mgmt_eth_data = &priv->mgmt_eth_data; -- -- write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -- QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -- QCA8K_MDIO_MASTER_REG_ADDR(regnum); -- -- if (read) { -- write_val |= QCA8K_MDIO_MASTER_READ; -- } else { -- write_val |= QCA8K_MDIO_MASTER_WRITE; -- write_val |= QCA8K_MDIO_MASTER_DATA(data); -- } -- -- /* Prealloc all the needed skb before the lock */ -- write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val, -- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val)); -- if (!write_skb) -- return -ENOMEM; -- -- clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, -- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); -- if (!clear_skb) { -- ret = -ENOMEM; -- goto err_clear_skb; -- } -- -- read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val, -- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); -- if (!read_skb) { -- ret = -ENOMEM; -- goto err_read_skb; -- } -- -- /* Actually start the request: -- * 1. Send mdio master packet -- * 2. Busy Wait for mdio master command -- * 3. Get the data if we are reading -- * 4. Reset the mdio master (even with error) -- */ -- mutex_lock(&mgmt_eth_data->mutex); -- -- /* Check if mgmt_master is operational */ -- mgmt_master = priv->mgmt_master; -- if (!mgmt_master) { -- mutex_unlock(&mgmt_eth_data->mutex); -- ret = -EINVAL; -- goto err_mgmt_master; -- } -- -- read_skb->dev = mgmt_master; -- clear_skb->dev = mgmt_master; -- write_skb->dev = mgmt_master; -- -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the write pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(write_skb); -- -- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- QCA8K_ETHERNET_TIMEOUT); -- -- ack = mgmt_eth_data->ack; -- -- if (ret <= 0) { -- ret = -ETIMEDOUT; -- kfree_skb(read_skb); -- goto exit; -- } -- -- if (!ack) { -- ret = -EINVAL; -- kfree_skb(read_skb); -- goto exit; -- } -- -- ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1, -- !(val & QCA8K_MDIO_MASTER_BUSY), 0, -- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -- mgmt_eth_data, read_skb, &val); -- -- if (ret < 0 && ret1 < 0) { -- ret = ret1; -- goto exit; -- } -- -- if (read) { -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the read pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(read_skb); -- -- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- QCA8K_ETHERNET_TIMEOUT); -- -- ack = mgmt_eth_data->ack; -- -- if (ret <= 0) { -- ret = -ETIMEDOUT; -- goto exit; -- } -- -- if (!ack) { -- ret = -EINVAL; -- goto exit; -- } -- -- ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK; -- } else { -- kfree_skb(read_skb); -- } --exit: -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the clear pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(clear_skb); -- -- wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- QCA8K_ETHERNET_TIMEOUT); -- -- mutex_unlock(&mgmt_eth_data->mutex); -- -- return ret; -- -- /* Error handling before lock */ --err_mgmt_master: -- kfree_skb(read_skb); --err_read_skb: -- kfree_skb(clear_skb); --err_clear_skb: -- kfree_skb(write_skb); -- -- return ret; --} -- --static u32 --qca8k_port_to_phy(int port) --{ -- /* From Andrew Lunn: -- * Port 0 has no internal phy. -- * Port 1 has an internal PHY at MDIO address 0. -- * Port 2 has an internal PHY at MDIO address 1. -- * ... -- * Port 5 has an internal PHY at MDIO address 4. -- * Port 6 has no internal PHY. -- */ -- -- return port - 1; --} -- --static int --qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) --{ -- u16 r1, r2, page; -- u32 val; -- int ret, ret1; -- -- qca8k_split_addr(reg, &r1, &r2, &page); -- -- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, -- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -- bus, 0x10 | r2, r1, &val); -- -- /* Check if qca8k_read has failed for a different reason -- * before returnting -ETIMEDOUT -- */ -- if (ret < 0 && ret1 < 0) -- return ret1; -- -- return ret; --} -- --static int --qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) --{ -- struct mii_bus *bus = priv->bus; -- u16 r1, r2, page; -- u32 val; -- int ret; -- -- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -- return -EINVAL; -- -- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -- QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -- QCA8K_MDIO_MASTER_REG_ADDR(regnum) | -- QCA8K_MDIO_MASTER_DATA(data); -- -- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -- -- ret = qca8k_set_page(priv, page); -- if (ret) -- goto exit; -- -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -- -- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, -- QCA8K_MDIO_MASTER_BUSY); -- --exit: -- /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(priv, 0x10 | r2, r1, 0); -- -- mutex_unlock(&bus->mdio_lock); -- -- return ret; --} -- --static int --qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) --{ -- struct mii_bus *bus = priv->bus; -- u16 r1, r2, page; -- u32 val; -- int ret; -- -- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -- return -EINVAL; -- -- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -- QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -- QCA8K_MDIO_MASTER_REG_ADDR(regnum); -- -- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -- -- ret = qca8k_set_page(priv, page); -- if (ret) -- goto exit; -- -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -- -- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, -- QCA8K_MDIO_MASTER_BUSY); -- if (ret) -- goto exit; -- -- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); -- --exit: -- /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(priv, 0x10 | r2, r1, 0); -- -- mutex_unlock(&bus->mdio_lock); -- -- if (ret >= 0) -- ret = val & QCA8K_MDIO_MASTER_DATA_MASK; -- -- return ret; --} -- --static int --qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) --{ -- struct qca8k_priv *priv = slave_bus->priv; -- int ret; -- -- /* Use mdio Ethernet when available, fallback to legacy one on error */ -- ret = qca8k_phy_eth_command(priv, false, phy, regnum, data); -- if (!ret) -- return 0; -- -- return qca8k_mdio_write(priv, phy, regnum, data); --} -- --static int --qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) --{ -- struct qca8k_priv *priv = slave_bus->priv; -- int ret; -- -- /* Use mdio Ethernet when available, fallback to legacy one on error */ -- ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0); -- if (ret >= 0) -- return ret; -- -- ret = qca8k_mdio_read(priv, phy, regnum); -- -- if (ret < 0) -- return 0xffff; -- -- return ret; --} -- --static int --qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) --{ -- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; -- -- return qca8k_internal_mdio_write(slave_bus, port, regnum, data); --} -- --static int --qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) --{ -- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; -- -- return qca8k_internal_mdio_read(slave_bus, port, regnum); --} -- --static int --qca8k_mdio_register(struct qca8k_priv *priv) --{ -- struct dsa_switch *ds = priv->ds; -- struct device_node *mdio; -- struct mii_bus *bus; -- -- bus = devm_mdiobus_alloc(ds->dev); -- if (!bus) -- return -ENOMEM; -- -- bus->priv = (void *)priv; -- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", -- ds->dst->index, ds->index); -- bus->parent = ds->dev; -- bus->phy_mask = ~ds->phys_mii_mask; -- ds->slave_mii_bus = bus; -- -- /* Check if the devicetree declare the port:phy mapping */ -- mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); -- if (of_device_is_available(mdio)) { -- bus->name = "qca8k slave mii"; -- bus->read = qca8k_internal_mdio_read; -- bus->write = qca8k_internal_mdio_write; -- return devm_of_mdiobus_register(priv->dev, bus, mdio); -- } -- -- /* If a mapping can't be found the legacy mapping is used, -- * using the qca8k_port_to_phy function -- */ -- bus->name = "qca8k-legacy slave mii"; -- bus->read = qca8k_legacy_mdio_read; -- bus->write = qca8k_legacy_mdio_write; -- return devm_mdiobus_register(priv->dev, bus); --} -- --static int --qca8k_setup_mdio_bus(struct qca8k_priv *priv) --{ -- u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; -- struct device_node *ports, *port; -- phy_interface_t mode; -- int err; -- -- ports = of_get_child_by_name(priv->dev->of_node, "ports"); -- if (!ports) -- ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports"); -- -- if (!ports) -- return -EINVAL; -- -- for_each_available_child_of_node(ports, port) { -- err = of_property_read_u32(port, "reg", ®); -- if (err) { -- of_node_put(port); -- of_node_put(ports); -- return err; -- } -- -- if (!dsa_is_user_port(priv->ds, reg)) -- continue; -- -- of_get_phy_mode(port, &mode); -- -- if (of_property_read_bool(port, "phy-handle") && -- mode != PHY_INTERFACE_MODE_INTERNAL) -- external_mdio_mask |= BIT(reg); -- else -- internal_mdio_mask |= BIT(reg); -- } -- -- of_node_put(ports); -- if (!external_mdio_mask && !internal_mdio_mask) { -- dev_err(priv->dev, "no PHYs are defined.\n"); -- return -EINVAL; -- } -- -- /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through -- * the MDIO_MASTER register also _disconnects_ the external MDC -- * passthrough to the internal PHYs. It's not possible to use both -- * configurations at the same time! -- * -- * Because this came up during the review process: -- * If the external mdio-bus driver is capable magically disabling -- * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's -- * accessors for the time being, it would be possible to pull this -- * off. -- */ -- if (!!external_mdio_mask && !!internal_mdio_mask) { -- dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n"); -- return -EINVAL; -- } -- -- if (external_mdio_mask) { -- /* Make sure to disable the internal mdio bus in cases -- * a dt-overlay and driver reload changed the configuration -- */ -- -- return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL, -- QCA8K_MDIO_MASTER_EN); -- } -- -- return qca8k_mdio_register(priv); --} -- --static int --qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) --{ -- u32 mask = 0; -- int ret = 0; -- -- /* SoC specific settings for ipq8064. -- * If more device require this consider adding -- * a dedicated binding. -- */ -- if (of_machine_is_compatible("qcom,ipq8064")) -- mask |= QCA8K_MAC_PWR_RGMII0_1_8V; -- -- /* SoC specific settings for ipq8065 */ -- if (of_machine_is_compatible("qcom,ipq8065")) -- mask |= QCA8K_MAC_PWR_RGMII1_1_8V; -- -- if (mask) { -- ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, -- QCA8K_MAC_PWR_RGMII0_1_8V | -- QCA8K_MAC_PWR_RGMII1_1_8V, -- mask); -- } -- -- return ret; --} -- --static int qca8k_find_cpu_port(struct dsa_switch *ds) --{ -- struct qca8k_priv *priv = ds->priv; -- -- /* Find the connected cpu port. Valid port are 0 or 6 */ -- if (dsa_is_cpu_port(ds, 0)) -- return 0; -- -- dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6"); -- -- if (dsa_is_cpu_port(ds, 6)) -- return 6; -- -- return -EINVAL; --} -- --static int --qca8k_setup_of_pws_reg(struct qca8k_priv *priv) --{ -- struct device_node *node = priv->dev->of_node; -- const struct qca8k_match_data *data; -- u32 val = 0; -- int ret; -- -- /* QCA8327 require to set to the correct mode. -- * His bigger brother QCA8328 have the 172 pin layout. -- * Should be applied by default but we set this just to make sure. -- */ -- if (priv->switch_id == QCA8K_ID_QCA8327) { -- data = of_device_get_match_data(priv->dev); -- -- /* Set the correct package of 148 pin for QCA8327 */ -- if (data->reduced_package) -- val |= QCA8327_PWS_PACKAGE148_EN; -- -- ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, -- val); -- if (ret) -- return ret; -- } -- -- if (of_property_read_bool(node, "qca,ignore-power-on-sel")) -- val |= QCA8K_PWS_POWER_ON_SEL; -- -- if (of_property_read_bool(node, "qca,led-open-drain")) { -- if (!(val & QCA8K_PWS_POWER_ON_SEL)) { -- dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set."); -- return -EINVAL; -- } -- -- val |= QCA8K_PWS_LED_OPEN_EN_CSR; -- } -- -- return qca8k_rmw(priv, QCA8K_REG_PWS, -- QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, -- val); --} -- --static int --qca8k_parse_port_config(struct qca8k_priv *priv) --{ -- int port, cpu_port_index = -1, ret; -- struct device_node *port_dn; -- phy_interface_t mode; -- struct dsa_port *dp; -- u32 delay; -- -- /* We have 2 CPU port. Check them */ -- for (port = 0; port < QCA8K_NUM_PORTS; port++) { -- /* Skip every other port */ -- if (port != 0 && port != 6) -- continue; -- -- dp = dsa_to_port(priv->ds, port); -- port_dn = dp->dn; -- cpu_port_index++; -- -- if (!of_device_is_available(port_dn)) -- continue; -- -- ret = of_get_phy_mode(port_dn, &mode); -- if (ret) -- continue; -- -- switch (mode) { -- case PHY_INTERFACE_MODE_RGMII: -- case PHY_INTERFACE_MODE_RGMII_ID: -- case PHY_INTERFACE_MODE_RGMII_TXID: -- case PHY_INTERFACE_MODE_RGMII_RXID: -- case PHY_INTERFACE_MODE_SGMII: -- delay = 0; -- -- if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay)) -- /* Switch regs accept value in ns, convert ps to ns */ -- delay = delay / 1000; -- else if (mode == PHY_INTERFACE_MODE_RGMII_ID || -- mode == PHY_INTERFACE_MODE_RGMII_TXID) -- delay = 1; -- -- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { -- dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); -- delay = 3; -- } -- -- priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay; -- -- delay = 0; -- -- if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay)) -- /* Switch regs accept value in ns, convert ps to ns */ -- delay = delay / 1000; -- else if (mode == PHY_INTERFACE_MODE_RGMII_ID || -- mode == PHY_INTERFACE_MODE_RGMII_RXID) -- delay = 2; -- -- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { -- dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); -- delay = 3; -- } -- -- priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay; -- -- /* Skip sgmii parsing for rgmii* mode */ -- if (mode == PHY_INTERFACE_MODE_RGMII || -- mode == PHY_INTERFACE_MODE_RGMII_ID || -- mode == PHY_INTERFACE_MODE_RGMII_TXID || -- mode == PHY_INTERFACE_MODE_RGMII_RXID) -- break; -- -- if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) -- priv->ports_config.sgmii_tx_clk_falling_edge = true; -- -- if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) -- priv->ports_config.sgmii_rx_clk_falling_edge = true; -- -- if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) { -- priv->ports_config.sgmii_enable_pll = true; -- -- if (priv->switch_id == QCA8K_ID_QCA8327) { -- dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling"); -- priv->ports_config.sgmii_enable_pll = false; -- } -- -- if (priv->switch_revision < 2) -- dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more."); -- } -- -- break; -- default: -- continue; -- } -- } -- -- return 0; --} -- --static int --qca8k_setup(struct dsa_switch *ds) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int cpu_port, ret, i; -- u32 mask; -- -- cpu_port = qca8k_find_cpu_port(ds); -- if (cpu_port < 0) { -- dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6"); -- return cpu_port; -- } -- -- /* Parse CPU port config to be later used in phy_link mac_config */ -- ret = qca8k_parse_port_config(priv); -- if (ret) -- return ret; -- -- ret = qca8k_setup_mdio_bus(priv); -- if (ret) -- return ret; -- -- ret = qca8k_setup_of_pws_reg(priv); -- if (ret) -- return ret; -- -- ret = qca8k_setup_mac_pwr_sel(priv); -- if (ret) -- return ret; -- -- /* Make sure MAC06 is disabled */ -- ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, -- QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); -- if (ret) { -- dev_err(priv->dev, "failed disabling MAC06 exchange"); -- return ret; -- } -- -- /* Enable CPU Port */ -- ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -- QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); -- if (ret) { -- dev_err(priv->dev, "failed enabling CPU port"); -- return ret; -- } -- -- /* Enable MIB counters */ -- ret = qca8k_mib_init(priv); -- if (ret) -- dev_warn(priv->dev, "mib init failed"); -- -- /* Initial setup of all ports */ -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- /* Disable forwarding by default on all ports */ -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_MEMBER, 0); -- if (ret) -- return ret; -- -- /* Enable QCA header mode on all cpu ports */ -- if (dsa_is_cpu_port(ds, i)) { -- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), -- FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | -- FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); -- if (ret) { -- dev_err(priv->dev, "failed enabling QCA header mode"); -- return ret; -- } -- } -- -- /* Disable MAC by default on all user ports */ -- if (dsa_is_user_port(ds, i)) -- qca8k_port_set_status(priv, i, 0); -- } -- -- /* Forward all unknown frames to CPU port for Linux processing -- * Notice that in multi-cpu config only one port should be set -- * for igmp, unknown, multicast and broadcast packet -- */ -- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); -- if (ret) -- return ret; -- -- /* Setup connection between CPU port & user ports -- * Configure specific switch configuration for ports -- */ -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- /* CPU port gets connected to all user ports of the switch */ -- if (dsa_is_cpu_port(ds, i)) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); -- if (ret) -- return ret; -- } -- -- /* Individual user ports get connected to CPU port only */ -- if (dsa_is_user_port(ds, i)) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_MEMBER, -- BIT(cpu_port)); -- if (ret) -- return ret; -- -- /* Enable ARP Auto-learning by default */ -- ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_LEARN); -- if (ret) -- return ret; -- -- /* For port based vlans to work we need to set the -- * default egress vid -- */ -- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), -- QCA8K_EGREES_VLAN_PORT_MASK(i), -- QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); -- if (ret) -- return ret; -- -- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), -- QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | -- QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); -- if (ret) -- return ret; -- } -- -- /* The port 5 of the qca8337 have some problem in flood condition. The -- * original legacy driver had some specific buffer and priority settings -- * for the different port suggested by the QCA switch team. Add this -- * missing settings to improve switch stability under load condition. -- * This problem is limited to qca8337 and other qca8k switch are not affected. -- */ -- if (priv->switch_id == QCA8K_ID_QCA8337) { -- switch (i) { -- /* The 2 CPU port and port 5 requires some different -- * priority than any other ports. -- */ -- case 0: -- case 5: -- case 6: -- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | -- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); -- break; -- default: -- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | -- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); -- } -- qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask); -- -- mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | -- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_WRED_EN; -- qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), -- QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | -- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_WRED_EN, -- mask); -- } -- } -- -- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ -- if (priv->switch_id == QCA8K_ID_QCA8327) { -- mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | -- QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); -- qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, -- QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | -- QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, -- mask); -- } -- -- /* Setup our port MTUs to match power on defaults */ -- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); -- if (ret) -- dev_warn(priv->dev, "failed setting MTU settings"); -- -- /* Flush the FDB table */ -- qca8k_fdb_flush(priv); -- -- /* We don't have interrupts for link changes, so we need to poll */ -- ds->pcs_poll = true; -- -- /* Set min a max ageing value supported */ -- ds->ageing_time_min = 7000; -- ds->ageing_time_max = 458745000; -- -- /* Set max number of LAGs supported */ -- ds->num_lag_ids = QCA8K_NUM_LAGS; -- -- return 0; --} -- --static void --qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index, -- u32 reg) --{ -- u32 delay, val = 0; -- int ret; -- -- /* Delay can be declared in 3 different way. -- * Mode to rgmii and internal-delay standard binding defined -- * rgmii-id or rgmii-tx/rx phy mode set. -- * The parse logic set a delay different than 0 only when one -- * of the 3 different way is used. In all other case delay is -- * not enabled. With ID or TX/RXID delay is enabled and set -- * to the default and recommended value. -- */ -- if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) { -- delay = priv->ports_config.rgmii_tx_delay[cpu_port_index]; -- -- val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | -- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; -- } -- -- if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) { -- delay = priv->ports_config.rgmii_rx_delay[cpu_port_index]; -- -- val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | -- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; -- } -- -- /* Set RGMII delay based on the selected values */ -- ret = qca8k_rmw(priv, reg, -- QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | -- QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | -- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | -- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, -- val); -- if (ret) -- dev_err(priv->dev, "Failed to set internal delay for CPU port%d", -- cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); --} -- --static void --qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, -- const struct phylink_link_state *state) --{ -- struct qca8k_priv *priv = ds->priv; -- int cpu_port_index, ret; -- u32 reg, val; -- -- switch (port) { -- case 0: /* 1st CPU port */ -- if (state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_RGMII_ID && -- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -- state->interface != PHY_INTERFACE_MODE_SGMII) -- return; -- -- reg = QCA8K_REG_PORT0_PAD_CTRL; -- cpu_port_index = QCA8K_CPU_PORT0; -- break; -- case 1: -- case 2: -- case 3: -- case 4: -- case 5: -- /* Internal PHY, nothing to do */ -- return; -- case 6: /* 2nd CPU port / external PHY */ -- if (state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_RGMII_ID && -- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -- state->interface != PHY_INTERFACE_MODE_SGMII && -- state->interface != PHY_INTERFACE_MODE_1000BASEX) -- return; -- -- reg = QCA8K_REG_PORT6_PAD_CTRL; -- cpu_port_index = QCA8K_CPU_PORT6; -- break; -- default: -- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); -- return; -- } -- -- if (port != 6 && phylink_autoneg_inband(mode)) { -- dev_err(ds->dev, "%s: in-band negotiation unsupported\n", -- __func__); -- return; -- } -- -- switch (state->interface) { -- case PHY_INTERFACE_MODE_RGMII: -- case PHY_INTERFACE_MODE_RGMII_ID: -- case PHY_INTERFACE_MODE_RGMII_TXID: -- case PHY_INTERFACE_MODE_RGMII_RXID: -- qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); -- -- /* Configure rgmii delay */ -- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -- -- /* QCA8337 requires to set rgmii rx delay for all ports. -- * This is enabled through PORT5_PAD_CTRL for all ports, -- * rather than individual port registers. -- */ -- if (priv->switch_id == QCA8K_ID_QCA8337) -- qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, -- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); -- break; -- case PHY_INTERFACE_MODE_SGMII: -- case PHY_INTERFACE_MODE_1000BASEX: -- /* Enable SGMII on the port */ -- qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); -- -- /* Enable/disable SerDes auto-negotiation as necessary */ -- ret = qca8k_read(priv, QCA8K_REG_PWS, &val); -- if (ret) -- return; -- if (phylink_autoneg_inband(mode)) -- val &= ~QCA8K_PWS_SERDES_AEN_DIS; -- else -- val |= QCA8K_PWS_SERDES_AEN_DIS; -- qca8k_write(priv, QCA8K_REG_PWS, val); -- -- /* Configure the SGMII parameters */ -- ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val); -- if (ret) -- return; -- -- val |= QCA8K_SGMII_EN_SD; -- -- if (priv->ports_config.sgmii_enable_pll) -- val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | -- QCA8K_SGMII_EN_TX; -- -- if (dsa_is_cpu_port(ds, port)) { -- /* CPU port, we're talking to the CPU MAC, be a PHY */ -- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -- val |= QCA8K_SGMII_MODE_CTRL_PHY; -- } else if (state->interface == PHY_INTERFACE_MODE_SGMII) { -- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -- val |= QCA8K_SGMII_MODE_CTRL_MAC; -- } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { -- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -- val |= QCA8K_SGMII_MODE_CTRL_BASEX; -- } -- -- qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); -- -- /* From original code is reported port instability as SGMII also -- * require delay set. Apply advised values here or take them from DT. -- */ -- if (state->interface == PHY_INTERFACE_MODE_SGMII) -- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -- -- /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and -- * falling edge is set writing in the PORT0 PAD reg -- */ -- if (priv->switch_id == QCA8K_ID_QCA8327 || -- priv->switch_id == QCA8K_ID_QCA8337) -- reg = QCA8K_REG_PORT0_PAD_CTRL; -- -- val = 0; -- -- /* SGMII Clock phase configuration */ -- if (priv->ports_config.sgmii_rx_clk_falling_edge) -- val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; -- -- if (priv->ports_config.sgmii_tx_clk_falling_edge) -- val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; -- -- if (val) -- ret = qca8k_rmw(priv, reg, -- QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | -- QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, -- val); -- -- break; -- default: -- dev_err(ds->dev, "xMII mode %s not supported for port %d\n", -- phy_modes(state->interface), port); -- return; -- } --} -- --static void --qca8k_phylink_validate(struct dsa_switch *ds, int port, -- unsigned long *supported, -- struct phylink_link_state *state) --{ -- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -- -- switch (port) { -- case 0: /* 1st CPU port */ -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_RGMII_ID && -- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -- state->interface != PHY_INTERFACE_MODE_SGMII) -- goto unsupported; -- break; -- case 1: -- case 2: -- case 3: -- case 4: -- case 5: -- /* Internal PHY */ -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_GMII && -- state->interface != PHY_INTERFACE_MODE_INTERNAL) -- goto unsupported; -- break; -- case 6: /* 2nd CPU port / external PHY */ -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_RGMII_ID && -- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -- state->interface != PHY_INTERFACE_MODE_SGMII && -- state->interface != PHY_INTERFACE_MODE_1000BASEX) -- goto unsupported; -- break; -- default: --unsupported: -- linkmode_zero(supported); -- return; -- } -- -- phylink_set_port_modes(mask); -- phylink_set(mask, Autoneg); -- -- phylink_set(mask, 1000baseT_Full); -- phylink_set(mask, 10baseT_Half); -- phylink_set(mask, 10baseT_Full); -- phylink_set(mask, 100baseT_Half); -- phylink_set(mask, 100baseT_Full); -- -- if (state->interface == PHY_INTERFACE_MODE_1000BASEX) -- phylink_set(mask, 1000baseX_Full); -- -- phylink_set(mask, Pause); -- phylink_set(mask, Asym_Pause); -- -- linkmode_and(supported, supported, mask); -- linkmode_and(state->advertising, state->advertising, mask); --} -- --static int --qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, -- struct phylink_link_state *state) --{ -- struct qca8k_priv *priv = ds->priv; -- u32 reg; -- int ret; -- -- ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), ®); -- if (ret < 0) -- return ret; -- -- state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); -- state->an_complete = state->link; -- state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO); -- state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : -- DUPLEX_HALF; -- -- switch (reg & QCA8K_PORT_STATUS_SPEED) { -- case QCA8K_PORT_STATUS_SPEED_10: -- state->speed = SPEED_10; -- break; -- case QCA8K_PORT_STATUS_SPEED_100: -- state->speed = SPEED_100; -- break; -- case QCA8K_PORT_STATUS_SPEED_1000: -- state->speed = SPEED_1000; -- break; -- default: -- state->speed = SPEED_UNKNOWN; -- break; -- } -- -- state->pause = MLO_PAUSE_NONE; -- if (reg & QCA8K_PORT_STATUS_RXFLOW) -- state->pause |= MLO_PAUSE_RX; -- if (reg & QCA8K_PORT_STATUS_TXFLOW) -- state->pause |= MLO_PAUSE_TX; -- -- return 1; --} -- --static void --qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, -- phy_interface_t interface) --{ -- struct qca8k_priv *priv = ds->priv; -- -- qca8k_port_set_status(priv, port, 0); --} -- --static void --qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, -- phy_interface_t interface, struct phy_device *phydev, -- int speed, int duplex, bool tx_pause, bool rx_pause) --{ -- struct qca8k_priv *priv = ds->priv; -- u32 reg; -- -- if (phylink_autoneg_inband(mode)) { -- reg = QCA8K_PORT_STATUS_LINK_AUTO; -- } else { -- switch (speed) { -- case SPEED_10: -- reg = QCA8K_PORT_STATUS_SPEED_10; -- break; -- case SPEED_100: -- reg = QCA8K_PORT_STATUS_SPEED_100; -- break; -- case SPEED_1000: -- reg = QCA8K_PORT_STATUS_SPEED_1000; -- break; -- default: -- reg = QCA8K_PORT_STATUS_LINK_AUTO; -- break; -- } -- -- if (duplex == DUPLEX_FULL) -- reg |= QCA8K_PORT_STATUS_DUPLEX; -- -- if (rx_pause || dsa_is_cpu_port(ds, port)) -- reg |= QCA8K_PORT_STATUS_RXFLOW; -- -- if (tx_pause || dsa_is_cpu_port(ds, port)) -- reg |= QCA8K_PORT_STATUS_TXFLOW; -- } -- -- reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; -- -- qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); --} -- --static void --qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) --{ -- const struct qca8k_match_data *match_data; -- struct qca8k_priv *priv = ds->priv; -- int i; -- -- if (stringset != ETH_SS_STATS) -- return; -- -- match_data = of_device_get_match_data(priv->dev); -- -- for (i = 0; i < match_data->mib_count; i++) -- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, -- ETH_GSTRING_LEN); --} -- --static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) --{ -- const struct qca8k_match_data *match_data; -- struct qca8k_mib_eth_data *mib_eth_data; -- struct qca8k_priv *priv = ds->priv; -- const struct qca8k_mib_desc *mib; -- struct mib_ethhdr *mib_ethhdr; -- int i, mib_len, offset = 0; -- u64 *data; -- u8 port; -- -- mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); -- mib_eth_data = &priv->mib_eth_data; -- -- /* The switch autocast every port. Ignore other packet and -- * parse only the requested one. -- */ -- port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr)); -- if (port != mib_eth_data->req_port) -- goto exit; -- -- match_data = device_get_match_data(priv->dev); -- data = mib_eth_data->data; -- -- for (i = 0; i < match_data->mib_count; i++) { -- mib = &ar8327_mib[i]; -- -- /* First 3 mib are present in the skb head */ -- if (i < 3) { -- data[i] = mib_ethhdr->data[i]; -- continue; -- } -- -- mib_len = sizeof(uint32_t); -- -- /* Some mib are 64 bit wide */ -- if (mib->size == 2) -- mib_len = sizeof(uint64_t); -- -- /* Copy the mib value from packet to the */ -- memcpy(data + i, skb->data + offset, mib_len); -- -- /* Set the offset for the next mib */ -- offset += mib_len; -- } -- --exit: -- /* Complete on receiving all the mib packet */ -- if (refcount_dec_and_test(&mib_eth_data->port_parsed)) -- complete(&mib_eth_data->rw_done); --} -- --static int --qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data) --{ -- struct dsa_port *dp = dsa_to_port(ds, port); -- struct qca8k_mib_eth_data *mib_eth_data; -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- mib_eth_data = &priv->mib_eth_data; -- -- mutex_lock(&mib_eth_data->mutex); -- -- reinit_completion(&mib_eth_data->rw_done); -- -- mib_eth_data->req_port = dp->index; -- mib_eth_data->data = data; -- refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS); -- -- mutex_lock(&priv->reg_mutex); -- -- /* Send mib autocast request */ -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) | -- QCA8K_MIB_BUSY); -- -- mutex_unlock(&priv->reg_mutex); -- -- if (ret) -- goto exit; -- -- ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT); -- --exit: -- mutex_unlock(&mib_eth_data->mutex); -- -- return ret; --} -- --static void --qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, -- uint64_t *data) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- const struct qca8k_match_data *match_data; -- const struct qca8k_mib_desc *mib; -- u32 reg, i, val; -- u32 hi = 0; -- int ret; -- -- if (priv->mgmt_master && -- qca8k_get_ethtool_stats_eth(ds, port, data) > 0) -- return; -- -- match_data = of_device_get_match_data(priv->dev); -- -- for (i = 0; i < match_data->mib_count; i++) { -- mib = &ar8327_mib[i]; -- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; -- -- ret = qca8k_read(priv, reg, &val); -- if (ret < 0) -- continue; -- -- if (mib->size == 2) { -- ret = qca8k_read(priv, reg + 4, &hi); -- if (ret < 0) -- continue; -- } -- -- data[i] = val; -- if (mib->size == 2) -- data[i] |= (u64)hi << 32; -- } --} -- --static int --qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) --{ -- const struct qca8k_match_data *match_data; -- struct qca8k_priv *priv = ds->priv; -- -- if (sset != ETH_SS_STATS) -- return 0; -- -- match_data = of_device_get_match_data(priv->dev); -- -- return match_data->mib_count; --} -- --static int --qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); -- u32 reg; -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); -- if (ret < 0) -- goto exit; -- -- if (eee->eee_enabled) -- reg |= lpi_en; -- else -- reg &= ~lpi_en; -- ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static int --qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) --{ -- /* Nothing to do on the port's MAC */ -- return 0; --} -- --static void --qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u32 stp_state; -- -- switch (state) { -- case BR_STATE_DISABLED: -- stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; -- break; -- case BR_STATE_BLOCKING: -- stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; -- break; -- case BR_STATE_LISTENING: -- stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; -- break; -- case BR_STATE_LEARNING: -- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; -- break; -- case BR_STATE_FORWARDING: -- default: -- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; -- break; -- } -- -- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); --} -- --static int --qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int port_mask, cpu_port; -- int i, ret; -- -- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -- port_mask = BIT(cpu_port); -- -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- if (dsa_is_cpu_port(ds, i)) -- continue; -- if (dsa_to_port(ds, i)->bridge_dev != br) -- continue; -- /* Add this port to the portvlan mask of the other ports -- * in the bridge -- */ -- ret = regmap_set_bits(priv->regmap, -- QCA8K_PORT_LOOKUP_CTRL(i), -- BIT(port)); -- if (ret) -- return ret; -- if (i != port) -- port_mask |= BIT(i); -- } -- -- /* Add all other ports to this ports portvlan mask */ -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_MEMBER, port_mask); -- -- return ret; --} -- --static void --qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int cpu_port, i; -- -- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -- -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- if (dsa_is_cpu_port(ds, i)) -- continue; -- if (dsa_to_port(ds, i)->bridge_dev != br) -- continue; -- /* Remove this port to the portvlan mask of the other ports -- * in the bridge -- */ -- regmap_clear_bits(priv->regmap, -- QCA8K_PORT_LOOKUP_CTRL(i), -- BIT(port)); -- } -- -- /* Set the cpu port to be the only one in the portvlan mask of -- * this port -- */ -- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); --} -- --static void --qca8k_port_fast_age(struct dsa_switch *ds, int port) --{ -- struct qca8k_priv *priv = ds->priv; -- -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); -- mutex_unlock(&priv->reg_mutex); --} -- --static int --qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) --{ -- struct qca8k_priv *priv = ds->priv; -- unsigned int secs = msecs / 1000; -- u32 val; -- -- /* AGE_TIME reg is set in 7s step */ -- val = secs / 7; -- -- /* Handle case with 0 as val to NOT disable -- * learning -- */ -- if (!val) -- val = 1; -- -- return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, -- QCA8K_ATU_AGE_TIME(val)); --} -- --static int --qca8k_port_enable(struct dsa_switch *ds, int port, -- struct phy_device *phy) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- -- qca8k_port_set_status(priv, port, 1); -- priv->port_enabled_map |= BIT(port); -- -- if (dsa_is_user_port(ds, port)) -- phy_support_asym_pause(phy); -- -- return 0; --} -- --static void --qca8k_port_disable(struct dsa_switch *ds, int port) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- -- qca8k_port_set_status(priv, port, 0); -- priv->port_enabled_map &= ~BIT(port); --} -- --static int --qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- /* We have only have a general MTU setting. -- * DSA always set the CPU port's MTU to the largest MTU of the slave -- * ports. -- * Setting MTU just for the CPU port is sufficient to correctly set a -- * value for every port. -- */ -- if (!dsa_is_cpu_port(ds, port)) -- return 0; -- -- /* To change the MAX_FRAME_SIZE the cpu ports must be off or -- * the switch panics. -- * Turn off both cpu ports before applying the new value to prevent -- * this. -- */ -- if (priv->port_enabled_map & BIT(0)) -- qca8k_port_set_status(priv, 0, 0); -- -- if (priv->port_enabled_map & BIT(6)) -- qca8k_port_set_status(priv, 6, 0); -- -- /* Include L2 header / FCS length */ -- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); -- -- if (priv->port_enabled_map & BIT(0)) -- qca8k_port_set_status(priv, 0, 1); -- -- if (priv->port_enabled_map & BIT(6)) -- qca8k_port_set_status(priv, 6, 1); -- -- return ret; --} -- --static int --qca8k_port_max_mtu(struct dsa_switch *ds, int port) --{ -- return QCA8K_MAX_MTU; --} -- --static int --qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, -- u16 port_mask, u16 vid) --{ -- /* Set the vid to the port vlan id if no vid is set */ -- if (!vid) -- vid = QCA8K_PORT_VID_DEF; -- -- return qca8k_fdb_add(priv, addr, port_mask, vid, -- QCA8K_ATU_STATUS_STATIC); --} -- --static int --qca8k_port_fdb_add(struct dsa_switch *ds, int port, -- const unsigned char *addr, u16 vid) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u16 port_mask = BIT(port); -- -- return qca8k_port_fdb_insert(priv, addr, port_mask, vid); --} -- --static int --qca8k_port_fdb_del(struct dsa_switch *ds, int port, -- const unsigned char *addr, u16 vid) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u16 port_mask = BIT(port); -- -- if (!vid) -- vid = QCA8K_PORT_VID_DEF; -- -- return qca8k_fdb_del(priv, addr, port_mask, vid); --} -- --static int --qca8k_port_fdb_dump(struct dsa_switch *ds, int port, -- dsa_fdb_dump_cb_t *cb, void *data) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- struct qca8k_fdb _fdb = { 0 }; -- int cnt = QCA8K_NUM_FDB_RECORDS; -- bool is_static; -- int ret = 0; -- -- mutex_lock(&priv->reg_mutex); -- while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { -- if (!_fdb.aging) -- break; -- is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); -- ret = cb(_fdb.mac, _fdb.vid, is_static, data); -- if (ret) -- break; -- } -- mutex_unlock(&priv->reg_mutex); -- -- return 0; --} -- --static int --qca8k_port_mdb_add(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_mdb *mdb) --{ -- struct qca8k_priv *priv = ds->priv; -- const u8 *addr = mdb->addr; -- u16 vid = mdb->vid; -- -- return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); --} -- --static int --qca8k_port_mdb_del(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_mdb *mdb) --{ -- struct qca8k_priv *priv = ds->priv; -- const u8 *addr = mdb->addr; -- u16 vid = mdb->vid; -- -- return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); --} -- --static int --qca8k_port_mirror_add(struct dsa_switch *ds, int port, -- struct dsa_mall_mirror_tc_entry *mirror, -- bool ingress) --{ -- struct qca8k_priv *priv = ds->priv; -- int monitor_port, ret; -- u32 reg, val; -- -- /* Check for existent entry */ -- if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) -- return -EEXIST; -- -- ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); -- if (ret) -- return ret; -- -- /* QCA83xx can have only one port set to mirror mode. -- * Check that the correct port is requested and return error otherwise. -- * When no mirror port is set, the values is set to 0xF -- */ -- monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -- if (monitor_port != 0xF && monitor_port != mirror->to_local_port) -- return -EEXIST; -- -- /* Set the monitor port */ -- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, -- mirror->to_local_port); -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -- if (ret) -- return ret; -- -- if (ingress) { -- reg = QCA8K_PORT_LOOKUP_CTRL(port); -- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -- } else { -- reg = QCA8K_REG_PORT_HOL_CTRL1(port); -- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -- } -- -- ret = regmap_update_bits(priv->regmap, reg, val, val); -- if (ret) -- return ret; -- -- /* Track mirror port for tx and rx to decide when the -- * mirror port has to be disabled. -- */ -- if (ingress) -- priv->mirror_rx |= BIT(port); -- else -- priv->mirror_tx |= BIT(port); -- -- return 0; --} -- --static void --qca8k_port_mirror_del(struct dsa_switch *ds, int port, -- struct dsa_mall_mirror_tc_entry *mirror) --{ -- struct qca8k_priv *priv = ds->priv; -- u32 reg, val; -- int ret; -- -- if (mirror->ingress) { -- reg = QCA8K_PORT_LOOKUP_CTRL(port); -- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -- } else { -- reg = QCA8K_REG_PORT_HOL_CTRL1(port); -- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -- } -- -- ret = regmap_clear_bits(priv->regmap, reg, val); -- if (ret) -- goto err; -- -- if (mirror->ingress) -- priv->mirror_rx &= ~BIT(port); -- else -- priv->mirror_tx &= ~BIT(port); -- -- /* No port set to send packet to mirror port. Disable mirror port */ -- if (!priv->mirror_rx && !priv->mirror_tx) { -- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -- if (ret) -- goto err; -- } --err: -- dev_err(priv->dev, "Failed to del mirror port from %d", port); --} -- --static int --qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, -- struct netlink_ext_ack *extack) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- if (vlan_filtering) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -- QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); -- } else { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -- QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); -- } -- -- return ret; --} -- --static int --qca8k_port_vlan_add(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_vlan *vlan, -- struct netlink_ext_ack *extack) --{ -- bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; -- bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); -- if (ret) { -- dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); -- return ret; -- } -- -- if (pvid) { -- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), -- QCA8K_EGREES_VLAN_PORT_MASK(port), -- QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); -- if (ret) -- return ret; -- -- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), -- QCA8K_PORT_VLAN_CVID(vlan->vid) | -- QCA8K_PORT_VLAN_SVID(vlan->vid)); -- } -- -- return ret; --} -- --static int --qca8k_port_vlan_del(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_vlan *vlan) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- ret = qca8k_vlan_del(priv, port, vlan->vid); -- if (ret) -- dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); -- -- return ret; --} -- --static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) --{ -- struct qca8k_priv *priv = ds->priv; -- -- /* Communicate to the phy internal driver the switch revision. -- * Based on the switch revision different values needs to be -- * set to the dbg and mmd reg on the phy. -- * The first 2 bit are used to communicate the switch revision -- * to the phy driver. -- */ -- if (port > 0 && port < 6) -- return priv->switch_revision; -- -- return 0; --} -- --static enum dsa_tag_protocol --qca8k_get_tag_protocol(struct dsa_switch *ds, int port, -- enum dsa_tag_protocol mp) --{ -- return DSA_TAG_PROTO_QCA; --} -- --static bool --qca8k_lag_can_offload(struct dsa_switch *ds, -- struct net_device *lag, -- struct netdev_lag_upper_info *info) --{ -- struct dsa_port *dp; -- int id, members = 0; -- -- id = dsa_lag_id(ds->dst, lag); -- if (id < 0 || id >= ds->num_lag_ids) -- return false; -- -- dsa_lag_foreach_port(dp, ds->dst, lag) -- /* Includes the port joining the LAG */ -- members++; -- -- if (members > QCA8K_NUM_PORTS_FOR_LAG) -- return false; -- -- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) -- return false; -- -- if (info->hash_type != NETDEV_LAG_HASH_L2 && -- info->hash_type != NETDEV_LAG_HASH_L23) -- return false; -- -- return true; --} -- --static int --qca8k_lag_setup_hash(struct dsa_switch *ds, -- struct net_device *lag, -- struct netdev_lag_upper_info *info) --{ -- struct qca8k_priv *priv = ds->priv; -- bool unique_lag = true; -- u32 hash = 0; -- int i, id; -- -- id = dsa_lag_id(ds->dst, lag); -- -- switch (info->hash_type) { -- case NETDEV_LAG_HASH_L23: -- hash |= QCA8K_TRUNK_HASH_SIP_EN; -- hash |= QCA8K_TRUNK_HASH_DIP_EN; -- fallthrough; -- case NETDEV_LAG_HASH_L2: -- hash |= QCA8K_TRUNK_HASH_SA_EN; -- hash |= QCA8K_TRUNK_HASH_DA_EN; -- break; -- default: /* We should NEVER reach this */ -- return -EOPNOTSUPP; -- } -- -- /* Check if we are the unique configured LAG */ -- dsa_lags_foreach_id(i, ds->dst) -- if (i != id && dsa_lag_dev(ds->dst, i)) { -- unique_lag = false; -- break; -- } -- -- /* Hash Mode is global. Make sure the same Hash Mode -- * is set to all the 4 possible lag. -- * If we are the unique LAG we can set whatever hash -- * mode we want. -- * To change hash mode it's needed to remove all LAG -- * and change the mode with the latest. -- */ -- if (unique_lag) { -- priv->lag_hash_mode = hash; -- } else if (priv->lag_hash_mode != hash) { -- netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); -- return -EOPNOTSUPP; -- } -- -- return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, -- QCA8K_TRUNK_HASH_MASK, hash); --} -- --static int --qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, -- struct net_device *lag, bool delete) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret, id, i; -- u32 val; -- -- id = dsa_lag_id(ds->dst, lag); -- -- /* Read current port member */ -- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); -- if (ret) -- return ret; -- -- /* Shift val to the correct trunk */ -- val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); -- val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; -- if (delete) -- val &= ~BIT(port); -- else -- val |= BIT(port); -- -- /* Update port member. With empty portmap disable trunk */ -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, -- QCA8K_REG_GOL_TRUNK_MEMBER(id) | -- QCA8K_REG_GOL_TRUNK_EN(id), -- !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | -- val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); -- -- /* Search empty member if adding or port on deleting */ -- for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { -- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); -- if (ret) -- return ret; -- -- val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); -- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; -- -- if (delete) { -- /* If port flagged to be disabled assume this member is -- * empty -- */ -- if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -- continue; -- -- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; -- if (val != port) -- continue; -- } else { -- /* If port flagged to be enabled assume this member is -- * already set -- */ -- if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -- continue; -- } -- -- /* We have found the member to add/remove */ -- break; -- } -- -- /* Set port in the correct port mask or disable port if in delete mode */ -- return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), -- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | -- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), -- !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | -- port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); --} -- --static int --qca8k_port_lag_join(struct dsa_switch *ds, int port, -- struct net_device *lag, -- struct netdev_lag_upper_info *info) --{ -- int ret; -- -- if (!qca8k_lag_can_offload(ds, lag, info)) -- return -EOPNOTSUPP; -- -- ret = qca8k_lag_setup_hash(ds, lag, info); -- if (ret) -- return ret; -- -- return qca8k_lag_refresh_portmap(ds, port, lag, false); --} -- --static int --qca8k_port_lag_leave(struct dsa_switch *ds, int port, -- struct net_device *lag) --{ -- return qca8k_lag_refresh_portmap(ds, port, lag, true); --} -- --static void --qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, -- bool operational) --{ -- struct dsa_port *dp = master->dsa_ptr; -- struct qca8k_priv *priv = ds->priv; -- -- /* Ethernet MIB/MDIO is only supported for CPU port 0 */ -- if (dp->index != 0) -- return; -- -- mutex_lock(&priv->mgmt_eth_data.mutex); -- mutex_lock(&priv->mib_eth_data.mutex); -- -- priv->mgmt_master = operational ? (struct net_device *)master : NULL; -- -- mutex_unlock(&priv->mib_eth_data.mutex); -- mutex_unlock(&priv->mgmt_eth_data.mutex); --} -- --static int qca8k_connect_tag_protocol(struct dsa_switch *ds, -- enum dsa_tag_protocol proto) --{ -- struct qca_tagger_data *tagger_data; -- -- switch (proto) { -- case DSA_TAG_PROTO_QCA: -- tagger_data = ds->tagger_data; -- -- tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; -- tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler; -- -- break; -- default: -- return -EOPNOTSUPP; -- } -- -- return 0; --} -- --static const struct dsa_switch_ops qca8k_switch_ops = { -- .get_tag_protocol = qca8k_get_tag_protocol, -- .setup = qca8k_setup, -- .get_strings = qca8k_get_strings, -- .get_ethtool_stats = qca8k_get_ethtool_stats, -- .get_sset_count = qca8k_get_sset_count, -- .set_ageing_time = qca8k_set_ageing_time, -- .get_mac_eee = qca8k_get_mac_eee, -- .set_mac_eee = qca8k_set_mac_eee, -- .port_enable = qca8k_port_enable, -- .port_disable = qca8k_port_disable, -- .port_change_mtu = qca8k_port_change_mtu, -- .port_max_mtu = qca8k_port_max_mtu, -- .port_stp_state_set = qca8k_port_stp_state_set, -- .port_bridge_join = qca8k_port_bridge_join, -- .port_bridge_leave = qca8k_port_bridge_leave, -- .port_fast_age = qca8k_port_fast_age, -- .port_fdb_add = qca8k_port_fdb_add, -- .port_fdb_del = qca8k_port_fdb_del, -- .port_fdb_dump = qca8k_port_fdb_dump, -- .port_mdb_add = qca8k_port_mdb_add, -- .port_mdb_del = qca8k_port_mdb_del, -- .port_mirror_add = qca8k_port_mirror_add, -- .port_mirror_del = qca8k_port_mirror_del, -- .port_vlan_filtering = qca8k_port_vlan_filtering, -- .port_vlan_add = qca8k_port_vlan_add, -- .port_vlan_del = qca8k_port_vlan_del, -- .phylink_validate = qca8k_phylink_validate, -- .phylink_mac_link_state = qca8k_phylink_mac_link_state, -- .phylink_mac_config = qca8k_phylink_mac_config, -- .phylink_mac_link_down = qca8k_phylink_mac_link_down, -- .phylink_mac_link_up = qca8k_phylink_mac_link_up, -- .get_phy_flags = qca8k_get_phy_flags, -- .port_lag_join = qca8k_port_lag_join, -- .port_lag_leave = qca8k_port_lag_leave, -- .master_state_change = qca8k_master_change, -- .connect_tag_protocol = qca8k_connect_tag_protocol, --}; -- --static int qca8k_read_switch_id(struct qca8k_priv *priv) --{ -- const struct qca8k_match_data *data; -- u32 val; -- u8 id; -- int ret; -- -- /* get the switches ID from the compatible */ -- data = of_device_get_match_data(priv->dev); -- if (!data) -- return -ENODEV; -- -- ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); -- if (ret < 0) -- return -ENODEV; -- -- id = QCA8K_MASK_CTRL_DEVICE_ID(val); -- if (id != data->id) { -- dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); -- return -ENODEV; -- } -- -- priv->switch_id = id; -- -- /* Save revision to communicate to the internal PHY driver */ -- priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); -- -- return 0; --} -- --static int --qca8k_sw_probe(struct mdio_device *mdiodev) --{ -- struct qca8k_priv *priv; -- int ret; -- -- /* allocate the private data struct so that we can probe the switches -- * ID register -- */ -- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- -- priv->bus = mdiodev->bus; -- priv->dev = &mdiodev->dev; -- -- priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", -- GPIOD_ASIS); -- if (IS_ERR(priv->reset_gpio)) -- return PTR_ERR(priv->reset_gpio); -- -- if (priv->reset_gpio) { -- gpiod_set_value_cansleep(priv->reset_gpio, 1); -- /* The active low duration must be greater than 10 ms -- * and checkpatch.pl wants 20 ms. -- */ -- msleep(20); -- gpiod_set_value_cansleep(priv->reset_gpio, 0); -- } -- -- /* Start by setting up the register mapping */ -- priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv, -- &qca8k_regmap_config); -- if (IS_ERR(priv->regmap)) { -- dev_err(priv->dev, "regmap initialization failed"); -- return PTR_ERR(priv->regmap); -- } -- -- priv->mdio_cache.page = 0xffff; -- priv->mdio_cache.lo = 0xffff; -- priv->mdio_cache.hi = 0xffff; -- -- /* Check the detected switch id */ -- ret = qca8k_read_switch_id(priv); -- if (ret) -- return ret; -- -- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); -- if (!priv->ds) -- return -ENOMEM; -- -- mutex_init(&priv->mgmt_eth_data.mutex); -- init_completion(&priv->mgmt_eth_data.rw_done); -- -- mutex_init(&priv->mib_eth_data.mutex); -- init_completion(&priv->mib_eth_data.rw_done); -- -- priv->ds->dev = &mdiodev->dev; -- priv->ds->num_ports = QCA8K_NUM_PORTS; -- priv->ds->priv = priv; -- priv->ds->ops = &qca8k_switch_ops; -- mutex_init(&priv->reg_mutex); -- dev_set_drvdata(&mdiodev->dev, priv); -- -- return dsa_register_switch(priv->ds); --} -- --static void --qca8k_sw_remove(struct mdio_device *mdiodev) --{ -- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); -- int i; -- -- if (!priv) -- return; -- -- for (i = 0; i < QCA8K_NUM_PORTS; i++) -- qca8k_port_set_status(priv, i, 0); -- -- dsa_unregister_switch(priv->ds); -- -- dev_set_drvdata(&mdiodev->dev, NULL); --} -- --static void qca8k_sw_shutdown(struct mdio_device *mdiodev) --{ -- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); -- -- if (!priv) -- return; -- -- dsa_switch_shutdown(priv->ds); -- -- dev_set_drvdata(&mdiodev->dev, NULL); --} -- --#ifdef CONFIG_PM_SLEEP --static void --qca8k_set_pm(struct qca8k_priv *priv, int enable) --{ -- int port; -- -- for (port = 0; port < QCA8K_NUM_PORTS; port++) { -- /* Do not enable on resume if the port was -- * disabled before. -- */ -- if (!(priv->port_enabled_map & BIT(port))) -- continue; -- -- qca8k_port_set_status(priv, port, enable); -- } --} -- --static int qca8k_suspend(struct device *dev) --{ -- struct qca8k_priv *priv = dev_get_drvdata(dev); -- -- qca8k_set_pm(priv, 0); -- -- return dsa_switch_suspend(priv->ds); --} -- --static int qca8k_resume(struct device *dev) --{ -- struct qca8k_priv *priv = dev_get_drvdata(dev); -- -- qca8k_set_pm(priv, 1); -- -- return dsa_switch_resume(priv->ds); --} --#endif /* CONFIG_PM_SLEEP */ -- --static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, -- qca8k_suspend, qca8k_resume); -- --static const struct qca8k_match_data qca8327 = { -- .id = QCA8K_ID_QCA8327, -- .reduced_package = true, -- .mib_count = QCA8K_QCA832X_MIB_COUNT, --}; -- --static const struct qca8k_match_data qca8328 = { -- .id = QCA8K_ID_QCA8327, -- .mib_count = QCA8K_QCA832X_MIB_COUNT, --}; -- --static const struct qca8k_match_data qca833x = { -- .id = QCA8K_ID_QCA8337, -- .mib_count = QCA8K_QCA833X_MIB_COUNT, --}; -- --static const struct of_device_id qca8k_of_match[] = { -- { .compatible = "qca,qca8327", .data = &qca8327 }, -- { .compatible = "qca,qca8328", .data = &qca8328 }, -- { .compatible = "qca,qca8334", .data = &qca833x }, -- { .compatible = "qca,qca8337", .data = &qca833x }, -- { /* sentinel */ }, --}; -- --static struct mdio_driver qca8kmdio_driver = { -- .probe = qca8k_sw_probe, -- .remove = qca8k_sw_remove, -- .shutdown = qca8k_sw_shutdown, -- .mdiodrv.driver = { -- .name = "qca8k", -- .of_match_table = qca8k_of_match, -- .pm = &qca8k_pm_ops, -- }, --}; -- --mdio_module_driver(qca8kmdio_driver); -- --MODULE_AUTHOR("Mathieu Olivari, John Crispin "); --MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family"); --MODULE_LICENSE("GPL v2"); --MODULE_ALIAS("platform:qca8k"); ---- a/drivers/net/dsa/qca8k.h -+++ /dev/null -@@ -1,411 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-only */ --/* -- * Copyright (C) 2009 Felix Fietkau -- * Copyright (C) 2011-2012 Gabor Juhos -- * Copyright (c) 2015, The Linux Foundation. All rights reserved. -- */ -- --#ifndef __QCA8K_H --#define __QCA8K_H -- --#include --#include --#include --#include -- --#define QCA8K_ETHERNET_MDIO_PRIORITY 7 --#define QCA8K_ETHERNET_PHY_PRIORITY 6 --#define QCA8K_ETHERNET_TIMEOUT 100 -- --#define QCA8K_NUM_PORTS 7 --#define QCA8K_NUM_CPU_PORTS 2 --#define QCA8K_MAX_MTU 9000 --#define QCA8K_NUM_LAGS 4 --#define QCA8K_NUM_PORTS_FOR_LAG 4 -- --#define PHY_ID_QCA8327 0x004dd034 --#define QCA8K_ID_QCA8327 0x12 --#define PHY_ID_QCA8337 0x004dd036 --#define QCA8K_ID_QCA8337 0x13 -- --#define QCA8K_QCA832X_MIB_COUNT 39 --#define QCA8K_QCA833X_MIB_COUNT 41 -- --#define QCA8K_BUSY_WAIT_TIMEOUT 2000 -- --#define QCA8K_NUM_FDB_RECORDS 2048 -- --#define QCA8K_PORT_VID_DEF 1 -- --/* Global control registers */ --#define QCA8K_REG_MASK_CTRL 0x000 --#define QCA8K_MASK_CTRL_REV_ID_MASK GENMASK(7, 0) --#define QCA8K_MASK_CTRL_REV_ID(x) FIELD_GET(QCA8K_MASK_CTRL_REV_ID_MASK, x) --#define QCA8K_MASK_CTRL_DEVICE_ID_MASK GENMASK(15, 8) --#define QCA8K_MASK_CTRL_DEVICE_ID(x) FIELD_GET(QCA8K_MASK_CTRL_DEVICE_ID_MASK, x) --#define QCA8K_REG_PORT0_PAD_CTRL 0x004 --#define QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN BIT(31) --#define QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE BIT(19) --#define QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE BIT(18) --#define QCA8K_REG_PORT5_PAD_CTRL 0x008 --#define QCA8K_REG_PORT6_PAD_CTRL 0x00c --#define QCA8K_PORT_PAD_RGMII_EN BIT(26) --#define QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK GENMASK(23, 22) --#define QCA8K_PORT_PAD_RGMII_TX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, x) --#define QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK GENMASK(21, 20) --#define QCA8K_PORT_PAD_RGMII_RX_DELAY(x) FIELD_PREP(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, x) --#define QCA8K_PORT_PAD_RGMII_TX_DELAY_EN BIT(25) --#define QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24) --#define QCA8K_PORT_PAD_SGMII_EN BIT(7) --#define QCA8K_REG_PWS 0x010 --#define QCA8K_PWS_POWER_ON_SEL BIT(31) --/* This reg is only valid for QCA832x and toggle the package -- * type from 176 pin (by default) to 148 pin used on QCA8327 -- */ --#define QCA8327_PWS_PACKAGE148_EN BIT(30) --#define QCA8K_PWS_LED_OPEN_EN_CSR BIT(24) --#define QCA8K_PWS_SERDES_AEN_DIS BIT(7) --#define QCA8K_REG_MODULE_EN 0x030 --#define QCA8K_MODULE_EN_MIB BIT(0) --#define QCA8K_REG_MIB 0x034 --#define QCA8K_MIB_FUNC GENMASK(26, 24) --#define QCA8K_MIB_CPU_KEEP BIT(20) --#define QCA8K_MIB_BUSY BIT(17) --#define QCA8K_MDIO_MASTER_CTRL 0x3c --#define QCA8K_MDIO_MASTER_BUSY BIT(31) --#define QCA8K_MDIO_MASTER_EN BIT(30) --#define QCA8K_MDIO_MASTER_READ BIT(27) --#define QCA8K_MDIO_MASTER_WRITE 0 --#define QCA8K_MDIO_MASTER_SUP_PRE BIT(26) --#define QCA8K_MDIO_MASTER_PHY_ADDR_MASK GENMASK(25, 21) --#define QCA8K_MDIO_MASTER_PHY_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_PHY_ADDR_MASK, x) --#define QCA8K_MDIO_MASTER_REG_ADDR_MASK GENMASK(20, 16) --#define QCA8K_MDIO_MASTER_REG_ADDR(x) FIELD_PREP(QCA8K_MDIO_MASTER_REG_ADDR_MASK, x) --#define QCA8K_MDIO_MASTER_DATA_MASK GENMASK(15, 0) --#define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) --#define QCA8K_MDIO_MASTER_MAX_PORTS 5 --#define QCA8K_MDIO_MASTER_MAX_REG 32 --#define QCA8K_GOL_MAC_ADDR0 0x60 --#define QCA8K_GOL_MAC_ADDR1 0x64 --#define QCA8K_MAX_FRAME_SIZE 0x78 --#define QCA8K_REG_PORT_STATUS(_i) (0x07c + (_i) * 4) --#define QCA8K_PORT_STATUS_SPEED GENMASK(1, 0) --#define QCA8K_PORT_STATUS_SPEED_10 0 --#define QCA8K_PORT_STATUS_SPEED_100 0x1 --#define QCA8K_PORT_STATUS_SPEED_1000 0x2 --#define QCA8K_PORT_STATUS_TXMAC BIT(2) --#define QCA8K_PORT_STATUS_RXMAC BIT(3) --#define QCA8K_PORT_STATUS_TXFLOW BIT(4) --#define QCA8K_PORT_STATUS_RXFLOW BIT(5) --#define QCA8K_PORT_STATUS_DUPLEX BIT(6) --#define QCA8K_PORT_STATUS_LINK_UP BIT(8) --#define QCA8K_PORT_STATUS_LINK_AUTO BIT(9) --#define QCA8K_PORT_STATUS_LINK_PAUSE BIT(10) --#define QCA8K_PORT_STATUS_FLOW_AUTO BIT(12) --#define QCA8K_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4)) --#define QCA8K_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2) --#define QCA8K_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0) --#define QCA8K_PORT_HDR_CTRL_ALL 2 --#define QCA8K_PORT_HDR_CTRL_MGMT 1 --#define QCA8K_PORT_HDR_CTRL_NONE 0 --#define QCA8K_REG_SGMII_CTRL 0x0e0 --#define QCA8K_SGMII_EN_PLL BIT(1) --#define QCA8K_SGMII_EN_RX BIT(2) --#define QCA8K_SGMII_EN_TX BIT(3) --#define QCA8K_SGMII_EN_SD BIT(4) --#define QCA8K_SGMII_CLK125M_DELAY BIT(7) --#define QCA8K_SGMII_MODE_CTRL_MASK GENMASK(23, 22) --#define QCA8K_SGMII_MODE_CTRL(x) FIELD_PREP(QCA8K_SGMII_MODE_CTRL_MASK, x) --#define QCA8K_SGMII_MODE_CTRL_BASEX QCA8K_SGMII_MODE_CTRL(0x0) --#define QCA8K_SGMII_MODE_CTRL_PHY QCA8K_SGMII_MODE_CTRL(0x1) --#define QCA8K_SGMII_MODE_CTRL_MAC QCA8K_SGMII_MODE_CTRL(0x2) -- --/* MAC_PWR_SEL registers */ --#define QCA8K_REG_MAC_PWR_SEL 0x0e4 --#define QCA8K_MAC_PWR_RGMII1_1_8V BIT(18) --#define QCA8K_MAC_PWR_RGMII0_1_8V BIT(19) -- --/* EEE control registers */ --#define QCA8K_REG_EEE_CTRL 0x100 --#define QCA8K_REG_EEE_CTRL_LPI_EN(_i) ((_i + 1) * 2) -- --/* TRUNK_HASH_EN registers */ --#define QCA8K_TRUNK_HASH_EN_CTRL 0x270 --#define QCA8K_TRUNK_HASH_SIP_EN BIT(3) --#define QCA8K_TRUNK_HASH_DIP_EN BIT(2) --#define QCA8K_TRUNK_HASH_SA_EN BIT(1) --#define QCA8K_TRUNK_HASH_DA_EN BIT(0) --#define QCA8K_TRUNK_HASH_MASK GENMASK(3, 0) -- --/* ACL registers */ --#define QCA8K_REG_PORT_VLAN_CTRL0(_i) (0x420 + (_i * 8)) --#define QCA8K_PORT_VLAN_CVID_MASK GENMASK(27, 16) --#define QCA8K_PORT_VLAN_CVID(x) FIELD_PREP(QCA8K_PORT_VLAN_CVID_MASK, x) --#define QCA8K_PORT_VLAN_SVID_MASK GENMASK(11, 0) --#define QCA8K_PORT_VLAN_SVID(x) FIELD_PREP(QCA8K_PORT_VLAN_SVID_MASK, x) --#define QCA8K_REG_PORT_VLAN_CTRL1(_i) (0x424 + (_i * 8)) --#define QCA8K_REG_IPV4_PRI_BASE_ADDR 0x470 --#define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474 -- --/* Lookup registers */ --#define QCA8K_REG_ATU_DATA0 0x600 --#define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24) --#define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16) --#define QCA8K_ATU_ADDR4_MASK GENMASK(15, 8) --#define QCA8K_ATU_ADDR5_MASK GENMASK(7, 0) --#define QCA8K_REG_ATU_DATA1 0x604 --#define QCA8K_ATU_PORT_MASK GENMASK(22, 16) --#define QCA8K_ATU_ADDR0_MASK GENMASK(15, 8) --#define QCA8K_ATU_ADDR1_MASK GENMASK(7, 0) --#define QCA8K_REG_ATU_DATA2 0x608 --#define QCA8K_ATU_VID_MASK GENMASK(19, 8) --#define QCA8K_ATU_STATUS_MASK GENMASK(3, 0) --#define QCA8K_ATU_STATUS_STATIC 0xf --#define QCA8K_REG_ATU_FUNC 0x60c --#define QCA8K_ATU_FUNC_BUSY BIT(31) --#define QCA8K_ATU_FUNC_PORT_EN BIT(14) --#define QCA8K_ATU_FUNC_MULTI_EN BIT(13) --#define QCA8K_ATU_FUNC_FULL BIT(12) --#define QCA8K_ATU_FUNC_PORT_MASK GENMASK(11, 8) --#define QCA8K_REG_VTU_FUNC0 0x610 --#define QCA8K_VTU_FUNC0_VALID BIT(20) --#define QCA8K_VTU_FUNC0_IVL_EN BIT(19) --/* QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(17, 4) -- * It does contain VLAN_MODE for each port [5:4] for port0, -- * [7:6] for port1 ... [17:16] for port6. Use virtual port -- * define to handle this. -- */ --#define QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i) (4 + (_i) * 2) --#define QCA8K_VTU_FUNC0_EG_MODE_MASK GENMASK(1, 0) --#define QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(_i) (GENMASK(1, 0) << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) --#define QCA8K_VTU_FUNC0_EG_MODE_UNMOD FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x0) --#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNMOD(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNMOD << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) --#define QCA8K_VTU_FUNC0_EG_MODE_UNTAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x1) --#define QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_UNTAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) --#define QCA8K_VTU_FUNC0_EG_MODE_TAG FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x2) --#define QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(_i) (QCA8K_VTU_FUNC0_EG_MODE_TAG << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) --#define QCA8K_VTU_FUNC0_EG_MODE_NOT FIELD_PREP(QCA8K_VTU_FUNC0_EG_MODE_MASK, 0x3) --#define QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(_i) (QCA8K_VTU_FUNC0_EG_MODE_NOT << QCA8K_VTU_FUNC0_EG_MODE_PORT_SHIFT(_i)) --#define QCA8K_REG_VTU_FUNC1 0x614 --#define QCA8K_VTU_FUNC1_BUSY BIT(31) --#define QCA8K_VTU_FUNC1_VID_MASK GENMASK(27, 16) --#define QCA8K_VTU_FUNC1_FULL BIT(4) --#define QCA8K_REG_ATU_CTRL 0x618 --#define QCA8K_ATU_AGE_TIME_MASK GENMASK(15, 0) --#define QCA8K_ATU_AGE_TIME(x) FIELD_PREP(QCA8K_ATU_AGE_TIME_MASK, (x)) --#define QCA8K_REG_GLOBAL_FW_CTRL0 0x620 --#define QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) --#define QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM GENMASK(7, 4) --#define QCA8K_REG_GLOBAL_FW_CTRL1 0x624 --#define QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24) --#define QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16) --#define QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8) --#define QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0) --#define QCA8K_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc) --#define QCA8K_PORT_LOOKUP_MEMBER GENMASK(6, 0) --#define QCA8K_PORT_LOOKUP_VLAN_MODE_MASK GENMASK(9, 8) --#define QCA8K_PORT_LOOKUP_VLAN_MODE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, x) --#define QCA8K_PORT_LOOKUP_VLAN_MODE_NONE QCA8K_PORT_LOOKUP_VLAN_MODE(0x0) --#define QCA8K_PORT_LOOKUP_VLAN_MODE_FALLBACK QCA8K_PORT_LOOKUP_VLAN_MODE(0x1) --#define QCA8K_PORT_LOOKUP_VLAN_MODE_CHECK QCA8K_PORT_LOOKUP_VLAN_MODE(0x2) --#define QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE QCA8K_PORT_LOOKUP_VLAN_MODE(0x3) --#define QCA8K_PORT_LOOKUP_STATE_MASK GENMASK(18, 16) --#define QCA8K_PORT_LOOKUP_STATE(x) FIELD_PREP(QCA8K_PORT_LOOKUP_STATE_MASK, x) --#define QCA8K_PORT_LOOKUP_STATE_DISABLED QCA8K_PORT_LOOKUP_STATE(0x0) --#define QCA8K_PORT_LOOKUP_STATE_BLOCKING QCA8K_PORT_LOOKUP_STATE(0x1) --#define QCA8K_PORT_LOOKUP_STATE_LISTENING QCA8K_PORT_LOOKUP_STATE(0x2) --#define QCA8K_PORT_LOOKUP_STATE_LEARNING QCA8K_PORT_LOOKUP_STATE(0x3) --#define QCA8K_PORT_LOOKUP_STATE_FORWARD QCA8K_PORT_LOOKUP_STATE(0x4) --#define QCA8K_PORT_LOOKUP_LEARN BIT(20) --#define QCA8K_PORT_LOOKUP_ING_MIRROR_EN BIT(25) -- --#define QCA8K_REG_GOL_TRUNK_CTRL0 0x700 --/* 4 max trunk first -- * first 6 bit for member bitmap -- * 7th bit is to enable trunk port -- */ --#define QCA8K_REG_GOL_TRUNK_SHIFT(_i) ((_i) * 8) --#define QCA8K_REG_GOL_TRUNK_EN_MASK BIT(7) --#define QCA8K_REG_GOL_TRUNK_EN(_i) (QCA8K_REG_GOL_TRUNK_EN_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) --#define QCA8K_REG_GOL_TRUNK_MEMBER_MASK GENMASK(6, 0) --#define QCA8K_REG_GOL_TRUNK_MEMBER(_i) (QCA8K_REG_GOL_TRUNK_MEMBER_MASK << QCA8K_REG_GOL_TRUNK_SHIFT(_i)) --/* 0x704 for TRUNK 0-1 --- 0x708 for TRUNK 2-3 */ --#define QCA8K_REG_GOL_TRUNK_CTRL(_i) (0x704 + (((_i) / 2) * 4)) --#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK GENMASK(3, 0) --#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK BIT(3) --#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK GENMASK(2, 0) --#define QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i) (((_i) / 2) * 16) --#define QCA8K_REG_GOL_MEM_ID_SHIFT(_i) ((_i) * 4) --/* Complex shift: FIRST shift for port THEN shift for trunk */ --#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j) (QCA8K_REG_GOL_MEM_ID_SHIFT(_j) + QCA8K_REG_GOL_TRUNK_ID_SHIFT(_i)) --#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) --#define QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(_i, _j) (QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(_i, _j)) -- --#define QCA8K_REG_GLOBAL_FC_THRESH 0x800 --#define QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK GENMASK(24, 16) --#define QCA8K_GLOBAL_FC_GOL_XON_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK, x) --#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK GENMASK(8, 0) --#define QCA8K_GLOBAL_FC_GOL_XOFF_THRES(x) FIELD_PREP(QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, x) -- --#define QCA8K_REG_PORT_HOL_CTRL0(_i) (0x970 + (_i) * 0x8) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK GENMASK(3, 0) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI0(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI0_BUF_MASK, x) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK GENMASK(7, 4) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI1(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI1_BUF_MASK, x) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK GENMASK(11, 8) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI2(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI2_BUF_MASK, x) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK GENMASK(15, 12) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI3(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI3_BUF_MASK, x) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK GENMASK(19, 16) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI4(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI4_BUF_MASK, x) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK GENMASK(23, 20) --#define QCA8K_PORT_HOL_CTRL0_EG_PRI5(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PRI5_BUF_MASK, x) --#define QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK GENMASK(29, 24) --#define QCA8K_PORT_HOL_CTRL0_EG_PORT(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL0_EG_PORT_BUF_MASK, x) -- --#define QCA8K_REG_PORT_HOL_CTRL1(_i) (0x974 + (_i) * 0x8) --#define QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK GENMASK(3, 0) --#define QCA8K_PORT_HOL_CTRL1_ING(x) FIELD_PREP(QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK, x) --#define QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN BIT(6) --#define QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7) --#define QCA8K_PORT_HOL_CTRL1_WRED_EN BIT(8) --#define QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN BIT(16) -- --/* Pkt edit registers */ --#define QCA8K_EGREES_VLAN_PORT_SHIFT(_i) (16 * ((_i) % 2)) --#define QCA8K_EGREES_VLAN_PORT_MASK(_i) (GENMASK(11, 0) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) --#define QCA8K_EGREES_VLAN_PORT(_i, x) ((x) << QCA8K_EGREES_VLAN_PORT_SHIFT(_i)) --#define QCA8K_EGRESS_VLAN(x) (0x0c70 + (4 * (x / 2))) -- --/* L3 registers */ --#define QCA8K_HROUTER_CONTROL 0xe00 --#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_M GENMASK(17, 16) --#define QCA8K_HROUTER_CONTROL_GLB_LOCKTIME_S 16 --#define QCA8K_HROUTER_CONTROL_ARP_AGE_MODE 1 --#define QCA8K_HROUTER_PBASED_CONTROL1 0xe08 --#define QCA8K_HROUTER_PBASED_CONTROL2 0xe0c --#define QCA8K_HNAT_CONTROL 0xe38 -- --/* MIB registers */ --#define QCA8K_PORT_MIB_COUNTER(_i) (0x1000 + (_i) * 0x100) -- --/* QCA specific MII registers */ --#define MII_ATH_MMD_ADDR 0x0d --#define MII_ATH_MMD_DATA 0x0e -- --enum { -- QCA8K_PORT_SPEED_10M = 0, -- QCA8K_PORT_SPEED_100M = 1, -- QCA8K_PORT_SPEED_1000M = 2, -- QCA8K_PORT_SPEED_ERR = 3, --}; -- --enum qca8k_fdb_cmd { -- QCA8K_FDB_FLUSH = 1, -- QCA8K_FDB_LOAD = 2, -- QCA8K_FDB_PURGE = 3, -- QCA8K_FDB_FLUSH_PORT = 5, -- QCA8K_FDB_NEXT = 6, -- QCA8K_FDB_SEARCH = 7, --}; -- --enum qca8k_vlan_cmd { -- QCA8K_VLAN_FLUSH = 1, -- QCA8K_VLAN_LOAD = 2, -- QCA8K_VLAN_PURGE = 3, -- QCA8K_VLAN_REMOVE_PORT = 4, -- QCA8K_VLAN_NEXT = 5, -- QCA8K_VLAN_READ = 6, --}; -- --enum qca8k_mid_cmd { -- QCA8K_MIB_FLUSH = 1, -- QCA8K_MIB_FLUSH_PORT = 2, -- QCA8K_MIB_CAST = 3, --}; -- --struct qca8k_match_data { -- u8 id; -- bool reduced_package; -- u8 mib_count; --}; -- --enum { -- QCA8K_CPU_PORT0, -- QCA8K_CPU_PORT6, --}; -- --struct qca8k_mgmt_eth_data { -- struct completion rw_done; -- struct mutex mutex; /* Enforce one mdio read/write at time */ -- bool ack; -- u32 seq; -- u32 data[4]; --}; -- --struct qca8k_mib_eth_data { -- struct completion rw_done; -- struct mutex mutex; /* Process one command at time */ -- refcount_t port_parsed; /* Counter to track parsed port */ -- u8 req_port; -- u64 *data; /* pointer to ethtool data */ --}; -- --struct qca8k_ports_config { -- bool sgmii_rx_clk_falling_edge; -- bool sgmii_tx_clk_falling_edge; -- bool sgmii_enable_pll; -- u8 rgmii_rx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ -- u8 rgmii_tx_delay[QCA8K_NUM_CPU_PORTS]; /* 0: CPU port0, 1: CPU port6 */ --}; -- --struct qca8k_mdio_cache { --/* The 32bit switch registers are accessed indirectly. To achieve this we need -- * to set the page of the register. Track the last page that was set to reduce -- * mdio writes -- */ -- u16 page; --/* lo and hi can also be cached and from Documentation we can skip one -- * extra mdio write if lo or hi is didn't change. -- */ -- u16 lo; -- u16 hi; --}; -- --struct qca8k_priv { -- u8 switch_id; -- u8 switch_revision; -- u8 mirror_rx; -- u8 mirror_tx; -- u8 lag_hash_mode; -- /* Each bit correspond to a port. This switch can support a max of 7 port. -- * Bit 1: port enabled. Bit 0: port disabled. -- */ -- u8 port_enabled_map; -- struct qca8k_ports_config ports_config; -- struct regmap *regmap; -- struct mii_bus *bus; -- struct dsa_switch *ds; -- struct mutex reg_mutex; -- struct device *dev; -- struct gpio_desc *reset_gpio; -- struct net_device *mgmt_master; /* Track if mdio/mib Ethernet is available */ -- struct qca8k_mgmt_eth_data mgmt_eth_data; -- struct qca8k_mib_eth_data mib_eth_data; -- struct qca8k_mdio_cache mdio_cache; --}; -- --struct qca8k_mib_desc { -- unsigned int size; -- unsigned int offset; -- const char *name; --}; -- --struct qca8k_fdb { -- u16 vid; -- u8 port_mask; -- u8 aging; -- u8 mac[6]; --}; -- --#endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch b/target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch deleted file mode 100644 index 77fe64632f4019..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-01-net-dsa-qca8k-cache-match-data-to-speed-up-access.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 3bb0844e7bcd0fb0bcfab6202b5edd349ef5250a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:10 +0200 -Subject: [PATCH 01/14] net: dsa: qca8k: cache match data to speed up access - -Using of_device_get_match_data is expensive. Cache match data to speed -up access and rework user of match data to use the new cached value. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k.c | 35 +++++++++++------------------------ - drivers/net/dsa/qca/qca8k.h | 1 + - 2 files changed, 12 insertions(+), 24 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k.c -+++ b/drivers/net/dsa/qca/qca8k.c -@@ -1462,8 +1462,8 @@ static int qca8k_find_cpu_port(struct ds - static int - qca8k_setup_of_pws_reg(struct qca8k_priv *priv) - { -+ const struct qca8k_match_data *data = priv->info; - struct device_node *node = priv->dev->of_node; -- const struct qca8k_match_data *data; - u32 val = 0; - int ret; - -@@ -1472,8 +1472,6 @@ qca8k_setup_of_pws_reg(struct qca8k_priv - * Should be applied by default but we set this just to make sure. - */ - if (priv->switch_id == QCA8K_ID_QCA8327) { -- data = of_device_get_match_data(priv->dev); -- - /* Set the correct package of 148 pin for QCA8327 */ - if (data->reduced_package) - val |= QCA8327_PWS_PACKAGE148_EN; -@@ -2146,23 +2144,19 @@ qca8k_phylink_mac_link_up(struct dsa_swi - static void - qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) - { -- const struct qca8k_match_data *match_data; - struct qca8k_priv *priv = ds->priv; - int i; - - if (stringset != ETH_SS_STATS) - return; - -- match_data = of_device_get_match_data(priv->dev); -- -- for (i = 0; i < match_data->mib_count; i++) -+ for (i = 0; i < priv->info->mib_count; i++) - strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, - ETH_GSTRING_LEN); - } - - static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) - { -- const struct qca8k_match_data *match_data; - struct qca8k_mib_eth_data *mib_eth_data; - struct qca8k_priv *priv = ds->priv; - const struct qca8k_mib_desc *mib; -@@ -2181,10 +2175,9 @@ static void qca8k_mib_autocast_handler(s - if (port != mib_eth_data->req_port) - goto exit; - -- match_data = device_get_match_data(priv->dev); - data = mib_eth_data->data; - -- for (i = 0; i < match_data->mib_count; i++) { -+ for (i = 0; i < priv->info->mib_count; i++) { - mib = &ar8327_mib[i]; - - /* First 3 mib are present in the skb head */ -@@ -2256,7 +2249,6 @@ qca8k_get_ethtool_stats(struct dsa_switc - uint64_t *data) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- const struct qca8k_match_data *match_data; - const struct qca8k_mib_desc *mib; - u32 reg, i, val; - u32 hi = 0; -@@ -2266,9 +2258,7 @@ qca8k_get_ethtool_stats(struct dsa_switc - qca8k_get_ethtool_stats_eth(ds, port, data) > 0) - return; - -- match_data = of_device_get_match_data(priv->dev); -- -- for (i = 0; i < match_data->mib_count; i++) { -+ for (i = 0; i < priv->info->mib_count; i++) { - mib = &ar8327_mib[i]; - reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; - -@@ -2291,15 +2281,12 @@ qca8k_get_ethtool_stats(struct dsa_switc - static int - qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) - { -- const struct qca8k_match_data *match_data; - struct qca8k_priv *priv = ds->priv; - - if (sset != ETH_SS_STATS) - return 0; - -- match_data = of_device_get_match_data(priv->dev); -- -- return match_data->mib_count; -+ return priv->info->mib_count; - } - - static int -@@ -3037,14 +3024,11 @@ static const struct dsa_switch_ops qca8k - - static int qca8k_read_switch_id(struct qca8k_priv *priv) - { -- const struct qca8k_match_data *data; - u32 val; - u8 id; - int ret; - -- /* get the switches ID from the compatible */ -- data = of_device_get_match_data(priv->dev); -- if (!data) -+ if (!priv->info) - return -ENODEV; - - ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); -@@ -3052,8 +3036,10 @@ static int qca8k_read_switch_id(struct q - return -ENODEV; - - id = QCA8K_MASK_CTRL_DEVICE_ID(val); -- if (id != data->id) { -- dev_err(priv->dev, "Switch id detected %x but expected %x", id, data->id); -+ if (id != priv->info->id) { -+ dev_err(priv->dev, -+ "Switch id detected %x but expected %x", -+ id, priv->info->id); - return -ENODEV; - } - -@@ -3078,6 +3064,7 @@ qca8k_sw_probe(struct mdio_device *mdiod - if (!priv) - return -ENOMEM; - -+ priv->info = of_device_get_match_data(priv->dev); - priv->bus = mdiodev->bus; - priv->dev = &mdiodev->dev; - ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -393,6 +393,7 @@ struct qca8k_priv { - struct qca8k_mgmt_eth_data mgmt_eth_data; - struct qca8k_mib_eth_data mib_eth_data; - struct qca8k_mdio_cache mdio_cache; -+ const struct qca8k_match_data *info; - }; - - struct qca8k_mib_desc { diff --git a/target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch b/target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch deleted file mode 100644 index 5b2dce4c556ce5..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-02-net-dsa-qca8k-make-mib-autocast-feature-optional.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 533c64bca62a8654f00698bc893f639013e38c7b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:11 +0200 -Subject: [PATCH 02/14] net: dsa: qca8k: make mib autocast feature optional - -Some switch may not support mib autocast feature and require the legacy -way of reading the regs directly. -Make the mib autocast feature optional and permit to declare support for -it using match_data struct in a dedicated qca8k_info_ops struct. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k.c | 11 +++++++++-- - drivers/net/dsa/qca/qca8k.h | 5 +++++ - 2 files changed, 14 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k.c -+++ b/drivers/net/dsa/qca/qca8k.c -@@ -2254,8 +2254,8 @@ qca8k_get_ethtool_stats(struct dsa_switc - u32 hi = 0; - int ret; - -- if (priv->mgmt_master && -- qca8k_get_ethtool_stats_eth(ds, port, data) > 0) -+ if (priv->mgmt_master && priv->info->ops->autocast_mib && -+ priv->info->ops->autocast_mib(ds, port, data) > 0) - return; - - for (i = 0; i < priv->info->mib_count; i++) { -@@ -3187,20 +3187,27 @@ static int qca8k_resume(struct device *d - static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, - qca8k_suspend, qca8k_resume); - -+static const struct qca8k_info_ops qca8xxx_ops = { -+ .autocast_mib = qca8k_get_ethtool_stats_eth, -+}; -+ - static const struct qca8k_match_data qca8327 = { - .id = QCA8K_ID_QCA8327, - .reduced_package = true, - .mib_count = QCA8K_QCA832X_MIB_COUNT, -+ .ops = &qca8xxx_ops, - }; - - static const struct qca8k_match_data qca8328 = { - .id = QCA8K_ID_QCA8327, - .mib_count = QCA8K_QCA832X_MIB_COUNT, -+ .ops = &qca8xxx_ops, - }; - - static const struct qca8k_match_data qca833x = { - .id = QCA8K_ID_QCA8337, - .mib_count = QCA8K_QCA833X_MIB_COUNT, -+ .ops = &qca8xxx_ops, - }; - - static const struct of_device_id qca8k_of_match[] = { ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -324,10 +324,15 @@ enum qca8k_mid_cmd { - QCA8K_MIB_CAST = 3, - }; - -+struct qca8k_info_ops { -+ int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data); -+}; -+ - struct qca8k_match_data { - u8 id; - bool reduced_package; - u8 mib_count; -+ const struct qca8k_info_ops *ops; - }; - - enum { diff --git a/target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch deleted file mode 100644 index afa466693a98c1..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-03-net-dsa-qca8k-move-mib-struct-to-common-code.patch +++ /dev/null @@ -1,6532 +0,0 @@ -From 027152b830434e3632ad5dd678cc5d4740358dbb Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:12 +0200 -Subject: [PATCH 03/14] net: dsa: qca8k: move mib struct to common code - -The same MIB struct is used by drivers based on qca8k family switch. Move -it to common code to make it accessible also by other drivers. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/Makefile | 1 + - drivers/net/dsa/qca/{qca8k.c => qca8k-8xxx.c} | 51 --------------- - drivers/net/dsa/qca/qca8k-common.c | 63 +++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 3 + - 4 files changed, 67 insertions(+), 51 deletions(-) - rename drivers/net/dsa/qca/{qca8k.c => qca8k-8xxx.c} (98%) - create mode 100644 drivers/net/dsa/qca/qca8k-common.c - ---- a/drivers/net/dsa/qca/Makefile -+++ b/drivers/net/dsa/qca/Makefile -@@ -1,3 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0-only - obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o - obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o -+qca8k-y += qca8k-common.o qca8k-8xxx.o ---- a/drivers/net/dsa/qca/qca8k.c -+++ /dev/null -@@ -1,3237 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Copyright (C) 2009 Felix Fietkau -- * Copyright (C) 2011-2012 Gabor Juhos -- * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. -- * Copyright (c) 2016 John Crispin -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "qca8k.h" -- --#define MIB_DESC(_s, _o, _n) \ -- { \ -- .size = (_s), \ -- .offset = (_o), \ -- .name = (_n), \ -- } -- --static const struct qca8k_mib_desc ar8327_mib[] = { -- MIB_DESC(1, 0x00, "RxBroad"), -- MIB_DESC(1, 0x04, "RxPause"), -- MIB_DESC(1, 0x08, "RxMulti"), -- MIB_DESC(1, 0x0c, "RxFcsErr"), -- MIB_DESC(1, 0x10, "RxAlignErr"), -- MIB_DESC(1, 0x14, "RxRunt"), -- MIB_DESC(1, 0x18, "RxFragment"), -- MIB_DESC(1, 0x1c, "Rx64Byte"), -- MIB_DESC(1, 0x20, "Rx128Byte"), -- MIB_DESC(1, 0x24, "Rx256Byte"), -- MIB_DESC(1, 0x28, "Rx512Byte"), -- MIB_DESC(1, 0x2c, "Rx1024Byte"), -- MIB_DESC(1, 0x30, "Rx1518Byte"), -- MIB_DESC(1, 0x34, "RxMaxByte"), -- MIB_DESC(1, 0x38, "RxTooLong"), -- MIB_DESC(2, 0x3c, "RxGoodByte"), -- MIB_DESC(2, 0x44, "RxBadByte"), -- MIB_DESC(1, 0x4c, "RxOverFlow"), -- MIB_DESC(1, 0x50, "Filtered"), -- MIB_DESC(1, 0x54, "TxBroad"), -- MIB_DESC(1, 0x58, "TxPause"), -- MIB_DESC(1, 0x5c, "TxMulti"), -- MIB_DESC(1, 0x60, "TxUnderRun"), -- MIB_DESC(1, 0x64, "Tx64Byte"), -- MIB_DESC(1, 0x68, "Tx128Byte"), -- MIB_DESC(1, 0x6c, "Tx256Byte"), -- MIB_DESC(1, 0x70, "Tx512Byte"), -- MIB_DESC(1, 0x74, "Tx1024Byte"), -- MIB_DESC(1, 0x78, "Tx1518Byte"), -- MIB_DESC(1, 0x7c, "TxMaxByte"), -- MIB_DESC(1, 0x80, "TxOverSize"), -- MIB_DESC(2, 0x84, "TxByte"), -- MIB_DESC(1, 0x8c, "TxCollision"), -- MIB_DESC(1, 0x90, "TxAbortCol"), -- MIB_DESC(1, 0x94, "TxMultiCol"), -- MIB_DESC(1, 0x98, "TxSingleCol"), -- MIB_DESC(1, 0x9c, "TxExcDefer"), -- MIB_DESC(1, 0xa0, "TxDefer"), -- MIB_DESC(1, 0xa4, "TxLateCol"), -- MIB_DESC(1, 0xa8, "RXUnicast"), -- MIB_DESC(1, 0xac, "TXUnicast"), --}; -- --static void --qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) --{ -- regaddr >>= 1; -- *r1 = regaddr & 0x1e; -- -- regaddr >>= 5; -- *r2 = regaddr & 0x7; -- -- regaddr >>= 3; -- *page = regaddr & 0x3ff; --} -- --static int --qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo) --{ -- u16 *cached_lo = &priv->mdio_cache.lo; -- struct mii_bus *bus = priv->bus; -- int ret; -- -- if (lo == *cached_lo) -- return 0; -- -- ret = bus->write(bus, phy_id, regnum, lo); -- if (ret < 0) -- dev_err_ratelimited(&bus->dev, -- "failed to write qca8k 32bit lo register\n"); -- -- *cached_lo = lo; -- return 0; --} -- --static int --qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi) --{ -- u16 *cached_hi = &priv->mdio_cache.hi; -- struct mii_bus *bus = priv->bus; -- int ret; -- -- if (hi == *cached_hi) -- return 0; -- -- ret = bus->write(bus, phy_id, regnum, hi); -- if (ret < 0) -- dev_err_ratelimited(&bus->dev, -- "failed to write qca8k 32bit hi register\n"); -- -- *cached_hi = hi; -- return 0; --} -- --static int --qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) --{ -- int ret; -- -- ret = bus->read(bus, phy_id, regnum); -- if (ret >= 0) { -- *val = ret; -- ret = bus->read(bus, phy_id, regnum + 1); -- *val |= ret << 16; -- } -- -- if (ret < 0) { -- dev_err_ratelimited(&bus->dev, -- "failed to read qca8k 32bit register\n"); -- *val = 0; -- return ret; -- } -- -- return 0; --} -- --static void --qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val) --{ -- u16 lo, hi; -- int ret; -- -- lo = val & 0xffff; -- hi = (u16)(val >> 16); -- -- ret = qca8k_set_lo(priv, phy_id, regnum, lo); -- if (ret >= 0) -- ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi); --} -- --static int --qca8k_set_page(struct qca8k_priv *priv, u16 page) --{ -- u16 *cached_page = &priv->mdio_cache.page; -- struct mii_bus *bus = priv->bus; -- int ret; -- -- if (page == *cached_page) -- return 0; -- -- ret = bus->write(bus, 0x18, 0, page); -- if (ret < 0) { -- dev_err_ratelimited(&bus->dev, -- "failed to set qca8k page\n"); -- return ret; -- } -- -- *cached_page = page; -- usleep_range(1000, 2000); -- return 0; --} -- --static int --qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) --{ -- return regmap_read(priv->regmap, reg, val); --} -- --static int --qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) --{ -- return regmap_write(priv->regmap, reg, val); --} -- --static int --qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) --{ -- return regmap_update_bits(priv->regmap, reg, mask, write_val); --} -- --static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) --{ -- struct qca8k_mgmt_eth_data *mgmt_eth_data; -- struct qca8k_priv *priv = ds->priv; -- struct qca_mgmt_ethhdr *mgmt_ethhdr; -- u8 len, cmd; -- -- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); -- mgmt_eth_data = &priv->mgmt_eth_data; -- -- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); -- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); -- -- /* Make sure the seq match the requested packet */ -- if (mgmt_ethhdr->seq == mgmt_eth_data->seq) -- mgmt_eth_data->ack = true; -- -- if (cmd == MDIO_READ) { -- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; -- -- /* Get the rest of the 12 byte of data. -- * The read/write function will extract the requested data. -- */ -- if (len > QCA_HDR_MGMT_DATA1_LEN) -- memcpy(mgmt_eth_data->data + 1, skb->data, -- QCA_HDR_MGMT_DATA2_LEN); -- } -- -- complete(&mgmt_eth_data->rw_done); --} -- --static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val, -- int priority, unsigned int len) --{ -- struct qca_mgmt_ethhdr *mgmt_ethhdr; -- unsigned int real_len; -- struct sk_buff *skb; -- u32 *data2; -- u16 hdr; -- -- skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); -- if (!skb) -- return NULL; -- -- /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte -- * Actually for some reason the steps are: -- * 0: nothing -- * 1-4: first 4 byte -- * 5-6: first 12 byte -- * 7-15: all 16 byte -- */ -- if (len == 16) -- real_len = 15; -- else -- real_len = len; -- -- skb_reset_mac_header(skb); -- skb_set_network_header(skb, skb->len); -- -- mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); -- -- hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); -- hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority); -- hdr |= QCA_HDR_XMIT_FROM_CPU; -- hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); -- hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); -- -- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); -- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); -- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); -- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, -- QCA_HDR_MGMT_CHECK_CODE_VAL); -- -- if (cmd == MDIO_WRITE) -- mgmt_ethhdr->mdio_data = *val; -- -- mgmt_ethhdr->hdr = htons(hdr); -- -- data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); -- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) -- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); -- -- return skb; --} -- --static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) --{ -- struct qca_mgmt_ethhdr *mgmt_ethhdr; -- -- mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; -- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); --} -- --static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; -- struct sk_buff *skb; -- bool ack; -- int ret; -- -- skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL, -- QCA8K_ETHERNET_MDIO_PRIORITY, len); -- if (!skb) -- return -ENOMEM; -- -- mutex_lock(&mgmt_eth_data->mutex); -- -- /* Check mgmt_master if is operational */ -- if (!priv->mgmt_master) { -- kfree_skb(skb); -- mutex_unlock(&mgmt_eth_data->mutex); -- return -EINVAL; -- } -- -- skb->dev = priv->mgmt_master; -- -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the mdio pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(skb); -- -- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); -- -- *val = mgmt_eth_data->data[0]; -- if (len > QCA_HDR_MGMT_DATA1_LEN) -- memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN); -- -- ack = mgmt_eth_data->ack; -- -- mutex_unlock(&mgmt_eth_data->mutex); -- -- if (ret <= 0) -- return -ETIMEDOUT; -- -- if (!ack) -- return -EINVAL; -- -- return 0; --} -- --static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; -- struct sk_buff *skb; -- bool ack; -- int ret; -- -- skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val, -- QCA8K_ETHERNET_MDIO_PRIORITY, len); -- if (!skb) -- return -ENOMEM; -- -- mutex_lock(&mgmt_eth_data->mutex); -- -- /* Check mgmt_master if is operational */ -- if (!priv->mgmt_master) { -- kfree_skb(skb); -- mutex_unlock(&mgmt_eth_data->mutex); -- return -EINVAL; -- } -- -- skb->dev = priv->mgmt_master; -- -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the mdio pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(skb); -- -- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); -- -- ack = mgmt_eth_data->ack; -- -- mutex_unlock(&mgmt_eth_data->mutex); -- -- if (ret <= 0) -- return -ETIMEDOUT; -- -- if (!ack) -- return -EINVAL; -- -- return 0; --} -- --static int --qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) --{ -- u32 val = 0; -- int ret; -- -- ret = qca8k_read_eth(priv, reg, &val, sizeof(val)); -- if (ret) -- return ret; -- -- val &= ~mask; -- val |= write_val; -- -- return qca8k_write_eth(priv, reg, &val, sizeof(val)); --} -- --static int --qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- int i, count = len / sizeof(u32), ret; -- -- if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) -- return 0; -- -- for (i = 0; i < count; i++) { -- ret = regmap_read(priv->regmap, reg + (i * 4), val + i); -- if (ret < 0) -- return ret; -- } -- -- return 0; --} -- --static int --qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- int i, count = len / sizeof(u32), ret; -- u32 tmp; -- -- if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) -- return 0; -- -- for (i = 0; i < count; i++) { -- tmp = val[i]; -- -- ret = regmap_write(priv->regmap, reg + (i * 4), tmp); -- if (ret < 0) -- return ret; -- } -- -- return 0; --} -- --static int --qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -- struct mii_bus *bus = priv->bus; -- u16 r1, r2, page; -- int ret; -- -- if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) -- return 0; -- -- qca8k_split_addr(reg, &r1, &r2, &page); -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -- -- ret = qca8k_set_page(priv, page); -- if (ret < 0) -- goto exit; -- -- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val); -- --exit: -- mutex_unlock(&bus->mdio_lock); -- return ret; --} -- --static int --qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -- struct mii_bus *bus = priv->bus; -- u16 r1, r2, page; -- int ret; -- -- if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) -- return 0; -- -- qca8k_split_addr(reg, &r1, &r2, &page); -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -- -- ret = qca8k_set_page(priv, page); -- if (ret < 0) -- goto exit; -- -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -- --exit: -- mutex_unlock(&bus->mdio_lock); -- return ret; --} -- --static int --qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -- struct mii_bus *bus = priv->bus; -- u16 r1, r2, page; -- u32 val; -- int ret; -- -- if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) -- return 0; -- -- qca8k_split_addr(reg, &r1, &r2, &page); -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -- -- ret = qca8k_set_page(priv, page); -- if (ret < 0) -- goto exit; -- -- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); -- if (ret < 0) -- goto exit; -- -- val &= ~mask; -- val |= write_val; -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -- --exit: -- mutex_unlock(&bus->mdio_lock); -- -- return ret; --} -- --static const struct regmap_range qca8k_readable_ranges[] = { -- regmap_reg_range(0x0000, 0x00e4), /* Global control */ -- regmap_reg_range(0x0100, 0x0168), /* EEE control */ -- regmap_reg_range(0x0200, 0x0270), /* Parser control */ -- regmap_reg_range(0x0400, 0x0454), /* ACL */ -- regmap_reg_range(0x0600, 0x0718), /* Lookup */ -- regmap_reg_range(0x0800, 0x0b70), /* QM */ -- regmap_reg_range(0x0c00, 0x0c80), /* PKT */ -- regmap_reg_range(0x0e00, 0x0e98), /* L3 */ -- regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ -- regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ -- regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ -- regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ -- regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ -- regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ -- regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ -- --}; -- --static const struct regmap_access_table qca8k_readable_table = { -- .yes_ranges = qca8k_readable_ranges, -- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), --}; -- --static struct regmap_config qca8k_regmap_config = { -- .reg_bits = 16, -- .val_bits = 32, -- .reg_stride = 4, -- .max_register = 0x16ac, /* end MIB - Port6 range */ -- .reg_read = qca8k_regmap_read, -- .reg_write = qca8k_regmap_write, -- .reg_update_bits = qca8k_regmap_update_bits, -- .rd_table = &qca8k_readable_table, -- .disable_locking = true, /* Locking is handled by qca8k read/write */ -- .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ --}; -- --static int --qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) --{ -- u32 val; -- -- return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, -- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); --} -- --static int --qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) --{ -- u32 reg[3]; -- int ret; -- -- /* load the ARL table into an array */ -- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -- if (ret) -- return ret; -- -- /* vid - 83:72 */ -- fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); -- /* aging - 67:64 */ -- fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); -- /* portmask - 54:48 */ -- fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); -- /* mac - 47:0 */ -- fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); -- fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); -- fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); -- fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); -- fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); -- fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); -- -- return 0; --} -- --static void --qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, -- u8 aging) --{ -- u32 reg[3] = { 0 }; -- -- /* vid - 83:72 */ -- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); -- /* aging - 67:64 */ -- reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); -- /* portmask - 54:48 */ -- reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); -- /* mac - 47:0 */ -- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); -- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); -- -- /* load the array into the ARL table */ -- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); --} -- --static int --qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) --{ -- u32 reg; -- int ret; -- -- /* Set the command and FDB index */ -- reg = QCA8K_ATU_FUNC_BUSY; -- reg |= cmd; -- if (port >= 0) { -- reg |= QCA8K_ATU_FUNC_PORT_EN; -- reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); -- } -- -- /* Write the function register triggering the table access */ -- ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); -- if (ret) -- return ret; -- -- /* wait for completion */ -- ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); -- if (ret) -- return ret; -- -- /* Check for table full violation when adding an entry */ -- if (cmd == QCA8K_FDB_LOAD) { -- ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); -- if (ret < 0) -- return ret; -- if (reg & QCA8K_ATU_FUNC_FULL) -- return -1; -- } -- -- return 0; --} -- --static int --qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) --{ -- int ret; -- -- qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); -- if (ret < 0) -- return ret; -- -- return qca8k_fdb_read(priv, fdb); --} -- --static int --qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, -- u16 vid, u8 aging) --{ -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_write(priv, vid, port_mask, mac, aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static int --qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) --{ -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_write(priv, vid, port_mask, mac, 0); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static void --qca8k_fdb_flush(struct qca8k_priv *priv) --{ -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); -- mutex_unlock(&priv->reg_mutex); --} -- --static int --qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, -- const u8 *mac, u16 vid) --{ -- struct qca8k_fdb fdb = { 0 }; -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- -- qca8k_fdb_write(priv, vid, 0, mac, 0); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -- if (ret < 0) -- goto exit; -- -- ret = qca8k_fdb_read(priv, &fdb); -- if (ret < 0) -- goto exit; -- -- /* Rule exist. Delete first */ -- if (!fdb.aging) { -- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -- if (ret) -- goto exit; -- } -- -- /* Add port to fdb portmask */ -- fdb.port_mask |= port_mask; -- -- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static int --qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, -- const u8 *mac, u16 vid) --{ -- struct qca8k_fdb fdb = { 0 }; -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- -- qca8k_fdb_write(priv, vid, 0, mac, 0); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -- if (ret < 0) -- goto exit; -- -- /* Rule doesn't exist. Why delete? */ -- if (!fdb.aging) { -- ret = -EINVAL; -- goto exit; -- } -- -- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -- if (ret) -- goto exit; -- -- /* Only port in the rule is this port. Don't re insert */ -- if (fdb.port_mask == port_mask) -- goto exit; -- -- /* Remove port from port mask */ -- fdb.port_mask &= ~port_mask; -- -- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static int --qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) --{ -- u32 reg; -- int ret; -- -- /* Set the command and VLAN index */ -- reg = QCA8K_VTU_FUNC1_BUSY; -- reg |= cmd; -- reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); -- -- /* Write the function register triggering the table access */ -- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); -- if (ret) -- return ret; -- -- /* wait for completion */ -- ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); -- if (ret) -- return ret; -- -- /* Check for table full violation when adding an entry */ -- if (cmd == QCA8K_VLAN_LOAD) { -- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); -- if (ret < 0) -- return ret; -- if (reg & QCA8K_VTU_FUNC1_FULL) -- return -ENOMEM; -- } -- -- return 0; --} -- --static int --qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) --{ -- u32 reg; -- int ret; -- -- /* -- We do the right thing with VLAN 0 and treat it as untagged while -- preserving the tag on egress. -- */ -- if (vid == 0) -- return 0; -- -- mutex_lock(&priv->reg_mutex); -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -- if (ret < 0) -- goto out; -- -- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -- if (ret < 0) -- goto out; -- reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; -- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -- if (untagged) -- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); -- else -- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); -- -- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -- if (ret) -- goto out; -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -- --out: -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static int --qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) --{ -- u32 reg, mask; -- int ret, i; -- bool del; -- -- mutex_lock(&priv->reg_mutex); -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -- if (ret < 0) -- goto out; -- -- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -- if (ret < 0) -- goto out; -- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); -- -- /* Check if we're the last member to be removed */ -- del = true; -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); -- -- if ((reg & mask) != mask) { -- del = false; -- break; -- } -- } -- -- if (del) { -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); -- } else { -- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -- if (ret) -- goto out; -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -- } -- --out: -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static int --qca8k_mib_init(struct qca8k_priv *priv) --{ -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | -- QCA8K_MIB_BUSY); -- if (ret) -- goto exit; -- -- ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); -- if (ret) -- goto exit; -- -- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); -- if (ret) -- goto exit; -- -- ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static void --qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) --{ -- u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; -- -- /* Port 0 and 6 have no internal PHY */ -- if (port > 0 && port < 6) -- mask |= QCA8K_PORT_STATUS_LINK_AUTO; -- -- if (enable) -- regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); -- else -- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); --} -- --static int --qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, -- struct sk_buff *read_skb, u32 *val) --{ -- struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL); -- bool ack; -- int ret; -- -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the copy pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(skb); -- -- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- QCA8K_ETHERNET_TIMEOUT); -- -- ack = mgmt_eth_data->ack; -- -- if (ret <= 0) -- return -ETIMEDOUT; -- -- if (!ack) -- return -EINVAL; -- -- *val = mgmt_eth_data->data[0]; -- -- return 0; --} -- --static int --qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, -- int regnum, u16 data) --{ -- struct sk_buff *write_skb, *clear_skb, *read_skb; -- struct qca8k_mgmt_eth_data *mgmt_eth_data; -- u32 write_val, clear_val = 0, val; -- struct net_device *mgmt_master; -- int ret, ret1; -- bool ack; -- -- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -- return -EINVAL; -- -- mgmt_eth_data = &priv->mgmt_eth_data; -- -- write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -- QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -- QCA8K_MDIO_MASTER_REG_ADDR(regnum); -- -- if (read) { -- write_val |= QCA8K_MDIO_MASTER_READ; -- } else { -- write_val |= QCA8K_MDIO_MASTER_WRITE; -- write_val |= QCA8K_MDIO_MASTER_DATA(data); -- } -- -- /* Prealloc all the needed skb before the lock */ -- write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val, -- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val)); -- if (!write_skb) -- return -ENOMEM; -- -- clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, -- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); -- if (!clear_skb) { -- ret = -ENOMEM; -- goto err_clear_skb; -- } -- -- read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val, -- QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); -- if (!read_skb) { -- ret = -ENOMEM; -- goto err_read_skb; -- } -- -- /* Actually start the request: -- * 1. Send mdio master packet -- * 2. Busy Wait for mdio master command -- * 3. Get the data if we are reading -- * 4. Reset the mdio master (even with error) -- */ -- mutex_lock(&mgmt_eth_data->mutex); -- -- /* Check if mgmt_master is operational */ -- mgmt_master = priv->mgmt_master; -- if (!mgmt_master) { -- mutex_unlock(&mgmt_eth_data->mutex); -- ret = -EINVAL; -- goto err_mgmt_master; -- } -- -- read_skb->dev = mgmt_master; -- clear_skb->dev = mgmt_master; -- write_skb->dev = mgmt_master; -- -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the write pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(write_skb); -- -- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- QCA8K_ETHERNET_TIMEOUT); -- -- ack = mgmt_eth_data->ack; -- -- if (ret <= 0) { -- ret = -ETIMEDOUT; -- kfree_skb(read_skb); -- goto exit; -- } -- -- if (!ack) { -- ret = -EINVAL; -- kfree_skb(read_skb); -- goto exit; -- } -- -- ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1, -- !(val & QCA8K_MDIO_MASTER_BUSY), 0, -- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -- mgmt_eth_data, read_skb, &val); -- -- if (ret < 0 && ret1 < 0) { -- ret = ret1; -- goto exit; -- } -- -- if (read) { -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the read pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(read_skb); -- -- ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- QCA8K_ETHERNET_TIMEOUT); -- -- ack = mgmt_eth_data->ack; -- -- if (ret <= 0) { -- ret = -ETIMEDOUT; -- goto exit; -- } -- -- if (!ack) { -- ret = -EINVAL; -- goto exit; -- } -- -- ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK; -- } else { -- kfree_skb(read_skb); -- } --exit: -- reinit_completion(&mgmt_eth_data->rw_done); -- -- /* Increment seq_num and set it in the clear pkt */ -- mgmt_eth_data->seq++; -- qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq); -- mgmt_eth_data->ack = false; -- -- dev_queue_xmit(clear_skb); -- -- wait_for_completion_timeout(&mgmt_eth_data->rw_done, -- QCA8K_ETHERNET_TIMEOUT); -- -- mutex_unlock(&mgmt_eth_data->mutex); -- -- return ret; -- -- /* Error handling before lock */ --err_mgmt_master: -- kfree_skb(read_skb); --err_read_skb: -- kfree_skb(clear_skb); --err_clear_skb: -- kfree_skb(write_skb); -- -- return ret; --} -- --static u32 --qca8k_port_to_phy(int port) --{ -- /* From Andrew Lunn: -- * Port 0 has no internal phy. -- * Port 1 has an internal PHY at MDIO address 0. -- * Port 2 has an internal PHY at MDIO address 1. -- * ... -- * Port 5 has an internal PHY at MDIO address 4. -- * Port 6 has no internal PHY. -- */ -- -- return port - 1; --} -- --static int --qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) --{ -- u16 r1, r2, page; -- u32 val; -- int ret, ret1; -- -- qca8k_split_addr(reg, &r1, &r2, &page); -- -- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, -- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -- bus, 0x10 | r2, r1, &val); -- -- /* Check if qca8k_read has failed for a different reason -- * before returnting -ETIMEDOUT -- */ -- if (ret < 0 && ret1 < 0) -- return ret1; -- -- return ret; --} -- --static int --qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) --{ -- struct mii_bus *bus = priv->bus; -- u16 r1, r2, page; -- u32 val; -- int ret; -- -- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -- return -EINVAL; -- -- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -- QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -- QCA8K_MDIO_MASTER_REG_ADDR(regnum) | -- QCA8K_MDIO_MASTER_DATA(data); -- -- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -- -- ret = qca8k_set_page(priv, page); -- if (ret) -- goto exit; -- -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -- -- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, -- QCA8K_MDIO_MASTER_BUSY); -- --exit: -- /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(priv, 0x10 | r2, r1, 0); -- -- mutex_unlock(&bus->mdio_lock); -- -- return ret; --} -- --static int --qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) --{ -- struct mii_bus *bus = priv->bus; -- u16 r1, r2, page; -- u32 val; -- int ret; -- -- if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -- return -EINVAL; -- -- val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -- QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -- QCA8K_MDIO_MASTER_REG_ADDR(regnum); -- -- qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -- -- ret = qca8k_set_page(priv, page); -- if (ret) -- goto exit; -- -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -- -- ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, -- QCA8K_MDIO_MASTER_BUSY); -- if (ret) -- goto exit; -- -- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); -- --exit: -- /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(priv, 0x10 | r2, r1, 0); -- -- mutex_unlock(&bus->mdio_lock); -- -- if (ret >= 0) -- ret = val & QCA8K_MDIO_MASTER_DATA_MASK; -- -- return ret; --} -- --static int --qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) --{ -- struct qca8k_priv *priv = slave_bus->priv; -- int ret; -- -- /* Use mdio Ethernet when available, fallback to legacy one on error */ -- ret = qca8k_phy_eth_command(priv, false, phy, regnum, data); -- if (!ret) -- return 0; -- -- return qca8k_mdio_write(priv, phy, regnum, data); --} -- --static int --qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) --{ -- struct qca8k_priv *priv = slave_bus->priv; -- int ret; -- -- /* Use mdio Ethernet when available, fallback to legacy one on error */ -- ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0); -- if (ret >= 0) -- return ret; -- -- ret = qca8k_mdio_read(priv, phy, regnum); -- -- if (ret < 0) -- return 0xffff; -- -- return ret; --} -- --static int --qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) --{ -- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; -- -- return qca8k_internal_mdio_write(slave_bus, port, regnum, data); --} -- --static int --qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) --{ -- port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; -- -- return qca8k_internal_mdio_read(slave_bus, port, regnum); --} -- --static int --qca8k_mdio_register(struct qca8k_priv *priv) --{ -- struct dsa_switch *ds = priv->ds; -- struct device_node *mdio; -- struct mii_bus *bus; -- -- bus = devm_mdiobus_alloc(ds->dev); -- if (!bus) -- return -ENOMEM; -- -- bus->priv = (void *)priv; -- snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", -- ds->dst->index, ds->index); -- bus->parent = ds->dev; -- bus->phy_mask = ~ds->phys_mii_mask; -- ds->slave_mii_bus = bus; -- -- /* Check if the devicetree declare the port:phy mapping */ -- mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); -- if (of_device_is_available(mdio)) { -- bus->name = "qca8k slave mii"; -- bus->read = qca8k_internal_mdio_read; -- bus->write = qca8k_internal_mdio_write; -- return devm_of_mdiobus_register(priv->dev, bus, mdio); -- } -- -- /* If a mapping can't be found the legacy mapping is used, -- * using the qca8k_port_to_phy function -- */ -- bus->name = "qca8k-legacy slave mii"; -- bus->read = qca8k_legacy_mdio_read; -- bus->write = qca8k_legacy_mdio_write; -- return devm_mdiobus_register(priv->dev, bus); --} -- --static int --qca8k_setup_mdio_bus(struct qca8k_priv *priv) --{ -- u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; -- struct device_node *ports, *port; -- phy_interface_t mode; -- int err; -- -- ports = of_get_child_by_name(priv->dev->of_node, "ports"); -- if (!ports) -- ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports"); -- -- if (!ports) -- return -EINVAL; -- -- for_each_available_child_of_node(ports, port) { -- err = of_property_read_u32(port, "reg", ®); -- if (err) { -- of_node_put(port); -- of_node_put(ports); -- return err; -- } -- -- if (!dsa_is_user_port(priv->ds, reg)) -- continue; -- -- of_get_phy_mode(port, &mode); -- -- if (of_property_read_bool(port, "phy-handle") && -- mode != PHY_INTERFACE_MODE_INTERNAL) -- external_mdio_mask |= BIT(reg); -- else -- internal_mdio_mask |= BIT(reg); -- } -- -- of_node_put(ports); -- if (!external_mdio_mask && !internal_mdio_mask) { -- dev_err(priv->dev, "no PHYs are defined.\n"); -- return -EINVAL; -- } -- -- /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through -- * the MDIO_MASTER register also _disconnects_ the external MDC -- * passthrough to the internal PHYs. It's not possible to use both -- * configurations at the same time! -- * -- * Because this came up during the review process: -- * If the external mdio-bus driver is capable magically disabling -- * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's -- * accessors for the time being, it would be possible to pull this -- * off. -- */ -- if (!!external_mdio_mask && !!internal_mdio_mask) { -- dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n"); -- return -EINVAL; -- } -- -- if (external_mdio_mask) { -- /* Make sure to disable the internal mdio bus in cases -- * a dt-overlay and driver reload changed the configuration -- */ -- -- return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL, -- QCA8K_MDIO_MASTER_EN); -- } -- -- return qca8k_mdio_register(priv); --} -- --static int --qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) --{ -- u32 mask = 0; -- int ret = 0; -- -- /* SoC specific settings for ipq8064. -- * If more device require this consider adding -- * a dedicated binding. -- */ -- if (of_machine_is_compatible("qcom,ipq8064")) -- mask |= QCA8K_MAC_PWR_RGMII0_1_8V; -- -- /* SoC specific settings for ipq8065 */ -- if (of_machine_is_compatible("qcom,ipq8065")) -- mask |= QCA8K_MAC_PWR_RGMII1_1_8V; -- -- if (mask) { -- ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, -- QCA8K_MAC_PWR_RGMII0_1_8V | -- QCA8K_MAC_PWR_RGMII1_1_8V, -- mask); -- } -- -- return ret; --} -- --static int qca8k_find_cpu_port(struct dsa_switch *ds) --{ -- struct qca8k_priv *priv = ds->priv; -- -- /* Find the connected cpu port. Valid port are 0 or 6 */ -- if (dsa_is_cpu_port(ds, 0)) -- return 0; -- -- dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6"); -- -- if (dsa_is_cpu_port(ds, 6)) -- return 6; -- -- return -EINVAL; --} -- --static int --qca8k_setup_of_pws_reg(struct qca8k_priv *priv) --{ -- const struct qca8k_match_data *data = priv->info; -- struct device_node *node = priv->dev->of_node; -- u32 val = 0; -- int ret; -- -- /* QCA8327 require to set to the correct mode. -- * His bigger brother QCA8328 have the 172 pin layout. -- * Should be applied by default but we set this just to make sure. -- */ -- if (priv->switch_id == QCA8K_ID_QCA8327) { -- /* Set the correct package of 148 pin for QCA8327 */ -- if (data->reduced_package) -- val |= QCA8327_PWS_PACKAGE148_EN; -- -- ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, -- val); -- if (ret) -- return ret; -- } -- -- if (of_property_read_bool(node, "qca,ignore-power-on-sel")) -- val |= QCA8K_PWS_POWER_ON_SEL; -- -- if (of_property_read_bool(node, "qca,led-open-drain")) { -- if (!(val & QCA8K_PWS_POWER_ON_SEL)) { -- dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set."); -- return -EINVAL; -- } -- -- val |= QCA8K_PWS_LED_OPEN_EN_CSR; -- } -- -- return qca8k_rmw(priv, QCA8K_REG_PWS, -- QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, -- val); --} -- --static int --qca8k_parse_port_config(struct qca8k_priv *priv) --{ -- int port, cpu_port_index = -1, ret; -- struct device_node *port_dn; -- phy_interface_t mode; -- struct dsa_port *dp; -- u32 delay; -- -- /* We have 2 CPU port. Check them */ -- for (port = 0; port < QCA8K_NUM_PORTS; port++) { -- /* Skip every other port */ -- if (port != 0 && port != 6) -- continue; -- -- dp = dsa_to_port(priv->ds, port); -- port_dn = dp->dn; -- cpu_port_index++; -- -- if (!of_device_is_available(port_dn)) -- continue; -- -- ret = of_get_phy_mode(port_dn, &mode); -- if (ret) -- continue; -- -- switch (mode) { -- case PHY_INTERFACE_MODE_RGMII: -- case PHY_INTERFACE_MODE_RGMII_ID: -- case PHY_INTERFACE_MODE_RGMII_TXID: -- case PHY_INTERFACE_MODE_RGMII_RXID: -- case PHY_INTERFACE_MODE_SGMII: -- delay = 0; -- -- if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay)) -- /* Switch regs accept value in ns, convert ps to ns */ -- delay = delay / 1000; -- else if (mode == PHY_INTERFACE_MODE_RGMII_ID || -- mode == PHY_INTERFACE_MODE_RGMII_TXID) -- delay = 1; -- -- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { -- dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); -- delay = 3; -- } -- -- priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay; -- -- delay = 0; -- -- if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay)) -- /* Switch regs accept value in ns, convert ps to ns */ -- delay = delay / 1000; -- else if (mode == PHY_INTERFACE_MODE_RGMII_ID || -- mode == PHY_INTERFACE_MODE_RGMII_RXID) -- delay = 2; -- -- if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { -- dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); -- delay = 3; -- } -- -- priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay; -- -- /* Skip sgmii parsing for rgmii* mode */ -- if (mode == PHY_INTERFACE_MODE_RGMII || -- mode == PHY_INTERFACE_MODE_RGMII_ID || -- mode == PHY_INTERFACE_MODE_RGMII_TXID || -- mode == PHY_INTERFACE_MODE_RGMII_RXID) -- break; -- -- if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) -- priv->ports_config.sgmii_tx_clk_falling_edge = true; -- -- if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) -- priv->ports_config.sgmii_rx_clk_falling_edge = true; -- -- if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) { -- priv->ports_config.sgmii_enable_pll = true; -- -- if (priv->switch_id == QCA8K_ID_QCA8327) { -- dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling"); -- priv->ports_config.sgmii_enable_pll = false; -- } -- -- if (priv->switch_revision < 2) -- dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more."); -- } -- -- break; -- default: -- continue; -- } -- } -- -- return 0; --} -- --static int --qca8k_setup(struct dsa_switch *ds) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int cpu_port, ret, i; -- u32 mask; -- -- cpu_port = qca8k_find_cpu_port(ds); -- if (cpu_port < 0) { -- dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6"); -- return cpu_port; -- } -- -- /* Parse CPU port config to be later used in phy_link mac_config */ -- ret = qca8k_parse_port_config(priv); -- if (ret) -- return ret; -- -- ret = qca8k_setup_mdio_bus(priv); -- if (ret) -- return ret; -- -- ret = qca8k_setup_of_pws_reg(priv); -- if (ret) -- return ret; -- -- ret = qca8k_setup_mac_pwr_sel(priv); -- if (ret) -- return ret; -- -- /* Make sure MAC06 is disabled */ -- ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, -- QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); -- if (ret) { -- dev_err(priv->dev, "failed disabling MAC06 exchange"); -- return ret; -- } -- -- /* Enable CPU Port */ -- ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -- QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); -- if (ret) { -- dev_err(priv->dev, "failed enabling CPU port"); -- return ret; -- } -- -- /* Enable MIB counters */ -- ret = qca8k_mib_init(priv); -- if (ret) -- dev_warn(priv->dev, "mib init failed"); -- -- /* Initial setup of all ports */ -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- /* Disable forwarding by default on all ports */ -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_MEMBER, 0); -- if (ret) -- return ret; -- -- /* Enable QCA header mode on all cpu ports */ -- if (dsa_is_cpu_port(ds, i)) { -- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), -- FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | -- FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); -- if (ret) { -- dev_err(priv->dev, "failed enabling QCA header mode"); -- return ret; -- } -- } -- -- /* Disable MAC by default on all user ports */ -- if (dsa_is_user_port(ds, i)) -- qca8k_port_set_status(priv, i, 0); -- } -- -- /* Forward all unknown frames to CPU port for Linux processing -- * Notice that in multi-cpu config only one port should be set -- * for igmp, unknown, multicast and broadcast packet -- */ -- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); -- if (ret) -- return ret; -- -- /* Setup connection between CPU port & user ports -- * Configure specific switch configuration for ports -- */ -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- /* CPU port gets connected to all user ports of the switch */ -- if (dsa_is_cpu_port(ds, i)) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); -- if (ret) -- return ret; -- } -- -- /* Individual user ports get connected to CPU port only */ -- if (dsa_is_user_port(ds, i)) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_MEMBER, -- BIT(cpu_port)); -- if (ret) -- return ret; -- -- /* Enable ARP Auto-learning by default */ -- ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_LEARN); -- if (ret) -- return ret; -- -- /* For port based vlans to work we need to set the -- * default egress vid -- */ -- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), -- QCA8K_EGREES_VLAN_PORT_MASK(i), -- QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); -- if (ret) -- return ret; -- -- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), -- QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | -- QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); -- if (ret) -- return ret; -- } -- -- /* The port 5 of the qca8337 have some problem in flood condition. The -- * original legacy driver had some specific buffer and priority settings -- * for the different port suggested by the QCA switch team. Add this -- * missing settings to improve switch stability under load condition. -- * This problem is limited to qca8337 and other qca8k switch are not affected. -- */ -- if (priv->switch_id == QCA8K_ID_QCA8337) { -- switch (i) { -- /* The 2 CPU port and port 5 requires some different -- * priority than any other ports. -- */ -- case 0: -- case 5: -- case 6: -- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | -- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); -- break; -- default: -- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | -- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); -- } -- qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask); -- -- mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | -- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_WRED_EN; -- qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), -- QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | -- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_WRED_EN, -- mask); -- } -- } -- -- /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ -- if (priv->switch_id == QCA8K_ID_QCA8327) { -- mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | -- QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); -- qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, -- QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | -- QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, -- mask); -- } -- -- /* Setup our port MTUs to match power on defaults */ -- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); -- if (ret) -- dev_warn(priv->dev, "failed setting MTU settings"); -- -- /* Flush the FDB table */ -- qca8k_fdb_flush(priv); -- -- /* We don't have interrupts for link changes, so we need to poll */ -- ds->pcs_poll = true; -- -- /* Set min a max ageing value supported */ -- ds->ageing_time_min = 7000; -- ds->ageing_time_max = 458745000; -- -- /* Set max number of LAGs supported */ -- ds->num_lag_ids = QCA8K_NUM_LAGS; -- -- return 0; --} -- --static void --qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index, -- u32 reg) --{ -- u32 delay, val = 0; -- int ret; -- -- /* Delay can be declared in 3 different way. -- * Mode to rgmii and internal-delay standard binding defined -- * rgmii-id or rgmii-tx/rx phy mode set. -- * The parse logic set a delay different than 0 only when one -- * of the 3 different way is used. In all other case delay is -- * not enabled. With ID or TX/RXID delay is enabled and set -- * to the default and recommended value. -- */ -- if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) { -- delay = priv->ports_config.rgmii_tx_delay[cpu_port_index]; -- -- val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | -- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; -- } -- -- if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) { -- delay = priv->ports_config.rgmii_rx_delay[cpu_port_index]; -- -- val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | -- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; -- } -- -- /* Set RGMII delay based on the selected values */ -- ret = qca8k_rmw(priv, reg, -- QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | -- QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | -- QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | -- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, -- val); -- if (ret) -- dev_err(priv->dev, "Failed to set internal delay for CPU port%d", -- cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); --} -- --static void --qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, -- const struct phylink_link_state *state) --{ -- struct qca8k_priv *priv = ds->priv; -- int cpu_port_index, ret; -- u32 reg, val; -- -- switch (port) { -- case 0: /* 1st CPU port */ -- if (state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_RGMII_ID && -- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -- state->interface != PHY_INTERFACE_MODE_SGMII) -- return; -- -- reg = QCA8K_REG_PORT0_PAD_CTRL; -- cpu_port_index = QCA8K_CPU_PORT0; -- break; -- case 1: -- case 2: -- case 3: -- case 4: -- case 5: -- /* Internal PHY, nothing to do */ -- return; -- case 6: /* 2nd CPU port / external PHY */ -- if (state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_RGMII_ID && -- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -- state->interface != PHY_INTERFACE_MODE_SGMII && -- state->interface != PHY_INTERFACE_MODE_1000BASEX) -- return; -- -- reg = QCA8K_REG_PORT6_PAD_CTRL; -- cpu_port_index = QCA8K_CPU_PORT6; -- break; -- default: -- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); -- return; -- } -- -- if (port != 6 && phylink_autoneg_inband(mode)) { -- dev_err(ds->dev, "%s: in-band negotiation unsupported\n", -- __func__); -- return; -- } -- -- switch (state->interface) { -- case PHY_INTERFACE_MODE_RGMII: -- case PHY_INTERFACE_MODE_RGMII_ID: -- case PHY_INTERFACE_MODE_RGMII_TXID: -- case PHY_INTERFACE_MODE_RGMII_RXID: -- qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); -- -- /* Configure rgmii delay */ -- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -- -- /* QCA8337 requires to set rgmii rx delay for all ports. -- * This is enabled through PORT5_PAD_CTRL for all ports, -- * rather than individual port registers. -- */ -- if (priv->switch_id == QCA8K_ID_QCA8337) -- qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, -- QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); -- break; -- case PHY_INTERFACE_MODE_SGMII: -- case PHY_INTERFACE_MODE_1000BASEX: -- /* Enable SGMII on the port */ -- qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); -- -- /* Enable/disable SerDes auto-negotiation as necessary */ -- ret = qca8k_read(priv, QCA8K_REG_PWS, &val); -- if (ret) -- return; -- if (phylink_autoneg_inband(mode)) -- val &= ~QCA8K_PWS_SERDES_AEN_DIS; -- else -- val |= QCA8K_PWS_SERDES_AEN_DIS; -- qca8k_write(priv, QCA8K_REG_PWS, val); -- -- /* Configure the SGMII parameters */ -- ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val); -- if (ret) -- return; -- -- val |= QCA8K_SGMII_EN_SD; -- -- if (priv->ports_config.sgmii_enable_pll) -- val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | -- QCA8K_SGMII_EN_TX; -- -- if (dsa_is_cpu_port(ds, port)) { -- /* CPU port, we're talking to the CPU MAC, be a PHY */ -- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -- val |= QCA8K_SGMII_MODE_CTRL_PHY; -- } else if (state->interface == PHY_INTERFACE_MODE_SGMII) { -- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -- val |= QCA8K_SGMII_MODE_CTRL_MAC; -- } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { -- val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -- val |= QCA8K_SGMII_MODE_CTRL_BASEX; -- } -- -- qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); -- -- /* From original code is reported port instability as SGMII also -- * require delay set. Apply advised values here or take them from DT. -- */ -- if (state->interface == PHY_INTERFACE_MODE_SGMII) -- qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -- -- /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and -- * falling edge is set writing in the PORT0 PAD reg -- */ -- if (priv->switch_id == QCA8K_ID_QCA8327 || -- priv->switch_id == QCA8K_ID_QCA8337) -- reg = QCA8K_REG_PORT0_PAD_CTRL; -- -- val = 0; -- -- /* SGMII Clock phase configuration */ -- if (priv->ports_config.sgmii_rx_clk_falling_edge) -- val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; -- -- if (priv->ports_config.sgmii_tx_clk_falling_edge) -- val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; -- -- if (val) -- ret = qca8k_rmw(priv, reg, -- QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | -- QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, -- val); -- -- break; -- default: -- dev_err(ds->dev, "xMII mode %s not supported for port %d\n", -- phy_modes(state->interface), port); -- return; -- } --} -- --static void --qca8k_phylink_validate(struct dsa_switch *ds, int port, -- unsigned long *supported, -- struct phylink_link_state *state) --{ -- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -- -- switch (port) { -- case 0: /* 1st CPU port */ -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_RGMII_ID && -- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -- state->interface != PHY_INTERFACE_MODE_SGMII) -- goto unsupported; -- break; -- case 1: -- case 2: -- case 3: -- case 4: -- case 5: -- /* Internal PHY */ -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_GMII && -- state->interface != PHY_INTERFACE_MODE_INTERNAL) -- goto unsupported; -- break; -- case 6: /* 2nd CPU port / external PHY */ -- if (state->interface != PHY_INTERFACE_MODE_NA && -- state->interface != PHY_INTERFACE_MODE_RGMII && -- state->interface != PHY_INTERFACE_MODE_RGMII_ID && -- state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -- state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -- state->interface != PHY_INTERFACE_MODE_SGMII && -- state->interface != PHY_INTERFACE_MODE_1000BASEX) -- goto unsupported; -- break; -- default: --unsupported: -- linkmode_zero(supported); -- return; -- } -- -- phylink_set_port_modes(mask); -- phylink_set(mask, Autoneg); -- -- phylink_set(mask, 1000baseT_Full); -- phylink_set(mask, 10baseT_Half); -- phylink_set(mask, 10baseT_Full); -- phylink_set(mask, 100baseT_Half); -- phylink_set(mask, 100baseT_Full); -- -- if (state->interface == PHY_INTERFACE_MODE_1000BASEX) -- phylink_set(mask, 1000baseX_Full); -- -- phylink_set(mask, Pause); -- phylink_set(mask, Asym_Pause); -- -- linkmode_and(supported, supported, mask); -- linkmode_and(state->advertising, state->advertising, mask); --} -- --static int --qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, -- struct phylink_link_state *state) --{ -- struct qca8k_priv *priv = ds->priv; -- u32 reg; -- int ret; -- -- ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), ®); -- if (ret < 0) -- return ret; -- -- state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); -- state->an_complete = state->link; -- state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO); -- state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : -- DUPLEX_HALF; -- -- switch (reg & QCA8K_PORT_STATUS_SPEED) { -- case QCA8K_PORT_STATUS_SPEED_10: -- state->speed = SPEED_10; -- break; -- case QCA8K_PORT_STATUS_SPEED_100: -- state->speed = SPEED_100; -- break; -- case QCA8K_PORT_STATUS_SPEED_1000: -- state->speed = SPEED_1000; -- break; -- default: -- state->speed = SPEED_UNKNOWN; -- break; -- } -- -- state->pause = MLO_PAUSE_NONE; -- if (reg & QCA8K_PORT_STATUS_RXFLOW) -- state->pause |= MLO_PAUSE_RX; -- if (reg & QCA8K_PORT_STATUS_TXFLOW) -- state->pause |= MLO_PAUSE_TX; -- -- return 1; --} -- --static void --qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, -- phy_interface_t interface) --{ -- struct qca8k_priv *priv = ds->priv; -- -- qca8k_port_set_status(priv, port, 0); --} -- --static void --qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, -- phy_interface_t interface, struct phy_device *phydev, -- int speed, int duplex, bool tx_pause, bool rx_pause) --{ -- struct qca8k_priv *priv = ds->priv; -- u32 reg; -- -- if (phylink_autoneg_inband(mode)) { -- reg = QCA8K_PORT_STATUS_LINK_AUTO; -- } else { -- switch (speed) { -- case SPEED_10: -- reg = QCA8K_PORT_STATUS_SPEED_10; -- break; -- case SPEED_100: -- reg = QCA8K_PORT_STATUS_SPEED_100; -- break; -- case SPEED_1000: -- reg = QCA8K_PORT_STATUS_SPEED_1000; -- break; -- default: -- reg = QCA8K_PORT_STATUS_LINK_AUTO; -- break; -- } -- -- if (duplex == DUPLEX_FULL) -- reg |= QCA8K_PORT_STATUS_DUPLEX; -- -- if (rx_pause || dsa_is_cpu_port(ds, port)) -- reg |= QCA8K_PORT_STATUS_RXFLOW; -- -- if (tx_pause || dsa_is_cpu_port(ds, port)) -- reg |= QCA8K_PORT_STATUS_TXFLOW; -- } -- -- reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; -- -- qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); --} -- --static void --qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) --{ -- struct qca8k_priv *priv = ds->priv; -- int i; -- -- if (stringset != ETH_SS_STATS) -- return; -- -- for (i = 0; i < priv->info->mib_count; i++) -- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, -- ETH_GSTRING_LEN); --} -- --static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) --{ -- struct qca8k_mib_eth_data *mib_eth_data; -- struct qca8k_priv *priv = ds->priv; -- const struct qca8k_mib_desc *mib; -- struct mib_ethhdr *mib_ethhdr; -- int i, mib_len, offset = 0; -- u64 *data; -- u8 port; -- -- mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); -- mib_eth_data = &priv->mib_eth_data; -- -- /* The switch autocast every port. Ignore other packet and -- * parse only the requested one. -- */ -- port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr)); -- if (port != mib_eth_data->req_port) -- goto exit; -- -- data = mib_eth_data->data; -- -- for (i = 0; i < priv->info->mib_count; i++) { -- mib = &ar8327_mib[i]; -- -- /* First 3 mib are present in the skb head */ -- if (i < 3) { -- data[i] = mib_ethhdr->data[i]; -- continue; -- } -- -- mib_len = sizeof(uint32_t); -- -- /* Some mib are 64 bit wide */ -- if (mib->size == 2) -- mib_len = sizeof(uint64_t); -- -- /* Copy the mib value from packet to the */ -- memcpy(data + i, skb->data + offset, mib_len); -- -- /* Set the offset for the next mib */ -- offset += mib_len; -- } -- --exit: -- /* Complete on receiving all the mib packet */ -- if (refcount_dec_and_test(&mib_eth_data->port_parsed)) -- complete(&mib_eth_data->rw_done); --} -- --static int --qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data) --{ -- struct dsa_port *dp = dsa_to_port(ds, port); -- struct qca8k_mib_eth_data *mib_eth_data; -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- mib_eth_data = &priv->mib_eth_data; -- -- mutex_lock(&mib_eth_data->mutex); -- -- reinit_completion(&mib_eth_data->rw_done); -- -- mib_eth_data->req_port = dp->index; -- mib_eth_data->data = data; -- refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS); -- -- mutex_lock(&priv->reg_mutex); -- -- /* Send mib autocast request */ -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) | -- QCA8K_MIB_BUSY); -- -- mutex_unlock(&priv->reg_mutex); -- -- if (ret) -- goto exit; -- -- ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT); -- --exit: -- mutex_unlock(&mib_eth_data->mutex); -- -- return ret; --} -- --static void --qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, -- uint64_t *data) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- const struct qca8k_mib_desc *mib; -- u32 reg, i, val; -- u32 hi = 0; -- int ret; -- -- if (priv->mgmt_master && priv->info->ops->autocast_mib && -- priv->info->ops->autocast_mib(ds, port, data) > 0) -- return; -- -- for (i = 0; i < priv->info->mib_count; i++) { -- mib = &ar8327_mib[i]; -- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; -- -- ret = qca8k_read(priv, reg, &val); -- if (ret < 0) -- continue; -- -- if (mib->size == 2) { -- ret = qca8k_read(priv, reg + 4, &hi); -- if (ret < 0) -- continue; -- } -- -- data[i] = val; -- if (mib->size == 2) -- data[i] |= (u64)hi << 32; -- } --} -- --static int --qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) --{ -- struct qca8k_priv *priv = ds->priv; -- -- if (sset != ETH_SS_STATS) -- return 0; -- -- return priv->info->mib_count; --} -- --static int --qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); -- u32 reg; -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); -- if (ret < 0) -- goto exit; -- -- if (eee->eee_enabled) -- reg |= lpi_en; -- else -- reg &= ~lpi_en; -- ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static int --qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) --{ -- /* Nothing to do on the port's MAC */ -- return 0; --} -- --static void --qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u32 stp_state; -- -- switch (state) { -- case BR_STATE_DISABLED: -- stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; -- break; -- case BR_STATE_BLOCKING: -- stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; -- break; -- case BR_STATE_LISTENING: -- stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; -- break; -- case BR_STATE_LEARNING: -- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; -- break; -- case BR_STATE_FORWARDING: -- default: -- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; -- break; -- } -- -- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); --} -- --static int --qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int port_mask, cpu_port; -- int i, ret; -- -- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -- port_mask = BIT(cpu_port); -- -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- if (dsa_is_cpu_port(ds, i)) -- continue; -- if (dsa_to_port(ds, i)->bridge_dev != br) -- continue; -- /* Add this port to the portvlan mask of the other ports -- * in the bridge -- */ -- ret = regmap_set_bits(priv->regmap, -- QCA8K_PORT_LOOKUP_CTRL(i), -- BIT(port)); -- if (ret) -- return ret; -- if (i != port) -- port_mask |= BIT(i); -- } -- -- /* Add all other ports to this ports portvlan mask */ -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_MEMBER, port_mask); -- -- return ret; --} -- --static void --qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int cpu_port, i; -- -- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -- -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- if (dsa_is_cpu_port(ds, i)) -- continue; -- if (dsa_to_port(ds, i)->bridge_dev != br) -- continue; -- /* Remove this port to the portvlan mask of the other ports -- * in the bridge -- */ -- regmap_clear_bits(priv->regmap, -- QCA8K_PORT_LOOKUP_CTRL(i), -- BIT(port)); -- } -- -- /* Set the cpu port to be the only one in the portvlan mask of -- * this port -- */ -- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); --} -- --static void --qca8k_port_fast_age(struct dsa_switch *ds, int port) --{ -- struct qca8k_priv *priv = ds->priv; -- -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); -- mutex_unlock(&priv->reg_mutex); --} -- --static int --qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) --{ -- struct qca8k_priv *priv = ds->priv; -- unsigned int secs = msecs / 1000; -- u32 val; -- -- /* AGE_TIME reg is set in 7s step */ -- val = secs / 7; -- -- /* Handle case with 0 as val to NOT disable -- * learning -- */ -- if (!val) -- val = 1; -- -- return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, -- QCA8K_ATU_AGE_TIME(val)); --} -- --static int --qca8k_port_enable(struct dsa_switch *ds, int port, -- struct phy_device *phy) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- -- qca8k_port_set_status(priv, port, 1); -- priv->port_enabled_map |= BIT(port); -- -- if (dsa_is_user_port(ds, port)) -- phy_support_asym_pause(phy); -- -- return 0; --} -- --static void --qca8k_port_disable(struct dsa_switch *ds, int port) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- -- qca8k_port_set_status(priv, port, 0); -- priv->port_enabled_map &= ~BIT(port); --} -- --static int --qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- /* We have only have a general MTU setting. -- * DSA always set the CPU port's MTU to the largest MTU of the slave -- * ports. -- * Setting MTU just for the CPU port is sufficient to correctly set a -- * value for every port. -- */ -- if (!dsa_is_cpu_port(ds, port)) -- return 0; -- -- /* To change the MAX_FRAME_SIZE the cpu ports must be off or -- * the switch panics. -- * Turn off both cpu ports before applying the new value to prevent -- * this. -- */ -- if (priv->port_enabled_map & BIT(0)) -- qca8k_port_set_status(priv, 0, 0); -- -- if (priv->port_enabled_map & BIT(6)) -- qca8k_port_set_status(priv, 6, 0); -- -- /* Include L2 header / FCS length */ -- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); -- -- if (priv->port_enabled_map & BIT(0)) -- qca8k_port_set_status(priv, 0, 1); -- -- if (priv->port_enabled_map & BIT(6)) -- qca8k_port_set_status(priv, 6, 1); -- -- return ret; --} -- --static int --qca8k_port_max_mtu(struct dsa_switch *ds, int port) --{ -- return QCA8K_MAX_MTU; --} -- --static int --qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, -- u16 port_mask, u16 vid) --{ -- /* Set the vid to the port vlan id if no vid is set */ -- if (!vid) -- vid = QCA8K_PORT_VID_DEF; -- -- return qca8k_fdb_add(priv, addr, port_mask, vid, -- QCA8K_ATU_STATUS_STATIC); --} -- --static int --qca8k_port_fdb_add(struct dsa_switch *ds, int port, -- const unsigned char *addr, u16 vid) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u16 port_mask = BIT(port); -- -- return qca8k_port_fdb_insert(priv, addr, port_mask, vid); --} -- --static int --qca8k_port_fdb_del(struct dsa_switch *ds, int port, -- const unsigned char *addr, u16 vid) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u16 port_mask = BIT(port); -- -- if (!vid) -- vid = QCA8K_PORT_VID_DEF; -- -- return qca8k_fdb_del(priv, addr, port_mask, vid); --} -- --static int --qca8k_port_fdb_dump(struct dsa_switch *ds, int port, -- dsa_fdb_dump_cb_t *cb, void *data) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- struct qca8k_fdb _fdb = { 0 }; -- int cnt = QCA8K_NUM_FDB_RECORDS; -- bool is_static; -- int ret = 0; -- -- mutex_lock(&priv->reg_mutex); -- while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { -- if (!_fdb.aging) -- break; -- is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); -- ret = cb(_fdb.mac, _fdb.vid, is_static, data); -- if (ret) -- break; -- } -- mutex_unlock(&priv->reg_mutex); -- -- return 0; --} -- --static int --qca8k_port_mdb_add(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_mdb *mdb) --{ -- struct qca8k_priv *priv = ds->priv; -- const u8 *addr = mdb->addr; -- u16 vid = mdb->vid; -- -- return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); --} -- --static int --qca8k_port_mdb_del(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_mdb *mdb) --{ -- struct qca8k_priv *priv = ds->priv; -- const u8 *addr = mdb->addr; -- u16 vid = mdb->vid; -- -- return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); --} -- --static int --qca8k_port_mirror_add(struct dsa_switch *ds, int port, -- struct dsa_mall_mirror_tc_entry *mirror, -- bool ingress) --{ -- struct qca8k_priv *priv = ds->priv; -- int monitor_port, ret; -- u32 reg, val; -- -- /* Check for existent entry */ -- if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) -- return -EEXIST; -- -- ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); -- if (ret) -- return ret; -- -- /* QCA83xx can have only one port set to mirror mode. -- * Check that the correct port is requested and return error otherwise. -- * When no mirror port is set, the values is set to 0xF -- */ -- monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -- if (monitor_port != 0xF && monitor_port != mirror->to_local_port) -- return -EEXIST; -- -- /* Set the monitor port */ -- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, -- mirror->to_local_port); -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -- if (ret) -- return ret; -- -- if (ingress) { -- reg = QCA8K_PORT_LOOKUP_CTRL(port); -- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -- } else { -- reg = QCA8K_REG_PORT_HOL_CTRL1(port); -- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -- } -- -- ret = regmap_update_bits(priv->regmap, reg, val, val); -- if (ret) -- return ret; -- -- /* Track mirror port for tx and rx to decide when the -- * mirror port has to be disabled. -- */ -- if (ingress) -- priv->mirror_rx |= BIT(port); -- else -- priv->mirror_tx |= BIT(port); -- -- return 0; --} -- --static void --qca8k_port_mirror_del(struct dsa_switch *ds, int port, -- struct dsa_mall_mirror_tc_entry *mirror) --{ -- struct qca8k_priv *priv = ds->priv; -- u32 reg, val; -- int ret; -- -- if (mirror->ingress) { -- reg = QCA8K_PORT_LOOKUP_CTRL(port); -- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -- } else { -- reg = QCA8K_REG_PORT_HOL_CTRL1(port); -- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -- } -- -- ret = regmap_clear_bits(priv->regmap, reg, val); -- if (ret) -- goto err; -- -- if (mirror->ingress) -- priv->mirror_rx &= ~BIT(port); -- else -- priv->mirror_tx &= ~BIT(port); -- -- /* No port set to send packet to mirror port. Disable mirror port */ -- if (!priv->mirror_rx && !priv->mirror_tx) { -- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -- if (ret) -- goto err; -- } --err: -- dev_err(priv->dev, "Failed to del mirror port from %d", port); --} -- --static int --qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, -- struct netlink_ext_ack *extack) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- if (vlan_filtering) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -- QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); -- } else { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -- QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); -- } -- -- return ret; --} -- --static int --qca8k_port_vlan_add(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_vlan *vlan, -- struct netlink_ext_ack *extack) --{ -- bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; -- bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); -- if (ret) { -- dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); -- return ret; -- } -- -- if (pvid) { -- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), -- QCA8K_EGREES_VLAN_PORT_MASK(port), -- QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); -- if (ret) -- return ret; -- -- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), -- QCA8K_PORT_VLAN_CVID(vlan->vid) | -- QCA8K_PORT_VLAN_SVID(vlan->vid)); -- } -- -- return ret; --} -- --static int --qca8k_port_vlan_del(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_vlan *vlan) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- ret = qca8k_vlan_del(priv, port, vlan->vid); -- if (ret) -- dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); -- -- return ret; --} -- --static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) --{ -- struct qca8k_priv *priv = ds->priv; -- -- /* Communicate to the phy internal driver the switch revision. -- * Based on the switch revision different values needs to be -- * set to the dbg and mmd reg on the phy. -- * The first 2 bit are used to communicate the switch revision -- * to the phy driver. -- */ -- if (port > 0 && port < 6) -- return priv->switch_revision; -- -- return 0; --} -- --static enum dsa_tag_protocol --qca8k_get_tag_protocol(struct dsa_switch *ds, int port, -- enum dsa_tag_protocol mp) --{ -- return DSA_TAG_PROTO_QCA; --} -- --static bool --qca8k_lag_can_offload(struct dsa_switch *ds, -- struct net_device *lag, -- struct netdev_lag_upper_info *info) --{ -- struct dsa_port *dp; -- int id, members = 0; -- -- id = dsa_lag_id(ds->dst, lag); -- if (id < 0 || id >= ds->num_lag_ids) -- return false; -- -- dsa_lag_foreach_port(dp, ds->dst, lag) -- /* Includes the port joining the LAG */ -- members++; -- -- if (members > QCA8K_NUM_PORTS_FOR_LAG) -- return false; -- -- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) -- return false; -- -- if (info->hash_type != NETDEV_LAG_HASH_L2 && -- info->hash_type != NETDEV_LAG_HASH_L23) -- return false; -- -- return true; --} -- --static int --qca8k_lag_setup_hash(struct dsa_switch *ds, -- struct net_device *lag, -- struct netdev_lag_upper_info *info) --{ -- struct qca8k_priv *priv = ds->priv; -- bool unique_lag = true; -- u32 hash = 0; -- int i, id; -- -- id = dsa_lag_id(ds->dst, lag); -- -- switch (info->hash_type) { -- case NETDEV_LAG_HASH_L23: -- hash |= QCA8K_TRUNK_HASH_SIP_EN; -- hash |= QCA8K_TRUNK_HASH_DIP_EN; -- fallthrough; -- case NETDEV_LAG_HASH_L2: -- hash |= QCA8K_TRUNK_HASH_SA_EN; -- hash |= QCA8K_TRUNK_HASH_DA_EN; -- break; -- default: /* We should NEVER reach this */ -- return -EOPNOTSUPP; -- } -- -- /* Check if we are the unique configured LAG */ -- dsa_lags_foreach_id(i, ds->dst) -- if (i != id && dsa_lag_dev(ds->dst, i)) { -- unique_lag = false; -- break; -- } -- -- /* Hash Mode is global. Make sure the same Hash Mode -- * is set to all the 4 possible lag. -- * If we are the unique LAG we can set whatever hash -- * mode we want. -- * To change hash mode it's needed to remove all LAG -- * and change the mode with the latest. -- */ -- if (unique_lag) { -- priv->lag_hash_mode = hash; -- } else if (priv->lag_hash_mode != hash) { -- netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); -- return -EOPNOTSUPP; -- } -- -- return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, -- QCA8K_TRUNK_HASH_MASK, hash); --} -- --static int --qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, -- struct net_device *lag, bool delete) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret, id, i; -- u32 val; -- -- id = dsa_lag_id(ds->dst, lag); -- -- /* Read current port member */ -- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); -- if (ret) -- return ret; -- -- /* Shift val to the correct trunk */ -- val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); -- val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; -- if (delete) -- val &= ~BIT(port); -- else -- val |= BIT(port); -- -- /* Update port member. With empty portmap disable trunk */ -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, -- QCA8K_REG_GOL_TRUNK_MEMBER(id) | -- QCA8K_REG_GOL_TRUNK_EN(id), -- !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | -- val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); -- -- /* Search empty member if adding or port on deleting */ -- for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { -- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); -- if (ret) -- return ret; -- -- val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); -- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; -- -- if (delete) { -- /* If port flagged to be disabled assume this member is -- * empty -- */ -- if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -- continue; -- -- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; -- if (val != port) -- continue; -- } else { -- /* If port flagged to be enabled assume this member is -- * already set -- */ -- if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -- continue; -- } -- -- /* We have found the member to add/remove */ -- break; -- } -- -- /* Set port in the correct port mask or disable port if in delete mode */ -- return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), -- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | -- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), -- !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | -- port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); --} -- --static int --qca8k_port_lag_join(struct dsa_switch *ds, int port, -- struct net_device *lag, -- struct netdev_lag_upper_info *info) --{ -- int ret; -- -- if (!qca8k_lag_can_offload(ds, lag, info)) -- return -EOPNOTSUPP; -- -- ret = qca8k_lag_setup_hash(ds, lag, info); -- if (ret) -- return ret; -- -- return qca8k_lag_refresh_portmap(ds, port, lag, false); --} -- --static int --qca8k_port_lag_leave(struct dsa_switch *ds, int port, -- struct net_device *lag) --{ -- return qca8k_lag_refresh_portmap(ds, port, lag, true); --} -- --static void --qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, -- bool operational) --{ -- struct dsa_port *dp = master->dsa_ptr; -- struct qca8k_priv *priv = ds->priv; -- -- /* Ethernet MIB/MDIO is only supported for CPU port 0 */ -- if (dp->index != 0) -- return; -- -- mutex_lock(&priv->mgmt_eth_data.mutex); -- mutex_lock(&priv->mib_eth_data.mutex); -- -- priv->mgmt_master = operational ? (struct net_device *)master : NULL; -- -- mutex_unlock(&priv->mib_eth_data.mutex); -- mutex_unlock(&priv->mgmt_eth_data.mutex); --} -- --static int qca8k_connect_tag_protocol(struct dsa_switch *ds, -- enum dsa_tag_protocol proto) --{ -- struct qca_tagger_data *tagger_data; -- -- switch (proto) { -- case DSA_TAG_PROTO_QCA: -- tagger_data = ds->tagger_data; -- -- tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; -- tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler; -- -- break; -- default: -- return -EOPNOTSUPP; -- } -- -- return 0; --} -- --static const struct dsa_switch_ops qca8k_switch_ops = { -- .get_tag_protocol = qca8k_get_tag_protocol, -- .setup = qca8k_setup, -- .get_strings = qca8k_get_strings, -- .get_ethtool_stats = qca8k_get_ethtool_stats, -- .get_sset_count = qca8k_get_sset_count, -- .set_ageing_time = qca8k_set_ageing_time, -- .get_mac_eee = qca8k_get_mac_eee, -- .set_mac_eee = qca8k_set_mac_eee, -- .port_enable = qca8k_port_enable, -- .port_disable = qca8k_port_disable, -- .port_change_mtu = qca8k_port_change_mtu, -- .port_max_mtu = qca8k_port_max_mtu, -- .port_stp_state_set = qca8k_port_stp_state_set, -- .port_bridge_join = qca8k_port_bridge_join, -- .port_bridge_leave = qca8k_port_bridge_leave, -- .port_fast_age = qca8k_port_fast_age, -- .port_fdb_add = qca8k_port_fdb_add, -- .port_fdb_del = qca8k_port_fdb_del, -- .port_fdb_dump = qca8k_port_fdb_dump, -- .port_mdb_add = qca8k_port_mdb_add, -- .port_mdb_del = qca8k_port_mdb_del, -- .port_mirror_add = qca8k_port_mirror_add, -- .port_mirror_del = qca8k_port_mirror_del, -- .port_vlan_filtering = qca8k_port_vlan_filtering, -- .port_vlan_add = qca8k_port_vlan_add, -- .port_vlan_del = qca8k_port_vlan_del, -- .phylink_validate = qca8k_phylink_validate, -- .phylink_mac_link_state = qca8k_phylink_mac_link_state, -- .phylink_mac_config = qca8k_phylink_mac_config, -- .phylink_mac_link_down = qca8k_phylink_mac_link_down, -- .phylink_mac_link_up = qca8k_phylink_mac_link_up, -- .get_phy_flags = qca8k_get_phy_flags, -- .port_lag_join = qca8k_port_lag_join, -- .port_lag_leave = qca8k_port_lag_leave, -- .master_state_change = qca8k_master_change, -- .connect_tag_protocol = qca8k_connect_tag_protocol, --}; -- --static int qca8k_read_switch_id(struct qca8k_priv *priv) --{ -- u32 val; -- u8 id; -- int ret; -- -- if (!priv->info) -- return -ENODEV; -- -- ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); -- if (ret < 0) -- return -ENODEV; -- -- id = QCA8K_MASK_CTRL_DEVICE_ID(val); -- if (id != priv->info->id) { -- dev_err(priv->dev, -- "Switch id detected %x but expected %x", -- id, priv->info->id); -- return -ENODEV; -- } -- -- priv->switch_id = id; -- -- /* Save revision to communicate to the internal PHY driver */ -- priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); -- -- return 0; --} -- --static int --qca8k_sw_probe(struct mdio_device *mdiodev) --{ -- struct qca8k_priv *priv; -- int ret; -- -- /* allocate the private data struct so that we can probe the switches -- * ID register -- */ -- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- -- priv->info = of_device_get_match_data(priv->dev); -- priv->bus = mdiodev->bus; -- priv->dev = &mdiodev->dev; -- -- priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", -- GPIOD_ASIS); -- if (IS_ERR(priv->reset_gpio)) -- return PTR_ERR(priv->reset_gpio); -- -- if (priv->reset_gpio) { -- gpiod_set_value_cansleep(priv->reset_gpio, 1); -- /* The active low duration must be greater than 10 ms -- * and checkpatch.pl wants 20 ms. -- */ -- msleep(20); -- gpiod_set_value_cansleep(priv->reset_gpio, 0); -- } -- -- /* Start by setting up the register mapping */ -- priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv, -- &qca8k_regmap_config); -- if (IS_ERR(priv->regmap)) { -- dev_err(priv->dev, "regmap initialization failed"); -- return PTR_ERR(priv->regmap); -- } -- -- priv->mdio_cache.page = 0xffff; -- priv->mdio_cache.lo = 0xffff; -- priv->mdio_cache.hi = 0xffff; -- -- /* Check the detected switch id */ -- ret = qca8k_read_switch_id(priv); -- if (ret) -- return ret; -- -- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); -- if (!priv->ds) -- return -ENOMEM; -- -- mutex_init(&priv->mgmt_eth_data.mutex); -- init_completion(&priv->mgmt_eth_data.rw_done); -- -- mutex_init(&priv->mib_eth_data.mutex); -- init_completion(&priv->mib_eth_data.rw_done); -- -- priv->ds->dev = &mdiodev->dev; -- priv->ds->num_ports = QCA8K_NUM_PORTS; -- priv->ds->priv = priv; -- priv->ds->ops = &qca8k_switch_ops; -- mutex_init(&priv->reg_mutex); -- dev_set_drvdata(&mdiodev->dev, priv); -- -- return dsa_register_switch(priv->ds); --} -- --static void --qca8k_sw_remove(struct mdio_device *mdiodev) --{ -- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); -- int i; -- -- if (!priv) -- return; -- -- for (i = 0; i < QCA8K_NUM_PORTS; i++) -- qca8k_port_set_status(priv, i, 0); -- -- dsa_unregister_switch(priv->ds); -- -- dev_set_drvdata(&mdiodev->dev, NULL); --} -- --static void qca8k_sw_shutdown(struct mdio_device *mdiodev) --{ -- struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); -- -- if (!priv) -- return; -- -- dsa_switch_shutdown(priv->ds); -- -- dev_set_drvdata(&mdiodev->dev, NULL); --} -- --#ifdef CONFIG_PM_SLEEP --static void --qca8k_set_pm(struct qca8k_priv *priv, int enable) --{ -- int port; -- -- for (port = 0; port < QCA8K_NUM_PORTS; port++) { -- /* Do not enable on resume if the port was -- * disabled before. -- */ -- if (!(priv->port_enabled_map & BIT(port))) -- continue; -- -- qca8k_port_set_status(priv, port, enable); -- } --} -- --static int qca8k_suspend(struct device *dev) --{ -- struct qca8k_priv *priv = dev_get_drvdata(dev); -- -- qca8k_set_pm(priv, 0); -- -- return dsa_switch_suspend(priv->ds); --} -- --static int qca8k_resume(struct device *dev) --{ -- struct qca8k_priv *priv = dev_get_drvdata(dev); -- -- qca8k_set_pm(priv, 1); -- -- return dsa_switch_resume(priv->ds); --} --#endif /* CONFIG_PM_SLEEP */ -- --static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, -- qca8k_suspend, qca8k_resume); -- --static const struct qca8k_info_ops qca8xxx_ops = { -- .autocast_mib = qca8k_get_ethtool_stats_eth, --}; -- --static const struct qca8k_match_data qca8327 = { -- .id = QCA8K_ID_QCA8327, -- .reduced_package = true, -- .mib_count = QCA8K_QCA832X_MIB_COUNT, -- .ops = &qca8xxx_ops, --}; -- --static const struct qca8k_match_data qca8328 = { -- .id = QCA8K_ID_QCA8327, -- .mib_count = QCA8K_QCA832X_MIB_COUNT, -- .ops = &qca8xxx_ops, --}; -- --static const struct qca8k_match_data qca833x = { -- .id = QCA8K_ID_QCA8337, -- .mib_count = QCA8K_QCA833X_MIB_COUNT, -- .ops = &qca8xxx_ops, --}; -- --static const struct of_device_id qca8k_of_match[] = { -- { .compatible = "qca,qca8327", .data = &qca8327 }, -- { .compatible = "qca,qca8328", .data = &qca8328 }, -- { .compatible = "qca,qca8334", .data = &qca833x }, -- { .compatible = "qca,qca8337", .data = &qca833x }, -- { /* sentinel */ }, --}; -- --static struct mdio_driver qca8kmdio_driver = { -- .probe = qca8k_sw_probe, -- .remove = qca8k_sw_remove, -- .shutdown = qca8k_sw_shutdown, -- .mdiodrv.driver = { -- .name = "qca8k", -- .of_match_table = qca8k_of_match, -- .pm = &qca8k_pm_ops, -- }, --}; -- --mdio_module_driver(qca8kmdio_driver); -- --MODULE_AUTHOR("Mathieu Olivari, John Crispin "); --MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family"); --MODULE_LICENSE("GPL v2"); --MODULE_ALIAS("platform:qca8k"); ---- /dev/null -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -0,0 +1,3186 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2009 Felix Fietkau -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2016 John Crispin -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "qca8k.h" -+ -+static void -+qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) -+{ -+ regaddr >>= 1; -+ *r1 = regaddr & 0x1e; -+ -+ regaddr >>= 5; -+ *r2 = regaddr & 0x7; -+ -+ regaddr >>= 3; -+ *page = regaddr & 0x3ff; -+} -+ -+static int -+qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo) -+{ -+ u16 *cached_lo = &priv->mdio_cache.lo; -+ struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ if (lo == *cached_lo) -+ return 0; -+ -+ ret = bus->write(bus, phy_id, regnum, lo); -+ if (ret < 0) -+ dev_err_ratelimited(&bus->dev, -+ "failed to write qca8k 32bit lo register\n"); -+ -+ *cached_lo = lo; -+ return 0; -+} -+ -+static int -+qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi) -+{ -+ u16 *cached_hi = &priv->mdio_cache.hi; -+ struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ if (hi == *cached_hi) -+ return 0; -+ -+ ret = bus->write(bus, phy_id, regnum, hi); -+ if (ret < 0) -+ dev_err_ratelimited(&bus->dev, -+ "failed to write qca8k 32bit hi register\n"); -+ -+ *cached_hi = hi; -+ return 0; -+} -+ -+static int -+qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) -+{ -+ int ret; -+ -+ ret = bus->read(bus, phy_id, regnum); -+ if (ret >= 0) { -+ *val = ret; -+ ret = bus->read(bus, phy_id, regnum + 1); -+ *val |= ret << 16; -+ } -+ -+ if (ret < 0) { -+ dev_err_ratelimited(&bus->dev, -+ "failed to read qca8k 32bit register\n"); -+ *val = 0; -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void -+qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val) -+{ -+ u16 lo, hi; -+ int ret; -+ -+ lo = val & 0xffff; -+ hi = (u16)(val >> 16); -+ -+ ret = qca8k_set_lo(priv, phy_id, regnum, lo); -+ if (ret >= 0) -+ ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi); -+} -+ -+static int -+qca8k_set_page(struct qca8k_priv *priv, u16 page) -+{ -+ u16 *cached_page = &priv->mdio_cache.page; -+ struct mii_bus *bus = priv->bus; -+ int ret; -+ -+ if (page == *cached_page) -+ return 0; -+ -+ ret = bus->write(bus, 0x18, 0, page); -+ if (ret < 0) { -+ dev_err_ratelimited(&bus->dev, -+ "failed to set qca8k page\n"); -+ return ret; -+ } -+ -+ *cached_page = page; -+ usleep_range(1000, 2000); -+ return 0; -+} -+ -+static int -+qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) -+{ -+ return regmap_read(priv->regmap, reg, val); -+} -+ -+static int -+qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) -+{ -+ return regmap_write(priv->regmap, reg, val); -+} -+ -+static int -+qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) -+{ -+ return regmap_update_bits(priv->regmap, reg, mask, write_val); -+} -+ -+static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) -+{ -+ struct qca8k_mgmt_eth_data *mgmt_eth_data; -+ struct qca8k_priv *priv = ds->priv; -+ struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ u8 len, cmd; -+ -+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); -+ mgmt_eth_data = &priv->mgmt_eth_data; -+ -+ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); -+ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); -+ -+ /* Make sure the seq match the requested packet */ -+ if (mgmt_ethhdr->seq == mgmt_eth_data->seq) -+ mgmt_eth_data->ack = true; -+ -+ if (cmd == MDIO_READ) { -+ mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; -+ -+ /* Get the rest of the 12 byte of data. -+ * The read/write function will extract the requested data. -+ */ -+ if (len > QCA_HDR_MGMT_DATA1_LEN) -+ memcpy(mgmt_eth_data->data + 1, skb->data, -+ QCA_HDR_MGMT_DATA2_LEN); -+ } -+ -+ complete(&mgmt_eth_data->rw_done); -+} -+ -+static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val, -+ int priority, unsigned int len) -+{ -+ struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ unsigned int real_len; -+ struct sk_buff *skb; -+ u32 *data2; -+ u16 hdr; -+ -+ skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); -+ if (!skb) -+ return NULL; -+ -+ /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte -+ * Actually for some reason the steps are: -+ * 0: nothing -+ * 1-4: first 4 byte -+ * 5-6: first 12 byte -+ * 7-15: all 16 byte -+ */ -+ if (len == 16) -+ real_len = 15; -+ else -+ real_len = len; -+ -+ skb_reset_mac_header(skb); -+ skb_set_network_header(skb, skb->len); -+ -+ mgmt_ethhdr = skb_push(skb, QCA_HDR_MGMT_HEADER_LEN + QCA_HDR_LEN); -+ -+ hdr = FIELD_PREP(QCA_HDR_XMIT_VERSION, QCA_HDR_VERSION); -+ hdr |= FIELD_PREP(QCA_HDR_XMIT_PRIORITY, priority); -+ hdr |= QCA_HDR_XMIT_FROM_CPU; -+ hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); -+ hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); -+ -+ mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); -+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); -+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); -+ mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, -+ QCA_HDR_MGMT_CHECK_CODE_VAL); -+ -+ if (cmd == MDIO_WRITE) -+ mgmt_ethhdr->mdio_data = *val; -+ -+ mgmt_ethhdr->hdr = htons(hdr); -+ -+ data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); -+ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) -+ memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); -+ -+ return skb; -+} -+ -+static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) -+{ -+ struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ -+ mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; -+ mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); -+} -+ -+static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; -+ struct sk_buff *skb; -+ bool ack; -+ int ret; -+ -+ skb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL, -+ QCA8K_ETHERNET_MDIO_PRIORITY, len); -+ if (!skb) -+ return -ENOMEM; -+ -+ mutex_lock(&mgmt_eth_data->mutex); -+ -+ /* Check mgmt_master if is operational */ -+ if (!priv->mgmt_master) { -+ kfree_skb(skb); -+ mutex_unlock(&mgmt_eth_data->mutex); -+ return -EINVAL; -+ } -+ -+ skb->dev = priv->mgmt_master; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the mdio pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); -+ -+ *val = mgmt_eth_data->data[0]; -+ if (len > QCA_HDR_MGMT_DATA1_LEN) -+ memcpy(val + 1, mgmt_eth_data->data + 1, len - QCA_HDR_MGMT_DATA1_LEN); -+ -+ ack = mgmt_eth_data->ack; -+ -+ mutex_unlock(&mgmt_eth_data->mutex); -+ -+ if (ret <= 0) -+ return -ETIMEDOUT; -+ -+ if (!ack) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ struct qca8k_mgmt_eth_data *mgmt_eth_data = &priv->mgmt_eth_data; -+ struct sk_buff *skb; -+ bool ack; -+ int ret; -+ -+ skb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val, -+ QCA8K_ETHERNET_MDIO_PRIORITY, len); -+ if (!skb) -+ return -ENOMEM; -+ -+ mutex_lock(&mgmt_eth_data->mutex); -+ -+ /* Check mgmt_master if is operational */ -+ if (!priv->mgmt_master) { -+ kfree_skb(skb); -+ mutex_unlock(&mgmt_eth_data->mutex); -+ return -EINVAL; -+ } -+ -+ skb->dev = priv->mgmt_master; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the mdio pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ msecs_to_jiffies(QCA8K_ETHERNET_TIMEOUT)); -+ -+ ack = mgmt_eth_data->ack; -+ -+ mutex_unlock(&mgmt_eth_data->mutex); -+ -+ if (ret <= 0) -+ return -ETIMEDOUT; -+ -+ if (!ack) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int -+qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) -+{ -+ u32 val = 0; -+ int ret; -+ -+ ret = qca8k_read_eth(priv, reg, &val, sizeof(val)); -+ if (ret) -+ return ret; -+ -+ val &= ~mask; -+ val |= write_val; -+ -+ return qca8k_write_eth(priv, reg, &val, sizeof(val)); -+} -+ -+static int -+qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ int i, count = len / sizeof(u32), ret; -+ -+ if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) -+ return 0; -+ -+ for (i = 0; i < count; i++) { -+ ret = regmap_read(priv->regmap, reg + (i * 4), val + i); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ int i, count = len / sizeof(u32), ret; -+ u32 tmp; -+ -+ if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) -+ return 0; -+ -+ for (i = 0; i < count; i++) { -+ tmp = val[i]; -+ -+ ret = regmap_write(priv->regmap, reg + (i * 4), tmp); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -+ struct mii_bus *bus = priv->bus; -+ u16 r1, r2, page; -+ int ret; -+ -+ if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) -+ return 0; -+ -+ qca8k_split_addr(reg, &r1, &r2, &page); -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = qca8k_set_page(priv, page); -+ if (ret < 0) -+ goto exit; -+ -+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, val); -+ -+exit: -+ mutex_unlock(&bus->mdio_lock); -+ return ret; -+} -+ -+static int -+qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -+ struct mii_bus *bus = priv->bus; -+ u16 r1, r2, page; -+ int ret; -+ -+ if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) -+ return 0; -+ -+ qca8k_split_addr(reg, &r1, &r2, &page); -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = qca8k_set_page(priv, page); -+ if (ret < 0) -+ goto exit; -+ -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ -+exit: -+ mutex_unlock(&bus->mdio_lock); -+ return ret; -+} -+ -+static int -+qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -+ struct mii_bus *bus = priv->bus; -+ u16 r1, r2, page; -+ u32 val; -+ int ret; -+ -+ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) -+ return 0; -+ -+ qca8k_split_addr(reg, &r1, &r2, &page); -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = qca8k_set_page(priv, page); -+ if (ret < 0) -+ goto exit; -+ -+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); -+ if (ret < 0) -+ goto exit; -+ -+ val &= ~mask; -+ val |= write_val; -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ -+exit: -+ mutex_unlock(&bus->mdio_lock); -+ -+ return ret; -+} -+ -+static const struct regmap_range qca8k_readable_ranges[] = { -+ regmap_reg_range(0x0000, 0x00e4), /* Global control */ -+ regmap_reg_range(0x0100, 0x0168), /* EEE control */ -+ regmap_reg_range(0x0200, 0x0270), /* Parser control */ -+ regmap_reg_range(0x0400, 0x0454), /* ACL */ -+ regmap_reg_range(0x0600, 0x0718), /* Lookup */ -+ regmap_reg_range(0x0800, 0x0b70), /* QM */ -+ regmap_reg_range(0x0c00, 0x0c80), /* PKT */ -+ regmap_reg_range(0x0e00, 0x0e98), /* L3 */ -+ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ -+ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ -+ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ -+ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ -+ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ -+ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ -+ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ -+ -+}; -+ -+static const struct regmap_access_table qca8k_readable_table = { -+ .yes_ranges = qca8k_readable_ranges, -+ .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), -+}; -+ -+static struct regmap_config qca8k_regmap_config = { -+ .reg_bits = 16, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .max_register = 0x16ac, /* end MIB - Port6 range */ -+ .reg_read = qca8k_regmap_read, -+ .reg_write = qca8k_regmap_write, -+ .reg_update_bits = qca8k_regmap_update_bits, -+ .rd_table = &qca8k_readable_table, -+ .disable_locking = true, /* Locking is handled by qca8k read/write */ -+ .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ -+}; -+ -+static int -+qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) -+{ -+ u32 val; -+ -+ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, -+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); -+} -+ -+static int -+qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) -+{ -+ u32 reg[3]; -+ int ret; -+ -+ /* load the ARL table into an array */ -+ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -+ if (ret) -+ return ret; -+ -+ /* vid - 83:72 */ -+ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); -+ /* aging - 67:64 */ -+ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); -+ /* portmask - 54:48 */ -+ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); -+ /* mac - 47:0 */ -+ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); -+ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); -+ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); -+ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); -+ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); -+ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); -+ -+ return 0; -+} -+ -+static void -+qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, -+ u8 aging) -+{ -+ u32 reg[3] = { 0 }; -+ -+ /* vid - 83:72 */ -+ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); -+ /* aging - 67:64 */ -+ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); -+ /* portmask - 54:48 */ -+ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); -+ /* mac - 47:0 */ -+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); -+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); -+ -+ /* load the array into the ARL table */ -+ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -+} -+ -+static int -+qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) -+{ -+ u32 reg; -+ int ret; -+ -+ /* Set the command and FDB index */ -+ reg = QCA8K_ATU_FUNC_BUSY; -+ reg |= cmd; -+ if (port >= 0) { -+ reg |= QCA8K_ATU_FUNC_PORT_EN; -+ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); -+ } -+ -+ /* Write the function register triggering the table access */ -+ ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); -+ if (ret) -+ return ret; -+ -+ /* wait for completion */ -+ ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); -+ if (ret) -+ return ret; -+ -+ /* Check for table full violation when adding an entry */ -+ if (cmd == QCA8K_FDB_LOAD) { -+ ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); -+ if (ret < 0) -+ return ret; -+ if (reg & QCA8K_ATU_FUNC_FULL) -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) -+{ -+ int ret; -+ -+ qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); -+ if (ret < 0) -+ return ret; -+ -+ return qca8k_fdb_read(priv, fdb); -+} -+ -+static int -+qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, -+ u16 vid, u8 aging) -+{ -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_write(priv, vid, port_mask, mac, aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int -+qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) -+{ -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_write(priv, vid, port_mask, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static void -+qca8k_fdb_flush(struct qca8k_priv *priv) -+{ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); -+ mutex_unlock(&priv->reg_mutex); -+} -+ -+static int -+qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, -+ const u8 *mac, u16 vid) -+{ -+ struct qca8k_fdb fdb = { 0 }; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ qca8k_fdb_write(priv, vid, 0, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -+ if (ret < 0) -+ goto exit; -+ -+ ret = qca8k_fdb_read(priv, &fdb); -+ if (ret < 0) -+ goto exit; -+ -+ /* Rule exist. Delete first */ -+ if (!fdb.aging) { -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ if (ret) -+ goto exit; -+ } -+ -+ /* Add port to fdb portmask */ -+ fdb.port_mask |= port_mask; -+ -+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static int -+qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, -+ const u8 *mac, u16 vid) -+{ -+ struct qca8k_fdb fdb = { 0 }; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ qca8k_fdb_write(priv, vid, 0, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -+ if (ret < 0) -+ goto exit; -+ -+ /* Rule doesn't exist. Why delete? */ -+ if (!fdb.aging) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ if (ret) -+ goto exit; -+ -+ /* Only port in the rule is this port. Don't re insert */ -+ if (fdb.port_mask == port_mask) -+ goto exit; -+ -+ /* Remove port from port mask */ -+ fdb.port_mask &= ~port_mask; -+ -+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static int -+qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) -+{ -+ u32 reg; -+ int ret; -+ -+ /* Set the command and VLAN index */ -+ reg = QCA8K_VTU_FUNC1_BUSY; -+ reg |= cmd; -+ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); -+ -+ /* Write the function register triggering the table access */ -+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); -+ if (ret) -+ return ret; -+ -+ /* wait for completion */ -+ ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); -+ if (ret) -+ return ret; -+ -+ /* Check for table full violation when adding an entry */ -+ if (cmd == QCA8K_VLAN_LOAD) { -+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); -+ if (ret < 0) -+ return ret; -+ if (reg & QCA8K_VTU_FUNC1_FULL) -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) -+{ -+ u32 reg; -+ int ret; -+ -+ /* -+ We do the right thing with VLAN 0 and treat it as untagged while -+ preserving the tag on egress. -+ */ -+ if (vid == 0) -+ return 0; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -+ if (ret < 0) -+ goto out; -+ -+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -+ if (ret < 0) -+ goto out; -+ reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; -+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -+ if (untagged) -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); -+ else -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); -+ -+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -+ if (ret) -+ goto out; -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -+ -+out: -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int -+qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) -+{ -+ u32 reg, mask; -+ int ret, i; -+ bool del; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -+ if (ret < 0) -+ goto out; -+ -+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -+ if (ret < 0) -+ goto out; -+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); -+ -+ /* Check if we're the last member to be removed */ -+ del = true; -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); -+ -+ if ((reg & mask) != mask) { -+ del = false; -+ break; -+ } -+ } -+ -+ if (del) { -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); -+ } else { -+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -+ if (ret) -+ goto out; -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -+ } -+ -+out: -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int -+qca8k_mib_init(struct qca8k_priv *priv) -+{ -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | -+ QCA8K_MIB_BUSY); -+ if (ret) -+ goto exit; -+ -+ ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); -+ if (ret) -+ goto exit; -+ -+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); -+ if (ret) -+ goto exit; -+ -+ ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static void -+qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) -+{ -+ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; -+ -+ /* Port 0 and 6 have no internal PHY */ -+ if (port > 0 && port < 6) -+ mask |= QCA8K_PORT_STATUS_LINK_AUTO; -+ -+ if (enable) -+ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); -+ else -+ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); -+} -+ -+static int -+qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, -+ struct sk_buff *read_skb, u32 *val) -+{ -+ struct sk_buff *skb = skb_copy(read_skb, GFP_KERNEL); -+ bool ack; -+ int ret; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the copy pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ ack = mgmt_eth_data->ack; -+ -+ if (ret <= 0) -+ return -ETIMEDOUT; -+ -+ if (!ack) -+ return -EINVAL; -+ -+ *val = mgmt_eth_data->data[0]; -+ -+ return 0; -+} -+ -+static int -+qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy, -+ int regnum, u16 data) -+{ -+ struct sk_buff *write_skb, *clear_skb, *read_skb; -+ struct qca8k_mgmt_eth_data *mgmt_eth_data; -+ u32 write_val, clear_val = 0, val; -+ struct net_device *mgmt_master; -+ int ret, ret1; -+ bool ack; -+ -+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -+ return -EINVAL; -+ -+ mgmt_eth_data = &priv->mgmt_eth_data; -+ -+ write_val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -+ QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -+ QCA8K_MDIO_MASTER_REG_ADDR(regnum); -+ -+ if (read) { -+ write_val |= QCA8K_MDIO_MASTER_READ; -+ } else { -+ write_val |= QCA8K_MDIO_MASTER_WRITE; -+ write_val |= QCA8K_MDIO_MASTER_DATA(data); -+ } -+ -+ /* Prealloc all the needed skb before the lock */ -+ write_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &write_val, -+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val)); -+ if (!write_skb) -+ return -ENOMEM; -+ -+ clear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, &clear_val, -+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); -+ if (!clear_skb) { -+ ret = -ENOMEM; -+ goto err_clear_skb; -+ } -+ -+ read_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, &clear_val, -+ QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val)); -+ if (!read_skb) { -+ ret = -ENOMEM; -+ goto err_read_skb; -+ } -+ -+ /* Actually start the request: -+ * 1. Send mdio master packet -+ * 2. Busy Wait for mdio master command -+ * 3. Get the data if we are reading -+ * 4. Reset the mdio master (even with error) -+ */ -+ mutex_lock(&mgmt_eth_data->mutex); -+ -+ /* Check if mgmt_master is operational */ -+ mgmt_master = priv->mgmt_master; -+ if (!mgmt_master) { -+ mutex_unlock(&mgmt_eth_data->mutex); -+ ret = -EINVAL; -+ goto err_mgmt_master; -+ } -+ -+ read_skb->dev = mgmt_master; -+ clear_skb->dev = mgmt_master; -+ write_skb->dev = mgmt_master; -+ -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the write pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(write_skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ ack = mgmt_eth_data->ack; -+ -+ if (ret <= 0) { -+ ret = -ETIMEDOUT; -+ kfree_skb(read_skb); -+ goto exit; -+ } -+ -+ if (!ack) { -+ ret = -EINVAL; -+ kfree_skb(read_skb); -+ goto exit; -+ } -+ -+ ret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1, -+ !(val & QCA8K_MDIO_MASTER_BUSY), 0, -+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -+ mgmt_eth_data, read_skb, &val); -+ -+ if (ret < 0 && ret1 < 0) { -+ ret = ret1; -+ goto exit; -+ } -+ -+ if (read) { -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the read pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(read_skb); -+ -+ ret = wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ ack = mgmt_eth_data->ack; -+ -+ if (ret <= 0) { -+ ret = -ETIMEDOUT; -+ goto exit; -+ } -+ -+ if (!ack) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ ret = mgmt_eth_data->data[0] & QCA8K_MDIO_MASTER_DATA_MASK; -+ } else { -+ kfree_skb(read_skb); -+ } -+exit: -+ reinit_completion(&mgmt_eth_data->rw_done); -+ -+ /* Increment seq_num and set it in the clear pkt */ -+ mgmt_eth_data->seq++; -+ qca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data->seq); -+ mgmt_eth_data->ack = false; -+ -+ dev_queue_xmit(clear_skb); -+ -+ wait_for_completion_timeout(&mgmt_eth_data->rw_done, -+ QCA8K_ETHERNET_TIMEOUT); -+ -+ mutex_unlock(&mgmt_eth_data->mutex); -+ -+ return ret; -+ -+ /* Error handling before lock */ -+err_mgmt_master: -+ kfree_skb(read_skb); -+err_read_skb: -+ kfree_skb(clear_skb); -+err_clear_skb: -+ kfree_skb(write_skb); -+ -+ return ret; -+} -+ -+static u32 -+qca8k_port_to_phy(int port) -+{ -+ /* From Andrew Lunn: -+ * Port 0 has no internal phy. -+ * Port 1 has an internal PHY at MDIO address 0. -+ * Port 2 has an internal PHY at MDIO address 1. -+ * ... -+ * Port 5 has an internal PHY at MDIO address 4. -+ * Port 6 has no internal PHY. -+ */ -+ -+ return port - 1; -+} -+ -+static int -+qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) -+{ -+ u16 r1, r2, page; -+ u32 val; -+ int ret, ret1; -+ -+ qca8k_split_addr(reg, &r1, &r2, &page); -+ -+ ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, -+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -+ bus, 0x10 | r2, r1, &val); -+ -+ /* Check if qca8k_read has failed for a different reason -+ * before returnting -ETIMEDOUT -+ */ -+ if (ret < 0 && ret1 < 0) -+ return ret1; -+ -+ return ret; -+} -+ -+static int -+qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data) -+{ -+ struct mii_bus *bus = priv->bus; -+ u16 r1, r2, page; -+ u32 val; -+ int ret; -+ -+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -+ return -EINVAL; -+ -+ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -+ QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -+ QCA8K_MDIO_MASTER_REG_ADDR(regnum) | -+ QCA8K_MDIO_MASTER_DATA(data); -+ -+ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = qca8k_set_page(priv, page); -+ if (ret) -+ goto exit; -+ -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ -+ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, -+ QCA8K_MDIO_MASTER_BUSY); -+ -+exit: -+ /* even if the busy_wait timeouts try to clear the MASTER_EN */ -+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0); -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ return ret; -+} -+ -+static int -+qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum) -+{ -+ struct mii_bus *bus = priv->bus; -+ u16 r1, r2, page; -+ u32 val; -+ int ret; -+ -+ if (regnum >= QCA8K_MDIO_MASTER_MAX_REG) -+ return -EINVAL; -+ -+ val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN | -+ QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) | -+ QCA8K_MDIO_MASTER_REG_ADDR(regnum); -+ -+ qca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, &r1, &r2, &page); -+ -+ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ -+ ret = qca8k_set_page(priv, page); -+ if (ret) -+ goto exit; -+ -+ qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ -+ ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, -+ QCA8K_MDIO_MASTER_BUSY); -+ if (ret) -+ goto exit; -+ -+ ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); -+ -+exit: -+ /* even if the busy_wait timeouts try to clear the MASTER_EN */ -+ qca8k_mii_write32(priv, 0x10 | r2, r1, 0); -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ if (ret >= 0) -+ ret = val & QCA8K_MDIO_MASTER_DATA_MASK; -+ -+ return ret; -+} -+ -+static int -+qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data) -+{ -+ struct qca8k_priv *priv = slave_bus->priv; -+ int ret; -+ -+ /* Use mdio Ethernet when available, fallback to legacy one on error */ -+ ret = qca8k_phy_eth_command(priv, false, phy, regnum, data); -+ if (!ret) -+ return 0; -+ -+ return qca8k_mdio_write(priv, phy, regnum, data); -+} -+ -+static int -+qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) -+{ -+ struct qca8k_priv *priv = slave_bus->priv; -+ int ret; -+ -+ /* Use mdio Ethernet when available, fallback to legacy one on error */ -+ ret = qca8k_phy_eth_command(priv, true, phy, regnum, 0); -+ if (ret >= 0) -+ return ret; -+ -+ ret = qca8k_mdio_read(priv, phy, regnum); -+ -+ if (ret < 0) -+ return 0xffff; -+ -+ return ret; -+} -+ -+static int -+qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data) -+{ -+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; -+ -+ return qca8k_internal_mdio_write(slave_bus, port, regnum, data); -+} -+ -+static int -+qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum) -+{ -+ port = qca8k_port_to_phy(port) % PHY_MAX_ADDR; -+ -+ return qca8k_internal_mdio_read(slave_bus, port, regnum); -+} -+ -+static int -+qca8k_mdio_register(struct qca8k_priv *priv) -+{ -+ struct dsa_switch *ds = priv->ds; -+ struct device_node *mdio; -+ struct mii_bus *bus; -+ -+ bus = devm_mdiobus_alloc(ds->dev); -+ if (!bus) -+ return -ENOMEM; -+ -+ bus->priv = (void *)priv; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", -+ ds->dst->index, ds->index); -+ bus->parent = ds->dev; -+ bus->phy_mask = ~ds->phys_mii_mask; -+ ds->slave_mii_bus = bus; -+ -+ /* Check if the devicetree declare the port:phy mapping */ -+ mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); -+ if (of_device_is_available(mdio)) { -+ bus->name = "qca8k slave mii"; -+ bus->read = qca8k_internal_mdio_read; -+ bus->write = qca8k_internal_mdio_write; -+ return devm_of_mdiobus_register(priv->dev, bus, mdio); -+ } -+ -+ /* If a mapping can't be found the legacy mapping is used, -+ * using the qca8k_port_to_phy function -+ */ -+ bus->name = "qca8k-legacy slave mii"; -+ bus->read = qca8k_legacy_mdio_read; -+ bus->write = qca8k_legacy_mdio_write; -+ return devm_mdiobus_register(priv->dev, bus); -+} -+ -+static int -+qca8k_setup_mdio_bus(struct qca8k_priv *priv) -+{ -+ u32 internal_mdio_mask = 0, external_mdio_mask = 0, reg; -+ struct device_node *ports, *port; -+ phy_interface_t mode; -+ int err; -+ -+ ports = of_get_child_by_name(priv->dev->of_node, "ports"); -+ if (!ports) -+ ports = of_get_child_by_name(priv->dev->of_node, "ethernet-ports"); -+ -+ if (!ports) -+ return -EINVAL; -+ -+ for_each_available_child_of_node(ports, port) { -+ err = of_property_read_u32(port, "reg", ®); -+ if (err) { -+ of_node_put(port); -+ of_node_put(ports); -+ return err; -+ } -+ -+ if (!dsa_is_user_port(priv->ds, reg)) -+ continue; -+ -+ of_get_phy_mode(port, &mode); -+ -+ if (of_property_read_bool(port, "phy-handle") && -+ mode != PHY_INTERFACE_MODE_INTERNAL) -+ external_mdio_mask |= BIT(reg); -+ else -+ internal_mdio_mask |= BIT(reg); -+ } -+ -+ of_node_put(ports); -+ if (!external_mdio_mask && !internal_mdio_mask) { -+ dev_err(priv->dev, "no PHYs are defined.\n"); -+ return -EINVAL; -+ } -+ -+ /* The QCA8K_MDIO_MASTER_EN Bit, which grants access to PHYs through -+ * the MDIO_MASTER register also _disconnects_ the external MDC -+ * passthrough to the internal PHYs. It's not possible to use both -+ * configurations at the same time! -+ * -+ * Because this came up during the review process: -+ * If the external mdio-bus driver is capable magically disabling -+ * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's -+ * accessors for the time being, it would be possible to pull this -+ * off. -+ */ -+ if (!!external_mdio_mask && !!internal_mdio_mask) { -+ dev_err(priv->dev, "either internal or external mdio bus configuration is supported.\n"); -+ return -EINVAL; -+ } -+ -+ if (external_mdio_mask) { -+ /* Make sure to disable the internal mdio bus in cases -+ * a dt-overlay and driver reload changed the configuration -+ */ -+ -+ return regmap_clear_bits(priv->regmap, QCA8K_MDIO_MASTER_CTRL, -+ QCA8K_MDIO_MASTER_EN); -+ } -+ -+ return qca8k_mdio_register(priv); -+} -+ -+static int -+qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv) -+{ -+ u32 mask = 0; -+ int ret = 0; -+ -+ /* SoC specific settings for ipq8064. -+ * If more device require this consider adding -+ * a dedicated binding. -+ */ -+ if (of_machine_is_compatible("qcom,ipq8064")) -+ mask |= QCA8K_MAC_PWR_RGMII0_1_8V; -+ -+ /* SoC specific settings for ipq8065 */ -+ if (of_machine_is_compatible("qcom,ipq8065")) -+ mask |= QCA8K_MAC_PWR_RGMII1_1_8V; -+ -+ if (mask) { -+ ret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL, -+ QCA8K_MAC_PWR_RGMII0_1_8V | -+ QCA8K_MAC_PWR_RGMII1_1_8V, -+ mask); -+ } -+ -+ return ret; -+} -+ -+static int qca8k_find_cpu_port(struct dsa_switch *ds) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ /* Find the connected cpu port. Valid port are 0 or 6 */ -+ if (dsa_is_cpu_port(ds, 0)) -+ return 0; -+ -+ dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6"); -+ -+ if (dsa_is_cpu_port(ds, 6)) -+ return 6; -+ -+ return -EINVAL; -+} -+ -+static int -+qca8k_setup_of_pws_reg(struct qca8k_priv *priv) -+{ -+ const struct qca8k_match_data *data = priv->info; -+ struct device_node *node = priv->dev->of_node; -+ u32 val = 0; -+ int ret; -+ -+ /* QCA8327 require to set to the correct mode. -+ * His bigger brother QCA8328 have the 172 pin layout. -+ * Should be applied by default but we set this just to make sure. -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8327) { -+ /* Set the correct package of 148 pin for QCA8327 */ -+ if (data->reduced_package) -+ val |= QCA8327_PWS_PACKAGE148_EN; -+ -+ ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN, -+ val); -+ if (ret) -+ return ret; -+ } -+ -+ if (of_property_read_bool(node, "qca,ignore-power-on-sel")) -+ val |= QCA8K_PWS_POWER_ON_SEL; -+ -+ if (of_property_read_bool(node, "qca,led-open-drain")) { -+ if (!(val & QCA8K_PWS_POWER_ON_SEL)) { -+ dev_err(priv->dev, "qca,led-open-drain require qca,ignore-power-on-sel to be set."); -+ return -EINVAL; -+ } -+ -+ val |= QCA8K_PWS_LED_OPEN_EN_CSR; -+ } -+ -+ return qca8k_rmw(priv, QCA8K_REG_PWS, -+ QCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL, -+ val); -+} -+ -+static int -+qca8k_parse_port_config(struct qca8k_priv *priv) -+{ -+ int port, cpu_port_index = -1, ret; -+ struct device_node *port_dn; -+ phy_interface_t mode; -+ struct dsa_port *dp; -+ u32 delay; -+ -+ /* We have 2 CPU port. Check them */ -+ for (port = 0; port < QCA8K_NUM_PORTS; port++) { -+ /* Skip every other port */ -+ if (port != 0 && port != 6) -+ continue; -+ -+ dp = dsa_to_port(priv->ds, port); -+ port_dn = dp->dn; -+ cpu_port_index++; -+ -+ if (!of_device_is_available(port_dn)) -+ continue; -+ -+ ret = of_get_phy_mode(port_dn, &mode); -+ if (ret) -+ continue; -+ -+ switch (mode) { -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ case PHY_INTERFACE_MODE_SGMII: -+ delay = 0; -+ -+ if (!of_property_read_u32(port_dn, "tx-internal-delay-ps", &delay)) -+ /* Switch regs accept value in ns, convert ps to ns */ -+ delay = delay / 1000; -+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID || -+ mode == PHY_INTERFACE_MODE_RGMII_TXID) -+ delay = 1; -+ -+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK, delay)) { -+ dev_err(priv->dev, "rgmii tx delay is limited to a max value of 3ns, setting to the max value"); -+ delay = 3; -+ } -+ -+ priv->ports_config.rgmii_tx_delay[cpu_port_index] = delay; -+ -+ delay = 0; -+ -+ if (!of_property_read_u32(port_dn, "rx-internal-delay-ps", &delay)) -+ /* Switch regs accept value in ns, convert ps to ns */ -+ delay = delay / 1000; -+ else if (mode == PHY_INTERFACE_MODE_RGMII_ID || -+ mode == PHY_INTERFACE_MODE_RGMII_RXID) -+ delay = 2; -+ -+ if (!FIELD_FIT(QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK, delay)) { -+ dev_err(priv->dev, "rgmii rx delay is limited to a max value of 3ns, setting to the max value"); -+ delay = 3; -+ } -+ -+ priv->ports_config.rgmii_rx_delay[cpu_port_index] = delay; -+ -+ /* Skip sgmii parsing for rgmii* mode */ -+ if (mode == PHY_INTERFACE_MODE_RGMII || -+ mode == PHY_INTERFACE_MODE_RGMII_ID || -+ mode == PHY_INTERFACE_MODE_RGMII_TXID || -+ mode == PHY_INTERFACE_MODE_RGMII_RXID) -+ break; -+ -+ if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge")) -+ priv->ports_config.sgmii_tx_clk_falling_edge = true; -+ -+ if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge")) -+ priv->ports_config.sgmii_rx_clk_falling_edge = true; -+ -+ if (of_property_read_bool(port_dn, "qca,sgmii-enable-pll")) { -+ priv->ports_config.sgmii_enable_pll = true; -+ -+ if (priv->switch_id == QCA8K_ID_QCA8327) { -+ dev_err(priv->dev, "SGMII PLL should NOT be enabled for qca8327. Aborting enabling"); -+ priv->ports_config.sgmii_enable_pll = false; -+ } -+ -+ if (priv->switch_revision < 2) -+ dev_warn(priv->dev, "SGMII PLL should NOT be enabled for qca8337 with revision 2 or more."); -+ } -+ -+ break; -+ default: -+ continue; -+ } -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_setup(struct dsa_switch *ds) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ int cpu_port, ret, i; -+ u32 mask; -+ -+ cpu_port = qca8k_find_cpu_port(ds); -+ if (cpu_port < 0) { -+ dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6"); -+ return cpu_port; -+ } -+ -+ /* Parse CPU port config to be later used in phy_link mac_config */ -+ ret = qca8k_parse_port_config(priv); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_setup_mdio_bus(priv); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_setup_of_pws_reg(priv); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_setup_mac_pwr_sel(priv); -+ if (ret) -+ return ret; -+ -+ /* Make sure MAC06 is disabled */ -+ ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, -+ QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); -+ if (ret) { -+ dev_err(priv->dev, "failed disabling MAC06 exchange"); -+ return ret; -+ } -+ -+ /* Enable CPU Port */ -+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); -+ if (ret) { -+ dev_err(priv->dev, "failed enabling CPU port"); -+ return ret; -+ } -+ -+ /* Enable MIB counters */ -+ ret = qca8k_mib_init(priv); -+ if (ret) -+ dev_warn(priv->dev, "mib init failed"); -+ -+ /* Initial setup of all ports */ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ /* Disable forwarding by default on all ports */ -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -+ QCA8K_PORT_LOOKUP_MEMBER, 0); -+ if (ret) -+ return ret; -+ -+ /* Enable QCA header mode on all cpu ports */ -+ if (dsa_is_cpu_port(ds, i)) { -+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), -+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | -+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); -+ if (ret) { -+ dev_err(priv->dev, "failed enabling QCA header mode"); -+ return ret; -+ } -+ } -+ -+ /* Disable MAC by default on all user ports */ -+ if (dsa_is_user_port(ds, i)) -+ qca8k_port_set_status(priv, i, 0); -+ } -+ -+ /* Forward all unknown frames to CPU port for Linux processing -+ * Notice that in multi-cpu config only one port should be set -+ * for igmp, unknown, multicast and broadcast packet -+ */ -+ ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); -+ if (ret) -+ return ret; -+ -+ /* Setup connection between CPU port & user ports -+ * Configure specific switch configuration for ports -+ */ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ /* CPU port gets connected to all user ports of the switch */ -+ if (dsa_is_cpu_port(ds, i)) { -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -+ QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); -+ if (ret) -+ return ret; -+ } -+ -+ /* Individual user ports get connected to CPU port only */ -+ if (dsa_is_user_port(ds, i)) { -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -+ QCA8K_PORT_LOOKUP_MEMBER, -+ BIT(cpu_port)); -+ if (ret) -+ return ret; -+ -+ /* Enable ARP Auto-learning by default */ -+ ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), -+ QCA8K_PORT_LOOKUP_LEARN); -+ if (ret) -+ return ret; -+ -+ /* For port based vlans to work we need to set the -+ * default egress vid -+ */ -+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), -+ QCA8K_EGREES_VLAN_PORT_MASK(i), -+ QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), -+ QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | -+ QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); -+ if (ret) -+ return ret; -+ } -+ -+ /* The port 5 of the qca8337 have some problem in flood condition. The -+ * original legacy driver had some specific buffer and priority settings -+ * for the different port suggested by the QCA switch team. Add this -+ * missing settings to improve switch stability under load condition. -+ * This problem is limited to qca8337 and other qca8k switch are not affected. -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8337) { -+ switch (i) { -+ /* The 2 CPU port and port 5 requires some different -+ * priority than any other ports. -+ */ -+ case 0: -+ case 5: -+ case 6: -+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | -+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); -+ break; -+ default: -+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | -+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); -+ } -+ qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask); -+ -+ mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | -+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_WRED_EN; -+ qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), -+ QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | -+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_WRED_EN, -+ mask); -+ } -+ } -+ -+ /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ -+ if (priv->switch_id == QCA8K_ID_QCA8327) { -+ mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | -+ QCA8K_GLOBAL_FC_GOL_XOFF_THRES(496); -+ qca8k_rmw(priv, QCA8K_REG_GLOBAL_FC_THRESH, -+ QCA8K_GLOBAL_FC_GOL_XON_THRES_MASK | -+ QCA8K_GLOBAL_FC_GOL_XOFF_THRES_MASK, -+ mask); -+ } -+ -+ /* Setup our port MTUs to match power on defaults */ -+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN); -+ if (ret) -+ dev_warn(priv->dev, "failed setting MTU settings"); -+ -+ /* Flush the FDB table */ -+ qca8k_fdb_flush(priv); -+ -+ /* We don't have interrupts for link changes, so we need to poll */ -+ ds->pcs_poll = true; -+ -+ /* Set min a max ageing value supported */ -+ ds->ageing_time_min = 7000; -+ ds->ageing_time_max = 458745000; -+ -+ /* Set max number of LAGs supported */ -+ ds->num_lag_ids = QCA8K_NUM_LAGS; -+ -+ return 0; -+} -+ -+static void -+qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index, -+ u32 reg) -+{ -+ u32 delay, val = 0; -+ int ret; -+ -+ /* Delay can be declared in 3 different way. -+ * Mode to rgmii and internal-delay standard binding defined -+ * rgmii-id or rgmii-tx/rx phy mode set. -+ * The parse logic set a delay different than 0 only when one -+ * of the 3 different way is used. In all other case delay is -+ * not enabled. With ID or TX/RXID delay is enabled and set -+ * to the default and recommended value. -+ */ -+ if (priv->ports_config.rgmii_tx_delay[cpu_port_index]) { -+ delay = priv->ports_config.rgmii_tx_delay[cpu_port_index]; -+ -+ val |= QCA8K_PORT_PAD_RGMII_TX_DELAY(delay) | -+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN; -+ } -+ -+ if (priv->ports_config.rgmii_rx_delay[cpu_port_index]) { -+ delay = priv->ports_config.rgmii_rx_delay[cpu_port_index]; -+ -+ val |= QCA8K_PORT_PAD_RGMII_RX_DELAY(delay) | -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN; -+ } -+ -+ /* Set RGMII delay based on the selected values */ -+ ret = qca8k_rmw(priv, reg, -+ QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK | -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK | -+ QCA8K_PORT_PAD_RGMII_TX_DELAY_EN | -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN, -+ val); -+ if (ret) -+ dev_err(priv->dev, "Failed to set internal delay for CPU port%d", -+ cpu_port_index == QCA8K_CPU_PORT0 ? 0 : 6); -+} -+ -+static void -+qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int cpu_port_index, ret; -+ u32 reg, val; -+ -+ switch (port) { -+ case 0: /* 1st CPU port */ -+ if (state->interface != PHY_INTERFACE_MODE_RGMII && -+ state->interface != PHY_INTERFACE_MODE_RGMII_ID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -+ state->interface != PHY_INTERFACE_MODE_SGMII) -+ return; -+ -+ reg = QCA8K_REG_PORT0_PAD_CTRL; -+ cpu_port_index = QCA8K_CPU_PORT0; -+ break; -+ case 1: -+ case 2: -+ case 3: -+ case 4: -+ case 5: -+ /* Internal PHY, nothing to do */ -+ return; -+ case 6: /* 2nd CPU port / external PHY */ -+ if (state->interface != PHY_INTERFACE_MODE_RGMII && -+ state->interface != PHY_INTERFACE_MODE_RGMII_ID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -+ state->interface != PHY_INTERFACE_MODE_SGMII && -+ state->interface != PHY_INTERFACE_MODE_1000BASEX) -+ return; -+ -+ reg = QCA8K_REG_PORT6_PAD_CTRL; -+ cpu_port_index = QCA8K_CPU_PORT6; -+ break; -+ default: -+ dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port); -+ return; -+ } -+ -+ if (port != 6 && phylink_autoneg_inband(mode)) { -+ dev_err(ds->dev, "%s: in-band negotiation unsupported\n", -+ __func__); -+ return; -+ } -+ -+ switch (state->interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN); -+ -+ /* Configure rgmii delay */ -+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -+ -+ /* QCA8337 requires to set rgmii rx delay for all ports. -+ * This is enabled through PORT5_PAD_CTRL for all ports, -+ * rather than individual port registers. -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8337) -+ qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, -+ QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); -+ break; -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ /* Enable SGMII on the port */ -+ qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); -+ -+ /* Enable/disable SerDes auto-negotiation as necessary */ -+ ret = qca8k_read(priv, QCA8K_REG_PWS, &val); -+ if (ret) -+ return; -+ if (phylink_autoneg_inband(mode)) -+ val &= ~QCA8K_PWS_SERDES_AEN_DIS; -+ else -+ val |= QCA8K_PWS_SERDES_AEN_DIS; -+ qca8k_write(priv, QCA8K_REG_PWS, val); -+ -+ /* Configure the SGMII parameters */ -+ ret = qca8k_read(priv, QCA8K_REG_SGMII_CTRL, &val); -+ if (ret) -+ return; -+ -+ val |= QCA8K_SGMII_EN_SD; -+ -+ if (priv->ports_config.sgmii_enable_pll) -+ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX | -+ QCA8K_SGMII_EN_TX; -+ -+ if (dsa_is_cpu_port(ds, port)) { -+ /* CPU port, we're talking to the CPU MAC, be a PHY */ -+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -+ val |= QCA8K_SGMII_MODE_CTRL_PHY; -+ } else if (state->interface == PHY_INTERFACE_MODE_SGMII) { -+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -+ val |= QCA8K_SGMII_MODE_CTRL_MAC; -+ } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) { -+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK; -+ val |= QCA8K_SGMII_MODE_CTRL_BASEX; -+ } -+ -+ qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val); -+ -+ /* From original code is reported port instability as SGMII also -+ * require delay set. Apply advised values here or take them from DT. -+ */ -+ if (state->interface == PHY_INTERFACE_MODE_SGMII) -+ qca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg); -+ -+ /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and -+ * falling edge is set writing in the PORT0 PAD reg -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8327 || -+ priv->switch_id == QCA8K_ID_QCA8337) -+ reg = QCA8K_REG_PORT0_PAD_CTRL; -+ -+ val = 0; -+ -+ /* SGMII Clock phase configuration */ -+ if (priv->ports_config.sgmii_rx_clk_falling_edge) -+ val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE; -+ -+ if (priv->ports_config.sgmii_tx_clk_falling_edge) -+ val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE; -+ -+ if (val) -+ ret = qca8k_rmw(priv, reg, -+ QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE | -+ QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE, -+ val); -+ -+ break; -+ default: -+ dev_err(ds->dev, "xMII mode %s not supported for port %d\n", -+ phy_modes(state->interface), port); -+ return; -+ } -+} -+ -+static void -+qca8k_phylink_validate(struct dsa_switch *ds, int port, -+ unsigned long *supported, -+ struct phylink_link_state *state) -+{ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -+ -+ switch (port) { -+ case 0: /* 1st CPU port */ -+ if (state->interface != PHY_INTERFACE_MODE_NA && -+ state->interface != PHY_INTERFACE_MODE_RGMII && -+ state->interface != PHY_INTERFACE_MODE_RGMII_ID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -+ state->interface != PHY_INTERFACE_MODE_SGMII) -+ goto unsupported; -+ break; -+ case 1: -+ case 2: -+ case 3: -+ case 4: -+ case 5: -+ /* Internal PHY */ -+ if (state->interface != PHY_INTERFACE_MODE_NA && -+ state->interface != PHY_INTERFACE_MODE_GMII && -+ state->interface != PHY_INTERFACE_MODE_INTERNAL) -+ goto unsupported; -+ break; -+ case 6: /* 2nd CPU port / external PHY */ -+ if (state->interface != PHY_INTERFACE_MODE_NA && -+ state->interface != PHY_INTERFACE_MODE_RGMII && -+ state->interface != PHY_INTERFACE_MODE_RGMII_ID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_TXID && -+ state->interface != PHY_INTERFACE_MODE_RGMII_RXID && -+ state->interface != PHY_INTERFACE_MODE_SGMII && -+ state->interface != PHY_INTERFACE_MODE_1000BASEX) -+ goto unsupported; -+ break; -+ default: -+unsupported: -+ linkmode_zero(supported); -+ return; -+ } -+ -+ phylink_set_port_modes(mask); -+ phylink_set(mask, Autoneg); -+ -+ phylink_set(mask, 1000baseT_Full); -+ phylink_set(mask, 10baseT_Half); -+ phylink_set(mask, 10baseT_Full); -+ phylink_set(mask, 100baseT_Half); -+ phylink_set(mask, 100baseT_Full); -+ -+ if (state->interface == PHY_INTERFACE_MODE_1000BASEX) -+ phylink_set(mask, 1000baseX_Full); -+ -+ phylink_set(mask, Pause); -+ phylink_set(mask, Asym_Pause); -+ -+ linkmode_and(supported, supported, mask); -+ linkmode_and(state->advertising, state->advertising, mask); -+} -+ -+static int -+qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port, -+ struct phylink_link_state *state) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ u32 reg; -+ int ret; -+ -+ ret = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port), ®); -+ if (ret < 0) -+ return ret; -+ -+ state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP); -+ state->an_complete = state->link; -+ state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO); -+ state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL : -+ DUPLEX_HALF; -+ -+ switch (reg & QCA8K_PORT_STATUS_SPEED) { -+ case QCA8K_PORT_STATUS_SPEED_10: -+ state->speed = SPEED_10; -+ break; -+ case QCA8K_PORT_STATUS_SPEED_100: -+ state->speed = SPEED_100; -+ break; -+ case QCA8K_PORT_STATUS_SPEED_1000: -+ state->speed = SPEED_1000; -+ break; -+ default: -+ state->speed = SPEED_UNKNOWN; -+ break; -+ } -+ -+ state->pause = MLO_PAUSE_NONE; -+ if (reg & QCA8K_PORT_STATUS_RXFLOW) -+ state->pause |= MLO_PAUSE_RX; -+ if (reg & QCA8K_PORT_STATUS_TXFLOW) -+ state->pause |= MLO_PAUSE_TX; -+ -+ return 1; -+} -+ -+static void -+qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode, -+ phy_interface_t interface) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ qca8k_port_set_status(priv, port, 0); -+} -+ -+static void -+qca8k_phylink_mac_link_up(struct dsa_switch *ds, int port, unsigned int mode, -+ phy_interface_t interface, struct phy_device *phydev, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ u32 reg; -+ -+ if (phylink_autoneg_inband(mode)) { -+ reg = QCA8K_PORT_STATUS_LINK_AUTO; -+ } else { -+ switch (speed) { -+ case SPEED_10: -+ reg = QCA8K_PORT_STATUS_SPEED_10; -+ break; -+ case SPEED_100: -+ reg = QCA8K_PORT_STATUS_SPEED_100; -+ break; -+ case SPEED_1000: -+ reg = QCA8K_PORT_STATUS_SPEED_1000; -+ break; -+ default: -+ reg = QCA8K_PORT_STATUS_LINK_AUTO; -+ break; -+ } -+ -+ if (duplex == DUPLEX_FULL) -+ reg |= QCA8K_PORT_STATUS_DUPLEX; -+ -+ if (rx_pause || dsa_is_cpu_port(ds, port)) -+ reg |= QCA8K_PORT_STATUS_RXFLOW; -+ -+ if (tx_pause || dsa_is_cpu_port(ds, port)) -+ reg |= QCA8K_PORT_STATUS_TXFLOW; -+ } -+ -+ reg |= QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; -+ -+ qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); -+} -+ -+static void -+qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int i; -+ -+ if (stringset != ETH_SS_STATS) -+ return; -+ -+ for (i = 0; i < priv->info->mib_count; i++) -+ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, -+ ETH_GSTRING_LEN); -+} -+ -+static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) -+{ -+ struct qca8k_mib_eth_data *mib_eth_data; -+ struct qca8k_priv *priv = ds->priv; -+ const struct qca8k_mib_desc *mib; -+ struct mib_ethhdr *mib_ethhdr; -+ int i, mib_len, offset = 0; -+ u64 *data; -+ u8 port; -+ -+ mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); -+ mib_eth_data = &priv->mib_eth_data; -+ -+ /* The switch autocast every port. Ignore other packet and -+ * parse only the requested one. -+ */ -+ port = FIELD_GET(QCA_HDR_RECV_SOURCE_PORT, ntohs(mib_ethhdr->hdr)); -+ if (port != mib_eth_data->req_port) -+ goto exit; -+ -+ data = mib_eth_data->data; -+ -+ for (i = 0; i < priv->info->mib_count; i++) { -+ mib = &ar8327_mib[i]; -+ -+ /* First 3 mib are present in the skb head */ -+ if (i < 3) { -+ data[i] = mib_ethhdr->data[i]; -+ continue; -+ } -+ -+ mib_len = sizeof(uint32_t); -+ -+ /* Some mib are 64 bit wide */ -+ if (mib->size == 2) -+ mib_len = sizeof(uint64_t); -+ -+ /* Copy the mib value from packet to the */ -+ memcpy(data + i, skb->data + offset, mib_len); -+ -+ /* Set the offset for the next mib */ -+ offset += mib_len; -+ } -+ -+exit: -+ /* Complete on receiving all the mib packet */ -+ if (refcount_dec_and_test(&mib_eth_data->port_parsed)) -+ complete(&mib_eth_data->rw_done); -+} -+ -+static int -+qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data) -+{ -+ struct dsa_port *dp = dsa_to_port(ds, port); -+ struct qca8k_mib_eth_data *mib_eth_data; -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ mib_eth_data = &priv->mib_eth_data; -+ -+ mutex_lock(&mib_eth_data->mutex); -+ -+ reinit_completion(&mib_eth_data->rw_done); -+ -+ mib_eth_data->req_port = dp->index; -+ mib_eth_data->data = data; -+ refcount_set(&mib_eth_data->port_parsed, QCA8K_NUM_PORTS); -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ /* Send mib autocast request */ -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_CAST) | -+ QCA8K_MIB_BUSY); -+ -+ mutex_unlock(&priv->reg_mutex); -+ -+ if (ret) -+ goto exit; -+ -+ ret = wait_for_completion_timeout(&mib_eth_data->rw_done, QCA8K_ETHERNET_TIMEOUT); -+ -+exit: -+ mutex_unlock(&mib_eth_data->mutex); -+ -+ return ret; -+} -+ -+static void -+qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, -+ uint64_t *data) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ const struct qca8k_mib_desc *mib; -+ u32 reg, i, val; -+ u32 hi = 0; -+ int ret; -+ -+ if (priv->mgmt_master && priv->info->ops->autocast_mib && -+ priv->info->ops->autocast_mib(ds, port, data) > 0) -+ return; -+ -+ for (i = 0; i < priv->info->mib_count; i++) { -+ mib = &ar8327_mib[i]; -+ reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; -+ -+ ret = qca8k_read(priv, reg, &val); -+ if (ret < 0) -+ continue; -+ -+ if (mib->size == 2) { -+ ret = qca8k_read(priv, reg + 4, &hi); -+ if (ret < 0) -+ continue; -+ } -+ -+ data[i] = val; -+ if (mib->size == 2) -+ data[i] |= (u64)hi << 32; -+ } -+} -+ -+static int -+qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ if (sset != ETH_SS_STATS) -+ return 0; -+ -+ return priv->info->mib_count; -+} -+ -+static int -+qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); -+ u32 reg; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); -+ if (ret < 0) -+ goto exit; -+ -+ if (eee->eee_enabled) -+ reg |= lpi_en; -+ else -+ reg &= ~lpi_en; -+ ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static int -+qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) -+{ -+ /* Nothing to do on the port's MAC */ -+ return 0; -+} -+ -+static void -+qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ u32 stp_state; -+ -+ switch (state) { -+ case BR_STATE_DISABLED: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; -+ break; -+ case BR_STATE_BLOCKING: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; -+ break; -+ case BR_STATE_LISTENING: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; -+ break; -+ case BR_STATE_LEARNING: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; -+ break; -+ case BR_STATE_FORWARDING: -+ default: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; -+ break; -+ } -+ -+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); -+} -+ -+static int -+qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ int port_mask, cpu_port; -+ int i, ret; -+ -+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -+ port_mask = BIT(cpu_port); -+ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ if (dsa_is_cpu_port(ds, i)) -+ continue; -+ if (dsa_to_port(ds, i)->bridge_dev != br) -+ continue; -+ /* Add this port to the portvlan mask of the other ports -+ * in the bridge -+ */ -+ ret = regmap_set_bits(priv->regmap, -+ QCA8K_PORT_LOOKUP_CTRL(i), -+ BIT(port)); -+ if (ret) -+ return ret; -+ if (i != port) -+ port_mask |= BIT(i); -+ } -+ -+ /* Add all other ports to this ports portvlan mask */ -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_MEMBER, port_mask); -+ -+ return ret; -+} -+ -+static void -+qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ int cpu_port, i; -+ -+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -+ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ if (dsa_is_cpu_port(ds, i)) -+ continue; -+ if (dsa_to_port(ds, i)->bridge_dev != br) -+ continue; -+ /* Remove this port to the portvlan mask of the other ports -+ * in the bridge -+ */ -+ regmap_clear_bits(priv->regmap, -+ QCA8K_PORT_LOOKUP_CTRL(i), -+ BIT(port)); -+ } -+ -+ /* Set the cpu port to be the only one in the portvlan mask of -+ * this port -+ */ -+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); -+} -+ -+static void -+qca8k_port_fast_age(struct dsa_switch *ds, int port) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); -+ mutex_unlock(&priv->reg_mutex); -+} -+ -+static int -+qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ unsigned int secs = msecs / 1000; -+ u32 val; -+ -+ /* AGE_TIME reg is set in 7s step */ -+ val = secs / 7; -+ -+ /* Handle case with 0 as val to NOT disable -+ * learning -+ */ -+ if (!val) -+ val = 1; -+ -+ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, -+ QCA8K_ATU_AGE_TIME(val)); -+} -+ -+static int -+qca8k_port_enable(struct dsa_switch *ds, int port, -+ struct phy_device *phy) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ -+ qca8k_port_set_status(priv, port, 1); -+ priv->port_enabled_map |= BIT(port); -+ -+ if (dsa_is_user_port(ds, port)) -+ phy_support_asym_pause(phy); -+ -+ return 0; -+} -+ -+static void -+qca8k_port_disable(struct dsa_switch *ds, int port) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ -+ qca8k_port_set_status(priv, port, 0); -+ priv->port_enabled_map &= ~BIT(port); -+} -+ -+static int -+qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ /* We have only have a general MTU setting. -+ * DSA always set the CPU port's MTU to the largest MTU of the slave -+ * ports. -+ * Setting MTU just for the CPU port is sufficient to correctly set a -+ * value for every port. -+ */ -+ if (!dsa_is_cpu_port(ds, port)) -+ return 0; -+ -+ /* To change the MAX_FRAME_SIZE the cpu ports must be off or -+ * the switch panics. -+ * Turn off both cpu ports before applying the new value to prevent -+ * this. -+ */ -+ if (priv->port_enabled_map & BIT(0)) -+ qca8k_port_set_status(priv, 0, 0); -+ -+ if (priv->port_enabled_map & BIT(6)) -+ qca8k_port_set_status(priv, 6, 0); -+ -+ /* Include L2 header / FCS length */ -+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); -+ -+ if (priv->port_enabled_map & BIT(0)) -+ qca8k_port_set_status(priv, 0, 1); -+ -+ if (priv->port_enabled_map & BIT(6)) -+ qca8k_port_set_status(priv, 6, 1); -+ -+ return ret; -+} -+ -+static int -+qca8k_port_max_mtu(struct dsa_switch *ds, int port) -+{ -+ return QCA8K_MAX_MTU; -+} -+ -+static int -+qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, -+ u16 port_mask, u16 vid) -+{ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = QCA8K_PORT_VID_DEF; -+ -+ return qca8k_fdb_add(priv, addr, port_mask, vid, -+ QCA8K_ATU_STATUS_STATIC); -+} -+ -+static int -+qca8k_port_fdb_add(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ u16 port_mask = BIT(port); -+ -+ return qca8k_port_fdb_insert(priv, addr, port_mask, vid); -+} -+ -+static int -+qca8k_port_fdb_del(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ u16 port_mask = BIT(port); -+ -+ if (!vid) -+ vid = QCA8K_PORT_VID_DEF; -+ -+ return qca8k_fdb_del(priv, addr, port_mask, vid); -+} -+ -+static int -+qca8k_port_fdb_dump(struct dsa_switch *ds, int port, -+ dsa_fdb_dump_cb_t *cb, void *data) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ struct qca8k_fdb _fdb = { 0 }; -+ int cnt = QCA8K_NUM_FDB_RECORDS; -+ bool is_static; -+ int ret = 0; -+ -+ mutex_lock(&priv->reg_mutex); -+ while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { -+ if (!_fdb.aging) -+ break; -+ is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); -+ ret = cb(_fdb.mac, _fdb.vid, is_static, data); -+ if (ret) -+ break; -+ } -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+static int -+qca8k_port_mdb_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ const u8 *addr = mdb->addr; -+ u16 vid = mdb->vid; -+ -+ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); -+} -+ -+static int -+qca8k_port_mdb_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ const u8 *addr = mdb->addr; -+ u16 vid = mdb->vid; -+ -+ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); -+} -+ -+static int -+qca8k_port_mirror_add(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror, -+ bool ingress) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int monitor_port, ret; -+ u32 reg, val; -+ -+ /* Check for existent entry */ -+ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) -+ return -EEXIST; -+ -+ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); -+ if (ret) -+ return ret; -+ -+ /* QCA83xx can have only one port set to mirror mode. -+ * Check that the correct port is requested and return error otherwise. -+ * When no mirror port is set, the values is set to 0xF -+ */ -+ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (monitor_port != 0xF && monitor_port != mirror->to_local_port) -+ return -EEXIST; -+ -+ /* Set the monitor port */ -+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, -+ mirror->to_local_port); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (ret) -+ return ret; -+ -+ if (ingress) { -+ reg = QCA8K_PORT_LOOKUP_CTRL(port); -+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -+ } else { -+ reg = QCA8K_REG_PORT_HOL_CTRL1(port); -+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -+ } -+ -+ ret = regmap_update_bits(priv->regmap, reg, val, val); -+ if (ret) -+ return ret; -+ -+ /* Track mirror port for tx and rx to decide when the -+ * mirror port has to be disabled. -+ */ -+ if (ingress) -+ priv->mirror_rx |= BIT(port); -+ else -+ priv->mirror_tx |= BIT(port); -+ -+ return 0; -+} -+ -+static void -+qca8k_port_mirror_del(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ u32 reg, val; -+ int ret; -+ -+ if (mirror->ingress) { -+ reg = QCA8K_PORT_LOOKUP_CTRL(port); -+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -+ } else { -+ reg = QCA8K_REG_PORT_HOL_CTRL1(port); -+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -+ } -+ -+ ret = regmap_clear_bits(priv->regmap, reg, val); -+ if (ret) -+ goto err; -+ -+ if (mirror->ingress) -+ priv->mirror_rx &= ~BIT(port); -+ else -+ priv->mirror_tx &= ~BIT(port); -+ -+ /* No port set to send packet to mirror port. Disable mirror port */ -+ if (!priv->mirror_rx && !priv->mirror_tx) { -+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (ret) -+ goto err; -+ } -+err: -+ dev_err(priv->dev, "Failed to del mirror port from %d", port); -+} -+ -+static int -+qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, -+ struct netlink_ext_ack *extack) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ if (vlan_filtering) { -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -+ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); -+ } else { -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -+ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); -+ } -+ -+ return ret; -+} -+ -+static int -+qca8k_port_vlan_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan, -+ struct netlink_ext_ack *extack) -+{ -+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; -+ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); -+ if (ret) { -+ dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); -+ return ret; -+ } -+ -+ if (pvid) { -+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), -+ QCA8K_EGREES_VLAN_PORT_MASK(port), -+ QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), -+ QCA8K_PORT_VLAN_CVID(vlan->vid) | -+ QCA8K_PORT_VLAN_SVID(vlan->vid)); -+ } -+ -+ return ret; -+} -+ -+static int -+qca8k_port_vlan_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ ret = qca8k_vlan_del(priv, port, vlan->vid); -+ if (ret) -+ dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); -+ -+ return ret; -+} -+ -+static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ /* Communicate to the phy internal driver the switch revision. -+ * Based on the switch revision different values needs to be -+ * set to the dbg and mmd reg on the phy. -+ * The first 2 bit are used to communicate the switch revision -+ * to the phy driver. -+ */ -+ if (port > 0 && port < 6) -+ return priv->switch_revision; -+ -+ return 0; -+} -+ -+static enum dsa_tag_protocol -+qca8k_get_tag_protocol(struct dsa_switch *ds, int port, -+ enum dsa_tag_protocol mp) -+{ -+ return DSA_TAG_PROTO_QCA; -+} -+ -+static bool -+qca8k_lag_can_offload(struct dsa_switch *ds, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ struct dsa_port *dp; -+ int id, members = 0; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ if (id < 0 || id >= ds->num_lag_ids) -+ return false; -+ -+ dsa_lag_foreach_port(dp, ds->dst, lag) -+ /* Includes the port joining the LAG */ -+ members++; -+ -+ if (members > QCA8K_NUM_PORTS_FOR_LAG) -+ return false; -+ -+ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) -+ return false; -+ -+ if (info->hash_type != NETDEV_LAG_HASH_L2 && -+ info->hash_type != NETDEV_LAG_HASH_L23) -+ return false; -+ -+ return true; -+} -+ -+static int -+qca8k_lag_setup_hash(struct dsa_switch *ds, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ bool unique_lag = true; -+ u32 hash = 0; -+ int i, id; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ -+ switch (info->hash_type) { -+ case NETDEV_LAG_HASH_L23: -+ hash |= QCA8K_TRUNK_HASH_SIP_EN; -+ hash |= QCA8K_TRUNK_HASH_DIP_EN; -+ fallthrough; -+ case NETDEV_LAG_HASH_L2: -+ hash |= QCA8K_TRUNK_HASH_SA_EN; -+ hash |= QCA8K_TRUNK_HASH_DA_EN; -+ break; -+ default: /* We should NEVER reach this */ -+ return -EOPNOTSUPP; -+ } -+ -+ /* Check if we are the unique configured LAG */ -+ dsa_lags_foreach_id(i, ds->dst) -+ if (i != id && dsa_lag_dev(ds->dst, i)) { -+ unique_lag = false; -+ break; -+ } -+ -+ /* Hash Mode is global. Make sure the same Hash Mode -+ * is set to all the 4 possible lag. -+ * If we are the unique LAG we can set whatever hash -+ * mode we want. -+ * To change hash mode it's needed to remove all LAG -+ * and change the mode with the latest. -+ */ -+ if (unique_lag) { -+ priv->lag_hash_mode = hash; -+ } else if (priv->lag_hash_mode != hash) { -+ netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, -+ QCA8K_TRUNK_HASH_MASK, hash); -+} -+ -+static int -+qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, -+ struct net_device *lag, bool delete) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret, id, i; -+ u32 val; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ -+ /* Read current port member */ -+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); -+ if (ret) -+ return ret; -+ -+ /* Shift val to the correct trunk */ -+ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); -+ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; -+ if (delete) -+ val &= ~BIT(port); -+ else -+ val |= BIT(port); -+ -+ /* Update port member. With empty portmap disable trunk */ -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, -+ QCA8K_REG_GOL_TRUNK_MEMBER(id) | -+ QCA8K_REG_GOL_TRUNK_EN(id), -+ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | -+ val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); -+ -+ /* Search empty member if adding or port on deleting */ -+ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { -+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); -+ if (ret) -+ return ret; -+ -+ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); -+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; -+ -+ if (delete) { -+ /* If port flagged to be disabled assume this member is -+ * empty -+ */ -+ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -+ continue; -+ -+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; -+ if (val != port) -+ continue; -+ } else { -+ /* If port flagged to be enabled assume this member is -+ * already set -+ */ -+ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -+ continue; -+ } -+ -+ /* We have found the member to add/remove */ -+ break; -+ } -+ -+ /* Set port in the correct port mask or disable port if in delete mode */ -+ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), -+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | -+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), -+ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | -+ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); -+} -+ -+static int -+qca8k_port_lag_join(struct dsa_switch *ds, int port, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ int ret; -+ -+ if (!qca8k_lag_can_offload(ds, lag, info)) -+ return -EOPNOTSUPP; -+ -+ ret = qca8k_lag_setup_hash(ds, lag, info); -+ if (ret) -+ return ret; -+ -+ return qca8k_lag_refresh_portmap(ds, port, lag, false); -+} -+ -+static int -+qca8k_port_lag_leave(struct dsa_switch *ds, int port, -+ struct net_device *lag) -+{ -+ return qca8k_lag_refresh_portmap(ds, port, lag, true); -+} -+ -+static void -+qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, -+ bool operational) -+{ -+ struct dsa_port *dp = master->dsa_ptr; -+ struct qca8k_priv *priv = ds->priv; -+ -+ /* Ethernet MIB/MDIO is only supported for CPU port 0 */ -+ if (dp->index != 0) -+ return; -+ -+ mutex_lock(&priv->mgmt_eth_data.mutex); -+ mutex_lock(&priv->mib_eth_data.mutex); -+ -+ priv->mgmt_master = operational ? (struct net_device *)master : NULL; -+ -+ mutex_unlock(&priv->mib_eth_data.mutex); -+ mutex_unlock(&priv->mgmt_eth_data.mutex); -+} -+ -+static int qca8k_connect_tag_protocol(struct dsa_switch *ds, -+ enum dsa_tag_protocol proto) -+{ -+ struct qca_tagger_data *tagger_data; -+ -+ switch (proto) { -+ case DSA_TAG_PROTO_QCA: -+ tagger_data = ds->tagger_data; -+ -+ tagger_data->rw_reg_ack_handler = qca8k_rw_reg_ack_handler; -+ tagger_data->mib_autocast_handler = qca8k_mib_autocast_handler; -+ -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static const struct dsa_switch_ops qca8k_switch_ops = { -+ .get_tag_protocol = qca8k_get_tag_protocol, -+ .setup = qca8k_setup, -+ .get_strings = qca8k_get_strings, -+ .get_ethtool_stats = qca8k_get_ethtool_stats, -+ .get_sset_count = qca8k_get_sset_count, -+ .set_ageing_time = qca8k_set_ageing_time, -+ .get_mac_eee = qca8k_get_mac_eee, -+ .set_mac_eee = qca8k_set_mac_eee, -+ .port_enable = qca8k_port_enable, -+ .port_disable = qca8k_port_disable, -+ .port_change_mtu = qca8k_port_change_mtu, -+ .port_max_mtu = qca8k_port_max_mtu, -+ .port_stp_state_set = qca8k_port_stp_state_set, -+ .port_bridge_join = qca8k_port_bridge_join, -+ .port_bridge_leave = qca8k_port_bridge_leave, -+ .port_fast_age = qca8k_port_fast_age, -+ .port_fdb_add = qca8k_port_fdb_add, -+ .port_fdb_del = qca8k_port_fdb_del, -+ .port_fdb_dump = qca8k_port_fdb_dump, -+ .port_mdb_add = qca8k_port_mdb_add, -+ .port_mdb_del = qca8k_port_mdb_del, -+ .port_mirror_add = qca8k_port_mirror_add, -+ .port_mirror_del = qca8k_port_mirror_del, -+ .port_vlan_filtering = qca8k_port_vlan_filtering, -+ .port_vlan_add = qca8k_port_vlan_add, -+ .port_vlan_del = qca8k_port_vlan_del, -+ .phylink_validate = qca8k_phylink_validate, -+ .phylink_mac_link_state = qca8k_phylink_mac_link_state, -+ .phylink_mac_config = qca8k_phylink_mac_config, -+ .phylink_mac_link_down = qca8k_phylink_mac_link_down, -+ .phylink_mac_link_up = qca8k_phylink_mac_link_up, -+ .get_phy_flags = qca8k_get_phy_flags, -+ .port_lag_join = qca8k_port_lag_join, -+ .port_lag_leave = qca8k_port_lag_leave, -+ .master_state_change = qca8k_master_change, -+ .connect_tag_protocol = qca8k_connect_tag_protocol, -+}; -+ -+static int qca8k_read_switch_id(struct qca8k_priv *priv) -+{ -+ u32 val; -+ u8 id; -+ int ret; -+ -+ if (!priv->info) -+ return -ENODEV; -+ -+ ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); -+ if (ret < 0) -+ return -ENODEV; -+ -+ id = QCA8K_MASK_CTRL_DEVICE_ID(val); -+ if (id != priv->info->id) { -+ dev_err(priv->dev, -+ "Switch id detected %x but expected %x", -+ id, priv->info->id); -+ return -ENODEV; -+ } -+ -+ priv->switch_id = id; -+ -+ /* Save revision to communicate to the internal PHY driver */ -+ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); -+ -+ return 0; -+} -+ -+static int -+qca8k_sw_probe(struct mdio_device *mdiodev) -+{ -+ struct qca8k_priv *priv; -+ int ret; -+ -+ /* allocate the private data struct so that we can probe the switches -+ * ID register -+ */ -+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->info = of_device_get_match_data(priv->dev); -+ priv->bus = mdiodev->bus; -+ priv->dev = &mdiodev->dev; -+ -+ priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", -+ GPIOD_ASIS); -+ if (IS_ERR(priv->reset_gpio)) -+ return PTR_ERR(priv->reset_gpio); -+ -+ if (priv->reset_gpio) { -+ gpiod_set_value_cansleep(priv->reset_gpio, 1); -+ /* The active low duration must be greater than 10 ms -+ * and checkpatch.pl wants 20 ms. -+ */ -+ msleep(20); -+ gpiod_set_value_cansleep(priv->reset_gpio, 0); -+ } -+ -+ /* Start by setting up the register mapping */ -+ priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, priv, -+ &qca8k_regmap_config); -+ if (IS_ERR(priv->regmap)) { -+ dev_err(priv->dev, "regmap initialization failed"); -+ return PTR_ERR(priv->regmap); -+ } -+ -+ priv->mdio_cache.page = 0xffff; -+ priv->mdio_cache.lo = 0xffff; -+ priv->mdio_cache.hi = 0xffff; -+ -+ /* Check the detected switch id */ -+ ret = qca8k_read_switch_id(priv); -+ if (ret) -+ return ret; -+ -+ priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); -+ if (!priv->ds) -+ return -ENOMEM; -+ -+ mutex_init(&priv->mgmt_eth_data.mutex); -+ init_completion(&priv->mgmt_eth_data.rw_done); -+ -+ mutex_init(&priv->mib_eth_data.mutex); -+ init_completion(&priv->mib_eth_data.rw_done); -+ -+ priv->ds->dev = &mdiodev->dev; -+ priv->ds->num_ports = QCA8K_NUM_PORTS; -+ priv->ds->priv = priv; -+ priv->ds->ops = &qca8k_switch_ops; -+ mutex_init(&priv->reg_mutex); -+ dev_set_drvdata(&mdiodev->dev, priv); -+ -+ return dsa_register_switch(priv->ds); -+} -+ -+static void -+qca8k_sw_remove(struct mdio_device *mdiodev) -+{ -+ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); -+ int i; -+ -+ if (!priv) -+ return; -+ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) -+ qca8k_port_set_status(priv, i, 0); -+ -+ dsa_unregister_switch(priv->ds); -+ -+ dev_set_drvdata(&mdiodev->dev, NULL); -+} -+ -+static void qca8k_sw_shutdown(struct mdio_device *mdiodev) -+{ -+ struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); -+ -+ if (!priv) -+ return; -+ -+ dsa_switch_shutdown(priv->ds); -+ -+ dev_set_drvdata(&mdiodev->dev, NULL); -+} -+ -+#ifdef CONFIG_PM_SLEEP -+static void -+qca8k_set_pm(struct qca8k_priv *priv, int enable) -+{ -+ int port; -+ -+ for (port = 0; port < QCA8K_NUM_PORTS; port++) { -+ /* Do not enable on resume if the port was -+ * disabled before. -+ */ -+ if (!(priv->port_enabled_map & BIT(port))) -+ continue; -+ -+ qca8k_port_set_status(priv, port, enable); -+ } -+} -+ -+static int qca8k_suspend(struct device *dev) -+{ -+ struct qca8k_priv *priv = dev_get_drvdata(dev); -+ -+ qca8k_set_pm(priv, 0); -+ -+ return dsa_switch_suspend(priv->ds); -+} -+ -+static int qca8k_resume(struct device *dev) -+{ -+ struct qca8k_priv *priv = dev_get_drvdata(dev); -+ -+ qca8k_set_pm(priv, 1); -+ -+ return dsa_switch_resume(priv->ds); -+} -+#endif /* CONFIG_PM_SLEEP */ -+ -+static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, -+ qca8k_suspend, qca8k_resume); -+ -+static const struct qca8k_info_ops qca8xxx_ops = { -+ .autocast_mib = qca8k_get_ethtool_stats_eth, -+}; -+ -+static const struct qca8k_match_data qca8327 = { -+ .id = QCA8K_ID_QCA8327, -+ .reduced_package = true, -+ .mib_count = QCA8K_QCA832X_MIB_COUNT, -+ .ops = &qca8xxx_ops, -+}; -+ -+static const struct qca8k_match_data qca8328 = { -+ .id = QCA8K_ID_QCA8327, -+ .mib_count = QCA8K_QCA832X_MIB_COUNT, -+ .ops = &qca8xxx_ops, -+}; -+ -+static const struct qca8k_match_data qca833x = { -+ .id = QCA8K_ID_QCA8337, -+ .mib_count = QCA8K_QCA833X_MIB_COUNT, -+ .ops = &qca8xxx_ops, -+}; -+ -+static const struct of_device_id qca8k_of_match[] = { -+ { .compatible = "qca,qca8327", .data = &qca8327 }, -+ { .compatible = "qca,qca8328", .data = &qca8328 }, -+ { .compatible = "qca,qca8334", .data = &qca833x }, -+ { .compatible = "qca,qca8337", .data = &qca833x }, -+ { /* sentinel */ }, -+}; -+ -+static struct mdio_driver qca8kmdio_driver = { -+ .probe = qca8k_sw_probe, -+ .remove = qca8k_sw_remove, -+ .shutdown = qca8k_sw_shutdown, -+ .mdiodrv.driver = { -+ .name = "qca8k", -+ .of_match_table = qca8k_of_match, -+ .pm = &qca8k_pm_ops, -+ }, -+}; -+ -+mdio_module_driver(qca8kmdio_driver); -+ -+MODULE_AUTHOR("Mathieu Olivari, John Crispin "); -+MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:qca8k"); ---- /dev/null -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -0,0 +1,63 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2009 Felix Fietkau -+ * Copyright (C) 2011-2012 Gabor Juhos -+ * Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2016 John Crispin -+ */ -+ -+#include -+#include -+ -+#include "qca8k.h" -+ -+#define MIB_DESC(_s, _o, _n) \ -+ { \ -+ .size = (_s), \ -+ .offset = (_o), \ -+ .name = (_n), \ -+ } -+ -+const struct qca8k_mib_desc ar8327_mib[] = { -+ MIB_DESC(1, 0x00, "RxBroad"), -+ MIB_DESC(1, 0x04, "RxPause"), -+ MIB_DESC(1, 0x08, "RxMulti"), -+ MIB_DESC(1, 0x0c, "RxFcsErr"), -+ MIB_DESC(1, 0x10, "RxAlignErr"), -+ MIB_DESC(1, 0x14, "RxRunt"), -+ MIB_DESC(1, 0x18, "RxFragment"), -+ MIB_DESC(1, 0x1c, "Rx64Byte"), -+ MIB_DESC(1, 0x20, "Rx128Byte"), -+ MIB_DESC(1, 0x24, "Rx256Byte"), -+ MIB_DESC(1, 0x28, "Rx512Byte"), -+ MIB_DESC(1, 0x2c, "Rx1024Byte"), -+ MIB_DESC(1, 0x30, "Rx1518Byte"), -+ MIB_DESC(1, 0x34, "RxMaxByte"), -+ MIB_DESC(1, 0x38, "RxTooLong"), -+ MIB_DESC(2, 0x3c, "RxGoodByte"), -+ MIB_DESC(2, 0x44, "RxBadByte"), -+ MIB_DESC(1, 0x4c, "RxOverFlow"), -+ MIB_DESC(1, 0x50, "Filtered"), -+ MIB_DESC(1, 0x54, "TxBroad"), -+ MIB_DESC(1, 0x58, "TxPause"), -+ MIB_DESC(1, 0x5c, "TxMulti"), -+ MIB_DESC(1, 0x60, "TxUnderRun"), -+ MIB_DESC(1, 0x64, "Tx64Byte"), -+ MIB_DESC(1, 0x68, "Tx128Byte"), -+ MIB_DESC(1, 0x6c, "Tx256Byte"), -+ MIB_DESC(1, 0x70, "Tx512Byte"), -+ MIB_DESC(1, 0x74, "Tx1024Byte"), -+ MIB_DESC(1, 0x78, "Tx1518Byte"), -+ MIB_DESC(1, 0x7c, "TxMaxByte"), -+ MIB_DESC(1, 0x80, "TxOverSize"), -+ MIB_DESC(2, 0x84, "TxByte"), -+ MIB_DESC(1, 0x8c, "TxCollision"), -+ MIB_DESC(1, 0x90, "TxAbortCol"), -+ MIB_DESC(1, 0x94, "TxMultiCol"), -+ MIB_DESC(1, 0x98, "TxSingleCol"), -+ MIB_DESC(1, 0x9c, "TxExcDefer"), -+ MIB_DESC(1, 0xa0, "TxDefer"), -+ MIB_DESC(1, 0xa4, "TxLateCol"), -+ MIB_DESC(1, 0xa8, "RXUnicast"), -+ MIB_DESC(1, 0xac, "TXUnicast"), -+}; ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -414,4 +414,7 @@ struct qca8k_fdb { - u8 mac[6]; - }; - -+/* Common setup function */ -+extern const struct qca8k_mib_desc ar8327_mib[]; -+ - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch b/target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch deleted file mode 100644 index 012ab854742a41..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-04-net-dsa-qca8k-move-qca8k-read-write-rmw-and-reg-tabl.patch +++ /dev/null @@ -1,135 +0,0 @@ -From d5f901eab2e9dfed1095995dfc98f231f4fd2971 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:13 +0200 -Subject: [PATCH 04/14] net: dsa: qca8k: move qca8k read/write/rmw and reg - table to common code - -The same reg table and read/write/rmw function are used by drivers -based on qca8k family switch. -Move them to common code to make it accessible also by other drivers. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 42 ------------------------------ - drivers/net/dsa/qca/qca8k-common.c | 38 +++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 6 +++++ - 3 files changed, 44 insertions(+), 42 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -133,24 +133,6 @@ qca8k_set_page(struct qca8k_priv *priv, - return 0; - } - --static int --qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) --{ -- return regmap_read(priv->regmap, reg, val); --} -- --static int --qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) --{ -- return regmap_write(priv->regmap, reg, val); --} -- --static int --qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) --{ -- return regmap_update_bits(priv->regmap, reg, mask, write_val); --} -- - static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) - { - struct qca8k_mgmt_eth_data *mgmt_eth_data; -@@ -483,30 +465,6 @@ exit: - return ret; - } - --static const struct regmap_range qca8k_readable_ranges[] = { -- regmap_reg_range(0x0000, 0x00e4), /* Global control */ -- regmap_reg_range(0x0100, 0x0168), /* EEE control */ -- regmap_reg_range(0x0200, 0x0270), /* Parser control */ -- regmap_reg_range(0x0400, 0x0454), /* ACL */ -- regmap_reg_range(0x0600, 0x0718), /* Lookup */ -- regmap_reg_range(0x0800, 0x0b70), /* QM */ -- regmap_reg_range(0x0c00, 0x0c80), /* PKT */ -- regmap_reg_range(0x0e00, 0x0e98), /* L3 */ -- regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ -- regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ -- regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ -- regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ -- regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ -- regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ -- regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ -- --}; -- --static const struct regmap_access_table qca8k_readable_table = { -- .yes_ranges = qca8k_readable_ranges, -- .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), --}; -- - static struct regmap_config qca8k_regmap_config = { - .reg_bits = 16, - .val_bits = 32, ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -61,3 +61,41 @@ const struct qca8k_mib_desc ar8327_mib[] - MIB_DESC(1, 0xa8, "RXUnicast"), - MIB_DESC(1, 0xac, "TXUnicast"), - }; -+ -+int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val) -+{ -+ return regmap_read(priv->regmap, reg, val); -+} -+ -+int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) -+{ -+ return regmap_write(priv->regmap, reg, val); -+} -+ -+int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val) -+{ -+ return regmap_update_bits(priv->regmap, reg, mask, write_val); -+} -+ -+static const struct regmap_range qca8k_readable_ranges[] = { -+ regmap_reg_range(0x0000, 0x00e4), /* Global control */ -+ regmap_reg_range(0x0100, 0x0168), /* EEE control */ -+ regmap_reg_range(0x0200, 0x0270), /* Parser control */ -+ regmap_reg_range(0x0400, 0x0454), /* ACL */ -+ regmap_reg_range(0x0600, 0x0718), /* Lookup */ -+ regmap_reg_range(0x0800, 0x0b70), /* QM */ -+ regmap_reg_range(0x0c00, 0x0c80), /* PKT */ -+ regmap_reg_range(0x0e00, 0x0e98), /* L3 */ -+ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ -+ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ -+ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ -+ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ -+ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ -+ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ -+ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ -+}; -+ -+const struct regmap_access_table qca8k_readable_table = { -+ .yes_ranges = qca8k_readable_ranges, -+ .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), -+}; ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -416,5 +416,11 @@ struct qca8k_fdb { - - /* Common setup function */ - extern const struct qca8k_mib_desc ar8327_mib[]; -+extern const struct regmap_access_table qca8k_readable_table; -+ -+/* Common read/write/rmw function */ -+int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val); -+int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val); -+int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val); - - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch b/target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch deleted file mode 100644 index 0ed7ed41fbe6c4..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-05-net-dsa-qca8k-move-qca8k-bulk-read-write-helper-to-c.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 910746444313dc463396cd63024cdf54ef04ef39 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:14 +0200 -Subject: [PATCH 05/14] net: dsa: qca8k: move qca8k bulk read/write helper to - common code - -The same ATU function are used by drivers based on qca8k family switch. -Move the bulk read/write helper to common code to declare these shared -ATU functions in common code. -These helper will be dropped when regmap correctly support bulk -read/write. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 39 ++---------------------------- - drivers/net/dsa/qca/qca8k-common.c | 39 ++++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 8 ++++++ - 3 files changed, 49 insertions(+), 37 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -343,43 +343,6 @@ qca8k_regmap_update_bits_eth(struct qca8 - } - - static int --qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- int i, count = len / sizeof(u32), ret; -- -- if (priv->mgmt_master && !qca8k_read_eth(priv, reg, val, len)) -- return 0; -- -- for (i = 0; i < count; i++) { -- ret = regmap_read(priv->regmap, reg + (i * 4), val + i); -- if (ret < 0) -- return ret; -- } -- -- return 0; --} -- --static int --qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- int i, count = len / sizeof(u32), ret; -- u32 tmp; -- -- if (priv->mgmt_master && !qca8k_write_eth(priv, reg, val, len)) -- return 0; -- -- for (i = 0; i < count; i++) { -- tmp = val[i]; -- -- ret = regmap_write(priv->regmap, reg + (i * 4), tmp); -- if (ret < 0) -- return ret; -- } -- -- return 0; --} -- --static int - qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ctx; -@@ -3096,6 +3059,8 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, - - static const struct qca8k_info_ops qca8xxx_ops = { - .autocast_mib = qca8k_get_ethtool_stats_eth, -+ .read_eth = qca8k_read_eth, -+ .write_eth = qca8k_write_eth, - }; - - static const struct qca8k_match_data qca8327 = { ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -99,3 +99,42 @@ const struct regmap_access_table qca8k_r - .yes_ranges = qca8k_readable_ranges, - .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), - }; -+ -+/* TODO: remove these extra ops when we can support regmap bulk read/write */ -+int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ int i, count = len / sizeof(u32), ret; -+ -+ if (priv->mgmt_master && priv->info->ops->read_eth && -+ !priv->info->ops->read_eth(priv, reg, val, len)) -+ return 0; -+ -+ for (i = 0; i < count; i++) { -+ ret = regmap_read(priv->regmap, reg + (i * 4), val + i); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/* TODO: remove these extra ops when we can support regmap bulk read/write */ -+int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+{ -+ int i, count = len / sizeof(u32), ret; -+ u32 tmp; -+ -+ if (priv->mgmt_master && priv->info->ops->write_eth && -+ !priv->info->ops->write_eth(priv, reg, val, len)) -+ return 0; -+ -+ for (i = 0; i < count; i++) { -+ tmp = val[i]; -+ -+ ret = regmap_write(priv->regmap, reg + (i * 4), tmp); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -324,8 +324,13 @@ enum qca8k_mid_cmd { - QCA8K_MIB_CAST = 3, - }; - -+struct qca8k_priv; -+ - struct qca8k_info_ops { - int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data); -+ /* TODO: remove these extra ops when we can support regmap bulk read/write */ -+ int (*read_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len); -+ int (*write_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len); - }; - - struct qca8k_match_data { -@@ -423,4 +428,7 @@ int qca8k_read(struct qca8k_priv *priv, - int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val); - int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val); - -+int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len); -+int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len); -+ - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch deleted file mode 100644 index a39a55b89b4b6b..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-06-net-dsa-qca8k-move-mib-init-function-to-common-code.patch +++ /dev/null @@ -1,137 +0,0 @@ -From fce1ec0c4e2d03d9c62ffc615a42bdba78eb4c14 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:15 +0200 -Subject: [PATCH 06/14] net: dsa: qca8k: move mib init function to common code - -The same mib function is used by drivers based on qca8k family switch. -Move it to common code to make it accessible also by other drivers. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 37 ------------------------------ - drivers/net/dsa/qca/qca8k-common.c | 35 ++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 4 ++++ - 3 files changed, 39 insertions(+), 37 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -442,15 +442,6 @@ static struct regmap_config qca8k_regmap - }; - - static int --qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) --{ -- u32 val; -- -- return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, -- QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); --} -- --static int - qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) - { - u32 reg[3]; -@@ -777,34 +768,6 @@ out: - return ret; - } - --static int --qca8k_mib_init(struct qca8k_priv *priv) --{ -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -- QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -- FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | -- QCA8K_MIB_BUSY); -- if (ret) -- goto exit; -- -- ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); -- if (ret) -- goto exit; -- -- ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); -- if (ret) -- goto exit; -- -- ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- - static void - qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) - { ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -7,6 +7,7 @@ - */ - - #include -+#include - #include - - #include "qca8k.h" -@@ -138,3 +139,38 @@ int qca8k_bulk_write(struct qca8k_priv * - - return 0; - } -+ -+int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) -+{ -+ u32 val; -+ -+ return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0, -+ QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); -+} -+ -+int qca8k_mib_init(struct qca8k_priv *priv) -+{ -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB, -+ QCA8K_MIB_FUNC | QCA8K_MIB_BUSY, -+ FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) | -+ QCA8K_MIB_BUSY); -+ if (ret) -+ goto exit; -+ -+ ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); -+ if (ret) -+ goto exit; -+ -+ ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); -+ if (ret) -+ goto exit; -+ -+ ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -422,6 +422,7 @@ struct qca8k_fdb { - /* Common setup function */ - extern const struct qca8k_mib_desc ar8327_mib[]; - extern const struct regmap_access_table qca8k_readable_table; -+int qca8k_mib_init(struct qca8k_priv *priv); - - /* Common read/write/rmw function */ - int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val); -@@ -431,4 +432,7 @@ int qca8k_rmw(struct qca8k_priv *priv, u - int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len); - int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len); - -+/* Common ops function */ -+int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask); -+ - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch b/target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch deleted file mode 100644 index 6fd1c66b0ae169..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-07-net-dsa-qca8k-move-port-set-status-eee-ethtool-stats.patch +++ /dev/null @@ -1,281 +0,0 @@ -From 472fcea160f27a5d9b7526093d9d8d89ba0b6137 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:16 +0200 -Subject: [PATCH 07/14] net: dsa: qca8k: move port set status/eee/ethtool stats - function to common code - -The same logic to disable/enable port, set eee and get ethtool stats is -used by drivers based on qca8k family switch. -Move it to common code to make it accessible also by other drivers. -While at it also drop unnecessary qca8k_priv cast for void pointers. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 105 ----------------------------- - drivers/net/dsa/qca/qca8k-common.c | 102 ++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 11 +++ - 3 files changed, 113 insertions(+), 105 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -768,21 +768,6 @@ out: - return ret; - } - --static void --qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) --{ -- u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; -- -- /* Port 0 and 6 have no internal PHY */ -- if (port > 0 && port < 6) -- mask |= QCA8K_PORT_STATUS_LINK_AUTO; -- -- if (enable) -- regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); -- else -- regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); --} -- - static int - qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, - struct sk_buff *read_skb, u32 *val) -@@ -1974,20 +1959,6 @@ qca8k_phylink_mac_link_up(struct dsa_swi - qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg); - } - --static void --qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data) --{ -- struct qca8k_priv *priv = ds->priv; -- int i; -- -- if (stringset != ETH_SS_STATS) -- return; -- -- for (i = 0; i < priv->info->mib_count; i++) -- strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, -- ETH_GSTRING_LEN); --} -- - static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *skb) - { - struct qca8k_mib_eth_data *mib_eth_data; -@@ -2078,82 +2049,6 @@ exit: - } - - static void --qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, -- uint64_t *data) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- const struct qca8k_mib_desc *mib; -- u32 reg, i, val; -- u32 hi = 0; -- int ret; -- -- if (priv->mgmt_master && priv->info->ops->autocast_mib && -- priv->info->ops->autocast_mib(ds, port, data) > 0) -- return; -- -- for (i = 0; i < priv->info->mib_count; i++) { -- mib = &ar8327_mib[i]; -- reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; -- -- ret = qca8k_read(priv, reg, &val); -- if (ret < 0) -- continue; -- -- if (mib->size == 2) { -- ret = qca8k_read(priv, reg + 4, &hi); -- if (ret < 0) -- continue; -- } -- -- data[i] = val; -- if (mib->size == 2) -- data[i] |= (u64)hi << 32; -- } --} -- --static int --qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) --{ -- struct qca8k_priv *priv = ds->priv; -- -- if (sset != ETH_SS_STATS) -- return 0; -- -- return priv->info->mib_count; --} -- --static int --qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); -- u32 reg; -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); -- if (ret < 0) -- goto exit; -- -- if (eee->eee_enabled) -- reg |= lpi_en; -- else -- reg &= ~lpi_en; -- ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static int --qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) --{ -- /* Nothing to do on the port's MAC */ -- return 0; --} -- --static void - qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -174,3 +174,105 @@ exit: - mutex_unlock(&priv->reg_mutex); - return ret; - } -+ -+void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) -+{ -+ u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC; -+ -+ /* Port 0 and 6 have no internal PHY */ -+ if (port > 0 && port < 6) -+ mask |= QCA8K_PORT_STATUS_LINK_AUTO; -+ -+ if (enable) -+ regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); -+ else -+ regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask); -+} -+ -+void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, -+ uint8_t *data) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int i; -+ -+ if (stringset != ETH_SS_STATS) -+ return; -+ -+ for (i = 0; i < priv->info->mib_count; i++) -+ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, -+ ETH_GSTRING_LEN); -+} -+ -+void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, -+ uint64_t *data) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ const struct qca8k_mib_desc *mib; -+ u32 reg, i, val; -+ u32 hi = 0; -+ int ret; -+ -+ if (priv->mgmt_master && priv->info->ops->autocast_mib && -+ priv->info->ops->autocast_mib(ds, port, data) > 0) -+ return; -+ -+ for (i = 0; i < priv->info->mib_count; i++) { -+ mib = &ar8327_mib[i]; -+ reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; -+ -+ ret = qca8k_read(priv, reg, &val); -+ if (ret < 0) -+ continue; -+ -+ if (mib->size == 2) { -+ ret = qca8k_read(priv, reg + 4, &hi); -+ if (ret < 0) -+ continue; -+ } -+ -+ data[i] = val; -+ if (mib->size == 2) -+ data[i] |= (u64)hi << 32; -+ } -+} -+ -+int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ if (sset != ETH_SS_STATS) -+ return 0; -+ -+ return priv->info->mib_count; -+} -+ -+int qca8k_set_mac_eee(struct dsa_switch *ds, int port, -+ struct ethtool_eee *eee) -+{ -+ u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); -+ struct qca8k_priv *priv = ds->priv; -+ u32 reg; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®); -+ if (ret < 0) -+ goto exit; -+ -+ if (eee->eee_enabled) -+ reg |= lpi_en; -+ else -+ reg &= ~lpi_en; -+ ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+int qca8k_get_mac_eee(struct dsa_switch *ds, int port, -+ struct ethtool_eee *e) -+{ -+ /* Nothing to do on the port's MAC */ -+ return 0; -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -423,6 +423,7 @@ struct qca8k_fdb { - extern const struct qca8k_mib_desc ar8327_mib[]; - extern const struct regmap_access_table qca8k_readable_table; - int qca8k_mib_init(struct qca8k_priv *priv); -+void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable); - - /* Common read/write/rmw function */ - int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val); -@@ -435,4 +436,14 @@ int qca8k_bulk_write(struct qca8k_priv * - /* Common ops function */ - int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask); - -+/* Common ethtool stats function */ -+void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data); -+void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, -+ uint64_t *data); -+int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset); -+ -+/* Common eee function */ -+int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee); -+int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); -+ - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch deleted file mode 100644 index 3ca682d72ccc99..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-08-net-dsa-qca8k-move-bridge-functions-to-common-code.patch +++ /dev/null @@ -1,237 +0,0 @@ -From fd3cae2f3ac190d06e48f43739237e02f9dc51ff Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:17 +0200 -Subject: [PATCH 08/14] net: dsa: qca8k: move bridge functions to common code - -The same bridge functions are used by drivers based on qca8k family -switch. Move them to common code to make them accessible also by other -drivers. -While at it also drop unnecessary qca8k_priv cast for void pointers. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 93 ------------------------------ - drivers/net/dsa/qca/qca8k-common.c | 93 ++++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 9 +++ - 3 files changed, 102 insertions(+), 93 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -2049,97 +2049,6 @@ exit: - } - - static void --qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u32 stp_state; -- -- switch (state) { -- case BR_STATE_DISABLED: -- stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; -- break; -- case BR_STATE_BLOCKING: -- stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; -- break; -- case BR_STATE_LISTENING: -- stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; -- break; -- case BR_STATE_LEARNING: -- stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; -- break; -- case BR_STATE_FORWARDING: -- default: -- stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; -- break; -- } -- -- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); --} -- --static int --qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int port_mask, cpu_port; -- int i, ret; -- -- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -- port_mask = BIT(cpu_port); -- -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- if (dsa_is_cpu_port(ds, i)) -- continue; -- if (dsa_to_port(ds, i)->bridge_dev != br) -- continue; -- /* Add this port to the portvlan mask of the other ports -- * in the bridge -- */ -- ret = regmap_set_bits(priv->regmap, -- QCA8K_PORT_LOOKUP_CTRL(i), -- BIT(port)); -- if (ret) -- return ret; -- if (i != port) -- port_mask |= BIT(i); -- } -- -- /* Add all other ports to this ports portvlan mask */ -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_MEMBER, port_mask); -- -- return ret; --} -- --static void --qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int cpu_port, i; -- -- cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -- -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- if (dsa_is_cpu_port(ds, i)) -- continue; -- if (dsa_to_port(ds, i)->bridge_dev != br) -- continue; -- /* Remove this port to the portvlan mask of the other ports -- * in the bridge -- */ -- regmap_clear_bits(priv->regmap, -- QCA8K_PORT_LOOKUP_CTRL(i), -- BIT(port)); -- } -- -- /* Set the cpu port to be the only one in the portvlan mask of -- * this port -- */ -- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); --} -- --static void - qca8k_port_fast_age(struct dsa_switch *ds, int port) - { - struct qca8k_priv *priv = ds->priv; ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - - #include "qca8k.h" - -@@ -276,3 +277,93 @@ int qca8k_get_mac_eee(struct dsa_switch - /* Nothing to do on the port's MAC */ - return 0; - } -+ -+void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ u32 stp_state; -+ -+ switch (state) { -+ case BR_STATE_DISABLED: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; -+ break; -+ case BR_STATE_BLOCKING: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; -+ break; -+ case BR_STATE_LISTENING: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; -+ break; -+ case BR_STATE_LEARNING: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; -+ break; -+ case BR_STATE_FORWARDING: -+ default: -+ stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; -+ break; -+ } -+ -+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); -+} -+ -+int qca8k_port_bridge_join(struct dsa_switch *ds, int port, -+ struct net_device *br) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int port_mask, cpu_port; -+ int i, ret; -+ -+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -+ port_mask = BIT(cpu_port); -+ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ if (dsa_is_cpu_port(ds, i)) -+ continue; -+ if (dsa_to_port(ds, i)->bridge_dev != br) -+ continue; -+ /* Add this port to the portvlan mask of the other ports -+ * in the bridge -+ */ -+ ret = regmap_set_bits(priv->regmap, -+ QCA8K_PORT_LOOKUP_CTRL(i), -+ BIT(port)); -+ if (ret) -+ return ret; -+ if (i != port) -+ port_mask |= BIT(i); -+ } -+ -+ /* Add all other ports to this ports portvlan mask */ -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_MEMBER, port_mask); -+ -+ return ret; -+} -+ -+void qca8k_port_bridge_leave(struct dsa_switch *ds, int port, -+ struct net_device *br) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int cpu_port, i; -+ -+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index; -+ -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ if (dsa_is_cpu_port(ds, i)) -+ continue; -+ if (dsa_to_port(ds, i)->bridge_dev != br) -+ continue; -+ /* Remove this port to the portvlan mask of the other ports -+ * in the bridge -+ */ -+ regmap_clear_bits(priv->regmap, -+ QCA8K_PORT_LOOKUP_CTRL(i), -+ BIT(port)); -+ } -+ -+ /* Set the cpu port to be the only one in the portvlan mask of -+ * this port -+ */ -+ qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -446,4 +446,11 @@ int qca8k_get_sset_count(struct dsa_swit - int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee); - int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); - -+/* Common bridge function */ -+void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state); -+int qca8k_port_bridge_join(struct dsa_switch *ds, int port, -+ struct net_device *br); -+void qca8k_port_bridge_leave(struct dsa_switch *ds, int port, -+ struct net_device *br); -+ - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch b/target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch deleted file mode 100644 index e3414408d64872..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-09-net-dsa-qca8k-move-set-age-MTU-port-enable-disable-f.patch +++ /dev/null @@ -1,227 +0,0 @@ -From b3a302b171f73425b41de8d3357fae3fa7057322 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:18 +0200 -Subject: [PATCH 09/14] net: dsa: qca8k: move set age/MTU/port enable/disable - functions to common code - -The same set age, MTU and port enable/disable function are used by -driver based on qca8k family switch. -Move them to common code to make them accessible also by other drivers. -While at it also drop unnecessary qca8k_priv cast for void pointers. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 88 ------------------------------ - drivers/net/dsa/qca/qca8k-common.c | 85 +++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 12 ++++ - 3 files changed, 97 insertions(+), 88 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -2059,94 +2059,6 @@ qca8k_port_fast_age(struct dsa_switch *d - } - - static int --qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) --{ -- struct qca8k_priv *priv = ds->priv; -- unsigned int secs = msecs / 1000; -- u32 val; -- -- /* AGE_TIME reg is set in 7s step */ -- val = secs / 7; -- -- /* Handle case with 0 as val to NOT disable -- * learning -- */ -- if (!val) -- val = 1; -- -- return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, QCA8K_ATU_AGE_TIME_MASK, -- QCA8K_ATU_AGE_TIME(val)); --} -- --static int --qca8k_port_enable(struct dsa_switch *ds, int port, -- struct phy_device *phy) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- -- qca8k_port_set_status(priv, port, 1); -- priv->port_enabled_map |= BIT(port); -- -- if (dsa_is_user_port(ds, port)) -- phy_support_asym_pause(phy); -- -- return 0; --} -- --static void --qca8k_port_disable(struct dsa_switch *ds, int port) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- -- qca8k_port_set_status(priv, port, 0); -- priv->port_enabled_map &= ~BIT(port); --} -- --static int --qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- /* We have only have a general MTU setting. -- * DSA always set the CPU port's MTU to the largest MTU of the slave -- * ports. -- * Setting MTU just for the CPU port is sufficient to correctly set a -- * value for every port. -- */ -- if (!dsa_is_cpu_port(ds, port)) -- return 0; -- -- /* To change the MAX_FRAME_SIZE the cpu ports must be off or -- * the switch panics. -- * Turn off both cpu ports before applying the new value to prevent -- * this. -- */ -- if (priv->port_enabled_map & BIT(0)) -- qca8k_port_set_status(priv, 0, 0); -- -- if (priv->port_enabled_map & BIT(6)) -- qca8k_port_set_status(priv, 6, 0); -- -- /* Include L2 header / FCS length */ -- ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + ETH_HLEN + ETH_FCS_LEN); -- -- if (priv->port_enabled_map & BIT(0)) -- qca8k_port_set_status(priv, 0, 1); -- -- if (priv->port_enabled_map & BIT(6)) -- qca8k_port_set_status(priv, 6, 1); -- -- return ret; --} -- --static int --qca8k_port_max_mtu(struct dsa_switch *ds, int port) --{ -- return QCA8K_MAX_MTU; --} -- --static int - qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, - u16 port_mask, u16 vid) - { ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -367,3 +367,88 @@ void qca8k_port_bridge_leave(struct dsa_ - qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); - } -+ -+int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ unsigned int secs = msecs / 1000; -+ u32 val; -+ -+ /* AGE_TIME reg is set in 7s step */ -+ val = secs / 7; -+ -+ /* Handle case with 0 as val to NOT disable -+ * learning -+ */ -+ if (!val) -+ val = 1; -+ -+ return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL, -+ QCA8K_ATU_AGE_TIME_MASK, -+ QCA8K_ATU_AGE_TIME(val)); -+} -+ -+int qca8k_port_enable(struct dsa_switch *ds, int port, -+ struct phy_device *phy) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ qca8k_port_set_status(priv, port, 1); -+ priv->port_enabled_map |= BIT(port); -+ -+ if (dsa_is_user_port(ds, port)) -+ phy_support_asym_pause(phy); -+ -+ return 0; -+} -+ -+void qca8k_port_disable(struct dsa_switch *ds, int port) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ qca8k_port_set_status(priv, port, 0); -+ priv->port_enabled_map &= ~BIT(port); -+} -+ -+int qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ /* We have only have a general MTU setting. -+ * DSA always set the CPU port's MTU to the largest MTU of the slave -+ * ports. -+ * Setting MTU just for the CPU port is sufficient to correctly set a -+ * value for every port. -+ */ -+ if (!dsa_is_cpu_port(ds, port)) -+ return 0; -+ -+ /* To change the MAX_FRAME_SIZE the cpu ports must be off or -+ * the switch panics. -+ * Turn off both cpu ports before applying the new value to prevent -+ * this. -+ */ -+ if (priv->port_enabled_map & BIT(0)) -+ qca8k_port_set_status(priv, 0, 0); -+ -+ if (priv->port_enabled_map & BIT(6)) -+ qca8k_port_set_status(priv, 6, 0); -+ -+ /* Include L2 header / FCS length */ -+ ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu + -+ ETH_HLEN + ETH_FCS_LEN); -+ -+ if (priv->port_enabled_map & BIT(0)) -+ qca8k_port_set_status(priv, 0, 1); -+ -+ if (priv->port_enabled_map & BIT(6)) -+ qca8k_port_set_status(priv, 6, 1); -+ -+ return ret; -+} -+ -+int qca8k_port_max_mtu(struct dsa_switch *ds, int port) -+{ -+ return QCA8K_MAX_MTU; -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -453,4 +453,16 @@ int qca8k_port_bridge_join(struct dsa_sw - void qca8k_port_bridge_leave(struct dsa_switch *ds, int port, - struct net_device *br); - -+/* Common port enable/disable function */ -+int qca8k_port_enable(struct dsa_switch *ds, int port, -+ struct phy_device *phy); -+void qca8k_port_disable(struct dsa_switch *ds, int port); -+ -+/* Common MTU function */ -+int qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu); -+int qca8k_port_max_mtu(struct dsa_switch *ds, int port); -+ -+/* Common fast age function */ -+int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs); -+ - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch b/target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch deleted file mode 100644 index 96468ae74e9a9d..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-10-net-dsa-qca8k-move-port-FDB-MDB-function-to-common-c.patch +++ /dev/null @@ -1,704 +0,0 @@ -From 2e5bd96eea86a246b4de3bf756f7a11b43e6187d Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:19 +0200 -Subject: [PATCH 10/14] net: dsa: qca8k: move port FDB/MDB function to common - code - -The same port FDB/MDB function are used by drivers based on qca8k family -switch. Move them to common code to make them accessible also by other -drivers. -Also drop bulk read/write functions and make them static - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 306 ----------------------------- - drivers/net/dsa/qca/qca8k-common.c | 297 +++++++++++++++++++++++++++- - drivers/net/dsa/qca/qca8k.h | 25 ++- - 3 files changed, 317 insertions(+), 311 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -442,217 +442,6 @@ static struct regmap_config qca8k_regmap - }; - - static int --qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) --{ -- u32 reg[3]; -- int ret; -- -- /* load the ARL table into an array */ -- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -- if (ret) -- return ret; -- -- /* vid - 83:72 */ -- fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); -- /* aging - 67:64 */ -- fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); -- /* portmask - 54:48 */ -- fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); -- /* mac - 47:0 */ -- fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); -- fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); -- fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); -- fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); -- fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); -- fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); -- -- return 0; --} -- --static void --qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, -- u8 aging) --{ -- u32 reg[3] = { 0 }; -- -- /* vid - 83:72 */ -- reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); -- /* aging - 67:64 */ -- reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); -- /* portmask - 54:48 */ -- reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); -- /* mac - 47:0 */ -- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); -- reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); -- reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); -- -- /* load the array into the ARL table */ -- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); --} -- --static int --qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) --{ -- u32 reg; -- int ret; -- -- /* Set the command and FDB index */ -- reg = QCA8K_ATU_FUNC_BUSY; -- reg |= cmd; -- if (port >= 0) { -- reg |= QCA8K_ATU_FUNC_PORT_EN; -- reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); -- } -- -- /* Write the function register triggering the table access */ -- ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); -- if (ret) -- return ret; -- -- /* wait for completion */ -- ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); -- if (ret) -- return ret; -- -- /* Check for table full violation when adding an entry */ -- if (cmd == QCA8K_FDB_LOAD) { -- ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); -- if (ret < 0) -- return ret; -- if (reg & QCA8K_ATU_FUNC_FULL) -- return -1; -- } -- -- return 0; --} -- --static int --qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) --{ -- int ret; -- -- qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); -- if (ret < 0) -- return ret; -- -- return qca8k_fdb_read(priv, fdb); --} -- --static int --qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, -- u16 vid, u8 aging) --{ -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_write(priv, vid, port_mask, mac, aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static int --qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) --{ -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_write(priv, vid, port_mask, mac, 0); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static void --qca8k_fdb_flush(struct qca8k_priv *priv) --{ -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); -- mutex_unlock(&priv->reg_mutex); --} -- --static int --qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, -- const u8 *mac, u16 vid) --{ -- struct qca8k_fdb fdb = { 0 }; -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- -- qca8k_fdb_write(priv, vid, 0, mac, 0); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -- if (ret < 0) -- goto exit; -- -- ret = qca8k_fdb_read(priv, &fdb); -- if (ret < 0) -- goto exit; -- -- /* Rule exist. Delete first */ -- if (!fdb.aging) { -- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -- if (ret) -- goto exit; -- } -- -- /* Add port to fdb portmask */ -- fdb.port_mask |= port_mask; -- -- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static int --qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, -- const u8 *mac, u16 vid) --{ -- struct qca8k_fdb fdb = { 0 }; -- int ret; -- -- mutex_lock(&priv->reg_mutex); -- -- qca8k_fdb_write(priv, vid, 0, mac, 0); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -- if (ret < 0) -- goto exit; -- -- /* Rule doesn't exist. Why delete? */ -- if (!fdb.aging) { -- ret = -EINVAL; -- goto exit; -- } -- -- ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -- if (ret) -- goto exit; -- -- /* Only port in the rule is this port. Don't re insert */ -- if (fdb.port_mask == port_mask) -- goto exit; -- -- /* Remove port from port mask */ -- fdb.port_mask &= ~port_mask; -- -- qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -- ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -- --exit: -- mutex_unlock(&priv->reg_mutex); -- return ret; --} -- --static int - qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) - { - u32 reg; -@@ -2048,97 +1837,6 @@ exit: - return ret; - } - --static void --qca8k_port_fast_age(struct dsa_switch *ds, int port) --{ -- struct qca8k_priv *priv = ds->priv; -- -- mutex_lock(&priv->reg_mutex); -- qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); -- mutex_unlock(&priv->reg_mutex); --} -- --static int --qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, -- u16 port_mask, u16 vid) --{ -- /* Set the vid to the port vlan id if no vid is set */ -- if (!vid) -- vid = QCA8K_PORT_VID_DEF; -- -- return qca8k_fdb_add(priv, addr, port_mask, vid, -- QCA8K_ATU_STATUS_STATIC); --} -- --static int --qca8k_port_fdb_add(struct dsa_switch *ds, int port, -- const unsigned char *addr, u16 vid) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u16 port_mask = BIT(port); -- -- return qca8k_port_fdb_insert(priv, addr, port_mask, vid); --} -- --static int --qca8k_port_fdb_del(struct dsa_switch *ds, int port, -- const unsigned char *addr, u16 vid) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- u16 port_mask = BIT(port); -- -- if (!vid) -- vid = QCA8K_PORT_VID_DEF; -- -- return qca8k_fdb_del(priv, addr, port_mask, vid); --} -- --static int --qca8k_port_fdb_dump(struct dsa_switch *ds, int port, -- dsa_fdb_dump_cb_t *cb, void *data) --{ -- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- struct qca8k_fdb _fdb = { 0 }; -- int cnt = QCA8K_NUM_FDB_RECORDS; -- bool is_static; -- int ret = 0; -- -- mutex_lock(&priv->reg_mutex); -- while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { -- if (!_fdb.aging) -- break; -- is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); -- ret = cb(_fdb.mac, _fdb.vid, is_static, data); -- if (ret) -- break; -- } -- mutex_unlock(&priv->reg_mutex); -- -- return 0; --} -- --static int --qca8k_port_mdb_add(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_mdb *mdb) --{ -- struct qca8k_priv *priv = ds->priv; -- const u8 *addr = mdb->addr; -- u16 vid = mdb->vid; -- -- return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); --} -- --static int --qca8k_port_mdb_del(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_mdb *mdb) --{ -- struct qca8k_priv *priv = ds->priv; -- const u8 *addr = mdb->addr; -- u16 vid = mdb->vid; -- -- return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); --} -- - static int - qca8k_port_mirror_add(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror, ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -103,7 +103,7 @@ const struct regmap_access_table qca8k_r - }; - - /* TODO: remove these extra ops when we can support regmap bulk read/write */ --int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+static int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) - { - int i, count = len / sizeof(u32), ret; - -@@ -121,7 +121,7 @@ int qca8k_bulk_read(struct qca8k_priv *p - } - - /* TODO: remove these extra ops when we can support regmap bulk read/write */ --int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) -+static int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) - { - int i, count = len / sizeof(u32), ret; - u32 tmp; -@@ -149,6 +149,211 @@ int qca8k_busy_wait(struct qca8k_priv *p - QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC); - } - -+static int qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) -+{ -+ u32 reg[3]; -+ int ret; -+ -+ /* load the ARL table into an array */ -+ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -+ if (ret) -+ return ret; -+ -+ /* vid - 83:72 */ -+ fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]); -+ /* aging - 67:64 */ -+ fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]); -+ /* portmask - 54:48 */ -+ fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]); -+ /* mac - 47:0 */ -+ fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]); -+ fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]); -+ fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]); -+ fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]); -+ fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]); -+ fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]); -+ -+ return 0; -+} -+ -+static void qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, -+ const u8 *mac, u8 aging) -+{ -+ u32 reg[3] = { 0 }; -+ -+ /* vid - 83:72 */ -+ reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); -+ /* aging - 67:64 */ -+ reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging); -+ /* portmask - 54:48 */ -+ reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask); -+ /* mac - 47:0 */ -+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]); -+ reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]); -+ reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); -+ -+ /* load the array into the ARL table */ -+ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -+} -+ -+static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, -+ int port) -+{ -+ u32 reg; -+ int ret; -+ -+ /* Set the command and FDB index */ -+ reg = QCA8K_ATU_FUNC_BUSY; -+ reg |= cmd; -+ if (port >= 0) { -+ reg |= QCA8K_ATU_FUNC_PORT_EN; -+ reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port); -+ } -+ -+ /* Write the function register triggering the table access */ -+ ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); -+ if (ret) -+ return ret; -+ -+ /* wait for completion */ -+ ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY); -+ if (ret) -+ return ret; -+ -+ /* Check for table full violation when adding an entry */ -+ if (cmd == QCA8K_FDB_LOAD) { -+ ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®); -+ if (ret < 0) -+ return ret; -+ if (reg & QCA8K_ATU_FUNC_FULL) -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, -+ int port) -+{ -+ int ret; -+ -+ qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); -+ if (ret < 0) -+ return ret; -+ -+ return qca8k_fdb_read(priv, fdb); -+} -+ -+static int qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, -+ u16 port_mask, u16 vid, u8 aging) -+{ -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_write(priv, vid, port_mask, mac, aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, -+ u16 port_mask, u16 vid) -+{ -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_write(priv, vid, port_mask, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+void qca8k_fdb_flush(struct qca8k_priv *priv) -+{ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); -+ mutex_unlock(&priv->reg_mutex); -+} -+ -+static int qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, -+ const u8 *mac, u16 vid) -+{ -+ struct qca8k_fdb fdb = { 0 }; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ qca8k_fdb_write(priv, vid, 0, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -+ if (ret < 0) -+ goto exit; -+ -+ ret = qca8k_fdb_read(priv, &fdb); -+ if (ret < 0) -+ goto exit; -+ -+ /* Rule exist. Delete first */ -+ if (!fdb.aging) { -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ if (ret) -+ goto exit; -+ } -+ -+ /* Add port to fdb portmask */ -+ fdb.port_mask |= port_mask; -+ -+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ -+static int qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, -+ const u8 *mac, u16 vid) -+{ -+ struct qca8k_fdb fdb = { 0 }; -+ int ret; -+ -+ mutex_lock(&priv->reg_mutex); -+ -+ qca8k_fdb_write(priv, vid, 0, mac, 0); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1); -+ if (ret < 0) -+ goto exit; -+ -+ /* Rule doesn't exist. Why delete? */ -+ if (!fdb.aging) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); -+ if (ret) -+ goto exit; -+ -+ /* Only port in the rule is this port. Don't re insert */ -+ if (fdb.port_mask == port_mask) -+ goto exit; -+ -+ /* Remove port from port mask */ -+ fdb.port_mask &= ~port_mask; -+ -+ qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging); -+ ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); -+ -+exit: -+ mutex_unlock(&priv->reg_mutex); -+ return ret; -+} -+ - int qca8k_mib_init(struct qca8k_priv *priv) - { - int ret; -@@ -368,6 +573,15 @@ void qca8k_port_bridge_leave(struct dsa_ - QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port)); - } - -+void qca8k_port_fast_age(struct dsa_switch *ds, int port) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ mutex_lock(&priv->reg_mutex); -+ qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port); -+ mutex_unlock(&priv->reg_mutex); -+} -+ - int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) - { - struct qca8k_priv *priv = ds->priv; -@@ -452,3 +666,78 @@ int qca8k_port_max_mtu(struct dsa_switch - { - return QCA8K_MAX_MTU; - } -+ -+int qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, -+ u16 port_mask, u16 vid) -+{ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = QCA8K_PORT_VID_DEF; -+ -+ return qca8k_fdb_add(priv, addr, port_mask, vid, -+ QCA8K_ATU_STATUS_STATIC); -+} -+ -+int qca8k_port_fdb_add(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ u16 port_mask = BIT(port); -+ -+ return qca8k_port_fdb_insert(priv, addr, port_mask, vid); -+} -+ -+int qca8k_port_fdb_del(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ u16 port_mask = BIT(port); -+ -+ if (!vid) -+ vid = QCA8K_PORT_VID_DEF; -+ -+ return qca8k_fdb_del(priv, addr, port_mask, vid); -+} -+ -+int qca8k_port_fdb_dump(struct dsa_switch *ds, int port, -+ dsa_fdb_dump_cb_t *cb, void *data) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ struct qca8k_fdb _fdb = { 0 }; -+ int cnt = QCA8K_NUM_FDB_RECORDS; -+ bool is_static; -+ int ret = 0; -+ -+ mutex_lock(&priv->reg_mutex); -+ while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { -+ if (!_fdb.aging) -+ break; -+ is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); -+ ret = cb(_fdb.mac, _fdb.vid, is_static, data); -+ if (ret) -+ break; -+ } -+ mutex_unlock(&priv->reg_mutex); -+ -+ return 0; -+} -+ -+int qca8k_port_mdb_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ const u8 *addr = mdb->addr; -+ u16 vid = mdb->vid; -+ -+ return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); -+} -+ -+int qca8k_port_mdb_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ const u8 *addr = mdb->addr; -+ u16 vid = mdb->vid; -+ -+ return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -430,11 +430,9 @@ int qca8k_read(struct qca8k_priv *priv, - int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val); - int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val); - --int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len); --int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len); -- - /* Common ops function */ - int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask); -+void qca8k_fdb_flush(struct qca8k_priv *priv); - - /* Common ethtool stats function */ - void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t *data); -@@ -463,6 +461,23 @@ int qca8k_port_change_mtu(struct dsa_swi - int qca8k_port_max_mtu(struct dsa_switch *ds, int port); - - /* Common fast age function */ -+void qca8k_port_fast_age(struct dsa_switch *ds, int port); - int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs); - -+/* Common FDB function */ -+int qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, -+ u16 port_mask, u16 vid); -+int qca8k_port_fdb_add(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid); -+int qca8k_port_fdb_del(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid); -+int qca8k_port_fdb_dump(struct dsa_switch *ds, int port, -+ dsa_fdb_dump_cb_t *cb, void *data); -+ -+/* Common MDB function */ -+int qca8k_port_mdb_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb); -+int qca8k_port_mdb_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_mdb *mdb); -+ - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch b/target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch deleted file mode 100644 index c1336d4a92164d..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-11-net-dsa-qca8k-move-port-mirror-functions-to-common-c.patch +++ /dev/null @@ -1,232 +0,0 @@ -From 742d37a84d3f7bb60d9b2d9ada9ad4e599f65ebf Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:20 +0200 -Subject: [PATCH 11/14] net: dsa: qca8k: move port mirror functions to common - code - -The same port mirror functions are used by drivers based on qca8k family -switch. Move them to common code to make them accessible also by other -drivers. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 93 ------------------------------ - drivers/net/dsa/qca/qca8k-common.c | 91 +++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 7 +++ - 3 files changed, 98 insertions(+), 93 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1838,99 +1838,6 @@ exit: - } - - static int --qca8k_port_mirror_add(struct dsa_switch *ds, int port, -- struct dsa_mall_mirror_tc_entry *mirror, -- bool ingress) --{ -- struct qca8k_priv *priv = ds->priv; -- int monitor_port, ret; -- u32 reg, val; -- -- /* Check for existent entry */ -- if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) -- return -EEXIST; -- -- ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); -- if (ret) -- return ret; -- -- /* QCA83xx can have only one port set to mirror mode. -- * Check that the correct port is requested and return error otherwise. -- * When no mirror port is set, the values is set to 0xF -- */ -- monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -- if (monitor_port != 0xF && monitor_port != mirror->to_local_port) -- return -EEXIST; -- -- /* Set the monitor port */ -- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, -- mirror->to_local_port); -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -- if (ret) -- return ret; -- -- if (ingress) { -- reg = QCA8K_PORT_LOOKUP_CTRL(port); -- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -- } else { -- reg = QCA8K_REG_PORT_HOL_CTRL1(port); -- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -- } -- -- ret = regmap_update_bits(priv->regmap, reg, val, val); -- if (ret) -- return ret; -- -- /* Track mirror port for tx and rx to decide when the -- * mirror port has to be disabled. -- */ -- if (ingress) -- priv->mirror_rx |= BIT(port); -- else -- priv->mirror_tx |= BIT(port); -- -- return 0; --} -- --static void --qca8k_port_mirror_del(struct dsa_switch *ds, int port, -- struct dsa_mall_mirror_tc_entry *mirror) --{ -- struct qca8k_priv *priv = ds->priv; -- u32 reg, val; -- int ret; -- -- if (mirror->ingress) { -- reg = QCA8K_PORT_LOOKUP_CTRL(port); -- val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -- } else { -- reg = QCA8K_REG_PORT_HOL_CTRL1(port); -- val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -- } -- -- ret = regmap_clear_bits(priv->regmap, reg, val); -- if (ret) -- goto err; -- -- if (mirror->ingress) -- priv->mirror_rx &= ~BIT(port); -- else -- priv->mirror_tx &= ~BIT(port); -- -- /* No port set to send packet to mirror port. Disable mirror port */ -- if (!priv->mirror_rx && !priv->mirror_tx) { -- val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -- QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -- if (ret) -- goto err; -- } --err: -- dev_err(priv->dev, "Failed to del mirror port from %d", port); --} -- --static int - qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, - struct netlink_ext_ack *extack) - { ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -741,3 +741,94 @@ int qca8k_port_mdb_del(struct dsa_switch - - return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); - } -+ -+int qca8k_port_mirror_add(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror, -+ bool ingress) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int monitor_port, ret; -+ u32 reg, val; -+ -+ /* Check for existent entry */ -+ if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port)) -+ return -EEXIST; -+ -+ ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val); -+ if (ret) -+ return ret; -+ -+ /* QCA83xx can have only one port set to mirror mode. -+ * Check that the correct port is requested and return error otherwise. -+ * When no mirror port is set, the values is set to 0xF -+ */ -+ monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (monitor_port != 0xF && monitor_port != mirror->to_local_port) -+ return -EEXIST; -+ -+ /* Set the monitor port */ -+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, -+ mirror->to_local_port); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (ret) -+ return ret; -+ -+ if (ingress) { -+ reg = QCA8K_PORT_LOOKUP_CTRL(port); -+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -+ } else { -+ reg = QCA8K_REG_PORT_HOL_CTRL1(port); -+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -+ } -+ -+ ret = regmap_update_bits(priv->regmap, reg, val, val); -+ if (ret) -+ return ret; -+ -+ /* Track mirror port for tx and rx to decide when the -+ * mirror port has to be disabled. -+ */ -+ if (ingress) -+ priv->mirror_rx |= BIT(port); -+ else -+ priv->mirror_tx |= BIT(port); -+ -+ return 0; -+} -+ -+void qca8k_port_mirror_del(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ u32 reg, val; -+ int ret; -+ -+ if (mirror->ingress) { -+ reg = QCA8K_PORT_LOOKUP_CTRL(port); -+ val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN; -+ } else { -+ reg = QCA8K_REG_PORT_HOL_CTRL1(port); -+ val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN; -+ } -+ -+ ret = regmap_clear_bits(priv->regmap, reg, val); -+ if (ret) -+ goto err; -+ -+ if (mirror->ingress) -+ priv->mirror_rx &= ~BIT(port); -+ else -+ priv->mirror_tx &= ~BIT(port); -+ -+ /* No port set to send packet to mirror port. Disable mirror port */ -+ if (!priv->mirror_rx && !priv->mirror_tx) { -+ val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF); -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, -+ QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val); -+ if (ret) -+ goto err; -+ } -+err: -+ dev_err(priv->dev, "Failed to del mirror port from %d", port); -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -480,4 +480,11 @@ int qca8k_port_mdb_add(struct dsa_switch - int qca8k_port_mdb_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_mdb *mdb); - -+/* Common port mirror function */ -+int qca8k_port_mirror_add(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror, -+ bool ingress); -+void qca8k_port_mirror_del(struct dsa_switch *ds, int port, -+ struct dsa_mall_mirror_tc_entry *mirror); -+ - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch b/target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch deleted file mode 100644 index 898010f9509606..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-12-net-dsa-qca8k-move-port-VLAN-functions-to-common-cod.patch +++ /dev/null @@ -1,448 +0,0 @@ -From c5290f636624b98e76a82bd63ffec0a8a9daa620 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:21 +0200 -Subject: [PATCH 12/14] net: dsa: qca8k: move port VLAN functions to common - code - -The same port VLAN functions are used by drivers based on qca8k family -switch. Move them to common code to make them accessible also by other -drivers. -Also drop exposing busy_wait and make it static. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 182 ----------------------------- - drivers/net/dsa/qca/qca8k-common.c | 179 +++++++++++++++++++++++++++- - drivers/net/dsa/qca/qca8k.h | 10 +- - 3 files changed, 187 insertions(+), 184 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -15,7 +15,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -442,122 +441,6 @@ static struct regmap_config qca8k_regmap - }; - - static int --qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid) --{ -- u32 reg; -- int ret; -- -- /* Set the command and VLAN index */ -- reg = QCA8K_VTU_FUNC1_BUSY; -- reg |= cmd; -- reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); -- -- /* Write the function register triggering the table access */ -- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); -- if (ret) -- return ret; -- -- /* wait for completion */ -- ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); -- if (ret) -- return ret; -- -- /* Check for table full violation when adding an entry */ -- if (cmd == QCA8K_VLAN_LOAD) { -- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); -- if (ret < 0) -- return ret; -- if (reg & QCA8K_VTU_FUNC1_FULL) -- return -ENOMEM; -- } -- -- return 0; --} -- --static int --qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged) --{ -- u32 reg; -- int ret; -- -- /* -- We do the right thing with VLAN 0 and treat it as untagged while -- preserving the tag on egress. -- */ -- if (vid == 0) -- return 0; -- -- mutex_lock(&priv->reg_mutex); -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -- if (ret < 0) -- goto out; -- -- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -- if (ret < 0) -- goto out; -- reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; -- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -- if (untagged) -- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); -- else -- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); -- -- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -- if (ret) -- goto out; -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -- --out: -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static int --qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) --{ -- u32 reg, mask; -- int ret, i; -- bool del; -- -- mutex_lock(&priv->reg_mutex); -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -- if (ret < 0) -- goto out; -- -- ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -- if (ret < 0) -- goto out; -- reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -- reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); -- -- /* Check if we're the last member to be removed */ -- del = true; -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); -- -- if ((reg & mask) != mask) { -- del = false; -- break; -- } -- } -- -- if (del) { -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); -- } else { -- ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -- if (ret) -- goto out; -- ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -- } -- --out: -- mutex_unlock(&priv->reg_mutex); -- -- return ret; --} -- --static int - qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data, - struct sk_buff *read_skb, u32 *val) - { -@@ -1836,71 +1719,6 @@ exit: - - return ret; - } -- --static int --qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, -- struct netlink_ext_ack *extack) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- if (vlan_filtering) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -- QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); -- } else { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -- QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); -- } -- -- return ret; --} -- --static int --qca8k_port_vlan_add(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_vlan *vlan, -- struct netlink_ext_ack *extack) --{ -- bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; -- bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); -- if (ret) { -- dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); -- return ret; -- } -- -- if (pvid) { -- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), -- QCA8K_EGREES_VLAN_PORT_MASK(port), -- QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); -- if (ret) -- return ret; -- -- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), -- QCA8K_PORT_VLAN_CVID(vlan->vid) | -- QCA8K_PORT_VLAN_SVID(vlan->vid)); -- } -- -- return ret; --} -- --static int --qca8k_port_vlan_del(struct dsa_switch *ds, int port, -- const struct switchdev_obj_port_vlan *vlan) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret; -- -- ret = qca8k_vlan_del(priv, port, vlan->vid); -- if (ret) -- dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); -- -- return ret; --} - - static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port) - { ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -141,7 +141,7 @@ static int qca8k_bulk_write(struct qca8k - return 0; - } - --int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) -+static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) - { - u32 val; - -@@ -354,6 +354,120 @@ exit: - return ret; - } - -+static int qca8k_vlan_access(struct qca8k_priv *priv, -+ enum qca8k_vlan_cmd cmd, u16 vid) -+{ -+ u32 reg; -+ int ret; -+ -+ /* Set the command and VLAN index */ -+ reg = QCA8K_VTU_FUNC1_BUSY; -+ reg |= cmd; -+ reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid); -+ -+ /* Write the function register triggering the table access */ -+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg); -+ if (ret) -+ return ret; -+ -+ /* wait for completion */ -+ ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY); -+ if (ret) -+ return ret; -+ -+ /* Check for table full violation when adding an entry */ -+ if (cmd == QCA8K_VLAN_LOAD) { -+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®); -+ if (ret < 0) -+ return ret; -+ if (reg & QCA8K_VTU_FUNC1_FULL) -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static int qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, -+ bool untagged) -+{ -+ u32 reg; -+ int ret; -+ -+ /* We do the right thing with VLAN 0 and treat it as untagged while -+ * preserving the tag on egress. -+ */ -+ if (vid == 0) -+ return 0; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -+ if (ret < 0) -+ goto out; -+ -+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -+ if (ret < 0) -+ goto out; -+ reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN; -+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -+ if (untagged) -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port); -+ else -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port); -+ -+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -+ if (ret) -+ goto out; -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -+ -+out: -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ -+static int qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid) -+{ -+ u32 reg, mask; -+ int ret, i; -+ bool del; -+ -+ mutex_lock(&priv->reg_mutex); -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid); -+ if (ret < 0) -+ goto out; -+ -+ ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®); -+ if (ret < 0) -+ goto out; -+ reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port); -+ reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port); -+ -+ /* Check if we're the last member to be removed */ -+ del = true; -+ for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i); -+ -+ if ((reg & mask) != mask) { -+ del = false; -+ break; -+ } -+ } -+ -+ if (del) { -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid); -+ } else { -+ ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg); -+ if (ret) -+ goto out; -+ ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid); -+ } -+ -+out: -+ mutex_unlock(&priv->reg_mutex); -+ -+ return ret; -+} -+ - int qca8k_mib_init(struct qca8k_priv *priv) - { - int ret; -@@ -832,3 +946,66 @@ void qca8k_port_mirror_del(struct dsa_sw - err: - dev_err(priv->dev, "Failed to del mirror port from %d", port); - } -+ -+int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, -+ bool vlan_filtering, -+ struct netlink_ext_ack *extack) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ if (vlan_filtering) { -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -+ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE); -+ } else { -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_VLAN_MODE_MASK, -+ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE); -+ } -+ -+ return ret; -+} -+ -+int qca8k_port_vlan_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan, -+ struct netlink_ext_ack *extack) -+{ -+ bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; -+ bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ ret = qca8k_vlan_add(priv, port, vlan->vid, untagged); -+ if (ret) { -+ dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret); -+ return ret; -+ } -+ -+ if (pvid) { -+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), -+ QCA8K_EGREES_VLAN_PORT_MASK(port), -+ QCA8K_EGREES_VLAN_PORT(port, vlan->vid)); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), -+ QCA8K_PORT_VLAN_CVID(vlan->vid) | -+ QCA8K_PORT_VLAN_SVID(vlan->vid)); -+ } -+ -+ return ret; -+} -+ -+int qca8k_port_vlan_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret; -+ -+ ret = qca8k_vlan_del(priv, port, vlan->vid); -+ if (ret) -+ dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret); -+ -+ return ret; -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -431,7 +431,6 @@ int qca8k_write(struct qca8k_priv *priv, - int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val); - - /* Common ops function */ --int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask); - void qca8k_fdb_flush(struct qca8k_priv *priv); - - /* Common ethtool stats function */ -@@ -487,4 +486,13 @@ int qca8k_port_mirror_add(struct dsa_swi - void qca8k_port_mirror_del(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror); - -+/* Common port VLAN function */ -+int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, -+ struct netlink_ext_ack *extack); -+int qca8k_port_vlan_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan, -+ struct netlink_ext_ack *extack); -+int qca8k_port_vlan_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan); -+ - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch b/target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch deleted file mode 100644 index 1802b17eaad731..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-13-net-dsa-qca8k-move-port-LAG-functions-to-common-code.patch +++ /dev/null @@ -1,384 +0,0 @@ -From e9bbf019af44b204b71ef8edf224002550aab641 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:22 +0200 -Subject: [PATCH 13/14] net: dsa: qca8k: move port LAG functions to common code - -The same port LAG functions are used by drivers based on qca8k family -switch. Move them to common code to make them accessible also by other -drivers. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 168 ----------------------------- - drivers/net/dsa/qca/qca8k-common.c | 165 ++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 6 ++ - 3 files changed, 171 insertions(+), 168 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1743,178 +1743,6 @@ qca8k_get_tag_protocol(struct dsa_switch - return DSA_TAG_PROTO_QCA; - } - --static bool --qca8k_lag_can_offload(struct dsa_switch *ds, -- struct net_device *lag, -- struct netdev_lag_upper_info *info) --{ -- struct dsa_port *dp; -- int id, members = 0; -- -- id = dsa_lag_id(ds->dst, lag); -- if (id < 0 || id >= ds->num_lag_ids) -- return false; -- -- dsa_lag_foreach_port(dp, ds->dst, lag) -- /* Includes the port joining the LAG */ -- members++; -- -- if (members > QCA8K_NUM_PORTS_FOR_LAG) -- return false; -- -- if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) -- return false; -- -- if (info->hash_type != NETDEV_LAG_HASH_L2 && -- info->hash_type != NETDEV_LAG_HASH_L23) -- return false; -- -- return true; --} -- --static int --qca8k_lag_setup_hash(struct dsa_switch *ds, -- struct net_device *lag, -- struct netdev_lag_upper_info *info) --{ -- struct qca8k_priv *priv = ds->priv; -- bool unique_lag = true; -- u32 hash = 0; -- int i, id; -- -- id = dsa_lag_id(ds->dst, lag); -- -- switch (info->hash_type) { -- case NETDEV_LAG_HASH_L23: -- hash |= QCA8K_TRUNK_HASH_SIP_EN; -- hash |= QCA8K_TRUNK_HASH_DIP_EN; -- fallthrough; -- case NETDEV_LAG_HASH_L2: -- hash |= QCA8K_TRUNK_HASH_SA_EN; -- hash |= QCA8K_TRUNK_HASH_DA_EN; -- break; -- default: /* We should NEVER reach this */ -- return -EOPNOTSUPP; -- } -- -- /* Check if we are the unique configured LAG */ -- dsa_lags_foreach_id(i, ds->dst) -- if (i != id && dsa_lag_dev(ds->dst, i)) { -- unique_lag = false; -- break; -- } -- -- /* Hash Mode is global. Make sure the same Hash Mode -- * is set to all the 4 possible lag. -- * If we are the unique LAG we can set whatever hash -- * mode we want. -- * To change hash mode it's needed to remove all LAG -- * and change the mode with the latest. -- */ -- if (unique_lag) { -- priv->lag_hash_mode = hash; -- } else if (priv->lag_hash_mode != hash) { -- netdev_err(lag, "Error: Mismateched Hash Mode across different lag is not supported\n"); -- return -EOPNOTSUPP; -- } -- -- return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, -- QCA8K_TRUNK_HASH_MASK, hash); --} -- --static int --qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, -- struct net_device *lag, bool delete) --{ -- struct qca8k_priv *priv = ds->priv; -- int ret, id, i; -- u32 val; -- -- id = dsa_lag_id(ds->dst, lag); -- -- /* Read current port member */ -- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); -- if (ret) -- return ret; -- -- /* Shift val to the correct trunk */ -- val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); -- val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; -- if (delete) -- val &= ~BIT(port); -- else -- val |= BIT(port); -- -- /* Update port member. With empty portmap disable trunk */ -- ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, -- QCA8K_REG_GOL_TRUNK_MEMBER(id) | -- QCA8K_REG_GOL_TRUNK_EN(id), -- !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | -- val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); -- -- /* Search empty member if adding or port on deleting */ -- for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { -- ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); -- if (ret) -- return ret; -- -- val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); -- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; -- -- if (delete) { -- /* If port flagged to be disabled assume this member is -- * empty -- */ -- if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -- continue; -- -- val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; -- if (val != port) -- continue; -- } else { -- /* If port flagged to be enabled assume this member is -- * already set -- */ -- if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -- continue; -- } -- -- /* We have found the member to add/remove */ -- break; -- } -- -- /* Set port in the correct port mask or disable port if in delete mode */ -- return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), -- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | -- QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), -- !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | -- port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); --} -- --static int --qca8k_port_lag_join(struct dsa_switch *ds, int port, -- struct net_device *lag, -- struct netdev_lag_upper_info *info) --{ -- int ret; -- -- if (!qca8k_lag_can_offload(ds, lag, info)) -- return -EOPNOTSUPP; -- -- ret = qca8k_lag_setup_hash(ds, lag, info); -- if (ret) -- return ret; -- -- return qca8k_lag_refresh_portmap(ds, port, lag, false); --} -- --static int --qca8k_port_lag_leave(struct dsa_switch *ds, int port, -- struct net_device *lag) --{ -- return qca8k_lag_refresh_portmap(ds, port, lag, true); --} -- - static void - qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, - bool operational) ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -1009,3 +1009,169 @@ int qca8k_port_vlan_del(struct dsa_switc - - return ret; - } -+ -+static bool qca8k_lag_can_offload(struct dsa_switch *ds, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ struct dsa_port *dp; -+ int id, members = 0; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ if (id < 0 || id >= ds->num_lag_ids) -+ return false; -+ -+ dsa_lag_foreach_port(dp, ds->dst, lag) -+ /* Includes the port joining the LAG */ -+ members++; -+ -+ if (members > QCA8K_NUM_PORTS_FOR_LAG) -+ return false; -+ -+ if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) -+ return false; -+ -+ if (info->hash_type != NETDEV_LAG_HASH_L2 && -+ info->hash_type != NETDEV_LAG_HASH_L23) -+ return false; -+ -+ return true; -+} -+ -+static int qca8k_lag_setup_hash(struct dsa_switch *ds, -+ struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ bool unique_lag = true; -+ u32 hash = 0; -+ int i, id; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ -+ switch (info->hash_type) { -+ case NETDEV_LAG_HASH_L23: -+ hash |= QCA8K_TRUNK_HASH_SIP_EN; -+ hash |= QCA8K_TRUNK_HASH_DIP_EN; -+ fallthrough; -+ case NETDEV_LAG_HASH_L2: -+ hash |= QCA8K_TRUNK_HASH_SA_EN; -+ hash |= QCA8K_TRUNK_HASH_DA_EN; -+ break; -+ default: /* We should NEVER reach this */ -+ return -EOPNOTSUPP; -+ } -+ -+ /* Check if we are the unique configured LAG */ -+ dsa_lags_foreach_id(i, ds->dst) -+ if (i != id && dsa_lag_dev(ds->dst, i)) { -+ unique_lag = false; -+ break; -+ } -+ -+ /* Hash Mode is global. Make sure the same Hash Mode -+ * is set to all the 4 possible lag. -+ * If we are the unique LAG we can set whatever hash -+ * mode we want. -+ * To change hash mode it's needed to remove all LAG -+ * and change the mode with the latest. -+ */ -+ if (unique_lag) { -+ priv->lag_hash_mode = hash; -+ } else if (priv->lag_hash_mode != hash) { -+ netdev_err(lag, "Error: Mismatched Hash Mode across different lag is not supported\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL, -+ QCA8K_TRUNK_HASH_MASK, hash); -+} -+ -+static int qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port, -+ struct net_device *lag, bool delete) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ int ret, id, i; -+ u32 val; -+ -+ id = dsa_lag_id(ds->dst, lag); -+ -+ /* Read current port member */ -+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val); -+ if (ret) -+ return ret; -+ -+ /* Shift val to the correct trunk */ -+ val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id); -+ val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK; -+ if (delete) -+ val &= ~BIT(port); -+ else -+ val |= BIT(port); -+ -+ /* Update port member. With empty portmap disable trunk */ -+ ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, -+ QCA8K_REG_GOL_TRUNK_MEMBER(id) | -+ QCA8K_REG_GOL_TRUNK_EN(id), -+ !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) | -+ val << QCA8K_REG_GOL_TRUNK_SHIFT(id)); -+ -+ /* Search empty member if adding or port on deleting */ -+ for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) { -+ ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val); -+ if (ret) -+ return ret; -+ -+ val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i); -+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK; -+ -+ if (delete) { -+ /* If port flagged to be disabled assume this member is -+ * empty -+ */ -+ if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -+ continue; -+ -+ val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK; -+ if (val != port) -+ continue; -+ } else { -+ /* If port flagged to be enabled assume this member is -+ * already set -+ */ -+ if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK) -+ continue; -+ } -+ -+ /* We have found the member to add/remove */ -+ break; -+ } -+ -+ /* Set port in the correct port mask or disable port if in delete mode */ -+ return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), -+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) | -+ QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i), -+ !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) | -+ port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i)); -+} -+ -+int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct net_device *lag, -+ struct netdev_lag_upper_info *info) -+{ -+ int ret; -+ -+ if (!qca8k_lag_can_offload(ds, lag, info)) -+ return -EOPNOTSUPP; -+ -+ ret = qca8k_lag_setup_hash(ds, lag, info); -+ if (ret) -+ return ret; -+ -+ return qca8k_lag_refresh_portmap(ds, port, lag, false); -+} -+ -+int qca8k_port_lag_leave(struct dsa_switch *ds, int port, -+ struct net_device *lag) -+{ -+ return qca8k_lag_refresh_portmap(ds, port, lag, true); -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -495,4 +495,10 @@ int qca8k_port_vlan_add(struct dsa_switc - int qca8k_port_vlan_del(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan); - -+/* Common port LAG function */ -+int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct net_device *lag, -+ struct netdev_lag_upper_info *info); -+int qca8k_port_lag_leave(struct dsa_switch *ds, int port, -+ struct net_device *lag); -+ - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch b/target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch deleted file mode 100644 index d6ec8b77e0ceed..00000000000000 --- a/target/linux/generic/backport-5.15/771-v6.0-14-net-dsa-qca8k-move-read_switch_id-function-to-common.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 9d1bcb1f293f1391302a109c9819c3705c804700 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 27 Jul 2022 13:35:23 +0200 -Subject: [PATCH 14/14] net: dsa: qca8k: move read_switch_id function to common - code - -The same function to read the switch id is used by drivers based on -qca8k family switch. Move them to common code to make them accessible -also by other drivers. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 29 ----------------------------- - drivers/net/dsa/qca/qca8k-common.c | 29 +++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 1 + - 3 files changed, 30 insertions(+), 29 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1822,35 +1822,6 @@ static const struct dsa_switch_ops qca8k - .connect_tag_protocol = qca8k_connect_tag_protocol, - }; - --static int qca8k_read_switch_id(struct qca8k_priv *priv) --{ -- u32 val; -- u8 id; -- int ret; -- -- if (!priv->info) -- return -ENODEV; -- -- ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); -- if (ret < 0) -- return -ENODEV; -- -- id = QCA8K_MASK_CTRL_DEVICE_ID(val); -- if (id != priv->info->id) { -- dev_err(priv->dev, -- "Switch id detected %x but expected %x", -- id, priv->info->id); -- return -ENODEV; -- } -- -- priv->switch_id = id; -- -- /* Save revision to communicate to the internal PHY driver */ -- priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); -- -- return 0; --} -- - static int - qca8k_sw_probe(struct mdio_device *mdiodev) - { ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -1175,3 +1175,32 @@ int qca8k_port_lag_leave(struct dsa_swit - { - return qca8k_lag_refresh_portmap(ds, port, lag, true); - } -+ -+int qca8k_read_switch_id(struct qca8k_priv *priv) -+{ -+ u32 val; -+ u8 id; -+ int ret; -+ -+ if (!priv->info) -+ return -ENODEV; -+ -+ ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val); -+ if (ret < 0) -+ return -ENODEV; -+ -+ id = QCA8K_MASK_CTRL_DEVICE_ID(val); -+ if (id != priv->info->id) { -+ dev_err(priv->dev, -+ "Switch id detected %x but expected %x", -+ id, priv->info->id); -+ return -ENODEV; -+ } -+ -+ priv->switch_id = id; -+ -+ /* Save revision to communicate to the internal PHY driver */ -+ priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val); -+ -+ return 0; -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -424,6 +424,7 @@ extern const struct qca8k_mib_desc ar832 - extern const struct regmap_access_table qca8k_readable_table; - int qca8k_mib_init(struct qca8k_priv *priv); - void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable); -+int qca8k_read_switch_id(struct qca8k_priv *priv); - - /* Common read/write/rmw function */ - int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val); diff --git a/target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch b/target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch deleted file mode 100644 index 0cca2788f6d3f5..00000000000000 --- a/target/linux/generic/backport-5.15/772-v6.0-net-dsa-qca8k-fix-NULL-pointer-dereference-for-of_de.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 057bcf15db8e625276ddf02b2b7c668a3cb43f81 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 4 Sep 2022 23:46:24 +0200 -Subject: [net PATCH] net: dsa: qca8k: fix NULL pointer dereference for - of_device_get_match_data - -of_device_get_match_data is called on priv->dev before priv->dev is -actually set. Move of_device_get_match_data after priv->dev is correctly -set to fix this kernel panic. - -Fixes: 3bb0844e7bcd ("net: dsa: qca8k: cache match data to speed up access") -Signed-off-by: Christian Marangi ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1835,9 +1835,9 @@ qca8k_sw_probe(struct mdio_device *mdiod - if (!priv) - return -ENOMEM; - -- priv->info = of_device_get_match_data(priv->dev); - priv->bus = mdiodev->bus; - priv->dev = &mdiodev->dev; -+ priv->info = of_device_get_match_data(priv->dev); - - priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", - GPIOD_ASIS); diff --git a/target/linux/generic/backport-5.15/773-v5.18-1-net-dsa-Move-VLAN-filtering-syncing-out-of-dsa_switc.patch b/target/linux/generic/backport-5.15/773-v5.18-1-net-dsa-Move-VLAN-filtering-syncing-out-of-dsa_switc.patch deleted file mode 100644 index 44093eab95b36d..00000000000000 --- a/target/linux/generic/backport-5.15/773-v5.18-1-net-dsa-Move-VLAN-filtering-syncing-out-of-dsa_switc.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 381a730182f1d174e1950cd4e63e885b1c302051 Mon Sep 17 00:00:00 2001 -From: Tobias Waldekranz -Date: Mon, 24 Jan 2022 22:09:43 +0100 -Subject: net: dsa: Move VLAN filtering syncing out of dsa_switch_bridge_leave - -Most of dsa_switch_bridge_leave was, in fact, dealing with the syncing -of VLAN filtering for switches on which that is a global -setting. Separate the two phases to prepare for the cross-chip related -bugfix in the following commit. - -Signed-off-by: Tobias Waldekranz -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - net/dsa/switch.c | 38 +++++++++++++++++++++++++------------- - 1 file changed, 25 insertions(+), 13 deletions(-) - ---- a/net/dsa/switch.c -+++ b/net/dsa/switch.c -@@ -113,25 +113,14 @@ static int dsa_switch_bridge_join(struct - return dsa_tag_8021q_bridge_join(ds, info); - } - --static int dsa_switch_bridge_leave(struct dsa_switch *ds, -- struct dsa_notifier_bridge_info *info) -+static int dsa_switch_sync_vlan_filtering(struct dsa_switch *ds, -+ struct dsa_notifier_bridge_info *info) - { -- struct dsa_switch_tree *dst = ds->dst; - struct netlink_ext_ack extack = {0}; - bool change_vlan_filtering = false; - bool vlan_filtering; - int err, port; - -- if (dst->index == info->tree_index && ds->index == info->sw_index && -- ds->ops->port_bridge_leave) -- ds->ops->port_bridge_leave(ds, info->port, info->br); -- -- if ((dst->index != info->tree_index || ds->index != info->sw_index) && -- ds->ops->crosschip_bridge_leave) -- ds->ops->crosschip_bridge_leave(ds, info->tree_index, -- info->sw_index, info->port, -- info->br); -- - if (ds->needs_standalone_vlan_filtering && !br_vlan_enabled(info->br)) { - change_vlan_filtering = true; - vlan_filtering = true; -@@ -172,6 +161,29 @@ static int dsa_switch_bridge_leave(struc - return err; - } - -+ return 0; -+} -+ -+static int dsa_switch_bridge_leave(struct dsa_switch *ds, -+ struct dsa_notifier_bridge_info *info) -+{ -+ struct dsa_switch_tree *dst = ds->dst; -+ int err; -+ -+ if (dst->index == info->tree_index && ds->index == info->sw_index && -+ ds->ops->port_bridge_leave) -+ ds->ops->port_bridge_leave(ds, info->port, info->br); -+ -+ if ((dst->index != info->tree_index || ds->index != info->sw_index) && -+ ds->ops->crosschip_bridge_leave) -+ ds->ops->crosschip_bridge_leave(ds, info->tree_index, -+ info->sw_index, info->port, -+ info->br); -+ -+ err = dsa_switch_sync_vlan_filtering(ds, info); -+ if (err) -+ return err; -+ - return dsa_tag_8021q_bridge_leave(ds, info); - } - diff --git a/target/linux/generic/backport-5.15/773-v5.18-2-net-dsa-Avoid-cross-chip-syncing-of-VLAN-filtering.patch b/target/linux/generic/backport-5.15/773-v5.18-2-net-dsa-Avoid-cross-chip-syncing-of-VLAN-filtering.patch deleted file mode 100644 index cdddbcf14ee9cb..00000000000000 --- a/target/linux/generic/backport-5.15/773-v5.18-2-net-dsa-Avoid-cross-chip-syncing-of-VLAN-filtering.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 108dc8741c203e9d6ce4e973367f1bac20c7192b Mon Sep 17 00:00:00 2001 -From: Tobias Waldekranz -Date: Mon, 24 Jan 2022 22:09:44 +0100 -Subject: net: dsa: Avoid cross-chip syncing of VLAN filtering - -Changes to VLAN filtering are not applicable to cross-chip -notifications. - -On a system like this: - -.-----. .-----. .-----. -| sw1 +---+ sw2 +---+ sw3 | -'-1-2-' '-1-2-' '-1-2-' - -Before this change, upon sw1p1 leaving a bridge, a call to -dsa_port_vlan_filtering would also be made to sw2p1 and sw3p1. - -In this scenario: - -.---------. .-----. .-----. -| sw1 +---+ sw2 +---+ sw3 | -'-1-2-3-4-' '-1-2-' '-1-2-' - -When sw1p4 would leave a bridge, dsa_port_vlan_filtering would be -called for sw2 and sw3 with a non-existing port - leading to array -out-of-bounds accesses and crashes on mv88e6xxx. - -Fixes: d371b7c92d19 ("net: dsa: Unset vlan_filtering when ports leave the bridge") -Signed-off-by: Tobias Waldekranz -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - net/dsa/switch.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/net/dsa/switch.c -+++ b/net/dsa/switch.c -@@ -180,9 +180,11 @@ static int dsa_switch_bridge_leave(struc - info->sw_index, info->port, - info->br); - -- err = dsa_switch_sync_vlan_filtering(ds, info); -- if (err) -- return err; -+ if (ds->dst->index == info->tree_index && ds->index == info->sw_index) { -+ err = dsa_switch_sync_vlan_filtering(ds, info); -+ if (err) -+ return err; -+ } - - return dsa_tag_8021q_bridge_leave(ds, info); - } diff --git a/target/linux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch b/target/linux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch deleted file mode 100644 index 78570c5e6e3eab..00000000000000 --- a/target/linux/generic/backport-5.15/774-v5.16-01-net-dsa-rtl8366rb-Support-bridge-offloading.patch +++ /dev/null @@ -1,141 +0,0 @@ -From c9111895fd38dadf125e07be627778a9950d8d77 Mon Sep 17 00:00:00 2001 -From: DENG Qingfang -Date: Sun, 26 Sep 2021 00:59:24 +0200 -Subject: [PATCH 01/11] net: dsa: rtl8366rb: Support bridge offloading -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use port isolation registers to configure bridge offloading. - -Tested on the D-Link DIR-685, switching between ports and -sniffing ports to make sure no packets leak. - -Cc: Vladimir Oltean -Cc: Mauri Sandberg -Reviewed-by: Vladimir Oltean -Reviewed-by: Alvin Šipraga -Reviewed-by: Florian Fainelli -Signed-off-by: DENG Qingfang -Signed-off-by: Linus Walleij -Signed-off-by: David S. Miller ---- - drivers/net/dsa/rtl8366rb.c | 86 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 86 insertions(+) - ---- a/drivers/net/dsa/rtl8366rb.c -+++ b/drivers/net/dsa/rtl8366rb.c -@@ -300,6 +300,13 @@ - #define RTL8366RB_INTERRUPT_STATUS_REG 0x0442 - #define RTL8366RB_NUM_INTERRUPT 14 /* 0..13 */ - -+/* Port isolation registers */ -+#define RTL8366RB_PORT_ISO_BASE 0x0F08 -+#define RTL8366RB_PORT_ISO(pnum) (RTL8366RB_PORT_ISO_BASE + (pnum)) -+#define RTL8366RB_PORT_ISO_EN BIT(0) -+#define RTL8366RB_PORT_ISO_PORTS_MASK GENMASK(7, 1) -+#define RTL8366RB_PORT_ISO_PORTS(pmask) ((pmask) << 1) -+ - /* bits 0..5 enable force when cleared */ - #define RTL8366RB_MAC_FORCE_CTRL_REG 0x0F11 - -@@ -835,6 +842,21 @@ static int rtl8366rb_setup(struct dsa_sw - if (ret) - return ret; - -+ /* Isolate all user ports so they can only send packets to itself and the CPU port */ -+ for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) { -+ ret = regmap_write(smi->map, RTL8366RB_PORT_ISO(i), -+ RTL8366RB_PORT_ISO_PORTS(BIT(RTL8366RB_PORT_NUM_CPU)) | -+ RTL8366RB_PORT_ISO_EN); -+ if (ret) -+ return ret; -+ } -+ /* CPU port can send packets to all ports */ -+ ret = regmap_write(smi->map, RTL8366RB_PORT_ISO(RTL8366RB_PORT_NUM_CPU), -+ RTL8366RB_PORT_ISO_PORTS(dsa_user_ports(ds)) | -+ RTL8366RB_PORT_ISO_EN); -+ if (ret) -+ return ret; -+ - /* Set up the "green ethernet" feature */ - ret = rtl8366rb_jam_table(rtl8366rb_green_jam, - ARRAY_SIZE(rtl8366rb_green_jam), smi, false); -@@ -1127,6 +1149,68 @@ rtl8366rb_port_disable(struct dsa_switch - rb8366rb_set_port_led(smi, port, false); - } - -+static int -+rtl8366rb_port_bridge_join(struct dsa_switch *ds, int port, -+ struct net_device *bridge) -+{ -+ struct realtek_smi *smi = ds->priv; -+ unsigned int port_bitmap = 0; -+ int ret, i; -+ -+ /* Loop over all other ports than the current one */ -+ for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) { -+ /* Current port handled last */ -+ if (i == port) -+ continue; -+ /* Not on this bridge */ -+ if (dsa_to_port(ds, i)->bridge_dev != bridge) -+ continue; -+ /* Join this port to each other port on the bridge */ -+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(i), -+ RTL8366RB_PORT_ISO_PORTS(BIT(port)), -+ RTL8366RB_PORT_ISO_PORTS(BIT(port))); -+ if (ret) -+ dev_err(smi->dev, "failed to join port %d\n", port); -+ -+ port_bitmap |= BIT(i); -+ } -+ -+ /* Set the bits for the ports we can access */ -+ return regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(port), -+ RTL8366RB_PORT_ISO_PORTS(port_bitmap), -+ RTL8366RB_PORT_ISO_PORTS(port_bitmap)); -+} -+ -+static void -+rtl8366rb_port_bridge_leave(struct dsa_switch *ds, int port, -+ struct net_device *bridge) -+{ -+ struct realtek_smi *smi = ds->priv; -+ unsigned int port_bitmap = 0; -+ int ret, i; -+ -+ /* Loop over all other ports than this one */ -+ for (i = 0; i < RTL8366RB_PORT_NUM_CPU; i++) { -+ /* Current port handled last */ -+ if (i == port) -+ continue; -+ /* Not on this bridge */ -+ if (dsa_to_port(ds, i)->bridge_dev != bridge) -+ continue; -+ /* Remove this port from any other port on the bridge */ -+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(i), -+ RTL8366RB_PORT_ISO_PORTS(BIT(port)), 0); -+ if (ret) -+ dev_err(smi->dev, "failed to leave port %d\n", port); -+ -+ port_bitmap |= BIT(i); -+ } -+ -+ /* Clear the bits for the ports we can not access, leave ourselves */ -+ regmap_update_bits(smi->map, RTL8366RB_PORT_ISO(port), -+ RTL8366RB_PORT_ISO_PORTS(port_bitmap), 0); -+} -+ - static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu) - { - struct realtek_smi *smi = ds->priv; -@@ -1510,6 +1594,8 @@ static const struct dsa_switch_ops rtl83 - .get_strings = rtl8366_get_strings, - .get_ethtool_stats = rtl8366_get_ethtool_stats, - .get_sset_count = rtl8366_get_sset_count, -+ .port_bridge_join = rtl8366rb_port_bridge_join, -+ .port_bridge_leave = rtl8366rb_port_bridge_leave, - .port_vlan_filtering = rtl8366_vlan_filtering, - .port_vlan_add = rtl8366_vlan_add, - .port_vlan_del = rtl8366_vlan_del, diff --git a/target/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch b/target/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch deleted file mode 100644 index e61349a32cabc5..00000000000000 --- a/target/linux/generic/backport-5.15/774-v5.16-02-net-dsa-rtl8366-Drop-custom-VLAN-set-up.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 96cf10a8e7297065459473c081a6fb6432a22312 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Sun, 26 Sep 2021 00:59:25 +0200 -Subject: [PATCH 02/11] net: dsa: rtl8366: Drop custom VLAN set-up -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This hacky default VLAN setup was done in order to direct -packets to the right ports and provide port isolation, both -which we now support properly using custom tags and proper -bridge port isolation. - -We can drop the custom VLAN code and leave all VLAN handling -alone, as users expect things to be. We can also drop -ds->configure_vlan_while_not_filtering = false; and let -the core deal with any VLANs it wants. - -Cc: Mauri Sandberg -Cc: DENG Qingfang -Reviewed-by: Vladimir Oltean -Reviewed-by: Alvin Šipraga -Reviewed-by: Florian Fainelli -Signed-off-by: Linus Walleij -Signed-off-by: David S. Miller ---- - drivers/net/dsa/realtek-smi-core.h | 1 - - drivers/net/dsa/rtl8366.c | 48 ------------------------------ - drivers/net/dsa/rtl8366rb.c | 4 +-- - 3 files changed, 1 insertion(+), 52 deletions(-) - ---- a/drivers/net/dsa/realtek-smi-core.h -+++ b/drivers/net/dsa/realtek-smi-core.h -@@ -129,7 +129,6 @@ int rtl8366_set_pvid(struct realtek_smi - int rtl8366_enable_vlan4k(struct realtek_smi *smi, bool enable); - int rtl8366_enable_vlan(struct realtek_smi *smi, bool enable); - int rtl8366_reset_vlan(struct realtek_smi *smi); --int rtl8366_init_vlan(struct realtek_smi *smi); - int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, - struct netlink_ext_ack *extack); - int rtl8366_vlan_add(struct dsa_switch *ds, int port, ---- a/drivers/net/dsa/rtl8366.c -+++ b/drivers/net/dsa/rtl8366.c -@@ -292,54 +292,6 @@ int rtl8366_reset_vlan(struct realtek_sm - } - EXPORT_SYMBOL_GPL(rtl8366_reset_vlan); - --int rtl8366_init_vlan(struct realtek_smi *smi) --{ -- int port; -- int ret; -- -- ret = rtl8366_reset_vlan(smi); -- if (ret) -- return ret; -- -- /* Loop over the available ports, for each port, associate -- * it with the VLAN (port+1) -- */ -- for (port = 0; port < smi->num_ports; port++) { -- u32 mask; -- -- if (port == smi->cpu_port) -- /* For the CPU port, make all ports members of this -- * VLAN. -- */ -- mask = GENMASK((int)smi->num_ports - 1, 0); -- else -- /* For all other ports, enable itself plus the -- * CPU port. -- */ -- mask = BIT(port) | BIT(smi->cpu_port); -- -- /* For each port, set the port as member of VLAN (port+1) -- * and untagged, except for the CPU port: the CPU port (5) is -- * member of VLAN 6 and so are ALL the other ports as well. -- * Use filter 0 (no filter). -- */ -- dev_info(smi->dev, "VLAN%d port mask for port %d, %08x\n", -- (port + 1), port, mask); -- ret = rtl8366_set_vlan(smi, (port + 1), mask, mask, 0); -- if (ret) -- return ret; -- -- dev_info(smi->dev, "VLAN%d port %d, PVID set to %d\n", -- (port + 1), port, (port + 1)); -- ret = rtl8366_set_pvid(smi, port, (port + 1)); -- if (ret) -- return ret; -- } -- -- return rtl8366_enable_vlan(smi, true); --} --EXPORT_SYMBOL_GPL(rtl8366_init_vlan); -- - int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, - struct netlink_ext_ack *extack) - { ---- a/drivers/net/dsa/rtl8366rb.c -+++ b/drivers/net/dsa/rtl8366rb.c -@@ -985,7 +985,7 @@ static int rtl8366rb_setup(struct dsa_sw - return ret; - } - -- ret = rtl8366_init_vlan(smi); -+ ret = rtl8366_reset_vlan(smi); - if (ret) - return ret; - -@@ -999,8 +999,6 @@ static int rtl8366rb_setup(struct dsa_sw - return -ENODEV; - } - -- ds->configure_vlan_while_not_filtering = false; -- - return 0; - } - diff --git a/target/linux/generic/backport-5.15/774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch b/target/linux/generic/backport-5.15/774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch deleted file mode 100644 index 2b1975239945d1..00000000000000 --- a/target/linux/generic/backport-5.15/774-v5.16-03-net-dsa-rtl8366rb-Rewrite-weird-VLAN-filering-enable.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 7028f54b620f8df344b18e46e4a78e266091ab45 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Sun, 26 Sep 2021 00:59:26 +0200 -Subject: [PATCH 03/11] net: dsa: rtl8366rb: Rewrite weird VLAN filering - enablement -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -While we were defining one VLAN per port for isolating the ports -the port_vlan_filtering() callback was implemented to enable a -VLAN on the port + 1. This function makes no sense, not only is -it incomplete as it only enables the VLAN, it doesn't do what -the callback is supposed to do, which is to selectively enable -and disable filtering on a certain port. - -Implement the correct callback: we have two registers dealing -with filtering on the RTL9366RB, so we implement an ASIC-specific -callback and implement filering using the register bit that makes -the switch drop frames if the port is not in the VLAN member set. - -The DSA documentation Documentation/networking/switchdev.rst states: - - When the bridge has VLAN filtering enabled and a PVID is not - configured on the ingress port, untagged and 802.1p tagged - packets must be dropped. When the bridge has VLAN filtering - enabled and a PVID exists on the ingress port, untagged and - priority-tagged packets must be accepted and forwarded according - to the bridge's port membership of the PVID VLAN. When the - bridge has VLAN filtering disabled, the presence/lack of a - PVID should not influence the packet forwarding decision. - -To comply with this, we add two arrays of bool in the RTL8366RB -state that keeps track of if filtering and PVID is enabled or -not for each port. We then add code such that whenever filtering -or PVID changes, we update the filter according to the -specification. - -Cc: Vladimir Oltean -Cc: Mauri Sandberg -Cc: Alvin Šipraga -Cc: Florian Fainelli -Cc: DENG Qingfang -Signed-off-by: Linus Walleij -Signed-off-by: David S. Miller ---- - drivers/net/dsa/realtek-smi-core.h | 2 - - drivers/net/dsa/rtl8366.c | 35 ---------- - drivers/net/dsa/rtl8366rb.c | 102 +++++++++++++++++++++++++++-- - 3 files changed, 95 insertions(+), 44 deletions(-) - ---- a/drivers/net/dsa/realtek-smi-core.h -+++ b/drivers/net/dsa/realtek-smi-core.h -@@ -129,8 +129,6 @@ int rtl8366_set_pvid(struct realtek_smi - int rtl8366_enable_vlan4k(struct realtek_smi *smi, bool enable); - int rtl8366_enable_vlan(struct realtek_smi *smi, bool enable); - int rtl8366_reset_vlan(struct realtek_smi *smi); --int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, -- struct netlink_ext_ack *extack); - int rtl8366_vlan_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct netlink_ext_ack *extack); ---- a/drivers/net/dsa/rtl8366.c -+++ b/drivers/net/dsa/rtl8366.c -@@ -292,41 +292,6 @@ int rtl8366_reset_vlan(struct realtek_sm - } - EXPORT_SYMBOL_GPL(rtl8366_reset_vlan); - --int rtl8366_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, -- struct netlink_ext_ack *extack) --{ -- struct realtek_smi *smi = ds->priv; -- struct rtl8366_vlan_4k vlan4k; -- int ret; -- -- /* Use VLAN nr port + 1 since VLAN0 is not valid */ -- if (!smi->ops->is_vlan_valid(smi, port + 1)) -- return -EINVAL; -- -- dev_info(smi->dev, "%s filtering on port %d\n", -- vlan_filtering ? "enable" : "disable", -- port); -- -- /* TODO: -- * The hardware support filter ID (FID) 0..7, I have no clue how to -- * support this in the driver when the callback only says on/off. -- */ -- ret = smi->ops->get_vlan_4k(smi, port + 1, &vlan4k); -- if (ret) -- return ret; -- -- /* Just set the filter to FID 1 for now then */ -- ret = rtl8366_set_vlan(smi, port + 1, -- vlan4k.member, -- vlan4k.untag, -- 1); -- if (ret) -- return ret; -- -- return 0; --} --EXPORT_SYMBOL_GPL(rtl8366_vlan_filtering); -- - int rtl8366_vlan_add(struct dsa_switch *ds, int port, - const struct switchdev_obj_port_vlan *vlan, - struct netlink_ext_ack *extack) ---- a/drivers/net/dsa/rtl8366rb.c -+++ b/drivers/net/dsa/rtl8366rb.c -@@ -143,6 +143,21 @@ - #define RTL8366RB_PHY_NO_OFFSET 9 - #define RTL8366RB_PHY_NO_MASK (0x1f << 9) - -+/* VLAN Ingress Control Register 1, one bit per port. -+ * bit 0 .. 5 will make the switch drop ingress frames without -+ * VID such as untagged or priority-tagged frames for respective -+ * port. -+ * bit 6 .. 11 will make the switch drop ingress frames carrying -+ * a C-tag with VID != 0 for respective port. -+ */ -+#define RTL8366RB_VLAN_INGRESS_CTRL1_REG 0x037E -+#define RTL8366RB_VLAN_INGRESS_CTRL1_DROP(port) (BIT((port)) | BIT((port) + 6)) -+ -+/* VLAN Ingress Control Register 2, one bit per port. -+ * bit0 .. bit5 will make the switch drop all ingress frames with -+ * a VLAN classification that does not include the port is in its -+ * member set. -+ */ - #define RTL8366RB_VLAN_INGRESS_CTRL2_REG 0x037f - - /* LED control registers */ -@@ -321,9 +336,13 @@ - /** - * struct rtl8366rb - RTL8366RB-specific data - * @max_mtu: per-port max MTU setting -+ * @pvid_enabled: if PVID is set for respective port -+ * @vlan_filtering: if VLAN filtering is enabled for respective port - */ - struct rtl8366rb { - unsigned int max_mtu[RTL8366RB_NUM_PORTS]; -+ bool pvid_enabled[RTL8366RB_NUM_PORTS]; -+ bool vlan_filtering[RTL8366RB_NUM_PORTS]; - }; - - static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = { -@@ -933,11 +952,13 @@ static int rtl8366rb_setup(struct dsa_sw - if (ret) - return ret; - -- /* Discard VLAN tagged packets if the port is not a member of -- * the VLAN with which the packets is associated. -- */ -+ /* Accept all packets by default, we enable filtering on-demand */ -+ ret = regmap_write(smi->map, RTL8366RB_VLAN_INGRESS_CTRL1_REG, -+ 0); -+ if (ret) -+ return ret; - ret = regmap_write(smi->map, RTL8366RB_VLAN_INGRESS_CTRL2_REG, -- RTL8366RB_PORT_ALL); -+ 0); - if (ret) - return ret; - -@@ -1209,6 +1230,53 @@ rtl8366rb_port_bridge_leave(struct dsa_s - RTL8366RB_PORT_ISO_PORTS(port_bitmap), 0); - } - -+/** -+ * rtl8366rb_drop_untagged() - make the switch drop untagged and C-tagged frames -+ * @smi: SMI state container -+ * @port: the port to drop untagged and C-tagged frames on -+ * @drop: whether to drop or pass untagged and C-tagged frames -+ */ -+static int rtl8366rb_drop_untagged(struct realtek_smi *smi, int port, bool drop) -+{ -+ return regmap_update_bits(smi->map, RTL8366RB_VLAN_INGRESS_CTRL1_REG, -+ RTL8366RB_VLAN_INGRESS_CTRL1_DROP(port), -+ drop ? RTL8366RB_VLAN_INGRESS_CTRL1_DROP(port) : 0); -+} -+ -+static int rtl8366rb_vlan_filtering(struct dsa_switch *ds, int port, -+ bool vlan_filtering, -+ struct netlink_ext_ack *extack) -+{ -+ struct realtek_smi *smi = ds->priv; -+ struct rtl8366rb *rb; -+ int ret; -+ -+ rb = smi->chip_data; -+ -+ dev_dbg(smi->dev, "port %d: %s VLAN filtering\n", port, -+ vlan_filtering ? "enable" : "disable"); -+ -+ /* If the port is not in the member set, the frame will be dropped */ -+ ret = regmap_update_bits(smi->map, RTL8366RB_VLAN_INGRESS_CTRL2_REG, -+ BIT(port), vlan_filtering ? BIT(port) : 0); -+ if (ret) -+ return ret; -+ -+ /* Keep track if filtering is enabled on each port */ -+ rb->vlan_filtering[port] = vlan_filtering; -+ -+ /* If VLAN filtering is enabled and PVID is also enabled, we must -+ * not drop any untagged or C-tagged frames. If we turn off VLAN -+ * filtering on a port, we need ti accept any frames. -+ */ -+ if (vlan_filtering) -+ ret = rtl8366rb_drop_untagged(smi, port, !rb->pvid_enabled[port]); -+ else -+ ret = rtl8366rb_drop_untagged(smi, port, false); -+ -+ return ret; -+} -+ - static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu) - { - struct realtek_smi *smi = ds->priv; -@@ -1420,14 +1488,34 @@ static int rtl8366rb_get_mc_index(struct - - static int rtl8366rb_set_mc_index(struct realtek_smi *smi, int port, int index) - { -+ struct rtl8366rb *rb; -+ bool pvid_enabled; -+ int ret; -+ -+ rb = smi->chip_data; -+ pvid_enabled = !!index; -+ - if (port >= smi->num_ports || index >= RTL8366RB_NUM_VLANS) - return -EINVAL; - -- return regmap_update_bits(smi->map, RTL8366RB_PORT_VLAN_CTRL_REG(port), -+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_VLAN_CTRL_REG(port), - RTL8366RB_PORT_VLAN_CTRL_MASK << - RTL8366RB_PORT_VLAN_CTRL_SHIFT(port), - (index & RTL8366RB_PORT_VLAN_CTRL_MASK) << - RTL8366RB_PORT_VLAN_CTRL_SHIFT(port)); -+ if (ret) -+ return ret; -+ -+ rb->pvid_enabled[port] = pvid_enabled; -+ -+ /* If VLAN filtering is enabled and PVID is also enabled, we must -+ * not drop any untagged or C-tagged frames. Make sure to update the -+ * filtering setting. -+ */ -+ if (rb->vlan_filtering[port]) -+ ret = rtl8366rb_drop_untagged(smi, port, !pvid_enabled); -+ -+ return ret; - } - - static bool rtl8366rb_is_vlan_valid(struct realtek_smi *smi, unsigned int vlan) -@@ -1437,7 +1525,7 @@ static bool rtl8366rb_is_vlan_valid(stru - if (smi->vlan4k_enabled) - max = RTL8366RB_NUM_VIDS - 1; - -- if (vlan == 0 || vlan > max) -+ if (vlan > max) - return false; - - return true; -@@ -1594,7 +1682,7 @@ static const struct dsa_switch_ops rtl83 - .get_sset_count = rtl8366_get_sset_count, - .port_bridge_join = rtl8366rb_port_bridge_join, - .port_bridge_leave = rtl8366rb_port_bridge_leave, -- .port_vlan_filtering = rtl8366_vlan_filtering, -+ .port_vlan_filtering = rtl8366rb_vlan_filtering, - .port_vlan_add = rtl8366_vlan_add, - .port_vlan_del = rtl8366_vlan_del, - .port_enable = rtl8366rb_port_enable, diff --git a/target/linux/generic/backport-5.15/774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch b/target/linux/generic/backport-5.15/774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch deleted file mode 100644 index b56032c366b0eb..00000000000000 --- a/target/linux/generic/backport-5.15/774-v5.16-06-net-dsa-rtl8366-Drop-and-depromote-pointless-prints.patch +++ /dev/null @@ -1,51 +0,0 @@ -From ddb59a5dc42714999c335dab4bf256125ba3120c Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Sun, 26 Sep 2021 00:59:29 +0200 -Subject: [PATCH 06/11] net: dsa: rtl8366: Drop and depromote pointless prints -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We don't need a message for every VLAN association, dbg -is fine. The message about adding the DSA or CPU -port to a VLAN is directly misleading, this is perfectly -fine. - -Cc: Vladimir Oltean -Cc: Mauri Sandberg -Cc: DENG Qingfang -Reviewed-by: Alvin Šipraga -Reviewed-by: Florian Fainelli -Signed-off-by: Linus Walleij -Signed-off-by: David S. Miller ---- - drivers/net/dsa/rtl8366.c | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) - ---- a/drivers/net/dsa/rtl8366.c -+++ b/drivers/net/dsa/rtl8366.c -@@ -318,12 +318,9 @@ int rtl8366_vlan_add(struct dsa_switch * - return ret; - } - -- dev_info(smi->dev, "add VLAN %d on port %d, %s, %s\n", -- vlan->vid, port, untagged ? "untagged" : "tagged", -- pvid ? " PVID" : "no PVID"); -- -- if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port)) -- dev_err(smi->dev, "port is DSA or CPU port\n"); -+ dev_dbg(smi->dev, "add VLAN %d on port %d, %s, %s\n", -+ vlan->vid, port, untagged ? "untagged" : "tagged", -+ pvid ? "PVID" : "no PVID"); - - member |= BIT(port); - -@@ -356,7 +353,7 @@ int rtl8366_vlan_del(struct dsa_switch * - struct realtek_smi *smi = ds->priv; - int ret, i; - -- dev_info(smi->dev, "del VLAN %04x on port %d\n", vlan->vid, port); -+ dev_dbg(smi->dev, "del VLAN %d on port %d\n", vlan->vid, port); - - for (i = 0; i < smi->num_vlan_mc; i++) { - struct rtl8366_vlan_mc vlanmc; diff --git a/target/linux/generic/backport-5.15/774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch b/target/linux/generic/backport-5.15/774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch deleted file mode 100644 index 8cd1df97f24e06..00000000000000 --- a/target/linux/generic/backport-5.15/774-v5.16-07-net-dsa-rtl8366rb-Use-core-filtering-tracking.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 5c9b66f3c8a3f72fa2a58e89a57c6d7afd550bf0 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Wed, 29 Sep 2021 13:23:22 +0200 -Subject: [PATCH 07/11] net: dsa: rtl8366rb: Use core filtering tracking -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We added a state variable to track whether a certain port -was VLAN filtering or not, but we can just inquire the DSA -core about this. - -Cc: Vladimir Oltean -Cc: Mauri Sandberg -Cc: DENG Qingfang -Cc: Alvin Šipraga -Cc: Reviewed-by: Florian Fainelli -Signed-off-by: Linus Walleij -Signed-off-by: David S. Miller ---- - drivers/net/dsa/rtl8366rb.c | 9 ++------- - 1 file changed, 2 insertions(+), 7 deletions(-) - ---- a/drivers/net/dsa/rtl8366rb.c -+++ b/drivers/net/dsa/rtl8366rb.c -@@ -337,12 +337,10 @@ - * struct rtl8366rb - RTL8366RB-specific data - * @max_mtu: per-port max MTU setting - * @pvid_enabled: if PVID is set for respective port -- * @vlan_filtering: if VLAN filtering is enabled for respective port - */ - struct rtl8366rb { - unsigned int max_mtu[RTL8366RB_NUM_PORTS]; - bool pvid_enabled[RTL8366RB_NUM_PORTS]; -- bool vlan_filtering[RTL8366RB_NUM_PORTS]; - }; - - static struct rtl8366_mib_counter rtl8366rb_mib_counters[] = { -@@ -1262,12 +1260,9 @@ static int rtl8366rb_vlan_filtering(stru - if (ret) - return ret; - -- /* Keep track if filtering is enabled on each port */ -- rb->vlan_filtering[port] = vlan_filtering; -- - /* If VLAN filtering is enabled and PVID is also enabled, we must - * not drop any untagged or C-tagged frames. If we turn off VLAN -- * filtering on a port, we need ti accept any frames. -+ * filtering on a port, we need to accept any frames. - */ - if (vlan_filtering) - ret = rtl8366rb_drop_untagged(smi, port, !rb->pvid_enabled[port]); -@@ -1512,7 +1507,7 @@ static int rtl8366rb_set_mc_index(struct - * not drop any untagged or C-tagged frames. Make sure to update the - * filtering setting. - */ -- if (rb->vlan_filtering[port]) -+ if (dsa_port_is_vlan_filtering(dsa_to_port(smi->ds, port))) - ret = rtl8366rb_drop_untagged(smi, port, !pvid_enabled); - - return ret; diff --git a/target/linux/generic/backport-5.15/774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch b/target/linux/generic/backport-5.15/774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch deleted file mode 100644 index 8306eb5aefa1ef..00000000000000 --- a/target/linux/generic/backport-5.15/774-v5.16-08-net-dsa-rtl8366rb-Support-disabling-learning.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 831a3d26bea0d14f8563eecf96def660a74a3000 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Tue, 5 Oct 2021 21:47:02 +0200 -Subject: [PATCH 08/11] net: dsa: rtl8366rb: Support disabling learning -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The RTL8366RB hardware supports disabling learning per-port -so let's make use of this feature. Rename some unfortunately -named registers in the process. - -Suggested-by: Vladimir Oltean -Cc: Alvin Šipraga -Cc: Mauri Sandberg -Cc: Florian Fainelli -Cc: DENG Qingfang -Reviewed-by: Vladimir Oltean -Signed-off-by: Linus Walleij -Signed-off-by: David S. Miller ---- - drivers/net/dsa/rtl8366rb.c | 50 ++++++++++++++++++++++++++++++++----- - 1 file changed, 44 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/rtl8366rb.c -+++ b/drivers/net/dsa/rtl8366rb.c -@@ -14,6 +14,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -42,9 +43,12 @@ - /* Port Enable Control register */ - #define RTL8366RB_PECR 0x0001 - --/* Switch Security Control registers */ --#define RTL8366RB_SSCR0 0x0002 --#define RTL8366RB_SSCR1 0x0003 -+/* Switch per-port learning disablement register */ -+#define RTL8366RB_PORT_LEARNDIS_CTRL 0x0002 -+ -+/* Security control, actually aging register */ -+#define RTL8366RB_SECURITY_CTRL 0x0003 -+ - #define RTL8366RB_SSCR2 0x0004 - #define RTL8366RB_SSCR2_DROP_UNKNOWN_DA BIT(0) - -@@ -927,13 +931,14 @@ static int rtl8366rb_setup(struct dsa_sw - /* layer 2 size, see rtl8366rb_change_mtu() */ - rb->max_mtu[i] = 1532; - -- /* Enable learning for all ports */ -- ret = regmap_write(smi->map, RTL8366RB_SSCR0, 0); -+ /* Disable learning for all ports */ -+ ret = regmap_write(smi->map, RTL8366RB_PORT_LEARNDIS_CTRL, -+ RTL8366RB_PORT_ALL); - if (ret) - return ret; - - /* Enable auto ageing for all ports */ -- ret = regmap_write(smi->map, RTL8366RB_SSCR1, 0); -+ ret = regmap_write(smi->map, RTL8366RB_SECURITY_CTRL, 0); - if (ret) - return ret; - -@@ -1272,6 +1277,37 @@ static int rtl8366rb_vlan_filtering(stru - return ret; - } - -+static int -+rtl8366rb_port_pre_bridge_flags(struct dsa_switch *ds, int port, -+ struct switchdev_brport_flags flags, -+ struct netlink_ext_ack *extack) -+{ -+ /* We support enabling/disabling learning */ -+ if (flags.mask & ~(BR_LEARNING)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static int -+rtl8366rb_port_bridge_flags(struct dsa_switch *ds, int port, -+ struct switchdev_brport_flags flags, -+ struct netlink_ext_ack *extack) -+{ -+ struct realtek_smi *smi = ds->priv; -+ int ret; -+ -+ if (flags.mask & BR_LEARNING) { -+ ret = regmap_update_bits(smi->map, RTL8366RB_PORT_LEARNDIS_CTRL, -+ BIT(port), -+ (flags.val & BR_LEARNING) ? 0 : BIT(port)); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ - static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu) - { - struct realtek_smi *smi = ds->priv; -@@ -1682,6 +1718,8 @@ static const struct dsa_switch_ops rtl83 - .port_vlan_del = rtl8366_vlan_del, - .port_enable = rtl8366rb_port_enable, - .port_disable = rtl8366rb_port_disable, -+ .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags, -+ .port_bridge_flags = rtl8366rb_port_bridge_flags, - .port_change_mtu = rtl8366rb_change_mtu, - .port_max_mtu = rtl8366rb_max_mtu, - }; diff --git a/target/linux/generic/backport-5.15/774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch b/target/linux/generic/backport-5.15/774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch deleted file mode 100644 index a74108e23dbdcb..00000000000000 --- a/target/linux/generic/backport-5.15/774-v5.16-09-net-dsa-rtl8366rb-Support-fast-aging.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 8eb13420eb9ab4a4e2ebd612bf5dc9dba0039236 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Tue, 5 Oct 2021 21:47:03 +0200 -Subject: [PATCH 09/11] net: dsa: rtl8366rb: Support fast aging -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This implements fast aging per-port using the special "security" -register, which will flush any learned L2 LUT entries on a port. - -The vendor API just enabled setting and clearing this bit, so -we set it to age out any entries on the port and then we clear -it again. - -Suggested-by: Vladimir Oltean -Cc: Mauri Sandberg -Cc: DENG Qingfang -Cc: Florian Fainelli -Reviewed-by: Alvin Šipraga -Signed-off-by: Linus Walleij -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/rtl8366rb.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/drivers/net/dsa/rtl8366rb.c -+++ b/drivers/net/dsa/rtl8366rb.c -@@ -1308,6 +1308,19 @@ rtl8366rb_port_bridge_flags(struct dsa_s - return 0; - } - -+static void -+rtl8366rb_port_fast_age(struct dsa_switch *ds, int port) -+{ -+ struct realtek_smi *smi = ds->priv; -+ -+ /* This will age out any learned L2 entries */ -+ regmap_update_bits(smi->map, RTL8366RB_SECURITY_CTRL, -+ BIT(port), BIT(port)); -+ /* Restore the normal state of things */ -+ regmap_update_bits(smi->map, RTL8366RB_SECURITY_CTRL, -+ BIT(port), 0); -+} -+ - static int rtl8366rb_change_mtu(struct dsa_switch *ds, int port, int new_mtu) - { - struct realtek_smi *smi = ds->priv; -@@ -1720,6 +1733,7 @@ static const struct dsa_switch_ops rtl83 - .port_disable = rtl8366rb_port_disable, - .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags, - .port_bridge_flags = rtl8366rb_port_bridge_flags, -+ .port_fast_age = rtl8366rb_port_fast_age, - .port_change_mtu = rtl8366rb_change_mtu, - .port_max_mtu = rtl8366rb_max_mtu, - }; diff --git a/target/linux/generic/backport-5.15/774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch b/target/linux/generic/backport-5.15/774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch deleted file mode 100644 index e787ce94811987..00000000000000 --- a/target/linux/generic/backport-5.15/774-v5.16-10-net-dsa-rtl8366rb-Support-setting-STP-state.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 90c855471a89d3e05ecf5b6464bd04abf2c83b70 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Tue, 5 Oct 2021 21:47:04 +0200 -Subject: [PATCH 10/11] net: dsa: rtl8366rb: Support setting STP state -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This adds support for setting the STP state to the RTL8366RB -DSA switch. This rids the following message from the kernel on -e.g. OpenWrt: - -DSA: failed to set STP state 3 (-95) - -Since the RTL8366RB has one STP state register per FID with -two bit per port in each, we simply loop over all the FIDs -and set the state on all of them. - -Cc: Vladimir Oltean -Cc: Alvin Šipraga -Cc: Mauri Sandberg -Cc: DENG Qingfang -Signed-off-by: Linus Walleij -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/rtl8366rb.c | 48 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 48 insertions(+) - ---- a/drivers/net/dsa/rtl8366rb.c -+++ b/drivers/net/dsa/rtl8366rb.c -@@ -110,6 +110,18 @@ - - #define RTL8366RB_POWER_SAVING_REG 0x0021 - -+/* Spanning tree status (STP) control, two bits per port per FID */ -+#define RTL8366RB_STP_STATE_BASE 0x0050 /* 0x0050..0x0057 */ -+#define RTL8366RB_STP_STATE_DISABLED 0x0 -+#define RTL8366RB_STP_STATE_BLOCKING 0x1 -+#define RTL8366RB_STP_STATE_LEARNING 0x2 -+#define RTL8366RB_STP_STATE_FORWARDING 0x3 -+#define RTL8366RB_STP_MASK GENMASK(1, 0) -+#define RTL8366RB_STP_STATE(port, state) \ -+ ((state) << ((port) * 2)) -+#define RTL8366RB_STP_STATE_MASK(port) \ -+ RTL8366RB_STP_STATE((port), RTL8366RB_STP_MASK) -+ - /* CPU port control reg */ - #define RTL8368RB_CPU_CTRL_REG 0x0061 - #define RTL8368RB_CPU_PORTS_MSK 0x00FF -@@ -234,6 +246,7 @@ - #define RTL8366RB_NUM_LEDGROUPS 4 - #define RTL8366RB_NUM_VIDS 4096 - #define RTL8366RB_PRIORITYMAX 7 -+#define RTL8366RB_NUM_FIDS 8 - #define RTL8366RB_FIDMAX 7 - - #define RTL8366RB_PORT_1 BIT(0) /* In userspace port 0 */ -@@ -1309,6 +1322,40 @@ rtl8366rb_port_bridge_flags(struct dsa_s - } - - static void -+rtl8366rb_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) -+{ -+ struct realtek_smi *smi = ds->priv; -+ u32 val; -+ int i; -+ -+ switch (state) { -+ case BR_STATE_DISABLED: -+ val = RTL8366RB_STP_STATE_DISABLED; -+ break; -+ case BR_STATE_BLOCKING: -+ case BR_STATE_LISTENING: -+ val = RTL8366RB_STP_STATE_BLOCKING; -+ break; -+ case BR_STATE_LEARNING: -+ val = RTL8366RB_STP_STATE_LEARNING; -+ break; -+ case BR_STATE_FORWARDING: -+ val = RTL8366RB_STP_STATE_FORWARDING; -+ break; -+ default: -+ dev_err(smi->dev, "unknown bridge state requested\n"); -+ return; -+ }; -+ -+ /* Set the same status for the port on all the FIDs */ -+ for (i = 0; i < RTL8366RB_NUM_FIDS; i++) { -+ regmap_update_bits(smi->map, RTL8366RB_STP_STATE_BASE + i, -+ RTL8366RB_STP_STATE_MASK(port), -+ RTL8366RB_STP_STATE(port, val)); -+ } -+} -+ -+static void - rtl8366rb_port_fast_age(struct dsa_switch *ds, int port) - { - struct realtek_smi *smi = ds->priv; -@@ -1733,6 +1780,7 @@ static const struct dsa_switch_ops rtl83 - .port_disable = rtl8366rb_port_disable, - .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags, - .port_bridge_flags = rtl8366rb_port_bridge_flags, -+ .port_stp_state_set = rtl8366rb_port_stp_state_set, - .port_fast_age = rtl8366rb_port_fast_age, - .port_change_mtu = rtl8366rb_change_mtu, - .port_max_mtu = rtl8366rb_max_mtu, diff --git a/target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch b/target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch deleted file mode 100644 index 43fc3b15235d5c..00000000000000 --- a/target/linux/generic/backport-5.15/775-v6.0-01-net-ethernet-stmicro-stmmac-move-queue-reset-to-dedi.patch +++ /dev/null @@ -1,142 +0,0 @@ -From f9ec5723c3dbfcede9c7b0dcdf85e401ce16316c Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 23 Jul 2022 16:29:29 +0200 -Subject: [PATCH 1/5] net: ethernet: stmicro: stmmac: move queue reset to - dedicated functions - -Move queue reset to dedicated functions. This aside from a simple -cleanup is also required to allocate a dma conf without resetting the tx -queue while the device is temporarily detached as now the reset is not -part of the dma init function and can be done later in the code flow. - -Signed-off-by: Christian Marangi -Signed-off-by: Jakub Kicinski ---- - .../net/ethernet/stmicro/stmmac/stmmac_main.c | 59 ++++++++++--------- - 1 file changed, 31 insertions(+), 28 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -130,6 +130,9 @@ static irqreturn_t stmmac_mac_interrupt( - static irqreturn_t stmmac_safety_interrupt(int irq, void *dev_id); - static irqreturn_t stmmac_msi_intr_tx(int irq, void *data); - static irqreturn_t stmmac_msi_intr_rx(int irq, void *data); -+static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue); -+static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue); -+static void stmmac_reset_queues_param(struct stmmac_priv *priv); - static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue); - static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue); - -@@ -1713,9 +1716,6 @@ static int __init_dma_rx_desc_rings(stru - return -ENOMEM; - } - -- rx_q->cur_rx = 0; -- rx_q->dirty_rx = 0; -- - /* Setup the chained descriptor addresses */ - if (priv->mode == STMMAC_CHAIN_MODE) { - if (priv->extend_desc) -@@ -1821,12 +1821,6 @@ static int __init_dma_tx_desc_rings(stru - tx_q->tx_skbuff[i] = NULL; - } - -- tx_q->dirty_tx = 0; -- tx_q->cur_tx = 0; -- tx_q->mss = 0; -- -- netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue)); -- - return 0; - } - -@@ -2695,10 +2689,7 @@ static void stmmac_tx_err(struct stmmac_ - stmmac_stop_tx_dma(priv, chan); - dma_free_tx_skbufs(priv, chan); - stmmac_clear_tx_descriptors(priv, chan); -- tx_q->dirty_tx = 0; -- tx_q->cur_tx = 0; -- tx_q->mss = 0; -- netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, chan)); -+ stmmac_reset_tx_queue(priv, chan); - stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, - tx_q->dma_tx_phy, chan); - stmmac_start_tx_dma(priv, chan); -@@ -3783,6 +3774,8 @@ static int stmmac_open(struct net_device - } - } - -+ stmmac_reset_queues_param(priv); -+ - ret = stmmac_hw_setup(dev, true); - if (ret < 0) { - netdev_err(priv->dev, "%s: Hw setup failed\n", __func__); -@@ -6412,6 +6405,7 @@ void stmmac_enable_rx_queue(struct stmma - return; - } - -+ stmmac_reset_rx_queue(priv, queue); - stmmac_clear_rx_descriptors(priv, queue); - - stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, -@@ -6473,6 +6467,7 @@ void stmmac_enable_tx_queue(struct stmma - return; - } - -+ stmmac_reset_tx_queue(priv, queue); - stmmac_clear_tx_descriptors(priv, queue); - - stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, -@@ -7400,6 +7395,25 @@ int stmmac_suspend(struct device *dev) - } - EXPORT_SYMBOL_GPL(stmmac_suspend); - -+static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue) -+{ -+ struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ -+ rx_q->cur_rx = 0; -+ rx_q->dirty_rx = 0; -+} -+ -+static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue) -+{ -+ struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ -+ tx_q->cur_tx = 0; -+ tx_q->dirty_tx = 0; -+ tx_q->mss = 0; -+ -+ netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue)); -+} -+ - /** - * stmmac_reset_queues_param - reset queue parameters - * @priv: device pointer -@@ -7410,22 +7424,11 @@ static void stmmac_reset_queues_param(st - u32 tx_cnt = priv->plat->tx_queues_to_use; - u32 queue; - -- for (queue = 0; queue < rx_cnt; queue++) { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ for (queue = 0; queue < rx_cnt; queue++) -+ stmmac_reset_rx_queue(priv, queue); - -- rx_q->cur_rx = 0; -- rx_q->dirty_rx = 0; -- } -- -- for (queue = 0; queue < tx_cnt; queue++) { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -- -- tx_q->cur_tx = 0; -- tx_q->dirty_tx = 0; -- tx_q->mss = 0; -- -- netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue)); -- } -+ for (queue = 0; queue < tx_cnt; queue++) -+ stmmac_reset_tx_queue(priv, queue); - } - - /** diff --git a/target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch b/target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch deleted file mode 100644 index 0940d3d799c9fa..00000000000000 --- a/target/linux/generic/backport-5.15/775-v6.0-02-net-ethernet-stmicro-stmmac-first-disable-all-queues.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 7028471edb646bfc532fec0973e50e784cdcb7c6 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 23 Jul 2022 16:29:30 +0200 -Subject: [PATCH 2/5] net: ethernet: stmicro: stmmac: first disable all queues - and disconnect in release - -Disable all queues and disconnect before tx_disable in stmmac_release to -prevent a corner case where packet may be still queued at the same time -tx_disable is called resulting in kernel panic if some packet still has -to be processed. - -Signed-off-by: Christian Marangi -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -3837,8 +3837,6 @@ static int stmmac_release(struct net_dev - struct stmmac_priv *priv = netdev_priv(dev); - u32 chan; - -- netif_tx_disable(dev); -- - if (device_may_wakeup(priv->device)) - phylink_speed_down(priv->phylink, false); - /* Stop and disconnect the PHY */ -@@ -3850,6 +3848,8 @@ static int stmmac_release(struct net_dev - for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) - hrtimer_cancel(&priv->tx_queue[chan].txtimer); - -+ netif_tx_disable(dev); -+ - /* Free the IRQ lines */ - stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0); - diff --git a/target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch b/target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch deleted file mode 100644 index 1b5a8a700be9cf..00000000000000 --- a/target/linux/generic/backport-5.15/775-v6.0-03-net-ethernet-stmicro-stmmac-move-dma-conf-to-dedicat.patch +++ /dev/null @@ -1,1289 +0,0 @@ -From 8531c80800c10e8ef7952022326c2f983e1314bf Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 23 Jul 2022 16:29:31 +0200 -Subject: [PATCH 3/5] net: ethernet: stmicro: stmmac: move dma conf to - dedicated struct - -Move dma buf conf to dedicated struct. This in preparation for code -rework that will permit to allocate separate dma_conf without affecting -the priv struct. - -Signed-off-by: Christian Marangi -Signed-off-by: Jakub Kicinski ---- - .../net/ethernet/stmicro/stmmac/chain_mode.c | 6 +- - .../net/ethernet/stmicro/stmmac/ring_mode.c | 4 +- - drivers/net/ethernet/stmicro/stmmac/stmmac.h | 21 +- - .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 4 +- - .../net/ethernet/stmicro/stmmac/stmmac_main.c | 286 +++++++++--------- - .../stmicro/stmmac/stmmac_selftests.c | 8 +- - .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 6 +- - 7 files changed, 172 insertions(+), 163 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c -+++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c -@@ -46,7 +46,7 @@ static int jumbo_frm(void *p, struct sk_ - - while (len != 0) { - tx_q->tx_skbuff[entry] = NULL; -- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size); -+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size); - desc = tx_q->dma_tx + entry; - - if (len > bmax) { -@@ -137,7 +137,7 @@ static void refill_desc3(void *priv_ptr, - */ - p->des3 = cpu_to_le32((unsigned int)(rx_q->dma_rx_phy + - (((rx_q->dirty_rx) + 1) % -- priv->dma_rx_size) * -+ priv->dma_conf.dma_rx_size) * - sizeof(struct dma_desc))); - } - -@@ -155,7 +155,7 @@ static void clean_desc3(void *priv_ptr, - */ - p->des3 = cpu_to_le32((unsigned int)((tx_q->dma_tx_phy + - ((tx_q->dirty_tx + 1) % -- priv->dma_tx_size)) -+ priv->dma_conf.dma_tx_size)) - * sizeof(struct dma_desc))); - } - ---- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c -+++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c -@@ -51,7 +51,7 @@ static int jumbo_frm(void *p, struct sk_ - stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum, - STMMAC_RING_MODE, 0, false, skb->len); - tx_q->tx_skbuff[entry] = NULL; -- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size); -+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size); - - if (priv->extend_desc) - desc = (struct dma_desc *)(tx_q->dma_etx + entry); -@@ -107,7 +107,7 @@ static void refill_desc3(void *priv_ptr, - struct stmmac_priv *priv = rx_q->priv_data; - - /* Fill DES3 in case of RING mode */ -- if (priv->dma_buf_sz == BUF_SIZE_16KiB) -+ if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB) - p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB); - } - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h -@@ -185,6 +185,18 @@ struct stmmac_rfs_entry { - int tc; - }; - -+struct stmmac_dma_conf { -+ unsigned int dma_buf_sz; -+ -+ /* RX Queue */ -+ struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES]; -+ unsigned int dma_rx_size; -+ -+ /* TX Queue */ -+ struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES]; -+ unsigned int dma_tx_size; -+}; -+ - struct stmmac_priv { - /* Frequently used values are kept adjacent for cache effect */ - u32 tx_coal_frames[MTL_MAX_TX_QUEUES]; -@@ -199,7 +211,6 @@ struct stmmac_priv { - int sph_cap; - u32 sarc_type; - -- unsigned int dma_buf_sz; - unsigned int rx_copybreak; - u32 rx_riwt[MTL_MAX_TX_QUEUES]; - int hwts_rx_en; -@@ -211,13 +222,7 @@ struct stmmac_priv { - int (*hwif_quirks)(struct stmmac_priv *priv); - struct mutex lock; - -- /* RX Queue */ -- struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES]; -- unsigned int dma_rx_size; -- -- /* TX Queue */ -- struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES]; -- unsigned int dma_tx_size; -+ struct stmmac_dma_conf dma_conf; - - /* Generic channel for NAPI */ - struct stmmac_channel channel[STMMAC_CH_MAX]; ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c -@@ -484,8 +484,8 @@ static void stmmac_get_ringparam(struct - - ring->rx_max_pending = DMA_MAX_RX_SIZE; - ring->tx_max_pending = DMA_MAX_TX_SIZE; -- ring->rx_pending = priv->dma_rx_size; -- ring->tx_pending = priv->dma_tx_size; -+ ring->rx_pending = priv->dma_conf.dma_rx_size; -+ ring->tx_pending = priv->dma_conf.dma_tx_size; - } - - static int stmmac_set_ringparam(struct net_device *netdev, ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -74,8 +74,8 @@ static int phyaddr = -1; - module_param(phyaddr, int, 0444); - MODULE_PARM_DESC(phyaddr, "Physical device address"); - --#define STMMAC_TX_THRESH(x) ((x)->dma_tx_size / 4) --#define STMMAC_RX_THRESH(x) ((x)->dma_rx_size / 4) -+#define STMMAC_TX_THRESH(x) ((x)->dma_conf.dma_tx_size / 4) -+#define STMMAC_RX_THRESH(x) ((x)->dma_conf.dma_rx_size / 4) - - /* Limit to make sure XDP TX and slow path can coexist */ - #define STMMAC_XSK_TX_BUDGET_MAX 256 -@@ -232,7 +232,7 @@ static void stmmac_disable_all_queues(st - - /* synchronize_rcu() needed for pending XDP buffers to drain */ - for (queue = 0; queue < rx_queues_cnt; queue++) { -- rx_q = &priv->rx_queue[queue]; -+ rx_q = &priv->dma_conf.rx_queue[queue]; - if (rx_q->xsk_pool) { - synchronize_rcu(); - break; -@@ -358,13 +358,13 @@ static void print_pkt(unsigned char *buf - - static inline u32 stmmac_tx_avail(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - u32 avail; - - if (tx_q->dirty_tx > tx_q->cur_tx) - avail = tx_q->dirty_tx - tx_q->cur_tx - 1; - else -- avail = priv->dma_tx_size - tx_q->cur_tx + tx_q->dirty_tx - 1; -+ avail = priv->dma_conf.dma_tx_size - tx_q->cur_tx + tx_q->dirty_tx - 1; - - return avail; - } -@@ -376,13 +376,13 @@ static inline u32 stmmac_tx_avail(struct - */ - static inline u32 stmmac_rx_dirty(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - u32 dirty; - - if (rx_q->dirty_rx <= rx_q->cur_rx) - dirty = rx_q->cur_rx - rx_q->dirty_rx; - else -- dirty = priv->dma_rx_size - rx_q->dirty_rx + rx_q->cur_rx; -+ dirty = priv->dma_conf.dma_rx_size - rx_q->dirty_rx + rx_q->cur_rx; - - return dirty; - } -@@ -410,7 +410,7 @@ static int stmmac_enable_eee_mode(struct - - /* check if all TX queues have the work finished */ - for (queue = 0; queue < tx_cnt; queue++) { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - - if (tx_q->dirty_tx != tx_q->cur_tx) - return -EBUSY; /* still unfinished work */ -@@ -1310,7 +1310,7 @@ static void stmmac_display_rx_rings(stru - - /* Display RX rings */ - for (queue = 0; queue < rx_cnt; queue++) { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - - pr_info("\tRX Queue %u rings\n", queue); - -@@ -1323,7 +1323,7 @@ static void stmmac_display_rx_rings(stru - } - - /* Display RX ring */ -- stmmac_display_ring(priv, head_rx, priv->dma_rx_size, true, -+ stmmac_display_ring(priv, head_rx, priv->dma_conf.dma_rx_size, true, - rx_q->dma_rx_phy, desc_size); - } - } -@@ -1337,7 +1337,7 @@ static void stmmac_display_tx_rings(stru - - /* Display TX rings */ - for (queue = 0; queue < tx_cnt; queue++) { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - - pr_info("\tTX Queue %d rings\n", queue); - -@@ -1352,7 +1352,7 @@ static void stmmac_display_tx_rings(stru - desc_size = sizeof(struct dma_desc); - } - -- stmmac_display_ring(priv, head_tx, priv->dma_tx_size, false, -+ stmmac_display_ring(priv, head_tx, priv->dma_conf.dma_tx_size, false, - tx_q->dma_tx_phy, desc_size); - } - } -@@ -1393,21 +1393,21 @@ static int stmmac_set_bfsize(int mtu, in - */ - static void stmmac_clear_rx_descriptors(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - int i; - - /* Clear the RX descriptors */ -- for (i = 0; i < priv->dma_rx_size; i++) -+ for (i = 0; i < priv->dma_conf.dma_rx_size; i++) - if (priv->extend_desc) - stmmac_init_rx_desc(priv, &rx_q->dma_erx[i].basic, - priv->use_riwt, priv->mode, -- (i == priv->dma_rx_size - 1), -- priv->dma_buf_sz); -+ (i == priv->dma_conf.dma_rx_size - 1), -+ priv->dma_conf.dma_buf_sz); - else - stmmac_init_rx_desc(priv, &rx_q->dma_rx[i], - priv->use_riwt, priv->mode, -- (i == priv->dma_rx_size - 1), -- priv->dma_buf_sz); -+ (i == priv->dma_conf.dma_rx_size - 1), -+ priv->dma_conf.dma_buf_sz); - } - - /** -@@ -1419,12 +1419,12 @@ static void stmmac_clear_rx_descriptors( - */ - static void stmmac_clear_tx_descriptors(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - int i; - - /* Clear the TX descriptors */ -- for (i = 0; i < priv->dma_tx_size; i++) { -- int last = (i == (priv->dma_tx_size - 1)); -+ for (i = 0; i < priv->dma_conf.dma_tx_size; i++) { -+ int last = (i == (priv->dma_conf.dma_tx_size - 1)); - struct dma_desc *p; - - if (priv->extend_desc) -@@ -1472,7 +1472,7 @@ static void stmmac_clear_descriptors(str - static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, - int i, gfp_t flags, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; - - if (!buf->page) { -@@ -1497,7 +1497,7 @@ static int stmmac_init_rx_buffers(struct - buf->addr = page_pool_get_dma_addr(buf->page) + buf->page_offset; - - stmmac_set_desc_addr(priv, p, buf->addr); -- if (priv->dma_buf_sz == BUF_SIZE_16KiB) -+ if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB) - stmmac_init_desc3(priv, p); - - return 0; -@@ -1511,7 +1511,7 @@ static int stmmac_init_rx_buffers(struct - */ - static void stmmac_free_rx_buffer(struct stmmac_priv *priv, u32 queue, int i) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; - - if (buf->page) -@@ -1531,7 +1531,7 @@ static void stmmac_free_rx_buffer(struct - */ - static void stmmac_free_tx_buffer(struct stmmac_priv *priv, u32 queue, int i) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - - if (tx_q->tx_skbuff_dma[i].buf && - tx_q->tx_skbuff_dma[i].buf_type != STMMAC_TXBUF_T_XDP_TX) { -@@ -1576,17 +1576,17 @@ static void dma_free_rx_skbufs(struct st - { - int i; - -- for (i = 0; i < priv->dma_rx_size; i++) -+ for (i = 0; i < priv->dma_conf.dma_rx_size; i++) - stmmac_free_rx_buffer(priv, queue, i); - } - - static int stmmac_alloc_rx_buffers(struct stmmac_priv *priv, u32 queue, - gfp_t flags) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - int i; - -- for (i = 0; i < priv->dma_rx_size; i++) { -+ for (i = 0; i < priv->dma_conf.dma_rx_size; i++) { - struct dma_desc *p; - int ret; - -@@ -1613,10 +1613,10 @@ static int stmmac_alloc_rx_buffers(struc - */ - static void dma_free_rx_xskbufs(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - int i; - -- for (i = 0; i < priv->dma_rx_size; i++) { -+ for (i = 0; i < priv->dma_conf.dma_rx_size; i++) { - struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; - - if (!buf->xdp) -@@ -1629,10 +1629,10 @@ static void dma_free_rx_xskbufs(struct s - - static int stmmac_alloc_rx_buffers_zc(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - int i; - -- for (i = 0; i < priv->dma_rx_size; i++) { -+ for (i = 0; i < priv->dma_conf.dma_rx_size; i++) { - struct stmmac_rx_buffer *buf; - dma_addr_t dma_addr; - struct dma_desc *p; -@@ -1675,7 +1675,7 @@ static struct xsk_buff_pool *stmmac_get_ - */ - static int __init_dma_rx_desc_rings(struct stmmac_priv *priv, u32 queue, gfp_t flags) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - int ret; - - netif_dbg(priv, probe, priv->dev, -@@ -1721,11 +1721,11 @@ static int __init_dma_rx_desc_rings(stru - if (priv->extend_desc) - stmmac_mode_init(priv, rx_q->dma_erx, - rx_q->dma_rx_phy, -- priv->dma_rx_size, 1); -+ priv->dma_conf.dma_rx_size, 1); - else - stmmac_mode_init(priv, rx_q->dma_rx, - rx_q->dma_rx_phy, -- priv->dma_rx_size, 0); -+ priv->dma_conf.dma_rx_size, 0); - } - - return 0; -@@ -1752,7 +1752,7 @@ static int init_dma_rx_desc_rings(struct - - err_init_rx_buffers: - while (queue >= 0) { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - - if (rx_q->xsk_pool) - dma_free_rx_xskbufs(priv, queue); -@@ -1781,7 +1781,7 @@ err_init_rx_buffers: - */ - static int __init_dma_tx_desc_rings(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - int i; - - netif_dbg(priv, probe, priv->dev, -@@ -1793,16 +1793,16 @@ static int __init_dma_tx_desc_rings(stru - if (priv->extend_desc) - stmmac_mode_init(priv, tx_q->dma_etx, - tx_q->dma_tx_phy, -- priv->dma_tx_size, 1); -+ priv->dma_conf.dma_tx_size, 1); - else if (!(tx_q->tbs & STMMAC_TBS_AVAIL)) - stmmac_mode_init(priv, tx_q->dma_tx, - tx_q->dma_tx_phy, -- priv->dma_tx_size, 0); -+ priv->dma_conf.dma_tx_size, 0); - } - - tx_q->xsk_pool = stmmac_get_xsk_pool(priv, queue); - -- for (i = 0; i < priv->dma_tx_size; i++) { -+ for (i = 0; i < priv->dma_conf.dma_tx_size; i++) { - struct dma_desc *p; - - if (priv->extend_desc) -@@ -1872,12 +1872,12 @@ static int init_dma_desc_rings(struct ne - */ - static void dma_free_tx_skbufs(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - int i; - - tx_q->xsk_frames_done = 0; - -- for (i = 0; i < priv->dma_tx_size; i++) -+ for (i = 0; i < priv->dma_conf.dma_tx_size; i++) - stmmac_free_tx_buffer(priv, queue, i); - - if (tx_q->xsk_pool && tx_q->xsk_frames_done) { -@@ -1907,7 +1907,7 @@ static void stmmac_free_tx_skbufs(struct - */ - static void __free_dma_rx_desc_resources(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - - /* Release the DMA RX socket buffers */ - if (rx_q->xsk_pool) -@@ -1920,11 +1920,11 @@ static void __free_dma_rx_desc_resources - - /* Free DMA regions of consistent memory previously allocated */ - if (!priv->extend_desc) -- dma_free_coherent(priv->device, priv->dma_rx_size * -+ dma_free_coherent(priv->device, priv->dma_conf.dma_rx_size * - sizeof(struct dma_desc), - rx_q->dma_rx, rx_q->dma_rx_phy); - else -- dma_free_coherent(priv->device, priv->dma_rx_size * -+ dma_free_coherent(priv->device, priv->dma_conf.dma_rx_size * - sizeof(struct dma_extended_desc), - rx_q->dma_erx, rx_q->dma_rx_phy); - -@@ -1953,7 +1953,7 @@ static void free_dma_rx_desc_resources(s - */ - static void __free_dma_tx_desc_resources(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - size_t size; - void *addr; - -@@ -1971,7 +1971,7 @@ static void __free_dma_tx_desc_resources - addr = tx_q->dma_tx; - } - -- size *= priv->dma_tx_size; -+ size *= priv->dma_conf.dma_tx_size; - - dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy); - -@@ -2000,7 +2000,7 @@ static void free_dma_tx_desc_resources(s - */ - static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - struct stmmac_channel *ch = &priv->channel[queue]; - bool xdp_prog = stmmac_xdp_is_enabled(priv); - struct page_pool_params pp_params = { 0 }; -@@ -2012,8 +2012,8 @@ static int __alloc_dma_rx_desc_resources - rx_q->priv_data = priv; - - pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV; -- pp_params.pool_size = priv->dma_rx_size; -- num_pages = DIV_ROUND_UP(priv->dma_buf_sz, PAGE_SIZE); -+ pp_params.pool_size = priv->dma_conf.dma_rx_size; -+ num_pages = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE); - pp_params.order = ilog2(num_pages); - pp_params.nid = dev_to_node(priv->device); - pp_params.dev = priv->device; -@@ -2028,7 +2028,7 @@ static int __alloc_dma_rx_desc_resources - return ret; - } - -- rx_q->buf_pool = kcalloc(priv->dma_rx_size, -+ rx_q->buf_pool = kcalloc(priv->dma_conf.dma_rx_size, - sizeof(*rx_q->buf_pool), - GFP_KERNEL); - if (!rx_q->buf_pool) -@@ -2036,7 +2036,7 @@ static int __alloc_dma_rx_desc_resources - - if (priv->extend_desc) { - rx_q->dma_erx = dma_alloc_coherent(priv->device, -- priv->dma_rx_size * -+ priv->dma_conf.dma_rx_size * - sizeof(struct dma_extended_desc), - &rx_q->dma_rx_phy, - GFP_KERNEL); -@@ -2045,7 +2045,7 @@ static int __alloc_dma_rx_desc_resources - - } else { - rx_q->dma_rx = dma_alloc_coherent(priv->device, -- priv->dma_rx_size * -+ priv->dma_conf.dma_rx_size * - sizeof(struct dma_desc), - &rx_q->dma_rx_phy, - GFP_KERNEL); -@@ -2102,20 +2102,20 @@ err_dma: - */ - static int __alloc_dma_tx_desc_resources(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - size_t size; - void *addr; - - tx_q->queue_index = queue; - tx_q->priv_data = priv; - -- tx_q->tx_skbuff_dma = kcalloc(priv->dma_tx_size, -+ tx_q->tx_skbuff_dma = kcalloc(priv->dma_conf.dma_tx_size, - sizeof(*tx_q->tx_skbuff_dma), - GFP_KERNEL); - if (!tx_q->tx_skbuff_dma) - return -ENOMEM; - -- tx_q->tx_skbuff = kcalloc(priv->dma_tx_size, -+ tx_q->tx_skbuff = kcalloc(priv->dma_conf.dma_tx_size, - sizeof(struct sk_buff *), - GFP_KERNEL); - if (!tx_q->tx_skbuff) -@@ -2128,7 +2128,7 @@ static int __alloc_dma_tx_desc_resources - else - size = sizeof(struct dma_desc); - -- size *= priv->dma_tx_size; -+ size *= priv->dma_conf.dma_tx_size; - - addr = dma_alloc_coherent(priv->device, size, - &tx_q->dma_tx_phy, GFP_KERNEL); -@@ -2372,7 +2372,7 @@ static void stmmac_dma_operation_mode(st - - /* configure all channels */ - for (chan = 0; chan < rx_channels_count; chan++) { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[chan]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan]; - u32 buf_size; - - qmode = priv->plat->rx_queues_cfg[chan].mode_to_use; -@@ -2387,7 +2387,7 @@ static void stmmac_dma_operation_mode(st - chan); - } else { - stmmac_set_dma_bfsize(priv, priv->ioaddr, -- priv->dma_buf_sz, -+ priv->dma_conf.dma_buf_sz, - chan); - } - } -@@ -2403,7 +2403,7 @@ static void stmmac_dma_operation_mode(st - static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) - { - struct netdev_queue *nq = netdev_get_tx_queue(priv->dev, queue); -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - struct xsk_buff_pool *pool = tx_q->xsk_pool; - unsigned int entry = tx_q->cur_tx; - struct dma_desc *tx_desc = NULL; -@@ -2478,7 +2478,7 @@ static bool stmmac_xdp_xmit_zc(struct st - - stmmac_enable_dma_transmission(priv, priv->ioaddr); - -- tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_tx_size); -+ tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size); - entry = tx_q->cur_tx; - } - -@@ -2504,7 +2504,7 @@ static bool stmmac_xdp_xmit_zc(struct st - */ - static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - unsigned int bytes_compl = 0, pkts_compl = 0; - unsigned int entry, xmits = 0, count = 0; - -@@ -2517,7 +2517,7 @@ static int stmmac_tx_clean(struct stmmac - entry = tx_q->dirty_tx; - - /* Try to clean all TX complete frame in 1 shot */ -- while ((entry != tx_q->cur_tx) && count < priv->dma_tx_size) { -+ while ((entry != tx_q->cur_tx) && count < priv->dma_conf.dma_tx_size) { - struct xdp_frame *xdpf; - struct sk_buff *skb; - struct dma_desc *p; -@@ -2617,7 +2617,7 @@ static int stmmac_tx_clean(struct stmmac - - stmmac_release_tx_desc(priv, p, priv->mode); - -- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size); -+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size); - } - tx_q->dirty_tx = entry; - -@@ -2682,7 +2682,7 @@ static int stmmac_tx_clean(struct stmmac - */ - static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; - - netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, chan)); - -@@ -2749,8 +2749,8 @@ static int stmmac_napi_check(struct stmm - { - int status = stmmac_dma_interrupt_status(priv, priv->ioaddr, - &priv->xstats, chan, dir); -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[chan]; -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; - struct stmmac_channel *ch = &priv->channel[chan]; - struct napi_struct *rx_napi; - struct napi_struct *tx_napi; -@@ -2926,7 +2926,7 @@ static int stmmac_init_dma_engine(struct - - /* DMA RX Channel Configuration */ - for (chan = 0; chan < rx_channels_count; chan++) { -- rx_q = &priv->rx_queue[chan]; -+ rx_q = &priv->dma_conf.rx_queue[chan]; - - stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, - rx_q->dma_rx_phy, chan); -@@ -2940,7 +2940,7 @@ static int stmmac_init_dma_engine(struct - - /* DMA TX Channel Configuration */ - for (chan = 0; chan < tx_channels_count; chan++) { -- tx_q = &priv->tx_queue[chan]; -+ tx_q = &priv->dma_conf.tx_queue[chan]; - - stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, - tx_q->dma_tx_phy, chan); -@@ -2955,7 +2955,7 @@ static int stmmac_init_dma_engine(struct - - static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - - hrtimer_start(&tx_q->txtimer, - STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), -@@ -3005,7 +3005,7 @@ static void stmmac_init_coalesce(struct - u32 chan; - - for (chan = 0; chan < tx_channel_count; chan++) { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; - - priv->tx_coal_frames[chan] = STMMAC_TX_FRAMES; - priv->tx_coal_timer[chan] = STMMAC_COAL_TX_TIMER; -@@ -3027,12 +3027,12 @@ static void stmmac_set_rings_length(stru - /* set TX ring length */ - for (chan = 0; chan < tx_channels_count; chan++) - stmmac_set_tx_ring_len(priv, priv->ioaddr, -- (priv->dma_tx_size - 1), chan); -+ (priv->dma_conf.dma_tx_size - 1), chan); - - /* set RX ring length */ - for (chan = 0; chan < rx_channels_count; chan++) - stmmac_set_rx_ring_len(priv, priv->ioaddr, -- (priv->dma_rx_size - 1), chan); -+ (priv->dma_conf.dma_rx_size - 1), chan); - } - - /** -@@ -3367,7 +3367,7 @@ static int stmmac_hw_setup(struct net_de - /* Enable TSO */ - if (priv->tso) { - for (chan = 0; chan < tx_cnt; chan++) { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; - - /* TSO and TBS cannot co-exist */ - if (tx_q->tbs & STMMAC_TBS_AVAIL) -@@ -3389,7 +3389,7 @@ static int stmmac_hw_setup(struct net_de - - /* TBS */ - for (chan = 0; chan < tx_cnt; chan++) { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; - int enable = tx_q->tbs & STMMAC_TBS_AVAIL; - - stmmac_enable_tbs(priv, priv->ioaddr, enable, chan); -@@ -3433,7 +3433,7 @@ static void stmmac_free_irq(struct net_d - for (j = irq_idx - 1; j >= 0; j--) { - if (priv->tx_irq[j] > 0) { - irq_set_affinity_hint(priv->tx_irq[j], NULL); -- free_irq(priv->tx_irq[j], &priv->tx_queue[j]); -+ free_irq(priv->tx_irq[j], &priv->dma_conf.tx_queue[j]); - } - } - irq_idx = priv->plat->rx_queues_to_use; -@@ -3442,7 +3442,7 @@ static void stmmac_free_irq(struct net_d - for (j = irq_idx - 1; j >= 0; j--) { - if (priv->rx_irq[j] > 0) { - irq_set_affinity_hint(priv->rx_irq[j], NULL); -- free_irq(priv->rx_irq[j], &priv->rx_queue[j]); -+ free_irq(priv->rx_irq[j], &priv->dma_conf.rx_queue[j]); - } - } - -@@ -3576,7 +3576,7 @@ static int stmmac_request_irq_multi_msi( - sprintf(int_name, "%s:%s-%d", dev->name, "rx", i); - ret = request_irq(priv->rx_irq[i], - stmmac_msi_intr_rx, -- 0, int_name, &priv->rx_queue[i]); -+ 0, int_name, &priv->dma_conf.rx_queue[i]); - if (unlikely(ret < 0)) { - netdev_err(priv->dev, - "%s: alloc rx-%d MSI %d (error: %d)\n", -@@ -3599,7 +3599,7 @@ static int stmmac_request_irq_multi_msi( - sprintf(int_name, "%s:%s-%d", dev->name, "tx", i); - ret = request_irq(priv->tx_irq[i], - stmmac_msi_intr_tx, -- 0, int_name, &priv->tx_queue[i]); -+ 0, int_name, &priv->dma_conf.tx_queue[i]); - if (unlikely(ret < 0)) { - netdev_err(priv->dev, - "%s: alloc tx-%d MSI %d (error: %d)\n", -@@ -3730,21 +3730,21 @@ static int stmmac_open(struct net_device - bfsize = 0; - - if (bfsize < BUF_SIZE_16KiB) -- bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); -+ bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_conf.dma_buf_sz); - -- priv->dma_buf_sz = bfsize; -+ priv->dma_conf.dma_buf_sz = bfsize; - buf_sz = bfsize; - - priv->rx_copybreak = STMMAC_RX_COPYBREAK; - -- if (!priv->dma_tx_size) -- priv->dma_tx_size = DMA_DEFAULT_TX_SIZE; -- if (!priv->dma_rx_size) -- priv->dma_rx_size = DMA_DEFAULT_RX_SIZE; -+ if (!priv->dma_conf.dma_tx_size) -+ priv->dma_conf.dma_tx_size = DMA_DEFAULT_TX_SIZE; -+ if (!priv->dma_conf.dma_rx_size) -+ priv->dma_conf.dma_rx_size = DMA_DEFAULT_RX_SIZE; - - /* Earlier check for TBS */ - for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; - int tbs_en = priv->plat->tx_queues_cfg[chan].tbs_en; - - /* Setup per-TXQ tbs flag before TX descriptor alloc */ -@@ -3802,7 +3802,7 @@ irq_error: - phylink_stop(priv->phylink); - - for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) -- hrtimer_cancel(&priv->tx_queue[chan].txtimer); -+ hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); - - stmmac_hw_teardown(dev); - init_error: -@@ -3846,7 +3846,7 @@ static int stmmac_release(struct net_dev - stmmac_disable_all_queues(priv); - - for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) -- hrtimer_cancel(&priv->tx_queue[chan].txtimer); -+ hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); - - netif_tx_disable(dev); - -@@ -3910,7 +3910,7 @@ static bool stmmac_vlan_insert(struct st - return false; - - stmmac_set_tx_owner(priv, p); -- tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_tx_size); -+ tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size); - return true; - } - -@@ -3928,7 +3928,7 @@ static bool stmmac_vlan_insert(struct st - static void stmmac_tso_allocator(struct stmmac_priv *priv, dma_addr_t des, - int total_len, bool last_segment, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - struct dma_desc *desc; - u32 buff_size; - int tmp_len; -@@ -3939,7 +3939,7 @@ static void stmmac_tso_allocator(struct - dma_addr_t curr_addr; - - tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, -- priv->dma_tx_size); -+ priv->dma_conf.dma_tx_size); - WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]); - - if (tx_q->tbs & STMMAC_TBS_AVAIL) -@@ -3967,7 +3967,7 @@ static void stmmac_tso_allocator(struct - - static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - int desc_size; - - if (likely(priv->extend_desc)) -@@ -4029,7 +4029,7 @@ static netdev_tx_t stmmac_tso_xmit(struc - dma_addr_t des; - int i; - -- tx_q = &priv->tx_queue[queue]; -+ tx_q = &priv->dma_conf.tx_queue[queue]; - first_tx = tx_q->cur_tx; - - /* Compute header lengths */ -@@ -4069,7 +4069,7 @@ static netdev_tx_t stmmac_tso_xmit(struc - stmmac_set_mss(priv, mss_desc, mss); - tx_q->mss = mss; - tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, -- priv->dma_tx_size); -+ priv->dma_conf.dma_tx_size); - WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]); - } - -@@ -4181,7 +4181,7 @@ static netdev_tx_t stmmac_tso_xmit(struc - * ndo_start_xmit will fill this descriptor the next time it's - * called and stmmac_tx_clean may clean up to this descriptor. - */ -- tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_tx_size); -+ tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size); - - if (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1))) { - netif_dbg(priv, hw, priv->dev, "%s: stop transmitted packets\n", -@@ -4269,7 +4269,7 @@ static netdev_tx_t stmmac_xmit(struct sk - int entry, first_tx; - dma_addr_t des; - -- tx_q = &priv->tx_queue[queue]; -+ tx_q = &priv->dma_conf.tx_queue[queue]; - first_tx = tx_q->cur_tx; - - if (priv->tx_path_in_lpi_mode && priv->eee_sw_timer_en) -@@ -4332,7 +4332,7 @@ static netdev_tx_t stmmac_xmit(struct sk - int len = skb_frag_size(frag); - bool last_segment = (i == (nfrags - 1)); - -- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size); -+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size); - WARN_ON(tx_q->tx_skbuff[entry]); - - if (likely(priv->extend_desc)) -@@ -4403,7 +4403,7 @@ static netdev_tx_t stmmac_xmit(struct sk - * ndo_start_xmit will fill this descriptor the next time it's - * called and stmmac_tx_clean may clean up to this descriptor. - */ -- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size); -+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size); - tx_q->cur_tx = entry; - - if (netif_msg_pktdata(priv)) { -@@ -4515,7 +4515,7 @@ static void stmmac_rx_vlan(struct net_de - */ - static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - int dirty = stmmac_rx_dirty(priv, queue); - unsigned int entry = rx_q->dirty_rx; - -@@ -4565,7 +4565,7 @@ static inline void stmmac_rx_refill(stru - dma_wmb(); - stmmac_set_rx_owner(priv, p, use_rx_wd); - -- entry = STMMAC_GET_ENTRY(entry, priv->dma_rx_size); -+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_rx_size); - } - rx_q->dirty_rx = entry; - rx_q->rx_tail_addr = rx_q->dma_rx_phy + -@@ -4593,12 +4593,12 @@ static unsigned int stmmac_rx_buf1_len(s - - /* First descriptor, not last descriptor and not split header */ - if (status & rx_not_ls) -- return priv->dma_buf_sz; -+ return priv->dma_conf.dma_buf_sz; - - plen = stmmac_get_rx_frame_len(priv, p, coe); - - /* First descriptor and last descriptor and not split header */ -- return min_t(unsigned int, priv->dma_buf_sz, plen); -+ return min_t(unsigned int, priv->dma_conf.dma_buf_sz, plen); - } - - static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv, -@@ -4614,7 +4614,7 @@ static unsigned int stmmac_rx_buf2_len(s - - /* Not last descriptor */ - if (status & rx_not_ls) -- return priv->dma_buf_sz; -+ return priv->dma_conf.dma_buf_sz; - - plen = stmmac_get_rx_frame_len(priv, p, coe); - -@@ -4625,7 +4625,7 @@ static unsigned int stmmac_rx_buf2_len(s - static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue, - struct xdp_frame *xdpf, bool dma_map) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - unsigned int entry = tx_q->cur_tx; - struct dma_desc *tx_desc; - dma_addr_t dma_addr; -@@ -4688,7 +4688,7 @@ static int stmmac_xdp_xmit_xdpf(struct s - - stmmac_enable_dma_transmission(priv, priv->ioaddr); - -- entry = STMMAC_GET_ENTRY(entry, priv->dma_tx_size); -+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size); - tx_q->cur_tx = entry; - - return STMMAC_XDP_TX; -@@ -4862,7 +4862,7 @@ static void stmmac_dispatch_skb_zc(struc - - static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - unsigned int entry = rx_q->dirty_rx; - struct dma_desc *rx_desc = NULL; - bool ret = true; -@@ -4905,7 +4905,7 @@ static bool stmmac_rx_refill_zc(struct s - dma_wmb(); - stmmac_set_rx_owner(priv, rx_desc, use_rx_wd); - -- entry = STMMAC_GET_ENTRY(entry, priv->dma_rx_size); -+ entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_rx_size); - } - - if (rx_desc) { -@@ -4920,7 +4920,7 @@ static bool stmmac_rx_refill_zc(struct s - - static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - unsigned int count = 0, error = 0, len = 0; - int dirty = stmmac_rx_dirty(priv, queue); - unsigned int next_entry = rx_q->cur_rx; -@@ -4942,7 +4942,7 @@ static int stmmac_rx_zc(struct stmmac_pr - desc_size = sizeof(struct dma_desc); - } - -- stmmac_display_ring(priv, rx_head, priv->dma_rx_size, true, -+ stmmac_display_ring(priv, rx_head, priv->dma_conf.dma_rx_size, true, - rx_q->dma_rx_phy, desc_size); - } - while (count < limit) { -@@ -4989,7 +4989,7 @@ read_again: - - /* Prefetch the next RX descriptor */ - rx_q->cur_rx = STMMAC_GET_ENTRY(rx_q->cur_rx, -- priv->dma_rx_size); -+ priv->dma_conf.dma_rx_size); - next_entry = rx_q->cur_rx; - - if (priv->extend_desc) -@@ -5110,7 +5110,7 @@ read_again: - */ - static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - struct stmmac_channel *ch = &priv->channel[queue]; - unsigned int count = 0, error = 0, len = 0; - int status = 0, coe = priv->hw->rx_csum; -@@ -5123,7 +5123,7 @@ static int stmmac_rx(struct stmmac_priv - int buf_sz; - - dma_dir = page_pool_get_dma_dir(rx_q->page_pool); -- buf_sz = DIV_ROUND_UP(priv->dma_buf_sz, PAGE_SIZE) * PAGE_SIZE; -+ buf_sz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE; - - if (netif_msg_rx_status(priv)) { - void *rx_head; -@@ -5137,7 +5137,7 @@ static int stmmac_rx(struct stmmac_priv - desc_size = sizeof(struct dma_desc); - } - -- stmmac_display_ring(priv, rx_head, priv->dma_rx_size, true, -+ stmmac_display_ring(priv, rx_head, priv->dma_conf.dma_rx_size, true, - rx_q->dma_rx_phy, desc_size); - } - while (count < limit) { -@@ -5181,7 +5181,7 @@ read_again: - break; - - rx_q->cur_rx = STMMAC_GET_ENTRY(rx_q->cur_rx, -- priv->dma_rx_size); -+ priv->dma_conf.dma_rx_size); - next_entry = rx_q->cur_rx; - - if (priv->extend_desc) -@@ -5315,7 +5315,7 @@ read_again: - buf1_len, dma_dir); - skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, - buf->page, buf->page_offset, buf1_len, -- priv->dma_buf_sz); -+ priv->dma_conf.dma_buf_sz); - - /* Data payload appended into SKB */ - page_pool_release_page(rx_q->page_pool, buf->page); -@@ -5327,7 +5327,7 @@ read_again: - buf2_len, dma_dir); - skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, - buf->sec_page, 0, buf2_len, -- priv->dma_buf_sz); -+ priv->dma_conf.dma_buf_sz); - - /* Data payload appended into SKB */ - page_pool_release_page(rx_q->page_pool, buf->sec_page); -@@ -5760,11 +5760,13 @@ static irqreturn_t stmmac_safety_interru - static irqreturn_t stmmac_msi_intr_tx(int irq, void *data) - { - struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)data; -+ struct stmmac_dma_conf *dma_conf; - int chan = tx_q->queue_index; - struct stmmac_priv *priv; - int status; - -- priv = container_of(tx_q, struct stmmac_priv, tx_queue[chan]); -+ dma_conf = container_of(tx_q, struct stmmac_dma_conf, tx_queue[chan]); -+ priv = container_of(dma_conf, struct stmmac_priv, dma_conf); - - /* Check if adapter is up */ - if (test_bit(STMMAC_DOWN, &priv->state)) -@@ -5799,10 +5801,12 @@ static irqreturn_t stmmac_msi_intr_tx(in - static irqreturn_t stmmac_msi_intr_rx(int irq, void *data) - { - struct stmmac_rx_queue *rx_q = (struct stmmac_rx_queue *)data; -+ struct stmmac_dma_conf *dma_conf; - int chan = rx_q->queue_index; - struct stmmac_priv *priv; - -- priv = container_of(rx_q, struct stmmac_priv, rx_queue[chan]); -+ dma_conf = container_of(rx_q, struct stmmac_dma_conf, rx_queue[chan]); -+ priv = container_of(dma_conf, struct stmmac_priv, dma_conf); - - /* Check if adapter is up */ - if (test_bit(STMMAC_DOWN, &priv->state)) -@@ -5828,10 +5832,10 @@ static void stmmac_poll_controller(struc - - if (priv->plat->multi_msi_en) { - for (i = 0; i < priv->plat->rx_queues_to_use; i++) -- stmmac_msi_intr_rx(0, &priv->rx_queue[i]); -+ stmmac_msi_intr_rx(0, &priv->dma_conf.rx_queue[i]); - - for (i = 0; i < priv->plat->tx_queues_to_use; i++) -- stmmac_msi_intr_tx(0, &priv->tx_queue[i]); -+ stmmac_msi_intr_tx(0, &priv->dma_conf.tx_queue[i]); - } else { - disable_irq(dev->irq); - stmmac_interrupt(dev->irq, dev); -@@ -6012,34 +6016,34 @@ static int stmmac_rings_status_show(stru - return 0; - - for (queue = 0; queue < rx_count; queue++) { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - - seq_printf(seq, "RX Queue %d:\n", queue); - - if (priv->extend_desc) { - seq_printf(seq, "Extended descriptor ring:\n"); - sysfs_display_ring((void *)rx_q->dma_erx, -- priv->dma_rx_size, 1, seq, rx_q->dma_rx_phy); -+ priv->dma_conf.dma_rx_size, 1, seq, rx_q->dma_rx_phy); - } else { - seq_printf(seq, "Descriptor ring:\n"); - sysfs_display_ring((void *)rx_q->dma_rx, -- priv->dma_rx_size, 0, seq, rx_q->dma_rx_phy); -+ priv->dma_conf.dma_rx_size, 0, seq, rx_q->dma_rx_phy); - } - } - - for (queue = 0; queue < tx_count; queue++) { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - - seq_printf(seq, "TX Queue %d:\n", queue); - - if (priv->extend_desc) { - seq_printf(seq, "Extended descriptor ring:\n"); - sysfs_display_ring((void *)tx_q->dma_etx, -- priv->dma_tx_size, 1, seq, tx_q->dma_tx_phy); -+ priv->dma_conf.dma_tx_size, 1, seq, tx_q->dma_tx_phy); - } else if (!(tx_q->tbs & STMMAC_TBS_AVAIL)) { - seq_printf(seq, "Descriptor ring:\n"); - sysfs_display_ring((void *)tx_q->dma_tx, -- priv->dma_tx_size, 0, seq, tx_q->dma_tx_phy); -+ priv->dma_conf.dma_tx_size, 0, seq, tx_q->dma_tx_phy); - } - } - -@@ -6386,7 +6390,7 @@ void stmmac_disable_rx_queue(struct stmm - - void stmmac_enable_rx_queue(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - struct stmmac_channel *ch = &priv->channel[queue]; - unsigned long flags; - u32 buf_size; -@@ -6423,7 +6427,7 @@ void stmmac_enable_rx_queue(struct stmma - rx_q->queue_index); - } else { - stmmac_set_dma_bfsize(priv, priv->ioaddr, -- priv->dma_buf_sz, -+ priv->dma_conf.dma_buf_sz, - rx_q->queue_index); - } - -@@ -6449,7 +6453,7 @@ void stmmac_disable_tx_queue(struct stmm - - void stmmac_enable_tx_queue(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - struct stmmac_channel *ch = &priv->channel[queue]; - unsigned long flags; - int ret; -@@ -6499,7 +6503,7 @@ void stmmac_xdp_release(struct net_devic - stmmac_disable_all_queues(priv); - - for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) -- hrtimer_cancel(&priv->tx_queue[chan].txtimer); -+ hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); - - /* Free the IRQ lines */ - stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0); -@@ -6558,7 +6562,7 @@ int stmmac_xdp_open(struct net_device *d - - /* DMA RX Channel Configuration */ - for (chan = 0; chan < rx_cnt; chan++) { -- rx_q = &priv->rx_queue[chan]; -+ rx_q = &priv->dma_conf.rx_queue[chan]; - - stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, - rx_q->dma_rx_phy, chan); -@@ -6576,7 +6580,7 @@ int stmmac_xdp_open(struct net_device *d - rx_q->queue_index); - } else { - stmmac_set_dma_bfsize(priv, priv->ioaddr, -- priv->dma_buf_sz, -+ priv->dma_conf.dma_buf_sz, - rx_q->queue_index); - } - -@@ -6585,7 +6589,7 @@ int stmmac_xdp_open(struct net_device *d - - /* DMA TX Channel Configuration */ - for (chan = 0; chan < tx_cnt; chan++) { -- tx_q = &priv->tx_queue[chan]; -+ tx_q = &priv->dma_conf.tx_queue[chan]; - - stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, - tx_q->dma_tx_phy, chan); -@@ -6618,7 +6622,7 @@ int stmmac_xdp_open(struct net_device *d - - irq_error: - for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) -- hrtimer_cancel(&priv->tx_queue[chan].txtimer); -+ hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); - - stmmac_hw_teardown(dev); - init_error: -@@ -6645,8 +6649,8 @@ int stmmac_xsk_wakeup(struct net_device - queue >= priv->plat->tx_queues_to_use) - return -EINVAL; - -- rx_q = &priv->rx_queue[queue]; -- tx_q = &priv->tx_queue[queue]; -+ rx_q = &priv->dma_conf.rx_queue[queue]; -+ tx_q = &priv->dma_conf.tx_queue[queue]; - ch = &priv->channel[queue]; - - if (!rx_q->xsk_pool && !tx_q->xsk_pool) -@@ -6906,8 +6910,8 @@ int stmmac_reinit_ringparam(struct net_d - if (netif_running(dev)) - stmmac_release(dev); - -- priv->dma_rx_size = rx_size; -- priv->dma_tx_size = tx_size; -+ priv->dma_conf.dma_rx_size = rx_size; -+ priv->dma_conf.dma_tx_size = tx_size; - - if (netif_running(dev)) - ret = stmmac_open(dev); -@@ -7345,7 +7349,7 @@ int stmmac_suspend(struct device *dev) - stmmac_disable_all_queues(priv); - - for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) -- hrtimer_cancel(&priv->tx_queue[chan].txtimer); -+ hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer); - - if (priv->eee_enabled) { - priv->tx_path_in_lpi_mode = false; -@@ -7397,7 +7401,7 @@ EXPORT_SYMBOL_GPL(stmmac_suspend); - - static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - - rx_q->cur_rx = 0; - rx_q->dirty_rx = 0; -@@ -7405,7 +7409,7 @@ static void stmmac_reset_rx_queue(struct - - static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - - tx_q->cur_tx = 0; - tx_q->dirty_tx = 0; ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c -@@ -795,8 +795,8 @@ static int stmmac_test_flowctrl(struct s - struct stmmac_channel *ch = &priv->channel[i]; - u32 tail; - -- tail = priv->rx_queue[i].dma_rx_phy + -- (priv->dma_rx_size * sizeof(struct dma_desc)); -+ tail = priv->dma_conf.rx_queue[i].dma_rx_phy + -+ (priv->dma_conf.dma_rx_size * sizeof(struct dma_desc)); - - stmmac_set_rx_tail_ptr(priv, priv->ioaddr, tail, i); - stmmac_start_rx(priv, priv->ioaddr, i); -@@ -1684,7 +1684,7 @@ cleanup: - static int __stmmac_test_jumbo(struct stmmac_priv *priv, u16 queue) - { - struct stmmac_packet_attrs attr = { }; -- int size = priv->dma_buf_sz; -+ int size = priv->dma_conf.dma_buf_sz; - - attr.dst = priv->dev->dev_addr; - attr.max_size = size - ETH_FCS_LEN; -@@ -1767,7 +1767,7 @@ static int stmmac_test_tbs(struct stmmac - - /* Find first TBS enabled Queue, if any */ - for (i = 0; i < priv->plat->tx_queues_to_use; i++) -- if (priv->tx_queue[i].tbs & STMMAC_TBS_AVAIL) -+ if (priv->dma_conf.tx_queue[i].tbs & STMMAC_TBS_AVAIL) - break; - - if (i >= priv->plat->tx_queues_to_use) ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c -@@ -971,13 +971,13 @@ static int tc_setup_etf(struct stmmac_pr - return -EOPNOTSUPP; - if (qopt->queue >= priv->plat->tx_queues_to_use) - return -EINVAL; -- if (!(priv->tx_queue[qopt->queue].tbs & STMMAC_TBS_AVAIL)) -+ if (!(priv->dma_conf.tx_queue[qopt->queue].tbs & STMMAC_TBS_AVAIL)) - return -EINVAL; - - if (qopt->enable) -- priv->tx_queue[qopt->queue].tbs |= STMMAC_TBS_EN; -+ priv->dma_conf.tx_queue[qopt->queue].tbs |= STMMAC_TBS_EN; - else -- priv->tx_queue[qopt->queue].tbs &= ~STMMAC_TBS_EN; -+ priv->dma_conf.tx_queue[qopt->queue].tbs &= ~STMMAC_TBS_EN; - - netdev_info(priv->dev, "%s ETF for Queue %d\n", - qopt->enable ? "enabled" : "disabled", qopt->queue); diff --git a/target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch b/target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch deleted file mode 100644 index 87da2af5624fec..00000000000000 --- a/target/linux/generic/backport-5.15/775-v6.0-04-net-ethernet-stmicro-stmmac-generate-stmmac-dma-conf.patch +++ /dev/null @@ -1,1161 +0,0 @@ -From ba39b344e9240a4a5fd4ab8178200b85cd1809da Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 23 Jul 2022 16:29:32 +0200 -Subject: [PATCH 4/5] net: ethernet: stmicro: stmmac: generate stmmac dma conf - before open - -Rework the driver to generate the stmmac dma_conf before stmmac_open. -This permits a function to first check if it's possible to allocate a -new dma_config and then pass it directly to __stmmac_open and "open" the -interface with the new configuration. - -Signed-off-by: Christian Marangi -Signed-off-by: Jakub Kicinski ---- - .../net/ethernet/stmicro/stmmac/stmmac_main.c | 462 +++++++++++------- - 1 file changed, 289 insertions(+), 173 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -1301,7 +1301,8 @@ static int stmmac_phy_setup(struct stmma - return 0; - } - --static void stmmac_display_rx_rings(struct stmmac_priv *priv) -+static void stmmac_display_rx_rings(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf) - { - u32 rx_cnt = priv->plat->rx_queues_to_use; - unsigned int desc_size; -@@ -1310,7 +1311,7 @@ static void stmmac_display_rx_rings(stru - - /* Display RX rings */ - for (queue = 0; queue < rx_cnt; queue++) { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - - pr_info("\tRX Queue %u rings\n", queue); - -@@ -1323,12 +1324,13 @@ static void stmmac_display_rx_rings(stru - } - - /* Display RX ring */ -- stmmac_display_ring(priv, head_rx, priv->dma_conf.dma_rx_size, true, -+ stmmac_display_ring(priv, head_rx, dma_conf->dma_rx_size, true, - rx_q->dma_rx_phy, desc_size); - } - } - --static void stmmac_display_tx_rings(struct stmmac_priv *priv) -+static void stmmac_display_tx_rings(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf) - { - u32 tx_cnt = priv->plat->tx_queues_to_use; - unsigned int desc_size; -@@ -1337,7 +1339,7 @@ static void stmmac_display_tx_rings(stru - - /* Display TX rings */ - for (queue = 0; queue < tx_cnt; queue++) { -- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue]; - - pr_info("\tTX Queue %d rings\n", queue); - -@@ -1352,18 +1354,19 @@ static void stmmac_display_tx_rings(stru - desc_size = sizeof(struct dma_desc); - } - -- stmmac_display_ring(priv, head_tx, priv->dma_conf.dma_tx_size, false, -+ stmmac_display_ring(priv, head_tx, dma_conf->dma_tx_size, false, - tx_q->dma_tx_phy, desc_size); - } - } - --static void stmmac_display_rings(struct stmmac_priv *priv) -+static void stmmac_display_rings(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf) - { - /* Display RX ring */ -- stmmac_display_rx_rings(priv); -+ stmmac_display_rx_rings(priv, dma_conf); - - /* Display TX ring */ -- stmmac_display_tx_rings(priv); -+ stmmac_display_tx_rings(priv, dma_conf); - } - - static int stmmac_set_bfsize(int mtu, int bufsize) -@@ -1387,44 +1390,50 @@ static int stmmac_set_bfsize(int mtu, in - /** - * stmmac_clear_rx_descriptors - clear RX descriptors - * @priv: driver private structure -+ * @dma_conf: structure to take the dma data - * @queue: RX queue index - * Description: this function is called to clear the RX descriptors - * in case of both basic and extended descriptors are used. - */ --static void stmmac_clear_rx_descriptors(struct stmmac_priv *priv, u32 queue) -+static void stmmac_clear_rx_descriptors(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - int i; - - /* Clear the RX descriptors */ -- for (i = 0; i < priv->dma_conf.dma_rx_size; i++) -+ for (i = 0; i < dma_conf->dma_rx_size; i++) - if (priv->extend_desc) - stmmac_init_rx_desc(priv, &rx_q->dma_erx[i].basic, - priv->use_riwt, priv->mode, -- (i == priv->dma_conf.dma_rx_size - 1), -- priv->dma_conf.dma_buf_sz); -+ (i == dma_conf->dma_rx_size - 1), -+ dma_conf->dma_buf_sz); - else - stmmac_init_rx_desc(priv, &rx_q->dma_rx[i], - priv->use_riwt, priv->mode, -- (i == priv->dma_conf.dma_rx_size - 1), -- priv->dma_conf.dma_buf_sz); -+ (i == dma_conf->dma_rx_size - 1), -+ dma_conf->dma_buf_sz); - } - - /** - * stmmac_clear_tx_descriptors - clear tx descriptors - * @priv: driver private structure -+ * @dma_conf: structure to take the dma data - * @queue: TX queue index. - * Description: this function is called to clear the TX descriptors - * in case of both basic and extended descriptors are used. - */ --static void stmmac_clear_tx_descriptors(struct stmmac_priv *priv, u32 queue) -+static void stmmac_clear_tx_descriptors(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue]; - int i; - - /* Clear the TX descriptors */ -- for (i = 0; i < priv->dma_conf.dma_tx_size; i++) { -- int last = (i == (priv->dma_conf.dma_tx_size - 1)); -+ for (i = 0; i < dma_conf->dma_tx_size; i++) { -+ int last = (i == (dma_conf->dma_tx_size - 1)); - struct dma_desc *p; - - if (priv->extend_desc) -@@ -1441,10 +1450,12 @@ static void stmmac_clear_tx_descriptors( - /** - * stmmac_clear_descriptors - clear descriptors - * @priv: driver private structure -+ * @dma_conf: structure to take the dma data - * Description: this function is called to clear the TX and RX descriptors - * in case of both basic and extended descriptors are used. - */ --static void stmmac_clear_descriptors(struct stmmac_priv *priv) -+static void stmmac_clear_descriptors(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf) - { - u32 rx_queue_cnt = priv->plat->rx_queues_to_use; - u32 tx_queue_cnt = priv->plat->tx_queues_to_use; -@@ -1452,16 +1463,17 @@ static void stmmac_clear_descriptors(str - - /* Clear the RX descriptors */ - for (queue = 0; queue < rx_queue_cnt; queue++) -- stmmac_clear_rx_descriptors(priv, queue); -+ stmmac_clear_rx_descriptors(priv, dma_conf, queue); - - /* Clear the TX descriptors */ - for (queue = 0; queue < tx_queue_cnt; queue++) -- stmmac_clear_tx_descriptors(priv, queue); -+ stmmac_clear_tx_descriptors(priv, dma_conf, queue); - } - - /** - * stmmac_init_rx_buffers - init the RX descriptor buffer. - * @priv: driver private structure -+ * @dma_conf: structure to take the dma data - * @p: descriptor pointer - * @i: descriptor index - * @flags: gfp flag -@@ -1469,10 +1481,12 @@ static void stmmac_clear_descriptors(str - * Description: this function is called to allocate a receive buffer, perform - * the DMA mapping and init the descriptor. - */ --static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, -+static int stmmac_init_rx_buffers(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ struct dma_desc *p, - int i, gfp_t flags, u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; - - if (!buf->page) { -@@ -1497,7 +1511,7 @@ static int stmmac_init_rx_buffers(struct - buf->addr = page_pool_get_dma_addr(buf->page) + buf->page_offset; - - stmmac_set_desc_addr(priv, p, buf->addr); -- if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB) -+ if (dma_conf->dma_buf_sz == BUF_SIZE_16KiB) - stmmac_init_desc3(priv, p); - - return 0; -@@ -1506,12 +1520,13 @@ static int stmmac_init_rx_buffers(struct - /** - * stmmac_free_rx_buffer - free RX dma buffers - * @priv: private structure -- * @queue: RX queue index -+ * @rx_q: RX queue - * @i: buffer index. - */ --static void stmmac_free_rx_buffer(struct stmmac_priv *priv, u32 queue, int i) -+static void stmmac_free_rx_buffer(struct stmmac_priv *priv, -+ struct stmmac_rx_queue *rx_q, -+ int i) - { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; - struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; - - if (buf->page) -@@ -1526,12 +1541,15 @@ static void stmmac_free_rx_buffer(struct - /** - * stmmac_free_tx_buffer - free RX dma buffers - * @priv: private structure -+ * @dma_conf: structure to take the dma data - * @queue: RX queue index - * @i: buffer index. - */ --static void stmmac_free_tx_buffer(struct stmmac_priv *priv, u32 queue, int i) -+static void stmmac_free_tx_buffer(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue, int i) - { -- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue]; - - if (tx_q->tx_skbuff_dma[i].buf && - tx_q->tx_skbuff_dma[i].buf_type != STMMAC_TXBUF_T_XDP_TX) { -@@ -1570,23 +1588,28 @@ static void stmmac_free_tx_buffer(struct - /** - * dma_free_rx_skbufs - free RX dma buffers - * @priv: private structure -+ * @dma_conf: structure to take the dma data - * @queue: RX queue index - */ --static void dma_free_rx_skbufs(struct stmmac_priv *priv, u32 queue) -+static void dma_free_rx_skbufs(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - int i; - -- for (i = 0; i < priv->dma_conf.dma_rx_size; i++) -- stmmac_free_rx_buffer(priv, queue, i); -+ for (i = 0; i < dma_conf->dma_rx_size; i++) -+ stmmac_free_rx_buffer(priv, rx_q, i); - } - --static int stmmac_alloc_rx_buffers(struct stmmac_priv *priv, u32 queue, -- gfp_t flags) -+static int stmmac_alloc_rx_buffers(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue, gfp_t flags) - { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - int i; - -- for (i = 0; i < priv->dma_conf.dma_rx_size; i++) { -+ for (i = 0; i < dma_conf->dma_rx_size; i++) { - struct dma_desc *p; - int ret; - -@@ -1595,7 +1618,7 @@ static int stmmac_alloc_rx_buffers(struc - else - p = rx_q->dma_rx + i; - -- ret = stmmac_init_rx_buffers(priv, p, i, flags, -+ ret = stmmac_init_rx_buffers(priv, dma_conf, p, i, flags, - queue); - if (ret) - return ret; -@@ -1609,14 +1632,17 @@ static int stmmac_alloc_rx_buffers(struc - /** - * dma_free_rx_xskbufs - free RX dma buffers from XSK pool - * @priv: private structure -+ * @dma_conf: structure to take the dma data - * @queue: RX queue index - */ --static void dma_free_rx_xskbufs(struct stmmac_priv *priv, u32 queue) -+static void dma_free_rx_xskbufs(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - int i; - -- for (i = 0; i < priv->dma_conf.dma_rx_size; i++) { -+ for (i = 0; i < dma_conf->dma_rx_size; i++) { - struct stmmac_rx_buffer *buf = &rx_q->buf_pool[i]; - - if (!buf->xdp) -@@ -1627,12 +1653,14 @@ static void dma_free_rx_xskbufs(struct s - } - } - --static int stmmac_alloc_rx_buffers_zc(struct stmmac_priv *priv, u32 queue) -+static int stmmac_alloc_rx_buffers_zc(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - int i; - -- for (i = 0; i < priv->dma_conf.dma_rx_size; i++) { -+ for (i = 0; i < dma_conf->dma_rx_size; i++) { - struct stmmac_rx_buffer *buf; - dma_addr_t dma_addr; - struct dma_desc *p; -@@ -1667,22 +1695,25 @@ static struct xsk_buff_pool *stmmac_get_ - /** - * __init_dma_rx_desc_rings - init the RX descriptor ring (per queue) - * @priv: driver private structure -+ * @dma_conf: structure to take the dma data - * @queue: RX queue index - * @flags: gfp flag. - * Description: this function initializes the DMA RX descriptors - * and allocates the socket buffers. It supports the chained and ring - * modes. - */ --static int __init_dma_rx_desc_rings(struct stmmac_priv *priv, u32 queue, gfp_t flags) -+static int __init_dma_rx_desc_rings(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue, gfp_t flags) - { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - int ret; - - netif_dbg(priv, probe, priv->dev, - "(%s) dma_rx_phy=0x%08x\n", __func__, - (u32)rx_q->dma_rx_phy); - -- stmmac_clear_rx_descriptors(priv, queue); -+ stmmac_clear_rx_descriptors(priv, dma_conf, queue); - - xdp_rxq_info_unreg_mem_model(&rx_q->xdp_rxq); - -@@ -1709,9 +1740,9 @@ static int __init_dma_rx_desc_rings(stru - /* RX XDP ZC buffer pool may not be populated, e.g. - * xdpsock TX-only. - */ -- stmmac_alloc_rx_buffers_zc(priv, queue); -+ stmmac_alloc_rx_buffers_zc(priv, dma_conf, queue); - } else { -- ret = stmmac_alloc_rx_buffers(priv, queue, flags); -+ ret = stmmac_alloc_rx_buffers(priv, dma_conf, queue, flags); - if (ret < 0) - return -ENOMEM; - } -@@ -1721,17 +1752,19 @@ static int __init_dma_rx_desc_rings(stru - if (priv->extend_desc) - stmmac_mode_init(priv, rx_q->dma_erx, - rx_q->dma_rx_phy, -- priv->dma_conf.dma_rx_size, 1); -+ dma_conf->dma_rx_size, 1); - else - stmmac_mode_init(priv, rx_q->dma_rx, - rx_q->dma_rx_phy, -- priv->dma_conf.dma_rx_size, 0); -+ dma_conf->dma_rx_size, 0); - } - - return 0; - } - --static int init_dma_rx_desc_rings(struct net_device *dev, gfp_t flags) -+static int init_dma_rx_desc_rings(struct net_device *dev, -+ struct stmmac_dma_conf *dma_conf, -+ gfp_t flags) - { - struct stmmac_priv *priv = netdev_priv(dev); - u32 rx_count = priv->plat->rx_queues_to_use; -@@ -1743,7 +1776,7 @@ static int init_dma_rx_desc_rings(struct - "SKB addresses:\nskb\t\tskb data\tdma data\n"); - - for (queue = 0; queue < rx_count; queue++) { -- ret = __init_dma_rx_desc_rings(priv, queue, flags); -+ ret = __init_dma_rx_desc_rings(priv, dma_conf, queue, flags); - if (ret) - goto err_init_rx_buffers; - } -@@ -1752,12 +1785,12 @@ static int init_dma_rx_desc_rings(struct - - err_init_rx_buffers: - while (queue >= 0) { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - - if (rx_q->xsk_pool) -- dma_free_rx_xskbufs(priv, queue); -+ dma_free_rx_xskbufs(priv, dma_conf, queue); - else -- dma_free_rx_skbufs(priv, queue); -+ dma_free_rx_skbufs(priv, dma_conf, queue); - - rx_q->buf_alloc_num = 0; - rx_q->xsk_pool = NULL; -@@ -1774,14 +1807,17 @@ err_init_rx_buffers: - /** - * __init_dma_tx_desc_rings - init the TX descriptor ring (per queue) - * @priv: driver private structure -- * @queue : TX queue index -+ * @dma_conf: structure to take the dma data -+ * @queue: TX queue index - * Description: this function initializes the DMA TX descriptors - * and allocates the socket buffers. It supports the chained and ring - * modes. - */ --static int __init_dma_tx_desc_rings(struct stmmac_priv *priv, u32 queue) -+static int __init_dma_tx_desc_rings(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue]; - int i; - - netif_dbg(priv, probe, priv->dev, -@@ -1793,16 +1829,16 @@ static int __init_dma_tx_desc_rings(stru - if (priv->extend_desc) - stmmac_mode_init(priv, tx_q->dma_etx, - tx_q->dma_tx_phy, -- priv->dma_conf.dma_tx_size, 1); -+ dma_conf->dma_tx_size, 1); - else if (!(tx_q->tbs & STMMAC_TBS_AVAIL)) - stmmac_mode_init(priv, tx_q->dma_tx, - tx_q->dma_tx_phy, -- priv->dma_conf.dma_tx_size, 0); -+ dma_conf->dma_tx_size, 0); - } - - tx_q->xsk_pool = stmmac_get_xsk_pool(priv, queue); - -- for (i = 0; i < priv->dma_conf.dma_tx_size; i++) { -+ for (i = 0; i < dma_conf->dma_tx_size; i++) { - struct dma_desc *p; - - if (priv->extend_desc) -@@ -1824,7 +1860,8 @@ static int __init_dma_tx_desc_rings(stru - return 0; - } - --static int init_dma_tx_desc_rings(struct net_device *dev) -+static int init_dma_tx_desc_rings(struct net_device *dev, -+ struct stmmac_dma_conf *dma_conf) - { - struct stmmac_priv *priv = netdev_priv(dev); - u32 tx_queue_cnt; -@@ -1833,7 +1870,7 @@ static int init_dma_tx_desc_rings(struct - tx_queue_cnt = priv->plat->tx_queues_to_use; - - for (queue = 0; queue < tx_queue_cnt; queue++) -- __init_dma_tx_desc_rings(priv, queue); -+ __init_dma_tx_desc_rings(priv, dma_conf, queue); - - return 0; - } -@@ -1841,26 +1878,29 @@ static int init_dma_tx_desc_rings(struct - /** - * init_dma_desc_rings - init the RX/TX descriptor rings - * @dev: net device structure -+ * @dma_conf: structure to take the dma data - * @flags: gfp flag. - * Description: this function initializes the DMA RX/TX descriptors - * and allocates the socket buffers. It supports the chained and ring - * modes. - */ --static int init_dma_desc_rings(struct net_device *dev, gfp_t flags) -+static int init_dma_desc_rings(struct net_device *dev, -+ struct stmmac_dma_conf *dma_conf, -+ gfp_t flags) - { - struct stmmac_priv *priv = netdev_priv(dev); - int ret; - -- ret = init_dma_rx_desc_rings(dev, flags); -+ ret = init_dma_rx_desc_rings(dev, dma_conf, flags); - if (ret) - return ret; - -- ret = init_dma_tx_desc_rings(dev); -+ ret = init_dma_tx_desc_rings(dev, dma_conf); - -- stmmac_clear_descriptors(priv); -+ stmmac_clear_descriptors(priv, dma_conf); - - if (netif_msg_hw(priv)) -- stmmac_display_rings(priv); -+ stmmac_display_rings(priv, dma_conf); - - return ret; - } -@@ -1868,17 +1908,20 @@ static int init_dma_desc_rings(struct ne - /** - * dma_free_tx_skbufs - free TX dma buffers - * @priv: private structure -+ * @dma_conf: structure to take the dma data - * @queue: TX queue index - */ --static void dma_free_tx_skbufs(struct stmmac_priv *priv, u32 queue) -+static void dma_free_tx_skbufs(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue]; - int i; - - tx_q->xsk_frames_done = 0; - -- for (i = 0; i < priv->dma_conf.dma_tx_size; i++) -- stmmac_free_tx_buffer(priv, queue, i); -+ for (i = 0; i < dma_conf->dma_tx_size; i++) -+ stmmac_free_tx_buffer(priv, dma_conf, queue, i); - - if (tx_q->xsk_pool && tx_q->xsk_frames_done) { - xsk_tx_completed(tx_q->xsk_pool, tx_q->xsk_frames_done); -@@ -1897,34 +1940,37 @@ static void stmmac_free_tx_skbufs(struct - u32 queue; - - for (queue = 0; queue < tx_queue_cnt; queue++) -- dma_free_tx_skbufs(priv, queue); -+ dma_free_tx_skbufs(priv, &priv->dma_conf, queue); - } - - /** - * __free_dma_rx_desc_resources - free RX dma desc resources (per queue) - * @priv: private structure -+ * @dma_conf: structure to take the dma data - * @queue: RX queue index - */ --static void __free_dma_rx_desc_resources(struct stmmac_priv *priv, u32 queue) -+static void __free_dma_rx_desc_resources(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - - /* Release the DMA RX socket buffers */ - if (rx_q->xsk_pool) -- dma_free_rx_xskbufs(priv, queue); -+ dma_free_rx_xskbufs(priv, dma_conf, queue); - else -- dma_free_rx_skbufs(priv, queue); -+ dma_free_rx_skbufs(priv, dma_conf, queue); - - rx_q->buf_alloc_num = 0; - rx_q->xsk_pool = NULL; - - /* Free DMA regions of consistent memory previously allocated */ - if (!priv->extend_desc) -- dma_free_coherent(priv->device, priv->dma_conf.dma_rx_size * -+ dma_free_coherent(priv->device, dma_conf->dma_rx_size * - sizeof(struct dma_desc), - rx_q->dma_rx, rx_q->dma_rx_phy); - else -- dma_free_coherent(priv->device, priv->dma_conf.dma_rx_size * -+ dma_free_coherent(priv->device, dma_conf->dma_rx_size * - sizeof(struct dma_extended_desc), - rx_q->dma_erx, rx_q->dma_rx_phy); - -@@ -1936,29 +1982,33 @@ static void __free_dma_rx_desc_resources - page_pool_destroy(rx_q->page_pool); - } - --static void free_dma_rx_desc_resources(struct stmmac_priv *priv) -+static void free_dma_rx_desc_resources(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf) - { - u32 rx_count = priv->plat->rx_queues_to_use; - u32 queue; - - /* Free RX queue resources */ - for (queue = 0; queue < rx_count; queue++) -- __free_dma_rx_desc_resources(priv, queue); -+ __free_dma_rx_desc_resources(priv, dma_conf, queue); - } - - /** - * __free_dma_tx_desc_resources - free TX dma desc resources (per queue) - * @priv: private structure -+ * @dma_conf: structure to take the dma data - * @queue: TX queue index - */ --static void __free_dma_tx_desc_resources(struct stmmac_priv *priv, u32 queue) -+static void __free_dma_tx_desc_resources(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue]; - size_t size; - void *addr; - - /* Release the DMA TX socket buffers */ -- dma_free_tx_skbufs(priv, queue); -+ dma_free_tx_skbufs(priv, dma_conf, queue); - - if (priv->extend_desc) { - size = sizeof(struct dma_extended_desc); -@@ -1971,7 +2021,7 @@ static void __free_dma_tx_desc_resources - addr = tx_q->dma_tx; - } - -- size *= priv->dma_conf.dma_tx_size; -+ size *= dma_conf->dma_tx_size; - - dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy); - -@@ -1979,28 +2029,32 @@ static void __free_dma_tx_desc_resources - kfree(tx_q->tx_skbuff); - } - --static void free_dma_tx_desc_resources(struct stmmac_priv *priv) -+static void free_dma_tx_desc_resources(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf) - { - u32 tx_count = priv->plat->tx_queues_to_use; - u32 queue; - - /* Free TX queue resources */ - for (queue = 0; queue < tx_count; queue++) -- __free_dma_tx_desc_resources(priv, queue); -+ __free_dma_tx_desc_resources(priv, dma_conf, queue); - } - - /** - * __alloc_dma_rx_desc_resources - alloc RX resources (per queue). - * @priv: private structure -+ * @dma_conf: structure to take the dma data - * @queue: RX queue index - * Description: according to which descriptor can be used (extend or basic) - * this function allocates the resources for TX and RX paths. In case of - * reception, for example, it pre-allocated the RX socket buffer in order to - * allow zero-copy mechanism. - */ --static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, u32 queue) -+static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -- struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue]; -+ struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue]; - struct stmmac_channel *ch = &priv->channel[queue]; - bool xdp_prog = stmmac_xdp_is_enabled(priv); - struct page_pool_params pp_params = { 0 }; -@@ -2012,8 +2066,8 @@ static int __alloc_dma_rx_desc_resources - rx_q->priv_data = priv; - - pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV; -- pp_params.pool_size = priv->dma_conf.dma_rx_size; -- num_pages = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE); -+ pp_params.pool_size = dma_conf->dma_rx_size; -+ num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE); - pp_params.order = ilog2(num_pages); - pp_params.nid = dev_to_node(priv->device); - pp_params.dev = priv->device; -@@ -2028,7 +2082,7 @@ static int __alloc_dma_rx_desc_resources - return ret; - } - -- rx_q->buf_pool = kcalloc(priv->dma_conf.dma_rx_size, -+ rx_q->buf_pool = kcalloc(dma_conf->dma_rx_size, - sizeof(*rx_q->buf_pool), - GFP_KERNEL); - if (!rx_q->buf_pool) -@@ -2036,7 +2090,7 @@ static int __alloc_dma_rx_desc_resources - - if (priv->extend_desc) { - rx_q->dma_erx = dma_alloc_coherent(priv->device, -- priv->dma_conf.dma_rx_size * -+ dma_conf->dma_rx_size * - sizeof(struct dma_extended_desc), - &rx_q->dma_rx_phy, - GFP_KERNEL); -@@ -2045,7 +2099,7 @@ static int __alloc_dma_rx_desc_resources - - } else { - rx_q->dma_rx = dma_alloc_coherent(priv->device, -- priv->dma_conf.dma_rx_size * -+ dma_conf->dma_rx_size * - sizeof(struct dma_desc), - &rx_q->dma_rx_phy, - GFP_KERNEL); -@@ -2070,7 +2124,8 @@ static int __alloc_dma_rx_desc_resources - return 0; - } - --static int alloc_dma_rx_desc_resources(struct stmmac_priv *priv) -+static int alloc_dma_rx_desc_resources(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf) - { - u32 rx_count = priv->plat->rx_queues_to_use; - u32 queue; -@@ -2078,7 +2133,7 @@ static int alloc_dma_rx_desc_resources(s - - /* RX queues buffers and DMA */ - for (queue = 0; queue < rx_count; queue++) { -- ret = __alloc_dma_rx_desc_resources(priv, queue); -+ ret = __alloc_dma_rx_desc_resources(priv, dma_conf, queue); - if (ret) - goto err_dma; - } -@@ -2086,7 +2141,7 @@ static int alloc_dma_rx_desc_resources(s - return 0; - - err_dma: -- free_dma_rx_desc_resources(priv); -+ free_dma_rx_desc_resources(priv, dma_conf); - - return ret; - } -@@ -2094,28 +2149,31 @@ err_dma: - /** - * __alloc_dma_tx_desc_resources - alloc TX resources (per queue). - * @priv: private structure -+ * @dma_conf: structure to take the dma data - * @queue: TX queue index - * Description: according to which descriptor can be used (extend or basic) - * this function allocates the resources for TX and RX paths. In case of - * reception, for example, it pre-allocated the RX socket buffer in order to - * allow zero-copy mechanism. - */ --static int __alloc_dma_tx_desc_resources(struct stmmac_priv *priv, u32 queue) -+static int __alloc_dma_tx_desc_resources(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf, -+ u32 queue) - { -- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; -+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue]; - size_t size; - void *addr; - - tx_q->queue_index = queue; - tx_q->priv_data = priv; - -- tx_q->tx_skbuff_dma = kcalloc(priv->dma_conf.dma_tx_size, -+ tx_q->tx_skbuff_dma = kcalloc(dma_conf->dma_tx_size, - sizeof(*tx_q->tx_skbuff_dma), - GFP_KERNEL); - if (!tx_q->tx_skbuff_dma) - return -ENOMEM; - -- tx_q->tx_skbuff = kcalloc(priv->dma_conf.dma_tx_size, -+ tx_q->tx_skbuff = kcalloc(dma_conf->dma_tx_size, - sizeof(struct sk_buff *), - GFP_KERNEL); - if (!tx_q->tx_skbuff) -@@ -2128,7 +2186,7 @@ static int __alloc_dma_tx_desc_resources - else - size = sizeof(struct dma_desc); - -- size *= priv->dma_conf.dma_tx_size; -+ size *= dma_conf->dma_tx_size; - - addr = dma_alloc_coherent(priv->device, size, - &tx_q->dma_tx_phy, GFP_KERNEL); -@@ -2145,7 +2203,8 @@ static int __alloc_dma_tx_desc_resources - return 0; - } - --static int alloc_dma_tx_desc_resources(struct stmmac_priv *priv) -+static int alloc_dma_tx_desc_resources(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf) - { - u32 tx_count = priv->plat->tx_queues_to_use; - u32 queue; -@@ -2153,7 +2212,7 @@ static int alloc_dma_tx_desc_resources(s - - /* TX queues buffers and DMA */ - for (queue = 0; queue < tx_count; queue++) { -- ret = __alloc_dma_tx_desc_resources(priv, queue); -+ ret = __alloc_dma_tx_desc_resources(priv, dma_conf, queue); - if (ret) - goto err_dma; - } -@@ -2161,27 +2220,29 @@ static int alloc_dma_tx_desc_resources(s - return 0; - - err_dma: -- free_dma_tx_desc_resources(priv); -+ free_dma_tx_desc_resources(priv, dma_conf); - return ret; - } - - /** - * alloc_dma_desc_resources - alloc TX/RX resources. - * @priv: private structure -+ * @dma_conf: structure to take the dma data - * Description: according to which descriptor can be used (extend or basic) - * this function allocates the resources for TX and RX paths. In case of - * reception, for example, it pre-allocated the RX socket buffer in order to - * allow zero-copy mechanism. - */ --static int alloc_dma_desc_resources(struct stmmac_priv *priv) -+static int alloc_dma_desc_resources(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf) - { - /* RX Allocation */ -- int ret = alloc_dma_rx_desc_resources(priv); -+ int ret = alloc_dma_rx_desc_resources(priv, dma_conf); - - if (ret) - return ret; - -- ret = alloc_dma_tx_desc_resources(priv); -+ ret = alloc_dma_tx_desc_resources(priv, dma_conf); - - return ret; - } -@@ -2189,16 +2250,18 @@ static int alloc_dma_desc_resources(stru - /** - * free_dma_desc_resources - free dma desc resources - * @priv: private structure -+ * @dma_conf: structure to take the dma data - */ --static void free_dma_desc_resources(struct stmmac_priv *priv) -+static void free_dma_desc_resources(struct stmmac_priv *priv, -+ struct stmmac_dma_conf *dma_conf) - { - /* Release the DMA TX socket buffers */ -- free_dma_tx_desc_resources(priv); -+ free_dma_tx_desc_resources(priv, dma_conf); - - /* Release the DMA RX socket buffers later - * to ensure all pending XDP_TX buffers are returned. - */ -- free_dma_rx_desc_resources(priv); -+ free_dma_rx_desc_resources(priv, dma_conf); - } - - /** -@@ -2687,8 +2750,8 @@ static void stmmac_tx_err(struct stmmac_ - netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, chan)); - - stmmac_stop_tx_dma(priv, chan); -- dma_free_tx_skbufs(priv, chan); -- stmmac_clear_tx_descriptors(priv, chan); -+ dma_free_tx_skbufs(priv, &priv->dma_conf, chan); -+ stmmac_clear_tx_descriptors(priv, &priv->dma_conf, chan); - stmmac_reset_tx_queue(priv, chan); - stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, - tx_q->dma_tx_phy, chan); -@@ -3686,19 +3749,93 @@ static int stmmac_request_irq(struct net - } - - /** -- * stmmac_open - open entry point of the driver -+ * stmmac_setup_dma_desc - Generate a dma_conf and allocate DMA queue -+ * @priv: driver private structure -+ * @mtu: MTU to setup the dma queue and buf with -+ * Description: Allocate and generate a dma_conf based on the provided MTU. -+ * Allocate the Tx/Rx DMA queue and init them. -+ * Return value: -+ * the dma_conf allocated struct on success and an appropriate ERR_PTR on failure. -+ */ -+static struct stmmac_dma_conf * -+stmmac_setup_dma_desc(struct stmmac_priv *priv, unsigned int mtu) -+{ -+ struct stmmac_dma_conf *dma_conf; -+ int chan, bfsize, ret; -+ -+ dma_conf = kzalloc(sizeof(*dma_conf), GFP_KERNEL); -+ if (!dma_conf) { -+ netdev_err(priv->dev, "%s: DMA conf allocation failed\n", -+ __func__); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ bfsize = stmmac_set_16kib_bfsize(priv, mtu); -+ if (bfsize < 0) -+ bfsize = 0; -+ -+ if (bfsize < BUF_SIZE_16KiB) -+ bfsize = stmmac_set_bfsize(mtu, 0); -+ -+ dma_conf->dma_buf_sz = bfsize; -+ /* Chose the tx/rx size from the already defined one in the -+ * priv struct. (if defined) -+ */ -+ dma_conf->dma_tx_size = priv->dma_conf.dma_tx_size; -+ dma_conf->dma_rx_size = priv->dma_conf.dma_rx_size; -+ -+ if (!dma_conf->dma_tx_size) -+ dma_conf->dma_tx_size = DMA_DEFAULT_TX_SIZE; -+ if (!dma_conf->dma_rx_size) -+ dma_conf->dma_rx_size = DMA_DEFAULT_RX_SIZE; -+ -+ /* Earlier check for TBS */ -+ for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) { -+ struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[chan]; -+ int tbs_en = priv->plat->tx_queues_cfg[chan].tbs_en; -+ -+ /* Setup per-TXQ tbs flag before TX descriptor alloc */ -+ tx_q->tbs |= tbs_en ? STMMAC_TBS_AVAIL : 0; -+ } -+ -+ ret = alloc_dma_desc_resources(priv, dma_conf); -+ if (ret < 0) { -+ netdev_err(priv->dev, "%s: DMA descriptors allocation failed\n", -+ __func__); -+ goto alloc_error; -+ } -+ -+ ret = init_dma_desc_rings(priv->dev, dma_conf, GFP_KERNEL); -+ if (ret < 0) { -+ netdev_err(priv->dev, "%s: DMA descriptors initialization failed\n", -+ __func__); -+ goto init_error; -+ } -+ -+ return dma_conf; -+ -+init_error: -+ free_dma_desc_resources(priv, dma_conf); -+alloc_error: -+ kfree(dma_conf); -+ return ERR_PTR(ret); -+} -+ -+/** -+ * __stmmac_open - open entry point of the driver - * @dev : pointer to the device structure. -+ * @dma_conf : structure to take the dma data - * Description: - * This function is the open entry point of the driver. - * Return value: - * 0 on success and an appropriate (-)ve integer as defined in errno.h - * file on failure. - */ --static int stmmac_open(struct net_device *dev) -+static int __stmmac_open(struct net_device *dev, -+ struct stmmac_dma_conf *dma_conf) - { - struct stmmac_priv *priv = netdev_priv(dev); - int mode = priv->plat->phy_interface; -- int bfsize = 0; - u32 chan; - int ret; - -@@ -3725,45 +3862,10 @@ static int stmmac_open(struct net_device - memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); - priv->xstats.threshold = tc; - -- bfsize = stmmac_set_16kib_bfsize(priv, dev->mtu); -- if (bfsize < 0) -- bfsize = 0; -- -- if (bfsize < BUF_SIZE_16KiB) -- bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_conf.dma_buf_sz); -- -- priv->dma_conf.dma_buf_sz = bfsize; -- buf_sz = bfsize; -- - priv->rx_copybreak = STMMAC_RX_COPYBREAK; - -- if (!priv->dma_conf.dma_tx_size) -- priv->dma_conf.dma_tx_size = DMA_DEFAULT_TX_SIZE; -- if (!priv->dma_conf.dma_rx_size) -- priv->dma_conf.dma_rx_size = DMA_DEFAULT_RX_SIZE; -- -- /* Earlier check for TBS */ -- for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) { -- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan]; -- int tbs_en = priv->plat->tx_queues_cfg[chan].tbs_en; -- -- /* Setup per-TXQ tbs flag before TX descriptor alloc */ -- tx_q->tbs |= tbs_en ? STMMAC_TBS_AVAIL : 0; -- } -- -- ret = alloc_dma_desc_resources(priv); -- if (ret < 0) { -- netdev_err(priv->dev, "%s: DMA descriptors allocation failed\n", -- __func__); -- goto dma_desc_error; -- } -- -- ret = init_dma_desc_rings(dev, GFP_KERNEL); -- if (ret < 0) { -- netdev_err(priv->dev, "%s: DMA descriptors initialization failed\n", -- __func__); -- goto init_error; -- } -+ buf_sz = dma_conf->dma_buf_sz; -+ memcpy(&priv->dma_conf, dma_conf, sizeof(*dma_conf)); - - if (priv->plat->serdes_powerup) { - ret = priv->plat->serdes_powerup(dev, priv->plat->bsp_priv); -@@ -3806,14 +3908,28 @@ irq_error: - - stmmac_hw_teardown(dev); - init_error: -- free_dma_desc_resources(priv); --dma_desc_error: -+ free_dma_desc_resources(priv, &priv->dma_conf); - phylink_disconnect_phy(priv->phylink); - init_phy_error: - pm_runtime_put(priv->device); - return ret; - } - -+static int stmmac_open(struct net_device *dev) -+{ -+ struct stmmac_priv *priv = netdev_priv(dev); -+ struct stmmac_dma_conf *dma_conf; -+ int ret; -+ -+ dma_conf = stmmac_setup_dma_desc(priv, dev->mtu); -+ if (IS_ERR(dma_conf)) -+ return PTR_ERR(dma_conf); -+ -+ ret = __stmmac_open(dev, dma_conf); -+ kfree(dma_conf); -+ return ret; -+} -+ - static void stmmac_fpe_stop_wq(struct stmmac_priv *priv) - { - set_bit(__FPE_REMOVING, &priv->fpe_task_state); -@@ -3862,7 +3978,7 @@ static int stmmac_release(struct net_dev - stmmac_stop_all_dma(priv); - - /* Release and free the Rx/Tx resources */ -- free_dma_desc_resources(priv); -+ free_dma_desc_resources(priv, &priv->dma_conf); - - /* Disable the MAC Rx/Tx */ - stmmac_mac_set(priv, priv->ioaddr, false); -@@ -6385,7 +6501,7 @@ void stmmac_disable_rx_queue(struct stmm - spin_unlock_irqrestore(&ch->lock, flags); - - stmmac_stop_rx_dma(priv, queue); -- __free_dma_rx_desc_resources(priv, queue); -+ __free_dma_rx_desc_resources(priv, &priv->dma_conf, queue); - } - - void stmmac_enable_rx_queue(struct stmmac_priv *priv, u32 queue) -@@ -6396,21 +6512,21 @@ void stmmac_enable_rx_queue(struct stmma - u32 buf_size; - int ret; - -- ret = __alloc_dma_rx_desc_resources(priv, queue); -+ ret = __alloc_dma_rx_desc_resources(priv, &priv->dma_conf, queue); - if (ret) { - netdev_err(priv->dev, "Failed to alloc RX desc.\n"); - return; - } - -- ret = __init_dma_rx_desc_rings(priv, queue, GFP_KERNEL); -+ ret = __init_dma_rx_desc_rings(priv, &priv->dma_conf, queue, GFP_KERNEL); - if (ret) { -- __free_dma_rx_desc_resources(priv, queue); -+ __free_dma_rx_desc_resources(priv, &priv->dma_conf, queue); - netdev_err(priv->dev, "Failed to init RX desc.\n"); - return; - } - - stmmac_reset_rx_queue(priv, queue); -- stmmac_clear_rx_descriptors(priv, queue); -+ stmmac_clear_rx_descriptors(priv, &priv->dma_conf, queue); - - stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, - rx_q->dma_rx_phy, rx_q->queue_index); -@@ -6448,7 +6564,7 @@ void stmmac_disable_tx_queue(struct stmm - spin_unlock_irqrestore(&ch->lock, flags); - - stmmac_stop_tx_dma(priv, queue); -- __free_dma_tx_desc_resources(priv, queue); -+ __free_dma_tx_desc_resources(priv, &priv->dma_conf, queue); - } - - void stmmac_enable_tx_queue(struct stmmac_priv *priv, u32 queue) -@@ -6458,21 +6574,21 @@ void stmmac_enable_tx_queue(struct stmma - unsigned long flags; - int ret; - -- ret = __alloc_dma_tx_desc_resources(priv, queue); -+ ret = __alloc_dma_tx_desc_resources(priv, &priv->dma_conf, queue); - if (ret) { - netdev_err(priv->dev, "Failed to alloc TX desc.\n"); - return; - } - -- ret = __init_dma_tx_desc_rings(priv, queue); -+ ret = __init_dma_tx_desc_rings(priv, &priv->dma_conf, queue); - if (ret) { -- __free_dma_tx_desc_resources(priv, queue); -+ __free_dma_tx_desc_resources(priv, &priv->dma_conf, queue); - netdev_err(priv->dev, "Failed to init TX desc.\n"); - return; - } - - stmmac_reset_tx_queue(priv, queue); -- stmmac_clear_tx_descriptors(priv, queue); -+ stmmac_clear_tx_descriptors(priv, &priv->dma_conf, queue); - - stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, - tx_q->dma_tx_phy, tx_q->queue_index); -@@ -6512,7 +6628,7 @@ void stmmac_xdp_release(struct net_devic - stmmac_stop_all_dma(priv); - - /* Release and free the Rx/Tx resources */ -- free_dma_desc_resources(priv); -+ free_dma_desc_resources(priv, &priv->dma_conf); - - /* Disable the MAC Rx/Tx */ - stmmac_mac_set(priv, priv->ioaddr, false); -@@ -6537,14 +6653,14 @@ int stmmac_xdp_open(struct net_device *d - u32 chan; - int ret; - -- ret = alloc_dma_desc_resources(priv); -+ ret = alloc_dma_desc_resources(priv, &priv->dma_conf); - if (ret < 0) { - netdev_err(dev, "%s: DMA descriptors allocation failed\n", - __func__); - goto dma_desc_error; - } - -- ret = init_dma_desc_rings(dev, GFP_KERNEL); -+ ret = init_dma_desc_rings(dev, &priv->dma_conf, GFP_KERNEL); - if (ret < 0) { - netdev_err(dev, "%s: DMA descriptors initialization failed\n", - __func__); -@@ -6626,7 +6742,7 @@ irq_error: - - stmmac_hw_teardown(dev); - init_error: -- free_dma_desc_resources(priv); -+ free_dma_desc_resources(priv, &priv->dma_conf); - dma_desc_error: - return ret; - } -@@ -7492,7 +7608,7 @@ int stmmac_resume(struct device *dev) - stmmac_reset_queues_param(priv); - - stmmac_free_tx_skbufs(priv); -- stmmac_clear_descriptors(priv); -+ stmmac_clear_descriptors(priv, &priv->dma_conf); - - stmmac_hw_setup(ndev, false); - stmmac_init_coalesce(priv); diff --git a/target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch b/target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch deleted file mode 100644 index e1d46f03a94be7..00000000000000 --- a/target/linux/generic/backport-5.15/775-v6.0-05-net-ethernet-stmicro-stmmac-permit-MTU-change-with-i.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 3470079687448abac42deb62774253be1d6bdef3 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 23 Jul 2022 16:29:33 +0200 -Subject: [PATCH 5/5] net: ethernet: stmicro: stmmac: permit MTU change with - interface up - -Remove the limitation where the interface needs to be down to change -MTU by releasing and opening the stmmac driver to set the new MTU. -Also call the set_filter function to correctly init the port. -This permits to remove the EBUSY error while the ethernet port is -running permitting a correct MTU change if for example a DSA request -a MTU change for a switch CPU port. - -Signed-off-by: Christian Marangi -Signed-off-by: Jakub Kicinski ---- - .../net/ethernet/stmicro/stmmac/stmmac_main.c | 30 +++++++++++++++---- - 1 file changed, 24 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -5627,18 +5627,15 @@ static int stmmac_change_mtu(struct net_ - { - struct stmmac_priv *priv = netdev_priv(dev); - int txfifosz = priv->plat->tx_fifo_size; -+ struct stmmac_dma_conf *dma_conf; - const int mtu = new_mtu; -+ int ret; - - if (txfifosz == 0) - txfifosz = priv->dma_cap.tx_fifo_size; - - txfifosz /= priv->plat->tx_queues_to_use; - -- if (netif_running(dev)) { -- netdev_err(priv->dev, "must be stopped to change its MTU\n"); -- return -EBUSY; -- } -- - if (stmmac_xdp_is_enabled(priv) && new_mtu > ETH_DATA_LEN) { - netdev_dbg(priv->dev, "Jumbo frames not supported for XDP\n"); - return -EINVAL; -@@ -5650,8 +5647,29 @@ static int stmmac_change_mtu(struct net_ - if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB)) - return -EINVAL; - -- dev->mtu = mtu; -+ if (netif_running(dev)) { -+ netdev_dbg(priv->dev, "restarting interface to change its MTU\n"); -+ /* Try to allocate the new DMA conf with the new mtu */ -+ dma_conf = stmmac_setup_dma_desc(priv, mtu); -+ if (IS_ERR(dma_conf)) { -+ netdev_err(priv->dev, "failed allocating new dma conf for new MTU %d\n", -+ mtu); -+ return PTR_ERR(dma_conf); -+ } -+ -+ stmmac_release(dev); -+ -+ ret = __stmmac_open(dev, dma_conf); -+ kfree(dma_conf); -+ if (ret) { -+ netdev_err(priv->dev, "failed reopening the interface after MTU change\n"); -+ return ret; -+ } -+ -+ stmmac_set_rx_mode(dev); -+ } - -+ dev->mtu = mtu; - netdev_update_features(dev); - - return 0; diff --git a/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch b/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch deleted file mode 100644 index 4f0d95f456106a..00000000000000 --- a/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch +++ /dev/null @@ -1,156 +0,0 @@ -From a2550d3ce53c68f54042bc5e468c4d07491ffe0e Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 12 Oct 2022 19:18:36 +0200 -Subject: [PATCH 1/2] net: dsa: qca8k: fix inband mgmt for big-endian systems - -The header and the data of the skb for the inband mgmt requires -to be in little-endian. This is problematic for big-endian system -as the mgmt header is written in the cpu byte order. - -Fix this by converting each value for the mgmt header and data to -little-endian, and convert to cpu byte order the mgmt header and -data sent by the switch. - -Fixes: 5950c7c0a68c ("net: dsa: qca8k: add support for mgmt read/write in Ethernet packet") -Tested-by: Pawel Dembicki -Tested-by: Lech Perczak -Signed-off-by: Christian Marangi -Reviewed-by: Lech Perczak -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 63 ++++++++++++++++++++++++-------- - include/linux/dsa/tag_qca.h | 6 +-- - 2 files changed, 50 insertions(+), 19 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -137,27 +137,42 @@ static void qca8k_rw_reg_ack_handler(str - struct qca8k_mgmt_eth_data *mgmt_eth_data; - struct qca8k_priv *priv = ds->priv; - struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ u32 command; - u8 len, cmd; -+ int i; - - mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); - mgmt_eth_data = &priv->mgmt_eth_data; - -- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); -- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); -+ command = get_unaligned_le32(&mgmt_ethhdr->command); -+ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command); -+ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command); - - /* Make sure the seq match the requested packet */ -- if (mgmt_ethhdr->seq == mgmt_eth_data->seq) -+ if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq) - mgmt_eth_data->ack = true; - - if (cmd == MDIO_READ) { -- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; -+ u32 *val = mgmt_eth_data->data; -+ -+ *val = get_unaligned_le32(&mgmt_ethhdr->mdio_data); - - /* Get the rest of the 12 byte of data. - * The read/write function will extract the requested data. - */ -- if (len > QCA_HDR_MGMT_DATA1_LEN) -- memcpy(mgmt_eth_data->data + 1, skb->data, -- QCA_HDR_MGMT_DATA2_LEN); -+ if (len > QCA_HDR_MGMT_DATA1_LEN) { -+ __le32 *data2 = (__le32 *)skb->data; -+ int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN, -+ len - QCA_HDR_MGMT_DATA1_LEN); -+ -+ val++; -+ -+ for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) { -+ *val = get_unaligned_le32(data2); -+ val++; -+ data2++; -+ } -+ } - } - - complete(&mgmt_eth_data->rw_done); -@@ -169,8 +184,10 @@ static struct sk_buff *qca8k_alloc_mdio_ - struct qca_mgmt_ethhdr *mgmt_ethhdr; - unsigned int real_len; - struct sk_buff *skb; -- u32 *data2; -+ __le32 *data2; -+ u32 command; - u16 hdr; -+ int i; - - skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); - if (!skb) -@@ -199,20 +216,32 @@ static struct sk_buff *qca8k_alloc_mdio_ - hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); - hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); - -- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); -- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); -- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); -- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, -+ command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); -+ command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); -+ command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); -+ command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, - QCA_HDR_MGMT_CHECK_CODE_VAL); - -+ put_unaligned_le32(command, &mgmt_ethhdr->command); -+ - if (cmd == MDIO_WRITE) -- mgmt_ethhdr->mdio_data = *val; -+ put_unaligned_le32(*val, &mgmt_ethhdr->mdio_data); - - mgmt_ethhdr->hdr = htons(hdr); - - data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); -- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) -- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); -+ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) { -+ int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN, -+ len - QCA_HDR_MGMT_DATA1_LEN); -+ -+ val++; -+ -+ for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) { -+ put_unaligned_le32(*val, data2); -+ data2++; -+ val++; -+ } -+ } - - return skb; - } -@@ -220,9 +249,11 @@ static struct sk_buff *qca8k_alloc_mdio_ - static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) - { - struct qca_mgmt_ethhdr *mgmt_ethhdr; -+ u32 seq; - -+ seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); - mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; -- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); -+ put_unaligned_le32(seq, &mgmt_ethhdr->seq); - } - - static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) ---- a/include/linux/dsa/tag_qca.h -+++ b/include/linux/dsa/tag_qca.h -@@ -56,9 +56,9 @@ - - /* Special struct emulating a Ethernet header */ - struct qca_mgmt_ethhdr { -- u32 command; /* command bit 31:0 */ -- u32 seq; /* seq 63:32 */ -- u32 mdio_data; /* first 4byte mdio */ -+ __le32 command; /* command bit 31:0 */ -+ __le32 seq; /* seq 63:32 */ -+ __le32 mdio_data; /* first 4byte mdio */ - __be16 hdr; /* qca hdr */ - } __packed; - diff --git a/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch b/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch deleted file mode 100644 index d13014bf93bdf9..00000000000000 --- a/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 0d4636f7d72df3179b20a2d32b647881917a5e2a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 12 Oct 2022 19:18:37 +0200 -Subject: [PATCH 2/2] net: dsa: qca8k: fix ethtool autocast mib for big-endian - systems - -The switch sends autocast mib in little-endian. This is problematic for -big-endian system as the values needs to be converted. - -Fix this by converting each mib value to cpu byte order. - -Fixes: 5c957c7ca78c ("net: dsa: qca8k: add support for mib autocast in Ethernet packet") -Tested-by: Pawel Dembicki -Tested-by: Lech Perczak -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 20 ++++++++------------ - include/linux/dsa/tag_qca.h | 2 +- - 2 files changed, 9 insertions(+), 13 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1668,9 +1668,9 @@ static void qca8k_mib_autocast_handler(s - struct qca8k_priv *priv = ds->priv; - const struct qca8k_mib_desc *mib; - struct mib_ethhdr *mib_ethhdr; -- int i, mib_len, offset = 0; -- u64 *data; -+ __le32 *data2; - u8 port; -+ int i; - - mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); - mib_eth_data = &priv->mib_eth_data; -@@ -1682,28 +1682,24 @@ static void qca8k_mib_autocast_handler(s - if (port != mib_eth_data->req_port) - goto exit; - -- data = mib_eth_data->data; -+ data2 = (__le32 *)skb->data; - - for (i = 0; i < priv->info->mib_count; i++) { - mib = &ar8327_mib[i]; - - /* First 3 mib are present in the skb head */ - if (i < 3) { -- data[i] = mib_ethhdr->data[i]; -+ mib_eth_data->data[i] = get_unaligned_le32(mib_ethhdr->data + i); - continue; - } - -- mib_len = sizeof(uint32_t); -- - /* Some mib are 64 bit wide */ - if (mib->size == 2) -- mib_len = sizeof(uint64_t); -- -- /* Copy the mib value from packet to the */ -- memcpy(data + i, skb->data + offset, mib_len); -+ mib_eth_data->data[i] = get_unaligned_le64((__le64 *)data2); -+ else -+ mib_eth_data->data[i] = get_unaligned_le32(data2); - -- /* Set the offset for the next mib */ -- offset += mib_len; -+ data2 += mib->size; - } - - exit: ---- a/include/linux/dsa/tag_qca.h -+++ b/include/linux/dsa/tag_qca.h -@@ -68,7 +68,7 @@ enum mdio_cmd { - }; - - struct mib_ethhdr { -- u32 data[3]; /* first 3 mib counter */ -+ __le32 data[3]; /* first 3 mib counter */ - __be16 hdr; /* qca hdr */ - } __packed; - diff --git a/target/linux/generic/backport-5.15/777-v6.2-01-net-dsa-qca8k-fix-wrong-length-value-for-mgmt-eth-pa.patch b/target/linux/generic/backport-5.15/777-v6.2-01-net-dsa-qca8k-fix-wrong-length-value-for-mgmt-eth-pa.patch deleted file mode 100644 index b61e7ede494652..00000000000000 --- a/target/linux/generic/backport-5.15/777-v6.2-01-net-dsa-qca8k-fix-wrong-length-value-for-mgmt-eth-pa.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 9807ae69746196ee4bbffe7d22d22ab2b61c6ed0 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 29 Dec 2022 17:33:32 +0100 -Subject: [PATCH 1/5] net: dsa: qca8k: fix wrong length value for mgmt eth - packet - -The assumption that Documentation was right about how this value work was -wrong. It was discovered that the length value of the mgmt header is in -step of word size. - -As an example to process 4 byte of data the correct length to set is 2. -To process 8 byte 4, 12 byte 6, 16 byte 8... - -Odd values will always return the next size on the ack packet. -(length of 3 (6 byte) will always return 8 bytes of data) - -This means that a value of 15 (0xf) actually means reading/writing 32 bytes -of data instead of 16 bytes. This behaviour is totally absent and not -documented in the switch Documentation. - -In fact from Documentation the max value that mgmt eth can process is -16 byte of data while in reality it can process 32 bytes at once. - -To handle this we always round up the length after deviding it for word -size. We check if the result is odd and we round another time to align -to what the switch will provide in the ack packet. -The workaround for the length limit of 15 is still needed as the length -reg max value is 0xf(15) - -Reported-by: Ronald Wahl -Tested-by: Ronald Wahl -Fixes: 90386223f44e ("net: dsa: qca8k: add support for larger read/write size with mgmt Ethernet") -Signed-off-by: Christian Marangi -Cc: stable@vger.kernel.org # v5.18+ -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 45 +++++++++++++++++++++++++------- - 1 file changed, 35 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -146,7 +146,16 @@ static void qca8k_rw_reg_ack_handler(str - - command = get_unaligned_le32(&mgmt_ethhdr->command); - cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command); -+ - len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command); -+ /* Special case for len of 15 as this is the max value for len and needs to -+ * be increased before converting it from word to dword. -+ */ -+ if (len == 15) -+ len++; -+ -+ /* We can ignore odd value, we always round up them in the alloc function. */ -+ len *= sizeof(u16); - - /* Make sure the seq match the requested packet */ - if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq) -@@ -193,17 +202,33 @@ static struct sk_buff *qca8k_alloc_mdio_ - if (!skb) - return NULL; - -- /* Max value for len reg is 15 (0xf) but the switch actually return 16 byte -- * Actually for some reason the steps are: -- * 0: nothing -- * 1-4: first 4 byte -- * 5-6: first 12 byte -- * 7-15: all 16 byte -+ /* Hdr mgmt length value is in step of word size. -+ * As an example to process 4 byte of data the correct length to set is 2. -+ * To process 8 byte 4, 12 byte 6, 16 byte 8... -+ * -+ * Odd values will always return the next size on the ack packet. -+ * (length of 3 (6 byte) will always return 8 bytes of data) -+ * -+ * This means that a value of 15 (0xf) actually means reading/writing 32 bytes -+ * of data. -+ * -+ * To correctly calculate the length we devide the requested len by word and -+ * round up. -+ * On the ack function we can skip the odd check as we already handle the -+ * case here. - */ -- if (len == 16) -- real_len = 15; -- else -- real_len = len; -+ real_len = DIV_ROUND_UP(len, sizeof(u16)); -+ -+ /* We check if the result len is odd and we round up another time to -+ * the next size. (length of 3 will be increased to 4 as switch will always -+ * return 8 bytes) -+ */ -+ if (real_len % sizeof(u16) != 0) -+ real_len++; -+ -+ /* Max reg value is 0xf(15) but switch will always return the next size (32 byte) */ -+ if (real_len == 16) -+ real_len--; - - skb_reset_mac_header(skb); - skb_set_network_header(skb, skb->len); diff --git a/target/linux/generic/backport-5.15/777-v6.2-02-net-dsa-tag_qca-fix-wrong-MGMT_DATA2-size.patch b/target/linux/generic/backport-5.15/777-v6.2-02-net-dsa-tag_qca-fix-wrong-MGMT_DATA2-size.patch deleted file mode 100644 index 55ecb1eb42e7cd..00000000000000 --- a/target/linux/generic/backport-5.15/777-v6.2-02-net-dsa-tag_qca-fix-wrong-MGMT_DATA2-size.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d9dba91be71f03cc75bcf39fc0d5d99ff33f1ae0 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 29 Dec 2022 17:33:33 +0100 -Subject: [PATCH 2/5] net: dsa: tag_qca: fix wrong MGMT_DATA2 size - -It was discovered that MGMT_DATA2 can contain up to 28 bytes of data -instead of the 12 bytes written in the Documentation by accounting the -limit of 16 bytes declared in Documentation subtracting the first 4 byte -in the packet header. - -Update the define with the real world value. - -Tested-by: Ronald Wahl -Fixes: c2ee8181fddb ("net: dsa: tag_qca: add define for handling mgmt Ethernet packet") -Signed-off-by: Christian Marangi -Cc: stable@vger.kernel.org # v5.18+ -Signed-off-by: David S. Miller ---- - include/linux/dsa/tag_qca.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/include/linux/dsa/tag_qca.h -+++ b/include/linux/dsa/tag_qca.h -@@ -40,8 +40,8 @@ - QCA_HDR_MGMT_COMMAND_LEN + \ - QCA_HDR_MGMT_DATA1_LEN) - --#define QCA_HDR_MGMT_DATA2_LEN 12 /* Other 12 byte for the mdio data */ --#define QCA_HDR_MGMT_PADDING_LEN 34 /* Padding to reach the min Ethernet packet */ -+#define QCA_HDR_MGMT_DATA2_LEN 28 /* Other 28 byte for the mdio data */ -+#define QCA_HDR_MGMT_PADDING_LEN 18 /* Padding to reach the min Ethernet packet */ - - #define QCA_HDR_MGMT_PKT_LEN (QCA_HDR_MGMT_HEADER_LEN + \ - QCA_HDR_LEN + \ diff --git a/target/linux/generic/backport-5.15/777-v6.2-03-Revert-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch b/target/linux/generic/backport-5.15/777-v6.2-03-Revert-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch deleted file mode 100644 index c8e22fd1b815f7..00000000000000 --- a/target/linux/generic/backport-5.15/777-v6.2-03-Revert-net-dsa-qca8k-cache-lo-and-hi-for-mdio-write.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 03cb9e6d0b32b768e3d9d473c5c4ca1100877664 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 29 Dec 2022 17:33:34 +0100 -Subject: [PATCH 3/5] Revert "net: dsa: qca8k: cache lo and hi for mdio write" - -This reverts commit 2481d206fae7884cd07014fd1318e63af35e99eb. - -The Documentation is very confusing about the topic. -The cache logic for hi and lo is wrong and actually miss some regs to be -actually written. - -What the Documentation actually intended was that it's possible to skip -writing hi OR lo if half of the reg is not needed to be written or read. - -Revert the change in favor of a better and correct implementation. - -Reported-by: Ronald Wahl -Signed-off-by: Christian Marangi -Cc: stable@vger.kernel.org # v5.18+ -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 61 +++++++------------------------- - drivers/net/dsa/qca/qca8k.h | 5 --- - 2 files changed, 12 insertions(+), 54 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -37,44 +37,6 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u - } - - static int --qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo) --{ -- u16 *cached_lo = &priv->mdio_cache.lo; -- struct mii_bus *bus = priv->bus; -- int ret; -- -- if (lo == *cached_lo) -- return 0; -- -- ret = bus->write(bus, phy_id, regnum, lo); -- if (ret < 0) -- dev_err_ratelimited(&bus->dev, -- "failed to write qca8k 32bit lo register\n"); -- -- *cached_lo = lo; -- return 0; --} -- --static int --qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi) --{ -- u16 *cached_hi = &priv->mdio_cache.hi; -- struct mii_bus *bus = priv->bus; -- int ret; -- -- if (hi == *cached_hi) -- return 0; -- -- ret = bus->write(bus, phy_id, regnum, hi); -- if (ret < 0) -- dev_err_ratelimited(&bus->dev, -- "failed to write qca8k 32bit hi register\n"); -- -- *cached_hi = hi; -- return 0; --} -- --static int - qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) - { - int ret; -@@ -97,7 +59,7 @@ qca8k_mii_read32(struct mii_bus *bus, in - } - - static void --qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val) -+qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) - { - u16 lo, hi; - int ret; -@@ -105,9 +67,12 @@ qca8k_mii_write32(struct qca8k_priv *pri - lo = val & 0xffff; - hi = (u16)(val >> 16); - -- ret = qca8k_set_lo(priv, phy_id, regnum, lo); -+ ret = bus->write(bus, phy_id, regnum, lo); - if (ret >= 0) -- ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi); -+ ret = bus->write(bus, phy_id, regnum + 1, hi); -+ if (ret < 0) -+ dev_err_ratelimited(&bus->dev, -+ "failed to write qca8k 32bit register\n"); - } - - static int -@@ -442,7 +407,7 @@ qca8k_regmap_write(void *ctx, uint32_t r - if (ret < 0) - goto exit; - -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ qca8k_mii_write32(bus, 0x10 | r2, r1, val); - - exit: - mutex_unlock(&bus->mdio_lock); -@@ -475,7 +440,7 @@ qca8k_regmap_update_bits(void *ctx, uint - - val &= ~mask; - val |= write_val; -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ qca8k_mii_write32(bus, 0x10 | r2, r1, val); - - exit: - mutex_unlock(&bus->mdio_lock); -@@ -750,14 +715,14 @@ qca8k_mdio_write(struct qca8k_priv *priv - if (ret) - goto exit; - -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ qca8k_mii_write32(bus, 0x10 | r2, r1, val); - - ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, - QCA8K_MDIO_MASTER_BUSY); - - exit: - /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(priv, 0x10 | r2, r1, 0); -+ qca8k_mii_write32(bus, 0x10 | r2, r1, 0); - - mutex_unlock(&bus->mdio_lock); - -@@ -787,7 +752,7 @@ qca8k_mdio_read(struct qca8k_priv *priv, - if (ret) - goto exit; - -- qca8k_mii_write32(priv, 0x10 | r2, r1, val); -+ qca8k_mii_write32(bus, 0x10 | r2, r1, val); - - ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, - QCA8K_MDIO_MASTER_BUSY); -@@ -798,7 +763,7 @@ qca8k_mdio_read(struct qca8k_priv *priv, - - exit: - /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(priv, 0x10 | r2, r1, 0); -+ qca8k_mii_write32(bus, 0x10 | r2, r1, 0); - - mutex_unlock(&bus->mdio_lock); - -@@ -1914,8 +1879,6 @@ qca8k_sw_probe(struct mdio_device *mdiod - } - - priv->mdio_cache.page = 0xffff; -- priv->mdio_cache.lo = 0xffff; -- priv->mdio_cache.hi = 0xffff; - - /* Check the detected switch id */ - ret = qca8k_read_switch_id(priv); ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -375,11 +375,6 @@ struct qca8k_mdio_cache { - * mdio writes - */ - u16 page; --/* lo and hi can also be cached and from Documentation we can skip one -- * extra mdio write if lo or hi is didn't change. -- */ -- u16 lo; -- u16 hi; - }; - - struct qca8k_priv { diff --git a/target/linux/generic/backport-5.15/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch b/target/linux/generic/backport-5.15/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch deleted file mode 100644 index c0320ad6f9d8ab..00000000000000 --- a/target/linux/generic/backport-5.15/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch +++ /dev/null @@ -1,150 +0,0 @@ -From cfbd6de588ef659c198083205dc954a6d3ed2aec Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 29 Dec 2022 17:33:35 +0100 -Subject: [PATCH 4/5] net: dsa: qca8k: introduce single mii read/write lo/hi - -It may be useful to read/write just the lo or hi half of a reg. - -This is especially useful for phy poll with the use of mdio master. -The mdio master reg is composed by the first 16 bit related to setup and -the other half with the returned data or data to write. - -Refactor the mii function to permit single mii read/write of lo or hi -half of the reg. - -Tested-by: Ronald Wahl -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 106 ++++++++++++++++++++++++------- - 1 file changed, 84 insertions(+), 22 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -37,42 +37,104 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u - } - - static int --qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) -+qca8k_mii_write_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) - { - int ret; -+ u16 lo; - -- ret = bus->read(bus, phy_id, regnum); -- if (ret >= 0) { -- *val = ret; -- ret = bus->read(bus, phy_id, regnum + 1); -- *val |= ret << 16; -- } -+ lo = val & 0xffff; -+ ret = bus->write(bus, phy_id, regnum, lo); -+ if (ret < 0) -+ dev_err_ratelimited(&bus->dev, -+ "failed to write qca8k 32bit lo register\n"); -+ -+ return ret; -+} - -- if (ret < 0) { -+static int -+qca8k_mii_write_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) -+{ -+ int ret; -+ u16 hi; -+ -+ hi = (u16)(val >> 16); -+ ret = bus->write(bus, phy_id, regnum, hi); -+ if (ret < 0) - dev_err_ratelimited(&bus->dev, -- "failed to read qca8k 32bit register\n"); -- *val = 0; -- return ret; -- } -+ "failed to write qca8k 32bit hi register\n"); - -+ return ret; -+} -+ -+static int -+qca8k_mii_read_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) -+{ -+ int ret; -+ -+ ret = bus->read(bus, phy_id, regnum); -+ if (ret < 0) -+ goto err; -+ -+ *val = ret & 0xffff; - return 0; -+ -+err: -+ dev_err_ratelimited(&bus->dev, -+ "failed to read qca8k 32bit lo register\n"); -+ *val = 0; -+ -+ return ret; - } - --static void --qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) -+static int -+qca8k_mii_read_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) - { -- u16 lo, hi; - int ret; - -- lo = val & 0xffff; -- hi = (u16)(val >> 16); -+ ret = bus->read(bus, phy_id, regnum); -+ if (ret < 0) -+ goto err; - -- ret = bus->write(bus, phy_id, regnum, lo); -- if (ret >= 0) -- ret = bus->write(bus, phy_id, regnum + 1, hi); -+ *val = ret << 16; -+ return 0; -+ -+err: -+ dev_err_ratelimited(&bus->dev, -+ "failed to read qca8k 32bit hi register\n"); -+ *val = 0; -+ -+ return ret; -+} -+ -+static int -+qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) -+{ -+ u32 hi, lo; -+ int ret; -+ -+ *val = 0; -+ -+ ret = qca8k_mii_read_lo(bus, phy_id, regnum, &lo); - if (ret < 0) -- dev_err_ratelimited(&bus->dev, -- "failed to write qca8k 32bit register\n"); -+ goto err; -+ -+ ret = qca8k_mii_read_hi(bus, phy_id, regnum + 1, &hi); -+ if (ret < 0) -+ goto err; -+ -+ *val = lo | hi; -+ -+err: -+ return ret; -+} -+ -+static void -+qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) -+{ -+ if (qca8k_mii_write_lo(bus, phy_id, regnum, val) < 0) -+ return; -+ -+ qca8k_mii_write_hi(bus, phy_id, regnum + 1, val); - } - - static int diff --git a/target/linux/generic/backport-5.15/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch b/target/linux/generic/backport-5.15/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch deleted file mode 100644 index 4cbb66cf35fac3..00000000000000 --- a/target/linux/generic/backport-5.15/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch +++ /dev/null @@ -1,73 +0,0 @@ -From a4165830ca237f2b3318faf62562bce8ce12a389 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 29 Dec 2022 17:33:36 +0100 -Subject: [PATCH 5/5] net: dsa: qca8k: improve mdio master read/write by using - single lo/hi - -Improve mdio master read/write by using singe mii read/write lo/hi. - -In a read and write we need to poll the mdio master regs in a busy loop -to check for a specific bit present in the upper half of the reg. We can -ignore the other half since it won't contain useful data. This will save -an additional useless read for each read and write operation. - -In a read operation the returned data is present in the mdio master reg -lower half. We can ignore the other half since it won't contain useful -data. This will save an additional useless read for each read operation. - -In a read operation it's needed to just set the hi half of the mdio -master reg as the lo half will be replaced by the result. This will save -an additional useless write for each read operation. - -Tested-by: Ronald Wahl -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -740,9 +740,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus - - qca8k_split_addr(reg, &r1, &r2, &page); - -- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, -+ ret = read_poll_timeout(qca8k_mii_read_hi, ret1, !(val & mask), 0, - QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -- bus, 0x10 | r2, r1, &val); -+ bus, 0x10 | r2, r1 + 1, &val); - - /* Check if qca8k_read has failed for a different reason - * before returnting -ETIMEDOUT -@@ -784,7 +784,7 @@ qca8k_mdio_write(struct qca8k_priv *priv - - exit: - /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(bus, 0x10 | r2, r1, 0); -+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0); - - mutex_unlock(&bus->mdio_lock); - -@@ -814,18 +814,18 @@ qca8k_mdio_read(struct qca8k_priv *priv, - if (ret) - goto exit; - -- qca8k_mii_write32(bus, 0x10 | r2, r1, val); -+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, val); - - ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, - QCA8K_MDIO_MASTER_BUSY); - if (ret) - goto exit; - -- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); -+ ret = qca8k_mii_read_lo(bus, 0x10 | r2, r1, &val); - - exit: - /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(bus, 0x10 | r2, r1, 0); -+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0); - - mutex_unlock(&bus->mdio_lock); - diff --git a/target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch b/target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch deleted file mode 100644 index 7cb21ed00d60c4..00000000000000 --- a/target/linux/generic/backport-5.15/778-v5.18-01-net-phy-at803x-add-fiber-support.patch +++ /dev/null @@ -1,193 +0,0 @@ -From 3265f421887847db9ae2c01a00645e33608556d8 Mon Sep 17 00:00:00 2001 -From: Robert Hancock -Date: Tue, 25 Jan 2022 10:54:09 -0600 -Subject: [PATCH] net: phy: at803x: add fiber support - -Previously this driver always forced the copper page to be selected, -however for AR8031 in 100Base-FX or 1000Base-X modes, the fiber page -needs to be selected. Set the appropriate mode based on the hardware -mode_cfg strap selection. - -Enable the appropriate interrupt bits to detect fiber-side link up -or down events. - -Update config_aneg and read_status methods to use the appropriate -Clause 37 calls when fiber mode is in use. - -Signed-off-by: Robert Hancock -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 76 +++++++++++++++++++++++++++++++++++----- - 1 file changed, 67 insertions(+), 9 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -48,6 +48,8 @@ - #define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12) - #define AT803X_INTR_ENABLE_LINK_FAIL BIT(11) - #define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10) -+#define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8) -+#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7) - #define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5) - #define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1) - #define AT803X_INTR_ENABLE_WOL BIT(0) -@@ -82,6 +84,17 @@ - - #define AT803X_MODE_CFG_MASK 0x0F - #define AT803X_MODE_CFG_SGMII 0x01 -+#define AT803X_MODE_CFG_BASET_RGMII 0x00 -+#define AT803X_MODE_CFG_BASET_SGMII 0x01 -+#define AT803X_MODE_CFG_BX1000_RGMII_50OHM 0x02 -+#define AT803X_MODE_CFG_BX1000_RGMII_75OHM 0x03 -+#define AT803X_MODE_CFG_BX1000_CONV_50OHM 0x04 -+#define AT803X_MODE_CFG_BX1000_CONV_75OHM 0x05 -+#define AT803X_MODE_CFG_FX100_RGMII_50OHM 0x06 -+#define AT803X_MODE_CFG_FX100_CONV_50OHM 0x07 -+#define AT803X_MODE_CFG_RGMII_AUTO_MDET 0x0B -+#define AT803X_MODE_CFG_FX100_RGMII_75OHM 0x0E -+#define AT803X_MODE_CFG_FX100_CONV_75OHM 0x0F - - #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/ - #define AT803X_PSSR_MR_AN_COMPLETE 0x0200 -@@ -199,6 +212,8 @@ struct at803x_priv { - u16 clk_25m_mask; - u8 smarteee_lpi_tw_1g; - u8 smarteee_lpi_tw_100m; -+ bool is_fiber; -+ bool is_1000basex; - struct regulator_dev *vddio_rdev; - struct regulator_dev *vddh_rdev; - struct regulator *vddio; -@@ -674,7 +689,33 @@ static int at803x_probe(struct phy_devic - return ret; - } - -+ if (phydev->drv->phy_id == ATH8031_PHY_ID) { -+ int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); -+ int mode_cfg; -+ -+ if (ccr < 0) -+ goto err; -+ mode_cfg = ccr & AT803X_MODE_CFG_MASK; -+ -+ switch (mode_cfg) { -+ case AT803X_MODE_CFG_BX1000_RGMII_50OHM: -+ case AT803X_MODE_CFG_BX1000_RGMII_75OHM: -+ priv->is_1000basex = true; -+ fallthrough; -+ case AT803X_MODE_CFG_FX100_RGMII_50OHM: -+ case AT803X_MODE_CFG_FX100_RGMII_75OHM: -+ priv->is_fiber = true; -+ break; -+ } -+ } -+ - return 0; -+ -+err: -+ if (priv->vddio) -+ regulator_disable(priv->vddio); -+ -+ return ret; - } - - static void at803x_remove(struct phy_device *phydev) -@@ -687,6 +728,7 @@ static void at803x_remove(struct phy_dev - - static int at803x_get_features(struct phy_device *phydev) - { -+ struct at803x_priv *priv = phydev->priv; - int err; - - err = genphy_read_abilities(phydev); -@@ -704,12 +746,13 @@ static int at803x_get_features(struct ph - * As a result of that, ESTATUS_1000_XFULL is set - * to 1 even when operating in copper TP mode. - * -- * Remove this mode from the supported link modes, -- * as this driver currently only supports copper -- * operation. -+ * Remove this mode from the supported link modes -+ * when not operating in 1000BaseX mode. - */ -- linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, -- phydev->supported); -+ if (!priv->is_1000basex) -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, -+ phydev->supported); -+ - return 0; - } - -@@ -773,15 +816,18 @@ static int at8031_pll_config(struct phy_ - - static int at803x_config_init(struct phy_device *phydev) - { -+ struct at803x_priv *priv = phydev->priv; - int ret; - - if (phydev->drv->phy_id == ATH8031_PHY_ID) { - /* Some bootloaders leave the fiber page selected. -- * Switch to the copper page, as otherwise we read -- * the PHY capabilities from the fiber side. -+ * Switch to the appropriate page (fiber or copper), as otherwise we -+ * read the PHY capabilities from the wrong page. - */ - phy_lock_mdio_bus(phydev); -- ret = at803x_write_page(phydev, AT803X_PAGE_COPPER); -+ ret = at803x_write_page(phydev, -+ priv->is_fiber ? AT803X_PAGE_FIBER : -+ AT803X_PAGE_COPPER); - phy_unlock_mdio_bus(phydev); - if (ret) - return ret; -@@ -840,6 +886,7 @@ static int at803x_ack_interrupt(struct p - - static int at803x_config_intr(struct phy_device *phydev) - { -+ struct at803x_priv *priv = phydev->priv; - int err; - int value; - -@@ -856,6 +903,10 @@ static int at803x_config_intr(struct phy - value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED; - value |= AT803X_INTR_ENABLE_LINK_FAIL; - value |= AT803X_INTR_ENABLE_LINK_SUCCESS; -+ if (priv->is_fiber) { -+ value |= AT803X_INTR_ENABLE_LINK_FAIL_BX; -+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX; -+ } - - err = phy_write(phydev, AT803X_INTR_ENABLE, value); - } else { -@@ -923,8 +974,12 @@ static void at803x_link_change_notify(st - - static int at803x_read_status(struct phy_device *phydev) - { -+ struct at803x_priv *priv = phydev->priv; - int ss, err, old_link = phydev->link; - -+ if (priv->is_1000basex) -+ return genphy_c37_read_status(phydev); -+ - /* Update the link, but return if there was an error */ - err = genphy_update_link(phydev); - if (err) -@@ -1023,6 +1078,7 @@ static int at803x_config_mdix(struct phy - - static int at803x_config_aneg(struct phy_device *phydev) - { -+ struct at803x_priv *priv = phydev->priv; - int ret; - - ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); -@@ -1039,6 +1095,9 @@ static int at803x_config_aneg(struct phy - return ret; - } - -+ if (priv->is_1000basex) -+ return genphy_c37_config_aneg(phydev); -+ - return genphy_config_aneg(phydev); - } - diff --git a/target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch b/target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch deleted file mode 100644 index 8393cb32e896f0..00000000000000 --- a/target/linux/generic/backport-5.15/778-v5.18-02-net-phy-at803x-support-downstream-SFP-cage.patch +++ /dev/null @@ -1,95 +0,0 @@ -From dc4d5fcc5d365c9f70ea3f5c09bdf70e988fad50 Mon Sep 17 00:00:00 2001 -From: Robert Hancock -Date: Tue, 25 Jan 2022 10:54:10 -0600 -Subject: [PATCH] net: phy: at803x: Support downstream SFP cage - -Add support for downstream SFP cages for AR8031 and AR8033. This is -primarily intended for fiber modules or direct-attach cables, however -copper modules which work in 1000Base-X mode may also function. Such -modules are allowed with a warning. - -Signed-off-by: Robert Hancock -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 56 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 56 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -19,6 +19,8 @@ - #include - #include - #include -+#include -+#include - #include - - #define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10 -@@ -555,6 +557,55 @@ static int at8031_register_regulators(st - return 0; - } - -+static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) -+{ -+ struct phy_device *phydev = upstream; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support); -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support); -+ phy_interface_t iface; -+ -+ linkmode_zero(phy_support); -+ phylink_set(phy_support, 1000baseX_Full); -+ phylink_set(phy_support, 1000baseT_Full); -+ phylink_set(phy_support, Autoneg); -+ phylink_set(phy_support, Pause); -+ phylink_set(phy_support, Asym_Pause); -+ -+ linkmode_zero(sfp_support); -+ sfp_parse_support(phydev->sfp_bus, id, sfp_support); -+ /* Some modules support 10G modes as well as others we support. -+ * Mask out non-supported modes so the correct interface is picked. -+ */ -+ linkmode_and(sfp_support, phy_support, sfp_support); -+ -+ if (linkmode_empty(sfp_support)) { -+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n"); -+ return -EINVAL; -+ } -+ -+ iface = sfp_select_interface(phydev->sfp_bus, sfp_support); -+ -+ /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes -+ * interface for use with SFP modules. -+ * However, some copper modules detected as having a preferred SGMII -+ * interface do default to and function in 1000Base-X mode, so just -+ * print a warning and allow such modules, as they may have some chance -+ * of working. -+ */ -+ if (iface == PHY_INTERFACE_MODE_SGMII) -+ dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n"); -+ else if (iface != PHY_INTERFACE_MODE_1000BASEX) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static const struct sfp_upstream_ops at803x_sfp_ops = { -+ .attach = phy_sfp_attach, -+ .detach = phy_sfp_detach, -+ .module_insert = at803x_sfp_insert, -+}; -+ - static int at803x_parse_dt(struct phy_device *phydev) - { - struct device_node *node = phydev->mdio.dev.of_node; -@@ -662,6 +713,11 @@ static int at803x_parse_dt(struct phy_de - phydev_err(phydev, "failed to get VDDIO regulator\n"); - return PTR_ERR(priv->vddio); - } -+ -+ /* Only AR8031/8033 support 1000Base-X for SFP modules */ -+ ret = phy_sfp_probe(phydev, &at803x_sfp_ops); -+ if (ret < 0) -+ return ret; - } - - return 0; diff --git a/target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch b/target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch deleted file mode 100644 index 53d6325c4942e4..00000000000000 --- a/target/linux/generic/backport-5.15/778-v5.18-03-net-phy-at803x-fix-NULL-pointer-dereference-on-AR9331-PHY.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 9926de7315be3d606cc011a305ad9adb9e8e14c9 Mon Sep 17 00:00:00 2001 -From: Oleksij Rempel -Date: Sat, 18 Jun 2022 14:23:33 +0200 -Subject: [PATCH] net: phy: at803x: fix NULL pointer dereference on AR9331 PHY - -Latest kernel will explode on the PHY interrupt config, since it depends -now on allocated priv. So, run probe to allocate priv to fix it. - - ar9331_switch ethernet.1:10 lan0 (uninitialized): PHY [!ahb!ethernet@1a000000!mdio!switch@10:00] driver [Qualcomm Atheros AR9331 built-in PHY] (irq=13) - CPU 0 Unable to handle kernel paging request at virtual address 0000000a, epc == 8050e8a8, ra == 80504b34 - ... - Call Trace: - [<8050e8a8>] at803x_config_intr+0x5c/0xd0 - [<80504b34>] phy_request_interrupt+0xa8/0xd0 - [<8050289c>] phylink_bringup_phy+0x2d8/0x3ac - [<80502b68>] phylink_fwnode_phy_connect+0x118/0x130 - [<8074d8ec>] dsa_slave_create+0x270/0x420 - [<80743b04>] dsa_port_setup+0x12c/0x148 - [<8074580c>] dsa_register_switch+0xaf0/0xcc0 - [<80511344>] ar9331_sw_probe+0x370/0x388 - [<8050cb78>] mdio_probe+0x44/0x70 - [<804df300>] really_probe+0x200/0x424 - [<804df7b4>] __driver_probe_device+0x290/0x298 - [<804df810>] driver_probe_device+0x54/0xe4 - [<804dfd50>] __device_attach_driver+0xe4/0x130 - [<804dcb00>] bus_for_each_drv+0xb4/0xd8 - [<804dfac4>] __device_attach+0x104/0x1a4 - [<804ddd24>] bus_probe_device+0x48/0xc4 - [<804deb44>] deferred_probe_work_func+0xf0/0x10c - [<800a0ffc>] process_one_work+0x314/0x4d4 - [<800a17fc>] worker_thread+0x2a4/0x354 - [<800a9a54>] kthread+0x134/0x13c - [<8006306c>] ret_from_kernel_thread+0x14/0x1c - -Same Issue would affect some other PHYs (QCA8081, QCA9561), so fix it -too. - -Fixes: 3265f4218878 ("net: phy: at803x: add fiber support") -Signed-off-by: Oleksij Rempel -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1592,6 +1592,8 @@ static struct phy_driver at803x_driver[] - /* ATHEROS AR9331 */ - PHY_ID_MATCH_EXACT(ATH9331_PHY_ID), - .name = "Qualcomm Atheros AR9331 built-in PHY", -+ .probe = at803x_probe, -+ .remove = at803x_remove, - .suspend = at803x_suspend, - .resume = at803x_resume, - .flags = PHY_POLL_CABLE_TEST, diff --git a/target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch b/target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch deleted file mode 100644 index cdae5b4ca423de..00000000000000 --- a/target/linux/generic/backport-5.15/778-v5.18-04-net-phy-at803x-fix-error-return-code-in-at803x_probe.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 1f0dd412e34e177621769866bef347f0b22364df Mon Sep 17 00:00:00 2001 -From: Wei Yongjun -Date: Fri, 18 Nov 2022 10:36:35 +0000 -Subject: [PATCH] net: phy: at803x: fix error return code in at803x_probe() - -Fix to return a negative error code from the ccr read error handling -case instead of 0, as done elsewhere in this function. - -Fixes: 3265f4218878 ("net: phy: at803x: add fiber support") -Signed-off-by: Wei Yongjun -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20221118103635.254256-1-weiyongjun@huaweicloud.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/at803x.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -749,8 +749,10 @@ static int at803x_probe(struct phy_devic - int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); - int mode_cfg; - -- if (ccr < 0) -+ if (ccr < 0) { -+ ret = ccr; - goto err; -+ } - mode_cfg = ccr & AT803X_MODE_CFG_MASK; - - switch (mode_cfg) { diff --git a/target/linux/generic/backport-5.15/780-v5.16-bus-mhi-pci_generic-Introduce-Sierra-EM919X-support.patch b/target/linux/generic/backport-5.15/780-v5.16-bus-mhi-pci_generic-Introduce-Sierra-EM919X-support.patch deleted file mode 100644 index 44f0864e9a8369..00000000000000 --- a/target/linux/generic/backport-5.15/780-v5.16-bus-mhi-pci_generic-Introduce-Sierra-EM919X-support.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 789d3eeb2367f92193a0882f7cdab03f0f9d6930 Mon Sep 17 00:00:00 2001 -From: Thomas Perrot -Date: Thu, 16 Dec 2021 13:42:27 +0530 -Subject: [PATCH] bus: mhi: pci_generic: Introduce Sierra EM919X support - -Add support for EM919X modems, this modem series is based on SDX55 -qcom chip. - -It is mandatory to use the same ring for control+data and diag events. - -Link: https://lore.kernel.org/r/20211123081541.648426-1-thomas.perrot@bootlin.com -Tested-by: Aleksander Morgado -Reviewed-by: Manivannan Sadhasivam -Signed-off-by: Thomas Perrot -Signed-off-by: Manivannan Sadhasivam -Link: https://lore.kernel.org/r/20211216081227.237749-11-manivannan.sadhasivam@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/bus/mhi/host/pci_generic.c | 43 +++++++++++++++++++++++++++++++++++ - 1 file changed, 43 insertions(+) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -406,6 +406,46 @@ static const struct mhi_pci_dev_info mhi - .mru_default = 32768, - }; - -+static const struct mhi_channel_config mhi_sierra_em919x_channels[] = { -+ MHI_CHANNEL_CONFIG_UL_SBL(2, "SAHARA", 32, 0), -+ MHI_CHANNEL_CONFIG_DL_SBL(3, "SAHARA", 256, 0), -+ MHI_CHANNEL_CONFIG_UL(4, "DIAG", 32, 0), -+ MHI_CHANNEL_CONFIG_DL(5, "DIAG", 32, 0), -+ MHI_CHANNEL_CONFIG_UL(12, "MBIM", 128, 0), -+ MHI_CHANNEL_CONFIG_DL(13, "MBIM", 128, 0), -+ MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0), -+ MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0), -+ MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0), -+ MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0), -+ MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 512, 1), -+ MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 512, 2), -+}; -+ -+static struct mhi_event_config modem_sierra_em919x_mhi_events[] = { -+ /* first ring is control+data and DIAG ring */ -+ MHI_EVENT_CONFIG_CTRL(0, 2048), -+ /* Hardware channels request dedicated hardware event rings */ -+ MHI_EVENT_CONFIG_HW_DATA(1, 2048, 100), -+ MHI_EVENT_CONFIG_HW_DATA(2, 2048, 101) -+}; -+ -+static const struct mhi_controller_config modem_sierra_em919x_config = { -+ .max_channels = 128, -+ .timeout_ms = 24000, -+ .num_channels = ARRAY_SIZE(mhi_sierra_em919x_channels), -+ .ch_cfg = mhi_sierra_em919x_channels, -+ .num_events = ARRAY_SIZE(modem_sierra_em919x_mhi_events), -+ .event_cfg = modem_sierra_em919x_mhi_events, -+}; -+ -+static const struct mhi_pci_dev_info mhi_sierra_em919x_info = { -+ .name = "sierra-em919x", -+ .config = &modem_sierra_em919x_config, -+ .bar_num = MHI_PCI_DEFAULT_BAR_NUM, -+ .dma_data_width = 32, -+ .sideband_wake = false, -+}; -+ - static const struct mhi_channel_config mhi_telit_fn980_hw_v1_channels[] = { - MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0), - MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0), -@@ -480,6 +520,9 @@ static const struct mhi_pci_dev_info mhi - }; - - static const struct pci_device_id mhi_pci_id_table[] = { -+ /* EM919x (sdx55), use the same vid:pid as qcom-sdx55m */ -+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x18d7, 0x0200), -+ .driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info }, - /* Telit FN980 hardware revision v1 */ - { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x1C5D, 0x2000), - .driver_data = (kernel_ulong_t) &mhi_telit_fn980_hw_v1_info }, diff --git a/target/linux/generic/backport-5.15/781-v6.1-bus-mhi-host-always-print-detected-modem-name.patch b/target/linux/generic/backport-5.15/781-v6.1-bus-mhi-host-always-print-detected-modem-name.patch deleted file mode 100644 index 3c71a27b79871b..00000000000000 --- a/target/linux/generic/backport-5.15/781-v6.1-bus-mhi-host-always-print-detected-modem-name.patch +++ /dev/null @@ -1,37 +0,0 @@ -From f369e9ad52ec9361827e21a631b7198c9fca438e Mon Sep 17 00:00:00 2001 -From: Koen Vandeputte -Date: Wed, 31 Aug 2022 12:03:49 +0200 -Subject: [PATCH] bus: mhi: host: always print detected modem name - -This harmless print provides a very easy way of knowing -if the modem is detected properly during probing. - -Promote it to an informational print so no hassle is required -enabling kernel debugging info to obtain it. - -The rationale here is that: -On a lot of low-storage embedded devices, extensive kernel -debugging info is not always present as this would -increase it's size to much causing partition size issues. - -Signed-off-by: Koen Vandeputte -Reviewed-by: Manivannan Sadhasivam -Reviewed-by: Loic Poulain -Link: https://lore.kernel.org/r/20220831100349.1488762-1-koen.vandeputte@citymesh.com -[mani: added missing review tags] -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -806,7 +806,7 @@ static int mhi_pci_probe(struct pci_dev - struct mhi_controller *mhi_cntrl; - int err; - -- dev_dbg(&pdev->dev, "MHI PCI device found: %s\n", info->name); -+ dev_info(&pdev->dev, "MHI PCI device found: %s\n", info->name); - - /* mhi_pdev.mhi_cntrl must be zero-initialized */ - mhi_pdev = devm_kzalloc(&pdev->dev, sizeof(*mhi_pdev), GFP_KERNEL); diff --git a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch b/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch deleted file mode 100644 index 7f16b936cde838..00000000000000 --- a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch +++ /dev/null @@ -1,130 +0,0 @@ -From e19de30d20809af3221ef8a2648b8a8a52e02d90 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 21 Sep 2022 01:23:14 +0100 -Subject: [PATCH 1/1] net: dsa: mt7530: add support for in-band link status - -Read link status from SGMII PCS for in-band managed 2500Base-X and -1000Base-X connection on a MAC port of the MT7531. This is needed to -get the SFP cage working which is connected to SGMII interface of -port 5 of the MT7531 switch IC on the Bananapi BPi-R3 board. -While at it also handle an_complete for both the autoneg and the -non-autoneg codepath. - -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 50 +++++++++++++++++++++++++++++----------- - drivers/net/dsa/mt7530.h | 1 + - 2 files changed, 38 insertions(+), 13 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2979,9 +2979,6 @@ mt7531_mac_config(struct dsa_switch *ds, - case PHY_INTERFACE_MODE_NA: - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_2500BASEX: -- if (phylink_autoneg_inband(mode)) -- return -EINVAL; -- - return mt7531_sgmii_setup_mode_force(priv, port, interface); - default: - return -EINVAL; -@@ -3057,13 +3054,6 @@ unsupported: - return; - } - -- if (phylink_autoneg_inband(mode) && -- state->interface != PHY_INTERFACE_MODE_SGMII) { -- dev_err(ds->dev, "%s: in-band negotiation unsupported\n", -- __func__); -- return; -- } -- - mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); - mcr_new = mcr_cur; - mcr_new &= ~PMCR_LINK_SETTINGS_MASK; -@@ -3200,6 +3190,9 @@ static void mt753x_phylink_get_caps(stru - config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000FD; - -+ if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port)) -+ config->mac_capabilities |= MAC_2500FD; -+ - /* This driver does not make use of the speed, duplex, pause or the - * advertisement in its mac_config, so it is safe to mark this driver - * as non-legacy. -@@ -3265,6 +3258,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 - - status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); - state->link = !!(status & MT7531_SGMII_LINK_STATUS); -+ state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE); - if (state->interface == PHY_INTERFACE_MODE_SGMII && - (status & MT7531_SGMII_AN_ENABLE)) { - val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port)); -@@ -3295,16 +3289,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7 - return 0; - } - -+static void -+mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port, -+ struct phylink_link_state *state) -+{ -+ unsigned int val; -+ -+ val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); -+ state->link = !!(val & MT7531_SGMII_LINK_STATUS); -+ if (!state->link) -+ return; -+ -+ state->an_complete = state->link; -+ -+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) -+ state->speed = SPEED_2500; -+ else -+ state->speed = SPEED_1000; -+ -+ state->duplex = DUPLEX_FULL; -+ state->pause = MLO_PAUSE_NONE; -+} -+ - static void mt7531_pcs_get_state(struct phylink_pcs *pcs, - struct phylink_link_state *state) - { - struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; - int port = pcs_to_mt753x_pcs(pcs)->port; - -- if (state->interface == PHY_INTERFACE_MODE_SGMII) -+ if (state->interface == PHY_INTERFACE_MODE_SGMII) { - mt7531_sgmii_pcs_get_state_an(priv, port, state); -- else -- state->link = false; -+ return; -+ } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) || -+ (state->interface == PHY_INTERFACE_MODE_2500BASEX)) { -+ mt7531_sgmii_pcs_get_state_inband(priv, port, state); -+ return; -+ } -+ -+ state->link = false; - } - - static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -3345,6 +3367,8 @@ mt753x_setup(struct dsa_switch *ds) - priv->pcs[i].pcs.ops = priv->info->pcs_ops; - priv->pcs[i].priv = priv; - priv->pcs[i].port = i; -+ if (mt753x_is_mac_port(i)) -+ priv->pcs[i].pcs.poll = 1; - } - - ret = priv->info->sw_setup(ds); ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -410,6 +410,7 @@ enum mt7530_vlan_port_acc_frm { - #define MT7531_SGMII_LINK_STATUS BIT(18) - #define MT7531_SGMII_AN_ENABLE BIT(12) - #define MT7531_SGMII_AN_RESTART BIT(9) -+#define MT7531_SGMII_AN_COMPLETE BIT(21) - - /* Register for SGMII PCS_SPPED_ABILITY */ - #define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08) diff --git a/target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch b/target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch deleted file mode 100644 index 77cd336d364c83..00000000000000 --- a/target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 8475c4b70b040f9d8cbc308100f2c4d865f810b3 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 13 Sep 2022 20:06:27 +0100 -Subject: [PATCH 1/1] net: sfp: re-implement soft state polling setup - -Re-implement the decision making for soft state polling. Instead of -generating the soft state mask in sfp_soft_start_poll() by looking at -which GPIOs are available, record their availability in -sfp_sm_mod_probe() in sfp->state_hw_mask. - -This will then allow us to clear bits in sfp->state_hw_mask in module -specific quirks when the hardware signals should not be used, thereby -allowing us to switch to using the software state polling. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/sfp.c | 38 ++++++++++++++++++++++++++------------ - 1 file changed, 26 insertions(+), 12 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -240,6 +240,7 @@ struct sfp { - bool need_poll; - - struct mutex st_mutex; /* Protects state */ -+ unsigned int state_hw_mask; - unsigned int state_soft_mask; - unsigned int state; - struct delayed_work poll; -@@ -505,17 +506,18 @@ static void sfp_soft_set_state(struct sf - static void sfp_soft_start_poll(struct sfp *sfp) - { - const struct sfp_eeprom_id *id = &sfp->id; -+ unsigned int mask = 0; - - sfp->state_soft_mask = 0; -- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE && -- !sfp->gpio[GPIO_TX_DISABLE]) -- sfp->state_soft_mask |= SFP_F_TX_DISABLE; -- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT && -- !sfp->gpio[GPIO_TX_FAULT]) -- sfp->state_soft_mask |= SFP_F_TX_FAULT; -- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS && -- !sfp->gpio[GPIO_LOS]) -- sfp->state_soft_mask |= SFP_F_LOS; -+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE) -+ mask |= SFP_F_TX_DISABLE; -+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT) -+ mask |= SFP_F_TX_FAULT; -+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS) -+ mask |= SFP_F_LOS; -+ -+ // Poll the soft state for hardware pins we want to ignore -+ sfp->state_soft_mask = ~sfp->state_hw_mask & mask; - - if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) && - !sfp->need_poll) -@@ -529,10 +531,11 @@ static void sfp_soft_stop_poll(struct sf - - static unsigned int sfp_get_state(struct sfp *sfp) - { -- unsigned int state = sfp->get_state(sfp); -+ unsigned int soft = sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT); -+ unsigned int state; - -- if (state & SFP_F_PRESENT && -- sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT)) -+ state = sfp->get_state(sfp) & sfp->state_hw_mask; -+ if (state & SFP_F_PRESENT && soft) - state |= sfp_soft_get_state(sfp); - - return state; -@@ -1942,6 +1945,15 @@ static int sfp_sm_mod_probe(struct sfp * - if (ret < 0) - return ret; - -+ /* Initialise state bits to use from hardware */ -+ sfp->state_hw_mask = SFP_F_PRESENT; -+ if (sfp->gpio[GPIO_TX_DISABLE]) -+ sfp->state_hw_mask |= SFP_F_TX_DISABLE; -+ if (sfp->gpio[GPIO_TX_FAULT]) -+ sfp->state_hw_mask |= SFP_F_TX_FAULT; -+ if (sfp->gpio[GPIO_LOS]) -+ sfp->state_hw_mask |= SFP_F_LOS; -+ - if (!memcmp(id.base.vendor_name, "ALCATELLUCENT ", 16) && - !memcmp(id.base.vendor_pn, "3FE46541AA ", 16)) - sfp->module_t_start_up = T_START_UP_BAD_GPON; -@@ -2568,6 +2580,8 @@ static int sfp_probe(struct platform_dev - return PTR_ERR(sfp->gpio[i]); - } - -+ sfp->state_hw_mask = SFP_F_PRESENT; -+ - sfp->get_state = sfp_gpio_get_state; - sfp->set_state = sfp_gpio_set_state; - diff --git a/target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch b/target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch deleted file mode 100644 index 02fa28c5af296d..00000000000000 --- a/target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch +++ /dev/null @@ -1,291 +0,0 @@ -From 23571c7b96437483d28a990c906cc81f5f66374e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 13 Sep 2022 20:06:32 +0100 -Subject: [PATCH 1/1] net: sfp: move quirk handling into sfp.c - -We need to handle more quirks than just those which affect the link -modes of the module. Move the quirk lookup into sfp.c, and pass the -quirk to sfp-bus.c - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/sfp-bus.c | 98 ++------------------------------------- - drivers/net/phy/sfp.c | 94 ++++++++++++++++++++++++++++++++++++- - drivers/net/phy/sfp.h | 9 +++- - 3 files changed, 104 insertions(+), 97 deletions(-) - ---- a/drivers/net/phy/sfp-bus.c -+++ b/drivers/net/phy/sfp-bus.c -@@ -10,12 +10,6 @@ - - #include "sfp.h" - --struct sfp_quirk { -- const char *vendor; -- const char *part; -- void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes); --}; -- - /** - * struct sfp_bus - internal representation of a sfp bus - */ -@@ -38,93 +32,6 @@ struct sfp_bus { - bool started; - }; - --static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id, -- unsigned long *modes) --{ -- phylink_set(modes, 2500baseX_Full); --} -- --static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id, -- unsigned long *modes) --{ -- /* Ubiquiti U-Fiber Instant module claims that support all transceiver -- * types including 10G Ethernet which is not truth. So clear all claimed -- * modes and set only one mode which module supports: 1000baseX_Full. -- */ -- phylink_zero(modes); -- phylink_set(modes, 1000baseX_Full); --} -- --static const struct sfp_quirk sfp_quirks[] = { -- { -- // Alcatel Lucent G-010S-P can operate at 2500base-X, but -- // incorrectly report 2500MBd NRZ in their EEPROM -- .vendor = "ALCATELLUCENT", -- .part = "G010SP", -- .modes = sfp_quirk_2500basex, -- }, { -- // Alcatel Lucent G-010S-A can operate at 2500base-X, but -- // report 3.2GBd NRZ in their EEPROM -- .vendor = "ALCATELLUCENT", -- .part = "3FE46541AA", -- .modes = sfp_quirk_2500basex, -- }, { -- // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd -- // NRZ in their EEPROM -- .vendor = "HUAWEI", -- .part = "MA5671A", -- .modes = sfp_quirk_2500basex, -- }, { -- // Lantech 8330-262D-E can operate at 2500base-X, but -- // incorrectly report 2500MBd NRZ in their EEPROM -- .vendor = "Lantech", -- .part = "8330-262D-E", -- .modes = sfp_quirk_2500basex, -- }, { -- .vendor = "UBNT", -- .part = "UF-INSTANT", -- .modes = sfp_quirk_ubnt_uf_instant, -- }, --}; -- --static size_t sfp_strlen(const char *str, size_t maxlen) --{ -- size_t size, i; -- -- /* Trailing characters should be filled with space chars */ -- for (i = 0, size = 0; i < maxlen; i++) -- if (str[i] != ' ') -- size = i + 1; -- -- return size; --} -- --static bool sfp_match(const char *qs, const char *str, size_t len) --{ -- if (!qs) -- return true; -- if (strlen(qs) != len) -- return false; -- return !strncmp(qs, str, len); --} -- --static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id) --{ -- const struct sfp_quirk *q; -- unsigned int i; -- size_t vs, ps; -- -- vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name)); -- ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn)); -- -- for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++) -- if (sfp_match(q->vendor, id->base.vendor_name, vs) && -- sfp_match(q->part, id->base.vendor_pn, ps)) -- return q; -- -- return NULL; --} -- - /** - * sfp_parse_port() - Parse the EEPROM base ID, setting the port type - * @bus: a pointer to the &struct sfp_bus structure for the sfp module -@@ -786,12 +693,13 @@ void sfp_link_down(struct sfp_bus *bus) - } - EXPORT_SYMBOL_GPL(sfp_link_down); - --int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id) -+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id, -+ const struct sfp_quirk *quirk) - { - const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus); - int ret = 0; - -- bus->sfp_quirk = sfp_lookup_quirk(id); -+ bus->sfp_quirk = quirk; - - if (ops && ops->module_insert) - ret = ops->module_insert(bus->upstream, id); ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -259,6 +259,8 @@ struct sfp { - unsigned int module_t_start_up; - bool tx_fault_ignore; - -+ const struct sfp_quirk *quirk; -+ - #if IS_ENABLED(CONFIG_HWMON) - struct sfp_diag diag; - struct delayed_work hwmon_probe; -@@ -315,6 +317,93 @@ static const struct of_device_id sfp_of_ - }; - MODULE_DEVICE_TABLE(of, sfp_of_match); - -+static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id, -+ unsigned long *modes) -+{ -+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, modes); -+} -+ -+static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id, -+ unsigned long *modes) -+{ -+ /* Ubiquiti U-Fiber Instant module claims that support all transceiver -+ * types including 10G Ethernet which is not truth. So clear all claimed -+ * modes and set only one mode which module supports: 1000baseX_Full. -+ */ -+ linkmode_zero(modes); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes); -+} -+ -+static const struct sfp_quirk sfp_quirks[] = { -+ { -+ // Alcatel Lucent G-010S-P can operate at 2500base-X, but -+ // incorrectly report 2500MBd NRZ in their EEPROM -+ .vendor = "ALCATELLUCENT", -+ .part = "G010SP", -+ .modes = sfp_quirk_2500basex, -+ }, { -+ // Alcatel Lucent G-010S-A can operate at 2500base-X, but -+ // report 3.2GBd NRZ in their EEPROM -+ .vendor = "ALCATELLUCENT", -+ .part = "3FE46541AA", -+ .modes = sfp_quirk_2500basex, -+ }, { -+ // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd -+ // NRZ in their EEPROM -+ .vendor = "HUAWEI", -+ .part = "MA5671A", -+ .modes = sfp_quirk_2500basex, -+ }, { -+ // Lantech 8330-262D-E can operate at 2500base-X, but -+ // incorrectly report 2500MBd NRZ in their EEPROM -+ .vendor = "Lantech", -+ .part = "8330-262D-E", -+ .modes = sfp_quirk_2500basex, -+ }, { -+ .vendor = "UBNT", -+ .part = "UF-INSTANT", -+ .modes = sfp_quirk_ubnt_uf_instant, -+ }, -+}; -+ -+static size_t sfp_strlen(const char *str, size_t maxlen) -+{ -+ size_t size, i; -+ -+ /* Trailing characters should be filled with space chars */ -+ for (i = 0, size = 0; i < maxlen; i++) -+ if (str[i] != ' ') -+ size = i + 1; -+ -+ return size; -+} -+ -+static bool sfp_match(const char *qs, const char *str, size_t len) -+{ -+ if (!qs) -+ return true; -+ if (strlen(qs) != len) -+ return false; -+ return !strncmp(qs, str, len); -+} -+ -+static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id) -+{ -+ const struct sfp_quirk *q; -+ unsigned int i; -+ size_t vs, ps; -+ -+ vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name)); -+ ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn)); -+ -+ for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++) -+ if (sfp_match(q->vendor, id->base.vendor_name, vs) && -+ sfp_match(q->part, id->base.vendor_pn, ps)) -+ return q; -+ -+ return NULL; -+} -+ - static unsigned long poll_jiffies; - - static unsigned int sfp_gpio_get_state(struct sfp *sfp) -@@ -1966,6 +2055,8 @@ static int sfp_sm_mod_probe(struct sfp * - else - sfp->tx_fault_ignore = false; - -+ sfp->quirk = sfp_lookup_quirk(&id); -+ - return 0; - } - -@@ -2077,7 +2168,8 @@ static void sfp_sm_module(struct sfp *sf - break; - - /* Report the module insertion to the upstream device */ -- err = sfp_module_insert(sfp->sfp_bus, &sfp->id); -+ err = sfp_module_insert(sfp->sfp_bus, &sfp->id, -+ sfp->quirk); - if (err < 0) { - sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); - break; ---- a/drivers/net/phy/sfp.h -+++ b/drivers/net/phy/sfp.h -@@ -6,6 +6,12 @@ - - struct sfp; - -+struct sfp_quirk { -+ const char *vendor; -+ const char *part; -+ void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes); -+}; -+ - struct sfp_socket_ops { - void (*attach)(struct sfp *sfp); - void (*detach)(struct sfp *sfp); -@@ -23,7 +29,8 @@ int sfp_add_phy(struct sfp_bus *bus, str - void sfp_remove_phy(struct sfp_bus *bus); - void sfp_link_up(struct sfp_bus *bus); - void sfp_link_down(struct sfp_bus *bus); --int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id); -+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id, -+ const struct sfp_quirk *quirk); - void sfp_module_remove(struct sfp_bus *bus); - int sfp_module_start(struct sfp_bus *bus); - void sfp_module_stop(struct sfp_bus *bus); diff --git a/target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch b/target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch deleted file mode 100644 index b076676cff6de7..00000000000000 --- a/target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 275416754e9a262c97a1ad6f806a4bc6e0464aa2 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 13 Sep 2022 20:06:37 +0100 -Subject: [PATCH 1/1] net: sfp: move Alcatel Lucent 3FE46541AA fixup - -Add a new fixup mechanism to the SFP quirks, and use it for this -module. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/sfp.c | 14 +++++++++----- - drivers/net/phy/sfp.h | 1 + - 2 files changed, 10 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -317,6 +317,11 @@ static const struct of_device_id sfp_of_ - }; - MODULE_DEVICE_TABLE(of, sfp_of_match); - -+static void sfp_fixup_long_startup(struct sfp *sfp) -+{ -+ sfp->module_t_start_up = T_START_UP_BAD_GPON; -+} -+ - static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id, - unsigned long *modes) - { -@@ -347,6 +352,7 @@ static const struct sfp_quirk sfp_quirks - .vendor = "ALCATELLUCENT", - .part = "3FE46541AA", - .modes = sfp_quirk_2500basex, -+ .fixup = sfp_fixup_long_startup, - }, { - // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd - // NRZ in their EEPROM -@@ -2043,11 +2049,7 @@ static int sfp_sm_mod_probe(struct sfp * - if (sfp->gpio[GPIO_LOS]) - sfp->state_hw_mask |= SFP_F_LOS; - -- if (!memcmp(id.base.vendor_name, "ALCATELLUCENT ", 16) && -- !memcmp(id.base.vendor_pn, "3FE46541AA ", 16)) -- sfp->module_t_start_up = T_START_UP_BAD_GPON; -- else -- sfp->module_t_start_up = T_START_UP; -+ sfp->module_t_start_up = T_START_UP; - - if (!memcmp(id.base.vendor_name, "HUAWEI ", 16) && - !memcmp(id.base.vendor_pn, "MA5671A ", 16)) -@@ -2056,6 +2058,8 @@ static int sfp_sm_mod_probe(struct sfp * - sfp->tx_fault_ignore = false; - - sfp->quirk = sfp_lookup_quirk(&id); -+ if (sfp->quirk && sfp->quirk->fixup) -+ sfp->quirk->fixup(sfp); - - return 0; - } ---- a/drivers/net/phy/sfp.h -+++ b/drivers/net/phy/sfp.h -@@ -10,6 +10,7 @@ struct sfp_quirk { - const char *vendor; - const char *part; - void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes); -+ void (*fixup)(struct sfp *sfp); - }; - - struct sfp_socket_ops { diff --git a/target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch b/target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch deleted file mode 100644 index 7f856e5b5bee19..00000000000000 --- a/target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 5029be761161374a3624aa7b4670174c35449bf5 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 13 Sep 2022 20:06:42 +0100 -Subject: [PATCH 1/1] net: sfp: move Huawei MA5671A fixup - -Move this module over to the new fixup mechanism. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/sfp.c | 12 +++++++----- - 1 file changed, 7 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -322,6 +322,11 @@ static void sfp_fixup_long_startup(struc - sfp->module_t_start_up = T_START_UP_BAD_GPON; - } - -+static void sfp_fixup_ignore_tx_fault(struct sfp *sfp) -+{ -+ sfp->tx_fault_ignore = true; -+} -+ - static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id, - unsigned long *modes) - { -@@ -359,6 +364,7 @@ static const struct sfp_quirk sfp_quirks - .vendor = "HUAWEI", - .part = "MA5671A", - .modes = sfp_quirk_2500basex, -+ .fixup = sfp_fixup_ignore_tx_fault, - }, { - // Lantech 8330-262D-E can operate at 2500base-X, but - // incorrectly report 2500MBd NRZ in their EEPROM -@@ -2051,11 +2057,7 @@ static int sfp_sm_mod_probe(struct sfp * - - 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; -+ sfp->tx_fault_ignore = false; - - sfp->quirk = sfp_lookup_quirk(&id); - if (sfp->quirk && sfp->quirk->fixup) diff --git a/target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch b/target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch deleted file mode 100644 index 81108e19c167d2..00000000000000 --- a/target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 73472c830eae5fce2107f7f086f1e6827d215caf Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 13 Sep 2022 20:06:48 +0100 -Subject: [PATCH 1/1] net: sfp: add support for HALNy GPON SFP - -Add a quirk for the HALNy HL-GSFP module, which appears to have an -inverted RX_LOS signal, and maybe uses TX_FAULT as a serial port -transmit pin. Rather than use these hardware signals, switch to -using software polling for these status signals. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/sfp-bus.c | 2 +- - drivers/net/phy/sfp.c | 21 ++++++++++++++++++--- - 2 files changed, 19 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/sfp-bus.c -+++ b/drivers/net/phy/sfp-bus.c -@@ -283,7 +283,7 @@ void sfp_parse_support(struct sfp_bus *b - phylink_set(modes, 2500baseX_Full); - } - -- if (bus->sfp_quirk) -+ if (bus->sfp_quirk && bus->sfp_quirk->modes) - bus->sfp_quirk->modes(id, modes); - - linkmode_or(support, support, modes); ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -327,6 +327,15 @@ static void sfp_fixup_ignore_tx_fault(st - sfp->tx_fault_ignore = true; - } - -+static void sfp_fixup_halny_gsfp(struct sfp *sfp) -+{ -+ /* Ignore the TX_FAULT and LOS signals on this module. -+ * these are possibly used for other purposes on this -+ * module, e.g. a serial port. -+ */ -+ sfp->state_hw_mask &= ~(SFP_F_TX_FAULT | SFP_F_LOS); -+} -+ - static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id, - unsigned long *modes) - { -@@ -359,6 +368,10 @@ static const struct sfp_quirk sfp_quirks - .modes = sfp_quirk_2500basex, - .fixup = sfp_fixup_long_startup, - }, { -+ .vendor = "HALNy", -+ .part = "HL-GSFP", -+ .fixup = sfp_fixup_halny_gsfp, -+ }, { - // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd - // NRZ in their EEPROM - .vendor = "HUAWEI", -@@ -375,16 +388,18 @@ static const struct sfp_quirk sfp_quirks - .vendor = "UBNT", - .part = "UF-INSTANT", - .modes = sfp_quirk_ubnt_uf_instant, -- }, -+ } - }; - - static size_t sfp_strlen(const char *str, size_t maxlen) - { - size_t size, i; - -- /* Trailing characters should be filled with space chars */ -+ /* Trailing characters should be filled with space chars, but -+ * some manufacturers can't read SFF-8472 and use NUL. -+ */ - for (i = 0, size = 0; i < maxlen; i++) -- if (str[i] != ' ') -+ if (str[i] != ' ' && str[i] != '\0') - size = i + 1; - - return size; diff --git a/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch b/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch deleted file mode 100644 index 8060ad5afceba6..00000000000000 --- a/target/linux/generic/backport-5.15/788-v6.3-net-dsa-mt7530-use-external-PCS-driver.patch +++ /dev/null @@ -1,514 +0,0 @@ -From patchwork Thu Mar 9 10:57:44 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 13167235 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -Date: Thu, 9 Mar 2023 10:57:44 +0000 -From: Daniel Golle -To: netdev@vger.kernel.org, linux-mediatek@lists.infradead.org, - linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, - Russell King , - Heiner Kallweit , - Lorenzo Bianconi , - Mark Lee , - John Crispin , Felix Fietkau , - AngeloGioacchino Del Regno - , - Matthias Brugger , - DENG Qingfang , - Landen Chao , - Sean Wang , - Paolo Abeni , - Jakub Kicinski , - Eric Dumazet , - "David S. Miller" , - Vladimir Oltean , - Florian Fainelli , - Andrew Lunn , - Vladimir Oltean -Cc: =?iso-8859-1?q?Bj=F8rn?= Mork , - Frank Wunderlich , - Alexander Couzens -Subject: [PATCH net-next v13 11/16] net: dsa: mt7530: use external PCS driver -Message-ID: - <2ac2ee40d3b0e705461b50613fda6a7edfdbc4b3.1678357225.git.daniel@makrotopia.org> -References: -MIME-Version: 1.0 -Content-Disposition: inline -In-Reply-To: -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -Implement regmap access wrappers, for now only to be used by the -pcs-mtk driver. -Make use of external PCS driver and drop the reduntant implementation -in mt7530.c. -As a nice side effect the SGMII registers can now also more easily be -inspected for debugging via /sys/kernel/debug/regmap. - -Reviewed-by: Russell King (Oracle) -Tested-by: Bjørn Mork -Signed-off-by: Daniel Golle -Tested-by: Frank Wunderlich ---- - drivers/net/dsa/Kconfig | 1 + - drivers/net/dsa/mt7530.c | 277 ++++++++++----------------------------- - drivers/net/dsa/mt7530.h | 47 +------ - 3 files changed, 71 insertions(+), 254 deletions(-) - ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -37,6 +37,7 @@ config NET_DSA_MT7530 - tristate "MediaTek MT753x and MT7621 Ethernet switch support" - select NET_DSA_TAG_MTK - select MEDIATEK_GE_PHY -+ select PCS_MTK_LYNXI - help - This enables support for the MediaTek MT7530, MT7531, and MT7621 - Ethernet switch chips. ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2831,128 +2832,11 @@ static int mt7531_rgmii_setup(struct mt7 - return 0; - } - --static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -- phy_interface_t interface, int speed, int duplex) --{ -- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; -- int port = pcs_to_mt753x_pcs(pcs)->port; -- unsigned int val; -- -- /* For adjusting speed and duplex of SGMII force mode. */ -- if (interface != PHY_INTERFACE_MODE_SGMII || -- phylink_autoneg_inband(mode)) -- return; -- -- /* SGMII force mode setting */ -- val = mt7530_read(priv, MT7531_SGMII_MODE(port)); -- val &= ~MT7531_SGMII_IF_MODE_MASK; -- -- switch (speed) { -- case SPEED_10: -- val |= MT7531_SGMII_FORCE_SPEED_10; -- break; -- case SPEED_100: -- val |= MT7531_SGMII_FORCE_SPEED_100; -- break; -- case SPEED_1000: -- val |= MT7531_SGMII_FORCE_SPEED_1000; -- break; -- } -- -- /* MT7531 SGMII 1G force mode can only work in full duplex mode, -- * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. -- * -- * The speed check is unnecessary as the MAC capabilities apply -- * this restriction. --rmk -- */ -- if ((speed == SPEED_10 || speed == SPEED_100) && -- duplex != DUPLEX_FULL) -- val |= MT7531_SGMII_FORCE_HALF_DUPLEX; -- -- mt7530_write(priv, MT7531_SGMII_MODE(port), val); --} -- - static bool mt753x_is_mac_port(u32 port) - { - return (port == 5 || port == 6); - } - --static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port, -- phy_interface_t interface) --{ -- u32 val; -- -- if (!mt753x_is_mac_port(port)) -- return -EINVAL; -- -- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port), -- MT7531_SGMII_PHYA_PWD); -- -- val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port)); -- val &= ~MT7531_RG_TPHY_SPEED_MASK; -- /* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B -- * encoding. -- */ -- val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ? -- MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G; -- mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val); -- -- mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE); -- -- /* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex -- * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. -- */ -- mt7530_rmw(priv, MT7531_SGMII_MODE(port), -- MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS, -- MT7531_SGMII_FORCE_SPEED_1000); -- -- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0); -- -- return 0; --} -- --static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port, -- phy_interface_t interface) --{ -- if (!mt753x_is_mac_port(port)) -- return -EINVAL; -- -- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port), -- MT7531_SGMII_PHYA_PWD); -- -- mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port), -- MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G); -- -- mt7530_set(priv, MT7531_SGMII_MODE(port), -- MT7531_SGMII_REMOTE_FAULT_DIS | -- MT7531_SGMII_SPEED_DUPLEX_AN); -- -- mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port), -- MT7531_SGMII_TX_CONFIG_MASK, 1); -- -- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE); -- -- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART); -- -- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0); -- -- return 0; --} -- --static void mt7531_pcs_an_restart(struct phylink_pcs *pcs) --{ -- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; -- int port = pcs_to_mt753x_pcs(pcs)->port; -- u32 val; -- -- /* Only restart AN when AN is enabled */ -- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); -- if (val & MT7531_SGMII_AN_ENABLE) { -- val |= MT7531_SGMII_AN_RESTART; -- mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val); -- } --} -- - static int - mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - phy_interface_t interface) -@@ -2975,11 +2859,11 @@ mt7531_mac_config(struct dsa_switch *ds, - phydev = dp->slave->phydev; - return mt7531_rgmii_setup(priv, port, interface, phydev); - case PHY_INTERFACE_MODE_SGMII: -- return mt7531_sgmii_setup_mode_an(priv, port, interface); - case PHY_INTERFACE_MODE_NA: - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_2500BASEX: -- return mt7531_sgmii_setup_mode_force(priv, port, interface); -+ /* handled in SGMII PCS driver */ -+ return 0; - default: - return -EINVAL; - } -@@ -3004,11 +2888,11 @@ mt753x_phylink_mac_select_pcs(struct dsa - - switch (interface) { - case PHY_INTERFACE_MODE_TRGMII: -+ return &priv->pcs[port].pcs; - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_2500BASEX: -- return &priv->pcs[port].pcs; -- -+ return priv->ports[port].sgmii_pcs; - default: - return NULL; - } -@@ -3249,86 +3133,6 @@ static void mt7530_pcs_get_state(struct - state->pause |= MLO_PAUSE_TX; - } - --static int --mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port, -- struct phylink_link_state *state) --{ -- u32 status, val; -- u16 config_reg; -- -- status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); -- state->link = !!(status & MT7531_SGMII_LINK_STATUS); -- state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE); -- if (state->interface == PHY_INTERFACE_MODE_SGMII && -- (status & MT7531_SGMII_AN_ENABLE)) { -- val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port)); -- config_reg = val >> 16; -- -- switch (config_reg & LPA_SGMII_SPD_MASK) { -- case LPA_SGMII_1000: -- state->speed = SPEED_1000; -- break; -- case LPA_SGMII_100: -- state->speed = SPEED_100; -- break; -- case LPA_SGMII_10: -- state->speed = SPEED_10; -- break; -- default: -- dev_err(priv->dev, "invalid sgmii PHY speed\n"); -- state->link = false; -- return -EINVAL; -- } -- -- if (config_reg & LPA_SGMII_FULL_DUPLEX) -- state->duplex = DUPLEX_FULL; -- else -- state->duplex = DUPLEX_HALF; -- } -- -- return 0; --} -- --static void --mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port, -- struct phylink_link_state *state) --{ -- unsigned int val; -- -- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); -- state->link = !!(val & MT7531_SGMII_LINK_STATUS); -- if (!state->link) -- return; -- -- state->an_complete = state->link; -- -- if (state->interface == PHY_INTERFACE_MODE_2500BASEX) -- state->speed = SPEED_2500; -- else -- state->speed = SPEED_1000; -- -- state->duplex = DUPLEX_FULL; -- state->pause = MLO_PAUSE_NONE; --} -- --static void mt7531_pcs_get_state(struct phylink_pcs *pcs, -- struct phylink_link_state *state) --{ -- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; -- int port = pcs_to_mt753x_pcs(pcs)->port; -- -- if (state->interface == PHY_INTERFACE_MODE_SGMII) { -- mt7531_sgmii_pcs_get_state_an(priv, port, state); -- return; -- } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) || -- (state->interface == PHY_INTERFACE_MODE_2500BASEX)) { -- mt7531_sgmii_pcs_get_state_inband(priv, port, state); -- return; -- } -- -- state->link = false; --} -- - static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, - phy_interface_t interface, - const unsigned long *advertising, -@@ -3348,18 +3152,57 @@ static const struct phylink_pcs_ops mt75 - .pcs_an_restart = mt7530_pcs_an_restart, - }; - --static const struct phylink_pcs_ops mt7531_pcs_ops = { -- .pcs_validate = mt753x_pcs_validate, -- .pcs_get_state = mt7531_pcs_get_state, -- .pcs_config = mt753x_pcs_config, -- .pcs_an_restart = mt7531_pcs_an_restart, -- .pcs_link_up = mt7531_pcs_link_up, -+static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) -+{ -+ struct mt7530_priv *priv = context; -+ -+ *val = mt7530_read(priv, reg); -+ return 0; -+}; -+ -+static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) -+{ -+ struct mt7530_priv *priv = context; -+ -+ mt7530_write(priv, reg, val); -+ return 0; -+}; -+ -+static int mt7530_regmap_update_bits(void *context, unsigned int reg, -+ unsigned int mask, unsigned int val) -+{ -+ struct mt7530_priv *priv = context; -+ -+ mt7530_rmw(priv, reg, mask, val); -+ return 0; -+}; -+ -+static const struct regmap_bus mt7531_regmap_bus = { -+ .reg_write = mt7530_regmap_write, -+ .reg_read = mt7530_regmap_read, -+ .reg_update_bits = mt7530_regmap_update_bits, -+}; -+ -+#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \ -+ { \ -+ .name = _name, \ -+ .reg_bits = 16, \ -+ .val_bits = 32, \ -+ .reg_stride = 4, \ -+ .reg_base = _reg_base, \ -+ .max_register = 0x17c, \ -+ } -+ -+static const struct regmap_config mt7531_pcs_config[] = { -+ MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)), -+ MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)), - }; - - static int - mt753x_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; -+ struct regmap *regmap; - int i, ret; - - /* Initialise the PCS devices */ -@@ -3367,8 +3210,6 @@ mt753x_setup(struct dsa_switch *ds) - priv->pcs[i].pcs.ops = priv->info->pcs_ops; - priv->pcs[i].priv = priv; - priv->pcs[i].port = i; -- if (mt753x_is_mac_port(i)) -- priv->pcs[i].pcs.poll = 1; - } - - ret = priv->info->sw_setup(ds); -@@ -3383,6 +3224,16 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -+ if (priv->id == ID_MT7531) -+ for (i = 0; i < 2; i++) { -+ regmap = devm_regmap_init(ds->dev, -+ &mt7531_regmap_bus, priv, -+ &mt7531_pcs_config[i]); -+ priv->ports[5 + i].sgmii_pcs = -+ mtk_pcs_lynxi_create(ds->dev, regmap, -+ MT7531_PHYA_CTRL_SIGNAL3, 0); -+ } -+ - return ret; - } - -@@ -3475,7 +3326,7 @@ static const struct mt753x_info mt753x_t - }, - [ID_MT7531] = { - .id = ID_MT7531, -- .pcs_ops = &mt7531_pcs_ops, -+ .pcs_ops = &mt7530_pcs_ops, - .sw_setup = mt7531_setup, - .phy_read = mt7531_ind_phy_read, - .phy_write = mt7531_ind_phy_write, -@@ -3583,7 +3434,7 @@ static void - mt7530_remove(struct mdio_device *mdiodev) - { - struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -- int ret = 0; -+ int ret = 0, i; - - if (!priv) - return; -@@ -3602,6 +3453,10 @@ mt7530_remove(struct mdio_device *mdiode - mt7530_free_irq(priv); - - dsa_unregister_switch(priv->ds); -+ -+ for (i = 0; i < 2; ++i) -+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs); -+ - mutex_destroy(&priv->reg_mutex); - - dev_set_drvdata(&mdiodev->dev, NULL); ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -401,47 +401,8 @@ enum mt7530_vlan_port_acc_frm { - CCR_TX_OCT_CNT_BAD) - - /* MT7531 SGMII register group */ --#define MT7531_SGMII_REG_BASE 0x5000 --#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \ -- ((p) - 5) * 0x1000 + (r)) -- --/* Register forSGMII PCS_CONTROL_1 */ --#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(p, 0x00) --#define MT7531_SGMII_LINK_STATUS BIT(18) --#define MT7531_SGMII_AN_ENABLE BIT(12) --#define MT7531_SGMII_AN_RESTART BIT(9) --#define MT7531_SGMII_AN_COMPLETE BIT(21) -- --/* Register for SGMII PCS_SPPED_ABILITY */ --#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08) --#define MT7531_SGMII_TX_CONFIG_MASK GENMASK(15, 0) --#define MT7531_SGMII_TX_CONFIG BIT(0) -- --/* Register for SGMII_MODE */ --#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(p, 0x20) --#define MT7531_SGMII_REMOTE_FAULT_DIS BIT(8) --#define MT7531_SGMII_IF_MODE_MASK GENMASK(5, 1) --#define MT7531_SGMII_FORCE_DUPLEX BIT(4) --#define MT7531_SGMII_FORCE_SPEED_MASK GENMASK(3, 2) --#define MT7531_SGMII_FORCE_SPEED_1000 BIT(3) --#define MT7531_SGMII_FORCE_SPEED_100 BIT(2) --#define MT7531_SGMII_FORCE_SPEED_10 0 --#define MT7531_SGMII_SPEED_DUPLEX_AN BIT(1) -- --enum mt7531_sgmii_force_duplex { -- MT7531_SGMII_FORCE_FULL_DUPLEX = 0, -- MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10, --}; -- --/* Fields of QPHY_PWR_STATE_CTRL */ --#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8) --#define MT7531_SGMII_PHYA_PWD BIT(4) -- --/* Values of SGMII SPEED */ --#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(p, 0x128) --#define MT7531_RG_TPHY_SPEED_MASK (BIT(2) | BIT(3)) --#define MT7531_RG_TPHY_SPEED_1_25G 0x0 --#define MT7531_RG_TPHY_SPEED_3_125G BIT(2) -+#define MT7531_SGMII_REG_BASE(p) (0x5000 + ((p) - 5) * 0x1000) -+#define MT7531_PHYA_CTRL_SIGNAL3 0x128 - - /* Register for system reset */ - #define MT7530_SYS_CTRL 0x7000 -@@ -741,13 +702,13 @@ struct mt7530_fdb { - * @pm: The matrix used to show all connections with the port. - * @pvid: The VLAN specified is to be considered a PVID at ingress. Any - * untagged frames will be assigned to the related VLAN. -- * @vlan_filtering: The flags indicating whether the port that can recognize -- * VLAN-tagged frames. -+ * @sgmii_pcs: Pointer to PCS instance for SerDes ports - */ - struct mt7530_port { - bool enable; - u32 pm; - u16 pvid; -+ struct phylink_pcs *sgmii_pcs; - }; - - /* Port 5 interface select definitions */ diff --git a/target/linux/generic/backport-5.15/789-v6.3-net-sfp-add-quirk-enabling-2500Base-x-for-HG-MXPD-48.patch b/target/linux/generic/backport-5.15/789-v6.3-net-sfp-add-quirk-enabling-2500Base-x-for-HG-MXPD-48.patch deleted file mode 100644 index 413c73f547863e..00000000000000 --- a/target/linux/generic/backport-5.15/789-v6.3-net-sfp-add-quirk-enabling-2500Base-x-for-HG-MXPD-48.patch +++ /dev/null @@ -1,37 +0,0 @@ -From ad651d68cee75e9ac20002254c4e5d09ee67a84b Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 2 Apr 2023 12:44:37 +0100 -Subject: [PATCH] net: sfp: add quirk enabling 2500Base-x for HG MXPD-483II - -The HG MXPD-483II 1310nm SFP module is meant to operate with 2500Base-X, -however, in their EEPROM they incorrectly specify: - Transceiver type : Ethernet: 1000BASE-LX - ... - BR, Nominal : 2600MBd - -Use sfp_quirk_2500basex for this module to allow 2500Base-X mode anyway. - -https://forum.banana-pi.org/t/bpi-r3-sfp-module-compatibility/14573/60 - -Reported-by: chowtom -Tested-by: chowtom -Signed-off-by: Daniel Golle -Reviewed-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/sfp.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -372,6 +372,10 @@ static const struct sfp_quirk sfp_quirks - .part = "HL-GSFP", - .fixup = sfp_fixup_halny_gsfp, - }, { -+ .vendor = "HG GENUINE", -+ .part = "MXPD-483II", -+ .modes = sfp_quirk_2500basex, -+ }, { - // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd - // NRZ in their EEPROM - .vendor = "HUAWEI", diff --git a/target/linux/generic/backport-5.15/790-v6.0-net-mii-add-mii_bmcr_encode_fixed.patch b/target/linux/generic/backport-5.15/790-v6.0-net-mii-add-mii_bmcr_encode_fixed.patch deleted file mode 100644 index 87d7ff6154d128..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.0-net-mii-add-mii_bmcr_encode_fixed.patch +++ /dev/null @@ -1,55 +0,0 @@ -From bdb6cfe7512f7a214815a3092f0be50963dcacbc Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Sat, 18 Jun 2022 11:28:32 +0100 -Subject: [PATCH] net: mii: add mii_bmcr_encode_fixed() - -Add a function to encode a fixed speed/duplex to a BMCR value. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - include/linux/mii.h | 35 +++++++++++++++++++++++++++++++++++ - 1 file changed, 35 insertions(+) - ---- a/include/linux/mii.h -+++ b/include/linux/mii.h -@@ -595,4 +595,39 @@ static inline u8 mii_resolve_flowctrl_fd - return cap; - } - -+/** -+ * mii_bmcr_encode_fixed - encode fixed speed/duplex settings to a BMCR value -+ * @speed: a SPEED_* value -+ * @duplex: a DUPLEX_* value -+ * -+ * Encode the speed and duplex to a BMCR value. 2500, 1000, 100 and 10 Mbps are -+ * supported. 2500Mbps is encoded to 1000Mbps. Other speeds are encoded as 10 -+ * Mbps. Unknown duplex values are encoded to half-duplex. -+ */ -+static inline u16 mii_bmcr_encode_fixed(int speed, int duplex) -+{ -+ u16 bmcr; -+ -+ switch (speed) { -+ case SPEED_2500: -+ case SPEED_1000: -+ bmcr = BMCR_SPEED1000; -+ break; -+ -+ case SPEED_100: -+ bmcr = BMCR_SPEED100; -+ break; -+ -+ case SPEED_10: -+ default: -+ bmcr = BMCR_SPEED10; -+ break; -+ } -+ -+ if (duplex == DUPLEX_FULL) -+ bmcr |= BMCR_FULLDPLX; -+ -+ return bmcr; -+} -+ - #endif /* __LINUX_MII_H__ */ diff --git a/target/linux/generic/backport-5.15/790-v6.4-0001-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch b/target/linux/generic/backport-5.15/790-v6.4-0001-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch deleted file mode 100644 index cfd0034ee637d9..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0001-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch +++ /dev/null @@ -1,32 +0,0 @@ -From b6f56cddb5f57a0b8da0ce582232a2f1933558c6 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:17:19 +0100 -Subject: [PATCH 04/16] net: dsa: mt7530: make some noise if register read - fails - -Simply returning the negative error value instead of the read value -doesn't seem like a good idea. Return 0 instead and add WARN_ON_ONCE(1) -so this kind of error will not go unnoticed. - -Suggested-by: Andrew Lunn -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -225,9 +225,10 @@ mt7530_mii_read(struct mt7530_priv *priv - /* MT7530 uses 31 as the pseudo port */ - ret = bus->write(bus, 0x1f, 0x1f, page); - if (ret < 0) { -+ WARN_ON_ONCE(1); - dev_err(&bus->dev, - "failed to read mt7530 register\n"); -- return ret; -+ return 0; - } - - lo = bus->read(bus, 0x1f, r); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch b/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch deleted file mode 100644 index 62d9c78cca3fd7..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0002-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 9ecc00164dc2300dfcd40afe549a8ee951dfea9f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:17:30 +0100 -Subject: [PATCH 05/16] net: dsa: mt7530: refactor SGMII PCS creation - -Instead of macro templates use a dedidated function and allocated -regmap_config when creating the regmaps for the pcs-mtk-lynxi -instances. -This is in preparation to switching to use unlocked regmap accessors -and have regmap's locking API handle locking for us. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 74 +++++++++++++++++++++++++++------------- - 1 file changed, 50 insertions(+), 24 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3184,26 +3184,56 @@ static const struct regmap_bus mt7531_re - .reg_update_bits = mt7530_regmap_update_bits, - }; - --#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \ -- { \ -- .name = _name, \ -- .reg_bits = 16, \ -- .val_bits = 32, \ -- .reg_stride = 4, \ -- .reg_base = _reg_base, \ -- .max_register = 0x17c, \ -+static int -+mt7531_create_sgmii(struct mt7530_priv *priv) -+{ -+ struct regmap_config *mt7531_pcs_config[2]; -+ struct phylink_pcs *pcs; -+ struct regmap *regmap; -+ int i, ret = 0; -+ -+ for (i = 0; i < 2; i++) { -+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev, -+ sizeof(struct regmap_config), -+ GFP_KERNEL); -+ if (!mt7531_pcs_config[i]) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ mt7531_pcs_config[i]->name = i ? "port6" : "port5"; -+ mt7531_pcs_config[i]->reg_bits = 16; -+ mt7531_pcs_config[i]->val_bits = 32; -+ mt7531_pcs_config[i]->reg_stride = 4; -+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); -+ mt7531_pcs_config[i]->max_register = 0x17c; -+ -+ regmap = devm_regmap_init(priv->dev, -+ &mt7531_regmap_bus, priv, -+ mt7531_pcs_config[i]); -+ if (IS_ERR(regmap)) { -+ ret = PTR_ERR(regmap); -+ break; -+ } -+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap, -+ MT7531_PHYA_CTRL_SIGNAL3, 0); -+ if (!pcs) { -+ ret = -ENXIO; -+ break; -+ } -+ priv->ports[5 + i].sgmii_pcs = pcs; - } - --static const struct regmap_config mt7531_pcs_config[] = { -- MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)), -- MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)), --}; -+ if (ret && i) -+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs); -+ -+ return ret; -+} - - static int - mt753x_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; -- struct regmap *regmap; - int i, ret; - - /* Initialise the PCS devices */ -@@ -3225,15 +3255,11 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -- if (priv->id == ID_MT7531) -- for (i = 0; i < 2; i++) { -- regmap = devm_regmap_init(ds->dev, -- &mt7531_regmap_bus, priv, -- &mt7531_pcs_config[i]); -- priv->ports[5 + i].sgmii_pcs = -- mtk_pcs_lynxi_create(ds->dev, regmap, -- MT7531_PHYA_CTRL_SIGNAL3, 0); -- } -+ if (priv->id == ID_MT7531) { -+ ret = mt7531_create_sgmii(priv); -+ if (ret && priv->irq) -+ mt7530_free_irq_common(priv); -+ } - - return ret; - } diff --git a/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch b/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch deleted file mode 100644 index e9f69a8777abbd..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0003-net-dsa-mt7530-use-unlocked-regmap-accessors.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 1bd099c49f65ed923b9f19b8c4b3cd1ff0024091 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:17:40 +0100 -Subject: [PATCH 06/16] net: dsa: mt7530: use unlocked regmap accessors - -Instead of wrapping the locked register accessor functions, use the -unlocked variants and add locking wrapper functions to let regmap -handle the locking. - -This is a preparation towards being able to always use regmap to -access switch registers instead of open-coded accessor functions. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 23 ++++++++++++++--------- - 1 file changed, 14 insertions(+), 9 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3157,7 +3157,7 @@ static int mt7530_regmap_read(void *cont - { - struct mt7530_priv *priv = context; - -- *val = mt7530_read(priv, reg); -+ *val = mt7530_mii_read(priv, reg); - return 0; - }; - -@@ -3165,23 +3165,25 @@ static int mt7530_regmap_write(void *con - { - struct mt7530_priv *priv = context; - -- mt7530_write(priv, reg, val); -+ mt7530_mii_write(priv, reg, val); - return 0; - }; - --static int mt7530_regmap_update_bits(void *context, unsigned int reg, -- unsigned int mask, unsigned int val) -+static void -+mt7530_mdio_regmap_lock(void *mdio_lock) - { -- struct mt7530_priv *priv = context; -+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED); -+} - -- mt7530_rmw(priv, reg, mask, val); -- return 0; --}; -+static void -+mt7530_mdio_regmap_unlock(void *mdio_lock) -+{ -+ mutex_unlock(mdio_lock); -+} - - static const struct regmap_bus mt7531_regmap_bus = { - .reg_write = mt7530_regmap_write, - .reg_read = mt7530_regmap_read, -- .reg_update_bits = mt7530_regmap_update_bits, - }; - - static int -@@ -3207,6 +3209,9 @@ mt7531_create_sgmii(struct mt7530_priv * - mt7531_pcs_config[i]->reg_stride = 4; - mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); - mt7531_pcs_config[i]->max_register = 0x17c; -+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock; -+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock; -+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; - - regmap = devm_regmap_init(priv->dev, - &mt7531_regmap_bus, priv, diff --git a/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch b/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch deleted file mode 100644 index a2dcc08b026478..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0004-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch +++ /dev/null @@ -1,224 +0,0 @@ -From a08c045580e060a6886bbb656c50ae20b0c780b5 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:17:52 +0100 -Subject: [PATCH 07/16] net: dsa: mt7530: use regmap to access switch register - space - -Use regmap API to access the switch register space. - -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++++---------------- - drivers/net/dsa/mt7530.h | 2 + - 2 files changed, 62 insertions(+), 39 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -184,9 +184,9 @@ core_clear(struct mt7530_priv *priv, u32 - } - - static int --mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val) -+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) - { -- struct mii_bus *bus = priv->bus; -+ struct mii_bus *bus = context; - u16 page, r, lo, hi; - int ret; - -@@ -198,24 +198,34 @@ mt7530_mii_write(struct mt7530_priv *pri - /* MT7530 uses 31 as the pseudo port */ - ret = bus->write(bus, 0x1f, 0x1f, page); - if (ret < 0) -- goto err; -+ return ret; - - ret = bus->write(bus, 0x1f, r, lo); - if (ret < 0) -- goto err; -+ return ret; - - ret = bus->write(bus, 0x1f, 0x10, hi); --err: -+ return ret; -+} -+ -+static int -+mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val) -+{ -+ int ret; -+ -+ ret = regmap_write(priv->regmap, reg, val); -+ - if (ret < 0) -- dev_err(&bus->dev, -+ dev_err(priv->dev, - "failed to write mt7530 register\n"); -+ - return ret; - } - --static u32 --mt7530_mii_read(struct mt7530_priv *priv, u32 reg) -+static int -+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) - { -- struct mii_bus *bus = priv->bus; -+ struct mii_bus *bus = context; - u16 page, r, lo, hi; - int ret; - -@@ -224,17 +234,32 @@ mt7530_mii_read(struct mt7530_priv *priv - - /* MT7530 uses 31 as the pseudo port */ - ret = bus->write(bus, 0x1f, 0x1f, page); -- if (ret < 0) { -+ if (ret < 0) -+ return ret; -+ -+ lo = bus->read(bus, 0x1f, r); -+ hi = bus->read(bus, 0x1f, 0x10); -+ -+ *val = (hi << 16) | (lo & 0xffff); -+ -+ return 0; -+} -+ -+static u32 -+mt7530_mii_read(struct mt7530_priv *priv, u32 reg) -+{ -+ int ret; -+ u32 val; -+ -+ ret = regmap_read(priv->regmap, reg, &val); -+ if (ret) { - WARN_ON_ONCE(1); -- dev_err(&bus->dev, -+ dev_err(priv->dev, - "failed to read mt7530 register\n"); - return 0; - } - -- lo = bus->read(bus, 0x1f, r); -- hi = bus->read(bus, 0x1f, 0x10); -- -- return (hi << 16) | (lo & 0xffff); -+ return val; - } - - static void -@@ -284,14 +309,10 @@ mt7530_rmw(struct mt7530_priv *priv, u32 - u32 mask, u32 set) - { - struct mii_bus *bus = priv->bus; -- u32 val; - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - -- val = mt7530_mii_read(priv, reg); -- val &= ~mask; -- val |= set; -- mt7530_mii_write(priv, reg, val); -+ regmap_update_bits(priv->regmap, reg, mask, set); - - mutex_unlock(&bus->mdio_lock); - } -@@ -299,7 +320,7 @@ mt7530_rmw(struct mt7530_priv *priv, u32 - static void - mt7530_set(struct mt7530_priv *priv, u32 reg, u32 val) - { -- mt7530_rmw(priv, reg, 0, val); -+ mt7530_rmw(priv, reg, val, val); - } - - static void -@@ -3153,22 +3174,6 @@ static const struct phylink_pcs_ops mt75 - .pcs_an_restart = mt7530_pcs_an_restart, - }; - --static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) --{ -- struct mt7530_priv *priv = context; -- -- *val = mt7530_mii_read(priv, reg); -- return 0; --}; -- --static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) --{ -- struct mt7530_priv *priv = context; -- -- mt7530_mii_write(priv, reg, val); -- return 0; --}; -- - static void - mt7530_mdio_regmap_lock(void *mdio_lock) - { -@@ -3181,7 +3186,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc - mutex_unlock(mdio_lock); - } - --static const struct regmap_bus mt7531_regmap_bus = { -+static const struct regmap_bus mt7530_regmap_bus = { - .reg_write = mt7530_regmap_write, - .reg_read = mt7530_regmap_read, - }; -@@ -3214,7 +3219,7 @@ mt7531_create_sgmii(struct mt7530_priv * - mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; - - regmap = devm_regmap_init(priv->dev, -- &mt7531_regmap_bus, priv, -+ &mt7530_regmap_bus, priv->bus, - mt7531_pcs_config[i]); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); -@@ -3380,6 +3385,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match) - static int - mt7530_probe(struct mdio_device *mdiodev) - { -+ static struct regmap_config *regmap_config; - struct mt7530_priv *priv; - struct device_node *dn; - -@@ -3459,6 +3465,21 @@ mt7530_probe(struct mdio_device *mdiodev - mutex_init(&priv->reg_mutex); - dev_set_drvdata(&mdiodev->dev, priv); - -+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config), -+ GFP_KERNEL); -+ if (!regmap_config) -+ return -ENOMEM; -+ -+ regmap_config->reg_bits = 16; -+ regmap_config->val_bits = 32; -+ regmap_config->reg_stride = 4; -+ regmap_config->max_register = MT7530_CREV; -+ regmap_config->disable_locking = true; -+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, -+ priv->bus, regmap_config); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); -+ - return dsa_register_switch(priv->ds); - } - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -785,6 +785,7 @@ struct mt753x_info { - * @dev: The device pointer - * @ds: The pointer to the dsa core structure - * @bus: The bus used for the device and built-in PHY -+ * @regmap: The regmap instance representing all switch registers - * @rstc: The pointer to reset control used by MCM - * @core_pwr: The power supplied into the core - * @io_pwr: The power supplied into the I/O -@@ -805,6 +806,7 @@ struct mt7530_priv { - struct device *dev; - struct dsa_switch *ds; - struct mii_bus *bus; -+ struct regmap *regmap; - struct reset_control *rstc; - struct regulator *core_pwr; - struct regulator *io_pwr; diff --git a/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch b/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch deleted file mode 100644 index abbecd5e402056..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0005-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 6de2852297737171ba96b91e89bf302ca1fda869 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:18:04 +0100 -Subject: [PATCH 08/16] net: dsa: mt7530: move SGMII PCS creation to - mt7530_probe function - -Move creating the SGMII PCS from mt753x_setup() to the more appropriate -mt7530_probe() function. -This is done also in preparation of moving all functions related to -MDIO-connected MT753x switches to a separate module. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3265,12 +3265,6 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -- if (priv->id == ID_MT7531) { -- ret = mt7531_create_sgmii(priv); -- if (ret && priv->irq) -- mt7530_free_irq_common(priv); -- } -- - return ret; - } - -@@ -3388,6 +3382,7 @@ mt7530_probe(struct mdio_device *mdiodev - static struct regmap_config *regmap_config; - struct mt7530_priv *priv; - struct device_node *dn; -+ int ret; - - dn = mdiodev->dev.of_node; - -@@ -3480,6 +3475,12 @@ mt7530_probe(struct mdio_device *mdiodev - if (IS_ERR(priv->regmap)) - return PTR_ERR(priv->regmap); - -+ if (priv->id == ID_MT7531) { -+ ret = mt7531_create_sgmii(priv); -+ if (ret) -+ return ret; -+ } -+ - return dsa_register_switch(priv->ds); - } - diff --git a/target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch b/target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch deleted file mode 100644 index ef02d469387d50..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0006-net-dsa-mt7530-introduce-mutex-helpers.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 1557c679f71c82a994eae0baadbaeb62b71e15bf Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:18:16 +0100 -Subject: [PATCH 09/16] net: dsa: mt7530: introduce mutex helpers - -As the MDIO bus lock only needs to be involved if actually operating -on an MDIO-connected switch we will need to skip locking for built-in -switches which are accessed via MMIO. -Create helper functions which simplify that upcoming change. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 73 ++++++++++++++++++++-------------------- - 1 file changed, 36 insertions(+), 37 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -144,31 +144,40 @@ err: - } - - static void --core_write(struct mt7530_priv *priv, u32 reg, u32 val) -+mt7530_mutex_lock(struct mt7530_priv *priv) - { -- struct mii_bus *bus = priv->bus; -+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); -+} - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+static void -+mt7530_mutex_unlock(struct mt7530_priv *priv) -+{ -+ mutex_unlock(&priv->bus->mdio_lock); -+} -+ -+static void -+core_write(struct mt7530_priv *priv, u32 reg, u32 val) -+{ -+ mt7530_mutex_lock(priv); - - core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - } - - static void - core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set) - { -- struct mii_bus *bus = priv->bus; - u32 val; - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2); - val &= ~mask; - val |= set; - core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - } - - static void -@@ -265,13 +274,11 @@ mt7530_mii_read(struct mt7530_priv *priv - static void - mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val) - { -- struct mii_bus *bus = priv->bus; -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - mt7530_mii_write(priv, reg, val); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - } - - static u32 -@@ -283,14 +290,13 @@ _mt7530_unlocked_read(struct mt7530_dumm - static u32 - _mt7530_read(struct mt7530_dummy_poll *p) - { -- struct mii_bus *bus = p->priv->bus; - u32 val; - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(p->priv); - - val = mt7530_mii_read(p->priv, p->reg); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(p->priv); - - return val; - } -@@ -308,13 +314,11 @@ static void - mt7530_rmw(struct mt7530_priv *priv, u32 reg, - u32 mask, u32 set) - { -- struct mii_bus *bus = priv->bus; -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - regmap_update_bits(priv->regmap, reg, mask, set); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - } - - static void -@@ -660,14 +664,13 @@ static int - mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad, - int regnum) - { -- struct mii_bus *bus = priv->bus; - struct mt7530_dummy_poll p; - u32 reg, val; - int ret; - - INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, - !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -700,7 +703,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr - - ret = val & MT7531_MDIO_RW_DATA_MASK; - out: -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - return ret; - } -@@ -709,14 +712,13 @@ static int - mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad, - int regnum, u32 data) - { -- struct mii_bus *bus = priv->bus; - struct mt7530_dummy_poll p; - u32 val, reg; - int ret; - - INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, - !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -748,7 +750,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p - } - - out: -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - return ret; - } -@@ -756,14 +758,13 @@ out: - static int - mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum) - { -- struct mii_bus *bus = priv->bus; - struct mt7530_dummy_poll p; - int ret; - u32 val; - - INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, - !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -786,7 +787,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr - - ret = val & MT7531_MDIO_RW_DATA_MASK; - out: -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - return ret; - } -@@ -795,14 +796,13 @@ static int - mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum, - u16 data) - { -- struct mii_bus *bus = priv->bus; - struct mt7530_dummy_poll p; - int ret; - u32 reg; - - INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg, - !(reg & MT7531_PHY_ACS_ST), 20, 100000); -@@ -824,7 +824,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p - } - - out: -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - return ret; - } -@@ -1344,7 +1344,6 @@ static int - mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) - { - struct mt7530_priv *priv = ds->priv; -- struct mii_bus *bus = priv->bus; - int length; - u32 val; - -@@ -1355,7 +1354,7 @@ mt7530_port_change_mtu(struct dsa_switch - if (!dsa_is_cpu_port(ds, port)) - return 0; - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - val = mt7530_mii_read(priv, MT7530_GMACCR); - val &= ~MAX_RX_PKT_LEN_MASK; -@@ -1376,7 +1375,7 @@ mt7530_port_change_mtu(struct dsa_switch - - mt7530_mii_write(priv, MT7530_GMACCR, val); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - return 0; - } -@@ -2172,10 +2171,10 @@ mt7530_irq_thread_fn(int irq, void *dev_ - u32 val; - int p; - -- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - val = mt7530_mii_read(priv, MT7530_SYS_INT_STS); - mt7530_mii_write(priv, MT7530_SYS_INT_STS, val); -- mutex_unlock(&priv->bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - for (p = 0; p < MT7530_NUM_PHYS; p++) { - if (BIT(p) & val) { -@@ -2211,7 +2210,7 @@ mt7530_irq_bus_lock(struct irq_data *d) - { - struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); - -- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - } - - static void -@@ -2220,7 +2219,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da - struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); - - mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable); -- mutex_unlock(&priv->bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - } - - static struct irq_chip mt7530_irq_chip = { diff --git a/target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch b/target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch deleted file mode 100644 index 2e1ed2e652a65b..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0007-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 25d15dee34a1a40d5fd71636a205e3211f09fd1d Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:18:28 +0100 -Subject: [PATCH 10/16] net: dsa: mt7530: move p5_intf_modes() function to - mt7530.c - -In preparation of splitting mt7530.c into a driver for MDIO-connected -as well as MDIO-accessed built-in switches on one hand and MMIO-accessed -built-in switches move the p5_inft_modes() function from mt7530.h to -mt7530.c. The function is only needed there and will trigger a compiler -warning about a defined but unused function otherwise when including -mt7530.h in the to-be-introduced bus-specific drivers. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 18 ++++++++++++++++++ - drivers/net/dsa/mt7530.h | 18 ------------------ - 2 files changed, 18 insertions(+), 18 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -965,6 +965,24 @@ mt7530_set_ageing_time(struct dsa_switch - return 0; - } - -+static const char *p5_intf_modes(unsigned int p5_interface) -+{ -+ switch (p5_interface) { -+ case P5_DISABLED: -+ return "DISABLED"; -+ case P5_INTF_SEL_PHY_P0: -+ return "PHY P0"; -+ case P5_INTF_SEL_PHY_P4: -+ return "PHY P4"; -+ case P5_INTF_SEL_GMAC5: -+ return "GMAC5"; -+ case P5_INTF_SEL_GMAC5_SGMII: -+ return "GMAC5_SGMII"; -+ default: -+ return "unknown"; -+ } -+} -+ - static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface) - { - struct mt7530_priv *priv = ds->priv; ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -720,24 +720,6 @@ enum p5_interface_select { - P5_INTF_SEL_GMAC5_SGMII, - }; - --static const char *p5_intf_modes(unsigned int p5_interface) --{ -- switch (p5_interface) { -- case P5_DISABLED: -- return "DISABLED"; -- case P5_INTF_SEL_PHY_P0: -- return "PHY P0"; -- case P5_INTF_SEL_PHY_P4: -- return "PHY P4"; -- case P5_INTF_SEL_GMAC5: -- return "GMAC5"; -- case P5_INTF_SEL_GMAC5_SGMII: -- return "GMAC5_SGMII"; -- default: -- return "unknown"; -- } --} -- - struct mt7530_priv; - - struct mt753x_pcs { diff --git a/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch b/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch deleted file mode 100644 index c9ff26ff2060ea..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0008-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 37c9c0d8d0b2e24f8c9af72ecd4edd31537284d3 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:18:39 +0100 -Subject: [PATCH 11/16] net: dsa: mt7530: introduce mt7530_probe_common helper - function - -Move commonly used parts from mt7530_probe into new mt7530_probe_common -helper function which will be used by both, mt7530_probe and the -to-be-introduced mt7988_probe. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 98 ++++++++++++++++++++++------------------ - 1 file changed, 54 insertions(+), 44 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3394,44 +3394,21 @@ static const struct of_device_id mt7530_ - MODULE_DEVICE_TABLE(of, mt7530_of_match); - - static int --mt7530_probe(struct mdio_device *mdiodev) -+mt7530_probe_common(struct mt7530_priv *priv) - { -- static struct regmap_config *regmap_config; -- struct mt7530_priv *priv; -- struct device_node *dn; -- int ret; -+ struct device *dev = priv->dev; - -- dn = mdiodev->dev.of_node; -- -- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- -- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); -+ priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL); - if (!priv->ds) - return -ENOMEM; - -- priv->ds->dev = &mdiodev->dev; -+ priv->ds->dev = dev; - priv->ds->num_ports = MT7530_NUM_PORTS; - -- /* Use medatek,mcm property to distinguish hardware type that would -- * casues a little bit differences on power-on sequence. -- */ -- priv->mcm = of_property_read_bool(dn, "mediatek,mcm"); -- if (priv->mcm) { -- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n"); -- -- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm"); -- if (IS_ERR(priv->rstc)) { -- dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -- return PTR_ERR(priv->rstc); -- } -- } -- - /* Get the hardware identifier from the devicetree node. - * We will need it for some of the clock and regulator setup. - */ -- priv->info = of_device_get_match_data(&mdiodev->dev); -+ priv->info = of_device_get_match_data(dev); - if (!priv->info) - return -EINVAL; - -@@ -3445,23 +3422,53 @@ mt7530_probe(struct mdio_device *mdiodev - return -EINVAL; - - priv->id = priv->info->id; -+ priv->dev = dev; -+ priv->ds->priv = priv; -+ priv->ds->ops = &mt7530_switch_ops; -+ mutex_init(&priv->reg_mutex); -+ dev_set_drvdata(dev, priv); - -- if (priv->id == ID_MT7530) { -- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); -- if (IS_ERR(priv->core_pwr)) -- return PTR_ERR(priv->core_pwr); -+ return 0; -+} - -- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io"); -- if (IS_ERR(priv->io_pwr)) -- return PTR_ERR(priv->io_pwr); -- } -+static int -+mt7530_probe(struct mdio_device *mdiodev) -+{ -+ static struct regmap_config *regmap_config; -+ struct mt7530_priv *priv; -+ struct device_node *dn; -+ int ret; -+ -+ dn = mdiodev->dev.of_node; -+ -+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; - -- /* Not MCM that indicates switch works as the remote standalone -+ priv->bus = mdiodev->bus; -+ priv->dev = &mdiodev->dev; -+ -+ ret = mt7530_probe_common(priv); -+ if (ret) -+ return ret; -+ -+ /* Use medatek,mcm property to distinguish hardware type that would -+ * cause a little bit differences on power-on sequence. -+ * Not MCM that indicates switch works as the remote standalone - * integrated circuit so the GPIO pin would be used to complete - * the reset, otherwise memory-mapped register accessing used - * through syscon provides in the case of MCM. - */ -- if (!priv->mcm) { -+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm"); -+ if (priv->mcm) { -+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n"); -+ -+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm"); -+ if (IS_ERR(priv->rstc)) { -+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -+ return PTR_ERR(priv->rstc); -+ } -+ } else { - priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", - GPIOD_OUT_LOW); - if (IS_ERR(priv->reset)) { -@@ -3470,12 +3477,15 @@ mt7530_probe(struct mdio_device *mdiodev - } - } - -- priv->bus = mdiodev->bus; -- priv->dev = &mdiodev->dev; -- priv->ds->priv = priv; -- priv->ds->ops = &mt7530_switch_ops; -- mutex_init(&priv->reg_mutex); -- dev_set_drvdata(&mdiodev->dev, priv); -+ if (priv->id == ID_MT7530) { -+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); -+ if (IS_ERR(priv->core_pwr)) -+ return PTR_ERR(priv->core_pwr); -+ -+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io"); -+ if (IS_ERR(priv->io_pwr)) -+ return PTR_ERR(priv->io_pwr); -+ } - - regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config), - GFP_KERNEL); diff --git a/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch b/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch deleted file mode 100644 index 7c1c80e7bc5665..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0009-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 720d736351761574af02ed093658ab60de60576c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:18:50 +0100 -Subject: [PATCH 12/16] net: dsa: mt7530: introduce mt7530_remove_common helper - function - -Move commonly used parts from mt7530_remove into new -mt7530_remove_common helper function which will be used by both, -mt7530_remove and the to-be-introduced mt7988_remove. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 18 ++++++++++++------ - 1 file changed, 12 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3512,6 +3512,17 @@ mt7530_probe(struct mdio_device *mdiodev - } - - static void -+mt7530_remove_common(struct mt7530_priv *priv) -+{ -+ if (priv->irq) -+ mt7530_free_irq(priv); -+ -+ dsa_unregister_switch(priv->ds); -+ -+ mutex_destroy(&priv->reg_mutex); -+} -+ -+static void - mt7530_remove(struct mdio_device *mdiodev) - { - struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -@@ -3530,16 +3541,11 @@ mt7530_remove(struct mdio_device *mdiode - dev_err(priv->dev, "Failed to disable io pwr: %d\n", - ret); - -- if (priv->irq) -- mt7530_free_irq(priv); -- -- dsa_unregister_switch(priv->ds); -+ mt7530_remove_common(priv); - - for (i = 0; i < 2; ++i) - mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs); - -- mutex_destroy(&priv->reg_mutex); -- - dev_set_drvdata(&mdiodev->dev, NULL); - } - diff --git a/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch b/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch deleted file mode 100644 index 84883147ac1ec2..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0011-net-dsa-mt7530-introduce-separate-MDIO-driver.patch +++ /dev/null @@ -1,692 +0,0 @@ -From cb675afcddbbeb2bfa6596e3bc236bc026cd425f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:19:13 +0100 -Subject: [PATCH 14/16] net: dsa: mt7530: introduce separate MDIO driver - -Split MT7530 switch driver into a common part and a part specific -for MDIO connected switches and multi-chip modules. -Move MDIO-specific functions to newly introduced mt7530-mdio.c while -keeping the common parts in mt7530.c. -Introduce new Kconfig symbol CONFIG_NET_DSA_MT7530_MDIO which is -implied by CONFIG_NET_DSA_MT7530. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - MAINTAINERS | 1 + - drivers/net/dsa/Kconfig | 15 +- - drivers/net/dsa/Makefile | 1 + - drivers/net/dsa/mt7530-mdio.c | 271 ++++++++++++++++++++++++++++++++++ - drivers/net/dsa/mt7530.c | 264 +-------------------------------- - drivers/net/dsa/mt7530.h | 6 + - 6 files changed, 300 insertions(+), 258 deletions(-) - create mode 100644 drivers/net/dsa/mt7530-mdio.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -11902,6 +11902,7 @@ M: Landen Chao - L: netdev@vger.kernel.org - S: Maintained -+F: drivers/net/dsa/mt7530-mdio.c - F: drivers/net/dsa/mt7530.* - F: net/dsa/tag_mtk.c - ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -37,10 +37,22 @@ config NET_DSA_MT7530 - tristate "MediaTek MT753x and MT7621 Ethernet switch support" - select NET_DSA_TAG_MTK - select MEDIATEK_GE_PHY -+ imply NET_DSA_MT7530_MDIO -+ help -+ This enables support for the MediaTek MT7530 and MT7531 Ethernet -+ switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT, -+ MT7621ST and MT7623AI SoCs, and built-in switch in MT7988 SoC are -+ supported as well. -+ -+config NET_DSA_MT7530_MDIO -+ tristate "MediaTek MT7530 MDIO interface driver" -+ depends on NET_DSA_MT7530 - select PCS_MTK_LYNXI - help -- This enables support for the MediaTek MT7530, MT7531, and MT7621 -- Ethernet switch chips. -+ This enables support for the MediaTek MT7530 and MT7531 switch -+ chips which are connected via MDIO, as well as multi-chip -+ module MT7530 which can be found in the MT7621AT, MT7621DAT, -+ MT7621ST and MT7623AI SoCs. - - config NET_DSA_MV88E6060 - tristate "Marvell 88E6060 ethernet switch chip support" ---- a/drivers/net/dsa/Makefile -+++ b/drivers/net/dsa/Makefile -@@ -7,6 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdi - endif - obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o - obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o -+obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o - obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o - obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o - realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o ---- /dev/null -+++ b/drivers/net/dsa/mt7530-mdio.c -@@ -0,0 +1,271 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mt7530.h" -+ -+static int -+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) -+{ -+ struct mii_bus *bus = context; -+ u16 page, r, lo, hi; -+ int ret; -+ -+ page = (reg >> 6) & 0x3ff; -+ r = (reg >> 2) & 0xf; -+ lo = val & 0xffff; -+ hi = val >> 16; -+ -+ /* MT7530 uses 31 as the pseudo port */ -+ ret = bus->write(bus, 0x1f, 0x1f, page); -+ if (ret < 0) -+ return ret; -+ -+ ret = bus->write(bus, 0x1f, r, lo); -+ if (ret < 0) -+ return ret; -+ -+ ret = bus->write(bus, 0x1f, 0x10, hi); -+ return ret; -+} -+ -+static int -+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) -+{ -+ struct mii_bus *bus = context; -+ u16 page, r, lo, hi; -+ int ret; -+ -+ page = (reg >> 6) & 0x3ff; -+ r = (reg >> 2) & 0xf; -+ -+ /* MT7530 uses 31 as the pseudo port */ -+ ret = bus->write(bus, 0x1f, 0x1f, page); -+ if (ret < 0) -+ return ret; -+ -+ lo = bus->read(bus, 0x1f, r); -+ hi = bus->read(bus, 0x1f, 0x10); -+ -+ *val = (hi << 16) | (lo & 0xffff); -+ -+ return 0; -+} -+ -+static void -+mt7530_mdio_regmap_lock(void *mdio_lock) -+{ -+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED); -+} -+ -+static void -+mt7530_mdio_regmap_unlock(void *mdio_lock) -+{ -+ mutex_unlock(mdio_lock); -+} -+ -+static const struct regmap_bus mt7530_regmap_bus = { -+ .reg_write = mt7530_regmap_write, -+ .reg_read = mt7530_regmap_read, -+}; -+ -+static int -+mt7531_create_sgmii(struct mt7530_priv *priv) -+{ -+ struct regmap_config *mt7531_pcs_config[2]; -+ struct phylink_pcs *pcs; -+ struct regmap *regmap; -+ int i, ret = 0; -+ -+ for (i = 0; i < 2; i++) { -+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev, -+ sizeof(struct regmap_config), -+ GFP_KERNEL); -+ if (!mt7531_pcs_config[i]) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ mt7531_pcs_config[i]->name = i ? "port6" : "port5"; -+ mt7531_pcs_config[i]->reg_bits = 16; -+ mt7531_pcs_config[i]->val_bits = 32; -+ mt7531_pcs_config[i]->reg_stride = 4; -+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); -+ mt7531_pcs_config[i]->max_register = 0x17c; -+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock; -+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock; -+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; -+ -+ regmap = devm_regmap_init(priv->dev, -+ &mt7530_regmap_bus, priv->bus, -+ mt7531_pcs_config[i]); -+ if (IS_ERR(regmap)) { -+ ret = PTR_ERR(regmap); -+ break; -+ } -+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap, -+ MT7531_PHYA_CTRL_SIGNAL3, 0); -+ if (!pcs) { -+ ret = -ENXIO; -+ break; -+ } -+ priv->ports[5 + i].sgmii_pcs = pcs; -+ } -+ -+ if (ret && i) -+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs); -+ -+ return ret; -+} -+ -+static const struct of_device_id mt7530_of_match[] = { -+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], }, -+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], }, -+ { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, mt7530_of_match); -+ -+static int -+mt7530_probe(struct mdio_device *mdiodev) -+{ -+ static struct regmap_config *regmap_config; -+ struct mt7530_priv *priv; -+ struct device_node *dn; -+ int ret; -+ -+ dn = mdiodev->dev.of_node; -+ -+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->bus = mdiodev->bus; -+ priv->dev = &mdiodev->dev; -+ -+ ret = mt7530_probe_common(priv); -+ if (ret) -+ return ret; -+ -+ /* Use medatek,mcm property to distinguish hardware type that would -+ * cause a little bit differences on power-on sequence. -+ * Not MCM that indicates switch works as the remote standalone -+ * integrated circuit so the GPIO pin would be used to complete -+ * the reset, otherwise memory-mapped register accessing used -+ * through syscon provides in the case of MCM. -+ */ -+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm"); -+ if (priv->mcm) { -+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n"); -+ -+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm"); -+ if (IS_ERR(priv->rstc)) { -+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -+ return PTR_ERR(priv->rstc); -+ } -+ } else { -+ priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", -+ GPIOD_OUT_LOW); -+ if (IS_ERR(priv->reset)) { -+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -+ return PTR_ERR(priv->reset); -+ } -+ } -+ -+ if (priv->id == ID_MT7530) { -+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); -+ if (IS_ERR(priv->core_pwr)) -+ return PTR_ERR(priv->core_pwr); -+ -+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io"); -+ if (IS_ERR(priv->io_pwr)) -+ return PTR_ERR(priv->io_pwr); -+ } -+ -+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config), -+ GFP_KERNEL); -+ if (!regmap_config) -+ return -ENOMEM; -+ -+ regmap_config->reg_bits = 16; -+ regmap_config->val_bits = 32; -+ regmap_config->reg_stride = 4; -+ regmap_config->max_register = MT7530_CREV; -+ regmap_config->disable_locking = true; -+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, -+ priv->bus, regmap_config); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); -+ -+ if (priv->id == ID_MT7531) { -+ ret = mt7531_create_sgmii(priv); -+ if (ret) -+ return ret; -+ } -+ -+ return dsa_register_switch(priv->ds); -+} -+ -+static void -+mt7530_remove(struct mdio_device *mdiodev) -+{ -+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -+ int ret = 0, i; -+ -+ if (!priv) -+ return; -+ -+ ret = regulator_disable(priv->core_pwr); -+ if (ret < 0) -+ dev_err(priv->dev, -+ "Failed to disable core power: %d\n", ret); -+ -+ ret = regulator_disable(priv->io_pwr); -+ if (ret < 0) -+ dev_err(priv->dev, "Failed to disable io pwr: %d\n", -+ ret); -+ -+ mt7530_remove_common(priv); -+ -+ for (i = 0; i < 2; ++i) -+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs); -+} -+ -+static void mt7530_shutdown(struct mdio_device *mdiodev) -+{ -+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -+ -+ if (!priv) -+ return; -+ -+ dsa_switch_shutdown(priv->ds); -+ -+ dev_set_drvdata(&mdiodev->dev, NULL); -+} -+ -+static struct mdio_driver mt7530_mdio_driver = { -+ .probe = mt7530_probe, -+ .remove = mt7530_remove, -+ .shutdown = mt7530_shutdown, -+ .mdiodrv.driver = { -+ .name = "mt7530-mdio", -+ .of_match_table = mt7530_of_match, -+ }, -+}; -+ -+mdio_module_driver(mt7530_mdio_driver); -+ -+MODULE_AUTHOR("Sean Wang "); -+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MDIO)"); -+MODULE_LICENSE("GPL"); ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -14,7 +14,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -193,31 +192,6 @@ core_clear(struct mt7530_priv *priv, u32 - } - - static int --mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) --{ -- struct mii_bus *bus = context; -- u16 page, r, lo, hi; -- int ret; -- -- page = (reg >> 6) & 0x3ff; -- r = (reg >> 2) & 0xf; -- lo = val & 0xffff; -- hi = val >> 16; -- -- /* MT7530 uses 31 as the pseudo port */ -- ret = bus->write(bus, 0x1f, 0x1f, page); -- if (ret < 0) -- return ret; -- -- ret = bus->write(bus, 0x1f, r, lo); -- if (ret < 0) -- return ret; -- -- ret = bus->write(bus, 0x1f, 0x10, hi); -- return ret; --} -- --static int - mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val) - { - int ret; -@@ -231,29 +205,6 @@ mt7530_mii_write(struct mt7530_priv *pri - return ret; - } - --static int --mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) --{ -- struct mii_bus *bus = context; -- u16 page, r, lo, hi; -- int ret; -- -- page = (reg >> 6) & 0x3ff; -- r = (reg >> 2) & 0xf; -- -- /* MT7530 uses 31 as the pseudo port */ -- ret = bus->write(bus, 0x1f, 0x1f, page); -- if (ret < 0) -- return ret; -- -- lo = bus->read(bus, 0x1f, r); -- hi = bus->read(bus, 0x1f, 0x10); -- -- *val = (hi << 16) | (lo & 0xffff); -- -- return 0; --} -- - static u32 - mt7530_mii_read(struct mt7530_priv *priv, u32 reg) - { -@@ -3191,72 +3142,6 @@ static const struct phylink_pcs_ops mt75 - .pcs_an_restart = mt7530_pcs_an_restart, - }; - --static void --mt7530_mdio_regmap_lock(void *mdio_lock) --{ -- mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED); --} -- --static void --mt7530_mdio_regmap_unlock(void *mdio_lock) --{ -- mutex_unlock(mdio_lock); --} -- --static const struct regmap_bus mt7530_regmap_bus = { -- .reg_write = mt7530_regmap_write, -- .reg_read = mt7530_regmap_read, --}; -- --static int --mt7531_create_sgmii(struct mt7530_priv *priv) --{ -- struct regmap_config *mt7531_pcs_config[2]; -- struct phylink_pcs *pcs; -- struct regmap *regmap; -- int i, ret = 0; -- -- for (i = 0; i < 2; i++) { -- mt7531_pcs_config[i] = devm_kzalloc(priv->dev, -- sizeof(struct regmap_config), -- GFP_KERNEL); -- if (!mt7531_pcs_config[i]) { -- ret = -ENOMEM; -- break; -- } -- -- mt7531_pcs_config[i]->name = i ? "port6" : "port5"; -- mt7531_pcs_config[i]->reg_bits = 16; -- mt7531_pcs_config[i]->val_bits = 32; -- mt7531_pcs_config[i]->reg_stride = 4; -- mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); -- mt7531_pcs_config[i]->max_register = 0x17c; -- mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock; -- mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock; -- mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; -- -- regmap = devm_regmap_init(priv->dev, -- &mt7530_regmap_bus, priv->bus, -- mt7531_pcs_config[i]); -- if (IS_ERR(regmap)) { -- ret = PTR_ERR(regmap); -- break; -- } -- pcs = mtk_pcs_lynxi_create(priv->dev, regmap, -- MT7531_PHYA_CTRL_SIGNAL3, 0); -- if (!pcs) { -- ret = -ENXIO; -- break; -- } -- priv->ports[5 + i].sgmii_pcs = pcs; -- } -- -- if (ret && i) -- mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs); -- -- return ret; --} -- - static int - mt753x_setup(struct dsa_switch *ds) - { -@@ -3315,7 +3200,7 @@ static int mt753x_set_mac_eee(struct dsa - return 0; - } - --static const struct dsa_switch_ops mt7530_switch_ops = { -+const struct dsa_switch_ops mt7530_switch_ops = { - .get_tag_protocol = mtk_get_tag_protocol, - .setup = mt753x_setup, - .preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port, -@@ -3350,8 +3235,9 @@ static const struct dsa_switch_ops mt753 - .get_mac_eee = mt753x_get_mac_eee, - .set_mac_eee = mt753x_set_mac_eee, - }; -+EXPORT_SYMBOL_GPL(mt7530_switch_ops); - --static const struct mt753x_info mt753x_table[] = { -+const struct mt753x_info mt753x_table[] = { - [ID_MT7621] = { - .id = ID_MT7621, - .pcs_ops = &mt7530_pcs_ops, -@@ -3384,16 +3270,9 @@ static const struct mt753x_info mt753x_t - .mac_port_config = mt7531_mac_config, - }, - }; -+EXPORT_SYMBOL_GPL(mt753x_table); - --static const struct of_device_id mt7530_of_match[] = { -- { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], }, -- { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], }, -- { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], }, -- { /* sentinel */ }, --}; --MODULE_DEVICE_TABLE(of, mt7530_of_match); -- --static int -+int - mt7530_probe_common(struct mt7530_priv *priv) - { - struct device *dev = priv->dev; -@@ -3430,88 +3309,9 @@ mt7530_probe_common(struct mt7530_priv * - - return 0; - } -+EXPORT_SYMBOL_GPL(mt7530_probe_common); - --static int --mt7530_probe(struct mdio_device *mdiodev) --{ -- static struct regmap_config *regmap_config; -- struct mt7530_priv *priv; -- struct device_node *dn; -- int ret; -- -- dn = mdiodev->dev.of_node; -- -- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- -- priv->bus = mdiodev->bus; -- priv->dev = &mdiodev->dev; -- -- ret = mt7530_probe_common(priv); -- if (ret) -- return ret; -- -- /* Use medatek,mcm property to distinguish hardware type that would -- * cause a little bit differences on power-on sequence. -- * Not MCM that indicates switch works as the remote standalone -- * integrated circuit so the GPIO pin would be used to complete -- * the reset, otherwise memory-mapped register accessing used -- * through syscon provides in the case of MCM. -- */ -- priv->mcm = of_property_read_bool(dn, "mediatek,mcm"); -- if (priv->mcm) { -- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n"); -- -- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm"); -- if (IS_ERR(priv->rstc)) { -- dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -- return PTR_ERR(priv->rstc); -- } -- } else { -- priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", -- GPIOD_OUT_LOW); -- if (IS_ERR(priv->reset)) { -- dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -- return PTR_ERR(priv->reset); -- } -- } -- -- if (priv->id == ID_MT7530) { -- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); -- if (IS_ERR(priv->core_pwr)) -- return PTR_ERR(priv->core_pwr); -- -- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io"); -- if (IS_ERR(priv->io_pwr)) -- return PTR_ERR(priv->io_pwr); -- } -- -- regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config), -- GFP_KERNEL); -- if (!regmap_config) -- return -ENOMEM; -- -- regmap_config->reg_bits = 16; -- regmap_config->val_bits = 32; -- regmap_config->reg_stride = 4; -- regmap_config->max_register = MT7530_CREV; -- regmap_config->disable_locking = true; -- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, -- priv->bus, regmap_config); -- if (IS_ERR(priv->regmap)) -- return PTR_ERR(priv->regmap); -- -- if (priv->id == ID_MT7531) { -- ret = mt7531_create_sgmii(priv); -- if (ret) -- return ret; -- } -- -- return dsa_register_switch(priv->ds); --} -- --static void -+void - mt7530_remove_common(struct mt7530_priv *priv) - { - if (priv->irq) -@@ -3522,57 +3322,6 @@ mt7530_remove_common(struct mt7530_priv - mutex_destroy(&priv->reg_mutex); - } - --static void --mt7530_remove(struct mdio_device *mdiodev) --{ -- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -- int ret = 0, i; -- -- if (!priv) -- return; -- -- ret = regulator_disable(priv->core_pwr); -- if (ret < 0) -- dev_err(priv->dev, -- "Failed to disable core power: %d\n", ret); -- -- ret = regulator_disable(priv->io_pwr); -- if (ret < 0) -- dev_err(priv->dev, "Failed to disable io pwr: %d\n", -- ret); -- -- mt7530_remove_common(priv); -- -- for (i = 0; i < 2; ++i) -- mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs); -- -- dev_set_drvdata(&mdiodev->dev, NULL); --} -- --static void mt7530_shutdown(struct mdio_device *mdiodev) --{ -- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -- -- if (!priv) -- return; -- -- dsa_switch_shutdown(priv->ds); -- -- dev_set_drvdata(&mdiodev->dev, NULL); --} -- --static struct mdio_driver mt7530_mdio_driver = { -- .probe = mt7530_probe, -- .remove = mt7530_remove, -- .shutdown = mt7530_shutdown, -- .mdiodrv.driver = { -- .name = "mt7530", -- .of_match_table = mt7530_of_match, -- }, --}; -- --mdio_module_driver(mt7530_mdio_driver); -- - MODULE_AUTHOR("Sean Wang "); - MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch"); - MODULE_LICENSE("GPL"); ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -845,4 +845,10 @@ static inline void INIT_MT7530_DUMMY_POL - p->reg = reg; - } - -+int mt7530_probe_common(struct mt7530_priv *priv); -+void mt7530_remove_common(struct mt7530_priv *priv); -+ -+extern const struct dsa_switch_ops mt7530_switch_ops; -+extern const struct mt753x_info mt753x_table[]; -+ - #endif /* __MT7530_H */ diff --git a/target/linux/generic/backport-5.15/790-v6.4-0012-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch b/target/linux/generic/backport-5.15/790-v6.4-0012-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch deleted file mode 100644 index 59e193f9f61224..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0012-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 54d4147a121cec5004a673a58572da346e4458f8 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:19:28 +0100 -Subject: [PATCH 15/16] net: dsa: mt7530: skip locking if MDIO bus isn't - present - -As MT7530 and MT7531 internally use 32-bit wide registers, each access -to any register of the switch requires several operations on the MDIO -bus. Hence if there is congruent access, e.g. due to PCS or PHY -polling, this can mess up and interfere with another ongoing register -access sequence. - -However, the MDIO bus mutex is only relevant for MDIO-connected -switches. Prepare switches which have there registers directly mapped -into the SoCs register space via MMIO which do not require such -locking. There we can simply use regmap's default locking mechanism. - -Hence guard mutex operations to only be performed in case of MDIO -connected switches. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -145,13 +145,15 @@ err: - static void - mt7530_mutex_lock(struct mt7530_priv *priv) - { -- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); -+ if (priv->bus) -+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); - } - - static void - mt7530_mutex_unlock(struct mt7530_priv *priv) - { -- mutex_unlock(&priv->bus->mdio_lock); -+ if (priv->bus) -+ mutex_unlock(&priv->bus->mdio_lock); - } - - static void diff --git a/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch b/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch deleted file mode 100644 index c8417091f90676..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0013-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch +++ /dev/null @@ -1,421 +0,0 @@ -From 110c18bfed41421edd677935dd33be5e6507ba92 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:19:40 +0100 -Subject: [PATCH 16/16] net: dsa: mt7530: introduce driver for MT7988 built-in - switch - -Add driver for the built-in Gigabit Ethernet switch which can be found -in the MediaTek MT7988 SoC. - -The switch shares most of its design with MT7530 and MT7531, but has -it's registers mapped into the SoCs register space rather than being -connected externally or internally via MDIO. - -Introduce a new platform driver to support that. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - MAINTAINERS | 2 + - drivers/net/dsa/Kconfig | 12 +++ - drivers/net/dsa/Makefile | 1 + - drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++ - drivers/net/dsa/mt7530.c | 137 +++++++++++++++++++++++++++++++++- - drivers/net/dsa/mt7530.h | 12 +-- - 6 files changed, 255 insertions(+), 10 deletions(-) - create mode 100644 drivers/net/dsa/mt7530-mmio.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -11900,9 +11900,11 @@ MEDIATEK SWITCH DRIVER - M: Sean Wang - M: Landen Chao - M: DENG Qingfang -+M: Daniel Golle - L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/dsa/mt7530-mdio.c -+F: drivers/net/dsa/mt7530-mmio.c - F: drivers/net/dsa/mt7530.* - F: net/dsa/tag_mtk.c - ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -38,6 +38,7 @@ config NET_DSA_MT7530 - select NET_DSA_TAG_MTK - select MEDIATEK_GE_PHY - imply NET_DSA_MT7530_MDIO -+ imply NET_DSA_MT7530_MMIO - help - This enables support for the MediaTek MT7530 and MT7531 Ethernet - switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT, -@@ -54,6 +55,17 @@ config NET_DSA_MT7530_MDIO - module MT7530 which can be found in the MT7621AT, MT7621DAT, - MT7621ST and MT7623AI SoCs. - -+config NET_DSA_MT7530_MMIO -+ tristate "MediaTek MT7530 MMIO interface driver" -+ depends on NET_DSA_MT7530 -+ depends on HAS_IOMEM -+ help -+ This enables support for the built-in Ethernet switch found -+ in the MediaTek MT7988 SoC. -+ The switch is a similar design as MT7531, but the switch registers -+ are directly mapped into the SoCs register space rather than being -+ accessible via MDIO. -+ - config NET_DSA_MV88E6060 - tristate "Marvell 88E6060 ethernet switch chip support" - select NET_DSA_TAG_TRAILER ---- a/drivers/net/dsa/Makefile -+++ b/drivers/net/dsa/Makefile -@@ -8,6 +8,7 @@ endif - obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o - obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o - obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o -+obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o - obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o - obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o - realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o ---- /dev/null -+++ b/drivers/net/dsa/mt7530-mmio.c -@@ -0,0 +1,101 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mt7530.h" -+ -+static const struct of_device_id mt7988_of_match[] = { -+ { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, mt7988_of_match); -+ -+static int -+mt7988_probe(struct platform_device *pdev) -+{ -+ static struct regmap_config *sw_regmap_config; -+ struct mt7530_priv *priv; -+ void __iomem *base_addr; -+ int ret; -+ -+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->bus = NULL; -+ priv->dev = &pdev->dev; -+ -+ ret = mt7530_probe_common(priv); -+ if (ret) -+ return ret; -+ -+ priv->rstc = devm_reset_control_get(&pdev->dev, NULL); -+ if (IS_ERR(priv->rstc)) { -+ dev_err(&pdev->dev, "Couldn't get our reset line\n"); -+ return PTR_ERR(priv->rstc); -+ } -+ -+ base_addr = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base_addr)) { -+ dev_err(&pdev->dev, "cannot request I/O memory space\n"); -+ return -ENXIO; -+ } -+ -+ sw_regmap_config = devm_kzalloc(&pdev->dev, sizeof(*sw_regmap_config), GFP_KERNEL); -+ if (!sw_regmap_config) -+ return -ENOMEM; -+ -+ sw_regmap_config->name = "switch"; -+ sw_regmap_config->reg_bits = 16; -+ sw_regmap_config->val_bits = 32; -+ sw_regmap_config->reg_stride = 4; -+ sw_regmap_config->max_register = MT7530_CREV; -+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base_addr, sw_regmap_config); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); -+ -+ return dsa_register_switch(priv->ds); -+} -+ -+static int -+mt7988_remove(struct platform_device *pdev) -+{ -+ struct mt7530_priv *priv = platform_get_drvdata(pdev); -+ -+ if (priv) -+ mt7530_remove_common(priv); -+ -+ return 0; -+} -+ -+static void mt7988_shutdown(struct platform_device *pdev) -+{ -+ struct mt7530_priv *priv = platform_get_drvdata(pdev); -+ -+ if (!priv) -+ return; -+ -+ dsa_switch_shutdown(priv->ds); -+ -+ dev_set_drvdata(&pdev->dev, NULL); -+} -+ -+static struct platform_driver mt7988_platform_driver = { -+ .probe = mt7988_probe, -+ .remove = mt7988_remove, -+ .shutdown = mt7988_shutdown, -+ .driver = { -+ .name = "mt7530-mmio", -+ .of_match_table = mt7988_of_match, -+ }, -+}; -+module_platform_driver(mt7988_platform_driver); -+ -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MMIO)"); -+MODULE_LICENSE("GPL"); ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2219,6 +2219,47 @@ static const struct irq_domain_ops mt753 - }; - - static void -+mt7988_irq_mask(struct irq_data *d) -+{ -+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); -+ -+ priv->irq_enable &= ~BIT(d->hwirq); -+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable); -+} -+ -+static void -+mt7988_irq_unmask(struct irq_data *d) -+{ -+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); -+ -+ priv->irq_enable |= BIT(d->hwirq); -+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable); -+} -+ -+static struct irq_chip mt7988_irq_chip = { -+ .name = KBUILD_MODNAME, -+ .irq_mask = mt7988_irq_mask, -+ .irq_unmask = mt7988_irq_unmask, -+}; -+ -+static int -+mt7988_irq_map(struct irq_domain *domain, unsigned int irq, -+ irq_hw_number_t hwirq) -+{ -+ irq_set_chip_data(irq, domain->host_data); -+ irq_set_chip_and_handler(irq, &mt7988_irq_chip, handle_simple_irq); -+ irq_set_nested_thread(irq, true); -+ irq_set_noprobe(irq); -+ -+ return 0; -+} -+ -+static const struct irq_domain_ops mt7988_irq_domain_ops = { -+ .map = mt7988_irq_map, -+ .xlate = irq_domain_xlate_onecell, -+}; -+ -+static void - mt7530_setup_mdio_irq(struct mt7530_priv *priv) - { - struct dsa_switch *ds = priv->ds; -@@ -2252,8 +2293,15 @@ mt7530_setup_irq(struct mt7530_priv *pri - return priv->irq ? : -EINVAL; - } - -- priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS, -- &mt7530_irq_domain_ops, priv); -+ if (priv->id == ID_MT7988) -+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS, -+ &mt7988_irq_domain_ops, -+ priv); -+ else -+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS, -+ &mt7530_irq_domain_ops, -+ priv); -+ - if (!priv->irq_domain) { - dev_err(dev, "failed to create IRQ domain\n"); - return -ENOMEM; -@@ -2754,6 +2802,25 @@ static void mt7531_mac_port_get_caps(str - } - } - -+static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port, -+ struct phylink_config *config) -+{ -+ phy_interface_zero(config->supported_interfaces); -+ -+ switch (port) { -+ case 0 ... 4: /* Internal phy */ -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ config->supported_interfaces); -+ break; -+ -+ case 6: -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ config->supported_interfaces); -+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -+ MAC_10000FD; -+ } -+} -+ - static int - mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) - { -@@ -2830,6 +2897,17 @@ static bool mt753x_is_mac_port(u32 port) - } - - static int -+mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode, -+ phy_interface_t interface) -+{ -+ if (dsa_is_cpu_port(ds, port) && -+ interface == PHY_INTERFACE_MODE_INTERNAL) -+ return 0; -+ -+ return -EINVAL; -+} -+ -+static int - mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - phy_interface_t interface) - { -@@ -2899,7 +2977,8 @@ mt753x_phylink_mac_config(struct dsa_swi - - switch (port) { - case 0 ... 4: /* Internal phy */ -- if (state->interface != PHY_INTERFACE_MODE_GMII) -+ if (state->interface != PHY_INTERFACE_MODE_GMII && -+ state->interface != PHY_INTERFACE_MODE_INTERNAL) - goto unsupported; - break; - case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -@@ -2977,7 +3056,8 @@ static void mt753x_phylink_mac_link_up(s - /* MT753x MAC works in 1G full duplex mode for all up-clocked - * variants. - */ -- if (interface == PHY_INTERFACE_MODE_TRGMII || -+ if (interface == PHY_INTERFACE_MODE_INTERNAL || -+ interface == PHY_INTERFACE_MODE_TRGMII || - (phy_interface_mode_is_8023z(interface))) { - speed = SPEED_1000; - duplex = DUPLEX_FULL; -@@ -3057,6 +3137,21 @@ mt7531_cpu_port_config(struct dsa_switch - return 0; - } - -+static int -+mt7988_cpu_port_config(struct dsa_switch *ds, int port) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ mt7530_write(priv, MT7530_PMCR_P(port), -+ PMCR_CPU_PORT_SETTING(priv->id)); -+ -+ mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, -+ PHY_INTERFACE_MODE_INTERNAL, NULL, -+ SPEED_10000, DUPLEX_FULL, true, true); -+ -+ return 0; -+} -+ - static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, - struct phylink_config *config) - { -@@ -3202,6 +3297,27 @@ static int mt753x_set_mac_eee(struct dsa - return 0; - } - -+static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface) -+{ -+ return 0; -+} -+ -+static int mt7988_setup(struct dsa_switch *ds) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ /* Reset the switch */ -+ reset_control_assert(priv->rstc); -+ usleep_range(20, 50); -+ reset_control_deassert(priv->rstc); -+ usleep_range(20, 50); -+ -+ /* Reset the switch PHYs */ -+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST); -+ -+ return mt7531_setup_common(ds); -+} -+ - const struct dsa_switch_ops mt7530_switch_ops = { - .get_tag_protocol = mtk_get_tag_protocol, - .setup = mt753x_setup, -@@ -3271,6 +3387,17 @@ const struct mt753x_info mt753x_table[] - .mac_port_get_caps = mt7531_mac_port_get_caps, - .mac_port_config = mt7531_mac_config, - }, -+ [ID_MT7988] = { -+ .id = ID_MT7988, -+ .pcs_ops = &mt7530_pcs_ops, -+ .sw_setup = mt7988_setup, -+ .phy_read = mt7531_ind_phy_read, -+ .phy_write = mt7531_ind_phy_write, -+ .pad_setup = mt7988_pad_setup, -+ .cpu_port_config = mt7988_cpu_port_config, -+ .mac_port_get_caps = mt7988_mac_port_get_caps, -+ .mac_port_config = mt7988_mac_config, -+ }, - }; - EXPORT_SYMBOL_GPL(mt753x_table); - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -18,6 +18,7 @@ enum mt753x_id { - ID_MT7530 = 0, - ID_MT7621 = 1, - ID_MT7531 = 2, -+ ID_MT7988 = 3, - }; - - #define NUM_TRGMII_CTRL 5 -@@ -59,11 +60,11 @@ enum mt753x_id { - #define MT7531_CPU_PMAP_MASK GENMASK(7, 0) - #define MT7531_CPU_PMAP(x) FIELD_PREP(MT7531_CPU_PMAP_MASK, x) - --#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \ -+#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ - MT7531_CFC : MT7530_MFC) --#define MT753X_MIRROR_EN(id) (((id) == ID_MT7531) ? \ -+#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ - MT7531_MIRROR_EN : MIRROR_EN) --#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \ -+#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ - MT7531_MIRROR_MASK : MIRROR_MASK) - - /* Registers for BPDU and PAE frame control*/ -@@ -332,9 +333,8 @@ enum mt7530_vlan_port_acc_frm { - MT7531_FORCE_DPX | \ - MT7531_FORCE_RX_FC | \ - MT7531_FORCE_TX_FC) --#define PMCR_FORCE_MODE_ID(id) (((id) == ID_MT7531) ? \ -- MT7531_FORCE_MODE : \ -- PMCR_FORCE_MODE) -+#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ -+ MT7531_FORCE_MODE : PMCR_FORCE_MODE) - #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \ - PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \ - PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ diff --git a/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch b/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch deleted file mode 100644 index 26896473198852..00000000000000 --- a/target/linux/generic/backport-5.15/790-v6.4-0014-net-dsa-mt7530-fix-support-for-MT7531BE.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 91daa4f62ce878b6e1ac5908aceb83550332447f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 16 Apr 2023 13:08:14 +0100 -Subject: [PATCH] net: dsa: mt7530: fix support for MT7531BE -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There are two variants of the MT7531 switch IC which got different -features (and pins) regarding port 5: - * MT7531AE: SGMII/1000Base-X/2500Base-X SerDes PCS - * MT7531BE: RGMII - -Moving the creation of the SerDes PCS from mt753x_setup to mt7530_probe -with commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation -to mt7530_probe function") works fine for MT7531AE which got two -instances of mtk-pcs-lynxi, however, MT7531BE requires mt7531_pll_setup -to setup clocks before the single PCS on port 6 (usually used as CPU -port) starts to work and hence the PCS creation failed on MT7531BE. - -Fix this by introducing a pointer to mt7531_create_sgmii function in -struct mt7530_priv and call it again at the end of mt753x_setup like it -was before commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS -creation to mt7530_probe function"). - -Fixes: 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation to mt7530_probe function") -Signed-off-by: Daniel Golle -Acked-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/ZDvlLhhqheobUvOK@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530-mdio.c | 16 ++++++++-------- - drivers/net/dsa/mt7530.c | 6 ++++++ - drivers/net/dsa/mt7530.h | 4 ++-- - 3 files changed, 16 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/mt7530-mdio.c -+++ b/drivers/net/dsa/mt7530-mdio.c -@@ -81,14 +81,17 @@ static const struct regmap_bus mt7530_re - }; - - static int --mt7531_create_sgmii(struct mt7530_priv *priv) -+mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii) - { -- struct regmap_config *mt7531_pcs_config[2]; -+ struct regmap_config *mt7531_pcs_config[2] = {}; - struct phylink_pcs *pcs; - struct regmap *regmap; - int i, ret = 0; - -- for (i = 0; i < 2; i++) { -+ /* MT7531AE has two SGMII units for port 5 and port 6 -+ * MT7531BE has only one SGMII unit for port 6 -+ */ -+ for (i = dual_sgmii ? 0 : 1; i < 2; i++) { - mt7531_pcs_config[i] = devm_kzalloc(priv->dev, - sizeof(struct regmap_config), - GFP_KERNEL); -@@ -208,11 +211,8 @@ mt7530_probe(struct mdio_device *mdiodev - if (IS_ERR(priv->regmap)) - return PTR_ERR(priv->regmap); - -- if (priv->id == ID_MT7531) { -- ret = mt7531_create_sgmii(priv); -- if (ret) -- return ret; -- } -+ if (priv->id == ID_MT7531) -+ priv->create_sgmii = mt7531_create_sgmii; - - return dsa_register_switch(priv->ds); - } ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3264,6 +3264,12 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -+ if (priv->create_sgmii) { -+ ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv)); -+ if (ret && priv->irq) -+ mt7530_free_irq(priv); -+ } -+ - return ret; - } - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -779,10 +779,10 @@ struct mt753x_info { - * registers - * @p6_interface Holding the current port 6 interface - * @p5_intf_sel: Holding the current port 5 interface select -- * - * @irq: IRQ number of the switch - * @irq_domain: IRQ domain of the switch irq_chip - * @irq_enable: IRQ enable bits, synced to SYS_INT_EN -+ * @create_sgmii: Pointer to function creating SGMII PCS instance(s) - */ - struct mt7530_priv { - struct device *dev; -@@ -801,7 +801,6 @@ struct mt7530_priv { - unsigned int p5_intf_sel; - u8 mirror_rx; - u8 mirror_tx; -- - struct mt7530_port ports[MT7530_NUM_PORTS]; - struct mt753x_pcs pcs[MT7530_NUM_PORTS]; - /* protect among processes for registers access*/ -@@ -809,6 +808,7 @@ struct mt7530_priv { - int irq; - struct irq_domain *irq_domain; - u32 irq_enable; -+ int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii); - }; - - struct mt7530_hw_vlan_entry { diff --git a/target/linux/generic/backport-5.15/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch b/target/linux/generic/backport-5.15/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch deleted file mode 100644 index c7f5856e8df49d..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch +++ /dev/null @@ -1,1724 +0,0 @@ -From 70479a40954cf353e87a486997a3477108c75aa9 Mon Sep 17 00:00:00 2001 -From: Frank -Date: Fri, 28 Oct 2022 17:26:21 +0800 -Subject: [PATCH] net: phy: Add driver for Motorcomm yt8521 gigabit ethernet - phy - -Add a driver for the motorcomm yt8521 gigabit ethernet phy. We have verified - the driver on StarFive VisionFive development board, which is developed by - Shanghai StarFive Technology Co., Ltd.. On the board, yt8521 gigabit ethernet - phy works in utp mode, RGMII interface, supports 1000M/100M/10M speeds, and - wol(magic package). - -Signed-off-by: Frank -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - MAINTAINERS | 1 + - drivers/net/phy/Kconfig | 2 +- - drivers/net/phy/motorcomm.c | 1635 ++++++++++++++++++++++++++++++++++- - 3 files changed, 1635 insertions(+), 3 deletions(-) - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -12701,6 +12701,7 @@ F: include/uapi/linux/meye.h - - MOTORCOMM PHY DRIVER - M: Peter Geis -+M: Frank - L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/phy/motorcomm.c ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -242,7 +242,7 @@ config MOTORCOMM_PHY - tristate "Motorcomm PHYs" - help - Enables support for Motorcomm network PHYs. -- Currently supports the YT8511 gigabit PHY. -+ Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs. - - config NATIONAL_PHY - tristate "National Semiconductor PHYs" ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1,15 +1,106 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* -- * Driver for Motorcomm PHYs -+ * Motorcomm 8511/8521 PHY driver. - * - * Author: Peter Geis -+ * Author: Frank - */ - -+#include - #include - #include - #include - - #define PHY_ID_YT8511 0x0000010a -+#define PHY_ID_YT8521 0x0000011A -+ -+/* YT8521 Register Overview -+ * UTP Register space | FIBER Register space -+ * ------------------------------------------------------------ -+ * | UTP MII | FIBER MII | -+ * | UTP MMD | | -+ * | UTP Extended | FIBER Extended | -+ * ------------------------------------------------------------ -+ * | Common Extended | -+ * ------------------------------------------------------------ -+ */ -+ -+/* 0x10 ~ 0x15 , 0x1E and 0x1F are common MII registers of yt phy */ -+ -+/* Specific Function Control Register */ -+#define YTPHY_SPECIFIC_FUNCTION_CONTROL_REG 0x10 -+ -+/* 2b00 Manual MDI configuration -+ * 2b01 Manual MDIX configuration -+ * 2b10 Reserved -+ * 2b11 Enable automatic crossover for all modes *default* -+ */ -+#define YTPHY_SFCR_MDI_CROSSOVER_MODE_MASK (BIT(6) | BIT(5)) -+#define YTPHY_SFCR_CROSSOVER_EN BIT(3) -+#define YTPHY_SFCR_SQE_TEST_EN BIT(2) -+#define YTPHY_SFCR_POLARITY_REVERSAL_EN BIT(1) -+#define YTPHY_SFCR_JABBER_DIS BIT(0) -+ -+/* Specific Status Register */ -+#define YTPHY_SPECIFIC_STATUS_REG 0x11 -+#define YTPHY_SSR_SPEED_MODE_OFFSET 14 -+ -+#define YTPHY_SSR_SPEED_MODE_MASK (BIT(15) | BIT(14)) -+#define YTPHY_SSR_SPEED_10M 0x0 -+#define YTPHY_SSR_SPEED_100M 0x1 -+#define YTPHY_SSR_SPEED_1000M 0x2 -+#define YTPHY_SSR_DUPLEX_OFFSET 13 -+#define YTPHY_SSR_DUPLEX BIT(13) -+#define YTPHY_SSR_PAGE_RECEIVED BIT(12) -+#define YTPHY_SSR_SPEED_DUPLEX_RESOLVED BIT(11) -+#define YTPHY_SSR_LINK BIT(10) -+#define YTPHY_SSR_MDIX_CROSSOVER BIT(6) -+#define YTPHY_SSR_DOWNGRADE BIT(5) -+#define YTPHY_SSR_TRANSMIT_PAUSE BIT(3) -+#define YTPHY_SSR_RECEIVE_PAUSE BIT(2) -+#define YTPHY_SSR_POLARITY BIT(1) -+#define YTPHY_SSR_JABBER BIT(0) -+ -+/* Interrupt enable Register */ -+#define YTPHY_INTERRUPT_ENABLE_REG 0x12 -+#define YTPHY_IER_WOL BIT(6) -+ -+/* Interrupt Status Register */ -+#define YTPHY_INTERRUPT_STATUS_REG 0x13 -+#define YTPHY_ISR_AUTONEG_ERR BIT(15) -+#define YTPHY_ISR_SPEED_CHANGED BIT(14) -+#define YTPHY_ISR_DUPLEX_CHANGED BIT(13) -+#define YTPHY_ISR_PAGE_RECEIVED BIT(12) -+#define YTPHY_ISR_LINK_FAILED BIT(11) -+#define YTPHY_ISR_LINK_SUCCESSED BIT(10) -+#define YTPHY_ISR_WOL BIT(6) -+#define YTPHY_ISR_WIRESPEED_DOWNGRADE BIT(5) -+#define YTPHY_ISR_SERDES_LINK_FAILED BIT(3) -+#define YTPHY_ISR_SERDES_LINK_SUCCESSED BIT(2) -+#define YTPHY_ISR_POLARITY_CHANGED BIT(1) -+#define YTPHY_ISR_JABBER_HAPPENED BIT(0) -+ -+/* Speed Auto Downgrade Control Register */ -+#define YTPHY_SPEED_AUTO_DOWNGRADE_CONTROL_REG 0x14 -+#define YTPHY_SADCR_SPEED_DOWNGRADE_EN BIT(5) -+ -+/* If these bits are set to 3, the PHY attempts five times ( 3(set value) + -+ * additional 2) before downgrading, default 0x3 -+ */ -+#define YTPHY_SADCR_SPEED_RETRY_LIMIT (0x3 << 2) -+ -+/* Rx Error Counter Register */ -+#define YTPHY_RX_ERROR_COUNTER_REG 0x15 -+ -+/* Extended Register's Address Offset Register */ -+#define YTPHY_PAGE_SELECT 0x1E -+ -+/* Extended Register's Data Register */ -+#define YTPHY_PAGE_DATA 0x1F -+ -+/* FIBER Auto-Negotiation link partner ability */ -+#define YTPHY_FLPA_PAUSE (0x3 << 7) -+#define YTPHY_FLPA_ASYM_PAUSE (0x2 << 7) - - #define YT8511_PAGE_SELECT 0x1e - #define YT8511_PAGE 0x1f -@@ -38,6 +129,352 @@ - #define YT8511_DELAY_FE_TX_EN (0xf << 12) - #define YT8511_DELAY_FE_TX_DIS (0x2 << 12) - -+/* Extended register is different from MMD Register and MII Register. -+ * We can use ytphy_read_ext/ytphy_write_ext/ytphy_modify_ext function to -+ * operate extended register. -+ * Extended Register start -+ */ -+ -+/* Phy gmii clock gating Register */ -+#define YT8521_CLOCK_GATING_REG 0xC -+#define YT8521_CGR_RX_CLK_EN BIT(12) -+ -+#define YT8521_EXTREG_SLEEP_CONTROL1_REG 0x27 -+#define YT8521_ESC1R_SLEEP_SW BIT(15) -+#define YT8521_ESC1R_PLLON_SLP BIT(14) -+ -+/* Phy fiber Link timer cfg2 Register */ -+#define YT8521_LINK_TIMER_CFG2_REG 0xA5 -+#define YT8521_LTCR_EN_AUTOSEN BIT(15) -+ -+/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers -+ * of yt8521 phy. There is no need to switch reg space when operating these -+ * registers. -+ */ -+ -+#define YT8521_REG_SPACE_SELECT_REG 0xA000 -+#define YT8521_RSSR_SPACE_MASK BIT(1) -+#define YT8521_RSSR_FIBER_SPACE (0x1 << 1) -+#define YT8521_RSSR_UTP_SPACE (0x0 << 1) -+#define YT8521_RSSR_TO_BE_ARBITRATED (0xFF) -+ -+#define YT8521_CHIP_CONFIG_REG 0xA001 -+#define YT8521_CCR_SW_RST BIT(15) -+ -+#define YT8521_CCR_MODE_SEL_MASK (BIT(2) | BIT(1) | BIT(0)) -+#define YT8521_CCR_MODE_UTP_TO_RGMII 0 -+#define YT8521_CCR_MODE_FIBER_TO_RGMII 1 -+#define YT8521_CCR_MODE_UTP_FIBER_TO_RGMII 2 -+#define YT8521_CCR_MODE_UTP_TO_SGMII 3 -+#define YT8521_CCR_MODE_SGPHY_TO_RGMAC 4 -+#define YT8521_CCR_MODE_SGMAC_TO_RGPHY 5 -+#define YT8521_CCR_MODE_UTP_TO_FIBER_AUTO 6 -+#define YT8521_CCR_MODE_UTP_TO_FIBER_FORCE 7 -+ -+/* 3 phy polling modes,poll mode combines utp and fiber mode*/ -+#define YT8521_MODE_FIBER 0x1 -+#define YT8521_MODE_UTP 0x2 -+#define YT8521_MODE_POLL 0x3 -+ -+#define YT8521_RGMII_CONFIG1_REG 0xA003 -+ -+/* TX Gig-E Delay is bits 3:0, default 0x1 -+ * TX Fast-E Delay is bits 7:4, default 0xf -+ * RX Delay is bits 13:10, default 0x0 -+ * Delay = 150ps * N -+ * On = 2250ps, off = 0ps -+ */ -+#define YT8521_RC1R_RX_DELAY_MASK (0xF << 10) -+#define YT8521_RC1R_RX_DELAY_EN (0xF << 10) -+#define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10) -+#define YT8521_RC1R_FE_TX_DELAY_MASK (0xF << 4) -+#define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4) -+#define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4) -+#define YT8521_RC1R_GE_TX_DELAY_MASK (0xF << 0) -+#define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0) -+#define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0) -+ -+#define YTPHY_MISC_CONFIG_REG 0xA006 -+#define YTPHY_MCR_FIBER_SPEED_MASK BIT(0) -+#define YTPHY_MCR_FIBER_1000BX (0x1 << 0) -+#define YTPHY_MCR_FIBER_100FX (0x0 << 0) -+ -+/* WOL MAC ADDR: MACADDR2(highest), MACADDR1(middle), MACADDR0(lowest) */ -+#define YTPHY_WOL_MACADDR2_REG 0xA007 -+#define YTPHY_WOL_MACADDR1_REG 0xA008 -+#define YTPHY_WOL_MACADDR0_REG 0xA009 -+ -+#define YTPHY_WOL_CONFIG_REG 0xA00A -+#define YTPHY_WCR_INTR_SEL BIT(6) -+#define YTPHY_WCR_ENABLE BIT(3) -+ -+/* 2b00 84ms -+ * 2b01 168ms *default* -+ * 2b10 336ms -+ * 2b11 672ms -+ */ -+#define YTPHY_WCR_PULSE_WIDTH_MASK (BIT(2) | BIT(1)) -+#define YTPHY_WCR_PULSE_WIDTH_672MS (BIT(2) | BIT(1)) -+ -+/* 1b0 Interrupt and WOL events is level triggered and active LOW *default* -+ * 1b1 Interrupt and WOL events is pulse triggered and active LOW -+ */ -+#define YTPHY_WCR_TYPE_PULSE BIT(0) -+ -+/* Extended Register end */ -+ -+struct yt8521_priv { -+ /* combo_advertising is used for case of YT8521 in combo mode, -+ * this means that yt8521 may work in utp or fiber mode which depends -+ * on which media is connected (YT8521_RSSR_TO_BE_ARBITRATED). -+ */ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(combo_advertising); -+ -+ /* YT8521_MODE_FIBER / YT8521_MODE_UTP / YT8521_MODE_POLL*/ -+ u8 polling_mode; -+ u8 strap_mode; /* 8 working modes */ -+ /* current reg page of yt8521 phy: -+ * YT8521_RSSR_UTP_SPACE -+ * YT8521_RSSR_FIBER_SPACE -+ * YT8521_RSSR_TO_BE_ARBITRATED -+ */ -+ u8 reg_page; -+}; -+ -+/** -+ * ytphy_read_ext() - read a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to read -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns the value of regnum reg or negative error code -+ */ -+static int ytphy_read_ext(struct phy_device *phydev, u16 regnum) -+{ -+ int ret; -+ -+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum); -+ if (ret < 0) -+ return ret; -+ -+ return __phy_read(phydev, YTPHY_PAGE_DATA); -+} -+ -+/** -+ * ytphy_read_ext_with_lock() - read a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to read -+ * -+ * returns the value of regnum reg or negative error code -+ */ -+static int ytphy_read_ext_with_lock(struct phy_device *phydev, u16 regnum) -+{ -+ int ret; -+ -+ phy_lock_mdio_bus(phydev); -+ ret = ytphy_read_ext(phydev, regnum); -+ phy_unlock_mdio_bus(phydev); -+ -+ return ret; -+} -+ -+/** -+ * ytphy_write_ext() - write a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to write -+ * @val: value to write to @regnum -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative error code -+ */ -+static int ytphy_write_ext(struct phy_device *phydev, u16 regnum, u16 val) -+{ -+ int ret; -+ -+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum); -+ if (ret < 0) -+ return ret; -+ -+ return __phy_write(phydev, YTPHY_PAGE_DATA, val); -+} -+ -+/** -+ * ytphy_write_ext_with_lock() - write a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to write -+ * @val: value to write to @regnum -+ * -+ * returns 0 or negative error code -+ */ -+static int ytphy_write_ext_with_lock(struct phy_device *phydev, u16 regnum, -+ u16 val) -+{ -+ int ret; -+ -+ phy_lock_mdio_bus(phydev); -+ ret = ytphy_write_ext(phydev, regnum, val); -+ phy_unlock_mdio_bus(phydev); -+ -+ return ret; -+} -+ -+/** -+ * ytphy_modify_ext() - bits modify a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to write -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ * -+ * NOTE: Convenience function which allows a PHY's extended register to be -+ * modified as new register value = (old register value & ~mask) | set. -+ * The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative error code -+ */ -+static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask, -+ u16 set) -+{ -+ int ret; -+ -+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum); -+ if (ret < 0) -+ return ret; -+ -+ return __phy_modify(phydev, YTPHY_PAGE_DATA, mask, set); -+} -+ -+/** -+ * ytphy_modify_ext_with_lock() - bits modify a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to write -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ * -+ * NOTE: Convenience function which allows a PHY's extended register to be -+ * modified as new register value = (old register value & ~mask) | set. -+ * -+ * returns 0 or negative error code -+ */ -+static int ytphy_modify_ext_with_lock(struct phy_device *phydev, u16 regnum, -+ u16 mask, u16 set) -+{ -+ int ret; -+ -+ phy_lock_mdio_bus(phydev); -+ ret = ytphy_modify_ext(phydev, regnum, mask, set); -+ phy_unlock_mdio_bus(phydev); -+ -+ return ret; -+} -+ -+/** -+ * ytphy_get_wol() - report whether wake-on-lan is enabled -+ * @phydev: a pointer to a &struct phy_device -+ * @wol: a pointer to a &struct ethtool_wolinfo -+ * -+ * NOTE: YTPHY_WOL_CONFIG_REG is common ext reg. -+ */ -+static void ytphy_get_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol) -+{ -+ int wol_config; -+ -+ wol->supported = WAKE_MAGIC; -+ wol->wolopts = 0; -+ -+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG); -+ if (wol_config < 0) -+ return; -+ -+ if (wol_config & YTPHY_WCR_ENABLE) -+ wol->wolopts |= WAKE_MAGIC; -+} -+ -+/** -+ * ytphy_set_wol() - turn wake-on-lan on or off -+ * @phydev: a pointer to a &struct phy_device -+ * @wol: a pointer to a &struct ethtool_wolinfo -+ * -+ * NOTE: YTPHY_WOL_CONFIG_REG, YTPHY_WOL_MACADDR2_REG, YTPHY_WOL_MACADDR1_REG -+ * and YTPHY_WOL_MACADDR0_REG are common ext reg. The -+ * YTPHY_INTERRUPT_ENABLE_REG of UTP is special, fiber also use this register. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) -+{ -+ struct net_device *p_attached_dev; -+ const u16 mac_addr_reg[] = { -+ YTPHY_WOL_MACADDR2_REG, -+ YTPHY_WOL_MACADDR1_REG, -+ YTPHY_WOL_MACADDR0_REG, -+ }; -+ const u8 *mac_addr; -+ int old_page; -+ int ret = 0; -+ u16 mask; -+ u16 val; -+ u8 i; -+ -+ if (wol->wolopts & WAKE_MAGIC) { -+ p_attached_dev = phydev->attached_dev; -+ if (!p_attached_dev) -+ return -ENODEV; -+ -+ mac_addr = (const u8 *)p_attached_dev->dev_addr; -+ if (!is_valid_ether_addr(mac_addr)) -+ return -EINVAL; -+ -+ /* lock mdio bus then switch to utp reg space */ -+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ /* Store the device address for the magic packet */ -+ for (i = 0; i < 3; i++) { -+ ret = ytphy_write_ext(phydev, mac_addr_reg[i], -+ ((mac_addr[i * 2] << 8)) | -+ (mac_addr[i * 2 + 1])); -+ if (ret < 0) -+ goto err_restore_page; -+ } -+ -+ /* Enable WOL feature */ -+ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL; -+ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; -+ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS; -+ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, val); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ /* Enable WOL interrupt */ -+ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0, -+ YTPHY_IER_WOL); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ } else { -+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ /* Disable WOL feature */ -+ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; -+ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, 0); -+ -+ /* Disable WOL interrupt */ -+ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, -+ YTPHY_IER_WOL, 0); -+ if (ret < 0) -+ goto err_restore_page; -+ } -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ - static int yt8511_read_page(struct phy_device *phydev) - { - return __phy_read(phydev, YT8511_PAGE_SELECT); -@@ -111,6 +548,1181 @@ err_restore_page: - return phy_restore_page(phydev, oldpage, ret); - } - -+/** -+ * yt8521_read_page() - read reg page -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns current reg space of yt8521 (YT8521_RSSR_FIBER_SPACE/ -+ * YT8521_RSSR_UTP_SPACE) or negative errno code -+ */ -+static int yt8521_read_page(struct phy_device *phydev) -+{ -+ int old_page; -+ -+ old_page = ytphy_read_ext(phydev, YT8521_REG_SPACE_SELECT_REG); -+ if (old_page < 0) -+ return old_page; -+ -+ if ((old_page & YT8521_RSSR_SPACE_MASK) == YT8521_RSSR_FIBER_SPACE) -+ return YT8521_RSSR_FIBER_SPACE; -+ -+ return YT8521_RSSR_UTP_SPACE; -+}; -+ -+/** -+ * yt8521_write_page() - write reg page -+ * @phydev: a pointer to a &struct phy_device -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to write. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_write_page(struct phy_device *phydev, int page) -+{ -+ int mask = YT8521_RSSR_SPACE_MASK; -+ int set; -+ -+ if ((page & YT8521_RSSR_SPACE_MASK) == YT8521_RSSR_FIBER_SPACE) -+ set = YT8521_RSSR_FIBER_SPACE; -+ else -+ set = YT8521_RSSR_UTP_SPACE; -+ -+ return ytphy_modify_ext(phydev, YT8521_REG_SPACE_SELECT_REG, mask, set); -+}; -+ -+/** -+ * yt8521_probe() - read chip config then set suitable polling_mode -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct yt8521_priv *priv; -+ int chip_config; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ phydev->priv = priv; -+ -+ chip_config = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG); -+ if (chip_config < 0) -+ return chip_config; -+ -+ priv->strap_mode = chip_config & YT8521_CCR_MODE_SEL_MASK; -+ switch (priv->strap_mode) { -+ case YT8521_CCR_MODE_FIBER_TO_RGMII: -+ case YT8521_CCR_MODE_SGPHY_TO_RGMAC: -+ case YT8521_CCR_MODE_SGMAC_TO_RGPHY: -+ priv->polling_mode = YT8521_MODE_FIBER; -+ priv->reg_page = YT8521_RSSR_FIBER_SPACE; -+ phydev->port = PORT_FIBRE; -+ break; -+ case YT8521_CCR_MODE_UTP_FIBER_TO_RGMII: -+ case YT8521_CCR_MODE_UTP_TO_FIBER_AUTO: -+ case YT8521_CCR_MODE_UTP_TO_FIBER_FORCE: -+ priv->polling_mode = YT8521_MODE_POLL; -+ priv->reg_page = YT8521_RSSR_TO_BE_ARBITRATED; -+ phydev->port = PORT_NONE; -+ break; -+ case YT8521_CCR_MODE_UTP_TO_SGMII: -+ case YT8521_CCR_MODE_UTP_TO_RGMII: -+ priv->polling_mode = YT8521_MODE_UTP; -+ priv->reg_page = YT8521_RSSR_UTP_SPACE; -+ phydev->port = PORT_TP; -+ break; -+ } -+ /* set default reg space */ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ ret = ytphy_write_ext_with_lock(phydev, -+ YT8521_REG_SPACE_SELECT_REG, -+ priv->reg_page); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/** -+ * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_utp_read_lpa(struct phy_device *phydev) -+{ -+ int lpa, lpagb; -+ -+ if (phydev->autoneg == AUTONEG_ENABLE) { -+ if (!phydev->autoneg_complete) { -+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, -+ 0); -+ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0); -+ return 0; -+ } -+ -+ if (phydev->is_gigabit_capable) { -+ lpagb = __phy_read(phydev, MII_STAT1000); -+ if (lpagb < 0) -+ return lpagb; -+ -+ if (lpagb & LPA_1000MSFAIL) { -+ int adv = __phy_read(phydev, MII_CTRL1000); -+ -+ if (adv < 0) -+ return adv; -+ -+ if (adv & CTL1000_ENABLE_MASTER) -+ phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); -+ else -+ phydev_err(phydev, "Master/Slave resolution failed\n"); -+ return -ENOLINK; -+ } -+ -+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, -+ lpagb); -+ } -+ -+ lpa = __phy_read(phydev, MII_LPA); -+ if (lpa < 0) -+ return lpa; -+ -+ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa); -+ } else { -+ linkmode_zero(phydev->lp_advertising); -+ } -+ -+ return 0; -+} -+ -+/** -+ * yt8521_adjust_status() - update speed and duplex to phydev. when in fiber -+ * mode, adjust speed and duplex. -+ * @phydev: a pointer to a &struct phy_device -+ * @status: yt8521 status read from YTPHY_SPECIFIC_STATUS_REG -+ * @is_utp: false(yt8521 work in fiber mode) or true(yt8521 work in utp mode) -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 -+ */ -+static int yt8521_adjust_status(struct phy_device *phydev, int status, -+ bool is_utp) -+{ -+ int speed_mode, duplex; -+ int speed; -+ int err; -+ int lpa; -+ -+ if (is_utp) -+ duplex = (status & YTPHY_SSR_DUPLEX) >> YTPHY_SSR_DUPLEX_OFFSET; -+ else -+ duplex = DUPLEX_FULL; /* for fiber, it always DUPLEX_FULL */ -+ -+ speed_mode = (status & YTPHY_SSR_SPEED_MODE_MASK) >> -+ YTPHY_SSR_SPEED_MODE_OFFSET; -+ -+ switch (speed_mode) { -+ case YTPHY_SSR_SPEED_10M: -+ if (is_utp) -+ speed = SPEED_10; -+ else -+ /* for fiber, it will never run here, default to -+ * SPEED_UNKNOWN -+ */ -+ speed = SPEED_UNKNOWN; -+ break; -+ case YTPHY_SSR_SPEED_100M: -+ speed = SPEED_100; -+ break; -+ case YTPHY_SSR_SPEED_1000M: -+ speed = SPEED_1000; -+ break; -+ default: -+ speed = SPEED_UNKNOWN; -+ break; -+ } -+ -+ phydev->speed = speed; -+ phydev->duplex = duplex; -+ -+ if (is_utp) { -+ err = ytphy_utp_read_lpa(phydev); -+ if (err < 0) -+ return err; -+ -+ phy_resolve_aneg_pause(phydev); -+ } else { -+ lpa = __phy_read(phydev, MII_LPA); -+ if (lpa < 0) -+ return lpa; -+ -+ /* only support 1000baseX Full */ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, -+ phydev->lp_advertising, lpa & LPA_1000XFULL); -+ -+ if (!(lpa & YTPHY_FLPA_PAUSE)) { -+ phydev->pause = 0; -+ phydev->asym_pause = 0; -+ } else if ((lpa & YTPHY_FLPA_ASYM_PAUSE)) { -+ phydev->pause = 1; -+ phydev->asym_pause = 1; -+ } else { -+ phydev->pause = 1; -+ phydev->asym_pause = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+/** -+ * yt8521_read_status_paged() - determines the speed and duplex of one page -+ * @phydev: a pointer to a &struct phy_device -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to -+ * operate. -+ * -+ * returns 1 (utp or fiber link),0 (no link) or negative errno code -+ */ -+static int yt8521_read_status_paged(struct phy_device *phydev, int page) -+{ -+ int fiber_latch_val; -+ int fiber_curr_val; -+ int old_page; -+ int ret = 0; -+ int status; -+ int link; -+ -+ linkmode_zero(phydev->lp_advertising); -+ phydev->duplex = DUPLEX_UNKNOWN; -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->asym_pause = 0; -+ phydev->pause = 0; -+ -+ /* YT8521 has two reg space (utp/fiber) for linkup with utp/fiber -+ * respectively. but for utp/fiber combo mode, reg space should be -+ * arbitrated based on media priority. by default, utp takes -+ * priority. reg space should be properly set before read -+ * YTPHY_SPECIFIC_STATUS_REG. -+ */ -+ -+ page &= YT8521_RSSR_SPACE_MASK; -+ old_page = phy_select_page(phydev, page); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ /* Read YTPHY_SPECIFIC_STATUS_REG, which indicates the speed and duplex -+ * of the PHY is actually using. -+ */ -+ ret = __phy_read(phydev, YTPHY_SPECIFIC_STATUS_REG); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ status = ret; -+ link = !!(status & YTPHY_SSR_LINK); -+ -+ /* When PHY is in fiber mode, speed transferred from 1000Mbps to -+ * 100Mbps,there is not link down from YTPHY_SPECIFIC_STATUS_REG, so -+ * we need check MII_BMSR to identify such case. -+ */ -+ if (page == YT8521_RSSR_FIBER_SPACE) { -+ ret = __phy_read(phydev, MII_BMSR); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ fiber_latch_val = ret; -+ ret = __phy_read(phydev, MII_BMSR); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ fiber_curr_val = ret; -+ if (link && fiber_latch_val != fiber_curr_val) { -+ link = 0; -+ phydev_info(phydev, -+ "%s, fiber link down detect, latch = %04x, curr = %04x\n", -+ __func__, fiber_latch_val, fiber_curr_val); -+ } -+ } else { -+ /* Read autonegotiation status */ -+ ret = __phy_read(phydev, MII_BMSR); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ phydev->autoneg_complete = ret & BMSR_ANEGCOMPLETE ? 1 : 0; -+ } -+ -+ if (link) { -+ if (page == YT8521_RSSR_UTP_SPACE) -+ yt8521_adjust_status(phydev, status, true); -+ else -+ yt8521_adjust_status(phydev, status, false); -+ } -+ return phy_restore_page(phydev, old_page, link); -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_read_status() - determines the negotiated speed and duplex -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_read_status(struct phy_device *phydev) -+{ -+ struct yt8521_priv *priv = phydev->priv; -+ int link_fiber = 0; -+ int link_utp; -+ int link; -+ int ret; -+ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ link = yt8521_read_status_paged(phydev, priv->reg_page); -+ if (link < 0) -+ return link; -+ } else { -+ /* when page is YT8521_RSSR_TO_BE_ARBITRATED, arbitration is -+ * needed. by default, utp is higher priority. -+ */ -+ -+ link_utp = yt8521_read_status_paged(phydev, -+ YT8521_RSSR_UTP_SPACE); -+ if (link_utp < 0) -+ return link_utp; -+ -+ if (!link_utp) { -+ link_fiber = yt8521_read_status_paged(phydev, -+ YT8521_RSSR_FIBER_SPACE); -+ if (link_fiber < 0) -+ return link_fiber; -+ } -+ -+ link = link_utp || link_fiber; -+ } -+ -+ if (link) { -+ if (phydev->link == 0) { -+ /* arbitrate reg space based on linkup media type. */ -+ if (priv->polling_mode == YT8521_MODE_POLL && -+ priv->reg_page == YT8521_RSSR_TO_BE_ARBITRATED) { -+ if (link_fiber) -+ priv->reg_page = -+ YT8521_RSSR_FIBER_SPACE; -+ else -+ priv->reg_page = YT8521_RSSR_UTP_SPACE; -+ -+ ret = ytphy_write_ext_with_lock(phydev, -+ YT8521_REG_SPACE_SELECT_REG, -+ priv->reg_page); -+ if (ret < 0) -+ return ret; -+ -+ phydev->port = link_fiber ? PORT_FIBRE : PORT_TP; -+ -+ phydev_info(phydev, "%s, link up, media: %s\n", -+ __func__, -+ (phydev->port == PORT_TP) ? -+ "UTP" : "Fiber"); -+ } -+ } -+ phydev->link = 1; -+ } else { -+ if (phydev->link == 1) { -+ phydev_info(phydev, "%s, link down, media: %s\n", -+ __func__, (phydev->port == PORT_TP) ? -+ "UTP" : "Fiber"); -+ -+ /* When in YT8521_MODE_POLL mode, need prepare for next -+ * arbitration. -+ */ -+ if (priv->polling_mode == YT8521_MODE_POLL) { -+ priv->reg_page = YT8521_RSSR_TO_BE_ARBITRATED; -+ phydev->port = PORT_NONE; -+ } -+ } -+ -+ phydev->link = 0; -+ } -+ -+ return 0; -+} -+ -+/** -+ * yt8521_modify_bmcr_paged - bits modify a PHY's BMCR register of one page -+ * @phydev: the phy_device struct -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to operate -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ * -+ * NOTE: Convenience function which allows a PHY's BMCR register to be -+ * modified as new register value = (old register value & ~mask) | set. -+ * YT8521 has two space (utp/fiber) and three mode (utp/fiber/poll), each space -+ * has MII_BMCR. poll mode combines utp and faber,so need do both. -+ * If it is reset, it will wait for completion. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_modify_bmcr_paged(struct phy_device *phydev, int page, -+ u16 mask, u16 set) -+{ -+ int max_cnt = 500; /* the max wait time of reset ~ 500 ms */ -+ int old_page; -+ int ret = 0; -+ -+ old_page = phy_select_page(phydev, page & YT8521_RSSR_SPACE_MASK); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ ret = __phy_modify(phydev, MII_BMCR, mask, set); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ /* If it is reset, need to wait for the reset to complete */ -+ if (set == BMCR_RESET) { -+ while (max_cnt--) { -+ usleep_range(1000, 1100); -+ ret = __phy_read(phydev, MII_BMCR); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ if (!(ret & BMCR_RESET)) -+ return phy_restore_page(phydev, old_page, 0); -+ } -+ } -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_modify_utp_fiber_bmcr - bits modify a PHY's BMCR register -+ * @phydev: the phy_device struct -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ * -+ * NOTE: Convenience function which allows a PHY's BMCR register to be -+ * modified as new register value = (old register value & ~mask) | set. -+ * YT8521 has two space (utp/fiber) and three mode (utp/fiber/poll), each space -+ * has MII_BMCR. poll mode combines utp and faber,so need do both. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_modify_utp_fiber_bmcr(struct phy_device *phydev, u16 mask, -+ u16 set) -+{ -+ struct yt8521_priv *priv = phydev->priv; -+ int ret; -+ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ ret = yt8521_modify_bmcr_paged(phydev, priv->reg_page, mask, -+ set); -+ if (ret < 0) -+ return ret; -+ } else { -+ ret = yt8521_modify_bmcr_paged(phydev, YT8521_RSSR_UTP_SPACE, -+ mask, set); -+ if (ret < 0) -+ return ret; -+ -+ ret = yt8521_modify_bmcr_paged(phydev, YT8521_RSSR_FIBER_SPACE, -+ mask, set); -+ if (ret < 0) -+ return ret; -+ } -+ return 0; -+} -+ -+/** -+ * yt8521_soft_reset() - called to issue a PHY software reset -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_soft_reset(struct phy_device *phydev) -+{ -+ return yt8521_modify_utp_fiber_bmcr(phydev, 0, BMCR_RESET); -+} -+ -+/** -+ * yt8521_suspend() - suspend the hardware -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_suspend(struct phy_device *phydev) -+{ -+ int wol_config; -+ -+ /* YTPHY_WOL_CONFIG_REG is common ext reg */ -+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG); -+ if (wol_config < 0) -+ return wol_config; -+ -+ /* if wol enable, do nothing */ -+ if (wol_config & YTPHY_WCR_ENABLE) -+ return 0; -+ -+ return yt8521_modify_utp_fiber_bmcr(phydev, 0, BMCR_PDOWN); -+} -+ -+/** -+ * yt8521_resume() - resume the hardware -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_resume(struct phy_device *phydev) -+{ -+ int ret; -+ int wol_config; -+ -+ /* disable auto sleep */ -+ ret = ytphy_modify_ext_with_lock(phydev, -+ YT8521_EXTREG_SLEEP_CONTROL1_REG, -+ YT8521_ESC1R_SLEEP_SW, 0); -+ if (ret < 0) -+ return ret; -+ -+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG); -+ if (wol_config < 0) -+ return wol_config; -+ -+ /* if wol enable, do nothing */ -+ if (wol_config & YTPHY_WCR_ENABLE) -+ return 0; -+ -+ return yt8521_modify_utp_fiber_bmcr(phydev, BMCR_PDOWN, 0); -+} -+ -+/** -+ * yt8521_config_init() - called to initialize the PHY -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_config_init(struct phy_device *phydev) -+{ -+ int old_page; -+ int ret = 0; -+ u16 val; -+ -+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS; -+ val |= YT8521_RC1R_RX_DELAY_DIS; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS; -+ val |= YT8521_RC1R_RX_DELAY_EN; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN; -+ val |= YT8521_RC1R_RX_DELAY_DIS; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN; -+ val |= YT8521_RC1R_RX_DELAY_EN; -+ break; -+ case PHY_INTERFACE_MODE_SGMII: -+ break; -+ default: /* do not support other modes */ -+ ret = -EOPNOTSUPP; -+ goto err_restore_page; -+ } -+ -+ /* set rgmii delay mode */ -+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII) { -+ ret = ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, -+ (YT8521_RC1R_RX_DELAY_MASK | -+ YT8521_RC1R_FE_TX_DELAY_MASK | -+ YT8521_RC1R_GE_TX_DELAY_MASK), -+ val); -+ if (ret < 0) -+ goto err_restore_page; -+ } -+ -+ /* disable auto sleep */ -+ ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG, -+ YT8521_ESC1R_SLEEP_SW, 0); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ /* enable RXC clock when no wire plug */ -+ ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG, -+ YT8521_CGR_RX_CLK_EN, 0); -+ if (ret < 0) -+ goto err_restore_page; -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_prepare_fiber_features() - A small helper function that setup -+ * fiber's features. -+ * @phydev: a pointer to a &struct phy_device -+ * @dst: a pointer to store fiber's features -+ */ -+static void yt8521_prepare_fiber_features(struct phy_device *phydev, -+ unsigned long *dst) -+{ -+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, dst); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, dst); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, dst); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, dst); -+} -+ -+/** -+ * yt8521_fiber_setup_forced - configures/forces speed from @phydev -+ * @phydev: target phy_device struct -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_fiber_setup_forced(struct phy_device *phydev) -+{ -+ u16 val; -+ int ret; -+ -+ if (phydev->speed == SPEED_1000) -+ val = YTPHY_MCR_FIBER_1000BX; -+ else if (phydev->speed == SPEED_100) -+ val = YTPHY_MCR_FIBER_100FX; -+ else -+ return -EINVAL; -+ -+ ret = __phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0); -+ if (ret < 0) -+ return ret; -+ -+ /* disable Fiber auto sensing */ -+ ret = ytphy_modify_ext(phydev, YT8521_LINK_TIMER_CFG2_REG, -+ YT8521_LTCR_EN_AUTOSEN, 0); -+ if (ret < 0) -+ return ret; -+ -+ ret = ytphy_modify_ext(phydev, YTPHY_MISC_CONFIG_REG, -+ YTPHY_MCR_FIBER_SPEED_MASK, val); -+ if (ret < 0) -+ return ret; -+ -+ return ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG, -+ YT8521_CCR_SW_RST, 0); -+} -+ -+/** -+ * ytphy_check_and_restart_aneg - Enable and restart auto-negotiation -+ * @phydev: target phy_device struct -+ * @restart: whether aneg restart is requested -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_check_and_restart_aneg(struct phy_device *phydev, bool restart) -+{ -+ int ret; -+ -+ if (!restart) { -+ /* Advertisement hasn't changed, but maybe aneg was never on to -+ * begin with? Or maybe phy was isolated? -+ */ -+ ret = __phy_read(phydev, MII_BMCR); -+ if (ret < 0) -+ return ret; -+ -+ if (!(ret & BMCR_ANENABLE) || (ret & BMCR_ISOLATE)) -+ restart = true; -+ } -+ /* Enable and Restart Autonegotiation -+ * Don't isolate the PHY if we're negotiating -+ */ -+ if (restart) -+ return __phy_modify(phydev, MII_BMCR, BMCR_ISOLATE, -+ BMCR_ANENABLE | BMCR_ANRESTART); -+ -+ return 0; -+} -+ -+/** -+ * yt8521_fiber_config_aneg - restart auto-negotiation or write -+ * YTPHY_MISC_CONFIG_REG. -+ * @phydev: target phy_device struct -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_fiber_config_aneg(struct phy_device *phydev) -+{ -+ int err, changed = 0; -+ int bmcr; -+ u16 adv; -+ -+ if (phydev->autoneg != AUTONEG_ENABLE) -+ return yt8521_fiber_setup_forced(phydev); -+ -+ /* enable Fiber auto sensing */ -+ err = ytphy_modify_ext(phydev, YT8521_LINK_TIMER_CFG2_REG, -+ 0, YT8521_LTCR_EN_AUTOSEN); -+ if (err < 0) -+ return err; -+ -+ err = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG, -+ YT8521_CCR_SW_RST, 0); -+ if (err < 0) -+ return err; -+ -+ bmcr = __phy_read(phydev, MII_BMCR); -+ if (bmcr < 0) -+ return bmcr; -+ -+ /* When it is coming from fiber forced mode, add bmcr power down -+ * and power up to let aneg work fine. -+ */ -+ if (!(bmcr & BMCR_ANENABLE)) { -+ __phy_modify(phydev, MII_BMCR, 0, BMCR_PDOWN); -+ usleep_range(1000, 1100); -+ __phy_modify(phydev, MII_BMCR, BMCR_PDOWN, 0); -+ } -+ -+ adv = linkmode_adv_to_mii_adv_x(phydev->advertising, -+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT); -+ -+ /* Setup fiber advertisement */ -+ err = __phy_modify_changed(phydev, MII_ADVERTISE, -+ ADVERTISE_1000XHALF | ADVERTISE_1000XFULL | -+ ADVERTISE_1000XPAUSE | -+ ADVERTISE_1000XPSE_ASYM, -+ adv); -+ if (err < 0) -+ return err; -+ -+ if (err > 0) -+ changed = 1; -+ -+ return ytphy_check_and_restart_aneg(phydev, changed); -+} -+ -+/** -+ * ytphy_setup_master_slave -+ * @phydev: target phy_device struct -+ * -+ * NOTE: The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_setup_master_slave(struct phy_device *phydev) -+{ -+ u16 ctl = 0; -+ -+ if (!phydev->is_gigabit_capable) -+ return 0; -+ -+ switch (phydev->master_slave_set) { -+ case MASTER_SLAVE_CFG_MASTER_PREFERRED: -+ ctl |= CTL1000_PREFER_MASTER; -+ break; -+ case MASTER_SLAVE_CFG_SLAVE_PREFERRED: -+ break; -+ case MASTER_SLAVE_CFG_MASTER_FORCE: -+ ctl |= CTL1000_AS_MASTER; -+ fallthrough; -+ case MASTER_SLAVE_CFG_SLAVE_FORCE: -+ ctl |= CTL1000_ENABLE_MASTER; -+ break; -+ case MASTER_SLAVE_CFG_UNKNOWN: -+ case MASTER_SLAVE_CFG_UNSUPPORTED: -+ return 0; -+ default: -+ phydev_warn(phydev, "Unsupported Master/Slave mode\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ return __phy_modify_changed(phydev, MII_CTRL1000, -+ (CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER | -+ CTL1000_PREFER_MASTER), ctl); -+} -+ -+/** -+ * ytphy_utp_config_advert - sanitize and advertise auto-negotiation parameters -+ * @phydev: target phy_device struct -+ * -+ * NOTE: Writes MII_ADVERTISE with the appropriate values, -+ * after sanitizing the values to make sure we only advertise -+ * what is supported. Returns < 0 on error, 0 if the PHY's advertisement -+ * hasn't changed, and > 0 if it has changed. -+ * The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_utp_config_advert(struct phy_device *phydev) -+{ -+ int err, bmsr, changed = 0; -+ u32 adv; -+ -+ /* Only allow advertising what this PHY supports */ -+ linkmode_and(phydev->advertising, phydev->advertising, -+ phydev->supported); -+ -+ adv = linkmode_adv_to_mii_adv_t(phydev->advertising); -+ -+ /* Setup standard advertisement */ -+ err = __phy_modify_changed(phydev, MII_ADVERTISE, -+ ADVERTISE_ALL | ADVERTISE_100BASE4 | -+ ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM, -+ adv); -+ if (err < 0) -+ return err; -+ if (err > 0) -+ changed = 1; -+ -+ bmsr = __phy_read(phydev, MII_BMSR); -+ if (bmsr < 0) -+ return bmsr; -+ -+ /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all -+ * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a -+ * logical 1. -+ */ -+ if (!(bmsr & BMSR_ESTATEN)) -+ return changed; -+ -+ adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); -+ -+ err = __phy_modify_changed(phydev, MII_CTRL1000, -+ ADVERTISE_1000FULL | ADVERTISE_1000HALF, -+ adv); -+ if (err < 0) -+ return err; -+ if (err > 0) -+ changed = 1; -+ -+ return changed; -+} -+ -+/** -+ * ytphy_utp_config_aneg - restart auto-negotiation or write BMCR -+ * @phydev: target phy_device struct -+ * @changed: whether autoneg is requested -+ * -+ * NOTE: If auto-negotiation is enabled, we configure the -+ * advertising, and then restart auto-negotiation. If it is not -+ * enabled, then we write the BMCR. -+ * The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_utp_config_aneg(struct phy_device *phydev, bool changed) -+{ -+ int err; -+ u16 ctl; -+ -+ err = ytphy_setup_master_slave(phydev); -+ if (err < 0) -+ return err; -+ else if (err) -+ changed = true; -+ -+ if (phydev->autoneg != AUTONEG_ENABLE) { -+ /* configures/forces speed/duplex from @phydev */ -+ -+ ctl = mii_bmcr_encode_fixed(phydev->speed, phydev->duplex); -+ -+ return __phy_modify(phydev, MII_BMCR, ~(BMCR_LOOPBACK | -+ BMCR_ISOLATE | BMCR_PDOWN), ctl); -+ } -+ -+ err = ytphy_utp_config_advert(phydev); -+ if (err < 0) /* error */ -+ return err; -+ else if (err) -+ changed = true; -+ -+ return ytphy_check_and_restart_aneg(phydev, changed); -+} -+ -+/** -+ * yt8521_config_aneg_paged() - switch reg space then call genphy_config_aneg -+ * of one page -+ * @phydev: a pointer to a &struct phy_device -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to -+ * operate. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_config_aneg_paged(struct phy_device *phydev, int page) -+{ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(fiber_supported); -+ struct yt8521_priv *priv = phydev->priv; -+ int old_page; -+ int ret = 0; -+ -+ page &= YT8521_RSSR_SPACE_MASK; -+ -+ old_page = phy_select_page(phydev, page); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ /* If reg_page is YT8521_RSSR_TO_BE_ARBITRATED, -+ * phydev->advertising should be updated. -+ */ -+ if (priv->reg_page == YT8521_RSSR_TO_BE_ARBITRATED) { -+ linkmode_zero(fiber_supported); -+ yt8521_prepare_fiber_features(phydev, fiber_supported); -+ -+ /* prepare fiber_supported, then setup advertising. */ -+ if (page == YT8521_RSSR_FIBER_SPACE) { -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, -+ fiber_supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, -+ fiber_supported); -+ linkmode_and(phydev->advertising, -+ priv->combo_advertising, fiber_supported); -+ } else { -+ /* ETHTOOL_LINK_MODE_Autoneg_BIT is also used in utp */ -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ fiber_supported); -+ linkmode_andnot(phydev->advertising, -+ priv->combo_advertising, -+ fiber_supported); -+ } -+ } -+ -+ if (page == YT8521_RSSR_FIBER_SPACE) -+ ret = yt8521_fiber_config_aneg(phydev); -+ else -+ ret = ytphy_utp_config_aneg(phydev, false); -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_config_aneg() - change reg space then call yt8521_config_aneg_paged -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_config_aneg(struct phy_device *phydev) -+{ -+ struct yt8521_priv *priv = phydev->priv; -+ int ret; -+ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ ret = yt8521_config_aneg_paged(phydev, priv->reg_page); -+ if (ret < 0) -+ return ret; -+ } else { -+ /* If reg_page is YT8521_RSSR_TO_BE_ARBITRATED, -+ * phydev->advertising need to be saved at first run. -+ * Because it contains the advertising which supported by both -+ * mac and yt8521(utp and fiber). -+ */ -+ if (linkmode_empty(priv->combo_advertising)) { -+ linkmode_copy(priv->combo_advertising, -+ phydev->advertising); -+ } -+ -+ ret = yt8521_config_aneg_paged(phydev, YT8521_RSSR_UTP_SPACE); -+ if (ret < 0) -+ return ret; -+ -+ ret = yt8521_config_aneg_paged(phydev, YT8521_RSSR_FIBER_SPACE); -+ if (ret < 0) -+ return ret; -+ -+ /* we don't known which will be link, so restore -+ * phydev->advertising as default value. -+ */ -+ linkmode_copy(phydev->advertising, priv->combo_advertising); -+ } -+ return 0; -+} -+ -+/** -+ * yt8521_aneg_done_paged() - determines the auto negotiation result of one -+ * page. -+ * @phydev: a pointer to a &struct phy_device -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to -+ * operate. -+ * -+ * returns 0(no link)or 1(fiber or utp link) or negative errno code -+ */ -+static int yt8521_aneg_done_paged(struct phy_device *phydev, int page) -+{ -+ int old_page; -+ int ret = 0; -+ int link; -+ -+ old_page = phy_select_page(phydev, page & YT8521_RSSR_SPACE_MASK); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ ret = __phy_read(phydev, YTPHY_SPECIFIC_STATUS_REG); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ link = !!(ret & YTPHY_SSR_LINK); -+ ret = link; -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_aneg_done() - determines the auto negotiation result -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0(no link)or 1(fiber or utp link) or negative errno code -+ */ -+static int yt8521_aneg_done(struct phy_device *phydev) -+{ -+ struct yt8521_priv *priv = phydev->priv; -+ int link_fiber = 0; -+ int link_utp; -+ int link; -+ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ link = yt8521_aneg_done_paged(phydev, priv->reg_page); -+ } else { -+ link_utp = yt8521_aneg_done_paged(phydev, -+ YT8521_RSSR_UTP_SPACE); -+ if (link_utp < 0) -+ return link_utp; -+ -+ if (!link_utp) { -+ link_fiber = yt8521_aneg_done_paged(phydev, -+ YT8521_RSSR_FIBER_SPACE); -+ if (link_fiber < 0) -+ return link_fiber; -+ } -+ link = link_fiber || link_utp; -+ phydev_info(phydev, "%s, link_fiber: %d, link_utp: %d\n", -+ __func__, link_fiber, link_utp); -+ } -+ -+ return link; -+} -+ -+/** -+ * ytphy_utp_read_abilities - read PHY abilities from Clause 22 registers -+ * @phydev: target phy_device struct -+ * -+ * NOTE: Reads the PHY's abilities and populates -+ * phydev->supported accordingly. -+ * The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_utp_read_abilities(struct phy_device *phydev) -+{ -+ int val; -+ -+ linkmode_set_bit_array(phy_basic_ports_array, -+ ARRAY_SIZE(phy_basic_ports_array), -+ phydev->supported); -+ -+ val = __phy_read(phydev, MII_BMSR); -+ if (val < 0) -+ return val; -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported, -+ val & BMSR_ANEGCAPABLE); -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported, -+ val & BMSR_100FULL); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, phydev->supported, -+ val & BMSR_100HALF); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, phydev->supported, -+ val & BMSR_10FULL); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, phydev->supported, -+ val & BMSR_10HALF); -+ -+ if (val & BMSR_ESTATEN) { -+ val = __phy_read(phydev, MII_ESTATUS); -+ if (val < 0) -+ return val; -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ phydev->supported, val & ESTATUS_1000_TFULL); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -+ phydev->supported, val & ESTATUS_1000_THALF); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, -+ phydev->supported, val & ESTATUS_1000_XFULL); -+ } -+ -+ return 0; -+} -+ -+/** -+ * yt8521_get_features_paged() - read supported link modes for one page -+ * @phydev: a pointer to a &struct phy_device -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to -+ * operate. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_get_features_paged(struct phy_device *phydev, int page) -+{ -+ int old_page; -+ int ret = 0; -+ -+ page &= YT8521_RSSR_SPACE_MASK; -+ old_page = phy_select_page(phydev, page); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ if (page == YT8521_RSSR_FIBER_SPACE) { -+ linkmode_zero(phydev->supported); -+ yt8521_prepare_fiber_features(phydev, phydev->supported); -+ } else { -+ ret = ytphy_utp_read_abilities(phydev); -+ if (ret < 0) -+ goto err_restore_page; -+ } -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_get_features - switch reg space then call yt8521_get_features_paged -+ * @phydev: target phy_device struct -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_get_features(struct phy_device *phydev) -+{ -+ struct yt8521_priv *priv = phydev->priv; -+ int ret; -+ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ ret = yt8521_get_features_paged(phydev, priv->reg_page); -+ } else { -+ ret = yt8521_get_features_paged(phydev, -+ YT8521_RSSR_UTP_SPACE); -+ if (ret < 0) -+ return ret; -+ -+ /* add fiber's features to phydev->supported */ -+ yt8521_prepare_fiber_features(phydev, phydev->supported); -+ } -+ return ret; -+} -+ - static struct phy_driver motorcomm_phy_drvs[] = { - { - PHY_ID_MATCH_EXACT(PHY_ID_YT8511), -@@ -121,16 +1733,35 @@ static struct phy_driver motorcomm_phy_d - .read_page = yt8511_read_page, - .write_page = yt8511_write_page, - }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_YT8521), -+ .name = "YT8521 Gigabit Ethernet", -+ .get_features = yt8521_get_features, -+ .probe = yt8521_probe, -+ .read_page = yt8521_read_page, -+ .write_page = yt8521_write_page, -+ .get_wol = ytphy_get_wol, -+ .set_wol = ytphy_set_wol, -+ .config_aneg = yt8521_config_aneg, -+ .aneg_done = yt8521_aneg_done, -+ .config_init = yt8521_config_init, -+ .read_status = yt8521_read_status, -+ .soft_reset = yt8521_soft_reset, -+ .suspend = yt8521_suspend, -+ .resume = yt8521_resume, -+ }, - }; - - module_phy_driver(motorcomm_phy_drvs); - --MODULE_DESCRIPTION("Motorcomm PHY driver"); -+MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver"); - MODULE_AUTHOR("Peter Geis"); -+MODULE_AUTHOR("Frank"); - MODULE_LICENSE("GPL"); - - static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { - { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, -+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, - { /* sentinal */ } - }; - diff --git a/target/linux/generic/backport-5.15/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch b/target/linux/generic/backport-5.15/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch deleted file mode 100644 index cce71c8d84bfd7..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 4e0243e7128c9b25ea2739136076a95d6adaba5e Mon Sep 17 00:00:00 2001 -From: Frank -Date: Fri, 4 Nov 2022 16:44:41 +0800 -Subject: [PATCH] net: phy: fix yt8521 duplicated argument to & or | - -cocci warnings: (new ones prefixed by >>) ->> drivers/net/phy/motorcomm.c:1122:8-35: duplicated argument to & or | - drivers/net/phy/motorcomm.c:1126:8-35: duplicated argument to & or | - drivers/net/phy/motorcomm.c:1130:8-34: duplicated argument to & or | - drivers/net/phy/motorcomm.c:1134:8-34: duplicated argument to & or | - - The second YT8521_RC1R_GE_TX_DELAY_xx should be YT8521_RC1R_FE_TX_DELAY_xx. - -Fixes: 70479a40954c ("net: phy: Add driver for Motorcomm yt8521 gigabit ethernet phy") -Reported-by: kernel test robot -Reported-by: Julia Lawall -Signed-off-by: Frank -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/motorcomm.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1119,19 +1119,19 @@ static int yt8521_config_init(struct phy - - switch (phydev->interface) { - case PHY_INTERFACE_MODE_RGMII: -- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS; -+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; - val |= YT8521_RC1R_RX_DELAY_DIS; - break; - case PHY_INTERFACE_MODE_RGMII_RXID: -- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS; -+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; - val |= YT8521_RC1R_RX_DELAY_EN; - break; - case PHY_INTERFACE_MODE_RGMII_TXID: -- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN; -+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; - val |= YT8521_RC1R_RX_DELAY_DIS; - break; - case PHY_INTERFACE_MODE_RGMII_ID: -- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN; -+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; - val |= YT8521_RC1R_RX_DELAY_EN; - break; - case PHY_INTERFACE_MODE_SGMII: diff --git a/target/linux/generic/backport-5.15/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch b/target/linux/generic/backport-5.15/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch deleted file mode 100644 index 94d09092cfd201..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 813abcd98fb1b2cccf850cdfa092a4bfc50b2363 Mon Sep 17 00:00:00 2001 -From: Frank -Date: Tue, 22 Nov 2022 16:42:32 +0800 -Subject: [PATCH] net: phy: add Motorcomm YT8531S phy id. - -We added patch for motorcomm.c to support YT8531S. This patch has -been tested on AM335x platform which has one YT8531S interface -card and passed all test cases. -The tested cases indluding: YT8531S UTP function with support of -10M/100M/1000M; YT8531S Fiber function with support of 100M/1000M; -and YT8531S Combo function that supports auto detection of media type. - -Since most functions of YT8531S are similar to YT8521 and we reuse some -codes for YT8521 in the patch file. - -Signed-off-by: Frank -Signed-off-by: David S. Miller ---- - drivers/net/phy/Kconfig | 2 +- - drivers/net/phy/motorcomm.c | 52 +++++++++++++++++++++++++++++++++---- - 2 files changed, 48 insertions(+), 6 deletions(-) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -242,7 +242,7 @@ config MOTORCOMM_PHY - tristate "Motorcomm PHYs" - help - Enables support for Motorcomm network PHYs. -- Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs. -+ Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs. - - config NATIONAL_PHY - tristate "National Semiconductor PHYs" ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* -- * Motorcomm 8511/8521 PHY driver. -+ * Motorcomm 8511/8521/8531S PHY driver. - * - * Author: Peter Geis - * Author: Frank -@@ -12,9 +12,10 @@ - #include - - #define PHY_ID_YT8511 0x0000010a --#define PHY_ID_YT8521 0x0000011A -+#define PHY_ID_YT8521 0x0000011A -+#define PHY_ID_YT8531S 0x4F51E91A - --/* YT8521 Register Overview -+/* YT8521/YT8531S Register Overview - * UTP Register space | FIBER Register space - * ------------------------------------------------------------ - * | UTP MII | FIBER MII | -@@ -147,7 +148,7 @@ - #define YT8521_LINK_TIMER_CFG2_REG 0xA5 - #define YT8521_LTCR_EN_AUTOSEN BIT(15) - --/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers -+/* 0xA000, 0xA001, 0xA003, 0xA006 ~ 0xA00A and 0xA012 are common ext registers - * of yt8521 phy. There is no need to switch reg space when operating these - * registers. - */ -@@ -221,6 +222,9 @@ - */ - #define YTPHY_WCR_TYPE_PULSE BIT(0) - -+#define YT8531S_SYNCE_CFG_REG 0xA012 -+#define YT8531S_SCR_SYNCE_ENABLE BIT(6) -+ - /* Extended Register end */ - - struct yt8521_priv { -@@ -648,6 +652,26 @@ static int yt8521_probe(struct phy_devic - } - - /** -+ * yt8531s_probe() - read chip config then set suitable polling_mode -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8531s_probe(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Disable SyncE clock output by default */ -+ ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG, -+ YT8531S_SCR_SYNCE_ENABLE, 0); -+ if (ret < 0) -+ return ret; -+ -+ /* same as yt8521_probe */ -+ return yt8521_probe(phydev); -+} -+ -+/** - * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp - * @phydev: a pointer to a &struct phy_device - * -@@ -1750,11 +1774,28 @@ static struct phy_driver motorcomm_phy_d - .suspend = yt8521_suspend, - .resume = yt8521_resume, - }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), -+ .name = "YT8531S Gigabit Ethernet", -+ .get_features = yt8521_get_features, -+ .probe = yt8531s_probe, -+ .read_page = yt8521_read_page, -+ .write_page = yt8521_write_page, -+ .get_wol = ytphy_get_wol, -+ .set_wol = ytphy_set_wol, -+ .config_aneg = yt8521_config_aneg, -+ .aneg_done = yt8521_aneg_done, -+ .config_init = yt8521_config_init, -+ .read_status = yt8521_read_status, -+ .soft_reset = yt8521_soft_reset, -+ .suspend = yt8521_suspend, -+ .resume = yt8521_resume, -+ }, - }; - - module_phy_driver(motorcomm_phy_drvs); - --MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver"); -+MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver"); - MODULE_AUTHOR("Peter Geis"); - MODULE_AUTHOR("Frank"); - MODULE_LICENSE("GPL"); -@@ -1762,6 +1803,7 @@ MODULE_LICENSE("GPL"); - static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { - { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, - { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, -+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, - { /* sentinal */ } - }; - diff --git a/target/linux/generic/backport-5.15/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch b/target/linux/generic/backport-5.15/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch deleted file mode 100644 index 94fc32aadb320d..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 4104a713204d62aca482eebb0c6226d82a0721eb Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Sat, 28 Jan 2023 14:35:57 +0800 -Subject: [PATCH] net: phy: fix the spelling problem of Sentinel - -CHECK: 'sentinal' may be misspelled - perhaps 'sentinel'? - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20230128063558.5850-1-Frank.Sae@motor-comm.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/motorcomm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1804,7 +1804,7 @@ static const struct mdio_device_id __may - { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, - { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, - { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, -- { /* sentinal */ } -+ { /* sentinel */ } - }; - - MODULE_DEVICE_TABLE(mdio, motorcomm_tbl); diff --git a/target/linux/generic/backport-5.15/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch b/target/linux/generic/backport-5.15/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch deleted file mode 100644 index 076fa82d267fce..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 3c1dc22162d673d595855d24f95200ed2643f88f Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Sat, 28 Jan 2023 14:35:58 +0800 -Subject: [PATCH] net: phy: motorcomm: change the phy id of yt8521 and yt8531s - to lowercase - -The phy id is usually defined in lower case. - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20230128063558.5850-2-Frank.Sae@motor-comm.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/motorcomm.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -12,8 +12,8 @@ - #include - - #define PHY_ID_YT8511 0x0000010a --#define PHY_ID_YT8521 0x0000011A --#define PHY_ID_YT8531S 0x4F51E91A -+#define PHY_ID_YT8521 0x0000011a -+#define PHY_ID_YT8531S 0x4f51e91a - - /* YT8521/YT8531S Register Overview - * UTP Register space | FIBER Register space diff --git a/target/linux/generic/backport-5.15/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch b/target/linux/generic/backport-5.15/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch deleted file mode 100644 index ba9a6ab4ccba3b..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 4869a146cd60fc8115230f0a45e15e534c531922 Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Thu, 2 Feb 2023 11:00:34 +0800 -Subject: [PATCH] net: phy: Add BIT macro for Motorcomm yt8521/yt8531 gigabit - ethernet phy - -Add BIT macro for Motorcomm yt8521/yt8531 gigabit ethernet phy. - This is a preparatory patch. Add BIT macro for 0xA012 reg, and - supplement for 0xA001 and 0xA003 reg. These will be used to support dts. - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/motorcomm.c | 55 ++++++++++++++++++++++++++++++++++--- - 1 file changed, 51 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -161,6 +161,11 @@ - - #define YT8521_CHIP_CONFIG_REG 0xA001 - #define YT8521_CCR_SW_RST BIT(15) -+/* 1b0 disable 1.9ns rxc clock delay *default* -+ * 1b1 enable 1.9ns rxc clock delay -+ */ -+#define YT8521_CCR_RXC_DLY_EN BIT(8) -+#define YT8521_CCR_RXC_DLY_1_900_NS 1900 - - #define YT8521_CCR_MODE_SEL_MASK (BIT(2) | BIT(1) | BIT(0)) - #define YT8521_CCR_MODE_UTP_TO_RGMII 0 -@@ -178,22 +183,41 @@ - #define YT8521_MODE_POLL 0x3 - - #define YT8521_RGMII_CONFIG1_REG 0xA003 -- -+/* 1b0 use original tx_clk_rgmii *default* -+ * 1b1 use inverted tx_clk_rgmii. -+ */ -+#define YT8521_RC1R_TX_CLK_SEL_INVERTED BIT(14) - /* TX Gig-E Delay is bits 3:0, default 0x1 - * TX Fast-E Delay is bits 7:4, default 0xf - * RX Delay is bits 13:10, default 0x0 - * Delay = 150ps * N - * On = 2250ps, off = 0ps - */ --#define YT8521_RC1R_RX_DELAY_MASK (0xF << 10) -+#define YT8521_RC1R_RX_DELAY_MASK GENMASK(13, 10) - #define YT8521_RC1R_RX_DELAY_EN (0xF << 10) - #define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10) --#define YT8521_RC1R_FE_TX_DELAY_MASK (0xF << 4) -+#define YT8521_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4) - #define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4) - #define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4) --#define YT8521_RC1R_GE_TX_DELAY_MASK (0xF << 0) -+#define YT8521_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0) - #define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0) - #define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0) -+#define YT8521_RC1R_RGMII_0_000_NS 0 -+#define YT8521_RC1R_RGMII_0_150_NS 1 -+#define YT8521_RC1R_RGMII_0_300_NS 2 -+#define YT8521_RC1R_RGMII_0_450_NS 3 -+#define YT8521_RC1R_RGMII_0_600_NS 4 -+#define YT8521_RC1R_RGMII_0_750_NS 5 -+#define YT8521_RC1R_RGMII_0_900_NS 6 -+#define YT8521_RC1R_RGMII_1_050_NS 7 -+#define YT8521_RC1R_RGMII_1_200_NS 8 -+#define YT8521_RC1R_RGMII_1_350_NS 9 -+#define YT8521_RC1R_RGMII_1_500_NS 10 -+#define YT8521_RC1R_RGMII_1_650_NS 11 -+#define YT8521_RC1R_RGMII_1_800_NS 12 -+#define YT8521_RC1R_RGMII_1_950_NS 13 -+#define YT8521_RC1R_RGMII_2_100_NS 14 -+#define YT8521_RC1R_RGMII_2_250_NS 15 - - #define YTPHY_MISC_CONFIG_REG 0xA006 - #define YTPHY_MCR_FIBER_SPEED_MASK BIT(0) -@@ -222,6 +246,29 @@ - */ - #define YTPHY_WCR_TYPE_PULSE BIT(0) - -+#define YTPHY_SYNCE_CFG_REG 0xA012 -+#define YT8521_SCR_SYNCE_ENABLE BIT(5) -+/* 1b0 output 25m clock -+ * 1b1 output 125m clock *default* -+ */ -+#define YT8521_SCR_CLK_FRE_SEL_125M BIT(3) -+#define YT8521_SCR_CLK_SRC_MASK GENMASK(2, 1) -+#define YT8521_SCR_CLK_SRC_PLL_125M 0 -+#define YT8521_SCR_CLK_SRC_UTP_RX 1 -+#define YT8521_SCR_CLK_SRC_SDS_RX 2 -+#define YT8521_SCR_CLK_SRC_REF_25M 3 -+#define YT8531_SCR_SYNCE_ENABLE BIT(6) -+/* 1b0 output 25m clock *default* -+ * 1b1 output 125m clock -+ */ -+#define YT8531_SCR_CLK_FRE_SEL_125M BIT(4) -+#define YT8531_SCR_CLK_SRC_MASK GENMASK(3, 1) -+#define YT8531_SCR_CLK_SRC_PLL_125M 0 -+#define YT8531_SCR_CLK_SRC_UTP_RX 1 -+#define YT8531_SCR_CLK_SRC_SDS_RX 2 -+#define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3 -+#define YT8531_SCR_CLK_SRC_REF_25M 4 -+#define YT8531_SCR_CLK_SRC_SSC_25M 5 - #define YT8531S_SYNCE_CFG_REG 0xA012 - #define YT8531S_SCR_SYNCE_ENABLE BIT(6) - diff --git a/target/linux/generic/backport-5.15/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch b/target/linux/generic/backport-5.15/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch deleted file mode 100644 index 6d89fae84ccc2f..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch +++ /dev/null @@ -1,343 +0,0 @@ -From a6e68f0f8769f79c67cdcfb6302feecd36197dec Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Thu, 2 Feb 2023 11:00:35 +0800 -Subject: [PATCH] net: phy: Add dts support for Motorcomm yt8521 gigabit - ethernet phy - -Add dts support for Motorcomm yt8521 gigabit ethernet phy. - Add ytphy_rgmii_clk_delay_config function to support dst config for - the delay of rgmii clk. This funciont is common for yt8521, yt8531s - and yt8531. - This patch has been verified on AM335x platform. - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/motorcomm.c | 253 ++++++++++++++++++++++++++++-------- - 1 file changed, 199 insertions(+), 54 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #define PHY_ID_YT8511 0x0000010a - #define PHY_ID_YT8521 0x0000011a -@@ -187,21 +188,9 @@ - * 1b1 use inverted tx_clk_rgmii. - */ - #define YT8521_RC1R_TX_CLK_SEL_INVERTED BIT(14) --/* TX Gig-E Delay is bits 3:0, default 0x1 -- * TX Fast-E Delay is bits 7:4, default 0xf -- * RX Delay is bits 13:10, default 0x0 -- * Delay = 150ps * N -- * On = 2250ps, off = 0ps -- */ - #define YT8521_RC1R_RX_DELAY_MASK GENMASK(13, 10) --#define YT8521_RC1R_RX_DELAY_EN (0xF << 10) --#define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10) - #define YT8521_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4) --#define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4) --#define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4) - #define YT8521_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0) --#define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0) --#define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0) - #define YT8521_RC1R_RGMII_0_000_NS 0 - #define YT8521_RC1R_RGMII_0_150_NS 1 - #define YT8521_RC1R_RGMII_0_300_NS 2 -@@ -274,6 +263,10 @@ - - /* Extended Register end */ - -+#define YTPHY_DTS_OUTPUT_CLK_DIS 0 -+#define YTPHY_DTS_OUTPUT_CLK_25M 25000000 -+#define YTPHY_DTS_OUTPUT_CLK_125M 125000000 -+ - struct yt8521_priv { - /* combo_advertising is used for case of YT8521 in combo mode, - * this means that yt8521 may work in utp or fiber mode which depends -@@ -641,6 +634,142 @@ static int yt8521_write_page(struct phy_ - }; - - /** -+ * struct ytphy_cfg_reg_map - map a config value to a register value -+ * @cfg: value in device configuration -+ * @reg: value in the register -+ */ -+struct ytphy_cfg_reg_map { -+ u32 cfg; -+ u32 reg; -+}; -+ -+static const struct ytphy_cfg_reg_map ytphy_rgmii_delays[] = { -+ /* for tx delay / rx delay with YT8521_CCR_RXC_DLY_EN is not set. */ -+ { 0, YT8521_RC1R_RGMII_0_000_NS }, -+ { 150, YT8521_RC1R_RGMII_0_150_NS }, -+ { 300, YT8521_RC1R_RGMII_0_300_NS }, -+ { 450, YT8521_RC1R_RGMII_0_450_NS }, -+ { 600, YT8521_RC1R_RGMII_0_600_NS }, -+ { 750, YT8521_RC1R_RGMII_0_750_NS }, -+ { 900, YT8521_RC1R_RGMII_0_900_NS }, -+ { 1050, YT8521_RC1R_RGMII_1_050_NS }, -+ { 1200, YT8521_RC1R_RGMII_1_200_NS }, -+ { 1350, YT8521_RC1R_RGMII_1_350_NS }, -+ { 1500, YT8521_RC1R_RGMII_1_500_NS }, -+ { 1650, YT8521_RC1R_RGMII_1_650_NS }, -+ { 1800, YT8521_RC1R_RGMII_1_800_NS }, -+ { 1950, YT8521_RC1R_RGMII_1_950_NS }, /* default tx/rx delay */ -+ { 2100, YT8521_RC1R_RGMII_2_100_NS }, -+ { 2250, YT8521_RC1R_RGMII_2_250_NS }, -+ -+ /* only for rx delay with YT8521_CCR_RXC_DLY_EN is set. */ -+ { 0 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_000_NS }, -+ { 150 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_150_NS }, -+ { 300 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_300_NS }, -+ { 450 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_450_NS }, -+ { 600 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_600_NS }, -+ { 750 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_750_NS }, -+ { 900 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_900_NS }, -+ { 1050 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_050_NS }, -+ { 1200 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_200_NS }, -+ { 1350 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_350_NS }, -+ { 1500 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_500_NS }, -+ { 1650 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_650_NS }, -+ { 1800 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_800_NS }, -+ { 1950 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_950_NS }, -+ { 2100 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_2_100_NS }, -+ { 2250 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_2_250_NS } -+}; -+ -+static u32 ytphy_get_delay_reg_value(struct phy_device *phydev, -+ const char *prop_name, -+ const struct ytphy_cfg_reg_map *tbl, -+ int tb_size, -+ u16 *rxc_dly_en, -+ u32 dflt) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ int tb_size_half = tb_size / 2; -+ u32 val; -+ int i; -+ -+ if (of_property_read_u32(node, prop_name, &val)) -+ goto err_dts_val; -+ -+ /* when rxc_dly_en is NULL, it is get the delay for tx, only half of -+ * tb_size is valid. -+ */ -+ if (!rxc_dly_en) -+ tb_size = tb_size_half; -+ -+ for (i = 0; i < tb_size; i++) { -+ if (tbl[i].cfg == val) { -+ if (rxc_dly_en && i < tb_size_half) -+ *rxc_dly_en = 0; -+ return tbl[i].reg; -+ } -+ } -+ -+ phydev_warn(phydev, "Unsupported value %d for %s using default (%u)\n", -+ val, prop_name, dflt); -+ -+err_dts_val: -+ /* when rxc_dly_en is not NULL, it is get the delay for rx. -+ * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps, -+ * so YT8521_CCR_RXC_DLY_EN should not be set. -+ */ -+ if (rxc_dly_en) -+ *rxc_dly_en = 0; -+ -+ return dflt; -+} -+ -+static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev) -+{ -+ int tb_size = ARRAY_SIZE(ytphy_rgmii_delays); -+ u16 rxc_dly_en = YT8521_CCR_RXC_DLY_EN; -+ u32 rx_reg, tx_reg; -+ u16 mask, val = 0; -+ int ret; -+ -+ rx_reg = ytphy_get_delay_reg_value(phydev, "rx-internal-delay-ps", -+ ytphy_rgmii_delays, tb_size, -+ &rxc_dly_en, -+ YT8521_RC1R_RGMII_1_950_NS); -+ tx_reg = ytphy_get_delay_reg_value(phydev, "tx-internal-delay-ps", -+ ytphy_rgmii_delays, tb_size, NULL, -+ YT8521_RC1R_RGMII_1_950_NS); -+ -+ switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ rxc_dly_en = 0; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg); -+ break; -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ rxc_dly_en = 0; -+ val |= FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg); -+ break; -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg) | -+ FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg); -+ break; -+ default: /* do not support other modes */ -+ return -EOPNOTSUPP; -+ } -+ -+ ret = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG, -+ YT8521_CCR_RXC_DLY_EN, rxc_dly_en); -+ if (ret < 0) -+ return ret; -+ -+ /* Generally, it is not necessary to adjust YT8521_RC1R_FE_TX_DELAY */ -+ mask = YT8521_RC1R_RX_DELAY_MASK | YT8521_RC1R_GE_TX_DELAY_MASK; -+ return ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, mask, val); -+} -+ -+/** - * yt8521_probe() - read chip config then set suitable polling_mode - * @phydev: a pointer to a &struct phy_device - * -@@ -648,9 +777,12 @@ static int yt8521_write_page(struct phy_ - */ - static int yt8521_probe(struct phy_device *phydev) - { -+ struct device_node *node = phydev->mdio.dev.of_node; - struct device *dev = &phydev->mdio.dev; - struct yt8521_priv *priv; - int chip_config; -+ u16 mask, val; -+ u32 freq; - int ret; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -@@ -695,7 +827,45 @@ static int yt8521_probe(struct phy_devic - return ret; - } - -- return 0; -+ if (of_property_read_u32(node, "motorcomm,clk-out-frequency-hz", &freq)) -+ freq = YTPHY_DTS_OUTPUT_CLK_DIS; -+ -+ if (phydev->drv->phy_id == PHY_ID_YT8521) { -+ switch (freq) { -+ case YTPHY_DTS_OUTPUT_CLK_DIS: -+ mask = YT8521_SCR_SYNCE_ENABLE; -+ val = 0; -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_25M: -+ mask = YT8521_SCR_SYNCE_ENABLE | -+ YT8521_SCR_CLK_SRC_MASK | -+ YT8521_SCR_CLK_FRE_SEL_125M; -+ val = YT8521_SCR_SYNCE_ENABLE | -+ FIELD_PREP(YT8521_SCR_CLK_SRC_MASK, -+ YT8521_SCR_CLK_SRC_REF_25M); -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_125M: -+ mask = YT8521_SCR_SYNCE_ENABLE | -+ YT8521_SCR_CLK_SRC_MASK | -+ YT8521_SCR_CLK_FRE_SEL_125M; -+ val = YT8521_SCR_SYNCE_ENABLE | -+ YT8521_SCR_CLK_FRE_SEL_125M | -+ FIELD_PREP(YT8521_SCR_CLK_SRC_MASK, -+ YT8521_SCR_CLK_SRC_PLL_125M); -+ break; -+ default: -+ phydev_warn(phydev, "Freq err:%u\n", freq); -+ return -EINVAL; -+ } -+ } else if (phydev->drv->phy_id == PHY_ID_YT8531S) { -+ return 0; -+ } else { -+ phydev_warn(phydev, "PHY id err\n"); -+ return -EINVAL; -+ } -+ -+ return ytphy_modify_ext_with_lock(phydev, YTPHY_SYNCE_CFG_REG, mask, -+ val); - } - - /** -@@ -1180,61 +1350,36 @@ static int yt8521_resume(struct phy_devi - */ - static int yt8521_config_init(struct phy_device *phydev) - { -+ struct device_node *node = phydev->mdio.dev.of_node; - int old_page; - int ret = 0; -- u16 val; - - old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); - if (old_page < 0) - goto err_restore_page; - -- switch (phydev->interface) { -- case PHY_INTERFACE_MODE_RGMII: -- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; -- val |= YT8521_RC1R_RX_DELAY_DIS; -- break; -- case PHY_INTERFACE_MODE_RGMII_RXID: -- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; -- val |= YT8521_RC1R_RX_DELAY_EN; -- break; -- case PHY_INTERFACE_MODE_RGMII_TXID: -- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; -- val |= YT8521_RC1R_RX_DELAY_DIS; -- break; -- case PHY_INTERFACE_MODE_RGMII_ID: -- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; -- val |= YT8521_RC1R_RX_DELAY_EN; -- break; -- case PHY_INTERFACE_MODE_SGMII: -- break; -- default: /* do not support other modes */ -- ret = -EOPNOTSUPP; -- goto err_restore_page; -- } -- - /* set rgmii delay mode */ - if (phydev->interface != PHY_INTERFACE_MODE_SGMII) { -- ret = ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, -- (YT8521_RC1R_RX_DELAY_MASK | -- YT8521_RC1R_FE_TX_DELAY_MASK | -- YT8521_RC1R_GE_TX_DELAY_MASK), -- val); -+ ret = ytphy_rgmii_clk_delay_config(phydev); - if (ret < 0) - goto err_restore_page; - } - -- /* disable auto sleep */ -- ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG, -- YT8521_ESC1R_SLEEP_SW, 0); -- if (ret < 0) -- goto err_restore_page; -- -- /* enable RXC clock when no wire plug */ -- ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG, -- YT8521_CGR_RX_CLK_EN, 0); -- if (ret < 0) -- goto err_restore_page; -+ if (of_property_read_bool(node, "motorcomm,auto-sleep-disabled")) { -+ /* disable auto sleep */ -+ ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG, -+ YT8521_ESC1R_SLEEP_SW, 0); -+ if (ret < 0) -+ goto err_restore_page; -+ } - -+ if (of_property_read_bool(node, "motorcomm,keep-pll-enabled")) { -+ /* enable RXC clock when no wire plug */ -+ ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG, -+ YT8521_CGR_RX_CLK_EN, 0); -+ if (ret < 0) -+ goto err_restore_page; -+ } - err_restore_page: - return phy_restore_page(phydev, old_page, ret); - } diff --git a/target/linux/generic/backport-5.15/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch b/target/linux/generic/backport-5.15/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch deleted file mode 100644 index 86fc04695c8ec2..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 36152f87dda4af221b16258751451d9cd3d0fb0b Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Thu, 2 Feb 2023 11:00:36 +0800 -Subject: [PATCH] net: phy: Add dts support for Motorcomm yt8531s gigabit - ethernet phy - -Add dts support for Motorcomm yt8531s gigabit ethernet phy. - Change yt8521_probe to support clk config of yt8531s. Becase - yt8521_probe does the things which yt8531s is needed, so - removed yt8531s function. - This patch has been verified on AM335x platform with yt8531s board. - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/motorcomm.c | 51 ++++++++++++++++++++----------------- - 1 file changed, 27 insertions(+), 24 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -258,8 +258,6 @@ - #define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3 - #define YT8531_SCR_CLK_SRC_REF_25M 4 - #define YT8531_SCR_CLK_SRC_SSC_25M 5 --#define YT8531S_SYNCE_CFG_REG 0xA012 --#define YT8531S_SCR_SYNCE_ENABLE BIT(6) - - /* Extended Register end */ - -@@ -858,7 +856,32 @@ static int yt8521_probe(struct phy_devic - return -EINVAL; - } - } else if (phydev->drv->phy_id == PHY_ID_YT8531S) { -- return 0; -+ switch (freq) { -+ case YTPHY_DTS_OUTPUT_CLK_DIS: -+ mask = YT8531_SCR_SYNCE_ENABLE; -+ val = 0; -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_25M: -+ mask = YT8531_SCR_SYNCE_ENABLE | -+ YT8531_SCR_CLK_SRC_MASK | -+ YT8531_SCR_CLK_FRE_SEL_125M; -+ val = YT8531_SCR_SYNCE_ENABLE | -+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK, -+ YT8531_SCR_CLK_SRC_REF_25M); -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_125M: -+ mask = YT8531_SCR_SYNCE_ENABLE | -+ YT8531_SCR_CLK_SRC_MASK | -+ YT8531_SCR_CLK_FRE_SEL_125M; -+ val = YT8531_SCR_SYNCE_ENABLE | -+ YT8531_SCR_CLK_FRE_SEL_125M | -+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK, -+ YT8531_SCR_CLK_SRC_PLL_125M); -+ break; -+ default: -+ phydev_warn(phydev, "Freq err:%u\n", freq); -+ return -EINVAL; -+ } - } else { - phydev_warn(phydev, "PHY id err\n"); - return -EINVAL; -@@ -869,26 +892,6 @@ static int yt8521_probe(struct phy_devic - } - - /** -- * yt8531s_probe() - read chip config then set suitable polling_mode -- * @phydev: a pointer to a &struct phy_device -- * -- * returns 0 or negative errno code -- */ --static int yt8531s_probe(struct phy_device *phydev) --{ -- int ret; -- -- /* Disable SyncE clock output by default */ -- ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG, -- YT8531S_SCR_SYNCE_ENABLE, 0); -- if (ret < 0) -- return ret; -- -- /* same as yt8521_probe */ -- return yt8521_probe(phydev); --} -- --/** - * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp - * @phydev: a pointer to a &struct phy_device - * -@@ -1970,7 +1973,7 @@ static struct phy_driver motorcomm_phy_d - PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), - .name = "YT8531S Gigabit Ethernet", - .get_features = yt8521_get_features, -- .probe = yt8531s_probe, -+ .probe = yt8521_probe, - .read_page = yt8521_read_page, - .write_page = yt8521_write_page, - .get_wol = ytphy_get_wol, diff --git a/target/linux/generic/backport-5.15/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch b/target/linux/generic/backport-5.15/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch deleted file mode 100644 index a8b9e3d13b0041..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch +++ /dev/null @@ -1,302 +0,0 @@ -From 4ac94f728a588e7096dd5010cd7141a309ea7805 Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Thu, 2 Feb 2023 11:00:37 +0800 -Subject: [PATCH] net: phy: Add driver for Motorcomm yt8531 gigabit ethernet - phy - -Add a driver for the motorcomm yt8531 gigabit ethernet phy. We have - verified the driver on AM335x platform with yt8531 board. On the - board, yt8531 gigabit ethernet phy works in utp mode, RGMII - interface, supports 1000M/100M/10M speeds, and wol(magic package). - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/Kconfig | 2 +- - drivers/net/phy/motorcomm.c | 208 +++++++++++++++++++++++++++++++++++- - 2 files changed, 207 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -242,7 +242,7 @@ config MOTORCOMM_PHY - tristate "Motorcomm PHYs" - help - Enables support for Motorcomm network PHYs. -- Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs. -+ Currently supports YT85xx Gigabit Ethernet PHYs. - - config NATIONAL_PHY - tristate "National Semiconductor PHYs" ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* -- * Motorcomm 8511/8521/8531S PHY driver. -+ * Motorcomm 8511/8521/8531/8531S PHY driver. - * - * Author: Peter Geis - * Author: Frank -@@ -14,6 +14,7 @@ - - #define PHY_ID_YT8511 0x0000010a - #define PHY_ID_YT8521 0x0000011a -+#define PHY_ID_YT8531 0x4f51e91b - #define PHY_ID_YT8531S 0x4f51e91a - - /* YT8521/YT8531S Register Overview -@@ -517,6 +518,61 @@ err_restore_page: - return phy_restore_page(phydev, old_page, ret); - } - -+static int yt8531_set_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol) -+{ -+ const u16 mac_addr_reg[] = { -+ YTPHY_WOL_MACADDR2_REG, -+ YTPHY_WOL_MACADDR1_REG, -+ YTPHY_WOL_MACADDR0_REG, -+ }; -+ const u8 *mac_addr; -+ u16 mask, val; -+ int ret; -+ u8 i; -+ -+ if (wol->wolopts & WAKE_MAGIC) { -+ mac_addr = phydev->attached_dev->dev_addr; -+ -+ /* Store the device address for the magic packet */ -+ for (i = 0; i < 3; i++) { -+ ret = ytphy_write_ext_with_lock(phydev, mac_addr_reg[i], -+ ((mac_addr[i * 2] << 8)) | -+ (mac_addr[i * 2 + 1])); -+ if (ret < 0) -+ return ret; -+ } -+ -+ /* Enable WOL feature */ -+ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL; -+ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; -+ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS; -+ ret = ytphy_modify_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG, -+ mask, val); -+ if (ret < 0) -+ return ret; -+ -+ /* Enable WOL interrupt */ -+ ret = phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0, -+ YTPHY_IER_WOL); -+ if (ret < 0) -+ return ret; -+ } else { -+ /* Disable WOL feature */ -+ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; -+ ret = ytphy_modify_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG, -+ mask, 0); -+ -+ /* Disable WOL interrupt */ -+ ret = phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, -+ YTPHY_IER_WOL, 0); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ - static int yt8511_read_page(struct phy_device *phydev) - { - return __phy_read(phydev, YT8511_PAGE_SELECT); -@@ -767,6 +823,17 @@ static int ytphy_rgmii_clk_delay_config( - return ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, mask, val); - } - -+static int ytphy_rgmii_clk_delay_config_with_lock(struct phy_device *phydev) -+{ -+ int ret; -+ -+ phy_lock_mdio_bus(phydev); -+ ret = ytphy_rgmii_clk_delay_config(phydev); -+ phy_unlock_mdio_bus(phydev); -+ -+ return ret; -+} -+ - /** - * yt8521_probe() - read chip config then set suitable polling_mode - * @phydev: a pointer to a &struct phy_device -@@ -891,6 +958,43 @@ static int yt8521_probe(struct phy_devic - val); - } - -+static int yt8531_probe(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ u16 mask, val; -+ u32 freq; -+ -+ if (of_property_read_u32(node, "motorcomm,clk-out-frequency-hz", &freq)) -+ freq = YTPHY_DTS_OUTPUT_CLK_DIS; -+ -+ switch (freq) { -+ case YTPHY_DTS_OUTPUT_CLK_DIS: -+ mask = YT8531_SCR_SYNCE_ENABLE; -+ val = 0; -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_25M: -+ mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK | -+ YT8531_SCR_CLK_FRE_SEL_125M; -+ val = YT8531_SCR_SYNCE_ENABLE | -+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK, -+ YT8531_SCR_CLK_SRC_REF_25M); -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_125M: -+ mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK | -+ YT8531_SCR_CLK_FRE_SEL_125M; -+ val = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_FRE_SEL_125M | -+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK, -+ YT8531_SCR_CLK_SRC_PLL_125M); -+ break; -+ default: -+ phydev_warn(phydev, "Freq err:%u\n", freq); -+ return -EINVAL; -+ } -+ -+ return ytphy_modify_ext_with_lock(phydev, YTPHY_SYNCE_CFG_REG, mask, -+ val); -+} -+ - /** - * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp - * @phydev: a pointer to a &struct phy_device -@@ -1387,6 +1491,94 @@ err_restore_page: - return phy_restore_page(phydev, old_page, ret); - } - -+static int yt8531_config_init(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ int ret; -+ -+ ret = ytphy_rgmii_clk_delay_config_with_lock(phydev); -+ if (ret < 0) -+ return ret; -+ -+ if (of_property_read_bool(node, "motorcomm,auto-sleep-disabled")) { -+ /* disable auto sleep */ -+ ret = ytphy_modify_ext_with_lock(phydev, -+ YT8521_EXTREG_SLEEP_CONTROL1_REG, -+ YT8521_ESC1R_SLEEP_SW, 0); -+ if (ret < 0) -+ return ret; -+ } -+ -+ if (of_property_read_bool(node, "motorcomm,keep-pll-enabled")) { -+ /* enable RXC clock when no wire plug */ -+ ret = ytphy_modify_ext_with_lock(phydev, -+ YT8521_CLOCK_GATING_REG, -+ YT8521_CGR_RX_CLK_EN, 0); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/** -+ * yt8531_link_change_notify() - Adjust the tx clock direction according to -+ * the current speed and dts config. -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * NOTE: This function is only used to adapt to VF2 with JH7110 SoC. Please -+ * keep "motorcomm,tx-clk-adj-enabled" not exist in dts when the soc is not -+ * JH7110. -+ */ -+static void yt8531_link_change_notify(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ bool tx_clk_adj_enabled = false; -+ bool tx_clk_1000_inverted; -+ bool tx_clk_100_inverted; -+ bool tx_clk_10_inverted; -+ u16 val = 0; -+ int ret; -+ -+ if (of_property_read_bool(node, "motorcomm,tx-clk-adj-enabled")) -+ tx_clk_adj_enabled = true; -+ -+ if (!tx_clk_adj_enabled) -+ return; -+ -+ if (of_property_read_bool(node, "motorcomm,tx-clk-10-inverted")) -+ tx_clk_10_inverted = true; -+ if (of_property_read_bool(node, "motorcomm,tx-clk-100-inverted")) -+ tx_clk_100_inverted = true; -+ if (of_property_read_bool(node, "motorcomm,tx-clk-1000-inverted")) -+ tx_clk_1000_inverted = true; -+ -+ if (phydev->speed < 0) -+ return; -+ -+ switch (phydev->speed) { -+ case SPEED_1000: -+ if (tx_clk_1000_inverted) -+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED; -+ break; -+ case SPEED_100: -+ if (tx_clk_100_inverted) -+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED; -+ break; -+ case SPEED_10: -+ if (tx_clk_10_inverted) -+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED; -+ break; -+ default: -+ return; -+ } -+ -+ ret = ytphy_modify_ext_with_lock(phydev, YT8521_RGMII_CONFIG1_REG, -+ YT8521_RC1R_TX_CLK_SEL_INVERTED, val); -+ if (ret < 0) -+ phydev_warn(phydev, "Modify TX_CLK_SEL err:%d\n", ret); -+} -+ - /** - * yt8521_prepare_fiber_features() - A small helper function that setup - * fiber's features. -@@ -1970,6 +2162,17 @@ static struct phy_driver motorcomm_phy_d - .resume = yt8521_resume, - }, - { -+ PHY_ID_MATCH_EXACT(PHY_ID_YT8531), -+ .name = "YT8531 Gigabit Ethernet", -+ .probe = yt8531_probe, -+ .config_init = yt8531_config_init, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .get_wol = ytphy_get_wol, -+ .set_wol = yt8531_set_wol, -+ .link_change_notify = yt8531_link_change_notify, -+ }, -+ { - PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), - .name = "YT8531S Gigabit Ethernet", - .get_features = yt8521_get_features, -@@ -1990,7 +2193,7 @@ static struct phy_driver motorcomm_phy_d - - module_phy_driver(motorcomm_phy_drvs); - --MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver"); -+MODULE_DESCRIPTION("Motorcomm 8511/8521/8531/8531S PHY driver"); - MODULE_AUTHOR("Peter Geis"); - MODULE_AUTHOR("Frank"); - MODULE_LICENSE("GPL"); -@@ -1998,6 +2201,7 @@ MODULE_LICENSE("GPL"); - static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { - { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, - { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, -+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8531) }, - { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, - { /* sentinel */ } - }; diff --git a/target/linux/generic/backport-5.15/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch b/target/linux/generic/backport-5.15/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch deleted file mode 100644 index 29ae86dbbc2c0c..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 9753613f7399601f9bae6ee81e9d4274246c98ab Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Wed, 15 Feb 2023 07:21:47 +0300 -Subject: [PATCH] net: phy: motorcomm: uninitialized variables in - yt8531_link_change_notify() - -These booleans are never set to false, but are just used without being -initialized. - -Fixes: 4ac94f728a58 ("net: phy: Add driver for Motorcomm yt8531 gigabit ethernet phy") -Signed-off-by: Dan Carpenter -Reviewed-by: Frank Sae -Link: https://lore.kernel.org/r/Y+xd2yJet2ImHLoQ@kili -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/motorcomm.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1533,10 +1533,10 @@ static int yt8531_config_init(struct phy - static void yt8531_link_change_notify(struct phy_device *phydev) - { - struct device_node *node = phydev->mdio.dev.of_node; -+ bool tx_clk_1000_inverted = false; -+ bool tx_clk_100_inverted = false; -+ bool tx_clk_10_inverted = false; - bool tx_clk_adj_enabled = false; -- bool tx_clk_1000_inverted; -- bool tx_clk_100_inverted; -- bool tx_clk_10_inverted; - u16 val = 0; - int ret; - diff --git a/target/linux/generic/backport-5.15/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch b/target/linux/generic/backport-5.15/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch deleted file mode 100644 index 010ca9b68aac75..00000000000000 --- a/target/linux/generic/backport-5.15/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 7a561e9351ae7e3fb1f08584d40b49c1e55dde60 Mon Sep 17 00:00:00 2001 -From: Samin Guo -Date: Thu, 20 Jul 2023 19:15:09 +0800 -Subject: [PATCH] net: phy: motorcomm: Add pad drive strength cfg support - -The motorcomm phy (YT8531) supports the ability to adjust the drive -strength of the rx_clk/rx_data, and the default strength may not be -suitable for all boards. So add configurable options to better match -the boards.(e.g. StarFive VisionFive 2) - -When we configure the drive strength, we need to read the current -LDO voltage value to ensure that it is a legal value at that LDO -voltage. - -Reviewed-by: Hal Feng -Signed-off-by: Samin Guo -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/motorcomm.c | 118 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 118 insertions(+) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -163,6 +163,10 @@ - - #define YT8521_CHIP_CONFIG_REG 0xA001 - #define YT8521_CCR_SW_RST BIT(15) -+#define YT8531_RGMII_LDO_VOL_MASK GENMASK(5, 4) -+#define YT8531_LDO_VOL_3V3 0x0 -+#define YT8531_LDO_VOL_1V8 0x2 -+ - /* 1b0 disable 1.9ns rxc clock delay *default* - * 1b1 enable 1.9ns rxc clock delay - */ -@@ -236,6 +240,12 @@ - */ - #define YTPHY_WCR_TYPE_PULSE BIT(0) - -+#define YTPHY_PAD_DRIVE_STRENGTH_REG 0xA010 -+#define YT8531_RGMII_RXC_DS_MASK GENMASK(15, 13) -+#define YT8531_RGMII_RXD_DS_HI_MASK BIT(12) /* Bit 2 of rxd_ds */ -+#define YT8531_RGMII_RXD_DS_LOW_MASK GENMASK(5, 4) /* Bit 1/0 of rxd_ds */ -+#define YT8531_RGMII_RX_DS_DEFAULT 0x3 -+ - #define YTPHY_SYNCE_CFG_REG 0xA012 - #define YT8521_SCR_SYNCE_ENABLE BIT(5) - /* 1b0 output 25m clock -@@ -835,6 +845,110 @@ static int ytphy_rgmii_clk_delay_config_ - } - - /** -+ * struct ytphy_ldo_vol_map - map a current value to a register value -+ * @vol: ldo voltage -+ * @ds: value in the register -+ * @cur: value in device configuration -+ */ -+struct ytphy_ldo_vol_map { -+ u32 vol; -+ u32 ds; -+ u32 cur; -+}; -+ -+static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = { -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 0, .cur = 1200}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 1, .cur = 2100}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 2, .cur = 2700}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 3, .cur = 2910}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 4, .cur = 3110}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 5, .cur = 3600}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 6, .cur = 3970}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 7, .cur = 4350}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 0, .cur = 3070}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 1, .cur = 4080}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 2, .cur = 4370}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 3, .cur = 4680}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 4, .cur = 5020}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 5, .cur = 5450}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 6, .cur = 5740}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 7, .cur = 6140}, -+}; -+ -+static u32 yt8531_get_ldo_vol(struct phy_device *phydev) -+{ -+ u32 val; -+ -+ val = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG); -+ val = FIELD_GET(YT8531_RGMII_LDO_VOL_MASK, val); -+ -+ return val <= YT8531_LDO_VOL_1V8 ? val : YT8531_LDO_VOL_1V8; -+} -+ -+static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur) -+{ -+ u32 vol; -+ int i; -+ -+ vol = yt8531_get_ldo_vol(phydev); -+ for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) { -+ if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur) -+ return yt8531_ldo_vol[i].ds; -+ } -+ -+ return -EINVAL; -+} -+ -+static int yt8531_set_ds(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ u32 ds_field_low, ds_field_hi, val; -+ int ret, ds; -+ -+ /* set rgmii rx clk driver strength */ -+ if (!of_property_read_u32(node, "motorcomm,rx-clk-drv-microamp", &val)) { -+ ds = yt8531_get_ds_map(phydev, val); -+ if (ds < 0) -+ return dev_err_probe(&phydev->mdio.dev, ds, -+ "No matching current value was found.\n"); -+ } else { -+ ds = YT8531_RGMII_RX_DS_DEFAULT; -+ } -+ -+ ret = ytphy_modify_ext_with_lock(phydev, -+ YTPHY_PAD_DRIVE_STRENGTH_REG, -+ YT8531_RGMII_RXC_DS_MASK, -+ FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds)); -+ if (ret < 0) -+ return ret; -+ -+ /* set rgmii rx data driver strength */ -+ if (!of_property_read_u32(node, "motorcomm,rx-data-drv-microamp", &val)) { -+ ds = yt8531_get_ds_map(phydev, val); -+ if (ds < 0) -+ return dev_err_probe(&phydev->mdio.dev, ds, -+ "No matching current value was found.\n"); -+ } else { -+ ds = YT8531_RGMII_RX_DS_DEFAULT; -+ } -+ -+ ds_field_hi = FIELD_GET(BIT(2), ds); -+ ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi); -+ -+ ds_field_low = FIELD_GET(GENMASK(1, 0), ds); -+ ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low); -+ -+ ret = ytphy_modify_ext_with_lock(phydev, -+ YTPHY_PAD_DRIVE_STRENGTH_REG, -+ YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK, -+ ds_field_low | ds_field_hi); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+/** - * yt8521_probe() - read chip config then set suitable polling_mode - * @phydev: a pointer to a &struct phy_device - * -@@ -1518,6 +1632,10 @@ static int yt8531_config_init(struct phy - return ret; - } - -+ ret = yt8531_set_ds(phydev); -+ if (ret < 0) -+ return ret; -+ - return 0; - } - diff --git a/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch b/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch deleted file mode 100644 index a0cb367ba7de45..00000000000000 --- a/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch +++ /dev/null @@ -1,81 +0,0 @@ -From bfac8c490d605bea03b1f1927582b6f396462164 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 27 Jun 2022 12:44:43 +0100 -Subject: [PATCH] net: phylink: disable PCS polling over major configuration - -While we are performing a major configuration, there is no point having -the PCS polling timer running. Stop it before we begin preparing for -the configuration change, and restart it only once we've successfully -completed the change. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 30 ++++++++++++++++++++---------- - 1 file changed, 20 insertions(+), 10 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -759,6 +759,18 @@ static void phylink_resolve_flow(struct - } - } - -+static void phylink_pcs_poll_stop(struct phylink *pl) -+{ -+ if (pl->cfg_link_an_mode == MLO_AN_INBAND) -+ del_timer(&pl->link_poll); -+} -+ -+static void phylink_pcs_poll_start(struct phylink *pl) -+{ -+ if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) -+ mod_timer(&pl->link_poll, jiffies + HZ); -+} -+ - static void phylink_mac_config(struct phylink *pl, - const struct phylink_link_state *state) - { -@@ -790,6 +802,7 @@ static void phylink_major_config(struct - const struct phylink_link_state *state) - { - struct phylink_pcs *pcs = NULL; -+ bool pcs_changed = false; - int err; - - phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); -@@ -802,8 +815,12 @@ static void phylink_major_config(struct - pcs); - return; - } -+ -+ pcs_changed = pcs && pl->pcs != pcs; - } - -+ phylink_pcs_poll_stop(pl); -+ - if (pl->mac_ops->mac_prepare) { - err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode, - state->interface); -@@ -817,8 +834,10 @@ static void phylink_major_config(struct - /* If we have a new PCS, switch to the new PCS after preparing the MAC - * for the change. - */ -- if (pcs) -- phylink_set_pcs(pl, pcs); -+ if (pcs_changed) { -+ pl->pcs = pcs; -+ pl->pcs_ops = pcs->ops; -+ } - - phylink_mac_config(pl, state); - -@@ -844,6 +863,8 @@ static void phylink_major_config(struct - phylink_err(pl, "mac_finish failed: %pe\n", - ERR_PTR(err)); - } -+ -+ phylink_pcs_poll_start(pl); - } - - /* diff --git a/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch b/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch deleted file mode 100644 index fec2fddfda85e2..00000000000000 --- a/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch +++ /dev/null @@ -1,38 +0,0 @@ -From b7d78b46d5e8dc77c656c13885d31e931923b915 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Wed, 29 Jun 2022 22:33:58 +0300 -Subject: [PATCH] net: phylink: fix NULL pl->pcs dereference during - phylink_pcs_poll_start - -The current link mode of the phylink instance may not require an -attached PCS. However, phylink_major_config() unconditionally -dereferences this potentially NULL pointer when restarting the link poll -timer, which will panic the kernel. - -Fix the problem by checking whether a PCS exists in phylink_pcs_poll_start(), -otherwise do nothing. The code prior to the blamed patch also only -looked at pcs->poll within an "if (pcs)" block. - -Fixes: bfac8c490d60 ("net: phylink: disable PCS polling over major configuration") -Signed-off-by: Vladimir Oltean -Reviewed-by: Russell King (Oracle) -Tested-by: Gerhard Engleder -Tested-by: Michael Walle # on kontron-kbox-a-230-ls -Tested-by: Nicolas Ferre # on sam9x60ek -Link: https://lore.kernel.org/r/20220629193358.4007923-1-vladimir.oltean@nxp.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -767,7 +767,7 @@ static void phylink_pcs_poll_stop(struct - - static void phylink_pcs_poll_start(struct phylink *pl) - { -- if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) -+ if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND) - mod_timer(&pl->link_poll, jiffies + HZ); - } - diff --git a/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch b/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch deleted file mode 100644 index 71b09cbe7592ee..00000000000000 --- a/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 90ef0a7b0622c62758b2638604927867775479ea Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 13 Jul 2023 09:42:07 +0100 -Subject: [PATCH] net: phylink: add pcs_enable()/pcs_disable() methods - -Add phylink PCS enable/disable callbacks that will allow us to place -IEEE 802.3 register compliant PCS in power-down mode while not being -used. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/phylink.c | 48 +++++++++++++++++++++++++++++++-------- - include/linux/phylink.h | 16 +++++++++++++ - 2 files changed, 55 insertions(+), 9 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -34,6 +34,10 @@ enum { - PHYLINK_DISABLE_STOPPED, - PHYLINK_DISABLE_LINK, - PHYLINK_DISABLE_MAC_WOL, -+ -+ PCS_STATE_DOWN = 0, -+ PCS_STATE_STARTING, -+ PCS_STATE_STARTED, - }; - - /** -@@ -72,6 +76,7 @@ struct phylink { - struct mutex state_mutex; - struct phylink_link_state phy_state; - struct work_struct resolve; -+ unsigned int pcs_state; - - bool mac_link_dropped; - bool using_mac_select_pcs; -@@ -798,6 +803,22 @@ static void phylink_mac_pcs_an_restart(s - } - } - -+static void phylink_pcs_disable(struct phylink_pcs *pcs) -+{ -+ if (pcs && pcs->ops->pcs_disable) -+ pcs->ops->pcs_disable(pcs); -+} -+ -+static int phylink_pcs_enable(struct phylink_pcs *pcs) -+{ -+ int err = 0; -+ -+ if (pcs && pcs->ops->pcs_enable) -+ err = pcs->ops->pcs_enable(pcs); -+ -+ return err; -+} -+ - static void phylink_major_config(struct phylink *pl, bool restart, - const struct phylink_link_state *state) - { -@@ -835,12 +856,16 @@ static void phylink_major_config(struct - * for the change. - */ - if (pcs_changed) { -+ phylink_pcs_disable(pl->pcs); - pl->pcs = pcs; - pl->pcs_ops = pcs->ops; - } - - phylink_mac_config(pl, state); - -+ if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) -+ phylink_pcs_enable(pl->pcs); -+ - if (pl->pcs_ops) { - err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode, - state->interface, -@@ -1264,6 +1289,7 @@ struct phylink *phylink_create(struct ph - pl->link_config.speed = SPEED_UNKNOWN; - pl->link_config.duplex = DUPLEX_UNKNOWN; - pl->link_config.an_enabled = true; -+ pl->pcs_state = PCS_STATE_DOWN; - pl->mac_ops = mac_ops; - __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); - timer_setup(&pl->link_poll, phylink_fixed_poll, 0); -@@ -1655,6 +1681,8 @@ void phylink_start(struct phylink *pl) - if (pl->netdev) - netif_carrier_off(pl->netdev); - -+ pl->pcs_state = PCS_STATE_STARTING; -+ - /* Apply the link configuration to the MAC when starting. This allows - * a fixed-link to start with the correct parameters, and also - * ensures that we set the appropriate advertisement for Serdes links. -@@ -1665,6 +1693,8 @@ void phylink_start(struct phylink *pl) - */ - phylink_mac_initial_config(pl, true); - -+ pl->pcs_state = PCS_STATE_STARTED; -+ - clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); - phylink_run_resolve(pl); - -@@ -1684,16 +1714,9 @@ void phylink_start(struct phylink *pl) - poll = true; - } - -- switch (pl->cfg_link_an_mode) { -- case MLO_AN_FIXED: -+ if (pl->cfg_link_an_mode == MLO_AN_FIXED) - poll |= pl->config->poll_fixed_state; -- break; -- case MLO_AN_INBAND: -- poll |= pl->config->pcs_poll; -- if (pl->pcs) -- poll |= pl->pcs->poll; -- break; -- } -+ - if (poll) - mod_timer(&pl->link_poll, jiffies + HZ); - if (pl->phydev) -@@ -1730,6 +1753,10 @@ void phylink_stop(struct phylink *pl) - } - - phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED); -+ -+ pl->pcs_state = PCS_STATE_DOWN; -+ -+ phylink_pcs_disable(pl->pcs); - } - EXPORT_SYMBOL_GPL(phylink_stop); - ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -419,6 +419,8 @@ struct phylink_pcs { - /** - * struct phylink_pcs_ops - MAC PCS operations structure. - * @pcs_validate: validate the link configuration. -+ * @pcs_enable: enable the PCS. -+ * @pcs_disable: disable the PCS. - * @pcs_get_state: read the current MAC PCS link state from the hardware. - * @pcs_config: configure the MAC PCS for the selected mode and state. - * @pcs_an_restart: restart 802.3z BaseX autonegotiation. -@@ -428,6 +430,8 @@ struct phylink_pcs { - struct phylink_pcs_ops { - int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported, - const struct phylink_link_state *state); -+ int (*pcs_enable)(struct phylink_pcs *pcs); -+ void (*pcs_disable)(struct phylink_pcs *pcs); - void (*pcs_get_state)(struct phylink_pcs *pcs, - struct phylink_link_state *state); - int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode, -@@ -458,6 +462,18 @@ int pcs_validate(struct phylink_pcs *pcs - const struct phylink_link_state *state); - - /** -+ * pcs_enable() - enable the PCS. -+ * @pcs: a pointer to a &struct phylink_pcs. -+ */ -+int pcs_enable(struct phylink_pcs *pcs); -+ -+/** -+ * pcs_disable() - disable the PCS. -+ * @pcs: a pointer to a &struct phylink_pcs. -+ */ -+void pcs_disable(struct phylink_pcs *pcs); -+ -+/** - * pcs_get_state() - Read the current inband link state from the hardware - * @pcs: a pointer to a &struct phylink_pcs. - * @state: a pointer to a &struct phylink_link_state. diff --git a/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch b/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch deleted file mode 100644 index eb9b4b7c09ee0d..00000000000000 --- a/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch +++ /dev/null @@ -1,44 +0,0 @@ -From e4ccdfb78a47132f2d215658aab8902fc457c4b4 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 18 Aug 2023 04:07:46 +0100 -Subject: [PATCH 082/125] net: pcs: lynxi: implement pcs_disable op - -When switching from 10GBase-R/5GBase-R/USXGMII to one of the interface -modes provided by mtk-pcs-lynxi we need to make sure to always perform -a full configuration of the PHYA. - -Implement pcs_disable op which resets the stored interface mode to -PHY_INTERFACE_MODE_NA to trigger a full reconfiguration once the LynxI -PCS driver had previously been deselected in favor of another PCS -driver such as the to-be-added driver for the USXGMII PCS found in -MT7988. - -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/f23d1a60d2c9d2fb72e32dcb0eaa5f7e867a3d68.1692327891.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/pcs/pcs-mtk-lynxi.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/net/pcs/pcs-mtk-lynxi.c -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -241,11 +241,19 @@ static void mtk_pcs_lynxi_link_up(struct - } - } - -+static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ -+ mpcs->interface = PHY_INTERFACE_MODE_NA; -+} -+ - static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { - .pcs_get_state = mtk_pcs_lynxi_get_state, - .pcs_config = mtk_pcs_lynxi_config, - .pcs_an_restart = mtk_pcs_lynxi_restart_an, - .pcs_link_up = mtk_pcs_lynxi_link_up, -+ .pcs_disable = mtk_pcs_lynxi_disable, - }; - - struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, diff --git a/target/linux/generic/backport-5.15/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch b/target/linux/generic/backport-5.15/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch deleted file mode 100644 index b0860db2669bf3..00000000000000 --- a/target/linux/generic/backport-5.15/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch +++ /dev/null @@ -1,136 +0,0 @@ -From: Andy Ren -Date: Mon, 7 Nov 2022 09:42:42 -0800 -Subject: [PATCH] net/core: Allow live renaming when an interface is up - -Allow a network interface to be renamed when the interface -is up. - -As described in the netconsole documentation [1], when netconsole is -used as a built-in, it will bring up the specified interface as soon as -possible. As a result, user space will not be able to rename the -interface since the kernel disallows renaming of interfaces that are -administratively up unless the 'IFF_LIVE_RENAME_OK' private flag was set -by the kernel. - -The original solution [2] to this problem was to add a new parameter to -the netconsole configuration parameters that allows renaming of -the interface used by netconsole while it is administratively up. -However, during the discussion that followed, it became apparent that we -have no reason to keep the current restriction and instead we should -allow user space to rename interfaces regardless of their administrative -state: - -1. The restriction was put in place over 20 years ago when renaming was -only possible via IOCTL and before rtnetlink started notifying user -space about such changes like it does today. - -2. The 'IFF_LIVE_RENAME_OK' flag was added over 3 years ago in version -5.2 and no regressions were reported. - -3. In-kernel listeners to 'NETDEV_CHANGENAME' do not seem to care about -the administrative state of interface. - -Therefore, allow user space to rename running interfaces by removing the -restriction and the associated 'IFF_LIVE_RENAME_OK' flag. Help in -possible triage by emitting a message to the kernel log that an -interface was renamed while UP. - -[1] https://www.kernel.org/doc/Documentation/networking/netconsole.rst -[2] https://lore.kernel.org/netdev/20221102002420.2613004-1-andy.ren@getcruise.com/ - -Signed-off-by: Andy Ren -Reviewed-by: Ido Schimmel -Reviewed-by: David Ahern -Signed-off-by: David S. Miller ---- - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1643,7 +1643,6 @@ struct net_device_ops { - * @IFF_FAILOVER: device is a failover master device - * @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device - * @IFF_L3MDEV_RX_HANDLER: only invoke the rx handler of L3 master device -- * @IFF_LIVE_RENAME_OK: rename is allowed while device is up and running - * @IFF_TX_SKB_NO_LINEAR: device/driver is capable of xmitting frames with - * skb_headlen(skb) == 0 (data starts from frag0) - */ -@@ -1678,7 +1677,7 @@ enum netdev_priv_flags { - IFF_FAILOVER = 1<<27, - IFF_FAILOVER_SLAVE = 1<<28, - IFF_L3MDEV_RX_HANDLER = 1<<29, -- IFF_LIVE_RENAME_OK = 1<<30, -+ /* was IFF_LIVE_RENAME_OK */ - IFF_TX_SKB_NO_LINEAR = BIT_ULL(31), - }; - -@@ -1712,7 +1711,6 @@ enum netdev_priv_flags { - #define IFF_FAILOVER IFF_FAILOVER - #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE - #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER --#define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK - #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR - - /* Specifies the type of the struct net_device::ml_priv pointer */ ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -1242,22 +1242,6 @@ int dev_change_name(struct net_device *d - - net = dev_net(dev); - -- /* Some auto-enslaved devices e.g. failover slaves are -- * special, as userspace might rename the device after -- * the interface had been brought up and running since -- * the point kernel initiated auto-enslavement. Allow -- * live name change even when these slave devices are -- * up and running. -- * -- * Typically, users of these auto-enslaving devices -- * don't actually care about slave name change, as -- * they are supposed to operate on master interface -- * directly. -- */ -- if (dev->flags & IFF_UP && -- likely(!(dev->priv_flags & IFF_LIVE_RENAME_OK))) -- return -EBUSY; -- - down_write(&devnet_rename_sem); - - if (strncmp(newname, dev->name, IFNAMSIZ) == 0) { -@@ -1274,7 +1258,8 @@ int dev_change_name(struct net_device *d - } - - if (oldname[0] && !strchr(oldname, '%')) -- netdev_info(dev, "renamed from %s\n", oldname); -+ netdev_info(dev, "renamed from %s%s\n", oldname, -+ dev->flags & IFF_UP ? " (while UP)" : ""); - - old_assign_type = dev->name_assign_type; - dev->name_assign_type = NET_NAME_RENAMED; ---- a/net/core/failover.c -+++ b/net/core/failover.c -@@ -80,14 +80,14 @@ static int failover_slave_register(struc - goto err_upper_link; - } - -- slave_dev->priv_flags |= (IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK); -+ slave_dev->priv_flags |= IFF_FAILOVER_SLAVE; - - if (fops && fops->slave_register && - !fops->slave_register(slave_dev, failover_dev)) - return NOTIFY_OK; - - netdev_upper_dev_unlink(slave_dev, failover_dev); -- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK); -+ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE; - err_upper_link: - netdev_rx_handler_unregister(slave_dev); - done: -@@ -121,7 +121,7 @@ int failover_slave_unregister(struct net - - netdev_rx_handler_unregister(slave_dev); - netdev_upper_dev_unlink(slave_dev, failover_dev); -- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK); -+ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE; - - if (fops && fops->slave_unregister && - !fops->slave_unregister(slave_dev, failover_dev)) diff --git a/target/linux/generic/backport-5.15/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch b/target/linux/generic/backport-5.15/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch deleted file mode 100644 index 2b3272cebd0149..00000000000000 --- a/target/linux/generic/backport-5.15/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 69649ef8405320f81497f4757faac8234f61b167 Mon Sep 17 00:00:00 2001 -From: Bjørn Mork -Date: Fri, 6 Jan 2023 17:07:39 +0100 -Subject: [PATCH] cdc_ether: no need to blacklist any r8152 devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The r8152 driver does not need this anymore. - -Dropping blacklist entries adds optional support for these -devices in ECM mode. - -The 8153 devices are handled by the r8153_ecm driver when -in ECM mode, and must still be blacklisted here. - -Signed-off-by: Bjørn Mork -Signed-off-by: David S. Miller ---- - drivers/net/usb/cdc_ether.c | 114 ------------------------------------ - 1 file changed, 114 deletions(-) - ---- a/drivers/net/usb/cdc_ether.c -+++ b/drivers/net/usb/cdc_ether.c -@@ -767,13 +767,6 @@ static const struct usb_device_id produc - .driver_info = 0, - }, - --/* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- - /* Realtek RTL8153 Based USB 3.0 Ethernet Adapters */ - { - USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM, -@@ -781,119 +774,12 @@ static const struct usb_device_id produc - .driver_info = 0, - }, - --/* Samsung USB Ethernet Adapters */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, 0xa101, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --#if IS_ENABLED(CONFIG_USB_RTL8152) --/* Linksys USB3GIGV1 Ethernet Adapter */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, --#endif -- --/* Lenovo ThinkPad OneLink+ Dock (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3054, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* ThinkPad USB-C Dock (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* ThinkPad Thunderbolt 3 Dock (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3069, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* ThinkPad Thunderbolt 3 Dock Gen 2 (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3082, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Lenovo USB C to Ethernet Adapter (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x720c, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Lenovo USB-C Travel Hub (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7214, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- - /* Lenovo Powered USB-C Travel Hub (4X90S92381, based on Realtek RTL8153) */ - { - USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x721e, USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), - .driver_info = 0, - }, -- --/* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0xa387, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* NVIDIA Tegra USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(NVIDIA_VENDOR_ID, 0x09ff, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Microsoft Surface 2 dock (based on Realtek RTL8152) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07ab, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07c6, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153B) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x0927, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, - - /* Aquantia AQtion USB to 5GbE Controller (based on AQC111U) */ - { diff --git a/target/linux/generic/backport-5.15/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch b/target/linux/generic/backport-5.15/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch deleted file mode 100644 index 482c6c6f133b40..00000000000000 --- a/target/linux/generic/backport-5.15/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 02767440e1dda9861a11ca1dbe0f19a760b1d5c2 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Thu, 19 Jan 2023 15:40:43 +0800 -Subject: [PATCH] r8152: reduce the control transfer of rtl8152_get_version() - -Reduce the control transfer by moving calling rtl8152_get_version() in -rtl8152_probe(). This could prevent from calling rtl8152_get_version() -for unnecessary situations. For example, after setting config #2 for the -device, there are two interfaces and rtl8152_probe() may be called -twice. However, we don't need to call rtl8152_get_version() for this -situation. - -Signed-off-by: Hayes Wang -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -9602,20 +9602,21 @@ static int rtl8152_probe(struct usb_inte - const struct usb_device_id *id) - { - struct usb_device *udev = interface_to_usbdev(intf); -- u8 version = rtl8152_get_version(intf); - struct r8152 *tp; - struct net_device *netdev; -+ u8 version; - int ret; - -- if (version == RTL_VER_UNKNOWN) -- return -ENODEV; -- - if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) - return -ENODEV; - - if (!rtl_check_vendor_ok(intf)) - return -ENODEV; - -+ version = rtl8152_get_version(intf); -+ if (version == RTL_VER_UNKNOWN) -+ return -ENODEV; -+ - usb_reset_device(udev); - netdev = alloc_etherdev(sizeof(struct r8152)); - if (!netdev) { diff --git a/target/linux/generic/backport-5.15/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch b/target/linux/generic/backport-5.15/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch deleted file mode 100644 index 5d1dfe3aef17fd..00000000000000 --- a/target/linux/generic/backport-5.15/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 5cc33f139e11b893ff6dc60d8a0ae865a65521ac Mon Sep 17 00:00:00 2001 -From: Douglas Anderson -Date: Thu, 6 Apr 2023 17:14:26 -0700 -Subject: [PATCH] r8152: Add __GFP_NOWARN to big allocations - -When memory is a little tight on my system, it's pretty easy to see -warnings that look like this. - - ksoftirqd/0: page allocation failure: order:3, mode:0x40a20(GFP_ATOMIC|__GFP_COMP), nodemask=(null),cpuset=/,mems_allowed=0 - ... - Call trace: - dump_backtrace+0x0/0x1e8 - show_stack+0x20/0x2c - dump_stack_lvl+0x60/0x78 - dump_stack+0x18/0x38 - warn_alloc+0x104/0x174 - __alloc_pages+0x588/0x67c - alloc_rx_agg+0xa0/0x190 [r8152 ...] - r8152_poll+0x270/0x760 [r8152 ...] - __napi_poll+0x44/0x1ec - net_rx_action+0x100/0x300 - __do_softirq+0xec/0x38c - run_ksoftirqd+0x38/0xec - smpboot_thread_fn+0xb8/0x248 - kthread+0x134/0x154 - ret_from_fork+0x10/0x20 - -On a fragmented system it's normal that order 3 allocations will -sometimes fail, especially atomic ones. The driver handles these -failures fine and the WARN just creates spam in the logs for this -case. The __GFP_NOWARN flag is exactly for this situation, so add it -to the allocation. - -NOTE: my testing is on a 5.15 system, but there should be no reason -that this would be fundamentally different on a mainline kernel. - -Signed-off-by: Douglas Anderson -Acked-by: Hayes Wang -Link: https://lore.kernel.org/r/20230406171411.1.I84dbef45786af440fd269b71e9436a96a8e7a152@changeid -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -1944,7 +1944,7 @@ static struct rx_agg *alloc_rx_agg(struc - if (!rx_agg) - return NULL; - -- rx_agg->page = alloc_pages(mflags | __GFP_COMP, order); -+ rx_agg->page = alloc_pages(mflags | __GFP_COMP | __GFP_NOWARN, order); - if (!rx_agg->page) - goto free_rx; - diff --git a/target/linux/generic/backport-5.15/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch b/target/linux/generic/backport-5.15/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch deleted file mode 100644 index 0da1a5b7cf7797..00000000000000 --- a/target/linux/generic/backport-5.15/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 57df0fb9d511f91202114813e90128d65c0589f0 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Wed, 26 Jul 2023 11:08:07 +0800 -Subject: [PATCH] r8152: adjust generic_ocp_write function - -Reduce the control transfer if all bytes of first or the last DWORD are -written. - -The original method is to split the control transfer into three parts -(the first DWORD, middle continuous data, and the last DWORD). However, -they could be combined if whole bytes of the first DWORD or last DWORD -are written. That is, the first DWORD or the last DWORD could be combined -with the middle continuous data, if the byte_en is 0xff. - -Signed-off-by: Hayes Wang -Link: https://lore.kernel.org/r/20230726030808.9093-418-nic_swsd@realtek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 29 ++++++++++++++++++----------- - 1 file changed, 18 insertions(+), 11 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -1310,16 +1310,24 @@ static int generic_ocp_write(struct r815 - byteen_end = byteen & BYTE_EN_END_MASK; - - byen = byteen_start | (byteen_start << 4); -- ret = set_registers(tp, index, type | byen, 4, data); -- if (ret < 0) -- goto error1; -- -- index += 4; -- data += 4; -- size -= 4; - -- if (size) { -+ /* Split the first DWORD if the byte_en is not 0xff */ -+ if (byen != BYTE_EN_DWORD) { -+ ret = set_registers(tp, index, type | byen, 4, data); -+ if (ret < 0) -+ goto error1; -+ -+ index += 4; -+ data += 4; - size -= 4; -+ } -+ -+ if (size) { -+ byen = byteen_end | (byteen_end >> 4); -+ -+ /* Split the last DWORD if the byte_en is not 0xff */ -+ if (byen != BYTE_EN_DWORD) -+ size -= 4; - - while (size) { - if (size > limit) { -@@ -1346,10 +1354,9 @@ static int generic_ocp_write(struct r815 - } - } - -- byen = byteen_end | (byteen_end >> 4); -- ret = set_registers(tp, index, type | byen, 4, data); -- if (ret < 0) -- goto error1; -+ /* Set the last DWORD */ -+ if (byen != BYTE_EN_DWORD) -+ ret = set_registers(tp, index, type | byen, 4, data); - } - - error1: diff --git a/target/linux/generic/backport-5.15/795-v6.6-09-r8152-set-bp-in-bulk.patch b/target/linux/generic/backport-5.15/795-v6.6-09-r8152-set-bp-in-bulk.patch deleted file mode 100644 index 6c7efd7f2bcdb0..00000000000000 --- a/target/linux/generic/backport-5.15/795-v6.6-09-r8152-set-bp-in-bulk.patch +++ /dev/null @@ -1,129 +0,0 @@ -From e5c266a61186b462c388c53a3564c375e72f2244 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Wed, 26 Jul 2023 11:08:08 +0800 -Subject: [PATCH] r8152: set bp in bulk - -PLA_BP_0 ~ PLA_BP_15 (0xfc28 ~ 0xfc46) are continuous registers, so we -could combine the control transfers into one control transfer. - -Signed-off-by: Hayes Wang -Link: https://lore.kernel.org/r/20230726030808.9093-419-nic_swsd@realtek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 75 ++++++++++++++--------------------------- - 1 file changed, 25 insertions(+), 50 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -3983,29 +3983,10 @@ static void rtl_reset_bmu(struct r8152 * - /* Clear the bp to stop the firmware before loading a new one */ - static void rtl_clear_bp(struct r8152 *tp, u16 type) - { -- switch (tp->version) { -- case RTL_VER_01: -- case RTL_VER_02: -- case RTL_VER_07: -- break; -- case RTL_VER_03: -- case RTL_VER_04: -- case RTL_VER_05: -- case RTL_VER_06: -- ocp_write_byte(tp, type, PLA_BP_EN, 0); -- break; -- case RTL_VER_14: -- ocp_write_word(tp, type, USB_BP2_EN, 0); -+ u16 bp[16] = {0}; -+ u16 bp_num; - -- ocp_write_word(tp, type, USB_BP_8, 0); -- ocp_write_word(tp, type, USB_BP_9, 0); -- ocp_write_word(tp, type, USB_BP_10, 0); -- ocp_write_word(tp, type, USB_BP_11, 0); -- ocp_write_word(tp, type, USB_BP_12, 0); -- ocp_write_word(tp, type, USB_BP_13, 0); -- ocp_write_word(tp, type, USB_BP_14, 0); -- ocp_write_word(tp, type, USB_BP_15, 0); -- break; -+ switch (tp->version) { - case RTL_VER_08: - case RTL_VER_09: - case RTL_VER_10: -@@ -4013,32 +3994,31 @@ static void rtl_clear_bp(struct r8152 *t - case RTL_VER_12: - case RTL_VER_13: - case RTL_VER_15: -- default: - if (type == MCU_TYPE_USB) { - ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0); -- -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0); -- } else { -- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0); -+ bp_num = 16; -+ break; - } -+ fallthrough; -+ case RTL_VER_03: -+ case RTL_VER_04: -+ case RTL_VER_05: -+ case RTL_VER_06: -+ ocp_write_byte(tp, type, PLA_BP_EN, 0); -+ fallthrough; -+ case RTL_VER_01: -+ case RTL_VER_02: -+ case RTL_VER_07: -+ bp_num = 8; -+ break; -+ case RTL_VER_14: -+ default: -+ ocp_write_word(tp, type, USB_BP2_EN, 0); -+ bp_num = 16; - break; - } - -- ocp_write_word(tp, type, PLA_BP_0, 0); -- ocp_write_word(tp, type, PLA_BP_1, 0); -- ocp_write_word(tp, type, PLA_BP_2, 0); -- ocp_write_word(tp, type, PLA_BP_3, 0); -- ocp_write_word(tp, type, PLA_BP_4, 0); -- ocp_write_word(tp, type, PLA_BP_5, 0); -- ocp_write_word(tp, type, PLA_BP_6, 0); -- ocp_write_word(tp, type, PLA_BP_7, 0); -+ generic_ocp_write(tp, PLA_BP_0, BYTE_EN_DWORD, bp_num << 1, bp, type); - - /* wait 3 ms to make sure the firmware is stopped */ - usleep_range(3000, 6000); -@@ -5015,10 +4995,9 @@ static void rtl8152_fw_phy_nc_apply(stru - - static void rtl8152_fw_mac_apply(struct r8152 *tp, struct fw_mac *mac) - { -- u16 bp_en_addr, bp_index, type, bp_num, fw_ver_reg; -+ u16 bp_en_addr, type, fw_ver_reg; - u32 length; - u8 *data; -- int i; - - switch (__le32_to_cpu(mac->blk_hdr.type)) { - case RTL_FW_PLA: -@@ -5060,12 +5039,8 @@ static void rtl8152_fw_mac_apply(struct - ocp_write_word(tp, type, __le16_to_cpu(mac->bp_ba_addr), - __le16_to_cpu(mac->bp_ba_value)); - -- bp_index = __le16_to_cpu(mac->bp_start); -- bp_num = __le16_to_cpu(mac->bp_num); -- for (i = 0; i < bp_num; i++) { -- ocp_write_word(tp, type, bp_index, __le16_to_cpu(mac->bp[i])); -- bp_index += 2; -- } -+ generic_ocp_write(tp, __le16_to_cpu(mac->bp_start), BYTE_EN_DWORD, -+ __le16_to_cpu(mac->bp_num) << 1, mac->bp, type); - - bp_en_addr = __le16_to_cpu(mac->bp_en_addr); - if (bp_en_addr) diff --git a/target/linux/generic/backport-5.15/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch b/target/linux/generic/backport-5.15/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch deleted file mode 100644 index 3ef8f379119639..00000000000000 --- a/target/linux/generic/backport-5.15/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch +++ /dev/null @@ -1,398 +0,0 @@ -From d9962b0d42029bcb40fe3c38bce06d1870fa4df4 Mon Sep 17 00:00:00 2001 -From: Douglas Anderson -Date: Fri, 20 Oct 2023 14:06:59 -0700 -Subject: [PATCH] r8152: Block future register access if register access fails - -Even though the functions to read/write registers can fail, most of -the places in the r8152 driver that read/write register values don't -check error codes. The lack of error code checking is problematic in -at least two ways. - -The first problem is that the r8152 driver often uses code patterns -similar to this: - x = read_register() - x = x | SOME_BIT; - write_register(x); - -...with the above pattern, if the read_register() fails and returns -garbage then we'll end up trying to write modified garbage back to the -Realtek adapter. If the write_register() succeeds that's bad. Note -that as of commit f53a7ad18959 ("r8152: Set memory to all 0xFFs on -failed reg reads") the "garbage" returned by read_register() will at -least be consistent garbage, but it is still garbage. - -It turns out that this problem is very serious. Writing garbage to -some of the hardware registers on the Ethernet adapter can put the -adapter in such a bad state that it needs to be power cycled (fully -unplugged and plugged in again) before it can enumerate again. - -The second problem is that the r8152 driver generally has functions -that are long sequences of register writes. Assuming everything will -be OK if a random register write fails in the middle isn't a great -assumption. - -One might wonder if the above two problems are real. You could ask if -we would really have a successful write after a failed read. It turns -out that the answer appears to be "yes, this can happen". In fact, -we've seen at least two distinct failure modes where this happens. - -On a sc7180-trogdor Chromebook if you drop into kdb for a while and -then resume, you can see: -1. We get a "Tx timeout" -2. The "Tx timeout" queues up a USB reset. -3. In rtl8152_pre_reset() we try to reinit the hardware. -4. The first several (2-9) register accesses fail with a timeout, then - things recover. - -The above test case was actually fixed by the patch ("r8152: Increase -USB control msg timeout to 5000ms as per spec") but at least shows -that we really can see successful calls after failed ones. - -On a different (AMD) based Chromebook with a particular adapter, we -found that during reboot tests we'd also sometimes get a transitory -failure. In this case we saw -EPIPE being returned sometimes. Retrying -worked, but retrying is not always safe for all register accesses -since reading/writing some registers might have side effects (like -registers that clear on read). - -Let's fully lock out all register access if a register access fails. -When we do this, we'll try to queue up a USB reset and try to unlock -register access after the reset. This is slightly tricker than it -sounds since the r8152 driver has an optimized reset sequence that -only works reliably after probe happens. In order to handle this, we -avoid the optimized reset if probe didn't finish. Instead, we simply -retry the probe routine in this case. - -When locking out access, we'll use the existing infrastructure that -the driver was using when it detected we were unplugged. This keeps us -from getting stuck in delay loops in some parts of the driver. - -Signed-off-by: Douglas Anderson -Reviewed-by: Grant Grundler -Signed-off-by: David S. Miller ---- - drivers/net/usb/r8152.c | 207 ++++++++++++++++++++++++++++++++++------ - 1 file changed, 176 insertions(+), 31 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -772,6 +772,9 @@ enum rtl8152_flags { - SCHEDULE_TASKLET, - GREEN_ETHERNET, - RX_EPROTO, -+ IN_PRE_RESET, -+ PROBED_WITH_NO_ERRORS, -+ PROBE_SHOULD_RETRY, - }; - - #define DEVICE_ID_THINKPAD_ONELINK_PLUS_DOCK 0x3054 -@@ -949,6 +952,8 @@ struct r8152 { - u8 version; - u8 duplex; - u8 autoneg; -+ -+ unsigned int reg_access_reset_count; - }; - - /** -@@ -1196,6 +1201,96 @@ static unsigned int agg_buf_sz = 16384; - - #define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - sizeof(struct tx_desc)) - -+/* If register access fails then we block access and issue a reset. If this -+ * happens too many times in a row without a successful access then we stop -+ * trying to reset and just leave access blocked. -+ */ -+#define REGISTER_ACCESS_MAX_RESETS 3 -+ -+static void rtl_set_inaccessible(struct r8152 *tp) -+{ -+ set_bit(RTL8152_INACCESSIBLE, &tp->flags); -+ smp_mb__after_atomic(); -+} -+ -+static void rtl_set_accessible(struct r8152 *tp) -+{ -+ clear_bit(RTL8152_INACCESSIBLE, &tp->flags); -+ smp_mb__after_atomic(); -+} -+ -+static -+int r8152_control_msg(struct r8152 *tp, unsigned int pipe, __u8 request, -+ __u8 requesttype, __u16 value, __u16 index, void *data, -+ __u16 size, const char *msg_tag) -+{ -+ struct usb_device *udev = tp->udev; -+ int ret; -+ -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) -+ return -ENODEV; -+ -+ ret = usb_control_msg(udev, pipe, request, requesttype, -+ value, index, data, size, -+ USB_CTRL_GET_TIMEOUT); -+ -+ /* No need to issue a reset to report an error if the USB device got -+ * unplugged; just return immediately. -+ */ -+ if (ret == -ENODEV) -+ return ret; -+ -+ /* If the write was successful then we're done */ -+ if (ret >= 0) { -+ tp->reg_access_reset_count = 0; -+ return ret; -+ } -+ -+ dev_err(&udev->dev, -+ "Failed to %s %d bytes at %#06x/%#06x (%d)\n", -+ msg_tag, size, value, index, ret); -+ -+ /* Block all future register access until we reset. Much of the code -+ * in the driver doesn't check for errors. Notably, many parts of the -+ * driver do a read/modify/write of a register value without -+ * confirming that the read succeeded. Writing back modified garbage -+ * like this can fully wedge the adapter, requiring a power cycle. -+ */ -+ rtl_set_inaccessible(tp); -+ -+ /* If probe hasn't yet finished, then we'll request a retry of the -+ * whole probe routine if we get any control transfer errors. We -+ * never have to clear this bit since we free/reallocate the whole "tp" -+ * structure if we retry probe. -+ */ -+ if (!test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) { -+ set_bit(PROBE_SHOULD_RETRY, &tp->flags); -+ return ret; -+ } -+ -+ /* Failing to access registers in pre-reset is not surprising since we -+ * wouldn't be resetting if things were behaving normally. The register -+ * access we do in pre-reset isn't truly mandatory--we're just reusing -+ * the disable() function and trying to be nice by powering the -+ * adapter down before resetting it. Thus, if we're in pre-reset, -+ * we'll return right away and not try to queue up yet another reset. -+ * We know the post-reset is already coming. -+ */ -+ if (test_bit(IN_PRE_RESET, &tp->flags)) -+ return ret; -+ -+ if (tp->reg_access_reset_count < REGISTER_ACCESS_MAX_RESETS) { -+ usb_queue_reset_device(tp->intf); -+ tp->reg_access_reset_count++; -+ } else if (tp->reg_access_reset_count == REGISTER_ACCESS_MAX_RESETS) { -+ dev_err(&udev->dev, -+ "Tried to reset %d times; giving up.\n", -+ REGISTER_ACCESS_MAX_RESETS); -+ } -+ -+ return ret; -+} -+ - static - int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) - { -@@ -1206,9 +1301,10 @@ int get_registers(struct r8152 *tp, u16 - if (!tmp) - return -ENOMEM; - -- ret = usb_control_msg(tp->udev, tp->pipe_ctrl_in, -- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, -- value, index, tmp, size, USB_CTRL_GET_TIMEOUT); -+ ret = r8152_control_msg(tp, tp->pipe_ctrl_in, -+ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, -+ value, index, tmp, size, "read"); -+ - if (ret < 0) - memset(data, 0xff, size); - else -@@ -1229,9 +1325,9 @@ int set_registers(struct r8152 *tp, u16 - if (!tmp) - return -ENOMEM; - -- ret = usb_control_msg(tp->udev, tp->pipe_ctrl_out, -- RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, -- value, index, tmp, size, USB_CTRL_SET_TIMEOUT); -+ ret = r8152_control_msg(tp, tp->pipe_ctrl_out, -+ RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, -+ value, index, tmp, size, "write"); - - kfree(tmp); - -@@ -1240,10 +1336,8 @@ int set_registers(struct r8152 *tp, u16 - - static void rtl_set_unplug(struct r8152 *tp) - { -- if (tp->udev->state == USB_STATE_NOTATTACHED) { -- set_bit(RTL8152_INACCESSIBLE, &tp->flags); -- smp_mb__after_atomic(); -- } -+ if (tp->udev->state == USB_STATE_NOTATTACHED) -+ rtl_set_inaccessible(tp); - } - - static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, -@@ -8268,7 +8362,7 @@ static int rtl8152_pre_reset(struct usb_ - struct r8152 *tp = usb_get_intfdata(intf); - struct net_device *netdev; - -- if (!tp) -+ if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) - return 0; - - netdev = tp->netdev; -@@ -8283,7 +8377,9 @@ static int rtl8152_pre_reset(struct usb_ - napi_disable(&tp->napi); - if (netif_carrier_ok(netdev)) { - mutex_lock(&tp->control); -+ set_bit(IN_PRE_RESET, &tp->flags); - tp->rtl_ops.disable(tp); -+ clear_bit(IN_PRE_RESET, &tp->flags); - mutex_unlock(&tp->control); - } - -@@ -8296,9 +8392,11 @@ static int rtl8152_post_reset(struct usb - struct net_device *netdev; - struct sockaddr sa; - -- if (!tp) -+ if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) - return 0; - -+ rtl_set_accessible(tp); -+ - /* reset the MAC address in case of policy change */ - if (determine_ethernet_addr(tp, &sa) >= 0) { - rtnl_lock(); -@@ -9496,17 +9594,29 @@ static u8 __rtl_get_hw_ver(struct usb_de - __le32 *tmp; - u8 version; - int ret; -+ int i; - - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); - if (!tmp) - return 0; - -- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), -- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, -- PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), -- USB_CTRL_GET_TIMEOUT); -- if (ret > 0) -- ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK; -+ /* Retry up to 3 times in case there is a transitory error. We do this -+ * since retrying a read of the version is always safe and this -+ * function doesn't take advantage of r8152_control_msg(). -+ */ -+ for (i = 0; i < 3; i++) { -+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), -+ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, -+ PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), -+ USB_CTRL_GET_TIMEOUT); -+ if (ret > 0) { -+ ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK; -+ break; -+ } -+ } -+ -+ if (i != 0 && ret > 0) -+ dev_warn(&udev->dev, "Needed %d retries to read version\n", i); - - kfree(tmp); - -@@ -9580,25 +9690,14 @@ u8 rtl8152_get_version(struct usb_interf - } - EXPORT_SYMBOL_GPL(rtl8152_get_version); - --static int rtl8152_probe(struct usb_interface *intf, -- const struct usb_device_id *id) -+static int rtl8152_probe_once(struct usb_interface *intf, -+ const struct usb_device_id *id, u8 version) - { - struct usb_device *udev = interface_to_usbdev(intf); - struct r8152 *tp; - struct net_device *netdev; -- u8 version; - int ret; - -- if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) -- return -ENODEV; -- -- if (!rtl_check_vendor_ok(intf)) -- return -ENODEV; -- -- version = rtl8152_get_version(intf); -- if (version == RTL_VER_UNKNOWN) -- return -ENODEV; -- - usb_reset_device(udev); - netdev = alloc_etherdev(sizeof(struct r8152)); - if (!netdev) { -@@ -9771,10 +9870,20 @@ static int rtl8152_probe(struct usb_inte - else - device_set_wakeup_enable(&udev->dev, false); - -+ /* If we saw a control transfer error while probing then we may -+ * want to try probe() again. Consider this an error. -+ */ -+ if (test_bit(PROBE_SHOULD_RETRY, &tp->flags)) -+ goto out2; -+ -+ set_bit(PROBED_WITH_NO_ERRORS, &tp->flags); - netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION); - - return 0; - -+out2: -+ unregister_netdev(netdev); -+ - out1: - tasklet_kill(&tp->tx_tl); - cancel_delayed_work_sync(&tp->hw_phy_work); -@@ -9783,10 +9892,46 @@ out1: - rtl8152_release_firmware(tp); - usb_set_intfdata(intf, NULL); - out: -+ if (test_bit(PROBE_SHOULD_RETRY, &tp->flags)) -+ ret = -EAGAIN; -+ - free_netdev(netdev); - return ret; - } - -+#define RTL8152_PROBE_TRIES 3 -+ -+static int rtl8152_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ u8 version; -+ int ret; -+ int i; -+ -+ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) -+ return -ENODEV; -+ -+ if (!rtl_check_vendor_ok(intf)) -+ return -ENODEV; -+ -+ version = rtl8152_get_version(intf); -+ if (version == RTL_VER_UNKNOWN) -+ return -ENODEV; -+ -+ for (i = 0; i < RTL8152_PROBE_TRIES; i++) { -+ ret = rtl8152_probe_once(intf, id, version); -+ if (ret != -EAGAIN) -+ break; -+ } -+ if (ret == -EAGAIN) { -+ dev_err(&intf->dev, -+ "r8152 failed probe after %d tries; giving up\n", i); -+ return -ENODEV; -+ } -+ -+ return ret; -+} -+ - static void rtl8152_disconnect(struct usb_interface *intf) - { - struct r8152 *tp = usb_get_intfdata(intf); diff --git a/target/linux/generic/backport-5.15/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch b/target/linux/generic/backport-5.15/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch deleted file mode 100644 index 42ca9e2ad1c886..00000000000000 --- a/target/linux/generic/backport-5.15/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 66eee612a1ba39f9a76a9ace4a34d012044767fb Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Tue, 26 Sep 2023 19:17:13 +0800 -Subject: [PATCH] r8152: break the loop when the budget is exhausted - -[ Upstream commit 2cf51f931797d9a47e75d999d0993a68cbd2a560 ] - -A bulk transfer of the USB may contain many packets. And, the total -number of the packets in the bulk transfer may be more than budget. - -Originally, only budget packets would be handled by napi_gro_receive(), -and the other packets would be queued in the driver for next schedule. - -This patch would break the loop about getting next bulk transfer, when -the budget is exhausted. That is, only the current bulk transfer would -be handled, and the other bulk transfers would be queued for next -schedule. Besides, the packets which are more than the budget in the -current bulk trasnfer would be still queued in the driver, as the -original method. - -In addition, a bulk transfer wouldn't contain more than 400 packets, so -the check of queue length is unnecessary. Therefore, I replace it with -WARN_ON_ONCE(). - -Fixes: cf74eb5a5bc8 ("eth: r8152: try to use a normal budget") -Signed-off-by: Hayes Wang -Link: https://lore.kernel.org/r/20230926111714.9448-433-nic_swsd@realtek.com -Signed-off-by: Jakub Kicinski -Signed-off-by: Sasha Levin ---- - drivers/net/usb/r8152.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -2539,7 +2539,7 @@ static int rx_bottom(struct r8152 *tp, i - } - } - -- if (list_empty(&tp->rx_done)) -+ if (list_empty(&tp->rx_done) || work_done >= budget) - goto out1; - - clear_bit(RX_EPROTO, &tp->flags); -@@ -2555,6 +2555,15 @@ static int rx_bottom(struct r8152 *tp, i - struct urb *urb; - u8 *rx_data; - -+ /* A bulk transfer of USB may contain may packets, so the -+ * total packets may more than the budget. Deal with all -+ * packets in current bulk transfer, and stop to handle the -+ * next bulk transfer until next schedule, if budget is -+ * exhausted. -+ */ -+ if (work_done >= budget) -+ break; -+ - list_del_init(cursor); - - agg = list_entry(cursor, struct rx_agg, list); -@@ -2574,9 +2583,7 @@ static int rx_bottom(struct r8152 *tp, i - unsigned int pkt_len, rx_frag_head_sz; - struct sk_buff *skb; - -- /* limit the skb numbers for rx_queue */ -- if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000)) -- break; -+ WARN_ON_ONCE(skb_queue_len(&tp->rx_queue) >= 1000); - - pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; - if (pkt_len < ETH_ZLEN) -@@ -2654,9 +2661,10 @@ submit: - } - } - -+ /* Splice the remained list back to rx_done for next schedule */ - if (!list_empty(&rx_queue)) { - spin_lock_irqsave(&tp->rx_lock, flags); -- list_splice_tail(&rx_queue, &tp->rx_done); -+ list_splice(&rx_queue, &tp->rx_done); - spin_unlock_irqrestore(&tp->rx_lock, flags); - } - diff --git a/target/linux/generic/backport-5.15/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch b/target/linux/generic/backport-5.15/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch deleted file mode 100644 index d578d0107fddc4..00000000000000 --- a/target/linux/generic/backport-5.15/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 1b0fce8c8e69485e49a7d34aac3d4c2a2aa15d62 Mon Sep 17 00:00:00 2001 -From: Davide Tronchin -Date: Thu, 29 Jun 2023 12:37:36 +0200 -Subject: [PATCH] net: usb: cdc_ether: add u-blox 0x1313 composition. - -Add CDC-ECM support for LARA-R6 01B. - -The new LARA-R6 product variant identified by the "01B" string can be -configured (by AT interface) in three different USB modes: -* Default mode (Vendor ID: 0x1546 Product ID: 0x1311) with 4 serial -interfaces -* RmNet mode (Vendor ID: 0x1546 Product ID: 0x1312) with 4 serial -interfaces and 1 RmNet virtual network interface -* CDC-ECM mode (Vendor ID: 0x1546 Product ID: 0x1313) with 4 serial -interface and 1 CDC-ECM virtual network interface -The first 4 interfaces of all the 3 configurations (default, RmNet, ECM) -are the same. - -In CDC-ECM mode LARA-R6 01B exposes the following interfaces: -If 0: Diagnostic -If 1: AT parser -If 2: AT parser -If 3: AT parset/alternative functions -If 4: CDC-ECM interface - -Signed-off-by: Davide Tronchin -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/usb/cdc_ether.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/usb/cdc_ether.c -+++ b/drivers/net/usb/cdc_ether.c -@@ -878,6 +878,12 @@ static const struct usb_device_id produc - USB_CDC_PROTO_NONE), - .driver_info = (unsigned long)&wwan_info, - }, { -+ /* U-blox LARA-R6 01B */ -+ USB_DEVICE_AND_INTERFACE_INFO(UBLOX_VENDOR_ID, 0x1313, USB_CLASS_COMM, -+ USB_CDC_SUBCLASS_ETHERNET, -+ USB_CDC_PROTO_NONE), -+ .driver_info = (unsigned long)&wwan_info, -+}, { - /* ZTE modules */ - USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, diff --git a/target/linux/generic/backport-5.15/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch b/target/linux/generic/backport-5.15/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch deleted file mode 100644 index d9d6f36fcef385..00000000000000 --- a/target/linux/generic/backport-5.15/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 2203718c2f59ffdd6c78d54e5add594aebb4461e Mon Sep 17 00:00:00 2001 -From: Georgi Valkov -Date: Wed, 7 Jun 2023 15:56:59 +0200 -Subject: [PATCH 1/4] usbnet: ipheth: fix risk of NULL pointer deallocation - -The cleanup precedure in ipheth_probe will attempt to free a -NULL pointer in dev->ctrl_buf if the memory allocation for -this buffer is not successful. While kfree ignores NULL pointers, -and the existing code is safe, it is a better design to rearrange -the goto labels and avoid this. - -Signed-off-by: Georgi Valkov -Signed-off-by: Foster Snowhill -Signed-off-by: David S. Miller ---- - drivers/net/usb/ipheth.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/usb/ipheth.c -+++ b/drivers/net/usb/ipheth.c -@@ -510,8 +510,8 @@ err_register_netdev: - ipheth_free_urbs(dev); - err_alloc_urbs: - err_get_macaddr: --err_alloc_ctrl_buf: - kfree(dev->ctrl_buf); -+err_alloc_ctrl_buf: - err_endpoints: - free_netdev(netdev); - return retval; diff --git a/target/linux/generic/backport-5.15/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch b/target/linux/generic/backport-5.15/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch deleted file mode 100644 index adfec356d9faee..00000000000000 --- a/target/linux/generic/backport-5.15/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 3e65efcca87a9bb5f3b864e0a43d167bc0a8688c Mon Sep 17 00:00:00 2001 -From: Foster Snowhill -Date: Wed, 7 Jun 2023 15:57:00 +0200 -Subject: [PATCH 2/4] usbnet: ipheth: transmit URBs without trailing padding - -The behaviour of the official iOS tethering driver on macOS is to not -transmit any trailing padding at the end of URBs. This is applicable -to both NCM and legacy modes, including older devices. - -Adapt the driver to not include trailing padding in TX URBs, matching -the behaviour of the official macOS driver. - -Signed-off-by: Foster Snowhill -Tested-by: Georgi Valkov -Signed-off-by: David S. Miller ---- - drivers/net/usb/ipheth.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/net/usb/ipheth.c -+++ b/drivers/net/usb/ipheth.c -@@ -373,12 +373,10 @@ static netdev_tx_t ipheth_tx(struct sk_b - } - - memcpy(dev->tx_buf, skb->data, skb->len); -- if (skb->len < IPHETH_BUF_SIZE) -- memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len); - - usb_fill_bulk_urb(dev->tx_urb, udev, - usb_sndbulkpipe(udev, dev->bulk_out), -- dev->tx_buf, IPHETH_BUF_SIZE, -+ dev->tx_buf, skb->len, - ipheth_sndbulk_callback, - dev); - dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; diff --git a/target/linux/generic/backport-5.15/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch b/target/linux/generic/backport-5.15/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch deleted file mode 100644 index e3f2b9c3311e2f..00000000000000 --- a/target/linux/generic/backport-5.15/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch +++ /dev/null @@ -1,326 +0,0 @@ -From a2d274c62e44b1995c170595db3865c6fe701226 Mon Sep 17 00:00:00 2001 -From: Foster Snowhill -Date: Wed, 7 Jun 2023 15:57:01 +0200 -Subject: [PATCH 3/4] usbnet: ipheth: add CDC NCM support - -Recent iOS releases support CDC NCM encapsulation on RX. This mode is -the default on macOS and Windows. In this mode, an iOS device may include -one or more Ethernet frames inside a single URB. - -Freshly booted iOS devices start in legacy mode, but are put into -NCM mode by the official Apple driver. When reconnecting such a device -from a macOS/Windows machine to a Linux host, the device stays in -NCM mode, making it unusable with the legacy ipheth driver code. - -To correctly support such a device, the driver has to either support -the NCM mode too, or put the device back into legacy mode. - -To match the behaviour of the macOS/Windows driver, and since there -is no documented control command to revert to legacy mode, implement -NCM support. The device is attempted to be put into NCM mode by default, -and falls back to legacy mode if the attempt fails. - -Signed-off-by: Foster Snowhill -Tested-by: Georgi Valkov -Signed-off-by: David S. Miller ---- - drivers/net/usb/ipheth.c | 180 +++++++++++++++++++++++++++++++++------ - 1 file changed, 155 insertions(+), 25 deletions(-) - ---- a/drivers/net/usb/ipheth.c -+++ b/drivers/net/usb/ipheth.c -@@ -52,6 +52,7 @@ - #include - #include - #include -+#include - - #define USB_VENDOR_APPLE 0x05ac - -@@ -59,8 +60,12 @@ - #define IPHETH_USBINTF_SUBCLASS 253 - #define IPHETH_USBINTF_PROTO 1 - --#define IPHETH_BUF_SIZE 1514 - #define IPHETH_IP_ALIGN 2 /* padding at front of URB */ -+#define IPHETH_NCM_HEADER_SIZE (12 + 96) /* NCMH + NCM0 */ -+#define IPHETH_TX_BUF_SIZE ETH_FRAME_LEN -+#define IPHETH_RX_BUF_SIZE_LEGACY (IPHETH_IP_ALIGN + ETH_FRAME_LEN) -+#define IPHETH_RX_BUF_SIZE_NCM 65536 -+ - #define IPHETH_TX_TIMEOUT (5 * HZ) - - #define IPHETH_INTFNUM 2 -@@ -71,6 +76,7 @@ - #define IPHETH_CTRL_TIMEOUT (5 * HZ) - - #define IPHETH_CMD_GET_MACADDR 0x00 -+#define IPHETH_CMD_ENABLE_NCM 0x04 - #define IPHETH_CMD_CARRIER_CHECK 0x45 - - #define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ) -@@ -97,6 +103,8 @@ struct ipheth_device { - u8 bulk_out; - struct delayed_work carrier_work; - bool confirmed_pairing; -+ int (*rcvbulk_callback)(struct urb *urb); -+ size_t rx_buf_len; - }; - - static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags); -@@ -116,12 +124,12 @@ static int ipheth_alloc_urbs(struct iphe - if (rx_urb == NULL) - goto free_tx_urb; - -- tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE, -+ tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, - GFP_KERNEL, &tx_urb->transfer_dma); - if (tx_buf == NULL) - goto free_rx_urb; - -- rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, -+ rx_buf = usb_alloc_coherent(iphone->udev, iphone->rx_buf_len, - GFP_KERNEL, &rx_urb->transfer_dma); - if (rx_buf == NULL) - goto free_tx_buf; -@@ -134,7 +142,7 @@ static int ipheth_alloc_urbs(struct iphe - return 0; - - free_tx_buf: -- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, tx_buf, -+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, tx_buf, - tx_urb->transfer_dma); - free_rx_urb: - usb_free_urb(rx_urb); -@@ -146,9 +154,9 @@ error_nomem: - - static void ipheth_free_urbs(struct ipheth_device *iphone) - { -- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, iphone->rx_buf, -+ usb_free_coherent(iphone->udev, iphone->rx_buf_len, iphone->rx_buf, - iphone->rx_urb->transfer_dma); -- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf, -+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, iphone->tx_buf, - iphone->tx_urb->transfer_dma); - usb_free_urb(iphone->rx_urb); - usb_free_urb(iphone->tx_urb); -@@ -160,15 +168,106 @@ static void ipheth_kill_urbs(struct iphe - usb_kill_urb(dev->rx_urb); - } - --static void ipheth_rcvbulk_callback(struct urb *urb) -+static int ipheth_consume_skb(char *buf, int len, struct ipheth_device *dev) - { -- struct ipheth_device *dev; - struct sk_buff *skb; -- int status; -+ -+ skb = dev_alloc_skb(len); -+ if (!skb) { -+ dev->net->stats.rx_dropped++; -+ return -ENOMEM; -+ } -+ -+ skb_put_data(skb, buf, len); -+ skb->dev = dev->net; -+ skb->protocol = eth_type_trans(skb, dev->net); -+ -+ dev->net->stats.rx_packets++; -+ dev->net->stats.rx_bytes += len; -+ netif_rx(skb); -+ -+ return 0; -+} -+ -+static int ipheth_rcvbulk_callback_legacy(struct urb *urb) -+{ -+ struct ipheth_device *dev; -+ char *buf; -+ int len; -+ -+ dev = urb->context; -+ -+ if (urb->actual_length <= IPHETH_IP_ALIGN) { -+ dev->net->stats.rx_length_errors++; -+ return -EINVAL; -+ } -+ len = urb->actual_length - IPHETH_IP_ALIGN; -+ buf = urb->transfer_buffer + IPHETH_IP_ALIGN; -+ -+ return ipheth_consume_skb(buf, len, dev); -+} -+ -+static int ipheth_rcvbulk_callback_ncm(struct urb *urb) -+{ -+ struct usb_cdc_ncm_nth16 *ncmh; -+ struct usb_cdc_ncm_ndp16 *ncm0; -+ struct usb_cdc_ncm_dpe16 *dpe; -+ struct ipheth_device *dev; -+ int retval = -EINVAL; - char *buf; - int len; - - dev = urb->context; -+ -+ if (urb->actual_length < IPHETH_NCM_HEADER_SIZE) { -+ dev->net->stats.rx_length_errors++; -+ return retval; -+ } -+ -+ ncmh = urb->transfer_buffer; -+ if (ncmh->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN) || -+ le16_to_cpu(ncmh->wNdpIndex) >= urb->actual_length) { -+ dev->net->stats.rx_errors++; -+ return retval; -+ } -+ -+ ncm0 = urb->transfer_buffer + le16_to_cpu(ncmh->wNdpIndex); -+ if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN) || -+ le16_to_cpu(ncmh->wHeaderLength) + le16_to_cpu(ncm0->wLength) >= -+ urb->actual_length) { -+ dev->net->stats.rx_errors++; -+ return retval; -+ } -+ -+ dpe = ncm0->dpe16; -+ while (le16_to_cpu(dpe->wDatagramIndex) != 0 && -+ le16_to_cpu(dpe->wDatagramLength) != 0) { -+ if (le16_to_cpu(dpe->wDatagramIndex) >= urb->actual_length || -+ le16_to_cpu(dpe->wDatagramIndex) + -+ le16_to_cpu(dpe->wDatagramLength) > urb->actual_length) { -+ dev->net->stats.rx_length_errors++; -+ return retval; -+ } -+ -+ buf = urb->transfer_buffer + le16_to_cpu(dpe->wDatagramIndex); -+ len = le16_to_cpu(dpe->wDatagramLength); -+ -+ retval = ipheth_consume_skb(buf, len, dev); -+ if (retval != 0) -+ return retval; -+ -+ dpe++; -+ } -+ -+ return 0; -+} -+ -+static void ipheth_rcvbulk_callback(struct urb *urb) -+{ -+ struct ipheth_device *dev; -+ int retval, status; -+ -+ dev = urb->context; - if (dev == NULL) - return; - -@@ -191,25 +290,27 @@ static void ipheth_rcvbulk_callback(stru - dev->net->stats.rx_length_errors++; - return; - } -- len = urb->actual_length - IPHETH_IP_ALIGN; -- buf = urb->transfer_buffer + IPHETH_IP_ALIGN; - -- skb = dev_alloc_skb(len); -- if (!skb) { -- dev_err(&dev->intf->dev, "%s: dev_alloc_skb: -ENOMEM\n", -- __func__); -- dev->net->stats.rx_dropped++; -+ /* RX URBs starting with 0x00 0x01 do not encapsulate Ethernet frames, -+ * but rather are control frames. Their purpose is not documented, and -+ * they don't affect driver functionality, okay to drop them. -+ * There is usually just one 4-byte control frame as the very first -+ * URB received from the bulk IN endpoint. -+ */ -+ if (unlikely -+ (((char *)urb->transfer_buffer)[0] == 0 && -+ ((char *)urb->transfer_buffer)[1] == 1)) -+ goto rx_submit; -+ -+ retval = dev->rcvbulk_callback(urb); -+ if (retval != 0) { -+ dev_err(&dev->intf->dev, "%s: callback retval: %d\n", -+ __func__, retval); - return; - } - -- skb_put_data(skb, buf, len); -- skb->dev = dev->net; -- skb->protocol = eth_type_trans(skb, dev->net); -- -- dev->net->stats.rx_packets++; -- dev->net->stats.rx_bytes += len; -+rx_submit: - dev->confirmed_pairing = true; -- netif_rx(skb); - ipheth_rx_submit(dev, GFP_ATOMIC); - } - -@@ -310,6 +411,27 @@ static int ipheth_get_macaddr(struct iph - return retval; - } - -+static int ipheth_enable_ncm(struct ipheth_device *dev) -+{ -+ struct usb_device *udev = dev->udev; -+ int retval; -+ -+ retval = usb_control_msg(udev, -+ usb_sndctrlpipe(udev, IPHETH_CTRL_ENDP), -+ IPHETH_CMD_ENABLE_NCM, /* request */ -+ 0x41, /* request type */ -+ 0x00, /* value */ -+ 0x02, /* index */ -+ NULL, -+ 0, -+ IPHETH_CTRL_TIMEOUT); -+ -+ dev_info(&dev->intf->dev, "%s: usb_control_msg: %d\n", -+ __func__, retval); -+ -+ return retval; -+} -+ - static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags) - { - struct usb_device *udev = dev->udev; -@@ -317,7 +439,7 @@ static int ipheth_rx_submit(struct iphet - - usb_fill_bulk_urb(dev->rx_urb, udev, - usb_rcvbulkpipe(udev, dev->bulk_in), -- dev->rx_buf, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, -+ dev->rx_buf, dev->rx_buf_len, - ipheth_rcvbulk_callback, - dev); - dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -@@ -365,7 +487,7 @@ static netdev_tx_t ipheth_tx(struct sk_b - int retval; - - /* Paranoid */ -- if (skb->len > IPHETH_BUF_SIZE) { -+ if (skb->len > IPHETH_TX_BUF_SIZE) { - WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len); - dev->net->stats.tx_dropped++; - dev_kfree_skb_any(skb); -@@ -448,6 +570,8 @@ static int ipheth_probe(struct usb_inter - dev->net = netdev; - dev->intf = intf; - dev->confirmed_pairing = false; -+ dev->rx_buf_len = IPHETH_RX_BUF_SIZE_LEGACY; -+ dev->rcvbulk_callback = ipheth_rcvbulk_callback_legacy; - /* Set up endpoints */ - hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM); - if (hintf == NULL) { -@@ -479,6 +603,12 @@ static int ipheth_probe(struct usb_inter - if (retval) - goto err_get_macaddr; - -+ retval = ipheth_enable_ncm(dev); -+ if (!retval) { -+ dev->rx_buf_len = IPHETH_RX_BUF_SIZE_NCM; -+ dev->rcvbulk_callback = ipheth_rcvbulk_callback_ncm; -+ } -+ - INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work); - - retval = ipheth_alloc_urbs(dev); diff --git a/target/linux/generic/backport-5.15/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch b/target/linux/generic/backport-5.15/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch deleted file mode 100644 index 2ab7e8feddc44c..00000000000000 --- a/target/linux/generic/backport-5.15/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0c6e9d32ef0ccfcf2d875cbcff23bf345a54d585 Mon Sep 17 00:00:00 2001 -From: Foster Snowhill -Date: Wed, 7 Jun 2023 15:57:02 +0200 -Subject: [PATCH 4/4] usbnet: ipheth: update Kconfig description - -This module has for a long time not been limited to iPhone <= 3GS. -Update description to match the actual state of the driver. - -Remove dead link from 2010, instead reference an existing userspace -iOS device pairing implementation as part of libimobiledevice. - -Signed-off-by: Foster Snowhill -Signed-off-by: David S. Miller ---- - drivers/net/usb/Kconfig | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - ---- a/drivers/net/usb/Kconfig -+++ b/drivers/net/usb/Kconfig -@@ -582,12 +582,10 @@ config USB_IPHETH - default n - help - Module used to share Internet connection (tethering) from your -- iPhone (Original, 3G and 3GS) to your system. -- Note that you need userspace libraries and programs that are needed -- to pair your device with your system and that understand the iPhone -- protocol. -- -- For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver -+ iPhone to your system. -+ Note that you need a corresponding userspace library/program -+ to pair your device with your system, for example usbmuxd -+ . - - config USB_SIERRA_NET - tristate "USB-to-WWAN Driver for Sierra Wireless modems" diff --git a/target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch b/target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch deleted file mode 100644 index b2af169b927685..00000000000000 --- a/target/linux/generic/backport-5.15/797-v5.17-net-usb-ax88179_178a-add-TSO-feature.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 16b1c4e01c89ba07367461e0bc4cb84993c2d027 Mon Sep 17 00:00:00 2001 -From: Jacky Chou -Date: Mon, 15 Nov 2021 11:49:41 +0800 -Subject: [PATCH] net: usb: ax88179_178a: add TSO feature - -On low-effciency embedded platforms, transmission performance is poor -due to on Bulk-out with single packet. -Adding TSO feature improves the transmission performance and reduces -the number of interrupt caused by Bulk-out complete. - -Reference to module, net: usb: aqc111. - -Signed-off-by: Jacky Chou -Signed-off-by: David S. Miller ---- - drivers/net/usb/ax88179_178a.c | 17 +++++++++++------ - 1 file changed, 11 insertions(+), 6 deletions(-) - ---- a/drivers/net/usb/ax88179_178a.c -+++ b/drivers/net/usb/ax88179_178a.c -@@ -1333,11 +1333,12 @@ static int ax88179_bind(struct usbnet *d - dev->mii.phy_id = 0x03; - dev->mii.supports_gmii = 1; - -- dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | -- NETIF_F_RXCSUM; -+ dev->net->features |= NETIF_F_SG | NETIF_F_IP_CSUM | -+ NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO; - -- dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | -- NETIF_F_RXCSUM; -+ dev->net->hw_features |= dev->net->features; -+ -+ netif_set_gso_max_size(dev->net, 16384); - - ax88179_reset(dev); - -@@ -1502,17 +1503,19 @@ ax88179_tx_fixup(struct usbnet *dev, str - { - u32 tx_hdr1, tx_hdr2; - int frame_size = dev->maxpacket; -- int mss = skb_shinfo(skb)->gso_size; - int headroom; - void *ptr; - - tx_hdr1 = skb->len; -- tx_hdr2 = mss; -+ tx_hdr2 = skb_shinfo(skb)->gso_size; /* Set TSO mss */ - if (((skb->len + 8) % frame_size) == 0) - tx_hdr2 |= 0x80008000; /* Enable padding */ - - headroom = skb_headroom(skb) - 8; - -+ if ((dev->net->features & NETIF_F_SG) && skb_linearize(skb)) -+ return NULL; -+ - if ((skb_header_cloned(skb) || headroom < 0) && - pskb_expand_head(skb, headroom < 0 ? 8 : 0, 0, GFP_ATOMIC)) { - dev_kfree_skb_any(skb); -@@ -1523,6 +1526,8 @@ ax88179_tx_fixup(struct usbnet *dev, str - put_unaligned_le32(tx_hdr1, ptr); - put_unaligned_le32(tx_hdr2, ptr + 4); - -+ usbnet_set_skb_tx_stats(skb, (skb_shinfo(skb)->gso_segs ?: 1), 0); -+ - return skb; - } - diff --git a/target/linux/generic/backport-5.15/798-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch b/target/linux/generic/backport-5.15/798-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch deleted file mode 100644 index d6015a56584143..00000000000000 --- a/target/linux/generic/backport-5.15/798-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d387e34fec407f881fdf165b5d7ec128ebff362f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 19 Sep 2023 14:47:20 +0200 -Subject: [PATCH] net: sfp: add quirk for Fiberstone GPON-ONU-34-20BI - -Fiberstone GPON-ONU-34-20B can operate at 2500base-X, but report 1.2GBd -NRZ in their EEPROM. - -The module also require the ignore tx fault fixup similar to Huawei MA5671A -as it gets disabled on error messages with serial redirection enabled. - -Signed-off-by: Christian Marangi -Link: https://lore.kernel.org/r/20230919124720.8210-1-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/sfp.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -368,6 +368,13 @@ static const struct sfp_quirk sfp_quirks - .modes = sfp_quirk_2500basex, - .fixup = sfp_fixup_long_startup, - }, { -+ // Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd -+ // NRZ in their EEPROM -+ .vendor = "FS", -+ .part = "GPON-ONU-34-20BI", -+ .modes = sfp_quirk_2500basex, -+ .fixup = sfp_fixup_ignore_tx_fault, -+ }, { - .vendor = "HALNy", - .part = "HL-GSFP", - .fixup = sfp_fixup_halny_gsfp, diff --git a/target/linux/generic/backport-5.15/800-v6.0-0001-dt-bindings-leds-add-Broadcom-s-BCM63138-controller.patch b/target/linux/generic/backport-5.15/800-v6.0-0001-dt-bindings-leds-add-Broadcom-s-BCM63138-controller.patch deleted file mode 100644 index b1072ce6408ddb..00000000000000 --- a/target/linux/generic/backport-5.15/800-v6.0-0001-dt-bindings-leds-add-Broadcom-s-BCM63138-controller.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 13344f8ce8a0d98aa7f5d69ce3b47393c73a343b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 27 Dec 2021 15:59:04 +0100 -Subject: [PATCH] dt-bindings: leds: add Broadcom's BCM63138 controller -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Broadcom used 2 LEDs hardware blocks for their BCM63xx SoCs: -1. Older one (BCM6318, BCM6328, BCM6362, BCM63268, BCM6838) -2. Newer one (BCM6848, BCM6858, BCM63138, BCM63148, BCM63381, BCM68360) - -The newer one was also later also used on BCM4908 SoC. - -Old block is already documented in the leds-bcm6328.yaml. This binding -documents the new one which uses different registers & programming. It's -first used in BCM63138 thus the binding name. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Rob Herring -Reviewed-by: Florian Fainelli -Signed-off-by: Pavel Machek ---- - .../bindings/leds/leds-bcm63138.yaml | 95 +++++++++++++++++++ - 1 file changed, 95 insertions(+) - create mode 100644 Documentation/devicetree/bindings/leds/leds-bcm63138.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/leds/leds-bcm63138.yaml -@@ -0,0 +1,95 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/leds/leds-bcm63138.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Broadcom's BCM63138 LEDs controller -+ -+maintainers: -+ - Rafał Miłecki -+ -+description: | -+ This LEDs controller was first used on BCM63138 and later reused on BCM4908, -+ BCM6848, BCM6858, BCM63138, BCM63148, BCM63381 and BCM68360 SoCs. -+ -+ It supports up to 32 LEDs that can be connected parallelly or serially. It -+ also includes limited support for hardware blinking. -+ -+ Binding serially connected LEDs isn't documented yet. -+ -+properties: -+ compatible: -+ oneOf: -+ - items: -+ - enum: -+ - brcm,bcm4908-leds -+ - brcm,bcm6848-leds -+ - brcm,bcm6858-leds -+ - brcm,bcm63148-leds -+ - brcm,bcm63381-leds -+ - brcm,bcm68360-leds -+ - const: brcm,bcm63138-leds -+ - const: brcm,bcm63138-leds -+ -+ reg: -+ maxItems: 1 -+ -+ "#address-cells": -+ const: 1 -+ -+ "#size-cells": -+ const: 0 -+ -+patternProperties: -+ "^led@[a-f0-9]+$": -+ type: object -+ -+ $ref: common.yaml# -+ -+ properties: -+ reg: -+ maxItems: 1 -+ description: LED pin number -+ -+ active-low: -+ type: boolean -+ description: Makes LED active low. -+ -+ required: -+ - reg -+ -+ unevaluatedProperties: false -+ -+required: -+ - reg -+ - "#address-cells" -+ - "#size-cells" -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include -+ -+ leds@ff800800 { -+ compatible = "brcm,bcm4908-leds", "brcm,bcm63138-leds"; -+ reg = <0xff800800 0xdc>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ led@0 { -+ reg = <0x0>; -+ function = LED_FUNCTION_POWER; -+ color = ; -+ default-state = "on"; -+ }; -+ -+ led@3 { -+ reg = <0x3>; -+ function = LED_FUNCTION_STATUS; -+ color = ; -+ active-low; -+ }; -+ }; diff --git a/target/linux/generic/backport-5.15/800-v6.0-0002-leds-bcm63138-add-support-for-BCM63138-controller.patch b/target/linux/generic/backport-5.15/800-v6.0-0002-leds-bcm63138-add-support-for-BCM63138-controller.patch deleted file mode 100644 index 376584574fcd17..00000000000000 --- a/target/linux/generic/backport-5.15/800-v6.0-0002-leds-bcm63138-add-support-for-BCM63138-controller.patch +++ /dev/null @@ -1,356 +0,0 @@ -From a0ba692072d89075d0a75c7ad9df31f2c1ee9a1c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 27 Dec 2021 15:59:05 +0100 -Subject: [PATCH] leds: bcm63138: add support for BCM63138 controller -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It's a new controller first introduced in BCM63138 SoC. Later it was -also used in BCM4908, some BCM68xx and some BCM63xxx SoCs. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Florian Fainelli -Signed-off-by: Pavel Machek ---- - drivers/leds/blink/Kconfig | 12 ++ - drivers/leds/blink/Makefile | 1 + - drivers/leds/blink/leds-bcm63138.c | 308 +++++++++++++++++++++++++++++ - 3 files changed, 321 insertions(+) - create mode 100644 drivers/leds/blink/leds-bcm63138.c - ---- a/drivers/leds/blink/Kconfig -+++ b/drivers/leds/blink/Kconfig -@@ -1,3 +1,15 @@ -+config LEDS_BCM63138 -+ tristate "LED Support for Broadcom BCM63138 SoC" -+ depends on LEDS_CLASS -+ depends on ARCH_BCM4908 || ARCH_BCM_5301X || BCM63XX || COMPILE_TEST -+ depends on HAS_IOMEM -+ depends on OF -+ default ARCH_BCM4908 -+ help -+ This option enables support for LED controller that is part of -+ BCM63138 SoC. The same hardware block is known to be also used -+ in BCM4908, BCM6848, BCM6858, BCM63148, BCM63381 and BCM68360. -+ - config LEDS_LGM - tristate "LED support for LGM SoC series" - depends on X86 || COMPILE_TEST ---- a/drivers/leds/blink/Makefile -+++ b/drivers/leds/blink/Makefile -@@ -1,2 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 -+obj-$(CONFIG_LEDS_BCM63138) += leds-bcm63138.o - obj-$(CONFIG_LEDS_LGM) += leds-lgm-sso.o ---- /dev/null -+++ b/drivers/leds/blink/leds-bcm63138.c -@@ -0,0 +1,308 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (C) 2021 Rafał Miłecki -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define BCM63138_MAX_LEDS 32 -+#define BCM63138_MAX_BRIGHTNESS 9 -+ -+#define BCM63138_LED_BITS 4 /* how many bits control a single LED */ -+#define BCM63138_LED_MASK ((1 << BCM63138_LED_BITS) - 1) /* 0xf */ -+#define BCM63138_LEDS_PER_REG (32 / BCM63138_LED_BITS) /* 8 */ -+ -+#define BCM63138_GLB_CTRL 0x00 -+#define BCM63138_GLB_CTRL_SERIAL_LED_DATA_PPOL 0x00000002 -+#define BCM63138_GLB_CTRL_SERIAL_LED_EN_POL 0x00000008 -+#define BCM63138_MASK 0x04 -+#define BCM63138_HW_LED_EN 0x08 -+#define BCM63138_SERIAL_LED_SHIFT_SEL 0x0c -+#define BCM63138_FLASH_RATE_CTRL1 0x10 -+#define BCM63138_FLASH_RATE_CTRL2 0x14 -+#define BCM63138_FLASH_RATE_CTRL3 0x18 -+#define BCM63138_FLASH_RATE_CTRL4 0x1c -+#define BCM63138_BRIGHT_CTRL1 0x20 -+#define BCM63138_BRIGHT_CTRL2 0x24 -+#define BCM63138_BRIGHT_CTRL3 0x28 -+#define BCM63138_BRIGHT_CTRL4 0x2c -+#define BCM63138_POWER_LED_CFG 0x30 -+#define BCM63138_HW_POLARITY 0xb4 -+#define BCM63138_SW_DATA 0xb8 -+#define BCM63138_SW_POLARITY 0xbc -+#define BCM63138_PARALLEL_LED_POLARITY 0xc0 -+#define BCM63138_SERIAL_LED_POLARITY 0xc4 -+#define BCM63138_HW_LED_STATUS 0xc8 -+#define BCM63138_FLASH_CTRL_STATUS 0xcc -+#define BCM63138_FLASH_BRT_CTRL 0xd0 -+#define BCM63138_FLASH_P_LED_OUT_STATUS 0xd4 -+#define BCM63138_FLASH_S_LED_OUT_STATUS 0xd8 -+ -+struct bcm63138_leds { -+ struct device *dev; -+ void __iomem *base; -+ spinlock_t lock; -+}; -+ -+struct bcm63138_led { -+ struct bcm63138_leds *leds; -+ struct led_classdev cdev; -+ u32 pin; -+ bool active_low; -+}; -+ -+/* -+ * I/O access -+ */ -+ -+static void bcm63138_leds_write(struct bcm63138_leds *leds, unsigned int reg, -+ u32 data) -+{ -+ writel(data, leds->base + reg); -+} -+ -+static unsigned long bcm63138_leds_read(struct bcm63138_leds *leds, -+ unsigned int reg) -+{ -+ return readl(leds->base + reg); -+} -+ -+static void bcm63138_leds_update_bits(struct bcm63138_leds *leds, -+ unsigned int reg, u32 mask, u32 val) -+{ -+ WARN_ON(val & ~mask); -+ -+ bcm63138_leds_write(leds, reg, (bcm63138_leds_read(leds, reg) & ~mask) | (val & mask)); -+} -+ -+/* -+ * Helpers -+ */ -+ -+static void bcm63138_leds_set_flash_rate(struct bcm63138_leds *leds, -+ struct bcm63138_led *led, -+ u8 value) -+{ -+ int reg_offset = (led->pin >> fls((BCM63138_LEDS_PER_REG - 1))) * 4; -+ int shift = (led->pin & (BCM63138_LEDS_PER_REG - 1)) * BCM63138_LED_BITS; -+ -+ bcm63138_leds_update_bits(leds, BCM63138_FLASH_RATE_CTRL1 + reg_offset, -+ BCM63138_LED_MASK << shift, value << shift); -+} -+ -+static void bcm63138_leds_set_bright(struct bcm63138_leds *leds, -+ struct bcm63138_led *led, -+ u8 value) -+{ -+ int reg_offset = (led->pin >> fls((BCM63138_LEDS_PER_REG - 1))) * 4; -+ int shift = (led->pin & (BCM63138_LEDS_PER_REG - 1)) * BCM63138_LED_BITS; -+ -+ bcm63138_leds_update_bits(leds, BCM63138_BRIGHT_CTRL1 + reg_offset, -+ BCM63138_LED_MASK << shift, value << shift); -+} -+ -+static void bcm63138_leds_enable_led(struct bcm63138_leds *leds, -+ struct bcm63138_led *led, -+ enum led_brightness value) -+{ -+ u32 bit = BIT(led->pin); -+ -+ bcm63138_leds_update_bits(leds, BCM63138_SW_DATA, bit, -+ value == LED_OFF ? 0 : bit); -+} -+ -+/* -+ * API callbacks -+ */ -+ -+static void bcm63138_leds_brightness_set(struct led_classdev *led_cdev, -+ enum led_brightness value) -+{ -+ struct bcm63138_led *led = container_of(led_cdev, struct bcm63138_led, cdev); -+ struct bcm63138_leds *leds = led->leds; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&leds->lock, flags); -+ -+ bcm63138_leds_enable_led(leds, led, value); -+ if (!value) -+ bcm63138_leds_set_flash_rate(leds, led, 0); -+ else -+ bcm63138_leds_set_bright(leds, led, value); -+ -+ spin_unlock_irqrestore(&leds->lock, flags); -+} -+ -+static int bcm63138_leds_blink_set(struct led_classdev *led_cdev, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct bcm63138_led *led = container_of(led_cdev, struct bcm63138_led, cdev); -+ struct bcm63138_leds *leds = led->leds; -+ unsigned long flags; -+ u8 value; -+ -+ if (!*delay_on && !*delay_off) { -+ *delay_on = 640; -+ *delay_off = 640; -+ } -+ -+ if (*delay_on != *delay_off) { -+ dev_dbg(led_cdev->dev, "Blinking at unequal delays is not supported\n"); -+ return -EINVAL; -+ } -+ -+ switch (*delay_on) { -+ case 1152 ... 1408: /* 1280 ms ± 10% */ -+ value = 0x7; -+ break; -+ case 576 ... 704: /* 640 ms ± 10% */ -+ value = 0x6; -+ break; -+ case 288 ... 352: /* 320 ms ± 10% */ -+ value = 0x5; -+ break; -+ case 126 ... 154: /* 140 ms ± 10% */ -+ value = 0x4; -+ break; -+ case 59 ... 72: /* 65 ms ± 10% */ -+ value = 0x3; -+ break; -+ default: -+ dev_dbg(led_cdev->dev, "Blinking delay value %lu is unsupported\n", -+ *delay_on); -+ return -EINVAL; -+ } -+ -+ spin_lock_irqsave(&leds->lock, flags); -+ -+ bcm63138_leds_enable_led(leds, led, BCM63138_MAX_BRIGHTNESS); -+ bcm63138_leds_set_flash_rate(leds, led, value); -+ -+ spin_unlock_irqrestore(&leds->lock, flags); -+ -+ return 0; -+} -+ -+/* -+ * LED driver -+ */ -+ -+static void bcm63138_leds_create_led(struct bcm63138_leds *leds, -+ struct device_node *np) -+{ -+ struct led_init_data init_data = { -+ .fwnode = of_fwnode_handle(np), -+ }; -+ struct device *dev = leds->dev; -+ struct bcm63138_led *led; -+ struct pinctrl *pinctrl; -+ u32 bit; -+ int err; -+ -+ led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); -+ if (!led) { -+ dev_err(dev, "Failed to alloc LED\n"); -+ return; -+ } -+ -+ led->leds = leds; -+ -+ if (of_property_read_u32(np, "reg", &led->pin)) { -+ dev_err(dev, "Missing \"reg\" property in %pOF\n", np); -+ goto err_free; -+ } -+ -+ if (led->pin >= BCM63138_MAX_LEDS) { -+ dev_err(dev, "Invalid \"reg\" value %d\n", led->pin); -+ goto err_free; -+ } -+ -+ led->active_low = of_property_read_bool(np, "active-low"); -+ -+ led->cdev.max_brightness = BCM63138_MAX_BRIGHTNESS; -+ led->cdev.brightness_set = bcm63138_leds_brightness_set; -+ led->cdev.blink_set = bcm63138_leds_blink_set; -+ -+ err = devm_led_classdev_register_ext(dev, &led->cdev, &init_data); -+ if (err) { -+ dev_err(dev, "Failed to register LED %pOF: %d\n", np, err); -+ goto err_free; -+ } -+ -+ pinctrl = devm_pinctrl_get_select_default(led->cdev.dev); -+ if (IS_ERR(pinctrl) && PTR_ERR(pinctrl) != -ENODEV) { -+ dev_warn(led->cdev.dev, "Failed to select %pOF pinctrl: %ld\n", -+ np, PTR_ERR(pinctrl)); -+ } -+ -+ bit = BIT(led->pin); -+ bcm63138_leds_update_bits(leds, BCM63138_PARALLEL_LED_POLARITY, bit, -+ led->active_low ? 0 : bit); -+ bcm63138_leds_update_bits(leds, BCM63138_HW_LED_EN, bit, 0); -+ bcm63138_leds_set_flash_rate(leds, led, 0); -+ bcm63138_leds_enable_led(leds, led, led->cdev.brightness); -+ -+ return; -+ -+err_free: -+ devm_kfree(dev, led); -+} -+ -+static int bcm63138_leds_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = dev_of_node(&pdev->dev); -+ struct device *dev = &pdev->dev; -+ struct bcm63138_leds *leds; -+ struct device_node *child; -+ -+ leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL); -+ if (!leds) -+ return -ENOMEM; -+ -+ leds->dev = dev; -+ -+ leds->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(leds->base)) -+ return PTR_ERR(leds->base); -+ -+ spin_lock_init(&leds->lock); -+ -+ bcm63138_leds_write(leds, BCM63138_GLB_CTRL, -+ BCM63138_GLB_CTRL_SERIAL_LED_DATA_PPOL | -+ BCM63138_GLB_CTRL_SERIAL_LED_EN_POL); -+ bcm63138_leds_write(leds, BCM63138_HW_LED_EN, 0); -+ bcm63138_leds_write(leds, BCM63138_SERIAL_LED_POLARITY, 0); -+ bcm63138_leds_write(leds, BCM63138_PARALLEL_LED_POLARITY, 0); -+ -+ for_each_available_child_of_node(np, child) { -+ bcm63138_leds_create_led(leds, child); -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm63138_leds_of_match_table[] = { -+ { .compatible = "brcm,bcm63138-leds", }, -+ { }, -+}; -+ -+static struct platform_driver bcm63138_leds_driver = { -+ .probe = bcm63138_leds_probe, -+ .driver = { -+ .name = "leds-bcm63xxx", -+ .of_match_table = bcm63138_leds_of_match_table, -+ }, -+}; -+ -+module_platform_driver(bcm63138_leds_driver); -+ -+MODULE_AUTHOR("Rafał Miłecki"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(of, bcm63138_leds_of_match_table); diff --git a/target/linux/generic/backport-5.15/801-v6.0-0001-dt-bindings-leds-leds-bcm63138-unify-full-stops-in-d.patch b/target/linux/generic/backport-5.15/801-v6.0-0001-dt-bindings-leds-leds-bcm63138-unify-full-stops-in-d.patch deleted file mode 100644 index 483826abed5f97..00000000000000 --- a/target/linux/generic/backport-5.15/801-v6.0-0001-dt-bindings-leds-leds-bcm63138-unify-full-stops-in-d.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 13b64a0c19059b38150c79d65d350ae44034c5df Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 17 Jul 2022 14:42:46 +0200 -Subject: [PATCH] dt-bindings: leds: leds-bcm63138: unify full stops in - descriptions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Description of "reg" doesn't have full stop at the end. It makes sense -as it's a one-sentence only. Use the same style for "active-low". - -Reported-by: Pavel Machek -Signed-off-by: Rafał Miłecki -Signed-off-by: Pavel Machek ---- - Documentation/devicetree/bindings/leds/leds-bcm63138.yaml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/Documentation/devicetree/bindings/leds/leds-bcm63138.yaml -+++ b/Documentation/devicetree/bindings/leds/leds-bcm63138.yaml -@@ -54,7 +54,7 @@ patternProperties: - - active-low: - type: boolean -- description: Makes LED active low. -+ description: Makes LED active low - - required: - - reg diff --git a/target/linux/generic/backport-5.15/801-v6.0-0002-leds-add-help-info-about-BCM63138-module-name.patch b/target/linux/generic/backport-5.15/801-v6.0-0002-leds-add-help-info-about-BCM63138-module-name.patch deleted file mode 100644 index 5430b1f08448a2..00000000000000 --- a/target/linux/generic/backport-5.15/801-v6.0-0002-leds-add-help-info-about-BCM63138-module-name.patch +++ /dev/null @@ -1,28 +0,0 @@ -From bcc607cdbb1f931111196699426f0cb83bfb296a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 17 Jul 2022 14:42:47 +0200 -Subject: [PATCH] leds: add help info about BCM63138 module name -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It's what we do for all other LEDs drivers. - -Reported-by: Pavel Machek -Signed-off-by: Rafał Miłecki -Signed-off-by: Pavel Machek ---- - drivers/leds/blink/Kconfig | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/leds/blink/Kconfig -+++ b/drivers/leds/blink/Kconfig -@@ -10,6 +10,8 @@ config LEDS_BCM63138 - BCM63138 SoC. The same hardware block is known to be also used - in BCM4908, BCM6848, BCM6858, BCM63148, BCM63381 and BCM68360. - -+ If compiled as module it will be called leds-bcm63138. -+ - config LEDS_LGM - tristate "LED support for LGM SoC series" - depends on X86 || COMPILE_TEST diff --git a/target/linux/generic/backport-5.15/801-v6.0-0003-leds-leds-bcm63138-get-rid-of-LED_OFF.patch b/target/linux/generic/backport-5.15/801-v6.0-0003-leds-leds-bcm63138-get-rid-of-LED_OFF.patch deleted file mode 100644 index e125a54613b27b..00000000000000 --- a/target/linux/generic/backport-5.15/801-v6.0-0003-leds-leds-bcm63138-get-rid-of-LED_OFF.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 92cfc71ee2ddfb499ed53e21b28bdf8739bc70bc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 17 Jul 2022 14:42:48 +0200 -Subject: [PATCH] leds: leds-bcm63138: get rid of LED_OFF -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The whole "enum led_brightness" is marked as obsolete. Replace it with a -(non-)zero check. - -Reported-by: Pavel Machek -Signed-off-by: Rafał Miłecki -Signed-off-by: Pavel Machek ---- - drivers/leds/blink/leds-bcm63138.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/leds/blink/leds-bcm63138.c -+++ b/drivers/leds/blink/leds-bcm63138.c -@@ -113,8 +113,7 @@ static void bcm63138_leds_enable_led(str - { - u32 bit = BIT(led->pin); - -- bcm63138_leds_update_bits(leds, BCM63138_SW_DATA, bit, -- value == LED_OFF ? 0 : bit); -+ bcm63138_leds_update_bits(leds, BCM63138_SW_DATA, bit, value ? bit : 0); - } - - /* diff --git a/target/linux/generic/backport-5.15/802-v5.16-0001-nvmem-core-rework-nvmem-cell-instance-creation.patch b/target/linux/generic/backport-5.15/802-v5.16-0001-nvmem-core-rework-nvmem-cell-instance-creation.patch deleted file mode 100644 index ebab8c7c736dd0..00000000000000 --- a/target/linux/generic/backport-5.15/802-v5.16-0001-nvmem-core-rework-nvmem-cell-instance-creation.patch +++ /dev/null @@ -1,456 +0,0 @@ -From 7ae6478b304bc004c3139b422665b0e23b57f05c Mon Sep 17 00:00:00 2001 -From: Srinivas Kandagatla -Date: Wed, 13 Oct 2021 14:19:55 +0100 -Subject: [PATCH] nvmem: core: rework nvmem cell instance creation - -In the existing design, we do not create a instance per nvmem cell consumer -but we directly refer cell from nvmem cell list that are added to provider. - -However this design has some limitations when consumers want to assign name -or connection id the nvmem cell instance, ex: via "nvmem-cell-names" or -id in nvmem_cell_get(id). - -Having a name associated with nvmem cell consumer instance will help -provider drivers in performing post processing of nvmem cell data if required -before data is seen by the consumers. This is pretty normal with some vendors -storing nvmem cells like mac-address in a vendor specific data layouts that -are not directly usable by the consumer drivers. - -With this patch nvmem cell will be created dynamically during nvmem_cell_get -and destroyed in nvmem_cell_put, allowing consumers to associate name with -nvmem cell consumer instance. - -With this patch a new struct nvmem_cell_entry replaces struct nvmem_cell -for storing nvmem cell information within the core. -This patch does not change nvmem-consumer interface based on nvmem_cell. - -Tested-by: Joakim Zhang -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20211013131957.30271-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 165 +++++++++++++++++++++++++++---------------- - 1 file changed, 105 insertions(+), 60 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -45,8 +45,7 @@ struct nvmem_device { - #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) - - #define FLAG_COMPAT BIT(0) -- --struct nvmem_cell { -+struct nvmem_cell_entry { - const char *name; - int offset; - int bytes; -@@ -57,6 +56,11 @@ struct nvmem_cell { - struct list_head node; - }; - -+struct nvmem_cell { -+ struct nvmem_cell_entry *entry; -+ const char *id; -+}; -+ - static DEFINE_MUTEX(nvmem_mutex); - static DEFINE_IDA(nvmem_ida); - -@@ -424,7 +428,7 @@ static struct bus_type nvmem_bus_type = - .name = "nvmem", - }; - --static void nvmem_cell_drop(struct nvmem_cell *cell) -+static void nvmem_cell_entry_drop(struct nvmem_cell_entry *cell) - { - blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_REMOVE, cell); - mutex_lock(&nvmem_mutex); -@@ -437,13 +441,13 @@ static void nvmem_cell_drop(struct nvmem - - static void nvmem_device_remove_all_cells(const struct nvmem_device *nvmem) - { -- struct nvmem_cell *cell, *p; -+ struct nvmem_cell_entry *cell, *p; - - list_for_each_entry_safe(cell, p, &nvmem->cells, node) -- nvmem_cell_drop(cell); -+ nvmem_cell_entry_drop(cell); - } - --static void nvmem_cell_add(struct nvmem_cell *cell) -+static void nvmem_cell_entry_add(struct nvmem_cell_entry *cell) - { - mutex_lock(&nvmem_mutex); - list_add_tail(&cell->node, &cell->nvmem->cells); -@@ -451,9 +455,9 @@ static void nvmem_cell_add(struct nvmem_ - blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_ADD, cell); - } - --static int nvmem_cell_info_to_nvmem_cell_nodup(struct nvmem_device *nvmem, -- const struct nvmem_cell_info *info, -- struct nvmem_cell *cell) -+static int nvmem_cell_info_to_nvmem_cell_entry_nodup(struct nvmem_device *nvmem, -+ const struct nvmem_cell_info *info, -+ struct nvmem_cell_entry *cell) - { - cell->nvmem = nvmem; - cell->offset = info->offset; -@@ -477,13 +481,13 @@ static int nvmem_cell_info_to_nvmem_cell - return 0; - } - --static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem, -- const struct nvmem_cell_info *info, -- struct nvmem_cell *cell) -+static int nvmem_cell_info_to_nvmem_cell_entry(struct nvmem_device *nvmem, -+ const struct nvmem_cell_info *info, -+ struct nvmem_cell_entry *cell) - { - int err; - -- err = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, cell); -+ err = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, cell); - if (err) - return err; - -@@ -507,7 +511,7 @@ static int nvmem_add_cells(struct nvmem_ - const struct nvmem_cell_info *info, - int ncells) - { -- struct nvmem_cell **cells; -+ struct nvmem_cell_entry **cells; - int i, rval; - - cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); -@@ -521,13 +525,13 @@ static int nvmem_add_cells(struct nvmem_ - goto err; - } - -- rval = nvmem_cell_info_to_nvmem_cell(nvmem, &info[i], cells[i]); -+ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); - if (rval) { - kfree(cells[i]); - goto err; - } - -- nvmem_cell_add(cells[i]); -+ nvmem_cell_entry_add(cells[i]); - } - - /* remove tmp array */ -@@ -536,7 +540,7 @@ static int nvmem_add_cells(struct nvmem_ - return 0; - err: - while (i--) -- nvmem_cell_drop(cells[i]); -+ nvmem_cell_entry_drop(cells[i]); - - kfree(cells); - -@@ -573,7 +577,7 @@ static int nvmem_add_cells_from_table(st - { - const struct nvmem_cell_info *info; - struct nvmem_cell_table *table; -- struct nvmem_cell *cell; -+ struct nvmem_cell_entry *cell; - int rval = 0, i; - - mutex_lock(&nvmem_cell_mutex); -@@ -588,15 +592,13 @@ static int nvmem_add_cells_from_table(st - goto out; - } - -- rval = nvmem_cell_info_to_nvmem_cell(nvmem, -- info, -- cell); -+ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell); - if (rval) { - kfree(cell); - goto out; - } - -- nvmem_cell_add(cell); -+ nvmem_cell_entry_add(cell); - } - } - } -@@ -606,10 +608,10 @@ out: - return rval; - } - --static struct nvmem_cell * --nvmem_find_cell_by_name(struct nvmem_device *nvmem, const char *cell_id) -+static struct nvmem_cell_entry * -+nvmem_find_cell_entry_by_name(struct nvmem_device *nvmem, const char *cell_id) - { -- struct nvmem_cell *iter, *cell = NULL; -+ struct nvmem_cell_entry *iter, *cell = NULL; - - mutex_lock(&nvmem_mutex); - list_for_each_entry(iter, &nvmem->cells, node) { -@@ -680,7 +682,7 @@ static int nvmem_add_cells_from_of(struc - { - struct device_node *parent, *child; - struct device *dev = &nvmem->dev; -- struct nvmem_cell *cell; -+ struct nvmem_cell_entry *cell; - const __be32 *addr; - int len; - -@@ -729,7 +731,7 @@ static int nvmem_add_cells_from_of(struc - } - - cell->np = of_node_get(child); -- nvmem_cell_add(cell); -+ nvmem_cell_entry_add(cell); - } - - return 0; -@@ -1142,9 +1144,33 @@ struct nvmem_device *devm_nvmem_device_g - } - EXPORT_SYMBOL_GPL(devm_nvmem_device_get); - -+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id) -+{ -+ struct nvmem_cell *cell; -+ const char *name = NULL; -+ -+ cell = kzalloc(sizeof(*cell), GFP_KERNEL); -+ if (!cell) -+ return ERR_PTR(-ENOMEM); -+ -+ if (id) { -+ name = kstrdup_const(id, GFP_KERNEL); -+ if (!name) { -+ kfree(cell); -+ return ERR_PTR(-ENOMEM); -+ } -+ } -+ -+ cell->id = name; -+ cell->entry = entry; -+ -+ return cell; -+} -+ - static struct nvmem_cell * - nvmem_cell_get_from_lookup(struct device *dev, const char *con_id) - { -+ struct nvmem_cell_entry *cell_entry; - struct nvmem_cell *cell = ERR_PTR(-ENOENT); - struct nvmem_cell_lookup *lookup; - struct nvmem_device *nvmem; -@@ -1169,11 +1195,15 @@ nvmem_cell_get_from_lookup(struct device - break; - } - -- cell = nvmem_find_cell_by_name(nvmem, -- lookup->cell_name); -- if (!cell) { -+ cell_entry = nvmem_find_cell_entry_by_name(nvmem, -+ lookup->cell_name); -+ if (!cell_entry) { - __nvmem_device_put(nvmem); - cell = ERR_PTR(-ENOENT); -+ } else { -+ cell = nvmem_create_cell(cell_entry, con_id); -+ if (IS_ERR(cell)) -+ __nvmem_device_put(nvmem); - } - break; - } -@@ -1184,10 +1214,10 @@ nvmem_cell_get_from_lookup(struct device - } - - #if IS_ENABLED(CONFIG_OF) --static struct nvmem_cell * --nvmem_find_cell_by_node(struct nvmem_device *nvmem, struct device_node *np) -+static struct nvmem_cell_entry * -+nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np) - { -- struct nvmem_cell *iter, *cell = NULL; -+ struct nvmem_cell_entry *iter, *cell = NULL; - - mutex_lock(&nvmem_mutex); - list_for_each_entry(iter, &nvmem->cells, node) { -@@ -1217,6 +1247,7 @@ struct nvmem_cell *of_nvmem_cell_get(str - { - struct device_node *cell_np, *nvmem_np; - struct nvmem_device *nvmem; -+ struct nvmem_cell_entry *cell_entry; - struct nvmem_cell *cell; - int index = 0; - -@@ -1237,12 +1268,16 @@ struct nvmem_cell *of_nvmem_cell_get(str - if (IS_ERR(nvmem)) - return ERR_CAST(nvmem); - -- cell = nvmem_find_cell_by_node(nvmem, cell_np); -- if (!cell) { -+ cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np); -+ if (!cell_entry) { - __nvmem_device_put(nvmem); - return ERR_PTR(-ENOENT); - } - -+ cell = nvmem_create_cell(cell_entry, id); -+ if (IS_ERR(cell)) -+ __nvmem_device_put(nvmem); -+ - return cell; - } - EXPORT_SYMBOL_GPL(of_nvmem_cell_get); -@@ -1348,13 +1383,17 @@ EXPORT_SYMBOL(devm_nvmem_cell_put); - */ - void nvmem_cell_put(struct nvmem_cell *cell) - { -- struct nvmem_device *nvmem = cell->nvmem; -+ struct nvmem_device *nvmem = cell->entry->nvmem; -+ -+ if (cell->id) -+ kfree_const(cell->id); - -+ kfree(cell); - __nvmem_device_put(nvmem); - } - EXPORT_SYMBOL_GPL(nvmem_cell_put); - --static void nvmem_shift_read_buffer_in_place(struct nvmem_cell *cell, void *buf) -+static void nvmem_shift_read_buffer_in_place(struct nvmem_cell_entry *cell, void *buf) - { - u8 *p, *b; - int i, extra, bit_offset = cell->bit_offset; -@@ -1388,8 +1427,8 @@ static void nvmem_shift_read_buffer_in_p - } - - static int __nvmem_cell_read(struct nvmem_device *nvmem, -- struct nvmem_cell *cell, -- void *buf, size_t *len) -+ struct nvmem_cell_entry *cell, -+ void *buf, size_t *len, const char *id) - { - int rc; - -@@ -1420,18 +1459,18 @@ static int __nvmem_cell_read(struct nvme - */ - void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) - { -- struct nvmem_device *nvmem = cell->nvmem; -+ struct nvmem_device *nvmem = cell->entry->nvmem; - u8 *buf; - int rc; - - if (!nvmem) - return ERR_PTR(-EINVAL); - -- buf = kzalloc(cell->bytes, GFP_KERNEL); -+ buf = kzalloc(cell->entry->bytes, GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - -- rc = __nvmem_cell_read(nvmem, cell, buf, len); -+ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id); - if (rc) { - kfree(buf); - return ERR_PTR(rc); -@@ -1441,7 +1480,7 @@ void *nvmem_cell_read(struct nvmem_cell - } - EXPORT_SYMBOL_GPL(nvmem_cell_read); - --static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell *cell, -+static void *nvmem_cell_prepare_write_buffer(struct nvmem_cell_entry *cell, - u8 *_buf, int len) - { - struct nvmem_device *nvmem = cell->nvmem; -@@ -1494,16 +1533,7 @@ err: - return ERR_PTR(rc); - } - --/** -- * nvmem_cell_write() - Write to a given nvmem cell -- * -- * @cell: nvmem cell to be written. -- * @buf: Buffer to be written. -- * @len: length of buffer to be written to nvmem cell. -- * -- * Return: length of bytes written or negative on failure. -- */ --int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) -+static int __nvmem_cell_entry_write(struct nvmem_cell_entry *cell, void *buf, size_t len) - { - struct nvmem_device *nvmem = cell->nvmem; - int rc; -@@ -1529,6 +1559,21 @@ int nvmem_cell_write(struct nvmem_cell * - - return len; - } -+ -+/** -+ * nvmem_cell_write() - Write to a given nvmem cell -+ * -+ * @cell: nvmem cell to be written. -+ * @buf: Buffer to be written. -+ * @len: length of buffer to be written to nvmem cell. -+ * -+ * Return: length of bytes written or negative on failure. -+ */ -+int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len) -+{ -+ return __nvmem_cell_entry_write(cell->entry, buf, len); -+} -+ - EXPORT_SYMBOL_GPL(nvmem_cell_write); - - static int nvmem_cell_read_common(struct device *dev, const char *cell_id, -@@ -1631,7 +1676,7 @@ static const void *nvmem_cell_read_varia - if (IS_ERR(cell)) - return cell; - -- nbits = cell->nbits; -+ nbits = cell->entry->nbits; - buf = nvmem_cell_read(cell, len); - nvmem_cell_put(cell); - if (IS_ERR(buf)) -@@ -1727,18 +1772,18 @@ EXPORT_SYMBOL_GPL(nvmem_cell_read_variab - ssize_t nvmem_device_cell_read(struct nvmem_device *nvmem, - struct nvmem_cell_info *info, void *buf) - { -- struct nvmem_cell cell; -+ struct nvmem_cell_entry cell; - int rc; - ssize_t len; - - if (!nvmem) - return -EINVAL; - -- rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell); -+ rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell); - if (rc) - return rc; - -- rc = __nvmem_cell_read(nvmem, &cell, buf, &len); -+ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL); - if (rc) - return rc; - -@@ -1758,17 +1803,17 @@ EXPORT_SYMBOL_GPL(nvmem_device_cell_read - int nvmem_device_cell_write(struct nvmem_device *nvmem, - struct nvmem_cell_info *info, void *buf) - { -- struct nvmem_cell cell; -+ struct nvmem_cell_entry cell; - int rc; - - if (!nvmem) - return -EINVAL; - -- rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell); -+ rc = nvmem_cell_info_to_nvmem_cell_entry_nodup(nvmem, info, &cell); - if (rc) - return rc; - -- return nvmem_cell_write(&cell, buf, cell.bytes); -+ return __nvmem_cell_entry_write(&cell, buf, cell.bytes); - } - EXPORT_SYMBOL_GPL(nvmem_device_cell_write); - diff --git a/target/linux/generic/backport-5.15/802-v5.16-0002-nvmem-core-add-nvmem-cell-post-processing-callback.patch b/target/linux/generic/backport-5.15/802-v5.16-0002-nvmem-core-add-nvmem-cell-post-processing-callback.patch deleted file mode 100644 index df264add24524a..00000000000000 --- a/target/linux/generic/backport-5.15/802-v5.16-0002-nvmem-core-add-nvmem-cell-post-processing-callback.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 5008062f1c3f5af3acf86164aa6fcc77b0c7bdce Mon Sep 17 00:00:00 2001 -From: Srinivas Kandagatla -Date: Wed, 13 Oct 2021 14:19:56 +0100 -Subject: [PATCH] nvmem: core: add nvmem cell post processing callback - -Some NVMEM providers have certain nvmem cells encoded, which requires -post processing before actually using it. - -For example mac-address is stored in either in ascii or delimited or reverse-order. - -Having a post-process callback hook to provider drivers would enable them to -do this vendor specific post processing before nvmem consumers see it. - -Tested-by: Joakim Zhang -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20211013131957.30271-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 9 +++++++++ - include/linux/nvmem-provider.h | 5 +++++ - 2 files changed, 14 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -38,6 +38,7 @@ struct nvmem_device { - unsigned int nkeepout; - nvmem_reg_read_t reg_read; - nvmem_reg_write_t reg_write; -+ nvmem_cell_post_process_t cell_post_process; - struct gpio_desc *wp_gpio; - void *priv; - }; -@@ -799,6 +800,7 @@ struct nvmem_device *nvmem_register(cons - nvmem->type = config->type; - nvmem->reg_read = config->reg_read; - nvmem->reg_write = config->reg_write; -+ nvmem->cell_post_process = config->cell_post_process; - nvmem->keepout = config->keepout; - nvmem->nkeepout = config->nkeepout; - if (config->of_node) -@@ -1441,6 +1443,13 @@ static int __nvmem_cell_read(struct nvme - if (cell->bit_offset || cell->nbits) - nvmem_shift_read_buffer_in_place(cell, buf); - -+ if (nvmem->cell_post_process) { -+ rc = nvmem->cell_post_process(nvmem->priv, id, -+ cell->offset, buf, cell->bytes); -+ if (rc) -+ return rc; -+ } -+ - if (len) - *len = cell->bytes; - ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -19,6 +19,9 @@ typedef int (*nvmem_reg_read_t)(void *pr - void *val, size_t bytes); - typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, - void *val, size_t bytes); -+/* used for vendor specific post processing of cell data */ -+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset, -+ void *buf, size_t bytes); - - enum nvmem_type { - NVMEM_TYPE_UNKNOWN = 0, -@@ -62,6 +65,7 @@ struct nvmem_keepout { - * @no_of_node: Device should not use the parent's of_node even if it's !NULL. - * @reg_read: Callback to read data. - * @reg_write: Callback to write data. -+ * @cell_post_process: Callback for vendor specific post processing of cell data - * @size: Device size. - * @word_size: Minimum read/write access granularity. - * @stride: Minimum read/write access stride. -@@ -92,6 +96,7 @@ struct nvmem_config { - bool no_of_node; - nvmem_reg_read_t reg_read; - nvmem_reg_write_t reg_write; -+ nvmem_cell_post_process_t cell_post_process; - int size; - int word_size; - int stride; diff --git a/target/linux/generic/backport-5.15/802-v5.16-0003-nvmem-imx-ocotp-add-support-for-post-processing.patch b/target/linux/generic/backport-5.15/802-v5.16-0003-nvmem-imx-ocotp-add-support-for-post-processing.patch deleted file mode 100644 index ee19228270d101..00000000000000 --- a/target/linux/generic/backport-5.15/802-v5.16-0003-nvmem-imx-ocotp-add-support-for-post-processing.patch +++ /dev/null @@ -1,92 +0,0 @@ -From d0221a780cbc99fec6c27a98dba2828dc5735c00 Mon Sep 17 00:00:00 2001 -From: Srinivas Kandagatla -Date: Wed, 13 Oct 2021 14:19:57 +0100 -Subject: [PATCH] nvmem: imx-ocotp: add support for post processing - -Add .cell_post_process callback for imx-ocotp to deal with MAC address, -since MAC address need to be reversed byte for some i.MX SoCs. - -Tested-by: Joakim Zhang -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20211013131957.30271-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/imx-ocotp.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -97,6 +97,7 @@ struct ocotp_params { - unsigned int bank_address_words; - void (*set_timing)(struct ocotp_priv *priv); - struct ocotp_ctrl_reg ctrl; -+ bool reverse_mac_address; - }; - - static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags) -@@ -221,6 +222,25 @@ read_end: - return ret; - } - -+static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset, -+ void *data, size_t bytes) -+{ -+ struct ocotp_priv *priv = context; -+ -+ /* Deal with some post processing of nvmem cell data */ -+ if (id && !strcmp(id, "mac-address")) { -+ if (priv->params->reverse_mac_address) { -+ u8 *buf = data; -+ int i; -+ -+ for (i = 0; i < bytes/2; i++) -+ swap(buf[i], buf[bytes - i - 1]); -+ } -+ } -+ -+ return 0; -+} -+ - static void imx_ocotp_set_imx6_timing(struct ocotp_priv *priv) - { - unsigned long clk_rate; -@@ -468,6 +488,7 @@ static struct nvmem_config imx_ocotp_nvm - .stride = 1, - .reg_read = imx_ocotp_read, - .reg_write = imx_ocotp_write, -+ .cell_post_process = imx_ocotp_cell_pp, - }; - - static const struct ocotp_params imx6q_params = { -@@ -530,6 +551,7 @@ static const struct ocotp_params imx8mq_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -+ .reverse_mac_address = true, - }; - - static const struct ocotp_params imx8mm_params = { -@@ -537,6 +559,7 @@ static const struct ocotp_params imx8mm_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -+ .reverse_mac_address = true, - }; - - static const struct ocotp_params imx8mn_params = { -@@ -544,6 +567,7 @@ static const struct ocotp_params imx8mn_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -+ .reverse_mac_address = true, - }; - - static const struct ocotp_params imx8mp_params = { -@@ -551,6 +575,7 @@ static const struct ocotp_params imx8mp_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_8MP, -+ .reverse_mac_address = true, - }; - - static const struct of_device_id imx_ocotp_dt_ids[] = { diff --git a/target/linux/generic/backport-5.15/803-v5.17-0002-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch b/target/linux/generic/backport-5.15/803-v5.17-0002-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch deleted file mode 100644 index 785bfe53f547ab..00000000000000 --- a/target/linux/generic/backport-5.15/803-v5.17-0002-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 98e2c4efae214fb7086cac9117616eb6ea11475d Mon Sep 17 00:00:00 2001 -From: Chunfeng Yun -Date: Thu, 9 Dec 2021 17:42:34 +0000 -Subject: [PATCH] nvmem: mtk-efuse: support minimum one byte access stride and - granularity - -In order to support nvmem bits property, should support minimum 1 byte -read stride and minimum 1 byte read granularity at the same time. - -Signed-off-by: Chunfeng Yun -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20211209174235.14049-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/mtk-efuse.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -19,11 +19,12 @@ static int mtk_reg_read(void *context, - unsigned int reg, void *_val, size_t bytes) - { - struct mtk_efuse_priv *priv = context; -- u32 *val = _val; -- int i = 0, words = bytes / 4; -+ void __iomem *addr = priv->base + reg; -+ u8 *val = _val; -+ int i; - -- while (words--) -- *val++ = readl(priv->base + reg + (i++ * 4)); -+ for (i = 0; i < bytes; i++, val++) -+ *val = readb(addr + i); - - return 0; - } -@@ -45,8 +46,8 @@ static int mtk_efuse_probe(struct platfo - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - -- econfig.stride = 4; -- econfig.word_size = 4; -+ econfig.stride = 1; -+ econfig.word_size = 1; - econfig.reg_read = mtk_reg_read; - econfig.size = resource_size(res); - econfig.priv = priv; diff --git a/target/linux/generic/backport-5.15/804-v5.18-0001-nvmem-core-Remove-unused-devm_nvmem_unregister.patch b/target/linux/generic/backport-5.15/804-v5.18-0001-nvmem-core-Remove-unused-devm_nvmem_unregister.patch deleted file mode 100644 index ca5357c8d9886e..00000000000000 --- a/target/linux/generic/backport-5.15/804-v5.18-0001-nvmem-core-Remove-unused-devm_nvmem_unregister.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 190fae468592bc2f0efc8b928920f8f712b5831e Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Sun, 20 Feb 2022 15:15:15 +0000 -Subject: [PATCH] nvmem: core: Remove unused devm_nvmem_unregister() - -There are no users and seems no will come of the devm_nvmem_unregister(). -Remove the function and remove the unused devm_nvmem_match() along with it. - -Signed-off-by: Andy Shevchenko -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220220151527.17216-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 22 ---------------------- - include/linux/nvmem-provider.h | 8 -------- - 2 files changed, 30 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -943,28 +943,6 @@ struct nvmem_device *devm_nvmem_register - } - EXPORT_SYMBOL_GPL(devm_nvmem_register); - --static int devm_nvmem_match(struct device *dev, void *res, void *data) --{ -- struct nvmem_device **r = res; -- -- return *r == data; --} -- --/** -- * devm_nvmem_unregister() - Unregister previously registered managed nvmem -- * device. -- * -- * @dev: Device that uses the nvmem device. -- * @nvmem: Pointer to previously registered nvmem device. -- * -- * Return: Will be negative on error or zero on success. -- */ --int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem) --{ -- return devres_release(dev, devm_nvmem_release, devm_nvmem_match, nvmem); --} --EXPORT_SYMBOL(devm_nvmem_unregister); -- - static struct nvmem_device *__nvmem_device_get(void *data, - int (*match)(struct device *dev, const void *data)) - { ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -133,8 +133,6 @@ void nvmem_unregister(struct nvmem_devic - struct nvmem_device *devm_nvmem_register(struct device *dev, - const struct nvmem_config *cfg); - --int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem); -- - void nvmem_add_cell_table(struct nvmem_cell_table *table); - void nvmem_del_cell_table(struct nvmem_cell_table *table); - -@@ -153,12 +151,6 @@ devm_nvmem_register(struct device *dev, - return nvmem_register(c); - } - --static inline int --devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem) --{ -- return -EOPNOTSUPP; --} -- - static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} - static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} - diff --git a/target/linux/generic/backport-5.15/804-v5.18-0002-nvmem-core-Use-devm_add_action_or_reset.patch b/target/linux/generic/backport-5.15/804-v5.18-0002-nvmem-core-Use-devm_add_action_or_reset.patch deleted file mode 100644 index b71a0a365b2166..00000000000000 --- a/target/linux/generic/backport-5.15/804-v5.18-0002-nvmem-core-Use-devm_add_action_or_reset.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 5825b2c6762611e67ccaf3ccf64485365a120f0b Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Sun, 20 Feb 2022 15:15:16 +0000 -Subject: [PATCH] nvmem: core: Use devm_add_action_or_reset() - -Slightly simplify the devm_nvmem_register() by using the -devm_add_action_or_reset(). - -Signed-off-by: Andy Shevchenko -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220220151527.17216-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 22 +++++++++------------- - 1 file changed, 9 insertions(+), 13 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -905,9 +905,9 @@ void nvmem_unregister(struct nvmem_devic - } - EXPORT_SYMBOL_GPL(nvmem_unregister); - --static void devm_nvmem_release(struct device *dev, void *res) -+static void devm_nvmem_unregister(void *nvmem) - { -- nvmem_unregister(*(struct nvmem_device **)res); -+ nvmem_unregister(nvmem); - } - - /** -@@ -924,20 +924,16 @@ static void devm_nvmem_release(struct de - struct nvmem_device *devm_nvmem_register(struct device *dev, - const struct nvmem_config *config) - { -- struct nvmem_device **ptr, *nvmem; -- -- ptr = devres_alloc(devm_nvmem_release, sizeof(*ptr), GFP_KERNEL); -- if (!ptr) -- return ERR_PTR(-ENOMEM); -+ struct nvmem_device *nvmem; -+ int ret; - - nvmem = nvmem_register(config); -+ if (IS_ERR(nvmem)) -+ return nvmem; - -- if (!IS_ERR(nvmem)) { -- *ptr = nvmem; -- devres_add(dev, ptr); -- } else { -- devres_free(ptr); -- } -+ ret = devm_add_action_or_reset(dev, devm_nvmem_unregister, nvmem); -+ if (ret) -+ return ERR_PTR(ret); - - return nvmem; - } diff --git a/target/linux/generic/backport-5.15/804-v5.18-0003-nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch b/target/linux/generic/backport-5.15/804-v5.18-0003-nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch deleted file mode 100644 index 4f471f266738ba..00000000000000 --- a/target/linux/generic/backport-5.15/804-v5.18-0003-nvmem-core-Check-input-parameter-for-NULL-in-nvmem_u.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8c751e0d9a5264376935a84429a2d468c8877d99 Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Sun, 20 Feb 2022 15:15:17 +0000 -Subject: [PATCH] nvmem: core: Check input parameter for NULL in - nvmem_unregister() - -nvmem_unregister() frees resources and standard pattern is to allow -caller to not care if it's NULL or not. This will reduce burden on -the callers to perform this check. - -Signed-off-by: Andy Shevchenko -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220220151527.17216-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -901,7 +901,8 @@ static void nvmem_device_release(struct - */ - void nvmem_unregister(struct nvmem_device *nvmem) - { -- kref_put(&nvmem->refcnt, nvmem_device_release); -+ if (nvmem) -+ kref_put(&nvmem->refcnt, nvmem_device_release); - } - EXPORT_SYMBOL_GPL(nvmem_unregister); - diff --git a/target/linux/generic/backport-5.15/804-v5.18-0004-nvmem-qfprom-fix-kerneldoc-warning.patch b/target/linux/generic/backport-5.15/804-v5.18-0004-nvmem-qfprom-fix-kerneldoc-warning.patch deleted file mode 100644 index c98f8e9d545e90..00000000000000 --- a/target/linux/generic/backport-5.15/804-v5.18-0004-nvmem-qfprom-fix-kerneldoc-warning.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 05196facc052385960028ac634447ecf6c764ec3 Mon Sep 17 00:00:00 2001 -From: Srinivas Kandagatla -Date: Sun, 20 Feb 2022 15:15:18 +0000 -Subject: [PATCH] nvmem: qfprom: fix kerneldoc warning - -This patch fixes below kernel doc warning, -warning: expecting prototype for qfprom_efuse_reg_write(). -Prototype was for qfprom_reg_write() instead - -No code changes. - -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220220151527.17216-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/qfprom.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/qfprom.c -+++ b/drivers/nvmem/qfprom.c -@@ -244,7 +244,7 @@ err_clk_prepared: - } - - /** -- * qfprom_efuse_reg_write() - Write to fuses. -+ * qfprom_reg_write() - Write to fuses. - * @context: Our driver data. - * @reg: The offset to write at. - * @_val: Pointer to data to write. diff --git a/target/linux/generic/backport-5.15/804-v5.18-0005-nvmem-sunxi_sid-Add-support-for-D1-variant.patch b/target/linux/generic/backport-5.15/804-v5.18-0005-nvmem-sunxi_sid-Add-support-for-D1-variant.patch deleted file mode 100644 index 6aad6af0800c55..00000000000000 --- a/target/linux/generic/backport-5.15/804-v5.18-0005-nvmem-sunxi_sid-Add-support-for-D1-variant.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 07ae4fde9efada7878e1383d6ccc7da70315ca23 Mon Sep 17 00:00:00 2001 -From: Samuel Holland -Date: Sun, 20 Feb 2022 15:15:20 +0000 -Subject: [PATCH] nvmem: sunxi_sid: Add support for D1 variant - -D1 has a smaller eFuse block than some other recent SoCs, and it no -longer requires a workaround to read the eFuse data. - -Signed-off-by: Samuel Holland -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220220151527.17216-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sunxi_sid.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/nvmem/sunxi_sid.c -+++ b/drivers/nvmem/sunxi_sid.c -@@ -184,6 +184,11 @@ static const struct sunxi_sid_cfg sun8i_ - .need_register_readout = true, - }; - -+static const struct sunxi_sid_cfg sun20i_d1_cfg = { -+ .value_offset = 0x200, -+ .size = 0x100, -+}; -+ - static const struct sunxi_sid_cfg sun50i_a64_cfg = { - .value_offset = 0x200, - .size = 0x100, -@@ -200,6 +205,7 @@ static const struct of_device_id sunxi_s - { .compatible = "allwinner,sun7i-a20-sid", .data = &sun7i_a20_cfg }, - { .compatible = "allwinner,sun8i-a83t-sid", .data = &sun50i_a64_cfg }, - { .compatible = "allwinner,sun8i-h3-sid", .data = &sun8i_h3_cfg }, -+ { .compatible = "allwinner,sun20i-d1-sid", .data = &sun20i_d1_cfg }, - { .compatible = "allwinner,sun50i-a64-sid", .data = &sun50i_a64_cfg }, - { .compatible = "allwinner,sun50i-h5-sid", .data = &sun50i_a64_cfg }, - { .compatible = "allwinner,sun50i-h6-sid", .data = &sun50i_h6_cfg }, diff --git a/target/linux/generic/backport-5.15/804-v5.18-0006-nvmem-meson-mx-efuse-replace-unnecessary-devm_kstrdu.patch b/target/linux/generic/backport-5.15/804-v5.18-0006-nvmem-meson-mx-efuse-replace-unnecessary-devm_kstrdu.patch deleted file mode 100644 index a73b42c5de3c68..00000000000000 --- a/target/linux/generic/backport-5.15/804-v5.18-0006-nvmem-meson-mx-efuse-replace-unnecessary-devm_kstrdu.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 4dc8d89faed9bb05f116fa1794fc955b14910386 Mon Sep 17 00:00:00 2001 -From: Xiaoke Wang -Date: Sun, 20 Feb 2022 15:15:21 +0000 -Subject: [PATCH] nvmem: meson-mx-efuse: replace unnecessary devm_kstrdup() - -Replace unnecessary devm_kstrdup() so to avoid redundant memory allocation. - -Suggested-by: Martin Blumenstingl -Signed-off-by: Xiaoke Wang -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220220151527.17216-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/meson-mx-efuse.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/meson-mx-efuse.c -+++ b/drivers/nvmem/meson-mx-efuse.c -@@ -209,8 +209,7 @@ static int meson_mx_efuse_probe(struct p - if (IS_ERR(efuse->base)) - return PTR_ERR(efuse->base); - -- efuse->config.name = devm_kstrdup(&pdev->dev, drvdata->name, -- GFP_KERNEL); -+ efuse->config.name = drvdata->name; - efuse->config.owner = THIS_MODULE; - efuse->config.dev = &pdev->dev; - efuse->config.priv = efuse; diff --git a/target/linux/generic/backport-5.15/804-v5.18-0007-nvmem-add-driver-for-Layerscape-SFP-Security-Fuse-Pr.patch b/target/linux/generic/backport-5.15/804-v5.18-0007-nvmem-add-driver-for-Layerscape-SFP-Security-Fuse-Pr.patch deleted file mode 100644 index 6afb68b3f91bb9..00000000000000 --- a/target/linux/generic/backport-5.15/804-v5.18-0007-nvmem-add-driver-for-Layerscape-SFP-Security-Fuse-Pr.patch +++ /dev/null @@ -1,139 +0,0 @@ -From f78451012b9e159afdba31c3eb69f223a9f42adc Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Sun, 20 Feb 2022 15:15:23 +0000 -Subject: [PATCH] nvmem: add driver for Layerscape SFP (Security Fuse - Processor) - -Add support for the Security Fuse Processor found on Layerscape SoCs. -This driver implements basic read access. - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220220151527.17216-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 12 +++++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/layerscape-sfp.c | 89 ++++++++++++++++++++++++++++++++++ - 3 files changed, 103 insertions(+) - create mode 100644 drivers/nvmem/layerscape-sfp.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -300,4 +300,16 @@ config NVMEM_BRCM_NVRAM - This driver provides support for Broadcom's NVRAM that can be accessed - using I/O mapping. - -+config NVMEM_LAYERSCAPE_SFP -+ tristate "Layerscape SFP (Security Fuse Processor) support" -+ depends on ARCH_LAYERSCAPE || COMPILE_TEST -+ depends on HAS_IOMEM -+ help -+ This driver provides support to read the eFuses on Freescale -+ Layerscape SoC's. For example, the vendor provides a per part -+ unique ID there. -+ -+ This driver can also be built as a module. If so, the module -+ will be called layerscape-sfp. -+ - endif ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -61,3 +61,5 @@ obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem. - nvmem-rmem-y := rmem.o - obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o - nvmem_brcm_nvram-y := brcm_nvram.o -+obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nvmem-layerscape-sfp.o -+nvmem-layerscape-sfp-y := layerscape-sfp.o ---- /dev/null -+++ b/drivers/nvmem/layerscape-sfp.c -@@ -0,0 +1,89 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Layerscape SFP driver -+ * -+ * Copyright (c) 2022 Michael Walle -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define LAYERSCAPE_SFP_OTP_OFFSET 0x0200 -+ -+struct layerscape_sfp_priv { -+ void __iomem *base; -+}; -+ -+struct layerscape_sfp_data { -+ int size; -+}; -+ -+static int layerscape_sfp_read(void *context, unsigned int offset, void *val, -+ size_t bytes) -+{ -+ struct layerscape_sfp_priv *priv = context; -+ -+ memcpy_fromio(val, priv->base + LAYERSCAPE_SFP_OTP_OFFSET + offset, -+ bytes); -+ -+ return 0; -+} -+ -+static struct nvmem_config layerscape_sfp_nvmem_config = { -+ .name = "fsl-sfp", -+ .reg_read = layerscape_sfp_read, -+}; -+ -+static int layerscape_sfp_probe(struct platform_device *pdev) -+{ -+ const struct layerscape_sfp_data *data; -+ struct layerscape_sfp_priv *priv; -+ struct nvmem_device *nvmem; -+ -+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(priv->base)) -+ return PTR_ERR(priv->base); -+ -+ data = device_get_match_data(&pdev->dev); -+ -+ layerscape_sfp_nvmem_config.size = data->size; -+ layerscape_sfp_nvmem_config.dev = &pdev->dev; -+ layerscape_sfp_nvmem_config.priv = priv; -+ -+ nvmem = devm_nvmem_register(&pdev->dev, &layerscape_sfp_nvmem_config); -+ -+ return PTR_ERR_OR_ZERO(nvmem); -+} -+ -+static const struct layerscape_sfp_data ls1028a_data = { -+ .size = 0x88, -+}; -+ -+static const struct of_device_id layerscape_sfp_dt_ids[] = { -+ { .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, layerscape_sfp_dt_ids); -+ -+static struct platform_driver layerscape_sfp_driver = { -+ .probe = layerscape_sfp_probe, -+ .driver = { -+ .name = "layerscape_sfp", -+ .of_match_table = layerscape_sfp_dt_ids, -+ }, -+}; -+module_platform_driver(layerscape_sfp_driver); -+ -+MODULE_AUTHOR("Michael Walle "); -+MODULE_DESCRIPTION("Layerscape Security Fuse Processor driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-5.15/804-v5.18-0008-nvmem-qfprom-Increase-fuse-blow-timeout-to-prevent-w.patch b/target/linux/generic/backport-5.15/804-v5.18-0008-nvmem-qfprom-Increase-fuse-blow-timeout-to-prevent-w.patch deleted file mode 100644 index 74bd4a7eb67636..00000000000000 --- a/target/linux/generic/backport-5.15/804-v5.18-0008-nvmem-qfprom-Increase-fuse-blow-timeout-to-prevent-w.patch +++ /dev/null @@ -1,32 +0,0 @@ -From bc5c75e0a5a9400f81a987cc720100ac475fa4d8 Mon Sep 17 00:00:00 2001 -From: Knox Chiou -Date: Wed, 23 Feb 2022 22:35:00 +0000 -Subject: [PATCH] nvmem: qfprom: Increase fuse blow timeout to prevent write - fail - -sc7180 blow fuses got slightly chances to hit qfprom_reg_write timeout. -Current timeout is simply too low. Since blowing fuses is a -very rare operation, so the risk associated with overestimating this -number is low. -Increase fuse blow timeout from 1ms to 10ms. - -Reviewed-by: Douglas Anderson -Signed-off-by: Knox Chiou -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220223223502.29454-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/qfprom.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/qfprom.c -+++ b/drivers/nvmem/qfprom.c -@@ -22,7 +22,7 @@ - - /* Amount of time required to hold charge to blow fuse in micro-seconds */ - #define QFPROM_FUSE_BLOW_POLL_US 100 --#define QFPROM_FUSE_BLOW_TIMEOUT_US 1000 -+#define QFPROM_FUSE_BLOW_TIMEOUT_US 10000 - - #define QFPROM_BLOW_STATUS_OFFSET 0x048 - #define QFPROM_BLOW_STATUS_BUSY 0x1 diff --git a/target/linux/generic/backport-5.15/804-v5.18-0009-nvmem-Add-driver-for-OCOTP-in-Sunplus-SP7021.patch b/target/linux/generic/backport-5.15/804-v5.18-0009-nvmem-Add-driver-for-OCOTP-in-Sunplus-SP7021.patch deleted file mode 100644 index ac77fc9b1d2edb..00000000000000 --- a/target/linux/generic/backport-5.15/804-v5.18-0009-nvmem-Add-driver-for-OCOTP-in-Sunplus-SP7021.patch +++ /dev/null @@ -1,291 +0,0 @@ -From 8747ec2e9762ed9ae53b3a590938f454b6a1abdf Mon Sep 17 00:00:00 2001 -From: Vincent Shih -Date: Wed, 23 Feb 2022 22:35:01 +0000 -Subject: [PATCH] nvmem: Add driver for OCOTP in Sunplus SP7021 - -Add driver for OCOTP in Sunplus SP7021 - -Signed-off-by: Vincent Shih -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220223223502.29454-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - MAINTAINERS | 5 + - drivers/nvmem/Kconfig | 12 ++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/sunplus-ocotp.c | 228 ++++++++++++++++++++++++++++++++++ - 4 files changed, 247 insertions(+) - create mode 100644 drivers/nvmem/sunplus-ocotp.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -17966,6 +17966,11 @@ L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/ethernet/dlink/sundance.c - -+SUNPLUS OCOTP DRIVER -+M: Vincent Shih -+S: Maintained -+F: drivers/nvmem/sunplus-ocotp.c -+ - SUPERH - M: Yoshinori Sato - M: Rich Felker ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -312,4 +312,16 @@ config NVMEM_LAYERSCAPE_SFP - This driver can also be built as a module. If so, the module - will be called layerscape-sfp. - -+config NVMEM_SUNPLUS_OCOTP -+ tristate "Sunplus SoC OTP support" -+ depends on SOC_SP7021 || COMPILE_TEST -+ depends on HAS_IOMEM -+ help -+ This is a driver for the On-chip OTP controller (OCOTP) available -+ on Sunplus SoCs. It provides access to 128 bytes of one-time -+ programmable eFuse. -+ -+ This driver can also be built as a module. If so, the module -+ will be called nvmem-sunplus-ocotp. -+ - endif ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -63,3 +63,5 @@ obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_ - nvmem_brcm_nvram-y := brcm_nvram.o - obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nvmem-layerscape-sfp.o - nvmem-layerscape-sfp-y := layerscape-sfp.o -+obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o -+nvmem_sunplus_ocotp-y := sunplus-ocotp.o ---- /dev/null -+++ b/drivers/nvmem/sunplus-ocotp.c -@@ -0,0 +1,228 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+/* -+ * The OCOTP driver for Sunplus SP7021 -+ * -+ * Copyright (C) 2019 Sunplus Technology Inc., All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * OTP memory -+ * Each bank contains 4 words (32 bits). -+ * Bank 0 starts at offset 0 from the base. -+ */ -+ -+#define OTP_WORDS_PER_BANK 4 -+#define OTP_WORD_SIZE sizeof(u32) -+#define OTP_BIT_ADDR_OF_BANK (8 * OTP_WORD_SIZE * OTP_WORDS_PER_BANK) -+#define QAC628_OTP_NUM_BANKS 8 -+#define QAC628_OTP_SIZE (QAC628_OTP_NUM_BANKS * OTP_WORDS_PER_BANK * OTP_WORD_SIZE) -+#define OTP_READ_TIMEOUT_US 200000 -+ -+/* HB_GPIO */ -+#define ADDRESS_8_DATA 0x20 -+ -+/* OTP_RX */ -+#define OTP_CONTROL_2 0x48 -+#define OTP_RD_PERIOD GENMASK(15, 8) -+#define OTP_RD_PERIOD_MASK ~GENMASK(15, 8) -+#define CPU_CLOCK FIELD_PREP(OTP_RD_PERIOD, 30) -+#define SEL_BAK_KEY2 BIT(5) -+#define SEL_BAK_KEY2_MASK ~BIT(5) -+#define SW_TRIM_EN BIT(4) -+#define SW_TRIM_EN_MASK ~BIT(4) -+#define SEL_BAK_KEY BIT(3) -+#define SEL_BAK_KEY_MASK ~BIT(3) -+#define OTP_READ BIT(2) -+#define OTP_LOAD_SECURE_DATA BIT(1) -+#define OTP_LOAD_SECURE_DATA_MASK ~BIT(1) -+#define OTP_DO_CRC BIT(0) -+#define OTP_DO_CRC_MASK ~BIT(0) -+#define OTP_STATUS 0x4c -+#define OTP_READ_DONE BIT(4) -+#define OTP_READ_DONE_MASK ~BIT(4) -+#define OTP_LOAD_SECURE_DONE_MASK ~BIT(2) -+#define OTP_READ_ADDRESS 0x50 -+ -+enum base_type { -+ HB_GPIO, -+ OTPRX, -+ BASEMAX, -+}; -+ -+struct sp_ocotp_priv { -+ struct device *dev; -+ void __iomem *base[BASEMAX]; -+ struct clk *clk; -+}; -+ -+struct sp_ocotp_data { -+ int size; -+}; -+ -+const struct sp_ocotp_data sp_otp_v0 = { -+ .size = QAC628_OTP_SIZE, -+}; -+ -+static int sp_otp_read_real(struct sp_ocotp_priv *otp, int addr, char *value) -+{ -+ unsigned int addr_data; -+ unsigned int byte_shift; -+ unsigned int status; -+ int ret; -+ -+ addr_data = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK); -+ addr_data = addr_data / OTP_WORD_SIZE; -+ -+ byte_shift = addr % (OTP_WORD_SIZE * OTP_WORDS_PER_BANK); -+ byte_shift = byte_shift % OTP_WORD_SIZE; -+ -+ addr = addr / (OTP_WORD_SIZE * OTP_WORDS_PER_BANK); -+ addr = addr * OTP_BIT_ADDR_OF_BANK; -+ -+ writel(readl(otp->base[OTPRX] + OTP_STATUS) & OTP_READ_DONE_MASK & -+ OTP_LOAD_SECURE_DONE_MASK, otp->base[OTPRX] + OTP_STATUS); -+ writel(addr, otp->base[OTPRX] + OTP_READ_ADDRESS); -+ writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) | OTP_READ, -+ otp->base[OTPRX] + OTP_CONTROL_2); -+ writel(readl(otp->base[OTPRX] + OTP_CONTROL_2) & SEL_BAK_KEY2_MASK & SW_TRIM_EN_MASK -+ & SEL_BAK_KEY_MASK & OTP_LOAD_SECURE_DATA_MASK & OTP_DO_CRC_MASK, -+ otp->base[OTPRX] + OTP_CONTROL_2); -+ writel((readl(otp->base[OTPRX] + OTP_CONTROL_2) & OTP_RD_PERIOD_MASK) | CPU_CLOCK, -+ otp->base[OTPRX] + OTP_CONTROL_2); -+ -+ ret = readl_poll_timeout(otp->base[OTPRX] + OTP_STATUS, status, -+ status & OTP_READ_DONE, 10, OTP_READ_TIMEOUT_US); -+ -+ if (ret < 0) -+ return ret; -+ -+ *value = (readl(otp->base[HB_GPIO] + ADDRESS_8_DATA + addr_data * OTP_WORD_SIZE) -+ >> (8 * byte_shift)) & 0xff; -+ -+ return ret; -+} -+ -+static int sp_ocotp_read(void *priv, unsigned int offset, void *value, size_t bytes) -+{ -+ struct sp_ocotp_priv *otp = priv; -+ unsigned int addr; -+ char *buf = value; -+ char val[4]; -+ int ret; -+ -+ ret = clk_enable(otp->clk); -+ if (ret) -+ return ret; -+ -+ *buf = 0; -+ for (addr = offset; addr < (offset + bytes); addr++) { -+ ret = sp_otp_read_real(otp, addr, val); -+ if (ret < 0) { -+ dev_err(otp->dev, "OTP read fail:%d at %d", ret, addr); -+ goto disable_clk; -+ } -+ -+ *buf++ = *val; -+ } -+ -+disable_clk: -+ clk_disable(otp->clk); -+ -+ return ret; -+} -+ -+static struct nvmem_config sp_ocotp_nvmem_config = { -+ .name = "sp-ocotp", -+ .read_only = true, -+ .word_size = 1, -+ .size = QAC628_OTP_SIZE, -+ .stride = 1, -+ .reg_read = sp_ocotp_read, -+ .owner = THIS_MODULE, -+}; -+ -+static int sp_ocotp_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct nvmem_device *nvmem; -+ struct sp_ocotp_priv *otp; -+ struct resource *res; -+ int ret; -+ -+ otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL); -+ if (!otp) -+ return -ENOMEM; -+ -+ otp->dev = dev; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio"); -+ otp->base[HB_GPIO] = devm_ioremap_resource(dev, res); -+ if (IS_ERR(otp->base[HB_GPIO])) -+ return PTR_ERR(otp->base[HB_GPIO]); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx"); -+ otp->base[OTPRX] = devm_ioremap_resource(dev, res); -+ if (IS_ERR(otp->base[OTPRX])) -+ return PTR_ERR(otp->base[OTPRX]); -+ -+ otp->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(otp->clk)) -+ return dev_err_probe(&pdev->dev, PTR_ERR(otp->clk), -+ "devm_clk_get fail\n"); -+ -+ ret = clk_prepare(otp->clk); -+ if (ret < 0) { -+ dev_err(dev, "failed to prepare clk: %d\n", ret); -+ return ret; -+ } -+ -+ sp_ocotp_nvmem_config.priv = otp; -+ sp_ocotp_nvmem_config.dev = dev; -+ -+ nvmem = devm_nvmem_register(dev, &sp_ocotp_nvmem_config); -+ if (IS_ERR(nvmem)) -+ return dev_err_probe(&pdev->dev, PTR_ERR(nvmem), -+ "register nvmem device fail\n"); -+ -+ platform_set_drvdata(pdev, nvmem); -+ -+ dev_dbg(dev, "banks:%d x wpb:%d x wsize:%d = %d", -+ (int)QAC628_OTP_NUM_BANKS, (int)OTP_WORDS_PER_BANK, -+ (int)OTP_WORD_SIZE, (int)QAC628_OTP_SIZE); -+ -+ dev_info(dev, "by Sunplus (C) 2020"); -+ -+ return 0; -+} -+ -+static const struct of_device_id sp_ocotp_dt_ids[] = { -+ { .compatible = "sunplus,sp7021-ocotp", .data = &sp_otp_v0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, sp_ocotp_dt_ids); -+ -+static struct platform_driver sp_otp_driver = { -+ .probe = sp_ocotp_probe, -+ .driver = { -+ .name = "sunplus,sp7021-ocotp", -+ .of_match_table = sp_ocotp_dt_ids, -+ } -+}; -+module_platform_driver(sp_otp_driver); -+ -+MODULE_AUTHOR("Vincent Shih "); -+MODULE_DESCRIPTION("Sunplus On-Chip OTP driver"); -+MODULE_LICENSE("GPL"); -+ diff --git a/target/linux/generic/backport-5.15/804-v5.18-0010-nvmem-brcm_nvram-parse-NVRAM-content-into-NVMEM-cell.patch b/target/linux/generic/backport-5.15/804-v5.18-0010-nvmem-brcm_nvram-parse-NVRAM-content-into-NVMEM-cell.patch deleted file mode 100644 index 99781b3a7b3a79..00000000000000 --- a/target/linux/generic/backport-5.15/804-v5.18-0010-nvmem-brcm_nvram-parse-NVRAM-content-into-NVMEM-cell.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 6e977eaa8280e957b87904b536661550f2a6b3e8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 25 Feb 2022 17:58:20 +0000 -Subject: [PATCH] nvmem: brcm_nvram: parse NVRAM content into NVMEM cells -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -NVRAM consist of header and NUL separated key-value pairs. Parse it and -create NVMEM cell for every key-value entry. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220225175822.8293-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/brcm_nvram.c | 90 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 90 insertions(+) - ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -6,12 +6,26 @@ - #include - #include - #include -+#include - #include - #include -+#include -+ -+#define NVRAM_MAGIC "FLSH" - - struct brcm_nvram { - struct device *dev; - void __iomem *base; -+ struct nvmem_cell_info *cells; -+ int ncells; -+}; -+ -+struct brcm_nvram_header { -+ char magic[4]; -+ __le32 len; -+ __le32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ -+ __le32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ -+ __le32 config_ncdl; /* ncdl values for memc */ - }; - - static int brcm_nvram_read(void *context, unsigned int offset, void *val, -@@ -26,6 +40,75 @@ static int brcm_nvram_read(void *context - return 0; - } - -+static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data, -+ size_t len) -+{ -+ struct device *dev = priv->dev; -+ char *var, *value, *eq; -+ int idx; -+ -+ priv->ncells = 0; -+ for (var = data + sizeof(struct brcm_nvram_header); -+ var < (char *)data + len && *var; -+ var += strlen(var) + 1) { -+ priv->ncells++; -+ } -+ -+ priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL); -+ if (!priv->cells) -+ return -ENOMEM; -+ -+ for (var = data + sizeof(struct brcm_nvram_header), idx = 0; -+ var < (char *)data + len && *var; -+ var = value + strlen(value) + 1, idx++) { -+ eq = strchr(var, '='); -+ if (!eq) -+ break; -+ *eq = '\0'; -+ value = eq + 1; -+ -+ priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL); -+ if (!priv->cells[idx].name) -+ return -ENOMEM; -+ priv->cells[idx].offset = value - (char *)data; -+ priv->cells[idx].bytes = strlen(value); -+ } -+ -+ return 0; -+} -+ -+static int brcm_nvram_parse(struct brcm_nvram *priv) -+{ -+ struct device *dev = priv->dev; -+ struct brcm_nvram_header header; -+ uint8_t *data; -+ size_t len; -+ int err; -+ -+ memcpy_fromio(&header, priv->base, sizeof(header)); -+ -+ if (memcmp(header.magic, NVRAM_MAGIC, 4)) { -+ dev_err(dev, "Invalid NVRAM magic\n"); -+ return -EINVAL; -+ } -+ -+ len = le32_to_cpu(header.len); -+ -+ data = kcalloc(1, len, GFP_KERNEL); -+ memcpy_fromio(data, priv->base, len); -+ data[len - 1] = '\0'; -+ -+ err = brcm_nvram_add_cells(priv, data, len); -+ if (err) { -+ dev_err(dev, "Failed to add cells: %d\n", err); -+ return err; -+ } -+ -+ kfree(data); -+ -+ return 0; -+} -+ - static int brcm_nvram_probe(struct platform_device *pdev) - { - struct nvmem_config config = { -@@ -35,6 +118,7 @@ static int brcm_nvram_probe(struct platf - struct device *dev = &pdev->dev; - struct resource *res; - struct brcm_nvram *priv; -+ int err; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -46,7 +130,13 @@ static int brcm_nvram_probe(struct platf - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - -+ err = brcm_nvram_parse(priv); -+ if (err) -+ return err; -+ - config.dev = dev; -+ config.cells = priv->cells; -+ config.ncells = priv->ncells; - config.priv = priv; - config.size = resource_size(res); - diff --git a/target/linux/generic/backport-5.15/805-v5.19-0001-nvmem-bcm-ocotp-mark-ACPI-device-ID-table-as-maybe-u.patch b/target/linux/generic/backport-5.15/805-v5.19-0001-nvmem-bcm-ocotp-mark-ACPI-device-ID-table-as-maybe-u.patch deleted file mode 100644 index ef3107db946c4f..00000000000000 --- a/target/linux/generic/backport-5.15/805-v5.19-0001-nvmem-bcm-ocotp-mark-ACPI-device-ID-table-as-maybe-u.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 6bd0ffeaa389866089e9573b2298ae58d6359b75 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Mon, 21 Mar 2022 12:03:24 +0100 -Subject: [PATCH] nvmem: bcm-ocotp: mark ACPI device ID table as maybe unused -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -"bcm_otpc_acpi_ids" is used with ACPI_PTR, so a build with !CONFIG_ACPI -has a warning: - - drivers/nvmem/bcm-ocotp.c:247:36: error: - ‘bcm_otpc_acpi_ids’ defined but not used [-Werror=unused-const-variable=] - -Signed-off-by: Krzysztof Kozlowski -Link: https://lore.kernel.org/r/20220321110326.44652-1-krzk@kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/bcm-ocotp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/bcm-ocotp.c -+++ b/drivers/nvmem/bcm-ocotp.c -@@ -244,7 +244,7 @@ static const struct of_device_id bcm_otp - }; - MODULE_DEVICE_TABLE(of, bcm_otpc_dt_ids); - --static const struct acpi_device_id bcm_otpc_acpi_ids[] = { -+static const struct acpi_device_id bcm_otpc_acpi_ids[] __maybe_unused = { - { .id = "BRCM0700", .driver_data = (kernel_ulong_t)&otp_map }, - { .id = "BRCM0701", .driver_data = (kernel_ulong_t)&otp_map_v2 }, - { /* sentinel */ } diff --git a/target/linux/generic/backport-5.15/805-v5.19-0002-nvmem-sunplus-ocotp-staticize-sp_otp_v0.patch b/target/linux/generic/backport-5.15/805-v5.19-0002-nvmem-sunplus-ocotp-staticize-sp_otp_v0.patch deleted file mode 100644 index a84d2316f0cce9..00000000000000 --- a/target/linux/generic/backport-5.15/805-v5.19-0002-nvmem-sunplus-ocotp-staticize-sp_otp_v0.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 1066f8156351fcd997125257cea47cf805ba4f6d Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Mon, 21 Mar 2022 12:03:25 +0100 -Subject: [PATCH] nvmem: sunplus-ocotp: staticize sp_otp_v0 - -The "sp_otp_v0" file scope variable is not used outside, so make it -static to fix warning: - - drivers/nvmem/sunplus-ocotp.c:74:29: sparse: - sparse: symbol 'sp_otp_v0' was not declared. Should it be static? - -Reported-by: kernel test robot -Signed-off-by: Krzysztof Kozlowski -Link: https://lore.kernel.org/r/20220321110326.44652-2-krzk@kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sunplus-ocotp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/sunplus-ocotp.c -+++ b/drivers/nvmem/sunplus-ocotp.c -@@ -71,7 +71,7 @@ struct sp_ocotp_data { - int size; - }; - --const struct sp_ocotp_data sp_otp_v0 = { -+static const struct sp_ocotp_data sp_otp_v0 = { - .size = QAC628_OTP_SIZE, - }; - diff --git a/target/linux/generic/backport-5.15/805-v5.19-0003-nvmem-sunplus-ocotp-drop-useless-probe-confirmation.patch b/target/linux/generic/backport-5.15/805-v5.19-0003-nvmem-sunplus-ocotp-drop-useless-probe-confirmation.patch deleted file mode 100644 index 886ebc12a9c916..00000000000000 --- a/target/linux/generic/backport-5.15/805-v5.19-0003-nvmem-sunplus-ocotp-drop-useless-probe-confirmation.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 874dfbcf219ccc42a2cbd187d087c7db82c3024b Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Mon, 21 Mar 2022 12:03:26 +0100 -Subject: [PATCH] nvmem: sunplus-ocotp: drop useless probe confirmation - -Printing probe success is discouraged, because we can use tracing for -this purpose. Remove useless print message after Sunplus OCOTP driver -probe. - -Signed-off-by: Krzysztof Kozlowski -Link: https://lore.kernel.org/r/20220321110326.44652-3-krzk@kernel.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sunplus-ocotp.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/nvmem/sunplus-ocotp.c -+++ b/drivers/nvmem/sunplus-ocotp.c -@@ -202,8 +202,6 @@ static int sp_ocotp_probe(struct platfor - (int)QAC628_OTP_NUM_BANKS, (int)OTP_WORDS_PER_BANK, - (int)OTP_WORD_SIZE, (int)QAC628_OTP_SIZE); - -- dev_info(dev, "by Sunplus (C) 2020"); -- - return 0; - } - diff --git a/target/linux/generic/backport-5.15/805-v5.19-0004-nvmem-core-support-passing-DT-node-in-cell-info.patch b/target/linux/generic/backport-5.15/805-v5.19-0004-nvmem-core-support-passing-DT-node-in-cell-info.patch deleted file mode 100644 index 3b1e76147a8b5d..00000000000000 --- a/target/linux/generic/backport-5.15/805-v5.19-0004-nvmem-core-support-passing-DT-node-in-cell-info.patch +++ /dev/null @@ -1,41 +0,0 @@ -From dbc2f62061c6bfba0aee93161ee3194dcee84bd0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 29 Apr 2022 17:26:46 +0100 -Subject: [PATCH] nvmem: core: support passing DT node in cell info -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some hardware may have NVMEM cells described in Device Tree using -individual nodes. Let drivers pass such nodes to the NVMEM subsystem so -they can be later used by NVMEM consumers. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220429162701.2222-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 1 + - include/linux/nvmem-consumer.h | 1 + - 2 files changed, 2 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -467,6 +467,7 @@ static int nvmem_cell_info_to_nvmem_cell - - cell->bit_offset = info->bit_offset; - cell->nbits = info->nbits; -+ cell->np = info->np; - - if (cell->nbits) - cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset, ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -25,6 +25,7 @@ struct nvmem_cell_info { - unsigned int bytes; - unsigned int bit_offset; - unsigned int nbits; -+ struct device_node *np; - }; - - /** diff --git a/target/linux/generic/backport-5.15/805-v5.19-0005-nvmem-brcm_nvram-find-Device-Tree-nodes-for-NVMEM-ce.patch b/target/linux/generic/backport-5.15/805-v5.19-0005-nvmem-brcm_nvram-find-Device-Tree-nodes-for-NVMEM-ce.patch deleted file mode 100644 index a9eacd9419cb2c..00000000000000 --- a/target/linux/generic/backport-5.15/805-v5.19-0005-nvmem-brcm_nvram-find-Device-Tree-nodes-for-NVMEM-ce.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 207775f7e17b8fd0426a2ac4a5b81e4e1d71849e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 29 Apr 2022 17:26:47 +0100 -Subject: [PATCH] nvmem: brcm_nvram: find Device Tree nodes for NVMEM cells -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -DT binding for Broadcom's NVRAM supports specifying NVMEM cells as NVMEM -device (provider) subnodes. Look for such subnodes when collecing NVMEM -cells. This allows NVMEM consumers to use NVRAM variables. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220429162701.2222-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/brcm_nvram.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -72,6 +73,7 @@ static int brcm_nvram_add_cells(struct b - return -ENOMEM; - priv->cells[idx].offset = value - (char *)data; - priv->cells[idx].bytes = strlen(value); -+ priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); - } - - return 0; diff --git a/target/linux/generic/backport-5.15/805-v5.19-0006-nvmem-Add-Apple-eFuse-driver.patch b/target/linux/generic/backport-5.15/805-v5.19-0006-nvmem-Add-Apple-eFuse-driver.patch deleted file mode 100644 index ebeb6f5ad394c2..00000000000000 --- a/target/linux/generic/backport-5.15/805-v5.19-0006-nvmem-Add-Apple-eFuse-driver.patch +++ /dev/null @@ -1,130 +0,0 @@ -From b6b7ef932ae838209254f016ecf8862d716a5ced Mon Sep 17 00:00:00 2001 -From: Sven Peter -Date: Fri, 29 Apr 2022 17:26:50 +0100 -Subject: [PATCH] nvmem: Add Apple eFuse driver - -Apple SoCs contain eFuses used to store factory-programmed data such -as calibration values for the PCIe or the Type-C PHY. They are organized -as 32bit values exposed as MMIO. - -Signed-off-by: Sven Peter -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220429162701.2222-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 12 ++++++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/apple-efuses.c | 80 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 94 insertions(+) - create mode 100644 drivers/nvmem/apple-efuses.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -324,4 +324,16 @@ config NVMEM_SUNPLUS_OCOTP - This driver can also be built as a module. If so, the module - will be called nvmem-sunplus-ocotp. - -+config NVMEM_APPLE_EFUSES -+ tristate "Apple eFuse support" -+ depends on ARCH_APPLE || COMPILE_TEST -+ default ARCH_APPLE -+ help -+ Say y here to enable support for reading eFuses on Apple SoCs -+ such as the M1. These are e.g. used to store factory programmed -+ calibration data required for the PCIe or the USB-C PHY. -+ -+ This driver can also be built as a module. If so, the module will -+ be called nvmem-apple-efuses. -+ - endif ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -65,3 +65,5 @@ obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nv - nvmem-layerscape-sfp-y := layerscape-sfp.o - obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o - nvmem_sunplus_ocotp-y := sunplus-ocotp.o -+obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o -+nvmem-apple-efuses-y := apple-efuses.o ---- /dev/null -+++ b/drivers/nvmem/apple-efuses.c -@@ -0,0 +1,80 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Apple SoC eFuse driver -+ * -+ * Copyright (C) The Asahi Linux Contributors -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+struct apple_efuses_priv { -+ void __iomem *fuses; -+}; -+ -+static int apple_efuses_read(void *context, unsigned int offset, void *val, -+ size_t bytes) -+{ -+ struct apple_efuses_priv *priv = context; -+ u32 *dst = val; -+ -+ while (bytes >= sizeof(u32)) { -+ *dst++ = readl_relaxed(priv->fuses + offset); -+ bytes -= sizeof(u32); -+ offset += sizeof(u32); -+ } -+ -+ return 0; -+} -+ -+static int apple_efuses_probe(struct platform_device *pdev) -+{ -+ struct apple_efuses_priv *priv; -+ struct resource *res; -+ struct nvmem_config config = { -+ .dev = &pdev->dev, -+ .read_only = true, -+ .reg_read = apple_efuses_read, -+ .stride = sizeof(u32), -+ .word_size = sizeof(u32), -+ .name = "apple_efuses_nvmem", -+ .id = NVMEM_DEVID_AUTO, -+ .root_only = true, -+ }; -+ -+ priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->fuses = devm_platform_get_and_ioremap_resource(pdev, 0, &res); -+ if (IS_ERR(priv->fuses)) -+ return PTR_ERR(priv->fuses); -+ -+ config.priv = priv; -+ config.size = resource_size(res); -+ -+ return PTR_ERR_OR_ZERO(devm_nvmem_register(config.dev, &config)); -+} -+ -+static const struct of_device_id apple_efuses_of_match[] = { -+ { .compatible = "apple,efuses", }, -+ {} -+}; -+ -+MODULE_DEVICE_TABLE(of, apple_efuses_of_match); -+ -+static struct platform_driver apple_efuses_driver = { -+ .driver = { -+ .name = "apple_efuses", -+ .of_match_table = apple_efuses_of_match, -+ }, -+ .probe = apple_efuses_probe, -+}; -+ -+module_platform_driver(apple_efuses_driver); -+ -+MODULE_AUTHOR("Sven Peter "); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-5.15/805-v5.19-0007-nvmem-qfprom-using-pm_runtime_resume_and_get-instead.patch b/target/linux/generic/backport-5.15/805-v5.19-0007-nvmem-qfprom-using-pm_runtime_resume_and_get-instead.patch deleted file mode 100644 index cd51d97006918f..00000000000000 --- a/target/linux/generic/backport-5.15/805-v5.19-0007-nvmem-qfprom-using-pm_runtime_resume_and_get-instead.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 517f6e2641a2802dce5a5aa0d18c7d37a35678d2 Mon Sep 17 00:00:00 2001 -From: Minghao Chi -Date: Fri, 29 Apr 2022 17:26:54 +0100 -Subject: [PATCH] nvmem: qfprom: using pm_runtime_resume_and_get instead of - pm_runtime_get_sync - -Using pm_runtime_resume_and_get is more appropriate -for simplifing code - -Reported-by: Zeal Robot -Signed-off-by: Minghao Chi -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220429162701.2222-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/qfprom.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/qfprom.c -+++ b/drivers/nvmem/qfprom.c -@@ -217,9 +217,8 @@ static int qfprom_enable_fuse_blowing(co - goto err_clk_rate_set; - } - -- ret = pm_runtime_get_sync(priv->dev); -+ ret = pm_runtime_resume_and_get(priv->dev); - if (ret < 0) { -- pm_runtime_put_noidle(priv->dev); - dev_err(priv->dev, "Failed to enable power-domain\n"); - goto err_reg_enable; - } diff --git a/target/linux/generic/backport-5.15/805-v5.19-0008-nvmem-sfp-Use-regmap.patch b/target/linux/generic/backport-5.15/805-v5.19-0008-nvmem-sfp-Use-regmap.patch deleted file mode 100644 index e187238ca38fa1..00000000000000 --- a/target/linux/generic/backport-5.15/805-v5.19-0008-nvmem-sfp-Use-regmap.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 943eadbdb11314b41eacbcc484dfb7f93e271ff4 Mon Sep 17 00:00:00 2001 -From: Sean Anderson -Date: Fri, 29 Apr 2022 17:27:00 +0100 -Subject: [PATCH] nvmem: sfp: Use regmap - -This converts the SFP driver to use regmap. This will allow easily -supporting devices with different endians. We disallow byte-level -access, as regmap_bulk_read doesn't support it (and it's unclear what -the correct result would be when we have an endianness difference). - -Signed-off-by: Sean Anderson -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220429162701.2222-16-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 1 + - drivers/nvmem/layerscape-sfp.c | 30 ++++++++++++++++++++++-------- - 2 files changed, 23 insertions(+), 8 deletions(-) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -304,6 +304,7 @@ config NVMEM_LAYERSCAPE_SFP - tristate "Layerscape SFP (Security Fuse Processor) support" - depends on ARCH_LAYERSCAPE || COMPILE_TEST - depends on HAS_IOMEM -+ select REGMAP_MMIO - help - This driver provides support to read the eFuses on Freescale - Layerscape SoC's. For example, the vendor provides a per part ---- a/drivers/nvmem/layerscape-sfp.c -+++ b/drivers/nvmem/layerscape-sfp.c -@@ -13,15 +13,17 @@ - #include - #include - #include -+#include - - #define LAYERSCAPE_SFP_OTP_OFFSET 0x0200 - - struct layerscape_sfp_priv { -- void __iomem *base; -+ struct regmap *regmap; - }; - - struct layerscape_sfp_data { - int size; -+ enum regmap_endian endian; - }; - - static int layerscape_sfp_read(void *context, unsigned int offset, void *val, -@@ -29,15 +31,16 @@ static int layerscape_sfp_read(void *con - { - struct layerscape_sfp_priv *priv = context; - -- memcpy_fromio(val, priv->base + LAYERSCAPE_SFP_OTP_OFFSET + offset, -- bytes); -- -- return 0; -+ return regmap_bulk_read(priv->regmap, -+ LAYERSCAPE_SFP_OTP_OFFSET + offset, val, -+ bytes / 4); - } - - static struct nvmem_config layerscape_sfp_nvmem_config = { - .name = "fsl-sfp", - .reg_read = layerscape_sfp_read, -+ .word_size = 4, -+ .stride = 4, - }; - - static int layerscape_sfp_probe(struct platform_device *pdev) -@@ -45,16 +48,26 @@ static int layerscape_sfp_probe(struct p - const struct layerscape_sfp_data *data; - struct layerscape_sfp_priv *priv; - struct nvmem_device *nvmem; -+ struct regmap_config config = { 0 }; -+ void __iomem *base; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - -- priv->base = devm_platform_ioremap_resource(pdev, 0); -- if (IS_ERR(priv->base)) -- return PTR_ERR(priv->base); -+ base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); - - data = device_get_match_data(&pdev->dev); -+ config.reg_bits = 32; -+ config.reg_stride = 4; -+ config.val_bits = 32; -+ config.val_format_endian = data->endian; -+ config.max_register = LAYERSCAPE_SFP_OTP_OFFSET + data->size - 4; -+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, &config); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); - - layerscape_sfp_nvmem_config.size = data->size; - layerscape_sfp_nvmem_config.dev = &pdev->dev; -@@ -67,6 +80,7 @@ static int layerscape_sfp_probe(struct p - - static const struct layerscape_sfp_data ls1028a_data = { - .size = 0x88, -+ .endian = REGMAP_ENDIAN_LITTLE, - }; - - static const struct of_device_id layerscape_sfp_dt_ids[] = { diff --git a/target/linux/generic/backport-5.15/805-v5.19-0009-nvmem-sfp-Add-support-for-TA-2.1-devices.patch b/target/linux/generic/backport-5.15/805-v5.19-0009-nvmem-sfp-Add-support-for-TA-2.1-devices.patch deleted file mode 100644 index ee000986181a9c..00000000000000 --- a/target/linux/generic/backport-5.15/805-v5.19-0009-nvmem-sfp-Add-support-for-TA-2.1-devices.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 33a1c6618677fe33f8e84cb7bedc45abbce89a50 Mon Sep 17 00:00:00 2001 -From: Sean Anderson -Date: Fri, 29 Apr 2022 17:27:01 +0100 -Subject: [PATCH] nvmem: sfp: Add support for TA 2.1 devices - -This adds support for Trust Architecture (TA) 2.1 devices to the SFP driver. -There are few differences between TA 2.1 and TA 3.0, especially for -read-only support, so just re-use the existing data. - -Signed-off-by: Sean Anderson -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220429162701.2222-17-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layerscape-sfp.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/nvmem/layerscape-sfp.c -+++ b/drivers/nvmem/layerscape-sfp.c -@@ -78,12 +78,18 @@ static int layerscape_sfp_probe(struct p - return PTR_ERR_OR_ZERO(nvmem); - } - -+static const struct layerscape_sfp_data ls1021a_data = { -+ .size = 0x88, -+ .endian = REGMAP_ENDIAN_BIG, -+}; -+ - static const struct layerscape_sfp_data ls1028a_data = { - .size = 0x88, - .endian = REGMAP_ENDIAN_LITTLE, - }; - - static const struct of_device_id layerscape_sfp_dt_ids[] = { -+ { .compatible = "fsl,ls1021a-sfp", .data = &ls1021a_data }, - { .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data }, - {}, - }; diff --git a/target/linux/generic/backport-5.15/806-v6.0-0001-nvmem-microchip-otpc-add-support.patch b/target/linux/generic/backport-5.15/806-v6.0-0001-nvmem-microchip-otpc-add-support.patch deleted file mode 100644 index f54ba7ebee20e8..00000000000000 --- a/target/linux/generic/backport-5.15/806-v6.0-0001-nvmem-microchip-otpc-add-support.patch +++ /dev/null @@ -1,389 +0,0 @@ -From 98830350d3fc824c1ff5c338140fe20f041a5916 Mon Sep 17 00:00:00 2001 -From: Claudiu Beznea -Date: Wed, 6 Jul 2022 11:06:22 +0100 -Subject: [PATCH] nvmem: microchip-otpc: add support - -Add support for Microchip OTP controller available on SAMA7G5. The OTPC -controls the access to a non-volatile memory. The memory behind OTPC is -organized into packets, packets are composed by a fixed length header -(4 bytes long) and a variable length payload (payload length is available -in the header). When software request the data at an offset in memory -the OTPC will return (via header + data registers) the whole packet that -has a word at that offset. For the OTP memory layout like below: - -offset OTP Memory layout - - . . - . ... . - . . -0x0E +-----------+ <--- packet X - | header X | -0x12 +-----------+ - | payload X | -0x16 | | - | | -0x1A | | - +-----------+ - . . - . ... . - . . - -if user requests data at address 0x16 the data started at 0x0E will be -returned by controller. User will be able to fetch the whole packet -starting at 0x0E (or parts of the packet) via proper registers. The same -packet will be returned if software request the data at offset 0x0E or -0x12 or 0x1A. - -The OTP will be populated by Microchip with at least 2 packets first one -being boot configuration packet and the 2nd one being temperature -calibration packet. The packet order will be preserved b/w different chip -revisions but the packet sizes may change. - -For the above reasons and to keep the same software able to work on all -chip variants the read function of the driver is working with a packet -id instead of an offset in OTP memory. - -Signed-off-by: Claudiu Beznea -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220706100627.6534-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - MAINTAINERS | 8 + - drivers/nvmem/Kconfig | 7 + - drivers/nvmem/Makefile | 2 + - drivers/nvmem/microchip-otpc.c | 288 +++++++++++++++++++++++++++++++++ - 4 files changed, 305 insertions(+) - create mode 100644 drivers/nvmem/microchip-otpc.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -12365,6 +12365,14 @@ S: Supported - F: Documentation/devicetree/bindings/mtd/atmel-nand.txt - F: drivers/mtd/nand/raw/atmel/* - -+MICROCHIP OTPC DRIVER -+M: Claudiu Beznea -+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -+S: Supported -+F: Documentation/devicetree/bindings/nvmem/microchip,sama7g5-otpc.yaml -+F: drivers/nvmem/microchip-otpc.c -+F: dt-bindings/nvmem/microchip,sama7g5-otpc.h -+ - MICROCHIP PWM DRIVER - M: Claudiu Beznea - L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -107,6 +107,13 @@ config MTK_EFUSE - This driver can also be built as a module. If so, the module - will be called efuse-mtk. - -+config MICROCHIP_OTPC -+ tristate "Microchip OTPC support" -+ depends on ARCH_AT91 || COMPILE_TEST -+ help -+ This driver enable the OTP controller available on Microchip SAMA7G5 -+ SoCs. It controlls the access to the OTP memory connected to it. -+ - config NVMEM_NINTENDO_OTP - tristate "Nintendo Wii and Wii U OTP Support" - depends on WII || COMPILE_TEST ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -67,3 +67,5 @@ obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvm - nvmem_sunplus_ocotp-y := sunplus-ocotp.o - obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o - nvmem-apple-efuses-y := apple-efuses.o -+obj-$(CONFIG_MICROCHIP_OTPC) += nvmem-microchip-otpc.o -+nvmem-microchip-otpc-y := microchip-otpc.o ---- /dev/null -+++ b/drivers/nvmem/microchip-otpc.c -@@ -0,0 +1,288 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * OTP Memory controller -+ * -+ * Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries -+ * -+ * Author: Claudiu Beznea -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MCHP_OTPC_CR (0x0) -+#define MCHP_OTPC_CR_READ BIT(6) -+#define MCHP_OTPC_MR (0x4) -+#define MCHP_OTPC_MR_ADDR GENMASK(31, 16) -+#define MCHP_OTPC_AR (0x8) -+#define MCHP_OTPC_SR (0xc) -+#define MCHP_OTPC_SR_READ BIT(6) -+#define MCHP_OTPC_HR (0x20) -+#define MCHP_OTPC_HR_SIZE GENMASK(15, 8) -+#define MCHP_OTPC_DR (0x24) -+ -+#define MCHP_OTPC_NAME "mchp-otpc" -+#define MCHP_OTPC_SIZE (11 * 1024) -+ -+/** -+ * struct mchp_otpc - OTPC private data structure -+ * @base: base address -+ * @dev: struct device pointer -+ * @packets: list of packets in OTP memory -+ * @npackets: number of packets in OTP memory -+ */ -+struct mchp_otpc { -+ void __iomem *base; -+ struct device *dev; -+ struct list_head packets; -+ u32 npackets; -+}; -+ -+/** -+ * struct mchp_otpc_packet - OTPC packet data structure -+ * @list: list head -+ * @id: packet ID -+ * @offset: packet offset (in words) in OTP memory -+ */ -+struct mchp_otpc_packet { -+ struct list_head list; -+ u32 id; -+ u32 offset; -+}; -+ -+static struct mchp_otpc_packet *mchp_otpc_id_to_packet(struct mchp_otpc *otpc, -+ u32 id) -+{ -+ struct mchp_otpc_packet *packet; -+ -+ if (id >= otpc->npackets) -+ return NULL; -+ -+ list_for_each_entry(packet, &otpc->packets, list) { -+ if (packet->id == id) -+ return packet; -+ } -+ -+ return NULL; -+} -+ -+static int mchp_otpc_prepare_read(struct mchp_otpc *otpc, -+ unsigned int offset) -+{ -+ u32 tmp; -+ -+ /* Set address. */ -+ tmp = readl_relaxed(otpc->base + MCHP_OTPC_MR); -+ tmp &= ~MCHP_OTPC_MR_ADDR; -+ tmp |= FIELD_PREP(MCHP_OTPC_MR_ADDR, offset); -+ writel_relaxed(tmp, otpc->base + MCHP_OTPC_MR); -+ -+ /* Set read. */ -+ tmp = readl_relaxed(otpc->base + MCHP_OTPC_CR); -+ tmp |= MCHP_OTPC_CR_READ; -+ writel_relaxed(tmp, otpc->base + MCHP_OTPC_CR); -+ -+ /* Wait for packet to be transferred into temporary buffers. */ -+ return read_poll_timeout(readl_relaxed, tmp, !(tmp & MCHP_OTPC_SR_READ), -+ 10000, 2000, false, otpc->base + MCHP_OTPC_SR); -+} -+ -+/* -+ * OTPC memory is organized into packets. Each packets contains a header and -+ * a payload. Header is 4 bytes long and contains the size of the payload. -+ * Payload size varies. The memory footprint is something as follows: -+ * -+ * Memory offset Memory footprint Packet ID -+ * ------------- ---------------- --------- -+ * -+ * 0x0 +------------+ <-- packet 0 -+ * | header 0 | -+ * 0x4 +------------+ -+ * | payload 0 | -+ * . . -+ * . ... . -+ * . . -+ * offset1 +------------+ <-- packet 1 -+ * | header 1 | -+ * offset1 + 0x4 +------------+ -+ * | payload 1 | -+ * . . -+ * . ... . -+ * . . -+ * offset2 +------------+ <-- packet 2 -+ * . . -+ * . ... . -+ * . . -+ * offsetN +------------+ <-- packet N -+ * | header N | -+ * offsetN + 0x4 +------------+ -+ * | payload N | -+ * . . -+ * . ... . -+ * . . -+ * +------------+ -+ * -+ * where offset1, offset2, offsetN depends on the size of payload 0, payload 1, -+ * payload N-1. -+ * -+ * The access to memory is done on a per packet basis: the control registers -+ * need to be updated with an offset address (within a packet range) and the -+ * data registers will be update by controller with information contained by -+ * that packet. E.g. if control registers are updated with any address within -+ * the range [offset1, offset2) the data registers are updated by controller -+ * with packet 1. Header data is accessible though MCHP_OTPC_HR register. -+ * Payload data is accessible though MCHP_OTPC_DR and MCHP_OTPC_AR registers. -+ * There is no direct mapping b/w the offset requested by software and the -+ * offset returned by hardware. -+ * -+ * For this, the read function will return the first requested bytes in the -+ * packet. The user will have to be aware of the memory footprint before doing -+ * the read request. -+ */ -+static int mchp_otpc_read(void *priv, unsigned int off, void *val, -+ size_t bytes) -+{ -+ struct mchp_otpc *otpc = priv; -+ struct mchp_otpc_packet *packet; -+ u32 *buf = val; -+ u32 offset; -+ size_t len = 0; -+ int ret, payload_size; -+ -+ /* -+ * We reach this point with off being multiple of stride = 4 to -+ * be able to cross the subsystem. Inside the driver we use continuous -+ * unsigned integer numbers for packet id, thus devide off by 4 -+ * before passing it to mchp_otpc_id_to_packet(). -+ */ -+ packet = mchp_otpc_id_to_packet(otpc, off / 4); -+ if (!packet) -+ return -EINVAL; -+ offset = packet->offset; -+ -+ while (len < bytes) { -+ ret = mchp_otpc_prepare_read(otpc, offset); -+ if (ret) -+ return ret; -+ -+ /* Read and save header content. */ -+ *buf++ = readl_relaxed(otpc->base + MCHP_OTPC_HR); -+ len += sizeof(*buf); -+ offset++; -+ if (len >= bytes) -+ break; -+ -+ /* Read and save payload content. */ -+ payload_size = FIELD_GET(MCHP_OTPC_HR_SIZE, *(buf - 1)); -+ writel_relaxed(0UL, otpc->base + MCHP_OTPC_AR); -+ do { -+ *buf++ = readl_relaxed(otpc->base + MCHP_OTPC_DR); -+ len += sizeof(*buf); -+ offset++; -+ payload_size--; -+ } while (payload_size >= 0 && len < bytes); -+ } -+ -+ return 0; -+} -+ -+static int mchp_otpc_init_packets_list(struct mchp_otpc *otpc, u32 *size) -+{ -+ struct mchp_otpc_packet *packet; -+ u32 word, word_pos = 0, id = 0, npackets = 0, payload_size; -+ int ret; -+ -+ INIT_LIST_HEAD(&otpc->packets); -+ *size = 0; -+ -+ while (*size < MCHP_OTPC_SIZE) { -+ ret = mchp_otpc_prepare_read(otpc, word_pos); -+ if (ret) -+ return ret; -+ -+ word = readl_relaxed(otpc->base + MCHP_OTPC_HR); -+ payload_size = FIELD_GET(MCHP_OTPC_HR_SIZE, word); -+ if (!payload_size) -+ break; -+ -+ packet = devm_kzalloc(otpc->dev, sizeof(*packet), GFP_KERNEL); -+ if (!packet) -+ return -ENOMEM; -+ -+ packet->id = id++; -+ packet->offset = word_pos; -+ INIT_LIST_HEAD(&packet->list); -+ list_add_tail(&packet->list, &otpc->packets); -+ -+ /* Count size by adding header and paload sizes. */ -+ *size += 4 * (payload_size + 1); -+ /* Next word: this packet (header, payload) position + 1. */ -+ word_pos += payload_size + 2; -+ -+ npackets++; -+ } -+ -+ otpc->npackets = npackets; -+ -+ return 0; -+} -+ -+static struct nvmem_config mchp_nvmem_config = { -+ .name = MCHP_OTPC_NAME, -+ .type = NVMEM_TYPE_OTP, -+ .read_only = true, -+ .word_size = 4, -+ .stride = 4, -+ .reg_read = mchp_otpc_read, -+}; -+ -+static int mchp_otpc_probe(struct platform_device *pdev) -+{ -+ struct nvmem_device *nvmem; -+ struct mchp_otpc *otpc; -+ u32 size; -+ int ret; -+ -+ otpc = devm_kzalloc(&pdev->dev, sizeof(*otpc), GFP_KERNEL); -+ if (!otpc) -+ return -ENOMEM; -+ -+ otpc->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(otpc->base)) -+ return PTR_ERR(otpc->base); -+ -+ otpc->dev = &pdev->dev; -+ ret = mchp_otpc_init_packets_list(otpc, &size); -+ if (ret) -+ return ret; -+ -+ mchp_nvmem_config.dev = otpc->dev; -+ mchp_nvmem_config.size = size; -+ mchp_nvmem_config.priv = otpc; -+ nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config); -+ -+ return PTR_ERR_OR_ZERO(nvmem); -+} -+ -+static const struct of_device_id __maybe_unused mchp_otpc_ids[] = { -+ { .compatible = "microchip,sama7g5-otpc", }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, mchp_otpc_ids); -+ -+static struct platform_driver mchp_otpc_driver = { -+ .probe = mchp_otpc_probe, -+ .driver = { -+ .name = MCHP_OTPC_NAME, -+ .of_match_table = of_match_ptr(mchp_otpc_ids), -+ }, -+}; -+module_platform_driver(mchp_otpc_driver); -+ -+MODULE_AUTHOR("Claudiu Beznea "); -+MODULE_DESCRIPTION("Microchip SAMA7G5 OTPC driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-5.15/806-v6.0-0002-nvmem-mtk-efuse-Simplify-with-devm_platform_get_and_.patch b/target/linux/generic/backport-5.15/806-v6.0-0002-nvmem-mtk-efuse-Simplify-with-devm_platform_get_and_.patch deleted file mode 100644 index 6a4126b9deda99..00000000000000 --- a/target/linux/generic/backport-5.15/806-v6.0-0002-nvmem-mtk-efuse-Simplify-with-devm_platform_get_and_.patch +++ /dev/null @@ -1,32 +0,0 @@ -From f5c97da8037b18d1256a58459fa96ed68e50fb41 Mon Sep 17 00:00:00 2001 -From: AngeloGioacchino Del Regno -Date: Wed, 6 Jul 2022 11:06:27 +0100 -Subject: [PATCH] nvmem: mtk-efuse: Simplify with - devm_platform_get_and_ioremap_resource() - -Convert platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -No functional changes. - -Signed-off-by: AngeloGioacchino Del Regno -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220706100627.6534-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/mtk-efuse.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -41,8 +41,7 @@ static int mtk_efuse_probe(struct platfo - if (!priv) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->base = devm_ioremap_resource(dev, res); -+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - diff --git a/target/linux/generic/backport-5.15/807-v6.1-0002-nvmem-add-driver-handling-U-Boot-environment-variabl.patch b/target/linux/generic/backport-5.15/807-v6.1-0002-nvmem-add-driver-handling-U-Boot-environment-variabl.patch deleted file mode 100644 index 9138807bc91cd9..00000000000000 --- a/target/linux/generic/backport-5.15/807-v6.1-0002-nvmem-add-driver-handling-U-Boot-environment-variabl.patch +++ /dev/null @@ -1,286 +0,0 @@ -From d5542923f200f95bddf524f36fd495f78aa28e3c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 16 Sep 2022 13:20:48 +0100 -Subject: [PATCH] nvmem: add driver handling U-Boot environment variables -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -U-Boot stores its setup as environment variables. It's a list of -key-value pairs stored on flash device with a custom header. - -This commit adds an NVMEM driver that: -1. Provides NVMEM access to environment vars binary data -2. Extracts variables as NVMEM cells - -Current Linux's NVMEM sysfs API allows reading whole NVMEM data block. -It can be used by user-space tools for reading U-Boot env vars block -without the hassle of finding its location. Parsing will still need to -be re-done there. - -Kernel-parsed NVMEM cells can be read however by Linux drivers. This may -be useful for Ethernet drivers for reading device MAC address which is -often stored as U-Boot env variable. - -Reviewed-by: Ahmad Fatoum -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220916122100.170016-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - MAINTAINERS | 1 + - drivers/nvmem/Kconfig | 13 +++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/u-boot-env.c | 218 +++++++++++++++++++++++++++++++++++++ - 4 files changed, 234 insertions(+) - create mode 100644 drivers/nvmem/u-boot-env.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -344,4 +344,17 @@ config NVMEM_APPLE_EFUSES - This driver can also be built as a module. If so, the module will - be called nvmem-apple-efuses. - -+config NVMEM_U_BOOT_ENV -+ tristate "U-Boot environment variables support" -+ depends on OF && MTD -+ select CRC32 -+ help -+ U-Boot stores its setup as environment variables. This driver adds -+ support for verifying & exporting such data. It also exposes variables -+ as NVMEM cells so they can be referenced by other drivers. -+ -+ Currently this drivers works only with env variables on top of MTD. -+ -+ If compiled as module it will be called nvmem_u-boot-env. -+ - endif ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -69,3 +69,5 @@ obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvme - nvmem-apple-efuses-y := apple-efuses.o - obj-$(CONFIG_MICROCHIP_OTPC) += nvmem-microchip-otpc.o - nvmem-microchip-otpc-y := microchip-otpc.o -+obj-$(CONFIG_NVMEM_U_BOOT_ENV) += nvmem_u-boot-env.o -+nvmem_u-boot-env-y := u-boot-env.o ---- /dev/null -+++ b/drivers/nvmem/u-boot-env.c -@@ -0,0 +1,218 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (C) 2022 Rafał Miłecki -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+enum u_boot_env_format { -+ U_BOOT_FORMAT_SINGLE, -+ U_BOOT_FORMAT_REDUNDANT, -+}; -+ -+struct u_boot_env { -+ struct device *dev; -+ enum u_boot_env_format format; -+ -+ struct mtd_info *mtd; -+ -+ /* Cells */ -+ struct nvmem_cell_info *cells; -+ int ncells; -+}; -+ -+struct u_boot_env_image_single { -+ __le32 crc32; -+ uint8_t data[]; -+} __packed; -+ -+struct u_boot_env_image_redundant { -+ __le32 crc32; -+ u8 mark; -+ uint8_t data[]; -+} __packed; -+ -+static int u_boot_env_read(void *context, unsigned int offset, void *val, -+ size_t bytes) -+{ -+ struct u_boot_env *priv = context; -+ struct device *dev = priv->dev; -+ size_t bytes_read; -+ int err; -+ -+ err = mtd_read(priv->mtd, offset, bytes, &bytes_read, val); -+ if (err && !mtd_is_bitflip(err)) { -+ dev_err(dev, "Failed to read from mtd: %d\n", err); -+ return err; -+ } -+ -+ if (bytes_read != bytes) { -+ dev_err(dev, "Failed to read %zu bytes\n", bytes); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, -+ size_t data_offset, size_t data_len) -+{ -+ struct device *dev = priv->dev; -+ char *data = buf + data_offset; -+ char *var, *value, *eq; -+ int idx; -+ -+ priv->ncells = 0; -+ for (var = data; var < data + data_len && *var; var += strlen(var) + 1) -+ priv->ncells++; -+ -+ priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL); -+ if (!priv->cells) -+ return -ENOMEM; -+ -+ for (var = data, idx = 0; -+ var < data + data_len && *var; -+ var = value + strlen(value) + 1, idx++) { -+ eq = strchr(var, '='); -+ if (!eq) -+ break; -+ *eq = '\0'; -+ value = eq + 1; -+ -+ priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL); -+ if (!priv->cells[idx].name) -+ return -ENOMEM; -+ priv->cells[idx].offset = data_offset + value - data; -+ priv->cells[idx].bytes = strlen(value); -+ } -+ -+ if (WARN_ON(idx != priv->ncells)) -+ priv->ncells = idx; -+ -+ return 0; -+} -+ -+static int u_boot_env_parse(struct u_boot_env *priv) -+{ -+ struct device *dev = priv->dev; -+ size_t crc32_data_offset; -+ size_t crc32_data_len; -+ size_t crc32_offset; -+ size_t data_offset; -+ size_t data_len; -+ uint32_t crc32; -+ uint32_t calc; -+ size_t bytes; -+ uint8_t *buf; -+ int err; -+ -+ buf = kcalloc(1, priv->mtd->size, GFP_KERNEL); -+ if (!buf) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf); -+ if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) { -+ dev_err(dev, "Failed to read from mtd: %d\n", err); -+ goto err_kfree; -+ } -+ -+ switch (priv->format) { -+ case U_BOOT_FORMAT_SINGLE: -+ crc32_offset = offsetof(struct u_boot_env_image_single, crc32); -+ crc32_data_offset = offsetof(struct u_boot_env_image_single, data); -+ data_offset = offsetof(struct u_boot_env_image_single, data); -+ break; -+ case U_BOOT_FORMAT_REDUNDANT: -+ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32); -+ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, mark); -+ data_offset = offsetof(struct u_boot_env_image_redundant, data); -+ break; -+ } -+ crc32 = le32_to_cpu(*(uint32_t *)(buf + crc32_offset)); -+ crc32_data_len = priv->mtd->size - crc32_data_offset; -+ data_len = priv->mtd->size - data_offset; -+ -+ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; -+ if (calc != crc32) { -+ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); -+ err = -EINVAL; -+ goto err_kfree; -+ } -+ -+ buf[priv->mtd->size - 1] = '\0'; -+ err = u_boot_env_add_cells(priv, buf, data_offset, data_len); -+ if (err) -+ dev_err(dev, "Failed to add cells: %d\n", err); -+ -+err_kfree: -+ kfree(buf); -+err_out: -+ return err; -+} -+ -+static int u_boot_env_probe(struct platform_device *pdev) -+{ -+ struct nvmem_config config = { -+ .name = "u-boot-env", -+ .reg_read = u_boot_env_read, -+ }; -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct u_boot_env *priv; -+ int err; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ priv->dev = dev; -+ -+ priv->format = (uintptr_t)of_device_get_match_data(dev); -+ -+ priv->mtd = of_get_mtd_device_by_node(np); -+ if (IS_ERR(priv->mtd)) { -+ dev_err_probe(dev, PTR_ERR(priv->mtd), "Failed to get %pOF MTD\n", np); -+ return PTR_ERR(priv->mtd); -+ } -+ -+ err = u_boot_env_parse(priv); -+ if (err) -+ return err; -+ -+ config.dev = dev; -+ config.cells = priv->cells; -+ config.ncells = priv->ncells; -+ config.priv = priv; -+ config.size = priv->mtd->size; -+ -+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config)); -+} -+ -+static const struct of_device_id u_boot_env_of_match_table[] = { -+ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, }, -+ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, -+ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, -+ {}, -+}; -+ -+static struct platform_driver u_boot_env_driver = { -+ .probe = u_boot_env_probe, -+ .driver = { -+ .name = "u_boot_env", -+ .of_match_table = u_boot_env_of_match_table, -+ }, -+}; -+module_platform_driver(u_boot_env_driver); -+ -+MODULE_AUTHOR("Rafał Miłecki"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table); diff --git a/target/linux/generic/backport-5.15/807-v6.1-0004-nvmem-brcm_nvram-Use-kzalloc-for-allocating-only-one.patch b/target/linux/generic/backport-5.15/807-v6.1-0004-nvmem-brcm_nvram-Use-kzalloc-for-allocating-only-one.patch deleted file mode 100644 index 48ad63fab5f923..00000000000000 --- a/target/linux/generic/backport-5.15/807-v6.1-0004-nvmem-brcm_nvram-Use-kzalloc-for-allocating-only-one.patch +++ /dev/null @@ -1,29 +0,0 @@ -From d3524bb5b9a0c567b853a0024526afe87dde01ed Mon Sep 17 00:00:00 2001 -From: Kenneth Lee -Date: Fri, 16 Sep 2022 13:20:52 +0100 -Subject: [PATCH] nvmem: brcm_nvram: Use kzalloc for allocating only one - element - -Use kzalloc(...) rather than kcalloc(1, ...) because the number of -elements we are specifying in this case is 1, so kzalloc would -accomplish the same thing and we can simplify. - -Signed-off-by: Kenneth Lee -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220916122100.170016-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/brcm_nvram.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -96,7 +96,7 @@ static int brcm_nvram_parse(struct brcm_ - - len = le32_to_cpu(header.len); - -- data = kcalloc(1, len, GFP_KERNEL); -+ data = kzalloc(len, GFP_KERNEL); - memcpy_fromio(data, priv->base, len); - data[len - 1] = '\0'; - diff --git a/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch b/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch deleted file mode 100644 index 4410fc4d615fc9..00000000000000 --- a/target/linux/generic/backport-5.15/807-v6.1-0005-nvmem-prefix-all-symbols-with-NVMEM_.patch +++ /dev/null @@ -1,281 +0,0 @@ -From 28fc7c986f01fdcfd28af648be2597624cac0e27 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 16 Sep 2022 13:20:54 +0100 -Subject: [PATCH] nvmem: prefix all symbols with NVMEM_ -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This unifies all NVMEM symbols. They follow one style now. - -Reviewed-by: Matthias Brugger -Acked-by: Arnd Bergmann -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220916122100.170016-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - arch/arm/configs/multi_v7_defconfig | 6 +++--- - arch/arm/configs/qcom_defconfig | 2 +- - arch/arm64/configs/defconfig | 10 +++++----- - arch/mips/configs/ci20_defconfig | 2 +- - drivers/cpufreq/Kconfig.arm | 2 +- - drivers/nvmem/Kconfig | 24 ++++++++++++------------ - drivers/nvmem/Makefile | 24 ++++++++++++------------ - drivers/soc/mediatek/Kconfig | 2 +- - drivers/thermal/qcom/Kconfig | 2 +- - 9 files changed, 37 insertions(+), 37 deletions(-) - ---- a/arch/arm/configs/multi_v7_defconfig -+++ b/arch/arm/configs/multi_v7_defconfig -@@ -1124,10 +1124,10 @@ CONFIG_TI_PIPE3=y - CONFIG_TWL4030_USB=m - CONFIG_RAS=y - CONFIG_NVMEM_IMX_OCOTP=y --CONFIG_ROCKCHIP_EFUSE=m -+CONFIG_NVMEM_ROCKCHIP_EFUSE=m - CONFIG_NVMEM_SUNXI_SID=y - CONFIG_NVMEM_VF610_OCOTP=y --CONFIG_MESON_MX_EFUSE=m -+CONFIG_NVMEM_MESON_MX_EFUSE=m - CONFIG_NVMEM_RMEM=m - CONFIG_FSI=m - CONFIG_FSI_MASTER_GPIO=m ---- a/arch/arm/configs/qcom_defconfig -+++ b/arch/arm/configs/qcom_defconfig -@@ -274,7 +274,7 @@ CONFIG_PHY_QCOM_USB_HS=y - CONFIG_PHY_QCOM_USB_HSIC=y - CONFIG_PHY_QCOM_QMP=y - CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y --CONFIG_QCOM_QFPROM=y -+CONFIG_NVMEM_QCOM_QFPROM=y - CONFIG_INTERCONNECT=y - CONFIG_INTERCONNECT_QCOM=y - CONFIG_INTERCONNECT_QCOM_MSM8974=m ---- a/arch/arm64/configs/defconfig -+++ b/arch/arm64/configs/defconfig -@@ -1135,11 +1135,11 @@ CONFIG_QCOM_L3_PMU=y - CONFIG_NVMEM_IMX_OCOTP=y - CONFIG_NVMEM_IMX_OCOTP_SCU=y - CONFIG_QCOM_QFPROM=y --CONFIG_MTK_EFUSE=y --CONFIG_ROCKCHIP_EFUSE=y -+CONFIG_NVMEM_MTK_EFUSE=y -+CONFIG_NVMEM_ROCKCHIP_EFUSE=y - CONFIG_NVMEM_SUNXI_SID=y --CONFIG_UNIPHIER_EFUSE=y --CONFIG_MESON_EFUSE=m -+CONFIG_NVMEM_UNIPHIER_EFUSE=y -+CONFIG_NVMEM_MESON_EFUSE=m - CONFIG_NVMEM_RMEM=m - CONFIG_FPGA=y - CONFIG_FPGA_MGR_STRATIX10_SOC=m ---- a/arch/mips/configs/ci20_defconfig -+++ b/arch/mips/configs/ci20_defconfig -@@ -137,7 +137,7 @@ CONFIG_MEMORY=y - CONFIG_JZ4780_NEMC=y - CONFIG_PWM=y - CONFIG_PWM_JZ4740=m --CONFIG_JZ4780_EFUSE=y -+CONFIG_NVMEM_JZ4780_EFUSE=y - CONFIG_JZ4770_PHY=y - CONFIG_EXT4_FS=y - # CONFIG_DNOTIFY is not set ---- a/drivers/cpufreq/Kconfig.arm -+++ b/drivers/cpufreq/Kconfig.arm -@@ -153,7 +153,7 @@ config ARM_OMAP2PLUS_CPUFREQ - config ARM_QCOM_CPUFREQ_NVMEM - tristate "Qualcomm nvmem based CPUFreq" - depends on ARCH_QCOM -- depends on QCOM_QFPROM -+ depends on NVMEM_QCOM_QFPROM - depends on QCOM_SMEM - select PM_OPP - help ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -52,7 +52,7 @@ config NVMEM_IMX_OCOTP_SCU - This is a driver for the SCU On-Chip OTP Controller (OCOTP) - available on i.MX8 SoCs. - --config JZ4780_EFUSE -+config NVMEM_JZ4780_EFUSE - tristate "JZ4780 EFUSE Memory Support" - depends on MACH_INGENIC || COMPILE_TEST - depends on HAS_IOMEM -@@ -96,7 +96,7 @@ config NVMEM_MXS_OCOTP - This driver can also be built as a module. If so, the module - will be called nvmem-mxs-ocotp. - --config MTK_EFUSE -+config NVMEM_MTK_EFUSE - tristate "Mediatek SoCs EFUSE support" - depends on ARCH_MEDIATEK || COMPILE_TEST - depends on HAS_IOMEM -@@ -107,7 +107,7 @@ config MTK_EFUSE - This driver can also be built as a module. If so, the module - will be called efuse-mtk. - --config MICROCHIP_OTPC -+config NVMEM_MICROCHIP_OTPC - tristate "Microchip OTPC support" - depends on ARCH_AT91 || COMPILE_TEST - help -@@ -126,7 +126,7 @@ config NVMEM_NINTENDO_OTP - This driver can also be built as a module. If so, the module - will be called nvmem-nintendo-otp. - --config QCOM_QFPROM -+config NVMEM_QCOM_QFPROM - tristate "QCOM QFPROM Support" - depends on ARCH_QCOM || COMPILE_TEST - depends on HAS_IOMEM -@@ -145,7 +145,7 @@ config NVMEM_SPMI_SDAM - Qualcomm Technologies, Inc. PMICs. It provides the clients - an interface to read/write to the SDAM module's shared memory. - --config ROCKCHIP_EFUSE -+config NVMEM_ROCKCHIP_EFUSE - tristate "Rockchip eFuse Support" - depends on ARCH_ROCKCHIP || COMPILE_TEST - depends on HAS_IOMEM -@@ -156,7 +156,7 @@ config ROCKCHIP_EFUSE - This driver can also be built as a module. If so, the module - will be called nvmem_rockchip_efuse. - --config ROCKCHIP_OTP -+config NVMEM_ROCKCHIP_OTP - tristate "Rockchip OTP controller support" - depends on ARCH_ROCKCHIP || COMPILE_TEST - depends on HAS_IOMEM -@@ -199,7 +199,7 @@ config NVMEM_SUNXI_SID - This driver can also be built as a module. If so, the module - will be called nvmem_sunxi_sid. - --config UNIPHIER_EFUSE -+config NVMEM_UNIPHIER_EFUSE - tristate "UniPhier SoCs eFuse support" - depends on ARCH_UNIPHIER || COMPILE_TEST - depends on HAS_IOMEM -@@ -221,7 +221,7 @@ config NVMEM_VF610_OCOTP - This driver can also be build as a module. If so, the module will - be called nvmem-vf610-ocotp. - --config MESON_EFUSE -+config NVMEM_MESON_EFUSE - tristate "Amlogic Meson GX eFuse Support" - depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM - help -@@ -231,7 +231,7 @@ config MESON_EFUSE - This driver can also be built as a module. If so, the module - will be called nvmem_meson_efuse. - --config MESON_MX_EFUSE -+config NVMEM_MESON_MX_EFUSE - tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support" - depends on ARCH_MESON || COMPILE_TEST - help -@@ -251,13 +251,13 @@ config NVMEM_SNVS_LPGPR - This driver can also be built as a module. If so, the module - will be called nvmem-snvs-lpgpr. - --config RAVE_SP_EEPROM -+config NVMEM_RAVE_SP_EEPROM - tristate "Rave SP EEPROM Support" - depends on RAVE_SP_CORE - help - Say y here to enable Rave SP EEPROM support. - --config SC27XX_EFUSE -+config NVMEM_SC27XX_EFUSE - tristate "Spreadtrum SC27XX eFuse Support" - depends on MFD_SC27XX_PMIC || COMPILE_TEST - depends on HAS_IOMEM -@@ -278,7 +278,7 @@ config NVMEM_ZYNQMP - - If sure, say yes. If unsure, say no. - --config SPRD_EFUSE -+config NVMEM_SPRD_EFUSE - tristate "Spreadtrum SoC eFuse Support" - depends on ARCH_SPRD || COMPILE_TEST - depends on HAS_IOMEM ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -15,7 +15,7 @@ obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-i - nvmem-imx-ocotp-y := imx-ocotp.o - obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvmem-imx-ocotp-scu.o - nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o --obj-$(CONFIG_JZ4780_EFUSE) += nvmem_jz4780_efuse.o -+obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o - nvmem_jz4780_efuse-y := jz4780-efuse.o - obj-$(CONFIG_NVMEM_LPC18XX_EEPROM) += nvmem_lpc18xx_eeprom.o - nvmem_lpc18xx_eeprom-y := lpc18xx_eeprom.o -@@ -25,37 +25,37 @@ obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-m - nvmem-mxs-ocotp-y := mxs-ocotp.o - obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvmem-nintendo-otp.o - nvmem-nintendo-otp-y := nintendo-otp.o --obj-$(CONFIG_MTK_EFUSE) += nvmem_mtk-efuse.o -+obj-$(CONFIG_NVMEM_MTK_EFUSE) += nvmem_mtk-efuse.o - nvmem_mtk-efuse-y := mtk-efuse.o --obj-$(CONFIG_QCOM_QFPROM) += nvmem_qfprom.o -+obj-$(CONFIG_NVMEM_QCOM_QFPROM) += nvmem_qfprom.o - nvmem_qfprom-y := qfprom.o - obj-$(CONFIG_NVMEM_SPMI_SDAM) += nvmem_qcom-spmi-sdam.o - nvmem_qcom-spmi-sdam-y += qcom-spmi-sdam.o --obj-$(CONFIG_ROCKCHIP_EFUSE) += nvmem_rockchip_efuse.o -+obj-$(CONFIG_NVMEM_ROCKCHIP_EFUSE) += nvmem_rockchip_efuse.o - nvmem_rockchip_efuse-y := rockchip-efuse.o --obj-$(CONFIG_ROCKCHIP_OTP) += nvmem-rockchip-otp.o -+obj-$(CONFIG_NVMEM_ROCKCHIP_OTP) += nvmem-rockchip-otp.o - nvmem-rockchip-otp-y := rockchip-otp.o - obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o - nvmem_stm32_romem-y := stm32-romem.o - obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o - nvmem_sunxi_sid-y := sunxi_sid.o --obj-$(CONFIG_UNIPHIER_EFUSE) += nvmem-uniphier-efuse.o -+obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE) += nvmem-uniphier-efuse.o - nvmem-uniphier-efuse-y := uniphier-efuse.o - obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvmem-vf610-ocotp.o - nvmem-vf610-ocotp-y := vf610-ocotp.o --obj-$(CONFIG_MESON_EFUSE) += nvmem_meson_efuse.o -+obj-$(CONFIG_NVMEM_MESON_EFUSE) += nvmem_meson_efuse.o - nvmem_meson_efuse-y := meson-efuse.o --obj-$(CONFIG_MESON_MX_EFUSE) += nvmem_meson_mx_efuse.o -+obj-$(CONFIG_NVMEM_MESON_MX_EFUSE) += nvmem_meson_mx_efuse.o - nvmem_meson_mx_efuse-y := meson-mx-efuse.o - obj-$(CONFIG_NVMEM_SNVS_LPGPR) += nvmem_snvs_lpgpr.o - nvmem_snvs_lpgpr-y := snvs_lpgpr.o --obj-$(CONFIG_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o -+obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o - nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o --obj-$(CONFIG_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o -+obj-$(CONFIG_NVMEM_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o - nvmem-sc27xx-efuse-y := sc27xx-efuse.o - obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o - nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o --obj-$(CONFIG_SPRD_EFUSE) += nvmem_sprd_efuse.o -+obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem_sprd_efuse.o - nvmem_sprd_efuse-y := sprd-efuse.o - obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o - nvmem-rmem-y := rmem.o -@@ -67,7 +67,7 @@ obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvm - nvmem_sunplus_ocotp-y := sunplus-ocotp.o - obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o - nvmem-apple-efuses-y := apple-efuses.o --obj-$(CONFIG_MICROCHIP_OTPC) += nvmem-microchip-otpc.o -+obj-$(CONFIG_NVMEM_MICROCHIP_OTPC) += nvmem-microchip-otpc.o - nvmem-microchip-otpc-y := microchip-otpc.o - obj-$(CONFIG_NVMEM_U_BOOT_ENV) += nvmem_u-boot-env.o - nvmem_u-boot-env-y := u-boot-env.o ---- a/drivers/thermal/qcom/Kconfig -+++ b/drivers/thermal/qcom/Kconfig -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - config QCOM_TSENS - tristate "Qualcomm TSENS Temperature Alarm" -- depends on QCOM_QFPROM -+ depends on NVMEM_QCOM_QFPROM - depends on ARCH_QCOM || COMPILE_TEST - help - This enables the thermal sysfs driver for the TSENS device. It shows diff --git a/target/linux/generic/backport-5.15/807-v6.1-0006-nvmem-sort-config-symbols-alphabetically.patch b/target/linux/generic/backport-5.15/807-v6.1-0006-nvmem-sort-config-symbols-alphabetically.patch deleted file mode 100644 index 4e45524bffcd5c..00000000000000 --- a/target/linux/generic/backport-5.15/807-v6.1-0006-nvmem-sort-config-symbols-alphabetically.patch +++ /dev/null @@ -1,535 +0,0 @@ -From a06d9e5a63b7c2f622c908cd9600ce735e70f7c6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 16 Sep 2022 13:20:55 +0100 -Subject: [PATCH] nvmem: sort config symbols alphabetically -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -1. Match what most subsystems do -2. Simplify maintenance a bit -3. Reduce amount of conflicts for new drivers patches - -While at it unify indent level in Makefile. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220916122100.170016-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 300 +++++++++++++++++++++-------------------- - drivers/nvmem/Makefile | 114 ++++++++-------- - 2 files changed, 208 insertions(+), 206 deletions(-) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -21,6 +21,40 @@ config NVMEM_SYSFS - This interface is mostly used by userspace applications to - read/write directly into nvmem. - -+# Devices -+ -+config NVMEM_APPLE_EFUSES -+ tristate "Apple eFuse support" -+ depends on ARCH_APPLE || COMPILE_TEST -+ default ARCH_APPLE -+ help -+ Say y here to enable support for reading eFuses on Apple SoCs -+ such as the M1. These are e.g. used to store factory programmed -+ calibration data required for the PCIe or the USB-C PHY. -+ -+ This driver can also be built as a module. If so, the module will -+ be called nvmem-apple-efuses. -+ -+config NVMEM_BCM_OCOTP -+ tristate "Broadcom On-Chip OTP Controller support" -+ depends on ARCH_BCM_IPROC || COMPILE_TEST -+ depends on HAS_IOMEM -+ default ARCH_BCM_IPROC -+ help -+ Say y here to enable read/write access to the Broadcom OTP -+ controller. -+ -+ This driver can also be built as a module. If so, the module -+ will be called nvmem-bcm-ocotp. -+ -+config NVMEM_BRCM_NVRAM -+ tristate "Broadcom's NVRAM support" -+ depends on ARCH_BCM_5301X || COMPILE_TEST -+ depends on HAS_IOMEM -+ help -+ This driver provides support for Broadcom's NVRAM that can be accessed -+ using I/O mapping. -+ - config NVMEM_IMX_IIM - tristate "i.MX IC Identification Module support" - depends on ARCH_MXC || COMPILE_TEST -@@ -64,6 +98,19 @@ config NVMEM_JZ4780_EFUSE - To compile this driver as a module, choose M here: the module - will be called nvmem_jz4780_efuse. - -+config NVMEM_LAYERSCAPE_SFP -+ tristate "Layerscape SFP (Security Fuse Processor) support" -+ depends on ARCH_LAYERSCAPE || COMPILE_TEST -+ depends on HAS_IOMEM -+ select REGMAP_MMIO -+ help -+ This driver provides support to read the eFuses on Freescale -+ Layerscape SoC's. For example, the vendor provides a per part -+ unique ID there. -+ -+ This driver can also be built as a module. If so, the module -+ will be called layerscape-sfp. -+ - config NVMEM_LPC18XX_EEPROM - tristate "NXP LPC18XX EEPROM Memory Support" - depends on ARCH_LPC18XX || COMPILE_TEST -@@ -84,17 +131,32 @@ config NVMEM_LPC18XX_OTP - To compile this driver as a module, choose M here: the module - will be called nvmem_lpc18xx_otp. - --config NVMEM_MXS_OCOTP -- tristate "Freescale MXS On-Chip OTP Memory Support" -- depends on ARCH_MXS || COMPILE_TEST -- depends on HAS_IOMEM -+config NVMEM_MESON_EFUSE -+ tristate "Amlogic Meson GX eFuse Support" -+ depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM - help -- If you say Y here, you will get readonly access to the -- One Time Programmable memory pages that are stored -- on the Freescale i.MX23/i.MX28 processor. -+ This is a driver to retrieve specific values from the eFuse found on -+ the Amlogic Meson GX SoCs. - - This driver can also be built as a module. If so, the module -- will be called nvmem-mxs-ocotp. -+ will be called nvmem_meson_efuse. -+ -+config NVMEM_MESON_MX_EFUSE -+ tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support" -+ depends on ARCH_MESON || COMPILE_TEST -+ help -+ This is a driver to retrieve specific values from the eFuse found on -+ the Amlogic Meson6, Meson8 and Meson8b SoCs. -+ -+ This driver can also be built as a module. If so, the module -+ will be called nvmem_meson_mx_efuse. -+ -+config NVMEM_MICROCHIP_OTPC -+ tristate "Microchip OTPC support" -+ depends on ARCH_AT91 || COMPILE_TEST -+ help -+ This driver enable the OTP controller available on Microchip SAMA7G5 -+ SoCs. It controlls the access to the OTP memory connected to it. - - config NVMEM_MTK_EFUSE - tristate "Mediatek SoCs EFUSE support" -@@ -107,12 +169,17 @@ config NVMEM_MTK_EFUSE - This driver can also be built as a module. If so, the module - will be called efuse-mtk. - --config NVMEM_MICROCHIP_OTPC -- tristate "Microchip OTPC support" -- depends on ARCH_AT91 || COMPILE_TEST -+config NVMEM_MXS_OCOTP -+ tristate "Freescale MXS On-Chip OTP Memory Support" -+ depends on ARCH_MXS || COMPILE_TEST -+ depends on HAS_IOMEM - help -- This driver enable the OTP controller available on Microchip SAMA7G5 -- SoCs. It controlls the access to the OTP memory connected to it. -+ If you say Y here, you will get readonly access to the -+ One Time Programmable memory pages that are stored -+ on the Freescale i.MX23/i.MX28 processor. -+ -+ This driver can also be built as a module. If so, the module -+ will be called nvmem-mxs-ocotp. - - config NVMEM_NINTENDO_OTP - tristate "Nintendo Wii and Wii U OTP Support" -@@ -137,13 +204,21 @@ config NVMEM_QCOM_QFPROM - This driver can also be built as a module. If so, the module - will be called nvmem_qfprom. - --config NVMEM_SPMI_SDAM -- tristate "SPMI SDAM Support" -- depends on SPMI -+config NVMEM_RAVE_SP_EEPROM -+ tristate "Rave SP EEPROM Support" -+ depends on RAVE_SP_CORE - help -- This driver supports the Shared Direct Access Memory Module on -- Qualcomm Technologies, Inc. PMICs. It provides the clients -- an interface to read/write to the SDAM module's shared memory. -+ Say y here to enable Rave SP EEPROM support. -+ -+config NVMEM_RMEM -+ tristate "Reserved Memory Based Driver Support" -+ depends on HAS_IOMEM -+ help -+ This driver maps reserved memory into an nvmem device. It might be -+ useful to expose information left by firmware in memory. -+ -+ This driver can also be built as a module. If so, the module -+ will be called nvmem-rmem. - - config NVMEM_ROCKCHIP_EFUSE - tristate "Rockchip eFuse Support" -@@ -167,79 +242,16 @@ config NVMEM_ROCKCHIP_OTP - This driver can also be built as a module. If so, the module - will be called nvmem_rockchip_otp. - --config NVMEM_BCM_OCOTP -- tristate "Broadcom On-Chip OTP Controller support" -- depends on ARCH_BCM_IPROC || COMPILE_TEST -- depends on HAS_IOMEM -- default ARCH_BCM_IPROC -- help -- Say y here to enable read/write access to the Broadcom OTP -- controller. -- -- This driver can also be built as a module. If so, the module -- will be called nvmem-bcm-ocotp. -- --config NVMEM_STM32_ROMEM -- tristate "STMicroelectronics STM32 factory-programmed memory support" -- depends on ARCH_STM32 || COMPILE_TEST -- help -- Say y here to enable read-only access for STMicroelectronics STM32 -- factory-programmed memory area. -- -- This driver can also be built as a module. If so, the module -- will be called nvmem-stm32-romem. -- --config NVMEM_SUNXI_SID -- tristate "Allwinner SoCs SID support" -- depends on ARCH_SUNXI -- help -- This is a driver for the 'security ID' available on various Allwinner -- devices. -- -- This driver can also be built as a module. If so, the module -- will be called nvmem_sunxi_sid. -- --config NVMEM_UNIPHIER_EFUSE -- tristate "UniPhier SoCs eFuse support" -- depends on ARCH_UNIPHIER || COMPILE_TEST -- depends on HAS_IOMEM -- help -- This is a simple driver to dump specified values of UniPhier SoC -- from eFuse. -- -- This driver can also be built as a module. If so, the module -- will be called nvmem-uniphier-efuse. -- --config NVMEM_VF610_OCOTP -- tristate "VF610 SoC OCOTP support" -- depends on SOC_VF610 || COMPILE_TEST -+config NVMEM_SC27XX_EFUSE -+ tristate "Spreadtrum SC27XX eFuse Support" -+ depends on MFD_SC27XX_PMIC || COMPILE_TEST - depends on HAS_IOMEM - help -- This is a driver for the 'OCOTP' peripheral available on Vybrid -- devices like VF5xx and VF6xx. -- -- This driver can also be build as a module. If so, the module will -- be called nvmem-vf610-ocotp. -- --config NVMEM_MESON_EFUSE -- tristate "Amlogic Meson GX eFuse Support" -- depends on (ARCH_MESON || COMPILE_TEST) && MESON_SM -- help -- This is a driver to retrieve specific values from the eFuse found on -- the Amlogic Meson GX SoCs. -- -- This driver can also be built as a module. If so, the module -- will be called nvmem_meson_efuse. -- --config NVMEM_MESON_MX_EFUSE -- tristate "Amlogic Meson6/Meson8/Meson8b eFuse Support" -- depends on ARCH_MESON || COMPILE_TEST -- help -- This is a driver to retrieve specific values from the eFuse found on -- the Amlogic Meson6, Meson8 and Meson8b SoCs. -+ This is a simple driver to dump specified values of Spreadtrum -+ SC27XX PMICs from eFuse. - - This driver can also be built as a module. If so, the module -- will be called nvmem_meson_mx_efuse. -+ will be called nvmem-sc27xx-efuse. - - config NVMEM_SNVS_LPGPR - tristate "Support for Low Power General Purpose Register" -@@ -251,32 +263,13 @@ config NVMEM_SNVS_LPGPR - This driver can also be built as a module. If so, the module - will be called nvmem-snvs-lpgpr. - --config NVMEM_RAVE_SP_EEPROM -- tristate "Rave SP EEPROM Support" -- depends on RAVE_SP_CORE -- help -- Say y here to enable Rave SP EEPROM support. -- --config NVMEM_SC27XX_EFUSE -- tristate "Spreadtrum SC27XX eFuse Support" -- depends on MFD_SC27XX_PMIC || COMPILE_TEST -- depends on HAS_IOMEM -- help -- This is a simple driver to dump specified values of Spreadtrum -- SC27XX PMICs from eFuse. -- -- This driver can also be built as a module. If so, the module -- will be called nvmem-sc27xx-efuse. -- --config NVMEM_ZYNQMP -- bool "Xilinx ZYNQMP SoC nvmem firmware support" -- depends on ARCH_ZYNQMP -+config NVMEM_SPMI_SDAM -+ tristate "SPMI SDAM Support" -+ depends on SPMI - help -- This is a driver to access hardware related data like -- soc revision, IDCODE... etc by using the firmware -- interface. -- -- If sure, say yes. If unsure, say no. -+ This driver supports the Shared Direct Access Memory Module on -+ Qualcomm Technologies, Inc. PMICs. It provides the clients -+ an interface to read/write to the SDAM module's shared memory. - - config NVMEM_SPRD_EFUSE - tristate "Spreadtrum SoC eFuse Support" -@@ -289,36 +282,15 @@ config NVMEM_SPRD_EFUSE - This driver can also be built as a module. If so, the module - will be called nvmem-sprd-efuse. - --config NVMEM_RMEM -- tristate "Reserved Memory Based Driver Support" -- depends on HAS_IOMEM -- help -- This driver maps reserved memory into an nvmem device. It might be -- useful to expose information left by firmware in memory. -- -- This driver can also be built as a module. If so, the module -- will be called nvmem-rmem. -- --config NVMEM_BRCM_NVRAM -- tristate "Broadcom's NVRAM support" -- depends on ARCH_BCM_5301X || COMPILE_TEST -- depends on HAS_IOMEM -- help -- This driver provides support for Broadcom's NVRAM that can be accessed -- using I/O mapping. -- --config NVMEM_LAYERSCAPE_SFP -- tristate "Layerscape SFP (Security Fuse Processor) support" -- depends on ARCH_LAYERSCAPE || COMPILE_TEST -- depends on HAS_IOMEM -- select REGMAP_MMIO -+config NVMEM_STM32_ROMEM -+ tristate "STMicroelectronics STM32 factory-programmed memory support" -+ depends on ARCH_STM32 || COMPILE_TEST - help -- This driver provides support to read the eFuses on Freescale -- Layerscape SoC's. For example, the vendor provides a per part -- unique ID there. -+ Say y here to enable read-only access for STMicroelectronics STM32 -+ factory-programmed memory area. - - This driver can also be built as a module. If so, the module -- will be called layerscape-sfp. -+ will be called nvmem-stm32-romem. - - config NVMEM_SUNPLUS_OCOTP - tristate "Sunplus SoC OTP support" -@@ -332,17 +304,15 @@ config NVMEM_SUNPLUS_OCOTP - This driver can also be built as a module. If so, the module - will be called nvmem-sunplus-ocotp. - --config NVMEM_APPLE_EFUSES -- tristate "Apple eFuse support" -- depends on ARCH_APPLE || COMPILE_TEST -- default ARCH_APPLE -+config NVMEM_SUNXI_SID -+ tristate "Allwinner SoCs SID support" -+ depends on ARCH_SUNXI - help -- Say y here to enable support for reading eFuses on Apple SoCs -- such as the M1. These are e.g. used to store factory programmed -- calibration data required for the PCIe or the USB-C PHY. -+ This is a driver for the 'security ID' available on various Allwinner -+ devices. - -- This driver can also be built as a module. If so, the module will -- be called nvmem-apple-efuses. -+ This driver can also be built as a module. If so, the module -+ will be called nvmem_sunxi_sid. - - config NVMEM_U_BOOT_ENV - tristate "U-Boot environment variables support" -@@ -357,4 +327,36 @@ config NVMEM_U_BOOT_ENV - - If compiled as module it will be called nvmem_u-boot-env. - -+config NVMEM_UNIPHIER_EFUSE -+ tristate "UniPhier SoCs eFuse support" -+ depends on ARCH_UNIPHIER || COMPILE_TEST -+ depends on HAS_IOMEM -+ help -+ This is a simple driver to dump specified values of UniPhier SoC -+ from eFuse. -+ -+ This driver can also be built as a module. If so, the module -+ will be called nvmem-uniphier-efuse. -+ -+config NVMEM_VF610_OCOTP -+ tristate "VF610 SoC OCOTP support" -+ depends on SOC_VF610 || COMPILE_TEST -+ depends on HAS_IOMEM -+ help -+ This is a driver for the 'OCOTP' peripheral available on Vybrid -+ devices like VF5xx and VF6xx. -+ -+ This driver can also be build as a module. If so, the module will -+ be called nvmem-vf610-ocotp. -+ -+config NVMEM_ZYNQMP -+ bool "Xilinx ZYNQMP SoC nvmem firmware support" -+ depends on ARCH_ZYNQMP -+ help -+ This is a driver to access hardware related data like -+ soc revision, IDCODE... etc by using the firmware -+ interface. -+ -+ If sure, say yes. If unsure, say no. -+ - endif ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -7,67 +7,67 @@ obj-$(CONFIG_NVMEM) += nvmem_core.o - nvmem_core-y := core.o - - # Devices --obj-$(CONFIG_NVMEM_BCM_OCOTP) += nvmem-bcm-ocotp.o --nvmem-bcm-ocotp-y := bcm-ocotp.o --obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-imx-iim.o --nvmem-imx-iim-y := imx-iim.o --obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o --nvmem-imx-ocotp-y := imx-ocotp.o -+obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o -+nvmem-apple-efuses-y := apple-efuses.o -+obj-$(CONFIG_NVMEM_BCM_OCOTP) += nvmem-bcm-ocotp.o -+nvmem-bcm-ocotp-y := bcm-ocotp.o -+obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o -+nvmem_brcm_nvram-y := brcm_nvram.o -+obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-imx-iim.o -+nvmem-imx-iim-y := imx-iim.o -+obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o -+nvmem-imx-ocotp-y := imx-ocotp.o - obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvmem-imx-ocotp-scu.o --nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o --obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o --nvmem_jz4780_efuse-y := jz4780-efuse.o -+nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o -+obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o -+nvmem_jz4780_efuse-y := jz4780-efuse.o -+obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nvmem-layerscape-sfp.o -+nvmem-layerscape-sfp-y := layerscape-sfp.o - obj-$(CONFIG_NVMEM_LPC18XX_EEPROM) += nvmem_lpc18xx_eeprom.o --nvmem_lpc18xx_eeprom-y := lpc18xx_eeprom.o --obj-$(CONFIG_NVMEM_LPC18XX_OTP) += nvmem_lpc18xx_otp.o --nvmem_lpc18xx_otp-y := lpc18xx_otp.o --obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-mxs-ocotp.o --nvmem-mxs-ocotp-y := mxs-ocotp.o --obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvmem-nintendo-otp.o --nvmem-nintendo-otp-y := nintendo-otp.o -+nvmem_lpc18xx_eeprom-y := lpc18xx_eeprom.o -+obj-$(CONFIG_NVMEM_LPC18XX_OTP) += nvmem_lpc18xx_otp.o -+nvmem_lpc18xx_otp-y := lpc18xx_otp.o -+obj-$(CONFIG_NVMEM_MESON_EFUSE) += nvmem_meson_efuse.o -+nvmem_meson_efuse-y := meson-efuse.o -+obj-$(CONFIG_NVMEM_MESON_MX_EFUSE) += nvmem_meson_mx_efuse.o -+nvmem_meson_mx_efuse-y := meson-mx-efuse.o -+obj-$(CONFIG_NVMEM_MICROCHIP_OTPC) += nvmem-microchip-otpc.o -+nvmem-microchip-otpc-y := microchip-otpc.o - obj-$(CONFIG_NVMEM_MTK_EFUSE) += nvmem_mtk-efuse.o --nvmem_mtk-efuse-y := mtk-efuse.o --obj-$(CONFIG_NVMEM_QCOM_QFPROM) += nvmem_qfprom.o --nvmem_qfprom-y := qfprom.o --obj-$(CONFIG_NVMEM_SPMI_SDAM) += nvmem_qcom-spmi-sdam.o --nvmem_qcom-spmi-sdam-y += qcom-spmi-sdam.o -+nvmem_mtk-efuse-y := mtk-efuse.o -+obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-mxs-ocotp.o -+nvmem-mxs-ocotp-y := mxs-ocotp.o -+obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvmem-nintendo-otp.o -+nvmem-nintendo-otp-y := nintendo-otp.o -+obj-$(CONFIG_NVMEM_QCOM_QFPROM) += nvmem_qfprom.o -+nvmem_qfprom-y := qfprom.o -+obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o -+nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o -+obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o -+nvmem-rmem-y := rmem.o - obj-$(CONFIG_NVMEM_ROCKCHIP_EFUSE) += nvmem_rockchip_efuse.o --nvmem_rockchip_efuse-y := rockchip-efuse.o -+nvmem_rockchip_efuse-y := rockchip-efuse.o - obj-$(CONFIG_NVMEM_ROCKCHIP_OTP) += nvmem-rockchip-otp.o --nvmem-rockchip-otp-y := rockchip-otp.o --obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o --nvmem_stm32_romem-y := stm32-romem.o --obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o --nvmem_sunxi_sid-y := sunxi_sid.o --obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE) += nvmem-uniphier-efuse.o --nvmem-uniphier-efuse-y := uniphier-efuse.o --obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvmem-vf610-ocotp.o --nvmem-vf610-ocotp-y := vf610-ocotp.o --obj-$(CONFIG_NVMEM_MESON_EFUSE) += nvmem_meson_efuse.o --nvmem_meson_efuse-y := meson-efuse.o --obj-$(CONFIG_NVMEM_MESON_MX_EFUSE) += nvmem_meson_mx_efuse.o --nvmem_meson_mx_efuse-y := meson-mx-efuse.o --obj-$(CONFIG_NVMEM_SNVS_LPGPR) += nvmem_snvs_lpgpr.o --nvmem_snvs_lpgpr-y := snvs_lpgpr.o --obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o --nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o -+nvmem-rockchip-otp-y := rockchip-otp.o - obj-$(CONFIG_NVMEM_SC27XX_EFUSE) += nvmem-sc27xx-efuse.o --nvmem-sc27xx-efuse-y := sc27xx-efuse.o --obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o --nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o --obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem_sprd_efuse.o --nvmem_sprd_efuse-y := sprd-efuse.o --obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o --nvmem-rmem-y := rmem.o --obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o --nvmem_brcm_nvram-y := brcm_nvram.o --obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nvmem-layerscape-sfp.o --nvmem-layerscape-sfp-y := layerscape-sfp.o -+nvmem-sc27xx-efuse-y := sc27xx-efuse.o -+obj-$(CONFIG_NVMEM_SNVS_LPGPR) += nvmem_snvs_lpgpr.o -+nvmem_snvs_lpgpr-y := snvs_lpgpr.o -+obj-$(CONFIG_NVMEM_SPMI_SDAM) += nvmem_qcom-spmi-sdam.o -+nvmem_qcom-spmi-sdam-y += qcom-spmi-sdam.o -+obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem_sprd_efuse.o -+nvmem_sprd_efuse-y := sprd-efuse.o -+obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o -+nvmem_stm32_romem-y := stm32-romem.o - obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o --nvmem_sunplus_ocotp-y := sunplus-ocotp.o --obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o --nvmem-apple-efuses-y := apple-efuses.o --obj-$(CONFIG_NVMEM_MICROCHIP_OTPC) += nvmem-microchip-otpc.o --nvmem-microchip-otpc-y := microchip-otpc.o --obj-$(CONFIG_NVMEM_U_BOOT_ENV) += nvmem_u-boot-env.o --nvmem_u-boot-env-y := u-boot-env.o -+nvmem_sunplus_ocotp-y := sunplus-ocotp.o -+obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o -+nvmem_sunxi_sid-y := sunxi_sid.o -+obj-$(CONFIG_NVMEM_U_BOOT_ENV) += nvmem_u-boot-env.o -+nvmem_u-boot-env-y := u-boot-env.o -+obj-$(CONFIG_NVMEM_UNIPHIER_EFUSE) += nvmem-uniphier-efuse.o -+nvmem-uniphier-efuse-y := uniphier-efuse.o -+obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvmem-vf610-ocotp.o -+nvmem-vf610-ocotp-y := vf610-ocotp.o -+obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o -+nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o diff --git a/target/linux/generic/backport-5.15/807-v6.1-0007-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch b/target/linux/generic/backport-5.15/807-v6.1-0007-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch deleted file mode 100644 index e0a082adc45e23..00000000000000 --- a/target/linux/generic/backport-5.15/807-v6.1-0007-nvmem-u-boot-env-find-Device-Tree-nodes-for-NVMEM-ce.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d4d432670f7dee0a5432fcffcfc8699b25181ace Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 16 Sep 2022 13:20:57 +0100 -Subject: [PATCH] nvmem: u-boot-env: find Device Tree nodes for NVMEM cells -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -DT binding allows specifying NVMEM cells as NVMEM device (provider) -subnodes. Looks for such subnodes when building NVMEM cells. - -This allows NVMEM consumers to use U-Boot environment variables. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220916122100.170016-11-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -92,6 +92,7 @@ static int u_boot_env_add_cells(struct u - return -ENOMEM; - priv->cells[idx].offset = data_offset + value - data; - priv->cells[idx].bytes = strlen(value); -+ priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); - } - - if (WARN_ON(idx != priv->ncells)) diff --git a/target/linux/generic/backport-5.15/807-v6.1-0008-nvmem-lan9662-otp-add-support.patch b/target/linux/generic/backport-5.15/807-v6.1-0008-nvmem-lan9662-otp-add-support.patch deleted file mode 100644 index 945c6128ff49c2..00000000000000 --- a/target/linux/generic/backport-5.15/807-v6.1-0008-nvmem-lan9662-otp-add-support.patch +++ /dev/null @@ -1,274 +0,0 @@ -From 9e8f208ad5229ddda97cd4a83ecf89c735d99592 Mon Sep 17 00:00:00 2001 -From: Horatiu Vultur -Date: Fri, 16 Sep 2022 13:20:59 +0100 -Subject: [PATCH] nvmem: lan9662-otp: add support - -Add support for OTP controller available on LAN9662. The OTPC controls -the access to a non-volatile memory. The size of the memory is 8KB. -The OTPC can access the memory based on an offset. -Implement both the read and the write functionality. - -Signed-off-by: Horatiu Vultur -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220916122100.170016-13-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 8 ++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/lan9662-otpc.c | 222 +++++++++++++++++++++++++++++++++++ - 3 files changed, 232 insertions(+) - create mode 100644 drivers/nvmem/lan9662-otpc.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -98,6 +98,14 @@ config NVMEM_JZ4780_EFUSE - To compile this driver as a module, choose M here: the module - will be called nvmem_jz4780_efuse. - -+config NVMEM_LAN9662_OTPC -+ tristate "Microchip LAN9662 OTP controller support" -+ depends on SOC_LAN966 || COMPILE_TEST -+ depends on HAS_IOMEM -+ help -+ This driver enables the OTP controller available on Microchip LAN9662 -+ SoCs. It controls the access to the OTP memory connected to it. -+ - config NVMEM_LAYERSCAPE_SFP - tristate "Layerscape SFP (Security Fuse Processor) support" - depends on ARCH_LAYERSCAPE || COMPILE_TEST ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -21,6 +21,8 @@ obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvm - nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o - obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o - nvmem_jz4780_efuse-y := jz4780-efuse.o -+obj-$(CONFIG_NVMEM_LAN9662_OTPC) += nvmem-lan9662-otpc.o -+nvmem-lan9662-otpc-y := lan9662-otpc.o - obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP) += nvmem-layerscape-sfp.o - nvmem-layerscape-sfp-y := layerscape-sfp.o - obj-$(CONFIG_NVMEM_LPC18XX_EEPROM) += nvmem_lpc18xx_eeprom.o ---- /dev/null -+++ b/drivers/nvmem/lan9662-otpc.c -@@ -0,0 +1,222 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define OTP_OTP_PWR_DN(t) (t + 0x00) -+#define OTP_OTP_PWR_DN_OTP_PWRDN_N BIT(0) -+#define OTP_OTP_ADDR_HI(t) (t + 0x04) -+#define OTP_OTP_ADDR_LO(t) (t + 0x08) -+#define OTP_OTP_PRGM_DATA(t) (t + 0x10) -+#define OTP_OTP_PRGM_MODE(t) (t + 0x14) -+#define OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE BIT(0) -+#define OTP_OTP_RD_DATA(t) (t + 0x18) -+#define OTP_OTP_FUNC_CMD(t) (t + 0x20) -+#define OTP_OTP_FUNC_CMD_OTP_PROGRAM BIT(1) -+#define OTP_OTP_FUNC_CMD_OTP_READ BIT(0) -+#define OTP_OTP_CMD_GO(t) (t + 0x28) -+#define OTP_OTP_CMD_GO_OTP_GO BIT(0) -+#define OTP_OTP_PASS_FAIL(t) (t + 0x2c) -+#define OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED BIT(3) -+#define OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED BIT(2) -+#define OTP_OTP_PASS_FAIL_OTP_FAIL BIT(0) -+#define OTP_OTP_STATUS(t) (t + 0x30) -+#define OTP_OTP_STATUS_OTP_CPUMPEN BIT(1) -+#define OTP_OTP_STATUS_OTP_BUSY BIT(0) -+ -+#define OTP_MEM_SIZE 8192 -+#define OTP_SLEEP_US 10 -+#define OTP_TIMEOUT_US 500000 -+ -+struct lan9662_otp { -+ struct device *dev; -+ void __iomem *base; -+}; -+ -+static bool lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) -+{ -+ u32 val; -+ -+ return readl_poll_timeout(reg, val, !(val & flag), -+ OTP_SLEEP_US, OTP_TIMEOUT_US); -+} -+ -+static int lan9662_otp_power(struct lan9662_otp *otp, bool up) -+{ -+ void __iomem *pwrdn = OTP_OTP_PWR_DN(otp->base); -+ -+ if (up) { -+ writel(readl(pwrdn) & ~OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn); -+ if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base), -+ OTP_OTP_STATUS_OTP_CPUMPEN)) -+ return -ETIMEDOUT; -+ } else { -+ writel(readl(pwrdn) | OTP_OTP_PWR_DN_OTP_PWRDN_N, pwrdn); -+ } -+ -+ return 0; -+} -+ -+static int lan9662_otp_execute(struct lan9662_otp *otp) -+{ -+ if (lan9662_otp_wait_flag_clear(OTP_OTP_CMD_GO(otp->base), -+ OTP_OTP_CMD_GO_OTP_GO)) -+ return -ETIMEDOUT; -+ -+ if (lan9662_otp_wait_flag_clear(OTP_OTP_STATUS(otp->base), -+ OTP_OTP_STATUS_OTP_BUSY)) -+ return -ETIMEDOUT; -+ -+ return 0; -+} -+ -+static void lan9662_otp_set_address(struct lan9662_otp *otp, u32 offset) -+{ -+ writel(0xff & (offset >> 8), OTP_OTP_ADDR_HI(otp->base)); -+ writel(0xff & offset, OTP_OTP_ADDR_LO(otp->base)); -+} -+ -+static int lan9662_otp_read_byte(struct lan9662_otp *otp, u32 offset, u8 *dst) -+{ -+ u32 pass; -+ int rc; -+ -+ lan9662_otp_set_address(otp, offset); -+ writel(OTP_OTP_FUNC_CMD_OTP_READ, OTP_OTP_FUNC_CMD(otp->base)); -+ writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base)); -+ rc = lan9662_otp_execute(otp); -+ if (!rc) { -+ pass = readl(OTP_OTP_PASS_FAIL(otp->base)); -+ if (pass & OTP_OTP_PASS_FAIL_OTP_READ_PROHIBITED) -+ return -EACCES; -+ *dst = (u8) readl(OTP_OTP_RD_DATA(otp->base)); -+ } -+ return rc; -+} -+ -+static int lan9662_otp_write_byte(struct lan9662_otp *otp, u32 offset, u8 data) -+{ -+ u32 pass; -+ int rc; -+ -+ lan9662_otp_set_address(otp, offset); -+ writel(OTP_OTP_PRGM_MODE_OTP_PGM_MODE_BYTE, OTP_OTP_PRGM_MODE(otp->base)); -+ writel(data, OTP_OTP_PRGM_DATA(otp->base)); -+ writel(OTP_OTP_FUNC_CMD_OTP_PROGRAM, OTP_OTP_FUNC_CMD(otp->base)); -+ writel(OTP_OTP_CMD_GO_OTP_GO, OTP_OTP_CMD_GO(otp->base)); -+ -+ rc = lan9662_otp_execute(otp); -+ if (!rc) { -+ pass = readl(OTP_OTP_PASS_FAIL(otp->base)); -+ if (pass & OTP_OTP_PASS_FAIL_OTP_WRITE_PROHIBITED) -+ return -EACCES; -+ if (pass & OTP_OTP_PASS_FAIL_OTP_FAIL) -+ return -EIO; -+ } -+ return rc; -+} -+ -+static int lan9662_otp_read(void *context, unsigned int offset, -+ void *_val, size_t bytes) -+{ -+ struct lan9662_otp *otp = context; -+ u8 *val = _val; -+ uint8_t data; -+ int i, rc = 0; -+ -+ lan9662_otp_power(otp, true); -+ for (i = 0; i < bytes; i++) { -+ rc = lan9662_otp_read_byte(otp, offset + i, &data); -+ if (rc < 0) -+ break; -+ *val++ = data; -+ } -+ lan9662_otp_power(otp, false); -+ -+ return rc; -+} -+ -+static int lan9662_otp_write(void *context, unsigned int offset, -+ void *_val, size_t bytes) -+{ -+ struct lan9662_otp *otp = context; -+ u8 *val = _val; -+ u8 data, newdata; -+ int i, rc = 0; -+ -+ lan9662_otp_power(otp, true); -+ for (i = 0; i < bytes; i++) { -+ /* Skip zero bytes */ -+ if (val[i]) { -+ rc = lan9662_otp_read_byte(otp, offset + i, &data); -+ if (rc < 0) -+ break; -+ -+ newdata = data | val[i]; -+ if (newdata == data) -+ continue; -+ -+ rc = lan9662_otp_write_byte(otp, offset + i, -+ newdata); -+ if (rc < 0) -+ break; -+ } -+ } -+ lan9662_otp_power(otp, false); -+ -+ return rc; -+} -+ -+static struct nvmem_config otp_config = { -+ .name = "lan9662-otp", -+ .stride = 1, -+ .word_size = 1, -+ .reg_read = lan9662_otp_read, -+ .reg_write = lan9662_otp_write, -+ .size = OTP_MEM_SIZE, -+}; -+ -+static int lan9662_otp_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct nvmem_device *nvmem; -+ struct lan9662_otp *otp; -+ -+ otp = devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL); -+ if (!otp) -+ return -ENOMEM; -+ -+ otp->dev = dev; -+ otp->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(otp->base)) -+ return PTR_ERR(otp->base); -+ -+ otp_config.priv = otp; -+ otp_config.dev = dev; -+ -+ nvmem = devm_nvmem_register(dev, &otp_config); -+ -+ return PTR_ERR_OR_ZERO(nvmem); -+} -+ -+static const struct of_device_id lan9662_otp_match[] = { -+ { .compatible = "microchip,lan9662-otp", }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, lan9662_otp_match); -+ -+static struct platform_driver lan9662_otp_driver = { -+ .probe = lan9662_otp_probe, -+ .driver = { -+ .name = "lan9662-otp", -+ .of_match_table = lan9662_otp_match, -+ }, -+}; -+module_platform_driver(lan9662_otp_driver); -+ -+MODULE_AUTHOR("Horatiu Vultur "); -+MODULE_DESCRIPTION("lan9662 OTP driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-5.15/807-v6.1-0009-nvmem-u-boot-env-fix-crc32-casting-type.patch b/target/linux/generic/backport-5.15/807-v6.1-0009-nvmem-u-boot-env-fix-crc32-casting-type.patch deleted file mode 100644 index 633a668a962f65..00000000000000 --- a/target/linux/generic/backport-5.15/807-v6.1-0009-nvmem-u-boot-env-fix-crc32-casting-type.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3717ca3e0cc8683f93b41d3f06ca79631eb58715 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 16 Sep 2022 13:21:00 +0100 -Subject: [PATCH] nvmem: u-boot-env: fix crc32 casting type -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes: -drivers/nvmem/u-boot-env.c:141:17: sparse: sparse: cast to restricted __le32 - -Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables") -Reported-by: kernel test robot -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20220916122100.170016-14-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -139,7 +139,7 @@ static int u_boot_env_parse(struct u_boo - data_offset = offsetof(struct u_boot_env_image_redundant, data); - break; - } -- crc32 = le32_to_cpu(*(uint32_t *)(buf + crc32_offset)); -+ crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); - crc32_data_len = priv->mtd->size - crc32_data_offset; - data_len = priv->mtd->size - data_offset; - diff --git a/target/linux/generic/backport-5.15/807-v6.1-0010-nvmem-lan9662-otp-Fix-compatible-string.patch b/target/linux/generic/backport-5.15/807-v6.1-0010-nvmem-lan9662-otp-Fix-compatible-string.patch deleted file mode 100644 index b663a1328df3df..00000000000000 --- a/target/linux/generic/backport-5.15/807-v6.1-0010-nvmem-lan9662-otp-Fix-compatible-string.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 1aeb122d214b92474c86fde00a03d6e2d69381b5 Mon Sep 17 00:00:00 2001 -From: Horatiu Vultur -Date: Wed, 28 Sep 2022 21:51:12 +0200 -Subject: [PATCH] nvmem: lan9662-otp: Fix compatible string - -The device tree bindings for lan9662-otp expects the compatible string -to be one of following compatible strings: -microchip,lan9662-otpc -microchip,lan9668-otpc - -The problem is that the lan9662-otp driver contains the -microchip,lan9662-otp compatible string instead of -microchip,lan9662-otpc. -Fix this by updating the compatible string in the driver. - -Fixes: 9e8f208ad5229d ("nvmem: lan9662-otp: add support") -Signed-off-by: Horatiu Vultur -Link: https://lore.kernel.org/r/20220928195112.630351-1-horatiu.vultur@microchip.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/lan9662-otpc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/lan9662-otpc.c -+++ b/drivers/nvmem/lan9662-otpc.c -@@ -203,7 +203,7 @@ static int lan9662_otp_probe(struct plat - } - - static const struct of_device_id lan9662_otp_match[] = { -- { .compatible = "microchip,lan9662-otp", }, -+ { .compatible = "microchip,lan9662-otpc", }, - { }, - }; - MODULE_DEVICE_TABLE(of, lan9662_otp_match); diff --git a/target/linux/generic/backport-5.15/807-v6.1-0011-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch b/target/linux/generic/backport-5.15/807-v6.1-0011-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch deleted file mode 100644 index 967e891dbd9c5f..00000000000000 --- a/target/linux/generic/backport-5.15/807-v6.1-0011-nvmem-u-boot-env-fix-crc32_data_offset-on-redundant-.patch +++ /dev/null @@ -1,59 +0,0 @@ -From ee424f7d3960152f5f862bbb6943e59828dc7917 Mon Sep 17 00:00:00 2001 -From: Christian Lamparter -Date: Fri, 4 Nov 2022 17:52:03 +0100 -Subject: [PATCH] nvmem: u-boot-env: fix crc32_data_offset on redundant - u-boot-env - -The Western Digital MyBook Live (PowerPC 464/APM82181) -has a set of redundant u-boot-env. Loading up the driver -the following error: - -| u_boot_env: Invalid calculated CRC32: 0x4f8f2c86 (expected: 0x98b14514) -| u_boot_env: probe of partition@1e000 failed with error -22 - -Looking up the userspace libubootenv utilities source [0], -it looks like the "mark" or "flag" is not part of the -crc32 sum... which is unfortunate :( - -|static int libuboot_load(struct uboot_ctx *ctx) -|{ -|[...] -| if (ctx->redundant) { -| [...] -| offsetdata = offsetof(struct uboot_env_redund, data); -| [...] //-----^^ -| } -| usable_envsize = ctx->size - offsetdata; -| buf[0] = malloc(bufsize); -|[...] -| for (i = 0; i < copies; i++) { -| data = (uint8_t *)(buf[i] + offsetdata); -| uint32_t crc; -| -| ret = devread(ctx, i, buf[i]); -| [...] -| crc = *(uint32_t *)(buf[i] + offsetcrc); -| dev->crc = crc32(0, (uint8_t *)data, usable_envsize); -| - -[0] https://github.com/sbabic/libubootenv/blob/master/src/uboot_env.c#L951 - -Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables") -Signed-off-by: Christian Lamparter -Link: https://lore.kernel.org/r/70a16eae113e08db2390b76e174f4837caa135c3.1667580636.git.chunkeey@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -135,7 +135,7 @@ static int u_boot_env_parse(struct u_boo - break; - case U_BOOT_FORMAT_REDUNDANT: - crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32); -- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, mark); -+ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); - data_offset = offsetof(struct u_boot_env_image_redundant, data); - break; - } diff --git a/target/linux/generic/backport-5.15/807-v6.1-0013-nvmem-lan9662-otp-Change-return-type-of-lan9662_otp_.patch b/target/linux/generic/backport-5.15/807-v6.1-0013-nvmem-lan9662-otp-Change-return-type-of-lan9662_otp_.patch deleted file mode 100644 index 0c842f0793219b..00000000000000 --- a/target/linux/generic/backport-5.15/807-v6.1-0013-nvmem-lan9662-otp-Change-return-type-of-lan9662_otp_.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 022b68f271de0e53024e6d5e96fee8e76d25eb95 Mon Sep 17 00:00:00 2001 -From: Horatiu Vultur -Date: Fri, 18 Nov 2022 06:38:40 +0000 -Subject: [PATCH] nvmem: lan9662-otp: Change return type of - lan9662_otp_wait_flag_clear() - -The blamed commit introduced the following smatch warning in the -function lan9662_otp_wait_flag_clear: -drivers/nvmem/lan9662-otpc.c:43 lan9662_otp_wait_flag_clear() warn: signedness bug returning '(-110)' - -Fix this by changing the return type of the function -lan9662_otp_wait_flag_clear() to be int instead of bool. - -Fixes: 9e8f208ad5229d ("nvmem: lan9662-otp: add support") -Reported-by: kernel test robot -Reported-by: Dan Carpenter -Signed-off-by: Horatiu Vultur -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063840.6357-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/lan9662-otpc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/lan9662-otpc.c -+++ b/drivers/nvmem/lan9662-otpc.c -@@ -36,7 +36,7 @@ struct lan9662_otp { - void __iomem *base; - }; - --static bool lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) -+static int lan9662_otp_wait_flag_clear(void __iomem *reg, u32 flag) - { - u32 val; - diff --git a/target/linux/generic/backport-5.15/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch b/target/linux/generic/backport-5.15/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch deleted file mode 100644 index 33759632ebe4f4..00000000000000 --- a/target/linux/generic/backport-5.15/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch +++ /dev/null @@ -1,82 +0,0 @@ -From fbfc4ca465a1f8d81bf2d67d95bf7fc67c3cf0c2 Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Fri, 18 Nov 2022 06:39:20 +0000 -Subject: [PATCH] nvmem: stm32: move STM32MP15_BSEC_NUM_LOWER in config - -Support STM32MP15_BSEC_NUM_LOWER in stm32 romem config to prepare -the next SoC in STM32MP family. - -Signed-off-by: Patrick Delaunay -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 21 ++++++++++++++++----- - 1 file changed, 16 insertions(+), 5 deletions(-) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -22,16 +22,15 @@ - /* shadow registers offest */ - #define STM32MP15_BSEC_DATA0 0x200 - --/* 32 (x 32-bits) lower shadow registers */ --#define STM32MP15_BSEC_NUM_LOWER 32 -- - struct stm32_romem_cfg { - int size; -+ u8 lower; - }; - - struct stm32_romem_priv { - void __iomem *base; - struct nvmem_config cfg; -+ u8 lower; - }; - - static int stm32_romem_read(void *context, unsigned int offset, void *buf, -@@ -85,7 +84,7 @@ static int stm32_bsec_read(void *context - for (i = roffset; (i < roffset + rbytes); i += 4) { - u32 otp = i >> 2; - -- if (otp < STM32MP15_BSEC_NUM_LOWER) { -+ if (otp < priv->lower) { - /* read lower data from shadow registers */ - val = readl_relaxed( - priv->base + STM32MP15_BSEC_DATA0 + i); -@@ -159,6 +158,8 @@ static int stm32_romem_probe(struct plat - priv->cfg.priv = priv; - priv->cfg.owner = THIS_MODULE; - -+ priv->lower = 0; -+ - cfg = (const struct stm32_romem_cfg *) - of_match_device(dev->driver->of_match_table, dev)->data; - if (!cfg) { -@@ -167,6 +168,7 @@ static int stm32_romem_probe(struct plat - priv->cfg.reg_read = stm32_romem_read; - } else { - priv->cfg.size = cfg->size; -+ priv->lower = cfg->lower; - priv->cfg.reg_read = stm32_bsec_read; - priv->cfg.reg_write = stm32_bsec_write; - } -@@ -174,8 +176,17 @@ static int stm32_romem_probe(struct plat - return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); - } - -+/* -+ * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) -+ * => 96 x 32-bits data words -+ * - Lower: 1K bits, 2:1 redundancy, incremental bit programming -+ * => 32 (x 32-bits) lower shadow registers = words 0 to 31 -+ * - Upper: 2K bits, ECC protection, word programming only -+ * => 64 (x 32-bits) = words 32 to 95 -+ */ - static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { -- .size = 384, /* 96 x 32-bits data words */ -+ .size = 384, -+ .lower = 32, - }; - - static const struct of_device_id stm32_romem_of_match[] = { diff --git a/target/linux/generic/backport-5.15/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch b/target/linux/generic/backport-5.15/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch deleted file mode 100644 index 5791df2606ffe3..00000000000000 --- a/target/linux/generic/backport-5.15/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d61784e6410f3df2028e6eb91b06ffed37a660e0 Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Fri, 18 Nov 2022 06:39:21 +0000 -Subject: [PATCH] nvmem: stm32: add warning when upper OTPs are updated - -As the upper OTPs are ECC protected, they support only one 32 bits word -programming. -For a second modification of this word, these ECC become invalid and -this OTP will be no more accessible, the shadowed value is invalid. - -This patch adds a warning to indicate an upper OTP update, because this -operation is dangerous as OTP is not locked by the driver after the first -update to avoid a second update. - -Signed-off-by: Patrick Delaunay -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -132,6 +132,9 @@ static int stm32_bsec_write(void *contex - } - } - -+ if (offset + bytes >= priv->lower * 4) -+ dev_warn(dev, "Update of upper OTPs with ECC protection (word programming, only once)\n"); -+ - return 0; - } - diff --git a/target/linux/generic/backport-5.15/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch b/target/linux/generic/backport-5.15/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch deleted file mode 100644 index b83ad69c6b4ebb..00000000000000 --- a/target/linux/generic/backport-5.15/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch +++ /dev/null @@ -1,26 +0,0 @@ -From a3816a7d7c097c1da46aad5f5d1e229b607dce04 Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Fri, 18 Nov 2022 06:39:22 +0000 -Subject: [PATCH] nvmem: stm32: add nvmem type attribute - -Inform NVMEM framework of type attribute for stm32-romem as NVMEM_TYPE_OTP -so userspace is able to know how the data is stored in BSEC. - -Signed-off-by: Patrick Delaunay -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -160,6 +160,7 @@ static int stm32_romem_probe(struct plat - priv->cfg.dev = dev; - priv->cfg.priv = priv; - priv->cfg.owner = THIS_MODULE; -+ priv->cfg.type = NVMEM_TYPE_OTP; - - priv->lower = 0; - diff --git a/target/linux/generic/backport-5.15/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch b/target/linux/generic/backport-5.15/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch deleted file mode 100644 index 52ba1e65b567fa..00000000000000 --- a/target/linux/generic/backport-5.15/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 06aac0e11960a7ddccc1888326b5906d017e0f24 Mon Sep 17 00:00:00 2001 -From: Jiangshan Yi -Date: Fri, 18 Nov 2022 06:39:24 +0000 -Subject: [PATCH] nvmem: stm32: fix spelling typo in comment - -Fix spelling typo in comment. - -Reported-by: k2ci -Signed-off-by: Jiangshan Yi -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -19,7 +19,7 @@ - #define STM32_SMC_WRITE_SHADOW 0x03 - #define STM32_SMC_READ_OTP 0x04 - --/* shadow registers offest */ -+/* shadow registers offset */ - #define STM32MP15_BSEC_DATA0 0x200 - - struct stm32_romem_cfg { diff --git a/target/linux/generic/backport-5.15/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch b/target/linux/generic/backport-5.15/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch deleted file mode 100644 index 8f024f4c1acb8b..00000000000000 --- a/target/linux/generic/backport-5.15/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch +++ /dev/null @@ -1,27 +0,0 @@ -From fb817c4ef63e8cfb6e77ae4a2875ae854c80708f Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Fri, 18 Nov 2022 06:39:26 +0000 -Subject: [PATCH] nvmem: Kconfig: Fix spelling mistake "controlls" -> - "controls" - -There is a spelling mistake in a Kconfig description. Fix it. - -Signed-off-by: Colin Ian King -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -164,7 +164,7 @@ config NVMEM_MICROCHIP_OTPC - depends on ARCH_AT91 || COMPILE_TEST - help - This driver enable the OTP controller available on Microchip SAMA7G5 -- SoCs. It controlls the access to the OTP memory connected to it. -+ SoCs. It controls the access to the OTP memory connected to it. - - config NVMEM_MTK_EFUSE - tristate "Mediatek SoCs EFUSE support" diff --git a/target/linux/generic/backport-5.15/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch b/target/linux/generic/backport-5.15/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch deleted file mode 100644 index 861386ad310b59..00000000000000 --- a/target/linux/generic/backport-5.15/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch +++ /dev/null @@ -1,67 +0,0 @@ -From ada84d07af6097b2addd18262668ce6cb9e15206 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 18 Nov 2022 06:39:27 +0000 -Subject: [PATCH] nvmem: u-boot-env: add Broadcom format support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Broadcom uses U-Boot for a lot of their bcmbca familiy chipsets. They -decided to store U-Boot environment data inside U-Boot partition and to -use a custom header (with "uEnv" magic and env data length). - -Add support for Broadcom's specific binding and their custom format. - -Ref: 6b0584c19d87 ("dt-bindings: nvmem: u-boot,env: add Broadcom's variant binding") -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -16,6 +16,7 @@ - enum u_boot_env_format { - U_BOOT_FORMAT_SINGLE, - U_BOOT_FORMAT_REDUNDANT, -+ U_BOOT_FORMAT_BROADCOM, - }; - - struct u_boot_env { -@@ -40,6 +41,13 @@ struct u_boot_env_image_redundant { - uint8_t data[]; - } __packed; - -+struct u_boot_env_image_broadcom { -+ __le32 magic; -+ __le32 len; -+ __le32 crc32; -+ uint8_t data[0]; -+} __packed; -+ - static int u_boot_env_read(void *context, unsigned int offset, void *val, - size_t bytes) - { -@@ -138,6 +146,11 @@ static int u_boot_env_parse(struct u_boo - crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); - data_offset = offsetof(struct u_boot_env_image_redundant, data); - break; -+ case U_BOOT_FORMAT_BROADCOM: -+ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32); -+ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data); -+ data_offset = offsetof(struct u_boot_env_image_broadcom, data); -+ break; - } - crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); - crc32_data_len = priv->mtd->size - crc32_data_offset; -@@ -202,6 +215,7 @@ static const struct of_device_id u_boot_ - { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, }, - { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, - { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, -+ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, }, - {}, - }; - diff --git a/target/linux/generic/backport-5.15/808-v6.2-0007-nvmem-brcm_nvram-Add-check-for-kzalloc.patch b/target/linux/generic/backport-5.15/808-v6.2-0007-nvmem-brcm_nvram-Add-check-for-kzalloc.patch deleted file mode 100644 index 14108b59276857..00000000000000 --- a/target/linux/generic/backport-5.15/808-v6.2-0007-nvmem-brcm_nvram-Add-check-for-kzalloc.patch +++ /dev/null @@ -1,30 +0,0 @@ -From b0576ade3aaf24b376ea1a4406ae138e2a22b0c0 Mon Sep 17 00:00:00 2001 -From: Jiasheng Jiang -Date: Fri, 27 Jan 2023 10:40:06 +0000 -Subject: [PATCH] nvmem: brcm_nvram: Add check for kzalloc - -Add the check for the return value of kzalloc in order to avoid -NULL pointer dereference. - -Fixes: 6e977eaa8280 ("nvmem: brcm_nvram: parse NVRAM content into NVMEM cells") -Cc: stable@vger.kernel.org -Signed-off-by: Jiasheng Jiang -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230127104015.23839-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/brcm_nvram.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -97,6 +97,9 @@ static int brcm_nvram_parse(struct brcm_ - len = le32_to_cpu(header.len); - - data = kzalloc(len, GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ - memcpy_fromio(data, priv->base, len); - data[len - 1] = '\0'; - diff --git a/target/linux/generic/backport-5.15/808-v6.2-0008-nvmem-sunxi_sid-Always-use-32-bit-MMIO-reads.patch b/target/linux/generic/backport-5.15/808-v6.2-0008-nvmem-sunxi_sid-Always-use-32-bit-MMIO-reads.patch deleted file mode 100644 index 632b01cb2ac8f3..00000000000000 --- a/target/linux/generic/backport-5.15/808-v6.2-0008-nvmem-sunxi_sid-Always-use-32-bit-MMIO-reads.patch +++ /dev/null @@ -1,55 +0,0 @@ -From c151d5ed8e8fe0474bd61dce7f2076ca5916c683 Mon Sep 17 00:00:00 2001 -From: Samuel Holland -Date: Fri, 27 Jan 2023 10:40:07 +0000 -Subject: [PATCH] nvmem: sunxi_sid: Always use 32-bit MMIO reads - -The SID SRAM on at least some SoCs (A64 and D1) returns different values -when read with bus cycles narrower than 32 bits. This is not immediately -obvious, because memcpy_fromio() uses word-size accesses as long as -enough data is being copied. - -The vendor driver always uses 32-bit MMIO reads, so do the same here. -This is faster than the register-based method, which is currently used -as a workaround on A64. And it fixes the values returned on D1, where -the SRAM method was being used. - -The special case for the last word is needed to maintain .word_size == 1 -for sysfs ABI compatibility, as noted previously in commit de2a3eaea552 -("nvmem: sunxi_sid: Optimize register read-out method"). - -Fixes: 07ae4fde9efa ("nvmem: sunxi_sid: Add support for D1 variant") -Cc: stable@vger.kernel.org -Tested-by: Heiko Stuebner -Signed-off-by: Samuel Holland -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230127104015.23839-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sunxi_sid.c | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - ---- a/drivers/nvmem/sunxi_sid.c -+++ b/drivers/nvmem/sunxi_sid.c -@@ -41,8 +41,21 @@ static int sunxi_sid_read(void *context, - void *val, size_t bytes) - { - struct sunxi_sid *sid = context; -+ u32 word; - -- memcpy_fromio(val, sid->base + sid->value_offset + offset, bytes); -+ /* .stride = 4 so offset is guaranteed to be aligned */ -+ __ioread32_copy(val, sid->base + sid->value_offset + offset, bytes / 4); -+ -+ val += round_down(bytes, 4); -+ offset += round_down(bytes, 4); -+ bytes = bytes % 4; -+ -+ if (!bytes) -+ return 0; -+ -+ /* Handle any trailing bytes */ -+ word = readl_relaxed(sid->base + sid->value_offset + offset); -+ memcpy(val, &word, bytes); - - return 0; - } diff --git a/target/linux/generic/backport-5.15/808-v6.2-0013-nvmem-core-fix-device-node-refcounting.patch b/target/linux/generic/backport-5.15/808-v6.2-0013-nvmem-core-fix-device-node-refcounting.patch deleted file mode 100644 index a229c303ad0f8c..00000000000000 --- a/target/linux/generic/backport-5.15/808-v6.2-0013-nvmem-core-fix-device-node-refcounting.patch +++ /dev/null @@ -1,48 +0,0 @@ -From edcf2fb660526b5ed29f93bd17328a2b4835c8b2 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Fri, 27 Jan 2023 10:40:12 +0000 -Subject: [PATCH] nvmem: core: fix device node refcounting - -In of_nvmem_cell_get(), of_get_next_parent() is used on cell_np. This -will decrement the refcount on cell_np, but cell_np is still used later -in the code. Use of_get_parent() instead and of_node_put() in the -appropriate places. - -Fixes: 69aba7948cbe ("nvmem: Add a simple NVMEM framework for consumers") -Fixes: 7ae6478b304b ("nvmem: core: rework nvmem cell instance creation") -Cc: stable@vger.kernel.org -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230127104015.23839-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -1237,16 +1237,21 @@ struct nvmem_cell *of_nvmem_cell_get(str - if (!cell_np) - return ERR_PTR(-ENOENT); - -- nvmem_np = of_get_next_parent(cell_np); -- if (!nvmem_np) -+ nvmem_np = of_get_parent(cell_np); -+ if (!nvmem_np) { -+ of_node_put(cell_np); - return ERR_PTR(-EINVAL); -+ } - - nvmem = __nvmem_device_get(nvmem_np, device_match_of_node); - of_node_put(nvmem_np); -- if (IS_ERR(nvmem)) -+ if (IS_ERR(nvmem)) { -+ of_node_put(cell_np); - return ERR_CAST(nvmem); -+ } - - cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np); -+ of_node_put(cell_np); - if (!cell_entry) { - __nvmem_device_put(nvmem); - return ERR_PTR(-ENOENT); diff --git a/target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch b/target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch deleted file mode 100644 index 01400fd490d027..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 2e8dc541ae207349b51c65391be625ffe1f86e0c Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 6 Feb 2023 13:43:41 +0000 -Subject: [PATCH] nvmem: core: remove spurious white space - -Remove a spurious white space in for the ida_alloc() call. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -764,7 +764,7 @@ struct nvmem_device *nvmem_register(cons - if (!nvmem) - return ERR_PTR(-ENOMEM); - -- rval = ida_alloc(&nvmem_ida, GFP_KERNEL); -+ rval = ida_alloc(&nvmem_ida, GFP_KERNEL); - if (rval < 0) { - kfree(nvmem); - return ERR_PTR(rval); diff --git a/target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch b/target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch deleted file mode 100644 index 454d3bf0ed1a4b..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 5d8e6e6c10a3d37486d263b16ddc15991a7e4a88 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:46 +0000 -Subject: [PATCH] nvmem: core: add an index parameter to the cell - -Sometimes a cell can represend multiple values. For example, a base -ethernet address stored in the NVMEM can be expanded into multiple -discreet ones by adding an offset. - -For this use case, introduce an index parameter which is then used to -distiguish between values. This parameter will then be passed to the -post process hook which can then use it to create different values -during reading. - -At the moment, there is only support for the device tree path. You can -add the index to the phandle, e.g. - - &net { - nvmem-cells = <&base_mac_address 2>; - nvmem-cell-names = "mac-address"; - }; - - &nvmem_provider { - base_mac_address: base-mac-address@0 { - #nvmem-cell-cells = <1>; - reg = <0 6>; - }; - }; - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-13-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 37 ++++++++++++++++++++++++---------- - drivers/nvmem/imx-ocotp.c | 4 ++-- - include/linux/nvmem-provider.h | 4 ++-- - 3 files changed, 30 insertions(+), 15 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -60,6 +60,7 @@ struct nvmem_cell_entry { - struct nvmem_cell { - struct nvmem_cell_entry *entry; - const char *id; -+ int index; - }; - - static DEFINE_MUTEX(nvmem_mutex); -@@ -1122,7 +1123,8 @@ struct nvmem_device *devm_nvmem_device_g - } - EXPORT_SYMBOL_GPL(devm_nvmem_device_get); - --static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id) -+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, -+ const char *id, int index) - { - struct nvmem_cell *cell; - const char *name = NULL; -@@ -1141,6 +1143,7 @@ static struct nvmem_cell *nvmem_create_c - - cell->id = name; - cell->entry = entry; -+ cell->index = index; - - return cell; - } -@@ -1179,7 +1182,7 @@ nvmem_cell_get_from_lookup(struct device - __nvmem_device_put(nvmem); - cell = ERR_PTR(-ENOENT); - } else { -- cell = nvmem_create_cell(cell_entry, con_id); -+ cell = nvmem_create_cell(cell_entry, con_id, 0); - if (IS_ERR(cell)) - __nvmem_device_put(nvmem); - } -@@ -1227,15 +1230,27 @@ struct nvmem_cell *of_nvmem_cell_get(str - struct nvmem_device *nvmem; - struct nvmem_cell_entry *cell_entry; - struct nvmem_cell *cell; -+ struct of_phandle_args cell_spec; - int index = 0; -+ int cell_index = 0; -+ int ret; - - /* if cell name exists, find index to the name */ - if (id) - index = of_property_match_string(np, "nvmem-cell-names", id); - -- cell_np = of_parse_phandle(np, "nvmem-cells", index); -- if (!cell_np) -- return ERR_PTR(-ENOENT); -+ ret = of_parse_phandle_with_optional_args(np, "nvmem-cells", -+ "#nvmem-cell-cells", -+ index, &cell_spec); -+ if (ret) -+ return ERR_PTR(ret); -+ -+ if (cell_spec.args_count > 1) -+ return ERR_PTR(-EINVAL); -+ -+ cell_np = cell_spec.np; -+ if (cell_spec.args_count) -+ cell_index = cell_spec.args[0]; - - nvmem_np = of_get_parent(cell_np); - if (!nvmem_np) { -@@ -1257,7 +1272,7 @@ struct nvmem_cell *of_nvmem_cell_get(str - return ERR_PTR(-ENOENT); - } - -- cell = nvmem_create_cell(cell_entry, id); -+ cell = nvmem_create_cell(cell_entry, id, cell_index); - if (IS_ERR(cell)) - __nvmem_device_put(nvmem); - -@@ -1410,8 +1425,8 @@ static void nvmem_shift_read_buffer_in_p - } - - static int __nvmem_cell_read(struct nvmem_device *nvmem, -- struct nvmem_cell_entry *cell, -- void *buf, size_t *len, const char *id) -+ struct nvmem_cell_entry *cell, -+ void *buf, size_t *len, const char *id, int index) - { - int rc; - -@@ -1425,7 +1440,7 @@ static int __nvmem_cell_read(struct nvme - nvmem_shift_read_buffer_in_place(cell, buf); - - if (nvmem->cell_post_process) { -- rc = nvmem->cell_post_process(nvmem->priv, id, -+ rc = nvmem->cell_post_process(nvmem->priv, id, index, - cell->offset, buf, cell->bytes); - if (rc) - return rc; -@@ -1460,7 +1475,7 @@ void *nvmem_cell_read(struct nvmem_cell - if (!buf) - return ERR_PTR(-ENOMEM); - -- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id); -+ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index); - if (rc) { - kfree(buf); - return ERR_PTR(rc); -@@ -1773,7 +1788,7 @@ ssize_t nvmem_device_cell_read(struct nv - if (rc) - return rc; - -- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL); -+ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0); - if (rc) - return rc; - ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -222,8 +222,8 @@ read_end: - return ret; - } - --static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset, -- void *data, size_t bytes) -+static int imx_ocotp_cell_pp(void *context, const char *id, int index, -+ unsigned int offset, void *data, size_t bytes) - { - struct ocotp_priv *priv = context; - ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -20,8 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *pr - typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, - void *val, size_t bytes); - /* used for vendor specific post processing of cell data */ --typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset, -- void *buf, size_t bytes); -+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, -+ unsigned int offset, void *buf, size_t bytes); - - enum nvmem_type { - NVMEM_TYPE_UNKNOWN = 0, diff --git a/target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch b/target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch deleted file mode 100644 index f3829b3e17f4f6..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch +++ /dev/null @@ -1,78 +0,0 @@ -From fbd03d27776c6121a483921601418e3c8f0ff37e Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:47 +0000 -Subject: [PATCH] nvmem: core: move struct nvmem_cell_info to nvmem-provider.h - -struct nvmem_cell_info is used to describe a cell. Thus this should -really be in the nvmem-provider's header. There are two (unused) nvmem -access methods which use the nvmem_cell_info to describe the cell to be -accesses. One can argue, that they will create a cell before accessing, -thus they are both a provider and a consumer. - -struct nvmem_cell_info will get used more and more by nvmem-providers, -don't force them to also include the consumer header, although they are -not. - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-14-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - include/linux/nvmem-consumer.h | 10 +--------- - include/linux/nvmem-provider.h | 19 ++++++++++++++++++- - 2 files changed, 19 insertions(+), 10 deletions(-) - ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -18,15 +18,7 @@ struct device_node; - /* consumer cookie */ - struct nvmem_cell; - struct nvmem_device; -- --struct nvmem_cell_info { -- const char *name; -- unsigned int offset; -- unsigned int bytes; -- unsigned int bit_offset; -- unsigned int nbits; -- struct device_node *np; --}; -+struct nvmem_cell_info; - - /** - * struct nvmem_cell_lookup - cell lookup entry ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -14,7 +14,6 @@ - #include - - struct nvmem_device; --struct nvmem_cell_info; - typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, - void *val, size_t bytes); - typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, -@@ -48,6 +47,24 @@ struct nvmem_keepout { - }; - - /** -+ * struct nvmem_cell_info - NVMEM cell description -+ * @name: Name. -+ * @offset: Offset within the NVMEM device. -+ * @bytes: Length of the cell. -+ * @bit_offset: Bit offset if cell is smaller than a byte. -+ * @nbits: Number of bits. -+ * @np: Optional device_node pointer. -+ */ -+struct nvmem_cell_info { -+ const char *name; -+ unsigned int offset; -+ unsigned int bytes; -+ unsigned int bit_offset; -+ unsigned int nbits; -+ struct device_node *np; -+}; -+ -+/** - * struct nvmem_config - NVMEM device configuration - * - * @dev: Parent device. diff --git a/target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch b/target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch deleted file mode 100644 index 8f996eab348ff4..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch +++ /dev/null @@ -1,65 +0,0 @@ -From cc5bdd323dde6494623f3ffe3a5b887fa21cd375 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:48 +0000 -Subject: [PATCH] nvmem: core: drop the removal of the cells in - nvmem_add_cells() - -If nvmem_add_cells() fails, the whole nvmem_register() will fail -and the cells will then be removed anyway. This is a preparation -to introduce a nvmem_add_one_cell() which can then be used by -nvmem_add_cells(). - -This is then the same to what nvmem_add_cells_from_table() and -nvmem_add_cells_from_of() do. - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-15-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 14 ++++---------- - 1 file changed, 4 insertions(+), 10 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -515,7 +515,7 @@ static int nvmem_add_cells(struct nvmem_ - int ncells) - { - struct nvmem_cell_entry **cells; -- int i, rval; -+ int i, rval = 0; - - cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); - if (!cells) -@@ -525,28 +525,22 @@ static int nvmem_add_cells(struct nvmem_ - cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); - if (!cells[i]) { - rval = -ENOMEM; -- goto err; -+ goto out; - } - - rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); - if (rval) { - kfree(cells[i]); -- goto err; -+ goto out; - } - - nvmem_cell_entry_add(cells[i]); - } - -+out: - /* remove tmp array */ - kfree(cells); - -- return 0; --err: -- while (i--) -- nvmem_cell_entry_drop(cells[i]); -- -- kfree(cells); -- - return rval; - } - diff --git a/target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch b/target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch deleted file mode 100644 index 711ce229b2c748..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 2ded6830d376d5e7bf43d59f7f7fdf1a59abc676 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:49 +0000 -Subject: [PATCH] nvmem: core: add nvmem_add_one_cell() - -Add a new function to add exactly one cell. This will be used by the -nvmem layout drivers to add custom cells. In contrast to the -nvmem_add_cells(), this has the advantage that we don't have to assemble -a list of cells on runtime. - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-16-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 59 ++++++++++++++++++++-------------- - include/linux/nvmem-provider.h | 8 +++++ - 2 files changed, 43 insertions(+), 24 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -502,6 +502,36 @@ static int nvmem_cell_info_to_nvmem_cell - } - - /** -+ * nvmem_add_one_cell() - Add one cell information to an nvmem device -+ * -+ * @nvmem: nvmem device to add cells to. -+ * @info: nvmem cell info to add to the device -+ * -+ * Return: 0 or negative error code on failure. -+ */ -+int nvmem_add_one_cell(struct nvmem_device *nvmem, -+ const struct nvmem_cell_info *info) -+{ -+ struct nvmem_cell_entry *cell; -+ int rval; -+ -+ cell = kzalloc(sizeof(*cell), GFP_KERNEL); -+ if (!cell) -+ return -ENOMEM; -+ -+ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell); -+ if (rval) { -+ kfree(cell); -+ return rval; -+ } -+ -+ nvmem_cell_entry_add(cell); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(nvmem_add_one_cell); -+ -+/** - * nvmem_add_cells() - Add cell information to an nvmem device - * - * @nvmem: nvmem device to add cells to. -@@ -514,34 +544,15 @@ static int nvmem_add_cells(struct nvmem_ - const struct nvmem_cell_info *info, - int ncells) - { -- struct nvmem_cell_entry **cells; -- int i, rval = 0; -- -- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); -- if (!cells) -- return -ENOMEM; -+ int i, rval; - - for (i = 0; i < ncells; i++) { -- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); -- if (!cells[i]) { -- rval = -ENOMEM; -- goto out; -- } -- -- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); -- if (rval) { -- kfree(cells[i]); -- goto out; -- } -- -- nvmem_cell_entry_add(cells[i]); -+ rval = nvmem_add_one_cell(nvmem, &info[i]); -+ if (rval) -+ return rval; - } - --out: -- /* remove tmp array */ -- kfree(cells); -- -- return rval; -+ return 0; - } - - /** ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -153,6 +153,9 @@ struct nvmem_device *devm_nvmem_register - void nvmem_add_cell_table(struct nvmem_cell_table *table); - void nvmem_del_cell_table(struct nvmem_cell_table *table); - -+int nvmem_add_one_cell(struct nvmem_device *nvmem, -+ const struct nvmem_cell_info *info); -+ - #else - - static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) -@@ -170,6 +173,11 @@ devm_nvmem_register(struct device *dev, - - static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} - static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} -+static inline int nvmem_add_one_cell(struct nvmem_device *nvmem, -+ const struct nvmem_cell_info *info) -+{ -+ return -EOPNOTSUPP; -+} - - #endif /* CONFIG_NVMEM */ - #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch b/target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch deleted file mode 100644 index e1791e5c83cff0..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 50014d659617dc58780a5d31ceb76c82779a9d8b Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:50 +0000 -Subject: [PATCH] nvmem: core: use nvmem_add_one_cell() in - nvmem_add_cells_from_of() - -Convert nvmem_add_cells_from_of() to use the new nvmem_add_one_cell(). -This will remove duplicate code and it will make it possible to add a -hook to a nvmem layout in between, which can change fields before the -cell is finally added. - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-17-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 45 ++++++++++++++------------------------------ - 1 file changed, 14 insertions(+), 31 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -688,15 +688,14 @@ static int nvmem_validate_keepouts(struc - - static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) - { -- struct device_node *parent, *child; - struct device *dev = &nvmem->dev; -- struct nvmem_cell_entry *cell; -+ struct device_node *child; - const __be32 *addr; -- int len; -+ int len, ret; - -- parent = dev->of_node; -+ for_each_child_of_node(dev->of_node, child) { -+ struct nvmem_cell_info info = {0}; - -- for_each_child_of_node(parent, child) { - addr = of_get_property(child, "reg", &len); - if (!addr) - continue; -@@ -706,40 +705,24 @@ static int nvmem_add_cells_from_of(struc - return -EINVAL; - } - -- cell = kzalloc(sizeof(*cell), GFP_KERNEL); -- if (!cell) { -- of_node_put(child); -- return -ENOMEM; -- } -- -- cell->nvmem = nvmem; -- cell->offset = be32_to_cpup(addr++); -- cell->bytes = be32_to_cpup(addr); -- cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); -+ info.offset = be32_to_cpup(addr++); -+ info.bytes = be32_to_cpup(addr); -+ info.name = kasprintf(GFP_KERNEL, "%pOFn", child); - - addr = of_get_property(child, "bits", &len); - if (addr && len == (2 * sizeof(u32))) { -- cell->bit_offset = be32_to_cpup(addr++); -- cell->nbits = be32_to_cpup(addr); -+ info.bit_offset = be32_to_cpup(addr++); -+ info.nbits = be32_to_cpup(addr); - } - -- if (cell->nbits) -- cell->bytes = DIV_ROUND_UP( -- cell->nbits + cell->bit_offset, -- BITS_PER_BYTE); -- -- if (!IS_ALIGNED(cell->offset, nvmem->stride)) { -- dev_err(dev, "cell %s unaligned to nvmem stride %d\n", -- cell->name, nvmem->stride); -- /* Cells already added will be freed later. */ -- kfree_const(cell->name); -- kfree(cell); -+ info.np = of_node_get(child); -+ -+ ret = nvmem_add_one_cell(nvmem, &info); -+ kfree(info.name); -+ if (ret) { - of_node_put(child); -- return -EINVAL; -+ return ret; - } -- -- cell->np = of_node_get(child); -- nvmem_cell_entry_add(cell); - } - - return 0; diff --git a/target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch b/target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch deleted file mode 100644 index 172a78b76af1a6..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch +++ /dev/null @@ -1,562 +0,0 @@ -From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Mon, 6 Feb 2023 13:43:51 +0000 -Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x - -For boot with OP-TEE on STM32MP13, the communication with the secure -world no more use STMicroelectronics SMC but communication with the -STM32MP BSEC TA, for data access (read/write) or lock operation: -- all the request are sent to OP-TEE trusted application, -- for upper OTP with ECC protection and with word programming only - each OTP are permanently locked when programmed to avoid ECC error - on the second write operation - -Signed-off-by: Patrick Delaunay -Reviewed-by: Etienne Carriere -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 11 + - drivers/nvmem/Makefile | 1 + - drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++ - drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++ - drivers/nvmem/stm32-romem.c | 54 ++++- - 5 files changed, 441 insertions(+), 3 deletions(-) - create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c - create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE - This driver can also be built as a module. If so, the module - will be called nvmem-sprd-efuse. - -+config NVMEM_STM32_BSEC_OPTEE_TA -+ bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver" -+ depends on OPTEE -+ help -+ Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE -+ trusted application STM32MP BSEC. -+ -+ This library is a used by stm32-romem driver or included in the module -+ called nvmem-stm32-romem. -+ - config NVMEM_STM32_ROMEM - tristate "STMicroelectronics STM32 factory-programmed memory support" - depends on ARCH_STM32 || COMPILE_TEST -+ imply NVMEM_STM32_BSEC_OPTEE_TA - help - Say y here to enable read-only access for STMicroelectronics STM32 - factory-programmed memory area. ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem - nvmem_sprd_efuse-y := sprd-efuse.o - obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o - nvmem_stm32_romem-y := stm32-romem.o -+nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o - obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o - nvmem_sunplus_ocotp-y := sunplus-ocotp.o - obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o ---- /dev/null -+++ b/drivers/nvmem/stm32-bsec-optee-ta.c -@@ -0,0 +1,298 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver -+ * -+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+ -+#include "stm32-bsec-optee-ta.h" -+ -+/* -+ * Read OTP memory -+ * -+ * [in] value[0].a OTP start offset in byte -+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) -+ * [out] memref[1].buffer Output buffer to store read values -+ * [out] memref[1].size Size of OTP to be read -+ * -+ * Return codes: -+ * TEE_SUCCESS - Invoke command success -+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param -+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller -+ */ -+#define PTA_BSEC_READ_MEM 0x0 -+ -+/* -+ * Write OTP memory -+ * -+ * [in] value[0].a OTP start offset in byte -+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) -+ * [in] memref[1].buffer Input buffer to read values -+ * [in] memref[1].size Size of OTP to be written -+ * -+ * Return codes: -+ * TEE_SUCCESS - Invoke command success -+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param -+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller -+ */ -+#define PTA_BSEC_WRITE_MEM 0x1 -+ -+/* value of PTA_BSEC access type = value[in] b */ -+#define SHADOW_ACCESS 0 -+#define FUSE_ACCESS 1 -+#define LOCK_ACCESS 2 -+ -+/* Bitfield definition for LOCK status */ -+#define LOCK_PERM BIT(30) -+ -+/* OP-TEE STM32MP BSEC TA UUID */ -+static const uuid_t stm32mp_bsec_ta_uuid = -+ UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5, -+ 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03); -+ -+/* -+ * Check whether this driver supports the BSEC TA in the TEE instance -+ * represented by the params (ver/data) to this function. -+ */ -+static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver, -+ const void *data) -+{ -+ /* Currently this driver only supports GP compliant, OP-TEE based TA */ -+ if ((ver->impl_id == TEE_IMPL_ID_OPTEE) && -+ (ver->gen_caps & TEE_GEN_CAP_GP)) -+ return 1; -+ else -+ return 0; -+} -+ -+/* Open a session to OP-TEE for STM32MP BSEC TA */ -+static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id) -+{ -+ struct tee_ioctl_open_session_arg sess_arg; -+ int rc; -+ -+ memset(&sess_arg, 0, sizeof(sess_arg)); -+ export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid); -+ sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; -+ sess_arg.num_params = 0; -+ -+ rc = tee_client_open_session(ctx, &sess_arg, NULL); -+ if ((rc < 0) || (sess_arg.ret != 0)) { -+ pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n", -+ __func__, sess_arg.ret, rc); -+ if (!rc) -+ rc = -EINVAL; -+ } else { -+ *id = sess_arg.session; -+ } -+ -+ return rc; -+} -+ -+/* close a session to OP-TEE for STM32MP BSEC TA */ -+static void stm32_bsec_ta_close_session(void *ctx, u32 id) -+{ -+ tee_client_close_session(ctx, id); -+} -+ -+/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */ -+int stm32_bsec_optee_ta_open(struct tee_context **ctx) -+{ -+ struct tee_context *tee_ctx; -+ u32 session_id; -+ int rc; -+ -+ /* Open context with TEE driver */ -+ tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL); -+ if (IS_ERR(tee_ctx)) { -+ rc = PTR_ERR(tee_ctx); -+ if (rc == -ENOENT) -+ return -EPROBE_DEFER; -+ pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc); -+ -+ return rc; -+ } -+ -+ /* Check STM32MP BSEC TA presence */ -+ rc = stm32_bsec_ta_open_session(tee_ctx, &session_id); -+ if (rc) { -+ tee_client_close_context(tee_ctx); -+ return rc; -+ } -+ -+ stm32_bsec_ta_close_session(tee_ctx, session_id); -+ -+ *ctx = tee_ctx; -+ -+ return 0; -+} -+ -+/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */ -+void stm32_bsec_optee_ta_close(void *ctx) -+{ -+ tee_client_close_context(ctx); -+} -+ -+/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */ -+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ struct tee_shm *shm; -+ struct tee_ioctl_invoke_arg arg; -+ struct tee_param param[2]; -+ u8 *shm_buf; -+ u32 start, num_bytes; -+ int ret; -+ u32 session_id; -+ -+ ret = stm32_bsec_ta_open_session(ctx, &session_id); -+ if (ret) -+ return ret; -+ -+ memset(&arg, 0, sizeof(arg)); -+ memset(¶m, 0, sizeof(param)); -+ -+ arg.func = PTA_BSEC_READ_MEM; -+ arg.session = session_id; -+ arg.num_params = 2; -+ -+ /* align access on 32bits */ -+ start = ALIGN_DOWN(offset, 4); -+ num_bytes = round_up(offset + bytes - start, 4); -+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; -+ param[0].u.value.a = start; -+ param[0].u.value.b = SHADOW_ACCESS; -+ -+ shm = tee_shm_alloc_kernel_buf(ctx, num_bytes); -+ if (IS_ERR(shm)) { -+ ret = PTR_ERR(shm); -+ goto out_tee_session; -+ } -+ -+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; -+ param[1].u.memref.shm = shm; -+ param[1].u.memref.size = num_bytes; -+ -+ ret = tee_client_invoke_func(ctx, &arg, param); -+ if (ret < 0 || arg.ret != 0) { -+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", -+ arg.ret, ret); -+ if (!ret) -+ ret = -EIO; -+ } -+ if (!ret) { -+ shm_buf = tee_shm_get_va(shm, 0); -+ if (IS_ERR(shm_buf)) { -+ ret = PTR_ERR(shm_buf); -+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret); -+ } else { -+ /* read data from 32 bits aligned buffer */ -+ memcpy(buf, &shm_buf[offset % 4], bytes); -+ } -+ } -+ -+ tee_shm_free(shm); -+ -+out_tee_session: -+ stm32_bsec_ta_close_session(ctx, session_id); -+ -+ return ret; -+} -+ -+/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */ -+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower, -+ unsigned int offset, void *buf, size_t bytes) -+{ struct tee_shm *shm; -+ struct tee_ioctl_invoke_arg arg; -+ struct tee_param param[2]; -+ u8 *shm_buf; -+ int ret; -+ u32 session_id; -+ -+ ret = stm32_bsec_ta_open_session(ctx, &session_id); -+ if (ret) -+ return ret; -+ -+ /* Allow only writing complete 32-bits aligned words */ -+ if ((bytes % 4) || (offset % 4)) -+ return -EINVAL; -+ -+ memset(&arg, 0, sizeof(arg)); -+ memset(¶m, 0, sizeof(param)); -+ -+ arg.func = PTA_BSEC_WRITE_MEM; -+ arg.session = session_id; -+ arg.num_params = 2; -+ -+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; -+ param[0].u.value.a = offset; -+ param[0].u.value.b = FUSE_ACCESS; -+ -+ shm = tee_shm_alloc_kernel_buf(ctx, bytes); -+ if (IS_ERR(shm)) { -+ ret = PTR_ERR(shm); -+ goto out_tee_session; -+ } -+ -+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; -+ param[1].u.memref.shm = shm; -+ param[1].u.memref.size = bytes; -+ -+ shm_buf = tee_shm_get_va(shm, 0); -+ if (IS_ERR(shm_buf)) { -+ ret = PTR_ERR(shm_buf); -+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret); -+ tee_shm_free(shm); -+ -+ goto out_tee_session; -+ } -+ -+ memcpy(shm_buf, buf, bytes); -+ -+ ret = tee_client_invoke_func(ctx, &arg, param); -+ if (ret < 0 || arg.ret != 0) { -+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret); -+ if (!ret) -+ ret = -EIO; -+ } -+ pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret); -+ -+ /* Lock the upper OTPs with ECC protection, word programming only */ -+ if (!ret && ((offset + bytes) >= (lower * 4))) { -+ u32 start, nb_lock; -+ u32 *lock = (u32 *)shm_buf; -+ int i; -+ -+ /* -+ * don't lock the lower OTPs, no ECC protection and incremental -+ * bit programming, a second write is allowed -+ */ -+ start = max_t(u32, offset, lower * 4); -+ nb_lock = (offset + bytes - start) / 4; -+ -+ param[0].u.value.a = start; -+ param[0].u.value.b = LOCK_ACCESS; -+ param[1].u.memref.size = nb_lock * 4; -+ -+ for (i = 0; i < nb_lock; i++) -+ lock[i] = LOCK_PERM; -+ -+ ret = tee_client_invoke_func(ctx, &arg, param); -+ if (ret < 0 || arg.ret != 0) { -+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret); -+ if (!ret) -+ ret = -EIO; -+ } -+ pr_debug("Lock upper OTPs %d to %d, ret=%d\n", -+ start / 4, start / 4 + nb_lock, ret); -+ } -+ -+ tee_shm_free(shm); -+ -+out_tee_session: -+ stm32_bsec_ta_close_session(ctx, session_id); -+ -+ return ret; -+} ---- /dev/null -+++ b/drivers/nvmem/stm32-bsec-optee-ta.h -@@ -0,0 +1,80 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver -+ * -+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved -+ */ -+ -+#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) -+/** -+ * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA -+ * @ctx: the OP-TEE context on success -+ * -+ * Return: -+ * On success, 0. On failure, -errno. -+ */ -+int stm32_bsec_optee_ta_open(struct tee_context **ctx); -+ -+/** -+ * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA -+ * @ctx: the OP-TEE context -+ * -+ * This function used to clean the OP-TEE resources initialized in -+ * stm32_bsec_optee_ta_open(); it can be used as callback to -+ * devm_add_action_or_reset() -+ */ -+void stm32_bsec_optee_ta_close(void *ctx); -+ -+/** -+ * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver -+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open -+ * @offset: nvmem offset -+ * @buf: buffer to fill with nvem values -+ * @bytes: number of bytes to read -+ * -+ * Return: -+ * On success, 0. On failure, -errno. -+ */ -+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset, -+ void *buf, size_t bytes); -+ -+/** -+ * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver -+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open -+ * @lower: number of lower OTP, not protected by ECC -+ * @offset: nvmem offset -+ * @buf: buffer with nvem values -+ * @bytes: number of bytes to write -+ * -+ * Return: -+ * On success, 0. On failure, -errno. -+ */ -+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower, -+ unsigned int offset, void *buf, size_t bytes); -+ -+#else -+ -+static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void stm32_bsec_optee_ta_close(void *ctx) -+{ -+} -+ -+static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx, -+ unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx, -+ unsigned int lower, -+ unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ return -EOPNOTSUPP; -+} -+#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */ ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -11,6 +11,9 @@ - #include - #include - #include -+#include -+ -+#include "stm32-bsec-optee-ta.h" - - /* BSEC secure service access from non-secure */ - #define STM32_SMC_BSEC 0x82001003 -@@ -25,12 +28,14 @@ - struct stm32_romem_cfg { - int size; - u8 lower; -+ bool ta; - }; - - struct stm32_romem_priv { - void __iomem *base; - struct nvmem_config cfg; - u8 lower; -+ struct tee_context *ctx; - }; - - static int stm32_romem_read(void *context, unsigned int offset, void *buf, -@@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex - return 0; - } - -+static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ struct stm32_romem_priv *priv = context; -+ -+ return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes); -+} -+ -+static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ struct stm32_romem_priv *priv = context; -+ -+ return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes); -+} -+ - static int stm32_romem_probe(struct platform_device *pdev) - { - const struct stm32_romem_cfg *cfg; - struct device *dev = &pdev->dev; - struct stm32_romem_priv *priv; - struct resource *res; -+ int rc; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat - } else { - priv->cfg.size = cfg->size; - priv->lower = cfg->lower; -- priv->cfg.reg_read = stm32_bsec_read; -- priv->cfg.reg_write = stm32_bsec_write; -+ if (cfg->ta) { -+ rc = stm32_bsec_optee_ta_open(&priv->ctx); -+ /* wait for OP-TEE client driver to be up and ready */ -+ if (rc) -+ return rc; -+ } -+ if (priv->ctx) { -+ rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx); -+ if (rc) { -+ dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc); -+ return rc; -+ } -+ priv->cfg.reg_read = stm32_bsec_pta_read; -+ priv->cfg.reg_write = stm32_bsec_pta_write; -+ } else { -+ priv->cfg.reg_read = stm32_bsec_read; -+ priv->cfg.reg_write = stm32_bsec_write; -+ } - } - - return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); - } - - /* -- * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) -+ * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) - * => 96 x 32-bits data words - * - Lower: 1K bits, 2:1 redundancy, incremental bit programming - * => 32 (x 32-bits) lower shadow registers = words 0 to 31 -@@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat - static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { - .size = 384, - .lower = 32, -+ .ta = false, -+}; -+ -+static const struct stm32_romem_cfg stm32mp13_bsec_cfg = { -+ .size = 384, -+ .lower = 32, -+ .ta = true, - }; - - static const struct of_device_id stm32_romem_of_match[] = { -@@ -198,7 +243,10 @@ static const struct of_device_id stm32_r - .compatible = "st,stm32mp15-bsec", - .data = (void *)&stm32mp15_bsec_cfg, - }, { -+ .compatible = "st,stm32mp13-bsec", -+ .data = (void *)&stm32mp13_bsec_cfg, - }, -+ { /* sentinel */ }, - }; - MODULE_DEVICE_TABLE(of, stm32_romem_of_match); - diff --git a/target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch b/target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch deleted file mode 100644 index cea8e93858fc7d..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch +++ /dev/null @@ -1,85 +0,0 @@ -From df2f34ef1d924125ffaf29dfdaf7cdbd3183c321 Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Mon, 6 Feb 2023 13:43:52 +0000 -Subject: [PATCH] nvmem: stm32: detect bsec pta presence for STM32MP15x - -On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used; -the PTA BSEC should be used as it is done on STM32MP13x platform, -but the BSEC SMC can be also used: it is a legacy mode in OP-TEE, -not recommended but used in previous OP-TEE firmware. - -The presence of OP-TEE is dynamically detected in STM32MP15x device tree -and the supported NVMEM backend is dynamically detected: -- PTA with stm32_bsec_pta_find -- SMC with stm32_bsec_check - -With OP-TEE but without PTA and SMC detection, the probe is deferred for -STM32MP15x devices. - -On STM32MP13x platform, only the PTA is supported with cfg->ta = true -and this detection is skipped. - -Signed-off-by: Patrick Delaunay -Reviewed-by: Etienne Carriere -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-19-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++---- - 1 file changed, 34 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *co - return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes); - } - -+static bool stm32_bsec_smc_check(void) -+{ -+ u32 val; -+ int ret; -+ -+ /* check that the OP-TEE support the BSEC SMC (legacy mode) */ -+ ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val); -+ -+ return !ret; -+} -+ -+static bool optee_presence_check(void) -+{ -+ struct device_node *np; -+ bool tee_detected = false; -+ -+ /* check that the OP-TEE node is present and available. */ -+ np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz"); -+ if (np && of_device_is_available(np)) -+ tee_detected = true; -+ of_node_put(np); -+ -+ return tee_detected; -+} -+ - static int stm32_romem_probe(struct platform_device *pdev) - { - const struct stm32_romem_cfg *cfg; -@@ -195,11 +220,16 @@ static int stm32_romem_probe(struct plat - } else { - priv->cfg.size = cfg->size; - priv->lower = cfg->lower; -- if (cfg->ta) { -+ if (cfg->ta || optee_presence_check()) { - rc = stm32_bsec_optee_ta_open(&priv->ctx); -- /* wait for OP-TEE client driver to be up and ready */ -- if (rc) -- return rc; -+ if (rc) { -+ /* wait for OP-TEE client driver to be up and ready */ -+ if (rc == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ /* BSEC PTA is required or SMC not supported */ -+ if (cfg->ta || !stm32_bsec_smc_check()) -+ return rc; -+ } - } - if (priv->ctx) { - rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx); diff --git a/target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch b/target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch deleted file mode 100644 index 9d6275a737bccb..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3e5ac22aa564026e99defc3a8e02082521a5b231 Mon Sep 17 00:00:00 2001 -From: Randy Dunlap -Date: Mon, 6 Feb 2023 13:43:53 +0000 -Subject: [PATCH] nvmem: rave-sp-eeprm: fix kernel-doc bad line warning - -Convert an empty line to " *" to avoid a kernel-doc warning: - -drivers/nvmem/rave-sp-eeprom.c:48: warning: bad line: - -Signed-off-by: Randy Dunlap -Cc: Srinivas Kandagatla -Cc: Andrey Vostrikov -Cc: Nikita Yushchenko -Cc: Andrey Smirnov -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-20-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rave-sp-eeprom.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/rave-sp-eeprom.c -+++ b/drivers/nvmem/rave-sp-eeprom.c -@@ -45,7 +45,7 @@ enum rave_sp_eeprom_header_size { - * @type: Access type (see enum rave_sp_eeprom_access_type) - * @success: Success flag (Success = 1, Failure = 0) - * @data: Read data -- -+ * - * Note this structure corresponds to RSP_*_EEPROM payload from RAVE - * SP ICD - */ diff --git a/target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch b/target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch deleted file mode 100644 index 1ab9e609d33c91..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch +++ /dev/null @@ -1,43 +0,0 @@ -From eb7dda20f42a9137e9ee53d5ed3b743d49338cb5 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Mon, 6 Feb 2023 13:43:54 +0000 -Subject: [PATCH] nvmem: qcom-spmi-sdam: register at device init time - -There are currently no in-tree users of the Qualcomm SDAM nvmem driver -and there is generally no point in registering a driver that can be -built as a module at subsys init time. - -Register the driver at the normal device init time instead and let -driver core sort out the probe order. - -Signed-off-by: Johan Hovold -Reviewed-by: Bjorn Andersson -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-21-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/qcom-spmi-sdam.c | 13 +------------ - 1 file changed, 1 insertion(+), 12 deletions(-) - ---- a/drivers/nvmem/qcom-spmi-sdam.c -+++ b/drivers/nvmem/qcom-spmi-sdam.c -@@ -175,18 +175,7 @@ static struct platform_driver sdam_drive - }, - .probe = sdam_probe, - }; -- --static int __init sdam_init(void) --{ -- return platform_driver_register(&sdam_driver); --} --subsys_initcall(sdam_init); -- --static void __exit sdam_exit(void) --{ -- return platform_driver_unregister(&sdam_driver); --} --module_exit(sdam_exit); -+module_platform_driver(sdam_driver); - - MODULE_DESCRIPTION("QCOM SPMI SDAM driver"); - MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch b/target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch deleted file mode 100644 index dcf704c6ffbbfa..00000000000000 --- a/target/linux/generic/backport-5.15/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 1dc7e37bb0ec1c997fac82031332a38c7610352f Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Mon, 6 Feb 2023 13:43:56 +0000 -Subject: [PATCH] nvmem: stm32: fix OPTEE dependency - -The stm32 nvmem driver fails to link as built-in when OPTEE -is a loadable module: - -aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec: -stm32-bsec-optee-ta.c:(.text+0xc8): undefined reference to `tee_client_open_session' -aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec: -stm32-bsec-optee-ta.c:(.text+0x1fc): undefined reference to `tee_client_open_context' - -Change the CONFIG_NVMEM_STM32_ROMEM definition so it can only -be built-in if OPTEE is either built-in or disabled, and -make NVMEM_STM32_BSEC_OPTEE_TA a hidden symbol instead. - -Signed-off-by: Arnd Bergmann -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-23-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -291,8 +291,7 @@ config NVMEM_SPRD_EFUSE - will be called nvmem-sprd-efuse. - - config NVMEM_STM32_BSEC_OPTEE_TA -- bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver" -- depends on OPTEE -+ def_bool NVMEM_STM32_ROMEM && OPTEE - help - Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE - trusted application STM32MP BSEC. -@@ -303,7 +302,7 @@ config NVMEM_STM32_BSEC_OPTEE_TA - config NVMEM_STM32_ROMEM - tristate "STMicroelectronics STM32 factory-programmed memory support" - depends on ARCH_STM32 || COMPILE_TEST -- imply NVMEM_STM32_BSEC_OPTEE_TA -+ depends on OPTEE || !OPTEE - help - Say y here to enable read-only access for STMicroelectronics STM32 - factory-programmed memory area. diff --git a/target/linux/generic/backport-5.15/810-v5.17-net-qmi_wwan-add-ZTE-MF286D-modem-19d2-1485.patch b/target/linux/generic/backport-5.15/810-v5.17-net-qmi_wwan-add-ZTE-MF286D-modem-19d2-1485.patch deleted file mode 100644 index dbd734e9cf43d5..00000000000000 --- a/target/linux/generic/backport-5.15/810-v5.17-net-qmi_wwan-add-ZTE-MF286D-modem-19d2-1485.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 078c6a1cbd4cd7496048786beec2e312577bebbf Mon Sep 17 00:00:00 2001 -From: Pawel Dembicki -Date: Tue, 11 Jan 2022 23:11:32 +0100 -Subject: [PATCH 1/1] net: qmi_wwan: add ZTE MF286D modem 19d2:1485 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Modem from ZTE MF286D is an Qualcomm MDM9250 based 3G/4G modem. - -T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=5000 MxCh= 0 -D: Ver= 3.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 -P: Vendor=19d2 ProdID=1485 Rev=52.87 -S: Manufacturer=ZTE,Incorporated -S: Product=ZTE Technologies MSM -S: SerialNumber=MF286DZTED000000 -C:* #Ifs= 7 Cfg#= 1 Atr=80 MxPwr=896mA -A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=06 Prot=00 -I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=ff Driver=rndis_host -E: Ad=82(I) Atr=03(Int.) MxPS= 8 Ivl=32ms -I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host -E: Ad=81(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms -E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms -I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option -E: Ad=83(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms -E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms -I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option -E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms -E: Ad=84(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms -E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms -I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option -E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms -E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms -E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms -I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan -E: Ad=88(I) Atr=03(Int.) MxPS= 8 Ivl=32ms -E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms -E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms -I:* If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=usbfs -E: Ad=05(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms -E: Ad=89(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms - -Signed-off-by: Pawel Dembicki -Acked-by: Bjørn Mork -Signed-off-by: David S. Miller ---- - drivers/net/usb/qmi_wwan.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/usb/qmi_wwan.c -+++ b/drivers/net/usb/qmi_wwan.c -@@ -1317,6 +1317,7 @@ static const struct usb_device_id produc - {QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */ - {QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */ - {QMI_FIXED_INTF(0x19d2, 0x1432, 3)}, /* ZTE ME3620 */ -+ {QMI_FIXED_INTF(0x19d2, 0x1485, 5)}, /* ZTE MF286D */ - {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ - {QMI_FIXED_INTF(0x2001, 0x7e16, 3)}, /* D-Link DWM-221 */ - {QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */ diff --git a/target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch b/target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch deleted file mode 100644 index 8328e87c0af7a4..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch +++ /dev/null @@ -1,35 +0,0 @@ -From bcd1fe07def0f070eb5f31594620aaee6f81d31a Mon Sep 17 00:00:00 2001 -From: Nick Alcock -Date: Tue, 4 Apr 2023 18:21:11 +0100 -Subject: [PATCH] nvmem: xilinx: zynqmp: make modular - -This driver has a MODULE_LICENSE but is not tristate so cannot be -built as a module, unlike all its peers: make it modular to match. - -Signed-off-by: Nick Alcock -Suggested-by: Michal Simek -Cc: Luis Chamberlain -Cc: linux-modules@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Cc: Hitomi Hasegawa -Cc: Srinivas Kandagatla -Cc: Michal Simek -Cc: linux-arm-kernel@lists.infradead.org -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -368,7 +368,7 @@ config NVMEM_VF610_OCOTP - be called nvmem-vf610-ocotp. - - config NVMEM_ZYNQMP -- bool "Xilinx ZYNQMP SoC nvmem firmware support" -+ tristate "Xilinx ZYNQMP SoC nvmem firmware support" - depends on ARCH_ZYNQMP - help - This is a driver to access hardware related data like diff --git a/target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch b/target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch deleted file mode 100644 index 23518d21f70c09..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch +++ /dev/null @@ -1,387 +0,0 @@ -From 266570f496b90dea8fda893c2cf7c28d63ae2bd9 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:21 +0100 -Subject: [PATCH] nvmem: core: introduce NVMEM layouts - -NVMEM layouts are used to generate NVMEM cells during runtime. Think of -an EEPROM with a well-defined conent. For now, the content can be -described by a device tree or a board file. But this only works if the -offsets and lengths are static and don't change. One could also argue -that putting the layout of the EEPROM in the device tree is the wrong -place. Instead, the device tree should just have a specific compatible -string. - -Right now there are two use cases: - (1) The NVMEM cell needs special processing. E.g. if it only specifies - a base MAC address offset and you need to add an offset, or it - needs to parse a MAC from ASCII format or some proprietary format. - (Post processing of cells is added in a later commit). - (2) u-boot environment parsing. The cells don't have a particular - offset but it needs parsing the content to determine the offsets - and length. - -Co-developed-by: Miquel Raynal -Signed-off-by: Miquel Raynal -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-14-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - Documentation/driver-api/nvmem.rst | 15 ++++ - drivers/nvmem/Kconfig | 4 + - drivers/nvmem/Makefile | 1 + - drivers/nvmem/core.c | 120 +++++++++++++++++++++++++++++ - drivers/nvmem/layouts/Kconfig | 5 ++ - drivers/nvmem/layouts/Makefile | 4 + - include/linux/nvmem-consumer.h | 7 ++ - include/linux/nvmem-provider.h | 51 ++++++++++++ - 8 files changed, 207 insertions(+) - create mode 100644 drivers/nvmem/layouts/Kconfig - create mode 100644 drivers/nvmem/layouts/Makefile - ---- a/Documentation/driver-api/nvmem.rst -+++ b/Documentation/driver-api/nvmem.rst -@@ -189,3 +189,18 @@ ex:: - ===================== - - See Documentation/devicetree/bindings/nvmem/nvmem.txt -+ -+8. NVMEM layouts -+================ -+ -+NVMEM layouts are yet another mechanism to create cells. With the device -+tree binding it is possible to specify simple cells by using an offset -+and a length. Sometimes, the cells doesn't have a static offset, but -+the content is still well defined, e.g. tag-length-values. In this case, -+the NVMEM device content has to be first parsed and the cells need to -+be added accordingly. Layouts let you read the content of the NVMEM device -+and let you add cells dynamically. -+ -+Another use case for layouts is the post processing of cells. With layouts, -+it is possible to associate a custom post processing hook to a cell. It -+even possible to add this hook to cells not created by the layout itself. ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -21,6 +21,10 @@ config NVMEM_SYSFS - This interface is mostly used by userspace applications to - read/write directly into nvmem. - -+# Layouts -+ -+source "drivers/nvmem/layouts/Kconfig" -+ - # Devices - - config NVMEM_APPLE_EFUSES ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -5,6 +5,7 @@ - - obj-$(CONFIG_NVMEM) += nvmem_core.o - nvmem_core-y := core.o -+obj-y += layouts/ - - # Devices - obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -40,6 +40,7 @@ struct nvmem_device { - nvmem_reg_write_t reg_write; - nvmem_cell_post_process_t cell_post_process; - struct gpio_desc *wp_gpio; -+ struct nvmem_layout *layout; - void *priv; - }; - -@@ -74,6 +75,9 @@ static LIST_HEAD(nvmem_lookup_list); - - static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); - -+static DEFINE_SPINLOCK(nvmem_layout_lock); -+static LIST_HEAD(nvmem_layouts); -+ - static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, - void *val, size_t bytes) - { -@@ -728,6 +732,101 @@ static int nvmem_add_cells_from_of(struc - return 0; - } - -+int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner) -+{ -+ layout->owner = owner; -+ -+ spin_lock(&nvmem_layout_lock); -+ list_add(&layout->node, &nvmem_layouts); -+ spin_unlock(&nvmem_layout_lock); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(__nvmem_layout_register); -+ -+void nvmem_layout_unregister(struct nvmem_layout *layout) -+{ -+ spin_lock(&nvmem_layout_lock); -+ list_del(&layout->node); -+ spin_unlock(&nvmem_layout_lock); -+} -+EXPORT_SYMBOL_GPL(nvmem_layout_unregister); -+ -+static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) -+{ -+ struct device_node *layout_np, *np = nvmem->dev.of_node; -+ struct nvmem_layout *l, *layout = NULL; -+ -+ layout_np = of_get_child_by_name(np, "nvmem-layout"); -+ if (!layout_np) -+ return NULL; -+ -+ spin_lock(&nvmem_layout_lock); -+ -+ list_for_each_entry(l, &nvmem_layouts, node) { -+ if (of_match_node(l->of_match_table, layout_np)) { -+ if (try_module_get(l->owner)) -+ layout = l; -+ -+ break; -+ } -+ } -+ -+ spin_unlock(&nvmem_layout_lock); -+ of_node_put(layout_np); -+ -+ return layout; -+} -+ -+static void nvmem_layout_put(struct nvmem_layout *layout) -+{ -+ if (layout) -+ module_put(layout->owner); -+} -+ -+static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem) -+{ -+ struct nvmem_layout *layout = nvmem->layout; -+ int ret; -+ -+ if (layout && layout->add_cells) { -+ ret = layout->add_cells(&nvmem->dev, nvmem, layout); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+#if IS_ENABLED(CONFIG_OF) -+/** -+ * of_nvmem_layout_get_container() - Get OF node to layout container. -+ * -+ * @nvmem: nvmem device. -+ * -+ * Return: a node pointer with refcount incremented or NULL if no -+ * container exists. Use of_node_put() on it when done. -+ */ -+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) -+{ -+ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); -+} -+EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container); -+#endif -+ -+const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout) -+{ -+ struct device_node __maybe_unused *layout_np; -+ const struct of_device_id *match; -+ -+ layout_np = of_nvmem_layout_get_container(nvmem); -+ match = of_match_node(layout->of_match_table, layout_np); -+ -+ return match ? match->data : NULL; -+} -+EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data); -+ - /** - * nvmem_register() - Register a nvmem device for given nvmem_config. - * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem -@@ -834,6 +933,12 @@ struct nvmem_device *nvmem_register(cons - goto err_put_device; - } - -+ /* -+ * If the driver supplied a layout by config->layout, the module -+ * pointer will be NULL and nvmem_layout_put() will be a noop. -+ */ -+ nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); -+ - if (config->cells) { - rval = nvmem_add_cells(nvmem, config->cells, config->ncells); - if (rval) -@@ -854,12 +959,17 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -+ rval = nvmem_add_cells_from_layout(nvmem); -+ if (rval) -+ goto err_remove_cells; -+ - blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); - - return nvmem; - - err_remove_cells: - nvmem_device_remove_all_cells(nvmem); -+ nvmem_layout_put(nvmem->layout); - if (config->compat) - nvmem_sysfs_remove_compat(nvmem, config); - err_put_device: -@@ -881,6 +991,7 @@ static void nvmem_device_release(struct - device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); - - nvmem_device_remove_all_cells(nvmem); -+ nvmem_layout_put(nvmem->layout); - device_unregister(&nvmem->dev); - } - -@@ -1246,6 +1357,15 @@ struct nvmem_cell *of_nvmem_cell_get(str - return ERR_PTR(-EINVAL); - } - -+ /* nvmem layouts produce cells within the nvmem-layout container */ -+ if (of_node_name_eq(nvmem_np, "nvmem-layout")) { -+ nvmem_np = of_get_next_parent(nvmem_np); -+ if (!nvmem_np) { -+ of_node_put(cell_np); -+ return ERR_PTR(-EINVAL); -+ } -+ } -+ - nvmem = __nvmem_device_get(nvmem_np, device_match_of_node); - of_node_put(nvmem_np); - if (IS_ERR(nvmem)) { ---- /dev/null -+++ b/drivers/nvmem/layouts/Kconfig -@@ -0,0 +1,5 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+menu "Layout Types" -+ -+endmenu ---- /dev/null -+++ b/drivers/nvmem/layouts/Makefile -@@ -0,0 +1,4 @@ -+# SPDX-License-Identifier: GPL-2.0 -+# -+# Makefile for nvmem layouts. -+# ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -239,6 +239,7 @@ struct nvmem_cell *of_nvmem_cell_get(str - const char *id); - struct nvmem_device *of_nvmem_device_get(struct device_node *np, - const char *name); -+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem); - #else - static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, - const char *id) -@@ -251,6 +252,12 @@ static inline struct nvmem_device *of_nv - { - return ERR_PTR(-EOPNOTSUPP); - } -+ -+static inline struct device_node * -+of_nvmem_layout_get_container(struct nvmem_device *nvmem) -+{ -+ return ERR_PTR(-EOPNOTSUPP); -+} - #endif /* CONFIG_NVMEM && CONFIG_OF */ - - #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */ ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -88,6 +88,7 @@ struct nvmem_cell_info { - * @stride: Minimum read/write access stride. - * @priv: User context passed to read/write callbacks. - * @ignore_wp: Write Protect pin is managed by the provider. -+ * @layout: Fixed layout associated with this nvmem device. - * - * Note: A default "nvmem" name will be assigned to the device if - * no name is specified in its configuration. In such case "" is -@@ -109,6 +110,7 @@ struct nvmem_config { - bool read_only; - bool root_only; - bool ignore_wp; -+ struct nvmem_layout *layout; - struct device_node *of_node; - bool no_of_node; - nvmem_reg_read_t reg_read; -@@ -142,6 +144,33 @@ struct nvmem_cell_table { - struct list_head node; - }; - -+/** -+ * struct nvmem_layout - NVMEM layout definitions -+ * -+ * @name: Layout name. -+ * @of_match_table: Open firmware match table. -+ * @add_cells: Will be called if a nvmem device is found which -+ * has this layout. The function will add layout -+ * specific cells with nvmem_add_one_cell(). -+ * @owner: Pointer to struct module. -+ * @node: List node. -+ * -+ * A nvmem device can hold a well defined structure which can just be -+ * evaluated during runtime. For example a TLV list, or a list of "name=val" -+ * pairs. A nvmem layout can parse the nvmem device and add appropriate -+ * cells. -+ */ -+struct nvmem_layout { -+ const char *name; -+ const struct of_device_id *of_match_table; -+ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, -+ struct nvmem_layout *layout); -+ -+ /* private */ -+ struct module *owner; -+ struct list_head node; -+}; -+ - #if IS_ENABLED(CONFIG_NVMEM) - - struct nvmem_device *nvmem_register(const struct nvmem_config *cfg); -@@ -156,6 +185,14 @@ void nvmem_del_cell_table(struct nvmem_c - int nvmem_add_one_cell(struct nvmem_device *nvmem, - const struct nvmem_cell_info *info); - -+int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner); -+#define nvmem_layout_register(layout) \ -+ __nvmem_layout_register(layout, THIS_MODULE) -+void nvmem_layout_unregister(struct nvmem_layout *layout); -+ -+const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout); -+ - #else - - static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) -@@ -179,5 +216,19 @@ static inline int nvmem_add_one_cell(str - return -EOPNOTSUPP; - } - -+static inline int nvmem_layout_register(struct nvmem_layout *layout) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {} -+ -+static inline const void * -+nvmem_layout_get_match_data(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout) -+{ -+ return NULL; -+} -+ - #endif /* CONFIG_NVMEM */ - #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch b/target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch deleted file mode 100644 index 6fa7b6382d8941..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 6468a6f45148fb5e95c86b4efebf63f9abcd2137 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:22 +0100 -Subject: [PATCH] nvmem: core: handle the absence of expected layouts - -Make nvmem_layout_get() return -EPROBE_DEFER while the expected layout -is not available. This condition cannot be triggered today as nvmem -layout drivers are initialed as part of an early init call, but soon -these drivers will be converted into modules and be initialized with a -standard priority, so the unavailability of the drivers might become a -reality that must be taken care of. - -Let's anticipate this by telling the caller the layout might not yet be -available. A probe deferral is requested in this case. - -Please note this does not affect any nvmem device not using layouts, -because an early check against the "nvmem-layout" container presence -will return NULL in this case. - -Signed-off-by: Miquel Raynal -Tested-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-15-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -755,7 +755,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste - static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) - { - struct device_node *layout_np, *np = nvmem->dev.of_node; -- struct nvmem_layout *l, *layout = NULL; -+ struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER); - - layout_np = of_get_child_by_name(np, "nvmem-layout"); - if (!layout_np) -@@ -938,6 +938,13 @@ struct nvmem_device *nvmem_register(cons - * pointer will be NULL and nvmem_layout_put() will be a noop. - */ - nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); -+ if (IS_ERR(nvmem->layout)) { -+ rval = PTR_ERR(nvmem->layout); -+ nvmem->layout = NULL; -+ -+ if (rval == -EPROBE_DEFER) -+ goto err_teardown_compat; -+ } - - if (config->cells) { - rval = nvmem_add_cells(nvmem, config->cells, config->ncells); -@@ -970,6 +977,7 @@ struct nvmem_device *nvmem_register(cons - err_remove_cells: - nvmem_device_remove_all_cells(nvmem); - nvmem_layout_put(nvmem->layout); -+err_teardown_compat: - if (config->compat) - nvmem_sysfs_remove_compat(nvmem, config); - err_put_device: diff --git a/target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch b/target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch deleted file mode 100644 index b9341666f91f9d..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch +++ /dev/null @@ -1,52 +0,0 @@ -From b1c37bec1ccfe5ccab72bc0ddc0dfa45c43e2de2 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:23 +0100 -Subject: [PATCH] nvmem: core: request layout modules loading - -When a storage device like an eeprom or an mtd device probes, it -registers an nvmem device if the nvmem subsystem has been enabled (bool -symbol). During nvmem registration, if the device is using layouts to -expose dynamic nvmem cells, the core will first try to get a reference -over the layout driver callbacks. In practice there is not relationship -that can be described between the storage driver and the nvmem -layout. So there is no way we can enforce both drivers will be built-in -or both will be modules. If the storage device driver is built-in but -the layout is built as a module, instead of badly failing with an -endless probe deferral loop, lets just make a modprobe call in case the -driver was made available in an initramfs with -of_device_node_request_module(), and offer a fully functional system to -the user. - -Signed-off-by: Miquel Raynal -Tested-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-16-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - - struct nvmem_device { -@@ -761,6 +762,13 @@ static struct nvmem_layout *nvmem_layout - if (!layout_np) - return NULL; - -+ /* -+ * In case the nvmem device was built-in while the layout was built as a -+ * module, we shall manually request the layout driver loading otherwise -+ * we'll never have any match. -+ */ -+ of_request_module(layout_np); -+ - spin_lock(&nvmem_layout_lock); - - list_for_each_entry(l, &nvmem_layouts, node) { diff --git a/target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch b/target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch deleted file mode 100644 index 53628cd4e4ffb4..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 345ec382cd4b736c36e01f155d08c913b225b736 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:24 +0100 -Subject: [PATCH] nvmem: core: add per-cell post processing - -Instead of relying on the name the consumer is using for the cell, like -it is done for the nvmem .cell_post_process configuration parameter, -provide a per-cell post processing hook. This can then be populated by -the NVMEM provider (or the NVMEM layout) when adding the cell. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-17-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 17 +++++++++++++++++ - include/linux/nvmem-provider.h | 3 +++ - 2 files changed, 20 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -54,6 +54,7 @@ struct nvmem_cell_entry { - int bytes; - int bit_offset; - int nbits; -+ nvmem_cell_post_process_t read_post_process; - struct device_node *np; - struct nvmem_device *nvmem; - struct list_head node; -@@ -470,6 +471,7 @@ static int nvmem_cell_info_to_nvmem_cell - cell->offset = info->offset; - cell->bytes = info->bytes; - cell->name = info->name; -+ cell->read_post_process = info->read_post_process; - - cell->bit_offset = info->bit_offset; - cell->nbits = info->nbits; -@@ -1563,6 +1565,13 @@ static int __nvmem_cell_read(struct nvme - if (cell->bit_offset || cell->nbits) - nvmem_shift_read_buffer_in_place(cell, buf); - -+ if (cell->read_post_process) { -+ rc = cell->read_post_process(nvmem->priv, id, index, -+ cell->offset, buf, cell->bytes); -+ if (rc) -+ return rc; -+ } -+ - if (nvmem->cell_post_process) { - rc = nvmem->cell_post_process(nvmem->priv, id, index, - cell->offset, buf, cell->bytes); -@@ -1671,6 +1680,14 @@ static int __nvmem_cell_entry_write(stru - (cell->bit_offset == 0 && len != cell->bytes)) - return -EINVAL; - -+ /* -+ * Any cells which have a read_post_process hook are read-only because -+ * we cannot reverse the operation and it might affect other cells, -+ * too. -+ */ -+ if (cell->read_post_process) -+ return -EINVAL; -+ - if (cell->bit_offset || cell->nbits) { - buf = nvmem_cell_prepare_write_buffer(cell, buf, len); - if (IS_ERR(buf)) ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -54,6 +54,8 @@ struct nvmem_keepout { - * @bit_offset: Bit offset if cell is smaller than a byte. - * @nbits: Number of bits. - * @np: Optional device_node pointer. -+ * @read_post_process: Callback for optional post processing of cell data -+ * on reads. - */ - struct nvmem_cell_info { - const char *name; -@@ -62,6 +64,7 @@ struct nvmem_cell_info { - unsigned int bit_offset; - unsigned int nbits; - struct device_node *np; -+ nvmem_cell_post_process_t read_post_process; - }; - - /** diff --git a/target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch b/target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch deleted file mode 100644 index 32990148c806f9..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch +++ /dev/null @@ -1,59 +0,0 @@ -From de12c9691501ccba41a154c223869f82be4c12fd Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:25 +0100 -Subject: [PATCH] nvmem: core: allow to modify a cell before adding it - -Provide a way to modify a cell before it will get added. This is useful -to attach a custom post processing hook via a layout. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-18-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 4 ++++ - include/linux/nvmem-provider.h | 5 +++++ - 2 files changed, 9 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -695,6 +695,7 @@ static int nvmem_validate_keepouts(struc - - static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) - { -+ struct nvmem_layout *layout = nvmem->layout; - struct device *dev = &nvmem->dev; - struct device_node *child; - const __be32 *addr; -@@ -724,6 +725,9 @@ static int nvmem_add_cells_from_of(struc - - info.np = of_node_get(child); - -+ if (layout && layout->fixup_cell_info) -+ layout->fixup_cell_info(nvmem, layout, &info); -+ - ret = nvmem_add_one_cell(nvmem, &info); - kfree(info.name); - if (ret) { ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -155,6 +155,8 @@ struct nvmem_cell_table { - * @add_cells: Will be called if a nvmem device is found which - * has this layout. The function will add layout - * specific cells with nvmem_add_one_cell(). -+ * @fixup_cell_info: Will be called before a cell is added. Can be -+ * used to modify the nvmem_cell_info. - * @owner: Pointer to struct module. - * @node: List node. - * -@@ -168,6 +170,9 @@ struct nvmem_layout { - const struct of_device_id *of_match_table; - int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, - struct nvmem_layout *layout); -+ void (*fixup_cell_info)(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout, -+ struct nvmem_cell_info *cell); - - /* private */ - struct module *owner; diff --git a/target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch b/target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch deleted file mode 100644 index 2a5fa618ea6529..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 6c56a82d7895a213a43182a5d01a21a906a79847 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:26 +0100 -Subject: [PATCH] nvmem: imx-ocotp: replace global post processing with layouts - -In preparation of retiring the global post processing hook change this -driver to use layouts. The layout will be supplied during registration -and will be used to add the post processing hook to all added cells. - -Signed-off-by: Michael Walle -Tested-by: Michael Walle # on kontron-pitx-imx8m -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-19-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/imx-ocotp.c | 30 +++++++++++++++++++----------- - 1 file changed, 19 insertions(+), 11 deletions(-) - ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -225,18 +225,13 @@ read_end: - static int imx_ocotp_cell_pp(void *context, const char *id, int index, - unsigned int offset, void *data, size_t bytes) - { -- struct ocotp_priv *priv = context; -+ u8 *buf = data; -+ int i; - - /* Deal with some post processing of nvmem cell data */ -- if (id && !strcmp(id, "mac-address")) { -- if (priv->params->reverse_mac_address) { -- u8 *buf = data; -- int i; -- -- for (i = 0; i < bytes/2; i++) -- swap(buf[i], buf[bytes - i - 1]); -- } -- } -+ if (id && !strcmp(id, "mac-address")) -+ for (i = 0; i < bytes / 2; i++) -+ swap(buf[i], buf[bytes - i - 1]); - - return 0; - } -@@ -488,7 +483,6 @@ static struct nvmem_config imx_ocotp_nvm - .stride = 1, - .reg_read = imx_ocotp_read, - .reg_write = imx_ocotp_write, -- .cell_post_process = imx_ocotp_cell_pp, - }; - - static const struct ocotp_params imx6q_params = { -@@ -595,6 +589,17 @@ static const struct of_device_id imx_oco - }; - MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids); - -+static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout, -+ struct nvmem_cell_info *cell) -+{ -+ cell->read_post_process = imx_ocotp_cell_pp; -+} -+ -+struct nvmem_layout imx_ocotp_layout = { -+ .fixup_cell_info = imx_ocotp_fixup_cell_info, -+}; -+ - static int imx_ocotp_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -619,6 +624,9 @@ static int imx_ocotp_probe(struct platfo - imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; - imx_ocotp_nvmem_config.dev = dev; - imx_ocotp_nvmem_config.priv = priv; -+ if (priv->params->reverse_mac_address) -+ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; -+ - priv->config = &imx_ocotp_nvmem_config; - - clk_prepare_enable(priv->clk); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch b/target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch deleted file mode 100644 index eac202b8829841..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 011e40a166fdaa65fb9946b7cd91efec85b70dbb Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:27 +0100 -Subject: [PATCH] nvmem: cell: drop global cell_post_process - -There are no users anymore for the global cell_post_process callback -anymore. New users should use proper nvmem layouts. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-20-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 9 --------- - include/linux/nvmem-provider.h | 2 -- - 2 files changed, 11 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -39,7 +39,6 @@ struct nvmem_device { - unsigned int nkeepout; - nvmem_reg_read_t reg_read; - nvmem_reg_write_t reg_write; -- nvmem_cell_post_process_t cell_post_process; - struct gpio_desc *wp_gpio; - struct nvmem_layout *layout; - void *priv; -@@ -903,7 +902,6 @@ struct nvmem_device *nvmem_register(cons - nvmem->type = config->type; - nvmem->reg_read = config->reg_read; - nvmem->reg_write = config->reg_write; -- nvmem->cell_post_process = config->cell_post_process; - nvmem->keepout = config->keepout; - nvmem->nkeepout = config->nkeepout; - if (config->of_node) -@@ -1575,13 +1573,6 @@ static int __nvmem_cell_read(struct nvme - if (rc) - return rc; - } -- -- if (nvmem->cell_post_process) { -- rc = nvmem->cell_post_process(nvmem->priv, id, index, -- cell->offset, buf, cell->bytes); -- if (rc) -- return rc; -- } - - if (len) - *len = cell->bytes; ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -85,7 +85,6 @@ struct nvmem_cell_info { - * @no_of_node: Device should not use the parent's of_node even if it's !NULL. - * @reg_read: Callback to read data. - * @reg_write: Callback to write data. -- * @cell_post_process: Callback for vendor specific post processing of cell data - * @size: Device size. - * @word_size: Minimum read/write access granularity. - * @stride: Minimum read/write access stride. -@@ -118,7 +117,6 @@ struct nvmem_config { - bool no_of_node; - nvmem_reg_read_t reg_read; - nvmem_reg_write_t reg_write; -- nvmem_cell_post_process_t cell_post_process; - int size; - int word_size; - int stride; diff --git a/target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch b/target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch deleted file mode 100644 index 46b30a2ed90417..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 8a134fd9f9323f4c39ec27055b3d3723cfb5c1e9 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:28 +0100 -Subject: [PATCH] nvmem: core: provide own priv pointer in post process - callback - -It doesn't make any more sense to have a opaque pointer set up by the -nvmem device. Usually, the layout isn't associated with a particular -nvmem device. Instead, let the caller who set the post process callback -provide the priv pointer. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-21-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 4 +++- - include/linux/nvmem-provider.h | 5 ++++- - 2 files changed, 7 insertions(+), 2 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -54,6 +54,7 @@ struct nvmem_cell_entry { - int bit_offset; - int nbits; - nvmem_cell_post_process_t read_post_process; -+ void *priv; - struct device_node *np; - struct nvmem_device *nvmem; - struct list_head node; -@@ -471,6 +472,7 @@ static int nvmem_cell_info_to_nvmem_cell - cell->bytes = info->bytes; - cell->name = info->name; - cell->read_post_process = info->read_post_process; -+ cell->priv = info->priv; - - cell->bit_offset = info->bit_offset; - cell->nbits = info->nbits; -@@ -1568,7 +1570,7 @@ static int __nvmem_cell_read(struct nvme - nvmem_shift_read_buffer_in_place(cell, buf); - - if (cell->read_post_process) { -- rc = cell->read_post_process(nvmem->priv, id, index, -+ rc = cell->read_post_process(cell->priv, id, index, - cell->offset, buf, cell->bytes); - if (rc) - return rc; ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -20,7 +20,8 @@ typedef int (*nvmem_reg_write_t)(void *p - void *val, size_t bytes); - /* used for vendor specific post processing of cell data */ - typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, -- unsigned int offset, void *buf, size_t bytes); -+ unsigned int offset, void *buf, -+ size_t bytes); - - enum nvmem_type { - NVMEM_TYPE_UNKNOWN = 0, -@@ -56,6 +57,7 @@ struct nvmem_keepout { - * @np: Optional device_node pointer. - * @read_post_process: Callback for optional post processing of cell data - * on reads. -+ * @priv: Opaque data passed to the read_post_process hook. - */ - struct nvmem_cell_info { - const char *name; -@@ -65,6 +67,7 @@ struct nvmem_cell_info { - unsigned int nbits; - struct device_node *np; - nvmem_cell_post_process_t read_post_process; -+ void *priv; - }; - - /** diff --git a/target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch b/target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch deleted file mode 100644 index 7d97658b60e289..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch +++ /dev/null @@ -1,215 +0,0 @@ -From d9fae023fe86069750092fc1c2f3a73e2fb18512 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:29 +0100 -Subject: [PATCH] nvmem: layouts: sl28vpd: Add new layout driver - -This layout applies to the VPD of the Kontron sl28 boards. The VPD only -contains a base MAC address. Therefore, we have to add an individual -offset to it. This is done by taking the second argument of the nvmem -phandle into account. Also this let us checking the VPD version and the -checksum. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-22-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/Kconfig | 9 ++ - drivers/nvmem/layouts/Makefile | 2 + - drivers/nvmem/layouts/sl28vpd.c | 165 ++++++++++++++++++++++++++++++++ - 3 files changed, 176 insertions(+) - create mode 100644 drivers/nvmem/layouts/sl28vpd.c - ---- a/drivers/nvmem/layouts/Kconfig -+++ b/drivers/nvmem/layouts/Kconfig -@@ -2,4 +2,13 @@ - - menu "Layout Types" - -+config NVMEM_LAYOUT_SL28_VPD -+ tristate "Kontron sl28 VPD layout support" -+ select CRC8 -+ help -+ Say Y here if you want to support the VPD layout of the Kontron -+ SMARC-sAL28 boards. -+ -+ If unsure, say N. -+ - endmenu ---- a/drivers/nvmem/layouts/Makefile -+++ b/drivers/nvmem/layouts/Makefile -@@ -2,3 +2,5 @@ - # - # Makefile for nvmem layouts. - # -+ -+obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o ---- /dev/null -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -0,0 +1,165 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define SL28VPD_MAGIC 'V' -+ -+struct sl28vpd_header { -+ u8 magic; -+ u8 version; -+} __packed; -+ -+struct sl28vpd_v1 { -+ struct sl28vpd_header header; -+ char serial_number[15]; -+ u8 base_mac_address[ETH_ALEN]; -+ u8 crc8; -+} __packed; -+ -+static int sl28vpd_mac_address_pp(void *priv, const char *id, int index, -+ unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ if (bytes != ETH_ALEN) -+ return -EINVAL; -+ -+ if (index < 0) -+ return -EINVAL; -+ -+ if (!is_valid_ether_addr(buf)) -+ return -EINVAL; -+ -+ eth_addr_add(buf, index); -+ -+ return 0; -+} -+ -+static const struct nvmem_cell_info sl28vpd_v1_entries[] = { -+ { -+ .name = "serial-number", -+ .offset = offsetof(struct sl28vpd_v1, serial_number), -+ .bytes = sizeof_field(struct sl28vpd_v1, serial_number), -+ }, -+ { -+ .name = "base-mac-address", -+ .offset = offsetof(struct sl28vpd_v1, base_mac_address), -+ .bytes = sizeof_field(struct sl28vpd_v1, base_mac_address), -+ .read_post_process = sl28vpd_mac_address_pp, -+ }, -+}; -+ -+static int sl28vpd_v1_check_crc(struct device *dev, struct nvmem_device *nvmem) -+{ -+ struct sl28vpd_v1 data_v1; -+ u8 table[CRC8_TABLE_SIZE]; -+ int ret; -+ u8 crc; -+ -+ crc8_populate_msb(table, 0x07); -+ -+ ret = nvmem_device_read(nvmem, 0, sizeof(data_v1), &data_v1); -+ if (ret < 0) -+ return ret; -+ else if (ret != sizeof(data_v1)) -+ return -EIO; -+ -+ crc = crc8(table, (void *)&data_v1, sizeof(data_v1) - 1, 0); -+ -+ if (crc != data_v1.crc8) { -+ dev_err(dev, -+ "Checksum is invalid (got %02x, expected %02x).\n", -+ crc, data_v1.crc8); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem, -+ struct nvmem_layout *layout) -+{ -+ const struct nvmem_cell_info *pinfo; -+ struct nvmem_cell_info info = {0}; -+ struct device_node *layout_np; -+ struct sl28vpd_header hdr; -+ int ret, i; -+ -+ /* check header */ -+ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); -+ if (ret < 0) -+ return ret; -+ else if (ret != sizeof(hdr)) -+ return -EIO; -+ -+ if (hdr.magic != SL28VPD_MAGIC) { -+ dev_err(dev, "Invalid magic value (%02x)\n", hdr.magic); -+ return -EINVAL; -+ } -+ -+ if (hdr.version != 1) { -+ dev_err(dev, "Version %d is unsupported.\n", hdr.version); -+ return -EINVAL; -+ } -+ -+ ret = sl28vpd_v1_check_crc(dev, nvmem); -+ if (ret) -+ return ret; -+ -+ layout_np = of_nvmem_layout_get_container(nvmem); -+ if (!layout_np) -+ return -ENOENT; -+ -+ for (i = 0; i < ARRAY_SIZE(sl28vpd_v1_entries); i++) { -+ pinfo = &sl28vpd_v1_entries[i]; -+ -+ info.name = pinfo->name; -+ info.offset = pinfo->offset; -+ info.bytes = pinfo->bytes; -+ info.read_post_process = pinfo->read_post_process; -+ info.np = of_get_child_by_name(layout_np, pinfo->name); -+ -+ ret = nvmem_add_one_cell(nvmem, &info); -+ if (ret) { -+ of_node_put(layout_np); -+ return ret; -+ } -+ } -+ -+ of_node_put(layout_np); -+ -+ return 0; -+} -+ -+static const struct of_device_id sl28vpd_of_match_table[] = { -+ { .compatible = "kontron,sl28-vpd" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); -+ -+struct nvmem_layout sl28vpd_layout = { -+ .name = "sl28-vpd", -+ .of_match_table = sl28vpd_of_match_table, -+ .add_cells = sl28vpd_add_cells, -+}; -+ -+static int __init sl28vpd_init(void) -+{ -+ return nvmem_layout_register(&sl28vpd_layout); -+} -+ -+static void __exit sl28vpd_exit(void) -+{ -+ nvmem_layout_unregister(&sl28vpd_layout); -+} -+ -+module_init(sl28vpd_init); -+module_exit(sl28vpd_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Michael Walle "); -+MODULE_DESCRIPTION("NVMEM layout driver for the VPD of Kontron sl28 boards"); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch b/target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch deleted file mode 100644 index ca8b4bc069146b..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch +++ /dev/null @@ -1,306 +0,0 @@ -From d3c0d12f6474216bf386101e2449cc73e5c5b61d Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:31 +0100 -Subject: [PATCH] nvmem: layouts: onie-tlv: Add new layout driver - -This layout applies on top of any non volatile storage device containing -an ONIE table factory flashed. This table follows the tlv -(type-length-value) organization described in the link below. We cannot -afford using regular parsers because the content of these tables is -manufacturer specific and must be dynamically discovered. - -Link: https://opencomputeproject.github.io/onie/design-spec/hw_requirements.html -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-24-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/Kconfig | 9 ++ - drivers/nvmem/layouts/Makefile | 1 + - drivers/nvmem/layouts/onie-tlv.c | 257 +++++++++++++++++++++++++++++++ - 3 files changed, 267 insertions(+) - create mode 100644 drivers/nvmem/layouts/onie-tlv.c - ---- a/drivers/nvmem/layouts/Kconfig -+++ b/drivers/nvmem/layouts/Kconfig -@@ -11,4 +11,13 @@ config NVMEM_LAYOUT_SL28_VPD - - If unsure, say N. - -+config NVMEM_LAYOUT_ONIE_TLV -+ tristate "ONIE tlv support" -+ select CRC32 -+ help -+ Say Y here if you want to support the Open Compute Project ONIE -+ Type-Length-Value standard table. -+ -+ If unsure, say N. -+ - endmenu ---- a/drivers/nvmem/layouts/Makefile -+++ b/drivers/nvmem/layouts/Makefile -@@ -4,3 +4,4 @@ - # - - obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o -+obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o ---- /dev/null -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -0,0 +1,257 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * ONIE tlv NVMEM cells provider -+ * -+ * Copyright (C) 2022 Open Compute Group ONIE -+ * Author: Miquel Raynal -+ * Based on the nvmem driver written by: Vadym Kochan -+ * Inspired by the first layout written by: Rafał Miłecki -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define ONIE_TLV_MAX_LEN 2048 -+#define ONIE_TLV_CRC_FIELD_SZ 6 -+#define ONIE_TLV_CRC_SZ 4 -+#define ONIE_TLV_HDR_ID "TlvInfo" -+ -+struct onie_tlv_hdr { -+ u8 id[8]; -+ u8 version; -+ __be16 data_len; -+} __packed; -+ -+struct onie_tlv { -+ u8 type; -+ u8 len; -+} __packed; -+ -+static const char *onie_tlv_cell_name(u8 type) -+{ -+ switch (type) { -+ case 0x21: -+ return "product-name"; -+ case 0x22: -+ return "part-number"; -+ case 0x23: -+ return "serial-number"; -+ case 0x24: -+ return "mac-address"; -+ case 0x25: -+ return "manufacture-date"; -+ case 0x26: -+ return "device-version"; -+ case 0x27: -+ return "label-revision"; -+ case 0x28: -+ return "platform-name"; -+ case 0x29: -+ return "onie-version"; -+ case 0x2A: -+ return "num-macs"; -+ case 0x2B: -+ return "manufacturer"; -+ case 0x2C: -+ return "country-code"; -+ case 0x2D: -+ return "vendor"; -+ case 0x2E: -+ return "diag-version"; -+ case 0x2F: -+ return "service-tag"; -+ case 0xFD: -+ return "vendor-extension"; -+ case 0xFE: -+ return "crc32"; -+ default: -+ break; -+ } -+ -+ return NULL; -+} -+ -+static int onie_tlv_mac_read_cb(void *priv, const char *id, int index, -+ unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ eth_addr_add(buf, index); -+ -+ return 0; -+} -+ -+static nvmem_cell_post_process_t onie_tlv_read_cb(u8 type, u8 *buf) -+{ -+ switch (type) { -+ case 0x24: -+ return &onie_tlv_mac_read_cb; -+ default: -+ break; -+ } -+ -+ return NULL; -+} -+ -+static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem, -+ size_t data_len, u8 *data) -+{ -+ struct nvmem_cell_info cell = {}; -+ struct device_node *layout; -+ struct onie_tlv tlv; -+ unsigned int hdr_len = sizeof(struct onie_tlv_hdr); -+ unsigned int offset = 0; -+ int ret; -+ -+ layout = of_nvmem_layout_get_container(nvmem); -+ if (!layout) -+ return -ENOENT; -+ -+ while (offset < data_len) { -+ memcpy(&tlv, data + offset, sizeof(tlv)); -+ if (offset + tlv.len >= data_len) { -+ dev_err(dev, "Out of bounds field (0x%x bytes at 0x%x)\n", -+ tlv.len, hdr_len + offset); -+ break; -+ } -+ -+ cell.name = onie_tlv_cell_name(tlv.type); -+ if (!cell.name) -+ continue; -+ -+ cell.offset = hdr_len + offset + sizeof(tlv.type) + sizeof(tlv.len); -+ cell.bytes = tlv.len; -+ cell.np = of_get_child_by_name(layout, cell.name); -+ cell.read_post_process = onie_tlv_read_cb(tlv.type, data + offset + sizeof(tlv)); -+ -+ ret = nvmem_add_one_cell(nvmem, &cell); -+ if (ret) { -+ of_node_put(layout); -+ return ret; -+ } -+ -+ offset += sizeof(tlv) + tlv.len; -+ } -+ -+ of_node_put(layout); -+ -+ return 0; -+} -+ -+static bool onie_tlv_hdr_is_valid(struct device *dev, struct onie_tlv_hdr *hdr) -+{ -+ if (memcmp(hdr->id, ONIE_TLV_HDR_ID, sizeof(hdr->id))) { -+ dev_err(dev, "Invalid header\n"); -+ return false; -+ } -+ -+ if (hdr->version != 0x1) { -+ dev_err(dev, "Invalid version number\n"); -+ return false; -+ } -+ -+ return true; -+} -+ -+static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *table) -+{ -+ struct onie_tlv crc_hdr; -+ u32 read_crc, calc_crc; -+ __be32 crc_be; -+ -+ memcpy(&crc_hdr, table + table_len - ONIE_TLV_CRC_FIELD_SZ, sizeof(crc_hdr)); -+ if (crc_hdr.type != 0xfe || crc_hdr.len != ONIE_TLV_CRC_SZ) { -+ dev_err(dev, "Invalid CRC field\n"); -+ return false; -+ } -+ -+ /* The table contains a JAMCRC, which is XOR'ed compared to the original -+ * CRC32 implementation as known in the Ethernet world. -+ */ -+ memcpy(&crc_be, table + table_len - ONIE_TLV_CRC_SZ, ONIE_TLV_CRC_SZ); -+ read_crc = be32_to_cpu(crc_be); -+ calc_crc = crc32(~0, table, table_len - ONIE_TLV_CRC_SZ) ^ 0xFFFFFFFF; -+ if (read_crc != calc_crc) { -+ dev_err(dev, "Invalid CRC read: 0x%08x, expected: 0x%08x\n", -+ read_crc, calc_crc); -+ return false; -+ } -+ -+ return true; -+} -+ -+static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem, -+ struct nvmem_layout *layout) -+{ -+ struct onie_tlv_hdr hdr; -+ size_t table_len, data_len, hdr_len; -+ u8 *table, *data; -+ int ret; -+ -+ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); -+ if (ret < 0) -+ return ret; -+ -+ if (!onie_tlv_hdr_is_valid(dev, &hdr)) { -+ dev_err(dev, "Invalid ONIE TLV header\n"); -+ return -EINVAL; -+ } -+ -+ hdr_len = sizeof(hdr.id) + sizeof(hdr.version) + sizeof(hdr.data_len); -+ data_len = be16_to_cpu(hdr.data_len); -+ table_len = hdr_len + data_len; -+ if (table_len > ONIE_TLV_MAX_LEN) { -+ dev_err(dev, "Invalid ONIE TLV data length\n"); -+ return -EINVAL; -+ } -+ -+ table = devm_kmalloc(dev, table_len, GFP_KERNEL); -+ if (!table) -+ return -ENOMEM; -+ -+ ret = nvmem_device_read(nvmem, 0, table_len, table); -+ if (ret != table_len) -+ return ret; -+ -+ if (!onie_tlv_crc_is_valid(dev, table_len, table)) -+ return -EINVAL; -+ -+ data = table + hdr_len; -+ ret = onie_tlv_add_cells(dev, nvmem, data_len, data); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static const struct of_device_id onie_tlv_of_match_table[] = { -+ { .compatible = "onie,tlv-layout", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table); -+ -+static struct nvmem_layout onie_tlv_layout = { -+ .name = "ONIE tlv layout", -+ .of_match_table = onie_tlv_of_match_table, -+ .add_cells = onie_tlv_parse_table, -+}; -+ -+static int __init onie_tlv_init(void) -+{ -+ return nvmem_layout_register(&onie_tlv_layout); -+} -+ -+static void __exit onie_tlv_exit(void) -+{ -+ nvmem_layout_unregister(&onie_tlv_layout); -+} -+ -+module_init(onie_tlv_init); -+module_exit(onie_tlv_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Miquel Raynal "); -+MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing"); -+MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing"); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch b/target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch deleted file mode 100644 index 94a0911d73cc76..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a4fb434ef96ace5af758ca2c52c3a3f8f3abc87c Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 4 Apr 2023 18:21:34 +0100 -Subject: [PATCH] nvmem: stm32-romem: mark OF related data as maybe unused -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The driver can be compile tested with !CONFIG_OF making certain data -unused: - - drivers/nvmem/stm32-romem.c:271:34: error: ‘stm32_romem_of_match’ defined but not used [-Werror=unused-const-variable=] - -Signed-off-by: Krzysztof Kozlowski -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-27-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -268,7 +268,7 @@ static const struct stm32_romem_cfg stm3 - .ta = true, - }; - --static const struct of_device_id stm32_romem_of_match[] = { -+static const struct of_device_id stm32_romem_of_match[] __maybe_unused = { - { .compatible = "st,stm32f4-otp", }, { - .compatible = "st,stm32mp15-bsec", - .data = (void *)&stm32mp15_bsec_cfg, diff --git a/target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch b/target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch deleted file mode 100644 index abda402bddb07a..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch +++ /dev/null @@ -1,120 +0,0 @@ -From de6e05097f7db066afb0ad4c88b730949f7b7749 Mon Sep 17 00:00:00 2001 -From: AngeloGioacchino Del Regno -Date: Tue, 4 Apr 2023 18:21:35 +0100 -Subject: [PATCH] nvmem: mtk-efuse: Support postprocessing for GPU speed - binning data - -On some MediaTek SoCs GPU speed binning data is available for read -in the SoC's eFuse array but it has a format that is incompatible -with what the OPP API expects, as we read a number from 0 to 7 but -opp-supported-hw is expecting a bitmask to enable an OPP entry: -being what we read limited to 0-7, it's straightforward to simply -convert the value to BIT(value) as a post-processing action. - -So, introduce post-processing support and enable it by evaluating -the newly introduced platform data's `uses_post_processing` member, -currently enabled only for MT8186. - -Signed-off-by: AngeloGioacchino Del Regno -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-28-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/mtk-efuse.c | 53 +++++++++++++++++++++++++++++++++++++-- - 1 file changed, 51 insertions(+), 2 deletions(-) - ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -10,6 +10,11 @@ - #include - #include - #include -+#include -+ -+struct mtk_efuse_pdata { -+ bool uses_post_processing; -+}; - - struct mtk_efuse_priv { - void __iomem *base; -@@ -29,6 +34,37 @@ static int mtk_reg_read(void *context, - return 0; - } - -+static int mtk_efuse_gpu_speedbin_pp(void *context, const char *id, int index, -+ unsigned int offset, void *data, size_t bytes) -+{ -+ u8 *val = data; -+ -+ if (val[0] < 8) -+ val[0] = BIT(val[0]); -+ -+ return 0; -+} -+ -+static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout, -+ struct nvmem_cell_info *cell) -+{ -+ size_t sz = strlen(cell->name); -+ -+ /* -+ * On some SoCs, the GPU speedbin is not read as bitmask but as -+ * a number with range [0-7] (max 3 bits): post process to use -+ * it in OPP tables to describe supported-hw. -+ */ -+ if (cell->nbits <= 3 && -+ strncmp(cell->name, "gpu-speedbin", min(sz, strlen("gpu-speedbin"))) == 0) -+ cell->read_post_process = mtk_efuse_gpu_speedbin_pp; -+} -+ -+static struct nvmem_layout mtk_efuse_layout = { -+ .fixup_cell_info = mtk_efuse_fixup_cell_info, -+}; -+ - static int mtk_efuse_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -36,6 +72,7 @@ static int mtk_efuse_probe(struct platfo - struct nvmem_device *nvmem; - struct nvmem_config econfig = {}; - struct mtk_efuse_priv *priv; -+ const struct mtk_efuse_pdata *pdata; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -45,20 +82,32 @@ static int mtk_efuse_probe(struct platfo - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - -+ pdata = device_get_match_data(dev); - econfig.stride = 1; - econfig.word_size = 1; - econfig.reg_read = mtk_reg_read; - econfig.size = resource_size(res); - econfig.priv = priv; - econfig.dev = dev; -+ if (pdata->uses_post_processing) -+ econfig.layout = &mtk_efuse_layout; - nvmem = devm_nvmem_register(dev, &econfig); - - return PTR_ERR_OR_ZERO(nvmem); - } - -+static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = { -+ .uses_post_processing = true, -+}; -+ -+static const struct mtk_efuse_pdata mtk_efuse_pdata = { -+ .uses_post_processing = false, -+}; -+ - static const struct of_device_id mtk_efuse_of_match[] = { -- { .compatible = "mediatek,mt8173-efuse",}, -- { .compatible = "mediatek,efuse",}, -+ { .compatible = "mediatek,mt8173-efuse", .data = &mtk_efuse_pdata }, -+ { .compatible = "mediatek,mt8186-efuse", .data = &mtk_mt8186_efuse_pdata }, -+ { .compatible = "mediatek,efuse", .data = &mtk_efuse_pdata }, - {/* sentinel */}, - }; - MODULE_DEVICE_TABLE(of, mtk_efuse_of_match); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch b/target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch deleted file mode 100644 index a0874f73d15c1f..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1dc552fa33cf98af3e784dbc0500da93cae3b24a Mon Sep 17 00:00:00 2001 -From: Yang Li -Date: Tue, 4 Apr 2023 18:21:38 +0100 -Subject: [PATCH] nvmem: bcm-ocotp: Use devm_platform_ioremap_resource() - -According to commit 7945f929f1a7 ("drivers: provide -devm_platform_ioremap_resource()"), convert platform_get_resource(), -devm_ioremap_resource() to a single call to use -devm_platform_ioremap_resource(), as this is exactly what this function -does. - -Signed-off-by: Yang Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-31-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/bcm-ocotp.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/nvmem/bcm-ocotp.c -+++ b/drivers/nvmem/bcm-ocotp.c -@@ -254,7 +254,6 @@ MODULE_DEVICE_TABLE(acpi, bcm_otpc_acpi_ - static int bcm_otpc_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -- struct resource *res; - struct otpc_priv *priv; - struct nvmem_device *nvmem; - int err; -@@ -269,8 +268,7 @@ static int bcm_otpc_probe(struct platfor - return -ENODEV; - - /* Get OTP base address register. */ -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->base = devm_ioremap_resource(dev, res); -+ priv->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->base)) { - dev_err(dev, "unable to map I/O memory\n"); - return PTR_ERR(priv->base); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch b/target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch deleted file mode 100644 index 890dacd08dbef8..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 649409990d2e93fac657be7c6960c28a2c601d65 Mon Sep 17 00:00:00 2001 -From: Yang Li -Date: Tue, 4 Apr 2023 18:21:39 +0100 -Subject: [PATCH] nvmem: nintendo-otp: Use devm_platform_ioremap_resource() - -According to commit 7945f929f1a7 ("drivers: provide -devm_platform_ioremap_resource()"), convert platform_get_resource(), -devm_ioremap_resource() to a single call to use -devm_platform_ioremap_resource(), as this is exactly what this function -does. - -Signed-off-by: Yang Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-32-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/nintendo-otp.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/nvmem/nintendo-otp.c -+++ b/drivers/nvmem/nintendo-otp.c -@@ -76,7 +76,6 @@ static int nintendo_otp_probe(struct pla - struct device *dev = &pdev->dev; - const struct of_device_id *of_id = - of_match_device(nintendo_otp_of_table, dev); -- struct resource *res; - struct nvmem_device *nvmem; - struct nintendo_otp_priv *priv; - -@@ -92,8 +91,7 @@ static int nintendo_otp_probe(struct pla - if (!priv) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->regs = devm_ioremap_resource(dev, res); -+ priv->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->regs)) - return PTR_ERR(priv->regs); - diff --git a/target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch deleted file mode 100644 index 3f5d3c1ad4c121..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c2367aa60d5e34d48582362c6de34b4131d92be7 Mon Sep 17 00:00:00 2001 -From: Yang Li -Date: Tue, 4 Apr 2023 18:21:40 +0100 -Subject: [PATCH] nvmem: vf610-ocotp: Use - devm_platform_get_and_ioremap_resource() - -According to commit 890cc39a8799 ("drivers: provide -devm_platform_get_and_ioremap_resource()"), convert -platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -Signed-off-by: Yang Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-33-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/vf610-ocotp.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/vf610-ocotp.c -+++ b/drivers/nvmem/vf610-ocotp.c -@@ -219,8 +219,7 @@ static int vf610_ocotp_probe(struct plat - if (!ocotp_dev) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- ocotp_dev->base = devm_ioremap_resource(dev, res); -+ ocotp_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(ocotp_dev->base)) - return PTR_ERR(ocotp_dev->base); - diff --git a/target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch b/target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch deleted file mode 100644 index eeb407e9bb664c..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 55d4980ce55b6bb4be66877de4dbec513911b988 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 4 Apr 2023 18:21:42 +0100 -Subject: [PATCH] nvmem: core: support specifying both: cell raw data & post - read lengths -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Callback .read_post_process() is designed to modify raw cell content -before providing it to the consumer. So far we were dealing with -modifications that didn't affect cell size (length). In some cases -however cell content needs to be reformatted and resized. - -It's required e.g. to provide properly formatted MAC address in case -it's stored in a non-binary format (e.g. using ASCII). - -There were few discussions how to optimally handle that. Following -possible solutions were considered: -1. Allow .read_post_process() to realloc (resize) content buffer -2. Allow .read_post_process() to adjust (decrease) just buffer length -3. Register NVMEM cells using post-read sizes - -The preferred solution was the last one. The problem is that simply -adjusting "bytes" in NVMEM providers would result in core code NOT -passing whole raw data to .read_post_process() callbacks. It means -callback functions couldn't do their job without somehow manually -reading original cell content on their own. - -This patch deals with that by registering NVMEM cells with both lengths: -raw content one and post read one. It allows: -1. Core code to read whole raw cell content -2. Callbacks to return content they want - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-35-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 11 +++++++---- - include/linux/nvmem-provider.h | 2 ++ - 2 files changed, 9 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -50,6 +50,7 @@ struct nvmem_device { - struct nvmem_cell_entry { - const char *name; - int offset; -+ size_t raw_len; - int bytes; - int bit_offset; - int nbits; -@@ -469,6 +470,7 @@ static int nvmem_cell_info_to_nvmem_cell - { - cell->nvmem = nvmem; - cell->offset = info->offset; -+ cell->raw_len = info->raw_len ?: info->bytes; - cell->bytes = info->bytes; - cell->name = info->name; - cell->read_post_process = info->read_post_process; -@@ -1560,7 +1562,7 @@ static int __nvmem_cell_read(struct nvme - { - int rc; - -- rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes); -+ rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->raw_len); - - if (rc) - return rc; -@@ -1571,7 +1573,7 @@ static int __nvmem_cell_read(struct nvme - - if (cell->read_post_process) { - rc = cell->read_post_process(cell->priv, id, index, -- cell->offset, buf, cell->bytes); -+ cell->offset, buf, cell->raw_len); - if (rc) - return rc; - } -@@ -1594,14 +1596,15 @@ static int __nvmem_cell_read(struct nvme - */ - void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) - { -- struct nvmem_device *nvmem = cell->entry->nvmem; -+ struct nvmem_cell_entry *entry = cell->entry; -+ struct nvmem_device *nvmem = entry->nvmem; - u8 *buf; - int rc; - - if (!nvmem) - return ERR_PTR(-EINVAL); - -- buf = kzalloc(cell->entry->bytes, GFP_KERNEL); -+ buf = kzalloc(max_t(size_t, entry->raw_len, entry->bytes), GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -51,6 +51,7 @@ struct nvmem_keepout { - * struct nvmem_cell_info - NVMEM cell description - * @name: Name. - * @offset: Offset within the NVMEM device. -+ * @raw_len: Length of raw data (without post processing). - * @bytes: Length of the cell. - * @bit_offset: Bit offset if cell is smaller than a byte. - * @nbits: Number of bits. -@@ -62,6 +63,7 @@ struct nvmem_keepout { - struct nvmem_cell_info { - const char *name; - unsigned int offset; -+ size_t raw_len; - unsigned int bytes; - unsigned int bit_offset; - unsigned int nbits; diff --git a/target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch b/target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch deleted file mode 100644 index adde0ffc4b1786..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch +++ /dev/null @@ -1,81 +0,0 @@ -From c49f1a8af6bcf6d18576bca898f8083ca4b129e1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 4 Apr 2023 18:21:43 +0100 -Subject: [PATCH] nvmem: u-boot-env: post-process "ethaddr" env variable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -U-Boot environment variables are stored in ASCII format so "ethaddr" -requires parsing into binary to make it work with Ethernet interfaces. - -This includes support for indexes to support #nvmem-cell-cells = <1>. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-36-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 1 + - drivers/nvmem/u-boot-env.c | 26 ++++++++++++++++++++++++++ - 2 files changed, 27 insertions(+) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -340,6 +340,7 @@ config NVMEM_U_BOOT_ENV - tristate "U-Boot environment variables support" - depends on OF && MTD - select CRC32 -+ select GENERIC_NET_UTILS - help - U-Boot stores its setup as environment variables. This driver adds - support for verifying & exporting such data. It also exposes variables ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -4,6 +4,8 @@ - */ - - #include -+#include -+#include - #include - #include - #include -@@ -70,6 +72,25 @@ static int u_boot_env_read(void *context - return 0; - } - -+static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, -+ unsigned int offset, void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (bytes != 3 * ETH_ALEN - 1) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ - static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, - size_t data_offset, size_t data_len) - { -@@ -101,6 +122,11 @@ static int u_boot_env_add_cells(struct u - priv->cells[idx].offset = data_offset + value - data; - priv->cells[idx].bytes = strlen(value); - priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); -+ if (!strcmp(var, "ethaddr")) { -+ priv->cells[idx].raw_len = strlen(value); -+ priv->cells[idx].bytes = ETH_ALEN; -+ priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr; -+ } - } - - if (WARN_ON(idx != priv->ncells)) diff --git a/target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch b/target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch deleted file mode 100644 index 7c6fe22b5f3a69..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 814c978f02db17f16e6aa2efa2a929372f06da09 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:44 +0100 -Subject: [PATCH] nvmem: Add macro to register nvmem layout drivers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Provide a module_nvmem_layout_driver() macro at the end of the -nvmem-provider.h header to reduce the boilerplate when registering nvmem -layout drivers. - -Suggested-by: Srinivas Kandagatla -Signed-off-by: Miquel Raynal -Acked-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-37-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - include/linux/nvmem-provider.h | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -9,6 +9,7 @@ - #ifndef _LINUX_NVMEM_PROVIDER_H - #define _LINUX_NVMEM_PROVIDER_H - -+#include - #include - #include - #include -@@ -242,4 +243,9 @@ nvmem_layout_get_match_data(struct nvmem - } - - #endif /* CONFIG_NVMEM */ -+ -+#define module_nvmem_layout_driver(__layout_driver) \ -+ module_driver(__layout_driver, nvmem_layout_register, \ -+ nvmem_layout_unregister) -+ - #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch b/target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch deleted file mode 100644 index 06646dd68bf67b..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0abdf99fe0c86252ba274703425f8d543d7e7f0d Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:45 +0100 -Subject: [PATCH] nvmem: layouts: sl28vpd: Use module_nvmem_layout_driver() - -Stop open-coding the module init/exit functions. Use the -module_nvmem_layout_driver() instead. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-38-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/sl28vpd.c | 14 +------------- - 1 file changed, 1 insertion(+), 13 deletions(-) - ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -146,19 +146,7 @@ struct nvmem_layout sl28vpd_layout = { - .of_match_table = sl28vpd_of_match_table, - .add_cells = sl28vpd_add_cells, - }; -- --static int __init sl28vpd_init(void) --{ -- return nvmem_layout_register(&sl28vpd_layout); --} -- --static void __exit sl28vpd_exit(void) --{ -- nvmem_layout_unregister(&sl28vpd_layout); --} -- --module_init(sl28vpd_init); --module_exit(sl28vpd_exit); -+module_nvmem_layout_driver(sl28vpd_layout); - - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Michael Walle "); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch b/target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch deleted file mode 100644 index 826f4378c2fabf..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch +++ /dev/null @@ -1,39 +0,0 @@ -From d119eb38faab61125aaa4f63c74eef61585cf34c Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:46 +0100 -Subject: [PATCH] nvmem: layouts: onie-tlv: Use module_nvmem_layout_driver() - -Stop open-coding the module init/exit functions. Use the -module_nvmem_layout_driver() instead. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-39-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/onie-tlv.c | 14 +------------- - 1 file changed, 1 insertion(+), 13 deletions(-) - ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -237,19 +237,7 @@ static struct nvmem_layout onie_tlv_layo - .of_match_table = onie_tlv_of_match_table, - .add_cells = onie_tlv_parse_table, - }; -- --static int __init onie_tlv_init(void) --{ -- return nvmem_layout_register(&onie_tlv_layout); --} -- --static void __exit onie_tlv_exit(void) --{ -- nvmem_layout_unregister(&onie_tlv_layout); --} -- --module_init(onie_tlv_init); --module_exit(onie_tlv_exit); -+module_nvmem_layout_driver(onie_tlv_layout); - - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Miquel Raynal "); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch b/target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch deleted file mode 100644 index f20db85ceb6ff6..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 6b13e4b6a9a45028ac730e550380077df1845912 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:47 +0100 -Subject: [PATCH] nvmem: layouts: onie-tlv: Drop wrong module alias - -The MODULE_ALIAS macro is misused here as it carries the -description. There is currently no relevant alias to provide so let's -just drop it. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-40-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/onie-tlv.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -242,4 +242,3 @@ module_nvmem_layout_driver(onie_tlv_layo - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Miquel Raynal "); - MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing"); --MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing"); diff --git a/target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch b/target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch deleted file mode 100644 index 5cf847b57ae130..00000000000000 --- a/target/linux/generic/backport-5.15/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch +++ /dev/null @@ -1,31 +0,0 @@ -From a8642cd11635a35a5f1dc31857887900d6610778 Mon Sep 17 00:00:00 2001 -From: Tom Rix -Date: Tue, 4 Apr 2023 18:21:48 +0100 -Subject: [PATCH] nvmem: layouts: sl28vpd: set varaiable sl28vpd_layout - storage-class-specifier to static - -smatch reports -drivers/nvmem/layouts/sl28vpd.c:144:21: warning: symbol - 'sl28vpd_layout' was not declared. Should it be static? - -This variable is only used in one file so it should be static. - -Signed-off-by: Tom Rix -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-41-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/sl28vpd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -141,7 +141,7 @@ static const struct of_device_id sl28vpd - }; - MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); - --struct nvmem_layout sl28vpd_layout = { -+static struct nvmem_layout sl28vpd_layout = { - .name = "sl28-vpd", - .of_match_table = sl28vpd_of_match_table, - .add_cells = sl28vpd_add_cells, diff --git a/target/linux/generic/backport-5.15/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch b/target/linux/generic/backport-5.15/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch deleted file mode 100644 index 13ee2d42293f91..00000000000000 --- a/target/linux/generic/backport-5.15/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch +++ /dev/null @@ -1,100 +0,0 @@ -From a5be5ce0e25439fae3cd42e3d775979547926812 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 3 Nov 2022 09:25:29 +0100 -Subject: [PATCH] firmware/nvram: bcm47xx: support init from IO memory -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Provide NVMEM content to the NVRAM driver from a simple -memory resource. This is necessary to use NVRAM in a memory- -mapped flash device. Patch taken from OpenWrts development -tree. - -This patch makes it possible to use memory-mapped NVRAM -on the D-Link DWL-8610AP and the D-Link DIR-890L. - -Cc: Hauke Mehrtens -Cc: linux-mips@vger.kernel.org -Cc: Florian Fainelli -Cc: bcm-kernel-feedback-list@broadcom.com -Cc: Thomas Bogendoerfer -Signed-off-by: Rafał Miłecki -[Added an export for modules potentially using the init symbol] -Signed-off-by: Linus Walleij -Link: https://lore.kernel.org/r/20221103082529.359084-1-linus.walleij@linaro.org -Signed-off-by: Florian Fainelli ---- - drivers/firmware/broadcom/bcm47xx_nvram.c | 18 ++++++++++++++++++ - drivers/nvmem/brcm_nvram.c | 3 +++ - include/linux/bcm47xx_nvram.h | 6 ++++++ - 3 files changed, 27 insertions(+) - ---- a/drivers/firmware/broadcom/bcm47xx_nvram.c -+++ b/drivers/firmware/broadcom/bcm47xx_nvram.c -@@ -110,6 +110,24 @@ found: - return 0; - } - -+int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size) -+{ -+ if (nvram_len) { -+ pr_warn("nvram already initialized\n"); -+ return -EEXIST; -+ } -+ -+ if (!bcm47xx_nvram_is_valid(nvram_start)) { -+ pr_err("No valid NVRAM found\n"); -+ return -ENOENT; -+ } -+ -+ bcm47xx_nvram_copy(nvram_start, res_size); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(bcm47xx_nvram_init_from_iomem); -+ - /* - * On bcm47xx we need access to the NVRAM very early, so we can't use mtd - * subsystem to access flash. We can't even use platform device / driver to ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -3,6 +3,7 @@ - * Copyright (C) 2021 Rafał Miłecki - */ - -+#include - #include - #include - #include -@@ -139,6 +140,8 @@ static int brcm_nvram_probe(struct platf - if (err) - return err; - -+ bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res)); -+ - config.dev = dev; - config.cells = priv->cells; - config.ncells = priv->ncells; ---- a/include/linux/bcm47xx_nvram.h -+++ b/include/linux/bcm47xx_nvram.h -@@ -11,6 +11,7 @@ - #include - - #ifdef CONFIG_BCM47XX_NVRAM -+int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size); - int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); - int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); - int bcm47xx_nvram_gpio_pin(const char *name); -@@ -20,6 +21,11 @@ static inline void bcm47xx_nvram_release - vfree(nvram); - }; - #else -+static inline int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, -+ size_t res_size) -+{ -+ return -ENOTSUPP; -+} - static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) - { - return -ENOTSUPP; diff --git a/target/linux/generic/backport-5.15/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch b/target/linux/generic/backport-5.15/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch deleted file mode 100644 index 38cfccd5ef9b29..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch +++ /dev/null @@ -1,31 +0,0 @@ -From eebc6573ad940b62a87776db3917e912b4f52d78 Mon Sep 17 00:00:00 2001 -From: Tom Rix -Date: Sun, 11 Jun 2023 15:03:05 +0100 -Subject: [PATCH] nvmem: imx-ocotp: set varaiable imx_ocotp_layout - storage-class-specifier to static - -smatch reports -drivers/nvmem/imx-ocotp.c:599:21: warning: symbol - 'imx_ocotp_layout' was not declared. Should it be static? - -This variable is only used in one file so should be static. - -Signed-off-by: Tom Rix -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-2-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/imx-ocotp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -596,7 +596,7 @@ static void imx_ocotp_fixup_cell_info(st - cell->read_post_process = imx_ocotp_cell_pp; - } - --struct nvmem_layout imx_ocotp_layout = { -+static struct nvmem_layout imx_ocotp_layout = { - .fixup_cell_info = imx_ocotp_fixup_cell_info, - }; - diff --git a/target/linux/generic/backport-5.15/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch b/target/linux/generic/backport-5.15/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch deleted file mode 100644 index 7523e5ebf645a7..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 8a00fc606312c68b98add8fe8e6f7a013ce29e78 Mon Sep 17 00:00:00 2001 -From: Alexander Stein -Date: Sun, 11 Jun 2023 15:03:06 +0100 -Subject: [PATCH] nvmem: imx-ocotp: Reverse MAC addresses on all i.MX derivates - -Not just i.MX8M, but all i.MX6/7 (and subtypes) need to reverse the -MAC address read from fuses. Exceptions are i.MX6SLL and i.MX7ULP which -do not support ethernet at all. - -Fixes: d0221a780cbc ("nvmem: imx-ocotp: add support for post processing") -Signed-off-by: Alexander Stein -Tested-by: Richard Leitner # imx6q -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-3-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/imx-ocotp.c | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -97,7 +97,6 @@ struct ocotp_params { - unsigned int bank_address_words; - void (*set_timing)(struct ocotp_priv *priv); - struct ocotp_ctrl_reg ctrl; -- bool reverse_mac_address; - }; - - static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags) -@@ -545,7 +544,6 @@ static const struct ocotp_params imx8mq_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -- .reverse_mac_address = true, - }; - - static const struct ocotp_params imx8mm_params = { -@@ -553,7 +551,6 @@ static const struct ocotp_params imx8mm_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -- .reverse_mac_address = true, - }; - - static const struct ocotp_params imx8mn_params = { -@@ -561,7 +558,6 @@ static const struct ocotp_params imx8mn_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -- .reverse_mac_address = true, - }; - - static const struct ocotp_params imx8mp_params = { -@@ -569,7 +565,6 @@ static const struct ocotp_params imx8mp_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_8MP, -- .reverse_mac_address = true, - }; - - static const struct of_device_id imx_ocotp_dt_ids[] = { -@@ -624,8 +619,7 @@ static int imx_ocotp_probe(struct platfo - imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; - imx_ocotp_nvmem_config.dev = dev; - imx_ocotp_nvmem_config.priv = priv; -- if (priv->params->reverse_mac_address) -- imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; -+ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; - - priv->config = &imx_ocotp_nvmem_config; - diff --git a/target/linux/generic/backport-5.15/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch b/target/linux/generic/backport-5.15/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch deleted file mode 100644 index fb4d346a95add1..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 73bcd133c910bff3b6d3b3834d0d14be9444e90a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 11 Jun 2023 15:03:08 +0100 -Subject: [PATCH] nvmem: brcm_nvram: add .read_post_process() for MACs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -1. Parse ASCII MAC format into byte based -2. Calculate relative addresses based on index argument - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-5-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 1 + - drivers/nvmem/brcm_nvram.c | 28 ++++++++++++++++++++++++++++ - 2 files changed, 29 insertions(+) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -55,6 +55,7 @@ config NVMEM_BRCM_NVRAM - tristate "Broadcom's NVRAM support" - depends on ARCH_BCM_5301X || COMPILE_TEST - depends on HAS_IOMEM -+ select GENERIC_NET_UTILS - help - This driver provides support for Broadcom's NVRAM that can be accessed - using I/O mapping. ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -4,6 +4,8 @@ - */ - - #include -+#include -+#include - #include - #include - #include -@@ -42,6 +44,25 @@ static int brcm_nvram_read(void *context - return 0; - } - -+static int brcm_nvram_read_post_process_macaddr(void *context, const char *id, int index, -+ unsigned int offset, void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (bytes != 3 * ETH_ALEN - 1) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ - static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data, - size_t len) - { -@@ -75,6 +96,13 @@ static int brcm_nvram_add_cells(struct b - priv->cells[idx].offset = value - (char *)data; - priv->cells[idx].bytes = strlen(value); - priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); -+ if (!strcmp(var, "et0macaddr") || -+ !strcmp(var, "et1macaddr") || -+ !strcmp(var, "et2macaddr")) { -+ priv->cells[idx].raw_len = strlen(value); -+ priv->cells[idx].bytes = ETH_ALEN; -+ priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr; -+ } - } - - return 0; diff --git a/target/linux/generic/backport-5.15/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch b/target/linux/generic/backport-5.15/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch deleted file mode 100644 index 3b6e6e57f52b44..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 8dc61364164e79e44c07fa2ac0a7b6939f00d5db Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sun, 11 Jun 2023 15:03:13 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Add clks and reg_read to rockchip_data - -In preparation to support new Rockchip OTP memory devices with different -clock configurations and register layout, extend rockchip_data struct -with the related members: clks, num_clks, reg_read. - -Additionally, to avoid managing redundant driver data, drop num_clks -member from rockchip_otp struct and update all references to point to -the equivalent member in rockchip_data. - -Signed-off-by: Cristian Ciocaltea -Tested-by: Vincent Legoll -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-10-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 79 ++++++++++++++++++++++-------------- - 1 file changed, 49 insertions(+), 30 deletions(-) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -54,21 +54,19 @@ - - #define OTPC_TIMEOUT 10000 - -+struct rockchip_data { -+ int size; -+ const char * const *clks; -+ int num_clks; -+ nvmem_reg_read_t reg_read; -+}; -+ - struct rockchip_otp { - struct device *dev; - void __iomem *base; -- struct clk_bulk_data *clks; -- int num_clks; -+ struct clk_bulk_data *clks; - struct reset_control *rst; --}; -- --/* list of required clocks */ --static const char * const rockchip_otp_clocks[] = { -- "otp", "apb_pclk", "phy", --}; -- --struct rockchip_data { -- int size; -+ const struct rockchip_data *data; - }; - - static int rockchip_otp_reset(struct rockchip_otp *otp) -@@ -132,29 +130,23 @@ static int rockchip_otp_ecc_enable(struc - return ret; - } - --static int rockchip_otp_read(void *context, unsigned int offset, -- void *val, size_t bytes) -+static int px30_otp_read(void *context, unsigned int offset, -+ void *val, size_t bytes) - { - struct rockchip_otp *otp = context; - u8 *buf = val; -- int ret = 0; -- -- ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks); -- if (ret < 0) { -- dev_err(otp->dev, "failed to prepare/enable clks\n"); -- return ret; -- } -+ int ret; - - ret = rockchip_otp_reset(otp); - if (ret) { - dev_err(otp->dev, "failed to reset otp phy\n"); -- goto disable_clks; -+ return ret; - } - - ret = rockchip_otp_ecc_enable(otp, false); - if (ret < 0) { - dev_err(otp->dev, "rockchip_otp_ecc_enable err\n"); -- goto disable_clks; -+ return ret; - } - - writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); -@@ -174,8 +166,28 @@ static int rockchip_otp_read(void *conte - - read_end: - writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); --disable_clks: -- clk_bulk_disable_unprepare(otp->num_clks, otp->clks); -+ -+ return ret; -+} -+ -+static int rockchip_otp_read(void *context, unsigned int offset, -+ void *val, size_t bytes) -+{ -+ struct rockchip_otp *otp = context; -+ int ret; -+ -+ if (!otp->data || !otp->data->reg_read) -+ return -EINVAL; -+ -+ ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks); -+ if (ret < 0) { -+ dev_err(otp->dev, "failed to prepare/enable clks\n"); -+ return ret; -+ } -+ -+ ret = otp->data->reg_read(context, offset, val, bytes); -+ -+ clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks); - - return ret; - } -@@ -189,8 +201,15 @@ static struct nvmem_config otp_config = - .reg_read = rockchip_otp_read, - }; - -+static const char * const px30_otp_clocks[] = { -+ "otp", "apb_pclk", "phy", -+}; -+ - static const struct rockchip_data px30_data = { - .size = 0x40, -+ .clks = px30_otp_clocks, -+ .num_clks = ARRAY_SIZE(px30_otp_clocks), -+ .reg_read = px30_otp_read, - }; - - static const struct of_device_id rockchip_otp_match[] = { -@@ -225,21 +244,21 @@ static int rockchip_otp_probe(struct pla - if (!otp) - return -ENOMEM; - -+ otp->data = data; - otp->dev = dev; - otp->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(otp->base)) - return PTR_ERR(otp->base); - -- otp->num_clks = ARRAY_SIZE(rockchip_otp_clocks); -- otp->clks = devm_kcalloc(dev, otp->num_clks, -- sizeof(*otp->clks), GFP_KERNEL); -+ otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks), -+ GFP_KERNEL); - if (!otp->clks) - return -ENOMEM; - -- for (i = 0; i < otp->num_clks; ++i) -- otp->clks[i].id = rockchip_otp_clocks[i]; -+ for (i = 0; i < data->num_clks; ++i) -+ otp->clks[i].id = data->clks[i]; - -- ret = devm_clk_bulk_get(dev, otp->num_clks, otp->clks); -+ ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks); - if (ret) - return ret; - diff --git a/target/linux/generic/backport-5.15/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch b/target/linux/generic/backport-5.15/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch deleted file mode 100644 index b5b66cfc5ac0d1..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 30fd21cfb1e64ef20035559a8246f5fbf682c40e Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sun, 11 Jun 2023 15:03:14 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Generalize rockchip_otp_wait_status() - -In preparation to support additional Rockchip OTP memory devices with -different register layout, generalize rockchip_otp_wait_status() to -accept a new parameter for specifying the offset of the status register. - -Signed-off-by: Cristian Ciocaltea -Tested-by: Vincent Legoll -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-11-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -90,18 +90,19 @@ static int rockchip_otp_reset(struct roc - return 0; - } - --static int rockchip_otp_wait_status(struct rockchip_otp *otp, u32 flag) -+static int rockchip_otp_wait_status(struct rockchip_otp *otp, -+ unsigned int reg, u32 flag) - { - u32 status = 0; - int ret; - -- ret = readl_poll_timeout_atomic(otp->base + OTPC_INT_STATUS, status, -+ ret = readl_poll_timeout_atomic(otp->base + reg, status, - (status & flag), 1, OTPC_TIMEOUT); - if (ret) - return ret; - - /* clean int status */ -- writel(flag, otp->base + OTPC_INT_STATUS); -+ writel(flag, otp->base + reg); - - return 0; - } -@@ -123,7 +124,7 @@ static int rockchip_otp_ecc_enable(struc - - writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL); - -- ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE); -+ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_SBPI_DONE); - if (ret < 0) - dev_err(otp->dev, "timeout during ecc_enable\n"); - -@@ -156,7 +157,7 @@ static int px30_otp_read(void *context, - otp->base + OTPC_USER_ADDR); - writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, - otp->base + OTPC_USER_ENABLE); -- ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); -+ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_USER_DONE); - if (ret < 0) { - dev_err(otp->dev, "timeout during read setup\n"); - goto read_end; diff --git a/target/linux/generic/backport-5.15/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch b/target/linux/generic/backport-5.15/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch deleted file mode 100644 index 3a17479d959ba2..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d325c9dd2b6e94040ca722ddcadcd6af358dd2be Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sun, 11 Jun 2023 15:03:15 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Use - devm_reset_control_array_get_exclusive() - -In preparation to support new Rockchip OTP memory devices having -specific reset configurations, switch devm_reset_control_get() to -devm_reset_control_array_get_exclusive(). - -Signed-off-by: Cristian Ciocaltea -Tested-by: Vincent Legoll -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-12-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -263,7 +263,7 @@ static int rockchip_otp_probe(struct pla - if (ret) - return ret; - -- otp->rst = devm_reset_control_get(dev, "phy"); -+ otp->rst = devm_reset_control_array_get_exclusive(dev); - if (IS_ERR(otp->rst)) - return PTR_ERR(otp->rst); - diff --git a/target/linux/generic/backport-5.15/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch b/target/linux/generic/backport-5.15/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch deleted file mode 100644 index 37cb927b100220..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 912517345b867a69542dc9f5c2cc3e9d8beaccf5 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sun, 11 Jun 2023 15:03:16 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Improve probe error handling - -Enhance error handling in the probe function by making use of -dev_err_probe(), which ensures the error code is always printed, in -addition to the specified error message. - -Signed-off-by: Cristian Ciocaltea -Tested-by: Vincent Legoll -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-13-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -235,10 +235,8 @@ static int rockchip_otp_probe(struct pla - int ret, i; - - data = of_device_get_match_data(dev); -- if (!data) { -- dev_err(dev, "failed to get match data\n"); -- return -EINVAL; -- } -+ if (!data) -+ return dev_err_probe(dev, -EINVAL, "failed to get match data\n"); - - otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp), - GFP_KERNEL); -@@ -249,7 +247,8 @@ static int rockchip_otp_probe(struct pla - otp->dev = dev; - otp->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(otp->base)) -- return PTR_ERR(otp->base); -+ return dev_err_probe(dev, PTR_ERR(otp->base), -+ "failed to ioremap resource\n"); - - otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks), - GFP_KERNEL); -@@ -261,18 +260,22 @@ static int rockchip_otp_probe(struct pla - - ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks); - if (ret) -- return ret; -+ return dev_err_probe(dev, ret, "failed to get clocks\n"); - - otp->rst = devm_reset_control_array_get_exclusive(dev); - if (IS_ERR(otp->rst)) -- return PTR_ERR(otp->rst); -+ return dev_err_probe(dev, PTR_ERR(otp->rst), -+ "failed to get resets\n"); - - otp_config.size = data->size; - otp_config.priv = otp; - otp_config.dev = dev; -- nvmem = devm_nvmem_register(dev, &otp_config); - -- return PTR_ERR_OR_ZERO(nvmem); -+ nvmem = devm_nvmem_register(dev, &otp_config); -+ if (IS_ERR(nvmem)) -+ return dev_err_probe(dev, PTR_ERR(nvmem), -+ "failed to register nvmem device\n"); -+ return 0; - } - - static struct platform_driver rockchip_otp_driver = { diff --git a/target/linux/generic/backport-5.15/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch b/target/linux/generic/backport-5.15/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch deleted file mode 100644 index c1e2231c9ec940..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 8ab099fafbbc8c9607c399d21a774784a6cb8b45 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sun, 11 Jun 2023 15:03:17 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3588 - -Add support for the OTP memory device found on the Rockchip RK3588 SoC. - -While here, remove the unnecessary 'void *' casts in the OF device ID -table. - -Co-developed-by: Finley Xiao -Signed-off-by: Finley Xiao -Signed-off-by: Cristian Ciocaltea -Tested-by: Vincent Legoll -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-14-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++- - 1 file changed, 76 insertions(+), 2 deletions(-) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -54,6 +54,19 @@ - - #define OTPC_TIMEOUT 10000 - -+/* RK3588 Register */ -+#define RK3588_OTPC_AUTO_CTRL 0x04 -+#define RK3588_OTPC_AUTO_EN 0x08 -+#define RK3588_OTPC_INT_ST 0x84 -+#define RK3588_OTPC_DOUT0 0x20 -+#define RK3588_NO_SECURE_OFFSET 0x300 -+#define RK3588_NBYTES 4 -+#define RK3588_BURST_NUM 1 -+#define RK3588_BURST_SHIFT 8 -+#define RK3588_ADDR_SHIFT 16 -+#define RK3588_AUTO_EN BIT(0) -+#define RK3588_RD_DONE BIT(1) -+ - struct rockchip_data { - int size; - const char * const *clks; -@@ -171,6 +184,52 @@ read_end: - return ret; - } - -+static int rk3588_otp_read(void *context, unsigned int offset, -+ void *val, size_t bytes) -+{ -+ struct rockchip_otp *otp = context; -+ unsigned int addr_start, addr_end, addr_len; -+ int ret, i = 0; -+ u32 data; -+ u8 *buf; -+ -+ addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES; -+ addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES; -+ addr_len = addr_end - addr_start; -+ addr_start += RK3588_NO_SECURE_OFFSET; -+ -+ buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ while (addr_len--) { -+ writel((addr_start << RK3588_ADDR_SHIFT) | -+ (RK3588_BURST_NUM << RK3588_BURST_SHIFT), -+ otp->base + RK3588_OTPC_AUTO_CTRL); -+ writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN); -+ -+ ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST, -+ RK3588_RD_DONE); -+ if (ret < 0) { -+ dev_err(otp->dev, "timeout during read setup\n"); -+ goto read_end; -+ } -+ -+ data = readl(otp->base + RK3588_OTPC_DOUT0); -+ memcpy(&buf[i], &data, RK3588_NBYTES); -+ -+ i += RK3588_NBYTES; -+ addr_start++; -+ } -+ -+ memcpy(val, buf + offset % RK3588_NBYTES, bytes); -+ -+read_end: -+ kfree(buf); -+ -+ return ret; -+} -+ - static int rockchip_otp_read(void *context, unsigned int offset, - void *val, size_t bytes) - { -@@ -213,14 +272,29 @@ static const struct rockchip_data px30_d - .reg_read = px30_otp_read, - }; - -+static const char * const rk3588_otp_clocks[] = { -+ "otp", "apb_pclk", "phy", "arb", -+}; -+ -+static const struct rockchip_data rk3588_data = { -+ .size = 0x400, -+ .clks = rk3588_otp_clocks, -+ .num_clks = ARRAY_SIZE(rk3588_otp_clocks), -+ .reg_read = rk3588_otp_read, -+}; -+ - static const struct of_device_id rockchip_otp_match[] = { - { - .compatible = "rockchip,px30-otp", -- .data = (void *)&px30_data, -+ .data = &px30_data, - }, - { - .compatible = "rockchip,rk3308-otp", -- .data = (void *)&px30_data, -+ .data = &px30_data, -+ }, -+ { -+ .compatible = "rockchip,rk3588-otp", -+ .data = &rk3588_data, - }, - { /* sentinel */ }, - }; diff --git a/target/linux/generic/backport-5.15/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch b/target/linux/generic/backport-5.15/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch deleted file mode 100644 index 220e3e9a05f303..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9734408969e978a1c0d5d752be63dd638288e374 Mon Sep 17 00:00:00 2001 -From: Michal Simek -Date: Sun, 11 Jun 2023 15:03:23 +0100 -Subject: [PATCH] nvmem: zynqmp: Switch @xilinx.com emails to @amd.com - -@xilinx.com is still working but better to switch to new amd.com after -AMD/Xilinx acquisition. - -Signed-off-by: Michal Simek -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-20-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/zynqmp_nvmem.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/zynqmp_nvmem.c -+++ b/drivers/nvmem/zynqmp_nvmem.c -@@ -76,6 +76,6 @@ static struct platform_driver zynqmp_nvm - - module_platform_driver(zynqmp_nvmem_driver); - --MODULE_AUTHOR("Michal Simek , Nava kishore Manne "); -+MODULE_AUTHOR("Michal Simek , Nava kishore Manne "); - MODULE_DESCRIPTION("ZynqMP NVMEM driver"); - MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-5.15/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch b/target/linux/generic/backport-5.15/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch deleted file mode 100644 index f8e6be4241604a..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch +++ /dev/null @@ -1,230 +0,0 @@ -From 22e9e6fcfb5042cb6d6c7874c459b034800092f1 Mon Sep 17 00:00:00 2001 -From: Peng Fan -Date: Sun, 11 Jun 2023 15:03:25 +0100 -Subject: [PATCH] nvmem: imx: support i.MX93 OCOTP - -Add i.MX93 OCOTP support. i.MX93 OCOTP has two parts: Fuse shadow -block(fsb) and fuse managed by ELE. The FSB part could be directly -accessed with MMIO, the ELE could only be accessed with ELE API. - -Currently the ELE API is not ready, so NULL function callback is used, -but it was tested with downstream ELE API. - -Signed-off-by: Peng Fan -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-22-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 9 ++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/imx-ocotp-ele.c | 175 ++++++++++++++++++++++++++++++++++ - 3 files changed, 186 insertions(+) - create mode 100644 drivers/nvmem/imx-ocotp-ele.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -83,6 +83,15 @@ config NVMEM_IMX_OCOTP - This driver can also be built as a module. If so, the module - will be called nvmem-imx-ocotp. - -+config NVMEM_IMX_OCOTP_ELE -+ tristate "i.MX On-Chip OTP Controller support" -+ depends on ARCH_MXC || COMPILE_TEST -+ depends on HAS_IOMEM -+ depends on OF -+ help -+ This is a driver for the On-Chip OTP Controller (OCOTP) -+ available on i.MX SoCs which has ELE. -+ - config NVMEM_IMX_OCOTP_SCU - tristate "i.MX8 SCU On-Chip OTP Controller support" - depends on IMX_SCU ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -18,6 +18,8 @@ obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-im - nvmem-imx-iim-y := imx-iim.o - obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o - nvmem-imx-ocotp-y := imx-ocotp.o -+obj-$(CONFIG_NVMEM_IMX_OCOTP_ELE) += nvmem-imx-ocotp-ele.o -+nvmem-imx-ocotp-ele-y := imx-ocotp-ele.o - obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvmem-imx-ocotp-scu.o - nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o - obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o ---- /dev/null -+++ b/drivers/nvmem/imx-ocotp-ele.c -@@ -0,0 +1,175 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * i.MX9 OCOTP fusebox driver -+ * -+ * Copyright 2023 NXP -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+enum fuse_type { -+ FUSE_FSB = 1, -+ FUSE_ELE = 2, -+ FUSE_INVALID = -1 -+}; -+ -+struct ocotp_map_entry { -+ u32 start; /* start word */ -+ u32 num; /* num words */ -+ enum fuse_type type; -+}; -+ -+struct ocotp_devtype_data { -+ u32 reg_off; -+ char *name; -+ u32 size; -+ u32 num_entry; -+ u32 flag; -+ nvmem_reg_read_t reg_read; -+ struct ocotp_map_entry entry[]; -+}; -+ -+struct imx_ocotp_priv { -+ struct device *dev; -+ void __iomem *base; -+ struct nvmem_config config; -+ struct mutex lock; -+ const struct ocotp_devtype_data *data; -+}; -+ -+static enum fuse_type imx_ocotp_fuse_type(void *context, u32 index) -+{ -+ struct imx_ocotp_priv *priv = context; -+ const struct ocotp_devtype_data *data = priv->data; -+ u32 start, end; -+ int i; -+ -+ for (i = 0; i < data->num_entry; i++) { -+ start = data->entry[i].start; -+ end = data->entry[i].start + data->entry[i].num; -+ -+ if (index >= start && index < end) -+ return data->entry[i].type; -+ } -+ -+ return FUSE_INVALID; -+} -+ -+static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, size_t bytes) -+{ -+ struct imx_ocotp_priv *priv = context; -+ void __iomem *reg = priv->base + priv->data->reg_off; -+ u32 count, index, num_bytes; -+ enum fuse_type type; -+ u32 *buf; -+ void *p; -+ int i; -+ -+ index = offset; -+ num_bytes = round_up(bytes, 4); -+ count = num_bytes >> 2; -+ -+ if (count > ((priv->data->size >> 2) - index)) -+ count = (priv->data->size >> 2) - index; -+ -+ p = kzalloc(num_bytes, GFP_KERNEL); -+ if (!p) -+ return -ENOMEM; -+ -+ mutex_lock(&priv->lock); -+ -+ buf = p; -+ -+ for (i = index; i < (index + count); i++) { -+ type = imx_ocotp_fuse_type(context, i); -+ if (type == FUSE_INVALID || type == FUSE_ELE) { -+ *buf++ = 0; -+ continue; -+ } -+ -+ *buf++ = readl_relaxed(reg + (i << 2)); -+ } -+ -+ memcpy(val, (u8 *)p, bytes); -+ -+ mutex_unlock(&priv->lock); -+ -+ kfree(p); -+ -+ return 0; -+}; -+ -+static int imx_ele_ocotp_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct imx_ocotp_priv *priv; -+ struct nvmem_device *nvmem; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->data = of_device_get_match_data(dev); -+ -+ priv->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(priv->base)) -+ return PTR_ERR(priv->base); -+ -+ priv->config.dev = dev; -+ priv->config.name = "ELE-OCOTP"; -+ priv->config.id = NVMEM_DEVID_AUTO; -+ priv->config.owner = THIS_MODULE; -+ priv->config.size = priv->data->size; -+ priv->config.reg_read = priv->data->reg_read; -+ priv->config.word_size = 4; -+ priv->config.stride = 1; -+ priv->config.priv = priv; -+ priv->config.read_only = true; -+ mutex_init(&priv->lock); -+ -+ nvmem = devm_nvmem_register(dev, &priv->config); -+ if (IS_ERR(nvmem)) -+ return PTR_ERR(nvmem); -+ -+ return 0; -+} -+ -+static const struct ocotp_devtype_data imx93_ocotp_data = { -+ .reg_off = 0x8000, -+ .reg_read = imx_ocotp_reg_read, -+ .size = 2048, -+ .num_entry = 6, -+ .entry = { -+ { 0, 52, FUSE_FSB }, -+ { 63, 1, FUSE_ELE}, -+ { 128, 16, FUSE_ELE }, -+ { 182, 1, FUSE_ELE }, -+ { 188, 1, FUSE_ELE }, -+ { 312, 200, FUSE_FSB } -+ }, -+}; -+ -+static const struct of_device_id imx_ele_ocotp_dt_ids[] = { -+ { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids); -+ -+static struct platform_driver imx_ele_ocotp_driver = { -+ .driver = { -+ .name = "imx_ele_ocotp", -+ .of_match_table = imx_ele_ocotp_dt_ids, -+ }, -+ .probe = imx_ele_ocotp_probe, -+}; -+module_platform_driver(imx_ele_ocotp_driver); -+ -+MODULE_DESCRIPTION("i.MX OCOTP/ELE driver"); -+MODULE_AUTHOR("Peng Fan "); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-5.15/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch b/target/linux/generic/backport-5.15/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch deleted file mode 100644 index 59b2f9fa2c6707..00000000000000 --- a/target/linux/generic/backport-5.15/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 27f699e578b1a72df89dfa3bc42e093a01dc8d10 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 11 Jun 2023 15:03:29 +0100 -Subject: [PATCH] nvmem: core: add support for fixed cells *layout* -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This adds support for the "fixed-layout" NVMEM layout binding. It allows -defining NVMEM cells in a layout DT node named "nvmem-layout". - -While NVMEM subsystem supports layout drivers it has been discussed that -"fixed-layout" may actually be supperted internally. It's because: -1. It's a very basic layout -2. It allows sharing code with legacy syntax parsing -3. It's safer for soc_device_match() due to -EPROBE_DEFER -4. This will make the syntax transition easier - -Signed-off-by: Rafał Miłecki -Reviewed-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-26-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 32 +++++++++++++++++++++++++++++--- - 1 file changed, 29 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -696,7 +696,7 @@ static int nvmem_validate_keepouts(struc - return 0; - } - --static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) -+static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) - { - struct nvmem_layout *layout = nvmem->layout; - struct device *dev = &nvmem->dev; -@@ -704,7 +704,7 @@ static int nvmem_add_cells_from_of(struc - const __be32 *addr; - int len, ret; - -- for_each_child_of_node(dev->of_node, child) { -+ for_each_child_of_node(np, child) { - struct nvmem_cell_info info = {0}; - - addr = of_get_property(child, "reg", &len); -@@ -742,6 +742,28 @@ static int nvmem_add_cells_from_of(struc - return 0; - } - -+static int nvmem_add_cells_from_legacy_of(struct nvmem_device *nvmem) -+{ -+ return nvmem_add_cells_from_dt(nvmem, nvmem->dev.of_node); -+} -+ -+static int nvmem_add_cells_from_fixed_layout(struct nvmem_device *nvmem) -+{ -+ struct device_node *layout_np; -+ int err = 0; -+ -+ layout_np = of_nvmem_layout_get_container(nvmem); -+ if (!layout_np) -+ return 0; -+ -+ if (of_device_is_compatible(layout_np, "fixed-layout")) -+ err = nvmem_add_cells_from_dt(nvmem, layout_np); -+ -+ of_node_put(layout_np); -+ -+ return err; -+} -+ - int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner) - { - layout->owner = owner; -@@ -972,7 +994,7 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -- rval = nvmem_add_cells_from_of(nvmem); -+ rval = nvmem_add_cells_from_legacy_of(nvmem); - if (rval) - goto err_remove_cells; - -@@ -982,6 +1004,10 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -+ rval = nvmem_add_cells_from_fixed_layout(nvmem); -+ if (rval) -+ goto err_remove_cells; -+ - rval = nvmem_add_cells_from_layout(nvmem); - if (rval) - goto err_remove_cells; diff --git a/target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch b/target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch deleted file mode 100644 index 592111fb9545be..00000000000000 --- a/target/linux/generic/backport-5.15/814-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 156a5bb89ca6f3edd2be0bfd0de15e575442927e Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Tue, 3 Jan 2023 15:12:47 +0200 -Subject: [PATCH] leds: Move led_init_default_state_get() to the global header - -There are users inside and outside LED framework that have implemented -a local copy of led_init_default_state_get(). In order to deduplicate -that, as the first step move the declaration from LED header to the -global one. - -Signed-off-by: Andy Shevchenko -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230103131256.33894-3-andriy.shevchenko@linux.intel.com ---- - drivers/leds/leds.h | 1 - - include/linux/leds.h | 2 ++ - 2 files changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/leds/leds.h -+++ b/drivers/leds/leds.h -@@ -27,7 +27,6 @@ ssize_t led_trigger_read(struct file *fi - ssize_t led_trigger_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, char *buf, - loff_t pos, size_t count); --enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); - - extern struct rw_semaphore leds_list_lock; - extern struct list_head leds_list; ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -63,6 +63,8 @@ struct led_init_data { - bool devname_mandatory; - }; - -+enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); -+ - struct led_hw_trigger_type { - int dummy; - }; diff --git a/target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch b/target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch deleted file mode 100644 index dcdca9044233aa..00000000000000 --- a/target/linux/generic/backport-5.15/815-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 3e8b4d6277fd19d98c817576954dd6a4ff3caa2b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 17 Apr 2023 17:17:23 +0200 -Subject: [PATCH 1/9] net: dsa: qca8k: move qca8k_port_to_phy() to header - -Move qca8k_port_to_phy() to qca8k header as it's useful for future -reference in Switch LEDs module since the same logic is applied to get -the right index of the switch port. -Make it inline as it's simple function that just decrease the port. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Reviewed-by: Michal Kubiak -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 15 --------------- - drivers/net/dsa/qca/qca8k.h | 14 ++++++++++++++ - 2 files changed, 14 insertions(+), 15 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -716,21 +716,6 @@ err_clear_skb: - return ret; - } - --static u32 --qca8k_port_to_phy(int port) --{ -- /* From Andrew Lunn: -- * Port 0 has no internal phy. -- * Port 1 has an internal PHY at MDIO address 0. -- * Port 2 has an internal PHY at MDIO address 1. -- * ... -- * Port 5 has an internal PHY at MDIO address 4. -- * Port 6 has no internal PHY. -- */ -- -- return port - 1; --} -- - static int - qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) - { ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -414,6 +414,20 @@ struct qca8k_fdb { - u8 mac[6]; - }; - -+static inline u32 qca8k_port_to_phy(int port) -+{ -+ /* From Andrew Lunn: -+ * Port 0 has no internal phy. -+ * Port 1 has an internal PHY at MDIO address 0. -+ * Port 2 has an internal PHY at MDIO address 1. -+ * ... -+ * Port 5 has an internal PHY at MDIO address 4. -+ * Port 6 has no internal PHY. -+ */ -+ -+ return port - 1; -+} -+ - /* Common setup function */ - extern const struct qca8k_mib_desc ar8327_mib[]; - extern const struct regmap_access_table qca8k_readable_table; diff --git a/target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch b/target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch deleted file mode 100644 index baf4c2e4ba713a..00000000000000 --- a/target/linux/generic/backport-5.15/815-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch +++ /dev/null @@ -1,435 +0,0 @@ -From 1e264f9d2918b5737023c44a23ae04def1095210 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 17 Apr 2023 17:17:24 +0200 -Subject: [PATCH 2/9] net: dsa: qca8k: add LEDs basic support - -Add LEDs basic support for qca8k Switch Family by adding basic -brightness_set() support. - -Since these LEDs refelect port status, the default label is set to -":port". DT binding should describe the color and function of the -LEDs using standard LEDs api. -Each LED always have the device name as prefix. The device name is -composed from the mii bus id and the PHY addr resulting in example -names like: -- qca8k-0.0:00:amber:lan -- qca8k-0.0:00:white:lan -- qca8k-0.0:01:amber:lan -- qca8k-0.0:01:white:lan - -These LEDs supports only blocking variant of the brightness_set() -function since they can sleep during access of the switch leds to set -the brightness. - -While at it add to the qca8k header file each mode defined by the Switch -Documentation for future use. - -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/Kconfig | 8 ++ - drivers/net/dsa/qca/Makefile | 3 + - drivers/net/dsa/qca/qca8k-8xxx.c | 5 + - drivers/net/dsa/qca/qca8k-leds.c | 239 +++++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 60 ++++++++ - drivers/net/dsa/qca/qca8k_leds.h | 16 +++ - 6 files changed, 331 insertions(+) - create mode 100644 drivers/net/dsa/qca/qca8k-leds.c - create mode 100644 drivers/net/dsa/qca/qca8k_leds.h - ---- a/drivers/net/dsa/qca/Kconfig -+++ b/drivers/net/dsa/qca/Kconfig -@@ -15,3 +15,11 @@ config NET_DSA_QCA8K - help - This enables support for the Qualcomm Atheros QCA8K Ethernet - switch chips. -+ -+config NET_DSA_QCA8K_LEDS_SUPPORT -+ bool "Qualcomm Atheros QCA8K Ethernet switch family LEDs support" -+ depends on NET_DSA_QCA8K -+ depends on LEDS_CLASS -+ help -+ This enabled support for LEDs present on the Qualcomm Atheros -+ QCA8K Ethernet switch chips. ---- a/drivers/net/dsa/qca/Makefile -+++ b/drivers/net/dsa/qca/Makefile -@@ -2,3 +2,6 @@ - obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o - obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o - qca8k-y += qca8k-common.o qca8k-8xxx.o -+ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT -+qca8k-y += qca8k-leds.o -+endif ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -22,6 +22,7 @@ - #include - - #include "qca8k.h" -+#include "qca8k_leds.h" - - static void - qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) -@@ -1185,6 +1186,10 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -+ ret = qca8k_setup_led_ctrl(priv); -+ if (ret) -+ return ret; -+ - /* Make sure MAC06 is disabled */ - ret = regmap_clear_bits(priv->regmap, QCA8K_REG_PORT0_PAD_CTRL, - QCA8K_PORT0_PAD_MAC06_EXCHANGE_EN); ---- /dev/null -+++ b/drivers/net/dsa/qca/qca8k-leds.c -@@ -0,0 +1,239 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include -+#include -+ -+#include "qca8k.h" -+#include "qca8k_leds.h" -+ -+static int -+qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) -+{ -+ switch (port_num) { -+ case 0: -+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); -+ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT; -+ break; -+ case 1: -+ case 2: -+ case 3: -+ /* Port 123 are controlled on a different reg */ -+ reg_info->reg = QCA8K_LED_CTRL3_REG; -+ reg_info->shift = QCA8K_LED_PHY123_PATTERN_EN_SHIFT(port_num, led_num); -+ break; -+ case 4: -+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); -+ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_led_brightness_set(struct qca8k_led *led, -+ enum led_brightness brightness) -+{ -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 mask, val; -+ -+ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); -+ -+ val = QCA8K_LED_ALWAYS_OFF; -+ if (brightness) -+ val = QCA8K_LED_ALWAYS_ON; -+ -+ /* HW regs to control brightness is special and port 1-2-3 -+ * are placed in a different reg. -+ * -+ * To control port 0 brightness: -+ * - the 2 bit (15, 14) of: -+ * - QCA8K_LED_CTRL0_REG for led1 -+ * - QCA8K_LED_CTRL1_REG for led2 -+ * - QCA8K_LED_CTRL2_REG for led3 -+ * -+ * To control port 4: -+ * - the 2 bit (31, 30) of: -+ * - QCA8K_LED_CTRL0_REG for led1 -+ * - QCA8K_LED_CTRL1_REG for led2 -+ * - QCA8K_LED_CTRL2_REG for led3 -+ * -+ * To control port 1: -+ * - the 2 bit at (9, 8) of QCA8K_LED_CTRL3_REG are used for led1 -+ * - the 2 bit at (11, 10) of QCA8K_LED_CTRL3_REG are used for led2 -+ * - the 2 bit at (13, 12) of QCA8K_LED_CTRL3_REG are used for led3 -+ * -+ * To control port 2: -+ * - the 2 bit at (15, 14) of QCA8K_LED_CTRL3_REG are used for led1 -+ * - the 2 bit at (17, 16) of QCA8K_LED_CTRL3_REG are used for led2 -+ * - the 2 bit at (19, 18) of QCA8K_LED_CTRL3_REG are used for led3 -+ * -+ * To control port 3: -+ * - the 2 bit at (21, 20) of QCA8K_LED_CTRL3_REG are used for led1 -+ * - the 2 bit at (23, 22) of QCA8K_LED_CTRL3_REG are used for led2 -+ * - the 2 bit at (25, 24) of QCA8K_LED_CTRL3_REG are used for led3 -+ * -+ * To abstract this and have less code, we use the port and led numm -+ * to calculate the shift and the correct reg due to this problem of -+ * not having a 1:1 map of LED with the regs. -+ */ -+ if (led->port_num == 0 || led->port_num == 4) { -+ mask = QCA8K_LED_PATTERN_EN_MASK; -+ val <<= QCA8K_LED_PATTERN_EN_SHIFT; -+ } else { -+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; -+ } -+ -+ return regmap_update_bits(priv->regmap, reg_info.reg, -+ mask << reg_info.shift, -+ val << reg_info.shift); -+} -+ -+static int -+qca8k_cled_brightness_set_blocking(struct led_classdev *ldev, -+ enum led_brightness brightness) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ -+ return qca8k_led_brightness_set(led, brightness); -+} -+ -+static enum led_brightness -+qca8k_led_brightness_get(struct qca8k_led *led) -+{ -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 val; -+ int ret; -+ -+ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); -+ -+ ret = regmap_read(priv->regmap, reg_info.reg, &val); -+ if (ret) -+ return 0; -+ -+ val >>= reg_info.shift; -+ -+ if (led->port_num == 0 || led->port_num == 4) { -+ val &= QCA8K_LED_PATTERN_EN_MASK; -+ val >>= QCA8K_LED_PATTERN_EN_SHIFT; -+ } else { -+ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK; -+ } -+ -+ /* Assume brightness ON only when the LED is set to always ON */ -+ return val == QCA8K_LED_ALWAYS_ON; -+} -+ -+static int -+qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) -+{ -+ struct fwnode_handle *led = NULL, *leds = NULL; -+ struct led_init_data init_data = { }; -+ struct dsa_switch *ds = priv->ds; -+ enum led_default_state state; -+ struct qca8k_led *port_led; -+ int led_num, led_index; -+ int ret; -+ -+ leds = fwnode_get_named_child_node(port, "leds"); -+ if (!leds) { -+ dev_dbg(priv->dev, "No Leds node specified in device tree for port %d!\n", -+ port_num); -+ return 0; -+ } -+ -+ fwnode_for_each_child_node(leds, led) { -+ /* Reg represent the led number of the port. -+ * Each port can have at most 3 leds attached -+ * Commonly: -+ * 1. is gigabit led -+ * 2. is mbit led -+ * 3. additional status led -+ */ -+ if (fwnode_property_read_u32(led, "reg", &led_num)) -+ continue; -+ -+ if (led_num >= QCA8K_LED_PORT_COUNT) { -+ dev_warn(priv->dev, "Invalid LED reg %d defined for port %d", -+ led_num, port_num); -+ continue; -+ } -+ -+ led_index = QCA8K_LED_PORT_INDEX(port_num, led_num); -+ -+ port_led = &priv->ports_led[led_index]; -+ port_led->port_num = port_num; -+ port_led->led_num = led_num; -+ port_led->priv = priv; -+ -+ state = led_init_default_state_get(led); -+ switch (state) { -+ case LEDS_DEFSTATE_ON: -+ port_led->cdev.brightness = 1; -+ qca8k_led_brightness_set(port_led, 1); -+ break; -+ case LEDS_DEFSTATE_KEEP: -+ port_led->cdev.brightness = -+ qca8k_led_brightness_get(port_led); -+ break; -+ default: -+ port_led->cdev.brightness = 0; -+ qca8k_led_brightness_set(port_led, 0); -+ } -+ -+ port_led->cdev.max_brightness = 1; -+ port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; -+ init_data.default_label = ":port"; -+ init_data.fwnode = led; -+ init_data.devname_mandatory = true; -+ init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d", ds->slave_mii_bus->id, -+ port_num); -+ if (!init_data.devicename) -+ return -ENOMEM; -+ -+ ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data); -+ if (ret) -+ dev_warn(priv->dev, "Failed to init LED %d for port %d", led_num, port_num); -+ -+ kfree(init_data.devicename); -+ } -+ -+ return 0; -+} -+ -+int -+qca8k_setup_led_ctrl(struct qca8k_priv *priv) -+{ -+ struct fwnode_handle *ports, *port; -+ int port_num; -+ int ret; -+ -+ ports = device_get_named_child_node(priv->dev, "ports"); -+ if (!ports) { -+ dev_info(priv->dev, "No ports node specified in device tree!"); -+ return 0; -+ } -+ -+ fwnode_for_each_child_node(ports, port) { -+ if (fwnode_property_read_u32(port, "reg", &port_num)) -+ continue; -+ -+ /* Skip checking for CPU port 0 and CPU port 6 as not supported */ -+ if (port_num == 0 || port_num == 6) -+ continue; -+ -+ /* Each port can have at most 3 different leds attached. -+ * Switch port starts from 0 to 6, but port 0 and 6 are CPU -+ * port. The port index needs to be decreased by one to identify -+ * the correct port for LED setup. -+ */ -+ ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num)); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - - #define QCA8K_ETHERNET_MDIO_PRIORITY 7 -@@ -85,6 +86,51 @@ - #define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) - #define QCA8K_MDIO_MASTER_MAX_PORTS 5 - #define QCA8K_MDIO_MASTER_MAX_REG 32 -+ -+/* LED control register */ -+#define QCA8K_LED_PORT_COUNT 3 -+#define QCA8K_LED_COUNT ((QCA8K_NUM_PORTS - QCA8K_NUM_CPU_PORTS) * QCA8K_LED_PORT_COUNT) -+#define QCA8K_LED_RULE_COUNT 6 -+#define QCA8K_LED_RULE_MAX 11 -+#define QCA8K_LED_PORT_INDEX(_phy, _led) (((_phy) * QCA8K_LED_PORT_COUNT) + (_led)) -+ -+#define QCA8K_LED_PHY123_PATTERN_EN_SHIFT(_phy, _led) ((((_phy) - 1) * 6) + 8 + (2 * (_led))) -+#define QCA8K_LED_PHY123_PATTERN_EN_MASK GENMASK(1, 0) -+ -+#define QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT 0 -+#define QCA8K_LED_PHY4_CONTROL_RULE_SHIFT 16 -+ -+#define QCA8K_LED_CTRL_REG(_i) (0x050 + (_i) * 4) -+#define QCA8K_LED_CTRL0_REG 0x50 -+#define QCA8K_LED_CTRL1_REG 0x54 -+#define QCA8K_LED_CTRL2_REG 0x58 -+#define QCA8K_LED_CTRL3_REG 0x5C -+#define QCA8K_LED_CTRL_SHIFT(_i) (((_i) % 2) * 16) -+#define QCA8K_LED_CTRL_MASK GENMASK(15, 0) -+#define QCA8K_LED_RULE_MASK GENMASK(13, 0) -+#define QCA8K_LED_BLINK_FREQ_MASK GENMASK(1, 0) -+#define QCA8K_LED_BLINK_FREQ_SHITF 0 -+#define QCA8K_LED_BLINK_2HZ 0 -+#define QCA8K_LED_BLINK_4HZ 1 -+#define QCA8K_LED_BLINK_8HZ 2 -+#define QCA8K_LED_BLINK_AUTO 3 -+#define QCA8K_LED_LINKUP_OVER_MASK BIT(2) -+#define QCA8K_LED_TX_BLINK_MASK BIT(4) -+#define QCA8K_LED_RX_BLINK_MASK BIT(5) -+#define QCA8K_LED_COL_BLINK_MASK BIT(7) -+#define QCA8K_LED_LINK_10M_EN_MASK BIT(8) -+#define QCA8K_LED_LINK_100M_EN_MASK BIT(9) -+#define QCA8K_LED_LINK_1000M_EN_MASK BIT(10) -+#define QCA8K_LED_POWER_ON_LIGHT_MASK BIT(11) -+#define QCA8K_LED_HALF_DUPLEX_MASK BIT(12) -+#define QCA8K_LED_FULL_DUPLEX_MASK BIT(13) -+#define QCA8K_LED_PATTERN_EN_MASK GENMASK(15, 14) -+#define QCA8K_LED_PATTERN_EN_SHIFT 14 -+#define QCA8K_LED_ALWAYS_OFF 0 -+#define QCA8K_LED_ALWAYS_BLINK_4HZ 1 -+#define QCA8K_LED_ALWAYS_ON 2 -+#define QCA8K_LED_RULE_CONTROLLED 3 -+ - #define QCA8K_GOL_MAC_ADDR0 0x60 - #define QCA8K_GOL_MAC_ADDR1 0x64 - #define QCA8K_MAX_FRAME_SIZE 0x78 -@@ -377,6 +423,19 @@ struct qca8k_mdio_cache { - u16 page; - }; - -+struct qca8k_led_pattern_en { -+ u32 reg; -+ u8 shift; -+}; -+ -+struct qca8k_led { -+ u8 port_num; -+ u8 led_num; -+ u16 old_rule; -+ struct qca8k_priv *priv; -+ struct led_classdev cdev; -+}; -+ - struct qca8k_priv { - u8 switch_id; - u8 switch_revision; -@@ -399,6 +458,7 @@ struct qca8k_priv { - struct qca8k_mib_eth_data mib_eth_data; - struct qca8k_mdio_cache mdio_cache; - const struct qca8k_match_data *info; -+ struct qca8k_led ports_led[QCA8K_LED_COUNT]; - }; - - struct qca8k_mib_desc { ---- /dev/null -+++ b/drivers/net/dsa/qca/qca8k_leds.h -@@ -0,0 +1,16 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#ifndef __QCA8K_LEDS_H -+#define __QCA8K_LEDS_H -+ -+/* Leds Support function */ -+#ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT -+int qca8k_setup_led_ctrl(struct qca8k_priv *priv); -+#else -+static inline int qca8k_setup_led_ctrl(struct qca8k_priv *priv) -+{ -+ return 0; -+} -+#endif -+ -+#endif /* __QCA8K_LEDS_H */ diff --git a/target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch b/target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch deleted file mode 100644 index 231c4156df8e06..00000000000000 --- a/target/linux/generic/backport-5.15/815-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 91acadcc6e599dfc62717abcdad58a459cfb1684 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 17 Apr 2023 17:17:25 +0200 -Subject: [PATCH 3/9] net: dsa: qca8k: add LEDs blink_set() support - -Add LEDs blink_set() support to qca8k Switch Family. -These LEDs support hw accellerated blinking at a fixed rate -of 4Hz. - -Reject any other value since not supported by the LEDs switch. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Acked-by: Pavel Machek -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-leds.c | 38 ++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - ---- a/drivers/net/dsa/qca/qca8k-leds.c -+++ b/drivers/net/dsa/qca/qca8k-leds.c -@@ -128,6 +128,43 @@ qca8k_led_brightness_get(struct qca8k_le - } - - static int -+qca8k_cled_blink_set(struct led_classdev *ldev, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ u32 mask, val = QCA8K_LED_ALWAYS_BLINK_4HZ; -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ -+ if (*delay_on == 0 && *delay_off == 0) { -+ *delay_on = 125; -+ *delay_off = 125; -+ } -+ -+ if (*delay_on != 125 || *delay_off != 125) { -+ /* The hardware only supports blinking at 4Hz. Fall back -+ * to software implementation in other cases. -+ */ -+ return -EINVAL; -+ } -+ -+ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); -+ -+ if (led->port_num == 0 || led->port_num == 4) { -+ mask = QCA8K_LED_PATTERN_EN_MASK; -+ val <<= QCA8K_LED_PATTERN_EN_SHIFT; -+ } else { -+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; -+ } -+ -+ regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift, -+ val << reg_info.shift); -+ -+ return 0; -+} -+ -+static int - qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) - { - struct fwnode_handle *led = NULL, *leds = NULL; -@@ -186,6 +223,7 @@ qca8k_parse_port_leds(struct qca8k_priv - - port_led->cdev.max_brightness = 1; - port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; -+ port_led->cdev.blink_set = qca8k_cled_blink_set; - init_data.default_label = ":port"; - init_data.fwnode = led; - init_data.devname_mandatory = true; diff --git a/target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch b/target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch deleted file mode 100644 index bc905b4468c1b2..00000000000000 --- a/target/linux/generic/backport-5.15/815-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch +++ /dev/null @@ -1,59 +0,0 @@ -From e5029edd53937a29801ef507cee12e657ff31ea9 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:26 +0200 -Subject: [PATCH 4/9] leds: Provide stubs for when CLASS_LED & NEW_LEDS are - disabled - -Provide stubs for devm_led_classdev_register_ext() and -led_init_default_state_get() so that LED drivers embedded within other -drivers such as PHYs and Ethernet switches still build when LEDS_CLASS -or NEW_LEDS are disabled. This also helps with Kconfig dependencies, -which are somewhat hairy for phylib and mdio and only get worse when -adding a dependency on LED_CLASS. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - include/linux/leds.h | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -63,7 +63,15 @@ struct led_init_data { - bool devname_mandatory; - }; - -+#if IS_ENABLED(CONFIG_NEW_LEDS) - enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); -+#else -+static inline enum led_default_state -+led_init_default_state_get(struct fwnode_handle *fwnode) -+{ -+ return LEDS_DEFSTATE_OFF; -+} -+#endif - - struct led_hw_trigger_type { - int dummy; -@@ -198,9 +206,19 @@ static inline int led_classdev_register( - return led_classdev_register_ext(parent, led_cdev, NULL); - } - -+#if IS_ENABLED(CONFIG_LEDS_CLASS) - int devm_led_classdev_register_ext(struct device *parent, - struct led_classdev *led_cdev, - struct led_init_data *init_data); -+#else -+static inline int -+devm_led_classdev_register_ext(struct device *parent, -+ struct led_classdev *led_cdev, -+ struct led_init_data *init_data) -+{ -+ return 0; -+} -+#endif - - static inline int devm_led_classdev_register(struct device *parent, - struct led_classdev *led_cdev) diff --git a/target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch b/target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch deleted file mode 100644 index 6e5ac8b249e486..00000000000000 --- a/target/linux/generic/backport-5.15/815-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 01e5b728e9e43ae444e0369695a5f72209906464 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:27 +0200 -Subject: [PATCH 5/9] net: phy: Add a binding for PHY LEDs - -Define common binding parsing for all PHY drivers with LEDs using -phylib. Parse the DT as part of the phy_probe and add LEDs to the -linux LED class infrastructure. For the moment, provide a dummy -brightness function, which will later be replaced with a call into the -PHY driver. This allows testing since the LED core might otherwise -reject an LED whose brightness cannot be set. - -Add a dependency on LED_CLASS. It either needs to be built in, or not -enabled, since a modular build can result in linker errors. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/Kconfig | 1 + - drivers/net/phy/phy_device.c | 76 ++++++++++++++++++++++++++++++++++++ - include/linux/phy.h | 16 ++++++++ - 3 files changed, 93 insertions(+) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -18,6 +18,7 @@ menuconfig PHYLIB - depends on NETDEVICES - select MDIO_DEVICE - select MDIO_DEVRES -+ depends on LEDS_CLASS || LEDS_CLASS=n - help - Ethernet controllers are usually attached to PHY - devices. This option provides infrastructure for ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -19,10 +19,12 @@ - #include - #include - #include -+#include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -641,6 +643,7 @@ struct phy_device *phy_device_create(str - device_initialize(&mdiodev->dev); - - dev->state = PHY_DOWN; -+ INIT_LIST_HEAD(&dev->leds); - - mutex_init(&dev->lock); - INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); -@@ -2942,6 +2945,74 @@ static bool phy_drv_supports_irq(struct - return phydrv->config_intr && phydrv->handle_interrupt; - } - -+/* Dummy implementation until calls into PHY driver are added */ -+static int phy_led_set_brightness(struct led_classdev *led_cdev, -+ enum led_brightness value) -+{ -+ return 0; -+} -+ -+static int of_phy_led(struct phy_device *phydev, -+ struct device_node *led) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct led_init_data init_data = {}; -+ struct led_classdev *cdev; -+ struct phy_led *phyled; -+ int err; -+ -+ phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL); -+ if (!phyled) -+ return -ENOMEM; -+ -+ cdev = &phyled->led_cdev; -+ -+ err = of_property_read_u8(led, "reg", &phyled->index); -+ if (err) -+ return err; -+ -+ cdev->brightness_set_blocking = phy_led_set_brightness; -+ cdev->max_brightness = 1; -+ init_data.devicename = dev_name(&phydev->mdio.dev); -+ init_data.fwnode = of_fwnode_handle(led); -+ init_data.devname_mandatory = true; -+ -+ err = devm_led_classdev_register_ext(dev, cdev, &init_data); -+ if (err) -+ return err; -+ -+ list_add(&phyled->list, &phydev->leds); -+ -+ return 0; -+} -+ -+static int of_phy_leds(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ struct device_node *leds, *led; -+ int err; -+ -+ if (!IS_ENABLED(CONFIG_OF_MDIO)) -+ return 0; -+ -+ if (!node) -+ return 0; -+ -+ leds = of_get_child_by_name(node, "leds"); -+ if (!leds) -+ return 0; -+ -+ for_each_available_child_of_node(leds, led) { -+ err = of_phy_led(phydev, led); -+ if (err) { -+ of_node_put(led); -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ - /** - * fwnode_mdio_find_device - Given a fwnode, find the mdio_device - * @fwnode: pointer to the mdio_device's fwnode -@@ -3120,6 +3191,11 @@ static int phy_probe(struct device *dev) - /* Set the state to READY by default */ - phydev->state = PHY_READY; - -+ /* Get the LEDs from the device tree, and instantiate standard -+ * LEDs for them. -+ */ -+ err = of_phy_leds(phydev); -+ - out: - /* Re-assert the reset signal on error */ - if (err) ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -590,6 +591,7 @@ struct macsec_ops; - * @phy_num_led_triggers: Number of triggers in @phy_led_triggers - * @led_link_trigger: LED trigger for link up/down - * @last_triggered: last LED trigger for link speed -+ * @leds: list of PHY LED structures - * @master_slave_set: User requested master/slave configuration - * @master_slave_get: Current master/slave advertisement - * @master_slave_state: Current master/slave configuration -@@ -678,6 +680,7 @@ struct phy_device { - - struct phy_led_trigger *led_link_trigger; - #endif -+ struct list_head leds; - - /* - * Interrupt number for this PHY -@@ -749,6 +752,19 @@ struct phy_tdr_config { - #define PHY_PAIR_ALL -1 - - /** -+ * struct phy_led: An LED driven by the PHY -+ * -+ * @list: List of LEDs -+ * @led_cdev: Standard LED class structure -+ * @index: Number of the LED -+ */ -+struct phy_led { -+ struct list_head list; -+ struct led_classdev led_cdev; -+ u8 index; -+}; -+ -+/** - * struct phy_driver - Driver structure for a particular PHY type - * - * @mdiodrv: Data common to all MDIO devices diff --git a/target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch deleted file mode 100644 index 3968a884b8b017..00000000000000 --- a/target/linux/generic/backport-5.15/815-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 684818189b04b095b34964ed4a3ea5249a840eab Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:28 +0200 -Subject: [PATCH 6/9] net: phy: phy_device: Call into the PHY driver to set LED - brightness - -Linux LEDs can be software controlled via the brightness file in /sys. -LED drivers need to implement a brightness_set function which the core -will call. Implement an intermediary in phy_device, which will call -into the phy driver if it implements the necessary function. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/phy_device.c | 15 ++++++++++++--- - include/linux/phy.h | 13 +++++++++++++ - 2 files changed, 25 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -2945,11 +2945,18 @@ static bool phy_drv_supports_irq(struct - return phydrv->config_intr && phydrv->handle_interrupt; - } - --/* Dummy implementation until calls into PHY driver are added */ - static int phy_led_set_brightness(struct led_classdev *led_cdev, - enum led_brightness value) - { -- return 0; -+ struct phy_led *phyled = to_phy_led(led_cdev); -+ struct phy_device *phydev = phyled->phydev; -+ int err; -+ -+ mutex_lock(&phydev->lock); -+ err = phydev->drv->led_brightness_set(phydev, phyled->index, value); -+ mutex_unlock(&phydev->lock); -+ -+ return err; - } - - static int of_phy_led(struct phy_device *phydev, -@@ -2966,12 +2973,14 @@ static int of_phy_led(struct phy_device - return -ENOMEM; - - cdev = &phyled->led_cdev; -+ phyled->phydev = phydev; - - err = of_property_read_u8(led, "reg", &phyled->index); - if (err) - return err; - -- cdev->brightness_set_blocking = phy_led_set_brightness; -+ if (phydev->drv->led_brightness_set) -+ cdev->brightness_set_blocking = phy_led_set_brightness; - cdev->max_brightness = 1; - init_data.devicename = dev_name(&phydev->mdio.dev); - init_data.fwnode = of_fwnode_handle(led); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -755,15 +755,19 @@ struct phy_tdr_config { - * struct phy_led: An LED driven by the PHY - * - * @list: List of LEDs -+ * @phydev: PHY this LED is attached to - * @led_cdev: Standard LED class structure - * @index: Number of the LED - */ - struct phy_led { - struct list_head list; -+ struct phy_device *phydev; - struct led_classdev led_cdev; - u8 index; - }; - -+#define to_phy_led(d) container_of(d, struct phy_led, led_cdev) -+ - /** - * struct phy_driver - Driver structure for a particular PHY type - * -@@ -978,6 +982,15 @@ struct phy_driver { - int (*get_sqi)(struct phy_device *dev); - /** @get_sqi_max: Get the maximum signal quality indication */ - int (*get_sqi_max)(struct phy_device *dev); -+ -+ /** -+ * @led_brightness_set: Set a PHY LED brightness. Index -+ * indicates which of the PHYs led should be set. Value -+ * follows the standard LED class meaning, e.g. LED_OFF, -+ * LED_HALF, LED_FULL. -+ */ -+ int (*led_brightness_set)(struct phy_device *dev, -+ u8 index, enum led_brightness value); - }; - #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ - struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch b/target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch deleted file mode 100644 index 053288ceca765a..00000000000000 --- a/target/linux/generic/backport-5.15/815-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 2d3960e58ef7c83fe1dbf952f056b9e906cb6df8 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:29 +0200 -Subject: [PATCH 7/9] net: phy: marvell: Add software control of the LEDs - -Add a brightness function, so the LEDs can be controlled from -software using the standard Linux LED infrastructure. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/marvell.c | 45 ++++++++++++++++++++++++++++++++++----- - 1 file changed, 40 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -144,11 +144,13 @@ - /* WOL Event Interrupt Enable */ - #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7) - --/* LED Timer Control Register */ --#define MII_88E1318S_PHY_LED_TCR 0x12 --#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) --#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) --#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) -+#define MII_88E1318S_PHY_LED_FUNC 0x10 -+#define MII_88E1318S_PHY_LED_FUNC_OFF (0x8) -+#define MII_88E1318S_PHY_LED_FUNC_ON (0x9) -+#define MII_88E1318S_PHY_LED_TCR 0x12 -+#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) -+#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) -+#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) - - /* Magic Packet MAC address registers */ - #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17 -@@ -2793,6 +2795,34 @@ static int marvell_hwmon_probe(struct ph - } - #endif - -+static int m88e1318_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ int reg; -+ -+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC); -+ if (reg < 0) -+ return reg; -+ -+ switch (index) { -+ case 0: -+ case 1: -+ case 2: -+ reg &= ~(0xf << (4 * index)); -+ if (value == LED_OFF) -+ reg |= MII_88E1318S_PHY_LED_FUNC_OFF << (4 * index); -+ else -+ reg |= MII_88E1318S_PHY_LED_FUNC_ON << (4 * index); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC, reg); -+} -+ - static int marvell_probe(struct phy_device *phydev) - { - struct marvell_priv *priv; -@@ -3041,6 +3071,7 @@ static struct phy_driver marvell_drivers - .get_sset_count = marvell_get_sset_count, - .get_strings = marvell_get_strings, - .get_stats = marvell_get_stats, -+ .led_brightness_set = m88e1318_led_brightness_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1145, -@@ -3147,6 +3178,7 @@ static struct phy_driver marvell_drivers - .cable_test_start = marvell_vct7_cable_test_start, - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, -+ .led_brightness_set = m88e1318_led_brightness_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1540, -@@ -3173,6 +3205,7 @@ static struct phy_driver marvell_drivers - .cable_test_start = marvell_vct7_cable_test_start, - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, -+ .led_brightness_set = m88e1318_led_brightness_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1545, -@@ -3199,6 +3232,7 @@ static struct phy_driver marvell_drivers - .cable_test_start = marvell_vct7_cable_test_start, - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, -+ .led_brightness_set = m88e1318_led_brightness_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E3016, -@@ -3340,6 +3374,7 @@ static struct phy_driver marvell_drivers - .get_stats = marvell_get_stats, - .get_tunable = m88e1540_get_tunable, - .set_tunable = m88e1540_set_tunable, -+ .led_brightness_set = m88e1318_led_brightness_set, - }, - }; - diff --git a/target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch deleted file mode 100644 index 35e1a1c7238c43..00000000000000 --- a/target/linux/generic/backport-5.15/815-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 4e901018432e38eab35d2a352661ce4727795be1 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:30 +0200 -Subject: [PATCH 8/9] net: phy: phy_device: Call into the PHY driver to set LED - blinking - -Linux LEDs can be requested to perform hardware accelerated -blinking. Pass this to the PHY driver, if it implements the op. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/phy_device.c | 18 ++++++++++++++++++ - include/linux/phy.h | 12 ++++++++++++ - 2 files changed, 30 insertions(+) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -2959,6 +2959,22 @@ static int phy_led_set_brightness(struct - return err; - } - -+static int phy_led_blink_set(struct led_classdev *led_cdev, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct phy_led *phyled = to_phy_led(led_cdev); -+ struct phy_device *phydev = phyled->phydev; -+ int err; -+ -+ mutex_lock(&phydev->lock); -+ err = phydev->drv->led_blink_set(phydev, phyled->index, -+ delay_on, delay_off); -+ mutex_unlock(&phydev->lock); -+ -+ return err; -+} -+ - static int of_phy_led(struct phy_device *phydev, - struct device_node *led) - { -@@ -2981,6 +2997,8 @@ static int of_phy_led(struct phy_device - - if (phydev->drv->led_brightness_set) - cdev->brightness_set_blocking = phy_led_set_brightness; -+ if (phydev->drv->led_blink_set) -+ cdev->blink_set = phy_led_blink_set; - cdev->max_brightness = 1; - init_data.devicename = dev_name(&phydev->mdio.dev); - init_data.fwnode = of_fwnode_handle(led); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -991,6 +991,18 @@ struct phy_driver { - */ - int (*led_brightness_set)(struct phy_device *dev, - u8 index, enum led_brightness value); -+ -+ /** -+ * @led_blink_set: Set a PHY LED brightness. Index indicates -+ * which of the PHYs led should be configured to blink. Delays -+ * are in milliseconds and if both are zero then a sensible -+ * default should be chosen. The call should adjust the -+ * timings in that case and if it can't match the values -+ * specified exactly. -+ */ -+ int (*led_blink_set)(struct phy_device *dev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off); - }; - #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ - struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch b/target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch deleted file mode 100644 index 0f258c6b92f95f..00000000000000 --- a/target/linux/generic/backport-5.15/815-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch +++ /dev/null @@ -1,104 +0,0 @@ -From ea9e86485decb2ac1750005bd96c166c9b780406 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:31 +0200 -Subject: [PATCH 9/9] net: phy: marvell: Implement led_blink_set() - -The Marvell PHY can blink the LEDs, simple on/off. All LEDs blink at -the same rate, and the reset default is 84ms per blink, which is -around 12Hz. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/marvell.c | 36 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -147,6 +147,8 @@ - #define MII_88E1318S_PHY_LED_FUNC 0x10 - #define MII_88E1318S_PHY_LED_FUNC_OFF (0x8) - #define MII_88E1318S_PHY_LED_FUNC_ON (0x9) -+#define MII_88E1318S_PHY_LED_FUNC_HI_Z (0xa) -+#define MII_88E1318S_PHY_LED_FUNC_BLINK (0xb) - #define MII_88E1318S_PHY_LED_TCR 0x12 - #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) - #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) -@@ -2823,6 +2825,35 @@ static int m88e1318_led_brightness_set(s - MII_88E1318S_PHY_LED_FUNC, reg); - } - -+static int m88e1318_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ int reg; -+ -+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC); -+ if (reg < 0) -+ return reg; -+ -+ switch (index) { -+ case 0: -+ case 1: -+ case 2: -+ reg &= ~(0xf << (4 * index)); -+ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); -+ /* Reset default is 84ms */ -+ *delay_on = 84 / 2; -+ *delay_off = 84 / 2; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC, reg); -+} -+ - static int marvell_probe(struct phy_device *phydev) - { - struct marvell_priv *priv; -@@ -3072,6 +3103,7 @@ static struct phy_driver marvell_drivers - .get_strings = marvell_get_strings, - .get_stats = marvell_get_stats, - .led_brightness_set = m88e1318_led_brightness_set, -+ .led_blink_set = m88e1318_led_blink_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1145, -@@ -3179,6 +3211,7 @@ static struct phy_driver marvell_drivers - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, - .led_brightness_set = m88e1318_led_brightness_set, -+ .led_blink_set = m88e1318_led_blink_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1540, -@@ -3206,6 +3239,7 @@ static struct phy_driver marvell_drivers - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, - .led_brightness_set = m88e1318_led_brightness_set, -+ .led_blink_set = m88e1318_led_blink_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1545, -@@ -3233,6 +3267,7 @@ static struct phy_driver marvell_drivers - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, - .led_brightness_set = m88e1318_led_brightness_set, -+ .led_blink_set = m88e1318_led_blink_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E3016, -@@ -3375,6 +3410,7 @@ static struct phy_driver marvell_drivers - .get_tunable = m88e1540_get_tunable, - .set_tunable = m88e1540_set_tunable, - .led_brightness_set = m88e1318_led_brightness_set, -+ .led_blink_set = m88e1318_led_blink_set, - }, - }; - diff --git a/target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch b/target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch deleted file mode 100644 index c5b611a125b1ae..00000000000000 --- a/target/linux/generic/backport-5.15/816-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 4774ad841bef97cc51df90195338c5b2573dd4cb Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 23 Apr 2023 19:28:00 +0200 -Subject: [PATCH] net: phy: marvell: Fix inconsistent indenting in - led_blink_set - -Fix inconsistent indeinting in m88e1318_led_blink_set reported by kernel -test robot, probably done by the presence of an if condition dropped in -later revision of the same code. - -Reported-by: kernel test robot -Link: https://lore.kernel.org/oe-kbuild-all/202304240007.0VEX8QYG-lkp@intel.com/ -Fixes: ea9e86485dec ("net: phy: marvell: Implement led_blink_set()") -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20230423172800.3470-1-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/marvell.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -2841,10 +2841,10 @@ static int m88e1318_led_blink_set(struct - case 1: - case 2: - reg &= ~(0xf << (4 * index)); -- reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); -- /* Reset default is 84ms */ -- *delay_on = 84 / 2; -- *delay_off = 84 / 2; -+ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); -+ /* Reset default is 84ms */ -+ *delay_on = 84 / 2; -+ *delay_off = 84 / 2; - break; - default: - return -EINVAL; diff --git a/target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch b/target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch deleted file mode 100644 index 3170c260580a4e..00000000000000 --- a/target/linux/generic/backport-5.15/817-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch +++ /dev/null @@ -1,87 +0,0 @@ -From e2f24cb1b5daf9a4f6f3ba574c1fa74aab9807a4 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 19 Apr 2023 23:07:40 +0200 -Subject: [PATCH 2/5] leds: trigger: netdev: Drop NETDEV_LED_MODE_LINKUP from - mode - -Putting NETDEV_LED_MODE_LINKUP in the same list of the netdev trigger -modes is wrong as it's used to set the link state of the device and not -to set a blink mode as it's done by NETDEV_LED_LINK, NETDEV_LED_TX and -NETDEV_LED_RX. It's also wrong to put this state in the same bitmap of the -netdev trigger mode and should be external to it. - -Drop NETDEV_LED_MODE_LINKUP from mode list and convert to a simple bool -that will be true or false based on the carrier link. No functional -change intended. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230419210743.3594-3-ansuelsmth@gmail.com ---- - drivers/leds/trigger/ledtrig-netdev.c | 19 ++++++++----------- - 1 file changed, 8 insertions(+), 11 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -50,10 +50,10 @@ struct led_netdev_data { - unsigned int last_activity; - - unsigned long mode; -+ bool carrier_link_up; - #define NETDEV_LED_LINK 0 - #define NETDEV_LED_TX 1 - #define NETDEV_LED_RX 2 --#define NETDEV_LED_MODE_LINKUP 3 - }; - - enum netdev_led_attr { -@@ -73,9 +73,9 @@ static void set_baseline_state(struct le - if (!led_cdev->blink_brightness) - led_cdev->blink_brightness = led_cdev->max_brightness; - -- if (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode)) -+ if (!trigger_data->carrier_link_up) { - led_set_brightness(led_cdev, LED_OFF); -- else { -+ } else { - if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) - led_set_brightness(led_cdev, - led_cdev->blink_brightness); -@@ -131,10 +131,9 @@ static ssize_t device_name_store(struct - trigger_data->net_dev = - dev_get_by_name(&init_net, trigger_data->device_name); - -- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ trigger_data->carrier_link_up = false; - if (trigger_data->net_dev != NULL) -- if (netif_carrier_ok(trigger_data->net_dev)) -- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev); - - trigger_data->last_activity = 0; - -@@ -315,11 +314,10 @@ static int netdev_trig_notify(struct not - - spin_lock_bh(&trigger_data->lock); - -- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ trigger_data->carrier_link_up = false; - switch (evt) { - case NETDEV_CHANGENAME: -- if (netif_carrier_ok(dev)) -- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ trigger_data->carrier_link_up = netif_carrier_ok(dev); - fallthrough; - case NETDEV_REGISTER: - if (trigger_data->net_dev) -@@ -333,8 +331,7 @@ static int netdev_trig_notify(struct not - break; - case NETDEV_UP: - case NETDEV_CHANGE: -- if (netif_carrier_ok(dev)) -- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ trigger_data->carrier_link_up = netif_carrier_ok(dev); - break; - } - diff --git a/target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch b/target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch deleted file mode 100644 index 19cc1d7c9edc16..00000000000000 --- a/target/linux/generic/backport-5.15/817-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch +++ /dev/null @@ -1,149 +0,0 @@ -From bdec9cb83936e0ac4cb87fed5b49fad0175f7dec Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 19 Apr 2023 23:07:41 +0200 -Subject: [PATCH 3/5] leds: trigger: netdev: Rename add namespace to netdev - trigger enum modes - -Rename NETDEV trigger enum modes to a more symbolic name and add a -namespace to them. - -Also add __TRIGGER_NETDEV_MAX to identify the max modes of the netdev -trigger. - -This is a cleanup to drop the define and no behaviour change are -intended. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230419210743.3594-4-ansuelsmth@gmail.com ---- - drivers/leds/trigger/ledtrig-netdev.c | 58 ++++++++++++--------------- - 1 file changed, 25 insertions(+), 33 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -51,15 +51,15 @@ struct led_netdev_data { - - unsigned long mode; - bool carrier_link_up; --#define NETDEV_LED_LINK 0 --#define NETDEV_LED_TX 1 --#define NETDEV_LED_RX 2 - }; - --enum netdev_led_attr { -- NETDEV_ATTR_LINK, -- NETDEV_ATTR_TX, -- NETDEV_ATTR_RX -+enum led_trigger_netdev_modes { -+ TRIGGER_NETDEV_LINK = 0, -+ TRIGGER_NETDEV_TX, -+ TRIGGER_NETDEV_RX, -+ -+ /* Keep last */ -+ __TRIGGER_NETDEV_MAX, - }; - - static void set_baseline_state(struct led_netdev_data *trigger_data) -@@ -76,7 +76,7 @@ static void set_baseline_state(struct le - if (!trigger_data->carrier_link_up) { - led_set_brightness(led_cdev, LED_OFF); - } else { -- if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) -+ if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode)) - led_set_brightness(led_cdev, - led_cdev->blink_brightness); - else -@@ -85,8 +85,8 @@ static void set_baseline_state(struct le - /* If we are looking for RX/TX start periodically - * checking stats - */ -- if (test_bit(NETDEV_LED_TX, &trigger_data->mode) || -- test_bit(NETDEV_LED_RX, &trigger_data->mode)) -+ if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) || -+ test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) - schedule_delayed_work(&trigger_data->work, 0); - } - } -@@ -146,20 +146,16 @@ static ssize_t device_name_store(struct - static DEVICE_ATTR_RW(device_name); - - static ssize_t netdev_led_attr_show(struct device *dev, char *buf, -- enum netdev_led_attr attr) -+ enum led_trigger_netdev_modes attr) - { - struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); - int bit; - - switch (attr) { -- case NETDEV_ATTR_LINK: -- bit = NETDEV_LED_LINK; -- break; -- case NETDEV_ATTR_TX: -- bit = NETDEV_LED_TX; -- break; -- case NETDEV_ATTR_RX: -- bit = NETDEV_LED_RX; -+ case TRIGGER_NETDEV_LINK: -+ case TRIGGER_NETDEV_TX: -+ case TRIGGER_NETDEV_RX: -+ bit = attr; - break; - default: - return -EINVAL; -@@ -169,7 +165,7 @@ static ssize_t netdev_led_attr_show(stru - } - - static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, -- size_t size, enum netdev_led_attr attr) -+ size_t size, enum led_trigger_netdev_modes attr) - { - struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); - unsigned long state; -@@ -181,14 +177,10 @@ static ssize_t netdev_led_attr_store(str - return ret; - - switch (attr) { -- case NETDEV_ATTR_LINK: -- bit = NETDEV_LED_LINK; -- break; -- case NETDEV_ATTR_TX: -- bit = NETDEV_LED_TX; -- break; -- case NETDEV_ATTR_RX: -- bit = NETDEV_LED_RX; -+ case TRIGGER_NETDEV_LINK: -+ case TRIGGER_NETDEV_TX: -+ case TRIGGER_NETDEV_RX: -+ bit = attr; - break; - default: - return -EINVAL; -@@ -360,21 +352,21 @@ static void netdev_trig_work(struct work - } - - /* If we are not looking for RX/TX then return */ -- if (!test_bit(NETDEV_LED_TX, &trigger_data->mode) && -- !test_bit(NETDEV_LED_RX, &trigger_data->mode)) -+ if (!test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) && -+ !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) - return; - - dev_stats = dev_get_stats(trigger_data->net_dev, &temp); - new_activity = -- (test_bit(NETDEV_LED_TX, &trigger_data->mode) ? -+ (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ? - dev_stats->tx_packets : 0) + -- (test_bit(NETDEV_LED_RX, &trigger_data->mode) ? -+ (test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ? - dev_stats->rx_packets : 0); - - if (trigger_data->last_activity != new_activity) { - led_stop_software_blink(trigger_data->led_cdev); - -- invert = test_bit(NETDEV_LED_LINK, &trigger_data->mode); -+ invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode); - interval = jiffies_to_msecs( - atomic_read(&trigger_data->interval)); - /* base state is ON (link present) */ diff --git a/target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch b/target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch deleted file mode 100644 index 3b45951f5706ad..00000000000000 --- a/target/linux/generic/backport-5.15/817-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 164b67d53476a9d114be85c885bd31f783835be4 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 19 Apr 2023 23:07:42 +0200 -Subject: [PATCH 4/5] leds: trigger: netdev: Convert device attr to macro - -Convert link tx and rx device attr to a common macro to reduce common -code and in preparation for additional attr. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230419210743.3594-5-ansuelsmth@gmail.com ---- - drivers/leds/trigger/ledtrig-netdev.c | 57 ++++++++------------------- - 1 file changed, 16 insertions(+), 41 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -198,47 +198,22 @@ static ssize_t netdev_led_attr_store(str - return size; - } - --static ssize_t link_show(struct device *dev, -- struct device_attribute *attr, char *buf) --{ -- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_LINK); --} -- --static ssize_t link_store(struct device *dev, -- struct device_attribute *attr, const char *buf, size_t size) --{ -- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_LINK); --} -- --static DEVICE_ATTR_RW(link); -- --static ssize_t tx_show(struct device *dev, -- struct device_attribute *attr, char *buf) --{ -- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_TX); --} -- --static ssize_t tx_store(struct device *dev, -- struct device_attribute *attr, const char *buf, size_t size) --{ -- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_TX); --} -- --static DEVICE_ATTR_RW(tx); -- --static ssize_t rx_show(struct device *dev, -- struct device_attribute *attr, char *buf) --{ -- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_RX); --} -- --static ssize_t rx_store(struct device *dev, -- struct device_attribute *attr, const char *buf, size_t size) --{ -- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_RX); --} -- --static DEVICE_ATTR_RW(rx); -+#define DEFINE_NETDEV_TRIGGER(trigger_name, trigger) \ -+ static ssize_t trigger_name##_show(struct device *dev, \ -+ struct device_attribute *attr, char *buf) \ -+ { \ -+ return netdev_led_attr_show(dev, buf, trigger); \ -+ } \ -+ static ssize_t trigger_name##_store(struct device *dev, \ -+ struct device_attribute *attr, const char *buf, size_t size) \ -+ { \ -+ return netdev_led_attr_store(dev, buf, size, trigger); \ -+ } \ -+ static DEVICE_ATTR_RW(trigger_name) -+ -+DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK); -+DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); -+DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); - - static ssize_t interval_show(struct device *dev, - struct device_attribute *attr, char *buf) diff --git a/target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch b/target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch deleted file mode 100644 index 180bee96128a5d..00000000000000 --- a/target/linux/generic/backport-5.15/817-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch +++ /dev/null @@ -1,106 +0,0 @@ -From d1b9e1391ab2dc80e9db87fe8b2de015c651e4c9 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 19 Apr 2023 23:07:43 +0200 -Subject: [PATCH 5/5] leds: trigger: netdev: Use mutex instead of spinlocks - -Some LEDs may require to sleep while doing some operation like setting -brightness and other cleanup. - -For this reason, using a spinlock will cause a sleep under spinlock -warning. - -It should be safe to convert this to a sleepable lock since: -- sysfs read/write can sleep -- netdev_trig_work is a work queue and can sleep -- netdev _trig_notify can sleep - -The spinlock was used when brightness didn't support sleeping, but this -changed and now it supported with brightness_set_blocking(). - -Convert to mutex lock to permit sleeping using brightness_set_blocking(). - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230419210743.3594-6-ansuelsmth@gmail.com ---- - drivers/leds/trigger/ledtrig-netdev.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -20,7 +20,7 @@ - #include - #include - #include --#include -+#include - #include - #include "../leds.h" - -@@ -37,7 +37,7 @@ - */ - - struct led_netdev_data { -- spinlock_t lock; -+ struct mutex lock; - - struct delayed_work work; - struct notifier_block notifier; -@@ -97,9 +97,9 @@ static ssize_t device_name_show(struct d - struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); - ssize_t len; - -- spin_lock_bh(&trigger_data->lock); -+ mutex_lock(&trigger_data->lock); - len = sprintf(buf, "%s\n", trigger_data->device_name); -- spin_unlock_bh(&trigger_data->lock); -+ mutex_unlock(&trigger_data->lock); - - return len; - } -@@ -115,7 +115,7 @@ static ssize_t device_name_store(struct - - cancel_delayed_work_sync(&trigger_data->work); - -- spin_lock_bh(&trigger_data->lock); -+ mutex_lock(&trigger_data->lock); - - if (trigger_data->net_dev) { - dev_put(trigger_data->net_dev); -@@ -138,7 +138,7 @@ static ssize_t device_name_store(struct - trigger_data->last_activity = 0; - - set_baseline_state(trigger_data); -- spin_unlock_bh(&trigger_data->lock); -+ mutex_unlock(&trigger_data->lock); - - return size; - } -@@ -279,7 +279,7 @@ static int netdev_trig_notify(struct not - - cancel_delayed_work_sync(&trigger_data->work); - -- spin_lock_bh(&trigger_data->lock); -+ mutex_lock(&trigger_data->lock); - - trigger_data->carrier_link_up = false; - switch (evt) { -@@ -304,7 +304,7 @@ static int netdev_trig_notify(struct not - - set_baseline_state(trigger_data); - -- spin_unlock_bh(&trigger_data->lock); -+ mutex_unlock(&trigger_data->lock); - - return NOTIFY_DONE; - } -@@ -365,7 +365,7 @@ static int netdev_trig_activate(struct l - if (!trigger_data) - return -ENOMEM; - -- spin_lock_init(&trigger_data->lock); -+ mutex_init(&trigger_data->lock); - - trigger_data->notifier.notifier_call = netdev_trig_notify; - trigger_data->notifier.priority = 10; diff --git a/target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch b/target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch deleted file mode 100644 index ac186117338ff5..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch +++ /dev/null @@ -1,74 +0,0 @@ -From ed554d3f945179c5b159bddfad7be34b403fe11a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:31 +0200 -Subject: [PATCH 01/13] leds: add APIs for LEDs hw control - -Add an option to permit LED driver to declare support for a specific -trigger to use hw control and setup the LED to blink based on specific -provided modes. - -Add APIs for LEDs hw control. These functions will be used to activate -hardware control where a LED will use the provided flags, from an -unique defined supported trigger, to setup the LED to be driven by -hardware. - -Add hw_control_is_supported() to ask the LED driver if the requested -mode by the trigger are supported and the LED can be setup to follow -the requested modes. - -Deactivate hardware blink control by setting brightness to LED_OFF via -the brightness_set() callback. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - include/linux/leds.h | 37 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -164,6 +164,43 @@ struct led_classdev { - - /* LEDs that have private triggers have this set */ - struct led_hw_trigger_type *trigger_type; -+ -+ /* Unique trigger name supported by LED set in hw control mode */ -+ const char *hw_control_trigger; -+ /* -+ * Check if the LED driver supports the requested mode provided by the -+ * defined supported trigger to setup the LED to hw control mode. -+ * -+ * Return 0 on success. Return -EOPNOTSUPP when the passed flags are not -+ * supported and software fallback needs to be used. -+ * Return a negative error number on any other case for check fail due -+ * to various reason like device not ready or timeouts. -+ */ -+ int (*hw_control_is_supported)(struct led_classdev *led_cdev, -+ unsigned long flags); -+ /* -+ * Activate hardware control, LED driver will use the provided flags -+ * from the supported trigger and setup the LED to be driven by hardware -+ * following the requested mode from the trigger flags. -+ * Deactivate hardware blink control by setting brightness to LED_OFF via -+ * the brightness_set() callback. -+ * -+ * Return 0 on success, a negative error number on flags apply fail. -+ */ -+ int (*hw_control_set)(struct led_classdev *led_cdev, -+ unsigned long flags); -+ /* -+ * Get from the LED driver the current mode that the LED is set in hw -+ * control mode and put them in flags. -+ * Trigger can use this to get the initial state of a LED already set in -+ * hardware blink control. -+ * -+ * Return 0 on success, a negative error number on failing parsing the -+ * initial mode. Error from this function is NOT FATAL as the device -+ * may be in a not supported initial state by the attached LED trigger. -+ */ -+ int (*hw_control_get)(struct led_classdev *led_cdev, -+ unsigned long *flags); - #endif - - #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED diff --git a/target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch b/target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch deleted file mode 100644 index 1a221727a01d7d..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 052c38eb17e866c5b4cd43924e7a5e20167b55c0 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 29 May 2023 18:32:32 +0200 -Subject: [PATCH 02/13] leds: add API to get attached device for LED hw control - -Some specific LED triggers blink the LED based on events from a device -or subsystem. -For example, an LED could be blinked to indicate a network device is -receiving packets, or a disk is reading blocks. To correctly enable and -request the hw control of the LED, the trigger has to check if the -network interface or block device configured via a /sys/class/led file -match the one the LED driver provide for hw control for. - -Provide an API call to get the device which the LED blinks for. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - include/linux/leds.h | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -201,6 +201,12 @@ struct led_classdev { - */ - int (*hw_control_get)(struct led_classdev *led_cdev, - unsigned long *flags); -+ /* -+ * Get the device this LED blinks in response to. -+ * e.g. for a PHY LED, it is the network device. If the LED is -+ * not yet associated to a device, return NULL. -+ */ -+ struct device *(*hw_control_get_device)(struct led_classdev *led_cdev); - #endif - - #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED diff --git a/target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch b/target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch deleted file mode 100644 index af9fb7fdc36526..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 8aa2fd7b66980ecd2e45e95af61cf7eafede1211 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:33 +0200 -Subject: [PATCH 03/13] Documentation: leds: leds-class: Document new Hardware - driven LEDs APIs - -Document new Hardware driven LEDs APIs. - -Some LEDs can be programmed to be driven by hardware. This is not -limited to blink but also to turn off or on autonomously. -To support this feature, a LED needs to implement various additional -ops and needs to declare specific support for the supported triggers. - -Add documentation for each required value and API to make hw control -possible and implementable by both LEDs and triggers. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - Documentation/leds/leds-class.rst | 81 +++++++++++++++++++++++++++++++ - 1 file changed, 81 insertions(+) - ---- a/Documentation/leds/leds-class.rst -+++ b/Documentation/leds/leds-class.rst -@@ -169,6 +169,87 @@ Setting the brightness to zero with brig - should completely turn off the LED and cancel the previously programmed - hardware blinking function, if any. - -+Hardware driven LEDs -+==================== -+ -+Some LEDs can be programmed to be driven by hardware. This is not -+limited to blink but also to turn off or on autonomously. -+To support this feature, a LED needs to implement various additional -+ops and needs to declare specific support for the supported triggers. -+ -+With hw control we refer to the LED driven by hardware. -+ -+LED driver must define the following value to support hw control: -+ -+ - hw_control_trigger: -+ unique trigger name supported by the LED in hw control -+ mode. -+ -+LED driver must implement the following API to support hw control: -+ - hw_control_is_supported: -+ check if the flags passed by the supported trigger can -+ be parsed and activate hw control on the LED. -+ -+ Return 0 if the passed flags mask is supported and -+ can be set with hw_control_set(). -+ -+ If the passed flags mask is not supported -EOPNOTSUPP -+ must be returned, the LED trigger will use software -+ fallback in this case. -+ -+ Return a negative error in case of any other error like -+ device not ready or timeouts. -+ -+ - hw_control_set: -+ activate hw control. LED driver will use the provided -+ flags passed from the supported trigger, parse them to -+ a set of mode and setup the LED to be driven by hardware -+ following the requested modes. -+ -+ Set LED_OFF via the brightness_set to deactivate hw control. -+ -+ Return 0 on success, a negative error number on failing to -+ apply flags. -+ -+ - hw_control_get: -+ get active modes from a LED already in hw control, parse -+ them and set in flags the current active flags for the -+ supported trigger. -+ -+ Return 0 on success, a negative error number on failing -+ parsing the initial mode. -+ Error from this function is NOT FATAL as the device may -+ be in a not supported initial state by the attached LED -+ trigger. -+ -+ - hw_control_get_device: -+ return the device associated with the LED driver in -+ hw control. A trigger might use this to match the -+ returned device from this function with a configured -+ device for the trigger as the source for blinking -+ events and correctly enable hw control. -+ (example a netdev trigger configured to blink for a -+ particular dev match the returned dev from get_device -+ to set hw control) -+ -+ Returns a pointer to a struct device or NULL if nothing -+ is currently attached. -+ -+LED driver can activate additional modes by default to workaround the -+impossibility of supporting each different mode on the supported trigger. -+Examples are hardcoding the blink speed to a set interval, enable special -+feature like bypassing blink if some requirements are not met. -+ -+A trigger should first check if the hw control API are supported by the LED -+driver and check if the trigger is supported to verify if hw control is possible, -+use hw_control_is_supported to check if the flags are supported and only at -+the end use hw_control_set to activate hw control. -+ -+A trigger can use hw_control_get to check if a LED is already in hw control -+and init their flags. -+ -+When the LED is in hw control, no software blink is possible and doing so -+will effectively disable hw control. - - Known Issues - ============ diff --git a/target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch b/target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch deleted file mode 100644 index 3c804c0b412e3c..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 28a6a2ef18ad840a390d519840c303b03040961c Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 29 May 2023 18:32:34 +0200 -Subject: [PATCH 04/13] leds: trigger: netdev: refactor code setting device - name - -Move the code into a helper, ready for it to be called at -other times. No intended behaviour change. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 29 ++++++++++++++++++--------- - 1 file changed, 20 insertions(+), 9 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -104,15 +104,9 @@ static ssize_t device_name_show(struct d - return len; - } - --static ssize_t device_name_store(struct device *dev, -- struct device_attribute *attr, const char *buf, -- size_t size) -+static int set_device_name(struct led_netdev_data *trigger_data, -+ const char *name, size_t size) - { -- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); -- -- if (size >= IFNAMSIZ) -- return -EINVAL; -- - cancel_delayed_work_sync(&trigger_data->work); - - mutex_lock(&trigger_data->lock); -@@ -122,7 +116,7 @@ static ssize_t device_name_store(struct - trigger_data->net_dev = NULL; - } - -- memcpy(trigger_data->device_name, buf, size); -+ memcpy(trigger_data->device_name, name, size); - trigger_data->device_name[size] = 0; - if (size > 0 && trigger_data->device_name[size - 1] == '\n') - trigger_data->device_name[size - 1] = 0; -@@ -140,6 +134,23 @@ static ssize_t device_name_store(struct - set_baseline_state(trigger_data); - mutex_unlock(&trigger_data->lock); - -+ return 0; -+} -+ -+static ssize_t device_name_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, -+ size_t size) -+{ -+ struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); -+ int ret; -+ -+ if (size >= IFNAMSIZ) -+ return -EINVAL; -+ -+ ret = set_device_name(trigger_data, buf, size); -+ -+ if (ret < 0) -+ return ret; - return size; - } - diff --git a/target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch b/target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch deleted file mode 100644 index 284b519482cfed..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 4fd1b6d47a7a38e81fdc6f8be2ccd4216b3f93db Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:35 +0200 -Subject: [PATCH 05/13] leds: trigger: netdev: introduce check for possible hw - control - -Introduce function to check if the requested mode can use hw control in -preparation for hw control support. Currently everything is handled in -software so can_hw_control will always return false. - -Add knob with the new value hw_control in trigger_data struct to -set hw control possible. Useful for future implementation to implement -in set_baseline_state() the required function to set the requested mode -using LEDs hw control ops and in other function to reject set if hw -control is currently active. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -51,6 +51,7 @@ struct led_netdev_data { - - unsigned long mode; - bool carrier_link_up; -+ bool hw_control; - }; - - enum led_trigger_netdev_modes { -@@ -91,6 +92,11 @@ static void set_baseline_state(struct le - } - } - -+static bool can_hw_control(struct led_netdev_data *trigger_data) -+{ -+ return false; -+} -+ - static ssize_t device_name_show(struct device *dev, - struct device_attribute *attr, char *buf) - { -@@ -204,6 +210,8 @@ static ssize_t netdev_led_attr_store(str - else - clear_bit(bit, &trigger_data->mode); - -+ trigger_data->hw_control = can_hw_control(trigger_data); -+ - set_baseline_state(trigger_data); - - return size; diff --git a/target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch b/target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch deleted file mode 100644 index 09759bc623e9c0..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6352f25f9fadba59d5df2ba7139495759ccc81d5 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:36 +0200 -Subject: [PATCH 06/13] leds: trigger: netdev: add basic check for hw control - support - -Add basic check for hw control support. Check if the required API are -defined and check if the defined trigger supported in hw control for the -LED driver match netdev. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -92,8 +92,22 @@ static void set_baseline_state(struct le - } - } - -+static bool supports_hw_control(struct led_classdev *led_cdev) -+{ -+ if (!led_cdev->hw_control_get || !led_cdev->hw_control_set || -+ !led_cdev->hw_control_is_supported) -+ return false; -+ -+ return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name); -+} -+ - static bool can_hw_control(struct led_netdev_data *trigger_data) - { -+ struct led_classdev *led_cdev = trigger_data->led_cdev; -+ -+ if (!supports_hw_control(led_cdev)) -+ return false; -+ - return false; - } - diff --git a/target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch b/target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch deleted file mode 100644 index 66349068003149..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c84c80c7388f887b10dafd70fc55bc6c5fe9fa5a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:37 +0200 -Subject: [PATCH 07/13] leds: trigger: netdev: reject interval store for - hw_control - -Reject interval store with hw_control enabled. It's are currently not -supported and MUST be set to the default value with hw control enabled. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -265,6 +265,9 @@ static ssize_t interval_store(struct dev - unsigned long value; - int ret; - -+ if (trigger_data->hw_control) -+ return -EINVAL; -+ - ret = kstrtoul(buf, 0, &value); - if (ret) - return ret; diff --git a/target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch b/target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch deleted file mode 100644 index 52faa4809b2ae0..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 7c145a34ba6e380616af93262fcab9fc7261d851 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:38 +0200 -Subject: [PATCH 08/13] leds: trigger: netdev: add support for LED hw control - -Add support for LED hw control for the netdev trigger. - -The trigger on calling set_baseline_state to configure a new mode, will -do various check to verify if hw control can be used for the requested -mode in can_hw_control() function. - -It will first check if the LED driver supports hw control for the netdev -trigger, then will use hw_control_is_supported() and finally will call -hw_control_set() to apply the requested mode. - -To use such mode, interval MUST be set to the default value and net_dev -MUST be set. If one of these 2 value are not valid, hw control will -never be used and normal software fallback is used. - -The default interval value is moved to a define to make sure they are -always synced. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 43 +++++++++++++++++++++++++-- - 1 file changed, 41 insertions(+), 2 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -24,6 +24,8 @@ - #include - #include "../leds.h" - -+#define NETDEV_LED_DEFAULT_INTERVAL 50 -+ - /* - * Configurable sysfs attributes: - * -@@ -68,6 +70,13 @@ static void set_baseline_state(struct le - int current_brightness; - struct led_classdev *led_cdev = trigger_data->led_cdev; - -+ /* Already validated, hw control is possible with the requested mode */ -+ if (trigger_data->hw_control) { -+ led_cdev->hw_control_set(led_cdev, trigger_data->mode); -+ -+ return; -+ } -+ - current_brightness = led_cdev->brightness; - if (current_brightness) - led_cdev->blink_brightness = current_brightness; -@@ -103,12 +112,42 @@ static bool supports_hw_control(struct l - - static bool can_hw_control(struct led_netdev_data *trigger_data) - { -+ unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL); -+ unsigned int interval = atomic_read(&trigger_data->interval); - struct led_classdev *led_cdev = trigger_data->led_cdev; -+ int ret; - - if (!supports_hw_control(led_cdev)) - return false; - -- return false; -+ /* -+ * Interval must be set to the default -+ * value. Any different value is rejected if in hw -+ * control. -+ */ -+ if (interval != default_interval) -+ return false; -+ -+ /* -+ * net_dev must be set with hw control, otherwise no -+ * blinking can be happening and there is nothing to -+ * offloaded. -+ */ -+ if (!trigger_data->net_dev) -+ return false; -+ -+ /* Check if the requested mode is supported */ -+ ret = led_cdev->hw_control_is_supported(led_cdev, trigger_data->mode); -+ /* Fall back to software blinking if not supported */ -+ if (ret == -EOPNOTSUPP) -+ return false; -+ if (ret) { -+ dev_warn(led_cdev->dev, -+ "Current mode check failed with error %d\n", ret); -+ return false; -+ } -+ -+ return true; - } - - static ssize_t device_name_show(struct device *dev, -@@ -413,7 +452,7 @@ static int netdev_trig_activate(struct l - trigger_data->device_name[0] = 0; - - trigger_data->mode = 0; -- atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); -+ atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL)); - trigger_data->last_activity = 0; - - led_set_trigger_data(led_cdev, trigger_data); diff --git a/target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch b/target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch deleted file mode 100644 index c129ffa4f5944c..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 33ec0b53befff2c0a7f3aa19ff08556d60585d6b Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 29 May 2023 18:32:39 +0200 -Subject: [PATCH 09/13] leds: trigger: netdev: validate configured netdev - -The netdev which the LED should blink for is configurable in -/sys/class/led/foo/device_name. Ensure when offloading that the -configured netdev is the same as the netdev the LED is associated -with. If it is not, only perform software blinking. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 24 ++++++++++++++++++++++-- - 1 file changed, 22 insertions(+), 2 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -110,6 +110,24 @@ static bool supports_hw_control(struct l - return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name); - } - -+/* -+ * Validate the configured netdev is the same as the one associated with -+ * the LED driver in hw control. -+ */ -+static bool validate_net_dev(struct led_classdev *led_cdev, -+ struct net_device *net_dev) -+{ -+ struct device *dev = led_cdev->hw_control_get_device(led_cdev); -+ struct net_device *ndev; -+ -+ if (!dev) -+ return false; -+ -+ ndev = to_net_dev(dev); -+ -+ return ndev == net_dev; -+} -+ - static bool can_hw_control(struct led_netdev_data *trigger_data) - { - unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL); -@@ -131,9 +149,11 @@ static bool can_hw_control(struct led_ne - /* - * net_dev must be set with hw control, otherwise no - * blinking can be happening and there is nothing to -- * offloaded. -+ * offloaded. Additionally, for hw control to be -+ * valid, the configured netdev must be the same as -+ * netdev associated to the LED. - */ -- if (!trigger_data->net_dev) -+ if (!validate_net_dev(led_cdev, trigger_data->net_dev)) - return false; - - /* Check if the requested mode is supported */ diff --git a/target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch b/target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch deleted file mode 100644 index e20594c99a3eaa..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0316cc5629d15880dd3f097d221c55ca648bcd61 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:40 +0200 -Subject: [PATCH 10/13] leds: trigger: netdev: init mode if hw control already - active - -On netdev trigger activation, hw control may be already active by -default. If this is the case and a device is actually provided by -hw_control_get_device(), init the already active mode and set the -bool to hw_control bool to true to reflect the already set mode in the -trigger_data. - -Co-developed-by: Andrew Lunn -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -454,6 +454,8 @@ static void netdev_trig_work(struct work - static int netdev_trig_activate(struct led_classdev *led_cdev) - { - struct led_netdev_data *trigger_data; -+ unsigned long mode; -+ struct device *dev; - int rc; - - trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); -@@ -475,6 +477,21 @@ static int netdev_trig_activate(struct l - atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL)); - trigger_data->last_activity = 0; - -+ /* Check if hw control is active by default on the LED. -+ * Init already enabled mode in hw control. -+ */ -+ if (supports_hw_control(led_cdev) && -+ !led_cdev->hw_control_get(led_cdev, &mode)) { -+ dev = led_cdev->hw_control_get_device(led_cdev); -+ if (dev) { -+ const char *name = dev_name(dev); -+ -+ set_device_name(trigger_data, name, strlen(name)); -+ trigger_data->hw_control = true; -+ trigger_data->mode = mode; -+ } -+ } -+ - led_set_trigger_data(led_cdev, trigger_data); - - rc = register_netdevice_notifier(&trigger_data->notifier); diff --git a/target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch b/target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch deleted file mode 100644 index 70aed850d13b4c..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 947acacab5ea151291b861cdfbde16ff5cf1b08c Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:41 +0200 -Subject: [PATCH 11/13] leds: trigger: netdev: expose netdev trigger modes in - linux include - -Expose netdev trigger modes to make them accessible by LED driver that -will support netdev trigger for hw control. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 9 --------- - include/linux/leds.h | 10 ++++++++++ - 2 files changed, 10 insertions(+), 9 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -56,15 +56,6 @@ struct led_netdev_data { - bool hw_control; - }; - --enum led_trigger_netdev_modes { -- TRIGGER_NETDEV_LINK = 0, -- TRIGGER_NETDEV_TX, -- TRIGGER_NETDEV_RX, -- -- /* Keep last */ -- __TRIGGER_NETDEV_MAX, --}; -- - static void set_baseline_state(struct led_netdev_data *trigger_data) - { - int current_brightness; ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -527,6 +527,16 @@ static inline void *led_get_trigger_data - - #endif /* CONFIG_LEDS_TRIGGERS */ - -+/* Trigger specific enum */ -+enum led_trigger_netdev_modes { -+ TRIGGER_NETDEV_LINK = 0, -+ TRIGGER_NETDEV_TX, -+ TRIGGER_NETDEV_RX, -+ -+ /* Keep last */ -+ __TRIGGER_NETDEV_MAX, -+}; -+ - /* Trigger specific functions */ - #ifdef CONFIG_LEDS_TRIGGER_DISK - void ledtrig_disk_activity(bool write); diff --git a/target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch b/target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch deleted file mode 100644 index ad76d89b7bf842..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch +++ /dev/null @@ -1,200 +0,0 @@ -From e0256648c831af13cbfe4a1787327fcec01c2807 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:42 +0200 -Subject: [PATCH 12/13] net: dsa: qca8k: implement hw_control ops - -Implement hw_control ops to drive Switch LEDs based on hardware events. - -Netdev trigger is the declared supported trigger for hw control -operation and supports the following mode: -- tx -- rx - -When hw_control_set is called, LEDs are set to follow the requested -mode. -Each LEDs will blink at 4Hz by default. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-leds.c | 154 +++++++++++++++++++++++++++++++ - 1 file changed, 154 insertions(+) - ---- a/drivers/net/dsa/qca/qca8k-leds.c -+++ b/drivers/net/dsa/qca/qca8k-leds.c -@@ -32,6 +32,43 @@ qca8k_get_enable_led_reg(int port_num, i - } - - static int -+qca8k_get_control_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) -+{ -+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); -+ -+ /* 6 total control rule: -+ * 3 control rules for phy0-3 that applies to all their leds -+ * 3 control rules for phy4 -+ */ -+ if (port_num == 4) -+ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT; -+ else -+ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT; -+ -+ return 0; -+} -+ -+static int -+qca8k_parse_netdev(unsigned long rules, u32 *offload_trigger) -+{ -+ /* Parsing specific to netdev trigger */ -+ if (test_bit(TRIGGER_NETDEV_TX, &rules)) -+ *offload_trigger |= QCA8K_LED_TX_BLINK_MASK; -+ if (test_bit(TRIGGER_NETDEV_RX, &rules)) -+ *offload_trigger |= QCA8K_LED_RX_BLINK_MASK; -+ -+ if (rules && !*offload_trigger) -+ return -EOPNOTSUPP; -+ -+ /* Enable some default rule by default to the requested mode: -+ * - Blink at 4Hz by default -+ */ -+ *offload_trigger |= QCA8K_LED_BLINK_4HZ; -+ -+ return 0; -+} -+ -+static int - qca8k_led_brightness_set(struct qca8k_led *led, - enum led_brightness brightness) - { -@@ -165,6 +202,119 @@ qca8k_cled_blink_set(struct led_classdev - } - - static int -+qca8k_cled_trigger_offload(struct led_classdev *ldev, bool enable) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 mask, val = QCA8K_LED_ALWAYS_OFF; -+ -+ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); -+ -+ if (enable) -+ val = QCA8K_LED_RULE_CONTROLLED; -+ -+ if (led->port_num == 0 || led->port_num == 4) { -+ mask = QCA8K_LED_PATTERN_EN_MASK; -+ val <<= QCA8K_LED_PATTERN_EN_SHIFT; -+ } else { -+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; -+ } -+ -+ return regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift, -+ val << reg_info.shift); -+} -+ -+static bool -+qca8k_cled_hw_control_status(struct led_classdev *ldev) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 val; -+ -+ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); -+ -+ regmap_read(priv->regmap, reg_info.reg, &val); -+ -+ val >>= reg_info.shift; -+ -+ if (led->port_num == 0 || led->port_num == 4) { -+ val &= QCA8K_LED_PATTERN_EN_MASK; -+ val >>= QCA8K_LED_PATTERN_EN_SHIFT; -+ } else { -+ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK; -+ } -+ -+ return val == QCA8K_LED_RULE_CONTROLLED; -+} -+ -+static int -+qca8k_cled_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules) -+{ -+ u32 offload_trigger = 0; -+ -+ return qca8k_parse_netdev(rules, &offload_trigger); -+} -+ -+static int -+qca8k_cled_hw_control_set(struct led_classdev *ldev, unsigned long rules) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 offload_trigger = 0; -+ int ret; -+ -+ ret = qca8k_parse_netdev(rules, &offload_trigger); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_cled_trigger_offload(ldev, true); -+ if (ret) -+ return ret; -+ -+ qca8k_get_control_led_reg(led->port_num, led->led_num, ®_info); -+ -+ return regmap_update_bits(priv->regmap, reg_info.reg, -+ QCA8K_LED_RULE_MASK << reg_info.shift, -+ offload_trigger << reg_info.shift); -+} -+ -+static int -+qca8k_cled_hw_control_get(struct led_classdev *ldev, unsigned long *rules) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 val; -+ int ret; -+ -+ /* With hw control not active return err */ -+ if (!qca8k_cled_hw_control_status(ldev)) -+ return -EINVAL; -+ -+ qca8k_get_control_led_reg(led->port_num, led->led_num, ®_info); -+ -+ ret = regmap_read(priv->regmap, reg_info.reg, &val); -+ if (ret) -+ return ret; -+ -+ val >>= reg_info.shift; -+ val &= QCA8K_LED_RULE_MASK; -+ -+ /* Parsing specific to netdev trigger */ -+ if (val & QCA8K_LED_TX_BLINK_MASK) -+ set_bit(TRIGGER_NETDEV_TX, rules); -+ if (val & QCA8K_LED_RX_BLINK_MASK) -+ set_bit(TRIGGER_NETDEV_RX, rules); -+ -+ return 0; -+} -+ -+static int - qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) - { - struct fwnode_handle *led = NULL, *leds = NULL; -@@ -224,6 +374,10 @@ qca8k_parse_port_leds(struct qca8k_priv - port_led->cdev.max_brightness = 1; - port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; - port_led->cdev.blink_set = qca8k_cled_blink_set; -+ port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported; -+ port_led->cdev.hw_control_set = qca8k_cled_hw_control_set; -+ port_led->cdev.hw_control_get = qca8k_cled_hw_control_get; -+ port_led->cdev.hw_control_trigger = "netdev"; - init_data.default_label = ":port"; - init_data.fwnode = led; - init_data.devname_mandatory = true; diff --git a/target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch b/target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch deleted file mode 100644 index feb6b9e1e4e8e4..00000000000000 --- a/target/linux/generic/backport-5.15/818-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 4f53c27f772e27e4cf4e5507d6f4d5980002cb6a Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 29 May 2023 18:32:43 +0200 -Subject: [PATCH 13/13] net: dsa: qca8k: add op to get ports netdev - -In order that the LED trigger can blink the switch MAC ports LED, it -needs to know the netdev associated to the port. Add the callback to -return the struct device of the netdev. - -Add an helper function qca8k_phy_to_port() to convert the phy back to -dsa_port index, as we reference LED port based on the internal PHY -index and needs to be converted back. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-leds.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - ---- a/drivers/net/dsa/qca/qca8k-leds.c -+++ b/drivers/net/dsa/qca/qca8k-leds.c -@@ -5,6 +5,18 @@ - #include "qca8k.h" - #include "qca8k_leds.h" - -+static u32 qca8k_phy_to_port(int phy) -+{ -+ /* Internal PHY 0 has port at index 1. -+ * Internal PHY 1 has port at index 2. -+ * Internal PHY 2 has port at index 3. -+ * Internal PHY 3 has port at index 4. -+ * Internal PHY 4 has port at index 5. -+ */ -+ -+ return phy + 1; -+} -+ - static int - qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) - { -@@ -314,6 +326,20 @@ qca8k_cled_hw_control_get(struct led_cla - return 0; - } - -+static struct device *qca8k_cled_hw_control_get_device(struct led_classdev *ldev) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ struct qca8k_priv *priv = led->priv; -+ struct dsa_port *dp; -+ -+ dp = dsa_to_port(priv->ds, qca8k_phy_to_port(led->port_num)); -+ if (!dp) -+ return NULL; -+ if (dp->slave) -+ return &dp->slave->dev; -+ return NULL; -+} -+ - static int - qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) - { -@@ -377,6 +403,7 @@ qca8k_parse_port_leds(struct qca8k_priv - port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported; - port_led->cdev.hw_control_set = qca8k_cled_hw_control_set; - port_led->cdev.hw_control_get = qca8k_cled_hw_control_get; -+ port_led->cdev.hw_control_get_device = qca8k_cled_hw_control_get_device; - port_led->cdev.hw_control_trigger = "netdev"; - init_data.default_label = ":port"; - init_data.fwnode = led; diff --git a/target/linux/generic/backport-5.15/819-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch b/target/linux/generic/backport-5.15/819-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch deleted file mode 100644 index bf7a816bb225cc..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 9ccfcbeb8f32ff89e99b36cb9cdebaa0d1b44ed1 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:24 +0100 -Subject: [PATCH] nvmem: sunxi_sid: Convert to devm_platform_ioremap_resource() - -Use devm_platform_ioremap_resource() to simplify code. - -Signed-off-by: Yangtao Li -Acked-by: Jernej Skrabec -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sunxi_sid.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/nvmem/sunxi_sid.c -+++ b/drivers/nvmem/sunxi_sid.c -@@ -125,7 +125,6 @@ static int sun8i_sid_read_by_reg(void *c - static int sunxi_sid_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -- struct resource *res; - struct nvmem_config *nvmem_cfg; - struct nvmem_device *nvmem; - struct sunxi_sid *sid; -@@ -142,8 +141,7 @@ static int sunxi_sid_probe(struct platfo - return -EINVAL; - sid->value_offset = cfg->value_offset; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- sid->base = devm_ioremap_resource(dev, res); -+ sid->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(sid->base)) - return PTR_ERR(sid->base); - diff --git a/target/linux/generic/backport-5.15/819-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch b/target/linux/generic/backport-5.15/819-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch deleted file mode 100644 index f142d735de38c0..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch +++ /dev/null @@ -1,30 +0,0 @@ -From cfadd0e7d9225566f320bc4dc716682be910be6c Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:25 +0100 -Subject: [PATCH] nvmem: brcm_nvram: Use - devm_platform_get_and_ioremap_resource() - -Convert platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/brcm_nvram.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -159,8 +159,7 @@ static int brcm_nvram_probe(struct platf - return -ENOMEM; - priv->dev = dev; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->base = devm_ioremap_resource(dev, res); -+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - diff --git a/target/linux/generic/backport-5.15/819-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch b/target/linux/generic/backport-5.15/819-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch deleted file mode 100644 index 0395bbf8bcef3e..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0b49178e2b6b4aac3c7fa3ce8d8c02208a13b988 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:26 +0100 -Subject: [PATCH] nvmem: lpc18xx_otp: Convert to - devm_platform_ioremap_resource() - -Use devm_platform_ioremap_resource() to simplify code. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/lpc18xx_otp.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/nvmem/lpc18xx_otp.c -+++ b/drivers/nvmem/lpc18xx_otp.c -@@ -68,14 +68,12 @@ static int lpc18xx_otp_probe(struct plat - { - struct nvmem_device *nvmem; - struct lpc18xx_otp *otp; -- struct resource *res; - - otp = devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL); - if (!otp) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- otp->base = devm_ioremap_resource(&pdev->dev, res); -+ otp->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(otp->base)) - return PTR_ERR(otp->base); - diff --git a/target/linux/generic/backport-5.15/819-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch b/target/linux/generic/backport-5.15/819-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch deleted file mode 100644 index da077eb4b745f6..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0a223a097709b99a0ba738d6be5b4f52c04ffb64 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:27 +0100 -Subject: [PATCH] nvmem: meson-mx-efuse: Convert to - devm_platform_ioremap_resource() - -Use devm_platform_ioremap_resource() to simplify code. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/meson-mx-efuse.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/nvmem/meson-mx-efuse.c -+++ b/drivers/nvmem/meson-mx-efuse.c -@@ -194,7 +194,6 @@ static int meson_mx_efuse_probe(struct p - { - const struct meson_mx_efuse_platform_data *drvdata; - struct meson_mx_efuse *efuse; -- struct resource *res; - - drvdata = of_device_get_match_data(&pdev->dev); - if (!drvdata) -@@ -204,8 +203,7 @@ static int meson_mx_efuse_probe(struct p - if (!efuse) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- efuse->base = devm_ioremap_resource(&pdev->dev, res); -+ efuse->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(efuse->base)) - return PTR_ERR(efuse->base); - diff --git a/target/linux/generic/backport-5.15/819-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch b/target/linux/generic/backport-5.15/819-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch deleted file mode 100644 index dc144ddfbdfa86..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 94904db28db49ac8fbb2a273d25156db26a3a985 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:28 +0100 -Subject: [PATCH] nvmem: rockchip-efuse: Use - devm_platform_get_and_ioremap_resource() - -Convert platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -Signed-off-by: Yangtao Li -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-efuse.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/rockchip-efuse.c -+++ b/drivers/nvmem/rockchip-efuse.c -@@ -267,8 +267,7 @@ static int rockchip_efuse_probe(struct p - if (!efuse) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- efuse->base = devm_ioremap_resource(dev, res); -+ efuse->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(efuse->base)) - return PTR_ERR(efuse->base); - diff --git a/target/linux/generic/backport-5.15/819-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-5.15/819-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch deleted file mode 100644 index 99e20939ccf09f..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0a4a8c0d238fec1fa4b85591524ef42ad261cb97 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:29 +0100 -Subject: [PATCH] nvmem: stm32-romem: Use - devm_platform_get_and_ioremap_resource() - -Convert platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -196,8 +196,7 @@ static int stm32_romem_probe(struct plat - if (!priv) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->base = devm_ioremap_resource(dev, res); -+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - diff --git a/target/linux/generic/backport-5.15/819-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch b/target/linux/generic/backport-5.15/819-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch deleted file mode 100644 index 6d93752e27177f..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0bc0d6dc2a9a05ae6729b4622f09782d9f230815 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:30 +0100 -Subject: [PATCH] nvmem: qfprom: do some cleanup - -Use devm_platform_ioremap_resource() and -devm_platform_get_and_ioremap_resource() to simplify code. -BTW convert to use dev_err_probe() instead of open it. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/qfprom.c | 17 +++++------------ - 1 file changed, 5 insertions(+), 12 deletions(-) - ---- a/drivers/nvmem/qfprom.c -+++ b/drivers/nvmem/qfprom.c -@@ -374,8 +374,7 @@ static int qfprom_probe(struct platform_ - return -ENOMEM; - - /* The corrected section is always provided */ -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->qfpcorrected = devm_ioremap_resource(dev, res); -+ priv->qfpcorrected = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(priv->qfpcorrected)) - return PTR_ERR(priv->qfpcorrected); - -@@ -402,12 +401,10 @@ static int qfprom_probe(struct platform_ - priv->qfpraw = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->qfpraw)) - return PTR_ERR(priv->qfpraw); -- res = platform_get_resource(pdev, IORESOURCE_MEM, 2); -- priv->qfpconf = devm_ioremap_resource(dev, res); -+ priv->qfpconf = devm_platform_ioremap_resource(pdev, 2); - if (IS_ERR(priv->qfpconf)) - return PTR_ERR(priv->qfpconf); -- res = platform_get_resource(pdev, IORESOURCE_MEM, 3); -- priv->qfpsecurity = devm_ioremap_resource(dev, res); -+ priv->qfpsecurity = devm_platform_ioremap_resource(pdev, 3); - if (IS_ERR(priv->qfpsecurity)) - return PTR_ERR(priv->qfpsecurity); - -@@ -427,12 +424,8 @@ static int qfprom_probe(struct platform_ - return PTR_ERR(priv->vcc); - - priv->secclk = devm_clk_get(dev, "core"); -- if (IS_ERR(priv->secclk)) { -- ret = PTR_ERR(priv->secclk); -- if (ret != -EPROBE_DEFER) -- dev_err(dev, "Error getting clock: %d\n", ret); -- return ret; -- } -+ if (IS_ERR(priv->secclk)) -+ return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n"); - - /* Only enable writing if we have SoC data. */ - if (priv->soc_data) diff --git a/target/linux/generic/backport-5.15/819-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch b/target/linux/generic/backport-5.15/819-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch deleted file mode 100644 index 3e328a4c99914b..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 6ac41c556e22a0d7d267c9b9d48681d73af4b368 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:31 +0100 -Subject: [PATCH] nvmem: uniphier: Use devm_platform_get_and_ioremap_resource() - -Convert platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/uniphier-efuse.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/uniphier-efuse.c -+++ b/drivers/nvmem/uniphier-efuse.c -@@ -41,8 +41,7 @@ static int uniphier_efuse_probe(struct p - if (!priv) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->base = devm_ioremap_resource(dev, res); -+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - diff --git a/target/linux/generic/backport-5.15/819-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch b/target/linux/generic/backport-5.15/819-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch deleted file mode 100644 index acbe18e270001f..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch +++ /dev/null @@ -1,133 +0,0 @@ -From c8efcf7a86ebf2ff48584d270b3070a7075bc345 Mon Sep 17 00:00:00 2001 -From: Richard Alpe -Date: Mon, 10 Apr 2023 10:20:51 +0200 -Subject: [PATCH] nvmem: add new NXP QorIQ eFuse driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add SFP (Security Fuse Processor) read support for NXP (Freescale) -QorIQ series SOC's. - -This patch adds support for the T1023 SOC using the SFP offset from -the existing T1023 device tree. In theory this should also work for -T1024, T1014 and T1013 which uses the same SFP base offset. - -Signed-off-by: Richard Alpe -Reviewed-by: Niklas Söderlund -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/Kconfig | 12 ++++++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/qoriq-efuse.c | 78 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 92 insertions(+) - create mode 100644 drivers/nvmem/qoriq-efuse.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -392,4 +392,16 @@ config NVMEM_ZYNQMP - - If sure, say yes. If unsure, say no. - -+config NVMEM_QORIQ_EFUSE -+ tristate "NXP QorIQ eFuse support" -+ depends on PPC_85xx || COMPILE_TEST -+ depends on HAS_IOMEM -+ help -+ This driver provides read support for the eFuses (SFP) on NXP QorIQ -+ series SoC's. This includes secure boot settings, the globally unique -+ NXP ID 'FUIDR' and the OEM unique ID 'OUIDR'. -+ -+ This driver can also be built as a module. If so, the module -+ will be called nvmem_qoriq_efuse. -+ - endif ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -77,3 +77,5 @@ obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvme - nvmem-vf610-ocotp-y := vf610-ocotp.o - obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o - nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o -+obj-$(CONFIG_NVMEM_QORIQ_EFUSE) += nvmem-qoriq-efuse.o -+nvmem-qoriq-efuse-y := qoriq-efuse.o ---- /dev/null -+++ b/drivers/nvmem/qoriq-efuse.c -@@ -0,0 +1,78 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2023 Westermo Network Technologies AB -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct qoriq_efuse_priv { -+ void __iomem *base; -+}; -+ -+static int qoriq_efuse_read(void *context, unsigned int offset, void *val, -+ size_t bytes) -+{ -+ struct qoriq_efuse_priv *priv = context; -+ -+ /* .stride = 4 so offset is guaranteed to be aligned */ -+ __ioread32_copy(val, priv->base + offset, bytes / 4); -+ -+ /* Ignore trailing bytes (there shouldn't be any) */ -+ -+ return 0; -+} -+ -+static int qoriq_efuse_probe(struct platform_device *pdev) -+{ -+ struct nvmem_config config = { -+ .dev = &pdev->dev, -+ .read_only = true, -+ .reg_read = qoriq_efuse_read, -+ .stride = sizeof(u32), -+ .word_size = sizeof(u32), -+ .name = "qoriq_efuse_read", -+ .id = NVMEM_DEVID_AUTO, -+ .root_only = true, -+ }; -+ struct qoriq_efuse_priv *priv; -+ struct nvmem_device *nvmem; -+ struct resource *res; -+ -+ priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); -+ if (IS_ERR(priv->base)) -+ return PTR_ERR(priv->base); -+ -+ config.size = resource_size(res); -+ config.priv = priv; -+ nvmem = devm_nvmem_register(config.dev, &config); -+ -+ return PTR_ERR_OR_ZERO(nvmem); -+} -+ -+static const struct of_device_id qoriq_efuse_of_match[] = { -+ { .compatible = "fsl,t1023-sfp", }, -+ {/* sentinel */}, -+}; -+MODULE_DEVICE_TABLE(of, qoriq_efuse_of_match); -+ -+static struct platform_driver qoriq_efuse_driver = { -+ .probe = qoriq_efuse_probe, -+ .driver = { -+ .name = "qoriq-efuse", -+ .of_match_table = qoriq_efuse_of_match, -+ }, -+}; -+module_platform_driver(qoriq_efuse_driver); -+ -+MODULE_AUTHOR("Richard Alpe "); -+MODULE_DESCRIPTION("NXP QorIQ Security Fuse Processor (SFP) Reader"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-5.15/819-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch b/target/linux/generic/backport-5.15/819-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch deleted file mode 100644 index 67f30e34a2346f..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 9d53d595f688c9837e88a919229cc61a165c7b9e Mon Sep 17 00:00:00 2001 -From: Diederik de Haas -Date: Mon, 24 Jul 2023 13:36:22 +0200 -Subject: [PATCH] nvmem: Kconfig: Fix typo "drive" -> "driver" - -Fix typo where "driver" was meant instead of "drive". -While at it, also capitalize "OTP". - -Signed-off-by: Diederik de Haas -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/Kconfig | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -247,7 +247,7 @@ config NVMEM_ROCKCHIP_EFUSE - depends on ARCH_ROCKCHIP || COMPILE_TEST - depends on HAS_IOMEM - help -- This is a simple drive to dump specified values of Rockchip SoC -+ This is a simple driver to dump specified values of Rockchip SoC - from eFuse, such as cpu-leakage. - - This driver can also be built as a module. If so, the module -@@ -258,8 +258,8 @@ config NVMEM_ROCKCHIP_OTP - depends on ARCH_ROCKCHIP || COMPILE_TEST - depends on HAS_IOMEM - help -- This is a simple drive to dump specified values of Rockchip SoC -- from otp, such as cpu-leakage. -+ This is a simple driver to dump specified values of Rockchip SoC -+ from OTP, such as cpu-leakage. - - This driver can also be built as a module. If so, the module - will be called nvmem_rockchip_otp. diff --git a/target/linux/generic/backport-5.15/819-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch b/target/linux/generic/backport-5.15/819-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch deleted file mode 100644 index d24a624ddfa75a..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0a9ec38c47c1ca4528aa058e2b9ea61901a7e632 Mon Sep 17 00:00:00 2001 -From: Komal Bajaj -Date: Tue, 1 Aug 2023 12:10:25 +0530 -Subject: [PATCH] nvmem: sec-qfprom: Add Qualcomm secure QFPROM support - -For some of the Qualcomm SoC's, it is possible that -some of the fuse regions or entire qfprom region is -protected from non-secure access. In such situations, -the OS will have to use secure calls to read the region. -With that motivation, add secure qfprom driver. - -Signed-off-by: Komal Bajaj -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/Kconfig | 13 ++++++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/sec-qfprom.c | 96 ++++++++++++++++++++++++++++++++++++++ - 3 files changed, 111 insertions(+) - create mode 100644 drivers/nvmem/sec-qfprom.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -226,6 +226,19 @@ config NVMEM_QCOM_QFPROM - This driver can also be built as a module. If so, the module - will be called nvmem_qfprom. - -+config NVMEM_QCOM_SEC_QFPROM -+ tristate "QCOM SECURE QFPROM Support" -+ depends on ARCH_QCOM || COMPILE_TEST -+ depends on HAS_IOMEM -+ depends on OF -+ select QCOM_SCM -+ help -+ Say y here to enable secure QFPROM support. The secure QFPROM provides access -+ functions for QFPROM data to rest of the drivers via nvmem interface. -+ -+ This driver can also be built as a module. If so, the module will be called -+ nvmem_sec_qfprom. -+ - config NVMEM_RAVE_SP_EEPROM - tristate "Rave SP EEPROM Support" - depends on RAVE_SP_CORE ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -46,6 +46,8 @@ obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvme - nvmem-nintendo-otp-y := nintendo-otp.o - obj-$(CONFIG_NVMEM_QCOM_QFPROM) += nvmem_qfprom.o - nvmem_qfprom-y := qfprom.o -+obj-$(CONFIG_NVMEM_QCOM_SEC_QFPROM) += nvmem_sec_qfprom.o -+nvmem_sec_qfprom-y := sec-qfprom.o - obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o - nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o - obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o ---- /dev/null -+++ b/drivers/nvmem/sec-qfprom.c -@@ -0,0 +1,96 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * struct sec_qfprom - structure holding secure qfprom attributes -+ * -+ * @base: starting physical address for secure qfprom corrected address space. -+ * @dev: qfprom device structure. -+ */ -+struct sec_qfprom { -+ phys_addr_t base; -+ struct device *dev; -+}; -+ -+static int sec_qfprom_reg_read(void *context, unsigned int reg, void *_val, size_t bytes) -+{ -+ struct sec_qfprom *priv = context; -+ unsigned int i; -+ u8 *val = _val; -+ u32 read_val; -+ u8 *tmp; -+ -+ for (i = 0; i < bytes; i++, reg++) { -+ if (i == 0 || reg % 4 == 0) { -+ if (qcom_scm_io_readl(priv->base + (reg & ~3), &read_val)) { -+ dev_err(priv->dev, "Couldn't access fuse register\n"); -+ return -EINVAL; -+ } -+ tmp = (u8 *)&read_val; -+ } -+ -+ val[i] = tmp[reg & 3]; -+ } -+ -+ return 0; -+} -+ -+static int sec_qfprom_probe(struct platform_device *pdev) -+{ -+ struct nvmem_config econfig = { -+ .name = "sec-qfprom", -+ .stride = 1, -+ .word_size = 1, -+ .id = NVMEM_DEVID_AUTO, -+ .reg_read = sec_qfprom_reg_read, -+ }; -+ struct device *dev = &pdev->dev; -+ struct nvmem_device *nvmem; -+ struct sec_qfprom *priv; -+ struct resource *res; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -EINVAL; -+ -+ priv->base = res->start; -+ -+ econfig.size = resource_size(res); -+ econfig.dev = dev; -+ econfig.priv = priv; -+ -+ priv->dev = dev; -+ -+ nvmem = devm_nvmem_register(dev, &econfig); -+ -+ return PTR_ERR_OR_ZERO(nvmem); -+} -+ -+static const struct of_device_id sec_qfprom_of_match[] = { -+ { .compatible = "qcom,sec-qfprom" }, -+ {/* sentinel */}, -+}; -+MODULE_DEVICE_TABLE(of, sec_qfprom_of_match); -+ -+static struct platform_driver qfprom_driver = { -+ .probe = sec_qfprom_probe, -+ .driver = { -+ .name = "qcom_sec_qfprom", -+ .of_match_table = sec_qfprom_of_match, -+ }, -+}; -+module_platform_driver(qfprom_driver); -+MODULE_DESCRIPTION("Qualcomm Secure QFPROM driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-5.15/819-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch b/target/linux/generic/backport-5.15/819-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch deleted file mode 100644 index dab8ec2c241dfe..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch +++ /dev/null @@ -1,30 +0,0 @@ -From c32f2186acc9abb4d766361255d7ddf07d15eeb2 Mon Sep 17 00:00:00 2001 -From: Atul Raut -Date: Sun, 30 Jul 2023 15:39:15 -0700 -Subject: [PATCH] nvmem: u-boot-env:: Replace zero-length array with - DECLARE_FLEX_ARRAY() helper - -We are moving toward replacing zero-length arrays with C99 flexible-array -members since they are deprecated. Therefore, the new DECLARE_FLEX_ARRAY() -helper macro should be used to replace the zero-length array declaration. - -This fixes warnings such as: -./drivers/nvmem/u-boot-env.c:50:9-13: WARNING use flexible-array member instead (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays) - -Signed-off-by: Atul Raut -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/u-boot-env.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -47,7 +47,7 @@ struct u_boot_env_image_broadcom { - __le32 magic; - __le32 len; - __le32 crc32; -- uint8_t data[0]; -+ DECLARE_FLEX_ARRAY(uint8_t, data); - } __packed; - - static int u_boot_env_read(void *context, unsigned int offset, void *val, diff --git a/target/linux/generic/backport-5.15/819-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch b/target/linux/generic/backport-5.15/819-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch deleted file mode 100644 index f9532f39c35bac..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 104af6a5b199eb4dc7970d1304aef38ac5a6ed54 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 8 Aug 2023 08:29:26 +0200 -Subject: [PATCH] nvmem: core: Create all cells before adding the nvmem device - -Let's pack all the cells creation in one place, so they are all created -before we add the nvmem device. - -Signed-off-by: Miquel Raynal -Reviewed-by: Michael Walle -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/core.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -998,17 +998,17 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -- dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); -- -- rval = device_add(&nvmem->dev); -+ rval = nvmem_add_cells_from_fixed_layout(nvmem); - if (rval) - goto err_remove_cells; - -- rval = nvmem_add_cells_from_fixed_layout(nvmem); -+ rval = nvmem_add_cells_from_layout(nvmem); - if (rval) - goto err_remove_cells; - -- rval = nvmem_add_cells_from_layout(nvmem); -+ dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); -+ -+ rval = device_add(&nvmem->dev); - if (rval) - goto err_remove_cells; - diff --git a/target/linux/generic/backport-5.15/819-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch b/target/linux/generic/backport-5.15/819-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch deleted file mode 100644 index 8f64d0c28b8599..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6c7f48ea2e663b679aa8e60d8d8e1e6306a644f9 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 8 Aug 2023 08:29:27 +0200 -Subject: [PATCH] nvmem: core: Return NULL when no nvmem layout is found - -Currently, of_nvmem_layout_get_container() returns NULL on error, or an -error pointer if either CONFIG_NVMEM or CONFIG_OF is turned off. We -should likely avoid this kind of mix for two reasons: to clarify the -intend and anyway fix the !CONFIG_OF which will likely always if we use -this helper somewhere else. Let's just return NULL when no layout is -found, we don't need an error value here. - -Link: https://staticthinking.wordpress.com/2022/08/01/mixing-error-pointers-and-null/ -Fixes: 266570f496b9 ("nvmem: core: introduce NVMEM layouts") -Reported-by: kernel test robot -Reported-by: Dan Carpenter -Closes: https://lore.kernel.org/r/202308030002.DnSFOrMB-lkp@intel.com/ -Signed-off-by: Miquel Raynal -Reviewed-by: Michael Walle -Signed-off-by: Srinivas Kandagatla ---- - include/linux/nvmem-consumer.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -256,7 +256,7 @@ static inline struct nvmem_device *of_nv - static inline struct device_node * - of_nvmem_layout_get_container(struct nvmem_device *nvmem) - { -- return ERR_PTR(-EOPNOTSUPP); -+ return NULL; - } - #endif /* CONFIG_NVMEM && CONFIG_OF */ - diff --git a/target/linux/generic/backport-5.15/819-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch b/target/linux/generic/backport-5.15/819-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch deleted file mode 100644 index 28d8bba1949adf..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch +++ /dev/null @@ -1,29 +0,0 @@ -From b8257f61b4ddac6d7d0e19a5a4e8b07afb3b4ed3 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 8 Aug 2023 08:29:28 +0200 -Subject: [PATCH] nvmem: core: Do not open-code existing functions - -Use of_nvmem_layout_get_container() instead of hardcoding it. - -Signed-off-by: Miquel Raynal -Reviewed-by: Michael Walle -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/core.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -786,10 +786,10 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste - - static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) - { -- struct device_node *layout_np, *np = nvmem->dev.of_node; -+ struct device_node *layout_np; - struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER); - -- layout_np = of_get_child_by_name(np, "nvmem-layout"); -+ layout_np = of_nvmem_layout_get_container(nvmem); - if (!layout_np) - return NULL; - diff --git a/target/linux/generic/backport-5.15/819-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch b/target/linux/generic/backport-5.15/819-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch deleted file mode 100644 index b62a0e18daa74b..00000000000000 --- a/target/linux/generic/backport-5.15/819-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0991afbe4b1805e7f0113ef10d7c5f0698a739e4 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 8 Aug 2023 08:29:29 +0200 -Subject: [PATCH] nvmem: core: Notify when a new layout is registered - -Tell listeners a new layout was introduced and is now available. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/core.c | 4 ++++ - include/linux/nvmem-consumer.h | 2 ++ - 2 files changed, 6 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -772,12 +772,16 @@ int __nvmem_layout_register(struct nvmem - list_add(&layout->node, &nvmem_layouts); - spin_unlock(&nvmem_layout_lock); - -+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_ADD, layout); -+ - return 0; - } - EXPORT_SYMBOL_GPL(__nvmem_layout_register); - - void nvmem_layout_unregister(struct nvmem_layout *layout) - { -+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_REMOVE, layout); -+ - spin_lock(&nvmem_layout_lock); - list_del(&layout->node); - spin_unlock(&nvmem_layout_lock); ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -43,6 +43,8 @@ enum { - NVMEM_REMOVE, - NVMEM_CELL_ADD, - NVMEM_CELL_REMOVE, -+ NVMEM_LAYOUT_ADD, -+ NVMEM_LAYOUT_REMOVE, - }; - - #if IS_ENABLED(CONFIG_NVMEM) diff --git a/target/linux/generic/backport-5.15/820-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch b/target/linux/generic/backport-5.15/820-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch deleted file mode 100644 index 66d402814057c4..00000000000000 --- a/target/linux/generic/backport-5.15/820-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 16724d6ea40a2c9315f5a0d81005dfa4d7a6da24 Mon Sep 17 00:00:00 2001 -From: Luca Weiss -Date: Fri, 20 Oct 2023 11:55:40 +0100 -Subject: [PATCH] nvmem: qfprom: Mark core clk as optional - -On some platforms like sc7280 on non-ChromeOS devices the core clock -cannot be touched by Linux so we cannot provide it. Mark it as optional -as accessing qfprom for reading works without it but we still prohibit -writing if we cannot provide the clock. - -Signed-off-by: Luca Weiss -Reviewed-by: Douglas Anderson -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231020105545.216052-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/qfprom.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/qfprom.c -+++ b/drivers/nvmem/qfprom.c -@@ -423,12 +423,12 @@ static int qfprom_probe(struct platform_ - if (IS_ERR(priv->vcc)) - return PTR_ERR(priv->vcc); - -- priv->secclk = devm_clk_get(dev, "core"); -+ priv->secclk = devm_clk_get_optional(dev, "core"); - if (IS_ERR(priv->secclk)) - return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n"); - -- /* Only enable writing if we have SoC data. */ -- if (priv->soc_data) -+ /* Only enable writing if we have SoC data and a valid clock */ -+ if (priv->soc_data && priv->secclk) - econfig.reg_write = qfprom_reg_write; - } - diff --git a/target/linux/generic/backport-5.15/820-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch b/target/linux/generic/backport-5.15/820-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch deleted file mode 100644 index 9ce78e1f09d336..00000000000000 --- a/target/linux/generic/backport-5.15/820-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 2cc3b37f5b6df8189d55d0e812d9658ce256dfec Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 20 Oct 2023 11:55:41 +0100 -Subject: [PATCH] nvmem: add explicit config option to read old syntax fixed OF - cells -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Binding for fixed NVMEM cells defined directly as NVMEM device subnodes -has been deprecated. It has been replaced by the "fixed-layout" NVMEM -layout binding. - -New syntax is meant to be clearer and should help avoiding imprecise -bindings. - -NVMEM subsystem already supports the new binding. It should be a good -idea to limit support for old syntax to existing drivers that actually -support & use it (we can't break backward compatibility!). That way we -additionally encourage new bindings & drivers to ignore deprecated -binding. - -It wasn't clear (to me) if rtc and w1 code actually uses old syntax -fixed cells. I enabled them to don't risk any breakage. - -Signed-off-by: Rafał Miłecki -[for meson-{efuse,mx-efuse}.c] -Acked-by: Martin Blumenstingl -[for mtk-efuse.c, nvmem/core.c, nvmem-provider.h] -Reviewed-by: AngeloGioacchino Del Regno -[MT8192, MT8195 Chromebooks] -Tested-by: AngeloGioacchino Del Regno -[for microchip-otpc.c] -Reviewed-by: Claudiu Beznea -[SAMA7G5-EK] -Tested-by: Claudiu Beznea -Acked-by: Jernej Skrabec -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231020105545.216052-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/mtd/mtdcore.c | 2 ++ - drivers/nvmem/apple-efuses.c | 1 + - drivers/nvmem/core.c | 8 +++++--- - drivers/nvmem/imx-ocotp-scu.c | 1 + - drivers/nvmem/imx-ocotp.c | 1 + - drivers/nvmem/meson-efuse.c | 1 + - drivers/nvmem/meson-mx-efuse.c | 1 + - drivers/nvmem/microchip-otpc.c | 1 + - drivers/nvmem/mtk-efuse.c | 1 + - drivers/nvmem/qcom-spmi-sdam.c | 1 + - drivers/nvmem/qfprom.c | 1 + - drivers/nvmem/rave-sp-eeprom.c | 1 + - drivers/nvmem/rockchip-efuse.c | 1 + - drivers/nvmem/sc27xx-efuse.c | 1 + - drivers/nvmem/sec-qfprom.c | 1 + - drivers/nvmem/sprd-efuse.c | 1 + - drivers/nvmem/stm32-romem.c | 1 + - drivers/nvmem/sunplus-ocotp.c | 1 + - drivers/nvmem/sunxi_sid.c | 1 + - drivers/nvmem/uniphier-efuse.c | 1 + - drivers/nvmem/zynqmp_nvmem.c | 1 + - drivers/rtc/nvmem.c | 1 + - drivers/w1/slaves/w1_ds250x.c | 1 + - include/linux/nvmem-provider.h | 2 ++ - 24 files changed, 30 insertions(+), 3 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -541,6 +541,7 @@ static int mtd_nvmem_add(struct mtd_info - config.dev = &mtd->dev; - config.name = dev_name(&mtd->dev); - config.owner = THIS_MODULE; -+ config.add_legacy_fixed_of_cells = of_device_is_compatible(node, "nvmem-cells"); - config.reg_read = mtd_nvmem_reg_read; - config.size = mtd->size; - config.word_size = 1; -@@ -898,6 +899,7 @@ static struct nvmem_device *mtd_otp_nvme - config.name = compatible; - config.id = NVMEM_DEVID_AUTO; - config.owner = THIS_MODULE; -+ config.add_legacy_fixed_of_cells = true; - config.type = NVMEM_TYPE_OTP; - config.root_only = true; - config.ignore_wp = true; ---- a/drivers/nvmem/apple-efuses.c -+++ b/drivers/nvmem/apple-efuses.c -@@ -36,6 +36,7 @@ static int apple_efuses_probe(struct pla - struct resource *res; - struct nvmem_config config = { - .dev = &pdev->dev, -+ .add_legacy_fixed_of_cells = true, - .read_only = true, - .reg_read = apple_efuses_read, - .stride = sizeof(u32), ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -998,9 +998,11 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -- rval = nvmem_add_cells_from_legacy_of(nvmem); -- if (rval) -- goto err_remove_cells; -+ if (config->add_legacy_fixed_of_cells) { -+ rval = nvmem_add_cells_from_legacy_of(nvmem); -+ if (rval) -+ goto err_remove_cells; -+ } - - rval = nvmem_add_cells_from_fixed_layout(nvmem); - if (rval) ---- a/drivers/nvmem/imx-ocotp-scu.c -+++ b/drivers/nvmem/imx-ocotp-scu.c -@@ -220,6 +220,7 @@ static int imx_scu_ocotp_write(void *con - - static struct nvmem_config imx_scu_ocotp_nvmem_config = { - .name = "imx-scu-ocotp", -+ .add_legacy_fixed_of_cells = true, - .read_only = false, - .word_size = 4, - .stride = 1, ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -616,6 +616,7 @@ static int imx_ocotp_probe(struct platfo - return PTR_ERR(priv->clk); - - priv->params = of_device_get_match_data(&pdev->dev); -+ imx_ocotp_nvmem_config.add_legacy_fixed_of_cells = true; - imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; - imx_ocotp_nvmem_config.dev = dev; - imx_ocotp_nvmem_config.priv = priv; ---- a/drivers/nvmem/meson-efuse.c -+++ b/drivers/nvmem/meson-efuse.c -@@ -74,6 +74,7 @@ static int meson_efuse_probe(struct plat - - econfig->dev = dev; - econfig->name = dev_name(dev); -+ econfig->add_legacy_fixed_of_cells = true; - econfig->stride = 1; - econfig->word_size = 1; - econfig->reg_read = meson_efuse_read; ---- a/drivers/nvmem/meson-mx-efuse.c -+++ b/drivers/nvmem/meson-mx-efuse.c -@@ -211,6 +211,7 @@ static int meson_mx_efuse_probe(struct p - efuse->config.owner = THIS_MODULE; - efuse->config.dev = &pdev->dev; - efuse->config.priv = efuse; -+ efuse->config.add_legacy_fixed_of_cells = true; - efuse->config.stride = drvdata->word_size; - efuse->config.word_size = drvdata->word_size; - efuse->config.size = SZ_512; ---- a/drivers/nvmem/microchip-otpc.c -+++ b/drivers/nvmem/microchip-otpc.c -@@ -261,6 +261,7 @@ static int mchp_otpc_probe(struct platfo - return ret; - - mchp_nvmem_config.dev = otpc->dev; -+ mchp_nvmem_config.add_legacy_fixed_of_cells = true; - mchp_nvmem_config.size = size; - mchp_nvmem_config.priv = otpc; - nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config); ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -83,6 +83,7 @@ static int mtk_efuse_probe(struct platfo - return PTR_ERR(priv->base); - - pdata = device_get_match_data(dev); -+ econfig.add_legacy_fixed_of_cells = true; - econfig.stride = 1; - econfig.word_size = 1; - econfig.reg_read = mtk_reg_read; ---- a/drivers/nvmem/qcom-spmi-sdam.c -+++ b/drivers/nvmem/qcom-spmi-sdam.c -@@ -142,6 +142,7 @@ static int sdam_probe(struct platform_de - sdam->sdam_config.name = "spmi_sdam"; - sdam->sdam_config.id = NVMEM_DEVID_AUTO; - sdam->sdam_config.owner = THIS_MODULE; -+ sdam->sdam_config.add_legacy_fixed_of_cells = true; - sdam->sdam_config.stride = 1; - sdam->sdam_config.word_size = 1; - sdam->sdam_config.reg_read = sdam_read; ---- a/drivers/nvmem/qfprom.c -+++ b/drivers/nvmem/qfprom.c -@@ -357,6 +357,7 @@ static int qfprom_probe(struct platform_ - { - struct nvmem_config econfig = { - .name = "qfprom", -+ .add_legacy_fixed_of_cells = true, - .stride = 1, - .word_size = 1, - .id = NVMEM_DEVID_AUTO, ---- a/drivers/nvmem/rave-sp-eeprom.c -+++ b/drivers/nvmem/rave-sp-eeprom.c -@@ -328,6 +328,7 @@ static int rave_sp_eeprom_probe(struct p - of_property_read_string(np, "zii,eeprom-name", &config.name); - config.priv = eeprom; - config.dev = dev; -+ config.add_legacy_fixed_of_cells = true; - config.size = size; - config.reg_read = rave_sp_eeprom_reg_read; - config.reg_write = rave_sp_eeprom_reg_write; ---- a/drivers/nvmem/rockchip-efuse.c -+++ b/drivers/nvmem/rockchip-efuse.c -@@ -205,6 +205,7 @@ static int rockchip_rk3399_efuse_read(vo - - static struct nvmem_config econfig = { - .name = "rockchip-efuse", -+ .add_legacy_fixed_of_cells = true, - .stride = 1, - .word_size = 1, - .read_only = true, ---- a/drivers/nvmem/sc27xx-efuse.c -+++ b/drivers/nvmem/sc27xx-efuse.c -@@ -248,6 +248,7 @@ static int sc27xx_efuse_probe(struct pla - econfig.reg_read = sc27xx_efuse_read; - econfig.priv = efuse; - econfig.dev = &pdev->dev; -+ econfig.add_legacy_fixed_of_cells = true; - nvmem = devm_nvmem_register(&pdev->dev, &econfig); - if (IS_ERR(nvmem)) { - dev_err(&pdev->dev, "failed to register nvmem config\n"); ---- a/drivers/nvmem/sec-qfprom.c -+++ b/drivers/nvmem/sec-qfprom.c -@@ -47,6 +47,7 @@ static int sec_qfprom_probe(struct platf - { - struct nvmem_config econfig = { - .name = "sec-qfprom", -+ .add_legacy_fixed_of_cells = true, - .stride = 1, - .word_size = 1, - .id = NVMEM_DEVID_AUTO, ---- a/drivers/nvmem/sprd-efuse.c -+++ b/drivers/nvmem/sprd-efuse.c -@@ -408,6 +408,7 @@ static int sprd_efuse_probe(struct platf - econfig.read_only = false; - econfig.name = "sprd-efuse"; - econfig.size = efuse->data->blk_nums * SPRD_EFUSE_BLOCK_WIDTH; -+ econfig.add_legacy_fixed_of_cells = true; - econfig.reg_read = sprd_efuse_read; - econfig.reg_write = sprd_efuse_write; - econfig.priv = efuse; ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -207,6 +207,7 @@ static int stm32_romem_probe(struct plat - priv->cfg.priv = priv; - priv->cfg.owner = THIS_MODULE; - priv->cfg.type = NVMEM_TYPE_OTP; -+ priv->cfg.add_legacy_fixed_of_cells = true; - - priv->lower = 0; - ---- a/drivers/nvmem/sunplus-ocotp.c -+++ b/drivers/nvmem/sunplus-ocotp.c -@@ -145,6 +145,7 @@ disable_clk: - - static struct nvmem_config sp_ocotp_nvmem_config = { - .name = "sp-ocotp", -+ .add_legacy_fixed_of_cells = true, - .read_only = true, - .word_size = 1, - .size = QAC628_OTP_SIZE, ---- a/drivers/nvmem/sunxi_sid.c -+++ b/drivers/nvmem/sunxi_sid.c -@@ -154,6 +154,7 @@ static int sunxi_sid_probe(struct platfo - nvmem_cfg->dev = dev; - nvmem_cfg->name = "sunxi-sid"; - nvmem_cfg->type = NVMEM_TYPE_OTP; -+ nvmem_cfg->add_legacy_fixed_of_cells = true; - nvmem_cfg->read_only = true; - nvmem_cfg->size = cfg->size; - nvmem_cfg->word_size = 1; ---- a/drivers/nvmem/uniphier-efuse.c -+++ b/drivers/nvmem/uniphier-efuse.c -@@ -52,6 +52,7 @@ static int uniphier_efuse_probe(struct p - econfig.size = resource_size(res); - econfig.priv = priv; - econfig.dev = dev; -+ econfig.add_legacy_fixed_of_cells = true; - nvmem = devm_nvmem_register(dev, &econfig); - - return PTR_ERR_OR_ZERO(nvmem); ---- a/drivers/nvmem/zynqmp_nvmem.c -+++ b/drivers/nvmem/zynqmp_nvmem.c -@@ -58,6 +58,7 @@ static int zynqmp_nvmem_probe(struct pla - - priv->dev = dev; - econfig.dev = dev; -+ econfig.add_legacy_fixed_of_cells = true; - econfig.reg_read = zynqmp_nvmem_read; - econfig.priv = priv; - ---- a/drivers/rtc/nvmem.c -+++ b/drivers/rtc/nvmem.c -@@ -21,6 +21,7 @@ int devm_rtc_nvmem_register(struct rtc_d - - nvmem_config->dev = dev; - nvmem_config->owner = rtc->owner; -+ nvmem_config->add_legacy_fixed_of_cells = true; - nvmem = devm_nvmem_register(dev, nvmem_config); - if (IS_ERR(nvmem)) - dev_err(dev, "failed to register nvmem device for RTC\n"); ---- a/drivers/w1/slaves/w1_ds250x.c -+++ b/drivers/w1/slaves/w1_ds250x.c -@@ -168,6 +168,7 @@ static int w1_eprom_add_slave(struct w1_ - struct nvmem_device *nvmem; - struct nvmem_config nvmem_cfg = { - .dev = &sl->dev, -+ .add_legacy_fixed_of_cells = true, - .reg_read = w1_nvmem_read, - .type = NVMEM_TYPE_OTP, - .read_only = true, ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -82,6 +82,7 @@ struct nvmem_cell_info { - * @owner: Pointer to exporter module. Used for refcounting. - * @cells: Optional array of pre-defined NVMEM cells. - * @ncells: Number of elements in cells. -+ * @add_legacy_fixed_of_cells: Read fixed NVMEM cells from old OF syntax. - * @keepout: Optional array of keepout ranges (sorted ascending by start). - * @nkeepout: Number of elements in the keepout array. - * @type: Type of the nvmem storage -@@ -112,6 +113,7 @@ struct nvmem_config { - struct module *owner; - const struct nvmem_cell_info *cells; - int ncells; -+ bool add_legacy_fixed_of_cells; - const struct nvmem_keepout *keepout; - unsigned int nkeepout; - enum nvmem_type type; diff --git a/target/linux/generic/backport-5.15/820-v6.7-0003-nvmem-Use-device_get_match_data.patch b/target/linux/generic/backport-5.15/820-v6.7-0003-nvmem-Use-device_get_match_data.patch deleted file mode 100644 index 84c0293982459f..00000000000000 --- a/target/linux/generic/backport-5.15/820-v6.7-0003-nvmem-Use-device_get_match_data.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0720219f4d34a88a9badb4de70cfad7585687d48 Mon Sep 17 00:00:00 2001 -From: Rob Herring -Date: Fri, 20 Oct 2023 11:55:45 +0100 -Subject: [PATCH] nvmem: Use device_get_match_data() - -Use preferred device_get_match_data() instead of of_match_device() to -get the driver match data. With this, adjust the includes to explicitly -include the correct headers. - -Signed-off-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231020105545.216052-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/mxs-ocotp.c | 10 ++++------ - drivers/nvmem/stm32-romem.c | 7 ++++--- - 2 files changed, 8 insertions(+), 9 deletions(-) - ---- a/drivers/nvmem/mxs-ocotp.c -+++ b/drivers/nvmem/mxs-ocotp.c -@@ -13,8 +13,9 @@ - #include - #include - #include --#include -+#include - #include -+#include - #include - #include - -@@ -140,11 +141,10 @@ static int mxs_ocotp_probe(struct platfo - struct device *dev = &pdev->dev; - const struct mxs_data *data; - struct mxs_ocotp *otp; -- const struct of_device_id *match; - int ret; - -- match = of_match_device(dev->driver->of_match_table, dev); -- if (!match || !match->data) -+ data = device_get_match_data(dev); -+ if (!data) - return -EINVAL; - - otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL); -@@ -169,8 +169,6 @@ static int mxs_ocotp_probe(struct platfo - if (ret) - return ret; - -- data = match->data; -- - ocotp_config.size = data->size; - ocotp_config.priv = otp; - ocotp_config.dev = dev; ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -10,7 +10,9 @@ - #include - #include - #include --#include -+#include -+#include -+#include - #include - - #include "stm32-bsec-optee-ta.h" -@@ -211,8 +213,7 @@ static int stm32_romem_probe(struct plat - - priv->lower = 0; - -- cfg = (const struct stm32_romem_cfg *) -- of_match_device(dev->driver->of_match_table, dev)->data; -+ cfg = device_get_match_data(dev); - if (!cfg) { - priv->cfg.read_only = true; - priv->cfg.size = resource_size(res); diff --git a/target/linux/generic/backport-5.15/820-v6.7-0004-Revert-nvmem-add-new-config-option.patch b/target/linux/generic/backport-5.15/820-v6.7-0004-Revert-nvmem-add-new-config-option.patch deleted file mode 100644 index b23a23ef3affc0..00000000000000 --- a/target/linux/generic/backport-5.15/820-v6.7-0004-Revert-nvmem-add-new-config-option.patch +++ /dev/null @@ -1,77 +0,0 @@ -From f4cf4e5db331a5ce69e3f0b21d322cac0f4e4b5d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 23 Oct 2023 12:27:59 +0200 -Subject: [PATCH] Revert "nvmem: add new config option" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit 517f14d9cf3533d5ab4fded195ab6f80a92e378f. - -Config option "no_of_node" is no longer needed since adding a more -explicit and targeted option "add_legacy_fixed_of_cells". - -That "no_of_node" config option was needed *earlier* to help mtd's case. - -DT nodes of MTD partitions (that are also NVMEM devices) may contain -subnodes. Those SHOULD NOT be treated as NVMEM fixed cells. - -To prevent NVMEM core code from parsing subnodes a "no_of_node" option -was added (and set to true in mtd) to make for_each_child_of_node() in -NVMEM a no-op. That was a bit hacky because it was messing with -"of_node" pointer to achieve some side-effect. - -With the introduction of "add_legacy_fixed_of_cells" config option -things got more explicit. MTD subsystem simply tells NVMEM when to look -for fixed cells and there is no need to hack "of_node" pointer anymore. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231023102759.31529-1-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/mtd/mtdcore.c | 1 - - drivers/nvmem/core.c | 2 +- - include/linux/nvmem-provider.h | 2 -- - 3 files changed, 1 insertion(+), 4 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -549,7 +549,6 @@ static int mtd_nvmem_add(struct mtd_info - config.read_only = true; - config.root_only = true; - config.ignore_wp = true; -- config.no_of_node = !of_device_is_compatible(node, "nvmem-cells"); - config.priv = mtd; - - mtd->nvmem = nvmem_register(&config); ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -936,7 +936,7 @@ struct nvmem_device *nvmem_register(cons - nvmem->nkeepout = config->nkeepout; - if (config->of_node) - nvmem->dev.of_node = config->of_node; -- else if (!config->no_of_node) -+ else - nvmem->dev.of_node = config->dev->of_node; - - switch (config->id) { ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -89,7 +89,6 @@ struct nvmem_cell_info { - * @read_only: Device is read-only. - * @root_only: Device is accessibly to root only. - * @of_node: If given, this will be used instead of the parent's of_node. -- * @no_of_node: Device should not use the parent's of_node even if it's !NULL. - * @reg_read: Callback to read data. - * @reg_write: Callback to write data. - * @size: Device size. -@@ -122,7 +121,6 @@ struct nvmem_config { - bool ignore_wp; - struct nvmem_layout *layout; - struct device_node *of_node; -- bool no_of_node; - nvmem_reg_read_t reg_read; - nvmem_reg_write_t reg_write; - int size; diff --git a/target/linux/generic/backport-5.15/820-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch b/target/linux/generic/backport-5.15/820-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch deleted file mode 100644 index bd5ceaabf7d49e..00000000000000 --- a/target/linux/generic/backport-5.15/820-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch +++ /dev/null @@ -1,45 +0,0 @@ -From b7c1e53751cb3990153084f31c41f25fde3b629c Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 24 Nov 2023 20:38:14 +0100 -Subject: [PATCH] nvmem: Do not expect fixed layouts to grab a layout driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Two series lived in parallel for some time, which led to this situation: -- The nvmem-layout container is used for dynamic layouts -- We now expect fixed layouts to also use the nvmem-layout container but -this does not require any additional driver, the support is built-in the -nvmem core. - -Ensure we don't refuse to probe for wrong reasons. - -Fixes: 27f699e578b1 ("nvmem: core: add support for fixed cells *layout*") -Cc: stable@vger.kernel.org -Reported-by: Luca Ceresoli -Signed-off-by: Miquel Raynal -Tested-by: Rafał Miłecki -Tested-by: Luca Ceresoli -Reviewed-by: Luca Ceresoli - -Link: https://lore.kernel.org/r/20231124193814.360552-1-miquel.raynal@bootlin.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -797,6 +797,12 @@ static struct nvmem_layout *nvmem_layout - if (!layout_np) - return NULL; - -+ /* Fixed layouts don't have a matching driver */ -+ if (of_device_is_compatible(layout_np, "fixed-layout")) { -+ of_node_put(layout_np); -+ return NULL; -+ } -+ - /* - * In case the nvmem device was built-in while the layout was built as a - * module, we shall manually request the layout driver loading otherwise diff --git a/target/linux/generic/backport-5.15/820-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch b/target/linux/generic/backport-5.15/820-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch deleted file mode 100644 index d49a20599dc2b0..00000000000000 --- a/target/linux/generic/backport-5.15/820-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch +++ /dev/null @@ -1,261 +0,0 @@ -From 1e37bf84afacd5ba17b7a13a18ca2bc78aff05c0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 15 Dec 2023 11:13:58 +0000 -Subject: [PATCH] nvmem: brcm_nvram: store a copy of NVRAM content -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This driver uses MMIO access for reading NVRAM from a flash device. -Underneath there is a flash controller that reads data and provides -mapping window. - -Using MMIO interface affects controller configuration and may break real -controller driver. It was reported by multiple users of devices with -NVRAM stored on NAND. - -Modify driver to read & cache NVRAM content during init and use that -copy to provide NVMEM data when requested. On NAND flashes due to their -alignment NVRAM partitions can be quite big (1 MiB and more) while -actual NVRAM content stays quite small (usually 16 to 32 KiB). To avoid -allocating so much memory check for actual data length. - -Link: https://lore.kernel.org/linux-mtd/CACna6rwf3_9QVjYcM+847biTX=K0EoWXuXcSMkJO1Vy_5vmVqA@mail.gmail.com/ -Fixes: 3fef9ed0627a ("nvmem: brcm_nvram: new driver exposing Broadcom's NVRAM") -Cc: -Cc: Arınç ÜNAL -Cc: Florian Fainelli -Cc: Scott Branden -Signed-off-by: Rafał Miłecki -Acked-by: Arınç ÜNAL -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111358.316727-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/brcm_nvram.c | 134 ++++++++++++++++++++++++++----------- - 1 file changed, 94 insertions(+), 40 deletions(-) - ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -17,9 +17,23 @@ - - #define NVRAM_MAGIC "FLSH" - -+/** -+ * struct brcm_nvram - driver state internal struct -+ * -+ * @dev: NVMEM device pointer -+ * @nvmem_size: Size of the whole space available for NVRAM -+ * @data: NVRAM data copy stored to avoid poking underlaying flash controller -+ * @data_len: NVRAM data size -+ * @padding_byte: Padding value used to fill remaining space -+ * @cells: Array of discovered NVMEM cells -+ * @ncells: Number of elements in cells -+ */ - struct brcm_nvram { - struct device *dev; -- void __iomem *base; -+ size_t nvmem_size; -+ uint8_t *data; -+ size_t data_len; -+ uint8_t padding_byte; - struct nvmem_cell_info *cells; - int ncells; - }; -@@ -36,10 +50,47 @@ static int brcm_nvram_read(void *context - size_t bytes) - { - struct brcm_nvram *priv = context; -- u8 *dst = val; -+ size_t to_copy; -+ -+ if (offset + bytes > priv->data_len) -+ to_copy = max_t(ssize_t, (ssize_t)priv->data_len - offset, 0); -+ else -+ to_copy = bytes; -+ -+ memcpy(val, priv->data + offset, to_copy); -+ -+ memset((uint8_t *)val + to_copy, priv->padding_byte, bytes - to_copy); -+ -+ return 0; -+} -+ -+static int brcm_nvram_copy_data(struct brcm_nvram *priv, struct platform_device *pdev) -+{ -+ struct resource *res; -+ void __iomem *base; -+ -+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ priv->nvmem_size = resource_size(res); -+ -+ priv->padding_byte = readb(base + priv->nvmem_size - 1); -+ for (priv->data_len = priv->nvmem_size; -+ priv->data_len; -+ priv->data_len--) { -+ if (readb(base + priv->data_len - 1) != priv->padding_byte) -+ break; -+ } -+ WARN(priv->data_len > SZ_128K, "Unexpected (big) NVRAM size: %zu B\n", priv->data_len); - -- while (bytes--) -- *dst++ = readb(priv->base + offset++); -+ priv->data = devm_kzalloc(priv->dev, priv->data_len, GFP_KERNEL); -+ if (!priv->data) -+ return -ENOMEM; -+ -+ memcpy_fromio(priv->data, base, priv->data_len); -+ -+ bcm47xx_nvram_init_from_iomem(base, priv->data_len); - - return 0; - } -@@ -67,8 +118,13 @@ static int brcm_nvram_add_cells(struct b - size_t len) - { - struct device *dev = priv->dev; -- char *var, *value, *eq; -+ char *var, *value; -+ uint8_t tmp; - int idx; -+ int err = 0; -+ -+ tmp = priv->data[len - 1]; -+ priv->data[len - 1] = '\0'; - - priv->ncells = 0; - for (var = data + sizeof(struct brcm_nvram_header); -@@ -78,67 +134,68 @@ static int brcm_nvram_add_cells(struct b - } - - priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL); -- if (!priv->cells) -- return -ENOMEM; -+ if (!priv->cells) { -+ err = -ENOMEM; -+ goto out; -+ } - - for (var = data + sizeof(struct brcm_nvram_header), idx = 0; - var < (char *)data + len && *var; - var = value + strlen(value) + 1, idx++) { -+ char *eq, *name; -+ - eq = strchr(var, '='); - if (!eq) - break; - *eq = '\0'; -+ name = devm_kstrdup(dev, var, GFP_KERNEL); -+ *eq = '='; -+ if (!name) { -+ err = -ENOMEM; -+ goto out; -+ } - value = eq + 1; - -- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL); -- if (!priv->cells[idx].name) -- return -ENOMEM; -+ priv->cells[idx].name = name; - priv->cells[idx].offset = value - (char *)data; - priv->cells[idx].bytes = strlen(value); - priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); -- if (!strcmp(var, "et0macaddr") || -- !strcmp(var, "et1macaddr") || -- !strcmp(var, "et2macaddr")) { -+ if (!strcmp(name, "et0macaddr") || -+ !strcmp(name, "et1macaddr") || -+ !strcmp(name, "et2macaddr")) { - priv->cells[idx].raw_len = strlen(value); - priv->cells[idx].bytes = ETH_ALEN; - priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr; - } - } - -- return 0; -+out: -+ priv->data[len - 1] = tmp; -+ return err; - } - - static int brcm_nvram_parse(struct brcm_nvram *priv) - { -+ struct brcm_nvram_header *header = (struct brcm_nvram_header *)priv->data; - struct device *dev = priv->dev; -- struct brcm_nvram_header header; -- uint8_t *data; - size_t len; - int err; - -- memcpy_fromio(&header, priv->base, sizeof(header)); -- -- if (memcmp(header.magic, NVRAM_MAGIC, 4)) { -+ if (memcmp(header->magic, NVRAM_MAGIC, 4)) { - dev_err(dev, "Invalid NVRAM magic\n"); - return -EINVAL; - } - -- len = le32_to_cpu(header.len); -- -- data = kzalloc(len, GFP_KERNEL); -- if (!data) -- return -ENOMEM; -- -- memcpy_fromio(data, priv->base, len); -- data[len - 1] = '\0'; -- -- err = brcm_nvram_add_cells(priv, data, len); -- if (err) { -- dev_err(dev, "Failed to add cells: %d\n", err); -- return err; -+ len = le32_to_cpu(header->len); -+ if (len > priv->nvmem_size) { -+ dev_err(dev, "NVRAM length (%zd) exceeds mapped size (%zd)\n", len, -+ priv->nvmem_size); -+ return -EINVAL; - } - -- kfree(data); -+ err = brcm_nvram_add_cells(priv, priv->data, len); -+ if (err) -+ dev_err(dev, "Failed to add cells: %d\n", err); - - return 0; - } -@@ -150,7 +207,6 @@ static int brcm_nvram_probe(struct platf - .reg_read = brcm_nvram_read, - }; - struct device *dev = &pdev->dev; -- struct resource *res; - struct brcm_nvram *priv; - int err; - -@@ -159,21 +215,19 @@ static int brcm_nvram_probe(struct platf - return -ENOMEM; - priv->dev = dev; - -- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); -- if (IS_ERR(priv->base)) -- return PTR_ERR(priv->base); -+ err = brcm_nvram_copy_data(priv, pdev); -+ if (err) -+ return err; - - err = brcm_nvram_parse(priv); - if (err) - return err; - -- bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res)); -- - config.dev = dev; - config.cells = priv->cells; - config.ncells = priv->ncells; - config.priv = priv; -- config.size = resource_size(res); -+ config.size = priv->nvmem_size; - - return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config)); - } diff --git a/target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch b/target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch deleted file mode 100644 index 4a63b89f578692..00000000000000 --- a/target/linux/generic/backport-5.15/821-v5.16-Bluetooth-btusb-Support-public-address-configuration.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 5cb03751455c299b1bf10cb48631bf359cfb11b5 Mon Sep 17 00:00:00 2001 -From: "mark-yw.chen" -Date: Wed, 1 Sep 2021 11:32:25 +0800 -Subject: [PATCH 1/5] Bluetooth: btusb: Support public address configuration - for MediaTek Chip. - -The MediaTek chip support vendor specific HCI command(0xfc1a) to -change the public address. Add hdev->set_bdaddr handler for MediaTek -Chip. After doing a power cycle or MediaTek Bluetooth reset, BD_ADDR -will bring back the original one. - -Signed-off-by: mark-yw.chen -Signed-off-by: Marcel Holtmann ---- - drivers/bluetooth/btusb.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -2289,6 +2289,23 @@ struct btmtk_section_map { - }; - } __packed; - -+static int btusb_set_bdaddr_mtk(struct hci_dev *hdev, const bdaddr_t *bdaddr) -+{ -+ struct sk_buff *skb; -+ long ret; -+ -+ skb = __hci_cmd_sync(hdev, 0xfc1a, sizeof(bdaddr), bdaddr, HCI_INIT_TIMEOUT); -+ if (IS_ERR(skb)) { -+ ret = PTR_ERR(skb); -+ bt_dev_err(hdev, "changing Mediatek device address failed (%ld)", -+ ret); -+ return ret; -+ } -+ kfree_skb(skb); -+ -+ return 0; -+} -+ - static void btusb_mtk_wmt_recv(struct urb *urb) - { - struct hci_dev *hdev = urb->context; -@@ -3943,6 +3960,7 @@ static int btusb_probe(struct usb_interf - hdev->shutdown = btusb_mtk_shutdown; - hdev->manufacturer = 70; - hdev->cmd_timeout = btusb_mtk_cmd_timeout; -+ hdev->set_bdaddr = btusb_set_bdaddr_mtk; - set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); - data->recv_acl = btusb_recv_acl_mtk; - } diff --git a/target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch b/target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch deleted file mode 100644 index d21adada975efb..00000000000000 --- a/target/linux/generic/backport-5.15/822-v5.17-Bluetooth-btusb-Fix-application-of-sizeof-to-pointer.patch +++ /dev/null @@ -1,29 +0,0 @@ -From af774a731f7b4c2a90a8476cd44045ba8d1263ba Mon Sep 17 00:00:00 2001 -From: David Yang -Date: Wed, 13 Oct 2021 08:56:33 +0800 -Subject: [PATCH 2/5] Bluetooth: btusb: Fix application of sizeof to pointer - -The coccinelle check report: -"./drivers/bluetooth/btusb.c:2239:36-42: -ERROR: application of sizeof to pointer". -Using the real size to fix it. - -Fixes: 5a87679ffd443 ("Bluetooth: btusb: Support public address configuration for MediaTek Chip.") -Reported-by: Zeal Robot -Signed-off-by: David Yang -Signed-off-by: Marcel Holtmann ---- - drivers/bluetooth/btusb.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -2294,7 +2294,7 @@ static int btusb_set_bdaddr_mtk(struct h - struct sk_buff *skb; - long ret; - -- skb = __hci_cmd_sync(hdev, 0xfc1a, sizeof(bdaddr), bdaddr, HCI_INIT_TIMEOUT); -+ skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT); - if (IS_ERR(skb)) { - ret = PTR_ERR(skb); - bt_dev_err(hdev, "changing Mediatek device address failed (%ld)", diff --git a/target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch b/target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch deleted file mode 100644 index 30492ac48da59b..00000000000000 --- a/target/linux/generic/backport-5.15/823-v5.18-Bluetooth-btusb-Add-a-new-PID-VID-13d3-3567-for-MT79.patch +++ /dev/null @@ -1,70 +0,0 @@ -From e57186fc02cedff191c469a26cce615371e41740 Mon Sep 17 00:00:00 2001 -From: Yake Yang -Date: Wed, 23 Feb 2022 07:55:59 +0800 -Subject: [PATCH 3/5] Bluetooth: btusb: Add a new PID/VID 13d3/3567 for MT7921 - -Add VID 13D3 & PID 3567 for MediaTek MT7921 USB Bluetooth chip. - -The information in /sys/kernel/debug/usb/devices about the Bluetooth -device is listed as the below. - -T: Bus=05 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 -D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 -P: Vendor=13d3 ProdID=3567 Rev= 1.00 -S: Manufacturer=MediaTek Inc. -S: Product=Wireless_Device -S: SerialNumber=000000000 -C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA -A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 -I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us -E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms -E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms -I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms -I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms -I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms -I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms -I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms -I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms -I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms -I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) -E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us -E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us -I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) -E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us -E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us - -Co-developed-by: Sean Wang -Signed-off-by: Sean Wang -Signed-off-by: Yake Yang -Signed-off-by: Marcel Holtmann ---- - drivers/bluetooth/btusb.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -478,6 +478,9 @@ static const struct usb_device_id blackl - { USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x13d3, 0x3567), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, - { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, diff --git a/target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch b/target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch deleted file mode 100644 index 6bcd81c3b8030a..00000000000000 --- a/target/linux/generic/backport-5.15/824-v5.19-Bluetooth-btusb-Add-a-new-PID-VID-0489-e0c8-for-MT79.patch +++ /dev/null @@ -1,68 +0,0 @@ -From e507366cd1e8e1d4eebe537c08fd142cf0b617fa Mon Sep 17 00:00:00 2001 -From: Sean Wang -Date: Thu, 28 Apr 2022 02:38:39 +0800 -Subject: [PATCH 4/5] Bluetooth: btusb: Add a new PID/VID 0489/e0c8 for MT7921 - -Add VID 0489 & PID e0c8 for MediaTek MT7921 USB Bluetooth chip. - -The information in /sys/kernel/debug/usb/devices about the Bluetooth -device is listed as the below. - -T: Bus=01 Lev=01 Prnt=01 Port=13 Cnt=03 Dev#= 4 Spd=480 MxCh= 0 -D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 -P: Vendor=0489 ProdID=e0c8 Rev= 1.00 -S: Manufacturer=MediaTek Inc. -S: Product=Wireless_Device -S: SerialNumber=000000000 -C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA -A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 -I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us -E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms -E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms -I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms -I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms -I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms -I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms -I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms -I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms -I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms -I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) -E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us -E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us -I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) -E: Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us -E: Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us - -Signed-off-by: Sean Wang -Signed-off-by: Marcel Holtmann ---- - drivers/bluetooth/btusb.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -469,6 +469,9 @@ static const struct usb_device_id blackl - BTUSB_VALID_LE_STATES }, - - /* Additional MediaTek MT7921 Bluetooth devices */ -+ { USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, - { USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, diff --git a/target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch b/target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch deleted file mode 100644 index b6b76f64fcbbfe..00000000000000 --- a/target/linux/generic/backport-5.15/825-v6.1-Bluetooth-btusb-Add-a-new-VID-PID-0e8d-0608-for-MT79.patch +++ /dev/null @@ -1,66 +0,0 @@ -From be55622ce673f9692cc15d26d77a050cda42a3d3 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 9 Sep 2022 21:00:30 +0100 -Subject: [PATCH 1/1] Bluetooth: btusb: Add a new VID/PID 0e8d/0608 for MT7921 - -Add a new PID/VID 0e8d/0608 for MT7921K chip found on AMD RZ608 module. - -From /sys/kernel/debug/usb/devices: -T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 -D: Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 -P: Vendor=0e8d ProdID=0608 Rev= 1.00 -S: Manufacturer=MediaTek Inc. -S: Product=Wireless_Device -S: SerialNumber=000000000 -C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA -A: FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01 -I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=125us -E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms -E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms -I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms -I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms -I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms -I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms -I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms -I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms -I: If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb -E: Ad=83(I) Atr=01(Isoc) MxPS= 63 Ivl=1ms -E: Ad=03(O) Atr=01(Isoc) MxPS= 63 Ivl=1ms -I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) -E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us -E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us -I: If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) -E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=125us -E: Ad=0a(O) Atr=03(Int.) MxPS= 64 Ivl=125us - -Signed-off-by: Daniel Golle -Signed-off-by: Luiz Augusto von Dentz ---- - drivers/bluetooth/btusb.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/bluetooth/btusb.c -+++ b/drivers/bluetooth/btusb.c -@@ -487,6 +487,9 @@ static const struct usb_device_id blackl - { USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK | - BTUSB_WIDEBAND_SPEECH | - BTUSB_VALID_LE_STATES }, -+ { USB_DEVICE(0x0e8d, 0x0608), .driver_info = BTUSB_MEDIATEK | -+ BTUSB_WIDEBAND_SPEECH | -+ BTUSB_VALID_LE_STATES }, - - /* MediaTek MT7922A Bluetooth devices */ - { USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK | diff --git a/target/linux/generic/backport-5.15/826-v5.17-of-base-make-small-of_parse_phandle-variants-static-.patch b/target/linux/generic/backport-5.15/826-v5.17-of-base-make-small-of_parse_phandle-variants-static-.patch deleted file mode 100644 index 0ad89de56007bd..00000000000000 --- a/target/linux/generic/backport-5.15/826-v5.17-of-base-make-small-of_parse_phandle-variants-static-.patch +++ /dev/null @@ -1,359 +0,0 @@ -From 66a8f7f04979f4ad739085f01d99c8caf620b4f5 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 18 Jan 2022 18:35:02 +0100 -Subject: [PATCH] of: base: make small of_parse_phandle() variants static - inline - -Make all the smaller variants of the of_parse_phandle() static inline. -This also let us remove the empty function stubs if CONFIG_OF is not -defined. - -Suggested-by: Rob Herring -Signed-off-by: Michael Walle -[robh: move index < 0 check into __of_parse_phandle_with_args] -Signed-off-by: Rob Herring -Link: https://lore.kernel.org/r/20220118173504.2867523-2-michael@walle.cc ---- - drivers/of/base.c | 131 +++------------------------------------ - include/linux/of.h | 148 ++++++++++++++++++++++++++++++++++++--------- - 2 files changed, 129 insertions(+), 150 deletions(-) - ---- a/drivers/of/base.c -+++ b/drivers/of/base.c -@@ -1371,15 +1371,18 @@ int of_phandle_iterator_args(struct of_p - return count; - } - --static int __of_parse_phandle_with_args(const struct device_node *np, -- const char *list_name, -- const char *cells_name, -- int cell_count, int index, -- struct of_phandle_args *out_args) -+int __of_parse_phandle_with_args(const struct device_node *np, -+ const char *list_name, -+ const char *cells_name, -+ int cell_count, int index, -+ struct of_phandle_args *out_args) - { - struct of_phandle_iterator it; - int rc, cur_index = 0; - -+ if (index < 0) -+ return -EINVAL; -+ - /* Loop over the phandles until all the requested entry is found */ - of_for_each_phandle(&it, rc, np, list_name, cells_name, cell_count) { - /* -@@ -1422,82 +1425,7 @@ static int __of_parse_phandle_with_args( - of_node_put(it.node); - return rc; - } -- --/** -- * of_parse_phandle - Resolve a phandle property to a device_node pointer -- * @np: Pointer to device node holding phandle property -- * @phandle_name: Name of property holding a phandle value -- * @index: For properties holding a table of phandles, this is the index into -- * the table -- * -- * Return: The device_node pointer with refcount incremented. Use -- * of_node_put() on it when done. -- */ --struct device_node *of_parse_phandle(const struct device_node *np, -- const char *phandle_name, int index) --{ -- struct of_phandle_args args; -- -- if (index < 0) -- return NULL; -- -- if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, -- index, &args)) -- return NULL; -- -- return args.np; --} --EXPORT_SYMBOL(of_parse_phandle); -- --/** -- * of_parse_phandle_with_args() - Find a node pointed by phandle in a list -- * @np: pointer to a device tree node containing a list -- * @list_name: property name that contains a list -- * @cells_name: property name that specifies phandles' arguments count -- * @index: index of a phandle to parse out -- * @out_args: optional pointer to output arguments structure (will be filled) -- * -- * This function is useful to parse lists of phandles and their arguments. -- * Returns 0 on success and fills out_args, on error returns appropriate -- * errno value. -- * -- * Caller is responsible to call of_node_put() on the returned out_args->np -- * pointer. -- * -- * Example:: -- * -- * phandle1: node1 { -- * #list-cells = <2>; -- * }; -- * -- * phandle2: node2 { -- * #list-cells = <1>; -- * }; -- * -- * node3 { -- * list = <&phandle1 1 2 &phandle2 3>; -- * }; -- * -- * To get a device_node of the ``node2`` node you may call this: -- * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); -- */ --int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, -- const char *cells_name, int index, -- struct of_phandle_args *out_args) --{ -- int cell_count = -1; -- -- if (index < 0) -- return -EINVAL; -- -- /* If cells_name is NULL we assume a cell count of 0 */ -- if (!cells_name) -- cell_count = 0; -- -- return __of_parse_phandle_with_args(np, list_name, cells_name, -- cell_count, index, out_args); --} --EXPORT_SYMBOL(of_parse_phandle_with_args); -+EXPORT_SYMBOL(__of_parse_phandle_with_args); - - /** - * of_parse_phandle_with_args_map() - Find a node pointed by phandle in a list and remap it -@@ -1685,47 +1613,6 @@ free: - EXPORT_SYMBOL(of_parse_phandle_with_args_map); - - /** -- * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list -- * @np: pointer to a device tree node containing a list -- * @list_name: property name that contains a list -- * @cell_count: number of argument cells following the phandle -- * @index: index of a phandle to parse out -- * @out_args: optional pointer to output arguments structure (will be filled) -- * -- * This function is useful to parse lists of phandles and their arguments. -- * Returns 0 on success and fills out_args, on error returns appropriate -- * errno value. -- * -- * Caller is responsible to call of_node_put() on the returned out_args->np -- * pointer. -- * -- * Example:: -- * -- * phandle1: node1 { -- * }; -- * -- * phandle2: node2 { -- * }; -- * -- * node3 { -- * list = <&phandle1 0 2 &phandle2 2 3>; -- * }; -- * -- * To get a device_node of the ``node2`` node you may call this: -- * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args); -- */ --int of_parse_phandle_with_fixed_args(const struct device_node *np, -- const char *list_name, int cell_count, -- int index, struct of_phandle_args *out_args) --{ -- if (index < 0) -- return -EINVAL; -- return __of_parse_phandle_with_args(np, list_name, NULL, cell_count, -- index, out_args); --} --EXPORT_SYMBOL(of_parse_phandle_with_fixed_args); -- --/** - * of_count_phandle_with_args() - Find the number of phandles references in a property - * @np: pointer to a device tree node containing a list - * @list_name: property name that contains a list ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -363,18 +363,12 @@ extern const struct of_device_id *of_mat - const struct of_device_id *matches, const struct device_node *node); - extern int of_modalias_node(struct device_node *node, char *modalias, int len); - extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args); --extern struct device_node *of_parse_phandle(const struct device_node *np, -- const char *phandle_name, -- int index); --extern int of_parse_phandle_with_args(const struct device_node *np, -- const char *list_name, const char *cells_name, int index, -- struct of_phandle_args *out_args); -+extern int __of_parse_phandle_with_args(const struct device_node *np, -+ const char *list_name, const char *cells_name, int cell_count, -+ int index, struct of_phandle_args *out_args); - extern int of_parse_phandle_with_args_map(const struct device_node *np, - const char *list_name, const char *stem_name, int index, - struct of_phandle_args *out_args); --extern int of_parse_phandle_with_fixed_args(const struct device_node *np, -- const char *list_name, int cells_count, int index, -- struct of_phandle_args *out_args); - extern int of_count_phandle_with_args(const struct device_node *np, - const char *list_name, const char *cells_name); - -@@ -714,18 +708,12 @@ static inline int of_property_read_strin - return -ENOSYS; - } - --static inline struct device_node *of_parse_phandle(const struct device_node *np, -- const char *phandle_name, -- int index) --{ -- return NULL; --} -- --static inline int of_parse_phandle_with_args(const struct device_node *np, -- const char *list_name, -- const char *cells_name, -- int index, -- struct of_phandle_args *out_args) -+static inline int __of_parse_phandle_with_args(const struct device_node *np, -+ const char *list_name, -+ const char *cells_name, -+ int cell_count, -+ int index, -+ struct of_phandle_args *out_args) - { - return -ENOSYS; - } -@@ -739,13 +727,6 @@ static inline int of_parse_phandle_with_ - return -ENOSYS; - } - --static inline int of_parse_phandle_with_fixed_args(const struct device_node *np, -- const char *list_name, int cells_count, int index, -- struct of_phandle_args *out_args) --{ -- return -ENOSYS; --} -- - static inline int of_count_phandle_with_args(const struct device_node *np, - const char *list_name, - const char *cells_name) -@@ -927,6 +908,117 @@ static inline bool of_node_is_type(const - } - - /** -+ * of_parse_phandle - Resolve a phandle property to a device_node pointer -+ * @np: Pointer to device node holding phandle property -+ * @phandle_name: Name of property holding a phandle value -+ * @index: For properties holding a table of phandles, this is the index into -+ * the table -+ * -+ * Return: The device_node pointer with refcount incremented. Use -+ * of_node_put() on it when done. -+ */ -+static inline struct device_node *of_parse_phandle(const struct device_node *np, -+ const char *phandle_name, -+ int index) -+{ -+ struct of_phandle_args args; -+ -+ if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, -+ index, &args)) -+ return NULL; -+ -+ return args.np; -+} -+ -+/** -+ * of_parse_phandle_with_args() - Find a node pointed by phandle in a list -+ * @np: pointer to a device tree node containing a list -+ * @list_name: property name that contains a list -+ * @cells_name: property name that specifies phandles' arguments count -+ * @index: index of a phandle to parse out -+ * @out_args: optional pointer to output arguments structure (will be filled) -+ * -+ * This function is useful to parse lists of phandles and their arguments. -+ * Returns 0 on success and fills out_args, on error returns appropriate -+ * errno value. -+ * -+ * Caller is responsible to call of_node_put() on the returned out_args->np -+ * pointer. -+ * -+ * Example:: -+ * -+ * phandle1: node1 { -+ * #list-cells = <2>; -+ * }; -+ * -+ * phandle2: node2 { -+ * #list-cells = <1>; -+ * }; -+ * -+ * node3 { -+ * list = <&phandle1 1 2 &phandle2 3>; -+ * }; -+ * -+ * To get a device_node of the ``node2`` node you may call this: -+ * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); -+ */ -+static inline int of_parse_phandle_with_args(const struct device_node *np, -+ const char *list_name, -+ const char *cells_name, -+ int index, -+ struct of_phandle_args *out_args) -+{ -+ int cell_count = -1; -+ -+ /* If cells_name is NULL we assume a cell count of 0 */ -+ if (!cells_name) -+ cell_count = 0; -+ -+ return __of_parse_phandle_with_args(np, list_name, cells_name, -+ cell_count, index, out_args); -+} -+ -+/** -+ * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list -+ * @np: pointer to a device tree node containing a list -+ * @list_name: property name that contains a list -+ * @cell_count: number of argument cells following the phandle -+ * @index: index of a phandle to parse out -+ * @out_args: optional pointer to output arguments structure (will be filled) -+ * -+ * This function is useful to parse lists of phandles and their arguments. -+ * Returns 0 on success and fills out_args, on error returns appropriate -+ * errno value. -+ * -+ * Caller is responsible to call of_node_put() on the returned out_args->np -+ * pointer. -+ * -+ * Example:: -+ * -+ * phandle1: node1 { -+ * }; -+ * -+ * phandle2: node2 { -+ * }; -+ * -+ * node3 { -+ * list = <&phandle1 0 2 &phandle2 2 3>; -+ * }; -+ * -+ * To get a device_node of the ``node2`` node you may call this: -+ * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args); -+ */ -+static inline int of_parse_phandle_with_fixed_args(const struct device_node *np, -+ const char *list_name, -+ int cell_count, -+ int index, -+ struct of_phandle_args *out_args) -+{ -+ return __of_parse_phandle_with_args(np, list_name, NULL, cell_count, -+ index, out_args); -+} -+ -+/** - * of_property_count_u8_elems - Count the number of u8 elements in a property - * - * @np: device node from which the property value is to be read. diff --git a/target/linux/generic/backport-5.15/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch b/target/linux/generic/backport-5.15/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch deleted file mode 100644 index 97f4c6981e211b..00000000000000 --- a/target/linux/generic/backport-5.15/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch +++ /dev/null @@ -1,58 +0,0 @@ -From c5d264d4b527c96ae8903376a4b195df47b05203 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:43 +0000 -Subject: [PATCH] of: base: add of_parse_phandle_with_optional_args() - -Add a new variant of the of_parse_phandle_with_args() which treats the -cells name as optional. If it's missing, it is assumed that the phandle -has no arguments. - -Up until now, a nvmem node didn't have any arguments, so all the device -trees haven't any '#*-cells' property. But there is a need for an -additional argument for the phandle, for which we need a '#*-cells' -property. Therefore, we need to support nvmem nodes with and without -this property. - -Signed-off-by: Michael Walle -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - include/linux/of.h | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -1019,6 +1019,31 @@ static inline int of_parse_phandle_with_ - } - - /** -+ * of_parse_phandle_with_optional_args() - Find a node pointed by phandle in a list -+ * @np: pointer to a device tree node containing a list -+ * @list_name: property name that contains a list -+ * @cells_name: property name that specifies phandles' arguments count -+ * @index: index of a phandle to parse out -+ * @out_args: optional pointer to output arguments structure (will be filled) -+ * -+ * Same as of_parse_phandle_with_args() except that if the cells_name property -+ * is not found, cell_count of 0 is assumed. -+ * -+ * This is used to useful, if you have a phandle which didn't have arguments -+ * before and thus doesn't have a '#*-cells' property but is now migrated to -+ * having arguments while retaining backwards compatibility. -+ */ -+static inline int of_parse_phandle_with_optional_args(const struct device_node *np, -+ const char *list_name, -+ const char *cells_name, -+ int index, -+ struct of_phandle_args *out_args) -+{ -+ return __of_parse_phandle_with_args(np, list_name, cells_name, -+ 0, index, out_args); -+} -+ -+/** - * of_property_count_u8_elems - Count the number of u8 elements in a property - * - * @np: device node from which the property value is to be read. diff --git a/target/linux/generic/backport-5.15/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch b/target/linux/generic/backport-5.15/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch deleted file mode 100644 index 39d9fae7239af5..00000000000000 --- a/target/linux/generic/backport-5.15/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ff24fed10ba414d19579e26e60b126fad2f2bb07 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:44 +0000 -Subject: [PATCH] of: property: make #.*-cells optional for simple props - -Sometimes, future bindings for phandles will get additional arguments. -Thus the target node of the phandle will need a new #.*-cells property. -To be backwards compatible, this needs to be optional. - -Prepare the DEFINE_SIMPLE_PROPS() to handle the cells name as optional. - -Signed-off-by: Michael Walle -Tested-by: Miquel Raynal -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-11-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/property.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/of/property.c -+++ b/drivers/of/property.c -@@ -1173,8 +1173,8 @@ static struct device_node *parse_prop_ce - if (strcmp(prop_name, list_name)) - return NULL; - -- if (of_parse_phandle_with_args(np, list_name, cells_name, index, -- &sup_args)) -+ if (__of_parse_phandle_with_args(np, list_name, cells_name, 0, index, -+ &sup_args)) - return NULL; - - return sup_args.np; diff --git a/target/linux/generic/backport-5.15/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch b/target/linux/generic/backport-5.15/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch deleted file mode 100644 index 774e793ca5a62c..00000000000000 --- a/target/linux/generic/backport-5.15/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch +++ /dev/null @@ -1,30 +0,0 @@ -From e2d8172043d2e50df19fcd59c11e5593de8188d7 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:45 +0000 -Subject: [PATCH] of: property: add #nvmem-cell-cells property - -Bindings describe the new '#nvmem-cell-cells' property. Now that the -arguments count property is optional, we just add this property to the -nvmem-cells. - -Signed-off-by: Michael Walle -Tested-by: Miquel Raynal -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-12-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/property.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/of/property.c -+++ b/drivers/of/property.c -@@ -1276,7 +1276,7 @@ DEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-c - DEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells") - DEFINE_SIMPLE_PROP(hwlocks, "hwlocks", "#hwlock-cells") - DEFINE_SIMPLE_PROP(extcon, "extcon", NULL) --DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", NULL) -+DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", "#nvmem-cell-cells") - DEFINE_SIMPLE_PROP(phys, "phys", "#phy-cells") - DEFINE_SIMPLE_PROP(wakeup_parent, "wakeup-parent", NULL) - DEFINE_SIMPLE_PROP(pinctrl0, "pinctrl-0", NULL) diff --git a/target/linux/generic/backport-5.15/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch b/target/linux/generic/backport-5.15/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch deleted file mode 100644 index 37eefc4570f9cc..00000000000000 --- a/target/linux/generic/backport-5.15/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 553bd29700145e1849698985e9800f14e967da49 Mon Sep 17 00:00:00 2001 -From: Alexander Stein -Date: Tue, 7 Feb 2023 12:05:29 +0100 -Subject: [PATCH] of: device: Ignore modalias of reused nodes - -If of_node is reused, do not use that node's modalias. This will hide -the name of the actual device. This is rather prominent in USB glue -drivers creating a platform device for the host controller. - -Signed-off-by: Alexander Stein -Reviewed-by: Rob Herring -Link: https://lore.kernel.org/r/20230207110531.1060252-2-alexander.stein@ew.tq-group.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/device.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -249,7 +249,7 @@ static ssize_t of_device_get_modalias(st - ssize_t csize; - ssize_t tsize; - -- if ((!dev) || (!dev->of_node)) -+ if ((!dev) || (!dev->of_node) || dev->of_node_reused) - return -ENODEV; - - /* Name & Type */ -@@ -372,7 +372,7 @@ int of_device_uevent_modalias(struct dev - { - int sl; - -- if ((!dev) || (!dev->of_node)) -+ if ((!dev) || (!dev->of_node) || dev->of_node_reused) - return -ENODEV; - - /* Devicetree modalias is tricky, we add it in 2 steps */ diff --git a/target/linux/generic/backport-5.15/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch b/target/linux/generic/backport-5.15/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch deleted file mode 100644 index dd5820e94a5067..00000000000000 --- a/target/linux/generic/backport-5.15/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 2295bed9bebe8d1eef276194fed5b5fbe89c5363 Mon Sep 17 00:00:00 2001 -From: Alexander Stein -Date: Tue, 7 Feb 2023 12:05:30 +0100 -Subject: [PATCH] of: device: Do not ignore error code in - of_device_uevent_modalias - -of_device_get_modalias might return an error code, propagate that one. -Otherwise the negative, signed integer is propagated to unsigned integer -for the comparison resulting in a huge 'sl' size. - -Signed-off-by: Alexander Stein -Reviewed-by: Rob Herring -Link: https://lore.kernel.org/r/20230207110531.1060252-3-alexander.stein@ew.tq-group.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/device.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -381,6 +381,8 @@ int of_device_uevent_modalias(struct dev - - sl = of_device_get_modalias(dev, &env->buf[env->buflen-1], - sizeof(env->buf) - env->buflen); -+ if (sl < 0) -+ return sl; - if (sl >= (sizeof(env->buf) - env->buflen)) - return -ENOMEM; - env->buflen += sl; diff --git a/target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch b/target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch deleted file mode 100644 index 4713cc71b1291c..00000000000000 --- a/target/linux/generic/backport-5.15/828-v6.4-0002-of-Update-of_device_get_modalias.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 5c3d15e127ebfc0754cd18def7124633b6d46672 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:15 +0100 -Subject: [PATCH] of: Update of_device_get_modalias() - -This function only needs a "struct device_node" to work, but for -convenience the author (and only user) of this helper did use a "struct -device" and put it in device.c. - -Let's convert this helper to take a "struct device node" instead. This -change asks for two additional changes: renaming it "of_modalias()" -to fit the current naming, and moving it outside of device.c which will -be done in a follow-up commit. - -Signed-off-by: Miquel Raynal -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/device.c | 29 +++++++++++++++++------------ - 1 file changed, 17 insertions(+), 12 deletions(-) - ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -241,7 +241,7 @@ const void *of_device_get_match_data(con - } - EXPORT_SYMBOL(of_device_get_match_data); - --static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) -+static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) - { - const char *compat; - char *c; -@@ -249,19 +249,16 @@ static ssize_t of_device_get_modalias(st - ssize_t csize; - ssize_t tsize; - -- if ((!dev) || (!dev->of_node) || dev->of_node_reused) -- return -ENODEV; -- - /* Name & Type */ - /* %p eats all alphanum characters, so %c must be used here */ -- csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T', -- of_node_get_device_type(dev->of_node)); -+ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', -+ of_node_get_device_type(np)); - tsize = csize; - len -= csize; - if (str) - str += csize; - -- of_property_for_each_string(dev->of_node, "compatible", p, compat) { -+ of_property_for_each_string(np, "compatible", p, compat) { - csize = strlen(compat) + 1; - tsize += csize; - if (csize > len) -@@ -286,7 +283,10 @@ int of_device_request_module(struct devi - ssize_t size; - int ret; - -- size = of_device_get_modalias(dev, NULL, 0); -+ if (!dev || !dev->of_node) -+ return -ENODEV; -+ -+ size = of_modalias(dev->of_node, NULL, 0); - if (size < 0) - return size; - -@@ -297,7 +297,7 @@ int of_device_request_module(struct devi - if (!str) - return -ENOMEM; - -- of_device_get_modalias(dev, str, size); -+ of_modalias(dev->of_node, str, size); - str[size - 1] = '\0'; - ret = request_module(str); - kfree(str); -@@ -314,7 +314,12 @@ EXPORT_SYMBOL_GPL(of_device_request_modu - */ - ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len) - { -- ssize_t sl = of_device_get_modalias(dev, str, len - 2); -+ ssize_t sl; -+ -+ if (!dev || !dev->of_node || dev->of_node_reused) -+ return -ENODEV; -+ -+ sl = of_modalias(dev->of_node, str, len - 2); - if (sl < 0) - return sl; - if (sl > len - 2) -@@ -379,8 +384,8 @@ int of_device_uevent_modalias(struct dev - if (add_uevent_var(env, "MODALIAS=")) - return -ENOMEM; - -- sl = of_device_get_modalias(dev, &env->buf[env->buflen-1], -- sizeof(env->buf) - env->buflen); -+ sl = of_modalias(dev->of_node, &env->buf[env->buflen-1], -+ sizeof(env->buf) - env->buflen); - if (sl < 0) - return sl; - if (sl >= (sizeof(env->buf) - env->buflen)) diff --git a/target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch b/target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch deleted file mode 100644 index 7cfdb28c642396..00000000000000 --- a/target/linux/generic/backport-5.15/828-v6.4-0003-of-Rename-of_modalias_node.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 673aa1ed1c9b6710bf24e3f0957d85e2f46c77db Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:16 +0100 -Subject: [PATCH] of: Rename of_modalias_node() - -This helper does not produce a real modalias, but tries to get the -"product" compatible part of the "vendor,product" compatibles only. It -is far from creating a purely useful modalias string and does not seem -to be used like that directly anyway, so let's try to give this helper a -more meaningful name before moving there a real modalias helper (already -existing under of/device.c). - -Also update the various documentations to refer to the strings as -"aliases" rather than "modaliases" which has a real meaning in the Linux -kernel. - -There is no functional change. - -Cc: Rafael J. Wysocki -Cc: Len Brown -Cc: Maarten Lankhorst -Cc: Maxime Ripard -Cc: Thomas Zimmermann -Cc: Sebastian Reichel -Cc: Wolfram Sang -Cc: Mark Brown -Signed-off-by: Miquel Raynal -Reviewed-by: Rob Herring -Acked-by: Mark Brown -Signed-off-by: Srinivas Kandagatla -Acked-by: Sebastian Reichel -Link: https://lore.kernel.org/r/20230404172148.82422-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/acpi/bus.c | 7 ++++--- - drivers/gpu/drm/drm_mipi_dsi.c | 2 +- - drivers/hsi/hsi_core.c | 2 +- - drivers/i2c/busses/i2c-powermac.c | 2 +- - drivers/i2c/i2c-core-of.c | 2 +- - drivers/of/base.c | 18 +++++++++++------- - drivers/spi/spi.c | 4 ++-- - include/linux/of.h | 3 ++- - 8 files changed, 23 insertions(+), 17 deletions(-) - ---- a/drivers/acpi/bus.c -+++ b/drivers/acpi/bus.c -@@ -785,9 +785,10 @@ static bool acpi_of_modalias(struct acpi - * @modalias: Pointer to buffer that modalias value will be copied into - * @len: Length of modalias buffer - * -- * This is a counterpart of of_modalias_node() for struct acpi_device objects. -- * If there is a compatible string for @adev, it will be copied to @modalias -- * with the vendor prefix stripped; otherwise, @default_id will be used. -+ * This is a counterpart of of_alias_from_compatible() for struct acpi_device -+ * objects. If there is a compatible string for @adev, it will be copied to -+ * @modalias with the vendor prefix stripped; otherwise, @default_id will be -+ * used. - */ - void acpi_set_modalias(struct acpi_device *adev, const char *default_id, - char *modalias, size_t len) ---- a/drivers/gpu/drm/drm_mipi_dsi.c -+++ b/drivers/gpu/drm/drm_mipi_dsi.c -@@ -160,7 +160,7 @@ of_mipi_dsi_device_add(struct mipi_dsi_h - int ret; - u32 reg; - -- if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { -+ if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) { - drm_err(host, "modalias failure on %pOF\n", node); - return ERR_PTR(-EINVAL); - } ---- a/drivers/hsi/hsi_core.c -+++ b/drivers/hsi/hsi_core.c -@@ -207,7 +207,7 @@ static void hsi_add_client_from_dt(struc - if (!cl) - return; - -- err = of_modalias_node(client, name, sizeof(name)); -+ err = of_alias_from_compatible(client, name, sizeof(name)); - if (err) - goto err; - ---- a/drivers/i2c/busses/i2c-powermac.c -+++ b/drivers/i2c/busses/i2c-powermac.c -@@ -284,7 +284,7 @@ static bool i2c_powermac_get_type(struct - */ - - /* First try proper modalias */ -- if (of_modalias_node(node, tmp, sizeof(tmp)) >= 0) { -+ if (of_alias_from_compatible(node, tmp, sizeof(tmp)) >= 0) { - snprintf(type, type_size, "MAC,%s", tmp); - return true; - } ---- a/drivers/i2c/i2c-core-of.c -+++ b/drivers/i2c/i2c-core-of.c -@@ -27,7 +27,7 @@ int of_i2c_get_board_info(struct device - - memset(info, 0, sizeof(*info)); - -- if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) { -+ if (of_alias_from_compatible(node, info->type, sizeof(info->type)) < 0) { - dev_err(dev, "of_i2c: modalias failure on %pOF\n", node); - return -EINVAL; - } ---- a/drivers/of/base.c -+++ b/drivers/of/base.c -@@ -1159,19 +1159,23 @@ struct device_node *of_find_matching_nod - EXPORT_SYMBOL(of_find_matching_node_and_match); - - /** -- * of_modalias_node - Lookup appropriate modalias for a device node -+ * of_alias_from_compatible - Lookup appropriate alias for a device node -+ * depending on compatible - * @node: pointer to a device tree node -- * @modalias: Pointer to buffer that modalias value will be copied into -- * @len: Length of modalias value -+ * @alias: Pointer to buffer that alias value will be copied into -+ * @len: Length of alias value - * - * Based on the value of the compatible property, this routine will attempt -- * to choose an appropriate modalias value for a particular device tree node. -+ * to choose an appropriate alias value for a particular device tree node. - * It does this by stripping the manufacturer prefix (as delimited by a ',') - * from the first entry in the compatible list property. - * -+ * Note: The matching on just the "product" side of the compatible is a relic -+ * from I2C and SPI. Please do not add any new user. -+ * - * Return: This routine returns 0 on success, <0 on failure. - */ --int of_modalias_node(struct device_node *node, char *modalias, int len) -+int of_alias_from_compatible(const struct device_node *node, char *alias, int len) - { - const char *compatible, *p; - int cplen; -@@ -1180,10 +1184,10 @@ int of_modalias_node(struct device_node - if (!compatible || strlen(compatible) > cplen) - return -ENODEV; - p = strchr(compatible, ','); -- strlcpy(modalias, p ? p + 1 : compatible, len); -+ strlcpy(alias, p ? p + 1 : compatible, len); - return 0; - } --EXPORT_SYMBOL_GPL(of_modalias_node); -+EXPORT_SYMBOL_GPL(of_alias_from_compatible); - - /** - * of_find_node_by_phandle - Find a node given a phandle ---- a/drivers/spi/spi.c -+++ b/drivers/spi/spi.c -@@ -2144,8 +2144,8 @@ of_register_spi_device(struct spi_contro - } - - /* Select device driver */ -- rc = of_modalias_node(nc, spi->modalias, -- sizeof(spi->modalias)); -+ rc = of_alias_from_compatible(nc, spi->modalias, -+ sizeof(spi->modalias)); - if (rc < 0) { - dev_err(&ctlr->dev, "cannot find modalias for %pOF\n", nc); - goto err_out; ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -361,7 +361,8 @@ extern int of_n_addr_cells(struct device - extern int of_n_size_cells(struct device_node *np); - extern const struct of_device_id *of_match_node( - const struct of_device_id *matches, const struct device_node *node); --extern int of_modalias_node(struct device_node *node, char *modalias, int len); -+extern int of_alias_from_compatible(const struct device_node *node, char *alias, -+ int len); - extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args); - extern int __of_parse_phandle_with_args(const struct device_node *np, - const char *list_name, const char *cells_name, int cell_count, diff --git a/target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch b/target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch deleted file mode 100644 index b4554b2ecad28c..00000000000000 --- a/target/linux/generic/backport-5.15/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch +++ /dev/null @@ -1,160 +0,0 @@ -From bd7a7ed774afd1a4174df34227626c95573be517 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:17 +0100 -Subject: [PATCH] of: Move of_modalias() to module.c - -Create a specific .c file for OF related module handling. -Move of_modalias() inside as a first step. - -The helper is exposed through of.h even though it is only used by core -files because the users from device.c will soon be split into an OF-only -helper in module.c as well as a device-oriented inline helper in -of_device.h. Putting this helper in of_private.h would require to -include of_private.h from of_device.h, which is not acceptable. - -Suggested-by: Rob Herring -Signed-off-by: Miquel Raynal -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/Makefile | 2 +- - drivers/of/device.c | 37 ------------------------------------- - drivers/of/module.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ - include/linux/of.h | 9 +++++++++ - 4 files changed, 54 insertions(+), 38 deletions(-) - create mode 100644 drivers/of/module.c - ---- a/drivers/of/Makefile -+++ b/drivers/of/Makefile -@@ -1,5 +1,5 @@ - # SPDX-License-Identifier: GPL-2.0 --obj-y = base.o device.o platform.o property.o -+obj-y = base.o device.o module.o platform.o property.o - obj-$(CONFIG_OF_KOBJ) += kobj.o - obj-$(CONFIG_OF_DYNAMIC) += dynamic.o - obj-$(CONFIG_OF_FLATTREE) += fdt.o ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -1,5 +1,4 @@ - // SPDX-License-Identifier: GPL-2.0 --#include - #include - #include - #include -@@ -241,42 +240,6 @@ const void *of_device_get_match_data(con - } - EXPORT_SYMBOL(of_device_get_match_data); - --static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) --{ -- const char *compat; -- char *c; -- struct property *p; -- ssize_t csize; -- ssize_t tsize; -- -- /* Name & Type */ -- /* %p eats all alphanum characters, so %c must be used here */ -- csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', -- of_node_get_device_type(np)); -- tsize = csize; -- len -= csize; -- if (str) -- str += csize; -- -- of_property_for_each_string(np, "compatible", p, compat) { -- csize = strlen(compat) + 1; -- tsize += csize; -- if (csize > len) -- continue; -- -- csize = snprintf(str, len, "C%s", compat); -- for (c = str; c; ) { -- c = strchr(c, ' '); -- if (c) -- *c++ = '_'; -- } -- len -= csize; -- str += csize; -- } -- -- return tsize; --} -- - int of_device_request_module(struct device *dev) - { - char *str; ---- /dev/null -+++ b/drivers/of/module.c -@@ -0,0 +1,44 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Linux kernel module helpers. -+ */ -+ -+#include -+#include -+#include -+ -+ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) -+{ -+ const char *compat; -+ char *c; -+ struct property *p; -+ ssize_t csize; -+ ssize_t tsize; -+ -+ /* Name & Type */ -+ /* %p eats all alphanum characters, so %c must be used here */ -+ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', -+ of_node_get_device_type(np)); -+ tsize = csize; -+ len -= csize; -+ if (str) -+ str += csize; -+ -+ of_property_for_each_string(np, "compatible", p, compat) { -+ csize = strlen(compat) + 1; -+ tsize += csize; -+ if (csize > len) -+ continue; -+ -+ csize = snprintf(str, len, "C%s", compat); -+ for (c = str; c; ) { -+ c = strchr(c, ' '); -+ if (c) -+ *c++ = '_'; -+ } -+ len -= csize; -+ str += csize; -+ } -+ -+ return tsize; -+} ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -373,6 +373,9 @@ extern int of_parse_phandle_with_args_ma - extern int of_count_phandle_with_args(const struct device_node *np, - const char *list_name, const char *cells_name); - -+/* module functions */ -+extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len); -+ - /* phandle iterator functions */ - extern int of_phandle_iterator_init(struct of_phandle_iterator *it, - const struct device_node *np, -@@ -735,6 +738,12 @@ static inline int of_count_phandle_with_ - return -ENOSYS; - } - -+static inline ssize_t of_modalias(const struct device_node *np, char *str, -+ ssize_t len) -+{ -+ return -ENODEV; -+} -+ - static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, - const struct device_node *np, - const char *list_name, diff --git a/target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch b/target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch deleted file mode 100644 index ad42039e112aee..00000000000000 --- a/target/linux/generic/backport-5.15/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch +++ /dev/null @@ -1,131 +0,0 @@ -From e6506f06d5e82765666902ccf9e9162f3e31d518 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:18 +0100 -Subject: [PATCH] of: Move the request module helper logic to module.c - -Depending on device.c for pure OF handling is considered -backwards. Let's extract the content of of_device_request_module() to -have the real logic under module.c. - -The next step will be to convert users of of_device_request_module() to -use the new helper. - -Signed-off-by: Miquel Raynal -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-11-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/device.c | 25 ++----------------------- - drivers/of/module.c | 30 ++++++++++++++++++++++++++++++ - include/linux/of.h | 6 ++++++ - 3 files changed, 38 insertions(+), 23 deletions(-) - ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -8,7 +8,6 @@ - #include /* for bus_dma_region */ - #include - #include --#include - #include - #include - #include -@@ -242,30 +241,10 @@ EXPORT_SYMBOL(of_device_get_match_data); - - int of_device_request_module(struct device *dev) - { -- char *str; -- ssize_t size; -- int ret; -- -- if (!dev || !dev->of_node) -+ if (!dev) - return -ENODEV; - -- size = of_modalias(dev->of_node, NULL, 0); -- if (size < 0) -- return size; -- -- /* Reserve an additional byte for the trailing '\0' */ -- size++; -- -- str = kmalloc(size, GFP_KERNEL); -- if (!str) -- return -ENOMEM; -- -- of_modalias(dev->of_node, str, size); -- str[size - 1] = '\0'; -- ret = request_module(str); -- kfree(str); -- -- return ret; -+ return of_request_module(dev->of_node); - } - EXPORT_SYMBOL_GPL(of_device_request_module); - ---- a/drivers/of/module.c -+++ b/drivers/of/module.c -@@ -4,6 +4,7 @@ - */ - - #include -+#include - #include - #include - -@@ -42,3 +43,32 @@ ssize_t of_modalias(const struct device_ - - return tsize; - } -+ -+int of_request_module(const struct device_node *np) -+{ -+ char *str; -+ ssize_t size; -+ int ret; -+ -+ if (!np) -+ return -ENODEV; -+ -+ size = of_modalias(np, NULL, 0); -+ if (size < 0) -+ return size; -+ -+ /* Reserve an additional byte for the trailing '\0' */ -+ size++; -+ -+ str = kmalloc(size, GFP_KERNEL); -+ if (!str) -+ return -ENOMEM; -+ -+ of_modalias(np, str, size); -+ str[size - 1] = '\0'; -+ ret = request_module(str); -+ kfree(str); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(of_request_module); ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -375,6 +375,7 @@ extern int of_count_phandle_with_args(co - - /* module functions */ - extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len); -+extern int of_request_module(const struct device_node *np); - - /* phandle iterator functions */ - extern int of_phandle_iterator_init(struct of_phandle_iterator *it, -@@ -743,6 +744,11 @@ static inline ssize_t of_modalias(const - { - return -ENODEV; - } -+ -+static inline int of_request_module(const struct device_node *np) -+{ -+ return -ENODEV; -+} - - static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, - const struct device_node *np, diff --git a/target/linux/generic/backport-5.15/829-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch b/target/linux/generic/backport-5.15/829-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch deleted file mode 100644 index 1365834563b275..00000000000000 --- a/target/linux/generic/backport-5.15/829-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 4d70c74659d9746502b23d055dba03d1d28ec388 Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Wed, 30 Nov 2022 15:48:35 +0200 -Subject: [PATCH] i915: Move list_count() to list.h as list_count_nodes() for - broader use - -Some of the existing users, and definitely will be new ones, want to -count existing nodes in the list. Provide a generic API for that by -moving code from i915 to list.h. - -Reviewed-by: Lucas De Marchi -Acked-by: Jani Nikula -Signed-off-by: Andy Shevchenko -Link: https://lore.kernel.org/r/20221130134838.23805-1-andriy.shevchenko@linux.intel.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/gpu/drm/i915/gt/intel_engine_cs.c | 15 ++------------- - include/linux/list.h | 15 +++++++++++++++ - 2 files changed, 17 insertions(+), 13 deletions(-) - ---- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c -+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c -@@ -1639,17 +1639,6 @@ static void print_request_ring(struct dr - } - } - --static unsigned long list_count(struct list_head *list) --{ -- struct list_head *pos; -- unsigned long count = 0; -- -- list_for_each(pos, list) -- count++; -- -- return count; --} -- - static unsigned long read_ul(void *p, size_t x) - { - return *(unsigned long *)(p + x); -@@ -1824,8 +1813,8 @@ void intel_engine_dump(struct intel_engi - spin_lock_irqsave(&engine->sched_engine->lock, flags); - engine_dump_active_requests(engine, m); - -- drm_printf(m, "\tOn hold?: %lu\n", -- list_count(&engine->sched_engine->hold)); -+ drm_printf(m, "\tOn hold?: %zu\n", -+ list_count_nodes(&engine->sched_engine->hold)); - spin_unlock_irqrestore(&engine->sched_engine->lock, flags); - - drm_printf(m, "\tMMIO base: 0x%08x\n", engine->mmio_base); ---- a/include/linux/list.h -+++ b/include/linux/list.h -@@ -628,6 +628,21 @@ static inline void list_splice_tail_init - pos = n, n = pos->prev) - - /** -+ * list_count_nodes - count nodes in the list -+ * @head: the head for your list. -+ */ -+static inline size_t list_count_nodes(struct list_head *head) -+{ -+ struct list_head *pos; -+ size_t count = 0; -+ -+ list_for_each(pos, head) -+ count++; -+ -+ return count; -+} -+ -+/** - * list_entry_is_head - test if the entry points to the head of the list - * @pos: the type * to cursor - * @head: the head for your list. diff --git a/target/linux/generic/backport-5.15/830-v6.0-leds-turris-omnia-convert-to-use-dev_groups.patch b/target/linux/generic/backport-5.15/830-v6.0-leds-turris-omnia-convert-to-use-dev_groups.patch deleted file mode 100644 index 99ebe064388c3d..00000000000000 --- a/target/linux/generic/backport-5.15/830-v6.0-leds-turris-omnia-convert-to-use-dev_groups.patch +++ /dev/null @@ -1,45 +0,0 @@ -From a01633cd867b8ddf2d8321fe575dc3c54e037b09 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Fri, 29 Jul 2022 16:03:46 +0200 -Subject: leds: turris-omnia: convert to use dev_groups -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The driver core supports the ability to handle the creation and removal -of device-specific sysfs files in a race-free manner. Take advantage of -that by converting this driver to use this by moving the sysfs -attributes into a group and assigning the dev_groups pointer to it. - -Cc: Pavel Machek -Cc: linux-leds@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Reviewed-by: Marek Behún -Signed-off-by: Greg Kroah-Hartman -Signed-off-by: Pavel Machek ---- - drivers/leds/leds-turris-omnia.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -(limited to 'drivers/leds/leds-turris-omnia.c') - ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -260,9 +260,6 @@ static int omnia_leds_probe(struct i2c_c - led += ret; - } - -- if (devm_device_add_groups(dev, omnia_led_controller_groups)) -- dev_warn(dev, "Could not add attribute group!\n"); -- - return 0; - } - -@@ -304,6 +301,7 @@ static struct i2c_driver omnia_leds_driv - .driver = { - .name = "leds-turris-omnia", - .of_match_table = of_omnia_leds_match, -+ .dev_groups = omnia_led_controller_groups, - }, - }; - diff --git a/target/linux/generic/backport-5.15/830-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch b/target/linux/generic/backport-5.15/830-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch deleted file mode 100644 index 835a5e884702b9..00000000000000 --- a/target/linux/generic/backport-5.15/830-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 72a29725b6f2577fa447ca9059cdcd17100043b4 Mon Sep 17 00:00:00 2001 -From: Marek Behún -Date: Wed, 2 Aug 2023 18:07:45 +0200 -Subject: leds: turris-omnia: Use sysfs_emit() instead of sprintf() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the dedicated sysfs_emit() function instead of sprintf() in sysfs -attribute accessor brightness_show(). - -Signed-off-by: Marek Behún -Link: https://lore.kernel.org/r/20230802160748.11208-4-kabel@kernel.org -Signed-off-by: Lee Jones ---- - drivers/leds/leds-turris-omnia.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -(limited to 'drivers/leds/leds-turris-omnia.c') - ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -194,7 +194,7 @@ static ssize_t brightness_show(struct de - if (ret < 0) - return ret; - -- return sprintf(buf, "%d\n", ret); -+ return sysfs_emit(buf, "%d\n", ret); - } - - static ssize_t brightness_store(struct device *dev, struct device_attribute *a, diff --git a/target/linux/generic/backport-5.15/830-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch b/target/linux/generic/backport-5.15/830-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch deleted file mode 100644 index 3f7dd64841ab71..00000000000000 --- a/target/linux/generic/backport-5.15/830-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 4d5ed2621c2437d40b8fe92bd0fd34b0b1870753 Mon Sep 17 00:00:00 2001 -From: Marek Behún -Date: Mon, 18 Sep 2023 18:11:02 +0200 -Subject: leds: turris-omnia: Make set_brightness() more efficient -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Implement caching of the LED color and state values that are sent to MCU -in order to make the set_brightness() operation more efficient by -avoiding I2C transactions which are not needed. - -On Turris Omnia's MCU, which acts as the RGB LED controller, each LED -has a RGB color, and a ON/OFF state, which are configurable via I2C -commands CMD_LED_COLOR and CMD_LED_STATE. - -The CMD_LED_COLOR command sends 5 bytes and the CMD_LED_STATE command 2 -bytes over the I2C bus, which operates at 100 kHz. With I2C overhead -this allows ~1670 color changing commands and ~3200 state changing -commands per second (or around 1000 color + state changes per second). -This may seem more than enough, but the issue is that the I2C bus is -shared with another peripheral, the MCU. The MCU exposes an interrupt -interface, and it can trigger hundreds of interrupts per second. Each -time, we need to read the interrupt state register over this I2C bus. -Whenever we are sending a LED color/state changing command, the -interrupt reading is waiting. - -Currently, every time LED brightness or LED multi intensity is changed, -we send a CMD_LED_STATE command, and if the computed color (brightness -adjusted multi_intensity) is non-zero, we also send a CMD_LED_COLOR -command. - -Consider for example the situation when we have a netdev trigger enabled -for a LED. The netdev trigger does not change the LED color, only the -brightness (either to 0 or to currently configured brightness), and so -there is no need to send the CMD_LED_COLOR command. But each change of -brightness to 0 sends one CMD_LED_STATE command, and each change of -brightness to max_brightness sends one CMD_LED_STATE command and one -CMD_LED_COLOR command: - set_brightness(0) -> CMD_LED_STATE - set_brightness(255) -> CMD_LED_STATE + CMD_LED_COLOR - (unnecessary) - -We can avoid the unnecessary I2C transactions if we cache the values of -state and color that are sent to the controller. If the color does not -change from the one previously sent, there is no need to do the -CMD_LED_COLOR I2C transaction, and if the state does not change, there -is no need to do the CMD_LED_STATE transaction. - -Because we need to make sure that our cached values are consistent with -the controller state, add explicit setting of the LED color to white at -probe time (this is the default setting when MCU resets, but does not -necessarily need to be the case, for example if U-Boot played with the -LED colors). - -Signed-off-by: Marek Behún -Link: https://lore.kernel.org/r/20230918161104.20860-3-kabel@kernel.org -Signed-off-by: Lee Jones ---- - drivers/leds/leds-turris-omnia.c | 96 ++++++++++++++++++++++++++++++++-------- - 1 file changed, 78 insertions(+), 18 deletions(-) - ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -30,6 +30,8 @@ - struct omnia_led { - struct led_classdev_mc mc_cdev; - struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS]; -+ u8 cached_channels[OMNIA_LED_NUM_CHANNELS]; -+ bool on; - int reg; - }; - -@@ -72,36 +74,82 @@ static int omnia_cmd_read_u8(const struc - return -EIO; - } - -+static int omnia_led_send_color_cmd(const struct i2c_client *client, -+ struct omnia_led *led) -+{ -+ char cmd[5]; -+ int ret; -+ -+ cmd[0] = CMD_LED_COLOR; -+ cmd[1] = led->reg; -+ cmd[2] = led->subled_info[0].brightness; -+ cmd[3] = led->subled_info[1].brightness; -+ cmd[4] = led->subled_info[2].brightness; -+ -+ /* Send the color change command */ -+ ret = i2c_master_send(client, cmd, 5); -+ if (ret < 0) -+ return ret; -+ -+ /* Cache the RGB channel brightnesses */ -+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i) -+ led->cached_channels[i] = led->subled_info[i].brightness; -+ -+ return 0; -+} -+ -+/* Determine if the computed RGB channels are different from the cached ones */ -+static bool omnia_led_channels_changed(struct omnia_led *led) -+{ -+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i) -+ if (led->subled_info[i].brightness != led->cached_channels[i]) -+ return true; -+ -+ return false; -+} -+ - static int omnia_led_brightness_set_blocking(struct led_classdev *cdev, - enum led_brightness brightness) - { - struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); - struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); - struct omnia_led *led = to_omnia_led(mc_cdev); -- u8 buf[5], state; -- int ret; -+ int err = 0; - - mutex_lock(&leds->lock); - -- led_mc_calc_color_components(&led->mc_cdev, brightness); -+ /* -+ * Only recalculate RGB brightnesses from intensities if brightness is -+ * non-zero. Otherwise we won't be using them and we can save ourselves -+ * some software divisions (Omnia's CPU does not implement the division -+ * instruction). -+ */ -+ if (brightness) { -+ led_mc_calc_color_components(mc_cdev, brightness); -+ -+ /* -+ * Send color command only if brightness is non-zero and the RGB -+ * channel brightnesses changed. -+ */ -+ if (omnia_led_channels_changed(led)) -+ err = omnia_led_send_color_cmd(leds->client, led); -+ } - -- buf[0] = CMD_LED_COLOR; -- buf[1] = led->reg; -- buf[2] = mc_cdev->subled_info[0].brightness; -- buf[3] = mc_cdev->subled_info[1].brightness; -- buf[4] = mc_cdev->subled_info[2].brightness; -- -- state = CMD_LED_STATE_LED(led->reg); -- if (buf[2] || buf[3] || buf[4]) -- state |= CMD_LED_STATE_ON; -- -- ret = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state); -- if (ret >= 0 && (state & CMD_LED_STATE_ON)) -- ret = i2c_master_send(leds->client, buf, 5); -+ /* Send on/off state change only if (bool)brightness changed */ -+ if (!err && !brightness != !led->on) { -+ u8 state = CMD_LED_STATE_LED(led->reg); -+ -+ if (brightness) -+ state |= CMD_LED_STATE_ON; -+ -+ err = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state); -+ if (!err) -+ led->on = !!brightness; -+ } - - mutex_unlock(&leds->lock); - -- return ret; -+ return err; - } - - static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, -@@ -129,11 +177,15 @@ static int omnia_led_register(struct i2c - } - - led->subled_info[0].color_index = LED_COLOR_ID_RED; -- led->subled_info[0].channel = 0; - led->subled_info[1].color_index = LED_COLOR_ID_GREEN; -- led->subled_info[1].channel = 1; - led->subled_info[2].color_index = LED_COLOR_ID_BLUE; -- led->subled_info[2].channel = 2; -+ -+ /* Initial color is white */ -+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i) { -+ led->subled_info[i].intensity = 255; -+ led->subled_info[i].brightness = 255; -+ led->subled_info[i].channel = i; -+ } - - led->mc_cdev.subled_info = led->subled_info; - led->mc_cdev.num_colors = OMNIA_LED_NUM_CHANNELS; -@@ -162,6 +214,14 @@ static int omnia_led_register(struct i2c - return ret; - } - -+ /* Set initial color and cache it */ -+ ret = omnia_led_send_color_cmd(client, led); -+ if (ret < 0) { -+ dev_err(dev, "Cannot set LED %pOF initial color: %i\n", np, -+ ret); -+ return ret; -+ } -+ - ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev, - &init_data); - if (ret < 0) { diff --git a/target/linux/generic/backport-5.15/830-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch b/target/linux/generic/backport-5.15/830-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch deleted file mode 100644 index 7f6bac37dd15ec..00000000000000 --- a/target/linux/generic/backport-5.15/830-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch +++ /dev/null @@ -1,201 +0,0 @@ -From aaf38273cf766d88296f4aa3f2e4e3c0d399a4a2 Mon Sep 17 00:00:00 2001 -From: Marek Behún -Date: Mon, 18 Sep 2023 18:11:03 +0200 -Subject: leds: turris-omnia: Support HW controlled mode via private trigger -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add support for enabling MCU controlled mode of the Turris Omnia LEDs -via a LED private trigger called "omnia-mcu". Recall that private LED -triggers will only be listed in the sysfs trigger file for LEDs that -support them (currently there is no user of this mechanism). - -When in MCU controlled mode, the user can still set LED color, but the -blinking is done by MCU, which does different things for different LEDs: -- WAN LED is blinked according to the LED[0] pin of the WAN PHY -- LAN LEDs are blinked according to the LED[0] output of the - corresponding port of the LAN switch -- PCIe LEDs are blinked according to the logical OR of the MiniPCIe port - LED pins - -In the future I want to make the netdev trigger to transparently offload -the blinking to the HW if user sets compatible settings for the netdev -trigger (for LEDs associated with network devices). -There was some work on this already, and hopefully we will be able to -complete it sometime, but for now there are still multiple blockers for -this, and even if there weren't, we still would not be able to configure -HW controlled mode for the LEDs associated with MiniPCIe ports. - -In the meantime let's support HW controlled mode via the private LED -trigger mechanism. If, in the future, we manage to complete the netdev -trigger offloading, we can still keep this private trigger for backwards -compatibility, if needed. - -We also set "omnia-mcu" to cdev->default_trigger, so that the MCU keeps -control until the user first wants to take over it. If a different -default trigger is specified in device-tree via the -'linux,default-trigger' property, LED class will overwrite -cdev->default_trigger, and so the DT property will be respected. - -Signed-off-by: Marek Behún -Link: https://lore.kernel.org/r/20230918161104.20860-4-kabel@kernel.org -Signed-off-by: Lee Jones ---- - drivers/leds/Kconfig | 1 + - drivers/leds/leds-turris-omnia.c | 98 ++++++++++++++++++++++++++++++++++++---- - 2 files changed, 91 insertions(+), 8 deletions(-) - ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -164,6 +164,7 @@ config LEDS_TURRIS_OMNIA - depends on I2C - depends on MACH_ARMADA_38X || COMPILE_TEST - depends on OF -+ select LEDS_TRIGGERS - help - This option enables basic support for the LEDs found on the front - side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -31,7 +31,7 @@ struct omnia_led { - struct led_classdev_mc mc_cdev; - struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS]; - u8 cached_channels[OMNIA_LED_NUM_CHANNELS]; -- bool on; -+ bool on, hwtrig; - int reg; - }; - -@@ -120,12 +120,14 @@ static int omnia_led_brightness_set_bloc - - /* - * Only recalculate RGB brightnesses from intensities if brightness is -- * non-zero. Otherwise we won't be using them and we can save ourselves -- * some software divisions (Omnia's CPU does not implement the division -- * instruction). -+ * non-zero (if it is zero and the LED is in HW blinking mode, we use -+ * max_brightness as brightness). Otherwise we won't be using them and -+ * we can save ourselves some software divisions (Omnia's CPU does not -+ * implement the division instruction). - */ -- if (brightness) { -- led_mc_calc_color_components(mc_cdev, brightness); -+ if (brightness || led->hwtrig) { -+ led_mc_calc_color_components(mc_cdev, brightness ?: -+ cdev->max_brightness); - - /* - * Send color command only if brightness is non-zero and the RGB -@@ -135,8 +137,11 @@ static int omnia_led_brightness_set_bloc - err = omnia_led_send_color_cmd(leds->client, led); - } - -- /* Send on/off state change only if (bool)brightness changed */ -- if (!err && !brightness != !led->on) { -+ /* -+ * Send on/off state change only if (bool)brightness changed and the LED -+ * is not being blinked by HW. -+ */ -+ if (!err && !led->hwtrig && !brightness != !led->on) { - u8 state = CMD_LED_STATE_LED(led->reg); - - if (brightness) -@@ -152,6 +157,71 @@ static int omnia_led_brightness_set_bloc - return err; - } - -+static struct led_hw_trigger_type omnia_hw_trigger_type; -+ -+static int omnia_hwtrig_activate(struct led_classdev *cdev) -+{ -+ struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); -+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); -+ struct omnia_led *led = to_omnia_led(mc_cdev); -+ int err = 0; -+ -+ mutex_lock(&leds->lock); -+ -+ if (!led->on) { -+ /* -+ * If the LED is off (brightness was set to 0), the last -+ * configured color was not necessarily sent to the MCU. -+ * Recompute with max_brightness and send if needed. -+ */ -+ led_mc_calc_color_components(mc_cdev, cdev->max_brightness); -+ -+ if (omnia_led_channels_changed(led)) -+ err = omnia_led_send_color_cmd(leds->client, led); -+ } -+ -+ if (!err) { -+ /* Put the LED into MCU controlled mode */ -+ err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE, -+ CMD_LED_MODE_LED(led->reg)); -+ if (!err) -+ led->hwtrig = true; -+ } -+ -+ mutex_unlock(&leds->lock); -+ -+ return err; -+} -+ -+static void omnia_hwtrig_deactivate(struct led_classdev *cdev) -+{ -+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); -+ struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev)); -+ int err; -+ -+ mutex_lock(&leds->lock); -+ -+ led->hwtrig = false; -+ -+ /* Put the LED into software mode */ -+ err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE, -+ CMD_LED_MODE_LED(led->reg) | -+ CMD_LED_MODE_USER); -+ -+ mutex_unlock(&leds->lock); -+ -+ if (err < 0) -+ dev_err(cdev->dev, "Cannot put LED to software mode: %i\n", -+ err); -+} -+ -+static struct led_trigger omnia_hw_trigger = { -+ .name = "omnia-mcu", -+ .activate = omnia_hwtrig_activate, -+ .deactivate = omnia_hwtrig_deactivate, -+ .trigger_type = &omnia_hw_trigger_type, -+}; -+ - static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, - struct device_node *np) - { -@@ -195,6 +265,12 @@ static int omnia_led_register(struct i2c - cdev = &led->mc_cdev.led_cdev; - cdev->max_brightness = 255; - cdev->brightness_set_blocking = omnia_led_brightness_set_blocking; -+ cdev->trigger_type = &omnia_hw_trigger_type; -+ /* -+ * Use the omnia-mcu trigger as the default trigger. It may be rewritten -+ * by LED class from the linux,default-trigger property. -+ */ -+ cdev->default_trigger = omnia_hw_trigger.name; - - /* put the LED into software mode */ - ret = omnia_cmd_write_u8(client, CMD_LED_MODE, -@@ -309,6 +385,12 @@ static int omnia_leds_probe(struct i2c_c - - mutex_init(&leds->lock); - -+ ret = devm_led_trigger_register(dev, &omnia_hw_trigger); -+ if (ret < 0) { -+ dev_err(dev, "Cannot register private LED trigger: %d\n", ret); -+ return ret; -+ } -+ - led = &leds->leds[0]; - for_each_available_child_of_node(np, child) { - ret = omnia_led_register(client, led, child); diff --git a/target/linux/generic/backport-5.15/830-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch b/target/linux/generic/backport-5.15/830-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch deleted file mode 100644 index 3bda4a9cef7c5f..00000000000000 --- a/target/linux/generic/backport-5.15/830-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch +++ /dev/null @@ -1,244 +0,0 @@ -From 00125699bb35ef58fffa8425e32a44a7af82cd28 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Mon, 18 Sep 2023 18:11:04 +0200 -Subject: [PATCH 07/17] leds: turris-omnia: Add support for enabling/disabling - HW gamma correction -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If the MCU on Turris Omnia is running newer firmware versions, the LED -controller supports RGB gamma correction (and enables it by default for -newer boards). - -Determine whether the gamma correction setting feature is supported and -add the ability to set it via sysfs attribute file. - -Signed-off-by: Marek Behún -Link: https://lore.kernel.org/r/20230918161104.20860-5-kabel@kernel.org -Signed-off-by: Lee Jones ---- - .../sysfs-class-led-driver-turris-omnia | 14 ++ - drivers/leds/leds-turris-omnia.c | 137 +++++++++++++++--- - 2 files changed, 134 insertions(+), 17 deletions(-) - ---- a/Documentation/ABI/testing/sysfs-class-led-driver-turris-omnia -+++ b/Documentation/ABI/testing/sysfs-class-led-driver-turris-omnia -@@ -12,3 +12,17 @@ Description: (RW) On the front panel of - able to change this setting from software. - - Format: %i -+ -+What: /sys/class/leds//device/gamma_correction -+Date: August 2023 -+KernelVersion: 6.6 -+Contact: Marek Behún -+Description: (RW) Newer versions of the microcontroller firmware of the -+ Turris Omnia router support gamma correction for the RGB LEDs. -+ This feature can be enabled/disabled by writing to this file. -+ -+ If the feature is not supported because the MCU firmware is too -+ old, the file always reads as 0, and writing to the file results -+ in the EOPNOTSUPP error. -+ -+ Format: %i ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -15,17 +15,30 @@ - #define OMNIA_BOARD_LEDS 12 - #define OMNIA_LED_NUM_CHANNELS 3 - --#define CMD_LED_MODE 3 --#define CMD_LED_MODE_LED(l) ((l) & 0x0f) --#define CMD_LED_MODE_USER 0x10 -- --#define CMD_LED_STATE 4 --#define CMD_LED_STATE_LED(l) ((l) & 0x0f) --#define CMD_LED_STATE_ON 0x10 -- --#define CMD_LED_COLOR 5 --#define CMD_LED_SET_BRIGHTNESS 7 --#define CMD_LED_GET_BRIGHTNESS 8 -+/* MCU controller commands at I2C address 0x2a */ -+#define OMNIA_MCU_I2C_ADDR 0x2a -+ -+#define CMD_GET_STATUS_WORD 0x01 -+#define STS_FEATURES_SUPPORTED BIT(2) -+ -+#define CMD_GET_FEATURES 0x10 -+#define FEAT_LED_GAMMA_CORRECTION BIT(5) -+ -+/* LED controller commands at I2C address 0x2b */ -+#define CMD_LED_MODE 0x03 -+#define CMD_LED_MODE_LED(l) ((l) & 0x0f) -+#define CMD_LED_MODE_USER 0x10 -+ -+#define CMD_LED_STATE 0x04 -+#define CMD_LED_STATE_LED(l) ((l) & 0x0f) -+#define CMD_LED_STATE_ON 0x10 -+ -+#define CMD_LED_COLOR 0x05 -+#define CMD_LED_SET_BRIGHTNESS 0x07 -+#define CMD_LED_GET_BRIGHTNESS 0x08 -+ -+#define CMD_SET_GAMMA_CORRECTION 0x30 -+#define CMD_GET_GAMMA_CORRECTION 0x31 - - struct omnia_led { - struct led_classdev_mc mc_cdev; -@@ -40,6 +53,7 @@ struct omnia_led { - struct omnia_leds { - struct i2c_client *client; - struct mutex lock; -+ bool has_gamma_correction; - struct omnia_led leds[]; - }; - -@@ -50,30 +64,42 @@ static int omnia_cmd_write_u8(const stru - return i2c_master_send(client, buf, sizeof(buf)); - } - --static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd) -+static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd, -+ void *reply, size_t len) - { - struct i2c_msg msgs[2]; -- u8 reply; - int ret; - -- msgs[0].addr = client->addr; -+ msgs[0].addr = addr; - msgs[0].flags = 0; - msgs[0].len = 1; - msgs[0].buf = &cmd; -- msgs[1].addr = client->addr; -+ msgs[1].addr = addr; - msgs[1].flags = I2C_M_RD; -- msgs[1].len = 1; -- msgs[1].buf = &reply; -+ msgs[1].len = len; -+ msgs[1].buf = reply; - -- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); -+ ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)); - if (likely(ret == ARRAY_SIZE(msgs))) -- return reply; -+ return len; - else if (ret < 0) - return ret; - else - return -EIO; - } - -+static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd) -+{ -+ u8 reply; -+ int ret; -+ -+ ret = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1); -+ if (ret < 0) -+ return ret; -+ -+ return reply; -+} -+ - static int omnia_led_send_color_cmd(const struct i2c_client *client, - struct omnia_led *led) - { -@@ -352,12 +378,74 @@ static ssize_t brightness_store(struct d - } - static DEVICE_ATTR_RW(brightness); - -+static ssize_t gamma_correction_show(struct device *dev, -+ struct device_attribute *a, char *buf) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct omnia_leds *leds = i2c_get_clientdata(client); -+ int ret; -+ -+ if (leds->has_gamma_correction) { -+ ret = omnia_cmd_read_u8(client, CMD_GET_GAMMA_CORRECTION); -+ if (ret < 0) -+ return ret; -+ } else { -+ ret = 0; -+ } -+ -+ return sysfs_emit(buf, "%d\n", !!ret); -+} -+ -+static ssize_t gamma_correction_store(struct device *dev, -+ struct device_attribute *a, -+ const char *buf, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct omnia_leds *leds = i2c_get_clientdata(client); -+ bool val; -+ int ret; -+ -+ if (!leds->has_gamma_correction) -+ return -EOPNOTSUPP; -+ -+ if (kstrtobool(buf, &val) < 0) -+ return -EINVAL; -+ -+ ret = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val); -+ -+ return ret < 0 ? ret : count; -+} -+static DEVICE_ATTR_RW(gamma_correction); -+ - static struct attribute *omnia_led_controller_attrs[] = { - &dev_attr_brightness.attr, -+ &dev_attr_gamma_correction.attr, - NULL, - }; - ATTRIBUTE_GROUPS(omnia_led_controller); - -+static int omnia_mcu_get_features(const struct i2c_client *client) -+{ -+ u16 reply; -+ int err; -+ -+ err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR, -+ CMD_GET_STATUS_WORD, &reply, sizeof(reply)); -+ if (err < 0) -+ return err; -+ -+ /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */ -+ if (!(le16_to_cpu(reply) & STS_FEATURES_SUPPORTED)) -+ return 0; -+ -+ err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR, -+ CMD_GET_FEATURES, &reply, sizeof(reply)); -+ if (err < 0) -+ return err; -+ -+ return le16_to_cpu(reply); -+} -+ - static int omnia_leds_probe(struct i2c_client *client, - const struct i2c_device_id *id) - { -@@ -383,6 +471,21 @@ static int omnia_leds_probe(struct i2c_c - leds->client = client; - i2c_set_clientdata(client, leds); - -+ ret = omnia_mcu_get_features(client); -+ if (ret < 0) { -+ dev_err(dev, "Cannot determine MCU supported features: %d\n", -+ ret); -+ return ret; -+ } -+ -+ leds->has_gamma_correction = ret & FEAT_LED_GAMMA_CORRECTION; -+ if (!leds->has_gamma_correction) { -+ dev_info(dev, -+ "Your board's MCU firmware does not support the LED gamma correction feature.\n"); -+ dev_info(dev, -+ "Consider upgrading MCU firmware with the omnia-mcutool utility.\n"); -+ } -+ - mutex_init(&leds->lock); - - ret = devm_led_trigger_register(dev, &omnia_hw_trigger); diff --git a/target/linux/generic/backport-5.15/830-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch b/target/linux/generic/backport-5.15/830-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch deleted file mode 100644 index ec6171ec67afb6..00000000000000 --- a/target/linux/generic/backport-5.15/830-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 33f339b70f020273ea40fb3c5d7b65697446bd6c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Mon, 16 Oct 2023 15:28:06 +0200 -Subject: [PATCH 08/17] leds: turris-omnia: Fix brightness setting and trigger - activating -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -I have improperly refactored commits - 4d5ed2621c24 ("leds: turris-omnia: Make set_brightness() more efficient") -and - aaf38273cf76 ("leds: turris-omnia: Support HW controlled mode via private trigger") -after Lee requested a change in API semantics of the new functions I -introduced in commit - 28350bc0ac77 ("leds: turris-omnia: Do not use SMBUS calls"). - -Before the change, the function omnia_cmd_write_u8() returned 0 on -success, and afterwards it returned a positive value (number of bytes -written). The latter version was applied, but the following commits did -not properly account for this change. - -This results in non-functional LED's .brightness_set_blocking() and -trigger's .activate() methods. - -The main reasoning behind the semantics change was that read/write -methods should return the number of read/written bytes on success. -It was pointed to me [1] that this is not always true (for example the -regmap API does not do so), and since the driver never uses this number -of read/written bytes information, I decided to fix this issue by -changing the functions to the original semantics (return 0 on success). - -[1] https://lore.kernel.org/linux-gpio/ZQnn+Gi0xVlsGCYA@smile.fi.intel.com/ - -Fixes: 28350bc0ac77 ("leds: turris-omnia: Do not use SMBUS calls") -Signed-off-by: Marek Behún ---- - drivers/leds/leds-turris-omnia.c | 37 +++++++++++++++++--------------- - 1 file changed, 20 insertions(+), 17 deletions(-) - ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -60,8 +60,11 @@ struct omnia_leds { - static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val) - { - u8 buf[2] = { cmd, val }; -+ int ret; -+ -+ ret = i2c_master_send(client, buf, sizeof(buf)); - -- return i2c_master_send(client, buf, sizeof(buf)); -+ return ret < 0 ? ret : 0; - } - - static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd, -@@ -81,7 +84,7 @@ static int omnia_cmd_read_raw(struct i2c - - ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)); - if (likely(ret == ARRAY_SIZE(msgs))) -- return len; -+ return 0; - else if (ret < 0) - return ret; - else -@@ -91,11 +94,11 @@ static int omnia_cmd_read_raw(struct i2c - static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd) - { - u8 reply; -- int ret; -+ int err; - -- ret = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1); -- if (ret < 0) -- return ret; -+ err = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1); -+ if (err) -+ return err; - - return reply; - } -@@ -236,7 +239,7 @@ static void omnia_hwtrig_deactivate(stru - - mutex_unlock(&leds->lock); - -- if (err < 0) -+ if (err) - dev_err(cdev->dev, "Cannot put LED to software mode: %i\n", - err); - } -@@ -302,7 +305,7 @@ static int omnia_led_register(struct i2c - ret = omnia_cmd_write_u8(client, CMD_LED_MODE, - CMD_LED_MODE_LED(led->reg) | - CMD_LED_MODE_USER); -- if (ret < 0) { -+ if (ret) { - dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np, - ret); - return ret; -@@ -311,7 +314,7 @@ static int omnia_led_register(struct i2c - /* disable the LED */ - ret = omnia_cmd_write_u8(client, CMD_LED_STATE, - CMD_LED_STATE_LED(led->reg)); -- if (ret < 0) { -+ if (ret) { - dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret); - return ret; - } -@@ -364,7 +367,7 @@ static ssize_t brightness_store(struct d - { - struct i2c_client *client = to_i2c_client(dev); - unsigned long brightness; -- int ret; -+ int err; - - if (kstrtoul(buf, 10, &brightness)) - return -EINVAL; -@@ -372,9 +375,9 @@ static ssize_t brightness_store(struct d - if (brightness > 100) - return -EINVAL; - -- ret = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness); -+ err = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness); - -- return ret < 0 ? ret : count; -+ return err ?: count; - } - static DEVICE_ATTR_RW(brightness); - -@@ -403,7 +406,7 @@ static ssize_t gamma_correction_store(st - struct i2c_client *client = to_i2c_client(dev); - struct omnia_leds *leds = i2c_get_clientdata(client); - bool val; -- int ret; -+ int err; - - if (!leds->has_gamma_correction) - return -EOPNOTSUPP; -@@ -411,9 +414,9 @@ static ssize_t gamma_correction_store(st - if (kstrtobool(buf, &val) < 0) - return -EINVAL; - -- ret = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val); -+ err = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val); - -- return ret < 0 ? ret : count; -+ return err ?: count; - } - static DEVICE_ATTR_RW(gamma_correction); - -@@ -431,7 +434,7 @@ static int omnia_mcu_get_features(const - - err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR, - CMD_GET_STATUS_WORD, &reply, sizeof(reply)); -- if (err < 0) -+ if (err) - return err; - - /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */ -@@ -440,7 +443,7 @@ static int omnia_mcu_get_features(const - - err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR, - CMD_GET_FEATURES, &reply, sizeof(reply)); -- if (err < 0) -+ if (err) - return err; - - return le16_to_cpu(reply); diff --git a/target/linux/generic/backport-5.15/831-v6.1-dt-bindings-leds-Expand-LED_COLOR_ID-definitions.patch b/target/linux/generic/backport-5.15/831-v6.1-dt-bindings-leds-Expand-LED_COLOR_ID-definitions.patch deleted file mode 100644 index c2a938c614f7fe..00000000000000 --- a/target/linux/generic/backport-5.15/831-v6.1-dt-bindings-leds-Expand-LED_COLOR_ID-definitions.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 472d7b9e8141729ec1e3fe6821b88563f6379533 Mon Sep 17 00:00:00 2001 -From: Olliver Schinagl -Date: Tue, 30 Aug 2022 15:46:13 +0200 -Subject: [PATCH] dt-bindings: leds: Expand LED_COLOR_ID definitions - -In commit 853a78a7d6c7 (dt-bindings: leds: Add LED_COLOR_ID definitions, -Sun Jun 9 20:19:04 2019 +0200) the most basic color definitions where -added. However, there's a little more very common LED colors. - -While the documentation states 'add what is missing', engineers tend to -be lazy and will just use what currently exists. So this patch will take -(a) list from online retailers [0], [1], [2] and use the common LED colors from -there, this being reasonable as this is what is currently available to purchase. - -Note, that LIME seems to be the modern take to 'Yellow-green' or -'Yellowish-green' from some older datasheets. - -[0]: https://www.digikey.com/en/products/filter/led-lighting-color/125 -[1]: https://eu.mouser.com/c/optoelectronics/led-lighting/led-emitters/standard-leds-smd -[2]: https://nl.farnell.com/en-NL/c/optoelectronics-displays/led-products/standard-single-colour-leds-under-75ma - -Signed-off-by: Olliver Schinagl -Acked-by: Krzysztof Kozlowski -Acked-by: Alexander Dahl -Acked-by: Jacek Anaszewski -Link: https://lore.kernel.org/r/20220830134613.1564059-1-oliver@schinagl.nl -Signed-off-by: Rob Herring ---- - include/dt-bindings/leds/common.h | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/include/dt-bindings/leds/common.h -+++ b/include/dt-bindings/leds/common.h -@@ -33,7 +33,12 @@ - #define LED_COLOR_ID_MULTI 8 /* For multicolor LEDs */ - #define LED_COLOR_ID_RGB 9 /* For multicolor LEDs that can do arbitrary color, - so this would include RGBW and similar */ --#define LED_COLOR_ID_MAX 10 -+#define LED_COLOR_ID_PURPLE 10 -+#define LED_COLOR_ID_ORANGE 11 -+#define LED_COLOR_ID_PINK 12 -+#define LED_COLOR_ID_CYAN 13 -+#define LED_COLOR_ID_LIME 14 -+#define LED_COLOR_ID_MAX 15 - - /* Standard LED functions */ - /* Keyboard LEDs, usually it would be input4::capslock etc. */ diff --git a/target/linux/generic/backport-5.15/832-v6.8-of-device-Export-of_device_make_bus_id.patch b/target/linux/generic/backport-5.15/832-v6.8-of-device-Export-of_device_make_bus_id.patch deleted file mode 100644 index d097c1b0f45d45..00000000000000 --- a/target/linux/generic/backport-5.15/832-v6.8-of-device-Export-of_device_make_bus_id.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 7f38b70042fcaa49219045bd1a9a2836e27a58ac Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:27 +0000 -Subject: [PATCH] of: device: Export of_device_make_bus_id() - -This helper is really handy to create unique device names based on their -device tree path, we may need it outside of the OF core (in the NVMEM -subsystem) so let's export it. As this helper has nothing patform -specific, let's move it to of/device.c instead of of/platform.c so we -can add its prototype to of_device.h. - -Signed-off-by: Miquel Raynal -Acked-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/device.c | 41 +++++++++++++++++++++++++++++++++++++++ - drivers/of/platform.c | 40 -------------------------------------- - include/linux/of_device.h | 6 ++++++ - 3 files changed, 47 insertions(+), 40 deletions(-) - ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -337,3 +337,38 @@ int of_device_uevent_modalias(struct dev - return 0; - } - EXPORT_SYMBOL_GPL(of_device_uevent_modalias); -+ -+/** -+ * of_device_make_bus_id - Use the device node data to assign a unique name -+ * @dev: pointer to device structure that is linked to a device tree node -+ * -+ * This routine will first try using the translated bus address to -+ * derive a unique name. If it cannot, then it will prepend names from -+ * parent nodes until a unique name can be derived. -+ */ -+void of_device_make_bus_id(struct device *dev) -+{ -+ struct device_node *node = dev->of_node; -+ const __be32 *reg; -+ u64 addr; -+ -+ /* Construct the name, using parent nodes if necessary to ensure uniqueness */ -+ while (node->parent) { -+ /* -+ * If the address can be translated, then that is as much -+ * uniqueness as we need. Make it the first component and return -+ */ -+ reg = of_get_property(node, "reg", NULL); -+ if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) { -+ dev_set_name(dev, dev_name(dev) ? "%llx.%pOFn:%s" : "%llx.%pOFn", -+ addr, node, dev_name(dev)); -+ return; -+ } -+ -+ /* format arguments only used if dev_name() resolves to NULL */ -+ dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s", -+ kbasename(node->full_name), dev_name(dev)); -+ node = node->parent; -+ } -+} -+EXPORT_SYMBOL_GPL(of_device_make_bus_id); ---- a/drivers/of/platform.c -+++ b/drivers/of/platform.c -@@ -64,40 +64,6 @@ EXPORT_SYMBOL(of_find_device_by_node); - */ - - /** -- * of_device_make_bus_id - Use the device node data to assign a unique name -- * @dev: pointer to device structure that is linked to a device tree node -- * -- * This routine will first try using the translated bus address to -- * derive a unique name. If it cannot, then it will prepend names from -- * parent nodes until a unique name can be derived. -- */ --static void of_device_make_bus_id(struct device *dev) --{ -- struct device_node *node = dev->of_node; -- const __be32 *reg; -- u64 addr; -- -- /* Construct the name, using parent nodes if necessary to ensure uniqueness */ -- while (node->parent) { -- /* -- * If the address can be translated, then that is as much -- * uniqueness as we need. Make it the first component and return -- */ -- reg = of_get_property(node, "reg", NULL); -- if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) { -- dev_set_name(dev, dev_name(dev) ? "%llx.%pOFn:%s" : "%llx.%pOFn", -- addr, node, dev_name(dev)); -- return; -- } -- -- /* format arguments only used if dev_name() resolves to NULL */ -- dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s", -- kbasename(node->full_name), dev_name(dev)); -- node = node->parent; -- } --} -- --/** - * of_device_alloc - Allocate and initialize an of_device - * @np: device node to assign to device - * @bus_id: Name to assign to the device. May be null to use default name. ---- a/include/linux/of_device.h -+++ b/include/linux/of_device.h -@@ -56,6 +56,9 @@ static inline int of_dma_configure(struc - { - return of_dma_configure_id(dev, np, force_dma, NULL); - } -+ -+void of_device_make_bus_id(struct device *dev); -+ - #else /* CONFIG_OF */ - - static inline int of_driver_match_device(struct device *dev, -@@ -113,6 +116,9 @@ static inline int of_dma_configure(struc - { - return 0; - } -+ -+static inline void of_device_make_bus_id(struct device *dev) {} -+ - #endif /* CONFIG_OF */ - - #endif /* _LINUX_OF_DEVICE_H */ diff --git a/target/linux/generic/backport-5.15/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch b/target/linux/generic/backport-5.15/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch deleted file mode 100644 index b71df6fa5726da..00000000000000 --- a/target/linux/generic/backport-5.15/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a067943129b4ec6b835e02cfd5fbef01093c1471 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 8 Oct 2023 16:40:13 +0200 -Subject: [PATCH] leds: core: Add more colors from DT bindings to led_colors - -The colors are already part of DT bindings. Make sure the kernel is -able to convert them to strings. - -Signed-off-by: Ondrej Jirman -Link: https://lore.kernel.org/r/20231008144014.1180334-1-megi@xff.cz -Signed-off-by: Lee Jones ---- - drivers/leds/led-core.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/leds/led-core.c -+++ b/drivers/leds/led-core.c -@@ -36,6 +36,11 @@ const char * const led_colors[LED_COLOR_ - [LED_COLOR_ID_IR] = "ir", - [LED_COLOR_ID_MULTI] = "multicolor", - [LED_COLOR_ID_RGB] = "rgb", -+ [LED_COLOR_ID_PURPLE] = "purple", -+ [LED_COLOR_ID_ORANGE] = "orange", -+ [LED_COLOR_ID_PINK] = "pink", -+ [LED_COLOR_ID_CYAN] = "cyan", -+ [LED_COLOR_ID_LIME] = "lime", - }; - EXPORT_SYMBOL_GPL(led_colors); - diff --git a/target/linux/generic/backport-5.15/834-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch b/target/linux/generic/backport-5.15/834-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch deleted file mode 100644 index 2093fac8a125c2..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 4a1a40233b4a9fc159a5c7a27dc34c5c7bc5be55 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:28 +0000 -Subject: [PATCH] nvmem: Move of_nvmem_layout_get_container() in another header - -nvmem-consumer.h is included by consumer devices, extracting data from -NVMEM devices whereas nvmem-provider.h is included by devices providing -NVMEM content. - -The only users of of_nvmem_layout_get_container() outside of the core -are layout drivers, so better move its prototype to nvmem-provider.h. - -While we do so, we also move the kdoc associated with the function to -the header rather than the .c file. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 8 -------- - include/linux/nvmem-consumer.h | 7 ------- - include/linux/nvmem-provider.h | 21 +++++++++++++++++++++ - 3 files changed, 21 insertions(+), 15 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -848,14 +848,6 @@ static int nvmem_add_cells_from_layout(s - } - - #if IS_ENABLED(CONFIG_OF) --/** -- * of_nvmem_layout_get_container() - Get OF node to layout container. -- * -- * @nvmem: nvmem device. -- * -- * Return: a node pointer with refcount incremented or NULL if no -- * container exists. Use of_node_put() on it when done. -- */ - struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) - { - return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -241,7 +241,6 @@ struct nvmem_cell *of_nvmem_cell_get(str - const char *id); - struct nvmem_device *of_nvmem_device_get(struct device_node *np, - const char *name); --struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem); - #else - static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, - const char *id) -@@ -254,12 +253,6 @@ static inline struct nvmem_device *of_nv - { - return ERR_PTR(-EOPNOTSUPP); - } -- --static inline struct device_node * --of_nvmem_layout_get_container(struct nvmem_device *nvmem) --{ -- return NULL; --} - #endif /* CONFIG_NVMEM && CONFIG_OF */ - - #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */ ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -244,6 +244,27 @@ nvmem_layout_get_match_data(struct nvmem - - #endif /* CONFIG_NVMEM */ - -+#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF) -+ -+/** -+ * of_nvmem_layout_get_container() - Get OF node of layout container -+ * -+ * @nvmem: nvmem device -+ * -+ * Return: a node pointer with refcount incremented or NULL if no -+ * container exists. Use of_node_put() on it when done. -+ */ -+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem); -+ -+#else /* CONFIG_NVMEM && CONFIG_OF */ -+ -+static inline struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) -+{ -+ return NULL; -+} -+ -+#endif /* CONFIG_NVMEM && CONFIG_OF */ -+ - #define module_nvmem_layout_driver(__layout_driver) \ - module_driver(__layout_driver, nvmem_layout_register, \ - nvmem_layout_unregister) diff --git a/target/linux/generic/backport-5.15/834-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch b/target/linux/generic/backport-5.15/834-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch deleted file mode 100644 index e722109f919552..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch +++ /dev/null @@ -1,91 +0,0 @@ -From ec9c08a1cb8dc5e8e003f95f5f62de41dde235bb Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:29 +0000 -Subject: [PATCH] nvmem: Create a header for internal sharing - -Before adding all the NVMEM layout bus infrastructure to the core, let's -move the main nvmem_device structure in an internal header, only -available to the core. This way all the additional code can be added in -a dedicated file in order to keep the current core file tidy. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 24 +----------------------- - drivers/nvmem/internals.h | 35 +++++++++++++++++++++++++++++++++++ - 2 files changed, 36 insertions(+), 23 deletions(-) - create mode 100644 drivers/nvmem/internals.h - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -20,29 +20,7 @@ - #include - #include - --struct nvmem_device { -- struct module *owner; -- struct device dev; -- int stride; -- int word_size; -- int id; -- struct kref refcnt; -- size_t size; -- bool read_only; -- bool root_only; -- int flags; -- enum nvmem_type type; -- struct bin_attribute eeprom; -- struct device *base_dev; -- struct list_head cells; -- const struct nvmem_keepout *keepout; -- unsigned int nkeepout; -- nvmem_reg_read_t reg_read; -- nvmem_reg_write_t reg_write; -- struct gpio_desc *wp_gpio; -- struct nvmem_layout *layout; -- void *priv; --}; -+#include "internals.h" - - #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) - ---- /dev/null -+++ b/drivers/nvmem/internals.h -@@ -0,0 +1,35 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+#ifndef _LINUX_NVMEM_INTERNALS_H -+#define _LINUX_NVMEM_INTERNALS_H -+ -+#include -+#include -+#include -+ -+struct nvmem_device { -+ struct module *owner; -+ struct device dev; -+ struct list_head node; -+ int stride; -+ int word_size; -+ int id; -+ struct kref refcnt; -+ size_t size; -+ bool read_only; -+ bool root_only; -+ int flags; -+ enum nvmem_type type; -+ struct bin_attribute eeprom; -+ struct device *base_dev; -+ struct list_head cells; -+ const struct nvmem_keepout *keepout; -+ unsigned int nkeepout; -+ nvmem_reg_read_t reg_read; -+ nvmem_reg_write_t reg_write; -+ struct gpio_desc *wp_gpio; -+ struct nvmem_layout *layout; -+ void *priv; -+}; -+ -+#endif /* ifndef _LINUX_NVMEM_INTERNALS_H */ diff --git a/target/linux/generic/backport-5.15/834-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch b/target/linux/generic/backport-5.15/834-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch deleted file mode 100644 index db2d8c1b46ed70..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 1b7c298a4ecbc28cc6ee94005734bff55eb83d22 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:30 +0000 -Subject: [PATCH] nvmem: Simplify the ->add_cells() hook - -The layout entry is not used and will anyway be made useless by the new -layout bus infrastructure coming next, so drop it. While at it, clarify -the kdoc entry. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - drivers/nvmem/layouts/onie-tlv.c | 3 +-- - drivers/nvmem/layouts/sl28vpd.c | 3 +-- - include/linux/nvmem-provider.h | 8 +++----- - 4 files changed, 6 insertions(+), 10 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -817,7 +817,7 @@ static int nvmem_add_cells_from_layout(s - int ret; - - if (layout && layout->add_cells) { -- ret = layout->add_cells(&nvmem->dev, nvmem, layout); -+ ret = layout->add_cells(&nvmem->dev, nvmem); - if (ret) - return ret; - } ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -182,8 +182,7 @@ static bool onie_tlv_crc_is_valid(struct - return true; - } - --static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem, -- struct nvmem_layout *layout) -+static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem) - { - struct onie_tlv_hdr hdr; - size_t table_len, data_len, hdr_len; ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -80,8 +80,7 @@ static int sl28vpd_v1_check_crc(struct d - return 0; - } - --static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem, -- struct nvmem_layout *layout) -+static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem) - { - const struct nvmem_cell_info *pinfo; - struct nvmem_cell_info info = {0}; ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -156,9 +156,8 @@ struct nvmem_cell_table { - * - * @name: Layout name. - * @of_match_table: Open firmware match table. -- * @add_cells: Will be called if a nvmem device is found which -- * has this layout. The function will add layout -- * specific cells with nvmem_add_one_cell(). -+ * @add_cells: Called to populate the layout using -+ * nvmem_add_one_cell(). - * @fixup_cell_info: Will be called before a cell is added. Can be - * used to modify the nvmem_cell_info. - * @owner: Pointer to struct module. -@@ -172,8 +171,7 @@ struct nvmem_cell_table { - struct nvmem_layout { - const char *name; - const struct of_device_id *of_match_table; -- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, -- struct nvmem_layout *layout); -+ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem); - void (*fixup_cell_info)(struct nvmem_device *nvmem, - struct nvmem_layout *layout, - struct nvmem_cell_info *cell); diff --git a/target/linux/generic/backport-5.15/834-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch b/target/linux/generic/backport-5.15/834-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch deleted file mode 100644 index 65aa37f8344e6d..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 1172460e716784ac7e1049a537bdca8edbf97360 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:31 +0000 -Subject: [PATCH] nvmem: Move and rename ->fixup_cell_info() - -This hook is meant to be used by any provider and instantiating a layout -just for this is useless. Let's instead move this hook to the nvmem -device and add it to the config structure to be easily shared by the -providers. - -While at moving this hook, rename it ->fixup_dt_cell_info() to clarify -its main intended purpose. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 6 +++--- - drivers/nvmem/imx-ocotp.c | 11 +++-------- - drivers/nvmem/internals.h | 2 ++ - drivers/nvmem/mtk-efuse.c | 11 +++-------- - include/linux/nvmem-provider.h | 9 ++++----- - 5 files changed, 15 insertions(+), 24 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -676,7 +676,6 @@ static int nvmem_validate_keepouts(struc - - static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) - { -- struct nvmem_layout *layout = nvmem->layout; - struct device *dev = &nvmem->dev; - struct device_node *child; - const __be32 *addr; -@@ -706,8 +705,8 @@ static int nvmem_add_cells_from_dt(struc - - info.np = of_node_get(child); - -- if (layout && layout->fixup_cell_info) -- layout->fixup_cell_info(nvmem, layout, &info); -+ if (nvmem->fixup_dt_cell_info) -+ nvmem->fixup_dt_cell_info(nvmem, &info); - - ret = nvmem_add_one_cell(nvmem, &info); - kfree(info.name); -@@ -896,6 +895,7 @@ struct nvmem_device *nvmem_register(cons - - kref_init(&nvmem->refcnt); - INIT_LIST_HEAD(&nvmem->cells); -+ nvmem->fixup_dt_cell_info = config->fixup_dt_cell_info; - - nvmem->owner = config->owner; - if (!nvmem->owner && config->dev->driver) ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -584,17 +584,12 @@ static const struct of_device_id imx_oco - }; - MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids); - --static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem, -- struct nvmem_layout *layout, -- struct nvmem_cell_info *cell) -+static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem, -+ struct nvmem_cell_info *cell) - { - cell->read_post_process = imx_ocotp_cell_pp; - } - --static struct nvmem_layout imx_ocotp_layout = { -- .fixup_cell_info = imx_ocotp_fixup_cell_info, --}; -- - static int imx_ocotp_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -620,7 +615,7 @@ static int imx_ocotp_probe(struct platfo - imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; - imx_ocotp_nvmem_config.dev = dev; - imx_ocotp_nvmem_config.priv = priv; -- imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; -+ imx_ocotp_nvmem_config.fixup_dt_cell_info = &imx_ocotp_fixup_dt_cell_info; - - priv->config = &imx_ocotp_nvmem_config; - ---- a/drivers/nvmem/internals.h -+++ b/drivers/nvmem/internals.h -@@ -23,6 +23,8 @@ struct nvmem_device { - struct bin_attribute eeprom; - struct device *base_dev; - struct list_head cells; -+ void (*fixup_dt_cell_info)(struct nvmem_device *nvmem, -+ struct nvmem_cell_info *cell); - const struct nvmem_keepout *keepout; - unsigned int nkeepout; - nvmem_reg_read_t reg_read; ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -45,9 +45,8 @@ static int mtk_efuse_gpu_speedbin_pp(voi - return 0; - } - --static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem, -- struct nvmem_layout *layout, -- struct nvmem_cell_info *cell) -+static void mtk_efuse_fixup_dt_cell_info(struct nvmem_device *nvmem, -+ struct nvmem_cell_info *cell) - { - size_t sz = strlen(cell->name); - -@@ -61,10 +60,6 @@ static void mtk_efuse_fixup_cell_info(st - cell->read_post_process = mtk_efuse_gpu_speedbin_pp; - } - --static struct nvmem_layout mtk_efuse_layout = { -- .fixup_cell_info = mtk_efuse_fixup_cell_info, --}; -- - static int mtk_efuse_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -91,7 +86,7 @@ static int mtk_efuse_probe(struct platfo - econfig.priv = priv; - econfig.dev = dev; - if (pdata->uses_post_processing) -- econfig.layout = &mtk_efuse_layout; -+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info; - nvmem = devm_nvmem_register(dev, &econfig); - - return PTR_ERR_OR_ZERO(nvmem); ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -83,6 +83,8 @@ struct nvmem_cell_info { - * @cells: Optional array of pre-defined NVMEM cells. - * @ncells: Number of elements in cells. - * @add_legacy_fixed_of_cells: Read fixed NVMEM cells from old OF syntax. -+ * @fixup_dt_cell_info: Will be called before a cell is added. Can be -+ * used to modify the nvmem_cell_info. - * @keepout: Optional array of keepout ranges (sorted ascending by start). - * @nkeepout: Number of elements in the keepout array. - * @type: Type of the nvmem storage -@@ -113,6 +115,8 @@ struct nvmem_config { - const struct nvmem_cell_info *cells; - int ncells; - bool add_legacy_fixed_of_cells; -+ void (*fixup_dt_cell_info)(struct nvmem_device *nvmem, -+ struct nvmem_cell_info *cell); - const struct nvmem_keepout *keepout; - unsigned int nkeepout; - enum nvmem_type type; -@@ -158,8 +162,6 @@ struct nvmem_cell_table { - * @of_match_table: Open firmware match table. - * @add_cells: Called to populate the layout using - * nvmem_add_one_cell(). -- * @fixup_cell_info: Will be called before a cell is added. Can be -- * used to modify the nvmem_cell_info. - * @owner: Pointer to struct module. - * @node: List node. - * -@@ -172,9 +174,6 @@ struct nvmem_layout { - const char *name; - const struct of_device_id *of_match_table; - int (*add_cells)(struct device *dev, struct nvmem_device *nvmem); -- void (*fixup_cell_info)(struct nvmem_device *nvmem, -- struct nvmem_layout *layout, -- struct nvmem_cell_info *cell); - - /* private */ - struct module *owner; diff --git a/target/linux/generic/backport-5.15/834-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch b/target/linux/generic/backport-5.15/834-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch deleted file mode 100644 index 18813323408fe2..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch +++ /dev/null @@ -1,763 +0,0 @@ -From fc29fd821d9ac2ae3d32a722fac39ce874efb883 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:32 +0000 -Subject: [PATCH] nvmem: core: Rework layouts to become regular devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Current layout support was initially written without modules support in -mind. When the requirement for module support rose, the existing base -was improved to adopt modularization support, but kind of a design flaw -was introduced. With the existing implementation, when a storage device -registers into NVMEM, the core tries to hook a layout (if any) and -populates its cells immediately. This means, if the hardware description -expects a layout to be hooked up, but no driver was provided for that, -the storage medium will fail to probe and try later from -scratch. Even if we consider that the hardware description shall be -correct, we could still probe the storage device (especially if it -contains the rootfs). - -One way to overcome this situation is to consider the layouts as -devices, and leverage the native notifier mechanism. When a new NVMEM -device is registered, we can populate its nvmem-layout child, if any, -and wait for the matching to be done in order to get the cells (the -waiting can be easily done with the NVMEM notifiers). If the layout -driver is compiled as a module, it should automatically be loaded. This -way, there is no strong order to enforce, any NVMEM device creation -or NVMEM layout driver insertion will be observed as a new event which -may lead to the creation of additional cells, without disturbing the -probes with costly (and sometimes endless) deferrals. - -In order to achieve that goal we create a new bus for the nvmem-layouts -with minimal logic to match nvmem-layout devices with nvmem-layout -drivers. All this infrastructure code is created in the layouts.c file. - -Signed-off-by: Miquel Raynal -Tested-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 1 + - drivers/nvmem/Makefile | 2 + - drivers/nvmem/core.c | 170 ++++++++++---------------- - drivers/nvmem/internals.h | 21 ++++ - drivers/nvmem/layouts.c | 201 +++++++++++++++++++++++++++++++ - drivers/nvmem/layouts/Kconfig | 8 ++ - drivers/nvmem/layouts/onie-tlv.c | 24 +++- - drivers/nvmem/layouts/sl28vpd.c | 24 +++- - include/linux/nvmem-provider.h | 38 +++--- - 9 files changed, 354 insertions(+), 135 deletions(-) - create mode 100644 drivers/nvmem/layouts.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - menuconfig NVMEM - bool "NVMEM Support" -+ imply NVMEM_LAYOUTS - help - Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES... - ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -5,6 +5,8 @@ - - obj-$(CONFIG_NVMEM) += nvmem_core.o - nvmem_core-y := core.o -+obj-$(CONFIG_NVMEM_LAYOUTS) += nvmem_layouts.o -+nvmem_layouts-y := layouts.o - obj-y += layouts/ - - # Devices ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -56,9 +56,6 @@ static LIST_HEAD(nvmem_lookup_list); - - static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); - --static DEFINE_SPINLOCK(nvmem_layout_lock); --static LIST_HEAD(nvmem_layouts); -- - static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, - void *val, size_t bytes) - { -@@ -741,97 +738,22 @@ static int nvmem_add_cells_from_fixed_la - return err; - } - --int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner) -+int nvmem_layout_register(struct nvmem_layout *layout) - { -- layout->owner = owner; -- -- spin_lock(&nvmem_layout_lock); -- list_add(&layout->node, &nvmem_layouts); -- spin_unlock(&nvmem_layout_lock); -- -- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_ADD, layout); -+ if (!layout->add_cells) -+ return -EINVAL; - -- return 0; -+ /* Populate the cells */ -+ return layout->add_cells(&layout->nvmem->dev, layout->nvmem); - } --EXPORT_SYMBOL_GPL(__nvmem_layout_register); -+EXPORT_SYMBOL_GPL(nvmem_layout_register); - - void nvmem_layout_unregister(struct nvmem_layout *layout) - { -- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_REMOVE, layout); -- -- spin_lock(&nvmem_layout_lock); -- list_del(&layout->node); -- spin_unlock(&nvmem_layout_lock); -+ /* Keep the API even with an empty stub in case we need it later */ - } - EXPORT_SYMBOL_GPL(nvmem_layout_unregister); - --static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) --{ -- struct device_node *layout_np; -- struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER); -- -- layout_np = of_nvmem_layout_get_container(nvmem); -- if (!layout_np) -- return NULL; -- -- /* Fixed layouts don't have a matching driver */ -- if (of_device_is_compatible(layout_np, "fixed-layout")) { -- of_node_put(layout_np); -- return NULL; -- } -- -- /* -- * In case the nvmem device was built-in while the layout was built as a -- * module, we shall manually request the layout driver loading otherwise -- * we'll never have any match. -- */ -- of_request_module(layout_np); -- -- spin_lock(&nvmem_layout_lock); -- -- list_for_each_entry(l, &nvmem_layouts, node) { -- if (of_match_node(l->of_match_table, layout_np)) { -- if (try_module_get(l->owner)) -- layout = l; -- -- break; -- } -- } -- -- spin_unlock(&nvmem_layout_lock); -- of_node_put(layout_np); -- -- return layout; --} -- --static void nvmem_layout_put(struct nvmem_layout *layout) --{ -- if (layout) -- module_put(layout->owner); --} -- --static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem) --{ -- struct nvmem_layout *layout = nvmem->layout; -- int ret; -- -- if (layout && layout->add_cells) { -- ret = layout->add_cells(&nvmem->dev, nvmem); -- if (ret) -- return ret; -- } -- -- return 0; --} -- --#if IS_ENABLED(CONFIG_OF) --struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) --{ -- return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); --} --EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container); --#endif -- - const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, - struct nvmem_layout *layout) - { -@@ -839,7 +761,7 @@ const void *nvmem_layout_get_match_data( - const struct of_device_id *match; - - layout_np = of_nvmem_layout_get_container(nvmem); -- match = of_match_node(layout->of_match_table, layout_np); -+ match = of_match_node(layout->dev.driver->of_match_table, layout_np); - - return match ? match->data : NULL; - } -@@ -951,19 +873,6 @@ struct nvmem_device *nvmem_register(cons - goto err_put_device; - } - -- /* -- * If the driver supplied a layout by config->layout, the module -- * pointer will be NULL and nvmem_layout_put() will be a noop. -- */ -- nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); -- if (IS_ERR(nvmem->layout)) { -- rval = PTR_ERR(nvmem->layout); -- nvmem->layout = NULL; -- -- if (rval == -EPROBE_DEFER) -- goto err_teardown_compat; -- } -- - if (config->cells) { - rval = nvmem_add_cells(nvmem, config->cells, config->ncells); - if (rval) -@@ -984,24 +893,24 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -- rval = nvmem_add_cells_from_layout(nvmem); -- if (rval) -- goto err_remove_cells; -- - dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); - - rval = device_add(&nvmem->dev); - if (rval) - goto err_remove_cells; - -+ rval = nvmem_populate_layout(nvmem); -+ if (rval) -+ goto err_remove_dev; -+ - blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); - - return nvmem; - -+err_remove_dev: -+ device_del(&nvmem->dev); - err_remove_cells: - nvmem_device_remove_all_cells(nvmem); -- nvmem_layout_put(nvmem->layout); --err_teardown_compat: - if (config->compat) - nvmem_sysfs_remove_compat(nvmem, config); - err_put_device: -@@ -1023,7 +932,7 @@ static void nvmem_device_release(struct - device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); - - nvmem_device_remove_all_cells(nvmem); -- nvmem_layout_put(nvmem->layout); -+ nvmem_destroy_layout(nvmem); - device_unregister(&nvmem->dev); - } - -@@ -1325,6 +1234,12 @@ nvmem_cell_get_from_lookup(struct device - return cell; - } - -+static void nvmem_layout_module_put(struct nvmem_device *nvmem) -+{ -+ if (nvmem->layout && nvmem->layout->dev.driver) -+ module_put(nvmem->layout->dev.driver->owner); -+} -+ - #if IS_ENABLED(CONFIG_OF) - static struct nvmem_cell_entry * - nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np) -@@ -1343,6 +1258,18 @@ nvmem_find_cell_entry_by_node(struct nvm - return cell; - } - -+static int nvmem_layout_module_get_optional(struct nvmem_device *nvmem) -+{ -+ if (!nvmem->layout) -+ return 0; -+ -+ if (!nvmem->layout->dev.driver || -+ !try_module_get(nvmem->layout->dev.driver->owner)) -+ return -EPROBE_DEFER; -+ -+ return 0; -+} -+ - /** - * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id - * -@@ -1405,16 +1332,29 @@ struct nvmem_cell *of_nvmem_cell_get(str - return ERR_CAST(nvmem); - } - -+ ret = nvmem_layout_module_get_optional(nvmem); -+ if (ret) { -+ of_node_put(cell_np); -+ __nvmem_device_put(nvmem); -+ return ERR_PTR(ret); -+ } -+ - cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np); - of_node_put(cell_np); - if (!cell_entry) { - __nvmem_device_put(nvmem); -- return ERR_PTR(-ENOENT); -+ nvmem_layout_module_put(nvmem); -+ if (nvmem->layout) -+ return ERR_PTR(-EPROBE_DEFER); -+ else -+ return ERR_PTR(-ENOENT); - } - - cell = nvmem_create_cell(cell_entry, id, cell_index); -- if (IS_ERR(cell)) -+ if (IS_ERR(cell)) { - __nvmem_device_put(nvmem); -+ nvmem_layout_module_put(nvmem); -+ } - - return cell; - } -@@ -1528,6 +1468,7 @@ void nvmem_cell_put(struct nvmem_cell *c - - kfree(cell); - __nvmem_device_put(nvmem); -+ nvmem_layout_module_put(nvmem); - } - EXPORT_SYMBOL_GPL(nvmem_cell_put); - -@@ -2105,11 +2046,22 @@ EXPORT_SYMBOL_GPL(nvmem_dev_name); - - static int __init nvmem_init(void) - { -- return bus_register(&nvmem_bus_type); -+ int ret; -+ -+ ret = bus_register(&nvmem_bus_type); -+ if (ret) -+ return ret; -+ -+ ret = nvmem_layout_bus_register(); -+ if (ret) -+ bus_unregister(&nvmem_bus_type); -+ -+ return ret; - } - - static void __exit nvmem_exit(void) - { -+ nvmem_layout_bus_unregister(); - bus_unregister(&nvmem_bus_type); - } - ---- a/drivers/nvmem/internals.h -+++ b/drivers/nvmem/internals.h -@@ -34,4 +34,25 @@ struct nvmem_device { - void *priv; - }; - -+#if IS_ENABLED(CONFIG_OF) -+int nvmem_layout_bus_register(void); -+void nvmem_layout_bus_unregister(void); -+int nvmem_populate_layout(struct nvmem_device *nvmem); -+void nvmem_destroy_layout(struct nvmem_device *nvmem); -+#else /* CONFIG_OF */ -+static inline int nvmem_layout_bus_register(void) -+{ -+ return 0; -+} -+ -+static inline void nvmem_layout_bus_unregister(void) {} -+ -+static inline int nvmem_populate_layout(struct nvmem_device *nvmem) -+{ -+ return 0; -+} -+ -+static inline void nvmem_destroy_layout(struct nvmem_device *nvmem) { } -+#endif /* CONFIG_OF */ -+ - #endif /* ifndef _LINUX_NVMEM_INTERNALS_H */ ---- /dev/null -+++ b/drivers/nvmem/layouts.c -@@ -0,0 +1,201 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * NVMEM layout bus handling -+ * -+ * Copyright (C) 2023 Bootlin -+ * Author: Miquel Raynal -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "internals.h" -+ -+#define to_nvmem_layout_driver(drv) \ -+ (container_of((drv), struct nvmem_layout_driver, driver)) -+#define to_nvmem_layout_device(_dev) \ -+ container_of((_dev), struct nvmem_layout, dev) -+ -+static int nvmem_layout_bus_match(struct device *dev, struct device_driver *drv) -+{ -+ return of_driver_match_device(dev, drv); -+} -+ -+static int nvmem_layout_bus_probe(struct device *dev) -+{ -+ struct nvmem_layout_driver *drv = to_nvmem_layout_driver(dev->driver); -+ struct nvmem_layout *layout = to_nvmem_layout_device(dev); -+ -+ if (!drv->probe || !drv->remove) -+ return -EINVAL; -+ -+ return drv->probe(layout); -+} -+ -+static void nvmem_layout_bus_remove(struct device *dev) -+{ -+ struct nvmem_layout_driver *drv = to_nvmem_layout_driver(dev->driver); -+ struct nvmem_layout *layout = to_nvmem_layout_device(dev); -+ -+ return drv->remove(layout); -+} -+ -+static struct bus_type nvmem_layout_bus_type = { -+ .name = "nvmem-layout", -+ .match = nvmem_layout_bus_match, -+ .probe = nvmem_layout_bus_probe, -+ .remove = nvmem_layout_bus_remove, -+}; -+ -+int nvmem_layout_driver_register(struct nvmem_layout_driver *drv) -+{ -+ drv->driver.bus = &nvmem_layout_bus_type; -+ -+ return driver_register(&drv->driver); -+} -+EXPORT_SYMBOL_GPL(nvmem_layout_driver_register); -+ -+void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv) -+{ -+ driver_unregister(&drv->driver); -+} -+EXPORT_SYMBOL_GPL(nvmem_layout_driver_unregister); -+ -+static void nvmem_layout_release_device(struct device *dev) -+{ -+ struct nvmem_layout *layout = to_nvmem_layout_device(dev); -+ -+ of_node_put(layout->dev.of_node); -+ kfree(layout); -+} -+ -+static int nvmem_layout_create_device(struct nvmem_device *nvmem, -+ struct device_node *np) -+{ -+ struct nvmem_layout *layout; -+ struct device *dev; -+ int ret; -+ -+ layout = kzalloc(sizeof(*layout), GFP_KERNEL); -+ if (!layout) -+ return -ENOMEM; -+ -+ /* Create a bidirectional link */ -+ layout->nvmem = nvmem; -+ nvmem->layout = layout; -+ -+ /* Device model registration */ -+ dev = &layout->dev; -+ device_initialize(dev); -+ dev->parent = &nvmem->dev; -+ dev->bus = &nvmem_layout_bus_type; -+ dev->release = nvmem_layout_release_device; -+ dev->coherent_dma_mask = DMA_BIT_MASK(32); -+ dev->dma_mask = &dev->coherent_dma_mask; -+ device_set_node(dev, of_fwnode_handle(of_node_get(np))); -+ of_device_make_bus_id(dev); -+ of_msi_configure(dev, dev->of_node); -+ -+ ret = device_add(dev); -+ if (ret) { -+ put_device(dev); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id of_nvmem_layout_skip_table[] = { -+ { .compatible = "fixed-layout", }, -+ {} -+}; -+ -+static int nvmem_layout_bus_populate(struct nvmem_device *nvmem, -+ struct device_node *layout_dn) -+{ -+ int ret; -+ -+ /* Make sure it has a compatible property */ -+ if (!of_get_property(layout_dn, "compatible", NULL)) { -+ pr_debug("%s() - skipping %pOF, no compatible prop\n", -+ __func__, layout_dn); -+ return 0; -+ } -+ -+ /* Fixed layouts are parsed manually somewhere else for now */ -+ if (of_match_node(of_nvmem_layout_skip_table, layout_dn)) { -+ pr_debug("%s() - skipping %pOF node\n", __func__, layout_dn); -+ return 0; -+ } -+ -+ if (of_node_check_flag(layout_dn, OF_POPULATED_BUS)) { -+ pr_debug("%s() - skipping %pOF, already populated\n", -+ __func__, layout_dn); -+ -+ return 0; -+ } -+ -+ /* NVMEM layout buses expect only a single device representing the layout */ -+ ret = nvmem_layout_create_device(nvmem, layout_dn); -+ if (ret) -+ return ret; -+ -+ of_node_set_flag(layout_dn, OF_POPULATED_BUS); -+ -+ return 0; -+} -+ -+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) -+{ -+ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); -+} -+EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container); -+ -+/* -+ * Returns the number of devices populated, 0 if the operation was not relevant -+ * for this nvmem device, an error code otherwise. -+ */ -+int nvmem_populate_layout(struct nvmem_device *nvmem) -+{ -+ struct device_node *layout_dn; -+ int ret; -+ -+ layout_dn = of_nvmem_layout_get_container(nvmem); -+ if (!layout_dn) -+ return 0; -+ -+ /* Populate the layout device */ -+ device_links_supplier_sync_state_pause(); -+ ret = nvmem_layout_bus_populate(nvmem, layout_dn); -+ device_links_supplier_sync_state_resume(); -+ -+ of_node_put(layout_dn); -+ return ret; -+} -+ -+void nvmem_destroy_layout(struct nvmem_device *nvmem) -+{ -+ struct device *dev; -+ -+ if (!nvmem->layout) -+ return; -+ -+ dev = &nvmem->layout->dev; -+ of_node_clear_flag(dev->of_node, OF_POPULATED_BUS); -+ device_unregister(dev); -+} -+ -+int nvmem_layout_bus_register(void) -+{ -+ return bus_register(&nvmem_layout_bus_type); -+} -+ -+void nvmem_layout_bus_unregister(void) -+{ -+ bus_unregister(&nvmem_layout_bus_type); -+} ---- a/drivers/nvmem/layouts/Kconfig -+++ b/drivers/nvmem/layouts/Kconfig -@@ -1,5 +1,11 @@ - # SPDX-License-Identifier: GPL-2.0 - -+config NVMEM_LAYOUTS -+ bool -+ depends on OF -+ -+if NVMEM_LAYOUTS -+ - menu "Layout Types" - - config NVMEM_LAYOUT_SL28_VPD -@@ -21,3 +27,5 @@ config NVMEM_LAYOUT_ONIE_TLV - If unsure, say N. - - endmenu -+ -+endif ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -225,16 +225,32 @@ static int onie_tlv_parse_table(struct d - return 0; - } - -+static int onie_tlv_probe(struct nvmem_layout *layout) -+{ -+ layout->add_cells = onie_tlv_parse_table; -+ -+ return nvmem_layout_register(layout); -+} -+ -+static void onie_tlv_remove(struct nvmem_layout *layout) -+{ -+ nvmem_layout_unregister(layout); -+} -+ - static const struct of_device_id onie_tlv_of_match_table[] = { - { .compatible = "onie,tlv-layout", }, - {}, - }; - MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table); - --static struct nvmem_layout onie_tlv_layout = { -- .name = "ONIE tlv layout", -- .of_match_table = onie_tlv_of_match_table, -- .add_cells = onie_tlv_parse_table, -+static struct nvmem_layout_driver onie_tlv_layout = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "onie-tlv-layout", -+ .of_match_table = onie_tlv_of_match_table, -+ }, -+ .probe = onie_tlv_probe, -+ .remove = onie_tlv_remove, - }; - module_nvmem_layout_driver(onie_tlv_layout); - ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -134,16 +134,32 @@ static int sl28vpd_add_cells(struct devi - return 0; - } - -+static int sl28vpd_probe(struct nvmem_layout *layout) -+{ -+ layout->add_cells = sl28vpd_add_cells; -+ -+ return nvmem_layout_register(layout); -+} -+ -+static void sl28vpd_remove(struct nvmem_layout *layout) -+{ -+ nvmem_layout_unregister(layout); -+} -+ - static const struct of_device_id sl28vpd_of_match_table[] = { - { .compatible = "kontron,sl28-vpd" }, - {}, - }; - MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); - --static struct nvmem_layout sl28vpd_layout = { -- .name = "sl28-vpd", -- .of_match_table = sl28vpd_of_match_table, -- .add_cells = sl28vpd_add_cells, -+static struct nvmem_layout_driver sl28vpd_layout = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "kontron-sl28vpd-layout", -+ .of_match_table = sl28vpd_of_match_table, -+ }, -+ .probe = sl28vpd_probe, -+ .remove = sl28vpd_remove, - }; - module_nvmem_layout_driver(sl28vpd_layout); - ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -9,6 +9,7 @@ - #ifndef _LINUX_NVMEM_PROVIDER_H - #define _LINUX_NVMEM_PROVIDER_H - -+#include - #include - #include - #include -@@ -158,12 +159,11 @@ struct nvmem_cell_table { - /** - * struct nvmem_layout - NVMEM layout definitions - * -- * @name: Layout name. -- * @of_match_table: Open firmware match table. -- * @add_cells: Called to populate the layout using -- * nvmem_add_one_cell(). -- * @owner: Pointer to struct module. -- * @node: List node. -+ * @dev: Device-model layout device. -+ * @nvmem: The underlying NVMEM device -+ * @add_cells: Will be called if a nvmem device is found which -+ * has this layout. The function will add layout -+ * specific cells with nvmem_add_one_cell(). - * - * A nvmem device can hold a well defined structure which can just be - * evaluated during runtime. For example a TLV list, or a list of "name=val" -@@ -171,13 +171,15 @@ struct nvmem_cell_table { - * cells. - */ - struct nvmem_layout { -- const char *name; -- const struct of_device_id *of_match_table; -+ struct device dev; -+ struct nvmem_device *nvmem; - int (*add_cells)(struct device *dev, struct nvmem_device *nvmem); -+}; - -- /* private */ -- struct module *owner; -- struct list_head node; -+struct nvmem_layout_driver { -+ struct device_driver driver; -+ int (*probe)(struct nvmem_layout *layout); -+ void (*remove)(struct nvmem_layout *layout); - }; - - #if IS_ENABLED(CONFIG_NVMEM) -@@ -194,11 +196,15 @@ void nvmem_del_cell_table(struct nvmem_c - int nvmem_add_one_cell(struct nvmem_device *nvmem, - const struct nvmem_cell_info *info); - --int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner); --#define nvmem_layout_register(layout) \ -- __nvmem_layout_register(layout, THIS_MODULE) -+int nvmem_layout_register(struct nvmem_layout *layout); - void nvmem_layout_unregister(struct nvmem_layout *layout); - -+int nvmem_layout_driver_register(struct nvmem_layout_driver *drv); -+void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv); -+#define module_nvmem_layout_driver(__nvmem_layout_driver) \ -+ module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \ -+ nvmem_layout_driver_unregister) -+ - const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, - struct nvmem_layout *layout); - -@@ -262,8 +268,4 @@ static inline struct device_node *of_nvm - - #endif /* CONFIG_NVMEM && CONFIG_OF */ - --#define module_nvmem_layout_driver(__layout_driver) \ -- module_driver(__layout_driver, nvmem_layout_register, \ -- nvmem_layout_unregister) -- - #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-5.15/834-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch b/target/linux/generic/backport-5.15/834-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch deleted file mode 100644 index 89872bec2e59d3..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch +++ /dev/null @@ -1,240 +0,0 @@ -From 0331c611949fffdf486652450901a4dc52bc5cca Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:34 +0000 -Subject: [PATCH] nvmem: core: Expose cells through sysfs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The binary content of nvmem devices is available to the user so in the -easiest cases, finding the content of a cell is rather easy as it is -just a matter of looking at a known and fixed offset. However, nvmem -layouts have been recently introduced to cope with more advanced -situations, where the offset and size of the cells is not known in -advance or is dynamic. When using layouts, more advanced parsers are -used by the kernel in order to give direct access to the content of each -cell, regardless of its position/size in the underlying -device. Unfortunately, these information are not accessible by users, -unless by fully re-implementing the parser logic in userland. - -Let's expose the cells and their content through sysfs to avoid these -situations. Of course the relevant NVMEM sysfs Kconfig option must be -enabled for this support to be available. - -Not all nvmem devices expose cells. Indeed, the .bin_attrs attribute -group member will be filled at runtime only when relevant and will -remain empty otherwise. In this case, as the cells attribute group will -be empty, it will not lead to any additional folder/file creation. - -Exposed cells are read-only. There is, in practice, everything in the -core to support a write path, but as I don't see any need for that, I -prefer to keep the interface simple (and probably safer). The interface -is documented as being in the "testing" state which means we can later -add a write attribute if though relevant. - -Signed-off-by: Miquel Raynal -Tested-by: Rafał Miłecki -Tested-by: Chen-Yu Tsai -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 135 +++++++++++++++++++++++++++++++++++++- - drivers/nvmem/internals.h | 1 + - 2 files changed, 135 insertions(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -300,6 +300,43 @@ static umode_t nvmem_bin_attr_is_visible - return nvmem_bin_attr_get_umode(nvmem); - } - -+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, -+ const char *id, int index); -+ -+static ssize_t nvmem_cell_attr_read(struct file *filp, struct kobject *kobj, -+ struct bin_attribute *attr, char *buf, -+ loff_t pos, size_t count) -+{ -+ struct nvmem_cell_entry *entry; -+ struct nvmem_cell *cell = NULL; -+ size_t cell_sz, read_len; -+ void *content; -+ -+ entry = attr->private; -+ cell = nvmem_create_cell(entry, entry->name, 0); -+ if (IS_ERR(cell)) -+ return PTR_ERR(cell); -+ -+ if (!cell) -+ return -EINVAL; -+ -+ content = nvmem_cell_read(cell, &cell_sz); -+ if (IS_ERR(content)) { -+ read_len = PTR_ERR(content); -+ goto destroy_cell; -+ } -+ -+ read_len = min_t(unsigned int, cell_sz - pos, count); -+ memcpy(buf, content + pos, read_len); -+ kfree(content); -+ -+destroy_cell: -+ kfree_const(cell->id); -+ kfree(cell); -+ -+ return read_len; -+} -+ - /* default read/write permissions */ - static struct bin_attribute bin_attr_rw_nvmem = { - .attr = { -@@ -321,11 +358,21 @@ static const struct attribute_group nvme - .is_bin_visible = nvmem_bin_attr_is_visible, - }; - -+/* Cell attributes will be dynamically allocated */ -+static struct attribute_group nvmem_cells_group = { -+ .name = "cells", -+}; -+ - static const struct attribute_group *nvmem_dev_groups[] = { - &nvmem_bin_group, - NULL, - }; - -+static const struct attribute_group *nvmem_cells_groups[] = { -+ &nvmem_cells_group, -+ NULL, -+}; -+ - static struct bin_attribute bin_attr_nvmem_eeprom_compat = { - .attr = { - .name = "eeprom", -@@ -381,6 +428,68 @@ static void nvmem_sysfs_remove_compat(st - device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); - } - -+static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem) -+{ -+ struct bin_attribute **cells_attrs, *attrs; -+ struct nvmem_cell_entry *entry; -+ unsigned int ncells = 0, i = 0; -+ int ret = 0; -+ -+ mutex_lock(&nvmem_mutex); -+ -+ if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) { -+ nvmem_cells_group.bin_attrs = NULL; -+ goto unlock_mutex; -+ } -+ -+ /* Allocate an array of attributes with a sentinel */ -+ ncells = list_count_nodes(&nvmem->cells); -+ cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1, -+ sizeof(struct bin_attribute *), GFP_KERNEL); -+ if (!cells_attrs) { -+ ret = -ENOMEM; -+ goto unlock_mutex; -+ } -+ -+ attrs = devm_kcalloc(&nvmem->dev, ncells, sizeof(struct bin_attribute), GFP_KERNEL); -+ if (!attrs) { -+ ret = -ENOMEM; -+ goto unlock_mutex; -+ } -+ -+ /* Initialize each attribute to take the name and size of the cell */ -+ list_for_each_entry(entry, &nvmem->cells, node) { -+ sysfs_bin_attr_init(&attrs[i]); -+ attrs[i].attr.name = devm_kasprintf(&nvmem->dev, GFP_KERNEL, -+ "%s@%x", entry->name, -+ entry->offset); -+ attrs[i].attr.mode = 0444; -+ attrs[i].size = entry->bytes; -+ attrs[i].read = &nvmem_cell_attr_read; -+ attrs[i].private = entry; -+ if (!attrs[i].attr.name) { -+ ret = -ENOMEM; -+ goto unlock_mutex; -+ } -+ -+ cells_attrs[i] = &attrs[i]; -+ i++; -+ } -+ -+ nvmem_cells_group.bin_attrs = cells_attrs; -+ -+ ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups); -+ if (ret) -+ goto unlock_mutex; -+ -+ nvmem->sysfs_cells_populated = true; -+ -+unlock_mutex: -+ mutex_unlock(&nvmem_mutex); -+ -+ return ret; -+} -+ - #else /* CONFIG_NVMEM_SYSFS */ - - static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, -@@ -740,11 +849,25 @@ static int nvmem_add_cells_from_fixed_la - - int nvmem_layout_register(struct nvmem_layout *layout) - { -+ int ret; -+ - if (!layout->add_cells) - return -EINVAL; - - /* Populate the cells */ -- return layout->add_cells(&layout->nvmem->dev, layout->nvmem); -+ ret = layout->add_cells(&layout->nvmem->dev, layout->nvmem); -+ if (ret) -+ return ret; -+ -+#ifdef CONFIG_NVMEM_SYSFS -+ ret = nvmem_populate_sysfs_cells(layout->nvmem); -+ if (ret) { -+ nvmem_device_remove_all_cells(layout->nvmem); -+ return ret; -+ } -+#endif -+ -+ return 0; - } - EXPORT_SYMBOL_GPL(nvmem_layout_register); - -@@ -903,10 +1026,20 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_dev; - -+#ifdef CONFIG_NVMEM_SYSFS -+ rval = nvmem_populate_sysfs_cells(nvmem); -+ if (rval) -+ goto err_destroy_layout; -+#endif -+ - blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); - - return nvmem; - -+#ifdef CONFIG_NVMEM_SYSFS -+err_destroy_layout: -+ nvmem_destroy_layout(nvmem); -+#endif - err_remove_dev: - device_del(&nvmem->dev); - err_remove_cells: ---- a/drivers/nvmem/internals.h -+++ b/drivers/nvmem/internals.h -@@ -32,6 +32,7 @@ struct nvmem_device { - struct gpio_desc *wp_gpio; - struct nvmem_layout *layout; - void *priv; -+ bool sysfs_cells_populated; - }; - - #if IS_ENABLED(CONFIG_OF) diff --git a/target/linux/generic/backport-5.15/834-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch b/target/linux/generic/backport-5.15/834-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch deleted file mode 100644 index f686222f881075..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch +++ /dev/null @@ -1,65 +0,0 @@ -From f0ac5b23039610619ca4a4805528553ecb6bc815 Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Fri, 15 Dec 2023 11:15:36 +0000 -Subject: [PATCH] nvmem: stm32: add support for STM32MP25 BSEC to control OTP - data - -On STM32MP25, OTP area may be read/written by using BSEC (boot, security -and OTP control). The BSEC internal peripheral is only managed by the -secure world. - -The 12 Kbits of OTP (effective) are organized into the following regions: -- lower OTP (OTP0 to OTP127) = 4096 lower OTP bits, - bitwise (1-bit) programmable -- mid OTP (OTP128 to OTP255) = 4096 middle OTP bits, - bulk (32-bit) programmable -- upper OTP (OTP256 to OTP383) = 4096 upper OTP bits, - bulk (32-bit) programmable, - only accessible when BSEC is in closed state. - -As HWKEY and ECIES key are only accessible by ROM code; -only 368 OTP words are managed in this driver (OTP0 to OTP267). - -This patch adds the STM32MP25 configuration for reading and writing -the OTP data using the OP-TEE BSEC TA services. - -Signed-off-by: Patrick Delaunay -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-11-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -269,6 +269,19 @@ static const struct stm32_romem_cfg stm3 - .ta = true, - }; - -+/* -+ * STM32MP25 BSEC OTP: 3 regions of 32-bits data words -+ * lower OTP (OTP0 to OTP127), bitwise (1-bit) programmable -+ * mid OTP (OTP128 to OTP255), bulk (32-bit) programmable -+ * upper OTP (OTP256 to OTP383), bulk (32-bit) programmable -+ * but no access to HWKEY and ECIES key: limited at OTP367 -+ */ -+static const struct stm32_romem_cfg stm32mp25_bsec_cfg = { -+ .size = 368 * 4, -+ .lower = 127, -+ .ta = true, -+}; -+ - static const struct of_device_id stm32_romem_of_match[] __maybe_unused = { - { .compatible = "st,stm32f4-otp", }, { - .compatible = "st,stm32mp15-bsec", -@@ -276,6 +289,9 @@ static const struct of_device_id stm32_r - }, { - .compatible = "st,stm32mp13-bsec", - .data = (void *)&stm32mp13_bsec_cfg, -+ }, { -+ .compatible = "st,stm32mp25-bsec", -+ .data = (void *)&stm32mp25_bsec_cfg, - }, - { /* sentinel */ }, - }; diff --git a/target/linux/generic/backport-5.15/834-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch b/target/linux/generic/backport-5.15/834-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch deleted file mode 100644 index 1bf3ba35b6d91e..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 401df0d4f4098ecc9c5278da2f50756d62e5b37d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 19 Dec 2023 13:01:03 +0100 -Subject: [PATCH] nvmem: layouts: refactor .add_cells() callback arguments -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Simply pass whole "struct nvmem_layout" instead of single variables. -There is nothing in "struct nvmem_layout" that we have to hide from -layout drivers. They also access it during .probe() and .remove(). - -Thanks to this change: - -1. API gets more consistent - All layouts drivers callbacks get the same argument - -2. Layouts get correct device - Before this change NVMEM core code was passing NVMEM device instead - of layout device. That resulted in: - * Confusing prints - * Calling devm_*() helpers on wrong device - * Helpers like of_device_get_match_data() dereferencing NULLs - -3. It gets possible to get match data - First of all nvmem_layout_get_match_data() requires passing "struct - nvmem_layout" which .add_cells() callback didn't have before this. It - doesn't matter much as it's rather useless now anyway (and will be - dropped). - What's more important however is that of_device_get_match_data() can - be used now thanks to owning a proper device pointer. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Reviewed-by: Michael Walle -Link: https://lore.kernel.org/r/20231219120104.3422-1-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - drivers/nvmem/layouts/onie-tlv.c | 4 +++- - drivers/nvmem/layouts/sl28vpd.c | 4 +++- - include/linux/nvmem-provider.h | 2 +- - 4 files changed, 8 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -855,7 +855,7 @@ int nvmem_layout_register(struct nvmem_l - return -EINVAL; - - /* Populate the cells */ -- ret = layout->add_cells(&layout->nvmem->dev, layout->nvmem); -+ ret = layout->add_cells(layout); - if (ret) - return ret; - ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -182,8 +182,10 @@ static bool onie_tlv_crc_is_valid(struct - return true; - } - --static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem) -+static int onie_tlv_parse_table(struct nvmem_layout *layout) - { -+ struct nvmem_device *nvmem = layout->nvmem; -+ struct device *dev = &layout->dev; - struct onie_tlv_hdr hdr; - size_t table_len, data_len, hdr_len; - u8 *table, *data; ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -80,8 +80,10 @@ static int sl28vpd_v1_check_crc(struct d - return 0; - } - --static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem) -+static int sl28vpd_add_cells(struct nvmem_layout *layout) - { -+ struct nvmem_device *nvmem = layout->nvmem; -+ struct device *dev = &layout->dev; - const struct nvmem_cell_info *pinfo; - struct nvmem_cell_info info = {0}; - struct device_node *layout_np; ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -173,7 +173,7 @@ struct nvmem_cell_table { - struct nvmem_layout { - struct device dev; - struct nvmem_device *nvmem; -- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem); -+ int (*add_cells)(struct nvmem_layout *layout); - }; - - struct nvmem_layout_driver { diff --git a/target/linux/generic/backport-5.15/834-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch b/target/linux/generic/backport-5.15/834-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch deleted file mode 100644 index 514b5f2de5c246..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 43f60e3fb62edc7bd8891de8779fb422f4ae23ae Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 19 Dec 2023 13:01:04 +0100 -Subject: [PATCH] nvmem: drop nvmem_layout_get_match_data() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Thanks for layouts refactoring we now have "struct device" associated -with layout. Also its OF pointer points directly to the "nvmem-layout" -DT node. - -All it takes to get match data is a generic of_device_get_match_data(). - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Reviewed-by: Michael Walle -Link: https://lore.kernel.org/r/20231219120104.3422-2-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 13 ------------- - include/linux/nvmem-provider.h | 10 ---------- - 2 files changed, 23 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -877,19 +877,6 @@ void nvmem_layout_unregister(struct nvme - } - EXPORT_SYMBOL_GPL(nvmem_layout_unregister); - --const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, -- struct nvmem_layout *layout) --{ -- struct device_node __maybe_unused *layout_np; -- const struct of_device_id *match; -- -- layout_np = of_nvmem_layout_get_container(nvmem); -- match = of_match_node(layout->dev.driver->of_match_table, layout_np); -- -- return match ? match->data : NULL; --} --EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data); -- - /** - * nvmem_register() - Register a nvmem device for given nvmem_config. - * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -205,9 +205,6 @@ void nvmem_layout_driver_unregister(stru - module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \ - nvmem_layout_driver_unregister) - --const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, -- struct nvmem_layout *layout); -- - #else - - static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) -@@ -238,13 +235,6 @@ static inline int nvmem_layout_register( - - static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {} - --static inline const void * --nvmem_layout_get_match_data(struct nvmem_device *nvmem, -- struct nvmem_layout *layout) --{ -- return NULL; --} -- - #endif /* CONFIG_NVMEM */ - - #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF) diff --git a/target/linux/generic/backport-5.15/834-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch b/target/linux/generic/backport-5.15/834-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch deleted file mode 100644 index aa0bbaa0c55834..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 33cf42e68efc8ff529a7eee08a4f0ba8c8d0a207 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 21 Dec 2023 18:34:17 +0100 -Subject: [PATCH] nvmem: core: add nvmem_dev_size() helper -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is required by layouts that need to read whole NVMEM content. It's -especially useful for NVMEM devices without hardcoded layout (like -U-Boot environment data block). - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Link: https://lore.kernel.org/r/20231221173421.13737-2-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 13 +++++++++++++ - include/linux/nvmem-consumer.h | 1 + - 2 files changed, 14 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -2164,6 +2164,19 @@ const char *nvmem_dev_name(struct nvmem_ - } - EXPORT_SYMBOL_GPL(nvmem_dev_name); - -+/** -+ * nvmem_dev_size() - Get the size of a given nvmem device. -+ * -+ * @nvmem: nvmem device. -+ * -+ * Return: size of the nvmem device. -+ */ -+size_t nvmem_dev_size(struct nvmem_device *nvmem) -+{ -+ return nvmem->size; -+} -+EXPORT_SYMBOL_GPL(nvmem_dev_size); -+ - static int __init nvmem_init(void) - { - int ret; ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -81,6 +81,7 @@ int nvmem_device_cell_write(struct nvmem - struct nvmem_cell_info *info, void *buf); - - const char *nvmem_dev_name(struct nvmem_device *nvmem); -+size_t nvmem_dev_size(struct nvmem_device *nvmem); - - void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, - size_t nentries); diff --git a/target/linux/generic/backport-5.15/834-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch b/target/linux/generic/backport-5.15/834-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch deleted file mode 100644 index fc826f3f7e4e87..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 7c8979b42b1a9c5604f431ba804928e55919263c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 21 Dec 2023 18:34:18 +0100 -Subject: [PATCH] nvmem: u-boot-env: use nvmem_add_one_cell() nvmem subsystem - helper -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Simplify adding NVMEM cells. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Link: https://lore.kernel.org/r/20231221173421.13737-3-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 55 +++++++++++++++----------------------- - 1 file changed, 21 insertions(+), 34 deletions(-) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -23,13 +23,10 @@ enum u_boot_env_format { - - struct u_boot_env { - struct device *dev; -+ struct nvmem_device *nvmem; - enum u_boot_env_format format; - - struct mtd_info *mtd; -- -- /* Cells */ -- struct nvmem_cell_info *cells; -- int ncells; - }; - - struct u_boot_env_image_single { -@@ -94,43 +91,36 @@ static int u_boot_env_read_post_process_ - static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, - size_t data_offset, size_t data_len) - { -+ struct nvmem_device *nvmem = priv->nvmem; - struct device *dev = priv->dev; - char *data = buf + data_offset; - char *var, *value, *eq; -- int idx; -- -- priv->ncells = 0; -- for (var = data; var < data + data_len && *var; var += strlen(var) + 1) -- priv->ncells++; -- -- priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL); -- if (!priv->cells) -- return -ENOMEM; - -- for (var = data, idx = 0; -+ for (var = data; - var < data + data_len && *var; -- var = value + strlen(value) + 1, idx++) { -+ var = value + strlen(value) + 1) { -+ struct nvmem_cell_info info = {}; -+ - eq = strchr(var, '='); - if (!eq) - break; - *eq = '\0'; - value = eq + 1; - -- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL); -- if (!priv->cells[idx].name) -+ info.name = devm_kstrdup(dev, var, GFP_KERNEL); -+ if (!info.name) - return -ENOMEM; -- priv->cells[idx].offset = data_offset + value - data; -- priv->cells[idx].bytes = strlen(value); -- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); -+ info.offset = data_offset + value - data; -+ info.bytes = strlen(value); -+ info.np = of_get_child_by_name(dev->of_node, info.name); - if (!strcmp(var, "ethaddr")) { -- priv->cells[idx].raw_len = strlen(value); -- priv->cells[idx].bytes = ETH_ALEN; -- priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr; -+ info.raw_len = strlen(value); -+ info.bytes = ETH_ALEN; -+ info.read_post_process = u_boot_env_read_post_process_ethaddr; - } -- } - -- if (WARN_ON(idx != priv->ncells)) -- priv->ncells = idx; -+ nvmem_add_one_cell(nvmem, &info); -+ } - - return 0; - } -@@ -209,7 +199,6 @@ static int u_boot_env_probe(struct platf - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct u_boot_env *priv; -- int err; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -224,17 +213,15 @@ static int u_boot_env_probe(struct platf - return PTR_ERR(priv->mtd); - } - -- err = u_boot_env_parse(priv); -- if (err) -- return err; -- - config.dev = dev; -- config.cells = priv->cells; -- config.ncells = priv->ncells; - config.priv = priv; - config.size = priv->mtd->size; - -- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config)); -+ priv->nvmem = devm_nvmem_register(dev, &config); -+ if (IS_ERR(priv->nvmem)) -+ return PTR_ERR(priv->nvmem); -+ -+ return u_boot_env_parse(priv); - } - - static const struct of_device_id u_boot_env_of_match_table[] = { diff --git a/target/linux/generic/backport-5.15/834-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch b/target/linux/generic/backport-5.15/834-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch deleted file mode 100644 index 70abc7cf1439f7..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch +++ /dev/null @@ -1,81 +0,0 @@ -From a832556d23c5a11115f300011a5874d6107a0d62 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 21 Dec 2023 18:34:19 +0100 -Subject: [PATCH] nvmem: u-boot-env: use nvmem device helpers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use nvmem_dev_size() and nvmem_device_read() to make this driver less -mtd dependent. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Link: https://lore.kernel.org/r/20231221173421.13737-4-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 23 +++++++++++++++-------- - 1 file changed, 15 insertions(+), 8 deletions(-) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -127,27 +127,34 @@ static int u_boot_env_add_cells(struct u - - static int u_boot_env_parse(struct u_boot_env *priv) - { -+ struct nvmem_device *nvmem = priv->nvmem; - struct device *dev = priv->dev; - size_t crc32_data_offset; - size_t crc32_data_len; - size_t crc32_offset; - size_t data_offset; - size_t data_len; -+ size_t dev_size; - uint32_t crc32; - uint32_t calc; -- size_t bytes; - uint8_t *buf; -+ int bytes; - int err; - -- buf = kcalloc(1, priv->mtd->size, GFP_KERNEL); -+ dev_size = nvmem_dev_size(nvmem); -+ -+ buf = kcalloc(1, dev_size, GFP_KERNEL); - if (!buf) { - err = -ENOMEM; - goto err_out; - } - -- err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf); -- if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) { -- dev_err(dev, "Failed to read from mtd: %d\n", err); -+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf); -+ if (bytes < 0) { -+ err = bytes; -+ goto err_kfree; -+ } else if (bytes != dev_size) { -+ err = -EIO; - goto err_kfree; - } - -@@ -169,8 +176,8 @@ static int u_boot_env_parse(struct u_boo - break; - } - crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); -- crc32_data_len = priv->mtd->size - crc32_data_offset; -- data_len = priv->mtd->size - data_offset; -+ crc32_data_len = dev_size - crc32_data_offset; -+ data_len = dev_size - data_offset; - - calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; - if (calc != crc32) { -@@ -179,7 +186,7 @@ static int u_boot_env_parse(struct u_boo - goto err_kfree; - } - -- buf[priv->mtd->size - 1] = '\0'; -+ buf[dev_size - 1] = '\0'; - err = u_boot_env_add_cells(priv, buf, data_offset, data_len); - if (err) - dev_err(dev, "Failed to add cells: %d\n", err); diff --git a/target/linux/generic/backport-5.15/834-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch b/target/linux/generic/backport-5.15/834-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch deleted file mode 100644 index 273cfed8743c04..00000000000000 --- a/target/linux/generic/backport-5.15/834-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 6bafe07c930676d6430be471310958070816a595 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 21 Dec 2023 18:34:20 +0100 -Subject: [PATCH] nvmem: u-boot-env: improve coding style -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -1. Prefer kzalloc() over kcalloc() - See memory-allocation.rst which says: "to be on the safe side it's - best to use routines that set memory to zero, like kzalloc()" -2. Drop dev_err() for u_boot_env_add_cells() fail - It can fail only on -ENOMEM. We don't want to print error then. -3. Add extra "crc32_addr" variable - It makes code reading header's crc32 easier to understand / review. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Link: https://lore.kernel.org/r/20231221173421.13737-5-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -132,6 +132,7 @@ static int u_boot_env_parse(struct u_boo - size_t crc32_data_offset; - size_t crc32_data_len; - size_t crc32_offset; -+ __le32 *crc32_addr; - size_t data_offset; - size_t data_len; - size_t dev_size; -@@ -143,7 +144,7 @@ static int u_boot_env_parse(struct u_boo - - dev_size = nvmem_dev_size(nvmem); - -- buf = kcalloc(1, dev_size, GFP_KERNEL); -+ buf = kzalloc(dev_size, GFP_KERNEL); - if (!buf) { - err = -ENOMEM; - goto err_out; -@@ -175,7 +176,8 @@ static int u_boot_env_parse(struct u_boo - data_offset = offsetof(struct u_boot_env_image_broadcom, data); - break; - } -- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); -+ crc32_addr = (__le32 *)(buf + crc32_offset); -+ crc32 = le32_to_cpu(*crc32_addr); - crc32_data_len = dev_size - crc32_data_offset; - data_len = dev_size - data_offset; - -@@ -188,8 +190,6 @@ static int u_boot_env_parse(struct u_boo - - buf[dev_size - 1] = '\0'; - err = u_boot_env_add_cells(priv, buf, data_offset, data_len); -- if (err) -- dev_err(dev, "Failed to add cells: %d\n", err); - - err_kfree: - kfree(buf); diff --git a/target/linux/generic/backport-5.15/835-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch b/target/linux/generic/backport-5.15/835-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch deleted file mode 100644 index 8b6d3e79e74193..00000000000000 --- a/target/linux/generic/backport-5.15/835-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ec18a2a83b8b9f7e39c80105ea148c769c46227b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 17 Jan 2024 16:17:36 +0100 -Subject: [PATCH] dt-bindings: leds: Add FUNCTION defines for per-band WLANs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Most wireless routers and access points can operate in multiple bands -simultaneously. Vendors often equip their devices with per-band LEDs. - -Add defines for those very common functions to allow cleaner & clearer -bindings. - -Signed-off-by: Rafał Miłecki -Acked-by: Rob Herring -Link: https://lore.kernel.org/r/20240117151736.27440-1-zajec5@gmail.com -Signed-off-by: Lee Jones ---- - include/dt-bindings/leds/common.h | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/include/dt-bindings/leds/common.h -+++ b/include/dt-bindings/leds/common.h -@@ -94,6 +94,9 @@ - #define LED_FUNCTION_USB "usb" - #define LED_FUNCTION_WAN "wan" - #define LED_FUNCTION_WLAN "wlan" -+#define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz" -+#define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz" -+#define LED_FUNCTION_WLAN_6GHZ "wlan-6ghz" - #define LED_FUNCTION_WPS "wps" - - #endif /* __DT_BINDINGS_LEDS_H */ diff --git a/target/linux/generic/backport-5.15/835-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch b/target/linux/generic/backport-5.15/835-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch deleted file mode 100644 index c1399ce3079b0e..00000000000000 --- a/target/linux/generic/backport-5.15/835-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 64e558500d2d04878b8a6d6578850c475171d6ba Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 23 Feb 2024 12:22:23 +0100 -Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_WAN_ONLINE for Internet - access -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It's common for routers to have LED indicating link on the WAN port. - -Some devices however have an extra LED that's meant to be used if WAN -connection is actually "online" (there is Internet access available). - -It was suggested to add #define for such use case. - -Link: https://lore.kernel.org/linux-devicetree/80e92209-5578-44e7-bd4b-603a29053ddf@collabora.com/T/#u -Signed-off-by: Rafał Miłecki -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20240223112223.1368-1-zajec5@gmail.com -Signed-off-by: Lee Jones ---- - include/dt-bindings/leds/common.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/dt-bindings/leds/common.h -+++ b/include/dt-bindings/leds/common.h -@@ -93,6 +93,7 @@ - #define LED_FUNCTION_TX "tx" - #define LED_FUNCTION_USB "usb" - #define LED_FUNCTION_WAN "wan" -+#define LED_FUNCTION_WAN_ONLINE "wan-online" - #define LED_FUNCTION_WLAN "wlan" - #define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz" - #define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz" diff --git a/target/linux/generic/backport-5.15/836-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch b/target/linux/generic/backport-5.15/836-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch deleted file mode 100644 index 8e7c8233e224ff..00000000000000 --- a/target/linux/generic/backport-5.15/836-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 998f0633773b3432829fe45d2cd2ffb842f3c78e Mon Sep 17 00:00:00 2001 -From: William-tw Lin -Date: Sat, 24 Feb 2024 11:45:07 +0000 -Subject: [PATCH] nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse - -The socinfo driver reads chip information from eFuses and does not need -any devicetree node. Register it from mtk-efuse. - -While at it, also add the name for this driver's nvmem_config. - -Signed-off-by: William-tw Lin -Reviewed-by: AngeloGioacchino Del Regno -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240224114516.86365-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/mtk-efuse.c | 21 ++++++++++++++++++++- - 1 file changed, 20 insertions(+), 1 deletion(-) - ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -68,6 +68,7 @@ static int mtk_efuse_probe(struct platfo - struct nvmem_config econfig = {}; - struct mtk_efuse_priv *priv; - const struct mtk_efuse_pdata *pdata; -+ struct platform_device *socinfo; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -85,11 +86,20 @@ static int mtk_efuse_probe(struct platfo - econfig.size = resource_size(res); - econfig.priv = priv; - econfig.dev = dev; -+ econfig.name = "mtk-efuse"; - if (pdata->uses_post_processing) - econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info; - nvmem = devm_nvmem_register(dev, &econfig); -+ if (IS_ERR(nvmem)) -+ return PTR_ERR(nvmem); - -- return PTR_ERR_OR_ZERO(nvmem); -+ socinfo = platform_device_register_data(&pdev->dev, "mtk-socinfo", -+ PLATFORM_DEVID_AUTO, NULL, 0); -+ if (IS_ERR(socinfo)) -+ dev_info(dev, "MediaTek SoC Information will be unavailable\n"); -+ -+ platform_set_drvdata(pdev, socinfo); -+ return 0; - } - - static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = { -@@ -108,8 +118,17 @@ static const struct of_device_id mtk_efu - }; - MODULE_DEVICE_TABLE(of, mtk_efuse_of_match); - -+static void mtk_efuse_remove(struct platform_device *pdev) -+{ -+ struct platform_device *socinfo = platform_get_drvdata(pdev); -+ -+ if (!IS_ERR_OR_NULL(socinfo)) -+ platform_device_unregister(socinfo); -+} -+ - static struct platform_driver mtk_efuse_driver = { - .probe = mtk_efuse_probe, -+ .remove_new = mtk_efuse_remove, - .driver = { - .name = "mediatek,efuse", - .of_match_table = mtk_efuse_of_match, diff --git a/target/linux/generic/backport-5.15/836-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch b/target/linux/generic/backport-5.15/836-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch deleted file mode 100644 index 0f90e548a2a66b..00000000000000 --- a/target/linux/generic/backport-5.15/836-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 29be47fcd6a06ea2e79eeeca6e69ad1e23254a69 Mon Sep 17 00:00:00 2001 -From: Praveen Teja Kundanala -Date: Sat, 24 Feb 2024 11:45:11 +0000 -Subject: [PATCH] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup - -- Remove static nvmem_config declaration -- Remove zynqmp_nvmem_data - -Signed-off-by: Praveen Teja Kundanala -Acked-by: Kalyani Akula -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240224114516.86365-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------ - 1 file changed, 12 insertions(+), 25 deletions(-) - ---- a/drivers/nvmem/zynqmp_nvmem.c -+++ b/drivers/nvmem/zynqmp_nvmem.c -@@ -1,6 +1,7 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright (C) 2019 Xilinx, Inc. -+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. - */ - - #include -@@ -11,36 +12,25 @@ - - #define SILICON_REVISION_MASK 0xF - --struct zynqmp_nvmem_data { -- struct device *dev; -- struct nvmem_device *nvmem; --}; - - static int zynqmp_nvmem_read(void *context, unsigned int offset, - void *val, size_t bytes) - { -+ struct device *dev = context; - int ret; -- int idcode, version; -- struct zynqmp_nvmem_data *priv = context; -+ int idcode; -+ int version; - - ret = zynqmp_pm_get_chipid(&idcode, &version); - if (ret < 0) - return ret; - -- dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version); -+ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version); - *(int *)val = version & SILICON_REVISION_MASK; - - return 0; - } - --static struct nvmem_config econfig = { -- .name = "zynqmp-nvmem", -- .owner = THIS_MODULE, -- .word_size = 1, -- .size = 1, -- .read_only = true, --}; -- - static const struct of_device_id zynqmp_nvmem_match[] = { - { .compatible = "xlnx,zynqmp-nvmem-fw", }, - { /* sentinel */ }, -@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_mat - static int zynqmp_nvmem_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -- struct zynqmp_nvmem_data *priv; -+ struct nvmem_config econfig = {}; - -- priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- -- priv->dev = dev; -+ econfig.name = "zynqmp-nvmem"; -+ econfig.owner = THIS_MODULE; -+ econfig.word_size = 1; -+ econfig.size = 1; - econfig.dev = dev; - econfig.add_legacy_fixed_of_cells = true; -+ econfig.read_only = true; - econfig.reg_read = zynqmp_nvmem_read; -- econfig.priv = priv; -- -- priv->nvmem = devm_nvmem_register(dev, &econfig); - -- return PTR_ERR_OR_ZERO(priv->nvmem); -+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig)); - } - - static struct platform_driver zynqmp_nvmem_driver = { diff --git a/target/linux/generic/backport-5.15/836-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch b/target/linux/generic/backport-5.15/836-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch deleted file mode 100644 index 39c2f178350bf1..00000000000000 --- a/target/linux/generic/backport-5.15/836-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch +++ /dev/null @@ -1,243 +0,0 @@ -From 737c0c8d07b5f671c0a33cec95965fcb2d2ea893 Mon Sep 17 00:00:00 2001 -From: Praveen Teja Kundanala -Date: Sat, 24 Feb 2024 11:45:12 +0000 -Subject: [PATCH] nvmem: zynqmp_nvmem: Add support to access efuse - -Add support to read/write efuse memory map of ZynqMP. -Below are the offsets of ZynqMP efuse memory map - 0 - SOC version(read only) - 0xC - 0xFC -ZynqMP specific purpose efuses - 0x100 - 0x17F - Physical Unclonable Function(PUF) - efuses repurposed as user efuses - -Signed-off-by: Praveen Teja Kundanala -Acked-by: Kalyani Akula -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240224114516.86365-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/zynqmp_nvmem.c | 186 +++++++++++++++++++++++++++++++++-- - 1 file changed, 176 insertions(+), 10 deletions(-) - ---- a/drivers/nvmem/zynqmp_nvmem.c -+++ b/drivers/nvmem/zynqmp_nvmem.c -@@ -4,6 +4,7 @@ - * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. - */ - -+#include - #include - #include - #include -@@ -11,24 +12,189 @@ - #include - - #define SILICON_REVISION_MASK 0xF -+#define P_USER_0_64_UPPER_MASK GENMASK(31, 16) -+#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0) -+#define WORD_INBYTES 4 -+#define SOC_VER_SIZE 0x4 -+#define EFUSE_MEMORY_SIZE 0x177 -+#define UNUSED_SPACE 0x8 -+#define ZYNQMP_NVMEM_SIZE (SOC_VER_SIZE + UNUSED_SPACE + \ -+ EFUSE_MEMORY_SIZE) -+#define SOC_VERSION_OFFSET 0x0 -+#define EFUSE_START_OFFSET 0xC -+#define EFUSE_END_OFFSET 0xFC -+#define EFUSE_PUF_START_OFFSET 0x100 -+#define EFUSE_PUF_MID_OFFSET 0x140 -+#define EFUSE_PUF_END_OFFSET 0x17F -+#define EFUSE_NOT_ENABLED 29 - -+/* -+ * efuse access type -+ */ -+enum efuse_access { -+ EFUSE_READ = 0, -+ EFUSE_WRITE -+}; -+ -+/** -+ * struct xilinx_efuse - the basic structure -+ * @src: address of the buffer to store the data to be write/read -+ * @size: read/write word count -+ * @offset: read/write offset -+ * @flag: 0 - represents efuse read and 1- represents efuse write -+ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write -+ * 1 - represents puf user fuse row number. -+ * -+ * this structure stores all the required details to -+ * read/write efuse memory. -+ */ -+struct xilinx_efuse { -+ u64 src; -+ u32 size; -+ u32 offset; -+ enum efuse_access flag; -+ u32 pufuserfuse; -+}; -+ -+static int zynqmp_efuse_access(void *context, unsigned int offset, -+ void *val, size_t bytes, enum efuse_access flag, -+ unsigned int pufflag) -+{ -+ struct device *dev = context; -+ struct xilinx_efuse *efuse; -+ dma_addr_t dma_addr; -+ dma_addr_t dma_buf; -+ size_t words = bytes / WORD_INBYTES; -+ int ret; -+ int value; -+ char *data; - --static int zynqmp_nvmem_read(void *context, unsigned int offset, -- void *val, size_t bytes) -+ if (bytes % WORD_INBYTES != 0) { -+ dev_err(dev, "Bytes requested should be word aligned\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (pufflag == 0 && offset % WORD_INBYTES) { -+ dev_err(dev, "Offset requested should be word aligned\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (pufflag == 1 && flag == EFUSE_WRITE) { -+ memcpy(&value, val, bytes); -+ if ((offset == EFUSE_PUF_START_OFFSET || -+ offset == EFUSE_PUF_MID_OFFSET) && -+ value & P_USER_0_64_UPPER_MASK) { -+ dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (offset == EFUSE_PUF_END_OFFSET && -+ (value & P_USER_127_LOWER_4_BIT_MASK)) { -+ dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n"); -+ return -EOPNOTSUPP; -+ } -+ } -+ -+ efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse), -+ &dma_addr, GFP_KERNEL); -+ if (!efuse) -+ return -ENOMEM; -+ -+ data = dma_alloc_coherent(dev, sizeof(bytes), -+ &dma_buf, GFP_KERNEL); -+ if (!data) { -+ ret = -ENOMEM; -+ goto efuse_data_fail; -+ } -+ -+ if (flag == EFUSE_WRITE) { -+ memcpy(data, val, bytes); -+ efuse->flag = EFUSE_WRITE; -+ } else { -+ efuse->flag = EFUSE_READ; -+ } -+ -+ efuse->src = dma_buf; -+ efuse->size = words; -+ efuse->offset = offset; -+ efuse->pufuserfuse = pufflag; -+ -+ zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret); -+ if (ret != 0) { -+ if (ret == EFUSE_NOT_ENABLED) { -+ dev_err(dev, "efuse access is not enabled\n"); -+ ret = -EOPNOTSUPP; -+ } else { -+ dev_err(dev, "Error in efuse read %x\n", ret); -+ ret = -EPERM; -+ } -+ goto efuse_access_err; -+ } -+ -+ if (flag == EFUSE_READ) -+ memcpy(val, data, bytes); -+efuse_access_err: -+ dma_free_coherent(dev, sizeof(bytes), -+ data, dma_buf); -+efuse_data_fail: -+ dma_free_coherent(dev, sizeof(struct xilinx_efuse), -+ efuse, dma_addr); -+ -+ return ret; -+} -+ -+static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size_t bytes) - { - struct device *dev = context; - int ret; -+ int pufflag = 0; - int idcode; - int version; - -- ret = zynqmp_pm_get_chipid(&idcode, &version); -- if (ret < 0) -- return ret; -+ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET) -+ pufflag = 1; -+ -+ switch (offset) { -+ /* Soc version offset is zero */ -+ case SOC_VERSION_OFFSET: -+ if (bytes != SOC_VER_SIZE) -+ return -EOPNOTSUPP; -+ -+ ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32 *)&version); -+ if (ret < 0) -+ return ret; -+ -+ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version); -+ *(int *)val = version & SILICON_REVISION_MASK; -+ break; -+ /* Efuse offset starts from 0xc */ -+ case EFUSE_START_OFFSET ... EFUSE_END_OFFSET: -+ case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET: -+ ret = zynqmp_efuse_access(context, offset, val, -+ bytes, EFUSE_READ, pufflag); -+ break; -+ default: -+ *(u32 *)val = 0xDEADBEEF; -+ ret = 0; -+ break; -+ } -+ -+ return ret; -+} -+ -+static int zynqmp_nvmem_write(void *context, -+ unsigned int offset, void *val, size_t bytes) -+{ -+ int pufflag = 0; -+ -+ if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET) -+ return -EOPNOTSUPP; - -- dev_dbg(dev, "Read chipid val %x %x\n", idcode, version); -- *(int *)val = version & SILICON_REVISION_MASK; -+ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET) -+ pufflag = 1; - -- return 0; -+ return zynqmp_efuse_access(context, offset, -+ val, bytes, EFUSE_WRITE, pufflag); - } - - static const struct of_device_id zynqmp_nvmem_match[] = { -@@ -45,11 +211,11 @@ static int zynqmp_nvmem_probe(struct pla - econfig.name = "zynqmp-nvmem"; - econfig.owner = THIS_MODULE; - econfig.word_size = 1; -- econfig.size = 1; -+ econfig.size = ZYNQMP_NVMEM_SIZE; - econfig.dev = dev; - econfig.add_legacy_fixed_of_cells = true; -- econfig.read_only = true; - econfig.reg_read = zynqmp_nvmem_read; -+ econfig.reg_write = zynqmp_nvmem_write; - - return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig)); - } diff --git a/target/linux/generic/backport-5.15/836-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch b/target/linux/generic/backport-5.15/836-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch deleted file mode 100644 index c67399cb13d076..00000000000000 --- a/target/linux/generic/backport-5.15/836-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 76c345edef754b16cab81ad9452cc49c09e67066 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Sat, 24 Feb 2024 11:45:14 +0000 -Subject: [PATCH] nvmem: mtk-efuse: Drop NVMEM device name -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT8183 has not one but two efuse devices. The static name and ID -causes the second efuse device to fail to probe, due to duplicate sysfs -entries. - -With the rework of the mtk-socinfo driver, lookup by name is no longer -necessary. The custom name can simply be dropped. - -Signed-off-by: Chen-Yu Tsai -Reviewed-by: AngeloGioacchino Del Regno -Tested-by: "Nícolas F. R. A. Prado" -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240224114516.86365-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/mtk-efuse.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platfo - econfig.size = resource_size(res); - econfig.priv = priv; - econfig.dev = dev; -- econfig.name = "mtk-efuse"; - if (pdata->uses_post_processing) - econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info; - nvmem = devm_nvmem_register(dev, &econfig); diff --git a/target/linux/generic/backport-5.15/836-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch b/target/linux/generic/backport-5.15/836-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch deleted file mode 100644 index 47787d9ad26820..00000000000000 --- a/target/linux/generic/backport-5.15/836-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch +++ /dev/null @@ -1,32 +0,0 @@ -From def3173d4f17b37cecbd74d7c269a080b0b01598 Mon Sep 17 00:00:00 2001 -From: Markus Schneider-Pargmann -Date: Sat, 24 Feb 2024 11:45:16 +0000 -Subject: [PATCH] nvmem: core: Print error on wrong bits DT property - -The algorithms in nvmem core are built with the constraint that -bit_offset < 8. If bit_offset is greater the results are wrong. Print an -error if the devicetree 'bits' property is outside of the valid range -and abort parsing. - -Signed-off-by: Markus Schneider-Pargmann -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240224114516.86365-12-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -807,6 +807,11 @@ static int nvmem_add_cells_from_dt(struc - if (addr && len == (2 * sizeof(u32))) { - info.bit_offset = be32_to_cpup(addr++); - info.nbits = be32_to_cpup(addr); -+ if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) { -+ dev_err(dev, "nvmem: invalid bits on %pOF\n", child); -+ of_node_put(child); -+ return -EINVAL; -+ } - } - - info.np = of_node_get(child); diff --git a/target/linux/generic/backport-5.15/837-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch b/target/linux/generic/backport-5.15/837-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch deleted file mode 100644 index c15b4b2265e73a..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 6d0ca4a2a7e25f9ad07c1f335f20b4d9e048cdd5 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Apr 2024 09:49:11 +0100 -Subject: [PATCH] nvmem: layouts: store owner from modules with - nvmem_layout_driver_register() - -Modules registering driver with nvmem_layout_driver_register() might -forget to set .owner field. The field is used by some of other kernel -parts for reference counting (try_module_get()), so it is expected that -drivers will set it. - -Solve the problem by moving this task away from the drivers to the core -code, just like we did for platform_driver in -commit 9447057eaff8 ("platform_device: use a macro instead of -platform_driver_register"). - -Signed-off-by: Krzysztof Kozlowski -Reviewed-by: Michael Walle -Reviewed-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts.c | 6 ++++-- - include/linux/nvmem-provider.h | 5 ++++- - 2 files changed, 8 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/layouts.c -+++ b/drivers/nvmem/layouts.c -@@ -52,13 +52,15 @@ static struct bus_type nvmem_layout_bus_ - .remove = nvmem_layout_bus_remove, - }; - --int nvmem_layout_driver_register(struct nvmem_layout_driver *drv) -+int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv, -+ struct module *owner) - { - drv->driver.bus = &nvmem_layout_bus_type; -+ drv->driver.owner = owner; - - return driver_register(&drv->driver); - } --EXPORT_SYMBOL_GPL(nvmem_layout_driver_register); -+EXPORT_SYMBOL_GPL(__nvmem_layout_driver_register); - - void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv) - { ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -199,7 +199,10 @@ int nvmem_add_one_cell(struct nvmem_devi - int nvmem_layout_register(struct nvmem_layout *layout); - void nvmem_layout_unregister(struct nvmem_layout *layout); - --int nvmem_layout_driver_register(struct nvmem_layout_driver *drv); -+#define nvmem_layout_driver_register(drv) \ -+ __nvmem_layout_driver_register(drv, THIS_MODULE) -+int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv, -+ struct module *owner); - void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv); - #define module_nvmem_layout_driver(__nvmem_layout_driver) \ - module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \ diff --git a/target/linux/generic/backport-5.15/837-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch b/target/linux/generic/backport-5.15/837-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch deleted file mode 100644 index b483dd243b94b3..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 21833338eccb91194fec6ba7548d9c454824eca0 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Apr 2024 09:49:12 +0100 -Subject: [PATCH] nvmem: layouts: onie-tlv: drop driver owner initialization - -Core in nvmem_layout_driver_register() already sets the .owner, so -driver does not need to. - -Signed-off-by: Krzysztof Kozlowski -Reviewed-by: Michael Walle -Acked-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/onie-tlv.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -247,7 +247,6 @@ MODULE_DEVICE_TABLE(of, onie_tlv_of_matc - - static struct nvmem_layout_driver onie_tlv_layout = { - .driver = { -- .owner = THIS_MODULE, - .name = "onie-tlv-layout", - .of_match_table = onie_tlv_of_match_table, - }, diff --git a/target/linux/generic/backport-5.15/837-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch b/target/linux/generic/backport-5.15/837-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch deleted file mode 100644 index 472a65feca0c54..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 23fd602f21953c03c0714257d36685cd6b486f04 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Apr 2024 09:49:13 +0100 -Subject: [PATCH] nvmem: layouts: sl28vpd: drop driver owner initialization - -Core in nvmem_layout_driver_register() already sets the .owner, so -driver does not need to. - -Signed-off-by: Krzysztof Kozlowski -Reviewed-by: Michael Walle -Reviewed-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/sl28vpd.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -156,7 +156,6 @@ MODULE_DEVICE_TABLE(of, sl28vpd_of_match - - static struct nvmem_layout_driver sl28vpd_layout = { - .driver = { -- .owner = THIS_MODULE, - .name = "kontron-sl28vpd-layout", - .of_match_table = sl28vpd_of_match_table, - }, diff --git a/target/linux/generic/backport-5.15/837-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch b/target/linux/generic/backport-5.15/837-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch deleted file mode 100644 index 2aa13a5c6463b3..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch +++ /dev/null @@ -1,26 +0,0 @@ -From dc3d88ade857ba3dca34f008e0b0aed3ef79cb15 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Apr 2024 09:49:14 +0100 -Subject: [PATCH] nvmem: sc27xx: fix module autoloading - -Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded -based on the alias from of_device_id table. - -Signed-off-by: Krzysztof Kozlowski -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sc27xx-efuse.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/sc27xx-efuse.c -+++ b/drivers/nvmem/sc27xx-efuse.c -@@ -263,6 +263,7 @@ static const struct of_device_id sc27xx_ - { .compatible = "sprd,sc2730-efuse", .data = &sc2730_edata}, - { } - }; -+MODULE_DEVICE_TABLE(of, sc27xx_efuse_of_match); - - static struct platform_driver sc27xx_efuse_driver = { - .probe = sc27xx_efuse_probe, diff --git a/target/linux/generic/backport-5.15/837-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch b/target/linux/generic/backport-5.15/837-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch deleted file mode 100644 index 0953c92340c320..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 154c1ec943e34f3188c9305b0c91d5e7dc1373b8 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Apr 2024 09:49:15 +0100 -Subject: [PATCH] nvmem: sprd: fix module autoloading - -Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded -based on the alias from of_device_id table. - -Signed-off-by: Krzysztof Kozlowski -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sprd-efuse.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/sprd-efuse.c -+++ b/drivers/nvmem/sprd-efuse.c -@@ -426,6 +426,7 @@ static const struct of_device_id sprd_ef - { .compatible = "sprd,ums312-efuse", .data = &ums312_data }, - { } - }; -+MODULE_DEVICE_TABLE(of, sprd_efuse_of_match); - - static struct platform_driver sprd_efuse_driver = { - .probe = sprd_efuse_probe, diff --git a/target/linux/generic/backport-5.15/837-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch b/target/linux/generic/backport-5.15/837-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch deleted file mode 100644 index 07eb08229616c5..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 8d8fc146dd7a0d6a6b37695747a524310dfb9d57 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Tue, 30 Apr 2024 09:49:16 +0100 -Subject: [PATCH] nvmem: core: switch to use device_add_groups() - -devm_device_add_groups() is being removed from the kernel, so move the -nvmem driver to use device_add_groups() instead. The logic is -identical, when the device is removed the driver core will properly -clean up and remove the groups, and the memory used by the attribute -groups will be freed because it was created with dev_* calls, so this is -functionally identical overall. - -Cc: Srinivas Kandagatla -Signed-off-by: Srinivas Kandagatla -Signed-off-by: Greg Kroah-Hartman -Link: https://lore.kernel.org/r/20240430084921.33387-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -478,7 +478,7 @@ static int nvmem_populate_sysfs_cells(st - - nvmem_cells_group.bin_attrs = cells_attrs; - -- ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups); -+ ret = device_add_groups(&nvmem->dev, nvmem_cells_groups); - if (ret) - goto unlock_mutex; - diff --git a/target/linux/generic/backport-5.15/837-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch b/target/linux/generic/backport-5.15/837-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch deleted file mode 100644 index 27d9270d31ee39..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 693d2f629962628ddefc88f4b6b453edda5ac32e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= -Date: Tue, 30 Apr 2024 09:49:17 +0100 -Subject: [PATCH] nvmem: lpc18xx_eeprom: Convert to platform remove callback - returning void -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The .remove() callback for a platform driver returns an int which makes -many driver authors wrongly assume it's possible to do error handling by -returning an error code. However the value returned is ignored (apart -from emitting a warning) and this typically results in resource leaks. - -To improve here there is a quest to make the remove callback return -void. In the first step of this quest all drivers are converted to -.remove_new(), which already returns void. Eventually after all drivers -are converted, .remove_new() will be renamed to .remove(). - -Trivially convert this driver from always returning zero in the remove -callback to the void returning variant. - -Signed-off-by: Uwe Kleine-König -Acked-by: Vladimir Zapolskiy -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/lpc18xx_eeprom.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/lpc18xx_eeprom.c -+++ b/drivers/nvmem/lpc18xx_eeprom.c -@@ -249,13 +249,11 @@ err_clk: - return ret; - } - --static int lpc18xx_eeprom_remove(struct platform_device *pdev) -+static void lpc18xx_eeprom_remove(struct platform_device *pdev) - { - struct lpc18xx_eeprom_dev *eeprom = platform_get_drvdata(pdev); - - clk_disable_unprepare(eeprom->clk); -- -- return 0; - } - - static const struct of_device_id lpc18xx_eeprom_of_match[] = { -@@ -266,7 +264,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_eeprom_o - - static struct platform_driver lpc18xx_eeprom_driver = { - .probe = lpc18xx_eeprom_probe, -- .remove = lpc18xx_eeprom_remove, -+ .remove_new = lpc18xx_eeprom_remove, - .driver = { - .name = "lpc18xx-eeprom", - .of_match_table = lpc18xx_eeprom_of_match, diff --git a/target/linux/generic/backport-5.15/837-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch b/target/linux/generic/backport-5.15/837-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch deleted file mode 100644 index 7770052d97d6cf..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 2a1ad6b75292d38aa2f6ded7335979e0632521da Mon Sep 17 00:00:00 2001 -From: Mukesh Ojha -Date: Tue, 30 Apr 2024 09:49:21 +0100 -Subject: [PATCH] nvmem: meson-mx-efuse: Remove nvmem_device from efuse struct - -nvmem_device is used at one place while registering nvmem -device and it is not required to be present in efuse struct -for just this purpose. - -Drop nvmem_device and manage with nvmem device stack variable. - -Signed-off-by: Mukesh Ojha -Reviewed-by: Martin Blumenstingl -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-12-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/meson-mx-efuse.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/meson-mx-efuse.c -+++ b/drivers/nvmem/meson-mx-efuse.c -@@ -44,7 +44,6 @@ struct meson_mx_efuse_platform_data { - struct meson_mx_efuse { - void __iomem *base; - struct clk *core_clk; -- struct nvmem_device *nvmem; - struct nvmem_config config; - }; - -@@ -194,6 +193,7 @@ static int meson_mx_efuse_probe(struct p - { - const struct meson_mx_efuse_platform_data *drvdata; - struct meson_mx_efuse *efuse; -+ struct nvmem_device *nvmem; - - drvdata = of_device_get_match_data(&pdev->dev); - if (!drvdata) -@@ -224,9 +224,9 @@ static int meson_mx_efuse_probe(struct p - return PTR_ERR(efuse->core_clk); - } - -- efuse->nvmem = devm_nvmem_register(&pdev->dev, &efuse->config); -+ nvmem = devm_nvmem_register(&pdev->dev, &efuse->config); - -- return PTR_ERR_OR_ZERO(efuse->nvmem); -+ return PTR_ERR_OR_ZERO(nvmem); - } - - static struct platform_driver meson_mx_efuse_driver = { diff --git a/target/linux/generic/backport-5.15/837-v6.10-0009-nvmem-rmem-Fix-return-value-of-rmem_read.patch b/target/linux/generic/backport-5.15/837-v6.10-0009-nvmem-rmem-Fix-return-value-of-rmem_read.patch deleted file mode 100644 index 0f0f68b4d714f2..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0009-nvmem-rmem-Fix-return-value-of-rmem_read.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 28b008751aa295612318a0fbb2f22dd4f6a83139 Mon Sep 17 00:00:00 2001 -From: Joy Chakraborty -Date: Fri, 28 Jun 2024 12:37:01 +0100 -Subject: [PATCH] nvmem: rmem: Fix return value of rmem_read() - -reg_read() callback registered with nvmem core expects 0 on success and -a negative value on error but rmem_read() returns the number of bytes -read which is treated as an error at the nvmem core. - -This does not break when rmem is accessed using sysfs via -bin_attr_nvmem_read()/write() but causes an error when accessed from -places like nvmem_access_with_keepouts(), etc. - -Change to return 0 on success and error in case -memory_read_from_buffer() returns an error or -EIO if bytes read do not -match what was requested. - -Fixes: 5a3fa75a4d9c ("nvmem: Add driver to expose reserved memory as nvmem") -Cc: stable@vger.kernel.org -Signed-off-by: Joy Chakraborty -Reviewed-by: Dan Carpenter -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240628113704.13742-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rmem.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/nvmem/rmem.c -+++ b/drivers/nvmem/rmem.c -@@ -46,7 +46,10 @@ static int rmem_read(void *context, unsi - - memunmap(addr); - -- return count; -+ if (count < 0) -+ return count; -+ -+ return count == bytes ? 0 : -EIO; - } - - static int rmem_probe(struct platform_device *pdev) diff --git a/target/linux/generic/backport-5.15/837-v6.10-0010-nvmem-meson-efuse-Fix-return-value-of-nvmem-callback.patch b/target/linux/generic/backport-5.15/837-v6.10-0010-nvmem-meson-efuse-Fix-return-value-of-nvmem-callback.patch deleted file mode 100644 index 9e5d6198b7f336..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0010-nvmem-meson-efuse-Fix-return-value-of-nvmem-callback.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 7a0a6d0a7c805f9380381f4deedffdf87b93f408 Mon Sep 17 00:00:00 2001 -From: Joy Chakraborty -Date: Fri, 28 Jun 2024 12:37:02 +0100 -Subject: [PATCH] nvmem: meson-efuse: Fix return value of nvmem callbacks - -Read/write callbacks registered with nvmem core expect 0 to be returned -on success and a negative value to be returned on failure. - -meson_efuse_read() and meson_efuse_write() call into -meson_sm_call_read() and meson_sm_call_write() respectively which return -the number of bytes read or written on success as per their api -description. - -Fix to return error if meson_sm_call_read()/meson_sm_call_write() -returns an error else return 0. - -Fixes: a29a63bdaf6f ("nvmem: meson-efuse: simplify read callback") -Cc: stable@vger.kernel.org -Signed-off-by: Joy Chakraborty -Reviewed-by: Dan Carpenter -Reviewed-by: Neil Armstrong -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240628113704.13742-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/meson-efuse.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/meson-efuse.c -+++ b/drivers/nvmem/meson-efuse.c -@@ -18,18 +18,24 @@ static int meson_efuse_read(void *contex - void *val, size_t bytes) - { - struct meson_sm_firmware *fw = context; -+ int ret; - -- return meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset, -- bytes, 0, 0, 0); -+ ret = meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset, -+ bytes, 0, 0, 0); -+ -+ return ret < 0 ? ret : 0; - } - - static int meson_efuse_write(void *context, unsigned int offset, - void *val, size_t bytes) - { - struct meson_sm_firmware *fw = context; -+ int ret; -+ -+ ret = meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset, -+ bytes, 0, 0, 0); - -- return meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset, -- bytes, 0, 0, 0); -+ return ret < 0 ? ret : 0; - } - - static const struct of_device_id meson_efuse_match[] = { diff --git a/target/linux/generic/backport-5.15/837-v6.10-0011-nvmem-core-only-change-name-to-fram-for-current-attr.patch b/target/linux/generic/backport-5.15/837-v6.10-0011-nvmem-core-only-change-name-to-fram-for-current-attr.patch deleted file mode 100644 index 064a44999b0890..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0011-nvmem-core-only-change-name-to-fram-for-current-attr.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0ba424c934fd43dccf0d597e1ae8851f07cb2edf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= -Date: Fri, 28 Jun 2024 12:37:03 +0100 -Subject: [PATCH] nvmem: core: only change name to fram for current attribute -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -bin_attr_nvmem_eeprom_compat is the template from which all future -compat attributes are created. -Changing it means to change all subsquent compat attributes, too. - -Instead only use the "fram" name for the currently registered attribute. - -Fixes: fd307a4ad332 ("nvmem: prepare basics for FRAM support") -Cc: stable@vger.kernel.org -Signed-off-by: Thomas Weißschuh -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240628113704.13742-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -397,10 +397,9 @@ static int nvmem_sysfs_setup_compat(stru - if (!config->base_dev) - return -EINVAL; - -- if (config->type == NVMEM_TYPE_FRAM) -- bin_attr_nvmem_eeprom_compat.attr.name = "fram"; -- - nvmem->eeprom = bin_attr_nvmem_eeprom_compat; -+ if (config->type == NVMEM_TYPE_FRAM) -+ nvmem->eeprom.attr.name = "fram"; - nvmem->eeprom.attr.mode = nvmem_bin_attr_get_umode(nvmem); - nvmem->eeprom.size = nvmem->size; - #ifdef CONFIG_DEBUG_LOCK_ALLOC diff --git a/target/linux/generic/backport-5.15/837-v6.10-0012-nvmem-core-limit-cell-sysfs-permissions-to-main-attr.patch b/target/linux/generic/backport-5.15/837-v6.10-0012-nvmem-core-limit-cell-sysfs-permissions-to-main-attr.patch deleted file mode 100644 index 88453e83cca726..00000000000000 --- a/target/linux/generic/backport-5.15/837-v6.10-0012-nvmem-core-limit-cell-sysfs-permissions-to-main-attr.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 6bef98bafd82903a8d461463f9594f19f1fd6a85 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= -Date: Fri, 28 Jun 2024 12:37:04 +0100 -Subject: [PATCH] nvmem: core: limit cell sysfs permissions to main attribute - ones -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The cell sysfs attribute should not provide more access to the nvmem -data than the main attribute itself. -For example if nvme_config::root_only was set, the cell attribute -would still provide read access to everybody. - -Mask out permissions not available on the main attribute. - -Fixes: 0331c611949f ("nvmem: core: Expose cells through sysfs") -Cc: stable@vger.kernel.org -Signed-off-by: Thomas Weißschuh -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240628113704.13742-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -462,7 +462,7 @@ static int nvmem_populate_sysfs_cells(st - attrs[i].attr.name = devm_kasprintf(&nvmem->dev, GFP_KERNEL, - "%s@%x", entry->name, - entry->offset); -- attrs[i].attr.mode = 0444; -+ attrs[i].attr.mode = 0444 & nvmem_bin_attr_get_umode(nvmem); - attrs[i].size = entry->bytes; - attrs[i].read = &nvmem_cell_attr_read; - attrs[i].private = entry; diff --git a/target/linux/generic/backport-5.15/838-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch b/target/linux/generic/backport-5.15/838-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch deleted file mode 100644 index a8ce832408f834..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c553bad4c5fc5ae44bd2fcaa73e1d6bedfb1c35c Mon Sep 17 00:00:00 2001 -From: Jeff Johnson -Date: Fri, 5 Jul 2024 08:48:38 +0100 -Subject: [PATCH] nvmem: add missing MODULE_DESCRIPTION() macros - -make allmodconfig && make W=1 C=1 reports: -WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem-apple-efuses.o -WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_brcm_nvram.o -WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_u-boot-env.o - -Add the missing invocations of the MODULE_DESCRIPTION() macro. - -Signed-off-by: Jeff Johnson -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/apple-efuses.c | 1 + - drivers/nvmem/brcm_nvram.c | 1 + - drivers/nvmem/u-boot-env.c | 1 + - 3 files changed, 3 insertions(+) - ---- a/drivers/nvmem/apple-efuses.c -+++ b/drivers/nvmem/apple-efuses.c -@@ -78,4 +78,5 @@ static struct platform_driver apple_efus - module_platform_driver(apple_efuses_driver); - - MODULE_AUTHOR("Sven Peter "); -+MODULE_DESCRIPTION("Apple SoC eFuse driver"); - MODULE_LICENSE("GPL"); ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -253,5 +253,6 @@ static int __init brcm_nvram_init(void) - subsys_initcall_sync(brcm_nvram_init); - - MODULE_AUTHOR("Rafał Miłecki"); -+MODULE_DESCRIPTION("Broadcom I/O-mapped NVRAM support driver"); - MODULE_LICENSE("GPL"); - MODULE_DEVICE_TABLE(of, brcm_nvram_of_match_table); ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -249,5 +249,6 @@ static struct platform_driver u_boot_env - module_platform_driver(u_boot_env_driver); - - MODULE_AUTHOR("Rafał Miłecki"); -+MODULE_DESCRIPTION("U-Boot environment variables support module"); - MODULE_LICENSE("GPL"); - MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table); diff --git a/target/linux/generic/backport-5.15/838-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch b/target/linux/generic/backport-5.15/838-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch deleted file mode 100644 index 05c82dbf6f560a..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 5fecb932607d83d37a703c731268e9d9051457f5 Mon Sep 17 00:00:00 2001 -From: MarileneGarcia -Date: Fri, 5 Jul 2024 08:48:40 +0100 -Subject: [PATCH] nvmem: meson-efuse: Replacing the use of of_node_put to - __free - -Use __free for device_node values, and thus drop calls to -of_node_put. - -The goal is to reduce memory management issues by using this -scope-based of_node_put() cleanup to simplify function exit -handling. When using __free a resource is allocated within a -block, it is automatically freed at the end of the block. - -Suggested-by: Julia Lawall -Signed-off-by: MarileneGarcia -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/meson-efuse.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/meson-efuse.c -+++ b/drivers/nvmem/meson-efuse.c -@@ -48,20 +48,19 @@ static int meson_efuse_probe(struct plat - { - struct device *dev = &pdev->dev; - struct meson_sm_firmware *fw; -- struct device_node *sm_np; - struct nvmem_device *nvmem; - struct nvmem_config *econfig; - struct clk *clk; - unsigned int size; -+ struct device_node *sm_np __free(device_node) = -+ of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0); - -- sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0); - if (!sm_np) { - dev_err(&pdev->dev, "no secure-monitor node\n"); - return -ENODEV; - } - - fw = meson_sm_get(sm_np); -- of_node_put(sm_np); - if (!fw) - return -EPROBE_DEFER; - diff --git a/target/linux/generic/backport-5.15/838-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch b/target/linux/generic/backport-5.15/838-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch deleted file mode 100644 index a8a30fc8103ef7..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2933e79db3c00a8cdc56f6bb050a857fec1875ad Mon Sep 17 00:00:00 2001 -From: Heiko Stuebner -Date: Fri, 5 Jul 2024 08:48:41 +0100 -Subject: [PATCH] nvmem: rockchip-otp: set add_legacy_fixed_of_cells config - option - -The Rockchip OTP describes its layout via devicetree subnodes, -so set the appropriate property. - -Fixes: 2cc3b37f5b6d ("nvmem: add explicit config option to read old syntax fixed OF cells") -Signed-off-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -255,6 +255,7 @@ static int rockchip_otp_read(void *conte - static struct nvmem_config otp_config = { - .name = "rockchip-otp", - .owner = THIS_MODULE, -+ .add_legacy_fixed_of_cells = true, - .read_only = true, - .stride = 1, - .word_size = 1, diff --git a/target/linux/generic/backport-5.15/838-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch b/target/linux/generic/backport-5.15/838-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch deleted file mode 100644 index 8491eb3c9ce2fb..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 39f95600d8c53355b212a117e91a6ba15e0cac47 Mon Sep 17 00:00:00 2001 -From: Heiko Stuebner -Date: Fri, 5 Jul 2024 08:48:42 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Set type to OTP - -The Rockchip OTP is obviously an OTP memory, so document this fact. - -Signed-off-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -256,6 +256,7 @@ static struct nvmem_config otp_config = - .name = "rockchip-otp", - .owner = THIS_MODULE, - .add_legacy_fixed_of_cells = true, -+ .type = NVMEM_TYPE_OTP, - .read_only = true, - .stride = 1, - .word_size = 1, diff --git a/target/linux/generic/backport-5.15/838-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch b/target/linux/generic/backport-5.15/838-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch deleted file mode 100644 index 260b03eb035fb6..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch +++ /dev/null @@ -1,26 +0,0 @@ -From ba64a04474d2989f397982c48e405cfd785e2dd5 Mon Sep 17 00:00:00 2001 -From: Heiko Stuebner -Date: Fri, 5 Jul 2024 08:48:43 +0100 -Subject: [PATCH] nvmem: rockchip-efuse: set type to OTP - -This device currently reports an "Unknown" type in sysfs. -Since it is an eFuse hardware device, set its type to OTP. - -Signed-off-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-efuse.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/rockchip-efuse.c -+++ b/drivers/nvmem/rockchip-efuse.c -@@ -206,6 +206,7 @@ static int rockchip_rk3399_efuse_read(vo - static struct nvmem_config econfig = { - .name = "rockchip-efuse", - .add_legacy_fixed_of_cells = true, -+ .type = NVMEM_TYPE_OTP, - .stride = 1, - .word_size = 1, - .read_only = true, diff --git a/target/linux/generic/backport-5.15/838-v6.11-0006-nvmem-core-add-single-sysfs-group.patch b/target/linux/generic/backport-5.15/838-v6.11-0006-nvmem-core-add-single-sysfs-group.patch deleted file mode 100644 index 4fb2afd2fa33c9..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0006-nvmem-core-add-single-sysfs-group.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6188f233161c6a5b2d1c396a221dfafc77dc9eec Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= -Date: Fri, 5 Jul 2024 08:48:46 +0100 -Subject: [PATCH] nvmem: core: add single sysfs group -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The sysfs core provides a function to easily register a single group. -Use it and remove the now unnecessary nvmem_cells_groups array. - -Signed-off-by: Thomas Weißschuh -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -368,11 +368,6 @@ static const struct attribute_group *nvm - NULL, - }; - --static const struct attribute_group *nvmem_cells_groups[] = { -- &nvmem_cells_group, -- NULL, --}; -- - static struct bin_attribute bin_attr_nvmem_eeprom_compat = { - .attr = { - .name = "eeprom", -@@ -477,7 +472,7 @@ static int nvmem_populate_sysfs_cells(st - - nvmem_cells_group.bin_attrs = cells_attrs; - -- ret = device_add_groups(&nvmem->dev, nvmem_cells_groups); -+ ret = device_add_group(&nvmem->dev, &nvmem_cells_group); - if (ret) - goto unlock_mutex; - diff --git a/target/linux/generic/backport-5.15/838-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch b/target/linux/generic/backport-5.15/838-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch deleted file mode 100644 index ef626d37a03182..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 6839fed062b7898665983368c88269a6fb1fc10f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= -Date: Fri, 5 Jul 2024 08:48:47 +0100 -Subject: [PATCH] nvmem: core: remove global nvmem_cells_group -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -nvmem_cells_groups is a global variable that is also mutated. -This is complicated and error-prone. - -Instead use a normal stack variable. - -Signed-off-by: Thomas Weißschuh -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-11-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 26 ++++++++++---------------- - 1 file changed, 10 insertions(+), 16 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -358,11 +358,6 @@ static const struct attribute_group nvme - .is_bin_visible = nvmem_bin_attr_is_visible, - }; - --/* Cell attributes will be dynamically allocated */ --static struct attribute_group nvmem_cells_group = { -- .name = "cells", --}; -- - static const struct attribute_group *nvmem_dev_groups[] = { - &nvmem_bin_group, - NULL, -@@ -424,23 +419,24 @@ static void nvmem_sysfs_remove_compat(st - - static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem) - { -- struct bin_attribute **cells_attrs, *attrs; -+ struct attribute_group group = { -+ .name = "cells", -+ }; - struct nvmem_cell_entry *entry; -+ struct bin_attribute *attrs; - unsigned int ncells = 0, i = 0; - int ret = 0; - - mutex_lock(&nvmem_mutex); - -- if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) { -- nvmem_cells_group.bin_attrs = NULL; -+ if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) - goto unlock_mutex; -- } - - /* Allocate an array of attributes with a sentinel */ - ncells = list_count_nodes(&nvmem->cells); -- cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1, -- sizeof(struct bin_attribute *), GFP_KERNEL); -- if (!cells_attrs) { -+ group.bin_attrs = devm_kcalloc(&nvmem->dev, ncells + 1, -+ sizeof(struct bin_attribute *), GFP_KERNEL); -+ if (!group.bin_attrs) { - ret = -ENOMEM; - goto unlock_mutex; - } -@@ -466,13 +462,11 @@ static int nvmem_populate_sysfs_cells(st - goto unlock_mutex; - } - -- cells_attrs[i] = &attrs[i]; -+ group.bin_attrs[i] = &attrs[i]; - i++; - } - -- nvmem_cells_group.bin_attrs = cells_attrs; -- -- ret = device_add_group(&nvmem->dev, &nvmem_cells_group); -+ ret = device_add_group(&nvmem->dev, &group); - if (ret) - goto unlock_mutex; - diff --git a/target/linux/generic/backport-5.15/838-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch b/target/linux/generic/backport-5.15/838-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch deleted file mode 100644 index 9b6251b919eba9..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 588773802c386d38f9c4e91acd47369e89d95a30 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= -Date: Fri, 5 Jul 2024 08:48:48 +0100 -Subject: [PATCH] nvmem: core: drop unnecessary range checks in sysfs callbacks -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The same checks have already been done in sysfs_kf_bin_write() and -sysfs_kf_bin_read() just before the callbacks are invoked. - -Signed-off-by: Thomas Weißschuh -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-12-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 14 -------------- - 1 file changed, 14 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -204,19 +204,12 @@ static ssize_t bin_attr_nvmem_read(struc - dev = kobj_to_dev(kobj); - nvmem = to_nvmem_device(dev); - -- /* Stop the user from reading */ -- if (pos >= nvmem->size) -- return 0; -- - if (!IS_ALIGNED(pos, nvmem->stride)) - return -EINVAL; - - if (count < nvmem->word_size) - return -EINVAL; - -- if (pos + count > nvmem->size) -- count = nvmem->size - pos; -- - count = round_down(count, nvmem->word_size); - - if (!nvmem->reg_read) -@@ -244,19 +237,12 @@ static ssize_t bin_attr_nvmem_write(stru - dev = kobj_to_dev(kobj); - nvmem = to_nvmem_device(dev); - -- /* Stop the user from writing */ -- if (pos >= nvmem->size) -- return -EFBIG; -- - if (!IS_ALIGNED(pos, nvmem->stride)) - return -EINVAL; - - if (count < nvmem->word_size) - return -EINVAL; - -- if (pos + count > nvmem->size) -- count = nvmem->size - pos; -- - count = round_down(count, nvmem->word_size); - - if (!nvmem->reg_write) diff --git a/target/linux/generic/backport-5.15/838-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch b/target/linux/generic/backport-5.15/838-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch deleted file mode 100644 index 3da1febaf10453..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 08c367e45b6d322956878774f0b88bf5e52c6d54 Mon Sep 17 00:00:00 2001 -From: Marek Vasut -Date: Fri, 5 Jul 2024 08:48:51 +0100 -Subject: [PATCH] nvmem: Use sysfs_emit() for type attribute - -Use sysfs_emit() instead of sprintf() to follow best practice per -Documentation/filesystems/sysfs.rst -" -show() should only use sysfs_emit()... -" - -Signed-off-by: Marek Vasut -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-15-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -180,7 +180,7 @@ static ssize_t type_show(struct device * - { - struct nvmem_device *nvmem = to_nvmem_device(dev); - -- return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]); -+ return sysfs_emit(buf, "%s\n", nvmem_type_str[nvmem->type]); - } - - static DEVICE_ATTR_RO(type); diff --git a/target/linux/generic/backport-5.15/838-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch b/target/linux/generic/backport-5.15/838-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch deleted file mode 100644 index ac7dda1bdf4298..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 9d7eb234ac7a56b88aea8a52ed81553a730fe25c Mon Sep 17 00:00:00 2001 -From: Marek Vasut -Date: Fri, 5 Jul 2024 08:48:52 +0100 -Subject: [PATCH] nvmem: core: Implement force_ro sysfs attribute - -Implement "force_ro" sysfs attribute to allow users to set read-write -devices as read-only and back to read-write from userspace. The choice -of the name is based on MMC core 'force_ro' attribute. - -This solves a situation where an AT24 I2C EEPROM with GPIO based nWP -signal may have to be occasionally updated. Such I2C EEPROM device is -usually set as read-only during most of the regular system operation, -but in case it has to be updated in a controlled manner, it could be -unlocked using this new "force_ro" sysfs attribute and then re-locked -again. - -The "read-only" DT property and config->read_only configuration is -respected and is used to set default state of the device, read-only -or read-write, for devices which do implement .reg_write function. -For devices which do not implement .reg_write function, the device -is unconditionally read-only and the "force_ro" attribute is not -visible. - -Signed-off-by: Marek Vasut -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-16-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - Documentation/ABI/stable/sysfs-bus-nvmem | 17 ++++++++++ - drivers/nvmem/core.c | 43 ++++++++++++++++++++++++ - 2 files changed, 60 insertions(+) - ---- a/Documentation/ABI/stable/sysfs-bus-nvmem -+++ b/Documentation/ABI/stable/sysfs-bus-nvmem -@@ -1,3 +1,20 @@ -+What: /sys/bus/nvmem/devices/.../force_ro -+Date: June 2024 -+KernelVersion: 6.11 -+Contact: Marek Vasut -+Description: -+ This read/write attribute allows users to set read-write -+ devices as read-only and back to read-write from userspace. -+ This can be used to unlock and relock write-protection of -+ devices which are generally locked, except during sporadic -+ programming operation. -+ Read returns '0' or '1' for read-write or read-only modes -+ respectively. -+ Write parses one of 'YyTt1NnFf0', or [oO][NnFf] for "on" -+ and "off", i.e. what kstrbool() supports. -+ Note: This file is only present if CONFIG_NVMEM_SYSFS -+ is enabled. -+ - What: /sys/bus/nvmem/devices/.../nvmem - Date: July 2015 - KernelVersion: 4.2 ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -185,7 +185,30 @@ static ssize_t type_show(struct device * - - static DEVICE_ATTR_RO(type); - -+static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct nvmem_device *nvmem = to_nvmem_device(dev); -+ -+ return sysfs_emit(buf, "%d\n", nvmem->read_only); -+} -+ -+static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct nvmem_device *nvmem = to_nvmem_device(dev); -+ int ret = kstrtobool(buf, &nvmem->read_only); -+ -+ if (ret < 0) -+ return ret; -+ -+ return count; -+} -+ -+static DEVICE_ATTR_RW(force_ro); -+ - static struct attribute *nvmem_attrs[] = { -+ &dev_attr_force_ro.attr, - &dev_attr_type.attr, - NULL, - }; -@@ -286,6 +309,25 @@ static umode_t nvmem_bin_attr_is_visible - return nvmem_bin_attr_get_umode(nvmem); - } - -+static umode_t nvmem_attr_is_visible(struct kobject *kobj, -+ struct attribute *attr, int i) -+{ -+ struct device *dev = kobj_to_dev(kobj); -+ struct nvmem_device *nvmem = to_nvmem_device(dev); -+ -+ /* -+ * If the device has no .reg_write operation, do not allow -+ * configuration as read-write. -+ * If the device is set as read-only by configuration, it -+ * can be forced into read-write mode using the 'force_ro' -+ * attribute. -+ */ -+ if (attr == &dev_attr_force_ro.attr && !nvmem->reg_write) -+ return 0; /* Attribute not visible */ -+ -+ return attr->mode; -+} -+ - static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, - const char *id, int index); - -@@ -342,6 +384,7 @@ static const struct attribute_group nvme - .bin_attrs = nvmem_bin_attributes, - .attrs = nvmem_attrs, - .is_bin_visible = nvmem_bin_attr_is_visible, -+ .is_visible = nvmem_attr_is_visible, - }; - - static const struct attribute_group *nvmem_dev_groups[] = { diff --git a/target/linux/generic/backport-5.15/838-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch b/target/linux/generic/backport-5.15/838-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch deleted file mode 100644 index 70d420f205fb63..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 8679e8b4a1ebdb40c4429e49368d29353e07b601 Mon Sep 17 00:00:00 2001 -From: John Thomson -Date: Mon, 2 Sep 2024 15:25:08 +0100 -Subject: [PATCH] nvmem: u-boot-env: error if NVMEM device is too small -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Verify data size before trying to parse it to avoid reading out of -buffer. This could happen in case of problems at MTD level or invalid DT -bindings. - -Signed-off-by: John Thomson -Cc: stable -Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables") -[rmilecki: simplify commit description & rebase] -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240902142510.71096-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -176,6 +176,13 @@ static int u_boot_env_parse(struct u_boo - data_offset = offsetof(struct u_boot_env_image_broadcom, data); - break; - } -+ -+ if (dev_size < data_offset) { -+ dev_err(dev, "Device too small for u-boot-env\n"); -+ err = -EIO; -+ goto err_kfree; -+ } -+ - crc32_addr = (__le32 *)(buf + crc32_offset); - crc32 = le32_to_cpu(*crc32_addr); - crc32_data_len = dev_size - crc32_data_offset; diff --git a/target/linux/generic/backport-5.15/838-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch b/target/linux/generic/backport-5.15/838-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch deleted file mode 100644 index 08f627884993ca..00000000000000 --- a/target/linux/generic/backport-5.15/838-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch +++ /dev/null @@ -1,37 +0,0 @@ -From c69f37f6559a8948d70badd2b179db7714dedd62 Mon Sep 17 00:00:00 2001 -From: Geert Uytterhoeven -Date: Mon, 2 Sep 2024 15:25:09 +0100 -Subject: [PATCH] nvmem: Fix return type of devm_nvmem_device_get() in - kerneldoc - -devm_nvmem_device_get() returns an nvmem device, not an nvmem cell. - -Fixes: e2a5402ec7c6d044 ("nvmem: Add nvmem_device based consumer apis.") -Cc: stable -Signed-off-by: Geert Uytterhoeven -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240902142510.71096-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -1276,13 +1276,13 @@ void nvmem_device_put(struct nvmem_devic - EXPORT_SYMBOL_GPL(nvmem_device_put); - - /** -- * devm_nvmem_device_get() - Get nvmem cell of device form a given id -+ * devm_nvmem_device_get() - Get nvmem device of device form a given id - * - * @dev: Device that requests the nvmem device. - * @id: name id for the requested nvmem device. - * -- * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_cell -- * on success. The nvmem_cell will be freed by the automatically once the -+ * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device -+ * on success. The nvmem_device will be freed by the automatically once the - * device is freed. - */ - struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id) diff --git a/target/linux/generic/backport-5.15/839-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch b/target/linux/generic/backport-5.15/839-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch deleted file mode 100644 index c19931b3fa01e6..00000000000000 --- a/target/linux/generic/backport-5.15/839-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch +++ /dev/null @@ -1,73 +0,0 @@ -From c3f9b7b4e5f9de319d00784577cda42036ff243a Mon Sep 17 00:00:00 2001 -From: Peng Fan -Date: Mon, 2 Sep 2024 15:29:45 +0100 -Subject: [PATCH] nvmem: imx-ocotp-ele: support i.MX95 - -i.MX95 OCOTP has same accessing method, so add an entry for i.MX95, but -some fuse has ECC feature, so only read out the lower 16bits for ECC fuses. - -Signed-off-by: Peng Fan -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240902142952.71639-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/imx-ocotp-ele.c | 32 +++++++++++++++++++++++++++++--- - 1 file changed, 29 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/imx-ocotp-ele.c -+++ b/drivers/nvmem/imx-ocotp-ele.c -@@ -14,8 +14,9 @@ - #include - - enum fuse_type { -- FUSE_FSB = 1, -- FUSE_ELE = 2, -+ FUSE_FSB = BIT(0), -+ FUSE_ELE = BIT(1), -+ FUSE_ECC = BIT(2), - FUSE_INVALID = -1 - }; - -@@ -93,7 +94,10 @@ static int imx_ocotp_reg_read(void *cont - continue; - } - -- *buf++ = readl_relaxed(reg + (i << 2)); -+ if (type & FUSE_ECC) -+ *buf++ = readl_relaxed(reg + (i << 2)) & GENMASK(15, 0); -+ else -+ *buf++ = readl_relaxed(reg + (i << 2)); - } - - memcpy(val, (u8 *)p, bytes); -@@ -155,8 +159,30 @@ static const struct ocotp_devtype_data i - }, - }; - -+static const struct ocotp_devtype_data imx95_ocotp_data = { -+ .reg_off = 0x8000, -+ .reg_read = imx_ocotp_reg_read, -+ .size = 2048, -+ .num_entry = 12, -+ .entry = { -+ { 0, 1, FUSE_FSB | FUSE_ECC }, -+ { 7, 1, FUSE_FSB | FUSE_ECC }, -+ { 9, 3, FUSE_FSB | FUSE_ECC }, -+ { 12, 24, FUSE_FSB }, -+ { 36, 2, FUSE_FSB | FUSE_ECC }, -+ { 38, 14, FUSE_FSB }, -+ { 63, 1, FUSE_ELE }, -+ { 128, 16, FUSE_ELE }, -+ { 188, 1, FUSE_ELE }, -+ { 317, 2, FUSE_FSB | FUSE_ECC }, -+ { 320, 7, FUSE_FSB }, -+ { 328, 184, FUSE_FSB } -+ }, -+}; -+ - static const struct of_device_id imx_ele_ocotp_dt_ids[] = { - { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, }, -+ { .compatible = "fsl,imx95-ocotp", .data = &imx95_ocotp_data, }, - {}, - }; - MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids); diff --git a/target/linux/generic/backport-5.15/839-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch b/target/linux/generic/backport-5.15/839-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch deleted file mode 100644 index 13ef50b1579600..00000000000000 --- a/target/linux/generic/backport-5.15/839-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 98ee46391baf35987227236d0c3bb30ab6e758c8 Mon Sep 17 00:00:00 2001 -From: Zhang Zekun -Date: Mon, 2 Sep 2024 15:29:50 +0100 -Subject: [PATCH] nvmem: sunplus-ocotp: Use - devm_platform_ioremap_resource_byname() helper function - -platform_get_resource_byname() and devm_ioremap_resource() can be -replaced by devm_platform_ioremap_resource_byname(), which can -simplify the code logic a bit, No functional change here. - -Signed-off-by: Zhang Zekun -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240902142952.71639-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sunplus-ocotp.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - ---- a/drivers/nvmem/sunplus-ocotp.c -+++ b/drivers/nvmem/sunplus-ocotp.c -@@ -159,7 +159,6 @@ static int sp_ocotp_probe(struct platfor - struct device *dev = &pdev->dev; - struct nvmem_device *nvmem; - struct sp_ocotp_priv *otp; -- struct resource *res; - int ret; - - otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL); -@@ -168,13 +167,11 @@ static int sp_ocotp_probe(struct platfor - - otp->dev = dev; - -- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio"); -- otp->base[HB_GPIO] = devm_ioremap_resource(dev, res); -+ otp->base[HB_GPIO] = devm_platform_ioremap_resource_byname(pdev, "hb_gpio"); - if (IS_ERR(otp->base[HB_GPIO])) - return PTR_ERR(otp->base[HB_GPIO]); - -- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx"); -- otp->base[OTPRX] = devm_ioremap_resource(dev, res); -+ otp->base[OTPRX] = devm_platform_ioremap_resource_byname(pdev, "otprx"); - if (IS_ERR(otp->base[OTPRX])) - return PTR_ERR(otp->base[OTPRX]); - diff --git a/target/linux/generic/backport-5.15/839-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch b/target/linux/generic/backport-5.15/839-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch deleted file mode 100644 index 138e602a54e1dd..00000000000000 --- a/target/linux/generic/backport-5.15/839-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch +++ /dev/null @@ -1,515 +0,0 @@ -From 5f15811286aff4664bf275a7ede64e1b8858151b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 2 Sep 2024 15:29:47 +0100 -Subject: [PATCH] nvmem: layouts: add U-Boot env layout -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -U-Boot environment variables are stored in a specific format. Actual -data can be placed in various storage sources (MTD, UBI volume, EEPROM, -NVRAM, etc.). - -Move all generic (NVMEM device independent) code from NVMEM device -driver to an NVMEM layout driver. Then add a simple NVMEM layout code on -top of it. - -This allows using NVMEM layout for parsing U-Boot env data stored in any -kind of NVMEM device. - -The old NVMEM glue driver stays in place for handling bindings in the -MTD context. To avoid code duplication it uses exported layout parsing -function. Please note that handling MTD & NVMEM layout bindings may be -refactored in the future. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240902142952.71639-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - MAINTAINERS | 1 + - drivers/nvmem/Kconfig | 3 +- - drivers/nvmem/layouts/Kconfig | 11 ++ - drivers/nvmem/layouts/Makefile | 1 + - drivers/nvmem/layouts/u-boot-env.c | 211 +++++++++++++++++++++++++++++ - drivers/nvmem/layouts/u-boot-env.h | 15 ++ - drivers/nvmem/u-boot-env.c | 165 +--------------------- - 7 files changed, 242 insertions(+), 165 deletions(-) - create mode 100644 drivers/nvmem/layouts/u-boot-env.c - create mode 100644 drivers/nvmem/layouts/u-boot-env.h - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -363,8 +363,7 @@ config NVMEM_SUNXI_SID - config NVMEM_U_BOOT_ENV - tristate "U-Boot environment variables support" - depends on OF && MTD -- select CRC32 -- select GENERIC_NET_UTILS -+ select NVMEM_LAYOUT_U_BOOT_ENV - help - U-Boot stores its setup as environment variables. This driver adds - support for verifying & exporting such data. It also exposes variables ---- a/drivers/nvmem/layouts/Kconfig -+++ b/drivers/nvmem/layouts/Kconfig -@@ -26,6 +26,17 @@ config NVMEM_LAYOUT_ONIE_TLV - - If unsure, say N. - -+config NVMEM_LAYOUT_U_BOOT_ENV -+ tristate "U-Boot environment variables layout" -+ select CRC32 -+ select GENERIC_NET_UTILS -+ help -+ U-Boot stores its setup as environment variables. This driver adds -+ support for verifying & exporting such data. It also exposes variables -+ as NVMEM cells so they can be referenced by other drivers. -+ -+ If unsure, say N. -+ - endmenu - - endif ---- a/drivers/nvmem/layouts/Makefile -+++ b/drivers/nvmem/layouts/Makefile -@@ -5,3 +5,4 @@ - - obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o - obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o -+obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o ---- /dev/null -+++ b/drivers/nvmem/layouts/u-boot-env.c -@@ -0,0 +1,211 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (C) 2022 - 2023 Rafał Miłecki -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "u-boot-env.h" -+ -+struct u_boot_env_image_single { -+ __le32 crc32; -+ uint8_t data[]; -+} __packed; -+ -+struct u_boot_env_image_redundant { -+ __le32 crc32; -+ u8 mark; -+ uint8_t data[]; -+} __packed; -+ -+struct u_boot_env_image_broadcom { -+ __le32 magic; -+ __le32 len; -+ __le32 crc32; -+ DECLARE_FLEX_ARRAY(uint8_t, data); -+} __packed; -+ -+static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, -+ unsigned int offset, void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (bytes != 3 * ETH_ALEN - 1) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ -+static int u_boot_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf, -+ size_t data_offset, size_t data_len) -+{ -+ char *data = buf + data_offset; -+ char *var, *value, *eq; -+ -+ for (var = data; -+ var < data + data_len && *var; -+ var = value + strlen(value) + 1) { -+ struct nvmem_cell_info info = {}; -+ -+ eq = strchr(var, '='); -+ if (!eq) -+ break; -+ *eq = '\0'; -+ value = eq + 1; -+ -+ info.name = devm_kstrdup(dev, var, GFP_KERNEL); -+ if (!info.name) -+ return -ENOMEM; -+ info.offset = data_offset + value - data; -+ info.bytes = strlen(value); -+ info.np = of_get_child_by_name(dev->of_node, info.name); -+ if (!strcmp(var, "ethaddr")) { -+ info.raw_len = strlen(value); -+ info.bytes = ETH_ALEN; -+ info.read_post_process = u_boot_env_read_post_process_ethaddr; -+ } -+ -+ nvmem_add_one_cell(nvmem, &info); -+ } -+ -+ return 0; -+} -+ -+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem, -+ enum u_boot_env_format format) -+{ -+ size_t crc32_data_offset; -+ size_t crc32_data_len; -+ size_t crc32_offset; -+ __le32 *crc32_addr; -+ size_t data_offset; -+ size_t data_len; -+ size_t dev_size; -+ uint32_t crc32; -+ uint32_t calc; -+ uint8_t *buf; -+ int bytes; -+ int err; -+ -+ dev_size = nvmem_dev_size(nvmem); -+ -+ buf = kzalloc(dev_size, GFP_KERNEL); -+ if (!buf) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf); -+ if (bytes < 0) { -+ err = bytes; -+ goto err_kfree; -+ } else if (bytes != dev_size) { -+ err = -EIO; -+ goto err_kfree; -+ } -+ -+ switch (format) { -+ case U_BOOT_FORMAT_SINGLE: -+ crc32_offset = offsetof(struct u_boot_env_image_single, crc32); -+ crc32_data_offset = offsetof(struct u_boot_env_image_single, data); -+ data_offset = offsetof(struct u_boot_env_image_single, data); -+ break; -+ case U_BOOT_FORMAT_REDUNDANT: -+ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32); -+ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); -+ data_offset = offsetof(struct u_boot_env_image_redundant, data); -+ break; -+ case U_BOOT_FORMAT_BROADCOM: -+ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32); -+ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data); -+ data_offset = offsetof(struct u_boot_env_image_broadcom, data); -+ break; -+ } -+ -+ if (dev_size < data_offset) { -+ dev_err(dev, "Device too small for u-boot-env\n"); -+ err = -EIO; -+ goto err_kfree; -+ } -+ -+ crc32_addr = (__le32 *)(buf + crc32_offset); -+ crc32 = le32_to_cpu(*crc32_addr); -+ crc32_data_len = dev_size - crc32_data_offset; -+ data_len = dev_size - data_offset; -+ -+ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; -+ if (calc != crc32) { -+ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); -+ err = -EINVAL; -+ goto err_kfree; -+ } -+ -+ buf[dev_size - 1] = '\0'; -+ err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len); -+ -+err_kfree: -+ kfree(buf); -+err_out: -+ return err; -+} -+EXPORT_SYMBOL_GPL(u_boot_env_parse); -+ -+static int u_boot_env_add_cells(struct nvmem_layout *layout) -+{ -+ struct device *dev = &layout->dev; -+ enum u_boot_env_format format; -+ -+ format = (uintptr_t)device_get_match_data(dev); -+ -+ return u_boot_env_parse(dev, layout->nvmem, format); -+} -+ -+static int u_boot_env_probe(struct nvmem_layout *layout) -+{ -+ layout->add_cells = u_boot_env_add_cells; -+ -+ return nvmem_layout_register(layout); -+} -+ -+static void u_boot_env_remove(struct nvmem_layout *layout) -+{ -+ nvmem_layout_unregister(layout); -+} -+ -+static const struct of_device_id u_boot_env_of_match_table[] = { -+ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, }, -+ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, -+ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, -+ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, }, -+ {}, -+}; -+ -+static struct nvmem_layout_driver u_boot_env_layout = { -+ .driver = { -+ .name = "u-boot-env-layout", -+ .of_match_table = u_boot_env_of_match_table, -+ }, -+ .probe = u_boot_env_probe, -+ .remove = u_boot_env_remove, -+}; -+module_nvmem_layout_driver(u_boot_env_layout); -+ -+MODULE_AUTHOR("Rafał Miłecki"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table); -+MODULE_DESCRIPTION("NVMEM layout driver for U-Boot environment variables"); ---- /dev/null -+++ b/drivers/nvmem/layouts/u-boot-env.h -@@ -0,0 +1,15 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H -+#define _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H -+ -+enum u_boot_env_format { -+ U_BOOT_FORMAT_SINGLE, -+ U_BOOT_FORMAT_REDUNDANT, -+ U_BOOT_FORMAT_BROADCOM, -+}; -+ -+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem, -+ enum u_boot_env_format format); -+ -+#endif /* ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H */ ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -3,23 +3,15 @@ - * Copyright (C) 2022 Rafał Miłecki - */ - --#include --#include --#include - #include - #include - #include --#include - #include - #include - #include - #include - --enum u_boot_env_format { -- U_BOOT_FORMAT_SINGLE, -- U_BOOT_FORMAT_REDUNDANT, -- U_BOOT_FORMAT_BROADCOM, --}; -+#include "layouts/u-boot-env.h" - - struct u_boot_env { - struct device *dev; -@@ -29,24 +21,6 @@ struct u_boot_env { - struct mtd_info *mtd; - }; - --struct u_boot_env_image_single { -- __le32 crc32; -- uint8_t data[]; --} __packed; -- --struct u_boot_env_image_redundant { -- __le32 crc32; -- u8 mark; -- uint8_t data[]; --} __packed; -- --struct u_boot_env_image_broadcom { -- __le32 magic; -- __le32 len; -- __le32 crc32; -- DECLARE_FLEX_ARRAY(uint8_t, data); --} __packed; -- - static int u_boot_env_read(void *context, unsigned int offset, void *val, - size_t bytes) - { -@@ -69,141 +43,6 @@ static int u_boot_env_read(void *context - return 0; - } - --static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, -- unsigned int offset, void *buf, size_t bytes) --{ -- u8 mac[ETH_ALEN]; -- -- if (bytes != 3 * ETH_ALEN - 1) -- return -EINVAL; -- -- if (!mac_pton(buf, mac)) -- return -EINVAL; -- -- if (index) -- eth_addr_add(mac, index); -- -- ether_addr_copy(buf, mac); -- -- return 0; --} -- --static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, -- size_t data_offset, size_t data_len) --{ -- struct nvmem_device *nvmem = priv->nvmem; -- struct device *dev = priv->dev; -- char *data = buf + data_offset; -- char *var, *value, *eq; -- -- for (var = data; -- var < data + data_len && *var; -- var = value + strlen(value) + 1) { -- struct nvmem_cell_info info = {}; -- -- eq = strchr(var, '='); -- if (!eq) -- break; -- *eq = '\0'; -- value = eq + 1; -- -- info.name = devm_kstrdup(dev, var, GFP_KERNEL); -- if (!info.name) -- return -ENOMEM; -- info.offset = data_offset + value - data; -- info.bytes = strlen(value); -- info.np = of_get_child_by_name(dev->of_node, info.name); -- if (!strcmp(var, "ethaddr")) { -- info.raw_len = strlen(value); -- info.bytes = ETH_ALEN; -- info.read_post_process = u_boot_env_read_post_process_ethaddr; -- } -- -- nvmem_add_one_cell(nvmem, &info); -- } -- -- return 0; --} -- --static int u_boot_env_parse(struct u_boot_env *priv) --{ -- struct nvmem_device *nvmem = priv->nvmem; -- struct device *dev = priv->dev; -- size_t crc32_data_offset; -- size_t crc32_data_len; -- size_t crc32_offset; -- __le32 *crc32_addr; -- size_t data_offset; -- size_t data_len; -- size_t dev_size; -- uint32_t crc32; -- uint32_t calc; -- uint8_t *buf; -- int bytes; -- int err; -- -- dev_size = nvmem_dev_size(nvmem); -- -- buf = kzalloc(dev_size, GFP_KERNEL); -- if (!buf) { -- err = -ENOMEM; -- goto err_out; -- } -- -- bytes = nvmem_device_read(nvmem, 0, dev_size, buf); -- if (bytes < 0) { -- err = bytes; -- goto err_kfree; -- } else if (bytes != dev_size) { -- err = -EIO; -- goto err_kfree; -- } -- -- switch (priv->format) { -- case U_BOOT_FORMAT_SINGLE: -- crc32_offset = offsetof(struct u_boot_env_image_single, crc32); -- crc32_data_offset = offsetof(struct u_boot_env_image_single, data); -- data_offset = offsetof(struct u_boot_env_image_single, data); -- break; -- case U_BOOT_FORMAT_REDUNDANT: -- crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32); -- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); -- data_offset = offsetof(struct u_boot_env_image_redundant, data); -- break; -- case U_BOOT_FORMAT_BROADCOM: -- crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32); -- crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data); -- data_offset = offsetof(struct u_boot_env_image_broadcom, data); -- break; -- } -- -- if (dev_size < data_offset) { -- dev_err(dev, "Device too small for u-boot-env\n"); -- err = -EIO; -- goto err_kfree; -- } -- -- crc32_addr = (__le32 *)(buf + crc32_offset); -- crc32 = le32_to_cpu(*crc32_addr); -- crc32_data_len = dev_size - crc32_data_offset; -- data_len = dev_size - data_offset; -- -- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; -- if (calc != crc32) { -- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); -- err = -EINVAL; -- goto err_kfree; -- } -- -- buf[dev_size - 1] = '\0'; -- err = u_boot_env_add_cells(priv, buf, data_offset, data_len); -- --err_kfree: -- kfree(buf); --err_out: -- return err; --} -- - static int u_boot_env_probe(struct platform_device *pdev) - { - struct nvmem_config config = { -@@ -235,7 +74,7 @@ static int u_boot_env_probe(struct platf - if (IS_ERR(priv->nvmem)) - return PTR_ERR(priv->nvmem); - -- return u_boot_env_parse(priv); -+ return u_boot_env_parse(dev, priv->nvmem, priv->format); - } - - static const struct of_device_id u_boot_env_of_match_table[] = { diff --git a/target/linux/generic/backport-5.15/860-v5.17-MIPS-ath79-drop-_machine_restart-again.patch b/target/linux/generic/backport-5.15/860-v5.17-MIPS-ath79-drop-_machine_restart-again.patch deleted file mode 100644 index e9d692b651a3af..00000000000000 --- a/target/linux/generic/backport-5.15/860-v5.17-MIPS-ath79-drop-_machine_restart-again.patch +++ /dev/null @@ -1,49 +0,0 @@ -From d3115128bdafb62628ab41861a4f06f6d02ac320 Mon Sep 17 00:00:00 2001 -From: Lech Perczak -Date: Mon, 10 Jan 2022 23:48:44 +0100 -Subject: MIPS: ath79: drop _machine_restart again - -Commit 81424d0ad0d4 ("MIPS: ath79: Use the reset controller to restart -OF machines") removed setup of _machine_restart on OF machines to use -reset handler in reset controller driver. -While removing remnants of non-OF machines in commit 3a77e0d75eed -("MIPS: ath79: drop machfiles"), this was introduced again, making it -impossible to use additional restart handlers registered through device -tree. Drop setting _machine_restart altogether, and ath79_restart -function, which is no longer used after this. - -Fixes: 3a77e0d75eed ("MIPS: ath79: drop machfiles") -Cc: John Crispin -Cc: Florian Fainelli -Signed-off-by: Lech Perczak -Signed-off-by: Thomas Bogendoerfer ---- - arch/mips/ath79/setup.c | 10 ---------- - 1 file changed, 10 deletions(-) - ---- a/arch/mips/ath79/setup.c -+++ b/arch/mips/ath79/setup.c -@@ -34,15 +34,6 @@ - - static char ath79_sys_type[ATH79_SYS_TYPE_LEN]; - --static void ath79_restart(char *command) --{ -- local_irq_disable(); -- ath79_device_reset_set(AR71XX_RESET_FULL_CHIP); -- for (;;) -- if (cpu_wait) -- cpu_wait(); --} -- - static void ath79_halt(void) - { - while (1) -@@ -234,7 +225,6 @@ void __init plat_mem_setup(void) - - detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); - -- _machine_restart = ath79_restart; - _machine_halt = ath79_halt; - pm_power_off = ath79_halt; - } diff --git a/target/linux/generic/backport-5.15/870-v5.18-hwmon-lm70-Add-ti-tmp125-support.patch b/target/linux/generic/backport-5.15/870-v5.18-hwmon-lm70-Add-ti-tmp125-support.patch deleted file mode 100644 index fabf177628f058..00000000000000 --- a/target/linux/generic/backport-5.15/870-v5.18-hwmon-lm70-Add-ti-tmp125-support.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 31d8f414e1596ba54a4315418e4c0086fda9e428 Mon Sep 17 00:00:00 2001 -From: Christian Lamparter -Date: Fri, 18 Feb 2022 10:06:43 +0100 -Subject: hwmon: (lm70) Add ti,tmp125 support - -The TMP125 is a 2 degree Celsius accurate Digital -Temperature Sensor with a SPI interface. - -The temperature register is a 16-bit, read-only register. -The MSB (Bit 15) is a leading zero and never set. Bits 14 -to 5 are the 1+9 temperature data bits in a two's -complement format. Bits 4 to 0 are useless copies of -Bit 5 value and therefore ignored. - -Signed-off-by: Christian Lamparter -Link: https://lore.kernel.org/r/43b19cbd4e7f51e9509e561b02b5d8d0e7079fac.1645175187.git.chunkeey@gmail.com -Signed-off-by: Guenter Roeck ---- ---- a/drivers/hwmon/lm70.c -+++ b/drivers/hwmon/lm70.c -@@ -34,6 +34,7 @@ - #define LM70_CHIP_LM71 2 /* NS LM71 */ - #define LM70_CHIP_LM74 3 /* NS LM74 */ - #define LM70_CHIP_TMP122 4 /* TI TMP122/TMP124 */ -+#define LM70_CHIP_TMP125 5 /* TI TMP125 */ - - struct lm70 { - struct spi_device *spi; -@@ -87,6 +88,12 @@ static ssize_t temp1_input_show(struct d - * LM71: - * 14 bits of 2's complement data, discard LSB 2 bits, - * resolution 0.0312 degrees celsius. -+ * -+ * TMP125: -+ * MSB/D15 is a leading zero. D14 is the sign-bit. This is -+ * followed by 9 temperature bits (D13..D5) in 2's complement -+ * data format with a resolution of 0.25 degrees celsius per unit. -+ * LSB 5 bits (D4..D0) share the same value as D5 and get discarded. - */ - switch (p_lm70->chip) { - case LM70_CHIP_LM70: -@@ -102,6 +109,10 @@ static ssize_t temp1_input_show(struct d - case LM70_CHIP_LM71: - val = ((int)raw / 4) * 3125 / 100; - break; -+ -+ case LM70_CHIP_TMP125: -+ val = (sign_extend32(raw, 14) / 32) * 250; -+ break; - } - - status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */ -@@ -136,6 +147,10 @@ static const struct of_device_id lm70_of - .data = (void *) LM70_CHIP_TMP122, - }, - { -+ .compatible = "ti,tmp125", -+ .data = (void *) LM70_CHIP_TMP125, -+ }, -+ { - .compatible = "ti,lm71", - .data = (void *) LM70_CHIP_LM71, - }, -@@ -184,6 +199,7 @@ static const struct spi_device_id lm70_i - { "lm70", LM70_CHIP_LM70 }, - { "tmp121", LM70_CHIP_TMP121 }, - { "tmp122", LM70_CHIP_TMP122 }, -+ { "tmp125", LM70_CHIP_TMP125 }, - { "lm71", LM70_CHIP_LM71 }, - { "lm74", LM70_CHIP_LM74 }, - { }, diff --git a/target/linux/generic/backport-5.15/880-v5.19-cdc_ether-export-usbnet_cdc_zte_rx_fixup.patch b/target/linux/generic/backport-5.15/880-v5.19-cdc_ether-export-usbnet_cdc_zte_rx_fixup.patch deleted file mode 100644 index 39fdb3277334bf..00000000000000 --- a/target/linux/generic/backport-5.15/880-v5.19-cdc_ether-export-usbnet_cdc_zte_rx_fixup.patch +++ /dev/null @@ -1,58 +0,0 @@ -From a79a5613e1907e1bf09bb6ba6fd5ff43b66c1afe Mon Sep 17 00:00:00 2001 -From: Lech Perczak -Date: Fri, 1 Apr 2022 22:03:55 +0200 -Subject: [PATCH 1/3] cdc_ether: export usbnet_cdc_zte_rx_fixup -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit bfe9b9d2df66 ("cdc_ether: Improve ZTE MF823/831/910 handling") -introduces a workaround for certain ZTE modems reporting invalid MAC -addresses over CDC-ECM. -The same issue was present on their RNDIS interface,which was fixed in -commit a5a18bdf7453 ("rndis_host: Set valid random MAC on buggy devices"). - -However, internal modem of ZTE MF286R router, on its RNDIS interface, also -exhibits a second issue fixed already in CDC-ECM, of the device not -respecting configured random MAC address. In order to share the fixup for -this with rndis_host driver, export the workaround function, which will -be re-used in the following commit in rndis_host. - -Cc: Kristian Evensen -Cc: Bjørn Mork -Cc: Oliver Neukum -Signed-off-by: Lech Perczak ---- - drivers/net/usb/cdc_ether.c | 3 ++- - include/linux/usb/usbnet.h | 1 + - 2 files changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/usb/cdc_ether.c -+++ b/drivers/net/usb/cdc_ether.c -@@ -479,7 +479,7 @@ static int usbnet_cdc_zte_bind(struct us - * device MAC address has been updated). Always set MAC address to that of the - * device. - */ --static int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb) -+int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - { - if (skb->len < ETH_HLEN || !(skb->data[0] & 0x02)) - return 1; -@@ -489,6 +489,7 @@ static int usbnet_cdc_zte_rx_fixup(struc - - return 1; - } -+EXPORT_SYMBOL_GPL(usbnet_cdc_zte_rx_fixup); - - /* Ensure correct link state - * ---- a/include/linux/usb/usbnet.h -+++ b/include/linux/usb/usbnet.h -@@ -214,6 +214,7 @@ extern int usbnet_ether_cdc_bind(struct - extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *); - extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *); - extern void usbnet_cdc_status(struct usbnet *, struct urb *); -+extern int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb); - - /* CDC and RNDIS support the same host-chosen packet filters for IN transfers */ - #define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ diff --git a/target/linux/generic/backport-5.15/881-v5.19-rndis_host-enable-the-bogus-MAC-fixup-for-ZTE-device.patch b/target/linux/generic/backport-5.15/881-v5.19-rndis_host-enable-the-bogus-MAC-fixup-for-ZTE-device.patch deleted file mode 100644 index 71a6df81020ad5..00000000000000 --- a/target/linux/generic/backport-5.15/881-v5.19-rndis_host-enable-the-bogus-MAC-fixup-for-ZTE-device.patch +++ /dev/null @@ -1,118 +0,0 @@ -From aa8aff10e969aca0cb64f5e54ff7489355582667 Mon Sep 17 00:00:00 2001 -From: Lech Perczak -Date: Fri, 1 Apr 2022 22:04:01 +0200 -Subject: [PATCH 2/3] rndis_host: enable the bogus MAC fixup for ZTE devices - from cdc_ether -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Certain ZTE modems, namely: MF823. MF831, MF910, built-in modem from -MF286R, expose both CDC-ECM and RNDIS network interfaces. -They have a trait of ignoring the locally-administered MAC address -configured on the interface both in CDC-ECM and RNDIS part, -and this leads to dropping of incoming traffic by the host. -However, the workaround was only present in CDC-ECM, and MF286R -explicitly requires it in RNDIS mode. - -Re-use the workaround in rndis_host as well, to fix operation of MF286R -module, some versions of which expose only the RNDIS interface. Do so by -introducing new flag, RNDIS_DRIVER_DATA_DST_MAC_FIXUP, and testing for it -in rndis_rx_fixup. This is required, as RNDIS uses frame batching, and all -of the packets inside the batch need the fixup. This might introduce a -performance penalty, because test is done for every returned Ethernet -frame. - -Apply the workaround to both "flavors" of RNDIS interfaces, as older ZTE -modems, like MF823 found in the wild, report the USB_CLASS_COMM class -interfaces, while MF286R reports USB_CLASS_WIRELESS_CONTROLLER. - -Suggested-by: Bjørn Mork -Cc: Kristian Evensen -Cc: Oliver Neukum -Signed-off-by: Lech Perczak ---- - drivers/net/usb/rndis_host.c | 32 ++++++++++++++++++++++++++++++++ - include/linux/usb/rndis_host.h | 1 + - 2 files changed, 33 insertions(+) - ---- a/drivers/net/usb/rndis_host.c -+++ b/drivers/net/usb/rndis_host.c -@@ -486,10 +486,14 @@ EXPORT_SYMBOL_GPL(rndis_unbind); - */ - int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - { -+ bool dst_mac_fixup; -+ - /* This check is no longer done by usbnet */ - if (skb->len < dev->net->hard_header_len) - return 0; - -+ dst_mac_fixup = !!(dev->driver_info->data & RNDIS_DRIVER_DATA_DST_MAC_FIXUP); -+ - /* peripheral may have batched packets to us... */ - while (likely(skb->len)) { - struct rndis_data_hdr *hdr = (void *)skb->data; -@@ -524,10 +528,17 @@ int rndis_rx_fixup(struct usbnet *dev, s - break; - skb_pull(skb, msg_len - sizeof *hdr); - skb_trim(skb2, data_len); -+ -+ if (unlikely(dst_mac_fixup)) -+ usbnet_cdc_zte_rx_fixup(dev, skb2); -+ - usbnet_skb_return(dev, skb2); - } - - /* caller will usbnet_skb_return the remaining packet */ -+ if (unlikely(dst_mac_fixup)) -+ usbnet_cdc_zte_rx_fixup(dev, skb); -+ - return 1; - } - EXPORT_SYMBOL_GPL(rndis_rx_fixup); -@@ -601,6 +612,17 @@ static const struct driver_info rndis_po - .tx_fixup = rndis_tx_fixup, - }; - -+static const struct driver_info zte_rndis_info = { -+ .description = "ZTE RNDIS device", -+ .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT, -+ .data = RNDIS_DRIVER_DATA_DST_MAC_FIXUP, -+ .bind = rndis_bind, -+ .unbind = rndis_unbind, -+ .status = rndis_status, -+ .rx_fixup = rndis_rx_fixup, -+ .tx_fixup = rndis_tx_fixup, -+}; -+ - /*-------------------------------------------------------------------------*/ - - static const struct usb_device_id products [] = { -@@ -615,6 +637,16 @@ static const struct usb_device_id produc - USB_CLASS_COMM, 2 /* ACM */, 0x0ff), - .driver_info = (unsigned long)&rndis_info, - }, { -+ /* ZTE WWAN modules */ -+ USB_VENDOR_AND_INTERFACE_INFO(0x19d2, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long)&zte_rndis_info, -+}, { -+ /* ZTE WWAN modules, ACM flavour */ -+ USB_VENDOR_AND_INTERFACE_INFO(0x19d2, -+ USB_CLASS_COMM, 2 /* ACM */, 0x0ff), -+ .driver_info = (unsigned long)&zte_rndis_info, -+}, { - /* RNDIS is MSFT's un-official variant of CDC ACM */ - USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), - .driver_info = (unsigned long) &rndis_info, ---- a/include/linux/usb/rndis_host.h -+++ b/include/linux/usb/rndis_host.h -@@ -197,6 +197,7 @@ struct rndis_keepalive_c { /* IN (option - - /* Flags for driver_info::data */ - #define RNDIS_DRIVER_DATA_POLL_STATUS 1 /* poll status before control */ -+#define RNDIS_DRIVER_DATA_DST_MAC_FIXUP 2 /* device ignores configured MAC address */ - - extern void rndis_status(struct usbnet *dev, struct urb *urb); - extern int diff --git a/target/linux/generic/backport-5.15/882-v5.19-rndis_host-limit-scope-of-bogus-MAC-address-detectio.patch b/target/linux/generic/backport-5.15/882-v5.19-rndis_host-limit-scope-of-bogus-MAC-address-detectio.patch deleted file mode 100644 index bdd812cc906c13..00000000000000 --- a/target/linux/generic/backport-5.15/882-v5.19-rndis_host-limit-scope-of-bogus-MAC-address-detectio.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 9bfb4bcda7ba32d73ea322ea56a8ebe32e9247f6 Mon Sep 17 00:00:00 2001 -From: Lech Perczak -Date: Sat, 2 Apr 2022 02:19:57 +0200 -Subject: [PATCH 3/3] rndis_host: limit scope of bogus MAC address detection to - ZTE devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Reporting of bogus MAC addresses and ignoring configuration of new -destination address wasn't observed outside of a range of ZTE devices, -among which this seems to be the common bug. Align rndis_host driver -with implementation found in cdc_ether, which also limits this workaround -to ZTE devices. - -Suggested-by: Bjørn Mork -Cc: Kristian Evensen -Cc: Oliver Neukum -Signed-off-by: Lech Perczak ---- - drivers/net/usb/rndis_host.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) - ---- a/drivers/net/usb/rndis_host.c -+++ b/drivers/net/usb/rndis_host.c -@@ -419,10 +419,7 @@ generic_rndis_bind(struct usbnet *dev, s - goto halt_fail_and_release; - } - -- if (bp[0] & 0x02) -- eth_hw_addr_random(net); -- else -- ether_addr_copy(net->dev_addr, bp); -+ ether_addr_copy(net->dev_addr, bp); - - /* set a nonzero filter to enable data transfers */ - memset(u.set, 0, sizeof *u.set); -@@ -464,6 +461,16 @@ static int rndis_bind(struct usbnet *dev - return generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_NOT_WIRELESS); - } - -+static int zte_rndis_bind(struct usbnet *dev, struct usb_interface *intf) -+{ -+ int status = rndis_bind(dev, intf); -+ -+ if (!status && (dev->net->dev_addr[0] & 0x02)) -+ eth_hw_addr_random(dev->net); -+ -+ return status; -+} -+ - void rndis_unbind(struct usbnet *dev, struct usb_interface *intf) - { - struct rndis_halt *halt; -@@ -616,7 +623,7 @@ static const struct driver_info zte_rndi - .description = "ZTE RNDIS device", - .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT, - .data = RNDIS_DRIVER_DATA_DST_MAC_FIXUP, -- .bind = rndis_bind, -+ .bind = zte_rndis_bind, - .unbind = rndis_unbind, - .status = rndis_status, - .rx_fixup = rndis_rx_fixup, diff --git a/target/linux/generic/backport-5.15/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch b/target/linux/generic/backport-5.15/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch deleted file mode 100644 index 38fbc3a3d73f33..00000000000000 --- a/target/linux/generic/backport-5.15/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch +++ /dev/null @@ -1,40 +0,0 @@ -From dbf70fc204d2fbb0d8ad8f42038a60846502efda Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Mon, 10 Oct 2022 13:51:09 +0300 -Subject: [PATCH] mtd: spinand: winbond: fix flash identification - -Winbond uses 3 bytes to identify flash: vendor_id, dev_id_0, dev_id_1, -but current driver uses only first 2 bytes of it for devices -identification. As result Winbond W25N02KV flash (id_bytes: EF, AA, 22) -is identified as W25N01GV (id_bytes: EF, AA, 21). - -Fix this by adding missed identification bytes. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: Frieder Schrempf -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221010105110.446674-1-mikhail.kshevetskiy@iopsys.eu ---- - drivers/mtd/nand/spi/winbond.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/mtd/nand/spi/winbond.c -+++ b/drivers/mtd/nand/spi/winbond.c -@@ -76,7 +76,7 @@ static int w25m02gv_select_target(struct - - static const struct spinand_info winbond_spinand_table[] = { - SPINAND_INFO("W25M02GV", -- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab), -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21), - NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2), - NAND_ECCREQ(1, 512), - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -@@ -86,7 +86,7 @@ static const struct spinand_info winbond - SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), - SPINAND_SELECT_TARGET(w25m02gv_select_target)), - SPINAND_INFO("W25N01GV", -- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa), -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21), - NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), - NAND_ECCREQ(1, 512), - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, diff --git a/target/linux/generic/backport-5.15/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch b/target/linux/generic/backport-5.15/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch deleted file mode 100644 index d75a1acc57c765..00000000000000 --- a/target/linux/generic/backport-5.15/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 6154c7a583483d7b69f53bea868efdc369edd563 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Mon, 10 Oct 2022 13:51:10 +0300 -Subject: [PATCH] mtd: spinand: winbond: add Winbond W25N02KV flash support - -Add support of Winbond W25N02KV flash - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: Frieder Schrempf -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221010105110.446674-2-mikhail.kshevetskiy@iopsys.eu ---- - drivers/mtd/nand/spi/winbond.c | 75 ++++++++++++++++++++++++++++++++++ - 1 file changed, 75 insertions(+) - ---- a/drivers/mtd/nand/spi/winbond.c -+++ b/drivers/mtd/nand/spi/winbond.c -@@ -74,6 +74,72 @@ static int w25m02gv_select_target(struct - return spi_mem_exec_op(spinand->spimem, &op); - } - -+static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section > 3) -+ return -ERANGE; -+ -+ region->offset = 64 + (16 * section); -+ region->length = 13; -+ -+ return 0; -+} -+ -+static int w25n02kv_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section > 3) -+ return -ERANGE; -+ -+ region->offset = (16 * section) + 2; -+ region->length = 14; -+ -+ return 0; -+} -+ -+static const struct mtd_ooblayout_ops w25n02kv_ooblayout = { -+ .ecc = w25n02kv_ooblayout_ecc, -+ .free = w25n02kv_ooblayout_free, -+}; -+ -+static int w25n02kv_ecc_get_status(struct spinand_device *spinand, -+ u8 status) -+{ -+ struct nand_device *nand = spinand_to_nand(spinand); -+ u8 mbf = 0; -+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); -+ -+ switch (status & STATUS_ECC_MASK) { -+ case STATUS_ECC_NO_BITFLIPS: -+ return 0; -+ -+ case STATUS_ECC_UNCOR_ERROR: -+ return -EBADMSG; -+ -+ case STATUS_ECC_HAS_BITFLIPS: -+ /* -+ * Let's try to retrieve the real maximum number of bitflips -+ * in order to avoid forcing the wear-leveling layer to move -+ * data around if it's not necessary. -+ */ -+ if (spi_mem_exec_op(spinand->spimem, &op)) -+ return nanddev_get_ecc_conf(nand)->strength; -+ -+ mbf >>= 4; -+ -+ if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) -+ return nanddev_get_ecc_conf(nand)->strength; -+ -+ return mbf; -+ -+ default: -+ break; -+ } -+ -+ return -EINVAL; -+} -+ - static const struct spinand_info winbond_spinand_table[] = { - SPINAND_INFO("W25M02GV", - SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21), -@@ -94,6 +160,15 @@ static const struct spinand_info winbond - &update_cache_variants), - 0, - SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)), -+ SPINAND_INFO("W25N02KV", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22), -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ 0, -+ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), - }; - - static int winbond_spinand_init(struct spinand_device *spinand) diff --git a/target/linux/generic/backport-5.15/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch b/target/linux/generic/backport-5.15/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch deleted file mode 100644 index 2f408f5a30090d..00000000000000 --- a/target/linux/generic/backport-5.15/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch +++ /dev/null @@ -1,49 +0,0 @@ -From f5a05060670a4d8d6523afc7963eb559c2e3615f Mon Sep 17 00:00:00 2001 -From: Olivier Maignial -Date: Fri, 23 Jun 2023 17:33:37 +0200 -Subject: [PATCH] mtd: spinand: winbond: Fix ecc_get_status - -Reading ECC status is failing. - -w25n02kv_ecc_get_status() is using on-stack buffer for -SPINAND_GET_FEATURE_OP() output. It is not suitable for -DMA needs of spi-mem. - -Fix this by using the spi-mem operations dedicated buffer -spinand->scratchbuf. - -See -spinand->scratchbuf: -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/mtd/spinand.h?h=v6.3#n418 -spi_mem_check_op(): -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-mem.c?h=v6.3#n199 - -Fixes: 6154c7a58348 ("mtd: spinand: winbond: add Winbond W25N02KV flash support") -Cc: stable@vger.kernel.org -Signed-off-by: Olivier Maignial -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/DB4P250MB1032EDB9E36B764A33769039FE23A@DB4P250MB1032.EURP250.PROD.OUTLOOK.COM ---- - drivers/mtd/nand/spi/winbond.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/mtd/nand/spi/winbond.c -+++ b/drivers/mtd/nand/spi/winbond.c -@@ -108,7 +108,7 @@ static int w25n02kv_ecc_get_status(struc - { - struct nand_device *nand = spinand_to_nand(spinand); - u8 mbf = 0; -- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); -+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf); - - switch (status & STATUS_ECC_MASK) { - case STATUS_ECC_NO_BITFLIPS: -@@ -126,7 +126,7 @@ static int w25n02kv_ecc_get_status(struc - if (spi_mem_exec_op(spinand->spimem, &op)) - return nanddev_get_ecc_conf(nand)->strength; - -- mbf >>= 4; -+ mbf = *(spinand->scratchbuf) >> 4; - - if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) - return nanddev_get_ecc_conf(nand)->strength; diff --git a/target/linux/generic/backport-5.15/893-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch b/target/linux/generic/backport-5.15/893-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch deleted file mode 100644 index 177a8ce43e2763..00000000000000 --- a/target/linux/generic/backport-5.15/893-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 19f291d8a65cd19e7595006c7872cd95aa6f9e93 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Fri, 4 Aug 2023 19:13:10 +0200 -Subject: [PATCH 893/898] net: dsa: mv88e6xxx: pass directly chip structure to - mv88e6xxx_phy_is_internal -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since this function is a simple helper, we do not need to pass a full -dsa_switch structure, we can directly pass the mv88e6xxx_chip structure. -Doing so will allow to share this function with any other function -not manipulating dsa_switch structure but needing info about number of -internal phys - -Signed-off-by: Alexis Lothoré -Reviewed-by: Russell King (Oracle) -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mv88e6xxx/chip.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -459,10 +459,8 @@ restore_link: - return err; - } - --static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port) -+static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port) - { -- struct mv88e6xxx_chip *chip = ds->priv; -- - return port < chip->info->num_internal_phys; - } - -@@ -704,7 +702,7 @@ static void mv88e6xxx_mac_config(struct - - mv88e6xxx_reg_lock(chip); - -- if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) { -+ if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(chip, port)) { - /* In inband mode, the link may come up at any time while the - * link is not forced down. Force the link down while we - * reconfigure the interface mode. diff --git a/target/linux/generic/backport-5.15/893-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch b/target/linux/generic/backport-5.15/893-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch deleted file mode 100644 index 02cafa3765332e..00000000000000 --- a/target/linux/generic/backport-5.15/893-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 03a50b4f81d9e8bcf86165d6b2ac9376d02e5df9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:42 +0200 -Subject: [PATCH 894/898] net: dsa: mv88e6xxx: use mv88e6xxx_phy_is_internal in - mv88e6xxx_port_ppu_updates -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make sure to use existing helper to get internal PHYs count instead of -redoing it manually - -Signed-off-by: Alexis Lothoré -Reviewed-by: Russell King (Oracle) -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mv88e6xxx/chip.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -473,7 +473,7 @@ static int mv88e6xxx_port_ppu_updates(st - * report whether the port is internal. - */ - if (chip->info->family == MV88E6XXX_FAMILY_6250) -- return port < chip->info->num_internal_phys; -+ return mv88e6xxx_phy_is_internal(chip, port); - - err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); - if (err) { diff --git a/target/linux/generic/backport-5.15/893-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch b/target/linux/generic/backport-5.15/893-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch deleted file mode 100644 index 239620b686ab2d..00000000000000 --- a/target/linux/generic/backport-5.15/893-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 07120894b24cc3cf2318925baeaaf0893e3312e4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:43 +0200 -Subject: [PATCH 895/898] net: dsa: mv88e6xxx: add field to specify internal - phys layout -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mv88e6xxx currently assumes that switch equipped with internal phys have -those phys mapped contiguously starting from port 0 (see -mv88e6xxx_phy_is_internal). However, some switches have internal PHYs but -NOT starting from port 0. For example 88e6393X, 88E6193X and 88E6191X have -integrated PHYs available on ports 1 to 8 -To properly support this offset, add a new field to allow specifying an -internal PHYs layout. If field is not set, default layout is assumed (start -at port 0) - -Signed-off-by: Alexis Lothoré -Reviewed-by: Andrew Lunn -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mv88e6xxx/chip.c | 4 +++- - drivers/net/dsa/mv88e6xxx/chip.h | 5 +++++ - drivers/net/dsa/mv88e6xxx/global2.c | 5 ++++- - 3 files changed, 12 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -461,7 +461,9 @@ restore_link: - - static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port) - { -- return port < chip->info->num_internal_phys; -+ return port >= chip->info->internal_phys_offset && -+ port < chip->info->num_internal_phys + -+ chip->info->internal_phys_offset; - } - - static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port) ---- a/drivers/net/dsa/mv88e6xxx/chip.h -+++ b/drivers/net/dsa/mv88e6xxx/chip.h -@@ -165,6 +165,11 @@ struct mv88e6xxx_info { - - /* Supports PTP */ - bool ptp_support; -+ -+ /* Internal PHY start index. 0 means that internal PHYs range starts at -+ * port 0, 1 means internal PHYs range starts at port 1, etc -+ */ -+ unsigned int internal_phys_offset; - }; - - struct mv88e6xxx_atu_entry { ---- a/drivers/net/dsa/mv88e6xxx/global2.c -+++ b/drivers/net/dsa/mv88e6xxx/global2.c -@@ -1185,8 +1185,11 @@ int mv88e6xxx_g2_irq_mdio_setup(struct m - struct mii_bus *bus) - { - int phy, irq, err, err_phy; -+ int phy_start = chip->info->internal_phys_offset; -+ int phy_end = chip->info->internal_phys_offset + -+ chip->info->num_internal_phys; - -- for (phy = 0; phy < chip->info->num_internal_phys; phy++) { -+ for (phy = phy_start; phy < phy_end; phy++) { - irq = irq_find_mapping(chip->g2_irq.domain, phy); - if (irq < 0) { - err = irq; diff --git a/target/linux/generic/backport-5.15/893-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch b/target/linux/generic/backport-5.15/893-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch deleted file mode 100644 index d0a2a98d3ce2d4..00000000000000 --- a/target/linux/generic/backport-5.15/893-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 492b06747f544c19b5ffe531a24b67858764c50e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:44 +0200 -Subject: [PATCH 896/898] net: dsa: mv88e6xxx: fix 88E6393X family internal - phys layout -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -88E6393X/88E6193X/88E6191X switches have in fact 8 internal PHYs, but those -are not present starting at port 0: supported ports go from 1 to 8 - -Signed-off-by: Alexis Lothoré -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mv88e6xxx/chip.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -5414,7 +5414,8 @@ static const struct mv88e6xxx_info mv88e - .name = "Marvell 88E6191X", - .num_databases = 4096, - .num_ports = 11, /* 10 + Z80 */ -- .num_internal_phys = 9, -+ .num_internal_phys = 8, -+ .internal_phys_offset = 1, - .max_vid = 8191, - .port_base_addr = 0x0, - .phy_base_addr = 0x0, -@@ -5436,7 +5437,8 @@ static const struct mv88e6xxx_info mv88e - .name = "Marvell 88E6193X", - .num_databases = 4096, - .num_ports = 11, /* 10 + Z80 */ -- .num_internal_phys = 9, -+ .num_internal_phys = 8, -+ .internal_phys_offset = 1, - .max_vid = 8191, - .port_base_addr = 0x0, - .phy_base_addr = 0x0, -@@ -5746,7 +5748,8 @@ static const struct mv88e6xxx_info mv88e - .name = "Marvell 88E6393X", - .num_databases = 4096, - .num_ports = 11, /* 10 + Z80 */ -- .num_internal_phys = 9, -+ .num_internal_phys = 8, -+ .internal_phys_offset = 1, - .max_vid = 8191, - .port_base_addr = 0x0, - .phy_base_addr = 0x0, diff --git a/target/linux/generic/backport-5.15/893-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch b/target/linux/generic/backport-5.15/893-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch deleted file mode 100644 index 9122960712105d..00000000000000 --- a/target/linux/generic/backport-5.15/893-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 68690045f8e220826517c0d6f9388ffc1faa57ea Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:45 +0200 -Subject: [PATCH 897/898] net: dsa: mv88e6xxx: pass mv88e6xxx_chip structure to - port_max_speed_mode -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some switches families have minor differences on supported link speed for -ports. Instead of redefining a new port_max_speed_mode for each different -configuration, allow to pass mv88e6xxx_chip structure to allow -differentiating those chips by known chip id - -Signed-off-by: Alexis Lothoré -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski -Update one more instance of port_max_speed_mode that 5.15 has. -[Robert Marko] -Signed-off-by: Robert Marko ---- - drivers/net/dsa/mv88e6xxx/chip.c | 2 +- - drivers/net/dsa/mv88e6xxx/chip.h | 3 ++- - drivers/net/dsa/mv88e6xxx/port.c | 12 ++++++++---- - drivers/net/dsa/mv88e6xxx/port.h | 12 ++++++++---- - 4 files changed, 19 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -443,7 +443,7 @@ static int mv88e6xxx_port_setup_mac(stru - } - - if (speed == SPEED_MAX && chip->info->ops->port_max_speed_mode) -- mode = chip->info->ops->port_max_speed_mode(port); -+ mode = chip->info->ops->port_max_speed_mode(chip, port); - - if (chip->info->ops->port_set_pause) { - err = chip->info->ops->port_set_pause(chip, port, pause); ---- a/drivers/net/dsa/mv88e6xxx/chip.h -+++ b/drivers/net/dsa/mv88e6xxx/chip.h -@@ -491,7 +491,8 @@ struct mv88e6xxx_ops { - int speed, int duplex); - - /* What interface mode should be used for maximum speed? */ -- phy_interface_t (*port_max_speed_mode)(int port); -+ phy_interface_t (*port_max_speed_mode)(struct mv88e6xxx_chip *chip, -+ int port); - - int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port); - ---- a/drivers/net/dsa/mv88e6xxx/port.c -+++ b/drivers/net/dsa/mv88e6xxx/port.c -@@ -357,7 +357,8 @@ int mv88e6341_port_set_speed_duplex(stru - duplex); - } - --phy_interface_t mv88e6341_port_max_speed_mode(int port) -+phy_interface_t mv88e6341_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port) - { - if (port == 5) - return PHY_INTERFACE_MODE_2500BASEX; -@@ -402,7 +403,8 @@ int mv88e6390_port_set_speed_duplex(stru - duplex); - } - --phy_interface_t mv88e6390_port_max_speed_mode(int port) -+phy_interface_t mv88e6390_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port) - { - if (port == 9 || port == 10) - return PHY_INTERFACE_MODE_2500BASEX; -@@ -427,7 +429,8 @@ int mv88e6390x_port_set_speed_duplex(str - duplex); - } - --phy_interface_t mv88e6390x_port_max_speed_mode(int port) -+phy_interface_t mv88e6390x_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port) - { - if (port == 9 || port == 10) - return PHY_INTERFACE_MODE_XAUI; -@@ -527,7 +530,8 @@ int mv88e6393x_port_set_speed_duplex(str - return 0; - } - --phy_interface_t mv88e6393x_port_max_speed_mode(int port) -+phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port) - { - if (port == 0 || port == 9 || port == 10) - return PHY_INTERFACE_MODE_10GBASER; ---- a/drivers/net/dsa/mv88e6xxx/port.h -+++ b/drivers/net/dsa/mv88e6xxx/port.h -@@ -350,10 +350,14 @@ int mv88e6390x_port_set_speed_duplex(str - int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port, - int speed, int duplex); - --phy_interface_t mv88e6341_port_max_speed_mode(int port); --phy_interface_t mv88e6390_port_max_speed_mode(int port); --phy_interface_t mv88e6390x_port_max_speed_mode(int port); --phy_interface_t mv88e6393x_port_max_speed_mode(int port); -+phy_interface_t mv88e6341_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port); -+phy_interface_t mv88e6390_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port); -+phy_interface_t mv88e6390x_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port); -+phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port); - - int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state); - diff --git a/target/linux/generic/backport-5.15/893-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch b/target/linux/generic/backport-5.15/893-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch deleted file mode 100644 index acb8d26c45f239..00000000000000 --- a/target/linux/generic/backport-5.15/893-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch +++ /dev/null @@ -1,165 +0,0 @@ -From f318a015330a11befd8c69336efc6284e240f535 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:46 +0200 -Subject: [PATCH 898/898] net: dsa: mv88e6xxx: enable support for 88E6361 - switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Marvell 88E6361 is an 8-port switch derived from the -88E6393X/88E9193X/88E6191X switches family. It can benefit from the -existing mv88e6xxx driver by simply adding the proper switch description in -the driver. Main differences with other switches from this -family are: -- 8 ports exposed (instead of 11): ports 1, 2 and 8 not available -- No 5GBase-x nor SFI/USXGMII support - -Signed-off-by: Alexis Lothoré -Reviewed-by: Andrew Lunn -Signed-off-by: Jakub Kicinski -Adapt to 5.15 since we dont have phylink_get_caps yet. -So, update the old mv88e6393x_phylink_validate instead. -Remove max_sid since 5.15 driver does not support it yet. -[Robert Marko] -Signed-off-by: Robert Marko ---- - drivers/net/dsa/mv88e6xxx/chip.c | 49 +++++++++++++++++++++++++++++++- - drivers/net/dsa/mv88e6xxx/chip.h | 3 +- - drivers/net/dsa/mv88e6xxx/port.c | 14 +++++++-- - drivers/net/dsa/mv88e6xxx/port.h | 1 + - 4 files changed, 62 insertions(+), 5 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -648,6 +648,8 @@ static void mv88e6393x_phylink_validate( - { - bool is_6191x = - chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X; -+ bool is_6361 = -+ chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361; - - if (((port == 0 || port == 9) && !is_6191x) || port == 10) { - phylink_set(mask, 10000baseT_Full); -@@ -662,8 +664,28 @@ static void mv88e6393x_phylink_validate( - phylink_set(mask, 2500baseT_Full); - } - -+ if (port == 0 || port == 9 || port == 10) { -+ phylink_set(mask, 1000baseX_Full); -+ -+ /* 6191X supports >1G modes only on port 10 */ -+ if (!is_6191x || port == 10) { -+ phylink_set(mask, 2500baseX_Full); -+ phylink_set(mask, 2500baseT_Full); -+ -+ if (!is_6361) { -+ phylink_set(mask, 10000baseT_Full); -+ phylink_set(mask, 10000baseKR_Full); -+ phylink_set(mask, 10000baseCR_Full); -+ phylink_set(mask, 10000baseSR_Full); -+ phylink_set(mask, 10000baseLR_Full); -+ phylink_set(mask, 10000baseLRM_Full); -+ phylink_set(mask, 10000baseER_Full); -+ phylink_set(mask, 5000baseT_Full); -+ } -+ } -+ } -+ - phylink_set(mask, 1000baseT_Full); -- phylink_set(mask, 1000baseX_Full); - - mv88e6065_phylink_validate(chip, port, mask, state); - } -@@ -5693,6 +5715,31 @@ static const struct mv88e6xxx_info mv88e - .ptp_support = true, - .ops = &mv88e6352_ops, - }, -+ [MV88E6361] = { -+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361, -+ .family = MV88E6XXX_FAMILY_6393, -+ .name = "Marvell 88E6361", -+ .num_databases = 4096, -+ .num_macs = 16384, -+ .num_ports = 11, -+ /* Ports 1, 2 and 8 are not routed */ -+ .invalid_port_mask = BIT(1) | BIT(2) | BIT(8), -+ .num_internal_phys = 5, -+ .internal_phys_offset = 3, -+ .max_vid = 4095, -+ .port_base_addr = 0x0, -+ .phy_base_addr = 0x0, -+ .global1_addr = 0x1b, -+ .global2_addr = 0x1c, -+ .age_time_coeff = 3750, -+ .g1_irqs = 10, -+ .g2_irqs = 14, -+ .atu_move_port_mask = 0x1f, -+ .pvt = true, -+ .multi_chip = true, -+ .ptp_support = true, -+ .ops = &mv88e6393x_ops, -+ }, - [MV88E6390] = { - .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390, - .family = MV88E6XXX_FAMILY_6390, ---- a/drivers/net/dsa/mv88e6xxx/chip.h -+++ b/drivers/net/dsa/mv88e6xxx/chip.h -@@ -81,6 +81,7 @@ enum mv88e6xxx_model { - MV88E6350, - MV88E6351, - MV88E6352, -+ MV88E6361, - MV88E6390, - MV88E6390X, - MV88E6393X, -@@ -99,7 +100,7 @@ enum mv88e6xxx_family { - MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */ - MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */ - MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */ -- MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6393X */ -+ MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6361 6393X */ - }; - - /** ---- a/drivers/net/dsa/mv88e6xxx/port.c -+++ b/drivers/net/dsa/mv88e6xxx/port.c -@@ -451,6 +451,10 @@ int mv88e6393x_port_set_speed_duplex(str - if (speed == SPEED_MAX) - speed = (port > 0 && port < 9) ? 1000 : 10000; - -+ if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361 && -+ speed > 2500) -+ return -EOPNOTSUPP; -+ - if (speed == 200 && port != 0) - return -EOPNOTSUPP; - -@@ -533,10 +537,14 @@ int mv88e6393x_port_set_speed_duplex(str - phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip, - int port) - { -- if (port == 0 || port == 9 || port == 10) -- return PHY_INTERFACE_MODE_10GBASER; - -- return PHY_INTERFACE_MODE_NA; -+ if (port != 0 && port != 9 && port != 10) -+ return PHY_INTERFACE_MODE_NA; -+ -+ if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361) -+ return PHY_INTERFACE_MODE_2500BASEX; -+ -+ return PHY_INTERFACE_MODE_10GBASER; - } - - static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, ---- a/drivers/net/dsa/mv88e6xxx/port.h -+++ b/drivers/net/dsa/mv88e6xxx/port.h -@@ -128,6 +128,7 @@ - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6220 0x2200 - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6240 0x2400 - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6250 0x2500 -+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6361 0x2610 - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6290 0x2900 - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6321 0x3100 - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6141 0x3400 diff --git a/target/linux/generic/backport-5.15/894-v6.8-net-ethtool-implement-ethtool_puts.patch b/target/linux/generic/backport-5.15/894-v6.8-net-ethtool-implement-ethtool_puts.patch deleted file mode 100644 index 283e226d16d37e..00000000000000 --- a/target/linux/generic/backport-5.15/894-v6.8-net-ethtool-implement-ethtool_puts.patch +++ /dev/null @@ -1,139 +0,0 @@ -From mboxrd@z Thu Jan 1 00:00:00 1970 -Authentication-Results: smtp.subspace.kernel.org; - dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="sMUeie/T" -Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84BB8D6D - for ; Wed, 6 Dec 2023 15:16:16 -0800 (PST) -Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-db5416d0fccso403298276.1 - for ; Wed, 06 Dec 2023 15:16:16 -0800 (PST) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=google.com; s=20230601; t=1701904575; x=1702509375; darn=vger.kernel.org; - h=cc:to:from:subject:message-id:references:mime-version:in-reply-to - :date:from:to:cc:subject:date:message-id:reply-to; - bh=/7eYcPC4ZNNyPcPPs0B5tDplF0arxw3r0vINNNou0rY=; - b=sMUeie/TxdytzC0EyT11QWi1TqTtiv7KCTs1F2vLmUUvPKNA3+1MHFo8ECW+0gQuDE - FGrgdZKGK5mXQgkF0N3JiSLvKO8tpQOIB57JLCG5IVy5dr2vVv0ExU3Dag2Cc4oBIBIO - w/cH95O1oPlvluIpATmAsxenVr7mFomU63BqYiRGLaEhWeb2hJ636GO8lubtsDfdFFoi - GPOL2tQwV93VnqmywBBpFaNAULN0UoCFhfkKv5prvpkXq19sWI7zyorVZ+rdTYem5m4T - dXsDaLXPtC3Dh2JOad1duSQIah/wCHYYUcV3IoFhwj2y0Uk/TTCrnZPORweSADcEy6Ho - vDrA== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1701904575; x=1702509375; - h=cc:to:from:subject:message-id:references:mime-version:in-reply-to - :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; - bh=/7eYcPC4ZNNyPcPPs0B5tDplF0arxw3r0vINNNou0rY=; - b=Dmc6aSntxPlxAk72zVO1G9WoZnFtLolxENlLscYYAHG3VE+PQ8gGN2rPzcGoKb2Btb - 4b0PvjOzSlPQyghahdhdlz04RtAeeGG/MkfNiYjFql5OifIoovb51kroiPYrVsa7Ps7Y - +Pxug0+NPdTm5s9TNz940ZKl3GRME8UTmVxpWJRX03XMOqb6Wgsh2SK9ahXKc4yRsi62 - 3a3J72WmmSgvimxwM/99fXwvoUQpiv2J1xCoqc1Ng4q4qSuZvzmHN7ZTGaUhLxOqLeLK - 3W4RKHW6rZ7UjppuB6I3NXW+D344By2rdKp1sRXpjdQ0GS3YUcvlRETcJBXJudHfQP5Y - CLOw== -X-Gm-Message-State: AOJu0YzdCTLdwny+N99zeMgyKqFsEZhfIhL2cbgKA6zC1U/OLkxxRLoM - XrYVBC9DmxCGmP4o+M/Z/kHUew/9faHlCiLGxw== -X-Google-Smtp-Source: AGHT+IFRXxBV6JuX5Cl/k2o1+WKkCwkR8j20MJSkmoGCedPAtqFttH8OVh1/6vdfnq8MPN++A2h89peZQhyG8OsJ8A== -X-Received: from jstitt-linux1.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:23b5]) - (user=justinstitt job=sendgmr) by 2002:a25:dac7:0:b0:da0:3117:f35 with SMTP - id n190-20020a25dac7000000b00da031170f35mr28652ybf.3.1701904575576; Wed, 06 - Dec 2023 15:16:15 -0800 (PST) -Date: Wed, 06 Dec 2023 23:16:10 +0000 -In-Reply-To: <20231206-ethtool_puts_impl-v5-0-5a2528e17bf8@google.com> -Precedence: bulk -X-Mailing-List: bpf@vger.kernel.org -List-Id: -List-Subscribe: -List-Unsubscribe: -Mime-Version: 1.0 -References: <20231206-ethtool_puts_impl-v5-0-5a2528e17bf8@google.com> -X-Developer-Key: i=justinstitt@google.com; a=ed25519; pk=tC3hNkJQTpNX/gLKxTNQKDmiQl6QjBNCGKJINqAdJsE= -X-Developer-Signature: v=1; a=ed25519-sha256; t=1701904573; l=1840; - i=justinstitt@google.com; s=20230717; h=from:subject:message-id; - bh=UMdetIL2ZsPIkSodqhw2fM21NHJVjCu0lRImFuNhVoM=; b=a8rMnXfVVQ5gsxHWG4WRMwOLxZgflqXZtNuKx26vv4DwYvvCtCiYjl3f1frOjV/Ul2kaxq5g/ - b/UOv678JKCDASVokxG5GJifAnU7/kqRxdhcwfRkrD8RUfcsmiZOfyF -X-Mailer: b4 0.12.3 -Message-ID: <20231206-ethtool_puts_impl-v5-1-5a2528e17bf8@google.com> -Subject: [PATCH net-next v5 1/3] ethtool: Implement ethtool_puts() -From: justinstitt@google.com -To: "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , Shay Agroskin , - Arthur Kiyanovski , David Arinzon , Noam Dagan , - Saeed Bishara , Rasesh Mody , - Sudarsana Kalluru , GR-Linux-NIC-Dev@marvell.com, - Dimitris Michailidis , Yisen Zhuang , - Salil Mehta , Jesse Brandeburg , - Tony Nguyen , Louis Peens , - Shannon Nelson , Brett Creeley , drivers@pensando.io, - "K. Y. Srinivasan" , Haiyang Zhang , Wei Liu , - Dexuan Cui , Ronak Doshi , - VMware PV-Drivers Reviewers , Andy Whitcroft , Joe Perches , - Dwaipayan Ray , Lukas Bulwahn , - Hauke Mehrtens , Andrew Lunn , - Florian Fainelli , Vladimir Oltean , - "=?utf-8?q?Ar=C4=B1n=C3=A7_=C3=9CNAL?=" , Daniel Golle , - Landen Chao , DENG Qingfang , - Sean Wang , Matthias Brugger , - AngeloGioacchino Del Regno , - Linus Walleij , - "=?utf-8?q?Alvin_=C5=A0ipraga?=" , Wei Fang , - Shenwei Wang , Clark Wang , - NXP Linux Team , Lars Povlsen , - Steen Hegelund , Daniel Machon , - UNGLinuxDriver@microchip.com, Jiawen Wu , - Mengyuan Lou , Heiner Kallweit , - Russell King , Alexei Starovoitov , - Daniel Borkmann , Jesper Dangaard Brouer , - John Fastabend -Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, - Nick Desaulniers , Nathan Chancellor , - Kees Cook , intel-wired-lan@lists.osuosl.org, - oss-drivers@corigine.com, linux-hyperv@vger.kernel.org, - linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, - bpf@vger.kernel.org, Justin Stitt -Content-Type: text/plain; charset="utf-8" - -Use strscpy() to implement ethtool_puts(). - -Functionally the same as ethtool_sprintf() when it's used with two -arguments or with just "%s" format specifier. - -Signed-off-by: Justin Stitt ---- - include/linux/ethtool.h | 13 +++++++++++++ - net/ethtool/ioctl.c | 7 +++++++ - 2 files changed, 20 insertions(+) - ---- a/include/linux/ethtool.h -+++ b/include/linux/ethtool.h -@@ -788,4 +788,17 @@ int ethtool_get_phc_vclocks(struct net_d - * next string. - */ - extern __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...); -+ -+/** -+ * ethtool_puts - Write string to ethtool string data -+ * @data: Pointer to a pointer to the start of string to update -+ * @str: String to write -+ * -+ * Write string to *data without a trailing newline. Update *data -+ * to point at start of next string. -+ * -+ * Prefer this function to ethtool_sprintf() when given only -+ * two arguments or if @fmt is just "%s". -+ */ -+extern void ethtool_puts(u8 **data, const char *str); - #endif /* _LINUX_ETHTOOL_H */ ---- a/net/ethtool/ioctl.c -+++ b/net/ethtool/ioctl.c -@@ -1954,6 +1954,13 @@ __printf(2, 3) void ethtool_sprintf(u8 * - } - EXPORT_SYMBOL(ethtool_sprintf); - -+void ethtool_puts(u8 **data, const char *str) -+{ -+ strscpy(*data, str, ETH_GSTRING_LEN); -+ *data += ETH_GSTRING_LEN; -+} -+EXPORT_SYMBOL(ethtool_puts); -+ - static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) - { - struct ethtool_value id; diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 deleted file mode 100644 index 4c5b8087993968..00000000000000 --- a/target/linux/generic/config-5.15 +++ /dev/null @@ -1,7622 +0,0 @@ -# CONFIG_104_QUAD_8 is not set -CONFIG_32BIT=y -CONFIG_64BIT_TIME=y -# CONFIG_6LOWPAN is not set -# CONFIG_6LOWPAN_DEBUGFS is not set -# CONFIG_6PACK is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_9P_FS is not set -# CONFIG_AB3100_CORE is not set -# CONFIG_AB8500_CORE is not set -# CONFIG_ABP060MG is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_ACENIC is not set -# CONFIG_ACERHDF is not set -# CONFIG_ACER_WIRELESS is not set -# CONFIG_ACORN_PARTITION is not set -# CONFIG_ACPI_ALS is not set -# CONFIG_ACPI_APEI is not set -# CONFIG_ACPI_APEI_PCIEAER is not set -# CONFIG_ACPI_BUTTON is not set -# CONFIG_ACPI_CONFIGFS is not set -# CONFIG_ACPI_CUSTOM_METHOD is not set -# CONFIG_ACPI_EXTLOG is not set -# CONFIG_ACPI_HED is not set -# CONFIG_ACPI_NFIT is not set -# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set -# CONFIG_ACPI_TABLE_UPGRADE is not set -# CONFIG_ACPI_VIDEO is not set -# CONFIG_AD2S1200 is not set -# CONFIG_AD2S1210 is not set -# CONFIG_AD2S90 is not set -# CONFIG_AD5064 is not set -# CONFIG_AD5110 is not set -# CONFIG_AD525X_DPOT is not set -# CONFIG_AD5272 is not set -# CONFIG_AD5360 is not set -# CONFIG_AD5380 is not set -# CONFIG_AD5421 is not set -# CONFIG_AD5446 is not set -# CONFIG_AD5449 is not set -# CONFIG_AD5504 is not set -# CONFIG_AD5592R is not set -# CONFIG_AD5593R is not set -# CONFIG_AD5624R_SPI is not set -# CONFIG_AD5686 is not set -# CONFIG_AD5686_SPI is not set -# CONFIG_AD5696_I2C is not set -# CONFIG_AD5755 is not set -# CONFIG_AD5758 is not set -# CONFIG_AD5761 is not set -# CONFIG_AD5764 is not set -# CONFIG_AD5766 is not set -# CONFIG_AD5770R is not set -# CONFIG_AD5791 is not set -# CONFIG_AD5933 is not set -# CONFIG_AD7091R5 is not set -# CONFIG_AD7124 is not set -# CONFIG_AD7150 is not set -# CONFIG_AD7152 is not set -# CONFIG_AD7192 is not set -# CONFIG_AD7266 is not set -# CONFIG_AD7280 is not set -# CONFIG_AD7291 is not set -# CONFIG_AD7292 is not set -# CONFIG_AD7298 is not set -# CONFIG_AD7303 is not set -# CONFIG_AD7476 is not set -# CONFIG_AD7606 is not set -# CONFIG_AD7606_IFACE_PARALLEL is not set -# CONFIG_AD7606_IFACE_SPI is not set -# CONFIG_AD7746 is not set -# CONFIG_AD7766 is not set -# CONFIG_AD7768_1 is not set -# CONFIG_AD7780 is not set -# CONFIG_AD7791 is not set -# CONFIG_AD7793 is not set -# CONFIG_AD7816 is not set -# CONFIG_AD7887 is not set -# CONFIG_AD7923 is not set -# CONFIG_AD7949 is not set -# CONFIG_AD799X is not set -# CONFIG_AD8366 is not set -# CONFIG_AD8801 is not set -# CONFIG_AD9467 is not set -# CONFIG_AD9523 is not set -# CONFIG_AD9832 is not set -# CONFIG_AD9834 is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_ADE7854 is not set -# CONFIG_ADF4350 is not set -# CONFIG_ADF4371 is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADIN_PHY is not set -# CONFIG_ADIS16080 is not set -# CONFIG_ADIS16130 is not set -# CONFIG_ADIS16136 is not set -# CONFIG_ADIS16201 is not set -# CONFIG_ADIS16203 is not set -# CONFIG_ADIS16209 is not set -# CONFIG_ADIS16240 is not set -# CONFIG_ADIS16260 is not set -# CONFIG_ADIS16400 is not set -# CONFIG_ADIS16460 is not set -# CONFIG_ADIS16475 is not set -# CONFIG_ADIS16480 is not set -# CONFIG_ADI_AXI_ADC is not set -# CONFIG_ADJD_S311 is not set -# CONFIG_ADM6996_PHY is not set -# CONFIG_ADM8211 is not set -# CONFIG_ADT7316 is not set -# CONFIG_ADUX1020 is not set -CONFIG_ADVISE_SYSCALLS=y -# CONFIG_ADXL345_I2C is not set -# CONFIG_ADXL345_SPI is not set -# CONFIG_ADXL372_I2C is not set -# CONFIG_ADXL372_SPI is not set -# CONFIG_ADXRS290 is not set -# CONFIG_ADXRS450 is not set -CONFIG_AEABI=y -# CONFIG_AFE4403 is not set -# CONFIG_AFE4404 is not set -# CONFIG_AFFS_FS is not set -# CONFIG_AFS_DEBUG_CURSOR is not set -# CONFIG_AFS_FS is not set -# CONFIG_AF_KCM is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_AF_RXRPC_INJECT_LOSS is not set -# CONFIG_AF_RXRPC_IPV6 is not set -CONFIG_AF_UNIX_OOB=y -# CONFIG_AGP is not set -# CONFIG_AHCI_BRCM is not set -# CONFIG_AHCI_CEVA is not set -# CONFIG_AHCI_IMX is not set -# CONFIG_AHCI_MVEBU is not set -# CONFIG_AHCI_QORIQ is not set -# CONFIG_AHCI_XGENE is not set -CONFIG_AIO=y -# CONFIG_AIRO is not set -# CONFIG_AIRO_CS is not set -# CONFIG_AIX_PARTITION is not set -# CONFIG_AK09911 is not set -# CONFIG_AK8974 is not set -# CONFIG_AK8975 is not set -# CONFIG_AL3010 is not set -# CONFIG_AL3320A is not set -# CONFIG_ALIM7101_WDT is not set -CONFIG_ALLOW_DEV_COREDUMP=y -# CONFIG_ALTERA_MBOX is not set -# CONFIG_ALTERA_MSGDMA is not set -# CONFIG_ALTERA_STAPL is not set -# CONFIG_ALTERA_TSE is not set -# CONFIG_ALX is not set -# CONFIG_AL_FIC is not set -# CONFIG_AM2315 is not set -# CONFIG_AM335X_PHY_USB is not set -# CONFIG_AMBA_PL08X is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_AMD_MEM_ENCRYPT is not set -# CONFIG_AMD_PHY is not set -# CONFIG_AMD_XGBE is not set -# CONFIG_AMD_XGBE_HAVE_ECC is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_AMILO_RFKILL is not set -# CONFIG_ANDROID is not set -CONFIG_ANON_INODES=y -# CONFIG_APDS9300 is not set -# CONFIG_APDS9802ALS is not set -# CONFIG_APDS9960 is not set -# CONFIG_APM8018X is not set -# CONFIG_APM_EMULATION is not set -# CONFIG_APPLE_GMUX is not set -# CONFIG_APPLE_MFI_FASTCHARGE is not set -# CONFIG_APPLE_PROPERTIES is not set -# CONFIG_APPLICOM is not set -# CONFIG_AQTION is not set -# CONFIG_AQUANTIA_PHY is not set -# CONFIG_AR5523 is not set -# CONFIG_AR7 is not set -# CONFIG_AR8216_PHY is not set -# CONFIG_AR8216_PHY_LEDS is not set -# CONFIG_ARCH_ACTIONS is not set -# CONFIG_ARCH_AGILEX is not set -# CONFIG_ARCH_ALPINE is not set -# CONFIG_ARCH_APPLE is not set -# CONFIG_ARCH_ARTPEC is not set -# CONFIG_ARCH_ASPEED is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_AXXIA is not set -# CONFIG_ARCH_BCM is not set -# CONFIG_ARCH_BCM2835 is not set -# CONFIG_ARCH_BCM4908 is not set -# CONFIG_ARCH_BCM_21664 is not set -# CONFIG_ARCH_BCM_23550 is not set -# CONFIG_ARCH_BCM_281XX is not set -# CONFIG_ARCH_BCM_5301X is not set -# CONFIG_ARCH_BCM_53573 is not set -# CONFIG_ARCH_BCM_63XX is not set -# CONFIG_ARCH_BCM_CYGNUS is not set -# CONFIG_ARCH_BCM_IPROC is not set -# CONFIG_ARCH_BCM_NSP is not set -# CONFIG_ARCH_BERLIN is not set -CONFIG_ARCH_BINFMT_ELF_STATE=y -# CONFIG_ARCH_BITMAIN is not set -# CONFIG_ARCH_BRCMSTB is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CNS3XXX is not set -# CONFIG_ARCH_DAVINCI is not set -# CONFIG_ARCH_DIGICOLOR is not set -# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set -# CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_EXYNOS is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_GEMINI is not set -# CONFIG_ARCH_HI3xxx is not set -# CONFIG_ARCH_HIGHBANK is not set -# CONFIG_ARCH_HISI is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_INTEL_SOCFPGA is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_K3 is not set -# CONFIG_ARCH_KEEMBAY is not set -# CONFIG_ARCH_KEYSTONE is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_LAYERSCAPE is not set -# CONFIG_ARCH_LG1K is not set -# CONFIG_ARCH_LPC32XX is not set -# CONFIG_ARCH_MEDIATEK is not set -# CONFIG_ARCH_MESON is not set -# CONFIG_ARCH_MILBEAUT is not set -CONFIG_ARCH_MMAP_RND_BITS=8 -CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 -# CONFIG_ARCH_MMP is not set -# CONFIG_ARCH_MSTARV7 is not set -# CONFIG_ARCH_MULTIPLATFORM is not set -# CONFIG_ARCH_MULTI_V6 is not set -# CONFIG_ARCH_MULTI_V7 is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_MVEBU is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_MXS is not set -# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_NOMADIK is not set -# CONFIG_ARCH_NPCM is not set -# CONFIG_ARCH_NSPIRE is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_OMAP1 is not set -# CONFIG_ARCH_OMAP2 is not set -# CONFIG_ARCH_OMAP2PLUS is not set -# CONFIG_ARCH_OMAP3 is not set -# CONFIG_ARCH_OMAP4 is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_OXNAS is not set -# CONFIG_ARCH_PICOXCELL is not set -# CONFIG_ARCH_PRIMA2 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_QCOM is not set -# CONFIG_ARCH_RANDOM is not set -# CONFIG_ARCH_RDA is not set -# CONFIG_ARCH_REALTEK is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_RENESAS is not set -# CONFIG_ARCH_ROCKCHIP is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_S32 is not set -# CONFIG_ARCH_S3C24XX is not set -# CONFIG_ARCH_S3C64XX is not set -# CONFIG_ARCH_S5PV210 is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_SEATTLE is not set -# CONFIG_ARCH_SHMOBILE is not set -# CONFIG_ARCH_SIRF is not set -# CONFIG_ARCH_SOCFPGA is not set -# CONFIG_ARCH_SPARX5 is not set -# CONFIG_ARCH_SPRD is not set -# CONFIG_ARCH_STI is not set -# CONFIG_ARCH_STM32 is not set -# CONFIG_ARCH_STRATIX10 is not set -# CONFIG_ARCH_SUNXI is not set -# CONFIG_ARCH_SYNQUACER is not set -# CONFIG_ARCH_TANGO is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_ARCH_THUNDER is not set -# CONFIG_ARCH_THUNDER2 is not set -# CONFIG_ARCH_U300 is not set -# CONFIG_ARCH_U8500 is not set -# CONFIG_ARCH_UNIPHIER is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_VEXPRESS is not set -# CONFIG_ARCH_VIRT is not set -# CONFIG_ARCH_VISCONTI is not set -# CONFIG_ARCH_VT8500 is not set -# CONFIG_ARCH_VULCAN is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_WANTS_THP_SWAP is not set -# CONFIG_ARCH_WM8505 is not set -# CONFIG_ARCH_WM8750 is not set -# CONFIG_ARCH_WM8850 is not set -# CONFIG_ARCH_XGENE is not set -# CONFIG_ARCH_ZX is not set -# CONFIG_ARCH_ZYNQ is not set -# CONFIG_ARCH_ZYNQMP is not set -# CONFIG_ARCNET is not set -# CONFIG_ARC_EMAC is not set -# CONFIG_ARC_IRQ_NO_AUTOSAVE is not set -# CONFIG_ARM64_16K_PAGES is not set -# CONFIG_ARM64_64K_PAGES is not set -# CONFIG_ARM64_AMU_EXTN is not set -# CONFIG_ARM64_BTI is not set -CONFIG_ARM64_CNP=y -# CONFIG_ARM64_CRYPTO is not set -# CONFIG_ARM64_E0PD is not set -# CONFIG_ARM64_EPAN is not set -# CONFIG_ARM64_ERRATUM_1024718 is not set -# CONFIG_ARM64_ERRATUM_1165522 is not set -# CONFIG_ARM64_ERRATUM_1286807 is not set -# CONFIG_ARM64_ERRATUM_1319367 is not set -# CONFIG_ARM64_ERRATUM_1418040 is not set -# CONFIG_ARM64_ERRATUM_1463225 is not set -# CONFIG_ARM64_ERRATUM_1508412 is not set -# CONFIG_ARM64_ERRATUM_1530923 is not set -# CONFIG_ARM64_ERRATUM_1542419 is not set -# CONFIG_ARM64_ERRATUM_1742098 is not set -# CONFIG_ARM64_ERRATUM_2253138 is not set -# CONFIG_ARM64_ERRATUM_2224489 is not set -# CONFIG_ARM64_ERRATUM_2054223 is not set -# CONFIG_ARM64_ERRATUM_2067961 is not set -# CONFIG_ARM64_ERRATUM_2441007 is not set -# CONFIG_ARM64_ERRATUM_2441009 is not set -# CONFIG_ARM64_ERRATUM_819472 is not set -# CONFIG_ARM64_ERRATUM_824069 is not set -# CONFIG_ARM64_ERRATUM_826319 is not set -# CONFIG_ARM64_ERRATUM_827319 is not set -# CONFIG_ARM64_ERRATUM_832075 is not set -# CONFIG_ARM64_ERRATUM_834220 is not set -# CONFIG_ARM64_ERRATUM_843419 is not set -# CONFIG_ARM64_ERRATUM_845719 is not set -# CONFIG_ARM64_ERRATUM_858921 is not set -# CONFIG_ARM64_HW_AFDBM is not set -# CONFIG_ARM64_LSE_ATOMICS is not set -CONFIG_ARM64_MODULE_PLTS=y -# CONFIG_ARM64_MTE is not set -CONFIG_ARM64_PAN=y -# CONFIG_ARM64_PMEM is not set -# CONFIG_ARM64_PSEUDO_NMI is not set -# CONFIG_ARM64_PTDUMP_DEBUGFS is not set -# CONFIG_ARM64_PTR_AUTH is not set -# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -# CONFIG_ARM64_RAS_EXTN is not set -# CONFIG_ARM64_RELOC_TEST is not set -# CONFIG_ARM64_SVE is not set -CONFIG_ARM64_SW_TTBR0_PAN=y -# CONFIG_ARM64_TLB_RANGE is not set -# CONFIG_ARM64_UAO is not set -# CONFIG_ARM64_USE_LSE_ATOMICS is not set -# CONFIG_ARM64_VA_BITS_48 is not set -# CONFIG_ARM64_VHE is not set -# CONFIG_ARM_APPENDED_DTB is not set -# CONFIG_ARM_ARCH_TIMER is not set -# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set -# CONFIG_ARM_CCI is not set -# CONFIG_ARM_CCI400_PMU is not set -# CONFIG_ARM_CCI5xx_PMU is not set -# CONFIG_ARM_CCI_PMU is not set -# CONFIG_ARM_CCN is not set -# CONFIG_ARM_CMN is not set -# CONFIG_ARM_CPUIDLE is not set -CONFIG_ARM_CPU_TOPOLOGY=y -# CONFIG_ARM_CRYPTO is not set -CONFIG_ARM_DMA_MEM_BUFFERABLE=y -# CONFIG_ARM_DSU_PMU is not set -# CONFIG_ARM_ERRATA_326103 is not set -# CONFIG_ARM_ERRATA_364296 is not set -# CONFIG_ARM_ERRATA_411920 is not set -# CONFIG_ARM_ERRATA_430973 is not set -# CONFIG_ARM_ERRATA_458693 is not set -# CONFIG_ARM_ERRATA_460075 is not set -# CONFIG_ARM_ERRATA_643719 is not set -# CONFIG_ARM_ERRATA_720789 is not set -# CONFIG_ARM_ERRATA_742230 is not set -# CONFIG_ARM_ERRATA_742231 is not set -# CONFIG_ARM_ERRATA_743622 is not set -# CONFIG_ARM_ERRATA_751472 is not set -# CONFIG_ARM_ERRATA_754322 is not set -# CONFIG_ARM_ERRATA_754327 is not set -# CONFIG_ARM_ERRATA_764369 is not set -# CONFIG_ARM_ERRATA_773022 is not set -# CONFIG_ARM_ERRATA_775420 is not set -# CONFIG_ARM_ERRATA_798181 is not set -# CONFIG_ARM_ERRATA_814220 is not set -# CONFIG_ARM_ERRATA_818325_852422 is not set -# CONFIG_ARM_ERRATA_821420 is not set -# CONFIG_ARM_ERRATA_825619 is not set -# CONFIG_ARM_ERRATA_852421 is not set -# CONFIG_ARM_ERRATA_852423 is not set -# CONFIG_ARM_ERRATA_857271 is not set -# CONFIG_ARM_ERRATA_857272 is not set -# CONFIG_ARM_FFA_TRANSPORT is not set -CONFIG_ARM_GIC_MAX_NR=1 -# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set -# CONFIG_ARM_KPROBES_TEST is not set -# CONFIG_ARM_LPAE is not set -# CONFIG_ARM_MEDIATEK_CPUFREQ_HW is not set -# CONFIG_ARM_MHU is not set -CONFIG_ARM_MODULE_PLTS=y -# CONFIG_ARM_PATCH_PHYS_VIRT is not set -# CONFIG_ARM_PSCI is not set -# CONFIG_ARM_PSCI_CHECKER is not set -# CONFIG_ARM_PSCI_CPUIDLE is not set -# CONFIG_ARM_PTDUMP_DEBUGFS is not set -# CONFIG_ARM_SBSA_WATCHDOG is not set -# CONFIG_ARM_SCMI_PROTOCOL is not set -# CONFIG_ARM_SCPI_PROTOCOL is not set -# CONFIG_ARM_SDE_INTERFACE is not set -# CONFIG_ARM_SMCCC_SOC_ID is not set -# CONFIG_ARM_SMC_WATCHDOG is not set -# CONFIG_ARM_SP805_WATCHDOG is not set -# CONFIG_ARM_SPE_PMU is not set -# CONFIG_ARM_THUMBEE is not set -# CONFIG_ARM_TIMER_SP804 is not set -# CONFIG_ARM_UNWIND is not set -# CONFIG_ARM_VIRT_EXT is not set -# CONFIG_AS3935 is not set -# CONFIG_AS73211 is not set -# CONFIG_ASM9260_TIMER is not set -# CONFIG_ASN1 is not set -# CONFIG_ASUS_LAPTOP is not set -# CONFIG_ASUS_WIRELESS is not set -# CONFIG_ASYMMETRIC_KEY_TYPE is not set -# CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE is not set -# CONFIG_ASYNC_RAID6_TEST is not set -# CONFIG_ASYNC_TX_DMA is not set -# CONFIG_AT76C50X_USB is not set -# CONFIG_AT803X_PHY is not set -# CONFIG_AT91_SAMA5D2_ADC is not set -# CONFIG_ATA is not set -# CONFIG_ATAGS is not set -CONFIG_ATAGS_PROC=y -# CONFIG_ATALK is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_ATA_ACPI is not set -CONFIG_ATA_BMDMA=y -# CONFIG_ATA_FORCE is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_ATA_LEDS is not set -# CONFIG_ATA_NONSTANDARD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_ATA_PIIX is not set -CONFIG_ATA_SFF=y -# CONFIG_ATA_VERBOSE_ERROR is not set -# CONFIG_ATH10K is not set -# CONFIG_ATH25 is not set -# CONFIG_ATH5K is not set -# CONFIG_ATH6KL is not set -# CONFIG_ATH79 is not set -# CONFIG_ATH9K is not set -# CONFIG_ATH9K_HTC is not set -# CONFIG_ATH_DEBUG is not set -# CONFIG_ATL1 is not set -# CONFIG_ATL1C is not set -# CONFIG_ATL1E is not set -# CONFIG_ATL2 is not set -# CONFIG_ATLAS_EZO_SENSOR is not set -# CONFIG_ATLAS_PH_SENSOR is not set -# CONFIG_ATM is not set -# CONFIG_ATMEL is not set -# CONFIG_ATMEL_PIT is not set -# CONFIG_ATMEL_SSC is not set -# CONFIG_ATM_AMBASSADOR is not set -# CONFIG_ATM_BR2684 is not set -CONFIG_ATM_BR2684_IPFILTER=y -# CONFIG_ATM_CLIP is not set -CONFIG_ATM_CLIP_NO_ICMP=y -# CONFIG_ATM_DRIVERS is not set -# CONFIG_ATM_DUMMY is not set -# CONFIG_ATM_ENI is not set -# CONFIG_ATM_FIRESTREAM is not set -# CONFIG_ATM_FORE200E is not set -# CONFIG_ATM_HE is not set -# CONFIG_ATM_HORIZON is not set -# CONFIG_ATM_IA is not set -# CONFIG_ATM_IDT77252 is not set -# CONFIG_ATM_LANAI is not set -# CONFIG_ATM_LANE is not set -# CONFIG_ATM_MPOA is not set -# CONFIG_ATM_NICSTAR is not set -# CONFIG_ATM_SOLOS is not set -# CONFIG_ATM_TCP is not set -# CONFIG_ATM_ZATM is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_ATP is not set -# CONFIG_AUDIT is not set -# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -# CONFIG_AURORA_NB8800 is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTO_ZRELADDR is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_AX25 is not set -# CONFIG_AX25_DAMA_SLAVE is not set -# CONFIG_AX88796 is not set -# CONFIG_AX88796B_PHY is not set -# CONFIG_AXP20X_ADC is not set -# CONFIG_AXP20X_POWER is not set -# CONFIG_AXP288_ADC is not set -# CONFIG_AXP288_FUEL_GAUGE is not set -# CONFIG_B43 is not set -# CONFIG_B43LEGACY is not set -# CONFIG_B44 is not set -# CONFIG_B53 is not set -# CONFIG_B53_MDIO_DRIVER is not set -# CONFIG_B53_MMAP_DRIVER is not set -# CONFIG_B53_SERDES is not set -# CONFIG_B53_SPI_DRIVER is not set -# CONFIG_B53_SRAB_DRIVER is not set -# CONFIG_BACKLIGHT_ADP8860 is not set -# CONFIG_BACKLIGHT_ADP8870 is not set -# CONFIG_BACKLIGHT_APPLE is not set -# CONFIG_BACKLIGHT_ARCXCNN is not set -# CONFIG_BACKLIGHT_BD6107 is not set -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -# CONFIG_BACKLIGHT_GENERIC is not set -# CONFIG_BACKLIGHT_GPIO is not set -# CONFIG_BACKLIGHT_KTD253 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -# CONFIG_BACKLIGHT_LED is not set -# CONFIG_BACKLIGHT_LM3630A is not set -# CONFIG_BACKLIGHT_LM3639 is not set -# CONFIG_BACKLIGHT_LP855X is not set -# CONFIG_BACKLIGHT_LV5207LP is not set -# CONFIG_BACKLIGHT_PANDORA is not set -# CONFIG_BACKLIGHT_PM8941_WLED is not set -# CONFIG_BACKLIGHT_PWM is not set -# CONFIG_BACKLIGHT_QCOM_WLED is not set -# CONFIG_BACKLIGHT_RPI is not set -# CONFIG_BACKLIGHT_SAHARA is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_BAREUDP is not set -CONFIG_BASE_FULL=y -CONFIG_BASE_SMALL=0 -# CONFIG_BATMAN_ADV is not set -# CONFIG_BATTERY_BQ27XXX is not set -# CONFIG_BATTERY_BQ27XXX_HDQ is not set -# CONFIG_BATTERY_CW2015 is not set -# CONFIG_BATTERY_DS2760 is not set -# CONFIG_BATTERY_DS2780 is not set -# CONFIG_BATTERY_DS2781 is not set -# CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_GAUGE_LTC2941 is not set -# CONFIG_BATTERY_GOLDFISH is not set -# CONFIG_BATTERY_LEGO_EV3 is not set -# CONFIG_BATTERY_MAX17040 is not set -# CONFIG_BATTERY_MAX17042 is not set -# CONFIG_BATTERY_MAX1721X is not set -# CONFIG_BATTERY_RT5033 is not set -# CONFIG_BATTERY_SBS is not set -# CONFIG_BAYCOM_EPP is not set -# CONFIG_BAYCOM_PAR is not set -# CONFIG_BAYCOM_SER_FDX is not set -# CONFIG_BAYCOM_SER_HDX is not set -# CONFIG_BCACHE is not set -# CONFIG_BCM47XX is not set -# CONFIG_BCM54140_PHY is not set -# CONFIG_BCM63XX is not set -# CONFIG_BCM63XX_PHY is not set -# CONFIG_BCM7038_WDT is not set -# CONFIG_BCM7XXX_PHY is not set -# CONFIG_BCM84881_PHY is not set -# CONFIG_BCM87XX_PHY is not set -# CONFIG_BCMA is not set -# CONFIG_BCMA_DRIVER_GPIO is not set -CONFIG_BCMA_POSSIBLE=y -# CONFIG_BCMGENET is not set -# CONFIG_BCM_IPROC_ADC is not set -# CONFIG_BCM_KONA_USB2_PHY is not set -# CONFIG_BCM_SBA_RAID is not set -# CONFIG_BCM_VK is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_BE2ISCSI is not set -# CONFIG_BE2NET is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_BGMAC is not set -# CONFIG_BH1750 is not set -# CONFIG_BH1780 is not set -# CONFIG_BIG_KEYS is not set -# CONFIG_BIG_LITTLE is not set -CONFIG_BINARY_PRINTF=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_ELF_FDPIC is not set -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set -CONFIG_BINFMT_SCRIPT=y -CONFIG_BITREVERSE=y -# CONFIG_BLK_CGROUP_IOCOST is not set -# CONFIG_BLK_CGROUP_IOLATENCY is not set -# CONFIG_BLK_CGROUP_IOPRIO is not set -# CONFIG_BLK_CMDLINE_PARSER is not set -# CONFIG_BLK_DEBUG_FS is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_BLK_DEV_4DRIVES is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI14XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_ATIIXP is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_BSGLIB is not set -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_CS5535 is not set -# CONFIG_BLK_DEV_CS5536 is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_DELKIN is not set -# CONFIG_BLK_DEV_DM is not set -# CONFIG_BLK_DEV_DRBD is not set -# CONFIG_BLK_DEV_DTC2278 is not set -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_HT6560B is not set -# CONFIG_BLK_DEV_IDEACPI is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDECS is not set -# CONFIG_BLK_DEV_IDEPCI is not set -# CONFIG_BLK_DEV_IDEPNP is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDE_AU1XXX is not set -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_INITRD=y -# CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_IT8172 is not set -# CONFIG_BLK_DEV_IT8213 is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_LOOP is not set -CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -# CONFIG_BLK_DEV_MD is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_NULL_BLK is not set -# CONFIG_BLK_DEV_NVME is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_PLATFORM is not set -# CONFIG_BLK_DEV_PMEM is not set -# CONFIG_BLK_DEV_QD65XX is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_RBD is not set -# CONFIG_BLK_DEV_RSXX is not set -# CONFIG_BLK_DEV_RZ1000 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_SD is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SIS5513 is not set -# CONFIG_BLK_DEV_SKD is not set -# CONFIG_BLK_DEV_SL82C105 is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_TC86C001 is not set -# CONFIG_BLK_DEV_THROTTLING is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_UMC8672 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_BLK_DEV_ZONED is not set -# CONFIG_BLK_INLINE_ENCRYPTION is not set -# CONFIG_BLK_SED_OPAL is not set -# CONFIG_BLK_WBT is not set -CONFIG_BLOCK=y -# CONFIG_BMA180 is not set -# CONFIG_BMA220 is not set -# CONFIG_BMA400 is not set -# CONFIG_BMC150_ACCEL is not set -# CONFIG_BMC150_MAGN is not set -# CONFIG_BMC150_MAGN_I2C is not set -# CONFIG_BMC150_MAGN_SPI is not set -# CONFIG_BME680 is not set -# CONFIG_BMG160 is not set -# CONFIG_BMI088_ACCEL is not set -# CONFIG_BMI160_I2C is not set -# CONFIG_BMI160_SPI is not set -# CONFIG_BMIPS_GENERIC is not set -# CONFIG_BMP280 is not set -# CONFIG_BNA is not set -# CONFIG_BNX2 is not set -# CONFIG_BNX2X is not set -# CONFIG_BNX2X_SRIOV is not set -# CONFIG_BNXT is not set -# CONFIG_BONDING is not set -# CONFIG_BOOKE_WDT is not set -CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3 -# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -# CONFIG_BOOTTIME_TRACING is not set -# CONFIG_BOOT_CONFIG is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -CONFIG_BOOT_RAW=y -# CONFIG_BOUNCE is not set -CONFIG_BPF=y -# CONFIG_BPFILTER is not set -CONFIG_BPF_JIT=y -# CONFIG_BPF_JIT_ALWAYS_ON is not set -CONFIG_BPF_JIT_DEFAULT_ON=y -# CONFIG_BPF_PRELOAD is not set -# CONFIG_BPF_STREAM_PARSER is not set -CONFIG_BPF_SYSCALL=y -CONFIG_BPF_UNPRIV_DEFAULT_OFF=y -# CONFIG_BPQETHER is not set -CONFIG_BQL=y -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_BRCMFMAC is not set -# CONFIG_BRCMSMAC is not set -# CONFIG_BRCMSTB_GISB_ARB is not set -CONFIG_BRIDGE=y -# CONFIG_BRIDGE_CFM is not set -# CONFIG_BRIDGE_EBT_802_3 is not set -# CONFIG_BRIDGE_EBT_AMONG is not set -# CONFIG_BRIDGE_EBT_ARP is not set -# CONFIG_BRIDGE_EBT_ARPREPLY is not set -# CONFIG_BRIDGE_EBT_BROUTE is not set -# CONFIG_BRIDGE_EBT_DNAT is not set -# CONFIG_BRIDGE_EBT_IP is not set -# CONFIG_BRIDGE_EBT_IP6 is not set -# CONFIG_BRIDGE_EBT_LIMIT is not set -# CONFIG_BRIDGE_EBT_LOG is not set -# CONFIG_BRIDGE_EBT_MARK is not set -# CONFIG_BRIDGE_EBT_MARK_T is not set -# CONFIG_BRIDGE_EBT_NFLOG is not set -# CONFIG_BRIDGE_EBT_PKTTYPE is not set -# CONFIG_BRIDGE_EBT_REDIRECT is not set -# CONFIG_BRIDGE_EBT_SNAT is not set -# CONFIG_BRIDGE_EBT_STP is not set -# CONFIG_BRIDGE_EBT_T_FILTER is not set -# CONFIG_BRIDGE_EBT_T_NAT is not set -# CONFIG_BRIDGE_EBT_VLAN is not set -CONFIG_BRIDGE_IGMP_SNOOPING=y -# CONFIG_BRIDGE_MRP is not set -# CONFIG_BRIDGE_NETFILTER is not set -# CONFIG_BRIDGE_NF_EBTABLES is not set -CONFIG_BRIDGE_VLAN_FILTERING=y -# CONFIG_BROADCOM_PHY is not set -CONFIG_BROKEN_ON_SMP=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_BT is not set -# CONFIG_BTRFS_ASSERT is not set -# CONFIG_BTRFS_DEBUG is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set -# CONFIG_BTRFS_FS_POSIX_ACL is not set -# CONFIG_BTRFS_FS_REF_VERIFY is not set -# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set -# CONFIG_BT_AOSPEXT is not set -# CONFIG_BT_ATH3K is not set -# CONFIG_BT_BNEP is not set -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -# CONFIG_BT_BREDR is not set -# CONFIG_BT_CMTP is not set -# CONFIG_BT_FEATURE_DEBUG is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBFUSB is not set -# CONFIG_BT_HCIBLUECARD is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBT3C is not set -# CONFIG_BT_HCIBTSDIO is not set -# CONFIG_BT_HCIBTUSB is not set -# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set -# CONFIG_BT_HCIBTUSB_MTK is not set -# CONFIG_BT_HCIBTUSB_RTL is not set -# CONFIG_BT_HCIDTL1 is not set -# CONFIG_BT_HCIUART is not set -# CONFIG_BT_HCIUART_3WIRE is not set -# CONFIG_BT_HCIUART_AG6XX is not set -# CONFIG_BT_HCIUART_ATH3K is not set -CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_H4=y -# CONFIG_BT_HCIUART_LL is not set -# CONFIG_BT_HCIUART_MRVL is not set -# CONFIG_BT_HCIUART_QCA is not set -# CONFIG_BT_HCIUART_RTL is not set -# CONFIG_BT_HCIVHCI is not set -# CONFIG_BT_HIDP is not set -# CONFIG_BT_HS is not set -# CONFIG_BT_LE is not set -# CONFIG_BT_LEDS is not set -# CONFIG_BT_MRVL is not set -# CONFIG_BT_MSFTEXT is not set -# CONFIG_BT_MTKSDIO is not set -# CONFIG_BT_MTKUART is not set -# CONFIG_BT_RFCOMM is not set -CONFIG_BT_RFCOMM_TTY=y -# CONFIG_BT_SELFTEST is not set -# CONFIG_BT_VIRTIO is not set -CONFIG_BUG=y -# CONFIG_BUG_ON_DATA_CORRUPTION is not set -CONFIG_BUILDTIME_EXTABLE_SORT=y -CONFIG_BUILDTIME_TABLE_SORT=y -# CONFIG_BUILD_BIN2C is not set -CONFIG_BUILD_SALT="" -# CONFIG_C2PORT is not set -CONFIG_CACHE_L2X0_PMU=y -# CONFIG_CADENCE_WATCHDOG is not set -# CONFIG_CAIF is not set -# CONFIG_CAN is not set -# CONFIG_CAN_BCM is not set -# CONFIG_CAN_DEBUG_DEVICES is not set -# CONFIG_CAN_DEV is not set -# CONFIG_CAN_ETAS_ES58X is not set -# CONFIG_CAN_GS_USB is not set -# CONFIG_CAN_GW is not set -# CONFIG_CAN_HI311X is not set -# CONFIG_CAN_IFI_CANFD is not set -# CONFIG_CAN_ISOTP is not set -# CONFIG_CAN_J1939 is not set -# CONFIG_CAN_KVASER_PCIEFD is not set -# CONFIG_CAN_MCBA_USB is not set -# CONFIG_CAN_MCP251XFD is not set -# CONFIG_CAN_M_CAN is not set -# CONFIG_CAN_PEAK_PCIEFD is not set -# CONFIG_CAN_RAW is not set -# CONFIG_CAN_RCAR is not set -# CONFIG_CAN_RCAR_CANFD is not set -# CONFIG_CAN_SLCAN is not set -# CONFIG_CAN_SUN4I is not set -# CONFIG_CAN_UCAN is not set -# CONFIG_CAN_VCAN is not set -# CONFIG_CAN_VXCAN is not set -# CONFIG_CAPI_AVM is not set -# CONFIG_CAPI_EICON is not set -# CONFIG_CAPI_TRACE is not set -CONFIG_CARDBUS=y -# CONFIG_CARDMAN_4000 is not set -# CONFIG_CARDMAN_4040 is not set -# CONFIG_CARL9170 is not set -# CONFIG_CASSINI is not set -# CONFIG_CAVIUM_CPT is not set -# CONFIG_CAVIUM_ERRATUM_22375 is not set -# CONFIG_CAVIUM_ERRATUM_23144 is not set -# CONFIG_CAVIUM_ERRATUM_23154 is not set -# CONFIG_CAVIUM_ERRATUM_27456 is not set -# CONFIG_CAVIUM_ERRATUM_30115 is not set -# CONFIG_CAVIUM_OCTEON_SOC is not set -# CONFIG_CAVIUM_PTP is not set -# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set -# CONFIG_CB710_CORE is not set -# CONFIG_CC10001_ADC is not set -# CONFIG_CCS811 is not set -CONFIG_CC_CAN_LINK=y -CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_CEPH_FS is not set -# CONFIG_CEPH_LIB is not set -# CONFIG_CFG80211 is not set -# CONFIG_CFG80211_CERTIFICATION_ONUS is not set -# CONFIG_CGROUPS is not set -# CONFIG_CGROUP_MISC is not set -# CONFIG_CHARGER_ADP5061 is not set -# CONFIG_CHARGER_BD99954 is not set -# CONFIG_CHARGER_BQ2415X is not set -# CONFIG_CHARGER_BQ24190 is not set -# CONFIG_CHARGER_BQ24257 is not set -# CONFIG_CHARGER_BQ24735 is not set -# CONFIG_CHARGER_BQ2515X is not set -# CONFIG_CHARGER_BQ256XX is not set -# CONFIG_CHARGER_BQ25890 is not set -# CONFIG_CHARGER_BQ25980 is not set -# CONFIG_CHARGER_DETECTOR_MAX14656 is not set -# CONFIG_CHARGER_GPIO is not set -# CONFIG_CHARGER_ISP1704 is not set -# CONFIG_CHARGER_LP8727 is not set -# CONFIG_CHARGER_LT3651 is not set -# CONFIG_CHARGER_LTC3651 is not set -# CONFIG_CHARGER_LTC4162L is not set -# CONFIG_CHARGER_MANAGER is not set -# CONFIG_CHARGER_MAX8903 is not set -# CONFIG_CHARGER_QCOM_SMBB is not set -# CONFIG_CHARGER_RT9455 is not set -# CONFIG_CHARGER_SBS is not set -# CONFIG_CHARGER_SMB347 is not set -# CONFIG_CHARGER_TWL4030 is not set -# CONFIG_CHARGER_UCS1002 is not set -# CONFIG_CHASH_SELFTEST is not set -# CONFIG_CHASH_STATS is not set -# CONFIG_CHECKPOINT_RESTORE is not set -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_CHELSIO_T4 is not set -# CONFIG_CHELSIO_T4VF is not set -# CONFIG_CHROME_PLATFORMS is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_CIFS is not set -# CONFIG_CIFS_ACL is not set -CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y -# CONFIG_CIFS_DEBUG is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_FSCACHE is not set -# CONFIG_CIFS_NFSD_EXPORT is not set -CONFIG_CIFS_POSIX=y -# CONFIG_CIFS_SMB2 is not set -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_STATS2 is not set -# CONFIG_CIFS_SWN_UPCALL is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -CONFIG_CIFS_XATTR=y -# CONFIG_CIO_DAC is not set -# CONFIG_CLEANCACHE is not set -# CONFIG_CLKSRC_PISTACHIO is not set -# CONFIG_CLKSRC_VERSATILE is not set -# CONFIG_CLK_GFM_LPASS_SM8250 is not set -# CONFIG_CLK_HSDK is not set -# CONFIG_CLK_QORIQ is not set -# CONFIG_CLK_SP810 is not set -# CONFIG_CLOCK_THERMAL is not set -CONFIG_CLS_U32_MARK=y -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CM32181 is not set -# CONFIG_CM3232 is not set -# CONFIG_CM3323 is not set -# CONFIG_CM3605 is not set -# CONFIG_CM36651 is not set -# CONFIG_CMA is not set -CONFIG_CMDLINE="" -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_CMDLINE_EXTEND is not set -# CONFIG_CMDLINE_FORCE is not set -# CONFIG_CMDLINE_FROM_BOOTLOADER is not set -# CONFIG_CMDLINE_PARTITION is not set -# CONFIG_CNIC is not set -# CONFIG_CODA_FS is not set -# CONFIG_CODE_PATCHING_SELFTEST is not set -# CONFIG_COMEDI is not set -# CONFIG_COMMON_CLK_AXI_CLKGEN is not set -# CONFIG_COMMON_CLK_BOSTON is not set -# CONFIG_COMMON_CLK_CDCE706 is not set -# CONFIG_COMMON_CLK_CDCE925 is not set -# CONFIG_COMMON_CLK_CS2000_CP is not set -# CONFIG_COMMON_CLK_FIXED_MMIO is not set -# CONFIG_COMMON_CLK_IPROC is not set -# CONFIG_COMMON_CLK_MAX9485 is not set -# CONFIG_COMMON_CLK_MT6765 is not set -# CONFIG_COMMON_CLK_MT8167 is not set -# CONFIG_COMMON_CLK_MT8167_AUDSYS is not set -# CONFIG_COMMON_CLK_MT8167_IMGSYS is not set -# CONFIG_COMMON_CLK_MT8167_MFGCFG is not set -# CONFIG_COMMON_CLK_MT8167_MMSYS is not set -# CONFIG_COMMON_CLK_MT8167_VDECSYS is not set -# CONFIG_COMMON_CLK_MT8192 is not set -# CONFIG_COMMON_CLK_NXP is not set -# CONFIG_COMMON_CLK_PIC32 is not set -# CONFIG_COMMON_CLK_PISTACHIO is not set -# CONFIG_COMMON_CLK_PWM is not set -# CONFIG_COMMON_CLK_PXA is not set -# CONFIG_COMMON_CLK_QCOM is not set -# CONFIG_COMMON_CLK_SI514 is not set -# CONFIG_COMMON_CLK_SI5341 is not set -# CONFIG_COMMON_CLK_SI5351 is not set -# CONFIG_COMMON_CLK_SI544 is not set -# CONFIG_COMMON_CLK_SI570 is not set -# CONFIG_COMMON_CLK_VC5 is not set -# CONFIG_COMMON_CLK_XGENE is not set -# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set -CONFIG_COMPACTION=y -# CONFIG_COMPAL_LAPTOP is not set -# CONFIG_COMPAT is not set -# CONFIG_COMPAT_BRK is not set -# CONFIG_COMPILE_TEST is not set -# CONFIG_CONFIGFS_FS is not set -# CONFIG_CONNECTOR is not set -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 -CONFIG_CONSOLE_LOGLEVEL_QUIET=4 -CONFIG_CONSTRUCTORS=y -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_COPS is not set -# CONFIG_CORDIC is not set -# CONFIG_COREDUMP is not set -# CONFIG_CORESIGHT is not set -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_CORTINA_PHY is not set -# CONFIG_COUNTER is not set -# CONFIG_CPA_DEBUG is not set -# CONFIG_CPU_BIG_ENDIAN is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set -# CONFIG_CPU_FREQ_STAT_DETAILS is not set -# CONFIG_CPU_FREQ_THERMAL is not set -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set -# CONFIG_CPU_IDLE is not set -# CONFIG_CPU_IDLE_GOV_LADDER is not set -# CONFIG_CPU_IDLE_GOV_MENU is not set -# CONFIG_CPU_IDLE_GOV_TEO is not set -# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set -# CONFIG_CPU_ISOLATION is not set -# CONFIG_CPU_LITTLE_ENDIAN is not set -# CONFIG_CPU_NO_EFFICIENT_FFS is not set -CONFIG_CPU_SW_DOMAIN_PAN=y -# CONFIG_CPU_THERMAL is not set -# CONFIG_CRAMFS is not set -CONFIG_CRAMFS_BLOCKDEV=y -# CONFIG_CRAMFS_MTD is not set -# CONFIG_CRASH_DUMP is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_CRC32_BIT is not set -# CONFIG_CRC32_SARWATE is not set -# CONFIG_CRC32_SELFTEST is not set -# CONFIG_CRC32_SLICEBY4 is not set -CONFIG_CRC32_SLICEBY8=y -# CONFIG_CRC4 is not set -# CONFIG_CRC64 is not set -# CONFIG_CRC7 is not set -# CONFIG_CRC8 is not set -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC_ITU_T is not set -# CONFIG_CRC_T10DIF is not set -CONFIG_CROSS_COMPILE="" -# CONFIG_CROSS_MEMORY_ATTACH is not set -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_842 is not set -CONFIG_CRYPTO_ACOMP2=y -# CONFIG_CRYPTO_ADIANTUM is not set -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -# CONFIG_CRYPTO_AEGIS128 is not set -# CONFIG_CRYPTO_AEGIS128L is not set -# CONFIG_CRYPTO_AEGIS128L_AESNI_SSE2 is not set -# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set -# CONFIG_CRYPTO_AEGIS256 is not set -# CONFIG_CRYPTO_AEGIS256_AESNI_SSE2 is not set -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_AES_586 is not set -# CONFIG_CRYPTO_AES_ARM is not set -# CONFIG_CRYPTO_AES_ARM64 is not set -# CONFIG_CRYPTO_AES_ARM64_BS is not set -# CONFIG_CRYPTO_AES_ARM64_CE is not set -# CONFIG_CRYPTO_AES_ARM64_CE_BLK is not set -# CONFIG_CRYPTO_AES_ARM64_CE_CCM is not set -# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set -# CONFIG_CRYPTO_AES_ARM_BS is not set -# CONFIG_CRYPTO_AES_ARM_CE is not set -# CONFIG_CRYPTO_AES_NI_INTEL is not set -# CONFIG_CRYPTO_AES_TI is not set -CONFIG_CRYPTO_AKCIPHER=y -CONFIG_CRYPTO_AKCIPHER2=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_BLAKE2B is not set -# CONFIG_CRYPTO_BLAKE2B_NEON is not set -# CONFIG_CRYPTO_BLAKE2S_ARM is not set -# CONFIG_CRYPTO_BLAKE2S_X86 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_CBC is not set -CONFIG_CRYPTO_CCM=y -# CONFIG_CRYPTO_CFB is not set -# CONFIG_CRYPTO_CHACHA20 is not set -# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -# CONFIG_CRYPTO_CHACHA20_NEON is not set -# CONFIG_CRYPTO_CHACHA20_X86_64 is not set -# CONFIG_CRYPTO_CHACHA_MIPS is not set -# CONFIG_CRYPTO_CMAC is not set -# CONFIG_CRYPTO_CRC32 is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CRC32C_INTEL is not set -# CONFIG_CRYPTO_CRC32_ARM_CE is not set -# CONFIG_CRYPTO_CRCT10DIF is not set -# CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set -# CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_CTR=y -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_CURVE25519 is not set -# CONFIG_CRYPTO_CURVE25519_NEON is not set -# CONFIG_CRYPTO_CURVE25519_X86 is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set -# CONFIG_CRYPTO_DEV_ATMEL_AES is not set -# CONFIG_CRYPTO_DEV_ATMEL_AUTHENC is not set -# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set -# CONFIG_CRYPTO_DEV_ATMEL_SHA is not set -# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set -# CONFIG_CRYPTO_DEV_ATMEL_TDES is not set -# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set -# CONFIG_CRYPTO_DEV_CCP is not set -# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set -# CONFIG_CRYPTO_DEV_CCREE is not set -# CONFIG_CRYPTO_DEV_FSL_CAAM is not set -# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set -# CONFIG_CRYPTO_DEV_HIFN_795X is not set -# CONFIG_CRYPTO_DEV_HISI_SEC is not set -# CONFIG_CRYPTO_DEV_HISI_ZIP is not set -# CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set -# CONFIG_CRYPTO_DEV_MARVELL_CESA is not set -# CONFIG_CRYPTO_DEV_MEDIATEK is not set -# CONFIG_CRYPTO_DEV_MV_CESA is not set -# CONFIG_CRYPTO_DEV_MXC_SCC is not set -# CONFIG_CRYPTO_DEV_MXS_DCP is not set -# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set -# CONFIG_CRYPTO_DEV_OCTEONTX_CPT is not set -# CONFIG_CRYPTO_DEV_QAT_4XXX is not set -# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set -# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set -# CONFIG_CRYPTO_DEV_QAT_C62X is not set -# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set -# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set -# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set -# CONFIG_CRYPTO_DEV_QCE is not set -# CONFIG_CRYPTO_DEV_S5P is not set -# CONFIG_CRYPTO_DEV_SAFEXCEL is not set -# CONFIG_CRYPTO_DEV_SAHARA is not set -# CONFIG_CRYPTO_DEV_SP_PSP is not set -# CONFIG_CRYPTO_DEV_TALITOS is not set -# CONFIG_CRYPTO_DEV_VIRTIO is not set -# CONFIG_CRYPTO_DH is not set -# CONFIG_CRYPTO_DRBG_CTR is not set -# CONFIG_CRYPTO_DRBG_HASH is not set -# CONFIG_CRYPTO_DRBG_MENU is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_ECDH is not set -# CONFIG_CRYPTO_ECDSA is not set -# CONFIG_CRYPTO_ECHAINIV is not set -# CONFIG_CRYPTO_ECRDSA is not set -# CONFIG_CRYPTO_ESSIV is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_GCM=y -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_GHASH=y -# CONFIG_CRYPTO_GHASH_ARM64_CE is not set -# CONFIG_CRYPTO_GHASH_ARM_CE is not set -# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_HW is not set -# CONFIG_CRYPTO_JITTERENTROPY is not set -# CONFIG_CRYPTO_KEYWRAP is not set -# CONFIG_CRYPTO_KHAZAD is not set -CONFIG_CRYPTO_KPP=y -CONFIG_CRYPTO_KPP2=y -CONFIG_CRYPTO_LIB_AES=y -CONFIG_CRYPTO_LIB_ARC4=y -# CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC is not set -# CONFIG_CRYPTO_LIB_CHACHA is not set -# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set -# CONFIG_CRYPTO_LIB_CURVE25519 is not set -# CONFIG_CRYPTO_LIB_POLY1305 is not set -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_LZ4 is not set -# CONFIG_CRYPTO_LZ4HC is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -# CONFIG_CRYPTO_MCRYPTD is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_MORUS1280 is not set -# CONFIG_CRYPTO_MORUS1280_AVX2 is not set -# CONFIG_CRYPTO_MORUS1280_SSE2 is not set -# CONFIG_CRYPTO_MORUS640 is not set -# CONFIG_CRYPTO_MORUS640_SSE2 is not set -# CONFIG_CRYPTO_NHPOLY1305_NEON is not set -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_NULL2=y -# CONFIG_CRYPTO_OFB is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_PCOMP is not set -# CONFIG_CRYPTO_PCOMP2 is not set -CONFIG_CRYPTO_PCRYPT=y -# CONFIG_CRYPTO_POLY1305 is not set -# CONFIG_CRYPTO_POLY1305_ARM is not set -# CONFIG_CRYPTO_POLY1305_MIPS is not set -# CONFIG_CRYPTO_POLY1305_NEON is not set -# CONFIG_CRYPTO_POLY1305_X86_64 is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RNG is not set -# CONFIG_CRYPTO_RSA is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SEQIV is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA1_ARM is not set -# CONFIG_CRYPTO_SHA1_ARM64_CE is not set -# CONFIG_CRYPTO_SHA1_ARM_CE is not set -# CONFIG_CRYPTO_SHA1_ARM_NEON is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA256_ARM is not set -# CONFIG_CRYPTO_SHA256_ARM64 is not set -# CONFIG_CRYPTO_SHA2_ARM64_CE is not set -# CONFIG_CRYPTO_SHA2_ARM_CE is not set -# CONFIG_CRYPTO_SHA3 is not set -# CONFIG_CRYPTO_SHA3_ARM64 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_SHA512_ARM is not set -# CONFIG_CRYPTO_SHA512_ARM64 is not set -# CONFIG_CRYPTO_SHA512_ARM64_CE is not set -# CONFIG_CRYPTO_SIMD is not set -CONFIG_CRYPTO_SKCIPHER=y -CONFIG_CRYPTO_SKCIPHER2=y -# CONFIG_CRYPTO_SM2 is not set -# CONFIG_CRYPTO_SM3 is not set -# CONFIG_CRYPTO_SM3_ARM64_CE is not set -# CONFIG_CRYPTO_SM4 is not set -# CONFIG_CRYPTO_SM4_ARM64_CE is not set -# CONFIG_CRYPTO_SPECK is not set -# CONFIG_CRYPTO_STATS is not set -# CONFIG_CRYPTO_STREEBOG is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TEST is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_TWOFISH_586 is not set -# CONFIG_CRYPTO_TWOFISH_COMMON is not set -# CONFIG_CRYPTO_USER is not set -# CONFIG_CRYPTO_USER_API_AEAD is not set -# CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set -# CONFIG_CRYPTO_USER_API_HASH is not set -# CONFIG_CRYPTO_USER_API_RNG is not set -# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set -# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -# CONFIG_CRYPTO_VMAC is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_XXHASH is not set -# CONFIG_CRYPTO_ZLIB is not set -# CONFIG_CRYPTO_ZSTD is not set -# CONFIG_CS5535_MFGPT is not set -# CONFIG_CS89x0 is not set -# CONFIG_CS89x0_PLATFORM is not set -# CONFIG_CSD_LOCK_WAIT_DEBUG is not set -# CONFIG_CUSE is not set -# CONFIG_CW1200 is not set -# CONFIG_CXD2880_SPI_DRV is not set -# CONFIG_CXL_AFU_DRIVER_OPS is not set -# CONFIG_CXL_BASE is not set -# CONFIG_CXL_BUS is not set -# CONFIG_CXL_EEH is not set -# CONFIG_CXL_KERNEL_API is not set -# CONFIG_CXL_LIB is not set -# CONFIG_CYPRESS_FIRMWARE is not set -# CONFIG_DA280 is not set -# CONFIG_DA311 is not set -# CONFIG_DAMON is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_DAX is not set -# CONFIG_DCB is not set -# CONFIG_DDR is not set -# CONFIG_DEBUG_ALIGN_RODATA is not set -# CONFIG_DEBUG_ATOMIC_SLEEP is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_CREDENTIALS is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_EFI is not set -# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B is not set -# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_FS_ALLOW_ALL=y -# CONFIG_DEBUG_FS_ALLOW_NONE is not set -# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set -# CONFIG_DEBUG_GPIO is not set -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_ICEDCC is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_INFO_BTF is not set -# CONFIG_DEBUG_INFO_COMPRESSED is not set -# CONFIG_DEBUG_INFO_DWARF4 is not set -# CONFIG_DEBUG_INFO_DWARF5 is not set -CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y -# CONFIG_DEBUG_INFO_REDUCED is not set -# CONFIG_DEBUG_INFO_SPLIT is not set -# CONFIG_DEBUG_IRQFLAGS is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_KMAP_LOCAL is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_KOBJECT_RELEASE is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_LL is not set -# CONFIG_DEBUG_LL_UART_8250 is not set -# CONFIG_DEBUG_LL_UART_PL01X is not set -# CONFIG_DEBUG_LOCKDEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_MISC is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_NX_TEST is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_DEBUG_PAGE_REF is not set -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -# CONFIG_DEBUG_PER_CPU_MAPS is not set -# CONFIG_DEBUG_PINCTRL is not set -# CONFIG_DEBUG_PI_LIST is not set -# CONFIG_DEBUG_PLIST is not set -# CONFIG_DEBUG_PREEMPT is not set -# CONFIG_DEBUG_RODATA_TEST is not set -# CONFIG_DEBUG_RSEQ is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -# CONFIG_DEBUG_SEMIHOSTING is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_SHIRQ is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set -# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -# CONFIG_DEBUG_TIMEKEEPING is not set -# CONFIG_DEBUG_UART_8250_PALMCHIP is not set -# CONFIG_DEBUG_UART_8250_WORD is not set -# CONFIG_DEBUG_UART_BCM63XX is not set -# CONFIG_DEBUG_UART_FLOW_CONTROL is not set -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_VIRTUAL is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_VM_PGFLAGS is not set -# CONFIG_DEBUG_VM_PGTABLE is not set -# CONFIG_DEBUG_VM_RB is not set -# CONFIG_DEBUG_VM_VMACACHE is not set -# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -# CONFIG_DEBUG_WX is not set -# CONFIG_DEBUG_ZBOOT is not set -# CONFIG_DECNET is not set -# CONFIG_DEFAULT_CODEL is not set -CONFIG_DEFAULT_CUBIC=y -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_FQ is not set -CONFIG_DEFAULT_FQ_CODEL=y -# CONFIG_DEFAULT_FQ_PIE is not set -CONFIG_DEFAULT_HOSTNAME="(none)" -CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 -CONFIG_DEFAULT_INIT="" -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_DEFAULT_NET_SCH="fq_codel" -# CONFIG_DEFAULT_NOOP is not set -# CONFIG_DEFAULT_PFIFO_FAST is not set -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_SECURITY="" -CONFIG_DEFAULT_SECURITY_DAC=y -# CONFIG_DEFAULT_SECURITY_SELINUX is not set -# CONFIG_DEFAULT_SFQ is not set -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set -# CONFIG_DELL_LAPTOP is not set -# CONFIG_DELL_RBTN is not set -# CONFIG_DELL_SMBIOS is not set -# CONFIG_DELL_SMO8800 is not set -# CONFIG_DEPRECATED_PARAM_STRUCT is not set -# CONFIG_DETECT_HUNG_TASK is not set -# CONFIG_DEVKMEM is not set -# CONFIG_DEVMEM is not set -CONFIG_DEVPORT=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_DEVTMPFS is not set -# CONFIG_DEVTMPFS_MOUNT is not set -# CONFIG_DEV_DAX is not set -# CONFIG_DGAP is not set -# CONFIG_DGNC is not set -# CONFIG_DHT11 is not set -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_DISPLAY_CONNECTOR_ANALOG_TV is not set -# CONFIG_DISPLAY_CONNECTOR_DVI is not set -# CONFIG_DISPLAY_CONNECTOR_HDMI is not set -# CONFIG_DISPLAY_ENCODER_TFP410 is not set -# CONFIG_DISPLAY_ENCODER_TPD12S015 is not set -# CONFIG_DISPLAY_PANEL_DPI is not set -# CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02 is not set -# CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1 is not set -# CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1 is not set -# CONFIG_DL2K is not set -# CONFIG_DLHL60D is not set -# CONFIG_DLM is not set -# CONFIG_DM9000 is not set -# CONFIG_DMABUF_DEBUG is not set -# CONFIG_DMABUF_HEAPS is not set -# CONFIG_DMABUF_MOVE_NOTIFY is not set -# CONFIG_DMABUF_SELFTESTS is not set -# CONFIG_DMABUF_SYSFS_STATS is not set -# CONFIG_DMADEVICES is not set -# CONFIG_DMADEVICES_DEBUG is not set -# CONFIG_DMARD06 is not set -# CONFIG_DMARD09 is not set -# CONFIG_DMARD10 is not set -# CONFIG_DMASCC is not set -# CONFIG_DMATEST is not set -# CONFIG_DMA_API_DEBUG is not set -CONFIG_DMA_COHERENT_POOL=y -CONFIG_DMA_DECLARE_COHERENT=y -# CONFIG_DMA_ENGINE is not set -# CONFIG_DMA_FENCE_TRACE is not set -# CONFIG_DMA_JZ4780 is not set -# CONFIG_DMA_MAP_BENCHMARK is not set -CONFIG_DMA_NONCOHERENT_MMAP=y -# CONFIG_DMA_NOOP_OPS is not set -# CONFIG_DMA_PERNUMA_CMA is not set -# CONFIG_DMA_RESTRICTED_POOL is not set -# CONFIG_DMA_SHARED_BUFFER is not set -# CONFIG_DMA_VIRT_OPS is not set -# CONFIG_DM_CACHE is not set -# CONFIG_DM_CLONE is not set -# CONFIG_DM_DEBUG is not set -# CONFIG_DM_DELAY is not set -# CONFIG_DM_DUST is not set -# CONFIG_DM_EBS is not set -# CONFIG_DM_ERA is not set -# CONFIG_DM_FLAKEY is not set -# CONFIG_DM_INTEGRITY is not set -# CONFIG_DM_LOG_USERSPACE is not set -# CONFIG_DM_LOG_WRITES is not set -# CONFIG_DM_MQ_DEFAULT is not set -# CONFIG_DM_MULTIPATH is not set -# CONFIG_DM_RAID is not set -# CONFIG_DM_SWITCH is not set -# CONFIG_DM_THIN_PROVISIONING is not set -# CONFIG_DM_UEVENT is not set -# CONFIG_DM_UNSTRIPED is not set -# CONFIG_DM_VERITY is not set -# CONFIG_DM_WRITECACHE is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DNET is not set -# CONFIG_DNOTIFY is not set -# CONFIG_DNS_RESOLVER is not set -CONFIG_DOUBLEFAULT=y -# CONFIG_DP83640_PHY is not set -# CONFIG_DP83822_PHY is not set -# CONFIG_DP83848_PHY is not set -# CONFIG_DP83867_PHY is not set -# CONFIG_DP83869_PHY is not set -# CONFIG_DP83TC811_PHY is not set -# CONFIG_DPOT_DAC is not set -# CONFIG_DPS310 is not set -CONFIG_DQL=y -# CONFIG_DRAGONRISE_FF is not set -# CONFIG_DRM is not set -# CONFIG_DRM_AMDGPU is not set -# CONFIG_DRM_AMDGPU_CIK is not set -# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set -# CONFIG_DRM_AMDGPU_SI is not set -# CONFIG_DRM_AMDGPU_USERPTR is not set -# CONFIG_DRM_AMD_ACP is not set -# CONFIG_DRM_AMD_DC_DCN2_0 is not set -# CONFIG_DRM_AMD_DC_DCN3_0 is not set -# CONFIG_DRM_AMD_DC_HDCP is not set -# CONFIG_DRM_AMD_DC_SI is not set -# CONFIG_DRM_AMD_SECURE_DISPLAY is not set -# CONFIG_DRM_ANALOGIX_ANX6345 is not set -# CONFIG_DRM_ANALOGIX_ANX7625 is not set -# CONFIG_DRM_ANALOGIX_ANX78XX is not set -# CONFIG_DRM_ARCPGU is not set -# CONFIG_DRM_ARMADA is not set -# CONFIG_DRM_AST is not set -# CONFIG_DRM_ATMEL_HLCDC is not set -# CONFIG_DRM_BOCHS is not set -# CONFIG_DRM_CDNS_DSI is not set -# CONFIG_DRM_CDNS_MHDP8546 is not set -# CONFIG_DRM_CHIPONE_ICN6211 is not set -# CONFIG_DRM_CHRONTEL_CH7033 is not set -# CONFIG_DRM_CIRRUS_QEMU is not set -# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set -# CONFIG_DRM_DEBUG_MM is not set -# CONFIG_DRM_DEBUG_SELFTEST is not set -# CONFIG_DRM_DISPLAY_CONNECTOR is not set -# CONFIG_DRM_DP_AUX_CHARDEV is not set -# CONFIG_DRM_DP_CEC is not set -# CONFIG_DRM_DUMB_VGA_DAC is not set -# CONFIG_DRM_DW_HDMI_CEC is not set -# CONFIG_DRM_ETNAVIV is not set -# CONFIG_DRM_EXYNOS is not set -# CONFIG_DRM_FBDEV_EMULATION is not set -# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set -# CONFIG_DRM_FSL_DCU is not set -# CONFIG_DRM_GM12U320 is not set -# CONFIG_DRM_GMA500 is not set -# CONFIG_DRM_GUD is not set -# CONFIG_DRM_HDLCD is not set -# CONFIG_DRM_HISI_HIBMC is not set -# CONFIG_DRM_HISI_KIRIN is not set -# CONFIG_DRM_I2C_ADV7511 is not set -# CONFIG_DRM_I2C_CH7006 is not set -# CONFIG_DRM_I2C_NXP_TDA9950 is not set -# CONFIG_DRM_I2C_NXP_TDA998X is not set -# CONFIG_DRM_I2C_SIL164 is not set -# CONFIG_DRM_I915 is not set -# CONFIG_DRM_ITE_IT66121 is not set -# CONFIG_DRM_KOMEDA is not set -# CONFIG_DRM_LEGACY is not set -# CONFIG_DRM_LIB_RANDOM is not set -# CONFIG_DRM_LIMA is not set -# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set -# CONFIG_DRM_LONTIUM_LT8912B is not set -# CONFIG_DRM_LONTIUM_LT9611 is not set -# CONFIG_DRM_LONTIUM_LT9611UXC is not set -# CONFIG_DRM_LVDS_CODEC is not set -# CONFIG_DRM_LVDS_ENCODER is not set -# CONFIG_DRM_MALI_DISPLAY is not set -# CONFIG_DRM_MCDE is not set -# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set -# CONFIG_DRM_MGAG200 is not set -# CONFIG_DRM_MXSFB is not set -# CONFIG_DRM_NOUVEAU is not set -# CONFIG_DRM_NWL_MIPI_DSI is not set -# CONFIG_DRM_NXP_PTN3460 is not set -# CONFIG_DRM_OMAP is not set -# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set -# CONFIG_DRM_PANEL_ARM_VERSATILE is not set -# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set -# CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set -# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set -# CONFIG_DRM_PANEL_DSI_CM is not set -# CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set -# CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set -# CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set -# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set -# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set -# CONFIG_DRM_PANEL_ILITEK_ILI9806E is not set -# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set -# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set -# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set -# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set -# CONFIG_DRM_PANEL_KHADAS_TS050 is not set -# CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set -# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set -# CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set -# CONFIG_DRM_PANEL_LG_LB035Q02 is not set -# CONFIG_DRM_PANEL_LG_LG4573 is not set -# CONFIG_DRM_PANEL_LVDS is not set -# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set -# CONFIG_DRM_PANEL_MIPI_DBI is not set -# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set -# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set -# CONFIG_DRM_PANEL_NOVATEK_NT36672A is not set -# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set -# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set -# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set -# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set -# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set -# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set -# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set -# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set -# CONFIG_DRM_PANEL_ROCKTECH_JH057N00900 is not set -# CONFIG_DRM_PANEL_RONBO_RB070D30 is not set -# CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 is not set -# CONFIG_DRM_PANEL_SAMSUNG_DB7430 is not set -# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set -# CONFIG_DRM_PANEL_SAMSUNG_SOFEF00 is not set -# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set -# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set -# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set -# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set -# CONFIG_DRM_PANEL_SIMPLE is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set -# CONFIG_DRM_PANEL_SONY_ACX424AKP is not set -# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set -# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set -# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set -# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set -# CONFIG_DRM_PANEL_TPO_TPG110 is not set -# CONFIG_DRM_PANEL_TPO_Y17P is not set -# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set -# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set -# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set -# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set -# CONFIG_DRM_PANFROST is not set -# CONFIG_DRM_PARADE_PS8622 is not set -# CONFIG_DRM_PARADE_PS8640 is not set -# CONFIG_DRM_PL111 is not set -# CONFIG_DRM_QXL is not set -# CONFIG_DRM_RADEON is not set -# CONFIG_DRM_RADEON_USERPTR is not set -# CONFIG_DRM_RCAR_DW_HDMI is not set -# CONFIG_DRM_RCAR_LVDS is not set -# CONFIG_DRM_RCAR_USE_LVDS is not set -# CONFIG_DRM_ROCKCHIP is not set -# CONFIG_DRM_SII902X is not set -# CONFIG_DRM_SII9234 is not set -# CONFIG_DRM_SIL_SII8620 is not set -# CONFIG_DRM_SIMPLEDRM is not set -# CONFIG_DRM_SIMPLE_BRIDGE is not set -# CONFIG_DRM_STI is not set -# CONFIG_DRM_STM is not set -# CONFIG_DRM_SUN4I is not set -# CONFIG_DRM_THINE_THC63LVD1024 is not set -# CONFIG_DRM_TIDSS is not set -# CONFIG_DRM_TILCDC is not set -# CONFIG_DRM_TINYDRM is not set -# CONFIG_DRM_TI_SN65DSI83 is not set -# CONFIG_DRM_TI_SN65DSI86 is not set -# CONFIG_DRM_TI_TFP410 is not set -# CONFIG_DRM_TI_TPD12S015 is not set -# CONFIG_DRM_TOSHIBA_TC358762 is not set -# CONFIG_DRM_TOSHIBA_TC358764 is not set -# CONFIG_DRM_TOSHIBA_TC358767 is not set -# CONFIG_DRM_TOSHIBA_TC358768 is not set -# CONFIG_DRM_TOSHIBA_TC358775 is not set -# CONFIG_DRM_TVE200 is not set -# CONFIG_DRM_UDL is not set -# CONFIG_DRM_VBOXVIDEO is not set -# CONFIG_DRM_VC4_HDMI_CEC is not set -# CONFIG_DRM_VGEM is not set -# CONFIG_DRM_VIRTIO_GPU is not set -# CONFIG_DRM_VKMS is not set -# CONFIG_DRM_VMWGFX is not set -# CONFIG_DRM_XEN is not set -# CONFIG_DRM_XEN_FRONTEND is not set -# CONFIG_DS1682 is not set -# CONFIG_DS1803 is not set -# CONFIG_DS4424 is not set -# CONFIG_DST_CACHE is not set -# CONFIG_DTLK is not set -# CONFIG_DUMMY is not set -CONFIG_DUMMY_CONSOLE_COLUMNS=80 -CONFIG_DUMMY_CONSOLE_ROWS=25 -# CONFIG_DUMMY_IRQ is not set -# CONFIG_DVB_A8293 is not set -# CONFIG_DVB_AF9013 is not set -# CONFIG_DVB_AF9033 is not set -# CONFIG_DVB_AS102 is not set -# CONFIG_DVB_ASCOT2E is not set -# CONFIG_DVB_ATBM8830 is not set -# CONFIG_DVB_AU8522_DTV is not set -# CONFIG_DVB_AU8522_V4L is not set -# CONFIG_DVB_B2C2_FLEXCOP_PCI is not set -# CONFIG_DVB_B2C2_FLEXCOP_USB is not set -# CONFIG_DVB_BCM3510 is not set -# CONFIG_DVB_BUDGET_CORE is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DVB_CX22700 is not set -# CONFIG_DVB_CX22702 is not set -# CONFIG_DVB_CX24110 is not set -# CONFIG_DVB_CX24116 is not set -# CONFIG_DVB_CX24117 is not set -# CONFIG_DVB_CX24120 is not set -# CONFIG_DVB_CX24123 is not set -# CONFIG_DVB_CXD2099 is not set -# CONFIG_DVB_CXD2820R is not set -# CONFIG_DVB_CXD2841ER is not set -# CONFIG_DVB_CXD2880 is not set -# CONFIG_DVB_DDBRIDGE is not set -# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set -# CONFIG_DVB_DIB3000MB is not set -# CONFIG_DVB_DIB3000MC is not set -# CONFIG_DVB_DIB7000M is not set -# CONFIG_DVB_DIB7000P is not set -# CONFIG_DVB_DIB8000 is not set -# CONFIG_DVB_DIB9000 is not set -# CONFIG_DVB_DRX39XYJ is not set -# CONFIG_DVB_DRXD is not set -# CONFIG_DVB_DRXK is not set -# CONFIG_DVB_DS3000 is not set -# CONFIG_DVB_DUMMY_FE is not set -# CONFIG_DVB_DYNAMIC_MINORS is not set -# CONFIG_DVB_EC100 is not set -# CONFIG_DVB_FIREDTV is not set -# CONFIG_DVB_HELENE is not set -# CONFIG_DVB_HORUS3A is not set -# CONFIG_DVB_ISL6405 is not set -# CONFIG_DVB_ISL6421 is not set -# CONFIG_DVB_ISL6423 is not set -# CONFIG_DVB_IX2505V is not set -# CONFIG_DVB_L64781 is not set -# CONFIG_DVB_LG2160 is not set -# CONFIG_DVB_LGDT3305 is not set -# CONFIG_DVB_LGDT3306A is not set -# CONFIG_DVB_LGDT330X is not set -# CONFIG_DVB_LGS8GL5 is not set -# CONFIG_DVB_LGS8GXX is not set -# CONFIG_DVB_LNBH25 is not set -# CONFIG_DVB_LNBH29 is not set -# CONFIG_DVB_LNBP21 is not set -# CONFIG_DVB_LNBP22 is not set -# CONFIG_DVB_M88DS3103 is not set -# CONFIG_DVB_M88RS2000 is not set -CONFIG_DVB_MAX_ADAPTERS=16 -# CONFIG_DVB_MB86A16 is not set -# CONFIG_DVB_MB86A20S is not set -# CONFIG_DVB_MMAP is not set -# CONFIG_DVB_MN88443X is not set -# CONFIG_DVB_MN88472 is not set -# CONFIG_DVB_MN88473 is not set -# CONFIG_DVB_MT312 is not set -# CONFIG_DVB_MT352 is not set -# CONFIG_DVB_MXL5XX is not set -# CONFIG_DVB_MXL692 is not set -# CONFIG_DVB_NET is not set -# CONFIG_DVB_NETUP_UNIDVB is not set -# CONFIG_DVB_NGENE is not set -# CONFIG_DVB_NXT200X is not set -# CONFIG_DVB_NXT6000 is not set -# CONFIG_DVB_OR51132 is not set -# CONFIG_DVB_OR51211 is not set -# CONFIG_DVB_PLATFORM_DRIVERS is not set -# CONFIG_DVB_PLL is not set -# CONFIG_DVB_PLUTO2 is not set -# CONFIG_DVB_PT1 is not set -# CONFIG_DVB_PT3 is not set -# CONFIG_DVB_RTL2830 is not set -# CONFIG_DVB_RTL2832 is not set -# CONFIG_DVB_RTL2832_SDR is not set -# CONFIG_DVB_S5H1409 is not set -# CONFIG_DVB_S5H1411 is not set -# CONFIG_DVB_S5H1420 is not set -# CONFIG_DVB_S5H1432 is not set -# CONFIG_DVB_S921 is not set -# CONFIG_DVB_SI2165 is not set -# CONFIG_DVB_SI2168 is not set -# CONFIG_DVB_SI21XX is not set -# CONFIG_DVB_SP2 is not set -# CONFIG_DVB_SP8870 is not set -# CONFIG_DVB_SP887X is not set -# CONFIG_DVB_STB0899 is not set -# CONFIG_DVB_STB6000 is not set -# CONFIG_DVB_STB6100 is not set -# CONFIG_DVB_STV0288 is not set -# CONFIG_DVB_STV0297 is not set -# CONFIG_DVB_STV0299 is not set -# CONFIG_DVB_STV0367 is not set -# CONFIG_DVB_STV0900 is not set -# CONFIG_DVB_STV090x is not set -# CONFIG_DVB_STV0910 is not set -# CONFIG_DVB_STV6110 is not set -# CONFIG_DVB_STV6110x is not set -# CONFIG_DVB_STV6111 is not set -# CONFIG_DVB_TC90522 is not set -# CONFIG_DVB_TDA10021 is not set -# CONFIG_DVB_TDA10023 is not set -# CONFIG_DVB_TDA10048 is not set -# CONFIG_DVB_TDA1004X is not set -# CONFIG_DVB_TDA10071 is not set -# CONFIG_DVB_TDA10086 is not set -# CONFIG_DVB_TDA18271C2DD is not set -# CONFIG_DVB_TDA665x is not set -# CONFIG_DVB_TDA8083 is not set -# CONFIG_DVB_TDA8261 is not set -# CONFIG_DVB_TDA826X is not set -# CONFIG_DVB_TEST_DRIVERS is not set -# CONFIG_DVB_TS2020 is not set -# CONFIG_DVB_TTUSB_BUDGET is not set -# CONFIG_DVB_TTUSB_DEC is not set -# CONFIG_DVB_TUA6100 is not set -# CONFIG_DVB_TUNER_CX24113 is not set -# CONFIG_DVB_TUNER_DIB0070 is not set -# CONFIG_DVB_TUNER_DIB0090 is not set -# CONFIG_DVB_TUNER_ITD1000 is not set -# CONFIG_DVB_ULE_DEBUG is not set -# CONFIG_DVB_USB is not set -# CONFIG_DVB_USB_V2 is not set -# CONFIG_DVB_VES1820 is not set -# CONFIG_DVB_VES1X93 is not set -# CONFIG_DVB_ZD1301_DEMOD is not set -# CONFIG_DVB_ZL10036 is not set -# CONFIG_DVB_ZL10039 is not set -# CONFIG_DVB_ZL10353 is not set -# CONFIG_DWC_XLGMAC is not set -# CONFIG_DWMAC_DWC_QOS_ETH is not set -# CONFIG_DWMAC_INTEL_PLAT is not set -# CONFIG_DWMAC_IPQ806X is not set -# CONFIG_DWMAC_LOONGSON is not set -# CONFIG_DWMAC_LPC18XX is not set -# CONFIG_DWMAC_MESON is not set -# CONFIG_DWMAC_ROCKCHIP is not set -# CONFIG_DWMAC_SOCFPGA is not set -# CONFIG_DWMAC_STI is not set -# CONFIG_DW_AXI_DMAC is not set -# CONFIG_DW_DMAC is not set -# CONFIG_DW_DMAC_PCI is not set -# CONFIG_DW_EDMA is not set -# CONFIG_DW_EDMA_PCIE is not set -# CONFIG_DW_WATCHDOG is not set -# CONFIG_DW_XDATA_PCIE is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_DYNAMIC_DEBUG_CORE is not set -# CONFIG_E100 is not set -# CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_E1000E_HWTS is not set -# CONFIG_EARLY_PRINTK_8250 is not set -# CONFIG_EARLY_PRINTK_USB_XDBC is not set -# CONFIG_EBC_C384_WDT is not set -# CONFIG_ECHO is not set -# CONFIG_ECRYPT_FS is not set -# CONFIG_EDAC is not set -# CONFIG_EEEPC_LAPTOP is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_EEPROM_93XX46 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_AT25 is not set -# CONFIG_EEPROM_DIGSY_MTC_CFG is not set -# CONFIG_EEPROM_EE1004 is not set -# CONFIG_EEPROM_IDT_89HPESX is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -# CONFIG_EFI is not set -CONFIG_EFI_PARTITION=y -# CONFIG_EFI_VARS_PSTORE is not set -# CONFIG_EFS_FS is not set -CONFIG_ELFCORE=y -# CONFIG_ELF_CORE is not set -# CONFIG_EMAC_ROCKCHIP is not set -CONFIG_EMBEDDED=y -# CONFIG_EM_TIMER_STI is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -# CONFIG_ENA_ETHERNET is not set -# CONFIG_ENC28J60 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_ENCRYPTED_KEYS is not set -# CONFIG_ENCX24J600 is not set -# CONFIG_ENERGY_MODEL is not set -# CONFIG_ENIC is not set -# CONFIG_ENVELOPE_DETECTOR is not set -# CONFIG_EPAPR_PARAVIRT is not set -# CONFIG_EPIC100 is not set -CONFIG_EPOLL=y -# CONFIG_EQUALIZER is not set -# CONFIG_EROFS_FS is not set -# CONFIG_ET131X is not set -CONFIG_ETHERNET=y -# CONFIG_ETHOC is not set -CONFIG_ETHTOOL_NETLINK=y -CONFIG_EVENTFD=y -# CONFIG_EVM is not set -# CONFIG_EXFAT_FS is not set -CONFIG_EXPERT=y -CONFIG_EXPORTFS=y -# CONFIG_EXPORTFS_BLOCK_OPS is not set -# CONFIG_EXT2_FS is not set -CONFIG_EXT2_FS_XATTR=y -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4_DEBUG is not set -# CONFIG_EXT4_ENCRYPTION is not set -# CONFIG_EXT4_FS is not set -# CONFIG_EXT4_FS_POSIX_ACL is not set -# CONFIG_EXT4_FS_SECURITY is not set -CONFIG_EXT4_USE_FOR_EXT2=y -# CONFIG_EXTCON is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_ARIZONA is not set -# CONFIG_EXTCON_AXP288 is not set -# CONFIG_EXTCON_FSA9480 is not set -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_INTEL_INT3496 is not set -# CONFIG_EXTCON_MAX3355 is not set -# CONFIG_EXTCON_PTN5150 is not set -# CONFIG_EXTCON_QCOM_SPMI_MISC is not set -# CONFIG_EXTCON_RT8973A is not set -# CONFIG_EXTCON_SM5502 is not set -# CONFIG_EXTCON_USBC_TUSB320 is not set -# CONFIG_EXTCON_USB_GPIO is not set -CONFIG_EXTRA_FIRMWARE="" -CONFIG_EXTRA_TARGETS="" -# CONFIG_EXYNOS_ADC is not set -# CONFIG_EXYNOS_VIDEO is not set -# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set -# CONFIG_EZX_PCAP is not set -# CONFIG_F2FS_CHECK_FS is not set -# CONFIG_F2FS_FAULT_INJECTION is not set -# CONFIG_F2FS_FS is not set -# CONFIG_F2FS_FS_COMPRESSION is not set -# CONFIG_F2FS_FS_ENCRYPTION is not set -# CONFIG_F2FS_FS_POSIX_ACL is not set -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -# CONFIG_F2FS_IOSTAT is not set -# CONFIG_F2FS_IO_TRACE is not set -CONFIG_F2FS_STAT_FS=y -# CONFIG_FAILOVER is not set -# CONFIG_FAIR_GROUP_SCHED is not set -# CONFIG_FANOTIFY is not set -# CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_FAT_DEFAULT_UTF8 is not set -# CONFIG_FAT_FS is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_FB is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_ARC is not set -# CONFIG_FB_ARK is not set -# CONFIG_FB_ARMCLCD is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_ATMEL is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_AUO_K190X is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_BIG_ENDIAN is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -# CONFIG_FB_BOTH_ENDIAN is not set -# CONFIG_FB_BROADSHEET is not set -# CONFIG_FB_CARMINE is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_DA8XX is not set -# CONFIG_FB_DDC is not set -# CONFIG_FB_FLEX is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_FSL_DIU is not set -# CONFIG_FB_GEODE is not set -# CONFIG_FB_GOLDFISH is not set -# CONFIG_FB_HGA is not set -# CONFIG_FB_I740 is not set -# CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_IMX is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_LE80578 is not set -# CONFIG_FB_LITTLE_ENDIAN is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_MXS is not set -# CONFIG_FB_N411 is not set -# CONFIG_FB_NEOMAGIC is not set -CONFIG_FB_NOTIFY=y -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_OF is not set -# CONFIG_FB_OMAP2 is not set -# CONFIG_FB_OPENCORES is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_PM3 is not set -# CONFIG_FB_PS3 is not set -# CONFIG_FB_PXA is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIMPLE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_SM712 is not set -# CONFIG_FB_SM750 is not set -# CONFIG_FB_SMSCUFX is not set -# CONFIG_FB_SSD1307 is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_TFT is not set -# CONFIG_FB_TFT_AGM1264K_FL is not set -# CONFIG_FB_TFT_BD663474 is not set -# CONFIG_FB_TFT_FBTFT_DEVICE is not set -# CONFIG_FB_TFT_HX8340BN is not set -# CONFIG_FB_TFT_HX8347D is not set -# CONFIG_FB_TFT_HX8353D is not set -# CONFIG_FB_TFT_HX8357D is not set -# CONFIG_FB_TFT_ILI9163 is not set -# CONFIG_FB_TFT_ILI9320 is not set -# CONFIG_FB_TFT_ILI9325 is not set -# CONFIG_FB_TFT_ILI9340 is not set -# CONFIG_FB_TFT_ILI9341 is not set -# CONFIG_FB_TFT_ILI9481 is not set -# CONFIG_FB_TFT_ILI9486 is not set -# CONFIG_FB_TFT_PCD8544 is not set -# CONFIG_FB_TFT_RA8875 is not set -# CONFIG_FB_TFT_S6D02A1 is not set -# CONFIG_FB_TFT_S6D1121 is not set -# CONFIG_FB_TFT_SEPS525 is not set -# CONFIG_FB_TFT_SH1106 is not set -# CONFIG_FB_TFT_SSD1289 is not set -# CONFIG_FB_TFT_SSD1305 is not set -# CONFIG_FB_TFT_SSD1306 is not set -# CONFIG_FB_TFT_SSD1325 is not set -# CONFIG_FB_TFT_SSD1331 is not set -# CONFIG_FB_TFT_SSD1351 is not set -# CONFIG_FB_TFT_ST7735R is not set -# CONFIG_FB_TFT_ST7789V is not set -# CONFIG_FB_TFT_TINYLCD is not set -# CONFIG_FB_TFT_TLS8204 is not set -# CONFIG_FB_TFT_UC1611 is not set -# CONFIG_FB_TFT_UC1701 is not set -# CONFIG_FB_TFT_UPD161704 is not set -# CONFIG_FB_TFT_WATTEROTT is not set -# CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_TMIO is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_UDL is not set -# CONFIG_FB_UVESA is not set -# CONFIG_FB_VGA16 is not set -# CONFIG_FB_VIA is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_VT8623 is not set -# CONFIG_FB_XGI is not set -# CONFIG_FCOE is not set -# CONFIG_FCOE_FNIC is not set -# CONFIG_FDDI is not set -# CONFIG_FEALNX is not set -# CONFIG_FENCE_TRACE is not set -# CONFIG_FHANDLE is not set -CONFIG_FIB_RULES=y -# CONFIG_FIELDBUS_DEV is not set -CONFIG_FILE_LOCKING=y -# CONFIG_FIND_BIT_BENCHMARK is not set -# CONFIG_FIREWIRE is not set -# CONFIG_FIREWIRE_NOSY is not set -# CONFIG_FIREWIRE_SERIAL is not set -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FIRMWARE_IN_KERNEL is not set -# CONFIG_FIRMWARE_MEMMAP is not set -# CONFIG_FIXED_PHY is not set -CONFIG_FLATMEM=y -CONFIG_FLATMEM_MANUAL=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_FM10K is not set -# CONFIG_FMC is not set -# CONFIG_FONTS is not set -# CONFIG_FONT_6x8 is not set -# CONFIG_FONT_TER16x32 is not set -# CONFIG_FORCEDETH is not set -CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_FORTIFY_SOURCE=y -# CONFIG_FPGA is not set -# CONFIG_FRAMEBUFFER_CONSOLE is not set -# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set -# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set -# CONFIG_FRAME_POINTER is not set -# CONFIG_FREEZER is not set -# CONFIG_FRONTSWAP is not set -# CONFIG_FSCACHE is not set -# CONFIG_FSI is not set -# CONFIG_FSL_DPAA2_SWITCH is not set -# CONFIG_FSL_EDMA is not set -# CONFIG_FSL_ENETC is not set -# CONFIG_FSL_ENETC_IERB is not set -# CONFIG_FSL_ENETC_MDIO is not set -# CONFIG_FSL_ENETC_VF is not set -# CONFIG_FSL_ERRATUM_A008585 is not set -# CONFIG_FSL_MC_BUS is not set -# CONFIG_FSL_PQ_MDIO is not set -# CONFIG_FSL_QDMA is not set -# CONFIG_FSL_RCPM is not set -# CONFIG_FSL_XGMAC_MDIO is not set -CONFIG_FSNOTIFY=y -# CONFIG_FS_DAX is not set -# CONFIG_FS_ENCRYPTION is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_FS_VERITY is not set -# CONFIG_FTGMAC100 is not set -# CONFIG_FTL is not set -# CONFIG_FTMAC100 is not set -# CONFIG_FTRACE is not set -# CONFIG_FTRACE_RECORD_RECURSION is not set -# CONFIG_FTRACE_STARTUP_TEST is not set -# CONFIG_FTR_FIXUP_SELFTEST is not set -# CONFIG_FTWDT010_WATCHDOG is not set -# CONFIG_FUJITSU_ERRATUM_010001 is not set -# CONFIG_FUJITSU_ES is not set -# CONFIG_FUJITSU_LAPTOP is not set -# CONFIG_FUJITSU_TABLET is not set -# CONFIG_FUNCTION_ERROR_INJECTION is not set -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_FUSE_FS is not set -# CONFIG_FUSION is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set -# CONFIG_FUSION_SPI is not set -CONFIG_FUTEX=y -CONFIG_FUTEX_PI=y -# CONFIG_FW_CFG_SYSFS is not set -CONFIG_FW_LOADER=y -# CONFIG_FW_LOADER_COMPRESS is not set -CONFIG_FW_LOADER_USER_HELPER=y -CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y -# CONFIG_FXAS21002C is not set -# CONFIG_FXLS8962AF_I2C is not set -# CONFIG_FXLS8962AF_SPI is not set -# CONFIG_FXOS8700_I2C is not set -# CONFIG_FXOS8700_SPI is not set -CONFIG_GACT_PROB=y -# CONFIG_GADGET_UAC1 is not set -# CONFIG_GAMEPORT is not set -# CONFIG_GATEWORKS_GW16083 is not set -# CONFIG_GCC_PLUGINS is not set -# CONFIG_GCOV is not set -# CONFIG_GCOV_KERNEL is not set -# CONFIG_GDB_SCRIPTS is not set -# CONFIG_GEMINI_ETHERNET is not set -# CONFIG_GENERIC_ADC_BATTERY is not set -# CONFIG_GENERIC_ADC_THERMAL is not set -CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_CPU_DEVICES is not set -CONFIG_GENERIC_HWEIGHT=y -# CONFIG_GENERIC_IRQ_DEBUGFS is not set -CONFIG_GENERIC_IRQ_IPI=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_NET_UTILS=y -# CONFIG_GENERIC_PHY is not set -CONFIG_GENERIC_PTDUMP=y -CONFIG_GENERIC_VDSO_TIME_NS=y -# CONFIG_GENEVE is not set -# CONFIG_GENWQE is not set -# CONFIG_GFS2_FS is not set -# CONFIG_GIGASET_CAPI is not set -# CONFIG_GIGASET_DEBUG is not set -# CONFIG_GIGASET_DUMMYLL is not set -# CONFIG_GLOB_SELFTEST is not set -# CONFIG_GNSS is not set -# CONFIG_GOLDFISH is not set -# CONFIG_GOOGLE_FIRMWARE is not set -# CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT is not set -# CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY is not set -# CONFIG_GOOGLE_SMI is not set -# CONFIG_GP2AP002 is not set -# CONFIG_GP2AP020A00F is not set -# CONFIG_GPD_POCKET_FAN is not set -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_FASTPATH_LIMIT=512 -# CONFIG_GPIO_104_DIO_48E is not set -# CONFIG_GPIO_104_IDIO_16 is not set -# CONFIG_GPIO_104_IDI_48 is not set -# CONFIG_GPIO_74X164 is not set -# CONFIG_GPIO_74XX_MMIO is not set -# CONFIG_GPIO_ADNP is not set -# CONFIG_GPIO_ADP5588 is not set -# CONFIG_GPIO_AGGREGATOR is not set -# CONFIG_GPIO_ALTERA is not set -# CONFIG_GPIO_AMD8111 is not set -# CONFIG_GPIO_AMDPT is not set -# CONFIG_GPIO_AMD_FCH is not set -# CONFIG_GPIO_BCM_KONA is not set -# CONFIG_GPIO_BT8XX is not set -# CONFIG_GPIO_CADENCE is not set -# CONFIG_GPIO_CASCADE is not set -# CONFIG_GPIO_CDEV is not set -# CONFIG_GPIO_CDEV_V1 is not set -# CONFIG_GPIO_CS5535 is not set -# CONFIG_GPIO_DWAPB is not set -# CONFIG_GPIO_EM is not set -# CONFIG_GPIO_EXAR is not set -# CONFIG_GPIO_F7188X is not set -# CONFIG_GPIO_FTGPIO010 is not set -# CONFIG_GPIO_GENERIC_PLATFORM is not set -# CONFIG_GPIO_GPIO_MM is not set -# CONFIG_GPIO_GRGPIO is not set -# CONFIG_GPIO_GW_PLD is not set -# CONFIG_GPIO_HLWD is not set -# CONFIG_GPIO_ICH is not set -# CONFIG_GPIO_IT87 is not set -# CONFIG_GPIO_LOGICVC is not set -# CONFIG_GPIO_LYNXPOINT is not set -# CONFIG_GPIO_MAX3191X is not set -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_MB86S7X is not set -# CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_ML_IOH is not set -# CONFIG_GPIO_MOCKUP is not set -# CONFIG_GPIO_MPC8XXX is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCA953X_IRQ is not set -# CONFIG_GPIO_PCA9570 is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_PCH is not set -# CONFIG_GPIO_PCIE_IDIO_24 is not set -# CONFIG_GPIO_PCI_IDIO_16 is not set -# CONFIG_GPIO_PISOSR is not set -# CONFIG_GPIO_PL061 is not set -# CONFIG_GPIO_PWM is not set -# CONFIG_GPIO_RCAR is not set -# CONFIG_GPIO_RDC321X is not set -# CONFIG_GPIO_SAMA5D2_PIOBU is not set -# CONFIG_GPIO_SCH is not set -# CONFIG_GPIO_SCH311X is not set -# CONFIG_GPIO_SIFIVE is not set -# CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_SYSCON is not set -CONFIG_GPIO_SYSFS=y -# CONFIG_GPIO_TPIC2810 is not set -# CONFIG_GPIO_TS4900 is not set -# CONFIG_GPIO_TS5500 is not set -# CONFIG_GPIO_VIRTIO is not set -# CONFIG_GPIO_VX855 is not set -# CONFIG_GPIO_WATCHDOG is not set -# CONFIG_GPIO_WINBOND is not set -# CONFIG_GPIO_WS16C48 is not set -# CONFIG_GPIO_XGENE is not set -# CONFIG_GPIO_XILINX is not set -# CONFIG_GPIO_XRA1403 is not set -# CONFIG_GPIO_ZEVIO is not set -# CONFIG_GPIO_ZX is not set -# CONFIG_GREENASIA_FF is not set -# CONFIG_GREYBUS is not set -# CONFIG_GS_FPGABOOT is not set -# CONFIG_GTP is not set -# CONFIG_GUP_BENCHMARK is not set -# CONFIG_GUP_TEST is not set -# CONFIG_GVE is not set -# CONFIG_HABANA_AI is not set -# CONFIG_HAMACHI is not set -# CONFIG_HAMRADIO is not set -# CONFIG_HAPPYMEAL is not set -CONFIG_HARDENED_USERCOPY=y -# CONFIG_HARDENED_USERCOPY_FALLBACK is not set -# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set -CONFIG_HARDEN_BRANCH_HISTORY=y -CONFIG_HARDEN_EL2_VECTORS=y -# CONFIG_HARDLOCKUP_DETECTOR is not set -# CONFIG_HAVE_ARM_ARCH_TIMER is not set -# CONFIG_HCALL_STATS is not set -# CONFIG_HDC100X is not set -# CONFIG_HDC2010 is not set -# CONFIG_HDLC is not set -# CONFIG_HDLC_CISCO is not set -# CONFIG_HDLC_FR is not set -# CONFIG_HDLC_PPP is not set -# CONFIG_HDLC_RAW is not set -# CONFIG_HDLC_RAW_ETH is not set -# CONFIG_HDMI_LPE_AUDIO is not set -# CONFIG_HDQ_MASTER_OMAP is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_HEADERS_INSTALL is not set -# CONFIG_HEADER_TEST is not set -# CONFIG_HERMES is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_HFSPLUS_FS_POSIX_ACL is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFS_FS_POSIX_ACL is not set -# CONFIG_HI6421V600_IRQ is not set -# CONFIG_HI8435 is not set -# CONFIG_HIBERNATION is not set -# CONFIG_HID is not set -# CONFIG_HIDRAW is not set -# CONFIG_HID_A4TECH is not set -# CONFIG_HID_ACCUTOUCH is not set -# CONFIG_HID_ACRUX is not set -# CONFIG_HID_ACRUX_FF is not set -# CONFIG_HID_ALPS is not set -# CONFIG_HID_APPLE is not set -# CONFIG_HID_APPLEIR is not set -# CONFIG_HID_ASUS is not set -# CONFIG_HID_AUREAL is not set -# CONFIG_HID_BATTERY_STRENGTH is not set -# CONFIG_HID_BELKIN is not set -# CONFIG_HID_BETOP_FF is not set -# CONFIG_HID_BIGBEN_FF is not set -# CONFIG_HID_CHERRY is not set -# CONFIG_HID_CHICONY is not set -# CONFIG_HID_CMEDIA is not set -# CONFIG_HID_CORSAIR is not set -# CONFIG_HID_COUGAR is not set -# CONFIG_HID_CP2112 is not set -# CONFIG_HID_CREATIVE_SB0540 is not set -# CONFIG_HID_CYPRESS is not set -# CONFIG_HID_DRAGONRISE is not set -# CONFIG_HID_ELAN is not set -# CONFIG_HID_ELECOM is not set -# CONFIG_HID_ELO is not set -# CONFIG_HID_EMS_FF is not set -# CONFIG_HID_EZKEY is not set -# CONFIG_HID_FT260 is not set -# CONFIG_HID_GEMBIRD is not set -# CONFIG_HID_GENERIC is not set -# CONFIG_HID_GFRM is not set -# CONFIG_HID_GLORIOUS is not set -# CONFIG_HID_GOOGLE_HAMMER is not set -# CONFIG_HID_GREENASIA is not set -# CONFIG_HID_GT683R is not set -# CONFIG_HID_GYRATION is not set -# CONFIG_HID_HOLTEK is not set -# CONFIG_HID_ICADE is not set -# CONFIG_HID_ITE is not set -# CONFIG_HID_JABRA is not set -# CONFIG_HID_KENSINGTON is not set -# CONFIG_HID_KEYTOUCH is not set -# CONFIG_HID_KYE is not set -# CONFIG_HID_LCPOWER is not set -# CONFIG_HID_LED is not set -# CONFIG_HID_LENOVO is not set -# CONFIG_HID_LOGITECH is not set -# CONFIG_HID_LOGITECH_DJ is not set -# CONFIG_HID_LOGITECH_HIDPP is not set -# CONFIG_HID_MACALLY is not set -# CONFIG_HID_MAGICMOUSE is not set -# CONFIG_HID_MALTRON is not set -# CONFIG_HID_MAYFLASH is not set -# CONFIG_HID_MCP2221 is not set -# CONFIG_HID_MICROSOFT is not set -# CONFIG_HID_MONTEREY is not set -# CONFIG_HID_MULTITOUCH is not set -# CONFIG_HID_NTI is not set -# CONFIG_HID_NTRIG is not set -# CONFIG_HID_ORTEK is not set -# CONFIG_HID_PANTHERLORD is not set -# CONFIG_HID_PENMOUNT is not set -# CONFIG_HID_PETALYNX is not set -# CONFIG_HID_PICOLCD is not set -# CONFIG_HID_PID is not set -# CONFIG_HID_PLANTRONICS is not set -# CONFIG_HID_PLAYSTATION is not set -# CONFIG_HID_PRIMAX is not set -# CONFIG_HID_PRODIKEYS is not set -# CONFIG_HID_REDRAGON is not set -# CONFIG_HID_RETRODE is not set -# CONFIG_HID_RMI is not set -# CONFIG_HID_ROCCAT is not set -# CONFIG_HID_SAITEK is not set -# CONFIG_HID_SAMSUNG is not set -# CONFIG_HID_SEMITEK is not set -# CONFIG_HID_SENSOR_HUB is not set -# CONFIG_HID_SMARTJOYPLUS is not set -# CONFIG_HID_SONY is not set -# CONFIG_HID_SPEEDLINK is not set -# CONFIG_HID_STEAM is not set -# CONFIG_HID_STEELSERIES is not set -# CONFIG_HID_SUNPLUS is not set -# CONFIG_HID_THINGM is not set -# CONFIG_HID_THRUSTMASTER is not set -# CONFIG_HID_TIVO is not set -# CONFIG_HID_TOPSEED is not set -# CONFIG_HID_TWINHAN is not set -# CONFIG_HID_U2FZERO is not set -# CONFIG_HID_UCLOGIC is not set -# CONFIG_HID_UDRAW_PS3 is not set -# CONFIG_HID_VIEWSONIC is not set -# CONFIG_HID_VIVALDI is not set -# CONFIG_HID_WACOM is not set -# CONFIG_HID_WALTOP is not set -# CONFIG_HID_WIIMOTE is not set -# CONFIG_HID_XINMO is not set -# CONFIG_HID_ZEROPLUS is not set -# CONFIG_HID_ZYDACRON is not set -# CONFIG_HIGHMEM is not set -CONFIG_HIGH_RES_TIMERS=y -# CONFIG_HINIC is not set -# CONFIG_HIP04_ETH is not set -# CONFIG_HIPPI is not set -# CONFIG_HISILICON_ERRATUM_161010101 is not set -# CONFIG_HISILICON_ERRATUM_161600802 is not set -# CONFIG_HISI_DMA is not set -# CONFIG_HISI_FEMAC is not set -# CONFIG_HISI_HIKEY_USB is not set -# CONFIG_HIST_TRIGGERS_DEBUG is not set -# CONFIG_HIX5HD2_GMAC is not set -# CONFIG_HMC425 is not set -# CONFIG_HMC6352 is not set -# CONFIG_HNS is not set -# CONFIG_HNS3 is not set -# CONFIG_HNS_DSAF is not set -# CONFIG_HNS_ENET is not set -# CONFIG_HOSTAP is not set -# CONFIG_HOSTAP_CS is not set -# CONFIG_HOSTAP_PCI is not set -# CONFIG_HOSTAP_PLX is not set -# CONFIG_HOTPLUG_CPU is not set -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_IBM is not set -# CONFIG_HOTPLUG_PCI_SHPC is not set -# CONFIG_HP03 is not set -# CONFIG_HP100 is not set -# CONFIG_HP206C is not set -CONFIG_HPET_MMAP_DEFAULT=y -# CONFIG_HPFS_FS is not set -# CONFIG_HP_ILO is not set -# CONFIG_HP_WIRELESS is not set -# CONFIG_HSA_AMD is not set -# CONFIG_HSI is not set -# CONFIG_HSR is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_I2CPLD is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTS221 is not set -# CONFIG_HTU21 is not set -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_HVC_DCC is not set -# CONFIG_HVC_UDBG is not set -# CONFIG_HWLAT_TRACER is not set -# CONFIG_HWMON is not set -# CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_HWMON_VID is not set -# CONFIG_HWSPINLOCK is not set -# CONFIG_HWSPINLOCK_OMAP is not set -CONFIG_HW_PERF_EVENTS=y -# CONFIG_HW_RANDOM is not set -# CONFIG_HW_RANDOM_AMD is not set -# CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set -# CONFIG_HW_RANDOM_ATMEL is not set -# CONFIG_HW_RANDOM_BA431 is not set -# CONFIG_HW_RANDOM_BCM2835 is not set -# CONFIG_HW_RANDOM_CAVIUM is not set -# CONFIG_HW_RANDOM_CCTRNG is not set -# CONFIG_HW_RANDOM_EXYNOS is not set -# CONFIG_HW_RANDOM_GEODE is not set -# CONFIG_HW_RANDOM_INTEL is not set -# CONFIG_HW_RANDOM_IPROC_RNG200 is not set -# CONFIG_HW_RANDOM_MTK is not set -# CONFIG_HW_RANDOM_OMAP is not set -# CONFIG_HW_RANDOM_OMAP3_ROM is not set -# CONFIG_HW_RANDOM_PPC4XX is not set -# CONFIG_HW_RANDOM_TIMERIOMEM is not set -CONFIG_HW_RANDOM_TPM=y -# CONFIG_HW_RANDOM_VIA is not set -# CONFIG_HW_RANDOM_VIRTIO is not set -# CONFIG_HW_RANDOM_XIPHERA is not set -# CONFIG_HX711 is not set -# CONFIG_HYPERV is not set -# CONFIG_HYPERV_TSCPAGE is not set -# CONFIG_HYSDN is not set -CONFIG_HZ=100 -CONFIG_HZ_100=y -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -# CONFIG_HZ_128 is not set -# CONFIG_HZ_200 is not set -# CONFIG_HZ_24 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -# CONFIG_HZ_300 is not set -# CONFIG_HZ_48 is not set -# CONFIG_HZ_500 is not set -# CONFIG_HZ_PERIODIC is not set -# CONFIG_I2C is not set -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCA is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -# CONFIG_I2C_AU1550 is not set -# CONFIG_I2C_BCM2835 is not set -# CONFIG_I2C_BCM_IPROC is not set -# CONFIG_I2C_BRCMSTB is not set -# CONFIG_I2C_CADENCE is not set -# CONFIG_I2C_CBUS_GPIO is not set -# CONFIG_I2C_CHARDEV is not set -# CONFIG_I2C_COMPAT is not set -# CONFIG_I2C_CP2615 is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEMUX_PINCTRL is not set -# CONFIG_I2C_DESIGNWARE_PCI is not set -# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -# CONFIG_I2C_DESIGNWARE_SLAVE is not set -# CONFIG_I2C_DIOLAN_U2C is not set -# CONFIG_I2C_EG20T is not set -# CONFIG_I2C_ELEKTOR is not set -# CONFIG_I2C_EMEV2 is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set -# CONFIG_I2C_HELPER_AUTO is not set -# CONFIG_I2C_HID is not set -# CONFIG_I2C_HID_OF is not set -# CONFIG_I2C_HID_OF_GOODIX is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_IBM_IIC is not set -# CONFIG_I2C_IMG is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_ISMT is not set -# CONFIG_I2C_JZ4780 is not set -# CONFIG_I2C_MLXCPLD is not set -# CONFIG_I2C_MPC is not set -# CONFIG_I2C_MT65XX is not set -# CONFIG_I2C_MUX is not set -# CONFIG_I2C_MUX_GPIO is not set -# CONFIG_I2C_MUX_GPMUX is not set -# CONFIG_I2C_MUX_LTC4306 is not set -# CONFIG_I2C_MUX_MLXCPLD is not set -# CONFIG_I2C_MUX_PCA9541 is not set -# CONFIG_I2C_MUX_PCA954x is not set -# CONFIG_I2C_MUX_PINCTRL is not set -# CONFIG_I2C_MUX_REG is not set -# CONFIG_I2C_MV64XXX is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_NOMADIK is not set -# CONFIG_I2C_NVIDIA_GPU is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_OCTEON is not set -# CONFIG_I2C_PARPORT is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PCA_ISA is not set -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_PXA_PCI is not set -# CONFIG_I2C_PXA_SLAVE is not set -# CONFIG_I2C_RCAR is not set -# CONFIG_I2C_RK3X is not set -# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -# CONFIG_I2C_S3C2410 is not set -# CONFIG_I2C_SCMI is not set -# CONFIG_I2C_SH_MOBILE is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_SLAVE is not set -# CONFIG_I2C_SLAVE_EEPROM is not set -# CONFIG_I2C_SMBUS is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_THUNDERX is not set -# CONFIG_I2C_TINY_USB is not set -# CONFIG_I2C_VERSATILE is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VIRTIO is not set -# CONFIG_I2C_XILINX is not set -# CONFIG_I3C is not set -# CONFIG_I40E is not set -# CONFIG_I40EVF is not set -# CONFIG_I6300ESB_WDT is not set -# CONFIG_I82092 is not set -# CONFIG_I82365 is not set -# CONFIG_IAQCORE is not set -# CONFIG_IBM_ASM is not set -# CONFIG_IBM_EMAC_DEBUG is not set -# CONFIG_IBM_EMAC_EMAC4 is not set -# CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_EMAC_MAL_COMMON_ERR is not set -# CONFIG_IBM_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_EMAC_RGMII is not set -# CONFIG_IBM_EMAC_TAH is not set -# CONFIG_IBM_EMAC_ZMII is not set -# CONFIG_ICE is not set -# CONFIG_ICP10100 is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ICST is not set -# CONFIG_IDE is not set -# CONFIG_IDEAPAD_LAPTOP is not set -# CONFIG_IDE_GD is not set -# CONFIG_IDE_PROC_FS is not set -# CONFIG_IDE_TASK_IOCTL is not set -# CONFIG_IDLE_PAGE_TRACKING is not set -# CONFIG_IEEE802154 is not set -# CONFIG_IEEE802154_ADF7242 is not set -# CONFIG_IEEE802154_ATUSB is not set -# CONFIG_IEEE802154_CA8210 is not set -# CONFIG_IEEE802154_HWSIM is not set -# CONFIG_IEEE802154_MCR20A is not set -# CONFIG_IFB is not set -# CONFIG_IGB is not set -# CONFIG_IGBVF is not set -# CONFIG_IGC is not set -# CONFIG_IIO is not set -# CONFIG_IIO_BUFFER is not set -# CONFIG_IIO_BUFFER_CB is not set -# CONFIG_IIO_BUFFER_DMA is not set -# CONFIG_IIO_BUFFER_DMAENGINE is not set -# CONFIG_IIO_BUFFER_HDC2010 is not set -# CONFIG_IIO_BUFFER_HW_CONSUMER is not set -# CONFIG_IIO_CONFIGFS is not set -CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 -# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set -# CONFIG_IIO_INTERRUPT_TRIGGER is not set -# CONFIG_IIO_MUX is not set -# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set -# CONFIG_IIO_RESCALE is not set -# CONFIG_IIO_SIMPLE_DUMMY is not set -# CONFIG_IIO_SSP_SENSORHUB is not set -# CONFIG_IIO_ST_ACCEL_3AXIS is not set -# CONFIG_IIO_ST_GYRO_3AXIS is not set -# CONFIG_IIO_ST_LSM6DSX is not set -# CONFIG_IIO_ST_LSM9DS0 is not set -# CONFIG_IIO_ST_MAGN_3AXIS is not set -# CONFIG_IIO_ST_PRESS is not set -# CONFIG_IIO_SW_DEVICE is not set -# CONFIG_IIO_SW_TRIGGER is not set -# CONFIG_IIO_SYSFS_TRIGGER is not set -# CONFIG_IIO_TRIGGER is not set -# CONFIG_IIO_TRIGGERED_EVENT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_IKCONFIG_PROC is not set -# CONFIG_IKHEADERS is not set -# CONFIG_IMA is not set -# CONFIG_IMGPDC_WDT is not set -# CONFIG_IMG_MDC_DMA is not set -# CONFIG_IMX7D_ADC is not set -# CONFIG_IMX_IPUV3_CORE is not set -# CONFIG_IMX_THERMAL is not set -# CONFIG_INA2XX_ADC is not set -# CONFIG_INDIRECT_PIO is not set -CONFIG_INET=y -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_ESPINTCP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_DIAG is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_ESPINTCP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_LRO is not set -CONFIG_INET_TABLE_PERTURB_ORDER=16 -# CONFIG_INET_TCP_DIAG is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_UDP_DIAG is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INFINIBAND is not set -# CONFIG_INFTL is not set -# CONFIG_INGENIC_ADC is not set -# CONFIG_INGENIC_CGU_JZ4725B is not set -# CONFIG_INGENIC_CGU_JZ4740 is not set -# CONFIG_INGENIC_CGU_JZ4760 is not set -# CONFIG_INGENIC_CGU_JZ4770 is not set -# CONFIG_INGENIC_CGU_JZ4780 is not set -# CONFIG_INGENIC_CGU_X1000 is not set -# CONFIG_INGENIC_CGU_X1830 is not set -# CONFIG_INGENIC_OST is not set -# CONFIG_INGENIC_SYSOST is not set -# CONFIG_INGENIC_TCU_CLK is not set -# CONFIG_INGENIC_TCU_IRQ is not set -# CONFIG_INGENIC_TIMER is not set -CONFIG_INIT_ENV_ARG_LIMIT=32 -# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set -# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set -# CONFIG_INIT_STACK_ALL_PATTERN is not set -# CONFIG_INIT_STACK_ALL_ZERO is not set -CONFIG_INIT_STACK_NONE=y -CONFIG_INOTIFY_USER=y -# CONFIG_INPUT is not set -# CONFIG_INPUT_AD714X is not set -# CONFIG_INPUT_ADXL34X is not set -# CONFIG_INPUT_APANEL is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_ATLAS_BTNS is not set -# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -# CONFIG_INPUT_AXP20X_PEK is not set -# CONFIG_INPUT_BMA150 is not set -# CONFIG_INPUT_CM109 is not set -# CONFIG_INPUT_CMA3000 is not set -# CONFIG_INPUT_DA7280_HAPTICS is not set -# CONFIG_INPUT_DRV260X_HAPTICS is not set -# CONFIG_INPUT_DRV2665_HAPTICS is not set -# CONFIG_INPUT_DRV2667_HAPTICS is not set -# CONFIG_INPUT_E3X0_BUTTON is not set -# CONFIG_INPUT_EVBUG is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_GP2A is not set -# CONFIG_INPUT_GPIO_BEEPER is not set -# CONFIG_INPUT_GPIO_DECODER is not set -# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -# CONFIG_INPUT_GPIO_TILT_POLLED is not set -# CONFIG_INPUT_GPIO_VIBRA is not set -# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set -# CONFIG_INPUT_IMS_PCU is not set -# CONFIG_INPUT_IQS269A is not set -# CONFIG_INPUT_IQS626A is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_KXTJ9 is not set -# CONFIG_INPUT_LEDS is not set -# CONFIG_INPUT_MATRIXKMAP is not set -# CONFIG_INPUT_MAX8997_HAPTIC is not set -CONFIG_INPUT_MISC=y -# CONFIG_INPUT_MMA8450 is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_MPU3050 is not set -# CONFIG_INPUT_MSM_VIBRATOR is not set -# CONFIG_INPUT_PALMAS_PWRBUTTON is not set -# CONFIG_INPUT_PCF8574 is not set -# CONFIG_INPUT_PCSPKR is not set -# CONFIG_INPUT_PM8941_PWRKEY is not set -# CONFIG_INPUT_PM8XXX_VIBRATOR is not set -# CONFIG_INPUT_POLLDEV is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_PWM_BEEPER is not set -# CONFIG_INPUT_PWM_VIBRA is not set -# CONFIG_INPUT_REGULATOR_HAPTIC is not set -# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set -# CONFIG_INPUT_SPARSEKMAP is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_TPS65218_PWRBUTTON is not set -# CONFIG_INPUT_TWL4030_PWRBUTTON is not set -# CONFIG_INPUT_TWL4030_VIBRA is not set -# CONFIG_INPUT_TWL6040_VIBRA is not set -# CONFIG_INPUT_UINPUT is not set -# CONFIG_INPUT_WISTRON_BTNS is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INT340X_THERMAL is not set -# CONFIG_INTEGRITY is not set -# CONFIG_INTEGRITY_AUDIT is not set -# CONFIG_INTEGRITY_SIGNATURE is not set -# CONFIG_INTEL_ATOMISP2_LED is not set -# CONFIG_INTEL_ATOMISP2_PM is not set -# CONFIG_INTEL_CHT_INT33FE is not set -# CONFIG_INTEL_HID_EVENT is not set -# CONFIG_INTEL_IDLE is not set -# CONFIG_INTEL_IDMA64 is not set -# CONFIG_INTEL_IDXD is not set -# CONFIG_INTEL_IDXD_COMPAT is not set -# CONFIG_INTEL_INT0002_VGPIO is not set -# CONFIG_INTEL_IOATDMA is not set -# CONFIG_INTEL_ISH_HID is not set -# CONFIG_INTEL_MEI is not set -# CONFIG_INTEL_MEI_ME is not set -# CONFIG_INTEL_MEI_TXE is not set -# CONFIG_INTEL_MIC_CARD is not set -# CONFIG_INTEL_MIC_HOST is not set -# CONFIG_INTEL_MID_PTI is not set -# CONFIG_INTEL_OAKTRAIL is not set -# CONFIG_INTEL_PMC_CORE is not set -# CONFIG_INTEL_PUNIT_IPC is not set -# CONFIG_INTEL_RST is not set -# CONFIG_INTEL_SMARTCONNECT is not set -# CONFIG_INTEL_SOC_PMIC is not set -# CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set -# CONFIG_INTEL_SOC_PMIC_CHTWC is not set -# CONFIG_INTEL_TH is not set -# CONFIG_INTEL_VBTN is not set -# CONFIG_INTEL_XWAY_PHY is not set -# CONFIG_INTERCONNECT is not set -# CONFIG_INTERVAL_TREE_TEST is not set -# CONFIG_INV_ICM42600_I2C is not set -# CONFIG_INV_ICM42600_SPI is not set -# CONFIG_INV_MPU6050_I2C is not set -# CONFIG_INV_MPU6050_IIO is not set -# CONFIG_INV_MPU6050_SPI is not set -# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set -# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set -# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set -# CONFIG_IOMMU_SUPPORT is not set -# CONFIG_IONIC is not set -# CONFIG_IOSCHED_BFQ is not set -# CONFIG_IOSM is not set -CONFIG_IO_STRICT_DEVMEM=y -# CONFIG_IO_URING is not set -CONFIG_IO_WQ=y -# CONFIG_IP17XX_PHY is not set -# CONFIG_IP6_NF_FILTER is not set -# CONFIG_IP6_NF_IPTABLES is not set -# CONFIG_IP6_NF_MANGLE is not set -# CONFIG_IP6_NF_MATCH_AH is not set -# CONFIG_IP6_NF_MATCH_EUI64 is not set -# CONFIG_IP6_NF_MATCH_FRAG is not set -# CONFIG_IP6_NF_MATCH_HL is not set -# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -# CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_RPFILTER is not set -# CONFIG_IP6_NF_MATCH_RT is not set -# CONFIG_IP6_NF_MATCH_SRH is not set -# CONFIG_IP6_NF_NAT is not set -# CONFIG_IP6_NF_RAW is not set -# CONFIG_IP6_NF_SECURITY is not set -# CONFIG_IP6_NF_TARGET_HL is not set -# CONFIG_IP6_NF_TARGET_MASQUERADE is not set -# CONFIG_IP6_NF_TARGET_REJECT is not set -# CONFIG_IP6_NF_TARGET_SYNPROXY is not set -# CONFIG_IPACK_BUS is not set -# CONFIG_IPC_NS is not set -# CONFIG_IPMB_DEVICE_INTERFACE is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_IPV6 is not set -# CONFIG_IPV6_FOU is not set -# CONFIG_IPV6_FOU_TUNNEL is not set -# CONFIG_IPV6_ILA is not set -# CONFIG_IPV6_IOAM6_LWTUNNEL is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -CONFIG_IPV6_NDISC_NODETYPE=y -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_ROUTE_INFO is not set -# CONFIG_IPV6_RPL_LWTUNNEL is not set -# CONFIG_IPV6_SEG6_HMAC is not set -# CONFIG_IPV6_SEG6_LWTUNNEL is not set -# CONFIG_IPV6_SIT is not set -# CONFIG_IPV6_SIT_6RD is not set -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_VTI is not set -# CONFIG_IPVLAN is not set -# CONFIG_IPVTAP is not set -# CONFIG_IPW2100 is not set -# CONFIG_IPW2100_DEBUG is not set -CONFIG_IPW2100_MONITOR=y -# CONFIG_IPW2200 is not set -# CONFIG_IPW2200_DEBUG is not set -CONFIG_IPW2200_MONITOR=y -# CONFIG_IPW2200_PROMISCUOUS is not set -# CONFIG_IPW2200_QOS is not set -# CONFIG_IPW2200_RADIOTAP is not set -# CONFIG_IPWIRELESS is not set -# CONFIG_IPX is not set -CONFIG_IP_ADVANCED_ROUTER=y -# CONFIG_IP_DCCP is not set -# CONFIG_IP_FIB_TRIE_STATS is not set -# CONFIG_IP_MROUTE is not set -CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_MULTIPLE_TABLES=y -# CONFIG_IP_NF_ARPFILTER is not set -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_ARP_MANGLE is not set -# CONFIG_IP_NF_FILTER is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_MANGLE is not set -# CONFIG_IP_NF_MATCH_AH is not set -# CONFIG_IP_NF_MATCH_ECN is not set -# CONFIG_IP_NF_MATCH_RPFILTER is not set -# CONFIG_IP_NF_MATCH_TTL is not set -# CONFIG_IP_NF_RAW is not set -# CONFIG_IP_NF_SECURITY is not set -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -# CONFIG_IP_NF_TARGET_ECN is not set -# CONFIG_IP_NF_TARGET_MASQUERADE is not set -# CONFIG_IP_NF_TARGET_NETMAP is not set -# CONFIG_IP_NF_TARGET_REDIRECT is not set -# CONFIG_IP_NF_TARGET_REJECT is not set -# CONFIG_IP_NF_TARGET_SYNPROXY is not set -# CONFIG_IP_NF_TARGET_TTL is not set -# CONFIG_IP_PIMSM_V1 is not set -# CONFIG_IP_PIMSM_V2 is not set -# CONFIG_IP_PNP is not set -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_SCTP is not set -# CONFIG_IP_SET is not set -# CONFIG_IP_SET_HASH_IPMAC is not set -# CONFIG_IP_VS is not set -# CONFIG_IP_VS_MH is not set -CONFIG_IP_VS_MH_TAB_INDEX=10 -# CONFIG_IP_VS_TWOS is not set -# CONFIG_IRDA is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_IRQ_ALL_CPUS is not set -# CONFIG_IRQ_DOMAIN_DEBUG is not set -# CONFIG_IRQ_POLL is not set -# CONFIG_IRQ_TIME_ACCOUNTING is not set -# CONFIG_IR_GPIO_CIR is not set -# CONFIG_IR_HIX5HD2 is not set -# CONFIG_IR_IGORPLUGUSB is not set -# CONFIG_IR_IGUANA is not set -# CONFIG_IR_IMG is not set -# CONFIG_IR_IMON is not set -# CONFIG_IR_IMON_RAW is not set -# CONFIG_IR_JVC_DECODER is not set -# CONFIG_IR_LIRC_CODEC is not set -# CONFIG_IR_MCEUSB is not set -# CONFIG_IR_NEC_DECODER is not set -# CONFIG_IR_RC5_DECODER is not set -# CONFIG_IR_RC6_DECODER is not set -# CONFIG_IR_REDRAT3 is not set -# CONFIG_IR_SERIAL is not set -# CONFIG_IR_SIR is not set -# CONFIG_IR_SONY_DECODER is not set -# CONFIG_IR_STREAMZAP is not set -# CONFIG_IR_TOY is not set -# CONFIG_IR_TTUSBIR is not set -# CONFIG_ISA_BUS is not set -# CONFIG_ISA_BUS_API is not set -# CONFIG_ISCSI_BOOT_SYSFS is not set -# CONFIG_ISCSI_TCP is not set -CONFIG_ISDN=y -# CONFIG_ISDN_AUDIO is not set -# CONFIG_ISDN_CAPI is not set -# CONFIG_ISDN_CAPI_CAPIDRV is not set -# CONFIG_ISDN_DIVERSION is not set -# CONFIG_ISDN_DRV_ACT2000 is not set -# CONFIG_ISDN_DRV_GIGASET is not set -# CONFIG_ISDN_DRV_HISAX is not set -# CONFIG_ISDN_DRV_ICN is not set -# CONFIG_ISDN_DRV_LOOP is not set -# CONFIG_ISDN_DRV_PCBIT is not set -# CONFIG_ISDN_DRV_SC is not set -# CONFIG_ISDN_I4L is not set -# CONFIG_ISL29003 is not set -# CONFIG_ISL29020 is not set -# CONFIG_ISL29125 is not set -# CONFIG_ISL29501 is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_ISS4xx is not set -# CONFIG_ITG3200 is not set -# CONFIG_IWL3945 is not set -# CONFIG_IWLWIFI is not set -# CONFIG_IXGB is not set -# CONFIG_IXGBE is not set -# CONFIG_IXGBEVF is not set -# CONFIG_JAILHOUSE_GUEST is not set -# CONFIG_JBD2_DEBUG is not set -# CONFIG_JFFS2_CMODE_FAVOURLZO is not set -# CONFIG_JFFS2_CMODE_NONE is not set -CONFIG_JFFS2_CMODE_PRIORITY=y -# CONFIG_JFFS2_CMODE_SIZE is not set -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_JFFS2_FS_POSIX_ACL is not set -# CONFIG_JFFS2_FS_SECURITY is not set -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -CONFIG_JFFS2_FS_WRITEBUFFER=y -CONFIG_JFFS2_FS_XATTR=y -CONFIG_JFFS2_LZMA=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_JFFS2_SUMMARY=y -# CONFIG_JFFS2_ZLIB is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_POSIX_ACL is not set -# CONFIG_JFS_SECURITY is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_JME is not set -CONFIG_JOLIET=y -# CONFIG_JSA1212 is not set -# CONFIG_JUMP_LABEL is not set -# CONFIG_JZ4740_WDT is not set -# CONFIG_JZ4770_PHY is not set -# CONFIG_KALLSYMS is not set -# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -# CONFIG_KALLSYMS_ALL is not set -CONFIG_KALLSYMS_BASE_RELATIVE=y -# CONFIG_KALLSYMS_UNCOMPRESSED is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_KASAN is not set -# CONFIG_KASAN_MODULE_TEST is not set -CONFIG_KASAN_STACK=y -# CONFIG_KCMP is not set -# CONFIG_KCOV is not set -CONFIG_KCOV_IRQ_AREA_SIZE=0x40000 -# CONFIG_KCSAN is not set -# CONFIG_KERNEL_BZIP2 is not set -# CONFIG_KERNEL_CAT is not set -# CONFIG_KERNEL_GZIP is not set -# CONFIG_KERNEL_LZ4 is not set -# CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_LZO is not set -CONFIG_KERNEL_MODE_NEON=y -CONFIG_KERNEL_XZ=y -# CONFIG_KERNEL_ZSTD is not set -CONFIG_KERNFS=y -# CONFIG_KEXEC is not set -# CONFIG_KEXEC_FILE is not set -# CONFIG_KEXEC_SIG is not set -# CONFIG_KEYBOARD_ADC is not set -# CONFIG_KEYBOARD_ADP5588 is not set -# CONFIG_KEYBOARD_ADP5589 is not set -# CONFIG_KEYBOARD_APPLESPI is not set -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_BCM is not set -# CONFIG_KEYBOARD_CAP11XX is not set -# CONFIG_KEYBOARD_DLINK_DIR685 is not set -# CONFIG_KEYBOARD_GPIO is not set -# CONFIG_KEYBOARD_GPIO_POLLED is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_LM8333 is not set -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_MAX7359 is not set -# CONFIG_KEYBOARD_MCS is not set -# CONFIG_KEYBOARD_MPR121 is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_OMAP4 is not set -# CONFIG_KEYBOARD_OPENCORES is not set -# CONFIG_KEYBOARD_PXA27x is not set -# CONFIG_KEYBOARD_QT1050 is not set -# CONFIG_KEYBOARD_QT1070 is not set -# CONFIG_KEYBOARD_QT2160 is not set -# CONFIG_KEYBOARD_SAMSUNG is not set -# CONFIG_KEYBOARD_SH_KEYSC is not set -# CONFIG_KEYBOARD_SNVS_PWRKEY is not set -# CONFIG_KEYBOARD_STMPE is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_TCA8418 is not set -# CONFIG_KEYBOARD_TEGRA is not set -# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set -# CONFIG_KEYBOARD_TWL4030 is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYS is not set -# CONFIG_KEYS_REQUEST_CACHE is not set -# CONFIG_KEY_DH_OPERATIONS is not set -# CONFIG_KFENCE is not set -# CONFIG_KGDB is not set -# CONFIG_KMEMCHECK is not set -# CONFIG_KMX61 is not set -# CONFIG_KPC2000 is not set -# CONFIG_KPROBES is not set -# CONFIG_KPROBES_SANITY_TEST is not set -# CONFIG_KPROBE_EVENTS_ON_NOTRACE is not set -# CONFIG_KPROBE_EVENT_GEN_TEST is not set -# CONFIG_KS7010 is not set -# CONFIG_KS8842 is not set -# CONFIG_KS8851 is not set -# CONFIG_KS8851_MLL is not set -# CONFIG_KSM is not set -# CONFIG_KSZ884X_PCI is not set -# CONFIG_KUNIT is not set -CONFIG_KUSER_HELPERS=y -# CONFIG_KVM_AMD is not set -# CONFIG_KVM_AMD_SEV is not set -# CONFIG_KVM_GUEST is not set -# CONFIG_KVM_INTEL is not set -# CONFIG_KVM_WERROR is not set -# CONFIG_KVM_XEN is not set -# CONFIG_KXCJK1013 is not set -# CONFIG_KXSD9 is not set -# CONFIG_L2TP is not set -# CONFIG_L2TP_ETH is not set -# CONFIG_L2TP_IP is not set -# CONFIG_L2TP_V3 is not set -# CONFIG_LAN743X is not set -# CONFIG_LANMEDIA is not set -# CONFIG_LANTIQ is not set -# CONFIG_LAPB is not set -# CONFIG_LASAT is not set -# CONFIG_LATENCYTOP is not set -# CONFIG_LATTICE_ECP3_CONFIG is not set -CONFIG_LBDAF=y -# CONFIG_LCD_AMS369FG06 is not set -# CONFIG_LCD_CLASS_DEVICE is not set -# CONFIG_LCD_HX8357 is not set -# CONFIG_LCD_ILI922X is not set -# CONFIG_LCD_ILI9320 is not set -# CONFIG_LCD_L4F00242T03 is not set -# CONFIG_LCD_LD9040 is not set -# CONFIG_LCD_LMS283GF05 is not set -# CONFIG_LCD_LMS501KF03 is not set -# CONFIG_LCD_LTV350QV is not set -# CONFIG_LCD_OTM3225A is not set -# CONFIG_LCD_S6E63M0 is not set -# CONFIG_LCD_TDO24M is not set -# CONFIG_LCD_VGG2432A4 is not set -CONFIG_LDISC_AUTOLOAD=y -# CONFIG_LDM_PARTITION is not set -CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y -# CONFIG_LD_HEAD_STUB_CATCH is not set -# CONFIG_LEDS_AN30259A is not set -# CONFIG_LEDS_APU is not set -# CONFIG_LEDS_AW2013 is not set -# CONFIG_LEDS_BCM6328 is not set -# CONFIG_LEDS_BCM6358 is not set -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_BLINKM is not set -CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y -CONFIG_LEDS_CLASS=y -# CONFIG_LEDS_CLASS_FLASH is not set -CONFIG_LEDS_CLASS_MULTICOLOR=y -# CONFIG_LEDS_CR0014114 is not set -# CONFIG_LEDS_DAC124S085 is not set -# CONFIG_LEDS_EL15203000 is not set -# CONFIG_LEDS_GPIO is not set -# CONFIG_LEDS_INTEL_SS4200 is not set -# CONFIG_LEDS_IS31FL319X is not set -# CONFIG_LEDS_IS31FL32XX is not set -# CONFIG_LEDS_LM3530 is not set -# CONFIG_LEDS_LM3532 is not set -# CONFIG_LEDS_LM355x is not set -# CONFIG_LEDS_LM3642 is not set -# CONFIG_LEDS_LM3692X is not set -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP3952 is not set -# CONFIG_LEDS_LP50XX is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_LP5562 is not set -# CONFIG_LEDS_LP55XX_COMMON is not set -# CONFIG_LEDS_LP8501 is not set -# CONFIG_LEDS_LP8860 is not set -# CONFIG_LEDS_LT3593 is not set -# CONFIG_LEDS_MLXCPLD is not set -# CONFIG_LEDS_MLXREG is not set -# CONFIG_LEDS_NIC78BX is not set -# CONFIG_LEDS_NS2 is not set -# CONFIG_LEDS_OT200 is not set -# CONFIG_LEDS_PCA9532 is not set -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_PCA963X is not set -# CONFIG_LEDS_PWM is not set -# CONFIG_LEDS_REGULATOR is not set -# CONFIG_LEDS_SPI_BYTE is not set -# CONFIG_LEDS_SYSCON is not set -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_TI_LMU_COMMON is not set -# CONFIG_LEDS_TLC591XX is not set -CONFIG_LEDS_TRIGGERS=y -# CONFIG_LEDS_TRIGGER_ACTIVITY is not set -# CONFIG_LEDS_TRIGGER_AUDIO is not set -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -# CONFIG_LEDS_TRIGGER_CAMERA is not set -# CONFIG_LEDS_TRIGGER_CPU is not set -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -# CONFIG_LEDS_TRIGGER_DISK is not set -# CONFIG_LEDS_TRIGGER_GPIO is not set -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LEDS_TRIGGER_MTD is not set -CONFIG_LEDS_TRIGGER_NETDEV=y -# CONFIG_LEDS_TRIGGER_ONESHOT is not set -# CONFIG_LEDS_TRIGGER_PANIC is not set -# CONFIG_LEDS_TRIGGER_PATTERN is not set -CONFIG_LEDS_TRIGGER_TIMER=y -# CONFIG_LEDS_TRIGGER_TRANSIENT is not set -# CONFIG_LEDS_TRIGGER_TTY is not set -# CONFIG_LEDS_TURRIS_OMNIA is not set -# CONFIG_LEDS_USER is not set -# CONFIG_LED_TRIGGER_PHY is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_LGUEST is not set -# CONFIG_LIB80211 is not set -# CONFIG_LIB80211_CRYPT_CCMP is not set -# CONFIG_LIB80211_CRYPT_TKIP is not set -# CONFIG_LIB80211_CRYPT_WEP is not set -# CONFIG_LIB80211_DEBUG is not set -# CONFIG_LIBCRC32C is not set -# CONFIG_LIBERTAS is not set -# CONFIG_LIBERTAS_THINFIRM is not set -# CONFIG_LIBERTAS_USB is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_LIBIPW_DEBUG is not set -# CONFIG_LIBNVDIMM is not set -CONFIG_LIB_MEMNEQ=y -# CONFIG_LIDAR_LITE_V2 is not set -CONFIG_LINEAR_RANGES=y -# CONFIG_LIQUIDIO is not set -# CONFIG_LIQUIDIO_VF is not set -# CONFIG_LIRC is not set -# CONFIG_LIS3L02DQ is not set -# CONFIG_LITEX_LITEETH is not set -# CONFIG_LITEX_SOC_CONTROLLER is not set -# CONFIG_LIVEPATCH is not set -# CONFIG_LKDTM is not set -CONFIG_LLC=y -# CONFIG_LLC2 is not set -# CONFIG_LMK04832 is not set -# CONFIG_LMP91000 is not set -# CONFIG_LNET is not set -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_LOCKD is not set -CONFIG_LOCKDEP_BITS=15 -CONFIG_LOCKDEP_CHAINS_BITS=16 -CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12 -CONFIG_LOCKDEP_STACK_TRACE_BITS=19 -CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14 -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_LOCKD_V4=y -# CONFIG_LOCKUP_DETECTOR is not set -# CONFIG_LOCK_EVENT_COUNTS is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_LOCK_TORTURE_TEST is not set -# CONFIG_LOGFS is not set -# CONFIG_LOGIG940_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIWHEELS_FF is not set -# CONFIG_LOGO is not set -CONFIG_LOG_BUF_SHIFT=17 -CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 -# CONFIG_LOONGSON_MC146818 is not set -# CONFIG_LPC_ICH is not set -# CONFIG_LPC_SCH is not set -# CONFIG_LP_CONSOLE is not set -CONFIG_LRU_GEN=y -CONFIG_LRU_GEN_ENABLED=y -# CONFIG_LRU_GEN_STATS is not set -# CONFIG_LSI_ET1011C_PHY is not set -CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" -CONFIG_LSM_MMAP_MIN_ADDR=65536 -# CONFIG_LTC1660 is not set -# CONFIG_LTC2471 is not set -# CONFIG_LTC2485 is not set -# CONFIG_LTC2496 is not set -# CONFIG_LTC2497 is not set -# CONFIG_LTC2632 is not set -# CONFIG_LTC2983 is not set -# CONFIG_LTE_GDM724X is not set -CONFIG_LTO_NONE=y -# CONFIG_LTPC is not set -# CONFIG_LTR501 is not set -# CONFIG_LUSTRE_FS is not set -# CONFIG_LV0104CS is not set -# CONFIG_LWTUNNEL is not set -# CONFIG_LXT_PHY is not set -# CONFIG_LZ4HC_COMPRESS is not set -# CONFIG_LZ4_COMPRESS is not set -# CONFIG_LZ4_DECOMPRESS is not set -CONFIG_LZMA_COMPRESS=y -CONFIG_LZMA_DECOMPRESS=y -# CONFIG_LZO_COMPRESS is not set -# CONFIG_LZO_DECOMPRESS is not set -# CONFIG_M62332 is not set -# CONFIG_MAC80211 is not set -# CONFIG_MAC80211_MESSAGE_TRACING is not set -CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -# CONFIG_MACB is not set -# CONFIG_MACH_ASM9260 is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_INGENIC is not set -# CONFIG_MACH_INGENIC_SOC is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_MACH_JZ4740 is not set -# CONFIG_MACH_LOONGSON2EF is not set -# CONFIG_MACH_LOONGSON32 is not set -# CONFIG_MACH_LOONGSON64 is not set -# CONFIG_MACH_NINTENDO64 is not set -# CONFIG_MACH_PIC32 is not set -# CONFIG_MACH_PISTACHIO is not set -# CONFIG_MACH_REALTEK_RTL is not set -# CONFIG_MACH_TX39XX is not set -# CONFIG_MACH_TX49XX is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_MACH_XILFPGA is not set -# CONFIG_MACINTOSH_DRIVERS is not set -# CONFIG_MACSEC is not set -# CONFIG_MACVLAN is not set -# CONFIG_MACVTAP is not set -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MAG3110 is not set -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 -# CONFIG_MAGIC_SYSRQ_SERIAL is not set -CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" -# CONFIG_MAILBOX is not set -# CONFIG_MANAGER_SBS is not set -# CONFIG_MANDATORY_FILE_LOCKING is not set -# CONFIG_MANGLE_BOOTARGS is not set -# CONFIG_MARVELL_10G_PHY is not set -# CONFIG_MARVELL_88X2222_PHY is not set -# CONFIG_MARVELL_PHY is not set -# CONFIG_MAX1027 is not set -# CONFIG_MAX11100 is not set -# CONFIG_MAX1118 is not set -# CONFIG_MAX1241 is not set -# CONFIG_MAX1363 is not set -# CONFIG_MAX30100 is not set -# CONFIG_MAX30102 is not set -# CONFIG_MAX31856 is not set -# CONFIG_MAX44000 is not set -# CONFIG_MAX44009 is not set -# CONFIG_MAX517 is not set -# CONFIG_MAX5432 is not set -# CONFIG_MAX5481 is not set -# CONFIG_MAX5487 is not set -# CONFIG_MAX5821 is not set -# CONFIG_MAX63XX_WATCHDOG is not set -# CONFIG_MAX9611 is not set -# CONFIG_MAXIM_THERMOCOUPLE is not set -# CONFIG_MAXLINEAR_GPHY is not set -CONFIG_MAY_USE_DEVLINK=y -# CONFIG_MB1232 is not set -# CONFIG_MC3230 is not set -# CONFIG_MCB is not set -# CONFIG_MCP320X is not set -# CONFIG_MCP3422 is not set -# CONFIG_MCP3911 is not set -# CONFIG_MCP4018 is not set -# CONFIG_MCP41010 is not set -# CONFIG_MCP4131 is not set -# CONFIG_MCP4531 is not set -# CONFIG_MCP4725 is not set -# CONFIG_MCP4922 is not set -# CONFIG_MCPM is not set -# CONFIG_MCTP is not set -# CONFIG_MD is not set -# CONFIG_MDIO_BCM_UNIMAC is not set -# CONFIG_MDIO_BITBANG is not set -# CONFIG_MDIO_BUS_MUX_GPIO is not set -# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set -# CONFIG_MDIO_DEVICE is not set -# CONFIG_MDIO_DEVRES is not set -# CONFIG_MDIO_HISI_FEMAC is not set -# CONFIG_MDIO_IPQ4019 is not set -# CONFIG_MDIO_IPQ8064 is not set -# CONFIG_MDIO_MSCC_MIIM is not set -# CONFIG_MDIO_MVUSB is not set -# CONFIG_MDIO_OCTEON is not set -# CONFIG_MDIO_THUNDER is not set -# CONFIG_MDIO_XPCS is not set -# CONFIG_MDM_GCC_9607 is not set -# CONFIG_MD_FAULTY is not set -# CONFIG_MEDIATEK_GE_PHY is not set -# CONFIG_MEDIATEK_MT6577_AUXADC is not set -# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -# CONFIG_MEDIA_ATTACH is not set -# CONFIG_MEDIA_CAMERA_SUPPORT is not set -# CONFIG_MEDIA_CEC_SUPPORT is not set -# CONFIG_MEDIA_CONTROLLER is not set -# CONFIG_MEDIA_CONTROLLER_DVB is not set -# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -# CONFIG_MEDIA_PCI_SUPPORT is not set -# CONFIG_MEDIA_PLATFORM_SUPPORT is not set -# CONFIG_MEDIA_RADIO_SUPPORT is not set -# CONFIG_MEDIA_RC_SUPPORT is not set -# CONFIG_MEDIA_SDR_SUPPORT is not set -# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -# CONFIG_MEDIA_SUPPORT is not set -# CONFIG_MEDIA_SUPPORT_FILTER is not set -# CONFIG_MEDIA_TEST_SUPPORT is not set -# CONFIG_MEDIA_TUNER_E4000 is not set -# CONFIG_MEDIA_TUNER_FC0011 is not set -# CONFIG_MEDIA_TUNER_FC0012 is not set -# CONFIG_MEDIA_TUNER_FC0013 is not set -# CONFIG_MEDIA_TUNER_FC2580 is not set -# CONFIG_MEDIA_TUNER_IT913X is not set -# CONFIG_MEDIA_TUNER_M88RS6000T is not set -# CONFIG_MEDIA_TUNER_MAX2165 is not set -# CONFIG_MEDIA_TUNER_MC44S803 is not set -# CONFIG_MEDIA_TUNER_MSI001 is not set -# CONFIG_MEDIA_TUNER_MT2060 is not set -# CONFIG_MEDIA_TUNER_MT2063 is not set -# CONFIG_MEDIA_TUNER_MT20XX is not set -# CONFIG_MEDIA_TUNER_MT2131 is not set -# CONFIG_MEDIA_TUNER_MT2266 is not set -# CONFIG_MEDIA_TUNER_MXL301RF is not set -# CONFIG_MEDIA_TUNER_MXL5005S is not set -# CONFIG_MEDIA_TUNER_MXL5007T is not set -# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set -# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set -# CONFIG_MEDIA_TUNER_QT1010 is not set -# CONFIG_MEDIA_TUNER_R820T is not set -# CONFIG_MEDIA_TUNER_SI2157 is not set -# CONFIG_MEDIA_TUNER_SIMPLE is not set -# CONFIG_MEDIA_TUNER_TDA18212 is not set -# CONFIG_MEDIA_TUNER_TDA18218 is not set -# CONFIG_MEDIA_TUNER_TDA18250 is not set -# CONFIG_MEDIA_TUNER_TDA18271 is not set -# CONFIG_MEDIA_TUNER_TDA827X is not set -# CONFIG_MEDIA_TUNER_TDA8290 is not set -# CONFIG_MEDIA_TUNER_TDA9887 is not set -# CONFIG_MEDIA_TUNER_TEA5761 is not set -# CONFIG_MEDIA_TUNER_TEA5767 is not set -# CONFIG_MEDIA_TUNER_TUA9001 is not set -# CONFIG_MEDIA_TUNER_XC2028 is not set -# CONFIG_MEDIA_TUNER_XC4000 is not set -# CONFIG_MEDIA_TUNER_XC5000 is not set -# CONFIG_MEDIA_USB_SUPPORT is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_MELLANOX_PLATFORM is not set -CONFIG_MEMBARRIER=y -# CONFIG_MEMORY is not set -# CONFIG_MEMORY_FAILURE is not set -# CONFIG_MEMORY_HOTPLUG is not set -# CONFIG_MEMSTICK is not set -# CONFIG_MEMTEST is not set -# CONFIG_MEN_A21_WDT is not set -# CONFIG_MESON_SM is not set -CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -# CONFIG_MFD_88PM800 is not set -# CONFIG_MFD_88PM805 is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_MFD_AC100 is not set -# CONFIG_MFD_ACT8945A is not set -# CONFIG_MFD_ARIZONA_I2C is not set -# CONFIG_MFD_ARIZONA_SPI is not set -# CONFIG_MFD_AS3711 is not set -# CONFIG_MFD_AS3722 is not set -# CONFIG_MFD_ASIC3 is not set -# CONFIG_MFD_ATC260X_I2C is not set -# CONFIG_MFD_ATMEL_FLEXCOM is not set -# CONFIG_MFD_ATMEL_HLCDC is not set -# CONFIG_MFD_AXP20X is not set -# CONFIG_MFD_AXP20X_I2C is not set -# CONFIG_MFD_BCM590XX is not set -# CONFIG_MFD_BD9571MWV is not set -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_CPCAP is not set -# CONFIG_MFD_CROS_EC is not set -# CONFIG_MFD_CS5535 is not set -# CONFIG_MFD_DA9052_I2C is not set -# CONFIG_MFD_DA9052_SPI is not set -# CONFIG_MFD_DA9055 is not set -# CONFIG_MFD_DA9062 is not set -# CONFIG_MFD_DA9063 is not set -# CONFIG_MFD_DA9150 is not set -# CONFIG_MFD_DLN2 is not set -# CONFIG_MFD_EXYNOS_LPASS is not set -# CONFIG_MFD_GATEWORKS_GSC is not set -# CONFIG_MFD_HI6421_PMIC is not set -# CONFIG_MFD_INTEL_M10_BMC is not set -# CONFIG_MFD_INTEL_PMT is not set -# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set -# CONFIG_MFD_IQS62X is not set -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_KEMPLD is not set -# CONFIG_MFD_LM3533 is not set -# CONFIG_MFD_LOCHNAGAR is not set -# CONFIG_MFD_LP3943 is not set -# CONFIG_MFD_LP8788 is not set -# CONFIG_MFD_MADERA is not set -# CONFIG_MFD_MAX14577 is not set -# CONFIG_MFD_MAX77620 is not set -# CONFIG_MFD_MAX77650 is not set -# CONFIG_MFD_MAX77686 is not set -# CONFIG_MFD_MAX77693 is not set -# CONFIG_MFD_MAX77843 is not set -# CONFIG_MFD_MAX8907 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_MC13XXX is not set -# CONFIG_MFD_MC13XXX_I2C is not set -# CONFIG_MFD_MC13XXX_SPI is not set -# CONFIG_MFD_MENF21BMC is not set -# CONFIG_MFD_MP2629 is not set -# CONFIG_MFD_MT6360 is not set -# CONFIG_MFD_MT6397 is not set -# CONFIG_MFD_NTXEC is not set -# CONFIG_MFD_OMAP_USB_HOST is not set -# CONFIG_MFD_PALMAS is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_PM8921_CORE is not set -# CONFIG_MFD_PM8XXX is not set -# CONFIG_MFD_QCOM_PM8008 is not set -# CONFIG_MFD_RC5T583 is not set -# CONFIG_MFD_RDC321X is not set -# CONFIG_MFD_RETU is not set -# CONFIG_MFD_RK808 is not set -# CONFIG_MFD_RN5T618 is not set -# CONFIG_MFD_ROHM_BD70528 is not set -# CONFIG_MFD_ROHM_BD71828 is not set -# CONFIG_MFD_ROHM_BD718XX is not set -# CONFIG_MFD_ROHM_BD957XMUF is not set -# CONFIG_MFD_RSMU_I2C is not set -# CONFIG_MFD_RSMU_SPI is not set -# CONFIG_MFD_RT4831 is not set -# CONFIG_MFD_RT5033 is not set -# CONFIG_MFD_RTSX_PCI is not set -# CONFIG_MFD_RTSX_USB is not set -# CONFIG_MFD_SEC_CORE is not set -# CONFIG_MFD_SI476X_CORE is not set -# CONFIG_MFD_SKY81452 is not set -# CONFIG_MFD_SL28CPLD is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_SMSC is not set -# CONFIG_MFD_STMFX is not set -# CONFIG_MFD_STMPE is not set -# CONFIG_MFD_STPMIC1 is not set -# CONFIG_MFD_SYSCON is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set -# CONFIG_MFD_TIMBERDALE is not set -# CONFIG_MFD_TI_AM335X_TSCADC is not set -# CONFIG_MFD_TI_LMU is not set -# CONFIG_MFD_TI_LP873X is not set -# CONFIG_MFD_TI_LP87565 is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_TPS65086 is not set -# CONFIG_MFD_TPS65090 is not set -# CONFIG_MFD_TPS65217 is not set -# CONFIG_MFD_TPS65218 is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_MFD_TPS68470 is not set -# CONFIG_MFD_TPS80031 is not set -# CONFIG_MFD_TQMX86 is not set -# CONFIG_MFD_VIPERBOARD is not set -# CONFIG_MFD_VX855 is not set -# CONFIG_MFD_WL1273_CORE is not set -# CONFIG_MFD_WM831X is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8994 is not set -# CONFIG_MG_DISK is not set -# CONFIG_MHI_BUS is not set -# CONFIG_MHI_BUS_DEBUG is not set -# CONFIG_MHI_BUS_PCI_GENERIC is not set -# CONFIG_MHI_NET is not set -# CONFIG_MHI_WWAN_CTRL is not set -# CONFIG_MHI_WWAN_MBIM is not set -# CONFIG_MICREL_KS8995MA is not set -# CONFIG_MICREL_PHY is not set -# CONFIG_MICROCHIP_KSZ is not set -# CONFIG_MICROCHIP_PHY is not set -# CONFIG_MICROCHIP_PIT64B is not set -# CONFIG_MICROCHIP_T1_PHY is not set -# CONFIG_MICROSEMI_PHY is not set -# CONFIG_MIGRATION is not set -CONFIG_MII=y -# CONFIG_MIKROTIK is not set -# CONFIG_MIKROTIK_RB532 is not set -# CONFIG_MINIX_FS is not set -# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_MIPS32_N32 is not set -# CONFIG_MIPS32_O32 is not set -# CONFIG_MIPS_ALCHEMY is not set -# CONFIG_MIPS_CDMM is not set -# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set -# CONFIG_MIPS_CMDLINE_FROM_DTB is not set -# CONFIG_MIPS_CMP is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MIPS_CPS is not set -# CONFIG_MIPS_ELF_APPENDED_DTB is not set -# CONFIG_MIPS_FPU_EMULATOR is not set -# CONFIG_MIPS_FP_SUPPORT is not set -# CONFIG_MIPS_GENERIC is not set -# CONFIG_MIPS_GENERIC_KERNEL is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_O32_FP64_SUPPORT is not set -# CONFIG_MIPS_PARAVIRT is not set -# CONFIG_MIPS_PLATFORM_DEVICES is not set -# CONFIG_MIPS_RAW_APPENDED_DTB is not set -# CONFIG_MIPS_SEAD3 is not set -# CONFIG_MIPS_VA_BITS_48 is not set -# CONFIG_MIPS_VPE_LOADER is not set -# CONFIG_MISC_ALCOR_PCI is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_MISC_RTSX_PCI is not set -# CONFIG_MISC_RTSX_USB is not set -# CONFIG_MISDN is not set -# CONFIG_MISDN_AVMFRITZ is not set -# CONFIG_MISDN_HFCPCI is not set -# CONFIG_MISDN_HFCUSB is not set -# CONFIG_MISDN_INFINEON is not set -# CONFIG_MISDN_NETJET is not set -# CONFIG_MISDN_SPEEDFAX is not set -# CONFIG_MISDN_W6692 is not set -CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y -# CONFIG_MKISS is not set -# CONFIG_MLX4_CORE is not set -# CONFIG_MLX4_EN is not set -# CONFIG_MLX5_CORE is not set -# CONFIG_MLX5_SF is not set -# CONFIG_MLX90614 is not set -# CONFIG_MLX90632 is not set -# CONFIG_MLXFW is not set -# CONFIG_MLXSW_CORE is not set -# CONFIG_MLX_CPLD_PLATFORM is not set -# CONFIG_MLX_PLATFORM is not set -# CONFIG_MMA7455_I2C is not set -# CONFIG_MMA7455_SPI is not set -# CONFIG_MMA7660 is not set -# CONFIG_MMA8452 is not set -# CONFIG_MMA9551 is not set -# CONFIG_MMA9553 is not set -# CONFIG_MMC is not set -# CONFIG_MMC35240 is not set -# CONFIG_MMC_ARMMMCI is not set -# CONFIG_MMC_AU1X is not set -# CONFIG_MMC_BLOCK is not set -CONFIG_MMC_BLOCK_MINORS=8 -# CONFIG_MMC_CAVIUM_THUNDERX is not set -# CONFIG_MMC_CB710 is not set -# CONFIG_MMC_CQHCI is not set -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_DW is not set -# CONFIG_MMC_HSQ is not set -# CONFIG_MMC_JZ4740 is not set -# CONFIG_MMC_MTK is not set -# CONFIG_MMC_MVSDIO is not set -# CONFIG_MMC_S3C is not set -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_SDHCI_ACPI is not set -# CONFIG_MMC_SDHCI_AM654 is not set -# CONFIG_MMC_SDHCI_BCM_KONA is not set -# CONFIG_MMC_SDHCI_BRCMSTB is not set -# CONFIG_MMC_SDHCI_CADENCE is not set -# CONFIG_MMC_SDHCI_F_SDH30 is not set -# CONFIG_MMC_SDHCI_IPROC is not set -# CONFIG_MMC_SDHCI_MILBEAUT is not set -# CONFIG_MMC_SDHCI_MSM is not set -# CONFIG_MMC_SDHCI_OF_ARASAN is not set -# CONFIG_MMC_SDHCI_OF_ASPEED is not set -# CONFIG_MMC_SDHCI_OF_AT91 is not set -# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set -# CONFIG_MMC_SDHCI_OF_ESDHC is not set -# CONFIG_MMC_SDHCI_OF_HLWD is not set -# CONFIG_MMC_SDHCI_OMAP is not set -# CONFIG_MMC_SDHCI_PXAV2 is not set -# CONFIG_MMC_SDHCI_PXAV3 is not set -# CONFIG_MMC_SDHCI_S3C is not set -# CONFIG_MMC_SDHCI_XENON is not set -# CONFIG_MMC_SDRICOH_CS is not set -# CONFIG_MMC_SPI is not set -# CONFIG_MMC_STM32_SDMMC is not set -# CONFIG_MMC_TEST is not set -# CONFIG_MMC_TIFM_SD is not set -# CONFIG_MMC_TOSHIBA_PCI is not set -# CONFIG_MMC_USDHI6ROL0 is not set -# CONFIG_MMC_USHC is not set -# CONFIG_MMC_VIA_SDMMC is not set -# CONFIG_MMC_VUB300 is not set -# CONFIG_MMIOTRACE is not set -CONFIG_MMU=y -CONFIG_MMU_GATHER_RCU_TABLE_FREE=y -CONFIG_MMU_GATHER_TABLE_FREE=y -CONFIG_MODPROBE_PATH="/sbin/modprobe" -CONFIG_MODULES=y -# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set -# CONFIG_MODULE_COMPRESS is not set -# CONFIG_MODULE_COMPRESS_GZIP is not set -CONFIG_MODULE_COMPRESS_NONE=y -# CONFIG_MODULE_COMPRESS_XZ is not set -# CONFIG_MODULE_COMPRESS_ZSTD is not set -# CONFIG_MODULE_FORCE_LOAD is not set -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODULE_SIG is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_MODULE_STRIPPED=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MOST is not set -# CONFIG_MOTORCOMM_PHY is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_ELAN_I2C is not set -# CONFIG_MOUSE_GPIO is not set -# CONFIG_MOUSE_INPORT is not set -# CONFIG_MOUSE_LOGIBM is not set -# CONFIG_MOUSE_PC110PAD is not set -# CONFIG_MOUSE_PS2_FOCALTECH is not set -# CONFIG_MOUSE_PS2_SENTELIC is not set -# CONFIG_MOUSE_SYNAPTICS_I2C is not set -# CONFIG_MOUSE_SYNAPTICS_USB is not set -# CONFIG_MOXTET is not set -# CONFIG_MPL115 is not set -# CONFIG_MPL115_I2C is not set -# CONFIG_MPL115_SPI is not set -# CONFIG_MPL3115 is not set -# CONFIG_MPLS is not set -# CONFIG_MPLS_IPTUNNEL is not set -# CONFIG_MPLS_ROUTING is not set -# CONFIG_MPTCP is not set -# CONFIG_MPU3050_I2C is not set -# CONFIG_MQ_IOSCHED_DEADLINE is not set -# CONFIG_MQ_IOSCHED_KYBER is not set -# CONFIG_MS5611 is not set -# CONFIG_MS5637 is not set -# CONFIG_MSCC_OCELOT_SWITCH is not set -# CONFIG_MSDOS_FS is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_MSI_BITMAP_SELFTEST is not set -# CONFIG_MSI_LAPTOP is not set -# CONFIG_MSM_GCC_8953 is not set -# CONFIG_MSM_MMCC_8994 is not set -# CONFIG_MST_IRQ is not set -CONFIG_MTD=y -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_MTD_BLOCK2MTD is not set -CONFIG_MTD_CFI=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_CMDLINE_PARTS is not set -CONFIG_MTD_COMPLEX_MAPPINGS=y -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_DOCG3 is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_GPIO_ADDR is not set -# CONFIG_MTD_HYPERBUS is not set -# CONFIG_MTD_IMPA7 is not set -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_JEDECPROBE is not set -# CONFIG_MTD_LATCH_ADDR is not set -# CONFIG_MTD_LPDDR is not set -# CONFIG_MTD_LPDDR2_NVM is not set -# CONFIG_MTD_M25P80 is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -CONFIG_MTD_MAP_BANK_WIDTH_2=y -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MCHP23K256 is not set -# CONFIG_MTD_MCHP48L640 is not set -# CONFIG_MTD_MT81xx_NOR is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_MYLOADER_PARTS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_NAND_AMS_DELTA is not set -# CONFIG_MTD_NAND_AR934X is not set -# CONFIG_MTD_NAND_AR934X_HW_ECC is not set -# CONFIG_MTD_NAND_ARASAN is not set -# CONFIG_MTD_NAND_ATMEL is not set -# CONFIG_MTD_NAND_AU1550 is not set -# CONFIG_MTD_NAND_BCH is not set -# CONFIG_MTD_NAND_BF5XX is not set -# CONFIG_MTD_NAND_BRCMNAND is not set -# CONFIG_MTD_NAND_CADENCE is not set -# CONFIG_MTD_NAND_CAFE is not set -# CONFIG_MTD_NAND_CM_X270 is not set -# CONFIG_MTD_NAND_CS553X is not set -# CONFIG_MTD_NAND_DAVINCI is not set -# CONFIG_MTD_NAND_DENALI is not set -# CONFIG_MTD_NAND_DENALI_DT is not set -# CONFIG_MTD_NAND_DENALI_PCI is not set -CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018 -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_DOCG4 is not set -# CONFIG_MTD_NAND_ECC is not set -# CONFIG_MTD_NAND_ECC_BCH is not set -# CONFIG_MTD_NAND_ECC_SMC is not set -# CONFIG_MTD_NAND_ECC_SW_BCH is not set -# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set -# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set -# CONFIG_MTD_NAND_FSL_ELBC is not set -# CONFIG_MTD_NAND_FSL_IFC is not set -# CONFIG_MTD_NAND_FSL_UPM is not set -# CONFIG_MTD_NAND_FSMC is not set -# CONFIG_MTD_NAND_GPIO is not set -# CONFIG_MTD_NAND_GPMI_NAND is not set -# CONFIG_MTD_NAND_HISI504 is not set -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_INTEL_LGM is not set -# CONFIG_MTD_NAND_JZ4740 is not set -# CONFIG_MTD_NAND_MPC5121_NFC is not set -# CONFIG_MTD_NAND_MTK is not set -# CONFIG_MTD_NAND_MTK_BMT is not set -# CONFIG_MTD_NAND_MXC is not set -# CONFIG_MTD_NAND_MXIC is not set -# CONFIG_MTD_NAND_NANDSIM is not set -# CONFIG_MTD_NAND_NDFC is not set -# CONFIG_MTD_NAND_NUC900 is not set -# CONFIG_MTD_NAND_OMAP2 is not set -# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -# CONFIG_MTD_NAND_ORION is not set -# CONFIG_MTD_NAND_PASEMI is not set -# CONFIG_MTD_NAND_PLATFORM is not set -# CONFIG_MTD_NAND_PXA3xx is not set -# CONFIG_MTD_NAND_RB4XX is not set -# CONFIG_MTD_NAND_RB750 is not set -# CONFIG_MTD_NAND_RB91X is not set -# CONFIG_MTD_NAND_RICOH is not set -# CONFIG_MTD_NAND_S3C2410 is not set -# CONFIG_MTD_NAND_SHARPSL is not set -# CONFIG_MTD_NAND_SH_FLCTL is not set -# CONFIG_MTD_NAND_SOCRATES is not set -# CONFIG_MTD_NAND_TMIO is not set -# CONFIG_MTD_NAND_TXX9NDFMC is not set -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_ONENAND is not set -# CONFIG_MTD_OOPS is not set -# CONFIG_MTD_OTP is not set -# CONFIG_MTD_PARSER_TRX is not set -# CONFIG_MTD_PARTITIONED_MASTER is not set -# CONFIG_MTD_PCI is not set -# CONFIG_MTD_PCMCIA is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PHYSMAP_COMPAT is not set -# CONFIG_MTD_PHYSMAP_GEMINI is not set -# CONFIG_MTD_PHYSMAP_GPIO_ADDR is not set -# CONFIG_MTD_PHYSMAP_IXP4XX is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set -# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set -# CONFIG_MTD_PHYSMAP_VERSATILE is not set -# CONFIG_MTD_PLATRAM is not set -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_RAW_NAND is not set -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set -# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set -# CONFIG_MTD_ROM is not set -CONFIG_MTD_ROOTFS_ROOT_DEV=y -# CONFIG_MTD_ROUTERBOOT_PARTS is not set -# CONFIG_MTD_SERCOMM_PARTS is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_SM_COMMON is not set -# CONFIG_MTD_SPINAND_MT29F is not set -# CONFIG_MTD_SPI_NAND is not set -# CONFIG_MTD_SPI_NOR is not set -# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set -CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y -# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set -# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -# CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE is not set -CONFIG_MTD_SPLIT=y -# CONFIG_MTD_SPLIT_BCM63XX_FW is not set -# CONFIG_MTD_SPLIT_BCM_WFI_FW is not set -# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set -# CONFIG_MTD_SPLIT_ELF_FW is not set -# CONFIG_MTD_SPLIT_EVA_FW is not set -# CONFIG_MTD_SPLIT_FIRMWARE is not set -CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware" -# CONFIG_MTD_SPLIT_FIT_FW is not set -# CONFIG_MTD_SPLIT_H3C_VFS is not set -# CONFIG_MTD_SPLIT_JIMAGE_FW is not set -# CONFIG_MTD_SPLIT_LZMA_FW is not set -# CONFIG_MTD_SPLIT_MINOR_FW is not set -# CONFIG_MTD_SPLIT_SEAMA_FW is not set -# CONFIG_MTD_SPLIT_SEIL_FW is not set -CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y -CONFIG_MTD_SPLIT_SUPPORT=y -# CONFIG_MTD_SPLIT_TPLINK_FW is not set -# CONFIG_MTD_SPLIT_TRX_FW is not set -# CONFIG_MTD_SPLIT_UIMAGE_FW is not set -# CONFIG_MTD_SPLIT_WRGG_FW is not set -# CONFIG_MTD_SST25L is not set -# CONFIG_MTD_SWAP is not set -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_UBI is not set -# CONFIG_MTD_UBI_FASTMAP is not set -# CONFIG_MTD_UBI_GLUEBI is not set -# CONFIG_MTD_UIMAGE_SPLIT is not set -# CONFIG_MTD_VIRT_CONCAT is not set -# CONFIG_MTK_DEVAPC is not set -# CONFIG_MTK_MMC is not set -# CONFIG_MTK_MMSYS is not set -# CONFIG_MTK_THERMAL is not set -# CONFIG_MULTIPLEXER is not set -CONFIG_MULTIUSER=y -# CONFIG_MUTEX_SPIN_ON_OWNER is not set -# CONFIG_MUX_ADG792A is not set -# CONFIG_MUX_ADGS1408 is not set -# CONFIG_MUX_GPIO is not set -# CONFIG_MUX_MMIO is not set -# CONFIG_MV643XX_ETH is not set -# CONFIG_MVMDIO is not set -# CONFIG_MVNETA_BM is not set -# CONFIG_MVSW61XX_PHY is not set -# CONFIG_MV_XOR_V2 is not set -# CONFIG_MWAVE is not set -# CONFIG_MWL8K is not set -# CONFIG_MXC4005 is not set -# CONFIG_MXC6255 is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NAMESPACES is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_NATSEMI is not set -# CONFIG_NAU7802 is not set -# CONFIG_NBPFAXI_DMA is not set -# CONFIG_NCP_FS is not set -# CONFIG_NE2000 is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NEC_MARKEINS is not set -CONFIG_NET=y -# CONFIG_NETCONSOLE is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVSIM is not set -# CONFIG_NETFILTER is not set -# CONFIG_NETFILTER_ADVANCED is not set -# CONFIG_NETFILTER_DEBUG is not set -# CONFIG_NETFILTER_INGRESS is not set -# CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NETFILTER_NETLINK_ACCT is not set -# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set -# CONFIG_NETFILTER_NETLINK_HOOK is not set -# CONFIG_NETFILTER_NETLINK_LOG is not set -# CONFIG_NETFILTER_NETLINK_OSF is not set -# CONFIG_NETFILTER_NETLINK_QUEUE is not set -# CONFIG_NETFILTER_XTABLES is not set -# CONFIG_NETFILTER_XTABLES_COMPAT is not set -# CONFIG_NETFILTER_XT_CONNMARK is not set -# CONFIG_NETFILTER_XT_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_BPF is not set -# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set -# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set -# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set -# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set -# CONFIG_NETFILTER_XT_MATCH_CPU is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -# CONFIG_NETFILTER_XT_MATCH_ECN is not set -# CONFIG_NETFILTER_XT_MATCH_ESP is not set -# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_HELPER is not set -# CONFIG_NETFILTER_XT_MATCH_HL is not set -# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set -# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set -# CONFIG_NETFILTER_XT_MATCH_L2TP is not set -# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set -# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_MAC is not set -# CONFIG_NETFILTER_XT_MATCH_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set -# CONFIG_NETFILTER_XT_MATCH_OSF is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set -# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set -# CONFIG_NETFILTER_XT_MATCH_STATE is not set -# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set -# CONFIG_NETFILTER_XT_MATCH_STRING is not set -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -# CONFIG_NETFILTER_XT_MATCH_TIME is not set -# CONFIG_NETFILTER_XT_MATCH_U32 is not set -# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set -# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set -# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set -# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set -# CONFIG_NETFILTER_XT_TARGET_CT is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_HL is not set -# CONFIG_NETFILTER_XT_TARGET_HMARK is not set -# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set -# CONFIG_NETFILTER_XT_TARGET_LED is not set -# CONFIG_NETFILTER_XT_TARGET_LOG is not set -# CONFIG_NETFILTER_XT_TARGET_MARK is not set -# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set -# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set -# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set -# CONFIG_NETFILTER_XT_TARGET_TEE is not set -# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set -# CONFIG_NETFILTER_XT_TARGET_TRACE is not set -# CONFIG_NETLABEL is not set -# CONFIG_NETLINK_DIAG is not set -# CONFIG_NETLINK_MMAP is not set -# CONFIG_NETPOLL is not set -# CONFIG_NETROM is not set -CONFIG_NETWORK_FILESYSTEMS=y -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETXEN_NIC is not set -# CONFIG_NET_9P is not set -# CONFIG_NET_ACT_BPF is not set -# CONFIG_NET_ACT_CSUM is not set -# CONFIG_NET_ACT_CT is not set -# CONFIG_NET_ACT_GACT is not set -# CONFIG_NET_ACT_GATE is not set -# CONFIG_NET_ACT_IFE is not set -# CONFIG_NET_ACT_IPT is not set -# CONFIG_NET_ACT_MIRRED is not set -# CONFIG_NET_ACT_MPLS is not set -# CONFIG_NET_ACT_NAT is not set -# CONFIG_NET_ACT_PEDIT is not set -# CONFIG_NET_ACT_POLICE is not set -# CONFIG_NET_ACT_SAMPLE is not set -# CONFIG_NET_ACT_SIMP is not set -# CONFIG_NET_ACT_SKBEDIT is not set -# CONFIG_NET_ACT_SKBMOD is not set -# CONFIG_NET_ACT_TUNNEL_KEY is not set -# CONFIG_NET_ACT_VLAN is not set -CONFIG_NET_CADENCE=y -# CONFIG_NET_CALXEDA_XGMAC is not set -CONFIG_NET_CLS=y -# CONFIG_NET_CLS_ACT is not set -# CONFIG_NET_CLS_BASIC is not set -# CONFIG_NET_CLS_BPF is not set -# CONFIG_NET_CLS_FLOW is not set -# CONFIG_NET_CLS_FLOWER is not set -# CONFIG_NET_CLS_FW is not set -CONFIG_NET_CLS_IND=y -# CONFIG_NET_CLS_MATCHALL is not set -# CONFIG_NET_CLS_ROUTE4 is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_CLS_U32 is not set -CONFIG_NET_CORE=y -# CONFIG_NET_DEVLINK is not set -# CONFIG_NET_DROP_MONITOR is not set -# CONFIG_NET_DSA is not set -# CONFIG_NET_DSA_AR9331 is not set -# CONFIG_NET_DSA_BCM_SF2 is not set -# CONFIG_NET_DSA_LANTIQ_GSWIP is not set -# CONFIG_NET_DSA_LEGACY is not set -# CONFIG_NET_DSA_LOOP is not set -# CONFIG_NET_DSA_MICROCHIP_KSZ8795 is not set -# CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set -# CONFIG_NET_DSA_MSCC_FELIX is not set -# CONFIG_NET_DSA_MSCC_SEVILLE is not set -# CONFIG_NET_DSA_MT7530 is not set -# CONFIG_NET_DSA_MV88E6060 is not set -# CONFIG_NET_DSA_MV88E6123_61_65 is not set -# CONFIG_NET_DSA_MV88E6131 is not set -# CONFIG_NET_DSA_MV88E6171 is not set -# CONFIG_NET_DSA_MV88E6352 is not set -# CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set -# CONFIG_NET_DSA_MV88E6XXX_PTP is not set -# CONFIG_NET_DSA_QCA8K is not set -# CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT is not set -# CONFIG_NET_DSA_REALTEK_SMI is not set -# CONFIG_NET_DSA_SJA1105 is not set -# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set -# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set -# CONFIG_NET_DSA_TAG_8021Q is not set -# CONFIG_NET_DSA_TAG_AR9331 is not set -# CONFIG_NET_DSA_TAG_BRCM is not set -# CONFIG_NET_DSA_TAG_BRCM_LEGACY is not set -# CONFIG_NET_DSA_TAG_BRCM_PREPEND is not set -# CONFIG_NET_DSA_TAG_DSA is not set -# CONFIG_NET_DSA_TAG_EDSA is not set -# CONFIG_NET_DSA_TAG_GSWIP is not set -# CONFIG_NET_DSA_TAG_HELLCREEK is not set -# CONFIG_NET_DSA_TAG_KSZ is not set -# CONFIG_NET_DSA_TAG_LAN9303 is not set -# CONFIG_NET_DSA_TAG_MTK is not set -# CONFIG_NET_DSA_TAG_OCELOT is not set -# CONFIG_NET_DSA_TAG_OCELOT_8021Q is not set -# CONFIG_NET_DSA_TAG_QCA is not set -# CONFIG_NET_DSA_TAG_RTL4_A is not set -# CONFIG_NET_DSA_TAG_SJA1105 is not set -# CONFIG_NET_DSA_TAG_TRAILER is not set -# CONFIG_NET_DSA_TAG_XRS700X is not set -# CONFIG_NET_DSA_VITESSE_VSC73XX is not set -# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set -# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set -# CONFIG_NET_DSA_XRS700X_I2C is not set -# CONFIG_NET_DSA_XRS700X_MDIO is not set -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_EMATCH_CANID is not set -# CONFIG_NET_EMATCH_CMP is not set -# CONFIG_NET_EMATCH_IPT is not set -# CONFIG_NET_EMATCH_META is not set -# CONFIG_NET_EMATCH_NBYTE is not set -CONFIG_NET_EMATCH_STACK=32 -# CONFIG_NET_EMATCH_TEXT is not set -# CONFIG_NET_EMATCH_U32 is not set -# CONFIG_NET_FAILOVER is not set -# CONFIG_NET_FC is not set -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_IFE is not set -# CONFIG_NET_IPGRE is not set -CONFIG_NET_IPGRE_BROADCAST=y -# CONFIG_NET_IPGRE_DEMUX is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPVTI is not set -# CONFIG_NET_IP_TUNNEL is not set -# CONFIG_NET_KEY is not set -# CONFIG_NET_KEY_MIGRATE is not set -# CONFIG_NET_L3_MASTER_DEV is not set -# CONFIG_NET_MEDIATEK_STAR_EMAC is not set -# CONFIG_NET_MPLS_GSO is not set -# CONFIG_NET_NCSI is not set -# CONFIG_NET_NSH is not set -# CONFIG_NET_PACKET_ENGINE is not set -# CONFIG_NET_PKTGEN is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_NET_PTP_CLASSIFY is not set -CONFIG_NET_RX_BUSY_POLL=y -# CONFIG_NET_SB1000 is not set -CONFIG_NET_SCHED=y -# CONFIG_NET_SCH_CAKE is not set -# CONFIG_NET_SCH_CBS is not set -# CONFIG_NET_SCH_CHOKE is not set -# CONFIG_NET_SCH_CODEL is not set -CONFIG_NET_SCH_DEFAULT=y -# CONFIG_NET_SCH_DRR is not set -# CONFIG_NET_SCH_ETF is not set -# CONFIG_NET_SCH_ETS is not set -CONFIG_NET_SCH_FIFO=y -# CONFIG_NET_SCH_FQ is not set -CONFIG_NET_SCH_FQ_CODEL=y -# CONFIG_NET_SCH_FQ_PIE is not set -# CONFIG_NET_SCH_GRED is not set -# CONFIG_NET_SCH_HFSC is not set -# CONFIG_NET_SCH_HHF is not set -# CONFIG_NET_SCH_HTB is not set -# CONFIG_NET_SCH_INGRESS is not set -# CONFIG_NET_SCH_MQPRIO is not set -# CONFIG_NET_SCH_MULTIQ is not set -# CONFIG_NET_SCH_NETEM is not set -# CONFIG_NET_SCH_PIE is not set -# CONFIG_NET_SCH_PLUG is not set -# CONFIG_NET_SCH_PRIO is not set -# CONFIG_NET_SCH_QFQ is not set -# CONFIG_NET_SCH_RED is not set -# CONFIG_NET_SCH_SFB is not set -# CONFIG_NET_SCH_SFQ is not set -# CONFIG_NET_SCH_SKBPRIO is not set -# CONFIG_NET_SCH_TAPRIO is not set -# CONFIG_NET_SCH_TBF is not set -# CONFIG_NET_SCH_TEQL is not set -# CONFIG_NET_SCTPPROBE is not set -# CONFIG_NET_SELFTESTS is not set -CONFIG_NET_SOCK_MSG=y -# CONFIG_NET_SWITCHDEV is not set -# CONFIG_NET_TCPPROBE is not set -# CONFIG_NET_TC_SKB_EXT is not set -# CONFIG_NET_TEAM is not set -# CONFIG_NET_TULIP is not set -# CONFIG_NET_UDP_TUNNEL is not set -CONFIG_NET_VENDOR_3COM=y -CONFIG_NET_VENDOR_8390=y -CONFIG_NET_VENDOR_ADAPTEC=y -CONFIG_NET_VENDOR_AGERE=y -CONFIG_NET_VENDOR_ALACRITECH=y -CONFIG_NET_VENDOR_ALTEON=y -CONFIG_NET_VENDOR_AMAZON=y -CONFIG_NET_VENDOR_AMD=y -CONFIG_NET_VENDOR_AQUANTIA=y -CONFIG_NET_VENDOR_ARC=y -CONFIG_NET_VENDOR_ATHEROS=y -CONFIG_NET_VENDOR_AURORA=y -CONFIG_NET_VENDOR_BROADCOM=y -CONFIG_NET_VENDOR_BROCADE=y -CONFIG_NET_VENDOR_CADENCE=y -CONFIG_NET_VENDOR_CAVIUM=y -CONFIG_NET_VENDOR_CHELSIO=y -CONFIG_NET_VENDOR_CIRRUS=y -CONFIG_NET_VENDOR_CISCO=y -CONFIG_NET_VENDOR_CORTINA=y -CONFIG_NET_VENDOR_DEC=y -CONFIG_NET_VENDOR_DLINK=y -CONFIG_NET_VENDOR_EMULEX=y -CONFIG_NET_VENDOR_EXAR=y -CONFIG_NET_VENDOR_EZCHIP=y -CONFIG_NET_VENDOR_FARADAY=y -CONFIG_NET_VENDOR_FREESCALE=y -CONFIG_NET_VENDOR_FUJITSU=y -CONFIG_NET_VENDOR_GOOGLE=y -CONFIG_NET_VENDOR_HISILICON=y -CONFIG_NET_VENDOR_HP=y -CONFIG_NET_VENDOR_HUAWEI=y -CONFIG_NET_VENDOR_I825XX=y -CONFIG_NET_VENDOR_IBM=y -CONFIG_NET_VENDOR_INTEL=y -# CONFIG_NET_VENDOR_LITEX is not set -CONFIG_NET_VENDOR_MARVELL=y -CONFIG_NET_VENDOR_MELLANOX=y -CONFIG_NET_VENDOR_MICREL=y -CONFIG_NET_VENDOR_MICROCHIP=y -CONFIG_NET_VENDOR_MICROSEMI=y -# CONFIG_NET_VENDOR_MICROSOFT is not set -CONFIG_NET_VENDOR_MYRI=y -CONFIG_NET_VENDOR_NATSEMI=y -CONFIG_NET_VENDOR_NETERION=y -CONFIG_NET_VENDOR_NETRONOME=y -CONFIG_NET_VENDOR_NI=y -CONFIG_NET_VENDOR_NVIDIA=y -CONFIG_NET_VENDOR_OKI=y -CONFIG_NET_VENDOR_PACKET_ENGINES=y -CONFIG_NET_VENDOR_PENSANDO=y -CONFIG_NET_VENDOR_QLOGIC=y -CONFIG_NET_VENDOR_QUALCOMM=y -CONFIG_NET_VENDOR_RDC=y -CONFIG_NET_VENDOR_REALTEK=y -CONFIG_NET_VENDOR_RENESAS=y -CONFIG_NET_VENDOR_ROCKER=y -CONFIG_NET_VENDOR_SAMSUNG=y -CONFIG_NET_VENDOR_SEEQ=y -CONFIG_NET_VENDOR_SILAN=y -CONFIG_NET_VENDOR_SIS=y -CONFIG_NET_VENDOR_SMSC=y -CONFIG_NET_VENDOR_SOCIONEXT=y -CONFIG_NET_VENDOR_SOLARFLARE=y -CONFIG_NET_VENDOR_STMICRO=y -CONFIG_NET_VENDOR_SUN=y -CONFIG_NET_VENDOR_SYNOPSYS=y -CONFIG_NET_VENDOR_TEHUTI=y -CONFIG_NET_VENDOR_TI=y -CONFIG_NET_VENDOR_TOSHIBA=y -CONFIG_NET_VENDOR_VIA=y -CONFIG_NET_VENDOR_WIZNET=y -CONFIG_NET_VENDOR_XILINX=y -CONFIG_NET_VENDOR_XIRCOM=y -# CONFIG_NET_VRF is not set -# CONFIG_NET_XGENE is not set -CONFIG_NEW_LEDS=y -# CONFIG_NFC is not set -# CONFIG_NFP is not set -# CONFIG_NFSD is not set -# CONFIG_NFSD_V2 is not set -# CONFIG_NFSD_V2_ACL is not set -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -# CONFIG_NFSD_V4 is not set -# CONFIG_NFS_ACL_SUPPORT is not set -CONFIG_NFS_COMMON=y -# CONFIG_NFS_DISABLE_UDP_SUPPORT is not set -# CONFIG_NFS_FS is not set -# CONFIG_NFS_FSCACHE is not set -# CONFIG_NFS_SWAP is not set -# CONFIG_NFS_V2 is not set -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_V4_1 is not set -# CONFIG_NFTL is not set -# CONFIG_NFT_BRIDGE_META is not set -# CONFIG_NFT_BRIDGE_REJECT is not set -# CONFIG_NFT_CONNLIMIT is not set -# CONFIG_NFT_DUP_IPV4 is not set -# CONFIG_NFT_DUP_IPV6 is not set -# CONFIG_NFT_FIB_IPV4 is not set -# CONFIG_NFT_FIB_IPV6 is not set -# CONFIG_NFT_FIB_NETDEV is not set -# CONFIG_NFT_FLOW_OFFLOAD is not set -# CONFIG_NFT_OBJREF is not set -# CONFIG_NFT_OSF is not set -# CONFIG_NFT_REJECT_NETDEV is not set -# CONFIG_NFT_RT is not set -# CONFIG_NFT_SET_BITMAP is not set -# CONFIG_NFT_SOCKET is not set -# CONFIG_NFT_SYNPROXY is not set -# CONFIG_NFT_TPROXY is not set -# CONFIG_NFT_TUNNEL is not set -# CONFIG_NFT_XFRM is not set -# CONFIG_NF_CONNTRACK is not set -# CONFIG_NF_CONNTRACK_AMANDA is not set -# CONFIG_NF_CONNTRACK_BRIDGE is not set -# CONFIG_NF_CONNTRACK_EVENTS is not set -# CONFIG_NF_CONNTRACK_FTP is not set -# CONFIG_NF_CONNTRACK_H323 is not set -# CONFIG_NF_CONNTRACK_IRC is not set -# CONFIG_NF_CONNTRACK_LABELS is not set -# CONFIG_NF_CONNTRACK_MARK is not set -# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -# CONFIG_NF_CONNTRACK_PPTP is not set -CONFIG_NF_CONNTRACK_PROCFS=y -# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set -# CONFIG_NF_CONNTRACK_SANE is not set -# CONFIG_NF_CONNTRACK_SECMARK is not set -# CONFIG_NF_CONNTRACK_SIP is not set -# CONFIG_NF_CONNTRACK_SNMP is not set -# CONFIG_NF_CONNTRACK_TFTP is not set -# CONFIG_NF_CONNTRACK_TIMEOUT is not set -# CONFIG_NF_CONNTRACK_TIMESTAMP is not set -# CONFIG_NF_CONNTRACK_ZONES is not set -# CONFIG_NF_CT_NETLINK is not set -# CONFIG_NF_CT_NETLINK_HELPER is not set -# CONFIG_NF_CT_NETLINK_TIMEOUT is not set -# CONFIG_NF_CT_PROTO_DCCP is not set -# CONFIG_NF_CT_PROTO_GRE is not set -# CONFIG_NF_CT_PROTO_SCTP is not set -# CONFIG_NF_CT_PROTO_UDPLITE is not set -# CONFIG_NF_DEFRAG_IPV4 is not set -# CONFIG_NF_DUP_IPV4 is not set -# CONFIG_NF_DUP_IPV6 is not set -# CONFIG_NF_FLOW_TABLE is not set -# CONFIG_NF_FLOW_TABLE_PROCFS is not set -# CONFIG_NF_LOG_ARP is not set -# CONFIG_NF_LOG_BRIDGE is not set -# CONFIG_NF_LOG_IPV4 is not set -# CONFIG_NF_LOG_NETDEV is not set -# CONFIG_NF_LOG_SYSLOG is not set -# CONFIG_NF_NAT is not set -# CONFIG_NF_NAT_AMANDA is not set -# CONFIG_NF_NAT_FTP is not set -# CONFIG_NF_NAT_H323 is not set -# CONFIG_NF_NAT_IRC is not set -# CONFIG_NF_NAT_NEEDED is not set -# CONFIG_NF_NAT_PPTP is not set -# CONFIG_NF_NAT_PROTO_GRE is not set -# CONFIG_NF_NAT_SIP is not set -# CONFIG_NF_NAT_SNMP_BASIC is not set -# CONFIG_NF_NAT_TFTP is not set -# CONFIG_NF_REJECT_IPV4 is not set -# CONFIG_NF_REJECT_IPV6 is not set -# CONFIG_NF_SOCKET_IPV4 is not set -# CONFIG_NF_SOCKET_IPV6 is not set -# CONFIG_NF_TABLES is not set -CONFIG_NF_TABLES_ARP=y -CONFIG_NF_TABLES_BRIDGE=y -CONFIG_NF_TABLES_INET=y -CONFIG_NF_TABLES_IPV4=y -CONFIG_NF_TABLES_IPV6=y -CONFIG_NF_TABLES_NETDEV=y -# CONFIG_NF_TABLES_SET is not set -# CONFIG_NF_TPROXY_IPV4 is not set -# CONFIG_NF_TPROXY_IPV6 is not set -# CONFIG_NI65 is not set -# CONFIG_NI903X_WDT is not set -# CONFIG_NIC7018_WDT is not set -# CONFIG_NILFS2_FS is not set -# CONFIG_NIU is not set -# CONFIG_NI_XGE_MANAGEMENT_ENET is not set -CONFIG_NLATTR=y -# CONFIG_NLMON is not set -# CONFIG_NLM_XLP_BOARD is not set -# CONFIG_NLM_XLR_BOARD is not set -# CONFIG_NLS is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_MAC_CELTIC is not set -# CONFIG_NLS_MAC_CENTEURO is not set -# CONFIG_NLS_MAC_CROATIAN is not set -# CONFIG_NLS_MAC_CYRILLIC is not set -# CONFIG_NLS_MAC_GAELIC is not set -# CONFIG_NLS_MAC_GREEK is not set -# CONFIG_NLS_MAC_ICELAND is not set -# CONFIG_NLS_MAC_INUIT is not set -# CONFIG_NLS_MAC_ROMAN is not set -# CONFIG_NLS_MAC_ROMANIAN is not set -# CONFIG_NLS_MAC_TURKISH is not set -# CONFIG_NLS_UTF8 is not set -CONFIG_NMI_LOG_BUF_SHIFT=13 -# CONFIG_NOA1305 is not set -# CONFIG_NOP_USB_XCEIV is not set -# CONFIG_NORTEL_HERMES is not set -# CONFIG_NOTIFIER_ERROR_INJECTION is not set -# CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT is not set -# CONFIG_NOZOMI is not set -# CONFIG_NO_BOOTMEM is not set -# CONFIG_NO_HZ is not set -# CONFIG_NO_HZ_FULL is not set -# CONFIG_NO_HZ_IDLE is not set -# CONFIG_NS83820 is not set -# CONFIG_NTB is not set -# CONFIG_NTFS3_64BIT_CLUSTER is not set -# CONFIG_NTFS3_FS is not set -# CONFIG_NTFS3_FS_POSIX_ACL is not set -# CONFIG_NTFS3_LZX_XPRESS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_NTP_PPS is not set -# CONFIG_NULL_TTY is not set -# CONFIG_NUMA is not set -# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set -# CONFIG_NVM is not set -# CONFIG_NVMEM is not set -# CONFIG_NVMEM_BCM_OCOTP is not set -# CONFIG_NVMEM_IMX_OCOTP is not set -# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set -# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set -# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set -# CONFIG_NVMEM_REBOOT_MODE is not set -# CONFIG_NVMEM_RMEM is not set -# CONFIG_NVMEM_SYSFS is not set -# CONFIG_NVMEM_U_BOOT_ENV is not set -# CONFIG_NVME_FC is not set -# CONFIG_NVME_TARGET is not set -# CONFIG_NVME_TCP is not set -# CONFIG_NVRAM is not set -# CONFIG_NV_TCO is not set -# CONFIG_NXP_C45_TJA11XX_PHY is not set -# CONFIG_NXP_STB220 is not set -# CONFIG_NXP_STB225 is not set -# CONFIG_NXP_TJA11XX_PHY is not set -# CONFIG_N_GSM is not set -# CONFIG_OABI_COMPAT is not set -# CONFIG_OBS600 is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_OCTEONTX2_AF is not set -# CONFIG_OCTEONTX2_PF is not set -# CONFIG_OF_OVERLAY is not set -CONFIG_OF_RESERVED_MEM=y -# CONFIG_OF_UNITTEST is not set -# CONFIG_OID_REGISTRY is not set -# CONFIG_OMAP2_DSS_DEBUG is not set -# CONFIG_OMAP2_DSS_DEBUGFS is not set -# CONFIG_OMAP2_DSS_SDI is not set -# CONFIG_OMAP_OCP2SCP is not set -# CONFIG_OMAP_USB2 is not set -# CONFIG_OMFS_FS is not set -# CONFIG_OPENVSWITCH is not set -# CONFIG_OPROFILE is not set -# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set -# CONFIG_OPT3001 is not set -CONFIG_OPTIMIZE_INLINING=y -# CONFIG_ORANGEFS_FS is not set -# CONFIG_ORION_WATCHDOG is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_OSNOISE_TRACER is not set -CONFIG_OVERLAY_FS=y -# CONFIG_OVERLAY_FS_INDEX is not set -# CONFIG_OVERLAY_FS_METACOPY is not set -CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y -# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set -CONFIG_OVERLAY_FS_XINO_AUTO=y -# CONFIG_OWL_LOADER is not set -# CONFIG_P54_COMMON is not set -# CONFIG_PA12203001 is not set -CONFIG_PACKET=y -# CONFIG_PACKET_DIAG is not set -# CONFIG_PACKING is not set -# CONFIG_PAGE_EXTENSION is not set -# CONFIG_PAGE_OWNER is not set -# CONFIG_PAGE_POISONING is not set -# CONFIG_PAGE_POOL is not set -# CONFIG_PAGE_POOL_STATS is not set -# CONFIG_PAGE_REPORTING is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_32KB is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_64KB is not set -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PALMAS_GPADC is not set -# CONFIG_PANASONIC_LAPTOP is not set -# CONFIG_PANEL is not set -CONFIG_PANIC_ON_OOPS=y -CONFIG_PANIC_ON_OOPS_VALUE=1 -CONFIG_PANIC_TIMEOUT=1 -# CONFIG_PANTHERLORD_FF is not set -# CONFIG_PARAVIRT is not set -# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -# CONFIG_PARPORT is not set -# CONFIG_PARPORT_1284 is not set -# CONFIG_PARPORT_AX88796 is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_PC is not set -CONFIG_PARTITION_ADVANCED=y -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARASAN_CF is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_ATP867X is not set -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CS5535 is not set -# CONFIG_PATA_CS5536 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IMX is not set -# CONFIG_PATA_ISAPNP is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_LEGACY is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NINJA32 is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_NS87415 is not set -# CONFIG_PATA_OCTEON_CF is not set -# CONFIG_PATA_OF_PLATFORM is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PCMCIA is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_PLATFORM is not set -# CONFIG_PATA_QDI is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RDC is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SCH is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_TOSHIBA is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -# CONFIG_PATA_WINBOND_VLB is not set -# CONFIG_PC104 is not set -# CONFIG_PC300TOO is not set -# CONFIG_PCCARD is not set -# CONFIG_PCH_DMA is not set -# CONFIG_PCH_GBE is not set -# CONFIG_PCH_PHUB is not set -# CONFIG_PCI is not set -# CONFIG_PCI200SYN is not set -# CONFIG_PCIEAER is not set -# CONFIG_PCIEAER_INJECT is not set -# CONFIG_PCIEASPM is not set -# CONFIG_PCIEPORTBUS is not set -# CONFIG_PCIE_AL is not set -# CONFIG_PCIE_ALTERA is not set -# CONFIG_PCIE_ARMADA_8K is not set -CONFIG_PCIE_BUS_DEFAULT=y -# CONFIG_PCIE_BUS_PEER2PEER is not set -# CONFIG_PCIE_BUS_PERFORMANCE is not set -# CONFIG_PCIE_BUS_SAFE is not set -# CONFIG_PCIE_BUS_TUNE_OFF is not set -# CONFIG_PCIE_BW is not set -# CONFIG_PCIE_CADENCE_HOST is not set -# CONFIG_PCIE_CADENCE_PLAT_HOST is not set -# CONFIG_PCIE_DPC is not set -# CONFIG_PCIE_DW_PLAT is not set -# CONFIG_PCIE_DW_PLAT_HOST is not set -# CONFIG_PCIE_ECRC is not set -# CONFIG_PCIE_IPROC is not set -# CONFIG_PCIE_KIRIN is not set -# CONFIG_PCIE_LAYERSCAPE_GEN4 is not set -# CONFIG_PCIE_MEDIATEK_GEN3 is not set -# CONFIG_PCIE_MICROCHIP_HOST is not set -# CONFIG_PCIE_PTM is not set -# CONFIG_PCIE_XILINX is not set -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_PCI_ATMEL is not set -# CONFIG_PCI_CNB20LE_QUIRK is not set -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set -# CONFIG_PCI_ENDPOINT is not set -# CONFIG_PCI_ENDPOINT_TEST is not set -# CONFIG_PCI_FTPCI100 is not set -# CONFIG_PCI_HERMES is not set -# CONFIG_PCI_HISI is not set -# CONFIG_PCI_HOST_GENERIC is not set -# CONFIG_PCI_HOST_THUNDER_ECAM is not set -# CONFIG_PCI_HOST_THUNDER_PEM is not set -# CONFIG_PCI_IOV is not set -# CONFIG_PCI_J721E_HOST is not set -# CONFIG_PCI_LAYERSCAPE is not set -# CONFIG_PCI_MESON is not set -# CONFIG_PCI_MSI is not set -# CONFIG_PCI_PASID is not set -# CONFIG_PCI_PF_STUB is not set -# CONFIG_PCI_PRI is not set -CONFIG_PCI_QUIRKS=y -# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set -# CONFIG_PCI_STUB is not set -# CONFIG_PCI_SW_SWITCHTEC is not set -CONFIG_PCI_SYSCALL=y -# CONFIG_PCI_V3_SEMI is not set -# CONFIG_PCI_XGENE is not set -# CONFIG_PCMCIA is not set -# CONFIG_PCMCIA_3C574 is not set -# CONFIG_PCMCIA_3C589 is not set -# CONFIG_PCMCIA_AHA152X is not set -# CONFIG_PCMCIA_ATMEL is not set -# CONFIG_PCMCIA_AXNET is not set -# CONFIG_PCMCIA_DEBUG is not set -# CONFIG_PCMCIA_FDOMAIN is not set -# CONFIG_PCMCIA_FMVJ18X is not set -# CONFIG_PCMCIA_HERMES is not set -# CONFIG_PCMCIA_LOAD_CIS is not set -# CONFIG_PCMCIA_NINJA_SCSI is not set -# CONFIG_PCMCIA_NMCLAN is not set -# CONFIG_PCMCIA_PCNET is not set -# CONFIG_PCMCIA_QLOGIC is not set -# CONFIG_PCMCIA_RAYCS is not set -# CONFIG_PCMCIA_SMC91C92 is not set -# CONFIG_PCMCIA_SPECTRUM is not set -# CONFIG_PCMCIA_SYM53C500 is not set -# CONFIG_PCMCIA_WL3501 is not set -# CONFIG_PCMCIA_XIRC2PS is not set -# CONFIG_PCMCIA_XIRCOM is not set -# CONFIG_PCNET32 is not set -# CONFIG_PCPU_DEV_REFCNT is not set -# CONFIG_PCSPKR_PLATFORM is not set -# CONFIG_PCS_XPCS is not set -# CONFIG_PD6729 is not set -# CONFIG_PDA_POWER is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_PERCPU_STATS is not set -# CONFIG_PERCPU_TEST is not set -# CONFIG_PERF_EVENTS is not set -# CONFIG_PERF_EVENTS_AMD_POWER is not set -# CONFIG_PERSISTENT_KEYRINGS is not set -# CONFIG_PHANTOM is not set -# CONFIG_PHONET is not set -# CONFIG_PHYLIB is not set -# CONFIG_PHYS_ADDR_T_64BIT is not set -# CONFIG_PHY_CADENCE_DP is not set -# CONFIG_PHY_CADENCE_DPHY is not set -# CONFIG_PHY_CADENCE_SALVO is not set -# CONFIG_PHY_CADENCE_SIERRA is not set -# CONFIG_PHY_CADENCE_TORRENT is not set -# CONFIG_PHY_CAN_TRANSCEIVER is not set -# CONFIG_PHY_CPCAP_USB is not set -# CONFIG_PHY_EXYNOS_DP_VIDEO is not set -# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set -# CONFIG_PHY_FSL_IMX8MQ_USB is not set -# CONFIG_PHY_INGENIC_USB is not set -# CONFIG_PHY_INTEL_KEEMBAY_EMMC is not set -# CONFIG_PHY_MAPPHONE_MDM6600 is not set -# CONFIG_PHY_MIXEL_MIPI_DPHY is not set -# CONFIG_PHY_MTK_HDMI is not set -# CONFIG_PHY_MTK_MIPI_DSI is not set -# CONFIG_PHY_MVEBU_CP110_UTMI is not set -# CONFIG_PHY_OCELOT_SERDES is not set -# CONFIG_PHY_PISTACHIO_USB is not set -# CONFIG_PHY_PXA_28NM_HSIC is not set -# CONFIG_PHY_PXA_28NM_USB2 is not set -# CONFIG_PHY_QCOM_DWC3 is not set -# CONFIG_PHY_QCOM_USB_HS is not set -# CONFIG_PHY_QCOM_USB_HSIC is not set -# CONFIG_PHY_SAMSUNG_USB2 is not set -# CONFIG_PHY_TUSB1210 is not set -# CONFIG_PHY_XGENE is not set -# CONFIG_PI433 is not set -# CONFIG_PID_IN_CONTEXTIDR is not set -# CONFIG_PID_NS is not set -CONFIG_PINCONF=y -# CONFIG_PINCTRL is not set -# CONFIG_PINCTRL_AMD is not set -# CONFIG_PINCTRL_AXP209 is not set -# CONFIG_PINCTRL_CEDARFORK is not set -# CONFIG_PINCTRL_EXYNOS is not set -# CONFIG_PINCTRL_EXYNOS5440 is not set -# CONFIG_PINCTRL_ICELAKE is not set -# CONFIG_PINCTRL_INGENIC is not set -# CONFIG_PINCTRL_LPASS_LPI is not set -# CONFIG_PINCTRL_MCP23S08 is not set -# CONFIG_PINCTRL_MDM9607 is not set -# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set -# CONFIG_PINCTRL_MSM8953 is not set -# CONFIG_PINCTRL_MSM8X74 is not set -# CONFIG_PINCTRL_MT6779 is not set -# CONFIG_PINCTRL_MT8167 is not set -# CONFIG_PINCTRL_MT8192 is not set -# CONFIG_PINCTRL_MT8195 is not set -# CONFIG_PINCTRL_MT8365 is not set -# CONFIG_PINCTRL_MTK_V2 is not set -# CONFIG_PINCTRL_OCELOT is not set -# CONFIG_PINCTRL_PISTACHIO is not set -# CONFIG_PINCTRL_SC7280 is not set -# CONFIG_PINCTRL_SC8180X is not set -# CONFIG_PINCTRL_SDX55 is not set -CONFIG_PINCTRL_SINGLE=y -# CONFIG_PINCTRL_SM6115 is not set -# CONFIG_PINCTRL_SM6125 is not set -# CONFIG_PINCTRL_SM8350 is not set -# CONFIG_PINCTRL_STMFX is not set -# CONFIG_PINCTRL_SX150X is not set -# CONFIG_PING is not set -CONFIG_PINMUX=y -# CONFIG_PKCS7_MESSAGE_PARSER is not set -# CONFIG_PL310_ERRATA_588369 is not set -# CONFIG_PL310_ERRATA_727915 is not set -# CONFIG_PL310_ERRATA_753970 is not set -# CONFIG_PL310_ERRATA_769419 is not set -# CONFIG_PL320_MBOX is not set -# CONFIG_PL330_DMA is not set -# CONFIG_PLATFORM_MHU is not set -# CONFIG_PLAT_SPEAR is not set -# CONFIG_PLIP is not set -# CONFIG_PLX_DMA is not set -# CONFIG_PLX_HERMES is not set -# CONFIG_PM is not set -# CONFIG_PMBUS is not set -# CONFIG_PMC_MSP is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_PMS7003 is not set -# CONFIG_PM_AUTOSLEEP is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_DEVFREQ is not set -# CONFIG_PM_WAKELOCKS is not set -# CONFIG_POSIX_MQUEUE is not set -CONFIG_POSIX_TIMERS=y -# CONFIG_POWERCAP is not set -# CONFIG_POWER_AVS is not set -# CONFIG_POWER_RESET is not set -# CONFIG_POWER_RESET_BRCMKONA is not set -# CONFIG_POWER_RESET_BRCMSTB is not set -# CONFIG_POWER_RESET_GPIO is not set -# CONFIG_POWER_RESET_GPIO_RESTART is not set -# CONFIG_POWER_RESET_LINKSTATION is not set -# CONFIG_POWER_RESET_LTC2952 is not set -# CONFIG_POWER_RESET_PIIX4_POWEROFF is not set -# CONFIG_POWER_RESET_QNAP is not set -# CONFIG_POWER_RESET_REGULATOR is not set -# CONFIG_POWER_RESET_RESTART is not set -# CONFIG_POWER_RESET_SYSCON is not set -# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -# CONFIG_POWER_RESET_VERSATILE is not set -# CONFIG_POWER_RESET_XGENE is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_POWER_SUPPLY_HWMON is not set -# CONFIG_PPC4xx_GPIO is not set -# CONFIG_PPC_16K_PAGES is not set -# CONFIG_PPC_256K_PAGES is not set -CONFIG_PPC_4K_PAGES=y -# CONFIG_PPC_64K_PAGES is not set -# CONFIG_PPC_DISABLE_WERROR is not set -# CONFIG_PPC_EMULATED_STATS is not set -# CONFIG_PPC_EPAPR_HV_BYTECHAN is not set -# CONFIG_PPC_QUEUED_SPINLOCKS is not set -# CONFIG_PPP is not set -# CONFIG_PPPOATM is not set -# CONFIG_PPPOE is not set -# CONFIG_PPPOL2TP is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_DEFLATE is not set -CONFIG_PPP_FILTER=y -# CONFIG_PPP_MPPE is not set -CONFIG_PPP_MULTILINK=y -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPS is not set -# CONFIG_PPS_CLIENT_GPIO is not set -# CONFIG_PPS_CLIENT_KTIMER is not set -# CONFIG_PPS_CLIENT_LDISC is not set -# CONFIG_PPS_CLIENT_PARPORT is not set -# CONFIG_PPS_DEBUG is not set -# CONFIG_PPTP is not set -# CONFIG_PREEMPT is not set -# CONFIG_PREEMPTIRQ_DELAY_TEST is not set -# CONFIG_PREEMPTIRQ_EVENTS is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PRESTERA is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_PRIME_NUMBERS is not set -CONFIG_PRINTK=y -# CONFIG_PRINTK_CALLER is not set -# CONFIG_PRINTK_INDEX is not set -CONFIG_PRINTK_NMI=y -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 -# CONFIG_PRINTK_TIME is not set -CONFIG_PRINT_STACK_DEPTH=64 -# CONFIG_PRISM2_USB is not set -# CONFIG_PRISM54 is not set -# CONFIG_PROC_CHILDREN is not set -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -# CONFIG_PROC_PAGE_MONITOR is not set -# CONFIG_PROC_STRIPPED is not set -CONFIG_PROC_SYSCTL=y -# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILING is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_PROVE_RAW_LOCK_NESTING is not set -# CONFIG_PROVE_RCU is not set -# CONFIG_PROVE_RCU_LIST is not set -# CONFIG_PROVE_RCU_REPEATEDLY is not set -# CONFIG_PSAMPLE is not set -# CONFIG_PSB6970_PHY is not set -# CONFIG_PSI is not set -# CONFIG_PSTORE is not set -# CONFIG_PSTORE_842_COMPRESS is not set -# CONFIG_PSTORE_BLK is not set -# CONFIG_PSTORE_COMPRESS is not set -# CONFIG_PSTORE_CONSOLE is not set -CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 -# CONFIG_PSTORE_DEFLATE_COMPRESS is not set -# CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT is not set -# CONFIG_PSTORE_FTRACE is not set -# CONFIG_PSTORE_LZ4HC_COMPRESS is not set -# CONFIG_PSTORE_LZ4_COMPRESS is not set -# CONFIG_PSTORE_LZO_COMPRESS is not set -# CONFIG_PSTORE_PMSG is not set -# CONFIG_PSTORE_RAM is not set -# CONFIG_PSTORE_ZSTD_COMPRESS is not set -# CONFIG_PTDUMP_DEBUGFS is not set -# CONFIG_PTP_1588_CLOCK is not set -# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set -# CONFIG_PTP_1588_CLOCK_IDTCM is not set -# CONFIG_PTP_1588_CLOCK_IXP46X is not set -# CONFIG_PTP_1588_CLOCK_KVM is not set -# CONFIG_PTP_1588_CLOCK_OCP is not set -# CONFIG_PTP_1588_CLOCK_PCH is not set -# CONFIG_PTP_1588_CLOCK_VMW is not set -# CONFIG_PUBLIC_KEY_ALGO_RSA is not set -# CONFIG_PVPANIC is not set -# CONFIG_PWM is not set -# CONFIG_PWM_ATMEL_TCB is not set -# CONFIG_PWM_DEBUG is not set -# CONFIG_PWM_DWC is not set -# CONFIG_PWM_FSL_FTM is not set -# CONFIG_PWM_IMG is not set -# CONFIG_PWM_JZ4740 is not set -# CONFIG_PWM_MEDIATEK is not set -# CONFIG_PWM_PCA9685 is not set -# CONFIG_PWM_RASPBERRYPI_POE is not set -CONFIG_PWRSEQ_EMMC=y -# CONFIG_PWRSEQ_SD8787 is not set -CONFIG_PWRSEQ_SIMPLE=y -# CONFIG_QCA7000 is not set -# CONFIG_QCA7000_SPI is not set -# CONFIG_QCA7000_UART is not set -# CONFIG_QCOM_A7PLL is not set -# CONFIG_QCOM_EMAC is not set -# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set -# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set -# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set -# CONFIG_QCOM_GPI_DMA is not set -# CONFIG_QCOM_HIDMA is not set -# CONFIG_QCOM_HIDMA_MGMT is not set -# CONFIG_QCOM_LMH is not set -# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set -# CONFIG_QCOM_SPMI_ADC5 is not set -# CONFIG_QCOM_SPMI_ADC_TM5 is not set -# CONFIG_QCOM_SPMI_IADC is not set -# CONFIG_QCOM_SPMI_TEMP_ALARM is not set -# CONFIG_QCOM_SPMI_VADC is not set -# CONFIG_QED is not set -# CONFIG_QFMT_V1 is not set -# CONFIG_QLA3XXX is not set -# CONFIG_QLCNIC is not set -# CONFIG_QLGE is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX6FS_FS is not set -# CONFIG_QORIQ_CPUFREQ is not set -# CONFIG_QORIQ_THERMAL is not set -# CONFIG_QRTR is not set -# CONFIG_QRTR_MHI is not set -# CONFIG_QRTR_TUN is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_QUEUED_LOCK_STAT is not set -# CONFIG_QUICC_ENGINE is not set -# CONFIG_QUOTA is not set -# CONFIG_QUOTACTL is not set -# CONFIG_QUOTA_DEBUG is not set -# CONFIG_QUOTA_NETLINK_INTERFACE is not set -# CONFIG_R3964 is not set -# CONFIG_R6040 is not set -# CONFIG_R8169 is not set -# CONFIG_R8188EU is not set -# CONFIG_R8712U is not set -# CONFIG_R8723AU is not set -# CONFIG_RADIO_ADAPTERS is not set -# CONFIG_RADIO_AZTECH is not set -# CONFIG_RADIO_CADET is not set -# CONFIG_RADIO_GEMTEK is not set -# CONFIG_RADIO_MAXIRADIO is not set -# CONFIG_RADIO_RTRACK is not set -# CONFIG_RADIO_RTRACK2 is not set -# CONFIG_RADIO_SF16FMI is not set -# CONFIG_RADIO_SF16FMR2 is not set -# CONFIG_RADIO_TERRATEC is not set -# CONFIG_RADIO_TRUST is not set -# CONFIG_RADIO_TYPHOON is not set -# CONFIG_RADIO_ZOLTRIX is not set -# CONFIG_RAID6_PQ_BENCHMARK is not set -# CONFIG_RAID_ATTRS is not set -# CONFIG_RALINK is not set -# CONFIG_RANDOM32_SELFTEST is not set -# CONFIG_RANDOMIZE_BASE is not set -# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set -CONFIG_RANDOM_TRUST_BOOTLOADER=y -CONFIG_RANDOM_TRUST_CPU=y -# CONFIG_RAPIDIO is not set -# CONFIG_RAS is not set -# CONFIG_RBTREE_TEST is not set -# CONFIG_RCU_BOOST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_RCU_EQS_DEBUG is not set -# CONFIG_RCU_EXPEDITE_BOOT is not set -# CONFIG_RCU_EXPERT is not set -CONFIG_RCU_KTHREAD_PRIO=0 -CONFIG_RCU_NEED_SEGCBLIST=y -# CONFIG_RCU_PERF_TEST is not set -# CONFIG_RCU_REF_SCALE_TEST is not set -# CONFIG_RCU_SCALE_TEST is not set -CONFIG_RCU_STALL_COMMON=y -# CONFIG_RCU_STRICT_GRACE_PERIOD is not set -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 -# CONFIG_RCU_TRACE is not set -# CONFIG_RC_ATI_REMOTE is not set -# CONFIG_RC_CORE is not set -# CONFIG_RC_DECODERS is not set -# CONFIG_RC_LOOPBACK is not set -# CONFIG_RC_MAP is not set -# CONFIG_RC_XBOX_DVD is not set -# CONFIG_RDS is not set -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_GZIP is not set -# CONFIG_RD_LZ4 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_LZO is not set -# CONFIG_RD_XZ is not set -# CONFIG_RD_ZSTD is not set -# CONFIG_READABLE_ASM is not set -# CONFIG_READ_ONLY_THP_FOR_FS is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_REDWOOD is not set -# CONFIG_REED_SOLOMON is not set -# CONFIG_REED_SOLOMON_DEC8 is not set -# CONFIG_REED_SOLOMON_ENC8 is not set -# CONFIG_REED_SOLOMON_TEST is not set -# CONFIG_REGMAP is not set -# CONFIG_REGMAP_I2C is not set -# CONFIG_REGMAP_MMIO is not set -# CONFIG_REGMAP_SPI is not set -# CONFIG_REGULATOR is not set -# CONFIG_REGULATOR_88PG86X is not set -# CONFIG_REGULATOR_ACT8865 is not set -# CONFIG_REGULATOR_AD5398 is not set -# CONFIG_REGULATOR_ANATOP is not set -# CONFIG_REGULATOR_DA9121 is not set -# CONFIG_REGULATOR_DA9210 is not set -# CONFIG_REGULATOR_DA9211 is not set -# CONFIG_REGULATOR_DEBUG is not set -# CONFIG_REGULATOR_FAN53555 is not set -# CONFIG_REGULATOR_FAN53880 is not set -# CONFIG_REGULATOR_FIXED_VOLTAGE is not set -# CONFIG_REGULATOR_GPIO is not set -# CONFIG_REGULATOR_ISL6271A is not set -# CONFIG_REGULATOR_ISL9305 is not set -# CONFIG_REGULATOR_LP3971 is not set -# CONFIG_REGULATOR_LP3972 is not set -# CONFIG_REGULATOR_LP872X is not set -# CONFIG_REGULATOR_LP8755 is not set -# CONFIG_REGULATOR_LTC3589 is not set -# CONFIG_REGULATOR_LTC3676 is not set -# CONFIG_REGULATOR_MAX1586 is not set -# CONFIG_REGULATOR_MAX77620 is not set -# CONFIG_REGULATOR_MAX77826 is not set -# CONFIG_REGULATOR_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8893 is not set -# CONFIG_REGULATOR_MAX8952 is not set -# CONFIG_REGULATOR_MAX8973 is not set -# CONFIG_REGULATOR_MCP16502 is not set -# CONFIG_REGULATOR_MP5416 is not set -# CONFIG_REGULATOR_MP8859 is not set -# CONFIG_REGULATOR_MP886X is not set -# CONFIG_REGULATOR_MPQ7920 is not set -# CONFIG_REGULATOR_MT6311 is not set -# CONFIG_REGULATOR_MT6315 is not set -# CONFIG_REGULATOR_MT6359 is not set -# CONFIG_REGULATOR_PCA9450 is not set -# CONFIG_REGULATOR_PF8X00 is not set -# CONFIG_REGULATOR_PFUZE100 is not set -# CONFIG_REGULATOR_PV88060 is not set -# CONFIG_REGULATOR_PV88080 is not set -# CONFIG_REGULATOR_PV88090 is not set -# CONFIG_REGULATOR_PWM is not set -# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set -# CONFIG_REGULATOR_RT4801 is not set -# CONFIG_REGULATOR_RT6160 is not set -# CONFIG_REGULATOR_RT6245 is not set -# CONFIG_REGULATOR_RTMV20 is not set -# CONFIG_REGULATOR_RTQ2134 is not set -# CONFIG_REGULATOR_RTQ6752 is not set -# CONFIG_REGULATOR_SLG51000 is not set -# CONFIG_REGULATOR_SY8106A is not set -# CONFIG_REGULATOR_SY8824X is not set -# CONFIG_REGULATOR_SY8827N is not set -# CONFIG_REGULATOR_TI_ABB is not set -# CONFIG_REGULATOR_TPS51632 is not set -# CONFIG_REGULATOR_TPS62360 is not set -# CONFIG_REGULATOR_TPS65023 is not set -# CONFIG_REGULATOR_TPS6507X is not set -# CONFIG_REGULATOR_TPS65132 is not set -# CONFIG_REGULATOR_TPS6524X is not set -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -# CONFIG_REGULATOR_VCTRL is not set -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_FS_POSIX_ACL is not set -# CONFIG_REISERFS_FS_SECURITY is not set -CONFIG_REISERFS_FS_XATTR=y -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_RELAY is not set -# CONFIG_RELOCATABLE is not set -CONFIG_RELR=y -# CONFIG_REMOTEPROC is not set -# CONFIG_RENESAS_PHY is not set -# CONFIG_RESET_ATH79 is not set -# CONFIG_RESET_BERLIN is not set -# CONFIG_RESET_BRCMSTB_RESCAL is not set -# CONFIG_RESET_CONTROLLER is not set -# CONFIG_RESET_IMX7 is not set -# CONFIG_RESET_INTEL_GW is not set -# CONFIG_RESET_LANTIQ is not set -# CONFIG_RESET_LPC18XX is not set -# CONFIG_RESET_MESON is not set -# CONFIG_RESET_PISTACHIO is not set -# CONFIG_RESET_SOCFPGA is not set -# CONFIG_RESET_STM32 is not set -# CONFIG_RESET_SUNXI is not set -# CONFIG_RESET_TEGRA_BPMP is not set -# CONFIG_RESET_TI_SYSCON is not set -# CONFIG_RESET_ZYNQ is not set -# CONFIG_RFD77402 is not set -# CONFIG_RFD_FTL is not set -CONFIG_RFKILL=y -# CONFIG_RFKILL_FULL is not set -# CONFIG_RFKILL_GPIO is not set -# CONFIG_RFKILL_INPUT is not set -# CONFIG_RFKILL_LEDS is not set -# CONFIG_RFKILL_REGULATOR is not set -# CONFIG_RING_BUFFER_BENCHMARK is not set -# CONFIG_RING_BUFFER_STARTUP_TEST is not set -# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set -# CONFIG_RMI4_CORE is not set -# CONFIG_RMNET is not set -# CONFIG_ROCKCHIP_PHY is not set -# CONFIG_ROCKER is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_ROSE is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPMSG_QCOM_GLINK_RPM is not set -# CONFIG_RPMSG_VIRTIO is not set -# CONFIG_RPMSG_WWAN_CTRL is not set -# CONFIG_RPR0521 is not set -# CONFIG_RSEQ is not set -# CONFIG_RT2X00 is not set -# CONFIG_RTC_CLASS is not set -# CONFIG_RTC_DEBUG is not set -# CONFIG_RTC_DRV_ABB5ZES3 is not set -# CONFIG_RTC_DRV_ABEOZ9 is not set -# CONFIG_RTC_DRV_ABX80X is not set -# CONFIG_RTC_DRV_ARMADA38X is not set -# CONFIG_RTC_DRV_AU1XXX is not set -# CONFIG_RTC_DRV_BQ32K is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_CADENCE is not set -CONFIG_RTC_DRV_CMOS=y -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1302 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1307_CENTURY is not set -# CONFIG_RTC_DRV_DS1307_HWMON is not set -# CONFIG_RTC_DRV_DS1343 is not set -# CONFIG_RTC_DRV_DS1347 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS1685_FAMILY is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_DS2404 is not set -# CONFIG_RTC_DRV_DS3232 is not set -# CONFIG_RTC_DRV_DS3234 is not set -# CONFIG_RTC_DRV_EM3027 is not set -# CONFIG_RTC_DRV_EP93XX is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_FTRTC010 is not set -# CONFIG_RTC_DRV_GENERIC is not set -# CONFIG_RTC_DRV_GOLDFISH is not set -# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -# CONFIG_RTC_DRV_HYM8563 is not set -# CONFIG_RTC_DRV_ISL12022 is not set -# CONFIG_RTC_DRV_ISL12026 is not set -# CONFIG_RTC_DRV_ISL12057 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_JZ4740 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_M41T93 is not set -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_MAX6916 is not set -# CONFIG_RTC_DRV_MAX77686 is not set -# CONFIG_RTC_DRV_MCP795 is not set -# CONFIG_RTC_DRV_MOXART is not set -# CONFIG_RTC_DRV_MPC5121 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_MT2712 is not set -# CONFIG_RTC_DRV_OMAP is not set -# CONFIG_RTC_DRV_PCF2123 is not set -# CONFIG_RTC_DRV_PCF2127 is not set -# CONFIG_RTC_DRV_PCF85063 is not set -# CONFIG_RTC_DRV_PCF8523 is not set -# CONFIG_RTC_DRV_PCF85363 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_PL030 is not set -# CONFIG_RTC_DRV_PL031 is not set -# CONFIG_RTC_DRV_PS3 is not set -# CONFIG_RTC_DRV_PT7C4338 is not set -# CONFIG_RTC_DRV_R7301 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_RTC7301 is not set -# CONFIG_RTC_DRV_RV3028 is not set -# CONFIG_RTC_DRV_RV3029C2 is not set -# CONFIG_RTC_DRV_RV3032 is not set -# CONFIG_RTC_DRV_RV8803 is not set -# CONFIG_RTC_DRV_RX4581 is not set -# CONFIG_RTC_DRV_RX6110 is not set -# CONFIG_RTC_DRV_RX8010 is not set -# CONFIG_RTC_DRV_RX8025 is not set -# CONFIG_RTC_DRV_RX8581 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_SD3078 is not set -# CONFIG_RTC_DRV_SNVS is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_SUN6I is not set -# CONFIG_RTC_DRV_TEGRA is not set -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_XGENE is not set -# CONFIG_RTC_DRV_ZYNQMP is not set -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_LIB=y -# CONFIG_RTC_NVMEM is not set -CONFIG_RTC_SYSTOHC=y -CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -# CONFIG_RTL8180 is not set -# CONFIG_RTL8187 is not set -# CONFIG_RTL8192E is not set -# CONFIG_RTL8192U is not set -# CONFIG_RTL8306_PHY is not set -# CONFIG_RTL8366RB_PHY is not set -# CONFIG_RTL8366S_PHY is not set -# CONFIG_RTL8366_SMI is not set -# CONFIG_RTL8366_SMI_DEBUG_FS is not set -# CONFIG_RTL8367B_PHY is not set -# CONFIG_RTL8367_PHY is not set -# CONFIG_RTLLIB is not set -# CONFIG_RTL_CARDS is not set -# CONFIG_RTS5208 is not set -CONFIG_RT_MUTEXES=y -# CONFIG_RUNTIME_DEBUG is not set -CONFIG_RUNTIME_TESTING_MENU=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_RXKAD=y -# CONFIG_S2IO is not set -# CONFIG_SAMPLES is not set -# CONFIG_SAMSUNG_LAPTOP is not set -# CONFIG_SATA_ACARD_AHCI is not set -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_AHCI_PLATFORM is not set -# CONFIG_SATA_DWC is not set -# CONFIG_SATA_DWC_DEBUG is not set -# CONFIG_SATA_DWC_OLD_DMA is not set -# CONFIG_SATA_FSL is not set -# CONFIG_SATA_HIGHBANK is not set -# CONFIG_SATA_HOST is not set -# CONFIG_SATA_INIC162X is not set -CONFIG_SATA_MOBILE_LPM_POLICY=0 -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_SATA_PMP is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_RCAR is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_SVW is not set -# CONFIG_SATA_SX4 is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_SBC_FITPC2_WATCHDOG is not set -CONFIG_SBITMAP=y -# CONFIG_SC92031 is not set -# CONFIG_SCA3000 is not set -# CONFIG_SCA3300 is not set -# CONFIG_SCACHE_DEBUGFS is not set -# CONFIG_SCC is not set -# CONFIG_SCD30_CORE is not set -# CONFIG_SCF_TORTURE_TEST is not set -# CONFIG_SCHEDSTATS is not set -# CONFIG_SCHED_AUTOGROUP is not set -# CONFIG_SCHED_DEBUG is not set -CONFIG_SCHED_HRTICK=y -# CONFIG_SCHED_MC is not set -CONFIG_SCHED_OMIT_FRAME_POINTER=y -# CONFIG_SCHED_SMT is not set -CONFIG_SCHED_STACK_END_CHECK=y -# CONFIG_SCHED_TRACER is not set -# CONFIG_SCR24X is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_3W_SAS is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_SCSI_BFA_FC is not set -# CONFIG_SCSI_BNX2X_FCOE is not set -# CONFIG_SCSI_BNX2_ISCSI is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CHELSIO_FCOE is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_CXGB3_ISCSI is not set -# CONFIG_SCSI_CXGB4_ISCSI is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_DH is not set -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_ESAS2R is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_FDOMAIN_PCI is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set -# CONFIG_SCSI_HISI_SAS is not set -# CONFIG_SCSI_HPSA is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_ISCI is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_LOGGING is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set -# CONFIG_SCSI_LPFC is not set -CONFIG_SCSI_MOD=y -# CONFIG_SCSI_MPI3MR is not set -# CONFIG_SCSI_MPT2SAS is not set -# CONFIG_SCSI_MPT3SAS is not set -# CONFIG_SCSI_MQ_DEFAULT is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_MVSAS_DEBUG is not set -# CONFIG_SCSI_MVUMI is not set -# CONFIG_SCSI_MYRB is not set -# CONFIG_SCSI_MYRS is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_OSD_INITIATOR is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PM8001 is not set -# CONFIG_SCSI_PMCRAID is not set -CONFIG_SCSI_PROC_FS=y -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -# CONFIG_SCSI_SMARTPQI is not set -# CONFIG_SCSI_SNIC is not set -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_UFSHCD is not set -# CONFIG_SCSI_ULTRASTOR is not set -# CONFIG_SCSI_VIRTIO is not set -# CONFIG_SCSI_WD719X is not set -# CONFIG_SC_CAMCC_7180 is not set -# CONFIG_SC_DISPCC_7280 is not set -# CONFIG_SC_GCC_7280 is not set -# CONFIG_SC_GCC_8180X is not set -# CONFIG_SC_GPUCC_7280 is not set -# CONFIG_SC_VIDEOCC_7280 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_SDIO_UART is not set -# CONFIG_SDM_GPUCC_660 is not set -# CONFIG_SDM_MMCC_660 is not set -# CONFIG_SDR_MAX2175 is not set -# CONFIG_SDR_PLATFORM_DRIVERS is not set -# CONFIG_SDX_GCC_55 is not set -# CONFIG_SD_ADC_MODULATOR is not set -# CONFIG_SECCOMP is not set -# CONFIG_SECCOMP_CACHE_DEBUG is not set -CONFIG_SECTION_MISMATCH_WARN_ONLY=y -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_APPARMOR is not set -CONFIG_SECURITY_DMESG_RESTRICT=y -# CONFIG_SECURITY_LANDLOCK is not set -# CONFIG_SECURITY_LOADPIN is not set -# CONFIG_SECURITY_LOCKDOWN_LSM is not set -# CONFIG_SECURITY_NETWORK_XFRM is not set -# CONFIG_SECURITY_PATH is not set -# CONFIG_SECURITY_SAFESETID is not set -# CONFIG_SECURITY_SELINUX_AVC_STATS is not set -# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set -CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0 -# CONFIG_SECURITY_SELINUX_DEVELOP is not set -# CONFIG_SECURITY_SELINUX_DISABLE is not set -# CONFIG_SECURITY_SMACK is not set -# CONFIG_SECURITY_TOMOYO is not set -# CONFIG_SECURITY_YAMA is not set -CONFIG_SELECT_MEMORY_MODEL=y -# CONFIG_SENSIRION_SGP30 is not set -# CONFIG_SENSIRION_SGP40 is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ABITUGURU3 is not set -# CONFIG_SENSORS_ACPI_POWER is not set -# CONFIG_SENSORS_AD7314 is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADC128D818 is not set -# CONFIG_SENSORS_ADCXX is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM1177 is not set -# CONFIG_SENSORS_ADM1266 is not set -# CONFIG_SENSORS_ADM1275 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADS1015 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_ADS7871 is not set -# CONFIG_SENSORS_ADT7310 is not set -# CONFIG_SENSORS_ADT7410 is not set -# CONFIG_SENSORS_ADT7411 is not set -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7475 is not set -# CONFIG_SENSORS_AHT10 is not set -# CONFIG_SENSORS_AMC6821 is not set -# CONFIG_SENSORS_APDS990X is not set -# CONFIG_SENSORS_APPLESMC is not set -# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set -# CONFIG_SENSORS_AS370 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ASC7621 is not set -# CONFIG_SENSORS_ASPEED is not set -# CONFIG_SENSORS_ATK0110 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_AXI_FAN_CONTROL is not set -# CONFIG_SENSORS_BEL_PFE is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_BPA_RS600 is not set -# CONFIG_SENSORS_CORETEMP is not set -# CONFIG_SENSORS_CORSAIR_CPRO is not set -# CONFIG_SENSORS_CORSAIR_PSU is not set -# CONFIG_SENSORS_DELL_SMM is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_DPS920AB is not set -# CONFIG_SENSORS_DRIVETEMP is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_DS620 is not set -# CONFIG_SENSORS_EMC1403 is not set -# CONFIG_SENSORS_EMC2103 is not set -# CONFIG_SENSORS_EMC2305 is not set -# CONFIG_SENSORS_EMC6W201 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_FAM15H_POWER is not set -# CONFIG_SENSORS_FSCHMD is not set -# CONFIG_SENSORS_FSP_3Y is not set -# CONFIG_SENSORS_FTSTEUTATES is not set -# CONFIG_SENSORS_G760A is not set -# CONFIG_SENSORS_G762 is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_GPIO_FAN is not set -# CONFIG_SENSORS_GSC is not set -# CONFIG_SENSORS_HDAPS is not set -# CONFIG_SENSORS_HIH6130 is not set -# CONFIG_SENSORS_HMC5843 is not set -# CONFIG_SENSORS_HMC5843_I2C is not set -# CONFIG_SENSORS_HMC5843_SPI is not set -# CONFIG_SENSORS_HTU21 is not set -# CONFIG_SENSORS_I5500 is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_IBM_CFFPS is not set -# CONFIG_SENSORS_IIO_HWMON is not set -# CONFIG_SENSORS_INA209 is not set -# CONFIG_SENSORS_INA2XX is not set -# CONFIG_SENSORS_INA3221 is not set -# CONFIG_SENSORS_INSPUR_IPSPS is not set -# CONFIG_SENSORS_IR35221 is not set -# CONFIG_SENSORS_IR36021 is not set -# CONFIG_SENSORS_IR38064 is not set -# CONFIG_SENSORS_IRPS5401 is not set -# CONFIG_SENSORS_ISL29018 is not set -# CONFIG_SENSORS_ISL29028 is not set -# CONFIG_SENSORS_ISL68137 is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_JC42 is not set -# CONFIG_SENSORS_K10TEMP is not set -# CONFIG_SENSORS_K8TEMP is not set -# CONFIG_SENSORS_LINEAGE is not set -# CONFIG_SENSORS_LIS3LV02D is not set -# CONFIG_SENSORS_LIS3_I2C is not set -# CONFIG_SENSORS_LIS3_SPI is not set -# CONFIG_SENSORS_LM25066 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM73 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_LM95234 is not set -# CONFIG_SENSORS_LM95241 is not set -# CONFIG_SENSORS_LM95245 is not set -# CONFIG_SENSORS_LTC2945 is not set -# CONFIG_SENSORS_LTC2947_I2C is not set -# CONFIG_SENSORS_LTC2947_SPI is not set -# CONFIG_SENSORS_LTC2978 is not set -# CONFIG_SENSORS_LTC2990 is not set -# CONFIG_SENSORS_LTC2992 is not set -# CONFIG_SENSORS_LTC3815 is not set -# CONFIG_SENSORS_LTC4151 is not set -# CONFIG_SENSORS_LTC4215 is not set -# CONFIG_SENSORS_LTC4222 is not set -# CONFIG_SENSORS_LTC4245 is not set -# CONFIG_SENSORS_LTC4260 is not set -# CONFIG_SENSORS_LTC4261 is not set -# CONFIG_SENSORS_LTQ_CPUTEMP is not set -# CONFIG_SENSORS_MAX1111 is not set -# CONFIG_SENSORS_MAX127 is not set -# CONFIG_SENSORS_MAX15301 is not set -# CONFIG_SENSORS_MAX16064 is not set -# CONFIG_SENSORS_MAX16065 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX16601 is not set -# CONFIG_SENSORS_MAX1668 is not set -# CONFIG_SENSORS_MAX197 is not set -# CONFIG_SENSORS_MAX20730 is not set -# CONFIG_SENSORS_MAX20751 is not set -# CONFIG_SENSORS_MAX31722 is not set -# CONFIG_SENSORS_MAX31730 is not set -# CONFIG_SENSORS_MAX31785 is not set -# CONFIG_SENSORS_MAX31790 is not set -# CONFIG_SENSORS_MAX34440 is not set -# CONFIG_SENSORS_MAX6621 is not set -# CONFIG_SENSORS_MAX6639 is not set -# CONFIG_SENSORS_MAX6642 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_MAX6697 is not set -# CONFIG_SENSORS_MAX8688 is not set -# CONFIG_SENSORS_MCP3021 is not set -# CONFIG_SENSORS_MP2888 is not set -# CONFIG_SENSORS_MP2975 is not set -# CONFIG_SENSORS_MR75203 is not set -# CONFIG_SENSORS_NCT6683 is not set -# CONFIG_SENSORS_NCT6775 is not set -# CONFIG_SENSORS_NCT7802 is not set -# CONFIG_SENSORS_NCT7904 is not set -# CONFIG_SENSORS_NPCM7XX is not set -# CONFIG_SENSORS_NSA320 is not set -# CONFIG_SENSORS_NTC_THERMISTOR is not set -# CONFIG_SENSORS_NZXT_KRAKEN2 is not set -# CONFIG_SENSORS_OCC_P8_I2C is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_PIM4328 is not set -# CONFIG_SENSORS_PM6764TR is not set -# CONFIG_SENSORS_PMBUS is not set -# CONFIG_SENSORS_POWR1220 is not set -# CONFIG_SENSORS_PWM_FAN is not set -# CONFIG_SENSORS_PXE1610 is not set -# CONFIG_SENSORS_Q54SJ108A2 is not set -# CONFIG_SENSORS_RM3100_I2C is not set -# CONFIG_SENSORS_RM3100_SPI is not set -# CONFIG_SENSORS_SBRMI is not set -# CONFIG_SENSORS_SBTSI is not set -# CONFIG_SENSORS_SCH5627 is not set -# CONFIG_SENSORS_SCH5636 is not set -# CONFIG_SENSORS_SCH56XX_COMMON is not set -# CONFIG_SENSORS_SHT15 is not set -# CONFIG_SENSORS_SHT21 is not set -# CONFIG_SENSORS_SHT3x is not set -# CONFIG_SENSORS_SHT4x is not set -# CONFIG_SENSORS_SHTC1 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMM665 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_STPDDC60 is not set -# CONFIG_SENSORS_STTS751 is not set -# CONFIG_SENSORS_TC654 is not set -# CONFIG_SENSORS_TC74 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_TMP102 is not set -# CONFIG_SENSORS_TMP103 is not set -# CONFIG_SENSORS_TMP108 is not set -# CONFIG_SENSORS_TMP401 is not set -# CONFIG_SENSORS_TMP421 is not set -# CONFIG_SENSORS_TMP513 is not set -# CONFIG_SENSORS_TPS23861 is not set -# CONFIG_SENSORS_TPS40422 is not set -# CONFIG_SENSORS_TPS53679 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_TSL2563 is not set -# CONFIG_SENSORS_UCD9000 is not set -# CONFIG_SENSORS_UCD9200 is not set -# CONFIG_SENSORS_VEXPRESS is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VIA_CPUTEMP is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83773G is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83795 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_XDPE122 is not set -# CONFIG_SENSORS_XGENE is not set -# CONFIG_SENSORS_ZL6100 is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_16550A_VARIANTS=y -# CONFIG_SERIAL_8250_ACCENT is not set -# CONFIG_SERIAL_8250_ASPEED_VUART is not set -# CONFIG_SERIAL_8250_BOCA is not set -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_CS is not set -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -CONFIG_SERIAL_8250_DMA=y -# CONFIG_SERIAL_8250_DW is not set -# CONFIG_SERIAL_8250_EM is not set -# CONFIG_SERIAL_8250_EXAR is not set -# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set -# CONFIG_SERIAL_8250_EXTENDED is not set -# CONFIG_SERIAL_8250_FINTEK is not set -# CONFIG_SERIAL_8250_FOURPORT is not set -# CONFIG_SERIAL_8250_HUB6 is not set -# CONFIG_SERIAL_8250_INGENIC is not set -# CONFIG_SERIAL_8250_LPSS is not set -# CONFIG_SERIAL_8250_MANY_PORTS is not set -# CONFIG_SERIAL_8250_MID is not set -# CONFIG_SERIAL_8250_MOXA is not set -CONFIG_SERIAL_8250_NR_UARTS=2 -# CONFIG_SERIAL_8250_PCI is not set -# CONFIG_SERIAL_8250_RSA is not set -# CONFIG_SERIAL_8250_RT288X is not set -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_AMBA_PL010 is not set -# CONFIG_SERIAL_AMBA_PL011 is not set -# CONFIG_SERIAL_ARC is not set -# CONFIG_SERIAL_BCM63XX is not set -# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_DEV_BUS is not set -CONFIG_SERIAL_EARLYCON=y -# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -# CONFIG_SERIAL_FSL_LINFLEXUART is not set -# CONFIG_SERIAL_FSL_LPUART is not set -# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set -# CONFIG_SERIAL_IFX6X60 is not set -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX310X is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_SERIAL_OF_PLATFORM is not set -# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set -# CONFIG_SERIAL_PCH_UART is not set -# CONFIG_SERIAL_RP2 is not set -# CONFIG_SERIAL_SC16IS7XX is not set -# CONFIG_SERIAL_SCCNXP is not set -# CONFIG_SERIAL_SH_SCI is not set -# CONFIG_SERIAL_SIFIVE is not set -# CONFIG_SERIAL_SPRD is not set -# CONFIG_SERIAL_STM32 is not set -# CONFIG_SERIAL_ST_ASC is not set -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_UARTLITE is not set -# CONFIG_SERIAL_XILINX_PS_UART is not set -# CONFIG_SERIO is not set -# CONFIG_SERIO_ALTERA_PS2 is not set -# CONFIG_SERIO_AMBAKMI is not set -# CONFIG_SERIO_APBPS2 is not set -# CONFIG_SERIO_ARC_PS2 is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_GPIO_PS2 is not set -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_PARKBD is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_PS2MULT is not set -# CONFIG_SERIO_RAW is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_SUN4I_PS2 is not set -# CONFIG_SFC is not set -# CONFIG_SFC_FALCON is not set -# CONFIG_SFI is not set -# CONFIG_SFP is not set -# CONFIG_SF_PDMA is not set -# CONFIG_SGETMASK_SYSCALL is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP28 is not set -# CONFIG_SGI_IP30 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SGI_MFD_IOC3 is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_SG_POOL is not set -# CONFIG_SG_SPLIT is not set -CONFIG_SHMEM=y -# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set -# CONFIG_SH_ETH is not set -# CONFIG_SH_TIMER_CMT is not set -# CONFIG_SH_TIMER_MTU2 is not set -# CONFIG_SH_TIMER_TMU is not set -# CONFIG_SI1133 is not set -# CONFIG_SI1145 is not set -# CONFIG_SI7005 is not set -# CONFIG_SI7020 is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_SWARM is not set -CONFIG_SIGNALFD=y -# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set -# CONFIG_SIMPLE_GPIO is not set -# CONFIG_SIMPLE_PM_BUS is not set -# CONFIG_SIOX is not set -# CONFIG_SIS190 is not set -# CONFIG_SIS900 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SKY2_DEBUG is not set -# CONFIG_SLAB is not set -CONFIG_SLABINFO=y -CONFIG_SLAB_FREELIST_HARDENED=y -CONFIG_SLAB_FREELIST_RANDOM=y -CONFIG_SLAB_MERGE_DEFAULT=y -# CONFIG_SLHC is not set -# CONFIG_SLICOSS is not set -# CONFIG_SLIMBUS is not set -# CONFIG_SLIP is not set -# CONFIG_SLOB is not set -CONFIG_SLUB=y -CONFIG_SLUB_CPU_PARTIAL=y -# CONFIG_SLUB_DEBUG is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_MEMCG_SYSFS_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_SMARTJOYPLUS_FF is not set -# CONFIG_SMB_SERVER is not set -# CONFIG_SMC911X is not set -# CONFIG_SMC9194 is not set -# CONFIG_SMC91X is not set -# CONFIG_SMP is not set -# CONFIG_SMSC911X is not set -# CONFIG_SMSC9420 is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_SMS_SDIO_DRV is not set -# CONFIG_SMS_USB_DRV is not set -# CONFIG_SM_CAMCC_8250 is not set -# CONFIG_SM_FTL is not set -# CONFIG_SM_GCC_6115 is not set -# CONFIG_SM_GCC_6125 is not set -# CONFIG_SM_GCC_6350 is not set -# CONFIG_SM_GCC_8350 is not set -# CONFIG_SND is not set -# CONFIG_SND_AC97_POWER_SAVE is not set -# CONFIG_SND_AD1816A is not set -# CONFIG_SND_AD1848 is not set -# CONFIG_SND_AD1889 is not set -# CONFIG_SND_ADLIB is not set -# CONFIG_SND_ALI5451 is not set -# CONFIG_SND_ALOOP is not set -# CONFIG_SND_ALS100 is not set -# CONFIG_SND_ALS300 is not set -# CONFIG_SND_ALS4000 is not set -# CONFIG_SND_ARM is not set -# CONFIG_SND_ASIHPI is not set -# CONFIG_SND_ATIIXP is not set -# CONFIG_SND_ATIIXP_MODEM is not set -# CONFIG_SND_ATMEL_AC97C is not set -# CONFIG_SND_ATMEL_SOC is not set -# CONFIG_SND_AU8810 is not set -# CONFIG_SND_AU8820 is not set -# CONFIG_SND_AU8830 is not set -# CONFIG_SND_AUDIO_GRAPH_CARD is not set -# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set -# CONFIG_SND_AW2 is not set -# CONFIG_SND_AZT2320 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BCD2000 is not set -# CONFIG_SND_BCM63XX_I2S_WHISTLER is not set -# CONFIG_SND_BT87X is not set -# CONFIG_SND_CA0106 is not set -# CONFIG_SND_CMI8330 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_CS4231 is not set -# CONFIG_SND_CS4236 is not set -# CONFIG_SND_CS4281 is not set -# CONFIG_SND_CS46XX is not set -# CONFIG_SND_CS5530 is not set -# CONFIG_SND_CS5535AUDIO is not set -# CONFIG_SND_CTXFI is not set -# CONFIG_SND_DARLA20 is not set -# CONFIG_SND_DARLA24 is not set -# CONFIG_SND_DEBUG is not set -# CONFIG_SND_DESIGNWARE_I2S is not set -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_DYNAMIC_MINORS is not set -# CONFIG_SND_ECHO3G is not set -# CONFIG_SND_EDMA_SOC is not set -# CONFIG_SND_EMU10K1 is not set -# CONFIG_SND_EMU10K1X is not set -# CONFIG_SND_EMU10K1_SEQ is not set -# CONFIG_SND_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_ES1688 is not set -# CONFIG_SND_ES18XX is not set -# CONFIG_SND_ES1938 is not set -# CONFIG_SND_ES1968 is not set -# CONFIG_SND_FIREWIRE is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_GINA20 is not set -# CONFIG_SND_GINA24 is not set -# CONFIG_SND_GUSCLASSIC is not set -# CONFIG_SND_GUSEXTREME is not set -# CONFIG_SND_GUSMAX is not set -# CONFIG_SND_HDA_CODEC_CS8409 is not set -# CONFIG_SND_HDA_INTEL is not set -# CONFIG_SND_HDA_INTEL_DETECT_DMIC is not set -# CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM is not set -CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 -CONFIG_SND_HDA_PREALLOC_SIZE=64 -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM is not set -# CONFIG_SND_HRTIMER is not set -# CONFIG_SND_HWDEP is not set -# CONFIG_SND_I2S_HI6210_I2S is not set -# CONFIG_SND_ICE1712 is not set -# CONFIG_SND_ICE1724 is not set -# CONFIG_SND_INDIGO is not set -# CONFIG_SND_INDIGODJ is not set -# CONFIG_SND_INDIGODJX is not set -# CONFIG_SND_INDIGOIO is not set -# CONFIG_SND_INDIGOIOX is not set -# CONFIG_SND_INTEL8X0 is not set -# CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_INTERWAVE is not set -# CONFIG_SND_INTERWAVE_STB is not set -# CONFIG_SND_ISA is not set -# CONFIG_SND_JZ4740_SOC_I2S is not set -# CONFIG_SND_KIRKWOOD_SOC is not set -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_LAYLA20 is not set -# CONFIG_SND_LAYLA24 is not set -# CONFIG_SND_LOLA is not set -# CONFIG_SND_LX6464ES is not set -# CONFIG_SND_MAESTRO3 is not set -CONFIG_SND_MAX_CARDS=16 -# CONFIG_SND_MIA is not set -# CONFIG_SND_MIPS is not set -# CONFIG_SND_MIRO is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_MONA is not set -# CONFIG_SND_MPC52xx_SOC_EFIKA is not set -# CONFIG_SND_MPU401 is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_MTS64 is not set -# CONFIG_SND_MXS_SOC is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_OPL3SA2 is not set -# CONFIG_SND_OPL3_LIB_SEQ is not set -# CONFIG_SND_OPL4_LIB_SEQ is not set -# CONFIG_SND_OPTI92X_AD1848 is not set -# CONFIG_SND_OPTI92X_CS4231 is not set -# CONFIG_SND_OPTI93X is not set -CONFIG_SND_OSSEMUL=y -# CONFIG_SND_OXYGEN is not set -CONFIG_SND_PCI=y -# CONFIG_SND_PCM is not set -# CONFIG_SND_PCMCIA is not set -# CONFIG_SND_PCM_OSS is not set -CONFIG_SND_PCM_OSS_PLUGINS=y -# CONFIG_SND_PCM_TIMER is not set -# CONFIG_SND_PCM_XRUN_DEBUG is not set -# CONFIG_SND_PCXHR is not set -# CONFIG_SND_PDAUDIOCF is not set -# CONFIG_SND_PORTMAN2X4 is not set -# CONFIG_SND_POWERPC_SOC is not set -# CONFIG_SND_PPC is not set -CONFIG_SND_PROC_FS=y -# CONFIG_SND_RAWMIDI is not set -# CONFIG_SND_RAWMIDI_SEQ is not set -# CONFIG_SND_RIPTIDE is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set -# CONFIG_SND_RTCTIMER is not set -# CONFIG_SND_SB16 is not set -# CONFIG_SND_SB8 is not set -# CONFIG_SND_SBAWE is not set -# CONFIG_SND_SBAWE_SEQ is not set -# CONFIG_SND_SE6X is not set -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_SIMPLE_CARD is not set -# CONFIG_SND_SIMPLE_SCU_CARD is not set -# CONFIG_SND_SIS7019 is not set -# CONFIG_SND_SOC is not set -# CONFIG_SND_SOC_AC97_CODEC is not set -# CONFIG_SND_SOC_AD193X_I2C is not set -# CONFIG_SND_SOC_AD193X_SPI is not set -# CONFIG_SND_SOC_ADAU1372_I2C is not set -# CONFIG_SND_SOC_ADAU1372_SPI is not set -# CONFIG_SND_SOC_ADAU1701 is not set -# CONFIG_SND_SOC_ADAU1761_I2C is not set -# CONFIG_SND_SOC_ADAU1761_SPI is not set -# CONFIG_SND_SOC_ADAU7002 is not set -# CONFIG_SND_SOC_ADAU7118_HW is not set -# CONFIG_SND_SOC_ADAU7118_I2C is not set -# CONFIG_SND_SOC_ADI is not set -# CONFIG_SND_SOC_AK4104 is not set -# CONFIG_SND_SOC_AK4118 is not set -# CONFIG_SND_SOC_AK4458 is not set -# CONFIG_SND_SOC_AK4554 is not set -# CONFIG_SND_SOC_AK4613 is not set -# CONFIG_SND_SOC_AK4642 is not set -# CONFIG_SND_SOC_AK5386 is not set -# CONFIG_SND_SOC_AK5558 is not set -# CONFIG_SND_SOC_ALC5623 is not set -# CONFIG_SND_SOC_AMD_ACP is not set -# CONFIG_SND_SOC_AMD_ACP3x is not set -# CONFIG_SND_SOC_AMD_ACP5x is not set -# CONFIG_SND_SOC_AMD_RENOIR is not set -# CONFIG_SND_SOC_AU1XAUDIO is not set -# CONFIG_SND_SOC_AU1XPSC is not set -# CONFIG_SND_SOC_BD28623 is not set -# CONFIG_SND_SOC_BT_SCO is not set -# CONFIG_SND_SOC_CS35L32 is not set -# CONFIG_SND_SOC_CS35L33 is not set -# CONFIG_SND_SOC_CS35L34 is not set -# CONFIG_SND_SOC_CS35L35 is not set -# CONFIG_SND_SOC_CS35L36 is not set -# CONFIG_SND_SOC_CS4234 is not set -# CONFIG_SND_SOC_CS4265 is not set -# CONFIG_SND_SOC_CS4270 is not set -# CONFIG_SND_SOC_CS4271 is not set -# CONFIG_SND_SOC_CS4271_I2C is not set -# CONFIG_SND_SOC_CS4271_SPI is not set -# CONFIG_SND_SOC_CS42L42 is not set -# CONFIG_SND_SOC_CS42L51_I2C is not set -# CONFIG_SND_SOC_CS42L52 is not set -# CONFIG_SND_SOC_CS42L56 is not set -# CONFIG_SND_SOC_CS42L73 is not set -# CONFIG_SND_SOC_CS42XX8_I2C is not set -# CONFIG_SND_SOC_CS43130 is not set -# CONFIG_SND_SOC_CS4341 is not set -# CONFIG_SND_SOC_CS4349 is not set -# CONFIG_SND_SOC_CS53L30 is not set -# CONFIG_SND_SOC_CX2072X is not set -# CONFIG_SND_SOC_DA7213 is not set -# CONFIG_SND_SOC_DIO2125 is not set -# CONFIG_SND_SOC_DMIC is not set -# CONFIG_SND_SOC_ES7134 is not set -# CONFIG_SND_SOC_ES7241 is not set -# CONFIG_SND_SOC_ES8316 is not set -# CONFIG_SND_SOC_ES8328 is not set -# CONFIG_SND_SOC_ES8328_I2C is not set -# CONFIG_SND_SOC_ES8328_SPI is not set -# CONFIG_SND_SOC_EUKREA_TLV320 is not set -# CONFIG_SND_SOC_FSL_ASOC_CARD is not set -# CONFIG_SND_SOC_FSL_ASRC is not set -# CONFIG_SND_SOC_FSL_AUD2HTX is not set -# CONFIG_SND_SOC_FSL_AUDMIX is not set -# CONFIG_SND_SOC_FSL_ESAI is not set -# CONFIG_SND_SOC_FSL_MICFIL is not set -# CONFIG_SND_SOC_FSL_RPMSG is not set -# CONFIG_SND_SOC_FSL_SAI is not set -# CONFIG_SND_SOC_FSL_SPDIF is not set -# CONFIG_SND_SOC_FSL_SSI is not set -# CONFIG_SND_SOC_FSL_XCVR is not set -# CONFIG_SND_SOC_GTM601 is not set -# CONFIG_SND_SOC_ICS43432 is not set -# CONFIG_SND_SOC_IMG is not set -# CONFIG_SND_SOC_IMX_AUDMIX is not set -# CONFIG_SND_SOC_IMX_AUDMUX is not set -# CONFIG_SND_SOC_IMX_CARD is not set -# CONFIG_SND_SOC_IMX_ES8328 is not set -# CONFIG_SND_SOC_IMX_HDMI is not set -# CONFIG_SND_SOC_IMX_RPMSG is not set -# CONFIG_SND_SOC_IMX_SPDIF is not set -# CONFIG_SND_SOC_IMX_WM8962 is not set -# CONFIG_SND_SOC_INNO_RK3036 is not set -# CONFIG_SND_SOC_INTEL_APL is not set -# CONFIG_SND_SOC_INTEL_BAYTRAIL is not set -# CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH is not set -# CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH is not set -# CONFIG_SND_SOC_INTEL_BXT_RT298_MACH is not set -# CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH is not set -# CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH is not set -# CONFIG_SND_SOC_INTEL_CATPT is not set -# CONFIG_SND_SOC_INTEL_CFL is not set -# CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH is not set -# CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH is not set -# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH is not set -# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH is not set -# CONFIG_SND_SOC_INTEL_CML_H is not set -# CONFIG_SND_SOC_INTEL_CML_LP is not set -# CONFIG_SND_SOC_INTEL_CNL is not set -# CONFIG_SND_SOC_INTEL_GLK is not set -# CONFIG_SND_SOC_INTEL_HASWELL is not set -# CONFIG_SND_SOC_INTEL_KBL is not set -# CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH is not set -# CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH is not set -# CONFIG_SND_SOC_INTEL_KEEMBAY is not set -# CONFIG_SND_SOC_INTEL_SKL is not set -# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH is not set -# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH is not set -# CONFIG_SND_SOC_INTEL_SKL_RT286_MACH is not set -# CONFIG_SND_SOC_INTEL_SKYLAKE is not set -# CONFIG_SND_SOC_INTEL_SST is not set -CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y -# CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES is not set -# CONFIG_SND_SOC_JZ4725B_CODEC is not set -# CONFIG_SND_SOC_JZ4740_CODEC is not set -# CONFIG_SND_SOC_JZ4770_CODEC is not set -# CONFIG_SND_SOC_LPASS_RX_MACRO is not set -# CONFIG_SND_SOC_LPASS_TX_MACRO is not set -# CONFIG_SND_SOC_LPASS_VA_MACRO is not set -# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set -# CONFIG_SND_SOC_MA120X0P is not set -# CONFIG_SND_SOC_MAX9759 is not set -# CONFIG_SND_SOC_MAX98088 is not set -# CONFIG_SND_SOC_MAX98357A is not set -# CONFIG_SND_SOC_MAX98373 is not set -# CONFIG_SND_SOC_MAX98373_I2C is not set -# CONFIG_SND_SOC_MAX98390 is not set -# CONFIG_SND_SOC_MAX98504 is not set -# CONFIG_SND_SOC_MAX9860 is not set -# CONFIG_SND_SOC_MAX9867 is not set -# CONFIG_SND_SOC_MAX98927 is not set -# CONFIG_SND_SOC_MEDIATEK is not set -# CONFIG_SND_SOC_MPC5200_AC97 is not set -# CONFIG_SND_SOC_MPC5200_I2S is not set -# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set -# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set -# CONFIG_SND_SOC_MT2701 is not set -# CONFIG_SND_SOC_MT6351 is not set -# CONFIG_SND_SOC_MT6358 is not set -# CONFIG_SND_SOC_MT6359 is not set -# CONFIG_SND_SOC_MT6359_ACCDET is not set -# CONFIG_SND_SOC_MT6660 is not set -# CONFIG_SND_SOC_MT6797 is not set -# CONFIG_SND_SOC_MT8173 is not set -# CONFIG_SND_SOC_MT8183 is not set -# CONFIG_SND_SOC_MT8192 is not set -# CONFIG_SND_SOC_MT8195 is not set -# CONFIG_SND_SOC_MTK_BTCVSD is not set -# CONFIG_SND_SOC_NAU8315 is not set -# CONFIG_SND_SOC_NAU8540 is not set -# CONFIG_SND_SOC_NAU8810 is not set -# CONFIG_SND_SOC_NAU8822 is not set -# CONFIG_SND_SOC_NAU8824 is not set -# CONFIG_SND_SOC_PCM1681 is not set -# CONFIG_SND_SOC_PCM1789_I2C is not set -# CONFIG_SND_SOC_PCM1792A is not set -# CONFIG_SND_SOC_PCM179X_I2C is not set -# CONFIG_SND_SOC_PCM179X_SPI is not set -# CONFIG_SND_SOC_PCM186X_I2C is not set -# CONFIG_SND_SOC_PCM186X_SPI is not set -# CONFIG_SND_SOC_PCM3060_I2C is not set -# CONFIG_SND_SOC_PCM3060_SPI is not set -# CONFIG_SND_SOC_PCM3168A_I2C is not set -# CONFIG_SND_SOC_PCM3168A_SPI is not set -# CONFIG_SND_SOC_PCM5102A is not set -# CONFIG_SND_SOC_PCM512x_I2C is not set -# CONFIG_SND_SOC_PCM512x_SPI is not set -# CONFIG_SND_SOC_QCOM is not set -# CONFIG_SND_SOC_RK3328 is not set -# CONFIG_SND_SOC_RK817 is not set -# CONFIG_SND_SOC_ROCKCHIP is not set -# CONFIG_SND_SOC_RT5616 is not set -# CONFIG_SND_SOC_RT5631 is not set -# CONFIG_SND_SOC_RT5640 is not set -# CONFIG_SND_SOC_RT5659 is not set -# CONFIG_SND_SOC_RT5677_SPI is not set -# CONFIG_SND_SOC_SGTL5000 is not set -# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set -# CONFIG_SND_SOC_SIMPLE_MUX is not set -# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set -# CONFIG_SND_SOC_SOF_TOPLEVEL is not set -# CONFIG_SND_SOC_SPDIF is not set -# CONFIG_SND_SOC_SSM2305 is not set -# CONFIG_SND_SOC_SSM2518 is not set -# CONFIG_SND_SOC_SSM2602_I2C is not set -# CONFIG_SND_SOC_SSM2602_SPI is not set -# CONFIG_SND_SOC_SSM4567 is not set -# CONFIG_SND_SOC_STA32X is not set -# CONFIG_SND_SOC_STA350 is not set -# CONFIG_SND_SOC_STI_SAS is not set -# CONFIG_SND_SOC_TAS2552 is not set -# CONFIG_SND_SOC_TAS2562 is not set -# CONFIG_SND_SOC_TAS2764 is not set -# CONFIG_SND_SOC_TAS2770 is not set -# CONFIG_SND_SOC_TAS5086 is not set -# CONFIG_SND_SOC_TAS571X is not set -# CONFIG_SND_SOC_TAS5720 is not set -# CONFIG_SND_SOC_TAS6424 is not set -# CONFIG_SND_SOC_TDA7419 is not set -# CONFIG_SND_SOC_TFA9879 is not set -# CONFIG_SND_SOC_TFA989X is not set -# CONFIG_SND_SOC_TLV320ADCX140 is not set -# CONFIG_SND_SOC_TLV320AIC23_I2C is not set -# CONFIG_SND_SOC_TLV320AIC23_SPI is not set -# CONFIG_SND_SOC_TLV320AIC31XX is not set -# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set -# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set -# CONFIG_SND_SOC_TLV320AIC3X is not set -# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set -# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set -# CONFIG_SND_SOC_TPA6130A2 is not set -# CONFIG_SND_SOC_TS3A227E is not set -# CONFIG_SND_SOC_TSCS42XX is not set -# CONFIG_SND_SOC_TSCS454 is not set -# CONFIG_SND_SOC_UDA1334 is not set -# CONFIG_SND_SOC_WM8510 is not set -# CONFIG_SND_SOC_WM8523 is not set -# CONFIG_SND_SOC_WM8524 is not set -# CONFIG_SND_SOC_WM8580 is not set -# CONFIG_SND_SOC_WM8711 is not set -# CONFIG_SND_SOC_WM8728 is not set -# CONFIG_SND_SOC_WM8731 is not set -# CONFIG_SND_SOC_WM8737 is not set -# CONFIG_SND_SOC_WM8741 is not set -# CONFIG_SND_SOC_WM8750 is not set -# CONFIG_SND_SOC_WM8753 is not set -# CONFIG_SND_SOC_WM8770 is not set -# CONFIG_SND_SOC_WM8776 is not set -# CONFIG_SND_SOC_WM8782 is not set -# CONFIG_SND_SOC_WM8804_I2C is not set -# CONFIG_SND_SOC_WM8804_SPI is not set -# CONFIG_SND_SOC_WM8903 is not set -# CONFIG_SND_SOC_WM8904 is not set -# CONFIG_SND_SOC_WM8960 is not set -# CONFIG_SND_SOC_WM8962 is not set -# CONFIG_SND_SOC_WM8974 is not set -# CONFIG_SND_SOC_WM8978 is not set -# CONFIG_SND_SOC_WM8985 is not set -# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set -# CONFIG_SND_SOC_XILINX_I2S is not set -# CONFIG_SND_SOC_XILINX_SPDIF is not set -# CONFIG_SND_SOC_XTFPGA_I2S is not set -# CONFIG_SND_SOC_ZL38060 is not set -# CONFIG_SND_SOC_ZX_AUD96P22 is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_SPI is not set -# CONFIG_SND_SSCAPE is not set -# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI is not set -# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI is not set -# CONFIG_SND_SUN4I_CODEC is not set -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_TIMER is not set -# CONFIG_SND_TRIDENT is not set -CONFIG_SND_USB=y -# CONFIG_SND_USB_6FIRE is not set -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_CAIAQ is not set -# CONFIG_SND_USB_HIFACE is not set -# CONFIG_SND_USB_POD is not set -# CONFIG_SND_USB_PODHD is not set -# CONFIG_SND_USB_TONEPORT is not set -# CONFIG_SND_USB_UA101 is not set -# CONFIG_SND_USB_US122L is not set -# CONFIG_SND_USB_USX2Y is not set -# CONFIG_SND_USB_VARIAX is not set -# CONFIG_SND_VERBOSE_PRINTK is not set -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VIA82XX is not set -# CONFIG_SND_VIA82XX_MODEM is not set -# CONFIG_SND_VIRTIO is not set -# CONFIG_SND_VIRTUOSO is not set -# CONFIG_SND_VX222 is not set -# CONFIG_SND_VXPOCKET is not set -# CONFIG_SND_WAVEFRONT is not set -CONFIG_SND_X86=y -# CONFIG_SND_XEN_FRONTEND is not set -# CONFIG_SND_YMFPCI is not set -# CONFIG_SNI_RM is not set -# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set -# CONFIG_SOCK_CGROUP_DATA is not set -# CONFIG_SOC_AM33XX is not set -# CONFIG_SOC_AM43XX is not set -# CONFIG_SOC_BRCMSTB is not set -# CONFIG_SOC_CAMERA is not set -# CONFIG_SOC_DRA7XX is not set -# CONFIG_SOC_HAS_OMAP2_SDRC is not set -# CONFIG_SOC_OMAP5 is not set -# CONFIG_SOC_TI is not set -# CONFIG_SOFTLOCKUP_DETECTOR is not set -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_SONYPI is not set -# CONFIG_SONY_LAPTOP is not set -# CONFIG_SOUND is not set -# CONFIG_SOUNDWIRE is not set -# CONFIG_SOUND_OSS_CORE is not set -# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set -# CONFIG_SOUND_PRIME is not set -# CONFIG_SP5100_TCO is not set -# CONFIG_SPARSEMEM_MANUAL is not set -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -# CONFIG_SPARSE_IRQ is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_SPEAKUP is not set -# CONFIG_SPI is not set -# CONFIG_SPINLOCK_TEST is not set -# CONFIG_SPI_ALTERA is not set -# CONFIG_SPI_AMD is not set -# CONFIG_SPI_AU1550 is not set -# CONFIG_SPI_AXI_SPI_ENGINE is not set -# CONFIG_SPI_BCM2835 is not set -# CONFIG_SPI_BCM_QSPI is not set -# CONFIG_SPI_BITBANG is not set -# CONFIG_SPI_BUTTERFLY is not set -# CONFIG_SPI_CADENCE is not set -# CONFIG_SPI_CADENCE_QUADSPI is not set -# CONFIG_SPI_DEBUG is not set -# CONFIG_SPI_DESIGNWARE is not set -# CONFIG_SPI_FSL_DSPI is not set -# CONFIG_SPI_FSL_ESPI is not set -# CONFIG_SPI_FSL_SPI is not set -# CONFIG_SPI_GPIO is not set -# CONFIG_SPI_GPIO_OLD is not set -# CONFIG_SPI_IMG_SPFI is not set -# CONFIG_SPI_LANTIQ_SSC is not set -# CONFIG_SPI_LM70_LLP is not set -# CONFIG_SPI_LOOPBACK_TEST is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_SPI_MEM is not set -# CONFIG_SPI_MPC52xx is not set -# CONFIG_SPI_MPC52xx_PSC is not set -# CONFIG_SPI_MTK_QUADSPI is not set -# CONFIG_SPI_MUX is not set -# CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set -# CONFIG_SPI_OCTEON is not set -# CONFIG_SPI_OC_TINY is not set -# CONFIG_SPI_ORION is not set -# CONFIG_SPI_PL022 is not set -# CONFIG_SPI_PPC4xx is not set -# CONFIG_SPI_PXA2XX is not set -# CONFIG_SPI_PXA2XX_PCI is not set -# CONFIG_SPI_QCOM_QSPI is not set -# CONFIG_SPI_ROCKCHIP is not set -# CONFIG_SPI_S3C64XX is not set -# CONFIG_SPI_SC18IS602 is not set -# CONFIG_SPI_SIFIVE is not set -# CONFIG_SPI_SLAVE is not set -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_THUNDERX is not set -# CONFIG_SPI_TI_QSPI is not set -# CONFIG_SPI_TLE62X0 is not set -# CONFIG_SPI_TOPCLIFF_PCH is not set -# CONFIG_SPI_XCOMM is not set -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_XWAY is not set -# CONFIG_SPI_ZYNQMP_GQSPI is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_SPMI is not set -# CONFIG_SPS30 is not set -# CONFIG_SPS30_I2C is not set -# CONFIG_SPS30_SERIAL is not set -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set -# CONFIG_SQUASHFS_DECOMP_MULTI is not set -CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y -# CONFIG_SQUASHFS_DECOMP_SINGLE is not set -CONFIG_SQUASHFS_EMBEDDED=y -# CONFIG_SQUASHFS_FILE_CACHE is not set -CONFIG_SQUASHFS_FILE_DIRECT=y -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_LZ4 is not set -# CONFIG_SQUASHFS_LZO is not set -# CONFIG_SQUASHFS_XATTR is not set -CONFIG_SQUASHFS_XZ=y -# CONFIG_SQUASHFS_ZLIB is not set -# CONFIG_SQUASHFS_ZSTD is not set -# CONFIG_SRAM is not set -# CONFIG_SRF04 is not set -# CONFIG_SRF08 is not set -# CONFIG_SSB is not set -# CONFIG_SSB_DEBUG is not set -# CONFIG_SSB_DRIVER_GPIO is not set -# CONFIG_SSB_HOST_SOC is not set -# CONFIG_SSB_PCMCIAHOST is not set -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB_SDIOHOST is not set -# CONFIG_SSB_SILENT is not set -# CONFIG_SSFDC is not set -# CONFIG_STACKPROTECTOR is not set -# CONFIG_STACKPROTECTOR_STRONG is not set -# CONFIG_STACKTRACE is not set -# CONFIG_STACKTRACE_BUILD_ID is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_STACK_HASH_ORDER=20 -# CONFIG_STACK_TRACER is not set -# CONFIG_STACK_VALIDATION is not set -CONFIG_STAGING=y -# CONFIG_STAGING_BOARD is not set -# CONFIG_STAGING_GASKET_FRAMEWORK is not set -# CONFIG_STAGING_MEDIA is not set -CONFIG_STANDALONE=y -# CONFIG_STATIC_KEYS_SELFTEST is not set -# CONFIG_STATIC_USERMODEHELPER is not set -CONFIG_STDBINUTILS=y -# CONFIG_STE10XP is not set -# CONFIG_STE_MODEM_RPROC is not set -# CONFIG_STK3310 is not set -# CONFIG_STK8312 is not set -# CONFIG_STK8BA50 is not set -# CONFIG_STM is not set -# CONFIG_STMMAC_ETH is not set -# CONFIG_STMMAC_PCI is not set -# CONFIG_STMMAC_PLATFORM is not set -# CONFIG_STMMAC_SELFTESTS is not set -# CONFIG_STM_DUMMY is not set -# CONFIG_STM_SOURCE_CONSOLE is not set -CONFIG_STP=y -# CONFIG_STREAM_PARSER is not set -# CONFIG_STRICT_DEVMEM is not set -CONFIG_STRICT_KERNEL_RWX=y -CONFIG_STRICT_MODULE_RWX=y -# CONFIG_STRING_SELFTEST is not set -CONFIG_STRIP_ASM_SYMS=y -# CONFIG_STX104 is not set -# CONFIG_ST_UVIS25 is not set -# CONFIG_SUN4I_GPADC is not set -# CONFIG_SUN50I_DE2_BUS is not set -# CONFIG_SUN50I_ERRATUM_UNKNOWN1 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_SUNRPC is not set -# CONFIG_SUNRPC_DEBUG is not set -CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y -# CONFIG_SUNRPC_GSS is not set -# CONFIG_SUNXI_SRAM is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_SURFACE_3_BUTTON is not set -# CONFIG_SUSPEND is not set -# CONFIG_SUSPEND_SKIP_SYNC is not set -CONFIG_SWAP=y -# CONFIG_SWCONFIG is not set -# CONFIG_SWCONFIG_B53 is not set -# CONFIG_SWCONFIG_B53_MDIO_DRIVER is not set -# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set -# CONFIG_SWCONFIG_B53_SPI_DRIVER is not set -# CONFIG_SWCONFIG_B53_SRAB_DRIVER is not set -# CONFIG_SWCONFIG_LEDS is not set -# CONFIG_SW_SYNC is not set -# CONFIG_SX9310 is not set -# CONFIG_SX9500 is not set -# CONFIG_SXGBE_ETH is not set -CONFIG_SYMBOLIC_ERRNAME=y -# CONFIG_SYNCLINK_CS is not set -# CONFIG_SYNC_FILE is not set -# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set -# CONFIG_SYNTH_EVENTS is not set -# CONFIG_SYNTH_EVENT_GEN_TEST is not set -CONFIG_SYN_COOKIES=y -# CONFIG_SYSCON_REBOOT_MODE is not set -CONFIG_SYSCTL=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_SYSFS=y -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_SYSFS_SYSCALL is not set -# CONFIG_SYSTEMPORT is not set -# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set -# CONFIG_SYSTEM_DATA_VERIFICATION is not set -# CONFIG_SYSTEM_TRUSTED_KEYRING is not set -CONFIG_SYSTEM_TRUSTED_KEYS="" -# CONFIG_SYSV68_PARTITION is not set -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_SYSV_FS is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_T5403 is not set -# CONFIG_TARGET_CORE is not set -# CONFIG_TASKSTATS is not set -# CONFIG_TASKS_RCU is not set -# CONFIG_TASK_XACCT is not set -# CONFIG_TC35815 is not set -# CONFIG_TCG_ATMEL is not set -# CONFIG_TCG_CRB is not set -# CONFIG_TCG_FTPM_TEE is not set -# CONFIG_TCG_INFINEON is not set -# CONFIG_TCG_NSC is not set -# CONFIG_TCG_ST33_I2C is not set -# CONFIG_TCG_TIS is not set -# CONFIG_TCG_TIS_I2C_ATMEL is not set -# CONFIG_TCG_TIS_I2C_CR50 is not set -# CONFIG_TCG_TIS_I2C_INFINEON is not set -# CONFIG_TCG_TIS_I2C_NUVOTON is not set -# CONFIG_TCG_TIS_SPI is not set -# CONFIG_TCG_TIS_ST33ZP24_I2C is not set -# CONFIG_TCG_TIS_ST33ZP24_SPI is not set -# CONFIG_TCG_TPM is not set -# CONFIG_TCG_VTPM_PROXY is not set -# CONFIG_TCG_XEN is not set -# CONFIG_TCIC is not set -CONFIG_TCP_CONG_ADVANCED=y -# CONFIG_TCP_CONG_BBR is not set -# CONFIG_TCP_CONG_BIC is not set -# CONFIG_TCP_CONG_CDG is not set -CONFIG_TCP_CONG_CUBIC=y -# CONFIG_TCP_CONG_DCTCP is not set -# CONFIG_TCP_CONG_HSTCP is not set -# CONFIG_TCP_CONG_HTCP is not set -# CONFIG_TCP_CONG_HYBLA is not set -# CONFIG_TCP_CONG_ILLINOIS is not set -# CONFIG_TCP_CONG_LP is not set -# CONFIG_TCP_CONG_NV is not set -# CONFIG_TCP_CONG_SCALABLE is not set -# CONFIG_TCP_CONG_VEGAS is not set -# CONFIG_TCP_CONG_VENO is not set -# CONFIG_TCP_CONG_WESTWOOD is not set -# CONFIG_TCP_CONG_YEAH is not set -# CONFIG_TCP_MD5SIG is not set -# CONFIG_TCS3414 is not set -# CONFIG_TCS3472 is not set -# CONFIG_TEE is not set -# CONFIG_TEGRA210_ADMA is not set -# CONFIG_TEGRA_ACONNECT is not set -# CONFIG_TEGRA_AHB is not set -# CONFIG_TEGRA_HOST1X is not set -# CONFIG_TEHUTI is not set -# CONFIG_TERANETICS_PHY is not set -# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set -# CONFIG_TEST_BITFIELD is not set -# CONFIG_TEST_BITMAP is not set -# CONFIG_TEST_BITOPS is not set -# CONFIG_TEST_BLACKHOLE_DEV is not set -# CONFIG_TEST_BPF is not set -# CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set -# CONFIG_TEST_DEBUG_VIRTUAL is not set -# CONFIG_TEST_DIV64 is not set -# CONFIG_TEST_FIRMWARE is not set -# CONFIG_TEST_FREE_PAGES is not set -# CONFIG_TEST_HASH is not set -# CONFIG_TEST_HEXDUMP is not set -# CONFIG_TEST_IDA is not set -# CONFIG_TEST_KASAN_MODULE is not set -# CONFIG_TEST_KMOD is not set -# CONFIG_TEST_KSTRTOX is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_TEST_LKM is not set -# CONFIG_TEST_LOCKUP is not set -# CONFIG_TEST_MEMCAT_P is not set -# CONFIG_TEST_MEMINIT is not set -# CONFIG_TEST_MIN_HEAP is not set -# CONFIG_TEST_OVERFLOW is not set -# CONFIG_TEST_POWER is not set -# CONFIG_TEST_PRINTF is not set -# CONFIG_TEST_RHASHTABLE is not set -# CONFIG_TEST_SCANF is not set -# CONFIG_TEST_SORT is not set -# CONFIG_TEST_STACKINIT is not set -# CONFIG_TEST_STATIC_KEYS is not set -# CONFIG_TEST_STRING_HELPERS is not set -# CONFIG_TEST_STRSCPY is not set -# CONFIG_TEST_SYSCTL is not set -# CONFIG_TEST_UBSAN is not set -# CONFIG_TEST_UDELAY is not set -# CONFIG_TEST_USER_COPY is not set -# CONFIG_TEST_UUID is not set -# CONFIG_TEST_VMALLOC is not set -# CONFIG_TEST_XARRAY is not set -CONFIG_TEXTSEARCH=y -# CONFIG_TEXTSEARCH_BM is not set -# CONFIG_TEXTSEARCH_FSM is not set -# CONFIG_TEXTSEARCH_KMP is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set -# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set -# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set -# CONFIG_THERMAL_EMULATION is not set -# CONFIG_THERMAL_GOV_BANG_BANG is not set -# CONFIG_THERMAL_GOV_FAIR_SHARE is not set -# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set -# CONFIG_THERMAL_GOV_USER_SPACE is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_THERMAL_MMIO is not set -# CONFIG_THERMAL_NETLINK is not set -# CONFIG_THERMAL_STATISTICS is not set -# CONFIG_THERMAL_WRITABLE_TRIPS is not set -# CONFIG_THINKPAD_ACPI is not set -CONFIG_THIN_ARCHIVES=y -# CONFIG_THRUSTMASTER_FF is not set -# CONFIG_THUMB2_KERNEL is not set -# CONFIG_THUNDERBOLT is not set -# CONFIG_THUNDER_NIC_BGX is not set -# CONFIG_THUNDER_NIC_PF is not set -# CONFIG_THUNDER_NIC_RGX is not set -# CONFIG_THUNDER_NIC_VF is not set -# CONFIG_TICK_CPU_ACCOUNTING is not set -CONFIG_TICK_ONESHOT=y -# CONFIG_TIFM_CORE is not set -# CONFIG_TIGON3 is not set -# CONFIG_TIMB_DMA is not set -CONFIG_TIMERFD=y -# CONFIG_TIMERLAT_TRACER is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_TIME_NS is not set -# CONFIG_TINYDRM_HX8357D is not set -# CONFIG_TINYDRM_ILI9225 is not set -# CONFIG_TINYDRM_ILI9341 is not set -# CONFIG_TINYDRM_ILI9486 is not set -# CONFIG_TINYDRM_MI0283QT is not set -# CONFIG_TINYDRM_REPAPER is not set -# CONFIG_TINYDRM_ST7586 is not set -# CONFIG_TINYDRM_ST7735R is not set -CONFIG_TINY_RCU=y -# CONFIG_TIPC is not set -# CONFIG_TI_ADC081C is not set -# CONFIG_TI_ADC0832 is not set -# CONFIG_TI_ADC084S021 is not set -# CONFIG_TI_ADC108S102 is not set -# CONFIG_TI_ADC12138 is not set -# CONFIG_TI_ADC128S052 is not set -# CONFIG_TI_ADC161S626 is not set -# CONFIG_TI_ADS1015 is not set -# CONFIG_TI_ADS124S08 is not set -# CONFIG_TI_ADS131E08 is not set -# CONFIG_TI_ADS7950 is not set -# CONFIG_TI_ADS8344 is not set -# CONFIG_TI_ADS8688 is not set -# CONFIG_TI_AM335X_ADC is not set -# CONFIG_TI_CPSW is not set -# CONFIG_TI_CPSW_ALE is not set -# CONFIG_TI_CPSW_PHY_SEL is not set -# CONFIG_TI_CPTS is not set -# CONFIG_TI_DAC082S085 is not set -# CONFIG_TI_DAC5571 is not set -# CONFIG_TI_DAC7311 is not set -# CONFIG_TI_DAC7512 is not set -# CONFIG_TI_DAC7612 is not set -# CONFIG_TI_DAVINCI_CPDMA is not set -# CONFIG_TI_DAVINCI_MDIO is not set -# CONFIG_TI_ST is not set -# CONFIG_TI_SYSCON_RESET is not set -# CONFIG_TI_TLC4541 is not set -# CONFIG_TI_TSC2046 is not set -# CONFIG_TLAN is not set -# CONFIG_TLS is not set -# CONFIG_TLS_DEVICE is not set -# CONFIG_TLS_TOE is not set -# CONFIG_TMD_HERMES is not set -# CONFIG_TMP006 is not set -# CONFIG_TMP007 is not set -# CONFIG_TMP117 is not set -CONFIG_TMPFS=y -# CONFIG_TMPFS_INODE64 is not set -# CONFIG_TMPFS_POSIX_ACL is not set -CONFIG_TMPFS_XATTR=y -# CONFIG_TOPSTAR_LAPTOP is not set -# CONFIG_TORTURE_TEST is not set -# CONFIG_TOSHIBA_HAPS is not set -# CONFIG_TOUCHSCREEN_88PM860X is not set -# CONFIG_TOUCHSCREEN_AD7877 is not set -# CONFIG_TOUCHSCREEN_AD7879 is not set -# CONFIG_TOUCHSCREEN_AD7879_I2C is not set -# CONFIG_TOUCHSCREEN_AD7879_SPI is not set -# CONFIG_TOUCHSCREEN_ADC is not set -# CONFIG_TOUCHSCREEN_ADS7846 is not set -# CONFIG_TOUCHSCREEN_AR1021_I2C is not set -# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set -# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set -# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set -# CONFIG_TOUCHSCREEN_BU21013 is not set -# CONFIG_TOUCHSCREEN_BU21029 is not set -# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set -# CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 is not set -# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set -# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set -# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set -# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set -# CONFIG_TOUCHSCREEN_CYTTSP4_I2C is not set -# CONFIG_TOUCHSCREEN_CYTTSP4_SPI is not set -# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set -# CONFIG_TOUCHSCREEN_CYTTSP_I2C is not set -# CONFIG_TOUCHSCREEN_CYTTSP_SPI is not set -# CONFIG_TOUCHSCREEN_DA9034 is not set -# CONFIG_TOUCHSCREEN_DA9052 is not set -# CONFIG_TOUCHSCREEN_DYNAPRO is not set -# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set -# CONFIG_TOUCHSCREEN_EETI is not set -# CONFIG_TOUCHSCREEN_EGALAX is not set -# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set -# CONFIG_TOUCHSCREEN_EKTF2127 is not set -# CONFIG_TOUCHSCREEN_ELAN is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_EXC3000 is not set -# CONFIG_TOUCHSCREEN_FUJITSU is not set -# CONFIG_TOUCHSCREEN_GOODIX is not set -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set -# CONFIG_TOUCHSCREEN_HIDEEP is not set -# CONFIG_TOUCHSCREEN_HP600 is not set -# CONFIG_TOUCHSCREEN_HP7XX is not set -# CONFIG_TOUCHSCREEN_HTCPEN is not set -# CONFIG_TOUCHSCREEN_HYCON_HY46XX is not set -# CONFIG_TOUCHSCREEN_ILI210X is not set -# CONFIG_TOUCHSCREEN_ILITEK is not set -# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set -# CONFIG_TOUCHSCREEN_INEXIO is not set -# CONFIG_TOUCHSCREEN_IPAQ_MICRO is not set -# CONFIG_TOUCHSCREEN_IPROC is not set -# CONFIG_TOUCHSCREEN_IQS5XX is not set -# CONFIG_TOUCHSCREEN_LPC32XX is not set -# CONFIG_TOUCHSCREEN_MAX11801 is not set -# CONFIG_TOUCHSCREEN_MC13783 is not set -# CONFIG_TOUCHSCREEN_MCS5000 is not set -# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set -# CONFIG_TOUCHSCREEN_MIGOR is not set -# CONFIG_TOUCHSCREEN_MK712 is not set -# CONFIG_TOUCHSCREEN_MMS114 is not set -# CONFIG_TOUCHSCREEN_MSG2638 is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_MX25 is not set -# CONFIG_TOUCHSCREEN_MXS_LRADC is not set -# CONFIG_TOUCHSCREEN_PCAP is not set -# CONFIG_TOUCHSCREEN_PENMOUNT is not set -# CONFIG_TOUCHSCREEN_PIXCIR is not set -# CONFIG_TOUCHSCREEN_PROPERTIES is not set -# CONFIG_TOUCHSCREEN_RASPBERRYPI_FW is not set -# CONFIG_TOUCHSCREEN_RM_TS is not set -# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set -# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set -# CONFIG_TOUCHSCREEN_S3C2410 is not set -# CONFIG_TOUCHSCREEN_S6SY761 is not set -# CONFIG_TOUCHSCREEN_SILEAD is not set -# CONFIG_TOUCHSCREEN_SIS_I2C is not set -# CONFIG_TOUCHSCREEN_ST1232 is not set -# CONFIG_TOUCHSCREEN_STMFTS is not set -# CONFIG_TOUCHSCREEN_STMPE is not set -# CONFIG_TOUCHSCREEN_SUN4I is not set -# CONFIG_TOUCHSCREEN_SUR40 is not set -# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set -# CONFIG_TOUCHSCREEN_SX8654 is not set -# CONFIG_TOUCHSCREEN_TI_AM335X_TSC is not set -# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set -# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_TPS6507X is not set -# CONFIG_TOUCHSCREEN_TS4800 is not set -# CONFIG_TOUCHSCREEN_TSC2004 is not set -# CONFIG_TOUCHSCREEN_TSC2005 is not set -# CONFIG_TOUCHSCREEN_TSC2007 is not set -# CONFIG_TOUCHSCREEN_TSC2007_IIO is not set -# CONFIG_TOUCHSCREEN_TSC200X_CORE is not set -# CONFIG_TOUCHSCREEN_TSC_SERIO is not set -# CONFIG_TOUCHSCREEN_UCB1400 is not set -# CONFIG_TOUCHSCREEN_USB_3M is not set -# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set -# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set -# CONFIG_TOUCHSCREEN_USB_E2I is not set -# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set -# CONFIG_TOUCHSCREEN_USB_EGALAX is not set -# CONFIG_TOUCHSCREEN_USB_ELO is not set -# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set -# CONFIG_TOUCHSCREEN_USB_ETURBO is not set -# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set -# CONFIG_TOUCHSCREEN_USB_GOTOP is not set -# CONFIG_TOUCHSCREEN_USB_GUNZE is not set -# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set -# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set -# CONFIG_TOUCHSCREEN_USB_ITM is not set -# CONFIG_TOUCHSCREEN_USB_JASTEC is not set -# CONFIG_TOUCHSCREEN_USB_NEXIO is not set -# CONFIG_TOUCHSCREEN_USB_PANJIT is not set -# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set -# CONFIG_TOUCHSCREEN_W90X900 is not set -# CONFIG_TOUCHSCREEN_WACOM_I2C is not set -# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set -# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set -# CONFIG_TOUCHSCREEN_WM831X is not set -# CONFIG_TOUCHSCREEN_WM9705 is not set -# CONFIG_TOUCHSCREEN_WM9712 is not set -# CONFIG_TOUCHSCREEN_WM9713 is not set -# CONFIG_TOUCHSCREEN_WM97XX is not set -# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set -# CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE is not set -# CONFIG_TOUCHSCREEN_ZET6223 is not set -# CONFIG_TOUCHSCREEN_ZFORCE is not set -# CONFIG_TOUCHSCREEN_ZINITIX is not set -# CONFIG_TPL0102 is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS65010 is not set -# CONFIG_TPS6507X is not set -# CONFIG_TRACEPOINT_BENCHMARK is not set -# CONFIG_TRACER_SNAPSHOT is not set -# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set -# CONFIG_TRACE_BRANCH_PROFILING is not set -# CONFIG_TRACE_EVAL_MAP_FILE is not set -# CONFIG_TRACE_EVENT_INJECT is not set -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_TRACE_SINK is not set -# CONFIG_TRACING_EVENTS_GPIO is not set -CONFIG_TRACING_SUPPORT=y -CONFIG_TRAD_SIGNALS=y -# CONFIG_TRANSPARENT_HUGEPAGE is not set -# CONFIG_TREE_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_TRIM_UNUSED_KSYMS is not set -# CONFIG_TRUSTED_FOUNDATIONS is not set -# CONFIG_TRUSTED_KEYS is not set -# CONFIG_TSL2583 is not set -# CONFIG_TSL2591 is not set -# CONFIG_TSL2772 is not set -# CONFIG_TSL2x7x is not set -# CONFIG_TSL4531 is not set -# CONFIG_TSYS01 is not set -# CONFIG_TSYS02D is not set -# CONFIG_TTPCI_EEPROM is not set -CONFIG_TTY=y -# CONFIG_TTY_PRINTK is not set -# CONFIG_TUN is not set -# CONFIG_TUN_VNET_CROSS_LE is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_TWL4030_MADC is not set -# CONFIG_TWL6030_GPADC is not set -# CONFIG_TWL6040_CORE is not set -# CONFIG_TYPEC is not set -# CONFIG_TYPEC_TCPM is not set -# CONFIG_TYPEC_UCSI is not set -# CONFIG_TYPHOON is not set -# CONFIG_UACCESS_WITH_MEMCPY is not set -# CONFIG_UBIFS_ATIME_SUPPORT is not set -# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -# CONFIG_UBIFS_FS_AUTHENTICATION is not set -# CONFIG_UBIFS_FS_ENCRYPTION is not set -CONFIG_UBIFS_FS_LZO=y -# CONFIG_UBIFS_FS_SECURITY is not set -CONFIG_UBIFS_FS_XATTR=y -CONFIG_UBIFS_FS_ZLIB=y -CONFIG_UBIFS_FS_ZSTD=y -# CONFIG_UBSAN is not set -CONFIG_UBSAN_ALIGNMENT=y -CONFIG_UBSAN_BOOL=y -# CONFIG_UBSAN_DIV_ZERO is not set -CONFIG_UBSAN_ENUM=y -# CONFIG_UBSAN_MISC is not set -CONFIG_UBSAN_SHIFT=y -# CONFIG_UBSAN_UNREACHABLE is not set -# CONFIG_UCB1400_CORE is not set -# CONFIG_UCSI is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDMABUF is not set -CONFIG_UEVENT_HELPER=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_UFS_FS is not set -# CONFIG_UHID is not set -CONFIG_UID16=y -# CONFIG_UIO is not set -# CONFIG_ULTRA is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_UNICODE is not set -# CONFIG_UNISYSSPAR is not set -# CONFIG_UNISYS_VISORBUS is not set -CONFIG_UNIX=y -CONFIG_UNIX98_PTYS=y -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_UNIX_DIAG is not set -CONFIG_UNIX_SCM=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_UNWINDER_FRAME_POINTER is not set -# CONFIG_UPROBES is not set -# CONFIG_UPROBE_EVENTS is not set -# CONFIG_US5182D is not set -# CONFIG_USB is not set -# CONFIG_USB4 is not set -# CONFIG_USBIP_CORE is not set -CONFIG_USBIP_VHCI_HC_PORTS=8 -CONFIG_USBIP_VHCI_NR_HCS=1 -# CONFIG_USBIP_VUDC is not set -# CONFIG_USBPCWATCHDOG is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AIRSPY is not set -CONFIG_USB_ALI_M5632=y -# CONFIG_USB_AMD5536UDC is not set -CONFIG_USB_AN2720=y -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -# CONFIG_USB_APPLEDISPLAY is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARMLINUX=y -# CONFIG_USB_ATM is not set -# CONFIG_USB_AUDIO is not set -CONFIG_USB_AUTOSUSPEND_DELAY=2 -# CONFIG_USB_BDC_UDC is not set -CONFIG_USB_BELKIN=y -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDC_COMPOSITE is not set -# CONFIG_USB_CDNS3 is not set -# CONFIG_USB_CDNS3_IMX is not set -# CONFIG_USB_CDNS3_PCI_WRAP is not set -# CONFIG_USB_CDNS_SUPPORT is not set -# CONFIG_USB_CDNSP_PCI is not set -# CONFIG_USB_CHAOSKEY is not set -# CONFIG_USB_CHIPIDEA is not set -# CONFIG_USB_CHIPIDEA_GENERIC is not set -# CONFIG_USB_CHIPIDEA_IMX is not set -# CONFIG_USB_CHIPIDEA_MSM is not set -# CONFIG_USB_CHIPIDEA_PCI is not set -# CONFIG_USB_CHIPIDEA_TEGRA is not set -# CONFIG_USB_CONFIGFS is not set -# CONFIG_USB_CONN_GPIO is not set -# CONFIG_USB_CXACRU is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -CONFIG_USB_DEFAULT_PERSIST=y -# CONFIG_USB_DSBR is not set -# CONFIG_USB_DUMMY_HCD is not set -# CONFIG_USB_DWC2 is not set -# CONFIG_USB_DWC2_DEBUG is not set -# CONFIG_USB_DWC2_DUAL_ROLE is not set -# CONFIG_USB_DWC2_HOST is not set -# CONFIG_USB_DWC2_PERIPHERAL is not set -# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set -# CONFIG_USB_DWC3 is not set -# CONFIG_USB_DWC3_EXYNOS is not set -# CONFIG_USB_DWC3_HAPS is not set -# CONFIG_USB_DWC3_KEYSTONE is not set -# CONFIG_USB_DWC3_OF_SIMPLE is not set -# CONFIG_USB_DWC3_PCI is not set -# CONFIG_USB_DWC3_QCOM is not set -# CONFIG_USB_DWC3_ULPI is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_EG20T is not set -# CONFIG_USB_EHCI_ATH79 is not set -# CONFIG_USB_EHCI_FSL is not set -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_EHCI_HCD_AT91 is not set -# CONFIG_USB_EHCI_HCD_OMAP is not set -# CONFIG_USB_EHCI_HCD_PPC_OF is not set -# CONFIG_USB_EHCI_MSM is not set -# CONFIG_USB_EHCI_MV is not set -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y -# CONFIG_USB_EHSET_TEST_FIXTURE is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EPSON2888 is not set -# CONFIG_USB_ETH is not set -# CONFIG_USB_EZUSB_FX2 is not set -# CONFIG_USB_FEW_INIT_RETRIES is not set -# CONFIG_USB_FOTG210_HCD is not set -# CONFIG_USB_FOTG210_UDC is not set -# CONFIG_USB_FSL_USB2 is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_FUNCTIONFS is not set -# CONFIG_USB_FUSB300 is not set -# CONFIG_USB_GADGET is not set -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_GADGET_DEBUG is not set -# CONFIG_USB_GADGET_DEBUG_FILES is not set -# CONFIG_USB_GADGET_DEBUG_FS is not set -CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -CONFIG_USB_GADGET_VBUS_DRAW=2 -# CONFIG_USB_GADGET_XILINX is not set -# CONFIG_USB_GL860 is not set -# CONFIG_USB_GOKU is not set -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_USB_GR_UDC is not set -# CONFIG_USB_GSPCA is not set -# CONFIG_USB_GSPCA_BENQ is not set -# CONFIG_USB_GSPCA_CONEX is not set -# CONFIG_USB_GSPCA_CPIA1 is not set -# CONFIG_USB_GSPCA_DTCS033 is not set -# CONFIG_USB_GSPCA_ETOMS is not set -# CONFIG_USB_GSPCA_FINEPIX is not set -# CONFIG_USB_GSPCA_JEILINJ is not set -# CONFIG_USB_GSPCA_JL2005BCD is not set -# CONFIG_USB_GSPCA_KINECT is not set -# CONFIG_USB_GSPCA_KONICA is not set -# CONFIG_USB_GSPCA_MARS is not set -# CONFIG_USB_GSPCA_MR97310A is not set -# CONFIG_USB_GSPCA_NW80X is not set -# CONFIG_USB_GSPCA_OV519 is not set -# CONFIG_USB_GSPCA_OV534 is not set -# CONFIG_USB_GSPCA_OV534_9 is not set -# CONFIG_USB_GSPCA_PAC207 is not set -# CONFIG_USB_GSPCA_PAC7302 is not set -# CONFIG_USB_GSPCA_PAC7311 is not set -# CONFIG_USB_GSPCA_SE401 is not set -# CONFIG_USB_GSPCA_SN9C2028 is not set -# CONFIG_USB_GSPCA_SN9C20X is not set -# CONFIG_USB_GSPCA_SONIXB is not set -# CONFIG_USB_GSPCA_SONIXJ is not set -# CONFIG_USB_GSPCA_SPCA1528 is not set -# CONFIG_USB_GSPCA_SPCA500 is not set -# CONFIG_USB_GSPCA_SPCA501 is not set -# CONFIG_USB_GSPCA_SPCA505 is not set -# CONFIG_USB_GSPCA_SPCA506 is not set -# CONFIG_USB_GSPCA_SPCA508 is not set -# CONFIG_USB_GSPCA_SPCA561 is not set -# CONFIG_USB_GSPCA_SQ905 is not set -# CONFIG_USB_GSPCA_SQ905C is not set -# CONFIG_USB_GSPCA_SQ930X is not set -# CONFIG_USB_GSPCA_STK014 is not set -# CONFIG_USB_GSPCA_STK1135 is not set -# CONFIG_USB_GSPCA_STV0680 is not set -# CONFIG_USB_GSPCA_SUNPLUS is not set -# CONFIG_USB_GSPCA_T613 is not set -# CONFIG_USB_GSPCA_TOPRO is not set -# CONFIG_USB_GSPCA_TOUPTEK is not set -# CONFIG_USB_GSPCA_TV8532 is not set -# CONFIG_USB_GSPCA_VC032X is not set -# CONFIG_USB_GSPCA_VICAM is not set -# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -# CONFIG_USB_GSPCA_ZC3XX is not set -# CONFIG_USB_G_ACM_MS is not set -# CONFIG_USB_G_DBGP is not set -# CONFIG_USB_G_HID is not set -# CONFIG_USB_G_MULTI is not set -# CONFIG_USB_G_NCM is not set -# CONFIG_USB_G_NOKIA is not set -# CONFIG_USB_G_PRINTER is not set -# CONFIG_USB_G_SERIAL is not set -# CONFIG_USB_G_WEBCAM is not set -# CONFIG_USB_HACKRF is not set -# CONFIG_USB_HCD_TEST_MODE is not set -# CONFIG_USB_HID is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_HSIC_USB3503 is not set -# CONFIG_USB_HSIC_USB4604 is not set -# CONFIG_USB_HSO is not set -# CONFIG_USB_HUB_USB251XB is not set -# CONFIG_USB_HWA_HCD is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_IMX21_HCD is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_IPHETH is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1301 is not set -# CONFIG_USB_ISP1362_HCD is not set -# CONFIG_USB_ISP1760 is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_KBD is not set -# CONFIG_USB_KC2190 is not set -# CONFIG_USB_LAN78XX is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set -# CONFIG_USB_LED_TRIG is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LGM_PHY is not set -# CONFIG_USB_LINK_LAYER_TEST is not set -# CONFIG_USB_M5602 is not set -# CONFIG_USB_M66592 is not set -# CONFIG_USB_MASS_STORAGE is not set -# CONFIG_USB_MAX3420_UDC is not set -# CONFIG_USB_MAX3421_HCD is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_MIDI_GADGET is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_MSI2500 is not set -# CONFIG_USB_MSM_OTG is not set -# CONFIG_USB_MTU3 is not set -# CONFIG_USB_MUSB_GADGET is not set -# CONFIG_USB_MUSB_HDRC is not set -# CONFIG_USB_MUSB_HOST is not set -# CONFIG_USB_MV_U3D is not set -# CONFIG_USB_MV_UDC is not set -# CONFIG_USB_MXS_PHY is not set -# CONFIG_USB_NET2272 is not set -# CONFIG_USB_NET2280 is not set -# CONFIG_USB_NET_AQC111 is not set -# CONFIG_USB_NET_AX88179_178A is not set -# CONFIG_USB_NET_AX8817X is not set -# CONFIG_USB_NET_CDCETHER is not set -# CONFIG_USB_NET_CDC_EEM is not set -# CONFIG_USB_NET_CDC_MBIM is not set -# CONFIG_USB_NET_CDC_NCM is not set -# CONFIG_USB_NET_CDC_SUBSET is not set -# CONFIG_USB_NET_CH9200 is not set -# CONFIG_USB_NET_CX82310_ETH is not set -# CONFIG_USB_NET_DM9601 is not set -# CONFIG_USB_NET_DRIVERS is not set -# CONFIG_USB_NET_GL620A is not set -# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set -# CONFIG_USB_NET_INT51X1 is not set -# CONFIG_USB_NET_KALMIA is not set -# CONFIG_USB_NET_MCS7830 is not set -# CONFIG_USB_NET_NET1080 is not set -# CONFIG_USB_NET_PLUSB is not set -# CONFIG_USB_NET_QMI_WWAN is not set -# CONFIG_USB_NET_RNDIS_HOST is not set -# CONFIG_USB_NET_RNDIS_WLAN is not set -# CONFIG_USB_NET_SMSC75XX is not set -# CONFIG_USB_NET_SMSC95XX is not set -# CONFIG_USB_NET_SR9700 is not set -# CONFIG_USB_NET_SR9800 is not set -# CONFIG_USB_NET_ZAURUS is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_OHCI_HCD_PCI is not set -# CONFIG_USB_OHCI_HCD_PPC_OF is not set -# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set -# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set -# CONFIG_USB_OHCI_HCD_SSB is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set -# CONFIG_USB_OTG_FSM is not set -# CONFIG_USB_OTG_PRODUCTLIST is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_PCI is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_PHY is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_PWC_INPUT_EVDEV is not set -# CONFIG_USB_PXA27X is not set -# CONFIG_USB_R8A66597 is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_RAW_GADGET is not set -# CONFIG_USB_RCAR_PHY is not set -# CONFIG_USB_RENESAS_USBHS is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ROLES_INTEL_XHCI is not set -# CONFIG_USB_ROLE_SWITCH is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_RTL8152 is not set -# CONFIG_USB_RTL8153_ECM is not set -# CONFIG_USB_S2255 is not set -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_AIRCABLE is not set -# CONFIG_USB_SERIAL_ARK3116 is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_CH341 is not set -# CONFIG_USB_SERIAL_CP210X is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_DEBUG is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_F81232 is not set -# CONFIG_USB_SERIAL_F8153X is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_GARMIN is not set -CONFIG_USB_SERIAL_GENERIC=y -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_IUU is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -CONFIG_USB_SERIAL_KEYSPAN_MPR=y -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -CONFIG_USB_SERIAL_KEYSPAN_USA18X=y -CONFIG_USB_SERIAL_KEYSPAN_USA19=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -CONFIG_USB_SERIAL_KEYSPAN_USA19W=y -CONFIG_USB_SERIAL_KEYSPAN_USA28=y -CONFIG_USB_SERIAL_KEYSPAN_USA28X=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y -CONFIG_USB_SERIAL_KEYSPAN_USA49W=y -CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_METRO is not set -# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set -# CONFIG_USB_SERIAL_MOS7720 is not set -# CONFIG_USB_SERIAL_MOS7840 is not set -# CONFIG_USB_SERIAL_MXUPORT is not set -# CONFIG_USB_SERIAL_NAVMAN is not set -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_SERIAL_OPTICON is not set -# CONFIG_USB_SERIAL_OPTION is not set -# CONFIG_USB_SERIAL_OTI6858 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_QCAUX is not set -# CONFIG_USB_SERIAL_QT2 is not set -# CONFIG_USB_SERIAL_QUALCOMM is not set -# CONFIG_USB_SERIAL_SAFE is not set -CONFIG_USB_SERIAL_SAFE_PADDED=y -# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set -# CONFIG_USB_SERIAL_SIMPLE is not set -# CONFIG_USB_SERIAL_SPCP8X5 is not set -# CONFIG_USB_SERIAL_SSU100 is not set -# CONFIG_USB_SERIAL_SYMBOL is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_UPD78F0730 is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_WISHBONE is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_XR is not set -# CONFIG_USB_SERIAL_XSENS_MT is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_SIERRA_NET is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_SNP_UDC_PLAT is not set -# CONFIG_USB_SPEEDTOUCH is not set -# CONFIG_USB_STKWEBCAM is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_ENE_UB6250 is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_REALTEK is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STV06XX is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_USB_SWITCH_FSA9480 is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_TMC is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_UAS is not set -# CONFIG_USB_UEAGLEATM is not set -# CONFIG_USB_ULPI is not set -# CONFIG_USB_ULPI_BUS is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_USS720 is not set -# CONFIG_USB_VIDEO_CLASS is not set -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -# CONFIG_USB_VL600 is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set -# CONFIG_USB_XHCI_DBGCAP is not set -# CONFIG_USB_XHCI_HCD is not set -# CONFIG_USB_XHCI_MVEBU is not set -# CONFIG_USB_XHCI_PCI_RENESAS is not set -# CONFIG_USB_XUSBATM is not set -# CONFIG_USB_YUREX is not set -# CONFIG_USB_ZD1201 is not set -# CONFIG_USB_ZERO is not set -# CONFIG_USB_ZR364XX is not set -# CONFIG_USELIB is not set -# CONFIG_USERFAULTFD is not set -# CONFIG_USERIO is not set -# CONFIG_USE_OF is not set -# CONFIG_UTS_NS is not set -# CONFIG_UWB is not set -# CONFIG_U_SERIAL_CONSOLE is not set -# CONFIG_V4L_MEM2MEM_DRIVERS is not set -# CONFIG_V4L_PLATFORM_DRIVERS is not set -# CONFIG_V4L_TEST_DRIVERS is not set -# CONFIG_VALIDATE_FS_PARSER is not set -# CONFIG_VBOXGUEST is not set -# CONFIG_VCNL3020 is not set -# CONFIG_VCNL4000 is not set -# CONFIG_VCNL4035 is not set -# CONFIG_VDPA is not set -CONFIG_VDSO=y -# CONFIG_VEML6030 is not set -# CONFIG_VEML6070 is not set -# CONFIG_VETH is not set -# CONFIG_VEXPRESS_CONFIG is not set -# CONFIG_VF610_ADC is not set -# CONFIG_VF610_DAC is not set -# CONFIG_VFAT_FS is not set -# CONFIG_VFIO is not set -# CONFIG_VGASTATE is not set -# CONFIG_VGA_ARB is not set -# CONFIG_VGA_CONSOLE is not set -# CONFIG_VGA_SWITCHEROO is not set -# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set -CONFIG_VHOST_MENU=y -# CONFIG_VHOST_NET is not set -# CONFIG_VHOST_VSOCK is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_VIDEO_AD5398 is not set -# CONFIG_VIDEO_AD5820 is not set -# CONFIG_VIDEO_AD9389B is not set -# CONFIG_VIDEO_ADP1653 is not set -# CONFIG_VIDEO_ADV7170 is not set -# CONFIG_VIDEO_ADV7175 is not set -# CONFIG_VIDEO_ADV7180 is not set -# CONFIG_VIDEO_ADV7183 is not set -# CONFIG_VIDEO_ADV7343 is not set -# CONFIG_VIDEO_ADV7393 is not set -# CONFIG_VIDEO_ADV748X is not set -# CONFIG_VIDEO_ADV7511 is not set -# CONFIG_VIDEO_ADV7604 is not set -# CONFIG_VIDEO_ADV7842 is not set -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_AK7375 is not set -# CONFIG_VIDEO_AK881X is not set -# CONFIG_VIDEO_AM437X_VPFE is not set -# CONFIG_VIDEO_ASPEED is not set -# CONFIG_VIDEO_ATMEL_ISC is not set -# CONFIG_VIDEO_ATMEL_ISI is not set -# CONFIG_VIDEO_AU0828 is not set -# CONFIG_VIDEO_BT819 is not set -# CONFIG_VIDEO_BT848 is not set -# CONFIG_VIDEO_BT856 is not set -# CONFIG_VIDEO_BT866 is not set -# CONFIG_VIDEO_CADENCE is not set -# CONFIG_VIDEO_CAFE_CCIC is not set -# CONFIG_VIDEO_CCS is not set -# CONFIG_VIDEO_COBALT is not set -# CONFIG_VIDEO_CODA is not set -# CONFIG_VIDEO_CS3308 is not set -# CONFIG_VIDEO_CS5345 is not set -# CONFIG_VIDEO_CS53L32A is not set -# CONFIG_VIDEO_CX231XX is not set -# CONFIG_VIDEO_CX2341X is not set -# CONFIG_VIDEO_CX25821 is not set -# CONFIG_VIDEO_CX25840 is not set -# CONFIG_VIDEO_CX88 is not set -# CONFIG_VIDEO_DEV is not set -# CONFIG_VIDEO_DM6446_CCDC is not set -# CONFIG_VIDEO_DT3155 is not set -# CONFIG_VIDEO_DW9714 is not set -# CONFIG_VIDEO_DW9768 is not set -# CONFIG_VIDEO_DW9807_VCM is not set -# CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_ET8EK8 is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_GO7007 is not set -# CONFIG_VIDEO_GS1662 is not set -# CONFIG_VIDEO_HDPVR is not set -# CONFIG_VIDEO_HEXIUM_GEMINI is not set -# CONFIG_VIDEO_HEXIUM_ORION is not set -# CONFIG_VIDEO_HI556 is not set -# CONFIG_VIDEO_I2C is not set -# CONFIG_VIDEO_IMX208 is not set -# CONFIG_VIDEO_IMX214 is not set -# CONFIG_VIDEO_IMX219 is not set -# CONFIG_VIDEO_IMX258 is not set -# CONFIG_VIDEO_IMX274 is not set -# CONFIG_VIDEO_IMX290 is not set -# CONFIG_VIDEO_IMX319 is not set -# CONFIG_VIDEO_IMX334 is not set -# CONFIG_VIDEO_IMX335 is not set -# CONFIG_VIDEO_IMX355 is not set -# CONFIG_VIDEO_IMX412 is not set -# CONFIG_VIDEO_IMX477 is not set -# CONFIG_VIDEO_IMX8_JPEG is not set -# CONFIG_VIDEO_IMX_PXP is not set -# CONFIG_VIDEO_IPU3_CIO2 is not set -# CONFIG_VIDEO_IRS1125 is not set -# CONFIG_VIDEO_IR_I2C is not set -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_KS0127 is not set -# CONFIG_VIDEO_LM3560 is not set -# CONFIG_VIDEO_LM3646 is not set -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_M5MOLS is not set -# CONFIG_VIDEO_MAX9286 is not set -# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set -# CONFIG_VIDEO_ML86V7667 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_MT9M001 is not set -# CONFIG_VIDEO_MT9M032 is not set -# CONFIG_VIDEO_MT9M111 is not set -# CONFIG_VIDEO_MT9P031 is not set -# CONFIG_VIDEO_MT9T001 is not set -# CONFIG_VIDEO_MT9T112 is not set -# CONFIG_VIDEO_MT9V011 is not set -# CONFIG_VIDEO_MT9V032 is not set -# CONFIG_VIDEO_MT9V111 is not set -# CONFIG_VIDEO_MUX is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_NOON010PC30 is not set -# CONFIG_VIDEO_OMAP2_VOUT is not set -# CONFIG_VIDEO_OV02A10 is not set -# CONFIG_VIDEO_OV13858 is not set -# CONFIG_VIDEO_OV2311 is not set -# CONFIG_VIDEO_OV2640 is not set -# CONFIG_VIDEO_OV2659 is not set -# CONFIG_VIDEO_OV2680 is not set -# CONFIG_VIDEO_OV2685 is not set -# CONFIG_VIDEO_OV2740 is not set -# CONFIG_VIDEO_OV5640 is not set -# CONFIG_VIDEO_OV5645 is not set -# CONFIG_VIDEO_OV5647 is not set -# CONFIG_VIDEO_OV5648 is not set -# CONFIG_VIDEO_OV5670 is not set -# CONFIG_VIDEO_OV5675 is not set -# CONFIG_VIDEO_OV5695 is not set -# CONFIG_VIDEO_OV6650 is not set -# CONFIG_VIDEO_OV7251 is not set -# CONFIG_VIDEO_OV7640 is not set -# CONFIG_VIDEO_OV7670 is not set -# CONFIG_VIDEO_OV772X is not set -# CONFIG_VIDEO_OV7740 is not set -# CONFIG_VIDEO_OV8856 is not set -# CONFIG_VIDEO_OV8865 is not set -# CONFIG_VIDEO_OV9281 is not set -# CONFIG_VIDEO_OV9282 is not set -# CONFIG_VIDEO_OV9640 is not set -# CONFIG_VIDEO_OV9650 is not set -# CONFIG_VIDEO_OV9734 is not set -# CONFIG_VIDEO_PVRUSB2 is not set -# CONFIG_VIDEO_RDACM20 is not set -# CONFIG_VIDEO_RDACM21 is not set -# CONFIG_VIDEO_RJ54N1 is not set -# CONFIG_VIDEO_ROCKCHIP_ISP1 is not set -# CONFIG_VIDEO_S5C73M3 is not set -# CONFIG_VIDEO_S5K4ECGX is not set -# CONFIG_VIDEO_S5K5BAF is not set -# CONFIG_VIDEO_S5K6A3 is not set -# CONFIG_VIDEO_S5K6AA is not set -# CONFIG_VIDEO_SAA6588 is not set -# CONFIG_VIDEO_SAA6752HS is not set -# CONFIG_VIDEO_SAA7110 is not set -# CONFIG_VIDEO_SAA711X is not set -# CONFIG_VIDEO_SAA7127 is not set -# CONFIG_VIDEO_SAA7134 is not set -# CONFIG_VIDEO_SAA7164 is not set -# CONFIG_VIDEO_SAA717X is not set -# CONFIG_VIDEO_SAA7185 is not set -# CONFIG_VIDEO_SH_MOBILE_CEU is not set -# CONFIG_VIDEO_SMIAPP is not set -# CONFIG_VIDEO_SOLO6X10 is not set -# CONFIG_VIDEO_SONY_BTF_MPX is not set -# CONFIG_VIDEO_SR030PC30 is not set -# CONFIG_VIDEO_STK1160_COMMON is not set -# CONFIG_VIDEO_ST_MIPID02 is not set -# CONFIG_VIDEO_TC358743 is not set -# CONFIG_VIDEO_TDA1997X is not set -# CONFIG_VIDEO_TDA7432 is not set -# CONFIG_VIDEO_TDA9840 is not set -# CONFIG_VIDEO_TEA6415C is not set -# CONFIG_VIDEO_TEA6420 is not set -# CONFIG_VIDEO_THS7303 is not set -# CONFIG_VIDEO_THS8200 is not set -# CONFIG_VIDEO_TIMBERDALE is not set -# CONFIG_VIDEO_TLV320AIC23B is not set -# CONFIG_VIDEO_TM6000 is not set -# CONFIG_VIDEO_TVAUDIO is not set -# CONFIG_VIDEO_TVP514X is not set -# CONFIG_VIDEO_TVP5150 is not set -# CONFIG_VIDEO_TVP7002 is not set -# CONFIG_VIDEO_TW2804 is not set -# CONFIG_VIDEO_TW5864 is not set -# CONFIG_VIDEO_TW68 is not set -# CONFIG_VIDEO_TW9903 is not set -# CONFIG_VIDEO_TW9906 is not set -# CONFIG_VIDEO_TW9910 is not set -# CONFIG_VIDEO_UDA1342 is not set -# CONFIG_VIDEO_UPD64031A is not set -# CONFIG_VIDEO_UPD64083 is not set -# CONFIG_VIDEO_USBTV is not set -# CONFIG_VIDEO_USBVISION is not set -# CONFIG_VIDEO_V4L2 is not set -# CONFIG_VIDEO_VP27SMPX is not set -# CONFIG_VIDEO_VPX3220 is not set -# CONFIG_VIDEO_VS6624 is not set -# CONFIG_VIDEO_WM8739 is not set -# CONFIG_VIDEO_WM8775 is not set -# CONFIG_VIDEO_XILINX is not set -# CONFIG_VIDEO_ZORAN is not set -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_BLK_SCSI is not set -# CONFIG_VIRTIO_CONSOLE is not set -# CONFIG_VIRTIO_FS is not set -# CONFIG_VIRTIO_INPUT is not set -# CONFIG_VIRTIO_IOMMU is not set -CONFIG_VIRTIO_MENU=y -# CONFIG_VIRTIO_MMIO is not set -# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set -# CONFIG_VIRTIO_PCI is not set -# CONFIG_VIRTUALIZATION is not set -# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -# CONFIG_VIRT_DRIVERS is not set -CONFIG_VIRT_TO_BUS=y -# CONFIG_VITESSE_PHY is not set -# CONFIG_VL53L0X_I2C is not set -# CONFIG_VL6180 is not set -CONFIG_VLAN_8021Q=y -# CONFIG_VLAN_8021Q_GVRP is not set -# CONFIG_VLAN_8021Q_MVRP is not set -# CONFIG_VME_BUS is not set -# CONFIG_VMLINUX_MAP is not set -# CONFIG_VMSPLIT_1G is not set -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_2G_OPT is not set -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_3G_OPT is not set -# CONFIG_VMWARE_PVSCSI is not set -# CONFIG_VMXNET3 is not set -# CONFIG_VM_EVENT_COUNTERS is not set -# CONFIG_VOP_BUS is not set -# CONFIG_VORTEX is not set -# CONFIG_VSOCKETS is not set -# CONFIG_VSOCKETS_DIAG is not set -# CONFIG_VT is not set -# CONFIG_VT6655 is not set -# CONFIG_VT6656 is not set -# CONFIG_VXFS_FS is not set -# CONFIG_VXGE is not set -# CONFIG_VXLAN is not set -# CONFIG_VZ89X is not set -# CONFIG_W1 is not set -# CONFIG_W1_CON is not set -# CONFIG_W1_MASTER_DS1WM is not set -# CONFIG_W1_MASTER_DS2482 is not set -# CONFIG_W1_MASTER_DS2490 is not set -# CONFIG_W1_MASTER_GPIO is not set -# CONFIG_W1_MASTER_MATROX is not set -# CONFIG_W1_MASTER_SGI is not set -# CONFIG_W1_SLAVE_DS2405 is not set -# CONFIG_W1_SLAVE_DS2406 is not set -# CONFIG_W1_SLAVE_DS2408 is not set -# CONFIG_W1_SLAVE_DS2413 is not set -# CONFIG_W1_SLAVE_DS2423 is not set -# CONFIG_W1_SLAVE_DS2430 is not set -# CONFIG_W1_SLAVE_DS2431 is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2438 is not set -# CONFIG_W1_SLAVE_DS250X is not set -# CONFIG_W1_SLAVE_DS2780 is not set -# CONFIG_W1_SLAVE_DS2781 is not set -# CONFIG_W1_SLAVE_DS2805 is not set -# CONFIG_W1_SLAVE_DS28E04 is not set -# CONFIG_W1_SLAVE_DS28E17 is not set -# CONFIG_W1_SLAVE_SMEM is not set -# CONFIG_W1_SLAVE_THERM is not set -# CONFIG_W83627HF_WDT is not set -# CONFIG_W83877F_WDT is not set -# CONFIG_W83977F_WDT is not set -# CONFIG_WAN is not set -# CONFIG_WANXL is not set -# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_CORE is not set -CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y -# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set -# CONFIG_WATCHDOG_NOWAYOUT is not set -CONFIG_WATCHDOG_OPEN_TIMEOUT=0 -# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set -# CONFIG_WATCHDOG_SYSFS is not set -# CONFIG_WATCH_QUEUE is not set -# CONFIG_WD80x3 is not set -# CONFIG_WDAT_WDT is not set -# CONFIG_WDTPCI is not set -# CONFIG_WERROR is not set -# CONFIG_WEXT_CORE is not set -# CONFIG_WEXT_PRIV is not set -# CONFIG_WEXT_PROC is not set -# CONFIG_WEXT_SPY is not set -CONFIG_WILINK_PLATFORM_DATA=y -# CONFIG_WIMAX is not set -# CONFIG_WIREGUARD is not set -CONFIG_WIRELESS=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_WIRELESS_WDS is not set -# CONFIG_WIZNET_W5100 is not set -# CONFIG_WIZNET_W5300 is not set -# CONFIG_WL1251 is not set -# CONFIG_WL12XX is not set -# CONFIG_WL18XX is not set -CONFIG_WLAN=y -# CONFIG_WLAN_VENDOR_ADMTEK is not set -# CONFIG_WLAN_VENDOR_ATH is not set -# CONFIG_WLAN_VENDOR_ATMEL is not set -# CONFIG_WLAN_VENDOR_BROADCOM is not set -# CONFIG_WLAN_VENDOR_CISCO is not set -# CONFIG_WLAN_VENDOR_INTEL is not set -# CONFIG_WLAN_VENDOR_INTERSIL is not set -# CONFIG_WLAN_VENDOR_MARVELL is not set -# CONFIG_WLAN_VENDOR_MEDIATEK is not set -# CONFIG_WLAN_VENDOR_MICROCHIP is not set -# CONFIG_WLAN_VENDOR_QUANTENNA is not set -# CONFIG_WLAN_VENDOR_RALINK is not set -# CONFIG_WLAN_VENDOR_REALTEK is not set -# CONFIG_WLAN_VENDOR_RSI is not set -# CONFIG_WLAN_VENDOR_ST is not set -# CONFIG_WLAN_VENDOR_TI is not set -# CONFIG_WLAN_VENDOR_ZYDAS is not set -# CONFIG_WLCORE is not set -CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y -# CONFIG_WQ_WATCHDOG is not set -# CONFIG_WWAN is not set -# CONFIG_WWAN_HWSIM is not set -# CONFIG_WW_MUTEX_SELFTEST is not set -# CONFIG_X25 is not set -# CONFIG_X509_CERTIFICATE_PARSER is not set -# CONFIG_X86_PKG_TEMP_THERMAL is not set -CONFIG_X86_SYSFB=y -# CONFIG_XDP_SOCKETS is not set -# CONFIG_XEN is not set -# CONFIG_XEN_GRANT_DMA_ALLOC is not set -# CONFIG_XEN_PVCALLS_FRONTEND is not set -CONFIG_XEN_SCRUB_PAGES_DEFAULT=y -CONFIG_XFRM=y -# CONFIG_XFRM_INTERFACE is not set -# CONFIG_XFRM_IPCOMP is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_USER is not set -# CONFIG_XFS_DEBUG is not set -# CONFIG_XFS_FS is not set -# CONFIG_XFS_ONLINE_SCRUB is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_RT is not set -# CONFIG_XFS_SUPPORT_V4 is not set -# CONFIG_XFS_WARN is not set -# CONFIG_XILINX_AXI_EMAC is not set -# CONFIG_XILINX_DMA is not set -# CONFIG_XILINX_EMACLITE is not set -# CONFIG_XILINX_GMII2RGMII is not set -# CONFIG_XILINX_LL_TEMAC is not set -# CONFIG_XILINX_SDFEC is not set -# CONFIG_XILINX_VCU is not set -# CONFIG_XILINX_WATCHDOG is not set -# CONFIG_XILINX_XADC is not set -# CONFIG_XILINX_ZYNQMP_DMA is not set -# CONFIG_XILINX_ZYNQMP_DPDMA is not set -# CONFIG_XILLYBUS is not set -# CONFIG_XILLYUSB is not set -# CONFIG_XIL_AXIS_FIFO is not set -# CONFIG_XIP_KERNEL is not set -# CONFIG_XMON is not set -CONFIG_XZ_DEC=y -# CONFIG_XZ_DEC_ARM is not set -# CONFIG_XZ_DEC_ARMTHUMB is not set -# CONFIG_XZ_DEC_BCJ is not set -# CONFIG_XZ_DEC_IA64 is not set -# CONFIG_XZ_DEC_POWERPC is not set -# CONFIG_XZ_DEC_SPARC is not set -# CONFIG_XZ_DEC_TEST is not set -# CONFIG_XZ_DEC_X86 is not set -# CONFIG_YAM is not set -# CONFIG_YAMAHA_YAS530 is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_YENTA is not set -# CONFIG_YENTA_O2 is not set -# CONFIG_YENTA_RICOH is not set -# CONFIG_YENTA_TI is not set -# CONFIG_YENTA_TOSHIBA is not set -# CONFIG_ZBUD is not set -# CONFIG_ZD1211RW is not set -# CONFIG_ZD1211RW_DEBUG is not set -# CONFIG_ZEROPLUS_FF is not set -# CONFIG_ZERO_CALL_USED_REGS is not set -# CONFIG_ZIIRAVE_WATCHDOG is not set -# CONFIG_ZISOFS is not set -# CONFIG_ZLIB_DEFLATE is not set -# CONFIG_ZLIB_INFLATE is not set -CONFIG_ZONE_DMA=y -# CONFIG_ZOPT2201 is not set -# CONFIG_ZPA2326 is not set -# CONFIG_ZPOOL is not set -# CONFIG_ZRAM is not set -# CONFIG_ZRAM_DEF_COMP_842 is not set -# CONFIG_ZRAM_DEF_COMP_LZ4 is not set -# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set -# CONFIG_ZRAM_DEF_COMP_LZO is not set -# CONFIG_ZRAM_DEF_COMP_LZORLE is not set -# CONFIG_ZRAM_DEF_COMP_ZSTD is not set -# CONFIG_ZRAM_MEMORY_TRACKING is not set -# CONFIG_ZSMALLOC is not set -# CONFIG_ZX_TDM is not set diff --git a/target/linux/generic/hack-5.15/204-module_strip.patch b/target/linux/generic/hack-5.15/204-module_strip.patch deleted file mode 100644 index e650c1b18471ab..00000000000000 --- a/target/linux/generic/hack-5.15/204-module_strip.patch +++ /dev/null @@ -1,212 +0,0 @@ -From a779a482fb9b9f8fcdf8b2519c789b4b9bb5dd05 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 16:56:48 +0200 -Subject: build: add a hack for removing non-essential module info - -Signed-off-by: Felix Fietkau ---- - include/linux/module.h | 13 ++++++++----- - include/linux/moduleparam.h | 15 ++++++++++++--- - init/Kconfig | 7 +++++++ - kernel/module.c | 5 ++++- - scripts/mod/modpost.c | 12 ++++++++++++ - 5 files changed, 43 insertions(+), 9 deletions(-) - ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -164,6 +164,7 @@ extern void cleanup_module(void); - - /* Generic info of form tag = "info" */ - #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) -+#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info) - - /* For userspace: you can also call me... */ - #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) -@@ -233,12 +234,12 @@ extern void cleanup_module(void); - * Author(s), use "Name " or just "Name", for multiple - * authors use multiple MODULE_AUTHOR() statements/lines. - */ --#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) -+#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author) - - /* What your module does. */ --#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) -+#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description) - --#ifdef MODULE -+#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED) - /* Creates an alias so file2alias.c can find device table. */ - #define MODULE_DEVICE_TABLE(type, name) \ - extern typeof(name) __mod_##type##__##name##_device_table \ -@@ -265,7 +266,9 @@ extern typeof(name) __mod_##type##__##na - */ - - #if defined(MODULE) || !defined(CONFIG_SYSFS) --#define MODULE_VERSION(_version) MODULE_INFO(version, _version) -+#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version) -+#elif defined(CONFIG_MODULE_STRIPPED) -+#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version) - #else - #define MODULE_VERSION(_version) \ - MODULE_INFO(version, _version); \ -@@ -288,7 +291,7 @@ extern typeof(name) __mod_##type##__##na - /* Optional firmware file (or files) needed by the module - * format is simply firmware file name. Multiple firmware - * files require multiple MODULE_FIRMWARE() specifiers */ --#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware) -+#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware) - - #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, #ns) - ---- a/include/linux/moduleparam.h -+++ b/include/linux/moduleparam.h -@@ -20,6 +20,16 @@ - /* Chosen so that structs with an unsigned long line up. */ - #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) - -+/* This struct is here for syntactic coherency, it is not used */ -+#define __MODULE_INFO_DISABLED(name) \ -+ struct __UNIQUE_ID(name) {} -+ -+#ifdef CONFIG_MODULE_STRIPPED -+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name) -+#else -+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info) -+#endif -+ - #define __MODULE_INFO(tag, name, info) \ - static const char __UNIQUE_ID(name)[] \ - __used __section(".modinfo") __aligned(1) \ -@@ -31,7 +41,7 @@ - /* One for each parameter, describing how to use it. Some files do - multiple of these per line, so can't just use MODULE_INFO. */ - #define MODULE_PARM_DESC(_parm, desc) \ -- __MODULE_INFO(parm, _parm, #_parm ":" desc) -+ __MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc) - - struct kernel_param; - ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -2356,6 +2356,13 @@ config UNUSED_KSYMS_WHITELIST - one per line. The path can be absolute, or relative to the kernel - source tree. - -+config MODULE_STRIPPED -+ bool "Reduce module size" -+ depends on MODULES -+ help -+ Remove module parameter descriptions, author info, version, aliases, -+ device tables, etc. -+ - endif # MODULES - - config MODULES_TREE_LOOKUP ---- a/kernel/module.c -+++ b/kernel/module.c -@@ -1218,6 +1218,7 @@ static struct module_attribute *modinfo_ - - static const char vermagic[] = VERMAGIC_STRING; - -+#if defined(CONFIG_MODVERSIONS) || !defined(CONFIG_MODULE_STRIPPED) - static int try_to_force_load(struct module *mod, const char *reason) - { - #ifdef CONFIG_MODULE_FORCE_LOAD -@@ -1229,6 +1230,7 @@ static int try_to_force_load(struct modu - return -ENOEXEC; - #endif - } -+#endif - - #ifdef CONFIG_MODVERSIONS - -@@ -3274,9 +3276,11 @@ static int setup_load_info(struct load_i - - static int check_modinfo(struct module *mod, struct load_info *info, int flags) - { -- const char *modmagic = get_modinfo(info, "vermagic"); - int err; - -+#ifndef CONFIG_MODULE_STRIPPED -+ const char *modmagic = get_modinfo(info, "vermagic"); -+ - if (flags & MODULE_INIT_IGNORE_VERMAGIC) - modmagic = NULL; - -@@ -3297,6 +3301,7 @@ static int check_modinfo(struct module * - mod->name); - add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); - } -+#endif - - check_modinfo_retpoline(mod, info); - ---- a/scripts/mod/modpost.c -+++ b/scripts/mod/modpost.c -@@ -2000,7 +2000,9 @@ static void read_symbols(const char *mod - symname = remove_dot(info.strtab + sym->st_name); - - handle_symbol(mod, &info, sym, symname); -+#ifndef CONFIG_MODULE_STRIPPED - handle_moddevtable(mod, &info, sym, symname); -+#endif - } - - for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { -@@ -2179,8 +2181,10 @@ static void add_header(struct buffer *b, - buf_printf(b, "BUILD_SALT;\n"); - buf_printf(b, "BUILD_LTO_INFO;\n"); - buf_printf(b, "\n"); -+#ifndef CONFIG_MODULE_STRIPPED - buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); - buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); -+#endif - buf_printf(b, "\n"); - buf_printf(b, "__visible struct module __this_module\n"); - buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n"); -@@ -2197,8 +2201,10 @@ static void add_header(struct buffer *b, - - static void add_intree_flag(struct buffer *b, int is_intree) - { -+#ifndef CONFIG_MODULE_STRIPPED - if (is_intree) - buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); -+#endif - } - - /* Cannot check for assembler */ -@@ -2211,8 +2217,10 @@ static void add_retpoline(struct buffer - - static void add_staging_flag(struct buffer *b, const char *name) - { -+#ifndef CONFIG_MODULE_STRIPPED - if (strstarts(name, "drivers/staging")) - buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); -+#endif - } - - /** -@@ -2292,11 +2300,13 @@ static void add_depends(struct buffer *b - - static void add_srcversion(struct buffer *b, struct module *mod) - { -+#ifndef CONFIG_MODULE_STRIPPED - if (mod->srcversion[0]) { - buf_printf(b, "\n"); - buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n", - mod->srcversion); - } -+#endif - } - - static void write_buf(struct buffer *b, const char *fname) -@@ -2545,7 +2555,9 @@ int main(int argc, char **argv) - add_staging_flag(&buf, mod->name); - add_versions(&buf, mod); - add_depends(&buf, mod); -+#ifndef CONFIG_MODULE_STRIPPED - add_moddevtable(&buf, mod); -+#endif - add_srcversion(&buf, mod); - - sprintf(fname, "%s.mod.c", mod->name); diff --git a/target/linux/generic/hack-5.15/205-kconfig-abort-configuration-on-unset-symbol.patch b/target/linux/generic/hack-5.15/205-kconfig-abort-configuration-on-unset-symbol.patch deleted file mode 100644 index a87c7a51169eb3..00000000000000 --- a/target/linux/generic/hack-5.15/205-kconfig-abort-configuration-on-unset-symbol.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 310e8e04a05d9eb43fa9dd7f00143300afcaa37a Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Fri, 11 Nov 2022 13:33:44 +0100 -Subject: [PATCH] kconfig: abort configuration on unset symbol - -When a target configuration has unset Kconfig symbols, the build will -fail when OpenWrt is compiled with V=s and stdin is connected to a tty. - -In case OpenWrt is compiled without either of these preconditions, the -build will succeed with the symbols in question being unset. - -Modify the kernel configuration in a way it fails on unset symbols -regardless of the aforementioned preconditions. - -Signed-off-by: David Bauer ---- - scripts/kconfig/conf.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/scripts/kconfig/conf.c -+++ b/scripts/kconfig/conf.c -@@ -341,6 +341,9 @@ static int conf_askvalue(struct symbol * - } - /* fall through */ - default: -+ if (!tty_stdio && getenv("FAIL_ON_UNCONFIGURED")) { -+ exit(1); -+ } - fflush(stdout); - xfgets(line, sizeof(line), stdin); - break; -@@ -523,6 +526,9 @@ static int conf_choice(struct menu *menu - } - /* fall through */ - case oldaskconfig: -+ if (!tty_stdio && getenv("FAIL_ON_UNCONFIGURED")) { -+ exit(1); -+ } - fflush(stdout); - xfgets(line, sizeof(line), stdin); - strip(line); diff --git a/target/linux/generic/hack-5.15/210-darwin_scripts_include.patch b/target/linux/generic/hack-5.15/210-darwin_scripts_include.patch deleted file mode 100644 index be6adc0d11aa4c..00000000000000 --- a/target/linux/generic/hack-5.15/210-darwin_scripts_include.patch +++ /dev/null @@ -1,3053 +0,0 @@ -From db7c30dcd9a0391bf13b62c9f91e144d762ef43a Mon Sep 17 00:00:00 2001 -From: Florian Fainelli -Date: Fri, 7 Jul 2017 17:00:49 +0200 -Subject: Add an OSX specific patch to make the kernel be compiled - -lede-commit: 3fc2a24f0422b2f55f9ed43f116db3111f700526 -Signed-off-by: Florian Fainelli ---- - scripts/kconfig/Makefile | 3 + - scripts/mod/elf.h | 3007 ++++++++++++++++++++++++++++++++++++++++++++ - scripts/mod/mk_elfconfig.c | 4 + - scripts/mod/modpost.h | 4 + - 4 files changed, 3018 insertions(+) - create mode 100644 scripts/mod/elf.h - ---- /dev/null -+++ b/scripts/mod/elf.h -@@ -0,0 +1,3007 @@ -+/* This file defines standard ELF types, structures, and macros. -+ Copyright (C) 1995-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#ifndef _ELF_H -+#define _ELF_H 1 -+ -+/* Standard ELF types. */ -+ -+#include -+ -+/* Type for a 16-bit quantity. */ -+typedef uint16_t Elf32_Half; -+typedef uint16_t Elf64_Half; -+ -+/* Types for signed and unsigned 32-bit quantities. */ -+typedef uint32_t Elf32_Word; -+typedef int32_t Elf32_Sword; -+typedef uint32_t Elf64_Word; -+typedef int32_t Elf64_Sword; -+ -+/* Types for signed and unsigned 64-bit quantities. */ -+typedef uint64_t Elf32_Xword; -+typedef int64_t Elf32_Sxword; -+typedef uint64_t Elf64_Xword; -+typedef int64_t Elf64_Sxword; -+ -+/* Type of addresses. */ -+typedef uint32_t Elf32_Addr; -+typedef uint64_t Elf64_Addr; -+ -+/* Type of file offsets. */ -+typedef uint32_t Elf32_Off; -+typedef uint64_t Elf64_Off; -+ -+/* Type for section indices, which are 16-bit quantities. */ -+typedef uint16_t Elf32_Section; -+typedef uint16_t Elf64_Section; -+ -+/* Type for version symbol information. */ -+typedef Elf32_Half Elf32_Versym; -+typedef Elf64_Half Elf64_Versym; -+ -+ -+/* The ELF file header. This appears at the start of every ELF file. */ -+ -+#define EI_NIDENT (16) -+ -+typedef struct -+{ -+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ -+ Elf32_Half e_type; /* Object file type */ -+ Elf32_Half e_machine; /* Architecture */ -+ Elf32_Word e_version; /* Object file version */ -+ Elf32_Addr e_entry; /* Entry point virtual address */ -+ Elf32_Off e_phoff; /* Program header table file offset */ -+ Elf32_Off e_shoff; /* Section header table file offset */ -+ Elf32_Word e_flags; /* Processor-specific flags */ -+ Elf32_Half e_ehsize; /* ELF header size in bytes */ -+ Elf32_Half e_phentsize; /* Program header table entry size */ -+ Elf32_Half e_phnum; /* Program header table entry count */ -+ Elf32_Half e_shentsize; /* Section header table entry size */ -+ Elf32_Half e_shnum; /* Section header table entry count */ -+ Elf32_Half e_shstrndx; /* Section header string table index */ -+} Elf32_Ehdr; -+ -+typedef struct -+{ -+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ -+ Elf64_Half e_type; /* Object file type */ -+ Elf64_Half e_machine; /* Architecture */ -+ Elf64_Word e_version; /* Object file version */ -+ Elf64_Addr e_entry; /* Entry point virtual address */ -+ Elf64_Off e_phoff; /* Program header table file offset */ -+ Elf64_Off e_shoff; /* Section header table file offset */ -+ Elf64_Word e_flags; /* Processor-specific flags */ -+ Elf64_Half e_ehsize; /* ELF header size in bytes */ -+ Elf64_Half e_phentsize; /* Program header table entry size */ -+ Elf64_Half e_phnum; /* Program header table entry count */ -+ Elf64_Half e_shentsize; /* Section header table entry size */ -+ Elf64_Half e_shnum; /* Section header table entry count */ -+ Elf64_Half e_shstrndx; /* Section header string table index */ -+} Elf64_Ehdr; -+ -+/* Fields in the e_ident array. The EI_* macros are indices into the -+ array. The macros under each EI_* macro are the values the byte -+ may have. */ -+ -+#define EI_MAG0 0 /* File identification byte 0 index */ -+#define ELFMAG0 0x7f /* Magic number byte 0 */ -+ -+#define EI_MAG1 1 /* File identification byte 1 index */ -+#define ELFMAG1 'E' /* Magic number byte 1 */ -+ -+#define EI_MAG2 2 /* File identification byte 2 index */ -+#define ELFMAG2 'L' /* Magic number byte 2 */ -+ -+#define EI_MAG3 3 /* File identification byte 3 index */ -+#define ELFMAG3 'F' /* Magic number byte 3 */ -+ -+/* Conglomeration of the identification bytes, for easy testing as a word. */ -+#define ELFMAG "\177ELF" -+#define SELFMAG 4 -+ -+#define EI_CLASS 4 /* File class byte index */ -+#define ELFCLASSNONE 0 /* Invalid class */ -+#define ELFCLASS32 1 /* 32-bit objects */ -+#define ELFCLASS64 2 /* 64-bit objects */ -+#define ELFCLASSNUM 3 -+ -+#define EI_DATA 5 /* Data encoding byte index */ -+#define ELFDATANONE 0 /* Invalid data encoding */ -+#define ELFDATA2LSB 1 /* 2's complement, little endian */ -+#define ELFDATA2MSB 2 /* 2's complement, big endian */ -+#define ELFDATANUM 3 -+ -+#define EI_VERSION 6 /* File version byte index */ -+ /* Value must be EV_CURRENT */ -+ -+#define EI_OSABI 7 /* OS ABI identification */ -+#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -+#define ELFOSABI_SYSV 0 /* Alias. */ -+#define ELFOSABI_HPUX 1 /* HP-UX */ -+#define ELFOSABI_NETBSD 2 /* NetBSD. */ -+#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ -+#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ -+#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ -+#define ELFOSABI_AIX 7 /* IBM AIX. */ -+#define ELFOSABI_IRIX 8 /* SGI Irix. */ -+#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ -+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ -+#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ -+#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ -+#define ELFOSABI_ARM 97 /* ARM */ -+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ -+ -+#define EI_ABIVERSION 8 /* ABI version */ -+ -+#define EI_PAD 9 /* Byte index of padding bytes */ -+ -+/* Legal values for e_type (object file type). */ -+ -+#define ET_NONE 0 /* No file type */ -+#define ET_REL 1 /* Relocatable file */ -+#define ET_EXEC 2 /* Executable file */ -+#define ET_DYN 3 /* Shared object file */ -+#define ET_CORE 4 /* Core file */ -+#define ET_NUM 5 /* Number of defined types */ -+#define ET_LOOS 0xfe00 /* OS-specific range start */ -+#define ET_HIOS 0xfeff /* OS-specific range end */ -+#define ET_LOPROC 0xff00 /* Processor-specific range start */ -+#define ET_HIPROC 0xffff /* Processor-specific range end */ -+ -+/* Legal values for e_machine (architecture). */ -+ -+#define EM_NONE 0 /* No machine */ -+#define EM_M32 1 /* AT&T WE 32100 */ -+#define EM_SPARC 2 /* SUN SPARC */ -+#define EM_386 3 /* Intel 80386 */ -+#define EM_68K 4 /* Motorola m68k family */ -+#define EM_88K 5 /* Motorola m88k family */ -+#define EM_860 7 /* Intel 80860 */ -+#define EM_MIPS 8 /* MIPS R3000 big-endian */ -+#define EM_S370 9 /* IBM System/370 */ -+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ -+ -+#define EM_PARISC 15 /* HPPA */ -+#define EM_VPP500 17 /* Fujitsu VPP500 */ -+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -+#define EM_960 19 /* Intel 80960 */ -+#define EM_PPC 20 /* PowerPC */ -+#define EM_PPC64 21 /* PowerPC 64-bit */ -+#define EM_S390 22 /* IBM S390 */ -+ -+#define EM_V800 36 /* NEC V800 series */ -+#define EM_FR20 37 /* Fujitsu FR20 */ -+#define EM_RH32 38 /* TRW RH-32 */ -+#define EM_RCE 39 /* Motorola RCE */ -+#define EM_ARM 40 /* ARM */ -+#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -+#define EM_SH 42 /* Hitachi SH */ -+#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -+#define EM_TRICORE 44 /* Siemens Tricore */ -+#define EM_ARC 45 /* Argonaut RISC Core */ -+#define EM_H8_300 46 /* Hitachi H8/300 */ -+#define EM_H8_300H 47 /* Hitachi H8/300H */ -+#define EM_H8S 48 /* Hitachi H8S */ -+#define EM_H8_500 49 /* Hitachi H8/500 */ -+#define EM_IA_64 50 /* Intel Merced */ -+#define EM_MIPS_X 51 /* Stanford MIPS-X */ -+#define EM_COLDFIRE 52 /* Motorola Coldfire */ -+#define EM_68HC12 53 /* Motorola M68HC12 */ -+#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ -+#define EM_PCP 55 /* Siemens PCP */ -+#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -+#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -+#define EM_STARCORE 58 /* Motorola Start*Core processor */ -+#define EM_ME16 59 /* Toyota ME16 processor */ -+#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -+#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ -+#define EM_X86_64 62 /* AMD x86-64 architecture */ -+#define EM_PDSP 63 /* Sony DSP Processor */ -+ -+#define EM_FX66 66 /* Siemens FX66 microcontroller */ -+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -+#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -+#define EM_SVX 73 /* Silicon Graphics SVx */ -+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -+#define EM_VAX 75 /* Digital VAX */ -+#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ -+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ -+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ -+#define EM_HUANY 81 /* Harvard University machine-independent object files */ -+#define EM_PRISM 82 /* SiTera Prism */ -+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -+#define EM_FR30 84 /* Fujitsu FR30 */ -+#define EM_D10V 85 /* Mitsubishi D10V */ -+#define EM_D30V 86 /* Mitsubishi D30V */ -+#define EM_V850 87 /* NEC v850 */ -+#define EM_M32R 88 /* Mitsubishi M32R */ -+#define EM_MN10300 89 /* Matsushita MN10300 */ -+#define EM_MN10200 90 /* Matsushita MN10200 */ -+#define EM_PJ 91 /* picoJava */ -+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ -+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -+#define EM_TILEPRO 188 /* Tilera TILEPro */ -+#define EM_TILEGX 191 /* Tilera TILE-Gx */ -+#define EM_NUM 192 -+ -+/* If it is necessary to assign new unofficial EM_* values, please -+ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the -+ chances of collision with official or non-GNU unofficial values. */ -+ -+#define EM_ALPHA 0x9026 -+ -+/* Legal values for e_version (version). */ -+ -+#define EV_NONE 0 /* Invalid ELF version */ -+#define EV_CURRENT 1 /* Current version */ -+#define EV_NUM 2 -+ -+/* Section header. */ -+ -+typedef struct -+{ -+ Elf32_Word sh_name; /* Section name (string tbl index) */ -+ Elf32_Word sh_type; /* Section type */ -+ Elf32_Word sh_flags; /* Section flags */ -+ Elf32_Addr sh_addr; /* Section virtual addr at execution */ -+ Elf32_Off sh_offset; /* Section file offset */ -+ Elf32_Word sh_size; /* Section size in bytes */ -+ Elf32_Word sh_link; /* Link to another section */ -+ Elf32_Word sh_info; /* Additional section information */ -+ Elf32_Word sh_addralign; /* Section alignment */ -+ Elf32_Word sh_entsize; /* Entry size if section holds table */ -+} Elf32_Shdr; -+ -+typedef struct -+{ -+ Elf64_Word sh_name; /* Section name (string tbl index) */ -+ Elf64_Word sh_type; /* Section type */ -+ Elf64_Xword sh_flags; /* Section flags */ -+ Elf64_Addr sh_addr; /* Section virtual addr at execution */ -+ Elf64_Off sh_offset; /* Section file offset */ -+ Elf64_Xword sh_size; /* Section size in bytes */ -+ Elf64_Word sh_link; /* Link to another section */ -+ Elf64_Word sh_info; /* Additional section information */ -+ Elf64_Xword sh_addralign; /* Section alignment */ -+ Elf64_Xword sh_entsize; /* Entry size if section holds table */ -+} Elf64_Shdr; -+ -+/* Special section indices. */ -+ -+#define SHN_UNDEF 0 /* Undefined section */ -+#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ -+#define SHN_LOPROC 0xff00 /* Start of processor-specific */ -+#define SHN_BEFORE 0xff00 /* Order section before all others -+ (Solaris). */ -+#define SHN_AFTER 0xff01 /* Order section after all others -+ (Solaris). */ -+#define SHN_HIPROC 0xff1f /* End of processor-specific */ -+#define SHN_LOOS 0xff20 /* Start of OS-specific */ -+#define SHN_HIOS 0xff3f /* End of OS-specific */ -+#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ -+#define SHN_COMMON 0xfff2 /* Associated symbol is common */ -+#define SHN_XINDEX 0xffff /* Index is in extra table. */ -+#define SHN_HIRESERVE 0xffff /* End of reserved indices */ -+ -+/* Legal values for sh_type (section type). */ -+ -+#define SHT_NULL 0 /* Section header table entry unused */ -+#define SHT_PROGBITS 1 /* Program data */ -+#define SHT_SYMTAB 2 /* Symbol table */ -+#define SHT_STRTAB 3 /* String table */ -+#define SHT_RELA 4 /* Relocation entries with addends */ -+#define SHT_HASH 5 /* Symbol hash table */ -+#define SHT_DYNAMIC 6 /* Dynamic linking information */ -+#define SHT_NOTE 7 /* Notes */ -+#define SHT_NOBITS 8 /* Program space with no data (bss) */ -+#define SHT_REL 9 /* Relocation entries, no addends */ -+#define SHT_SHLIB 10 /* Reserved */ -+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -+#define SHT_INIT_ARRAY 14 /* Array of constructors */ -+#define SHT_FINI_ARRAY 15 /* Array of destructors */ -+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -+#define SHT_GROUP 17 /* Section group */ -+#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -+#define SHT_NUM 19 /* Number of defined types. */ -+#define SHT_LOOS 0x60000000 /* Start OS-specific. */ -+#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ -+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -+#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ -+#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ -+#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ -+#define SHT_SUNW_move 0x6ffffffa -+#define SHT_SUNW_COMDAT 0x6ffffffb -+#define SHT_SUNW_syminfo 0x6ffffffc -+#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -+#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -+#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -+#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -+#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -+#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -+#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -+#define SHT_HIUSER 0x8fffffff /* End of application-specific */ -+ -+/* Legal values for sh_flags (section flags). */ -+ -+#define SHF_WRITE (1 << 0) /* Writable */ -+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -+#define SHF_EXECINSTR (1 << 2) /* Executable */ -+#define SHF_MERGE (1 << 4) /* Might be merged */ -+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ -+#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ -+#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ -+#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling -+ required */ -+#define SHF_GROUP (1 << 9) /* Section is member of a group. */ -+#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ -+#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ -+#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ -+#define SHF_ORDERED (1 << 30) /* Special ordering requirement -+ (Solaris). */ -+#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless -+ referenced or allocated (Solaris).*/ -+ -+/* Section group handling. */ -+#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ -+ -+/* Symbol table entry. */ -+ -+typedef struct -+{ -+ Elf32_Word st_name; /* Symbol name (string tbl index) */ -+ Elf32_Addr st_value; /* Symbol value */ -+ Elf32_Word st_size; /* Symbol size */ -+ unsigned char st_info; /* Symbol type and binding */ -+ unsigned char st_other; /* Symbol visibility */ -+ Elf32_Section st_shndx; /* Section index */ -+} Elf32_Sym; -+ -+typedef struct -+{ -+ Elf64_Word st_name; /* Symbol name (string tbl index) */ -+ unsigned char st_info; /* Symbol type and binding */ -+ unsigned char st_other; /* Symbol visibility */ -+ Elf64_Section st_shndx; /* Section index */ -+ Elf64_Addr st_value; /* Symbol value */ -+ Elf64_Xword st_size; /* Symbol size */ -+} Elf64_Sym; -+ -+/* The syminfo section if available contains additional information about -+ every dynamic symbol. */ -+ -+typedef struct -+{ -+ Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ -+ Elf32_Half si_flags; /* Per symbol flags */ -+} Elf32_Syminfo; -+ -+typedef struct -+{ -+ Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ -+ Elf64_Half si_flags; /* Per symbol flags */ -+} Elf64_Syminfo; -+ -+/* Possible values for si_boundto. */ -+#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ -+#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ -+#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ -+ -+/* Possible bitmasks for si_flags. */ -+#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -+#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ -+#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ -+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy -+ loaded */ -+/* Syminfo version values. */ -+#define SYMINFO_NONE 0 -+#define SYMINFO_CURRENT 1 -+#define SYMINFO_NUM 2 -+ -+ -+/* How to extract and insert information held in the st_info field. */ -+ -+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -+#define ELF32_ST_TYPE(val) ((val) & 0xf) -+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) -+ -+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ -+#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -+#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) -+ -+/* Legal values for ST_BIND subfield of st_info (symbol binding). */ -+ -+#define STB_LOCAL 0 /* Local symbol */ -+#define STB_GLOBAL 1 /* Global symbol */ -+#define STB_WEAK 2 /* Weak symbol */ -+#define STB_NUM 3 /* Number of defined types. */ -+#define STB_LOOS 10 /* Start of OS-specific */ -+#define STB_GNU_UNIQUE 10 /* Unique symbol. */ -+#define STB_HIOS 12 /* End of OS-specific */ -+#define STB_LOPROC 13 /* Start of processor-specific */ -+#define STB_HIPROC 15 /* End of processor-specific */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_NOTYPE 0 /* Symbol type is unspecified */ -+#define STT_OBJECT 1 /* Symbol is a data object */ -+#define STT_FUNC 2 /* Symbol is a code object */ -+#define STT_SECTION 3 /* Symbol associated with a section */ -+#define STT_FILE 4 /* Symbol's name is file name */ -+#define STT_COMMON 5 /* Symbol is a common data object */ -+#define STT_TLS 6 /* Symbol is thread-local data object*/ -+#define STT_NUM 7 /* Number of defined types. */ -+#define STT_LOOS 10 /* Start of OS-specific */ -+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ -+#define STT_HIOS 12 /* End of OS-specific */ -+#define STT_LOPROC 13 /* Start of processor-specific */ -+#define STT_HIPROC 15 /* End of processor-specific */ -+ -+ -+/* Symbol table indices are found in the hash buckets and chain table -+ of a symbol hash table section. This special index value indicates -+ the end of a chain, meaning no further symbols are found in that bucket. */ -+ -+#define STN_UNDEF 0 /* End of a chain. */ -+ -+ -+/* How to extract and insert information held in the st_other field. */ -+ -+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) -+ -+/* For ELF64 the definitions are the same. */ -+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) -+ -+/* Symbol visibility specification encoded in the st_other field. */ -+#define STV_DEFAULT 0 /* Default symbol visibility rules */ -+#define STV_INTERNAL 1 /* Processor specific hidden class */ -+#define STV_HIDDEN 2 /* Sym unavailable in other modules */ -+#define STV_PROTECTED 3 /* Not preemptible, not exported */ -+ -+ -+/* Relocation table entry without addend (in section of type SHT_REL). */ -+ -+typedef struct -+{ -+ Elf32_Addr r_offset; /* Address */ -+ Elf32_Word r_info; /* Relocation type and symbol index */ -+} Elf32_Rel; -+ -+/* I have seen two different definitions of the Elf64_Rel and -+ Elf64_Rela structures, so we'll leave them out until Novell (or -+ whoever) gets their act together. */ -+/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ -+ -+typedef struct -+{ -+ Elf64_Addr r_offset; /* Address */ -+ Elf64_Xword r_info; /* Relocation type and symbol index */ -+} Elf64_Rel; -+ -+/* Relocation table entry with addend (in section of type SHT_RELA). */ -+ -+typedef struct -+{ -+ Elf32_Addr r_offset; /* Address */ -+ Elf32_Word r_info; /* Relocation type and symbol index */ -+ Elf32_Sword r_addend; /* Addend */ -+} Elf32_Rela; -+ -+typedef struct -+{ -+ Elf64_Addr r_offset; /* Address */ -+ Elf64_Xword r_info; /* Relocation type and symbol index */ -+ Elf64_Sxword r_addend; /* Addend */ -+} Elf64_Rela; -+ -+/* How to extract and insert information held in the r_info field. */ -+ -+#define ELF32_R_SYM(val) ((val) >> 8) -+#define ELF32_R_TYPE(val) ((val) & 0xff) -+#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) -+ -+#define ELF64_R_SYM(i) ((i) >> 32) -+#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -+#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) -+ -+/* Program segment header. */ -+ -+typedef struct -+{ -+ Elf32_Word p_type; /* Segment type */ -+ Elf32_Off p_offset; /* Segment file offset */ -+ Elf32_Addr p_vaddr; /* Segment virtual address */ -+ Elf32_Addr p_paddr; /* Segment physical address */ -+ Elf32_Word p_filesz; /* Segment size in file */ -+ Elf32_Word p_memsz; /* Segment size in memory */ -+ Elf32_Word p_flags; /* Segment flags */ -+ Elf32_Word p_align; /* Segment alignment */ -+} Elf32_Phdr; -+ -+typedef struct -+{ -+ Elf64_Word p_type; /* Segment type */ -+ Elf64_Word p_flags; /* Segment flags */ -+ Elf64_Off p_offset; /* Segment file offset */ -+ Elf64_Addr p_vaddr; /* Segment virtual address */ -+ Elf64_Addr p_paddr; /* Segment physical address */ -+ Elf64_Xword p_filesz; /* Segment size in file */ -+ Elf64_Xword p_memsz; /* Segment size in memory */ -+ Elf64_Xword p_align; /* Segment alignment */ -+} Elf64_Phdr; -+ -+/* Special value for e_phnum. This indicates that the real number of -+ program headers is too large to fit into e_phnum. Instead the real -+ value is in the field sh_info of section 0. */ -+ -+#define PN_XNUM 0xffff -+ -+/* Legal values for p_type (segment type). */ -+ -+#define PT_NULL 0 /* Program header table entry unused */ -+#define PT_LOAD 1 /* Loadable program segment */ -+#define PT_DYNAMIC 2 /* Dynamic linking information */ -+#define PT_INTERP 3 /* Program interpreter */ -+#define PT_NOTE 4 /* Auxiliary information */ -+#define PT_SHLIB 5 /* Reserved */ -+#define PT_PHDR 6 /* Entry for header table itself */ -+#define PT_TLS 7 /* Thread-local storage segment */ -+#define PT_NUM 8 /* Number of defined types */ -+#define PT_LOOS 0x60000000 /* Start of OS-specific */ -+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ -+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ -+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ -+#define PT_LOSUNW 0x6ffffffa -+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -+#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ -+#define PT_HISUNW 0x6fffffff -+#define PT_HIOS 0x6fffffff /* End of OS-specific */ -+#define PT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define PT_HIPROC 0x7fffffff /* End of processor-specific */ -+ -+/* Legal values for p_flags (segment flags). */ -+ -+#define PF_X (1 << 0) /* Segment is executable */ -+#define PF_W (1 << 1) /* Segment is writable */ -+#define PF_R (1 << 2) /* Segment is readable */ -+#define PF_MASKOS 0x0ff00000 /* OS-specific */ -+#define PF_MASKPROC 0xf0000000 /* Processor-specific */ -+ -+/* Legal values for note segment descriptor types for core files. */ -+ -+#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ -+#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ -+#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ -+#define NT_PRXREG 4 /* Contains copy of prxregset struct */ -+#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ -+#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ -+#define NT_AUXV 6 /* Contains copy of auxv array */ -+#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ -+#define NT_ASRS 8 /* Contains copy of asrset struct */ -+#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ -+#define NT_PSINFO 13 /* Contains copy of psinfo struct */ -+#define NT_PRCRED 14 /* Contains copy of prcred struct */ -+#define NT_UTSNAME 15 /* Contains copy of utsname struct */ -+#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ -+#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ -+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ -+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ -+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ -+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ -+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ -+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ -+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ -+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ -+ -+/* Legal values for the note segment descriptor types for object files. */ -+ -+#define NT_VERSION 1 /* Contains a version string. */ -+ -+ -+/* Dynamic section entry. */ -+ -+typedef struct -+{ -+ Elf32_Sword d_tag; /* Dynamic entry type */ -+ union -+ { -+ Elf32_Word d_val; /* Integer value */ -+ Elf32_Addr d_ptr; /* Address value */ -+ } d_un; -+} Elf32_Dyn; -+ -+typedef struct -+{ -+ Elf64_Sxword d_tag; /* Dynamic entry type */ -+ union -+ { -+ Elf64_Xword d_val; /* Integer value */ -+ Elf64_Addr d_ptr; /* Address value */ -+ } d_un; -+} Elf64_Dyn; -+ -+/* Legal values for d_tag (dynamic entry type). */ -+ -+#define DT_NULL 0 /* Marks end of dynamic section */ -+#define DT_NEEDED 1 /* Name of needed library */ -+#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ -+#define DT_PLTGOT 3 /* Processor defined value */ -+#define DT_HASH 4 /* Address of symbol hash table */ -+#define DT_STRTAB 5 /* Address of string table */ -+#define DT_SYMTAB 6 /* Address of symbol table */ -+#define DT_RELA 7 /* Address of Rela relocs */ -+#define DT_RELASZ 8 /* Total size of Rela relocs */ -+#define DT_RELAENT 9 /* Size of one Rela reloc */ -+#define DT_STRSZ 10 /* Size of string table */ -+#define DT_SYMENT 11 /* Size of one symbol table entry */ -+#define DT_INIT 12 /* Address of init function */ -+#define DT_FINI 13 /* Address of termination function */ -+#define DT_SONAME 14 /* Name of shared object */ -+#define DT_RPATH 15 /* Library search path (deprecated) */ -+#define DT_SYMBOLIC 16 /* Start symbol search here */ -+#define DT_REL 17 /* Address of Rel relocs */ -+#define DT_RELSZ 18 /* Total size of Rel relocs */ -+#define DT_RELENT 19 /* Size of one Rel reloc */ -+#define DT_PLTREL 20 /* Type of reloc in PLT */ -+#define DT_DEBUG 21 /* For debugging; unspecified */ -+#define DT_TEXTREL 22 /* Reloc might modify .text */ -+#define DT_JMPREL 23 /* Address of PLT relocs */ -+#define DT_BIND_NOW 24 /* Process relocations of object */ -+#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ -+#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ -+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ -+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ -+#define DT_RUNPATH 29 /* Library search path */ -+#define DT_FLAGS 30 /* Flags for the object being loaded */ -+#define DT_ENCODING 32 /* Start of encoded range */ -+#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ -+#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ -+#define DT_NUM 34 /* Number used */ -+#define DT_LOOS 0x6000000d /* Start of OS-specific */ -+#define DT_HIOS 0x6ffff000 /* End of OS-specific */ -+#define DT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define DT_HIPROC 0x7fffffff /* End of processor-specific */ -+#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ -+ -+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the -+ Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's -+ approach. */ -+#define DT_VALRNGLO 0x6ffffd00 -+#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ -+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ -+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ -+#define DT_CHECKSUM 0x6ffffdf8 -+#define DT_PLTPADSZ 0x6ffffdf9 -+#define DT_MOVEENT 0x6ffffdfa -+#define DT_MOVESZ 0x6ffffdfb -+#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ -+#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting -+ the following DT_* entry. */ -+#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ -+#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ -+#define DT_VALRNGHI 0x6ffffdff -+#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ -+#define DT_VALNUM 12 -+ -+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the -+ Dyn.d_un.d_ptr field of the Elf*_Dyn structure. -+ -+ If any adjustment is made to the ELF object after it has been -+ built these entries will need to be adjusted. */ -+#define DT_ADDRRNGLO 0x6ffffe00 -+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ -+#define DT_TLSDESC_PLT 0x6ffffef6 -+#define DT_TLSDESC_GOT 0x6ffffef7 -+#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ -+#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ -+#define DT_CONFIG 0x6ffffefa /* Configuration information. */ -+#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ -+#define DT_AUDIT 0x6ffffefc /* Object auditing. */ -+#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ -+#define DT_MOVETAB 0x6ffffefe /* Move table. */ -+#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ -+#define DT_ADDRRNGHI 0x6ffffeff -+#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ -+#define DT_ADDRNUM 11 -+ -+/* The versioning entry types. The next are defined as part of the -+ GNU extension. */ -+#define DT_VERSYM 0x6ffffff0 -+ -+#define DT_RELACOUNT 0x6ffffff9 -+#define DT_RELCOUNT 0x6ffffffa -+ -+/* These were chosen by Sun. */ -+#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ -+#define DT_VERDEF 0x6ffffffc /* Address of version definition -+ table */ -+#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ -+#define DT_VERNEED 0x6ffffffe /* Address of table with needed -+ versions */ -+#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ -+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -+#define DT_VERSIONTAGNUM 16 -+ -+/* Sun added these machine-independent extensions in the "processor-specific" -+ range. Be compatible. */ -+#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ -+#define DT_FILTER 0x7fffffff /* Shared object to get values from */ -+#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) -+#define DT_EXTRANUM 3 -+ -+/* Values of `d_un.d_val' in the DT_FLAGS entry. */ -+#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ -+#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ -+#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ -+#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ -+#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ -+ -+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 -+ entry in the dynamic section. */ -+#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ -+#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ -+#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ -+#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ -+#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ -+#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ -+#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ -+#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ -+#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ -+#define DF_1_TRANS 0x00000200 -+#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ -+#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ -+#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ -+#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ -+#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ -+#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ -+#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ -+ -+/* Flags for the feature selection in DT_FEATURE_1. */ -+#define DTF_1_PARINIT 0x00000001 -+#define DTF_1_CONFEXP 0x00000002 -+ -+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ -+#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ -+#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not -+ generally available. */ -+ -+/* Version definition sections. */ -+ -+typedef struct -+{ -+ Elf32_Half vd_version; /* Version revision */ -+ Elf32_Half vd_flags; /* Version information */ -+ Elf32_Half vd_ndx; /* Version Index */ -+ Elf32_Half vd_cnt; /* Number of associated aux entries */ -+ Elf32_Word vd_hash; /* Version name hash value */ -+ Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ -+ Elf32_Word vd_next; /* Offset in bytes to next verdef -+ entry */ -+} Elf32_Verdef; -+ -+typedef struct -+{ -+ Elf64_Half vd_version; /* Version revision */ -+ Elf64_Half vd_flags; /* Version information */ -+ Elf64_Half vd_ndx; /* Version Index */ -+ Elf64_Half vd_cnt; /* Number of associated aux entries */ -+ Elf64_Word vd_hash; /* Version name hash value */ -+ Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ -+ Elf64_Word vd_next; /* Offset in bytes to next verdef -+ entry */ -+} Elf64_Verdef; -+ -+ -+/* Legal values for vd_version (version revision). */ -+#define VER_DEF_NONE 0 /* No version */ -+#define VER_DEF_CURRENT 1 /* Current version */ -+#define VER_DEF_NUM 2 /* Given version number */ -+ -+/* Legal values for vd_flags (version information flags). */ -+#define VER_FLG_BASE 0x1 /* Version definition of file itself */ -+#define VER_FLG_WEAK 0x2 /* Weak version identifier */ -+ -+/* Versym symbol index values. */ -+#define VER_NDX_LOCAL 0 /* Symbol is local. */ -+#define VER_NDX_GLOBAL 1 /* Symbol is global. */ -+#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ -+#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ -+ -+/* Auxialiary version information. */ -+ -+typedef struct -+{ -+ Elf32_Word vda_name; /* Version or dependency names */ -+ Elf32_Word vda_next; /* Offset in bytes to next verdaux -+ entry */ -+} Elf32_Verdaux; -+ -+typedef struct -+{ -+ Elf64_Word vda_name; /* Version or dependency names */ -+ Elf64_Word vda_next; /* Offset in bytes to next verdaux -+ entry */ -+} Elf64_Verdaux; -+ -+ -+/* Version dependency section. */ -+ -+typedef struct -+{ -+ Elf32_Half vn_version; /* Version of structure */ -+ Elf32_Half vn_cnt; /* Number of associated aux entries */ -+ Elf32_Word vn_file; /* Offset of filename for this -+ dependency */ -+ Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ -+ Elf32_Word vn_next; /* Offset in bytes to next verneed -+ entry */ -+} Elf32_Verneed; -+ -+typedef struct -+{ -+ Elf64_Half vn_version; /* Version of structure */ -+ Elf64_Half vn_cnt; /* Number of associated aux entries */ -+ Elf64_Word vn_file; /* Offset of filename for this -+ dependency */ -+ Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ -+ Elf64_Word vn_next; /* Offset in bytes to next verneed -+ entry */ -+} Elf64_Verneed; -+ -+ -+/* Legal values for vn_version (version revision). */ -+#define VER_NEED_NONE 0 /* No version */ -+#define VER_NEED_CURRENT 1 /* Current version */ -+#define VER_NEED_NUM 2 /* Given version number */ -+ -+/* Auxiliary needed version information. */ -+ -+typedef struct -+{ -+ Elf32_Word vna_hash; /* Hash value of dependency name */ -+ Elf32_Half vna_flags; /* Dependency specific information */ -+ Elf32_Half vna_other; /* Unused */ -+ Elf32_Word vna_name; /* Dependency name string offset */ -+ Elf32_Word vna_next; /* Offset in bytes to next vernaux -+ entry */ -+} Elf32_Vernaux; -+ -+typedef struct -+{ -+ Elf64_Word vna_hash; /* Hash value of dependency name */ -+ Elf64_Half vna_flags; /* Dependency specific information */ -+ Elf64_Half vna_other; /* Unused */ -+ Elf64_Word vna_name; /* Dependency name string offset */ -+ Elf64_Word vna_next; /* Offset in bytes to next vernaux -+ entry */ -+} Elf64_Vernaux; -+ -+ -+/* Legal values for vna_flags. */ -+#define VER_FLG_WEAK 0x2 /* Weak version identifier */ -+ -+ -+/* Auxiliary vector. */ -+ -+/* This vector is normally only used by the program interpreter. The -+ usual definition in an ABI supplement uses the name auxv_t. The -+ vector is not usually defined in a standard file, but it -+ can't hurt. We rename it to avoid conflicts. The sizes of these -+ types are an arrangement between the exec server and the program -+ interpreter, so we don't fully specify them here. */ -+ -+typedef struct -+{ -+ uint32_t a_type; /* Entry type */ -+ union -+ { -+ uint32_t a_val; /* Integer value */ -+ /* We use to have pointer elements added here. We cannot do that, -+ though, since it does not work when using 32-bit definitions -+ on 64-bit platforms and vice versa. */ -+ } a_un; -+} Elf32_auxv_t; -+ -+typedef struct -+{ -+ uint64_t a_type; /* Entry type */ -+ union -+ { -+ uint64_t a_val; /* Integer value */ -+ /* We use to have pointer elements added here. We cannot do that, -+ though, since it does not work when using 32-bit definitions -+ on 64-bit platforms and vice versa. */ -+ } a_un; -+} Elf64_auxv_t; -+ -+/* Legal values for a_type (entry type). */ -+ -+#define AT_NULL 0 /* End of vector */ -+#define AT_IGNORE 1 /* Entry should be ignored */ -+#define AT_EXECFD 2 /* File descriptor of program */ -+#define AT_PHDR 3 /* Program headers for program */ -+#define AT_PHENT 4 /* Size of program header entry */ -+#define AT_PHNUM 5 /* Number of program headers */ -+#define AT_PAGESZ 6 /* System page size */ -+#define AT_BASE 7 /* Base address of interpreter */ -+#define AT_FLAGS 8 /* Flags */ -+#define AT_ENTRY 9 /* Entry point of program */ -+#define AT_NOTELF 10 /* Program is not ELF */ -+#define AT_UID 11 /* Real uid */ -+#define AT_EUID 12 /* Effective uid */ -+#define AT_GID 13 /* Real gid */ -+#define AT_EGID 14 /* Effective gid */ -+#define AT_CLKTCK 17 /* Frequency of times() */ -+ -+/* Some more special a_type values describing the hardware. */ -+#define AT_PLATFORM 15 /* String identifying platform. */ -+#define AT_HWCAP 16 /* Machine dependent hints about -+ processor capabilities. */ -+ -+/* This entry gives some information about the FPU initialization -+ performed by the kernel. */ -+#define AT_FPUCW 18 /* Used FPU control word. */ -+ -+/* Cache block sizes. */ -+#define AT_DCACHEBSIZE 19 /* Data cache block size. */ -+#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ -+#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ -+ -+/* A special ignored value for PPC, used by the kernel to control the -+ interpretation of the AUXV. Must be > 16. */ -+#define AT_IGNOREPPC 22 /* Entry should be ignored. */ -+ -+#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ -+ -+#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ -+ -+#define AT_RANDOM 25 /* Address of 16 random bytes. */ -+ -+#define AT_EXECFN 31 /* Filename of executable. */ -+ -+/* Pointer to the global system page used for system calls and other -+ nice things. */ -+#define AT_SYSINFO 32 -+#define AT_SYSINFO_EHDR 33 -+ -+/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains -+ log2 of line size; mask those to get cache size. */ -+#define AT_L1I_CACHESHAPE 34 -+#define AT_L1D_CACHESHAPE 35 -+#define AT_L2_CACHESHAPE 36 -+#define AT_L3_CACHESHAPE 37 -+ -+/* Note section contents. Each entry in the note section begins with -+ a header of a fixed form. */ -+ -+typedef struct -+{ -+ Elf32_Word n_namesz; /* Length of the note's name. */ -+ Elf32_Word n_descsz; /* Length of the note's descriptor. */ -+ Elf32_Word n_type; /* Type of the note. */ -+} Elf32_Nhdr; -+ -+typedef struct -+{ -+ Elf64_Word n_namesz; /* Length of the note's name. */ -+ Elf64_Word n_descsz; /* Length of the note's descriptor. */ -+ Elf64_Word n_type; /* Type of the note. */ -+} Elf64_Nhdr; -+ -+/* Known names of notes. */ -+ -+/* Solaris entries in the note section have this name. */ -+#define ELF_NOTE_SOLARIS "SUNW Solaris" -+ -+/* Note entries for GNU systems have this name. */ -+#define ELF_NOTE_GNU "GNU" -+ -+ -+/* Defined types of notes for Solaris. */ -+ -+/* Value of descriptor (one word) is desired pagesize for the binary. */ -+#define ELF_NOTE_PAGESIZE_HINT 1 -+ -+ -+/* Defined note types for GNU systems. */ -+ -+/* ABI information. The descriptor consists of words: -+ word 0: OS descriptor -+ word 1: major version of the ABI -+ word 2: minor version of the ABI -+ word 3: subminor version of the ABI -+*/ -+#define NT_GNU_ABI_TAG 1 -+#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ -+ -+/* Known OSes. These values can appear in word 0 of an -+ NT_GNU_ABI_TAG note section entry. */ -+#define ELF_NOTE_OS_LINUX 0 -+#define ELF_NOTE_OS_GNU 1 -+#define ELF_NOTE_OS_SOLARIS2 2 -+#define ELF_NOTE_OS_FREEBSD 3 -+ -+/* Synthetic hwcap information. The descriptor begins with two words: -+ word 0: number of entries -+ word 1: bitmask of enabled entries -+ Then follow variable-length entries, one byte followed by a -+ '\0'-terminated hwcap name string. The byte gives the bit -+ number to test if enabled, (1U << bit) & bitmask. */ -+#define NT_GNU_HWCAP 2 -+ -+/* Build ID bits as generated by ld --build-id. -+ The descriptor consists of any nonzero number of bytes. */ -+#define NT_GNU_BUILD_ID 3 -+ -+/* Version note generated by GNU gold containing a version string. */ -+#define NT_GNU_GOLD_VERSION 4 -+ -+ -+/* Move records. */ -+typedef struct -+{ -+ Elf32_Xword m_value; /* Symbol value. */ -+ Elf32_Word m_info; /* Size and index. */ -+ Elf32_Word m_poffset; /* Symbol offset. */ -+ Elf32_Half m_repeat; /* Repeat count. */ -+ Elf32_Half m_stride; /* Stride info. */ -+} Elf32_Move; -+ -+typedef struct -+{ -+ Elf64_Xword m_value; /* Symbol value. */ -+ Elf64_Xword m_info; /* Size and index. */ -+ Elf64_Xword m_poffset; /* Symbol offset. */ -+ Elf64_Half m_repeat; /* Repeat count. */ -+ Elf64_Half m_stride; /* Stride info. */ -+} Elf64_Move; -+ -+/* Macro to construct move records. */ -+#define ELF32_M_SYM(info) ((info) >> 8) -+#define ELF32_M_SIZE(info) ((unsigned char) (info)) -+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) -+ -+#define ELF64_M_SYM(info) ELF32_M_SYM (info) -+#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) -+#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) -+ -+ -+/* Motorola 68k specific definitions. */ -+ -+/* Values for Elf32_Ehdr.e_flags. */ -+#define EF_CPU32 0x00810000 -+ -+/* m68k relocs. */ -+ -+#define R_68K_NONE 0 /* No reloc */ -+#define R_68K_32 1 /* Direct 32 bit */ -+#define R_68K_16 2 /* Direct 16 bit */ -+#define R_68K_8 3 /* Direct 8 bit */ -+#define R_68K_PC32 4 /* PC relative 32 bit */ -+#define R_68K_PC16 5 /* PC relative 16 bit */ -+#define R_68K_PC8 6 /* PC relative 8 bit */ -+#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ -+#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ -+#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ -+#define R_68K_GOT32O 10 /* 32 bit GOT offset */ -+#define R_68K_GOT16O 11 /* 16 bit GOT offset */ -+#define R_68K_GOT8O 12 /* 8 bit GOT offset */ -+#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ -+#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ -+#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ -+#define R_68K_PLT32O 16 /* 32 bit PLT offset */ -+#define R_68K_PLT16O 17 /* 16 bit PLT offset */ -+#define R_68K_PLT8O 18 /* 8 bit PLT offset */ -+#define R_68K_COPY 19 /* Copy symbol at runtime */ -+#define R_68K_GLOB_DAT 20 /* Create GOT entry */ -+#define R_68K_JMP_SLOT 21 /* Create PLT entry */ -+#define R_68K_RELATIVE 22 /* Adjust by program base */ -+#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ -+#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ -+#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ -+#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ -+#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ -+#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ -+#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ -+#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ -+#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ -+#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ -+#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ -+#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ -+#define R_68K_TLS_LE32 37 /* 32 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_LE16 38 /* 16 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_LE8 39 /* 8 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ -+#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ -+#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ -+/* Keep this the last entry. */ -+#define R_68K_NUM 43 -+ -+/* Intel 80386 specific definitions. */ -+ -+/* i386 relocs. */ -+ -+#define R_386_NONE 0 /* No reloc */ -+#define R_386_32 1 /* Direct 32 bit */ -+#define R_386_PC32 2 /* PC relative 32 bit */ -+#define R_386_GOT32 3 /* 32 bit GOT entry */ -+#define R_386_PLT32 4 /* 32 bit PLT address */ -+#define R_386_COPY 5 /* Copy symbol at runtime */ -+#define R_386_GLOB_DAT 6 /* Create GOT entry */ -+#define R_386_JMP_SLOT 7 /* Create PLT entry */ -+#define R_386_RELATIVE 8 /* Adjust by program base */ -+#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ -+#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ -+#define R_386_32PLT 11 -+#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ -+#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS -+ block offset */ -+#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block -+ offset */ -+#define R_386_TLS_LE 17 /* Offset relative to static TLS -+ block */ -+#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of -+ general dynamic thread local data */ -+#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of -+ local dynamic thread local data -+ in LE code */ -+#define R_386_16 20 -+#define R_386_PC16 21 -+#define R_386_8 22 -+#define R_386_PC8 23 -+#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic -+ thread local data */ -+#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ -+#define R_386_TLS_GD_CALL 26 /* Relocation for call to -+ __tls_get_addr() */ -+#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ -+#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic -+ thread local data in LE code */ -+#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ -+#define R_386_TLS_LDM_CALL 30 /* Relocation for call to -+ __tls_get_addr() in LDM code */ -+#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ -+#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ -+#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS -+ block offset */ -+#define R_386_TLS_LE_32 34 /* Negated offset relative to static -+ TLS block */ -+#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ -+#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ -+#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ -+/* 38? */ -+#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ -+#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS -+ descriptor for -+ relaxation. */ -+#define R_386_TLS_DESC 41 /* TLS descriptor containing -+ pointer to code and to -+ argument, returning the TLS -+ offset for the symbol. */ -+#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ -+/* Keep this the last entry. */ -+#define R_386_NUM 43 -+ -+/* SUN SPARC specific definitions. */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ -+ -+/* Values for Elf64_Ehdr.e_flags. */ -+ -+#define EF_SPARCV9_MM 3 -+#define EF_SPARCV9_TSO 0 -+#define EF_SPARCV9_PSO 1 -+#define EF_SPARCV9_RMO 2 -+#define EF_SPARC_LEDATA 0x800000 /* little endian data */ -+#define EF_SPARC_EXT_MASK 0xFFFF00 -+#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ -+#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ -+#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ -+#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ -+ -+/* SPARC relocs. */ -+ -+#define R_SPARC_NONE 0 /* No reloc */ -+#define R_SPARC_8 1 /* Direct 8 bit */ -+#define R_SPARC_16 2 /* Direct 16 bit */ -+#define R_SPARC_32 3 /* Direct 32 bit */ -+#define R_SPARC_DISP8 4 /* PC relative 8 bit */ -+#define R_SPARC_DISP16 5 /* PC relative 16 bit */ -+#define R_SPARC_DISP32 6 /* PC relative 32 bit */ -+#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ -+#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ -+#define R_SPARC_HI22 9 /* High 22 bit */ -+#define R_SPARC_22 10 /* Direct 22 bit */ -+#define R_SPARC_13 11 /* Direct 13 bit */ -+#define R_SPARC_LO10 12 /* Truncated 10 bit */ -+#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ -+#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ -+#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ -+#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ -+#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ -+#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ -+#define R_SPARC_COPY 19 /* Copy symbol at runtime */ -+#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ -+#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ -+#define R_SPARC_RELATIVE 22 /* Adjust by program base */ -+#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ -+ -+/* Additional Sparc64 relocs. */ -+ -+#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ -+#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ -+#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ -+#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ -+#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ -+#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ -+#define R_SPARC_10 30 /* Direct 10 bit */ -+#define R_SPARC_11 31 /* Direct 11 bit */ -+#define R_SPARC_64 32 /* Direct 64 bit */ -+#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ -+#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ -+#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ -+#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ -+#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ -+#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ -+#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ -+#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ -+#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ -+#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ -+#define R_SPARC_7 43 /* Direct 7 bit */ -+#define R_SPARC_5 44 /* Direct 5 bit */ -+#define R_SPARC_6 45 /* Direct 6 bit */ -+#define R_SPARC_DISP64 46 /* PC relative 64 bit */ -+#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ -+#define R_SPARC_HIX22 48 /* High 22 bit complemented */ -+#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ -+#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ -+#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ -+#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ -+#define R_SPARC_REGISTER 53 /* Global register usage */ -+#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ -+#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ -+#define R_SPARC_TLS_GD_HI22 56 -+#define R_SPARC_TLS_GD_LO10 57 -+#define R_SPARC_TLS_GD_ADD 58 -+#define R_SPARC_TLS_GD_CALL 59 -+#define R_SPARC_TLS_LDM_HI22 60 -+#define R_SPARC_TLS_LDM_LO10 61 -+#define R_SPARC_TLS_LDM_ADD 62 -+#define R_SPARC_TLS_LDM_CALL 63 -+#define R_SPARC_TLS_LDO_HIX22 64 -+#define R_SPARC_TLS_LDO_LOX10 65 -+#define R_SPARC_TLS_LDO_ADD 66 -+#define R_SPARC_TLS_IE_HI22 67 -+#define R_SPARC_TLS_IE_LO10 68 -+#define R_SPARC_TLS_IE_LD 69 -+#define R_SPARC_TLS_IE_LDX 70 -+#define R_SPARC_TLS_IE_ADD 71 -+#define R_SPARC_TLS_LE_HIX22 72 -+#define R_SPARC_TLS_LE_LOX10 73 -+#define R_SPARC_TLS_DTPMOD32 74 -+#define R_SPARC_TLS_DTPMOD64 75 -+#define R_SPARC_TLS_DTPOFF32 76 -+#define R_SPARC_TLS_DTPOFF64 77 -+#define R_SPARC_TLS_TPOFF32 78 -+#define R_SPARC_TLS_TPOFF64 79 -+#define R_SPARC_GOTDATA_HIX22 80 -+#define R_SPARC_GOTDATA_LOX10 81 -+#define R_SPARC_GOTDATA_OP_HIX22 82 -+#define R_SPARC_GOTDATA_OP_LOX10 83 -+#define R_SPARC_GOTDATA_OP 84 -+#define R_SPARC_H34 85 -+#define R_SPARC_SIZE32 86 -+#define R_SPARC_SIZE64 87 -+#define R_SPARC_WDISP10 88 -+#define R_SPARC_JMP_IREL 248 -+#define R_SPARC_IRELATIVE 249 -+#define R_SPARC_GNU_VTINHERIT 250 -+#define R_SPARC_GNU_VTENTRY 251 -+#define R_SPARC_REV32 252 -+/* Keep this the last entry. */ -+#define R_SPARC_NUM 253 -+ -+/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ -+ -+#define DT_SPARC_REGISTER 0x70000001 -+#define DT_SPARC_NUM 2 -+ -+/* MIPS R3000 specific definitions. */ -+ -+/* Legal values for e_flags field of Elf32_Ehdr. */ -+ -+#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ -+#define EF_MIPS_PIC 2 /* Contains PIC code */ -+#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ -+#define EF_MIPS_XGOT 8 -+#define EF_MIPS_64BIT_WHIRL 16 -+#define EF_MIPS_ABI2 32 -+#define EF_MIPS_ABI_ON32 64 -+#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ -+ -+/* Legal values for MIPS architecture level. */ -+ -+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -+#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -+#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ -+ -+/* The following are non-official names and should not be used. */ -+ -+#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -+#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -+#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -+#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -+#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -+#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -+#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ -+ -+/* Special section indices. */ -+ -+#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ -+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ -+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ -+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ -+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ -+ -+/* Legal values for sh_type field of Elf32_Shdr. */ -+ -+#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ -+#define SHT_MIPS_MSYM 0x70000001 -+#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ -+#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ -+#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ -+#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ -+#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ -+#define SHT_MIPS_PACKAGE 0x70000007 -+#define SHT_MIPS_PACKSYM 0x70000008 -+#define SHT_MIPS_RELD 0x70000009 -+#define SHT_MIPS_IFACE 0x7000000b -+#define SHT_MIPS_CONTENT 0x7000000c -+#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ -+#define SHT_MIPS_SHDR 0x70000010 -+#define SHT_MIPS_FDESC 0x70000011 -+#define SHT_MIPS_EXTSYM 0x70000012 -+#define SHT_MIPS_DENSE 0x70000013 -+#define SHT_MIPS_PDESC 0x70000014 -+#define SHT_MIPS_LOCSYM 0x70000015 -+#define SHT_MIPS_AUXSYM 0x70000016 -+#define SHT_MIPS_OPTSYM 0x70000017 -+#define SHT_MIPS_LOCSTR 0x70000018 -+#define SHT_MIPS_LINE 0x70000019 -+#define SHT_MIPS_RFDESC 0x7000001a -+#define SHT_MIPS_DELTASYM 0x7000001b -+#define SHT_MIPS_DELTAINST 0x7000001c -+#define SHT_MIPS_DELTACLASS 0x7000001d -+#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ -+#define SHT_MIPS_DELTADECL 0x7000001f -+#define SHT_MIPS_SYMBOL_LIB 0x70000020 -+#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ -+#define SHT_MIPS_TRANSLATE 0x70000022 -+#define SHT_MIPS_PIXIE 0x70000023 -+#define SHT_MIPS_XLATE 0x70000024 -+#define SHT_MIPS_XLATE_DEBUG 0x70000025 -+#define SHT_MIPS_WHIRL 0x70000026 -+#define SHT_MIPS_EH_REGION 0x70000027 -+#define SHT_MIPS_XLATE_OLD 0x70000028 -+#define SHT_MIPS_PDR_EXCEPTION 0x70000029 -+ -+/* Legal values for sh_flags field of Elf32_Shdr. */ -+ -+#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ -+#define SHF_MIPS_MERGE 0x20000000 -+#define SHF_MIPS_ADDR 0x40000000 -+#define SHF_MIPS_STRINGS 0x80000000 -+#define SHF_MIPS_NOSTRIP 0x08000000 -+#define SHF_MIPS_LOCAL 0x04000000 -+#define SHF_MIPS_NAMES 0x02000000 -+#define SHF_MIPS_NODUPE 0x01000000 -+ -+ -+/* Symbol tables. */ -+ -+/* MIPS specific values for `st_other'. */ -+#define STO_MIPS_DEFAULT 0x0 -+#define STO_MIPS_INTERNAL 0x1 -+#define STO_MIPS_HIDDEN 0x2 -+#define STO_MIPS_PROTECTED 0x3 -+#define STO_MIPS_PLT 0x8 -+#define STO_MIPS_SC_ALIGN_UNUSED 0xff -+ -+/* MIPS specific values for `st_info'. */ -+#define STB_MIPS_SPLIT_COMMON 13 -+ -+/* Entries found in sections of type SHT_MIPS_GPTAB. */ -+ -+typedef union -+{ -+ struct -+ { -+ Elf32_Word gt_current_g_value; /* -G value used for compilation */ -+ Elf32_Word gt_unused; /* Not used */ -+ } gt_header; /* First entry in section */ -+ struct -+ { -+ Elf32_Word gt_g_value; /* If this value were used for -G */ -+ Elf32_Word gt_bytes; /* This many bytes would be used */ -+ } gt_entry; /* Subsequent entries in section */ -+} Elf32_gptab; -+ -+/* Entry found in sections of type SHT_MIPS_REGINFO. */ -+ -+typedef struct -+{ -+ Elf32_Word ri_gprmask; /* General registers used */ -+ Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ -+ Elf32_Sword ri_gp_value; /* $gp register value */ -+} Elf32_RegInfo; -+ -+/* Entries found in sections of type SHT_MIPS_OPTIONS. */ -+ -+typedef struct -+{ -+ unsigned char kind; /* Determines interpretation of the -+ variable part of descriptor. */ -+ unsigned char size; /* Size of descriptor, including header. */ -+ Elf32_Section section; /* Section header index of section affected, -+ 0 for global options. */ -+ Elf32_Word info; /* Kind-specific information. */ -+} Elf_Options; -+ -+/* Values for `kind' field in Elf_Options. */ -+ -+#define ODK_NULL 0 /* Undefined. */ -+#define ODK_REGINFO 1 /* Register usage information. */ -+#define ODK_EXCEPTIONS 2 /* Exception processing options. */ -+#define ODK_PAD 3 /* Section padding options. */ -+#define ODK_HWPATCH 4 /* Hardware workarounds performed */ -+#define ODK_FILL 5 /* record the fill value used by the linker. */ -+#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ -+#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ -+#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ -+ -+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ -+ -+#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ -+#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ -+#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ -+#define OEX_SMM 0x20000 /* Force sequential memory mode? */ -+#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ -+#define OEX_PRECISEFP OEX_FPDBUG -+#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ -+ -+#define OEX_FPU_INVAL 0x10 -+#define OEX_FPU_DIV0 0x08 -+#define OEX_FPU_OFLO 0x04 -+#define OEX_FPU_UFLO 0x02 -+#define OEX_FPU_INEX 0x01 -+ -+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ -+ -+#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ -+#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ -+#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ -+#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ -+ -+#define OPAD_PREFIX 0x1 -+#define OPAD_POSTFIX 0x2 -+#define OPAD_SYMBOL 0x4 -+ -+/* Entry found in `.options' section. */ -+ -+typedef struct -+{ -+ Elf32_Word hwp_flags1; /* Extra flags. */ -+ Elf32_Word hwp_flags2; /* Extra flags. */ -+} Elf_Options_Hw; -+ -+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ -+ -+#define OHWA0_R4KEOP_CHECKED 0x00000001 -+#define OHWA1_R4KEOP_CLEAN 0x00000002 -+ -+/* MIPS relocs. */ -+ -+#define R_MIPS_NONE 0 /* No reloc */ -+#define R_MIPS_16 1 /* Direct 16 bit */ -+#define R_MIPS_32 2 /* Direct 32 bit */ -+#define R_MIPS_REL32 3 /* PC relative 32 bit */ -+#define R_MIPS_26 4 /* Direct 26 bit shifted */ -+#define R_MIPS_HI16 5 /* High 16 bit */ -+#define R_MIPS_LO16 6 /* Low 16 bit */ -+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ -+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ -+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ -+#define R_MIPS_PC16 10 /* PC relative 16 bit */ -+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ -+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ -+ -+#define R_MIPS_SHIFT5 16 -+#define R_MIPS_SHIFT6 17 -+#define R_MIPS_64 18 -+#define R_MIPS_GOT_DISP 19 -+#define R_MIPS_GOT_PAGE 20 -+#define R_MIPS_GOT_OFST 21 -+#define R_MIPS_GOT_HI16 22 -+#define R_MIPS_GOT_LO16 23 -+#define R_MIPS_SUB 24 -+#define R_MIPS_INSERT_A 25 -+#define R_MIPS_INSERT_B 26 -+#define R_MIPS_DELETE 27 -+#define R_MIPS_HIGHER 28 -+#define R_MIPS_HIGHEST 29 -+#define R_MIPS_CALL_HI16 30 -+#define R_MIPS_CALL_LO16 31 -+#define R_MIPS_SCN_DISP 32 -+#define R_MIPS_REL16 33 -+#define R_MIPS_ADD_IMMEDIATE 34 -+#define R_MIPS_PJUMP 35 -+#define R_MIPS_RELGOT 36 -+#define R_MIPS_JALR 37 -+#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ -+#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ -+#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ -+#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ -+#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ -+#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ -+#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ -+#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ -+#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ -+#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ -+#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ -+#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ -+#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ -+#define R_MIPS_GLOB_DAT 51 -+#define R_MIPS_COPY 126 -+#define R_MIPS_JUMP_SLOT 127 -+/* Keep this the last entry. */ -+#define R_MIPS_NUM 128 -+ -+/* Legal values for p_type field of Elf32_Phdr. */ -+ -+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ -+#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ -+#define PT_MIPS_OPTIONS 0x70000002 -+ -+/* Special program header types. */ -+ -+#define PF_MIPS_LOCAL 0x10000000 -+ -+/* Legal values for d_tag field of Elf32_Dyn. */ -+ -+#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ -+#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ -+#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ -+#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ -+#define DT_MIPS_FLAGS 0x70000005 /* Flags */ -+#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ -+#define DT_MIPS_MSYM 0x70000007 -+#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ -+#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ -+#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ -+#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ -+#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ -+#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ -+#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ -+#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ -+#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ -+#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ -+#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ -+#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in -+ DT_MIPS_DELTA_CLASS. */ -+#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ -+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in -+ DT_MIPS_DELTA_INSTANCE. */ -+#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ -+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in -+ DT_MIPS_DELTA_RELOC. */ -+#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta -+ relocations refer to. */ -+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in -+ DT_MIPS_DELTA_SYM. */ -+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the -+ class declaration. */ -+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in -+ DT_MIPS_DELTA_CLASSSYM. */ -+#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ -+#define DT_MIPS_PIXIE_INIT 0x70000023 -+#define DT_MIPS_SYMBOL_LIB 0x70000024 -+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 -+#define DT_MIPS_LOCAL_GOTIDX 0x70000026 -+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 -+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 -+#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ -+#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ -+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b -+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ -+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve -+ function stored in GOT. */ -+#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added -+ by rld on dlopen() calls. */ -+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ -+#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ -+#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ -+/* The address of .got.plt in an executable using the new non-PIC ABI. */ -+#define DT_MIPS_PLTGOT 0x70000032 -+/* The base of the PLT in an executable using the new non-PIC ABI if that -+ PLT is writable. For a non-writable PLT, this is omitted or has a zero -+ value. */ -+#define DT_MIPS_RWPLT 0x70000034 -+#define DT_MIPS_NUM 0x35 -+ -+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ -+ -+#define RHF_NONE 0 /* No flags */ -+#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ -+#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ -+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ -+#define RHF_NO_MOVE (1 << 3) -+#define RHF_SGI_ONLY (1 << 4) -+#define RHF_GUARANTEE_INIT (1 << 5) -+#define RHF_DELTA_C_PLUS_PLUS (1 << 6) -+#define RHF_GUARANTEE_START_INIT (1 << 7) -+#define RHF_PIXIE (1 << 8) -+#define RHF_DEFAULT_DELAY_LOAD (1 << 9) -+#define RHF_REQUICKSTART (1 << 10) -+#define RHF_REQUICKSTARTED (1 << 11) -+#define RHF_CORD (1 << 12) -+#define RHF_NO_UNRES_UNDEF (1 << 13) -+#define RHF_RLD_ORDER_SAFE (1 << 14) -+ -+/* Entries found in sections of type SHT_MIPS_LIBLIST. */ -+ -+typedef struct -+{ -+ Elf32_Word l_name; /* Name (string table index) */ -+ Elf32_Word l_time_stamp; /* Timestamp */ -+ Elf32_Word l_checksum; /* Checksum */ -+ Elf32_Word l_version; /* Interface version */ -+ Elf32_Word l_flags; /* Flags */ -+} Elf32_Lib; -+ -+typedef struct -+{ -+ Elf64_Word l_name; /* Name (string table index) */ -+ Elf64_Word l_time_stamp; /* Timestamp */ -+ Elf64_Word l_checksum; /* Checksum */ -+ Elf64_Word l_version; /* Interface version */ -+ Elf64_Word l_flags; /* Flags */ -+} Elf64_Lib; -+ -+ -+/* Legal values for l_flags. */ -+ -+#define LL_NONE 0 -+#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ -+#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ -+#define LL_REQUIRE_MINOR (1 << 2) -+#define LL_EXPORTS (1 << 3) -+#define LL_DELAY_LOAD (1 << 4) -+#define LL_DELTA (1 << 5) -+ -+/* Entries found in sections of type SHT_MIPS_CONFLICT. */ -+ -+typedef Elf32_Addr Elf32_Conflict; -+ -+ -+/* HPPA specific definitions. */ -+ -+/* Legal values for e_flags field of Elf32_Ehdr. */ -+ -+#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ -+#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ -+#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ -+#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ -+#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch -+ prediction. */ -+#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ -+#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ -+ -+/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ -+ -+#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ -+#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ -+#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ -+ -+/* Additional section indeces. */ -+ -+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared -+ symbols in ANSI C. */ -+#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ -+ -+/* Legal values for sh_type field of Elf32_Shdr. */ -+ -+#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ -+#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ -+#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ -+ -+/* Legal values for sh_flags field of Elf32_Shdr. */ -+ -+#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ -+#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ -+#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ -+ -+#define STT_HP_OPAQUE (STT_LOOS + 0x1) -+#define STT_HP_STUB (STT_LOOS + 0x2) -+ -+/* HPPA relocs. */ -+ -+#define R_PARISC_NONE 0 /* No reloc. */ -+#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ -+#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ -+#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ -+#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ -+#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ -+#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ -+#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ -+#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ -+#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ -+#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ -+#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ -+#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ -+#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ -+#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ -+#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ -+#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ -+#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ -+#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ -+#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ -+#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ -+#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ -+#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ -+#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ -+#define R_PARISC_FPTR64 64 /* 64 bits function address. */ -+#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ -+#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ -+#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ -+#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ -+#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ -+#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ -+#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ -+#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ -+#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ -+#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ -+#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ -+#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ -+#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ -+#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ -+#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ -+#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ -+#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ -+#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ -+#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ -+#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ -+#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ -+#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ -+#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ -+#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ -+#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ -+#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ -+#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ -+#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ -+#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ -+#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ -+#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ -+#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ -+#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ -+#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LORESERVE 128 -+#define R_PARISC_COPY 128 /* Copy relocation. */ -+#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ -+#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ -+#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ -+#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ -+#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ -+#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ -+#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ -+#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ -+#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ -+#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ -+#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_GNU_VTENTRY 232 -+#define R_PARISC_GNU_VTINHERIT 233 -+#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ -+#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ -+#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ -+#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ -+#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ -+#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ -+#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ -+#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ -+#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ -+#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ -+#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ -+#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ -+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L -+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R -+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L -+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R -+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 -+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 -+#define R_PARISC_HIRESERVE 255 -+ -+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ -+ -+#define PT_HP_TLS (PT_LOOS + 0x0) -+#define PT_HP_CORE_NONE (PT_LOOS + 0x1) -+#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) -+#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) -+#define PT_HP_CORE_COMM (PT_LOOS + 0x4) -+#define PT_HP_CORE_PROC (PT_LOOS + 0x5) -+#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) -+#define PT_HP_CORE_STACK (PT_LOOS + 0x7) -+#define PT_HP_CORE_SHM (PT_LOOS + 0x8) -+#define PT_HP_CORE_MMF (PT_LOOS + 0x9) -+#define PT_HP_PARALLEL (PT_LOOS + 0x10) -+#define PT_HP_FASTBIND (PT_LOOS + 0x11) -+#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) -+#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) -+#define PT_HP_STACK (PT_LOOS + 0x14) -+ -+#define PT_PARISC_ARCHEXT 0x70000000 -+#define PT_PARISC_UNWIND 0x70000001 -+ -+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ -+ -+#define PF_PARISC_SBP 0x08000000 -+ -+#define PF_HP_PAGE_SIZE 0x00100000 -+#define PF_HP_FAR_SHARED 0x00200000 -+#define PF_HP_NEAR_SHARED 0x00400000 -+#define PF_HP_CODE 0x01000000 -+#define PF_HP_MODIFY 0x02000000 -+#define PF_HP_LAZYSWAP 0x04000000 -+#define PF_HP_SBP 0x08000000 -+ -+ -+/* Alpha specific definitions. */ -+ -+/* Legal values for e_flags field of Elf64_Ehdr. */ -+ -+#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ -+#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ -+ -+/* Legal values for sh_type field of Elf64_Shdr. */ -+ -+/* These two are primerily concerned with ECOFF debugging info. */ -+#define SHT_ALPHA_DEBUG 0x70000001 -+#define SHT_ALPHA_REGINFO 0x70000002 -+ -+/* Legal values for sh_flags field of Elf64_Shdr. */ -+ -+#define SHF_ALPHA_GPREL 0x10000000 -+ -+/* Legal values for st_other field of Elf64_Sym. */ -+#define STO_ALPHA_NOPV 0x80 /* No PV required. */ -+#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ -+ -+/* Alpha relocs. */ -+ -+#define R_ALPHA_NONE 0 /* No reloc */ -+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -+#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ -+#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ -+#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ -+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ -+#define R_ALPHA_TLS_GD_HI 28 -+#define R_ALPHA_TLSGD 29 -+#define R_ALPHA_TLS_LDM 30 -+#define R_ALPHA_DTPMOD64 31 -+#define R_ALPHA_GOTDTPREL 32 -+#define R_ALPHA_DTPREL64 33 -+#define R_ALPHA_DTPRELHI 34 -+#define R_ALPHA_DTPRELLO 35 -+#define R_ALPHA_DTPREL16 36 -+#define R_ALPHA_GOTTPREL 37 -+#define R_ALPHA_TPREL64 38 -+#define R_ALPHA_TPRELHI 39 -+#define R_ALPHA_TPRELLO 40 -+#define R_ALPHA_TPREL16 41 -+/* Keep this the last entry. */ -+#define R_ALPHA_NUM 46 -+ -+/* Magic values of the LITUSE relocation addend. */ -+#define LITUSE_ALPHA_ADDR 0 -+#define LITUSE_ALPHA_BASE 1 -+#define LITUSE_ALPHA_BYTOFF 2 -+#define LITUSE_ALPHA_JSR 3 -+#define LITUSE_ALPHA_TLS_GD 4 -+#define LITUSE_ALPHA_TLS_LDM 5 -+ -+/* Legal values for d_tag of Elf64_Dyn. */ -+#define DT_ALPHA_PLTRO (DT_LOPROC + 0) -+#define DT_ALPHA_NUM 1 -+ -+/* PowerPC specific declarations */ -+ -+/* Values for Elf32/64_Ehdr.e_flags. */ -+#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ -+ -+/* Cygnus local bits below */ -+#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ -+#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib -+ flag */ -+ -+/* PowerPC relocations defined by the ABIs */ -+#define R_PPC_NONE 0 -+#define R_PPC_ADDR32 1 /* 32bit absolute address */ -+#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -+#define R_PPC_ADDR16 3 /* 16bit absolute address */ -+#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -+#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -+#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -+#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -+#define R_PPC_ADDR14_BRTAKEN 8 -+#define R_PPC_ADDR14_BRNTAKEN 9 -+#define R_PPC_REL24 10 /* PC relative 26 bit */ -+#define R_PPC_REL14 11 /* PC relative 16 bit */ -+#define R_PPC_REL14_BRTAKEN 12 -+#define R_PPC_REL14_BRNTAKEN 13 -+#define R_PPC_GOT16 14 -+#define R_PPC_GOT16_LO 15 -+#define R_PPC_GOT16_HI 16 -+#define R_PPC_GOT16_HA 17 -+#define R_PPC_PLTREL24 18 -+#define R_PPC_COPY 19 -+#define R_PPC_GLOB_DAT 20 -+#define R_PPC_JMP_SLOT 21 -+#define R_PPC_RELATIVE 22 -+#define R_PPC_LOCAL24PC 23 -+#define R_PPC_UADDR32 24 -+#define R_PPC_UADDR16 25 -+#define R_PPC_REL32 26 -+#define R_PPC_PLT32 27 -+#define R_PPC_PLTREL32 28 -+#define R_PPC_PLT16_LO 29 -+#define R_PPC_PLT16_HI 30 -+#define R_PPC_PLT16_HA 31 -+#define R_PPC_SDAREL16 32 -+#define R_PPC_SECTOFF 33 -+#define R_PPC_SECTOFF_LO 34 -+#define R_PPC_SECTOFF_HI 35 -+#define R_PPC_SECTOFF_HA 36 -+ -+/* PowerPC relocations defined for the TLS access ABI. */ -+#define R_PPC_TLS 67 /* none (sym+add)@tls */ -+#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ -+#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ -+#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -+#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -+#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -+#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ -+#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ -+#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -+#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -+#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -+#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ -+#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -+#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -+#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -+#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -+#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -+#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -+#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -+#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -+#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ -+#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ -+#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -+#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -+#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ -+#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ -+#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ -+#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ -+ -+/* The remaining relocs are from the Embedded ELF ABI, and are not -+ in the SVR4 ELF ABI. */ -+#define R_PPC_EMB_NADDR32 101 -+#define R_PPC_EMB_NADDR16 102 -+#define R_PPC_EMB_NADDR16_LO 103 -+#define R_PPC_EMB_NADDR16_HI 104 -+#define R_PPC_EMB_NADDR16_HA 105 -+#define R_PPC_EMB_SDAI16 106 -+#define R_PPC_EMB_SDA2I16 107 -+#define R_PPC_EMB_SDA2REL 108 -+#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ -+#define R_PPC_EMB_MRKREF 110 -+#define R_PPC_EMB_RELSEC16 111 -+#define R_PPC_EMB_RELST_LO 112 -+#define R_PPC_EMB_RELST_HI 113 -+#define R_PPC_EMB_RELST_HA 114 -+#define R_PPC_EMB_BIT_FLD 115 -+#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ -+ -+/* Diab tool relocations. */ -+#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ -+#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ -+#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ -+#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ -+#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ -+#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ -+ -+/* GNU extension to support local ifunc. */ -+#define R_PPC_IRELATIVE 248 -+ -+/* GNU relocs used in PIC code sequences. */ -+#define R_PPC_REL16 249 /* half16 (sym+add-.) */ -+#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ -+#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ -+#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ -+ -+/* This is a phony reloc to handle any old fashioned TOC16 references -+ that may still be in object files. */ -+#define R_PPC_TOC16 255 -+ -+/* PowerPC specific values for the Dyn d_tag field. */ -+#define DT_PPC_GOT (DT_LOPROC + 0) -+#define DT_PPC_NUM 1 -+ -+/* PowerPC64 relocations defined by the ABIs */ -+#define R_PPC64_NONE R_PPC_NONE -+#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ -+#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ -+#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ -+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ -+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ -+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ -+#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ -+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN -+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN -+#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ -+#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ -+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN -+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN -+#define R_PPC64_GOT16 R_PPC_GOT16 -+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO -+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI -+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA -+ -+#define R_PPC64_COPY R_PPC_COPY -+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT -+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT -+#define R_PPC64_RELATIVE R_PPC_RELATIVE -+ -+#define R_PPC64_UADDR32 R_PPC_UADDR32 -+#define R_PPC64_UADDR16 R_PPC_UADDR16 -+#define R_PPC64_REL32 R_PPC_REL32 -+#define R_PPC64_PLT32 R_PPC_PLT32 -+#define R_PPC64_PLTREL32 R_PPC_PLTREL32 -+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO -+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI -+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA -+ -+#define R_PPC64_SECTOFF R_PPC_SECTOFF -+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO -+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI -+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA -+#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ -+#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ -+#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ -+#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ -+#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ -+#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ -+#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ -+#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ -+#define R_PPC64_PLT64 45 /* doubleword64 L + A */ -+#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ -+#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ -+#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ -+#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ -+#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ -+#define R_PPC64_TOC 51 /* doubleword64 .TOC */ -+#define R_PPC64_PLTGOT16 52 /* half16* M + A */ -+#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ -+#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ -+#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ -+ -+#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ -+#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ -+#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ -+#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ -+#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ -+#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ -+#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ -+#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ -+#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ -+#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ -+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ -+ -+/* PowerPC64 relocations defined for the TLS access ABI. */ -+#define R_PPC64_TLS 67 /* none (sym+add)@tls */ -+#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ -+#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ -+#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -+#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -+#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -+#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ -+#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ -+#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -+#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -+#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -+#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ -+#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -+#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -+#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -+#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -+#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -+#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -+#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -+#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -+#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ -+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ -+#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -+#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -+#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ -+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ -+#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ -+#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ -+#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ -+#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ -+#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ -+#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ -+#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ -+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ -+#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ -+#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ -+#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ -+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ -+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ -+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ -+ -+/* GNU extension to support local ifunc. */ -+#define R_PPC64_JMP_IREL 247 -+#define R_PPC64_IRELATIVE 248 -+#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ -+#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ -+#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ -+#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ -+ -+/* PowerPC64 specific values for the Dyn d_tag field. */ -+#define DT_PPC64_GLINK (DT_LOPROC + 0) -+#define DT_PPC64_OPD (DT_LOPROC + 1) -+#define DT_PPC64_OPDSZ (DT_LOPROC + 2) -+#define DT_PPC64_NUM 3 -+ -+ -+/* ARM specific declarations */ -+ -+/* Processor specific flags for the ELF header e_flags field. */ -+#define EF_ARM_RELEXEC 0x01 -+#define EF_ARM_HASENTRY 0x02 -+#define EF_ARM_INTERWORK 0x04 -+#define EF_ARM_APCS_26 0x08 -+#define EF_ARM_APCS_FLOAT 0x10 -+#define EF_ARM_PIC 0x20 -+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -+#define EF_ARM_NEW_ABI 0x80 -+#define EF_ARM_OLD_ABI 0x100 -+#define EF_ARM_SOFT_FLOAT 0x200 -+#define EF_ARM_VFP_FLOAT 0x400 -+#define EF_ARM_MAVERICK_FLOAT 0x800 -+ -+ -+/* Other constants defined in the ARM ELF spec. version B-01. */ -+/* NB. These conflict with values defined above. */ -+#define EF_ARM_SYMSARESORTED 0x04 -+#define EF_ARM_DYNSYMSUSESEGIDX 0x08 -+#define EF_ARM_MAPSYMSFIRST 0x10 -+#define EF_ARM_EABIMASK 0XFF000000 -+ -+/* Constants defined in AAELF. */ -+#define EF_ARM_BE8 0x00800000 -+#define EF_ARM_LE8 0x00400000 -+ -+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) -+#define EF_ARM_EABI_UNKNOWN 0x00000000 -+#define EF_ARM_EABI_VER1 0x01000000 -+#define EF_ARM_EABI_VER2 0x02000000 -+#define EF_ARM_EABI_VER3 0x03000000 -+#define EF_ARM_EABI_VER4 0x04000000 -+#define EF_ARM_EABI_VER5 0x05000000 -+ -+/* Additional symbol types for Thumb. */ -+#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -+#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ -+ -+/* ARM-specific values for sh_flags */ -+#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ -+#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined -+ in the input to a link step. */ -+ -+/* ARM-specific program header flags */ -+#define PF_ARM_SB 0x10000000 /* Segment contains the location -+ addressed by the static base. */ -+#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ -+#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ -+ -+/* Processor specific values for the Phdr p_type field. */ -+#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ -+ -+/* Processor specific values for the Shdr sh_type field. */ -+#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ -+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ -+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ -+ -+ -+/* ARM relocs. */ -+ -+#define R_ARM_NONE 0 /* No reloc */ -+#define R_ARM_PC24 1 /* PC relative 26 bit branch */ -+#define R_ARM_ABS32 2 /* Direct 32 bit */ -+#define R_ARM_REL32 3 /* PC relative 32 bit */ -+#define R_ARM_PC13 4 -+#define R_ARM_ABS16 5 /* Direct 16 bit */ -+#define R_ARM_ABS12 6 /* Direct 12 bit */ -+#define R_ARM_THM_ABS5 7 -+#define R_ARM_ABS8 8 /* Direct 8 bit */ -+#define R_ARM_SBREL32 9 -+#define R_ARM_THM_PC22 10 -+#define R_ARM_THM_PC8 11 -+#define R_ARM_AMP_VCALL9 12 -+#define R_ARM_SWI24 13 /* Obsolete static relocation. */ -+#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ -+#define R_ARM_THM_SWI8 14 -+#define R_ARM_XPC25 15 -+#define R_ARM_THM_XPC22 16 -+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ -+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ -+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ -+#define R_ARM_COPY 20 /* Copy symbol at runtime */ -+#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ -+#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ -+#define R_ARM_RELATIVE 23 /* Adjust by program base */ -+#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ -+#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ -+#define R_ARM_GOT32 26 /* 32 bit GOT entry */ -+#define R_ARM_PLT32 27 /* 32 bit PLT address */ -+#define R_ARM_ALU_PCREL_7_0 32 -+#define R_ARM_ALU_PCREL_15_8 33 -+#define R_ARM_ALU_PCREL_23_15 34 -+#define R_ARM_LDR_SBREL_11_0 35 -+#define R_ARM_ALU_SBREL_19_12 36 -+#define R_ARM_ALU_SBREL_27_20 37 -+#define R_ARM_TLS_GOTDESC 90 -+#define R_ARM_TLS_CALL 91 -+#define R_ARM_TLS_DESCSEQ 92 -+#define R_ARM_THM_TLS_CALL 93 -+#define R_ARM_GNU_VTENTRY 100 -+#define R_ARM_GNU_VTINHERIT 101 -+#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ -+#define R_ARM_THM_PC9 103 /* thumb conditional branch */ -+#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic -+ thread local data */ -+#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic -+ thread local data */ -+#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS -+ block */ -+#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of -+ static TLS block offset */ -+#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static -+ TLS block */ -+#define R_ARM_THM_TLS_DESCSEQ 129 -+#define R_ARM_IRELATIVE 160 -+#define R_ARM_RXPC25 249 -+#define R_ARM_RSBREL32 250 -+#define R_ARM_THM_RPC22 251 -+#define R_ARM_RREL32 252 -+#define R_ARM_RABS22 253 -+#define R_ARM_RPC24 254 -+#define R_ARM_RBASE 255 -+/* Keep this the last entry. */ -+#define R_ARM_NUM 256 -+ -+/* IA-64 specific declarations. */ -+ -+/* Processor specific flags for the Ehdr e_flags field. */ -+#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ -+#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ -+#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ -+ -+/* Processor specific values for the Phdr p_type field. */ -+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ -+#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ -+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) -+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) -+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) -+ -+/* Processor specific flags for the Phdr p_flags field. */ -+#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ -+ -+/* Processor specific values for the Shdr sh_type field. */ -+#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ -+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ -+ -+/* Processor specific flags for the Shdr sh_flags field. */ -+#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ -+#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ -+ -+/* Processor specific values for the Dyn d_tag field. */ -+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) -+#define DT_IA_64_NUM 1 -+ -+/* IA-64 relocations. */ -+#define R_IA64_NONE 0x00 /* none */ -+#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ -+#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ -+#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ -+#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ -+#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ -+#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ -+#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ -+#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ -+#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ -+#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ -+#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ -+#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ -+#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ -+#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ -+#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ -+#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ -+#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ -+#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ -+#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ -+#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ -+#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ -+#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ -+#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ -+#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ -+#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ -+#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ -+#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ -+#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ -+#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ -+#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ -+#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ -+#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ -+#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ -+#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ -+#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ -+#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ -+#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ -+#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ -+#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ -+#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ -+#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ -+#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ -+#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ -+#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ -+#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ -+#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ -+#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ -+#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ -+#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ -+#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ -+#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ -+#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ -+#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ -+#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ -+#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ -+#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ -+#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ -+#define R_IA64_COPY 0x84 /* copy relocation */ -+#define R_IA64_SUB 0x85 /* Addend and symbol difference */ -+#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ -+#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ -+#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ -+#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ -+#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ -+#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ -+#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ -+#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ -+#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ -+#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ -+#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ -+#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ -+#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ -+#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ -+#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ -+#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ -+ -+/* SH specific declarations */ -+ -+/* Processor specific flags for the ELF header e_flags field. */ -+#define EF_SH_MACH_MASK 0x1f -+#define EF_SH_UNKNOWN 0x0 -+#define EF_SH1 0x1 -+#define EF_SH2 0x2 -+#define EF_SH3 0x3 -+#define EF_SH_DSP 0x4 -+#define EF_SH3_DSP 0x5 -+#define EF_SH4AL_DSP 0x6 -+#define EF_SH3E 0x8 -+#define EF_SH4 0x9 -+#define EF_SH2E 0xb -+#define EF_SH4A 0xc -+#define EF_SH2A 0xd -+#define EF_SH4_NOFPU 0x10 -+#define EF_SH4A_NOFPU 0x11 -+#define EF_SH4_NOMMU_NOFPU 0x12 -+#define EF_SH2A_NOFPU 0x13 -+#define EF_SH3_NOMMU 0x14 -+#define EF_SH2A_SH4_NOFPU 0x15 -+#define EF_SH2A_SH3_NOFPU 0x16 -+#define EF_SH2A_SH4 0x17 -+#define EF_SH2A_SH3E 0x18 -+ -+/* SH relocs. */ -+#define R_SH_NONE 0 -+#define R_SH_DIR32 1 -+#define R_SH_REL32 2 -+#define R_SH_DIR8WPN 3 -+#define R_SH_IND12W 4 -+#define R_SH_DIR8WPL 5 -+#define R_SH_DIR8WPZ 6 -+#define R_SH_DIR8BP 7 -+#define R_SH_DIR8W 8 -+#define R_SH_DIR8L 9 -+#define R_SH_SWITCH16 25 -+#define R_SH_SWITCH32 26 -+#define R_SH_USES 27 -+#define R_SH_COUNT 28 -+#define R_SH_ALIGN 29 -+#define R_SH_CODE 30 -+#define R_SH_DATA 31 -+#define R_SH_LABEL 32 -+#define R_SH_SWITCH8 33 -+#define R_SH_GNU_VTINHERIT 34 -+#define R_SH_GNU_VTENTRY 35 -+#define R_SH_TLS_GD_32 144 -+#define R_SH_TLS_LD_32 145 -+#define R_SH_TLS_LDO_32 146 -+#define R_SH_TLS_IE_32 147 -+#define R_SH_TLS_LE_32 148 -+#define R_SH_TLS_DTPMOD32 149 -+#define R_SH_TLS_DTPOFF32 150 -+#define R_SH_TLS_TPOFF32 151 -+#define R_SH_GOT32 160 -+#define R_SH_PLT32 161 -+#define R_SH_COPY 162 -+#define R_SH_GLOB_DAT 163 -+#define R_SH_JMP_SLOT 164 -+#define R_SH_RELATIVE 165 -+#define R_SH_GOTOFF 166 -+#define R_SH_GOTPC 167 -+/* Keep this the last entry. */ -+#define R_SH_NUM 256 -+ -+/* S/390 specific definitions. */ -+ -+/* Valid values for the e_flags field. */ -+ -+#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ -+ -+/* Additional s390 relocs */ -+ -+#define R_390_NONE 0 /* No reloc. */ -+#define R_390_8 1 /* Direct 8 bit. */ -+#define R_390_12 2 /* Direct 12 bit. */ -+#define R_390_16 3 /* Direct 16 bit. */ -+#define R_390_32 4 /* Direct 32 bit. */ -+#define R_390_PC32 5 /* PC relative 32 bit. */ -+#define R_390_GOT12 6 /* 12 bit GOT offset. */ -+#define R_390_GOT32 7 /* 32 bit GOT offset. */ -+#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ -+#define R_390_COPY 9 /* Copy symbol at runtime. */ -+#define R_390_GLOB_DAT 10 /* Create GOT entry. */ -+#define R_390_JMP_SLOT 11 /* Create PLT entry. */ -+#define R_390_RELATIVE 12 /* Adjust by program base. */ -+#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ -+#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ -+#define R_390_GOT16 15 /* 16 bit GOT offset. */ -+#define R_390_PC16 16 /* PC relative 16 bit. */ -+#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ -+#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ -+#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ -+#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ -+#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ -+#define R_390_64 22 /* Direct 64 bit. */ -+#define R_390_PC64 23 /* PC relative 64 bit. */ -+#define R_390_GOT64 24 /* 64 bit GOT offset. */ -+#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ -+#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ -+#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ -+#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ -+#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ -+#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ -+#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ -+#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ -+#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ -+#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ -+#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ -+#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ -+#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ -+#define R_390_TLS_GDCALL 38 /* Tag for function call in general -+ dynamic TLS code. */ -+#define R_390_TLS_LDCALL 39 /* Tag for function call in local -+ dynamic TLS code. */ -+#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic -+ thread local data. */ -+#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic -+ thread local data. */ -+#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic -+ thread local data in LE code. */ -+#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic -+ thread local data in LE code. */ -+#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to -+ static TLS block. */ -+#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to -+ static TLS block. */ -+#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS -+ block. */ -+#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS -+ block. */ -+#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ -+#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ -+#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS -+ block. */ -+#define R_390_20 57 /* Direct 20 bit. */ -+#define R_390_GOT20 58 /* 20 bit GOT offset. */ -+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ -+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ -+/* Keep this the last entry. */ -+#define R_390_NUM 62 -+ -+ -+/* CRIS relocations. */ -+#define R_CRIS_NONE 0 -+#define R_CRIS_8 1 -+#define R_CRIS_16 2 -+#define R_CRIS_32 3 -+#define R_CRIS_8_PCREL 4 -+#define R_CRIS_16_PCREL 5 -+#define R_CRIS_32_PCREL 6 -+#define R_CRIS_GNU_VTINHERIT 7 -+#define R_CRIS_GNU_VTENTRY 8 -+#define R_CRIS_COPY 9 -+#define R_CRIS_GLOB_DAT 10 -+#define R_CRIS_JUMP_SLOT 11 -+#define R_CRIS_RELATIVE 12 -+#define R_CRIS_16_GOT 13 -+#define R_CRIS_32_GOT 14 -+#define R_CRIS_16_GOTPLT 15 -+#define R_CRIS_32_GOTPLT 16 -+#define R_CRIS_32_GOTREL 17 -+#define R_CRIS_32_PLT_GOTREL 18 -+#define R_CRIS_32_PLT_PCREL 19 -+ -+#define R_CRIS_NUM 20 -+ -+ -+/* AMD x86-64 relocations. */ -+#define R_X86_64_NONE 0 /* No reloc */ -+#define R_X86_64_64 1 /* Direct 64 bit */ -+#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -+#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -+#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -+#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -+#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -+#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative -+ offset to GOT */ -+#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -+#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -+#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -+#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ -+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -+#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ -+#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ -+#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset -+ to two GOT entries for GD symbol */ -+#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset -+ to two GOT entries for LD symbol */ -+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -+#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset -+ to GOT entry for IE symbol */ -+#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ -+#define R_X86_64_PC64 24 /* PC relative 64 bit */ -+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ -+#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative -+ offset to GOT */ -+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ -+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset -+ to GOT entry */ -+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ -+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ -+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset -+ to PLT entry */ -+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ -+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ -+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ -+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS -+ descriptor. */ -+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ -+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ -+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ -+ -+#define R_X86_64_NUM 39 -+ -+ -+/* AM33 relocations. */ -+#define R_MN10300_NONE 0 /* No reloc. */ -+#define R_MN10300_32 1 /* Direct 32 bit. */ -+#define R_MN10300_16 2 /* Direct 16 bit. */ -+#define R_MN10300_8 3 /* Direct 8 bit. */ -+#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ -+#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ -+#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ -+#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ -+#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ -+#define R_MN10300_24 9 /* Direct 24 bit. */ -+#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ -+#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ -+#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ -+#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ -+#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ -+#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ -+#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ -+#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ -+#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ -+#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ -+#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ -+#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ -+#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ -+#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ -+ -+#define R_MN10300_NUM 24 -+ -+ -+/* M32R relocs. */ -+#define R_M32R_NONE 0 /* No reloc. */ -+#define R_M32R_16 1 /* Direct 16 bit. */ -+#define R_M32R_32 2 /* Direct 32 bit. */ -+#define R_M32R_24 3 /* Direct 24 bit. */ -+#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ -+#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ -+#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ -+#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ -+#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ -+#define R_M32R_LO16 9 /* Low 16 bit. */ -+#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ -+#define R_M32R_GNU_VTINHERIT 11 -+#define R_M32R_GNU_VTENTRY 12 -+/* M32R relocs use SHT_RELA. */ -+#define R_M32R_16_RELA 33 /* Direct 16 bit. */ -+#define R_M32R_32_RELA 34 /* Direct 32 bit. */ -+#define R_M32R_24_RELA 35 /* Direct 24 bit. */ -+#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ -+#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ -+#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ -+#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ -+#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ -+#define R_M32R_LO16_RELA 41 /* Low 16 bit */ -+#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ -+#define R_M32R_RELA_GNU_VTINHERIT 43 -+#define R_M32R_RELA_GNU_VTENTRY 44 -+#define R_M32R_REL32 45 /* PC relative 32 bit. */ -+ -+#define R_M32R_GOT24 48 /* 24 bit GOT entry */ -+#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ -+#define R_M32R_COPY 50 /* Copy symbol at runtime */ -+#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ -+#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ -+#define R_M32R_RELATIVE 53 /* Adjust by program base */ -+#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ -+#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ -+#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned -+ low */ -+#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed -+ low */ -+#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ -+#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to -+ GOT with unsigned low */ -+#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to -+ GOT with signed low */ -+#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to -+ GOT */ -+#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT -+ with unsigned low */ -+#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT -+ with signed low */ -+#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ -+#define R_M32R_NUM 256 /* Keep this the last entry. */ -+ -+ -+/* TILEPro relocations. */ -+#define R_TILEPRO_NONE 0 /* No reloc */ -+#define R_TILEPRO_32 1 /* Direct 32 bit */ -+#define R_TILEPRO_16 2 /* Direct 16 bit */ -+#define R_TILEPRO_8 3 /* Direct 8 bit */ -+#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ -+#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ -+#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ -+#define R_TILEPRO_LO16 7 /* Low 16 bit */ -+#define R_TILEPRO_HI16 8 /* High 16 bit */ -+#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ -+#define R_TILEPRO_COPY 10 /* Copy relocation */ -+#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ -+#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ -+#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ -+#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ -+#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ -+#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ -+#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ -+#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ -+#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ -+#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ -+#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ -+#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ -+#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ -+#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ -+#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ -+#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ -+#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ -+#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ -+#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ -+#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ -+#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ -+#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ -+#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ -+#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ -+#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ -+#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ -+#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ -+#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ -+#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ -+#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ -+#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ -+#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ -+#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ -+#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ -+#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ -+#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ -+#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ -+#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ -+/* Relocs 56-59 are currently not defined. */ -+#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ -+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ -+#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ -+#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ -+#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ -+#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ -+#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ -+#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ -+ -+#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -+#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ -+ -+#define R_TILEPRO_NUM 130 -+ -+ -+/* TILE-Gx relocations. */ -+#define R_TILEGX_NONE 0 /* No reloc */ -+#define R_TILEGX_64 1 /* Direct 64 bit */ -+#define R_TILEGX_32 2 /* Direct 32 bit */ -+#define R_TILEGX_16 3 /* Direct 16 bit */ -+#define R_TILEGX_8 4 /* Direct 8 bit */ -+#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ -+#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ -+#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ -+#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ -+#define R_TILEGX_HW0 9 /* hword 0 16-bit */ -+#define R_TILEGX_HW1 10 /* hword 1 16-bit */ -+#define R_TILEGX_HW2 11 /* hword 2 16-bit */ -+#define R_TILEGX_HW3 12 /* hword 3 16-bit */ -+#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ -+#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ -+#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ -+#define R_TILEGX_COPY 16 /* Copy relocation */ -+#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ -+#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ -+#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ -+#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ -+#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ -+#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ -+#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ -+#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ -+#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ -+#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ -+#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ -+#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ -+#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ -+#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ -+#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ -+#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ -+#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ -+#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ -+#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ -+#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ -+#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ -+#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ -+#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ -+#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ -+#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ -+#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ -+#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ -+/* Relocs 66-71 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ -+/* Relocs 76-77 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ -+/* Relocs 90-91 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ -+/* Relocs 94-99 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ -+/* Relocs 104-105 are currently not defined. */ -+#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ -+#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ -+#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ -+#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ -+#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ -+#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ -+#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ -+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ -+#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ -+#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ -+ -+#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -+#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ -+ -+#define R_TILEGX_NUM 130 -+ -+#endif /* elf.h */ ---- a/scripts/mod/mk_elfconfig.c -+++ b/scripts/mod/mk_elfconfig.c -@@ -2,7 +2,11 @@ - #include - #include - #include -+#ifndef __APPLE__ - #include -+#else -+#include "elf.h" -+#endif - - int - main(int argc, char **argv) ---- a/scripts/mod/modpost.h -+++ b/scripts/mod/modpost.h -@@ -8,7 +8,11 @@ - #include - #include - #include -+#if !(defined(__APPLE__) || defined(__CYGWIN__)) - #include -+#else -+#include "elf.h" -+#endif - - #include "elfconfig.h" - diff --git a/target/linux/generic/hack-5.15/211-darwin-uuid-typedef-clash.patch b/target/linux/generic/hack-5.15/211-darwin-uuid-typedef-clash.patch deleted file mode 100644 index 50a6227148f4ea..00000000000000 --- a/target/linux/generic/hack-5.15/211-darwin-uuid-typedef-clash.patch +++ /dev/null @@ -1,22 +0,0 @@ -From e44fc2af1ddc452b6659d08c16973d65c73b7d0a Mon Sep 17 00:00:00 2001 -From: Kevin Darbyshire-Bryant -Date: Wed, 5 Feb 2020 18:36:43 +0000 -Subject: [PATCH] file2alias: build on macos - -Signed-off-by: Kevin Darbyshire-Bryant ---- - scripts/mod/file2alias.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/scripts/mod/file2alias.c -+++ b/scripts/mod/file2alias.c -@@ -38,6 +38,9 @@ typedef struct { - __u8 b[16]; - } guid_t; - -+#ifdef __APPLE__ -+#define uuid_t compat_uuid_t -+#endif - /* backwards compatibility, don't use in new code */ - typedef struct { - __u8 b[16]; diff --git a/target/linux/generic/hack-5.15/212-tools_portability.patch b/target/linux/generic/hack-5.15/212-tools_portability.patch deleted file mode 100644 index b488155f9425ad..00000000000000 --- a/target/linux/generic/hack-5.15/212-tools_portability.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 48232d3d931c95953ce2ddfe7da7bb164aef6a73 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:03:16 +0200 -Subject: fix portability of some includes files in tools/ used on the host - -Signed-off-by: Felix Fietkau ---- - tools/include/tools/be_byteshift.h | 4 ++++ - tools/include/tools/le_byteshift.h | 4 ++++ - tools/include/tools/linux_types.h | 22 ++++++++++++++++++++++ - 3 files changed, 30 insertions(+) - create mode 100644 tools/include/tools/linux_types.h - ---- a/tools/include/tools/be_byteshift.h -+++ b/tools/include/tools/be_byteshift.h -@@ -2,6 +2,10 @@ - #ifndef _TOOLS_BE_BYTESHIFT_H - #define _TOOLS_BE_BYTESHIFT_H - -+#ifndef __linux__ -+#include "linux_types.h" -+#endif -+ - #include - - static inline uint16_t __get_unaligned_be16(const uint8_t *p) ---- a/tools/include/tools/le_byteshift.h -+++ b/tools/include/tools/le_byteshift.h -@@ -2,6 +2,10 @@ - #ifndef _TOOLS_LE_BYTESHIFT_H - #define _TOOLS_LE_BYTESHIFT_H - -+#ifndef __linux__ -+#include "linux_types.h" -+#endif -+ - #include - - static inline uint16_t __get_unaligned_le16(const uint8_t *p) ---- /dev/null -+++ b/tools/include/tools/linux_types.h -@@ -0,0 +1,26 @@ -+#ifndef __LINUX_TYPES_H -+#define __LINUX_TYPES_H -+ -+#include -+ -+typedef int8_t __s8; -+typedef uint8_t __u8; -+typedef uint8_t __be8; -+typedef uint8_t __le8; -+ -+typedef int16_t __s16; -+typedef uint16_t __u16; -+typedef uint16_t __be16; -+typedef uint16_t __le16; -+ -+typedef int32_t __s32; -+typedef uint32_t __u32; -+typedef uint32_t __be32; -+typedef uint32_t __le32; -+ -+typedef int64_t __s64; -+typedef uint64_t __u64; -+typedef uint64_t __be64; -+typedef uint64_t __le64; -+ -+#endif ---- a/tools/include/linux/types.h -+++ b/tools/include/linux/types.h -@@ -10,8 +10,12 @@ - #define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */ - #endif - -+#ifndef __linux__ -+#include -+#else - #include - #include -+#endif - - struct page; - struct kmem_cache; ---- a/tools/perf/pmu-events/jevents.c -+++ b/tools/perf/pmu-events/jevents.c -@@ -1,4 +1,6 @@ -+#ifdef __linux__ - #define _XOPEN_SOURCE 500 /* needed for nftw() */ -+#endif - #define _GNU_SOURCE /* needed for asprintf() */ - - /* Parse event JSON files */ -@@ -35,6 +37,7 @@ - #include - #include - #include -+#include - #include - #include - #include ---- a/tools/perf/pmu-events/json.c -+++ b/tools/perf/pmu-events/json.c -@@ -38,7 +38,6 @@ - #include - #include "jsmn.h" - #include "json.h" --#include - - - static char *mapfile(const char *fn, size_t *size) diff --git a/target/linux/generic/hack-5.15/214-spidev_h_portability.patch b/target/linux/generic/hack-5.15/214-spidev_h_portability.patch deleted file mode 100644 index db754a29033c06..00000000000000 --- a/target/linux/generic/hack-5.15/214-spidev_h_portability.patch +++ /dev/null @@ -1,24 +0,0 @@ -From be9be95ff10e16a5b4ad36f903978d0cc5747024 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:04:08 +0200 -Subject: kernel: fix linux/spi/spidev.h portability issues with musl - -Felix will try to get this define included into musl - -lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff -Signed-off-by: Felix Fietkau ---- - include/uapi/linux/spi/spidev.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/include/uapi/linux/spi/spidev.h -+++ b/include/uapi/linux/spi/spidev.h -@@ -93,7 +93,7 @@ struct spi_ioc_transfer { - - /* not all platforms use or _IOC_TYPECHECK() ... */ - #define SPI_MSGSIZE(N) \ -- ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ -+ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \ - ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0) - #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) - diff --git a/target/linux/generic/hack-5.15/220-arm-gc_sections.patch b/target/linux/generic/hack-5.15/220-arm-gc_sections.patch deleted file mode 100644 index dd6507c9178b29..00000000000000 --- a/target/linux/generic/hack-5.15/220-arm-gc_sections.patch +++ /dev/null @@ -1,123 +0,0 @@ -From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 15 Jul 2017 23:42:36 +0200 -Subject: use -ffunction-sections, -fdata-sections and --gc-sections - -In combination with kernel symbol export stripping this significantly reduces -the kernel image size. Used on both ARM and MIPS architectures. - -Signed-off-by: Felix Fietkau -Signed-off-by: Jonas Gorski -Signed-off-by: Gabor Juhos ---- ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -118,6 +118,7 @@ config ARM - select HAVE_UID16 - select HAVE_VIRT_CPU_ACCOUNTING_GEN - select IRQ_FORCED_THREADING -+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION - select MODULES_USE_ELF_REL - select NEED_DMA_MAP_STATE - select OF_EARLY_FLATTREE if OF ---- a/arch/arm/boot/compressed/Makefile -+++ b/arch/arm/boot/compressed/Makefile -@@ -92,6 +92,7 @@ endif - ifeq ($(CONFIG_USE_OF),y) - OBJS += $(libfdt_objs) fdt_check_mem_start.o - endif -+KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL)) - - # -fstack-protector-strong triggers protection checks in this code, - # but it is being used too early to link to meaningful stack_chk logic. ---- a/arch/arm/kernel/vmlinux.lds.S -+++ b/arch/arm/kernel/vmlinux.lds.S -@@ -75,7 +75,7 @@ SECTIONS - . = ALIGN(4); - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { - __start___ex_table = .; -- ARM_MMU_KEEP(*(__ex_table)) -+ KEEP(*(__ex_table)) - __stop___ex_table = .; - } - -@@ -100,24 +100,24 @@ SECTIONS - } - .init.arch.info : { - __arch_info_begin = .; -- *(.arch.info.init) -+ KEEP(*(.arch.info.init)) - __arch_info_end = .; - } - .init.tagtable : { - __tagtable_begin = .; -- *(.taglist.init) -+ KEEP(*(.taglist.init)) - __tagtable_end = .; - } - #ifdef CONFIG_SMP_ON_UP - .init.smpalt : { - __smpalt_begin = .; -- *(.alt.smp.init) -+ KEEP(*(.alt.smp.init)) - __smpalt_end = .; - } - #endif - .init.pv_table : { - __pv_table_begin = .; -- *(.pv_table) -+ KEEP(*(.pv_table)) - __pv_table_end = .; - } - ---- a/arch/arm/include/asm/vmlinux.lds.h -+++ b/arch/arm/include/asm/vmlinux.lds.h -@@ -42,13 +42,13 @@ - #define PROC_INFO \ - . = ALIGN(4); \ - __proc_info_begin = .; \ -- *(.proc.info.init) \ -+ KEEP(*(.proc.info.init)) \ - __proc_info_end = .; - - #define IDMAP_TEXT \ - ALIGN_FUNCTION(); \ - __idmap_text_start = .; \ -- *(.idmap.text) \ -+ KEEP(*(.idmap.text)) \ - __idmap_text_end = .; \ - - #define ARM_DISCARD \ -@@ -109,12 +109,12 @@ - . = ALIGN(8); \ - .ARM.unwind_idx : { \ - __start_unwind_idx = .; \ -- *(.ARM.exidx*) \ -+ KEEP(*(.ARM.exidx*)) \ - __stop_unwind_idx = .; \ - } \ - .ARM.unwind_tab : { \ - __start_unwind_tab = .; \ -- *(.ARM.extab*) \ -+ KEEP(*(.ARM.extab*)) \ - __stop_unwind_tab = .; \ - } - -@@ -126,7 +126,7 @@ - __vectors_lma = .; \ - OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \ - .vectors { \ -- *(.vectors) \ -+ KEEP(*(.vectors)) \ - } \ - .vectors.bhb.loop8 { \ - *(.vectors.bhb.loop8) \ -@@ -144,7 +144,7 @@ - \ - __stubs_lma = .; \ - .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \ -- *(.stubs) \ -+ KEEP(*(.stubs)) \ - } \ - ARM_LMA(__stubs, .stubs); \ - . = __stubs_lma + SIZEOF(.stubs); \ diff --git a/target/linux/generic/hack-5.15/221-module_exports.patch b/target/linux/generic/hack-5.15/221-module_exports.patch deleted file mode 100644 index 8db0f7dac78c34..00000000000000 --- a/target/linux/generic/hack-5.15/221-module_exports.patch +++ /dev/null @@ -1,126 +0,0 @@ -From b14784e7883390c20ed3ff904892255404a5914b Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:05:53 +0200 -Subject: add an optional config option for stripping all unnecessary symbol exports from the kernel image - -lede-commit: bb5a40c64b7c4f4848509fa0a6625055fc9e66cc -Signed-off-by: Felix Fietkau ---- - include/asm-generic/vmlinux.lds.h | 18 +++++++++++++++--- - include/linux/export.h | 9 ++++++++- - scripts/Makefile.build | 2 +- - 3 files changed, 24 insertions(+), 5 deletions(-) - ---- a/include/asm-generic/vmlinux.lds.h -+++ b/include/asm-generic/vmlinux.lds.h -@@ -81,6 +81,16 @@ - #define RO_EXCEPTION_TABLE - #endif - -+#ifndef SYMTAB_KEEP -+#define SYMTAB_KEEP KEEP(*(SORT(___ksymtab+*))) -+#define SYMTAB_KEEP_GPL KEEP(*(SORT(___ksymtab_gpl+*))) -+#endif -+ -+#ifndef SYMTAB_DISCARD -+#define SYMTAB_DISCARD -+#define SYMTAB_DISCARD_GPL -+#endif -+ - /* Align . function alignment. */ - #define ALIGN_FUNCTION() . = ALIGN(CONFIG_FUNCTION_ALIGNMENT) - -@@ -485,14 +495,14 @@ - /* Kernel symbol table: Normal symbols */ \ - __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ - __start___ksymtab = .; \ -- KEEP(*(SORT(___ksymtab+*))) \ -+ SYMTAB_KEEP \ - __stop___ksymtab = .; \ - } \ - \ - /* Kernel symbol table: GPL-only symbols */ \ - __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ - __start___ksymtab_gpl = .; \ -- KEEP(*(SORT(___ksymtab_gpl+*))) \ -+ SYMTAB_KEEP_GPL \ - __stop___ksymtab_gpl = .; \ - } \ - \ -@@ -512,7 +522,7 @@ - \ - /* Kernel symbol table: strings */ \ - __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ -- *(__ksymtab_strings) \ -+ *(__ksymtab_strings+*) \ - } \ - \ - /* __*init sections */ \ -@@ -1022,6 +1032,8 @@ - - #define COMMON_DISCARDS \ - SANITIZER_DISCARDS \ -+ SYMTAB_DISCARD \ -+ SYMTAB_DISCARD_GPL \ - *(.discard) \ - *(.discard.*) \ - *(.modinfo) \ ---- a/include/linux/export.h -+++ b/include/linux/export.h -@@ -84,6 +84,12 @@ struct kernel_symbol { - - #else - -+#ifdef MODULE -+#define __EXPORT_SUFFIX(sym) -+#else -+#define __EXPORT_SUFFIX(sym) "+" #sym -+#endif -+ - /* - * For every exported symbol, do the following: - * -@@ -101,7 +107,7 @@ struct kernel_symbol { - extern const char __kstrtab_##sym[]; \ - extern const char __kstrtabns_##sym[]; \ - __CRC_SYMBOL(sym, sec); \ -- asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \ -+ asm(" .section \"__ksymtab_strings" __EXPORT_SUFFIX(sym) "\",\"aMS\",%progbits,1 \n" \ - "__kstrtab_" #sym ": \n" \ - " .asciz \"" #sym "\" \n" \ - "__kstrtabns_" #sym ": \n" \ ---- a/include/asm-generic/export.h -+++ b/include/asm-generic/export.h -@@ -26,6 +26,12 @@ - #endif - .endm - -+#ifdef MODULE -+#define __EXPORT_SUFFIX(name) -+#else -+#define __EXPORT_SUFFIX(name) + #name -+#endif -+ - /* - * note on .section use: we specify progbits since usage of the "M" (SHF_MERGE) - * section flag requires it. Use '%progbits' instead of '@progbits' since the -@@ -39,7 +45,7 @@ - __ksymtab_\name: - __put \val, __kstrtab_\name - .previous -- .section __ksymtab_strings,"aMS",%progbits,1 -+ .section __ksymtab_strings __EXPORT_SUFFIX(name),"aMS",%progbits,1 - __kstrtab_\name: - .asciz "\name" - .previous ---- a/scripts/Makefile.build -+++ b/scripts/Makefile.build -@@ -397,7 +397,7 @@ targets += $(real-dtb-y) $(lib-y) $(alwa - # Linker scripts preprocessor (.lds.S -> .lds) - # --------------------------------------------------------------------------- - quiet_cmd_cpp_lds_S = LDS $@ -- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \ -+ cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -U$(ARCH) \ - -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< - - $(obj)/%.lds: $(src)/%.lds.S FORCE diff --git a/target/linux/generic/hack-5.15/230-openwrt_lzma_options.patch b/target/linux/generic/hack-5.15/230-openwrt_lzma_options.patch deleted file mode 100644 index f9361b060bdd52..00000000000000 --- a/target/linux/generic/hack-5.15/230-openwrt_lzma_options.patch +++ /dev/null @@ -1,34 +0,0 @@ -From b3d00b452467f621317953d9e4c6f9ae8dcfd271 Mon Sep 17 00:00:00 2001 -From: Imre Kaloz -Date: Fri, 7 Jul 2017 17:06:55 +0200 -Subject: use the openwrt lzma options for now - -lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c -Signed-off-by: Imre Kaloz ---- - lib/decompress.c | 1 + - scripts/Makefile.lib | 2 +- - usr/gen_initramfs_list.sh | 10 +++++----- - 3 files changed, 7 insertions(+), 6 deletions(-) - ---- a/lib/decompress.c -+++ b/lib/decompress.c -@@ -53,6 +53,7 @@ static const struct compress_format comp - { {0x1f, 0x9e}, "gzip", gunzip }, - { {0x42, 0x5a}, "bzip2", bunzip2 }, - { {0x5d, 0x00}, "lzma", unlzma }, -+ { {0x6d, 0x00}, "lzma-openwrt", unlzma }, - { {0xfd, 0x37}, "xz", unxz }, - { {0x89, 0x4c}, "lzo", unlzo }, - { {0x02, 0x21}, "lz4", unlz4 }, ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -402,7 +402,7 @@ quiet_cmd_bzip2 = BZIP2 $@ - # --------------------------------------------------------------------------- - - quiet_cmd_lzma = LZMA $@ -- cmd_lzma = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@ -+ cmd_lzma = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@ - - quiet_cmd_lzo = LZO $@ - cmd_lzo = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@ diff --git a/target/linux/generic/hack-5.15/250-netfilter_depends.patch b/target/linux/generic/hack-5.15/250-netfilter_depends.patch deleted file mode 100644 index 1f8af6dbe847c6..00000000000000 --- a/target/linux/generic/hack-5.15/250-netfilter_depends.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Felix Fietkau -Subject: hack: net: remove bogus netfilter dependencies - -lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6 -Signed-off-by: Felix Fietkau ---- - net/netfilter/Kconfig | 2 -- - 1 file changed, 2 deletions(-) - ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -242,7 +242,6 @@ config NF_CONNTRACK_FTP - - config NF_CONNTRACK_H323 - tristate "H.323 protocol support" -- depends on IPV6 || IPV6=n - depends on NETFILTER_ADVANCED - help - H.323 is a VoIP signalling protocol from ITU-T. As one of the most -@@ -1114,7 +1113,6 @@ config NETFILTER_XT_TARGET_SECMARK - - config NETFILTER_XT_TARGET_TCPMSS - tristate '"TCPMSS" target support' -- depends on IPV6 || IPV6=n - default m if NETFILTER_ADVANCED=n - help - This option adds a `TCPMSS' target, which allows you to alter the diff --git a/target/linux/generic/hack-5.15/251-kconfig.patch b/target/linux/generic/hack-5.15/251-kconfig.patch deleted file mode 100644 index 00c23db955e83c..00000000000000 --- a/target/linux/generic/hack-5.15/251-kconfig.patch +++ /dev/null @@ -1,157 +0,0 @@ -From da3c50704f14132f4adf80d48e9a4cd5d46e54c9 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 7 Jul 2017 17:09:21 +0200 -Subject: kconfig: owrt specifc dependencies - -Signed-off-by: John Crispin ---- - crypto/Kconfig | 10 +++++----- - drivers/bcma/Kconfig | 1 + - drivers/ssb/Kconfig | 3 ++- - lib/Kconfig | 8 ++++---- - net/netfilter/Kconfig | 2 +- - net/wireless/Kconfig | 17 ++++++++++------- - sound/core/Kconfig | 4 ++-- - 7 files changed, 25 insertions(+), 20 deletions(-) - ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -34,7 +34,7 @@ config CRYPTO_FIPS - this is. - - config CRYPTO_ALGAPI -- tristate -+ tristate "ALGAPI" - select CRYPTO_ALGAPI2 - help - This option provides the API for cryptographic algorithms. -@@ -43,7 +43,7 @@ config CRYPTO_ALGAPI2 - tristate - - config CRYPTO_AEAD -- tristate -+ tristate "AEAD" - select CRYPTO_AEAD2 - select CRYPTO_ALGAPI - -@@ -54,7 +54,7 @@ config CRYPTO_AEAD2 - select CRYPTO_RNG2 - - config CRYPTO_SKCIPHER -- tristate -+ tristate "SKCIPHER" - select CRYPTO_SKCIPHER2 - select CRYPTO_ALGAPI - -@@ -64,7 +64,7 @@ config CRYPTO_SKCIPHER2 - select CRYPTO_RNG2 - - config CRYPTO_HASH -- tristate -+ tristate "HASH" - select CRYPTO_HASH2 - select CRYPTO_ALGAPI - -@@ -73,7 +73,7 @@ config CRYPTO_HASH2 - select CRYPTO_ALGAPI2 - - config CRYPTO_RNG -- tristate -+ tristate "RNG" - select CRYPTO_RNG2 - select CRYPTO_ALGAPI - ---- a/drivers/bcma/Kconfig -+++ b/drivers/bcma/Kconfig -@@ -16,6 +16,7 @@ if BCMA - # Support for Block-I/O. SELECT this from the driver that needs it. - config BCMA_BLOCKIO - bool -+ default y - - config BCMA_HOST_PCI_POSSIBLE - bool ---- a/drivers/ssb/Kconfig -+++ b/drivers/ssb/Kconfig -@@ -29,6 +29,7 @@ config SSB_SPROM - config SSB_BLOCKIO - bool - depends on SSB -+ default y - - config SSB_PCIHOST_POSSIBLE - bool -@@ -49,7 +50,7 @@ config SSB_PCIHOST - config SSB_B43_PCI_BRIDGE - bool - depends on SSB_PCIHOST -- default n -+ default y - - config SSB_PCMCIAHOST_POSSIBLE - bool ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -443,16 +443,16 @@ config BCH_CONST_T - # Textsearch support is select'ed if needed - # - config TEXTSEARCH -- bool -+ bool "Textsearch support" - - config TEXTSEARCH_KMP -- tristate -+ tristate "Textsearch KMP" - - config TEXTSEARCH_BM -- tristate -+ tristate "Textsearch BM" - - config TEXTSEARCH_FSM -- tristate -+ tristate "Textsearch FSM" - - config BTREE - bool ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -11,7 +11,7 @@ config NETFILTER_INGRESS - infrastructure. - - config NETFILTER_NETLINK -- tristate -+ tristate "Netfilter NFNETLINK interface" - - config NETFILTER_FAMILY_BRIDGE - bool ---- a/sound/core/Kconfig -+++ b/sound/core/Kconfig -@@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM - tristate - - config SND_HWDEP -- tristate -+ tristate "Sound hardware support" - - config SND_SEQ_DEVICE - tristate -@@ -27,7 +27,7 @@ config SND_RAWMIDI - select SND_SEQ_DEVICE if SND_SEQUENCER != n - - config SND_COMPRESS_OFFLOAD -- tristate -+ tristate "Compression offloading support" - - config SND_JACK - bool ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -430,7 +430,7 @@ config NET_DEVLINK - default n - - config PAGE_POOL -- bool -+ bool "Page pool support" - - config PAGE_POOL_STATS - default n diff --git a/target/linux/generic/hack-5.15/253-ksmbd-config.patch b/target/linux/generic/hack-5.15/253-ksmbd-config.patch deleted file mode 100644 index b8cb94f62bc0a8..00000000000000 --- a/target/linux/generic/hack-5.15/253-ksmbd-config.patch +++ /dev/null @@ -1,32 +0,0 @@ -From dcd966fa7ca63f38cf7147e1184d13d66e2ca340 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:33:30 +0200 -Subject: [PATCH] Kconfig: add tristate for OID and ASNI string - ---- - init/Kconfig | 2 +- - lib/Kconfig | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -2388,7 +2388,7 @@ config PADATA - bool - - config ASN1 -- tristate -+ tristate "ASN1" - help - Build a simple ASN.1 grammar compiler that produces a bytecode output - that can be interpreted by the ASN.1 stream decoder and used to ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -614,7 +614,7 @@ config LIBFDT - bool - - config OID_REGISTRY -- tristate -+ tristate "OID" - help - Enable fast lookup object identifier registry. - diff --git a/target/linux/generic/hack-5.15/259-regmap_dynamic.patch b/target/linux/generic/hack-5.15/259-regmap_dynamic.patch deleted file mode 100644 index ea06821c4bd6fe..00000000000000 --- a/target/linux/generic/hack-5.15/259-regmap_dynamic.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 811d9e2268a62b830cfe93cd8bc929afcb8b198b Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 15 Jul 2017 21:12:38 +0200 -Subject: kernel: move regmap bloat out of the kernel image if it is only being used in modules - -lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998 -Signed-off-by: Felix Fietkau ---- - drivers/base/regmap/Kconfig | 15 ++++++++++----- - drivers/base/regmap/Makefile | 12 ++++++++---- - drivers/base/regmap/regmap.c | 3 +++ - include/linux/regmap.h | 2 +- - 4 files changed, 22 insertions(+), 10 deletions(-) - ---- a/drivers/base/regmap/Kconfig -+++ b/drivers/base/regmap/Kconfig -@@ -4,10 +4,9 @@ - # subsystems should select the appropriate symbols. - - config REGMAP -- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM || REGMAP_MDIO) - select IRQ_DOMAIN if REGMAP_IRQ - select MDIO_BUS if REGMAP_MDIO -- bool -+ tristate - - config REGCACHE_COMPRESSED - select LZO_COMPRESS -@@ -15,53 +14,67 @@ config REGCACHE_COMPRESSED - bool - - config REGMAP_AC97 -+ select REGMAP - tristate - - config REGMAP_I2C -+ select REGMAP - tristate - depends on I2C - - config REGMAP_SLIMBUS -+ select REGMAP - tristate - depends on SLIMBUS - - config REGMAP_SPI -+ select REGMAP - tristate - depends on SPI - - config REGMAP_SPMI -+ select REGMAP - tristate - depends on SPMI - - config REGMAP_W1 -+ select REGMAP - tristate - depends on W1 - - config REGMAP_MDIO -+ select REGMAP - tristate - - config REGMAP_MMIO -+ select REGMAP - tristate - - config REGMAP_IRQ -+ select REGMAP - bool - - config REGMAP_SOUNDWIRE -+ select REGMAP - tristate - depends on SOUNDWIRE - - config REGMAP_SOUNDWIRE_MBQ -+ select REGMAP - tristate - depends on SOUNDWIRE - - config REGMAP_SCCB -+ select REGMAP - tristate - depends on I2C - - config REGMAP_I3C -+ select REGMAP - tristate - depends on I3C - - config REGMAP_SPI_AVMM -+ select REGMAP - tristate - depends on SPI ---- a/drivers/base/regmap/Makefile -+++ b/drivers/base/regmap/Makefile -@@ -2,10 +2,14 @@ - # For include/trace/define_trace.h to include trace.h - CFLAGS_regmap.o := -I$(src) - --obj-$(CONFIG_REGMAP) += regmap.o regcache.o --obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o --obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o --obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o -+regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o -+ifdef CONFIG_DEBUG_FS -+regmap-core-objs += regmap-debugfs.o -+endif -+ifdef CONFIG_REGCACHE_COMPRESSED -+regmap-core-objs += regcache-lzo.o -+endif -+obj-$(CONFIG_REGMAP) += regmap-core.o - obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o - obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o - obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o ---- a/drivers/base/regmap/regmap.c -+++ b/drivers/base/regmap/regmap.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -3364,3 +3365,5 @@ static int __init regmap_initcall(void) - return 0; - } - postcore_initcall(regmap_initcall); -+ -+MODULE_LICENSE("GPL"); ---- a/include/linux/regmap.h -+++ b/include/linux/regmap.h -@@ -180,7 +180,7 @@ struct reg_sequence { - __ret ?: __tmp; \ - }) - --#ifdef CONFIG_REGMAP -+#if IS_REACHABLE(CONFIG_REGMAP) - - enum regmap_endian { - /* Unspecified -> 0 -> Backwards compatible default */ diff --git a/target/linux/generic/hack-5.15/260-crypto_test_dependencies.patch b/target/linux/generic/hack-5.15/260-crypto_test_dependencies.patch deleted file mode 100644 index 64daa8274390f7..00000000000000 --- a/target/linux/generic/hack-5.15/260-crypto_test_dependencies.patch +++ /dev/null @@ -1,52 +0,0 @@ -From fd1799b0bf5efa46dd3e6dfbbf3955564807e508 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:12:51 +0200 -Subject: kernel: prevent cryptomgr from pulling in useless extra dependencies for tests that are not run - -Reduces kernel size after LZMA by about 5k on MIPS - -lede-commit: 044c316167e076479a344c59905e5b435b84a77f -Signed-off-by: Felix Fietkau ---- - crypto/Kconfig | 13 ++++++------- - crypto/algboss.c | 4 ++++ - 2 files changed, 10 insertions(+), 7 deletions(-) - ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -121,13 +121,13 @@ config CRYPTO_MANAGER - cbc(aes). - - config CRYPTO_MANAGER2 -- def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y) -- select CRYPTO_AEAD2 -- select CRYPTO_HASH2 -- select CRYPTO_SKCIPHER2 -- select CRYPTO_AKCIPHER2 -- select CRYPTO_KPP2 -- select CRYPTO_ACOMP2 -+ def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS) -+ select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_SKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_ACOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS - - config CRYPTO_USER - tristate "Userspace cryptographic algorithm configuration" ---- a/crypto/algboss.c -+++ b/crypto/algboss.c -@@ -211,8 +211,12 @@ static int cryptomgr_schedule_test(struc - type = alg->cra_flags; - - /* Do not test internal algorithms. */ -+#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS -+ type |= CRYPTO_ALG_TESTED; -+#else - if (type & CRYPTO_ALG_INTERNAL) - type |= CRYPTO_ALG_TESTED; -+#endif - - param->type = type; - diff --git a/target/linux/generic/hack-5.15/261-lib-arc4-unhide.patch b/target/linux/generic/hack-5.15/261-lib-arc4-unhide.patch deleted file mode 100644 index ee923c73f759f4..00000000000000 --- a/target/linux/generic/hack-5.15/261-lib-arc4-unhide.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 241e5d3f7b0dd3c01f8c7fa83cbc9a3882286d53 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:35:18 +0200 -Subject: [PATCH] lib/crypto: add tristate string for ARC4 - -This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We -need this to be able to compile this into the kernel and make use of it -from backports. - ---- - lib/crypto/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/lib/crypto/Kconfig -+++ b/lib/crypto/Kconfig -@@ -6,7 +6,7 @@ config CRYPTO_LIB_AES - tristate - - config CRYPTO_LIB_ARC4 -- tristate -+ tristate "ARC4 cipher library" - - config CRYPTO_ARCH_HAVE_LIB_BLAKE2S - bool diff --git a/target/linux/generic/hack-5.15/280-rfkill-stubs.patch b/target/linux/generic/hack-5.15/280-rfkill-stubs.patch deleted file mode 100644 index ff6638f7a05b4c..00000000000000 --- a/target/linux/generic/hack-5.15/280-rfkill-stubs.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 236c1acdfef5958010ac9814a9872e0a46fd78ee Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 7 Jul 2017 17:13:44 +0200 -Subject: rfkill: add fake rfkill support - -allow building of modules depending on RFKILL even if RFKILL is not enabled. - -Signed-off-by: John Crispin ---- - include/linux/rfkill.h | 2 +- - net/Makefile | 2 +- - net/rfkill/Kconfig | 14 +++++++++----- - net/rfkill/Makefile | 2 +- - 4 files changed, 12 insertions(+), 8 deletions(-) - ---- a/include/linux/rfkill.h -+++ b/include/linux/rfkill.h -@@ -64,7 +64,7 @@ struct rfkill_ops { - int (*set_block)(void *data, bool blocked); - }; - --#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) -+#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE) - /** - * rfkill_alloc - Allocate rfkill structure - * @name: name of the struct -- the string is not copied internally ---- a/net/Makefile -+++ b/net/Makefile -@@ -51,7 +51,7 @@ obj-$(CONFIG_TIPC) += tipc/ - obj-$(CONFIG_NETLABEL) += netlabel/ - obj-$(CONFIG_IUCV) += iucv/ - obj-$(CONFIG_SMC) += smc/ --obj-$(CONFIG_RFKILL) += rfkill/ -+obj-$(CONFIG_RFKILL_FULL) += rfkill/ - obj-$(CONFIG_NET_9P) += 9p/ - obj-$(CONFIG_CAIF) += caif/ - obj-$(CONFIG_DCB) += dcb/ ---- a/net/rfkill/Kconfig -+++ b/net/rfkill/Kconfig -@@ -2,7 +2,11 @@ - # - # RF switch subsystem configuration - # --menuconfig RFKILL -+config RFKILL -+ bool -+ default y -+ -+menuconfig RFKILL_FULL - tristate "RF switch subsystem support" - help - Say Y here if you want to have control over RF switches -@@ -14,19 +18,19 @@ menuconfig RFKILL - # LED trigger support - config RFKILL_LEDS - bool -- depends on RFKILL -+ depends on RFKILL_FULL - depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS - default y - - config RFKILL_INPUT - bool "RF switch input support" if EXPERT -- depends on RFKILL -+ depends on RFKILL_FULL - depends on INPUT = y || RFKILL = INPUT - default y if !EXPERT - - config RFKILL_GPIO - tristate "GPIO RFKILL driver" -- depends on RFKILL -+ depends on RFKILL_FULL - depends on GPIOLIB || COMPILE_TEST - default n - help ---- a/net/rfkill/Makefile -+++ b/net/rfkill/Makefile -@@ -5,5 +5,5 @@ - - rfkill-y += core.o - rfkill-$(CONFIG_RFKILL_INPUT) += input.o --obj-$(CONFIG_RFKILL) += rfkill.o -+obj-$(CONFIG_RFKILL_FULL) += rfkill.o - obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o diff --git a/target/linux/generic/hack-5.15/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch b/target/linux/generic/hack-5.15/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch deleted file mode 100644 index f21f200136f00b..00000000000000 --- a/target/linux/generic/hack-5.15/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch +++ /dev/null @@ -1,64 +0,0 @@ -From: Ben Menchaca -Date: Fri, 7 Jun 2013 18:35:22 -0500 -Subject: MIPS: r4k_cache: use more efficient cache blast - -Optimize the compiler output for larger cache blast cases that are -common for DMA-based networking. - -Signed-off-by: Ben Menchaca -Signed-off-by: Felix Fietkau ---- ---- a/arch/mips/include/asm/r4kcache.h -+++ b/arch/mips/include/asm/r4kcache.h -@@ -286,14 +286,46 @@ static inline void prot##extra##blast_## - unsigned long end) \ - { \ - unsigned long lsize = cpu_##desc##_line_size(); \ -+ unsigned long lsize_2 = lsize * 2; \ -+ unsigned long lsize_3 = lsize * 3; \ -+ unsigned long lsize_4 = lsize * 4; \ -+ unsigned long lsize_5 = lsize * 5; \ -+ unsigned long lsize_6 = lsize * 6; \ -+ unsigned long lsize_7 = lsize * 7; \ -+ unsigned long lsize_8 = lsize * 8; \ - unsigned long addr = start & ~(lsize - 1); \ -- unsigned long aend = (end - 1) & ~(lsize - 1); \ -+ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \ -+ int lines = (aend - addr) / lsize; \ - \ -- while (1) { \ -+ while (lines >= 8) { \ -+ prot##cache_op(hitop, addr); \ -+ prot##cache_op(hitop, addr + lsize); \ -+ prot##cache_op(hitop, addr + lsize_2); \ -+ prot##cache_op(hitop, addr + lsize_3); \ -+ prot##cache_op(hitop, addr + lsize_4); \ -+ prot##cache_op(hitop, addr + lsize_5); \ -+ prot##cache_op(hitop, addr + lsize_6); \ -+ prot##cache_op(hitop, addr + lsize_7); \ -+ addr += lsize_8; \ -+ lines -= 8; \ -+ } \ -+ \ -+ if (lines & 0x4) { \ -+ prot##cache_op(hitop, addr); \ -+ prot##cache_op(hitop, addr + lsize); \ -+ prot##cache_op(hitop, addr + lsize_2); \ -+ prot##cache_op(hitop, addr + lsize_3); \ -+ addr += lsize_4; \ -+ } \ -+ \ -+ if (lines & 0x2) { \ -+ prot##cache_op(hitop, addr); \ -+ prot##cache_op(hitop, addr + lsize); \ -+ addr += lsize_2; \ -+ } \ -+ \ -+ if (lines & 0x1) { \ - prot##cache_op(hitop, addr); \ -- if (addr == aend) \ -- break; \ -- addr += lsize; \ - } \ - } - diff --git a/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch b/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch deleted file mode 100644 index 8aac97c47f41ad..00000000000000 --- a/target/linux/generic/hack-5.15/402-mtd-blktrans-call-add-disks-after-mtd-device.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 0bccc3722bdd88e8ae995e77ef9f7b77ee4cbdee Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 7 Apr 2021 22:45:54 +0100 -Subject: [PATCH 2/2] mtd: blktrans: call add disks after mtd device -To: linux-mtd@lists.infradead.org -Cc: Vignesh Raghavendra , - Richard Weinberger , - Miquel Raynal , - David Woodhouse - -Calling device_add_disk while holding mtd_table_mutex leads -to deadlock in case part_bits!=0 as block partition parsers -will try to open the newly created disks, trying to acquire -mutex once again. -Move device_add_disk to additional function called after -add partitions of an MTD device have been added and locks -have been released. - -Signed-off-by: Daniel Golle ---- - drivers/mtd/mtd_blkdevs.c | 33 ++++++++++++++++++++++++++------- - drivers/mtd/mtdcore.c | 3 +++ - include/linux/mtd/blktrans.h | 1 + - 3 files changed, 30 insertions(+), 7 deletions(-) - ---- a/drivers/mtd/mtd_blkdevs.c -+++ b/drivers/mtd/mtd_blkdevs.c -@@ -384,13 +384,6 @@ int add_mtd_blktrans_dev(struct mtd_blkt - if (new->readonly) - set_disk_ro(gd, 1); - -- device_add_disk(&new->mtd->dev, gd, NULL); -- -- if (new->disk_attributes) { -- ret = sysfs_create_group(&disk_to_dev(gd)->kobj, -- new->disk_attributes); -- WARN_ON(ret); -- } - return 0; - - out_free_tag_set: -@@ -402,6 +395,27 @@ out_list_del: - return ret; - } - -+void register_mtd_blktrans_devs(void) -+{ -+ struct mtd_blktrans_ops *tr; -+ struct mtd_blktrans_dev *dev, *next; -+ int ret; -+ -+ list_for_each_entry(tr, &blktrans_majors, list) { -+ list_for_each_entry_safe(dev, next, &tr->devs, list) { -+ if (disk_live(dev->disk)) -+ continue; -+ -+ device_add_disk(&dev->mtd->dev, dev->disk, NULL); -+ if (dev->disk_attributes) { -+ ret = sysfs_create_group(&disk_to_dev(dev->disk)->kobj, -+ dev->disk_attributes); -+ WARN_ON(ret); -+ } -+ } -+ } -+} -+ - int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) - { - unsigned long flags; ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -32,6 +32,7 @@ - - #include - #include -+#include - - #include "mtdcore.h" - -@@ -1108,6 +1109,8 @@ int mtd_device_parse_register(struct mtd - register_reboot_notifier(&mtd->reboot_notifier); - } - -+ register_mtd_blktrans_devs(); -+ - out: - if (ret) { - nvmem_unregister(mtd->otp_user_nvmem); ---- a/include/linux/mtd/blktrans.h -+++ b/include/linux/mtd/blktrans.h -@@ -76,6 +76,7 @@ extern int deregister_mtd_blktrans(struc - extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); - extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); - extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev); -+extern void register_mtd_blktrans_devs(void); - - /** - * module_mtd_blktrans() - Helper macro for registering a mtd blktrans driver diff --git a/target/linux/generic/hack-5.15/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch b/target/linux/generic/hack-5.15/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch deleted file mode 100644 index ed46301b0ee77c..00000000000000 --- a/target/linux/generic/hack-5.15/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 7 Nov 2022 23:48:24 +0100 -Subject: [PATCH] mtd: support OpenWrt's MTD_ROOTFS_ROOT_DEV -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows setting ROOT_DEV to MTD partition named "rootfs". - -Signed-off-by: Rafał Miłecki ---- - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -784,7 +784,8 @@ int add_mtd_device(struct mtd_info *mtd) - - mutex_unlock(&mtd_table_mutex); - -- if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) { -+ if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL) || -+ (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && !strcmp(mtd->name, "rootfs") && ROOT_DEV == 0)) { - if (IS_BUILTIN(CONFIG_MTD)) { - pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name); - ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); diff --git a/target/linux/generic/hack-5.15/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch b/target/linux/generic/hack-5.15/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch deleted file mode 100644 index 965a331a1905bb..00000000000000 --- a/target/linux/generic/hack-5.15/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 6fa9e3678eb002246df1280322b6a024853950a5 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 11 Oct 2021 00:53:14 +0200 -Subject: [PATCH] drivers: mtd: parsers: add nvmem support to cmdlinepart - -Assuming cmdlinepart is only one level deep partition scheme and that -static partition are also defined in DTS, we can assign an of_node for -partition declared from bootargs. cmdlinepart have priority than -fiexed-partition parser so in this specific case the parser doesn't -assign an of_node. Fix this by searching a defined of_node using a -similar fixed_partition parser and if a partition is found with the same -label, check that it has the same offset and size and return the DT -of_node to correctly use NVMEM cells. - -Signed-off-by: Ansuel Smith ---- - drivers/mtd/parsers/cmdlinepart.c | 71 +++++++++++++++++++++++++++++++ - 1 file changed, 71 insertions(+) - ---- a/drivers/mtd/parsers/cmdlinepart.c -+++ b/drivers/mtd/parsers/cmdlinepart.c -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include - - /* debug macro */ - #if 0 -@@ -323,6 +324,68 @@ static int mtdpart_setup_real(char *s) - return 0; - } - -+static int search_fixed_partition(struct mtd_info *master, -+ struct mtd_partition *target_part, -+ struct mtd_partition *fixed_part) -+{ -+ struct device_node *mtd_node; -+ struct device_node *ofpart_node; -+ struct device_node *pp; -+ struct mtd_partition part; -+ const char *partname; -+ -+ mtd_node = mtd_get_of_node(master); -+ if (!mtd_node) -+ return -EINVAL; -+ -+ ofpart_node = of_get_child_by_name(mtd_node, "partitions"); -+ -+ for_each_child_of_node(ofpart_node, pp) { -+ const __be32 *reg; -+ int len; -+ int a_cells, s_cells; -+ -+ reg = of_get_property(pp, "reg", &len); -+ if (!reg) { -+ pr_debug("%s: ofpart partition %pOF (%pOF) missing reg property.\n", -+ master->name, pp, -+ mtd_node); -+ continue; -+ } -+ -+ a_cells = of_n_addr_cells(pp); -+ s_cells = of_n_size_cells(pp); -+ if (len / 4 != a_cells + s_cells) { -+ pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n", -+ master->name, pp, -+ mtd_node); -+ continue; -+ } -+ -+ part.offset = of_read_number(reg, a_cells); -+ part.size = of_read_number(reg + a_cells, s_cells); -+ part.of_node = pp; -+ -+ partname = of_get_property(pp, "label", &len); -+ if (!partname) -+ partname = of_get_property(pp, "name", &len); -+ part.name = partname; -+ -+ if (!strncmp(target_part->name, part.name, len)) { -+ if (part.offset != target_part->offset) -+ return -EINVAL; -+ -+ if (part.size != target_part->size) -+ return -EINVAL; -+ -+ memcpy(fixed_part, &part, sizeof(struct mtd_partition)); -+ return 0; -+ } -+ } -+ -+ return -EINVAL; -+} -+ - /* - * Main function to be called from the MTD mapping driver/device to - * obtain the partitioning information. At this point the command line -@@ -338,6 +401,7 @@ static int parse_cmdline_partitions(stru - int i, err; - struct cmdline_mtd_partition *part; - const char *mtd_id = master->name; -+ struct mtd_partition fixed_part; - - /* parse command line */ - if (!cmdline_parsed) { -@@ -382,6 +446,13 @@ static int parse_cmdline_partitions(stru - sizeof(*part->parts) * (part->num_parts - i)); - i--; - } -+ -+ err = search_fixed_partition(master, &part->parts[i], &fixed_part); -+ if (!err) { -+ part->parts[i].of_node = fixed_part.of_node; -+ pr_info("Found partition defined in DT for %s. Assigning OF node to support nvmem.", -+ part->parts[i].name); -+ } - } - - *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts, diff --git a/target/linux/generic/hack-5.15/430-mtk-bmt-support.patch b/target/linux/generic/hack-5.15/430-mtk-bmt-support.patch deleted file mode 100644 index 2a83f46e0ee8af..00000000000000 --- a/target/linux/generic/hack-5.15/430-mtk-bmt-support.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ac84397efb3b3868c71c10ad7521161773228a17 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:41:44 +0200 -Subject: [PATCH] mtd/nand: add MediaTek NAND bad block managment table - ---- - drivers/mtd/nand/Kconfig | 4 ++++ - drivers/mtd/nand/Makefile | 1 + - 2 files changed, 5 insertions(+) - ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -46,6 +46,10 @@ config MTD_NAND_ECC_SW_BCH - ECC codes. They are used with NAND devices requiring more than 1 bit - of error correction. - -+config MTD_NAND_MTK_BMT -+ bool "Support MediaTek NAND Bad-block Management Table" -+ default n -+ - endmenu - - endmenu ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -2,6 +2,7 @@ - - nandcore-objs := core.o bbt.o - obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o -+obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o - - obj-y += onenand/ - obj-y += raw/ diff --git a/target/linux/generic/hack-5.15/645-netfilter-connmark-introduce-set-dscpmark.patch b/target/linux/generic/hack-5.15/645-netfilter-connmark-introduce-set-dscpmark.patch deleted file mode 100644 index c368c4ae3bfd9e..00000000000000 --- a/target/linux/generic/hack-5.15/645-netfilter-connmark-introduce-set-dscpmark.patch +++ /dev/null @@ -1,214 +0,0 @@ -From eda40b8c8c82e0f2789d6bc8bf63846dce2e8f32 Mon Sep 17 00:00:00 2001 -From: Kevin Darbyshire-Bryant -Date: Sat, 23 Mar 2019 09:29:49 +0000 -Subject: [PATCH] netfilter: connmark: introduce set-dscpmark - -set-dscpmark is a method of storing the DSCP of an ip packet into -conntrack mark. In combination with a suitable tc filter action -(act_ctinfo) DSCP values are able to be stored in the mark on egress and -restored on ingress across links that otherwise alter or bleach DSCP. - -This is useful for qdiscs such as CAKE which are able to shape according -to policies based on DSCP. - -Ingress classification is traditionally a challenging task since -iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT -lookups, hence are unable to see internal IPv4 addresses as used on the -typical home masquerading gateway. - -x_tables CONNMARK set-dscpmark target solves the problem of storing the -DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc -action to restore. - -The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a -32bit 'statemask'. The dscp mask must be 6 contiguous bits and -represents the area where the DSCP will be stored in the connmark. The -state mask is a minimum 1 bit length mask that must not overlap with the -dscpmask. It represents a flag which is set when the DSCP has been -stored in the conntrack mark. This is useful to implement a 'one shot' -iptables based classification where the 'complicated' iptables rules are -only run once to classify the connection on initial (egress) packet and -subsequent packets are all marked/restored with the same DSCP. A state -mask of zero disables the setting of a status bit/s. - -example syntax with a suitably modified iptables user space application: - -iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000 - -Would store the DSCP in the top 6 bits of the 32bit mark field, and use -the LSB of the top byte as the 'DSCP has been stored' marker. - -|----0xFC----conntrack mark----000000---| -| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| -| DSCP | unused | flag |unused | -|-----------------------0x01---000000---| - ^ ^ - | | - ---| Conditional flag - | set this when dscp -|-ip diffserv-| stored in mark -| 6 bits | -|-------------| - -an identically configured tc action to restore looks like: - -tc filter show dev eth0 ingress -filter parent ffff: protocol all pref 10 u32 chain 0 -filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1 -filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw - match 00000000/00000000 at 0 - action order 1: ctinfo zone 0 pipe - index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000 - - action order 2: mirred (Egress Redirect to device ifb4eth0) stolen - index 1 ref 1 bind 1 - -|----0xFC----conntrack mark----000000---| -| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| -| DSCP | unused | flag |unused | -|-----------------------0x01---000000---| - | | - | | - ---| Conditional flag - v only restore if set -|-ip diffserv-| -| 6 bits | -|-------------| - -Signed-off-by: Kevin Darbyshire-Bryant ---- - include/uapi/linux/netfilter/xt_connmark.h | 10 ++++ - net/netfilter/xt_connmark.c | 55 ++++++++++++++++++---- - 2 files changed, 57 insertions(+), 8 deletions(-) - ---- a/include/uapi/linux/netfilter/xt_connmark.h -+++ b/include/uapi/linux/netfilter/xt_connmark.h -@@ -20,6 +20,11 @@ enum { - }; - - enum { -+ XT_CONNMARK_VALUE = (1 << 0), -+ XT_CONNMARK_DSCP = (1 << 1) -+}; -+ -+enum { - D_SHIFT_LEFT = 0, - D_SHIFT_RIGHT, - }; -@@ -34,6 +39,11 @@ struct xt_connmark_tginfo2 { - __u8 shift_dir, shift_bits, mode; - }; - -+struct xt_connmark_tginfo3 { -+ __u32 ctmark, ctmask, nfmask; -+ __u8 shift_dir, shift_bits, mode, func; -+}; -+ - struct xt_connmark_mtinfo1 { - __u32 mark, mask; - __u8 invert; ---- a/net/netfilter/xt_connmark.c -+++ b/net/netfilter/xt_connmark.c -@@ -24,13 +24,13 @@ MODULE_ALIAS("ipt_connmark"); - MODULE_ALIAS("ip6t_connmark"); - - static unsigned int --connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info) -+connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info) - { - enum ip_conntrack_info ctinfo; - u_int32_t new_targetmark; - struct nf_conn *ct; - u_int32_t newmark; -- u_int32_t oldmark; -+ u_int8_t dscp; - - ct = nf_ct_get(skb, &ctinfo); - if (ct == NULL) -@@ -38,13 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, c - - switch (info->mode) { - case XT_CONNMARK_SET: -- oldmark = READ_ONCE(ct->mark); -- newmark = (oldmark & ~info->ctmask) ^ info->ctmark; -- if (info->shift_dir == D_SHIFT_RIGHT) -- newmark >>= info->shift_bits; -- else -- newmark <<= info->shift_bits; -+ newmark = READ_ONCE(ct->mark); -+ if (info->func & XT_CONNMARK_VALUE) { -+ newmark = (newmark & ~info->ctmask) ^ info->ctmark; -+ if (info->shift_dir == D_SHIFT_RIGHT) -+ newmark >>= info->shift_bits; -+ else -+ newmark <<= info->shift_bits; -+ } else if (info->func & XT_CONNMARK_DSCP) { -+ if (skb->protocol == htons(ETH_P_IP)) -+ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2; -+ else if (skb->protocol == htons(ETH_P_IPV6)) -+ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2; -+ else /* protocol doesn't have diffserv */ -+ break; - -+ newmark = (newmark & ~info->ctmark) | -+ (info->ctmask | (dscp << info->shift_bits)); -+ } - if (READ_ONCE(ct->mark) != newmark) { - WRITE_ONCE(ct->mark, newmark); - nf_conntrack_event_cache(IPCT_MARK, ct); -@@ -83,20 +94,36 @@ static unsigned int - connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) - { - const struct xt_connmark_tginfo1 *info = par->targinfo; -- const struct xt_connmark_tginfo2 info2 = { -+ const struct xt_connmark_tginfo3 info3 = { - .ctmark = info->ctmark, - .ctmask = info->ctmask, - .nfmask = info->nfmask, - .mode = info->mode, -+ .func = XT_CONNMARK_VALUE - }; - -- return connmark_tg_shift(skb, &info2); -+ return connmark_tg_shift(skb, &info3); - } - - static unsigned int - connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par) - { - const struct xt_connmark_tginfo2 *info = par->targinfo; -+ const struct xt_connmark_tginfo3 info3 = { -+ .ctmark = info->ctmark, -+ .ctmask = info->ctmask, -+ .nfmask = info->nfmask, -+ .mode = info->mode, -+ .func = XT_CONNMARK_VALUE -+ }; -+ -+ return connmark_tg_shift(skb, &info3); -+} -+ -+static unsigned int -+connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ const struct xt_connmark_tginfo3 *info = par->targinfo; - - return connmark_tg_shift(skb, info); - } -@@ -167,6 +194,16 @@ static struct xt_target connmark_tg_reg[ - .targetsize = sizeof(struct xt_connmark_tginfo2), - .destroy = connmark_tg_destroy, - .me = THIS_MODULE, -+ }, -+ { -+ .name = "CONNMARK", -+ .revision = 3, -+ .family = NFPROTO_UNSPEC, -+ .checkentry = connmark_tg_check, -+ .target = connmark_tg_v3, -+ .targetsize = sizeof(struct xt_connmark_tginfo3), -+ .destroy = connmark_tg_destroy, -+ .me = THIS_MODULE, - } - }; - diff --git a/target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch b/target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch deleted file mode 100644 index d22b9f909bb86c..00000000000000 --- a/target/linux/generic/hack-5.15/650-netfilter-add-xt_FLOWOFFLOAD-target.patch +++ /dev/null @@ -1,865 +0,0 @@ -From: Felix Fietkau -Date: Tue, 20 Feb 2018 15:56:02 +0100 -Subject: [PATCH] netfilter: add xt_FLOWOFFLOAD target - -Signed-off-by: Felix Fietkau ---- - create mode 100644 net/netfilter/xt_OFFLOAD.c - ---- a/net/ipv4/netfilter/Kconfig -+++ b/net/ipv4/netfilter/Kconfig -@@ -56,8 +56,6 @@ config NF_TABLES_ARP - help - This option enables the ARP support for nf_tables. - --endif # NF_TABLES -- - config NF_FLOW_TABLE_IPV4 - tristate "Netfilter flow table IPv4 module" - depends on NF_FLOW_TABLE -@@ -66,6 +64,8 @@ config NF_FLOW_TABLE_IPV4 - - To compile it as a module, choose M here. - -+endif # NF_TABLES -+ - config NF_DUP_IPV4 - tristate "Netfilter IPv4 packet duplication to alternate destination" - depends on !NF_CONNTRACK || NF_CONNTRACK ---- a/net/ipv6/netfilter/Kconfig -+++ b/net/ipv6/netfilter/Kconfig -@@ -45,7 +45,6 @@ config NFT_FIB_IPV6 - multicast or blackhole. - - endif # NF_TABLES_IPV6 --endif # NF_TABLES - - config NF_FLOW_TABLE_IPV6 - tristate "Netfilter flow table IPv6 module" -@@ -55,6 +54,8 @@ config NF_FLOW_TABLE_IPV6 - - To compile it as a module, choose M here. - -+endif # NF_TABLES -+ - config NF_DUP_IPV6 - tristate "Netfilter IPv6 packet duplication to alternate destination" - depends on !NF_CONNTRACK || NF_CONNTRACK ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -707,8 +707,6 @@ config NFT_REJECT_NETDEV - - endif # NF_TABLES_NETDEV - --endif # NF_TABLES -- - config NF_FLOW_TABLE_INET - tristate "Netfilter flow table mixed IPv4/IPv6 module" - depends on NF_FLOW_TABLE -@@ -717,11 +715,12 @@ config NF_FLOW_TABLE_INET - - To compile it as a module, choose M here. - -+endif # NF_TABLES -+ - config NF_FLOW_TABLE - tristate "Netfilter flow table module" - depends on NETFILTER_INGRESS - depends on NF_CONNTRACK -- depends on NF_TABLES - help - This option adds the flow table core infrastructure. - -@@ -1019,6 +1018,15 @@ config NETFILTER_XT_TARGET_NOTRACK - depends on NETFILTER_ADVANCED - select NETFILTER_XT_TARGET_CT - -+config NETFILTER_XT_TARGET_FLOWOFFLOAD -+ tristate '"FLOWOFFLOAD" target support' -+ depends on NF_FLOW_TABLE -+ depends on NETFILTER_INGRESS -+ help -+ This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload -+ module to speed up processing of packets by bypassing the usual -+ netfilter chains -+ - config NETFILTER_XT_TARGET_RATEEST - tristate '"RATEEST" target support' - depends on NETFILTER_ADVANCED ---- a/net/netfilter/Makefile -+++ b/net/netfilter/Makefile -@@ -144,6 +144,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF - obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o - obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o - obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o -+obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o - obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o - obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o - obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o ---- /dev/null -+++ b/net/netfilter/xt_FLOWOFFLOAD.c -@@ -0,0 +1,702 @@ -+/* -+ * Copyright (C) 2018-2021 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct xt_flowoffload_hook { -+ struct hlist_node list; -+ struct nf_hook_ops ops; -+ struct net *net; -+ bool registered; -+ bool used; -+}; -+ -+struct xt_flowoffload_table { -+ struct nf_flowtable ft; -+ struct hlist_head hooks; -+ 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); -+ -+struct xt_flowoffload_table flowtable[2]; -+ -+static unsigned int -+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ struct vlan_ethhdr *veth; -+ __be16 proto; -+ -+ 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): -+ if (!nf_flow_pppoe_proto(skb, &proto)) -+ return NF_ACCEPT; -+ break; -+ default: -+ proto = skb->protocol; -+ break; -+ } -+ -+ switch (proto) { -+ 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 -+xt_flowoffload_create_hook(struct xt_flowoffload_table *table, -+ struct net_device *dev) -+{ -+ struct xt_flowoffload_hook *hook; -+ struct nf_hook_ops *ops; -+ -+ hook = kzalloc(sizeof(*hook), GFP_ATOMIC); -+ if (!hook) -+ return -ENOMEM; -+ -+ ops = &hook->ops; -+ ops->pf = NFPROTO_NETDEV; -+ ops->hooknum = NF_NETDEV_INGRESS; -+ ops->priority = 10; -+ ops->priv = &table->ft; -+ ops->hook = xt_flowoffload_net_hook; -+ ops->dev = dev; -+ -+ hlist_add_head(&hook->list, &table->hooks); -+ mod_delayed_work(system_power_efficient_wq, &table->work, 0); -+ -+ return 0; -+} -+ -+static struct xt_flowoffload_hook * -+flow_offload_lookup_hook(struct xt_flowoffload_table *table, -+ struct net_device *dev) -+{ -+ struct xt_flowoffload_hook *hook; -+ -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->ops.dev == dev) -+ return hook; -+ } -+ -+ return NULL; -+} -+ -+static void -+xt_flowoffload_check_device(struct xt_flowoffload_table *table, -+ struct net_device *dev) -+{ -+ struct xt_flowoffload_hook *hook; -+ -+ if (!dev) -+ return; -+ -+ spin_lock_bh(&hooks_lock); -+ hook = flow_offload_lookup_hook(table, dev); -+ if (hook) -+ hook->used = true; -+ else -+ xt_flowoffload_create_hook(table, dev); -+ spin_unlock_bh(&hooks_lock); -+} -+ -+static void -+xt_flowoffload_register_hooks(struct xt_flowoffload_table *table) -+{ -+ struct xt_flowoffload_hook *hook; -+ -+restart: -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->registered) -+ continue; -+ -+ hook->registered = true; -+ hook->net = dev_net(hook->ops.dev); -+ spin_unlock_bh(&hooks_lock); -+ nf_register_net_hook(hook->net, &hook->ops); -+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD) -+ table->ft.type->setup(&table->ft, hook->ops.dev, -+ FLOW_BLOCK_BIND); -+ spin_lock_bh(&hooks_lock); -+ goto restart; -+ } -+ -+} -+ -+static bool -+xt_flowoffload_cleanup_hooks(struct xt_flowoffload_table *table) -+{ -+ struct xt_flowoffload_hook *hook; -+ bool active = false; -+ -+restart: -+ spin_lock_bh(&hooks_lock); -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->used || !hook->registered) { -+ active = true; -+ continue; -+ } -+ -+ hlist_del(&hook->list); -+ spin_unlock_bh(&hooks_lock); -+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD) -+ table->ft.type->setup(&table->ft, hook->ops.dev, -+ FLOW_BLOCK_UNBIND); -+ nf_unregister_net_hook(hook->net, &hook->ops); -+ kfree(hook); -+ goto restart; -+ } -+ spin_unlock_bh(&hooks_lock); -+ -+ return active; -+} -+ -+static void -+xt_flowoffload_check_hook(struct nf_flowtable *flowtable, -+ struct flow_offload *flow, void *data) -+{ -+ struct xt_flowoffload_table *table; -+ struct flow_offload_tuple *tuple0 = &flow->tuplehash[0].tuple; -+ struct flow_offload_tuple *tuple1 = &flow->tuplehash[1].tuple; -+ struct xt_flowoffload_hook *hook; -+ -+ table = container_of(flowtable, struct xt_flowoffload_table, ft); -+ -+ spin_lock_bh(&hooks_lock); -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->ops.dev->ifindex != tuple0->iifidx && -+ hook->ops.dev->ifindex != tuple1->iifidx) -+ continue; -+ -+ hook->used = true; -+ } -+ spin_unlock_bh(&hooks_lock); -+} -+ -+static void -+xt_flowoffload_hook_work(struct work_struct *work) -+{ -+ struct xt_flowoffload_table *table; -+ struct xt_flowoffload_hook *hook; -+ int err; -+ -+ table = container_of(work, struct xt_flowoffload_table, work.work); -+ -+ spin_lock_bh(&hooks_lock); -+ xt_flowoffload_register_hooks(table); -+ hlist_for_each_entry(hook, &table->hooks, list) -+ hook->used = false; -+ spin_unlock_bh(&hooks_lock); -+ -+ err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook, -+ NULL); -+ if (err && err != -EAGAIN) -+ goto out; -+ -+ if (!xt_flowoffload_cleanup_hooks(table)) -+ return; -+ -+out: -+ queue_delayed_work(system_power_efficient_wq, &table->work, HZ); -+} -+ -+static bool -+xt_flowoffload_skip(struct sk_buff *skb, int family) -+{ -+ if (skb_sec_path(skb)) -+ return true; -+ -+ if (family == NFPROTO_IPV4) { -+ const struct ip_options *opt = &(IPCB(skb)->opt); -+ -+ if (unlikely(opt->optlen)) -+ return true; -+ } -+ -+ return false; -+} -+ -+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 || -+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr)) -+ return false; -+ -+ return true; -+} -+ -+static void nf_dev_path_info(const struct net_device_path_stack *stack, -+ struct nf_forward_info *info, -+ unsigned char *ha) -+{ -+ const struct net_device_path *path; -+ int i; -+ -+ memcpy(info->h_dest, ha, ETH_ALEN); -+ -+ for (i = 0; i < stack->num_paths; i++) { -+ path = &stack->path[i]; -+ switch (path->type) { -+ case DEV_PATH_ETHERNET: -+ case DEV_PATH_DSA: -+ case DEV_PATH_VLAN: -+ case DEV_PATH_PPPOE: -+ info->indev = path->dev; -+ 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; -+ } -+ -+ /* DEV_PATH_VLAN and DEV_PATH_PPPOE */ -+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) { -+ 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) -+ memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN); -+ break; -+ case DEV_PATH_BRIDGE: -+ if (is_zero_ether_addr(info->h_source)) -+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN); -+ -+ switch (path->bridge.vlan_mode) { -+ case DEV_PATH_BR_VLAN_UNTAG_HW: -+ info->ingress_vlans |= BIT(info->num_encaps - 1); -+ break; -+ 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; -+ case DEV_PATH_BR_VLAN_UNTAG: -+ info->num_encaps--; -+ break; -+ case DEV_PATH_BR_VLAN_KEEP: -+ break; -+ } -+ break; -+ default: -+ info->indev = NULL; -+ break; -+ } -+ } -+ if (!info->outdev) -+ info->outdev = info->indev; -+ -+ info->hw_outdev = info->indev; -+ -+ if (nf_is_valid_ether_device(info->indev)) -+ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT; -+} -+ -+static int nf_dev_fill_forward_path(const struct nf_flow_route *route, -+ const struct dst_entry *dst_cache, -+ const struct nf_conn *ct, -+ enum ip_conntrack_dir dir, u8 *ha, -+ struct net_device_path_stack *stack) -+{ -+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; -+ struct net_device *dev = dst_cache->dev; -+ struct neighbour *n; -+ u8 nud_state; -+ -+ if (!nf_is_valid_ether_device(dev)) -+ goto out; -+ -+ n = dst_neigh_lookup(dst_cache, daddr); -+ if (!n) -+ return -1; -+ -+ read_lock_bh(&n->lock); -+ nud_state = n->nud_state; -+ ether_addr_copy(ha, n->ha); -+ read_unlock_bh(&n->lock); -+ neigh_release(n); -+ -+ if (!(nud_state & NUD_VALID)) -+ return -1; -+ -+out: -+ return dev_fill_forward_path(dev, ha, stack); -+} -+ -+static void nf_dev_forward_path(struct nf_flow_route *route, -+ const struct nf_conn *ct, -+ 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; -+ -+ if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0) -+ nf_dev_path_info(&stack, &info, ha); -+ -+ 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 -+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct, -+ const struct xt_action_param *par, -+ struct nf_flow_route *route, enum ip_conntrack_dir dir, -+ struct net_device **devs) -+{ -+ struct dst_entry *this_dst = skb_dst(skb); -+ struct dst_entry *other_dst = NULL; -+ struct flowi fl; -+ -+ memset(&fl, 0, sizeof(fl)); -+ switch (xt_family(par)) { -+ case NFPROTO_IPV4: -+ 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; -+ } -+ -+ if (!dst_hold_safe(this_dst)) -+ return -ENOENT; -+ -+ nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par)); -+ if (!other_dst) { -+ dst_release(this_dst); -+ return -ENOENT; -+ } -+ -+ nf_default_forward_path(route, this_dst, dir, devs); -+ 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; -+} -+ -+static unsigned int -+flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ struct xt_flowoffload_table *table; -+ const struct xt_flowoffload_target_info *info = par->targinfo; -+ struct tcphdr _tcph, *tcph = NULL; -+ enum ip_conntrack_info ctinfo; -+ enum ip_conntrack_dir dir; -+ struct nf_flow_route route = {}; -+ struct flow_offload *flow = NULL; -+ struct net_device *devs[2] = {}; -+ struct nf_conn *ct; -+ struct net *net; -+ -+ if (xt_flowoffload_skip(skb, xt_family(par))) -+ return XT_CONTINUE; -+ -+ ct = nf_ct_get(skb, &ctinfo); -+ if (ct == NULL) -+ return XT_CONTINUE; -+ -+ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { -+ case IPPROTO_TCP: -+ if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) -+ return XT_CONTINUE; -+ -+ tcph = skb_header_pointer(skb, par->thoff, -+ sizeof(_tcph), &_tcph); -+ if (unlikely(!tcph || tcph->fin || tcph->rst)) -+ return XT_CONTINUE; -+ break; -+ case IPPROTO_UDP: -+ break; -+ default: -+ return XT_CONTINUE; -+ } -+ -+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) || -+ ct->status & (IPS_SEQ_ADJUST | IPS_NAT_CLASH)) -+ return XT_CONTINUE; -+ -+ if (!nf_ct_is_confirmed(ct)) -+ return XT_CONTINUE; -+ -+ dir = CTINFO2DIR(ctinfo); -+ -+ devs[dir] = xt_out(par); -+ devs[!dir] = xt_in(par); -+ -+ if (!devs[dir] || !devs[!dir]) -+ return XT_CONTINUE; -+ -+ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status)) -+ return XT_CONTINUE; -+ -+ if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0) -+ goto err_flow_route; -+ -+ flow = flow_offload_alloc(ct); -+ if (!flow) -+ goto err_flow_alloc; -+ -+ flow_offload_route_init(flow, &route); -+ -+ if (tcph) { -+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; -+ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; -+ } -+ -+ table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)]; -+ -+ net = read_pnet(&table->ft.net); -+ if (!net) -+ write_pnet(&table->ft.net, xt_net(par)); -+ -+ if (flow_offload_add(&table->ft, flow) < 0) -+ goto err_flow_add; -+ -+ xt_flowoffload_check_device(table, devs[0]); -+ xt_flowoffload_check_device(table, devs[1]); -+ -+ return XT_CONTINUE; -+ -+err_flow_add: -+ flow_offload_free(flow); -+err_flow_alloc: -+ dst_release(route.tuple[dir].dst); -+ dst_release(route.tuple[!dir].dst); -+err_flow_route: -+ clear_bit(IPS_OFFLOAD_BIT, &ct->status); -+ -+ return XT_CONTINUE; -+} -+ -+static int flowoffload_chk(const struct xt_tgchk_param *par) -+{ -+ struct xt_flowoffload_target_info *info = par->targinfo; -+ -+ if (info->flags & ~XT_FLOWOFFLOAD_MASK) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static struct xt_target offload_tg_reg __read_mostly = { -+ .family = NFPROTO_UNSPEC, -+ .name = "FLOWOFFLOAD", -+ .revision = 0, -+ .targetsize = sizeof(struct xt_flowoffload_target_info), -+ .usersize = sizeof(struct xt_flowoffload_target_info), -+ .checkentry = flowoffload_chk, -+ .target = flowoffload_tg, -+ .me = THIS_MODULE, -+}; -+ -+static int flow_offload_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ struct xt_flowoffload_hook *hook0, *hook1; -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ -+ if (event != NETDEV_UNREGISTER) -+ return NOTIFY_DONE; -+ -+ spin_lock_bh(&hooks_lock); -+ hook0 = flow_offload_lookup_hook(&flowtable[0], dev); -+ if (hook0) -+ hlist_del(&hook0->list); -+ -+ hook1 = flow_offload_lookup_hook(&flowtable[1], dev); -+ if (hook1) -+ hlist_del(&hook1->list); -+ spin_unlock_bh(&hooks_lock); -+ -+ if (hook0) { -+ nf_unregister_net_hook(hook0->net, &hook0->ops); -+ kfree(hook0); -+ } -+ -+ if (hook1) { -+ nf_unregister_net_hook(hook1->net, &hook1->ops); -+ kfree(hook1); -+ } -+ -+ nf_flow_table_cleanup(dev); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block flow_offload_netdev_notifier = { -+ .notifier_call = flow_offload_netdev_event, -+}; -+ -+static int nf_flow_rule_route_inet(struct net *net, -+ const struct flow_offload *flow, -+ enum flow_offload_tuple_dir dir, -+ struct nf_flow_rule *flow_rule) -+{ -+ const struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; -+ int err; -+ -+ switch (flow_tuple->l3proto) { -+ case NFPROTO_IPV4: -+ err = nf_flow_rule_route_ipv4(net, flow, dir, flow_rule); -+ break; -+ case NFPROTO_IPV6: -+ err = nf_flow_rule_route_ipv6(net, flow, dir, flow_rule); -+ break; -+ default: -+ err = -1; -+ break; -+ } -+ -+ return err; -+} -+ -+static struct nf_flowtable_type flowtable_inet = { -+ .family = NFPROTO_INET, -+ .init = nf_flow_table_init, -+ .setup = nf_flow_table_offload_setup, -+ .action = nf_flow_rule_route_inet, -+ .free = nf_flow_table_free, -+ .hook = xt_flowoffload_net_hook, -+ .owner = THIS_MODULE, -+}; -+ -+static int init_flowtable(struct xt_flowoffload_table *tbl) -+{ -+ INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work); -+ tbl->ft.type = &flowtable_inet; -+ tbl->ft.flags = NF_FLOWTABLE_COUNTER; -+ -+ return nf_flow_table_init(&tbl->ft); -+} -+ -+static int __init xt_flowoffload_tg_init(void) -+{ -+ int ret; -+ -+ register_netdevice_notifier(&flow_offload_netdev_notifier); -+ -+ ret = init_flowtable(&flowtable[0]); -+ if (ret) -+ return ret; -+ -+ ret = init_flowtable(&flowtable[1]); -+ if (ret) -+ goto cleanup; -+ -+ flowtable[1].ft.flags |= NF_FLOWTABLE_HW_OFFLOAD; -+ -+ ret = xt_register_target(&offload_tg_reg); -+ if (ret) -+ goto cleanup2; -+ -+ return 0; -+ -+cleanup2: -+ nf_flow_table_free(&flowtable[1].ft); -+cleanup: -+ nf_flow_table_free(&flowtable[0].ft); -+ return ret; -+} -+ -+static void __exit xt_flowoffload_tg_exit(void) -+{ -+ xt_unregister_target(&offload_tg_reg); -+ unregister_netdevice_notifier(&flow_offload_netdev_notifier); -+ nf_flow_table_free(&flowtable[0].ft); -+ nf_flow_table_free(&flowtable[1].ft); -+} -+ -+MODULE_LICENSE("GPL"); -+module_init(xt_flowoffload_tg_init); -+module_exit(xt_flowoffload_tg_exit); ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -7,7 +7,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -373,8 +372,7 @@ flow_offload_lookup(struct nf_flowtable - } - EXPORT_SYMBOL_GPL(flow_offload_lookup); - --static int --nf_flow_table_iterate(struct nf_flowtable *flow_table, -+int nf_flow_table_iterate(struct nf_flowtable *flow_table, - void (*iter)(struct nf_flowtable *flowtable, - struct flow_offload *flow, void *data), - void *data) -@@ -428,6 +426,7 @@ static void nf_flow_offload_gc_step(stru - nf_flow_offload_stats(flow_table, flow); - } - } -+EXPORT_SYMBOL_GPL(nf_flow_table_iterate); - - void nf_flow_table_gc_run(struct nf_flowtable *flow_table) - { ---- /dev/null -+++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h -@@ -0,0 +1,17 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#ifndef _XT_FLOWOFFLOAD_H -+#define _XT_FLOWOFFLOAD_H -+ -+#include -+ -+enum { -+ XT_FLOWOFFLOAD_HW = 1 << 0, -+ -+ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW -+}; -+ -+struct xt_flowoffload_target_info { -+ __u32 flags; -+}; -+ -+#endif /* _XT_FLOWOFFLOAD_H */ ---- a/include/net/netfilter/nf_flow_table.h -+++ b/include/net/netfilter/nf_flow_table.h -@@ -276,6 +276,11 @@ void nf_flow_table_free(struct nf_flowta - - void flow_offload_teardown(struct flow_offload *flow); - -+int nf_flow_table_iterate(struct nf_flowtable *flow_table, -+ void (*iter)(struct nf_flowtable *flowtable, -+ struct flow_offload *flow, void *data), -+ void *data); -+ - void nf_flow_snat_port(const struct flow_offload *flow, - struct sk_buff *skb, unsigned int thoff, - u8 protocol, enum flow_offload_tuple_dir dir); diff --git a/target/linux/generic/hack-5.15/651-wireless_mesh_header.patch b/target/linux/generic/hack-5.15/651-wireless_mesh_header.patch deleted file mode 100644 index 12a031ec84d1ce..00000000000000 --- a/target/linux/generic/hack-5.15/651-wireless_mesh_header.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 6d3bc769657b0ee7c7506dad9911111c4226a7ea Mon Sep 17 00:00:00 2001 -From: Imre Kaloz -Date: Fri, 7 Jul 2017 17:21:05 +0200 -Subject: mac80211: increase wireless mesh header size - -lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1 -Signed-off-by: Imre Kaloz ---- - include/linux/netdevice.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -145,8 +145,8 @@ static inline bool dev_xmit_complete(int - - #if defined(CONFIG_HYPERV_NET) - # define LL_MAX_HEADER 128 --#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) --# if defined(CONFIG_MAC80211_MESH) -+#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1 -+# if defined(CONFIG_MAC80211_MESH) || 1 - # define LL_MAX_HEADER 128 - # else - # define LL_MAX_HEADER 96 diff --git a/target/linux/generic/hack-5.15/660-fq_codel_defaults.patch b/target/linux/generic/hack-5.15/660-fq_codel_defaults.patch deleted file mode 100644 index a57a045f4a8382..00000000000000 --- a/target/linux/generic/hack-5.15/660-fq_codel_defaults.patch +++ /dev/null @@ -1,27 +0,0 @@ -From a6ccb238939b25851474a279b20367fd24a0e816 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:21:53 +0200 -Subject: hack: net: fq_codel: tune defaults for small devices - -Assume that x86_64 devices always have a big memory and do not need this -optimization compared to devices with only 32 MB or 64 MB RAM. - -Signed-off-by: Felix Fietkau ---- - net/sched/sch_fq_codel.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/net/sched/sch_fq_codel.c -+++ b/net/sched/sch_fq_codel.c -@@ -467,7 +467,11 @@ static int fq_codel_init(struct Qdisc *s - - sch->limit = 10*1024; - q->flows_cnt = 1024; -+#ifdef CONFIG_X86_64 - q->memory_limit = 32 << 20; /* 32 MBytes */ -+#else -+ q->memory_limit = 4 << 20; /* 4 MBytes */ -+#endif - q->drop_batch_size = 64; - q->quantum = psched_mtu(qdisc_dev(sch)); - INIT_LIST_HEAD(&q->new_flows); diff --git a/target/linux/generic/hack-5.15/661-kernel-ct-size-the-hashtable-more-adequately.patch b/target/linux/generic/hack-5.15/661-kernel-ct-size-the-hashtable-more-adequately.patch deleted file mode 100644 index 89074d0a04b26d..00000000000000 --- a/target/linux/generic/hack-5.15/661-kernel-ct-size-the-hashtable-more-adequately.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 804fbb3f2ec9283f7b778e057a68bfff440a0be6 Mon Sep 17 00:00:00 2001 -From: Rui Salvaterra -Date: Wed, 30 Mar 2022 22:51:55 +0100 -Subject: [PATCH] kernel: ct: size the hashtable more adequately - -To set the default size of the connection tracking hash table, a divider of -16384 becomes inadequate for a router handling lots of connections. Divide by -2048 instead, making the default size scale better with the available RAM. - -Signed-off-by: Rui Salvaterra ---- - net/netfilter/nf_conntrack_core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -2737,7 +2737,7 @@ int nf_conntrack_init_start(void) - - if (!nf_conntrack_htable_size) { - nf_conntrack_htable_size -- = (((nr_pages << PAGE_SHIFT) / 16384) -+ = (((nr_pages << PAGE_SHIFT) / 2048) - / sizeof(struct hlist_head)); - if (BITS_PER_LONG >= 64 && - nr_pages > (4 * (1024 * 1024 * 1024 / PAGE_SIZE))) diff --git a/target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch deleted file mode 100644 index 9d77efaca6ef99..00000000000000 --- a/target/linux/generic/hack-5.15/700-swconfig_switch_drivers.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 36e516290611e613aa92996cb4339561452695b4 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:24:23 +0200 -Subject: net: swconfig: adds openwrt switch layer - -Signed-off-by: Felix Fietkau ---- - drivers/net/phy/Kconfig | 83 +++++++++++++++++++++++++++++++++++++++++++++++ - drivers/net/phy/Makefile | 15 +++++++++ - include/uapi/linux/Kbuild | 1 + - 3 files changed, 99 insertions(+) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -62,6 +62,80 @@ config SFP - depends on HWMON || HWMON=n - select MDIO_I2C - -+comment "Switch configuration API + drivers" -+ -+config SWCONFIG -+ tristate "Switch configuration API" -+ help -+ Switch configuration API using netlink. This allows -+ you to configure the VLAN features of certain switches. -+ -+config SWCONFIG_LEDS -+ bool "Switch LED trigger support" -+ depends on (SWCONFIG && LEDS_TRIGGERS) -+ -+config ADM6996_PHY -+ tristate "Driver for ADM6996 switches" -+ select SWCONFIG -+ help -+ Currently supports the ADM6996FC and ADM6996M switches. -+ Support for FC is very limited. -+ -+config AR8216_PHY -+ tristate "Driver for Atheros AR8216/8327 switches" -+ select SWCONFIG -+ select ETHERNET_PACKET_MANGLE -+ -+config AR8216_PHY_LEDS -+ bool "Atheros AR8216 switch LED support" -+ depends on (AR8216_PHY && LEDS_CLASS) -+ -+source "drivers/net/phy/b53/Kconfig" -+ -+config IP17XX_PHY -+ tristate "Driver for IC+ IP17xx switches" -+ select SWCONFIG -+ -+config PSB6970_PHY -+ tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch" -+ select SWCONFIG -+ -+config RTL8306_PHY -+ tristate "Driver for Realtek RTL8306S switches" -+ select SWCONFIG -+ -+config RTL8366_SMI -+ tristate "Driver for the RTL8366 SMI interface" -+ depends on GPIOLIB -+ help -+ This module implements the SMI interface protocol which is used -+ by some RTL8366 ethernet switch devices via the generic GPIO API. -+ -+if RTL8366_SMI -+ -+config RTL8366_SMI_DEBUG_FS -+ bool "RTL8366 SMI interface debugfs support" -+ depends on DEBUG_FS -+ default n -+ -+config RTL8366S_PHY -+ tristate "Driver for the Realtek RTL8366S switch" -+ select SWCONFIG -+ -+config RTL8366RB_PHY -+ tristate "Driver for the Realtek RTL8366RB switch" -+ select SWCONFIG -+ -+config RTL8367_PHY -+ tristate "Driver for the Realtek RTL8367R/M switches" -+ select SWCONFIG -+ -+config RTL8367B_PHY -+ tristate "Driver fot the Realtek RTL8367R-VB switch" -+ select SWCONFIG -+ -+endif # RTL8366_SMI -+ - comment "MII PHY device drivers" - - config AMD_PHY ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -24,6 +24,21 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_ - obj-$(CONFIG_PHYLINK) += phylink.o - obj-$(CONFIG_PHYLIB) += libphy.o - -+obj-$(CONFIG_SWCONFIG) += swconfig.o -+obj-$(CONFIG_ADM6996_PHY) += adm6996.o -+obj-$(CONFIG_AR8216_PHY) += ar8xxx.o -+ar8xxx-y += ar8216.o -+ar8xxx-y += ar8327.o -+obj-$(CONFIG_SWCONFIG_B53) += b53/ -+obj-$(CONFIG_IP17XX_PHY) += ip17xx.o -+obj-$(CONFIG_PSB6970_PHY) += psb6970.o -+obj-$(CONFIG_RTL8306_PHY) += rtl8306.o -+obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o -+obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o -+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o -+obj-$(CONFIG_RTL8367_PHY) += rtl8367.o -+obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o -+ - obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o - - obj-$(CONFIG_SFP) += sfp.o ---- a/include/linux/platform_data/b53.h -+++ b/include/linux/platform_data/b53.h -@@ -29,6 +29,9 @@ struct b53_platform_data { - u32 chip_id; - u16 enabled_ports; - -+ /* allow to specify an ethX alias */ -+ const char *alias; -+ - /* only used by MMAP'd driver */ - unsigned big_endian:1; - void __iomem *regs; diff --git a/target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch b/target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch deleted file mode 100644 index 526cfdb4938047..00000000000000 --- a/target/linux/generic/hack-5.15/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch +++ /dev/null @@ -1,21 +0,0 @@ -From ebd924d773223593142d417c41d4ee6fa16f1805 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:45:56 +0200 -Subject: [PATCH] net/dsa/mv88e6xxx: disable ATU violation - ---- - drivers/net/dsa/mv88e6xxx/chip.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -3027,6 +3027,9 @@ static int mv88e6xxx_setup_port(struct m - else - reg = 1 << port; - -+ /* Disable ATU member violation interrupt */ -+ reg |= MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG; -+ - err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, - reg); - if (err) diff --git a/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch deleted file mode 100644 index 70a0a1ef6080c8..00000000000000 --- a/target/linux/generic/hack-5.15/721-net-add-packet-mangeling.patch +++ /dev/null @@ -1,178 +0,0 @@ -From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:25:00 +0200 -Subject: net: add packet mangeling - -ar8216 switches have a hardware bug, which renders normal 802.1q support -unusable. Packet mangling is required to fix up the vlan for incoming -packets. - -Signed-off-by: Felix Fietkau ---- - include/linux/netdevice.h | 11 +++++++++++ - include/linux/skbuff.h | 14 ++++---------- - net/Kconfig | 6 ++++++ - net/core/dev.c | 20 +++++++++++++++----- - net/core/skbuff.c | 17 +++++++++++++++++ - net/ethernet/eth.c | 6 ++++++ - 6 files changed, 59 insertions(+), 15 deletions(-) - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1682,6 +1682,10 @@ enum netdev_priv_flags { - IFF_TX_SKB_NO_LINEAR = BIT_ULL(31), - }; - -+enum netdev_extra_priv_flags { -+ IFF_NO_IP_ALIGN = 1<<0, -+}; -+ - #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN - #define IFF_EBRIDGE IFF_EBRIDGE - #define IFF_BONDING IFF_BONDING -@@ -1713,6 +1717,7 @@ enum netdev_priv_flags { - #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE - #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER - #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR -+#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN - - /* Specifies the type of the struct net_device::ml_priv pointer */ - enum netdev_ml_priv_type { -@@ -2013,6 +2018,7 @@ struct net_device { - /* Read-mostly cache-line for fast-path access */ - unsigned int flags; - unsigned int priv_flags; -+ unsigned int extra_priv_flags; - const struct net_device_ops *netdev_ops; - int ifindex; - unsigned short gflags; -@@ -2073,6 +2079,11 @@ struct net_device { - const struct tlsdev_ops *tlsdev_ops; - #endif - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb); -+ struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb); -+#endif -+ - const struct header_ops *header_ops; - - unsigned char operstate; -@@ -2144,6 +2155,10 @@ struct net_device { - struct mctp_dev __rcu *mctp_ptr; - #endif - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ void *phy_ptr; /* PHY device specific data */ -+#endif -+ - /* - * Cache lines mostly used on receive path (including eth_type_trans()) - */ ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -2870,6 +2870,10 @@ static inline int pskb_trim(struct sk_bu - return (len < skb->len) ? __pskb_trim(skb, len) : 0; - } - -+extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -+ unsigned int length, gfp_t gfp); -+ -+ - /** - * pskb_trim_unique - remove end from a paged unique (not cloned) buffer - * @skb: buffer to alter -@@ -3020,16 +3024,6 @@ static inline struct sk_buff *dev_alloc_ - } - - --static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -- unsigned int length, gfp_t gfp) --{ -- struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); -- -- if (NET_IP_ALIGN && skb) -- skb_reserve(skb, NET_IP_ALIGN); -- return skb; --} -- - static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, - unsigned int length) - { ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -26,6 +26,12 @@ menuconfig NET - - if NET - -+config ETHERNET_PACKET_MANGLE -+ bool -+ help -+ This option can be selected by phy drivers that need to mangle -+ packets going in or out of an ethernet device. -+ - config WANT_COMPAT_NETLINK_MESSAGES - bool - help ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -3600,6 +3600,11 @@ static int xmit_one(struct sk_buff *skb, - if (dev_nit_active(dev)) - dev_queue_xmit_nit(skb, dev); - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb))) -+ return NETDEV_TX_OK; -+#endif -+ - len = skb->len; - PRANDOM_ADD_NOISE(skb, dev, txq, len + jiffies); - trace_net_dev_start_xmit(skb, dev); ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -61,6 +61,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -602,6 +603,22 @@ skb_fail: - } - EXPORT_SYMBOL(__napi_alloc_skb); - -+struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -+ unsigned int length, gfp_t gfp) -+{ -+ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev && (dev->extra_priv_flags & IFF_NO_IP_ALIGN)) -+ return skb; -+#endif -+ -+ if (NET_IP_ALIGN && skb) -+ skb_reserve(skb, NET_IP_ALIGN); -+ return skb; -+} -+EXPORT_SYMBOL(__netdev_alloc_skb_ip_align); -+ - void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, - int size, unsigned int truesize) - { ---- a/net/ethernet/eth.c -+++ b/net/ethernet/eth.c -@@ -170,6 +170,12 @@ __be16 eth_type_trans(struct sk_buff *sk - const struct ethhdr *eth; - - skb->dev = dev; -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev->eth_mangle_rx) -+ dev->eth_mangle_rx(dev, skb); -+#endif -+ - skb_reset_mac_header(skb); - - eth = (struct ethhdr *)skb->data; diff --git a/target/linux/generic/hack-5.15/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch b/target/linux/generic/hack-5.15/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch deleted file mode 100644 index d003291f755aea..00000000000000 --- a/target/linux/generic/hack-5.15/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 5f62951fba63a9f9cfff564209426bdea5fcc371 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 27 Aug 2019 15:16:56 +0300 -Subject: [PATCH] drivers: net: phy: aquantia: enable AQR112 and AQR412 - -Adds support for AQR112 and AQR412 which is mostly based on existing code -with the addition of code configuring the protocol on system side. -This allows changing the system side protocol without having to deploy a -different firmware on the PHY. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/aquantia/aquantia_main.c | 88 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 88 insertions(+) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -27,6 +27,8 @@ - #define PHY_ID_AQR113 0x31c31c40 - #define PHY_ID_AQR113C 0x31c31c12 - #define PHY_ID_AQR813 0x31c31cb2 -+#define PHY_ID_AQR112 0x03a1b662 -+#define PHY_ID_AQR412 0x03a1b712 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -@@ -99,6 +101,29 @@ - #define AQR107_OP_IN_PROG_SLEEP 1000 - #define AQR107_OP_IN_PROG_TIMEOUT 100000 - -+/* registers in MDIO_MMD_VEND1 region */ -+#define AQUANTIA_VND1_GLOBAL_SC 0x000 -+#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb) -+ -+/* global start rate, the protocol associated with this speed is used by default -+ * on SI. -+ */ -+#define AQUANTIA_VND1_GSTART_RATE 0x31a -+#define AQUANTIA_VND1_GSTART_RATE_OFF 0 -+#define AQUANTIA_VND1_GSTART_RATE_100M 1 -+#define AQUANTIA_VND1_GSTART_RATE_1G 2 -+#define AQUANTIA_VND1_GSTART_RATE_10G 3 -+#define AQUANTIA_VND1_GSTART_RATE_2_5G 4 -+#define AQUANTIA_VND1_GSTART_RATE_5G 5 -+ -+/* SYSCFG registers for 100M, 1G, 2.5G, 5G, 10G */ -+#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b -+#define AQUANTIA_VND1_GSYSCFG_100M 0 -+#define AQUANTIA_VND1_GSYSCFG_1G 1 -+#define AQUANTIA_VND1_GSYSCFG_2_5G 2 -+#define AQUANTIA_VND1_GSYSCFG_5G 3 -+#define AQUANTIA_VND1_GSYSCFG_10G 4 -+ - struct aqr107_hw_stat { - const char *name; - int reg; -@@ -230,6 +255,51 @@ static int aqr_config_aneg(struct phy_de - return genphy_c45_check_and_restart_aneg(phydev, changed); - } - -+static struct { -+ u16 syscfg; -+ int cnt; -+ u16 start_rate; -+} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = { -+ [PHY_INTERFACE_MODE_SGMII] = {0x04b, AQUANTIA_VND1_GSYSCFG_1G, -+ AQUANTIA_VND1_GSTART_RATE_1G}, -+ [PHY_INTERFACE_MODE_2500BASEX] = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G, -+ AQUANTIA_VND1_GSTART_RATE_2_5G}, -+ [PHY_INTERFACE_MODE_XGMII] = {0x100, AQUANTIA_VND1_GSYSCFG_10G, -+ AQUANTIA_VND1_GSTART_RATE_10G}, -+ [PHY_INTERFACE_MODE_USXGMII] = {0x080, AQUANTIA_VND1_GSYSCFG_10G, -+ AQUANTIA_VND1_GSTART_RATE_10G}, -+}; -+ -+/* Sets up protocol on system side before calling aqr_config_aneg */ -+static int aqr_config_aneg_set_prot(struct phy_device *phydev) -+{ -+ int if_type = phydev->interface; -+ int i; -+ -+ if (!aquantia_syscfg[if_type].cnt) -+ return 0; -+ -+ /* set PHY in low power mode so we can configure protocols */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, -+ AQUANTIA_VND1_GLOBAL_SC_LP); -+ mdelay(10); -+ -+ /* set the default rate to enable the SI link */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, -+ aquantia_syscfg[if_type].start_rate); -+ -+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ AQUANTIA_VND1_GSYSCFG_BASE + i, -+ aquantia_syscfg[if_type].syscfg); -+ -+ /* wake PHY back up */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); -+ mdelay(10); -+ -+ return aqr_config_aneg(phydev); -+} -+ - static int aqr_config_intr(struct phy_device *phydev) - { - bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED; -@@ -858,6 +928,30 @@ static struct phy_driver aqr_driver[] = - .get_stats = aqr107_get_stats, - .link_change_notify = aqr107_link_change_notify, - }, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112), -+ .name = "Aquantia AQR112", -+ .probe = aqr107_probe, -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR412), -+ .name = "Aquantia AQR412", -+ .probe = aqr107_probe, -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+}, - }; - - module_phy_driver(aqr_driver); -@@ -875,6 +969,8 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) }, - { } - }; - diff --git a/target/linux/generic/hack-5.15/723-net-phy-aquantia-fix-system-side-protocol-mi.patch b/target/linux/generic/hack-5.15/723-net-phy-aquantia-fix-system-side-protocol-mi.patch deleted file mode 100644 index 72a70ebc140a94..00000000000000 --- a/target/linux/generic/hack-5.15/723-net-phy-aquantia-fix-system-side-protocol-mi.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5f008cb22f60da4e10375f22266c1a4e20b1252e Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Fri, 20 Sep 2019 18:22:52 +0300 -Subject: [PATCH] drivers: net: phy: aquantia: fix system side protocol - misconfiguration - -Do not set up protocols for speeds that are not supported by FW. Enabling -these protocols leads to link issues on system side. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/aquantia/aquantia_main.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -288,10 +288,16 @@ static int aqr_config_aneg_set_prot(stru - phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, - aquantia_syscfg[if_type].start_rate); - -- for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) -+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) { -+ u16 reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, -+ AQUANTIA_VND1_GSYSCFG_BASE + i); -+ if (!reg) -+ continue; -+ - phy_write_mmd(phydev, MDIO_MMD_VEND1, - AQUANTIA_VND1_GSYSCFG_BASE + i, - aquantia_syscfg[if_type].syscfg); -+ } - - /* wake PHY back up */ - phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); diff --git a/target/linux/generic/hack-5.15/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch b/target/linux/generic/hack-5.15/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch deleted file mode 100644 index 2193844e64a784..00000000000000 --- a/target/linux/generic/hack-5.15/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3b92ee7b7899b6beffb2b484c58326e36612a873 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 23 Dec 2021 14:52:56 +0000 -Subject: [PATCH] net: phy: aquantia: add PHY_ID for AQR112R - -As advised by Ian Chang this PHY is used in Puzzle devices. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/aquantia/aquantia_main.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -29,6 +29,8 @@ - #define PHY_ID_AQR813 0x31c31cb2 - #define PHY_ID_AQR112 0x03a1b662 - #define PHY_ID_AQR412 0x03a1b712 -+#define PHY_ID_AQR112C 0x03a1b790 -+#define PHY_ID_AQR112R 0x31c31d12 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -@@ -880,6 +882,30 @@ static struct phy_driver aqr_driver[] = - .read_status = aqr_read_status, - }, - { -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112C), -+ .name = "Aquantia AQR112C", -+ .probe = aqr107_probe, -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112R), -+ .name = "Aquantia AQR112R", -+ .probe = aqr107_probe, -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+}, -+{ - PHY_ID_MATCH_MODEL(PHY_ID_AQR113), - .name = "Aquantia AQR113", - .probe = aqr107_probe, -@@ -977,6 +1003,8 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112C) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112R) }, - { } - }; - diff --git a/target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch b/target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch deleted file mode 100644 index 8b7f2f095577fd..00000000000000 --- a/target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 880d1311335120f64447ca9d11933872d734e19a Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 27 Mar 2023 18:41:54 +0100 -Subject: [PATCH] generic: pcs-mtk-lynxi: add hack to use 2500Base-X without AN - -Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually -disabling auto-negotiation, e.g. using ethtool. While a proper fix -using SFP quirks is being discussed upstream, bring a work-around to -restore user experience to what it was before the switch to the -dedicated SGMII PCS driver. - -Signed-off-by: Daniel Golle - ---- a/drivers/net/pcs/pcs-mtk-lynxi.c -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -92,14 +92,23 @@ static void mtk_pcs_lynxi_get_state(stru - struct phylink_link_state *state) - { - struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -- unsigned int bm, adv; -+ unsigned int bm, bmsr, adv; - - /* Read the BMSR and LPA */ - regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); -- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -+ bmsr = FIELD_GET(SGMII_BMSR, bm); -+ -+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { -+ state->link = !!(bmsr & BMSR_LSTATUS); -+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); -+ state->speed = SPEED_2500; -+ state->duplex = DUPLEX_FULL; - -- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), -- FIELD_GET(SGMII_LPA, adv)); -+ return; -+ } -+ -+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -+ phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv)); - } - - static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -134,7 +143,8 @@ static int mtk_pcs_lynxi_config(struct p - /* 1000base-X or 2500base-X autoneg */ - sgm_mode = SGMII_REMOTE_FAULT_DIS; - use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -- advertising); -+ advertising) && -+ !(interface == PHY_INTERFACE_MODE_2500BASEX); - } else { - /* 1000base-X or 2500base-X without autoneg */ - sgm_mode = 0; diff --git a/target/linux/generic/hack-5.15/760-net-usb-r8152-add-LED-configuration-from-OF.patch b/target/linux/generic/hack-5.15/760-net-usb-r8152-add-LED-configuration-from-OF.patch deleted file mode 100644 index 5c5bd99b4504f6..00000000000000 --- a/target/linux/generic/hack-5.15/760-net-usb-r8152-add-LED-configuration-from-OF.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 82985725e071f2a5735052f18e109a32aeac3a0b Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sun, 26 Jul 2020 02:38:31 +0200 -Subject: [PATCH] net: usb: r8152: add LED configuration from OF - -This adds the ability to configure the LED configuration register using -OF. This way, the correct value for board specific LED configuration can -be determined. - -Signed-off-by: David Bauer ---- - drivers/net/usb/r8152.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -6994,6 +6995,22 @@ static void rtl_tally_reset(struct r8152 - ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data); - } - -+static int r8152_led_configuration(struct r8152 *tp) -+{ -+ u32 led_data; -+ int ret; -+ -+ ret = of_property_read_u32(tp->udev->dev.of_node, "realtek,led-data", -+ &led_data); -+ -+ if (ret) -+ return ret; -+ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, led_data); -+ -+ return 0; -+} -+ - static void r8152b_init(struct r8152 *tp) - { - u32 ocp_data; -@@ -7035,6 +7052,8 @@ static void r8152b_init(struct r8152 *tp - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); - ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); - ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ -+ r8152_led_configuration(tp); - } - - static void r8153_init(struct r8152 *tp) -@@ -7175,6 +7194,8 @@ static void r8153_init(struct r8152 *tp) - tp->coalesce = COALESCE_SLOW; - break; - } -+ -+ r8152_led_configuration(tp); - } - - static void r8153b_init(struct r8152 *tp) -@@ -7257,6 +7278,8 @@ static void r8153b_init(struct r8152 *tp - rtl_tally_reset(tp); - - tp->coalesce = 15000; /* 15 us */ -+ -+ r8152_led_configuration(tp); - } - - static void r8153c_init(struct r8152 *tp) diff --git a/target/linux/generic/hack-5.15/761-dt-bindings-net-add-RTL8152-binding-documentation.patch b/target/linux/generic/hack-5.15/761-dt-bindings-net-add-RTL8152-binding-documentation.patch deleted file mode 100644 index be262b993cd5d4..00000000000000 --- a/target/linux/generic/hack-5.15/761-dt-bindings-net-add-RTL8152-binding-documentation.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 3ee05f4aa64fc86af3be5bc176ba5808de9260a7 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sun, 26 Jul 2020 15:30:33 +0200 -Subject: [PATCH] dt-bindings: net: add RTL8152 binding documentation - -Add binding documentation for the Realtek RTL8152 / RTL8153 USB ethernet -adapters. - -Signed-off-by: David Bauer ---- - .../bindings/net/realtek,rtl8152.yaml | 36 +++++++++++++++++++ - 1 file changed, 36 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8152.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/realtek,rtl8152.yaml -@@ -0,0 +1,36 @@ -+# SPDX-License-Identifier: GPL-2.0 -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/net/realtek,rtl8152.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Realtek RTL8152/RTL8153 series USB ethernet -+ -+maintainers: -+ - David Bauer -+ -+properties: -+ compatible: -+ oneOf: -+ - items: -+ - enum: -+ - realtek,rtl8152 -+ - realtek,rtl8153 -+ -+ reg: -+ description: The device number on the USB bus -+ -+ realtek,led-data: -+ description: Value to be written to the LED configuration register. -+ -+required: -+ - compatible -+ - reg -+ -+examples: -+ - | -+ usb-eth@2 { -+ compatible = "realtek,rtl8153"; -+ reg = <2>; -+ realtek,led-data = <0x87>; -+ }; -\ No newline at end of file diff --git a/target/linux/generic/hack-5.15/765-mxl-gpy-control-LED-reg-from-DT.patch b/target/linux/generic/hack-5.15/765-mxl-gpy-control-LED-reg-from-DT.patch deleted file mode 100644 index 95e9749d9126f4..00000000000000 --- a/target/linux/generic/hack-5.15/765-mxl-gpy-control-LED-reg-from-DT.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 94b90966095f3fa625897e8f53d215882f6e19b3 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sat, 11 Mar 2023 17:00:01 +0100 -Subject: [PATCH] mxl-gpy: control LED reg from DT - -Add dynamic configuration for the LED control registers on MXL PHYs. - -This patch has been tested with MaxLinear GPY211C. It is unlikely to be -accepted upstream, as upstream plans on integrating their own framework -for handling these LEDs. - -For the time being, use this hack to configure PHY driven device-LEDs to -show the correct state. - -A possible alternative might be to expose the LEDs using the kernel LED -framework and bind it to the netdevice. This might also be upstreamable, -although it is a considerable extra amount of work. - -Signed-off-by: David Bauer ---- - drivers/net/phy/mxl-gpy.c | 37 ++++++++++++++++++++++++++++++++++++- - 1 file changed, 36 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/mxl-gpy.c -+++ b/drivers/net/phy/mxl-gpy.c -@@ -8,6 +8,7 @@ - - #include - #include -+#include - #include - #include - -@@ -30,6 +31,7 @@ - #define PHY_MIISTAT 0x18 /* MII state */ - #define PHY_IMASK 0x19 /* interrupt mask */ - #define PHY_ISTAT 0x1A /* interrupt status */ -+#define PHY_LED 0x1B /* LED control */ - #define PHY_FWV 0x1E /* firmware version */ - - #define PHY_MIISTAT_SPD_MASK GENMASK(2, 0) -@@ -53,10 +55,15 @@ - PHY_IMASK_ADSC | \ - PHY_IMASK_ANC) - -+#define PHY_LED_NUM_LEDS 4 -+ - #define PHY_FWV_REL_MASK BIT(15) - #define PHY_FWV_TYPE_MASK GENMASK(11, 8) - #define PHY_FWV_MINOR_MASK GENMASK(7, 0) - -+/* LED */ -+#define VSPEC1_LED(x) (0x1 + x) -+ - /* SGMII */ - #define VSPEC1_SGMII_CTRL 0x08 - #define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */ -@@ -80,6 +87,35 @@ static const struct { - {9, 0x73}, - }; - -+static int gpy_led_write(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ u32 led_regs[PHY_LED_NUM_LEDS]; -+ int i, ret; -+ u16 val = 0xff00; -+ -+ if (!IS_ENABLED(CONFIG_OF_MDIO)) -+ return 0; -+ -+ if (of_property_read_u32_array(node, "mxl,led-config", led_regs, PHY_LED_NUM_LEDS)) -+ return 0; -+ -+ if (of_property_read_bool(node, "mxl,led-drive-vdd")) -+ val &= 0x0fff; -+ -+ /* Enable LED function handling on all ports*/ -+ phy_write(phydev, PHY_LED, val); -+ -+ /* Write LED register values */ -+ for (i = 0; i < PHY_LED_NUM_LEDS; i++) { -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(i), (u16)led_regs[i]); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ - static int gpy_config_init(struct phy_device *phydev) - { - int ret; -@@ -91,7 +127,10 @@ static int gpy_config_init(struct phy_de - - /* Clear all pending interrupts */ - ret = phy_read(phydev, PHY_ISTAT); -- return ret < 0 ? ret : 0; -+ if (ret < 0) -+ return ret; -+ -+ return gpy_led_write(phydev); - } - - static int gpy_probe(struct phy_device *phydev) diff --git a/target/linux/generic/hack-5.15/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch b/target/linux/generic/hack-5.15/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch deleted file mode 100644 index 3405d5c535b6c9..00000000000000 --- a/target/linux/generic/hack-5.15/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch +++ /dev/null @@ -1,72 +0,0 @@ -From cc225d163b5a4f7a0d1968298bf7927306646a47 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Fri, 28 Apr 2023 01:53:01 +0200 -Subject: [PATCH] net: phy: mediatek-ge: add LED configuration interface - -This adds a small hack similar to the one used for ar8xxx switches to -read a reg:value map for configuring the LED configuration registers. - -This allows OpenWrt to write device-specific LED action as well as blink -configurations. It is unlikely to be accepted upstream, as upstream -plans on integrating their own framework for handling these LEDs. - -Signed-off-by: David Bauer ---- - drivers/net/phy/mediatek-ge.c | 33 +++++++++++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - ---- a/drivers/net/phy/mediatek-ge.c -+++ b/drivers/net/phy/mediatek-ge.c -@@ -1,4 +1,5 @@ - // SPDX-License-Identifier: GPL-2.0+ -+#include - #include - #include - #include -@@ -53,6 +54,36 @@ static int mt7530_phy_config_init(struct - return 0; - } - -+static int mt7530_led_config_of(struct phy_device *phydev) -+{ -+ struct device_node *np = phydev->mdio.dev.of_node; -+ const __be32 *paddr; -+ int len; -+ int i; -+ -+ paddr = of_get_property(np, "mediatek,led-config", &len); -+ if (!paddr) -+ return 0; -+ -+ if (len < (2 * sizeof(*paddr))) -+ return -EINVAL; -+ -+ len /= sizeof(*paddr); -+ -+ phydev_warn(phydev, "Configure LED registers (num=%d)\n", len); -+ for (i = 0; i < len - 1; i += 2) { -+ u32 reg; -+ u32 val; -+ -+ reg = be32_to_cpup(paddr + i); -+ val = be32_to_cpup(paddr + i + 1); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val); -+ } -+ -+ return 0; -+} -+ - static int mt7531_phy_config_init(struct phy_device *phydev) - { - mtk_gephy_config_init(phydev); -@@ -65,6 +96,9 @@ static int mt7531_phy_config_init(struct - phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404); - phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404); - -+ /* LED Config*/ -+ mt7530_led_config_of(phydev); -+ - return 0; - } - diff --git a/target/linux/generic/hack-5.15/773-bgmac-add-srab-switch.patch b/target/linux/generic/hack-5.15/773-bgmac-add-srab-switch.patch deleted file mode 100644 index 7127aa136c6a53..00000000000000 --- a/target/linux/generic/hack-5.15/773-bgmac-add-srab-switch.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 3cb240533ab787899dc7f17aa7d6c5b4810e2e58 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Fri, 7 Jul 2017 17:26:01 +0200 -Subject: bcm53xx: bgmac: use srab switch driver - -use the srab switch driver on these SoCs. - -Signed-off-by: Hauke Mehrtens ---- - drivers/net/ethernet/broadcom/bgmac-bcma.c | 1 + - drivers/net/ethernet/broadcom/bgmac.c | 24 ++++++++++++++++++++++++ - drivers/net/ethernet/broadcom/bgmac.h | 4 ++++ - 3 files changed, 29 insertions(+) - ---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c -+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c -@@ -280,6 +280,7 @@ static int bgmac_probe(struct bcma_devic - bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; - bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; - bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500; -+ bgmac->feature_flags |= BGMAC_FEAT_SRAB; - break; - default: - bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1408,6 +1409,17 @@ static const struct ethtool_ops bgmac_et - .set_link_ksettings = phy_ethtool_set_link_ksettings, - }; - -+static struct b53_platform_data bgmac_b53_pdata = { -+}; -+ -+static struct platform_device bgmac_b53_dev = { -+ .name = "b53-srab-switch", -+ .id = -1, -+ .dev = { -+ .platform_data = &bgmac_b53_pdata, -+ }, -+}; -+ - /************************************************** - * MII - **************************************************/ -@@ -1546,6 +1558,14 @@ int bgmac_enet_probe(struct bgmac *bgmac - - bgmac->in_init = false; - -+ if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) { -+ bgmac_b53_pdata.regs = ioremap(0x18007000, 0x1000); -+ -+ err = platform_device_register(&bgmac_b53_dev); -+ if (!err) -+ bgmac->b53_device = &bgmac_b53_dev; -+ } -+ - err = register_netdev(bgmac->net_dev); - if (err) { - dev_err(bgmac->dev, "Cannot register net device\n"); -@@ -1568,6 +1588,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe); - - void bgmac_enet_remove(struct bgmac *bgmac) - { -+ if (bgmac->b53_device) -+ platform_device_unregister(&bgmac_b53_dev); -+ bgmac->b53_device = NULL; -+ - unregister_netdev(bgmac->net_dev); - phy_disconnect(bgmac->net_dev->phydev); - netif_napi_del(&bgmac->napi); ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -390,6 +390,7 @@ - #define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18) - #define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19) - #define BGMAC_FEAT_IDM_MASK BIT(20) -+#define BGMAC_FEAT_SRAB BIT(21) - - struct bgmac_slot_info { - union { -@@ -497,6 +498,9 @@ struct bgmac { - void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask, - u32 set); - int (*phy_connect)(struct bgmac *bgmac); -+ -+ /* platform device for associated switch */ -+ struct platform_device *b53_device; - }; - - struct bgmac *bgmac_alloc(struct device *dev); diff --git a/target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch deleted file mode 100644 index b4ed6c991010b1..00000000000000 --- a/target/linux/generic/hack-5.15/780-usb-net-MeigLink_modem_support.patch +++ /dev/null @@ -1,69 +0,0 @@ -From f81700b6bb2eda3756247bce472d8eaf6f466f61 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:49:26 +0200 -Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support - ---- - drivers/net/usb/qmi_wwan.c | 1 + - drivers/usb/serial/option.c | 7 +++++++ - 2 files changed, 8 insertions(+) - ---- a/drivers/net/usb/qmi_wwan.c -+++ b/drivers/net/usb/qmi_wwan.c -@@ -1080,12 +1080,18 @@ static const struct usb_device_id produc - USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), - .driver_info = (unsigned long)&qmi_wwan_info, - }, -+ { /* Meiglink SGM828 */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d49, USB_CLASS_VENDOR_SPEC, 0x10, 0x05), -+ .driver_info = (unsigned long)&qmi_wwan_info, -+ }, -+ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */ -+ {QMI_MATCH_FF_FF_FF(0x05c6, 0xf601)}, /* MeigLink SLM750 */ - - /* 3. Combined interface devices matching on interface number */ - {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -247,6 +247,11 @@ static void option_instat_callback(struc - #define UBLOX_PRODUCT_R410M 0x90b2 - /* These Yuga products use Qualcomm's vendor ID */ - #define YUGA_PRODUCT_CLM920_NC5 0x9625 -+/* These MeigLink products use Qualcomm's vendor ID */ -+#define MEIGLINK_PRODUCT_SLM750 0xf601 -+ -+#define MEIGLINK_VENDOR_ID 0x2dee -+#define MEIGLINK_PRODUCT_SLM828 0x4d49 - - #define QUECTEL_VENDOR_ID 0x2c7c - /* These Quectel products use Quectel's vendor ID */ -@@ -1156,6 +1161,11 @@ static const struct usb_device_id option - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */ - .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) }, -+ /* MeiG */ -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x01) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x02) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x03) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x04) }, - /* Quectel products using Qualcomm vendor ID */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, - { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), -@@ -1197,6 +1207,11 @@ static const struct usb_device_id option - .driver_info = ZLP }, - { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), - .driver_info = RSVD(4) }, -+ /* Meiglink products using Qualcomm vendor ID */ -+ // Works OK. In case of some issues check macros that are used by Quectel Products -+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0xff, 0xff), -+ .driver_info = NUMEP2 }, -+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), - .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, diff --git a/target/linux/generic/hack-5.15/781-usb-net-rndis-support-asr.patch b/target/linux/generic/hack-5.15/781-usb-net-rndis-support-asr.patch deleted file mode 100644 index 47339b6c22f7b2..00000000000000 --- a/target/linux/generic/hack-5.15/781-usb-net-rndis-support-asr.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 9fabf60187f1fa19e6f6bb5441587d485bd534b0 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 9 Apr 2024 17:06:38 +0100 -Subject: [PATCH] rndis_host: add a bunch of USB IDs - -Add a bunch of USB IDs found in various places online to the -RNDIS USB network driver. - -Signed-off-by: Daniel Golle ---- - drivers/net/usb/rndis_host.c | 40 ++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - ---- a/drivers/net/usb/rndis_host.c -+++ b/drivers/net/usb/rndis_host.c -@@ -630,6 +630,16 @@ static const struct driver_info zte_rndi - .tx_fixup = rndis_tx_fixup, - }; - -+static const struct driver_info asr_rndis_info = { -+ .description = "Asr RNDIS device", -+ .flags = FLAG_WWAN | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT | FLAG_NOARP, -+ .bind = rndis_bind, -+ .unbind = rndis_unbind, -+ .status = rndis_status, -+ .rx_fixup = rndis_rx_fixup, -+ .tx_fixup = rndis_tx_fixup, -+}; -+ - /*-------------------------------------------------------------------------*/ - - static const struct usb_device_id products [] = { -@@ -666,6 +676,36 @@ static const struct usb_device_id produc - USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3), - .driver_info = (unsigned long) &rndis_info, - }, { -+ /* Quectel EG060V rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6004, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Quectel EC200A rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6005, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Quectel EC200T rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6026, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Simcom A7906E rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x1e0e, 0x9011, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Meig SLM770A */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Meig SLM828 */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d49, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { - /* Novatel Verizon USB730L */ - USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1), - .driver_info = (unsigned long) &rndis_info, diff --git a/target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch b/target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch deleted file mode 100644 index e7372b31d1ea0c..00000000000000 --- a/target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 7cc39a6bedbd85f3ff7e16845f310e4ce8d9833f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 6 Sep 2022 00:31:19 +0100 -Subject: [PATCH] net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module -To: netdev@vger.kernel.org, - linux-kernel@vger.kernel.org, - Russell King , - Andrew Lunn , - Heiner Kallweit -Cc: David S. Miller , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Josef Schlehofer - -This copper module comes with broken TX_FAULT indicator which must be -ignored for it to work. Implement ignoring TX_FAULT state bit also -during reset/insertion and mute the warning telling the user that the -module indicates TX_FAULT. - -Co-authored-by: Josef Schlehofer -Signed-off-by: Daniel Golle ---- - drivers/net/phy/sfp.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -390,6 +390,11 @@ static const struct sfp_quirk sfp_quirks - .modes = sfp_quirk_2500basex, - .fixup = sfp_fixup_ignore_tx_fault, - }, { -+ // OEM SFP-GE-T is 1000Base-T module -+ .vendor = "OEM", -+ .part = "SFP-GE-T", -+ .fixup = sfp_fixup_ignore_tx_fault, -+ }, { - // Lantech 8330-262D-E can operate at 2500base-X, but - // incorrectly report 2500MBd NRZ in their EEPROM - .vendor = "Lantech", -@@ -2319,7 +2324,8 @@ static void sfp_sm_main(struct sfp *sfp, - * or t_start_up, so assume there is a fault. - */ - sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT, -- sfp->sm_fault_retries == N_FAULT_INIT); -+ !sfp->tx_fault_ignore && -+ (sfp->sm_fault_retries == N_FAULT_INIT)); - } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) { - init_done: - sfp->sm_phy_retries = R_PHY_RETRY; -@@ -2542,10 +2548,12 @@ static void sfp_check_state(struct sfp * - mutex_lock(&sfp->st_mutex); - state = sfp_get_state(sfp); - changed = state ^ sfp->state; -- if (sfp->tx_fault_ignore) -+ if (sfp->tx_fault_ignore) { - changed &= SFP_F_PRESENT | SFP_F_LOS; -- else -+ state &= ~SFP_F_TX_FAULT; -+ } else { - changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT; -+ } - - for (i = 0; i < GPIO_MAX; i++) - if (changed & BIT(i)) diff --git a/target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch b/target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch deleted file mode 100644 index f93d84c6a43c42..00000000000000 --- a/target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 027586ae8ecacff49757ed854c020f35d24a599c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 11 Mar 2023 03:44:41 +0000 -Subject: [PATCH] generic: backport some phylink helper functions - -It isn't feasible to literally backport all upstream phylink_pcs changes -down to Linux 5.15: It's just too many patches, and many downstream -drivers and hacks are likely to break. We are too close to branching off -to risk this, and it's also just too much work. -Instead just add helper functions used by modern PCS drivers while keeping -the original functions instact as well. While this may add a kilobyte or -two of extra kernel size, it has the advantage that we get the best of both -worlds: None of the existing codepaths are touched, but yet we have the -option to backport singular improvements to Ethernet drivers where needed. - -Signed-off-by: Daniel Golle - ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -600,10 +600,37 @@ int phylink_speed_up(struct phylink *pl) - #define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode) - - void phylink_set_port_modes(unsigned long *bits); -+ -+/** -+ * phylink_get_link_timer_ns - return the PCS link timer value -+ * @interface: link &typedef phy_interface_t mode -+ * -+ * Return the PCS link timer setting in nanoseconds for the PHY @interface -+ * mode, or -EINVAL if not appropriate. -+ */ -+static inline int phylink_get_link_timer_ns(phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ return 1600000; -+ -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ return 10000000; -+ -+ default: -+ return -EINVAL; -+ } -+} -+ - void phylink_helper_basex_speed(struct phylink_link_state *state); - -+void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state, -+ u16 bmsr, u16 lpa); - void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs, - struct phylink_link_state *state); -+int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface, -+ const unsigned long *advertising); - int phylink_mii_c22_pcs_set_advertisement(struct mdio_device *pcs, - phy_interface_t interface, - const unsigned long *advertising); ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -934,7 +934,6 @@ static int phylink_change_inband_advert( - - return 0; - } -- - static void phylink_mac_pcs_get_state(struct phylink *pl, - struct phylink_link_state *state) - { -@@ -3019,6 +3018,52 @@ void phylink_mii_c22_pcs_get_state(struc - EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state); - - /** -+ * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers -+ * @state: a pointer to a &struct phylink_link_state. -+ * @bmsr: The value of the %MII_BMSR register -+ * @lpa: The value of the %MII_LPA register -+ * -+ * Helper for MAC PCS supporting the 802.3 clause 22 register set for -+ * clause 37 negotiation and/or SGMII control. -+ * -+ * Parse the Clause 37 or Cisco SGMII link partner negotiation word into -+ * the phylink @state structure. This is suitable to be used for implementing -+ * the mac_pcs_get_state() member of the struct phylink_mac_ops structure if -+ * accessing @bmsr and @lpa cannot be done with MDIO directly. -+ */ -+void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state, -+ u16 bmsr, u16 lpa) -+{ -+ state->link = !!(bmsr & BMSR_LSTATUS); -+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); -+ /* If there is no link or autonegotiation is disabled, the LP advertisement -+ * data is not meaningful, so don't go any further. -+ */ -+ if (!state->link || !state->an_enabled) -+ return; -+ -+ switch (state->interface) { -+ case PHY_INTERFACE_MODE_1000BASEX: -+ phylink_decode_c37_word(state, lpa, SPEED_1000); -+ break; -+ -+ case PHY_INTERFACE_MODE_2500BASEX: -+ phylink_decode_c37_word(state, lpa, SPEED_2500); -+ break; -+ -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ phylink_decode_sgmii_word(state, lpa); -+ break; -+ -+ default: -+ state->link = false; -+ break; -+ } -+} -+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_decode_state); -+ -+/** - * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS - * advertisement - * @pcs: a pointer to a &struct mdio_device. -@@ -3090,6 +3135,46 @@ int phylink_mii_c22_pcs_set_advertisemen - EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement); - - /** -+ * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS -+ * advertisement -+ * @interface: the PHY interface mode being configured -+ * @advertising: the ethtool advertisement mask -+ * -+ * Helper for MAC PCS supporting the 802.3 clause 22 register set for -+ * clause 37 negotiation and/or SGMII control. -+ * -+ * Encode the clause 37 PCS advertisement as specified by @interface and -+ * @advertising. -+ * -+ * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed. -+ */ -+int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface, -+ const unsigned long *advertising) -+{ -+ u16 adv; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ adv = ADVERTISE_1000XFULL; -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, -+ advertising)) -+ adv |= ADVERTISE_1000XPAUSE; -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, -+ advertising)) -+ adv |= ADVERTISE_1000XPSE_ASYM; -+ return adv; -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ return 0x0001; -+ default: -+ /* Nothing to do for other modes */ -+ return -EINVAL; -+ } -+} -+EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_encode_advertisement); -+ -+/** - * phylink_mii_c22_pcs_config() - configure clause 22 PCS - * @pcs: a pointer to a &struct mdio_device. - * @mode: link autonegotiation mode diff --git a/target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch b/target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch deleted file mode 100644 index 258a5fb33c3bd8..00000000000000 --- a/target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch +++ /dev/null @@ -1,190 +0,0 @@ -From cc809a441d8f2924f785eb863dfa6aef47a25b0b Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 12 Aug 2014 20:49:27 +0200 -Subject: [PATCH 30/36] GPIO: add named gpio exports - -Signed-off-by: John Crispin ---- a/drivers/gpio/gpiolib-of.c -+++ b/drivers/gpio/gpiolib-of.c -@@ -19,6 +19,8 @@ - #include - #include - #include -+#include -+#include - - #include "gpiolib.h" - #include "gpiolib-of.h" -@@ -1059,3 +1061,100 @@ void of_gpio_dev_init(struct gpio_chip * - else - gc->of_node = gdev->dev.of_node; - } -+ -+#ifdef CONFIG_GPIO_SYSFS -+ -+static struct of_device_id gpio_export_ids[] = { -+ { .compatible = "gpio-export" }, -+ { /* sentinel */ } -+}; -+ -+static int of_gpio_export_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device_node *cnp; -+ u32 val; -+ int nb = 0; -+ -+ for_each_child_of_node(np, cnp) { -+ const char *name = NULL; -+ int gpio; -+ bool dmc; -+ int max_gpio = 1; -+ int i; -+ -+ of_property_read_string(cnp, "gpio-export,name", &name); -+ -+ if (!name) -+ max_gpio = of_gpio_count(cnp); -+ -+ for (i = 0; i < max_gpio; i++) { -+ struct gpio_desc *desc; -+ unsigned flags = 0; -+ enum of_gpio_flags of_flags; -+ -+ gpio = of_get_gpio_flags(cnp, i, &of_flags); -+ if (!gpio_is_valid(gpio)) -+ return gpio; -+ -+ if (of_flags & OF_GPIO_ACTIVE_LOW) -+ flags |= GPIOF_ACTIVE_LOW; -+ -+ if (!of_property_read_u32(cnp, "gpio-export,output", &val)) { -+ if (of_flags & OF_GPIO_SINGLE_ENDED) { -+ /* -+ * As gpiod_direction_output_raw() is used, we -+ * need to emulate open drain or open source here. -+ */ -+ if (of_flags & OF_GPIO_OPEN_DRAIN) { -+ flags |= GPIOF_OPEN_DRAIN; -+ flags |= val ? GPIOF_IN : GPIOF_OUT_INIT_LOW; -+ } else { -+ flags |= GPIOF_OPEN_SOURCE; -+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_IN; -+ } -+ } else { -+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; -+ } -+ } else { -+ flags |= GPIOF_IN; -+ } -+ -+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np))) -+ continue; -+ -+ /* -+ * When emulating open-source or open-drain functionalities by not -+ * actively driving the line (setting mode to input) we still need to -+ * set the IS_OUT flag or otherwise we won't be able to set the line -+ * value anymore. -+ */ -+ if ((flags & GPIOF_IN) && -+ ((flags & GPIOF_OPEN_DRAIN) || (flags & GPIOF_OPEN_SOURCE))) { -+ desc = gpio_to_desc(gpio); -+ set_bit(FLAG_IS_OUT, &desc->flags); -+ } -+ -+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change"); -+ gpio_export_with_name(gpio, dmc, name); -+ nb++; -+ } -+ } -+ -+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb); -+ -+ return 0; -+} -+ -+static struct platform_driver gpio_export_driver = { -+ .driver = { -+ .name = "gpio-export", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(gpio_export_ids), -+ }, -+ .probe = of_gpio_export_probe, -+}; -+ -+module_platform_driver(gpio_export_driver); -+ -+#endif ---- a/include/asm-generic/gpio.h -+++ b/include/asm-generic/gpio.h -@@ -125,6 +125,12 @@ static inline int gpio_export(unsigned g - return gpiod_export(gpio_to_desc(gpio), direction_may_change); - } - -+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name); -+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name) -+{ -+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name); -+} -+ - static inline int gpio_export_link(struct device *dev, const char *name, - unsigned gpio) - { ---- a/include/linux/gpio/consumer.h -+++ b/include/linux/gpio/consumer.h -@@ -712,6 +712,7 @@ static inline void devm_acpi_dev_remove_ - - #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) - -+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name); - int gpiod_export(struct gpio_desc *desc, bool direction_may_change); - int gpiod_export_link(struct device *dev, const char *name, - struct gpio_desc *desc); -@@ -719,6 +720,13 @@ void gpiod_unexport(struct gpio_desc *de - - #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */ - -+static inline int _gpiod_export(struct gpio_desc *desc, -+ bool direction_may_change, -+ const char *name) -+{ -+ return -ENOSYS; -+} -+ - static inline int gpiod_export(struct gpio_desc *desc, - bool direction_may_change) - { ---- a/drivers/gpio/gpiolib-sysfs.c -+++ b/drivers/gpio/gpiolib-sysfs.c -@@ -564,7 +564,7 @@ static struct class gpio_class = { - * - * Returns zero on success, else an error. - */ --int gpiod_export(struct gpio_desc *desc, bool direction_may_change) -+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name) - { - struct gpio_chip *chip; - struct gpio_device *gdev; -@@ -626,6 +626,8 @@ int gpiod_export(struct gpio_desc *desc, - offset = gpio_chip_hwgpio(desc); - if (chip->names && chip->names[offset]) - ioname = chip->names[offset]; -+ if (name) -+ ioname = name; - - dev = device_create_with_groups(&gpio_class, &gdev->dev, - MKDEV(0, 0), data, gpio_groups, -@@ -647,6 +649,12 @@ err_unlock: - gpiod_dbg(desc, "%s: status %d\n", __func__, status); - return status; - } -+EXPORT_SYMBOL_GPL(__gpiod_export); -+ -+int gpiod_export(struct gpio_desc *desc, bool direction_may_change) -+{ -+ return __gpiod_export(desc, direction_may_change, NULL); -+} - EXPORT_SYMBOL_GPL(gpiod_export); - - static int match_export(struct device *dev, const void *desc) diff --git a/target/linux/generic/hack-5.15/810-bcma-ssb-fallback-sprom.patch b/target/linux/generic/hack-5.15/810-bcma-ssb-fallback-sprom.patch deleted file mode 100644 index c581a512cbd5d0..00000000000000 --- a/target/linux/generic/hack-5.15/810-bcma-ssb-fallback-sprom.patch +++ /dev/null @@ -1,187 +0,0 @@ -From e4d708702e6c98f2111e33201a264d6788564cb2 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Fri, 12 May 2023 11:08:43 +0200 -Subject: [PATCH] ssb_sprom: add generic kernel support for Broadcom Fallback SPROMs - ---- - drivers/bcma/Kconfig | 4 ++++ - drivers/bcma/Makefile | 1 + - drivers/bcma/bcma_private.h | 4 ++++ - drivers/bcma/main.c | 8 ++++++++ - drivers/bcma/sprom.c | 23 ++++++++++++++--------- - drivers/ssb/Kconfig | 5 +++++ - drivers/ssb/Makefile | 1 + - drivers/ssb/main.c | 8 ++++++++ - drivers/ssb/sprom.c | 12 +++++++++++- - drivers/ssb/ssb_private.h | 4 ++++ - 10 files changed, 60 insertions(+), 10 deletions(-) - ---- a/drivers/bcma/Kconfig -+++ b/drivers/bcma/Kconfig -@@ -18,6 +18,10 @@ config BCMA_BLOCKIO - bool - default y - -+config BCMA_FALLBACK_SPROM -+ bool -+ default y -+ - config BCMA_HOST_PCI_POSSIBLE - bool - depends on PCI = y ---- a/drivers/bcma/Makefile -+++ b/drivers/bcma/Makefile -@@ -11,6 +11,7 @@ bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) - bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o - bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o - bcma-$(CONFIG_BCMA_DRIVER_GPIO) += driver_gpio.o -+bcma-$(CONFIG_BCMA_FALLBACK_SPROM) += fallback-sprom.o - bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o - bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o - obj-$(CONFIG_BCMA) += bcma.o ---- a/drivers/bcma/bcma_private.h -+++ b/drivers/bcma/bcma_private.h -@@ -38,6 +38,10 @@ int bcma_bus_resume(struct bcma_bus *bus - void bcma_detect_chip(struct bcma_bus *bus); - int bcma_bus_scan(struct bcma_bus *bus); - -+/* fallback-sprom.c */ -+int __init bcma_fbs_register(void); -+int bcma_get_fallback_sprom(struct bcma_bus *dev, struct ssb_sprom *out); -+ - /* sprom.c */ - int bcma_sprom_get(struct bcma_bus *bus); - ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -668,6 +668,14 @@ static int __init bcma_modinit(void) - { - int err; - -+#ifdef CONFIG_BCMA_FALLBACK_SPROM -+ err = bcma_fbs_register(); -+ if (err) { -+ pr_err("Fallback SPROM initialization failed\n"); -+ err = 0; -+ } -+#endif /* CONFIG_BCMA_FALLBACK_SPROM */ -+ - err = bcma_init_bus_register(); - if (err) - return err; ---- a/drivers/bcma/sprom.c -+++ b/drivers/bcma/sprom.c -@@ -51,21 +51,26 @@ static int bcma_fill_sprom_with_fallback - { - int err; - -- if (!get_fallback_sprom) { -+ if (get_fallback_sprom) -+ err = get_fallback_sprom(bus, out); -+ -+#ifdef CONFIG_BCMA_FALLBACK_SPROM -+ if (!get_fallback_sprom || err) -+ err = bcma_get_fallback_sprom(bus, out); -+#else -+ if (!get_fallback_sprom) - err = -ENOENT; -- goto fail; -- } -+#endif /* CONFIG_BCMA_FALLBACK_SPROM */ - -- err = get_fallback_sprom(bus, out); -- if (err) -- goto fail; -+ if (err) { -+ bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err); -+ return err; -+ } - - bcma_debug(bus, "Using SPROM revision %d provided by platform.\n", - bus->sprom.revision); -+ - return 0; --fail: -- bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err); -- return err; - } - - /************************************************** ---- a/drivers/ssb/Kconfig -+++ b/drivers/ssb/Kconfig -@@ -25,6 +25,11 @@ if SSB - config SSB_SPROM - bool - -+config SSB_FALLBACK_SPROM -+ bool -+ depends on SSB_PCIHOST -+ default y -+ - # Support for Block-I/O. SELECT this from the driver that needs it. - config SSB_BLOCKIO - bool ---- a/drivers/ssb/Makefile -+++ b/drivers/ssb/Makefile -@@ -2,6 +2,7 @@ - # core - ssb-y += main.o scan.o - ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o -+ssb-$(CONFIG_SSB_FALLBACK_SPROM) += fallback-sprom.o - ssb-$(CONFIG_SSB_SPROM) += sprom.o - - # host support ---- a/drivers/ssb/main.c -+++ b/drivers/ssb/main.c -@@ -1287,6 +1287,14 @@ static int __init ssb_modinit(void) - { - int err; - -+#ifdef CONFIG_SSB_FALLBACK_SPROM -+ err = ssb_fbs_register(); -+ if (err) { -+ pr_err("Fallback SPROM initialization failed\n"); -+ err = 0; -+ } -+#endif /* CONFIG_SSB_FALLBACK_SPROM */ -+ - /* See the comment at the ssb_is_early_boot definition */ - ssb_is_early_boot = 0; - err = bus_register(&ssb_bustype); ---- a/drivers/ssb/sprom.c -+++ b/drivers/ssb/sprom.c -@@ -180,10 +180,20 @@ int ssb_arch_register_fallback_sprom(int - - int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out) - { -+ int err; -+ -+ if (get_fallback_sprom) -+ err = get_fallback_sprom(bus, out); -+ -+#ifdef CONFIG_SSB_FALLBACK_SPROM -+ if (!get_fallback_sprom || err) -+ err = ssb_get_fallback_sprom(bus, out); -+#else - if (!get_fallback_sprom) - return -ENOENT; -+#endif /* CONFIG_SSB_FALLBACK_SPROM */ - -- return get_fallback_sprom(bus, out); -+ return err; - } - - /* https://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ ---- a/drivers/ssb/ssb_private.h -+++ b/drivers/ssb/ssb_private.h -@@ -143,6 +143,10 @@ extern int ssb_bus_scan(struct ssb_bus * - extern void ssb_iounmap(struct ssb_bus *ssb); - - -+/* fallback-sprom.c */ -+int __init ssb_fbs_register(void); -+int ssb_get_fallback_sprom(struct ssb_bus *dev, struct ssb_sprom *out); -+ - /* sprom.c */ - extern - ssize_t ssb_attr_sprom_show(struct ssb_bus *bus, char *buf, diff --git a/target/linux/generic/hack-5.15/901-debloat_sock_diag.patch b/target/linux/generic/hack-5.15/901-debloat_sock_diag.patch deleted file mode 100644 index cf8ddea255276d..00000000000000 --- a/target/linux/generic/hack-5.15/901-debloat_sock_diag.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 3b6115d6b57a263bdc8c9b1df273bd4a7955eead Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 8 Jul 2017 08:16:31 +0200 -Subject: debloat: add some debloat patches, strip down procfs and make O_DIRECT support optional, saves ~15K after lzma on MIPS - -Signed-off-by: Felix Fietkau ---- - net/Kconfig | 3 +++ - net/core/Makefile | 3 ++- - net/core/sock.c | 2 ++ - net/ipv4/Kconfig | 1 + - net/netlink/Kconfig | 1 + - net/packet/Kconfig | 1 + - net/unix/Kconfig | 1 + - 7 files changed, 11 insertions(+), 1 deletion(-) - ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -104,6 +104,9 @@ source "net/mptcp/Kconfig" - - endif # if INET - -+config SOCK_DIAG -+ bool -+ - config NETWORK_SECMARK - bool "Security Marking" - help ---- a/net/core/Makefile -+++ b/net/core/Makefile -@@ -10,9 +10,10 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core. - - obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ - neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ -- sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ -+ dev_ioctl.o tso.o sock_reuseport.o \ - fib_notifier.o xdp.o flow_offload.o - -+obj-$(CONFIG_SOCK_DIAG) += sock_diag.o - obj-y += net-sysfs.o - obj-$(CONFIG_PAGE_POOL) += page_pool.o - obj-$(CONFIG_PROC_FS) += net-procfs.o ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -114,6 +114,7 @@ - #include - #include - #include -+#include - - #include - -@@ -143,6 +144,7 @@ - - static DEFINE_MUTEX(proto_list_mutex); - static LIST_HEAD(proto_list); -+DEFINE_COOKIE(sock_cookie); - - static void sock_inuse_add(struct net *net, int val); - -@@ -545,6 +547,18 @@ discard_and_relse: - } - EXPORT_SYMBOL(__sk_receive_skb); - -+u64 __sock_gen_cookie(struct sock *sk) -+{ -+ while (1) { -+ u64 res = atomic64_read(&sk->sk_cookie); -+ -+ if (res) -+ return res; -+ res = gen_cookie_next(&sock_cookie); -+ atomic64_cmpxchg(&sk->sk_cookie, 0, res); -+ } -+} -+ - INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *, - u32)); - INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *, -@@ -2005,9 +2019,11 @@ static void __sk_free(struct sock *sk) - if (likely(sk->sk_net_refcnt)) - sock_inuse_add(sock_net(sk), -1); - -+#ifdef CONFIG_SOCK_DIAG - if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk))) - sock_diag_broadcast_destroy(sk); - else -+#endif - sk_destruct(sk); - } - ---- a/net/core/sock_diag.c -+++ b/net/core/sock_diag.c -@@ -11,7 +11,6 @@ - #include - #include - #include --#include - #include - #include - -@@ -20,20 +19,6 @@ static int (*inet_rcv_compat)(struct sk_ - static DEFINE_MUTEX(sock_diag_table_mutex); - static struct workqueue_struct *broadcast_wq; - --DEFINE_COOKIE(sock_cookie); -- --u64 __sock_gen_cookie(struct sock *sk) --{ -- while (1) { -- u64 res = atomic64_read(&sk->sk_cookie); -- -- if (res) -- return res; -- res = gen_cookie_next(&sock_cookie); -- atomic64_cmpxchg(&sk->sk_cookie, 0, res); -- } --} -- - int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie) - { - u64 res; ---- a/net/ipv4/Kconfig -+++ b/net/ipv4/Kconfig -@@ -424,6 +424,7 @@ config INET_TUNNEL - - config INET_DIAG - tristate "INET: socket monitoring interface" -+ select SOCK_DIAG - default y - help - Support for INET (TCP, DCCP, etc) socket monitoring interface used by ---- a/net/netlink/Kconfig -+++ b/net/netlink/Kconfig -@@ -5,6 +5,7 @@ - - config NETLINK_DIAG - tristate "NETLINK: socket monitoring interface" -+ select SOCK_DIAG - default n - help - Support for NETLINK socket monitoring interface used by the ss tool. ---- a/net/packet/Kconfig -+++ b/net/packet/Kconfig -@@ -19,6 +19,7 @@ config PACKET - config PACKET_DIAG - tristate "Packet: sockets monitoring interface" - depends on PACKET -+ select SOCK_DIAG - default n - help - Support for PF_PACKET sockets monitoring interface used by the ss tool. ---- a/net/unix/Kconfig -+++ b/net/unix/Kconfig -@@ -33,6 +33,7 @@ config AF_UNIX_OOB - config UNIX_DIAG - tristate "UNIX: socket monitoring interface" - depends on UNIX -+ select SOCK_DIAG - default n - help - Support for UNIX socket monitoring interface used by the ss tool. ---- a/net/xdp/Kconfig -+++ b/net/xdp/Kconfig -@@ -10,6 +10,7 @@ config XDP_SOCKETS - config XDP_SOCKETS_DIAG - tristate "XDP sockets: monitoring interface" - depends on XDP_SOCKETS -+ select SOCK_DIAG - default n - help - Support for PF_XDP sockets monitoring interface used by the ss tool. diff --git a/target/linux/generic/hack-5.15/902-debloat_proc.patch b/target/linux/generic/hack-5.15/902-debloat_proc.patch deleted file mode 100644 index 4404d3456ee337..00000000000000 --- a/target/linux/generic/hack-5.15/902-debloat_proc.patch +++ /dev/null @@ -1,408 +0,0 @@ -From 9e3f1d0805b2d919904dd9a4ff0d956314cc3cba Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 8 Jul 2017 08:20:09 +0200 -Subject: debloat: procfs - -Signed-off-by: Felix Fietkau ---- - fs/locks.c | 2 ++ - fs/proc/Kconfig | 5 +++++ - fs/proc/consoles.c | 3 +++ - fs/proc/proc_tty.c | 11 ++++++++++- - include/net/snmp.h | 18 +++++++++++++++++- - ipc/msg.c | 3 +++ - ipc/sem.c | 2 ++ - ipc/shm.c | 2 ++ - ipc/util.c | 3 +++ - kernel/exec_domain.c | 2 ++ - kernel/irq/proc.c | 9 +++++++++ - kernel/time/timer_list.c | 2 ++ - mm/vmalloc.c | 2 ++ - mm/vmstat.c | 8 +++++--- - net/8021q/vlanproc.c | 6 ++++++ - net/core/net-procfs.c | 18 ++++++++++++------ - net/core/sock.c | 2 ++ - net/ipv4/fib_trie.c | 18 ++++++++++++------ - net/ipv4/proc.c | 3 +++ - net/ipv4/route.c | 3 +++ - 20 files changed, 105 insertions(+), 17 deletions(-) - ---- a/fs/locks.c -+++ b/fs/locks.c -@@ -3008,6 +3008,8 @@ static const struct seq_operations locks - - static int __init proc_locks_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - proc_create_seq_private("locks", 0, NULL, &locks_seq_operations, - sizeof(struct locks_iterator), NULL); - return 0; ---- a/fs/proc/Kconfig -+++ b/fs/proc/Kconfig -@@ -100,6 +100,11 @@ config PROC_CHILDREN - Say Y if you are running any user-space software which takes benefit from - this interface. For example, rkt is such a piece of software. - -+config PROC_STRIPPED -+ default n -+ depends on EXPERT -+ bool "Strip non-essential /proc functionality to reduce code size" -+ - config PROC_PID_ARCH_STATUS - def_bool n - depends on PROC_FS ---- a/fs/proc/consoles.c -+++ b/fs/proc/consoles.c -@@ -92,6 +92,9 @@ static const struct seq_operations conso - - static int __init proc_consoles_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - proc_create_seq("consoles", 0, NULL, &consoles_op); - return 0; - } ---- a/fs/proc/proc_tty.c -+++ b/fs/proc/proc_tty.c -@@ -133,7 +133,10 @@ static const struct seq_operations tty_d - void proc_tty_register_driver(struct tty_driver *driver) - { - struct proc_dir_entry *ent; -- -+ -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (!driver->driver_name || driver->proc_entry || - !driver->ops->proc_show) - return; -@@ -150,6 +153,9 @@ void proc_tty_unregister_driver(struct t - { - struct proc_dir_entry *ent; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - ent = driver->proc_entry; - if (!ent) - return; -@@ -164,6 +170,9 @@ void proc_tty_unregister_driver(struct t - */ - void __init proc_tty_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (!proc_mkdir("tty", NULL)) - return; - proc_mkdir("tty/ldisc", NULL); /* Preserved: it's userspace visible */ ---- a/include/net/snmp.h -+++ b/include/net/snmp.h -@@ -124,6 +124,21 @@ struct linux_tls_mib { - #define DECLARE_SNMP_STAT(type, name) \ - extern __typeof__(type) __percpu *name - -+#ifdef CONFIG_PROC_STRIPPED -+#define __SNMP_STATS_DUMMY(mib) \ -+ do { (void) mib->mibs[0]; } while(0) -+ -+#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -+#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib) -+#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -+#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -+#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) -+#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) -+#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) -+#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) -+ -+#else -+ - #define __SNMP_INC_STATS(mib, field) \ - __this_cpu_inc(mib->mibs[field]) - -@@ -154,8 +169,9 @@ struct linux_tls_mib { - __this_cpu_add(ptr[basefield##OCTETS], addend); \ - } while (0) - -+#endif - --#if BITS_PER_LONG==32 -+#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED) - - #define __SNMP_ADD_STATS64(mib, field, addend) \ - do { \ ---- a/ipc/msg.c -+++ b/ipc/msg.c -@@ -1350,6 +1350,9 @@ void __init msg_init(void) - { - msg_init_ns(&init_ipc_ns); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - ipc_init_proc_interface("sysvipc/msg", - " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n", - IPC_MSG_IDS, sysvipc_msg_proc_show); ---- a/ipc/sem.c -+++ b/ipc/sem.c -@@ -268,6 +268,8 @@ void sem_exit_ns(struct ipc_namespace *n - void __init sem_init(void) - { - sem_init_ns(&init_ipc_ns); -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; - ipc_init_proc_interface("sysvipc/sem", - " key semid perms nsems uid gid cuid cgid otime ctime\n", - IPC_SEM_IDS, sysvipc_sem_proc_show); ---- a/ipc/shm.c -+++ b/ipc/shm.c -@@ -154,6 +154,8 @@ pure_initcall(ipc_ns_init); - - void __init shm_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; - ipc_init_proc_interface("sysvipc/shm", - #if BITS_PER_LONG <= 32 - " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n", ---- a/ipc/util.c -+++ b/ipc/util.c -@@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(cons - struct proc_dir_entry *pde; - struct ipc_proc_iface *iface; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - iface = kmalloc(sizeof(*iface), GFP_KERNEL); - if (!iface) - return; ---- a/kernel/exec_domain.c -+++ b/kernel/exec_domain.c -@@ -29,6 +29,8 @@ static int execdomains_proc_show(struct - - static int __init proc_execdomains_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - proc_create_single("execdomains", 0, NULL, execdomains_proc_show); - return 0; - } ---- a/kernel/irq/proc.c -+++ b/kernel/irq/proc.c -@@ -341,6 +341,9 @@ void register_irq_proc(unsigned int irq, - void __maybe_unused *irqp = (void *)(unsigned long) irq; - char name [MAX_NAMELEN]; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) - return; - -@@ -394,6 +397,9 @@ void unregister_irq_proc(unsigned int ir - { - char name [MAX_NAMELEN]; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - if (!root_irq_dir || !desc->dir) - return; - #ifdef CONFIG_SMP -@@ -432,6 +438,9 @@ void init_irq_proc(void) - unsigned int irq; - struct irq_desc *desc; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - /* create /proc/irq */ - root_irq_dir = proc_mkdir("irq", NULL); - if (!root_irq_dir) ---- a/kernel/time/timer_list.c -+++ b/kernel/time/timer_list.c -@@ -350,6 +350,8 @@ static int __init init_timer_list_procfs - { - struct proc_dir_entry *pe; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops, - sizeof(struct timer_list_iter), NULL); - if (!pe) ---- a/mm/vmalloc.c -+++ b/mm/vmalloc.c -@@ -3986,6 +3986,8 @@ static const struct seq_operations vmall - - static int __init proc_vmalloc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - if (IS_ENABLED(CONFIG_NUMA)) - proc_create_seq_private("vmallocinfo", 0400, NULL, - &vmalloc_op, ---- a/mm/vmstat.c -+++ b/mm/vmstat.c -@@ -2083,10 +2083,12 @@ void __init init_mm_internals(void) - start_shepherd_timer(); - #endif - #ifdef CONFIG_PROC_FS -- proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); -- proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); -+ proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); -+ proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op); -+ } - proc_create_seq("vmstat", 0444, NULL, &vmstat_op); -- proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op); - #endif - } - ---- a/net/8021q/vlanproc.c -+++ b/net/8021q/vlanproc.c -@@ -93,6 +93,9 @@ void vlan_proc_cleanup(struct net *net) - { - struct vlan_net *vn = net_generic(net, vlan_net_id); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (vn->proc_vlan_conf) - remove_proc_entry(name_conf, vn->proc_vlan_dir); - -@@ -112,6 +115,9 @@ int __net_init vlan_proc_init(struct net - { - struct vlan_net *vn = net_generic(net, vlan_net_id); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net); - if (!vn->proc_vlan_dir) - goto err; ---- a/net/core/net-procfs.c -+++ b/net/core/net-procfs.c -@@ -317,10 +317,12 @@ static int __net_init dev_proc_net_init( - if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops, - sizeof(struct seq_net_private))) - goto out; -- if (!proc_create_seq("softnet_stat", 0444, net->proc_net, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_seq("softnet_stat", 0444, net->proc_net, - &softnet_seq_ops)) - goto out_dev; -- if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops, - sizeof(struct seq_net_private))) - goto out_softnet; - -@@ -330,9 +332,11 @@ static int __net_init dev_proc_net_init( - out: - return rc; - out_ptype: -- remove_proc_entry("ptype", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("ptype", net->proc_net); - out_softnet: -- remove_proc_entry("softnet_stat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("softnet_stat", net->proc_net); - out_dev: - remove_proc_entry("dev", net->proc_net); - goto out; -@@ -342,8 +346,10 @@ static void __net_exit dev_proc_net_exit - { - wext_proc_exit(net); - -- remove_proc_entry("ptype", net->proc_net); -- remove_proc_entry("softnet_stat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ remove_proc_entry("ptype", net->proc_net); -+ remove_proc_entry("softnet_stat", net->proc_net); -+ } - remove_proc_entry("dev", net->proc_net); - } - ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -3900,6 +3900,8 @@ static __net_initdata struct pernet_oper - - static int __init proto_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - return register_pernet_subsys(&proto_net_ops); - } - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -3029,11 +3029,13 @@ static const struct seq_operations fib_r - - int __net_init fib_proc_init(struct net *net) - { -- if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops, - sizeof(struct fib_trie_iter))) - goto out1; - -- if (!proc_create_net_single("fib_triestat", 0444, net->proc_net, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_net_single("fib_triestat", 0444, net->proc_net, - fib_triestat_seq_show, NULL)) - goto out2; - -@@ -3044,17 +3046,21 @@ int __net_init fib_proc_init(struct net - return 0; - - out3: -- remove_proc_entry("fib_triestat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("fib_triestat", net->proc_net); - out2: -- remove_proc_entry("fib_trie", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("fib_trie", net->proc_net); - out1: - return -ENOMEM; - } - - void __net_exit fib_proc_exit(struct net *net) - { -- remove_proc_entry("fib_trie", net->proc_net); -- remove_proc_entry("fib_triestat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ remove_proc_entry("fib_trie", net->proc_net); -+ remove_proc_entry("fib_triestat", net->proc_net); -+ } - remove_proc_entry("route", net->proc_net); - } - ---- a/net/ipv4/proc.c -+++ b/net/ipv4/proc.c -@@ -553,5 +553,8 @@ static __net_initdata struct pernet_oper - - int __init ip_misc_proc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - return register_pernet_subsys(&ip_proc_ops); - } ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -388,6 +388,9 @@ static struct pernet_operations ip_rt_pr - - static int __init ip_rt_proc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - return register_pernet_subsys(&ip_rt_proc_ops); - } - diff --git a/target/linux/generic/hack-5.15/904-debloat_dma_buf.patch b/target/linux/generic/hack-5.15/904-debloat_dma_buf.patch deleted file mode 100644 index 71546bf942da4e..00000000000000 --- a/target/linux/generic/hack-5.15/904-debloat_dma_buf.patch +++ /dev/null @@ -1,92 +0,0 @@ -From e3692cb2fcd5ba1244512a0f43b8118f65f1c375 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 8 Jul 2017 08:20:43 +0200 -Subject: debloat: dmabuf - -Signed-off-by: Felix Fietkau ---- - drivers/base/Kconfig | 2 +- - drivers/dma-buf/Makefile | 10 +++++++--- - drivers/dma-buf/dma-buf.c | 4 +++- - kernel/sched/core.c | 1 + - 4 files changed, 12 insertions(+), 5 deletions(-) - ---- a/drivers/base/Kconfig -+++ b/drivers/base/Kconfig -@@ -187,7 +187,7 @@ config SOC_BUS - source "drivers/base/regmap/Kconfig" - - config DMA_SHARED_BUFFER -- bool -+ tristate - default n - select IRQ_WORK - help ---- a/drivers/dma-buf/heaps/Makefile -+++ b/drivers/dma-buf/heaps/Makefile -@@ -1,3 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 --obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o --obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o -+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o -+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o ---- a/drivers/dma-buf/Makefile -+++ b/drivers/dma-buf/Makefile -@@ -1,16 +1,20 @@ - # SPDX-License-Identifier: GPL-2.0-only --obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ -+obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o -+ -+dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ - dma-resv.o seqno-fence.o --obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o --obj-$(CONFIG_DMABUF_HEAPS) += heaps/ --obj-$(CONFIG_SYNC_FILE) += sync_file.o --obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o --obj-$(CONFIG_UDMABUF) += udmabuf.o --obj-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o -+dma-buf-objs-$(CONFIG_DMABUF_HEAPS) += dma-heap.o -+obj-$(CONFIG_DMABUF_HEAPS) += heaps/ -+dma-buf-objs-$(CONFIG_SYNC_FILE) += sync_file.o -+dma-buf-objs-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o -+dma-buf-objs-$(CONFIG_UDMABUF) += udmabuf.o -+dma-buf-objs-$(CONFIG_DMABUF_SYSFS_STATS) += udmabuf.o - - dmabuf_selftests-y := \ - selftest.o \ - st-dma-fence.o \ - st-dma-fence-chain.o - --obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o -+dma-buf-objs-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o -+ -+dma-shared-buffer-objs := $(dma-buf-objs-y) ---- a/drivers/dma-buf/dma-buf.c -+++ b/drivers/dma-buf/dma-buf.c -@@ -1513,4 +1513,5 @@ static void __exit dma_buf_deinit(void) - kern_unmount(dma_buf_mnt); - dma_buf_uninit_sysfs_statistics(); - } --__exitcall(dma_buf_deinit); -+module_exit(dma_buf_deinit); -+MODULE_LICENSE("GPL"); ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -4220,6 +4220,7 @@ int wake_up_state(struct task_struct *p, - { - return try_to_wake_up(p, state, 0); - } -+EXPORT_SYMBOL_GPL(wake_up_state); - - /* - * Perform scheduler related setup for a newly forked process p. ---- a/fs/d_path.c -+++ b/fs/d_path.c -@@ -316,6 +316,7 @@ char *dynamic_dname(struct dentry *dentr - buffer += buflen - sz; - return memcpy(buffer, temp, sz); - } -+EXPORT_SYMBOL_GPL(dynamic_dname); - - char *simple_dname(struct dentry *dentry, char *buffer, int buflen) - { diff --git a/target/linux/generic/hack-5.15/910-kobject_uevent.patch b/target/linux/generic/hack-5.15/910-kobject_uevent.patch deleted file mode 100644 index c4c41ca400ae32..00000000000000 --- a/target/linux/generic/hack-5.15/910-kobject_uevent.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sun, 16 Jul 2017 16:56:10 +0200 -Subject: lib: add uevent_next_seqnum() - -Signed-off-by: Felix Fietkau ---- - include/linux/kobject.h | 5 +++++ - lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 42 insertions(+) - ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -179,6 +179,18 @@ out: - return r; - } - -+u64 uevent_next_seqnum(void) -+{ -+ u64 seq; -+ -+ mutex_lock(&uevent_sock_mutex); -+ seq = ++uevent_seqnum; -+ mutex_unlock(&uevent_sock_mutex); -+ -+ return seq; -+} -+EXPORT_SYMBOL_GPL(uevent_next_seqnum); -+ - /** - * kobject_synth_uevent - send synthetic uevent with arguments - * diff --git a/target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch deleted file mode 100644 index dd93e0be4283b1..00000000000000 --- a/target/linux/generic/hack-5.15/911-kobject_add_broadcast_uevent.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sun, 16 Jul 2017 16:56:10 +0200 -Subject: lib: add broadcast_uevent() - -Signed-off-by: Felix Fietkau ---- - include/linux/kobject.h | 5 +++++ - lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 42 insertions(+) - ---- a/include/linux/kobject.h -+++ b/include/linux/kobject.h -@@ -32,6 +32,8 @@ - #define UEVENT_NUM_ENVP 64 /* number of env pointers */ - #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */ - -+struct sk_buff; -+ - #ifdef CONFIG_UEVENT_HELPER - /* path to the userspace helper executed on an event */ - extern char uevent_helper[]; -@@ -244,4 +246,7 @@ int kobject_synth_uevent(struct kobject - __printf(2, 3) - int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); - -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation); -+ - #endif /* _KOBJECT_H_ */ ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -691,6 +691,43 @@ int add_uevent_var(struct kobj_uevent_en - EXPORT_SYMBOL_GPL(add_uevent_var); - - #if defined(CONFIG_NET) -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation) -+{ -+ struct uevent_sock *ue_sk; -+ int err = 0; -+ -+ /* send netlink message */ -+ mutex_lock(&uevent_sock_mutex); -+ list_for_each_entry(ue_sk, &uevent_sock_list, list) { -+ struct sock *uevent_sock = ue_sk->sk; -+ struct sk_buff *skb2; -+ -+ skb2 = skb_clone(skb, allocation); -+ if (!skb2) -+ break; -+ -+ err = netlink_broadcast(uevent_sock, skb2, pid, group, -+ allocation); -+ if (err) -+ break; -+ } -+ mutex_unlock(&uevent_sock_mutex); -+ -+ kfree_skb(skb); -+ return err; -+} -+#else -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation) -+{ -+ kfree_skb(skb); -+ return 0; -+} -+#endif -+EXPORT_SYMBOL_GPL(broadcast_uevent); -+ -+#if defined(CONFIG_NET) - static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb, - struct netlink_ext_ack *extack) - { diff --git a/target/linux/generic/hack-5.15/920-device_tree_cmdline.patch b/target/linux/generic/hack-5.15/920-device_tree_cmdline.patch deleted file mode 100644 index d1f36e716ed9ba..00000000000000 --- a/target/linux/generic/hack-5.15/920-device_tree_cmdline.patch +++ /dev/null @@ -1,21 +0,0 @@ -From e08bcbbaa52fcc41f02743fd2e62a33255ce52da Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:52:28 +0200 -Subject: [PATCH] of/ftd: add device tree cmdline - ---- - drivers/of/fdt.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/of/fdt.c -+++ b/drivers/of/fdt.c -@@ -1158,6 +1158,9 @@ int __init early_init_dt_scan_chosen(uns - p = of_get_flat_dt_prop(node, "bootargs", &l); - if (p != NULL && l > 0) - strlcpy(data, p, min(l, COMMAND_LINE_SIZE)); -+ p = of_get_flat_dt_prop(node, "bootargs-append", &l); -+ if (p != NULL && l > 0) -+ strlcat(data, p, min_t(int, strlen(data) + (int)l, COMMAND_LINE_SIZE)); - - /* - * CONFIG_CMDLINE is meant to be a default in case nothing else diff --git a/target/linux/generic/hack-5.15/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch b/target/linux/generic/hack-5.15/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch deleted file mode 100644 index b4339e82d76e25..00000000000000 --- a/target/linux/generic/hack-5.15/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 19 Jul 2022 06:17:48 +0200 -Subject: [PATCH] Revert "Revert "Revert "driver core: Set fw_devlink=on by - default""" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit ea718c699055c8566eb64432388a04974c43b2ea. - -With of_platform_populate() called for MTD partitions that commit breaks -probing devices which reference MTD in device tree. - -Link: https://lore.kernel.org/all/696cb2da-20b9-b3dd-46d9-de4bf91a1506@gmail.com/T/#u -Signed-off-by: Rafał Miłecki ---- - drivers/base/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -1577,7 +1577,7 @@ static void device_links_purge(struct de - #define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \ - DL_FLAG_PM_RUNTIME) - --static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_ON; -+static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_PERMISSIVE; - static int __init fw_devlink_setup(char *arg) - { - if (!arg) diff --git a/target/linux/generic/pending-5.15/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch b/target/linux/generic/pending-5.15/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch deleted file mode 100644 index 22f52c1d46258c..00000000000000 --- a/target/linux/generic/pending-5.15/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Felix Fietkau -Date: Thu, 22 Oct 2020 22:00:03 +0200 -Subject: [PATCH] compiler.h: only include asm/rwonce.h for kernel code - -This header file is not in uapi, which makes any user space code that includes -linux/compiler.h to fail with the error 'asm/rwonce.h: No such file or directory' - -Fixes: e506ea451254 ("compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h") -Signed-off-by: Felix Fietkau ---- - ---- a/include/linux/compiler.h -+++ b/include/linux/compiler.h -@@ -220,6 +220,8 @@ void ftrace_likely_update(struct ftrace_ - #define function_nocfi(x) (x) - #endif - -+#include -+ - #endif /* __KERNEL__ */ - - /* -@@ -252,6 +254,4 @@ static inline void *offset_to_ptr(const - */ - #define prevent_tail_call_optimization() mb() - --#include -- - #endif /* __LINUX_COMPILER_H */ diff --git a/target/linux/generic/pending-5.15/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch b/target/linux/generic/pending-5.15/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch deleted file mode 100644 index 95a9656d268d2d..00000000000000 --- a/target/linux/generic/pending-5.15/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch +++ /dev/null @@ -1,57 +0,0 @@ -From: Felix Fietkau -Date: Wed, 18 Apr 2018 10:50:05 +0200 -Subject: [PATCH] MIPS: only process negative stack offsets on stack traces - -Fixes endless back traces in cases where the compiler emits a stack -pointer increase in a branch delay slot (probably for some form of -function return). - -[ 3.475442] BUG: MAX_STACK_TRACE_ENTRIES too low! -[ 3.480070] turning off the locking correctness validator. -[ 3.485521] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.34 #0 -[ 3.491475] Stack : 00000000 00000000 00000000 00000000 80e0fce2 00000034 00000000 00000000 -[ 3.499764] 87c3838c 80696377 8061047c 00000000 00000001 00000001 87c2d850 6534689f -[ 3.508059] 00000000 00000000 80e10000 00000000 00000000 000000cf 0000000f 00000000 -[ 3.516353] 00000000 806a0000 00076891 00000000 00000000 00000000 ffffffff 00000000 -[ 3.524648] 806c0000 00000004 80e10000 806a0000 00000003 80690000 00000000 80700000 -[ 3.532942] ... -[ 3.535362] Call Trace: -[ 3.537818] [<80010a48>] show_stack+0x58/0x100 -[ 3.542207] [<804c2f78>] dump_stack+0xe8/0x170 -[ 3.546613] [<80079f90>] save_trace+0xf0/0x110 -[ 3.551010] [<8007b1ec>] mark_lock+0x33c/0x78c -[ 3.555413] [<8007bf48>] __lock_acquire+0x2ac/0x1a08 -[ 3.560337] [<8007de60>] lock_acquire+0x64/0x8c -[ 3.564846] [<804e1570>] _raw_spin_lock_irqsave+0x54/0x78 -[ 3.570186] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.574770] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.579257] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.583839] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.588329] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.592911] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.597401] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.601983] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.606473] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.611055] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.615545] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.620125] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.624619] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.629197] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.633691] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.638269] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.642763] [<801b618c>] kernfs_notify+0x94/0xac - -Signed-off-by: Felix Fietkau ---- - ---- a/arch/mips/kernel/process.c -+++ b/arch/mips/kernel/process.c -@@ -393,6 +393,8 @@ static inline int is_sp_move_ins(union m - - if (ip->i_format.opcode == addiu_op || - ip->i_format.opcode == daddiu_op) { -+ if (ip->i_format.simmediate > 0) -+ return 0; - *frame_size = -ip->i_format.simmediate; - return 1; - } diff --git a/target/linux/generic/pending-5.15/103-kbuild-export-SUBARCH.patch b/target/linux/generic/pending-5.15/103-kbuild-export-SUBARCH.patch deleted file mode 100644 index 120b6e4cf897f8..00000000000000 --- a/target/linux/generic/pending-5.15/103-kbuild-export-SUBARCH.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 173019b66dcc9d68ad9333aa744dad1e369b5aa8 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sun, 9 Jul 2017 00:26:53 +0200 -Subject: [PATCH 34/34] kernel: add compile fix for linux 4.9 on x86 - -Signed-off-by: Felix Fietkau ---- - Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/Makefile -+++ b/Makefile -@@ -534,7 +534,7 @@ KBUILD_LDFLAGS_MODULE := - KBUILD_LDFLAGS := - CLANG_FLAGS := - --export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG -+export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG - export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL - export PERL PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX - export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD diff --git a/target/linux/generic/pending-5.15/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch b/target/linux/generic/pending-5.15/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch deleted file mode 100644 index d6b10491f830e5..00000000000000 --- a/target/linux/generic/pending-5.15/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch +++ /dev/null @@ -1,75 +0,0 @@ -From bd1b9f66d5134e518419f4c4dacf1884c1616983 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Thu, 28 Apr 2022 11:13:23 +0200 -Subject: [PATCH] watchdog: max63xx_wdt: Add support for specifying WDI logic - via GPIO -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On some boards is WDI logic of max6370 chip connected via GPIO. -So extend max63xx_wdt driver to allow specifying WDI logic via GPIO. - -Signed-off-by: Pali Rohár ---- - drivers/watchdog/max63xx_wdt.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - ---- a/drivers/watchdog/max63xx_wdt.c -+++ b/drivers/watchdog/max63xx_wdt.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - #define DEFAULT_HEARTBEAT 60 - #define MAX_HEARTBEAT 60 -@@ -53,6 +54,9 @@ struct max63xx_wdt { - void __iomem *base; - spinlock_t lock; - -+ /* GPIOs */ -+ struct gpio_desc *gpio_wdi; -+ - /* WDI and WSET bits write access routines */ - void (*ping)(struct max63xx_wdt *wdt); - void (*set)(struct max63xx_wdt *wdt, u8 set); -@@ -158,6 +162,17 @@ static const struct watchdog_info max63x - .identity = "max63xx Watchdog", - }; - -+static void max63xx_gpio_ping(struct max63xx_wdt *wdt) -+{ -+ spin_lock(&wdt->lock); -+ -+ gpiod_set_value(wdt->gpio_wdi, 1); -+ udelay(1); -+ gpiod_set_value(wdt->gpio_wdi, 0); -+ -+ spin_unlock(&wdt->lock); -+} -+ - static void max63xx_mmap_ping(struct max63xx_wdt *wdt) - { - u8 val; -@@ -225,10 +240,19 @@ static int max63xx_wdt_probe(struct plat - return -EINVAL; - } - -+ wdt->gpio_wdi = devm_gpiod_get(dev, NULL, GPIOD_FLAGS_BIT_DIR_OUT); -+ if (IS_ERR(wdt->gpio_wdi) && PTR_ERR(wdt->gpio_wdi) != -ENOENT) -+ return dev_err_probe(dev, PTR_ERR(wdt->gpio_wdi), -+ "unable to request gpio: %ld\n", -+ PTR_ERR(wdt->gpio_wdi)); -+ - err = max63xx_mmap_init(pdev, wdt); - if (err) - return err; - -+ if (!IS_ERR(wdt->gpio_wdi)) -+ wdt->ping = max63xx_gpio_ping; -+ - platform_set_drvdata(pdev, &wdt->wdd); - watchdog_set_drvdata(&wdt->wdd, wdt); - diff --git a/target/linux/generic/pending-5.15/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-5.15/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch deleted file mode 100644 index 42f5a8c2467c5a..00000000000000 --- a/target/linux/generic/pending-5.15/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch +++ /dev/null @@ -1,82 +0,0 @@ -From: Tobias Wolf -Subject: mm: Fix alloc_node_mem_map with ARCH_PFN_OFFSET calculation - -An rt288x (ralink) based router (Belkin F5D8235 v1) does not boot with any -kernel beyond version 4.3 resulting in: - -BUG: Bad page state in process swapper pfn:086ac - -bisect resulted in: - -a1c34a3bf00af2cede839879502e12dc68491ad5 is the first bad commit -commit a1c34a3bf00af2cede839879502e12dc68491ad5 -Author: Laura Abbott -Date: Thu Nov 5 18:48:46 2015 -0800 - - mm: Don't offset memmap for flatmem - - Srinivas Kandagatla reported bad page messages when trying to remove the - bottom 2MB on an ARM based IFC6410 board - - BUG: Bad page state in process swapper pfn:fffa8 - page:ef7fb500 count:0 mapcount:0 mapping: (null) index:0x0 - flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked) - page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set - bad because of flags: - flags: 0x200041(locked|active|mlocked) - Modules linked in: - CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty -#816 - Hardware name: Qualcomm (Flattened Device Tree) - unwind_backtrace - show_stack - dump_stack - bad_page - free_pages_prepare - free_hot_cold_page - __free_pages - free_highmem_page - mem_init - start_kernel - Disabling lock debugging due to kernel taint - [...] -:040000 040000 2de013c372345fd471cd58f0553c9b38b0ef1cc4 -0a8156f848733dfa21e16c196dfb6c0a76290709 M mm - -This fix for ARM does not account ARCH_PFN_OFFSET for mem_map as later used by -page_to_pfn anymore. - -The following output was generated with two hacked in printk statements: - -printk("before %p vs. %p or %p\n", mem_map, mem_map - offset, mem_map - -(pgdat->node_start_pfn - ARCH_PFN_OFFSET)); - if (page_to_pfn(mem_map) != pgdat->node_start_pfn) - mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); -printk("after %p\n", mem_map); - -Output: - -[ 0.000000] before 8861b280 vs. 8861b280 or 8851b280 -[ 0.000000] after 8851b280 - -As seen in the first line mem_map with subtraction of offset does not equal the -mem_map after subtraction of ARCH_PFN_OFFSET. - -After adding the offset of ARCH_PFN_OFFSET as well to mem_map as the -previously calculated offset is zero for the named platform it is able to boot -4.4 and 4.9-rc7 again. - -Signed-off-by: Tobias Wolf ---- - ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -7622,7 +7622,7 @@ static void __init alloc_node_mem_map(st - if (pgdat == NODE_DATA(0)) { - mem_map = NODE_DATA(0)->node_mem_map; - if (page_to_pfn(mem_map) != pgdat->node_start_pfn) -- mem_map -= offset; -+ mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); - } - #endif - } diff --git a/target/linux/generic/pending-5.15/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch b/target/linux/generic/pending-5.15/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch deleted file mode 100644 index 8f40ae3ba2400d..00000000000000 --- a/target/linux/generic/pending-5.15/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch +++ /dev/null @@ -1,81 +0,0 @@ -From: Felix Fietkau -Subject: jffs2: use .rename2 and add RENAME_WHITEOUT support - -It is required for renames on overlayfs - -Signed-off-by: Felix Fietkau ---- - ---- a/fs/jffs2/dir.c -+++ b/fs/jffs2/dir.c -@@ -614,8 +614,8 @@ static int jffs2_rmdir (struct inode *di - return ret; - } - --static int jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i, -- struct dentry *dentry, umode_t mode, dev_t rdev) -+static int __jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i, -+ struct dentry *dentry, umode_t mode, dev_t rdev, bool whiteout) - { - struct jffs2_inode_info *f, *dir_f; - struct jffs2_sb_info *c; -@@ -754,7 +754,11 @@ static int jffs2_mknod (struct user_name - mutex_unlock(&dir_f->sem); - jffs2_complete_reservation(c); - -- d_instantiate_new(dentry, inode); -+ if (!whiteout) -+ d_instantiate_new(dentry, inode); -+ else -+ unlock_new_inode(inode); -+ - return 0; - - fail: -@@ -762,6 +766,19 @@ static int jffs2_mknod (struct user_name - return ret; - } - -+static int jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i, -+ struct dentry *dentry, umode_t mode, dev_t rdev) -+{ -+ return __jffs2_mknod(mnt_userns, dir_i, dentry, mode, rdev, false); -+} -+ -+static int jffs2_whiteout (struct user_namespace *mnt_userns, struct inode *old_dir, -+ struct dentry *old_dentry) -+{ -+ return __jffs2_mknod(mnt_userns, old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, -+ WHITEOUT_DEV, true); -+} -+ - static int jffs2_rename (struct user_namespace *mnt_userns, - struct inode *old_dir_i, struct dentry *old_dentry, - struct inode *new_dir_i, struct dentry *new_dentry, -@@ -773,7 +790,7 @@ static int jffs2_rename (struct user_nam - uint8_t type; - uint32_t now; - -- if (flags & ~RENAME_NOREPLACE) -+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) - return -EINVAL; - - /* The VFS will check for us and prevent trying to rename a -@@ -839,9 +856,14 @@ static int jffs2_rename (struct user_nam - if (d_is_dir(old_dentry) && !victim_f) - inc_nlink(new_dir_i); - -- /* Unlink the original */ -- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -- old_dentry->d_name.name, old_dentry->d_name.len, NULL, now); -+ if (flags & RENAME_WHITEOUT) -+ /* Replace with whiteout */ -+ ret = jffs2_whiteout(mnt_userns, old_dir_i, old_dentry); -+ else -+ /* Unlink the original */ -+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -+ old_dentry->d_name.name, -+ old_dentry->d_name.len, NULL, now); - - /* We don't touch inode->i_nlink */ - diff --git a/target/linux/generic/pending-5.15/141-jffs2-add-RENAME_EXCHANGE-support.patch b/target/linux/generic/pending-5.15/141-jffs2-add-RENAME_EXCHANGE-support.patch deleted file mode 100644 index f58fc791d28157..00000000000000 --- a/target/linux/generic/pending-5.15/141-jffs2-add-RENAME_EXCHANGE-support.patch +++ /dev/null @@ -1,73 +0,0 @@ -From: Felix Fietkau -Subject: jffs2: add RENAME_EXCHANGE support - -Signed-off-by: Felix Fietkau ---- - ---- a/fs/jffs2/dir.c -+++ b/fs/jffs2/dir.c -@@ -787,18 +787,31 @@ static int jffs2_rename (struct user_nam - int ret; - struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); - struct jffs2_inode_info *victim_f = NULL; -+ struct inode *fst_inode = d_inode(old_dentry); -+ struct inode *snd_inode = d_inode(new_dentry); - uint8_t type; - uint32_t now; - -- if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) -+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT|RENAME_EXCHANGE)) - return -EINVAL; - -+ if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) { -+ if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) { -+ inc_nlink(new_dir_i); -+ drop_nlink(old_dir_i); -+ } -+ else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) { -+ drop_nlink(new_dir_i); -+ inc_nlink(old_dir_i); -+ } -+ } -+ - /* The VFS will check for us and prevent trying to rename a - * file over a directory and vice versa, but if it's a directory, - * the VFS can't check whether the victim is empty. The filesystem - * needs to do that for itself. - */ -- if (d_really_is_positive(new_dentry)) { -+ if (d_really_is_positive(new_dentry) && !(flags & RENAME_EXCHANGE)) { - victim_f = JFFS2_INODE_INFO(d_inode(new_dentry)); - if (d_is_dir(new_dentry)) { - struct jffs2_full_dirent *fd; -@@ -833,7 +846,7 @@ static int jffs2_rename (struct user_nam - if (ret) - return ret; - -- if (victim_f) { -+ if (victim_f && !(flags & RENAME_EXCHANGE)) { - /* There was a victim. Kill it off nicely */ - if (d_is_dir(new_dentry)) - clear_nlink(d_inode(new_dentry)); -@@ -859,6 +872,12 @@ static int jffs2_rename (struct user_nam - if (flags & RENAME_WHITEOUT) - /* Replace with whiteout */ - ret = jffs2_whiteout(mnt_userns, old_dir_i, old_dentry); -+ else if (flags & RENAME_EXCHANGE) -+ /* Replace the original */ -+ ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i), -+ d_inode(new_dentry)->i_ino, type, -+ old_dentry->d_name.name, old_dentry->d_name.len, -+ now); - else - /* Unlink the original */ - ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -@@ -890,7 +909,7 @@ static int jffs2_rename (struct user_nam - return ret; - } - -- if (d_is_dir(old_dentry)) -+ if (d_is_dir(old_dentry) && !(flags & RENAME_EXCHANGE)) - drop_nlink(old_dir_i); - - new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); diff --git a/target/linux/generic/pending-5.15/142-jffs2-add-splice-ops.patch b/target/linux/generic/pending-5.15/142-jffs2-add-splice-ops.patch deleted file mode 100644 index de847a1f5cd1fc..00000000000000 --- a/target/linux/generic/pending-5.15/142-jffs2-add-splice-ops.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Felix Fietkau -Subject: jffs2: add splice ops - -Add splice_read using generic_file_splice_read. -Add splice_write using iter_file_splice_write - -Signed-off-by: Felix Fietkau ---- - ---- a/fs/jffs2/file.c -+++ b/fs/jffs2/file.c -@@ -53,6 +53,8 @@ const struct file_operations jffs2_file_ - .open = generic_file_open, - .read_iter = generic_file_read_iter, - .write_iter = generic_file_write_iter, -+ .splice_read = generic_file_splice_read, -+ .splice_write = iter_file_splice_write, - .unlocked_ioctl=jffs2_ioctl, - .mmap = generic_file_readonly_mmap, - .fsync = jffs2_fsync, diff --git a/target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch deleted file mode 100644 index a64d3021d4b6aa..00000000000000 --- a/target/linux/generic/pending-5.15/150-bridge_allow_receiption_on_disabled_port.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Stephen Hemminger -Subject: bridge: allow receiption on disabled port - -When an ethernet device is enslaved to a bridge, and the bridge STP -detects loss of carrier (or operational state down), then normally -packet receiption is blocked. - -This breaks control applications like WPA which maybe expecting to -receive packets to negotiate to bring link up. The bridge needs to -block forwarding packets from these disabled ports, but there is no -hard requirement to not allow local packet delivery. - -Signed-off-by: Stephen Hemminger -Signed-off-by: Felix Fietkau - ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -209,6 +209,9 @@ static void __br_handle_local_finish(str - /* note: already called with rcu_read_lock */ - static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) - { -+ struct net_bridge_port *p = br_port_get_rcu(skb->dev); -+ -+ if (p->state != BR_STATE_DISABLED) - __br_handle_local_finish(skb); - - /* return 1 to signal the okfn() was called so it's ok to use the skb */ -@@ -376,6 +379,17 @@ static rx_handler_result_t br_handle_fra - - forward: - switch (p->state) { -+ case BR_STATE_DISABLED: -+ if (ether_addr_equal(p->br->dev->dev_addr, dest)) -+ skb->pkt_type = PACKET_HOST; -+ -+ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, -+ dev_net(skb->dev), NULL, skb, skb->dev, NULL, -+ br_handle_local_finish) == 1) { -+ return RX_HANDLER_PASS; -+ } -+ break; -+ - case BR_STATE_FORWARDING: - case BR_STATE_LEARNING: - if (ether_addr_equal(p->br->dev->dev_addr, dest)) diff --git a/target/linux/generic/pending-5.15/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch b/target/linux/generic/pending-5.15/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch deleted file mode 100644 index f420d210c27cad..00000000000000 --- a/target/linux/generic/pending-5.15/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Felix Fietkau -Date: Thu, 4 Jan 2024 15:21:21 +0100 -Subject: [PATCH] net: bridge: do not send arp replies if src and target hw - addr is the same - -There are broken devices in the wild that handle duplicate IP address -detection by sending out ARP requests for the IP that they received from a -DHCP server and refuse the address if they get a reply. -When proxyarp is enabled, they would go into a loop of requesting an address -and then NAKing it again. - -Link: https://github.com/openwrt/openwrt/issues/14309 -Signed-off-by: Felix Fietkau ---- - ---- a/net/bridge/br_arp_nd_proxy.c -+++ b/net/bridge/br_arp_nd_proxy.c -@@ -204,7 +204,10 @@ void br_do_proxy_suppress_arp(struct sk_ - if ((p && (p->flags & BR_PROXYARP)) || - (f->dst && (f->dst->flags & (BR_PROXYARP_WIFI | - BR_NEIGH_SUPPRESS)))) { -- if (!vid) -+ replied = true; -+ if (!memcmp(n->ha, sha, dev->addr_len)) -+ replied = false; -+ else if (!vid) - br_arp_send(br, p, skb->dev, sip, tip, - sha, n->ha, sha, 0, 0); - else -@@ -212,7 +215,6 @@ void br_do_proxy_suppress_arp(struct sk_ - sha, n->ha, sha, - skb->vlan_proto, - skb_vlan_tag_get(skb)); -- replied = true; - } - - /* If we have replied or as long as we know the diff --git a/target/linux/generic/pending-5.15/190-rtc-rs5c372-support_alarms_up_to_1_week.patch b/target/linux/generic/pending-5.15/190-rtc-rs5c372-support_alarms_up_to_1_week.patch deleted file mode 100644 index 13b79b5c098733..00000000000000 --- a/target/linux/generic/pending-5.15/190-rtc-rs5c372-support_alarms_up_to_1_week.patch +++ /dev/null @@ -1,94 +0,0 @@ -From: Daniel González Cabanelas -Subject: [PATCH 1/2] rtc: rs5c372: support alarms up to 1 week - -The Ricoh R2221x, R2223x, RS5C372, RV5C387A chips can handle 1 week -alarms. - -Read the "wday" alarm register and convert it to a date to support up 1 -week in our driver. - -Signed-off-by: Daniel González Cabanelas ---- - drivers/rtc/rtc-rs5c372.c | 48 ++++++++++++++++++++++++++++++++++----- - 1 file changed, 42 insertions(+), 6 deletions(-) - ---- a/drivers/rtc/rtc-rs5c372.c -+++ b/drivers/rtc/rtc-rs5c372.c -@@ -393,7 +393,9 @@ static int rs5c_read_alarm(struct device - { - struct i2c_client *client = to_i2c_client(dev); - struct rs5c372 *rs5c = i2c_get_clientdata(client); -- int status; -+ int status, wday_offs; -+ struct rtc_time rtc; -+ unsigned long alarm_secs; - - status = rs5c_get_regs(rs5c); - if (status < 0) -@@ -403,6 +405,30 @@ static int rs5c_read_alarm(struct device - t->time.tm_sec = 0; - t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); - t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); -+ t->time.tm_wday = ffs(rs5c->regs[RS5C_REG_ALARM_A_WDAY] & 0x7f) - 1; -+ -+ /* determine the day, month and year based on alarm wday, taking as a -+ * reference the current time from the rtc -+ */ -+ status = rs5c372_rtc_read_time(dev, &rtc); -+ if (status < 0) -+ return status; -+ -+ wday_offs = t->time.tm_wday - rtc.tm_wday; -+ alarm_secs = mktime64(rtc.tm_year + 1900, -+ rtc.tm_mon + 1, -+ rtc.tm_mday + wday_offs, -+ t->time.tm_hour, -+ t->time.tm_min, -+ t->time.tm_sec); -+ -+ if (wday_offs < 0 || (wday_offs == 0 && -+ (t->time.tm_hour < rtc.tm_hour || -+ (t->time.tm_hour == rtc.tm_hour && -+ t->time.tm_min <= rtc.tm_min)))) -+ alarm_secs += 7 * 86400; -+ -+ rtc_time64_to_tm(alarm_secs, &t->time); - - /* ... and status */ - t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); -@@ -417,12 +443,20 @@ static int rs5c_set_alarm(struct device - struct rs5c372 *rs5c = i2c_get_clientdata(client); - int status, addr, i; - unsigned char buf[3]; -+ struct rtc_time rtc_tm; -+ unsigned long rtc_secs, alarm_secs; - -- /* only handle up to 24 hours in the future, like RTC_ALM_SET */ -- if (t->time.tm_mday != -1 -- || t->time.tm_mon != -1 -- || t->time.tm_year != -1) -+ /* chip only can handle alarms up to one week in the future*/ -+ status = rs5c372_rtc_read_time(dev, &rtc_tm); -+ if (status) -+ return status; -+ rtc_secs = rtc_tm_to_time64(&rtc_tm); -+ alarm_secs = rtc_tm_to_time64(&t->time); -+ if (alarm_secs >= rtc_secs + 7 * 86400) { -+ dev_err(dev, "%s: alarm maximum is one week in the future (%d)\n", -+ __func__, status); - return -EINVAL; -+ } - - /* REVISIT: round up tm_sec */ - -@@ -443,7 +477,9 @@ static int rs5c_set_alarm(struct device - /* set alarm */ - buf[0] = bin2bcd(t->time.tm_min); - buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour); -- buf[2] = 0x7f; /* any/all days */ -+ /* each bit is the day of the week, 0x7f means all days */ -+ buf[2] = (t->time.tm_wday >= 0 && t->time.tm_wday < 7) ? -+ BIT(t->time.tm_wday) : 0x7f; - - for (i = 0; i < sizeof(buf); i++) { - addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i); diff --git a/target/linux/generic/pending-5.15/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch b/target/linux/generic/pending-5.15/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch deleted file mode 100644 index 7e9d0e66c051e0..00000000000000 --- a/target/linux/generic/pending-5.15/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch +++ /dev/null @@ -1,70 +0,0 @@ -From: Daniel González Cabanelas -Subject: [PATCH 2/2] rtc: rs5c372: let the alarm to be used as wakeup source - -Currently there is no use for the interrupts on the rs5c372 RTC and the -wakealarm isn't enabled. There are some devices like NASes which use this -RTC to wake up from the power off state when the INTR pin is activated by -the alarm clock. - -Enable the alarm and let to be used as a wakeup source. - -Tested on a Buffalo LS421DE NAS. - -Signed-off-by: Daniel González Cabanelas ---- - drivers/rtc/rtc-rs5c372.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/drivers/rtc/rtc-rs5c372.c -+++ b/drivers/rtc/rtc-rs5c372.c -@@ -654,6 +654,7 @@ static int rs5c372_probe(struct i2c_clie - int err = 0; - int smbus_mode = 0; - struct rs5c372 *rs5c372; -+ bool rs5c372_can_wakeup_device = false; - - dev_dbg(&client->dev, "%s\n", __func__); - -@@ -689,6 +690,12 @@ static int rs5c372_probe(struct i2c_clie - else - rs5c372->type = id->driver_data; - -+#ifdef CONFIG_OF -+ if(of_property_read_bool(client->dev.of_node, -+ "wakeup-source")) -+ rs5c372_can_wakeup_device = true; -+#endif -+ - /* we read registers 0x0f then 0x00-0x0f; skip the first one */ - rs5c372->regs = &rs5c372->buf[1]; - rs5c372->smbus = smbus_mode; -@@ -722,6 +729,8 @@ static int rs5c372_probe(struct i2c_clie - goto exit; - } - -+ rs5c372->has_irq = 1; -+ - /* if the oscillator lost power and no other software (like - * the bootloader) set it up, do it here. - * -@@ -748,6 +757,10 @@ static int rs5c372_probe(struct i2c_clie - ); - - /* REVISIT use client->irq to register alarm irq ... */ -+ if (rs5c372_can_wakeup_device) { -+ device_init_wakeup(&client->dev, true); -+ } -+ - rs5c372->rtc = devm_rtc_device_register(&client->dev, - rs5c372_driver.driver.name, - &rs5c372_rtc_ops, THIS_MODULE); -@@ -761,6 +774,9 @@ static int rs5c372_probe(struct i2c_clie - if (err) - goto exit; - -+ /* the rs5c372 alarm only supports a minute accuracy */ -+ rs5c372->rtc->uie_unsupported = 1; -+ - return 0; - - exit: diff --git a/target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch deleted file mode 100644 index fc4fe6d6b08d4f..00000000000000 --- a/target/linux/generic/pending-5.15/203-kallsyms_uncompressed.patch +++ /dev/null @@ -1,119 +0,0 @@ -From: Felix Fietkau -Subject: kernel: add a config option for keeping the kallsyms table uncompressed, saving ~9kb kernel size after lzma on ar71xx - -[john@phrozen.org: added to my upstream queue 30.12.2016] -lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed -Signed-off-by: Felix Fietkau ---- - init/Kconfig | 11 +++++++++++ - kernel/kallsyms.c | 8 ++++++++ - scripts/kallsyms.c | 12 ++++++++++++ - scripts/link-vmlinux.sh | 4 ++++ - 4 files changed, 35 insertions(+) - ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1447,6 +1447,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW - the unaligned access emulation. - see arch/parisc/kernel/unaligned.c for reference - -+config KALLSYMS_UNCOMPRESSED -+ bool "Keep kallsyms uncompressed" -+ depends on KALLSYMS -+ help -+ Normally kallsyms contains compressed symbols (using a token table), -+ reducing the uncompressed kernel image size. Keeping the symbol table -+ uncompressed significantly improves the size of this part in compressed -+ kernel images. -+ -+ Say N unless you need compressed kernel images to be small. -+ - config HAVE_PCSPKR_PLATFORM - bool - ---- a/kernel/kallsyms.c -+++ b/kernel/kallsyms.c -@@ -88,6 +88,11 @@ static unsigned int kallsyms_expand_symb - * For every byte on the compressed symbol data, copy the table - * entry for that byte. - */ -+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED -+ memcpy(result, data + 1, len - 1); -+ result += len - 1; -+ len = 0; -+#endif - while (len) { - tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; - data++; -@@ -120,6 +125,9 @@ tail: - */ - static char kallsyms_get_symbol_type(unsigned int off) - { -+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED -+ return kallsyms_names[off + 1]; -+#endif - /* - * Get just the first code, look it up in the token table, - * and return the first char from this token. ---- a/scripts/kallsyms.c -+++ b/scripts/kallsyms.c -@@ -58,6 +58,7 @@ static struct addr_range percpu_range = - static struct sym_entry **table; - static unsigned int table_size, table_cnt; - static int all_symbols; -+static int uncompressed; - static int absolute_percpu; - static int base_relative; - -@@ -509,6 +510,9 @@ static void write_src(void) - - free(markers); - -+ if (uncompressed) -+ return; -+ - output_label("kallsyms_token_table"); - off = 0; - for (i = 0; i < 256; i++) { -@@ -560,6 +564,9 @@ static unsigned char *find_token(unsigne - { - int i; - -+ if (uncompressed) -+ return NULL; -+ - for (i = 0; i < len - 1; i++) { - if (str[i] == token[0] && str[i+1] == token[1]) - return &str[i]; -@@ -632,6 +639,9 @@ static void optimize_result(void) - { - int i, best; - -+ if (uncompressed) -+ return; -+ - /* using the '\0' symbol last allows compress_symbols to use standard - * fast string functions */ - for (i = 255; i >= 0; i--) { -@@ -796,6 +806,8 @@ int main(int argc, char **argv) - absolute_percpu = 1; - else if (strcmp(argv[i], "--base-relative") == 0) - base_relative = 1; -+ else if (strcmp(argv[i], "--uncompressed") == 0) -+ uncompressed = 1; - else - usage(); - } ---- a/scripts/link-vmlinux.sh -+++ b/scripts/link-vmlinux.sh -@@ -262,6 +262,10 @@ kallsyms() - kallsymopt="${kallsymopt} --base-relative" - fi - -+ if [ -n "${CONFIG_KALLSYMS_UNCOMPRESSED}" ]; then -+ kallsymopt="${kallsymopt} --uncompressed" -+ fi -+ - info KSYMS ${2} - ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2} - } diff --git a/target/linux/generic/pending-5.15/205-backtrace_module_info.patch b/target/linux/generic/pending-5.15/205-backtrace_module_info.patch deleted file mode 100644 index 6379ce071d7c32..00000000000000 --- a/target/linux/generic/pending-5.15/205-backtrace_module_info.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Felix Fietkau -Subject: kernel: when KALLSYMS is disabled, print module address + size for matching backtrace entries - -[john@phrozen.org: felix will add this to his upstream queue] - -lede-commit 53827cdc824556cda910b23ce5030c363b8f1461 -Signed-off-by: Felix Fietkau ---- - lib/vsprintf.c | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - ---- a/lib/vsprintf.c -+++ b/lib/vsprintf.c -@@ -1003,8 +1003,10 @@ char *symbol_string(char *buf, char *end - struct printf_spec spec, const char *fmt) - { - unsigned long value; --#ifdef CONFIG_KALLSYMS - char sym[KSYM_SYMBOL_LEN]; -+#ifndef CONFIG_KALLSYMS -+ struct module *mod; -+ int len; - #endif - - if (fmt[1] == 'R') -@@ -1025,8 +1027,14 @@ char *symbol_string(char *buf, char *end - - return string_nocheck(buf, end, sym, spec); - #else -- return special_hex_number(buf, end, value, sizeof(void *)); -+ len = snprintf(sym, sizeof(sym), "0x%lx", value); -+ mod = __module_address(value); -+ if (mod) -+ snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]", -+ mod->name, mod->core_layout.base, -+ mod->core_layout.size); - #endif -+ return string(buf, end, sym, spec); - } - - static const struct printf_spec default_str_spec = { diff --git a/target/linux/generic/pending-5.15/240-remove-unsane-filenames-from-deps_initramfs-list.patch b/target/linux/generic/pending-5.15/240-remove-unsane-filenames-from-deps_initramfs-list.patch deleted file mode 100644 index 29cfade7163590..00000000000000 --- a/target/linux/generic/pending-5.15/240-remove-unsane-filenames-from-deps_initramfs-list.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Gabor Juhos -Subject: usr: sanitize deps_initramfs list - -If any filename in the intramfs dependency -list contains a colon, that causes a kernel -build error like this: - -/devel/openwrt/build_dir/linux-ar71xx_generic/linux-3.6.6/usr/Makefile:58: *** multiple target patterns. Stop. -make[5]: *** [usr] Error 2 - -Fix it by removing such filenames from the -deps_initramfs list. - -Signed-off-by: Gabor Juhos -Signed-off-by: Felix Fietkau ---- - usr/Makefile | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/usr/Makefile -+++ b/usr/Makefile -@@ -61,6 +61,8 @@ hostprogs := gen_init_cpio - # The dependency list is generated by gen_initramfs.sh -l - -include $(obj)/.initramfs_data.cpio.d - -+deps_initramfs := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v))) -+ - # do not try to update files included in initramfs - $(deps_initramfs): ; - diff --git a/target/linux/generic/pending-5.15/261-enable_wilink_platform_without_drivers.patch b/target/linux/generic/pending-5.15/261-enable_wilink_platform_without_drivers.patch deleted file mode 100644 index cd31f9d9342925..00000000000000 --- a/target/linux/generic/pending-5.15/261-enable_wilink_platform_without_drivers.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Imre Kaloz -Subject: [PATCH] hack: net: wireless: make the wl12xx glue code available with - compat-wireless, too - -Signed-off-by: Imre Kaloz ---- - drivers/net/wireless/ti/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/ti/Kconfig -+++ b/drivers/net/wireless/ti/Kconfig -@@ -20,7 +20,7 @@ source "drivers/net/wireless/ti/wlcore/K - - config WILINK_PLATFORM_DATA - bool "TI WiLink platform data" -- depends on WLCORE_SDIO || WL1251_SDIO -+ depends on WLCORE_SDIO || WL1251_SDIO || ARCH_OMAP2PLUS - default y - help - Small platform data bit needed to pass data to the sdio modules. diff --git a/target/linux/generic/pending-5.15/270-platform-mikrotik-build-bits.patch b/target/linux/generic/pending-5.15/270-platform-mikrotik-build-bits.patch deleted file mode 100644 index 99f83bb2c4e971..00000000000000 --- a/target/linux/generic/pending-5.15/270-platform-mikrotik-build-bits.patch +++ /dev/null @@ -1,31 +0,0 @@ -From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= -Date: Sat, 28 Mar 2020 12:11:50 +0100 -Subject: [PATCH] generic: platform/mikrotik build bits (5.4) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds platform/mikrotik kernel build bits - -Signed-off-by: Thibaut VARÈNE ---- - drivers/platform/Kconfig | 2 ++ - drivers/platform/Makefile | 1 + - 2 files changed, 3 insertions(+) - ---- a/drivers/platform/Kconfig -+++ b/drivers/platform/Kconfig -@@ -15,3 +15,5 @@ source "drivers/platform/mellanox/Kconfi - source "drivers/platform/olpc/Kconfig" - - source "drivers/platform/surface/Kconfig" -+ -+source "drivers/platform/mikrotik/Kconfig" ---- a/drivers/platform/Makefile -+++ b/drivers/platform/Makefile -@@ -10,3 +10,4 @@ obj-$(CONFIG_OLPC_EC) += olpc/ - obj-$(CONFIG_GOLDFISH) += goldfish/ - obj-$(CONFIG_CHROME_PLATFORMS) += chrome/ - obj-$(CONFIG_SURFACE_PLATFORMS) += surface/ -+obj-$(CONFIG_MIKROTIK) += mikrotik/ diff --git a/target/linux/generic/pending-5.15/300-mips_expose_boot_raw.patch b/target/linux/generic/pending-5.15/300-mips_expose_boot_raw.patch deleted file mode 100644 index be4dacf0945861..00000000000000 --- a/target/linux/generic/pending-5.15/300-mips_expose_boot_raw.patch +++ /dev/null @@ -1,40 +0,0 @@ -From: Mark Miller -Subject: mips: expose CONFIG_BOOT_RAW - -This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on -certain Broadcom chipsets running CFE in order to load the kernel. - -Signed-off-by: Mark Miller -Acked-by: Rob Landley ---- ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -1103,9 +1103,6 @@ config FW_ARC - config ARCH_MAY_HAVE_PC_FDC - bool - --config BOOT_RAW -- bool -- - config CEVT_BCM1480 - bool - -@@ -3186,6 +3183,18 @@ choice - bool "Extend builtin kernel arguments with bootloader arguments" - endchoice - -+config BOOT_RAW -+ bool "Enable the kernel to be executed from the load address" -+ default n -+ help -+ Allow the kernel to be executed from the load address for -+ bootloaders which cannot read the ELF format. This places -+ a jump to start_kernel at the load address. -+ -+ If unsure, say N. -+ -+ -+ - endmenu - - config LOCKDEP_SUPPORT diff --git a/target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch b/target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch deleted file mode 100644 index 726c884027f1d1..00000000000000 --- a/target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch +++ /dev/null @@ -1,71 +0,0 @@ -From e6e6ef4275978823ec3a84133fc91f4ffbef5c84 Mon Sep 17 00:00:00 2001 -From: Paul Burton -Date: Mon, 22 Feb 2016 18:09:44 +0000 -Subject: [PATCH] MIPS: Add barriers between dcache & icache flushes - -Index-based cache operations may be arbitrarily reordered by out of -order CPUs. Thus code which writes back the dcache & then invalidates -the icache using indexed cache ops must include a barrier between -operating on the 2 caches in order to prevent the scenario in which: - - - icache invalidation occurs. - - - icache fetch occurs, due to speculation. - - - dcache writeback occurs. - -If the above were allowed to happen then the icache would contain stale -data. Forcing the dcache writeback to complete before the icache -invalidation avoids this. - -Signed-off-by: Paul Burton -Cc: James Hogan ---- - arch/mips/mm/c-r4k.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - ---- a/arch/mips/mm/c-r4k.c -+++ b/arch/mips/mm/c-r4k.c -@@ -515,6 +515,7 @@ static inline void local_r4k___flush_cac - - default: - r4k_blast_dcache(); -+ mb(); /* cache instructions may be reordered */ - r4k_blast_icache(); - break; - } -@@ -595,8 +596,10 @@ static inline void local_r4k_flush_cache - if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) - r4k_blast_dcache(); - /* If executable, blast stale lines from icache */ -- if (exec) -+ if (exec) { -+ mb(); /* cache instructions may be reordered */ - r4k_blast_icache(); -+ } - } - - static void r4k_flush_cache_range(struct vm_area_struct *vma, -@@ -697,8 +700,13 @@ static inline void local_r4k_flush_cache - if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { - vaddr ? r4k_blast_dcache_page(addr) : - r4k_blast_dcache_user_page(addr); -- if (exec && !cpu_icache_snoops_remote_store) -+ if (exec) -+ mb(); /* cache instructions may be reordered */ -+ -+ if (exec && !cpu_icache_snoops_remote_store) { - r4k_blast_scache_page(addr); -+ mb(); /* cache instructions may be reordered */ -+ } - } - if (exec) { - if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { -@@ -765,6 +773,7 @@ static inline void __local_r4k_flush_ica - else - blast_dcache_range(start, end); - } -+ mb(); /* cache instructions may be reordered */ - } - - if (type == R4K_INDEX || diff --git a/target/linux/generic/pending-5.15/302-mips_no_branch_likely.patch b/target/linux/generic/pending-5.15/302-mips_no_branch_likely.patch deleted file mode 100644 index 271923fca8c14e..00000000000000 --- a/target/linux/generic/pending-5.15/302-mips_no_branch_likely.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Subject: mips: use -mno-branch-likely for kernel and userspace - -saves ~11k kernel size after lzma and ~12k squashfs size in the - -lede-commit: 41a039f46450ffae9483d6216422098669da2900 -Signed-off-by: Felix Fietkau ---- - arch/mips/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -95,7 +95,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin - # machines may also. Since BFD is incredibly buggy with respect to - # crossformat linking we rely on the elf2ecoff tool for format conversion. - # --cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -+cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely - cflags-y += -msoft-float - LDFLAGS_vmlinux += -G 0 -static -n -nostdlib - KBUILD_AFLAGS_MODULE += -mlong-calls diff --git a/target/linux/generic/pending-5.15/305-mips_module_reloc.patch b/target/linux/generic/pending-5.15/305-mips_module_reloc.patch deleted file mode 100644 index bbea1f61c1489d..00000000000000 --- a/target/linux/generic/pending-5.15/305-mips_module_reloc.patch +++ /dev/null @@ -1,370 +0,0 @@ -From: Felix Fietkau -Subject: mips: replace -mlong-calls with -mno-long-calls to make function calls faster in kernel modules to achieve this, try to - -lede-commit: 3b3d64743ba2a874df9d70cd19e242205b0a788c -Signed-off-by: Felix Fietkau ---- - arch/mips/Makefile | 5 + - arch/mips/include/asm/module.h | 5 + - arch/mips/kernel/module.c | 279 ++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 284 insertions(+), 5 deletions(-) - ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -98,8 +98,18 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin - cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely - cflags-y += -msoft-float - LDFLAGS_vmlinux += -G 0 -static -n -nostdlib -+ifdef CONFIG_64BIT - KBUILD_AFLAGS_MODULE += -mlong-calls - KBUILD_CFLAGS_MODULE += -mlong-calls -+else -+ ifdef CONFIG_DYNAMIC_FTRACE -+ KBUILD_AFLAGS_MODULE += -mlong-calls -+ KBUILD_CFLAGS_MODULE += -mlong-calls -+ else -+ KBUILD_AFLAGS_MODULE += -mno-long-calls -+ KBUILD_CFLAGS_MODULE += -mno-long-calls -+ endif -+endif - - ifeq ($(CONFIG_RELOCATABLE),y) - LDFLAGS_vmlinux += --emit-relocs ---- a/arch/mips/include/asm/module.h -+++ b/arch/mips/include/asm/module.h -@@ -12,6 +12,11 @@ struct mod_arch_specific { - const struct exception_table_entry *dbe_start; - const struct exception_table_entry *dbe_end; - struct mips_hi16 *r_mips_hi16_list; -+ -+ void *phys_plt_tbl; -+ void *virt_plt_tbl; -+ unsigned int phys_plt_offset; -+ unsigned int virt_plt_offset; - }; - - typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ ---- a/arch/mips/kernel/module.c -+++ b/arch/mips/kernel/module.c -@@ -31,23 +31,261 @@ struct mips_hi16 { - static LIST_HEAD(dbe_list); - static DEFINE_SPINLOCK(dbe_lock); - --#ifdef MODULE_START -+/* -+ * Get the potential max trampolines size required of the init and -+ * non-init sections. Only used if we cannot find enough contiguous -+ * physically mapped memory to put the module into. -+ */ -+static unsigned int -+get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, -+ const char *secstrings, unsigned int symindex, bool is_init) -+{ -+ unsigned long ret = 0; -+ unsigned int i, j; -+ Elf_Sym *syms; -+ -+ /* Everything marked ALLOC (this includes the exported symbols) */ -+ for (i = 1; i < hdr->e_shnum; ++i) { -+ unsigned int info = sechdrs[i].sh_info; -+ -+ if (sechdrs[i].sh_type != SHT_REL -+ && sechdrs[i].sh_type != SHT_RELA) -+ continue; -+ -+ /* Not a valid relocation section? */ -+ if (info >= hdr->e_shnum) -+ continue; -+ -+ /* Don't bother with non-allocated sections */ -+ if (!(sechdrs[info].sh_flags & SHF_ALLOC)) -+ continue; -+ -+ /* If it's called *.init*, and we're not init, we're -+ not interested */ -+ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) -+ != is_init) -+ continue; -+ -+ syms = (Elf_Sym *) sechdrs[symindex].sh_addr; -+ if (sechdrs[i].sh_type == SHT_REL) { -+ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; -+ unsigned int size = sechdrs[i].sh_size / sizeof(*rel); -+ -+ for (j = 0; j < size; ++j) { -+ Elf_Sym *sym; -+ -+ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) -+ continue; -+ -+ sym = syms + ELF_MIPS_R_SYM(rel[j]); -+ if (!is_init && sym->st_shndx != SHN_UNDEF) -+ continue; -+ -+ ret += 4 * sizeof(int); -+ } -+ } else { -+ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; -+ unsigned int size = sechdrs[i].sh_size / sizeof(*rela); -+ -+ for (j = 0; j < size; ++j) { -+ Elf_Sym *sym; -+ -+ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) -+ continue; -+ -+ sym = syms + ELF_MIPS_R_SYM(rela[j]); -+ if (!is_init && sym->st_shndx != SHN_UNDEF) -+ continue; -+ -+ ret += 4 * sizeof(int); -+ } -+ } -+ } -+ -+ return ret; -+} -+ -+#ifndef MODULE_START -+static void *alloc_phys(unsigned long size) -+{ -+ unsigned order; -+ struct page *page; -+ struct page *p; -+ -+ size = PAGE_ALIGN(size); -+ order = get_order(size); -+ -+ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | -+ __GFP_THISNODE, order); -+ if (!page) -+ return NULL; -+ -+ split_page(page, order); -+ -+ /* mark all pages except for the last one */ -+ for (p = page; p + 1 < page + (size >> PAGE_SHIFT); ++p) -+ set_bit(PG_owner_priv_1, &p->flags); -+ -+ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) -+ __free_page(p); -+ -+ return page_address(page); -+} -+#endif -+ -+static void free_phys(void *ptr) -+{ -+ struct page *page; -+ bool free; -+ -+ page = virt_to_page(ptr); -+ do { -+ free = test_and_clear_bit(PG_owner_priv_1, &page->flags); -+ __free_page(page); -+ page++; -+ } while (free); -+} -+ -+ - void *module_alloc(unsigned long size) - { -+#ifdef MODULE_START - return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, - GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, - __builtin_return_address(0)); -+#else -+ void *ptr; -+ -+ if (size == 0) -+ return NULL; -+ -+ ptr = alloc_phys(size); -+ -+ /* If we failed to allocate physically contiguous memory, -+ * fall back to regular vmalloc. The module loader code will -+ * create jump tables to handle long jumps */ -+ if (!ptr) -+ return vmalloc(size); -+ -+ return ptr; -+#endif - } -+ -+static inline bool is_phys_addr(void *ptr) -+{ -+#ifdef CONFIG_64BIT -+ return (KSEGX((unsigned long)ptr) == CKSEG0); -+#else -+ return (KSEGX(ptr) == KSEG0); - #endif -+} -+ -+/* Free memory returned from module_alloc */ -+void module_memfree(void *module_region) -+{ -+ if (is_phys_addr(module_region)) -+ free_phys(module_region); -+ else -+ vfree(module_region); -+} -+ -+static void *__module_alloc(int size, bool phys) -+{ -+ void *ptr; -+ -+ if (phys) -+ ptr = kmalloc(size, GFP_KERNEL); -+ else -+ ptr = vmalloc(size); -+ return ptr; -+} -+ -+static void __module_free(void *ptr) -+{ -+ if (is_phys_addr(ptr)) -+ kfree(ptr); -+ else -+ vfree(ptr); -+} -+ -+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, -+ char *secstrings, struct module *mod) -+{ -+ unsigned int symindex = 0; -+ unsigned int core_size, init_size; -+ int i; -+ -+ mod->arch.phys_plt_offset = 0; -+ mod->arch.virt_plt_offset = 0; -+ mod->arch.phys_plt_tbl = NULL; -+ mod->arch.virt_plt_tbl = NULL; -+ -+ if (IS_ENABLED(CONFIG_64BIT)) -+ return 0; -+ -+ for (i = 1; i < hdr->e_shnum; i++) -+ if (sechdrs[i].sh_type == SHT_SYMTAB) -+ symindex = i; -+ -+ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); -+ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); -+ -+ if ((core_size + init_size) == 0) -+ return 0; -+ -+ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); -+ if (!mod->arch.phys_plt_tbl) -+ return -ENOMEM; -+ -+ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); -+ if (!mod->arch.virt_plt_tbl) { -+ __module_free(mod->arch.phys_plt_tbl); -+ mod->arch.phys_plt_tbl = NULL; -+ return -ENOMEM; -+ } -+ -+ return 0; -+} - - static void apply_r_mips_32(u32 *location, u32 base, Elf_Addr v) - { - *location = base + v; - } - -+static Elf_Addr add_plt_entry_to(unsigned *plt_offset, -+ void *start, Elf_Addr v) -+{ -+ unsigned *tramp = start + *plt_offset; -+ *plt_offset += 4 * sizeof(int); -+ -+ /* adjust carry for addiu */ -+ if (v & 0x00008000) -+ v += 0x10000; -+ -+ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */ -+ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */ -+ tramp[2] = 0x03200008; /* jr t9 */ -+ tramp[3] = 0x00000000; /* nop */ -+ -+ return (Elf_Addr) tramp; -+} -+ -+static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) -+{ -+ if (is_phys_addr(location)) -+ return add_plt_entry_to(&me->arch.phys_plt_offset, -+ me->arch.phys_plt_tbl, v); -+ else -+ return add_plt_entry_to(&me->arch.virt_plt_offset, -+ me->arch.virt_plt_tbl, v); -+ -+} -+ - static int apply_r_mips_26(struct module *me, u32 *location, u32 base, - Elf_Addr v) - { -+ u32 ofs = base & 0x03ffffff; -+ - if (v % 4) { - pr_err("module %s: dangerous R_MIPS_26 relocation\n", - me->name); -@@ -55,13 +293,17 @@ static int apply_r_mips_26(struct module - } - - if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { -- pr_err("module %s: relocation overflow\n", -- me->name); -- return -ENOEXEC; -+ v = add_plt_entry(me, location, v + (ofs << 2)); -+ if (!v) { -+ pr_err("module %s: relocation overflow\n", -+ me->name); -+ return -ENOEXEC; -+ } -+ ofs = 0; - } - - *location = (*location & ~0x03ffffff) | -- ((base + (v >> 2)) & 0x03ffffff); -+ ((ofs + (v >> 2)) & 0x03ffffff); - - return 0; - } -@@ -441,9 +683,36 @@ int module_finalize(const Elf_Ehdr *hdr, - list_add(&me->arch.dbe_list, &dbe_list); - spin_unlock_irq(&dbe_lock); - } -+ -+ /* Get rid of the fixup trampoline if we're running the module -+ * from physically mapped address space */ -+ if (me->arch.phys_plt_offset == 0) { -+ __module_free(me->arch.phys_plt_tbl); -+ me->arch.phys_plt_tbl = NULL; -+ } -+ if (me->arch.virt_plt_offset == 0) { -+ __module_free(me->arch.virt_plt_tbl); -+ me->arch.virt_plt_tbl = NULL; -+ } -+ - return 0; - } - -+void module_arch_freeing_init(struct module *mod) -+{ -+ if (mod->state == MODULE_STATE_LIVE) -+ return; -+ -+ if (mod->arch.phys_plt_tbl) { -+ __module_free(mod->arch.phys_plt_tbl); -+ mod->arch.phys_plt_tbl = NULL; -+ } -+ if (mod->arch.virt_plt_tbl) { -+ __module_free(mod->arch.virt_plt_tbl); -+ mod->arch.virt_plt_tbl = NULL; -+ } -+} -+ - void module_arch_cleanup(struct module *mod) - { - spin_lock_irq(&dbe_lock); diff --git a/target/linux/generic/pending-5.15/308-mips32r2_tune.patch b/target/linux/generic/pending-5.15/308-mips32r2_tune.patch deleted file mode 100644 index ef92a5dfb69b56..00000000000000 --- a/target/linux/generic/pending-5.15/308-mips32r2_tune.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Subject: kernel: add -mtune=34kc to MIPS CFLAGS when building for mips32r2 - -This provides a good tradeoff across at least 24Kc-74Kc, while also -producing smaller code. - -Signed-off-by: Felix Fietkau ---- - arch/mips/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -175,7 +175,7 @@ cflags-$(CONFIG_CPU_VR41XX) += -march=r4 - cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap - cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap - cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap --cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,--trap -+cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -mtune=34kc -Wa,--trap - cflags-$(CONFIG_CPU_MIPS32_R5) += -march=mips32r5 -Wa,--trap -modd-spreg - cflags-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,--trap -modd-spreg - cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap diff --git a/target/linux/generic/pending-5.15/310-arm_module_unresolved_weak_sym.patch b/target/linux/generic/pending-5.15/310-arm_module_unresolved_weak_sym.patch deleted file mode 100644 index 191dc6ac3cd934..00000000000000 --- a/target/linux/generic/pending-5.15/310-arm_module_unresolved_weak_sym.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Subject: fix errors in unresolved weak symbols on arm - -lede-commit: 570699d4838a907c3ef9f2819bf19eb72997b32f -Signed-off-by: Felix Fietkau ---- - arch/arm/kernel/module.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/arm/kernel/module.c -+++ b/arch/arm/kernel/module.c -@@ -105,6 +105,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons - return -ENOEXEC; - } - -+ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) && -+ ELF_ST_BIND(sym->st_info) == STB_WEAK) -+ continue; -+ - loc = dstsec->sh_addr + rel->r_offset; - - switch (ELF32_R_TYPE(rel->r_info)) { diff --git a/target/linux/generic/pending-5.15/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch b/target/linux/generic/pending-5.15/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch deleted file mode 100644 index 3f553b28b34be7..00000000000000 --- a/target/linux/generic/pending-5.15/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch +++ /dev/null @@ -1,282 +0,0 @@ -From: Yousong Zhou -Subject: MIPS: kexec: Accept command line parameters from userspace. - -Signed-off-by: Yousong Zhou ---- - arch/mips/kernel/machine_kexec.c | 153 +++++++++++++++++++++++++++++++----- - arch/mips/kernel/machine_kexec.h | 20 +++++ - arch/mips/kernel/relocate_kernel.S | 21 +++-- - 3 files changed, 167 insertions(+), 27 deletions(-) - create mode 100644 arch/mips/kernel/machine_kexec.h - ---- a/arch/mips/kernel/machine_kexec.c -+++ b/arch/mips/kernel/machine_kexec.c -@@ -9,14 +9,11 @@ - #include - #include - -+#include - #include - #include -- --extern const unsigned char relocate_new_kernel[]; --extern const size_t relocate_new_kernel_size; -- --extern unsigned long kexec_start_address; --extern unsigned long kexec_indirection_page; -+#include -+#include "machine_kexec.h" - - static unsigned long reboot_code_buffer; - -@@ -30,6 +27,101 @@ void (*_crash_smp_send_stop)(void) = NUL - void (*_machine_kexec_shutdown)(void) = NULL; - void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL; - -+static void machine_kexec_print_args(void) -+{ -+ unsigned long argc = (int)kexec_args[0]; -+ int i; -+ -+ pr_info("kexec_args[0] (argc): %lu\n", argc); -+ pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]); -+ pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]); -+ pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]); -+ -+ for (i = 0; i < argc; i++) { -+ pr_info("kexec_argv[%d] = %p, %s\n", -+ i, kexec_argv[i], kexec_argv[i]); -+ } -+} -+ -+static void machine_kexec_init_argv(struct kimage *image) -+{ -+ void __user *buf = NULL; -+ size_t bufsz; -+ size_t size; -+ int i; -+ -+ bufsz = 0; -+ for (i = 0; i < image->nr_segments; i++) { -+ struct kexec_segment *seg; -+ -+ seg = &image->segment[i]; -+ if (seg->bufsz < 6) -+ continue; -+ -+ if (strncmp((char *) seg->buf, "kexec ", 6)) -+ continue; -+ -+ buf = seg->buf; -+ bufsz = seg->bufsz; -+ break; -+ } -+ -+ if (!buf) -+ return; -+ -+ size = KEXEC_COMMAND_LINE_SIZE; -+ size = min(size, bufsz); -+ if (size < bufsz) -+ pr_warn("kexec command line truncated to %zd bytes\n", size); -+ -+ /* Copy to kernel space */ -+ if (copy_from_user(kexec_argv_buf, buf, size)) -+ pr_warn("kexec command line copy to kernel space failed\n"); -+ -+ kexec_argv_buf[size - 1] = 0; -+} -+ -+static void machine_kexec_parse_argv(struct kimage *image) -+{ -+ char *reboot_code_buffer; -+ int reloc_delta; -+ char *ptr; -+ int argc; -+ int i; -+ -+ ptr = kexec_argv_buf; -+ argc = 0; -+ -+ /* -+ * convert command line string to array of parameters -+ * (as bootloader does). -+ */ -+ while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) { -+ if (*ptr == ' ') { -+ *ptr++ = '\0'; -+ continue; -+ } -+ -+ kexec_argv[argc++] = ptr; -+ ptr = strchr(ptr, ' '); -+ } -+ -+ if (!argc) -+ return; -+ -+ kexec_args[0] = argc; -+ kexec_args[1] = (unsigned long)kexec_argv; -+ kexec_args[2] = 0; -+ kexec_args[3] = 0; -+ -+ reboot_code_buffer = page_address(image->control_code_page); -+ reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel; -+ -+ kexec_args[1] += reloc_delta; -+ for (i = 0; i < argc; i++) -+ kexec_argv[i] += reloc_delta; -+} -+ - static void kexec_image_info(const struct kimage *kimage) - { - unsigned long i; -@@ -99,6 +191,18 @@ machine_kexec_prepare(struct kimage *kim - #endif - - kexec_image_info(kimage); -+ /* -+ * Whenever arguments passed from kexec-tools, Init the arguments as -+ * the original ones to try avoiding booting failure. -+ */ -+ -+ kexec_args[0] = fw_arg0; -+ kexec_args[1] = fw_arg1; -+ kexec_args[2] = fw_arg2; -+ kexec_args[3] = fw_arg3; -+ -+ machine_kexec_init_argv(kimage); -+ machine_kexec_parse_argv(kimage); - - if (_machine_kexec_prepare) - return _machine_kexec_prepare(kimage); -@@ -161,7 +265,7 @@ machine_crash_shutdown(struct pt_regs *r - void kexec_nonboot_cpu_jump(void) - { - local_flush_icache_range((unsigned long)relocated_kexec_smp_wait, -- reboot_code_buffer + relocate_new_kernel_size); -+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE); - - relocated_kexec_smp_wait(NULL); - } -@@ -199,7 +303,7 @@ void kexec_reboot(void) - * machine_kexec() CPU. - */ - local_flush_icache_range(reboot_code_buffer, -- reboot_code_buffer + relocate_new_kernel_size); -+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE); - - do_kexec = (void *)reboot_code_buffer; - do_kexec(); -@@ -212,10 +316,12 @@ machine_kexec(struct kimage *image) - unsigned long *ptr; - - reboot_code_buffer = -- (unsigned long)page_address(image->control_code_page); -+ (unsigned long)page_address(image->control_code_page); -+ pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer); - - kexec_start_address = - (unsigned long) phys_to_virt(image->start); -+ pr_info("kexec_start_address = %p\n", (void *)kexec_start_address); - - if (image->type == KEXEC_TYPE_DEFAULT) { - kexec_indirection_page = -@@ -223,9 +329,19 @@ machine_kexec(struct kimage *image) - } else { - kexec_indirection_page = (unsigned long)&image->head; - } -+ pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page); - -- memcpy((void*)reboot_code_buffer, relocate_new_kernel, -- relocate_new_kernel_size); -+ pr_info("Where is memcpy: %p\n", memcpy); -+ pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n", -+ (void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end); -+ pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE, -+ (void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer); -+ memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel, -+ KEXEC_RELOCATE_NEW_KERNEL_SIZE); -+ -+ pr_info("Before _print_args().\n"); -+ machine_kexec_print_args(); -+ pr_info("Before eval loop.\n"); - - /* - * The generic kexec code builds a page list with physical -@@ -256,7 +372,7 @@ machine_kexec(struct kimage *image) - #ifdef CONFIG_SMP - /* All secondary cpus now may jump to kexec_wait cycle */ - relocated_kexec_smp_wait = reboot_code_buffer + -- (void *)(kexec_smp_wait - relocate_new_kernel); -+ (void *)(kexec_smp_wait - kexec_relocate_new_kernel); - smp_wmb(); - atomic_set(&kexec_ready_to_reboot, 1); - #endif ---- /dev/null -+++ b/arch/mips/kernel/machine_kexec.h -@@ -0,0 +1,20 @@ -+#ifndef _MACHINE_KEXEC_H -+#define _MACHINE_KEXEC_H -+ -+#ifndef __ASSEMBLY__ -+extern const unsigned char kexec_relocate_new_kernel[]; -+extern unsigned long kexec_relocate_new_kernel_end; -+extern unsigned long kexec_start_address; -+extern unsigned long kexec_indirection_page; -+ -+extern char kexec_argv_buf[]; -+extern char *kexec_argv[]; -+ -+#define KEXEC_RELOCATE_NEW_KERNEL_SIZE ((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel) -+#endif /* !__ASSEMBLY__ */ -+ -+#define KEXEC_COMMAND_LINE_SIZE 256 -+#define KEXEC_ARGV_SIZE (KEXEC_COMMAND_LINE_SIZE / 16) -+#define KEXEC_MAX_ARGC (KEXEC_ARGV_SIZE / sizeof(long)) -+ -+#endif ---- a/arch/mips/kernel/relocate_kernel.S -+++ b/arch/mips/kernel/relocate_kernel.S -@@ -10,10 +10,11 @@ - #include - #include - #include -+#include "machine_kexec.h" - - #include - --LEAF(relocate_new_kernel) -+LEAF(kexec_relocate_new_kernel) - PTR_L a0, arg0 - PTR_L a1, arg1 - PTR_L a2, arg2 -@@ -98,7 +99,7 @@ done: - #endif - /* jump to kexec_start_address */ - j s1 -- END(relocate_new_kernel) -+ END(kexec_relocate_new_kernel) - - #ifdef CONFIG_SMP - /* -@@ -177,8 +178,15 @@ EXPORT(kexec_indirection_page) - PTR_WD 0 - .size kexec_indirection_page, PTRSIZE - --relocate_new_kernel_end: -+kexec_argv_buf: -+ EXPORT(kexec_argv_buf) -+ .skip KEXEC_COMMAND_LINE_SIZE -+ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE -+ -+kexec_argv: -+ EXPORT(kexec_argv) -+ .skip KEXEC_ARGV_SIZE -+ .size kexec_argv, KEXEC_ARGV_SIZE - --EXPORT(relocate_new_kernel_size) -- PTR_WD relocate_new_kernel_end - relocate_new_kernel -- .size relocate_new_kernel_size, PTRSIZE -+kexec_relocate_new_kernel_end: -+ EXPORT(kexec_relocate_new_kernel_end) diff --git a/target/linux/generic/pending-5.15/332-arc-add-OWRTDTB-section.patch b/target/linux/generic/pending-5.15/332-arc-add-OWRTDTB-section.patch deleted file mode 100644 index 30158cf399b1f2..00000000000000 --- a/target/linux/generic/pending-5.15/332-arc-add-OWRTDTB-section.patch +++ /dev/null @@ -1,84 +0,0 @@ -From bb0c3b0175240bf152fd7c644821a0cf9f77c37c Mon Sep 17 00:00:00 2001 -From: Evgeniy Didin -Date: Fri, 15 Mar 2019 18:53:38 +0300 -Subject: [PATCH] arc add OWRTDTB section - -This change allows OpenWRT to patch resulting kernel binary with -external .dtb. - -That allows us to re-use exactky the same vmlinux on different boards -given its ARC core configurations match (at least cache line sizes etc). - -""patch-dtb" searches for ASCII "OWRTDTB:" strign and copies external -.dtb right after it, keeping the string in place. - -Signed-off-by: Eugeniy Paltsev -Signed-off-by: Alexey Brodkin -Signed-off-by: Evgeniy Didin ---- - arch/arc/kernel/head.S | 10 ++++++++++ - arch/arc/kernel/setup.c | 4 +++- - arch/arc/kernel/vmlinux.lds.S | 13 +++++++++++++ - 3 files changed, 26 insertions(+), 1 deletion(-) - ---- a/arch/arc/kernel/head.S -+++ b/arch/arc/kernel/head.S -@@ -88,6 +88,16 @@ - DSP_EARLY_INIT - .endm - -+ ; Here "patch-dtb" will embed external .dtb -+ ; Note "patch-dtb" searches for ASCII "OWRTDTB:" string -+ ; and pastes .dtb right after it, hense the string precedes -+ ; __image_dtb symbol. -+ .section .owrt, "aw",@progbits -+ .ascii "OWRTDTB:" -+ENTRY(__image_dtb) -+ .fill 0x4000 -+END(__image_dtb) -+ - .section .init.text, "ax",@progbits - - ;---------------------------------------------------------------- ---- a/arch/arc/kernel/setup.c -+++ b/arch/arc/kernel/setup.c -@@ -495,6 +495,8 @@ static inline bool uboot_arg_invalid(uns - /* We always pass 0 as magic from U-boot */ - #define UBOOT_MAGIC_VALUE 0 - -+extern struct boot_param_header __image_dtb; -+ - void __init handle_uboot_args(void) - { - bool use_embedded_dtb = true; -@@ -533,7 +535,7 @@ void __init handle_uboot_args(void) - ignore_uboot_args: - - if (use_embedded_dtb) { -- machine_desc = setup_machine_fdt(__dtb_start); -+ machine_desc = setup_machine_fdt(&__image_dtb); - if (!machine_desc) - panic("Embedded DT invalid\n"); - } ---- a/arch/arc/kernel/vmlinux.lds.S -+++ b/arch/arc/kernel/vmlinux.lds.S -@@ -27,6 +27,19 @@ SECTIONS - - . = CONFIG_LINUX_LINK_BASE; - -+ /* -+ * In OpenWRT we want to patch built binary embedding .dtb of choice. -+ * This is implemented with "patch-dtb" utility which searches for -+ * "OWRTDTB:" string in first 16k of image and if it is found -+ * copies .dtb right after mentioned string. -+ * -+ * Note: "OWRTDTB:" won't be overwritten with .dtb, .dtb will follow it. -+ */ -+ .owrt : { -+ *(.owrt) -+ . = ALIGN(PAGE_SIZE); -+ } -+ - _int_vec_base_lds = .; - .vector : { - *(.vector) diff --git a/target/linux/generic/pending-5.15/333-arc-enable-unaligned-access-in-kernel-mode.patch b/target/linux/generic/pending-5.15/333-arc-enable-unaligned-access-in-kernel-mode.patch deleted file mode 100644 index 1848a84cc4970f..00000000000000 --- a/target/linux/generic/pending-5.15/333-arc-enable-unaligned-access-in-kernel-mode.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Alexey Brodkin -Subject: arc: enable unaligned access in kernel mode - -This enables misaligned access handling even in kernel mode. -Some wireless drivers (ath9k-htc and mt7601u) use misaligned accesses -here and there and to cope with that without fixing stuff in the drivers -we're just gracefully handling it on ARC. - -Signed-off-by: Alexey Brodkin ---- - arch/arc/kernel/unaligned.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arc/kernel/unaligned.c -+++ b/arch/arc/kernel/unaligned.c -@@ -202,7 +202,7 @@ int misaligned_fixup(unsigned long addre - char buf[TASK_COMM_LEN]; - - /* handle user mode only and only if enabled by sysadmin */ -- if (!user_mode(regs) || !unaligned_enabled) -+ if (!unaligned_enabled) - return 1; - - if (no_unaligned_warning) { diff --git a/target/linux/generic/pending-5.15/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch b/target/linux/generic/pending-5.15/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch deleted file mode 100644 index 082b122cb4d3db..00000000000000 --- a/target/linux/generic/pending-5.15/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 66770a004afe10df11d3902e16eaa0c2c39436bb Mon Sep 17 00:00:00 2001 -From: Pawel Dembicki -Date: Fri, 24 May 2019 17:56:19 +0200 -Subject: [PATCH] powerpc: Enable kernel XZ compression option on PPC_85xx - -Enable kernel XZ compression option on PPC_85xx. Tested with -simpleImage on TP-Link TL-WDR4900 (Freescale P1014 processor). - -Suggested-by: Christian Lamparter -Signed-off-by: Pawel Dembicki ---- - arch/powerpc/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/powerpc/Kconfig -+++ b/arch/powerpc/Kconfig -@@ -221,7 +221,7 @@ config PPC - select HAVE_KERNEL_GZIP - select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE - select HAVE_KERNEL_LZO if DEFAULT_UIMAGE -- select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x -+ select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x || PPC_85xx - select HAVE_KPROBES - select HAVE_KPROBES_ON_FTRACE - select HAVE_KRETPROBES diff --git a/target/linux/generic/pending-5.15/351-irqchip-bcm-6345-l1-request-memory-region.patch b/target/linux/generic/pending-5.15/351-irqchip-bcm-6345-l1-request-memory-region.patch deleted file mode 100644 index 91654cc294c31f..00000000000000 --- a/target/linux/generic/pending-5.15/351-irqchip-bcm-6345-l1-request-memory-region.patch +++ /dev/null @@ -1,113 +0,0 @@ -From patchwork Thu Mar 16 19:28:33 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13178238 -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 5EF2AC6FD19 - for ; Thu, 16 Mar 2023 19:28:43 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S230076AbjCPT2l (ORCPT ); - Thu, 16 Mar 2023 15:28:41 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56412 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S230039AbjCPT2k (ORCPT - ); Thu, 16 Mar 2023 15:28:40 -0400 -Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com - [IPv6:2a00:1450:4864:20::42f]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7259B7D9F; - Thu, 16 Mar 2023 12:28:38 -0700 (PDT) -Received: by mail-wr1-x42f.google.com with SMTP id y14so2539231wrq.4; - Thu, 16 Mar 2023 12:28:38 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1678994917; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=j8afldfRZftLeVmekmQfoh01jVdumsVP7nkKoPaU3Q0=; - b=FzMRr5ekh/fDiJqTlezNj6nLjzvn5z92FtYeB8MquVSMB8PuvarccnyqAzsXiccf+v - uwRFIomnTWNLGVjzc1xrB2hGiCKD3jBo5n1u8p/yEV6rpolbxVjfM7eTHXyAHXGXz7ZJ - TPeVbWfAlxiSD6+BPtXr/efehcdI64fIoL6G/U1WHNMo01Tzr/Obf3y5tug17N0fGcXg - CH6E5a2HguZUtwrm26LcK9IOV/7xEx5eIE1cOvTLMxPbGWaZwEjjP16HylJr06xRLhaf - RpiYBT3mXwwuOx0jLOhqavY/2kZ9GVbZRWMMwZrZv9xNO13SBwc1VUVgD4k3FntnSk7Z - AaOQ== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1678994917; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=j8afldfRZftLeVmekmQfoh01jVdumsVP7nkKoPaU3Q0=; - b=OaA5DMgqalrfqO5iOtmmxFPsH90MkN7l4EJpyVnzuiO1Wd6rSCpqPOR7xpxZno8OPP - tdfm4vzn9Ie4AUDbFKDTUlPG+tgkmIruo3K9C0VnY9DD2PRZMEYBbWaJKU1otqKt0NKu - IAAHNvxvQvCESKzbXFLYwWbRKFScOSMGmGBTDfgThz51A18Ff1hJy/BmnuZk7M2TLgHO - wQpy9t7oeB/Hkxl41y46emLc/nESsvwvAG/fx/zPzCe9UiaQLrdZq+BKeOwSBedktzK5 - U/ZTfgzU2UGSI67aGRqqGnI0uXq+MAJMK18qzM0VByxj6W+AXJ6BJr5P0quljeQ8upSg - bEUg== -X-Gm-Message-State: AO0yUKWnqTlccBDnqwCSRdqOBGc2FyfiLy1Tg7EjPENlISpzXuDYwW/R - lJSI06rrfq+Vel/SigfpGJI= -X-Google-Smtp-Source: - AK7set/jYfYl9ttVzIXJO+ZQVfa6cE/yOsP8fx4teiTmGNNWyVlIJRzMAlF3IUGqRAXAmY3hAabIuQ== -X-Received: by 2002:a5d:40ce:0:b0:2cd:ceab:df1a with SMTP id - b14-20020a5d40ce000000b002cdceabdf1amr381006wrq.32.1678994916642; - Thu, 16 Mar 2023 12:28:36 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - l10-20020a5d4bca000000b002cfea3c49d5sm180041wrt.52.2023.03.16.12.28.35 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Thu, 16 Mar 2023 12:28:35 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: f.fainelli@gmail.com, jonas.gorski@gmail.com, - bcm-kernel-feedback-list@broadcom.com, tglx@linutronix.de, - maz@kernel.org, linux-mips@vger.kernel.org, - linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v2] irqchip/bcm-6345-l1: request memory region -Date: Thu, 16 Mar 2023 20:28:33 +0100 -Message-Id: <20230316192833.1603149-1-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230316180701.783785-1-noltari@gmail.com> -References: <20230316180701.783785-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: linux-mips@vger.kernel.org - -Request memory region in order to display it in /proc/iomem. -Also stop printing the MMIO address since it just displays (ptrval). - -Signed-off-by: Álvaro Fernández Rojas -Acked-by: Florian Fainelli ---- - v2: request memory region and stop displaying MMIO address. - - drivers/irqchip/irq-bcm6345-l1.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/irqchip/irq-bcm6345-l1.c -+++ b/drivers/irqchip/irq-bcm6345-l1.c -@@ -257,6 +257,9 @@ static int __init bcm6345_l1_init_one(st - if (!cpu->map_base) - return -ENOMEM; - -+ if (!request_mem_region(res.start, sz, res.name)) -+ pr_err("failed to request intc memory"); -+ - for (i = 0; i < n_words; i++) { - cpu->enable_cache[i] = 0; - __raw_writel(0, cpu->map_base + reg_enable(intc, i)); -@@ -335,8 +338,7 @@ static int __init bcm6345_l1_of_init(str - for_each_cpu(idx, &intc->cpumask) { - struct bcm6345_l1_cpu *cpu = intc->cpus[idx]; - -- pr_info(" CPU%u at MMIO 0x%p (irq = %d)\n", idx, -- cpu->map_base, cpu->parent_irq); -+ pr_info(" CPU%u (irq = %d)\n", idx, cpu->parent_irq); - } - - return 0; diff --git a/target/linux/generic/pending-5.15/400-mtd-mtdsplit-support.patch b/target/linux/generic/pending-5.15/400-mtd-mtdsplit-support.patch deleted file mode 100644 index 46ef15d127dfb6..00000000000000 --- a/target/linux/generic/pending-5.15/400-mtd-mtdsplit-support.patch +++ /dev/null @@ -1,328 +0,0 @@ -From 39717277d5c87bdb183cf2f258957b44ba99b4df Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 11:47:35 +0200 -Subject: [PATCH] mtd: mtdsplit support - ---- - drivers/mtd/Kconfig | 19 ++++ - drivers/mtd/Makefile | 2 + - drivers/mtd/mtdpart.c | 169 ++++++++++++++++++++++++++++----- - include/linux/mtd/mtd.h | 25 +++++ - include/linux/mtd/partitions.h | 7 ++ - 5 files changed, 197 insertions(+), 25 deletions(-) - ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -12,6 +12,25 @@ menuconfig MTD - - if MTD - -+menu "OpenWrt specific MTD options" -+ -+config MTD_ROOTFS_ROOT_DEV -+ bool "Automatically set 'rootfs' partition to be root filesystem" -+ default y -+ -+config MTD_SPLIT_FIRMWARE -+ bool "Automatically split firmware partition for kernel+rootfs" -+ default y -+ -+config MTD_SPLIT_FIRMWARE_NAME -+ string "Firmware partition name" -+ depends on MTD_SPLIT_FIRMWARE -+ default "firmware" -+ -+source "drivers/mtd/mtdsplit/Kconfig" -+ -+endmenu -+ - config MTD_TESTS - tristate "MTD tests support (DANGEROUS)" - depends on m ---- a/drivers/mtd/Makefile -+++ b/drivers/mtd/Makefile -@@ -9,6 +9,8 @@ mtd-y := mtdcore.o mtdsuper.o mtdconc - - obj-y += parsers/ - -+obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ -+ - # 'Users' - code which presents functionality to userspace. - obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o - obj-$(CONFIG_MTD_BLOCK) += mtdblock.o ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -15,11 +15,13 @@ - #include - #include - #include -+#include - #include - #include - #include - - #include "mtdcore.h" -+#include "mtdsplit/mtdsplit.h" - - /* - * MTD methods which simply translate the effective address and pass through -@@ -236,6 +238,147 @@ static int mtd_add_partition_attrs(struc - return ret; - } - -+static DEFINE_SPINLOCK(part_parser_lock); -+static LIST_HEAD(part_parsers); -+ -+static struct mtd_part_parser *mtd_part_parser_get(const char *name) -+{ -+ struct mtd_part_parser *p, *ret = NULL; -+ -+ spin_lock(&part_parser_lock); -+ -+ list_for_each_entry(p, &part_parsers, list) -+ if (!strcmp(p->name, name) && try_module_get(p->owner)) { -+ ret = p; -+ break; -+ } -+ -+ spin_unlock(&part_parser_lock); -+ -+ return ret; -+} -+ -+static inline void mtd_part_parser_put(const struct mtd_part_parser *p) -+{ -+ module_put(p->owner); -+} -+ -+static struct mtd_part_parser * -+get_partition_parser_by_type(enum mtd_parser_type type, -+ struct mtd_part_parser *start) -+{ -+ struct mtd_part_parser *p, *ret = NULL; -+ -+ spin_lock(&part_parser_lock); -+ -+ p = list_prepare_entry(start, &part_parsers, list); -+ if (start) -+ mtd_part_parser_put(start); -+ -+ list_for_each_entry_continue(p, &part_parsers, list) { -+ if (p->type == type && try_module_get(p->owner)) { -+ ret = p; -+ break; -+ } -+ } -+ -+ spin_unlock(&part_parser_lock); -+ -+ return ret; -+} -+ -+static int parse_mtd_partitions_by_type(struct mtd_info *master, -+ enum mtd_parser_type type, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_part_parser *prev = NULL; -+ int ret = 0; -+ -+ while (1) { -+ struct mtd_part_parser *parser; -+ -+ parser = get_partition_parser_by_type(type, prev); -+ if (!parser) -+ break; -+ -+ ret = (*parser->parse_fn)(master, pparts, data); -+ -+ if (ret > 0) { -+ mtd_part_parser_put(parser); -+ printk(KERN_NOTICE -+ "%d %s partitions found on MTD device %s\n", -+ ret, parser->name, master->name); -+ break; -+ } -+ -+ prev = parser; -+ } -+ -+ return ret; -+} -+ -+static int -+run_parsers_by_type(struct mtd_info *child, enum mtd_parser_type type) -+{ -+ struct mtd_partition *parts; -+ int nr_parts; -+ int i; -+ -+ nr_parts = parse_mtd_partitions_by_type(child, type, (const struct mtd_partition **)&parts, -+ NULL); -+ if (nr_parts <= 0) -+ return nr_parts; -+ -+ if (WARN_ON(!parts)) -+ return 0; -+ -+ for (i = 0; i < nr_parts; i++) { -+ /* adjust partition offsets */ -+ parts[i].offset += child->part.offset; -+ -+ mtd_add_partition(child->parent, -+ parts[i].name, -+ parts[i].offset, -+ parts[i].size); -+ } -+ -+ kfree(parts); -+ -+ return nr_parts; -+} -+ -+#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#else -+#define SPLIT_FIRMWARE_NAME "unused" -+#endif -+ -+static void split_firmware(struct mtd_info *master, struct mtd_info *part) -+{ -+ run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); -+} -+ -+static void mtd_partition_split(struct mtd_info *master, struct mtd_info *part) -+{ -+ static int rootfs_found = 0; -+ -+ if (rootfs_found) -+ return; -+ -+ if (of_find_property(mtd_get_of_node(part), "linux,rootfs", NULL) || -+ !strcmp(part->name, "rootfs")) { -+ run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); -+ -+ rootfs_found = 1; -+ } -+ -+ if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) && -+ !strcmp(part->name, SPLIT_FIRMWARE_NAME) && -+ !of_find_property(mtd_get_of_node(part), "compatible", NULL)) -+ split_firmware(master, part); -+} -+ - int mtd_add_partition(struct mtd_info *parent, const char *name, - long long offset, long long length) - { -@@ -274,6 +417,7 @@ int mtd_add_partition(struct mtd_info *p - if (ret) - goto err_remove_part; - -+ mtd_partition_split(parent, child); - mtd_add_partition_attrs(child); - - return 0; -@@ -422,6 +566,7 @@ int add_mtd_partitions(struct mtd_info * - goto err_del_partitions; - } - -+ mtd_partition_split(master, child); - mtd_add_partition_attrs(child); - - /* Look for subpartitions */ -@@ -438,31 +583,6 @@ err_del_partitions: - return ret; - } - --static DEFINE_SPINLOCK(part_parser_lock); --static LIST_HEAD(part_parsers); -- --static struct mtd_part_parser *mtd_part_parser_get(const char *name) --{ -- struct mtd_part_parser *p, *ret = NULL; -- -- spin_lock(&part_parser_lock); -- -- list_for_each_entry(p, &part_parsers, list) -- if (!strcmp(p->name, name) && try_module_get(p->owner)) { -- ret = p; -- break; -- } -- -- spin_unlock(&part_parser_lock); -- -- return ret; --} -- --static inline void mtd_part_parser_put(const struct mtd_part_parser *p) --{ -- module_put(p->owner); --} -- - /* - * Many partition parsers just expected the core to kfree() all their data in - * one chunk. Do that by default. ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -620,6 +620,24 @@ static inline void mtd_align_erase_req(s - req->len += mtd->erasesize - mod; - } - -+static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd) -+{ -+ if (mtd_mod_by_eb(sz, mtd) == 0) -+ return sz; -+ -+ /* Round up to next erase block */ -+ return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize; -+} -+ -+static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd) -+{ -+ if (mtd_mod_by_eb(sz, mtd) == 0) -+ return sz; -+ -+ /* Round down to the start of the current erase block */ -+ return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize; -+} -+ - static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) - { - if (mtd->writesize_shift) -@@ -693,6 +711,13 @@ extern struct mtd_info *of_get_mtd_devic - extern struct mtd_info *get_mtd_device_nm(const char *name); - extern void put_mtd_device(struct mtd_info *mtd); - -+static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd) -+{ -+ if (!mtd_is_partition(mtd)) -+ return 0; -+ -+ return mtd->part.offset; -+} - - struct mtd_notifier { - void (*add)(struct mtd_info *mtd); ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -75,6 +75,12 @@ struct mtd_part_parser_data { - * Functions dealing with the various ways of partitioning the space - */ - -+enum mtd_parser_type { -+ MTD_PARSER_TYPE_DEVICE = 0, -+ MTD_PARSER_TYPE_ROOTFS, -+ MTD_PARSER_TYPE_FIRMWARE, -+}; -+ - struct mtd_part_parser { - struct list_head list; - struct module *owner; -@@ -83,6 +89,7 @@ struct mtd_part_parser { - int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, - struct mtd_part_parser_data *); - void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); -+ enum mtd_parser_type type; - }; - - /* Container for passing around a set of parsed partitions */ diff --git a/target/linux/generic/pending-5.15/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch b/target/linux/generic/pending-5.15/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch deleted file mode 100644 index 650e10a3a5d852..00000000000000 --- a/target/linux/generic/pending-5.15/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 31 Oct 2023 15:51:01 +0100 -Subject: [PATCH] mtd: don't register NVMEM devices for partitions with custom - drivers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes issue exposed by upstream commit f4cf4e5db331 ("Revert -"nvmem: add new config option""). - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/mtdcore.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -537,6 +537,29 @@ static int mtd_nvmem_add(struct mtd_info - struct device_node *node = mtd_get_of_node(mtd); - struct nvmem_config config = {}; - -+ /* -+ * Do NOT register NVMEM device for any partition that is meant to be -+ * handled by a U-Boot env driver. That would result in associating two -+ * different NVMEM devices with the same OF node. -+ * -+ * An example of unwanted behaviour of above (forwardtrace): -+ * of_get_mac_addr_nvmem() -+ * of_nvmem_cell_get() -+ * __nvmem_device_get() -+ * -+ * We can't have __nvmem_device_get() return "mtdX" NVMEM device instead -+ * of U-Boot env NVMEM device. That would result in failing to find -+ * NVMEM cell. -+ * -+ * This issue seems to affect U-Boot env case only and will go away with -+ * switch to NVMEM layouts. -+ */ -+ if (of_device_is_compatible(node, "u-boot,env") || -+ of_device_is_compatible(node, "u-boot,env-redundant-bool") || -+ of_device_is_compatible(node, "u-boot,env-redundant-count") || -+ of_device_is_compatible(node, "brcm,env")) -+ return 0; -+ - config.id = -1; - config.dev = &mtd->dev; - config.name = dev_name(&mtd->dev); diff --git a/target/linux/generic/pending-5.15/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch b/target/linux/generic/pending-5.15/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch deleted file mode 100644 index 0a12132de36b56..00000000000000 --- a/target/linux/generic/pending-5.15/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch +++ /dev/null @@ -1,245 +0,0 @@ -From acacdac272927ae1d96e0bca51eb82899671eaea Mon Sep 17 00:00:00 2001 -From: John Thomson -Date: Fri, 25 Dec 2020 18:50:08 +1000 -Subject: [PATCH] mtd: spi-nor: write support for minor aligned partitions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Do not prevent writing to mtd partitions where a partition boundary sits -on a minor erasesize boundary. -This addresses a FIXME that has been present since the start of the -linux git history: -/* Doesn't start on a boundary of major erase size */ -/* FIXME: Let it be writable if it is on a boundary of - * _minor_ erase size though */ - -Allow a uniform erase region spi-nor device to be configured -to use the non-uniform erase regions code path for an erase with: -CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y - -On supporting hardware (SECT_4K: majority of current SPI-NOR device) -provide the facility for an erase to use the least number -of SPI-NOR operations, as well as access to 4K erase without -requiring CONFIG_MTD_SPI_NOR_USE_4K_SECTORS - -Introduce erasesize_minor to the mtd struct, -the smallest erasesize supported by the device - -On existing devices, this is useful where write support is wanted -for data on a 4K partition, such as some u-boot-env partitions, -or RouterBoot soft_config, while still netting the performance -benefits of using 64K sectors - -Performance: -time mtd erase firmware -OpenWrt 5.10 ramips MT7621 w25q128jv 0xfc0000 partition length - -Without this patch -MTD_SPI_NOR_USE_4K_SECTORS=y |n -real 2m 11.66s |0m 50.86s -user 0m 0.00s |0m 0.00s -sys 1m 56.20s |0m 50.80s - -With this patch -MTD_SPI_NOR_USE_VARIABLE_ERASE=n|y |4K_SECTORS=y -real 0m 51.68s |0m 50.85s |2m 12.89s -user 0m 0.00s |0m 0.00s |0m 0.01s -sys 0m 46.94s |0m 50.38s |2m 12.46s - -Signed-off-by: John Thomson -Signed-off-by: Thibaut VARÈNE - ---- - -checkpatch does not like the printk(KERN_WARNING -these should be changed separately beforehand? - -Changes v1 -> v2: -Added mtdcore sysfs for erasesize_minor -Removed finding minor erasesize for variable erase regions device, -as untested and no responses regarding it. -Moved IF_ENABLED for SPINOR variable erase to guard setting -erasesize_minor in spi-nor/core.c -Removed setting erasesize to minor where partition boundaries require -minor erase to be writable -Simplified minor boundary check by relying on minor being a factor of -major - -Changes RFC -> v1: -Fix uninitialized variable smatch warning -Reported-by: kernel test robot -Reported-by: Dan Carpenter ---- - drivers/mtd/mtdcore.c | 10 ++++++++++ - drivers/mtd/mtdpart.c | 35 +++++++++++++++++++++++++---------- - drivers/mtd/spi-nor/Kconfig | 10 ++++++++++ - drivers/mtd/spi-nor/core.c | 11 +++++++++-- - include/linux/mtd/mtd.h | 2 ++ - 5 files changed, 56 insertions(+), 12 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -169,6 +169,15 @@ static ssize_t mtd_erasesize_show(struct - } - MTD_DEVICE_ATTR_RO(erasesize); - -+static ssize_t mtd_erasesize_minor_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct mtd_info *mtd = dev_get_drvdata(dev); -+ -+ return sysfs_emit(buf, "%lu\n", (unsigned long)mtd->erasesize_minor); -+} -+MTD_DEVICE_ATTR_RO(erasesize_minor); -+ - static ssize_t mtd_writesize_show(struct device *dev, - struct device_attribute *attr, char *buf) - { -@@ -314,6 +323,7 @@ static struct attribute *mtd_attrs[] = { - &dev_attr_flags.attr, - &dev_attr_size.attr, - &dev_attr_erasesize.attr, -+ &dev_attr_erasesize_minor.attr, - &dev_attr_writesize.attr, - &dev_attr_subpagesize.attr, - &dev_attr_oobsize.attr, ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -41,6 +41,7 @@ static struct mtd_info *allocate_partiti - struct mtd_info *master = mtd_get_master(parent); - int wr_alignment = (parent->flags & MTD_NO_ERASE) ? - master->writesize : master->erasesize; -+ int wr_alignment_minor = 0; - u64 parent_size = mtd_is_partition(parent) ? - parent->part.size : parent->size; - struct mtd_info *child; -@@ -165,6 +166,7 @@ static struct mtd_info *allocate_partiti - } else { - /* Single erase size */ - child->erasesize = master->erasesize; -+ child->erasesize_minor = master->erasesize_minor; - } - - /* -@@ -172,26 +174,39 @@ static struct mtd_info *allocate_partiti - * exposes several regions with different erasesize. Adjust - * wr_alignment accordingly. - */ -- if (!(child->flags & MTD_NO_ERASE)) -+ if (!(child->flags & MTD_NO_ERASE)) { - wr_alignment = child->erasesize; -+ wr_alignment_minor = child->erasesize_minor; -+ } - - tmp = mtd_get_master_ofs(child, 0); - remainder = do_div(tmp, wr_alignment); - if ((child->flags & MTD_WRITEABLE) && remainder) { -- /* Doesn't start on a boundary of major erase size */ -- /* FIXME: Let it be writable if it is on a boundary of -- * _minor_ erase size though */ -- child->flags &= ~MTD_WRITEABLE; -- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", -- part->name); -+ if (wr_alignment_minor) { -+ /* rely on minor being a factor of major erasesize */ -+ tmp = remainder; -+ remainder = do_div(tmp, wr_alignment_minor); -+ } -+ if (remainder) { -+ child->flags &= ~MTD_WRITEABLE; -+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", -+ part->name); -+ } - } - - tmp = mtd_get_master_ofs(child, 0) + child->part.size; - remainder = do_div(tmp, wr_alignment); - if ((child->flags & MTD_WRITEABLE) && remainder) { -- child->flags &= ~MTD_WRITEABLE; -- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", -- part->name); -+ if (wr_alignment_minor) { -+ tmp = remainder; -+ remainder = do_div(tmp, wr_alignment_minor); -+ } -+ -+ if (remainder) { -+ child->flags &= ~MTD_WRITEABLE; -+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", -+ part->name); -+ } - } - - child->size = child->part.size; ---- a/drivers/mtd/spi-nor/Kconfig -+++ b/drivers/mtd/spi-nor/Kconfig -@@ -10,6 +10,16 @@ menuconfig MTD_SPI_NOR - - if MTD_SPI_NOR - -+config MTD_SPI_NOR_USE_VARIABLE_ERASE -+ bool "Disable uniform_erase to allow use of all hardware supported erasesizes" -+ depends on !MTD_SPI_NOR_USE_4K_SECTORS -+ default n -+ help -+ Allow mixed use of all hardware supported erasesizes, -+ by forcing spi_nor to use the multiple eraseregions code path. -+ For example: A 68K erase will use one 64K erase, and one 4K erase -+ on supporting hardware. -+ - config MTD_SPI_NOR_USE_4K_SECTORS - bool "Use small 4096 B erase sectors" - default y ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -1272,6 +1272,8 @@ static u8 spi_nor_convert_3to4_erase(u8 - - static bool spi_nor_has_uniform_erase(const struct spi_nor *nor) - { -+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE)) -+ return false; - return !!nor->params->erase_map.uniform_erase_type; - } - -@@ -2401,6 +2403,7 @@ static int spi_nor_select_erase(struct s - { - struct spi_nor_erase_map *map = &nor->params->erase_map; - const struct spi_nor_erase_type *erase = NULL; -+ const struct spi_nor_erase_type *erase_minor = NULL; - struct mtd_info *mtd = &nor->mtd; - u32 wanted_size = nor->info->sector_size; - int i; -@@ -2433,8 +2436,9 @@ static int spi_nor_select_erase(struct s - */ - for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) { - if (map->erase_type[i].size) { -- erase = &map->erase_type[i]; -- break; -+ if (!erase) -+ erase = &map->erase_type[i]; -+ erase_minor = &map->erase_type[i]; - } - } - -@@ -2442,6 +2446,9 @@ static int spi_nor_select_erase(struct s - return -EINVAL; - - mtd->erasesize = erase->size; -+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE) && -+ erase_minor && erase_minor->size < erase->size) -+ mtd->erasesize_minor = erase_minor->size; - return 0; - } - ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -250,6 +250,8 @@ struct mtd_info { - * information below if they desire - */ - uint32_t erasesize; -+ /* "Minor" (smallest) erase size supported by the whole device */ -+ uint32_t erasesize_minor; - /* Minimal writable flash unit size. In case of NOR flash it is 1 (even - * though individual bits can be cleared), in case of NAND flash it is - * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR diff --git a/target/linux/generic/pending-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch b/target/linux/generic/pending-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch deleted file mode 100644 index 6363cb61af004b..00000000000000 --- a/target/linux/generic/pending-5.15/405-mtd-spi-nor-Add-support-for-BoHong-bh25q128as.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 52d14545d2fc276b1bf9ccf48d4612fab6edfb6a Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Thu, 6 May 2021 17:49:55 +0200 -Subject: [PATCH] mtd: spi-nor: Add support for BoHong bh25q128as - -Add MTD support for the BoHong bh25q128as SPI NOR chip. -The chip has 16MB of total capacity, divided into a total of 256 -sectors, each 64KB sized. The chip also supports 4KB sectors. -Additionally, it supports dual and quad read modes. - -Functionality was verified on an Tenbay WR1800K / MTK MT7621 board. - -Signed-off-by: David Bauer ---- - drivers/mtd/spi-nor/Makefile | 1 + - drivers/mtd/spi-nor/bohong.c | 21 +++++++++++++++++++++ - drivers/mtd/spi-nor/core.c | 1 + - drivers/mtd/spi-nor/core.h | 1 + - 4 files changed, 24 insertions(+) - create mode 100644 drivers/mtd/spi-nor/bohong.c - ---- a/drivers/mtd/spi-nor/Makefile -+++ b/drivers/mtd/spi-nor/Makefile -@@ -2,6 +2,7 @@ - - spi-nor-objs := core.o sfdp.o swp.o otp.o sysfs.o - spi-nor-objs += atmel.o -+spi-nor-objs += bohong.o - spi-nor-objs += catalyst.o - spi-nor-objs += eon.o - spi-nor-objs += esmt.o ---- /dev/null -+++ b/drivers/mtd/spi-nor/bohong.c -@@ -0,0 +1,21 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005, Intec Automation Inc. -+ * Copyright (C) 2014, Freescale Semiconductor, Inc. -+ */ -+ -+#include -+ -+#include "core.h" -+ -+static const struct flash_info bohong_parts[] = { -+ /* BoHong Microelectronics */ -+ { "bh25q128as", INFO(0x684018, 0, 64 * 1024, 256, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+}; -+ -+const struct spi_nor_manufacturer spi_nor_bohong = { -+ .name = "bohong", -+ .parts = bohong_parts, -+ .nparts = ARRAY_SIZE(bohong_parts), -+}; ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -1844,6 +1844,7 @@ int spi_nor_sr2_bit7_quad_enable(struct - - static const struct spi_nor_manufacturer *manufacturers[] = { - &spi_nor_atmel, -+ &spi_nor_bohong, - &spi_nor_catalyst, - &spi_nor_eon, - &spi_nor_esmt, ---- a/drivers/mtd/spi-nor/core.h -+++ b/drivers/mtd/spi-nor/core.h -@@ -473,6 +473,7 @@ struct sfdp { - - /* Manufacturer drivers. */ - extern const struct spi_nor_manufacturer spi_nor_atmel; -+extern const struct spi_nor_manufacturer spi_nor_bohong; - extern const struct spi_nor_manufacturer spi_nor_catalyst; - extern const struct spi_nor_manufacturer spi_nor_eon; - extern const struct spi_nor_manufacturer spi_nor_esmt; diff --git a/target/linux/generic/pending-5.15/420-mtd-redboot_space.patch b/target/linux/generic/pending-5.15/420-mtd-redboot_space.patch deleted file mode 100644 index 5518ea71dd51f9..00000000000000 --- a/target/linux/generic/pending-5.15/420-mtd-redboot_space.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Felix Fietkau -Subject: add patch for including unpartitioned space in the rootfs partition for redboot devices (if applicable) - -[john@phrozen.org: used by ixp and others] - -lede-commit: 394918851f84e4d00fa16eb900e7700e95091f00 -Signed-off-by: Felix Fietkau ---- - drivers/mtd/redboot.c | 19 +++++++++++++------ - 1 file changed, 13 insertions(+), 6 deletions(-) - ---- a/drivers/mtd/parsers/redboot.c -+++ b/drivers/mtd/parsers/redboot.c -@@ -278,14 +278,21 @@ nogood: - #endif - names += strlen(names) + 1; - --#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED - if (fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { -- i++; -- parts[i].offset = parts[i - 1].size + parts[i - 1].offset; -- parts[i].size = fl->next->img->flash_base - parts[i].offset; -- parts[i].name = nullname; -- } -+ if (!strcmp(parts[i].name, "rootfs")) { -+ parts[i].size = fl->next->img->flash_base; -+ parts[i].size &= ~(master->erasesize - 1); -+ parts[i].size -= parts[i].offset; -+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED -+ nrparts--; -+ } else { -+ i++; -+ parts[i].offset = parts[i-1].size + parts[i-1].offset; -+ parts[i].size = fl->next->img->flash_base - parts[i].offset; -+ parts[i].name = nullname; - #endif -+ } -+ } - tmp_fl = fl; - fl = fl->next; - kfree(tmp_fl); diff --git a/target/linux/generic/pending-5.15/430-mtd-add-myloader-partition-parser.patch b/target/linux/generic/pending-5.15/430-mtd-add-myloader-partition-parser.patch deleted file mode 100644 index c7a8d9d7b7ca9c..00000000000000 --- a/target/linux/generic/pending-5.15/430-mtd-add-myloader-partition-parser.patch +++ /dev/null @@ -1,229 +0,0 @@ -From: Florian Fainelli -Subject: Add myloader partition table parser - -[john@phozen.org: shoud be upstreamable] - -lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8 -Signed-off-by: Florian Fainelli -[adjust for kernel 5.4, add myloader.c to patch] -Signed-off-by: Adrian Schmutzler - ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -57,6 +57,22 @@ config MTD_CMDLINE_PARTS - - If unsure, say 'N'. - -+config MTD_MYLOADER_PARTS -+ tristate "MyLoader partition parsing" -+ depends on ADM5120 || ATH79 -+ help -+ MyLoader is a bootloader which allows the user to define partitions -+ in flash devices, by putting a table in the second erase block -+ on the device, similar to a partition table. This table gives the -+ offsets and lengths of the user defined partitions. -+ -+ If you need code which can detect and parse these tables, and -+ register MTD 'partitions' corresponding to each image detected, -+ enable this option. -+ -+ You will still need the parsing functions to be called by the driver -+ for your particular device. It won't happen automatically. -+ - config MTD_OF_PARTS - tristate "OpenFirmware (device tree) partitioning parser" - default y ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -3,6 +3,7 @@ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part. - obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o - obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o - obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o -+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o - obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o - ofpart-y += ofpart_core.o - ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o ---- /dev/null -+++ b/drivers/mtd/parsers/myloader.c -@@ -0,0 +1,181 @@ -+/* -+ * Parse MyLoader-style flash partition tables and produce a Linux partition -+ * array to match. -+ * -+ * Copyright (C) 2007-2009 Gabor Juhos -+ * -+ * This file was based on drivers/mtd/redboot.c -+ * Author: Red Hat, Inc. - David Woodhouse -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define BLOCK_LEN_MIN 0x10000 -+#define PART_NAME_LEN 32 -+ -+struct part_data { -+ struct mylo_partition_table tab; -+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN]; -+}; -+ -+static int myloader_parse_partitions(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct part_data *buf; -+ struct mylo_partition_table *tab; -+ struct mylo_partition *part; -+ struct mtd_partition *mtd_parts; -+ struct mtd_partition *mtd_part; -+ int num_parts; -+ int ret, i; -+ size_t retlen; -+ char *names; -+ unsigned long offset; -+ unsigned long blocklen; -+ -+ buf = vmalloc(sizeof(*buf)); -+ if (!buf) { -+ return -ENOMEM; -+ goto out; -+ } -+ tab = &buf->tab; -+ -+ blocklen = master->erasesize; -+ if (blocklen < BLOCK_LEN_MIN) -+ blocklen = BLOCK_LEN_MIN; -+ -+ offset = blocklen; -+ -+ /* Find the partition table */ -+ for (i = 0; i < 4; i++, offset += blocklen) { -+ printk(KERN_DEBUG "%s: searching for MyLoader partition table" -+ " at offset 0x%lx\n", master->name, offset); -+ -+ ret = mtd_read(master, offset, sizeof(*buf), &retlen, -+ (void *)buf); -+ if (ret) -+ goto out_free_buf; -+ -+ if (retlen != sizeof(*buf)) { -+ ret = -EIO; -+ goto out_free_buf; -+ } -+ -+ /* Check for Partition Table magic number */ -+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS)) -+ break; -+ -+ } -+ -+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) { -+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n", -+ master->name); -+ ret = 0; -+ goto out_free_buf; -+ } -+ -+ /* The MyLoader and the Partition Table is always present */ -+ num_parts = 2; -+ -+ /* Detect number of used partitions */ -+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { -+ part = &tab->partitions[i]; -+ -+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) -+ continue; -+ -+ num_parts++; -+ } -+ -+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) + -+ num_parts * PART_NAME_LEN), GFP_KERNEL); -+ -+ if (!mtd_parts) { -+ ret = -ENOMEM; -+ goto out_free_buf; -+ } -+ -+ mtd_part = mtd_parts; -+ names = (char *)&mtd_parts[num_parts]; -+ -+ strncpy(names, "myloader", PART_NAME_LEN); -+ mtd_part->name = names; -+ mtd_part->offset = 0; -+ mtd_part->size = offset; -+ mtd_part->mask_flags = MTD_WRITEABLE; -+ mtd_part++; -+ names += PART_NAME_LEN; -+ -+ strncpy(names, "partition_table", PART_NAME_LEN); -+ mtd_part->name = names; -+ mtd_part->offset = offset; -+ mtd_part->size = blocklen; -+ mtd_part->mask_flags = MTD_WRITEABLE; -+ mtd_part++; -+ names += PART_NAME_LEN; -+ -+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { -+ part = &tab->partitions[i]; -+ -+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) -+ continue; -+ -+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff')) -+ strncpy(names, buf->names[i], PART_NAME_LEN); -+ else -+ snprintf(names, PART_NAME_LEN, "partition%d", i); -+ -+ mtd_part->offset = le32_to_cpu(part->addr); -+ mtd_part->size = le32_to_cpu(part->size); -+ mtd_part->name = names; -+ mtd_part++; -+ names += PART_NAME_LEN; -+ } -+ -+ *pparts = mtd_parts; -+ ret = num_parts; -+ -+ out_free_buf: -+ vfree(buf); -+ out: -+ return ret; -+} -+ -+static struct mtd_part_parser myloader_mtd_parser = { -+ .owner = THIS_MODULE, -+ .parse_fn = myloader_parse_partitions, -+ .name = "MyLoader", -+}; -+ -+static int __init myloader_mtd_parser_init(void) -+{ -+ register_mtd_parser(&myloader_mtd_parser); -+ -+ return 0; -+} -+ -+static void __exit myloader_mtd_parser_exit(void) -+{ -+ deregister_mtd_parser(&myloader_mtd_parser); -+} -+ -+module_init(myloader_mtd_parser_init); -+module_exit(myloader_mtd_parser_exit); -+ -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/pending-5.15/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/pending-5.15/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch deleted file mode 100644 index bcea45d009bb11..00000000000000 --- a/target/linux/generic/pending-5.15/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating offsets - -Signed-off-by: Rafał Miłecki ---- - ---- a/drivers/mtd/parsers/parser_trx.c -+++ b/drivers/mtd/parsers/parser_trx.c -@@ -25,6 +25,33 @@ struct trx_header { - uint32_t offset[3]; - } __packed; - -+/* -+ * Calculate real end offset (address) for a given amount of data. It checks -+ * all blocks skipping bad ones. -+ */ -+static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes) -+{ -+ size_t real_offset = 0; -+ -+ if (mtd_block_isbad(mtd, real_offset)) -+ pr_warn("Base offset shouldn't be at bad block"); -+ -+ while (bytes >= mtd->erasesize) { -+ bytes -= mtd->erasesize; -+ real_offset += mtd->erasesize; -+ while (mtd_block_isbad(mtd, real_offset)) { -+ real_offset += mtd->erasesize; -+ -+ if (real_offset >= mtd->size) -+ return real_offset - mtd->erasesize; -+ } -+ } -+ -+ real_offset += bytes; -+ -+ return real_offset; -+} -+ - static const char *parser_trx_data_part_name(struct mtd_info *master, - size_t offset) - { -@@ -86,21 +113,21 @@ static int parser_trx_parse(struct mtd_i - if (trx.offset[2]) { - part = &parts[curr_part++]; - part->name = "loader"; -- part->offset = trx.offset[i]; -+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); - i++; - } - - if (trx.offset[i]) { - part = &parts[curr_part++]; - part->name = "linux"; -- part->offset = trx.offset[i]; -+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); - i++; - } - - if (trx.offset[i]) { - part = &parts[curr_part++]; -- part->name = parser_trx_data_part_name(mtd, trx.offset[i]); -- part->offset = trx.offset[i]; -+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); -+ part->name = parser_trx_data_part_name(mtd, part->offset); - i++; - } - diff --git a/target/linux/generic/pending-5.15/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/pending-5.15/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch deleted file mode 100644 index 852654d924a8ce..00000000000000 --- a/target/linux/generic/pending-5.15/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: mtd: bcm47xxpart: detect T_Meter partition - -It can be found on many Netgear devices. It consists of many 0x30 blocks -starting with 4D 54. - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/bcm47xxpart.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/mtd/parsers/bcm47xxpart.c -+++ b/drivers/mtd/parsers/bcm47xxpart.c -@@ -35,6 +35,7 @@ - #define NVRAM_HEADER 0x48534C46 /* FLSH */ - #define POT_MAGIC1 0x54544f50 /* POTT */ - #define POT_MAGIC2 0x504f /* OP */ -+#define T_METER_MAGIC 0x4D540000 /* MT */ - #define ML_MAGIC1 0x39685a42 - #define ML_MAGIC2 0x26594131 - #define TRX_MAGIC 0x30524448 -@@ -178,6 +179,15 @@ static int bcm47xxpart_parse(struct mtd_ - MTD_WRITEABLE); - continue; - } -+ -+ /* T_Meter */ -+ if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC && -+ (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC && -+ (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) { -+ bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset, -+ MTD_WRITEABLE); -+ continue; -+ } - - /* TRX */ - if (buf[0x000 / 4] == TRX_MAGIC) { diff --git a/target/linux/generic/pending-5.15/435-mtd-add-routerbootpart-parser-config.patch b/target/linux/generic/pending-5.15/435-mtd-add-routerbootpart-parser-config.patch deleted file mode 100644 index ee949f73c095f9..00000000000000 --- a/target/linux/generic/pending-5.15/435-mtd-add-routerbootpart-parser-config.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= -Date: Tue, 24 Mar 2020 11:45:07 +0100 -Subject: [PATCH] generic: routerboot partition build bits (5.4) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds routerbootpart kernel build bits - -Signed-off-by: Thibaut VARÈNE ---- - drivers/mtd/parsers/Kconfig | 9 +++++++++ - drivers/mtd/parsers/Makefile | 1 + - 2 files changed, 10 insertions(+) - ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -226,3 +226,12 @@ config MTD_SERCOMM_PARTS - partition map. This partition table contains real partition - offsets, which may differ from device to device depending on the - number and location of bad blocks on NAND. -+ -+config MTD_ROUTERBOOT_PARTS -+ tristate "RouterBoot flash partition parser" -+ depends on MTD && OF -+ help -+ MikroTik RouterBoot is implemented as a multi segment system on the -+ flash, some of which are fixed and some of which are located at -+ variable offsets. This parser handles both cases via properly -+ formatted DTS. ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -16,3 +16,4 @@ obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpa - obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o - obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o - obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o -+obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o diff --git a/target/linux/generic/pending-5.15/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch b/target/linux/generic/pending-5.15/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch deleted file mode 100644 index 0be74a59777a79..00000000000000 --- a/target/linux/generic/pending-5.15/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Felix Fietkau -Subject: kernel: disable cfi cmdset 0002 erase suspend - -on some platforms, erase suspend leads to data corruption and lockups when write -ops collide with erase ops. this has been observed on the buffalo wzr-hp-g300nh. -rather than play whack-a-mole with a hard to reproduce issue on a variety of devices, -simply disable erase suspend, as it will usually not produce any useful gain on -the small filesystems used on embedded hardware. - -Signed-off-by: Felix Fietkau ---- - drivers/mtd/chips/cfi_cmdset_0002.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/mtd/chips/cfi_cmdset_0002.c -+++ b/drivers/mtd/chips/cfi_cmdset_0002.c -@@ -907,7 +907,7 @@ static int get_chip(struct map_info *map - return 0; - - case FL_ERASING: -- if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) || -+ if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) || - !(mode == FL_READY || mode == FL_POINT || - (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) - goto sleep; diff --git a/target/linux/generic/pending-5.15/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch b/target/linux/generic/pending-5.15/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch deleted file mode 100644 index ca56de82711711..00000000000000 --- a/target/linux/generic/pending-5.15/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch +++ /dev/null @@ -1,17 +0,0 @@ -From: George Kashperko -Subject: Issue map read after Write Buffer Load command to ensure chip is ready to receive data. - -Signed-off-by: George Kashperko ---- - drivers/mtd/chips/cfi_cmdset_0002.c | 1 + - 1 file changed, 1 insertion(+) ---- a/drivers/mtd/chips/cfi_cmdset_0002.c -+++ b/drivers/mtd/chips/cfi_cmdset_0002.c -@@ -2051,6 +2051,7 @@ static int __xipram do_write_buffer(stru - - /* Write Buffer Load */ - map_write(map, CMD(0x25), cmd_adr); -+ (void) map_read(map, cmd_adr); - - chip->state = FL_WRITING_TO_BUFFER; - diff --git a/target/linux/generic/pending-5.15/465-m25p80-mx-disable-software-protection.patch b/target/linux/generic/pending-5.15/465-m25p80-mx-disable-software-protection.patch deleted file mode 100644 index f58d5452abe9f2..00000000000000 --- a/target/linux/generic/pending-5.15/465-m25p80-mx-disable-software-protection.patch +++ /dev/null @@ -1,18 +0,0 @@ -From: Felix Fietkau -Subject: Disable software protection bits for Macronix flashes. - -Signed-off-by: Felix Fietkau ---- - drivers/mtd/spi-nor/spi-nor.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/spi-nor/macronix.c -+++ b/drivers/mtd/spi-nor/macronix.c -@@ -93,6 +93,7 @@ static void macronix_default_init(struct - { - nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; - nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode; -+ nor->flags |= SNOR_F_HAS_LOCK; - } - - static const struct spi_nor_fixups macronix_fixups = { diff --git a/target/linux/generic/pending-5.15/476-mtd-spi-nor-add-eon-en25q128.patch b/target/linux/generic/pending-5.15/476-mtd-spi-nor-add-eon-en25q128.patch deleted file mode 100644 index 9383e48856d91f..00000000000000 --- a/target/linux/generic/pending-5.15/476-mtd-spi-nor-add-eon-en25q128.patch +++ /dev/null @@ -1,18 +0,0 @@ -From: Piotr Dymacz -Subject: kernel/mtd: add support for EON EN25Q128 - -Signed-off-by: Piotr Dymacz ---- - drivers/mtd/spi-nor/spi-nor.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/spi-nor/eon.c -+++ b/drivers/mtd/spi-nor/eon.c -@@ -25,6 +25,7 @@ static const struct flash_info eon_parts - { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, - { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, SECT_4K) }, - { "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16, - SECT_4K | SPI_NOR_DUAL_READ) }, - { "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32, diff --git a/target/linux/generic/pending-5.15/477-mtd-spi-nor-add-eon-en25qx128a.patch b/target/linux/generic/pending-5.15/477-mtd-spi-nor-add-eon-en25qx128a.patch deleted file mode 100644 index 3c579e55e34c4d..00000000000000 --- a/target/linux/generic/pending-5.15/477-mtd-spi-nor-add-eon-en25qx128a.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Christian Marangi -Subject: kernel/mtd: add support for EON EN25QX128A - -Add support for EON EN25QX128A with no flags as it does -support SFDP parsing. - -Signed-off-by: Christian Marangi ---- - drivers/mtd/spi-nor/spi-nor.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/spi-nor/eon.c -+++ b/drivers/mtd/spi-nor/eon.c -@@ -26,6 +26,7 @@ static const struct flash_info eon_parts - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, - { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, - { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, SECT_4K) }, -+ { "en25qx128a", INFO(0x1c7118, 0, 64 * 1024, 256, 0) }, - { "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16, - SECT_4K | SPI_NOR_DUAL_READ) }, - { "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32, diff --git a/target/linux/generic/pending-5.15/479-mtd-spi-nor-add-xtx-xt25f128b.patch b/target/linux/generic/pending-5.15/479-mtd-spi-nor-add-xtx-xt25f128b.patch deleted file mode 100644 index 46471588ecc4d8..00000000000000 --- a/target/linux/generic/pending-5.15/479-mtd-spi-nor-add-xtx-xt25f128b.patch +++ /dev/null @@ -1,79 +0,0 @@ -From patchwork Thu Feb 6 17:19:41 2020 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 1234465 -Date: Thu, 6 Feb 2020 19:19:41 +0200 -From: Daniel Golle -To: linux-mtd@lists.infradead.org -Subject: [PATCH v2] mtd: spi-nor: Add support for xt25f128b chip -Message-ID: <20200206171941.GA2398@makrotopia.org> -MIME-Version: 1.0 -Content-Disposition: inline -List-Subscribe: , - -Cc: Eitan Cohen , Piotr Dymacz , - Tudor Ambarus -Sender: "linux-mtd" -Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org - -Add XT25F128B made by XTX Technology (Shenzhen) Limited. -This chip supports dual and quad read and uniform 4K-byte erase. -Verified on Teltonika RUT955 which comes with XT25F128B in recent -versions of the device. - -Signed-off-by: Daniel Golle -Signed-off-by: Felix Fietkau ---- - drivers/mtd/spi-nor/spi-nor.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/mtd/spi-nor/Makefile -+++ b/drivers/mtd/spi-nor/Makefile -@@ -18,6 +18,7 @@ spi-nor-objs += sst.o - spi-nor-objs += winbond.o - spi-nor-objs += xilinx.o - spi-nor-objs += xmc.o -+spi-nor-objs += xtx.o - obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o - - obj-$(CONFIG_MTD_SPI_NOR) += controllers/ ---- /dev/null -+++ b/drivers/mtd/spi-nor/xtx.c -@@ -0,0 +1,15 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include -+ -+#include "core.h" -+ -+static const struct flash_info xtx_parts[] = { -+ /* XTX Technology (Shenzhen) Limited */ -+ { "xt25f128b", INFO(0x0B4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+}; -+ -+const struct spi_nor_manufacturer spi_nor_xtx = { -+ .name = "xtx", -+ .parts = xtx_parts, -+ .nparts = ARRAY_SIZE(xtx_parts), -+}; ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -1861,6 +1861,7 @@ static const struct spi_nor_manufacturer - &spi_nor_winbond, - &spi_nor_xilinx, - &spi_nor_xmc, -+ &spi_nor_xtx, - }; - - static const struct flash_info * ---- a/drivers/mtd/spi-nor/core.h -+++ b/drivers/mtd/spi-nor/core.h -@@ -490,6 +490,7 @@ extern const struct spi_nor_manufacturer - extern const struct spi_nor_manufacturer spi_nor_winbond; - extern const struct spi_nor_manufacturer spi_nor_xilinx; - extern const struct spi_nor_manufacturer spi_nor_xmc; -+extern const struct spi_nor_manufacturer spi_nor_xtx; - - extern const struct attribute_group *spi_nor_sysfs_groups[]; - diff --git a/target/linux/generic/pending-5.15/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch b/target/linux/generic/pending-5.15/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch deleted file mode 100644 index c32cde559dbe77..00000000000000 --- a/target/linux/generic/pending-5.15/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch +++ /dev/null @@ -1,22 +0,0 @@ -From d68b4aa22e8c625685bfad642dd7337948dc0ad1 Mon Sep 17 00:00:00 2001 -From: Koen Vandeputte -Date: Mon, 6 Jan 2020 13:07:56 +0100 -Subject: [PATCH] mtd: spi-nor: add support for Gigadevice GD25D05 - -Signed-off-by: Koen Vandeputte ---- - drivers/mtd/spi-nor/spi-nor.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/mtd/spi-nor/gigadevice.c -+++ b/drivers/mtd/spi-nor/gigadevice.c -@@ -24,6 +24,9 @@ static struct spi_nor_fixups gd25q256_fi - }; - - static const struct flash_info gigadevice_parts[] = { -+ { "gd25q05", INFO(0xc84010, 0, 64 * 1024, 1, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, - { "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | - SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, diff --git a/target/linux/generic/pending-5.15/482-mtd-spi-nor-add-gd25q512.patch b/target/linux/generic/pending-5.15/482-mtd-spi-nor-add-gd25q512.patch deleted file mode 100644 index 7c8b6862777814..00000000000000 --- a/target/linux/generic/pending-5.15/482-mtd-spi-nor-add-gd25q512.patch +++ /dev/null @@ -1,21 +0,0 @@ -From f8943df3beb0d3f9754bb35320c3a378727175a8 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Thu, 14 Jul 2022 08:38:07 +0200 -Subject: [PATCH] spi-nor/gigadevic: add gd25q512 - ---- - drivers/mtd/spi-nor/gigadevice.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/mtd/spi-nor/gigadevice.c -+++ b/drivers/mtd/spi-nor/gigadevice.c -@@ -53,6 +53,9 @@ static const struct flash_info gigadevic - SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | - SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6) - .fixups = &gd25q256_fixups }, -+ { "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | -+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES) }, - }; - - const struct spi_nor_manufacturer spi_nor_gigadevice = { diff --git a/target/linux/generic/pending-5.15/484-mtd-spi-nor-add-esmt-f25l16pa.patch b/target/linux/generic/pending-5.15/484-mtd-spi-nor-add-esmt-f25l16pa.patch deleted file mode 100644 index ab402e622a20f5..00000000000000 --- a/target/linux/generic/pending-5.15/484-mtd-spi-nor-add-esmt-f25l16pa.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 87363cc0e522de3294ea6ae10fb468d2a8d6fb2f Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:17:21 +0200 -Subject: [PATCH] spi-nor/esmt.c: add esmt f25l16pa - -This fixes support for Dongwon T&I DW02-412H which uses F25L16PA(2S) -flash. - ---- - drivers/mtd/spi-nor/esmt.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/mtd/spi-nor/esmt.c -+++ b/drivers/mtd/spi-nor/esmt.c -@@ -10,6 +10,8 @@ - - static const struct flash_info esmt_parts[] = { - /* ESMT */ -+ { "f25l16pa-2s", INFO(0x8c2115, 0, 64 * 1024, 32, -+ SECT_4K | SPI_NOR_HAS_LOCK) }, - { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, - SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) }, - { "f25l32qa", INFO(0x8c4116, 0, 64 * 1024, 64, diff --git a/target/linux/generic/pending-5.15/485-mtd-spi-nor-add-xmc-xm25qh128c.patch b/target/linux/generic/pending-5.15/485-mtd-spi-nor-add-xmc-xm25qh128c.patch deleted file mode 100644 index 68e373ea2360d3..00000000000000 --- a/target/linux/generic/pending-5.15/485-mtd-spi-nor-add-xmc-xm25qh128c.patch +++ /dev/null @@ -1,24 +0,0 @@ -From f6b33d850f7f12555df2fa0e3349b33427bf5890 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:19:01 +0200 -Subject: [PATCH] spi-nor/xmc.c: add xm25qh128c - -The XMC XM25QH128C is a 16MB SPI NOR chip. The patch is verified on -Ruijie RG-EW3200GX PRO. -Datasheet available at https://www.xmcwh.com/uploads/435/XM25QH128C.pdf - ---- - drivers/mtd/spi-nor/xmc.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/mtd/spi-nor/xmc.c -+++ b/drivers/mtd/spi-nor/xmc.c -@@ -14,6 +14,8 @@ static const struct flash_info xmc_parts - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "XM25QH128C", INFO(0x204018, 0, 64 * 1024, 256, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - }; - - const struct spi_nor_manufacturer spi_nor_xmc = { diff --git a/target/linux/generic/pending-5.15/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch b/target/linux/generic/pending-5.15/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch deleted file mode 100644 index d117cfe0a3a9cd..00000000000000 --- a/target/linux/generic/pending-5.15/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch +++ /dev/null @@ -1,143 +0,0 @@ -From a43b844cb40bf1b783055fdc81b7f991e21e7e76 Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo -Date: Wed, 13 Apr 2022 11:58:17 +0800 -Subject: [PATCH] mtd: spinand: add support for ESMT F50x1G41LB - -This patch adds support for ESMT F50L1G41LB and F50D1G41LB. -It seems that ESMT likes to use random JEDEC ID from other vendors. -Their 1G chips uses 0xc8 from GigaDevice and 2G/4G chips uses 0x2c from -Micron. For this reason, the ESMT entry is named esmt_c8 with explicit -JEDEC ID in variable name. - -Datasheets: -https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50L1G41LB(2M).pdf -https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50D1G41LB(2M).pdf - -Signed-off-by: Chuanhong Guo ---- - drivers/mtd/nand/spi/Makefile | 2 +- - drivers/mtd/nand/spi/core.c | 1 + - drivers/mtd/nand/spi/esmt.c | 89 +++++++++++++++++++++++++++++++++++ - include/linux/mtd/spinand.h | 1 + - 4 files changed, 92 insertions(+), 1 deletion(-) - create mode 100644 drivers/mtd/nand/spi/esmt.c - ---- a/drivers/mtd/nand/spi/Makefile -+++ b/drivers/mtd/nand/spi/Makefile -@@ -1,3 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 --spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o -+spinand-objs := core.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o - obj-$(CONFIG_MTD_SPI_NAND) += spinand.o ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -906,6 +906,7 @@ static const struct nand_ops spinand_ops - }; - - static const struct spinand_manufacturer *spinand_manufacturers[] = { -+ &esmt_c8_spinand_manufacturer, - &gigadevice_spinand_manufacturer, - ¯onix_spinand_manufacturer, - µn_spinand_manufacturer, ---- /dev/null -+++ b/drivers/mtd/nand/spi/esmt.c -@@ -0,0 +1,89 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Author: -+ * Chuanhong Guo -+ */ -+ -+#include -+#include -+#include -+ -+/* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */ -+#define SPINAND_MFR_ESMT_C8 0xc8 -+ -+static SPINAND_OP_VARIANTS(read_cache_variants, -+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(write_cache_variants, -+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), -+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(update_cache_variants, -+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), -+ SPINAND_PROG_LOAD(false, 0, NULL, 0)); -+ -+static int f50l1g41lb_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section > 3) -+ return -ERANGE; -+ -+ region->offset = 16 * section + 8; -+ region->length = 8; -+ -+ return 0; -+} -+ -+static int f50l1g41lb_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section > 3) -+ return -ERANGE; -+ -+ region->offset = 16 * section + 2; -+ region->length = 6; -+ -+ return 0; -+} -+ -+static const struct mtd_ooblayout_ops f50l1g41lb_ooblayout = { -+ .ecc = f50l1g41lb_ooblayout_ecc, -+ .free = f50l1g41lb_ooblayout_free, -+}; -+ -+static const struct spinand_info esmt_c8_spinand_table[] = { -+ SPINAND_INFO("F50L1G41LB", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01), -+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(1, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ 0, -+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), -+ SPINAND_INFO("F50D1G41LB", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11), -+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(1, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ 0, -+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), -+}; -+ -+static const struct spinand_manufacturer_ops esmt_spinand_manuf_ops = { -+}; -+ -+const struct spinand_manufacturer esmt_c8_spinand_manufacturer = { -+ .id = SPINAND_MFR_ESMT_C8, -+ .name = "ESMT", -+ .chips = esmt_c8_spinand_table, -+ .nchips = ARRAY_SIZE(esmt_c8_spinand_table), -+ .ops = &esmt_spinand_manuf_ops, -+}; ---- a/include/linux/mtd/spinand.h -+++ b/include/linux/mtd/spinand.h -@@ -260,6 +260,7 @@ struct spinand_manufacturer { - }; - - /* SPI NAND manufacturers */ -+extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; - extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; - extern const struct spinand_manufacturer macronix_spinand_manufacturer; - extern const struct spinand_manufacturer micron_spinand_manufacturer; diff --git a/target/linux/generic/pending-5.15/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch b/target/linux/generic/pending-5.15/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch deleted file mode 100644 index 7e20e14bb620ef..00000000000000 --- a/target/linux/generic/pending-5.15/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch +++ /dev/null @@ -1,168 +0,0 @@ -From f32085fc0b87049491b07e198d924d738a1a2834 Mon Sep 17 00:00:00 2001 -From: Daniel Danzberger -Date: Wed, 3 Aug 2022 17:31:03 +0200 -Subject: [PATCH] mtd: spinand: Add support for Etron EM73D044VCx - -Airoha is a new ARM platform based on Cortex-A53 which has recently been -merged into linux-next. - -Due to BootROM limitations on this platform, the Cortex-A53 can't run in -Aarch64 mode and code must be compiled for 32-Bit ARM. - -This support is based mostly on those linux-next commits backported -for kernel 5.15. - -Patches: -1 - platform support = linux-next -2 - clock driver = linux-next -3 - gpio driver = linux-next -4 - linux,usable-memory-range dts support = linux-next -5 - mtd spinand driver -6 - spi driver -7 - pci driver (kconfig only, uses mediatek PCI) = linux-next - -Still missing: -- Ethernet driver -- Sysupgrade support - -A.t.m there exists one subtarget EN7523 with only one evaluation -board. - -The initramfs can be run with the following commands from u-boot: -- -u-boot> setenv bootfile \ - openwrt-airoha-airoha_en7523-evb-initramfs-kernel.bin -u-boot> tftpboot -u-boot> bootm 0x81800000 -- - -Submitted-by: Daniel Danzberger - ---- a/drivers/mtd/nand/spi/Makefile -+++ b/drivers/mtd/nand/spi/Makefile -@@ -1,3 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 --spinand-objs := core.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o -+spinand-objs := core.o esmt.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o - obj-$(CONFIG_MTD_SPI_NAND) += spinand.o ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -908,6 +908,7 @@ static const struct nand_ops spinand_ops - static const struct spinand_manufacturer *spinand_manufacturers[] = { - &esmt_c8_spinand_manufacturer, - &gigadevice_spinand_manufacturer, -+ &etron_spinand_manufacturer, - ¯onix_spinand_manufacturer, - µn_spinand_manufacturer, - ¶gon_spinand_manufacturer, ---- /dev/null -+++ b/drivers/mtd/nand/spi/etron.c -@@ -0,0 +1,98 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+ -+#define SPINAND_MFR_ETRON 0xd5 -+ -+ -+static SPINAND_OP_VARIANTS(read_cache_variants, -+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(write_cache_variants, -+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), -+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(update_cache_variants, -+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), -+ SPINAND_PROG_LOAD(false, 0, NULL, 0)); -+ -+static int etron_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) -+ return -ERANGE; -+ -+ oobregion->offset = 72; -+ oobregion->length = 56; -+ -+ return 0; -+} -+ -+static int etron_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) -+ return -ERANGE; -+ -+ oobregion->offset = 1; -+ oobregion->length = 71; -+ -+ return 0; -+} -+ -+static int etron_ecc_get_status(struct spinand_device *spinand, u8 status) -+{ -+ switch (status & STATUS_ECC_MASK) { -+ case STATUS_ECC_NO_BITFLIPS: -+ return 0; -+ -+ case STATUS_ECC_HAS_BITFLIPS: -+ /* Between 1-7 bitflips were corrected */ -+ return 7; -+ -+ case STATUS_ECC_MASK: -+ /* Maximum bitflips were corrected */ -+ return 8; -+ -+ case STATUS_ECC_UNCOR_ERROR: -+ return -EBADMSG; -+ } -+ -+ return -EINVAL; -+} -+ -+static const struct mtd_ooblayout_ops etron_ooblayout = { -+ .ecc = etron_ooblayout_ecc, -+ .free = etron_ooblayout_free, -+}; -+ -+static const struct spinand_info etron_spinand_table[] = { -+ SPINAND_INFO("EM73D044VCx", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f), -+ // bpc, pagesize, oobsize, pagesperblock, bperlun, maxbadplun, ppl, lpt, #t -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)), -+}; -+ -+static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = { -+}; -+ -+const struct spinand_manufacturer etron_spinand_manufacturer = { -+ .id = SPINAND_MFR_ETRON, -+ .name = "Etron", -+ .chips = etron_spinand_table, -+ .nchips = ARRAY_SIZE(etron_spinand_table), -+ .ops = &etron_spinand_manuf_ops, -+}; ---- a/include/linux/mtd/spinand.h -+++ b/include/linux/mtd/spinand.h -@@ -261,6 +261,7 @@ struct spinand_manufacturer { - - /* SPI NAND manufacturers */ - extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; -+extern const struct spinand_manufacturer etron_spinand_manufacturer; - extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; - extern const struct spinand_manufacturer macronix_spinand_manufacturer; - extern const struct spinand_manufacturer micron_spinand_manufacturer; diff --git a/target/linux/generic/pending-5.15/488-mtd-spi-nor-add-xmc-xm25qh64c.patch b/target/linux/generic/pending-5.15/488-mtd-spi-nor-add-xmc-xm25qh64c.patch deleted file mode 100644 index 236d1c2755fee2..00000000000000 --- a/target/linux/generic/pending-5.15/488-mtd-spi-nor-add-xmc-xm25qh64c.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Joe Mullally -Subject: mtd/spi-nor/xmc: add support for XMC XM25QH64C - -The XMC XM25QH64C is a 8MB SPI NOR chip. The patch is verified on TL-WPA8631P v3. -Datasheet available at https://www.xmcwh.com/uploads/442/XM25QH64C.pdf - -Signed-off-by: Joe Mullally ---- - drivers/mtd/spi-nor/xmc.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/mtd/spi-nor/xmc.c -+++ b/drivers/mtd/spi-nor/xmc.c -@@ -12,6 +12,8 @@ static const struct flash_info xmc_parts - /* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */ - { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, -+ { "XM25QH64C", INFO(0x204017, 0, 64 * 1024, 128, -+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256, - SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "XM25QH128C", INFO(0x204018, 0, 64 * 1024, 256, diff --git a/target/linux/generic/pending-5.15/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch b/target/linux/generic/pending-5.15/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch deleted file mode 100644 index e8da36edba5bea..00000000000000 --- a/target/linux/generic/pending-5.15/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch +++ /dev/null @@ -1,97 +0,0 @@ -From: Daniel Golle -Subject: ubi: auto-attach mtd device named "ubi" or "data" on boot - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - ---- a/drivers/mtd/ubi/build.c -+++ b/drivers/mtd/ubi/build.c -@@ -1207,6 +1207,73 @@ static struct mtd_info * __init open_mtd - return mtd; - } - -+/* -+ * This function tries attaching mtd partitions named either "ubi" or "data" -+ * during boot. -+ */ -+static void __init ubi_auto_attach(void) -+{ -+ int err; -+ struct mtd_info *mtd; -+ loff_t offset = 0; -+ size_t len; -+ char magic[4]; -+ -+ /* try attaching mtd device named "ubi" or "data" */ -+ mtd = open_mtd_device("ubi"); -+ if (IS_ERR(mtd)) -+ mtd = open_mtd_device("data"); -+ -+ if (IS_ERR(mtd)) -+ return; -+ -+ /* get the first not bad block */ -+ if (mtd_can_have_bb(mtd)) -+ while (mtd_block_isbad(mtd, offset)) { -+ offset += mtd->erasesize; -+ -+ if (offset > mtd->size) { -+ pr_err("UBI error: Failed to find a non-bad " -+ "block on mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ } -+ -+ /* check if the read from flash was successful */ -+ err = mtd_read(mtd, offset, 4, &len, (void *) magic); -+ if ((err && !mtd_is_bitflip(err)) || len != 4) { -+ pr_err("UBI error: unable to read from mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ -+ /* check for a valid ubi magic */ -+ if (strncmp(magic, "UBI#", 4)) { -+ pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ -+ /* don't auto-add media types where UBI doesn't makes sense */ -+ if (mtd->type != MTD_NANDFLASH && -+ mtd->type != MTD_NORFLASH && -+ mtd->type != MTD_DATAFLASH && -+ mtd->type != MTD_MLCNANDFLASH) -+ goto cleanup; -+ -+ mutex_lock(&ubi_devices_mutex); -+ pr_notice("UBI: auto-attach mtd%d\n", mtd->index); -+ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0); -+ mutex_unlock(&ubi_devices_mutex); -+ if (err < 0) { -+ pr_err("UBI error: cannot attach mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ -+ return; -+ -+cleanup: -+ put_mtd_device(mtd); -+} -+ - static int __init ubi_init(void) - { - int err, i, k; -@@ -1290,6 +1357,12 @@ static int __init ubi_init(void) - } - } - -+ /* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd -+ * parameter was given */ -+ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && -+ !ubi_is_module() && !mtd_devs) -+ ubi_auto_attach(); -+ - err = ubiblock_init(); - if (err) { - pr_err("UBI error: block: cannot initialize, error %d\n", err); diff --git a/target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch deleted file mode 100644 index 4ddd27add9d4d6..00000000000000 --- a/target/linux/generic/pending-5.15/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +++ /dev/null @@ -1,69 +0,0 @@ -From: Daniel Golle -Subject: ubi: auto-create ubiblock device for rootfs - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 42 insertions(+) - ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -642,6 +642,47 @@ static void __init ubiblock_create_from_ - } - } - -+#define UBIFS_NODE_MAGIC 0x06101831 -+static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc) -+{ -+ int ret; -+ uint32_t magic_of, magic; -+ ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4); -+ if (ret) -+ return 0; -+ magic = le32_to_cpu(magic_of); -+ return magic == UBIFS_NODE_MAGIC; -+} -+ -+static void ubiblock_create_auto_rootfs(void) -+{ -+ int ubi_num, ret, is_ubifs; -+ struct ubi_volume_desc *desc; -+ struct ubi_volume_info vi; -+ -+ for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) { -+ desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY); -+ if (IS_ERR(desc)) -+ desc = ubi_open_volume_nm(ubi_num, "fit", UBI_READONLY);; -+ -+ if (IS_ERR(desc)) -+ continue; -+ -+ ubi_get_volume_info(desc, &vi); -+ is_ubifs = ubi_vol_is_ubifs(desc); -+ ubi_close_volume(desc); -+ if (is_ubifs) -+ break; -+ -+ ret = ubiblock_create(&vi); -+ if (ret) -+ pr_err("UBI error: block: can't add '%s' volume, err=%d\n", -+ vi.name, ret); -+ /* always break if we get here */ -+ break; -+ } -+} -+ - static void ubiblock_remove_all(void) - { - struct ubiblock *next; -@@ -674,6 +715,10 @@ int __init ubiblock_init(void) - */ - ubiblock_create_from_param(); - -+ /* auto-attach "rootfs" volume if existing and non-ubifs */ -+ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV)) -+ ubiblock_create_auto_rootfs(); -+ - /* - * Block devices are only created upon user requests, so we ignore - * existing volumes. diff --git a/target/linux/generic/pending-5.15/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch b/target/linux/generic/pending-5.15/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch deleted file mode 100644 index cf41c8cad3f31c..00000000000000 --- a/target/linux/generic/pending-5.15/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: Daniel Golle -Subject: try auto-mounting ubi0:rootfs in init/do_mounts.c - -Signed-off-by: Daniel Golle ---- - init/do_mounts.c | 26 +++++++++++++++++++++++++- - 1 file changed, 25 insertions(+), 1 deletion(-) - ---- a/init/do_mounts.c -+++ b/init/do_mounts.c -@@ -447,7 +447,30 @@ retry: - out: - put_page(page); - } -- -+ -+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV -+static int __init mount_ubi_rootfs(void) -+{ -+ int flags = MS_SILENT; -+ int err, tried = 0; -+ -+ while (tried < 2) { -+ err = do_mount_root("ubi0:rootfs", "ubifs", flags, \ -+ root_mount_data); -+ switch (err) { -+ case -EACCES: -+ flags |= MS_RDONLY; -+ tried++; -+ break; -+ default: -+ return err; -+ } -+ } -+ -+ return -EINVAL; -+} -+#endif -+ - #ifdef CONFIG_ROOT_NFS - - #define NFSROOT_TIMEOUT_MIN 5 -@@ -580,6 +603,10 @@ void __init mount_root(void) - return; - } - #endif -+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV -+ if (!mount_ubi_rootfs()) -+ return; -+#endif - if (ROOT_DEV == 0 && root_device_name && root_fs_names) { - if (mount_nodev_root() == 0) - return; diff --git a/target/linux/generic/pending-5.15/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch b/target/linux/generic/pending-5.15/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch deleted file mode 100644 index 266a6331c2acc0..00000000000000 --- a/target/linux/generic/pending-5.15/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Daniel Golle -Subject: ubi: set ROOT_DEV to ubiblock "rootfs" if unset - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/block.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -42,6 +42,7 @@ - #include - #include - #include -+#include - - #include "ubi-media.h" - #include "ubi.h" -@@ -451,6 +452,15 @@ int ubiblock_create(struct ubi_volume_in - dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)", - dev->ubi_num, dev->vol_id, vi->name); - mutex_unlock(&devices_mutex); -+ -+ if (!strcmp(vi->name, "rootfs") && -+ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && -+ ROOT_DEV == 0) { -+ pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n", -+ dev->ubi_num, dev->vol_id, vi->name); -+ ROOT_DEV = MKDEV(gd->major, gd->first_minor); -+ } -+ - return 0; - - out_remove_minor: diff --git a/target/linux/generic/pending-5.15/494-mtd-ubi-add-EOF-marker-support.patch b/target/linux/generic/pending-5.15/494-mtd-ubi-add-EOF-marker-support.patch deleted file mode 100644 index 413431755f1d2c..00000000000000 --- a/target/linux/generic/pending-5.15/494-mtd-ubi-add-EOF-marker-support.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: Gabor Juhos -Subject: mtd: add EOF marker support to the UBI layer - -Signed-off-by: Gabor Juhos ---- - drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++--- - drivers/mtd/ubi/ubi.h | 1 + - 2 files changed, 23 insertions(+), 3 deletions(-) - ---- a/drivers/mtd/ubi/attach.c -+++ b/drivers/mtd/ubi/attach.c -@@ -926,6 +926,13 @@ static bool vol_ignored(int vol_id) - #endif - } - -+static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech) -+{ -+ return ech->padding1[0] == 'E' && -+ ech->padding1[1] == 'O' && -+ ech->padding1[2] == 'F'; -+} -+ - /** - * scan_peb - scan and process UBI headers of a PEB. - * @ubi: UBI device description object -@@ -958,9 +965,21 @@ static int scan_peb(struct ubi_device *u - return 0; - } - -- err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); -- if (err < 0) -- return err; -+ if (!ai->eof_found) { -+ err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); -+ if (err < 0) -+ return err; -+ -+ if (ec_hdr_has_eof(ech)) { -+ pr_notice("UBI: EOF marker found, PEBs from %d will be erased\n", -+ pnum); -+ ai->eof_found = true; -+ } -+ } -+ -+ if (ai->eof_found) -+ err = UBI_IO_FF_BITFLIPS; -+ - switch (err) { - case 0: - break; ---- a/drivers/mtd/ubi/ubi.h -+++ b/drivers/mtd/ubi/ubi.h -@@ -778,6 +778,7 @@ struct ubi_attach_info { - int mean_ec; - uint64_t ec_sum; - int ec_count; -+ bool eof_found; - struct kmem_cache *aeb_slab_cache; - struct ubi_ec_hdr *ech; - struct ubi_vid_io_buf *vidb; diff --git a/target/linux/generic/pending-5.15/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch b/target/linux/generic/pending-5.15/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch deleted file mode 100644 index 01f3b9ec2da0ce..00000000000000 --- a/target/linux/generic/pending-5.15/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 5734c6669fba7ddb5ef491ccff7159d15dba0b59 Mon Sep 17 00:00:00 2001 -From: Bernhard Frauendienst -Date: Wed, 5 Sep 2018 01:32:51 +0200 -Subject: [PATCH 496/497] dt-bindings: add bindings for mtd-concat devices - -Document virtual mtd-concat device bindings. - -Signed-off-by: Bernhard Frauendienst ---- - .../devicetree/bindings/mtd/mtd-concat.txt | 36 +++++++++++++++++++ - 1 file changed, 36 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mtd/mtd-concat.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/mtd/mtd-concat.txt -@@ -0,0 +1,36 @@ -+Virtual MTD concat device -+ -+Requires properties: -+- devices: list of phandles to mtd nodes that should be concatenated -+ -+Example: -+ -+&spi { -+ flash0: flash@0 { -+ ... -+ }; -+ flash1: flash@1 { -+ ... -+ }; -+}; -+ -+flash { -+ compatible = "mtd-concat"; -+ -+ devices = <&flash0 &flash1>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ -+ partition@0 { -+ label = "boot"; -+ reg = <0x0000000 0x0040000>; -+ read-only; -+ }; -+ -+ partition@40000 { -+ label = "firmware"; -+ reg = <0x0040000 0x1fc0000>; -+ }; -+ } -+} diff --git a/target/linux/generic/pending-5.15/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch b/target/linux/generic/pending-5.15/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch deleted file mode 100644 index e0cbc4508b0607..00000000000000 --- a/target/linux/generic/pending-5.15/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch +++ /dev/null @@ -1,216 +0,0 @@ -From e53f712d8eac71f54399b61038ccf87d2cee99d7 Mon Sep 17 00:00:00 2001 -From: Bernhard Frauendienst -Date: Sat, 25 Aug 2018 12:35:22 +0200 -Subject: [PATCH 497/497] mtd: mtdconcat: add dt driver for concat devices - -Some mtd drivers like physmap variants have support for concatenating -multiple mtd devices, but there is no generic way to define such a -concat device from within the device tree. - -This is useful for some SoC boards that use multiple flash chips as -memory banks of a single mtd device, with partitions spanning chip -borders. - -This commit adds a driver for creating virtual mtd-concat devices. They -must have a compatible = "mtd-concat" line, and define a list of devices -to concat in the 'devices' property, for example: - -flash { - compatible = "mtd-concat"; - - devices = <&flash0 &flash1>; - - partitions { - ... - }; -}; - -The driver is added to the very end of the mtd Makefile to increase the -likelyhood of all child devices already being loaded at the time of -probing, preventing unnecessary deferred probes. - -Signed-off-by: Bernhard Frauendienst ---- - drivers/mtd/Kconfig | 2 + - drivers/mtd/Makefile | 3 + - drivers/mtd/composite/Kconfig | 12 +++ - drivers/mtd/composite/Makefile | 6 ++ - drivers/mtd/composite/virt_concat.c | 128 ++++++++++++++++++++++++++++ - 5 files changed, 151 insertions(+) - create mode 100644 drivers/mtd/composite/Kconfig - create mode 100644 drivers/mtd/composite/Makefile - create mode 100644 drivers/mtd/composite/virt_concat.c - ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -241,4 +241,6 @@ source "drivers/mtd/ubi/Kconfig" - - source "drivers/mtd/hyperbus/Kconfig" - -+source "drivers/mtd/composite/Kconfig" -+ - endif # MTD ---- a/drivers/mtd/Makefile -+++ b/drivers/mtd/Makefile -@@ -33,3 +33,6 @@ obj-y += chips/ lpddr/ maps/ devices/ n - obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ - obj-$(CONFIG_MTD_UBI) += ubi/ - obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/ -+ -+# Composite drivers must be loaded last -+obj-y += composite/ ---- /dev/null -+++ b/drivers/mtd/composite/Kconfig -@@ -0,0 +1,12 @@ -+menu "Composite MTD device drivers" -+ depends on MTD!=n -+ -+config MTD_VIRT_CONCAT -+ tristate "Virtual concat MTD device" -+ help -+ This driver allows creation of a virtual MTD concat device, which -+ concatenates multiple underlying MTD devices to a single device. -+ This is required by some SoC boards where multiple memory banks are -+ used as one device with partitions spanning across device boundaries. -+ -+endmenu ---- /dev/null -+++ b/drivers/mtd/composite/Makefile -@@ -0,0 +1,6 @@ -+# SPDX-License-Identifier: GPL-2.0 -+# -+# linux/drivers/mtd/composite/Makefile -+# -+ -+obj-$(CONFIG_MTD_VIRT_CONCAT) += virt_concat.o ---- /dev/null -+++ b/drivers/mtd/composite/virt_concat.c -@@ -0,0 +1,128 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Virtual concat MTD device driver -+ * -+ * Copyright (C) 2018 Bernhard Frauendienst -+ * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * struct of_virt_concat - platform device driver data. -+ * @cmtd the final mtd_concat device -+ * @num_devices the number of devices in @devices -+ * @devices points to an array of devices already loaded -+ */ -+struct of_virt_concat { -+ struct mtd_info *cmtd; -+ int num_devices; -+ struct mtd_info **devices; -+}; -+ -+static int virt_concat_remove(struct platform_device *pdev) -+{ -+ struct of_virt_concat *info; -+ int i; -+ -+ info = platform_get_drvdata(pdev); -+ if (!info) -+ return 0; -+ -+ // unset data for when this is called after a probe error -+ platform_set_drvdata(pdev, NULL); -+ -+ if (info->cmtd) { -+ mtd_device_unregister(info->cmtd); -+ mtd_concat_destroy(info->cmtd); -+ } -+ -+ if (info->devices) { -+ for (i = 0; i < info->num_devices; i++) -+ put_mtd_device(info->devices[i]); -+ } -+ -+ return 0; -+} -+ -+static int virt_concat_probe(struct platform_device *pdev) -+{ -+ struct device_node *node = pdev->dev.of_node; -+ struct of_phandle_iterator it; -+ struct of_virt_concat *info; -+ struct mtd_info *mtd; -+ int err = 0, count; -+ -+ count = of_count_phandle_with_args(node, "devices", NULL); -+ if (count <= 0) -+ return -EINVAL; -+ -+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; -+ info->devices = devm_kcalloc(&pdev->dev, count, -+ sizeof(*(info->devices)), GFP_KERNEL); -+ if (!info->devices) { -+ err = -ENOMEM; -+ goto err_remove; -+ } -+ -+ platform_set_drvdata(pdev, info); -+ -+ of_for_each_phandle(&it, err, node, "devices", NULL, 0) { -+ mtd = of_get_mtd_device_by_node(it.node); -+ if (IS_ERR(mtd)) { -+ of_node_put(it.node); -+ err = -EPROBE_DEFER; -+ goto err_remove; -+ } -+ -+ info->devices[info->num_devices++] = mtd; -+ } -+ -+ info->cmtd = mtd_concat_create(info->devices, info->num_devices, -+ dev_name(&pdev->dev)); -+ if (!info->cmtd) { -+ err = -ENXIO; -+ goto err_remove; -+ } -+ -+ info->cmtd->dev.parent = &pdev->dev; -+ mtd_set_of_node(info->cmtd, node); -+ mtd_device_register(info->cmtd, NULL, 0); -+ -+ return 0; -+ -+err_remove: -+ virt_concat_remove(pdev); -+ -+ return err; -+} -+ -+static const struct of_device_id virt_concat_of_match[] = { -+ { .compatible = "mtd-concat", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, virt_concat_of_match); -+ -+static struct platform_driver virt_concat_driver = { -+ .probe = virt_concat_probe, -+ .remove = virt_concat_remove, -+ .driver = { -+ .name = "virt-mtdconcat", -+ .of_match_table = virt_concat_of_match, -+ }, -+}; -+ -+module_platform_driver(virt_concat_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Bernhard Frauendienst "); -+MODULE_DESCRIPTION("Virtual concat MTD device driver"); diff --git a/target/linux/generic/pending-5.15/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch b/target/linux/generic/pending-5.15/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch deleted file mode 100644 index 81de7648760d1b..00000000000000 --- a/target/linux/generic/pending-5.15/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 8bf2ce6ea4ee840b70f55a27f80e1cd308051b13 Mon Sep 17 00:00:00 2001 -From: Nick Hainke -Date: Mon, 27 Dec 2021 00:38:13 +0100 -Subject: [PATCH 1/2] mtd: spi-nor: locking support for MX25L6405D - -Macronix MX25L6405D supports locking with four block-protection bits. -Currently, the driver only sets three bits. If the bootloader does not -sustain the flash chip in an unlocked state, the flash might be -non-writeable. Add the corresponding flag to enable locking support with -four bits in the status register. - -Tested on Nanostation M2 XM. - -Similar to commit 7ea40b54e83b ("mtd: spi-nor: enable locking support for -MX25L12805D") - -Signed-off-by: David Bauer -Signed-off-by: Nick Hainke ---- - drivers/mtd/spi-nor/macronix.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/spi-nor/macronix.c -+++ b/drivers/mtd/spi-nor/macronix.c -@@ -41,7 +41,8 @@ static const struct flash_info macronix_ - { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, - { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, - { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, -- { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K | -+ SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP) }, - { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4, SECT_4K) }, - { "mx25u3235f", INFO(0xc22536, 0, 64 * 1024, 64, - SECT_4K | SPI_NOR_DUAL_READ | diff --git a/target/linux/generic/pending-5.15/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch b/target/linux/generic/pending-5.15/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch deleted file mode 100644 index ec14f6341cc2d8..00000000000000 --- a/target/linux/generic/pending-5.15/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 245224608b5368c10407da07557e546743d3c489 Mon Sep 17 00:00:00 2001 -From: Nick Hainke -Date: Mon, 27 Dec 2021 09:33:13 +0100 -Subject: [PATCH 2/2] mtd: spi-nor: disable 16-bit-sr for macronix - -Macronix flash chips seem to consist of only one status register. -These chips will not work with the "16-bit Write Status (01h) Command". -Disable SNOR_F_HAS_16BIT_SR for all Macronix chips. - -Tested with MX25L6405D. - -Fixes: 39d1e3340c73 ("mtd: spi-nor: Fix clearing of QE bit on -lock()/unlock()") - -Signed-off-by: David Bauer -Signed-off-by: Nick Hainke ---- - drivers/mtd/spi-nor/macronix.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/spi-nor/macronix.c -+++ b/drivers/mtd/spi-nor/macronix.c -@@ -94,6 +94,7 @@ static void macronix_default_init(struct - { - nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; - nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode; -+ nor->flags &= ~SNOR_F_HAS_16BIT_SR; - nor->flags |= SNOR_F_HAS_LOCK; - } - diff --git a/target/linux/generic/pending-5.15/500-fs_cdrom_dependencies.patch b/target/linux/generic/pending-5.15/500-fs_cdrom_dependencies.patch deleted file mode 100644 index 2053c0fbe2e095..00000000000000 --- a/target/linux/generic/pending-5.15/500-fs_cdrom_dependencies.patch +++ /dev/null @@ -1,52 +0,0 @@ -From af7b91bcecce0eae24e90acd35d96ecee73e1407 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:21:15 +0200 -Subject: [PATCH] fs: add cdrom dependency - ---- - fs/hfs/Kconfig | 1 + - fs/hfsplus/Kconfig | 1 + - fs/isofs/Kconfig | 1 + - fs/udf/Kconfig | 1 + - 4 files changed, 4 insertions(+) - ---- a/fs/hfs/Kconfig -+++ b/fs/hfs/Kconfig -@@ -2,6 +2,7 @@ - config HFS_FS - tristate "Apple Macintosh file system support" - depends on BLOCK -+ select CDROM - select NLS - help - If you say Y here, you will be able to mount Macintosh-formatted ---- a/fs/hfsplus/Kconfig -+++ b/fs/hfsplus/Kconfig -@@ -2,6 +2,7 @@ - config HFSPLUS_FS - tristate "Apple Extended HFS file system support" - depends on BLOCK -+ select CDROM - select NLS - select NLS_UTF8 - help ---- a/fs/isofs/Kconfig -+++ b/fs/isofs/Kconfig -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - config ISO9660_FS - tristate "ISO 9660 CDROM file system support" -+ select CDROM - help - This is the standard file system used on CD-ROMs. It was previously - known as "High Sierra File System" and is called "hsfs" on other ---- a/fs/udf/Kconfig -+++ b/fs/udf/Kconfig -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - config UDF_FS - tristate "UDF file system support" -+ select CDROM - select CRC_ITU_T - select NLS - help diff --git a/target/linux/generic/pending-5.15/530-jffs2_make_lzma_available.patch b/target/linux/generic/pending-5.15/530-jffs2_make_lzma_available.patch deleted file mode 100644 index f236657b71602b..00000000000000 --- a/target/linux/generic/pending-5.15/530-jffs2_make_lzma_available.patch +++ /dev/null @@ -1,4581 +0,0 @@ -From: Alexandros C. Couloumbis -Subject: fs: add jffs2/lzma support (not activated by default yet) - -lede-commit: c2c88d315fa0e881f8b19da07b62859b915b11b2 -Signed-off-by: Alexandros C. Couloumbis ---- - fs/jffs2/Kconfig | 9 + - fs/jffs2/Makefile | 3 + - fs/jffs2/compr.c | 6 + - fs/jffs2/compr.h | 10 +- - fs/jffs2/compr_lzma.c | 128 +++ - fs/jffs2/super.c | 33 +- - include/linux/lzma.h | 62 ++ - include/linux/lzma/LzFind.h | 115 +++ - include/linux/lzma/LzHash.h | 54 + - include/linux/lzma/LzmaDec.h | 231 +++++ - include/linux/lzma/LzmaEnc.h | 80 ++ - include/linux/lzma/Types.h | 226 +++++ - include/uapi/linux/jffs2.h | 1 + - lib/Kconfig | 6 + - lib/Makefile | 12 + - lib/lzma/LzFind.c | 761 ++++++++++++++ - lib/lzma/LzmaDec.c | 999 +++++++++++++++++++ - lib/lzma/LzmaEnc.c | 2271 ++++++++++++++++++++++++++++++++++++++++++ - lib/lzma/Makefile | 7 + - 19 files changed, 5008 insertions(+), 6 deletions(-) - create mode 100644 fs/jffs2/compr_lzma.c - create mode 100644 include/linux/lzma.h - create mode 100644 include/linux/lzma/LzFind.h - create mode 100644 include/linux/lzma/LzHash.h - create mode 100644 include/linux/lzma/LzmaDec.h - create mode 100644 include/linux/lzma/LzmaEnc.h - create mode 100644 include/linux/lzma/Types.h - create mode 100644 lib/lzma/LzFind.c - create mode 100644 lib/lzma/LzmaDec.c - create mode 100644 lib/lzma/LzmaEnc.c - create mode 100644 lib/lzma/Makefile - ---- a/fs/jffs2/Kconfig -+++ b/fs/jffs2/Kconfig -@@ -136,6 +136,15 @@ config JFFS2_LZO - This feature was added in July, 2007. Say 'N' if you need - compatibility with older bootloaders or kernels. - -+config JFFS2_LZMA -+ bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS -+ select LZMA_COMPRESS -+ select LZMA_DECOMPRESS -+ depends on JFFS2_FS -+ default n -+ help -+ JFFS2 wrapper to the LZMA C SDK -+ - config JFFS2_RTIME - bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS - depends on JFFS2_FS ---- a/fs/jffs2/Makefile -+++ b/fs/jffs2/Makefile -@@ -19,4 +19,7 @@ jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rub - jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o - jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o - jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o -+jffs2-$(CONFIG_JFFS2_LZMA) += compr_lzma.o - jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o -+ -+CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma ---- a/fs/jffs2/compr.c -+++ b/fs/jffs2/compr.c -@@ -378,6 +378,9 @@ int __init jffs2_compressors_init(void) - #ifdef CONFIG_JFFS2_LZO - jffs2_lzo_init(); - #endif -+#ifdef CONFIG_JFFS2_LZMA -+ jffs2_lzma_init(); -+#endif - /* Setting default compression mode */ - #ifdef CONFIG_JFFS2_CMODE_NONE - jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; -@@ -401,6 +404,9 @@ int __init jffs2_compressors_init(void) - int jffs2_compressors_exit(void) - { - /* Unregistering compressors */ -+#ifdef CONFIG_JFFS2_LZMA -+ jffs2_lzma_exit(); -+#endif - #ifdef CONFIG_JFFS2_LZO - jffs2_lzo_exit(); - #endif ---- a/fs/jffs2/compr.h -+++ b/fs/jffs2/compr.h -@@ -29,9 +29,9 @@ - #define JFFS2_DYNRUBIN_PRIORITY 20 - #define JFFS2_LZARI_PRIORITY 30 - #define JFFS2_RTIME_PRIORITY 50 --#define JFFS2_ZLIB_PRIORITY 60 --#define JFFS2_LZO_PRIORITY 80 -- -+#define JFFS2_LZMA_PRIORITY 70 -+#define JFFS2_ZLIB_PRIORITY 80 -+#define JFFS2_LZO_PRIORITY 90 - - #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ - #define JFFS2_DYNRUBIN_DISABLED /* for decompression */ -@@ -101,5 +101,9 @@ void jffs2_zlib_exit(void); - int jffs2_lzo_init(void); - void jffs2_lzo_exit(void); - #endif -+#ifdef CONFIG_JFFS2_LZMA -+int jffs2_lzma_init(void); -+void jffs2_lzma_exit(void); -+#endif - - #endif /* __JFFS2_COMPR_H__ */ ---- /dev/null -+++ b/fs/jffs2/compr_lzma.c -@@ -0,0 +1,128 @@ -+/* -+ * JFFS2 -- Journalling Flash File System, Version 2. -+ * -+ * For licensing information, see the file 'LICENCE' in this directory. -+ * -+ * JFFS2 wrapper to the LZMA C SDK -+ * -+ */ -+ -+#include -+#include "compr.h" -+ -+#ifdef __KERNEL__ -+ static DEFINE_MUTEX(deflate_mutex); -+#endif -+ -+CLzmaEncHandle *p; -+Byte propsEncoded[LZMA_PROPS_SIZE]; -+SizeT propsSize = sizeof(propsEncoded); -+ -+STATIC void lzma_free_workspace(void) -+{ -+ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); -+} -+ -+STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) -+{ -+ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) -+ { -+ PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); -+ return -ENOMEM; -+ } -+ -+ if (LzmaEnc_SetProps(p, props) != SZ_OK) -+ { -+ lzma_free_workspace(); -+ return -1; -+ } -+ -+ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) -+ { -+ lzma_free_workspace(); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t *sourcelen, uint32_t *dstlen) -+{ -+ SizeT compress_size = (SizeT)(*dstlen); -+ int ret; -+ -+ #ifdef __KERNEL__ -+ mutex_lock(&deflate_mutex); -+ #endif -+ -+ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, -+ 0, NULL, &lzma_alloc, &lzma_alloc); -+ -+ #ifdef __KERNEL__ -+ mutex_unlock(&deflate_mutex); -+ #endif -+ -+ if (ret != SZ_OK) -+ return -1; -+ -+ *dstlen = (uint32_t)compress_size; -+ -+ return 0; -+} -+ -+STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t srclen, uint32_t destlen) -+{ -+ int ret; -+ SizeT dl = (SizeT)destlen; -+ SizeT sl = (SizeT)srclen; -+ ELzmaStatus status; -+ -+ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, -+ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); -+ -+ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) -+ return -1; -+ -+ return 0; -+} -+ -+static struct jffs2_compressor jffs2_lzma_comp = { -+ .priority = JFFS2_LZMA_PRIORITY, -+ .name = "lzma", -+ .compr = JFFS2_COMPR_LZMA, -+ .compress = &jffs2_lzma_compress, -+ .decompress = &jffs2_lzma_decompress, -+ .disabled = 0, -+}; -+ -+int INIT jffs2_lzma_init(void) -+{ -+ int ret; -+ CLzmaEncProps props; -+ LzmaEncProps_Init(&props); -+ -+ props.dictSize = LZMA_BEST_DICT(0x2000); -+ props.level = LZMA_BEST_LEVEL; -+ props.lc = LZMA_BEST_LC; -+ props.lp = LZMA_BEST_LP; -+ props.pb = LZMA_BEST_PB; -+ props.fb = LZMA_BEST_FB; -+ -+ ret = lzma_alloc_workspace(&props); -+ if (ret < 0) -+ return ret; -+ -+ ret = jffs2_register_compressor(&jffs2_lzma_comp); -+ if (ret) -+ lzma_free_workspace(); -+ -+ return ret; -+} -+ -+void jffs2_lzma_exit(void) -+{ -+ jffs2_unregister_compressor(&jffs2_lzma_comp); -+ lzma_free_workspace(); -+} ---- a/fs/jffs2/super.c -+++ b/fs/jffs2/super.c -@@ -374,14 +374,41 @@ static int __init init_jffs2_fs(void) - BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); - BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); - -- pr_info("version 2.2." -+ pr_info("version 2.2" - #ifdef CONFIG_JFFS2_FS_WRITEBUFFER - " (NAND)" - #endif - #ifdef CONFIG_JFFS2_SUMMARY -- " (SUMMARY) " -+ " (SUMMARY)" - #endif -- " © 2001-2006 Red Hat, Inc.\n"); -+#ifdef CONFIG_JFFS2_ZLIB -+ " (ZLIB)" -+#endif -+#ifdef CONFIG_JFFS2_LZO -+ " (LZO)" -+#endif -+#ifdef CONFIG_JFFS2_LZMA -+ " (LZMA)" -+#endif -+#ifdef CONFIG_JFFS2_RTIME -+ " (RTIME)" -+#endif -+#ifdef CONFIG_JFFS2_RUBIN -+ " (RUBIN)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_NONE -+ " (CMODE_NONE)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_PRIORITY -+ " (CMODE_PRIORITY)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_SIZE -+ " (CMODE_SIZE)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO -+ " (CMODE_FAVOURLZO)" -+#endif -+ " (c) 2001-2006 Red Hat, Inc.\n"); - - jffs2_inode_cachep = kmem_cache_create("jffs2_i", - sizeof(struct jffs2_inode_info), ---- /dev/null -+++ b/include/linux/lzma.h -@@ -0,0 +1,62 @@ -+#ifndef __LZMA_H__ -+#define __LZMA_H__ -+ -+#ifdef __KERNEL__ -+ #include -+ #include -+ #include -+ #include -+ #include -+ #define LZMA_MALLOC vmalloc -+ #define LZMA_FREE vfree -+ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg) -+ #define INIT __init -+ #define STATIC static -+#else -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #ifndef PAGE_SIZE -+ extern int page_size; -+ #define PAGE_SIZE page_size -+ #endif -+ #define LZMA_MALLOC malloc -+ #define LZMA_FREE free -+ #define PRINT_ERROR(msg) fprintf(stderr, msg) -+ #define INIT -+ #define STATIC -+#endif -+ -+#include "lzma/LzmaDec.h" -+#include "lzma/LzmaEnc.h" -+ -+#define LZMA_BEST_LEVEL (9) -+#define LZMA_BEST_LC (0) -+#define LZMA_BEST_LP (0) -+#define LZMA_BEST_PB (0) -+#define LZMA_BEST_FB (273) -+ -+#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2) -+ -+static void *p_lzma_malloc(void *p, size_t size) -+{ -+ if (size == 0) -+ return NULL; -+ -+ return LZMA_MALLOC(size); -+} -+ -+static void p_lzma_free(void *p, void *address) -+{ -+ if (address != NULL) -+ LZMA_FREE(address); -+} -+ -+static ISzAlloc lzma_alloc = { .Alloc = p_lzma_malloc, .Free = p_lzma_free }; -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzFind.h -@@ -0,0 +1,98 @@ -+/* LzFind.h -- Match finder for LZ algorithms -+2009-04-22 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZ_FIND_H -+#define __LZ_FIND_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+typedef UInt32 CLzRef; -+ -+typedef struct _CMatchFinder -+{ -+ Byte *buffer; -+ UInt32 pos; -+ UInt32 posLimit; -+ UInt32 streamPos; -+ UInt32 lenLimit; -+ -+ UInt32 cyclicBufferPos; -+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ -+ -+ UInt32 matchMaxLen; -+ CLzRef *hash; -+ CLzRef *son; -+ UInt32 hashMask; -+ UInt32 cutValue; -+ -+ Byte *bufferBase; -+ ISeqInStream *stream; -+ int streamEndWasReached; -+ -+ UInt32 blockSize; -+ UInt32 keepSizeBefore; -+ UInt32 keepSizeAfter; -+ -+ UInt32 numHashBytes; -+ int directInput; -+ size_t directInputRem; -+ int btMode; -+ int bigHash; -+ UInt32 historySize; -+ UInt32 fixedHashSize; -+ UInt32 hashSizeSum; -+ UInt32 numSons; -+ SRes result; -+ UInt32 crc[256]; -+} CMatchFinder; -+ -+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) -+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) -+ -+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) -+ -+void MatchFinder_Construct(CMatchFinder *p); -+ -+/* Conditions: -+ historySize <= 3 GB -+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB -+*/ -+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc); -+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); -+ -+/* -+Conditions: -+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. -+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function -+*/ -+ -+typedef void (*Mf_Init_Func)(void *object); -+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); -+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); -+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); -+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); -+typedef void (*Mf_Skip_Func)(void *object, UInt32); -+ -+typedef struct _IMatchFinder -+{ -+ Mf_Init_Func Init; -+ Mf_GetIndexByte_Func GetIndexByte; -+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; -+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; -+ Mf_GetMatches_Func GetMatches; -+ Mf_Skip_Func Skip; -+} IMatchFinder; -+ -+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzHash.h -@@ -0,0 +1,54 @@ -+/* LzHash.h -- HASH functions for LZ algorithms -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZ_HASH_H -+#define __LZ_HASH_H -+ -+#define kHash2Size (1 << 10) -+#define kHash3Size (1 << 16) -+#define kHash4Size (1 << 20) -+ -+#define kFix3HashSize (kHash2Size) -+#define kFix4HashSize (kHash2Size + kHash3Size) -+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) -+ -+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); -+ -+#define HASH3_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } -+ -+#define HASH4_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } -+ -+#define HASH5_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ -+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ -+ hash4Value &= (kHash4Size - 1); } -+ -+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ -+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; -+ -+ -+#define MT_HASH2_CALC \ -+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); -+ -+#define MT_HASH3_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } -+ -+#define MT_HASH4_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzmaDec.h -@@ -0,0 +1,130 @@ -+/* LzmaDec.h -- LZMA Decoder -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZMA_DEC_H -+#define __LZMA_DEC_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* #define _LZMA_PROB32 */ -+/* _LZMA_PROB32 can increase the speed on some CPUs, -+ but memory usage for CLzmaDec::probs will be doubled in that case */ -+ -+#ifdef _LZMA_PROB32 -+#define CLzmaProb UInt32 -+#else -+#define CLzmaProb UInt16 -+#endif -+ -+ -+/* ---------- LZMA Properties ---------- */ -+ -+#define LZMA_PROPS_SIZE 5 -+ -+typedef struct _CLzmaProps -+{ -+ unsigned lc, lp, pb; -+ UInt32 dicSize; -+} CLzmaProps; -+ -+ -+/* ---------- LZMA Decoder state ---------- */ -+ -+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. -+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ -+ -+#define LZMA_REQUIRED_INPUT_MAX 20 -+ -+typedef struct -+{ -+ CLzmaProps prop; -+ CLzmaProb *probs; -+ Byte *dic; -+ const Byte *buf; -+ UInt32 range, code; -+ SizeT dicPos; -+ SizeT dicBufSize; -+ UInt32 processedPos; -+ UInt32 checkDicSize; -+ unsigned state; -+ UInt32 reps[4]; -+ unsigned remainLen; -+ int needFlush; -+ int needInitState; -+ UInt32 numProbs; -+ unsigned tempBufSize; -+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; -+} CLzmaDec; -+ -+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } -+ -+/* There are two types of LZMA streams: -+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. -+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ -+ -+typedef enum -+{ -+ LZMA_FINISH_ANY, /* finish at any point */ -+ LZMA_FINISH_END /* block must be finished at the end */ -+} ELzmaFinishMode; -+ -+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! -+ -+ You must use LZMA_FINISH_END, when you know that current output buffer -+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. -+ -+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, -+ and output value of destLen will be less than output buffer size limit. -+ You can check status result also. -+ -+ You can use multiple checks to test data integrity after full decompression: -+ 1) Check Result and "status" variable. -+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. -+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. -+ You must use correct finish mode in that case. */ -+ -+typedef enum -+{ -+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ -+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ -+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ -+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ -+} ELzmaStatus; -+ -+/* ELzmaStatus is used only as output value for function call */ -+ -+/* ---------- One Call Interface ---------- */ -+ -+/* LzmaDecode -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (*destLen). -+ LZMA_FINISH_ANY - Decode just destLen bytes. -+ LZMA_FINISH_END - Stream must be finished after (*destLen). -+ -+Returns: -+ SZ_OK -+ status: -+ LZMA_STATUS_FINISHED_WITH_MARK -+ LZMA_STATUS_NOT_FINISHED -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -+ SZ_ERROR_DATA - Data error -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -+*/ -+ -+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+ ELzmaStatus *status, ISzAlloc *alloc); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzmaEnc.h -@@ -0,0 +1,60 @@ -+/* LzmaEnc.h -- LZMA Encoder -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZMA_ENC_H -+#define __LZMA_ENC_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define LZMA_PROPS_SIZE 5 -+ -+typedef struct _CLzmaEncProps -+{ -+ int level; /* 0 <= level <= 9 */ -+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version -+ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version -+ default = (1 << 24) */ -+ int lc; /* 0 <= lc <= 8, default = 3 */ -+ int lp; /* 0 <= lp <= 4, default = 0 */ -+ int pb; /* 0 <= pb <= 4, default = 2 */ -+ int algo; /* 0 - fast, 1 - normal, default = 1 */ -+ int fb; /* 5 <= fb <= 273, default = 32 */ -+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ -+ int numHashBytes; /* 2, 3 or 4, default = 4 */ -+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ -+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ -+ int numThreads; /* 1 or 2, default = 2 */ -+} CLzmaEncProps; -+ -+void LzmaEncProps_Init(CLzmaEncProps *p); -+ -+/* ---------- CLzmaEncHandle Interface ---------- */ -+ -+/* LzmaEnc_* functions can return the following exit codes: -+Returns: -+ SZ_OK - OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_PARAM - Incorrect paramater in props -+ SZ_ERROR_WRITE - Write callback error. -+ SZ_ERROR_PROGRESS - some break from progress callback -+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -+*/ -+ -+typedef void * CLzmaEncHandle; -+ -+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); -+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); -+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); -+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); -+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/Types.h -@@ -0,0 +1,226 @@ -+/* Types.h -- Basic types -+2009-11-23 : Igor Pavlov : Public domain */ -+ -+#ifndef __7Z_TYPES_H -+#define __7Z_TYPES_H -+ -+#include -+ -+#ifdef _WIN32 -+#include -+#endif -+ -+#ifndef EXTERN_C_BEGIN -+#ifdef __cplusplus -+#define EXTERN_C_BEGIN extern "C" { -+#define EXTERN_C_END } -+#else -+#define EXTERN_C_BEGIN -+#define EXTERN_C_END -+#endif -+#endif -+ -+EXTERN_C_BEGIN -+ -+#define SZ_OK 0 -+ -+#define SZ_ERROR_DATA 1 -+#define SZ_ERROR_MEM 2 -+#define SZ_ERROR_CRC 3 -+#define SZ_ERROR_UNSUPPORTED 4 -+#define SZ_ERROR_PARAM 5 -+#define SZ_ERROR_INPUT_EOF 6 -+#define SZ_ERROR_OUTPUT_EOF 7 -+#define SZ_ERROR_READ 8 -+#define SZ_ERROR_WRITE 9 -+#define SZ_ERROR_PROGRESS 10 -+#define SZ_ERROR_FAIL 11 -+#define SZ_ERROR_THREAD 12 -+ -+#define SZ_ERROR_ARCHIVE 16 -+#define SZ_ERROR_NO_ARCHIVE 17 -+ -+typedef int SRes; -+ -+#ifdef _WIN32 -+typedef DWORD WRes; -+#else -+typedef int WRes; -+#endif -+ -+#ifndef RINOK -+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } -+#endif -+ -+typedef unsigned char Byte; -+typedef short Int16; -+typedef unsigned short UInt16; -+ -+#ifdef _LZMA_UINT32_IS_ULONG -+typedef long Int32; -+typedef unsigned long UInt32; -+#else -+typedef int Int32; -+typedef unsigned int UInt32; -+#endif -+ -+#ifdef _SZ_NO_INT_64 -+ -+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. -+ NOTES: Some code will work incorrectly in that case! */ -+ -+typedef long Int64; -+typedef unsigned long UInt64; -+ -+#else -+ -+#if defined(_MSC_VER) || defined(__BORLANDC__) -+typedef __int64 Int64; -+typedef unsigned __int64 UInt64; -+#else -+typedef long long int Int64; -+typedef unsigned long long int UInt64; -+#endif -+ -+#endif -+ -+#ifdef _LZMA_NO_SYSTEM_SIZE_T -+typedef UInt32 SizeT; -+#else -+typedef size_t SizeT; -+#endif -+ -+typedef int Bool; -+#define True 1 -+#define False 0 -+ -+ -+#ifdef _WIN32 -+#define MY_STD_CALL __stdcall -+#else -+#define MY_STD_CALL -+#endif -+ -+#ifdef _MSC_VER -+ -+#if _MSC_VER >= 1300 -+#define MY_NO_INLINE __declspec(noinline) -+#else -+#define MY_NO_INLINE -+#endif -+ -+#define MY_CDECL __cdecl -+#define MY_FAST_CALL __fastcall -+ -+#else -+ -+#define MY_CDECL -+#define MY_FAST_CALL -+ -+#endif -+ -+ -+/* The following interfaces use first parameter as pointer to structure */ -+ -+typedef struct -+{ -+ SRes (*Read)(void *p, void *buf, size_t *size); -+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -+ (output(*size) < input(*size)) is allowed */ -+} ISeqInStream; -+ -+/* it can return SZ_ERROR_INPUT_EOF */ -+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); -+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); -+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); -+ -+typedef struct -+{ -+ size_t (*Write)(void *p, const void *buf, size_t size); -+ /* Returns: result - the number of actually written bytes. -+ (result < size) means error */ -+} ISeqOutStream; -+ -+typedef enum -+{ -+ SZ_SEEK_SET = 0, -+ SZ_SEEK_CUR = 1, -+ SZ_SEEK_END = 2 -+} ESzSeek; -+ -+typedef struct -+{ -+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ -+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -+} ISeekInStream; -+ -+typedef struct -+{ -+ SRes (*Look)(void *p, void **buf, size_t *size); -+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -+ (output(*size) > input(*size)) is not allowed -+ (output(*size) < input(*size)) is allowed */ -+ SRes (*Skip)(void *p, size_t offset); -+ /* offset must be <= output(*size) of Look */ -+ -+ SRes (*Read)(void *p, void *buf, size_t *size); -+ /* reads directly (without buffer). It's same as ISeqInStream::Read */ -+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -+} ILookInStream; -+ -+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); -+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); -+ -+/* reads via ILookInStream::Read */ -+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); -+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); -+ -+#define LookToRead_BUF_SIZE (1 << 14) -+ -+typedef struct -+{ -+ ILookInStream s; -+ ISeekInStream *realStream; -+ size_t pos; -+ size_t size; -+ Byte buf[LookToRead_BUF_SIZE]; -+} CLookToRead; -+ -+void LookToRead_CreateVTable(CLookToRead *p, int lookahead); -+void LookToRead_Init(CLookToRead *p); -+ -+typedef struct -+{ -+ ISeqInStream s; -+ ILookInStream *realStream; -+} CSecToLook; -+ -+void SecToLook_CreateVTable(CSecToLook *p); -+ -+typedef struct -+{ -+ ISeqInStream s; -+ ILookInStream *realStream; -+} CSecToRead; -+ -+void SecToRead_CreateVTable(CSecToRead *p); -+ -+typedef struct -+{ -+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); -+ /* Returns: result. (result != SZ_OK) means break. -+ Value (UInt64)(Int64)-1 for size means unknown value. */ -+} ICompressProgress; -+ -+typedef struct -+{ -+ void *(*Alloc)(void *p, size_t size); -+ void (*Free)(void *p, void *address); /* address can be 0 */ -+} ISzAlloc; -+ -+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -+#define IAlloc_Free(p, a) (p)->Free((p), a) -+ -+EXTERN_C_END -+ -+#endif ---- a/include/uapi/linux/jffs2.h -+++ b/include/uapi/linux/jffs2.h -@@ -46,6 +46,7 @@ - #define JFFS2_COMPR_DYNRUBIN 0x05 - #define JFFS2_COMPR_ZLIB 0x06 - #define JFFS2_COMPR_LZO 0x07 -+#define JFFS2_COMPR_LZMA 0x08 - /* Compatibility flags. */ - #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ - #define JFFS2_NODE_ACCURATE 0x2000 ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -340,6 +340,12 @@ config ZSTD_DECOMPRESS - - source "lib/xz/Kconfig" - -+config LZMA_COMPRESS -+ tristate -+ -+config LZMA_DECOMPRESS -+ tristate -+ - # - # These all provide a common interface (hence the apparent duplication with - # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -135,6 +135,16 @@ CFLAGS_kobject.o += -DDEBUG - CFLAGS_kobject_uevent.o += -DDEBUG - endif - -+ifdef CONFIG_JFFS2_ZLIB -+ CONFIG_ZLIB_INFLATE:=y -+ CONFIG_ZLIB_DEFLATE:=y -+endif -+ -+ifdef CONFIG_JFFS2_LZMA -+ CONFIG_LZMA_DECOMPRESS:=y -+ CONFIG_LZMA_COMPRESS:=y -+endif -+ - obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o - CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any) - -@@ -192,6 +202,8 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ - obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ - obj-$(CONFIG_XZ_DEC) += xz/ - obj-$(CONFIG_RAID6_PQ) += raid6/ -+obj-$(CONFIG_LZMA_COMPRESS) += lzma/ -+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ - - lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o - lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o ---- /dev/null -+++ b/lib/lzma/LzFind.c -@@ -0,0 +1,522 @@ -+/* LzFind.c -- Match finder for LZ algorithms -+2009-04-22 : Igor Pavlov : Public domain */ -+ -+#include -+ -+#include "LzFind.h" -+#include "LzHash.h" -+ -+#define kEmptyHashValue 0 -+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) -+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ -+#define kNormalizeMask (~(kNormalizeStepMin - 1)) -+#define kMaxHistorySize ((UInt32)3 << 30) -+ -+#define kStartMaxLen 3 -+ -+#if 0 -+#define DIRECT_INPUT p->directInput -+#else -+#define DIRECT_INPUT 1 -+#endif -+ -+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ if (!DIRECT_INPUT) -+ { -+ alloc->Free(alloc, p->bufferBase); -+ p->bufferBase = 0; -+ } -+} -+ -+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ -+ -+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) -+{ -+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; -+ if (DIRECT_INPUT) -+ { -+ p->blockSize = blockSize; -+ return 1; -+ } -+ if (p->bufferBase == 0 || p->blockSize != blockSize) -+ { -+ LzInWindow_Free(p, alloc); -+ p->blockSize = blockSize; -+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); -+ } -+ return (p->bufferBase != 0); -+} -+ -+static Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -+static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } -+ -+static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } -+ -+static void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -+{ -+ p->posLimit -= subValue; -+ p->pos -= subValue; -+ p->streamPos -= subValue; -+} -+ -+static void MatchFinder_ReadBlock(CMatchFinder *p) -+{ -+ if (p->streamEndWasReached || p->result != SZ_OK) -+ return; -+ if (DIRECT_INPUT) -+ { -+ UInt32 curSize = 0xFFFFFFFF - p->streamPos; -+ if (curSize > p->directInputRem) -+ curSize = (UInt32)p->directInputRem; -+ p->directInputRem -= curSize; -+ p->streamPos += curSize; -+ if (p->directInputRem == 0) -+ p->streamEndWasReached = 1; -+ return; -+ } -+ for (;;) -+ { -+ Byte *dest = p->buffer + (p->streamPos - p->pos); -+ size_t size = (p->bufferBase + p->blockSize - dest); -+ if (size == 0) -+ return; -+ p->result = p->stream->Read(p->stream, dest, &size); -+ if (p->result != SZ_OK) -+ return; -+ if (size == 0) -+ { -+ p->streamEndWasReached = 1; -+ return; -+ } -+ p->streamPos += (UInt32)size; -+ if (p->streamPos - p->pos > p->keepSizeAfter) -+ return; -+ } -+} -+ -+static void MatchFinder_MoveBlock(CMatchFinder *p) -+{ -+ memmove(p->bufferBase, -+ p->buffer - p->keepSizeBefore, -+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); -+ p->buffer = p->bufferBase + p->keepSizeBefore; -+} -+ -+static int MatchFinder_NeedMove(CMatchFinder *p) -+{ -+ if (DIRECT_INPUT) -+ return 0; -+ /* if (p->streamEndWasReached) return 0; */ -+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); -+} -+ -+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) -+{ -+ if (MatchFinder_NeedMove(p)) -+ MatchFinder_MoveBlock(p); -+ MatchFinder_ReadBlock(p); -+} -+ -+static void MatchFinder_SetDefaultSettings(CMatchFinder *p) -+{ -+ p->cutValue = 32; -+ p->btMode = 1; -+ p->numHashBytes = 4; -+ p->bigHash = 0; -+} -+ -+#define kCrcPoly 0xEDB88320 -+ -+void MatchFinder_Construct(CMatchFinder *p) -+{ -+ UInt32 i; -+ p->bufferBase = 0; -+ p->directInput = 0; -+ p->hash = 0; -+ MatchFinder_SetDefaultSettings(p); -+ -+ for (i = 0; i < 256; i++) -+ { -+ UInt32 r = i; -+ int j; -+ for (j = 0; j < 8; j++) -+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); -+ p->crc[i] = r; -+ } -+} -+ -+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->hash); -+ p->hash = 0; -+} -+ -+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ MatchFinder_FreeThisClassMemory(p, alloc); -+ LzInWindow_Free(p, alloc); -+} -+ -+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) -+{ -+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef); -+ if (sizeInBytes / sizeof(CLzRef) != num) -+ return 0; -+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); -+} -+ -+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc) -+{ -+ UInt32 sizeReserv; -+ if (historySize > kMaxHistorySize) -+ { -+ MatchFinder_Free(p, alloc); -+ return 0; -+ } -+ sizeReserv = historySize >> 1; -+ if (historySize > ((UInt32)2 << 30)) -+ sizeReserv = historySize >> 2; -+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); -+ -+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1; -+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; -+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ -+ if (LzInWindow_Create(p, sizeReserv, alloc)) -+ { -+ UInt32 newCyclicBufferSize = historySize + 1; -+ UInt32 hs; -+ p->matchMaxLen = matchMaxLen; -+ { -+ p->fixedHashSize = 0; -+ if (p->numHashBytes == 2) -+ hs = (1 << 16) - 1; -+ else -+ { -+ hs = historySize - 1; -+ hs |= (hs >> 1); -+ hs |= (hs >> 2); -+ hs |= (hs >> 4); -+ hs |= (hs >> 8); -+ hs >>= 1; -+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */ -+ if (hs > (1 << 24)) -+ { -+ if (p->numHashBytes == 3) -+ hs = (1 << 24) - 1; -+ else -+ hs >>= 1; -+ } -+ } -+ p->hashMask = hs; -+ hs++; -+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; -+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; -+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; -+ hs += p->fixedHashSize; -+ } -+ -+ { -+ UInt32 prevSize = p->hashSizeSum + p->numSons; -+ UInt32 newSize; -+ p->historySize = historySize; -+ p->hashSizeSum = hs; -+ p->cyclicBufferSize = newCyclicBufferSize; -+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); -+ newSize = p->hashSizeSum + p->numSons; -+ if (p->hash != 0 && prevSize == newSize) -+ return 1; -+ MatchFinder_FreeThisClassMemory(p, alloc); -+ p->hash = AllocRefs(newSize, alloc); -+ if (p->hash != 0) -+ { -+ p->son = p->hash + p->hashSizeSum; -+ return 1; -+ } -+ } -+ } -+ MatchFinder_Free(p, alloc); -+ return 0; -+} -+ -+static void MatchFinder_SetLimits(CMatchFinder *p) -+{ -+ UInt32 limit = kMaxValForNormalize - p->pos; -+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; -+ if (limit2 < limit) -+ limit = limit2; -+ limit2 = p->streamPos - p->pos; -+ if (limit2 <= p->keepSizeAfter) -+ { -+ if (limit2 > 0) -+ limit2 = 1; -+ } -+ else -+ limit2 -= p->keepSizeAfter; -+ if (limit2 < limit) -+ limit = limit2; -+ { -+ UInt32 lenLimit = p->streamPos - p->pos; -+ if (lenLimit > p->matchMaxLen) -+ lenLimit = p->matchMaxLen; -+ p->lenLimit = lenLimit; -+ } -+ p->posLimit = p->pos + limit; -+} -+ -+static void MatchFinder_Init(CMatchFinder *p) -+{ -+ UInt32 i; -+ for (i = 0; i < p->hashSizeSum; i++) -+ p->hash[i] = kEmptyHashValue; -+ p->cyclicBufferPos = 0; -+ p->buffer = p->bufferBase; -+ p->pos = p->streamPos = p->cyclicBufferSize; -+ p->result = SZ_OK; -+ p->streamEndWasReached = 0; -+ MatchFinder_ReadBlock(p); -+ MatchFinder_SetLimits(p); -+} -+ -+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) -+{ -+ return (p->pos - p->historySize - 1) & kNormalizeMask; -+} -+ -+static void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -+{ -+ UInt32 i; -+ for (i = 0; i < numItems; i++) -+ { -+ UInt32 value = items[i]; -+ if (value <= subValue) -+ value = kEmptyHashValue; -+ else -+ value -= subValue; -+ items[i] = value; -+ } -+} -+ -+static void MatchFinder_Normalize(CMatchFinder *p) -+{ -+ UInt32 subValue = MatchFinder_GetSubValue(p); -+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); -+ MatchFinder_ReduceOffsets(p, subValue); -+} -+ -+static void MatchFinder_CheckLimits(CMatchFinder *p) -+{ -+ if (p->pos == kMaxValForNormalize) -+ MatchFinder_Normalize(p); -+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) -+ MatchFinder_CheckAndMoveAndRead(p); -+ if (p->cyclicBufferPos == p->cyclicBufferSize) -+ p->cyclicBufferPos = 0; -+ MatchFinder_SetLimits(p); -+} -+ -+static UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+ UInt32 *distances, UInt32 maxLen) -+{ -+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -+ UInt32 len0 = 0, len1 = 0; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ { -+ *ptr0 = *ptr1 = kEmptyHashValue; -+ return distances; -+ } -+ { -+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -+ const Byte *pb = cur - delta; -+ UInt32 len = (len0 < len1 ? len0 : len1); -+ if (pb[len] == cur[len]) -+ { -+ if (++len != lenLimit && pb[len] == cur[len]) -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ if (maxLen < len) -+ { -+ *distances++ = maxLen = len; -+ *distances++ = delta - 1; -+ if (len == lenLimit) -+ { -+ *ptr1 = pair[0]; -+ *ptr0 = pair[1]; -+ return distances; -+ } -+ } -+ } -+ if (pb[len] < cur[len]) -+ { -+ *ptr1 = curMatch; -+ ptr1 = pair + 1; -+ curMatch = *ptr1; -+ len1 = len; -+ } -+ else -+ { -+ *ptr0 = curMatch; -+ ptr0 = pair; -+ curMatch = *ptr0; -+ len0 = len; -+ } -+ } -+ } -+} -+ -+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) -+{ -+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -+ UInt32 len0 = 0, len1 = 0; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ { -+ *ptr0 = *ptr1 = kEmptyHashValue; -+ return; -+ } -+ { -+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -+ const Byte *pb = cur - delta; -+ UInt32 len = (len0 < len1 ? len0 : len1); -+ if (pb[len] == cur[len]) -+ { -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ { -+ if (len == lenLimit) -+ { -+ *ptr1 = pair[0]; -+ *ptr0 = pair[1]; -+ return; -+ } -+ } -+ } -+ if (pb[len] < cur[len]) -+ { -+ *ptr1 = curMatch; -+ ptr1 = pair + 1; -+ curMatch = *ptr1; -+ len1 = len; -+ } -+ else -+ { -+ *ptr0 = curMatch; -+ ptr0 = pair; -+ curMatch = *ptr0; -+ len0 = len; -+ } -+ } -+ } -+} -+ -+#define MOVE_POS \ -+ ++p->cyclicBufferPos; \ -+ p->buffer++; \ -+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); -+ -+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } -+ -+#define MOVE_POS_RET MatchFinder_MovePos(p); return offset; -+ -+#define GET_MATCHES_HEADER2(minLen, ret_op) \ -+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ -+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ -+ cur = p->buffer; -+ -+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) -+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) -+ -+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue -+ -+#define GET_MATCHES_FOOTER(offset, maxLen) \ -+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ -+ distances + offset, maxLen) - distances); MOVE_POS_RET; -+ -+#define SKIP_FOOTER \ -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MatchFinder_MovePos(p); -+ -+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -+ GET_MATCHES_HEADER(4) -+ -+ HASH4_CALC; -+ -+ delta2 = p->pos - p->hash[ hash2Value]; -+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ -+ maxLen = 1; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+ { -+ distances[0] = maxLen = 2; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ } -+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -+ { -+ maxLen = 3; -+ distances[offset + 1] = delta3 - 1; -+ offset += 2; -+ delta2 = delta3; -+ } -+ if (offset != 0) -+ { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[offset - 2] = maxLen; -+ if (maxLen == lenLimit) -+ { -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -+ MOVE_POS_RET; -+ } -+ } -+ if (maxLen < 3) -+ maxLen = 3; -+ GET_MATCHES_FOOTER(offset, maxLen) -+} -+ -+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ UInt32 hash2Value, hash3Value; -+ SKIP_HEADER(4) -+ HASH4_CALC; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = p->pos; -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) -+{ -+ vTable->Init = (Mf_Init_Func)MatchFinder_Init; -+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; -+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; -+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; -+} ---- /dev/null -+++ b/lib/lzma/LzmaDec.c -@@ -0,0 +1,925 @@ -+/* LzmaDec.c -- LZMA Decoder -+2009-09-20 : Igor Pavlov : Public domain */ -+ -+#include "LzmaDec.h" -+ -+#include -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+ -+#define RC_INIT_SIZE 5 -+ -+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } -+ -+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); -+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ -+ { UPDATE_0(p); i = (i + i); A0; } else \ -+ { UPDATE_1(p); i = (i + i) + 1; A1; } -+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) -+ -+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } -+#define TREE_DECODE(probs, limit, i) \ -+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } -+ -+/* #define _LZMA_SIZE_OPT */ -+ -+#ifdef _LZMA_SIZE_OPT -+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) -+#else -+#define TREE_6_DECODE(probs, i) \ -+ { i = 1; \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ i -= 0x40; } -+#endif -+ -+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } -+ -+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -+#define UPDATE_0_CHECK range = bound; -+#define UPDATE_1_CHECK range -= bound; code -= bound; -+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ -+ { UPDATE_0_CHECK; i = (i + i); A0; } else \ -+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } -+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) -+#define TREE_DECODE_CHECK(probs, limit, i) \ -+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } -+ -+ -+#define kNumPosBitsMax 4 -+#define kNumPosStatesMax (1 << kNumPosBitsMax) -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define LenChoice 0 -+#define LenChoice2 (LenChoice + 1) -+#define LenLow (LenChoice2 + 1) -+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) -+ -+ -+#define kNumStates 12 -+#define kNumLitStates 7 -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#define kNumPosSlotBits 6 -+#define kNumLenToPosStates 4 -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+ -+#define kMatchMinLen 2 -+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -+ -+#define IsMatch 0 -+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -+#define IsRepG0 (IsRep + kNumStates) -+#define IsRepG1 (IsRepG0 + kNumStates) -+#define IsRepG2 (IsRepG1 + kNumStates) -+#define IsRep0Long (IsRepG2 + kNumStates) -+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -+#define LenCoder (Align + kAlignTableSize) -+#define RepLenCoder (LenCoder + kNumLenProbs) -+#define Literal (RepLenCoder + kNumLenProbs) -+ -+#define LZMA_BASE_SIZE 1846 -+#define LZMA_LIT_SIZE 768 -+ -+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) -+ -+#if Literal != LZMA_BASE_SIZE -+StopCompilingDueBUG -+#endif -+ -+#define LZMA_DIC_MIN (1 << 12) -+ -+/* First LZMA-symbol is always decoded. -+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization -+Out: -+ Result: -+ SZ_OK - OK -+ SZ_ERROR_DATA - Error -+ p->remainLen: -+ < kMatchSpecLenStart : normal remain -+ = kMatchSpecLenStart : finished -+ = kMatchSpecLenStart + 1 : Flush marker -+ = kMatchSpecLenStart + 2 : State Init Marker -+*/ -+ -+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -+{ -+ CLzmaProb *probs = p->probs; -+ -+ unsigned state = p->state; -+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; -+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; -+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; -+ unsigned lc = p->prop.lc; -+ -+ Byte *dic = p->dic; -+ SizeT dicBufSize = p->dicBufSize; -+ SizeT dicPos = p->dicPos; -+ -+ UInt32 processedPos = p->processedPos; -+ UInt32 checkDicSize = p->checkDicSize; -+ unsigned len = 0; -+ -+ const Byte *buf = p->buf; -+ UInt32 range = p->range; -+ UInt32 code = p->code; -+ -+ do -+ { -+ CLzmaProb *prob; -+ UInt32 bound; -+ unsigned ttt; -+ unsigned posState = processedPos & pbMask; -+ -+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0(prob) -+ { -+ unsigned symbol; -+ UPDATE_0(prob); -+ prob = probs + Literal; -+ if (checkDicSize != 0 || processedPos != 0) -+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + -+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); -+ -+ if (state < kNumLitStates) -+ { -+ state -= (state < 4) ? state : 3; -+ symbol = 1; -+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); -+ } -+ else -+ { -+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ unsigned offs = 0x100; -+ state -= (state < 10) ? 3 : 6; -+ symbol = 1; -+ do -+ { -+ unsigned bit; -+ CLzmaProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & offs); -+ probLit = prob + offs + bit + symbol; -+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) -+ } -+ while (symbol < 0x100); -+ } -+ dic[dicPos++] = (Byte)symbol; -+ processedPos++; -+ continue; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ prob = probs + IsRep + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ state += kNumStates; -+ prob = probs + LenCoder; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ if (checkDicSize == 0 && processedPos == 0) -+ return SZ_ERROR_DATA; -+ prob = probs + IsRepG0 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ dicPos++; -+ processedPos++; -+ state = state < kNumLitStates ? 9 : 11; -+ continue; -+ } -+ UPDATE_1(prob); -+ } -+ else -+ { -+ UInt32 distance; -+ UPDATE_1(prob); -+ prob = probs + IsRepG1 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ distance = rep1; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ prob = probs + IsRepG2 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ distance = rep2; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ distance = rep3; -+ rep3 = rep2; -+ } -+ rep2 = rep1; -+ } -+ rep1 = rep0; -+ rep0 = distance; -+ } -+ state = state < kNumLitStates ? 8 : 11; -+ prob = probs + RepLenCoder; -+ } -+ { -+ unsigned limit, offset; -+ CLzmaProb *probLen = prob + LenChoice; -+ IF_BIT_0(probLen) -+ { -+ UPDATE_0(probLen); -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ limit = (1 << kLenNumLowBits); -+ } -+ else -+ { -+ UPDATE_1(probLen); -+ probLen = prob + LenChoice2; -+ IF_BIT_0(probLen) -+ { -+ UPDATE_0(probLen); -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ limit = (1 << kLenNumMidBits); -+ } -+ else -+ { -+ UPDATE_1(probLen); -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ limit = (1 << kLenNumHighBits); -+ } -+ } -+ TREE_DECODE(probLen, limit, len); -+ len += offset; -+ } -+ -+ if (state >= kNumStates) -+ { -+ UInt32 distance; -+ prob = probs + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); -+ TREE_6_DECODE(prob, distance); -+ if (distance >= kStartPosModelIndex) -+ { -+ unsigned posSlot = (unsigned)distance; -+ int numDirectBits = (int)(((distance >> 1) - 1)); -+ distance = (2 | (distance & 1)); -+ if (posSlot < kEndPosModelIndex) -+ { -+ distance <<= numDirectBits; -+ prob = probs + SpecPos + distance - posSlot - 1; -+ { -+ UInt32 mask = 1; -+ unsigned i = 1; -+ do -+ { -+ GET_BIT2(prob + i, i, ; , distance |= mask); -+ mask <<= 1; -+ } -+ while (--numDirectBits != 0); -+ } -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ NORMALIZE -+ range >>= 1; -+ -+ { -+ UInt32 t; -+ code -= range; -+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ -+ distance = (distance << 1) + (t + 1); -+ code += range & t; -+ } -+ /* -+ distance <<= 1; -+ if (code >= range) -+ { -+ code -= range; -+ distance |= 1; -+ } -+ */ -+ } -+ while (--numDirectBits != 0); -+ prob = probs + Align; -+ distance <<= kNumAlignBits; -+ { -+ unsigned i = 1; -+ GET_BIT2(prob + i, i, ; , distance |= 1); -+ GET_BIT2(prob + i, i, ; , distance |= 2); -+ GET_BIT2(prob + i, i, ; , distance |= 4); -+ GET_BIT2(prob + i, i, ; , distance |= 8); -+ } -+ if (distance == (UInt32)0xFFFFFFFF) -+ { -+ len += kMatchSpecLenStart; -+ state -= kNumStates; -+ break; -+ } -+ } -+ } -+ rep3 = rep2; -+ rep2 = rep1; -+ rep1 = rep0; -+ rep0 = distance + 1; -+ if (checkDicSize == 0) -+ { -+ if (distance >= processedPos) -+ return SZ_ERROR_DATA; -+ } -+ else if (distance >= checkDicSize) -+ return SZ_ERROR_DATA; -+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; -+ } -+ -+ len += kMatchMinLen; -+ -+ if (limit == dicPos) -+ return SZ_ERROR_DATA; -+ { -+ SizeT rem = limit - dicPos; -+ unsigned curLen = ((rem < len) ? (unsigned)rem : len); -+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); -+ -+ processedPos += curLen; -+ -+ len -= curLen; -+ if (pos + curLen <= dicBufSize) -+ { -+ Byte *dest = dic + dicPos; -+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; -+ const Byte *lim = dest + curLen; -+ dicPos += curLen; -+ do -+ *(dest) = (Byte)*(dest + src); -+ while (++dest != lim); -+ } -+ else -+ { -+ do -+ { -+ dic[dicPos++] = dic[pos]; -+ if (++pos == dicBufSize) -+ pos = 0; -+ } -+ while (--curLen != 0); -+ } -+ } -+ } -+ } -+ while (dicPos < limit && buf < bufLimit); -+ NORMALIZE; -+ p->buf = buf; -+ p->range = range; -+ p->code = code; -+ p->remainLen = len; -+ p->dicPos = dicPos; -+ p->processedPos = processedPos; -+ p->reps[0] = rep0; -+ p->reps[1] = rep1; -+ p->reps[2] = rep2; -+ p->reps[3] = rep3; -+ p->state = state; -+ -+ return SZ_OK; -+} -+ -+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) -+{ -+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) -+ { -+ Byte *dic = p->dic; -+ SizeT dicPos = p->dicPos; -+ SizeT dicBufSize = p->dicBufSize; -+ unsigned len = p->remainLen; -+ UInt32 rep0 = p->reps[0]; -+ if (limit - dicPos < len) -+ len = (unsigned)(limit - dicPos); -+ -+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) -+ p->checkDicSize = p->prop.dicSize; -+ -+ p->processedPos += len; -+ p->remainLen -= len; -+ while (len-- != 0) -+ { -+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ dicPos++; -+ } -+ p->dicPos = dicPos; -+ } -+} -+ -+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -+{ -+ do -+ { -+ SizeT limit2 = limit; -+ if (p->checkDicSize == 0) -+ { -+ UInt32 rem = p->prop.dicSize - p->processedPos; -+ if (limit - p->dicPos > rem) -+ limit2 = p->dicPos + rem; -+ } -+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); -+ if (p->processedPos >= p->prop.dicSize) -+ p->checkDicSize = p->prop.dicSize; -+ LzmaDec_WriteRem(p, limit); -+ } -+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); -+ -+ if (p->remainLen > kMatchSpecLenStart) -+ { -+ p->remainLen = kMatchSpecLenStart; -+ } -+ return 0; -+} -+ -+typedef enum -+{ -+ DUMMY_ERROR, /* unexpected end of input stream */ -+ DUMMY_LIT, -+ DUMMY_MATCH, -+ DUMMY_REP -+} ELzmaDummy; -+ -+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) -+{ -+ UInt32 range = p->range; -+ UInt32 code = p->code; -+ const Byte *bufLimit = buf + inSize; -+ CLzmaProb *probs = p->probs; -+ unsigned state = p->state; -+ ELzmaDummy res; -+ -+ { -+ CLzmaProb *prob; -+ UInt32 bound; -+ unsigned ttt; -+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); -+ -+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK -+ -+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ -+ -+ prob = probs + Literal; -+ if (p->checkDicSize != 0 || p->processedPos != 0) -+ prob += (LZMA_LIT_SIZE * -+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + -+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); -+ -+ if (state < kNumLitStates) -+ { -+ unsigned symbol = 1; -+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); -+ } -+ else -+ { -+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + -+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; -+ unsigned offs = 0x100; -+ unsigned symbol = 1; -+ do -+ { -+ unsigned bit; -+ CLzmaProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & offs); -+ probLit = prob + offs + bit + symbol; -+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) -+ } -+ while (symbol < 0x100); -+ } -+ res = DUMMY_LIT; -+ } -+ else -+ { -+ unsigned len; -+ UPDATE_1_CHECK; -+ -+ prob = probs + IsRep + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ state = 0; -+ prob = probs + LenCoder; -+ res = DUMMY_MATCH; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ res = DUMMY_REP; -+ prob = probs + IsRepG0 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ NORMALIZE_CHECK; -+ return DUMMY_REP; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ } -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ prob = probs + IsRepG1 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ prob = probs + IsRepG2 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ } -+ } -+ } -+ state = kNumStates; -+ prob = probs + RepLenCoder; -+ } -+ { -+ unsigned limit, offset; -+ CLzmaProb *probLen = prob + LenChoice; -+ IF_BIT_0_CHECK(probLen) -+ { -+ UPDATE_0_CHECK; -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ limit = 1 << kLenNumLowBits; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ probLen = prob + LenChoice2; -+ IF_BIT_0_CHECK(probLen) -+ { -+ UPDATE_0_CHECK; -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ limit = 1 << kLenNumMidBits; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ limit = 1 << kLenNumHighBits; -+ } -+ } -+ TREE_DECODE_CHECK(probLen, limit, len); -+ len += offset; -+ } -+ -+ if (state < 4) -+ { -+ unsigned posSlot; -+ prob = probs + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << -+ kNumPosSlotBits); -+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); -+ if (posSlot >= kStartPosModelIndex) -+ { -+ int numDirectBits = ((posSlot >> 1) - 1); -+ -+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ -+ -+ if (posSlot < kEndPosModelIndex) -+ { -+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ NORMALIZE_CHECK -+ range >>= 1; -+ code -= range & (((code - range) >> 31) - 1); -+ /* if (code >= range) code -= range; */ -+ } -+ while (--numDirectBits != 0); -+ prob = probs + Align; -+ numDirectBits = kNumAlignBits; -+ } -+ { -+ unsigned i = 1; -+ do -+ { -+ GET_BIT_CHECK(prob + i, i); -+ } -+ while (--numDirectBits != 0); -+ } -+ } -+ } -+ } -+ } -+ NORMALIZE_CHECK; -+ return res; -+} -+ -+ -+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) -+{ -+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); -+ p->range = 0xFFFFFFFF; -+ p->needFlush = 0; -+} -+ -+static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -+{ -+ p->needFlush = 1; -+ p->remainLen = 0; -+ p->tempBufSize = 0; -+ -+ if (initDic) -+ { -+ p->processedPos = 0; -+ p->checkDicSize = 0; -+ p->needInitState = 1; -+ } -+ if (initState) -+ p->needInitState = 1; -+} -+ -+static void LzmaDec_Init(CLzmaDec *p) -+{ -+ p->dicPos = 0; -+ LzmaDec_InitDicAndState(p, True, True); -+} -+ -+static void LzmaDec_InitStateReal(CLzmaDec *p) -+{ -+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); -+ UInt32 i; -+ CLzmaProb *probs = p->probs; -+ for (i = 0; i < numProbs; i++) -+ probs[i] = kBitModelTotal >> 1; -+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; -+ p->state = 0; -+ p->needInitState = 0; -+} -+ -+static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, -+ ELzmaFinishMode finishMode, ELzmaStatus *status) -+{ -+ SizeT inSize = *srcLen; -+ (*srcLen) = 0; -+ LzmaDec_WriteRem(p, dicLimit); -+ -+ *status = LZMA_STATUS_NOT_SPECIFIED; -+ -+ while (p->remainLen != kMatchSpecLenStart) -+ { -+ int checkEndMarkNow; -+ -+ if (p->needFlush != 0) -+ { -+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) -+ p->tempBuf[p->tempBufSize++] = *src++; -+ if (p->tempBufSize < RC_INIT_SIZE) -+ { -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (p->tempBuf[0] != 0) -+ return SZ_ERROR_DATA; -+ -+ LzmaDec_InitRc(p, p->tempBuf); -+ p->tempBufSize = 0; -+ } -+ -+ checkEndMarkNow = 0; -+ if (p->dicPos >= dicLimit) -+ { -+ if (p->remainLen == 0 && p->code == 0) -+ { -+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; -+ return SZ_OK; -+ } -+ if (finishMode == LZMA_FINISH_ANY) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_OK; -+ } -+ if (p->remainLen != 0) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ checkEndMarkNow = 1; -+ } -+ -+ if (p->needInitState) -+ LzmaDec_InitStateReal(p); -+ -+ if (p->tempBufSize == 0) -+ { -+ SizeT processed; -+ const Byte *bufLimit; -+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -+ { -+ int dummyRes = LzmaDec_TryDummy(p, src, inSize); -+ if (dummyRes == DUMMY_ERROR) -+ { -+ memcpy(p->tempBuf, src, inSize); -+ p->tempBufSize = (unsigned)inSize; -+ (*srcLen) += inSize; -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ bufLimit = src; -+ } -+ else -+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; -+ p->buf = src; -+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) -+ return SZ_ERROR_DATA; -+ processed = (SizeT)(p->buf - src); -+ (*srcLen) += processed; -+ src += processed; -+ inSize -= processed; -+ } -+ else -+ { -+ unsigned rem = p->tempBufSize, lookAhead = 0; -+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) -+ p->tempBuf[rem++] = src[lookAhead++]; -+ p->tempBufSize = rem; -+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -+ { -+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); -+ if (dummyRes == DUMMY_ERROR) -+ { -+ (*srcLen) += lookAhead; -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ } -+ p->buf = p->tempBuf; -+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) -+ return SZ_ERROR_DATA; -+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); -+ (*srcLen) += lookAhead; -+ src += lookAhead; -+ inSize -= lookAhead; -+ p->tempBufSize = 0; -+ } -+ } -+ if (p->code == 0) -+ *status = LZMA_STATUS_FINISHED_WITH_MARK; -+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -+} -+ -+static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->probs); -+ p->probs = 0; -+} -+ -+static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -+{ -+ UInt32 dicSize; -+ Byte d; -+ -+ if (size < LZMA_PROPS_SIZE) -+ return SZ_ERROR_UNSUPPORTED; -+ else -+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); -+ -+ if (dicSize < LZMA_DIC_MIN) -+ dicSize = LZMA_DIC_MIN; -+ p->dicSize = dicSize; -+ -+ d = data[0]; -+ if (d >= (9 * 5 * 5)) -+ return SZ_ERROR_UNSUPPORTED; -+ -+ p->lc = d % 9; -+ d /= 9; -+ p->pb = d / 5; -+ p->lp = d % 5; -+ -+ return SZ_OK; -+} -+ -+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) -+{ -+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew); -+ if (p->probs == 0 || numProbs != p->numProbs) -+ { -+ LzmaDec_FreeProbs(p, alloc); -+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); -+ p->numProbs = numProbs; -+ if (p->probs == 0) -+ return SZ_ERROR_MEM; -+ } -+ return SZ_OK; -+} -+ -+static SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+{ -+ CLzmaProps propNew; -+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -+ p->prop = propNew; -+ return SZ_OK; -+} -+ -+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+ ELzmaStatus *status, ISzAlloc *alloc) -+{ -+ CLzmaDec p; -+ SRes res; -+ SizeT inSize = *srcLen; -+ SizeT outSize = *destLen; -+ *srcLen = *destLen = 0; -+ if (inSize < RC_INIT_SIZE) -+ return SZ_ERROR_INPUT_EOF; -+ -+ LzmaDec_Construct(&p); -+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); -+ if (res != 0) -+ return res; -+ p.dic = dest; -+ p.dicBufSize = outSize; -+ -+ LzmaDec_Init(&p); -+ -+ *srcLen = inSize; -+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); -+ -+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) -+ res = SZ_ERROR_INPUT_EOF; -+ -+ (*destLen) = p.dicPos; -+ LzmaDec_FreeProbs(&p, alloc); -+ return res; -+} ---- /dev/null -+++ b/lib/lzma/LzmaEnc.c -@@ -0,0 +1,2123 @@ -+/* LzmaEnc.c -- LZMA Encoder -+2009-11-24 : Igor Pavlov : Public domain */ -+ -+#include -+ -+/* #define SHOW_STAT */ -+/* #define SHOW_STAT2 */ -+ -+#if defined(SHOW_STAT) || defined(SHOW_STAT2) -+#include -+#endif -+ -+#include "LzmaEnc.h" -+ -+/* disable MT */ -+#define _7ZIP_ST -+ -+#include "LzFind.h" -+#ifndef _7ZIP_ST -+#include "LzFindMt.h" -+#endif -+ -+#ifdef SHOW_STAT -+static int ttt = 0; -+#endif -+ -+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) -+ -+#define kBlockSize (9 << 10) -+#define kUnpackBlockSize (1 << 18) -+#define kMatchArraySize (1 << 21) -+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) -+ -+#define kNumMaxDirectBits (31) -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+#define kProbInitValue (kBitModelTotal >> 1) -+ -+#define kNumMoveReducingBits 4 -+#define kNumBitPriceShiftBits 4 -+#define kBitPrice (1 << kNumBitPriceShiftBits) -+ -+void LzmaEncProps_Init(CLzmaEncProps *p) -+{ -+ p->level = 5; -+ p->dictSize = p->mc = 0; -+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; -+ p->writeEndMark = 0; -+} -+ -+static void LzmaEncProps_Normalize(CLzmaEncProps *p) -+{ -+ int level = p->level; -+ if (level < 0) level = 5; -+ p->level = level; -+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); -+ if (p->lc < 0) p->lc = 3; -+ if (p->lp < 0) p->lp = 0; -+ if (p->pb < 0) p->pb = 2; -+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); -+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); -+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); -+ if (p->numHashBytes < 0) p->numHashBytes = 4; -+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); -+ if (p->numThreads < 0) -+ p->numThreads = -+ #ifndef _7ZIP_ST -+ ((p->btMode && p->algo) ? 2 : 1); -+ #else -+ 1; -+ #endif -+} -+ -+static UInt32 __maybe_unused LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -+{ -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+ return props.dictSize; -+} -+ -+/* #define LZMA_LOG_BSR */ -+/* Define it for Intel's CPU */ -+ -+ -+#ifdef LZMA_LOG_BSR -+ -+#define kDicLogSizeMaxCompress 30 -+ -+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } -+ -+static UInt32 GetPosSlot1(UInt32 pos) -+{ -+ UInt32 res; -+ BSR2_RET(pos, res); -+ return res; -+} -+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } -+ -+#else -+ -+#define kNumLogBits (9 + (int)sizeof(size_t) / 2) -+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) -+ -+static void LzmaEnc_FastPosInit(Byte *g_FastPos) -+{ -+ int c = 2, slotFast; -+ g_FastPos[0] = 0; -+ g_FastPos[1] = 1; -+ -+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) -+ { -+ UInt32 k = (1 << ((slotFast >> 1) - 1)); -+ UInt32 j; -+ for (j = 0; j < k; j++, c++) -+ g_FastPos[c] = (Byte)slotFast; -+ } -+} -+ -+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ -+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ -+ res = p->g_FastPos[pos >> i] + (i * 2); } -+/* -+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ -+ p->g_FastPos[pos >> 6] + 12 : \ -+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } -+*/ -+ -+#define GetPosSlot1(pos) p->g_FastPos[pos] -+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } -+ -+#endif -+ -+ -+#define LZMA_NUM_REPS 4 -+ -+typedef unsigned CState; -+ -+typedef struct -+{ -+ UInt32 price; -+ -+ CState state; -+ int prev1IsChar; -+ int prev2; -+ -+ UInt32 posPrev2; -+ UInt32 backPrev2; -+ -+ UInt32 posPrev; -+ UInt32 backPrev; -+ UInt32 backs[LZMA_NUM_REPS]; -+} COptimal; -+ -+#define kNumOpts (1 << 12) -+ -+#define kNumLenToPosStates 4 -+#define kNumPosSlotBits 6 -+#define kDicLogSizeMin 0 -+#define kDicLogSizeMax 32 -+#define kDistTableSizeMax (kDicLogSizeMax * 2) -+ -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+#define kAlignMask (kAlignTableSize - 1) -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) -+ -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#ifdef _LZMA_PROB32 -+#define CLzmaProb UInt32 -+#else -+#define CLzmaProb UInt16 -+#endif -+ -+#define LZMA_PB_MAX 4 -+#define LZMA_LC_MAX 8 -+#define LZMA_LP_MAX 4 -+ -+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) -+ -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -+ -+#define LZMA_MATCH_LEN_MIN 2 -+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) -+ -+#define kNumStates 12 -+ -+typedef struct -+{ -+ CLzmaProb choice; -+ CLzmaProb choice2; -+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; -+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; -+ CLzmaProb high[kLenNumHighSymbols]; -+} CLenEnc; -+ -+typedef struct -+{ -+ CLenEnc p; -+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; -+ UInt32 tableSize; -+ UInt32 counters[LZMA_NUM_PB_STATES_MAX]; -+} CLenPriceEnc; -+ -+typedef struct -+{ -+ UInt32 range; -+ Byte cache; -+ UInt64 low; -+ UInt64 cacheSize; -+ Byte *buf; -+ Byte *bufLim; -+ Byte *bufBase; -+ ISeqOutStream *outStream; -+ UInt64 processed; -+ SRes res; -+} CRangeEnc; -+ -+typedef struct -+{ -+ CLzmaProb *litProbs; -+ -+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ CLzmaProb isRep[kNumStates]; -+ CLzmaProb isRepG0[kNumStates]; -+ CLzmaProb isRepG1[kNumStates]; -+ CLzmaProb isRepG2[kNumStates]; -+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ -+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -+ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -+ -+ CLenPriceEnc lenEnc; -+ CLenPriceEnc repLenEnc; -+ -+ UInt32 reps[LZMA_NUM_REPS]; -+ UInt32 state; -+} CSaveState; -+ -+typedef struct -+{ -+ IMatchFinder matchFinder; -+ void *matchFinderObj; -+ -+ #ifndef _7ZIP_ST -+ Bool mtMode; -+ CMatchFinderMt matchFinderMt; -+ #endif -+ -+ CMatchFinder matchFinderBase; -+ -+ #ifndef _7ZIP_ST -+ Byte pad[128]; -+ #endif -+ -+ UInt32 optimumEndIndex; -+ UInt32 optimumCurrentIndex; -+ -+ UInt32 longestMatchLength; -+ UInt32 numPairs; -+ UInt32 numAvail; -+ COptimal opt[kNumOpts]; -+ -+ #ifndef LZMA_LOG_BSR -+ Byte g_FastPos[1 << kNumLogBits]; -+ #endif -+ -+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; -+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; -+ UInt32 numFastBytes; -+ UInt32 additionalOffset; -+ UInt32 reps[LZMA_NUM_REPS]; -+ UInt32 state; -+ -+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; -+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; -+ UInt32 alignPrices[kAlignTableSize]; -+ UInt32 alignPriceCount; -+ -+ UInt32 distTableSize; -+ -+ unsigned lc, lp, pb; -+ unsigned lpMask, pbMask; -+ -+ CLzmaProb *litProbs; -+ -+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ CLzmaProb isRep[kNumStates]; -+ CLzmaProb isRepG0[kNumStates]; -+ CLzmaProb isRepG1[kNumStates]; -+ CLzmaProb isRepG2[kNumStates]; -+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ -+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -+ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -+ -+ CLenPriceEnc lenEnc; -+ CLenPriceEnc repLenEnc; -+ -+ unsigned lclp; -+ -+ Bool fastMode; -+ -+ CRangeEnc rc; -+ -+ Bool writeEndMark; -+ UInt64 nowPos64; -+ UInt32 matchPriceCount; -+ Bool finished; -+ Bool multiThread; -+ -+ SRes result; -+ UInt32 dictSize; -+ UInt32 matchFinderCycles; -+ -+ int needInit; -+ -+ CSaveState saveState; -+} CLzmaEnc; -+ -+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+ -+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || -+ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) -+ return SZ_ERROR_PARAM; -+ p->dictSize = props.dictSize; -+ p->matchFinderCycles = props.mc; -+ { -+ unsigned fb = props.fb; -+ if (fb < 5) -+ fb = 5; -+ if (fb > LZMA_MATCH_LEN_MAX) -+ fb = LZMA_MATCH_LEN_MAX; -+ p->numFastBytes = fb; -+ } -+ p->lc = props.lc; -+ p->lp = props.lp; -+ p->pb = props.pb; -+ p->fastMode = (props.algo == 0); -+ p->matchFinderBase.btMode = props.btMode; -+ { -+ UInt32 numHashBytes = 4; -+ if (props.btMode) -+ { -+ if (props.numHashBytes < 2) -+ numHashBytes = 2; -+ else if (props.numHashBytes < 4) -+ numHashBytes = props.numHashBytes; -+ } -+ p->matchFinderBase.numHashBytes = numHashBytes; -+ } -+ -+ p->matchFinderBase.cutValue = props.mc; -+ -+ p->writeEndMark = props.writeEndMark; -+ -+ #ifndef _7ZIP_ST -+ /* -+ if (newMultiThread != _multiThread) -+ { -+ ReleaseMatchFinder(); -+ _multiThread = newMultiThread; -+ } -+ */ -+ p->multiThread = (props.numThreads > 1); -+ #endif -+ -+ return SZ_OK; -+} -+ -+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; -+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; -+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; -+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; -+ -+#define IsCharState(s) ((s) < 7) -+ -+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) -+ -+#define kInfinityPrice (1 << 30) -+ -+static void RangeEnc_Construct(CRangeEnc *p) -+{ -+ p->outStream = 0; -+ p->bufBase = 0; -+} -+ -+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) -+ -+#define RC_BUF_SIZE (1 << 16) -+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) -+{ -+ if (p->bufBase == 0) -+ { -+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); -+ if (p->bufBase == 0) -+ return 0; -+ p->bufLim = p->bufBase + RC_BUF_SIZE; -+ } -+ return 1; -+} -+ -+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->bufBase); -+ p->bufBase = 0; -+} -+ -+static void RangeEnc_Init(CRangeEnc *p) -+{ -+ /* Stream.Init(); */ -+ p->low = 0; -+ p->range = 0xFFFFFFFF; -+ p->cacheSize = 1; -+ p->cache = 0; -+ -+ p->buf = p->bufBase; -+ -+ p->processed = 0; -+ p->res = SZ_OK; -+} -+ -+static void RangeEnc_FlushStream(CRangeEnc *p) -+{ -+ size_t num; -+ if (p->res != SZ_OK) -+ return; -+ num = p->buf - p->bufBase; -+ if (num != p->outStream->Write(p->outStream, p->bufBase, num)) -+ p->res = SZ_ERROR_WRITE; -+ p->processed += num; -+ p->buf = p->bufBase; -+} -+ -+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) -+{ -+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) -+ { -+ Byte temp = p->cache; -+ do -+ { -+ Byte *buf = p->buf; -+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); -+ p->buf = buf; -+ if (buf == p->bufLim) -+ RangeEnc_FlushStream(p); -+ temp = 0xFF; -+ } -+ while (--p->cacheSize != 0); -+ p->cache = (Byte)((UInt32)p->low >> 24); -+ } -+ p->cacheSize++; -+ p->low = (UInt32)p->low << 8; -+} -+ -+static void RangeEnc_FlushData(CRangeEnc *p) -+{ -+ int i; -+ for (i = 0; i < 5; i++) -+ RangeEnc_ShiftLow(p); -+} -+ -+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) -+{ -+ do -+ { -+ p->range >>= 1; -+ p->low += p->range & (0 - ((value >> --numBits) & 1)); -+ if (p->range < kTopValue) -+ { -+ p->range <<= 8; -+ RangeEnc_ShiftLow(p); -+ } -+ } -+ while (numBits != 0); -+} -+ -+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) -+{ -+ UInt32 ttt = *prob; -+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; -+ if (symbol == 0) -+ { -+ p->range = newBound; -+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits; -+ } -+ else -+ { -+ p->low += newBound; -+ p->range -= newBound; -+ ttt -= ttt >> kNumMoveBits; -+ } -+ *prob = (CLzmaProb)ttt; -+ if (p->range < kTopValue) -+ { -+ p->range <<= 8; -+ RangeEnc_ShiftLow(p); -+ } -+} -+ -+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) -+{ -+ symbol |= 0x100; -+ do -+ { -+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); -+ symbol <<= 1; -+ } -+ while (symbol < 0x10000); -+} -+ -+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) -+{ -+ UInt32 offs = 0x100; -+ symbol |= 0x100; -+ do -+ { -+ matchByte <<= 1; -+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); -+ symbol <<= 1; -+ offs &= ~(matchByte ^ symbol); -+ } -+ while (symbol < 0x10000); -+} -+ -+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -+{ -+ UInt32 i; -+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) -+ { -+ const int kCyclesBits = kNumBitPriceShiftBits; -+ UInt32 w = i; -+ UInt32 bitCount = 0; -+ int j; -+ for (j = 0; j < kCyclesBits; j++) -+ { -+ w = w * w; -+ bitCount <<= 1; -+ while (w >= ((UInt32)1 << 16)) -+ { -+ w >>= 1; -+ bitCount++; -+ } -+ } -+ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); -+ } -+} -+ -+ -+#define GET_PRICE(prob, symbol) \ -+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -+ -+#define GET_PRICEa(prob, symbol) \ -+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -+ -+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] -+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -+ -+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] -+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -+ -+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ symbol |= 0x100; -+ do -+ { -+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); -+ symbol <<= 1; -+ } -+ while (symbol < 0x10000); -+ return price; -+} -+ -+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ UInt32 offs = 0x100; -+ symbol |= 0x100; -+ do -+ { -+ matchByte <<= 1; -+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); -+ symbol <<= 1; -+ offs &= ~(matchByte ^ symbol); -+ } -+ while (symbol < 0x10000); -+ return price; -+} -+ -+ -+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -+{ -+ UInt32 m = 1; -+ int i; -+ for (i = numBitLevels; i != 0;) -+ { -+ UInt32 bit; -+ i--; -+ bit = (symbol >> i) & 1; -+ RangeEnc_EncodeBit(rc, probs + m, bit); -+ m = (m << 1) | bit; -+ } -+} -+ -+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -+{ -+ UInt32 m = 1; -+ int i; -+ for (i = 0; i < numBitLevels; i++) -+ { -+ UInt32 bit = symbol & 1; -+ RangeEnc_EncodeBit(rc, probs + m, bit); -+ m = (m << 1) | bit; -+ symbol >>= 1; -+ } -+} -+ -+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ symbol |= (1 << numBitLevels); -+ while (symbol != 1) -+ { -+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1); -+ symbol >>= 1; -+ } -+ return price; -+} -+ -+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ UInt32 m = 1; -+ int i; -+ for (i = numBitLevels; i != 0; i--) -+ { -+ UInt32 bit = symbol & 1; -+ symbol >>= 1; -+ price += GET_PRICEa(probs[m], bit); -+ m = (m << 1) | bit; -+ } -+ return price; -+} -+ -+ -+static void LenEnc_Init(CLenEnc *p) -+{ -+ unsigned i; -+ p->choice = p->choice2 = kProbInitValue; -+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) -+ p->low[i] = kProbInitValue; -+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) -+ p->mid[i] = kProbInitValue; -+ for (i = 0; i < kLenNumHighSymbols; i++) -+ p->high[i] = kProbInitValue; -+} -+ -+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) -+{ -+ if (symbol < kLenNumLowSymbols) -+ { -+ RangeEnc_EncodeBit(rc, &p->choice, 0); -+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); -+ } -+ else -+ { -+ RangeEnc_EncodeBit(rc, &p->choice, 1); -+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) -+ { -+ RangeEnc_EncodeBit(rc, &p->choice2, 0); -+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); -+ } -+ else -+ { -+ RangeEnc_EncodeBit(rc, &p->choice2, 1); -+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); -+ } -+ } -+} -+ -+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) -+{ -+ UInt32 a0 = GET_PRICE_0a(p->choice); -+ UInt32 a1 = GET_PRICE_1a(p->choice); -+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); -+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); -+ UInt32 i = 0; -+ for (i = 0; i < kLenNumLowSymbols; i++) -+ { -+ if (i >= numSymbols) -+ return; -+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); -+ } -+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) -+ { -+ if (i >= numSymbols) -+ return; -+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); -+ } -+ for (; i < numSymbols; i++) -+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); -+} -+ -+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) -+{ -+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); -+ p->counters[posState] = p->tableSize; -+} -+ -+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) -+{ -+ UInt32 posState; -+ for (posState = 0; posState < numPosStates; posState++) -+ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -+} -+ -+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) -+{ -+ LenEnc_Encode(&p->p, rc, symbol, posState); -+ if (updatePrice) -+ if (--p->counters[posState] == 0) -+ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -+} -+ -+ -+ -+ -+static void MovePos(CLzmaEnc *p, UInt32 num) -+{ -+ #ifdef SHOW_STAT -+ ttt += num; -+ printf("\n MovePos %d", num); -+ #endif -+ if (num != 0) -+ { -+ p->additionalOffset += num; -+ p->matchFinder.Skip(p->matchFinderObj, num); -+ } -+} -+ -+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) -+{ -+ UInt32 lenRes = 0, numPairs; -+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); -+ #ifdef SHOW_STAT -+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); -+ ttt++; -+ { -+ UInt32 i; -+ for (i = 0; i < numPairs; i += 2) -+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); -+ } -+ #endif -+ if (numPairs > 0) -+ { -+ lenRes = p->matches[numPairs - 2]; -+ if (lenRes == p->numFastBytes) -+ { -+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ UInt32 distance = p->matches[numPairs - 1] + 1; -+ UInt32 numAvail = p->numAvail; -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ { -+ const Byte *pby2 = pby - distance; -+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); -+ } -+ } -+ } -+ p->additionalOffset++; -+ *numDistancePairsRes = numPairs; -+ return lenRes; -+} -+ -+ -+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; -+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; -+#define IsShortRep(p) ((p)->backPrev == 0) -+ -+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) -+{ -+ return -+ GET_PRICE_0(p->isRepG0[state]) + -+ GET_PRICE_0(p->isRep0Long[state][posState]); -+} -+ -+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) -+{ -+ UInt32 price; -+ if (repIndex == 0) -+ { -+ price = GET_PRICE_0(p->isRepG0[state]); -+ price += GET_PRICE_1(p->isRep0Long[state][posState]); -+ } -+ else -+ { -+ price = GET_PRICE_1(p->isRepG0[state]); -+ if (repIndex == 1) -+ price += GET_PRICE_0(p->isRepG1[state]); -+ else -+ { -+ price += GET_PRICE_1(p->isRepG1[state]); -+ price += GET_PRICE(p->isRepG2[state], repIndex - 2); -+ } -+ } -+ return price; -+} -+ -+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) -+{ -+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + -+ GetPureRepPrice(p, repIndex, state, posState); -+} -+ -+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) -+{ -+ UInt32 posMem = p->opt[cur].posPrev; -+ UInt32 backMem = p->opt[cur].backPrev; -+ p->optimumEndIndex = cur; -+ do -+ { -+ if (p->opt[cur].prev1IsChar) -+ { -+ MakeAsChar(&p->opt[posMem]) -+ p->opt[posMem].posPrev = posMem - 1; -+ if (p->opt[cur].prev2) -+ { -+ p->opt[posMem - 1].prev1IsChar = False; -+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; -+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; -+ } -+ } -+ { -+ UInt32 posPrev = posMem; -+ UInt32 backCur = backMem; -+ -+ backMem = p->opt[posPrev].backPrev; -+ posMem = p->opt[posPrev].posPrev; -+ -+ p->opt[posPrev].backPrev = backCur; -+ p->opt[posPrev].posPrev = cur; -+ cur = posPrev; -+ } -+ } -+ while (cur != 0); -+ *backRes = p->opt[0].backPrev; -+ p->optimumCurrentIndex = p->opt[0].posPrev; -+ return p->optimumCurrentIndex; -+} -+ -+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) -+ -+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) -+{ -+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; -+ UInt32 matchPrice, repMatchPrice, normalMatchPrice; -+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; -+ UInt32 *matches; -+ const Byte *data; -+ Byte curByte, matchByte; -+ if (p->optimumEndIndex != p->optimumCurrentIndex) -+ { -+ const COptimal *opt = &p->opt[p->optimumCurrentIndex]; -+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; -+ *backRes = opt->backPrev; -+ p->optimumCurrentIndex = opt->posPrev; -+ return lenRes; -+ } -+ p->optimumCurrentIndex = p->optimumEndIndex = 0; -+ -+ if (p->additionalOffset == 0) -+ mainLen = ReadMatchDistances(p, &numPairs); -+ else -+ { -+ mainLen = p->longestMatchLength; -+ numPairs = p->numPairs; -+ } -+ -+ numAvail = p->numAvail; -+ if (numAvail < 2) -+ { -+ *backRes = (UInt32)(-1); -+ return 1; -+ } -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ repMaxIndex = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 lenTest; -+ const Byte *data2; -+ reps[i] = p->reps[i]; -+ data2 = data - (reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ { -+ repLens[i] = 0; -+ continue; -+ } -+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -+ repLens[i] = lenTest; -+ if (lenTest > repLens[repMaxIndex]) -+ repMaxIndex = i; -+ } -+ if (repLens[repMaxIndex] >= p->numFastBytes) -+ { -+ UInt32 lenRes; -+ *backRes = repMaxIndex; -+ lenRes = repLens[repMaxIndex]; -+ MovePos(p, lenRes - 1); -+ return lenRes; -+ } -+ -+ matches = p->matches; -+ if (mainLen >= p->numFastBytes) -+ { -+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 1); -+ return mainLen; -+ } -+ curByte = *data; -+ matchByte = *(data - (reps[0] + 1)); -+ -+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) -+ { -+ *backRes = (UInt32)-1; -+ return 1; -+ } -+ -+ p->opt[0].state = (CState)p->state; -+ -+ posState = (position & p->pbMask); -+ -+ { -+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + -+ (!IsCharState(p->state) ? -+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -+ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -+ } -+ -+ MakeAsChar(&p->opt[1]); -+ -+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); -+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); -+ -+ if (matchByte == curByte) -+ { -+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); -+ if (shortRepPrice < p->opt[1].price) -+ { -+ p->opt[1].price = shortRepPrice; -+ MakeAsShortRep(&p->opt[1]); -+ } -+ } -+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); -+ -+ if (lenEnd < 2) -+ { -+ *backRes = p->opt[1].backPrev; -+ return 1; -+ } -+ -+ p->opt[1].posPrev = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ p->opt[0].backs[i] = reps[i]; -+ -+ len = lenEnd; -+ do -+ p->opt[len--].price = kInfinityPrice; -+ while (len >= 2); -+ -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 repLen = repLens[i]; -+ UInt32 price; -+ if (repLen < 2) -+ continue; -+ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); -+ do -+ { -+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; -+ COptimal *opt = &p->opt[repLen]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = 0; -+ opt->backPrev = i; -+ opt->prev1IsChar = False; -+ } -+ } -+ while (--repLen >= 2); -+ } -+ -+ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); -+ -+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); -+ if (len <= mainLen) -+ { -+ UInt32 offs = 0; -+ while (len > matches[offs]) -+ offs += 2; -+ for (; ; len++) -+ { -+ COptimal *opt; -+ UInt32 distance = matches[offs + 1]; -+ -+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; -+ UInt32 lenToPosState = GetLenToPosState(len); -+ if (distance < kNumFullDistances) -+ curAndLenPrice += p->distancesPrices[lenToPosState][distance]; -+ else -+ { -+ UInt32 slot; -+ GetPosSlot2(distance, slot); -+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; -+ } -+ opt = &p->opt[len]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = 0; -+ opt->backPrev = distance + LZMA_NUM_REPS; -+ opt->prev1IsChar = False; -+ } -+ if (len == matches[offs]) -+ { -+ offs += 2; -+ if (offs == numPairs) -+ break; -+ } -+ } -+ } -+ -+ cur = 0; -+ -+ #ifdef SHOW_STAT2 -+ if (position >= 0) -+ { -+ unsigned i; -+ printf("\n pos = %4X", position); -+ for (i = cur; i <= lenEnd; i++) -+ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); -+ } -+ #endif -+ -+ for (;;) -+ { -+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; -+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; -+ Bool nextIsChar; -+ Byte curByte, matchByte; -+ const Byte *data; -+ COptimal *curOpt; -+ COptimal *nextOpt; -+ -+ cur++; -+ if (cur == lenEnd) -+ return Backward(p, backRes, cur); -+ -+ newLen = ReadMatchDistances(p, &numPairs); -+ if (newLen >= p->numFastBytes) -+ { -+ p->numPairs = numPairs; -+ p->longestMatchLength = newLen; -+ return Backward(p, backRes, cur); -+ } -+ position++; -+ curOpt = &p->opt[cur]; -+ posPrev = curOpt->posPrev; -+ if (curOpt->prev1IsChar) -+ { -+ posPrev--; -+ if (curOpt->prev2) -+ { -+ state = p->opt[curOpt->posPrev2].state; -+ if (curOpt->backPrev2 < LZMA_NUM_REPS) -+ state = kRepNextStates[state]; -+ else -+ state = kMatchNextStates[state]; -+ } -+ else -+ state = p->opt[posPrev].state; -+ state = kLiteralNextStates[state]; -+ } -+ else -+ state = p->opt[posPrev].state; -+ if (posPrev == cur - 1) -+ { -+ if (IsShortRep(curOpt)) -+ state = kShortRepNextStates[state]; -+ else -+ state = kLiteralNextStates[state]; -+ } -+ else -+ { -+ UInt32 pos; -+ const COptimal *prevOpt; -+ if (curOpt->prev1IsChar && curOpt->prev2) -+ { -+ posPrev = curOpt->posPrev2; -+ pos = curOpt->backPrev2; -+ state = kRepNextStates[state]; -+ } -+ else -+ { -+ pos = curOpt->backPrev; -+ if (pos < LZMA_NUM_REPS) -+ state = kRepNextStates[state]; -+ else -+ state = kMatchNextStates[state]; -+ } -+ prevOpt = &p->opt[posPrev]; -+ if (pos < LZMA_NUM_REPS) -+ { -+ UInt32 i; -+ reps[0] = prevOpt->backs[pos]; -+ for (i = 1; i <= pos; i++) -+ reps[i] = prevOpt->backs[i - 1]; -+ for (; i < LZMA_NUM_REPS; i++) -+ reps[i] = prevOpt->backs[i]; -+ } -+ else -+ { -+ UInt32 i; -+ reps[0] = (pos - LZMA_NUM_REPS); -+ for (i = 1; i < LZMA_NUM_REPS; i++) -+ reps[i] = prevOpt->backs[i - 1]; -+ } -+ } -+ curOpt->state = (CState)state; -+ -+ curOpt->backs[0] = reps[0]; -+ curOpt->backs[1] = reps[1]; -+ curOpt->backs[2] = reps[2]; -+ curOpt->backs[3] = reps[3]; -+ -+ curPrice = curOpt->price; -+ nextIsChar = False; -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ curByte = *data; -+ matchByte = *(data - (reps[0] + 1)); -+ -+ posState = (position & p->pbMask); -+ -+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); -+ { -+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -+ curAnd1Price += -+ (!IsCharState(state) ? -+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -+ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -+ } -+ -+ nextOpt = &p->opt[cur + 1]; -+ -+ if (curAnd1Price < nextOpt->price) -+ { -+ nextOpt->price = curAnd1Price; -+ nextOpt->posPrev = cur; -+ MakeAsChar(nextOpt); -+ nextIsChar = True; -+ } -+ -+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); -+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); -+ -+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) -+ { -+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); -+ if (shortRepPrice <= nextOpt->price) -+ { -+ nextOpt->price = shortRepPrice; -+ nextOpt->posPrev = cur; -+ MakeAsShortRep(nextOpt); -+ nextIsChar = True; -+ } -+ } -+ numAvailFull = p->numAvail; -+ { -+ UInt32 temp = kNumOpts - 1 - cur; -+ if (temp < numAvailFull) -+ numAvailFull = temp; -+ } -+ -+ if (numAvailFull < 2) -+ continue; -+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); -+ -+ if (!nextIsChar && matchByte != curByte) /* speed optimization */ -+ { -+ /* try Literal + rep0 */ -+ UInt32 temp; -+ UInt32 lenTest2; -+ const Byte *data2 = data - (reps[0] + 1); -+ UInt32 limit = p->numFastBytes + 1; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ -+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); -+ lenTest2 = temp - 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kLiteralNextStates[state]; -+ UInt32 posStateNext = (position + 1) & p->pbMask; -+ UInt32 nextRepMatchPrice = curAnd1Price + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ UInt32 offset = cur + 1 + lenTest2; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = False; -+ } -+ } -+ } -+ } -+ -+ startLen = 2; /* speed optimization */ -+ { -+ UInt32 repIndex; -+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) -+ { -+ UInt32 lenTest; -+ UInt32 lenTestTemp; -+ UInt32 price; -+ const Byte *data2 = data - (reps[repIndex] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -+ while (lenEnd < cur + lenTest) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ lenTestTemp = lenTest; -+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); -+ do -+ { -+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; -+ COptimal *opt = &p->opt[cur + lenTest]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur; -+ opt->backPrev = repIndex; -+ opt->prev1IsChar = False; -+ } -+ } -+ while (--lenTest >= 2); -+ lenTest = lenTestTemp; -+ -+ if (repIndex == 0) -+ startLen = lenTest + 1; -+ -+ /* if (_maxMode) */ -+ { -+ UInt32 lenTest2 = lenTest + 1; -+ UInt32 limit = lenTest2 + p->numFastBytes; -+ UInt32 nextRepMatchPrice; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -+ lenTest2 -= lenTest + 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kRepNextStates[state]; -+ UInt32 posStateNext = (position + lenTest) & p->pbMask; -+ UInt32 curAndLenCharPrice = -+ price + p->repLenEnc.prices[posState][lenTest - 2] + -+ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -+ data[lenTest], data2[lenTest], p->ProbPrices); -+ state2 = kLiteralNextStates[state2]; -+ posStateNext = (position + lenTest + 1) & p->pbMask; -+ nextRepMatchPrice = curAndLenCharPrice + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ UInt32 offset = cur + lenTest + 1 + lenTest2; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + lenTest + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = True; -+ opt->posPrev2 = cur; -+ opt->backPrev2 = repIndex; -+ } -+ } -+ } -+ } -+ } -+ } -+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ -+ if (newLen > numAvail) -+ { -+ newLen = numAvail; -+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); -+ matches[numPairs] = newLen; -+ numPairs += 2; -+ } -+ if (newLen >= startLen) -+ { -+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); -+ UInt32 offs, curBack, posSlot; -+ UInt32 lenTest; -+ while (lenEnd < cur + newLen) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ -+ offs = 0; -+ while (startLen > matches[offs]) -+ offs += 2; -+ curBack = matches[offs + 1]; -+ GetPosSlot2(curBack, posSlot); -+ for (lenTest = /*2*/ startLen; ; lenTest++) -+ { -+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; -+ UInt32 lenToPosState = GetLenToPosState(lenTest); -+ COptimal *opt; -+ if (curBack < kNumFullDistances) -+ curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; -+ else -+ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; -+ -+ opt = &p->opt[cur + lenTest]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur; -+ opt->backPrev = curBack + LZMA_NUM_REPS; -+ opt->prev1IsChar = False; -+ } -+ -+ if (/*_maxMode && */lenTest == matches[offs]) -+ { -+ /* Try Match + Literal + Rep0 */ -+ const Byte *data2 = data - (curBack + 1); -+ UInt32 lenTest2 = lenTest + 1; -+ UInt32 limit = lenTest2 + p->numFastBytes; -+ UInt32 nextRepMatchPrice; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -+ lenTest2 -= lenTest + 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kMatchNextStates[state]; -+ UInt32 posStateNext = (position + lenTest) & p->pbMask; -+ UInt32 curAndLenCharPrice = curAndLenPrice + -+ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -+ data[lenTest], data2[lenTest], p->ProbPrices); -+ state2 = kLiteralNextStates[state2]; -+ posStateNext = (posStateNext + 1) & p->pbMask; -+ nextRepMatchPrice = curAndLenCharPrice + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 offset = cur + lenTest + 1 + lenTest2; -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + lenTest + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = True; -+ opt->posPrev2 = cur; -+ opt->backPrev2 = curBack + LZMA_NUM_REPS; -+ } -+ } -+ } -+ offs += 2; -+ if (offs == numPairs) -+ break; -+ curBack = matches[offs + 1]; -+ if (curBack >= kNumFullDistances) -+ GetPosSlot2(curBack, posSlot); -+ } -+ } -+ } -+ } -+} -+ -+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) -+ -+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) -+{ -+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; -+ const Byte *data; -+ const UInt32 *matches; -+ -+ if (p->additionalOffset == 0) -+ mainLen = ReadMatchDistances(p, &numPairs); -+ else -+ { -+ mainLen = p->longestMatchLength; -+ numPairs = p->numPairs; -+ } -+ -+ numAvail = p->numAvail; -+ *backRes = (UInt32)-1; -+ if (numAvail < 2) -+ return 1; -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ -+ repLen = repIndex = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 len; -+ const Byte *data2 = data - (p->reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ for (len = 2; len < numAvail && data[len] == data2[len]; len++); -+ if (len >= p->numFastBytes) -+ { -+ *backRes = i; -+ MovePos(p, len - 1); -+ return len; -+ } -+ if (len > repLen) -+ { -+ repIndex = i; -+ repLen = len; -+ } -+ } -+ -+ matches = p->matches; -+ if (mainLen >= p->numFastBytes) -+ { -+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 1); -+ return mainLen; -+ } -+ -+ mainDist = 0; /* for GCC */ -+ if (mainLen >= 2) -+ { -+ mainDist = matches[numPairs - 1]; -+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) -+ { -+ if (!ChangePair(matches[numPairs - 3], mainDist)) -+ break; -+ numPairs -= 2; -+ mainLen = matches[numPairs - 2]; -+ mainDist = matches[numPairs - 1]; -+ } -+ if (mainLen == 2 && mainDist >= 0x80) -+ mainLen = 1; -+ } -+ -+ if (repLen >= 2 && ( -+ (repLen + 1 >= mainLen) || -+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || -+ (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) -+ { -+ *backRes = repIndex; -+ MovePos(p, repLen - 1); -+ return repLen; -+ } -+ -+ if (mainLen < 2 || numAvail <= 2) -+ return 1; -+ -+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); -+ if (p->longestMatchLength >= 2) -+ { -+ UInt32 newDistance = matches[p->numPairs - 1]; -+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || -+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || -+ (p->longestMatchLength > mainLen + 1) || -+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) -+ return 1; -+ } -+ -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 len, limit; -+ const Byte *data2 = data - (p->reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ limit = mainLen - 1; -+ for (len = 2; len < limit && data[len] == data2[len]; len++); -+ if (len >= limit) -+ return 1; -+ } -+ *backRes = mainDist + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 2); -+ return mainLen; -+} -+ -+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) -+{ -+ UInt32 len; -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -+ p->state = kMatchNextStates[p->state]; -+ len = LZMA_MATCH_LEN_MIN; -+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); -+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); -+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); -+} -+ -+static SRes CheckErrors(CLzmaEnc *p) -+{ -+ if (p->result != SZ_OK) -+ return p->result; -+ if (p->rc.res != SZ_OK) -+ p->result = SZ_ERROR_WRITE; -+ if (p->matchFinderBase.result != SZ_OK) -+ p->result = SZ_ERROR_READ; -+ if (p->result != SZ_OK) -+ p->finished = True; -+ return p->result; -+} -+ -+static SRes Flush(CLzmaEnc *p, UInt32 nowPos) -+{ -+ /* ReleaseMFStream(); */ -+ p->finished = True; -+ if (p->writeEndMark) -+ WriteEndMarker(p, nowPos & p->pbMask); -+ RangeEnc_FlushData(&p->rc); -+ RangeEnc_FlushStream(&p->rc); -+ return CheckErrors(p); -+} -+ -+static void FillAlignPrices(CLzmaEnc *p) -+{ -+ UInt32 i; -+ for (i = 0; i < kAlignTableSize; i++) -+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); -+ p->alignPriceCount = 0; -+} -+ -+static void FillDistancesPrices(CLzmaEnc *p) -+{ -+ UInt32 tempPrices[kNumFullDistances]; -+ UInt32 i, lenToPosState; -+ for (i = kStartPosModelIndex; i < kNumFullDistances; i++) -+ { -+ UInt32 posSlot = GetPosSlot1(i); -+ UInt32 footerBits = ((posSlot >> 1) - 1); -+ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -+ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); -+ } -+ -+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) -+ { -+ UInt32 posSlot; -+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; -+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; -+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++) -+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); -+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) -+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); -+ -+ { -+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; -+ UInt32 i; -+ for (i = 0; i < kStartPosModelIndex; i++) -+ distancesPrices[i] = posSlotPrices[i]; -+ for (; i < kNumFullDistances; i++) -+ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; -+ } -+ } -+ p->matchPriceCount = 0; -+} -+ -+static void LzmaEnc_Construct(CLzmaEnc *p) -+{ -+ RangeEnc_Construct(&p->rc); -+ MatchFinder_Construct(&p->matchFinderBase); -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Construct(&p->matchFinderMt); -+ p->matchFinderMt.MatchFinder = &p->matchFinderBase; -+ #endif -+ -+ { -+ CLzmaEncProps props; -+ LzmaEncProps_Init(&props); -+ LzmaEnc_SetProps(p, &props); -+ } -+ -+ #ifndef LZMA_LOG_BSR -+ LzmaEnc_FastPosInit(p->g_FastPos); -+ #endif -+ -+ LzmaEnc_InitPriceTables(p->ProbPrices); -+ p->litProbs = 0; -+ p->saveState.litProbs = 0; -+} -+ -+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) -+{ -+ void *p; -+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); -+ if (p != 0) -+ LzmaEnc_Construct((CLzmaEnc *)p); -+ return p; -+} -+ -+static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->litProbs); -+ alloc->Free(alloc, p->saveState.litProbs); -+ p->litProbs = 0; -+ p->saveState.litProbs = 0; -+} -+ -+static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); -+ #endif -+ MatchFinder_Free(&p->matchFinderBase, allocBig); -+ LzmaEnc_FreeLits(p, alloc); -+ RangeEnc_Free(&p->rc, alloc); -+} -+ -+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); -+ alloc->Free(alloc, p); -+} -+ -+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) -+{ -+ UInt32 nowPos32, startPos32; -+ if (p->needInit) -+ { -+ p->matchFinder.Init(p->matchFinderObj); -+ p->needInit = 0; -+ } -+ -+ if (p->finished) -+ return p->result; -+ RINOK(CheckErrors(p)); -+ -+ nowPos32 = (UInt32)p->nowPos64; -+ startPos32 = nowPos32; -+ -+ if (p->nowPos64 == 0) -+ { -+ UInt32 numPairs; -+ Byte curByte; -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -+ return Flush(p, nowPos32); -+ ReadMatchDistances(p, &numPairs); -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); -+ p->state = kLiteralNextStates[p->state]; -+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); -+ LitEnc_Encode(&p->rc, p->litProbs, curByte); -+ p->additionalOffset--; -+ nowPos32++; -+ } -+ -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) -+ for (;;) -+ { -+ UInt32 pos, len, posState; -+ -+ if (p->fastMode) -+ len = GetOptimumFast(p, &pos); -+ else -+ len = GetOptimum(p, nowPos32, &pos); -+ -+ #ifdef SHOW_STAT2 -+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); -+ #endif -+ -+ posState = nowPos32 & p->pbMask; -+ if (len == 1 && pos == (UInt32)-1) -+ { -+ Byte curByte; -+ CLzmaProb *probs; -+ const Byte *data; -+ -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -+ curByte = *data; -+ probs = LIT_PROBS(nowPos32, *(data - 1)); -+ if (IsCharState(p->state)) -+ LitEnc_Encode(&p->rc, probs, curByte); -+ else -+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); -+ p->state = kLiteralNextStates[p->state]; -+ } -+ else -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -+ if (pos < LZMA_NUM_REPS) -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); -+ if (pos == 0) -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); -+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); -+ } -+ else -+ { -+ UInt32 distance = p->reps[pos]; -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); -+ if (pos == 1) -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); -+ else -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); -+ if (pos == 3) -+ p->reps[3] = p->reps[2]; -+ p->reps[2] = p->reps[1]; -+ } -+ p->reps[1] = p->reps[0]; -+ p->reps[0] = distance; -+ } -+ if (len == 1) -+ p->state = kShortRepNextStates[p->state]; -+ else -+ { -+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ p->state = kRepNextStates[p->state]; -+ } -+ } -+ else -+ { -+ UInt32 posSlot; -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -+ p->state = kMatchNextStates[p->state]; -+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ pos -= LZMA_NUM_REPS; -+ GetPosSlot(pos, posSlot); -+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); -+ -+ if (posSlot >= kStartPosModelIndex) -+ { -+ UInt32 footerBits = ((posSlot >> 1) - 1); -+ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -+ UInt32 posReduced = pos - base; -+ -+ if (posSlot < kEndPosModelIndex) -+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); -+ else -+ { -+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); -+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); -+ p->alignPriceCount++; -+ } -+ } -+ p->reps[3] = p->reps[2]; -+ p->reps[2] = p->reps[1]; -+ p->reps[1] = p->reps[0]; -+ p->reps[0] = pos; -+ p->matchPriceCount++; -+ } -+ } -+ p->additionalOffset -= len; -+ nowPos32 += len; -+ if (p->additionalOffset == 0) -+ { -+ UInt32 processed; -+ if (!p->fastMode) -+ { -+ if (p->matchPriceCount >= (1 << 7)) -+ FillDistancesPrices(p); -+ if (p->alignPriceCount >= kAlignTableSize) -+ FillAlignPrices(p); -+ } -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -+ break; -+ processed = nowPos32 - startPos32; -+ if (useLimits) -+ { -+ if (processed + kNumOpts + 300 >= maxUnpackSize || -+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) -+ break; -+ } -+ else if (processed >= (1 << 15)) -+ { -+ p->nowPos64 += nowPos32 - startPos32; -+ return CheckErrors(p); -+ } -+ } -+ } -+ p->nowPos64 += nowPos32 - startPos32; -+ return Flush(p, nowPos32); -+} -+ -+#define kBigHashDicLimit ((UInt32)1 << 24) -+ -+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ UInt32 beforeSize = kNumOpts; -+ Bool btMode; -+ if (!RangeEnc_Alloc(&p->rc, alloc)) -+ return SZ_ERROR_MEM; -+ btMode = (p->matchFinderBase.btMode != 0); -+ #ifndef _7ZIP_ST -+ p->mtMode = (p->multiThread && !p->fastMode && btMode); -+ #endif -+ -+ { -+ unsigned lclp = p->lc + p->lp; -+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) -+ { -+ LzmaEnc_FreeLits(p, alloc); -+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -+ if (p->litProbs == 0 || p->saveState.litProbs == 0) -+ { -+ LzmaEnc_FreeLits(p, alloc); -+ return SZ_ERROR_MEM; -+ } -+ p->lclp = lclp; -+ } -+ } -+ -+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); -+ -+ if (beforeSize + p->dictSize < keepWindowSize) -+ beforeSize = keepWindowSize - p->dictSize; -+ -+ #ifndef _7ZIP_ST -+ if (p->mtMode) -+ { -+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); -+ p->matchFinderObj = &p->matchFinderMt; -+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); -+ } -+ else -+ #endif -+ { -+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) -+ return SZ_ERROR_MEM; -+ p->matchFinderObj = &p->matchFinderBase; -+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); -+ } -+ return SZ_OK; -+} -+ -+static void LzmaEnc_Init(CLzmaEnc *p) -+{ -+ UInt32 i; -+ p->state = 0; -+ for (i = 0 ; i < LZMA_NUM_REPS; i++) -+ p->reps[i] = 0; -+ -+ RangeEnc_Init(&p->rc); -+ -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ UInt32 j; -+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) -+ { -+ p->isMatch[i][j] = kProbInitValue; -+ p->isRep0Long[i][j] = kProbInitValue; -+ } -+ p->isRep[i] = kProbInitValue; -+ p->isRepG0[i] = kProbInitValue; -+ p->isRepG1[i] = kProbInitValue; -+ p->isRepG2[i] = kProbInitValue; -+ } -+ -+ { -+ UInt32 num = 0x300 << (p->lp + p->lc); -+ for (i = 0; i < num; i++) -+ p->litProbs[i] = kProbInitValue; -+ } -+ -+ { -+ for (i = 0; i < kNumLenToPosStates; i++) -+ { -+ CLzmaProb *probs = p->posSlotEncoder[i]; -+ UInt32 j; -+ for (j = 0; j < (1 << kNumPosSlotBits); j++) -+ probs[j] = kProbInitValue; -+ } -+ } -+ { -+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) -+ p->posEncoders[i] = kProbInitValue; -+ } -+ -+ LenEnc_Init(&p->lenEnc.p); -+ LenEnc_Init(&p->repLenEnc.p); -+ -+ for (i = 0; i < (1 << kNumAlignBits); i++) -+ p->posAlignEncoder[i] = kProbInitValue; -+ -+ p->optimumEndIndex = 0; -+ p->optimumCurrentIndex = 0; -+ p->additionalOffset = 0; -+ -+ p->pbMask = (1 << p->pb) - 1; -+ p->lpMask = (1 << p->lp) - 1; -+} -+ -+static void LzmaEnc_InitPrices(CLzmaEnc *p) -+{ -+ if (!p->fastMode) -+ { -+ FillDistancesPrices(p); -+ FillAlignPrices(p); -+ } -+ -+ p->lenEnc.tableSize = -+ p->repLenEnc.tableSize = -+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; -+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); -+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); -+} -+ -+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ UInt32 i; -+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) -+ if (p->dictSize <= ((UInt32)1 << i)) -+ break; -+ p->distTableSize = i * 2; -+ -+ p->finished = False; -+ p->result = SZ_OK; -+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); -+ LzmaEnc_Init(p); -+ LzmaEnc_InitPrices(p); -+ p->nowPos64 = 0; -+ return SZ_OK; -+} -+ -+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -+{ -+ p->matchFinderBase.directInput = 1; -+ p->matchFinderBase.bufferBase = (Byte *)src; -+ p->matchFinderBase.directInputRem = srcLen; -+} -+ -+static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, -+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ LzmaEnc_SetInputBuf(p, src, srcLen); -+ p->needInit = 1; -+ -+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+} -+ -+static void LzmaEnc_Finish(CLzmaEncHandle pp) -+{ -+ #ifndef _7ZIP_ST -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ if (p->mtMode) -+ MatchFinderMt_ReleaseStream(&p->matchFinderMt); -+ #else -+ pp = pp; -+ #endif -+} -+ -+typedef struct -+{ -+ ISeqOutStream funcTable; -+ Byte *data; -+ SizeT rem; -+ Bool overflow; -+} CSeqOutStreamBuf; -+ -+static size_t MyWrite(void *pp, const void *data, size_t size) -+{ -+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; -+ if (p->rem < size) -+ { -+ size = p->rem; -+ p->overflow = True; -+ } -+ memcpy(p->data, data, size); -+ p->rem -= size; -+ p->data += size; -+ return size; -+} -+ -+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) -+{ -+ SRes res = SZ_OK; -+ -+ #ifndef _7ZIP_ST -+ Byte allocaDummy[0x300]; -+ int i = 0; -+ for (i = 0; i < 16; i++) -+ allocaDummy[i] = (Byte)i; -+ #endif -+ -+ for (;;) -+ { -+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0); -+ if (res != SZ_OK || p->finished != 0) -+ break; -+ if (progress != 0) -+ { -+ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); -+ if (res != SZ_OK) -+ { -+ res = SZ_ERROR_PROGRESS; -+ break; -+ } -+ } -+ } -+ LzmaEnc_Finish(p); -+ return res; -+} -+ -+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ int i; -+ UInt32 dictSize = p->dictSize; -+ if (*size < LZMA_PROPS_SIZE) -+ return SZ_ERROR_PARAM; -+ *size = LZMA_PROPS_SIZE; -+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); -+ -+ for (i = 11; i <= 30; i++) -+ { -+ if (dictSize <= ((UInt32)2 << i)) -+ { -+ dictSize = (2 << i); -+ break; -+ } -+ if (dictSize <= ((UInt32)3 << i)) -+ { -+ dictSize = (3 << i); -+ break; -+ } -+ } -+ -+ for (i = 0; i < 4; i++) -+ props[1 + i] = (Byte)(dictSize >> (8 * i)); -+ return SZ_OK; -+} -+ -+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ SRes res; -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ -+ CSeqOutStreamBuf outStream; -+ -+ LzmaEnc_SetInputBuf(p, src, srcLen); -+ -+ outStream.funcTable.Write = MyWrite; -+ outStream.data = dest; -+ outStream.rem = *destLen; -+ outStream.overflow = False; -+ -+ p->writeEndMark = writeEndMark; -+ -+ p->rc.outStream = &outStream.funcTable; -+ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); -+ if (res == SZ_OK) -+ res = LzmaEnc_Encode2(p, progress); -+ -+ *destLen -= outStream.rem; -+ if (outStream.overflow) -+ return SZ_ERROR_OUTPUT_EOF; -+ return res; -+} ---- /dev/null -+++ b/lib/lzma/Makefile -@@ -0,0 +1,7 @@ -+lzma_compress-objs := LzFind.o LzmaEnc.o -+lzma_decompress-objs := LzmaDec.o -+ -+obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o -+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o -+ -+EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h diff --git a/target/linux/generic/pending-5.15/532-jffs2_eofdetect.patch b/target/linux/generic/pending-5.15/532-jffs2_eofdetect.patch deleted file mode 100644 index 744fbd0e21790b..00000000000000 --- a/target/linux/generic/pending-5.15/532-jffs2_eofdetect.patch +++ /dev/null @@ -1,65 +0,0 @@ -From: Felix Fietkau -Subject: fs: jffs2: EOF marker - -Signed-off-by: Felix Fietkau ---- - fs/jffs2/build.c | 10 ++++++++++ - fs/jffs2/scan.c | 21 +++++++++++++++++++-- - 2 files changed, 29 insertions(+), 2 deletions(-) - ---- a/fs/jffs2/build.c -+++ b/fs/jffs2/build.c -@@ -117,6 +117,16 @@ static int jffs2_build_filesystem(struct - dbg_fsbuild("scanned flash completely\n"); - jffs2_dbg_dump_block_lists_nolock(c); - -+ if (c->flags & (1 << 7)) { -+ printk("%s(): unlocking the mtd device... ", __func__); -+ mtd_unlock(c->mtd, 0, c->mtd->size); -+ printk("done.\n"); -+ -+ printk("%s(): erasing all blocks after the end marker... ", __func__); -+ jffs2_erase_pending_blocks(c, -1); -+ printk("done.\n"); -+ } -+ - dbg_fsbuild("pass 1 starting\n"); - c->flags |= JFFS2_SB_FLAG_BUILDING; - /* Now scan the directory tree, increasing nlink according to every dirent found. */ ---- a/fs/jffs2/scan.c -+++ b/fs/jffs2/scan.c -@@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_in - /* reset summary info for next eraseblock scan */ - jffs2_sum_reset_collected(s); - -- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -- buf_size, s); -+ if (c->flags & (1 << 7)) { -+ if (mtd_block_isbad(c->mtd, jeb->offset)) -+ ret = BLK_STATE_BADBLOCK; -+ else -+ ret = BLK_STATE_ALLFF; -+ } else -+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -+ buf_size, s); - - if (ret < 0) - goto out; -@@ -567,6 +573,17 @@ full_scan: - return err; - } - -+ if ((buf[0] == 0xde) && -+ (buf[1] == 0xad) && -+ (buf[2] == 0xc0) && -+ (buf[3] == 0xde)) { -+ /* end of filesystem. erase everything after this point */ -+ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset); -+ c->flags |= (1 << 7); -+ -+ return BLK_STATE_ALLFF; -+ } -+ - /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ - ofs = 0; - max_ofs = EMPTY_SCAN_SIZE(c->sector_size); diff --git a/target/linux/generic/pending-5.15/600-netfilter_conntrack_flush.patch b/target/linux/generic/pending-5.15/600-netfilter_conntrack_flush.patch deleted file mode 100644 index a88e3d7d9a77eb..00000000000000 --- a/target/linux/generic/pending-5.15/600-netfilter_conntrack_flush.patch +++ /dev/null @@ -1,88 +0,0 @@ -From: Felix Fietkau -Subject: netfilter: add support for flushing conntrack via /proc - -lede-commit 8193bbe59a74d34d6a26d4a8cb857b1952905314 -Signed-off-by: Felix Fietkau ---- - net/netfilter/nf_conntrack_standalone.c | 59 ++++++++++++++++++++++++++++++++- - 1 file changed, 58 insertions(+), 1 deletion(-) - ---- a/net/netfilter/nf_conntrack_standalone.c -+++ b/net/netfilter/nf_conntrack_standalone.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #ifdef CONFIG_SYSCTL - #include -@@ -462,6 +463,56 @@ static int ct_cpu_seq_show(struct seq_fi - return 0; - } - -+struct kill_request { -+ u16 family; -+ union nf_inet_addr addr; -+}; -+ -+static int kill_matching(struct nf_conn *i, void *data) -+{ -+ struct kill_request *kr = data; -+ struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple; -+ struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple; -+ -+ if (!kr->family) -+ return 1; -+ -+ if (t1->src.l3num != kr->family) -+ return 0; -+ -+ return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t2->src.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t2->dst.u3)); -+} -+ -+static int ct_file_write(struct file *file, char *buf, size_t count) -+{ -+ struct seq_file *seq = file->private_data; -+ struct net *net = seq_file_net(seq); -+ struct kill_request kr = { }; -+ -+ if (count == 0) -+ return 0; -+ -+ if (count >= INET6_ADDRSTRLEN) -+ count = INET6_ADDRSTRLEN - 1; -+ -+ if (strnchr(buf, count, ':')) { -+ kr.family = AF_INET6; -+ if (!in6_pton(buf, count, (void *)&kr.addr, '\n', NULL)) -+ return -EINVAL; -+ } else if (strnchr(buf, count, '.')) { -+ kr.family = AF_INET; -+ if (!in4_pton(buf, count, (void *)&kr.addr, '\n', NULL)) -+ return -EINVAL; -+ } -+ -+ nf_ct_iterate_cleanup_net(net, kill_matching, &kr, 0, 0); -+ -+ return 0; -+} -+ - static const struct seq_operations ct_cpu_seq_ops = { - .start = ct_cpu_seq_start, - .next = ct_cpu_seq_next, -@@ -475,8 +526,9 @@ static int nf_conntrack_standalone_init_ - kuid_t root_uid; - kgid_t root_gid; - -- pde = proc_create_net("nf_conntrack", 0440, net->proc_net, &ct_seq_ops, -- sizeof(struct ct_iter_state)); -+ pde = proc_create_net_data_write("nf_conntrack", 0440, net->proc_net, -+ &ct_seq_ops, &ct_file_write, -+ sizeof(struct ct_iter_state), NULL); - if (!pde) - goto out_nf_conntrack; - diff --git a/target/linux/generic/pending-5.15/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-5.15/610-netfilter_match_bypass_default_checks.patch deleted file mode 100644 index 8b1e70bd0edebb..00000000000000 --- a/target/linux/generic/pending-5.15/610-netfilter_match_bypass_default_checks.patch +++ /dev/null @@ -1,110 +0,0 @@ -From: Felix Fietkau -Subject: kernel: add a new version of my netfilter speedup patches for linux 2.6.39 and 3.0 - -Signed-off-by: Felix Fietkau ---- - include/uapi/linux/netfilter_ipv4/ip_tables.h | 1 + - net/ipv4/netfilter/ip_tables.c | 37 +++++++++++++++++++++++++++ - 2 files changed, 38 insertions(+) - ---- a/include/uapi/linux/netfilter_ipv4/ip_tables.h -+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h -@@ -89,6 +89,7 @@ struct ipt_ip { - #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ - #define IPT_F_GOTO 0x02 /* Set if jump is a goto */ - #define IPT_F_MASK 0x03 /* All possible flag bits mask. */ -+#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */ - - /* Values for "inv" field in struct ipt_ip. */ - #define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */ ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -50,6 +50,9 @@ ip_packet_match(const struct iphdr *ip, - { - unsigned long ret; - -+ if (ipinfo->flags & IPT_F_NO_DEF_MATCH) -+ return true; -+ - if (NF_INVF(ipinfo, IPT_INV_SRCIP, - (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) || - NF_INVF(ipinfo, IPT_INV_DSTIP, -@@ -80,6 +83,29 @@ ip_packet_match(const struct iphdr *ip, - return true; - } - -+static void -+ip_checkdefault(struct ipt_ip *ip) -+{ -+ static const char iface_mask[IFNAMSIZ] = {}; -+ -+ if (ip->invflags || ip->flags & IPT_F_FRAG) -+ return; -+ -+ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0) -+ return; -+ -+ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0) -+ return; -+ -+ if (ip->smsk.s_addr || ip->dmsk.s_addr) -+ return; -+ -+ if (ip->proto) -+ return; -+ -+ ip->flags |= IPT_F_NO_DEF_MATCH; -+} -+ - static bool - ip_checkentry(const struct ipt_ip *ip) - { -@@ -524,6 +550,8 @@ find_check_entry(struct ipt_entry *e, st - struct xt_mtchk_param mtpar; - struct xt_entry_match *ematch; - -+ ip_checkdefault(&e->ip); -+ - if (!xt_percpu_counter_alloc(alloc_state, &e->counters)) - return -ENOMEM; - -@@ -818,6 +846,7 @@ copy_entries_to_user(unsigned int total_ - const struct xt_table_info *private = table->private; - int ret = 0; - const void *loc_cpu_entry; -+ u8 flags; - - counters = alloc_counters(table); - if (IS_ERR(counters)) -@@ -845,6 +874,14 @@ copy_entries_to_user(unsigned int total_ - goto free_counters; - } - -+ flags = e->ip.flags & IPT_F_MASK; -+ if (copy_to_user(userptr + off -+ + offsetof(struct ipt_entry, ip.flags), -+ &flags, sizeof(flags)) != 0) { -+ ret = -EFAULT; -+ goto free_counters; -+ } -+ - for (i = sizeof(struct ipt_entry); - i < e->target_offset; - i += m->u.match_size) { -@@ -1226,12 +1263,15 @@ compat_copy_entry_to_user(struct ipt_ent - compat_uint_t origsize; - const struct xt_entry_match *ematch; - int ret = 0; -+ u8 flags = e->ip.flags & IPT_F_MASK; - - origsize = *size; - ce = *dstptr; - if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 || - copy_to_user(&ce->counters, &counters[i], -- sizeof(counters[i])) != 0) -+ sizeof(counters[i])) != 0 || -+ copy_to_user(&ce->ip.flags, &flags, -+ sizeof(flags)) != 0) - return -EFAULT; - - *dstptr += sizeof(struct compat_ipt_entry); diff --git a/target/linux/generic/pending-5.15/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/pending-5.15/611-netfilter_match_bypass_default_table.patch deleted file mode 100644 index baf738a8d20898..00000000000000 --- a/target/linux/generic/pending-5.15/611-netfilter_match_bypass_default_table.patch +++ /dev/null @@ -1,106 +0,0 @@ -From: Felix Fietkau -Subject: netfilter: match bypass default table - -Signed-off-by: Felix Fietkau ---- - net/ipv4/netfilter/ip_tables.c | 79 +++++++++++++++++++++++++++++++----------- - 1 file changed, 58 insertions(+), 21 deletions(-) - ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -246,6 +246,33 @@ struct ipt_entry *ipt_next_entry(const s - return (void *)entry + entry->next_offset; - } - -+static bool -+ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict) -+{ -+ struct xt_entry_target *t; -+ struct xt_standard_target *st; -+ -+ if (e->target_offset != sizeof(struct ipt_entry)) -+ return false; -+ -+ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH)) -+ return false; -+ -+ t = ipt_get_target(e); -+ if (t->u.kernel.target->target) -+ return false; -+ -+ st = (struct xt_standard_target *) t; -+ if (st->verdict == XT_RETURN) -+ return false; -+ -+ if (st->verdict >= 0) -+ return false; -+ -+ *verdict = (unsigned)(-st->verdict) - 1; -+ return true; -+} -+ - /* Returns one of the generic firewall policies, like NF_ACCEPT. */ - unsigned int - ipt_do_table(struct sk_buff *skb, -@@ -266,27 +293,28 @@ ipt_do_table(struct sk_buff *skb, - unsigned int addend; - - /* Initialization */ -+ WARN_ON(!(table->valid_hooks & (1 << hook))); -+ local_bh_disable(); -+ private = READ_ONCE(table->private); /* Address dependency. */ -+ cpu = smp_processor_id(); -+ table_base = private->entries; -+ -+ e = get_entry(table_base, private->hook_entry[hook]); -+ if (ipt_handle_default_rule(e, &verdict)) { -+ struct xt_counters *counter; -+ -+ counter = xt_get_this_cpu_counter(&e->counters); -+ ADD_COUNTER(*counter, skb->len, 1); -+ local_bh_enable(); -+ return verdict; -+ } -+ - stackidx = 0; - ip = ip_hdr(skb); - indev = state->in ? state->in->name : nulldevname; - outdev = state->out ? state->out->name : nulldevname; -- /* We handle fragments by dealing with the first fragment as -- * if it was a normal packet. All other fragments are treated -- * normally, except that they will NEVER match rules that ask -- * things we don't know, ie. tcp syn flag or ports). If the -- * rule is also a fragment-specific rule, non-fragments won't -- * match it. */ -- acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -- acpar.thoff = ip_hdrlen(skb); -- acpar.hotdrop = false; -- acpar.state = state; - -- WARN_ON(!(table->valid_hooks & (1 << hook))); -- local_bh_disable(); - addend = xt_write_recseq_begin(); -- private = READ_ONCE(table->private); /* Address dependency. */ -- cpu = smp_processor_id(); -- table_base = private->entries; - jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; - - /* Switch to alternate jumpstack if we're being invoked via TEE. -@@ -299,7 +327,16 @@ ipt_do_table(struct sk_buff *skb, - if (static_key_false(&xt_tee_enabled)) - jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated); - -- e = get_entry(table_base, private->hook_entry[hook]); -+ /* We handle fragments by dealing with the first fragment as -+ * if it was a normal packet. All other fragments are treated -+ * normally, except that they will NEVER match rules that ask -+ * things we don't know, ie. tcp syn flag or ports). If the -+ * rule is also a fragment-specific rule, non-fragments won't -+ * match it. */ -+ acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -+ acpar.thoff = ip_hdrlen(skb); -+ acpar.hotdrop = false; -+ acpar.state = state; - - do { - const struct xt_entry_target *t; diff --git a/target/linux/generic/pending-5.15/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/pending-5.15/612-netfilter_match_reduce_memory_access.patch deleted file mode 100644 index 79da6778b684a5..00000000000000 --- a/target/linux/generic/pending-5.15/612-netfilter_match_reduce_memory_access.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Subject: netfilter: reduce match memory access - -Signed-off-by: Felix Fietkau ---- - net/ipv4/netfilter/ip_tables.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -53,9 +53,9 @@ ip_packet_match(const struct iphdr *ip, - if (ipinfo->flags & IPT_F_NO_DEF_MATCH) - return true; - -- if (NF_INVF(ipinfo, IPT_INV_SRCIP, -+ if (NF_INVF(ipinfo, IPT_INV_SRCIP, ipinfo->smsk.s_addr && - (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) || -- NF_INVF(ipinfo, IPT_INV_DSTIP, -+ NF_INVF(ipinfo, IPT_INV_DSTIP, ipinfo->dmsk.s_addr && - (ip->daddr & ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr)) - return false; - diff --git a/target/linux/generic/pending-5.15/620-net_sched-codel-do-not-defer-queue-length-update.patch b/target/linux/generic/pending-5.15/620-net_sched-codel-do-not-defer-queue-length-update.patch deleted file mode 100644 index 4b4825ae3b9a4a..00000000000000 --- a/target/linux/generic/pending-5.15/620-net_sched-codel-do-not-defer-queue-length-update.patch +++ /dev/null @@ -1,86 +0,0 @@ -From: Konstantin Khlebnikov -Date: Mon, 21 Aug 2017 11:14:14 +0300 -Subject: [PATCH] net_sched/codel: do not defer queue length update - -When codel wants to drop last packet in ->dequeue() it cannot call -qdisc_tree_reduce_backlog() right away - it will notify parent qdisc -about zero qlen and HTB/HFSC will deactivate class. The same class will -be deactivated second time by caller of ->dequeue(). Currently codel and -fq_codel defer update. This triggers warning in HFSC when it's qlen != 0 -but there is no active classes. - -This patch update parent queue length immediately: just temporary increase -qlen around qdisc_tree_reduce_backlog() to prevent first class deactivation -if we have skb to return. - -This might open another problem in HFSC - now operation peek could fail and -deactivate parent class. - -Signed-off-by: Konstantin Khlebnikov -Link: https://bugzilla.kernel.org/show_bug.cgi?id=109581 ---- - ---- a/net/sched/sch_codel.c -+++ b/net/sched/sch_codel.c -@@ -95,11 +95,17 @@ static struct sk_buff *codel_qdisc_deque - &q->stats, qdisc_pkt_len, codel_get_enqueue_time, - drop_func, dequeue_func); - -- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0, -- * or HTB crashes. Defer it for next round. -+ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate -+ * parent class, dequeue in parent qdisc will do the same if we -+ * return skb. Temporary increment qlen if we have skb. - */ -- if (q->stats.drop_count && sch->q.qlen) { -- qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len); -+ if (q->stats.drop_count) { -+ if (skb) -+ sch->q.qlen++; -+ qdisc_tree_reduce_backlog(sch, q->stats.drop_count, -+ q->stats.drop_len); -+ if (skb) -+ sch->q.qlen--; - q->stats.drop_count = 0; - q->stats.drop_len = 0; - } ---- a/net/sched/sch_fq_codel.c -+++ b/net/sched/sch_fq_codel.c -@@ -304,6 +304,21 @@ begin: - &flow->cvars, &q->cstats, qdisc_pkt_len, - codel_get_enqueue_time, drop_func, dequeue_func); - -+ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate -+ * parent class, dequeue in parent qdisc will do the same if we -+ * return skb. Temporary increment qlen if we have skb. -+ */ -+ if (q->cstats.drop_count) { -+ if (skb) -+ sch->q.qlen++; -+ qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, -+ q->cstats.drop_len); -+ if (skb) -+ sch->q.qlen--; -+ q->cstats.drop_count = 0; -+ q->cstats.drop_len = 0; -+ } -+ - if (!skb) { - /* force a pass through old_flows to prevent starvation */ - if ((head == &q->new_flows) && !list_empty(&q->old_flows)) -@@ -314,15 +329,6 @@ begin: - } - qdisc_bstats_update(sch, skb); - flow->deficit -= qdisc_pkt_len(skb); -- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0, -- * or HTB crashes. Defer it for next round. -- */ -- if (q->cstats.drop_count && sch->q.qlen) { -- qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, -- q->cstats.drop_len); -- q->cstats.drop_count = 0; -- q->cstats.drop_len = 0; -- } - return skb; - } - diff --git a/target/linux/generic/pending-5.15/630-packet_socket_type.patch b/target/linux/generic/pending-5.15/630-packet_socket_type.patch deleted file mode 100644 index 486ba9dee91c64..00000000000000 --- a/target/linux/generic/pending-5.15/630-packet_socket_type.patch +++ /dev/null @@ -1,138 +0,0 @@ -From: Felix Fietkau -Subject: net: add an optimization for dealing with raw sockets - -lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6 -Signed-off-by: Felix Fietkau ---- - include/uapi/linux/if_packet.h | 3 +++ - net/packet/af_packet.c | 34 +++++++++++++++++++++++++++------- - net/packet/internal.h | 1 + - 3 files changed, 31 insertions(+), 7 deletions(-) - ---- a/include/uapi/linux/if_packet.h -+++ b/include/uapi/linux/if_packet.h -@@ -33,6 +33,8 @@ struct sockaddr_ll { - #define PACKET_KERNEL 7 /* To kernel space */ - /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */ - #define PACKET_FASTROUTE 6 /* Fastrouted frame */ -+#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */ -+ - - /* Packet socket options */ - -@@ -59,6 +61,7 @@ struct sockaddr_ll { - #define PACKET_ROLLOVER_STATS 21 - #define PACKET_FANOUT_DATA 22 - #define PACKET_IGNORE_OUTGOING 23 -+#define PACKET_RECV_TYPE 24 - - #define PACKET_FANOUT_HASH 0 - #define PACKET_FANOUT_LB 1 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -1830,6 +1830,7 @@ static int packet_rcv_spkt(struct sk_buf - { - struct sock *sk; - struct sockaddr_pkt *spkt; -+ struct packet_sock *po; - - /* - * When we registered the protocol we saved the socket in the data -@@ -1837,6 +1838,7 @@ static int packet_rcv_spkt(struct sk_buf - */ - - sk = pt->af_packet_priv; -+ po = pkt_sk(sk); - - /* - * Yank back the headers [hope the device set this -@@ -1849,7 +1851,7 @@ static int packet_rcv_spkt(struct sk_buf - * so that this procedure is noop. - */ - -- if (skb->pkt_type == PACKET_LOOPBACK) -+ if (!(po->pkt_type & (1 << skb->pkt_type))) - goto out; - - if (!net_eq(dev_net(dev), sock_net(sk))) -@@ -2095,12 +2097,12 @@ static int packet_rcv(struct sk_buff *sk - unsigned int snaplen, res; - bool is_drop_n_account = false; - -- if (skb->pkt_type == PACKET_LOOPBACK) -- goto drop; -- - sk = pt->af_packet_priv; - po = pkt_sk(sk); - -+ if (!(po->pkt_type & (1 << skb->pkt_type))) -+ goto drop; -+ - if (!net_eq(dev_net(dev), sock_net(sk))) - goto drop; - -@@ -2226,12 +2228,12 @@ static int tpacket_rcv(struct sk_buff *s - BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32); - BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48); - -- if (skb->pkt_type == PACKET_LOOPBACK) -- goto drop; -- - sk = pt->af_packet_priv; - po = pkt_sk(sk); - -+ if (!(po->pkt_type & (1 << skb->pkt_type))) -+ goto drop; -+ - if (!net_eq(dev_net(dev), sock_net(sk))) - goto drop; - -@@ -3345,6 +3347,7 @@ static int packet_create(struct net *net - mutex_init(&po->pg_vec_lock); - po->rollover = NULL; - po->prot_hook.func = packet_rcv; -+ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK); - - if (sock->type == SOCK_PACKET) - po->prot_hook.func = packet_rcv_spkt; -@@ -3982,6 +3985,16 @@ packet_setsockopt(struct socket *sock, i - WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit); - return 0; - } -+ case PACKET_RECV_TYPE: -+ { -+ unsigned int val; -+ if (optlen != sizeof(val)) -+ return -EINVAL; -+ if (copy_from_sockptr(&val, optval, sizeof(val))) -+ return -EFAULT; -+ po->pkt_type = val & ~BIT(PACKET_LOOPBACK); -+ return 0; -+ } - default: - return -ENOPROTOOPT; - } -@@ -4038,6 +4051,13 @@ static int packet_getsockopt(struct sock - case PACKET_VNET_HDR: - val = po->has_vnet_hdr; - break; -+ case PACKET_RECV_TYPE: -+ if (len > sizeof(unsigned int)) -+ len = sizeof(unsigned int); -+ val = po->pkt_type; -+ -+ data = &val; -+ break; - case PACKET_VERSION: - val = po->tp_version; - break; ---- a/net/packet/internal.h -+++ b/net/packet/internal.h -@@ -136,6 +136,7 @@ struct packet_sock { - int (*xmit)(struct sk_buff *skb); - struct packet_type prot_hook ____cacheline_aligned_in_smp; - atomic_t tp_drops ____cacheline_aligned_in_smp; -+ unsigned int pkt_type; - }; - - static inline struct packet_sock *pkt_sk(struct sock *sk) diff --git a/target/linux/generic/pending-5.15/655-increase_skb_pad.patch b/target/linux/generic/pending-5.15/655-increase_skb_pad.patch deleted file mode 100644 index e9075f43c8743c..00000000000000 --- a/target/linux/generic/pending-5.15/655-increase_skb_pad.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Felix Fietkau -Subject: kernel: add a few patches for avoiding unnecessary skb reallocations - significantly improves ethernet<->wireless performance - -lede-commit: 6f89cffc9add6939d44a6b54cf9a5e77849aa7fd -Signed-off-by: Felix Fietkau ---- - include/linux/skbuff.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -2836,7 +2836,7 @@ static inline int pskb_network_may_pull( - * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) - */ - #ifndef NET_SKB_PAD --#define NET_SKB_PAD max(32, L1_CACHE_BYTES) -+#define NET_SKB_PAD max(64, L1_CACHE_BYTES) - #endif - - int ___pskb_trim(struct sk_buff *skb, unsigned int len); diff --git a/target/linux/generic/pending-5.15/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-5.15/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch deleted file mode 100644 index 3931278a6df481..00000000000000 --- a/target/linux/generic/pending-5.15/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch +++ /dev/null @@ -1,511 +0,0 @@ -From: Steven Barth -Subject: Add support for MAP-E FMRs (mesh mode) - -MAP-E FMRs (draft-ietf-softwire-map-10) are rules for IPv4-communication -between MAP CEs (mesh mode) without the need to forward such data to a -border relay. This is similar to how 6rd works but for IPv4 over IPv6. - -Signed-off-by: Steven Barth ---- - include/net/ip6_tunnel.h | 13 ++ - include/uapi/linux/if_tunnel.h | 13 ++ - net/ipv6/ip6_tunnel.c | 276 +++++++++++++++++++++++++++++++++++++++-- - 3 files changed, 291 insertions(+), 11 deletions(-) - ---- a/include/net/ip6_tunnel.h -+++ b/include/net/ip6_tunnel.h -@@ -18,6 +18,18 @@ - /* determine capability on a per-packet basis */ - #define IP6_TNL_F_CAP_PER_PACKET 0x40000 - -+/* IPv6 tunnel FMR */ -+struct __ip6_tnl_fmr { -+ struct __ip6_tnl_fmr *next; /* next fmr in list */ -+ struct in6_addr ip6_prefix; -+ struct in_addr ip4_prefix; -+ -+ __u8 ip6_prefix_len; -+ __u8 ip4_prefix_len; -+ __u8 ea_len; -+ __u8 offset; -+}; -+ - struct __ip6_tnl_parm { - char name[IFNAMSIZ]; /* name of tunnel device */ - int link; /* ifindex of underlying L2 interface */ -@@ -29,6 +41,7 @@ struct __ip6_tnl_parm { - __u32 flags; /* tunnel flags */ - struct in6_addr laddr; /* local tunnel end-point address */ - struct in6_addr raddr; /* remote tunnel end-point address */ -+ struct __ip6_tnl_fmr *fmrs; /* FMRs */ - - __be16 i_flags; - __be16 o_flags; ---- a/include/uapi/linux/if_tunnel.h -+++ b/include/uapi/linux/if_tunnel.h -@@ -77,10 +77,23 @@ enum { - IFLA_IPTUN_ENCAP_DPORT, - IFLA_IPTUN_COLLECT_METADATA, - IFLA_IPTUN_FWMARK, -+ IFLA_IPTUN_FMRS, - __IFLA_IPTUN_MAX, - }; - #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) - -+enum { -+ IFLA_IPTUN_FMR_UNSPEC, -+ IFLA_IPTUN_FMR_IP6_PREFIX, -+ IFLA_IPTUN_FMR_IP4_PREFIX, -+ IFLA_IPTUN_FMR_IP6_PREFIX_LEN, -+ IFLA_IPTUN_FMR_IP4_PREFIX_LEN, -+ IFLA_IPTUN_FMR_EA_LEN, -+ IFLA_IPTUN_FMR_OFFSET, -+ __IFLA_IPTUN_FMR_MAX, -+}; -+#define IFLA_IPTUN_FMR_MAX (__IFLA_IPTUN_FMR_MAX - 1) -+ - enum tunnel_encap_types { - TUNNEL_ENCAP_NONE, - TUNNEL_ENCAP_FOU, ---- a/net/ipv6/ip6_tunnel.c -+++ b/net/ipv6/ip6_tunnel.c -@@ -11,6 +11,9 @@ - * linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c - * - * RFC 2473 -+ * -+ * Changes: -+ * Steven Barth : MAP-E FMR support - */ - - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -@@ -67,9 +70,9 @@ static bool log_ecn_error = true; - module_param(log_ecn_error, bool, 0644); - MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); - --static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) -+static u32 HASH(const struct in6_addr *addr) - { -- u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2); -+ u32 hash = ipv6_addr_hash(addr); - - return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT); - } -@@ -114,17 +117,33 @@ static struct ip6_tnl * - ip6_tnl_lookup(struct net *net, int link, - const struct in6_addr *remote, const struct in6_addr *local) - { -- unsigned int hash = HASH(remote, local); -+ unsigned int hash = HASH(local); - struct ip6_tnl *t, *cand = NULL; - struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - struct in6_addr any; - - for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { - if (!ipv6_addr_equal(local, &t->parms.laddr) || -- !ipv6_addr_equal(remote, &t->parms.raddr) || - !(t->dev->flags & IFF_UP)) - continue; - -+ if (!ipv6_addr_equal(remote, &t->parms.raddr)) { -+ struct __ip6_tnl_fmr *fmr; -+ bool found = false; -+ -+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { -+ if (!ipv6_prefix_equal(remote, &fmr->ip6_prefix, -+ fmr->ip6_prefix_len)) -+ continue; -+ -+ found = true; -+ break; -+ } -+ -+ if (!found) -+ continue; -+ } -+ - if (link == t->parms.link) - return t; - else -@@ -132,7 +151,7 @@ ip6_tnl_lookup(struct net *net, int link - } - - memset(&any, 0, sizeof(any)); -- hash = HASH(&any, local); -+ hash = HASH(local); - for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { - if (!ipv6_addr_equal(local, &t->parms.laddr) || - !ipv6_addr_any(&t->parms.raddr) || -@@ -145,7 +164,7 @@ ip6_tnl_lookup(struct net *net, int link - cand = t; - } - -- hash = HASH(remote, &any); -+ hash = HASH(&any); - for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { - if (!ipv6_addr_equal(remote, &t->parms.raddr) || - !ipv6_addr_any(&t->parms.laddr) || -@@ -194,7 +213,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, - - if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) { - prio = 1; -- h = HASH(remote, local); -+ h = HASH(local); - } - return &ip6n->tnls[prio][h]; - } -@@ -378,6 +397,12 @@ ip6_tnl_dev_uninit(struct net_device *de - struct net *net = t->net; - struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - -+ while (t->parms.fmrs) { -+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; -+ kfree(t->parms.fmrs); -+ t->parms.fmrs = next; -+ } -+ - if (dev == ip6n->fb_tnl_dev) - RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL); - else -@@ -790,6 +815,107 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t, - } - EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl); - -+/** -+ * ip4ip6_fmr_calc - calculate target / source IPv6-address based on FMR -+ * @dest: destination IPv6 address buffer -+ * @skb: received socket buffer -+ * @fmr: MAP FMR -+ * @xmit: Calculate for xmit or rcv -+ **/ -+static void ip4ip6_fmr_calc(struct in6_addr *dest, -+ const struct iphdr *iph, const uint8_t *end, -+ const struct __ip6_tnl_fmr *fmr, bool xmit) -+{ -+ int psidlen = fmr->ea_len - (32 - fmr->ip4_prefix_len); -+ u8 *portp = NULL; -+ bool use_dest_addr; -+ const struct iphdr *dsth = iph; -+ -+ if ((u8*)dsth >= end) -+ return; -+ -+ /* find significant IP header */ -+ if (iph->protocol == IPPROTO_ICMP) { -+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); -+ if (ih && ((u8*)&ih[1]) <= end && ( -+ ih->type == ICMP_DEST_UNREACH || -+ ih->type == ICMP_SOURCE_QUENCH || -+ ih->type == ICMP_TIME_EXCEEDED || -+ ih->type == ICMP_PARAMETERPROB || -+ ih->type == ICMP_REDIRECT)) -+ dsth = (const struct iphdr*)&ih[1]; -+ } -+ -+ /* in xmit-path use dest port by default and source port only if -+ this is an ICMP reply to something else; vice versa in rcv-path */ -+ use_dest_addr = (xmit && dsth == iph) || (!xmit && dsth != iph); -+ -+ /* get dst port */ -+ if (((u8*)&dsth[1]) <= end && ( -+ dsth->protocol == IPPROTO_UDP || -+ dsth->protocol == IPPROTO_TCP || -+ dsth->protocol == IPPROTO_SCTP || -+ dsth->protocol == IPPROTO_DCCP)) { -+ /* for UDP, TCP, SCTP and DCCP source and dest port -+ follow IPv4 header directly */ -+ portp = ((u8*)dsth) + dsth->ihl * 4; -+ -+ if (use_dest_addr) -+ portp += sizeof(u16); -+ } else if (iph->protocol == IPPROTO_ICMP) { -+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); -+ -+ /* use icmp identifier as port */ -+ if (((u8*)&ih) <= end && ( -+ (use_dest_addr && ( -+ ih->type == ICMP_ECHOREPLY || -+ ih->type == ICMP_TIMESTAMPREPLY || -+ ih->type == ICMP_INFO_REPLY || -+ ih->type == ICMP_ADDRESSREPLY)) || -+ (!use_dest_addr && ( -+ ih->type == ICMP_ECHO || -+ ih->type == ICMP_TIMESTAMP || -+ ih->type == ICMP_INFO_REQUEST || -+ ih->type == ICMP_ADDRESS) -+ ))) -+ portp = (u8*)&ih->un.echo.id; -+ } -+ -+ if ((portp && &portp[2] <= end) || psidlen == 0) { -+ int frombyte = fmr->ip6_prefix_len / 8; -+ int fromrem = fmr->ip6_prefix_len % 8; -+ int bytes = sizeof(struct in6_addr) - frombyte; -+ const u32 *addr = (use_dest_addr) ? &iph->daddr : &iph->saddr; -+ u64 eabits = ((u64)ntohl(*addr)) << (32 + fmr->ip4_prefix_len); -+ u64 t = 0; -+ -+ /* extract PSID from port and add it to eabits */ -+ u16 psidbits = 0; -+ if (psidlen > 0) { -+ psidbits = ((u16)portp[0]) << 8 | ((u16)portp[1]); -+ psidbits >>= 16 - psidlen - fmr->offset; -+ psidbits = (u16)(psidbits << (16 - psidlen)); -+ eabits |= ((u64)psidbits) << (48 - (fmr->ea_len - psidlen)); -+ } -+ -+ /* rewrite destination address */ -+ *dest = fmr->ip6_prefix; -+ memcpy(&dest->s6_addr[10], addr, sizeof(*addr)); -+ dest->s6_addr16[7] = htons(psidbits >> (16 - psidlen)); -+ -+ if (bytes > sizeof(u64)) -+ bytes = sizeof(u64); -+ -+ /* insert eabits */ -+ memcpy(&t, &dest->s6_addr[frombyte], bytes); -+ t = be64_to_cpu(t) & ~(((((u64)1) << fmr->ea_len) - 1) -+ << (64 - fmr->ea_len - fromrem)); -+ t = cpu_to_be64(t | (eabits >> fromrem)); -+ memcpy(&dest->s6_addr[frombyte], &t, bytes); -+ } -+} -+ -+ - static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, - const struct tnl_ptk_info *tpi, - struct metadata_dst *tun_dst, -@@ -857,6 +983,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl - - memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); - -+ if (tpi->proto == htons(ETH_P_IP) && tunnel->parms.fmrs && -+ !ipv6_addr_equal(&ipv6h->saddr, &tunnel->parms.raddr)) { -+ /* Packet didn't come from BR, so lookup FMR */ -+ struct __ip6_tnl_fmr *fmr; -+ struct in6_addr expected = tunnel->parms.raddr; -+ for (fmr = tunnel->parms.fmrs; fmr; fmr = fmr->next) -+ if (ipv6_prefix_equal(&ipv6h->saddr, -+ &fmr->ip6_prefix, fmr->ip6_prefix_len)) -+ break; -+ -+ /* Check that IPv6 matches IPv4 source to prevent spoofing */ -+ if (fmr) -+ ip4ip6_fmr_calc(&expected, ip_hdr(skb), -+ skb_tail_pointer(skb), fmr, false); -+ -+ if (!ipv6_addr_equal(&ipv6h->saddr, &expected)) { -+ rcu_read_unlock(); -+ goto drop; -+ } -+ } -+ - __skb_tunnel_rx(skb, tunnel->dev, tunnel->net); - - err = dscp_ecn_decapsulate(tunnel, ipv6h, skb); -@@ -1004,6 +1151,7 @@ static void init_tel_txopt(struct ipv6_t - opt->ops.opt_nflen = 8; - } - -+ - /** - * ip6_tnl_addr_conflict - compare packet addresses to tunnel's own - * @t: the outgoing tunnel device -@@ -1284,6 +1432,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str - u8 protocol) - { - struct ip6_tnl *t = netdev_priv(dev); -+ struct __ip6_tnl_fmr *fmr; - struct ipv6hdr *ipv6h; - const struct iphdr *iph; - int encap_limit = -1; -@@ -1383,6 +1532,18 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str - fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); - dsfield = INET_ECN_encapsulate(dsfield, orig_dsfield); - -+ /* try to find matching FMR */ -+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { -+ unsigned mshift = 32 - fmr->ip4_prefix_len; -+ if (ntohl(fmr->ip4_prefix.s_addr) >> mshift == -+ ntohl(ip_hdr(skb)->daddr) >> mshift) -+ break; -+ } -+ -+ /* change dstaddr according to FMR */ -+ if (fmr) -+ ip4ip6_fmr_calc(&fl6.daddr, ip_hdr(skb), skb_tail_pointer(skb), fmr, true); -+ - if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) - return -1; - -@@ -1536,6 +1697,14 @@ ip6_tnl_change(struct ip6_tnl *t, const - t->parms.link = p->link; - t->parms.proto = p->proto; - t->parms.fwmark = p->fwmark; -+ -+ while (t->parms.fmrs) { -+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; -+ kfree(t->parms.fmrs); -+ t->parms.fmrs = next; -+ } -+ t->parms.fmrs = p->fmrs; -+ - dst_cache_reset(&t->dst_cache); - ip6_tnl_link_config(t); - return 0; -@@ -1574,6 +1743,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_ - p->flowinfo = u->flowinfo; - p->link = u->link; - p->proto = u->proto; -+ p->fmrs = NULL; - memcpy(p->name, u->name, sizeof(u->name)); - } - -@@ -1960,6 +2130,15 @@ static int ip6_tnl_validate(struct nlatt - return 0; - } - -+static const struct nla_policy ip6_tnl_fmr_policy[IFLA_IPTUN_FMR_MAX + 1] = { -+ [IFLA_IPTUN_FMR_IP6_PREFIX] = { .len = sizeof(struct in6_addr) }, -+ [IFLA_IPTUN_FMR_IP4_PREFIX] = { .len = sizeof(struct in_addr) }, -+ [IFLA_IPTUN_FMR_IP6_PREFIX_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_IP4_PREFIX_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_EA_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_OFFSET] = { .type = NLA_U8 } -+}; -+ - static void ip6_tnl_netlink_parms(struct nlattr *data[], - struct __ip6_tnl_parm *parms) - { -@@ -1997,6 +2176,46 @@ static void ip6_tnl_netlink_parms(struct - - if (data[IFLA_IPTUN_FWMARK]) - parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]); -+ -+ if (data[IFLA_IPTUN_FMRS]) { -+ unsigned rem; -+ struct nlattr *fmr; -+ nla_for_each_nested(fmr, data[IFLA_IPTUN_FMRS], rem) { -+ struct nlattr *fmrd[IFLA_IPTUN_FMR_MAX + 1], *c; -+ struct __ip6_tnl_fmr *nfmr; -+ -+ nla_parse_nested(fmrd, IFLA_IPTUN_FMR_MAX, -+ fmr, ip6_tnl_fmr_policy, NULL); -+ -+ if (!(nfmr = kzalloc(sizeof(*nfmr), GFP_KERNEL))) -+ continue; -+ -+ nfmr->offset = 6; -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX])) -+ nla_memcpy(&nfmr->ip6_prefix, fmrd[IFLA_IPTUN_FMR_IP6_PREFIX], -+ sizeof(nfmr->ip6_prefix)); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX])) -+ nla_memcpy(&nfmr->ip4_prefix, fmrd[IFLA_IPTUN_FMR_IP4_PREFIX], -+ sizeof(nfmr->ip4_prefix)); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX_LEN])) -+ nfmr->ip6_prefix_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX_LEN])) -+ nfmr->ip4_prefix_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_EA_LEN])) -+ nfmr->ea_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_OFFSET])) -+ nfmr->offset = nla_get_u8(c); -+ -+ nfmr->next = parms->fmrs; -+ parms->fmrs = nfmr; -+ } -+ } - } - - static bool ip6_tnl_netlink_encap_parms(struct nlattr *data[], -@@ -2112,6 +2331,12 @@ static void ip6_tnl_dellink(struct net_d - - static size_t ip6_tnl_get_size(const struct net_device *dev) - { -+ const struct ip6_tnl *t = netdev_priv(dev); -+ struct __ip6_tnl_fmr *c; -+ int fmrs = 0; -+ for (c = t->parms.fmrs; c; c = c->next) -+ ++fmrs; -+ - return - /* IFLA_IPTUN_LINK */ - nla_total_size(4) + -@@ -2141,6 +2366,24 @@ static size_t ip6_tnl_get_size(const str - nla_total_size(0) + - /* IFLA_IPTUN_FWMARK */ - nla_total_size(4) + -+ /* IFLA_IPTUN_FMRS */ -+ nla_total_size(0) + -+ ( -+ /* nest */ -+ nla_total_size(0) + -+ /* IFLA_IPTUN_FMR_IP6_PREFIX */ -+ nla_total_size(sizeof(struct in6_addr)) + -+ /* IFLA_IPTUN_FMR_IP4_PREFIX */ -+ nla_total_size(sizeof(struct in_addr)) + -+ /* IFLA_IPTUN_FMR_EA_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_IP6_PREFIX_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_IP4_PREFIX_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_OFFSET */ -+ nla_total_size(1) -+ ) * fmrs + - 0; - } - -@@ -2148,6 +2391,9 @@ static int ip6_tnl_fill_info(struct sk_b - { - struct ip6_tnl *tunnel = netdev_priv(dev); - struct __ip6_tnl_parm *parm = &tunnel->parms; -+ struct __ip6_tnl_fmr *c; -+ int fmrcnt = 0; -+ struct nlattr *fmrs; - - if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || - nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) || -@@ -2157,9 +2403,27 @@ static int ip6_tnl_fill_info(struct sk_b - nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || - nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) || - nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) || -- nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark)) -+ nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark) || -+ !(fmrs = nla_nest_start(skb, IFLA_IPTUN_FMRS))) - goto nla_put_failure; - -+ for (c = parm->fmrs; c; c = c->next) { -+ struct nlattr *fmr = nla_nest_start(skb, ++fmrcnt); -+ if (!fmr || -+ nla_put(skb, IFLA_IPTUN_FMR_IP6_PREFIX, -+ sizeof(c->ip6_prefix), &c->ip6_prefix) || -+ nla_put(skb, IFLA_IPTUN_FMR_IP4_PREFIX, -+ sizeof(c->ip4_prefix), &c->ip4_prefix) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, c->ip6_prefix_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, c->ip4_prefix_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_EA_LEN, c->ea_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_OFFSET, c->offset)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, fmr); -+ } -+ nla_nest_end(skb, fmrs); -+ - if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) || - nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) || - nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) || -@@ -2199,6 +2463,7 @@ static const struct nla_policy ip6_tnl_p - [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 }, - [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG }, - [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 }, -+ [IFLA_IPTUN_FMRS] = { .type = NLA_NESTED }, - }; - - static struct rtnl_link_ops ip6_link_ops __read_mostly = { diff --git a/target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch deleted file mode 100644 index d4e274e9a42a99..00000000000000 --- a/target/linux/generic/pending-5.15/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch +++ /dev/null @@ -1,263 +0,0 @@ -From: Jonas Gorski -Subject: ipv6: allow rejecting with "source address failed policy" - -RFC6204 L-14 requires rejecting traffic from invalid addresses with -ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/ -egress policy) on the LAN side, so add an appropriate rule for that. - -Signed-off-by: Jonas Gorski ---- - include/net/netns/ipv6.h | 1 + - include/uapi/linux/fib_rules.h | 4 +++ - include/uapi/linux/rtnetlink.h | 1 + - net/ipv4/fib_semantics.c | 4 +++ - net/ipv4/fib_trie.c | 1 + - net/ipv4/ipmr.c | 1 + - net/ipv6/fib6_rules.c | 4 +++ - net/ipv6/ip6mr.c | 2 ++ - net/ipv6/route.c | 58 +++++++++++++++++++++++++++++++++++++++++- - 9 files changed, 75 insertions(+), 1 deletion(-) - ---- a/include/net/netns/ipv6.h -+++ b/include/net/netns/ipv6.h -@@ -85,6 +85,7 @@ struct netns_ipv6 { - unsigned int fib6_routes_require_src; - #endif - struct rt6_info *ip6_prohibit_entry; -+ struct rt6_info *ip6_policy_failed_entry; - struct rt6_info *ip6_blk_hole_entry; - struct fib6_table *fib6_local_tbl; - struct fib_rules_ops *fib6_rules_ops; ---- a/include/uapi/linux/fib_rules.h -+++ b/include/uapi/linux/fib_rules.h -@@ -82,6 +82,10 @@ enum { - FR_ACT_BLACKHOLE, /* Drop without notification */ - FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ - FR_ACT_PROHIBIT, /* Drop with EACCES */ -+ FR_ACT_RES9, -+ FR_ACT_RES10, -+ FR_ACT_RES11, -+ FR_ACT_POLICY_FAILED, /* Drop with EACCES */ - __FR_ACT_MAX, - }; - ---- a/include/uapi/linux/rtnetlink.h -+++ b/include/uapi/linux/rtnetlink.h -@@ -256,6 +256,7 @@ enum { - RTN_THROW, /* Not in this table */ - RTN_NAT, /* Translate this address */ - RTN_XRESOLVE, /* Use external resolver */ -+ RTN_POLICY_FAILED, /* Failed ingress/egress policy */ - __RTN_MAX - }; - ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -143,6 +143,10 @@ const struct fib_prop fib_props[RTN_MAX - .error = -EINVAL, - .scope = RT_SCOPE_NOWHERE, - }, -+ [RTN_POLICY_FAILED] = { -+ .error = -EACCES, -+ .scope = RT_SCOPE_UNIVERSE, -+ }, - }; - - static void rt_fibinfo_free(struct rtable __rcu **rtp) ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -2777,6 +2777,7 @@ static const char *const rtn_type_names[ - [RTN_THROW] = "THROW", - [RTN_NAT] = "NAT", - [RTN_XRESOLVE] = "XRESOLVE", -+ [RTN_POLICY_FAILED] = "POLICY_FAILED", - }; - - static inline const char *rtn_type(char *buf, size_t len, unsigned int t) ---- a/net/ipv4/ipmr.c -+++ b/net/ipv4/ipmr.c -@@ -175,6 +175,7 @@ static int ipmr_rule_action(struct fib_r - case FR_ACT_UNREACHABLE: - return -ENETUNREACH; - case FR_ACT_PROHIBIT: -+ case FR_ACT_POLICY_FAILED: - return -EACCES; - case FR_ACT_BLACKHOLE: - default: ---- a/net/ipv6/fib6_rules.c -+++ b/net/ipv6/fib6_rules.c -@@ -220,6 +220,10 @@ static int __fib6_rule_action(struct fib - err = -EACCES; - rt = net->ipv6.ip6_prohibit_entry; - goto discard_pkt; -+ case FR_ACT_POLICY_FAILED: -+ err = -EACCES; -+ rt = net->ipv6.ip6_policy_failed_entry; -+ goto discard_pkt; - } - - tb_id = fib_rule_get_table(rule, arg); ---- a/net/ipv6/ip6mr.c -+++ b/net/ipv6/ip6mr.c -@@ -163,6 +163,8 @@ static int ip6mr_rule_action(struct fib_ - return -ENETUNREACH; - case FR_ACT_PROHIBIT: - return -EACCES; -+ case FR_ACT_POLICY_FAILED: -+ return -EACCES; - case FR_ACT_BLACKHOLE: - default: - return -EINVAL; ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -98,6 +98,8 @@ static int ip6_pkt_discard(struct sk_bu - static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); - static int ip6_pkt_prohibit(struct sk_buff *skb); - static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); -+static int ip6_pkt_policy_failed(struct sk_buff *skb); -+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb); - static void ip6_link_failure(struct sk_buff *skb); - static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, - struct sk_buff *skb, u32 mtu, -@@ -313,6 +315,18 @@ static const struct rt6_info ip6_prohibi - .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), - }; - -+static const struct rt6_info ip6_policy_failed_entry_template = { -+ .dst = { -+ .__refcnt = ATOMIC_INIT(1), -+ .__use = 1, -+ .obsolete = DST_OBSOLETE_FORCE_CHK, -+ .error = -EACCES, -+ .input = ip6_pkt_policy_failed, -+ .output = ip6_pkt_policy_failed_out, -+ }, -+ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), -+}; -+ - static const struct rt6_info ip6_blk_hole_entry_template = { - .dst = { - .__refcnt = ATOMIC_INIT(1), -@@ -1034,6 +1048,7 @@ static const int fib6_prop[RTN_MAX + 1] - [RTN_BLACKHOLE] = -EINVAL, - [RTN_UNREACHABLE] = -EHOSTUNREACH, - [RTN_PROHIBIT] = -EACCES, -+ [RTN_POLICY_FAILED] = -EACCES, - [RTN_THROW] = -EAGAIN, - [RTN_NAT] = -EINVAL, - [RTN_XRESOLVE] = -EINVAL, -@@ -1069,6 +1084,10 @@ static void ip6_rt_init_dst_reject(struc - rt->dst.output = ip6_pkt_prohibit_out; - rt->dst.input = ip6_pkt_prohibit; - break; -+ case RTN_POLICY_FAILED: -+ rt->dst.output = ip6_pkt_policy_failed_out; -+ rt->dst.input = ip6_pkt_policy_failed; -+ break; - case RTN_THROW: - case RTN_UNREACHABLE: - default: -@@ -4561,6 +4580,17 @@ static int ip6_pkt_prohibit_out(struct n - return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); - } - -+static int ip6_pkt_policy_failed(struct sk_buff *skb) -+{ -+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES); -+} -+ -+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb) -+{ -+ skb->dev = skb_dst(skb)->dev; -+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES); -+} -+ - /* - * Allocate a dst for local (unicast / anycast) address. - */ -@@ -5048,7 +5078,8 @@ static int rtm_to_fib6_config(struct sk_ - if (rtm->rtm_type == RTN_UNREACHABLE || - rtm->rtm_type == RTN_BLACKHOLE || - rtm->rtm_type == RTN_PROHIBIT || -- rtm->rtm_type == RTN_THROW) -+ rtm->rtm_type == RTN_THROW || -+ rtm->rtm_type == RTN_POLICY_FAILED) - cfg->fc_flags |= RTF_REJECT; - - if (rtm->rtm_type == RTN_LOCAL) -@@ -6295,6 +6326,8 @@ static int ip6_route_dev_notify(struct n - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - net->ipv6.ip6_prohibit_entry->dst.dev = dev; - net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); -+ net->ipv6.ip6_policy_failed_entry->dst.dev = dev; -+ net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev); - net->ipv6.ip6_blk_hole_entry->dst.dev = dev; - net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); - #endif -@@ -6306,6 +6339,7 @@ static int ip6_route_dev_notify(struct n - in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); -+ in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev); - in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); - #endif - } -@@ -6497,6 +6531,8 @@ static int __net_init ip6_route_net_init - - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - net->ipv6.fib6_has_custom_rules = false; -+ -+ - net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, - sizeof(*net->ipv6.ip6_prohibit_entry), - GFP_KERNEL); -@@ -6507,11 +6543,21 @@ static int __net_init ip6_route_net_init - ip6_template_metrics, true); - INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached); - -+ net->ipv6.ip6_policy_failed_entry = -+ kmemdup(&ip6_policy_failed_entry_template, -+ sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL); -+ if (!net->ipv6.ip6_policy_failed_entry) -+ goto out_ip6_prohibit_entry; -+ net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops; -+ dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst, -+ ip6_template_metrics, true); -+ INIT_LIST_HEAD(&net->ipv6.ip6_policy_failed_entry->rt6i_uncached); -+ - net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, - sizeof(*net->ipv6.ip6_blk_hole_entry), - GFP_KERNEL); - if (!net->ipv6.ip6_blk_hole_entry) -- goto out_ip6_prohibit_entry; -+ goto out_ip6_policy_failed_entry; - net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; - dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, - ip6_template_metrics, true); -@@ -6538,6 +6584,8 @@ out: - return ret; - - #ifdef CONFIG_IPV6_MULTIPLE_TABLES -+out_ip6_policy_failed_entry: -+ kfree(net->ipv6.ip6_policy_failed_entry); - out_ip6_prohibit_entry: - kfree(net->ipv6.ip6_prohibit_entry); - out_ip6_null_entry: -@@ -6557,6 +6605,7 @@ static void __net_exit ip6_route_net_exi - kfree(net->ipv6.ip6_null_entry); - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - kfree(net->ipv6.ip6_prohibit_entry); -+ kfree(net->ipv6.ip6_policy_failed_entry); - kfree(net->ipv6.ip6_blk_hole_entry); - #endif - dst_entries_destroy(&net->ipv6.ip6_dst_ops); -@@ -6640,6 +6689,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_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_policy_failed_entry->dst.dev = init_net.loopback_dev; -+ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev = -+ in6_dev_get(init_net.loopback_dev); - #endif - } - diff --git a/target/linux/generic/pending-5.15/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch b/target/linux/generic/pending-5.15/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch deleted file mode 100644 index bea43b2bada70c..00000000000000 --- a/target/linux/generic/pending-5.15/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Jonas Gorski -Subject: net: provide defines for _POLICY_FAILED until all code is updated - -Upstream introduced ICMPV6_POLICY_FAIL for code 5 of destination -unreachable, conflicting with our name. - -Add appropriate defines to allow our code to build with the new -name until we have updated our local patches for older kernels -and userspace packages. - -Signed-off-by: Jonas Gorski ---- - include/uapi/linux/fib_rules.h | 2 ++ - include/uapi/linux/icmpv6.h | 2 ++ - include/uapi/linux/rtnetlink.h | 2 ++ - 3 files changed, 6 insertions(+) - ---- a/include/uapi/linux/fib_rules.h -+++ b/include/uapi/linux/fib_rules.h -@@ -89,6 +89,8 @@ enum { - __FR_ACT_MAX, - }; - -+#define FR_ACT_FAILED_POLICY FR_ACT_POLICY_FAILED -+ - #define FR_ACT_MAX (__FR_ACT_MAX - 1) - - #endif ---- a/include/uapi/linux/icmpv6.h -+++ b/include/uapi/linux/icmpv6.h -@@ -126,6 +126,8 @@ struct icmp6hdr { - #define ICMPV6_POLICY_FAIL 5 - #define ICMPV6_REJECT_ROUTE 6 - -+#define ICMPV6_FAILED_POLICY ICMPV6_POLICY_FAIL -+ - /* - * Codes for Time Exceeded - */ ---- a/include/uapi/linux/rtnetlink.h -+++ b/include/uapi/linux/rtnetlink.h -@@ -260,6 +260,8 @@ enum { - __RTN_MAX - }; - -+#define RTN_FAILED_POLICY RTN_POLICY_FAILED -+ - #define RTN_MAX (__RTN_MAX - 1) - - diff --git a/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch deleted file mode 100644 index 6eb72abaa76fc7..00000000000000 --- a/target/linux/generic/pending-5.15/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +++ /dev/null @@ -1,149 +0,0 @@ -From: Felix Fietkau -Subject: net: replace GRO optimization patch with a new one that supports VLANs/bridges with different MAC addresses - -Signed-off-by: Felix Fietkau ---- - include/linux/netdevice.h | 2 ++ - include/linux/skbuff.h | 3 ++- - net/core/dev.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ - net/ethernet/eth.c | 18 +++++++++++++++++- - 4 files changed, 69 insertions(+), 2 deletions(-) - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -2099,6 +2099,8 @@ struct net_device { - struct netdev_hw_addr_list mc; - struct netdev_hw_addr_list dev_addrs; - -+ unsigned char local_addr_mask[MAX_ADDR_LEN]; -+ - #ifdef CONFIG_SYSFS - struct kset *queues_kset; - #endif ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -893,6 +893,7 @@ struct sk_buff { - #ifdef CONFIG_IPV6_NDISC_NODETYPE - __u8 ndisc_nodetype:2; - #endif -+ __u8 gro_skip:1; - - __u8 ipvs_property:1; - __u8 inner_protocol_type:1; ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -6077,6 +6077,9 @@ static enum gro_result dev_gro_receive(s - int same_flow; - int grow; - -+ if (skb->gro_skip) -+ goto normal; -+ - if (netif_elide_gro(skb->dev)) - goto normal; - -@@ -8094,6 +8097,48 @@ static void __netdev_adjacent_dev_unlink - &upper_dev->adj_list.lower); - } - -+static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr, -+ struct net_device *dev) -+{ -+ int i; -+ -+ for (i = 0; i < dev->addr_len; i++) -+ mask[i] |= addr[i] ^ dev->dev_addr[i]; -+} -+ -+static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev, -+ struct net_device *lower) -+{ -+ struct net_device *cur; -+ struct list_head *iter; -+ -+ netdev_for_each_upper_dev_rcu(dev, cur, iter) { -+ __netdev_addr_mask(mask, cur->dev_addr, lower); -+ __netdev_upper_mask(mask, cur, lower); -+ } -+} -+ -+static void __netdev_update_addr_mask(struct net_device *dev) -+{ -+ unsigned char mask[MAX_ADDR_LEN]; -+ struct net_device *cur; -+ struct list_head *iter; -+ -+ memset(mask, 0, sizeof(mask)); -+ __netdev_upper_mask(mask, dev, dev); -+ memcpy(dev->local_addr_mask, mask, dev->addr_len); -+ -+ netdev_for_each_lower_dev(dev, cur, iter) -+ __netdev_update_addr_mask(cur); -+} -+ -+static void netdev_update_addr_mask(struct net_device *dev) -+{ -+ rcu_read_lock(); -+ __netdev_update_addr_mask(dev); -+ rcu_read_unlock(); -+} -+ - static int __netdev_upper_dev_link(struct net_device *dev, - struct net_device *upper_dev, bool master, - void *upper_priv, void *upper_info, -@@ -8145,6 +8190,7 @@ static int __netdev_upper_dev_link(struc - if (ret) - return ret; - -+ netdev_update_addr_mask(dev); - ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, - &changeupper_info.info); - ret = notifier_to_errno(ret); -@@ -8241,6 +8287,7 @@ static void __netdev_upper_dev_unlink(st - - __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev); - -+ netdev_update_addr_mask(dev); - call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, - &changeupper_info.info); - -@@ -9060,6 +9107,7 @@ int dev_set_mac_address(struct net_devic - if (err) - return err; - dev->addr_assign_type = NET_ADDR_SET; -+ netdev_update_addr_mask(dev); - call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - add_device_randomness(dev->dev_addr, dev->addr_len); - return 0; ---- a/net/ethernet/eth.c -+++ b/net/ethernet/eth.c -@@ -142,6 +142,18 @@ u32 eth_get_headlen(const struct net_dev - } - EXPORT_SYMBOL(eth_get_headlen); - -+static inline bool -+eth_check_local_mask(const void *addr1, const void *addr2, const void *mask) -+{ -+ const u16 *a1 = addr1; -+ const u16 *a2 = addr2; -+ const u16 *m = mask; -+ -+ return (((a1[0] ^ a2[0]) & ~m[0]) | -+ ((a1[1] ^ a2[1]) & ~m[1]) | -+ ((a1[2] ^ a2[2]) & ~m[2])); -+} -+ - /** - * eth_type_trans - determine the packet's protocol ID. - * @skb: received socket data -@@ -165,6 +177,10 @@ __be16 eth_type_trans(struct sk_buff *sk - - eth_skb_pkt_type(skb, dev); - -+ if (unlikely(!ether_addr_equal_64bits(eth->h_dest, dev->dev_addr)) && -+ eth_check_local_mask(eth->h_dest, dev->dev_addr, dev->local_addr_mask)) -+ skb->gro_skip = 1; -+ - /* - * Some variants of DSA tagging don't have an ethertype field - * at all, so we check here whether one of those tagging diff --git a/target/linux/generic/pending-5.15/683-of_net-add-mac-address-to-of-tree.patch b/target/linux/generic/pending-5.15/683-of_net-add-mac-address-to-of-tree.patch deleted file mode 100644 index 03ee537fb8f8ad..00000000000000 --- a/target/linux/generic/pending-5.15/683-of_net-add-mac-address-to-of-tree.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 8585756342caa6d27008d1ad0c18023e4211a40a Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:22:48 +0200 -Subject: [PATCH] of/of_net: write back netdev MAC-address to device-tree - -The label-mac logic relies on the mac-address property of a netdev -devices of-node. However, the mac address can also be stored as a -different property or read from e.g. an mtd device. - -Create this node when reading a mac-address from OF if it does not -already exist and copy the mac-address used for the device to this -property. This way, the MAC address can be accessed using procfs. - ---- - net/core/of_net.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - ---- a/net/core/of_net.c -+++ b/net/core/of_net.c -@@ -95,6 +95,27 @@ static int of_get_mac_addr_nvmem(struct - return 0; - } - -+static int of_add_mac_address(struct device_node *np, u8* addr) -+{ -+ struct property *prop; -+ -+ prop = kzalloc(sizeof(*prop), GFP_KERNEL); -+ if (!prop) -+ return -ENOMEM; -+ -+ prop->name = "mac-address"; -+ prop->length = ETH_ALEN; -+ prop->value = kmemdup(addr, ETH_ALEN, GFP_KERNEL); -+ if (!prop->value || of_update_property(np, prop)) -+ goto free; -+ -+ return 0; -+free: -+ kfree(prop->value); -+ kfree(prop); -+ return -ENOMEM; -+} -+ - /** - * of_get_mac_address() - * @np: Caller's Device Node -@@ -130,17 +151,23 @@ int of_get_mac_address(struct device_nod - - ret = of_get_mac_addr(np, "mac-address", addr); - if (!ret) -- return 0; -+ goto found; - - ret = of_get_mac_addr(np, "local-mac-address", addr); - if (!ret) -- return 0; -+ goto found; - - ret = of_get_mac_addr(np, "address", addr); - if (!ret) -- return 0; -+ goto found; - -- return of_get_mac_addr_nvmem(np, addr); -+ ret = of_get_mac_addr_nvmem(np, addr); -+ if (ret) -+ return ret; -+ -+found: -+ ret = of_add_mac_address(np, addr); -+ return ret; - } - EXPORT_SYMBOL(of_get_mac_address); - diff --git a/target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch deleted file mode 100644 index ba75e4a0f10433..00000000000000 --- a/target/linux/generic/pending-5.15/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch +++ /dev/null @@ -1,110 +0,0 @@ -From: Pablo Neira Ayuso -Date: Thu, 25 Jan 2018 12:58:55 +0100 -Subject: [PATCH] netfilter: nft_flow_offload: handle netdevice events from - nf_flow_table - -Move the code that deals with device events to the core. - -Signed-off-by: Pablo Neira Ayuso ---- - ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -651,6 +651,23 @@ static struct pernet_operations nf_flow_ - .exit_batch = nf_flow_table_pernet_exit, - }; - -+static int nf_flow_table_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ -+ if (event != NETDEV_DOWN) -+ return NOTIFY_DONE; -+ -+ nf_flow_table_cleanup(dev); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block flow_offload_netdev_notifier = { -+ .notifier_call = nf_flow_table_netdev_event, -+}; -+ - static int __init nf_flow_table_module_init(void) - { - int ret; -@@ -663,8 +680,14 @@ static int __init nf_flow_table_module_i - if (ret) - goto out_offload; - -+ ret = register_netdevice_notifier(&flow_offload_netdev_notifier); -+ if (ret) -+ goto out_offload_init; -+ - return 0; - -+out_offload_init: -+ nf_flow_table_offload_exit(); - out_offload: - unregister_pernet_subsys(&nf_flow_table_net_ops); - return ret; -@@ -672,6 +695,7 @@ out_offload: - - static void __exit nf_flow_table_module_exit(void) - { -+ unregister_netdevice_notifier(&flow_offload_netdev_notifier); - nf_flow_table_offload_exit(); - unregister_pernet_subsys(&nf_flow_table_net_ops); - } ---- a/net/netfilter/nft_flow_offload.c -+++ b/net/netfilter/nft_flow_offload.c -@@ -455,47 +455,14 @@ static struct nft_expr_type nft_flow_off - .owner = THIS_MODULE, - }; - --static int flow_offload_netdev_event(struct notifier_block *this, -- unsigned long event, void *ptr) --{ -- struct net_device *dev = netdev_notifier_info_to_dev(ptr); -- -- if (event != NETDEV_DOWN) -- return NOTIFY_DONE; -- -- nf_flow_table_cleanup(dev); -- -- return NOTIFY_DONE; --} -- --static struct notifier_block flow_offload_netdev_notifier = { -- .notifier_call = flow_offload_netdev_event, --}; -- - static int __init nft_flow_offload_module_init(void) - { -- int err; -- -- err = register_netdevice_notifier(&flow_offload_netdev_notifier); -- if (err) -- goto err; -- -- err = nft_register_expr(&nft_flow_offload_type); -- if (err < 0) -- goto register_expr; -- -- return 0; -- --register_expr: -- unregister_netdevice_notifier(&flow_offload_netdev_notifier); --err: -- return err; -+ return nft_register_expr(&nft_flow_offload_type); - } - - static void __exit nft_flow_offload_module_exit(void) - { - nft_unregister_expr(&nft_flow_offload_type); -- unregister_netdevice_notifier(&flow_offload_netdev_notifier); - } - - module_init(nft_flow_offload_module_init); diff --git a/target/linux/generic/pending-5.15/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-5.15/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch deleted file mode 100644 index 3037a724bff767..00000000000000 --- a/target/linux/generic/pending-5.15/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Felix Fietkau -Date: Thu, 31 Aug 2023 21:48:38 +0200 -Subject: [PATCH] netfilter: nf_tables: ignore -EOPNOTSUPP on flowtable device - offload setup - -On many embedded devices, it is common to configure flowtable offloading for -a mix of different devices, some of which have hardware offload support and -some of which don't. -The current code limits the ability of user space to properly set up such a -configuration by only allowing adding devices with hardware offload support to -a offload-enabled flowtable. -Given that offload-enabled flowtables also imply fallback to pure software -offloading, this limitation makes little sense. -Fix it by not bailing out when the offload setup returns -EOPNOTSUPP - -Signed-off-by: Felix Fietkau ---- - ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -7811,7 +7811,7 @@ static int nft_register_flowtable_net_ho - err = flowtable->data.type->setup(&flowtable->data, - hook->ops.dev, - FLOW_BLOCK_BIND); -- if (err < 0) -+ if (err < 0 && err != -EOPNOTSUPP) - goto err_unregister_net_hooks; - - err = nf_register_net_hook(net, &hook->ops); diff --git a/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch b/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch deleted file mode 100644 index 67cff4d22bac1b..00000000000000 --- a/target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Felix Fietkau -Date: Mon, 21 Mar 2022 20:39:59 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: enable threaded NAPI - -This can improve performance under load by ensuring that NAPI processing is -not pinned on CPU 0. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3099,8 +3099,8 @@ static irqreturn_t mtk_handle_irq_rx(int - - eth->rx_events++; - if (likely(napi_schedule_prep(ð->rx_napi))) { -- __napi_schedule(ð->rx_napi); - mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); -+ __napi_schedule(ð->rx_napi); - } - - return IRQ_HANDLED; -@@ -3112,8 +3112,8 @@ static irqreturn_t mtk_handle_irq_tx(int - - eth->tx_events++; - if (likely(napi_schedule_prep(ð->tx_napi))) { -- __napi_schedule(ð->tx_napi); - mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); -+ __napi_schedule(ð->tx_napi); - } - - return IRQ_HANDLED; -@@ -4887,6 +4887,8 @@ static int mtk_probe(struct platform_dev - * for NAPI to work - */ - init_dummy_netdev(ð->dummy_dev); -+ eth->dummy_dev.threaded = 1; -+ strcpy(eth->dummy_dev.name, "mtk_eth"); - netif_napi_add(ð->dummy_dev, ð->tx_napi, mtk_napi_tx, - NAPI_POLL_WEIGHT); - netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx, diff --git a/target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch deleted file mode 100644 index f93dca68141b6f..00000000000000 --- a/target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Gabor Juhos -Subject: generic: add detach callback to struct phy_driver - -lede-commit: fe61fc2d7d0b3fb348b502f68f98243b3ddf5867 - -Signed-off-by: Gabor Juhos ---- - drivers/net/phy/phy_device.c | 3 +++ - include/linux/phy.h | 6 ++++++ - 2 files changed, 9 insertions(+) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -1751,6 +1751,9 @@ void phy_detach(struct phy_device *phyde - struct module *ndev_owner = NULL; - struct mii_bus *bus; - -+ if (phydev->drv && phydev->drv->detach) -+ phydev->drv->detach(phydev); -+ - if (phydev->sysfs_links) { - if (dev) - sysfs_remove_link(&dev->dev.kobj, "phydev"); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -868,6 +868,12 @@ struct phy_driver { - /** @handle_interrupt: Override default interrupt handling */ - irqreturn_t (*handle_interrupt)(struct phy_device *phydev); - -+ /* -+ * Called before an ethernet device is detached -+ * from the PHY. -+ */ -+ void (*detach)(struct phy_device *phydev); -+ - /** @remove: Clears up any memory if needed */ - void (*remove)(struct phy_device *phydev); - diff --git a/target/linux/generic/pending-5.15/704-01-v6.4-net-mvneta-fix-transmit-path-dma-unmapping-on-error.patch b/target/linux/generic/pending-5.15/704-01-v6.4-net-mvneta-fix-transmit-path-dma-unmapping-on-error.patch deleted file mode 100644 index 287728ba1df5f7..00000000000000 --- a/target/linux/generic/pending-5.15/704-01-v6.4-net-mvneta-fix-transmit-path-dma-unmapping-on-error.patch +++ /dev/null @@ -1,111 +0,0 @@ -From d6d80269cf5c79f9dfe7d69f8b41a72015c89748 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 3 Apr 2023 19:30:20 +0100 -Subject: [PATCH 1/5] net: mvneta: fix transmit path dma-unmapping on error - -The transmit code assumes that the transmit descriptors that are used -begin with the first descriptor in the ring, but this may not be the -case. Fix this by providing a new function that dma-unmaps a range of -numbered descriptor entries, and use that to do the unmapping. - -Signed-off-by: Russell King (Oracle) ---- - drivers/net/ethernet/marvell/mvneta.c | 53 +++++++++++++++++---------- - 1 file changed, 33 insertions(+), 20 deletions(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -2647,14 +2647,40 @@ mvneta_tso_put_data(struct net_device *d - return 0; - } - -+static void mvneta_release_descs(struct mvneta_port *pp, -+ struct mvneta_tx_queue *txq, -+ int first, int num) -+{ -+ int desc_idx, i; -+ -+ desc_idx = first + num; -+ if (desc_idx >= txq->size) -+ desc_idx -= txq->size; -+ -+ for (i = num; i >= 0; i--) { -+ struct mvneta_tx_desc *tx_desc = txq->descs + desc_idx; -+ -+ if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr)) -+ dma_unmap_single(pp->dev->dev.parent, -+ tx_desc->buf_phys_addr, -+ tx_desc->data_size, -+ DMA_TO_DEVICE); -+ -+ mvneta_txq_desc_put(txq); -+ -+ if (desc_idx == 0) -+ desc_idx = txq->size; -+ desc_idx -= 1; -+ } -+} -+ - static int mvneta_tx_tso(struct sk_buff *skb, struct net_device *dev, - struct mvneta_tx_queue *txq) - { - int hdr_len, total_len, data_left; -- int desc_count = 0; -+ int first_desc, desc_count = 0; - struct mvneta_port *pp = netdev_priv(dev); - struct tso_t tso; -- int i; - - /* Count needed descriptors */ - if ((txq->count + tso_count_descs(skb)) >= txq->size) -@@ -2665,6 +2691,8 @@ static int mvneta_tx_tso(struct sk_buff - return 0; - } - -+ first_desc = txq->txq_put_index; -+ - /* Initialize the TSO handler, and prepare the first payload */ - hdr_len = tso_start(skb, &tso); - -@@ -2705,15 +2733,7 @@ err_release: - /* Release all used data descriptors; header descriptors must not - * be DMA-unmapped. - */ -- for (i = desc_count - 1; i >= 0; i--) { -- struct mvneta_tx_desc *tx_desc = txq->descs + i; -- if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr)) -- dma_unmap_single(pp->dev->dev.parent, -- tx_desc->buf_phys_addr, -- tx_desc->data_size, -- DMA_TO_DEVICE); -- mvneta_txq_desc_put(txq); -- } -+ mvneta_release_descs(pp, txq, first_desc, desc_count - 1); - return 0; - } - -@@ -2723,6 +2743,7 @@ static int mvneta_tx_frag_process(struct - { - struct mvneta_tx_desc *tx_desc; - int i, nr_frags = skb_shinfo(skb)->nr_frags; -+ int first_desc = txq->txq_put_index; - - for (i = 0; i < nr_frags; i++) { - struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index]; -@@ -2761,15 +2782,7 @@ error: - /* Release all descriptors that were used to map fragments of - * this packet, as well as the corresponding DMA mappings - */ -- for (i = i - 1; i >= 0; i--) { -- tx_desc = txq->descs + i; -- dma_unmap_single(pp->dev->dev.parent, -- tx_desc->buf_phys_addr, -- tx_desc->data_size, -- DMA_TO_DEVICE); -- mvneta_txq_desc_put(txq); -- } -- -+ mvneta_release_descs(pp, txq, first_desc, i - 1); - return -ENOMEM; - } - diff --git a/target/linux/generic/pending-5.15/704-02-v6.4-net-mvneta-mark-mapped-and-tso-buffers-separately.patch b/target/linux/generic/pending-5.15/704-02-v6.4-net-mvneta-mark-mapped-and-tso-buffers-separately.patch deleted file mode 100644 index 4db3ffe4e149d4..00000000000000 --- a/target/linux/generic/pending-5.15/704-02-v6.4-net-mvneta-mark-mapped-and-tso-buffers-separately.patch +++ /dev/null @@ -1,42 +0,0 @@ -From e3c77d0a1b635d114c147fd2078afb57ed558b81 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 3 Apr 2023 19:30:25 +0100 -Subject: [PATCH 2/5] net: mvneta: mark mapped and tso buffers separately - -Mark dma-mapped skbs and TSO buffers separately, so we can use -buf->type to identify their differences. - -Signed-off-by: Russell King (Oracle) ---- - drivers/net/ethernet/marvell/mvneta.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -607,6 +607,7 @@ struct mvneta_rx_desc { - #endif - - enum mvneta_tx_buf_type { -+ MVNETA_TYPE_TSO, - MVNETA_TYPE_SKB, - MVNETA_TYPE_XDP_TX, - MVNETA_TYPE_XDP_NDO, -@@ -1852,7 +1853,8 @@ static void mvneta_txq_bufs_free(struct - dma_unmap_single(pp->dev->dev.parent, - tx_desc->buf_phys_addr, - tx_desc->data_size, DMA_TO_DEVICE); -- if (buf->type == MVNETA_TYPE_SKB && buf->skb) { -+ if ((buf->type == MVNETA_TYPE_TSO || -+ buf->type == MVNETA_TYPE_SKB) && buf->skb) { - bytes_compl += buf->skb->len; - pkts_compl++; - dev_kfree_skb_any(buf->skb); -@@ -2607,7 +2609,7 @@ mvneta_tso_put_hdr(struct sk_buff *skb, - tx_desc->command |= MVNETA_TXD_F_DESC; - tx_desc->buf_phys_addr = txq->tso_hdrs_phys + - txq->txq_put_index * TSO_HEADER_SIZE; -- buf->type = MVNETA_TYPE_SKB; -+ buf->type = MVNETA_TYPE_TSO; - buf->skb = NULL; - - mvneta_txq_inc_put(txq); diff --git a/target/linux/generic/pending-5.15/704-03-v6.4-net-mvneta-use-buf-type-to-determine-whether-to-dma-.patch b/target/linux/generic/pending-5.15/704-03-v6.4-net-mvneta-use-buf-type-to-determine-whether-to-dma-.patch deleted file mode 100644 index 37511ff1dd75e4..00000000000000 --- a/target/linux/generic/pending-5.15/704-03-v6.4-net-mvneta-use-buf-type-to-determine-whether-to-dma-.patch +++ /dev/null @@ -1,59 +0,0 @@ -From fe2abc1abc0dfc6c13fe8f189216f00dbbb33044 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 3 Apr 2023 19:30:30 +0100 -Subject: [PATCH 3/5] net: mvneta: use buf->type to determine whether to - dma-unmap - -Now that we use a different buffer type for TSO headers, we can use -buf->type to determine whether the original buffer was DMA-mapped or -not. The rules are: - - MVNETA_TYPE_XDP_TX - from a DMA pool, no unmap is required - MVNETA_TYPE_XDP_NDO - dma_map_single()'d - MVNETA_TYPE_SKB - normal skbuff, dma_map_single()'d - MVNETA_TYPE_TSO - from the TSO buffer area - -This means we only need to call dma_unmap_single() on the XDP_NDO and -SKB types of buffer, and we no longer need the private IS_TSO_HEADER() -which relies on the TSO region being contiguously allocated. - -Signed-off-by: Russell King (Oracle) ---- - drivers/net/ethernet/marvell/mvneta.c | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -334,10 +334,6 @@ - MVNETA_SKB_HEADROOM)) - #define MVNETA_MAX_RX_BUF_SIZE (PAGE_SIZE - MVNETA_SKB_PAD) - --#define IS_TSO_HEADER(txq, addr) \ -- ((addr >= txq->tso_hdrs_phys) && \ -- (addr < txq->tso_hdrs_phys + txq->size * TSO_HEADER_SIZE)) -- - #define MVNETA_RX_GET_BM_POOL_ID(rxd) \ - (((rxd)->status & MVNETA_RXD_BM_POOL_MASK) >> MVNETA_RXD_BM_POOL_SHIFT) - -@@ -1848,8 +1844,8 @@ static void mvneta_txq_bufs_free(struct - - mvneta_txq_inc_get(txq); - -- if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr) && -- buf->type != MVNETA_TYPE_XDP_TX) -+ if (buf->type == MVNETA_TYPE_XDP_NDO || -+ buf->type == MVNETA_TYPE_SKB) - dma_unmap_single(pp->dev->dev.parent, - tx_desc->buf_phys_addr, - tx_desc->data_size, DMA_TO_DEVICE); -@@ -2661,8 +2657,9 @@ static void mvneta_release_descs(struct - - for (i = num; i >= 0; i--) { - struct mvneta_tx_desc *tx_desc = txq->descs + desc_idx; -+ struct mvneta_tx_buf *buf = &txq->buf[desc_idx]; - -- if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr)) -+ if (buf->type == MVNETA_TYPE_SKB) - dma_unmap_single(pp->dev->dev.parent, - tx_desc->buf_phys_addr, - tx_desc->data_size, diff --git a/target/linux/generic/pending-5.15/704-04-v6.4-net-mvneta-move-tso_build_hdr-into-mvneta_tso_put_hd.patch b/target/linux/generic/pending-5.15/704-04-v6.4-net-mvneta-move-tso_build_hdr-into-mvneta_tso_put_hd.patch deleted file mode 100644 index 444b60f15166d0..00000000000000 --- a/target/linux/generic/pending-5.15/704-04-v6.4-net-mvneta-move-tso_build_hdr-into-mvneta_tso_put_hd.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 210ca75d4949f1ace8ea53a75148806cc28224a0 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 3 Apr 2023 19:30:35 +0100 -Subject: [PATCH 4/5] net: mvneta: move tso_build_hdr() into - mvneta_tso_put_hdr() - -Move tso_build_hdr() into mvneta_tso_put_hdr() so that all the TSO -header building code is in one place. - -Signed-off-by: Russell King (Oracle) ---- - drivers/net/ethernet/marvell/mvneta.c | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -2592,19 +2592,24 @@ err_drop_frame: - return rx_done; - } - --static inline void --mvneta_tso_put_hdr(struct sk_buff *skb, struct mvneta_tx_queue *txq) -+static void mvneta_tso_put_hdr(struct sk_buff *skb, struct mvneta_tx_queue *txq, -+ struct tso_t *tso, int size, bool is_last) - { -- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); -+ int tso_offset, hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); - struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index]; - struct mvneta_tx_desc *tx_desc; -+ char *hdr; -+ -+ tso_offset = txq->txq_put_index * TSO_HEADER_SIZE; -+ -+ hdr = txq->tso_hdrs + tso_offset; -+ tso_build_hdr(skb, hdr, tso, size, is_last); - - tx_desc = mvneta_txq_next_desc_get(txq); - tx_desc->data_size = hdr_len; - tx_desc->command = mvneta_skb_tx_csum(skb); - tx_desc->command |= MVNETA_TXD_F_DESC; -- tx_desc->buf_phys_addr = txq->tso_hdrs_phys + -- txq->txq_put_index * TSO_HEADER_SIZE; -+ tx_desc->buf_phys_addr = txq->tso_hdrs_phys + tso_offset; - buf->type = MVNETA_TYPE_TSO; - buf->skb = NULL; - -@@ -2697,17 +2702,12 @@ static int mvneta_tx_tso(struct sk_buff - - total_len = skb->len - hdr_len; - while (total_len > 0) { -- char *hdr; -- - data_left = min_t(int, skb_shinfo(skb)->gso_size, total_len); - total_len -= data_left; - desc_count++; - - /* prepare packet headers: MAC + IP + TCP */ -- hdr = txq->tso_hdrs + txq->txq_put_index * TSO_HEADER_SIZE; -- tso_build_hdr(skb, hdr, &tso, data_left, total_len == 0); -- -- mvneta_tso_put_hdr(skb, txq); -+ mvneta_tso_put_hdr(skb, txq, &tso, data_left, total_len == 0); - - while (data_left > 0) { - int size; diff --git a/target/linux/generic/pending-5.15/704-05-v6.4-net-mvneta-allocate-TSO-header-DMA-memory-in-chunks.patch b/target/linux/generic/pending-5.15/704-05-v6.4-net-mvneta-allocate-TSO-header-DMA-memory-in-chunks.patch deleted file mode 100644 index 395a0bf5d2b8d4..00000000000000 --- a/target/linux/generic/pending-5.15/704-05-v6.4-net-mvneta-allocate-TSO-header-DMA-memory-in-chunks.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 58d50fb089da553023df5a05f5ae86feaacc7f24 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 3 Apr 2023 19:30:40 +0100 -Subject: [PATCH 5/5] net: mvneta: allocate TSO header DMA memory in chunks - -Now that we no longer need to check whether the DMA address is within -the TSO header DMA memory range for the queue, we can allocate the TSO -header DMA memory in chunks rather than one contiguous order-6 chunk, -which can stress the kernel's memory subsystems to allocate. - -Instead, use order-1 (8k) allocations, which will result in 32 order-1 -pages containing 32 TSO headers. - -Signed-off-by: Russell King (Oracle) ---- - drivers/net/ethernet/marvell/mvneta.c | 88 +++++++++++++++++++++------ - 1 file changed, 70 insertions(+), 18 deletions(-) - ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -314,6 +314,15 @@ - - #define MVNETA_MAX_SKB_DESCS (MVNETA_MAX_TSO_SEGS * 2 + MAX_SKB_FRAGS) - -+/* The size of a TSO header page */ -+#define MVNETA_TSO_PAGE_SIZE (2 * PAGE_SIZE) -+ -+/* Number of TSO headers per page. This should be a power of 2 */ -+#define MVNETA_TSO_PER_PAGE (MVNETA_TSO_PAGE_SIZE / TSO_HEADER_SIZE) -+ -+/* Maximum number of TSO header pages */ -+#define MVNETA_MAX_TSO_PAGES (MVNETA_MAX_TXD / MVNETA_TSO_PER_PAGE) -+ - /* descriptor aligned size */ - #define MVNETA_DESC_ALIGNED_SIZE 32 - -@@ -656,10 +665,10 @@ struct mvneta_tx_queue { - int next_desc_to_proc; - - /* DMA buffers for TSO headers */ -- char *tso_hdrs; -+ char *tso_hdrs[MVNETA_MAX_TSO_PAGES]; - - /* DMA address of TSO headers */ -- dma_addr_t tso_hdrs_phys; -+ dma_addr_t tso_hdrs_phys[MVNETA_MAX_TSO_PAGES]; - - /* Affinity mask for CPUs*/ - cpumask_t affinity_mask; -@@ -2592,24 +2601,71 @@ err_drop_frame: - return rx_done; - } - -+static void mvneta_free_tso_hdrs(struct mvneta_port *pp, -+ struct mvneta_tx_queue *txq) -+{ -+ struct device *dev = pp->dev->dev.parent; -+ int i; -+ -+ for (i = 0; i < MVNETA_MAX_TSO_PAGES; i++) { -+ if (txq->tso_hdrs[i]) { -+ dma_free_coherent(dev, MVNETA_TSO_PAGE_SIZE, -+ txq->tso_hdrs[i], -+ txq->tso_hdrs_phys[i]); -+ txq->tso_hdrs[i] = NULL; -+ } -+ } -+} -+ -+static int mvneta_alloc_tso_hdrs(struct mvneta_port *pp, -+ struct mvneta_tx_queue *txq) -+{ -+ struct device *dev = pp->dev->dev.parent; -+ int i, num; -+ -+ num = DIV_ROUND_UP(txq->size, MVNETA_TSO_PER_PAGE); -+ for (i = 0; i < num; i++) { -+ txq->tso_hdrs[i] = dma_alloc_coherent(dev, MVNETA_TSO_PAGE_SIZE, -+ &txq->tso_hdrs_phys[i], -+ GFP_KERNEL); -+ if (!txq->tso_hdrs[i]) { -+ mvneta_free_tso_hdrs(pp, txq); -+ return -ENOMEM; -+ } -+ } -+ -+ return 0; -+} -+ -+static char *mvneta_get_tso_hdr(struct mvneta_tx_queue *txq, dma_addr_t *dma) -+{ -+ int index, offset; -+ -+ index = txq->txq_put_index / MVNETA_TSO_PER_PAGE; -+ offset = (txq->txq_put_index % MVNETA_TSO_PER_PAGE) * TSO_HEADER_SIZE; -+ -+ *dma = txq->tso_hdrs_phys[index] + offset; -+ -+ return txq->tso_hdrs[index] + offset; -+} -+ - static void mvneta_tso_put_hdr(struct sk_buff *skb, struct mvneta_tx_queue *txq, - struct tso_t *tso, int size, bool is_last) - { -- int tso_offset, hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); -+ int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); - struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index]; - struct mvneta_tx_desc *tx_desc; -+ dma_addr_t hdr_phys; - char *hdr; - -- tso_offset = txq->txq_put_index * TSO_HEADER_SIZE; -- -- hdr = txq->tso_hdrs + tso_offset; -+ hdr = mvneta_get_tso_hdr(txq, &hdr_phys); - tso_build_hdr(skb, hdr, tso, size, is_last); - - tx_desc = mvneta_txq_next_desc_get(txq); - tx_desc->data_size = hdr_len; - tx_desc->command = mvneta_skb_tx_csum(skb); - tx_desc->command |= MVNETA_TXD_F_DESC; -- tx_desc->buf_phys_addr = txq->tso_hdrs_phys + tso_offset; -+ tx_desc->buf_phys_addr = hdr_phys; - buf->type = MVNETA_TYPE_TSO; - buf->skb = NULL; - -@@ -3401,7 +3457,7 @@ static void mvneta_rxq_deinit(struct mvn - static int mvneta_txq_sw_init(struct mvneta_port *pp, - struct mvneta_tx_queue *txq) - { -- int cpu; -+ int cpu, err; - - txq->size = pp->tx_ring_size; - -@@ -3426,11 +3482,9 @@ static int mvneta_txq_sw_init(struct mvn - return -ENOMEM; - - /* Allocate DMA buffers for TSO MAC/IP/TCP headers */ -- txq->tso_hdrs = dma_alloc_coherent(pp->dev->dev.parent, -- txq->size * TSO_HEADER_SIZE, -- &txq->tso_hdrs_phys, GFP_KERNEL); -- if (!txq->tso_hdrs) -- return -ENOMEM; -+ err = mvneta_alloc_tso_hdrs(pp, txq); -+ if (err) -+ return err; - - /* Setup XPS mapping */ - if (pp->neta_armada3700) -@@ -3482,10 +3536,7 @@ static void mvneta_txq_sw_deinit(struct - - kfree(txq->buf); - -- if (txq->tso_hdrs) -- dma_free_coherent(pp->dev->dev.parent, -- txq->size * TSO_HEADER_SIZE, -- txq->tso_hdrs, txq->tso_hdrs_phys); -+ mvneta_free_tso_hdrs(pp, txq); - if (txq->descs) - dma_free_coherent(pp->dev->dev.parent, - txq->size * MVNETA_DESC_ALIGNED_SIZE, -@@ -3494,7 +3545,6 @@ static void mvneta_txq_sw_deinit(struct - netdev_tx_reset_queue(nq); - - txq->buf = NULL; -- txq->tso_hdrs = NULL; - txq->descs = NULL; - txq->last_desc = 0; - txq->next_desc_to_proc = 0; -@@ -5543,6 +5593,8 @@ static int __init mvneta_driver_init(voi - { - int ret; - -+ BUILD_BUG_ON_NOT_POWER_OF_2(MVNETA_TSO_PER_PAGE); -+ - ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "net/mvneta:online", - mvneta_cpu_online, - mvneta_cpu_down_prepare); diff --git a/target/linux/generic/pending-5.15/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch b/target/linux/generic/pending-5.15/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch deleted file mode 100644 index d444b2027cb462..00000000000000 --- a/target/linux/generic/pending-5.15/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Felix Fietkau -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 ---- - ---- a/net/dsa/tag_mtk.c -+++ b/net/dsa/tag_mtk.c -@@ -27,6 +27,13 @@ static struct sk_buff *mtk_tag_xmit(stru - - skb_set_queue_mapping(skb, dp->index); - -+ /* 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). -+ */ -+ eth_skb_pad(skb); -+ - /* 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 diff --git a/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch deleted file mode 100644 index fd1b79cdfe4f3f..00000000000000 --- a/target/linux/generic/pending-5.15/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch +++ /dev/null @@ -1,174 +0,0 @@ -From: Felix Fietkau -Date: Fri, 27 Aug 2021 12:22:32 +0200 -Subject: [PATCH] bridge: add knob for filtering rx/tx BPDU packets on a port - -Some devices (e.g. wireless APs) can't have devices behind them be part of -a bridge topology with redundant links, due to address limitations. -Additionally, broadcast traffic on these devices is somewhat expensive, due to -the low data rate and wakeups of clients in powersave mode. -This knob can be used to ensure that BPDU packets are never sent or forwarded -to/from these devices - -Signed-off-by: Felix Fietkau ---- - ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -58,6 +58,7 @@ struct br_ip_list { - #define BR_MRP_LOST_CONT BIT(18) - #define BR_MRP_LOST_IN_CONT BIT(19) - #define BR_TX_FWD_OFFLOAD BIT(20) -+#define BR_BPDU_FILTER BIT(21) - - #define BR_DEFAULT_AGEING_TIME (300 * HZ) - ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -199,6 +199,7 @@ out: - void br_flood(struct net_bridge *br, struct sk_buff *skb, - enum br_pkt_type pkt_type, bool local_rcv, bool local_orig) - { -+ const unsigned char *dest = eth_hdr(skb)->h_dest; - struct net_bridge_port *prev = NULL; - struct net_bridge_port *p; - -@@ -214,6 +215,10 @@ void br_flood(struct net_bridge *br, str - case BR_PKT_MULTICAST: - if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev) - continue; -+ if ((p->flags & BR_BPDU_FILTER) && -+ unlikely(is_link_local_ether_addr(dest) && -+ dest[5] == 0)) -+ continue; - break; - case BR_PKT_BROADCAST: - if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev) ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -331,6 +331,8 @@ static rx_handler_result_t br_handle_fra - fwd_mask |= p->group_fwd_mask; - switch (dest[5]) { - case 0x00: /* Bridge Group Address */ -+ if (p->flags & BR_BPDU_FILTER) -+ goto drop; - /* If STP is turned off, - then must forward to keep loop detection */ - if (p->br->stp_enabled == BR_NO_STP || ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -240,6 +240,7 @@ BRPORT_ATTR_FLAG(multicast_flood, BR_MCA - BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD); - BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); - BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); -+BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER); - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) -@@ -292,6 +293,7 @@ static const struct brport_attribute *br - &brport_attr_group_fwd_mask, - &brport_attr_neigh_suppress, - &brport_attr_isolated, -+ &brport_attr_bpdu_filter, - &brport_attr_backup_port, - NULL - }; ---- a/net/bridge/br_stp_bpdu.c -+++ b/net/bridge/br_stp_bpdu.c -@@ -80,7 +80,8 @@ void br_send_config_bpdu(struct net_brid - { - unsigned char buf[35]; - -- if (p->br->stp_enabled != BR_KERNEL_STP) -+ if (p->br->stp_enabled != BR_KERNEL_STP || -+ (p->flags & BR_BPDU_FILTER)) - return; - - buf[0] = 0; -@@ -127,7 +128,8 @@ void br_send_tcn_bpdu(struct net_bridge_ - { - unsigned char buf[4]; - -- if (p->br->stp_enabled != BR_KERNEL_STP) -+ if (p->br->stp_enabled != BR_KERNEL_STP || -+ (p->flags & BR_BPDU_FILTER)) - return; - - buf[0] = 0; -@@ -172,6 +174,9 @@ void br_stp_rcv(const struct stp_proto * - if (!(br->dev->flags & IFF_UP)) - goto out; - -+ if (p->flags & BR_BPDU_FILTER) -+ goto out; -+ - if (p->state == BR_STATE_DISABLED) - goto out; - ---- a/include/uapi/linux/if_link.h -+++ b/include/uapi/linux/if_link.h -@@ -536,6 +536,7 @@ enum { - IFLA_BRPORT_MRP_IN_OPEN, - IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT, - IFLA_BRPORT_MCAST_EHT_HOSTS_CNT, -+ IFLA_BRPORT_BPDU_FILTER, - __IFLA_BRPORT_MAX - }; - #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -184,6 +184,7 @@ static inline size_t br_port_info_size(v - + nla_total_size(1) /* IFLA_BRPORT_VLAN_TUNNEL */ - + nla_total_size(1) /* IFLA_BRPORT_NEIGH_SUPPRESS */ - + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */ -+ + nla_total_size(1) /* IFLA_BRPORT_BPDU_FILTER */ - + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */ - + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */ - + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */ -@@ -269,7 +270,8 @@ static int br_port_fill_attrs(struct sk_ - BR_MRP_LOST_CONT)) || - nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN, - !!(p->flags & BR_MRP_LOST_IN_CONT)) || -- nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED))) -+ nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) || -+ nla_put_u8(skb, IFLA_BRPORT_BPDU_FILTER, !!(p->flags & BR_BPDU_FILTER))) - return -EMSGSIZE; - - timerval = br_timer_value(&p->message_age_timer); -@@ -829,6 +831,7 @@ static const struct nla_policy br_port_p - [IFLA_BRPORT_ISOLATED] = { .type = NLA_U8 }, - [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 }, - [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 }, -+ [IFLA_BRPORT_BPDU_FILTER] = { .type = NLA_U8 }, - }; - - /* Change the state of the port and notify spanning tree */ -@@ -893,6 +896,7 @@ static int br_setport(struct net_bridge_ - br_set_port_flag(p, tb, IFLA_BRPORT_VLAN_TUNNEL, BR_VLAN_TUNNEL); - br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS, BR_NEIGH_SUPPRESS); - br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED); -+ br_set_port_flag(p, tb, IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER); - - changed_mask = old_flags ^ p->flags; - ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -55,7 +55,7 @@ - #include - - #define RTNL_MAX_TYPE 50 --#define RTNL_SLAVE_MAX_TYPE 40 -+#define RTNL_SLAVE_MAX_TYPE 41 - - struct rtnl_link { - rtnl_doit_func doit; -@@ -4739,7 +4739,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu - brport_nla_put_flag(skb, flags, mask, - IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) || - brport_nla_put_flag(skb, flags, mask, -- IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD)) { -+ IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD) || -+ brport_nla_put_flag(skb, flags, mask, -+ IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER)) { - nla_nest_cancel(skb, protinfo); - goto nla_put_failure; - } diff --git a/target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch b/target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch deleted file mode 100644 index c93fe42273ea60..00000000000000 --- a/target/linux/generic/pending-5.15/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch +++ /dev/null @@ -1,106 +0,0 @@ -From ace6abaa0f9203083fe4c0a6a74da2d96410b625 Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Sat, 13 Aug 2022 12:49:33 +0200 -Subject: [PATCH 01/10] net: phy: realtek: rtl8221: allow to configure SERDES - mode - -The rtl8221 supports multiple SERDES modes: -- SGMII -- 2500base-x -- HiSGMII - -Further it supports rate adaption on SERDES links to allow -slow ethernet speeds (10/100/1000mbit) to work on 2500base-x/HiSGMII -links without reducing the SERDES speed. - -When operating without rate adapters the SERDES link will follow the -ethernet speed. - -Signed-off-by: Alexander Couzens ---- - drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 48 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -53,6 +53,15 @@ - RTL8201F_ISR_LINK) - #define RTL8201F_IER 0x13 - -+#define RTL8221B_MMD_SERDES_CTRL MDIO_MMD_VEND1 -+#define RTL8221B_MMD_PHY_CTRL MDIO_MMD_VEND2 -+#define RTL8221B_SERDES_OPTION 0x697a -+#define RTL8221B_SERDES_OPTION_MODE_MASK GENMASK(5, 0) -+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII 0 -+#define RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII 1 -+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2 -+#define RTL8221B_SERDES_OPTION_MODE_HISGMII 3 -+ - #define RTL8366RB_POWER_SAVE 0x15 - #define RTL8366RB_POWER_SAVE_ON BIT(12) - -@@ -841,6 +850,48 @@ static irqreturn_t rtl9000a_handle_inter - return IRQ_HANDLED; - } - -+static int rtl8221b_config_init(struct phy_device *phydev) -+{ -+ u16 option_mode; -+ -+ switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_2500BASEX: -+ if (!phydev->is_c45) { -+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX; -+ break; -+ } -+ fallthrough; -+ case PHY_INTERFACE_MODE_SGMII: -+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII; -+ break; -+ default: -+ return 0; -+ } -+ -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, -+ 0x75f3, 0); -+ -+ phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL, -+ RTL8221B_SERDES_OPTION, -+ RTL8221B_SERDES_OPTION_MODE_MASK, option_mode); -+ switch (option_mode) { -+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII: -+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX: -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020); -+ break; -+ case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII: -+ case RTL8221B_SERDES_OPTION_MODE_HISGMII: -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020); -+ break; -+ } -+ -+ return 0; -+} -+ - static struct phy_driver realtek_drvs[] = { - { - PHY_ID_MATCH_EXACT(0x00008201), -@@ -981,6 +1032,7 @@ static struct phy_driver realtek_drvs[] - PHY_ID_MATCH_EXACT(0x001cc849), - .name = "RTL8221B-VB-CG 2.5Gbps PHY", - .get_features = rtl822x_get_features, -+ .config_init = rtl8221b_config_init, - .config_aneg = rtl822x_config_aneg, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, -@@ -992,6 +1044,7 @@ static struct phy_driver realtek_drvs[] - .name = "RTL8221B-VM-CG 2.5Gbps PHY", - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, -+ .config_init = rtl8221b_config_init, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, diff --git a/target/linux/generic/pending-5.15/722-net-phy-realtek-support-switching-between-SGMII-and-.patch b/target/linux/generic/pending-5.15/722-net-phy-realtek-support-switching-between-SGMII-and-.patch deleted file mode 100644 index 211a8ed297f86f..00000000000000 --- a/target/linux/generic/pending-5.15/722-net-phy-realtek-support-switching-between-SGMII-and-.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 312753d0aadba0f58841ae513b80fdbabc887523 Mon Sep 17 00:00:00 2001 -From: Chukun Pan -Date: Wed, 8 Feb 2023 16:32:18 +0800 -Subject: [PATCH] net: phy: realtek: support switching between SGMII and - 2500BASE-X for RTL822x series - -After commit ace6aba ("net: phy: realtek: rtl8221: allow to configure -SERDES mode"), the rtl8221 phy can work in SGMII and 2500base-x modes -respectively. So add interface automatic switching for rtl8221 phy to -match various wire speeds. - -Signed-off-by: Chukun Pan ---- - drivers/net/phy/realtek.c | 26 ++++++++++++++++++++++++-- - 1 file changed, 24 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -676,6 +676,25 @@ static int rtl822x_config_aneg(struct ph - return __genphy_config_aneg(phydev, ret); - } - -+static void rtl822x_update_interface(struct phy_device *phydev) -+{ -+ /* Automatically switch SERDES interface between -+ * SGMII and 2500-BaseX according to speed. -+ */ -+ switch (phydev->speed) { -+ case SPEED_2500: -+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -+ break; -+ case SPEED_1000: -+ case SPEED_100: -+ case SPEED_10: -+ phydev->interface = PHY_INTERFACE_MODE_SGMII; -+ break; -+ default: -+ break; -+ } -+} -+ - static int rtl822x_read_status(struct phy_device *phydev) - { - int ret; -@@ -694,11 +713,14 @@ static int rtl822x_read_status(struct ph - phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL); - } - -- ret = genphy_read_status(phydev); -+ ret = rtlgen_read_status(phydev); - if (ret < 0) - return ret; - -- return rtlgen_get_speed(phydev); -+ if (phydev->is_c45 && phydev->link) -+ rtl822x_update_interface(phydev); -+ -+ return 0; - } - - static bool rtlgen_supports_2_5gbps(struct phy_device *phydev) diff --git a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch b/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch deleted file mode 100644 index 792135b0d2d4bf..00000000000000 --- a/target/linux/generic/pending-5.15/723-net-mt7531-ensure-all-MACs-are-powered-down-before-r.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 3fb8841513c4ec3a2e5d366df86230c45f239a57 Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Sat, 13 Aug 2022 13:08:22 +0200 -Subject: [PATCH 03/10] net: mt7531: ensure all MACs are powered down before - reset - -The datasheet [1] explicit describes it as requirement for a reset. - -[1] MT7531 Reference Manual for Development Board rev 1.0, page 735 - -Signed-off-by: Alexander Couzens ---- - drivers/net/dsa/mt7530.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2680,6 +2680,10 @@ mt7531_setup(struct dsa_switch *ds) - return -ENODEV; - } - -+ /* all MACs must be forced link-down before sw reset */ -+ for (i = 0; i < MT7530_NUM_PORTS; i++) -+ mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK); -+ - /* Reset the switch through internal reset */ - mt7530_write(priv, MT7530_SYS_CTRL, - SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST | diff --git a/target/linux/generic/pending-5.15/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-5.15/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch deleted file mode 100644 index 69418183510209..00000000000000 --- a/target/linux/generic/pending-5.15/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 2 Apr 2023 23:56:16 +0100 -Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs - -Some vendor bootloaders do weird things with those PHYs which result in -link modes being reported wrongly. Start from a clean sheet by resetting -the PHY. - -Reported-by: Yevhen Kolomeiko -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -1018,6 +1018,7 @@ static struct phy_driver realtek_drvs[] - .write_page = rtl821x_write_page, - .read_mmd = rtl822x_read_mmd, - .write_mmd = rtl822x_write_mmd, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc840), - .name = "RTL8226B_RTL8221B 2.5Gbps PHY", -@@ -1030,6 +1031,7 @@ static struct phy_driver realtek_drvs[] - .write_page = rtl821x_write_page, - .read_mmd = rtl822x_read_mmd, - .write_mmd = rtl822x_write_mmd, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc838), - .name = "RTL8226-CG 2.5Gbps PHY", -@@ -1040,6 +1042,7 @@ static struct phy_driver realtek_drvs[] - .resume = rtlgen_resume, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc848), - .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY", -@@ -1050,6 +1053,7 @@ static struct phy_driver realtek_drvs[] - .resume = rtlgen_resume, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc849), - .name = "RTL8221B-VB-CG 2.5Gbps PHY", -@@ -1061,6 +1065,7 @@ static struct phy_driver realtek_drvs[] - .resume = rtlgen_resume, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc84a), - .name = "RTL8221B-VM-CG 2.5Gbps PHY", -@@ -1072,6 +1077,7 @@ static struct phy_driver realtek_drvs[] - .resume = rtlgen_resume, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc961), - .name = "RTL8366RB Gigabit Ethernet", diff --git a/target/linux/generic/pending-5.15/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-5.15/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch deleted file mode 100644 index 1370c6324bba7c..00000000000000 --- a/target/linux/generic/pending-5.15/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 2b1b8c4c215af7988136401c902338d091d408a1 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 01:21:57 +0300 -Subject: [PATCH 2/2] net: phy: realtek: disable SGMII in-band AN for 2.5G PHYs - -MAC drivers don't use SGMII in-band autonegotiation unless told to do so -in device tree using 'managed = "in-band-status"'. When using MDIO to -access a PHY, in-band-status is unneeded as we have link-status via -MDIO. Switch off SGMII in-band autonegotiation using magic values. - -Reported-by: Chen Minqiang -Reported-by: Chukun Pan -Reported-by: Yevhen Kolomeiko -Tested-by: Yevhen Kolomeiko -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -875,6 +875,7 @@ static irqreturn_t rtl9000a_handle_inter - static int rtl8221b_config_init(struct phy_device *phydev) - { - u16 option_mode; -+ int val; - - switch (phydev->interface) { - case PHY_INTERFACE_MODE_2500BASEX: -@@ -911,6 +912,13 @@ static int rtl8221b_config_init(struct p - break; - } - -+ /* Disable SGMII AN */ -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7588, 0x2); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7589, 0x71d0); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, 0x3); -+ phy_read_mmd_poll_timeout(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, -+ val, !(val & BIT(0)), 500, 100000, false); -+ - return 0; - } - diff --git a/target/linux/generic/pending-5.15/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-5.15/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch deleted file mode 100644 index 31f0622327b869..00000000000000 --- a/target/linux/generic/pending-5.15/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 22 Apr 2023 01:21:14 +0100 -Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex - -As we cannot rely on phy_read_paged function before the PHY is -identified, the paged read in rtlgen_supports_2_5gbps needs to be open -coded as it is being called by the match_phy_device function, ie. before -.read_page and .write_page have been populated. - -Make sure it is also protected by the MDIO bus mutex and use -rtl821x_write_page instead of 3 individually locked MDIO bus operations. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -727,9 +727,11 @@ static bool rtlgen_supports_2_5gbps(stru - { - int val; - -- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61); -- val = phy_read(phydev, 0x13); -- phy_write(phydev, RTL821x_PAGE_SELECT, 0); -+ mutex_lock(&phydev->mdio.bus->mdio_lock); -+ rtl821x_write_page(phydev, 0xa61); -+ val = __phy_read(phydev, 0x13); -+ rtl821x_write_page(phydev, 0); -+ mutex_unlock(&phydev->mdio.bus->mdio_lock); - - return val >= 0 && val & RTL_SUPPORTS_2500FULL; - } diff --git a/target/linux/generic/pending-5.15/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch b/target/linux/generic/pending-5.15/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch deleted file mode 100644 index a24b4dd79a1b5f..00000000000000 --- a/target/linux/generic/pending-5.15/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 22 Apr 2023 01:23:08 +0100 -Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE - advertisement - -Use existing generic inline functions to encode local advertisement -of 10GbE link modes as well as to decode link-partner advertisement. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 22 +++++----------------- - 1 file changed, 5 insertions(+), 17 deletions(-) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -68,10 +68,6 @@ - #define RTL_SUPPORTS_5000FULL BIT(14) - #define RTL_SUPPORTS_2500FULL BIT(13) - #define RTL_SUPPORTS_10000FULL BIT(0) --#define RTL_ADV_2500FULL BIT(7) --#define RTL_LPADV_10000FULL BIT(11) --#define RTL_LPADV_5000FULL BIT(6) --#define RTL_LPADV_2500FULL BIT(5) - - #define RTL9000A_GINMR 0x14 - #define RTL9000A_GINMR_LINK_STATUS BIT(4) -@@ -661,14 +657,11 @@ static int rtl822x_config_aneg(struct ph - int ret = 0; - - if (phydev->autoneg == AUTONEG_ENABLE) { -- u16 adv2500 = 0; -- -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -- phydev->advertising)) -- adv2500 = RTL_ADV_2500FULL; -- - ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12, -- RTL_ADV_2500FULL, adv2500); -+ MDIO_AN_10GBT_CTRL_ADV10G | -+ MDIO_AN_10GBT_CTRL_ADV5G | -+ MDIO_AN_10GBT_CTRL_ADV2_5G, -+ linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising)); - if (ret < 0) - return ret; - } -@@ -705,12 +698,7 @@ static int rtl822x_read_status(struct ph - if (lpadv < 0) - return lpadv; - -- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, -- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL); -- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, -- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL); -- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL); -+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv); - } - - ret = rtlgen_read_status(phydev); diff --git a/target/linux/generic/pending-5.15/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch b/target/linux/generic/pending-5.15/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch deleted file mode 100644 index 084ee4b6450204..00000000000000 --- a/target/linux/generic/pending-5.15/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 22 Apr 2023 01:25:39 +0100 -Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner - advertisement - -Only use link-partner advertisement bits for 10GbE modes if they are -actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes -unless both of them are set. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -698,6 +698,10 @@ static int rtl822x_read_status(struct ph - if (lpadv < 0) - return lpadv; - -+ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) || -+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK)) -+ lpadv = 0; -+ - mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv); - } - diff --git a/target/linux/generic/pending-5.15/729-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-5.15/729-net-phy-realtek-introduce-rtl822x_probe.patch deleted file mode 100644 index cea3511b8306f1..00000000000000 --- a/target/linux/generic/pending-5.15/729-net-phy-realtek-introduce-rtl822x_probe.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 22 Apr 2023 03:26:01 +0100 -Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x - -Setup Link Down Power Saving Mode according the DTS property -just like for RTL821x 1GE PHYs. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -62,6 +62,10 @@ - #define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2 - #define RTL8221B_SERDES_OPTION_MODE_HISGMII 3 - -+#define RTL8221B_PHYCR1 0xa430 -+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2) -+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12) -+ - #define RTL8366RB_POWER_SAVE 0x15 - #define RTL8366RB_POWER_SAVE_ON BIT(12) - -@@ -740,6 +744,25 @@ static int rtl8226_match_phy_device(stru - rtlgen_supports_2_5gbps(phydev); - } - -+static int rtl822x_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ int val; -+ -+ val = phy_read_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1); -+ if (val < 0) -+ return val; -+ -+ if (of_property_read_bool(dev->of_node, "realtek,aldps-enable")) -+ val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN; -+ else -+ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN); -+ -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1, val); -+ -+ return 0; -+} -+ - static int rtlgen_resume(struct phy_device *phydev) - { - int ret = genphy_resume(phydev); -@@ -1039,6 +1062,7 @@ static struct phy_driver realtek_drvs[] - .name = "RTL8226-CG 2.5Gbps PHY", - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, -+ .probe = rtl822x_probe, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, -@@ -1050,6 +1074,7 @@ static struct phy_driver realtek_drvs[] - .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY", - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, -+ .probe = rtl822x_probe, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, -@@ -1062,6 +1087,7 @@ static struct phy_driver realtek_drvs[] - .get_features = rtl822x_get_features, - .config_init = rtl8221b_config_init, - .config_aneg = rtl822x_config_aneg, -+ .probe = rtl822x_probe, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, -@@ -1074,6 +1100,7 @@ static struct phy_driver realtek_drvs[] - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, - .config_init = rtl8221b_config_init, -+ .probe = rtl822x_probe, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, diff --git a/target/linux/generic/pending-5.15/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-5.15/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch deleted file mode 100644 index e3edfa47c609ab..00000000000000 --- a/target/linux/generic/pending-5.15/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 30 Apr 2023 00:15:41 +0100 -Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B - -Early versions (?) of the RTL8221B PHY cannot be identified in a regular -Clause-45 bus scan as the PHY doesn't report the implemented MMDs -correctly but returns 0 instead. -Implement custom identify function using the PKGID instead of iterating -over the implemented MMDs. - -Signed-off-by: Daniel Golle - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -79,6 +79,7 @@ - #define RTLGEN_SPEED_MASK 0x0630 - - #define RTL_GENERIC_PHYID 0x001cc800 -+#define RTL_8221B_VB_CG_PHYID 0x001cc849 - - MODULE_DESCRIPTION("Realtek PHY driver"); - MODULE_AUTHOR("Johnson Leung"); -@@ -744,6 +745,38 @@ static int rtl8226_match_phy_device(stru - rtlgen_supports_2_5gbps(phydev); - } - -+static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev) -+{ -+ int val; -+ u32 id; -+ -+ if (phydev->mdio.bus->probe_capabilities >= MDIOBUS_C45) { -+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1); -+ if (val < 0) -+ return 0; -+ -+ id = val << 16; -+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2); -+ if (val < 0) -+ return 0; -+ -+ id |= val; -+ } else { -+ val = phy_read(phydev, MII_PHYSID1); -+ if (val < 0) -+ return 0; -+ -+ id = val << 16; -+ val = phy_read(phydev, MII_PHYSID2); -+ if (val < 0) -+ return 0; -+ -+ id |= val; -+ } -+ -+ return (id == RTL_8221B_VB_CG_PHYID); -+} -+ - static int rtl822x_probe(struct phy_device *phydev) - { - struct device *dev = &phydev->mdio.dev; -@@ -1082,7 +1115,7 @@ static struct phy_driver realtek_drvs[] - .write_page = rtl821x_write_page, - .soft_reset = genphy_soft_reset, - }, { -- PHY_ID_MATCH_EXACT(0x001cc849), -+ .match_phy_device = rtl8221b_vb_cg_match_phy_device, - .name = "RTL8221B-VB-CG 2.5Gbps PHY", - .get_features = rtl822x_get_features, - .config_init = rtl8221b_config_init, diff --git a/target/linux/generic/pending-5.15/731-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-5.15/731-net-phy-realtek-support-interrupt-of-RTL8221B.patch deleted file mode 100644 index 07d46d8daada57..00000000000000 --- a/target/linux/generic/pending-5.15/731-net-phy-realtek-support-interrupt-of-RTL8221B.patch +++ /dev/null @@ -1,75 +0,0 @@ -From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001 -From: Jianhui Zhao -Date: Sun, 24 Sep 2023 22:15:00 +0800 -Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B - -This commit introduces interrupt support for RTL8221B. - -Signed-off-by: Jianhui Zhao ---- - drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 47 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -972,6 +972,51 @@ static int rtl8221b_config_init(struct p - return 0; - } - -+static int rtl8221b_ack_interrupt(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = phy_read_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d4); -+ -+ return (err < 0) ? err : 0; -+} -+ -+static int rtl8221b_config_intr(struct phy_device *phydev) -+{ -+ int err; -+ -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { -+ err = rtl8221b_ack_interrupt(phydev); -+ if (err) -+ return err; -+ -+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x7ff); -+ } else { -+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x0); -+ if (err) -+ return err; -+ -+ err = rtl8221b_ack_interrupt(phydev); -+ } -+ -+ return err; -+} -+ -+static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = rtl8221b_ack_interrupt(phydev); -+ if (err) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ phy_trigger_machine(phydev); -+ -+ return IRQ_HANDLED; -+} -+ - static struct phy_driver realtek_drvs[] = { - { - PHY_ID_MATCH_EXACT(0x00008201), -@@ -1120,6 +1165,8 @@ static struct phy_driver realtek_drvs[] - .get_features = rtl822x_get_features, - .config_init = rtl8221b_config_init, - .config_aneg = rtl822x_config_aneg, -+ .config_intr = rtl8221b_config_intr, -+ .handle_interrupt = rtl8221b_handle_interrupt, - .probe = rtl822x_probe, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, diff --git a/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch deleted file mode 100644 index 1d84ea9ced5743..00000000000000 --- a/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From: Felix Fietkau -Date: Thu, 27 Oct 2022 23:39:52 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code - on mt7621 - -Avoid some branches in the hot path on low-end devices with limited CPU power, -and reduce code size - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1323,6 +1323,22 @@ struct mtk_mac { - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ - extern const struct of_device_id of_mtk_match[]; - -+#ifdef CONFIG_SOC_MT7621 -+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) -+{ -+ return true; -+} -+ -+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) -+{ -+ return false; -+} -+ -+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) -+{ -+ return false; -+} -+#else - static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) - { - return eth->soc->version == 1; -@@ -1337,6 +1353,7 @@ static inline bool mtk_is_netsys_v3_or_g - { - return eth->soc->version > 2; - } -+#endif - - static inline struct mtk_foe_entry * - mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) diff --git a/target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch b/target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch deleted file mode 100644 index 56edb63234539e..00000000000000 --- a/target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch +++ /dev/null @@ -1,94 +0,0 @@ -From: Felix Fietkau -Date: Thu, 3 Nov 2022 12:38:49 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: work around issue with sending - small fragments - -When lots of frames are sent with a number of very small fragments, an -internal FIFO can overflow, causing the DMA engine to lock up lock up and -transmit attempts time out. - -Fix this on MT7986 by increasing the reserved FIFO space. -Fix this on older chips by detecting the presence of small fragments and use -skb_gso_segment + skb_linearize to deal with them. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1516,12 +1516,28 @@ static void mtk_wake_queue(struct mtk_et - } - } - -+static bool mtk_skb_has_small_frag(struct sk_buff *skb) -+{ -+ int min_size = 16; -+ int i; -+ -+ if (skb_headlen(skb) < min_size) -+ return true; -+ -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -+ if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size) -+ return true; -+ -+ return false; -+} -+ - static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - struct mtk_tx_ring *ring = ð->tx_ring; - struct net_device_stats *stats = &dev->stats; -+ struct sk_buff *segs, *next; - bool gso = false; - int tx_num; - -@@ -1543,6 +1559,18 @@ static netdev_tx_t mtk_start_xmit(struct - return NETDEV_TX_BUSY; - } - -+ if (mtk_is_netsys_v1(eth) && -+ skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { -+ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO); -+ if (IS_ERR(segs)) -+ goto drop; -+ -+ if (segs) { -+ consume_skb(skb); -+ skb = segs; -+ } -+ } -+ - /* TSO: fill MSS info in tcp checksum field */ - if (skb_is_gso(skb)) { - if (skb_cow_head(skb, 0)) { -@@ -1558,8 +1586,14 @@ static netdev_tx_t mtk_start_xmit(struct - } - } - -- if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) -- goto drop; -+ skb_list_walk_safe(skb, skb, next) { -+ if ((mtk_is_netsys_v1(eth) && -+ mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || -+ mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { -+ stats->tx_dropped++; -+ dev_kfree_skb_any(skb); -+ } -+ } - - if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) - netif_tx_stop_all_queues(dev); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -268,7 +268,7 @@ - #define MTK_CHK_DDONE_EN BIT(28) - #define MTK_DMAD_WR_WDONE BIT(26) - #define MTK_WCOMP_EN BIT(24) --#define MTK_RESV_BUF (0x40 << 16) -+#define MTK_RESV_BUF (0x80 << 16) - #define MTK_MUTLI_CNT (0x4 << 12) - #define MTK_LEAKY_BUCKET_EN BIT(11) - diff --git a/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch b/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch deleted file mode 100644 index 11a81dd0bfdc9b..00000000000000 --- a/target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Felix Fietkau -Date: Fri, 28 Oct 2022 12:54:48 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: set NETIF_F_ALL_TSO - -Significantly improves performance by avoiding unnecessary segmentation - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -47,8 +47,7 @@ - #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \ - NETIF_F_RXCSUM | \ - NETIF_F_HW_VLAN_CTAG_TX | \ -- NETIF_F_SG | NETIF_F_TSO | \ -- NETIF_F_TSO6 | \ -+ NETIF_F_SG | NETIF_F_ALL_TSO | \ - NETIF_F_IPV6_CSUM |\ - NETIF_F_HW_TC) - #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM) diff --git a/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch b/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch deleted file mode 100644 index cc6c9e91bf7294..00000000000000 --- a/target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Felix Fietkau -Date: Wed, 29 Mar 2023 16:02:54 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix remaining throughput - regression - -Based on further tests, it seems that the QDMA shaper is not able to -perform shaping close to the MAC link rate without throughput loss. -This cannot be compensated by increasing the shaping rate, so it seems -to be an internal limit. - -Fix the remaining throughput regression by detecting that condition and -limiting shaping to ports with lower link speed. - -This patch intentionally ignores link speed gain from TRGMII, because -even on such links, shaping to 1000 Mbit/s incurs some throughput -degradation. - -Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues") -Reported-by: Frank Wunderlich -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -723,6 +723,7 @@ static void mtk_mac_link_up(struct phyli - MAC_MCR_FORCE_RX_FC); - - /* Configure speed */ -+ mac->speed = speed; - switch (speed) { - case SPEED_2500: - case SPEED_1000: -@@ -3292,6 +3293,9 @@ found: - if (dp->index >= MTK_QDMA_NUM_QUEUES) - return NOTIFY_DONE; - -+ if (mac->speed > 0 && mac->speed <= s.base.speed) -+ s.base.speed = 0; -+ - mtk_set_queue_speed(eth, dp->index + 3, s.base.speed); - - return NOTIFY_DONE; diff --git a/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch b/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch deleted file mode 100644 index ed0a544228101e..00000000000000 --- a/target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Felix Fietkau -Date: Tue, 27 Dec 2022 15:02:51 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: ppe: fix L2 offloading with DSA - untagging offload enabled - -Check for skb metadata in order to detect the case where the DSA header is not -present. - -Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging") -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include "mtk_eth_soc.h" - #include "mtk_ppe.h" -@@ -835,7 +836,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe - skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK) - goto out; - -- tag += 4; -+ if (!skb_metadata_dst(skb)) -+ tag += 4; -+ - if (get_unaligned_be16(tag) != ETH_P_8021Q) - break; - diff --git a/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch deleted file mode 100644 index 61c23da821a491..00000000000000 --- a/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch +++ /dev/null @@ -1,1605 +0,0 @@ -From 1e25ca1147579bda8b941be1b9851f5911d44eb0 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 22 Aug 2023 19:04:42 +0100 -Subject: [PATCH 098/125] net: ethernet: mtk_eth_soc: add paths and SerDes - modes for MT7988 - -MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to -connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R, -2500Base-X, 1000Base-X and Cisco SGMII interface modes. - -Implement support for configuring for the new paths to SerDes interfaces -and the internal 2.5G PHY. - -Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and -setup the new PHYA on MT7988 to access the also still existing old -LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface -modes. - -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/Kconfig | 16 + - drivers/net/ethernet/mediatek/Makefile | 1 + - drivers/net/ethernet/mediatek/mtk_eth_path.c | 123 +++- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 182 ++++- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 232 ++++++- - drivers/net/ethernet/mediatek/mtk_usxgmii.c | 692 +++++++++++++++++++ - 6 files changed, 1215 insertions(+), 31 deletions(-) - create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c - ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -24,6 +24,22 @@ config NET_MEDIATEK_SOC - This driver supports the gigabit ethernet MACs in the - MediaTek SoC family. - -+config NET_MEDIATEK_SOC_USXGMII -+ bool "Support USXGMII SerDes on MT7988" -+ depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST -+ def_bool NET_MEDIATEK_SOC != n -+ help -+ Include support for 10GE SerDes which can be found on MT7988. -+ If this kernel should run on SoCs with 10 GBit/s Ethernet you -+ will need to select this option to use GMAC2 and GMAC3 with -+ external PHYs, SFP(+) cages in 10GBase-R, 5GBase-R or USXGMII -+ interface modes. -+ -+ Note that as the 2500Base-X/1000Base-X/Cisco SGMII SerDes PCS -+ unit (MediaTek LynxI) in MT7988 is connected via the new 10GE -+ SerDes, you will also need to select this option in case you -+ want to use any of those SerDes modes. -+ - config NET_MEDIATEK_STAR_EMAC - tristate "MediaTek STAR Ethernet MAC support" - select PHYLIB ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -5,6 +5,7 @@ - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o - mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o -+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.o - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o - ifdef CONFIG_DEBUG_FS - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64 - return "gmac2_rgmii"; - case MTK_ETH_PATH_GMAC2_SGMII: - return "gmac2_sgmii"; -+ case MTK_ETH_PATH_GMAC2_2P5GPHY: -+ return "gmac2_2p5gphy"; - case MTK_ETH_PATH_GMAC2_GEPHY: - return "gmac2_gephy"; -+ case MTK_ETH_PATH_GMAC3_SGMII: -+ return "gmac3_sgmii"; - case MTK_ETH_PATH_GDM1_ESW: - return "gdm1_esw"; -+ case MTK_ETH_PATH_GMAC1_USXGMII: -+ return "gmac1_usxgmii"; -+ case MTK_ETH_PATH_GMAC2_USXGMII: -+ return "gmac2_usxgmii"; -+ case MTK_ETH_PATH_GMAC3_USXGMII: -+ return "gmac3_usxgmii"; - default: - return "unknown path"; - } -@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(stru - return 0; - } - -+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path) -+{ -+ int ret; -+ -+ if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) { -+ ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2); -+ if (ret) -+ return ret; -+ -+ /* Setup mux to 2p5g PHY */ -+ ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL); -+ if (ret) -+ return ret; -+ -+ dev_dbg(eth->dev, "path %s in %s updated\n", -+ mtk_eth_path_name(path), __func__); -+ } -+ -+ return 0; -+} -+ - static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; -@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_ - return 0; - } - --static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) -+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path) -+{ -+ unsigned int val = 0; -+ bool updated = true; -+ int mac_id = 0; -+ -+ /* Disable SYSCFG1 SGMII */ -+ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); -+ -+ switch (path) { -+ case MTK_ETH_PATH_GMAC1_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2; -+ mac_id = MTK_GMAC1_ID; -+ break; -+ case MTK_ETH_PATH_GMAC2_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2; -+ mac_id = MTK_GMAC2_ID; -+ break; -+ case MTK_ETH_PATH_GMAC3_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2; -+ mac_id = MTK_GMAC3_ID; -+ break; -+ default: -+ updated = false; -+ }; -+ -+ if (updated) { -+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, -+ SYSCFG0_SGMII_MASK, val); -+ -+ if (mac_id == MTK_GMAC2_ID) -+ regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, -+ MUX_G2_USXGMII_SEL); -+ } -+ -+ dev_dbg(eth->dev, "path %s in %s updated = %d\n", -+ mtk_eth_path_name(path), __func__, updated); -+ -+ return 0; -+} -+ -+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii - case MTK_ETH_PATH_GMAC2_SGMII: - val |= SYSCFG0_SGMII_GMAC2_V2; - break; -+ case MTK_ETH_PATH_GMAC3_SGMII: -+ val |= SYSCFG0_SGMII_GMAC3_V2; -+ break; - default: - updated = false; - } -@@ -210,13 +285,25 @@ static const struct mtk_eth_muxc mtk_eth - .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY, - .set_path = set_mux_u3_gmac2_to_qphy, - }, { -+ .name = "mux_gmac2_to_2p5gphy", -+ .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY, -+ .set_path = set_mux_gmac2_to_2p5gphy, -+ }, { - .name = "mux_gmac1_gmac2_to_sgmii_rgmii", - .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII, - .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii, - }, { - .name = "mux_gmac12_to_gephy_sgmii", - .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII, -- .set_path = set_mux_gmac12_to_gephy_sgmii, -+ .set_path = set_mux_gmac123_to_gephy_sgmii, -+ }, { -+ .name = "mux_gmac123_to_gephy_sgmii", -+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII, -+ .set_path = set_mux_gmac123_to_gephy_sgmii, -+ }, { -+ .name = "mux_gmac123_to_usxgmii", -+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII, -+ .set_path = set_mux_gmac123_to_usxgmii, - }, - }; - -@@ -249,12 +336,39 @@ out: - return err; - } - -+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id) -+{ -+ u64 path; -+ -+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII : -+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII : -+ MTK_ETH_PATH_GMAC3_USXGMII; -+ -+ /* Setup proper MUXes along the path */ -+ return mtk_eth_mux_setup(eth, path); -+} -+ - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id) - { - u64 path; - -- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII : -- MTK_ETH_PATH_GMAC2_SGMII; -+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII : -+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII : -+ MTK_ETH_PATH_GMAC3_SGMII; -+ -+ /* Setup proper MUXes along the path */ -+ return mtk_eth_mux_setup(eth, path); -+} -+ -+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id) -+{ -+ u64 path = 0; -+ -+ if (mac_id == MTK_GMAC2_ID) -+ path = MTK_ETH_PATH_GMAC2_2P5GPHY; -+ -+ if (!path) -+ return -EINVAL; - - /* Setup proper MUXes along the path */ - return mtk_eth_mux_setup(eth, path); -@@ -284,4 +398,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk - /* Setup proper MUXes along the path */ - return mtk_eth_mux_setup(eth, path); - } -- ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -432,6 +432,30 @@ static void mtk_setup_bridge_switch(stru - MTK_GSW_CFG); - } - -+static bool mtk_check_gmac23_idle(struct mtk_mac *mac) -+{ -+ u32 mac_fsm, gdm_fsm; -+ -+ mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id)); -+ -+ switch (mac->id) { -+ case MTK_GMAC2_ID: -+ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM); -+ break; -+ case MTK_GMAC3_ID: -+ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM); -+ break; -+ default: -+ return true; -+ }; -+ -+ if ((mac_fsm & 0xFFFF0000) == 0x01010000 && -+ (gdm_fsm & 0xFFFF0000) == 0x00000000) -+ return true; -+ -+ return false; -+} -+ - static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, - phy_interface_t interface) - { -@@ -440,12 +464,20 @@ static struct phylink_pcs *mtk_mac_selec - struct mtk_eth *eth = mac->hw; - unsigned int sid; - -- if (interface == PHY_INTERFACE_MODE_SGMII || -- phy_interface_mode_is_8023z(interface)) { -- sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? -- 0 : mac->id; -- -- return eth->sgmii_pcs[sid]; -+ if ((interface == PHY_INTERFACE_MODE_SGMII || -+ phy_interface_mode_is_8023z(interface)) && -+ MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { -+ sid = mtk_mac2xgmii_id(eth, mac->id); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) -+ return mtk_sgmii_wrapper_select_pcs(eth, mac->id); -+ else -+ return eth->sgmii_pcs[sid]; -+ } else if ((interface == PHY_INTERFACE_MODE_USXGMII || -+ interface == PHY_INTERFACE_MODE_10GBASER || -+ interface == PHY_INTERFACE_MODE_5GBASER) && -+ MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII) && -+ mac->id != MTK_GMAC1_ID) { -+ return mtk_usxgmii_select_pcs(eth, mac->id); - } - - return NULL; -@@ -501,7 +533,22 @@ static void mtk_mac_config(struct phylin - goto init_err; - } - break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_5GBASER: -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { -+ err = mtk_gmac_usxgmii_path_setup(eth, mac->id); -+ if (err) -+ goto init_err; -+ } -+ break; - case PHY_INTERFACE_MODE_INTERNAL: -+ if (mac->id == MTK_GMAC2_ID && -+ MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) { -+ err = mtk_gmac_2p5gphy_path_setup(eth, mac->id); -+ if (err) -+ goto init_err; -+ } - break; - default: - goto err_phy; -@@ -556,8 +603,6 @@ static void mtk_mac_config(struct phylin - val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id); - val |= SYSCFG0_GE_MODE(ge_mode, mac->id); - regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val); -- -- mac->interface = state->interface; - } - - /* SGMII */ -@@ -574,21 +619,40 @@ static void mtk_mac_config(struct phylin - - /* Save the syscfg0 value for mac_finish */ - mac->syscfg0 = val; -- } else if (phylink_autoneg_inband(mode)) { -+ } else if (state->interface != PHY_INTERFACE_MODE_USXGMII && -+ state->interface != PHY_INTERFACE_MODE_10GBASER && -+ state->interface != PHY_INTERFACE_MODE_5GBASER && -+ phylink_autoneg_inband(mode)) { - dev_err(eth->dev, -- "In-band mode not supported in non SGMII mode!\n"); -+ "In-band mode not supported in non-SerDes modes!\n"); - return; - } - - /* Setup gmac */ -- if (mtk_is_netsys_v3_or_greater(eth) && -- mac->interface == PHY_INTERFACE_MODE_INTERNAL) { -- mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); -- mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ if (mtk_interface_mode_is_xgmii(state->interface)) { -+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); -+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); -+ -+ if (mac->id == MTK_GMAC1_ID) -+ mtk_setup_bridge_switch(eth); -+ } else { -+ mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id)); - -- mtk_setup_bridge_switch(eth); -+ /* FIXME: In current hardware design, we have to reset FE -+ * when swtiching XGDM to GDM. Therefore, here trigger an SER -+ * to let GDM go back to the initial state. -+ */ -+ if ((mtk_interface_mode_is_xgmii(mac->interface) || -+ mac->interface == PHY_INTERFACE_MODE_NA) && -+ !mtk_check_gmac23_idle(mac) && -+ !test_bit(MTK_RESETTING, ð->state)) -+ schedule_work(ð->pending_work); -+ } - } - -+ mac->interface = state->interface; -+ - return; - - err_phy: -@@ -633,10 +697,14 @@ static void mtk_mac_link_down(struct phy - { - struct mtk_mac *mac = container_of(config, struct mtk_mac, - phylink_config); -- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - -- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK); -- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); -+ if (!mtk_interface_mode_is_xgmii(interface)) { -+ mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK, 0, MTK_MAC_MCR(mac->id)); -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id)); -+ } else if (mac->id != MTK_GMAC1_ID) { -+ mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id)); -+ } - } - - static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, -@@ -708,13 +776,11 @@ static void mtk_set_queue_speed(struct m - mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); - } - --static void mtk_mac_link_up(struct phylink_config *config, -- struct phy_device *phy, -- unsigned int mode, phy_interface_t interface, -- int speed, int duplex, bool tx_pause, bool rx_pause) -+static void mtk_gdm_mac_link_up(struct mtk_mac *mac, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) - { -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); - u32 mcr; - - mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -@@ -748,6 +814,55 @@ static void mtk_mac_link_up(struct phyli - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ u32 mcr, force_link = 0; -+ -+ if (mac->id == MTK_GMAC1_ID) -+ return; -+ -+ /* Eliminate the interference(before link-up) caused by PHY noise */ -+ mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id)); -+ mdelay(20); -+ mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id)); -+ -+ if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID) -+ force_link = MTK_XGMAC_FORCE_LINK(mac->id); -+ -+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id)); -+ -+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id)); -+ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE); -+ /* Configure pause modes - -+ * phylink will avoid these for half duplex -+ */ -+ if (tx_pause) -+ mcr |= XMAC_MCR_FORCE_TX_FC; -+ if (rx_pause) -+ mcr |= XMAC_MCR_FORCE_RX_FC; -+ -+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id)); -+} -+ -+static void mtk_mac_link_up(struct phylink_config *config, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct mtk_mac *mac = container_of(config, struct mtk_mac, -+ phylink_config); -+ -+ if (mtk_interface_mode_is_xgmii(interface)) -+ mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex, -+ tx_pause, rx_pause); -+ else -+ mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex, -+ tx_pause, rx_pause); -+} -+ - static const struct phylink_mac_ops mtk_phylink_ops = { - .validate = phylink_generic_validate, - .mac_select_pcs = mtk_mac_select_pcs, -@@ -4562,8 +4677,21 @@ static int mtk_add_mac(struct mtk_eth *e - phy_interface_zero(mac->phylink_config.supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - mac->phylink_config.supported_interfaces); -+ } else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) { -+ mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD; -+ __set_bit(PHY_INTERFACE_MODE_5GBASER, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_10GBASER, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_USXGMII, -+ mac->phylink_config.supported_interfaces); - } - -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) && -+ id == MTK_GMAC2_ID) -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ mac->phylink_config.supported_interfaces); -+ - phylink = phylink_create(&mac->phylink_config, - of_fwnode_handle(mac->of_node), - phy_mode, &mtk_phylink_ops); -@@ -4756,6 +4884,13 @@ static int mtk_probe(struct platform_dev - - if (err) - return err; -+ } -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { -+ err = mtk_usxgmii_init(eth); -+ -+ if (err) -+ return err; - } - - if (eth->soc->required_pctl) { ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -499,6 +499,21 @@ - #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED) - #define INTF_MODE_RGMII_10_100 0 - -+/* XFI Mac control registers */ -+#define MTK_XMAC_BASE(x) (0x12000 + (((x) - 1) * 0x1000)) -+#define MTK_XMAC_MCR(x) (MTK_XMAC_BASE(x)) -+#define XMAC_MCR_TRX_DISABLE 0xf -+#define XMAC_MCR_FORCE_TX_FC BIT(5) -+#define XMAC_MCR_FORCE_RX_FC BIT(4) -+ -+/* XFI Mac logic reset registers */ -+#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10) -+#define XMAC_LOGIC_RST BIT(0) -+ -+/* XFI Mac count global control */ -+#define MTK_XMAC_CNT_CTRL(x) (MTK_XMAC_BASE(x) + 0x100) -+#define XMAC_GLB_CNTCLR BIT(0) -+ - /* GPIO port control registers for GMAC 2*/ - #define GPIO_OD33_CTRL8 0x4c0 - #define GPIO_BIAS_CTRL 0xed0 -@@ -524,6 +539,7 @@ - #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) - #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) - #define SYSCFG0_SGMII_GMAC2_V2 BIT(8) -+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7) - - - /* ethernet subsystem clock register */ -@@ -556,12 +572,74 @@ - #define ETHSYS_DMA_AG_MAP_QDMA BIT(1) - #define ETHSYS_DMA_AG_MAP_PPE BIT(2) - -+/* USXGMII subsystem config registers */ -+/* Register to control speed */ -+#define RG_PHY_TOP_SPEED_CTRL1 0x80C -+#define USXGMII_RATE_UPDATE_MODE BIT(31) -+#define USXGMII_MAC_CK_GATED BIT(29) -+#define USXGMII_IF_FORCE_EN BIT(28) -+#define USXGMII_RATE_ADAPT_MODE GENMASK(10, 8) -+#define USXGMII_RATE_ADAPT_MODE_X1 0 -+#define USXGMII_RATE_ADAPT_MODE_X2 1 -+#define USXGMII_RATE_ADAPT_MODE_X4 2 -+#define USXGMII_RATE_ADAPT_MODE_X10 3 -+#define USXGMII_RATE_ADAPT_MODE_X100 4 -+#define USXGMII_RATE_ADAPT_MODE_X5 5 -+#define USXGMII_RATE_ADAPT_MODE_X50 6 -+#define USXGMII_XFI_RX_MODE GENMASK(6, 4) -+#define USXGMII_XFI_RX_MODE_10G 0 -+#define USXGMII_XFI_RX_MODE_5G 1 -+#define USXGMII_XFI_TX_MODE GENMASK(2, 0) -+#define USXGMII_XFI_TX_MODE_10G 0 -+#define USXGMII_XFI_TX_MODE_5G 1 -+ -+/* Register to control PCS AN */ -+#define RG_PCS_AN_CTRL0 0x810 -+#define USXGMII_AN_RESTART BIT(31) -+#define USXGMII_AN_SYNC_CNT GENMASK(30, 11) -+#define USXGMII_AN_ENABLE BIT(0) -+ -+#define RG_PCS_AN_CTRL2 0x818 -+#define USXGMII_LINK_TIMER_IDLE_DETECT GENMASK(29, 20) -+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT GENMASK(19, 10) -+#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0) -+ -+/* Register to read PCS AN status */ -+#define RG_PCS_AN_STS0 0x81c -+#define USXGMII_PCS_AN_WORD GENMASK(15, 0) -+#define USXGMII_LPA_LATCH BIT(31) -+ -+/* Register to control USXGMII XFI PLL digital */ -+#define XFI_PLL_DIG_GLB8 0x08 -+#define RG_XFI_PLL_EN BIT(31) -+ -+/* Register to control USXGMII XFI PLL analog */ -+#define XFI_PLL_ANA_GLB8 0x108 -+#define RG_XFI_PLL_ANA_SWWA 0x02283248 -+ - /* Infrasys subsystem config registers */ - #define INFRA_MISC2 0x70c - #define CO_QPHY_SEL BIT(0) - #define GEPHY_MAC_SEL BIT(1) - -+/* Toprgu subsystem config registers */ -+#define TOPRGU_SWSYSRST 0x18 -+#define SWSYSRST_UNLOCK_KEY GENMASK(31, 24) -+#define SWSYSRST_XFI_PLL_GRST BIT(16) -+#define SWSYSRST_XFI_PEXPT1_GRST BIT(15) -+#define SWSYSRST_XFI_PEXPT0_GRST BIT(14) -+#define SWSYSRST_XFI1_GRST BIT(13) -+#define SWSYSRST_XFI0_GRST BIT(12) -+#define SWSYSRST_SGMII1_GRST BIT(2) -+#define SWSYSRST_SGMII0_GRST BIT(1) -+#define TOPRGU_SWSYSRST_EN 0xFC -+ - /* Top misc registers */ -+#define TOP_MISC_NETSYS_PCS_MUX 0x84 -+#define NETSYS_PCS_MUX_MASK GENMASK(1, 0) -+#define MUX_G2_USXGMII_SEL BIT(1) -+#define MUX_HSGMII1_G1_SEL BIT(0) -+ - #define USB_PHY_SWITCH_REG 0x218 - #define QPHY_SEL_MASK GENMASK(1, 0) - #define SGMII_QPHY_SEL 0x2 -@@ -586,6 +664,8 @@ - #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) - #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) - -+/* Debug Purpose Register */ -+#define MTK_PSE_FQFC_CFG 0x100 - #define MTK_FE_CDM1_FSM 0x220 - #define MTK_FE_CDM2_FSM 0x224 - #define MTK_FE_CDM3_FSM 0x238 -@@ -594,6 +674,11 @@ - #define MTK_FE_CDM6_FSM 0x328 - #define MTK_FE_GDM1_FSM 0x228 - #define MTK_FE_GDM2_FSM 0x22C -+#define MTK_FE_GDM3_FSM 0x23C -+#define MTK_FE_PSE_FREE 0x240 -+#define MTK_FE_DROP_FQ 0x244 -+#define MTK_FE_DROP_FC 0x248 -+#define MTK_FE_DROP_PPE 0x24C - - #define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) - -@@ -940,6 +1025,8 @@ enum mkt_eth_capabilities { - MTK_RGMII_BIT = 0, - MTK_TRGMII_BIT, - MTK_SGMII_BIT, -+ MTK_USXGMII_BIT, -+ MTK_2P5GPHY_BIT, - MTK_ESW_BIT, - MTK_GEPHY_BIT, - MTK_MUX_BIT, -@@ -960,8 +1047,11 @@ enum mkt_eth_capabilities { - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, - MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT, - MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT, -+ MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT, - MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT, - MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT, -+ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT, -+ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT, - - /* PATH BITS */ - MTK_ETH_PATH_GMAC1_RGMII_BIT, -@@ -969,14 +1059,21 @@ enum mkt_eth_capabilities { - MTK_ETH_PATH_GMAC1_SGMII_BIT, - MTK_ETH_PATH_GMAC2_RGMII_BIT, - MTK_ETH_PATH_GMAC2_SGMII_BIT, -+ MTK_ETH_PATH_GMAC2_2P5GPHY_BIT, - MTK_ETH_PATH_GMAC2_GEPHY_BIT, -+ MTK_ETH_PATH_GMAC3_SGMII_BIT, - MTK_ETH_PATH_GDM1_ESW_BIT, -+ MTK_ETH_PATH_GMAC1_USXGMII_BIT, -+ MTK_ETH_PATH_GMAC2_USXGMII_BIT, -+ MTK_ETH_PATH_GMAC3_USXGMII_BIT, - }; - - /* Supported hardware group on SoCs */ - #define MTK_RGMII BIT_ULL(MTK_RGMII_BIT) - #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) - #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) -+#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT) -+#define MTK_2P5GPHY BIT_ULL(MTK_2P5GPHY_BIT) - #define MTK_ESW BIT_ULL(MTK_ESW_BIT) - #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) - #define MTK_MUX BIT_ULL(MTK_MUX_BIT) -@@ -999,10 +1096,16 @@ enum mkt_eth_capabilities { - BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) - #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \ - BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) -+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY \ -+ BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT) - #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \ - BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) - #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ - BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) -+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \ -+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT) -+#define MTK_ETH_MUX_GMAC123_TO_USXGMII \ -+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT) - - /* Supported path present on SoCs */ - #define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) -@@ -1010,8 +1113,13 @@ enum mkt_eth_capabilities { - #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT) - #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) - #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_2P5GPHY BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT) - #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) -+#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT) - #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) -+#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT) -+#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT) - - #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) - #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) -@@ -1019,7 +1127,12 @@ enum mkt_eth_capabilities { - #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII) - #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) - #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) -+#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY) -+#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII) - #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW) -+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII) -+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII) -+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII) - - /* MUXes present on SoCs */ - /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */ -@@ -1038,10 +1151,20 @@ enum mkt_eth_capabilities { - (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \ - MTK_SHARED_SGMII) - -+/* 2: GMAC2 -> XGMII */ -+#define MTK_MUX_GMAC2_TO_2P5GPHY \ -+ (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA) -+ - /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */ - #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ - (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) - -+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \ -+ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX) -+ -+#define MTK_MUX_GMAC123_TO_USXGMII \ -+ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA) -+ - #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) - - #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ -@@ -1073,8 +1196,12 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_RSTCTRL_PPE1 | MTK_SRAM) - --#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \ -- MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) -+#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \ -+ MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \ -+ MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \ -+ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ -+ MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \ -+ MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1184,6 +1311,24 @@ struct mtk_soc_data { - /* currently no SoC has more than 3 macs */ - #define MTK_MAX_DEVS 3 - -+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and -+ * associated data -+ * @regmap: The register map pointing at the range used to setup -+ * USXGMII modes -+ * @interface: Currently selected interface mode -+ * @id: The element is used to record the index of PCS -+ * @pcs: Phylink PCS structure -+ */ -+struct mtk_usxgmii_pcs { -+ struct mtk_eth *eth; -+ struct regmap *regmap; -+ struct phylink_pcs *wrapped_sgmii_pcs; -+ phy_interface_t interface; -+ u8 id; -+ unsigned int mode; -+ struct phylink_pcs pcs; -+}; -+ - /* struct mtk_eth - This is the main datasructure for holding the state - * of the driver - * @dev: The device pointer -@@ -1204,6 +1349,12 @@ struct mtk_soc_data { - * @infra: The register map pointing at the range used to setup - * SGMII and GePHY path - * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances -+ * @sgmii_wrapped_pcs: Pointers to NETSYSv3 wrapper PCS instances -+ * @usxgmii_pll: The register map pointing at the range used to control -+ * the USXGMII SerDes PLL -+ * @regmap_pextp: The register map pointing at the range used to setup -+ * PHYA -+ * @usxgmii_pcs: Pointer to array of pointers to struct for USXGMII PCS - * @pctl: The register map pointing at the range used to setup - * GMAC port drive/slew values - * @dma_refcnt: track how many netdevs are using the DMA engine -@@ -1247,6 +1398,10 @@ struct mtk_eth { - struct regmap *ethsys; - struct regmap *infra; - struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS]; -+ struct regmap *toprgu; -+ struct regmap *usxgmii_pll; -+ struct regmap *regmap_pextp[MTK_MAX_DEVS]; -+ struct mtk_usxgmii_pcs *usxgmii_pcs[MTK_MAX_DEVS]; - struct regmap *pctl; - bool hwlro; - refcount_t dma_refcnt; -@@ -1434,6 +1589,19 @@ static inline u32 mtk_get_ib2_multicast_ - return MTK_FOE_IB2_MULTICAST; - } - -+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_INTERNAL: -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_5GBASER: -+ return true; -+ default: -+ return false; -+ } -+} -+ - /* read the hardware status register */ - void mtk_stats_update_mac(struct mtk_mac *mac); - -@@ -1442,8 +1610,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne - u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); -+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); -+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id); - - int mtk_eth_offload_init(struct mtk_eth *eth); - int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, -@@ -1453,5 +1623,63 @@ int mtk_flow_offload_cmd(struct mtk_eth - void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list); - void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev); - -+static inline int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id) -+{ -+ int xgmii_id = mac_id; -+ -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ switch (mac_id) { -+ case MTK_GMAC1_ID: -+ case MTK_GMAC2_ID: -+ xgmii_id = 1; -+ break; -+ case MTK_GMAC3_ID: -+ xgmii_id = 0; -+ break; -+ default: -+ xgmii_id = -1; -+ } -+ } -+ -+ return MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII) ? 0 : xgmii_id; -+} -+ -+static inline int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id) -+{ -+ int mac_id = xgmii_id; -+ -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ switch (xgmii_id) { -+ case 0: -+ mac_id = 2; -+ break; -+ case 1: -+ mac_id = 1; -+ break; -+ default: -+ mac_id = -1; -+ } -+ } -+ -+ return mac_id; -+} -+ -+#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII -+struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id); -+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id); -+int mtk_usxgmii_init(struct mtk_eth *eth); -+#else -+static inline struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id) -+{ -+ return NULL; -+} -+ -+static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id) -+{ -+ return NULL; -+} -+ -+static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; } -+#endif /* NET_MEDIATEK_SOC_USXGMII */ - - #endif /* MTK_ETH_H */ ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c -@@ -0,0 +1,690 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2023 MediaTek Inc. -+ * Author: Henry Yen -+ * Daniel Golle -+ */ -+ -+#include -+#include -+#include -+#include "mtk_eth_soc.h" -+ -+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs) -+{ -+ return container_of(pcs, struct mtk_usxgmii_pcs, pcs); -+} -+ -+static int mtk_xfi_pextp_init(struct mtk_eth *eth) -+{ -+ struct device *dev = eth->dev; -+ struct device_node *r = dev->of_node; -+ struct device_node *np; -+ int i; -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ np = of_parse_phandle(r, "mediatek,xfi-pextp", i); -+ if (!np) -+ break; -+ -+ eth->regmap_pextp[i] = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->regmap_pextp[i])) -+ return PTR_ERR(eth->regmap_pextp[i]); -+ } -+ -+ return 0; -+} -+ -+static int mtk_xfi_pll_init(struct mtk_eth *eth) -+{ -+ struct device_node *r = eth->dev->of_node; -+ struct device_node *np; -+ -+ np = of_parse_phandle(r, "mediatek,xfi-pll", 0); -+ if (!np) -+ return -1; -+ -+ eth->usxgmii_pll = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->usxgmii_pll)) -+ return PTR_ERR(eth->usxgmii_pll); -+ -+ return 0; -+} -+ -+static int mtk_toprgu_init(struct mtk_eth *eth) -+{ -+ struct device_node *r = eth->dev->of_node; -+ struct device_node *np; -+ -+ np = of_parse_phandle(r, "mediatek,toprgu", 0); -+ if (!np) -+ return -1; -+ -+ eth->toprgu = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->toprgu)) -+ return PTR_ERR(eth->toprgu); -+ -+ return 0; -+} -+ -+static int mtk_xfi_pll_enable(struct mtk_eth *eth) -+{ -+ u32 val = 0; -+ -+ if (!eth->usxgmii_pll) -+ return -EINVAL; -+ -+ /* Add software workaround for USXGMII PLL TCL issue */ -+ regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA); -+ -+ regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val); -+ val |= RG_XFI_PLL_EN; -+ regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val); -+ -+ return 0; -+} -+ -+static void mtk_usxgmii_setup_phya(struct regmap *pextp, phy_interface_t interface, int id) -+{ -+ bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER || -+ interface == PHY_INTERFACE_MODE_USXGMII); -+ bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX); -+ bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER); -+ -+ /* Setup operation mode */ -+ if (is_10g) -+ regmap_write(pextp, 0x9024, 0x00C9071C); -+ else -+ regmap_write(pextp, 0x9024, 0x00D9071C); -+ -+ if (is_5g) -+ regmap_write(pextp, 0x2020, 0xAAA5A5AA); -+ else -+ regmap_write(pextp, 0x2020, 0xAA8585AA); -+ -+ if (is_2p5g || is_5g || is_10g) { -+ regmap_write(pextp, 0x2030, 0x0C020707); -+ regmap_write(pextp, 0x2034, 0x0E050F0F); -+ regmap_write(pextp, 0x2040, 0x00140032); -+ } else { -+ regmap_write(pextp, 0x2030, 0x0C020207); -+ regmap_write(pextp, 0x2034, 0x0E05050F); -+ regmap_write(pextp, 0x2040, 0x00200032); -+ } -+ -+ if (is_2p5g || is_10g) -+ regmap_write(pextp, 0x50F0, 0x00C014AA); -+ else if (is_5g) -+ regmap_write(pextp, 0x50F0, 0x00C018AA); -+ else -+ regmap_write(pextp, 0x50F0, 0x00C014BA); -+ -+ if (is_5g) { -+ regmap_write(pextp, 0x50E0, 0x3777812B); -+ regmap_write(pextp, 0x506C, 0x005C9CFF); -+ regmap_write(pextp, 0x5070, 0x9DFAFAFA); -+ regmap_write(pextp, 0x5074, 0x273F3F3F); -+ regmap_write(pextp, 0x5078, 0xA8883868); -+ regmap_write(pextp, 0x507C, 0x14661466); -+ } else { -+ regmap_write(pextp, 0x50E0, 0x3777C12B); -+ regmap_write(pextp, 0x506C, 0x005F9CFF); -+ regmap_write(pextp, 0x5070, 0x9D9DFAFA); -+ regmap_write(pextp, 0x5074, 0x27273F3F); -+ regmap_write(pextp, 0x5078, 0xA7883C68); -+ regmap_write(pextp, 0x507C, 0x11661166); -+ } -+ -+ if (is_2p5g || is_10g) { -+ regmap_write(pextp, 0x5080, 0x0E000AAF); -+ regmap_write(pextp, 0x5084, 0x08080D0D); -+ regmap_write(pextp, 0x5088, 0x02030909); -+ } else if (is_5g) { -+ regmap_write(pextp, 0x5080, 0x0E001ABF); -+ regmap_write(pextp, 0x5084, 0x080B0D0D); -+ regmap_write(pextp, 0x5088, 0x02050909); -+ } else { -+ regmap_write(pextp, 0x5080, 0x0E000EAF); -+ regmap_write(pextp, 0x5084, 0x08080E0D); -+ regmap_write(pextp, 0x5088, 0x02030B09); -+ } -+ -+ if (is_5g) { -+ regmap_write(pextp, 0x50E4, 0x0C000000); -+ regmap_write(pextp, 0x50E8, 0x04000000); -+ } else { -+ regmap_write(pextp, 0x50E4, 0x0C0C0000); -+ regmap_write(pextp, 0x50E8, 0x04040000); -+ } -+ -+ if (is_2p5g || mtk_interface_mode_is_xgmii(interface)) -+ regmap_write(pextp, 0x50EC, 0x0F0F0C06); -+ else -+ regmap_write(pextp, 0x50EC, 0x0F0F0606); -+ -+ if (is_5g) { -+ regmap_write(pextp, 0x50A8, 0x50808C8C); -+ regmap_write(pextp, 0x6004, 0x18000000); -+ } else { -+ regmap_write(pextp, 0x50A8, 0x506E8C8C); -+ regmap_write(pextp, 0x6004, 0x18190000); -+ } -+ -+ if (is_10g) -+ regmap_write(pextp, 0x00F8, 0x01423342); -+ else if (is_5g) -+ regmap_write(pextp, 0x00F8, 0x00A132A1); -+ else if (is_2p5g) -+ regmap_write(pextp, 0x00F8, 0x009C329C); -+ else -+ regmap_write(pextp, 0x00F8, 0x00FA32FA); -+ -+ /* Force SGDT_OUT off and select PCS */ -+ if (mtk_interface_mode_is_xgmii(interface)) -+ regmap_write(pextp, 0x00F4, 0x80201F20); -+ else -+ regmap_write(pextp, 0x00F4, 0x80201F21); -+ -+ /* Force GLB_CKDET_OUT */ -+ regmap_write(pextp, 0x0030, 0x00050C00); -+ -+ /* Force AEQ on */ -+ regmap_write(pextp, 0x0070, 0x02002800); -+ ndelay(1020); -+ -+ /* Setup DA default value */ -+ regmap_write(pextp, 0x30B0, 0x00000020); -+ regmap_write(pextp, 0x3028, 0x00008A01); -+ regmap_write(pextp, 0x302C, 0x0000A884); -+ regmap_write(pextp, 0x3024, 0x00083002); -+ if (mtk_interface_mode_is_xgmii(interface)) { -+ regmap_write(pextp, 0x3010, 0x00022220); -+ regmap_write(pextp, 0x5064, 0x0F020A01); -+ regmap_write(pextp, 0x50B4, 0x06100600); -+ if (interface == PHY_INTERFACE_MODE_USXGMII) -+ regmap_write(pextp, 0x3048, 0x40704000); -+ else -+ regmap_write(pextp, 0x3048, 0x47684100); -+ } else { -+ regmap_write(pextp, 0x3010, 0x00011110); -+ regmap_write(pextp, 0x3048, 0x40704000); -+ } -+ -+ if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g) -+ regmap_write(pextp, 0x3064, 0x0000C000); -+ -+ if (interface == PHY_INTERFACE_MODE_USXGMII) { -+ regmap_write(pextp, 0x3050, 0xA8000000); -+ regmap_write(pextp, 0x3054, 0x000000AA); -+ } else if (mtk_interface_mode_is_xgmii(interface)) { -+ regmap_write(pextp, 0x3050, 0x00000000); -+ regmap_write(pextp, 0x3054, 0x00000000); -+ } else { -+ regmap_write(pextp, 0x3050, 0xA8000000); -+ regmap_write(pextp, 0x3054, 0x000000AA); -+ } -+ -+ if (mtk_interface_mode_is_xgmii(interface)) -+ regmap_write(pextp, 0x306C, 0x00000F00); -+ else if (is_2p5g) -+ regmap_write(pextp, 0x306C, 0x22000F00); -+ else -+ regmap_write(pextp, 0x306C, 0x20200F00); -+ -+ if (interface == PHY_INTERFACE_MODE_10GBASER && id == 0) -+ regmap_write(pextp, 0xA008, 0x0007B400); -+ -+ if (mtk_interface_mode_is_xgmii(interface)) -+ regmap_write(pextp, 0xA060, 0x00040000); -+ else -+ regmap_write(pextp, 0xA060, 0x00050000); -+ -+ if (is_10g) -+ regmap_write(pextp, 0x90D0, 0x00000001); -+ else if (is_5g) -+ regmap_write(pextp, 0x90D0, 0x00000003); -+ else if (is_2p5g) -+ regmap_write(pextp, 0x90D0, 0x00000005); -+ else -+ regmap_write(pextp, 0x90D0, 0x00000007); -+ -+ /* Release reset */ -+ regmap_write(pextp, 0x0070, 0x0200E800); -+ usleep_range(150, 500); -+ -+ /* Switch to P0 */ -+ regmap_write(pextp, 0x0070, 0x0200C111); -+ ndelay(1020); -+ regmap_write(pextp, 0x0070, 0x0200C101); -+ usleep_range(15, 50); -+ -+ if (mtk_interface_mode_is_xgmii(interface)) { -+ /* Switch to Gen3 */ -+ regmap_write(pextp, 0x0070, 0x0202C111); -+ } else { -+ /* Switch to Gen2 */ -+ regmap_write(pextp, 0x0070, 0x0201C111); -+ } -+ ndelay(1020); -+ if (mtk_interface_mode_is_xgmii(interface)) -+ regmap_write(pextp, 0x0070, 0x0202C101); -+ else -+ regmap_write(pextp, 0x0070, 0x0201C101); -+ usleep_range(100, 500); -+ regmap_write(pextp, 0x30B0, 0x00000030); -+ if (mtk_interface_mode_is_xgmii(interface)) -+ regmap_write(pextp, 0x00F4, 0x80201F00); -+ else -+ regmap_write(pextp, 0x00F4, 0x80201F01); -+ -+ regmap_write(pextp, 0x3040, 0x30000000); -+ usleep_range(400, 1000); -+} -+ -+static void mtk_usxgmii_reset(struct mtk_eth *eth, int id) -+{ -+ u32 toggle, val; -+ -+ if (id >= MTK_MAX_DEVS || !eth->toprgu) -+ return; -+ -+ switch (id) { -+ case 0: -+ toggle = SWSYSRST_XFI_PEXPT0_GRST | SWSYSRST_XFI0_GRST | -+ SWSYSRST_SGMII0_GRST; -+ break; -+ case 1: -+ toggle = SWSYSRST_XFI_PEXPT1_GRST | SWSYSRST_XFI1_GRST | -+ SWSYSRST_SGMII1_GRST; -+ break; -+ default: -+ return; -+ } -+ -+ /* Enable software reset */ -+ regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle); -+ -+ /* Assert USXGMII reset */ -+ regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST, -+ FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | toggle); -+ -+ usleep_range(100, 500); -+ -+ /* De-assert USXGMII reset */ -+ regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val); -+ val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88); -+ val &= ~toggle; -+ regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val); -+ -+ /* Disable software reset */ -+ regmap_clear_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle); -+ -+ mdelay(10); -+} -+ -+/* As the USXGMII PHYA is shared with the 1000Base-X/2500Base-X/Cisco SGMII unit -+ * the psc-mtk-lynxi instance needs to be wrapped, so that calls to .pcs_config -+ * also trigger an initial reset and subsequent configuration of the PHYA. -+ */ -+struct mtk_sgmii_wrapper_pcs { -+ struct mtk_eth *eth; -+ struct phylink_pcs *wrapped_pcs; -+ u8 id; -+ struct phylink_pcs pcs; -+}; -+ -+static int mtk_sgmii_wrapped_pcs_config(struct phylink_pcs *pcs, -+ unsigned int mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); -+ bool full_reconf; -+ int ret; -+ -+ full_reconf = interface != wp->eth->usxgmii_pcs[wp->id]->interface; -+ if (full_reconf) { -+ mtk_xfi_pll_enable(wp->eth); -+ mtk_usxgmii_reset(wp->eth, wp->id); -+ } -+ -+ ret = wp->wrapped_pcs->ops->pcs_config(wp->wrapped_pcs, mode, interface, -+ advertising, permit_pause_to_mac); -+ -+ if (full_reconf) -+ mtk_usxgmii_setup_phya(wp->eth->regmap_pextp[wp->id], interface, wp->id); -+ -+ wp->eth->usxgmii_pcs[wp->id]->interface = interface; -+ -+ return ret; -+} -+ -+static void mtk_sgmii_wrapped_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); -+ -+ return wp->wrapped_pcs->ops->pcs_get_state(wp->wrapped_pcs, state); -+} -+ -+static void mtk_sgmii_wrapped_pcs_an_restart(struct phylink_pcs *pcs) -+{ -+ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); -+ -+ wp->wrapped_pcs->ops->pcs_an_restart(wp->wrapped_pcs); -+} -+ -+static void mtk_sgmii_wrapped_pcs_link_up(struct phylink_pcs *pcs, -+ unsigned int mode, -+ phy_interface_t interface, int speed, -+ int duplex) -+{ -+ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); -+ -+ wp->wrapped_pcs->ops->pcs_link_up(wp->wrapped_pcs, mode, interface, speed, duplex); -+} -+ -+static void mtk_sgmii_wrapped_pcs_disable(struct phylink_pcs *pcs) -+{ -+ struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs); -+ -+ wp->wrapped_pcs->ops->pcs_disable(wp->wrapped_pcs); -+ -+ wp->eth->usxgmii_pcs[wp->id]->interface = PHY_INTERFACE_MODE_NA; -+} -+ -+static const struct phylink_pcs_ops mtk_sgmii_wrapped_pcs_ops = { -+ .pcs_get_state = mtk_sgmii_wrapped_pcs_get_state, -+ .pcs_config = mtk_sgmii_wrapped_pcs_config, -+ .pcs_an_restart = mtk_sgmii_wrapped_pcs_an_restart, -+ .pcs_link_up = mtk_sgmii_wrapped_pcs_link_up, -+ .pcs_disable = mtk_sgmii_wrapped_pcs_disable, -+}; -+ -+static int mtk_sgmii_wrapper_init(struct mtk_eth *eth) -+{ -+ struct mtk_sgmii_wrapper_pcs *wp; -+ int i; -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ if (!eth->sgmii_pcs[i]) -+ continue; -+ -+ if (!eth->usxgmii_pcs[i]) -+ continue; -+ -+ /* Make sure all PCS ops are supported by wrapped PCS */ -+ if (!eth->sgmii_pcs[i]->ops->pcs_get_state || -+ !eth->sgmii_pcs[i]->ops->pcs_config || -+ !eth->sgmii_pcs[i]->ops->pcs_an_restart || -+ !eth->sgmii_pcs[i]->ops->pcs_link_up || -+ !eth->sgmii_pcs[i]->ops->pcs_disable) -+ return -EOPNOTSUPP; -+ -+ wp = devm_kzalloc(eth->dev, sizeof(*wp), GFP_KERNEL); -+ if (!wp) -+ return -ENOMEM; -+ -+ wp->wrapped_pcs = eth->sgmii_pcs[i]; -+ wp->id = i; -+ wp->pcs.poll = true; -+ wp->pcs.ops = &mtk_sgmii_wrapped_pcs_ops; -+ wp->eth = eth; -+ -+ eth->usxgmii_pcs[i]->wrapped_sgmii_pcs = &wp->pcs; -+ } -+ -+ return 0; -+} -+ -+struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int mac_id) -+{ -+ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id); -+ -+ if (!eth->usxgmii_pcs[xgmii_id]) -+ return NULL; -+ -+ return eth->usxgmii_pcs[xgmii_id]->wrapped_sgmii_pcs; -+} -+ -+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ struct mtk_eth *eth = mpcs->eth; -+ struct regmap *pextp = eth->regmap_pextp[mpcs->id]; -+ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0; -+ bool mode_changed = false; -+ -+ if (!pextp) -+ return -ENODEV; -+ -+ if (interface == PHY_INTERFACE_MODE_USXGMII) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE; -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G); -+ } else if (interface == PHY_INTERFACE_MODE_10GBASER) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF); -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G); -+ adapt_mode = USXGMII_RATE_UPDATE_MODE; -+ } else if (interface == PHY_INTERFACE_MODE_5GBASER) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF); -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_5G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_5G); -+ adapt_mode = USXGMII_RATE_UPDATE_MODE; -+ } else { -+ return -EINVAL; -+ } -+ -+ adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1); -+ -+ if (mpcs->interface != interface) { -+ mpcs->interface = interface; -+ mode_changed = true; -+ } -+ -+ mtk_xfi_pll_enable(eth); -+ mtk_usxgmii_reset(eth, mpcs->id); -+ -+ /* Setup USXGMII AN ctrl */ -+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0, -+ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, -+ an_ctrl); -+ -+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2, -+ USXGMII_LINK_TIMER_IDLE_DETECT | -+ USXGMII_LINK_TIMER_COMP_ACK_DETECT | -+ USXGMII_LINK_TIMER_AN_RESTART, -+ link_timer); -+ -+ mpcs->mode = mode; -+ -+ /* Gated MAC CK */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED); -+ -+ /* Enable interface force mode */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN); -+ -+ /* Setup USXGMII adapt mode */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE, -+ adapt_mode); -+ -+ /* Setup USXGMII speed */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE, -+ xfi_mode); -+ -+ usleep_range(1, 10); -+ -+ /* Un-gated MAC CK */ -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_MAC_CK_GATED, 0); -+ -+ usleep_range(1, 10); -+ -+ /* Disable interface force mode for the AN mode */ -+ if (an_ctrl & USXGMII_AN_ENABLE) -+ regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_IF_FORCE_EN, 0); -+ -+ /* Setup USXGMIISYS with the determined property */ -+ mtk_usxgmii_setup_phya(pextp, interface, mpcs->id); -+ -+ return mode_changed; -+} -+ -+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ struct mtk_eth *eth = mpcs->eth; -+ struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)]; -+ u32 val = 0; -+ -+ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val); -+ if (FIELD_GET(USXGMII_AN_ENABLE, val)) { -+ /* Refresh LPA by inverting LPA_LATCH */ -+ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val); -+ regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0, -+ USXGMII_LPA_LATCH, -+ !(val & USXGMII_LPA_LATCH)); -+ -+ regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val); -+ -+ phylink_decode_usxgmii_word(state, FIELD_GET(USXGMII_PCS_AN_WORD, -+ val)); -+ -+ state->interface = mpcs->interface; -+ } else { -+ val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id)); -+ -+ if (mac->id == MTK_GMAC2_ID) -+ val >>= 16; -+ -+ switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) { -+ case 0: -+ state->speed = SPEED_10000; -+ break; -+ case 1: -+ state->speed = SPEED_5000; -+ break; -+ case 2: -+ state->speed = SPEED_2500; -+ break; -+ case 3: -+ state->speed = SPEED_1000; -+ break; -+ } -+ -+ state->interface = mpcs->interface; -+ state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val); -+ state->duplex = DUPLEX_FULL; -+ } -+ -+ /* Continuously repeat re-configuration sequence until link comes up */ -+ if (state->link == 0) -+ mtk_usxgmii_pcs_config(pcs, mpcs->mode, -+ state->interface, NULL, false); -+} -+ -+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ unsigned int val = 0; -+ -+ if (!mpcs->regmap) -+ return; -+ -+ regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val); -+ val |= USXGMII_AN_RESTART; -+ regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val); -+} -+ -+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ int speed, int duplex) -+{ -+ /* Reconfiguring USXGMII to ensure the quality of the RX signal -+ * after the line side link up. -+ */ -+ mtk_usxgmii_pcs_config(pcs, mode, -+ interface, NULL, false); -+} -+ -+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { -+ .pcs_config = mtk_usxgmii_pcs_config, -+ .pcs_get_state = mtk_usxgmii_pcs_get_state, -+ .pcs_an_restart = mtk_usxgmii_pcs_restart_an, -+ .pcs_link_up = mtk_usxgmii_pcs_link_up, -+}; -+ -+int mtk_usxgmii_init(struct mtk_eth *eth) -+{ -+ struct device_node *r = eth->dev->of_node; -+ struct device *dev = eth->dev; -+ struct device_node *np; -+ int i, ret; -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ np = of_parse_phandle(r, "mediatek,usxgmiisys", i); -+ if (!np) -+ break; -+ -+ eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs[i]), GFP_KERNEL); -+ if (!eth->usxgmii_pcs[i]) -+ return -ENOMEM; -+ -+ eth->usxgmii_pcs[i]->id = i; -+ eth->usxgmii_pcs[i]->eth = eth; -+ eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np); -+ if (IS_ERR(eth->usxgmii_pcs[i]->regmap)) -+ return PTR_ERR(eth->usxgmii_pcs[i]->regmap); -+ -+ eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops; -+ eth->usxgmii_pcs[i]->pcs.poll = true; -+ eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA; -+ eth->usxgmii_pcs[i]->mode = -1; -+ -+ of_node_put(np); -+ } -+ -+ ret = mtk_xfi_pextp_init(eth); -+ if (ret) -+ return ret; -+ -+ ret = mtk_xfi_pll_init(eth); -+ if (ret) -+ return ret; -+ -+ ret = mtk_toprgu_init(eth); -+ if (ret) -+ return ret; -+ -+ return mtk_sgmii_wrapper_init(eth); -+} -+ -+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id) -+{ -+ u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id); -+ -+ if (!eth->usxgmii_pcs[xgmii_id]->regmap) -+ return NULL; -+ -+ return ð->usxgmii_pcs[xgmii_id]->pcs; -+} diff --git a/target/linux/generic/pending-5.15/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch b/target/linux/generic/pending-5.15/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch deleted file mode 100644 index dda864ab4df022..00000000000000 --- a/target/linux/generic/pending-5.15/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch +++ /dev/null @@ -1,46 +0,0 @@ -From dee3f591103910c8d8b2a6d57879ccd2a4be4b10 Mon Sep 17 00:00:00 2001 -Message-ID: -From: Daniel Golle -Date: Wed, 24 Jan 2024 03:19:49 +0000 -Subject: [PATCH net] net: ethernet: mtk_eth_soc: set coherent mask to get PPE - working -To: Felix Fietkau , - Sean Wang , - Mark Lee , - Lorenzo Bianconi , - David S. Miller , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Matthias Brugger , - AngeloGioacchino Del Regno , - Daniel Golle , - netdev@vger.kernel.org, - linux-kernel@vger.kernel.org, - linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org - -Set DMA coherent mask to 32-bit which makes PPE offloading engine start -working on BPi-R4 which got 4 GiB of RAM. - -Fixes: 2d75891ebc09 ("net: ethernet: mtk_eth_soc: support 36-bit DMA addressing on MT7988") -Suggested-by: Elad Yifee -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4832,7 +4832,10 @@ static int mtk_probe(struct platform_dev - } - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { -- err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); -+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36)); -+ if (!err) -+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); -+ - if (err) { - dev_err(&pdev->dev, "Wrong DMA config\n"); - return -EINVAL; diff --git a/target/linux/generic/pending-5.15/740-net-phy-motorcomm-Add-missing-include.patch b/target/linux/generic/pending-5.15/740-net-phy-motorcomm-Add-missing-include.patch deleted file mode 100644 index 2a1f908cfb32e6..00000000000000 --- a/target/linux/generic/pending-5.15/740-net-phy-motorcomm-Add-missing-include.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 6f291aa7da199c6486cc229b055dcbcd5cee7a21 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Sun, 21 May 2023 22:24:56 +0200 -Subject: [PATCH] net: phy: motorcomm: Add missing include - -Directly include linux/bitfield.h which provides FIELD_PREP. - -Signed-off-by: Hauke Mehrtens ---- - drivers/net/phy/motorcomm.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -6,6 +6,7 @@ - * Author: Frank - */ - -+#include - #include - #include - #include diff --git a/target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch b/target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch deleted file mode 100644 index ec3e57031bcce5..00000000000000 --- a/target/linux/generic/pending-5.15/750-skb-Do-mix-page-pool-and-page-referenced-frags-in-GR.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Alexander Duyck -Date: Thu, 26 Jan 2023 11:06:59 -0800 -Subject: [PATCH] skb: Do mix page pool and page referenced frags in GRO - -GSO should not merge page pool recycled frames with standard reference -counted frames. Traditionally this didn't occur, at least not often. -However as we start looking at adding support for wireless adapters there -becomes the potential to mix the two due to A-MSDU repartitioning frames in -the receive path. There are possibly other places where this may have -occurred however I suspect they must be few and far between as we have not -seen this issue until now. - -Fixes: 53e0961da1c7 ("page_pool: add frag page recycling support in page pool") -Reported-by: Felix Fietkau -Signed-off-by: Alexander Duyck ---- - ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -4371,6 +4371,15 @@ int skb_gro_receive(struct sk_buff *p, s - if (unlikely(p->len + len >= 65536 || NAPI_GRO_CB(skb)->flush)) - return -E2BIG; - -+ /* Do not splice page pool based packets w/ non-page pool -+ * packets. This can result in reference count issues as page -+ * pool pages will not decrement the reference count and will -+ * instead be immediately returned to the pool or have frag -+ * count decremented. -+ */ -+ if (p->pp_recycle != skb->pp_recycle) -+ return -ETOOMANYREFS; -+ - lp = NAPI_GRO_CB(p)->last; - pinfo = skb_shinfo(lp); - diff --git a/target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch b/target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch deleted file mode 100644 index 1d1b168e0725da..00000000000000 --- a/target/linux/generic/pending-5.15/760-net-core-add-optional-threading-for-backlog-processi.patch +++ /dev/null @@ -1,232 +0,0 @@ -From: Felix Fietkau -Date: Thu, 16 Feb 2023 18:39:04 +0100 -Subject: [PATCH] net/core: add optional threading for backlog processing - -When dealing with few flows or an imbalance on CPU utilization, static RPS -CPU assignment can be too inflexible. Add support for enabling threaded NAPI -for backlog processing in order to allow the scheduler to better balance -processing. This helps better spread the load across idle CPUs. - -Signed-off-by: Felix Fietkau ---- - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -502,6 +502,7 @@ static inline bool napi_complete(struct - } - - int dev_set_threaded(struct net_device *dev, bool threaded); -+int backlog_set_threaded(bool threaded); - - /** - * napi_disable - prevent NAPI from scheduling -@@ -3364,6 +3365,7 @@ struct softnet_data { - unsigned int processed; - unsigned int time_squeeze; - unsigned int received_rps; -+ unsigned int process_queue_empty; - #ifdef CONFIG_RPS - struct softnet_data *rps_ipi_list; - #endif ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -4586,7 +4586,7 @@ static int rps_ipi_queued(struct softnet - #ifdef CONFIG_RPS - struct softnet_data *mysd = this_cpu_ptr(&softnet_data); - -- if (sd != mysd) { -+ if (sd != mysd && !test_bit(NAPI_STATE_THREADED, &sd->backlog.state)) { - sd->rps_ipi_next = mysd->rps_ipi_list; - mysd->rps_ipi_list = sd; - -@@ -5767,6 +5767,8 @@ static DEFINE_PER_CPU(struct work_struct - /* Network device is going away, flush any packets still pending */ - static void flush_backlog(struct work_struct *work) - { -+ unsigned int process_queue_empty; -+ bool threaded, flush_processq; - struct sk_buff *skb, *tmp; - struct softnet_data *sd; - -@@ -5782,9 +5784,18 @@ static void flush_backlog(struct work_st - input_queue_head_incr(sd); - } - } -+ -+ threaded = test_bit(NAPI_STATE_THREADED, &sd->backlog.state); -+ flush_processq = threaded && -+ !skb_queue_empty_lockless(&sd->process_queue); -+ if (flush_processq) -+ process_queue_empty = sd->process_queue_empty; - rps_unlock(sd); - local_irq_enable(); - -+ if (threaded) -+ goto out; -+ - skb_queue_walk_safe(&sd->process_queue, skb, tmp) { - if (skb->dev->reg_state == NETREG_UNREGISTERING) { - __skb_unlink(skb, &sd->process_queue); -@@ -5792,7 +5803,18 @@ static void flush_backlog(struct work_st - input_queue_head_incr(sd); - } - } -+ -+out: - local_bh_enable(); -+ -+ while (flush_processq) { -+ msleep(1); -+ local_irq_disable(); -+ rps_lock(sd); -+ flush_processq = process_queue_empty == sd->process_queue_empty; -+ rps_unlock(sd); -+ local_irq_enable(); -+ } - } - - static bool flush_required(int cpu) -@@ -6475,6 +6497,7 @@ static int process_backlog(struct napi_s - - local_irq_disable(); - rps_lock(sd); -+ sd->process_queue_empty++; - if (skb_queue_empty(&sd->input_pkt_queue)) { - /* - * Inline a custom version of __napi_complete(). -@@ -6484,7 +6507,8 @@ static int process_backlog(struct napi_s - * We can use a plain write instead of clear_bit(), - * and we dont need an smp_mb() memory barrier. - */ -- napi->state = 0; -+ napi->state &= ~(NAPIF_STATE_SCHED | -+ NAPIF_STATE_SCHED_THREADED); - again = false; - } else { - skb_queue_splice_tail_init(&sd->input_pkt_queue, -@@ -6901,6 +6925,57 @@ int dev_set_threaded(struct net_device * - } - EXPORT_SYMBOL(dev_set_threaded); - -+int backlog_set_threaded(bool threaded) -+{ -+ static bool backlog_threaded; -+ int err = 0; -+ int i; -+ -+ if (backlog_threaded == threaded) -+ return 0; -+ -+ for_each_possible_cpu(i) { -+ struct softnet_data *sd = &per_cpu(softnet_data, i); -+ struct napi_struct *n = &sd->backlog; -+ -+ if (n->thread) -+ continue; -+ n->thread = kthread_run(napi_threaded_poll, n, "napi/backlog-%d", i); -+ if (IS_ERR(n->thread)) { -+ err = PTR_ERR(n->thread); -+ pr_err("kthread_run failed with err %d\n", err); -+ n->thread = NULL; -+ threaded = false; -+ break; -+ } -+ -+ } -+ -+ backlog_threaded = threaded; -+ -+ /* Make sure kthread is created before THREADED bit -+ * is set. -+ */ -+ smp_mb__before_atomic(); -+ -+ for_each_possible_cpu(i) { -+ struct softnet_data *sd = &per_cpu(softnet_data, i); -+ struct napi_struct *n = &sd->backlog; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ rps_lock(sd); -+ if (threaded) -+ n->state |= NAPIF_STATE_THREADED; -+ else -+ n->state &= ~NAPIF_STATE_THREADED; -+ rps_unlock(sd); -+ local_irq_restore(flags); -+ } -+ -+ return err; -+} -+ - void netif_napi_add(struct net_device *dev, struct napi_struct *napi, - int (*poll)(struct napi_struct *, int), int weight) - { -@@ -11385,6 +11460,9 @@ static int dev_cpu_dead(unsigned int old - raise_softirq_irqoff(NET_TX_SOFTIRQ); - local_irq_enable(); - -+ if (test_bit(NAPI_STATE_THREADED, &oldsd->backlog.state)) -+ return 0; -+ - #ifdef CONFIG_RPS - remsd = oldsd->rps_ipi_list; - oldsd->rps_ipi_list = NULL; -@@ -11724,6 +11802,7 @@ static int __init net_dev_init(void) - sd->cpu = i; - #endif - -+ INIT_LIST_HEAD(&sd->backlog.poll_list); - init_gro_hash(&sd->backlog); - sd->backlog.poll = process_backlog; - sd->backlog.weight = weight_p; ---- a/net/core/sysctl_net_core.c -+++ b/net/core/sysctl_net_core.c -@@ -28,6 +28,7 @@ static int int_3600 = 3600; - static int min_sndbuf = SOCK_MIN_SNDBUF; - static int min_rcvbuf = SOCK_MIN_RCVBUF; - static int max_skb_frags = MAX_SKB_FRAGS; -+static int backlog_threaded; - static long long_one __maybe_unused = 1; - static long long_max __maybe_unused = LONG_MAX; - -@@ -114,6 +115,23 @@ static int rps_sock_flow_sysctl(struct c - } - #endif /* CONFIG_RPS */ - -+static int backlog_threaded_sysctl(struct ctl_table *table, int write, -+ void *buffer, size_t *lenp, loff_t *ppos) -+{ -+ static DEFINE_MUTEX(backlog_threaded_mutex); -+ int ret; -+ -+ mutex_lock(&backlog_threaded_mutex); -+ -+ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); -+ if (write && !ret) -+ ret = backlog_set_threaded(backlog_threaded); -+ -+ mutex_unlock(&backlog_threaded_mutex); -+ -+ return ret; -+} -+ - #ifdef CONFIG_NET_FLOW_LIMIT - static DEFINE_MUTEX(flow_limit_update_mutex); - -@@ -470,6 +488,15 @@ static struct ctl_table net_core_table[] - .proc_handler = rps_sock_flow_sysctl - }, - #endif -+ { -+ .procname = "backlog_threaded", -+ .data = &backlog_threaded, -+ .maxlen = sizeof(unsigned int), -+ .mode = 0644, -+ .proc_handler = backlog_threaded_sysctl, -+ .extra1 = SYSCTL_ZERO, -+ .extra2 = SYSCTL_ONE -+ }, - #ifdef CONFIG_NET_FLOW_LIMIT - { - .procname = "flow_limit_cpu_bitmap", diff --git a/target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch deleted file mode 100644 index 4f322da4fcabd1..00000000000000 --- a/target/linux/generic/pending-5.15/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Tobias Waldekranz -Subject: [RFC net-next 7/7] net: dsa: mv88e6xxx: Request assisted learning on CPU port -Date: Sat, 16 Jan 2021 02:25:15 +0100 -Archived-At: - -While the hardware is capable of performing learning on the CPU port, -it requires alot of additions to the bridge's forwarding path in order -to handle multi-destination traffic correctly. - -Until that is in place, opt for the next best thing and let DSA sync -the relevant addresses down to the hardware FDB. - -Signed-off-by: Tobias Waldekranz ---- - drivers/net/dsa/mv88e6xxx/chip.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -6435,6 +6435,7 @@ static int mv88e6xxx_register_switch(str - ds->ops = &mv88e6xxx_switch_ops; - ds->ageing_time_min = chip->info->age_time_coeff; - ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; -+ ds->assisted_learning_on_cpu_port = true; - - /* Some chips support up to 32, but that requires enabling the - * 5-bit port mode, which we do not support. 640k^W16 ought to diff --git a/target/linux/generic/pending-5.15/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch b/target/linux/generic/pending-5.15/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch deleted file mode 100644 index ca963d1260c538..00000000000000 --- a/target/linux/generic/pending-5.15/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch +++ /dev/null @@ -1,174 +0,0 @@ -From patchwork Sun Mar 19 22:08:05 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13180645 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id A7A46C6FD1F - for ; Sun, 19 Mar 2023 22:08:15 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S230223AbjCSWIN (ORCPT ); - Sun, 19 Mar 2023 18:08:13 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32878 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S229565AbjCSWIM (ORCPT - ); Sun, 19 Mar 2023 18:08:12 -0400 -Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com - [IPv6:2a00:1450:4864:20::42e]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 605D3E062; - Sun, 19 Mar 2023 15:08:10 -0700 (PDT) -Received: by mail-wr1-x42e.google.com with SMTP id h17so8695188wrt.8; - Sun, 19 Mar 2023 15:08:10 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679263689; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=GmPK75Q9ZD3h3IYflWYuDwS99V2e532KgDlnNucAoJg=; - b=PSdrywW48P4Lq8z9wOSPXFB/ZdO/JfuyiGlw3Gz1Iriy+Smo/cBnJ0Ve9zKkX3AKTO - Tr7/g8xhSQX8sU5WAOEPC13uVjKpO4VZsamXHTmMKL4mmfII3K/piAsQcMQkkNpgouab - Ci9yr+7ASSmqEUHIbYTM6sl6a47rPwqk3b3DcTIE2CwJsPPNXnpQ/aSVbJAcEdhcZICc - X4rAmjrYjcsl8coFIGHHPlrMH9ShekQWxB84vEb6bO1nXOORNPizOHuY1vJ3wa3WgXsx - YwlvutMFVIUXfgL2ZwCmQAKWJPiAaFk+CCk3oxSeOYoAzkjcbMyapz9VnooStfvR2aV3 - k+2g== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679263689; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=GmPK75Q9ZD3h3IYflWYuDwS99V2e532KgDlnNucAoJg=; - b=NGjqrGERyaxRwINtevHaY97h9X9W+1UY62YYwotqwv5+cfvB8myjBbD3WH2WzaqMes - o9MMER9RE8/arW3jIVlBv4ORDUuEZ7AeGgy5UbFyQZIPHlp+hJ/sxFrGvYUwamg4Qrr9 - ojargh8ORsEiMeqaf+5AkmEagNhrrV3ax0pUuWDzbJ3vXGoHjfCetHz5xyNL46dvXBfb - l/OZqjv9IYob552uUoUmCy/TbEQDqvmjkFrROFK9gtBNxgxUJkwbyiWIOVsf6RR8OarP - f7bbvSJYkvTvzx2u/g0Up7NW5ZyihMGBmDs377M3yW6AnSxW6jlfl30QmMU1aEigYXvy - v3mA== -X-Gm-Message-State: AO0yUKUm1PYmYa4xlHuVD23mZcZm83a+xbhcbs0Xryi3yF/+UnjM4Cho - GAfqSh5MZ/rlOAm3Vnpn//9hOG5Lc8vLYg== -X-Google-Smtp-Source: - AK7set+5pTahGGgk1hF/mHGkGBhsMf0//oQjZd4QFHx+HaeSgP5f6q7g0bRUcTX8kRtgHH0T7l1/hQ== -X-Received: by 2002:a5d:474f:0:b0:2d6:2ae8:70d with SMTP id - o15-20020a5d474f000000b002d62ae8070dmr2382593wrs.39.1679263688549; - Sun, 19 Mar 2023 15:08:08 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - d6-20020a5d6dc6000000b002c53f6c7599sm7354727wrz.29.2023.03.19.15.08.07 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Sun, 19 Mar 2023 15:08:07 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, - olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, - linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v2] net: dsa: b53: add support for BCM63xx RGMIIs -Date: Sun, 19 Mar 2023 23:08:05 +0100 -Message-Id: <20230319220805.124024-1-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230319183330.761251-1-noltari@gmail.com> -References: <20230319183330.761251-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -BCM63xx RGMII ports require additional configuration in order to work. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Andrew Lunn ---- - v2: add changes suggested by Andrew: - - Use a switch statement. - - Use dev_dbg() instead of dev_info(). - - drivers/net/dsa/b53/b53_common.c | 46 ++++++++++++++++++++++++++++++++ - drivers/net/dsa/b53/b53_priv.h | 1 + - 2 files changed, 47 insertions(+) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -1209,6 +1209,46 @@ static void b53_force_port_config(struct - b53_write8(dev, B53_CTRL_PAGE, off, reg); - } - -+static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port, -+ phy_interface_t interface) -+{ -+ struct b53_device *dev = ds->priv; -+ u8 rgmii_ctrl = 0, off; -+ -+ if (port == dev->imp_port) -+ off = B53_RGMII_CTRL_IMP; -+ else -+ off = B53_RGMII_CTRL_P(port); -+ -+ b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl); -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ rgmii_ctrl |= (RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC); -+ break; -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_TXC); -+ rgmii_ctrl |= RGMII_CTRL_DLL_RXC; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC); -+ rgmii_ctrl |= RGMII_CTRL_DLL_TXC; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ default: -+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC); -+ break; -+ } -+ -+ if (port != dev->imp_port) -+ rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII; -+ -+ b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl); -+ -+ dev_dbg(ds->dev, "Configured port %d for %s\n", port, -+ phy_modes(interface)); -+} -+ - static void b53_adjust_link(struct dsa_switch *ds, int port, - struct phy_device *phydev) - { -@@ -1235,6 +1275,9 @@ static void b53_adjust_link(struct dsa_s - tx_pause, rx_pause); - b53_force_link(dev, port, phydev->link); - -+ if (is63xx(dev) && port >= B53_63XX_RGMII0) -+ b53_adjust_63xx_rgmii(ds, port, phydev->interface); -+ - if (is531x5(dev) && phy_interface_is_rgmii(phydev)) { - if (port == dev->imp_port) - off = B53_RGMII_CTRL_IMP; -@@ -1419,6 +1462,9 @@ void b53_phylink_mac_link_up(struct dsa_ - { - struct b53_device *dev = ds->priv; - -+ if (is63xx(dev) && port >= B53_63XX_RGMII0) -+ b53_adjust_63xx_rgmii(ds, port, interface); -+ - if (mode == MLO_AN_PHY) - return; - ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -206,6 +206,7 @@ static inline int is58xx(struct b53_devi - dev->chip_id == BCM7278_DEVICE_ID; - } - -+#define B53_63XX_RGMII0 4 - #define B53_CPU_PORT_25 5 - #define B53_CPU_PORT 8 - diff --git a/target/linux/generic/pending-5.15/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch b/target/linux/generic/pending-5.15/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch deleted file mode 100644 index e2da4e7f0552a6..00000000000000 --- a/target/linux/generic/pending-5.15/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch +++ /dev/null @@ -1,108 +0,0 @@ -From patchwork Tue Mar 21 17:33:57 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13183003 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 823A1C761AF - for ; Tue, 21 Mar 2023 17:35:06 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S230490AbjCURfE (ORCPT ); - Tue, 21 Mar 2023 13:35:04 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47440 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S230357AbjCURex (ORCPT - ); Tue, 21 Mar 2023 13:34:53 -0400 -Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com - [IPv6:2a00:1450:4864:20::430]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9A45559D8; - Tue, 21 Mar 2023 10:34:26 -0700 (PDT) -Received: by mail-wr1-x430.google.com with SMTP id m2so14547588wrh.6; - Tue, 21 Mar 2023 10:34:26 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679420063; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=cUvnluVaZPzfEQB9fMRuYo+4/361t/7po7nyUBBJfxc=; - b=F0pa8JmQZ1FeXVtdpCygur8UmLrgKwxCcjaMn312u5zNvsXsEPeCAIDqP2tvNNTwv/ - UYjaNaoZ77HSvv/gSqeG808AXGyNs1PvLuHZYuUTJRNuLaMixKtkNFi4ypheCdk0WCiE - IWz0DIm6ojmdwMqafDUKQ6Qwkv5R0vo8Wh5vpjimEmCelOyMvfuLZNqubsiGqpnCguBp - uWlmKh95/VubCGgiGG2xK1IXQayL14ENuWseDds7nVpVK50NycrFgJbL17Bd6qJKYkbo - m70IC+9jM0hjwKXpyi6ipCBNcW+1E6JIwILVC04Xi+BTpOGhbUAQ59Yn2hyq7tQM7dzs - 4PLg== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679420063; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=cUvnluVaZPzfEQB9fMRuYo+4/361t/7po7nyUBBJfxc=; - b=SCX78yTuGjdnE5nuL0p7+kxGnOzsCExsigLdaV+x/JswmwxSpZvxn223i1yM95klj9 - Rk0RnXqATLF1wZA7L1YmbeZ66zxUwW/osnCjJHPeEF8AGgjK/qawtLl/HJQHN67NaRNQ - bDsRn2nWQ2GRTRFpvD+iGRy4uyQCDu9HFxLbn43fBsBmRnXWGPQP5cEb90tL83/Onp4D - Lx/XcyZOh9QRfJNhj+G1BAeRCLRA/sdA0W3Ecu5SCFs+LtS6uvLVGWDKEDfnZhYY8Xqf - Mx9evWzdW2OorEN2FI6+xTglvnEBcVhHIJ7XEGAhCG6ocgMZeck++774S8RWumWl8xpy - /K9Q== -X-Gm-Message-State: AO0yUKUORAlGfbkNwnYmQnTWcGPqW6sp4g9WfgQmRZGCV+9tCB0OebSP - ICq6v4YPmUPNRl/WNnVCbps= -X-Google-Smtp-Source: - AK7set8pFDl8fHRwGPhAguqxIfqnQ4PY+b57IHEsybIaQ/HPNwdJ1cs1+IPBGHe3TL14dTS4aVNpHA== -X-Received: by 2002:a5d:6991:0:b0:2ce:aab5:f96b with SMTP id - g17-20020a5d6991000000b002ceaab5f96bmr2965175wru.67.1679420062764; - Tue, 21 Mar 2023 10:34:22 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.21 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Tue, 21 Mar 2023 10:34:21 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, - olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v2 2/4] net: dsa: b53: mmap: add more 63xx SoCs -Date: Tue, 21 Mar 2023 18:33:57 +0100 -Message-Id: <20230321173359.251778-3-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230321173359.251778-1-noltari@gmail.com> -References: <20230320155024.164523-1-noltari@gmail.com> - <20230321173359.251778-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -BCM6318, BCM6362 and BCM63268 are SoCs with a B53 MMAP switch. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Florian Fainelli ---- - v2: no changes. - - drivers/net/dsa/b53/b53_mmap.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/dsa/b53/b53_mmap.c -+++ b/drivers/net/dsa/b53/b53_mmap.c -@@ -347,8 +347,11 @@ static void b53_mmap_shutdown(struct pla - - static const struct of_device_id b53_mmap_of_table[] = { - { .compatible = "brcm,bcm3384-switch" }, -+ { .compatible = "brcm,bcm6318-switch" }, - { .compatible = "brcm,bcm6328-switch" }, -+ { .compatible = "brcm,bcm6362-switch" }, - { .compatible = "brcm,bcm6368-switch" }, -+ { .compatible = "brcm,bcm63268-switch" }, - { .compatible = "brcm,bcm63xx-switch" }, - { /* sentinel */ }, - }; diff --git a/target/linux/generic/pending-5.15/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch b/target/linux/generic/pending-5.15/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch deleted file mode 100644 index 456643f05d6d31..00000000000000 --- a/target/linux/generic/pending-5.15/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch +++ /dev/null @@ -1,195 +0,0 @@ -From patchwork Tue Mar 21 17:33:58 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13183004 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id B2B12C74A5B - for ; Tue, 21 Mar 2023 17:35:12 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S230297AbjCURfK (ORCPT ); - Tue, 21 Mar 2023 13:35:10 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47438 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S230374AbjCURex (ORCPT - ); Tue, 21 Mar 2023 13:34:53 -0400 -Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com - [IPv6:2a00:1450:4864:20::432]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C906B5550A; - Tue, 21 Mar 2023 10:34:26 -0700 (PDT) -Received: by mail-wr1-x432.google.com with SMTP id y14so14546846wrq.4; - Tue, 21 Mar 2023 10:34:26 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679420064; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=vnvnwWc5Tmg09HBQo/m9RbRM6yM8KLx8r1VA+Abfg3k=; - b=eFv+mwe94Y2YZMiJP5gydXVrGlbIAR5HCrY0rdcoGoMPzQUHLFckZeYCgEKudI55I7 - gMLZYCtLwvDXvKeHM2AUigsq2YuJSeF5QwICPrhTnMwUGBg4yyyltrc3+J0lSd6/4kQv - h0yM1Oo4v0d8CuqjBU6bXienIk34AFVJfsPq+vWQTjAbUL7ht4WHZ2Ez2MFoTvZpkIJA - 5iWMyVoMbugZl6eqNRjvDHFmtBtrZIv8AFs10r2Ca6+Yxm+aq0v33DRkbSVVqgFPNEzy - q5QOXOeLBPL6BvyovOpmVSWGoHf1zFV7lrzcqi+uc+FuYxQ9dyN3ND73DrrhWSkLaSg9 - r8yA== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679420064; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=vnvnwWc5Tmg09HBQo/m9RbRM6yM8KLx8r1VA+Abfg3k=; - b=jIRB8pIlrLA/ovhnEoePs/6SX8fn6l7l4fY2CxX2pLrTbP1JI8AAetPavvrNVQTr2M - Vm0iLbKyL/VpTq9+bSN1SMjaoi4lAMj0pgafoHrwABMVZpFauYvtCfSYTstZ2pw4Dr1j - wYQGj3BUSpFIYHtSIDMkb5449WA3T3TONhaQLRFAUCBD6gAFyEky5fY+DIHrGaj352B6 - 9ST/tkqHgPpuFlmromr42KQWoTFU+Pj0Uhyp7ru4BsnF7tTshWroZZIHUJmSACudEadr - fBPiuurX9jgp9zNqj8Oy0HjiVUnULFCapj8yICGp5s44uDAK/XFqFXpOuJ8ptS6uPazU - xUwg== -X-Gm-Message-State: AO0yUKX2w6QZfaGDHtlZAlY/U8F8VuJa3HwlgXbxgGChgdgvIoFThawv - oDyFAhWbVfe4DxwXTwxgJ/I= -X-Google-Smtp-Source: - AK7set+sH60XiJYup7bqrZTzFJVNe1YGcX/UTfjWV9xfGwNyodc34cHvKpqNagw5J+vEpv6CKvNHaA== -X-Received: by 2002:adf:f344:0:b0:2cd:de25:1c76 with SMTP id - e4-20020adff344000000b002cdde251c76mr12989754wrp.17.1679420064464; - Tue, 21 Mar 2023 10:34:24 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.22 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Tue, 21 Mar 2023 10:34:23 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, - olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v2 3/4] net: dsa: b53: mmap: allow passing a chip ID -Date: Tue, 21 Mar 2023 18:33:58 +0100 -Message-Id: <20230321173359.251778-4-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230321173359.251778-1-noltari@gmail.com> -References: <20230320155024.164523-1-noltari@gmail.com> - <20230321173359.251778-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -BCM6318 and BCM63268 SoCs require a special handling for their RGMIIs, so we -should be able to identify them as a special BCM63xx switch. - -Signed-off-by: Álvaro Fernández Rojas ---- - v2: - - Add missing chip to b53_switch_chips[]. - - Fix device_get_match_data() casting warning. - - Add BCM63268_DEVICE_ID to BCM6318 too. - - Add BCM6318 in commit description. - - drivers/net/dsa/b53/b53_common.c | 13 +++++++++++++ - drivers/net/dsa/b53/b53_mmap.c | 32 +++++++++++++++++++++++--------- - drivers/net/dsa/b53/b53_priv.h | 9 ++++++++- - 3 files changed, 44 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -2461,6 +2461,19 @@ static const struct b53_chip_data b53_sw - .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, - }, - { -+ .chip_id = BCM63268_DEVICE_ID, -+ .dev_name = "BCM63268", -+ .vlans = 4096, -+ .enabled_ports = 0, /* pdata must provide them */ -+ .arl_bins = 4, -+ .arl_buckets = 1024, -+ .imp_port = 8, -+ .vta_regs = B53_VTA_REGS_63XX, -+ .duplex_reg = B53_DUPLEX_STAT_63XX, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, -+ }, -+ { - .chip_id = BCM53010_DEVICE_ID, - .dev_name = "BCM53010", - .vlans = 4096, ---- a/drivers/net/dsa/b53/b53_mmap.c -+++ b/drivers/net/dsa/b53/b53_mmap.c -@@ -262,7 +262,7 @@ static int b53_mmap_probe_of(struct plat - return -ENOMEM; - - pdata->regs = mem; -- pdata->chip_id = BCM63XX_DEVICE_ID; -+ pdata->chip_id = (u32)(unsigned long)device_get_match_data(dev); - pdata->big_endian = of_property_read_bool(np, "big-endian"); - - of_ports = of_get_child_by_name(np, "ports"); -@@ -346,14 +346,28 @@ static void b53_mmap_shutdown(struct pla - } - - static const struct of_device_id b53_mmap_of_table[] = { -- { .compatible = "brcm,bcm3384-switch" }, -- { .compatible = "brcm,bcm6318-switch" }, -- { .compatible = "brcm,bcm6328-switch" }, -- { .compatible = "brcm,bcm6362-switch" }, -- { .compatible = "brcm,bcm6368-switch" }, -- { .compatible = "brcm,bcm63268-switch" }, -- { .compatible = "brcm,bcm63xx-switch" }, -- { /* sentinel */ }, -+ { -+ .compatible = "brcm,bcm3384-switch", -+ .data = (void *)BCM63XX_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm6318-switch", -+ .data = (void *)BCM63268_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm6328-switch", -+ .data = (void *)BCM63XX_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm6362-switch", -+ .data = (void *)BCM63XX_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm6368-switch", -+ .data = (void *)BCM63XX_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm63268-switch", -+ .data = (void *)BCM63268_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm63xx-switch", -+ .data = (void *)BCM63XX_DEVICE_ID, -+ }, { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, b53_mmap_of_table); - ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -75,6 +75,7 @@ enum { - BCM53125_DEVICE_ID = 0x53125, - BCM53128_DEVICE_ID = 0x53128, - BCM63XX_DEVICE_ID = 0x6300, -+ BCM63268_DEVICE_ID = 0x63268, - BCM53010_DEVICE_ID = 0x53010, - BCM53011_DEVICE_ID = 0x53011, - BCM53012_DEVICE_ID = 0x53012, -@@ -186,7 +187,13 @@ static inline int is531x5(struct b53_dev - - static inline int is63xx(struct b53_device *dev) - { -- return dev->chip_id == BCM63XX_DEVICE_ID; -+ return dev->chip_id == BCM63XX_DEVICE_ID || -+ dev->chip_id == BCM63268_DEVICE_ID; -+} -+ -+static inline int is63268(struct b53_device *dev) -+{ -+ return dev->chip_id == BCM63268_DEVICE_ID; - } - - static inline int is5301x(struct b53_device *dev) diff --git a/target/linux/generic/pending-5.15/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch b/target/linux/generic/pending-5.15/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch deleted file mode 100644 index d90d757fb2c2ae..00000000000000 --- a/target/linux/generic/pending-5.15/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch +++ /dev/null @@ -1,123 +0,0 @@ -From patchwork Tue Mar 21 17:33:59 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13183005 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 31BE4C761A6 - for ; Tue, 21 Mar 2023 17:35:16 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S229674AbjCURfN (ORCPT ); - Tue, 21 Mar 2023 13:35:13 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47684 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S230327AbjCURfB (ORCPT - ); Tue, 21 Mar 2023 13:35:01 -0400 -Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com - [IPv6:2a00:1450:4864:20::436]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E1D855507D; - Tue, 21 Mar 2023 10:34:27 -0700 (PDT) -Received: by mail-wr1-x436.google.com with SMTP id i9so14537769wrp.3; - Tue, 21 Mar 2023 10:34:27 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679420066; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=asmFs22xWYwR1Ql9m/IrNv+MPUNDn8hSjmwDRYvO7mE=; - b=Cqj2C6aG5vEOlhh9N3ybvDA0CV38nhQODnfdnr7utNddd323iDagoJty1Wmi3MAzj1 - 5ORmYT5fQvUnild7C4RhcCNTBn+MoYZ+wDZwZYelu6BKHkW11YFK949ax5B50by+ASR2 - z+rGI3wR5fVXd4VDgmcsT6zF5x69wKyhbhqIfrhG9BVFTctfaBgDS/l+bX1C56kSqv82 - bQkKSSAehSLGpFoCU3q62OGoZVi3jDe6HDb5M1Dp2mgHhqsW19otZpJ57DjtZ1CmtPai - o7T/ew6WoIYSl6whBmV36jeNaDJ3TItOBrKc4nMJBDWaCg4DNzUSe0ei5Xz7Oik5lb3p - y9ew== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679420066; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=asmFs22xWYwR1Ql9m/IrNv+MPUNDn8hSjmwDRYvO7mE=; - b=UdI2iQNBYwRf40ivf3ROR132t95BU/p3RUzXdZLCyz6c6JWtECQ5byyGeEwoX10n5u - HlepoNTJxMFLYrAHGvNLDPpWPuLXMa645S1mCVZ7NyWp8W96XzSynNZPeXHuJdb464QU - A7UTRSW3mlvKe9OR3EcB2CfBZv0yHWR0ldbnxcxGUFw8z78PNqpOVnITtjBdfpGesJ9c - VJw+fiM6hCcahor4nk9LLcAryPm8xmhDLxBKaLILO8wyTUiHY8G9hsXnFCtcpetnF5wS - pW13beAE+odb7ZZaXZUYpWGYhCe/hLzNjbo8YpgzHwadZthxPrT5YvNIYwyrvoViLM0n - KDRQ== -X-Gm-Message-State: AO0yUKW+9H/kqcAUyWeZhZJhiJjsBcYn1THmZaSDrPrk/pNuGXJXGtJd - NgsGZW8iSqLEv81yK+U5Os8= -X-Google-Smtp-Source: - AK7set/lzQZwCSxVaOe5dZ+7TR3xaQty/vg5xvZDpRW8TwTiPQblIbw5kJJTPLp67RySehrPIlCqSg== -X-Received: by 2002:a5d:65c9:0:b0:2ce:ac31:54ff with SMTP id - e9-20020a5d65c9000000b002ceac3154ffmr2776515wrw.2.1679420066191; - Tue, 21 Mar 2023 10:34:26 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.24 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Tue, 21 Mar 2023 10:34:25 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, - olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= , - Simon Horman -Subject: [PATCH v2 4/4] net: dsa: b53: add BCM63268 RGMII configuration -Date: Tue, 21 Mar 2023 18:33:59 +0100 -Message-Id: <20230321173359.251778-5-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230321173359.251778-1-noltari@gmail.com> -References: <20230320155024.164523-1-noltari@gmail.com> - <20230321173359.251778-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -BCM63268 requires special RGMII configuration to work. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Florian Fainelli -Reviewed-by: Simon Horman ---- - v2: no changes. - - drivers/net/dsa/b53/b53_common.c | 6 +++++- - drivers/net/dsa/b53/b53_regs.h | 1 + - 2 files changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -1240,8 +1240,12 @@ static void b53_adjust_63xx_rgmii(struct - break; - } - -- if (port != dev->imp_port) -+ if (port != dev->imp_port) { -+ if (is63268(dev)) -+ rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE; -+ - rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII; -+ } - - b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl); - ---- a/drivers/net/dsa/b53/b53_regs.h -+++ b/drivers/net/dsa/b53/b53_regs.h -@@ -138,6 +138,7 @@ - - #define B53_RGMII_CTRL_IMP 0x60 - #define RGMII_CTRL_ENABLE_GMII BIT(7) -+#define RGMII_CTRL_MII_OVERRIDE BIT(6) - #define RGMII_CTRL_TIMING_SEL BIT(2) - #define RGMII_CTRL_DLL_RXC BIT(1) - #define RGMII_CTRL_DLL_TXC BIT(0) diff --git a/target/linux/generic/pending-5.15/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch b/target/linux/generic/pending-5.15/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch deleted file mode 100644 index 53494eca6ed52f..00000000000000 --- a/target/linux/generic/pending-5.15/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch +++ /dev/null @@ -1,189 +0,0 @@ -From patchwork Fri Mar 24 08:41:38 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13186549 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id EF744C76195 - for ; Fri, 24 Mar 2023 08:42:01 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S231807AbjCXImA (ORCPT ); - Fri, 24 Mar 2023 04:42:00 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32956 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S231272AbjCXIly (ORCPT - ); Fri, 24 Mar 2023 04:41:54 -0400 -Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com - [IPv6:2a00:1450:4864:20::535]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 113A517CF3; - Fri, 24 Mar 2023 01:41:46 -0700 (PDT) -Received: by mail-ed1-x535.google.com with SMTP id ek18so4877175edb.6; - Fri, 24 Mar 2023 01:41:45 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679647304; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=OfUWRaFIQIQw/lRivER+LHryfdLliXzvabGrcmkQVEU=; - b=JMrl6Eay1FS0JZqgPHsbcVzuNAbFELc0SLNGyzYtOVQXcI+YwKDM9Ls7I9PsQVEPoZ - CthomCTYoz5G9DU7uBuia207rnjOhssZJRu0syrCoU+O/ZiQyGLJDvq61z5oZJxC2S40 - kzRsUsC6MRjn64DKPWmxhsSTMKLzn2+P233LKNFbHtfi3NWF5Qu/85sUkxMurnfUgja0 - qQhl25qYY7ZIvmlFHYefaI5UkITQFuiybrqJW9tztCdHf/gS+f33YkkvQ8njmMQa1DW0 - ppedfOUotX+6kmHZGX1yea2V5ezEGGvRourZtYMoecTiD0E5d1J1bKhktKslVLIDm0ig - oc2g== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679647304; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=OfUWRaFIQIQw/lRivER+LHryfdLliXzvabGrcmkQVEU=; - b=b3Gmga5ZDbnmQfnw1GCz+eU2JwgsVzfciZuSmfYAiVxpW4c6cur3MHbpzDPhi99wzA - ZYAM7ryLv88rXl/tQB5g2Nte5rvMfxUeHXsT/JpsRcSSocFRbRrk0QJyiA/Xj86NiD5N - C1sKz50Im190FmrvPcBh6OHQbv/3MQyE+1fQx+9q3jW5rQiAWQaYk4Ng8GlWA7gtG3jB - fHO6Fuoenn32pgkveJbQLYL/2t2f53wGf3QLQ3IeKW7jdfIHNThwrwqBMxdHoIDaTBT9 - UWMeJuiYtylIibo/3zbORbWOgIERlWxZRf3BCOFpnzUn4eBzio4LgjtNxZ77ITRxsmbk - 3+Hg== -X-Gm-Message-State: AAQBX9dfyBfbR7Sdd5wqxMiAv3Yhk47pK1XzD87MZyAF3AxyoFyKcMaF - EbwJLyRvTGQEFdVWCGw1eMU= -X-Google-Smtp-Source: - AKy350bpDVLq7k1FxG2Mek/VIobZL4KhufiKx8qfmpxpcWmLI3bLg8wfQKEAKJRNJBleo/7CZuCL5g== -X-Received: by 2002:aa7:c711:0:b0:4a2:588f:b3c5 with SMTP id - i17-20020aa7c711000000b004a2588fb3c5mr2261236edq.21.1679647304260; - Fri, 24 Mar 2023 01:41:44 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - z21-20020a50cd15000000b004acbda55f6bsm10323728edi.27.2023.03.24.01.41.43 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Fri, 24 Mar 2023 01:41:43 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: paul.geurts@prodrive-technologies.com, f.fainelli@gmail.com, - jonas.gorski@gmail.com, andrew@lunn.ch, olteanv@gmail.com, - davem@davemloft.net, edumazet@google.com, kuba@kernel.org, - pabeni@redhat.com, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v2 2/2] net: dsa: b53: mdio: add support for BCM53134 -Date: Fri, 24 Mar 2023 09:41:38 +0100 -Message-Id: <20230324084138.664285-3-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230324084138.664285-1-noltari@gmail.com> -References: <20230323121804.2249605-1-noltari@gmail.com> - <20230324084138.664285-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -From: Paul Geurts - -Add support for the BCM53134 Ethernet switch in the existing b53 dsa driver. -BCM53134 is very similar to the BCM58XX series. - -Signed-off-by: Paul Geurts -Signed-off-by: Álvaro Fernández Rojas ---- - v2: add BCM53134 to is531x5() and remove special RGMII config - - drivers/net/dsa/b53/b53_common.c | 15 +++++++++++++++ - drivers/net/dsa/b53/b53_mdio.c | 5 ++++- - drivers/net/dsa/b53/b53_priv.h | 7 +++++-- - 3 files changed, 24 insertions(+), 3 deletions(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -2609,6 +2609,20 @@ static const struct b53_chip_data b53_sw - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, - .jumbo_size_reg = B53_JUMBO_MAX_SIZE, - }, -+ { -+ .chip_id = BCM53134_DEVICE_ID, -+ .dev_name = "BCM53134", -+ .vlans = 4096, -+ .enabled_ports = 0x12f, -+ .imp_port = 8, -+ .cpu_port = B53_CPU_PORT, -+ .vta_regs = B53_VTA_REGS, -+ .arl_bins = 4, -+ .arl_buckets = 1024, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ }, - }; - - static int b53_switch_init(struct b53_device *dev) -@@ -2785,6 +2799,7 @@ int b53_switch_detect(struct b53_device - case BCM53012_DEVICE_ID: - case BCM53018_DEVICE_ID: - case BCM53019_DEVICE_ID: -+ case BCM53134_DEVICE_ID: - dev->chip_id = id32; - break; - default: ---- a/drivers/net/dsa/b53/b53_mdio.c -+++ b/drivers/net/dsa/b53/b53_mdio.c -@@ -286,6 +286,7 @@ static const struct b53_io_ops b53_mdio_ - #define B53_BRCM_OUI_2 0x03625c00 - #define B53_BRCM_OUI_3 0x00406000 - #define B53_BRCM_OUI_4 0x01410c00 -+#define B53_BRCM_OUI_5 0xae025000 - - static int b53_mdio_probe(struct mdio_device *mdiodev) - { -@@ -313,7 +314,8 @@ static int b53_mdio_probe(struct mdio_de - if ((phy_id & 0xfffffc00) != B53_BRCM_OUI_1 && - (phy_id & 0xfffffc00) != B53_BRCM_OUI_2 && - (phy_id & 0xfffffc00) != B53_BRCM_OUI_3 && -- (phy_id & 0xfffffc00) != B53_BRCM_OUI_4) { -+ (phy_id & 0xfffffc00) != B53_BRCM_OUI_4 && -+ (phy_id & 0xfffffc00) != B53_BRCM_OUI_5) { - dev_err(&mdiodev->dev, "Unsupported device: 0x%08x\n", phy_id); - return -ENODEV; - } -@@ -377,6 +379,7 @@ static const struct of_device_id b53_of_ - { .compatible = "brcm,bcm53115" }, - { .compatible = "brcm,bcm53125" }, - { .compatible = "brcm,bcm53128" }, -+ { .compatible = "brcm,bcm53134" }, - { .compatible = "brcm,bcm5365" }, - { .compatible = "brcm,bcm5389" }, - { .compatible = "brcm,bcm5395" }, ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -85,6 +85,7 @@ enum { - BCM583XX_DEVICE_ID = 0x58300, - BCM7445_DEVICE_ID = 0x7445, - BCM7278_DEVICE_ID = 0x7278, -+ BCM53134_DEVICE_ID = 0x5075, - }; - - #define B53_N_PORTS 9 -@@ -182,7 +183,8 @@ static inline int is531x5(struct b53_dev - { - return dev->chip_id == BCM53115_DEVICE_ID || - dev->chip_id == BCM53125_DEVICE_ID || -- dev->chip_id == BCM53128_DEVICE_ID; -+ dev->chip_id == BCM53128_DEVICE_ID || -+ dev->chip_id == BCM53134_DEVICE_ID; - } - - static inline int is63xx(struct b53_device *dev) -@@ -210,7 +212,8 @@ static inline int is58xx(struct b53_devi - return dev->chip_id == BCM58XX_DEVICE_ID || - dev->chip_id == BCM583XX_DEVICE_ID || - dev->chip_id == BCM7445_DEVICE_ID || -- dev->chip_id == BCM7278_DEVICE_ID; -+ dev->chip_id == BCM7278_DEVICE_ID || -+ dev->chip_id == BCM53134_DEVICE_ID; - } - - #define B53_63XX_RGMII0 4 diff --git a/target/linux/generic/pending-5.15/779-net-vxlan-don-t-learn-non-unicast-L2-destinations.patch b/target/linux/generic/pending-5.15/779-net-vxlan-don-t-learn-non-unicast-L2-destinations.patch deleted file mode 100644 index 6c1f5967590078..00000000000000 --- a/target/linux/generic/pending-5.15/779-net-vxlan-don-t-learn-non-unicast-L2-destinations.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 3f1a227cb071f65f6ecc4db9f399649869735a7c Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sat, 17 Feb 2024 22:34:59 +0100 -Subject: [PATCH] net vxlan: don't learn non-unicast L2 destinations - -This patch avoids learning non-unicast targets in the vxlan FDB. -They are non-unicast and thus should be sent to the broadcast-IPv6 -instead of a unicast address. - -Link: https://lore.kernel.org/netdev/15ee0cc7-9252-466b-8ce7-5225d605dde8@david-bauer.net/ -Link: https://github.com/freifunk-gluon/gluon/issues/3191 - -Signed-off-by: David Bauer ---- - drivers/net/vxlan.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/vxlan/vxlan_core.c -+++ b/drivers/net/vxlan/vxlan_core.c -@@ -1493,6 +1493,10 @@ static bool vxlan_snoop(struct net_devic - struct vxlan_fdb *f; - u32 ifindex = 0; - -+ /* Don't learn broadcast packets */ -+ if (is_multicast_ether_addr(src_mac) || is_zero_ether_addr(src_mac)) -+ return false; -+ - #if IS_ENABLED(CONFIG_IPV6) - if (src_ip->sa.sa_family == AF_INET6 && - (ipv6_addr_type(&src_ip->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)) diff --git a/target/linux/generic/pending-5.15/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch b/target/linux/generic/pending-5.15/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch deleted file mode 100644 index 39ba71606ec235..00000000000000 --- a/target/linux/generic/pending-5.15/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch +++ /dev/null @@ -1,61 +0,0 @@ -From patchwork Thu Aug 5 22:23:30 2021 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 12422209 -Date: Thu, 5 Aug 2021 23:23:30 +0100 -From: Daniel Golle -To: linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org, - linux-kernel@vger.kernel.org -Cc: "David S. Miller" , Andrew Lunn , - Michael Walle -Subject: [PATCH] ARM: kirkwood: add missing for ETH_ALEN -Message-ID: -MIME-Version: 1.0 -Content-Disposition: inline -X-BeenThere: linux-arm-kernel@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Archive: -Sender: "linux-arm-kernel" - -After commit 83216e3988cd1 ("of: net: pass the dst buffer to -of_get_mac_address()") build fails for kirkwood as ETH_ALEN is not -defined. - -arch/arm/mach-mvebu/kirkwood.c: In function 'kirkwood_dt_eth_fixup': -arch/arm/mach-mvebu/kirkwood.c:87:13: error: 'ETH_ALEN' undeclared (first use in this function); did you mean 'ESTALE'? - u8 tmpmac[ETH_ALEN]; - ^~~~~~~~ - ESTALE -arch/arm/mach-mvebu/kirkwood.c:87:13: note: each undeclared identifier is reported only once for each function it appears in -arch/arm/mach-mvebu/kirkwood.c:87:6: warning: unused variable 'tmpmac' [-Wunused-variable] - u8 tmpmac[ETH_ALEN]; - ^~~~~~ -make[5]: *** [scripts/Makefile.build:262: arch/arm/mach-mvebu/kirkwood.o] Error 1 -make[5]: *** Waiting for unfinished jobs.... - -Add missing #include to fix this. - -Cc: David S. Miller -Cc: Andrew Lunn -Cc: Michael Walle -Reported-by: https://buildbot.openwrt.org/master/images/#/builders/56/builds/220/steps/44/logs/stdio -Fixes: 83216e3988cd1 ("of: net: pass the dst buffer to of_get_mac_address()") -Signed-off-by: Daniel Golle ---- - arch/arm/mach-mvebu/kirkwood.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/mach-mvebu/kirkwood.c -+++ b/arch/arm/mach-mvebu/kirkwood.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/target/linux/generic/pending-5.15/790-bus-mhi-core-add-SBL-state-callback.patch b/target/linux/generic/pending-5.15/790-bus-mhi-core-add-SBL-state-callback.patch deleted file mode 100644 index 6402dd9066aad3..00000000000000 --- a/target/linux/generic/pending-5.15/790-bus-mhi-core-add-SBL-state-callback.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 5f7c5e1c0d7a79be144e5efc1f24728ddd7fc25c Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sat, 5 Nov 2022 20:02:56 +0100 -Subject: [PATCH 1/2] bus: mhi: core: add SBL state callback - -Add support for SBL state callback in MHI core. - -It is required for ath11k MHI devices in order to be able to set QRTR -instance ID in the SBL state so that QRTR instance ID-s dont conflict in -case of multiple PCI/MHI cards or AHB + PCI/MHI card. -Setting QRTR instance ID is only possible in SBL state and there is -currently no way to ensure that we are in that state, so provide a -callback that the controller can trigger off. - -Signed-off-by: Robert Marko ---- - drivers/bus/mhi/host/main.c | 1 + - include/linux/mhi.h | 2 ++ - 2 files changed, 3 insertions(+) - ---- a/drivers/bus/mhi/host/main.c -+++ b/drivers/bus/mhi/host/main.c -@@ -896,6 +896,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_ - switch (event) { - case MHI_EE_SBL: - st = DEV_ST_TRANSITION_SBL; -+ mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_SBL_MODE); - break; - case MHI_EE_WFW: - case MHI_EE_AMSS: ---- a/include/linux/mhi.h -+++ b/include/linux/mhi.h -@@ -34,6 +34,7 @@ struct mhi_buf_info; - * @MHI_CB_SYS_ERROR: MHI device entered error state (may recover) - * @MHI_CB_FATAL_ERROR: MHI device entered fatal error state - * @MHI_CB_BW_REQ: Received a bandwidth switch request from device -+ * @MHI_CB_EE_SBL_MODE: MHI device entered SBL mode - */ - enum mhi_callback { - MHI_CB_IDLE, -@@ -45,6 +46,7 @@ enum mhi_callback { - MHI_CB_SYS_ERROR, - MHI_CB_FATAL_ERROR, - MHI_CB_BW_REQ, -+ MHI_CB_EE_SBL_MODE, - }; - - /** diff --git a/target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch b/target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch deleted file mode 100644 index 609e03d964412b..00000000000000 --- a/target/linux/generic/pending-5.15/795-mt7530-register-OF-node-for-internal-MDIO-bus.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 1d81e51d6d79d9098013b2e8cdd677bae998c5d8 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Fri, 28 Apr 2023 02:22:59 +0200 -Subject: [PATCH 1/2] mt7530: register OF node for internal MDIO bus - -The MT753x switches provide a switch-internal MDIO bus for the embedded -PHYs. - -Register a OF sub-node on the switch OF-node for this internal MDIO bus. -This allows to configure the embedded PHYs using device-tree. - -Signed-off-by: David Bauer ---- - drivers/net/dsa/mt7530.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2356,10 +2356,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr - { - struct dsa_switch *ds = priv->ds; - struct device *dev = priv->dev; -+ struct device_node *np, *mnp; - struct mii_bus *bus; - static int idx; - int ret; - -+ np = priv->dev->of_node; -+ - bus = devm_mdiobus_alloc(dev); - if (!bus) - return -ENOMEM; -@@ -2376,7 +2379,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr - if (priv->irq) - mt7530_setup_mdio_irq(priv); - -- ret = devm_mdiobus_register(dev, bus); -+ mnp = of_get_child_by_name(np, "mdio"); -+ ret = devm_of_mdiobus_register(dev, bus, mnp); -+ of_node_put(mnp); - if (ret) { - dev_err(dev, "failed to register MDIO bus: %d\n", ret); - if (priv->irq) diff --git a/target/linux/generic/pending-5.15/796-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch b/target/linux/generic/pending-5.15/796-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch deleted file mode 100644 index 1697347b53c962..00000000000000 --- a/target/linux/generic/pending-5.15/796-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch +++ /dev/null @@ -1,45 +0,0 @@ -From a444877c10a665cd8a869e6d37facdb89fd95f79 Mon Sep 17 00:00:00 2001 -Message-ID: -From: Daniel Golle -Date: Wed, 24 Jan 2024 04:17:11 +0000 -Subject: [PATCH net] net: dsa: mt7530: fix 10M/100M speed on MT7988 switch -To: Arınç ÜNAL , - Daniel Golle , - DENG Qingfang , - Sean Wang , - Andrew Lunn , - Florian Fainelli , - Vladimir Oltean , - David S. Miller , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Matthias Brugger , - AngeloGioacchino Del Regno , - netdev@vger.kernel.org, - linux-kernel@vger.kernel.org, - linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org - -Setup PMCR port register for actual speed and duplex on internally -connected PHYs of the MT7988 built-in switch. This fixes links with -speeds other than 1000M. - -Fixes: ("110c18bfed414 net: dsa: mt7530: introduce driver for MT7988 built-in switch") -Signed-off-by: Daniel Golle ---- - drivers/net/dsa/mt7530.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3065,8 +3065,7 @@ static void mt753x_phylink_mac_link_up(s - /* MT753x MAC works in 1G full duplex mode for all up-clocked - * variants. - */ -- if (interface == PHY_INTERFACE_MODE_INTERNAL || -- interface == PHY_INTERFACE_MODE_TRGMII || -+ if (interface == PHY_INTERFACE_MODE_TRGMII || - (phy_interface_mode_is_8023z(interface))) { - speed = SPEED_1000; - duplex = DUPLEX_FULL; diff --git a/target/linux/generic/pending-5.15/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch b/target/linux/generic/pending-5.15/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch deleted file mode 100644 index 478a2cb27d8014..00000000000000 --- a/target/linux/generic/pending-5.15/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch +++ /dev/null @@ -1,73 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH] bcma: get SoC device struct & copy its DMA params to the - subdevices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -For bus devices to be fully usable it's required to set their DMA -parameters. - -For years it has been missing and remained unnoticed because of -mips_dma_alloc_coherent() silently handling the empty coherent_dma_mask. -Kernel 4.19 came with a lot of DMA changes and caused a regression on -the bcm47xx. Starting with the commit f8c55dc6e828 ("MIPS: use generic -dma noncoherent ops for simple noncoherent platforms") DMA coherent -allocations just fail. Example: -[ 1.114914] bgmac_bcma bcma0:2: Allocation of TX ring 0x200 failed -[ 1.121215] bgmac_bcma bcma0:2: Unable to alloc memory for DMA -[ 1.127626] bgmac_bcma: probe of bcma0:2 failed with error -12 -[ 1.133838] bgmac_bcma: Broadcom 47xx GBit MAC driver loaded - -This change fixes above regression in addition to the MIPS bcm47xx -commit 321c46b91550 ("MIPS: BCM47XX: Setup struct device for the SoC"). - -It also fixes another *old* GPIO regression caused by a parent pointing -to the NULL: -[ 0.157054] missing gpiochip .dev parent pointer -[ 0.157287] bcma: bus0: Error registering GPIO driver: -22 -introduced by the commit 74f4e0cc6108 ("bcma: switch GPIO portions to -use GPIOLIB_IRQCHIP"). - -Fixes: f8c55dc6e828 ("MIPS: use generic dma noncoherent ops for simple noncoherent platforms") -Fixes: 74f4e0cc6108 ("bcma: switch GPIO portions to use GPIOLIB_IRQCHIP") -Cc: linux-mips@linux-mips.org -Cc: Christoph Hellwig -Cc: Linus Walleij -Signed-off-by: Rafał Miłecki ---- - ---- a/drivers/bcma/host_soc.c -+++ b/drivers/bcma/host_soc.c -@@ -191,6 +191,8 @@ int __init bcma_host_soc_init(struct bcm - struct bcma_bus *bus = &soc->bus; - int err; - -+ bus->dev = soc->dev; -+ - /* Scan bus and initialize it */ - err = bcma_bus_early_register(bus); - if (err) ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -236,13 +236,17 @@ EXPORT_SYMBOL(bcma_core_irq); - - void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) - { -- device_initialize(&core->dev); -+ struct device *dev = &core->dev; -+ -+ device_initialize(dev); - core->dev.release = bcma_release_core_dev; - core->dev.bus = &bcma_bus_type; -- dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); -+ dev_set_name(dev, "bcma%d:%d", bus->num, core->core_index); - core->dev.parent = bus->dev; -- if (bus->dev) -+ if (bus->dev) { - bcma_of_fill_device(bus->dev, core); -+ dma_coerce_mask_and_coherent(dev, bus->dev->coherent_dma_mask); -+ } - - switch (bus->hosttype) { - case BCMA_HOSTTYPE_PCI: diff --git a/target/linux/generic/pending-5.15/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch b/target/linux/generic/pending-5.15/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch deleted file mode 100644 index c1e14b92714f84..00000000000000 --- a/target/linux/generic/pending-5.15/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch +++ /dev/null @@ -1,222 +0,0 @@ -From fc23ea48ba52c24f201fe5ca0132ee1a3de5a70a Mon Sep 17 00:00:00 2001 -From: Mauri Sandberg -Date: Thu, 25 Mar 2021 11:48:05 +0200 -Subject: [PATCH 2/2] gpio: gpio-cascade: add generic GPIO cascade - -Adds support for building cascades of GPIO lines. That is, it allows -setups when there is one upstream line and multiple cascaded lines, out -of which one can be chosen at a time. The status of the upstream line -can be conveyed to the selected cascaded line or, vice versa, the status -of the cascaded line can be conveyed to the upstream line. - -A multiplexer is being used to select, which cascaded GPIO line is being -used at any given time. - -At the moment only input direction is supported. In future it should be -possible to add support for output direction, too. - -Signed-off-by: Mauri Sandberg -Reviewed-by: Linus Walleij -Reviewed-by: Andy Shevchenko ---- -v7 -> v8: - - rearrange members in struct gpio_cascade - - cosmetic changes in file header and in one function declaration - - added Reviewed-by tags by Linus and Andy -v6 -> v7: - - In Kconfig add info about module name - - adhere to new convention that allows lines longer than 80 chars - - use dev_probe_err with upstream gpio line too - - refactor for cleaner exit of probe function. -v5 -> v6: - - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER - - refactor code preferring one-liners - - clean up prints, removing them from success-path. - - don't explicitly set gpio_chip.of_node as it's done in the GPIO library - - use devm_gpiochip_add_data instead of gpiochip_add -v4 -> v5: - - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly - here and there and changed to use new bindings and compatible string - - ambigious and vague 'pin' was rename to 'upstream_line' - - dropped Tested-by and Reviewed-by due to changes in bindings - - dropped Reported-by suggested by an automatic bot as it was not really - appropriate to begin with - - functionally it's the same as v4 -v3 -> v4: - - Changed author email - - Included Tested-by and Reviewed-by from Drew -v2 -> v3: - - use managed device resources - - update Kconfig description -v1 -> v2: - - removed .owner from platform_driver as per test bot's instruction - - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE - - added gpio_mux_input_get_direction as it's recommended for all chips - - removed because this is input only chip: gpio_mux_input_set_value - - removed because they are not needed for input/output only chips: - gpio_mux_input_direction_input - gpio_mux_input_direction_output - - fixed typo in an error message - - added info message about successful registration - - removed can_sleep flag as this does not sleep while getting GPIO value - like I2C or SPI do - - Updated description in Kconfig ---- - drivers/gpio/Kconfig | 15 +++++ - drivers/gpio/Makefile | 1 + - drivers/gpio/gpio-cascade.c | 117 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 133 insertions(+) - create mode 100644 drivers/gpio/gpio-cascade.c - ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -1683,4 +1683,19 @@ config GPIO_VIRTIO - - endmenu - -+comment "Other GPIO expanders" -+ -+config GPIO_CASCADE -+ tristate "General GPIO cascade" -+ select MULTIPLEXER -+ help -+ Say yes here to enable support for generic GPIO cascade. -+ -+ This allows building one-to-many cascades of GPIO lines using -+ different types of multiplexers readily available. At the -+ moment only input lines are supported. -+ -+ To build the driver as a module choose 'm' and the resulting module -+ will be called 'gpio-cascade'. -+ - endif ---- a/drivers/gpio/Makefile -+++ b/drivers/gpio/Makefile -@@ -45,6 +45,7 @@ obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd - obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o - obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o - obj-$(CONFIG_GPIO_CADENCE) += gpio-cadence.o -+obj-$(CONFIG_GPIO_CASCADE) += gpio-cascade.o - obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o - obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o - obj-$(CONFIG_GPIO_CRYSTAL_COVE) += gpio-crystalcove.o ---- /dev/null -+++ b/drivers/gpio/gpio-cascade.c -@@ -0,0 +1,117 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * A generic GPIO cascade driver -+ * -+ * Copyright (C) 2021 Mauri Sandberg -+ * -+ * This allows building cascades of GPIO lines in a manner illustrated -+ * below: -+ * -+ * /|---- Cascaded GPIO line 0 -+ * Upstream | |---- Cascaded GPIO line 1 -+ * GPIO line ----+ | . -+ * | | . -+ * \|---- Cascaded GPIO line n -+ * -+ * A multiplexer is being used to select, which cascaded line is being -+ * addressed at any given time. -+ * -+ * At the moment only input mode is supported due to lack of means for -+ * testing output functionality. At least theoretically output should be -+ * possible with open drain constructions. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+struct gpio_cascade { -+ struct gpio_chip gpio_chip; -+ struct device *parent; -+ struct mux_control *mux_control; -+ struct gpio_desc *upstream_line; -+}; -+ -+static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc) -+{ -+ return container_of(gc, struct gpio_cascade, gpio_chip); -+} -+ -+static int gpio_cascade_get_direction(struct gpio_chip *gc, unsigned int offset) -+{ -+ return GPIO_LINE_DIRECTION_IN; -+} -+ -+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset) -+{ -+ struct gpio_cascade *cas = chip_to_cascade(gc); -+ int ret; -+ -+ ret = mux_control_select(cas->mux_control, offset); -+ if (ret) -+ return ret; -+ -+ ret = gpiod_get_value(cas->upstream_line); -+ mux_control_deselect(cas->mux_control); -+ return ret; -+} -+ -+static int gpio_cascade_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct gpio_cascade *cas; -+ struct mux_control *mc; -+ struct gpio_desc *upstream; -+ struct gpio_chip *gc; -+ -+ cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL); -+ if (!cas) -+ return -ENOMEM; -+ -+ mc = devm_mux_control_get(dev, NULL); -+ if (IS_ERR(mc)) -+ return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n"); -+ -+ cas->mux_control = mc; -+ upstream = devm_gpiod_get(dev, "upstream", GPIOD_IN); -+ if (IS_ERR(upstream)) -+ return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n"); -+ -+ cas->upstream_line = upstream; -+ cas->parent = dev; -+ -+ gc = &cas->gpio_chip; -+ gc->get = gpio_cascade_get_value; -+ gc->get_direction = gpio_cascade_get_direction; -+ gc->base = -1; -+ gc->ngpio = mux_control_states(mc); -+ gc->label = dev_name(cas->parent); -+ gc->parent = cas->parent; -+ gc->owner = THIS_MODULE; -+ -+ platform_set_drvdata(pdev, cas); -+ return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL); -+} -+ -+static const struct of_device_id gpio_cascade_id[] = { -+ { .compatible = "gpio-cascade" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, gpio_cascade_id); -+ -+static struct platform_driver gpio_cascade_driver = { -+ .driver = { -+ .name = "gpio-cascade", -+ .of_match_table = gpio_cascade_id, -+ }, -+ .probe = gpio_cascade_probe, -+}; -+module_platform_driver(gpio_cascade_driver); -+ -+MODULE_AUTHOR("Mauri Sandberg "); -+MODULE_DESCRIPTION("Generic GPIO cascade"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch deleted file mode 100644 index 29fe668f8de98a..00000000000000 --- a/target/linux/generic/pending-5.15/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Thu, 13 Oct 2022 00:51:33 +0900 -Subject: [PATCH] nvmem: layouts: u-boot-env: align endianness of crc32 values -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch fixes crc32 error on Big-Endianness system by conversion of -calculated crc32 value. - -Little-Endianness system: - - obtained crc32: Little -calculated crc32: Little - -Big-Endianness system: - - obtained crc32: Little -calculated crc32: Big - -log (APRESIA ApresiaLightGS120GT-SS, RTL8382M, Big-Endianness): - -[ 8.570000] u_boot_env 18001200.spi:flash@0:partitions:partition@c0000: Invalid calculated CRC32: 0x88cd6f09 (expected: 0x096fcd88) -[ 8.580000] u_boot_env: probe of 18001200.spi:flash@0:partitions:partition@c0000 failed with error -22 - -Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables") - -Signed-off-by: INAGAKI Hiroshi -Acked-by: Rafał Miłecki -Tested-by: Christian Lamparter -Signed-off-by: Srinivas Kandagatla ---- - ---- a/drivers/nvmem/layouts/u-boot-env.c -+++ b/drivers/nvmem/layouts/u-boot-env.c -@@ -148,7 +148,7 @@ int u_boot_env_parse(struct device *dev, - crc32_data_len = dev_size - crc32_data_offset; - data_len = dev_size - data_offset; - -- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; -+ calc = le32_to_cpu((__le32)crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L); - if (calc != crc32) { - dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); - err = -EINVAL; diff --git a/target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch b/target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch deleted file mode 100644 index 29cda1824e2ed0..00000000000000 --- a/target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch +++ /dev/null @@ -1,124 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 13 Jul 2023 18:29:19 +0200 -Subject: [PATCH] nvmem: core: support "mac-base" fixed layout cells - -Fixed layout binding allows specifying "mac-base" NVMEM cells. It's used -for base MAC address (that can be used for calculating relative -addresses). It can be stored in a raw binary format or as an ASCII -string. ---- - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - menuconfig NVMEM - bool "NVMEM Support" -+ select GENERIC_NET_UTILS - imply NVMEM_LAYOUTS - help - Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES... ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -7,9 +7,12 @@ - */ - - #include -+#include -+#include - #include - #include - #include -+#include - #include - #include - #include -@@ -797,6 +800,62 @@ static int nvmem_validate_keepouts(struc - return 0; - } - -+static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ if (WARN_ON(bytes != ETH_ALEN)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(buf, index); -+ -+ return 0; -+} -+ -+static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (WARN_ON(bytes != 3 * ETH_ALEN - 1)) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ -+static int nvmem_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN], *hexstr; -+ int i; -+ -+ if (WARN_ON(bytes != 2 * ETH_ALEN)) -+ return -EINVAL; -+ -+ hexstr = (u8 *)buf; -+ for (i = 0; i < ETH_ALEN; i++) { -+ if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1])) -+ return -EINVAL; -+ -+ mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]); -+ } -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ - static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) - { - struct device *dev = &nvmem->dev; -@@ -836,6 +895,25 @@ static int nvmem_add_cells_from_dt(struc - if (nvmem->fixup_dt_cell_info) - nvmem->fixup_dt_cell_info(nvmem, &info); - -+ if (of_device_is_compatible(np, "fixed-layout")) { -+ if (of_device_is_compatible(child, "mac-base")) { -+ if (info.bytes == ETH_ALEN) { -+ info.raw_len = info.bytes; -+ info.bytes = ETH_ALEN; -+ info.read_post_process = nvmem_mac_base_raw_read; -+ } else if (info.bytes == 2 * ETH_ALEN) { -+ info.raw_len = info.bytes; -+ info.bytes = ETH_ALEN; -+ info.read_post_process = nvmem_mac_base_hex_read; -+ } else if (info.bytes == 3 * ETH_ALEN - 1) { -+ info.raw_len = info.bytes; -+ info.bytes = ETH_ALEN; -+ info.read_post_process = nvmem_mac_base_ascii_read; -+ } -+ -+ } -+ } -+ - ret = nvmem_add_one_cell(nvmem, &info); - kfree(info.name); - if (ret) { diff --git a/target/linux/generic/pending-5.15/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-5.15/810-pci_disable_common_quirks.patch deleted file mode 100644 index 302051cc3be8ac..00000000000000 --- a/target/linux/generic/pending-5.15/810-pci_disable_common_quirks.patch +++ /dev/null @@ -1,62 +0,0 @@ -From: Gabor Juhos -Subject: debloat: add kernel config option to disabling common PCI quirks - -Signed-off-by: Gabor Juhos ---- - drivers/pci/Kconfig | 6 ++++++ - drivers/pci/quirks.c | 6 ++++++ - 2 files changed, 12 insertions(+) - ---- a/drivers/pci/Kconfig -+++ b/drivers/pci/Kconfig -@@ -118,6 +118,13 @@ config XEN_PCIDEV_FRONTEND - The PCI device frontend driver allows the kernel to import arbitrary - PCI devices from a PCI backend to support PCI driver domains. - -+config PCI_DISABLE_COMMON_QUIRKS -+ bool "PCI disable common quirks" -+ depends on PCI -+ help -+ If you don't know what to do here, say N. -+ -+ - config PCI_ATS - bool - ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -207,6 +207,7 @@ static void quirk_mmio_always_on(struct - DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS - /* - * The Mellanox Tavor device gives false positive parity errors. Disable - * parity error reporting. -@@ -3369,6 +3370,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); - -+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ - /* - * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. - * To work around this, query the size it should be configured to by the -@@ -3394,6 +3397,8 @@ static void quirk_intel_ntb(struct pci_d - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ - /* - * Some BIOS implementations leave the Intel GPU interrupts enabled, even - * though no one is handling them (e.g., if the i915 driver is never -@@ -3432,6 +3437,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq); - -+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ - /* - * PCI devices which are on Intel chips can skip the 10ms delay - * before entering D3 mode. diff --git a/target/linux/generic/pending-5.15/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-5.15/811-pci_disable_usb_common_quirks.patch deleted file mode 100644 index b498d9f700a91e..00000000000000 --- a/target/linux/generic/pending-5.15/811-pci_disable_usb_common_quirks.patch +++ /dev/null @@ -1,115 +0,0 @@ -From: Felix Fietkau -Subject: debloat: disable common USB quirks - -Signed-off-by: Felix Fietkau ---- - drivers/usb/host/pci-quirks.c | 16 ++++++++++++++++ - drivers/usb/host/pci-quirks.h | 18 +++++++++++++++++- - include/linux/usb/hcd.h | 7 +++++++ - 3 files changed, 40 insertions(+), 1 deletion(-) - ---- a/drivers/usb/host/pci-quirks.c -+++ b/drivers/usb/host/pci-quirks.c -@@ -128,6 +128,8 @@ struct amd_chipset_type { - u8 rev; - }; - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ - static struct amd_chipset_info { - struct pci_dev *nb_dev; - struct pci_dev *smbus_dev; -@@ -633,6 +635,10 @@ bool usb_amd_pt_check_port(struct device - } - EXPORT_SYMBOL_GPL(usb_amd_pt_check_port); - -+#endif /* CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ -+#if IS_ENABLED(CONFIG_USB_UHCI_HCD) -+ - /* - * Make sure the controller is completely inactive, unable to - * generate interrupts or do DMA. -@@ -712,8 +718,17 @@ reset_needed: - uhci_reset_hc(pdev, base); - return 1; - } -+#else -+int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) -+{ -+ return 0; -+} -+ -+#endif - EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ - static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) - { - u16 cmd; -@@ -1285,3 +1300,4 @@ static void quirk_usb_early_handoff(stru - } - DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff); -+#endif ---- a/drivers/usb/host/pci-quirks.h -+++ b/drivers/usb/host/pci-quirks.h -@@ -5,6 +5,9 @@ - #ifdef CONFIG_USB_PCI - void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); - int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); -+#endif /* CONFIG_USB_PCI */ -+ -+#if defined(CONFIG_USB_PCI) && !defined(CONFIG_PCI_DISABLE_COMMON_QUIRKS) - int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev); - bool usb_amd_hang_symptom_quirk(void); - bool usb_amd_prefetch_quirk(void); -@@ -19,6 +22,18 @@ void sb800_prefetch(struct device *dev, - bool usb_amd_pt_check_port(struct device *device, int port); - #else - struct pci_dev; -+static inline int usb_amd_quirk_pll_check(void) -+{ -+ return 0; -+} -+static inline bool usb_amd_hang_symptom_quirk(void) -+{ -+ return false; -+} -+static inline bool usb_amd_prefetch_quirk(void) -+{ -+ return false; -+} - static inline void usb_amd_quirk_pll_disable(void) {} - static inline void usb_amd_quirk_pll_enable(void) {} - static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {} -@@ -29,6 +44,11 @@ static inline bool usb_amd_pt_check_port - { - return false; - } -+static inline void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) {} -+static inline bool usb_xhci_needs_pci_reset(struct pci_dev *pdev) -+{ -+ return false; -+} - #endif /* CONFIG_USB_PCI */ - - #endif /* __LINUX_USB_PCI_QUIRKS_H */ ---- a/include/linux/usb/hcd.h -+++ b/include/linux/usb/hcd.h -@@ -498,7 +498,14 @@ extern int usb_hcd_pci_probe(struct pci_ - extern void usb_hcd_pci_remove(struct pci_dev *dev); - extern void usb_hcd_pci_shutdown(struct pci_dev *dev); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS - extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev); -+#else -+static inline int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev) -+{ -+ return 0; -+} -+#endif - - #ifdef CONFIG_PM - extern const struct dev_pm_ops usb_hcd_pci_pm_ops; diff --git a/target/linux/generic/pending-5.15/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch b/target/linux/generic/pending-5.15/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch deleted file mode 100644 index 33eb34c913ea4a..00000000000000 --- a/target/linux/generic/pending-5.15/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d9c8bc8c1408f3e8529db6e4e04017b4c579c342 Mon Sep 17 00:00:00 2001 -From: Pawel Dembicki -Date: Sun, 18 Feb 2018 17:08:04 +0100 -Subject: [PATCH] w1: gpio: fix problem with platfom data in w1-gpio - -In devices, where fdt is used, is impossible to apply platform data -without proper fdt node. - -This patch allow to use platform data in devices with fdt. - -Signed-off-by: Pawel Dembicki ---- - drivers/w1/masters/w1-gpio.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/w1/masters/w1-gpio.c -+++ b/drivers/w1/masters/w1-gpio.c -@@ -76,7 +76,7 @@ static int w1_gpio_probe(struct platform - enum gpiod_flags gflags = GPIOD_OUT_LOW_OPEN_DRAIN; - int err; - -- if (of_have_populated_dt()) { -+ if (of_have_populated_dt() && !dev_get_platdata(&pdev->dev)) { - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; diff --git a/target/linux/generic/pending-5.15/834-ledtrig-libata.patch b/target/linux/generic/pending-5.15/834-ledtrig-libata.patch deleted file mode 100644 index d61e28b4c3880f..00000000000000 --- a/target/linux/generic/pending-5.15/834-ledtrig-libata.patch +++ /dev/null @@ -1,149 +0,0 @@ -From: Daniel Golle -Subject: libata: add ledtrig support - -This adds a LED trigger for each ATA port indicating disk activity. - -As this is needed only on specific platforms (NAS SoCs and such), -these platforms should define ARCH_WANTS_LIBATA_LEDS if there -are boards with LED(s) intended to indicate ATA disk activity and -need the OS to take care of that. -In that way, if not selected, LED trigger support not will be -included in libata-core and both, codepaths and structures remain -untouched. - -Signed-off-by: Daniel Golle ---- - drivers/ata/Kconfig | 16 ++++++++++++++++ - drivers/ata/libata-core.c | 41 +++++++++++++++++++++++++++++++++++++++++ - include/linux/libata.h | 9 +++++++++ - 3 files changed, 66 insertions(+) - ---- a/drivers/ata/Kconfig -+++ b/drivers/ata/Kconfig -@@ -67,6 +67,22 @@ config ATA_FORCE - - If unsure, say Y. - -+config ARCH_WANT_LIBATA_LEDS -+ bool -+ -+config ATA_LEDS -+ bool "support ATA port LED triggers" -+ depends on ARCH_WANT_LIBATA_LEDS -+ select NEW_LEDS -+ select LEDS_CLASS -+ select LEDS_TRIGGERS -+ default y -+ help -+ This option adds a LED trigger for each registered ATA port. -+ It is used to drive disk activity leds connected via GPIO. -+ -+ If unsure, say N. -+ - config ATA_ACPI - bool "ATA ACPI Support" - depends on ACPI ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -656,6 +656,19 @@ u64 ata_tf_read_block(const struct ata_t - return block; - } - -+#ifdef CONFIG_ATA_LEDS -+#define LIBATA_BLINK_DELAY 20 /* ms */ -+static inline void ata_led_act(struct ata_port *ap) -+{ -+ unsigned long led_delay = LIBATA_BLINK_DELAY; -+ -+ if (unlikely(!ap->ledtrig)) -+ return; -+ -+ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0); -+} -+#endif -+ - /** - * ata_build_rw_tf - Build ATA taskfile for given read/write request - * @tf: Target ATA taskfile -@@ -4580,6 +4593,9 @@ struct ata_queued_cmd *ata_qc_new_init(s - if (tag < 0) - return NULL; - } -+#ifdef CONFIG_ATA_LEDS -+ ata_led_act(ap); -+#endif - - qc = __ata_qc_from_tag(ap, tag); - qc->tag = qc->hw_tag = tag; -@@ -5358,6 +5374,9 @@ struct ata_port *ata_port_alloc(struct a - ap->stats.unhandled_irq = 1; - ap->stats.idle_irq = 1; - #endif -+#ifdef CONFIG_ATA_LEDS -+ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); -+#endif - ata_sff_port_init(ap); - - return ap; -@@ -5393,6 +5412,12 @@ static void ata_host_release(struct kref - - kfree(ap->pmp_link); - kfree(ap->slave_link); -+#ifdef CONFIG_ATA_LEDS -+ if (ap->ledtrig) { -+ led_trigger_unregister(ap->ledtrig); -+ kfree(ap->ledtrig); -+ }; -+#endif - kfree(ap); - host->ports[i] = NULL; - } -@@ -5799,7 +5824,23 @@ int ata_host_register(struct ata_host *h - host->ports[i]->print_id = atomic_inc_return(&ata_print_id); - host->ports[i]->local_port_no = i + 1; - } -+#ifdef CONFIG_ATA_LEDS -+ for (i = 0; i < host->n_ports; i++) { -+ if (unlikely(!host->ports[i]->ledtrig)) -+ continue; - -+ snprintf(host->ports[i]->ledtrig_name, -+ sizeof(host->ports[i]->ledtrig_name), "ata%u", -+ host->ports[i]->print_id); -+ -+ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name; -+ -+ if (led_trigger_register(host->ports[i]->ledtrig)) { -+ kfree(host->ports[i]->ledtrig); -+ host->ports[i]->ledtrig = NULL; -+ } -+ } -+#endif - /* Create associated sysfs transport objects */ - for (i = 0; i < host->n_ports; i++) { - rc = ata_tport_add(host->dev,host->ports[i]); ---- a/include/linux/libata.h -+++ b/include/linux/libata.h -@@ -23,6 +23,9 @@ - #include - #include - #include -+#ifdef CONFIG_ATA_LEDS -+#include -+#endif - - /* - * Define if arch has non-standard setup. This is a _PCI_ standard -@@ -898,6 +901,12 @@ struct ata_port { - #ifdef CONFIG_ATA_ACPI - struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ - #endif -+ -+#ifdef CONFIG_ATA_LEDS -+ struct led_trigger *ledtrig; -+ char ledtrig_name[8]; -+#endif -+ - /* owned by EH */ - u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; - }; diff --git a/target/linux/generic/pending-5.15/840-hwrng-bcm2835-set-quality-to-1000.patch b/target/linux/generic/pending-5.15/840-hwrng-bcm2835-set-quality-to-1000.patch deleted file mode 100644 index 5ca8933d6fef4b..00000000000000 --- a/target/linux/generic/pending-5.15/840-hwrng-bcm2835-set-quality-to-1000.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d6988cf1d16faac56899918bb2b1be8d85155e3f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 20 Feb 2021 18:36:38 +0100 -Subject: [PATCH] hwrng: bcm2835: set quality to 1000 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows devices without a high precission timer to reduce boot from >100s -to <30s. - -Signed-off-by: Álvaro Fernández Rojas ---- - drivers/char/hw_random/bcm2835-rng.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/char/hw_random/bcm2835-rng.c -+++ b/drivers/char/hw_random/bcm2835-rng.c -@@ -170,6 +170,7 @@ static int bcm2835_rng_probe(struct plat - priv->rng.init = bcm2835_rng_init; - priv->rng.read = bcm2835_rng_read; - priv->rng.cleanup = bcm2835_rng_cleanup; -+ priv->rng.quality = 1000; - - if (dev_of_node(dev)) { - rng_id = of_match_node(bcm2835_rng_of_match, dev->of_node); diff --git a/target/linux/generic/pending-5.15/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch b/target/linux/generic/pending-5.15/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch deleted file mode 100644 index e180a385e11ff1..00000000000000 --- a/target/linux/generic/pending-5.15/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 663b9f99bb35dbc0c7b685f71ee3668a60d31320 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Mon, 10 Jan 2022 02:02:00 +0100 -Subject: [PATCH] PCI: aardvark: Make main irq_chip structure a static driver - structure -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Marc Zyngier says [1] that we should use struct irq_chip as a global -static struct in the driver. Even though the structure currently -contains a dynamic member (parent_device), Marc says [2] that he plans -to kill it and make the structure completely static. - -We have already converted others irq_chip structures in this driver in -this way, but we omitted this one because the .name member is -dynamically created from device's name, and the name is displayed in -sysfs, so changing it would break sysfs ABI. - -The rationale for changing the name (to "advk-INT") in spite of sysfs -ABI, and thus allowing to convert to a static structure, is that after -the other changes we made in this series, the IRQ chip is basically -something different: it no logner generates ERR and PME interrupts (they -are generated by emulated bridge's rp_irq_chip). - -[1] https://lore.kernel.org/linux-pci/877dbcvngf.wl-maz@kernel.org/ -[2] https://lore.kernel.org/linux-pci/874k6gvkhz.wl-maz@kernel.org/ - -Signed-off-by: Marek Behún ---- - drivers/pci/controller/pci-aardvark.c | 25 +++++++------------------ - 1 file changed, 7 insertions(+), 18 deletions(-) - ---- a/drivers/pci/controller/pci-aardvark.c -+++ b/drivers/pci/controller/pci-aardvark.c -@@ -275,7 +275,6 @@ struct advk_pcie { - u8 wins_count; - struct irq_domain *rp_irq_domain; - struct irq_domain *irq_domain; -- struct irq_chip irq_chip; - raw_spinlock_t irq_lock; - struct irq_domain *msi_domain; - struct irq_domain *msi_inner_domain; -@@ -1345,14 +1344,19 @@ static void advk_pcie_irq_unmask(struct - raw_spin_unlock_irqrestore(&pcie->irq_lock, flags); - } - -+static struct irq_chip advk_irq_chip = { -+ .name = "advk-INT", -+ .irq_mask = advk_pcie_irq_mask, -+ .irq_unmask = advk_pcie_irq_unmask, -+}; -+ - static int advk_pcie_irq_map(struct irq_domain *h, - unsigned int virq, irq_hw_number_t hwirq) - { - struct advk_pcie *pcie = h->host_data; - - irq_set_status_flags(virq, IRQ_LEVEL); -- irq_set_chip_and_handler(virq, &pcie->irq_chip, -- handle_level_irq); -+ irq_set_chip_and_handler(virq, &advk_irq_chip, handle_level_irq); - irq_set_chip_data(virq, pcie); - - return 0; -@@ -1411,7 +1415,6 @@ static int advk_pcie_init_irq_domain(str - struct device *dev = &pcie->pdev->dev; - struct device_node *node = dev->of_node; - struct device_node *pcie_intc_node; -- struct irq_chip *irq_chip; - int ret = 0; - - raw_spin_lock_init(&pcie->irq_lock); -@@ -1422,28 +1425,14 @@ static int advk_pcie_init_irq_domain(str - return -ENODEV; - } - -- irq_chip = &pcie->irq_chip; -- -- irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq", -- dev_name(dev)); -- if (!irq_chip->name) { -- ret = -ENOMEM; -- goto out_put_node; -- } -- -- irq_chip->irq_mask = advk_pcie_irq_mask; -- irq_chip->irq_unmask = advk_pcie_irq_unmask; -- - pcie->irq_domain = - irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, - &advk_pcie_irq_domain_ops, pcie); - if (!pcie->irq_domain) { - dev_err(dev, "Failed to get a INTx IRQ domain\n"); - ret = -ENOMEM; -- goto out_put_node; - } - --out_put_node: - of_node_put(pcie_intc_node); - return ret; - } diff --git a/target/linux/generic/pending-5.15/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch b/target/linux/generic/pending-5.15/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch deleted file mode 100644 index cc6f1e0d9dbec4..00000000000000 --- a/target/linux/generic/pending-5.15/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch +++ /dev/null @@ -1,114 +0,0 @@ -From patchwork Wed Mar 22 17:15:12 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13184389 -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 73F2DC6FD1C - for ; Wed, 22 Mar 2023 17:15:59 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S231363AbjCVRP5 (ORCPT ); - Wed, 22 Mar 2023 13:15:57 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58824 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S231408AbjCVRPy (ORCPT - ); Wed, 22 Mar 2023 13:15:54 -0400 -Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com - [IPv6:2a00:1450:4864:20::32d]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70E4C64B28; - Wed, 22 Mar 2023 10:15:24 -0700 (PDT) -Received: by mail-wm1-x32d.google.com with SMTP id n19so1740892wms.0; - Wed, 22 Mar 2023 10:15:24 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679505322; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=dEknM98Izmc8d/crPsoJ+ejZxfl78958Ei6SPYhYDHs=; - b=LTOQ75W3s5nYo+nEfiJAKqytSopONB4jCtU3zRygzPMasugVOrYFMsUR+WrpsAjuRT - v4HgWpJxEsIWeRXrUN9W21mFXhGgJLJXSxRnrio0CsZZBNMdkebbNOphgKXIWAdm+2iM - PzqAdGm5t38wT2mmm6V/9hCy90+12raHM82tNFdhhiezfg2cukVOKP3j/TeOVCwas0gQ - iFc+CuZB6y73zYXvMUMUpTsqI5vev4xJsSMHIQJVmUxJAwqhOBhN9JCRo7Ao+wayjn2d - Fxo6AV3A8v68nVfoQ0K0I+eWXG48nMCX45iWh/lVvVTOFcR99kn4va7NY1oVnPsh+WQz - WcLA== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679505322; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=dEknM98Izmc8d/crPsoJ+ejZxfl78958Ei6SPYhYDHs=; - b=wv2NSR1B5RnsdoEE7mgJSHAfSs1JHZbQ1HPMldyaGWAk1dcucqh/uDzM3Flz+ADRi1 - 19NoaB2Ur7QaWZejbuplnIOK/nte3PnmqJ9ZNw8HejmuS4eU8mB1V1aJUSKSPGsfUi4a - LYe3HSw87l0jrAC7ptdKvdUtzBoIkX0CeFvfguTQQkDhUTyAFIG144hY6uPXY9Mga96b - gnNe2dLCzHQLbEJpaDaavT7FEEcLDxaq7jNcR2xqEEZaIwfcew+Q05t4xL/3i8GAj9Ru - 6ivQjIbBKfYQF88o7KnOW9o1wjrGsk+Nd4Iy0OLZix3JQasCJGrKV7ib5awI9J39upYV - fa4A== -X-Gm-Message-State: AO0yUKWw75I1M5Vjrd4vXq4GTruQu0H84pycgyi2CT3bczTYRJpWmEWg - +bHDhvp1n5IWW85GI9vKWpbclB13a/S0RQ== -X-Google-Smtp-Source: - AK7set9T/2oJsVetUb2L4mPEWu8YqDrnK8EzHK5bJf1ABIa1Et8f7BFJ7AA3j14ITZuf8cH0HqlRtg== -X-Received: by 2002:a05:600c:2304:b0:3ed:2949:985b with SMTP id - 4-20020a05600c230400b003ed2949985bmr206833wmo.23.1679505322457; - Wed, 22 Mar 2023 10:15:22 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.21 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Wed, 22 Mar 2023 10:15:22 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de, - f.fainelli@gmail.com, jonas.gorski@gmail.com, - william.zhang@broadcom.com, linux-clk@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= , - Rob Herring -Subject: [PATCH v4 1/4] dt-bindings: clk: add BCM63268 timer clock definitions -Date: Wed, 22 Mar 2023 18:15:12 +0100 -Message-Id: <20230322171515.120353-2-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230322171515.120353-1-noltari@gmail.com> -References: <20230322171515.120353-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: linux-clk@vger.kernel.org - -Add missing timer clock definitions for BCM63268. - -Signed-off-by: Álvaro Fernández Rojas -Acked-by: Rob Herring ---- - v4: no changes - v3: no changes - v2: change commit title, as suggested by Stephen Boyd - - include/dt-bindings/clock/bcm63268-clock.h | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - ---- a/include/dt-bindings/clock/bcm63268-clock.h -+++ b/include/dt-bindings/clock/bcm63268-clock.h -@@ -27,4 +27,17 @@ - #define BCM63268_CLK_TBUS 27 - #define BCM63268_CLK_ROBOSW250 31 - -+#define BCM63268_TCLK_EPHY1 0 -+#define BCM63268_TCLK_EPHY2 1 -+#define BCM63268_TCLK_EPHY3 2 -+#define BCM63268_TCLK_GPHY1 3 -+#define BCM63268_TCLK_DSL 4 -+#define BCM63268_TCLK_WAKEON_EPHY 6 -+#define BCM63268_TCLK_WAKEON_DSL 7 -+#define BCM63268_TCLK_FAP1 11 -+#define BCM63268_TCLK_FAP2 15 -+#define BCM63268_TCLK_UTO_50 16 -+#define BCM63268_TCLK_UTO_EXTIN 17 -+#define BCM63268_TCLK_USB_REF 18 -+ - #endif /* __DT_BINDINGS_CLOCK_BCM63268_H */ diff --git a/target/linux/generic/pending-5.15/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch b/target/linux/generic/pending-5.15/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch deleted file mode 100644 index 5f1be105ac7295..00000000000000 --- a/target/linux/generic/pending-5.15/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch +++ /dev/null @@ -1,107 +0,0 @@ -From patchwork Wed Mar 22 17:15:13 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13184390 -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id D0B1AC6FD1C - for ; Wed, 22 Mar 2023 17:16:08 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S231472AbjCVRQI (ORCPT ); - Wed, 22 Mar 2023 13:16:08 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58934 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S231435AbjCVRP5 (ORCPT - ); Wed, 22 Mar 2023 13:15:57 -0400 -Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com - [IPv6:2a00:1450:4864:20::329]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9655064863; - Wed, 22 Mar 2023 10:15:25 -0700 (PDT) -Received: by mail-wm1-x329.google.com with SMTP id - v4-20020a05600c470400b003ee4f06428fso2424553wmo.4; - Wed, 22 Mar 2023 10:15:25 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679505324; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=C7ykhArT1dO7P8wtmI92eo4c7KtPZI9w182/5+cB3T0=; - b=WRZRU2SM9n1LfUj4SgTPfQczADC2pfvoIrOsNpBLTym2eOfmkTetb/WbGSla5kw2Wb - SH5MIC2fFeScJg6T5FFAUOOLmRVW9xvl8Q3T3NKb3z/9wvPHO767nrdIbffRWMJFs7gW - wT/kuTpn8GYdfY0sZ/dMTkq41DVusEkxfX6GxtG85O98ZP8xMHQog8aPs9fRfUvI5ZKB - eGYcRz/Wn1cHhjey9jtWzQEEmZ/BT3b0HQTF9Tl88oofhiEgbyjFXr91+vRsLbsJpGXH - /1FjjaLG5DnonKubV9rmbuCU8KzwH331gi2KuRjvLD2V+OMewqSa5i+GvgVv8x2zC8y+ - /mLQ== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679505324; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=C7ykhArT1dO7P8wtmI92eo4c7KtPZI9w182/5+cB3T0=; - b=bhd0fNh0jDOMlGSC4F+p5igV8AUlGEPj2cXUwgdgqRfSSuUy9z+Li8cT0MbY/aWH5Z - qInRVA+R1cWV3ubrDyKag6oEc0LDU234bnMFcP9b7MRlrM8Dpit9TFSyqJU4sDUWNDs5 - KOe2k/SNIdat6munC9VOuEBDO0eB/UDMN+repKwXNdHChp/Toq9qMvW4Uy8uHxosbQlD - 8P88GbKFjynb1E8I8croGjfub7+y8PPsWB0xNUcafIv6xs3MnVOP1Mk4KwBCbqS509la - mfjsriXtIybO8XFqtn100ungjvbFWdogEplLdSPVdgAqdfF5J8gHxAoApoeYejYkL5/R - kOhQ== -X-Gm-Message-State: AO0yUKWdzr3dMmjKhD8tF+ec4Dfdq9VGZ/WCU4d85npKQvxSwhNPZZ1J - 5WYRIqivh0suFC1OqEidwenpiJYvXedYjw== -X-Google-Smtp-Source: - AK7set87ew2/mKWeShXTTW/YBbBJNR2zeGFV0CfuqLXhiJEU6tqFuyKcW+vFEoKHIbNUS8wRy1SzLA== -X-Received: by 2002:a05:600c:290:b0:3ee:6d88:774a with SMTP id - 16-20020a05600c029000b003ee6d88774amr160734wmk.14.1679505323514; - Wed, 22 Mar 2023 10:15:23 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.22 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Wed, 22 Mar 2023 10:15:23 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de, - f.fainelli@gmail.com, jonas.gorski@gmail.com, - william.zhang@broadcom.com, linux-clk@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= , - Rob Herring -Subject: [PATCH v4 2/4] dt-bindings: reset: add BCM63268 timer reset - definitions -Date: Wed, 22 Mar 2023 18:15:13 +0100 -Message-Id: <20230322171515.120353-3-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230322171515.120353-1-noltari@gmail.com> -References: <20230322171515.120353-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: linux-clk@vger.kernel.org - -Add missing timer reset definitions for BCM63268. - -Signed-off-by: Álvaro Fernández Rojas -Acked-by: Rob Herring ---- - v4: no changes - v3: no changes - v2: change commit title, as suggested by Stephen Boyd - - include/dt-bindings/reset/bcm63268-reset.h | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/include/dt-bindings/reset/bcm63268-reset.h -+++ b/include/dt-bindings/reset/bcm63268-reset.h -@@ -23,4 +23,8 @@ - #define BCM63268_RST_PCIE_HARD 17 - #define BCM63268_RST_GPHY 18 - -+#define BCM63268_TRST_SW 29 -+#define BCM63268_TRST_HW 30 -+#define BCM63268_TRST_POR 31 -+ - #endif /* __DT_BINDINGS_RESET_BCM63268_H */ diff --git a/target/linux/generic/pending-5.15/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch b/target/linux/generic/pending-5.15/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch deleted file mode 100644 index 7e500cd1b58c85..00000000000000 --- a/target/linux/generic/pending-5.15/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch +++ /dev/null @@ -1,345 +0,0 @@ -From patchwork Wed Mar 22 17:15:15 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13184392 -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 199D9C76196 - for ; Wed, 22 Mar 2023 17:16:11 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S231512AbjCVRQJ (ORCPT ); - Wed, 22 Mar 2023 13:16:09 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58942 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S231442AbjCVRP5 (ORCPT - ); Wed, 22 Mar 2023 13:15:57 -0400 -Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com - [IPv6:2a00:1450:4864:20::32c]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DDB36487D; - Wed, 22 Mar 2023 10:15:27 -0700 (PDT) -Received: by mail-wm1-x32c.google.com with SMTP id - i5-20020a05600c354500b003edd24054e0so6717370wmq.4; - Wed, 22 Mar 2023 10:15:27 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679505325; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=rkv/eZYA1ncHp5FnV2ZWc3hgYnAx28S86QA9vmcXFCY=; - b=Y1mva2Bt3sUbKxLgEUS331CJbGxUc4z8kTQW8qiHWGhYlFKtm+d5z4sT40E5BeZAnU - zmTbCI7jbroe9NYBxGUmSli6LNVDPjND80ChbhWTqbqMQTmeQFWut9KmeBWK6Oze2lC/ - XMSOorUzowjcU2xtHNrzoq2KH2pstW573lsB8WnzFVfhMaRkE9DfRr6WNyA7zC8DyxM5 - ezxlCQtCmgPfCqlyksbIDKrgrRf3GiUR0yUd6xRU+MssyvH1FkYGDCerPctDto6lGHBz - 8Y15jT3l6OnQMT6dkekgpPF5/XrSUY93u9g0B4U8+0dhNj+K7vmDen+jqdess+tpLnq/ - gFrA== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679505325; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=rkv/eZYA1ncHp5FnV2ZWc3hgYnAx28S86QA9vmcXFCY=; - b=Ym4+u8bbTQGNkewUBrLf+89vE0EFJBQp2f1crwUxZFboKTROF9ltZonY1CGepo7b0B - fkx3TbWQy5X65g3ScuieqtClCI8WanPeNBJ48+JipJYO3ODVNBxnVaTuW/0FOIcahfqe - sG5GvggHhzRz+Yeybsbnupmzxnw8Ez0BpMl3p7zcjHL7BGZDdOOX2Zbw3zfyYa5sg2nX - UXYJT36zy2h39gxUsy9QkhQ76CG3w6omniohZpYidpojpiDjbOy0nKFky4kUe+YyA1fF - 4IBhjAm6mH+uh6wHSG1qj+NAXHs0xDDJps16PbJwAgL7Qt9K5WW+R/UAYPmHFgaRIHOw - /seA== -X-Gm-Message-State: AO0yUKXRtoYO8Nfus6Ca8lhM39P1Xn6TGkhatEfoISd1YNOkTJJN2hW+ - xRphLgxlzNfCLcVPlpGK9dk= -X-Google-Smtp-Source: - AK7set9VnMEykugk8ZYnkXuqK41bX1dzlvKsAXHEjr8i2NZBld0buKhQLcGYEcwxnBgVTtC7eRGfXw== -X-Received: by 2002:a1c:7c0b:0:b0:3e2:1dac:b071 with SMTP id - x11-20020a1c7c0b000000b003e21dacb071mr178053wmc.13.1679505325582; - Wed, 22 Mar 2023 10:15:25 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.24 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Wed, 22 Mar 2023 10:15:25 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de, - f.fainelli@gmail.com, jonas.gorski@gmail.com, - william.zhang@broadcom.com, linux-clk@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v4 4/4] clk: bcm: Add BCM63268 timer clock and reset driver -Date: Wed, 22 Mar 2023 18:15:15 +0100 -Message-Id: <20230322171515.120353-5-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230322171515.120353-1-noltari@gmail.com> -References: <20230322171515.120353-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: linux-clk@vger.kernel.org - -Add driver for BCM63268 timer clock and reset controller. - -Signed-off-by: Álvaro Fernández Rojas ---- - v4: add changes suggested by Stephen Boyd: - - Usage of of_device_get_match_data() isn't needed. - - Use devm_clk_hw_register_gate(). - - Drop clk_hw_unregister_gate(). - v3: add missing include to fix build warning - v2: add changes suggested by Stephen Boyd - - drivers/clk/bcm/Kconfig | 9 ++ - drivers/clk/bcm/Makefile | 1 + - drivers/clk/bcm/clk-bcm63268-timer.c | 215 +++++++++++++++++++++++++++ - 3 files changed, 225 insertions(+) - create mode 100644 drivers/clk/bcm/clk-bcm63268-timer.c - ---- a/drivers/clk/bcm/Kconfig -+++ b/drivers/clk/bcm/Kconfig -@@ -37,6 +37,15 @@ config CLK_BCM_63XX_GATE - Enable common clock framework support for Broadcom BCM63xx DSL SoCs - based on the MIPS architecture - -+config CLK_BCM63268_TIMER -+ bool "Broadcom BCM63268 timer clock and reset support" -+ depends on BMIPS_GENERIC || COMPILE_TEST -+ default BMIPS_GENERIC -+ select RESET_CONTROLLER -+ help -+ Enable timer clock and reset support for Broadcom BCM63268 DSL SoCs -+ based on the MIPS architecture. -+ - config CLK_BCM_KONA - bool "Broadcom Kona CCU clock support" - depends on ARCH_BCM_MOBILE || COMPILE_TEST ---- a/drivers/clk/bcm/Makefile -+++ b/drivers/clk/bcm/Makefile -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o - obj-$(CONFIG_CLK_BCM_63XX_GATE) += clk-bcm63xx-gate.o -+obj-$(CONFIG_CLK_BCM63268_TIMER) += clk-bcm63268-timer.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o ---- /dev/null -+++ b/drivers/clk/bcm/clk-bcm63268-timer.c -@@ -0,0 +1,215 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * BCM63268 Timer Clock and Reset Controller Driver -+ * -+ * Copyright (C) 2023 Álvaro Fernández Rojas -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define BCM63268_TIMER_RESET_SLEEP_MIN_US 10000 -+#define BCM63268_TIMER_RESET_SLEEP_MAX_US 20000 -+ -+struct bcm63268_tclkrst_hw { -+ void __iomem *regs; -+ spinlock_t lock; -+ -+ struct reset_controller_dev rcdev; -+ struct clk_hw_onecell_data data; -+}; -+ -+struct bcm63268_tclk_table_entry { -+ const char * const name; -+ u8 bit; -+}; -+ -+static const struct bcm63268_tclk_table_entry bcm63268_timer_clocks[] = { -+ { -+ .name = "ephy1", -+ .bit = BCM63268_TCLK_EPHY1, -+ }, { -+ .name = "ephy2", -+ .bit = BCM63268_TCLK_EPHY2, -+ }, { -+ .name = "ephy3", -+ .bit = BCM63268_TCLK_EPHY3, -+ }, { -+ .name = "gphy1", -+ .bit = BCM63268_TCLK_GPHY1, -+ }, { -+ .name = "dsl", -+ .bit = BCM63268_TCLK_DSL, -+ }, { -+ .name = "wakeon_ephy", -+ .bit = BCM63268_TCLK_WAKEON_EPHY, -+ }, { -+ .name = "wakeon_dsl", -+ .bit = BCM63268_TCLK_WAKEON_DSL, -+ }, { -+ .name = "fap1_pll", -+ .bit = BCM63268_TCLK_FAP1, -+ }, { -+ .name = "fap2_pll", -+ .bit = BCM63268_TCLK_FAP2, -+ }, { -+ .name = "uto_50", -+ .bit = BCM63268_TCLK_UTO_50, -+ }, { -+ .name = "uto_extin", -+ .bit = BCM63268_TCLK_UTO_EXTIN, -+ }, { -+ .name = "usb_ref", -+ .bit = BCM63268_TCLK_USB_REF, -+ }, { -+ /* sentinel */ -+ } -+}; -+ -+static inline struct bcm63268_tclkrst_hw * -+to_bcm63268_timer_reset(struct reset_controller_dev *rcdev) -+{ -+ return container_of(rcdev, struct bcm63268_tclkrst_hw, rcdev); -+} -+ -+static int bcm63268_timer_reset_update(struct reset_controller_dev *rcdev, -+ unsigned long id, bool assert) -+{ -+ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev); -+ unsigned long flags; -+ uint32_t val; -+ -+ spin_lock_irqsave(&reset->lock, flags); -+ val = __raw_readl(reset->regs); -+ if (assert) -+ val &= ~BIT(id); -+ else -+ val |= BIT(id); -+ __raw_writel(val, reset->regs); -+ spin_unlock_irqrestore(&reset->lock, flags); -+ -+ return 0; -+} -+ -+static int bcm63268_timer_reset_assert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ return bcm63268_timer_reset_update(rcdev, id, true); -+} -+ -+static int bcm63268_timer_reset_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ return bcm63268_timer_reset_update(rcdev, id, false); -+} -+ -+static int bcm63268_timer_reset_reset(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ bcm63268_timer_reset_update(rcdev, id, true); -+ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US, -+ BCM63268_TIMER_RESET_SLEEP_MAX_US); -+ -+ bcm63268_timer_reset_update(rcdev, id, false); -+ /* -+ * Ensure component is taken out reset state by sleeping also after -+ * deasserting the reset. Otherwise, the component may not be ready -+ * for operation. -+ */ -+ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US, -+ BCM63268_TIMER_RESET_SLEEP_MAX_US); -+ -+ return 0; -+} -+ -+static int bcm63268_timer_reset_status(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev); -+ -+ return !(__raw_readl(reset->regs) & BIT(id)); -+} -+ -+static struct reset_control_ops bcm63268_timer_reset_ops = { -+ .assert = bcm63268_timer_reset_assert, -+ .deassert = bcm63268_timer_reset_deassert, -+ .reset = bcm63268_timer_reset_reset, -+ .status = bcm63268_timer_reset_status, -+}; -+ -+static int bcm63268_tclk_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ const struct bcm63268_tclk_table_entry *entry; -+ struct bcm63268_tclkrst_hw *hw; -+ struct clk_hw *clk; -+ u8 maxbit = 0; -+ int i, ret; -+ -+ for (entry = bcm63268_timer_clocks; entry->name; entry++) -+ maxbit = max(maxbit, entry->bit); -+ maxbit++; -+ -+ hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit), -+ GFP_KERNEL); -+ if (!hw) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, hw); -+ -+ spin_lock_init(&hw->lock); -+ -+ hw->data.num = maxbit; -+ for (i = 0; i < maxbit; i++) -+ hw->data.hws[i] = ERR_PTR(-ENODEV); -+ -+ hw->regs = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(hw->regs)) -+ return PTR_ERR(hw->regs); -+ -+ for (entry = bcm63268_timer_clocks; entry->name; entry++) { -+ clk = devm_clk_hw_register_gate(dev, entry->name, NULL, 0, -+ hw->regs, entry->bit, -+ CLK_GATE_BIG_ENDIAN, -+ &hw->lock); -+ if (IS_ERR(clk)) -+ return PTR_ERR(clk); -+ -+ hw->data.hws[entry->bit] = clk; -+ } -+ -+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, -+ &hw->data); -+ if (ret) -+ return ret; -+ -+ hw->rcdev.of_node = dev->of_node; -+ hw->rcdev.ops = &bcm63268_timer_reset_ops; -+ -+ ret = devm_reset_controller_register(dev, &hw->rcdev); -+ if (ret) -+ dev_err(dev, "Failed to register reset controller\n"); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm63268_tclk_dt_ids[] = { -+ { .compatible = "brcm,bcm63268-timer-clocks" }, -+ { /* sentinel */ } -+}; -+ -+static struct platform_driver bcm63268_tclk = { -+ .probe = bcm63268_tclk_probe, -+ .driver = { -+ .name = "bcm63268-timer-clock", -+ .of_match_table = bcm63268_tclk_dt_ids, -+ }, -+}; -+builtin_platform_driver(bcm63268_tclk); diff --git a/target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch b/target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch deleted file mode 100644 index c5db5d9491d410..00000000000000 --- a/target/linux/generic/pending-5.15/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 629c701fc39f1ada9416e0766a86729e83bde86c Mon Sep 17 00:00:00 2001 -Message-ID: <629c701fc39f1ada9416e0766a86729e83bde86c.1694465766.git.daniel@makrotopia.org> -From: Daniel Golle -Date: Mon, 11 Sep 2023 21:27:44 +0100 -Subject: [PATCH] serial: 8250_mtk: track busclk state to avoid bus error -To: Greg Kroah-Hartman , - Jiri Slaby , - Matthias Brugger , - AngeloGioacchino Del Regno , - Daniel Golle , - John Ogness , - Chen-Yu Tsai , - Changqi Hu , - linux-kernel@vger.kernel.org, - linux-serial@vger.kernel.org, - linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org - -Commit e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and -clock management") introduced polling a debug register to make sure -the UART is idle before disabling the bus clock. However, at least on -some MediaTek SoCs access to that very debug register requires the bus -clock being enabled. Hence calling the suspend function while already -in suspended state results in that register access triggering a bus -error. In order to avoid that, track the state of the bus clock and -only poll the debug register if not already in suspended state. - -Fixes: e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and clock management") -Signed-off-by: Daniel Golle ---- - drivers/tty/serial/8250/8250_mtk.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - ---- a/drivers/tty/serial/8250/8250_mtk.c -+++ b/drivers/tty/serial/8250/8250_mtk.c -@@ -32,7 +32,7 @@ - #define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */ - #define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */ - #define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */ --#define MTK_UART_DEBUG0 0x18 -+#define MTK_UART_DEBUG0 0x18 - #define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */ - #define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */ - #define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */ -@@ -418,13 +418,12 @@ static int __maybe_unused mtk8250_runtim - struct mtk8250_data *data = dev_get_drvdata(dev); - struct uart_8250_port *up = serial8250_get_port(data->line); - -- /* wait until UART in idle status */ -- while -- (serial_in(up, MTK_UART_DEBUG0)); -- - if (data->clk_count == 0U) { - dev_dbg(dev, "%s clock count is 0\n", __func__); - } else { -+ /* wait until UART in idle status */ -+ while -+ (serial_in(up, MTK_UART_DEBUG0)); - clk_disable_unprepare(data->bus_clk); - data->clk_count--; - } diff --git a/target/linux/generic/pending-5.15/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch b/target/linux/generic/pending-5.15/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch deleted file mode 100644 index 186b052d40c862..00000000000000 --- a/target/linux/generic/pending-5.15/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 89a74fc5d367441bf4912e9158f0640ea3494b9e Mon Sep 17 00:00:00 2001 -From: Lech Perczak -Date: Fri, 17 Nov 2023 21:33:04 +0100 -Subject: [PATCH] ARM: dts: nxp: imx7d-pico: add cpu-supply nodes - -The PICO-IMX7D SoM has the usual power supply configuration using -output sw1a of PF3000 PMIC, which was defined in downstream derivative -of linux-imx (see link) in the sources for "Android Things" devkit. -It is required to support CPU frequency scaling. - -Map the respective "cpu-supply" nodes of each core to sw1a of the PMIC. - -Enabling them causes cpufreq-dt, and imx-thermal drivers to probe -successfully, and CPU frequency scaling to function. - -Link: https://android.googlesource.com/platform/hardware/bsp/kernel/nxp/imx-v4.1/+/o-iot-preview-5/arch/arm/boot/dts/imx7d-pico.dtsi#849 - -Cc: Fabio Estevam -Cc: Shawn Guo -Cc: Sascha Hauer - -Signed-off-by: Lech Perczak ---- - arch/arm/boot/dts/imx7d-pico.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/arch/arm/boot/dts/imx7d-pico.dtsi -+++ b/arch/arm/boot/dts/imx7d-pico.dtsi -@@ -108,6 +108,14 @@ - assigned-clock-rates = <0>, <32768>; - }; - -+&cpu0 { -+ cpu-supply = <&sw1a_reg>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&sw1a_reg>; -+}; -+ - &ecspi3 { - cs-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; - pinctrl-names = "default"; diff --git a/target/linux/generic/pending-5.15/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch b/target/linux/generic/pending-5.15/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch deleted file mode 100644 index 04c6efe3e83b41..00000000000000 --- a/target/linux/generic/pending-5.15/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 38eb5b3370c29515d2ce92adac2d6eba96f276f5 Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Wed, 20 Mar 2024 15:32:18 +0900 -Subject: [PATCH v2 1/2] dt-bindings: leds: add LED_FUNCTION_MOBILE for mobile - network - -Add LED_FUNCTION_MOBILE for LEDs that indicate status of mobile network -connection. This is useful to distinguish those LEDs from LEDs that -indicates status of wired "wan" connection. - -example (on stock fw): - -IIJ SA-W2 has "Mobile" LEDs that indicate status (no signal, too low, -low, good) of mobile network connection via dongle connected to USB -port. - -- no signal: (none, turned off) -- too low: green:mobile & red:mobile (amber, blink) -- low: green:mobile & red:mobile (amber, turned on) -- good: green:mobile (turned on) - -Suggested-by: Hauke Mehrtens -Signed-off-by: INAGAKI Hiroshi ---- - include/dt-bindings/leds/common.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/dt-bindings/leds/common.h -+++ b/include/dt-bindings/leds/common.h -@@ -83,6 +83,7 @@ - #define LED_FUNCTION_INDICATOR "indicator" - #define LED_FUNCTION_LAN "lan" - #define LED_FUNCTION_MAIL "mail" -+#define LED_FUNCTION_MOBILE "mobile" - #define LED_FUNCTION_MTD "mtd" - #define LED_FUNCTION_PANIC "panic" - #define LED_FUNCTION_PROGRAMMING "programming" diff --git a/target/linux/generic/pending-5.15/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch b/target/linux/generic/pending-5.15/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch deleted file mode 100644 index e6014814467390..00000000000000 --- a/target/linux/generic/pending-5.15/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch +++ /dev/null @@ -1,37 +0,0 @@ -From e22afe910afcfb51b6ba6a0ae776939959727f54 Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Wed, 20 Mar 2024 15:59:06 +0900 -Subject: [PATCH v2 2/2] dt-bindings: leds: add LED_FUNCTION_SPEED_* for link - speed on LAN/WAN - -Add LED_FUNCTION_SPEED_LAN and LED_FUNCTION_SPEED_WAN for LEDs that -indicate link speed of ethernet ports on LAN/WAN. This is useful to -distinguish those LEDs from LEDs that indicate link status (up/down). - -example: - -Fortinet FortiGate 30E/50E have LEDs that indicate link speed on each -of the ethernet ports in addition to LEDs that indicate link status -(up/down). - -- 1000 Mbps: green:speed-(lan|wan)-N -- 100 Mbps: amber:speed-(lan|wan)-N -- 10 Mbps: (none, turned off) - -Reviewed-by: Rob Herring -Signed-off-by: INAGAKI Hiroshi ---- - include/dt-bindings/leds/common.h | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/include/dt-bindings/leds/common.h -+++ b/include/dt-bindings/leds/common.h -@@ -89,6 +89,8 @@ - #define LED_FUNCTION_PROGRAMMING "programming" - #define LED_FUNCTION_RX "rx" - #define LED_FUNCTION_SD "sd" -+#define LED_FUNCTION_SPEED_LAN "speed-lan" -+#define LED_FUNCTION_SPEED_WAN "speed-wan" - #define LED_FUNCTION_STANDBY "standby" - #define LED_FUNCTION_TORCH "torch" - #define LED_FUNCTION_TX "tx" diff --git a/target/linux/generic/pending-5.15/920-mangle_bootargs.patch b/target/linux/generic/pending-5.15/920-mangle_bootargs.patch deleted file mode 100644 index b127d76e005b9a..00000000000000 --- a/target/linux/generic/pending-5.15/920-mangle_bootargs.patch +++ /dev/null @@ -1,71 +0,0 @@ -From: Imre Kaloz -Subject: init: add CONFIG_MANGLE_BOOTARGS and disable it by default - -Enabling this option renames the bootloader supplied root= -and rootfstype= variables, which might have to be know but -would break the automatisms OpenWrt uses. - -Signed-off-by: Imre Kaloz ---- - init/Kconfig | 9 +++++++++ - init/main.c | 24 ++++++++++++++++++++++++ - 2 files changed, 33 insertions(+) - ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1814,6 +1814,15 @@ config EMBEDDED - an embedded system so certain expert options are available - for configuration. - -+config MANGLE_BOOTARGS -+ bool "Rename offending bootargs" -+ depends on EXPERT -+ help -+ Sometimes the bootloader passed bogus root= and rootfstype= -+ parameters to the kernel, and while you want to ignore them, -+ you need to know the values f.e. to support dual firmware -+ layouts on the flash. -+ - config HAVE_PERF_EVENTS - bool - help ---- a/init/main.c -+++ b/init/main.c -@@ -619,6 +619,29 @@ static inline void setup_nr_cpu_ids(void - static inline void smp_prepare_cpus(unsigned int maxcpus) { } - #endif - -+#ifdef CONFIG_MANGLE_BOOTARGS -+static void __init mangle_bootargs(char *command_line) -+{ -+ char *rootdev; -+ char *rootfs; -+ -+ rootdev = strstr(command_line, "root=/dev/mtdblock"); -+ -+ if (rootdev) -+ strncpy(rootdev, "mangled_rootblock=", 18); -+ -+ rootfs = strstr(command_line, "rootfstype"); -+ -+ if (rootfs) -+ strncpy(rootfs, "mangled_fs", 10); -+ -+} -+#else -+static void __init mangle_bootargs(char *command_line) -+{ -+} -+#endif -+ - /* - * We need to store the untouched command line for future reference. - * We also need to store the touched command line since the parameter -@@ -960,6 +983,7 @@ asmlinkage __visible void __init __no_sa - pr_notice("%s", linux_banner); - early_security_init(); - setup_arch(&command_line); -+ mangle_bootargs(command_line); - setup_boot_config(); - setup_command_line(command_line); - setup_nr_cpu_ids(); diff --git a/target/linux/generic/pending-5.15/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch b/target/linux/generic/pending-5.15/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch deleted file mode 100644 index 6a0a19987fad6b..00000000000000 --- a/target/linux/generic/pending-5.15/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a7a94ca21ac0f347f683d33c72b4aab57ce5eec3 Mon Sep 17 00:00:00 2001 -From: Florian Eckert -Date: Mon, 20 Nov 2023 11:13:20 +0100 -Subject: [PATCH] tools/thermal/tmon: Fix compilation warning for wrong format - -The following warnings are shown during compilation: - -tui.c: In function 'show_cooling_device': - tui.c:216:40: warning: format '%d' expects argument of type 'int', but -argument 7 has type 'long unsigned int' [-Wformat=] - 216 | "%02d %12.12s%6d %6d", - | ~~^ - | | - | int - | %6ld - ...... - 219 | ptdata.cdi[j].cur_state, - | ~~~~~~~~~~~~~~~~~~~~~~~ - | | - | long unsigned int - tui.c:216:44: warning: format '%d' expects argument of type 'int', but -argument 8 has type 'long unsigned int' [-Wformat=] - 216 | "%02d %12.12s%6d %6d", - | ~~^ - | | - | int - | %6ld - ...... - 220 | ptdata.cdi[j].max_state); - | ~~~~~~~~~~~~~~~~~~~~~~~ - | | - | long unsigned int - -To fix this, the correct string format must be used for printing. - -Signed-off-by: Florian Eckert ---- - tools/thermal/tmon/tui.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/tools/thermal/tmon/tui.c -+++ b/tools/thermal/tmon/tui.c -@@ -213,7 +213,7 @@ void show_cooling_device(void) - * cooling device instances. skip unused idr. - */ - mvwprintw(cooling_device_window, j + 2, 1, -- "%02d %12.12s%6d %6d", -+ "%02d %12.12s%6lu %6lu", - ptdata.cdi[j].instance, - ptdata.cdi[j].type, - ptdata.cdi[j].cur_state, From 1a728cfc1a56b7df89a99359c4b544eb02d540a5 Mon Sep 17 00:00:00 2001 From: Mieczyslaw Nalewaj Date: Wed, 18 Sep 2024 10:48:03 +0200 Subject: [PATCH 03/23] packages: remove kernel 5.15 remnants Remove kernel 5.15 remnants. Signed-off-by: Mieczyslaw Nalewaj Link: https://github.com/openwrt/openwrt/pull/16417 Signed-off-by: Robert Marko --- package/kernel/linux/modules/fs.mk | 17 ++++++----------- package/kernel/linux/modules/hwmon.mk | 4 ++-- package/kernel/linux/modules/lib.mk | 2 +- package/kernel/linux/modules/netdevices.mk | 4 ++-- package/kernel/linux/modules/netfilter.mk | 2 +- package/kernel/linux/modules/other.mk | 2 +- package/kernel/linux/modules/usb.mk | 4 ++-- package/kernel/linux/modules/video.mk | 22 +++++++++------------- package/kernel/mac80211/ath.mk | 2 +- package/kernel/mac80211/intel.mk | 2 +- package/utils/fitblk/Makefile | 1 - 11 files changed, 26 insertions(+), 36 deletions(-) diff --git a/package/kernel/linux/modules/fs.mk b/package/kernel/linux/modules/fs.mk index bc55dbd96779c1..7d3180febf2fce 100644 --- a/package/kernel/linux/modules/fs.mk +++ b/package/kernel/linux/modules/fs.mk @@ -10,7 +10,7 @@ FS_MENU:=Filesystems define KernelPackage/fs-9p SUBMENU:=$(FS_MENU) TITLE:=Plan 9 Resource Sharing Support - DEPENDS:=+kmod-9pnet +LINUX_6_1:kmod-fs-netfs +LINUX_6_6:kmod-fs-netfs + DEPENDS:=+kmod-9pnet +kmod-fs-netfs KCONFIG:=\ CONFIG_9P_FS \ CONFIG_9P_FS_POSIX_ACL=n \ @@ -89,13 +89,10 @@ define KernelPackage/fs-smbfs-common HIDDEN:=1 DEPENDS:=+LINUX_6_6:kmod-fs-netfs +LINUX_6_6:kmod-nls-ucs2-utils KCONFIG:=\ - CONFIG_SMBFS_COMMON@lt6.1 \ - CONFIG_SMBFS@ge6.1 + CONFIG_SMBFS FILES:= \ - $(LINUX_DIR)/fs/smbfs_common/cifs_arc4.ko@lt6.1 \ - $(LINUX_DIR)/fs/smbfs_common/cifs_md4.ko@lt6.1 \ - $(LINUX_DIR)/fs/smb/common/cifs_arc4.ko@ge6.1 \ - $(LINUX_DIR)/fs/smb/common/cifs_md4.ko@ge6.1 + $(LINUX_DIR)/fs/smb/common/cifs_arc4.ko \ + $(LINUX_DIR)/fs/smb/common/cifs_md4.ko endef define KernelPackage/fs-smbfs-common/description @@ -113,8 +110,7 @@ define KernelPackage/fs-cifs CONFIG_CIFS_DFS_UPCALL=n \ CONFIG_CIFS_UPCALL=n FILES:= \ - $(LINUX_DIR)/fs/cifs/cifs.ko@lt6.1 \ - $(LINUX_DIR)/fs/smb/client/cifs.ko@ge6.1 + $(LINUX_DIR)/fs/smb/client/cifs.ko AUTOLOAD:=$(call AutoLoad,30,cifs) $(call AddDepends/nls) DEPENDS+= \ @@ -380,8 +376,7 @@ define KernelPackage/fs-ksmbd CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN=n \ CONFIG_SMB_SERVER_KERBEROS5=n FILES:= \ - $(LINUX_DIR)/fs/ksmbd/ksmbd.ko@lt6.1 \ - $(LINUX_DIR)/fs/smb/server/ksmbd.ko@ge6.1 + $(LINUX_DIR)/fs/smb/server/ksmbd.ko AUTOLOAD:=$(call AutoLoad,41,ksmbd) endef diff --git a/package/kernel/linux/modules/hwmon.mk b/package/kernel/linux/modules/hwmon.mk index 9a329bc6bca97a..dc921f8fca8582 100644 --- a/package/kernel/linux/modules/hwmon.mk +++ b/package/kernel/linux/modules/hwmon.mk @@ -52,7 +52,7 @@ define KernelPackage/hwmon-adt7410 $(LINUX_DIR)/drivers/hwmon/adt7x10.ko \ $(LINUX_DIR)/drivers/hwmon/adt7410.ko AUTOLOAD:=$(call AutoLoad,60,adt7x10 adt7410) - $(call AddDepends/hwmon,+kmod-i2c-core +!LINUX_5_15:kmod-regmap-core) + $(call AddDepends/hwmon,+kmod-i2c-core +kmod-regmap-core) endef define KernelPackage/hwmon-adt7410/description @@ -130,7 +130,7 @@ define KernelPackage/hwmon-emc2305 KCONFIG:=CONFIG_SENSORS_EMC2305 FILES:=$(LINUX_DIR)/drivers/hwmon/emc2305.ko AUTOLOAD:=$(call AutoProbe,emc2305) - $(call AddDepends/hwmon,+kmod-i2c-core +PACKAGE_kmod-thermal:kmod-thermal +kmod-regmap-i2c @LINUX_6_1||LINUX_6_6) + $(call AddDepends/hwmon,+kmod-i2c-core +PACKAGE_kmod-thermal:kmod-thermal +kmod-regmap-i2c) endef define KernelPackage/hwmon-emc2305/description diff --git a/package/kernel/linux/modules/lib.mk b/package/kernel/linux/modules/lib.mk index ea4f034b998a2a..dc51cd00713039 100644 --- a/package/kernel/linux/modules/lib.mk +++ b/package/kernel/linux/modules/lib.mk @@ -143,7 +143,7 @@ define KernelPackage/lib-zstd CONFIG_ZSTD_DECOMPRESS FILES:= \ $(LINUX_DIR)/crypto/zstd.ko \ - $(LINUX_DIR)/lib/zstd/zstd_common.ko@ge6.1 \ + $(LINUX_DIR)/lib/zstd/zstd_common.ko \ $(LINUX_DIR)/lib/zstd/zstd_compress.ko \ $(LINUX_DIR)/lib/zstd/zstd_decompress.ko AUTOLOAD:=$(call AutoProbe,zstd zstd_compress zstd_decompress) diff --git a/package/kernel/linux/modules/netdevices.mk b/package/kernel/linux/modules/netdevices.mk index 312f310485d2bb..ab5232650c7163 100644 --- a/package/kernel/linux/modules/netdevices.mk +++ b/package/kernel/linux/modules/netdevices.mk @@ -378,7 +378,7 @@ $(eval $(call KernelPackage,phy-smsc)) define KernelPackage/phy-airoha-en8811h SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=Airoha EN8811H 2.5G Ethernet PHY - DEPENDS:=+airoha-en8811h-firmware +kmod-libphy @!LINUX_5_15 + DEPENDS:=+airoha-en8811h-firmware +kmod-libphy KCONFIG:=CONFIG_AIR_EN8811H_PHY FILES:= \ $(LINUX_DIR)/drivers/net/phy/air_en8811h.ko @@ -1737,7 +1737,7 @@ $(eval $(call KernelPackage,mhi-wwan-mbim)) define KernelPackage/mtk-t7xx SUBMENU:=$(NETWORK_DEVICES_MENU) TITLE:=MediaTek T7xx 5G modem - DEPENDS:=@!LINUX_5_15 @PCI_SUPPORT +kmod-wwan + DEPENDS:=@PCI_SUPPORT +kmod-wwan KCONFIG:=CONFIG_MTK_T7XX FILES:=$(LINUX_DIR)/drivers/net/wwan/t7xx/mtk_t7xx.ko AUTOLOAD:=$(call AutoProbe,mtk_t7xx) diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk index 3cf63982ba4416..42c20a288fe00d 100644 --- a/package/kernel/linux/modules/netfilter.mk +++ b/package/kernel/linux/modules/netfilter.mk @@ -823,7 +823,7 @@ define KernelPackage/ipt-clusterip KCONFIG:=$(KCONFIG_IPT_CLUSTERIP) FILES:=$(foreach mod,$(IPT_CLUSTERIP-m),$(LINUX_DIR)/net/$(mod).ko) AUTOLOAD:=$(call AutoProbe,$(notdir $(IPT_CLUSTERIP-m))) - $(call AddDepends/ipt,+kmod-nf-conntrack @LINUX_5_15||LINUX_6_1) + $(call AddDepends/ipt,+kmod-nf-conntrack @LINUX_6_1) endef define KernelPackage/ipt-clusterip/description diff --git a/package/kernel/linux/modules/other.mk b/package/kernel/linux/modules/other.mk index 1d762e6b338232..222f8880bd47b1 100644 --- a/package/kernel/linux/modules/other.mk +++ b/package/kernel/linux/modules/other.mk @@ -597,7 +597,7 @@ define KernelPackage/mtdtests $(LINUX_DIR)/drivers/mtd/tests/mtd_speedtest.ko \ $(LINUX_DIR)/drivers/mtd/tests/mtd_stresstest.ko \ $(LINUX_DIR)/drivers/mtd/tests/mtd_subpagetest.ko \ - $(LINUX_DIR)/drivers/mtd/tests/mtd_test.ko@ge6.1 \ + $(LINUX_DIR)/drivers/mtd/tests/mtd_test.ko \ $(LINUX_DIR)/drivers/mtd/tests/mtd_torturetest.ko endef diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk index b0037378342149..9d33bacfc31ff4 100644 --- a/package/kernel/linux/modules/usb.mk +++ b/package/kernel/linux/modules/usb.mk @@ -1200,7 +1200,7 @@ define KernelPackage/usb-net-asix TITLE:=Kernel module for USB-to-Ethernet Asix convertors DEPENDS:= \ +kmod-libphy +kmod-net-selftests +kmod-mdio-devres +kmod-phy-ax88796b \ - +LINUX_6_1:kmod-phylink +LINUX_6_6:kmod-phylink + +kmod-phylink KCONFIG:=CONFIG_USB_NET_AX8817X FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/asix.ko AUTOLOAD:=$(call AutoProbe,asix) @@ -1328,7 +1328,7 @@ $(eval $(call KernelPackage,usb-net-smsc75xx)) define KernelPackage/usb-net-smsc95xx TITLE:=SMSC LAN95XX based USB 2.0 10/100 ethernet devices - DEPENDS:=+kmod-libphy +kmod-phy-smsc +!LINUX_5_15:kmod-net-selftests + DEPENDS:=+kmod-libphy +kmod-phy-smsc +kmod-net-selftests KCONFIG:=CONFIG_USB_NET_SMSC95XX FILES:=$(LINUX_DIR)/drivers/$(USBNET_DIR)/smsc95xx.ko AUTOLOAD:=$(call AutoProbe,smsc95xx) diff --git a/package/kernel/linux/modules/video.mk b/package/kernel/linux/modules/video.mk index bbfceb691b52a4..8a1c4fdfa36ebf 100644 --- a/package/kernel/linux/modules/video.mk +++ b/package/kernel/linux/modules/video.mk @@ -268,7 +268,7 @@ $(eval $(call KernelPackage,drm)) define KernelPackage/drm-buddy SUBMENU:=$(VIDEO_MENU) TITLE:=A page based buddy allocator - DEPENDS:=@DISPLAY_SUPPORT +kmod-drm @LINUX_6_1||LINUX_6_6 + DEPENDS:=@DISPLAY_SUPPORT +kmod-drm KCONFIG:=CONFIG_DRM_BUDDY FILES:= $(LINUX_DIR)/drivers/gpu/drm/drm_buddy.ko AUTOLOAD:=$(call AutoProbe,drm_buddy) @@ -283,7 +283,7 @@ $(eval $(call KernelPackage,drm-buddy)) define KernelPackage/drm-display-helper SUBMENU:=$(VIDEO_MENU) TITLE:=DRM helpers for display adapters drivers - DEPENDS:=@DISPLAY_SUPPORT +kmod-drm-kms-helper @LINUX_6_1||LINUX_6_6 + DEPENDS:=@DISPLAY_SUPPORT +kmod-drm-kms-helper KCONFIG:=CONFIG_DRM_DISPLAY_HELPER FILES:=$(LINUX_DIR)/drivers/gpu/drm/display/drm_display_helper.ko AUTOLOAD:=$(call AutoProbe,drm_display_helper) @@ -428,7 +428,7 @@ define KernelPackage/drm-imx FILES:= \ $(LINUX_DIR)/drivers/gpu/drm/imx/imxdrm.ko@lt6.6 \ $(LINUX_DIR)/drivers/gpu/drm/imx/ipuv3/imxdrm.ko@ge6.6 \ - $(LINUX_DIR)/drivers/gpu/drm/drm_dma_helper.ko@ge6.1 \ + $(LINUX_DIR)/drivers/gpu/drm/drm_dma_helper.ko \ $(LINUX_DIR)/drivers/gpu/ipu-v3/imx-ipu-v3.ko AUTOLOAD:=$(call AutoLoad,08,imxdrm imx-ipu-v3 imx-ipuv3-crtc) endef @@ -476,8 +476,7 @@ define KernelPackage/drm-imx-ldb CONFIG_DRM_PANEL_SITRONIX_ST7789V=n FILES:=$(LINUX_DIR)/drivers/gpu/drm/imx/imx-ldb.ko@lt6.6 \ $(LINUX_DIR)/drivers/gpu/drm/imx/ipuv3/imx-ldb.ko@ge6.6 \ - $(LINUX_DIR)/drivers/gpu/drm/panel/panel-simple.ko \ - $(LINUX_DIR)/drivers/gpu/drm/drm_dp_aux_bus.ko@lt6.1 + $(LINUX_DIR)/drivers/gpu/drm/panel/panel-simple.ko AUTOLOAD:=$(call AutoLoad,08,imx-ldb) endef @@ -517,7 +516,7 @@ define KernelPackage/video-core CONFIG_MEDIA_CAMERA_SUPPORT=y \ CONFIG_VIDEO_DEV \ CONFIG_V4L_PLATFORM_DRIVERS=y \ - CONFIG_MEDIA_PLATFORM_DRIVERS=y@ge6.1 + CONFIG_MEDIA_PLATFORM_DRIVERS=y FILES:= \ $(LINUX_DIR)/drivers/media/$(V4L2_DIR)/videodev.ko AUTOLOAD:=$(call AutoLoad,60,videodev) @@ -572,7 +571,7 @@ $(eval $(call KernelPackage,video-videobuf2)) define KernelPackage/video-cpia2 TITLE:=CPIA2 video driver - DEPENDS:=@USB_SUPPORT +kmod-usb-core @LINUX_5_15 + DEPENDS:=@USB_SUPPORT KCONFIG:=CONFIG_VIDEO_CPIA2 FILES:=$(LINUX_DIR)/drivers/media/$(V4L2_USB_DIR)/cpia2/cpia2.ko AUTOLOAD:=$(call AutoProbe,cpia2) @@ -1234,10 +1233,8 @@ define KernelPackage/video-coda CONFIG_VIDEO_CODA \ CONFIG_VIDEO_IMX_VDOA FILES:= \ - $(LINUX_DIR)/drivers/media/$(V4L2_MEM2MEM_DIR)/coda/coda-vpu.ko@lt6.1 \ - $(LINUX_DIR)/drivers/media/$(V4L2_MEM2MEM_DIR)/chips-media/coda-vpu.ko@ge6.1 \ - $(LINUX_DIR)/drivers/media/$(V4L2_MEM2MEM_DIR)/coda/imx-vdoa.ko@lt6.1 \ - $(LINUX_DIR)/drivers/media/$(V4L2_MEM2MEM_DIR)/chips-media/imx-vdoa.ko@ge6.1 \ + $(LINUX_DIR)/drivers/media/$(V4L2_MEM2MEM_DIR)/chips-media/coda-vpu.ko \ + $(LINUX_DIR)/drivers/media/$(V4L2_MEM2MEM_DIR)/chips-media/imx-vdoa.ko \ $(LINUX_DIR)/drivers/media/$(V4L2_DIR)/v4l2-jpeg.ko AUTOLOAD:=$(call AutoProbe,coda-vpu imx-vdoa v4l2-jpeg) $(call AddDepends/video) @@ -1253,8 +1250,7 @@ define KernelPackage/video-pxp TITLE:=i.MX PXP support DEPENDS:=@TARGET_imx +kmod-video-mem2mem +kmod-video-dma-contig KCONFIG:= CONFIG_VIDEO_IMX_PXP - FILES:= $(LINUX_DIR)/drivers/media/$(V4L2_MEM2MEM_DIR)/imx-pxp.ko@lt6.1 \ - $(LINUX_DIR)/drivers/media/platform/nxp/imx-pxp.ko@ge6.1 + FILES:= $(LINUX_DIR)/drivers/media/platform/nxp/imx-pxp.ko AUTOLOAD:=$(call AutoProbe,imx-pxp) $(call AddDepends/video) endef diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 1d4b37d259bb0f..b0c3691a572ae6 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -296,7 +296,7 @@ define KernelPackage/ath11k $(call KernelPackage/mac80211/Default) TITLE:=Qualcomm 802.11ax wireless chipset support (common code) URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k - DEPENDS+= +kmod-ath +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT @!LINUX_5_15 \ + DEPENDS+= +kmod-ath +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT \ +kmod-crypto-michael-mic +ATH11K_THERMAL:kmod-hwmon-core +ATH11K_THERMAL:kmod-thermal FILES:=$(PKG_BUILD_DIR)/drivers/soc/qcom/qmi_helpers.ko \ $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k.ko diff --git a/package/kernel/mac80211/intel.mk b/package/kernel/mac80211/intel.mk index 63b19a55c1c642..f2aceb96cd5a5e 100644 --- a/package/kernel/mac80211/intel.mk +++ b/package/kernel/mac80211/intel.mk @@ -6,7 +6,7 @@ config-$(CONFIG_PACKAGE_IWLWIFI_DEBUGFS)+= IWLWIFI_DEBUGFS define KernelPackage/iwlwifi $(call KernelPackage/mac80211/Default) - DEPENDS:= +kmod-mac80211 +kmod-ptp @PCI_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT @!LINUX_5_15 + DEPENDS:= +kmod-mac80211 +kmod-ptp @PCI_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11AX_SUPPORT TITLE:=Intel AGN Wireless support FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/iwlwifi.ko \ diff --git a/package/utils/fitblk/Makefile b/package/utils/fitblk/Makefile index 8fb6e14c7e0532..325963d8e2513d 100644 --- a/package/utils/fitblk/Makefile +++ b/package/utils/fitblk/Makefile @@ -16,7 +16,6 @@ define Package/fitblk SECTION:=base CATEGORY:=Base system TITLE:=fitblk firmware release tool - DEPENDS:=@!LINUX_5_15 endef define Package/fitblk/description From 2ee1392e094f9b6fdb2a759e2e29fa203b61e066 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 20 Sep 2024 11:23:24 +0200 Subject: [PATCH 04/23] ucode: another fix for host installation The previous host installation fix accidentally moved the rpath settings out of CMAKE_HOST_OPTIONS and into CMAKE_OPTIONS. Fixes: ae42ecaad4e7 ("ucode: fix host installation") Signed-off-by: Felix Fietkau --- package/utils/ucode/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package/utils/ucode/Makefile b/package/utils/ucode/Makefile index e1703cdca18f77..9dcd5ff3ab0a48 100644 --- a/package/utils/ucode/Makefile +++ b/package/utils/ucode/Makefile @@ -26,7 +26,9 @@ include $(INCLUDE_DIR)/host-build.mk include $(INCLUDE_DIR)/cmake.mk CMAKE_OPTIONS += \ - -DSOVERSION=$(PKG_ABI_VERSION) \ + -DSOVERSION=$(PKG_ABI_VERSION) + +CMAKE_HOST_OPTIONS += \ -DCMAKE_SKIP_RPATH=FALSE \ -DCMAKE_INSTALL_RPATH="${STAGING_DIR_HOSTPKG}/lib" From 0787d95f06d962ef32ca1dd096b4d121155e25ae Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Wed, 18 Sep 2024 02:12:24 +0100 Subject: [PATCH 05/23] generic: 6.6: mtk_eth_soc: reset all TX queues on DMA free The purpose of resetting the TX queue is to reset the byte and packet count as well as to clear the software flow control XOFF bit. MediaTek developers pointed out that netdev_reset_queue would only resets queue 0 of the network device. Queues that are not reset may cause unexpected issues. Packets may stop being sent after reset and "transmit timeout" log may be displayed. Import fix from MediaTek's SDK to resolve this issue. Link: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/5746a94456f466446cc0dcdfbd9078df6df31b63 Signed-off-by: Daniel Golle --- ..._eth_soc-reset-all-TX-queues-on-DMA-.patch | 49 +++++++++++++++++++ ..._eth_soc-add-paths-and-SerDes-modes-.patch | 18 +++---- 2 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 target/linux/generic/pending-6.6/730-net-ethernet-mtk_eth_soc-reset-all-TX-queues-on-DMA-.patch diff --git a/target/linux/generic/pending-6.6/730-net-ethernet-mtk_eth_soc-reset-all-TX-queues-on-DMA-.patch b/target/linux/generic/pending-6.6/730-net-ethernet-mtk_eth_soc-reset-all-TX-queues-on-DMA-.patch new file mode 100644 index 00000000000000..67d0ab45373c7b --- /dev/null +++ b/target/linux/generic/pending-6.6/730-net-ethernet-mtk_eth_soc-reset-all-TX-queues-on-DMA-.patch @@ -0,0 +1,49 @@ +From 7d41a5a8e9c91cc6bb011dd953570738583dd091 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 18 Sep 2024 02:01:01 +0100 +Subject: [PATCH] net: ethernet: mtk_eth_soc: reset all TX queues on DMA free + +The purpose of resetting the TX queue is to reset the +byte and packet count as well as to clear the software +flow control XOFF bit. + +MediaTek developers pointed out that netdev_reset_queue would only +resets queue 0 of the network device. +Queues that are not reset may cause unexpected issues. + +Packets may stop being sent after reset and "transmit timeout" log may +be displayed. + +Import fix from MediaTek's SDK to resolve this issue. + +Signed-off-by: Daniel Golle +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3135,11 +3135,19 @@ static int mtk_dma_init(struct mtk_eth * + static void mtk_dma_free(struct mtk_eth *eth) + { + const struct mtk_soc_data *soc = eth->soc; +- int i; ++ int i, j, txqs = 1; ++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) ++ txqs = MTK_QDMA_NUM_QUEUES; ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ if (!eth->netdev[i]) ++ continue; ++ ++ for (j = 0; j < txqs; j++) ++ netdev_tx_reset_queue(netdev_get_tx_queue(eth->netdev[i], j)); ++ } + +- for (i = 0; i < MTK_MAX_DEVS; i++) +- if (eth->netdev[i]) +- netdev_reset_queue(eth->netdev[i]); + if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) { + dma_free_coherent(eth->dma_dev, + MTK_QDMA_RING_SIZE * soc->tx.desc_size, diff --git a/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch index f9e10e57335f36..3e3b7f60741cc6 100644 --- a/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch +++ b/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch @@ -490,7 +490,7 @@ Signed-off-by: Daniel Golle .mac_finish = mtk_mac_finish, .mac_link_down = mtk_mac_link_down, .mac_link_up = mtk_mac_link_up, -@@ -3407,6 +3548,9 @@ static int mtk_open(struct net_device *d +@@ -3415,6 +3556,9 @@ static int mtk_open(struct net_device *d ppe_num = eth->soc->ppe_num; @@ -500,7 +500,7 @@ Signed-off-by: Daniel Golle err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); if (err) { netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -@@ -3557,6 +3701,9 @@ static int mtk_stop(struct net_device *d +@@ -3565,6 +3709,9 @@ static int mtk_stop(struct net_device *d for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) mtk_ppe_stop(eth->ppe[i]); @@ -510,7 +510,7 @@ Signed-off-by: Daniel Golle return 0; } -@@ -4570,6 +4717,7 @@ static const struct net_device_ops mtk_n +@@ -4578,6 +4725,7 @@ static const struct net_device_ops mtk_n static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) { const __be32 *_id = of_get_property(np, "reg", NULL); @@ -518,7 +518,7 @@ Signed-off-by: Daniel Golle phy_interface_t phy_mode; struct phylink *phylink; struct mtk_mac *mac; -@@ -4606,16 +4754,41 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4614,16 +4762,41 @@ static int mtk_add_mac(struct mtk_eth *e mac->id = id; mac->hw = eth; mac->of_node = np; @@ -568,7 +568,7 @@ Signed-off-by: Daniel Golle } memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip)); -@@ -4698,8 +4871,21 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4706,8 +4879,21 @@ static int mtk_add_mac(struct mtk_eth *e phy_interface_zero(mac->phylink_config.supported_interfaces); __set_bit(PHY_INTERFACE_MODE_INTERNAL, mac->phylink_config.supported_interfaces); @@ -590,7 +590,7 @@ Signed-off-by: Daniel Golle phylink = phylink_create(&mac->phylink_config, of_fwnode_handle(mac->of_node), phy_mode, &mtk_phylink_ops); -@@ -4750,6 +4936,26 @@ free_netdev: +@@ -4758,6 +4944,26 @@ free_netdev: return err; } @@ -617,7 +617,7 @@ Signed-off-by: Daniel Golle void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev) { struct net_device *dev, *tmp; -@@ -4896,7 +5102,8 @@ static int mtk_probe(struct platform_dev +@@ -4904,7 +5110,8 @@ static int mtk_probe(struct platform_dev regmap_write(cci, 0, 3); } @@ -627,7 +627,7 @@ Signed-off-by: Daniel Golle err = mtk_sgmii_init(eth); if (err) -@@ -5007,6 +5214,24 @@ static int mtk_probe(struct platform_dev +@@ -5015,6 +5222,24 @@ static int mtk_probe(struct platform_dev } } @@ -652,7 +652,7 @@ Signed-off-by: Daniel Golle if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) { err = devm_request_irq(eth->dev, eth->irq[0], mtk_handle_irq, 0, -@@ -5110,6 +5335,11 @@ static int mtk_remove(struct platform_de +@@ -5118,6 +5343,11 @@ static int mtk_remove(struct platform_de mtk_stop(eth->netdev[i]); mac = netdev_priv(eth->netdev[i]); phylink_disconnect_phy(mac->phylink); From 852ed0379a170ca031bc238ec34a4a8768526a45 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Thu, 19 Sep 2024 14:33:15 +0100 Subject: [PATCH 06/23] generic: 6.6: mtk_eth_soc: increase QDMA RESV_BUF size Increase QDMA RESV_BUF from 2K to 3K for netsys v2 to match Mediatek SDK. This helps reduce the possibility of Ethernet transmit timeouts. Link: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/19d8456c3051e5f6dabf42fa770916a2126ea4bf Signed-off-by: Daniel Golle --- ...-mediatek-enlarge-DMA-reserve-buffer.patch | 44 +++++++++++++++ ..._eth_soc-add-paths-and-SerDes-modes-.patch | 54 +++++++++---------- 2 files changed, 71 insertions(+), 27 deletions(-) create mode 100644 target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch diff --git a/target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch b/target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch new file mode 100644 index 00000000000000..d786b462c2579d --- /dev/null +++ b/target/linux/generic/pending-6.6/734-net-ethernet-mediatek-enlarge-DMA-reserve-buffer.patch @@ -0,0 +1,44 @@ +From: Chad Monroe +Date: Mon, 16 Sep 2024 19:29:03 -0700 +Subject: [PATCH] net: ethernet: mediatek: increase QDMA RESV_BUF size + +Increase QDMA RESV_BUF from 2K to 3K for netsys v2 to match Mediatek SDK[1]. +This helps reduce the possibility of Ethernet transmit timeouts. + +[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/19d8456c3051e5f6dabf42fa770916a2126ea4bf + +Signed-off-by: Chad Monroe +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 ++++-- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -271,6 +271,7 @@ + #define MTK_WCOMP_EN BIT(24) + #define MTK_RESV_BUF (0x80 << 16) + #define MTK_MUTLI_CNT (0x4 << 12) ++#define MTK_RESV_BUF_MASK (0xff << 16) + #define MTK_LEAKY_BUCKET_EN BIT(11) + + /* QDMA Flow Control Register */ +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -3309,12 +3309,14 @@ static int mtk_start_dma(struct mtk_eth + MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | + MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE; + +- if (mtk_is_netsys_v2_or_greater(eth)) ++ if (mtk_is_netsys_v2_or_greater(eth)) { ++ val &= ~MTK_RESV_BUF_MASK; + val |= MTK_MUTLI_CNT | MTK_RESV_BUF | + MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | + MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; +- else ++ } else { + val |= MTK_RX_BT_32DWORDS; ++ } + mtk_w32(eth, val, reg_map->qdma.glo_cfg); + + mtk_w32(eth, diff --git a/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch index 3e3b7f60741cc6..f4e12ca63a9986 100644 --- a/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch +++ b/target/linux/generic/pending-6.6/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch @@ -490,7 +490,7 @@ Signed-off-by: Daniel Golle .mac_finish = mtk_mac_finish, .mac_link_down = mtk_mac_link_down, .mac_link_up = mtk_mac_link_up, -@@ -3415,6 +3556,9 @@ static int mtk_open(struct net_device *d +@@ -3417,6 +3558,9 @@ static int mtk_open(struct net_device *d ppe_num = eth->soc->ppe_num; @@ -500,7 +500,7 @@ Signed-off-by: Daniel Golle err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); if (err) { netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -@@ -3565,6 +3709,9 @@ static int mtk_stop(struct net_device *d +@@ -3567,6 +3711,9 @@ static int mtk_stop(struct net_device *d for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) mtk_ppe_stop(eth->ppe[i]); @@ -510,7 +510,7 @@ Signed-off-by: Daniel Golle return 0; } -@@ -4578,6 +4725,7 @@ static const struct net_device_ops mtk_n +@@ -4580,6 +4727,7 @@ static const struct net_device_ops mtk_n static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) { const __be32 *_id = of_get_property(np, "reg", NULL); @@ -518,7 +518,7 @@ Signed-off-by: Daniel Golle phy_interface_t phy_mode; struct phylink *phylink; struct mtk_mac *mac; -@@ -4614,16 +4762,41 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4616,16 +4764,41 @@ static int mtk_add_mac(struct mtk_eth *e mac->id = id; mac->hw = eth; mac->of_node = np; @@ -568,7 +568,7 @@ Signed-off-by: Daniel Golle } memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip)); -@@ -4706,8 +4879,21 @@ static int mtk_add_mac(struct mtk_eth *e +@@ -4708,8 +4881,21 @@ static int mtk_add_mac(struct mtk_eth *e phy_interface_zero(mac->phylink_config.supported_interfaces); __set_bit(PHY_INTERFACE_MODE_INTERNAL, mac->phylink_config.supported_interfaces); @@ -590,7 +590,7 @@ Signed-off-by: Daniel Golle phylink = phylink_create(&mac->phylink_config, of_fwnode_handle(mac->of_node), phy_mode, &mtk_phylink_ops); -@@ -4758,6 +4944,26 @@ free_netdev: +@@ -4760,6 +4946,26 @@ free_netdev: return err; } @@ -617,7 +617,7 @@ Signed-off-by: Daniel Golle void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev) { struct net_device *dev, *tmp; -@@ -4904,7 +5110,8 @@ static int mtk_probe(struct platform_dev +@@ -4906,7 +5112,8 @@ static int mtk_probe(struct platform_dev regmap_write(cci, 0, 3); } @@ -627,7 +627,7 @@ Signed-off-by: Daniel Golle err = mtk_sgmii_init(eth); if (err) -@@ -5015,6 +5222,24 @@ static int mtk_probe(struct platform_dev +@@ -5017,6 +5224,24 @@ static int mtk_probe(struct platform_dev } } @@ -652,7 +652,7 @@ Signed-off-by: Daniel Golle if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) { err = devm_request_irq(eth->dev, eth->irq[0], mtk_handle_irq, 0, -@@ -5118,6 +5343,11 @@ static int mtk_remove(struct platform_de +@@ -5120,6 +5345,11 @@ static int mtk_remove(struct platform_de mtk_stop(eth->netdev[i]); mac = netdev_priv(eth->netdev[i]); phylink_disconnect_phy(mac->phylink); @@ -674,7 +674,7 @@ Signed-off-by: Daniel Golle #include #include #include -@@ -504,6 +505,21 @@ +@@ -505,6 +506,21 @@ #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED) #define INTF_MODE_RGMII_10_100 0 @@ -696,7 +696,7 @@ Signed-off-by: Daniel Golle /* GPIO port control registers for GMAC 2*/ #define GPIO_OD33_CTRL8 0x4c0 #define GPIO_BIAS_CTRL 0xed0 -@@ -529,6 +545,7 @@ +@@ -530,6 +546,7 @@ #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) #define SYSCFG0_SGMII_GMAC2_V2 BIT(8) @@ -704,7 +704,7 @@ Signed-off-by: Daniel Golle /* ethernet subsystem clock register */ -@@ -567,6 +584,11 @@ +@@ -568,6 +585,11 @@ #define GEPHY_MAC_SEL BIT(1) /* Top misc registers */ @@ -716,7 +716,7 @@ Signed-off-by: Daniel Golle #define USB_PHY_SWITCH_REG 0x218 #define QPHY_SEL_MASK GENMASK(1, 0) #define SGMII_QPHY_SEL 0x2 -@@ -591,6 +613,8 @@ +@@ -592,6 +614,8 @@ #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) @@ -725,7 +725,7 @@ Signed-off-by: Daniel Golle #define MTK_FE_CDM1_FSM 0x220 #define MTK_FE_CDM2_FSM 0x224 #define MTK_FE_CDM3_FSM 0x238 -@@ -599,6 +623,11 @@ +@@ -600,6 +624,11 @@ #define MTK_FE_CDM6_FSM 0x328 #define MTK_FE_GDM1_FSM 0x228 #define MTK_FE_GDM2_FSM 0x22C @@ -737,7 +737,7 @@ Signed-off-by: Daniel Golle #define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) -@@ -723,12 +752,8 @@ enum mtk_clks_map { +@@ -724,12 +753,8 @@ enum mtk_clks_map { MTK_CLK_ETHWARP_WOCPU2, MTK_CLK_ETHWARP_WOCPU1, MTK_CLK_ETHWARP_WOCPU0, @@ -750,7 +750,7 @@ Signed-off-by: Daniel Golle MTK_CLK_TOP_ETH_GMII_SEL, MTK_CLK_TOP_ETH_REFCK_50M_SEL, MTK_CLK_TOP_ETH_SYS_200M_SEL, -@@ -799,19 +824,9 @@ enum mtk_clks_map { +@@ -800,19 +825,9 @@ enum mtk_clks_map { BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \ BIT_ULL(MTK_CLK_CRYPTO) | \ @@ -770,7 +770,7 @@ Signed-off-by: Daniel Golle BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \ -@@ -945,6 +960,8 @@ enum mkt_eth_capabilities { +@@ -946,6 +961,8 @@ enum mkt_eth_capabilities { MTK_RGMII_BIT = 0, MTK_TRGMII_BIT, MTK_SGMII_BIT, @@ -779,7 +779,7 @@ Signed-off-by: Daniel Golle MTK_ESW_BIT, MTK_GEPHY_BIT, MTK_MUX_BIT, -@@ -965,8 +982,11 @@ enum mkt_eth_capabilities { +@@ -966,8 +983,11 @@ enum mkt_eth_capabilities { MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT, MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT, @@ -791,7 +791,7 @@ Signed-off-by: Daniel Golle /* PATH BITS */ MTK_ETH_PATH_GMAC1_RGMII_BIT, -@@ -974,14 +994,21 @@ enum mkt_eth_capabilities { +@@ -975,14 +995,21 @@ enum mkt_eth_capabilities { MTK_ETH_PATH_GMAC1_SGMII_BIT, MTK_ETH_PATH_GMAC2_RGMII_BIT, MTK_ETH_PATH_GMAC2_SGMII_BIT, @@ -813,7 +813,7 @@ Signed-off-by: Daniel Golle #define MTK_ESW BIT_ULL(MTK_ESW_BIT) #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) #define MTK_MUX BIT_ULL(MTK_MUX_BIT) -@@ -1004,10 +1031,16 @@ enum mkt_eth_capabilities { +@@ -1005,10 +1032,16 @@ enum mkt_eth_capabilities { BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \ BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) @@ -830,7 +830,7 @@ Signed-off-by: Daniel Golle /* Supported path present on SoCs */ #define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) -@@ -1015,8 +1048,13 @@ enum mkt_eth_capabilities { +@@ -1016,8 +1049,13 @@ enum mkt_eth_capabilities { #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT) #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) @@ -844,7 +844,7 @@ Signed-off-by: Daniel Golle #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) -@@ -1024,7 +1062,12 @@ enum mkt_eth_capabilities { +@@ -1025,7 +1063,12 @@ enum mkt_eth_capabilities { #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII) #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) @@ -857,7 +857,7 @@ Signed-off-by: Daniel Golle /* MUXes present on SoCs */ /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */ -@@ -1043,10 +1086,20 @@ enum mkt_eth_capabilities { +@@ -1044,10 +1087,20 @@ enum mkt_eth_capabilities { (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \ MTK_SHARED_SGMII) @@ -878,7 +878,7 @@ Signed-off-by: Daniel Golle #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ -@@ -1078,8 +1131,12 @@ enum mkt_eth_capabilities { +@@ -1079,8 +1132,12 @@ enum mkt_eth_capabilities { MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ MTK_RSTCTRL_PPE1 | MTK_SRAM) @@ -893,7 +893,7 @@ Signed-off-by: Daniel Golle struct mtk_tx_dma_desc_info { dma_addr_t addr; -@@ -1324,6 +1381,9 @@ struct mtk_mac { +@@ -1325,6 +1382,9 @@ struct mtk_mac { struct device_node *of_node; struct phylink *phylink; struct phylink_config phylink_config; @@ -903,7 +903,7 @@ Signed-off-by: Daniel Golle struct mtk_eth *hw; struct mtk_hw_stats *hw_stats; __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; -@@ -1447,6 +1507,19 @@ static inline u32 mtk_get_ib2_multicast_ +@@ -1448,6 +1508,19 @@ static inline u32 mtk_get_ib2_multicast_ return MTK_FOE_IB2_MULTICAST; } @@ -923,7 +923,7 @@ Signed-off-by: Daniel Golle /* read the hardware status register */ void mtk_stats_update_mac(struct mtk_mac *mac); -@@ -1455,8 +1528,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne +@@ -1456,8 +1529,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); From 8043e2e7464befb6f3fd8b42e891ba35248c0fa4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 20 Sep 2024 16:55:45 +0200 Subject: [PATCH 07/23] tools/llvm-bpf: filter out STAGING_DIR_HOST/include from cflags on non-linux systems Avoids picking up an incompatible libuuid from util-linux Signed-off-by: Felix Fietkau --- tools/llvm-bpf/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/llvm-bpf/Makefile b/tools/llvm-bpf/Makefile index b8c2005de8850e..a36ca0647fd6d3 100644 --- a/tools/llvm-bpf/Makefile +++ b/tools/llvm-bpf/Makefile @@ -22,6 +22,11 @@ CMAKE_SOURCE_SUBDIR := llvm include $(INCLUDE_DIR)/host-build.mk include $(INCLUDE_DIR)/cmake.mk +ifneq ($(HOST_OS),Linux) + HOST_CFLAGS := $(filter-out -I$(STAGING_DIR_HOST)/include,$(HOST_CFLAGS)) + HOST_CXXFLAGS := $(filter-out -I$(STAGING_DIR_HOST)/include,$(HOST_CXXFLAGS)) +endif + LLVM_BPF_PREFIX = llvm-bpf-$(PKG_VERSION).$(HOST_OS)-$(HOST_ARCH) CMAKE_HOST_INSTALL_PREFIX = $(STAGING_DIR_HOST)/$(LLVM_BPF_PREFIX) From 5b9e41828ef2298e95931209eb1e95b881c29f01 Mon Sep 17 00:00:00 2001 From: Mieczyslaw Nalewaj Date: Fri, 9 Aug 2024 17:57:23 +0200 Subject: [PATCH 08/23] at91: use kernel 6.6 by default Switch to Linux kernel version 6.6. Signed-off-by: Mieczyslaw Nalewaj --- target/linux/at91/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/target/linux/at91/Makefile b/target/linux/at91/Makefile index cde2d77c7e4193..8fd4a0183411de 100644 --- a/target/linux/at91/Makefile +++ b/target/linux/at91/Makefile @@ -10,8 +10,7 @@ BOARDNAME:=Microchip (Atmel AT91) FEATURES:=ext4 squashfs targz usbgadget ubifs SUBTARGETS:=sama7 sama5 sam9x -KERNEL_PATCHVER:=6.1 -KERNEL_TESTING_PATCHVER:=6.6 +KERNEL_PATCHVER:=6.6 include $(INCLUDE_DIR)/target.mk From d1e9f79ca39e70adc9d70ded8ac2d6d3c7b2faa6 Mon Sep 17 00:00:00 2001 From: Mieczyslaw Nalewaj Date: Fri, 9 Aug 2024 18:00:21 +0200 Subject: [PATCH 09/23] at91: drop 6.1 support Drop config and files for Linux 6.1. Signed-off-by: Mieczyslaw Nalewaj --- target/linux/at91/image/Makefile | 4 +- ...convert-to-NOIRQ_SYSTEM_SLEEP_PM_OPS.patch | 34 -- target/linux/at91/sam9x/config-6.1 | 341 ------------ target/linux/at91/sama5/config-6.1 | 517 ------------------ target/linux/at91/sama7/config-6.1 | 424 -------------- 5 files changed, 1 insertion(+), 1319 deletions(-) delete mode 100644 target/linux/at91/patches-6.1/0001-v6.3-pinctrl-at91-convert-to-NOIRQ_SYSTEM_SLEEP_PM_OPS.patch delete mode 100644 target/linux/at91/sam9x/config-6.1 delete mode 100644 target/linux/at91/sama5/config-6.1 delete mode 100644 target/linux/at91/sama7/config-6.1 diff --git a/target/linux/at91/image/Makefile b/target/linux/at91/image/Makefile index aba95fde910d37..b825a412473028 100644 --- a/target/linux/at91/image/Makefile +++ b/target/linux/at91/image/Makefile @@ -19,9 +19,7 @@ FAT32_BLOCKS:=$(shell echo \ $$(($(AT91_SD_BOOT_PARTSIZE)*1024*1024/$(FAT32_BLOCK_SIZE)))) define Device/Default - ifdef CONFIG_LINUX_6_6 - DEVICE_DTS_DIR := $(DTS_DIR)/microchip - endif + DEVICE_DTS_DIR := $(DTS_DIR)/microchip $(Device/default-nand) PROFILES := Default FILESYSTEMS := squashfs ubifs ext4 diff --git a/target/linux/at91/patches-6.1/0001-v6.3-pinctrl-at91-convert-to-NOIRQ_SYSTEM_SLEEP_PM_OPS.patch b/target/linux/at91/patches-6.1/0001-v6.3-pinctrl-at91-convert-to-NOIRQ_SYSTEM_SLEEP_PM_OPS.patch deleted file mode 100644 index 874e33059ad76d..00000000000000 --- a/target/linux/at91/patches-6.1/0001-v6.3-pinctrl-at91-convert-to-NOIRQ_SYSTEM_SLEEP_PM_OPS.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5d8ae2928f71f0f9c2c3f8f13d00ecec35649ad3 Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Thu, 15 Dec 2022 17:42:54 +0100 -Subject: [PATCH] pinctrl: at91: convert to NOIRQ_SYSTEM_SLEEP_PM_OPS - -With the old SET_NOIRQ_SYSTEM_SLEEP_PM_OPS, some configs result in a -build warning: - -drivers/pinctrl/pinctrl-at91.c:1668:12: error: 'at91_gpio_resume' defined but not used [-Werror=unused-function] - 1668 | static int at91_gpio_resume(struct device *dev) - | ^~~~~~~~~~~~~~~~ -drivers/pinctrl/pinctrl-at91.c:1650:12: error: 'at91_gpio_suspend' defined but not used [-Werror=unused-function] - 1650 | static int at91_gpio_suspend(struct device *dev) - | ^~~~~~~~~~~~~~~~~ - -Signed-off-by: Arnd Bergmann -Reviewed-by: Ryan Wanner -Link: https://lore.kernel.org/r/20221215164301.934805-1-arnd@kernel.org -Signed-off-by: Linus Walleij ---- - drivers/pinctrl/pinctrl-at91.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/pinctrl/pinctrl-at91.c -+++ b/drivers/pinctrl/pinctrl-at91.c -@@ -1921,7 +1921,7 @@ err: - } - - static const struct dev_pm_ops at91_gpio_pm_ops = { -- SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(at91_gpio_suspend, at91_gpio_resume) -+ NOIRQ_SYSTEM_SLEEP_PM_OPS(at91_gpio_suspend, at91_gpio_resume) - }; - - static struct platform_driver at91_gpio_driver = { diff --git a/target/linux/at91/sam9x/config-6.1 b/target/linux/at91/sam9x/config-6.1 deleted file mode 100644 index ac4d7cd666f364..00000000000000 --- a/target/linux/at91/sam9x/config-6.1 +++ /dev/null @@ -1,341 +0,0 @@ -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_AT91=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -# CONFIG_ARCH_MULTI_V4 is not set -CONFIG_ARCH_MULTI_V4T=y -CONFIG_ARCH_MULTI_V4_V5=y -CONFIG_ARCH_MULTI_V5=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_HAS_GROUP_RELOCS=y -CONFIG_ARM_L1_CACHE_SHIFT=5 -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_ARM_THUMB=y -CONFIG_ARM_UNWIND=y -# CONFIG_AT91RM9200_WATCHDOG is not set -CONFIG_AT91SAM9X_WATCHDOG=y -# CONFIG_AT91_ADC is not set -CONFIG_AT91_SAMA5D2_ADC=y -CONFIG_AT91_SOC_ID=y -# CONFIG_AT91_SOC_SFR is not set -CONFIG_ATMEL_AIC5_IRQ=y -CONFIG_ATMEL_AIC_IRQ=y -CONFIG_ATMEL_CLOCKSOURCE_PIT=y -CONFIG_ATMEL_CLOCKSOURCE_TCB=y -CONFIG_ATMEL_EBI=y -CONFIG_ATMEL_PIT=y -CONFIG_ATMEL_PM=y -CONFIG_ATMEL_SDRAMC=y -CONFIG_ATMEL_SSC=y -CONFIG_ATMEL_ST=y -CONFIG_ATMEL_TCB_CLKSRC=y -CONFIG_AT_HDMAC=y -CONFIG_AT_XDMAC=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y -CONFIG_BLK_PM=y -CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_AT91=y -CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONFIGFS_FS=y -CONFIG_CPU_32v4T=y -CONFIG_CPU_32v5=y -CONFIG_CPU_ABRT_EV4T=y -CONFIG_CPU_ABRT_EV5TJ=y -CONFIG_CPU_ARM920T=y -CONFIG_CPU_ARM926T=y -# CONFIG_CPU_CACHE_ROUND_ROBIN is not set -CONFIG_CPU_CACHE_V4WT=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_COPY_V4WB=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -# CONFIG_CPU_DCACHE_WRITETHROUGH is not set -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_NO_EFFICIENT_FFS=y -CONFIG_CPU_PABRT_LEGACY=y -CONFIG_CPU_PM=y -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V4WBI=y -CONFIG_CPU_USE_DOMAINS=y -CONFIG_CRC16=y -CONFIG_CRC7=y -CONFIG_CRC_CCITT=y -CONFIG_CRC_ITU_T=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_SHA1=y -CONFIG_CRYPTO_LIB_UTILS=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_ZSTD=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -CONFIG_DMADEVICES=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_OPS=y -CONFIG_DTC=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EEPROM_AT24=y -CONFIG_EXCLUSIVE_SYSTEM_RAM=y -CONFIG_EXT4_FS=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FREEZER=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FWNODE_MDIO=y -CONFIG_FW_CACHE=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y -CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ATOMIC64=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GLOB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_ATMEL=y -CONFIG_HZ=128 -CONFIG_HZ_FIXED=128 -CONFIG_HZ_PERIODIC=y -CONFIG_I2C=y -CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_AT91=y -# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_GPIO=y -CONFIG_IIO=y -CONFIG_IIO_BUFFER=y -CONFIG_IIO_KFIFO_BUF=y -CONFIG_IIO_TRIGGER=y -CONFIG_IIO_TRIGGERED_BUFFER=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_INPUT=y -CONFIG_IRQCHIP=y -CONFIG_IRQSTACKS=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_PWM=y -CONFIG_LEDS_TRIGGER_CPU=y -CONFIG_LEDS_TRIGGER_GPIO=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MACB=y -CONFIG_MACB_USE_HWSTAMP=y -# CONFIG_MCHP_EIC is not set -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY=y -CONFIG_MFD_AT91_USART=y -CONFIG_MFD_ATMEL_FLEXCOM=y -CONFIG_MFD_ATMEL_HLCDC=y -CONFIG_MFD_ATMEL_SMC=y -CONFIG_MFD_CORE=y -CONFIG_MFD_SYSCON=y -CONFIG_MICREL_PHY=y -CONFIG_MICROCHIP_CLOCKSOURCE_PIT64B=y -CONFIG_MICROCHIP_PIT64B=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_OF_AT91=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_DATAFLASH=y -# CONFIG_MTD_DATAFLASH_OTP is not set -# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -# CONFIG_MTD_UBI_BLOCK is not set -CONFIG_MTD_UBI_FASTMAP=y -CONFIG_MTD_UBI_GLUEBI=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_KUSER_HELPERS=y -CONFIG_NEED_PER_CPU_KM=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_SELFTESTS=y -CONFIG_NLS=y -CONFIG_NVMEM=y -CONFIG_NVMEM_LAYOUTS=y -# CONFIG_NVMEM_MICROCHIP_OTPC is not set -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_SIGSUSPEND3=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PAGE_POOL=y -CONFIG_PAGE_SIZE_LESS_THAN_256KB=y -CONFIG_PAGE_SIZE_LESS_THAN_64KB=y -CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLIB_LEDS=y -CONFIG_PHYLINK=y -CONFIG_PINCTRL=y -CONFIG_PINCTRL_AT91=y -# CONFIG_PINCTRL_AT91PIO4 is not set -CONFIG_PM=y -CONFIG_PM_CLK=y -CONFIG_PM_SLEEP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_AT91_POWEROFF=y -CONFIG_POWER_RESET_AT91_RESET=y -CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y -CONFIG_POWER_SUPPLY=y -CONFIG_PPS=y -CONFIG_PREEMPT_NONE_BUILD=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=y -CONFIG_PWM_ATMEL_HLCDC_PWM=y -CONFIG_PWM_ATMEL_TCB=y -CONFIG_PWM_SYSFS=y -CONFIG_RANDSTRUCT_NONE=y -CONFIG_RATIONAL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91RM9200=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_RTC_MC146818_LIB=y -CONFIG_SAMA5D4_WATCHDOG=y -# CONFIG_SERIAL_8250 is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_SERIAL_ATMEL_PDC=y -# CONFIG_SERIAL_ATMEL_TTYAT is not set -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SGL_ALLOC=y -CONFIG_SOC_AT91RM9200=y -CONFIG_SOC_AT91SAM9=y -CONFIG_SOC_BUS=y -CONFIG_SOC_SAM9X60=y -CONFIG_SOC_SAM_V4_V5=y -CONFIG_SOFTIRQ_ON_OWN_STACK=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -# CONFIG_SPI_AT91_USART is not set -CONFIG_SPI_ATMEL=y -CONFIG_SPI_ATMEL_QUADSPI=y -CONFIG_SPI_BITBANG=y -CONFIG_SPI_GPIO=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SPI_SPIDEV=y -CONFIG_SPLIT_PTLOCK_CPUS=999999 -CONFIG_SRAM=y -CONFIG_SRAM_EXEC=y -CONFIG_SRCU=y -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWPHY=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TINY_SRCU=y -CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_ADVANCED_COMPR=y -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_UNWINDER_ARM=y -CONFIG_USB=y -CONFIG_USB_ACM=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -# CONFIG_USB_AT91 is not set -# CONFIG_USB_ATMEL_USBA is not set -CONFIG_USB_COMMON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_HCD_AT91=y -# CONFIG_USB_EHCI_HCD_PLATFORM is not set -CONFIG_USB_GADGET=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_AT91=y -CONFIG_USB_OHCI_HCD_PLATFORM=y -CONFIG_USB_SERIAL=y -# CONFIG_USB_SERIAL_CONSOLE is not set -CONFIG_USB_SERIAL_FTDI_SIO=y -CONFIG_USB_SERIAL_PL2303=y -CONFIG_USB_SUPPORT=y -CONFIG_USE_OF=y -# CONFIG_VFP is not set -# CONFIG_VIDEO_ATMEL_XISC is not set -# CONFIG_VIDEO_MICROCHIP_CSI2DC is not set -CONFIG_WATCHDOG_CORE=y -CONFIG_XXHASH=y -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZSTD_COMMON=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/at91/sama5/config-6.1 b/target/linux/at91/sama5/config-6.1 deleted file mode 100644 index a3168040c2d23c..00000000000000 --- a/target/linux/at91/sama5/config-6.1 +++ /dev/null @@ -1,517 +0,0 @@ -CONFIG_ALIGNMENT_TRAP=y -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_AT91=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM=y -CONFIG_ARM_AT91_CPUIDLE=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_HAS_GROUP_RELOCS=y -CONFIG_ARM_HEAVY_MB=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_ARM_THUMB=y -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_AT91SAM9X_WATCHDOG=y -CONFIG_AT91_ADC=y -CONFIG_AT91_SAMA5D2_ADC=y -CONFIG_AT91_SOC_ID=y -# CONFIG_AT91_SOC_SFR is not set -CONFIG_ATMEL_AIC5_IRQ=y -# CONFIG_ATMEL_CLOCKSOURCE_PIT is not set -CONFIG_ATMEL_CLOCKSOURCE_TCB=y -CONFIG_ATMEL_EBI=y -CONFIG_ATMEL_PM=y -CONFIG_ATMEL_SDRAMC=y -# CONFIG_ATMEL_SECURE_PM is not set -CONFIG_ATMEL_SSC=y -CONFIG_ATMEL_TCB_CLKSRC=y -CONFIG_AT_HDMAC=y -CONFIG_AT_XDMAC=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BACKLIGHT_PWM=y -CONFIG_BATTERY_ACT8945A=y -CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=4 -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_PM=y -CONFIG_CACHE_L2X0=y -CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=16 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -# CONFIG_CMA_SYSFS is not set -CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw" -CONFIG_CMDLINE_FROM_BOOTLOADER=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_AT91=y -CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONFIGFS_FS=y -CONFIG_CONTIG_ALLOC=y -CONFIG_COREDUMP=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_PM=y -CONFIG_CPU_SPECTRE=y -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRASH_CORE=y -CONFIG_CRASH_DUMP=y -CONFIG_CRC16=y -# CONFIG_CRC32_SARWATE is not set -CONFIG_CRC32_SLICEBY8=y -CONFIG_CROSS_MEMORY_ATTACH=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DRBG=y -CONFIG_CRYPTO_DRBG_HMAC=y -CONFIG_CRYPTO_DRBG_MENU=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_JITTERENTROPY=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_SHA1=y -CONFIG_CRYPTO_LIB_SHA256=y -CONFIG_CRYPTO_LIB_UTILS=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_RNG_DEFAULT=y -CONFIG_CRYPTO_SEQIV=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_ZSTD=y -CONFIG_CURRENT_POINTER_IN_TPIDRURO=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -CONFIG_DEBUG_MEMORY_INIT=y -CONFIG_DEBUG_USER=y -CONFIG_DMADEVICES=y -CONFIG_DMA_CMA=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_OPS=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_DNOTIFY=y -CONFIG_DRM=y -CONFIG_DRM_ATMEL_HLCDC=y -CONFIG_DRM_BRIDGE=y -CONFIG_DRM_FBDEV_EMULATION=y -CONFIG_DRM_FBDEV_OVERALLOC=100 -CONFIG_DRM_GEM_DMA_HELPER=y -CONFIG_DRM_KMS_HELPER=y -CONFIG_DRM_NOMODESET=y -CONFIG_DRM_PANEL=y -CONFIG_DRM_PANEL_BRIDGE=y -CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y -CONFIG_DRM_PANEL_SIMPLE=y -CONFIG_DTC=y -CONFIG_DVB_CORE=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EEPROM_AT24=y -CONFIG_ELF_CORE=y -CONFIG_EXCLUSIVE_SYSTEM_RAM=y -CONFIG_EXT4_FS=y -CONFIG_FAT_FS=y -CONFIG_FB=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_CMDLINE=y -CONFIG_FB_DEFERRED_IO=y -CONFIG_FB_SYS_COPYAREA=y -CONFIG_FB_SYS_FILLRECT=y -CONFIG_FB_SYS_FOPS=y -CONFIG_FB_SYS_IMAGEBLIT=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FREEZER=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FWNODE_MDIO=y -CONFIG_FW_CACHE=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y -CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_VDSO_32=y -CONFIG_GLOB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -# CONFIG_HARDEN_BRANCH_HISTORY is not set -# CONFIG_HARDEN_BRANCH_PREDICTOR is not set -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAVE_SMP=y -CONFIG_HDMI=y -CONFIG_HID=y -CONFIG_HID_GENERIC=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_ATMEL=y -CONFIG_HZ_FIXED=0 -CONFIG_I2C=y -CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_AT91=y -# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_GPIO=y -CONFIG_I2C_HELPER_AUTO=y -CONFIG_IIO=y -CONFIG_IIO_BUFFER=y -CONFIG_IIO_KFIFO_BUF=y -CONFIG_IIO_TRIGGER=y -CONFIG_IIO_TRIGGERED_BUFFER=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_INPUT=y -CONFIG_INPUT_EVDEV=y -CONFIG_INPUT_KEYBOARD=y -CONFIG_INPUT_LEDS=y -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_IRQCHIP=y -CONFIG_IRQSTACKS=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -# CONFIG_JFFS2_FS is not set -CONFIG_KCMP=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_XZ is not set -CONFIG_KEXEC=y -CONFIG_KEXEC_CORE=y -CONFIG_KEYBOARD_GPIO=y -CONFIG_KEYBOARD_QT1070=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_PWM=y -CONFIG_LEDS_TRIGGER_CPU=y -CONFIG_LEDS_TRIGGER_GPIO=y -CONFIG_LIBFDT=y -CONFIG_LOCALVERSION_AUTO=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOG_BUF_SHIFT=16 -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MACB=y -CONFIG_MACB_USE_HWSTAMP=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_MCHP_EIC is not set -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -CONFIG_MEDIA_ATTACH=y -CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -CONFIG_MEDIA_PLATFORM_SUPPORT=y -CONFIG_MEDIA_RADIO_SUPPORT=y -CONFIG_MEDIA_SDR_SUPPORT=y -CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_TEST_SUPPORT=y -CONFIG_MEDIA_TUNER=y -CONFIG_MEDIA_USB_SUPPORT=y -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_MFD_ACT8945A=y -CONFIG_MFD_AT91_USART=y -CONFIG_MFD_ATMEL_FLEXCOM=y -CONFIG_MFD_ATMEL_HLCDC=y -CONFIG_MFD_ATMEL_SMC=y -CONFIG_MFD_CORE=y -CONFIG_MFD_SYSCON=y -CONFIG_MICREL_PHY=y -# CONFIG_MICROCHIP_CLOCKSOURCE_PIT64B is not set -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_ATMELMCI=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_OF_AT91=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MODULES_USE_ELF_REL=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -# CONFIG_MTD_UBI_BLOCK is not set -CONFIG_MTD_UBI_FASTMAP=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_PER_CPU_KM=y -# CONFIG_NEON is not set -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_SELFTESTS=y -CONFIG_NLS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NVMEM=y -CONFIG_NVMEM_LAYOUTS=y -# CONFIG_NVMEM_MICROCHIP_OTPC is not set -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_SIGSUSPEND3=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PAGE_POOL=y -CONFIG_PAGE_SIZE_LESS_THAN_256KB=y -CONFIG_PAGE_SIZE_LESS_THAN_64KB=y -CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLIB_LEDS=y -CONFIG_PHYLINK=y -CONFIG_PINCTRL=y -CONFIG_PINCTRL_AT91=y -CONFIG_PINCTRL_AT91PIO4=y -# CONFIG_PINCTRL_SINGLE is not set -CONFIG_PM=y -CONFIG_PM_CLK=y -CONFIG_PM_SLEEP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_AT91_POWEROFF=y -CONFIG_POWER_RESET_AT91_RESET=y -CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y -CONFIG_POWER_SUPPLY=y -CONFIG_PPS=y -CONFIG_PREEMPT_NONE_BUILD=y -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -CONFIG_PRINTK_TIME=y -CONFIG_PROC_VMCORE=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=y -CONFIG_PWM_ATMEL_HLCDC_PWM=y -CONFIG_PWM_ATMEL_TCB=y -CONFIG_PWM_SYSFS=y -CONFIG_RANDSTRUCT_NONE=y -CONFIG_RATIONAL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_ACT8865=y -CONFIG_REGULATOR_ACT8945A=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91RM9200=y -# CONFIG_RTC_DRV_AT91SAM9 is not set -# CONFIG_RTC_DRV_CMOS is not set -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_SAMA5D4_WATCHDOG=y -CONFIG_SCSI=y -CONFIG_SCSI_COMMON=y -# CONFIG_SCSI_LOWLEVEL is not set -# CONFIG_SERIAL_8250 is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_SERIAL_ATMEL_PDC=y -# CONFIG_SERIAL_ATMEL_TTYAT is not set -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SGL_ALLOC=y -CONFIG_SG_POOL=y -CONFIG_SND=y -CONFIG_SND_ARM=y -# CONFIG_SND_AT73C213 is not set -# CONFIG_SND_AT91_SOC_SAM9G20_WM8731 is not set -# CONFIG_SND_AT91_SOC_SAM9X5_WM8731 is not set -CONFIG_SND_ATMEL_SOC=y -CONFIG_SND_ATMEL_SOC_CLASSD=y -CONFIG_SND_ATMEL_SOC_DMA=y -CONFIG_SND_ATMEL_SOC_I2S=y -CONFIG_SND_ATMEL_SOC_PDC=y -# CONFIG_SND_ATMEL_SOC_PDMIC is not set -CONFIG_SND_ATMEL_SOC_SSC=y -CONFIG_SND_ATMEL_SOC_SSC_DMA=y -# CONFIG_SND_ATMEL_SOC_SSC_PDC is not set -# CONFIG_SND_ATMEL_SOC_TSE850_PCM5142 is not set -CONFIG_SND_ATMEL_SOC_WM8904=y -# CONFIG_SND_COMPRESS_OFFLOAD is not set -CONFIG_SND_DMAENGINE_PCM=y -CONFIG_SND_JACK=y -CONFIG_SND_JACK_INPUT_DEV=y -# CONFIG_SND_MCHP_SOC_I2S_MCC is not set -# CONFIG_SND_MCHP_SOC_PDMC is not set -# CONFIG_SND_MCHP_SOC_SPDIFRX is not set -# CONFIG_SND_MCHP_SOC_SPDIFTX is not set -CONFIG_SND_PCM=y -CONFIG_SND_PCM_TIMER=y -CONFIG_SND_SOC=y -CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y -CONFIG_SND_SOC_I2C_AND_SPI=y -CONFIG_SND_SOC_MIKROE_PROTO=y -CONFIG_SND_SOC_WM8731=y -CONFIG_SND_SOC_WM8904=y -CONFIG_SND_SPI=y -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_TIMER=y -CONFIG_SOC_BUS=y -# CONFIG_SOC_LAN966 is not set -CONFIG_SOC_SAMA5=y -CONFIG_SOC_SAMA5D2=y -CONFIG_SOC_SAMA5D3=y -CONFIG_SOC_SAMA5D4=y -# CONFIG_SOC_SAMA7G5 is not set -CONFIG_SOC_SAM_V7=y -CONFIG_SOFTIRQ_ON_OWN_STACK=y -CONFIG_SOUND=y -CONFIG_SOUND_OSS_CORE=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -# CONFIG_SPI_AT91_USART is not set -CONFIG_SPI_ATMEL=y -CONFIG_SPI_ATMEL_QUADSPI=y -CONFIG_SPI_BITBANG=y -CONFIG_SPI_GPIO=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -# CONFIG_SQUASHFS is not set -CONFIG_SRAM=y -CONFIG_SRAM_EXEC=y -CONFIG_SRCU=y -# CONFIG_STANDALONE is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWPHY=y -# CONFIG_SWP_EMULATE is not set -CONFIG_SYNC_FILE=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TINY_SRCU=y -CONFIG_TOUCHSCREEN_ATMEL_MXT=y -CONFIG_UACCESS_WITH_MEMCPY=y -CONFIG_UBIFS_FS=y -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_UNWINDER_ARM=y -CONFIG_USB=y -CONFIG_USB_ACM=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -# CONFIG_USB_AT91 is not set -# CONFIG_USB_ATMEL_USBA is not set -CONFIG_USB_COMMON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_HCD_AT91=y -# CONFIG_USB_EHCI_HCD_PLATFORM is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -CONFIG_USB_GADGET=y -CONFIG_USB_HID=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_AT91=y -CONFIG_USB_OHCI_HCD_PLATFORM=y -# CONFIG_USB_PWC is not set -CONFIG_USB_SERIAL=y -# CONFIG_USB_SERIAL_CONSOLE is not set -CONFIG_USB_SERIAL_FTDI_SIO=y -CONFIG_USB_SERIAL_PL2303=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USE_OF=y -CONFIG_VFAT_FS=y -CONFIG_VFP=y -CONFIG_VFPv3=y -# CONFIG_VIDEO_ATMEL_XISC is not set -CONFIG_VIDEOMODE_HELPERS=y -CONFIG_VIDEO_DEV=y -# CONFIG_VIDEO_MICROCHIP_CSI2DC is not set -CONFIG_VIDEO_V4L2_I2C=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_XXHASH=y -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZSTD_COMMON=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/at91/sama7/config-6.1 b/target/linux/at91/sama7/config-6.1 deleted file mode 100644 index 0fd9a693676d47..00000000000000 --- a/target/linux/at91/sama7/config-6.1 +++ /dev/null @@ -1,424 +0,0 @@ -CONFIG_ALIGNMENT_TRAP=y -# CONFIG_ALLOW_DEV_COREDUMP is not set -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_AT91=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM=y -CONFIG_ARM_GIC=y -CONFIG_ARM_HAS_GROUP_RELOCS=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -# CONFIG_ARM_PATCH_IDIV is not set -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_ARM_THUMB=y -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -# CONFIG_AT91SAM9X_WATCHDOG is not set -# CONFIG_AT91_ADC is not set -CONFIG_AT91_SAMA5D2_ADC=y -CONFIG_AT91_SOC_ID=y -# CONFIG_AT91_SOC_SFR is not set -CONFIG_ATMEL_CLOCKSOURCE_TCB=y -# CONFIG_ATMEL_EBI is not set -CONFIG_ATMEL_SDRAMC=y -CONFIG_ATMEL_TCB_CLKSRC=y -# CONFIG_AT_HDMAC is not set -CONFIG_AT_XDMAC=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=1 -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_SD=y -# CONFIG_CACHE_L2X0 is not set -CONFIG_CAN=y -CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=9 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=256 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -# CONFIG_CMA_SYSFS is not set -CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk nocache ignore_loglevel" -CONFIG_CMDLINE_FROM_BOOTLOADER=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_AT91=y -# CONFIG_COMPACTION is not set -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_CONTIG_ALLOC=y -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_SPECTRE=y -# CONFIG_CPU_SW_DOMAIN_PAN is not set -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRC16=y -CONFIG_CRC_CCITT=y -CONFIG_CRC_ITU_T=y -CONFIG_CRYPTO_CMAC=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DRBG=y -CONFIG_CRYPTO_DRBG_HMAC=y -CONFIG_CRYPTO_DRBG_MENU=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_ECC=y -CONFIG_CRYPTO_ECDH=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_JITTERENTROPY=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_SHA1=y -CONFIG_CRYPTO_LIB_SHA256=y -CONFIG_CRYPTO_LIB_UTILS=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_RNG_DEFAULT=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CURRENT_POINTER_IN_TPIDRURO=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_AT91_SAMA7G5_FLEXCOM3=y -CONFIG_DEBUG_AT91_UART=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL=y -CONFIG_DEBUG_LL_INCLUDE="debug/at91.S" -CONFIG_DEBUG_UART_PHYS=0xe1824200 -CONFIG_DEBUG_UART_VIRT=0xe0824200 -CONFIG_DEBUG_USER=y -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_DMADEVICES=y -CONFIG_DMATEST=y -CONFIG_DMA_CMA=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_ENGINE_RAID=y -CONFIG_DMA_OF=y -CONFIG_DMA_OPS=y -CONFIG_DTC=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_EARLY_PRINTK=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EEPROM_AT24=y -# CONFIG_EFI_PARTITION is not set -CONFIG_EXCLUSIVE_SYSTEM_RAM=y -CONFIG_EXT4_FS=y -CONFIG_FANOTIFY=y -CONFIG_FAT_FS=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FWNODE_MDIO=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y -CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_VDSO_32=y -CONFIG_GLOB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GRACE_PERIOD=y -# CONFIG_HARDEN_BRANCH_HISTORY is not set -# CONFIG_HARDEN_BRANCH_PREDICTOR is not set -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAVE_SMP=y -CONFIG_HW_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_HZ_FIXED=0 -CONFIG_I2C=y -CONFIG_I2C_AT91=y -# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_IIO=y -CONFIG_IIO_BUFFER=y -CONFIG_IIO_CONFIGFS=y -# CONFIG_IIO_HRTIMER_TRIGGER is not set -CONFIG_IIO_KFIFO_BUF=y -CONFIG_IIO_SW_TRIGGER=y -# CONFIG_IIO_TIGHTLOOP_TRIGGER is not set -CONFIG_IIO_TRIGGER=y -CONFIG_IIO_TRIGGERED_BUFFER=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_INPUT=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_BOOTP is not set -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_RARP is not set -CONFIG_IRQCHIP=y -CONFIG_IRQSTACKS=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_LEDS_GPIO=y -CONFIG_LIBFDT=y -CONFIG_LOCKD=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOG_BUF_SHIFT=16 -CONFIG_LSM="N" -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MACB=y -CONFIG_MACB_USE_HWSTAMP=y -# CONFIG_MCHP_EIC is not set -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_CONTROLLER=y -CONFIG_MEDIA_PLATFORM_SUPPORT=y -CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_SUPPORT_FILTER=y -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 -CONFIG_MFD_AT91_USART=y -CONFIG_MFD_ATMEL_FLEXCOM=y -CONFIG_MFD_CORE=y -CONFIG_MFD_SYSCON=y -CONFIG_MICREL_PHY=y -CONFIG_MICROCHIP_CLOCKSOURCE_PIT64B=y -CONFIG_MICROCHIP_PIT64B=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -# CONFIG_MMC_ATMELMCI is not set -CONFIG_MMC_BLOCK=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_OF_AT91=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_PER_CPU_KM=y -CONFIG_NEON=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_SELFTESTS=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NFS_FS=y -CONFIG_NLS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NVMEM=y -CONFIG_NVMEM_LAYOUTS=y -# CONFIG_NVMEM_MICROCHIP_OTPC is not set -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_SIGSUSPEND3=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PAGE_POOL=y -CONFIG_PAGE_SIZE_LESS_THAN_256KB=y -CONFIG_PAGE_SIZE_LESS_THAN_64KB=y -CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y -CONFIG_PCCARD=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLIB_LEDS=y -CONFIG_PHYLINK=y -CONFIG_PINCTRL=y -CONFIG_PINCTRL_AT91=y -CONFIG_PINCTRL_AT91PIO4=y -CONFIG_PM_OPP=y -CONFIG_POWER_RESET=y -# CONFIG_POWER_RESET_AT91_POWEROFF is not set -CONFIG_POWER_RESET_AT91_RESET=y -CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y -CONFIG_PPS=y -CONFIG_PREEMPT_NONE_BUILD=y -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -CONFIG_PRINTK_TIME=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_PWM=y -CONFIG_PWM_ATMEL=y -CONFIG_PWM_SYSFS=y -CONFIG_RANDSTRUCT_NONE=y -CONFIG_RATIONAL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_MCP16502=y -CONFIG_ROOT_NFS=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91RM9200=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_RTC_MC146818_LIB=y -# CONFIG_RUNTIME_TESTING_MENU is not set -CONFIG_SAMA5D4_WATCHDOG=y -CONFIG_SCSI=y -CONFIG_SCSI_COMMON=y -# CONFIG_SERIAL_8250 is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_SERIAL_ATMEL_PDC=y -# CONFIG_SERIAL_ATMEL_TTYAT is not set -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SGL_ALLOC=y -CONFIG_SG_POOL=y -CONFIG_SND=y -CONFIG_SND_ATMEL_SOC=y -# CONFIG_SND_ATMEL_SOC_CLASSD is not set -# CONFIG_SND_ATMEL_SOC_I2S is not set -# CONFIG_SND_ATMEL_SOC_PDMIC is not set -# CONFIG_SND_COMPRESS_OFFLOAD is not set -CONFIG_SND_DMAENGINE_PCM=y -CONFIG_SND_JACK=y -CONFIG_SND_JACK_INPUT_DEV=y -CONFIG_SND_MCHP_SOC_I2S_MCC=y -# CONFIG_SND_MCHP_SOC_PDMC is not set -CONFIG_SND_MCHP_SOC_SPDIFRX=y -CONFIG_SND_MCHP_SOC_SPDIFTX=y -CONFIG_SND_PCM=y -CONFIG_SND_SIMPLE_CARD=y -CONFIG_SND_SIMPLE_CARD_UTILS=y -CONFIG_SND_SOC=y -CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y -CONFIG_SND_SOC_I2C_AND_SPI=y -# CONFIG_SND_SOC_MIKROE_PROTO is not set -CONFIG_SND_SOC_PCM5102A=y -CONFIG_SND_SOC_SPDIF=y -CONFIG_SOC_BUS=y -# CONFIG_SOC_LAN966 is not set -# CONFIG_SOC_SAMA5D2 is not set -# CONFIG_SOC_SAMA5D3 is not set -# CONFIG_SOC_SAMA5D4 is not set -CONFIG_SOC_SAMA7=y -CONFIG_SOC_SAMA7G5=y -CONFIG_SOC_SAM_V7=y -CONFIG_SOFTIRQ_ON_OWN_STACK=y -CONFIG_SOUND=y -CONFIG_SOUND_OSS_CORE=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -# CONFIG_SPI_AT91_USART is not set -CONFIG_SPI_ATMEL=y -# CONFIG_SPI_ATMEL_QUADSPI is not set -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SRCU=y -CONFIG_STACKTRACE=y -# CONFIG_STANDALONE is not set -CONFIG_SUNRPC=y -# CONFIG_SWAP is not set -CONFIG_SWPHY=y -# CONFIG_SWP_EMULATE is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TINY_SRCU=y -CONFIG_UACCESS_WITH_MEMCPY=y -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_UNWINDER_ARM=y -CONFIG_USE_OF=y -CONFIG_VFAT_FS=y -CONFIG_VFP=y -CONFIG_VFPv3=y -# CONFIG_VIDEO_ATMEL_XISC is not set -CONFIG_VIDEO_DEV=y -# CONFIG_VIDEO_MICROCHIP_CSI2DC is not set -CONFIG_VIDEO_V4L2_I2C=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_WATCHDOG_CORE=y -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y From 0627030fbe0e79c3af103583194b2ac7c2b4a6c4 Mon Sep 17 00:00:00 2001 From: Mieczyslaw Nalewaj Date: Fri, 9 Aug 2024 17:47:02 +0200 Subject: [PATCH 10/23] qoriq: use kernel 6.6 by default Switch to Linux kernel version 6.6. Link: https://github.com/openwrt/openwrt/pull/16120 Signed-off-by: Mieczyslaw Nalewaj --- target/linux/qoriq/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/target/linux/qoriq/Makefile b/target/linux/qoriq/Makefile index 9d03c3183ff4f5..59c413aa506883 100644 --- a/target/linux/qoriq/Makefile +++ b/target/linux/qoriq/Makefile @@ -11,8 +11,7 @@ CPU_TYPE:=e5500 FEATURES:=boot-part ext4 fpu legacy-sdcard powerpc64 ramdisk rootfs-part rtc source-only SUBTARGETS:=generic -KERNEL_PATCHVER:=6.1 -KERNEL_TESTING_PATCHVER:=6.6 +KERNEL_PATCHVER:=6.6 KERNELNAME:=zImage From 8d581a8b489126dff64aa69bf7b78d674765df99 Mon Sep 17 00:00:00 2001 From: Mieczyslaw Nalewaj Date: Sun, 8 Sep 2024 10:11:15 +0200 Subject: [PATCH 11/23] qoriq: drop 6.1 support Drop config for Linux 6.1. Link: https://github.com/openwrt/openwrt/pull/16120 Signed-off-by: Mieczyslaw Nalewaj --- target/linux/qoriq/config-6.1 | 420 ---------------------------------- 1 file changed, 420 deletions(-) delete mode 100644 target/linux/qoriq/config-6.1 diff --git a/target/linux/qoriq/config-6.1 b/target/linux/qoriq/config-6.1 deleted file mode 100644 index 4d803ffa80667c..00000000000000 --- a/target/linux/qoriq/config-6.1 +++ /dev/null @@ -1,420 +0,0 @@ -CONFIG_64BIT=y -CONFIG_ALTIVEC=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_FORCE_MAX_ORDER=13 -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=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=32 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=17 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_STACKWALK=y -CONFIG_ARCH_WEAK_RELEASE_ACQUIRE=y -CONFIG_ASN1=y -CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y -CONFIG_AUDIT_ARCH=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_PM=y -CONFIG_BOOKE=y -CONFIG_BOOKE_OR_40x=y -CONFIG_BOOKE_WDT=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y -CONFIG_CLK_QORIQ=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CLZ_TAB=y -CONFIG_COMMON_CLK=y -CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 -# CONFIG_COMPAT_32BIT_TIME is not set -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_CONTEXT_TRACKING=y -CONFIG_CONTEXT_TRACKING_IDLE=y -CONFIG_CORENET_GENERIC=y -# CONFIG_CPUFREQ_DT is not set -CONFIG_CPU_BIG_ENDIAN=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -# CONFIG_CPU_FREQ_STAT is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_TEO=y -CONFIG_CPU_ISOLATION=y -CONFIG_CPU_RMAP=y -CONFIG_CRC16=y -CONFIG_CRYPTO_AUTHENC=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -# CONFIG_CRYPTO_CRC32C_VPMSUM is not set -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_DEV_FSL_CAAM=y -CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y -CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=y -CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=y -CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y -CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=y -CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI=y -# CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG is not set -# CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set -CONFIG_CRYPTO_DEV_FSL_CAAM_JR=y -CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y -CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y -CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9 -CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y -# CONFIG_CRYPTO_DEV_NX is not set -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_ENGINE=y -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_DES=y -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=1 -CONFIG_CRYPTO_LIB_SHA1=y -CONFIG_CRYPTO_LIB_UTILS=y -# CONFIG_CRYPTO_MD5_PPC is not set -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_RSA=y -# CONFIG_CRYPTO_SHA1_PPC is not set -CONFIG_CRYPTO_XTS=y -CONFIG_DATA_SHIFT=12 -CONFIG_DEBUG_INFO=y -CONFIG_DEFAULT_UIMAGE=y -CONFIG_DMADEVICES=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_OPS=y -CONFIG_DMA_OPS_BYPASS=y -CONFIG_DTC=y -CONFIG_DUMMY_CONSOLE=y -# CONFIG_E5500_CPU is not set -CONFIG_E6500_CPU=y -CONFIG_EARLY_PRINTK=y -CONFIG_EDAC=y -CONFIG_EDAC_ATOMIC_SCRUB=y -# CONFIG_EDAC_CPC925 is not set -# CONFIG_EDAC_DEBUG is not set -CONFIG_EDAC_LEGACY_SYSFS=y -CONFIG_EDAC_MPC85XX=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EPAPR_PARAVIRT=y -CONFIG_EXCLUSIVE_SYSTEM_RAM=y -CONFIG_EXT4_FS=y -CONFIG_F2FS_FS=y -CONFIG_FIXED_PHY=y -# CONFIG_FSL_BMAN_TEST is not set -CONFIG_FSL_CORENET_CF=y -CONFIG_FSL_CORENET_RCPM=y -CONFIG_FSL_DMA=y -CONFIG_FSL_DPAA=y -# CONFIG_FSL_DPAA_CHECKING is not set -CONFIG_FSL_DPAA_ETH=y -CONFIG_FSL_EMB_PERFMON=y -CONFIG_FSL_FMAN=y -CONFIG_FSL_GUTS=y -CONFIG_FSL_IFC=y -CONFIG_FSL_LBC=y -CONFIG_FSL_MPIC_TIMER_WAKEUP=y -CONFIG_FSL_PAMU=y -CONFIG_FSL_PCI=y -# CONFIG_FSL_QMAN_TEST is not set -CONFIG_FSL_SOC=y -CONFIG_FSL_SOC_BOOKE=y -CONFIG_FSL_XGMAC_MDIO=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FTL=y -CONFIG_FUNCTION_ERROR_INJECTION=y -CONFIG_FWNODE_MDIO=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC10_NO_ARRAY_BOUNDS=y -CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IRQ_MIGRATION=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_PHY=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_GIANFAR is not set -CONFIG_GLOB=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_MPC8XXX=y -CONFIG_GRO_CELLS=y -# CONFIG_HANGCHECK_TIMER is not set -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HWMON=y -CONFIG_HW_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_MPC=y -CONFIG_ILLEGAL_POINTER_VALUE=0x5deadbeef0000000 -CONFIG_INITRAMFS_SOURCE="" -CONFIG_INPUT=y -CONFIG_IOMMU_API=y -# CONFIG_IOMMU_DEBUGFS is not set -# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set -CONFIG_IOMMU_DEFAULT_DMA_STRICT=y -# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set -CONFIG_IOMMU_HELPER=y -CONFIG_IOMMU_SUPPORT=y -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_JBD2=y -CONFIG_JUMP_LABEL=y -CONFIG_JUMP_LABEL_FEATURE_CHECKS=y -# CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG is not set -CONFIG_KALLSYMS=y -CONFIG_KERNEL_GZIP=y -CONFIG_KERNEL_START=0xc000000000000000 -CONFIG_KPROBES=y -CONFIG_KRETPROBES=y -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MARVELL_PHY=y -CONFIG_MATH_EMULATION=y -# CONFIG_MATH_EMULATION_FULL is not set -CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_DEBUG=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_IO_ACCESSORS=y -CONFIG_MMC_SDHCI_OF_ESDHC=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -# CONFIG_MMC_WBSD is not set -CONFIG_MMIOWB=y -CONFIG_MMU_GATHER_MERGE_VMAS=y -CONFIG_MMU_GATHER_PAGE_SIZE=y -CONFIG_MODULES_USE_ELF_RELA=y -CONFIG_MPIC=y -CONFIG_MPIC_MSGR=y -CONFIG_MPIC_TIMER=y -CONFIG_MPILIB=y -CONFIG_MTD_NAND_CORE=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_ECC_SW_HAMMING=y -CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_RAW_NAND=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y -CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_MV88E6XXX=y -CONFIG_NET_DSA_TAG_DSA=y -CONFIG_NET_DSA_TAG_DSA_COMMON=y -CONFIG_NET_DSA_TAG_EDSA=y -CONFIG_NET_DSA_TAG_OCELOT=y -CONFIG_NET_DSA_TAG_TRAILER=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_SELFTESTS=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NLS=y -CONFIG_NONSTATIC_KERNEL=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=24 -CONFIG_NR_IRQS=512 -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_DMA_DEFAULT_COHERENT=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IOMMU=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_OLD_SIGSUSPEND=y -CONFIG_OPTPROBES=y -CONFIG_PACKING=y -CONFIG_PADATA=y -CONFIG_PAGE_OFFSET=0xc000000000000000 -CONFIG_PAGE_POOL=y -CONFIG_PAGE_SIZE_LESS_THAN_256KB=y -CONFIG_PAGE_SIZE_LESS_THAN_64KB=y -CONFIG_PAHOLE_HAS_LANG_EXCLUDE=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_ARCH_FALLBACKS=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PCS_LYNX=y -CONFIG_PGTABLE_LEVELS=4 -CONFIG_PHYLIB=y -CONFIG_PHYLIB_LEDS=y -CONFIG_PHYLINK=y -CONFIG_PHYSICAL_START=0x00000000 -CONFIG_PHYS_64BIT=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_PM=y -# CONFIG_PMU_SYSFS is not set -CONFIG_PM_CLK=y -CONFIG_PPC=y -CONFIG_PPC64=y -CONFIG_PPC64_ELF_ABI_V1=y -CONFIG_PPC_ADV_DEBUG_DACS=2 -CONFIG_PPC_ADV_DEBUG_DVCS=0 -CONFIG_PPC_ADV_DEBUG_IACS=2 -CONFIG_PPC_ADV_DEBUG_REGS=y -CONFIG_PPC_BARRIER_NOSPEC=y -CONFIG_PPC_BOOK3E_64=y -# CONFIG_PPC_BOOK3S_64 is not set -CONFIG_PPC_DAWR=y -CONFIG_PPC_DOORBELL=y -CONFIG_PPC_E500=y -CONFIG_PPC_E500MC=y -# CONFIG_PPC_EARLY_DEBUG is not set -CONFIG_PPC_EPAPR_HV_PIC=y -CONFIG_PPC_FPU=y -CONFIG_PPC_FPU_REGS=y -CONFIG_PPC_INDIRECT_PCI=y -# CONFIG_PPC_IRQ_SOFT_MASK_DEBUG is not set -CONFIG_PPC_KUAP=y -# CONFIG_PPC_KUAP_DEBUG is not set -CONFIG_PPC_KUEP=y -CONFIG_PPC_MMU_NOHASH=y -CONFIG_PPC_MSI_BITMAP=y -CONFIG_PPC_OF_BOOT_TRAMPOLINE=y -CONFIG_PPC_PAGE_SHIFT=12 -# CONFIG_PPC_QEMU_E500 is not set -CONFIG_PPC_QUEUED_SPINLOCKS=y -CONFIG_PPC_SMP_MUXED_IPI=y -CONFIG_PPC_UDBG_16550=y -CONFIG_PPC_WERROR=y -CONFIG_PPS=y -CONFIG_PREEMPT_NONE_BUILD=y -CONFIG_PTE_64BIT=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_PTP_1588_CLOCK_QORIQ=y -CONFIG_QORIQ_CPUFREQ=y -CONFIG_QORIQ_THERMAL=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -CONFIG_RANDSTRUCT_NONE=y -CONFIG_RAS=y -CONFIG_RATIONAL=y -# CONFIG_RAVE_SP_CORE is not set -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_RELOCATABLE=y -# CONFIG_RELOCATABLE_TEST is not set -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -# CONFIG_SCOM_DEBUGFS is not set -CONFIG_SCSI=y -CONFIG_SCSI_COMMON=y -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_DEV_BUS=y -CONFIG_SERIAL_DEV_CTRL_TTYPORT=y -CONFIG_SERIAL_FSL_LINFLEXUART=y -CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y -CONFIG_SERIAL_FSL_LPUART=y -CONFIG_SERIAL_FSL_LPUART_CONSOLE=y -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_SOC_BUS=y -CONFIG_SOFTIRQ_ON_OWN_STACK=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -CONFIG_SPI_FSL_ESPI=y -CONFIG_SPI_MASTER=y -CONFIG_SRCU=y -CONFIG_SWIOTLB=y -CONFIG_SWPHY=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_TARGET_CPU="e6500" -CONFIG_TARGET_CPU_BOOL=y -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_THREAD_SHIFT=14 -# CONFIG_TOOLCHAIN_DEFAULT_CPU is not set -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -# CONFIG_UACCE is not set -# CONFIG_UCLAMP_TASK is not set -CONFIG_USB=y -CONFIG_USB_COMMON=y -CONFIG_USB_EHCI_FSL=y -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_HCD_PLATFORM is not set -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USB_UAS=y -CONFIG_VGA_CONSOLE=y -CONFIG_VIRT_CPU_ACCOUNTING=y -CONFIG_VIRT_CPU_ACCOUNTING_NATIVE=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -CONFIG_WATCHDOG_CORE=y -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_XPS=y -CONFIG_ZLIB_DEFLATE=y From b40cc46cc882ff97f2752e7837173ffc9f884eb9 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Sat, 14 Sep 2024 19:10:10 +0200 Subject: [PATCH 12/23] ipq40xx: add PoE passthrough GPIO Add the GPIO pin of the PoE passthrough switch on the Aruba AP-303H. Power is activated when the pin is low. It enables a PSE chip, so power is only supplied to downstream devices when they are 802.3af/at compliant devices. Ensure you use a sufficient power supply when chaining a consuming device after the AP. Signed-off-by: David Bauer --- target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches b/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches index 226785d46c43df..43ed32fc2b7c80 100644 --- a/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches +++ b/target/linux/ipq40xx/base-files/etc/board.d/03_gpio_switches @@ -6,6 +6,9 @@ board_config_update board=$(board_name) case "$board" in +aruba,ap-303h) + ucidef_add_gpio_switch "poe_passtrough" "POE passtrough disable" "546" "1" + ;; cellc,rtl30vw) ucidef_add_gpio_switch "w_disable" "W_DISABLE mPCIE pin" "398" "1" ucidef_add_gpio_switch "pmd_resin_n" "PMD_RESIN_N pin" "399" "1" From 12a8e72ed20a56f2989d44c6e7ca06dc03cd25aa Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 20 Sep 2024 18:45:07 +0100 Subject: [PATCH 13/23] pistachio: drop files for Linux 6.1 Drop obsolete config and patches for Linux 6.1. Signed-off-by: Daniel Golle --- target/linux/pistachio/config-6.1 | 333 ------------------ ...ine-img-mdc-Handle-early-status-read.patch | 68 ---- ...mg-spfi-Implement-dual-and-quad-mode.patch | 198 ----------- ...-device-0-configuration-for-all-devi.patch | 64 ---- ...i-RX-maximum-burst-size-for-DMA-is-8.patch | 59 ---- ...g-spfi-finish-every-transfer-cleanly.patch | 120 ------- ...istachio-Fix-wrong-SDHost-card-speed.patch | 49 --- ...-img-marduk-switch-mmc-to-1-bit-mode.patch | 47 --- ...or-support-mtd-name-from-device-tree.patch | 53 --- ...PS-DTS-img-marduk-Add-SPI-NAND-flash.patch | 30 -- ...mg-marduk-Add-Cascoda-CA8210-6LoWPAN.patch | 43 --- ...-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch | 81 ----- ...PS-DTS-img-marduk-Add-partition-name.patch | 27 -- ...-MIPS-DTS-img-marduk-Add-led-aliases.patch | 27 -- 14 files changed, 1199 deletions(-) delete mode 100644 target/linux/pistachio/config-6.1 delete mode 100644 target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch delete mode 100644 target/linux/pistachio/patches-6.1/102-spi-img-spfi-Implement-dual-and-quad-mode.patch delete mode 100644 target/linux/pistachio/patches-6.1/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch delete mode 100644 target/linux/pistachio/patches-6.1/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch delete mode 100644 target/linux/pistachio/patches-6.1/106-spi-img-spfi-finish-every-transfer-cleanly.patch delete mode 100644 target/linux/pistachio/patches-6.1/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch delete mode 100644 target/linux/pistachio/patches-6.1/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch delete mode 100644 target/linux/pistachio/patches-6.1/401-mtd-nor-support-mtd-name-from-device-tree.patch delete mode 100644 target/linux/pistachio/patches-6.1/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch delete mode 100644 target/linux/pistachio/patches-6.1/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch delete mode 100644 target/linux/pistachio/patches-6.1/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch delete mode 100644 target/linux/pistachio/patches-6.1/904-MIPS-DTS-img-marduk-Add-partition-name.patch delete mode 100644 target/linux/pistachio/patches-6.1/905-MIPS-DTS-img-marduk-Add-led-aliases.patch diff --git a/target/linux/pistachio/config-6.1 b/target/linux/pistachio/config-6.1 deleted file mode 100644 index 54145cd1f4aedb..00000000000000 --- a/target/linux/pistachio/config-6.1 +++ /dev/null @@ -1,333 +0,0 @@ -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MMAP_RND_BITS_MAX=15 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_SD=y -# CONFIG_BOARD_INGENIC is not set -CONFIG_BOARD_SCACHE=y -CONFIG_BUILTIN_DTB=y -CONFIG_CEVT_R4K=y -CONFIG_CLKSRC_MIPS_GIC=y -CONFIG_CLKSRC_PISTACHIO=y -CONFIG_CLOCKSOURCE_WATCHDOG=y -CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100 -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_PISTACHIO=y -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONNECTOR=y -CONFIG_CPU_GENERIC_DUMP_TLB=y -CONFIG_CPU_HAS_DIEI=y -CONFIG_CPU_HAS_PREFETCH=y -CONFIG_CPU_HAS_RIXI=y -# CONFIG_CPU_HAS_SMARTMIPS is not set -CONFIG_CPU_HAS_SYNC=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_CPU_MICROMIPS is not set -CONFIG_CPU_MIPS32=y -# CONFIG_CPU_MIPS32_R1 is not set -CONFIG_CPU_MIPS32_R2=y -# CONFIG_CPU_MIPS32_R6 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_MIPS64_R6 is not set -CONFIG_CPU_MIPSR2=y -CONFIG_CPU_MIPSR2_IRQ_EI=y -CONFIG_CPU_MIPSR2_IRQ_VI=y -CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y -CONFIG_CPU_PM=y -CONFIG_CPU_R4K_CACHE_TLB=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_HIGHMEM=y -CONFIG_CPU_SUPPORTS_MSA=y -CONFIG_CRC16=y -CONFIG_CRC_CCITT=y -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2 -CONFIG_CRYPTO_LIB_SHA256=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_ZSTD=y -CONFIG_CSRC_R4K=y -CONFIG_DMADEVICES=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_OF=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DTC=y -CONFIG_DWMAC_GENERIC=y -CONFIG_EXT4_FS=y -# CONFIG_FIT_IMAGE_FDT_BOSTON is not set -# CONFIG_FIT_IMAGE_FDT_JAGUAR2 is not set -# CONFIG_FIT_IMAGE_FDT_LUTON is not set -CONFIG_FIT_IMAGE_FDT_MARDUK=y -# CONFIG_FIT_IMAGE_FDT_NI169445 is not set -# CONFIG_FIT_IMAGE_FDT_OCELOT is not set -# CONFIG_FIT_IMAGE_FDT_SERVAL is not set -# CONFIG_FIT_IMAGE_FDT_XILFPGA is not set -CONFIG_FIXED_PHY=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FWNODE_MDIO=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ATOMIC64=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_FIND_FIRST_BIT=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IOMAP=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_LIB_ASHLDI3=y -CONFIG_GENERIC_LIB_ASHRDI3=y -CONFIG_GENERIC_LIB_CMPDI2=y -CONFIG_GENERIC_LIB_LSHRDI3=y -CONFIG_GENERIC_LIB_UCMPDI2=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDWARE_WATCHPOINTS=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HOTPLUG_CPU=y -CONFIG_HZ_PERIODIC=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_IMG=y -CONFIG_IMGPDC_WDT=y -CONFIG_IMG_MDC_DMA=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_MIPS_CPU=y -CONFIG_IRQ_WORK=y -CONFIG_JBD2=y -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_PWM=y -# CONFIG_LEGACY_BOARD_OCELOT is not set -# CONFIG_LEGACY_BOARD_SEAD3 is not set -CONFIG_LIBFDT=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOG_BUF_SHIFT=18 -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0 -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -CONFIG_MEMFD_CREATE=y -CONFIG_MFD_SYSCON=y -CONFIG_MICREL_PHY=y -CONFIG_MIGRATION=y -CONFIG_MIPS=y -CONFIG_MIPS_ASID_BITS=8 -CONFIG_MIPS_ASID_SHIFT=0 -CONFIG_MIPS_AUTO_PFN_OFFSET=y -CONFIG_MIPS_CLOCK_VSYSCALL=y -CONFIG_MIPS_CM=y -CONFIG_MIPS_CMDLINE_DTB_EXTEND=y -# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set -CONFIG_MIPS_CPC=y -CONFIG_MIPS_CPS=y -# CONFIG_MIPS_CPS_CPUIDLE is not set -# CONFIG_MIPS_CPS_NS16550_BOOL is not set -CONFIG_MIPS_CPS_PM=y -CONFIG_MIPS_CPU_SCACHE=y -CONFIG_MIPS_EBPF_JIT=y -CONFIG_MIPS_GENERIC=y -CONFIG_MIPS_GENERIC_KERNEL=y -CONFIG_MIPS_GIC=y -CONFIG_MIPS_L1_CACHE_SHIFT=7 -CONFIG_MIPS_L1_CACHE_SHIFT_7=y -CONFIG_MIPS_LD_CAN_LINK_VDSO=y -CONFIG_MIPS_MT=y -CONFIG_MIPS_MT_FPAFF=y -CONFIG_MIPS_MT_SMP=y -CONFIG_MIPS_NO_APPENDED_DTB=y -CONFIG_MIPS_NR_CPU_NR_MAP=4 -CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y -CONFIG_MIPS_SPRAM=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_DW=y -# CONFIG_MMC_DW_BLUEFIELD is not set -# CONFIG_MMC_DW_EXYNOS is not set -# CONFIG_MMC_DW_HI3798CV200 is not set -# CONFIG_MMC_DW_K3 is not set -CONFIG_MMC_DW_PLTFM=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_NAND_CORE=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_SPI_NAND=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -CONFIG_MTD_UBI_BLOCK=y -CONFIG_MTD_UBI_FASTMAP=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_SELFTESTS=y -CONFIG_NLS=y -CONFIG_NO_EXCEPT_FILL=y -CONFIG_NR_CPUS=4 -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_PADATA=y -CONFIG_PAGE_POOL=y -CONFIG_PCI_DRIVERS_GENERIC=y -CONFIG_PCS_XPCS=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=2 -CONFIG_PHYLIB=y -CONFIG_PHYLINK=y -CONFIG_PHY_PISTACHIO_USB=y -CONFIG_PINCTRL=y -CONFIG_PINCTRL_PISTACHIO=y -CONFIG_POWER_SUPPLY=y -CONFIG_PPS=y -CONFIG_PRINTK_TIME=y -CONFIG_PROC_EVENTS=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_PWM=y -CONFIG_PWM_IMG=y -CONFIG_PWM_SYSFS=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -CONFIG_RATIONAL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_GPIO=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RESET_PISTACHIO=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_SCHEDSTATS=y -CONFIG_SCHED_INFO=y -CONFIG_SCSI=y -CONFIG_SCSI_COMMON=y -CONFIG_SCSI_SPI_ATTRS=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_8250_DWLIB=y -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SERIAL_SC16IS7XX=y -CONFIG_SERIAL_SC16IS7XX_CORE=y -# CONFIG_SERIAL_SC16IS7XX_I2C is not set -CONFIG_SERIAL_SC16IS7XX_SPI=y -CONFIG_SGL_ALLOC=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SMP_UP=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_SPI=y -CONFIG_SPI_IMG_SPFI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SRAM=y -CONFIG_SRCU=y -CONFIG_STMMAC_ETH=y -CONFIG_STMMAC_PLATFORM=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_SWPHY=y -CONFIG_SYNC_R4K=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_SYS_HAS_CPU_MIPS32_R1=y -CONFIG_SYS_HAS_CPU_MIPS32_R2=y -CONFIG_SYS_HAS_CPU_MIPS32_R6=y -CONFIG_SYS_HAS_CPU_MIPS64_R1=y -CONFIG_SYS_HAS_CPU_MIPS64_R2=y -CONFIG_SYS_HAS_CPU_MIPS64_R6=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_SYS_SUPPORTS_HIGHMEM=y -CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y -CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y -CONFIG_SYS_SUPPORTS_MICROMIPS=y -CONFIG_SYS_SUPPORTS_MIPS16=y -CONFIG_SYS_SUPPORTS_MIPS_CPS=y -CONFIG_SYS_SUPPORTS_MULTITHREADING=y -CONFIG_SYS_SUPPORTS_RELOCATABLE=y -CONFIG_SYS_SUPPORTS_SCHED_SMT=y -CONFIG_SYS_SUPPORTS_SMARTMIPS=y -CONFIG_SYS_SUPPORTS_SMP=y -CONFIG_SYS_SUPPORTS_ZBOOT=y -CONFIG_TARGET_ISA_REV=2 -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_UBIFS_FS=y -CONFIG_UHI_BOOT=y -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_COMMON=y -CONFIG_USB_DWC2=y -CONFIG_USB_DWC2_DUAL_ROLE=y -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_HCD_PLATFORM is not set -CONFIG_USB_GADGET=y -CONFIG_USB_ROLE_SWITCH=y -CONFIG_USB_STORAGE=y -CONFIG_USB_SUPPORT=y -CONFIG_USE_OF=y -# CONFIG_VIRT_BOARD_RANCHU is not set -CONFIG_WATCHDOG_CORE=y -CONFIG_WEAK_ORDERING=y -CONFIG_XPS=y -CONFIG_XXHASH=y -CONFIG_ZBOOT_LOAD_ADDRESS=0x0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZSMALLOC=y -# CONFIG_ZSMALLOC_STAT is not set -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch b/target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch deleted file mode 100644 index 031a4e3e5eedd6..00000000000000 --- a/target/linux/pistachio/patches-6.1/101-dmaengine-img-mdc-Handle-early-status-read.patch +++ /dev/null @@ -1,68 +0,0 @@ -From a2dd154377c9aa6ddda00d39b8c7c334e4fa16ff Mon Sep 17 00:00:00 2001 -From: Damien Horsley -Date: Tue, 22 Mar 2016 12:46:09 +0000 -Subject: dmaengine: img-mdc: Handle early status read - -It is possible that mdc_tx_status may be called before the first -node has been read from memory. - -In this case, the residue value stored in the register is undefined. -Return the transfer size instead. - -Signed-off-by: Damien Horsley ---- - drivers/dma/img-mdc-dma.c | 40 ++++++++++++++++++++++++---------------- - 1 file changed, 24 insertions(+), 16 deletions(-) - ---- a/drivers/dma/img-mdc-dma.c -+++ b/drivers/dma/img-mdc-dma.c -@@ -618,25 +618,33 @@ static enum dma_status mdc_tx_status(str - (MDC_CMDS_PROCESSED_CMDS_DONE_MASK + 1); - - /* -- * If the command loaded event hasn't been processed yet, then -- * the difference above includes an extra command. -+ * If the first node has not yet been read from memory, -+ * the residue register value is undefined - */ -- if (!mdesc->cmd_loaded) -- cmds--; -- else -- cmds += mdesc->list_cmds_done; -- -- bytes = mdesc->list_xfer_size; -- ldesc = mdesc->list; -- for (i = 0; i < cmds; i++) { -- bytes -= ldesc->xfer_size + 1; -- ldesc = ldesc->next_desc; -- } -- if (ldesc) { -- if (residue != MDC_TRANSFER_SIZE_MASK) -- bytes -= ldesc->xfer_size - residue; -+ if (!mdesc->cmd_loaded && !cmds) { -+ bytes = mdesc->list_xfer_size; -+ } else { -+ /* -+ * If the command loaded event hasn't been processed yet, then -+ * the difference above includes an extra command. -+ */ -+ if (!mdesc->cmd_loaded) -+ cmds--; - else -+ cmds += mdesc->list_cmds_done; -+ -+ bytes = mdesc->list_xfer_size; -+ ldesc = mdesc->list; -+ for (i = 0; i < cmds; i++) { - bytes -= ldesc->xfer_size + 1; -+ ldesc = ldesc->next_desc; -+ } -+ if (ldesc) { -+ if (residue != MDC_TRANSFER_SIZE_MASK) -+ bytes -= ldesc->xfer_size - residue; -+ else -+ bytes -= ldesc->xfer_size + 1; -+ } - } - } - spin_unlock_irqrestore(&mchan->vc.lock, flags); diff --git a/target/linux/pistachio/patches-6.1/102-spi-img-spfi-Implement-dual-and-quad-mode.patch b/target/linux/pistachio/patches-6.1/102-spi-img-spfi-Implement-dual-and-quad-mode.patch deleted file mode 100644 index 83f21a5c0a5dee..00000000000000 --- a/target/linux/pistachio/patches-6.1/102-spi-img-spfi-Implement-dual-and-quad-mode.patch +++ /dev/null @@ -1,198 +0,0 @@ -From cd2a6af51553d38072cd31699b58d16ca6176ef5 Mon Sep 17 00:00:00 2001 -From: Ionela Voinescu -Date: Thu, 2 Feb 2017 16:46:14 +0000 -Subject: spi: img-spfi: Implement dual and quad mode - -For dual and quad modes to work the SPFI controller needs -to have information about command/address/dummy bytes in the -transaction register. This information is not relevant for -single mode, and therefore it can have any value in the -allowed range. Therefore, for any read or write transfers of less -than 8 bytes (cmd = 1 byte, addr up to 7 bytes), SPFI will be -configured, but not enabled (unless it is the last transfer in -the queue). The transfer will be enabled by the subsequent tranfer. -A pending transfer is determined by the content of the transaction -register: if command part is set and tsize is not. - -This way we ensure that for dual and quad transactions -the command request size will apear in the command/address part -of the transaction register, while the data size will be in -tsize, all data being sent/received in the same transaction (as -set up in the transaction register). - -Signed-off-by: Ionela Voinescu -Signed-off-by: Ezequiel Garcia ---- - drivers/spi/spi-img-spfi.c | 96 ++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 85 insertions(+), 11 deletions(-) - ---- a/drivers/spi/spi-img-spfi.c -+++ b/drivers/spi/spi-img-spfi.c -@@ -36,7 +36,8 @@ - #define SPFI_CONTROL_SOFT_RESET BIT(11) - #define SPFI_CONTROL_SEND_DMA BIT(10) - #define SPFI_CONTROL_GET_DMA BIT(9) --#define SPFI_CONTROL_SE BIT(8) -+#define SPFI_CONTROL_SE BIT(8) -+#define SPFI_CONTROL_TX_RX BIT(1) - #define SPFI_CONTROL_TMODE_SHIFT 5 - #define SPFI_CONTROL_TMODE_MASK 0x7 - #define SPFI_CONTROL_TMODE_SINGLE 0 -@@ -47,6 +48,10 @@ - #define SPFI_TRANSACTION 0x18 - #define SPFI_TRANSACTION_TSIZE_SHIFT 16 - #define SPFI_TRANSACTION_TSIZE_MASK 0xffff -+#define SPFI_TRANSACTION_CMD_SHIFT 13 -+#define SPFI_TRANSACTION_CMD_MASK 0x7 -+#define SPFI_TRANSACTION_ADDR_SHIFT 10 -+#define SPFI_TRANSACTION_ADDR_MASK 0x7 - - #define SPFI_PORT_STATE 0x1c - #define SPFI_PORT_STATE_DEV_SEL_SHIFT 20 -@@ -83,6 +88,7 @@ - */ - #define SPFI_32BIT_FIFO_SIZE 64 - #define SPFI_8BIT_FIFO_SIZE 16 -+#define SPFI_DATA_REQUEST_MAX_SIZE 8 - - struct img_spfi { - struct device *dev; -@@ -99,6 +105,8 @@ struct img_spfi { - struct dma_chan *tx_ch; - bool tx_dma_busy; - bool rx_dma_busy; -+ -+ bool complete; - }; - - static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg) -@@ -115,9 +123,11 @@ static inline void spfi_start(struct img - { - u32 val; - -- val = spfi_readl(spfi, SPFI_CONTROL); -- val |= SPFI_CONTROL_SPFI_EN; -- spfi_writel(spfi, val, SPFI_CONTROL); -+ if (spfi->complete) { -+ val = spfi_readl(spfi, SPFI_CONTROL); -+ val |= SPFI_CONTROL_SPFI_EN; -+ spfi_writel(spfi, val, SPFI_CONTROL); -+ } - } - - static inline void spfi_reset(struct img_spfi *spfi) -@@ -130,12 +140,21 @@ static int spfi_wait_all_done(struct img - { - unsigned long timeout = jiffies + msecs_to_jiffies(50); - -+ if (!(spfi->complete)) -+ return 0; -+ - while (time_before(jiffies, timeout)) { - u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); - - if (status & SPFI_INTERRUPT_ALLDONETRIG) { - spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG, - SPFI_INTERRUPT_CLEAR); -+ /* -+ * Disable SPFI for it not to interfere with -+ * pending transactions -+ */ -+ spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL) -+ & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL); - return 0; - } - cpu_relax(); -@@ -441,9 +460,32 @@ static void img_spfi_config(struct spi_m - struct spi_transfer *xfer) - { - struct img_spfi *spfi = spi_master_get_devdata(spi->master); -- u32 val, div; -+ u32 val, div, transact; -+ bool is_pending; - - /* -+ * For read or write transfers of less than 8 bytes (cmd = 1 byte, -+ * addr up to 7 bytes), SPFI will be configured, but not enabled -+ * (unless it is the last transfer in the queue).The transfer will -+ * be enabled by the subsequent transfer. -+ * A pending transfer is determined by the content of the -+ * transaction register: if command part is set and tsize -+ * is not -+ */ -+ transact = spfi_readl(spfi, SPFI_TRANSACTION); -+ is_pending = ((transact >> SPFI_TRANSACTION_CMD_SHIFT) & -+ SPFI_TRANSACTION_CMD_MASK) && -+ (!((transact >> SPFI_TRANSACTION_TSIZE_SHIFT) & -+ SPFI_TRANSACTION_TSIZE_MASK)); -+ -+ /* If there are no pending transactions it's OK to soft reset */ -+ if (!is_pending) { -+ /* Start the transaction from a known (reset) state */ -+ spfi_reset(spfi); -+ } -+ -+ /* -+ * Before anything else, set up parameters. - * output = spfi_clk * (BITCLK / 512), where BITCLK must be a - * power of 2 up to 128 - */ -@@ -456,20 +498,52 @@ static void img_spfi_config(struct spi_m - val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT; - spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select)); - -- spfi_writel(spfi, xfer->len << SPFI_TRANSACTION_TSIZE_SHIFT, -- SPFI_TRANSACTION); -+ if (!list_is_last(&xfer->transfer_list, &master->cur_msg->transfers) && -+ /* -+ * For duplex mode (both the tx and rx buffers are !NULL) the -+ * CMD, ADDR, and DUMMY byte parts of the transaction register -+ * should always be 0 and therefore the pending transfer -+ * technique cannot be used. -+ */ -+ (xfer->tx_buf) && (!xfer->rx_buf) && -+ (xfer->len <= SPFI_DATA_REQUEST_MAX_SIZE) && !is_pending) { -+ transact = (1 & SPFI_TRANSACTION_CMD_MASK) << -+ SPFI_TRANSACTION_CMD_SHIFT; -+ transact |= ((xfer->len - 1) & SPFI_TRANSACTION_ADDR_MASK) << -+ SPFI_TRANSACTION_ADDR_SHIFT; -+ spfi->complete = false; -+ } else { -+ spfi->complete = true; -+ if (is_pending) { -+ /* Keep setup from pending transfer */ -+ transact |= ((xfer->len & SPFI_TRANSACTION_TSIZE_MASK) << -+ SPFI_TRANSACTION_TSIZE_SHIFT); -+ } else { -+ transact = ((xfer->len & SPFI_TRANSACTION_TSIZE_MASK) << -+ SPFI_TRANSACTION_TSIZE_SHIFT); -+ } -+ } -+ spfi_writel(spfi, transact, SPFI_TRANSACTION); - - val = spfi_readl(spfi, SPFI_CONTROL); - val &= ~(SPFI_CONTROL_SEND_DMA | SPFI_CONTROL_GET_DMA); -- if (xfer->tx_buf) -+ /* -+ * We set up send DMA for pending transfers also, as -+ * those are always send transfers -+ */ -+ if ((xfer->tx_buf) || is_pending) - val |= SPFI_CONTROL_SEND_DMA; -- if (xfer->rx_buf) -+ if (xfer->tx_buf) -+ val |= SPFI_CONTROL_TX_RX; -+ if (xfer->rx_buf) { - val |= SPFI_CONTROL_GET_DMA; -+ val &= ~SPFI_CONTROL_TX_RX; -+ } - val &= ~(SPFI_CONTROL_TMODE_MASK << SPFI_CONTROL_TMODE_SHIFT); -- if (xfer->tx_nbits == SPI_NBITS_DUAL && -+ if (xfer->tx_nbits == SPI_NBITS_DUAL || - xfer->rx_nbits == SPI_NBITS_DUAL) - val |= SPFI_CONTROL_TMODE_DUAL << SPFI_CONTROL_TMODE_SHIFT; -- else if (xfer->tx_nbits == SPI_NBITS_QUAD && -+ else if (xfer->tx_nbits == SPI_NBITS_QUAD || - xfer->rx_nbits == SPI_NBITS_QUAD) - val |= SPFI_CONTROL_TMODE_QUAD << SPFI_CONTROL_TMODE_SHIFT; - val |= SPFI_CONTROL_SE; diff --git a/target/linux/pistachio/patches-6.1/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch b/target/linux/pistachio/patches-6.1/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch deleted file mode 100644 index 2995b7dd88c569..00000000000000 --- a/target/linux/pistachio/patches-6.1/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 905ee06a9966113fe51d6bad1819759cb30fd0bd Mon Sep 17 00:00:00 2001 -From: Ionela Voinescu -Date: Tue, 9 Feb 2016 10:18:31 +0000 -Subject: spi: img-spfi: use device 0 configuration for all devices - -Given that we control the chip select line externally -we can use only one parameter register (device 0 parameter -register) and one set of configuration bits (port configuration -bits for device 0) for all devices (all chip select lines). - -Signed-off-by: Ionela Voinescu ---- - drivers/spi/spi-img-spfi.c | 23 ++++++++++++++++------- - 1 file changed, 16 insertions(+), 7 deletions(-) - ---- a/drivers/spi/spi-img-spfi.c -+++ b/drivers/spi/spi-img-spfi.c -@@ -429,18 +429,23 @@ static int img_spfi_prepare(struct spi_m - struct img_spfi *spfi = spi_master_get_devdata(master); - u32 val; - -+ /* -+ * The chip select line is controlled externally so -+ * we can use the CS0 configuration for all devices -+ */ - val = spfi_readl(spfi, SPFI_PORT_STATE); -+ -+ /* 0 for device selection */ - val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK << - SPFI_PORT_STATE_DEV_SEL_SHIFT); -- val |= msg->spi->chip_select << SPFI_PORT_STATE_DEV_SEL_SHIFT; - if (msg->spi->mode & SPI_CPHA) -- val |= SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select); -+ val |= SPFI_PORT_STATE_CK_PHASE(0); - else -- val &= ~SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select); -+ val &= ~SPFI_PORT_STATE_CK_PHASE(0); - if (msg->spi->mode & SPI_CPOL) -- val |= SPFI_PORT_STATE_CK_POL(msg->spi->chip_select); -+ val |= SPFI_PORT_STATE_CK_POL(0); - else -- val &= ~SPFI_PORT_STATE_CK_POL(msg->spi->chip_select); -+ val &= ~SPFI_PORT_STATE_CK_POL(0); - spfi_writel(spfi, val, SPFI_PORT_STATE); - - return 0; -@@ -492,11 +497,15 @@ static void img_spfi_config(struct spi_m - div = DIV_ROUND_UP(clk_get_rate(spfi->spfi_clk), xfer->speed_hz); - div = clamp(512 / (1 << get_count_order(div)), 1, 128); - -- val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(spi->chip_select)); -+ /* -+ * The chip select line is controlled externally so -+ * we can use the CS0 parameters for all devices -+ */ -+ val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(0)); - val &= ~(SPFI_DEVICE_PARAMETER_BITCLK_MASK << - SPFI_DEVICE_PARAMETER_BITCLK_SHIFT); - val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT; -- spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select)); -+ spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(0)); - - if (!list_is_last(&xfer->transfer_list, &master->cur_msg->transfers) && - /* diff --git a/target/linux/pistachio/patches-6.1/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch b/target/linux/pistachio/patches-6.1/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch deleted file mode 100644 index 54185038162116..00000000000000 --- a/target/linux/pistachio/patches-6.1/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 56466f505f58f44b69feb7eaed3b506842800456 Mon Sep 17 00:00:00 2001 -From: Ionela Voinescu -Date: Tue, 1 Mar 2016 17:49:45 +0000 -Subject: spi: img-spfi: RX maximum burst size for DMA is 8 - -The depth of the FIFOs is 16 bytes. The DMA request line is tied -to the half full/empty (depending on the use of the TX or RX FIFO) -threshold. For the TX FIFO, if you set a burst size of 8 (equal to -half the depth) the first burst goes into FIFO without any issues, -but due the latency involved (the time the data leaves the DMA -engine to the time it arrives at the FIFO), the DMA might trigger -another burst of 8. But given that there is no space for 2 additonal -bursts of 8, this would result in a failure. Therefore, we have to -keep the burst size for TX to 4 to accomodate for an extra burst. - -For the read (RX) scenario, the DMA request line goes high when -there is at least 8 entries in the FIFO (half full), and we can -program the burst size to be 8 because the risk of accidental burst -does not exist. The DMA engine will not trigger another read until -the read data for all the burst it has sent out has been received. - -While here, move the burst size setting outside of the if/else branches -as they have the same value for both 8 and 32 bit data widths. - -Signed-off-by: Ionela Voinescu ---- - drivers/spi/spi-img-spfi.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/drivers/spi/spi-img-spfi.c -+++ b/drivers/spi/spi-img-spfi.c -@@ -338,12 +338,11 @@ static int img_spfi_start_dma(struct spi - if (xfer->len % 4 == 0) { - rxconf.src_addr = spfi->phys + SPFI_RX_32BIT_VALID_DATA; - rxconf.src_addr_width = 4; -- rxconf.src_maxburst = 4; - } else { - rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA; - rxconf.src_addr_width = 1; -- rxconf.src_maxburst = 4; - } -+ rxconf.src_maxburst = 8; - dmaengine_slave_config(spfi->rx_ch, &rxconf); - - rxdesc = dmaengine_prep_slave_sg(spfi->rx_ch, xfer->rx_sg.sgl, -@@ -362,12 +361,11 @@ static int img_spfi_start_dma(struct spi - if (xfer->len % 4 == 0) { - txconf.dst_addr = spfi->phys + SPFI_TX_32BIT_VALID_DATA; - txconf.dst_addr_width = 4; -- txconf.dst_maxburst = 4; - } else { - txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA; - txconf.dst_addr_width = 1; -- txconf.dst_maxburst = 4; - } -+ txconf.dst_maxburst = 4; - dmaengine_slave_config(spfi->tx_ch, &txconf); - - txdesc = dmaengine_prep_slave_sg(spfi->tx_ch, xfer->tx_sg.sgl, diff --git a/target/linux/pistachio/patches-6.1/106-spi-img-spfi-finish-every-transfer-cleanly.patch b/target/linux/pistachio/patches-6.1/106-spi-img-spfi-finish-every-transfer-cleanly.patch deleted file mode 100644 index ea1f9f28cc7361..00000000000000 --- a/target/linux/pistachio/patches-6.1/106-spi-img-spfi-finish-every-transfer-cleanly.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 5fcca3fd4b621d7b5bdeca18d36dfc6ca6cfe383 Mon Sep 17 00:00:00 2001 -From: Ionela Voinescu -Date: Wed, 10 Aug 2016 11:42:26 +0100 -Subject: spi: img-spfi: finish every transfer cleanly - -Before this change, the interrupt status bit that signaled -the end of a tranfers was cleared in the wait_all_done -function. That functionality triggered issues for DMA -duplex transactions where the wait function was called -twice, in both the TX and RX callbacks. - -In order to fix the issue, clear all interrupt data bits -at the end of a PIO transfer or at the end of both TX and RX -duplex transfers, if the transfer is not a pending tranfer -(command waiting for data). After that, the status register -is checked for new incoming data or new data requests to be -signaled. If SPFI finished cleanly, no new interrupt data -bits should be set. - -Signed-off-by: Ionela Voinescu ---- - drivers/spi/spi-img-spfi.c | 49 +++++++++++++++++++++++++++++++++------------- - 1 file changed, 35 insertions(+), 14 deletions(-) - ---- a/drivers/spi/spi-img-spfi.c -+++ b/drivers/spi/spi-img-spfi.c -@@ -79,6 +79,14 @@ - #define SPFI_INTERRUPT_SDE BIT(1) - #define SPFI_INTERRUPT_SDTRIG BIT(0) - -+#define SPFI_INTERRUPT_DATA_BITS (SPFI_INTERRUPT_SDHF |\ -+ SPFI_INTERRUPT_SDFUL |\ -+ SPFI_INTERRUPT_GDEX32BIT |\ -+ SPFI_INTERRUPT_GDHF |\ -+ SPFI_INTERRUPT_GDFUL |\ -+ SPFI_INTERRUPT_ALLDONETRIG |\ -+ SPFI_INTERRUPT_GDEX8BIT) -+ - /* - * There are four parallel FIFOs of 16 bytes each. The word buffer - * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an -@@ -136,6 +144,23 @@ static inline void spfi_reset(struct img - spfi_writel(spfi, 0, SPFI_CONTROL); - } - -+static inline void spfi_finish(struct img_spfi *spfi) -+{ -+ if (!(spfi->complete)) -+ return; -+ -+ /* Clear data bits as all transfers(TX and RX) have finished */ -+ spfi_writel(spfi, SPFI_INTERRUPT_DATA_BITS, SPFI_INTERRUPT_CLEAR); -+ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & SPFI_INTERRUPT_DATA_BITS) { -+ dev_err(spfi->dev, "SPFI did not finish transfer cleanly.\n"); -+ spfi_reset(spfi); -+ } -+ /* Disable SPFI for it not to interfere with pending transactions */ -+ spfi_writel(spfi, -+ spfi_readl(spfi, SPFI_CONTROL) & ~SPFI_CONTROL_SPFI_EN, -+ SPFI_CONTROL); -+} -+ - static int spfi_wait_all_done(struct img_spfi *spfi) - { - unsigned long timeout = jiffies + msecs_to_jiffies(50); -@@ -144,19 +169,9 @@ static int spfi_wait_all_done(struct img - return 0; - - while (time_before(jiffies, timeout)) { -- u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); -- -- if (status & SPFI_INTERRUPT_ALLDONETRIG) { -- spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG, -- SPFI_INTERRUPT_CLEAR); -- /* -- * Disable SPFI for it not to interfere with -- * pending transactions -- */ -- spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL) -- & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL); -+ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & -+ SPFI_INTERRUPT_ALLDONETRIG) - return 0; -- } - cpu_relax(); - } - -@@ -288,6 +303,8 @@ static int img_spfi_start_pio(struct spi - } - - ret = spfi_wait_all_done(spfi); -+ spfi_finish(spfi); -+ - if (ret < 0) - return ret; - -@@ -303,8 +320,10 @@ static void img_spfi_dma_rx_cb(void *dat - - spin_lock_irqsave(&spfi->lock, flags); - spfi->rx_dma_busy = false; -- if (!spfi->tx_dma_busy) -+ if (!spfi->tx_dma_busy) { -+ spfi_finish(spfi); - spi_finalize_current_transfer(spfi->master); -+ } - spin_unlock_irqrestore(&spfi->lock, flags); - } - -@@ -317,8 +336,10 @@ static void img_spfi_dma_tx_cb(void *dat - - spin_lock_irqsave(&spfi->lock, flags); - spfi->tx_dma_busy = false; -- if (!spfi->rx_dma_busy) -+ if (!spfi->rx_dma_busy) { -+ spfi_finish(spfi); - spi_finalize_current_transfer(spfi->master); -+ } - spin_unlock_irqrestore(&spfi->lock, flags); - } - diff --git a/target/linux/pistachio/patches-6.1/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch b/target/linux/pistachio/patches-6.1/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch deleted file mode 100644 index 6fddbe269afc6a..00000000000000 --- a/target/linux/pistachio/patches-6.1/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 3642843a06025ec333d7e92580cf52cb8db2a652 Mon Sep 17 00:00:00 2001 -From: Govindraj Raja -Date: Fri, 8 Jan 2016 16:36:07 +0000 -Subject: clk: pistachio: Fix wrong SDHost card speed - -The SDHost currently clocks the card 4x slower than it -should do, because there is fixed divide by 4 in the -sdhost wrapper that is not present in the clock tree. -To model this add a fixed divide by 4 clock node in -the SDHost clock path. - -This will ensure the right clock frequency is selected when -the mmc driver tries to configure frequency on card insert. - -Signed-off-by: Govindraj Raja ---- - drivers/clk/pistachio/clk-pistachio.c | 3 ++- - include/dt-bindings/clock/pistachio-clk.h | 1 + - 2 files changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/clk/pistachio/clk-pistachio.c -+++ b/drivers/clk/pistachio/clk-pistachio.c -@@ -41,7 +41,7 @@ static struct pistachio_gate pistachio_g - GATE(CLK_AUX_ADC_INTERNAL, "aux_adc_internal", "sys_internal_div", - 0x104, 22), - GATE(CLK_AUX_ADC, "aux_adc", "aux_adc_div", 0x104, 23), -- GATE(CLK_SD_HOST, "sd_host", "sd_host_div", 0x104, 24), -+ GATE(CLK_SD_HOST, "sd_host", "sd_host_div4", 0x104, 24), - GATE(CLK_BT, "bt", "bt_div", 0x104, 25), - GATE(CLK_BT_DIV4, "bt_div4", "bt_div4_div", 0x104, 26), - GATE(CLK_BT_DIV8, "bt_div8", "bt_div8_div", 0x104, 27), -@@ -51,6 +51,7 @@ static struct pistachio_gate pistachio_g - static struct pistachio_fixed_factor pistachio_ffs[] __initdata = { - FIXED_FACTOR(CLK_WIFI_DIV4, "wifi_div4", "wifi_pll", 4), - FIXED_FACTOR(CLK_WIFI_DIV8, "wifi_div8", "wifi_pll", 8), -+ FIXED_FACTOR(CLK_SDHOST_DIV4, "sd_host_div4", "sd_host_div", 4), - }; - - static struct pistachio_div pistachio_divs[] __initdata = { ---- a/include/dt-bindings/clock/pistachio-clk.h -+++ b/include/dt-bindings/clock/pistachio-clk.h -@@ -18,6 +18,7 @@ - /* Fixed-factor clocks */ - #define CLK_WIFI_DIV4 16 - #define CLK_WIFI_DIV8 17 -+#define CLK_SDHOST_DIV4 18 - - /* Gate clocks */ - #define CLK_MIPS 32 diff --git a/target/linux/pistachio/patches-6.1/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch b/target/linux/pistachio/patches-6.1/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch deleted file mode 100644 index faba23c5f1bf46..00000000000000 --- a/target/linux/pistachio/patches-6.1/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 981c1d416af45eff207227aec106381ac23aac99 Mon Sep 17 00:00:00 2001 -From: Ian Pozella -Date: Mon, 20 Feb 2017 10:00:52 +0000 -Subject: MIPS: DTS: img: marduk: switch mmc to 1 bit mode - -The mmc block in Pistachio allows 1 to 8 data bits to be used. -Marduk uses 4 bits allowing the upper 4 bits to be allocated -to the Mikrobus ports. However these bits are still connected -internally meaning the mmc block recieves signals on all data lines -and seems the internal HW CRC checks get corrupted by this erroneous -data. - -We cannot control what data is sent on these lines because they go -to external ports. 1 bit mode does not exhibit the issue hence the -safe default is to use this. If a user knows that in their use case -they will not use the upper bits then they can set to 4 bit mode in -order to improve performance. - -Also make sure that the upper 4 bits don't get allocated to the mmc -driver (the default is to assign all 8 pins) so they can be allocated -to other drivers. Allocating all 4 despite setting 1 bit mode as this -matches what is there in hardware. - -Signed-off-by: Ian Pozella ---- - arch/mips/boot/dts/img/pistachio_marduk.dts | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/arch/mips/boot/dts/img/pistachio_marduk.dts -+++ b/arch/mips/boot/dts/img/pistachio_marduk.dts -@@ -118,7 +118,7 @@ - - &sdhost { - status = "okay"; -- bus-width = <4>; -+ bus-width = <1>; - disable-wp; - }; - -@@ -128,6 +128,7 @@ - - &pin_sdhost_data { - drive-strength = <2>; -+ pins = "mfio17", "mfio18", "mfio19", "mfio20"; - }; - - &pwm { diff --git a/target/linux/pistachio/patches-6.1/401-mtd-nor-support-mtd-name-from-device-tree.patch b/target/linux/pistachio/patches-6.1/401-mtd-nor-support-mtd-name-from-device-tree.patch deleted file mode 100644 index a8ebab9cd230d3..00000000000000 --- a/target/linux/pistachio/patches-6.1/401-mtd-nor-support-mtd-name-from-device-tree.patch +++ /dev/null @@ -1,53 +0,0 @@ -From f32bc2aa01edcba2f2ed5db151cf183eac9ef919 Mon Sep 17 00:00:00 2001 -From: Abhimanyu Vishwakarma -Date: Sat, 25 Feb 2017 16:42:50 +0000 -Subject: mtd: nor: support mtd name from device tree - -Signed-off-by: Abhimanyu Vishwakarma ---- - drivers/mtd/spi-nor/spi-nor.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -2964,12 +2964,20 @@ static void spi_nor_set_mtd_info(struct - { - struct mtd_info *mtd = &nor->mtd; - struct device *dev = nor->dev; -+ struct device_node *np = spi_nor_get_flash_node(nor); -+ const char __maybe_unused *of_mtd_name = NULL; - - spi_nor_set_mtd_locking_ops(nor); - spi_nor_set_mtd_otp_ops(nor); - - mtd->dev.parent = dev; - if (!mtd->name) -+#ifdef CONFIG_MTD_OF_PARTS -+ of_property_read_string(np, "linux,mtd-name", &of_mtd_name); -+#endif -+ if (of_mtd_name) -+ mtd->name = of_mtd_name; -+ else if (!mtd->name) - mtd->name = dev_name(dev); - mtd->type = MTD_NORFLASH; - mtd->flags = MTD_CAP_NORFLASH; ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -863,6 +863,17 @@ out_error: - */ - static void mtd_set_dev_defaults(struct mtd_info *mtd) - { -+#ifdef CONFIG_MTD_OF_PARTS -+ const char __maybe_unused *of_mtd_name = NULL; -+ struct device_node *np; -+ -+ np = mtd_get_of_node(mtd); -+ if (np && !mtd->name) { -+ of_property_read_string(np, "linux,mtd-name", &of_mtd_name); -+ if (of_mtd_name) -+ mtd->name = of_mtd_name; -+ } else -+#endif - if (mtd->dev.parent) { - if (!mtd->owner && mtd->dev.parent->driver) - mtd->owner = mtd->dev.parent->driver->owner; diff --git a/target/linux/pistachio/patches-6.1/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch b/target/linux/pistachio/patches-6.1/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch deleted file mode 100644 index 4b28f4683333c7..00000000000000 --- a/target/linux/pistachio/patches-6.1/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0023c706f7e0f0f02bd48a63a2f3c04c839532ae Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Sat, 15 Aug 2020 16:04:53 +0200 -Subject: [PATCH 901/904] MIPS: DTS: img: marduk: Add SPI NAND flash - -Add Gigadevice GD5F4GQ4UCYIGT SPI NAND flash to the device tree. - -The NAND flash chip is connected with quad SPI, but reading currently -fails in quad SPI mode. - -Signed-off-by: Hauke Mehrtens ---- - arch/mips/boot/dts/img/pistachio_marduk.dts | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/arch/mips/boot/dts/img/pistachio_marduk.dts -+++ b/arch/mips/boot/dts/img/pistachio_marduk.dts -@@ -89,6 +89,12 @@ - reg = <0>; - spi-max-frequency = <50000000>; - }; -+ -+ flash@1 { -+ compatible = "spi-nand"; -+ reg = <1>; -+ spi-max-frequency = <50000000>; -+ }; - }; - - &uart0 { diff --git a/target/linux/pistachio/patches-6.1/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch b/target/linux/pistachio/patches-6.1/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch deleted file mode 100644 index d4c4ccac53d50e..00000000000000 --- a/target/linux/pistachio/patches-6.1/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch +++ /dev/null @@ -1,43 +0,0 @@ -From b7700154d75e8d7c9a2022f09c2d5430137606fa Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Sat, 15 Aug 2020 16:05:25 +0200 -Subject: [PATCH 902/904] MIPS: DTS: img: marduk: Add Cascoda CA8210 6LoWPAN - -Add Cascoda CA8210 6LoWPAN controller to device tree. - -Signed-off-by: Hauke Mehrtens ---- - arch/mips/boot/dts/img/pistachio_marduk.dts | 22 +++++++++++++++++++++ - 1 file changed, 22 insertions(+) - ---- a/arch/mips/boot/dts/img/pistachio_marduk.dts -+++ b/arch/mips/boot/dts/img/pistachio_marduk.dts -@@ -76,6 +76,28 @@ - VDD-supply = <&internal_dac_supply>; - }; - -+&spfi0 { -+ status = "okay"; -+ pinctrl-0 = <&spim0_pins>, <&spim0_cs0_alt_pin>, <&spim0_cs2_alt_pin>, <&spim0_cs3_alt_pin>, <&spim0_cs4_alt_pin>; -+ pinctrl-names = "default"; -+ -+ cs-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>, <&gpio0 2 GPIO_ACTIVE_HIGH>, -+ <&gpio1 12 GPIO_ACTIVE_HIGH>, <&gpio1 13 GPIO_ACTIVE_HIGH>; -+ -+ ca8210: ca8210@0 { -+ status = "okay"; -+ compatible = "cascoda,ca8210"; -+ reg = <0>; -+ spi-max-frequency = <4000000>; -+ spi-cpol; -+ reset-gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; -+ irq-gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>; -+ extclock-enable; -+ extclock-freq = <16000000>; -+ extclock-gpio = <2>; -+ }; -+}; -+ - &spfi1 { - status = "okay"; - diff --git a/target/linux/pistachio/patches-6.1/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch b/target/linux/pistachio/patches-6.1/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch deleted file mode 100644 index b1070c3d309eac..00000000000000 --- a/target/linux/pistachio/patches-6.1/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch +++ /dev/null @@ -1,81 +0,0 @@ -From ad4eba0c36ce8af6ab9ea1bc163e4c1ac7c271c3 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Sat, 15 Aug 2020 16:09:02 +0200 -Subject: [PATCH 903/904] MIPS: DTS: img: marduk: Add NXP SC16IS752IPW - -Add NXP SC16IS752IPW SPI-UART controller to device tree. - -This controller drives 2 UARTs and 7 LEDs on the board. - -Signed-off-by: Hauke Mehrtens ---- - arch/mips/boot/dts/img/pistachio_marduk.dts | 51 +++++++++++++++++++++ - 1 file changed, 51 insertions(+) - ---- a/arch/mips/boot/dts/img/pistachio_marduk.dts -+++ b/arch/mips/boot/dts/img/pistachio_marduk.dts -@@ -46,6 +46,46 @@ - regulator-max-microvolt = <1800000>; - }; - -+ /* EXT clock from ca8210 is fed to sc16is752 */ -+ ca8210_ext_clk: ca8210-ext-clk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <16000000>; -+ clock-output-names = "ca8210_ext_clock"; -+ }; -+ -+ gpioleds { -+ compatible = "gpio-leds"; -+ user1 { -+ label = "marduk:red:user1"; -+ gpios = <&sc16is752 0 GPIO_ACTIVE_LOW>; -+ }; -+ user2 { -+ label = "marduk:red:user2"; -+ gpios = <&sc16is752 1 GPIO_ACTIVE_LOW>; -+ }; -+ user3 { -+ label = "marduk:red:user3"; -+ gpios = <&sc16is752 2 GPIO_ACTIVE_LOW>; -+ }; -+ user4 { -+ label = "marduk:red:user4"; -+ gpios = <&sc16is752 3 GPIO_ACTIVE_LOW>; -+ }; -+ user5 { -+ label = "marduk:red:user5"; -+ gpios = <&sc16is752 4 GPIO_ACTIVE_LOW>; -+ }; -+ user6 { -+ label = "marduk:red:user6"; -+ gpios = <&sc16is752 5 GPIO_ACTIVE_LOW>; -+ }; -+ user7 { -+ label = "marduk:red:user7"; -+ gpios = <&sc16is752 6 GPIO_ACTIVE_LOW>; -+ }; -+ }; -+ - led-controller { - compatible = "pwm-leds"; - -@@ -96,6 +136,17 @@ - extclock-freq = <16000000>; - extclock-gpio = <2>; - }; -+ -+ sc16is752: sc16is752@1 { -+ compatible = "nxp,sc16is752"; -+ reg = <1>; -+ clocks = <&ca8210_ext_clk>; -+ spi-max-frequency = <4000000>; -+ interrupt-parent = <&gpio0>; -+ interrupts = <11 IRQ_TYPE_EDGE_FALLING>; -+ gpio-controller; -+ #gpio-cells = <2>; -+ }; - }; - - &spfi1 { diff --git a/target/linux/pistachio/patches-6.1/904-MIPS-DTS-img-marduk-Add-partition-name.patch b/target/linux/pistachio/patches-6.1/904-MIPS-DTS-img-marduk-Add-partition-name.patch deleted file mode 100644 index 490027a7021f0b..00000000000000 --- a/target/linux/pistachio/patches-6.1/904-MIPS-DTS-img-marduk-Add-partition-name.patch +++ /dev/null @@ -1,27 +0,0 @@ -From ff0e950b605047bf50d470023e0fb2fc2003a0f0 Mon Sep 17 00:00:00 2001 -From: Ian Pozella -Date: Mon, 20 Feb 2017 10:38:07 +0000 -Subject: [PATCH 904/904] MIPS: DTS: img: marduk: Add partition name - -Signed-off-by: Ian Pozella ---- - arch/mips/boot/dts/img/pistachio_marduk.dts | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/mips/boot/dts/img/pistachio_marduk.dts -+++ b/arch/mips/boot/dts/img/pistachio_marduk.dts -@@ -161,12 +161,14 @@ - compatible = "spansion,s25fl016k", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <50000000>; -+ linux,mtd-name = "spi-nor"; - }; - - flash@1 { - compatible = "spi-nand"; - reg = <1>; - spi-max-frequency = <50000000>; -+ linux,mtd-name = "spi-nand"; - }; - }; - diff --git a/target/linux/pistachio/patches-6.1/905-MIPS-DTS-img-marduk-Add-led-aliases.patch b/target/linux/pistachio/patches-6.1/905-MIPS-DTS-img-marduk-Add-led-aliases.patch deleted file mode 100644 index 8c03ddeea277d3..00000000000000 --- a/target/linux/pistachio/patches-6.1/905-MIPS-DTS-img-marduk-Add-led-aliases.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/arch/mips/boot/dts/img/pistachio_marduk.dts -+++ b/arch/mips/boot/dts/img/pistachio_marduk.dts -@@ -19,6 +19,11 @@ - ethernet0 = &enet; - spi0 = &spfi0; - spi1 = &spfi1; -+ -+ led-boot = &led_heartbeat; -+ led-failsafe = &led_heartbeat; -+ led-running = &led_heartbeat; -+ led-upgrade = &led_heartbeat; - }; - - chosen { -@@ -89,11 +94,10 @@ - led-controller { - compatible = "pwm-leds"; - -- led-1 { -+ led_heartbeat: heartbeat { - label = "marduk:red:heartbeat"; - pwms = <&pwm 3 300000>; - max-brightness = <255>; -- linux,default-trigger = "heartbeat"; - }; - }; - From b56f66464d9e17b202fc192d23ac44d59138bb10 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 20 Sep 2024 18:46:18 +0100 Subject: [PATCH 14/23] layerscape: remove left-over config-6.1 files Remove left-over config-6.1 files which should have been removed when removing kernel 6.1 support. Fixes: f20987c161 ("layerscape: remove kernel 6.1 support") Signed-off-by: Daniel Golle --- target/linux/layerscape/armv7/config-6.1 | 695 -------------- target/linux/layerscape/armv8_64b/config-6.1 | 894 ------------------- 2 files changed, 1589 deletions(-) delete mode 100644 target/linux/layerscape/armv7/config-6.1 delete mode 100644 target/linux/layerscape/armv8_64b/config-6.1 diff --git a/target/linux/layerscape/armv7/config-6.1 b/target/linux/layerscape/armv7/config-6.1 deleted file mode 100644 index 6606d53e95974a..00000000000000 --- a/target/linux/layerscape/armv7/config-6.1 +++ /dev/null @@ -1,695 +0,0 @@ -CONFIG_AD525X_DPOT=y -CONFIG_AD525X_DPOT_I2C=y -# CONFIG_AD525X_DPOT_SPI is not set -CONFIG_ALIGNMENT_TRAP=y -CONFIG_APDS9802ALS=y -CONFIG_AQUANTIA_PHY=y -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_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_MXC=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM=y -CONFIG_ARM_APPENDED_DTB=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ATAG_DTB_COMPAT=y -CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -CONFIG_ARM_CPUIDLE=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_ERRATA_430973=y -CONFIG_ARM_ERRATA_643719=y -CONFIG_ARM_ERRATA_720789=y -CONFIG_ARM_ERRATA_754322=y -CONFIG_ARM_ERRATA_754327=y -CONFIG_ARM_ERRATA_764369=y -CONFIG_ARM_ERRATA_775420=y -CONFIG_ARM_ERRATA_798181=y -CONFIG_ARM_GIC=y -CONFIG_ARM_HAS_GROUP_RELOCS=y -CONFIG_ARM_HEAVY_MB=y -# CONFIG_ARM_HIGHBANK_CPUIDLE is not set -# CONFIG_ARM_IMX8M_DDRC_DEVFREQ is not set -# CONFIG_ARM_IMX_BUS_DEVFREQ is not set -# CONFIG_ARM_IMX_CPUFREQ_DT is not set -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_LPAE=y -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_ARM_PSCI=y -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_SMMU is not set -CONFIG_ARM_THUMB=y -CONFIG_ARM_THUMBEE=y -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_ATAGS=y -CONFIG_AUTOFS4_FS=y -CONFIG_AUTOFS_FS=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_BATTERY_SBS=y -CONFIG_BCM_NET_PHYLIB=y -CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y -CONFIG_BLK_DEV_BSG=y -CONFIG_BLK_DEV_BSG_COMMON=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=262144 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_MQ_VIRTIO=y -CONFIG_BLK_PM=y -CONFIG_BOUNCE=y -CONFIG_BRCMSTB_GISB_ARB=y -CONFIG_BROADCOM_PHY=y -CONFIG_CACHE_L2X0=y -CONFIG_CC_HAVE_STACKPROTECTOR_TLS=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y -CONFIG_CDROM=y -CONFIG_CHECKPOINT_RESTORE=y -CONFIG_CHR_DEV_SG=y -CONFIG_CLKSRC_IMX_GPT=y -CONFIG_CLKSRC_MMIO=y -# CONFIG_CLK_IMX8MM is not set -# CONFIG_CLK_IMX8MN is not set -# CONFIG_CLK_IMX8MP is not set -# CONFIG_CLK_IMX8MQ is not set -# CONFIG_CLK_IMX8ULP is not set -# CONFIG_CLK_IMX93 is not set -CONFIG_CLK_QORIQ=y -# CONFIG_CLK_VEXPRESS_OSC is not set -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=64 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -# CONFIG_CMA_SYSFS is not set -CONFIG_CMDLINE_PARTITION=y -CONFIG_COMMON_CLK=y -CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_CONTEXT_TRACKING=y -CONFIG_CONTEXT_TRACKING_IDLE=y -CONFIG_CONTIG_ALLOC=y -CONFIG_COREDUMP=y -CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_SPECTRE=y -CONFIG_CPU_THERMAL=y -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRASH_CORE=y -CONFIG_CRC16=y -# CONFIG_CRC32_SARWATE is not set -CONFIG_CRC32_SLICEBY8=y -CONFIG_CROSS_MEMORY_ATTACH=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_SHA1=y -CONFIG_CRYPTO_LIB_UTILS=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_ZSTD=y -CONFIG_CURRENT_POINTER_IN_TPIDRURO=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -CONFIG_DECOMPRESS_BZIP2=y -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_LZMA=y -CONFIG_DECOMPRESS_LZO=y -CONFIG_DECOMPRESS_XZ=y -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_DEVFREQ_GOV_PASSIVE is not set -# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set -# CONFIG_DEVFREQ_GOV_POWERSAVE is not set -# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set -# CONFIG_DEVFREQ_GOV_USERSPACE is not set -# CONFIG_DEVFREQ_THERMAL is not set -CONFIG_DMADEVICES=y -CONFIG_DMA_CMA=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_OPS=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DNOTIFY=y -CONFIG_DTC=y -CONFIG_DT_IDLE_STATES=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_DW_DMAC=y -CONFIG_DW_DMAC_CORE=y -CONFIG_DW_WATCHDOG=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EEPROM_93CX6=y -CONFIG_EEPROM_AT24=y -CONFIG_ELF_CORE=y -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -CONFIG_EXCLUSIVE_SYSTEM_RAM=y -CONFIG_EXT4_FS=y -CONFIG_F2FS_FS=y -CONFIG_FAILOVER=y -CONFIG_FAT_FS=y -# CONFIG_FEC is not set -CONFIG_FHANDLE=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FREEZER=y -# CONFIG_FSL_DPAA2_SWITCH is not set -CONFIG_FSL_EDMA=y -CONFIG_FSL_GUTS=y -CONFIG_FSL_IFC=y -# CONFIG_FSL_PPFE is not set -CONFIG_FSL_PQ_MDIO=y -CONFIG_FSL_RCPM=y -CONFIG_FSL_XGMAC_MDIO=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FTRACE=y -# CONFIG_FTRACE_SYSCALLS is not set -CONFIG_FUSE_FS=y -CONFIG_FWNODE_MDIO=y -CONFIG_FW_CACHE=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_FW_LOADER_SYSFS=y -# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -CONFIG_GCC11_NO_ARRAY_BOUNDS=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_VDSO_32=y -CONFIG_GIANFAR=y -CONFIG_GLOB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_GENERIC_PLATFORM=y -CONFIG_GPIO_MPC8XXX=y -CONFIG_GPIO_MXC=y -CONFIG_GPIO_VF610=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAVE_SMP=y -CONFIG_HID=y -CONFIG_HID_GENERIC=y -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -# CONFIG_HIST_TRIGGERS is not set -CONFIG_HOTPLUG_CPU=y -CONFIG_HVC_DRIVER=y -CONFIG_HW_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_HZ_FIXED=0 -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_DEMUX_PINCTRL=y -CONFIG_I2C_DESIGNWARE_CORE=y -CONFIG_I2C_DESIGNWARE_PLATFORM=y -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_IMX=y -# CONFIG_I2C_IMX_LPI2C is not set -CONFIG_I2C_MUX=y -CONFIG_I2C_MUX_PCA954x=y -CONFIG_I2C_MUX_PINCTRL=y -CONFIG_I2C_RK3X=y -CONFIG_I2C_SLAVE=y -CONFIG_I2C_SLAVE_EEPROM=y -# CONFIG_I2C_SLAVE_TESTUNIT is not set -CONFIG_I2C_XILINX=y -CONFIG_ICPLUS_PHY=y -CONFIG_ICS932S401=y -CONFIG_IMX2_WDT=y -# CONFIG_IMX7ULP_WDT is not set -# CONFIG_IMX8MM_THERMAL is not set -CONFIG_IMX_DMA=y -# CONFIG_IMX_GPCV2_PM_DOMAINS is not set -CONFIG_IMX_INTMUX=y -# CONFIG_IMX_IRQSTEER is not set -# CONFIG_IMX_MU_MSI is not set -CONFIG_IMX_SDMA=y -# CONFIG_IMX_WEIM is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_INPUT=y -# CONFIG_IOMMU_DEBUGFS is not set -# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set -# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set -CONFIG_IOMMU_SUPPORT=y -CONFIG_IPC_NS=y -CONFIG_IRQCHIP=y -CONFIG_IRQSTACKS=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -# CONFIG_ISDN is not set -CONFIG_ISL29003=y -CONFIG_JBD2=y -CONFIG_KALLSYMS=y -CONFIG_KCMP=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_XZ is not set -CONFIG_KEXEC=y -CONFIG_KEXEC_CORE=y -CONFIG_KMAP_LOCAL=y -CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY=y -CONFIG_LIBFDT=y -CONFIG_LOCALVERSION_AUTO=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LS_EXTIRQ=y -CONFIG_LS_SCFG_MSI=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MARVELL_PHY=y -CONFIG_MCPM=y -CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -# CONFIG_MDIO_GPIO is not set -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY=y -CONFIG_MEMORY_ISOLATION=y -# CONFIG_MFD_HI6421_SPMI is not set -CONFIG_MFD_SYSCON=y -# CONFIG_MFD_VEXPRESS_SYSREG is not set -CONFIG_MICREL_PHY=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=16 -# CONFIG_MMC_MXC is not set -CONFIG_MMC_SDHCI=y -# CONFIG_MMC_SDHCI_ESDHC_IMX is not set -CONFIG_MMC_SDHCI_IO_ACCESSORS=y -CONFIG_MMC_SDHCI_OF_ESDHC=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MSDOS_FS=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_DATAFLASH=y -# CONFIG_MTD_DATAFLASH_OTP is not set -# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set -CONFIG_MTD_NAND_CORE=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_ECC_SW_HAMMING=y -CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_RAW_NAND=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y -CONFIG_MTD_SST25L=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -# CONFIG_MTD_UBI_BLOCK is not set -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_MX3_IPU=y -CONFIG_MX3_IPU_IRQS=4 -CONFIG_MXC_CLK=y -# CONFIG_MXS_DMA is not set -CONFIG_NAMESPACES=y -CONFIG_NATIONAL_PHY=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEON=y -CONFIG_NET_FAILOVER=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_NS=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_SELFTESTS=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NLS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=16 -CONFIG_NTFS_FS=y -CONFIG_NVMEM=y -# CONFIG_NVMEM_IMX_IIM is not set -# CONFIG_NVMEM_IMX_OCOTP_ELE is not set -# CONFIG_NVMEM_SNVS_LPGPR is not set -# CONFIG_NVMEM_SPMI_SDAM is not set -CONFIG_NVMEM_SYSFS=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_DYNAMIC=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_SIGSUSPEND3=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -CONFIG_PACKET_DIAG=y -CONFIG_PADATA=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PAGE_POOL=y -CONFIG_PAGE_SIZE_LESS_THAN_256KB=y -CONFIG_PAGE_SIZE_LESS_THAN_64KB=y -# CONFIG_PANIC_ON_OOPS is not set -CONFIG_PANIC_ON_OOPS_VALUE=0 -CONFIG_PANIC_TIMEOUT=0 -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEASPM=y -CONFIG_PCIEASPM_DEFAULT=y -# CONFIG_PCIEASPM_PERFORMANCE is not set -# CONFIG_PCIEASPM_POWERSAVE is not set -# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_DW=y -CONFIG_PCIE_DW_HOST=y -CONFIG_PCIE_PME=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_ECAM=y -CONFIG_PCI_HOST_COMMON=y -CONFIG_PCI_HOST_GENERIC=y -# CONFIG_PCI_IMX6 is not set -CONFIG_PCI_LAYERSCAPE=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=3 -CONFIG_PHYLIB=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_PID_NS=y -CONFIG_PINCTRL=y -# CONFIG_PINCTRL_IMX8ULP is not set -# CONFIG_PINCTRL_IMX93 is not set -# CONFIG_PINCTRL_IMXRT1050 is not set -# CONFIG_PINCTRL_IMXRT1170 is not set -CONFIG_PL310_ERRATA_588369=y -CONFIG_PL310_ERRATA_727915=y -CONFIG_PL310_ERRATA_753970=y -CONFIG_PL310_ERRATA_769419=y -CONFIG_PM=y -CONFIG_PM_CLK=y -CONFIG_PM_DEVFREQ=y -# CONFIG_PM_DEVFREQ_EVENT is not set -CONFIG_PM_OPP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_BRCMKONA=y -CONFIG_POWER_RESET_BRCMSTB=y -CONFIG_POWER_RESET_GPIO=y -CONFIG_POWER_RESET_GPIO_RESTART=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_POWER_RESET_SYSCON_POWEROFF=y -CONFIG_POWER_RESET_VEXPRESS=y -CONFIG_POWER_SUPPLY=y -CONFIG_PPS=y -CONFIG_PREEMPT_NONE_BUILD=y -CONFIG_PRINTK_TIME=y -CONFIG_PROC_CHILDREN=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PSTORE=y -CONFIG_PSTORE_COMPRESS=y -CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" -CONFIG_PSTORE_CONSOLE=y -CONFIG_PSTORE_DEFLATE_COMPRESS=y -CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y -CONFIG_PSTORE_PMSG=y -CONFIG_PSTORE_RAM=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_PTP_1588_CLOCK_QORIQ=y -CONFIG_QORIQ_CPUFREQ=y -CONFIG_RANDSTRUCT_NONE=y -CONFIG_RAS=y -CONFIG_RATIONAL=y -CONFIG_RD_BZIP2=y -CONFIG_RD_GZIP=y -CONFIG_RD_LZMA=y -CONFIG_RD_LZO=y -CONFIG_RD_XZ=y -CONFIG_REALTEK_PHY=y -CONFIG_REED_SOLOMON=y -CONFIG_REED_SOLOMON_DEC8=y -CONFIG_REED_SOLOMON_ENC8=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_DRV_CMOS is not set -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS3232=y -CONFIG_RTC_DRV_EM3027=y -CONFIG_RTC_DRV_FSL_FTM_ALARM=y -# CONFIG_RTC_DRV_IMXDI is not set -# CONFIG_RTC_DRV_MXC is not set -# CONFIG_RTC_DRV_MXC_V2 is not set -CONFIG_RTC_DRV_PCF2127=y -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_SCHED_DEBUG=y -CONFIG_SCSI=y -CONFIG_SCSI_COMMON=y -CONFIG_SECCOMP=y -CONFIG_SECCOMP_FILTER=y -# CONFIG_SECURITY_DMESG_RESTRICT is not set -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_8250_DWLIB=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_CONEXANT_DIGICOLOR=y -CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y -CONFIG_SERIAL_FSL_LPUART=y -CONFIG_SERIAL_FSL_LPUART_CONSOLE=y -CONFIG_SERIAL_IMX=y -CONFIG_SERIAL_IMX_CONSOLE=y -CONFIG_SERIAL_IMX_EARLYCON=y -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SERIAL_ST_ASC=y -CONFIG_SERIAL_ST_ASC_CONSOLE=y -CONFIG_SERIAL_XILINX_PS_UART=y -CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y -CONFIG_SGL_ALLOC=y -CONFIG_SG_POOL=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_SMSC_PHY=y -CONFIG_SOCK_DIAG=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_SOC_BRCMSTB=y -CONFIG_SOC_BUS=y -# CONFIG_SOC_IMX50 is not set -# CONFIG_SOC_IMX51 is not set -# CONFIG_SOC_IMX53 is not set -# CONFIG_SOC_IMX6Q is not set -# CONFIG_SOC_IMX6SL is not set -# CONFIG_SOC_IMX6SLL is not set -# CONFIG_SOC_IMX6SX is not set -# CONFIG_SOC_IMX6UL is not set -# CONFIG_SOC_IMX7D is not set -# CONFIG_SOC_IMX7ULP is not set -# CONFIG_SOC_IMX8M is not set -# CONFIG_SOC_IMX9 is not set -CONFIG_SOC_LS1021A=y -# CONFIG_SOC_VF610 is not set -CONFIG_SOFTIRQ_ON_OWN_STACK=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -CONFIG_SPI_BITBANG=y -CONFIG_SPI_CADENCE=y -CONFIG_SPI_DYNAMIC=y -# CONFIG_SPI_FSL_LPSPI is not set -# CONFIG_SPI_FSL_QUADSPI is not set -# CONFIG_SPI_IMX is not set -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SPI_SPIDEV=y -CONFIG_SPI_XILINX=y -CONFIG_SPMI=y -# CONFIG_SPMI_HISI3670 is not set -# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set -CONFIG_SQUASHFS_DECOMP_SINGLE=y -CONFIG_SQUASHFS_FILE_CACHE=y -# CONFIG_SQUASHFS_FILE_DIRECT is not set -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_ZLIB=y -CONFIG_SRAM=y -CONFIG_SRAM_EXEC=y -CONFIG_SRCU=y -CONFIG_STACKTRACE=y -CONFIG_STAGING_BOARD=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWIOTLB=y -CONFIG_SWPHY=y -CONFIG_SWP_EMULATE=y -CONFIG_SYNC_FILE=y -CONFIG_SYSFS_SYSCALL=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -CONFIG_UBIFS_FS=y -# CONFIG_UCLAMP_TASK is not set -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_UNIX_DIAG=y -CONFIG_UNWINDER_ARM=y -CONFIG_USB_SUPPORT=y -CONFIG_USER_NS=y -CONFIG_USE_OF=y -CONFIG_UTS_NS=y -CONFIG_VEXPRESS_CONFIG=y -CONFIG_VFAT_FS=y -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_VIRTIO=y -CONFIG_VIRTIO_ANCHOR=y -CONFIG_VIRTIO_BLK=y -CONFIG_VIRTIO_CONSOLE=y -CONFIG_VIRTIO_MMIO=y -CONFIG_VIRTIO_NET=y -CONFIG_VIRTIO_PCI=y -CONFIG_VIRTIO_PCI_LEGACY=y -CONFIG_VIRTIO_PCI_LIB=y -CONFIG_VIRTIO_PCI_LIB_LEGACY=y -CONFIG_VITESSE_PHY=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_XILINX_WATCHDOG=y -CONFIG_XPS=y -CONFIG_XXHASH=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_ARMTHUMB=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_XZ_DEC_IA64=y -CONFIG_XZ_DEC_POWERPC=y -CONFIG_XZ_DEC_SPARC=y -CONFIG_XZ_DEC_X86=y -CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_ZBOOT_ROM_TEXT=0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZSTD_COMMON=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/layerscape/armv8_64b/config-6.1 b/target/linux/layerscape/armv8_64b/config-6.1 deleted file mode 100644 index d0b71a91f1bbaf..00000000000000 --- a/target/linux/layerscape/armv8_64b/config-6.1 +++ /dev/null @@ -1,894 +0,0 @@ -CONFIG_64BIT=y -CONFIG_AQUANTIA_PHY=y -CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y -CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_HIBERNATION_HEADER=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_LAYERSCAPE=y -CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y -CONFIG_ARCH_MMAP_RND_BITS=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=33 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_NXP=y -CONFIG_ARCH_PROC_KCORE_TEXT=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_STACKWALK=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_WANTS_NO_INSTR=y -CONFIG_ARCH_WANTS_THP_SWAP=y -CONFIG_ARM64=y -CONFIG_ARM64_4K_PAGES=y -CONFIG_ARM64_ERRATUM_1165522=y -CONFIG_ARM64_ERRATUM_1286807=y -CONFIG_ARM64_ERRATUM_2051678=y -CONFIG_ARM64_ERRATUM_2054223=y -CONFIG_ARM64_ERRATUM_2067961=y -CONFIG_ARM64_ERRATUM_2077057=y -CONFIG_ARM64_ERRATUM_2658417=y -CONFIG_ARM64_ERRATUM_819472=y -CONFIG_ARM64_ERRATUM_824069=y -CONFIG_ARM64_ERRATUM_826319=y -CONFIG_ARM64_ERRATUM_827319=y -CONFIG_ARM64_ERRATUM_832075=y -CONFIG_ARM64_ERRATUM_843419=y -CONFIG_ARM64_HW_AFDBM=y -CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y -CONFIG_ARM64_PAGE_SHIFT=12 -CONFIG_ARM64_PA_BITS=48 -CONFIG_ARM64_PA_BITS_48=y -CONFIG_ARM64_PTR_AUTH=y -CONFIG_ARM64_PTR_AUTH_KERNEL=y -CONFIG_ARM64_SME=y -CONFIG_ARM64_SVE=y -CONFIG_ARM64_TAGGED_ADDR_ABI=y -CONFIG_ARM64_VA_BITS=48 -# CONFIG_ARM64_VA_BITS_39 is not set -CONFIG_ARM64_VA_BITS_48=y -CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y -CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y -CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y -CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_V2M=y -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_GIC_V3_ITS=y -CONFIG_ARM_GIC_V3_ITS_FSL_MC=y -CONFIG_ARM_GIC_V3_ITS_PCI=y -# CONFIG_ARM_PL172_MPMC is not set -CONFIG_ARM_PSCI_CPUIDLE=y -CONFIG_ARM_PSCI_FW=y -CONFIG_ARM_SMMU=y -# CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT is not set -# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set -CONFIG_ARM_SMMU_V3=y -# CONFIG_ARM_SMMU_V3_SVA is not set -CONFIG_ARM_SP805_WATCHDOG=y -CONFIG_ASM_MODVERSIONS=y -CONFIG_ASN1=y -CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y -CONFIG_ATA=y -CONFIG_AUDIT=y -CONFIG_AUDITSYSCALL=y -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -CONFIG_AUDIT_GENERIC=y -CONFIG_AUTOFS4_FS=y -CONFIG_AUTOFS_FS=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BALLOON_COMPACTION=y -CONFIG_BATTERY_BQ27XXX=y -# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set -CONFIG_BATTERY_BQ27XXX_I2C=y -CONFIG_BLK_DEV_BSG=y -CONFIG_BLK_DEV_BSGLIB=y -CONFIG_BLK_DEV_BSG_COMMON=y -CONFIG_BLK_DEV_INTEGRITY=y -CONFIG_BLK_DEV_INTEGRITY_T10=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=262144 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_MQ_VIRTIO=y -CONFIG_BLK_PM=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_CAVIUM_ERRATUM_22375=y -CONFIG_CAVIUM_ERRATUM_23144=y -CONFIG_CAVIUM_ERRATUM_23154=y -CONFIG_CAVIUM_ERRATUM_27456=y -CONFIG_CC_HAVE_SHADOW_CALL_STACK=y -CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y -CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5" -CONFIG_CC_NO_ARRAY_BOUNDS=y -CONFIG_CHECKPOINT_RESTORE=y -CONFIG_CHROME_PLATFORMS=y -CONFIG_CLK_LS1028A_PLLDIG=y -CONFIG_CLK_QORIQ=y -# CONFIG_CLK_VEXPRESS_OSC is not set -CONFIG_CLONE_BACKWARDS=y -CONFIG_CLZ_TAB=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=16 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -# CONFIG_CMA_SYSFS is not set -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_CS2000_CP=y -CONFIG_COMMON_CLK_FSL_FLEXSPI=y -# CONFIG_COMMON_CLK_FSL_SAI is not set -CONFIG_COMMON_CLK_XGENE=y -CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1 -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_CONTEXT_TRACKING=y -CONFIG_CONTEXT_TRACKING_IDLE=y -CONFIG_CONTIG_ALLOC=y -CONFIG_COREDUMP=y -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_FREQ_THERMAL=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_THERMAL=y -CONFIG_CRASH_CORE=y -CONFIG_CRC16=y -# CONFIG_CRC32_SARWATE is not set -CONFIG_CRC32_SLICEBY8=y -CONFIG_CRC64=y -CONFIG_CRC64_ROCKSOFT=y -CONFIG_CRC7=y -CONFIG_CRC_ITU_T=y -CONFIG_CRC_T10DIF=y -CONFIG_CROSS_MEMORY_ATTACH=y -# CONFIG_CROS_EC is not set -CONFIG_CRYPTO_AES_ARM64=y -CONFIG_CRYPTO_AES_ARM64_CE=y -CONFIG_CRYPTO_AES_ARM64_CE_BLK=y -CONFIG_CRYPTO_AES_ARM64_CE_CCM=y -CONFIG_CRYPTO_AUTHENC=y -CONFIG_CRYPTO_BLAKE2B=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CRC64_ROCKSOFT=y -CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=y -CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_DEV_FSL_CAAM=y -CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y -CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC=y -CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON=y -CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y -CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC=y -CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI=y -# CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG is not set -# CONFIG_CRYPTO_DEV_FSL_CAAM_INTC is not set -CONFIG_CRYPTO_DEV_FSL_CAAM_JR=y -CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API=y -CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API=y -CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9 -CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y -CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_ENGINE=y -CONFIG_CRYPTO_GHASH_ARM64_CE=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y -CONFIG_CRYPTO_LIB_DES=y -CONFIG_CRYPTO_LIB_SHA1=y -CONFIG_CRYPTO_LIB_SHA256=y -CONFIG_CRYPTO_LIB_UTILS=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_RNG=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_RSA=y -CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA256_ARM64=y -CONFIG_CRYPTO_SHA2_ARM64_CE=y -CONFIG_CRYPTO_XTS=y -CONFIG_CRYPTO_XXHASH=y -CONFIG_CRYPTO_ZSTD=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_MEMORY_INIT=y -CONFIG_DECOMPRESS_BZIP2=y -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_LZMA=y -CONFIG_DECOMPRESS_LZO=y -CONFIG_DECOMPRESS_XZ=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_DIMLIB=y -CONFIG_DMADEVICES=y -CONFIG_DMATEST=y -CONFIG_DMA_CMA=y -CONFIG_DMA_DIRECT_REMAP=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_ENGINE_RAID=y -CONFIG_DMA_OF=y -CONFIG_DMA_OPS=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DNOTIFY=y -CONFIG_DPAA2_CONSOLE=y -CONFIG_DPAA_ERRATUM_A050385=y -CONFIG_DTC=y -CONFIG_DT_IDLE_STATES=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EEPROM_AT24=y -CONFIG_ELF_CORE=y -# CONFIG_EMBEDDED is not set -CONFIG_EXCLUSIVE_SYSTEM_RAM=y -CONFIG_EXT4_FS=y -CONFIG_EXTCON=y -CONFIG_EXTCON_USB_GPIO=y -CONFIG_F2FS_FS=y -CONFIG_FAILOVER=y -CONFIG_FANOTIFY=y -CONFIG_FAT_FS=y -CONFIG_FB=y -CONFIG_FB_ARMCLCD=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_CMDLINE=y -CONFIG_FB_DEFERRED_IO=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_SYS_COPYAREA=y -CONFIG_FB_SYS_FILLRECT=y -CONFIG_FB_SYS_FOPS=y -CONFIG_FB_SYS_IMAGEBLIT=y -CONFIG_FHANDLE=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FONT_8x16=y -CONFIG_FONT_8x8=y -CONFIG_FONT_SUPPORT=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FRAME_POINTER=y -CONFIG_FREEZER=y -# CONFIG_FSL_BMAN_TEST is not set -CONFIG_FSL_DPAA=y -CONFIG_FSL_DPAA2_ETH=y -CONFIG_FSL_DPAA2_PTP_CLOCK=y -# CONFIG_FSL_DPAA2_QDMA is not set -# CONFIG_FSL_DPAA2_SWITCH is not set -# CONFIG_FSL_DPAA_CHECKING is not set -CONFIG_FSL_DPAA_ETH=y -CONFIG_FSL_EDMA=y -CONFIG_FSL_ENETC=y -CONFIG_FSL_ENETC_IERB=y -CONFIG_FSL_ENETC_MDIO=y -CONFIG_FSL_ENETC_PTP_CLOCK=y -CONFIG_FSL_ENETC_VF=y -CONFIG_FSL_ERRATUM_A008585=y -CONFIG_FSL_FMAN=y -CONFIG_FSL_GUTS=y -CONFIG_FSL_IFC=y -CONFIG_FSL_MC_BUS=y -CONFIG_FSL_MC_DPIO=y -CONFIG_FSL_MC_UAPI_SUPPORT=y -# CONFIG_FSL_PPFE is not set -# CONFIG_FSL_QMAN_TEST is not set -CONFIG_FSL_RCPM=y -CONFIG_FSL_XGMAC_MDIO=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FUSE_FS=y -CONFIG_FWNODE_MDIO=y -CONFIG_FW_CACHE=y -CONFIG_FW_LOADER_PAGED_BUF=y -CONFIG_FW_LOADER_SYSFS=y -# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -CONFIG_GARP=y -CONFIG_GCC11_NO_ARRAY_BOUNDS=y -CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_NUMA=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_CSUM=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IOREMAP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -# CONFIG_GIANFAR is not set -CONFIG_GLOB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_CDEV=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_GENERIC_PLATFORM=y -CONFIG_GPIO_MPC8XXX=y -CONFIG_GPIO_PCA953X=y -CONFIG_GPIO_PCA953X_IRQ=y -CONFIG_GRO_CELLS=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HIBERNATE_CALLBACKS=y -CONFIG_HIBERNATION=y -CONFIG_HIBERNATION_SNAPSHOT_DEV=y -CONFIG_HID=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GENERIC=y -CONFIG_HID_KENSINGTON=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HOTPLUG_CPU=y -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_HVC_DRIVER=y -CONFIG_HVC_IRQ=y -CONFIG_HVC_XEN=y -CONFIG_HVC_XEN_FRONTEND=y -CONFIG_HW_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_DESIGNWARE_CORE=y -CONFIG_I2C_DESIGNWARE_PLATFORM=y -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_IMX=y -CONFIG_I2C_MUX=y -CONFIG_I2C_MUX_PCA954x=y -CONFIG_I2C_RK3X=y -CONFIG_I2C_SLAVE=y -# CONFIG_I2C_SLAVE_TESTUNIT is not set -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_IMX2_WDT=y -CONFIG_INET_DIAG=y -# CONFIG_INET_DIAG_DESTROY is not set -# CONFIG_INET_RAW_DIAG is not set -CONFIG_INET_TCP_DIAG=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_INPUT=y -CONFIG_INPUT_EVDEV=y -CONFIG_INPUT_FF_MEMLESS=y -CONFIG_INPUT_KEYBOARD=y -CONFIG_INPUT_MOUSE=y -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_VIVALDIFMAP=y -CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y -CONFIG_INTERVAL_TREE=y -CONFIG_IOMMU_API=y -# CONFIG_IOMMU_DEBUGFS is not set -# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set -# CONFIG_IOMMU_DEFAULT_DMA_STRICT is not set -CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y -CONFIG_IOMMU_DMA=y -CONFIG_IOMMU_IOVA=y -CONFIG_IOMMU_IO_PGTABLE=y -# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set -# CONFIG_IOMMU_IO_PGTABLE_DART is not set -CONFIG_IOMMU_IO_PGTABLE_LPAE=y -# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set -CONFIG_IOMMU_SUPPORT=y -CONFIG_IPC_NS=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_BYPASS_MANAGER=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_MSI_IOMMU=y -CONFIG_IRQ_WORK=y -# CONFIG_ISDN is not set -CONFIG_JBD2=y -CONFIG_JUMP_LABEL=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -CONFIG_KCMP=y -CONFIG_KEXEC=y -CONFIG_KEXEC_CORE=y -CONFIG_KEYBOARD_ATKBD=y -CONFIG_KEYBOARD_GPIO=y -CONFIG_KSM=y -CONFIG_LIBCRC32C=y -CONFIG_LIBFDT=y -CONFIG_LOCALVERSION_AUTO=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_LS_EXTIRQ=y -CONFIG_LS_SCFG_MSI=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_BUS_MUX=y -CONFIG_MDIO_BUS_MUX_MMIOREG=y -CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y -CONFIG_MDIO_DEVICE=y -CONFIG_MDIO_DEVRES=y -# CONFIG_MDIO_GPIO is not set -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY=y -CONFIG_MEMORY_BALLOON=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_MEMTEST=y -# CONFIG_MFD_HI6421_SPMI is not set -CONFIG_MFD_SYSCON=y -# CONFIG_MFD_VEXPRESS_SYSREG is not set -CONFIG_MICREL_PHY=y -CONFIG_MICROSEMI_PHY=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=32 -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_IO_ACCESSORS=y -CONFIG_MMC_SDHCI_OF_ESDHC=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MMU_NOTIFIER=y -CONFIG_MODULES_USE_ELF_RELA=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_CYAPA is not set -CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_BYD=y -CONFIG_MOUSE_PS2_CYPRESS=y -# CONFIG_MOUSE_PS2_ELANTECH is not set -CONFIG_MOUSE_PS2_FOCALTECH=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SMBUS=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -CONFIG_MPILIB=y -CONFIG_MRP=y -CONFIG_MSCC_OCELOT_SWITCH_LIB=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -# CONFIG_MTD_CFI_GEOMETRY is not set -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_DATAFLASH=y -# CONFIG_MTD_DATAFLASH_OTP is not set -# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set -CONFIG_MTD_NAND_CORE=y -CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_ECC_SW_HAMMING=y -CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_RAW_NAND=y -CONFIG_MTD_SPI_NAND=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_FIT_FW=y -CONFIG_MTD_SST25L=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -CONFIG_MTD_UBI_BLOCK=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MULTIPLEXER=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_MUX_MMIO=y -CONFIG_MV_XOR_V2=y -CONFIG_NAMESPACES=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y -CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NET_DEVLINK=y -CONFIG_NET_DSA=y -CONFIG_NET_DSA_MSCC_FELIX=y -CONFIG_NET_DSA_TAG_OCELOT=y -CONFIG_NET_DSA_TAG_OCELOT_8021Q=y -CONFIG_NET_FAILOVER=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_NS=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_SELFTESTS=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NLS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NODES_SHIFT=2 -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=64 -CONFIG_NUMA=y -CONFIG_NUMA_BALANCING=y -CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y -CONFIG_NVMEM=y -CONFIG_NVMEM_LAYERSCAPE_SFP=y -# CONFIG_NVMEM_SPMI_SDAM is not set -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_IOMMU=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_OF_NUMA=y -CONFIG_PACKET_DIAG=y -CONFIG_PACKING=y -CONFIG_PADATA=y -CONFIG_PAGE_POOL=y -CONFIG_PAGE_REPORTING=y -CONFIG_PAGE_SIZE_LESS_THAN_256KB=y -CONFIG_PAGE_SIZE_LESS_THAN_64KB=y -# CONFIG_PANIC_ON_OOPS is not set -CONFIG_PANIC_ON_OOPS_VALUE=0 -CONFIG_PANIC_TIMEOUT=0 -CONFIG_PARAVIRT=y -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_PARTITION_PERCPU=y -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEASPM=y -CONFIG_PCIEASPM_DEFAULT=y -# CONFIG_PCIEASPM_PERFORMANCE is not set -# CONFIG_PCIEASPM_POWERSAVE is not set -# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_DW=y -CONFIG_PCIE_DW_HOST=y -CONFIG_PCIE_LAYERSCAPE_GEN4=y -CONFIG_PCIE_MOBIVEIL=y -CONFIG_PCIE_MOBIVEIL_HOST=y -CONFIG_PCIE_PME=y -CONFIG_PCI_ATS=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_ECAM=y -CONFIG_PCI_HISI=y -CONFIG_PCI_HOST_COMMON=y -CONFIG_PCI_HOST_GENERIC=y -CONFIG_PCI_IOV=y -CONFIG_PCI_LAYERSCAPE=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PCS_LYNX=y -CONFIG_PGTABLE_LEVELS=4 -CONFIG_PHYLIB=y -CONFIG_PHYLINK=y -CONFIG_PHYS_ADDR_T_64BIT=y -# CONFIG_PHY_FSL_LYNX_28G is not set -CONFIG_PHY_XGENE=y -CONFIG_PID_IN_CONTEXTIDR=y -CONFIG_PID_NS=y -CONFIG_PL330_DMA=y -CONFIG_PM=y -CONFIG_PM_CLK=y -CONFIG_PM_OPP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_PM_STD_PARTITION="" -CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_POWER_RESET_VEXPRESS=y -CONFIG_POWER_RESET_XGENE=y -CONFIG_POWER_SUPPLY=y -CONFIG_PPS=y -CONFIG_PREEMPT=y -CONFIG_PREEMPTION=y -CONFIG_PREEMPT_BUILD=y -CONFIG_PREEMPT_COUNT=y -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_RCU=y -CONFIG_PRINTK_TIME=y -CONFIG_PRINT_QUOTA_WARNING=y -CONFIG_PROC_CHILDREN=y -CONFIG_PROFILING=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_PTP_1588_CLOCK_OPTIONAL=y -CONFIG_PTP_1588_CLOCK_QORIQ=y -CONFIG_QCOM_HIDMA=y -CONFIG_QCOM_HIDMA_MGMT=y -CONFIG_QCOM_QDF2400_ERRATUM_0065=y -# CONFIG_QFMT_V2 is not set -CONFIG_QORIQ_CPUFREQ=y -CONFIG_QORIQ_THERMAL=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -CONFIG_QUOTA=y -CONFIG_QUOTACTL=y -CONFIG_RAID6_PQ=y -# CONFIG_RANDOMIZE_KSTACK_OFFSET is not set -CONFIG_RANDSTRUCT_NONE=y -CONFIG_RAS=y -CONFIG_RATIONAL=y -CONFIG_RD_BZIP2=y -CONFIG_RD_GZIP=y -CONFIG_RD_LZMA=y -CONFIG_RD_LZO=y -CONFIG_RD_XZ=y -CONFIG_REALTEK_PHY=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RODATA_FULL_DEFAULT_ENABLED=y -CONFIG_RPS=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS3232=y -CONFIG_RTC_DRV_FSL_FTM_ALARM=y -CONFIG_RTC_DRV_PCF2127=y -CONFIG_RTC_DRV_PL031=y -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_SCHED_INFO=y -CONFIG_SCHED_MC=y -CONFIG_SCHED_THERMAL_PRESSURE=y -CONFIG_SCSI=y -CONFIG_SCSI_COMMON=y -# CONFIG_SCSI_PROC_FS is not set -# CONFIG_SCSI_SAS_ATA is not set -CONFIG_SCSI_SAS_ATTRS=y -CONFIG_SCSI_SAS_HOST_SMP=y -CONFIG_SCSI_SAS_LIBSAS=y -CONFIG_SECCOMP=y -CONFIG_SECCOMP_FILTER=y -CONFIG_SECRETMEM=y -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_8250_DWLIB=y -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_FSL_LPUART=y -CONFIG_SERIAL_FSL_LPUART_CONSOLE=y -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SERIAL_SC16IS7XX=y -CONFIG_SERIAL_SC16IS7XX_CORE=y -# CONFIG_SERIAL_SC16IS7XX_I2C is not set -CONFIG_SERIAL_SC16IS7XX_SPI=y -CONFIG_SERIAL_XILINX_PS_UART=y -CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y -CONFIG_SERIO=y -CONFIG_SERIO_AMBAKMI=y -CONFIG_SERIO_LIBPS2=y -CONFIG_SGL_ALLOC=y -CONFIG_SG_POOL=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -CONFIG_SMP=y -CONFIG_SOCK_DIAG=y -CONFIG_SOCK_RX_QUEUE_MAPPING=y -CONFIG_SOC_BUS=y -CONFIG_SOFTIRQ_ON_OWN_STACK=y -CONFIG_SPARSEMEM=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -CONFIG_SPI_FSL_DSPI=y -CONFIG_SPI_FSL_QUADSPI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SPI_NXP_FLEXSPI=y -CONFIG_SPI_PL022=y -CONFIG_SPMI=y -# CONFIG_SPMI_HISI3670 is not set -# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set -CONFIG_SQUASHFS_DECOMP_SINGLE=y -CONFIG_SQUASHFS_FILE_CACHE=y -# CONFIG_SQUASHFS_FILE_DIRECT is not set -# CONFIG_SQUASHFS_XZ is not set -CONFIG_SQUASHFS_ZLIB=y -CONFIG_SRAM=y -CONFIG_SRCU=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWIOTLB=y -CONFIG_SWIOTLB_XEN=y -CONFIG_SWPHY=y -CONFIG_SYNC_FILE=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_SYSFS_SYSCALL=y -CONFIG_SYS_HYPERVISOR=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_TASK_XACCT=y -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_EMULATION=y -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THP_SWAP=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y -CONFIG_TRANSPARENT_HUGEPAGE=y -CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y -# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set -CONFIG_TRANS_TABLE=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -# CONFIG_UACCE is not set -CONFIG_UBIFS_FS=y -# CONFIG_UCLAMP_TASK is not set -CONFIG_UIO=y -CONFIG_UIO_AEC=y -CONFIG_UIO_CIF=y -CONFIG_UIO_DMEM_GENIRQ=y -CONFIG_UIO_MF624=y -CONFIG_UIO_NETX=y -CONFIG_UIO_PCI_GENERIC=y -CONFIG_UIO_PDRV_GENIRQ=y -# CONFIG_UIO_PRUSS is not set -CONFIG_UIO_SERCOS3=y -CONFIG_UNINLINE_SPIN_UNLOCK=y -CONFIG_UNIX_DIAG=y -CONFIG_UNMAP_KERNEL_AT_EL0=y -CONFIG_USB_SUPPORT=y -CONFIG_USER_NS=y -CONFIG_USE_PERCPU_NUMA_NODE_ID=y -CONFIG_UTS_NS=y -CONFIG_VEXPRESS_CONFIG=y -CONFIG_VFAT_FS=y -CONFIG_VFIO=y -CONFIG_VFIO_FSL_MC=y -CONFIG_VFIO_IOMMU_TYPE1=y -# CONFIG_VFIO_MDEV is not set -# CONFIG_VFIO_NOIOMMU is not set -CONFIG_VFIO_PCI=y -CONFIG_VFIO_PCI_CORE=y -CONFIG_VFIO_PCI_INTX=y -CONFIG_VFIO_PCI_MMAP=y -CONFIG_VFIO_VIRQFD=y -CONFIG_VGA_ARB=y -CONFIG_VGA_ARB_MAX_GPUS=16 -CONFIG_VIDEOMODE_HELPERS=y -CONFIG_VIRTIO=y -CONFIG_VIRTIO_ANCHOR=y -CONFIG_VIRTIO_BALLOON=y -CONFIG_VIRTIO_BLK=y -CONFIG_VIRTIO_CONSOLE=y -# CONFIG_VIRTIO_IOMMU is not set -CONFIG_VIRTIO_MMIO=y -CONFIG_VIRTIO_NET=y -CONFIG_VIRTIO_PCI=y -CONFIG_VIRTIO_PCI_LEGACY=y -CONFIG_VIRTIO_PCI_LIB=y -CONFIG_VIRTIO_PCI_LIB_LEGACY=y -CONFIG_VITESSE_PHY=y -CONFIG_VLAN_8021Q_GVRP=y -CONFIG_VLAN_8021Q_MVRP=y -CONFIG_VMAP_STACK=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_XARRAY_MULTI=y -CONFIG_XEN=y -CONFIG_XENFS=y -CONFIG_XEN_AUTO_XLATE=y -CONFIG_XEN_BACKEND=y -CONFIG_XEN_BALLOON=y -# CONFIG_XEN_BLKDEV_BACKEND is not set -CONFIG_XEN_BLKDEV_FRONTEND=y -CONFIG_XEN_COMPAT_XENFS=y -CONFIG_XEN_DEV_EVTCHN=y -CONFIG_XEN_DOM0=y -CONFIG_XEN_FBDEV_FRONTEND=y -CONFIG_XEN_GNTDEV=y -CONFIG_XEN_GRANT_DEV_ALLOC=y -# CONFIG_XEN_NETDEV_BACKEND is not set -CONFIG_XEN_NETDEV_FRONTEND=y -# CONFIG_XEN_PCIDEV_STUB is not set -CONFIG_XEN_PRIVCMD=y -# CONFIG_XEN_PVCALLS_BACKEND is not set -# CONFIG_XEN_SCSI_FRONTEND is not set -CONFIG_XEN_SYS_HYPERVISOR=y -# CONFIG_XEN_VIRTIO is not set -# CONFIG_XEN_WDT is not set -CONFIG_XEN_XENBUS_FRONTEND=y -CONFIG_XFS_FS=y -CONFIG_XFS_RT=y -CONFIG_XOR_BLOCKS=y -CONFIG_XPS=y -CONFIG_XXHASH=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_ARMTHUMB=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_XZ_DEC_IA64=y -CONFIG_XZ_DEC_POWERPC=y -CONFIG_XZ_DEC_SPARC=y -CONFIG_XZ_DEC_X86=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZONE_DMA32=y -CONFIG_ZSTD_COMMON=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y From e6da78d193a4ddfc0f61f336c980ed08bd9faa23 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 20 Sep 2024 18:48:01 +0100 Subject: [PATCH 15/23] armsr: remove left-over patches for kernel 6.1 Support for Linux 6.1 has already been removed from the armsr target. Remove left-over patches-6.1 folder as well. Fixes: fd47fdf527 ("armsr: Remove kernel 6.1 configuration") Signed-off-by: Daniel Golle --- .../221-armsr-disable_gc_sections_armv7.patch | 23 -- ...a2-eth-don-t-use-ENOTSUPP-error-code.patch | 44 --- ...e-dpaa2_mac_is_type_fixed-with-dpaa2.patch | 99 ------ ...sorb-phylink_start-call-into-dpaa2_m.patch | 88 ----- ...move-defensive-check-in-dpaa2_mac_di.patch | 50 --- ...sign-priv-mac-after-dpaa2_mac_connec.patch | 101 ------ ...-assign-port_priv-mac-after-dpaa2_ma.patch | 73 ---- ...h-MAC-stringset-to-ethtool-S-even-if.patch | 111 ------ ...-replace-direct-MAC-access-with-dpaa.patch | 28 -- ...nnect-to-MAC-before-requesting-the-e.patch | 93 ----- ...rialize-changes-to-priv-mac-with-a-m.patch | 320 ------------------ ...h-serialize-changes-to-priv-mac-with.patch | 203 ----------- ...c-move-rtnl_lock-only-around-phylink.patch | 113 ------- 13 files changed, 1346 deletions(-) delete mode 100644 target/linux/armsr/patches-6.1/221-armsr-disable_gc_sections_armv7.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch delete mode 100644 target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch diff --git a/target/linux/armsr/patches-6.1/221-armsr-disable_gc_sections_armv7.patch b/target/linux/armsr/patches-6.1/221-armsr-disable_gc_sections_armv7.patch deleted file mode 100644 index 7c0b4b19202130..00000000000000 --- a/target/linux/armsr/patches-6.1/221-armsr-disable_gc_sections_armv7.patch +++ /dev/null @@ -1,23 +0,0 @@ -From b77c0ecdc7915e5c5c515da1aa6cfaf6f4eb8351 Mon Sep 17 00:00:00 2001 -From: Mathew McBride -Date: Wed, 28 Sep 2022 16:39:31 +1000 -Subject: [PATCH] arm: disable code size reduction measures - (gc-sections,-f*-sections) - -This interferes with the EFI boot stub on armv7l. - -Signed-off-by: Mathew McBride ---- - arch/arm/Kconfig | 1 - - 1 file changed, 1 deletion(-) - ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -124,7 +124,6 @@ config ARM - select HAVE_VIRT_CPU_ACCOUNTING_GEN - select IRQ_FORCED_THREADING - select LOCK_MM_AND_FIND_VMA -- select HAVE_LD_DEAD_CODE_DATA_ELIMINATION - select MODULES_USE_ELF_REL - select NEED_DMA_MAP_STATE - select OF_EARLY_FLATTREE if OF diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch b/target/linux/armsr/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch deleted file mode 100644 index f173cad7efd102..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0001-net-dpaa2-eth-don-t-use-ENOTSUPP-error-code.patch +++ /dev/null @@ -1,44 +0,0 @@ -From f3763a0c1b07273218cbf5886bdf8df9df501111 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:10 +0200 -Subject: [PATCH 03/14] net: dpaa2-eth: don't use -ENOTSUPP error code - -dpaa2_eth_setup_dpni() is called from the probe path and -dpaa2_eth_set_link_ksettings() is propagated to user space. - -include/linux/errno.h says that ENOTSUPP is "Defined for the NFSv3 -protocol". Conventional wisdom has it to not use it in networking -drivers. Replace it with -EOPNOTSUPP. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Andrew Lunn -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 +- - drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -3618,7 +3618,7 @@ static int dpaa2_eth_setup_dpni(struct f - dev_err(dev, "DPNI version %u.%u not supported, need >= %u.%u\n", - priv->dpni_ver_major, priv->dpni_ver_minor, - DPNI_VER_MAJOR, DPNI_VER_MINOR); -- err = -ENOTSUPP; -+ err = -EOPNOTSUPP; - goto close; - } - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -@@ -118,7 +118,7 @@ dpaa2_eth_set_link_ksettings(struct net_ - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); - - if (!dpaa2_eth_is_type_phy(priv)) -- return -ENOTSUPP; -+ return -EOPNOTSUPP; - - return phylink_ethtool_ksettings_set(priv->mac->phylink, link_settings); - } diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch b/target/linux/armsr/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch deleted file mode 100644 index 501eaf42ff33dd..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0002-net-dpaa2-replace-dpaa2_mac_is_type_fixed-with-dpaa2.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 022a11062261dc4703da846d3bf4d194ef6bebf5 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:11 +0200 -Subject: [PATCH 04/14] net: dpaa2: replace dpaa2_mac_is_type_fixed() with - dpaa2_mac_is_type_phy() - -dpaa2_mac_is_type_fixed() is a header with no implementation and no -callers, which is referenced from the documentation though. It can be -deleted. - -On the other hand, it would be useful to reuse the code between -dpaa2_eth_is_type_phy() and dpaa2_switch_port_is_type_phy(). That common -code should be called dpaa2_mac_is_type_phy(), so let's create that. - -The removal and the addition are merged into the same patch because, -in fact, is_type_phy() is the logical opposite of is_type_fixed(). - -Signed-off-by: Vladimir Oltean -Reviewed-by: Andrew Lunn -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - .../ethernet/freescale/dpaa2/mac-phy-support.rst | 9 ++++++--- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 7 +------ - drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h | 10 ++++++++-- - drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h | 7 +------ - 4 files changed, 16 insertions(+), 17 deletions(-) - ---- a/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support.rst -+++ b/Documentation/networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support.rst -@@ -181,10 +181,13 @@ when necessary using the below listed AP - - int dpaa2_mac_connect(struct dpaa2_mac *mac); - - void dpaa2_mac_disconnect(struct dpaa2_mac *mac); - --A phylink integration is necessary only when the partner DPMAC is not of TYPE_FIXED. --One can check for this condition using the below API:: -+A phylink integration is necessary only when the partner DPMAC is not of -+``TYPE_FIXED``. This means it is either of ``TYPE_PHY``, or of -+``TYPE_BACKPLANE`` (the difference being the two that in the ``TYPE_BACKPLANE`` -+mode, the MC firmware does not access the PCS registers). One can check for -+this condition using the following helper:: - -- - bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,struct fsl_mc_io *mc_io); -+ - static inline bool dpaa2_mac_is_type_phy(struct dpaa2_mac *mac); - - Before connection to a MAC, the caller must allocate and populate the - dpaa2_mac structure with the associated net_device, a pointer to the MC portal ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -733,12 +733,7 @@ static inline unsigned int dpaa2_eth_rx_ - - static inline bool dpaa2_eth_is_type_phy(struct dpaa2_eth_priv *priv) - { -- if (priv->mac && -- (priv->mac->attr.link_type == DPMAC_LINK_TYPE_PHY || -- priv->mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE)) -- return true; -- -- return false; -+ return dpaa2_mac_is_type_phy(priv->mac); - } - - static inline bool dpaa2_eth_has_mac(struct dpaa2_eth_priv *priv) ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h -@@ -30,8 +30,14 @@ struct dpaa2_mac { - struct phy *serdes_phy; - }; - --bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev, -- struct fsl_mc_io *mc_io); -+static inline bool dpaa2_mac_is_type_phy(struct dpaa2_mac *mac) -+{ -+ if (!mac) -+ return false; -+ -+ return mac->attr.link_type == DPMAC_LINK_TYPE_PHY || -+ mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE; -+} - - int dpaa2_mac_open(struct dpaa2_mac *mac); - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h -@@ -230,12 +230,7 @@ static inline bool dpaa2_switch_supports - static inline bool - dpaa2_switch_port_is_type_phy(struct ethsw_port_priv *port_priv) - { -- if (port_priv->mac && -- (port_priv->mac->attr.link_type == DPMAC_LINK_TYPE_PHY || -- port_priv->mac->attr.link_type == DPMAC_LINK_TYPE_BACKPLANE)) -- return true; -- -- return false; -+ return dpaa2_mac_is_type_phy(port_priv->mac); - } - - static inline bool dpaa2_switch_port_has_mac(struct ethsw_port_priv *port_priv) diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch b/target/linux/armsr/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch deleted file mode 100644 index af5ff2aea6046f..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0003-net-dpaa2-mac-absorb-phylink_start-call-into-dpaa2_m.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 97c07369ab8bf9895e05d4b468f18e6567263154 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:12 +0200 -Subject: [PATCH 05/14] net: dpaa2-mac: absorb phylink_start() call into - dpaa2_mac_start() - -The phylink handling is intended to be hidden inside the dpaa2_mac -object. Move the phylink_start() call into dpaa2_mac_start(), and -phylink_stop() into dpaa2_mac_stop(). - -Signed-off-by: Vladimir Oltean -Reviewed-by: Andrew Lunn -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 5 +---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 8 ++++++++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 5 +---- - 3 files changed, 10 insertions(+), 8 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -2083,10 +2083,8 @@ static int dpaa2_eth_open(struct net_dev - goto enable_err; - } - -- if (dpaa2_eth_is_type_phy(priv)) { -+ if (dpaa2_eth_is_type_phy(priv)) - dpaa2_mac_start(priv->mac); -- phylink_start(priv->mac->phylink); -- } - - return 0; - -@@ -2160,7 +2158,6 @@ static int dpaa2_eth_stop(struct net_dev - int retries = 10; - - if (dpaa2_eth_is_type_phy(priv)) { -- phylink_stop(priv->mac->phylink); - dpaa2_mac_stop(priv->mac); - } else { - netif_tx_stop_all_queues(net_dev); ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c -@@ -336,12 +336,20 @@ static void dpaa2_mac_set_supported_inte - - void dpaa2_mac_start(struct dpaa2_mac *mac) - { -+ ASSERT_RTNL(); -+ - if (mac->serdes_phy) - phy_power_on(mac->serdes_phy); -+ -+ phylink_start(mac->phylink); - } - - void dpaa2_mac_stop(struct dpaa2_mac *mac) - { -+ ASSERT_RTNL(); -+ -+ phylink_stop(mac->phylink); -+ - if (mac->serdes_phy) - phy_power_off(mac->serdes_phy); - } ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -@@ -703,10 +703,8 @@ static int dpaa2_switch_port_open(struct - - dpaa2_switch_enable_ctrl_if_napi(ethsw); - -- if (dpaa2_switch_port_is_type_phy(port_priv)) { -+ if (dpaa2_switch_port_is_type_phy(port_priv)) - dpaa2_mac_start(port_priv->mac); -- phylink_start(port_priv->mac->phylink); -- } - - return 0; - } -@@ -718,7 +716,6 @@ static int dpaa2_switch_port_stop(struct - int err; - - if (dpaa2_switch_port_is_type_phy(port_priv)) { -- phylink_stop(port_priv->mac->phylink); - dpaa2_mac_stop(port_priv->mac); - } else { - netif_tx_stop_all_queues(netdev); diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch b/target/linux/armsr/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch deleted file mode 100644 index c3028357fe5894..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0004-net-dpaa2-mac-remove-defensive-check-in-dpaa2_mac_di.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 095ef388f714d622aa503fcccf20dc4095b72762 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:13 +0200 -Subject: [PATCH 06/14] net: dpaa2-mac: remove defensive check in - dpaa2_mac_disconnect() - -dpaa2_mac_disconnect() will only be called with a NULL mac->phylink if -dpaa2_mac_connect() failed, or was never called. - -The callers are these: - -dpaa2_eth_disconnect_mac(): - - if (dpaa2_eth_is_type_phy(priv)) - dpaa2_mac_disconnect(priv->mac); - -dpaa2_switch_port_disconnect_mac(): - - if (dpaa2_switch_port_is_type_phy(port_priv)) - dpaa2_mac_disconnect(port_priv->mac); - -priv->mac can be NULL, but in that case, dpaa2_eth_is_type_phy() returns -false, and dpaa2_mac_disconnect() is never called. Similar for -dpaa2-switch. - -When priv->mac is non-NULL, it means that dpaa2_mac_connect() returned -zero (success), and therefore, priv->mac->phylink is also a valid -pointer. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Andrew Lunn -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 3 --- - 1 file changed, 3 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c -@@ -446,9 +446,6 @@ err_pcs_destroy: - - void dpaa2_mac_disconnect(struct dpaa2_mac *mac) - { -- if (!mac->phylink) -- return; -- - phylink_disconnect_phy(mac->phylink); - phylink_destroy(mac->phylink); - dpaa2_pcs_destroy(mac); diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch b/target/linux/armsr/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch deleted file mode 100644 index bd27c8be20a1e0..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0005-net-dpaa2-eth-assign-priv-mac-after-dpaa2_mac_connec.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 06efc9b8a1360cad83cae6e71558e5458cc1fbf3 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:14 +0200 -Subject: [PATCH 07/14] net: dpaa2-eth: assign priv->mac after - dpaa2_mac_connect() call - -There are 2 requirements for correct code: - -- Any time the driver accesses the priv->mac pointer at runtime, it - either holds NULL to indicate a DPNI-DPNI connection (or unconnected - DPNI), or a struct dpaa2_mac whose phylink instance was fully - initialized (created and connected to the PHY). No changes are made to - priv->mac while it is being used. Currently, rtnl_lock() watches over - the call to dpaa2_eth_connect_mac(), so it serves the purpose of - serializing this with all readers of priv->mac. - -- dpaa2_mac_connect() should run unlocked, because inside it are 2 - phylink calls with incompatible locking requirements: phylink_create() - requires that the rtnl_mutex isn't held, and phylink_fwnode_phy_connect() - requires that the rtnl_mutex is held. The only way to solve those - contradictory requirements is to let dpaa2_mac_connect() take - rtnl_lock() when it needs to. - -To solve both requirements, we need to identify the writer side of the -priv->mac pointer, which can be wrapped in a mutex private to the driver -in a future patch. The dpaa2_mac_connect() cannot be part of the writer -side critical section, because of an AB/BA deadlock with rtnl_lock(). - -So the strategy needs to be that where we prepare the DPMAC by calling -dpaa2_mac_connect(), and only make priv->mac point to it once it's fully -prepared. This ensures that the writer side critical section has the -absolute minimum surface it can. - -The reverse strategy is adopted in the dpaa2_eth_disconnect_mac() code -path. This makes sure that priv->mac is NULL when we start tearing down -the DPMAC that we disconnected from, and concurrent code will simply not -see it. - -No locking changes in this patch (concurrent code is still blocked by -the rtnl_mutex). - -Signed-off-by: Vladimir Oltean -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 21 +++++++++++-------- - 1 file changed, 12 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -4448,9 +4448,8 @@ static int dpaa2_eth_connect_mac(struct - err = dpaa2_mac_open(mac); - if (err) - goto err_free_mac; -- priv->mac = mac; - -- if (dpaa2_eth_is_type_phy(priv)) { -+ if (dpaa2_mac_is_type_phy(mac)) { - err = dpaa2_mac_connect(mac); - if (err && err != -EPROBE_DEFER) - netdev_err(priv->net_dev, "Error connecting to the MAC endpoint: %pe", -@@ -4459,11 +4458,12 @@ static int dpaa2_eth_connect_mac(struct - goto err_close_mac; - } - -+ priv->mac = mac; -+ - return 0; - - err_close_mac: - dpaa2_mac_close(mac); -- priv->mac = NULL; - err_free_mac: - kfree(mac); - return err; -@@ -4471,15 +4471,18 @@ err_free_mac: - - static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv) - { -- if (dpaa2_eth_is_type_phy(priv)) -- dpaa2_mac_disconnect(priv->mac); -+ struct dpaa2_mac *mac = priv->mac; -+ -+ priv->mac = NULL; - -- if (!dpaa2_eth_has_mac(priv)) -+ if (!mac) - return; - -- dpaa2_mac_close(priv->mac); -- kfree(priv->mac); -- priv->mac = NULL; -+ if (dpaa2_mac_is_type_phy(mac)) -+ dpaa2_mac_disconnect(mac); -+ -+ dpaa2_mac_close(mac); -+ kfree(mac); - } - - static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg) diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch b/target/linux/armsr/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch deleted file mode 100644 index e63654984a5194..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0006-net-dpaa2-switch-assign-port_priv-mac-after-dpaa2_ma.patch +++ /dev/null @@ -1,73 +0,0 @@ -From a5e7f7e277bd4403c45c1c7922d56d0eb08dbc7c Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:15 +0200 -Subject: [PATCH 08/14] net: dpaa2-switch: assign port_priv->mac after - dpaa2_mac_connect() call - -The dpaa2-switch has the exact same locking requirements when connected -to a DPMAC, so it needs port_priv->mac to always point either to NULL, -or to a DPMAC with a fully initialized phylink instance. - -Make the same preparatory change in the dpaa2-switch driver as in the -dpaa2-eth one. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - .../ethernet/freescale/dpaa2/dpaa2-switch.c | 21 +++++++++++-------- - 1 file changed, 12 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -@@ -1450,9 +1450,8 @@ static int dpaa2_switch_port_connect_mac - err = dpaa2_mac_open(mac); - if (err) - goto err_free_mac; -- port_priv->mac = mac; - -- if (dpaa2_switch_port_is_type_phy(port_priv)) { -+ if (dpaa2_mac_is_type_phy(mac)) { - err = dpaa2_mac_connect(mac); - if (err) { - netdev_err(port_priv->netdev, -@@ -1462,11 +1461,12 @@ static int dpaa2_switch_port_connect_mac - } - } - -+ port_priv->mac = mac; -+ - return 0; - - err_close_mac: - dpaa2_mac_close(mac); -- port_priv->mac = NULL; - err_free_mac: - kfree(mac); - return err; -@@ -1474,15 +1474,18 @@ err_free_mac: - - static void dpaa2_switch_port_disconnect_mac(struct ethsw_port_priv *port_priv) - { -- if (dpaa2_switch_port_is_type_phy(port_priv)) -- dpaa2_mac_disconnect(port_priv->mac); -+ struct dpaa2_mac *mac = port_priv->mac; -+ -+ port_priv->mac = NULL; - -- if (!dpaa2_switch_port_has_mac(port_priv)) -+ if (!mac) - return; - -- dpaa2_mac_close(port_priv->mac); -- kfree(port_priv->mac); -- port_priv->mac = NULL; -+ if (dpaa2_mac_is_type_phy(mac)) -+ dpaa2_mac_disconnect(mac); -+ -+ dpaa2_mac_close(mac); -+ kfree(mac); - } - - static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg) diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch b/target/linux/armsr/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch deleted file mode 100644 index c790ba1bd50680..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch +++ /dev/null @@ -1,111 +0,0 @@ -From ce44b6ed9ee65efa9b3025552c513842eabcab88 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:16 +0200 -Subject: [PATCH 09/14] net: dpaa2: publish MAC stringset to ethtool -S even if - MAC is missing - -DPNIs and DPSW objects can connect and disconnect at runtime from DPMAC -objects on the same fsl-mc bus. The DPMAC object also holds "ethtool -S" -unstructured counters. Those counters are only shown for the entity -owning the netdev (DPNI, DPSW) if it's connected to a DPMAC. - -The ethtool stringset code path is split into multiple callbacks, but -currently, connecting and disconnecting the DPMAC takes the rtnl_lock(). -This blocks the entire ethtool code path from running, see -ethnl_default_doit() -> rtnl_lock() -> ops->prepare_data() -> -strset_prepare_data(). - -This is going to be a problem if we are going to no longer require -rtnl_lock() when connecting/disconnecting the DPMAC, because the DPMAC -could appear between ops->get_sset_count() and ops->get_strings(). -If it appears out of the blue, we will provide a stringset into an array -that was dimensioned thinking the DPMAC wouldn't be there => array -accessed out of bounds. - -There isn't really a good way to work around that, and I don't want to -put too much pressure on the ethtool framework by playing locking games. -Just make the DPMAC counters be always available. They'll be zeroes if -the DPNI or DPSW isn't connected to a DPMAC. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Andrew Lunn -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 12 +++--------- - .../ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c | 11 ++--------- - 2 files changed, 5 insertions(+), 18 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -@@ -186,7 +186,6 @@ static int dpaa2_eth_set_pauseparam(stru - static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset, - u8 *data) - { -- struct dpaa2_eth_priv *priv = netdev_priv(netdev); - u8 *p = data; - int i; - -@@ -200,22 +199,17 @@ static void dpaa2_eth_get_strings(struct - strscpy(p, dpaa2_ethtool_extras[i], ETH_GSTRING_LEN); - p += ETH_GSTRING_LEN; - } -- if (dpaa2_eth_has_mac(priv)) -- dpaa2_mac_get_strings(p); -+ dpaa2_mac_get_strings(p); - break; - } - } - - static int dpaa2_eth_get_sset_count(struct net_device *net_dev, int sset) - { -- int num_ss_stats = DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS; -- struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -- - switch (sset) { - case ETH_SS_STATS: /* ethtool_get_stats(), ethtool_get_drvinfo() */ -- if (dpaa2_eth_has_mac(priv)) -- num_ss_stats += dpaa2_mac_get_sset_count(); -- return num_ss_stats; -+ return DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS + -+ dpaa2_mac_get_sset_count(); - default: - return -EOPNOTSUPP; - } ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c -@@ -145,14 +145,9 @@ dpaa2_switch_set_link_ksettings(struct n - static int - dpaa2_switch_ethtool_get_sset_count(struct net_device *netdev, int sset) - { -- struct ethsw_port_priv *port_priv = netdev_priv(netdev); -- int num_ss_stats = DPAA2_SWITCH_NUM_COUNTERS; -- - switch (sset) { - case ETH_SS_STATS: -- if (port_priv->mac) -- num_ss_stats += dpaa2_mac_get_sset_count(); -- return num_ss_stats; -+ return DPAA2_SWITCH_NUM_COUNTERS + dpaa2_mac_get_sset_count(); - default: - return -EOPNOTSUPP; - } -@@ -161,7 +156,6 @@ dpaa2_switch_ethtool_get_sset_count(stru - static void dpaa2_switch_ethtool_get_strings(struct net_device *netdev, - u32 stringset, u8 *data) - { -- struct ethsw_port_priv *port_priv = netdev_priv(netdev); - u8 *p = data; - int i; - -@@ -172,8 +166,7 @@ static void dpaa2_switch_ethtool_get_str - ETH_GSTRING_LEN); - p += ETH_GSTRING_LEN; - } -- if (port_priv->mac) -- dpaa2_mac_get_strings(p); -+ dpaa2_mac_get_strings(p); - break; - } - } diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch b/target/linux/armsr/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch deleted file mode 100644 index 0663bf6fb10f17..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0008-net-dpaa2-switch-replace-direct-MAC-access-with-dpaa.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c838d9fd7e6ba9ddd6006bf0a296396266e9f121 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:17 +0200 -Subject: [PATCH 10/14] net: dpaa2-switch replace direct MAC access with - dpaa2_switch_port_has_mac() - -The helper function will gain a lockdep annotation in a future patch. -Make sure to benefit from it. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c -@@ -189,7 +189,7 @@ static void dpaa2_switch_ethtool_get_sta - dpaa2_switch_ethtool_counters[i].name, err); - } - -- if (port_priv->mac) -+ if (dpaa2_switch_port_has_mac(port_priv)) - dpaa2_mac_get_ethtool_stats(port_priv->mac, data + i); - } - diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch b/target/linux/armsr/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch deleted file mode 100644 index 246cd633ba6379..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0009-net-dpaa2-eth-connect-to-MAC-before-requesting-the-e.patch +++ /dev/null @@ -1,93 +0,0 @@ -From e0ea63162cb5f1ca7f844d6ef5fc4079448ee2d5 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:18 +0200 -Subject: [PATCH 11/14] net: dpaa2-eth: connect to MAC before requesting the - "endpoint changed" IRQ - -dpaa2_eth_connect_mac() is called both from dpaa2_eth_probe() and from -dpni_irq0_handler_thread(). - -It could happen that the DPNI gets connected to a DPMAC on the fsl-mc -bus exactly during probe, as soon as the "endpoint change" interrupt is -requested in dpaa2_eth_setup_irqs(). This will cause the -dpni_irq0_handler_thread() to register a phylink instance for that DPMAC. - -Then, the probing function will also try to register a phylink instance -for the same DPMAC, operation which should fail (and this will fail the -probing of the driver). - -Reorder dpaa2_eth_setup_irqs() and dpaa2_eth_connect_mac(), such that -dpni_irq0_handler_thread() never races with the DPMAC-related portion of -the probing path. - -Also reorder dpaa2_eth_disconnect_mac() to be in the mirror position of -dpaa2_eth_connect_mac() in the teardown path. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -4715,6 +4715,10 @@ static int dpaa2_eth_probe(struct fsl_mc - } - #endif - -+ err = dpaa2_eth_connect_mac(priv); -+ if (err) -+ goto err_connect_mac; -+ - err = dpaa2_eth_setup_irqs(dpni_dev); - if (err) { - netdev_warn(net_dev, "Failed to set link interrupt, fall back to polling\n"); -@@ -4727,10 +4731,6 @@ static int dpaa2_eth_probe(struct fsl_mc - priv->do_link_poll = true; - } - -- err = dpaa2_eth_connect_mac(priv); -- if (err) -- goto err_connect_mac; -- - err = dpaa2_eth_dl_alloc(priv); - if (err) - goto err_dl_register; -@@ -4766,13 +4766,13 @@ err_dl_port_add: - err_dl_trap_register: - dpaa2_eth_dl_free(priv); - err_dl_register: -- dpaa2_eth_disconnect_mac(priv); --err_connect_mac: - if (priv->do_link_poll) - kthread_stop(priv->poll_thread); - else - fsl_mc_free_irqs(dpni_dev); - err_poll_thread: -+ dpaa2_eth_disconnect_mac(priv); -+err_connect_mac: - dpaa2_eth_free_rings(priv); - err_alloc_rings: - err_csum: -@@ -4820,9 +4820,6 @@ static int dpaa2_eth_remove(struct fsl_m - #endif - - unregister_netdev(net_dev); -- rtnl_lock(); -- dpaa2_eth_disconnect_mac(priv); -- rtnl_unlock(); - - dpaa2_eth_dl_port_del(priv); - dpaa2_eth_dl_traps_unregister(priv); -@@ -4833,6 +4830,9 @@ static int dpaa2_eth_remove(struct fsl_m - else - fsl_mc_free_irqs(ls_dev); - -+ rtnl_lock(); -+ dpaa2_eth_disconnect_mac(priv); -+ rtnl_unlock(); - dpaa2_eth_free_rings(priv); - free_percpu(priv->fd); - free_percpu(priv->sgt_cache); diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch b/target/linux/armsr/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch deleted file mode 100644 index 553870d8ec6792..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0010-net-dpaa2-eth-serialize-changes-to-priv-mac-with-a-m.patch +++ /dev/null @@ -1,320 +0,0 @@ -From 5e448a17dfa2e95166534df7f677a3694ef6187d Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:19 +0200 -Subject: [PATCH 12/14] net: dpaa2-eth: serialize changes to priv->mac with a - mutex - -The dpaa2 architecture permits dynamic connections between objects on -the fsl-mc bus, specifically between a DPNI object (represented by a -struct net_device) and a DPMAC object (represented by a struct phylink). - -The DPNI driver is notified when those connections are created/broken -through the dpni_irq0_handler_thread() method. To ensure that ethtool -operations, as well as netdev up/down operations serialize with the -connection/disconnection of the DPNI with a DPMAC, -dpni_irq0_handler_thread() takes the rtnl_lock() to block those other -operations from taking place. - -There is code called by dpaa2_mac_connect() which wants to acquire the -rtnl_mutex once again, see phylink_create() -> phylink_register_sfp() -> -sfp_bus_add_upstream() -> rtnl_lock(). So the strategy doesn't quite -work out, even though it's fairly simple. - -Create a different strategy, where all code paths in the dpaa2-eth -driver access priv->mac only while they are holding priv->mac_lock. -The phylink instance is not created or connected to the PHY under the -priv->mac_lock, but only assigned to priv->mac then. This will eliminate -the reliance on the rtnl_mutex. - -Add lockdep annotations and put comments where holding the lock is not -necessary, and priv->mac can be dereferenced freely. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 43 ++++++++++++-- - .../net/ethernet/freescale/dpaa2/dpaa2-eth.h | 6 ++ - .../ethernet/freescale/dpaa2/dpaa2-ethtool.c | 58 +++++++++++++++---- - 3 files changed, 91 insertions(+), 16 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -2021,8 +2021,11 @@ static int dpaa2_eth_link_state_update(s - - /* When we manage the MAC/PHY using phylink there is no need - * to manually update the netif_carrier. -+ * We can avoid locking because we are called from the "link changed" -+ * IRQ handler, which is the same as the "endpoint changed" IRQ handler -+ * (the writer to priv->mac), so we cannot race with it. - */ -- if (dpaa2_eth_is_type_phy(priv)) -+ if (dpaa2_mac_is_type_phy(priv->mac)) - goto out; - - /* Chech link state; speed / duplex changes are not treated yet */ -@@ -2061,6 +2064,8 @@ static int dpaa2_eth_open(struct net_dev - priv->dpbp_dev->obj_desc.id, priv->bpid); - } - -+ mutex_lock(&priv->mac_lock); -+ - if (!dpaa2_eth_is_type_phy(priv)) { - /* We'll only start the txqs when the link is actually ready; - * make sure we don't race against the link up notification, -@@ -2079,6 +2084,7 @@ static int dpaa2_eth_open(struct net_dev - - err = dpni_enable(priv->mc_io, 0, priv->mc_token); - if (err < 0) { -+ mutex_unlock(&priv->mac_lock); - netdev_err(net_dev, "dpni_enable() failed\n"); - goto enable_err; - } -@@ -2086,6 +2092,8 @@ static int dpaa2_eth_open(struct net_dev - if (dpaa2_eth_is_type_phy(priv)) - dpaa2_mac_start(priv->mac); - -+ mutex_unlock(&priv->mac_lock); -+ - return 0; - - enable_err: -@@ -2157,6 +2165,8 @@ static int dpaa2_eth_stop(struct net_dev - int dpni_enabled = 0; - int retries = 10; - -+ mutex_lock(&priv->mac_lock); -+ - if (dpaa2_eth_is_type_phy(priv)) { - dpaa2_mac_stop(priv->mac); - } else { -@@ -2164,6 +2174,8 @@ static int dpaa2_eth_stop(struct net_dev - netif_carrier_off(net_dev); - } - -+ mutex_unlock(&priv->mac_lock); -+ - /* On dpni_disable(), the MC firmware will: - * - stop MAC Rx and wait for all Rx frames to be enqueued to software - * - cut off WRIOP dequeues from egress FQs and wait until transmission -@@ -2489,12 +2501,20 @@ static int dpaa2_eth_ts_ioctl(struct net - static int dpaa2_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) - { - struct dpaa2_eth_priv *priv = netdev_priv(dev); -+ int err; - - if (cmd == SIOCSHWTSTAMP) - return dpaa2_eth_ts_ioctl(dev, rq, cmd); - -- if (dpaa2_eth_is_type_phy(priv)) -- return phylink_mii_ioctl(priv->mac->phylink, rq, cmd); -+ mutex_lock(&priv->mac_lock); -+ -+ if (dpaa2_eth_is_type_phy(priv)) { -+ err = phylink_mii_ioctl(priv->mac->phylink, rq, cmd); -+ mutex_unlock(&priv->mac_lock); -+ return err; -+ } -+ -+ mutex_unlock(&priv->mac_lock); - - return -EOPNOTSUPP; - } -@@ -4458,7 +4478,9 @@ static int dpaa2_eth_connect_mac(struct - goto err_close_mac; - } - -+ mutex_lock(&priv->mac_lock); - priv->mac = mac; -+ mutex_unlock(&priv->mac_lock); - - return 0; - -@@ -4471,9 +4493,12 @@ err_free_mac: - - static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv) - { -- struct dpaa2_mac *mac = priv->mac; -+ struct dpaa2_mac *mac; - -+ mutex_lock(&priv->mac_lock); -+ mac = priv->mac; - priv->mac = NULL; -+ mutex_unlock(&priv->mac_lock); - - if (!mac) - return; -@@ -4492,6 +4517,7 @@ static irqreturn_t dpni_irq0_handler_thr - struct fsl_mc_device *dpni_dev = to_fsl_mc_device(dev); - struct net_device *net_dev = dev_get_drvdata(dev); - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ bool had_mac; - int err; - - err = dpni_get_irq_status(dpni_dev->mc_io, 0, dpni_dev->mc_handle, -@@ -4509,7 +4535,12 @@ static irqreturn_t dpni_irq0_handler_thr - dpaa2_eth_update_tx_fqids(priv); - - rtnl_lock(); -- if (dpaa2_eth_has_mac(priv)) -+ /* We can avoid locking because the "endpoint changed" IRQ -+ * handler is the only one who changes priv->mac at runtime, -+ * so we are not racing with anyone. -+ */ -+ had_mac = !!priv->mac; -+ if (had_mac) - dpaa2_eth_disconnect_mac(priv); - else - dpaa2_eth_connect_mac(priv); -@@ -4610,6 +4641,8 @@ static int dpaa2_eth_probe(struct fsl_mc - priv = netdev_priv(net_dev); - priv->net_dev = net_dev; - -+ mutex_init(&priv->mac_lock); -+ - priv->iommu_domain = iommu_get_domain_for_dev(dev); - - priv->tx_tstamp_type = HWTSTAMP_TX_OFF; ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -580,6 +580,8 @@ struct dpaa2_eth_priv { - #endif - - struct dpaa2_mac *mac; -+ /* Serializes changes to priv->mac */ -+ struct mutex mac_lock; - struct workqueue_struct *dpaa2_ptp_wq; - struct work_struct tx_onestep_tstamp; - struct sk_buff_head tx_skbs; -@@ -733,11 +735,15 @@ static inline unsigned int dpaa2_eth_rx_ - - static inline bool dpaa2_eth_is_type_phy(struct dpaa2_eth_priv *priv) - { -+ lockdep_assert_held(&priv->mac_lock); -+ - return dpaa2_mac_is_type_phy(priv->mac); - } - - static inline bool dpaa2_eth_has_mac(struct dpaa2_eth_priv *priv) - { -+ lockdep_assert_held(&priv->mac_lock); -+ - return priv->mac ? true : false; - } - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -@@ -86,11 +86,16 @@ static void dpaa2_eth_get_drvinfo(struct - static int dpaa2_eth_nway_reset(struct net_device *net_dev) - { - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ int err = -EOPNOTSUPP; -+ -+ mutex_lock(&priv->mac_lock); - - if (dpaa2_eth_is_type_phy(priv)) -- return phylink_ethtool_nway_reset(priv->mac->phylink); -+ err = phylink_ethtool_nway_reset(priv->mac->phylink); -+ -+ mutex_unlock(&priv->mac_lock); - -- return -EOPNOTSUPP; -+ return err; - } - - static int -@@ -98,10 +103,18 @@ dpaa2_eth_get_link_ksettings(struct net_ - struct ethtool_link_ksettings *link_settings) - { - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ int err; - -- if (dpaa2_eth_is_type_phy(priv)) -- return phylink_ethtool_ksettings_get(priv->mac->phylink, -- link_settings); -+ mutex_lock(&priv->mac_lock); -+ -+ if (dpaa2_eth_is_type_phy(priv)) { -+ err = phylink_ethtool_ksettings_get(priv->mac->phylink, -+ link_settings); -+ mutex_unlock(&priv->mac_lock); -+ return err; -+ } -+ -+ mutex_unlock(&priv->mac_lock); - - link_settings->base.autoneg = AUTONEG_DISABLE; - if (!(priv->link_state.options & DPNI_LINK_OPT_HALF_DUPLEX)) -@@ -116,11 +129,17 @@ dpaa2_eth_set_link_ksettings(struct net_ - const struct ethtool_link_ksettings *link_settings) - { - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ int err = -EOPNOTSUPP; - -- if (!dpaa2_eth_is_type_phy(priv)) -- return -EOPNOTSUPP; -+ mutex_lock(&priv->mac_lock); -+ -+ if (dpaa2_eth_is_type_phy(priv)) -+ err = phylink_ethtool_ksettings_set(priv->mac->phylink, -+ link_settings); - -- return phylink_ethtool_ksettings_set(priv->mac->phylink, link_settings); -+ mutex_unlock(&priv->mac_lock); -+ -+ return err; - } - - static void dpaa2_eth_get_pauseparam(struct net_device *net_dev, -@@ -129,11 +148,16 @@ static void dpaa2_eth_get_pauseparam(str - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); - u64 link_options = priv->link_state.options; - -+ mutex_lock(&priv->mac_lock); -+ - if (dpaa2_eth_is_type_phy(priv)) { - phylink_ethtool_get_pauseparam(priv->mac->phylink, pause); -+ mutex_unlock(&priv->mac_lock); - return; - } - -+ mutex_unlock(&priv->mac_lock); -+ - pause->rx_pause = dpaa2_eth_rx_pause_enabled(link_options); - pause->tx_pause = dpaa2_eth_tx_pause_enabled(link_options); - pause->autoneg = AUTONEG_DISABLE; -@@ -152,9 +176,17 @@ static int dpaa2_eth_set_pauseparam(stru - return -EOPNOTSUPP; - } - -- if (dpaa2_eth_is_type_phy(priv)) -- return phylink_ethtool_set_pauseparam(priv->mac->phylink, -- pause); -+ mutex_lock(&priv->mac_lock); -+ -+ if (dpaa2_eth_is_type_phy(priv)) { -+ err = phylink_ethtool_set_pauseparam(priv->mac->phylink, -+ pause); -+ mutex_unlock(&priv->mac_lock); -+ return err; -+ } -+ -+ mutex_unlock(&priv->mac_lock); -+ - if (pause->autoneg) - return -EOPNOTSUPP; - -@@ -307,8 +339,12 @@ static void dpaa2_eth_get_ethtool_stats( - } - *(data + i++) = buf_cnt; - -+ mutex_lock(&priv->mac_lock); -+ - if (dpaa2_eth_has_mac(priv)) - dpaa2_mac_get_ethtool_stats(priv->mac, data + i); -+ -+ mutex_unlock(&priv->mac_lock); - } - - static int dpaa2_eth_prep_eth_rule(struct ethhdr *eth_value, struct ethhdr *eth_mask, diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch b/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch deleted file mode 100644 index abf127b15534aa..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0011-net-dpaa2-switch-serialize-changes-to-priv-mac-with.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 80d12452a5f160c39d63efc1be07df36f9d07133 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:20 +0200 -Subject: [PATCH 13/14] net: dpaa2-switch: serialize changes to priv->mac with - a mutex - -The dpaa2-switch driver uses a DPMAC in the same way as the dpaa2-eth -driver, so we need to duplicate the locking solution established by the -previous change to the switch driver as well. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - .../freescale/dpaa2/dpaa2-switch-ethtool.c | 32 +++++++++++++++---- - .../ethernet/freescale/dpaa2/dpaa2-switch.c | 31 ++++++++++++++++-- - .../ethernet/freescale/dpaa2/dpaa2-switch.h | 2 ++ - 3 files changed, 55 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c -@@ -60,11 +60,18 @@ dpaa2_switch_get_link_ksettings(struct n - { - struct ethsw_port_priv *port_priv = netdev_priv(netdev); - struct dpsw_link_state state = {0}; -- int err = 0; -+ int err; - -- if (dpaa2_switch_port_is_type_phy(port_priv)) -- return phylink_ethtool_ksettings_get(port_priv->mac->phylink, -- link_ksettings); -+ mutex_lock(&port_priv->mac_lock); -+ -+ if (dpaa2_switch_port_is_type_phy(port_priv)) { -+ err = phylink_ethtool_ksettings_get(port_priv->mac->phylink, -+ link_ksettings); -+ mutex_unlock(&port_priv->mac_lock); -+ return err; -+ } -+ -+ mutex_unlock(&port_priv->mac_lock); - - err = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0, - port_priv->ethsw_data->dpsw_handle, -@@ -99,9 +106,16 @@ dpaa2_switch_set_link_ksettings(struct n - bool if_running; - int err = 0, ret; - -- if (dpaa2_switch_port_is_type_phy(port_priv)) -- return phylink_ethtool_ksettings_set(port_priv->mac->phylink, -- link_ksettings); -+ mutex_lock(&port_priv->mac_lock); -+ -+ if (dpaa2_switch_port_is_type_phy(port_priv)) { -+ err = phylink_ethtool_ksettings_set(port_priv->mac->phylink, -+ link_ksettings); -+ mutex_unlock(&port_priv->mac_lock); -+ return err; -+ } -+ -+ mutex_unlock(&port_priv->mac_lock); - - /* Interface needs to be down to change link settings */ - if_running = netif_running(netdev); -@@ -189,8 +203,12 @@ static void dpaa2_switch_ethtool_get_sta - dpaa2_switch_ethtool_counters[i].name, err); - } - -+ mutex_lock(&port_priv->mac_lock); -+ - if (dpaa2_switch_port_has_mac(port_priv)) - dpaa2_mac_get_ethtool_stats(port_priv->mac, data + i); -+ -+ mutex_unlock(&port_priv->mac_lock); - } - - const struct ethtool_ops dpaa2_switch_port_ethtool_ops = { ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -@@ -603,8 +603,11 @@ static int dpaa2_switch_port_link_state_ - - /* When we manage the MAC/PHY using phylink there is no need - * to manually update the netif_carrier. -+ * We can avoid locking because we are called from the "link changed" -+ * IRQ handler, which is the same as the "endpoint changed" IRQ handler -+ * (the writer to port_priv->mac), so we cannot race with it. - */ -- if (dpaa2_switch_port_is_type_phy(port_priv)) -+ if (dpaa2_mac_is_type_phy(port_priv->mac)) - return 0; - - /* Interrupts are received even though no one issued an 'ifconfig up' -@@ -684,6 +687,8 @@ static int dpaa2_switch_port_open(struct - struct ethsw_core *ethsw = port_priv->ethsw_data; - int err; - -+ mutex_lock(&port_priv->mac_lock); -+ - if (!dpaa2_switch_port_is_type_phy(port_priv)) { - /* Explicitly set carrier off, otherwise - * netif_carrier_ok() will return true and cause 'ip link show' -@@ -697,6 +702,7 @@ static int dpaa2_switch_port_open(struct - port_priv->ethsw_data->dpsw_handle, - port_priv->idx); - if (err) { -+ mutex_unlock(&port_priv->mac_lock); - netdev_err(netdev, "dpsw_if_enable err %d\n", err); - return err; - } -@@ -706,6 +712,8 @@ static int dpaa2_switch_port_open(struct - if (dpaa2_switch_port_is_type_phy(port_priv)) - dpaa2_mac_start(port_priv->mac); - -+ mutex_unlock(&port_priv->mac_lock); -+ - return 0; - } - -@@ -715,6 +723,8 @@ static int dpaa2_switch_port_stop(struct - struct ethsw_core *ethsw = port_priv->ethsw_data; - int err; - -+ mutex_lock(&port_priv->mac_lock); -+ - if (dpaa2_switch_port_is_type_phy(port_priv)) { - dpaa2_mac_stop(port_priv->mac); - } else { -@@ -722,6 +732,8 @@ static int dpaa2_switch_port_stop(struct - netif_carrier_off(netdev); - } - -+ mutex_unlock(&port_priv->mac_lock); -+ - err = dpsw_if_disable(port_priv->ethsw_data->mc_io, 0, - port_priv->ethsw_data->dpsw_handle, - port_priv->idx); -@@ -1461,7 +1473,9 @@ static int dpaa2_switch_port_connect_mac - } - } - -+ mutex_lock(&port_priv->mac_lock); - port_priv->mac = mac; -+ mutex_unlock(&port_priv->mac_lock); - - return 0; - -@@ -1474,9 +1488,12 @@ err_free_mac: - - static void dpaa2_switch_port_disconnect_mac(struct ethsw_port_priv *port_priv) - { -- struct dpaa2_mac *mac = port_priv->mac; -+ struct dpaa2_mac *mac; - -+ mutex_lock(&port_priv->mac_lock); -+ mac = port_priv->mac; - port_priv->mac = NULL; -+ mutex_unlock(&port_priv->mac_lock); - - if (!mac) - return; -@@ -1495,6 +1512,7 @@ static irqreturn_t dpaa2_switch_irq0_han - struct ethsw_port_priv *port_priv; - u32 status = ~0; - int err, if_id; -+ bool had_mac; - - err = dpsw_get_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle, - DPSW_IRQ_INDEX_IF, &status); -@@ -1513,7 +1531,12 @@ static irqreturn_t dpaa2_switch_irq0_han - - if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) { - rtnl_lock(); -- if (dpaa2_switch_port_has_mac(port_priv)) -+ /* We can avoid locking because the "endpoint changed" IRQ -+ * handler is the only one who changes priv->mac at runtime, -+ * so we are not racing with anyone. -+ */ -+ had_mac = !!port_priv->mac; -+ if (had_mac) - dpaa2_switch_port_disconnect_mac(port_priv); - else - dpaa2_switch_port_connect_mac(port_priv); -@@ -3250,6 +3273,8 @@ static int dpaa2_switch_probe_port(struc - port_priv->netdev = port_netdev; - port_priv->ethsw_data = ethsw; - -+ mutex_init(&port_priv->mac_lock); -+ - port_priv->idx = port_idx; - port_priv->stp_state = BR_STATE_FORWARDING; - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h -@@ -161,6 +161,8 @@ struct ethsw_port_priv { - - struct dpaa2_switch_filter_block *filter_block; - struct dpaa2_mac *mac; -+ /* Protects against changes to port_priv->mac */ -+ struct mutex mac_lock; - }; - - /* Switch data */ diff --git a/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch b/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch deleted file mode 100644 index d71b85b45278ef..00000000000000 --- a/target/linux/armsr/patches-6.1/701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 4ea2faf5bb13d9ba9f07e996d495c4cbe34a4236 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 29 Nov 2022 16:12:21 +0200 -Subject: [PATCH 14/14] net: dpaa2-mac: move rtnl_lock() only around - phylink_{,dis}connect_phy() - -After the introduction of a private mac_lock that serializes access to -priv->mac (and port_priv->mac in the switch), the only remaining purpose -of rtnl_lock() is to satisfy the locking requirements of -phylink_fwnode_phy_connect() and phylink_disconnect_phy(). - -But the functions these live in, dpaa2_mac_connect() and -dpaa2_mac_disconnect(), have contradictory locking requirements. -While phylink_fwnode_phy_connect() wants rtnl_lock() to be held, -phylink_create() wants it to not be held. - -Move the rtnl_lock() from top-level (in the dpaa2-eth and dpaa2-switch -drivers) to only surround the phylink calls that require it, in the -dpaa2-mac library code. - -This is possible because dpaa2_mac_connect() and dpaa2_mac_disconnect() -run unlocked, and there isn't any danger of an AB/BA deadlock between -the rtnl_mutex and other private locks. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Ioana Ciornei -Tested-by: Ioana Ciornei -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 5 +++++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 4 ---- - 3 files changed, 5 insertions(+), 8 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -4534,7 +4534,6 @@ static irqreturn_t dpni_irq0_handler_thr - dpaa2_eth_set_mac_addr(netdev_priv(net_dev)); - dpaa2_eth_update_tx_fqids(priv); - -- rtnl_lock(); - /* We can avoid locking because the "endpoint changed" IRQ - * handler is the only one who changes priv->mac at runtime, - * so we are not racing with anyone. -@@ -4544,7 +4543,6 @@ static irqreturn_t dpni_irq0_handler_thr - dpaa2_eth_disconnect_mac(priv); - else - dpaa2_eth_connect_mac(priv); -- rtnl_unlock(); - } - - return IRQ_HANDLED; -@@ -4863,9 +4861,7 @@ static int dpaa2_eth_remove(struct fsl_m - else - fsl_mc_free_irqs(ls_dev); - -- rtnl_lock(); - dpaa2_eth_disconnect_mac(priv); -- rtnl_unlock(); - dpaa2_eth_free_rings(priv); - free_percpu(priv->fd); - free_percpu(priv->sgt_cache); ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c -@@ -428,7 +428,9 @@ int dpaa2_mac_connect(struct dpaa2_mac * - } - mac->phylink = phylink; - -+ rtnl_lock(); - err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0); -+ rtnl_unlock(); - if (err) { - netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err); - goto err_phylink_destroy; -@@ -446,7 +448,10 @@ err_pcs_destroy: - - void dpaa2_mac_disconnect(struct dpaa2_mac *mac) - { -+ rtnl_lock(); - phylink_disconnect_phy(mac->phylink); -+ rtnl_unlock(); -+ - phylink_destroy(mac->phylink); - dpaa2_pcs_destroy(mac); - of_phy_put(mac->serdes_phy); ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c -@@ -1530,7 +1530,6 @@ static irqreturn_t dpaa2_switch_irq0_han - } - - if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) { -- rtnl_lock(); - /* We can avoid locking because the "endpoint changed" IRQ - * handler is the only one who changes priv->mac at runtime, - * so we are not racing with anyone. -@@ -1540,7 +1539,6 @@ static irqreturn_t dpaa2_switch_irq0_han - dpaa2_switch_port_disconnect_mac(port_priv); - else - dpaa2_switch_port_connect_mac(port_priv); -- rtnl_unlock(); - } - - out: -@@ -2952,9 +2950,7 @@ static void dpaa2_switch_remove_port(str - { - struct ethsw_port_priv *port_priv = ethsw->ports[port_idx]; - -- rtnl_lock(); - dpaa2_switch_port_disconnect_mac(port_priv); -- rtnl_unlock(); - free_netdev(port_priv->netdev); - ethsw->ports[port_idx] = NULL; - } From 97e1a223fd2349582ca1c043e55ee1175bd968a9 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 20 Sep 2024 18:53:46 +0100 Subject: [PATCH 16/23] kirkwood: remove left-over files-6.1 folder Remove folder with DTS files for Linux 6.1 which has already been dropped. Fixes: f142ce87d9 ("kirkwood: remove 6.1 support") Signed-off-by: Daniel Golle --- .../arch/arm/boot/dts/kirkwood-dns320l.dts | 202 --------------- .../arch/arm/boot/dts/kirkwood-e4200-v2.dts | 8 - .../arch/arm/boot/dts/kirkwood-ea3500.dts | 243 ------------------ .../arch/arm/boot/dts/kirkwood-ea4500.dts | 8 - .../arch/arm/boot/dts/kirkwood-goflexhome.dts | 135 ---------- .../arch/arm/boot/dts/kirkwood-ix4-200d.dts | 199 -------------- .../arch/arm/boot/dts/kirkwood-nas1.dts | 234 ----------------- .../arch/arm/boot/dts/kirkwood-nsa310b.dts | 144 ----------- .../arch/arm/boot/dts/kirkwood-on100.dts | 165 ------------ .../arch/arm/boot/dts/kirkwood-stora.dts | 227 ---------------- 10 files changed, 1565 deletions(-) delete mode 100644 target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-dns320l.dts delete mode 100644 target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-e4200-v2.dts delete mode 100644 target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea3500.dts delete mode 100644 target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea4500.dts delete mode 100644 target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-goflexhome.dts delete mode 100644 target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ix4-200d.dts delete mode 100644 target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nas1.dts delete mode 100644 target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts delete mode 100644 target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-on100.dts delete mode 100644 target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-stora.dts diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-dns320l.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-dns320l.dts deleted file mode 100644 index afeb76d5ffe39b..00000000000000 --- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-dns320l.dts +++ /dev/null @@ -1,202 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Device Tree file for DLINK DNS-320L - * - * Copyright (C) 2024, Zoltan HERPAI - * Copyright (C) 2015, Sunke Schlüters - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * This file is based on the works of: - * - Sunke Schlüters - * - https://github.com/scus1/dns320l/blob/master/kernel/dts/kirkwood-dns320l.dts - * - Andreas Böhler : - * - http://www.aboehler.at/doku/doku.php/projects:dns320l - * - http://www.aboehler.at/hg/linux-dns320l/file/ba7a60ad7687/linux-3.12/kirkwood-dns320l.dts - */ - -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6281.dtsi" - -/ { - model = "D-Link DNS-320L"; - compatible = "dlink,dns320l", "marvell,kirkwood-88f6702", "marvell,kirkwood"; - - memory { - device_type = "memory"; - reg = <0x00000000 0x10000000>; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - stdout-path = &uart0; - }; - - gpio-keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_buttons>; - pinctrl-names = "default"; - - button@1 { - label = "Reset push button"; - linux,code = ; - gpios = <&gpio0 28 1>; - }; - - button@2 { - label = "USB unmount button"; - linux,code = ; - gpios = <&gpio0 27 1>; - }; - }; - - gpio-leds { - compatible = "gpio-leds"; - pinctrl-0 = <&pmx_leds>; - pinctrl-names = "default"; - - blue-usb { - label = "dns320l:usb:blue"; - gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "usbport"; - }; - - orange-usb { - label = "dns320l:usb:orange"; - gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>; - }; - - orange-l-hdd { - label = "dns320l:orange:l_hdd"; - gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; - }; - - orange-r-hdd { - label = "dns320l:orange:r_hdd"; - gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>; - }; - }; - - ocp@f1000000 { - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - - serial@12000 { - status = "okay"; - }; - - serial@12100 { - pinctrl-0 = <&pmx_uart1>; - pinctrl-names = "default"; - status = "okay"; - }; - }; - - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_sata>; - pinctrl-names = "default"; - - sata_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "SATA Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpios = <&gpio0 24 0>; - }; - }; -}; - -&nand { - pinctrl-0 = <&pmx_nand>; - pinctrl-names = "default"; - chip-delay = <40>; - status = "okay"; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x100000>; - }; - - partition@100000 { - label = "ubootenv"; - reg = <0x100000 0x20000>; - }; - - partition@120000 { - label = "ubi"; - reg = <0x120000 0x6de0000>; - }; - - partition@6f00000 { - label = "mini firmware"; - reg = <0x6f00000 0xa00000>; - }; - - partition@7900000 { - label = "config"; - reg = <0x7900000 0x500000>; - }; - - partition@7e00000 { - label = "my-dlink"; - reg = <0x7e00000 0x200000>; - }; -}; - -&mdio { - status = "okay"; - - ethphy0: ethernet-phy@0 { - reg = <0>; - }; -}; - -&pinctrl { - pmx_sata1: pmx-sata1 { - marvell,pins = "mpp20"; - marvell,function = "sata1"; - }; - - pmx_sata0: pmx-sata0 { - marvell,pins = "mpp21"; - marvell,function = "sata0"; - }; - - pmx_power_sata: pmx-power-sata { - marvell,pins = "mpp24"; - marvell,function = "gpio"; - }; - - pmx_leds: pmx-leds { - marvell,pins = "mpp22", "mpp23", "mpp25", "mpp26"; - marvell,function = "gpio"; - }; - - pmx_buttons: pmx-buttons { - marvell,pins = "mpp27", "mpp28", "mpp29"; - marvell,function = "gpio"; - }; -}; - -ð0 { - status = "okay"; - ethernet0-port@0 { - phy-handle = <ðphy0>; - }; -}; diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-e4200-v2.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-e4200-v2.dts deleted file mode 100644 index bfd708a677c96a..00000000000000 --- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-e4200-v2.dts +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT - -#include "kirkwood-linksys-viper.dts" - -/ { - model = "Linksys E4200 v2 (Viper)"; - compatible = "linksys,e4200-v2", "linksys,viper", "marvell,kirkwood-88f6282", "marvell,kirkwood"; -}; diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea3500.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea3500.dts deleted file mode 100644 index e9f9e30bb4c071..00000000000000 --- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea3500.dts +++ /dev/null @@ -1,243 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * kirkwood-linksys-audi.dts - Device Tree file for Linksys EA3500 - * - * (c) 2013 Jonas Gorski - * (c) 2013 Deutsche Telekom Innovation Laboratories - * (c) 2014 Luka Perkov - * (c) 2014 Dan Walters - * - */ - -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6282.dtsi" - -/ { - model = "Linksys EA3500 (Audi)"; - compatible = "linksys,ea3500", "linksys,audi", "marvell,kirkwood-88f6282", "marvell,kirkwood"; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x4000000>; - }; - - aliases { - led-boot = &led_power; - led-failsafe = &led_power; - led-running = &led_power; - led-upgrade = &led_power; - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - gpio-keys { - compatible = "gpio-keys"; - - pinctrl-0 = <&pmx_btn_wps &pmx_btn_reset>; - pinctrl-names = "default"; - - wps { - label = "WPS Button"; - linux,code = ; - gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; - }; - - reset { - label = "Reset Button"; - linux,code = ; - gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; - }; - }; - - gpio-leds { - compatible = "gpio-leds"; - - pinctrl-0 = <&pmx_led_green_power>; - pinctrl-names = "default"; - - led_power: power { - label = "audi:green:power"; - gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - }; -}; - -&pinctrl { - pmx_led_green_power: pmx-led-green-power { - marvell,pins = "mpp7"; - marvell,function = "gpo"; - }; - - pmx_btn_wps: pmx-btn-wps { - marvell,pins = "mpp47"; - marvell,function = "gpio"; - }; - - pmx_btn_reset: pmx-btn-reset { - marvell,pins = "mpp48"; - marvell,function = "gpio"; - }; -}; - -&mdio { - status = "okay"; - - switch@10 { - compatible = "marvell,mv88e6085"; - #address-cells = <1>; - #size-cells = <0>; - reg = <16>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - label = "ethernet1"; - }; - - port@1 { - reg = <1>; - label = "ethernet2"; - }; - - port@2 { - reg = <2>; - label = "ethernet3"; - }; - - port@3 { - reg = <3>; - label = "ethernet4"; - }; - - port@4 { - reg = <4>; - label = "internet"; - }; - - port@5 { - reg = <5>; - phy-mode = "rgmii-id"; - ethernet = <ð0port>; - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - }; - }; -}; - -&nand { - status = "okay"; - - pinctrl-0 = <&pmx_nand>; - pinctrl-names = "default"; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "u-boot"; - reg = <0x0 0x80000>; - read-only; - }; - - partition@80000 { - label = "u_env"; - reg = <0x80000 0x4000>; - }; - - partition@84000 { - label = "s_env"; - reg = <0x84000 0x4000>; - }; - - partition@200000 { - label = "kernel1"; - reg = <0x200000 0x1400000>; - }; - - partition@600000 { - label = "rootfs1"; - reg = <0x600000 0x1000000>; - }; - - partition@1600000 { - label = "kernel2"; - reg = <0x1600000 0x1400000>; - }; - - partition@1a00000 { - label = "rootfs2"; - reg = <0x1a00000 0x1000000>; - }; - - partition@2a00000 { - label = "syscfg"; - reg = <0x2a00000 0x1600000>; - }; - - partition@88000 { - label = "unused"; - reg = <0x88000 0x178000>; - }; - }; -}; - -&pciec { - status = "okay"; -}; - -&pcie0 { - status = "okay"; -}; - -&pcie1 { - status = "okay"; -}; - -&mdio { - status = "okay"; -}; - -&uart0 { - status = "okay"; -}; - -/* eth0 is connected to a Marvell 88E6171 switch, without a PHY. So set - * fixed speed and duplex. - */ -ð0 { - status = "okay"; - - ethernet0-port@0 { - speed = <1000>; - duplex = <1>; - phy-mode = "rgmii"; - }; -}; - -/* eth1 is connected to the switch at port 6. However DSA only supports a - * single CPU port. This port is disabled to avoid confusion. - */ -ð1 { - status = "disabled"; -}; - -/* There is no battery on the board, so the RTC does not keep - * time when there is no power, making it useless. - */ -&rtc { - status = "disabled"; -}; diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea4500.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea4500.dts deleted file mode 100644 index 495cff34a43e7e..00000000000000 --- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ea4500.dts +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT - -#include "kirkwood-linksys-viper.dts" - -/ { - model = "Linksys EA4500 (Viper)"; - compatible = "linksys,ea4500", "linksys,viper", "marvell,kirkwood-88f6282", "marvell,kirkwood"; -}; diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-goflexhome.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-goflexhome.dts deleted file mode 100644 index 2f4109fe63eac3..00000000000000 --- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-goflexhome.dts +++ /dev/null @@ -1,135 +0,0 @@ -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6281.dtsi" - -/ { - model = "Seagate GoFlex Home"; - compatible = "seagate,goflexhome", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - aliases { - led-boot = &led_health; - led-failsafe = &led_fault; - led-running = &led_health; - led-upgrade = &led_fault; - }; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x8000000>; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/sda1 rootdelay=10"; - stdout-path = &uart0; - }; - - ocp@f1000000 { - pinctrl: pin-controller@10000 { - pmx_usb_power_enable: pmx-usb-power-enable { - marvell,pins = "mpp29"; - marvell,function = "gpio"; - }; - - pmx_led_white: pmx-led-white { - marvell,pins = "mpp40"; - marvell,function = "gpio"; - }; - - pmx_led_green: pmx-led_green { - marvell,pins = "mpp46"; - marvell,function = "gpio"; - }; - - pmx_led_orange: pmx-led-orange { - marvell,pins = "mpp47"; - marvell,function = "gpio"; - }; - }; - - serial@12000 { - status = "okay"; - }; - - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - }; - - gpio-leds { - compatible = "gpio-leds"; - - led_health: health { - label = "status:green:health"; - gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; - default-state = "on"; - }; - - led_fault: fault { - label = "status:orange:fault"; - gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; - }; - - misc { - label = "status:white:misc"; - gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; - linux,default-trigger = "disk-activity"; - }; - }; - - regulators { - compatible = "simple-bus"; - - #address-cells = <1>; - #size-cells = <0>; - - pinctrl-0 = <&pmx_usb_power_enable>; - pinctrl-names = "default"; - - usb_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; - }; - }; -}; - -&nand { - status = "okay"; - - chip-delay = <40>; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x0100000>; - read-only; - }; - - partition@100000 { - label = "ubi"; - reg = <0x0100000 0xff00000>; - }; -}; - -&mdio { - status = "okay"; - - ethphy0: ethernet-phy@0 { - reg = <0>; - }; -}; - -ð0 { - status = "okay"; - - ethernet0-port@0 { - phy-handle = <ðphy0>; - }; -}; diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ix4-200d.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ix4-200d.dts deleted file mode 100644 index 6220fbf13759be..00000000000000 --- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-ix4-200d.dts +++ /dev/null @@ -1,199 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6281.dtsi" -#include - -/ { - model = "Iomega ix4-200d"; - compatible = "iom,ix4-200d", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - aliases { - led-boot = &led_status_white; - led-failsafe = &led_status_red; - led-running = &led_power_white; - led-upgrade = &led_status_red; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - stdout-path = &uart0; - }; - - memory { - device_type = "memory"; - reg = <0x00000000 0x20000000>; - }; - - ocp@f1000000 { - i2c@11000 { - status = "okay"; - - adt7473@2e { - compatible = "adi,adt7473"; - reg = <0x2e>; - }; - }; - - pinctrl: pin-controller@10000 { - pmx_spi: pmx-spi { - marvell,pins = "mpp12", "mpp13", "mpp14"; - marvell,function = "gpio"; - }; - - pmx_keys: pmx-keys { - marvell,pins = "mpp16", "mpp29", "mpp47", "mpp49"; - marvell,function = "gpio"; - }; - }; - - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - - serial@12000 { - status = "okay"; - }; - - spi3 { - compatible = "spi-gpio"; - #address-cells = <0x1>; - ranges; - status = "okay"; - sck-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; - mosi-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; - cs-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; - num-chipselects = <1>; - #size-cells = <0>; - - gpio_spi: gpio_spi@0 { - compatible = "fairchild,74hc595"; - reg = <0>; - gpio-controller; - #gpio-cells = <2>; - registers-number = <1>; - spi-max-frequency = <100000>; - }; - }; - - gpio-keys { - compatible = "gpio-keys"; - pinctrl-0 = <&pmx_keys>; - pinctrl-names = "default"; - - button-0 { - label = "Next Button"; - linux,code = ; - gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; - }; - - button-1 { - label = "Reset Button"; - linux,code = ; - gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; - }; - - button-2 { - label = "Cancel Button"; - linux,code = ; - gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; - }; - - button-3 { - label = "Power Button"; - linux,code = ; - gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; - }; - }; - - gpio-leds { - compatible = "gpio-leds"; - - led_status_white: led-0 { - function = LED_FUNCTION_STATUS; - color = ; - gpios = <&gpio_spi 4 GPIO_ACTIVE_LOW>; - }; - - led_status_red: led-1 { - function = LED_FUNCTION_STATUS; - color = ; - gpios = <&gpio_spi 5 GPIO_ACTIVE_LOW>; - }; - - led_power_white: led-2 { - function = LED_FUNCTION_POWER; - color = ; - gpios = <&gpio_spi 7 GPIO_ACTIVE_HIGH>; - }; - }; - }; -}; - -ð0 { - status = "okay"; - ethernet0-port@0 { - phy-handle = <ðphy0>; - }; -}; - -ð1 { - status = "okay"; - ethernet1-port@0 { - phy-handle = <ðphy1>; - }; -}; - -&mdio { - status = "okay"; - - ethphy0: ethernet-phy@8 { - reg = <8>; - }; - - ethphy1: ethernet-phy@9 { - reg = <9>; - }; -}; - -&nand { - status = "okay"; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x100000>; - read-only; - }; - - partition@a0000 { - label = "u-boot environment"; - reg = <0xa0000 0x20000>; - read-only; - }; - - partition@100000 { - label = "kernel"; - reg = <0x100000 0x400000>; - }; - - partition@500000 { - label = "ubi"; - reg = <0x500000 0x1B00000>; - }; - }; -}; - -&pciec { - status = "okay"; -}; - -&pcie0 { - status = "okay"; -}; diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nas1.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nas1.dts deleted file mode 100644 index 0ceddb0d64ca65..00000000000000 --- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nas1.dts +++ /dev/null @@ -1,234 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT -/dts-v1/; - -#include - -#include "kirkwood.dtsi" -#include "kirkwood-6281.dtsi" - -/ { - model = "ipTIME NAS1"; - compatible = "iptime,nas1", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - aliases { - serial0 = &uart0; - led-boot = &led_ready; - led-failsafe = &led_ready; - led-running = &led_ready; - led-upgrade = &led_ready; - }; - - chosen { - /* - * "root" argument from the stock bootloader should be ignored - * as it'll prevent the kernel from finding the correct rootfs. - */ - bootargs-append = " console=ttyS0,115200 root="; - stdout-path = "serial0:115200n8"; - }; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x10000000>; - }; - - gpio-leds { - compatible = "gpio-leds"; - - pinctrl-0 = <&pmx_led>; - pinctrl-names = "default"; - - hdd { - label = "blue:hdd"; - gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "ata1"; - }; - - usb { - function = LED_FUNCTION_USB; - color = ; - gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; - trigger-sources = <&ehci_port1>; - linux,default-trigger = "usbport"; - }; - - led_ready: ready { - label = "blue:ready"; - gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; - }; - }; - - gpio-keys { - compatible = "gpio-keys"; - - pinctrl-0 = <&pmx_button>; - pinctrl-names = "default"; - - reset-copy { - label = "Reset/Copy Button"; - linux,code = ; - gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; - }; - - power { - label = "Power Button"; - linux,code = ; - gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>; - }; - }; - - gpio-fan { - compatible = "gpio-fan"; - - pinctrl-0 = <&pmx_fan>; - pinctrl-names = "default"; - gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>, - <&gpio1 10 GPIO_ACTIVE_HIGH>; - /* We don't know the exact rpm, just use dummy values here. */ - gpio-fan,speed-map = <0 0>, <1 1>, <2 2>; - #cooling-cells = <2>; - }; - - gpio-poweroff { - compatible = "gpio-poweroff"; - gpios = <&pca9536 0 GPIO_ACTIVE_LOW>; - }; - - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - pinctrl-0 = <&pmx_usb_vbus>; - pinctrl-names = "default"; - - regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; - }; - }; -}; - -&pinctrl { - pmx_led: pmx-led { - marvell,pins = "mpp35", "mpp45", "mpp46"; - marvell,function = "gpio"; - }; - - pmx_fan: pmx-fan { - marvell,pins = "mpp41", "mpp42"; - marvell,function = "gpio"; - }; - - pmx_usb_vbus: pmx-usb-vbus { - marvell,pins = "mpp43"; - marvell,function = "gpio"; - }; - - pmx_button: pmx-button { - marvell,pins = "mpp44", "mpp48"; - marvell,function = "gpio"; - }; -}; - -&spi0 { - status = "okay"; - - flash@0 { - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <20000000>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "u-boot"; - reg = <0x0 0x40000>; - read-only; - }; - - partition@40000 { - compatible = "openwrt,uimage", "denx,uimage"; - openwrt,offset = <0x400>; - label = "firmware"; - reg = <0x40000 0xf80000>; - }; - - partition@fc0000 { - label = "config"; - reg = <0xfc0000 0x40000>; - read-only; - }; - }; - }; -}; - -&rtc { - status = "disabled"; -}; - -&i2c0 { - status = "okay"; - - pca9536: gpio@41 { - compatible = "nxp,pca9536"; - reg = <0x41>; - gpio-controller; - #gpio-cells = <2>; - }; -}; - -&uart0 { - status = "okay"; -}; - -&usb0 { - status = "okay"; - - #address-cells = <1>; - #size-cells = <0>; - - ehci_port1: port@1 { - reg = <1>; - #trigger-source-cells = <0>; - }; -}; - -&mdio { - status = "okay"; - - ethphyb: ethernet-phy@b { - reg = <0x0b>; - }; -}; - -ð1 { - status = "okay"; -}; - -ð1port { - phy-handle = <ðphyb>; - phy-connection-type = "rgmii-id"; -}; - -&sata { - status = "okay"; - - #address-cells = <1>; - #size-cells = <0>; - nr-ports = <1>; - - sata-port@0 { - reg = <0>; - #thermal-sensor-cells = <0>; - }; -}; diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts deleted file mode 100644 index 594be97929d27f..00000000000000 --- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-nsa310b.dts +++ /dev/null @@ -1,144 +0,0 @@ -/dts-v1/; - -#include "kirkwood-nsa3x0-common.dtsi" - -/* - * There are at least two different NSA310 designs. This variant has - * a red/green USB Led (same as nsa310) and a lm85 temp/fan controller. - */ - -/ { - model = "Zyxel NSA310b"; - compatible = "zyxel,nsa310b", "zyxel,nsa310", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - aliases { - led-boot = &led_green_sys; - led-failsafe = &led_red_sys; - led-running = &led_green_sys; - led-upgrade = &led_red_sys; - }; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x10000000>; - }; - - chosen { - bootargs = "console=ttyS0,115200"; - stdout-path = &uart0; - }; - - ocp@f1000000 { - pinctrl: pin-controller@10000 { - pinctrl-names = "default"; - - pmx_led_esata_green: pmx-led-esata-green { - marvell,pins = "mpp12"; - marvell,function = "gpio"; - }; - - pmx_led_esata_red: pmx-led-esata-red { - marvell,pins = "mpp13"; - marvell,function = "gpio"; - }; - - pmx_led_usb_green: pmx-led-usb-green { - marvell,pins = "mpp15"; - marvell,function = "gpio"; - }; - - pmx_led_usb_red: pmx-led-usb-red { - marvell,pins = "mpp16"; - marvell,function = "gpio"; - }; - - pmx_led_sys_green: pmx-led-sys-green { - marvell,pins = "mpp28"; - marvell,function = "gpio"; - }; - - pmx_led_sys_red: pmx-led-sys-red { - marvell,pins = "mpp29"; - marvell,function = "gpio"; - }; - - pmx_led_hdd_green: pmx-led-hdd-green { - marvell,pins = "mpp41"; - marvell,function = "gpio"; - }; - - pmx_led_hdd_red: pmx-led-hdd-red { - marvell,pins = "mpp42"; - marvell,function = "gpio"; - }; - - }; - - i2c@11000 { - status = "okay"; - - lm85: lm85@2e { - compatible = "national,lm85"; - reg = <0x2e>; - }; - }; - }; - - gpio-leds { - compatible = "gpio-leds"; - - led_green_sys: green-sys { - label = "nsa310:green:sys"; - gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - - led_red_sys: red-sys { - label = "nsa310:red:sys"; - gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>; - }; - - green-hdd { - label = "nsa310:green:hdd"; - gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "ata1"; - }; - - red-hdd { - label = "nsa310:red:hdd"; - gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; - }; - - green-esata { - label = "nsa310:green:esata"; - gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "ata2"; - }; - - red-esata { - label = "nsa310:red:esata"; - gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; - }; - - green-usb { - label = "nsa310:green:usb"; - gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "usb-host"; - }; - - red-usb { - label = "nsa310:red:usb"; - gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>; - }; - - green-copy { - label = "nsa310:green:copy"; - gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; - }; - - red-copy { - label = "nsa310:red:copy"; - gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; - }; - }; -}; diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-on100.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-on100.dts deleted file mode 100644 index 5ae66ede2f97c8..00000000000000 --- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-on100.dts +++ /dev/null @@ -1,165 +0,0 @@ -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6282.dtsi" - -/ { - model = "Cisco Systems ON100"; - compatible = "cisco,on100", "marvell,kirkwood-88f6282", "marvell,kirkwood"; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x20000000>; - }; - - aliases { - led-boot = &led_health_green; - led-failsafe = &led_health_red; - led-running = &led_health_green; - led-upgrade = &led_health_red; - serial0 = &uart0; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - stdout-path = "serial0:115200n8"; - }; - - gpio-keys { - compatible = "gpio-keys"; - - pinctrl-0 = <&pmx_btn_reset>; - pinctrl-names = "default"; - - reset { - label = "Reset Button"; - linux,code = ; - gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; - }; - }; - - gpio-leds { - compatible = "gpio-leds"; - - pinctrl-0 = <&pmx_led_health_red &pmx_led_health_green>; - pinctrl-names = "default"; - - led_health_green: health-green { - label = "on100:green:health"; - gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; - default-state = "on"; - }; - - led_health_red: health-red { - label = "on100:red:health"; - gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; - }; - - health2-green { - label = "on100:green:health2"; - gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; - }; - - health2-red { - label = "on100:red:health2"; - gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; - }; - }; -}; - -ð0 { - status = "okay"; - - ethernet0-port@0 { - phy-handle = <ðphy0>; - phy-connection-type = "rgmii-id"; - }; -}; - -ð1 { - status = "okay"; - - ethernet1-port@0 { - phy-handle = <ðphy1>; - phy-connection-type = "rgmii-id"; - }; -}; - -&mdio { - status = "okay"; - - ethphy0: ethernet-phy@0 { - /* Marvell 88E1121R */ - compatible = "ethernet-phy-id0141.0cb0", - "ethernet-phy-ieee802.3-c22"; - reg = <0>; - }; - - ethphy1: ethernet-phy@1 { - /* Marvell 88E1121R */ - compatible = "ethernet-phy-id0141.0cb0", - "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; -}; - -&nand { - status = "okay"; - - partition@0 { - label = "u-boot"; - reg = <0x00000000 0x000a0000>; - read-only; - }; - - partition@a0000 { - label = "u-boot environment"; - reg = <0x000a0000 0x00020000>; - read-only; - }; - - partition@c0000 { - label = "kernel"; - reg = <0x000c0000 0x00540000>; - }; - - partition@600000 { - label = "ubi"; - reg = <0x00600000 0x1fa00000>; - }; -}; - -&pinctrl { - pmx_led_health_red: pmx-led-health-red { - marvell,pins = "mpp45"; - marvell,function = "gpio"; - }; - - pmx_led_health_green: pmx-led-health-green { - marvell,pins = "mpp44"; - marvell,function = "gpio"; - }; - - pmx_led_health2_red: pmx-led-health2-red { - marvell,pins = "mpp47"; - marvell,function = "gpio"; - }; - - pmx_led_health2_green: pmx-led-health2-green { - marvell,pins = "mpp46"; - marvell,function = "gpio"; - }; - - pmx_btn_reset: pmx-btn-reset { - marvell,pins = "mpp31"; - marvell,function = "gpio"; - }; -}; - -&sdio { - status = "okay"; -}; - -&uart0 { - status = "okay"; -}; diff --git a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-stora.dts b/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-stora.dts deleted file mode 100644 index 577c009144693c..00000000000000 --- a/target/linux/kirkwood/files-6.1/arch/arm/boot/dts/kirkwood-stora.dts +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Device Tree file for NETGEAR Stora (MS2000/2110) - * - * Copyright (C) 2013, Arnaud EBALARD - * Copyright (C) 2021, Zoltan HERPAI - */ - -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6281.dtsi" - -/ { - model = "NETGEAR Stora (MS2000/2110)"; - compatible = "netgear,stora", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - memory { /* 128 MB */ - device_type = "memory"; - reg = <0x00000000 0x8000000>; - }; - - aliases { - led-boot = &led_power; - led-failsafe = &led_power; - led-running = &led_power; - led-upgrade = &led_power; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - stdout-path = &uart0; - }; - - ocp@f1000000 { - pinctrl: pin-controller@10000 { - pmx_button_power: pmx-button-power { - marvell,pins = "mpp36"; - marvell,function = "gpio"; - }; - - pmx_button_reset: pmx-button-reset { - marvell,pins = "mpp38"; - marvell,function = "gpio"; - }; - - pmx_led_blue_power: pmx-led-blue-power { - marvell,pins = "mpp31"; - marvell,function = "gpio"; - }; - - pmx_led_green_disk1: pmx-led-green-disk1 { - marvell,pins = "mpp21"; - marvell,function = "gpio"; - }; - - pmx_led_green_disk2: pmx-led-green-disk2 { - marvell,pins = "mpp20"; - marvell,function = "gpio"; - }; - - pmx_led_red_disk1: pmx-led-red-disk1 { - marvell,pins = "mpp23"; - marvell,function = "gpio"; - }; - - pmx_led_red_disk2: pmx-led-red-disk2 { - marvell,pins = "mpp22"; - marvell,function = "gpio"; - }; - - pmx_poweroff: pmx-poweroff { - marvell,pins = "mpp40"; - marvell,function = "gpio"; - }; - - pmx_fan_tacho: pmx-fan-tacho { - marvell,pins = "mpp41"; - marvell,function = "gpio"; - }; - }; - - clocks { - pcf8563_clk: pcf8563-oscillator { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <2048>; - }; - }; - - i2c@11000 { - status = "okay"; - - tc654@1b { - compatible = "microchip,tc654"; - reg = <0x1b>; - }; - - lm75@48 { - compatible = "national,lm75"; - reg = <0x48>; - }; - - pcf8563@51 { - compatible = "nxp,pcf8563"; - reg = <0x51>; - }; - }; - - serial@12000 { - status = "okay"; - }; - - sata@80000 { - status = "okay"; - phy-names = "port0", "port1"; - nr-ports = <2>; - }; - }; - - gpio-leds { - compatible = "gpio-leds"; - pinctrl-0 = < &pmx_led_blue_power - &pmx_led_green_disk1 &pmx_led_green_disk2 - &pmx_led_red_disk1 &pmx_led_red_disk2 >; - pinctrl-names = "default"; - - led_power: power { - label = "blue:power"; - gpios = <&gpio0 31 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-on"; - }; - - disk1 { - label = "green:disk1"; - gpios = <&gpio0 21 GPIO_ACTIVE_LOW>; - linux,default-trigger = "ata1"; - }; - - disk2 { - label = "green:disk2"; - gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; - linux,default-trigger = "ata2"; - }; - - disk1_fail { - label = "red:disk1_fail"; - gpios = <&gpio0 23 GPIO_ACTIVE_LOW>; - }; - - disk2_fail { - label = "red:disk2_fail"; - gpios = <&gpio0 22 GPIO_ACTIVE_LOW>; - }; - }; - - gpio-keys { - compatible = "gpio-keys"; - pinctrl-0 = <&pmx_button_power &pmx_button_reset >; - pinctrl-names = "default"; - - power { - label = "Power Button"; - linux,code = ; - gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; - }; - - reset { - label = "Reset Button"; - linux,code = ; - gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; - }; - }; - - gpio-poweroff { - compatible = "gpio-poweroff"; - pinctrl-0 = <&pmx_poweroff>; - pinctrl-names = "default"; - gpios = <&gpio0 40 GPIO_ACTIVE_LOW>; - }; -}; - -&nand { - status = "okay"; - chip-delay = <40>; - - partition@0 { - label = "u-boot"; - reg = <0x0000000 0x0e0000>; - read-only; - }; - - partition@e0000 { - label = "u-boot-env"; - reg = <0x0e00000 0x020000>; - }; - - partition@100000 { - label = "ubi"; - reg = <0x0100000 0xff00000>; - }; -}; - -&mdio { - status = "okay"; - - ethphy0: ethernet-phy@0 { /* Marvell 88E1318 */ - compatible = "marvell,88e1116"; - reg = <8>; - }; -}; - -ð0 { - status = "okay"; - - ethernet0-port@0 { - phy-handle = <ðphy0>; - }; -}; - -&pciec { - status = "okay"; -}; - -&pcie0 { - status = "okay"; -}; From 3f01b2914652a5f389ea95e7d1936dde6b66f73e Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 20 Sep 2024 18:55:32 +0100 Subject: [PATCH 17/23] generic: drop 6.1 support Drop config and files for Linux 6.1. Signed-off-by: Daniel Golle --- ...i-gen-LRU-rename-lru_gen_struct-to-l.patch | 352 - ...i-gen-LRU-remove-eviction-fairness-s.patch | 192 - ...i-gen-LRU-remove-aging-fairness-safe.patch | 294 - ...lti-gen-LRU-shuffle-should_run_aging.patch | 166 - ...i-gen-LRU-per-node-lru_gen_folio-lis.patch | 876 -- ...i-gen-LRU-clarify-scan_control-flags.patch | 202 - ...i-gen-LRU-simplify-arch_has_hw_pte_y.patch | 38 - ...m-multi-gen-LRU-avoid-futile-retries.patch | 92 - ...3-10-UPSTREAM-mm-add-vma_has_recency.patch | 191 - ...STREAM-mm-support-POSIX_FADV_NOREUSE.patch | 129 - ...i-gen-LRU-section-for-working-set-pr.patch | 67 - ...i-gen-LRU-section-for-rmap-PT-walk-f.patch | 57 - ...ti-gen-LRU-section-for-Bloom-filters.patch | 243 - ...-multi-gen-LRU-section-for-memcg-LRU.patch | 427 - ...i-gen-LRU-improve-lru_gen_exit_memcg.patch | 40 - ...multi-gen-LRU-improve-walk_pmd_range.patch | 135 - ...i-gen-LRU-simplify-lru_gen_look_arou.patch | 148 - ...i-gen-LRU-remove-wait_event_killable.patch | 273 - ...0-v6.3-bitfield-add-FIELD_PREP_CONST.patch | 58 - ...-some-linker-warnings-in-recent-link.patch | 63 - ....h-removed-REPEAT_BYTE-from-kernel.h.patch | 161 - ...per_-_bits-and-lower_-_bits-to-wordp.patch | 107 - ...nand-Support-write-protection-settin.patch | 36 - ...y-a-bit-code-find-partition-matching.patch | 65 - ...find-OF-node-for-every-MTD-partition.patch | 84 - ...T_DEV-for-partitions-marked-as-rootf.patch | 47 - ...mtd-spi-nor-add-generic-flash-driver.patch | 117 - ...ilicon-Labs-SI3210-device-compatible.patch | 32 - ...TP-Link-SafeLoader-partitions-table-.patch | 229 - ...onix-use-scratch-buffer-for-DMA-oper.patch | 35 - ....3-mtd-ubi-wire-up-parent-MTD-device.patch | 33 - ...-mtd-ubi-block-wire-up-device-parent.patch | 49 - ...-mtd_otp_nvmem_add-to-handle-EPROBE_.patch | 47 - ...v6-ext-headers-without-frag0-invalid.patch | 107 - ...611-v6.3-net-add-helper-eth_addr_add.patch | 41 - ...uirk-for-Fiberstone-GPON-ONU-34-20BI.patch | 32 - ...-aquantia-move-to-separate-directory.patch | 2306 ----- ...antia-move-MMD_VEND-define-to-header.patch | 183 - ...y-aquantia-add-firmware-load-support.patch | 504 -- ...edicated-C45-API-to-MDIO-bus-drivers.patch | 326 - ...-Introduce-PSGMII-PHY-interface-mode.patch | 105 - ...eplace-of_gpio.h-with-what-indeed-is.patch | 32 - ...upport-qca8081-genphy_c45_pma_read_a.patch | 70 - ...3x-merge-qca8081-slave-seed-function.patch | 73 - ...nable-qca8081-slave-seed-conditional.patch | 76 - ...-at803x-support-qca8081-1G-chip-type.patch | 48 - ...emove-qca8081-1G-fast-retrain-and-sl.patch | 98 - ...dd-qca8081-fifo-reset-on-the-link-ch.patch | 55 - ...ove-disable-WOL-to-specific-at8031-p.patch | 69 - ...aname-hw_stats-functions-to-qca83xx-.patch | 129 - ...ove-qca83xx-specific-check-in-dedica.patch | 155 - ...ove-specific-DT-option-for-at8031-to.patch | 94 - ...ove-specific-at8031-probe-mode-check.patch | 78 - ...ove-specific-at8031-config_init-to-d.patch | 86 - ...ove-specific-at8031-WOL-bits-to-dedi.patch | 92 - ...ove-specific-at8031-config_intr-to-d.patch | 78 - ...ake-at8031-related-DT-functions-name.patch | 78 - ...ove-at8031-functions-in-dedicated-se.patch | 297 - ...ove-at8035-specific-DT-parse-to-dedi.patch | 114 - ...rop-specific-PHY-ID-check-from-cable.patch | 219 - ...ove-specific-qca808x-config_aneg-to-.patch | 116 - ...ake-read-specific-status-function-mo.patch | 97 - ...at803x-remove-extra-space-after-cast.patch | 27 - ...x-replace-msleep-1-with-usleep_range.patch | 38 - ...etter-align-function-varibles-to-ope.patch | 152 - ...generalize-cdt-fault-length-function.patch | 62 - ...efactor-qca808x-cable-test-get-statu.patch | 118 - ...dd-support-for-cdt-cross-short-test-.patch | 182 - ...at803x-make-read_status-more-generic.patch | 62 - ...y-at803x-add-LED-support-for-qca808x.patch | 408 - ...03x-PHY-driver-to-dedicated-director.patch | 5598 ------------ ...ate-and-move-functions-to-shared-lib.patch | 243 - ...eatch-qca83xx-PHY-driver-from-at803x.patch | 638 -- ...e-additional-functions-to-shared-lib.patch | 1014 --- ...etach-qca808x-PHY-driver-from-at803x.patch | 1936 ---- ...cs-add-driver-for-MediaTek-SGMII-PCS.patch | 394 - ...r-type-u8-in-phy_package_shared-stru.patch | 28 - ...HY-package-API-to-support-multiple-g.patch | 341 - ...ure-__phy_write-read_mmd-to-helper-a.patch | 116 - ...pport-for-PHY-package-MMD-read-write.patch | 196 - ....2-net-fman-memac-Add-serdes-support.patch | 103 - ...2-net-fman-memac-Use-lynx-pcs-driver.patch | 384 - ...-03-v6.2-net-dpaa-Convert-to-phylink.patch | 2451 ----- ...ide-phylink_validate_mask_caps-helpe.patch | 93 - ...valid-state-argument-to-phylink_vali.patch | 39 - ...add-phylink_get_link_timer_ns-helper.patch | 48 - ...cit-phylink_generic_validate-referen.patch | 250 - ..._bus_find_fwnode-take-a-const-fwnode.patch | 48 - ...-t-print-an_enabled-in-pcs_get_state.patch | 31 - ...e-Autoneg-bit-rather-than-an_enabled.patch | 32 - ...ort-validated-pause-and-autoneg-in-f.patch | 64 - ...2-v6.4-net-phylink-remove-an_enabled.patch | 177 - ...et-phylink-constify-fwnode-arguments.patch | 88 - ...-fwnode_get_phy_node-fwnode-argument.patch | 38 - ...ylink-fix-ksettings_set-ethtool-call.patch | 44 - ...-support-for-setting-signalling-rate.patch | 149 - ...hy-add-helpers-for-comparing-phy-IDs.patch | 147 - ...ire-supported_interfaces-to-be-fille.patch | 71 - ...ve-duplicated-linkmode-pause-resolut.patch | 64 - ...function-to-resolve-clause-73-negoti.patch | 76 - ...ide-phylink_pcs_config-and-phylink_p.patch | 100 - ...ually-fix-ksettings_set-ethtool-call.patch | 55 - ...net-phylink-add-PCS-negotiation-mode.patch | 324 - ...ert-phylink_mii_c22_pcs_config-to-ne.patch | 45 - ...-neg_mode-into-phylink_mii_c22_pcs_c.patch | 187 - ...xi-update-PCS-driver-to-use-neg_mode.patch | 101 - ...e-Autoneg-bit-rather-than-an_enabled.patch | 55 - ...s-fix-incorrect-number-of-interfaces.patch | 30 - ...808x-fix-logic-error-in-LED-brightne.patch | 36 - ...808x-default-to-LED-active-High-if-n.patch | 41 - ...ort-for-scanning-PHY-in-PHY-packages.patch | 211 - ...-add-devm-of_phy_package_join-helper.patch | 185 - ...move-more-function-to-shared-library.patch | 583 -- ...whether-link-has-changed-in-c37_read.patch | 100 - ...m-add-support-for-QCA807x-PHY-Family.patch | 668 -- ...e-common-qca808x-LED-define-to-share.patch | 179 - ...eneralize-some-qca808x-LED-functions.patch | 172 - ...07x-add-support-for-configurable-LED.patch | 326 - ...move-interface-mode-check-to-.config.patch | 51 - ...03x-fix-kernel-panic-with-at8031_pro.patch | 45 - ...-add-support-for-clock-frequency-pro.patch | 205 - ...-drop-wrong-endianness-conversion-fo.patch | 92 - ..._eth_soc-enable-flow-offloading-supp.patch | 26 - ...et-mtk_wed-introduce-wed-mcu-support.patch | 591 -- ...net-mtk_wed-introduce-wed-wo-support.patch | 737 -- ..._wed-rename-tx_wdma-array-in-rx_wdma.patch | 79 - ...mtk_wed-add-configure-wed-wo-support.patch | 1521 ---- ...ethernet-mtk_wed-add-rx-mib-counters.patch | 149 - ..._eth_soc-remove-cpu_relax-in-mtk_pen.patch | 36 - ..._wed-add-wcid-overwritten-support-fo.patch | 80 - ..._wed-return-status-value-in-mtk_wdma.patch | 85 - ..._wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch | 52 - ...ethernet-mtk_wed-update-mtk_wed_stop.patch | 98 - ...mtk_wed-add-mtk_wed_rx_reset-routine.patch | 309 - ..._wed-add-reset-to-tx_ring_setup-call.patch | 103 - ..._wed-fix-sleep-while-atomic-in-mtk_w.patch | 103 - ..._wed-get-rid-of-queue-lock-for-rx-qu.patch | 52 - ..._wed-get-rid-of-queue-lock-for-tx-qu.patch | 75 - ..._eth_soc-introduce-mtk_hw_reset-util.patch | 70 - ..._eth_soc-introduce-mtk_hw_warm_reset.patch | 107 - ..._eth_soc-align-reset-procedure-to-ve.patch | 262 - ..._eth_soc-add-dma-checks-to-mtk_hw_re.patch | 249 - ..._wed-add-reset-reset_complete-callba.patch | 124 - ..._wed-add-reset-to-rx_ring_setup-call.patch | 106 - ..._eth_soc-account-for-vlan-in-rx-head.patch | 22 - ..._eth_soc-increase-tx-ring-side-for-Q.patch | 143 - ..._eth_soc-avoid-port_mg-assignment-on.patch | 52 - ..._eth_soc-implement-multi-queue-suppo.patch | 654 -- ...t-dsa-tag_mtk-assign-per-port-queues.patch | 20 - ...iatek-ppe-assign-per-port-queues-for.patch | 93 - ...ort-for-DSA-rx-offloading-via-metada.patch | 72 - ..._eth_soc-fix-VLAN-rx-hardware-accele.patch | 192 - ..._eth_soc-disable-hardware-DSA-untagg.patch | 42 - ..._eth_soc-enable-special-tag-when-any.patch | 54 - ..._eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch | 129 - ..._wed-No-need-to-clear-memory-after-a.patch | 26 - ..._wed-fix-some-possible-NULL-pointer-.patch | 61 - ..._wed-fix-possible-deadlock-if-mtk_we.patch | 58 - ..._eth_soc-fix-tx-throughput-regressio.patch | 31 - ...-mtk_eth_soc-add-definitions-for-PCS.patch | 55 - ...eliminate-unnecessary-error-handling.patch | 74 - ...soc-add-pcs_get_state-implementation.patch | 46 - ...convert-mtk_sgmii-to-use-regmap_upda.patch | 130 - ...add-out-of-band-forcing-of-speed-and.patch | 52 - ...07-net-mtk_eth_soc-move-PHY-power-up.patch | 48 - ...h_soc-move-interface-speed-selection.patch | 48 - ...th_soc-add-advertisement-programming.patch | 52 - ...move-and-correct-link-timer-programm.patch | 63 - ...add-support-for-in-band-802.3z-negot.patch | 132 - ...ii-ensure-the-SGMII-PHY-is-powered-d.patch | 119 - ...iatek-sgmii-fix-duplex-configuration.patch | 52 - ...enable-PCS-polling-to-allow-SFP-work.patch | 33 - ...ethernet-mtk_eth_soc-reset-PCS-state.patch | 48 - ..._eth_soc-only-write-values-if-needed.patch | 103 - ...t-mtk_eth_soc-add-support-for-MT7981.patch | 206 - ..._eth_soc-set-MDIO-bus-clock-frequenc.patch | 76 - ..._eth_soc-switch-to-external-PCS-driv.patch | 512 -- ...k_eth_soc-use-WO-firmware-for-MT7981.patch | 46 - ..._eth_soc-fix-NULL-pointer-dereferenc.patch | 28 - ..._eth_soc-ppe-add-support-for-flow-ac.patch | 403 - ...iatek-fix-ppe-flow-accounting-for-v1.patch | 58 - ..._eth_soc-drop-generic-vlan-rx-offloa.patch | 201 - ..._eth_soc-always-mtk_get_ib1_pkt_type.patch | 31 - ...net-phy-bcm54612e-add-suspend-resume.patch | 27 - ..._ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch | 78 - ..._eth_soc-remove-incorrect-PLL-config.patch | 141 - ..._eth_soc-remove-mac_pcs_get_state-an.patch | 81 - ..._eth_soc-add-version-in-mtk_soc_data.patch | 550 -- ...t-mtk_eth_soc-increase-MAX_DEVS-to-3.patch | 29 - ..._eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch | 186 - ..._eth_soc-add-NETSYS_V3-version-suppo.patch | 307 - ..._eth_soc-convert-caps-in-mtk_soc_dat.patch | 193 - ..._eth_soc-convert-clock-bitmap-to-u64.patch | 132 - ..._eth_soc-add-basic-support-for-MT798.patch | 477 - ..._eth_soc-enable-page_pool-support-fo.patch | 27 - ..._eth_soc-enable-nft-hw-flowtable_off.patch | 135 - ..._eth_soc-support-per-flow-accounting.patch | 78 - ..._eth_soc-fix-NULL-pointer-on-hw-rese.patch | 52 - ..._eth_soc-fix-register-definitions-fo.patch | 44 - ...tk_eth_soc-add-reset-bits-for-MT7988.patch | 188 - ..._eth_soc-add-support-for-in-SoC-SRAM.patch | 254 - ..._eth_soc-support-36-bit-DMA-addressi.patch | 166 - ...k_eth_soc-fix-uninitialized-variable.patch | 44 - ..._eth_soc-fix-pse_port-configuration-.patch | 33 - ..._eth_soc-add-code-for-offloading-flo.patch | 271 - ...iatek-mtk_ppe-prefer-newly-added-l2-.patch | 37 - ..._eth_soc-improve-keeping-track-of-of.patch | 334 - ...iatek-fix-ppe-flow-accounting-for-L2.patch | 342 - ..._wed-add-some-more-info-in-wed_txinf.patch | 45 - ..._wed-minor-change-in-wed_-tx-rx-info.patch | 47 - ..._eth_soc-rely-on-mtk_pse_port-defini.patch | 29 - ..._wed-check-update_wo_rx_stats-in-mtk.patch | 26 - ..._wed-do-not-assume-offload-callbacks.patch | 68 - ..._wed-introduce-versioning-utility-ro.patch | 232 - ..._wed-do-not-configure-rx-offload-if-.patch | 234 - ..._wed-rename-mtk_rxbm_desc-in-mtk_wed.patch | 52 - ..._wed-introduce-mtk_wed_buf-structure.patch | 87 - ..._wed-move-mem_region-array-out-of-mt.patch | 88 - ...-mtk_wed-make-memory-region-optional.patch | 71 - ...k_wed-add-mtk_wed_soc_data-structure.patch | 217 - ..._wed-introduce-WED-support-for-MT798.patch | 1280 --- ..._wed-refactor-mtk_wed_check_wfdma_rx.patch | 95 - ..._wed-introduce-partial-AMSDU-offload.patch | 465 - ..._wed-introduce-hw_rro-support-for-MT.patch | 483 - ..._wed-debugfs-move-wed_v2-specific-re.patch | 78 - ..._wed-debugfs-add-WED-3.0-debugfs-ent.patch | 432 - ...et-mtk_wed-add-wed-3.0-reset-support.patch | 587 -- ...antia-add-AQR111-and-AQR111B0-PHY-ID.patch | 102 - ...9-net-phy-aquantia-add-AQR113-PHY-ID.patch | 60 - ...9-net-phy-aquantia-add-AQR813-PHY-ID.patch | 59 - ...et-dsa-introduce-dsa_phylink_to_port.patch | 99 - ...A-switch-drivers-to-provide-their-ow.patch | 117 - ...t-introduce-napi_is_scheduled-helper.patch | 96 - ...et-stmmac-improve-TX-timer-arm-logic.patch | 77 - ...c-move-TX-timer-arm-after-DMA-enable.patch | 96 - ...ac-increase-TX-coalesce-timer-to-5ms.patch | 38 - ...ntroduce-single-mii-read-write-lo-hi.patch | 150 - ...prove-mdio-master-read-write-by-usin.patch | 73 - ...d-QCA8K_ATU_TABLE_SIZE-define-for-fd.patch | 63 - ...a8k-convert-to-regmap-read-write-API.patch | 261 - ...-enable-use_single_write-for-qca8xxx.patch | 78 - ...ke-learning-configurable-and-keep-of.patch | 146 - ...mit-user-ports-access-to-the-first-C.patch | 53 - ...ve-qca8xxx-hol-fixup-to-separate-fun.patch | 111 - ...e-dsa_for_each-macro-instead-of-for-.patch | 158 - ...x-regmap-bulk-read-write-methods-on-.patch | 61 - ...a-mt7530-remove-redundant-assignment.patch | 32 - ...t-dsa-mt7530-use-external-PCS-driver.patch | 477 - ...ake-some-noise-if-register-read-fail.patch | 32 - ...a-mt7530-refactor-SGMII-PCS-creation.patch | 111 - ...mt7530-use-unlocked-regmap-accessors.patch | 74 - ...se-regmap-to-access-switch-register-.patch | 224 - ...ove-SGMII-PCS-creation-to-mt7530_pro.patch | 54 - ...t-dsa-mt7530-introduce-mutex-helpers.patch | 273 - ...ove-p5_intf_modes-function-to-mt7530.patch | 75 - ...ntroduce-mt7530_probe_common-helper-.patch | 155 - ...ntroduce-mt7530_remove_common-helper.patch | 54 - ...t7530-introduce-separate-MDIO-driver.patch | 695 -- ...kip-locking-if-MDIO-bus-isn-t-presen.patch | 47 - ...ntroduce-driver-for-MT7988-built-in-.patch | 421 - ...-dsa-mt7530-fix-support-for-MT7531BE.patch | 118 - ...30-update-PCS-driver-to-use-neg_mode.patch | 35 - ...onvert-to-platform-remove-callback-r.patch | 58 - ...3x-remove-mt753x_phylink_pcs_link_up.patch | 51 - ...eplace-deprecated-strncpy-with-ethto.patch | 40 - ...upport-OF-based-registration-of-swit.patch | 116 - ...-fix-10M-100M-speed-on-MT7988-switch.patch | 34 - ...lways-trap-frames-to-active-CPU-port.patch | 125 - ...se-p5_interface_select-as-data-type-.patch | 45 - ...tore-port-5-SGMII-capability-of-MT75.patch | 227 - ...mprove-comments-regarding-switch-por.patch | 133 - ...mprove-code-path-for-setting-up-port.patch | 95 - ...o-not-set-priv-p5_interface-on-mt753.patch | 42 - ...o-not-run-mt7530_setup_port5-if-port.patch | 62 - ...mpty-default-case-on-mt7530_setup_po.patch | 58 - ...7530-move-XTAL-check-to-mt7530_setup.patch | 53 - ...mt7530-simplify-mt7530_pad_clk_setup.patch | 146 - ...all-port-6-setup-from-mt7530_mac_con.patch | 97 - ...30-remove-pad_setup-function-pointer.patch | 148 - ...-correct-port-capabilities-of-MT7988.patch | 36 - ...o-not-clear-config-supported_interfa.patch | 38 - ...emove-.mac_port_config-for-MT7988-an.patch | 81 - ...et-interrupt-register-only-for-MT753.patch | 31 - ...o-not-use-SW_PHY_RST-to-reset-MT7531.patch | 41 - ...et-rid-of-useless-error-returns-on-p.patch | 217 - ...get-rid-of-priv-info-cpu_port_config.patch | 305 - ...-mt7530-get-rid-of-mt753x_mac_config.patch | 48 - ...ut-initialising-PCS-devices-code-bac.patch | 57 - ...ort-link-settings-ops-and-force-link.patch | 68 - ...-dsa-mt7530-simplify-link-operations.patch | 83 - ...0-provide-own-phylink-MAC-operations.patch | 135 - ...ix-port-mirroring-for-MT7988-SoC-swi.patch | 49 - ...dio-read-PHY-address-of-switch-from-.patch | 238 - ...-dsa-mt7530-simplify-core-operations.patch | 186 - ...isable-EEE-abilities-on-failure-on-M.patch | 88 - ...et-dsa-mt7530-refactor-MT7530_PMCR_P.patch | 200 - ...ename-p5_intf_sel-and-use-only-for-M.patch | 185 - ...ename-mt753x_bpdu_port_fw-enum-to-mt.patch | 169 - ...efactor-MT7530_MFC-and-MT7531_CFC-ad.patch | 201 - ...efactor-MT7530_HWTRAP-and-MT7530_MHW.patch | 257 - ...ove-MT753X_MTRAP-operations-for-MT75.patch | 117 - ...eturn-mt7530_setup_mdio-mt7531_setup.patch | 39 - ...efine-MAC-speed-capabilities-per-swi.patch | 75 - ...530-get-rid-of-function-sanity-check.patch | 33 - ...dsa-mt7530-refactor-MT7530_PMEEECR_P.patch | 71 - ...et-rid-of-mac_port_validate-member-o.patch | 46 - ...se-priv-ds-num_ports-instead-of-MT75.patch | 57 - ...o-not-pass-port-variable-to-mt7531_r.patch | 37 - ...xplain-exposing-MDIO-bus-of-MT7531AE.patch | 33 - ...0-do-not-set-MT7530_P5_DIS-when-PHY-.patch | 45 - ...etect-PHY-muxing-when-PHY-is-defined.patch | 45 - ...or-Motorcomm-yt8521-gigabit-ethernet.patch | 1724 ---- ...fix-yt8521-duplicated-argument-to-or.patch | 49 - ...net-phy-add-Motorcomm-YT8531S-phy-id.patch | 140 - ...fix-the-spelling-problem-of-Sentinel.patch | 26 - ...nge-the-phy-id-of-yt8521-and-yt8531s.patch | 29 - ...-for-Motorcomm-yt8521-yt8531-gigabit.patch | 107 - ...support-for-Motorcomm-yt8521-gigabit.patch | 343 - ...upport-for-Motorcomm-yt8531s-gigabit.patch | 100 - ...or-Motorcomm-yt8531-gigabit-ethernet.patch | 302 - ...motorcomm-uninitialized-variables-in.patch | 34 - ...m-Add-pad-drive-strength-cfg-support.patch | 170 - ...k-add-pcs_enable-pcs_disable-methods.patch | 173 - ...t-pcs-lynxi-implement-pcs_disable-op.patch | 44 - ...ive-renaming-when-an-interface-is-up.patch | 136 - ...-need-to-blacklist-any-r8152-devices.patch | 158 - ...-control-transfer-of-rtl8152_get_ver.patch | 46 - ...-Add-__GFP_NOWARN-to-big-allocations.patch | 55 - ...52-adjust-generic_ocp_write-function.patch | 70 - .../795-v6.6-09-r8152-set-bp-in-bulk.patch | 129 - ...eth-r8152-try-to-use-a-normal-budget.patch | 39 - ...re-register-access-if-register-acces.patch | 398 - ...he-loop-when-the-budget-is-exhausted.patch | 83 - ..._ether-add-u-blox-0x1313-composition.patch | 47 - ...795-v6.7-16-r8152-use-napi_gro_frags.patch | 122 - ...ix-risk-of-NULL-pointer-deallocation.patch | 30 - ...ansmit-URBs-without-trailing-padding.patch | 35 - ...03-usbnet-ipheth-add-CDC-NCM-support.patch | 326 - ...et-ipheth-update-Kconfig-description.patch | 36 - ...6xxx-fix-marvell-6350-switch-probing.patch | 89 - ...11h-Add-the-Airoha-EN8811H-PHY-drive.patch | 1140 --- ...phy-air_en8811h-fix-some-error-codes.patch | 47 - ...it_default_state_get-to-the-global-h.patch | 39 - ...a8k-move-qca8k_port_to_phy-to-header.patch | 67 - ...net-dsa-qca8k-add-LEDs-basic-support.patch | 435 - ...dsa-qca8k-add-LEDs-blink_set-support.patch | 74 - ...bs-for-when-CLASS_LED-NEW_LEDS-are-d.patch | 59 - ...5-net-phy-Add-a-binding-for-PHY-LEDs.patch | 191 - ...ce-Call-into-the-PHY-driver-to-set-L.patch | 97 - ...ell-Add-software-control-of-the-LEDs.patch | 112 - ...ce-Call-into-the-PHY-driver-to-set-L.patch | 73 - ...-phy-marvell-Implement-led_blink_set.patch | 104 - ...Fix-inconsistent-indenting-in-led_bl.patch | 38 - ...dev-Drop-NETDEV_LED_MODE_LINKUP-from.patch | 87 - ...dev-Rename-add-namespace-to-netdev-t.patch | 149 - ...-netdev-Convert-device-attr-to-macro.patch | 82 - ...etdev-Use-mutex-instead-of-spinlocks.patch | 106 - ...01-leds-add-APIs-for-LEDs-hw-control.patch | 74 - ...get-attached-device-for-LED-hw-contr.patch | 37 - ...ds-leds-class-Document-new-Hardware-.patch | 113 - ...dev-refactor-code-setting-device-nam.patch | 69 - ...dev-introduce-check-for-possible-hw-.patch | 54 - ...dev-add-basic-check-for-hw-control-s.patch | 42 - ...dev-reject-interval-store-for-hw_con.patch | 28 - ...etdev-add-support-for-LED-hw-control.patch | 107 - ...er-netdev-validate-configured-netdev.patch | 58 - ...dev-init-mode-if-hw-control-already-.patch | 53 - ...dev-expose-netdev-trigger-modes-in-l.patch | 54 - ...t-dsa-qca8k-implement-hw_control-ops.patch | 200 - ...dsa-qca8k-add-op-to-get-ports-netdev.patch | 70 - ...dev-add-additional-specific-link-spe.patch | 242 - ...dev-add-additional-specific-link-dup.patch | 138 - ...dev-expose-hw_control-status-via-sys.patch | 45 - ...d-support-for-additional-modes-for-n.patch | 64 - ...x-pass-directly-chip-structure-to-mv.patch | 64 - ...x-use-mv88e6xxx_phy_is_internal-in-m.patch | 31 - ...x-add-field-to-specify-internal-phys.patch | 69 - ...x-fix-88E6393X-family-internal-phys-.patch | 52 - ...x-pass-mv88e6xxx_chip-structure-to-p.patch | 110 - ...xx-enable-support-for-88E6361-switch.patch | 153 - ...e-STM32MP15_BSEC_NUM_LOWER-in-config.patch | 82 - ...-warning-when-upper-OTPs-are-updated.patch | 34 - ...nvmem-stm32-add-nvmem-type-attribute.patch | 26 - ...m-stm32-fix-spelling-typo-in-comment.patch | 27 - ...x-spelling-mistake-controlls-control.patch | 27 - ...boot-env-add-Broadcom-format-support.patch | 67 - ...mem-core-remove-spurious-white-space.patch | 26 - ...e-add-an-index-parameter-to-the-cell.patch | 180 - ...struct-nvmem_cell_info-to-nvmem-prov.patch | 78 - ...the-removal-of-the-cells-in-nvmem_ad.patch | 65 - ...05-nvmem-core-add-nvmem_add_one_cell.patch | 122 - ...vmem_add_one_cell-in-nvmem_add_cells.patch | 93 - ...32-add-OP-TEE-support-for-STM32MP13x.patch | 562 -- ...ect-bsec-pta-presence-for-STM32MP15x.patch | 85 - ...eprm-fix-kernel-doc-bad-line-warning.patch | 32 - ...mi-sdam-register-at-device-init-time.patch | 43 - ...011-nvmem-stm32-fix-OPTEE-dependency.patch | 46 - ...ount-to-list.h-as-list_count_nodes-f.patch | 75 - ...001-nvmem-xilinx-zynqmp-make-modular.patch | 35 - ...2-nvmem-core-introduce-NVMEM-layouts.patch | 387 - ...ndle-the-absence-of-expected-layouts.patch | 61 - ...-core-request-layout-modules-loading.patch | 52 - ...em-core-add-per-cell-post-processing.patch | 86 - ...ow-to-modify-a-cell-before-adding-it.patch | 59 - ...replace-global-post-processing-with-.patch | 81 - ...m-cell-drop-global-cell_post_process.patch | 68 - ...de-own-priv-pointer-in-post-process-.patch | 76 - ...ayouts-sl28vpd-Add-new-layout-driver.patch | 215 - ...youts-onie-tlv-Add-new-layout-driver.patch | 306 - ...m-mark-OF-related-data-as-maybe-unus.patch | 32 - ...Support-postprocessing-for-GPU-speed.patch | 120 - ...p-Use-devm_platform_ioremap_resource.patch | 39 - ...tp-Use-devm_platform_ioremap_resourc.patch | 39 - ...p-Use-devm_platform_get_and_ioremap_.patch | 32 - ...rt-specifying-both-cell-raw-data-pos.patch | 115 - ...nv-post-process-ethaddr-env-variable.patch | 81 - ...cro-to-register-nvmem-layout-drivers.patch | 42 - ...28vpd-Use-module_nvmem_layout_driver.patch | 39 - ...ie-tlv-Use-module_nvmem_layout_drive.patch | 39 - ...uts-onie-tlv-Drop-wrong-module-alias.patch | 24 - ...28vpd-set-varaiable-sl28vpd_layout-s.patch | 31 - ...-bcm47xx-support-init-from-IO-memory.patch | 100 - ...set-varaiable-imx_ocotp_layout-stora.patch | 31 - ...Reverse-MAC-addresses-on-all-i.MX-de.patch | 71 - ...vram-add-.read_post_process-for-MACs.patch | 81 - ...tp-Add-clks-and-reg_read-to-rockchip.patch | 166 - ...tp-Generalize-rockchip_otp_wait_stat.patch | 62 - ...tp-Use-devm_reset_control_array_get_.patch | 31 - ...hip-otp-Improve-probe-error-handling.patch | 71 - ...-rockchip-otp-Add-support-for-RK3588.patch | 129 - ...-Switch-xilinx.com-emails-to-amd.com.patch | 26 - ...-0010-nvmem-imx-support-i.MX93-OCOTP.patch | 230 - ...e-add-support-for-fixed-cells-layout.patch | 96 - ...Convert-to-devm_platform_ioremap_res.patch | 36 - ...-Use-devm_platform_get_and_ioremap_r.patch | 30 - ...p-Convert-to-devm_platform_ioremap_r.patch | 34 - ...fuse-Convert-to-devm_platform_iorema.patch | 36 - ...fuse-Use-devm_platform_get_and_iorem.patch | 31 - ...m-Use-devm_platform_get_and_ioremap_.patch | 30 - ....6-0007-nvmem-qfprom-do-some-cleanup.patch | 59 - ...se-devm_platform_get_and_ioremap_res.patch | 29 - ...nvmem-add-new-NXP-QorIQ-eFuse-driver.patch | 133 - ...-nvmem-Kconfig-Fix-typo-drive-driver.patch | 37 - ...m-Add-Qualcomm-secure-QFPROM-support.patch | 152 - ...-Replace-zero-length-array-with-DECL.patch | 30 - ...e-all-cells-before-adding-the-nvmem-.patch | 40 - ...n-NULL-when-no-nvmem-layout-is-found.patch | 35 - ...-Do-not-open-code-existing-functions.patch | 29 - ...tify-when-a-new-layout-is-registered.patch | 44 - ...ia-Use-sysfs_emit-instead-of-sprintf.patch | 29 - ...a-Make-set_brightness-more-efficient.patch | 207 - ...a-Support-HW-controlled-mode-via-pri.patch | 202 - ...a-Add-support-for-enabling-disabling.patch | 244 - ...a-Fix-brightness-setting-and-trigger.patch | 167 - ...mem-qfprom-Mark-core-clk-as-optional.patch | 37 - ...it-config-option-to-read-old-syntax-.patch | 330 - ...0003-nvmem-Use-device_get_match_data.patch | 77 - ...4-Revert-nvmem-add-new-config-option.patch | 77 - ...ect-fixed-layouts-to-grab-a-layout-d.patch | 45 - ..._nvram-store-a-copy-of-NVRAM-content.patch | 261 - ...-Add-FUNCTION-defines-for-per-band-W.patch | 34 - ...-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch | 35 - ...-device-Export-of_device_make_bus_id.patch | 140 - ...mem_layout_get_container-in-another-.patch | 95 - ...Create-a-header-for-internal-sharing.patch | 91 - ...03-nvmem-Simplify-the-add_cells-hook.patch | 79 - ...vmem-Move-and-rename-fixup_cell_info.patch | 169 - ...rk-layouts-to-become-regular-devices.patch | 763 -- ...vmem-core-Expose-cells-through-sysfs.patch | 240 - ...support-for-STM32MP25-BSEC-to-contro.patch | 65 - ...factor-.add_cells-callback-arguments.patch | 94 - ...mem-drop-nvmem_layout_get_match_data.patch | 72 - ...nvmem-core-add-nvmem_dev_size-helper.patch | 53 - ...-use-nvmem_add_one_cell-nvmem-subsys.patch | 126 - ...-u-boot-env-use-nvmem-device-helpers.patch | 81 - ...vmem-u-boot-env-improve-coding-style.patch | 62 - ...fix-circular-LEDS_CLASS-dependencies.patch | 65 - ...net-phy-Fix-reading-LED-reg-property.patch | 43 - ...emove-LEDs-to-ensure-correct-orderin.patch | 67 - ...Register-MediaTek-socinfo-driver-fro.patch | 69 - ...qmp_nvmem-zynqmp_nvmem_probe-cleanup.patch | 97 - ...mp_nvmem-Add-support-to-access-efuse.patch | 243 - ...mem-mtk-efuse-Drop-NVMEM-device-name.patch | 35 - ...rint-error-on-wrong-bits-DT-property.patch | 32 - ...dev-Remove-NULL-check-before-dev_-pu.patch | 44 - ...dev-uninitialized-variable-in-netdev.patch | 31 - ...netdev-Fix-requesting-offload-device.patch | 57 - ...ce-Call-into-the-PHY-driver-to-set-L.patch | 149 - ...Add-support-for-offloading-LED-blink.patch | 344 - ...-Disable-offload-on-deactivation-of-.patch | 31 - ...-of_parse_phandle_with_optional_args.patch | 58 - ...ke-.-cells-optional-for-simple-props.patch | 34 - ...operty-add-nvmem-cell-cells-property.patch | 30 - ...vice-Ignore-modalias-of-reused-nodes.patch | 37 - ...-ignore-error-code-in-of_device_ueve.patch | 29 - ...002-of-Update-of_device_get_modalias.patch | 103 - ...v6.4-0003-of-Rename-of_modalias_node.patch | 173 - ...0004-of-Move-of_modalias-to-module.c.patch | 160 - ...uest-module-helper-logic-to-module.c.patch | 131 - ...ore-owner-from-modules-with-nvmem_la.patch | 61 - ...ie-tlv-drop-driver-owner-initializat.patch | 28 - ...28vpd-drop-driver-owner-initializati.patch | 28 - ...-nvmem-sc27xx-fix-module-autoloading.patch | 26 - ...05-nvmem-sprd-fix-module-autoloading.patch | 26 - ...core-switch-to-use-device_add_groups.patch | 32 - ...prom-Convert-to-platform-remove-call.patch | 57 - ...fuse-Remove-nvmem_device-from-efuse-.patch | 50 - ...qcom-document-qcom-msm-id-and-qcom-b.patch | 207 - ...-move-SMEM-item-struct-and-defines-t.patch | 171 - ...com-smem-Switch-to-EXPORT_SYMBOL_GPL.patch | 55 - ...-smem-introduce-qcom_smem_get_soc_id.patch | 70 - ...com-nvmem-use-SoC-ID-s-from-bindings.patch | 51 - ...-nvmem-use-helper-to-get-SMEM-SoC-ID.patch | 109 - ...tc-rtc7301-Support-byte-addressed-IO.patch | 93 - ...t-phy-amd-Support-the-Altima-AMI101L.patch | 82 - ...ors-from-DT-bindings-to-led_co.patch.patch | 29 - ...igger-netdev-Extend-speeds-up-to-10G.patch | 111 - ...-support-for-PHY-LEDs-polarity-modes.patch | 98 - ...dev-fix-RTNL-handling-to-prevent-pot.patch | 170 - ....4-net-phy-hide-the-PHYLIB_LEDS-knob.patch | 43 - ...dev-Fix-kernel-panic-on-interface-re.patch | 55 - ...-clear-PMD-Global-Transmit-Disable-b.patch | 103 - ...dd-missing-MODULE_DESCRIPTION-macros.patch | 48 - ...e-Replacing-the-use-of-of_node_put-t.patch | 48 - ...tp-set-add_legacy_fixed_of_cells-con.patch | 28 - ...4-nvmem-rockchip-otp-Set-type-to-OTP.patch | 25 - ...nvmem-rockchip-efuse-set-type-to-OTP.patch | 26 - ...06-nvmem-core-add-single-sysfs-group.patch | 42 - ...core-remove-global-nvmem_cells_group.patch | 83 - ...unnecessary-range-checks-in-sysfs-ca.patch | 61 - ...em-Use-sysfs_emit-for-type-attribute.patch | 30 - ...e-Implement-force_ro-sysfs-attribute.patch | 122 - ...v-error-if-NVMEM-device-is-too-small.patch | 40 - ...-type-of-devm_nvmem_device_get-in-ke.patch | 37 - ...1-nvmem-imx-ocotp-ele-support-i.MX95.patch | 73 - ...otp-Use-devm_platform_ioremap_resour.patch | 44 - ...-nvmem-layouts-add-U-Boot-env-layout.patch | 525 -- ..._generic-add-support-for-sc8280xp-cr.patch | 32 - ...ci_generic-Add-HP-variant-of-T99W175.patch | 34 - ..._generic-Add-definition-for-some-VID.patch | 66 - ..._generic-Drop-redundant-pci_enable_p.patch | 68 - ...-mhi-pci_generic-Add-Foxconn-T99W510.patch | 49 - ..._generic-Add-support-for-IP_SW0-chan.patch | 67 - ..._generic-Add-support-for-Quectel-EM1.patch | 34 - ..._generic-Add-support-for-Quectel-RM5.patch | 49 - ..._generic-Add-support-for-Dell-DW5932.patch | 34 - ..._generic-Add-support-for-Quectel-RM5.patch | 36 - ...-a-separate-timeout-parameter-for-wa.patch | 175 - ..._generic-Add-SDX75-based-modem-suppo.patch | 62 - ..._generic-constify-modem_telit_fn980_.patch | 28 - ...ow-MHI-client-drivers-to-provide-the.patch | 142 - ...ix-order-of-pek-rise-and-fall-events.patch | 80 - ...0x-Switch-to-the-sys-off-handler-API.patch | 82 - ...fd-axp20x-Fix-axp288-writable-ranges.patch | 28 - ...axp20x-Add-support-for-AXP15060-PMIC.patch | 343 - ...-axp20x-Add-support-for-AXP313a-PMIC.patch | 256 - ...p20x-Add-support-for-AXP313a-variant.patch | 129 - ...egulator-axp20x-Add-AXP15060-support.patch | 367 - ....5-mfd-axp20x-Add-support-for-AXP192.patch | 383 - ...-spinand-winbond-fix-flash-detection.patch | 40 - ...6.2-mtd-spinand-winbond-add-W25N02KV.patch | 106 - ...d-spinand-winbond-Fix-ecc_get_status.patch | 49 - ...8-net-ethtool-implement-ethtool_puts.patch | 139 - ...v6.8-net-phy-add-possible-interfaces.patch | 60 - ...6.8-net-phylink-use-for_each_set_bit.patch | 46 - ...k-split-out-per-interface-validation.patch | 76 - ...k-pass-PHY-into-phylink_validate_one.patch | 47 - ...-pass-PHY-into-phylink_validate_mask.patch | 58 - ...t-out-PHY-validation-from-phylink_br.patch | 95 - ...the-PHY-s-possible_interfaces-if-pop.patch | 130 - ...808x-add-helper-for-checking-for-1G-.patch | 50 - ...-qca808x-fill-in-possible_interfaces.patch | 44 - target/linux/generic/config-6.1 | 7955 ----------------- .../generic/hack-6.1/204-module_strip.patch | 210 - ...-abort-configuration-on-unset-symbol.patch | 41 - .../hack-6.1/210-darwin_scripts_include.patch | 3053 ------- .../211-darwin-uuid-typedef-clash.patch | 22 - .../hack-6.1/212-tools_portability.patch | 360 - .../hack-6.1/214-spidev_h_portability.patch | 24 - .../hack-6.1/220-arm-gc_sections.patch | 123 - .../generic/hack-6.1/221-module_exports.patch | 126 - .../hack-6.1/230-openwrt_lzma_options.patch | 38 - .../hack-6.1/250-netfilter_depends.patch | 27 - .../linux/generic/hack-6.1/251-kconfig.patch | 157 - .../generic/hack-6.1/253-ksmbd-config.patch | 32 - .../generic/hack-6.1/259-regmap_dynamic.patch | 144 - .../260-crypto_test_dependencies.patch | 52 - .../hack-6.1/261-lib-arc4-unhide.patch | 24 - .../generic/hack-6.1/280-rfkill-stubs.patch | 84 - ...cache-use-more-efficient-cache-blast.patch | 64 - ...rans-call-add-disks-after-mtd-device.patch | 112 - ...upport-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch | 24 - ...ers-add-nvmem-support-to-cmdlinepart.patch | 120 - .../hack-6.1/430-mtk-bmt-support.patch | 33 - ...0-net-enable-fraglist-GRO-by-default.patch | 24 - ...lter-connmark-introduce-set-dscpmark.patch | 214 - ...-netfilter-add-xt_FLOWOFFLOAD-target.patch | 812 -- .../hack-6.1/651-wireless_mesh_header.patch | 24 - .../hack-6.1/660-fq_codel_defaults.patch | 27 - ...t-size-the-hashtable-more-adequately.patch | 25 - .../700-swconfig_switch_drivers.patch | 131 - ...-dsa-mv88e6xxx-disable-ATU-violation.patch | 21 - .../721-net-add-packet-mangeling.patch | 167 - ...hy-aquantia-enable-AQR112-and-AQR412.patch | 148 - ...aquantia-fix-system-side-protocol-mi.patch | 34 - ...ntia-add-PHY_IDs-for-AQR112-variants.patch | 63 - ...mtk-lynxi-workaround-2500BaseX-no-an.patch | 53 - ...-r8152-add-LED-configuration-from-OF.patch | 74 - ...et-add-RTL8152-binding-documentation.patch | 54 - .../765-mxl-gpy-control-LED-reg-from-DT.patch | 98 - ...k-ge-add-LED-configuration-interface.patch | 72 - .../hack-6.1/773-bgmac-add-srab-switch.patch | 98 - .../780-usb-net-MeigLink_modem_support.patch | 69 - .../781-usb-net-rndis-support-asr.patch | 69 - .../790-SFP-GE-T-ignore-TX_FAULT.patch | 63 - .../800-GPIO-add-named-gpio-exports.patch | 190 - .../810-bcma-ssb-fallback-sprom.patch | 187 - .../hack-6.1/901-debloat_sock_diag.patch | 174 - .../generic/hack-6.1/902-debloat_proc.patch | 419 - .../hack-6.1/904-debloat_dma_buf.patch | 93 - .../generic/hack-6.1/910-kobject_uevent.patch | 32 - .../911-kobject_add_broadcast_uevent.patch | 76 - .../hack-6.1/920-device_tree_cmdline.patch | 21 - ...vert-driver-core-Set-fw_devlink-on-b.patch | 30 - ...include-asm-rwonce.h-for-kernel-code.patch | 29 - ...s-negative-stack-offsets-on-stack-tr.patch | 57 - .../103-kbuild-export-SUBARCH.patch | 21 - ..._wdt-Add-support-for-specifying-WDI-.patch | 75 - ...e_mem_map-with-ARCH_PFN_OFFSET-calcu.patch | 82 - ...ame2-and-add-RENAME_WHITEOUT-support.patch | 81 - ...41-jffs2-add-RENAME_EXCHANGE-support.patch | 73 - .../142-jffs2-add-splice-ops.patch | 20 - ...ge_allow_receiption_on_disabled_port.patch | 45 - ...t-send-arp-replies-if-src-and-target.patch | 37 - ...-rs5c372-support_alarms_up_to_1_week.patch | 94 - ...he_alarm_to_be_used_as_wakeup_source.patch | 71 - .../203-kallsyms_uncompressed.patch | 118 - .../205-backtrace_module_info.patch | 41 - ...e-filenames-from-deps_initramfs-list.patch | 30 - ...able_wilink_platform_without_drivers.patch | 20 - .../270-platform-mikrotik-build-bits.patch | 31 - .../300-mips_expose_boot_raw.patch | 40 - ...rriers-between-dcache-icache-flushes.patch | 71 - .../302-mips_no_branch_likely.patch | 22 - .../pending-6.1/305-mips_module_reloc.patch | 370 - .../pending-6.1/308-mips32r2_tune.patch | 22 - .../310-arm_module_unresolved_weak_sym.patch | 22 - ...t-command-line-parameters-from-users.patch | 282 - .../332-arc-add-OWRTDTB-section.patch | 84 - ...able-unaligned-access-in-kernel-mode.patch | 24 - ...ernel-XZ-compression-option-on-PPC_8.patch | 25 - ...el-fix-detect_memory_region-function.patch | 74 - ...ip-bcm-6345-l1-request-memory-region.patch | 113 - .../400-mtd-mtdsplit-support.patch | 328 - ...er-NVMEM-devices-for-partitions-with.patch | 48 - ...support-for-minor-aligned-partitions.patch | 245 - .../pending-6.1/420-mtd-redboot_space.patch | 41 - ...30-mtd-add-myloader-partition-parser.patch | 229 - ...check-for-bad-blocks-when-calculatin.patch | 68 - ...bcm47xxpart-detect-T_Meter-partition.patch | 37 - ...mtd-add-routerbootpart-parser-config.patch | 38 - ...dings-mtd-add-basic-bindings-for-UBI.patch | 121 - ...ubi-volume-allow-UBI-volumes-to-prov.patch | 48 - ...e-notifier-to-create-ubiblock-from-p.patch | 225 - ...0-04-mtd-ubi-attach-from-device-tree.patch | 264 - ...e-pre-removal-notification-for-UBI-v.patch | 226 - ...6-mtd-ubi-populate-ubi-volume-fwnode.patch | 65 - ...provide-NVMEM-layer-over-UBI-volumes.patch | 246 - ...k-add-basic-bindings-for-block-devic.patch | 120 - ...-09-block-partitions-populate-fwnode.patch | 77 - ...ck-add-new-genhd-flag-GENHD_FL_NVMEM.patch | 29 - ...50-11-block-implement-NVMEM-provider.patch | 235 - ...-mmc-mmc-card-add-block-device-nodes.patch | 74 - ...0-13-mmc-core-set-card-fwnode_handle.patch | 23 - ...mmc-block-set-fwnode-of-disk-devices.patch | 39 - .../450-15-mmc-block-set-GENHD_FL_NVMEM.patch | 22 - ...mtd-cfi_cmdset_0002-no-erase_suspend.patch | 25 - ...et_0002-add-buffer-write-cmd-timeout.patch | 17 - ...25p80-mx-disable-software-protection.patch | 18 - .../476-mtd-spi-nor-add-eon-en25q128.patch | 19 - .../477-mtd-spi-nor-add-eon-en25qx128a.patch | 21 - .../479-mtd-spi-nor-add-xtx-xt25f128b.patch | 81 - ...r-add-support-for-Gigadevice-GD25D05.patch | 23 - .../482-mtd-spi-nor-add-gd25q512.patch | 23 - .../484-mtd-spi-nor-add-esmt-f25l16pa.patch | 24 - .../485-mtd-spi-nor-add-xmc-xm25qh128c.patch | 25 - ...nand-add-support-for-ESMT-F50x1G41LB.patch | 143 - ...nd-Add-support-for-Etron-EM73D044VCx.patch | 168 - .../488-mtd-spi-nor-add-xmc-xm25qh64c.patch | 23 - ...mtd-device-named-ubi-or-data-on-boot.patch | 98 - ...to-create-ubiblock-device-for-rootfs.patch | 77 - ...ting-ubi0-rootfs-in-init-do_mounts.c.patch | 53 - ...ROOT_DEV-to-ubiblock-rootfs-if-unset.patch | 34 - .../494-mtd-ubi-add-EOF-marker-support.patch | 60 - ...-add-bindings-for-mtd-concat-devices.patch | 52 - ...cat-add-dt-driver-for-concat-devices.patch | 216 - ...i-nor-locking-support-for-MX25L6405D.patch | 32 - ...i-nor-disable-16-bit-sr-for-macronix.patch | 30 - .../500-fs_cdrom_dependencies.patch | 52 - ...add-uImage.FIT-subimage-block-driver.patch | 733 -- ...ass-device-lookup-for-dev-fit-rootfs.patch | 25 - .../530-jffs2_make_lzma_available.patch | 5180 ----------- .../pending-6.1/532-jffs2_eofdetect.patch | 65 - .../600-netfilter_conntrack_flush.patch | 90 - ...etfilter_match_bypass_default_checks.patch | 110 - ...netfilter_match_bypass_default_table.patch | 106 - ...netfilter_match_reduce_memory_access.patch | 22 - ...del-do-not-defer-queue-length-update.patch | 86 - .../pending-6.1/630-packet_socket_type.patch | 138 - .../pending-6.1/655-increase_skb_pad.patch | 20 - ...Add-support-for-MAP-E-FMRs-mesh-mode.patch | 511 -- ...ng-with-source-address-failed-policy.patch | 263 - ...nes-for-_POLICY_FAILED-until-all-cod.patch | 50 - ...680-net-add-TCP-fraglist-GRO-support.patch | 627 -- ...83-of_net-add-mac-address-to-of-tree.patch | 75 - ...ow_offload-handle-netdevice-events-f.patch | 110 - ...les-ignore-EOPNOTSUPP-on-flowtable-d.patch | 29 - ...net-mtk_eth_soc-enable-threaded-NAPI.patch | 21 - ...detach-callback-to-struct-phy_driver.patch | 38 - ...les-fix-bidirectional-offload-regres.patch | 24 - ...a-tag_mtk-add-padding-for-tx-packets.patch | 28 - ...d-knob-for-filtering-rx-tx-BPDU-pack.patch | 174 - ...-qca8k-implement-lag_fdb_add-del-ops.patch | 86 - ...a8k-enable-flooding-to-both-CPU-port.patch | 37 - ...k-add-support-for-port_change_master.patch | 158 - ...enable-assisted-learning-on-CPU-port.patch | 57 - ...pq8074-add-clock-frequency-to-MDIO-n.patch | 25 - ...rtl8221-allow-to-configure-SERDES-mo.patch | 106 - ...support-switching-between-SGMII-and-.patch | 61 - ...-use-genphy_soft_reset-for-2.5G-PHYs.patch | 65 - ...sable-SGMII-in-band-AN-for-2-5G-PHYs.patch | 43 - ...make-sure-paged-read-is-protected-by.patch | 35 - ...use-inline-functions-for-10GbE-adver.patch | 60 - ...check-validity-of-10GbE-link-partner.patch | 28 - ...-phy-realtek-introduce-rtl822x_probe.patch | 84 - ...tek-detect-early-version-of-RTL8221B.patch | 71 - ...0211_ptr-even-with-no-CFG82111-suppo.patch | 59 - ..._eth_soc-compile-out-netsys-v2-code-.patch | 44 - ..._eth_soc-work-around-issue-with-send.patch | 94 - ...rnet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch | 21 - ..._eth_soc-fix-remaining-throughput-re.patch | 42 - ..._eth_soc-ppe-fix-L2-offloading-with-.patch | 33 - ..._eth_soc-add-paths-and-SerDes-modes-.patch | 936 -- ..._eth_soc-set-coherent-mask-to-get-PP.patch | 46 - ...y-mediatek-xfi-tphy-add-new-bindings.patch | 136 - ...hy-add-driver-for-MediaTek-XFI-T-PHY.patch | 498 -- ...lynxi-add-platform-driver-for-MT7988.patch | 371 - ...pcs-add-bindings-for-MediaTek-USXGMI.patch | 81 - ...-add-driver-for-MediaTek-USXGMII-PCS.patch | 547 -- ...et-phy-motorcomm-Add-missing-include.patch | 22 - ...ealtek-support-interrupt-of-RTL8221B.patch | 75 - ...11h-reset-netdev-rules-when-LED-is-s.patch | 45 - ...ional-threading-for-backlog-processi.patch | 227 - ...equest-assisted-learning-on-CPU-port.patch | 27 - ...a-b53-add-support-for-BCM63xx-RGMIIs.patch | 174 - ...-net-dsa-b53-mmap-add-more-63xx-SoCs.patch | 108 - ...dsa-b53-mmap-allow-passing-a-chip-ID.patch | 195 - ...b53-add-BCM63268-RGMII-configuration.patch | 123 - ...sa-b53-mdio-add-support-for-BCM53134.patch | 189 - ...-missing-linux-if_ether.h-for-ETH_AL.patch | 61 - ...-bus-mhi-core-add-SBL-state-callback.patch | 48 - ...ice-struct-copy-its-DMA-params-to-th.patch | 73 - ...pio-cascade-add-generic-GPIO-cascade.patch | 222 - ...e-old-opp-to-config_clks-on-_set_opp.patch | 108 - ...env-align-endianness-of-crc32-values.patch | 45 - ...-support-mac-base-fixed-layout-cells.patch | 124 - .../810-pci_disable_common_quirks.patch | 62 - .../811-pci_disable_usb_common_quirks.patch | 115 - ...problem-with-platfom-data-in-w1-gpio.patch | 26 - .../pending-6.1/834-ledtrig-libata.patch | 149 - ...40-hwrng-bcm2835-set-quality-to-1000.patch | 26 - ...e-main-irq_chip-structure-a-static-d.patch | 102 - ...add-BCM63268-timer-clock-definitions.patch | 114 - ...add-BCM63268-timer-reset-definitions.patch | 107 - ...CM63268-timer-clock-and-reset-driver.patch | 345 - ...rack-busclk-state-to-avoid-bus-error.patch | 61 - ...-nxp-imx7d-pico-add-cpu-supply-nodes.patch | 43 - ...-add-LED_FUNCTION_MOBILE-for-mobile-.patch | 37 - ...-add-LED_FUNCTION_SPEED_-for-link-sp.patch | 37 - .../pending-6.1/920-mangle_bootargs.patch | 71 - ...on-Fix-compilation-warning-for-wrong.patch | 51 - 781 files changed, 124368 deletions(-) delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch delete mode 100644 target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch delete mode 100644 target/linux/generic/backport-6.1/200-v6.3-bitfield-add-FIELD_PREP_CONST.patch delete mode 100644 target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch delete mode 100644 target/linux/generic/backport-6.1/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch delete mode 100644 target/linux/generic/backport-6.1/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch delete mode 100644 target/linux/generic/backport-6.1/400-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch delete mode 100644 target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch delete mode 100644 target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch delete mode 100644 target/linux/generic/backport-6.1/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch delete mode 100644 target/linux/generic/backport-6.1/410-v6.2-mtd-spi-nor-add-generic-flash-driver.patch delete mode 100644 target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch delete mode 100644 target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch delete mode 100644 target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch delete mode 100644 target/linux/generic/backport-6.1/424-v6.3-mtd-ubi-wire-up-parent-MTD-device.patch delete mode 100644 target/linux/generic/backport-6.1/425-v6.3-mtd-ubi-block-wire-up-device-parent.patch delete mode 100644 target/linux/generic/backport-6.1/426-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch delete mode 100644 target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch delete mode 100644 target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch delete mode 100644 target/linux/generic/backport-6.1/701-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch delete mode 100644 target/linux/generic/backport-6.1/702-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch delete mode 100644 target/linux/generic/backport-6.1/702-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch delete mode 100644 target/linux/generic/backport-6.1/702-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch delete mode 100644 target/linux/generic/backport-6.1/703-v6.3-net-mdio-Add-dedicated-C45-API-to-MDIO-bus-drivers.patch delete mode 100644 target/linux/generic/backport-6.1/704-v6.6-net-phy-Introduce-PSGMII-PHY-interface-mode.patch delete mode 100644 target/linux/generic/backport-6.1/705-v6.4-net-phy-at803x-Replace-of_gpio.h-with-what-indeed-is.patch delete mode 100644 target/linux/generic/backport-6.1/706-v6.6-01-net-phy-at803x-support-qca8081-genphy_c45_pma_read_a.patch delete mode 100644 target/linux/generic/backport-6.1/706-v6.6-02-net-phy-at803x-merge-qca8081-slave-seed-function.patch delete mode 100644 target/linux/generic/backport-6.1/706-v6.6-03-net-phy-at803x-enable-qca8081-slave-seed-conditional.patch delete mode 100644 target/linux/generic/backport-6.1/706-v6.6-04-net-phy-at803x-support-qca8081-1G-chip-type.patch delete mode 100644 target/linux/generic/backport-6.1/706-v6.6-05-net-phy-at803x-remove-qca8081-1G-fast-retrain-and-sl.patch delete mode 100644 target/linux/generic/backport-6.1/706-v6.6-06-net-phy-at803x-add-qca8081-fifo-reset-on-the-link-ch.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-02-net-phy-at803x-move-disable-WOL-to-specific-at8031-p.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-03-net-phy-at803x-raname-hw_stats-functions-to-qca83xx-.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-04-net-phy-at803x-move-qca83xx-specific-check-in-dedica.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-05-net-phy-at803x-move-specific-DT-option-for-at8031-to.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-06-net-phy-at803x-move-specific-at8031-probe-mode-check.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-07-net-phy-at803x-move-specific-at8031-config_init-to-d.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-08-net-phy-at803x-move-specific-at8031-WOL-bits-to-dedi.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-09-net-phy-at803x-move-specific-at8031-config_intr-to-d.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-10-net-phy-at803x-make-at8031-related-DT-functions-name.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-11-net-phy-at803x-move-at8031-functions-in-dedicated-se.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-12-net-phy-at803x-move-at8035-specific-DT-parse-to-dedi.patch delete mode 100644 target/linux/generic/backport-6.1/707-v6.8-13-net-phy-at803x-drop-specific-PHY-ID-check-from-cable.patch delete mode 100644 target/linux/generic/backport-6.1/708-v6.8-01-net-phy-at803x-move-specific-qca808x-config_aneg-to-.patch delete mode 100644 target/linux/generic/backport-6.1/708-v6.8-02-net-phy-at803x-make-read-specific-status-function-mo.patch delete mode 100644 target/linux/generic/backport-6.1/709-v6.8-01-net-phy-at803x-remove-extra-space-after-cast.patch delete mode 100644 target/linux/generic/backport-6.1/709-v6.8-02-net-phy-at803x-replace-msleep-1-with-usleep_range.patch delete mode 100644 target/linux/generic/backport-6.1/710-v6.8-net-phy-at803x-better-align-function-varibles-to-ope.patch delete mode 100644 target/linux/generic/backport-6.1/711-v6.8-01-net-phy-at803x-generalize-cdt-fault-length-function.patch delete mode 100644 target/linux/generic/backport-6.1/711-v6.8-02-net-phy-at803x-refactor-qca808x-cable-test-get-statu.patch delete mode 100644 target/linux/generic/backport-6.1/711-v6.8-03-net-phy-at803x-add-support-for-cdt-cross-short-test-.patch delete mode 100644 target/linux/generic/backport-6.1/711-v6.8-04-net-phy-at803x-make-read_status-more-generic.patch delete mode 100644 target/linux/generic/backport-6.1/712-v6.9-net-phy-at803x-add-LED-support-for-qca808x.patch delete mode 100644 target/linux/generic/backport-6.1/713-v6.9-01-net-phy-move-at803x-PHY-driver-to-dedicated-director.patch delete mode 100644 target/linux/generic/backport-6.1/713-v6.9-02-net-phy-qcom-create-and-move-functions-to-shared-lib.patch delete mode 100644 target/linux/generic/backport-6.1/713-v6.9-03-net-phy-qcom-deatch-qca83xx-PHY-driver-from-at803x.patch delete mode 100644 target/linux/generic/backport-6.1/713-v6.9-04-net-phy-qcom-move-additional-functions-to-shared-lib.patch delete mode 100644 target/linux/generic/backport-6.1/713-v6.9-05-net-phy-qcom-detach-qca808x-PHY-driver-from-at803x.patch delete mode 100644 target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch delete mode 100644 target/linux/generic/backport-6.1/714-v6.8-01-net-phy-make-addr-type-u8-in-phy_package_shared-stru.patch delete mode 100644 target/linux/generic/backport-6.1/714-v6.8-02-net-phy-extend-PHY-package-API-to-support-multiple-g.patch delete mode 100644 target/linux/generic/backport-6.1/714-v6.8-03-net-phy-restructure-__phy_write-read_mmd-to-helper-a.patch delete mode 100644 target/linux/generic/backport-6.1/714-v6.8-04-net-phy-add-support-for-PHY-package-MMD-read-write.patch delete mode 100644 target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch delete mode 100644 target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch delete mode 100644 target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch delete mode 100644 target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch delete mode 100644 target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch delete mode 100644 target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch delete mode 100644 target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch delete mode 100644 target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch delete mode 100644 target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch delete mode 100644 target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch delete mode 100644 target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch delete mode 100644 target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch delete mode 100644 target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch delete mode 100644 target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch delete mode 100644 target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch delete mode 100644 target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch delete mode 100644 target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch delete mode 100644 target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch delete mode 100644 target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch delete mode 100644 target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch delete mode 100644 target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch delete mode 100644 target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch delete mode 100644 target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch delete mode 100644 target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch delete mode 100644 target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch delete mode 100644 target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch delete mode 100644 target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch delete mode 100644 target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch delete mode 100644 target/linux/generic/backport-6.1/715-v6.9-01-net-phy-qcom-qca808x-fix-logic-error-in-LED-brightne.patch delete mode 100644 target/linux/generic/backport-6.1/715-v6.9-02-net-phy-qcom-qca808x-default-to-LED-active-High-if-n.patch delete mode 100644 target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch delete mode 100644 target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch delete mode 100644 target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch delete mode 100644 target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch delete mode 100644 target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch delete mode 100644 target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch delete mode 100644 target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch delete mode 100644 target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch delete mode 100644 target/linux/generic/backport-6.1/717-v6.9-net-phy-qca807x-move-interface-mode-check-to-.config.patch delete mode 100644 target/linux/generic/backport-6.1/718-v6.9-net-phy-qcom-at803x-fix-kernel-panic-with-at8031_pro.patch delete mode 100644 target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch delete mode 100644 target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch delete mode 100644 target/linux/generic/backport-6.1/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch delete mode 100644 target/linux/generic/backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch delete mode 100644 target/linux/generic/backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch delete mode 100644 target/linux/generic/backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch delete mode 100644 target/linux/generic/backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch delete mode 100644 target/linux/generic/backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch delete mode 100644 target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch delete mode 100644 target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch delete mode 100644 target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch delete mode 100644 target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch delete mode 100644 target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch delete mode 100644 target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch delete mode 100644 target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch delete mode 100644 target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch delete mode 100644 target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch delete mode 100644 target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch delete mode 100644 target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch delete mode 100644 target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch delete mode 100644 target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch delete mode 100644 target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch delete mode 100644 target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch delete mode 100644 target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch delete mode 100644 target/linux/generic/backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch delete mode 100644 target/linux/generic/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch delete mode 100644 target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch delete mode 100644 target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch delete mode 100644 target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch delete mode 100644 target/linux/generic/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch delete mode 100644 target/linux/generic/backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch delete mode 100644 target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch delete mode 100644 target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch delete mode 100644 target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch delete mode 100644 target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch delete mode 100644 target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch delete mode 100644 target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch delete mode 100644 target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch delete mode 100644 target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch delete mode 100644 target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch delete mode 100644 target/linux/generic/backport-6.1/734-v6.8-net-phy-bcm54612e-add-suspend-resume.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch delete mode 100644 target/linux/generic/backport-6.1/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch delete mode 100644 target/linux/generic/backport-6.1/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch delete mode 100644 target/linux/generic/backport-6.1/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch delete mode 100644 target/linux/generic/backport-6.1/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch delete mode 100644 target/linux/generic/backport-6.1/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch delete mode 100644 target/linux/generic/backport-6.1/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch delete mode 100644 target/linux/generic/backport-6.1/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch delete mode 100644 target/linux/generic/backport-6.1/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch delete mode 100644 target/linux/generic/backport-6.1/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch delete mode 100644 target/linux/generic/backport-6.1/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch delete mode 100644 target/linux/generic/backport-6.1/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch delete mode 100644 target/linux/generic/backport-6.1/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch delete mode 100644 target/linux/generic/backport-6.1/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch delete mode 100644 target/linux/generic/backport-6.1/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch delete mode 100644 target/linux/generic/backport-6.1/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch delete mode 100644 target/linux/generic/backport-6.1/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch delete mode 100644 target/linux/generic/backport-6.1/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch delete mode 100644 target/linux/generic/backport-6.1/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch delete mode 100644 target/linux/generic/backport-6.1/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch delete mode 100644 target/linux/generic/backport-6.1/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch delete mode 100644 target/linux/generic/backport-6.1/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch delete mode 100644 target/linux/generic/backport-6.1/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch delete mode 100644 target/linux/generic/backport-6.1/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch delete mode 100644 target/linux/generic/backport-6.1/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch delete mode 100644 target/linux/generic/backport-6.1/760-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch delete mode 100644 target/linux/generic/backport-6.1/761-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch delete mode 100644 target/linux/generic/backport-6.1/762-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch delete mode 100644 target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch delete mode 100644 target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch delete mode 100644 target/linux/generic/backport-6.1/770-net-introduce-napi_is_scheduled-helper.patch delete mode 100644 target/linux/generic/backport-6.1/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch delete mode 100644 target/linux/generic/backport-6.1/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch delete mode 100644 target/linux/generic/backport-6.1/771-v6.7-03-net-stmmac-increase-TX-coalesce-timer-to-5ms.patch delete mode 100644 target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch delete mode 100644 target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch delete mode 100644 target/linux/generic/backport-6.1/778-v6.3-01-net-dsa-qca8k-add-QCA8K_ATU_TABLE_SIZE-define-for-fd.patch delete mode 100644 target/linux/generic/backport-6.1/778-v6.3-02-net-dsa-qca8k-convert-to-regmap-read-write-API.patch delete mode 100644 target/linux/generic/backport-6.1/779-v6.5-net-dsa-qca8k-enable-use_single_write-for-qca8xxx.patch delete mode 100644 target/linux/generic/backport-6.1/780-v6.6-01-net-dsa-qca8k-make-learning-configurable-and-keep-of.patch delete mode 100644 target/linux/generic/backport-6.1/780-v6.6-02-net-dsa-qca8k-limit-user-ports-access-to-the-first-C.patch delete mode 100644 target/linux/generic/backport-6.1/780-v6.6-03-net-dsa-qca8k-move-qca8xxx-hol-fixup-to-separate-fun.patch delete mode 100644 target/linux/generic/backport-6.1/780-v6.6-04-net-dsa-qca8k-use-dsa_for_each-macro-instead-of-for-.patch delete mode 100644 target/linux/generic/backport-6.1/781-v6.6-01-net-dsa-qca8k-fix-regmap-bulk-read-write-methods-on-.patch delete mode 100644 target/linux/generic/backport-6.1/790-01-v6.2-net-dsa-mt7530-remove-redundant-assignment.patch delete mode 100644 target/linux/generic/backport-6.1/790-02-v6.4-net-dsa-mt7530-use-external-PCS-driver.patch delete mode 100644 target/linux/generic/backport-6.1/790-03-v6.4-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch delete mode 100644 target/linux/generic/backport-6.1/790-04-v6.4-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch delete mode 100644 target/linux/generic/backport-6.1/790-05-v6.4-net-dsa-mt7530-use-unlocked-regmap-accessors.patch delete mode 100644 target/linux/generic/backport-6.1/790-06-v6.4-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch delete mode 100644 target/linux/generic/backport-6.1/790-07-v6.4-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch delete mode 100644 target/linux/generic/backport-6.1/790-08-v6.4-net-dsa-mt7530-introduce-mutex-helpers.patch delete mode 100644 target/linux/generic/backport-6.1/790-09-v6.4-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch delete mode 100644 target/linux/generic/backport-6.1/790-10-v6.4-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch delete mode 100644 target/linux/generic/backport-6.1/790-11-v6.4-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch delete mode 100644 target/linux/generic/backport-6.1/790-12-v6.4-net-dsa-mt7530-introduce-separate-MDIO-driver.patch delete mode 100644 target/linux/generic/backport-6.1/790-13-v6.4-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch delete mode 100644 target/linux/generic/backport-6.1/790-14-v6.4-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch delete mode 100644 target/linux/generic/backport-6.1/790-15-v6.4-net-dsa-mt7530-fix-support-for-MT7531BE.patch delete mode 100644 target/linux/generic/backport-6.1/790-17-v6.5-net-dsa-mt7530-update-PCS-driver-to-use-neg_mode.patch delete mode 100644 target/linux/generic/backport-6.1/790-18-v6.7-net-dsa-mt7530-Convert-to-platform-remove-callback-r.patch delete mode 100644 target/linux/generic/backport-6.1/790-19-v6.7-net-dsa-mt753x-remove-mt753x_phylink_pcs_link_up.patch delete mode 100644 target/linux/generic/backport-6.1/790-20-v6.7-net-dsa-mt7530-replace-deprecated-strncpy-with-ethto.patch delete mode 100644 target/linux/generic/backport-6.1/790-21-v6.9-net-dsa-mt7530-support-OF-based-registration-of-swit.patch delete mode 100644 target/linux/generic/backport-6.1/790-22-v6.8-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch delete mode 100644 target/linux/generic/backport-6.1/790-23-v6.9-net-dsa-mt7530-always-trap-frames-to-active-CPU-port.patch delete mode 100644 target/linux/generic/backport-6.1/790-24-v6.9-net-dsa-mt7530-use-p5_interface_select-as-data-type-.patch delete mode 100644 target/linux/generic/backport-6.1/790-25-v6.9-net-dsa-mt7530-store-port-5-SGMII-capability-of-MT75.patch delete mode 100644 target/linux/generic/backport-6.1/790-26-v6.9-net-dsa-mt7530-improve-comments-regarding-switch-por.patch delete mode 100644 target/linux/generic/backport-6.1/790-27-v6.9-net-dsa-mt7530-improve-code-path-for-setting-up-port.patch delete mode 100644 target/linux/generic/backport-6.1/790-28-v6.9-net-dsa-mt7530-do-not-set-priv-p5_interface-on-mt753.patch delete mode 100644 target/linux/generic/backport-6.1/790-29-v6.9-net-dsa-mt7530-do-not-run-mt7530_setup_port5-if-port.patch delete mode 100644 target/linux/generic/backport-6.1/790-30-v6.9-net-dsa-mt7530-empty-default-case-on-mt7530_setup_po.patch delete mode 100644 target/linux/generic/backport-6.1/790-31-v6.9-net-dsa-mt7530-move-XTAL-check-to-mt7530_setup.patch delete mode 100644 target/linux/generic/backport-6.1/790-32-v6.9-net-dsa-mt7530-simplify-mt7530_pad_clk_setup.patch delete mode 100644 target/linux/generic/backport-6.1/790-33-v6.9-net-dsa-mt7530-call-port-6-setup-from-mt7530_mac_con.patch delete mode 100644 target/linux/generic/backport-6.1/790-34-v6.9-net-dsa-mt7530-remove-pad_setup-function-pointer.patch delete mode 100644 target/linux/generic/backport-6.1/790-35-v6.9-net-dsa-mt7530-correct-port-capabilities-of-MT7988.patch delete mode 100644 target/linux/generic/backport-6.1/790-36-v6.9-net-dsa-mt7530-do-not-clear-config-supported_interfa.patch delete mode 100644 target/linux/generic/backport-6.1/790-37-v6.9-net-dsa-mt7530-remove-.mac_port_config-for-MT7988-an.patch delete mode 100644 target/linux/generic/backport-6.1/790-38-v6.9-net-dsa-mt7530-set-interrupt-register-only-for-MT753.patch delete mode 100644 target/linux/generic/backport-6.1/790-39-v6.9-net-dsa-mt7530-do-not-use-SW_PHY_RST-to-reset-MT7531.patch delete mode 100644 target/linux/generic/backport-6.1/790-40-v6.9-net-dsa-mt7530-get-rid-of-useless-error-returns-on-p.patch delete mode 100644 target/linux/generic/backport-6.1/790-41-v6.9-net-dsa-mt7530-get-rid-of-priv-info-cpu_port_config.patch delete mode 100644 target/linux/generic/backport-6.1/790-42-v6.9-net-dsa-mt7530-get-rid-of-mt753x_mac_config.patch delete mode 100644 target/linux/generic/backport-6.1/790-43-v6.9-net-dsa-mt7530-put-initialising-PCS-devices-code-bac.patch delete mode 100644 target/linux/generic/backport-6.1/790-44-v6.9-net-dsa-mt7530-sort-link-settings-ops-and-force-link.patch delete mode 100644 target/linux/generic/backport-6.1/790-45-v6.9-net-dsa-mt7530-simplify-link-operations.patch delete mode 100644 target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch delete mode 100644 target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch delete mode 100644 target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch delete mode 100644 target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch delete mode 100644 target/linux/generic/backport-6.1/790-54-v6.10-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch delete mode 100644 target/linux/generic/backport-6.1/790-55-v6.10-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch delete mode 100644 target/linux/generic/backport-6.1/790-56-v6.10-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch delete mode 100644 target/linux/generic/backport-6.1/790-57-v6.10-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch delete mode 100644 target/linux/generic/backport-6.1/790-58-v6.10-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch delete mode 100644 target/linux/generic/backport-6.1/790-59-v6.10-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch delete mode 100644 target/linux/generic/backport-6.1/790-60-v6.10-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch delete mode 100644 target/linux/generic/backport-6.1/790-61-v6.10-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch delete mode 100644 target/linux/generic/backport-6.1/790-62-v6.10-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch delete mode 100644 target/linux/generic/backport-6.1/790-63-v6.10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch delete mode 100644 target/linux/generic/backport-6.1/790-64-v6.10-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch delete mode 100644 target/linux/generic/backport-6.1/790-65-v6.10-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch delete mode 100644 target/linux/generic/backport-6.1/790-66-v6.10-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch delete mode 100644 target/linux/generic/backport-6.1/790-67-v6.10-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch delete mode 100644 target/linux/generic/backport-6.1/790-68-v6.10-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch delete mode 100644 target/linux/generic/backport-6.1/790-69-v6.10-net-dsa-mt7530-do-not-set-MT7530_P5_DIS-when-PHY-.patch delete mode 100644 target/linux/generic/backport-6.1/790-70-v6.10-796-net-dsa-mt7530-detect-PHY-muxing-when-PHY-is-defined.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch delete mode 100644 target/linux/generic/backport-6.1/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch delete mode 100644 target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch delete mode 100644 target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch delete mode 100644 target/linux/generic/backport-6.1/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch delete mode 100644 target/linux/generic/backport-6.1/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch delete mode 100644 target/linux/generic/backport-6.1/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch delete mode 100644 target/linux/generic/backport-6.1/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch delete mode 100644 target/linux/generic/backport-6.1/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch delete mode 100644 target/linux/generic/backport-6.1/795-v6.6-09-r8152-set-bp-in-bulk.patch delete mode 100644 target/linux/generic/backport-6.1/795-v6.6-10-eth-r8152-try-to-use-a-normal-budget.patch delete mode 100644 target/linux/generic/backport-6.1/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch delete mode 100644 target/linux/generic/backport-6.1/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch delete mode 100644 target/linux/generic/backport-6.1/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch delete mode 100644 target/linux/generic/backport-6.1/795-v6.7-16-r8152-use-napi_gro_frags.patch delete mode 100644 target/linux/generic/backport-6.1/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch delete mode 100644 target/linux/generic/backport-6.1/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch delete mode 100644 target/linux/generic/backport-6.1/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch delete mode 100644 target/linux/generic/backport-6.1/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch delete mode 100644 target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch delete mode 100644 target/linux/generic/backport-6.1/798-v6.10-net-phy-air_en8811h-Add-the-Airoha-EN8811H-PHY-drive.patch delete mode 100644 target/linux/generic/backport-6.1/799-v6.10-net-phy-air_en8811h-fix-some-error-codes.patch delete mode 100644 target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch delete mode 100644 target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch delete mode 100644 target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch delete mode 100644 target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch delete mode 100644 target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch delete mode 100644 target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch delete mode 100644 target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch delete mode 100644 target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch delete mode 100644 target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch delete mode 100644 target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch delete mode 100644 target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch delete mode 100644 target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch delete mode 100644 target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch delete mode 100644 target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch delete mode 100644 target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch delete mode 100644 target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch delete mode 100644 target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch delete mode 100644 target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch delete mode 100644 target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch delete mode 100644 target/linux/generic/backport-6.1/806-v6.5-net-dsa-qca8k-add-support-for-additional-modes-for-n.patch delete mode 100644 target/linux/generic/backport-6.1/807-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch delete mode 100644 target/linux/generic/backport-6.1/807-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch delete mode 100644 target/linux/generic/backport-6.1/807-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch delete mode 100644 target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch delete mode 100644 target/linux/generic/backport-6.1/807-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch delete mode 100644 target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch delete mode 100644 target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch delete mode 100644 target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch delete mode 100644 target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch delete mode 100644 target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch delete mode 100644 target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch delete mode 100644 target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch delete mode 100644 target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch delete mode 100644 target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch delete mode 100644 target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch delete mode 100644 target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch delete mode 100644 target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch delete mode 100644 target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch delete mode 100644 target/linux/generic/backport-6.1/815-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch delete mode 100644 target/linux/generic/backport-6.1/815-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch delete mode 100644 target/linux/generic/backport-6.1/815-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch delete mode 100644 target/linux/generic/backport-6.1/815-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch delete mode 100644 target/linux/generic/backport-6.1/815-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch delete mode 100644 target/linux/generic/backport-6.1/816-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch delete mode 100644 target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch delete mode 100644 target/linux/generic/backport-6.1/816-v6.7-0003-nvmem-Use-device_get_match_data.patch delete mode 100644 target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch delete mode 100644 target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch delete mode 100644 target/linux/generic/backport-6.1/816-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch delete mode 100644 target/linux/generic/backport-6.1/817-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch delete mode 100644 target/linux/generic/backport-6.1/817-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch delete mode 100644 target/linux/generic/backport-6.1/818-v6.8-of-device-Export-of_device_make_bus_id.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch delete mode 100644 target/linux/generic/backport-6.1/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch delete mode 100644 target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch delete mode 100644 target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch delete mode 100644 target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch delete mode 100644 target/linux/generic/backport-6.1/823-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch delete mode 100644 target/linux/generic/backport-6.1/823-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch delete mode 100644 target/linux/generic/backport-6.1/823-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch delete mode 100644 target/linux/generic/backport-6.1/823-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch delete mode 100644 target/linux/generic/backport-6.1/823-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch delete mode 100644 target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch delete mode 100644 target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch delete mode 100644 target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch delete mode 100644 target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch delete mode 100644 target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch delete mode 100644 target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch delete mode 100644 target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch delete mode 100644 target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch delete mode 100644 target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch delete mode 100644 target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch delete mode 100644 target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch delete mode 100644 target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch delete mode 100644 target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch delete mode 100644 target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch delete mode 100644 target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch delete mode 100644 target/linux/generic/backport-6.1/829-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch delete mode 100644 target/linux/generic/backport-6.1/829-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch delete mode 100644 target/linux/generic/backport-6.1/829-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch delete mode 100644 target/linux/generic/backport-6.1/829-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch delete mode 100644 target/linux/generic/backport-6.1/829-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch delete mode 100644 target/linux/generic/backport-6.1/829-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch delete mode 100644 target/linux/generic/backport-6.1/829-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch delete mode 100644 target/linux/generic/backport-6.1/829-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch delete mode 100644 target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch delete mode 100644 target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch delete mode 100644 target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch delete mode 100644 target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch delete mode 100644 target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch delete mode 100644 target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch delete mode 100644 target/linux/generic/backport-6.1/831-v6.7-rtc-rtc7301-Support-byte-addressed-IO.patch delete mode 100644 target/linux/generic/backport-6.1/832-v6.7-net-phy-amd-Support-the-Altima-AMI101L.patch delete mode 100644 target/linux/generic/backport-6.1/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch delete mode 100644 target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch delete mode 100644 target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch delete mode 100644 target/linux/generic/backport-6.1/836-v6.7-leds-trigger-netdev-fix-RTNL-handling-to-prevent-pot.patch delete mode 100644 target/linux/generic/backport-6.1/837-v6.4-net-phy-hide-the-PHYLIB_LEDS-knob.patch delete mode 100644 target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch delete mode 100644 target/linux/generic/backport-6.1/839-v6.9-net-phy-aquantia-clear-PMD-Global-Transmit-Disable-b.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0006-nvmem-core-add-single-sysfs-group.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch delete mode 100644 target/linux/generic/backport-6.1/840-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch delete mode 100644 target/linux/generic/backport-6.1/841-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch delete mode 100644 target/linux/generic/backport-6.1/841-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch delete mode 100644 target/linux/generic/backport-6.1/841-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch delete mode 100644 target/linux/generic/backport-6.1/850-v6.2-bus-mhi-host-pci_generic-add-support-for-sc8280xp-cr.patch delete mode 100644 target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch delete mode 100644 target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch delete mode 100644 target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch delete mode 100644 target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch delete mode 100644 target/linux/generic/backport-6.1/855-v6.6-bus-mhi-host-pci_generic-Add-support-for-IP_SW0-chan.patch delete mode 100644 target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch delete mode 100644 target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch delete mode 100644 target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch delete mode 100644 target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch delete mode 100644 target/linux/generic/backport-6.1/861-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch delete mode 100644 target/linux/generic/backport-6.1/862-v6.8-bus-mhi-host-pci_generic-Add-SDX75-based-modem-suppo.patch delete mode 100644 target/linux/generic/backport-6.1/863-stable-bus-mhi-host-pci_generic-constify-modem_telit_fn980_.patch delete mode 100644 target/linux/generic/backport-6.1/864-v6.6-bus-mhi-host-allow-MHI-client-drivers-to-provide-the.patch delete mode 100644 target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch delete mode 100644 target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch delete mode 100644 target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch delete mode 100644 target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch delete mode 100644 target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch delete mode 100644 target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch delete mode 100644 target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch delete mode 100644 target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch delete mode 100644 target/linux/generic/backport-6.1/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch delete mode 100644 target/linux/generic/backport-6.1/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch delete mode 100644 target/linux/generic/backport-6.1/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch delete mode 100644 target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch delete mode 100644 target/linux/generic/backport-6.1/895-01-v6.8-net-phy-add-possible-interfaces.patch delete mode 100644 target/linux/generic/backport-6.1/895-02-v6.8-net-phylink-use-for_each_set_bit.patch delete mode 100644 target/linux/generic/backport-6.1/895-03-v6.8-net-phylink-split-out-per-interface-validation.patch delete mode 100644 target/linux/generic/backport-6.1/895-04-v6.8-net-phylink-pass-PHY-into-phylink_validate_one.patch delete mode 100644 target/linux/generic/backport-6.1/895-05-v6.8-net-phylink-pass-PHY-into-phylink_validate_mask.patch delete mode 100644 target/linux/generic/backport-6.1/895-06-v6.8-net-phylink-split-out-PHY-validation-from-phylink_br.patch delete mode 100644 target/linux/generic/backport-6.1/895-07-v6.8-net-phylink-use-the-PHY-s-possible_interfaces-if-pop.patch delete mode 100644 target/linux/generic/backport-6.1/897-01-v6.9-net-phy-qcom-qca808x-add-helper-for-checking-for-1G-.patch delete mode 100644 target/linux/generic/backport-6.1/897-02-v6.9-net-phy-qcom-qca808x-fill-in-possible_interfaces.patch delete mode 100644 target/linux/generic/config-6.1 delete mode 100644 target/linux/generic/hack-6.1/204-module_strip.patch delete mode 100644 target/linux/generic/hack-6.1/205-kconfig-abort-configuration-on-unset-symbol.patch delete mode 100644 target/linux/generic/hack-6.1/210-darwin_scripts_include.patch delete mode 100644 target/linux/generic/hack-6.1/211-darwin-uuid-typedef-clash.patch delete mode 100644 target/linux/generic/hack-6.1/212-tools_portability.patch delete mode 100644 target/linux/generic/hack-6.1/214-spidev_h_portability.patch delete mode 100644 target/linux/generic/hack-6.1/220-arm-gc_sections.patch delete mode 100644 target/linux/generic/hack-6.1/221-module_exports.patch delete mode 100644 target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch delete mode 100644 target/linux/generic/hack-6.1/250-netfilter_depends.patch delete mode 100644 target/linux/generic/hack-6.1/251-kconfig.patch delete mode 100644 target/linux/generic/hack-6.1/253-ksmbd-config.patch delete mode 100644 target/linux/generic/hack-6.1/259-regmap_dynamic.patch delete mode 100644 target/linux/generic/hack-6.1/260-crypto_test_dependencies.patch delete mode 100644 target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch delete mode 100644 target/linux/generic/hack-6.1/280-rfkill-stubs.patch delete mode 100644 target/linux/generic/hack-6.1/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch delete mode 100644 target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch delete mode 100644 target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch delete mode 100644 target/linux/generic/hack-6.1/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch delete mode 100644 target/linux/generic/hack-6.1/430-mtk-bmt-support.patch delete mode 100644 target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch delete mode 100644 target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch delete mode 100644 target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch delete mode 100644 target/linux/generic/hack-6.1/651-wireless_mesh_header.patch delete mode 100644 target/linux/generic/hack-6.1/660-fq_codel_defaults.patch delete mode 100644 target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch delete mode 100644 target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch delete mode 100644 target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch delete mode 100644 target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch delete mode 100644 target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch delete mode 100644 target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch delete mode 100644 target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch delete mode 100644 target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch delete mode 100644 target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch delete mode 100644 target/linux/generic/hack-6.1/761-dt-bindings-net-add-RTL8152-binding-documentation.patch delete mode 100644 target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch delete mode 100644 target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch delete mode 100644 target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch delete mode 100644 target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch delete mode 100644 target/linux/generic/hack-6.1/781-usb-net-rndis-support-asr.patch delete mode 100644 target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch delete mode 100644 target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch delete mode 100644 target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch delete mode 100644 target/linux/generic/hack-6.1/901-debloat_sock_diag.patch delete mode 100644 target/linux/generic/hack-6.1/902-debloat_proc.patch delete mode 100644 target/linux/generic/hack-6.1/904-debloat_dma_buf.patch delete mode 100644 target/linux/generic/hack-6.1/910-kobject_uevent.patch delete mode 100644 target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch delete mode 100644 target/linux/generic/hack-6.1/920-device_tree_cmdline.patch delete mode 100644 target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch delete mode 100644 target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch delete mode 100644 target/linux/generic/pending-6.1/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch delete mode 100644 target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch delete mode 100644 target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch delete mode 100644 target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch delete mode 100644 target/linux/generic/pending-6.1/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch delete mode 100644 target/linux/generic/pending-6.1/141-jffs2-add-RENAME_EXCHANGE-support.patch delete mode 100644 target/linux/generic/pending-6.1/142-jffs2-add-splice-ops.patch delete mode 100644 target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch delete mode 100644 target/linux/generic/pending-6.1/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch delete mode 100644 target/linux/generic/pending-6.1/190-rtc-rs5c372-support_alarms_up_to_1_week.patch delete mode 100644 target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch delete mode 100644 target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch delete mode 100644 target/linux/generic/pending-6.1/205-backtrace_module_info.patch delete mode 100644 target/linux/generic/pending-6.1/240-remove-unsane-filenames-from-deps_initramfs-list.patch delete mode 100644 target/linux/generic/pending-6.1/261-enable_wilink_platform_without_drivers.patch delete mode 100644 target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch delete mode 100644 target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch delete mode 100644 target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch delete mode 100644 target/linux/generic/pending-6.1/302-mips_no_branch_likely.patch delete mode 100644 target/linux/generic/pending-6.1/305-mips_module_reloc.patch delete mode 100644 target/linux/generic/pending-6.1/308-mips32r2_tune.patch delete mode 100644 target/linux/generic/pending-6.1/310-arm_module_unresolved_weak_sym.patch delete mode 100644 target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch delete mode 100644 target/linux/generic/pending-6.1/332-arc-add-OWRTDTB-section.patch delete mode 100644 target/linux/generic/pending-6.1/333-arc-enable-unaligned-access-in-kernel-mode.patch delete mode 100644 target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch delete mode 100644 target/linux/generic/pending-6.1/350-mips-kernel-fix-detect_memory_region-function.patch delete mode 100644 target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch delete mode 100644 target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch delete mode 100644 target/linux/generic/pending-6.1/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch delete mode 100644 target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch delete mode 100644 target/linux/generic/pending-6.1/420-mtd-redboot_space.patch delete mode 100644 target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch delete mode 100644 target/linux/generic/pending-6.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch delete mode 100644 target/linux/generic/pending-6.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch delete mode 100644 target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch delete mode 100644 target/linux/generic/pending-6.1/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch delete mode 100644 target/linux/generic/pending-6.1/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch delete mode 100644 target/linux/generic/pending-6.1/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch delete mode 100644 target/linux/generic/pending-6.1/450-04-mtd-ubi-attach-from-device-tree.patch delete mode 100644 target/linux/generic/pending-6.1/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch delete mode 100644 target/linux/generic/pending-6.1/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch delete mode 100644 target/linux/generic/pending-6.1/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch delete mode 100644 target/linux/generic/pending-6.1/450-08-dt-bindings-block-add-basic-bindings-for-block-devic.patch delete mode 100644 target/linux/generic/pending-6.1/450-09-block-partitions-populate-fwnode.patch delete mode 100644 target/linux/generic/pending-6.1/450-10-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch delete mode 100644 target/linux/generic/pending-6.1/450-11-block-implement-NVMEM-provider.patch delete mode 100644 target/linux/generic/pending-6.1/450-12-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch delete mode 100644 target/linux/generic/pending-6.1/450-13-mmc-core-set-card-fwnode_handle.patch delete mode 100644 target/linux/generic/pending-6.1/450-14-mmc-block-set-fwnode-of-disk-devices.patch delete mode 100644 target/linux/generic/pending-6.1/450-15-mmc-block-set-GENHD_FL_NVMEM.patch delete mode 100644 target/linux/generic/pending-6.1/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch delete mode 100644 target/linux/generic/pending-6.1/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch delete mode 100644 target/linux/generic/pending-6.1/465-m25p80-mx-disable-software-protection.patch delete mode 100644 target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch delete mode 100644 target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch delete mode 100644 target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch delete mode 100644 target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch delete mode 100644 target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch delete mode 100644 target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch delete mode 100644 target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch delete mode 100644 target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch delete mode 100644 target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch delete mode 100644 target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch delete mode 100644 target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch delete mode 100644 target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch delete mode 100644 target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch delete mode 100644 target/linux/generic/pending-6.1/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch delete mode 100644 target/linux/generic/pending-6.1/494-mtd-ubi-add-EOF-marker-support.patch delete mode 100644 target/linux/generic/pending-6.1/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch delete mode 100644 target/linux/generic/pending-6.1/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch delete mode 100644 target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch delete mode 100644 target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch delete mode 100644 target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch delete mode 100644 target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch delete mode 100644 target/linux/generic/pending-6.1/511-init-bypass-device-lookup-for-dev-fit-rootfs.patch delete mode 100644 target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch delete mode 100644 target/linux/generic/pending-6.1/532-jffs2_eofdetect.patch delete mode 100644 target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch delete mode 100644 target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch delete mode 100644 target/linux/generic/pending-6.1/611-netfilter_match_bypass_default_table.patch delete mode 100644 target/linux/generic/pending-6.1/612-netfilter_match_reduce_memory_access.patch delete mode 100644 target/linux/generic/pending-6.1/620-net_sched-codel-do-not-defer-queue-length-update.patch delete mode 100644 target/linux/generic/pending-6.1/630-packet_socket_type.patch delete mode 100644 target/linux/generic/pending-6.1/655-increase_skb_pad.patch delete mode 100644 target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch delete mode 100644 target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch delete mode 100644 target/linux/generic/pending-6.1/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch delete mode 100644 target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch delete mode 100644 target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch delete mode 100644 target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch delete mode 100644 target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch delete mode 100644 target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch delete mode 100644 target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch delete mode 100644 target/linux/generic/pending-6.1/704-netfilter-nf_tables-fix-bidirectional-offload-regres.patch delete mode 100644 target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch delete mode 100644 target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch delete mode 100644 target/linux/generic/pending-6.1/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch delete mode 100644 target/linux/generic/pending-6.1/711-02-net-dsa-qca8k-enable-flooding-to-both-CPU-port.patch delete mode 100644 target/linux/generic/pending-6.1/711-03-net-dsa-qca8k-add-support-for-port_change_master.patch delete mode 100644 target/linux/generic/pending-6.1/712-net-dsa-qca8k-enable-assisted-learning-on-CPU-port.patch delete mode 100644 target/linux/generic/pending-6.1/713-03-arm64-dts-qcom-ipq8074-add-clock-frequency-to-MDIO-n.patch delete mode 100644 target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch delete mode 100644 target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch delete mode 100644 target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch delete mode 100644 target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch delete mode 100644 target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch delete mode 100644 target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch delete mode 100644 target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch delete mode 100644 target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch delete mode 100644 target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch delete mode 100644 target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch delete mode 100644 target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch delete mode 100644 target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch delete mode 100644 target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch delete mode 100644 target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch delete mode 100644 target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch delete mode 100644 target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch delete mode 100644 target/linux/generic/pending-6.1/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch delete mode 100644 target/linux/generic/pending-6.1/739-01-dt-bindings-phy-mediatek-xfi-tphy-add-new-bindings.patch delete mode 100644 target/linux/generic/pending-6.1/739-02-phy-add-driver-for-MediaTek-XFI-T-PHY.patch delete mode 100644 target/linux/generic/pending-6.1/739-03-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch delete mode 100644 target/linux/generic/pending-6.1/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch delete mode 100644 target/linux/generic/pending-6.1/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch delete mode 100644 target/linux/generic/pending-6.1/740-net-phy-motorcomm-Add-missing-include.patch delete mode 100644 target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch delete mode 100644 target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch delete mode 100644 target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch delete mode 100644 target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch delete mode 100644 target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch delete mode 100644 target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch delete mode 100644 target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch delete mode 100644 target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch delete mode 100644 target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch delete mode 100644 target/linux/generic/pending-6.1/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch delete mode 100644 target/linux/generic/pending-6.1/790-bus-mhi-core-add-SBL-state-callback.patch delete mode 100644 target/linux/generic/pending-6.1/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch delete mode 100644 target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch delete mode 100644 target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch delete mode 100644 target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch delete mode 100644 target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch delete mode 100644 target/linux/generic/pending-6.1/810-pci_disable_common_quirks.patch delete mode 100644 target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch delete mode 100644 target/linux/generic/pending-6.1/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch delete mode 100644 target/linux/generic/pending-6.1/834-ledtrig-libata.patch delete mode 100644 target/linux/generic/pending-6.1/840-hwrng-bcm2835-set-quality-to-1000.patch delete mode 100644 target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch delete mode 100644 target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch delete mode 100644 target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch delete mode 100644 target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch delete mode 100644 target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch delete mode 100644 target/linux/generic/pending-6.1/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch delete mode 100644 target/linux/generic/pending-6.1/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch delete mode 100644 target/linux/generic/pending-6.1/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch delete mode 100644 target/linux/generic/pending-6.1/920-mangle_bootargs.patch delete mode 100644 target/linux/generic/pending-6.1/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch diff --git a/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch b/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch deleted file mode 100644 index 2428bdcb72c0ce..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-01-UPSTREAM-mm-multi-gen-LRU-rename-lru_gen_struct-to-l.patch +++ /dev/null @@ -1,352 +0,0 @@ -From 8c20e2eb5f2a0175b774134685e4d7bd93e85ff8 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:18:59 -0700 -Subject: [PATCH 01/19] UPSTREAM: mm: multi-gen LRU: rename lru_gen_struct to - lru_gen_folio - -Patch series "mm: multi-gen LRU: memcg LRU", v3. - -Overview -======== - -An memcg LRU is a per-node LRU of memcgs. It is also an LRU of LRUs, -since each node and memcg combination has an LRU of folios (see -mem_cgroup_lruvec()). - -Its goal is to improve the scalability of global reclaim, which is -critical to system-wide memory overcommit in data centers. Note that -memcg reclaim is currently out of scope. - -Its memory bloat is a pointer to each lruvec and negligible to each -pglist_data. In terms of traversing memcgs during global reclaim, it -improves the best-case complexity from O(n) to O(1) and does not affect -the worst-case complexity O(n). Therefore, on average, it has a sublinear -complexity in contrast to the current linear complexity. - -The basic structure of an memcg LRU can be understood by an analogy to -the active/inactive LRU (of folios): -1. It has the young and the old (generations), i.e., the counterparts - to the active and the inactive; -2. The increment of max_seq triggers promotion, i.e., the counterpart - to activation; -3. Other events trigger similar operations, e.g., offlining an memcg - triggers demotion, i.e., the counterpart to deactivation. - -In terms of global reclaim, it has two distinct features: -1. Sharding, which allows each thread to start at a random memcg (in - the old generation) and improves parallelism; -2. Eventual fairness, which allows direct reclaim to bail out at will - and reduces latency without affecting fairness over some time. - -The commit message in patch 6 details the workflow: -https://lore.kernel.org/r/20221222041905.2431096-7-yuzhao@google.com/ - -The following is a simple test to quickly verify its effectiveness. - - Test design: - 1. Create multiple memcgs. - 2. Each memcg contains a job (fio). - 3. All jobs access the same amount of memory randomly. - 4. The system does not experience global memory pressure. - 5. Periodically write to the root memory.reclaim. - - Desired outcome: - 1. All memcgs have similar pgsteal counts, i.e., stddev(pgsteal) - over mean(pgsteal) is close to 0%. - 2. The total pgsteal is close to the total requested through - memory.reclaim, i.e., sum(pgsteal) over sum(requested) is close - to 100%. - - Actual outcome [1]: - MGLRU off MGLRU on - stddev(pgsteal) / mean(pgsteal) 75% 20% - sum(pgsteal) / sum(requested) 425% 95% - - #################################################################### - MEMCGS=128 - - for ((memcg = 0; memcg < $MEMCGS; memcg++)); do - mkdir /sys/fs/cgroup/memcg$memcg - done - - start() { - echo $BASHPID > /sys/fs/cgroup/memcg$memcg/cgroup.procs - - fio -name=memcg$memcg --numjobs=1 --ioengine=mmap \ - --filename=/dev/zero --size=1920M --rw=randrw \ - --rate=64m,64m --random_distribution=random \ - --fadvise_hint=0 --time_based --runtime=10h \ - --group_reporting --minimal - } - - for ((memcg = 0; memcg < $MEMCGS; memcg++)); do - start & - done - - sleep 600 - - for ((i = 0; i < 600; i++)); do - echo 256m >/sys/fs/cgroup/memory.reclaim - sleep 6 - done - - for ((memcg = 0; memcg < $MEMCGS; memcg++)); do - grep "pgsteal " /sys/fs/cgroup/memcg$memcg/memory.stat - done - #################################################################### - -[1]: This was obtained from running the above script (touches less - than 256GB memory) on an EPYC 7B13 with 512GB DRAM for over an - hour. - -This patch (of 8): - -The new name lru_gen_folio will be more distinct from the coming -lru_gen_memcg. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-1-yuzhao@google.com -Link: https://lkml.kernel.org/r/20221222041905.2431096-2-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton -Bug: 274865848 -(cherry picked from commit 391655fe08d1f942359a11148aa9aaf3f99d6d6f) -Change-Id: I7df67e0e2435ba28f10eaa57d28d98b61a9210a6 -Signed-off-by: T.J. Mercier ---- - include/linux/mm_inline.h | 4 ++-- - include/linux/mmzone.h | 6 +++--- - mm/vmscan.c | 34 +++++++++++++++++----------------- - mm/workingset.c | 4 ++-- - 4 files changed, 24 insertions(+), 24 deletions(-) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -178,7 +178,7 @@ static inline void lru_gen_update_size(s - int zone = folio_zonenum(folio); - int delta = folio_nr_pages(folio); - enum lru_list lru = type * LRU_INACTIVE_FILE; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - - VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS); - VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS); -@@ -224,7 +224,7 @@ static inline bool lru_gen_add_folio(str - int gen = folio_lru_gen(folio); - int type = folio_is_file_lru(folio); - int zone = folio_zonenum(folio); -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - - VM_WARN_ON_ONCE_FOLIO(gen != -1, folio); - ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -404,7 +404,7 @@ enum { - * The number of pages in each generation is eventually consistent and therefore - * can be transiently negative when reset_batch_size() is pending. - */ --struct lru_gen_struct { -+struct lru_gen_folio { - /* the aging increments the youngest generation number */ - unsigned long max_seq; - /* the eviction increments the oldest generation numbers */ -@@ -461,7 +461,7 @@ struct lru_gen_mm_state { - struct lru_gen_mm_walk { - /* the lruvec under reclaim */ - struct lruvec *lruvec; -- /* unstable max_seq from lru_gen_struct */ -+ /* unstable max_seq from lru_gen_folio */ - unsigned long max_seq; - /* the next address within an mm to scan */ - unsigned long next_addr; -@@ -524,7 +524,7 @@ struct lruvec { - unsigned long flags; - #ifdef CONFIG_LRU_GEN - /* evictable pages divided into generations */ -- struct lru_gen_struct lrugen; -+ struct lru_gen_folio lrugen; - /* to concurrently iterate lru_gen_mm_list */ - struct lru_gen_mm_state mm_state; - #endif ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3190,7 +3190,7 @@ static int get_nr_gens(struct lruvec *lr - - static bool __maybe_unused seq_is_valid(struct lruvec *lruvec) - { -- /* see the comment on lru_gen_struct */ -+ /* see the comment on lru_gen_folio */ - return get_nr_gens(lruvec, LRU_GEN_FILE) >= MIN_NR_GENS && - get_nr_gens(lruvec, LRU_GEN_FILE) <= get_nr_gens(lruvec, LRU_GEN_ANON) && - get_nr_gens(lruvec, LRU_GEN_ANON) <= MAX_NR_GENS; -@@ -3596,7 +3596,7 @@ struct ctrl_pos { - static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain, - struct ctrl_pos *pos) - { -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - int hist = lru_hist_from_seq(lrugen->min_seq[type]); - - pos->refaulted = lrugen->avg_refaulted[type][tier] + -@@ -3611,7 +3611,7 @@ static void read_ctrl_pos(struct lruvec - static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover) - { - int hist, tier; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1; - unsigned long seq = carryover ? lrugen->min_seq[type] : lrugen->max_seq + 1; - -@@ -3688,7 +3688,7 @@ static int folio_update_gen(struct folio - static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, bool reclaiming) - { - int type = folio_is_file_lru(folio); -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]); - unsigned long new_flags, old_flags = READ_ONCE(folio->flags); - -@@ -3733,7 +3733,7 @@ static void update_batch_size(struct lru - static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk) - { - int gen, type, zone; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - - walk->batched = 0; - -@@ -4250,7 +4250,7 @@ static bool inc_min_seq(struct lruvec *l - { - int zone; - int remaining = MAX_LRU_BATCH; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]); - - if (type == LRU_GEN_ANON && !can_swap) -@@ -4286,7 +4286,7 @@ static bool try_to_inc_min_seq(struct lr - { - int gen, type, zone; - bool success = false; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - DEFINE_MIN_SEQ(lruvec); - - VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); -@@ -4307,7 +4307,7 @@ next: - ; - } - -- /* see the comment on lru_gen_struct */ -+ /* see the comment on lru_gen_folio */ - if (can_swap) { - min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]); - min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]); -@@ -4329,7 +4329,7 @@ static void inc_max_seq(struct lruvec *l - { - int prev, next; - int type, zone; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - - restart: - spin_lock_irq(&lruvec->lru_lock); -@@ -4389,7 +4389,7 @@ static bool try_to_inc_max_seq(struct lr - bool success; - struct lru_gen_mm_walk *walk; - struct mm_struct *mm = NULL; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - - VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq)); - -@@ -4454,7 +4454,7 @@ static bool should_run_aging(struct lruv - unsigned long old = 0; - unsigned long young = 0; - unsigned long total = 0; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - - for (type = !can_swap; type < ANON_AND_FILE; type++) { -@@ -4740,7 +4740,7 @@ static bool sort_folio(struct lruvec *lr - int delta = folio_nr_pages(folio); - int refs = folio_lru_refs(folio); - int tier = lru_tier_from_refs(refs); -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - - VM_WARN_ON_ONCE_FOLIO(gen >= MAX_NR_GENS, folio); - -@@ -4848,7 +4848,7 @@ static int scan_folios(struct lruvec *lr - int scanned = 0; - int isolated = 0; - int remaining = MAX_LRU_BATCH; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - - VM_WARN_ON_ONCE(!list_empty(list)); -@@ -5248,7 +5248,7 @@ done: - - static bool __maybe_unused state_is_valid(struct lruvec *lruvec) - { -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - - if (lrugen->enabled) { - enum lru_list lru; -@@ -5530,7 +5530,7 @@ static void lru_gen_seq_show_full(struct - int i; - int type, tier; - int hist = lru_hist_from_seq(seq); -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - - for (tier = 0; tier < MAX_NR_TIERS; tier++) { - seq_printf(m, " %10d", tier); -@@ -5580,7 +5580,7 @@ static int lru_gen_seq_show(struct seq_f - unsigned long seq; - bool full = !debugfs_real_fops(m->file)->write; - struct lruvec *lruvec = v; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - int nid = lruvec_pgdat(lruvec)->node_id; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MAX_SEQ(lruvec); -@@ -5834,7 +5834,7 @@ void lru_gen_init_lruvec(struct lruvec * - { - int i; - int gen, type, zone; -- struct lru_gen_struct *lrugen = &lruvec->lrugen; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - - lrugen->max_seq = MIN_NR_GENS + 1; - lrugen->enabled = lru_gen_enabled(); ---- a/mm/workingset.c -+++ b/mm/workingset.c -@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct fol - unsigned long token; - unsigned long min_seq; - struct lruvec *lruvec; -- struct lru_gen_struct *lrugen; -+ struct lru_gen_folio *lrugen; - int type = folio_is_file_lru(folio); - int delta = folio_nr_pages(folio); - int refs = folio_lru_refs(folio); -@@ -252,7 +252,7 @@ static void lru_gen_refault(struct folio - unsigned long token; - unsigned long min_seq; - struct lruvec *lruvec; -- struct lru_gen_struct *lrugen; -+ struct lru_gen_folio *lrugen; - struct mem_cgroup *memcg; - struct pglist_data *pgdat; - int type = folio_is_file_lru(folio); diff --git a/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch b/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch deleted file mode 100644 index 3a27bbcae03205..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-03-UPSTREAM-mm-multi-gen-LRU-remove-eviction-fairness-s.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 14f9a7a15f3d1af351f30e0438fd747b7ac253b0 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:01 -0700 -Subject: [PATCH 03/19] UPSTREAM: mm: multi-gen LRU: remove eviction fairness - safeguard - -Recall that the eviction consumes the oldest generation: first it -bucket-sorts folios whose gen counters were updated by the aging and -reclaims the rest; then it increments lrugen->min_seq. - -The current eviction fairness safeguard for global reclaim has a -dilemma: when there are multiple eligible memcgs, should it continue -or stop upon meeting the reclaim goal? If it continues, it overshoots -and increases direct reclaim latency; if it stops, it loses fairness -between memcgs it has taken memory away from and those it has yet to. - -With memcg LRU, the eviction, while ensuring eventual fairness, will -stop upon meeting its goal. Therefore the current eviction fairness -safeguard for global reclaim will not be needed. - -Note that memcg LRU only applies to global reclaim. For memcg reclaim, -the eviction will continue, even if it is overshooting. This becomes -unconditional due to code simplification. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-4-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton -Bug: 274865848 -(cherry picked from commit a579086c99ed70cc4bfc104348dbe3dd8f2787e6) -Change-Id: I08ac1b3c90e29cafd0566785aaa4bcdb5db7d22c -Signed-off-by: T.J. Mercier ---- - mm/vmscan.c | 81 +++++++++++++++-------------------------------------- - 1 file changed, 23 insertions(+), 58 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -448,6 +448,11 @@ static bool cgroup_reclaim(struct scan_c - return sc->target_mem_cgroup; - } - -+static bool global_reclaim(struct scan_control *sc) -+{ -+ return !sc->target_mem_cgroup || mem_cgroup_is_root(sc->target_mem_cgroup); -+} -+ - /** - * writeback_throttling_sane - is the usual dirty throttling mechanism available? - * @sc: scan_control in question -@@ -498,6 +503,11 @@ static bool cgroup_reclaim(struct scan_c - return false; - } - -+static bool global_reclaim(struct scan_control *sc) -+{ -+ return true; -+} -+ - static bool writeback_throttling_sane(struct scan_control *sc) - { - return true; -@@ -5005,8 +5015,7 @@ static int isolate_folios(struct lruvec - return scanned; - } - --static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness, -- bool *need_swapping) -+static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness) - { - int type; - int scanned; -@@ -5094,9 +5103,6 @@ retry: - goto retry; - } - -- if (need_swapping && type == LRU_GEN_ANON) -- *need_swapping = true; -- - return scanned; - } - -@@ -5135,67 +5141,26 @@ done: - return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; - } - --static bool should_abort_scan(struct lruvec *lruvec, unsigned long seq, -- struct scan_control *sc, bool need_swapping) -+static unsigned long get_nr_to_reclaim(struct scan_control *sc) - { -- int i; -- DEFINE_MAX_SEQ(lruvec); -- -- if (!current_is_kswapd()) { -- /* age each memcg at most once to ensure fairness */ -- if (max_seq - seq > 1) -- return true; -- -- /* over-swapping can increase allocation latency */ -- if (sc->nr_reclaimed >= sc->nr_to_reclaim && need_swapping) -- return true; -- -- /* give this thread a chance to exit and free its memory */ -- if (fatal_signal_pending(current)) { -- sc->nr_reclaimed += MIN_LRU_BATCH; -- return true; -- } -- -- if (cgroup_reclaim(sc)) -- return false; -- } else if (sc->nr_reclaimed - sc->last_reclaimed < sc->nr_to_reclaim) -- return false; -- -- /* keep scanning at low priorities to ensure fairness */ -- if (sc->priority > DEF_PRIORITY - 2) -- return false; -- -- /* -- * A minimum amount of work was done under global memory pressure. For -- * kswapd, it may be overshooting. For direct reclaim, the allocation -- * may succeed if all suitable zones are somewhat safe. In either case, -- * it's better to stop now, and restart later if necessary. -- */ -- for (i = 0; i <= sc->reclaim_idx; i++) { -- unsigned long wmark; -- struct zone *zone = lruvec_pgdat(lruvec)->node_zones + i; -- -- if (!managed_zone(zone)) -- continue; -- -- wmark = current_is_kswapd() ? high_wmark_pages(zone) : low_wmark_pages(zone); -- if (wmark > zone_page_state(zone, NR_FREE_PAGES)) -- return false; -- } -+ /* don't abort memcg reclaim to ensure fairness */ -+ if (!global_reclaim(sc)) -+ return -1; - -- sc->nr_reclaimed += MIN_LRU_BATCH; -+ /* discount the previous progress for kswapd */ -+ if (current_is_kswapd()) -+ return sc->nr_to_reclaim + sc->last_reclaimed; - -- return true; -+ return max(sc->nr_to_reclaim, compact_gap(sc->order)); - } - - static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { - struct blk_plug plug; - bool need_aging = false; -- bool need_swapping = false; - unsigned long scanned = 0; - unsigned long reclaimed = sc->nr_reclaimed; -- DEFINE_MAX_SEQ(lruvec); -+ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); - - lru_add_drain(); - -@@ -5219,7 +5184,7 @@ static void lru_gen_shrink_lruvec(struct - if (!nr_to_scan) - goto done; - -- delta = evict_folios(lruvec, sc, swappiness, &need_swapping); -+ delta = evict_folios(lruvec, sc, swappiness); - if (!delta) - goto done; - -@@ -5227,7 +5192,7 @@ static void lru_gen_shrink_lruvec(struct - if (scanned >= nr_to_scan) - break; - -- if (should_abort_scan(lruvec, max_seq, sc, need_swapping)) -+ if (sc->nr_reclaimed >= nr_to_reclaim) - break; - - cond_resched(); -@@ -5677,7 +5642,7 @@ static int run_eviction(struct lruvec *l - if (sc->nr_reclaimed >= nr_to_reclaim) - return 0; - -- if (!evict_folios(lruvec, sc, swappiness, NULL)) -+ if (!evict_folios(lruvec, sc, swappiness)) - return 0; - - cond_resched(); diff --git a/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch b/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch deleted file mode 100644 index 82958895541039..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-04-BACKPORT-mm-multi-gen-LRU-remove-aging-fairness-safe.patch +++ /dev/null @@ -1,294 +0,0 @@ -From f3c93d2e37a3c56593d7ccf4f4bcf1b58426fdd8 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:02 -0700 -Subject: [PATCH 04/19] BACKPORT: mm: multi-gen LRU: remove aging fairness - safeguard - -Recall that the aging produces the youngest generation: first it scans -for accessed folios and updates their gen counters; then it increments -lrugen->max_seq. - -The current aging fairness safeguard for kswapd uses two passes to -ensure the fairness to multiple eligible memcgs. On the first pass, -which is shared with the eviction, it checks whether all eligible -memcgs are low on cold folios. If so, it requires a second pass, on -which it ages all those memcgs at the same time. - -With memcg LRU, the aging, while ensuring eventual fairness, will run -when necessary. Therefore the current aging fairness safeguard for -kswapd will not be needed. - -Note that memcg LRU only applies to global reclaim. For memcg reclaim, -the aging can be unfair to different memcgs, i.e., their -lrugen->max_seq can be incremented at different paces. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-5-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton -Bug: 274865848 -(cherry picked from commit 7348cc91821b0cb24dfb00e578047f68299a50ab) -[TJ: Resolved conflicts with older function signatures for -min_cgroup_below_min / min_cgroup_below_low] -Change-Id: I6e36ecfbaaefbc0a56d9a9d5d7cbe404ed7f57a5 -Signed-off-by: T.J. Mercier ---- - mm/vmscan.c | 126 ++++++++++++++++++++++++---------------------------- - 1 file changed, 59 insertions(+), 67 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -136,7 +136,6 @@ struct scan_control { - - #ifdef CONFIG_LRU_GEN - /* help kswapd make better choices among multiple memcgs */ -- unsigned int memcgs_need_aging:1; - unsigned long last_reclaimed; - #endif - -@@ -4457,7 +4456,7 @@ done: - return true; - } - --static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq, -+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, - struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) - { - int gen, type, zone; -@@ -4466,6 +4465,13 @@ static bool should_run_aging(struct lruv - unsigned long total = 0; - struct lru_gen_folio *lrugen = &lruvec->lrugen; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ /* whether this lruvec is completely out of cold folios */ -+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) { -+ *nr_to_scan = 0; -+ return true; -+ } - - for (type = !can_swap; type < ANON_AND_FILE; type++) { - unsigned long seq; -@@ -4494,8 +4500,6 @@ static bool should_run_aging(struct lruv - * stalls when the number of generations reaches MIN_NR_GENS. Hence, the - * ideal number of generations is MIN_NR_GENS+1. - */ -- if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) -- return true; - if (min_seq[!can_swap] + MIN_NR_GENS < max_seq) - return false; - -@@ -4514,40 +4518,54 @@ static bool should_run_aging(struct lruv - return false; - } - --static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc, unsigned long min_ttl) -+static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc) - { -- bool need_aging; -- unsigned long nr_to_scan; -- int swappiness = get_swappiness(lruvec, sc); -+ int gen, type, zone; -+ unsigned long total = 0; -+ bool can_swap = get_swappiness(lruvec, sc); -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MAX_SEQ(lruvec); - DEFINE_MIN_SEQ(lruvec); - -- VM_WARN_ON_ONCE(sc->memcg_low_reclaim); -+ for (type = !can_swap; type < ANON_AND_FILE; type++) { -+ unsigned long seq; - -- mem_cgroup_calculate_protection(NULL, memcg); -+ for (seq = min_seq[type]; seq <= max_seq; seq++) { -+ gen = lru_gen_from_seq(seq); - -- if (mem_cgroup_below_min(memcg)) -- return false; -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) -+ total += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); -+ } -+ } - -- need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan); -+ /* whether the size is big enough to be helpful */ -+ return mem_cgroup_online(memcg) ? (total >> sc->priority) : total; -+} - -- if (min_ttl) { -- int gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); -- unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); -+static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc, -+ unsigned long min_ttl) -+{ -+ int gen; -+ unsigned long birth; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MIN_SEQ(lruvec); - -- if (time_is_after_jiffies(birth + min_ttl)) -- return false; -+ VM_WARN_ON_ONCE(sc->memcg_low_reclaim); - -- /* the size is likely too small to be helpful */ -- if (!nr_to_scan && sc->priority != DEF_PRIORITY) -- return false; -- } -+ /* see the comment on lru_gen_folio */ -+ gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); -+ birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); - -- if (need_aging) -- try_to_inc_max_seq(lruvec, max_seq, sc, swappiness, false); -+ if (time_is_after_jiffies(birth + min_ttl)) -+ return false; - -- return true; -+ if (!lruvec_is_sizable(lruvec, sc)) -+ return false; -+ -+ mem_cgroup_calculate_protection(NULL, memcg); -+ -+ return !mem_cgroup_below_min(memcg); - } - - /* to protect the working set of the last N jiffies */ -@@ -4556,46 +4574,32 @@ static unsigned long lru_gen_min_ttl __r - static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc) - { - struct mem_cgroup *memcg; -- bool success = false; - unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl); - - VM_WARN_ON_ONCE(!current_is_kswapd()); - - sc->last_reclaimed = sc->nr_reclaimed; - -- /* -- * To reduce the chance of going into the aging path, which can be -- * costly, optimistically skip it if the flag below was cleared in the -- * eviction path. This improves the overall performance when multiple -- * memcgs are available. -- */ -- if (!sc->memcgs_need_aging) { -- sc->memcgs_need_aging = true; -+ /* check the order to exclude compaction-induced reclaim */ -+ if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY) - return; -- } -- -- set_mm_walk(pgdat); - - memcg = mem_cgroup_iter(NULL, NULL, NULL); - do { - struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); - -- if (age_lruvec(lruvec, sc, min_ttl)) -- success = true; -+ if (lruvec_is_reclaimable(lruvec, sc, min_ttl)) { -+ mem_cgroup_iter_break(NULL, memcg); -+ return; -+ } - - cond_resched(); - } while ((memcg = mem_cgroup_iter(NULL, memcg, NULL))); - -- clear_mm_walk(); -- -- /* check the order to exclude compaction-induced reclaim */ -- if (success || !min_ttl || sc->order) -- return; -- - /* - * The main goal is to OOM kill if every generation from all memcgs is - * younger than min_ttl. However, another possibility is all memcgs are -- * either below min or empty. -+ * either too small or below min. - */ - if (mutex_trylock(&oom_lock)) { - struct oom_control oc = { -@@ -5112,33 +5116,27 @@ retry: - * reclaim. - */ - static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, -- bool can_swap, bool *need_aging) -+ bool can_swap) - { - unsigned long nr_to_scan; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MAX_SEQ(lruvec); -- DEFINE_MIN_SEQ(lruvec); - - if (mem_cgroup_below_min(memcg) || - (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) - return 0; - -- *need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan); -- if (!*need_aging) -+ if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan)) - return nr_to_scan; - - /* skip the aging path at the default priority */ - if (sc->priority == DEF_PRIORITY) -- goto done; -+ return nr_to_scan; - -- /* leave the work to lru_gen_age_node() */ -- if (current_is_kswapd()) -- return 0; -+ try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false); - -- if (try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false)) -- return nr_to_scan; --done: -- return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0; -+ /* skip this lruvec as it's low on cold folios */ -+ return 0; - } - - static unsigned long get_nr_to_reclaim(struct scan_control *sc) -@@ -5157,9 +5155,7 @@ static unsigned long get_nr_to_reclaim(s - static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { - struct blk_plug plug; -- bool need_aging = false; - unsigned long scanned = 0; -- unsigned long reclaimed = sc->nr_reclaimed; - unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); - - lru_add_drain(); -@@ -5180,13 +5176,13 @@ static void lru_gen_shrink_lruvec(struct - else - swappiness = 0; - -- nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness, &need_aging); -+ nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); - if (!nr_to_scan) -- goto done; -+ break; - - delta = evict_folios(lruvec, sc, swappiness); - if (!delta) -- goto done; -+ break; - - scanned += delta; - if (scanned >= nr_to_scan) -@@ -5198,10 +5194,6 @@ static void lru_gen_shrink_lruvec(struct - cond_resched(); - } - -- /* see the comment in lru_gen_age_node() */ -- if (sc->nr_reclaimed - reclaimed >= MIN_LRU_BATCH && !need_aging) -- sc->memcgs_need_aging = false; --done: - clear_mm_walk(); - - blk_finish_plug(&plug); diff --git a/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch b/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch deleted file mode 100644 index 6374b425cd5495..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-05-UPSTREAM-mm-multi-gen-LRU-shuffle-should_run_aging.patch +++ /dev/null @@ -1,166 +0,0 @@ -From eca3858631e0cbad2ca6e40f788892749428e4cb Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:03 -0700 -Subject: [PATCH 05/19] UPSTREAM: mm: multi-gen LRU: shuffle should_run_aging() - -Move should_run_aging() next to its only caller left. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-6-yuzhao@google.com -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton -Bug: 274865848 -(cherry picked from commit 77d4459a4a1a472b7309e475f962dda87d950abd) -Signed-off-by: T.J. Mercier -Change-Id: I3b0383fe16b93a783b4d8c0b3a0b325160392576 -Signed-off-by: Yu Zhao -Signed-off-by: T.J. Mercier ---- - mm/vmscan.c | 124 ++++++++++++++++++++++++++-------------------------- - 1 file changed, 62 insertions(+), 62 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4456,68 +4456,6 @@ done: - return true; - } - --static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, -- struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) --{ -- int gen, type, zone; -- unsigned long old = 0; -- unsigned long young = 0; -- unsigned long total = 0; -- struct lru_gen_folio *lrugen = &lruvec->lrugen; -- struct mem_cgroup *memcg = lruvec_memcg(lruvec); -- DEFINE_MIN_SEQ(lruvec); -- -- /* whether this lruvec is completely out of cold folios */ -- if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) { -- *nr_to_scan = 0; -- return true; -- } -- -- for (type = !can_swap; type < ANON_AND_FILE; type++) { -- unsigned long seq; -- -- for (seq = min_seq[type]; seq <= max_seq; seq++) { -- unsigned long size = 0; -- -- gen = lru_gen_from_seq(seq); -- -- for (zone = 0; zone < MAX_NR_ZONES; zone++) -- size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); -- -- total += size; -- if (seq == max_seq) -- young += size; -- else if (seq + MIN_NR_GENS == max_seq) -- old += size; -- } -- } -- -- /* try to scrape all its memory if this memcg was deleted */ -- *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total; -- -- /* -- * The aging tries to be lazy to reduce the overhead, while the eviction -- * stalls when the number of generations reaches MIN_NR_GENS. Hence, the -- * ideal number of generations is MIN_NR_GENS+1. -- */ -- if (min_seq[!can_swap] + MIN_NR_GENS < max_seq) -- return false; -- -- /* -- * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1) -- * of the total number of pages for each generation. A reasonable range -- * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The -- * aging cares about the upper bound of hot pages, while the eviction -- * cares about the lower bound of cold pages. -- */ -- if (young * MIN_NR_GENS > total) -- return true; -- if (old * (MIN_NR_GENS + 2) < total) -- return true; -- -- return false; --} -- - static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc) - { - int gen, type, zone; -@@ -5110,6 +5048,68 @@ retry: - return scanned; - } - -+static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, -+ struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan) -+{ -+ int gen, type, zone; -+ unsigned long old = 0; -+ unsigned long young = 0; -+ unsigned long total = 0; -+ struct lru_gen_folio *lrugen = &lruvec->lrugen; -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ DEFINE_MIN_SEQ(lruvec); -+ -+ /* whether this lruvec is completely out of cold folios */ -+ if (min_seq[!can_swap] + MIN_NR_GENS > max_seq) { -+ *nr_to_scan = 0; -+ return true; -+ } -+ -+ for (type = !can_swap; type < ANON_AND_FILE; type++) { -+ unsigned long seq; -+ -+ for (seq = min_seq[type]; seq <= max_seq; seq++) { -+ unsigned long size = 0; -+ -+ gen = lru_gen_from_seq(seq); -+ -+ for (zone = 0; zone < MAX_NR_ZONES; zone++) -+ size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L); -+ -+ total += size; -+ if (seq == max_seq) -+ young += size; -+ else if (seq + MIN_NR_GENS == max_seq) -+ old += size; -+ } -+ } -+ -+ /* try to scrape all its memory if this memcg was deleted */ -+ *nr_to_scan = mem_cgroup_online(memcg) ? (total >> sc->priority) : total; -+ -+ /* -+ * The aging tries to be lazy to reduce the overhead, while the eviction -+ * stalls when the number of generations reaches MIN_NR_GENS. Hence, the -+ * ideal number of generations is MIN_NR_GENS+1. -+ */ -+ if (min_seq[!can_swap] + MIN_NR_GENS < max_seq) -+ return false; -+ -+ /* -+ * It's also ideal to spread pages out evenly, i.e., 1/(MIN_NR_GENS+1) -+ * of the total number of pages for each generation. A reasonable range -+ * for this average portion is [1/MIN_NR_GENS, 1/(MIN_NR_GENS+2)]. The -+ * aging cares about the upper bound of hot pages, while the eviction -+ * cares about the lower bound of cold pages. -+ */ -+ if (young * MIN_NR_GENS > total) -+ return true; -+ if (old * (MIN_NR_GENS + 2) < total) -+ return true; -+ -+ return false; -+} -+ - /* - * For future optimizations: - * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg diff --git a/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch b/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch deleted file mode 100644 index 50ceaf13ed0030..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-06-BACKPORT-mm-multi-gen-LRU-per-node-lru_gen_folio-lis.patch +++ /dev/null @@ -1,876 +0,0 @@ -From 8ee8571e47aa75221e5fbd4c9c7802fc4244c346 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:04 -0700 -Subject: [PATCH 06/19] BACKPORT: mm: multi-gen LRU: per-node lru_gen_folio - lists - -For each node, memcgs are divided into two generations: the old and -the young. For each generation, memcgs are randomly sharded into -multiple bins to improve scalability. For each bin, an RCU hlist_nulls -is virtually divided into three segments: the head, the tail and the -default. - -An onlining memcg is added to the tail of a random bin in the old -generation. The eviction starts at the head of a random bin in the old -generation. The per-node memcg generation counter, whose reminder (mod -2) indexes the old generation, is incremented when all its bins become -empty. - -There are four operations: -1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in - its current generation (old or young) and updates its "seg" to - "head"; -2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in - its current generation (old or young) and updates its "seg" to - "tail"; -3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in - the old generation, updates its "gen" to "old" and resets its "seg" - to "default"; -4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin - in the young generation, updates its "gen" to "young" and resets - its "seg" to "default". - -The events that trigger the above operations are: -1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD; -2. The first attempt to reclaim an memcg below low, which triggers - MEMCG_LRU_TAIL; -3. The first attempt to reclaim an memcg below reclaimable size - threshold, which triggers MEMCG_LRU_TAIL; -4. The second attempt to reclaim an memcg below reclaimable size - threshold, which triggers MEMCG_LRU_YOUNG; -5. Attempting to reclaim an memcg below min, which triggers - MEMCG_LRU_YOUNG; -6. Finishing the aging on the eviction path, which triggers - MEMCG_LRU_YOUNG; -7. Offlining an memcg, which triggers MEMCG_LRU_OLD. - -Note that memcg LRU only applies to global reclaim, and the -round-robin incrementing of their max_seq counters ensures the -eventual fairness to all eligible memcgs. For memcg reclaim, it still -relies on mem_cgroup_iter(). - -Link: https://lkml.kernel.org/r/20221222041905.2431096-7-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton -Bug: 274865848 -(cherry picked from commit e4dde56cd208674ce899b47589f263499e5b8cdc) -[TJ: Resolved conflicts with older function signatures for -min_cgroup_below_min / min_cgroup_below_low and includes] -Change-Id: Idc8a0f635e035d72dd911f807d1224cb47cbd655 -Signed-off-by: T.J. Mercier ---- - include/linux/memcontrol.h | 10 + - include/linux/mm_inline.h | 17 ++ - include/linux/mmzone.h | 117 +++++++++++- - mm/memcontrol.c | 16 ++ - mm/page_alloc.c | 1 + - mm/vmscan.c | 374 +++++++++++++++++++++++++++++++++---- - 6 files changed, 500 insertions(+), 35 deletions(-) - ---- a/include/linux/memcontrol.h -+++ b/include/linux/memcontrol.h -@@ -795,6 +795,11 @@ static inline void obj_cgroup_put(struct - percpu_ref_put(&objcg->refcnt); - } - -+static inline bool mem_cgroup_tryget(struct mem_cgroup *memcg) -+{ -+ return !memcg || css_tryget(&memcg->css); -+} -+ - static inline void mem_cgroup_put(struct mem_cgroup *memcg) - { - if (memcg) -@@ -1295,6 +1300,11 @@ static inline void obj_cgroup_put(struct - { - } - -+static inline bool mem_cgroup_tryget(struct mem_cgroup *memcg) -+{ -+ return true; -+} -+ - static inline void mem_cgroup_put(struct mem_cgroup *memcg) - { - } ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -122,6 +122,18 @@ static inline bool lru_gen_in_fault(void - return current->in_lru_fault; - } - -+#ifdef CONFIG_MEMCG -+static inline int lru_gen_memcg_seg(struct lruvec *lruvec) -+{ -+ return READ_ONCE(lruvec->lrugen.seg); -+} -+#else -+static inline int lru_gen_memcg_seg(struct lruvec *lruvec) -+{ -+ return 0; -+} -+#endif -+ - static inline int lru_gen_from_seq(unsigned long seq) - { - return seq % MAX_NR_GENS; -@@ -302,6 +314,11 @@ static inline bool lru_gen_in_fault(void - return false; - } - -+static inline int lru_gen_memcg_seg(struct lruvec *lruvec) -+{ -+ return 0; -+} -+ - static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming) - { - return false; ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -7,6 +7,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -367,6 +368,15 @@ struct page_vma_mapped_walk; - #define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF) - #define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF) - -+/* see the comment on MEMCG_NR_GENS */ -+enum { -+ MEMCG_LRU_NOP, -+ MEMCG_LRU_HEAD, -+ MEMCG_LRU_TAIL, -+ MEMCG_LRU_OLD, -+ MEMCG_LRU_YOUNG, -+}; -+ - #ifdef CONFIG_LRU_GEN - - enum { -@@ -426,6 +436,14 @@ struct lru_gen_folio { - atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS]; - /* whether the multi-gen LRU is enabled */ - bool enabled; -+#ifdef CONFIG_MEMCG -+ /* the memcg generation this lru_gen_folio belongs to */ -+ u8 gen; -+ /* the list segment this lru_gen_folio belongs to */ -+ u8 seg; -+ /* per-node lru_gen_folio list for global reclaim */ -+ struct hlist_nulls_node list; -+#endif - }; - - enum { -@@ -479,12 +497,87 @@ void lru_gen_init_lruvec(struct lruvec * - void lru_gen_look_around(struct page_vma_mapped_walk *pvmw); - - #ifdef CONFIG_MEMCG -+ -+/* -+ * For each node, memcgs are divided into two generations: the old and the -+ * young. For each generation, memcgs are randomly sharded into multiple bins -+ * to improve scalability. For each bin, the hlist_nulls is virtually divided -+ * into three segments: the head, the tail and the default. -+ * -+ * An onlining memcg is added to the tail of a random bin in the old generation. -+ * The eviction starts at the head of a random bin in the old generation. The -+ * per-node memcg generation counter, whose reminder (mod MEMCG_NR_GENS) indexes -+ * the old generation, is incremented when all its bins become empty. -+ * -+ * There are four operations: -+ * 1. MEMCG_LRU_HEAD, which moves an memcg to the head of a random bin in its -+ * current generation (old or young) and updates its "seg" to "head"; -+ * 2. MEMCG_LRU_TAIL, which moves an memcg to the tail of a random bin in its -+ * current generation (old or young) and updates its "seg" to "tail"; -+ * 3. MEMCG_LRU_OLD, which moves an memcg to the head of a random bin in the old -+ * generation, updates its "gen" to "old" and resets its "seg" to "default"; -+ * 4. MEMCG_LRU_YOUNG, which moves an memcg to the tail of a random bin in the -+ * young generation, updates its "gen" to "young" and resets its "seg" to -+ * "default". -+ * -+ * The events that trigger the above operations are: -+ * 1. Exceeding the soft limit, which triggers MEMCG_LRU_HEAD; -+ * 2. The first attempt to reclaim an memcg below low, which triggers -+ * MEMCG_LRU_TAIL; -+ * 3. The first attempt to reclaim an memcg below reclaimable size threshold, -+ * which triggers MEMCG_LRU_TAIL; -+ * 4. The second attempt to reclaim an memcg below reclaimable size threshold, -+ * which triggers MEMCG_LRU_YOUNG; -+ * 5. Attempting to reclaim an memcg below min, which triggers MEMCG_LRU_YOUNG; -+ * 6. Finishing the aging on the eviction path, which triggers MEMCG_LRU_YOUNG; -+ * 7. Offlining an memcg, which triggers MEMCG_LRU_OLD. -+ * -+ * Note that memcg LRU only applies to global reclaim, and the round-robin -+ * incrementing of their max_seq counters ensures the eventual fairness to all -+ * eligible memcgs. For memcg reclaim, it still relies on mem_cgroup_iter(). -+ */ -+#define MEMCG_NR_GENS 2 -+#define MEMCG_NR_BINS 8 -+ -+struct lru_gen_memcg { -+ /* the per-node memcg generation counter */ -+ unsigned long seq; -+ /* each memcg has one lru_gen_folio per node */ -+ unsigned long nr_memcgs[MEMCG_NR_GENS]; -+ /* per-node lru_gen_folio list for global reclaim */ -+ struct hlist_nulls_head fifo[MEMCG_NR_GENS][MEMCG_NR_BINS]; -+ /* protects the above */ -+ spinlock_t lock; -+}; -+ -+void lru_gen_init_pgdat(struct pglist_data *pgdat); -+ - void lru_gen_init_memcg(struct mem_cgroup *memcg); - void lru_gen_exit_memcg(struct mem_cgroup *memcg); --#endif -+void lru_gen_online_memcg(struct mem_cgroup *memcg); -+void lru_gen_offline_memcg(struct mem_cgroup *memcg); -+void lru_gen_release_memcg(struct mem_cgroup *memcg); -+void lru_gen_rotate_memcg(struct lruvec *lruvec, int op); -+ -+#else /* !CONFIG_MEMCG */ -+ -+#define MEMCG_NR_GENS 1 -+ -+struct lru_gen_memcg { -+}; -+ -+static inline void lru_gen_init_pgdat(struct pglist_data *pgdat) -+{ -+} -+ -+#endif /* CONFIG_MEMCG */ - - #else /* !CONFIG_LRU_GEN */ - -+static inline void lru_gen_init_pgdat(struct pglist_data *pgdat) -+{ -+} -+ - static inline void lru_gen_init_lruvec(struct lruvec *lruvec) - { - } -@@ -494,6 +587,7 @@ static inline void lru_gen_look_around(s - } - - #ifdef CONFIG_MEMCG -+ - static inline void lru_gen_init_memcg(struct mem_cgroup *memcg) - { - } -@@ -501,7 +595,24 @@ static inline void lru_gen_init_memcg(st - static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg) - { - } --#endif -+ -+static inline void lru_gen_online_memcg(struct mem_cgroup *memcg) -+{ -+} -+ -+static inline void lru_gen_offline_memcg(struct mem_cgroup *memcg) -+{ -+} -+ -+static inline void lru_gen_release_memcg(struct mem_cgroup *memcg) -+{ -+} -+ -+static inline void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) -+{ -+} -+ -+#endif /* CONFIG_MEMCG */ - - #endif /* CONFIG_LRU_GEN */ - -@@ -1218,6 +1329,8 @@ typedef struct pglist_data { - #ifdef CONFIG_LRU_GEN - /* kswap mm walk data */ - struct lru_gen_mm_walk mm_walk; -+ /* lru_gen_folio list */ -+ struct lru_gen_memcg memcg_lru; - #endif - - CACHELINE_PADDING(_pad2_); ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -477,6 +477,16 @@ static void mem_cgroup_update_tree(struc - struct mem_cgroup_per_node *mz; - struct mem_cgroup_tree_per_node *mctz; - -+ if (lru_gen_enabled()) { -+ struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec; -+ -+ /* see the comment on MEMCG_NR_GENS */ -+ if (soft_limit_excess(memcg) && lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD) -+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD); -+ -+ return; -+ } -+ - mctz = soft_limit_tree.rb_tree_per_node[nid]; - if (!mctz) - return; -@@ -3524,6 +3534,9 @@ unsigned long mem_cgroup_soft_limit_recl - struct mem_cgroup_tree_per_node *mctz; - unsigned long excess; - -+ if (lru_gen_enabled()) -+ return 0; -+ - if (order > 0) - return 0; - -@@ -5390,6 +5403,7 @@ static int mem_cgroup_css_online(struct - if (unlikely(mem_cgroup_is_root(memcg))) - queue_delayed_work(system_unbound_wq, &stats_flush_dwork, - 2UL*HZ); -+ lru_gen_online_memcg(memcg); - return 0; - offline_kmem: - memcg_offline_kmem(memcg); -@@ -5421,6 +5435,7 @@ static void mem_cgroup_css_offline(struc - memcg_offline_kmem(memcg); - reparent_shrinker_deferred(memcg); - wb_memcg_offline(memcg); -+ lru_gen_offline_memcg(memcg); - - drain_all_stock(memcg); - -@@ -5432,6 +5447,7 @@ static void mem_cgroup_css_released(stru - struct mem_cgroup *memcg = mem_cgroup_from_css(css); - - invalidate_reclaim_iterators(memcg); -+ lru_gen_release_memcg(memcg); - } - - static void mem_cgroup_css_free(struct cgroup_subsys_state *css) ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -7956,6 +7956,7 @@ static void __init free_area_init_node(i - pgdat_set_deferred_range(pgdat); - - free_area_init_core(pgdat); -+ lru_gen_init_pgdat(pgdat); - } - - static void __init free_area_init_memoryless_node(int nid) ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -54,6 +54,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -134,11 +136,6 @@ struct scan_control { - /* Always discard instead of demoting to lower tier memory */ - unsigned int no_demotion:1; - --#ifdef CONFIG_LRU_GEN -- /* help kswapd make better choices among multiple memcgs */ -- unsigned long last_reclaimed; --#endif -- - /* Allocation order */ - s8 order; - -@@ -3160,6 +3157,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_ca - for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \ - for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++) - -+#define get_memcg_gen(seq) ((seq) % MEMCG_NR_GENS) -+#define get_memcg_bin(bin) ((bin) % MEMCG_NR_BINS) -+ - static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid) - { - struct pglist_data *pgdat = NODE_DATA(nid); -@@ -4442,8 +4442,7 @@ done: - if (sc->priority <= DEF_PRIORITY - 2) - wait_event_killable(lruvec->mm_state.wait, - max_seq < READ_ONCE(lrugen->max_seq)); -- -- return max_seq < READ_ONCE(lrugen->max_seq); -+ return false; - } - - VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq)); -@@ -4516,8 +4515,6 @@ static void lru_gen_age_node(struct pgli - - VM_WARN_ON_ONCE(!current_is_kswapd()); - -- sc->last_reclaimed = sc->nr_reclaimed; -- - /* check the order to exclude compaction-induced reclaim */ - if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY) - return; -@@ -5115,8 +5112,7 @@ static bool should_run_aging(struct lruv - * 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg - * reclaim. - */ --static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, -- bool can_swap) -+static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool can_swap) - { - unsigned long nr_to_scan; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); -@@ -5133,10 +5129,8 @@ static unsigned long get_nr_to_scan(stru - if (sc->priority == DEF_PRIORITY) - return nr_to_scan; - -- try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false); -- - /* skip this lruvec as it's low on cold folios */ -- return 0; -+ return try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false) ? -1 : 0; - } - - static unsigned long get_nr_to_reclaim(struct scan_control *sc) -@@ -5145,29 +5139,18 @@ static unsigned long get_nr_to_reclaim(s - if (!global_reclaim(sc)) - return -1; - -- /* discount the previous progress for kswapd */ -- if (current_is_kswapd()) -- return sc->nr_to_reclaim + sc->last_reclaimed; -- - return max(sc->nr_to_reclaim, compact_gap(sc->order)); - } - --static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) - { -- struct blk_plug plug; -+ long nr_to_scan; - unsigned long scanned = 0; - unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); - -- lru_add_drain(); -- -- blk_start_plug(&plug); -- -- set_mm_walk(lruvec_pgdat(lruvec)); -- - while (true) { - int delta; - int swappiness; -- unsigned long nr_to_scan; - - if (sc->may_swap) - swappiness = get_swappiness(lruvec, sc); -@@ -5177,7 +5160,7 @@ static void lru_gen_shrink_lruvec(struct - swappiness = 0; - - nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); -- if (!nr_to_scan) -+ if (nr_to_scan <= 0) - break; - - delta = evict_folios(lruvec, sc, swappiness); -@@ -5194,10 +5177,251 @@ static void lru_gen_shrink_lruvec(struct - cond_resched(); - } - -+ /* whether try_to_inc_max_seq() was successful */ -+ return nr_to_scan < 0; -+} -+ -+static int shrink_one(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ bool success; -+ unsigned long scanned = sc->nr_scanned; -+ unsigned long reclaimed = sc->nr_reclaimed; -+ int seg = lru_gen_memcg_seg(lruvec); -+ struct mem_cgroup *memcg = lruvec_memcg(lruvec); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ -+ /* see the comment on MEMCG_NR_GENS */ -+ if (!lruvec_is_sizable(lruvec, sc)) -+ return seg != MEMCG_LRU_TAIL ? MEMCG_LRU_TAIL : MEMCG_LRU_YOUNG; -+ -+ mem_cgroup_calculate_protection(NULL, memcg); -+ -+ if (mem_cgroup_below_min(memcg)) -+ return MEMCG_LRU_YOUNG; -+ -+ if (mem_cgroup_below_low(memcg)) { -+ /* see the comment on MEMCG_NR_GENS */ -+ if (seg != MEMCG_LRU_TAIL) -+ return MEMCG_LRU_TAIL; -+ -+ memcg_memory_event(memcg, MEMCG_LOW); -+ } -+ -+ success = try_to_shrink_lruvec(lruvec, sc); -+ -+ shrink_slab(sc->gfp_mask, pgdat->node_id, memcg, sc->priority); -+ -+ if (!sc->proactive) -+ vmpressure(sc->gfp_mask, memcg, false, sc->nr_scanned - scanned, -+ sc->nr_reclaimed - reclaimed); -+ -+ sc->nr_reclaimed += current->reclaim_state->reclaimed_slab; -+ current->reclaim_state->reclaimed_slab = 0; -+ -+ return success ? MEMCG_LRU_YOUNG : 0; -+} -+ -+#ifdef CONFIG_MEMCG -+ -+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ int gen; -+ int bin; -+ int first_bin; -+ struct lruvec *lruvec; -+ struct lru_gen_folio *lrugen; -+ const struct hlist_nulls_node *pos; -+ int op = 0; -+ struct mem_cgroup *memcg = NULL; -+ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); -+ -+ bin = first_bin = get_random_u32_below(MEMCG_NR_BINS); -+restart: -+ gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq)); -+ -+ rcu_read_lock(); -+ -+ hlist_nulls_for_each_entry_rcu(lrugen, pos, &pgdat->memcg_lru.fifo[gen][bin], list) { -+ if (op) -+ lru_gen_rotate_memcg(lruvec, op); -+ -+ mem_cgroup_put(memcg); -+ -+ lruvec = container_of(lrugen, struct lruvec, lrugen); -+ memcg = lruvec_memcg(lruvec); -+ -+ if (!mem_cgroup_tryget(memcg)) { -+ op = 0; -+ memcg = NULL; -+ continue; -+ } -+ -+ rcu_read_unlock(); -+ -+ op = shrink_one(lruvec, sc); -+ -+ if (sc->nr_reclaimed >= nr_to_reclaim) -+ goto success; -+ -+ rcu_read_lock(); -+ } -+ -+ rcu_read_unlock(); -+ -+ /* restart if raced with lru_gen_rotate_memcg() */ -+ if (gen != get_nulls_value(pos)) -+ goto restart; -+ -+ /* try the rest of the bins of the current generation */ -+ bin = get_memcg_bin(bin + 1); -+ if (bin != first_bin) -+ goto restart; -+success: -+ if (op) -+ lru_gen_rotate_memcg(lruvec, op); -+ -+ mem_cgroup_put(memcg); -+} -+ -+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ struct blk_plug plug; -+ -+ VM_WARN_ON_ONCE(global_reclaim(sc)); -+ -+ lru_add_drain(); -+ -+ blk_start_plug(&plug); -+ -+ set_mm_walk(lruvec_pgdat(lruvec)); -+ -+ if (try_to_shrink_lruvec(lruvec, sc)) -+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG); -+ -+ clear_mm_walk(); -+ -+ blk_finish_plug(&plug); -+} -+ -+#else /* !CONFIG_MEMCG */ -+ -+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ BUILD_BUG(); -+} -+ -+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -+{ -+ BUILD_BUG(); -+} -+ -+#endif -+ -+static void set_initial_priority(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ int priority; -+ unsigned long reclaimable; -+ struct lruvec *lruvec = mem_cgroup_lruvec(NULL, pgdat); -+ -+ if (sc->priority != DEF_PRIORITY || sc->nr_to_reclaim < MIN_LRU_BATCH) -+ return; -+ /* -+ * Determine the initial priority based on ((total / MEMCG_NR_GENS) >> -+ * priority) * reclaimed_to_scanned_ratio = nr_to_reclaim, where the -+ * estimated reclaimed_to_scanned_ratio = inactive / total. -+ */ -+ reclaimable = node_page_state(pgdat, NR_INACTIVE_FILE); -+ if (get_swappiness(lruvec, sc)) -+ reclaimable += node_page_state(pgdat, NR_INACTIVE_ANON); -+ -+ reclaimable /= MEMCG_NR_GENS; -+ -+ /* round down reclaimable and round up sc->nr_to_reclaim */ -+ priority = fls_long(reclaimable) - 1 - fls_long(sc->nr_to_reclaim - 1); -+ -+ sc->priority = clamp(priority, 0, DEF_PRIORITY); -+} -+ -+static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+ struct blk_plug plug; -+ unsigned long reclaimed = sc->nr_reclaimed; -+ -+ VM_WARN_ON_ONCE(!global_reclaim(sc)); -+ -+ lru_add_drain(); -+ -+ blk_start_plug(&plug); -+ -+ set_mm_walk(pgdat); -+ -+ set_initial_priority(pgdat, sc); -+ -+ if (current_is_kswapd()) -+ sc->nr_reclaimed = 0; -+ -+ if (mem_cgroup_disabled()) -+ shrink_one(&pgdat->__lruvec, sc); -+ else -+ shrink_many(pgdat, sc); -+ -+ if (current_is_kswapd()) -+ sc->nr_reclaimed += reclaimed; -+ - clear_mm_walk(); - - blk_finish_plug(&plug); -+ -+ /* kswapd should never fail */ -+ pgdat->kswapd_failures = 0; -+} -+ -+#ifdef CONFIG_MEMCG -+void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) -+{ -+ int seg; -+ int old, new; -+ int bin = get_random_u32_below(MEMCG_NR_BINS); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ -+ spin_lock(&pgdat->memcg_lru.lock); -+ -+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); -+ -+ seg = 0; -+ new = old = lruvec->lrugen.gen; -+ -+ /* see the comment on MEMCG_NR_GENS */ -+ if (op == MEMCG_LRU_HEAD) -+ seg = MEMCG_LRU_HEAD; -+ else if (op == MEMCG_LRU_TAIL) -+ seg = MEMCG_LRU_TAIL; -+ else if (op == MEMCG_LRU_OLD) -+ new = get_memcg_gen(pgdat->memcg_lru.seq); -+ else if (op == MEMCG_LRU_YOUNG) -+ new = get_memcg_gen(pgdat->memcg_lru.seq + 1); -+ else -+ VM_WARN_ON_ONCE(true); -+ -+ hlist_nulls_del_rcu(&lruvec->lrugen.list); -+ -+ if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD) -+ hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); -+ else -+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); -+ -+ pgdat->memcg_lru.nr_memcgs[old]--; -+ pgdat->memcg_lru.nr_memcgs[new]++; -+ -+ lruvec->lrugen.gen = new; -+ WRITE_ONCE(lruvec->lrugen.seg, seg); -+ -+ if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq)) -+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); -+ -+ spin_unlock(&pgdat->memcg_lru.lock); - } -+#endif - - /****************************************************************************** - * state change -@@ -5655,11 +5879,11 @@ static int run_cmd(char cmd, int memcg_i - - if (!mem_cgroup_disabled()) { - rcu_read_lock(); -+ - memcg = mem_cgroup_from_id(memcg_id); --#ifdef CONFIG_MEMCG -- if (memcg && !css_tryget(&memcg->css)) -+ if (!mem_cgroup_tryget(memcg)) - memcg = NULL; --#endif -+ - rcu_read_unlock(); - - if (!memcg) -@@ -5807,6 +6031,19 @@ void lru_gen_init_lruvec(struct lruvec * - } - - #ifdef CONFIG_MEMCG -+ -+void lru_gen_init_pgdat(struct pglist_data *pgdat) -+{ -+ int i, j; -+ -+ spin_lock_init(&pgdat->memcg_lru.lock); -+ -+ for (i = 0; i < MEMCG_NR_GENS; i++) { -+ for (j = 0; j < MEMCG_NR_BINS; j++) -+ INIT_HLIST_NULLS_HEAD(&pgdat->memcg_lru.fifo[i][j], i); -+ } -+} -+ - void lru_gen_init_memcg(struct mem_cgroup *memcg) - { - INIT_LIST_HEAD(&memcg->mm_list.fifo); -@@ -5830,7 +6067,69 @@ void lru_gen_exit_memcg(struct mem_cgrou - } - } - } --#endif -+ -+void lru_gen_online_memcg(struct mem_cgroup *memcg) -+{ -+ int gen; -+ int nid; -+ int bin = get_random_u32_below(MEMCG_NR_BINS); -+ -+ for_each_node(nid) { -+ struct pglist_data *pgdat = NODE_DATA(nid); -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ spin_lock(&pgdat->memcg_lru.lock); -+ -+ VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list)); -+ -+ gen = get_memcg_gen(pgdat->memcg_lru.seq); -+ -+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]); -+ pgdat->memcg_lru.nr_memcgs[gen]++; -+ -+ lruvec->lrugen.gen = gen; -+ -+ spin_unlock(&pgdat->memcg_lru.lock); -+ } -+} -+ -+void lru_gen_offline_memcg(struct mem_cgroup *memcg) -+{ -+ int nid; -+ -+ for_each_node(nid) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD); -+ } -+} -+ -+void lru_gen_release_memcg(struct mem_cgroup *memcg) -+{ -+ int gen; -+ int nid; -+ -+ for_each_node(nid) { -+ struct pglist_data *pgdat = NODE_DATA(nid); -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ spin_lock(&pgdat->memcg_lru.lock); -+ -+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); -+ -+ gen = lruvec->lrugen.gen; -+ -+ hlist_nulls_del_rcu(&lruvec->lrugen.list); -+ pgdat->memcg_lru.nr_memcgs[gen]--; -+ -+ if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq)) -+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); -+ -+ spin_unlock(&pgdat->memcg_lru.lock); -+ } -+} -+ -+#endif /* CONFIG_MEMCG */ - - static int __init init_lru_gen(void) - { -@@ -5857,6 +6156,10 @@ static void lru_gen_shrink_lruvec(struct - { - } - -+static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *sc) -+{ -+} -+ - #endif /* CONFIG_LRU_GEN */ - - static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) -@@ -5870,7 +6173,7 @@ static void shrink_lruvec(struct lruvec - bool proportional_reclaim; - struct blk_plug plug; - -- if (lru_gen_enabled()) { -+ if (lru_gen_enabled() && !global_reclaim(sc)) { - lru_gen_shrink_lruvec(lruvec, sc); - return; - } -@@ -6113,6 +6416,11 @@ static void shrink_node(pg_data_t *pgdat - struct lruvec *target_lruvec; - bool reclaimable = false; - -+ if (lru_gen_enabled() && global_reclaim(sc)) { -+ lru_gen_shrink_node(pgdat, sc); -+ return; -+ } -+ - target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat); - - again: diff --git a/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch b/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch deleted file mode 100644 index 079f4fd20289ca..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-07-BACKPORT-mm-multi-gen-LRU-clarify-scan_control-flags.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 11b14ee8cbbbebd8204609076a9327a1171cd253 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:05 -0700 -Subject: [PATCH 07/19] BACKPORT: mm: multi-gen LRU: clarify scan_control flags - -Among the flags in scan_control: -1. sc->may_swap, which indicates swap constraint due to memsw.max, is - supported as usual. -2. sc->proactive, which indicates reclaim by memory.reclaim, may not - opportunistically skip the aging path, since it is considered less - latency sensitive. -3. !(sc->gfp_mask & __GFP_IO), which indicates IO constraint, lowers - swappiness to prioritize file LRU, since clean file folios are more - likely to exist. -4. sc->may_writepage and sc->may_unmap, which indicates opportunistic - reclaim, are rejected, since unmapped clean folios are already - prioritized. Scanning for more of them is likely futile and can - cause high reclaim latency when there is a large number of memcgs. - -The rest are handled by the existing code. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-8-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton -Bug: 274865848 -(cherry picked from commit e9d4e1ee788097484606c32122f146d802a9c5fb) -[TJ: Resolved conflict with older function signature for min_cgroup_below_min, and over -cdded861182142ac4488a4d64c571107aeb77f53 ("ANDROID: MGLRU: Don't skip anon reclaim if swap low")] -Change-Id: Ic2e779eaf4e91a3921831b4e2fa10c740dc59d50 -Signed-off-by: T.J. Mercier ---- - mm/vmscan.c | 55 +++++++++++++++++++++++++++-------------------------- - 1 file changed, 28 insertions(+), 27 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3185,6 +3185,9 @@ static int get_swappiness(struct lruvec - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - struct pglist_data *pgdat = lruvec_pgdat(lruvec); - -+ if (!sc->may_swap) -+ return 0; -+ - if (!can_demote(pgdat->node_id, sc) && - mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH) - return 0; -@@ -4223,7 +4226,7 @@ static void walk_mm(struct lruvec *lruve - } while (err == -EAGAIN); - } - --static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat) -+static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat, bool force_alloc) - { - struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk; - -@@ -4231,7 +4234,7 @@ static struct lru_gen_mm_walk *set_mm_wa - VM_WARN_ON_ONCE(walk); - - walk = &pgdat->mm_walk; -- } else if (!pgdat && !walk) { -+ } else if (!walk && force_alloc) { - VM_WARN_ON_ONCE(current_is_kswapd()); - - walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); -@@ -4419,7 +4422,7 @@ static bool try_to_inc_max_seq(struct lr - goto done; - } - -- walk = set_mm_walk(NULL); -+ walk = set_mm_walk(NULL, true); - if (!walk) { - success = iterate_mm_list_nowalk(lruvec, max_seq); - goto done; -@@ -4488,8 +4491,6 @@ static bool lruvec_is_reclaimable(struct - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MIN_SEQ(lruvec); - -- VM_WARN_ON_ONCE(sc->memcg_low_reclaim); -- - /* see the comment on lru_gen_folio */ - gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]); - birth = READ_ONCE(lruvec->lrugen.timestamps[gen]); -@@ -4753,12 +4754,8 @@ static bool isolate_folio(struct lruvec - { - bool success; - -- /* unmapping inhibited */ -- if (!sc->may_unmap && folio_mapped(folio)) -- return false; -- - /* swapping inhibited */ -- if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) && -+ if (!(sc->gfp_mask & __GFP_IO) && - (folio_test_dirty(folio) || - (folio_test_anon(folio) && !folio_test_swapcache(folio)))) - return false; -@@ -4857,9 +4854,8 @@ static int scan_folios(struct lruvec *lr - __count_vm_events(PGSCAN_ANON + type, isolated); - - /* -- * There might not be eligible pages due to reclaim_idx, may_unmap and -- * may_writepage. Check the remaining to prevent livelock if it's not -- * making progress. -+ * There might not be eligible folios due to reclaim_idx. Check the -+ * remaining to prevent livelock if it's not making progress. - */ - return isolated || !remaining ? scanned : 0; - } -@@ -5118,8 +5114,7 @@ static long get_nr_to_scan(struct lruvec - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - DEFINE_MAX_SEQ(lruvec); - -- if (mem_cgroup_below_min(memcg) || -- (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) -+ if (mem_cgroup_below_min(memcg)) - return 0; - - if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan)) -@@ -5147,17 +5142,14 @@ static bool try_to_shrink_lruvec(struct - long nr_to_scan; - unsigned long scanned = 0; - unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); -+ int swappiness = get_swappiness(lruvec, sc); -+ -+ /* clean file folios are more likely to exist */ -+ if (swappiness && !(sc->gfp_mask & __GFP_IO)) -+ swappiness = 1; - - while (true) { - int delta; -- int swappiness; -- -- if (sc->may_swap) -- swappiness = get_swappiness(lruvec, sc); -- else if (!cgroup_reclaim(sc) && get_swappiness(lruvec, sc)) -- swappiness = 1; -- else -- swappiness = 0; - - nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness); - if (nr_to_scan <= 0) -@@ -5288,12 +5280,13 @@ static void lru_gen_shrink_lruvec(struct - struct blk_plug plug; - - VM_WARN_ON_ONCE(global_reclaim(sc)); -+ VM_WARN_ON_ONCE(!sc->may_writepage || !sc->may_unmap); - - lru_add_drain(); - - blk_start_plug(&plug); - -- set_mm_walk(lruvec_pgdat(lruvec)); -+ set_mm_walk(NULL, sc->proactive); - - if (try_to_shrink_lruvec(lruvec, sc)) - lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG); -@@ -5349,11 +5342,19 @@ static void lru_gen_shrink_node(struct p - - VM_WARN_ON_ONCE(!global_reclaim(sc)); - -+ /* -+ * Unmapped clean folios are already prioritized. Scanning for more of -+ * them is likely futile and can cause high reclaim latency when there -+ * is a large number of memcgs. -+ */ -+ if (!sc->may_writepage || !sc->may_unmap) -+ goto done; -+ - lru_add_drain(); - - blk_start_plug(&plug); - -- set_mm_walk(pgdat); -+ set_mm_walk(pgdat, sc->proactive); - - set_initial_priority(pgdat, sc); - -@@ -5371,7 +5372,7 @@ static void lru_gen_shrink_node(struct p - clear_mm_walk(); - - blk_finish_plug(&plug); -- -+done: - /* kswapd should never fail */ - pgdat->kswapd_failures = 0; - } -@@ -5943,7 +5944,7 @@ static ssize_t lru_gen_seq_write(struct - set_task_reclaim_state(current, &sc.reclaim_state); - flags = memalloc_noreclaim_save(); - blk_start_plug(&plug); -- if (!set_mm_walk(NULL)) { -+ if (!set_mm_walk(NULL, true)) { - err = -ENOMEM; - goto done; - } diff --git a/target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch b/target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch deleted file mode 100644 index 3cbc84f8b8e5c8..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-08-UPSTREAM-mm-multi-gen-LRU-simplify-arch_has_hw_pte_y.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 25887d48dff860751a06caa4188bfaf6bfb6e4b2 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Wed, 21 Dec 2022 21:19:06 -0700 -Subject: [PATCH 08/19] UPSTREAM: mm: multi-gen LRU: simplify - arch_has_hw_pte_young() check - -Scanning page tables when hardware does not set the accessed bit has -no real use cases. - -Link: https://lkml.kernel.org/r/20221222041905.2431096-9-yuzhao@google.com -Signed-off-by: Yu Zhao -Cc: Johannes Weiner -Cc: Jonathan Corbet -Cc: Michael Larabel -Cc: Michal Hocko -Cc: Mike Rapoport -Cc: Roman Gushchin -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton -Bug: 274865848 -(cherry picked from commit f386e9314025ea99dae639ed2032560a92081430) -Change-Id: I84d97ab665b4e3bb862a9bc7d72f50dea7191a6b -Signed-off-by: T.J. Mercier ---- - mm/vmscan.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4417,7 +4417,7 @@ static bool try_to_inc_max_seq(struct lr - * handful of PTEs. Spreading the work out over a period of time usually - * is less efficient, but it avoids bursty page faults. - */ -- if (!force_scan && !(arch_has_hw_pte_young() && get_cap(LRU_GEN_MM_WALK))) { -+ if (!arch_has_hw_pte_young() || !get_cap(LRU_GEN_MM_WALK)) { - success = iterate_mm_list_nowalk(lruvec, max_seq); - goto done; - } diff --git a/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch b/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch deleted file mode 100644 index 2ed3f07bbf6c39..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-09-UPSTREAM-mm-multi-gen-LRU-avoid-futile-retries.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 620b0ee94455e48d124414cd06d8a53f69fb6453 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Mon, 13 Feb 2023 00:53:22 -0700 -Subject: [PATCH 09/19] UPSTREAM: mm: multi-gen LRU: avoid futile retries - -Recall that the per-node memcg LRU has two generations and they alternate -when the last memcg (of a given node) is moved from one to the other. -Each generation is also sharded into multiple bins to improve scalability. -A reclaimer starts with a random bin (in the old generation) and, if it -fails, it will retry, i.e., to try the rest of the bins. - -If a reclaimer fails with the last memcg, it should move this memcg to the -young generation first, which causes the generations to alternate, and -then retry. Otherwise, the retries will be futile because all other bins -are empty. - -Link: https://lkml.kernel.org/r/20230213075322.1416966-1-yuzhao@google.com -Fixes: e4dde56cd208 ("mm: multi-gen LRU: per-node lru_gen_folio lists") -Signed-off-by: Yu Zhao -Reported-by: T.J. Mercier -Signed-off-by: Andrew Morton -Bug: 274865848 -(cherry picked from commit 9f550d78b40da21b4da515db4c37d8d7b12aa1a6) -Change-Id: Ie92535676b005ec9e7987632b742fdde8d54436f -Signed-off-by: T.J. Mercier ---- - mm/vmscan.c | 25 +++++++++++++++---------- - 1 file changed, 15 insertions(+), 10 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -5217,18 +5217,20 @@ static int shrink_one(struct lruvec *lru - - static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc) - { -+ int op; - int gen; - int bin; - int first_bin; - struct lruvec *lruvec; - struct lru_gen_folio *lrugen; -+ struct mem_cgroup *memcg; - const struct hlist_nulls_node *pos; -- int op = 0; -- struct mem_cgroup *memcg = NULL; - unsigned long nr_to_reclaim = get_nr_to_reclaim(sc); - - bin = first_bin = get_random_u32_below(MEMCG_NR_BINS); - restart: -+ op = 0; -+ memcg = NULL; - gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq)); - - rcu_read_lock(); -@@ -5252,14 +5254,22 @@ restart: - - op = shrink_one(lruvec, sc); - -- if (sc->nr_reclaimed >= nr_to_reclaim) -- goto success; -- - rcu_read_lock(); -+ -+ if (sc->nr_reclaimed >= nr_to_reclaim) -+ break; - } - - rcu_read_unlock(); - -+ if (op) -+ lru_gen_rotate_memcg(lruvec, op); -+ -+ mem_cgroup_put(memcg); -+ -+ if (sc->nr_reclaimed >= nr_to_reclaim) -+ return; -+ - /* restart if raced with lru_gen_rotate_memcg() */ - if (gen != get_nulls_value(pos)) - goto restart; -@@ -5268,11 +5278,6 @@ restart: - bin = get_memcg_bin(bin + 1); - if (bin != first_bin) - goto restart; --success: -- if (op) -- lru_gen_rotate_memcg(lruvec, op); -- -- mem_cgroup_put(memcg); - } - - static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) diff --git a/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch b/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch deleted file mode 100644 index 19d6e0a2077b74..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-10-UPSTREAM-mm-add-vma_has_recency.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 70d216c71ff5c5b17dd1da6294f97b91fb6aba7a Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Fri, 30 Dec 2022 14:52:51 -0700 -Subject: [PATCH 10/19] UPSTREAM: mm: add vma_has_recency() - -Add vma_has_recency() to indicate whether a VMA may exhibit temporal -locality that the LRU algorithm relies on. - -This function returns false for VMAs marked by VM_SEQ_READ or -VM_RAND_READ. While the former flag indicates linear access, i.e., a -special case of spatial locality, both flags indicate a lack of temporal -locality, i.e., the reuse of an area within a relatively small duration. - -"Recency" is chosen over "locality" to avoid confusion between temporal -and spatial localities. - -Before this patch, the active/inactive LRU only ignored the accessed bit -from VMAs marked by VM_SEQ_READ. After this patch, the active/inactive -LRU and MGLRU share the same logic: they both ignore the accessed bit if -vma_has_recency() returns false. - -For the active/inactive LRU, the following fio test showed a [6, 8]% -increase in IOPS when randomly accessing mapped files under memory -pressure. - - kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo) - kb=$((kb - 8*1024*1024)) - - modprobe brd rd_nr=1 rd_size=$kb - dd if=/dev/zero of=/dev/ram0 bs=1M - - mkfs.ext4 /dev/ram0 - mount /dev/ram0 /mnt/ - swapoff -a - - fio --name=test --directory=/mnt/ --ioengine=mmap --numjobs=8 \ - --size=8G --rw=randrw --time_based --runtime=10m \ - --group_reporting - -The discussion that led to this patch is here [1]. Additional test -results are available in that thread. - -[1] https://lore.kernel.org/r/Y31s%2FK8T85jh05wH@google.com/ - -Link: https://lkml.kernel.org/r/20221230215252.2628425-1-yuzhao@google.com -Change-Id: I291dcb795197659e40e46539cd32b857677c34ad -Signed-off-by: Yu Zhao -Cc: Alexander Viro -Cc: Andrea Righi -Cc: Johannes Weiner -Cc: Michael Larabel -Signed-off-by: Andrew Morton -(cherry picked from commit 8788f6781486769d9598dcaedc3fe0eb12fc3e59) -Bug: 274865848 -Signed-off-by: T.J. Mercier ---- - include/linux/mm_inline.h | 8 ++++++++ - mm/memory.c | 7 +++---- - mm/rmap.c | 42 +++++++++++++++++---------------------- - mm/vmscan.c | 5 ++++- - 4 files changed, 33 insertions(+), 29 deletions(-) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -600,4 +600,12 @@ pte_install_uffd_wp_if_needed(struct vm_ - #endif - } - -+static inline bool vma_has_recency(struct vm_area_struct *vma) -+{ -+ if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)) -+ return false; -+ -+ return true; -+} -+ - #endif ---- a/mm/memory.c -+++ b/mm/memory.c -@@ -1445,8 +1445,7 @@ again: - force_flush = 1; - set_page_dirty(page); - } -- if (pte_young(ptent) && -- likely(!(vma->vm_flags & VM_SEQ_READ))) -+ if (pte_young(ptent) && likely(vma_has_recency(vma))) - mark_page_accessed(page); - } - rss[mm_counter(page)]--; -@@ -5218,8 +5217,8 @@ static inline void mm_account_fault(stru - #ifdef CONFIG_LRU_GEN - static void lru_gen_enter_fault(struct vm_area_struct *vma) - { -- /* the LRU algorithm doesn't apply to sequential or random reads */ -- current->in_lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)); -+ /* the LRU algorithm only applies to accesses with recency */ -+ current->in_lru_fault = vma_has_recency(vma); - } - - static void lru_gen_exit_fault(void) ---- a/mm/rmap.c -+++ b/mm/rmap.c -@@ -823,25 +823,14 @@ static bool folio_referenced_one(struct - } - - if (pvmw.pte) { -- if (lru_gen_enabled() && pte_young(*pvmw.pte) && -- !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))) { -+ if (lru_gen_enabled() && pte_young(*pvmw.pte)) { - lru_gen_look_around(&pvmw); - referenced++; - } - - if (ptep_clear_flush_young_notify(vma, address, -- pvmw.pte)) { -- /* -- * Don't treat a reference through -- * a sequentially read mapping as such. -- * If the folio has been used in another mapping, -- * we will catch it; if this other mapping is -- * already gone, the unmap path will have set -- * the referenced flag or activated the folio. -- */ -- if (likely(!(vma->vm_flags & VM_SEQ_READ))) -- referenced++; -- } -+ pvmw.pte)) -+ referenced++; - } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { - if (pmdp_clear_flush_young_notify(vma, address, - pvmw.pmd)) -@@ -875,7 +864,20 @@ static bool invalid_folio_referenced_vma - struct folio_referenced_arg *pra = arg; - struct mem_cgroup *memcg = pra->memcg; - -- if (!mm_match_cgroup(vma->vm_mm, memcg)) -+ /* -+ * Ignore references from this mapping if it has no recency. If the -+ * folio has been used in another mapping, we will catch it; if this -+ * other mapping is already gone, the unmap path will have set the -+ * referenced flag or activated the folio in zap_pte_range(). -+ */ -+ if (!vma_has_recency(vma)) -+ return true; -+ -+ /* -+ * If we are reclaiming on behalf of a cgroup, skip counting on behalf -+ * of references from different cgroups. -+ */ -+ if (memcg && !mm_match_cgroup(vma->vm_mm, memcg)) - return true; - - return false; -@@ -906,6 +908,7 @@ int folio_referenced(struct folio *folio - .arg = (void *)&pra, - .anon_lock = folio_lock_anon_vma_read, - .try_lock = true, -+ .invalid_vma = invalid_folio_referenced_vma, - }; - - *vm_flags = 0; -@@ -921,15 +924,6 @@ int folio_referenced(struct folio *folio - return 1; - } - -- /* -- * If we are reclaiming on behalf of a cgroup, skip -- * counting on behalf of references from different -- * cgroups -- */ -- if (memcg) { -- rwc.invalid_vma = invalid_folio_referenced_vma; -- } -- - rmap_walk(folio, &rwc); - *vm_flags = pra.vm_flags; - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3778,7 +3778,10 @@ static int should_skip_vma(unsigned long - if (is_vm_hugetlb_page(vma)) - return true; - -- if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ | VM_RAND_READ)) -+ if (!vma_has_recency(vma)) -+ return true; -+ -+ if (vma->vm_flags & (VM_LOCKED | VM_SPECIAL)) - return true; - - if (vma == get_gate_vma(vma->vm_mm)) diff --git a/target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch b/target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch deleted file mode 100644 index f9c39be920cc85..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-11-UPSTREAM-mm-support-POSIX_FADV_NOREUSE.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 9ca4e437a24dfc4ec6c362f319eb9850b9eca497 Mon Sep 17 00:00:00 2001 -From: Yu Zhao -Date: Fri, 30 Dec 2022 14:52:52 -0700 -Subject: [PATCH 11/19] UPSTREAM: mm: support POSIX_FADV_NOREUSE - -This patch adds POSIX_FADV_NOREUSE to vma_has_recency() so that the LRU -algorithm can ignore access to mapped files marked by this flag. - -The advantages of POSIX_FADV_NOREUSE are: -1. Unlike MADV_SEQUENTIAL and MADV_RANDOM, it does not alter the - default readahead behavior. -2. Unlike MADV_SEQUENTIAL and MADV_RANDOM, it does not split VMAs and - therefore does not take mmap_lock. -3. Unlike MADV_COLD, setting it has a negligible cost, regardless of - how many pages it affects. - -Its limitations are: -1. Like POSIX_FADV_RANDOM and POSIX_FADV_SEQUENTIAL, it currently does - not support range. IOW, its scope is the entire file. -2. It currently does not ignore access through file descriptors. - Specifically, for the active/inactive LRU, given a file page shared - by two users and one of them having set POSIX_FADV_NOREUSE on the - file, this page will be activated upon the second user accessing - it. This corner case can be covered by checking POSIX_FADV_NOREUSE - before calling folio_mark_accessed() on the read path. But it is - considered not worth the effort. - -There have been a few attempts to support POSIX_FADV_NOREUSE, e.g., [1]. -This time the goal is to fill a niche: a few desktop applications, e.g., -large file transferring and video encoding/decoding, want fast file -streaming with mmap() rather than direct IO. Among those applications, an -SVT-AV1 regression was reported when running with MGLRU [2]. The -following test can reproduce that regression. - - kb=$(awk '/MemTotal/ { print $2 }' /proc/meminfo) - kb=$((kb - 8*1024*1024)) - - modprobe brd rd_nr=1 rd_size=$kb - dd if=/dev/zero of=/dev/ram0 bs=1M - - mkfs.ext4 /dev/ram0 - mount /dev/ram0 /mnt/ - swapoff -a - - fallocate -l 8G /mnt/swapfile - mkswap /mnt/swapfile - swapon /mnt/swapfile - - wget http://ultravideo.cs.tut.fi/video/Bosphorus_3840x2160_120fps_420_8bit_YUV_Y4M.7z - 7z e -o/mnt/ Bosphorus_3840x2160_120fps_420_8bit_YUV_Y4M.7z - SvtAv1EncApp --preset 12 -w 3840 -h 2160 \ - -i /mnt/Bosphorus_3840x2160.y4m - -For MGLRU, the following change showed a [9-11]% increase in FPS, -which makes it on par with the active/inactive LRU. - - patch Source/App/EncApp/EbAppMain.c < #include - 35d35 - < #include /* _O_BINARY */ - 117a118 - > posix_fadvise(config->mmap.fd, 0, 0, POSIX_FADV_NOREUSE); - EOF - -[1] https://lore.kernel.org/r/1308923350-7932-1-git-send-email-andrea@betterlinux.com/ -[2] https://openbenchmarking.org/result/2209259-PTS-MGLRU8GB57 - -Link: https://lkml.kernel.org/r/20221230215252.2628425-2-yuzhao@google.com -Change-Id: I0b7f5f971d78014ea1ba44cee6a8ec902a4330d0 -Signed-off-by: Yu Zhao -Cc: Alexander Viro -Cc: Andrea Righi -Cc: Johannes Weiner -Cc: Michael Larabel -Signed-off-by: Andrew Morton -(cherry picked from commit 17e810229cb3068b692fa078bd9b3a6527e0866a) -Bug: 274865848 -Signed-off-by: T.J. Mercier ---- - include/linux/fs.h | 2 ++ - include/linux/mm_inline.h | 3 +++ - mm/fadvise.c | 5 ++++- - 3 files changed, 9 insertions(+), 1 deletion(-) - ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -166,6 +166,8 @@ typedef int (dio_iodone_t)(struct kiocb - /* File supports DIRECT IO */ - #define FMODE_CAN_ODIRECT ((__force fmode_t)0x400000) - -+#define FMODE_NOREUSE ((__force fmode_t)0x800000) -+ - /* File was opened by fanotify and shouldn't generate fanotify events */ - #define FMODE_NONOTIFY ((__force fmode_t)0x4000000) - ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -605,6 +605,9 @@ static inline bool vma_has_recency(struc - if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)) - return false; - -+ if (vma->vm_file && (vma->vm_file->f_mode & FMODE_NOREUSE)) -+ return false; -+ - return true; - } - ---- a/mm/fadvise.c -+++ b/mm/fadvise.c -@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, l - case POSIX_FADV_NORMAL: - file->f_ra.ra_pages = bdi->ra_pages; - spin_lock(&file->f_lock); -- file->f_mode &= ~FMODE_RANDOM; -+ file->f_mode &= ~(FMODE_RANDOM | FMODE_NOREUSE); - spin_unlock(&file->f_lock); - break; - case POSIX_FADV_RANDOM: -@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, l - force_page_cache_readahead(mapping, file, start_index, nrpages); - break; - case POSIX_FADV_NOREUSE: -+ spin_lock(&file->f_lock); -+ file->f_mode |= FMODE_NOREUSE; -+ spin_unlock(&file->f_lock); - break; - case POSIX_FADV_DONTNEED: - __filemap_fdatawrite_range(mapping, offset, endbyte, diff --git a/target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch b/target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch deleted file mode 100644 index bac2e3e34409b0..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-12-UPSTREAM-mm-multi-gen-LRU-section-for-working-set-pr.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 1b5e4c317d80f4826eceb3781702d18d06b14394 Mon Sep 17 00:00:00 2001 -From: "T.J. Alumbaugh" -Date: Wed, 18 Jan 2023 00:18:21 +0000 -Subject: [PATCH 12/19] UPSTREAM: mm: multi-gen LRU: section for working set - protection - -Patch series "mm: multi-gen LRU: improve". - -This patch series improves a few MGLRU functions, collects related -functions, and adds additional documentation. - -This patch (of 7): - -Add a section for working set protection in the code and the design doc. -The admin doc already contains its usage. - -Link: https://lkml.kernel.org/r/20230118001827.1040870-1-talumbau@google.com -Link: https://lkml.kernel.org/r/20230118001827.1040870-2-talumbau@google.com -Change-Id: I65599075fd42951db7739a2ab7cee78516e157b3 -Signed-off-by: T.J. Alumbaugh -Cc: Yu Zhao -Signed-off-by: Andrew Morton -(cherry picked from commit 7b8144e63d84716f16a1b929e0c7e03ae5c4d5c1) -Bug: 274865848 -Signed-off-by: T.J. Mercier ---- - Documentation/mm/multigen_lru.rst | 15 +++++++++++++++ - mm/vmscan.c | 4 ++++ - 2 files changed, 19 insertions(+) - ---- a/Documentation/mm/multigen_lru.rst -+++ b/Documentation/mm/multigen_lru.rst -@@ -141,6 +141,21 @@ loop has detected outlying refaults from - this end, the feedback loop uses the first tier as the baseline, for - the reason stated earlier. - -+Working set protection -+---------------------- -+Each generation is timestamped at birth. If ``lru_gen_min_ttl`` is -+set, an ``lruvec`` is protected from the eviction when its oldest -+generation was born within ``lru_gen_min_ttl`` milliseconds. In other -+words, it prevents the working set of ``lru_gen_min_ttl`` milliseconds -+from getting evicted. The OOM killer is triggered if this working set -+cannot be kept in memory. -+ -+This time-based approach has the following advantages: -+ -+1. It is easier to configure because it is agnostic to applications -+ and memory sizes. -+2. It is more reliable because it is directly wired to the OOM killer. -+ - Summary - ------- - The multi-gen LRU can be disassembled into the following parts: ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4461,6 +4461,10 @@ done: - return true; - } - -+/****************************************************************************** -+ * working set protection -+ ******************************************************************************/ -+ - static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc) - { - int gen, type, zone; diff --git a/target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch b/target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch deleted file mode 100644 index c28a1c5d5b9b4b..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-13-UPSTREAM-mm-multi-gen-LRU-section-for-rmap-PT-walk-f.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 5ddf9d53d375e42af49b744bd7c2f8247c6bce15 Mon Sep 17 00:00:00 2001 -From: "T.J. Alumbaugh" -Date: Wed, 18 Jan 2023 00:18:22 +0000 -Subject: [PATCH 13/19] UPSTREAM: mm: multi-gen LRU: section for rmap/PT walk - feedback - -Add a section for lru_gen_look_around() in the code and the design doc. - -Link: https://lkml.kernel.org/r/20230118001827.1040870-3-talumbau@google.com -Change-Id: I5097af63f61b3b69ec2abee6cdbdc33c296df213 -Signed-off-by: T.J. Alumbaugh -Cc: Yu Zhao -Signed-off-by: Andrew Morton -(cherry picked from commit db19a43d9b3a8876552f00f656008206ef9a5efa) -Bug: 274865848 -Signed-off-by: T.J. Mercier ---- - Documentation/mm/multigen_lru.rst | 14 ++++++++++++++ - mm/vmscan.c | 4 ++++ - 2 files changed, 18 insertions(+) - ---- a/Documentation/mm/multigen_lru.rst -+++ b/Documentation/mm/multigen_lru.rst -@@ -156,6 +156,20 @@ This time-based approach has the followi - and memory sizes. - 2. It is more reliable because it is directly wired to the OOM killer. - -+Rmap/PT walk feedback -+--------------------- -+Searching the rmap for PTEs mapping each page on an LRU list (to test -+and clear the accessed bit) can be expensive because pages from -+different VMAs (PA space) are not cache friendly to the rmap (VA -+space). For workloads mostly using mapped pages, searching the rmap -+can incur the highest CPU cost in the reclaim path. -+ -+``lru_gen_look_around()`` exploits spatial locality to reduce the -+trips into the rmap. It scans the adjacent PTEs of a young PTE and -+promotes hot pages. If the scan was done cacheline efficiently, it -+adds the PMD entry pointing to the PTE table to the Bloom filter. This -+forms a feedback loop between the eviction and the aging. -+ - Summary - ------- - The multi-gen LRU can be disassembled into the following parts: ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4555,6 +4555,10 @@ static void lru_gen_age_node(struct pgli - } - } - -+/****************************************************************************** -+ * rmap/PT walk feedback -+ ******************************************************************************/ -+ - /* - * This function exploits spatial locality when shrink_folio_list() walks the - * rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. If diff --git a/target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch b/target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch deleted file mode 100644 index a7dfb5ffe7960e..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-14-UPSTREAM-mm-multi-gen-LRU-section-for-Bloom-filters.patch +++ /dev/null @@ -1,243 +0,0 @@ -From 397624e12244ec038f51cb1f178ccb7a2ec562e5 Mon Sep 17 00:00:00 2001 -From: "T.J. Alumbaugh" -Date: Wed, 18 Jan 2023 00:18:23 +0000 -Subject: [PATCH 14/19] UPSTREAM: mm: multi-gen LRU: section for Bloom filters - -Move Bloom filters code into a dedicated section. Improve the design doc -to explain Bloom filter usage and connection between aging and eviction in -their use. - -Link: https://lkml.kernel.org/r/20230118001827.1040870-4-talumbau@google.com -Change-Id: I73e866f687c1ed9f5c8538086aa39408b79897db -Signed-off-by: T.J. Alumbaugh -Cc: Yu Zhao -Signed-off-by: Andrew Morton -(cherry picked from commit ccbbbb85945d8f0255aa9dbc1b617017e2294f2c) -Bug: 274865848 -Signed-off-by: T.J. Mercier ---- - Documentation/mm/multigen_lru.rst | 16 +++ - mm/vmscan.c | 180 +++++++++++++++--------------- - 2 files changed, 108 insertions(+), 88 deletions(-) - ---- a/Documentation/mm/multigen_lru.rst -+++ b/Documentation/mm/multigen_lru.rst -@@ -170,6 +170,22 @@ promotes hot pages. If the scan was done - adds the PMD entry pointing to the PTE table to the Bloom filter. This - forms a feedback loop between the eviction and the aging. - -+Bloom Filters -+------------- -+Bloom filters are a space and memory efficient data structure for set -+membership test, i.e., test if an element is not in the set or may be -+in the set. -+ -+In the eviction path, specifically, in ``lru_gen_look_around()``, if a -+PMD has a sufficient number of hot pages, its address is placed in the -+filter. In the aging path, set membership means that the PTE range -+will be scanned for young pages. -+ -+Note that Bloom filters are probabilistic on set membership. If a test -+is false positive, the cost is an additional scan of a range of PTEs, -+which may yield hot pages anyway. Parameters of the filter itself can -+control the false positive rate in the limit. -+ - Summary - ------- - The multi-gen LRU can be disassembled into the following parts: ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3209,6 +3209,98 @@ static bool __maybe_unused seq_is_valid( - } - - /****************************************************************************** -+ * Bloom filters -+ ******************************************************************************/ -+ -+/* -+ * Bloom filters with m=1<<15, k=2 and the false positive rates of ~1/5 when -+ * n=10,000 and ~1/2 when n=20,000, where, conventionally, m is the number of -+ * bits in a bitmap, k is the number of hash functions and n is the number of -+ * inserted items. -+ * -+ * Page table walkers use one of the two filters to reduce their search space. -+ * To get rid of non-leaf entries that no longer have enough leaf entries, the -+ * aging uses the double-buffering technique to flip to the other filter each -+ * time it produces a new generation. For non-leaf entries that have enough -+ * leaf entries, the aging carries them over to the next generation in -+ * walk_pmd_range(); the eviction also report them when walking the rmap -+ * in lru_gen_look_around(). -+ * -+ * For future optimizations: -+ * 1. It's not necessary to keep both filters all the time. The spare one can be -+ * freed after the RCU grace period and reallocated if needed again. -+ * 2. And when reallocating, it's worth scaling its size according to the number -+ * of inserted entries in the other filter, to reduce the memory overhead on -+ * small systems and false positives on large systems. -+ * 3. Jenkins' hash function is an alternative to Knuth's. -+ */ -+#define BLOOM_FILTER_SHIFT 15 -+ -+static inline int filter_gen_from_seq(unsigned long seq) -+{ -+ return seq % NR_BLOOM_FILTERS; -+} -+ -+static void get_item_key(void *item, int *key) -+{ -+ u32 hash = hash_ptr(item, BLOOM_FILTER_SHIFT * 2); -+ -+ BUILD_BUG_ON(BLOOM_FILTER_SHIFT * 2 > BITS_PER_TYPE(u32)); -+ -+ key[0] = hash & (BIT(BLOOM_FILTER_SHIFT) - 1); -+ key[1] = hash >> BLOOM_FILTER_SHIFT; -+} -+ -+static bool test_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item) -+{ -+ int key[2]; -+ unsigned long *filter; -+ int gen = filter_gen_from_seq(seq); -+ -+ filter = READ_ONCE(lruvec->mm_state.filters[gen]); -+ if (!filter) -+ return true; -+ -+ get_item_key(item, key); -+ -+ return test_bit(key[0], filter) && test_bit(key[1], filter); -+} -+ -+static void update_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item) -+{ -+ int key[2]; -+ unsigned long *filter; -+ int gen = filter_gen_from_seq(seq); -+ -+ filter = READ_ONCE(lruvec->mm_state.filters[gen]); -+ if (!filter) -+ return; -+ -+ get_item_key(item, key); -+ -+ if (!test_bit(key[0], filter)) -+ set_bit(key[0], filter); -+ if (!test_bit(key[1], filter)) -+ set_bit(key[1], filter); -+} -+ -+static void reset_bloom_filter(struct lruvec *lruvec, unsigned long seq) -+{ -+ unsigned long *filter; -+ int gen = filter_gen_from_seq(seq); -+ -+ filter = lruvec->mm_state.filters[gen]; -+ if (filter) { -+ bitmap_clear(filter, 0, BIT(BLOOM_FILTER_SHIFT)); -+ return; -+ } -+ -+ filter = bitmap_zalloc(BIT(BLOOM_FILTER_SHIFT), -+ __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); -+ WRITE_ONCE(lruvec->mm_state.filters[gen], filter); -+} -+ -+/****************************************************************************** - * mm_struct list - ******************************************************************************/ - -@@ -3333,94 +3425,6 @@ void lru_gen_migrate_mm(struct mm_struct - } - #endif - --/* -- * Bloom filters with m=1<<15, k=2 and the false positive rates of ~1/5 when -- * n=10,000 and ~1/2 when n=20,000, where, conventionally, m is the number of -- * bits in a bitmap, k is the number of hash functions and n is the number of -- * inserted items. -- * -- * Page table walkers use one of the two filters to reduce their search space. -- * To get rid of non-leaf entries that no longer have enough leaf entries, the -- * aging uses the double-buffering technique to flip to the other filter each -- * time it produces a new generation. For non-leaf entries that have enough -- * leaf entries, the aging carries them over to the next generation in -- * walk_pmd_range(); the eviction also report them when walking the rmap -- * in lru_gen_look_around(). -- * -- * For future optimizations: -- * 1. It's not necessary to keep both filters all the time. The spare one can be -- * freed after the RCU grace period and reallocated if needed again. -- * 2. And when reallocating, it's worth scaling its size according to the number -- * of inserted entries in the other filter, to reduce the memory overhead on -- * small systems and false positives on large systems. -- * 3. Jenkins' hash function is an alternative to Knuth's. -- */ --#define BLOOM_FILTER_SHIFT 15 -- --static inline int filter_gen_from_seq(unsigned long seq) --{ -- return seq % NR_BLOOM_FILTERS; --} -- --static void get_item_key(void *item, int *key) --{ -- u32 hash = hash_ptr(item, BLOOM_FILTER_SHIFT * 2); -- -- BUILD_BUG_ON(BLOOM_FILTER_SHIFT * 2 > BITS_PER_TYPE(u32)); -- -- key[0] = hash & (BIT(BLOOM_FILTER_SHIFT) - 1); -- key[1] = hash >> BLOOM_FILTER_SHIFT; --} -- --static void reset_bloom_filter(struct lruvec *lruvec, unsigned long seq) --{ -- unsigned long *filter; -- int gen = filter_gen_from_seq(seq); -- -- filter = lruvec->mm_state.filters[gen]; -- if (filter) { -- bitmap_clear(filter, 0, BIT(BLOOM_FILTER_SHIFT)); -- return; -- } -- -- filter = bitmap_zalloc(BIT(BLOOM_FILTER_SHIFT), -- __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); -- WRITE_ONCE(lruvec->mm_state.filters[gen], filter); --} -- --static void update_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item) --{ -- int key[2]; -- unsigned long *filter; -- int gen = filter_gen_from_seq(seq); -- -- filter = READ_ONCE(lruvec->mm_state.filters[gen]); -- if (!filter) -- return; -- -- get_item_key(item, key); -- -- if (!test_bit(key[0], filter)) -- set_bit(key[0], filter); -- if (!test_bit(key[1], filter)) -- set_bit(key[1], filter); --} -- --static bool test_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item) --{ -- int key[2]; -- unsigned long *filter; -- int gen = filter_gen_from_seq(seq); -- -- filter = READ_ONCE(lruvec->mm_state.filters[gen]); -- if (!filter) -- return true; -- -- get_item_key(item, key); -- -- return test_bit(key[0], filter) && test_bit(key[1], filter); --} -- - static void reset_mm_stats(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, bool last) - { - int i; diff --git a/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch b/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch deleted file mode 100644 index 11c1b43db96903..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-15-UPSTREAM-mm-multi-gen-LRU-section-for-memcg-LRU.patch +++ /dev/null @@ -1,427 +0,0 @@ -From 48c916b812652f9453be5bd45a703728926d41ca Mon Sep 17 00:00:00 2001 -From: "T.J. Alumbaugh" -Date: Wed, 18 Jan 2023 00:18:24 +0000 -Subject: [PATCH 15/19] UPSTREAM: mm: multi-gen LRU: section for memcg LRU - -Move memcg LRU code into a dedicated section. Improve the design doc to -outline its architecture. - -Link: https://lkml.kernel.org/r/20230118001827.1040870-5-talumbau@google.com -Change-Id: Id252e420cff7a858acb098cf2b3642da5c40f602 -Signed-off-by: T.J. Alumbaugh -Cc: Yu Zhao -Signed-off-by: Andrew Morton -(cherry picked from commit 36c7b4db7c942ae9e1b111f0c6b468c8b2e33842) -Bug: 274865848 -Signed-off-by: T.J. Mercier ---- - Documentation/mm/multigen_lru.rst | 33 +++- - include/linux/mm_inline.h | 17 -- - include/linux/mmzone.h | 13 +- - mm/memcontrol.c | 8 +- - mm/vmscan.c | 250 +++++++++++++++++------------- - 5 files changed, 178 insertions(+), 143 deletions(-) - ---- a/Documentation/mm/multigen_lru.rst -+++ b/Documentation/mm/multigen_lru.rst -@@ -186,9 +186,40 @@ is false positive, the cost is an additi - which may yield hot pages anyway. Parameters of the filter itself can - control the false positive rate in the limit. - -+Memcg LRU -+--------- -+An memcg LRU is a per-node LRU of memcgs. It is also an LRU of LRUs, -+since each node and memcg combination has an LRU of folios (see -+``mem_cgroup_lruvec()``). Its goal is to improve the scalability of -+global reclaim, which is critical to system-wide memory overcommit in -+data centers. Note that memcg LRU only applies to global reclaim. -+ -+The basic structure of an memcg LRU can be understood by an analogy to -+the active/inactive LRU (of folios): -+ -+1. It has the young and the old (generations), i.e., the counterparts -+ to the active and the inactive; -+2. The increment of ``max_seq`` triggers promotion, i.e., the -+ counterpart to activation; -+3. Other events trigger similar operations, e.g., offlining an memcg -+ triggers demotion, i.e., the counterpart to deactivation. -+ -+In terms of global reclaim, it has two distinct features: -+ -+1. Sharding, which allows each thread to start at a random memcg (in -+ the old generation) and improves parallelism; -+2. Eventual fairness, which allows direct reclaim to bail out at will -+ and reduces latency without affecting fairness over some time. -+ -+In terms of traversing memcgs during global reclaim, it improves the -+best-case complexity from O(n) to O(1) and does not affect the -+worst-case complexity O(n). Therefore, on average, it has a sublinear -+complexity. -+ - Summary - ------- --The multi-gen LRU can be disassembled into the following parts: -+The multi-gen LRU (of folios) can be disassembled into the following -+parts: - - * Generations - * Rmap walks ---- a/include/linux/mm_inline.h -+++ b/include/linux/mm_inline.h -@@ -122,18 +122,6 @@ static inline bool lru_gen_in_fault(void - return current->in_lru_fault; - } - --#ifdef CONFIG_MEMCG --static inline int lru_gen_memcg_seg(struct lruvec *lruvec) --{ -- return READ_ONCE(lruvec->lrugen.seg); --} --#else --static inline int lru_gen_memcg_seg(struct lruvec *lruvec) --{ -- return 0; --} --#endif -- - static inline int lru_gen_from_seq(unsigned long seq) - { - return seq % MAX_NR_GENS; -@@ -314,11 +302,6 @@ static inline bool lru_gen_in_fault(void - return false; - } - --static inline int lru_gen_memcg_seg(struct lruvec *lruvec) --{ -- return 0; --} -- - static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming) - { - return false; ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -368,15 +368,6 @@ struct page_vma_mapped_walk; - #define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF) - #define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF) - --/* see the comment on MEMCG_NR_GENS */ --enum { -- MEMCG_LRU_NOP, -- MEMCG_LRU_HEAD, -- MEMCG_LRU_TAIL, -- MEMCG_LRU_OLD, -- MEMCG_LRU_YOUNG, --}; -- - #ifdef CONFIG_LRU_GEN - - enum { -@@ -557,7 +548,7 @@ void lru_gen_exit_memcg(struct mem_cgrou - void lru_gen_online_memcg(struct mem_cgroup *memcg); - void lru_gen_offline_memcg(struct mem_cgroup *memcg); - void lru_gen_release_memcg(struct mem_cgroup *memcg); --void lru_gen_rotate_memcg(struct lruvec *lruvec, int op); -+void lru_gen_soft_reclaim(struct lruvec *lruvec); - - #else /* !CONFIG_MEMCG */ - -@@ -608,7 +599,7 @@ static inline void lru_gen_release_memcg - { - } - --static inline void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) -+static inline void lru_gen_soft_reclaim(struct lruvec *lruvec) - { - } - ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -478,12 +478,8 @@ static void mem_cgroup_update_tree(struc - struct mem_cgroup_tree_per_node *mctz; - - if (lru_gen_enabled()) { -- struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec; -- -- /* see the comment on MEMCG_NR_GENS */ -- if (soft_limit_excess(memcg) && lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD) -- lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD); -- -+ if (soft_limit_excess(memcg)) -+ lru_gen_soft_reclaim(&memcg->nodeinfo[nid]->lruvec); - return; - } - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4692,6 +4692,148 @@ void lru_gen_look_around(struct page_vma - } - - /****************************************************************************** -+ * memcg LRU -+ ******************************************************************************/ -+ -+/* see the comment on MEMCG_NR_GENS */ -+enum { -+ MEMCG_LRU_NOP, -+ MEMCG_LRU_HEAD, -+ MEMCG_LRU_TAIL, -+ MEMCG_LRU_OLD, -+ MEMCG_LRU_YOUNG, -+}; -+ -+#ifdef CONFIG_MEMCG -+ -+static int lru_gen_memcg_seg(struct lruvec *lruvec) -+{ -+ return READ_ONCE(lruvec->lrugen.seg); -+} -+ -+static void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) -+{ -+ int seg; -+ int old, new; -+ int bin = get_random_u32_below(MEMCG_NR_BINS); -+ struct pglist_data *pgdat = lruvec_pgdat(lruvec); -+ -+ spin_lock(&pgdat->memcg_lru.lock); -+ -+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); -+ -+ seg = 0; -+ new = old = lruvec->lrugen.gen; -+ -+ /* see the comment on MEMCG_NR_GENS */ -+ if (op == MEMCG_LRU_HEAD) -+ seg = MEMCG_LRU_HEAD; -+ else if (op == MEMCG_LRU_TAIL) -+ seg = MEMCG_LRU_TAIL; -+ else if (op == MEMCG_LRU_OLD) -+ new = get_memcg_gen(pgdat->memcg_lru.seq); -+ else if (op == MEMCG_LRU_YOUNG) -+ new = get_memcg_gen(pgdat->memcg_lru.seq + 1); -+ else -+ VM_WARN_ON_ONCE(true); -+ -+ hlist_nulls_del_rcu(&lruvec->lrugen.list); -+ -+ if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD) -+ hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); -+ else -+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); -+ -+ pgdat->memcg_lru.nr_memcgs[old]--; -+ pgdat->memcg_lru.nr_memcgs[new]++; -+ -+ lruvec->lrugen.gen = new; -+ WRITE_ONCE(lruvec->lrugen.seg, seg); -+ -+ if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq)) -+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); -+ -+ spin_unlock(&pgdat->memcg_lru.lock); -+} -+ -+void lru_gen_online_memcg(struct mem_cgroup *memcg) -+{ -+ int gen; -+ int nid; -+ int bin = get_random_u32_below(MEMCG_NR_BINS); -+ -+ for_each_node(nid) { -+ struct pglist_data *pgdat = NODE_DATA(nid); -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ spin_lock(&pgdat->memcg_lru.lock); -+ -+ VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list)); -+ -+ gen = get_memcg_gen(pgdat->memcg_lru.seq); -+ -+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]); -+ pgdat->memcg_lru.nr_memcgs[gen]++; -+ -+ lruvec->lrugen.gen = gen; -+ -+ spin_unlock(&pgdat->memcg_lru.lock); -+ } -+} -+ -+void lru_gen_offline_memcg(struct mem_cgroup *memcg) -+{ -+ int nid; -+ -+ for_each_node(nid) { -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD); -+ } -+} -+ -+void lru_gen_release_memcg(struct mem_cgroup *memcg) -+{ -+ int gen; -+ int nid; -+ -+ for_each_node(nid) { -+ struct pglist_data *pgdat = NODE_DATA(nid); -+ struct lruvec *lruvec = get_lruvec(memcg, nid); -+ -+ spin_lock(&pgdat->memcg_lru.lock); -+ -+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); -+ -+ gen = lruvec->lrugen.gen; -+ -+ hlist_nulls_del_rcu(&lruvec->lrugen.list); -+ pgdat->memcg_lru.nr_memcgs[gen]--; -+ -+ if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq)) -+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); -+ -+ spin_unlock(&pgdat->memcg_lru.lock); -+ } -+} -+ -+void lru_gen_soft_reclaim(struct lruvec *lruvec) -+{ -+ /* see the comment on MEMCG_NR_GENS */ -+ if (lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD) -+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD); -+} -+ -+#else /* !CONFIG_MEMCG */ -+ -+static int lru_gen_memcg_seg(struct lruvec *lruvec) -+{ -+ return 0; -+} -+ -+#endif -+ -+/****************************************************************************** - * the eviction - ******************************************************************************/ - -@@ -5397,53 +5539,6 @@ done: - pgdat->kswapd_failures = 0; - } - --#ifdef CONFIG_MEMCG --void lru_gen_rotate_memcg(struct lruvec *lruvec, int op) --{ -- int seg; -- int old, new; -- int bin = get_random_u32_below(MEMCG_NR_BINS); -- struct pglist_data *pgdat = lruvec_pgdat(lruvec); -- -- spin_lock(&pgdat->memcg_lru.lock); -- -- VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); -- -- seg = 0; -- new = old = lruvec->lrugen.gen; -- -- /* see the comment on MEMCG_NR_GENS */ -- if (op == MEMCG_LRU_HEAD) -- seg = MEMCG_LRU_HEAD; -- else if (op == MEMCG_LRU_TAIL) -- seg = MEMCG_LRU_TAIL; -- else if (op == MEMCG_LRU_OLD) -- new = get_memcg_gen(pgdat->memcg_lru.seq); -- else if (op == MEMCG_LRU_YOUNG) -- new = get_memcg_gen(pgdat->memcg_lru.seq + 1); -- else -- VM_WARN_ON_ONCE(true); -- -- hlist_nulls_del_rcu(&lruvec->lrugen.list); -- -- if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD) -- hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); -- else -- hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]); -- -- pgdat->memcg_lru.nr_memcgs[old]--; -- pgdat->memcg_lru.nr_memcgs[new]++; -- -- lruvec->lrugen.gen = new; -- WRITE_ONCE(lruvec->lrugen.seg, seg); -- -- if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq)) -- WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); -- -- spin_unlock(&pgdat->memcg_lru.lock); --} --#endif -- - /****************************************************************************** - * state change - ******************************************************************************/ -@@ -6089,67 +6184,6 @@ void lru_gen_exit_memcg(struct mem_cgrou - } - } - --void lru_gen_online_memcg(struct mem_cgroup *memcg) --{ -- int gen; -- int nid; -- int bin = get_random_u32_below(MEMCG_NR_BINS); -- -- for_each_node(nid) { -- struct pglist_data *pgdat = NODE_DATA(nid); -- struct lruvec *lruvec = get_lruvec(memcg, nid); -- -- spin_lock(&pgdat->memcg_lru.lock); -- -- VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list)); -- -- gen = get_memcg_gen(pgdat->memcg_lru.seq); -- -- hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]); -- pgdat->memcg_lru.nr_memcgs[gen]++; -- -- lruvec->lrugen.gen = gen; -- -- spin_unlock(&pgdat->memcg_lru.lock); -- } --} -- --void lru_gen_offline_memcg(struct mem_cgroup *memcg) --{ -- int nid; -- -- for_each_node(nid) { -- struct lruvec *lruvec = get_lruvec(memcg, nid); -- -- lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD); -- } --} -- --void lru_gen_release_memcg(struct mem_cgroup *memcg) --{ -- int gen; -- int nid; -- -- for_each_node(nid) { -- struct pglist_data *pgdat = NODE_DATA(nid); -- struct lruvec *lruvec = get_lruvec(memcg, nid); -- -- spin_lock(&pgdat->memcg_lru.lock); -- -- VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list)); -- -- gen = lruvec->lrugen.gen; -- -- hlist_nulls_del_rcu(&lruvec->lrugen.list); -- pgdat->memcg_lru.nr_memcgs[gen]--; -- -- if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq)) -- WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1); -- -- spin_unlock(&pgdat->memcg_lru.lock); -- } --} -- - #endif /* CONFIG_MEMCG */ - - static int __init init_lru_gen(void) diff --git a/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch b/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch deleted file mode 100644 index fcb9708d8aaeec..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-16-UPSTREAM-mm-multi-gen-LRU-improve-lru_gen_exit_memcg.patch +++ /dev/null @@ -1,40 +0,0 @@ -From bec433f29537652ed054148edfd7e2183ddcf7c3 Mon Sep 17 00:00:00 2001 -From: "T.J. Alumbaugh" -Date: Wed, 18 Jan 2023 00:18:25 +0000 -Subject: [PATCH 16/19] UPSTREAM: mm: multi-gen LRU: improve - lru_gen_exit_memcg() - -Add warnings and poison ->next. - -Link: https://lkml.kernel.org/r/20230118001827.1040870-6-talumbau@google.com -Change-Id: I53de9e04c1ae941e122b33cd45d2bbb5f34aae0c -Signed-off-by: T.J. Alumbaugh -Cc: Yu Zhao -Signed-off-by: Andrew Morton -(cherry picked from commit 37cc99979d04cca677c0ad5c0acd1149ec165d1b) -Bug: 274865848 -Signed-off-by: T.J. Mercier ---- - mm/vmscan.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -6171,12 +6171,17 @@ void lru_gen_exit_memcg(struct mem_cgrou - int i; - int nid; - -+ VM_WARN_ON_ONCE(!list_empty(&memcg->mm_list.fifo)); -+ - for_each_node(nid) { - struct lruvec *lruvec = get_lruvec(memcg, nid); - -+ VM_WARN_ON_ONCE(lruvec->mm_state.nr_walkers); - VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0, - sizeof(lruvec->lrugen.nr_pages))); - -+ lruvec->lrugen.list.next = LIST_POISON1; -+ - for (i = 0; i < NR_BLOOM_FILTERS; i++) { - bitmap_free(lruvec->mm_state.filters[i]); - lruvec->mm_state.filters[i] = NULL; diff --git a/target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch b/target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch deleted file mode 100644 index 2273977dc9c143..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-17-UPSTREAM-mm-multi-gen-LRU-improve-walk_pmd_range.patch +++ /dev/null @@ -1,135 +0,0 @@ -From fc0e3b06e0f19917b7ecad7967a72f61d4743644 Mon Sep 17 00:00:00 2001 -From: "T.J. Alumbaugh" -Date: Wed, 18 Jan 2023 00:18:26 +0000 -Subject: [PATCH 17/19] UPSTREAM: mm: multi-gen LRU: improve walk_pmd_range() - -Improve readability of walk_pmd_range() and walk_pmd_range_locked(). - -Link: https://lkml.kernel.org/r/20230118001827.1040870-7-talumbau@google.com -Change-Id: Ia084fbf53fe989673b7804ca8ca520af12d7d52a -Signed-off-by: T.J. Alumbaugh -Cc: Yu Zhao -Signed-off-by: Andrew Morton -(cherry picked from commit b5ff4133617d0eced35b685da0bd0929dd9fabb7) -Bug: 274865848 -Signed-off-by: T.J. Mercier ---- - mm/vmscan.c | 40 ++++++++++++++++++++-------------------- - 1 file changed, 20 insertions(+), 20 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3980,8 +3980,8 @@ restart: - } - - #if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG) --static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma, -- struct mm_walk *args, unsigned long *bitmap, unsigned long *start) -+static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area_struct *vma, -+ struct mm_walk *args, unsigned long *bitmap, unsigned long *first) - { - int i; - pmd_t *pmd; -@@ -3994,18 +3994,19 @@ static void walk_pmd_range_locked(pud_t - VM_WARN_ON_ONCE(pud_leaf(*pud)); - - /* try to batch at most 1+MIN_LRU_BATCH+1 entries */ -- if (*start == -1) { -- *start = next; -+ if (*first == -1) { -+ *first = addr; -+ bitmap_zero(bitmap, MIN_LRU_BATCH); - return; - } - -- i = next == -1 ? 0 : pmd_index(next) - pmd_index(*start); -+ i = addr == -1 ? 0 : pmd_index(addr) - pmd_index(*first); - if (i && i <= MIN_LRU_BATCH) { - __set_bit(i - 1, bitmap); - return; - } - -- pmd = pmd_offset(pud, *start); -+ pmd = pmd_offset(pud, *first); - - ptl = pmd_lockptr(args->mm, pmd); - if (!spin_trylock(ptl)) -@@ -4016,15 +4017,16 @@ static void walk_pmd_range_locked(pud_t - do { - unsigned long pfn; - struct folio *folio; -- unsigned long addr = i ? (*start & PMD_MASK) + i * PMD_SIZE : *start; -+ -+ /* don't round down the first address */ -+ addr = i ? (*first & PMD_MASK) + i * PMD_SIZE : *first; - - pfn = get_pmd_pfn(pmd[i], vma, addr); - if (pfn == -1) - goto next; - - if (!pmd_trans_huge(pmd[i])) { -- if (arch_has_hw_nonleaf_pmd_young() && -- get_cap(LRU_GEN_NONLEAF_YOUNG)) -+ if (arch_has_hw_nonleaf_pmd_young() && get_cap(LRU_GEN_NONLEAF_YOUNG)) - pmdp_test_and_clear_young(vma, addr, pmd + i); - goto next; - } -@@ -4053,12 +4055,11 @@ next: - arch_leave_lazy_mmu_mode(); - spin_unlock(ptl); - done: -- *start = -1; -- bitmap_zero(bitmap, MIN_LRU_BATCH); -+ *first = -1; - } - #else --static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma, -- struct mm_walk *args, unsigned long *bitmap, unsigned long *start) -+static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area_struct *vma, -+ struct mm_walk *args, unsigned long *bitmap, unsigned long *first) - { - } - #endif -@@ -4071,9 +4072,9 @@ static void walk_pmd_range(pud_t *pud, u - unsigned long next; - unsigned long addr; - struct vm_area_struct *vma; -- unsigned long pos = -1; -+ unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)]; -+ unsigned long first = -1; - struct lru_gen_mm_walk *walk = args->private; -- unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {}; - - VM_WARN_ON_ONCE(pud_leaf(*pud)); - -@@ -4115,18 +4116,17 @@ restart: - if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat)) - continue; - -- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); -+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first); - continue; - } - #endif - walk->mm_stats[MM_NONLEAF_TOTAL]++; - -- if (arch_has_hw_nonleaf_pmd_young() && -- get_cap(LRU_GEN_NONLEAF_YOUNG)) { -+ if (arch_has_hw_nonleaf_pmd_young() && get_cap(LRU_GEN_NONLEAF_YOUNG)) { - if (!pmd_young(val)) - continue; - -- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos); -+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first); - } - - if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i)) -@@ -4143,7 +4143,7 @@ restart: - update_bloom_filter(walk->lruvec, walk->max_seq + 1, pmd + i); - } - -- walk_pmd_range_locked(pud, -1, vma, args, bitmap, &pos); -+ walk_pmd_range_locked(pud, -1, vma, args, bitmap, &first); - - if (i < PTRS_PER_PMD && get_next_vma(PUD_MASK, PMD_SIZE, args, &start, &end)) - goto restart; diff --git a/target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch b/target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch deleted file mode 100644 index 856199574a1c43..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.3-18-UPSTREAM-mm-multi-gen-LRU-simplify-lru_gen_look_arou.patch +++ /dev/null @@ -1,148 +0,0 @@ -From e604c3ccb4dfbdde2467fccef9bb36170a392695 Mon Sep 17 00:00:00 2001 -From: "T.J. Alumbaugh" -Date: Wed, 18 Jan 2023 00:18:27 +0000 -Subject: [PATCH 18/19] UPSTREAM: mm: multi-gen LRU: simplify - lru_gen_look_around() - -Update the folio generation in place with or without -current->reclaim_state->mm_walk. The LRU lock is held for longer, if -mm_walk is NULL and the number of folios to update is more than -PAGEVEC_SIZE. - -This causes a measurable regression from the LRU lock contention during a -microbencmark. But a tiny regression is not worth the complexity. - -Link: https://lkml.kernel.org/r/20230118001827.1040870-8-talumbau@google.com -Change-Id: I9ce18b4f4062e6c1c13c98ece9422478eb8e1846 -Signed-off-by: T.J. Alumbaugh -Cc: Yu Zhao -Signed-off-by: Andrew Morton -(cherry picked from commit abf086721a2f1e6897c57796f7268df1b194c750) -Bug: 274865848 -Signed-off-by: T.J. Mercier ---- - mm/vmscan.c | 73 +++++++++++++++++------------------------------------ - 1 file changed, 23 insertions(+), 50 deletions(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -4573,13 +4573,12 @@ static void lru_gen_age_node(struct pgli - void lru_gen_look_around(struct page_vma_mapped_walk *pvmw) - { - int i; -- pte_t *pte; - unsigned long start; - unsigned long end; -- unsigned long addr; - struct lru_gen_mm_walk *walk; - int young = 0; -- unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {}; -+ pte_t *pte = pvmw->pte; -+ unsigned long addr = pvmw->address; - struct folio *folio = pfn_folio(pvmw->pfn); - struct mem_cgroup *memcg = folio_memcg(folio); - struct pglist_data *pgdat = folio_pgdat(folio); -@@ -4596,25 +4595,28 @@ void lru_gen_look_around(struct page_vma - /* avoid taking the LRU lock under the PTL when possible */ - walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL; - -- start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start); -- end = min(pvmw->address | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1; -+ start = max(addr & PMD_MASK, pvmw->vma->vm_start); -+ end = min(addr | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1; - - if (end - start > MIN_LRU_BATCH * PAGE_SIZE) { -- if (pvmw->address - start < MIN_LRU_BATCH * PAGE_SIZE / 2) -+ if (addr - start < MIN_LRU_BATCH * PAGE_SIZE / 2) - end = start + MIN_LRU_BATCH * PAGE_SIZE; -- else if (end - pvmw->address < MIN_LRU_BATCH * PAGE_SIZE / 2) -+ else if (end - addr < MIN_LRU_BATCH * PAGE_SIZE / 2) - start = end - MIN_LRU_BATCH * PAGE_SIZE; - else { -- start = pvmw->address - MIN_LRU_BATCH * PAGE_SIZE / 2; -- end = pvmw->address + MIN_LRU_BATCH * PAGE_SIZE / 2; -+ start = addr - MIN_LRU_BATCH * PAGE_SIZE / 2; -+ end = addr + MIN_LRU_BATCH * PAGE_SIZE / 2; - } - } - -- pte = pvmw->pte - (pvmw->address - start) / PAGE_SIZE; -+ /* folio_update_gen() requires stable folio_memcg() */ -+ if (!mem_cgroup_trylock_pages(memcg)) -+ return; - -- rcu_read_lock(); - arch_enter_lazy_mmu_mode(); - -+ pte -= (addr - start) / PAGE_SIZE; -+ - for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) { - unsigned long pfn; - -@@ -4639,56 +4641,27 @@ void lru_gen_look_around(struct page_vma - !folio_test_swapcache(folio))) - folio_mark_dirty(folio); - -+ if (walk) { -+ old_gen = folio_update_gen(folio, new_gen); -+ if (old_gen >= 0 && old_gen != new_gen) -+ update_batch_size(walk, folio, old_gen, new_gen); -+ -+ continue; -+ } -+ - old_gen = folio_lru_gen(folio); - if (old_gen < 0) - folio_set_referenced(folio); - else if (old_gen != new_gen) -- __set_bit(i, bitmap); -+ folio_activate(folio); - } - - arch_leave_lazy_mmu_mode(); -- rcu_read_unlock(); -+ mem_cgroup_unlock_pages(); - - /* feedback from rmap walkers to page table walkers */ - if (suitable_to_scan(i, young)) - update_bloom_filter(lruvec, max_seq, pvmw->pmd); -- -- if (!walk && bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) { -- for_each_set_bit(i, bitmap, MIN_LRU_BATCH) { -- folio = pfn_folio(pte_pfn(pte[i])); -- folio_activate(folio); -- } -- return; -- } -- -- /* folio_update_gen() requires stable folio_memcg() */ -- if (!mem_cgroup_trylock_pages(memcg)) -- return; -- -- if (!walk) { -- spin_lock_irq(&lruvec->lru_lock); -- new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq); -- } -- -- for_each_set_bit(i, bitmap, MIN_LRU_BATCH) { -- folio = pfn_folio(pte_pfn(pte[i])); -- if (folio_memcg_rcu(folio) != memcg) -- continue; -- -- old_gen = folio_update_gen(folio, new_gen); -- if (old_gen < 0 || old_gen == new_gen) -- continue; -- -- if (walk) -- update_batch_size(walk, folio, old_gen, new_gen); -- else -- lru_gen_update_size(lruvec, folio, old_gen, new_gen); -- } -- -- if (!walk) -- spin_unlock_irq(&lruvec->lru_lock); -- -- mem_cgroup_unlock_pages(); - } - - /****************************************************************************** diff --git a/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch b/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch deleted file mode 100644 index 958d4596865718..00000000000000 --- a/target/linux/generic/backport-6.1/020-v6.4-19-mm-Multi-gen-LRU-remove-wait_event_killable.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 418038c22452df38cde519cc8c662bb15139764a Mon Sep 17 00:00:00 2001 -From: Kalesh Singh -Date: Thu, 13 Apr 2023 14:43:26 -0700 -Subject: [PATCH 19/19] mm: Multi-gen LRU: remove wait_event_killable() - -Android 14 and later default to MGLRU [1] and field telemetry showed -occasional long tail latency (>100ms) in the reclaim path. - -Tracing revealed priority inversion in the reclaim path. In -try_to_inc_max_seq(), when high priority tasks were blocked on -wait_event_killable(), the preemption of the low priority task to call -wake_up_all() caused those high priority tasks to wait longer than -necessary. In general, this problem is not different from others of its -kind, e.g., one caused by mutex_lock(). However, it is specific to MGLRU -because it introduced the new wait queue lruvec->mm_state.wait. - -The purpose of this new wait queue is to avoid the thundering herd -problem. If many direct reclaimers rush into try_to_inc_max_seq(), only -one can succeed, i.e., the one to wake up the rest, and the rest who -failed might cause premature OOM kills if they do not wait. So far there -is no evidence supporting this scenario, based on how often the wait has -been hit. And this begs the question how useful the wait queue is in -practice. - -Based on Minchan's recommendation, which is in line with his commit -6d4675e60135 ("mm: don't be stuck to rmap lock on reclaim path") and the -rest of the MGLRU code which also uses trylock when possible, remove the -wait queue. - -[1] https://android-review.googlesource.com/q/I7ed7fbfd6ef9ce10053347528125dd98c39e50bf - -Link: https://lkml.kernel.org/r/20230413214326.2147568-1-kaleshsingh@google.com -Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks") -Signed-off-by: Kalesh Singh -Suggested-by: Minchan Kim -Reported-by: Wei Wang -Acked-by: Yu Zhao -Cc: Minchan Kim -Cc: Jan Alexander Steffens (heftig) -Cc: Oleksandr Natalenko -Cc: Suleiman Souhlal -Cc: Suren Baghdasaryan -Signed-off-by: Andrew Morton ---- - include/linux/mmzone.h | 8 +-- - mm/vmscan.c | 112 +++++++++++++++-------------------------- - 2 files changed, 42 insertions(+), 78 deletions(-) - ---- a/include/linux/mmzone.h -+++ b/include/linux/mmzone.h -@@ -453,18 +453,14 @@ enum { - struct lru_gen_mm_state { - /* set to max_seq after each iteration */ - unsigned long seq; -- /* where the current iteration continues (inclusive) */ -+ /* where the current iteration continues after */ - struct list_head *head; -- /* where the last iteration ended (exclusive) */ -+ /* where the last iteration ended before */ - struct list_head *tail; -- /* to wait for the last page table walker to finish */ -- struct wait_queue_head wait; - /* Bloom filters flip after each iteration */ - unsigned long *filters[NR_BLOOM_FILTERS]; - /* the mm stats for debugging */ - unsigned long stats[NR_HIST_GENS][NR_MM_STATS]; -- /* the number of concurrent page table walkers */ -- int nr_walkers; - }; - - struct lru_gen_mm_walk { ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3371,18 +3371,13 @@ void lru_gen_del_mm(struct mm_struct *mm - if (!lruvec) - continue; - -- /* where the last iteration ended (exclusive) */ -+ /* where the current iteration continues after */ -+ if (lruvec->mm_state.head == &mm->lru_gen.list) -+ lruvec->mm_state.head = lruvec->mm_state.head->prev; -+ -+ /* where the last iteration ended before */ - if (lruvec->mm_state.tail == &mm->lru_gen.list) - lruvec->mm_state.tail = lruvec->mm_state.tail->next; -- -- /* where the current iteration continues (inclusive) */ -- if (lruvec->mm_state.head != &mm->lru_gen.list) -- continue; -- -- lruvec->mm_state.head = lruvec->mm_state.head->next; -- /* the deletion ends the current iteration */ -- if (lruvec->mm_state.head == &mm_list->fifo) -- WRITE_ONCE(lruvec->mm_state.seq, lruvec->mm_state.seq + 1); - } - - list_del_init(&mm->lru_gen.list); -@@ -3478,68 +3473,54 @@ static bool iterate_mm_list(struct lruve - struct mm_struct **iter) - { - bool first = false; -- bool last = true; -+ bool last = false; - struct mm_struct *mm = NULL; - struct mem_cgroup *memcg = lruvec_memcg(lruvec); - struct lru_gen_mm_list *mm_list = get_mm_list(memcg); - struct lru_gen_mm_state *mm_state = &lruvec->mm_state; - - /* -- * There are four interesting cases for this page table walker: -- * 1. It tries to start a new iteration of mm_list with a stale max_seq; -- * there is nothing left to do. -- * 2. It's the first of the current generation, and it needs to reset -- * the Bloom filter for the next generation. -- * 3. It reaches the end of mm_list, and it needs to increment -- * mm_state->seq; the iteration is done. -- * 4. It's the last of the current generation, and it needs to reset the -- * mm stats counters for the next generation. -+ * mm_state->seq is incremented after each iteration of mm_list. There -+ * are three interesting cases for this page table walker: -+ * 1. It tries to start a new iteration with a stale max_seq: there is -+ * nothing left to do. -+ * 2. It started the next iteration: it needs to reset the Bloom filter -+ * so that a fresh set of PTE tables can be recorded. -+ * 3. It ended the current iteration: it needs to reset the mm stats -+ * counters and tell its caller to increment max_seq. - */ - spin_lock(&mm_list->lock); - - VM_WARN_ON_ONCE(mm_state->seq + 1 < walk->max_seq); -- VM_WARN_ON_ONCE(*iter && mm_state->seq > walk->max_seq); -- VM_WARN_ON_ONCE(*iter && !mm_state->nr_walkers); - -- if (walk->max_seq <= mm_state->seq) { -- if (!*iter) -- last = false; -+ if (walk->max_seq <= mm_state->seq) - goto done; -- } - -- if (!mm_state->nr_walkers) { -- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo); -+ if (!mm_state->head) -+ mm_state->head = &mm_list->fifo; - -- mm_state->head = mm_list->fifo.next; -+ if (mm_state->head == &mm_list->fifo) - first = true; -- } -- -- while (!mm && mm_state->head != &mm_list->fifo) { -- mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list); - -+ do { - mm_state->head = mm_state->head->next; -+ if (mm_state->head == &mm_list->fifo) { -+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1); -+ last = true; -+ break; -+ } - - /* force scan for those added after the last iteration */ -- if (!mm_state->tail || mm_state->tail == &mm->lru_gen.list) { -- mm_state->tail = mm_state->head; -+ if (!mm_state->tail || mm_state->tail == mm_state->head) { -+ mm_state->tail = mm_state->head->next; - walk->force_scan = true; - } - -+ mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list); - if (should_skip_mm(mm, walk)) - mm = NULL; -- } -- -- if (mm_state->head == &mm_list->fifo) -- WRITE_ONCE(mm_state->seq, mm_state->seq + 1); -+ } while (!mm); - done: -- if (*iter && !mm) -- mm_state->nr_walkers--; -- if (!*iter && mm) -- mm_state->nr_walkers++; -- -- if (mm_state->nr_walkers) -- last = false; -- - if (*iter || last) - reset_mm_stats(lruvec, walk, last); - -@@ -3567,9 +3548,9 @@ static bool iterate_mm_list_nowalk(struc - - VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq); - -- if (max_seq > mm_state->seq && !mm_state->nr_walkers) { -- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo); -- -+ if (max_seq > mm_state->seq) { -+ mm_state->head = NULL; -+ mm_state->tail = NULL; - WRITE_ONCE(mm_state->seq, mm_state->seq + 1); - reset_mm_stats(lruvec, NULL, true); - success = true; -@@ -4172,10 +4153,6 @@ restart: - - walk_pmd_range(&val, addr, next, args); - -- /* a racy check to curtail the waiting time */ -- if (wq_has_sleeper(&walk->lruvec->mm_state.wait)) -- return 1; -- - if (need_resched() || walk->batched >= MAX_LRU_BATCH) { - end = (addr | ~PUD_MASK) + 1; - goto done; -@@ -4208,8 +4185,14 @@ static void walk_mm(struct lruvec *lruve - walk->next_addr = FIRST_USER_ADDRESS; - - do { -+ DEFINE_MAX_SEQ(lruvec); -+ - err = -EBUSY; - -+ /* another thread might have called inc_max_seq() */ -+ if (walk->max_seq != max_seq) -+ break; -+ - /* folio_update_gen() requires stable folio_memcg() */ - if (!mem_cgroup_trylock_pages(memcg)) - break; -@@ -4444,25 +4427,12 @@ static bool try_to_inc_max_seq(struct lr - success = iterate_mm_list(lruvec, walk, &mm); - if (mm) - walk_mm(lruvec, mm, walk); -- -- cond_resched(); - } while (mm); - done: -- if (!success) { -- if (sc->priority <= DEF_PRIORITY - 2) -- wait_event_killable(lruvec->mm_state.wait, -- max_seq < READ_ONCE(lrugen->max_seq)); -- return false; -- } -+ if (success) -+ inc_max_seq(lruvec, can_swap, force_scan); - -- VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq)); -- -- inc_max_seq(lruvec, can_swap, force_scan); -- /* either this sees any waiters or they will see updated max_seq */ -- if (wq_has_sleeper(&lruvec->mm_state.wait)) -- wake_up_all(&lruvec->mm_state.wait); -- -- return true; -+ return success; - } - - /****************************************************************************** -@@ -6116,7 +6086,6 @@ void lru_gen_init_lruvec(struct lruvec * - INIT_LIST_HEAD(&lrugen->folios[gen][type][zone]); - - lruvec->mm_state.seq = MIN_NR_GENS; -- init_waitqueue_head(&lruvec->mm_state.wait); - } - - #ifdef CONFIG_MEMCG -@@ -6149,7 +6118,6 @@ void lru_gen_exit_memcg(struct mem_cgrou - for_each_node(nid) { - struct lruvec *lruvec = get_lruvec(memcg, nid); - -- VM_WARN_ON_ONCE(lruvec->mm_state.nr_walkers); - VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0, - sizeof(lruvec->lrugen.nr_pages))); - diff --git a/target/linux/generic/backport-6.1/200-v6.3-bitfield-add-FIELD_PREP_CONST.patch b/target/linux/generic/backport-6.1/200-v6.3-bitfield-add-FIELD_PREP_CONST.patch deleted file mode 100644 index 2e6d881fe9f15a..00000000000000 --- a/target/linux/generic/backport-6.1/200-v6.3-bitfield-add-FIELD_PREP_CONST.patch +++ /dev/null @@ -1,58 +0,0 @@ -From e2192de59e457aef8d1f055a452131f0b3e5d097 Mon Sep 17 00:00:00 2001 -From: Johannes Berg -Date: Wed, 18 Jan 2023 14:26:53 +0100 -Subject: [PATCH] bitfield: add FIELD_PREP_CONST() - -Neither FIELD_PREP() nor *_encode_bits() can be used -in constant contexts (such as initializers), but we -don't want to define shift constants for all masks -just for use in initializers, and having checks that -the values fit is also useful. - -Therefore, add FIELD_PREP_CONST() which is a smaller -version of FIELD_PREP() that can only take constant -arguments and has less friendly (but not less strict) -error checks, and expands to a constant value. - -Signed-off-by: Johannes Berg -Link: https://lore.kernel.org/r/20230118142652.53f20593504b.Iaeea0aee77a6493d70e573b4aa55c91c00e01e4b@changeid -Signed-off-by: Johannes Berg ---- - include/linux/bitfield.h | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - ---- a/include/linux/bitfield.h -+++ b/include/linux/bitfield.h -@@ -115,6 +115,32 @@ - ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ - }) - -+#define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0) -+ -+/** -+ * FIELD_PREP_CONST() - prepare a constant bitfield element -+ * @_mask: shifted mask defining the field's length and position -+ * @_val: value to put in the field -+ * -+ * FIELD_PREP_CONST() masks and shifts up the value. The result should -+ * be combined with other fields of the bitfield using logical OR. -+ * -+ * Unlike FIELD_PREP() this is a constant expression and can therefore -+ * be used in initializers. Error checking is less comfortable for this -+ * version, and non-constant masks cannot be used. -+ */ -+#define FIELD_PREP_CONST(_mask, _val) \ -+ ( \ -+ /* mask must be non-zero */ \ -+ BUILD_BUG_ON_ZERO((_mask) == 0) + \ -+ /* check if value fits */ \ -+ BUILD_BUG_ON_ZERO(~((_mask) >> __bf_shf(_mask)) & (_val)) + \ -+ /* check if mask is contiguous */ \ -+ __BF_CHECK_POW2((_mask) + (1ULL << __bf_shf(_mask))) + \ -+ /* and create the value */ \ -+ (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) \ -+ ) -+ - /** - * FIELD_GET() - extract a bitfield element - * @_mask: shifted mask defining the field's length and position diff --git a/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch b/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch deleted file mode 100644 index d8d0cf95557875..00000000000000 --- a/target/linux/generic/backport-6.1/300-v6.2-powerpc-suppress-some-linker-warnings-in-recent-link.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 579aee9fc594af94c242068c011b0233563d4bbf Mon Sep 17 00:00:00 2001 -From: Stephen Rothwell -Date: Mon, 10 Oct 2022 16:57:21 +1100 -Subject: [PATCH] powerpc: suppress some linker warnings in recent linker - versions - -This is a follow on from commit - - 0d362be5b142 ("Makefile: link with -z noexecstack --no-warn-rwx-segments") - -for arch/powerpc/boot to address wanrings like: - - ld: warning: opal-calls.o: missing .note.GNU-stack section implies executable stack - ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker - ld: warning: arch/powerpc/boot/zImage.epapr has a LOAD segment with RWX permissions - -This fixes issue https://github.com/linuxppc/issues/issues/417 - -Signed-off-by: Stephen Rothwell -Signed-off-by: Michael Ellerman -Link: https://lore.kernel.org/r/20221010165721.106267e6@canb.auug.org.au ---- - arch/powerpc/boot/wrapper | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - ---- a/arch/powerpc/boot/wrapper -+++ b/arch/powerpc/boot/wrapper -@@ -215,6 +215,11 @@ ld_version() - }' - } - -+ld_is_lld() -+{ -+ ${CROSS}ld -V 2>&1 | grep -q LLD -+} -+ - # Do not include PT_INTERP segment when linking pie. Non-pie linking - # just ignores this option. - LD_VERSION=$(${CROSS}ld --version | ld_version) -@@ -223,6 +228,14 @@ if [ "$LD_VERSION" -ge "$LD_NO_DL_MIN_VE - nodl="--no-dynamic-linker" - fi - -+# suppress some warnings in recent ld versions -+nowarn="-z noexecstack" -+if ! ld_is_lld; then -+ if [ "$LD_VERSION" -ge "$(echo 2.39 | ld_version)" ]; then -+ nowarn="$nowarn --no-warn-rwx-segments" -+ fi -+fi -+ - platformo=$object/"$platform".o - lds=$object/zImage.lds - ext=strip -@@ -504,7 +517,7 @@ if [ "$platform" != "miboot" ]; then - text_start="-Ttext $link_address" - fi - #link everything -- ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $rodynamic $notext -o "$ofile" $map \ -+ ${CROSS}ld -m $format -T $lds $text_start $pie $nodl $nowarn $rodynamic $notext -o "$ofile" $map \ - $platformo $tmp $object/wrapper.a - rm $tmp - fi diff --git a/target/linux/generic/backport-6.1/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch b/target/linux/generic/backport-6.1/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch deleted file mode 100644 index 239adff1af7d4d..00000000000000 --- a/target/linux/generic/backport-6.1/301-v6.9-kernel.h-removed-REPEAT_BYTE-from-kernel.h.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 66a5c40f60f5d88ad8d47ba6a4ba05892853fa1f Mon Sep 17 00:00:00 2001 -From: Tanzir Hasan -Date: Tue, 26 Dec 2023 18:00:00 +0000 -Subject: [PATCH] kernel.h: removed REPEAT_BYTE from kernel.h - -This patch creates wordpart.h and includes it in asm/word-at-a-time.h -for all architectures. WORD_AT_A_TIME_CONSTANTS depends on kernel.h -because of REPEAT_BYTE. Moving this to another header and including it -where necessary allows us to not include the bloated kernel.h. Making -this implicit dependency on REPEAT_BYTE explicit allows for later -improvements in the lib/string.c inclusion list. - -Suggested-by: Al Viro -Suggested-by: Andy Shevchenko -Signed-off-by: Tanzir Hasan -Reviewed-by: Andy Shevchenko -Link: https://lore.kernel.org/r/20231226-libstringheader-v6-1-80aa08c7652c@google.com -Signed-off-by: Kees Cook ---- - arch/arm/include/asm/word-at-a-time.h | 3 ++- - arch/arm64/include/asm/word-at-a-time.h | 3 ++- - arch/powerpc/include/asm/word-at-a-time.h | 4 ++-- - arch/riscv/include/asm/word-at-a-time.h | 3 ++- - arch/s390/include/asm/word-at-a-time.h | 3 ++- - arch/sh/include/asm/word-at-a-time.h | 2 ++ - arch/x86/include/asm/word-at-a-time.h | 3 ++- - arch/x86/kvm/mmu/mmu.c | 1 + - fs/namei.c | 2 +- - include/asm-generic/word-at-a-time.h | 3 ++- - include/linux/kernel.h | 8 -------- - include/linux/wordpart.h | 13 +++++++++++++ - 12 files changed, 31 insertions(+), 17 deletions(-) - create mode 100644 include/linux/wordpart.h - ---- a/arch/arm/include/asm/word-at-a-time.h -+++ b/arch/arm/include/asm/word-at-a-time.h -@@ -8,7 +8,8 @@ - * Little-endian word-at-a-time zero byte handling. - * Heavily based on the x86 algorithm. - */ --#include -+#include -+#include - - struct word_at_a_time { - const unsigned long one_bits, high_bits; ---- a/arch/arm64/include/asm/word-at-a-time.h -+++ b/arch/arm64/include/asm/word-at-a-time.h -@@ -9,7 +9,8 @@ - - #ifndef __AARCH64EB__ - --#include -+#include -+#include - - struct word_at_a_time { - const unsigned long one_bits, high_bits; ---- a/arch/powerpc/include/asm/word-at-a-time.h -+++ b/arch/powerpc/include/asm/word-at-a-time.h -@@ -4,8 +4,8 @@ - /* - * Word-at-a-time interfaces for PowerPC. - */ -- --#include -+#include -+#include - #include - #include - ---- a/arch/sh/include/asm/word-at-a-time.h -+++ b/arch/sh/include/asm/word-at-a-time.h -@@ -5,6 +5,8 @@ - #ifdef CONFIG_CPU_BIG_ENDIAN - # include - #else -+#include -+#include - /* - * Little-endian version cribbed from x86. - */ ---- a/arch/x86/include/asm/word-at-a-time.h -+++ b/arch/x86/include/asm/word-at-a-time.h -@@ -2,7 +2,8 @@ - #ifndef _ASM_WORD_AT_A_TIME_H - #define _ASM_WORD_AT_A_TIME_H - --#include -+#include -+#include - - /* - * This is largely generic for little-endian machines, but the ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -44,6 +44,7 @@ - #include - #include - #include -+#include - - #include - #include ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -17,8 +17,8 @@ - - #include - #include --#include - #include -+#include - #include - #include - #include ---- a/include/asm-generic/word-at-a-time.h -+++ b/include/asm-generic/word-at-a-time.h -@@ -2,7 +2,8 @@ - #ifndef _ASM_WORD_AT_A_TIME_H - #define _ASM_WORD_AT_A_TIME_H - --#include -+#include -+#include - #include - - #ifdef __BIG_ENDIAN ---- a/include/linux/kernel.h -+++ b/include/linux/kernel.h -@@ -36,14 +36,6 @@ - - #define STACK_MAGIC 0xdeadbeef - --/** -- * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value -- * @x: value to repeat -- * -- * NOTE: @x is not checked for > 0xff; larger values produce odd results. -- */ --#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) -- - /* generic data direction definitions */ - #define READ 0 - #define WRITE 1 ---- /dev/null -+++ b/include/linux/wordpart.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+#ifndef _LINUX_WORDPART_H -+#define _LINUX_WORDPART_H -+/** -+ * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value -+ * @x: value to repeat -+ * -+ * NOTE: @x is not checked for > 0xff; larger values produce odd results. -+ */ -+#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) -+ -+#endif // _LINUX_WORDPART_H diff --git a/target/linux/generic/backport-6.1/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch b/target/linux/generic/backport-6.1/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch deleted file mode 100644 index 9bbd515852d597..00000000000000 --- a/target/linux/generic/backport-6.1/302-v6.9-kernel.h-Move-upper_-_bits-and-lower_-_bits-to-wordp.patch +++ /dev/null @@ -1,107 +0,0 @@ -From adeb04362d74188c1e22ccb824b15a0a7b3de2f4 Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Wed, 14 Feb 2024 19:26:32 +0200 -Subject: [PATCH] kernel.h: Move upper_*_bits() and lower_*_bits() to - wordpart.h - -The wordpart.h header is collecting APIs related to the handling -parts of the word (usually in byte granularity). The upper_*_bits() -and lower_*_bits() are good candidates to be moved to there. - -This helps to clean up header dependency hell with regard to kernel.h -as the latter gathers completely unrelated stuff together and slows -down compilation (especially when it's included into other header). - -Signed-off-by: Andy Shevchenko -Link: https://lore.kernel.org/r/20240214172752.3605073-1-andriy.shevchenko@linux.intel.com -Reviewed-by: Randy Dunlap -Signed-off-by: Kees Cook ---- - include/linux/kernel.h | 30 ++---------------------------- - include/linux/wordpart.h | 29 +++++++++++++++++++++++++++++ - 2 files changed, 31 insertions(+), 28 deletions(-) - ---- a/include/linux/kernel.h -+++ b/include/linux/kernel.h -@@ -30,6 +30,8 @@ - #include - #include - #include -+#include -+ - #include - - #include -@@ -55,34 +57,6 @@ - } \ - ) - --/** -- * upper_32_bits - return bits 32-63 of a number -- * @n: the number we're accessing -- * -- * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress -- * the "right shift count >= width of type" warning when that quantity is -- * 32-bits. -- */ --#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16)) -- --/** -- * lower_32_bits - return bits 0-31 of a number -- * @n: the number we're accessing -- */ --#define lower_32_bits(n) ((u32)((n) & 0xffffffff)) -- --/** -- * upper_16_bits - return bits 16-31 of a number -- * @n: the number we're accessing -- */ --#define upper_16_bits(n) ((u16)((n) >> 16)) -- --/** -- * lower_16_bits - return bits 0-15 of a number -- * @n: the number we're accessing -- */ --#define lower_16_bits(n) ((u16)((n) & 0xffff)) -- - struct completion; - struct user; - ---- a/include/linux/wordpart.h -+++ b/include/linux/wordpart.h -@@ -2,6 +2,35 @@ - - #ifndef _LINUX_WORDPART_H - #define _LINUX_WORDPART_H -+ -+/** -+ * upper_32_bits - return bits 32-63 of a number -+ * @n: the number we're accessing -+ * -+ * A basic shift-right of a 64- or 32-bit quantity. Use this to suppress -+ * the "right shift count >= width of type" warning when that quantity is -+ * 32-bits. -+ */ -+#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16)) -+ -+/** -+ * lower_32_bits - return bits 0-31 of a number -+ * @n: the number we're accessing -+ */ -+#define lower_32_bits(n) ((u32)((n) & 0xffffffff)) -+ -+/** -+ * upper_16_bits - return bits 16-31 of a number -+ * @n: the number we're accessing -+ */ -+#define upper_16_bits(n) ((u16)((n) >> 16)) -+ -+/** -+ * lower_16_bits - return bits 0-15 of a number -+ * @n: the number we're accessing -+ */ -+#define lower_16_bits(n) ((u16)((n) & 0xffff)) -+ - /** - * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value - * @x: value to repeat diff --git a/target/linux/generic/backport-6.1/400-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch b/target/linux/generic/backport-6.1/400-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch deleted file mode 100644 index ba01bac8d2fa1c..00000000000000 --- a/target/linux/generic/backport-6.1/400-v6.9-mtd-rawnand-brcmnand-Support-write-protection-settin.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 8e7daa85641c9559c113f6b217bdc923397de77c Mon Sep 17 00:00:00 2001 -From: William Zhang -Date: Thu, 22 Feb 2024 19:47:58 -0800 -Subject: [PATCH] mtd: rawnand: brcmnand: Support write protection setting from - dts - -The write protection feature is controlled by the module parameter wp_on -with default set to enabled. But not all the board use this feature -especially in BCMBCA broadband board. And module parameter is not -sufficient as different board can have different option. Add a device -tree property and allow this feature to be configured through the board -dts on per board basis. - -Signed-off-by: William Zhang -Reviewed-by: Florian Fainelli -Reviewed-by: Kamal Dasu -Reviewed-by: David Regan -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20240223034758.13753-14-william.zhang@broadcom.com ---- - drivers/mtd/nand/raw/brcmnand/brcmnand.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c -+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c -@@ -3188,6 +3188,10 @@ int brcmnand_probe(struct platform_devic - /* Disable XOR addressing */ - brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0); - -+ /* Check if the board connects the WP pin */ -+ if (of_property_read_bool(dn, "brcm,wp-not-connected")) -+ wp_on = 0; -+ - if (ctrl->features & BRCMNAND_HAS_WP) { - /* Permanently disable write protection */ - if (wp_on == 2) diff --git a/target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch b/target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch deleted file mode 100644 index eb6be5ed00e2f0..00000000000000 --- a/target/linux/generic/backport-6.1/406-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 63db0cb35e1cb3b3c134906d1062f65513fdda2d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 4 Oct 2022 10:37:09 +0200 -Subject: [PATCH] mtd: core: simplify (a bit) code find partition-matching - dynamic OF node -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -1. Don't hardcode "partition-" string twice -2. Use simpler logic & use ->name to avoid of_property_read_string() -3. Use mtd_get_of_node() helper - -Cc: Christian Marangi -Signed-off-by: Rafał Miłecki -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-1-zajec5@gmail.com ---- - drivers/mtd/mtdcore.c | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -551,18 +551,16 @@ static void mtd_check_of_node(struct mtd - struct device_node *partitions, *parent_dn, *mtd_dn = NULL; - const char *pname, *prefix = "partition-"; - int plen, mtd_name_len, offset, prefix_len; -- struct mtd_info *parent; - bool found = false; - - /* Check if MTD already has a device node */ -- if (dev_of_node(&mtd->dev)) -+ if (mtd_get_of_node(mtd)) - return; - - /* Check if a partitions node exist */ - if (!mtd_is_partition(mtd)) - return; -- parent = mtd->parent; -- parent_dn = of_node_get(dev_of_node(&parent->dev)); -+ parent_dn = of_node_get(mtd_get_of_node(mtd->parent)); - if (!parent_dn) - return; - -@@ -575,15 +573,15 @@ static void mtd_check_of_node(struct mtd - - /* Search if a partition is defined with the same name */ - for_each_child_of_node(partitions, mtd_dn) { -- offset = 0; -- - /* Skip partition with no/wrong prefix */ -- if (!of_node_name_prefix(mtd_dn, "partition-")) -+ if (!of_node_name_prefix(mtd_dn, prefix)) - continue; - - /* Label have priority. Check that first */ -- if (of_property_read_string(mtd_dn, "label", &pname)) { -- of_property_read_string(mtd_dn, "name", &pname); -+ if (!of_property_read_string(mtd_dn, "label", &pname)) { -+ offset = 0; -+ } else { -+ pname = mtd_dn->name; - offset = prefix_len; - } - diff --git a/target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch b/target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch deleted file mode 100644 index f8d3a370d448f3..00000000000000 --- a/target/linux/generic/backport-6.1/406-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch +++ /dev/null @@ -1,84 +0,0 @@ -From ddb8cefb7af288950447ca6eeeafb09977dab56f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 4 Oct 2022 10:37:10 +0200 -Subject: [PATCH] mtd: core: try to find OF node for every MTD partition -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -So far this feature was limited to the top-level "nvmem-cells" node. -There are multiple parsers creating partitions and subpartitions -dynamically. Extend that code to handle them too. - -This allows finding partition-* node for every MTD (sub)partition. - -Random example: - -partitions { - compatible = "brcm,bcm947xx-cfe-partitions"; - - partition-firmware { - compatible = "brcm,trx"; - - partition-loader { - }; - }; -}; - -Cc: Christian Marangi -Signed-off-by: Rafał Miłecki -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221004083710.27704-2-zajec5@gmail.com ---- - drivers/mtd/mtdcore.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -551,20 +551,22 @@ static void mtd_check_of_node(struct mtd - struct device_node *partitions, *parent_dn, *mtd_dn = NULL; - const char *pname, *prefix = "partition-"; - int plen, mtd_name_len, offset, prefix_len; -- bool found = false; - - /* Check if MTD already has a device node */ - if (mtd_get_of_node(mtd)) - return; - -- /* Check if a partitions node exist */ - if (!mtd_is_partition(mtd)) - return; -+ - parent_dn = of_node_get(mtd_get_of_node(mtd->parent)); - if (!parent_dn) - return; - -- partitions = of_get_child_by_name(parent_dn, "partitions"); -+ if (mtd_is_partition(mtd->parent)) -+ partitions = of_node_get(parent_dn); -+ else -+ partitions = of_get_child_by_name(parent_dn, "partitions"); - if (!partitions) - goto exit_parent; - -@@ -588,19 +590,11 @@ static void mtd_check_of_node(struct mtd - plen = strlen(pname) - offset; - if (plen == mtd_name_len && - !strncmp(mtd->name, pname + offset, plen)) { -- found = true; -+ mtd_set_of_node(mtd, mtd_dn); - break; - } - } - -- if (!found) -- goto exit_partitions; -- -- /* Set of_node only for nvmem */ -- if (of_device_is_compatible(mtd_dn, "nvmem-cells")) -- mtd_set_of_node(mtd, mtd_dn); -- --exit_partitions: - of_node_put(partitions); - exit_parent: - of_node_put(parent_dn); diff --git a/target/linux/generic/backport-6.1/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch b/target/linux/generic/backport-6.1/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch deleted file mode 100644 index 5a5e11c8f7adb9..00000000000000 --- a/target/linux/generic/backport-6.1/408-v6.2-mtd-core-set-ROOT_DEV-for-partitions-marked-as-rootf.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 26422ac78e9d8767bd4aabfbae616b15edbf6a1b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 22 Oct 2022 23:13:18 +0200 -Subject: [PATCH] mtd: core: set ROOT_DEV for partitions marked as rootfs in DT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This adds support for "linux,rootfs" binding that is used to mark flash -partition containing rootfs. It's useful for devices using device tree -that don't have bootloader passing root info in cmdline. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221022211318.32009-2-zajec5@gmail.com ---- - drivers/mtd/mtdcore.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -737,6 +738,17 @@ int add_mtd_device(struct mtd_info *mtd) - not->add(mtd); - - mutex_unlock(&mtd_table_mutex); -+ -+ if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) { -+ if (IS_BUILTIN(CONFIG_MTD)) { -+ pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name); -+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); -+ } else { -+ pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n", -+ mtd->index, mtd->name); -+ } -+ } -+ - /* We _know_ we aren't being removed, because - our caller is still holding us here. So none - of this try_ nonsense, and no bitching about it diff --git a/target/linux/generic/backport-6.1/410-v6.2-mtd-spi-nor-add-generic-flash-driver.patch b/target/linux/generic/backport-6.1/410-v6.2-mtd-spi-nor-add-generic-flash-driver.patch deleted file mode 100644 index 4978dcedbf6eea..00000000000000 --- a/target/linux/generic/backport-6.1/410-v6.2-mtd-spi-nor-add-generic-flash-driver.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 773bbe10449731c9525457873e0c2342e5cf883b Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Thu, 11 Aug 2022 00:06:53 +0200 -Subject: [PATCH] mtd: spi-nor: add generic flash driver - -Our SFDP parsing is everything we need to support all basic operations -of a flash device. If the flash isn't found in our in-kernel flash -database, gracefully fall back to a driver described solely by its SFDP -tables. - -Signed-off-by: Michael Walle -Signed-off-by: Tudor Ambarus -Tested-by: Tudor Ambarus -Reviewed-by: Takahiro Kuwano -Link: https://lore.kernel.org/r/20220810220654.1297699-7-michael@walle.cc ---- - drivers/mtd/spi-nor/core.c | 26 ++++++++++++++++++++++++-- - drivers/mtd/spi-nor/core.h | 1 + - drivers/mtd/spi-nor/sfdp.c | 27 +++++++++++++++++++++++++++ - 3 files changed, 52 insertions(+), 2 deletions(-) - ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -1636,6 +1636,16 @@ static const struct spi_nor_manufacturer - &spi_nor_xmc, - }; - -+static const struct flash_info spi_nor_generic_flash = { -+ .name = "spi-nor-generic", -+ /* -+ * JESD216 rev A doesn't specify the page size, therefore we need a -+ * sane default. -+ */ -+ .page_size = 256, -+ .parse_sfdp = true, -+}; -+ - static const struct flash_info *spi_nor_match_id(struct spi_nor *nor, - const u8 *id) - { -@@ -1669,6 +1679,14 @@ static const struct flash_info *spi_nor_ - } - - info = spi_nor_match_id(nor, id); -+ -+ /* Fallback to a generic flash described only by its SFDP data. */ -+ if (!info) { -+ ret = spi_nor_check_sfdp_signature(nor); -+ if (!ret) -+ info = &spi_nor_generic_flash; -+ } -+ - if (!info) { - dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n", - SPI_NOR_MAX_ID_LEN, id); -@@ -2105,8 +2123,12 @@ static int spi_nor_select_pp(struct spi_ - * spi_nor_select_uniform_erase() - select optimum uniform erase type - * @map: the erase map of the SPI NOR - * @wanted_size: the erase type size to search for. Contains the value of -- * info->sector_size or of the "small sector" size in case -- * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined. -+ * info->sector_size, the "small sector" size in case -+ * CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is defined or 0 if -+ * there is no information about the sector size. The -+ * latter is the case if the flash parameters are parsed -+ * solely by SFDP, then the largest supported erase type -+ * is selected. - * - * Once the optimum uniform sector erase command is found, disable all the - * other. ---- a/drivers/mtd/spi-nor/core.h -+++ b/drivers/mtd/spi-nor/core.h -@@ -708,6 +708,8 @@ int spi_nor_controller_ops_read_reg(stru - int spi_nor_controller_ops_write_reg(struct spi_nor *nor, u8 opcode, - const u8 *buf, size_t len); - -+int spi_nor_check_sfdp_signature(struct spi_nor *nor); -+ - static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) - { - return container_of(mtd, struct spi_nor, mtd); ---- a/drivers/mtd/spi-nor/sfdp.c -+++ b/drivers/mtd/spi-nor/sfdp.c -@@ -1250,6 +1250,33 @@ static void spi_nor_post_sfdp_fixups(str - } - - /** -+ * spi_nor_check_sfdp_signature() - check for a valid SFDP signature -+ * @nor: pointer to a 'struct spi_nor' -+ * -+ * Used to detect if the flash supports the RDSFDP command as well as the -+ * presence of a valid SFDP table. -+ * -+ * Return: 0 on success, -errno otherwise. -+ */ -+int spi_nor_check_sfdp_signature(struct spi_nor *nor) -+{ -+ u32 signature; -+ int err; -+ -+ /* Get the SFDP header. */ -+ err = spi_nor_read_sfdp_dma_unsafe(nor, 0, sizeof(signature), -+ &signature); -+ if (err < 0) -+ return err; -+ -+ /* Check the SFDP signature. */ -+ if (le32_to_cpu(signature) != SFDP_SIGNATURE) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+/** - * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters. - * @nor: pointer to a 'struct spi_nor' - * diff --git a/target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch b/target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch deleted file mode 100644 index 1f8501dc1c26f1..00000000000000 --- a/target/linux/generic/backport-6.1/412-v6.3-02-spidev-Add-Silicon-Labs-SI3210-device-compatible.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 6c9d1fd52956c3148e847a214bae9102b1811de5 Mon Sep 17 00:00:00 2001 -From: Vincent Tremblay -Date: Tue, 27 Dec 2022 09:10:08 -0500 -Subject: [PATCH] spidev: Add Silicon Labs SI3210 device compatible - -Add compatible string for Silicon Labs SI3210 device. - -Signed-off-by: Vincent Tremblay -Link: https://lore.kernel.org/r/20221227141011.111410-2-vincent@vtremblay.dev -Signed-off-by: Mark Brown ---- - drivers/spi/spidev.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/spi/spidev.c -+++ b/drivers/spi/spidev.c -@@ -702,6 +702,7 @@ static const struct spi_device_id spidev - { .name = "spi-petra" }, - { .name = "spi-authenta" }, - { .name = "em3581" }, -+ { .name = "si3210" }, - {}, - }; - MODULE_DEVICE_TABLE(spi, spidev_spi_ids); -@@ -730,6 +731,7 @@ static const struct of_device_id spidev_ - { .compatible = "rohm,dh2228fv", .data = &spidev_of_check }, - { .compatible = "semtech,sx1301", .data = &spidev_of_check }, - { .compatible = "silabs,em3581", .data = &spidev_of_check }, -+ { .compatible = "silabs,si3210", .data = &spidev_of_check }, - {}, - }; - MODULE_DEVICE_TABLE(of, spidev_dt_ids); diff --git a/target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch b/target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch deleted file mode 100644 index e570564a0bc5bb..00000000000000 --- a/target/linux/generic/backport-6.1/421-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch +++ /dev/null @@ -1,229 +0,0 @@ -From aec4d5f5ffd0f0092bd9dc21ea90e0bc237d4b74 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sat, 15 Oct 2022 11:29:50 +0200 -Subject: [PATCH] mtd: parsers: add TP-Link SafeLoader partitions table parser -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This parser deals with most TP-Link home routers. It reads info about -partitions and registers them in the MTD subsystem. - -Example from TP-Link Archer C5 V2: - -spi-nor spi0.0: s25fl128s1 (16384 Kbytes) -15 tplink-safeloader partitions found on MTD device spi0.0 -Creating 15 MTD partitions on "spi0.0": -0x000000000000-0x000000040000 : "fs-uboot" -0x000000040000-0x000000440000 : "os-image" -0x000000440000-0x000000e40000 : "rootfs" -0x000000e40000-0x000000e40200 : "default-mac" -0x000000e40200-0x000000e40400 : "pin" -0x000000e40400-0x000000e40600 : "product-info" -0x000000e50000-0x000000e60000 : "partition-table" -0x000000e60000-0x000000e60200 : "soft-version" -0x000000e61000-0x000000e70000 : "support-list" -0x000000e70000-0x000000e80000 : "profile" -0x000000e80000-0x000000e90000 : "default-config" -0x000000e90000-0x000000ee0000 : "user-config" -0x000000ee0000-0x000000fe0000 : "log" -0x000000fe0000-0x000000ff0000 : "radio_bk" -0x000000ff0000-0x000001000000 : "radio" - -Signed-off-by: Rafał Miłecki -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221015092950.27467-2-zajec5@gmail.com ---- - drivers/mtd/parsers/Kconfig | 15 +++ - drivers/mtd/parsers/Makefile | 1 + - drivers/mtd/parsers/tplink_safeloader.c | 150 ++++++++++++++++++++++++ - 3 files changed, 166 insertions(+) - create mode 100644 drivers/mtd/parsers/tplink_safeloader.c - ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -123,6 +123,21 @@ config MTD_AFS_PARTS - for your particular device. It won't happen automatically. The - 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. - -+config MTD_PARSER_TPLINK_SAFELOADER -+ tristate "TP-Link Safeloader partitions parser" -+ depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST) -+ help -+ TP-Link home routers use flash partitions to store various data. Info -+ about flash space layout is stored in a partitions table using a -+ custom ASCII-based format. -+ -+ That format was first found in devices with SafeLoader bootloader and -+ was named after it. Later it was adapted to CFE and U-Boot -+ bootloaders. -+ -+ This driver reads partitions table, parses it and creates MTD -+ partitions. -+ - config MTD_PARSER_TRX - tristate "Parser for TRX format partitions" - depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST) ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -10,6 +10,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += - ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o - obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o - obj-$(CONFIG_MTD_AFS_PARTS) += afs.o -+obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o - obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o - obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o - obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o ---- /dev/null -+++ b/drivers/mtd/parsers/tplink_safeloader.c -@@ -0,0 +1,150 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright © 2022 Rafał Miłecki -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define TPLINK_SAFELOADER_DATA_OFFSET 4 -+#define TPLINK_SAFELOADER_MAX_PARTS 32 -+ -+struct safeloader_cmn_header { -+ __be32 size; -+ uint32_t unused; -+} __packed; -+ -+static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd) -+{ -+ struct safeloader_cmn_header hdr; -+ struct device_node *np; -+ size_t bytes_read; -+ size_t offset; -+ size_t size; -+ char *buf; -+ int err; -+ -+ np = mtd_get_of_node(mtd); -+ if (mtd_is_partition(mtd)) -+ of_node_get(np); -+ else -+ np = of_get_child_by_name(np, "partitions"); -+ -+ if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) { -+ pr_err("Failed to get partitions table offset\n"); -+ goto err_put; -+ } -+ -+ err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr); -+ if (err && !mtd_is_bitflip(err)) { -+ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset); -+ goto err_put; -+ } -+ -+ size = be32_to_cpu(hdr.size); -+ -+ buf = kmalloc(size + 1, GFP_KERNEL); -+ if (!buf) -+ goto err_put; -+ -+ err = mtd_read(mtd, offset + sizeof(hdr), size, &bytes_read, buf); -+ if (err && !mtd_is_bitflip(err)) { -+ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset + sizeof(hdr)); -+ goto err_kfree; -+ } -+ -+ buf[size] = '\0'; -+ -+ of_node_put(np); -+ -+ return buf; -+ -+err_kfree: -+ kfree(buf); -+err_put: -+ of_node_put(np); -+ return NULL; -+} -+ -+static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_partition *parts; -+ char name[65]; -+ size_t offset; -+ size_t bytes; -+ char *buf; -+ int idx; -+ int err; -+ -+ parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL); -+ if (!parts) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ buf = mtd_parser_tplink_safeloader_read_table(mtd); -+ if (!buf) { -+ err = -ENOENT; -+ goto err_out; -+ } -+ -+ for (idx = 0, offset = TPLINK_SAFELOADER_DATA_OFFSET; -+ idx < TPLINK_SAFELOADER_MAX_PARTS && -+ sscanf(buf + offset, "partition %64s base 0x%llx size 0x%llx%zn\n", -+ name, &parts[idx].offset, &parts[idx].size, &bytes) == 3; -+ idx++, offset += bytes + 1) { -+ parts[idx].name = kstrdup(name, GFP_KERNEL); -+ if (!parts[idx].name) { -+ err = -ENOMEM; -+ goto err_free; -+ } -+ } -+ -+ if (idx == TPLINK_SAFELOADER_MAX_PARTS) -+ pr_warn("Reached maximum number of partitions!\n"); -+ -+ kfree(buf); -+ -+ *pparts = parts; -+ -+ return idx; -+ -+err_free: -+ for (idx -= 1; idx >= 0; idx--) -+ kfree(parts[idx].name); -+err_out: -+ return err; -+}; -+ -+static void mtd_parser_tplink_safeloader_cleanup(const struct mtd_partition *pparts, -+ int nr_parts) -+{ -+ int i; -+ -+ for (i = 0; i < nr_parts; i++) -+ kfree(pparts[i].name); -+ -+ kfree(pparts); -+} -+ -+static const struct of_device_id mtd_parser_tplink_safeloader_of_match_table[] = { -+ { .compatible = "tplink,safeloader-partitions" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtd_parser_tplink_safeloader_of_match_table); -+ -+static struct mtd_part_parser mtd_parser_tplink_safeloader = { -+ .parse_fn = mtd_parser_tplink_safeloader_parse, -+ .cleanup = mtd_parser_tplink_safeloader_cleanup, -+ .name = "tplink-safeloader", -+ .of_match_table = mtd_parser_tplink_safeloader_of_match_table, -+}; -+module_mtd_part_parser(mtd_parser_tplink_safeloader); -+ -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch b/target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch deleted file mode 100644 index 7dbc2717250bfc..00000000000000 --- a/target/linux/generic/backport-6.1/423-v6.3-mtd-spinand-macronix-use-scratch-buffer-for-DMA-oper.patch +++ /dev/null @@ -1,35 +0,0 @@ -From ebed787a0becb9354f0a23620a5130cccd6c730c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 19 Jan 2023 03:45:43 +0000 -Subject: [PATCH] mtd: spinand: macronix: use scratch buffer for DMA operation - -The mx35lf1ge4ab_get_eccsr() function uses an SPI DMA operation to -read the eccsr, hence the buffer should not be on stack. Since commit -380583227c0c7f ("spi: spi-mem: Add extra sanity checks on the op param") -the kernel emmits a warning and blocks such operations. - -Use the scratch buffer to get eccsr instead of trying to directly read -into a stack-allocated variable. - -Signed-off-by: Daniel Golle -Reviewed-by: Dhruva Gole -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/Y8i85zM0u4XdM46z@makrotopia.org ---- - drivers/mtd/nand/spi/macronix.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/nand/spi/macronix.c -+++ b/drivers/mtd/nand/spi/macronix.c -@@ -83,9 +83,10 @@ static int mx35lf1ge4ab_ecc_get_status(s - * in order to avoid forcing the wear-leveling layer to move - * data around if it's not necessary. - */ -- if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr)) -+ if (mx35lf1ge4ab_get_eccsr(spinand, spinand->scratchbuf)) - return nanddev_get_ecc_conf(nand)->strength; - -+ eccsr = *spinand->scratchbuf; - if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength || - !eccsr)) - return nanddev_get_ecc_conf(nand)->strength; diff --git a/target/linux/generic/backport-6.1/424-v6.3-mtd-ubi-wire-up-parent-MTD-device.patch b/target/linux/generic/backport-6.1/424-v6.3-mtd-ubi-wire-up-parent-MTD-device.patch deleted file mode 100644 index 657404196d37d3..00000000000000 --- a/target/linux/generic/backport-6.1/424-v6.3-mtd-ubi-wire-up-parent-MTD-device.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 1ecf9e390452e73a362ea7fbde8f3f0db83de856 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 22 Dec 2022 19:33:04 +0000 -Subject: [PATCH] mtd: ubi: wire-up parent MTD device - -Wire up the device parent pointer of UBI devices to their lower MTD -device, typically an MTD partition or whole-chip device. - -The most noticeable change is that in sysfs, previously ubi devices -would be could in /sys/devices/virtual/ubi while after this change they -would be correctly attached to their parent MTD device, e.g. - -/sys/devices/platform/1100d000.spi/spi_master/spi1/spi1.0/mtd/mtd2/ubi0. - -Locating UBI devices using /sys/class/ubi/ of course still works as -well. - -Signed-off-by: Daniel Golle -Signed-off-by: Richard Weinberger ---- - drivers/mtd/ubi/build.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/ubi/build.c -+++ b/drivers/mtd/ubi/build.c -@@ -929,6 +929,7 @@ int ubi_attach_mtd_dev(struct mtd_info * - ubi->dev.release = dev_release; - ubi->dev.class = &ubi_class; - ubi->dev.groups = ubi_dev_groups; -+ ubi->dev.parent = &mtd->dev; - - ubi->mtd = mtd; - ubi->ubi_num = ubi_num; diff --git a/target/linux/generic/backport-6.1/425-v6.3-mtd-ubi-block-wire-up-device-parent.patch b/target/linux/generic/backport-6.1/425-v6.3-mtd-ubi-block-wire-up-device-parent.patch deleted file mode 100644 index 48bf9861184738..00000000000000 --- a/target/linux/generic/backport-6.1/425-v6.3-mtd-ubi-block-wire-up-device-parent.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 05b8773ca33253ea562be145cf3145b05ef19f86 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 22 Dec 2022 19:33:31 +0000 -Subject: [PATCH] mtd: ubi: block: wire-up device parent - -ubiblock devices were previously only identifyable by their name, but -not connected to their parent UBI volume device e.g. in sysfs. -Properly parent ubiblock device as descendant of a UBI volume device -to reflect device model hierachy. - -Signed-off-by: Daniel Golle -Signed-off-by: Richard Weinberger ---- - drivers/mtd/ubi/block.c | 2 +- - drivers/mtd/ubi/kapi.c | 1 + - include/linux/mtd/ubi.h | 1 + - 3 files changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -452,7 +452,7 @@ int ubiblock_create(struct ubi_volume_in - list_add_tail(&dev->list, &ubiblock_devices); - - /* Must be the last step: anyone can call file ops from now on */ -- ret = add_disk(dev->gd); -+ ret = device_add_disk(vi->dev, dev->gd, NULL); - if (ret) - goto out_destroy_wq; - ---- a/drivers/mtd/ubi/kapi.c -+++ b/drivers/mtd/ubi/kapi.c -@@ -79,6 +79,7 @@ void ubi_do_get_volume_info(struct ubi_d - vi->name_len = vol->name_len; - vi->name = vol->name; - vi->cdev = vol->cdev.dev; -+ vi->dev = &vol->dev; - } - - /** ---- a/include/linux/mtd/ubi.h -+++ b/include/linux/mtd/ubi.h -@@ -110,6 +110,7 @@ struct ubi_volume_info { - int name_len; - const char *name; - dev_t cdev; -+ struct device *dev; - }; - - /** diff --git a/target/linux/generic/backport-6.1/426-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch b/target/linux/generic/backport-6.1/426-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch deleted file mode 100644 index 28f54d9e5e5abf..00000000000000 --- a/target/linux/generic/backport-6.1/426-v6.4-0004-mtd-core-prepare-mtd_otp_nvmem_add-to-handle-EPROBE_.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 281f7a6c1a33fffcde32001bacbb4f672140fbf9 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Wed, 8 Mar 2023 09:20:21 +0100 -Subject: [PATCH] mtd: core: prepare mtd_otp_nvmem_add() to handle - -EPROBE_DEFER - -NVMEM soon will get the ability for nvmem layouts and these might -not be ready when nvmem_register() is called and thus it might -return -EPROBE_DEFER. Don't print the error message in this case. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc ---- - drivers/mtd/mtdcore.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -955,8 +955,8 @@ static int mtd_otp_nvmem_add(struct mtd_ - nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size, - mtd_nvmem_user_otp_reg_read); - if (IS_ERR(nvmem)) { -- dev_err(dev, "Failed to register OTP NVMEM device\n"); -- return PTR_ERR(nvmem); -+ err = PTR_ERR(nvmem); -+ goto err; - } - mtd->otp_user_nvmem = nvmem; - } -@@ -973,7 +973,6 @@ static int mtd_otp_nvmem_add(struct mtd_ - nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size, - mtd_nvmem_fact_otp_reg_read); - if (IS_ERR(nvmem)) { -- dev_err(dev, "Failed to register OTP NVMEM device\n"); - err = PTR_ERR(nvmem); - goto err; - } -@@ -985,7 +984,7 @@ static int mtd_otp_nvmem_add(struct mtd_ - - err: - nvmem_unregister(mtd->otp_user_nvmem); -- return err; -+ return dev_err_probe(dev, err, "Failed to register OTP NVMEM device\n"); - } - - /** diff --git a/target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch b/target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch deleted file mode 100644 index 6dbec3c75244c0..00000000000000 --- a/target/linux/generic/backport-6.1/600-v6.9-01-net-gro-parse-ipv6-ext-headers-without-frag0-invalid.patch +++ /dev/null @@ -1,107 +0,0 @@ -From: Richard Gobert -Date: Wed, 3 Jan 2024 15:44:21 +0100 -Subject: [PATCH] net: gro: parse ipv6 ext headers without frag0 invalidation - -The existing code always pulls the IPv6 header and sets the transport -offset initially. Then optionally again pulls any extension headers in -ipv6_gso_pull_exthdrs and sets the transport offset again on return from -that call. skb->data is set at the start of the first extension header -before calling ipv6_gso_pull_exthdrs, and must disable the frag0 -optimization because that function uses pskb_may_pull/pskb_pull instead of -skb_gro_ helpers. It sets the GRO offset to the TCP header with -skb_gro_pull and sets the transport header. Then returns skb->data to its -position before this block. - -This commit introduces a new helper function - ipv6_gro_pull_exthdrs - -which is used in ipv6_gro_receive to pull ipv6 ext headers instead of -ipv6_gso_pull_exthdrs. Thus, there is no modification of skb->data, all -operations use skb_gro_* helpers, and the frag0 fast path can be taken for -IPv6 packets with ext headers. - -Signed-off-by: Richard Gobert -Reviewed-by: Willem de Bruijn -Reviewed-by: David Ahern -Reviewed-by: Eric Dumazet -Link: https://lore.kernel.org/r/504130f6-b56c-4dcc-882c-97942c59f5b7@gmail.com -Signed-off-by: Jakub Kicinski ---- - ---- a/net/ipv6/ip6_offload.c -+++ b/net/ipv6/ip6_offload.c -@@ -36,6 +36,40 @@ - INDIRECT_CALL_L4(cb, f2, f1, head, skb); \ - }) - -+static int ipv6_gro_pull_exthdrs(struct sk_buff *skb, int off, int proto) -+{ -+ const struct net_offload *ops = NULL; -+ struct ipv6_opt_hdr *opth; -+ -+ for (;;) { -+ int len; -+ -+ ops = rcu_dereference(inet6_offloads[proto]); -+ -+ if (unlikely(!ops)) -+ break; -+ -+ if (!(ops->flags & INET6_PROTO_GSO_EXTHDR)) -+ break; -+ -+ opth = skb_gro_header(skb, off + sizeof(*opth), off); -+ if (unlikely(!opth)) -+ break; -+ -+ len = ipv6_optlen(opth); -+ -+ opth = skb_gro_header(skb, off + len, off); -+ if (unlikely(!opth)) -+ break; -+ proto = opth->nexthdr; -+ -+ off += len; -+ } -+ -+ skb_gro_pull(skb, off - skb_network_offset(skb)); -+ return proto; -+} -+ - static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto) - { - const struct net_offload *ops = NULL; -@@ -224,28 +258,25 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff * - goto out; - - skb_set_network_header(skb, off); -- skb_gro_pull(skb, sizeof(*iph)); -- skb_set_transport_header(skb, skb_gro_offset(skb)); - -- flush += ntohs(iph->payload_len) != skb_gro_len(skb); -+ flush += ntohs(iph->payload_len) != skb->len - hlen; - - proto = iph->nexthdr; - ops = rcu_dereference(inet6_offloads[proto]); - if (!ops || !ops->callbacks.gro_receive) { -- pskb_pull(skb, skb_gro_offset(skb)); -- skb_gro_frag0_invalidate(skb); -- proto = ipv6_gso_pull_exthdrs(skb, proto); -- skb_gro_pull(skb, -skb_transport_offset(skb)); -- skb_reset_transport_header(skb); -- __skb_push(skb, skb_gro_offset(skb)); -+ proto = ipv6_gro_pull_exthdrs(skb, hlen, proto); - - ops = rcu_dereference(inet6_offloads[proto]); - if (!ops || !ops->callbacks.gro_receive) - goto out; - -- iph = ipv6_hdr(skb); -+ iph = skb_gro_network_header(skb); -+ } else { -+ skb_gro_pull(skb, sizeof(*iph)); - } - -+ skb_set_transport_header(skb, skb_gro_offset(skb)); -+ - NAPI_GRO_CB(skb)->proto = proto; - - flush--; diff --git a/target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch b/target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch deleted file mode 100644 index 28b7b4383e64c3..00000000000000 --- a/target/linux/generic/backport-6.1/611-v6.3-net-add-helper-eth_addr_add.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 7390609b0121a1b982c5ecdfcd72dc328e5784ee Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:42 +0000 -Subject: [PATCH] net: add helper eth_addr_add() - -Add a helper to add an offset to a ethernet address. This comes in handy -if you have a base ethernet address for multiple interfaces. - -Signed-off-by: Michael Walle -Reviewed-by: Andrew Lunn -Acked-by: Jakub Kicinski -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - include/linux/etherdevice.h | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/include/linux/etherdevice.h -+++ b/include/linux/etherdevice.h -@@ -508,6 +508,20 @@ static inline void eth_addr_inc(u8 *addr - } - - /** -+ * eth_addr_add() - Add (or subtract) an offset to/from the given MAC address. -+ * -+ * @offset: Offset to add. -+ * @addr: Pointer to a six-byte array containing Ethernet address to increment. -+ */ -+static inline void eth_addr_add(u8 *addr, long offset) -+{ -+ u64 u = ether_addr_to_u64(addr); -+ -+ u += offset; -+ u64_to_ether_addr(u, addr); -+} -+ -+/** - * is_etherdev_addr - Tell if given Ethernet address belongs to the device. - * @dev: Pointer to a device structure - * @addr: Pointer to a six-byte array containing the Ethernet address diff --git a/target/linux/generic/backport-6.1/701-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch b/target/linux/generic/backport-6.1/701-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch deleted file mode 100644 index 56e14c5c0a90cc..00000000000000 --- a/target/linux/generic/backport-6.1/701-net-next-net-sfp-add-quirk-for-Fiberstone-GPON-ONU-34-20BI.patch +++ /dev/null @@ -1,32 +0,0 @@ -From d387e34fec407f881fdf165b5d7ec128ebff362f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 19 Sep 2023 14:47:20 +0200 -Subject: [PATCH] net: sfp: add quirk for Fiberstone GPON-ONU-34-20BI - -Fiberstone GPON-ONU-34-20B can operate at 2500base-X, but report 1.2GBd -NRZ in their EEPROM. - -The module also require the ignore tx fault fixup similar to Huawei MA5671A -as it gets disabled on error messages with serial redirection enabled. - -Signed-off-by: Christian Marangi -Link: https://lore.kernel.org/r/20230919124720.8210-1-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/sfp.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -393,6 +393,11 @@ static const struct sfp_quirk sfp_quirks - SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", sfp_quirk_2500basex, - sfp_fixup_long_startup), - -+ // Fiberstore GPON-ONU-34-20BI can operate at 2500base-X, but report 1.2GBd -+ // NRZ in their EEPROM -+ SFP_QUIRK("FS", "GPON-ONU-34-20BI", sfp_quirk_2500basex, -+ sfp_fixup_ignore_tx_fault), -+ - SFP_QUIRK_F("HALNy", "HL-GSFP", sfp_fixup_halny_gsfp), - - // HG MXPD-483II-F 2.5G supports 2500Base-X, but incorrectly reports diff --git a/target/linux/generic/backport-6.1/702-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch b/target/linux/generic/backport-6.1/702-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch deleted file mode 100644 index 0cad6c53d4283e..00000000000000 --- a/target/linux/generic/backport-6.1/702-01-v6.7-net-phy-aquantia-move-to-separate-directory.patch +++ /dev/null @@ -1,2306 +0,0 @@ -From d2213db3f49bce8e7a87c8de05b9a091f78f654e Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 14 Nov 2023 15:08:41 +0100 -Subject: [PATCH 1/3] net: phy: aquantia: move to separate directory - -Move aquantia PHY driver to separate driectory in preparation for -firmware loading support to keep things tidy. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/Kconfig | 5 +---- - drivers/net/phy/Makefile | 6 +----- - drivers/net/phy/aquantia/Kconfig | 5 +++++ - drivers/net/phy/aquantia/Makefile | 6 ++++++ - drivers/net/phy/{ => aquantia}/aquantia.h | 0 - drivers/net/phy/{ => aquantia}/aquantia_hwmon.c | 0 - drivers/net/phy/{ => aquantia}/aquantia_main.c | 0 - 7 files changed, 13 insertions(+), 9 deletions(-) - create mode 100644 drivers/net/phy/aquantia/Kconfig - create mode 100644 drivers/net/phy/aquantia/Makefile - rename drivers/net/phy/{ => aquantia}/aquantia.h (100%) - rename drivers/net/phy/{ => aquantia}/aquantia_hwmon.c (100%) - rename drivers/net/phy/{ => aquantia}/aquantia_main.c (100%) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -90,10 +90,7 @@ config ADIN1100_PHY - Currently supports the: - - ADIN1100 - Robust,Industrial, Low Power 10BASE-T1L Ethernet PHY - --config AQUANTIA_PHY -- tristate "Aquantia PHYs" -- help -- Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405 -+source "drivers/net/phy/aquantia/Kconfig" - - config AX88796B_PHY - tristate "Asix PHYs" ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -33,11 +33,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m) - obj-$(CONFIG_ADIN_PHY) += adin.o - obj-$(CONFIG_ADIN1100_PHY) += adin1100.o - obj-$(CONFIG_AMD_PHY) += amd.o --aquantia-objs += aquantia_main.o --ifdef CONFIG_HWMON --aquantia-objs += aquantia_hwmon.o --endif --obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o -+obj-$(CONFIG_AQUANTIA_PHY) += aquantia/ - obj-$(CONFIG_AT803X_PHY) += at803x.o - obj-$(CONFIG_AX88796B_PHY) += ax88796b.o - obj-$(CONFIG_BCM54140_PHY) += bcm54140.o ---- /dev/null -+++ b/drivers/net/phy/aquantia/Kconfig -@@ -0,0 +1,5 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+config AQUANTIA_PHY -+ tristate "Aquantia PHYs" -+ help -+ Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405 ---- /dev/null -+++ b/drivers/net/phy/aquantia/Makefile -@@ -0,0 +1,6 @@ -+# SPDX-License-Identifier: GPL-2.0 -+aquantia-objs += aquantia_main.o -+ifdef CONFIG_HWMON -+aquantia-objs += aquantia_hwmon.o -+endif -+obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o ---- a/drivers/net/phy/aquantia.h -+++ /dev/null -@@ -1,16 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* HWMON driver for Aquantia PHY -- * -- * Author: Nikita Yushchenko -- * Author: Andrew Lunn -- * Author: Heiner Kallweit -- */ -- --#include --#include -- --#if IS_REACHABLE(CONFIG_HWMON) --int aqr_hwmon_probe(struct phy_device *phydev); --#else --static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; } --#endif ---- /dev/null -+++ b/drivers/net/phy/aquantia/aquantia.h -@@ -0,0 +1,16 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* HWMON driver for Aquantia PHY -+ * -+ * Author: Nikita Yushchenko -+ * Author: Andrew Lunn -+ * Author: Heiner Kallweit -+ */ -+ -+#include -+#include -+ -+#if IS_REACHABLE(CONFIG_HWMON) -+int aqr_hwmon_probe(struct phy_device *phydev); -+#else -+static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; } -+#endif ---- /dev/null -+++ b/drivers/net/phy/aquantia/aquantia_hwmon.c -@@ -0,0 +1,250 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* HWMON driver for Aquantia PHY -+ * -+ * Author: Nikita Yushchenko -+ * Author: Andrew Lunn -+ * Author: Heiner Kallweit -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "aquantia.h" -+ -+/* Vendor specific 1, MDIO_MMD_VEND2 */ -+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421 -+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422 -+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423 -+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424 -+#define VEND1_THERMAL_STAT1 0xc820 -+#define VEND1_THERMAL_STAT2 0xc821 -+#define VEND1_THERMAL_STAT2_VALID BIT(0) -+#define VEND1_GENERAL_STAT1 0xc830 -+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14) -+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13) -+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12) -+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11) -+ -+#if IS_REACHABLE(CONFIG_HWMON) -+ -+static umode_t aqr_hwmon_is_visible(const void *data, -+ enum hwmon_sensor_types type, -+ u32 attr, int channel) -+{ -+ if (type != hwmon_temp) -+ return 0; -+ -+ switch (attr) { -+ case hwmon_temp_input: -+ case hwmon_temp_min_alarm: -+ case hwmon_temp_max_alarm: -+ case hwmon_temp_lcrit_alarm: -+ case hwmon_temp_crit_alarm: -+ return 0444; -+ case hwmon_temp_min: -+ case hwmon_temp_max: -+ case hwmon_temp_lcrit: -+ case hwmon_temp_crit: -+ return 0644; -+ default: -+ return 0; -+ } -+} -+ -+static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value) -+{ -+ int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg); -+ -+ if (temp < 0) -+ return temp; -+ -+ /* 16 bit value is 2's complement with LSB = 1/256th degree Celsius */ -+ *value = (s16)temp * 1000 / 256; -+ -+ return 0; -+} -+ -+static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value) -+{ -+ int temp; -+ -+ if (value >= 128000 || value < -128000) -+ return -ERANGE; -+ -+ temp = value * 256 / 1000; -+ -+ /* temp is in s16 range and we're interested in lower 16 bits only */ -+ return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, (u16)temp); -+} -+ -+static int aqr_hwmon_test_bit(struct phy_device *phydev, int reg, int bit) -+{ -+ int val = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg); -+ -+ if (val < 0) -+ return val; -+ -+ return !!(val & bit); -+} -+ -+static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value) -+{ -+ int val = aqr_hwmon_test_bit(phydev, VEND1_GENERAL_STAT1, bit); -+ -+ if (val < 0) -+ return val; -+ -+ *value = val; -+ -+ return 0; -+} -+ -+static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type, -+ u32 attr, int channel, long *value) -+{ -+ struct phy_device *phydev = dev_get_drvdata(dev); -+ int reg; -+ -+ if (type != hwmon_temp) -+ return -EOPNOTSUPP; -+ -+ switch (attr) { -+ case hwmon_temp_input: -+ reg = aqr_hwmon_test_bit(phydev, VEND1_THERMAL_STAT2, -+ VEND1_THERMAL_STAT2_VALID); -+ if (reg < 0) -+ return reg; -+ if (!reg) -+ return -EBUSY; -+ -+ return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value); -+ -+ case hwmon_temp_lcrit: -+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL, -+ value); -+ case hwmon_temp_min: -+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN, -+ value); -+ case hwmon_temp_max: -+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN, -+ value); -+ case hwmon_temp_crit: -+ return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL, -+ value); -+ case hwmon_temp_lcrit_alarm: -+ return aqr_hwmon_status1(phydev, -+ VEND1_GENERAL_STAT1_LOW_TEMP_FAIL, -+ value); -+ case hwmon_temp_min_alarm: -+ return aqr_hwmon_status1(phydev, -+ VEND1_GENERAL_STAT1_LOW_TEMP_WARN, -+ value); -+ case hwmon_temp_max_alarm: -+ return aqr_hwmon_status1(phydev, -+ VEND1_GENERAL_STAT1_HIGH_TEMP_WARN, -+ value); -+ case hwmon_temp_crit_alarm: -+ return aqr_hwmon_status1(phydev, -+ VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL, -+ value); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type, -+ u32 attr, int channel, long value) -+{ -+ struct phy_device *phydev = dev_get_drvdata(dev); -+ -+ if (type != hwmon_temp) -+ return -EOPNOTSUPP; -+ -+ switch (attr) { -+ case hwmon_temp_lcrit: -+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL, -+ value); -+ case hwmon_temp_min: -+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN, -+ value); -+ case hwmon_temp_max: -+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN, -+ value); -+ case hwmon_temp_crit: -+ return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL, -+ value); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static const struct hwmon_ops aqr_hwmon_ops = { -+ .is_visible = aqr_hwmon_is_visible, -+ .read = aqr_hwmon_read, -+ .write = aqr_hwmon_write, -+}; -+ -+static u32 aqr_hwmon_chip_config[] = { -+ HWMON_C_REGISTER_TZ, -+ 0, -+}; -+ -+static const struct hwmon_channel_info aqr_hwmon_chip = { -+ .type = hwmon_chip, -+ .config = aqr_hwmon_chip_config, -+}; -+ -+static u32 aqr_hwmon_temp_config[] = { -+ HWMON_T_INPUT | -+ HWMON_T_MAX | HWMON_T_MIN | -+ HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM | -+ HWMON_T_CRIT | HWMON_T_LCRIT | -+ HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM, -+ 0, -+}; -+ -+static const struct hwmon_channel_info aqr_hwmon_temp = { -+ .type = hwmon_temp, -+ .config = aqr_hwmon_temp_config, -+}; -+ -+static const struct hwmon_channel_info *aqr_hwmon_info[] = { -+ &aqr_hwmon_chip, -+ &aqr_hwmon_temp, -+ NULL, -+}; -+ -+static const struct hwmon_chip_info aqr_hwmon_chip_info = { -+ .ops = &aqr_hwmon_ops, -+ .info = aqr_hwmon_info, -+}; -+ -+int aqr_hwmon_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct device *hwmon_dev; -+ char *hwmon_name; -+ int i, j; -+ -+ hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); -+ if (!hwmon_name) -+ return -ENOMEM; -+ -+ for (i = j = 0; hwmon_name[i]; i++) { -+ if (isalnum(hwmon_name[i])) { -+ if (i != j) -+ hwmon_name[j] = hwmon_name[i]; -+ j++; -+ } -+ } -+ hwmon_name[j] = '\0'; -+ -+ hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name, -+ phydev, &aqr_hwmon_chip_info, NULL); -+ -+ return PTR_ERR_OR_ZERO(hwmon_dev); -+} -+ -+#endif ---- /dev/null -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -0,0 +1,842 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Driver for Aquantia PHY -+ * -+ * Author: Shaohui Xie -+ * -+ * Copyright 2015 Freescale Semiconductor, Inc. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "aquantia.h" -+ -+#define PHY_ID_AQ1202 0x03a1b445 -+#define PHY_ID_AQ2104 0x03a1b460 -+#define PHY_ID_AQR105 0x03a1b4a2 -+#define PHY_ID_AQR106 0x03a1b4d0 -+#define PHY_ID_AQR107 0x03a1b4e0 -+#define PHY_ID_AQCS109 0x03a1b5c2 -+#define PHY_ID_AQR405 0x03a1b4b0 -+#define PHY_ID_AQR113C 0x31c31c12 -+ -+#define MDIO_PHYXS_VEND_IF_STATUS 0xe812 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 1 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 3 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7 -+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10 -+ -+#define MDIO_AN_VEND_PROV 0xc400 -+#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) -+#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) -+#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11) -+#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10) -+#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4) -+#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0) -+#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4 -+ -+#define MDIO_AN_TX_VEND_STATUS1 0xc800 -+#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1) -+#define MDIO_AN_TX_VEND_STATUS1_10BASET 0 -+#define MDIO_AN_TX_VEND_STATUS1_100BASETX 1 -+#define MDIO_AN_TX_VEND_STATUS1_1000BASET 2 -+#define MDIO_AN_TX_VEND_STATUS1_10GBASET 3 -+#define MDIO_AN_TX_VEND_STATUS1_2500BASET 4 -+#define MDIO_AN_TX_VEND_STATUS1_5000BASET 5 -+#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX BIT(0) -+ -+#define MDIO_AN_TX_VEND_INT_STATUS1 0xcc00 -+#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT BIT(1) -+ -+#define MDIO_AN_TX_VEND_INT_STATUS2 0xcc01 -+#define MDIO_AN_TX_VEND_INT_STATUS2_MASK BIT(0) -+ -+#define MDIO_AN_TX_VEND_INT_MASK2 0xd401 -+#define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0) -+ -+#define MDIO_AN_RX_LP_STAT1 0xe820 -+#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15) -+#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14) -+#define MDIO_AN_RX_LP_STAT1_SHORT_REACH BIT(13) -+#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT BIT(12) -+#define MDIO_AN_RX_LP_STAT1_AQ_PHY BIT(2) -+ -+#define MDIO_AN_RX_LP_STAT4 0xe823 -+#define MDIO_AN_RX_LP_STAT4_FW_MAJOR GENMASK(15, 8) -+#define MDIO_AN_RX_LP_STAT4_FW_MINOR GENMASK(7, 0) -+ -+#define MDIO_AN_RX_VEND_STAT3 0xe832 -+#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0) -+ -+/* MDIO_MMD_C22EXT */ -+#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292 -+#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294 -+#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297 -+#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313 -+#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315 -+#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317 -+#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318 -+#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319 -+#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a -+#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b -+ -+/* Vendor specific 1, MDIO_MMD_VEND1 */ -+#define VEND1_GLOBAL_FW_ID 0x0020 -+#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) -+#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) -+ -+#define VEND1_GLOBAL_GEN_STAT2 0xc831 -+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15) -+ -+/* The following registers all have similar layouts; first the registers... */ -+#define VEND1_GLOBAL_CFG_10M 0x0310 -+#define VEND1_GLOBAL_CFG_100M 0x031b -+#define VEND1_GLOBAL_CFG_1G 0x031c -+#define VEND1_GLOBAL_CFG_2_5G 0x031d -+#define VEND1_GLOBAL_CFG_5G 0x031e -+#define VEND1_GLOBAL_CFG_10G 0x031f -+/* ...and now the fields */ -+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7) -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0 -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1 -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 -+ -+#define VEND1_GLOBAL_RSVD_STAT1 0xc885 -+#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4) -+#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0) -+ -+#define VEND1_GLOBAL_RSVD_STAT9 0xc88d -+#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0) -+#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23 -+ -+#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00 -+#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01 -+ -+#define VEND1_GLOBAL_INT_STD_MASK 0xff00 -+#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15) -+#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11) -+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10) -+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9) -+#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8) -+#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7) -+#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6) -+#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0) -+ -+#define VEND1_GLOBAL_INT_VEND_MASK 0xff01 -+#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15) -+#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14) -+#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13) -+#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12) -+#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0) -+ -+/* Sleep and timeout for checking if the Processor-Intensive -+ * MDIO operation is finished -+ */ -+#define AQR107_OP_IN_PROG_SLEEP 1000 -+#define AQR107_OP_IN_PROG_TIMEOUT 100000 -+ -+struct aqr107_hw_stat { -+ const char *name; -+ int reg; -+ int size; -+}; -+ -+#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s } -+static const struct aqr107_hw_stat aqr107_hw_stats[] = { -+ SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26), -+ SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26), -+ SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8), -+ SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26), -+ SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26), -+ SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8), -+ SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8), -+ SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8), -+ SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16), -+ SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22), -+}; -+#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats) -+ -+struct aqr107_priv { -+ u64 sgmii_stats[AQR107_SGMII_STAT_SZ]; -+}; -+ -+static int aqr107_get_sset_count(struct phy_device *phydev) -+{ -+ return AQR107_SGMII_STAT_SZ; -+} -+ -+static void aqr107_get_strings(struct phy_device *phydev, u8 *data) -+{ -+ int i; -+ -+ for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) -+ strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name, -+ ETH_GSTRING_LEN); -+} -+ -+static u64 aqr107_get_stat(struct phy_device *phydev, int index) -+{ -+ const struct aqr107_hw_stat *stat = aqr107_hw_stats + index; -+ int len_l = min(stat->size, 16); -+ int len_h = stat->size - len_l; -+ u64 ret; -+ int val; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg); -+ if (val < 0) -+ return U64_MAX; -+ -+ ret = val & GENMASK(len_l - 1, 0); -+ if (len_h) { -+ val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1); -+ if (val < 0) -+ return U64_MAX; -+ -+ ret += (val & GENMASK(len_h - 1, 0)) << 16; -+ } -+ -+ return ret; -+} -+ -+static void aqr107_get_stats(struct phy_device *phydev, -+ struct ethtool_stats *stats, u64 *data) -+{ -+ struct aqr107_priv *priv = phydev->priv; -+ u64 val; -+ int i; -+ -+ for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) { -+ val = aqr107_get_stat(phydev, i); -+ if (val == U64_MAX) -+ phydev_err(phydev, "Reading HW Statistics failed for %s\n", -+ aqr107_hw_stats[i].name); -+ else -+ priv->sgmii_stats[i] += val; -+ -+ data[i] = priv->sgmii_stats[i]; -+ } -+} -+ -+static int aqr_config_aneg(struct phy_device *phydev) -+{ -+ bool changed = false; -+ u16 reg; -+ int ret; -+ -+ if (phydev->autoneg == AUTONEG_DISABLE) -+ return genphy_c45_pma_setup_forced(phydev); -+ -+ ret = genphy_c45_an_config_aneg(phydev); -+ if (ret < 0) -+ return ret; -+ if (ret > 0) -+ changed = true; -+ -+ /* Clause 45 has no standardized support for 1000BaseT, therefore -+ * use vendor registers for this mode. -+ */ -+ reg = 0; -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ phydev->advertising)) -+ reg |= MDIO_AN_VEND_PROV_1000BASET_FULL; -+ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -+ phydev->advertising)) -+ reg |= MDIO_AN_VEND_PROV_1000BASET_HALF; -+ -+ /* Handle the case when the 2.5G and 5G speeds are not advertised */ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ phydev->advertising)) -+ reg |= MDIO_AN_VEND_PROV_2500BASET_FULL; -+ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, -+ phydev->advertising)) -+ reg |= MDIO_AN_VEND_PROV_5000BASET_FULL; -+ -+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, -+ MDIO_AN_VEND_PROV_1000BASET_HALF | -+ MDIO_AN_VEND_PROV_1000BASET_FULL | -+ MDIO_AN_VEND_PROV_2500BASET_FULL | -+ MDIO_AN_VEND_PROV_5000BASET_FULL, reg); -+ if (ret < 0) -+ return ret; -+ if (ret > 0) -+ changed = true; -+ -+ return genphy_c45_check_and_restart_aneg(phydev, changed); -+} -+ -+static int aqr_config_intr(struct phy_device *phydev) -+{ -+ bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED; -+ int err; -+ -+ if (en) { -+ /* Clear any pending interrupts before enabling them */ -+ err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2); -+ if (err < 0) -+ return err; -+ } -+ -+ err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2, -+ en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0); -+ if (err < 0) -+ return err; -+ -+ err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK, -+ en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0); -+ if (err < 0) -+ return err; -+ -+ err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK, -+ en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 | -+ VEND1_GLOBAL_INT_VEND_MASK_AN : 0); -+ if (err < 0) -+ return err; -+ -+ if (!en) { -+ /* Clear any pending interrupts after we have disabled them */ -+ err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2); -+ if (err < 0) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev) -+{ -+ int irq_status; -+ -+ irq_status = phy_read_mmd(phydev, MDIO_MMD_AN, -+ MDIO_AN_TX_VEND_INT_STATUS2); -+ if (irq_status < 0) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK)) -+ return IRQ_NONE; -+ -+ phy_trigger_machine(phydev); -+ -+ return IRQ_HANDLED; -+} -+ -+static int aqr_read_status(struct phy_device *phydev) -+{ -+ int val; -+ -+ if (phydev->autoneg == AUTONEG_ENABLE) { -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1); -+ if (val < 0) -+ return val; -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ phydev->lp_advertising, -+ val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -+ phydev->lp_advertising, -+ val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF); -+ } -+ -+ return genphy_c45_read_status(phydev); -+} -+ -+static int aqr107_read_rate(struct phy_device *phydev) -+{ -+ u32 config_reg; -+ int val; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1); -+ if (val < 0) -+ return val; -+ -+ if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX) -+ phydev->duplex = DUPLEX_FULL; -+ else -+ phydev->duplex = DUPLEX_HALF; -+ -+ switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) { -+ case MDIO_AN_TX_VEND_STATUS1_10BASET: -+ phydev->speed = SPEED_10; -+ config_reg = VEND1_GLOBAL_CFG_10M; -+ break; -+ case MDIO_AN_TX_VEND_STATUS1_100BASETX: -+ phydev->speed = SPEED_100; -+ config_reg = VEND1_GLOBAL_CFG_100M; -+ break; -+ case MDIO_AN_TX_VEND_STATUS1_1000BASET: -+ phydev->speed = SPEED_1000; -+ config_reg = VEND1_GLOBAL_CFG_1G; -+ break; -+ case MDIO_AN_TX_VEND_STATUS1_2500BASET: -+ phydev->speed = SPEED_2500; -+ config_reg = VEND1_GLOBAL_CFG_2_5G; -+ break; -+ case MDIO_AN_TX_VEND_STATUS1_5000BASET: -+ phydev->speed = SPEED_5000; -+ config_reg = VEND1_GLOBAL_CFG_5G; -+ break; -+ case MDIO_AN_TX_VEND_STATUS1_10GBASET: -+ phydev->speed = SPEED_10000; -+ config_reg = VEND1_GLOBAL_CFG_10G; -+ break; -+ default: -+ phydev->speed = SPEED_UNKNOWN; -+ return 0; -+ } -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg); -+ if (val < 0) -+ return val; -+ -+ if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) == -+ VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE) -+ phydev->rate_matching = RATE_MATCH_PAUSE; -+ else -+ phydev->rate_matching = RATE_MATCH_NONE; -+ -+ return 0; -+} -+ -+static int aqr107_read_status(struct phy_device *phydev) -+{ -+ int val, ret; -+ -+ ret = aqr_read_status(phydev); -+ if (ret) -+ return ret; -+ -+ if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE) -+ return 0; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS); -+ if (val < 0) -+ return val; -+ -+ switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) { -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR: -+ phydev->interface = PHY_INTERFACE_MODE_10GKR; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX: -+ phydev->interface = PHY_INTERFACE_MODE_1000BASEKX; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI: -+ phydev->interface = PHY_INTERFACE_MODE_10GBASER; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII: -+ phydev->interface = PHY_INTERFACE_MODE_USXGMII; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI: -+ phydev->interface = PHY_INTERFACE_MODE_XAUI; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII: -+ phydev->interface = PHY_INTERFACE_MODE_SGMII; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI: -+ phydev->interface = PHY_INTERFACE_MODE_RXAUI; -+ break; -+ case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII: -+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -+ break; -+ default: -+ phydev->interface = PHY_INTERFACE_MODE_NA; -+ break; -+ } -+ -+ /* Read possibly downshifted rate from vendor register */ -+ return aqr107_read_rate(phydev); -+} -+ -+static int aqr107_get_downshift(struct phy_device *phydev, u8 *data) -+{ -+ int val, cnt, enable; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV); -+ if (val < 0) -+ return val; -+ -+ enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val); -+ cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val); -+ -+ *data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE; -+ -+ return 0; -+} -+ -+static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt) -+{ -+ int val = 0; -+ -+ if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt)) -+ return -E2BIG; -+ -+ if (cnt != DOWNSHIFT_DEV_DISABLE) { -+ val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN; -+ val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt); -+ } -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, -+ MDIO_AN_VEND_PROV_DOWNSHIFT_EN | -+ MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val); -+} -+ -+static int aqr107_get_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, void *data) -+{ -+ switch (tuna->id) { -+ case ETHTOOL_PHY_DOWNSHIFT: -+ return aqr107_get_downshift(phydev, data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int aqr107_set_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, const void *data) -+{ -+ switch (tuna->id) { -+ case ETHTOOL_PHY_DOWNSHIFT: -+ return aqr107_set_downshift(phydev, *(const u8 *)data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+/* If we configure settings whilst firmware is still initializing the chip, -+ * then these settings may be overwritten. Therefore make sure chip -+ * initialization has completed. Use presence of the firmware ID as -+ * indicator for initialization having completed. -+ * The chip also provides a "reset completed" bit, but it's cleared after -+ * read. Therefore function would time out if called again. -+ */ -+static int aqr107_wait_reset_complete(struct phy_device *phydev) -+{ -+ int val; -+ -+ return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_FW_ID, val, val != 0, -+ 20000, 2000000, false); -+} -+ -+static void aqr107_chip_info(struct phy_device *phydev) -+{ -+ u8 fw_major, fw_minor, build_id, prov_id; -+ int val; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID); -+ if (val < 0) -+ return; -+ -+ fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val); -+ fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1); -+ if (val < 0) -+ return; -+ -+ build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val); -+ prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val); -+ -+ phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n", -+ fw_major, fw_minor, build_id, prov_id); -+} -+ -+static int aqr107_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Check that the PHY interface type is compatible */ -+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII && -+ phydev->interface != PHY_INTERFACE_MODE_1000BASEKX && -+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX && -+ phydev->interface != PHY_INTERFACE_MODE_XGMII && -+ phydev->interface != PHY_INTERFACE_MODE_USXGMII && -+ phydev->interface != PHY_INTERFACE_MODE_10GKR && -+ phydev->interface != PHY_INTERFACE_MODE_10GBASER && -+ phydev->interface != PHY_INTERFACE_MODE_XAUI && -+ phydev->interface != PHY_INTERFACE_MODE_RXAUI) -+ return -ENODEV; -+ -+ WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII, -+ "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n"); -+ -+ ret = aqr107_wait_reset_complete(phydev); -+ if (!ret) -+ aqr107_chip_info(phydev); -+ -+ return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); -+} -+ -+static int aqcs109_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Check that the PHY interface type is compatible */ -+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII && -+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX) -+ return -ENODEV; -+ -+ ret = aqr107_wait_reset_complete(phydev); -+ if (!ret) -+ aqr107_chip_info(phydev); -+ -+ /* AQCS109 belongs to a chip family partially supporting 10G and 5G. -+ * PMA speed ability bits are the same for all members of the family, -+ * AQCS109 however supports speeds up to 2.5G only. -+ */ -+ phy_set_max_speed(phydev, SPEED_2500); -+ -+ return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); -+} -+ -+static void aqr107_link_change_notify(struct phy_device *phydev) -+{ -+ u8 fw_major, fw_minor; -+ bool downshift, short_reach, afr; -+ int mode, val; -+ -+ if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE) -+ return; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1); -+ /* call failed or link partner is no Aquantia PHY */ -+ if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY)) -+ return; -+ -+ short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH; -+ downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4); -+ if (val < 0) -+ return; -+ -+ fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val); -+ fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3); -+ if (val < 0) -+ return; -+ -+ afr = val & MDIO_AN_RX_VEND_STAT3_AFR; -+ -+ phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n", -+ fw_major, fw_minor, -+ short_reach ? ", short reach mode" : "", -+ downshift ? ", fast-retrain downshift advertised" : "", -+ afr ? ", fast reframe advertised" : ""); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT9); -+ if (val < 0) -+ return; -+ -+ mode = FIELD_GET(VEND1_GLOBAL_RSVD_STAT9_MODE, val); -+ if (mode == VEND1_GLOBAL_RSVD_STAT9_1000BT2) -+ phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n"); -+} -+ -+static int aqr107_wait_processor_intensive_op(struct phy_device *phydev) -+{ -+ int val, err; -+ -+ /* The datasheet notes to wait at least 1ms after issuing a -+ * processor intensive operation before checking. -+ * We cannot use the 'sleep_before_read' parameter of read_poll_timeout -+ * because that just determines the maximum time slept, not the minimum. -+ */ -+ usleep_range(1000, 5000); -+ -+ err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_GEN_STAT2, val, -+ !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG), -+ AQR107_OP_IN_PROG_SLEEP, -+ AQR107_OP_IN_PROG_TIMEOUT, false); -+ if (err) { -+ phydev_err(phydev, "timeout: processor-intensive MDIO operation\n"); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int aqr107_get_rate_matching(struct phy_device *phydev, -+ phy_interface_t iface) -+{ -+ if (iface == PHY_INTERFACE_MODE_10GBASER || -+ iface == PHY_INTERFACE_MODE_2500BASEX || -+ iface == PHY_INTERFACE_MODE_NA) -+ return RATE_MATCH_PAUSE; -+ return RATE_MATCH_NONE; -+} -+ -+static int aqr107_suspend(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, -+ MDIO_CTRL1_LPOWER); -+ if (err) -+ return err; -+ -+ return aqr107_wait_processor_intensive_op(phydev); -+} -+ -+static int aqr107_resume(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, -+ MDIO_CTRL1_LPOWER); -+ if (err) -+ return err; -+ -+ return aqr107_wait_processor_intensive_op(phydev); -+} -+ -+static int aqr107_probe(struct phy_device *phydev) -+{ -+ phydev->priv = devm_kzalloc(&phydev->mdio.dev, -+ sizeof(struct aqr107_priv), GFP_KERNEL); -+ if (!phydev->priv) -+ return -ENOMEM; -+ -+ return aqr_hwmon_probe(phydev); -+} -+ -+static struct phy_driver aqr_driver[] = { -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQ1202), -+ .name = "Aquantia AQ1202", -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr_read_status, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQ2104), -+ .name = "Aquantia AQ2104", -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr_read_status, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR105), -+ .name = "Aquantia AQR105", -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr_read_status, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR106), -+ .name = "Aquantia AQR106", -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr_read_status, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR107), -+ .name = "Aquantia AQR107", -+ .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, -+ .config_init = aqr107_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQCS109), -+ .name = "Aquantia AQCS109", -+ .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, -+ .config_init = aqcs109_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR405), -+ .name = "Aquantia AQR405", -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr_read_status, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C), -+ .name = "Aquantia AQR113C", -+ .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, -+ .config_init = aqr107_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+}; -+ -+module_phy_driver(aqr_driver); -+ -+static struct mdio_device_id __maybe_unused aqr_tbl[] = { -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(mdio, aqr_tbl); -+ -+MODULE_DESCRIPTION("Aquantia PHY driver"); -+MODULE_AUTHOR("Shaohui Xie "); -+MODULE_LICENSE("GPL v2"); ---- a/drivers/net/phy/aquantia_hwmon.c -+++ /dev/null -@@ -1,250 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* HWMON driver for Aquantia PHY -- * -- * Author: Nikita Yushchenko -- * Author: Andrew Lunn -- * Author: Heiner Kallweit -- */ -- --#include --#include --#include --#include -- --#include "aquantia.h" -- --/* Vendor specific 1, MDIO_MMD_VEND2 */ --#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421 --#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422 --#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423 --#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424 --#define VEND1_THERMAL_STAT1 0xc820 --#define VEND1_THERMAL_STAT2 0xc821 --#define VEND1_THERMAL_STAT2_VALID BIT(0) --#define VEND1_GENERAL_STAT1 0xc830 --#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14) --#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13) --#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12) --#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11) -- --#if IS_REACHABLE(CONFIG_HWMON) -- --static umode_t aqr_hwmon_is_visible(const void *data, -- enum hwmon_sensor_types type, -- u32 attr, int channel) --{ -- if (type != hwmon_temp) -- return 0; -- -- switch (attr) { -- case hwmon_temp_input: -- case hwmon_temp_min_alarm: -- case hwmon_temp_max_alarm: -- case hwmon_temp_lcrit_alarm: -- case hwmon_temp_crit_alarm: -- return 0444; -- case hwmon_temp_min: -- case hwmon_temp_max: -- case hwmon_temp_lcrit: -- case hwmon_temp_crit: -- return 0644; -- default: -- return 0; -- } --} -- --static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value) --{ -- int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg); -- -- if (temp < 0) -- return temp; -- -- /* 16 bit value is 2's complement with LSB = 1/256th degree Celsius */ -- *value = (s16)temp * 1000 / 256; -- -- return 0; --} -- --static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value) --{ -- int temp; -- -- if (value >= 128000 || value < -128000) -- return -ERANGE; -- -- temp = value * 256 / 1000; -- -- /* temp is in s16 range and we're interested in lower 16 bits only */ -- return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, (u16)temp); --} -- --static int aqr_hwmon_test_bit(struct phy_device *phydev, int reg, int bit) --{ -- int val = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg); -- -- if (val < 0) -- return val; -- -- return !!(val & bit); --} -- --static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value) --{ -- int val = aqr_hwmon_test_bit(phydev, VEND1_GENERAL_STAT1, bit); -- -- if (val < 0) -- return val; -- -- *value = val; -- -- return 0; --} -- --static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type, -- u32 attr, int channel, long *value) --{ -- struct phy_device *phydev = dev_get_drvdata(dev); -- int reg; -- -- if (type != hwmon_temp) -- return -EOPNOTSUPP; -- -- switch (attr) { -- case hwmon_temp_input: -- reg = aqr_hwmon_test_bit(phydev, VEND1_THERMAL_STAT2, -- VEND1_THERMAL_STAT2_VALID); -- if (reg < 0) -- return reg; -- if (!reg) -- return -EBUSY; -- -- return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value); -- -- case hwmon_temp_lcrit: -- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL, -- value); -- case hwmon_temp_min: -- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN, -- value); -- case hwmon_temp_max: -- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN, -- value); -- case hwmon_temp_crit: -- return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL, -- value); -- case hwmon_temp_lcrit_alarm: -- return aqr_hwmon_status1(phydev, -- VEND1_GENERAL_STAT1_LOW_TEMP_FAIL, -- value); -- case hwmon_temp_min_alarm: -- return aqr_hwmon_status1(phydev, -- VEND1_GENERAL_STAT1_LOW_TEMP_WARN, -- value); -- case hwmon_temp_max_alarm: -- return aqr_hwmon_status1(phydev, -- VEND1_GENERAL_STAT1_HIGH_TEMP_WARN, -- value); -- case hwmon_temp_crit_alarm: -- return aqr_hwmon_status1(phydev, -- VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL, -- value); -- default: -- return -EOPNOTSUPP; -- } --} -- --static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type, -- u32 attr, int channel, long value) --{ -- struct phy_device *phydev = dev_get_drvdata(dev); -- -- if (type != hwmon_temp) -- return -EOPNOTSUPP; -- -- switch (attr) { -- case hwmon_temp_lcrit: -- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL, -- value); -- case hwmon_temp_min: -- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN, -- value); -- case hwmon_temp_max: -- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN, -- value); -- case hwmon_temp_crit: -- return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL, -- value); -- default: -- return -EOPNOTSUPP; -- } --} -- --static const struct hwmon_ops aqr_hwmon_ops = { -- .is_visible = aqr_hwmon_is_visible, -- .read = aqr_hwmon_read, -- .write = aqr_hwmon_write, --}; -- --static u32 aqr_hwmon_chip_config[] = { -- HWMON_C_REGISTER_TZ, -- 0, --}; -- --static const struct hwmon_channel_info aqr_hwmon_chip = { -- .type = hwmon_chip, -- .config = aqr_hwmon_chip_config, --}; -- --static u32 aqr_hwmon_temp_config[] = { -- HWMON_T_INPUT | -- HWMON_T_MAX | HWMON_T_MIN | -- HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM | -- HWMON_T_CRIT | HWMON_T_LCRIT | -- HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM, -- 0, --}; -- --static const struct hwmon_channel_info aqr_hwmon_temp = { -- .type = hwmon_temp, -- .config = aqr_hwmon_temp_config, --}; -- --static const struct hwmon_channel_info *aqr_hwmon_info[] = { -- &aqr_hwmon_chip, -- &aqr_hwmon_temp, -- NULL, --}; -- --static const struct hwmon_chip_info aqr_hwmon_chip_info = { -- .ops = &aqr_hwmon_ops, -- .info = aqr_hwmon_info, --}; -- --int aqr_hwmon_probe(struct phy_device *phydev) --{ -- struct device *dev = &phydev->mdio.dev; -- struct device *hwmon_dev; -- char *hwmon_name; -- int i, j; -- -- hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL); -- if (!hwmon_name) -- return -ENOMEM; -- -- for (i = j = 0; hwmon_name[i]; i++) { -- if (isalnum(hwmon_name[i])) { -- if (i != j) -- hwmon_name[j] = hwmon_name[i]; -- j++; -- } -- } -- hwmon_name[j] = '\0'; -- -- hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name, -- phydev, &aqr_hwmon_chip_info, NULL); -- -- return PTR_ERR_OR_ZERO(hwmon_dev); --} -- --#endif ---- a/drivers/net/phy/aquantia_main.c -+++ /dev/null -@@ -1,842 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --/* -- * Driver for Aquantia PHY -- * -- * Author: Shaohui Xie -- * -- * Copyright 2015 Freescale Semiconductor, Inc. -- */ -- --#include --#include --#include --#include --#include -- --#include "aquantia.h" -- --#define PHY_ID_AQ1202 0x03a1b445 --#define PHY_ID_AQ2104 0x03a1b460 --#define PHY_ID_AQR105 0x03a1b4a2 --#define PHY_ID_AQR106 0x03a1b4d0 --#define PHY_ID_AQR107 0x03a1b4e0 --#define PHY_ID_AQCS109 0x03a1b5c2 --#define PHY_ID_AQR405 0x03a1b4b0 --#define PHY_ID_AQR113C 0x31c31c12 -- --#define MDIO_PHYXS_VEND_IF_STATUS 0xe812 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX 1 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII 3 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI 4 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7 --#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10 -- --#define MDIO_AN_VEND_PROV 0xc400 --#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) --#define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) --#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11) --#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10) --#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4) --#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0) --#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4 -- --#define MDIO_AN_TX_VEND_STATUS1 0xc800 --#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1) --#define MDIO_AN_TX_VEND_STATUS1_10BASET 0 --#define MDIO_AN_TX_VEND_STATUS1_100BASETX 1 --#define MDIO_AN_TX_VEND_STATUS1_1000BASET 2 --#define MDIO_AN_TX_VEND_STATUS1_10GBASET 3 --#define MDIO_AN_TX_VEND_STATUS1_2500BASET 4 --#define MDIO_AN_TX_VEND_STATUS1_5000BASET 5 --#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX BIT(0) -- --#define MDIO_AN_TX_VEND_INT_STATUS1 0xcc00 --#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT BIT(1) -- --#define MDIO_AN_TX_VEND_INT_STATUS2 0xcc01 --#define MDIO_AN_TX_VEND_INT_STATUS2_MASK BIT(0) -- --#define MDIO_AN_TX_VEND_INT_MASK2 0xd401 --#define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0) -- --#define MDIO_AN_RX_LP_STAT1 0xe820 --#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15) --#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14) --#define MDIO_AN_RX_LP_STAT1_SHORT_REACH BIT(13) --#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT BIT(12) --#define MDIO_AN_RX_LP_STAT1_AQ_PHY BIT(2) -- --#define MDIO_AN_RX_LP_STAT4 0xe823 --#define MDIO_AN_RX_LP_STAT4_FW_MAJOR GENMASK(15, 8) --#define MDIO_AN_RX_LP_STAT4_FW_MINOR GENMASK(7, 0) -- --#define MDIO_AN_RX_VEND_STAT3 0xe832 --#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0) -- --/* MDIO_MMD_C22EXT */ --#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292 --#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294 --#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297 --#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313 --#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315 --#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317 --#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318 --#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319 --#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a --#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b -- --/* Vendor specific 1, MDIO_MMD_VEND1 */ --#define VEND1_GLOBAL_FW_ID 0x0020 --#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) --#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) -- --#define VEND1_GLOBAL_GEN_STAT2 0xc831 --#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15) -- --/* The following registers all have similar layouts; first the registers... */ --#define VEND1_GLOBAL_CFG_10M 0x0310 --#define VEND1_GLOBAL_CFG_100M 0x031b --#define VEND1_GLOBAL_CFG_1G 0x031c --#define VEND1_GLOBAL_CFG_2_5G 0x031d --#define VEND1_GLOBAL_CFG_5G 0x031e --#define VEND1_GLOBAL_CFG_10G 0x031f --/* ...and now the fields */ --#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7) --#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0 --#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1 --#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 -- --#define VEND1_GLOBAL_RSVD_STAT1 0xc885 --#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4) --#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0) -- --#define VEND1_GLOBAL_RSVD_STAT9 0xc88d --#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0) --#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23 -- --#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00 --#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01 -- --#define VEND1_GLOBAL_INT_STD_MASK 0xff00 --#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15) --#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14) --#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13) --#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12) --#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11) --#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10) --#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9) --#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8) --#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7) --#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6) --#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0) -- --#define VEND1_GLOBAL_INT_VEND_MASK 0xff01 --#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15) --#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14) --#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13) --#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12) --#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0) -- --/* Sleep and timeout for checking if the Processor-Intensive -- * MDIO operation is finished -- */ --#define AQR107_OP_IN_PROG_SLEEP 1000 --#define AQR107_OP_IN_PROG_TIMEOUT 100000 -- --struct aqr107_hw_stat { -- const char *name; -- int reg; -- int size; --}; -- --#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s } --static const struct aqr107_hw_stat aqr107_hw_stats[] = { -- SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26), -- SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26), -- SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8), -- SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26), -- SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26), -- SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8), -- SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8), -- SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8), -- SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16), -- SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22), --}; --#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats) -- --struct aqr107_priv { -- u64 sgmii_stats[AQR107_SGMII_STAT_SZ]; --}; -- --static int aqr107_get_sset_count(struct phy_device *phydev) --{ -- return AQR107_SGMII_STAT_SZ; --} -- --static void aqr107_get_strings(struct phy_device *phydev, u8 *data) --{ -- int i; -- -- for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) -- strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name, -- ETH_GSTRING_LEN); --} -- --static u64 aqr107_get_stat(struct phy_device *phydev, int index) --{ -- const struct aqr107_hw_stat *stat = aqr107_hw_stats + index; -- int len_l = min(stat->size, 16); -- int len_h = stat->size - len_l; -- u64 ret; -- int val; -- -- val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg); -- if (val < 0) -- return U64_MAX; -- -- ret = val & GENMASK(len_l - 1, 0); -- if (len_h) { -- val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1); -- if (val < 0) -- return U64_MAX; -- -- ret += (val & GENMASK(len_h - 1, 0)) << 16; -- } -- -- return ret; --} -- --static void aqr107_get_stats(struct phy_device *phydev, -- struct ethtool_stats *stats, u64 *data) --{ -- struct aqr107_priv *priv = phydev->priv; -- u64 val; -- int i; -- -- for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) { -- val = aqr107_get_stat(phydev, i); -- if (val == U64_MAX) -- phydev_err(phydev, "Reading HW Statistics failed for %s\n", -- aqr107_hw_stats[i].name); -- else -- priv->sgmii_stats[i] += val; -- -- data[i] = priv->sgmii_stats[i]; -- } --} -- --static int aqr_config_aneg(struct phy_device *phydev) --{ -- bool changed = false; -- u16 reg; -- int ret; -- -- if (phydev->autoneg == AUTONEG_DISABLE) -- return genphy_c45_pma_setup_forced(phydev); -- -- ret = genphy_c45_an_config_aneg(phydev); -- if (ret < 0) -- return ret; -- if (ret > 0) -- changed = true; -- -- /* Clause 45 has no standardized support for 1000BaseT, therefore -- * use vendor registers for this mode. -- */ -- reg = 0; -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -- phydev->advertising)) -- reg |= MDIO_AN_VEND_PROV_1000BASET_FULL; -- -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -- phydev->advertising)) -- reg |= MDIO_AN_VEND_PROV_1000BASET_HALF; -- -- /* Handle the case when the 2.5G and 5G speeds are not advertised */ -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -- phydev->advertising)) -- reg |= MDIO_AN_VEND_PROV_2500BASET_FULL; -- -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, -- phydev->advertising)) -- reg |= MDIO_AN_VEND_PROV_5000BASET_FULL; -- -- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, -- MDIO_AN_VEND_PROV_1000BASET_HALF | -- MDIO_AN_VEND_PROV_1000BASET_FULL | -- MDIO_AN_VEND_PROV_2500BASET_FULL | -- MDIO_AN_VEND_PROV_5000BASET_FULL, reg); -- if (ret < 0) -- return ret; -- if (ret > 0) -- changed = true; -- -- return genphy_c45_check_and_restart_aneg(phydev, changed); --} -- --static int aqr_config_intr(struct phy_device *phydev) --{ -- bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED; -- int err; -- -- if (en) { -- /* Clear any pending interrupts before enabling them */ -- err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2); -- if (err < 0) -- return err; -- } -- -- err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2, -- en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0); -- if (err < 0) -- return err; -- -- err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK, -- en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0); -- if (err < 0) -- return err; -- -- err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK, -- en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 | -- VEND1_GLOBAL_INT_VEND_MASK_AN : 0); -- if (err < 0) -- return err; -- -- if (!en) { -- /* Clear any pending interrupts after we have disabled them */ -- err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2); -- if (err < 0) -- return err; -- } -- -- return 0; --} -- --static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev) --{ -- int irq_status; -- -- irq_status = phy_read_mmd(phydev, MDIO_MMD_AN, -- MDIO_AN_TX_VEND_INT_STATUS2); -- if (irq_status < 0) { -- phy_error(phydev); -- return IRQ_NONE; -- } -- -- if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK)) -- return IRQ_NONE; -- -- phy_trigger_machine(phydev); -- -- return IRQ_HANDLED; --} -- --static int aqr_read_status(struct phy_device *phydev) --{ -- int val; -- -- if (phydev->autoneg == AUTONEG_ENABLE) { -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1); -- if (val < 0) -- return val; -- -- linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -- phydev->lp_advertising, -- val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL); -- linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -- phydev->lp_advertising, -- val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF); -- } -- -- return genphy_c45_read_status(phydev); --} -- --static int aqr107_read_rate(struct phy_device *phydev) --{ -- u32 config_reg; -- int val; -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1); -- if (val < 0) -- return val; -- -- if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX) -- phydev->duplex = DUPLEX_FULL; -- else -- phydev->duplex = DUPLEX_HALF; -- -- switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) { -- case MDIO_AN_TX_VEND_STATUS1_10BASET: -- phydev->speed = SPEED_10; -- config_reg = VEND1_GLOBAL_CFG_10M; -- break; -- case MDIO_AN_TX_VEND_STATUS1_100BASETX: -- phydev->speed = SPEED_100; -- config_reg = VEND1_GLOBAL_CFG_100M; -- break; -- case MDIO_AN_TX_VEND_STATUS1_1000BASET: -- phydev->speed = SPEED_1000; -- config_reg = VEND1_GLOBAL_CFG_1G; -- break; -- case MDIO_AN_TX_VEND_STATUS1_2500BASET: -- phydev->speed = SPEED_2500; -- config_reg = VEND1_GLOBAL_CFG_2_5G; -- break; -- case MDIO_AN_TX_VEND_STATUS1_5000BASET: -- phydev->speed = SPEED_5000; -- config_reg = VEND1_GLOBAL_CFG_5G; -- break; -- case MDIO_AN_TX_VEND_STATUS1_10GBASET: -- phydev->speed = SPEED_10000; -- config_reg = VEND1_GLOBAL_CFG_10G; -- break; -- default: -- phydev->speed = SPEED_UNKNOWN; -- return 0; -- } -- -- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg); -- if (val < 0) -- return val; -- -- if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) == -- VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE) -- phydev->rate_matching = RATE_MATCH_PAUSE; -- else -- phydev->rate_matching = RATE_MATCH_NONE; -- -- return 0; --} -- --static int aqr107_read_status(struct phy_device *phydev) --{ -- int val, ret; -- -- ret = aqr_read_status(phydev); -- if (ret) -- return ret; -- -- if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE) -- return 0; -- -- val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS); -- if (val < 0) -- return val; -- -- switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) { -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR: -- phydev->interface = PHY_INTERFACE_MODE_10GKR; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX: -- phydev->interface = PHY_INTERFACE_MODE_1000BASEKX; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI: -- phydev->interface = PHY_INTERFACE_MODE_10GBASER; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII: -- phydev->interface = PHY_INTERFACE_MODE_USXGMII; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI: -- phydev->interface = PHY_INTERFACE_MODE_XAUI; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII: -- phydev->interface = PHY_INTERFACE_MODE_SGMII; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI: -- phydev->interface = PHY_INTERFACE_MODE_RXAUI; -- break; -- case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII: -- phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -- break; -- default: -- phydev->interface = PHY_INTERFACE_MODE_NA; -- break; -- } -- -- /* Read possibly downshifted rate from vendor register */ -- return aqr107_read_rate(phydev); --} -- --static int aqr107_get_downshift(struct phy_device *phydev, u8 *data) --{ -- int val, cnt, enable; -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV); -- if (val < 0) -- return val; -- -- enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val); -- cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val); -- -- *data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE; -- -- return 0; --} -- --static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt) --{ -- int val = 0; -- -- if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt)) -- return -E2BIG; -- -- if (cnt != DOWNSHIFT_DEV_DISABLE) { -- val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN; -- val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt); -- } -- -- return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, -- MDIO_AN_VEND_PROV_DOWNSHIFT_EN | -- MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val); --} -- --static int aqr107_get_tunable(struct phy_device *phydev, -- struct ethtool_tunable *tuna, void *data) --{ -- switch (tuna->id) { -- case ETHTOOL_PHY_DOWNSHIFT: -- return aqr107_get_downshift(phydev, data); -- default: -- return -EOPNOTSUPP; -- } --} -- --static int aqr107_set_tunable(struct phy_device *phydev, -- struct ethtool_tunable *tuna, const void *data) --{ -- switch (tuna->id) { -- case ETHTOOL_PHY_DOWNSHIFT: -- return aqr107_set_downshift(phydev, *(const u8 *)data); -- default: -- return -EOPNOTSUPP; -- } --} -- --/* If we configure settings whilst firmware is still initializing the chip, -- * then these settings may be overwritten. Therefore make sure chip -- * initialization has completed. Use presence of the firmware ID as -- * indicator for initialization having completed. -- * The chip also provides a "reset completed" bit, but it's cleared after -- * read. Therefore function would time out if called again. -- */ --static int aqr107_wait_reset_complete(struct phy_device *phydev) --{ -- int val; -- -- return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -- VEND1_GLOBAL_FW_ID, val, val != 0, -- 20000, 2000000, false); --} -- --static void aqr107_chip_info(struct phy_device *phydev) --{ -- u8 fw_major, fw_minor, build_id, prov_id; -- int val; -- -- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID); -- if (val < 0) -- return; -- -- fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val); -- fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val); -- -- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1); -- if (val < 0) -- return; -- -- build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val); -- prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val); -- -- phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n", -- fw_major, fw_minor, build_id, prov_id); --} -- --static int aqr107_config_init(struct phy_device *phydev) --{ -- int ret; -- -- /* Check that the PHY interface type is compatible */ -- if (phydev->interface != PHY_INTERFACE_MODE_SGMII && -- phydev->interface != PHY_INTERFACE_MODE_1000BASEKX && -- phydev->interface != PHY_INTERFACE_MODE_2500BASEX && -- phydev->interface != PHY_INTERFACE_MODE_XGMII && -- phydev->interface != PHY_INTERFACE_MODE_USXGMII && -- phydev->interface != PHY_INTERFACE_MODE_10GKR && -- phydev->interface != PHY_INTERFACE_MODE_10GBASER && -- phydev->interface != PHY_INTERFACE_MODE_XAUI && -- phydev->interface != PHY_INTERFACE_MODE_RXAUI) -- return -ENODEV; -- -- WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII, -- "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n"); -- -- ret = aqr107_wait_reset_complete(phydev); -- if (!ret) -- aqr107_chip_info(phydev); -- -- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); --} -- --static int aqcs109_config_init(struct phy_device *phydev) --{ -- int ret; -- -- /* Check that the PHY interface type is compatible */ -- if (phydev->interface != PHY_INTERFACE_MODE_SGMII && -- phydev->interface != PHY_INTERFACE_MODE_2500BASEX) -- return -ENODEV; -- -- ret = aqr107_wait_reset_complete(phydev); -- if (!ret) -- aqr107_chip_info(phydev); -- -- /* AQCS109 belongs to a chip family partially supporting 10G and 5G. -- * PMA speed ability bits are the same for all members of the family, -- * AQCS109 however supports speeds up to 2.5G only. -- */ -- phy_set_max_speed(phydev, SPEED_2500); -- -- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); --} -- --static void aqr107_link_change_notify(struct phy_device *phydev) --{ -- u8 fw_major, fw_minor; -- bool downshift, short_reach, afr; -- int mode, val; -- -- if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE) -- return; -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1); -- /* call failed or link partner is no Aquantia PHY */ -- if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY)) -- return; -- -- short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH; -- downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT; -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4); -- if (val < 0) -- return; -- -- fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val); -- fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val); -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3); -- if (val < 0) -- return; -- -- afr = val & MDIO_AN_RX_VEND_STAT3_AFR; -- -- phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n", -- fw_major, fw_minor, -- short_reach ? ", short reach mode" : "", -- downshift ? ", fast-retrain downshift advertised" : "", -- afr ? ", fast reframe advertised" : ""); -- -- val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT9); -- if (val < 0) -- return; -- -- mode = FIELD_GET(VEND1_GLOBAL_RSVD_STAT9_MODE, val); -- if (mode == VEND1_GLOBAL_RSVD_STAT9_1000BT2) -- phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n"); --} -- --static int aqr107_wait_processor_intensive_op(struct phy_device *phydev) --{ -- int val, err; -- -- /* The datasheet notes to wait at least 1ms after issuing a -- * processor intensive operation before checking. -- * We cannot use the 'sleep_before_read' parameter of read_poll_timeout -- * because that just determines the maximum time slept, not the minimum. -- */ -- usleep_range(1000, 5000); -- -- err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -- VEND1_GLOBAL_GEN_STAT2, val, -- !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG), -- AQR107_OP_IN_PROG_SLEEP, -- AQR107_OP_IN_PROG_TIMEOUT, false); -- if (err) { -- phydev_err(phydev, "timeout: processor-intensive MDIO operation\n"); -- return err; -- } -- -- return 0; --} -- --static int aqr107_get_rate_matching(struct phy_device *phydev, -- phy_interface_t iface) --{ -- if (iface == PHY_INTERFACE_MODE_10GBASER || -- iface == PHY_INTERFACE_MODE_2500BASEX || -- iface == PHY_INTERFACE_MODE_NA) -- return RATE_MATCH_PAUSE; -- return RATE_MATCH_NONE; --} -- --static int aqr107_suspend(struct phy_device *phydev) --{ -- int err; -- -- err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, -- MDIO_CTRL1_LPOWER); -- if (err) -- return err; -- -- return aqr107_wait_processor_intensive_op(phydev); --} -- --static int aqr107_resume(struct phy_device *phydev) --{ -- int err; -- -- err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1, -- MDIO_CTRL1_LPOWER); -- if (err) -- return err; -- -- return aqr107_wait_processor_intensive_op(phydev); --} -- --static int aqr107_probe(struct phy_device *phydev) --{ -- phydev->priv = devm_kzalloc(&phydev->mdio.dev, -- sizeof(struct aqr107_priv), GFP_KERNEL); -- if (!phydev->priv) -- return -ENOMEM; -- -- return aqr_hwmon_probe(phydev); --} -- --static struct phy_driver aqr_driver[] = { --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQ1202), -- .name = "Aquantia AQ1202", -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr_read_status, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQ2104), -- .name = "Aquantia AQ2104", -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr_read_status, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQR105), -- .name = "Aquantia AQR105", -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr_read_status, -- .suspend = aqr107_suspend, -- .resume = aqr107_resume, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQR106), -- .name = "Aquantia AQR106", -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr_read_status, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQR107), -- .name = "Aquantia AQR107", -- .probe = aqr107_probe, -- .get_rate_matching = aqr107_get_rate_matching, -- .config_init = aqr107_config_init, -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr107_read_status, -- .get_tunable = aqr107_get_tunable, -- .set_tunable = aqr107_set_tunable, -- .suspend = aqr107_suspend, -- .resume = aqr107_resume, -- .get_sset_count = aqr107_get_sset_count, -- .get_strings = aqr107_get_strings, -- .get_stats = aqr107_get_stats, -- .link_change_notify = aqr107_link_change_notify, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQCS109), -- .name = "Aquantia AQCS109", -- .probe = aqr107_probe, -- .get_rate_matching = aqr107_get_rate_matching, -- .config_init = aqcs109_config_init, -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr107_read_status, -- .get_tunable = aqr107_get_tunable, -- .set_tunable = aqr107_set_tunable, -- .suspend = aqr107_suspend, -- .resume = aqr107_resume, -- .get_sset_count = aqr107_get_sset_count, -- .get_strings = aqr107_get_strings, -- .get_stats = aqr107_get_stats, -- .link_change_notify = aqr107_link_change_notify, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQR405), -- .name = "Aquantia AQR405", -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr_read_status, --}, --{ -- PHY_ID_MATCH_MODEL(PHY_ID_AQR113C), -- .name = "Aquantia AQR113C", -- .probe = aqr107_probe, -- .get_rate_matching = aqr107_get_rate_matching, -- .config_init = aqr107_config_init, -- .config_aneg = aqr_config_aneg, -- .config_intr = aqr_config_intr, -- .handle_interrupt = aqr_handle_interrupt, -- .read_status = aqr107_read_status, -- .get_tunable = aqr107_get_tunable, -- .set_tunable = aqr107_set_tunable, -- .suspend = aqr107_suspend, -- .resume = aqr107_resume, -- .get_sset_count = aqr107_get_sset_count, -- .get_strings = aqr107_get_strings, -- .get_stats = aqr107_get_stats, -- .link_change_notify = aqr107_link_change_notify, --}, --}; -- --module_phy_driver(aqr_driver); -- --static struct mdio_device_id __maybe_unused aqr_tbl[] = { -- { PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQR105) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQR106) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, -- { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, -- { } --}; -- --MODULE_DEVICE_TABLE(mdio, aqr_tbl); -- --MODULE_DESCRIPTION("Aquantia PHY driver"); --MODULE_AUTHOR("Shaohui Xie "); --MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/backport-6.1/702-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch b/target/linux/generic/backport-6.1/702-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch deleted file mode 100644 index 2b945227237762..00000000000000 --- a/target/linux/generic/backport-6.1/702-02-v6.7-net-phy-aquantia-move-MMD_VEND-define-to-header.patch +++ /dev/null @@ -1,183 +0,0 @@ -From e1fbfa4a995d42e02e22b0dff2f8b4fdee1504b3 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 14 Nov 2023 15:08:42 +0100 -Subject: [PATCH 2/3] net: phy: aquantia: move MMD_VEND define to header - -Move MMD_VEND define to header to clean things up and in preparation for -firmware loading support that require some define placed in -aquantia_main. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/aquantia/aquantia.h | 69 +++++++++++++++++++++++ - drivers/net/phy/aquantia/aquantia_hwmon.c | 14 ----- - drivers/net/phy/aquantia/aquantia_main.c | 55 ------------------ - 3 files changed, 69 insertions(+), 69 deletions(-) - ---- a/drivers/net/phy/aquantia/aquantia.h -+++ b/drivers/net/phy/aquantia/aquantia.h -@@ -9,6 +9,75 @@ - #include - #include - -+/* Vendor specific 1, MDIO_MMD_VEND1 */ -+#define VEND1_GLOBAL_FW_ID 0x0020 -+#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) -+#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) -+ -+/* The following registers all have similar layouts; first the registers... */ -+#define VEND1_GLOBAL_CFG_10M 0x0310 -+#define VEND1_GLOBAL_CFG_100M 0x031b -+#define VEND1_GLOBAL_CFG_1G 0x031c -+#define VEND1_GLOBAL_CFG_2_5G 0x031d -+#define VEND1_GLOBAL_CFG_5G 0x031e -+#define VEND1_GLOBAL_CFG_10G 0x031f -+/* ...and now the fields */ -+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7) -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0 -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1 -+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 -+ -+/* Vendor specific 1, MDIO_MMD_VEND2 */ -+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421 -+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422 -+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423 -+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424 -+#define VEND1_THERMAL_STAT1 0xc820 -+#define VEND1_THERMAL_STAT2 0xc821 -+#define VEND1_THERMAL_STAT2_VALID BIT(0) -+#define VEND1_GENERAL_STAT1 0xc830 -+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14) -+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13) -+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12) -+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11) -+ -+#define VEND1_GLOBAL_GEN_STAT2 0xc831 -+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15) -+ -+#define VEND1_GLOBAL_RSVD_STAT1 0xc885 -+#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4) -+#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0) -+ -+#define VEND1_GLOBAL_RSVD_STAT9 0xc88d -+#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0) -+#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23 -+ -+#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00 -+#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01 -+ -+#define VEND1_GLOBAL_INT_STD_MASK 0xff00 -+#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15) -+#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12) -+#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11) -+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10) -+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9) -+#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8) -+#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7) -+#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6) -+#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0) -+ -+#define VEND1_GLOBAL_INT_VEND_MASK 0xff01 -+#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15) -+#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14) -+#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13) -+#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12) -+#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1) -+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0) -+ - #if IS_REACHABLE(CONFIG_HWMON) - int aqr_hwmon_probe(struct phy_device *phydev); - #else ---- a/drivers/net/phy/aquantia/aquantia_hwmon.c -+++ b/drivers/net/phy/aquantia/aquantia_hwmon.c -@@ -13,20 +13,6 @@ - - #include "aquantia.h" - --/* Vendor specific 1, MDIO_MMD_VEND2 */ --#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421 --#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422 --#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423 --#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424 --#define VEND1_THERMAL_STAT1 0xc820 --#define VEND1_THERMAL_STAT2 0xc821 --#define VEND1_THERMAL_STAT2_VALID BIT(0) --#define VEND1_GENERAL_STAT1 0xc830 --#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14) --#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13) --#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12) --#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11) -- - #if IS_REACHABLE(CONFIG_HWMON) - - static umode_t aqr_hwmon_is_visible(const void *data, ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -89,61 +89,6 @@ - #define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a - #define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b - --/* Vendor specific 1, MDIO_MMD_VEND1 */ --#define VEND1_GLOBAL_FW_ID 0x0020 --#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) --#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) -- --#define VEND1_GLOBAL_GEN_STAT2 0xc831 --#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15) -- --/* The following registers all have similar layouts; first the registers... */ --#define VEND1_GLOBAL_CFG_10M 0x0310 --#define VEND1_GLOBAL_CFG_100M 0x031b --#define VEND1_GLOBAL_CFG_1G 0x031c --#define VEND1_GLOBAL_CFG_2_5G 0x031d --#define VEND1_GLOBAL_CFG_5G 0x031e --#define VEND1_GLOBAL_CFG_10G 0x031f --/* ...and now the fields */ --#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7) --#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0 --#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1 --#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 -- --#define VEND1_GLOBAL_RSVD_STAT1 0xc885 --#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4) --#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0) -- --#define VEND1_GLOBAL_RSVD_STAT9 0xc88d --#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0) --#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23 -- --#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00 --#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01 -- --#define VEND1_GLOBAL_INT_STD_MASK 0xff00 --#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15) --#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14) --#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13) --#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12) --#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11) --#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10) --#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9) --#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8) --#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7) --#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6) --#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0) -- --#define VEND1_GLOBAL_INT_VEND_MASK 0xff01 --#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15) --#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14) --#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13) --#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12) --#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1) --#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0) -- - /* Sleep and timeout for checking if the Processor-Intensive - * MDIO operation is finished - */ diff --git a/target/linux/generic/backport-6.1/702-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch b/target/linux/generic/backport-6.1/702-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch deleted file mode 100644 index aa52b3baa64ca5..00000000000000 --- a/target/linux/generic/backport-6.1/702-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch +++ /dev/null @@ -1,504 +0,0 @@ -From e93984ebc1c82bd34f7a1b3391efaceee0a8ae96 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Tue, 14 Nov 2023 15:08:43 +0100 -Subject: [PATCH 3/3] net: phy: aquantia: add firmware load support - -Aquantia PHY-s require firmware to be loaded before they start operating. -It can be automatically loaded in case when there is a SPI-NOR connected -to Aquantia PHY-s or can be loaded from the host via MDIO. - -This patch adds support for loading the firmware via MDIO as in most cases -there is no SPI-NOR being used to save on cost. -Firmware loading code itself is ported from mainline U-boot with cleanups. - -The firmware has mixed values both in big and little endian. -PHY core itself is big-endian but it expects values to be in little-endian. -The firmware is little-endian but CRC-16 value for it is stored at the end -of firmware in big-endian. - -It seems the PHY does the conversion internally from firmware that is -little-endian to the PHY that is big-endian on using the mailbox -but mailbox returns a big-endian CRC-16 to verify the written data -integrity. - -Co-developed-by: Christian Marangi -Signed-off-by: Robert Marko -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/aquantia/Kconfig | 1 + - drivers/net/phy/aquantia/Makefile | 2 +- - drivers/net/phy/aquantia/aquantia.h | 32 ++ - drivers/net/phy/aquantia/aquantia_firmware.c | 370 +++++++++++++++++++ - drivers/net/phy/aquantia/aquantia_main.c | 6 + - 5 files changed, 410 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/phy/aquantia/aquantia_firmware.c - ---- a/drivers/net/phy/aquantia/Kconfig -+++ b/drivers/net/phy/aquantia/Kconfig -@@ -1,5 +1,6 @@ - # SPDX-License-Identifier: GPL-2.0-only - config AQUANTIA_PHY - tristate "Aquantia PHYs" -+ select CRC_CCITT - help - Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405 ---- a/drivers/net/phy/aquantia/Makefile -+++ b/drivers/net/phy/aquantia/Makefile -@@ -1,5 +1,5 @@ - # SPDX-License-Identifier: GPL-2.0 --aquantia-objs += aquantia_main.o -+aquantia-objs += aquantia_main.o aquantia_firmware.o - ifdef CONFIG_HWMON - aquantia-objs += aquantia_hwmon.o - endif ---- a/drivers/net/phy/aquantia/aquantia.h -+++ b/drivers/net/phy/aquantia/aquantia.h -@@ -10,10 +10,35 @@ - #include - - /* Vendor specific 1, MDIO_MMD_VEND1 */ -+#define VEND1_GLOBAL_SC 0x0 -+#define VEND1_GLOBAL_SC_SOFT_RESET BIT(15) -+#define VEND1_GLOBAL_SC_LOW_POWER BIT(11) -+ - #define VEND1_GLOBAL_FW_ID 0x0020 - #define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8) - #define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0) - -+#define VEND1_GLOBAL_MAILBOX_INTERFACE1 0x0200 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE BIT(15) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE BIT(14) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET BIT(12) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_BUSY BIT(8) -+ -+#define VEND1_GLOBAL_MAILBOX_INTERFACE2 0x0201 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE3 0x0202 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK GENMASK(15, 0) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK, (u16)((x) >> 16)) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE4 0x0203 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK GENMASK(15, 2) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK, (u16)(x)) -+ -+#define VEND1_GLOBAL_MAILBOX_INTERFACE5 0x0204 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK GENMASK(15, 0) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK, (u16)((x) >> 16)) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE6 0x0205 -+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK GENMASK(15, 0) -+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK, (u16)(x)) -+ - /* The following registers all have similar layouts; first the registers... */ - #define VEND1_GLOBAL_CFG_10M 0x0310 - #define VEND1_GLOBAL_CFG_100M 0x031b -@@ -28,6 +53,11 @@ - #define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2 - - /* Vendor specific 1, MDIO_MMD_VEND2 */ -+#define VEND1_GLOBAL_CONTROL2 0xc001 -+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST BIT(15) -+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD BIT(6) -+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL BIT(0) -+ - #define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421 - #define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422 - #define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423 -@@ -83,3 +113,5 @@ int aqr_hwmon_probe(struct phy_device *p - #else - static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; } - #endif -+ -+int aqr_firmware_load(struct phy_device *phydev); ---- /dev/null -+++ b/drivers/net/phy/aquantia/aquantia_firmware.c -@@ -0,0 +1,370 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "aquantia.h" -+ -+#define UP_RESET_SLEEP 100 -+ -+/* addresses of memory segments in the phy */ -+#define DRAM_BASE_ADDR 0x3FFE0000 -+#define IRAM_BASE_ADDR 0x40000000 -+ -+/* firmware image format constants */ -+#define VERSION_STRING_SIZE 0x40 -+#define VERSION_STRING_OFFSET 0x0200 -+/* primary offset is written at an offset from the start of the fw blob */ -+#define PRIMARY_OFFSET_OFFSET 0x8 -+/* primary offset needs to be then added to a base offset */ -+#define PRIMARY_OFFSET_SHIFT 12 -+#define PRIMARY_OFFSET(x) ((x) << PRIMARY_OFFSET_SHIFT) -+#define HEADER_OFFSET 0x300 -+ -+struct aqr_fw_header { -+ u32 padding; -+ u8 iram_offset[3]; -+ u8 iram_size[3]; -+ u8 dram_offset[3]; -+ u8 dram_size[3]; -+} __packed; -+ -+enum aqr_fw_src { -+ AQR_FW_SRC_NVMEM = 0, -+ AQR_FW_SRC_FS, -+}; -+ -+static const char * const aqr_fw_src_string[] = { -+ [AQR_FW_SRC_NVMEM] = "NVMEM", -+ [AQR_FW_SRC_FS] = "FS", -+}; -+ -+/* AQR firmware doesn't have fixed offsets for iram and dram section -+ * but instead provide an header with the offset to use on reading -+ * and parsing the firmware. -+ * -+ * AQR firmware can't be trusted and each offset is validated to be -+ * not negative and be in the size of the firmware itself. -+ */ -+static bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size) -+{ -+ return offset + get_size <= size; -+} -+ -+static int aqr_fw_get_be16(const u8 *data, size_t offset, size_t size, u16 *value) -+{ -+ if (!aqr_fw_validate_get(size, offset, sizeof(u16))) -+ return -EINVAL; -+ -+ *value = get_unaligned_be16(data + offset); -+ -+ return 0; -+} -+ -+static int aqr_fw_get_le16(const u8 *data, size_t offset, size_t size, u16 *value) -+{ -+ if (!aqr_fw_validate_get(size, offset, sizeof(u16))) -+ return -EINVAL; -+ -+ *value = get_unaligned_le16(data + offset); -+ -+ return 0; -+} -+ -+static int aqr_fw_get_le24(const u8 *data, size_t offset, size_t size, u32 *value) -+{ -+ if (!aqr_fw_validate_get(size, offset, sizeof(u8) * 3)) -+ return -EINVAL; -+ -+ *value = get_unaligned_le24(data + offset); -+ -+ return 0; -+} -+ -+/* load data into the phy's memory */ -+static int aqr_fw_load_memory(struct phy_device *phydev, u32 addr, -+ const u8 *data, size_t len) -+{ -+ u16 crc = 0, up_crc; -+ size_t pos; -+ -+ /* PHY expect addr in LE */ -+ addr = (__force u32)cpu_to_le32(addr); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_MAILBOX_INTERFACE1, -+ VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET); -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_MAILBOX_INTERFACE3, -+ VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(addr)); -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_MAILBOX_INTERFACE4, -+ VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(addr)); -+ -+ /* We assume and enforce the size to be word aligned. -+ * If a firmware that is not word aligned is found, please report upstream. -+ */ -+ for (pos = 0; pos < len; pos += sizeof(u32)) { -+ u32 word; -+ -+ /* FW data is always stored in little-endian */ -+ word = get_unaligned((const u32 *)(data + pos)); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE5, -+ VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(word)); -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE6, -+ VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(word)); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE1, -+ VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE | -+ VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE); -+ -+ /* calculate CRC as we load data to the mailbox. -+ * We convert word to big-endian as PHY is BE and mailbox will -+ * return a BE CRC. -+ */ -+ word = (__force u32)cpu_to_be32(word); -+ crc = crc_ccitt_false(crc, (u8 *)&word, sizeof(word)); -+ } -+ -+ up_crc = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE2); -+ if (crc != up_crc) { -+ phydev_err(phydev, "CRC mismatch: calculated 0x%04x PHY 0x%04x\n", -+ crc, up_crc); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size, -+ enum aqr_fw_src fw_src) -+{ -+ u16 calculated_crc, read_crc, read_primary_offset; -+ u32 iram_offset = 0, iram_size = 0; -+ u32 dram_offset = 0, dram_size = 0; -+ char version[VERSION_STRING_SIZE]; -+ u32 primary_offset = 0; -+ int ret; -+ -+ /* extract saved CRC at the end of the fw -+ * CRC is saved in big-endian as PHY is BE -+ */ -+ ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc); -+ if (ret) { -+ phydev_err(phydev, "bad firmware CRC in firmware\n"); -+ return ret; -+ } -+ calculated_crc = crc_ccitt_false(0, data, size - sizeof(u16)); -+ if (read_crc != calculated_crc) { -+ phydev_err(phydev, "bad firmware CRC: file 0x%04x calculated 0x%04x\n", -+ read_crc, calculated_crc); -+ return -EINVAL; -+ } -+ -+ /* Get the primary offset to extract DRAM and IRAM sections. */ -+ ret = aqr_fw_get_le16(data, PRIMARY_OFFSET_OFFSET, size, &read_primary_offset); -+ if (ret) { -+ phydev_err(phydev, "bad primary offset in firmware\n"); -+ return ret; -+ } -+ primary_offset = PRIMARY_OFFSET(read_primary_offset); -+ -+ /* Find the DRAM and IRAM sections within the firmware file. -+ * Make sure the fw_header is correctly in the firmware. -+ */ -+ if (!aqr_fw_validate_get(size, primary_offset + HEADER_OFFSET, -+ sizeof(struct aqr_fw_header))) { -+ phydev_err(phydev, "bad fw_header in firmware\n"); -+ return -EINVAL; -+ } -+ -+ /* offset are in LE and values needs to be converted to cpu endian */ -+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET + -+ offsetof(struct aqr_fw_header, iram_offset), -+ size, &iram_offset); -+ if (ret) { -+ phydev_err(phydev, "bad iram offset in firmware\n"); -+ return ret; -+ } -+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET + -+ offsetof(struct aqr_fw_header, iram_size), -+ size, &iram_size); -+ if (ret) { -+ phydev_err(phydev, "invalid iram size in firmware\n"); -+ return ret; -+ } -+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET + -+ offsetof(struct aqr_fw_header, dram_offset), -+ size, &dram_offset); -+ if (ret) { -+ phydev_err(phydev, "bad dram offset in firmware\n"); -+ return ret; -+ } -+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET + -+ offsetof(struct aqr_fw_header, dram_size), -+ size, &dram_size); -+ if (ret) { -+ phydev_err(phydev, "invalid dram size in firmware\n"); -+ return ret; -+ } -+ -+ /* Increment the offset with the primary offset. -+ * Validate iram/dram offset and size. -+ */ -+ iram_offset += primary_offset; -+ if (iram_size % sizeof(u32)) { -+ phydev_err(phydev, "iram size if not aligned to word size. Please report this upstream!\n"); -+ return -EINVAL; -+ } -+ if (!aqr_fw_validate_get(size, iram_offset, iram_size)) { -+ phydev_err(phydev, "invalid iram offset for iram size\n"); -+ return -EINVAL; -+ } -+ -+ dram_offset += primary_offset; -+ if (dram_size % sizeof(u32)) { -+ phydev_err(phydev, "dram size if not aligned to word size. Please report this upstream!\n"); -+ return -EINVAL; -+ } -+ if (!aqr_fw_validate_get(size, dram_offset, dram_size)) { -+ phydev_err(phydev, "invalid iram offset for iram size\n"); -+ return -EINVAL; -+ } -+ -+ phydev_dbg(phydev, "primary %d IRAM offset=%d size=%d DRAM offset=%d size=%d\n", -+ primary_offset, iram_offset, iram_size, dram_offset, dram_size); -+ -+ if (!aqr_fw_validate_get(size, dram_offset + VERSION_STRING_OFFSET, -+ VERSION_STRING_SIZE)) { -+ phydev_err(phydev, "invalid version in firmware\n"); -+ return -EINVAL; -+ } -+ strscpy(version, (char *)data + dram_offset + VERSION_STRING_OFFSET, -+ VERSION_STRING_SIZE); -+ if (version[0] == '\0') { -+ phydev_err(phydev, "invalid version in firmware\n"); -+ return -EINVAL; -+ } -+ phydev_info(phydev, "loading firmware version '%s' from '%s'\n", version, -+ aqr_fw_src_string[fw_src]); -+ -+ /* stall the microcprocessor */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2, -+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL | VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD); -+ -+ phydev_dbg(phydev, "loading DRAM 0x%08x from offset=%d size=%d\n", -+ DRAM_BASE_ADDR, dram_offset, dram_size); -+ ret = aqr_fw_load_memory(phydev, DRAM_BASE_ADDR, data + dram_offset, -+ dram_size); -+ if (ret) -+ return ret; -+ -+ phydev_dbg(phydev, "loading IRAM 0x%08x from offset=%d size=%d\n", -+ IRAM_BASE_ADDR, iram_offset, iram_size); -+ ret = aqr_fw_load_memory(phydev, IRAM_BASE_ADDR, data + iram_offset, -+ iram_size); -+ if (ret) -+ return ret; -+ -+ /* make sure soft reset and low power mode are clear */ -+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_SC, -+ VEND1_GLOBAL_SC_SOFT_RESET | VEND1_GLOBAL_SC_LOW_POWER); -+ -+ /* Release the microprocessor. UP_RESET must be held for 100 usec. */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2, -+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL | -+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD | -+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST); -+ usleep_range(UP_RESET_SLEEP, UP_RESET_SLEEP * 2); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2, -+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD); -+ -+ return 0; -+} -+ -+static int aqr_firmware_load_nvmem(struct phy_device *phydev) -+{ -+ struct nvmem_cell *cell; -+ size_t size; -+ u8 *buf; -+ int ret; -+ -+ cell = nvmem_cell_get(&phydev->mdio.dev, "firmware"); -+ if (IS_ERR(cell)) -+ return PTR_ERR(cell); -+ -+ buf = nvmem_cell_read(cell, &size); -+ if (IS_ERR(buf)) { -+ ret = PTR_ERR(buf); -+ goto exit; -+ } -+ -+ ret = aqr_fw_boot(phydev, buf, size, AQR_FW_SRC_NVMEM); -+ if (ret) -+ phydev_err(phydev, "firmware loading failed: %d\n", ret); -+ -+ kfree(buf); -+exit: -+ nvmem_cell_put(cell); -+ -+ return ret; -+} -+ -+static int aqr_firmware_load_fs(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ const struct firmware *fw; -+ const char *fw_name; -+ int ret; -+ -+ ret = of_property_read_string(dev->of_node, "firmware-name", -+ &fw_name); -+ if (ret) -+ return ret; -+ -+ ret = request_firmware(&fw, fw_name, dev); -+ if (ret) { -+ phydev_err(phydev, "failed to find FW file %s (%d)\n", -+ fw_name, ret); -+ return ret; -+ } -+ -+ ret = aqr_fw_boot(phydev, fw->data, fw->size, AQR_FW_SRC_FS); -+ if (ret) -+ phydev_err(phydev, "firmware loading failed: %d\n", ret); -+ -+ release_firmware(fw); -+ -+ return ret; -+} -+ -+int aqr_firmware_load(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Check if the firmware is not already loaded by pooling -+ * the current version returned by the PHY. If 0 is returned, -+ * no firmware is loaded. -+ */ -+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID); -+ if (ret > 0) -+ goto exit; -+ -+ ret = aqr_firmware_load_nvmem(phydev); -+ if (!ret) -+ goto exit; -+ -+ ret = aqr_firmware_load_fs(phydev); -+ if (ret) -+ return ret; -+ -+exit: -+ return 0; -+} ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -656,11 +656,17 @@ static int aqr107_resume(struct phy_devi - - static int aqr107_probe(struct phy_device *phydev) - { -+ int ret; -+ - phydev->priv = devm_kzalloc(&phydev->mdio.dev, - sizeof(struct aqr107_priv), GFP_KERNEL); - if (!phydev->priv) - return -ENOMEM; - -+ ret = aqr_firmware_load(phydev); -+ if (ret) -+ return ret; -+ - return aqr_hwmon_probe(phydev); - } - diff --git a/target/linux/generic/backport-6.1/703-v6.3-net-mdio-Add-dedicated-C45-API-to-MDIO-bus-drivers.patch b/target/linux/generic/backport-6.1/703-v6.3-net-mdio-Add-dedicated-C45-API-to-MDIO-bus-drivers.patch deleted file mode 100644 index ff186742ba4919..00000000000000 --- a/target/linux/generic/backport-6.1/703-v6.3-net-mdio-Add-dedicated-C45-API-to-MDIO-bus-drivers.patch +++ /dev/null @@ -1,326 +0,0 @@ -From 4e4aafcddbbfcdd6eed5780e190fcbfac8b4685a Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 9 Jan 2023 16:30:41 +0100 -Subject: [PATCH] net: mdio: Add dedicated C45 API to MDIO bus drivers - -Currently C22 and C45 transactions are mixed over a combined API calls -which make use of a special bit in the reg address to indicate if a -C45 transaction should be performed. This makes it impossible to know -if the bus driver actually supports C45. Additionally, many C22 only -drivers don't return -EOPNOTSUPP when asked to perform a C45 -transaction, they mistaking perform a C22 transaction. - -This is the first step to cleanly separate C22 from C45. To maintain -backwards compatibility until all drivers which are capable of -performing C45 are converted to this new API, the helper functions -will fall back to the older API if the new API is not -supported. Eventually this fallback will be removed. - -Signed-off-by: Andrew Lunn -Signed-off-by: Michael Walle -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/mdio_bus.c | 189 +++++++++++++++++++++++++++++++++++++ - include/linux/mdio.h | 39 ++++---- - include/linux/phy.h | 5 + - 3 files changed, 214 insertions(+), 19 deletions(-) - ---- a/drivers/net/phy/mdio_bus.c -+++ b/drivers/net/phy/mdio_bus.c -@@ -832,6 +832,100 @@ int __mdiobus_modify_changed(struct mii_ - EXPORT_SYMBOL_GPL(__mdiobus_modify_changed); - - /** -+ * __mdiobus_c45_read - Unlocked version of the mdiobus_c45_read function -+ * @bus: the mii_bus struct -+ * @addr: the phy address -+ * @devad: device address to read -+ * @regnum: register number to read -+ * -+ * Read a MDIO bus register. Caller must hold the mdio bus lock. -+ * -+ * NOTE: MUST NOT be called from interrupt context. -+ */ -+int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum) -+{ -+ int retval; -+ -+ lockdep_assert_held_once(&bus->mdio_lock); -+ -+ if (bus->read_c45) -+ retval = bus->read_c45(bus, addr, devad, regnum); -+ else -+ retval = bus->read(bus, addr, mdiobus_c45_addr(devad, regnum)); -+ -+ trace_mdio_access(bus, 1, addr, regnum, retval, retval); -+ mdiobus_stats_acct(&bus->stats[addr], true, retval); -+ -+ return retval; -+} -+EXPORT_SYMBOL(__mdiobus_c45_read); -+ -+/** -+ * __mdiobus_c45_write - Unlocked version of the mdiobus_write function -+ * @bus: the mii_bus struct -+ * @addr: the phy address -+ * @devad: device address to read -+ * @regnum: register number to write -+ * @val: value to write to @regnum -+ * -+ * Write a MDIO bus register. Caller must hold the mdio bus lock. -+ * -+ * NOTE: MUST NOT be called from interrupt context. -+ */ -+int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum, -+ u16 val) -+{ -+ int err; -+ -+ lockdep_assert_held_once(&bus->mdio_lock); -+ -+ if (bus->write_c45) -+ err = bus->write_c45(bus, addr, devad, regnum, val); -+ else -+ err = bus->write(bus, addr, mdiobus_c45_addr(devad, regnum), -+ val); -+ -+ trace_mdio_access(bus, 0, addr, regnum, val, err); -+ mdiobus_stats_acct(&bus->stats[addr], false, err); -+ -+ return err; -+} -+EXPORT_SYMBOL(__mdiobus_c45_write); -+ -+/** -+ * __mdiobus_c45_modify_changed - Unlocked version of the mdiobus_modify function -+ * @bus: the mii_bus struct -+ * @addr: the phy address -+ * @devad: device address to read -+ * @regnum: register number to modify -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ * -+ * Read, modify, and if any change, write the register value back to the -+ * device. Any error returns a negative number. -+ * -+ * NOTE: MUST NOT be called from interrupt context. -+ */ -+static int __mdiobus_c45_modify_changed(struct mii_bus *bus, int addr, -+ int devad, u32 regnum, u16 mask, -+ u16 set) -+{ -+ int new, ret; -+ -+ ret = __mdiobus_c45_read(bus, addr, devad, regnum); -+ if (ret < 0) -+ return ret; -+ -+ new = (ret & ~mask) | set; -+ if (new == ret) -+ return 0; -+ -+ ret = __mdiobus_c45_write(bus, addr, devad, regnum, new); -+ -+ return ret < 0 ? ret : 1; -+} -+ -+/** - * mdiobus_read_nested - Nested version of the mdiobus_read function - * @bus: the mii_bus struct - * @addr: the phy address -@@ -879,6 +973,29 @@ int mdiobus_read(struct mii_bus *bus, in - EXPORT_SYMBOL(mdiobus_read); - - /** -+ * mdiobus_c45_read - Convenience function for reading a given MII mgmt register -+ * @bus: the mii_bus struct -+ * @addr: the phy address -+ * @devad: device address to read -+ * @regnum: register number to read -+ * -+ * NOTE: MUST NOT be called from interrupt context, -+ * because the bus read/write functions may wait for an interrupt -+ * to conclude the operation. -+ */ -+int mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum) -+{ -+ int retval; -+ -+ mutex_lock(&bus->mdio_lock); -+ retval = __mdiobus_c45_read(bus, addr, devad, regnum); -+ mutex_unlock(&bus->mdio_lock); -+ -+ return retval; -+} -+EXPORT_SYMBOL(mdiobus_c45_read); -+ -+/** - * mdiobus_write_nested - Nested version of the mdiobus_write function - * @bus: the mii_bus struct - * @addr: the phy address -@@ -928,6 +1045,31 @@ int mdiobus_write(struct mii_bus *bus, i - EXPORT_SYMBOL(mdiobus_write); - - /** -+ * mdiobus_c45_write - Convenience function for writing a given MII mgmt register -+ * @bus: the mii_bus struct -+ * @addr: the phy address -+ * @devad: device address to read -+ * @regnum: register number to write -+ * @val: value to write to @regnum -+ * -+ * NOTE: MUST NOT be called from interrupt context, -+ * because the bus read/write functions may wait for an interrupt -+ * to conclude the operation. -+ */ -+int mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum, -+ u16 val) -+{ -+ int err; -+ -+ mutex_lock(&bus->mdio_lock); -+ err = __mdiobus_c45_write(bus, addr, devad, regnum, val); -+ mutex_unlock(&bus->mdio_lock); -+ -+ return err; -+} -+EXPORT_SYMBOL(mdiobus_c45_write); -+ -+/** - * mdiobus_modify - Convenience function for modifying a given mdio device - * register - * @bus: the mii_bus struct -@@ -949,6 +1091,30 @@ int mdiobus_modify(struct mii_bus *bus, - EXPORT_SYMBOL_GPL(mdiobus_modify); - - /** -+ * mdiobus_c45_modify - Convenience function for modifying a given mdio device -+ * register -+ * @bus: the mii_bus struct -+ * @addr: the phy address -+ * @devad: device address to read -+ * @regnum: register number to write -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ */ -+int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum, -+ u16 mask, u16 set) -+{ -+ int err; -+ -+ mutex_lock(&bus->mdio_lock); -+ err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum, -+ mask, set); -+ mutex_unlock(&bus->mdio_lock); -+ -+ return err < 0 ? err : 0; -+} -+EXPORT_SYMBOL_GPL(mdiobus_c45_modify); -+ -+/** - * mdiobus_modify_changed - Convenience function for modifying a given mdio - * device register and returning if it changed - * @bus: the mii_bus struct -@@ -971,6 +1137,29 @@ int mdiobus_modify_changed(struct mii_bu - EXPORT_SYMBOL_GPL(mdiobus_modify_changed); - - /** -+ * mdiobus_c45_modify_changed - Convenience function for modifying a given mdio -+ * device register and returning if it changed -+ * @bus: the mii_bus struct -+ * @addr: the phy address -+ * @devad: device address to read -+ * @regnum: register number to write -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ */ -+int mdiobus_c45_modify_changed(struct mii_bus *bus, int devad, int addr, -+ u32 regnum, u16 mask, u16 set) -+{ -+ int err; -+ -+ mutex_lock(&bus->mdio_lock); -+ err = __mdiobus_c45_modify_changed(bus, addr, devad, regnum, mask, set); -+ mutex_unlock(&bus->mdio_lock); -+ -+ return err; -+} -+EXPORT_SYMBOL_GPL(mdiobus_c45_modify_changed); -+ -+/** - * mdio_bus_match - determine if given MDIO driver supports the given - * MDIO device - * @dev: target MDIO device ---- a/include/linux/mdio.h -+++ b/include/linux/mdio.h -@@ -423,6 +423,17 @@ int mdiobus_modify(struct mii_bus *bus, - u16 set); - int mdiobus_modify_changed(struct mii_bus *bus, int addr, u32 regnum, - u16 mask, u16 set); -+int __mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum); -+int mdiobus_c45_read(struct mii_bus *bus, int addr, int devad, u32 regnum); -+int __mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum, -+ u16 val); -+int mdiobus_c45_write(struct mii_bus *bus, int addr, int devad, u32 regnum, -+ u16 val); -+int mdiobus_c45_modify(struct mii_bus *bus, int addr, int devad, u32 regnum, -+ u16 mask, u16 set); -+ -+int mdiobus_c45_modify_changed(struct mii_bus *bus, int addr, int devad, -+ u32 regnum, u16 mask, u16 set); - - static inline int mdiodev_read(struct mdio_device *mdiodev, u32 regnum) - { -@@ -463,29 +474,19 @@ static inline u16 mdiobus_c45_devad(u32 - return FIELD_GET(MII_DEVADDR_C45_MASK, regnum); - } - --static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad, -- u16 regnum) --{ -- return __mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum)); --} -- --static inline int __mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad, -- u16 regnum, u16 val) --{ -- return __mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum), -- val); --} -- --static inline int mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad, -- u16 regnum) -+static inline int mdiodev_c45_modify(struct mdio_device *mdiodev, int devad, -+ u32 regnum, u16 mask, u16 set) - { -- return mdiobus_read(bus, prtad, mdiobus_c45_addr(devad, regnum)); -+ return mdiobus_c45_modify(mdiodev->bus, mdiodev->addr, devad, regnum, -+ mask, set); - } - --static inline int mdiobus_c45_write(struct mii_bus *bus, int prtad, int devad, -- u16 regnum, u16 val) -+static inline int mdiodev_c45_modify_changed(struct mdio_device *mdiodev, -+ int devad, u32 regnum, u16 mask, -+ u16 set) - { -- return mdiobus_write(bus, prtad, mdiobus_c45_addr(devad, regnum), val); -+ return mdiobus_c45_modify_changed(mdiodev->bus, mdiodev->addr, devad, -+ regnum, mask, set); - } - - int mdiobus_register_device(struct mdio_device *mdiodev); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -364,6 +364,11 @@ struct mii_bus { - int (*read)(struct mii_bus *bus, int addr, int regnum); - /** @write: Perform a write transfer on the bus */ - int (*write)(struct mii_bus *bus, int addr, int regnum, u16 val); -+ /** @read_c45: Perform a C45 read transfer on the bus */ -+ int (*read_c45)(struct mii_bus *bus, int addr, int devnum, int regnum); -+ /** @write_c45: Perform a C45 write transfer on the bus */ -+ int (*write_c45)(struct mii_bus *bus, int addr, int devnum, -+ int regnum, u16 val); - /** @reset: Perform a reset of the bus */ - int (*reset)(struct mii_bus *bus); - diff --git a/target/linux/generic/backport-6.1/704-v6.6-net-phy-Introduce-PSGMII-PHY-interface-mode.patch b/target/linux/generic/backport-6.1/704-v6.6-net-phy-Introduce-PSGMII-PHY-interface-mode.patch deleted file mode 100644 index 80210e6da1eb55..00000000000000 --- a/target/linux/generic/backport-6.1/704-v6.6-net-phy-Introduce-PSGMII-PHY-interface-mode.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 9a0e95e34e9c0a713ddfd48c3a88a20d2bdfd514 Mon Sep 17 00:00:00 2001 -From: Gabor Juhos -Date: Fri, 11 Aug 2023 13:10:07 +0200 -Subject: [PATCH] net: phy: Introduce PSGMII PHY interface mode - -The PSGMII interface is similar to QSGMII. The main difference -is that the PSGMII interface combines five SGMII lines into a -single link while in QSGMII only four lines are combined. - -Similarly to the QSGMII, this interface mode might also needs -special handling within the MAC driver. - -It is commonly used by Qualcomm with their QCA807x PHY series and -modern WiSoC-s. - -Add definitions for the PHY layer to allow to express this type -of connection between the MAC and PHY. - -Signed-off-by: Gabor Juhos -Signed-off-by: Robert Marko -Signed-off-by: David S. Miller ---- - Documentation/networking/phy.rst | 4 ++++ - drivers/net/phy/phy-core.c | 2 ++ - drivers/net/phy/phylink.c | 3 +++ - include/linux/phy.h | 4 ++++ - 4 files changed, 13 insertions(+) - ---- a/Documentation/networking/phy.rst -+++ b/Documentation/networking/phy.rst -@@ -323,6 +323,10 @@ Some of the interface modes are describe - contrast with the 1000BASE-X phy mode used for Clause 38 and 39 PMDs, this - interface mode has different autonegotiation and only supports full duplex. - -+``PHY_INTERFACE_MODE_PSGMII`` -+ This is the Penta SGMII mode, it is similar to QSGMII but it combines 5 -+ SGMII lines into a single link compared to 4 on QSGMII. -+ - Pause frames / flow control - =========================== - ---- a/drivers/net/phy/phy-core.c -+++ b/drivers/net/phy/phy-core.c -@@ -140,6 +140,8 @@ int phy_interface_num_ports(phy_interfac - case PHY_INTERFACE_MODE_QSGMII: - case PHY_INTERFACE_MODE_QUSGMII: - return 4; -+ case PHY_INTERFACE_MODE_PSGMII: -+ return 5; - case PHY_INTERFACE_MODE_MAX: - WARN_ONCE(1, "PHY_INTERFACE_MODE_MAX isn't a valid interface mode"); - return 0; ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -187,6 +187,7 @@ static int phylink_interface_max_speed(p - case PHY_INTERFACE_MODE_RGMII_RXID: - case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_PSGMII: - case PHY_INTERFACE_MODE_QSGMII: - case PHY_INTERFACE_MODE_QUSGMII: - case PHY_INTERFACE_MODE_SGMII: -@@ -448,6 +449,7 @@ unsigned long phylink_get_capabilities(p - case PHY_INTERFACE_MODE_RGMII_RXID: - case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_PSGMII: - case PHY_INTERFACE_MODE_QSGMII: - case PHY_INTERFACE_MODE_QUSGMII: - case PHY_INTERFACE_MODE_SGMII: -@@ -814,6 +816,7 @@ static int phylink_parse_mode(struct phy - - switch (pl->link_config.interface) { - case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_PSGMII: - case PHY_INTERFACE_MODE_QSGMII: - case PHY_INTERFACE_MODE_QUSGMII: - case PHY_INTERFACE_MODE_RGMII: ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -103,6 +103,7 @@ extern const int phy_10gbit_features_arr - * @PHY_INTERFACE_MODE_XGMII: 10 gigabit media-independent interface - * @PHY_INTERFACE_MODE_XLGMII:40 gigabit media-independent interface - * @PHY_INTERFACE_MODE_MOCA: Multimedia over Coax -+ * @PHY_INTERFACE_MODE_PSGMII: Penta SGMII - * @PHY_INTERFACE_MODE_QSGMII: Quad SGMII - * @PHY_INTERFACE_MODE_TRGMII: Turbo RGMII - * @PHY_INTERFACE_MODE_100BASEX: 100 BaseX -@@ -140,6 +141,7 @@ typedef enum { - PHY_INTERFACE_MODE_XGMII, - PHY_INTERFACE_MODE_XLGMII, - PHY_INTERFACE_MODE_MOCA, -+ PHY_INTERFACE_MODE_PSGMII, - PHY_INTERFACE_MODE_QSGMII, - PHY_INTERFACE_MODE_TRGMII, - PHY_INTERFACE_MODE_100BASEX, -@@ -247,6 +249,8 @@ static inline const char *phy_modes(phy_ - return "xlgmii"; - case PHY_INTERFACE_MODE_MOCA: - return "moca"; -+ case PHY_INTERFACE_MODE_PSGMII: -+ return "psgmii"; - case PHY_INTERFACE_MODE_QSGMII: - return "qsgmii"; - case PHY_INTERFACE_MODE_TRGMII: diff --git a/target/linux/generic/backport-6.1/705-v6.4-net-phy-at803x-Replace-of_gpio.h-with-what-indeed-is.patch b/target/linux/generic/backport-6.1/705-v6.4-net-phy-at803x-Replace-of_gpio.h-with-what-indeed-is.patch deleted file mode 100644 index 7cacb71b182764..00000000000000 --- a/target/linux/generic/backport-6.1/705-v6.4-net-phy-at803x-Replace-of_gpio.h-with-what-indeed-is.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a593a2fcfdfb92cfd0ffc54bc81b07e6bfaaaf46 Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Thu, 16 Mar 2023 14:08:26 +0200 -Subject: [PATCH] net: phy: at803x: Replace of_gpio.h with what indeed is used - -of_gpio.h in this driver is solely used as a proxy to other headers. -This is incorrect usage of the of_gpio.h. Replace it .h with what -indeed is used in the code. - -Signed-off-by: Andy Shevchenko -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -13,12 +13,11 @@ - #include - #include - #include --#include - #include --#include - #include - #include - #include -+#include - #include - #include - #include diff --git a/target/linux/generic/backport-6.1/706-v6.6-01-net-phy-at803x-support-qca8081-genphy_c45_pma_read_a.patch b/target/linux/generic/backport-6.1/706-v6.6-01-net-phy-at803x-support-qca8081-genphy_c45_pma_read_a.patch deleted file mode 100644 index dab49289609076..00000000000000 --- a/target/linux/generic/backport-6.1/706-v6.6-01-net-phy-at803x-support-qca8081-genphy_c45_pma_read_a.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 8b8bc13d89a7d23d14b0e041c73f037c9db997b1 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 16 Jul 2023 16:49:19 +0800 -Subject: [PATCH 1/6] net: phy: at803x: support qca8081 - genphy_c45_pma_read_abilities - -qca8081 PHY supports to use genphy_c45_pma_read_abilities for -getting the PHY features supported except for the autoneg ability - -but autoneg ability exists in MDIO_STAT1 instead of MMD7.1, add it -manually after calling genphy_c45_pma_read_abilities. - -Signed-off-by: Luo Jie -Reviewed-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 28 ++++++++++++++++++---------- - 1 file changed, 18 insertions(+), 10 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -902,15 +902,6 @@ static int at803x_get_features(struct ph - if (err) - return err; - -- if (phydev->drv->phy_id == QCA8081_PHY_ID) { -- err = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_NG_EXTABLE); -- if (err < 0) -- return err; -- -- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported, -- err & MDIO_PMA_NG_EXTABLE_2_5GBT); -- } -- - if (phydev->drv->phy_id != ATH8031_PHY_ID) - return 0; - -@@ -1996,6 +1987,23 @@ static int qca808x_cable_test_get_status - return 0; - } - -+static int qca808x_get_features(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = genphy_c45_pma_read_abilities(phydev); -+ if (ret) -+ return ret; -+ -+ /* The autoneg ability is not existed in bit3 of MMD7.1, -+ * but it is supported by qca808x PHY, so we add it here -+ * manually. -+ */ -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported); -+ -+ return 0; -+} -+ - static struct phy_driver at803x_driver[] = { - { - /* Qualcomm Atheros AR8035 */ -@@ -2163,7 +2171,7 @@ static struct phy_driver at803x_driver[] - .set_tunable = at803x_set_tunable, - .set_wol = at803x_set_wol, - .get_wol = at803x_get_wol, -- .get_features = at803x_get_features, -+ .get_features = qca808x_get_features, - .config_aneg = at803x_config_aneg, - .suspend = genphy_suspend, - .resume = genphy_resume, diff --git a/target/linux/generic/backport-6.1/706-v6.6-02-net-phy-at803x-merge-qca8081-slave-seed-function.patch b/target/linux/generic/backport-6.1/706-v6.6-02-net-phy-at803x-merge-qca8081-slave-seed-function.patch deleted file mode 100644 index 28874068ce6c1a..00000000000000 --- a/target/linux/generic/backport-6.1/706-v6.6-02-net-phy-at803x-merge-qca8081-slave-seed-function.patch +++ /dev/null @@ -1,73 +0,0 @@ -From f3db55ae860a82e1224a909072783ef850e5d228 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 16 Jul 2023 16:49:20 +0800 -Subject: [PATCH 2/6] net: phy: at803x: merge qca8081 slave seed function - -merge the seed enablement and seed value configuration into -one function, since the random seed value is needed to be -configured when the seed is enabled. - -Signed-off-by: Luo Jie -Reviewed-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 29 +++++++++-------------------- - 1 file changed, 9 insertions(+), 20 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1730,24 +1730,19 @@ static int qca808x_phy_fast_retrain_conf - return 0; - } - --static int qca808x_phy_ms_random_seed_set(struct phy_device *phydev) --{ -- u16 seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE); -- -- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -- QCA808X_MASTER_SLAVE_SEED_CFG, -- FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value)); --} -- - static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable) - { -- u16 seed_enable = 0; -+ u16 seed_value; - -- if (enable) -- seed_enable = QCA808X_MASTER_SLAVE_SEED_ENABLE; -+ if (!enable) -+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -+ QCA808X_MASTER_SLAVE_SEED_ENABLE, 0); - -+ seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE); - return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -- QCA808X_MASTER_SLAVE_SEED_ENABLE, seed_enable); -+ QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE, -+ FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) | -+ QCA808X_MASTER_SLAVE_SEED_ENABLE); - } - - static int qca808x_config_init(struct phy_device *phydev) -@@ -1771,12 +1766,7 @@ static int qca808x_config_init(struct ph - if (ret) - return ret; - -- /* Configure lower ramdom seed to make phy linked as slave mode */ -- ret = qca808x_phy_ms_random_seed_set(phydev); -- if (ret) -- return ret; -- -- /* Enable seed */ -+ /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */ - ret = qca808x_phy_ms_seed_enable(phydev, true); - if (ret) - return ret; -@@ -1821,7 +1811,6 @@ static int qca808x_read_status(struct ph - if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) { - qca808x_phy_ms_seed_enable(phydev, false); - } else { -- qca808x_phy_ms_random_seed_set(phydev); - qca808x_phy_ms_seed_enable(phydev, true); - } - } diff --git a/target/linux/generic/backport-6.1/706-v6.6-03-net-phy-at803x-enable-qca8081-slave-seed-conditional.patch b/target/linux/generic/backport-6.1/706-v6.6-03-net-phy-at803x-enable-qca8081-slave-seed-conditional.patch deleted file mode 100644 index b91d2cab30e63a..00000000000000 --- a/target/linux/generic/backport-6.1/706-v6.6-03-net-phy-at803x-enable-qca8081-slave-seed-conditional.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 7cc3209558002d95c0d45a1276ba4f5f741eec42 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 16 Jul 2023 16:49:21 +0800 -Subject: [PATCH 3/6] net: phy: at803x: enable qca8081 slave seed conditionally - -qca8081 is the single port PHY, the slave prefer mode is used -by default. - -if the phy master perfer mode is configured, the slave seed -configuration should not be enabled, since the slave seed -enablement is for making PHY linked as slave mode easily. - -disable slave seed if the master mode is preferred. - -Signed-off-by: Luo Jie -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 25 ++++++++++++++++++++----- - 1 file changed, 20 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1745,6 +1745,12 @@ static int qca808x_phy_ms_seed_enable(st - QCA808X_MASTER_SLAVE_SEED_ENABLE); - } - -+static bool qca808x_is_prefer_master(struct phy_device *phydev) -+{ -+ return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) || -+ (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED); -+} -+ - static int qca808x_config_init(struct phy_device *phydev) - { - int ret; -@@ -1766,11 +1772,17 @@ static int qca808x_config_init(struct ph - if (ret) - return ret; - -- /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */ -- ret = qca808x_phy_ms_seed_enable(phydev, true); -- if (ret) -+ ret = genphy_read_master_slave(phydev); -+ if (ret < 0) - return ret; - -+ if (!qca808x_is_prefer_master(phydev)) { -+ /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */ -+ ret = qca808x_phy_ms_seed_enable(phydev, true); -+ if (ret) -+ return ret; -+ } -+ - /* Configure adc threshold as 100mv for the link 10M */ - return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD, - QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV); -@@ -1802,13 +1814,16 @@ static int qca808x_read_status(struct ph - phydev->interface = PHY_INTERFACE_MODE_SGMII; - } else { - /* generate seed as a lower random value to make PHY linked as SLAVE easily, -- * except for master/slave configuration fault detected. -+ * except for master/slave configuration fault detected or the master mode -+ * preferred. -+ * - * the reason for not putting this code into the function link_change_notify is - * the corner case where the link partner is also the qca8081 PHY and the seed - * value is configured as the same value, the link can't be up and no link change - * occurs. - */ -- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) { -+ if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR || -+ qca808x_is_prefer_master(phydev)) { - qca808x_phy_ms_seed_enable(phydev, false); - } else { - qca808x_phy_ms_seed_enable(phydev, true); diff --git a/target/linux/generic/backport-6.1/706-v6.6-04-net-phy-at803x-support-qca8081-1G-chip-type.patch b/target/linux/generic/backport-6.1/706-v6.6-04-net-phy-at803x-support-qca8081-1G-chip-type.patch deleted file mode 100644 index b8db89d853c1a6..00000000000000 --- a/target/linux/generic/backport-6.1/706-v6.6-04-net-phy-at803x-support-qca8081-1G-chip-type.patch +++ /dev/null @@ -1,48 +0,0 @@ -From fea7cfb83d1a2782e39cd101dd44ed2548539de5 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 16 Jul 2023 16:49:22 +0800 -Subject: [PATCH 4/6] net: phy: at803x: support qca8081 1G chip type - -The qca8081 1G chip version does not support 2.5 capability, which -is distinguished from qca8081 2.5G chip according to the bit0 of -register mmd7.0x901d, the 1G version chip also has the same PHY ID -as the normal qca8081 2.5G chip. - -Signed-off-by: Luo Jie -Reviewed-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -272,6 +272,10 @@ - #define QCA808X_CDT_STATUS_STAT_OPEN 2 - #define QCA808X_CDT_STATUS_STAT_SHORT 3 - -+/* QCA808X 1G chip type */ -+#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d -+#define QCA808X_PHY_CHIP_TYPE_1G BIT(0) -+ - MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver"); - MODULE_AUTHOR("Matus Ujhelyi"); - MODULE_LICENSE("GPL"); -@@ -2005,6 +2009,17 @@ static int qca808x_get_features(struct p - */ - linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported); - -+ /* As for the qca8081 1G version chip, the 2500baseT ability is also -+ * existed in the bit0 of MMD1.21, we need to remove it manually if -+ * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d. -+ */ -+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE); -+ if (ret < 0) -+ return ret; -+ -+ if (QCA808X_PHY_CHIP_TYPE_1G & ret) -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); -+ - return 0; - } - diff --git a/target/linux/generic/backport-6.1/706-v6.6-05-net-phy-at803x-remove-qca8081-1G-fast-retrain-and-sl.patch b/target/linux/generic/backport-6.1/706-v6.6-05-net-phy-at803x-remove-qca8081-1G-fast-retrain-and-sl.patch deleted file mode 100644 index b54a86e5f50bd9..00000000000000 --- a/target/linux/generic/backport-6.1/706-v6.6-05-net-phy-at803x-remove-qca8081-1G-fast-retrain-and-sl.patch +++ /dev/null @@ -1,98 +0,0 @@ -From df9401ff3e6eeaa42bfb06761967f1b71f5afce7 Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 16 Jul 2023 16:49:23 +0800 -Subject: [PATCH 5/6] net: phy: at803x: remove qca8081 1G fast retrain and - slave seed config - -The fast retrain and slave seed configs are only applicable when the 2.5G -ability is supported. - -Signed-off-by: Luo Jie -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 50 +++++++++++++++++++++++++--------------- - 1 file changed, 32 insertions(+), 18 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1755,6 +1755,11 @@ static bool qca808x_is_prefer_master(str - (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED); - } - -+static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev) -+{ -+ return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); -+} -+ - static int qca808x_config_init(struct phy_device *phydev) - { - int ret; -@@ -1771,20 +1776,24 @@ static int qca808x_config_init(struct ph - if (ret) - return ret; - -- /* Config the fast retrain for the link 2500M */ -- ret = qca808x_phy_fast_retrain_config(phydev); -- if (ret) -- return ret; -- -- ret = genphy_read_master_slave(phydev); -- if (ret < 0) -- return ret; -- -- if (!qca808x_is_prefer_master(phydev)) { -- /* Enable seed and configure lower ramdom seed to make phy linked as slave mode */ -- ret = qca808x_phy_ms_seed_enable(phydev, true); -+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { -+ /* Config the fast retrain for the link 2500M */ -+ ret = qca808x_phy_fast_retrain_config(phydev); - if (ret) - return ret; -+ -+ ret = genphy_read_master_slave(phydev); -+ if (ret < 0) -+ return ret; -+ -+ if (!qca808x_is_prefer_master(phydev)) { -+ /* Enable seed and configure lower ramdom seed to make phy -+ * linked as slave mode. -+ */ -+ ret = qca808x_phy_ms_seed_enable(phydev, true); -+ if (ret) -+ return ret; -+ } - } - - /* Configure adc threshold as 100mv for the link 10M */ -@@ -1826,11 +1835,13 @@ static int qca808x_read_status(struct ph - * value is configured as the same value, the link can't be up and no link change - * occurs. - */ -- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR || -- qca808x_is_prefer_master(phydev)) { -- qca808x_phy_ms_seed_enable(phydev, false); -- } else { -- qca808x_phy_ms_seed_enable(phydev, true); -+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { -+ if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR || -+ qca808x_is_prefer_master(phydev)) { -+ qca808x_phy_ms_seed_enable(phydev, false); -+ } else { -+ qca808x_phy_ms_seed_enable(phydev, true); -+ } - } - } - -@@ -1845,7 +1856,10 @@ static int qca808x_soft_reset(struct phy - if (ret < 0) - return ret; - -- return qca808x_phy_ms_seed_enable(phydev, true); -+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) -+ ret = qca808x_phy_ms_seed_enable(phydev, true); -+ -+ return ret; - } - - static bool qca808x_cdt_fault_length_valid(int cdt_code) diff --git a/target/linux/generic/backport-6.1/706-v6.6-06-net-phy-at803x-add-qca8081-fifo-reset-on-the-link-ch.patch b/target/linux/generic/backport-6.1/706-v6.6-06-net-phy-at803x-add-qca8081-fifo-reset-on-the-link-ch.patch deleted file mode 100644 index e382cf78762bc8..00000000000000 --- a/target/linux/generic/backport-6.1/706-v6.6-06-net-phy-at803x-add-qca8081-fifo-reset-on-the-link-ch.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 723970affdd8766fa0d91cd34bf2ffc861538b5f Mon Sep 17 00:00:00 2001 -From: Luo Jie -Date: Sun, 16 Jul 2023 16:49:24 +0800 -Subject: [PATCH 6/6] net: phy: at803x: add qca8081 fifo reset on the link - changed - -The qca8081 sgmii fifo needs to be reset on link down and -released on the link up in case of any abnormal issue -such as the packet blocked on the PHY. - -Signed-off-by: Luo Jie -Reviewed-by: Andrew Lunn -Reviewed-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -276,6 +276,9 @@ - #define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d - #define QCA808X_PHY_CHIP_TYPE_1G BIT(0) - -+#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072 -+#define QCA8081_PHY_FIFO_RSTN BIT(11) -+ - MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver"); - MODULE_AUTHOR("Matus Ujhelyi"); - MODULE_LICENSE("GPL"); -@@ -2037,6 +2040,16 @@ static int qca808x_get_features(struct p - return 0; - } - -+static void qca808x_link_change_notify(struct phy_device *phydev) -+{ -+ /* Assert interface sgmii fifo on link down, deassert it on link up, -+ * the interface device address is always phy address added by 1. -+ */ -+ mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1, -+ MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL, -+ QCA8081_PHY_FIFO_RSTN, phydev->link ? QCA8081_PHY_FIFO_RSTN : 0); -+} -+ - static struct phy_driver at803x_driver[] = { - { - /* Qualcomm Atheros AR8035 */ -@@ -2213,6 +2226,7 @@ static struct phy_driver at803x_driver[] - .soft_reset = qca808x_soft_reset, - .cable_test_start = qca808x_cable_test_start, - .cable_test_get_status = qca808x_cable_test_get_status, -+ .link_change_notify = qca808x_link_change_notify, - }, }; - - module_phy_driver(at803x_driver); diff --git a/target/linux/generic/backport-6.1/707-v6.8-02-net-phy-at803x-move-disable-WOL-to-specific-at8031-p.patch b/target/linux/generic/backport-6.1/707-v6.8-02-net-phy-at803x-move-disable-WOL-to-specific-at8031-p.patch deleted file mode 100644 index eb9172b1cca35f..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-02-net-phy-at803x-move-disable-WOL-to-specific-at8031-p.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 6a3b8c573b5a152a6aa7a0b54c5e18b84c6ba6f5 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:49 +0100 -Subject: [PATCH 02/13] net: phy: at803x: move disable WOL to specific at8031 - probe - -Move the WOL disable call to specific at8031 probe to make at803x_probe -more generic and drop extra check for PHY ID. - -Keep the same previous behaviour by first calling at803x_probe and then -disabling WOL. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 27 +++++++++++++++++---------- - 1 file changed, 17 insertions(+), 10 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -886,15 +886,6 @@ static int at803x_probe(struct phy_devic - priv->is_fiber = true; - break; - } -- -- /* Disable WoL in 1588 register which is enabled -- * by default -- */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -- AT803X_PHY_MMD3_WOL_CTRL, -- AT803X_WOL_EN, 0); -- if (ret) -- return ret; - } - - return 0; -@@ -1591,6 +1582,22 @@ static int at803x_cable_test_start(struc - return 0; - } - -+static int at8031_probe(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = at803x_probe(phydev); -+ if (ret) -+ return ret; -+ -+ /* Disable WoL in 1588 register which is enabled -+ * by default -+ */ -+ return phy_modify_mmd(phydev, MDIO_MMD_PCS, -+ AT803X_PHY_MMD3_WOL_CTRL, -+ AT803X_WOL_EN, 0); -+} -+ - static int qca83xx_config_init(struct phy_device *phydev) - { - u8 switch_revision; -@@ -2092,7 +2099,7 @@ static struct phy_driver at803x_driver[] - PHY_ID_MATCH_EXACT(ATH8031_PHY_ID), - .name = "Qualcomm Atheros AR8031/AR8033", - .flags = PHY_POLL_CABLE_TEST, -- .probe = at803x_probe, -+ .probe = at8031_probe, - .config_init = at803x_config_init, - .config_aneg = at803x_config_aneg, - .soft_reset = genphy_soft_reset, diff --git a/target/linux/generic/backport-6.1/707-v6.8-03-net-phy-at803x-raname-hw_stats-functions-to-qca83xx-.patch b/target/linux/generic/backport-6.1/707-v6.8-03-net-phy-at803x-raname-hw_stats-functions-to-qca83xx-.patch deleted file mode 100644 index 5a9d1764f1ba78..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-03-net-phy-at803x-raname-hw_stats-functions-to-qca83xx-.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 07b1ad83b9ed6db1735ba10baf67b7a565ac0cef Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:50 +0100 -Subject: [PATCH 03/13] net: phy: at803x: raname hw_stats functions to qca83xx - specific name - -The function and the struct related to hw_stats were specific to qca83xx -PHY but were called following the convention in the driver of calling -everything with at803x prefix. - -To better organize the code, rename these function a more specific name -to better describe that they are specific to 83xx PHY family. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 44 ++++++++++++++++++++-------------------- - 1 file changed, 22 insertions(+), 22 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -295,7 +295,7 @@ struct at803x_hw_stat { - enum stat_access_type access_type; - }; - --static struct at803x_hw_stat at803x_hw_stats[] = { -+static struct at803x_hw_stat qca83xx_hw_stats[] = { - { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY}, - { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY}, - { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD}, -@@ -311,7 +311,7 @@ struct at803x_priv { - bool is_1000basex; - struct regulator_dev *vddio_rdev; - struct regulator_dev *vddh_rdev; -- u64 stats[ARRAY_SIZE(at803x_hw_stats)]; -+ u64 stats[ARRAY_SIZE(qca83xx_hw_stats)]; - }; - - struct at803x_context { -@@ -529,24 +529,24 @@ static void at803x_get_wol(struct phy_de - wol->wolopts |= WAKE_MAGIC; - } - --static int at803x_get_sset_count(struct phy_device *phydev) -+static int qca83xx_get_sset_count(struct phy_device *phydev) - { -- return ARRAY_SIZE(at803x_hw_stats); -+ return ARRAY_SIZE(qca83xx_hw_stats); - } - --static void at803x_get_strings(struct phy_device *phydev, u8 *data) -+static void qca83xx_get_strings(struct phy_device *phydev, u8 *data) - { - int i; - -- for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++) { -+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) { - strscpy(data + i * ETH_GSTRING_LEN, -- at803x_hw_stats[i].string, ETH_GSTRING_LEN); -+ qca83xx_hw_stats[i].string, ETH_GSTRING_LEN); - } - } - --static u64 at803x_get_stat(struct phy_device *phydev, int i) -+static u64 qca83xx_get_stat(struct phy_device *phydev, int i) - { -- struct at803x_hw_stat stat = at803x_hw_stats[i]; -+ struct at803x_hw_stat stat = qca83xx_hw_stats[i]; - struct at803x_priv *priv = phydev->priv; - int val; - u64 ret; -@@ -567,13 +567,13 @@ static u64 at803x_get_stat(struct phy_de - return ret; - } - --static void at803x_get_stats(struct phy_device *phydev, -- struct ethtool_stats *stats, u64 *data) -+static void qca83xx_get_stats(struct phy_device *phydev, -+ struct ethtool_stats *stats, u64 *data) - { - int i; - -- for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++) -- data[i] = at803x_get_stat(phydev, i); -+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) -+ data[i] = qca83xx_get_stat(phydev, i); - } - - static int at803x_suspend(struct phy_device *phydev) -@@ -2175,9 +2175,9 @@ static struct phy_driver at803x_driver[] - .flags = PHY_IS_INTERNAL, - .config_init = qca83xx_config_init, - .soft_reset = genphy_soft_reset, -- .get_sset_count = at803x_get_sset_count, -- .get_strings = at803x_get_strings, -- .get_stats = at803x_get_stats, -+ .get_sset_count = qca83xx_get_sset_count, -+ .get_strings = qca83xx_get_strings, -+ .get_stats = qca83xx_get_stats, - .suspend = qca83xx_suspend, - .resume = qca83xx_resume, - }, { -@@ -2191,9 +2191,9 @@ static struct phy_driver at803x_driver[] - .flags = PHY_IS_INTERNAL, - .config_init = qca83xx_config_init, - .soft_reset = genphy_soft_reset, -- .get_sset_count = at803x_get_sset_count, -- .get_strings = at803x_get_strings, -- .get_stats = at803x_get_stats, -+ .get_sset_count = qca83xx_get_sset_count, -+ .get_strings = qca83xx_get_strings, -+ .get_stats = qca83xx_get_stats, - .suspend = qca83xx_suspend, - .resume = qca83xx_resume, - }, { -@@ -2207,9 +2207,9 @@ static struct phy_driver at803x_driver[] - .flags = PHY_IS_INTERNAL, - .config_init = qca83xx_config_init, - .soft_reset = genphy_soft_reset, -- .get_sset_count = at803x_get_sset_count, -- .get_strings = at803x_get_strings, -- .get_stats = at803x_get_stats, -+ .get_sset_count = qca83xx_get_sset_count, -+ .get_strings = qca83xx_get_strings, -+ .get_stats = qca83xx_get_stats, - .suspend = qca83xx_suspend, - .resume = qca83xx_resume, - }, { diff --git a/target/linux/generic/backport-6.1/707-v6.8-04-net-phy-at803x-move-qca83xx-specific-check-in-dedica.patch b/target/linux/generic/backport-6.1/707-v6.8-04-net-phy-at803x-move-qca83xx-specific-check-in-dedica.patch deleted file mode 100644 index f09142c5ed446d..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-04-net-phy-at803x-move-qca83xx-specific-check-in-dedica.patch +++ /dev/null @@ -1,155 +0,0 @@ -From d43cff3f82336c0bd965ea552232d9f4ddac71a6 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:51 +0100 -Subject: [PATCH 04/13] net: phy: at803x: move qca83xx specific check in - dedicated functions - -Rework qca83xx specific check to dedicated function to tidy things up -and drop useless phy_id check. - -Also drop an useless link_change_notify for QCA8337 as it did nothing an -returned early. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 68 ++++++++++++++++++++++------------------ - 1 file changed, 37 insertions(+), 31 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1623,27 +1623,26 @@ static int qca83xx_config_init(struct ph - break; - } - -+ /* Following original QCA sourcecode set port to prefer master */ -+ phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER); -+ -+ return 0; -+} -+ -+static int qca8327_config_init(struct phy_device *phydev) -+{ - /* QCA8327 require DAC amplitude adjustment for 100m set to +6%. - * Disable on init and enable only with 100m speed following - * qca original source code. - */ -- if (phydev->drv->phy_id == QCA8327_A_PHY_ID || -- phydev->drv->phy_id == QCA8327_B_PHY_ID) -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -- QCA8327_DEBUG_MANU_CTRL_EN, 0); -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -+ QCA8327_DEBUG_MANU_CTRL_EN, 0); - -- /* Following original QCA sourcecode set port to prefer master */ -- phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER); -- -- return 0; -+ return qca83xx_config_init(phydev); - } - - static void qca83xx_link_change_notify(struct phy_device *phydev) - { -- /* QCA8337 doesn't require DAC Amplitude adjustement */ -- if (phydev->drv->phy_id == QCA8337_PHY_ID) -- return; -- - /* Set DAC Amplitude adjustment to +6% for 100m on link running */ - if (phydev->state == PHY_RUNNING) { - if (phydev->speed == SPEED_100) -@@ -1686,19 +1685,6 @@ static int qca83xx_resume(struct phy_dev - - static int qca83xx_suspend(struct phy_device *phydev) - { -- u16 mask = 0; -- -- /* Only QCA8337 support actual suspend. -- * QCA8327 cause port unreliability when phy suspend -- * is set. -- */ -- if (phydev->drv->phy_id == QCA8337_PHY_ID) { -- genphy_suspend(phydev); -- } else { -- mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX); -- phy_modify(phydev, MII_BMCR, mask, 0); -- } -- - at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN, - AT803X_DEBUG_GATE_CLK_IN1000, 0); - -@@ -1709,6 +1695,27 @@ static int qca83xx_suspend(struct phy_de - return 0; - } - -+static int qca8337_suspend(struct phy_device *phydev) -+{ -+ /* Only QCA8337 support actual suspend. */ -+ genphy_suspend(phydev); -+ -+ return qca83xx_suspend(phydev); -+} -+ -+static int qca8327_suspend(struct phy_device *phydev) -+{ -+ u16 mask = 0; -+ -+ /* QCA8327 cause port unreliability when phy suspend -+ * is set. -+ */ -+ mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX); -+ phy_modify(phydev, MII_BMCR, mask, 0); -+ -+ return qca83xx_suspend(phydev); -+} -+ - static int qca808x_phy_fast_retrain_config(struct phy_device *phydev) - { - int ret; -@@ -2170,7 +2177,6 @@ static struct phy_driver at803x_driver[] - .phy_id_mask = QCA8K_PHY_ID_MASK, - .name = "Qualcomm Atheros 8337 internal PHY", - /* PHY_GBIT_FEATURES */ -- .link_change_notify = qca83xx_link_change_notify, - .probe = at803x_probe, - .flags = PHY_IS_INTERNAL, - .config_init = qca83xx_config_init, -@@ -2178,7 +2184,7 @@ static struct phy_driver at803x_driver[] - .get_sset_count = qca83xx_get_sset_count, - .get_strings = qca83xx_get_strings, - .get_stats = qca83xx_get_stats, -- .suspend = qca83xx_suspend, -+ .suspend = qca8337_suspend, - .resume = qca83xx_resume, - }, { - /* QCA8327-A from switch QCA8327-AL1A */ -@@ -2189,12 +2195,12 @@ static struct phy_driver at803x_driver[] - .link_change_notify = qca83xx_link_change_notify, - .probe = at803x_probe, - .flags = PHY_IS_INTERNAL, -- .config_init = qca83xx_config_init, -+ .config_init = qca8327_config_init, - .soft_reset = genphy_soft_reset, - .get_sset_count = qca83xx_get_sset_count, - .get_strings = qca83xx_get_strings, - .get_stats = qca83xx_get_stats, -- .suspend = qca83xx_suspend, -+ .suspend = qca8327_suspend, - .resume = qca83xx_resume, - }, { - /* QCA8327-B from switch QCA8327-BL1A */ -@@ -2205,12 +2211,12 @@ static struct phy_driver at803x_driver[] - .link_change_notify = qca83xx_link_change_notify, - .probe = at803x_probe, - .flags = PHY_IS_INTERNAL, -- .config_init = qca83xx_config_init, -+ .config_init = qca8327_config_init, - .soft_reset = genphy_soft_reset, - .get_sset_count = qca83xx_get_sset_count, - .get_strings = qca83xx_get_strings, - .get_stats = qca83xx_get_stats, -- .suspend = qca83xx_suspend, -+ .suspend = qca8327_suspend, - .resume = qca83xx_resume, - }, { - /* Qualcomm QCA8081 */ diff --git a/target/linux/generic/backport-6.1/707-v6.8-05-net-phy-at803x-move-specific-DT-option-for-at8031-to.patch b/target/linux/generic/backport-6.1/707-v6.8-05-net-phy-at803x-move-specific-DT-option-for-at8031-to.patch deleted file mode 100644 index a5cc67a8c8e19c..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-05-net-phy-at803x-move-specific-DT-option-for-at8031-to.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 900eef75cc5018e149c52fe305c9c3fe424c52a7 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:52 +0100 -Subject: [PATCH 05/13] net: phy: at803x: move specific DT option for at8031 to - specific probe - -Move specific DT options for at8031 to specific probe to tidy things up -and make at803x_parse_dt more generic. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 55 ++++++++++++++++++++++------------------ - 1 file changed, 31 insertions(+), 24 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -825,30 +825,6 @@ static int at803x_parse_dt(struct phy_de - } - } - -- /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping -- * options. -- */ -- if (phydev->drv->phy_id == ATH8031_PHY_ID) { -- if (of_property_read_bool(node, "qca,keep-pll-enabled")) -- priv->flags |= AT803X_KEEP_PLL_ENABLED; -- -- ret = at8031_register_regulators(phydev); -- if (ret < 0) -- return ret; -- -- ret = devm_regulator_get_enable_optional(&phydev->mdio.dev, -- "vddio"); -- if (ret) { -- phydev_err(phydev, "failed to get VDDIO regulator\n"); -- return ret; -- } -- -- /* Only AR8031/8033 support 1000Base-X for SFP modules */ -- ret = phy_sfp_probe(phydev, &at803x_sfp_ops); -- if (ret < 0) -- return ret; -- } -- - return 0; - } - -@@ -1582,6 +1558,30 @@ static int at803x_cable_test_start(struc - return 0; - } - -+static int at8031_parse_dt(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ struct at803x_priv *priv = phydev->priv; -+ int ret; -+ -+ if (of_property_read_bool(node, "qca,keep-pll-enabled")) -+ priv->flags |= AT803X_KEEP_PLL_ENABLED; -+ -+ ret = at8031_register_regulators(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ret = devm_regulator_get_enable_optional(&phydev->mdio.dev, -+ "vddio"); -+ if (ret) { -+ phydev_err(phydev, "failed to get VDDIO regulator\n"); -+ return ret; -+ } -+ -+ /* Only AR8031/8033 support 1000Base-X for SFP modules */ -+ return phy_sfp_probe(phydev, &at803x_sfp_ops); -+} -+ - static int at8031_probe(struct phy_device *phydev) - { - int ret; -@@ -1590,6 +1590,13 @@ static int at8031_probe(struct phy_devic - if (ret) - return ret; - -+ /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping -+ * options. -+ */ -+ ret = at8031_parse_dt(phydev); -+ if (ret) -+ return ret; -+ - /* Disable WoL in 1588 register which is enabled - * by default - */ diff --git a/target/linux/generic/backport-6.1/707-v6.8-06-net-phy-at803x-move-specific-at8031-probe-mode-check.patch b/target/linux/generic/backport-6.1/707-v6.8-06-net-phy-at803x-move-specific-at8031-probe-mode-check.patch deleted file mode 100644 index 9e10e000e5b9b6..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-06-net-phy-at803x-move-specific-at8031-probe-mode-check.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 25d2ba94005fac18fe68878cddff59a67e115554 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:53 +0100 -Subject: [PATCH 06/13] net: phy: at803x: move specific at8031 probe mode check - to dedicated probe - -Move specific at8031 probe mode check to dedicated probe to make -at803x_probe more generic and keep code tidy. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 39 +++++++++++++++++++-------------------- - 1 file changed, 19 insertions(+), 20 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -844,26 +844,6 @@ static int at803x_probe(struct phy_devic - if (ret) - return ret; - -- if (phydev->drv->phy_id == ATH8031_PHY_ID) { -- int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); -- int mode_cfg; -- -- if (ccr < 0) -- return ccr; -- mode_cfg = ccr & AT803X_MODE_CFG_MASK; -- -- switch (mode_cfg) { -- case AT803X_MODE_CFG_BX1000_RGMII_50OHM: -- case AT803X_MODE_CFG_BX1000_RGMII_75OHM: -- priv->is_1000basex = true; -- fallthrough; -- case AT803X_MODE_CFG_FX100_RGMII_50OHM: -- case AT803X_MODE_CFG_FX100_RGMII_75OHM: -- priv->is_fiber = true; -- break; -- } -- } -- - return 0; - } - -@@ -1584,6 +1564,9 @@ static int at8031_parse_dt(struct phy_de - - static int at8031_probe(struct phy_device *phydev) - { -+ struct at803x_priv *priv = phydev->priv; -+ int mode_cfg; -+ int ccr; - int ret; - - ret = at803x_probe(phydev); -@@ -1597,6 +1580,22 @@ static int at8031_probe(struct phy_devic - if (ret) - return ret; - -+ ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); -+ if (ccr < 0) -+ return ccr; -+ mode_cfg = ccr & AT803X_MODE_CFG_MASK; -+ -+ switch (mode_cfg) { -+ case AT803X_MODE_CFG_BX1000_RGMII_50OHM: -+ case AT803X_MODE_CFG_BX1000_RGMII_75OHM: -+ priv->is_1000basex = true; -+ fallthrough; -+ case AT803X_MODE_CFG_FX100_RGMII_50OHM: -+ case AT803X_MODE_CFG_FX100_RGMII_75OHM: -+ priv->is_fiber = true; -+ break; -+ } -+ - /* Disable WoL in 1588 register which is enabled - * by default - */ diff --git a/target/linux/generic/backport-6.1/707-v6.8-07-net-phy-at803x-move-specific-at8031-config_init-to-d.patch b/target/linux/generic/backport-6.1/707-v6.8-07-net-phy-at803x-move-specific-at8031-config_init-to-d.patch deleted file mode 100644 index c9ef6df8279818..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-07-net-phy-at803x-move-specific-at8031-config_init-to-d.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 3ae3bc426eaf57ca8f53d75777d9a5ef779bc7b7 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:54 +0100 -Subject: [PATCH 07/13] net: phy: at803x: move specific at8031 config_init to - dedicated function - -Move specific at8031 config_init to dedicated function to make -at803x_config_init more generic and tidy things up. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 45 ++++++++++++++++++++++------------------ - 1 file changed, 25 insertions(+), 20 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -951,27 +951,8 @@ static int at803x_hibernation_mode_confi - - static int at803x_config_init(struct phy_device *phydev) - { -- struct at803x_priv *priv = phydev->priv; - int ret; - -- if (phydev->drv->phy_id == ATH8031_PHY_ID) { -- /* Some bootloaders leave the fiber page selected. -- * Switch to the appropriate page (fiber or copper), as otherwise we -- * read the PHY capabilities from the wrong page. -- */ -- phy_lock_mdio_bus(phydev); -- ret = at803x_write_page(phydev, -- priv->is_fiber ? AT803X_PAGE_FIBER : -- AT803X_PAGE_COPPER); -- phy_unlock_mdio_bus(phydev); -- if (ret) -- return ret; -- -- ret = at8031_pll_config(phydev); -- if (ret < 0) -- return ret; -- } -- - /* The RX and TX delay default is: - * after HW reset: RX delay enabled and TX delay disabled - * after SW reset: RX delay enabled, while TX delay retains the -@@ -1604,6 +1585,30 @@ static int at8031_probe(struct phy_devic - AT803X_WOL_EN, 0); - } - -+static int at8031_config_init(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ int ret; -+ -+ /* Some bootloaders leave the fiber page selected. -+ * Switch to the appropriate page (fiber or copper), as otherwise we -+ * read the PHY capabilities from the wrong page. -+ */ -+ phy_lock_mdio_bus(phydev); -+ ret = at803x_write_page(phydev, -+ priv->is_fiber ? AT803X_PAGE_FIBER : -+ AT803X_PAGE_COPPER); -+ phy_unlock_mdio_bus(phydev); -+ if (ret) -+ return ret; -+ -+ ret = at8031_pll_config(phydev); -+ if (ret < 0) -+ return ret; -+ -+ return at803x_config_init(phydev); -+} -+ - static int qca83xx_config_init(struct phy_device *phydev) - { - u8 switch_revision; -@@ -2113,7 +2118,7 @@ static struct phy_driver at803x_driver[] - .name = "Qualcomm Atheros AR8031/AR8033", - .flags = PHY_POLL_CABLE_TEST, - .probe = at8031_probe, -- .config_init = at803x_config_init, -+ .config_init = at8031_config_init, - .config_aneg = at803x_config_aneg, - .soft_reset = genphy_soft_reset, - .set_wol = at803x_set_wol, diff --git a/target/linux/generic/backport-6.1/707-v6.8-08-net-phy-at803x-move-specific-at8031-WOL-bits-to-dedi.patch b/target/linux/generic/backport-6.1/707-v6.8-08-net-phy-at803x-move-specific-at8031-WOL-bits-to-dedi.patch deleted file mode 100644 index 6746a4d43ca87a..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-08-net-phy-at803x-move-specific-at8031-WOL-bits-to-dedi.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 27b89c9dc1b0393090d68d651b82f30ad2696baa Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:55 +0100 -Subject: [PATCH 08/13] net: phy: at803x: move specific at8031 WOL bits to - dedicated function - -Move specific at8031 WOL enable/disable to dedicated function to make -at803x_set_wol more generic. - -This is needed in preparation for PHY driver split as qca8081 share the -same function to toggle WOL settings. - -In this new implementation WOL module in at8031 is enabled after the -generic interrupt is setup. This should not cause any problem as the -WOL_INT has a separate implementation and only relay on MAC bits. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 42 ++++++++++++++++++++++++---------------- - 1 file changed, 25 insertions(+), 17 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -466,27 +466,11 @@ static int at803x_set_wol(struct phy_dev - phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i], - mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); - -- /* Enable WOL function for 1588 */ -- if (phydev->drv->phy_id == ATH8031_PHY_ID) { -- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -- AT803X_PHY_MMD3_WOL_CTRL, -- 0, AT803X_WOL_EN); -- if (ret) -- return ret; -- } - /* Enable WOL interrupt */ - ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL); - if (ret) - return ret; - } else { -- /* Disable WoL function for 1588 */ -- if (phydev->drv->phy_id == ATH8031_PHY_ID) { -- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -- AT803X_PHY_MMD3_WOL_CTRL, -- AT803X_WOL_EN, 0); -- if (ret) -- return ret; -- } - /* Disable WOL interrupt */ - ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0); - if (ret) -@@ -1609,6 +1593,30 @@ static int at8031_config_init(struct phy - return at803x_config_init(phydev); - } - -+static int at8031_set_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol) -+{ -+ int ret; -+ -+ /* First setup MAC address and enable WOL interrupt */ -+ ret = at803x_set_wol(phydev, wol); -+ if (ret) -+ return ret; -+ -+ if (wol->wolopts & WAKE_MAGIC) -+ /* Enable WOL function for 1588 */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -+ AT803X_PHY_MMD3_WOL_CTRL, -+ 0, AT803X_WOL_EN); -+ else -+ /* Disable WoL function for 1588 */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -+ AT803X_PHY_MMD3_WOL_CTRL, -+ AT803X_WOL_EN, 0); -+ -+ return ret; -+} -+ - static int qca83xx_config_init(struct phy_device *phydev) - { - u8 switch_revision; -@@ -2121,7 +2129,7 @@ static struct phy_driver at803x_driver[] - .config_init = at8031_config_init, - .config_aneg = at803x_config_aneg, - .soft_reset = genphy_soft_reset, -- .set_wol = at803x_set_wol, -+ .set_wol = at8031_set_wol, - .get_wol = at803x_get_wol, - .suspend = at803x_suspend, - .resume = at803x_resume, diff --git a/target/linux/generic/backport-6.1/707-v6.8-09-net-phy-at803x-move-specific-at8031-config_intr-to-d.patch b/target/linux/generic/backport-6.1/707-v6.8-09-net-phy-at803x-move-specific-at8031-config_intr-to-d.patch deleted file mode 100644 index 0d284c3d2418ad..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-09-net-phy-at803x-move-specific-at8031-config_intr-to-d.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 30dd62191d3dd97c08f7f9dc9ce77ffab457e4fb Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:56 +0100 -Subject: [PATCH 09/13] net: phy: at803x: move specific at8031 config_intr to - dedicated function - -Move specific at8031 config_intr bits to dedicated function to make -at803x_config_initr more generic. - -This is needed in preparation for PHY driver split as qca8081 share the -same function to setup interrupts. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 30 ++++++++++++++++++++++++------ - 1 file changed, 24 insertions(+), 6 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -990,7 +990,6 @@ static int at803x_ack_interrupt(struct p - - static int at803x_config_intr(struct phy_device *phydev) - { -- struct at803x_priv *priv = phydev->priv; - int err; - int value; - -@@ -1007,10 +1006,6 @@ static int at803x_config_intr(struct phy - value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED; - value |= AT803X_INTR_ENABLE_LINK_FAIL; - value |= AT803X_INTR_ENABLE_LINK_SUCCESS; -- if (priv->is_fiber) { -- value |= AT803X_INTR_ENABLE_LINK_FAIL_BX; -- value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX; -- } - - err = phy_write(phydev, AT803X_INTR_ENABLE, value); - } else { -@@ -1617,6 +1612,29 @@ static int at8031_set_wol(struct phy_dev - return ret; - } - -+static int at8031_config_intr(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ int err, value = 0; -+ -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED && -+ priv->is_fiber) { -+ /* Clear any pending interrupts */ -+ err = at803x_ack_interrupt(phydev); -+ if (err) -+ return err; -+ -+ value |= AT803X_INTR_ENABLE_LINK_FAIL_BX; -+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX; -+ -+ err = phy_set_bits(phydev, AT803X_INTR_ENABLE, value); -+ if (err) -+ return err; -+ } -+ -+ return at803x_config_intr(phydev); -+} -+ - static int qca83xx_config_init(struct phy_device *phydev) - { - u8 switch_revision; -@@ -2137,7 +2155,7 @@ static struct phy_driver at803x_driver[] - .write_page = at803x_write_page, - .get_features = at803x_get_features, - .read_status = at803x_read_status, -- .config_intr = at803x_config_intr, -+ .config_intr = at8031_config_intr, - .handle_interrupt = at803x_handle_interrupt, - .get_tunable = at803x_get_tunable, - .set_tunable = at803x_set_tunable, diff --git a/target/linux/generic/backport-6.1/707-v6.8-10-net-phy-at803x-make-at8031-related-DT-functions-name.patch b/target/linux/generic/backport-6.1/707-v6.8-10-net-phy-at803x-make-at8031-related-DT-functions-name.patch deleted file mode 100644 index 210949ea81b985..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-10-net-phy-at803x-make-at8031-related-DT-functions-name.patch +++ /dev/null @@ -1,78 +0,0 @@ -From a5ab9d8e7ae0da8328ac1637a9755311508dc8ab Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:57 +0100 -Subject: [PATCH 10/13] net: phy: at803x: make at8031 related DT functions name - more specific - -Rename at8031 related DT function name to a more specific name -referencing they are only related to at8031 and not to the generic -at803x PHY family. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -583,7 +583,7 @@ static int at803x_resume(struct phy_devi - return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0); - } - --static int at803x_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev, -+static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev, - unsigned int selector) - { - struct phy_device *phydev = rdev_get_drvdata(rdev); -@@ -596,7 +596,7 @@ static int at803x_rgmii_reg_set_voltage_ - AT803X_DEBUG_RGMII_1V8, 0); - } - --static int at803x_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev) -+static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev) - { - struct phy_device *phydev = rdev_get_drvdata(rdev); - int val; -@@ -610,8 +610,8 @@ static int at803x_rgmii_reg_get_voltage_ - - static const struct regulator_ops vddio_regulator_ops = { - .list_voltage = regulator_list_voltage_table, -- .set_voltage_sel = at803x_rgmii_reg_set_voltage_sel, -- .get_voltage_sel = at803x_rgmii_reg_get_voltage_sel, -+ .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel, -+ .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel, - }; - - static const unsigned int vddio_voltage_table[] = { -@@ -666,7 +666,7 @@ static int at8031_register_regulators(st - return 0; - } - --static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) -+static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) - { - struct phy_device *phydev = upstream; - __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support); -@@ -710,10 +710,10 @@ static int at803x_sfp_insert(void *upstr - return 0; - } - --static const struct sfp_upstream_ops at803x_sfp_ops = { -+static const struct sfp_upstream_ops at8031_sfp_ops = { - .attach = phy_sfp_attach, - .detach = phy_sfp_detach, -- .module_insert = at803x_sfp_insert, -+ .module_insert = at8031_sfp_insert, - }; - - static int at803x_parse_dt(struct phy_device *phydev) -@@ -1519,7 +1519,7 @@ static int at8031_parse_dt(struct phy_de - } - - /* Only AR8031/8033 support 1000Base-X for SFP modules */ -- return phy_sfp_probe(phydev, &at803x_sfp_ops); -+ return phy_sfp_probe(phydev, &at8031_sfp_ops); - } - - static int at8031_probe(struct phy_device *phydev) diff --git a/target/linux/generic/backport-6.1/707-v6.8-11-net-phy-at803x-move-at8031-functions-in-dedicated-se.patch b/target/linux/generic/backport-6.1/707-v6.8-11-net-phy-at803x-move-at8031-functions-in-dedicated-se.patch deleted file mode 100644 index 5856b597511833..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-11-net-phy-at803x-move-at8031-functions-in-dedicated-se.patch +++ /dev/null @@ -1,297 +0,0 @@ -From f932a6dc8bae0dae9645b5b1b4c65aed8a8acb2a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:58 +0100 -Subject: [PATCH 11/13] net: phy: at803x: move at8031 functions in dedicated - section - -Move at8031 functions in dedicated section with dedicated at8031 -parse_dt and probe. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 266 +++++++++++++++++++-------------------- - 1 file changed, 133 insertions(+), 133 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -583,139 +583,6 @@ static int at803x_resume(struct phy_devi - return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0); - } - --static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev, -- unsigned int selector) --{ -- struct phy_device *phydev = rdev_get_drvdata(rdev); -- -- if (selector) -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -- 0, AT803X_DEBUG_RGMII_1V8); -- else -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -- AT803X_DEBUG_RGMII_1V8, 0); --} -- --static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev) --{ -- struct phy_device *phydev = rdev_get_drvdata(rdev); -- int val; -- -- val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F); -- if (val < 0) -- return val; -- -- return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0; --} -- --static const struct regulator_ops vddio_regulator_ops = { -- .list_voltage = regulator_list_voltage_table, -- .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel, -- .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel, --}; -- --static const unsigned int vddio_voltage_table[] = { -- 1500000, -- 1800000, --}; -- --static const struct regulator_desc vddio_desc = { -- .name = "vddio", -- .of_match = of_match_ptr("vddio-regulator"), -- .n_voltages = ARRAY_SIZE(vddio_voltage_table), -- .volt_table = vddio_voltage_table, -- .ops = &vddio_regulator_ops, -- .type = REGULATOR_VOLTAGE, -- .owner = THIS_MODULE, --}; -- --static const struct regulator_ops vddh_regulator_ops = { --}; -- --static const struct regulator_desc vddh_desc = { -- .name = "vddh", -- .of_match = of_match_ptr("vddh-regulator"), -- .n_voltages = 1, -- .fixed_uV = 2500000, -- .ops = &vddh_regulator_ops, -- .type = REGULATOR_VOLTAGE, -- .owner = THIS_MODULE, --}; -- --static int at8031_register_regulators(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- struct device *dev = &phydev->mdio.dev; -- struct regulator_config config = { }; -- -- config.dev = dev; -- config.driver_data = phydev; -- -- priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config); -- if (IS_ERR(priv->vddio_rdev)) { -- phydev_err(phydev, "failed to register VDDIO regulator\n"); -- return PTR_ERR(priv->vddio_rdev); -- } -- -- priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config); -- if (IS_ERR(priv->vddh_rdev)) { -- phydev_err(phydev, "failed to register VDDH regulator\n"); -- return PTR_ERR(priv->vddh_rdev); -- } -- -- return 0; --} -- --static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) --{ -- struct phy_device *phydev = upstream; -- __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support); -- __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support); -- DECLARE_PHY_INTERFACE_MASK(interfaces); -- phy_interface_t iface; -- -- linkmode_zero(phy_support); -- phylink_set(phy_support, 1000baseX_Full); -- phylink_set(phy_support, 1000baseT_Full); -- phylink_set(phy_support, Autoneg); -- phylink_set(phy_support, Pause); -- phylink_set(phy_support, Asym_Pause); -- -- linkmode_zero(sfp_support); -- sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces); -- /* Some modules support 10G modes as well as others we support. -- * Mask out non-supported modes so the correct interface is picked. -- */ -- linkmode_and(sfp_support, phy_support, sfp_support); -- -- if (linkmode_empty(sfp_support)) { -- dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n"); -- return -EINVAL; -- } -- -- iface = sfp_select_interface(phydev->sfp_bus, sfp_support); -- -- /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes -- * interface for use with SFP modules. -- * However, some copper modules detected as having a preferred SGMII -- * interface do default to and function in 1000Base-X mode, so just -- * print a warning and allow such modules, as they may have some chance -- * of working. -- */ -- if (iface == PHY_INTERFACE_MODE_SGMII) -- dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n"); -- else if (iface != PHY_INTERFACE_MODE_1000BASEX) -- return -EINVAL; -- -- return 0; --} -- --static const struct sfp_upstream_ops at8031_sfp_ops = { -- .attach = phy_sfp_attach, -- .detach = phy_sfp_detach, -- .module_insert = at8031_sfp_insert, --}; -- - static int at803x_parse_dt(struct phy_device *phydev) - { - struct device_node *node = phydev->mdio.dev.of_node; -@@ -1498,6 +1365,139 @@ static int at803x_cable_test_start(struc - return 0; - } - -+static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev, -+ unsigned int selector) -+{ -+ struct phy_device *phydev = rdev_get_drvdata(rdev); -+ -+ if (selector) -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -+ 0, AT803X_DEBUG_RGMII_1V8); -+ else -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -+ AT803X_DEBUG_RGMII_1V8, 0); -+} -+ -+static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev) -+{ -+ struct phy_device *phydev = rdev_get_drvdata(rdev); -+ int val; -+ -+ val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F); -+ if (val < 0) -+ return val; -+ -+ return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0; -+} -+ -+static const struct regulator_ops vddio_regulator_ops = { -+ .list_voltage = regulator_list_voltage_table, -+ .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel, -+ .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel, -+}; -+ -+static const unsigned int vddio_voltage_table[] = { -+ 1500000, -+ 1800000, -+}; -+ -+static const struct regulator_desc vddio_desc = { -+ .name = "vddio", -+ .of_match = of_match_ptr("vddio-regulator"), -+ .n_voltages = ARRAY_SIZE(vddio_voltage_table), -+ .volt_table = vddio_voltage_table, -+ .ops = &vddio_regulator_ops, -+ .type = REGULATOR_VOLTAGE, -+ .owner = THIS_MODULE, -+}; -+ -+static const struct regulator_ops vddh_regulator_ops = { -+}; -+ -+static const struct regulator_desc vddh_desc = { -+ .name = "vddh", -+ .of_match = of_match_ptr("vddh-regulator"), -+ .n_voltages = 1, -+ .fixed_uV = 2500000, -+ .ops = &vddh_regulator_ops, -+ .type = REGULATOR_VOLTAGE, -+ .owner = THIS_MODULE, -+}; -+ -+static int at8031_register_regulators(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ struct device *dev = &phydev->mdio.dev; -+ struct regulator_config config = { }; -+ -+ config.dev = dev; -+ config.driver_data = phydev; -+ -+ priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config); -+ if (IS_ERR(priv->vddio_rdev)) { -+ phydev_err(phydev, "failed to register VDDIO regulator\n"); -+ return PTR_ERR(priv->vddio_rdev); -+ } -+ -+ priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config); -+ if (IS_ERR(priv->vddh_rdev)) { -+ phydev_err(phydev, "failed to register VDDH regulator\n"); -+ return PTR_ERR(priv->vddh_rdev); -+ } -+ -+ return 0; -+} -+ -+static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) -+{ -+ struct phy_device *phydev = upstream; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support); -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support); -+ DECLARE_PHY_INTERFACE_MASK(interfaces); -+ phy_interface_t iface; -+ -+ linkmode_zero(phy_support); -+ phylink_set(phy_support, 1000baseX_Full); -+ phylink_set(phy_support, 1000baseT_Full); -+ phylink_set(phy_support, Autoneg); -+ phylink_set(phy_support, Pause); -+ phylink_set(phy_support, Asym_Pause); -+ -+ linkmode_zero(sfp_support); -+ sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces); -+ /* Some modules support 10G modes as well as others we support. -+ * Mask out non-supported modes so the correct interface is picked. -+ */ -+ linkmode_and(sfp_support, phy_support, sfp_support); -+ -+ if (linkmode_empty(sfp_support)) { -+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n"); -+ return -EINVAL; -+ } -+ -+ iface = sfp_select_interface(phydev->sfp_bus, sfp_support); -+ -+ /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes -+ * interface for use with SFP modules. -+ * However, some copper modules detected as having a preferred SGMII -+ * interface do default to and function in 1000Base-X mode, so just -+ * print a warning and allow such modules, as they may have some chance -+ * of working. -+ */ -+ if (iface == PHY_INTERFACE_MODE_SGMII) -+ dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n"); -+ else if (iface != PHY_INTERFACE_MODE_1000BASEX) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static const struct sfp_upstream_ops at8031_sfp_ops = { -+ .attach = phy_sfp_attach, -+ .detach = phy_sfp_detach, -+ .module_insert = at8031_sfp_insert, -+}; -+ - static int at8031_parse_dt(struct phy_device *phydev) - { - struct device_node *node = phydev->mdio.dev.of_node; diff --git a/target/linux/generic/backport-6.1/707-v6.8-12-net-phy-at803x-move-at8035-specific-DT-parse-to-dedi.patch b/target/linux/generic/backport-6.1/707-v6.8-12-net-phy-at803x-move-at8035-specific-DT-parse-to-dedi.patch deleted file mode 100644 index 0a822c6d37195e..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-12-net-phy-at803x-move-at8035-specific-DT-parse-to-dedi.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 21a2802a8365cfa82cc02187c1f95136d85592ad Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:51:59 +0100 -Subject: [PATCH 12/13] net: phy: at803x: move at8035 specific DT parse to - dedicated probe - -Move at8035 specific DT parse for clock out frequency to dedicated probe -to make at803x probe function more generic. - -This is to tidy code and no behaviour change are intended. - -Detection logic is changed, we check if the clk 25m mask is set and if -it's not zero, we assume the qca,clk-out-frequency property is set. - -The property is checked in the generic at803x_parse_dt called by -at803x_probe. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 60 +++++++++++++++++++++++++++------------- - 1 file changed, 41 insertions(+), 19 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -638,23 +638,6 @@ static int at803x_parse_dt(struct phy_de - - priv->clk_25m_reg |= FIELD_PREP(AT803X_CLK_OUT_MASK, sel); - priv->clk_25m_mask |= AT803X_CLK_OUT_MASK; -- -- /* Fixup for the AR8030/AR8035. This chip has another mask and -- * doesn't support the DSP reference. Eg. the lowest bit of the -- * mask. The upper two bits select the same frequencies. Mask -- * the lowest bit here. -- * -- * Warning: -- * There was no datasheet for the AR8030 available so this is -- * just a guess. But the AR8035 is listed as pin compatible -- * to the AR8030 so there might be a good chance it works on -- * the AR8030 too. -- */ -- if (phydev->drv->phy_id == ATH8030_PHY_ID || -- phydev->drv->phy_id == ATH8035_PHY_ID) { -- priv->clk_25m_reg &= AT8035_CLK_OUT_MASK; -- priv->clk_25m_mask &= AT8035_CLK_OUT_MASK; -- } - } - - ret = of_property_read_u32(node, "qca,clk-out-strength", &strength); -@@ -1635,6 +1618,45 @@ static int at8031_config_intr(struct phy - return at803x_config_intr(phydev); - } - -+static int at8035_parse_dt(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ -+ /* Mask is set by the generic at803x_parse_dt -+ * if property is set. Assume property is set -+ * with the mask not zero. -+ */ -+ if (priv->clk_25m_mask) { -+ /* Fixup for the AR8030/AR8035. This chip has another mask and -+ * doesn't support the DSP reference. Eg. the lowest bit of the -+ * mask. The upper two bits select the same frequencies. Mask -+ * the lowest bit here. -+ * -+ * Warning: -+ * There was no datasheet for the AR8030 available so this is -+ * just a guess. But the AR8035 is listed as pin compatible -+ * to the AR8030 so there might be a good chance it works on -+ * the AR8030 too. -+ */ -+ priv->clk_25m_reg &= AT8035_CLK_OUT_MASK; -+ priv->clk_25m_mask &= AT8035_CLK_OUT_MASK; -+ } -+ -+ return 0; -+} -+ -+/* AR8030 and AR8035 shared the same special mask for clk_25m */ -+static int at8035_probe(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = at803x_probe(phydev); -+ if (ret) -+ return ret; -+ -+ return at8035_parse_dt(phydev); -+} -+ - static int qca83xx_config_init(struct phy_device *phydev) - { - u8 switch_revision; -@@ -2107,7 +2129,7 @@ static struct phy_driver at803x_driver[] - PHY_ID_MATCH_EXACT(ATH8035_PHY_ID), - .name = "Qualcomm Atheros AR8035", - .flags = PHY_POLL_CABLE_TEST, -- .probe = at803x_probe, -+ .probe = at8035_probe, - .config_aneg = at803x_config_aneg, - .config_init = at803x_config_init, - .soft_reset = genphy_soft_reset, -@@ -2128,7 +2150,7 @@ static struct phy_driver at803x_driver[] - .phy_id = ATH8030_PHY_ID, - .name = "Qualcomm Atheros AR8030", - .phy_id_mask = AT8030_PHY_ID_MASK, -- .probe = at803x_probe, -+ .probe = at8035_probe, - .config_init = at803x_config_init, - .link_change_notify = at803x_link_change_notify, - .set_wol = at803x_set_wol, diff --git a/target/linux/generic/backport-6.1/707-v6.8-13-net-phy-at803x-drop-specific-PHY-ID-check-from-cable.patch b/target/linux/generic/backport-6.1/707-v6.8-13-net-phy-at803x-drop-specific-PHY-ID-check-from-cable.patch deleted file mode 100644 index e1ba6ec2d0f2a8..00000000000000 --- a/target/linux/generic/backport-6.1/707-v6.8-13-net-phy-at803x-drop-specific-PHY-ID-check-from-cable.patch +++ /dev/null @@ -1,219 +0,0 @@ -From ef9df47b449e32e06501a11272809be49019bdb6 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 8 Dec 2023 15:52:00 +0100 -Subject: [PATCH 13/13] net: phy: at803x: drop specific PHY ID check from cable - test functions - -Drop specific PHY ID check for cable test functions for at803x. This is -done to make functions more generic. While at it better describe what -the functions does by using more symbolic function names. - -PHYs that requires to set additional reg are moved to specific function -calling the more generic one. - -cdt_start and cdt_wait_for_completion are changed to take an additional -arg to pass specific values specific to the PHY. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 95 +++++++++++++++++++++------------------- - 1 file changed, 50 insertions(+), 45 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1222,31 +1222,16 @@ static int at803x_cdt_fault_length(u16 s - return (dt * 824) / 10; - } - --static int at803x_cdt_start(struct phy_device *phydev, int pair) -+static int at803x_cdt_start(struct phy_device *phydev, -+ u32 cdt_start) - { -- u16 cdt; -- -- /* qca8081 takes the different bit 15 to enable CDT test */ -- if (phydev->drv->phy_id == QCA8081_PHY_ID) -- cdt = QCA808X_CDT_ENABLE_TEST | -- QCA808X_CDT_LENGTH_UNIT | -- QCA808X_CDT_INTER_CHECK_DIS; -- else -- cdt = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) | -- AT803X_CDT_ENABLE_TEST; -- -- return phy_write(phydev, AT803X_CDT, cdt); -+ return phy_write(phydev, AT803X_CDT, cdt_start); - } - --static int at803x_cdt_wait_for_completion(struct phy_device *phydev) -+static int at803x_cdt_wait_for_completion(struct phy_device *phydev, -+ u32 cdt_en) - { - int val, ret; -- u16 cdt_en; -- -- if (phydev->drv->phy_id == QCA8081_PHY_ID) -- cdt_en = QCA808X_CDT_ENABLE_TEST; -- else -- cdt_en = AT803X_CDT_ENABLE_TEST; - - /* One test run takes about 25ms */ - ret = phy_read_poll_timeout(phydev, AT803X_CDT, val, -@@ -1266,11 +1251,13 @@ static int at803x_cable_test_one_pair(st - }; - int ret, val; - -- ret = at803x_cdt_start(phydev, pair); -+ val = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) | -+ AT803X_CDT_ENABLE_TEST; -+ ret = at803x_cdt_start(phydev, val); - if (ret) - return ret; - -- ret = at803x_cdt_wait_for_completion(phydev); -+ ret = at803x_cdt_wait_for_completion(phydev, AT803X_CDT_ENABLE_TEST); - if (ret) - return ret; - -@@ -1292,19 +1279,11 @@ static int at803x_cable_test_one_pair(st - } - - static int at803x_cable_test_get_status(struct phy_device *phydev, -- bool *finished) -+ bool *finished, unsigned long pair_mask) - { -- unsigned long pair_mask; - int retries = 20; - int pair, ret; - -- if (phydev->phy_id == ATH9331_PHY_ID || -- phydev->phy_id == ATH8032_PHY_ID || -- phydev->phy_id == QCA9561_PHY_ID) -- pair_mask = 0x3; -- else -- pair_mask = 0xf; -- - *finished = false; - - /* According to the datasheet the CDT can be performed when -@@ -1331,7 +1310,7 @@ static int at803x_cable_test_get_status( - return 0; - } - --static int at803x_cable_test_start(struct phy_device *phydev) -+static void at803x_cable_test_autoneg(struct phy_device *phydev) - { - /* Enable auto-negotiation, but advertise no capabilities, no link - * will be established. A restart of the auto-negotiation is not -@@ -1339,11 +1318,11 @@ static int at803x_cable_test_start(struc - */ - phy_write(phydev, MII_BMCR, BMCR_ANENABLE); - phy_write(phydev, MII_ADVERTISE, ADVERTISE_CSMA); -- if (phydev->phy_id != ATH9331_PHY_ID && -- phydev->phy_id != ATH8032_PHY_ID && -- phydev->phy_id != QCA9561_PHY_ID) -- phy_write(phydev, MII_CTRL1000, 0); -+} - -+static int at803x_cable_test_start(struct phy_device *phydev) -+{ -+ at803x_cable_test_autoneg(phydev); - /* we do all the (time consuming) work later */ - return 0; - } -@@ -1618,6 +1597,29 @@ static int at8031_config_intr(struct phy - return at803x_config_intr(phydev); - } - -+/* AR8031 and AR8035 share the same cable test get status reg */ -+static int at8031_cable_test_get_status(struct phy_device *phydev, -+ bool *finished) -+{ -+ return at803x_cable_test_get_status(phydev, finished, 0xf); -+} -+ -+/* AR8031 and AR8035 share the same cable test start logic */ -+static int at8031_cable_test_start(struct phy_device *phydev) -+{ -+ at803x_cable_test_autoneg(phydev); -+ phy_write(phydev, MII_CTRL1000, 0); -+ /* we do all the (time consuming) work later */ -+ return 0; -+} -+ -+/* AR8032, AR9331 and QCA9561 share the same cable test get status reg */ -+static int at8032_cable_test_get_status(struct phy_device *phydev, -+ bool *finished) -+{ -+ return at803x_cable_test_get_status(phydev, finished, 0x3); -+} -+ - static int at8035_parse_dt(struct phy_device *phydev) - { - struct at803x_priv *priv = phydev->priv; -@@ -2041,11 +2043,14 @@ static int qca808x_cable_test_get_status - - *finished = false; - -- ret = at803x_cdt_start(phydev, 0); -+ val = QCA808X_CDT_ENABLE_TEST | -+ QCA808X_CDT_LENGTH_UNIT | -+ QCA808X_CDT_INTER_CHECK_DIS; -+ ret = at803x_cdt_start(phydev, val); - if (ret) - return ret; - -- ret = at803x_cdt_wait_for_completion(phydev); -+ ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); - if (ret) - return ret; - -@@ -2143,8 +2148,8 @@ static struct phy_driver at803x_driver[] - .handle_interrupt = at803x_handle_interrupt, - .get_tunable = at803x_get_tunable, - .set_tunable = at803x_set_tunable, -- .cable_test_start = at803x_cable_test_start, -- .cable_test_get_status = at803x_cable_test_get_status, -+ .cable_test_start = at8031_cable_test_start, -+ .cable_test_get_status = at8031_cable_test_get_status, - }, { - /* Qualcomm Atheros AR8030 */ - .phy_id = ATH8030_PHY_ID, -@@ -2181,8 +2186,8 @@ static struct phy_driver at803x_driver[] - .handle_interrupt = at803x_handle_interrupt, - .get_tunable = at803x_get_tunable, - .set_tunable = at803x_set_tunable, -- .cable_test_start = at803x_cable_test_start, -- .cable_test_get_status = at803x_cable_test_get_status, -+ .cable_test_start = at8031_cable_test_start, -+ .cable_test_get_status = at8031_cable_test_get_status, - }, { - /* Qualcomm Atheros AR8032 */ - PHY_ID_MATCH_EXACT(ATH8032_PHY_ID), -@@ -2197,7 +2202,7 @@ static struct phy_driver at803x_driver[] - .config_intr = at803x_config_intr, - .handle_interrupt = at803x_handle_interrupt, - .cable_test_start = at803x_cable_test_start, -- .cable_test_get_status = at803x_cable_test_get_status, -+ .cable_test_get_status = at8032_cable_test_get_status, - }, { - /* ATHEROS AR9331 */ - PHY_ID_MATCH_EXACT(ATH9331_PHY_ID), -@@ -2210,7 +2215,7 @@ static struct phy_driver at803x_driver[] - .config_intr = at803x_config_intr, - .handle_interrupt = at803x_handle_interrupt, - .cable_test_start = at803x_cable_test_start, -- .cable_test_get_status = at803x_cable_test_get_status, -+ .cable_test_get_status = at8032_cable_test_get_status, - .read_status = at803x_read_status, - .soft_reset = genphy_soft_reset, - .config_aneg = at803x_config_aneg, -@@ -2226,7 +2231,7 @@ static struct phy_driver at803x_driver[] - .config_intr = at803x_config_intr, - .handle_interrupt = at803x_handle_interrupt, - .cable_test_start = at803x_cable_test_start, -- .cable_test_get_status = at803x_cable_test_get_status, -+ .cable_test_get_status = at8032_cable_test_get_status, - .read_status = at803x_read_status, - .soft_reset = genphy_soft_reset, - .config_aneg = at803x_config_aneg, diff --git a/target/linux/generic/backport-6.1/708-v6.8-01-net-phy-at803x-move-specific-qca808x-config_aneg-to-.patch b/target/linux/generic/backport-6.1/708-v6.8-01-net-phy-at803x-move-specific-qca808x-config_aneg-to-.patch deleted file mode 100644 index 0bb3673c02c133..00000000000000 --- a/target/linux/generic/backport-6.1/708-v6.8-01-net-phy-at803x-move-specific-qca808x-config_aneg-to-.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 8e732f1c6f2dc5e18f766d0f1b11df9db2dd044a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 14 Dec 2023 01:44:31 +0100 -Subject: [PATCH 1/2] net: phy: at803x: move specific qca808x config_aneg to - dedicated function - -Move specific qca808x config_aneg to dedicated function to permit easier -split of qca808x portion from at803x driver. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 66 ++++++++++++++++++++++++---------------- - 1 file changed, 40 insertions(+), 26 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1045,9 +1045,8 @@ static int at803x_config_mdix(struct phy - FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val)); - } - --static int at803x_config_aneg(struct phy_device *phydev) -+static int at803x_prepare_config_aneg(struct phy_device *phydev) - { -- struct at803x_priv *priv = phydev->priv; - int ret; - - ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); -@@ -1064,33 +1063,22 @@ static int at803x_config_aneg(struct phy - return ret; - } - -- if (priv->is_1000basex) -- return genphy_c37_config_aneg(phydev); -- -- /* Do not restart auto-negotiation by setting ret to 0 defautly, -- * when calling __genphy_config_aneg later. -- */ -- ret = 0; -- -- if (phydev->drv->phy_id == QCA8081_PHY_ID) { -- int phy_ctrl = 0; -+ return 0; -+} - -- /* The reg MII_BMCR also needs to be configured for force mode, the -- * genphy_config_aneg is also needed. -- */ -- if (phydev->autoneg == AUTONEG_DISABLE) -- genphy_c45_pma_setup_forced(phydev); -+static int at803x_config_aneg(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ int ret; - -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising)) -- phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G; -+ ret = at803x_prepare_config_aneg(phydev); -+ if (ret) -+ return ret; - -- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, -- MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl); -- if (ret < 0) -- return ret; -- } -+ if (priv->is_1000basex) -+ return genphy_c37_config_aneg(phydev); - -- return __genphy_config_aneg(phydev, ret); -+ return genphy_config_aneg(phydev); - } - - static int at803x_get_downshift(struct phy_device *phydev, u8 *d) -@@ -2118,6 +2106,32 @@ static int qca808x_get_features(struct p - return 0; - } - -+static int qca808x_config_aneg(struct phy_device *phydev) -+{ -+ int phy_ctrl = 0; -+ int ret; -+ -+ ret = at803x_prepare_config_aneg(phydev); -+ if (ret) -+ return ret; -+ -+ /* The reg MII_BMCR also needs to be configured for force mode, the -+ * genphy_config_aneg is also needed. -+ */ -+ if (phydev->autoneg == AUTONEG_DISABLE) -+ genphy_c45_pma_setup_forced(phydev); -+ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising)) -+ phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G; -+ -+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, -+ MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl); -+ if (ret < 0) -+ return ret; -+ -+ return __genphy_config_aneg(phydev, ret); -+} -+ - static void qca808x_link_change_notify(struct phy_device *phydev) - { - /* Assert interface sgmii fifo on link down, deassert it on link up, -@@ -2295,7 +2309,7 @@ static struct phy_driver at803x_driver[] - .set_wol = at803x_set_wol, - .get_wol = at803x_get_wol, - .get_features = qca808x_get_features, -- .config_aneg = at803x_config_aneg, -+ .config_aneg = qca808x_config_aneg, - .suspend = genphy_suspend, - .resume = genphy_resume, - .read_status = qca808x_read_status, diff --git a/target/linux/generic/backport-6.1/708-v6.8-02-net-phy-at803x-make-read-specific-status-function-mo.patch b/target/linux/generic/backport-6.1/708-v6.8-02-net-phy-at803x-make-read-specific-status-function-mo.patch deleted file mode 100644 index 54ca3bdfc8258c..00000000000000 --- a/target/linux/generic/backport-6.1/708-v6.8-02-net-phy-at803x-make-read-specific-status-function-mo.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 38eb804e8458ba181a03a0498ce4bf84eebd1931 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 14 Dec 2023 01:44:32 +0100 -Subject: [PATCH 2/2] net: phy: at803x: make read specific status function more - generic - -Rework read specific status function to be more generic. The function -apply different speed mask based on the PHY ID. Make it more generic by -adding an additional arg to pass the specific speed (ss) mask and use -the provided mask to parse the speed value. - -This is needed to permit an easier deatch of qca808x code from the -at803x driver. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 26 ++++++++++++++++++-------- - 1 file changed, 18 insertions(+), 8 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -301,6 +301,11 @@ static struct at803x_hw_stat qca83xx_hw_ - { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD}, - }; - -+struct at803x_ss_mask { -+ u16 speed_mask; -+ u8 speed_shift; -+}; -+ - struct at803x_priv { - int flags; - u16 clk_25m_reg; -@@ -921,7 +926,8 @@ static void at803x_link_change_notify(st - } - } - --static int at803x_read_specific_status(struct phy_device *phydev) -+static int at803x_read_specific_status(struct phy_device *phydev, -+ struct at803x_ss_mask ss_mask) - { - int ss; - -@@ -940,11 +946,8 @@ static int at803x_read_specific_status(s - if (sfc < 0) - return sfc; - -- /* qca8081 takes the different bits for speed value from at803x */ -- if (phydev->drv->phy_id == QCA8081_PHY_ID) -- speed = FIELD_GET(QCA808X_SS_SPEED_MASK, ss); -- else -- speed = FIELD_GET(AT803X_SS_SPEED_MASK, ss); -+ speed = ss & ss_mask.speed_mask; -+ speed >>= ss_mask.speed_shift; - - switch (speed) { - case AT803X_SS_SPEED_10: -@@ -989,6 +992,7 @@ static int at803x_read_specific_status(s - static int at803x_read_status(struct phy_device *phydev) - { - struct at803x_priv *priv = phydev->priv; -+ struct at803x_ss_mask ss_mask = { 0 }; - int err, old_link = phydev->link; - - if (priv->is_1000basex) -@@ -1012,7 +1016,9 @@ static int at803x_read_status(struct phy - if (err < 0) - return err; - -- err = at803x_read_specific_status(phydev); -+ ss_mask.speed_mask = AT803X_SS_SPEED_MASK; -+ ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK); -+ err = at803x_read_specific_status(phydev, ss_mask); - if (err < 0) - return err; - -@@ -1869,6 +1875,7 @@ static int qca808x_config_init(struct ph - - static int qca808x_read_status(struct phy_device *phydev) - { -+ struct at803x_ss_mask ss_mask = { 0 }; - int ret; - - ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); -@@ -1882,7 +1889,10 @@ static int qca808x_read_status(struct ph - if (ret) - return ret; - -- ret = at803x_read_specific_status(phydev); -+ /* qca8081 takes the different bits for speed value from at803x */ -+ ss_mask.speed_mask = QCA808X_SS_SPEED_MASK; -+ ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK); -+ ret = at803x_read_specific_status(phydev, ss_mask); - if (ret < 0) - return ret; - diff --git a/target/linux/generic/backport-6.1/709-v6.8-01-net-phy-at803x-remove-extra-space-after-cast.patch b/target/linux/generic/backport-6.1/709-v6.8-01-net-phy-at803x-remove-extra-space-after-cast.patch deleted file mode 100644 index 8097a33e49eaf0..00000000000000 --- a/target/linux/generic/backport-6.1/709-v6.8-01-net-phy-at803x-remove-extra-space-after-cast.patch +++ /dev/null @@ -1,27 +0,0 @@ -From fc9d7264ddc32eaa647d6bfcdc25cdf9f786fde0 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 18 Dec 2023 00:27:39 +0100 -Subject: [PATCH 1/2] net: phy: at803x: remove extra space after cast - -Remove extra space after cast as reported by checkpatch to keep code -clean. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20231217232739.27065-1-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/at803x.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -462,7 +462,7 @@ static int at803x_set_wol(struct phy_dev - if (!ndev) - return -ENODEV; - -- mac = (const u8 *) ndev->dev_addr; -+ mac = (const u8 *)ndev->dev_addr; - - if (!is_valid_ether_addr(mac)) - return -EINVAL; diff --git a/target/linux/generic/backport-6.1/709-v6.8-02-net-phy-at803x-replace-msleep-1-with-usleep_range.patch b/target/linux/generic/backport-6.1/709-v6.8-02-net-phy-at803x-replace-msleep-1-with-usleep_range.patch deleted file mode 100644 index b8d45910877727..00000000000000 --- a/target/linux/generic/backport-6.1/709-v6.8-02-net-phy-at803x-replace-msleep-1-with-usleep_range.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 3ab5720881a924fb6405d9e6a3b09f1026467c47 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 18 Dec 2023 00:25:08 +0100 -Subject: [PATCH 2/2] net: phy: at803x: replace msleep(1) with usleep_range - -Replace msleep(1) with usleep_range as suggested by timers-howto guide. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20231217232508.26470-1-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/at803x.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -916,9 +916,9 @@ static void at803x_link_change_notify(st - at803x_context_save(phydev, &context); - - phy_device_reset(phydev, 1); -- msleep(1); -+ usleep_range(1000, 2000); - phy_device_reset(phydev, 0); -- msleep(1); -+ usleep_range(1000, 2000); - - at803x_context_restore(phydev, &context); - -@@ -1733,7 +1733,7 @@ static int qca83xx_resume(struct phy_dev - if (ret) - return ret; - -- msleep(1); -+ usleep_range(1000, 2000); - - return 0; - } diff --git a/target/linux/generic/backport-6.1/710-v6.8-net-phy-at803x-better-align-function-varibles-to-ope.patch b/target/linux/generic/backport-6.1/710-v6.8-net-phy-at803x-better-align-function-varibles-to-ope.patch deleted file mode 100644 index 776b7bb43f711f..00000000000000 --- a/target/linux/generic/backport-6.1/710-v6.8-net-phy-at803x-better-align-function-varibles-to-ope.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 7961ef1fa10ec35ad6923fb5751877116e4b035b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 19 Dec 2023 21:21:24 +0100 -Subject: [PATCH] net: phy: at803x: better align function varibles to open - parenthesis - -Better align function variables to open parenthesis as suggested by -checkpatch script for qca808x function to make code cleaner. - -For cable_test_get_status function some additional rework was needed to -handle too long functions. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 67 ++++++++++++++++++++++------------------ - 1 file changed, 37 insertions(+), 30 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1781,27 +1781,27 @@ static int qca808x_phy_fast_retrain_conf - return ret; - - phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1, -- QCA808X_TOP_OPTION1_DATA); -+ QCA808X_TOP_OPTION1_DATA); - phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB, -- QCA808X_MSE_THRESHOLD_20DB_VALUE); -+ QCA808X_MSE_THRESHOLD_20DB_VALUE); - phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB, -- QCA808X_MSE_THRESHOLD_17DB_VALUE); -+ QCA808X_MSE_THRESHOLD_17DB_VALUE); - phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB, -- QCA808X_MSE_THRESHOLD_27DB_VALUE); -+ QCA808X_MSE_THRESHOLD_27DB_VALUE); - phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB, -- QCA808X_MSE_THRESHOLD_28DB_VALUE); -+ QCA808X_MSE_THRESHOLD_28DB_VALUE); - phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1, -- QCA808X_MMD3_DEBUG_1_VALUE); -+ QCA808X_MMD3_DEBUG_1_VALUE); - phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4, -- QCA808X_MMD3_DEBUG_4_VALUE); -+ QCA808X_MMD3_DEBUG_4_VALUE); - phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5, -- QCA808X_MMD3_DEBUG_5_VALUE); -+ QCA808X_MMD3_DEBUG_5_VALUE); - phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3, -- QCA808X_MMD3_DEBUG_3_VALUE); -+ QCA808X_MMD3_DEBUG_3_VALUE); - phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6, -- QCA808X_MMD3_DEBUG_6_VALUE); -+ QCA808X_MMD3_DEBUG_6_VALUE); - phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2, -- QCA808X_MMD3_DEBUG_2_VALUE); -+ QCA808X_MMD3_DEBUG_2_VALUE); - - return 0; - } -@@ -1838,13 +1838,14 @@ static int qca808x_config_init(struct ph - - /* Active adc&vga on 802.3az for the link 1000M and 100M */ - ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7, -- QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN); -+ QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN); - if (ret) - return ret; - - /* Adjust the threshold on 802.3az for the link 1000M */ - ret = phy_write_mmd(phydev, MDIO_MMD_PCS, -- QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, QCA808X_MMD3_AZ_TRAINING_VAL); -+ QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, -+ QCA808X_MMD3_AZ_TRAINING_VAL); - if (ret) - return ret; - -@@ -1870,7 +1871,8 @@ static int qca808x_config_init(struct ph - - /* Configure adc threshold as 100mv for the link 10M */ - return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD, -- QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV); -+ QCA808X_ADC_THRESHOLD_MASK, -+ QCA808X_ADC_THRESHOLD_100MV); - } - - static int qca808x_read_status(struct phy_device *phydev) -@@ -1883,7 +1885,7 @@ static int qca808x_read_status(struct ph - return ret; - - linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising, -- ret & MDIO_AN_10GBT_STAT_LP2_5G); -+ ret & MDIO_AN_10GBT_STAT_LP2_5G); - - ret = genphy_read_status(phydev); - if (ret) -@@ -1913,7 +1915,7 @@ static int qca808x_read_status(struct ph - */ - if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { - if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR || -- qca808x_is_prefer_master(phydev)) { -+ qca808x_is_prefer_master(phydev)) { - qca808x_phy_ms_seed_enable(phydev, false); - } else { - qca808x_phy_ms_seed_enable(phydev, true); -@@ -2070,18 +2072,22 @@ static int qca808x_cable_test_get_status - ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D, - qca808x_cable_test_result_trans(pair_d)); - -- if (qca808x_cdt_fault_length_valid(pair_a)) -- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A, -- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A)); -- if (qca808x_cdt_fault_length_valid(pair_b)) -- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B, -- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B)); -- if (qca808x_cdt_fault_length_valid(pair_c)) -- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C, -- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C)); -- if (qca808x_cdt_fault_length_valid(pair_d)) -- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D, -- qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D)); -+ if (qca808x_cdt_fault_length_valid(pair_a)) { -+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A); -+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A, val); -+ } -+ if (qca808x_cdt_fault_length_valid(pair_b)) { -+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B); -+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B, val); -+ } -+ if (qca808x_cdt_fault_length_valid(pair_c)) { -+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C); -+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C, val); -+ } -+ if (qca808x_cdt_fault_length_valid(pair_d)) { -+ val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D); -+ ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D, val); -+ } - - *finished = true; - -@@ -2148,8 +2154,9 @@ static void qca808x_link_change_notify(s - * the interface device address is always phy address added by 1. - */ - mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1, -- MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL, -- QCA8081_PHY_FIFO_RSTN, phydev->link ? QCA8081_PHY_FIFO_RSTN : 0); -+ MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL, -+ QCA8081_PHY_FIFO_RSTN, -+ phydev->link ? QCA8081_PHY_FIFO_RSTN : 0); - } - - static struct phy_driver at803x_driver[] = { diff --git a/target/linux/generic/backport-6.1/711-v6.8-01-net-phy-at803x-generalize-cdt-fault-length-function.patch b/target/linux/generic/backport-6.1/711-v6.8-01-net-phy-at803x-generalize-cdt-fault-length-function.patch deleted file mode 100644 index d7196da46e1258..00000000000000 --- a/target/linux/generic/backport-6.1/711-v6.8-01-net-phy-at803x-generalize-cdt-fault-length-function.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 22eb276098da820d9440fad22901f9b74ed4d659 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 4 Jan 2024 22:30:38 +0100 -Subject: [PATCH 1/4] net: phy: at803x: generalize cdt fault length function - -Generalize cable test fault length function since they all base on the -same magic values (already reverse engineered to understand the meaning -of it) to have consistenct values on every PHY. - -Signed-off-by: Christian Marangi -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1192,10 +1192,8 @@ static bool at803x_cdt_fault_length_vali - return false; - } - --static int at803x_cdt_fault_length(u16 status) -+static int at803x_cdt_fault_length(int dt) - { -- int dt; -- - /* According to the datasheet the distance to the fault is - * DELTA_TIME * 0.824 meters. - * -@@ -1211,8 +1209,6 @@ static int at803x_cdt_fault_length(u16 s - * With a VF of 0.69 we get the factor 0.824 mentioned in the - * datasheet. - */ -- dt = FIELD_GET(AT803X_CDT_STATUS_DELTA_TIME_MASK, status); -- - return (dt * 824) / 10; - } - -@@ -1265,9 +1261,11 @@ static int at803x_cable_test_one_pair(st - ethnl_cable_test_result(phydev, ethtool_pair[pair], - at803x_cable_test_result_trans(val)); - -- if (at803x_cdt_fault_length_valid(val)) -+ if (at803x_cdt_fault_length_valid(val)) { -+ val = FIELD_GET(AT803X_CDT_STATUS_DELTA_TIME_MASK, val); - ethnl_cable_test_fault_length(phydev, ethtool_pair[pair], - at803x_cdt_fault_length(val)); -+ } - - return 1; - } -@@ -1992,7 +1990,8 @@ static int qca808x_cdt_fault_length(stru - if (val < 0) - return val; - -- return (FIELD_GET(QCA808X_CDT_DIAG_LENGTH, val) * 824) / 10; -+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH, val); -+ return at803x_cdt_fault_length(val); - } - - static int qca808x_cable_test_start(struct phy_device *phydev) diff --git a/target/linux/generic/backport-6.1/711-v6.8-02-net-phy-at803x-refactor-qca808x-cable-test-get-statu.patch b/target/linux/generic/backport-6.1/711-v6.8-02-net-phy-at803x-refactor-qca808x-cable-test-get-statu.patch deleted file mode 100644 index 5d38fe7e91cbb0..00000000000000 --- a/target/linux/generic/backport-6.1/711-v6.8-02-net-phy-at803x-refactor-qca808x-cable-test-get-statu.patch +++ /dev/null @@ -1,118 +0,0 @@ -From e0e9ada1df6133513249861c1d91c1dbefd9383b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 4 Jan 2024 22:30:39 +0100 -Subject: [PATCH 2/4] net: phy: at803x: refactor qca808x cable test get status - function - -Refactor qca808x cable test get status function to remove code -duplication and clean things up. - -The same logic is applied to each pair hence it can be generalized and -moved to a common function. - -Signed-off-by: Christian Marangi -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 80 ++++++++++++++++++++++++---------------- - 1 file changed, 49 insertions(+), 31 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -2035,10 +2035,43 @@ static int qca808x_cable_test_start(stru - return 0; - } - -+static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, -+ u16 status) -+{ -+ u16 pair_code; -+ int length; -+ -+ switch (pair) { -+ case ETHTOOL_A_CABLE_PAIR_A: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_B: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_C: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_D: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ ethnl_cable_test_result(phydev, pair, -+ qca808x_cable_test_result_trans(pair_code)); -+ -+ if (qca808x_cdt_fault_length_valid(pair_code)) { -+ length = qca808x_cdt_fault_length(phydev, pair); -+ ethnl_cable_test_fault_length(phydev, pair, length); -+ } -+ -+ return 0; -+} -+ - static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) - { - int ret, val; -- int pair_a, pair_b, pair_c, pair_d; - - *finished = false; - -@@ -2057,36 +2090,21 @@ static int qca808x_cable_test_get_status - if (val < 0) - return val; - -- pair_a = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, val); -- pair_b = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, val); -- pair_c = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, val); -- pair_d = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, val); -- -- ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A, -- qca808x_cable_test_result_trans(pair_a)); -- ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B, -- qca808x_cable_test_result_trans(pair_b)); -- ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C, -- qca808x_cable_test_result_trans(pair_c)); -- ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D, -- qca808x_cable_test_result_trans(pair_d)); -- -- if (qca808x_cdt_fault_length_valid(pair_a)) { -- val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A); -- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A, val); -- } -- if (qca808x_cdt_fault_length_valid(pair_b)) { -- val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B); -- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B, val); -- } -- if (qca808x_cdt_fault_length_valid(pair_c)) { -- val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C); -- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C, val); -- } -- if (qca808x_cdt_fault_length_valid(pair_d)) { -- val = qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D); -- ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D, val); -- } -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); -+ if (ret) -+ return ret; - - *finished = true; - diff --git a/target/linux/generic/backport-6.1/711-v6.8-03-net-phy-at803x-add-support-for-cdt-cross-short-test-.patch b/target/linux/generic/backport-6.1/711-v6.8-03-net-phy-at803x-add-support-for-cdt-cross-short-test-.patch deleted file mode 100644 index d5793860a96863..00000000000000 --- a/target/linux/generic/backport-6.1/711-v6.8-03-net-phy-at803x-add-support-for-cdt-cross-short-test-.patch +++ /dev/null @@ -1,182 +0,0 @@ -From ea73e5ea442ee2aade67b1fb1233ccb3cbea2ceb Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 4 Jan 2024 22:30:40 +0100 -Subject: [PATCH 3/4] net: phy: at803x: add support for cdt cross short test - for qca808x - -QCA808x PHY Family supports Cable Diagnostic Test also for Cross Pair -Short. - -Add all the define to make enable and support these additional tests. - -Cross Short test was previously disabled by default, this is now changed -and enabled by default. In this mode, the mask changed a bit and length -is shifted based on the fault condition. - -Signed-off-by: Christian Marangi -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 86 ++++++++++++++++++++++++++++++++-------- - 1 file changed, 69 insertions(+), 17 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -254,6 +254,7 @@ - - #define QCA808X_CDT_ENABLE_TEST BIT(15) - #define QCA808X_CDT_INTER_CHECK_DIS BIT(13) -+#define QCA808X_CDT_STATUS BIT(11) - #define QCA808X_CDT_LENGTH_UNIT BIT(10) - - #define QCA808X_MMD3_CDT_STATUS 0x8064 -@@ -261,16 +262,44 @@ - #define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 - #define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 - #define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 --#define QCA808X_CDT_DIAG_LENGTH GENMASK(7, 0) -+#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) -+#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) - - #define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) - #define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) - #define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) - #define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) --#define QCA808X_CDT_STATUS_STAT_FAIL 0 --#define QCA808X_CDT_STATUS_STAT_NORMAL 1 --#define QCA808X_CDT_STATUS_STAT_OPEN 2 --#define QCA808X_CDT_STATUS_STAT_SHORT 3 -+ -+#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) -+#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) -+#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) -+#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) -+#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) -+ -+#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) -+#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) -+#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) -+#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) -+ -+/* NORMAL are MDI with type set to 0 */ -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI1) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI1) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI2) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI2) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI3) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI3) -+ -+/* Added for reference of existence but should be handled by wait_for_completion already */ -+#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) - - /* QCA808X 1G chip type */ - #define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d -@@ -1941,8 +1970,17 @@ static int qca808x_soft_reset(struct phy - static bool qca808x_cdt_fault_length_valid(int cdt_code) - { - switch (cdt_code) { -- case QCA808X_CDT_STATUS_STAT_SHORT: -- case QCA808X_CDT_STATUS_STAT_OPEN: -+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: - return true; - default: - return false; -@@ -1954,17 +1992,28 @@ static int qca808x_cable_test_result_tra - switch (cdt_code) { - case QCA808X_CDT_STATUS_STAT_NORMAL: - return ETHTOOL_A_CABLE_RESULT_CODE_OK; -- case QCA808X_CDT_STATUS_STAT_SHORT: -+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT: - return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; -- case QCA808X_CDT_STATUS_STAT_OPEN: -+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN: - return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -+ return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; - case QCA808X_CDT_STATUS_STAT_FAIL: - default: - return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; - } - } - --static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair) -+static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, -+ int result) - { - int val; - u32 cdt_length_reg = 0; -@@ -1990,7 +2039,11 @@ static int qca808x_cdt_fault_length(stru - if (val < 0) - return val; - -- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH, val); -+ if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) -+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); -+ else -+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); -+ - return at803x_cdt_fault_length(val); - } - -@@ -2038,8 +2091,8 @@ static int qca808x_cable_test_start(stru - static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, - u16 status) - { -+ int length, result; - u16 pair_code; -- int length; - - switch (pair) { - case ETHTOOL_A_CABLE_PAIR_A: -@@ -2058,11 +2111,11 @@ static int qca808x_cable_test_get_pair_s - return -EINVAL; - } - -- ethnl_cable_test_result(phydev, pair, -- qca808x_cable_test_result_trans(pair_code)); -+ result = qca808x_cable_test_result_trans(pair_code); -+ ethnl_cable_test_result(phydev, pair, result); - - if (qca808x_cdt_fault_length_valid(pair_code)) { -- length = qca808x_cdt_fault_length(phydev, pair); -+ length = qca808x_cdt_fault_length(phydev, pair, result); - ethnl_cable_test_fault_length(phydev, pair, length); - } - -@@ -2076,8 +2129,7 @@ static int qca808x_cable_test_get_status - *finished = false; - - val = QCA808X_CDT_ENABLE_TEST | -- QCA808X_CDT_LENGTH_UNIT | -- QCA808X_CDT_INTER_CHECK_DIS; -+ QCA808X_CDT_LENGTH_UNIT; - ret = at803x_cdt_start(phydev, val); - if (ret) - return ret; diff --git a/target/linux/generic/backport-6.1/711-v6.8-04-net-phy-at803x-make-read_status-more-generic.patch b/target/linux/generic/backport-6.1/711-v6.8-04-net-phy-at803x-make-read_status-more-generic.patch deleted file mode 100644 index c146e502fe8c20..00000000000000 --- a/target/linux/generic/backport-6.1/711-v6.8-04-net-phy-at803x-make-read_status-more-generic.patch +++ /dev/null @@ -1,62 +0,0 @@ -From c34d9452d4e5d98a655d7b625e85466320885416 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 4 Jan 2024 22:30:41 +0100 -Subject: [PATCH 4/4] net: phy: at803x: make read_status more generic - -Make read_status more generic in preparation on moving it to shared -library as other PHY Family Driver will have the exact same -implementation. - -The only specific part was a check for AR8031/33 if 1000basex was used. -The check is moved to a dedicated function specific for those PHYs. - -Signed-off-by: Christian Marangi -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/phy/at803x.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -1020,13 +1020,9 @@ static int at803x_read_specific_status(s - - static int at803x_read_status(struct phy_device *phydev) - { -- struct at803x_priv *priv = phydev->priv; - struct at803x_ss_mask ss_mask = { 0 }; - int err, old_link = phydev->link; - -- if (priv->is_1000basex) -- return genphy_c37_read_status(phydev); -- - /* Update the link, but return if there was an error */ - err = genphy_update_link(phydev); - if (err) -@@ -1618,6 +1614,17 @@ static int at8031_config_intr(struct phy - return at803x_config_intr(phydev); - } - -+/* AR8031 and AR8033 share the same read status logic */ -+static int at8031_read_status(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ -+ if (priv->is_1000basex) -+ return genphy_c37_read_status(phydev); -+ -+ return at803x_read_status(phydev); -+} -+ - /* AR8031 and AR8035 share the same cable test get status reg */ - static int at8031_cable_test_get_status(struct phy_device *phydev, - bool *finished) -@@ -2281,7 +2288,7 @@ static struct phy_driver at803x_driver[] - .read_page = at803x_read_page, - .write_page = at803x_write_page, - .get_features = at803x_get_features, -- .read_status = at803x_read_status, -+ .read_status = at8031_read_status, - .config_intr = at8031_config_intr, - .handle_interrupt = at803x_handle_interrupt, - .get_tunable = at803x_get_tunable, diff --git a/target/linux/generic/backport-6.1/712-v6.9-net-phy-at803x-add-LED-support-for-qca808x.patch b/target/linux/generic/backport-6.1/712-v6.9-net-phy-at803x-add-LED-support-for-qca808x.patch deleted file mode 100644 index 36675e7588dd88..00000000000000 --- a/target/linux/generic/backport-6.1/712-v6.9-net-phy-at803x-add-LED-support-for-qca808x.patch +++ /dev/null @@ -1,408 +0,0 @@ -From 7196062b64ee470b91015f3d2e82d225948258ea Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 25 Jan 2024 21:37:01 +0100 -Subject: [PATCH 5/5] net: phy: at803x: add LED support for qca808x - -Add LED support for QCA8081 PHY. - -Documentation for this LEDs PHY is very scarce even with NDA access -to Documentation for OEMs. Only the blink pattern are documented and are -very confusing most of the time. No documentation is present about -forcing the LED on/off or to always blink. - -Those settings were reversed by poking the regs and trying to find the -correct bits to trigger these modes. Some bits mode are not clear and -maybe the documentation option are not 100% correct. For the sake of LED -support the reversed option are enough to add support for current LED -APIs. - -Supported HW control modes are: -- tx -- rx -- link_10 -- link_100 -- link_1000 -- link_2500 -- half_duplex -- full_duplex - -Also add support for LED polarity set to set LED polarity to active -high or low. QSDK sets this value to high by default but PHY reset value -doesn't have this enabled by default. - -QSDK also sets 2 additional bits but their usage is not clear, info about -this is added in the header. It was verified that for correct function -of the LED if active high is needed, only BIT 6 is needed. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240125203702.4552-6-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/at803x.c | 327 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 327 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -301,6 +301,87 @@ - /* Added for reference of existence but should be handled by wait_for_completion already */ - #define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) - -+#define QCA808X_MMD7_LED_GLOBAL 0x8073 -+#define QCA808X_LED_BLINK_1 GENMASK(11, 6) -+#define QCA808X_LED_BLINK_2 GENMASK(5, 0) -+/* Values are the same for both BLINK_1 and BLINK_2 */ -+#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) -+#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) -+#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) -+#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) -+#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) -+#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) -+#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) -+#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) -+#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) -+#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) -+#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) -+#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) -+#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) -+#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) -+#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) -+#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) -+#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) -+#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) -+ -+#define QCA808X_MMD7_LED2_CTRL 0x8074 -+#define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075 -+#define QCA808X_MMD7_LED1_CTRL 0x8076 -+#define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077 -+#define QCA808X_MMD7_LED0_CTRL 0x8078 -+#define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2)) -+ -+/* LED hw control pattern is the same for every LED */ -+#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) -+#define QCA808X_LED_SPEED2500_ON BIT(15) -+#define QCA808X_LED_SPEED2500_BLINK BIT(14) -+/* Follow blink trigger even if duplex or speed condition doesn't match */ -+#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) -+#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) -+#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) -+#define QCA808X_LED_TX_BLINK BIT(10) -+#define QCA808X_LED_RX_BLINK BIT(9) -+#define QCA808X_LED_TX_ON_10MS BIT(8) -+#define QCA808X_LED_RX_ON_10MS BIT(7) -+#define QCA808X_LED_SPEED1000_ON BIT(6) -+#define QCA808X_LED_SPEED100_ON BIT(5) -+#define QCA808X_LED_SPEED10_ON BIT(4) -+#define QCA808X_LED_COLLISION_BLINK BIT(3) -+#define QCA808X_LED_SPEED1000_BLINK BIT(2) -+#define QCA808X_LED_SPEED100_BLINK BIT(1) -+#define QCA808X_LED_SPEED10_BLINK BIT(0) -+ -+#define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079 -+#define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2)) -+ -+/* LED force ctrl is the same for every LED -+ * No documentation exist for this, not even internal one -+ * with NDA as QCOM gives only info about configuring -+ * hw control pattern rules and doesn't indicate any way -+ * to force the LED to specific mode. -+ * These define comes from reverse and testing and maybe -+ * lack of some info or some info are not entirely correct. -+ * For the basic LED control and hw control these finding -+ * are enough to support LED control in all the required APIs. -+ * -+ * On doing some comparison with implementation with qca807x, -+ * it was found that it's 1:1 equal to it and confirms all the -+ * reverse done. It was also found further specification with the -+ * force mode and the blink modes. -+ */ -+#define QCA808X_LED_FORCE_EN BIT(15) -+#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) -+#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) -+#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) -+#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) -+#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) -+ -+#define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a -+/* QSDK sets by default 0x46 to this reg that sets BIT 6 for -+ * LED to active high. It's not clear what BIT 3 and BIT 4 does. -+ */ -+#define QCA808X_LED_ACTIVE_HIGH BIT(6) -+ - /* QCA808X 1G chip type */ - #define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d - #define QCA808X_PHY_CHIP_TYPE_1G BIT(0) -@@ -346,6 +427,7 @@ struct at803x_priv { - struct regulator_dev *vddio_rdev; - struct regulator_dev *vddh_rdev; - u64 stats[ARRAY_SIZE(qca83xx_hw_stats)]; -+ int led_polarity_mode; - }; - - struct at803x_context { -@@ -706,6 +788,9 @@ static int at803x_probe(struct phy_devic - if (!priv) - return -ENOMEM; - -+ /* Init LED polarity mode to -1 */ -+ priv->led_polarity_mode = -1; -+ - phydev->priv = priv; - - ret = at803x_parse_dt(phydev); -@@ -2235,6 +2320,242 @@ static void qca808x_link_change_notify(s - phydev->link ? QCA8081_PHY_FIFO_RSTN : 0); - } - -+static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules, -+ u16 *offload_trigger) -+{ -+ /* Parsing specific to netdev trigger */ -+ if (test_bit(TRIGGER_NETDEV_TX, &rules)) -+ *offload_trigger |= QCA808X_LED_TX_BLINK; -+ if (test_bit(TRIGGER_NETDEV_RX, &rules)) -+ *offload_trigger |= QCA808X_LED_RX_BLINK; -+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED10_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED100_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED1000_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED2500_ON; -+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) -+ *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON; -+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) -+ *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON; -+ -+ if (rules && !*offload_trigger) -+ return -EOPNOTSUPP; -+ -+ /* Enable BLINK_CHECK_BYPASS by default to make the LED -+ * blink even with duplex or speed mode not enabled. -+ */ -+ *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS; -+ -+ return 0; -+} -+ -+static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN); -+} -+ -+static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 offload_trigger = 0; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ return qca808x_led_parse_netdev(phydev, rules, &offload_trigger); -+} -+ -+static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 reg, offload_trigger = 0; -+ int ret; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_CTRL(index); -+ -+ ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_led_hw_control_enable(phydev, index); -+ if (ret) -+ return ret; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_PATTERN_MASK, -+ offload_trigger); -+} -+ -+static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ int val; -+ -+ if (index > 2) -+ return false; -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -+ -+ return !(val & QCA808X_LED_FORCE_EN); -+} -+ -+static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ u16 reg; -+ int val; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ /* Check if we have hw control enabled */ -+ if (qca808x_led_hw_control_status(phydev, index)) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_CTRL(index); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -+ if (val & QCA808X_LED_TX_BLINK) -+ set_bit(TRIGGER_NETDEV_TX, rules); -+ if (val & QCA808X_LED_RX_BLINK) -+ set_bit(TRIGGER_NETDEV_RX, rules); -+ if (val & QCA808X_LED_SPEED10_ON) -+ set_bit(TRIGGER_NETDEV_LINK_10, rules); -+ if (val & QCA808X_LED_SPEED100_ON) -+ set_bit(TRIGGER_NETDEV_LINK_100, rules); -+ if (val & QCA808X_LED_SPEED1000_ON) -+ set_bit(TRIGGER_NETDEV_LINK_1000, rules); -+ if (val & QCA808X_LED_SPEED2500_ON) -+ set_bit(TRIGGER_NETDEV_LINK_2500, rules); -+ if (val & QCA808X_LED_HALF_DUPLEX_ON) -+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); -+ if (val & QCA808X_LED_FULL_DUPLEX_ON) -+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); -+ -+ return 0; -+} -+ -+static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_CTRL(index); -+ -+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_PATTERN_MASK); -+} -+ -+static int qca808x_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ u16 reg; -+ int ret; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ if (!value) { -+ ret = qca808x_led_hw_control_reset(phydev, index); -+ if (ret) -+ return ret; -+ } -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -+ QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON : -+ QCA808X_LED_FORCE_OFF); -+} -+ -+static int qca808x_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ int ret; -+ u16 reg; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ /* Set blink to 50% off, 50% on at 4Hz by default */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, -+ QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, -+ QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); -+ if (ret) -+ return ret; -+ -+ /* We use BLINK_1 for normal blinking */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); -+ if (ret) -+ return ret; -+ -+ /* We set blink to 4Hz, aka 250ms */ -+ *delay_on = 250 / 2; -+ *delay_off = 250 / 2; -+ -+ return 0; -+} -+ -+static int qca808x_led_polarity_set(struct phy_device *phydev, int index, -+ unsigned long modes) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ bool active_low = false; -+ u32 mode; -+ -+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { -+ switch (mode) { -+ case PHY_LED_ACTIVE_LOW: -+ active_low = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ /* PHY polarity is global and can't be set per LED. -+ * To detect this, check if last requested polarity mode -+ * match the new one. -+ */ -+ if (priv->led_polarity_mode >= 0 && -+ priv->led_polarity_mode != active_low) { -+ phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n"); -+ return -EINVAL; -+ } -+ -+ /* Save the last PHY polarity mode */ -+ priv->led_polarity_mode = active_low; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, -+ QCA808X_MMD7_LED_POLARITY_CTRL, -+ QCA808X_LED_ACTIVE_HIGH, -+ active_low ? 0 : QCA808X_LED_ACTIVE_HIGH); -+} -+ - static struct phy_driver at803x_driver[] = { - { - /* Qualcomm Atheros AR8035 */ -@@ -2411,6 +2732,12 @@ static struct phy_driver at803x_driver[] - .cable_test_start = qca808x_cable_test_start, - .cable_test_get_status = qca808x_cable_test_get_status, - .link_change_notify = qca808x_link_change_notify, -+ .led_brightness_set = qca808x_led_brightness_set, -+ .led_blink_set = qca808x_led_blink_set, -+ .led_hw_is_supported = qca808x_led_hw_is_supported, -+ .led_hw_control_set = qca808x_led_hw_control_set, -+ .led_hw_control_get = qca808x_led_hw_control_get, -+ .led_polarity_set = qca808x_led_polarity_set, - }, }; - - module_phy_driver(at803x_driver); diff --git a/target/linux/generic/backport-6.1/713-v6.9-01-net-phy-move-at803x-PHY-driver-to-dedicated-director.patch b/target/linux/generic/backport-6.1/713-v6.9-01-net-phy-move-at803x-PHY-driver-to-dedicated-director.patch deleted file mode 100644 index 8c9babea7b1203..00000000000000 --- a/target/linux/generic/backport-6.1/713-v6.9-01-net-phy-move-at803x-PHY-driver-to-dedicated-director.patch +++ /dev/null @@ -1,5598 +0,0 @@ -From 9e56ff53b4115875667760445b028357848b4748 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 Jan 2024 15:15:19 +0100 -Subject: [PATCH 1/5] net: phy: move at803x PHY driver to dedicated directory - -In preparation for addition of other Qcom PHY and to tidy things up, -move the at803x PHY driver to dedicated directory. - -The same order in the Kconfig selection is saved. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240129141600.2592-2-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/Kconfig | 7 +------ - drivers/net/phy/Makefile | 2 +- - drivers/net/phy/qcom/Kconfig | 7 +++++++ - drivers/net/phy/qcom/Makefile | 2 ++ - drivers/net/phy/{ => qcom}/at803x.c | 0 - 5 files changed, 11 insertions(+), 7 deletions(-) - create mode 100644 drivers/net/phy/qcom/Kconfig - create mode 100644 drivers/net/phy/qcom/Makefile - rename drivers/net/phy/{ => qcom}/at803x.c (100%) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -277,12 +277,7 @@ config NXP_TJA11XX_PHY - help - Currently supports the NXP TJA1100 and TJA1101 PHY. - --config AT803X_PHY -- tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs" -- depends on REGULATOR -- help -- Currently supports the AR8030, AR8031, AR8033, AR8035 and internal -- QCA8337(Internal qca8k PHY) model -+source "drivers/net/phy/qcom/Kconfig" - - config QSEMI_PHY - tristate "Quality Semiconductor PHYs" ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -34,7 +34,6 @@ obj-$(CONFIG_ADIN_PHY) += adin.o - obj-$(CONFIG_ADIN1100_PHY) += adin1100.o - obj-$(CONFIG_AMD_PHY) += amd.o - obj-$(CONFIG_AQUANTIA_PHY) += aquantia/ --obj-$(CONFIG_AT803X_PHY) += at803x.o - obj-$(CONFIG_AX88796B_PHY) += ax88796b.o - obj-$(CONFIG_BCM54140_PHY) += bcm54140.o - obj-$(CONFIG_BCM63XX_PHY) += bcm63xx.o -@@ -75,6 +74,7 @@ obj-$(CONFIG_MOTORCOMM_PHY) += motorcomm - obj-$(CONFIG_NATIONAL_PHY) += national.o - obj-$(CONFIG_NXP_C45_TJA11XX_PHY) += nxp-c45-tja11xx.o - obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o -+obj-y += qcom/ - obj-$(CONFIG_QSEMI_PHY) += qsemi.o - obj-$(CONFIG_REALTEK_PHY) += realtek.o - obj-$(CONFIG_RENESAS_PHY) += uPD60620.o ---- /dev/null -+++ b/drivers/net/phy/qcom/Kconfig -@@ -0,0 +1,7 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+config AT803X_PHY -+ tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs" -+ depends on REGULATOR -+ help -+ Currently supports the AR8030, AR8031, AR8033, AR8035 and internal -+ QCA8337(Internal qca8k PHY) model ---- /dev/null -+++ b/drivers/net/phy/qcom/Makefile -@@ -0,0 +1,2 @@ -+# SPDX-License-Identifier: GPL-2.0 -+obj-$(CONFIG_AT803X_PHY) += at803x.o ---- a/drivers/net/phy/at803x.c -+++ /dev/null -@@ -1,2759 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0+ --/* -- * drivers/net/phy/at803x.c -- * -- * Driver for Qualcomm Atheros AR803x PHY -- * -- * Author: Matus Ujhelyi -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10 --#define AT803X_SFC_ASSERT_CRS BIT(11) --#define AT803X_SFC_FORCE_LINK BIT(10) --#define AT803X_SFC_MDI_CROSSOVER_MODE_M GENMASK(6, 5) --#define AT803X_SFC_AUTOMATIC_CROSSOVER 0x3 --#define AT803X_SFC_MANUAL_MDIX 0x1 --#define AT803X_SFC_MANUAL_MDI 0x0 --#define AT803X_SFC_SQE_TEST BIT(2) --#define AT803X_SFC_POLARITY_REVERSAL BIT(1) --#define AT803X_SFC_DISABLE_JABBER BIT(0) -- --#define AT803X_SPECIFIC_STATUS 0x11 --#define AT803X_SS_SPEED_MASK GENMASK(15, 14) --#define AT803X_SS_SPEED_1000 2 --#define AT803X_SS_SPEED_100 1 --#define AT803X_SS_SPEED_10 0 --#define AT803X_SS_DUPLEX BIT(13) --#define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11) --#define AT803X_SS_MDIX BIT(6) -- --#define QCA808X_SS_SPEED_MASK GENMASK(9, 7) --#define QCA808X_SS_SPEED_2500 4 -- --#define AT803X_INTR_ENABLE 0x12 --#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15) --#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14) --#define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13) --#define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12) --#define AT803X_INTR_ENABLE_LINK_FAIL BIT(11) --#define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10) --#define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8) --#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7) --#define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5) --#define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1) --#define AT803X_INTR_ENABLE_WOL BIT(0) -- --#define AT803X_INTR_STATUS 0x13 -- --#define AT803X_SMART_SPEED 0x14 --#define AT803X_SMART_SPEED_ENABLE BIT(5) --#define AT803X_SMART_SPEED_RETRY_LIMIT_MASK GENMASK(4, 2) --#define AT803X_SMART_SPEED_BYPASS_TIMER BIT(1) --#define AT803X_CDT 0x16 --#define AT803X_CDT_MDI_PAIR_MASK GENMASK(9, 8) --#define AT803X_CDT_ENABLE_TEST BIT(0) --#define AT803X_CDT_STATUS 0x1c --#define AT803X_CDT_STATUS_STAT_NORMAL 0 --#define AT803X_CDT_STATUS_STAT_SHORT 1 --#define AT803X_CDT_STATUS_STAT_OPEN 2 --#define AT803X_CDT_STATUS_STAT_FAIL 3 --#define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8) --#define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0) --#define AT803X_LED_CONTROL 0x18 -- --#define AT803X_PHY_MMD3_WOL_CTRL 0x8012 --#define AT803X_WOL_EN BIT(5) --#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C --#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B --#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A --#define AT803X_REG_CHIP_CONFIG 0x1f --#define AT803X_BT_BX_REG_SEL 0x8000 -- --#define AT803X_DEBUG_ADDR 0x1D --#define AT803X_DEBUG_DATA 0x1E -- --#define AT803X_MODE_CFG_MASK 0x0F --#define AT803X_MODE_CFG_BASET_RGMII 0x00 --#define AT803X_MODE_CFG_BASET_SGMII 0x01 --#define AT803X_MODE_CFG_BX1000_RGMII_50OHM 0x02 --#define AT803X_MODE_CFG_BX1000_RGMII_75OHM 0x03 --#define AT803X_MODE_CFG_BX1000_CONV_50OHM 0x04 --#define AT803X_MODE_CFG_BX1000_CONV_75OHM 0x05 --#define AT803X_MODE_CFG_FX100_RGMII_50OHM 0x06 --#define AT803X_MODE_CFG_FX100_CONV_50OHM 0x07 --#define AT803X_MODE_CFG_RGMII_AUTO_MDET 0x0B --#define AT803X_MODE_CFG_FX100_RGMII_75OHM 0x0E --#define AT803X_MODE_CFG_FX100_CONV_75OHM 0x0F -- --#define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/ --#define AT803X_PSSR_MR_AN_COMPLETE 0x0200 -- --#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00 --#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2) --#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2) --#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) -- --#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05 --#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) -- --#define AT803X_DEBUG_REG_HIB_CTRL 0x0b --#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10) --#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13) --#define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15) -- --#define AT803X_DEBUG_REG_3C 0x3C -- --#define AT803X_DEBUG_REG_GREEN 0x3D --#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6) -- --#define AT803X_DEBUG_REG_1F 0x1F --#define AT803X_DEBUG_PLL_ON BIT(2) --#define AT803X_DEBUG_RGMII_1V8 BIT(3) -- --#define MDIO_AZ_DEBUG 0x800D -- --/* AT803x supports either the XTAL input pad, an internal PLL or the -- * DSP as clock reference for the clock output pad. The XTAL reference -- * is only used for 25 MHz output, all other frequencies need the PLL. -- * The DSP as a clock reference is used in synchronous ethernet -- * applications. -- * -- * By default the PLL is only enabled if there is a link. Otherwise -- * the PHY will go into low power state and disabled the PLL. You can -- * set the PLL_ON bit (see debug register 0x1f) to keep the PLL always -- * enabled. -- */ --#define AT803X_MMD7_CLK25M 0x8016 --#define AT803X_CLK_OUT_MASK GENMASK(4, 2) --#define AT803X_CLK_OUT_25MHZ_XTAL 0 --#define AT803X_CLK_OUT_25MHZ_DSP 1 --#define AT803X_CLK_OUT_50MHZ_PLL 2 --#define AT803X_CLK_OUT_50MHZ_DSP 3 --#define AT803X_CLK_OUT_62_5MHZ_PLL 4 --#define AT803X_CLK_OUT_62_5MHZ_DSP 5 --#define AT803X_CLK_OUT_125MHZ_PLL 6 --#define AT803X_CLK_OUT_125MHZ_DSP 7 -- --/* The AR8035 has another mask which is compatible with the AR8031/AR8033 mask -- * but doesn't support choosing between XTAL/PLL and DSP. -- */ --#define AT8035_CLK_OUT_MASK GENMASK(4, 3) -- --#define AT803X_CLK_OUT_STRENGTH_MASK GENMASK(8, 7) --#define AT803X_CLK_OUT_STRENGTH_FULL 0 --#define AT803X_CLK_OUT_STRENGTH_HALF 1 --#define AT803X_CLK_OUT_STRENGTH_QUARTER 2 -- --#define AT803X_DEFAULT_DOWNSHIFT 5 --#define AT803X_MIN_DOWNSHIFT 2 --#define AT803X_MAX_DOWNSHIFT 9 -- --#define AT803X_MMD3_SMARTEEE_CTL1 0x805b --#define AT803X_MMD3_SMARTEEE_CTL2 0x805c --#define AT803X_MMD3_SMARTEEE_CTL3 0x805d --#define AT803X_MMD3_SMARTEEE_CTL3_LPI_EN BIT(8) -- --#define ATH9331_PHY_ID 0x004dd041 --#define ATH8030_PHY_ID 0x004dd076 --#define ATH8031_PHY_ID 0x004dd074 --#define ATH8032_PHY_ID 0x004dd023 --#define ATH8035_PHY_ID 0x004dd072 --#define AT8030_PHY_ID_MASK 0xffffffef -- --#define QCA8081_PHY_ID 0x004dd101 -- --#define QCA8327_A_PHY_ID 0x004dd033 --#define QCA8327_B_PHY_ID 0x004dd034 --#define QCA8337_PHY_ID 0x004dd036 --#define QCA9561_PHY_ID 0x004dd042 --#define QCA8K_PHY_ID_MASK 0xffffffff -- --#define QCA8K_DEVFLAGS_REVISION_MASK GENMASK(2, 0) -- --#define AT803X_PAGE_FIBER 0 --#define AT803X_PAGE_COPPER 1 -- --/* don't turn off internal PLL */ --#define AT803X_KEEP_PLL_ENABLED BIT(0) --#define AT803X_DISABLE_SMARTEEE BIT(1) -- --/* disable hibernation mode */ --#define AT803X_DISABLE_HIBERNATION_MODE BIT(2) -- --/* ADC threshold */ --#define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80 --#define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0) --#define QCA808X_ADC_THRESHOLD_80MV 0 --#define QCA808X_ADC_THRESHOLD_100MV 0xf0 --#define QCA808X_ADC_THRESHOLD_200MV 0x0f --#define QCA808X_ADC_THRESHOLD_300MV 0xff -- --/* CLD control */ --#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007 --#define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4) --#define QCA808X_8023AZ_AFE_EN 0x90 -- --/* AZ control */ --#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008 --#define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32 -- --#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014 --#define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529 -- --#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E --#define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341 -- --#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E --#define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419 -- --#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020 --#define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341 -- --#define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c --#define QCA808X_TOP_OPTION1_DATA 0x0 -- --#define QCA808X_PHY_MMD3_DEBUG_1 0xa100 --#define QCA808X_MMD3_DEBUG_1_VALUE 0x9203 --#define QCA808X_PHY_MMD3_DEBUG_2 0xa101 --#define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad --#define QCA808X_PHY_MMD3_DEBUG_3 0xa103 --#define QCA808X_MMD3_DEBUG_3_VALUE 0x1698 --#define QCA808X_PHY_MMD3_DEBUG_4 0xa105 --#define QCA808X_MMD3_DEBUG_4_VALUE 0x8001 --#define QCA808X_PHY_MMD3_DEBUG_5 0xa106 --#define QCA808X_MMD3_DEBUG_5_VALUE 0x1111 --#define QCA808X_PHY_MMD3_DEBUG_6 0xa011 --#define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85 -- --/* master/slave seed config */ --#define QCA808X_PHY_DEBUG_LOCAL_SEED 9 --#define QCA808X_MASTER_SLAVE_SEED_ENABLE BIT(1) --#define QCA808X_MASTER_SLAVE_SEED_CFG GENMASK(12, 2) --#define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32 -- --/* Hibernation yields lower power consumpiton in contrast with normal operation mode. -- * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s. -- */ --#define QCA808X_DBG_AN_TEST 0xb --#define QCA808X_HIBERNATION_EN BIT(15) -- --#define QCA808X_CDT_ENABLE_TEST BIT(15) --#define QCA808X_CDT_INTER_CHECK_DIS BIT(13) --#define QCA808X_CDT_STATUS BIT(11) --#define QCA808X_CDT_LENGTH_UNIT BIT(10) -- --#define QCA808X_MMD3_CDT_STATUS 0x8064 --#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 --#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 --#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 --#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 --#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) --#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) -- --#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) --#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) --#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) --#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) -- --#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) --#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) --#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) --#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) --#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) -- --#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) --#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) --#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) --#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) -- --/* NORMAL are MDI with type set to 0 */ --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -- QCA808X_CDT_STATUS_STAT_MDI1) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -- QCA808X_CDT_STATUS_STAT_MDI1) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -- QCA808X_CDT_STATUS_STAT_MDI2) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -- QCA808X_CDT_STATUS_STAT_MDI2) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -- QCA808X_CDT_STATUS_STAT_MDI3) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -- QCA808X_CDT_STATUS_STAT_MDI3) -- --/* Added for reference of existence but should be handled by wait_for_completion already */ --#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) -- --#define QCA808X_MMD7_LED_GLOBAL 0x8073 --#define QCA808X_LED_BLINK_1 GENMASK(11, 6) --#define QCA808X_LED_BLINK_2 GENMASK(5, 0) --/* Values are the same for both BLINK_1 and BLINK_2 */ --#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) --#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) --#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) --#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) --#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) --#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) --#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) --#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) --#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) --#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) --#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) --#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) --#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) --#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) --#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) --#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) --#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) --#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) -- --#define QCA808X_MMD7_LED2_CTRL 0x8074 --#define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075 --#define QCA808X_MMD7_LED1_CTRL 0x8076 --#define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077 --#define QCA808X_MMD7_LED0_CTRL 0x8078 --#define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2)) -- --/* LED hw control pattern is the same for every LED */ --#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) --#define QCA808X_LED_SPEED2500_ON BIT(15) --#define QCA808X_LED_SPEED2500_BLINK BIT(14) --/* Follow blink trigger even if duplex or speed condition doesn't match */ --#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) --#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) --#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) --#define QCA808X_LED_TX_BLINK BIT(10) --#define QCA808X_LED_RX_BLINK BIT(9) --#define QCA808X_LED_TX_ON_10MS BIT(8) --#define QCA808X_LED_RX_ON_10MS BIT(7) --#define QCA808X_LED_SPEED1000_ON BIT(6) --#define QCA808X_LED_SPEED100_ON BIT(5) --#define QCA808X_LED_SPEED10_ON BIT(4) --#define QCA808X_LED_COLLISION_BLINK BIT(3) --#define QCA808X_LED_SPEED1000_BLINK BIT(2) --#define QCA808X_LED_SPEED100_BLINK BIT(1) --#define QCA808X_LED_SPEED10_BLINK BIT(0) -- --#define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079 --#define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2)) -- --/* LED force ctrl is the same for every LED -- * No documentation exist for this, not even internal one -- * with NDA as QCOM gives only info about configuring -- * hw control pattern rules and doesn't indicate any way -- * to force the LED to specific mode. -- * These define comes from reverse and testing and maybe -- * lack of some info or some info are not entirely correct. -- * For the basic LED control and hw control these finding -- * are enough to support LED control in all the required APIs. -- * -- * On doing some comparison with implementation with qca807x, -- * it was found that it's 1:1 equal to it and confirms all the -- * reverse done. It was also found further specification with the -- * force mode and the blink modes. -- */ --#define QCA808X_LED_FORCE_EN BIT(15) --#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) --#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) --#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) --#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) --#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) -- --#define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a --/* QSDK sets by default 0x46 to this reg that sets BIT 6 for -- * LED to active high. It's not clear what BIT 3 and BIT 4 does. -- */ --#define QCA808X_LED_ACTIVE_HIGH BIT(6) -- --/* QCA808X 1G chip type */ --#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d --#define QCA808X_PHY_CHIP_TYPE_1G BIT(0) -- --#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072 --#define QCA8081_PHY_FIFO_RSTN BIT(11) -- --MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver"); --MODULE_AUTHOR("Matus Ujhelyi"); --MODULE_LICENSE("GPL"); -- --enum stat_access_type { -- PHY, -- MMD --}; -- --struct at803x_hw_stat { -- const char *string; -- u8 reg; -- u32 mask; -- enum stat_access_type access_type; --}; -- --static struct at803x_hw_stat qca83xx_hw_stats[] = { -- { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY}, -- { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY}, -- { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD}, --}; -- --struct at803x_ss_mask { -- u16 speed_mask; -- u8 speed_shift; --}; -- --struct at803x_priv { -- int flags; -- u16 clk_25m_reg; -- u16 clk_25m_mask; -- u8 smarteee_lpi_tw_1g; -- u8 smarteee_lpi_tw_100m; -- bool is_fiber; -- bool is_1000basex; -- struct regulator_dev *vddio_rdev; -- struct regulator_dev *vddh_rdev; -- u64 stats[ARRAY_SIZE(qca83xx_hw_stats)]; -- int led_polarity_mode; --}; -- --struct at803x_context { -- u16 bmcr; -- u16 advertise; -- u16 control1000; -- u16 int_enable; -- u16 smart_speed; -- u16 led_control; --}; -- --static int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data) --{ -- int ret; -- -- ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); -- if (ret < 0) -- return ret; -- -- return phy_write(phydev, AT803X_DEBUG_DATA, data); --} -- --static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg) --{ -- int ret; -- -- ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); -- if (ret < 0) -- return ret; -- -- return phy_read(phydev, AT803X_DEBUG_DATA); --} -- --static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, -- u16 clear, u16 set) --{ -- u16 val; -- int ret; -- -- ret = at803x_debug_reg_read(phydev, reg); -- if (ret < 0) -- return ret; -- -- val = ret & 0xffff; -- val &= ~clear; -- val |= set; -- -- return phy_write(phydev, AT803X_DEBUG_DATA, val); --} -- --static int at803x_write_page(struct phy_device *phydev, int page) --{ -- int mask; -- int set; -- -- if (page == AT803X_PAGE_COPPER) { -- set = AT803X_BT_BX_REG_SEL; -- mask = 0; -- } else { -- set = 0; -- mask = AT803X_BT_BX_REG_SEL; -- } -- -- return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set); --} -- --static int at803x_read_page(struct phy_device *phydev) --{ -- int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG); -- -- if (ccr < 0) -- return ccr; -- -- if (ccr & AT803X_BT_BX_REG_SEL) -- return AT803X_PAGE_COPPER; -- -- return AT803X_PAGE_FIBER; --} -- --static int at803x_enable_rx_delay(struct phy_device *phydev) --{ -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0, -- AT803X_DEBUG_RX_CLK_DLY_EN); --} -- --static int at803x_enable_tx_delay(struct phy_device *phydev) --{ -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0, -- AT803X_DEBUG_TX_CLK_DLY_EN); --} -- --static int at803x_disable_rx_delay(struct phy_device *phydev) --{ -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -- AT803X_DEBUG_RX_CLK_DLY_EN, 0); --} -- --static int at803x_disable_tx_delay(struct phy_device *phydev) --{ -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, -- AT803X_DEBUG_TX_CLK_DLY_EN, 0); --} -- --/* save relevant PHY registers to private copy */ --static void at803x_context_save(struct phy_device *phydev, -- struct at803x_context *context) --{ -- context->bmcr = phy_read(phydev, MII_BMCR); -- context->advertise = phy_read(phydev, MII_ADVERTISE); -- context->control1000 = phy_read(phydev, MII_CTRL1000); -- context->int_enable = phy_read(phydev, AT803X_INTR_ENABLE); -- context->smart_speed = phy_read(phydev, AT803X_SMART_SPEED); -- context->led_control = phy_read(phydev, AT803X_LED_CONTROL); --} -- --/* restore relevant PHY registers from private copy */ --static void at803x_context_restore(struct phy_device *phydev, -- const struct at803x_context *context) --{ -- phy_write(phydev, MII_BMCR, context->bmcr); -- phy_write(phydev, MII_ADVERTISE, context->advertise); -- phy_write(phydev, MII_CTRL1000, context->control1000); -- phy_write(phydev, AT803X_INTR_ENABLE, context->int_enable); -- phy_write(phydev, AT803X_SMART_SPEED, context->smart_speed); -- phy_write(phydev, AT803X_LED_CONTROL, context->led_control); --} -- --static int at803x_set_wol(struct phy_device *phydev, -- struct ethtool_wolinfo *wol) --{ -- int ret, irq_enabled; -- -- if (wol->wolopts & WAKE_MAGIC) { -- struct net_device *ndev = phydev->attached_dev; -- const u8 *mac; -- unsigned int i; -- static const unsigned int offsets[] = { -- AT803X_LOC_MAC_ADDR_32_47_OFFSET, -- AT803X_LOC_MAC_ADDR_16_31_OFFSET, -- AT803X_LOC_MAC_ADDR_0_15_OFFSET, -- }; -- -- if (!ndev) -- return -ENODEV; -- -- mac = (const u8 *)ndev->dev_addr; -- -- if (!is_valid_ether_addr(mac)) -- return -EINVAL; -- -- for (i = 0; i < 3; i++) -- phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i], -- mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); -- -- /* Enable WOL interrupt */ -- ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL); -- if (ret) -- return ret; -- } else { -- /* Disable WOL interrupt */ -- ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0); -- if (ret) -- return ret; -- } -- -- /* Clear WOL status */ -- ret = phy_read(phydev, AT803X_INTR_STATUS); -- if (ret < 0) -- return ret; -- -- /* Check if there are other interrupts except for WOL triggered when PHY is -- * in interrupt mode, only the interrupts enabled by AT803X_INTR_ENABLE can -- * be passed up to the interrupt PIN. -- */ -- irq_enabled = phy_read(phydev, AT803X_INTR_ENABLE); -- if (irq_enabled < 0) -- return irq_enabled; -- -- irq_enabled &= ~AT803X_INTR_ENABLE_WOL; -- if (ret & irq_enabled && !phy_polling_mode(phydev)) -- phy_trigger_machine(phydev); -- -- return 0; --} -- --static void at803x_get_wol(struct phy_device *phydev, -- struct ethtool_wolinfo *wol) --{ -- int value; -- -- wol->supported = WAKE_MAGIC; -- wol->wolopts = 0; -- -- value = phy_read(phydev, AT803X_INTR_ENABLE); -- if (value < 0) -- return; -- -- if (value & AT803X_INTR_ENABLE_WOL) -- wol->wolopts |= WAKE_MAGIC; --} -- --static int qca83xx_get_sset_count(struct phy_device *phydev) --{ -- return ARRAY_SIZE(qca83xx_hw_stats); --} -- --static void qca83xx_get_strings(struct phy_device *phydev, u8 *data) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) { -- strscpy(data + i * ETH_GSTRING_LEN, -- qca83xx_hw_stats[i].string, ETH_GSTRING_LEN); -- } --} -- --static u64 qca83xx_get_stat(struct phy_device *phydev, int i) --{ -- struct at803x_hw_stat stat = qca83xx_hw_stats[i]; -- struct at803x_priv *priv = phydev->priv; -- int val; -- u64 ret; -- -- if (stat.access_type == MMD) -- val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg); -- else -- val = phy_read(phydev, stat.reg); -- -- if (val < 0) { -- ret = U64_MAX; -- } else { -- val = val & stat.mask; -- priv->stats[i] += val; -- ret = priv->stats[i]; -- } -- -- return ret; --} -- --static void qca83xx_get_stats(struct phy_device *phydev, -- struct ethtool_stats *stats, u64 *data) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) -- data[i] = qca83xx_get_stat(phydev, i); --} -- --static int at803x_suspend(struct phy_device *phydev) --{ -- int value; -- int wol_enabled; -- -- value = phy_read(phydev, AT803X_INTR_ENABLE); -- wol_enabled = value & AT803X_INTR_ENABLE_WOL; -- -- if (wol_enabled) -- value = BMCR_ISOLATE; -- else -- value = BMCR_PDOWN; -- -- phy_modify(phydev, MII_BMCR, 0, value); -- -- return 0; --} -- --static int at803x_resume(struct phy_device *phydev) --{ -- return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0); --} -- --static int at803x_parse_dt(struct phy_device *phydev) --{ -- struct device_node *node = phydev->mdio.dev.of_node; -- struct at803x_priv *priv = phydev->priv; -- u32 freq, strength, tw; -- unsigned int sel; -- int ret; -- -- if (!IS_ENABLED(CONFIG_OF_MDIO)) -- return 0; -- -- if (of_property_read_bool(node, "qca,disable-smarteee")) -- priv->flags |= AT803X_DISABLE_SMARTEEE; -- -- if (of_property_read_bool(node, "qca,disable-hibernation-mode")) -- priv->flags |= AT803X_DISABLE_HIBERNATION_MODE; -- -- if (!of_property_read_u32(node, "qca,smarteee-tw-us-1g", &tw)) { -- if (!tw || tw > 255) { -- phydev_err(phydev, "invalid qca,smarteee-tw-us-1g\n"); -- return -EINVAL; -- } -- priv->smarteee_lpi_tw_1g = tw; -- } -- -- if (!of_property_read_u32(node, "qca,smarteee-tw-us-100m", &tw)) { -- if (!tw || tw > 255) { -- phydev_err(phydev, "invalid qca,smarteee-tw-us-100m\n"); -- return -EINVAL; -- } -- priv->smarteee_lpi_tw_100m = tw; -- } -- -- ret = of_property_read_u32(node, "qca,clk-out-frequency", &freq); -- if (!ret) { -- switch (freq) { -- case 25000000: -- sel = AT803X_CLK_OUT_25MHZ_XTAL; -- break; -- case 50000000: -- sel = AT803X_CLK_OUT_50MHZ_PLL; -- break; -- case 62500000: -- sel = AT803X_CLK_OUT_62_5MHZ_PLL; -- break; -- case 125000000: -- sel = AT803X_CLK_OUT_125MHZ_PLL; -- break; -- default: -- phydev_err(phydev, "invalid qca,clk-out-frequency\n"); -- return -EINVAL; -- } -- -- priv->clk_25m_reg |= FIELD_PREP(AT803X_CLK_OUT_MASK, sel); -- priv->clk_25m_mask |= AT803X_CLK_OUT_MASK; -- } -- -- ret = of_property_read_u32(node, "qca,clk-out-strength", &strength); -- if (!ret) { -- priv->clk_25m_mask |= AT803X_CLK_OUT_STRENGTH_MASK; -- switch (strength) { -- case AR803X_STRENGTH_FULL: -- priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_FULL; -- break; -- case AR803X_STRENGTH_HALF: -- priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_HALF; -- break; -- case AR803X_STRENGTH_QUARTER: -- priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_QUARTER; -- break; -- default: -- phydev_err(phydev, "invalid qca,clk-out-strength\n"); -- return -EINVAL; -- } -- } -- -- return 0; --} -- --static int at803x_probe(struct phy_device *phydev) --{ -- struct device *dev = &phydev->mdio.dev; -- struct at803x_priv *priv; -- int ret; -- -- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- -- /* Init LED polarity mode to -1 */ -- priv->led_polarity_mode = -1; -- -- phydev->priv = priv; -- -- ret = at803x_parse_dt(phydev); -- if (ret) -- return ret; -- -- return 0; --} -- --static int at803x_get_features(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- int err; -- -- err = genphy_read_abilities(phydev); -- if (err) -- return err; -- -- if (phydev->drv->phy_id != ATH8031_PHY_ID) -- return 0; -- -- /* AR8031/AR8033 have different status registers -- * for copper and fiber operation. However, the -- * extended status register is the same for both -- * operation modes. -- * -- * As a result of that, ESTATUS_1000_XFULL is set -- * to 1 even when operating in copper TP mode. -- * -- * Remove this mode from the supported link modes -- * when not operating in 1000BaseX mode. -- */ -- if (!priv->is_1000basex) -- linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, -- phydev->supported); -- -- return 0; --} -- --static int at803x_smarteee_config(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- u16 mask = 0, val = 0; -- int ret; -- -- if (priv->flags & AT803X_DISABLE_SMARTEEE) -- return phy_modify_mmd(phydev, MDIO_MMD_PCS, -- AT803X_MMD3_SMARTEEE_CTL3, -- AT803X_MMD3_SMARTEEE_CTL3_LPI_EN, 0); -- -- if (priv->smarteee_lpi_tw_1g) { -- mask |= 0xff00; -- val |= priv->smarteee_lpi_tw_1g << 8; -- } -- if (priv->smarteee_lpi_tw_100m) { -- mask |= 0x00ff; -- val |= priv->smarteee_lpi_tw_100m; -- } -- if (!mask) -- return 0; -- -- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL1, -- mask, val); -- if (ret) -- return ret; -- -- return phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL3, -- AT803X_MMD3_SMARTEEE_CTL3_LPI_EN, -- AT803X_MMD3_SMARTEEE_CTL3_LPI_EN); --} -- --static int at803x_clk_out_config(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- -- if (!priv->clk_25m_mask) -- return 0; -- -- return phy_modify_mmd(phydev, MDIO_MMD_AN, AT803X_MMD7_CLK25M, -- priv->clk_25m_mask, priv->clk_25m_reg); --} -- --static int at8031_pll_config(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- -- /* The default after hardware reset is PLL OFF. After a soft reset, the -- * values are retained. -- */ -- if (priv->flags & AT803X_KEEP_PLL_ENABLED) -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -- 0, AT803X_DEBUG_PLL_ON); -- else -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -- AT803X_DEBUG_PLL_ON, 0); --} -- --static int at803x_hibernation_mode_config(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- -- /* The default after hardware reset is hibernation mode enabled. After -- * software reset, the value is retained. -- */ -- if (!(priv->flags & AT803X_DISABLE_HIBERNATION_MODE)) -- return 0; -- -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL, -- AT803X_DEBUG_HIB_CTRL_PS_HIB_EN, 0); --} -- --static int at803x_config_init(struct phy_device *phydev) --{ -- int ret; -- -- /* The RX and TX delay default is: -- * after HW reset: RX delay enabled and TX delay disabled -- * after SW reset: RX delay enabled, while TX delay retains the -- * value before reset. -- */ -- if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || -- phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) -- ret = at803x_enable_rx_delay(phydev); -- else -- ret = at803x_disable_rx_delay(phydev); -- if (ret < 0) -- return ret; -- -- if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || -- phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) -- ret = at803x_enable_tx_delay(phydev); -- else -- ret = at803x_disable_tx_delay(phydev); -- if (ret < 0) -- return ret; -- -- ret = at803x_smarteee_config(phydev); -- if (ret < 0) -- return ret; -- -- ret = at803x_clk_out_config(phydev); -- if (ret < 0) -- return ret; -- -- ret = at803x_hibernation_mode_config(phydev); -- if (ret < 0) -- return ret; -- -- /* Ar803x extended next page bit is enabled by default. Cisco -- * multigig switches read this bit and attempt to negotiate 10Gbps -- * rates even if the next page bit is disabled. This is incorrect -- * behaviour but we still need to accommodate it. XNP is only needed -- * for 10Gbps support, so disable XNP. -- */ -- return phy_modify(phydev, MII_ADVERTISE, MDIO_AN_CTRL1_XNP, 0); --} -- --static int at803x_ack_interrupt(struct phy_device *phydev) --{ -- int err; -- -- err = phy_read(phydev, AT803X_INTR_STATUS); -- -- return (err < 0) ? err : 0; --} -- --static int at803x_config_intr(struct phy_device *phydev) --{ -- int err; -- int value; -- -- value = phy_read(phydev, AT803X_INTR_ENABLE); -- -- if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { -- /* Clear any pending interrupts */ -- err = at803x_ack_interrupt(phydev); -- if (err) -- return err; -- -- value |= AT803X_INTR_ENABLE_AUTONEG_ERR; -- value |= AT803X_INTR_ENABLE_SPEED_CHANGED; -- value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED; -- value |= AT803X_INTR_ENABLE_LINK_FAIL; -- value |= AT803X_INTR_ENABLE_LINK_SUCCESS; -- -- err = phy_write(phydev, AT803X_INTR_ENABLE, value); -- } else { -- err = phy_write(phydev, AT803X_INTR_ENABLE, 0); -- if (err) -- return err; -- -- /* Clear any pending interrupts */ -- err = at803x_ack_interrupt(phydev); -- } -- -- return err; --} -- --static irqreturn_t at803x_handle_interrupt(struct phy_device *phydev) --{ -- int irq_status, int_enabled; -- -- irq_status = phy_read(phydev, AT803X_INTR_STATUS); -- if (irq_status < 0) { -- phy_error(phydev); -- return IRQ_NONE; -- } -- -- /* Read the current enabled interrupts */ -- int_enabled = phy_read(phydev, AT803X_INTR_ENABLE); -- if (int_enabled < 0) { -- phy_error(phydev); -- return IRQ_NONE; -- } -- -- /* See if this was one of our enabled interrupts */ -- if (!(irq_status & int_enabled)) -- return IRQ_NONE; -- -- phy_trigger_machine(phydev); -- -- return IRQ_HANDLED; --} -- --static void at803x_link_change_notify(struct phy_device *phydev) --{ -- /* -- * Conduct a hardware reset for AT8030 every time a link loss is -- * signalled. This is necessary to circumvent a hardware bug that -- * occurs when the cable is unplugged while TX packets are pending -- * in the FIFO. In such cases, the FIFO enters an error mode it -- * cannot recover from by software. -- */ -- if (phydev->state == PHY_NOLINK && phydev->mdio.reset_gpio) { -- struct at803x_context context; -- -- at803x_context_save(phydev, &context); -- -- phy_device_reset(phydev, 1); -- usleep_range(1000, 2000); -- phy_device_reset(phydev, 0); -- usleep_range(1000, 2000); -- -- at803x_context_restore(phydev, &context); -- -- phydev_dbg(phydev, "%s(): phy was reset\n", __func__); -- } --} -- --static int at803x_read_specific_status(struct phy_device *phydev, -- struct at803x_ss_mask ss_mask) --{ -- int ss; -- -- /* Read the AT8035 PHY-Specific Status register, which indicates the -- * speed and duplex that the PHY is actually using, irrespective of -- * whether we are in autoneg mode or not. -- */ -- ss = phy_read(phydev, AT803X_SPECIFIC_STATUS); -- if (ss < 0) -- return ss; -- -- if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) { -- int sfc, speed; -- -- sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL); -- if (sfc < 0) -- return sfc; -- -- speed = ss & ss_mask.speed_mask; -- speed >>= ss_mask.speed_shift; -- -- switch (speed) { -- case AT803X_SS_SPEED_10: -- phydev->speed = SPEED_10; -- break; -- case AT803X_SS_SPEED_100: -- phydev->speed = SPEED_100; -- break; -- case AT803X_SS_SPEED_1000: -- phydev->speed = SPEED_1000; -- break; -- case QCA808X_SS_SPEED_2500: -- phydev->speed = SPEED_2500; -- break; -- } -- if (ss & AT803X_SS_DUPLEX) -- phydev->duplex = DUPLEX_FULL; -- else -- phydev->duplex = DUPLEX_HALF; -- -- if (ss & AT803X_SS_MDIX) -- phydev->mdix = ETH_TP_MDI_X; -- else -- phydev->mdix = ETH_TP_MDI; -- -- switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) { -- case AT803X_SFC_MANUAL_MDI: -- phydev->mdix_ctrl = ETH_TP_MDI; -- break; -- case AT803X_SFC_MANUAL_MDIX: -- phydev->mdix_ctrl = ETH_TP_MDI_X; -- break; -- case AT803X_SFC_AUTOMATIC_CROSSOVER: -- phydev->mdix_ctrl = ETH_TP_MDI_AUTO; -- break; -- } -- } -- -- return 0; --} -- --static int at803x_read_status(struct phy_device *phydev) --{ -- struct at803x_ss_mask ss_mask = { 0 }; -- int err, old_link = phydev->link; -- -- /* Update the link, but return if there was an error */ -- err = genphy_update_link(phydev); -- if (err) -- return err; -- -- /* why bother the PHY if nothing can have changed */ -- if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) -- return 0; -- -- phydev->speed = SPEED_UNKNOWN; -- phydev->duplex = DUPLEX_UNKNOWN; -- phydev->pause = 0; -- phydev->asym_pause = 0; -- -- err = genphy_read_lpa(phydev); -- if (err < 0) -- return err; -- -- ss_mask.speed_mask = AT803X_SS_SPEED_MASK; -- ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK); -- err = at803x_read_specific_status(phydev, ss_mask); -- if (err < 0) -- return err; -- -- if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) -- phy_resolve_aneg_pause(phydev); -- -- return 0; --} -- --static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl) --{ -- u16 val; -- -- switch (ctrl) { -- case ETH_TP_MDI: -- val = AT803X_SFC_MANUAL_MDI; -- break; -- case ETH_TP_MDI_X: -- val = AT803X_SFC_MANUAL_MDIX; -- break; -- case ETH_TP_MDI_AUTO: -- val = AT803X_SFC_AUTOMATIC_CROSSOVER; -- break; -- default: -- return 0; -- } -- -- return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL, -- AT803X_SFC_MDI_CROSSOVER_MODE_M, -- FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val)); --} -- --static int at803x_prepare_config_aneg(struct phy_device *phydev) --{ -- int ret; -- -- ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); -- if (ret < 0) -- return ret; -- -- /* Changes of the midx bits are disruptive to the normal operation; -- * therefore any changes to these registers must be followed by a -- * software reset to take effect. -- */ -- if (ret == 1) { -- ret = genphy_soft_reset(phydev); -- if (ret < 0) -- return ret; -- } -- -- return 0; --} -- --static int at803x_config_aneg(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- int ret; -- -- ret = at803x_prepare_config_aneg(phydev); -- if (ret) -- return ret; -- -- if (priv->is_1000basex) -- return genphy_c37_config_aneg(phydev); -- -- return genphy_config_aneg(phydev); --} -- --static int at803x_get_downshift(struct phy_device *phydev, u8 *d) --{ -- int val; -- -- val = phy_read(phydev, AT803X_SMART_SPEED); -- if (val < 0) -- return val; -- -- if (val & AT803X_SMART_SPEED_ENABLE) -- *d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2; -- else -- *d = DOWNSHIFT_DEV_DISABLE; -- -- return 0; --} -- --static int at803x_set_downshift(struct phy_device *phydev, u8 cnt) --{ -- u16 mask, set; -- int ret; -- -- switch (cnt) { -- case DOWNSHIFT_DEV_DEFAULT_COUNT: -- cnt = AT803X_DEFAULT_DOWNSHIFT; -- fallthrough; -- case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT: -- set = AT803X_SMART_SPEED_ENABLE | -- AT803X_SMART_SPEED_BYPASS_TIMER | -- FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2); -- mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK; -- break; -- case DOWNSHIFT_DEV_DISABLE: -- set = 0; -- mask = AT803X_SMART_SPEED_ENABLE | -- AT803X_SMART_SPEED_BYPASS_TIMER; -- break; -- default: -- return -EINVAL; -- } -- -- ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set); -- -- /* After changing the smart speed settings, we need to perform a -- * software reset, use phy_init_hw() to make sure we set the -- * reapply any values which might got lost during software reset. -- */ -- if (ret == 1) -- ret = phy_init_hw(phydev); -- -- return ret; --} -- --static int at803x_get_tunable(struct phy_device *phydev, -- struct ethtool_tunable *tuna, void *data) --{ -- switch (tuna->id) { -- case ETHTOOL_PHY_DOWNSHIFT: -- return at803x_get_downshift(phydev, data); -- default: -- return -EOPNOTSUPP; -- } --} -- --static int at803x_set_tunable(struct phy_device *phydev, -- struct ethtool_tunable *tuna, const void *data) --{ -- switch (tuna->id) { -- case ETHTOOL_PHY_DOWNSHIFT: -- return at803x_set_downshift(phydev, *(const u8 *)data); -- default: -- return -EOPNOTSUPP; -- } --} -- --static int at803x_cable_test_result_trans(u16 status) --{ -- switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) { -- case AT803X_CDT_STATUS_STAT_NORMAL: -- return ETHTOOL_A_CABLE_RESULT_CODE_OK; -- case AT803X_CDT_STATUS_STAT_SHORT: -- return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; -- case AT803X_CDT_STATUS_STAT_OPEN: -- return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; -- case AT803X_CDT_STATUS_STAT_FAIL: -- default: -- return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; -- } --} -- --static bool at803x_cdt_test_failed(u16 status) --{ -- return FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status) == -- AT803X_CDT_STATUS_STAT_FAIL; --} -- --static bool at803x_cdt_fault_length_valid(u16 status) --{ -- switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) { -- case AT803X_CDT_STATUS_STAT_OPEN: -- case AT803X_CDT_STATUS_STAT_SHORT: -- return true; -- } -- return false; --} -- --static int at803x_cdt_fault_length(int dt) --{ -- /* According to the datasheet the distance to the fault is -- * DELTA_TIME * 0.824 meters. -- * -- * The author suspect the correct formula is: -- * -- * fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2 -- * -- * where c is the speed of light, VF is the velocity factor of -- * the twisted pair cable, 125MHz the counter frequency and -- * we need to divide by 2 because the hardware will measure the -- * round trip time to the fault and back to the PHY. -- * -- * With a VF of 0.69 we get the factor 0.824 mentioned in the -- * datasheet. -- */ -- return (dt * 824) / 10; --} -- --static int at803x_cdt_start(struct phy_device *phydev, -- u32 cdt_start) --{ -- return phy_write(phydev, AT803X_CDT, cdt_start); --} -- --static int at803x_cdt_wait_for_completion(struct phy_device *phydev, -- u32 cdt_en) --{ -- int val, ret; -- -- /* One test run takes about 25ms */ -- ret = phy_read_poll_timeout(phydev, AT803X_CDT, val, -- !(val & cdt_en), -- 30000, 100000, true); -- -- return ret < 0 ? ret : 0; --} -- --static int at803x_cable_test_one_pair(struct phy_device *phydev, int pair) --{ -- static const int ethtool_pair[] = { -- ETHTOOL_A_CABLE_PAIR_A, -- ETHTOOL_A_CABLE_PAIR_B, -- ETHTOOL_A_CABLE_PAIR_C, -- ETHTOOL_A_CABLE_PAIR_D, -- }; -- int ret, val; -- -- val = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) | -- AT803X_CDT_ENABLE_TEST; -- ret = at803x_cdt_start(phydev, val); -- if (ret) -- return ret; -- -- ret = at803x_cdt_wait_for_completion(phydev, AT803X_CDT_ENABLE_TEST); -- if (ret) -- return ret; -- -- val = phy_read(phydev, AT803X_CDT_STATUS); -- if (val < 0) -- return val; -- -- if (at803x_cdt_test_failed(val)) -- return 0; -- -- ethnl_cable_test_result(phydev, ethtool_pair[pair], -- at803x_cable_test_result_trans(val)); -- -- if (at803x_cdt_fault_length_valid(val)) { -- val = FIELD_GET(AT803X_CDT_STATUS_DELTA_TIME_MASK, val); -- ethnl_cable_test_fault_length(phydev, ethtool_pair[pair], -- at803x_cdt_fault_length(val)); -- } -- -- return 1; --} -- --static int at803x_cable_test_get_status(struct phy_device *phydev, -- bool *finished, unsigned long pair_mask) --{ -- int retries = 20; -- int pair, ret; -- -- *finished = false; -- -- /* According to the datasheet the CDT can be performed when -- * there is no link partner or when the link partner is -- * auto-negotiating. Starting the test will restart the AN -- * automatically. It seems that doing this repeatedly we will -- * get a slot where our link partner won't disturb our -- * measurement. -- */ -- while (pair_mask && retries--) { -- for_each_set_bit(pair, &pair_mask, 4) { -- ret = at803x_cable_test_one_pair(phydev, pair); -- if (ret < 0) -- return ret; -- if (ret) -- clear_bit(pair, &pair_mask); -- } -- if (pair_mask) -- msleep(250); -- } -- -- *finished = true; -- -- return 0; --} -- --static void at803x_cable_test_autoneg(struct phy_device *phydev) --{ -- /* Enable auto-negotiation, but advertise no capabilities, no link -- * will be established. A restart of the auto-negotiation is not -- * required, because the cable test will automatically break the link. -- */ -- phy_write(phydev, MII_BMCR, BMCR_ANENABLE); -- phy_write(phydev, MII_ADVERTISE, ADVERTISE_CSMA); --} -- --static int at803x_cable_test_start(struct phy_device *phydev) --{ -- at803x_cable_test_autoneg(phydev); -- /* we do all the (time consuming) work later */ -- return 0; --} -- --static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev, -- unsigned int selector) --{ -- struct phy_device *phydev = rdev_get_drvdata(rdev); -- -- if (selector) -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -- 0, AT803X_DEBUG_RGMII_1V8); -- else -- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -- AT803X_DEBUG_RGMII_1V8, 0); --} -- --static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev) --{ -- struct phy_device *phydev = rdev_get_drvdata(rdev); -- int val; -- -- val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F); -- if (val < 0) -- return val; -- -- return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0; --} -- --static const struct regulator_ops vddio_regulator_ops = { -- .list_voltage = regulator_list_voltage_table, -- .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel, -- .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel, --}; -- --static const unsigned int vddio_voltage_table[] = { -- 1500000, -- 1800000, --}; -- --static const struct regulator_desc vddio_desc = { -- .name = "vddio", -- .of_match = of_match_ptr("vddio-regulator"), -- .n_voltages = ARRAY_SIZE(vddio_voltage_table), -- .volt_table = vddio_voltage_table, -- .ops = &vddio_regulator_ops, -- .type = REGULATOR_VOLTAGE, -- .owner = THIS_MODULE, --}; -- --static const struct regulator_ops vddh_regulator_ops = { --}; -- --static const struct regulator_desc vddh_desc = { -- .name = "vddh", -- .of_match = of_match_ptr("vddh-regulator"), -- .n_voltages = 1, -- .fixed_uV = 2500000, -- .ops = &vddh_regulator_ops, -- .type = REGULATOR_VOLTAGE, -- .owner = THIS_MODULE, --}; -- --static int at8031_register_regulators(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- struct device *dev = &phydev->mdio.dev; -- struct regulator_config config = { }; -- -- config.dev = dev; -- config.driver_data = phydev; -- -- priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config); -- if (IS_ERR(priv->vddio_rdev)) { -- phydev_err(phydev, "failed to register VDDIO regulator\n"); -- return PTR_ERR(priv->vddio_rdev); -- } -- -- priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config); -- if (IS_ERR(priv->vddh_rdev)) { -- phydev_err(phydev, "failed to register VDDH regulator\n"); -- return PTR_ERR(priv->vddh_rdev); -- } -- -- return 0; --} -- --static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) --{ -- struct phy_device *phydev = upstream; -- __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support); -- __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support); -- DECLARE_PHY_INTERFACE_MASK(interfaces); -- phy_interface_t iface; -- -- linkmode_zero(phy_support); -- phylink_set(phy_support, 1000baseX_Full); -- phylink_set(phy_support, 1000baseT_Full); -- phylink_set(phy_support, Autoneg); -- phylink_set(phy_support, Pause); -- phylink_set(phy_support, Asym_Pause); -- -- linkmode_zero(sfp_support); -- sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces); -- /* Some modules support 10G modes as well as others we support. -- * Mask out non-supported modes so the correct interface is picked. -- */ -- linkmode_and(sfp_support, phy_support, sfp_support); -- -- if (linkmode_empty(sfp_support)) { -- dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n"); -- return -EINVAL; -- } -- -- iface = sfp_select_interface(phydev->sfp_bus, sfp_support); -- -- /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes -- * interface for use with SFP modules. -- * However, some copper modules detected as having a preferred SGMII -- * interface do default to and function in 1000Base-X mode, so just -- * print a warning and allow such modules, as they may have some chance -- * of working. -- */ -- if (iface == PHY_INTERFACE_MODE_SGMII) -- dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n"); -- else if (iface != PHY_INTERFACE_MODE_1000BASEX) -- return -EINVAL; -- -- return 0; --} -- --static const struct sfp_upstream_ops at8031_sfp_ops = { -- .attach = phy_sfp_attach, -- .detach = phy_sfp_detach, -- .module_insert = at8031_sfp_insert, --}; -- --static int at8031_parse_dt(struct phy_device *phydev) --{ -- struct device_node *node = phydev->mdio.dev.of_node; -- struct at803x_priv *priv = phydev->priv; -- int ret; -- -- if (of_property_read_bool(node, "qca,keep-pll-enabled")) -- priv->flags |= AT803X_KEEP_PLL_ENABLED; -- -- ret = at8031_register_regulators(phydev); -- if (ret < 0) -- return ret; -- -- ret = devm_regulator_get_enable_optional(&phydev->mdio.dev, -- "vddio"); -- if (ret) { -- phydev_err(phydev, "failed to get VDDIO regulator\n"); -- return ret; -- } -- -- /* Only AR8031/8033 support 1000Base-X for SFP modules */ -- return phy_sfp_probe(phydev, &at8031_sfp_ops); --} -- --static int at8031_probe(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- int mode_cfg; -- int ccr; -- int ret; -- -- ret = at803x_probe(phydev); -- if (ret) -- return ret; -- -- /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping -- * options. -- */ -- ret = at8031_parse_dt(phydev); -- if (ret) -- return ret; -- -- ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); -- if (ccr < 0) -- return ccr; -- mode_cfg = ccr & AT803X_MODE_CFG_MASK; -- -- switch (mode_cfg) { -- case AT803X_MODE_CFG_BX1000_RGMII_50OHM: -- case AT803X_MODE_CFG_BX1000_RGMII_75OHM: -- priv->is_1000basex = true; -- fallthrough; -- case AT803X_MODE_CFG_FX100_RGMII_50OHM: -- case AT803X_MODE_CFG_FX100_RGMII_75OHM: -- priv->is_fiber = true; -- break; -- } -- -- /* Disable WoL in 1588 register which is enabled -- * by default -- */ -- return phy_modify_mmd(phydev, MDIO_MMD_PCS, -- AT803X_PHY_MMD3_WOL_CTRL, -- AT803X_WOL_EN, 0); --} -- --static int at8031_config_init(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- int ret; -- -- /* Some bootloaders leave the fiber page selected. -- * Switch to the appropriate page (fiber or copper), as otherwise we -- * read the PHY capabilities from the wrong page. -- */ -- phy_lock_mdio_bus(phydev); -- ret = at803x_write_page(phydev, -- priv->is_fiber ? AT803X_PAGE_FIBER : -- AT803X_PAGE_COPPER); -- phy_unlock_mdio_bus(phydev); -- if (ret) -- return ret; -- -- ret = at8031_pll_config(phydev); -- if (ret < 0) -- return ret; -- -- return at803x_config_init(phydev); --} -- --static int at8031_set_wol(struct phy_device *phydev, -- struct ethtool_wolinfo *wol) --{ -- int ret; -- -- /* First setup MAC address and enable WOL interrupt */ -- ret = at803x_set_wol(phydev, wol); -- if (ret) -- return ret; -- -- if (wol->wolopts & WAKE_MAGIC) -- /* Enable WOL function for 1588 */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -- AT803X_PHY_MMD3_WOL_CTRL, -- 0, AT803X_WOL_EN); -- else -- /* Disable WoL function for 1588 */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -- AT803X_PHY_MMD3_WOL_CTRL, -- AT803X_WOL_EN, 0); -- -- return ret; --} -- --static int at8031_config_intr(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- int err, value = 0; -- -- if (phydev->interrupts == PHY_INTERRUPT_ENABLED && -- priv->is_fiber) { -- /* Clear any pending interrupts */ -- err = at803x_ack_interrupt(phydev); -- if (err) -- return err; -- -- value |= AT803X_INTR_ENABLE_LINK_FAIL_BX; -- value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX; -- -- err = phy_set_bits(phydev, AT803X_INTR_ENABLE, value); -- if (err) -- return err; -- } -- -- return at803x_config_intr(phydev); --} -- --/* AR8031 and AR8033 share the same read status logic */ --static int at8031_read_status(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- -- if (priv->is_1000basex) -- return genphy_c37_read_status(phydev); -- -- return at803x_read_status(phydev); --} -- --/* AR8031 and AR8035 share the same cable test get status reg */ --static int at8031_cable_test_get_status(struct phy_device *phydev, -- bool *finished) --{ -- return at803x_cable_test_get_status(phydev, finished, 0xf); --} -- --/* AR8031 and AR8035 share the same cable test start logic */ --static int at8031_cable_test_start(struct phy_device *phydev) --{ -- at803x_cable_test_autoneg(phydev); -- phy_write(phydev, MII_CTRL1000, 0); -- /* we do all the (time consuming) work later */ -- return 0; --} -- --/* AR8032, AR9331 and QCA9561 share the same cable test get status reg */ --static int at8032_cable_test_get_status(struct phy_device *phydev, -- bool *finished) --{ -- return at803x_cable_test_get_status(phydev, finished, 0x3); --} -- --static int at8035_parse_dt(struct phy_device *phydev) --{ -- struct at803x_priv *priv = phydev->priv; -- -- /* Mask is set by the generic at803x_parse_dt -- * if property is set. Assume property is set -- * with the mask not zero. -- */ -- if (priv->clk_25m_mask) { -- /* Fixup for the AR8030/AR8035. This chip has another mask and -- * doesn't support the DSP reference. Eg. the lowest bit of the -- * mask. The upper two bits select the same frequencies. Mask -- * the lowest bit here. -- * -- * Warning: -- * There was no datasheet for the AR8030 available so this is -- * just a guess. But the AR8035 is listed as pin compatible -- * to the AR8030 so there might be a good chance it works on -- * the AR8030 too. -- */ -- priv->clk_25m_reg &= AT8035_CLK_OUT_MASK; -- priv->clk_25m_mask &= AT8035_CLK_OUT_MASK; -- } -- -- return 0; --} -- --/* AR8030 and AR8035 shared the same special mask for clk_25m */ --static int at8035_probe(struct phy_device *phydev) --{ -- int ret; -- -- ret = at803x_probe(phydev); -- if (ret) -- return ret; -- -- return at8035_parse_dt(phydev); --} -- --static int qca83xx_config_init(struct phy_device *phydev) --{ -- u8 switch_revision; -- -- switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK; -- -- switch (switch_revision) { -- case 1: -- /* For 100M waveform */ -- at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea); -- /* Turn on Gigabit clock */ -- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0); -- break; -- -- case 2: -- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0); -- fallthrough; -- case 4: -- phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f); -- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860); -- at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46); -- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000); -- break; -- } -- -- /* Following original QCA sourcecode set port to prefer master */ -- phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER); -- -- return 0; --} -- --static int qca8327_config_init(struct phy_device *phydev) --{ -- /* QCA8327 require DAC amplitude adjustment for 100m set to +6%. -- * Disable on init and enable only with 100m speed following -- * qca original source code. -- */ -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -- QCA8327_DEBUG_MANU_CTRL_EN, 0); -- -- return qca83xx_config_init(phydev); --} -- --static void qca83xx_link_change_notify(struct phy_device *phydev) --{ -- /* Set DAC Amplitude adjustment to +6% for 100m on link running */ -- if (phydev->state == PHY_RUNNING) { -- if (phydev->speed == SPEED_100) -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -- QCA8327_DEBUG_MANU_CTRL_EN, -- QCA8327_DEBUG_MANU_CTRL_EN); -- } else { -- /* Reset DAC Amplitude adjustment */ -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -- QCA8327_DEBUG_MANU_CTRL_EN, 0); -- } --} -- --static int qca83xx_resume(struct phy_device *phydev) --{ -- int ret, val; -- -- /* Skip reset if not suspended */ -- if (!phydev->suspended) -- return 0; -- -- /* Reinit the port, reset values set by suspend */ -- qca83xx_config_init(phydev); -- -- /* Reset the port on port resume */ -- phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); -- -- /* On resume from suspend the switch execute a reset and -- * restart auto-negotiation. Wait for reset to complete. -- */ -- ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET), -- 50000, 600000, true); -- if (ret) -- return ret; -- -- usleep_range(1000, 2000); -- -- return 0; --} -- --static int qca83xx_suspend(struct phy_device *phydev) --{ -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN, -- AT803X_DEBUG_GATE_CLK_IN1000, 0); -- -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL, -- AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE | -- AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0); -- -- return 0; --} -- --static int qca8337_suspend(struct phy_device *phydev) --{ -- /* Only QCA8337 support actual suspend. */ -- genphy_suspend(phydev); -- -- return qca83xx_suspend(phydev); --} -- --static int qca8327_suspend(struct phy_device *phydev) --{ -- u16 mask = 0; -- -- /* QCA8327 cause port unreliability when phy suspend -- * is set. -- */ -- mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX); -- phy_modify(phydev, MII_BMCR, mask, 0); -- -- return qca83xx_suspend(phydev); --} -- --static int qca808x_phy_fast_retrain_config(struct phy_device *phydev) --{ -- int ret; -- -- /* Enable fast retrain */ -- ret = genphy_c45_fast_retrain(phydev, true); -- if (ret) -- return ret; -- -- phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1, -- QCA808X_TOP_OPTION1_DATA); -- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB, -- QCA808X_MSE_THRESHOLD_20DB_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB, -- QCA808X_MSE_THRESHOLD_17DB_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB, -- QCA808X_MSE_THRESHOLD_27DB_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB, -- QCA808X_MSE_THRESHOLD_28DB_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1, -- QCA808X_MMD3_DEBUG_1_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4, -- QCA808X_MMD3_DEBUG_4_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5, -- QCA808X_MMD3_DEBUG_5_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3, -- QCA808X_MMD3_DEBUG_3_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6, -- QCA808X_MMD3_DEBUG_6_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2, -- QCA808X_MMD3_DEBUG_2_VALUE); -- -- return 0; --} -- --static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable) --{ -- u16 seed_value; -- -- if (!enable) -- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -- QCA808X_MASTER_SLAVE_SEED_ENABLE, 0); -- -- seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE); -- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -- QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE, -- FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) | -- QCA808X_MASTER_SLAVE_SEED_ENABLE); --} -- --static bool qca808x_is_prefer_master(struct phy_device *phydev) --{ -- return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) || -- (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED); --} -- --static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev) --{ -- return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); --} -- --static int qca808x_config_init(struct phy_device *phydev) --{ -- int ret; -- -- /* Active adc&vga on 802.3az for the link 1000M and 100M */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7, -- QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN); -- if (ret) -- return ret; -- -- /* Adjust the threshold on 802.3az for the link 1000M */ -- ret = phy_write_mmd(phydev, MDIO_MMD_PCS, -- QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, -- QCA808X_MMD3_AZ_TRAINING_VAL); -- if (ret) -- return ret; -- -- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { -- /* Config the fast retrain for the link 2500M */ -- ret = qca808x_phy_fast_retrain_config(phydev); -- if (ret) -- return ret; -- -- ret = genphy_read_master_slave(phydev); -- if (ret < 0) -- return ret; -- -- if (!qca808x_is_prefer_master(phydev)) { -- /* Enable seed and configure lower ramdom seed to make phy -- * linked as slave mode. -- */ -- ret = qca808x_phy_ms_seed_enable(phydev, true); -- if (ret) -- return ret; -- } -- } -- -- /* Configure adc threshold as 100mv for the link 10M */ -- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD, -- QCA808X_ADC_THRESHOLD_MASK, -- QCA808X_ADC_THRESHOLD_100MV); --} -- --static int qca808x_read_status(struct phy_device *phydev) --{ -- struct at803x_ss_mask ss_mask = { 0 }; -- int ret; -- -- ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); -- if (ret < 0) -- return ret; -- -- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising, -- ret & MDIO_AN_10GBT_STAT_LP2_5G); -- -- ret = genphy_read_status(phydev); -- if (ret) -- return ret; -- -- /* qca8081 takes the different bits for speed value from at803x */ -- ss_mask.speed_mask = QCA808X_SS_SPEED_MASK; -- ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK); -- ret = at803x_read_specific_status(phydev, ss_mask); -- if (ret < 0) -- return ret; -- -- if (phydev->link) { -- if (phydev->speed == SPEED_2500) -- phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -- else -- phydev->interface = PHY_INTERFACE_MODE_SGMII; -- } else { -- /* generate seed as a lower random value to make PHY linked as SLAVE easily, -- * except for master/slave configuration fault detected or the master mode -- * preferred. -- * -- * the reason for not putting this code into the function link_change_notify is -- * the corner case where the link partner is also the qca8081 PHY and the seed -- * value is configured as the same value, the link can't be up and no link change -- * occurs. -- */ -- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { -- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR || -- qca808x_is_prefer_master(phydev)) { -- qca808x_phy_ms_seed_enable(phydev, false); -- } else { -- qca808x_phy_ms_seed_enable(phydev, true); -- } -- } -- } -- -- return 0; --} -- --static int qca808x_soft_reset(struct phy_device *phydev) --{ -- int ret; -- -- ret = genphy_soft_reset(phydev); -- if (ret < 0) -- return ret; -- -- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) -- ret = qca808x_phy_ms_seed_enable(phydev, true); -- -- return ret; --} -- --static bool qca808x_cdt_fault_length_valid(int cdt_code) --{ -- switch (cdt_code) { -- case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -- return true; -- default: -- return false; -- } --} -- --static int qca808x_cable_test_result_trans(int cdt_code) --{ -- switch (cdt_code) { -- case QCA808X_CDT_STATUS_STAT_NORMAL: -- return ETHTOOL_A_CABLE_RESULT_CODE_OK; -- case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -- return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; -- case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -- return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -- return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; -- case QCA808X_CDT_STATUS_STAT_FAIL: -- default: -- return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; -- } --} -- --static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, -- int result) --{ -- int val; -- u32 cdt_length_reg = 0; -- -- switch (pair) { -- case ETHTOOL_A_CABLE_PAIR_A: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; -- break; -- case ETHTOOL_A_CABLE_PAIR_B: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; -- break; -- case ETHTOOL_A_CABLE_PAIR_C: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; -- break; -- case ETHTOOL_A_CABLE_PAIR_D: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; -- break; -- default: -- return -EINVAL; -- } -- -- val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); -- if (val < 0) -- return val; -- -- if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) -- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); -- else -- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); -- -- return at803x_cdt_fault_length(val); --} -- --static int qca808x_cable_test_start(struct phy_device *phydev) --{ -- int ret; -- -- /* perform CDT with the following configs: -- * 1. disable hibernation. -- * 2. force PHY working in MDI mode. -- * 3. for PHY working in 1000BaseT. -- * 4. configure the threshold. -- */ -- -- ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0); -- if (ret < 0) -- return ret; -- -- ret = at803x_config_mdix(phydev, ETH_TP_MDI); -- if (ret < 0) -- return ret; -- -- /* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */ -- phydev->duplex = DUPLEX_FULL; -- phydev->speed = SPEED_1000; -- ret = genphy_c45_pma_setup_forced(phydev); -- if (ret < 0) -- return ret; -- -- ret = genphy_setup_forced(phydev); -- if (ret < 0) -- return ret; -- -- /* configure the thresholds for open, short, pair ok test */ -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040); -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040); -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060); -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050); -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060); -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060); -- -- return 0; --} -- --static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, -- u16 status) --{ -- int length, result; -- u16 pair_code; -- -- switch (pair) { -- case ETHTOOL_A_CABLE_PAIR_A: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); -- break; -- case ETHTOOL_A_CABLE_PAIR_B: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); -- break; -- case ETHTOOL_A_CABLE_PAIR_C: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); -- break; -- case ETHTOOL_A_CABLE_PAIR_D: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); -- break; -- default: -- return -EINVAL; -- } -- -- result = qca808x_cable_test_result_trans(pair_code); -- ethnl_cable_test_result(phydev, pair, result); -- -- if (qca808x_cdt_fault_length_valid(pair_code)) { -- length = qca808x_cdt_fault_length(phydev, pair, result); -- ethnl_cable_test_fault_length(phydev, pair, length); -- } -- -- return 0; --} -- --static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) --{ -- int ret, val; -- -- *finished = false; -- -- val = QCA808X_CDT_ENABLE_TEST | -- QCA808X_CDT_LENGTH_UNIT; -- ret = at803x_cdt_start(phydev, val); -- if (ret) -- return ret; -- -- ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); -- if (ret) -- return ret; -- -- val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); -- if (val < 0) -- return val; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); -- if (ret) -- return ret; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); -- if (ret) -- return ret; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); -- if (ret) -- return ret; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); -- if (ret) -- return ret; -- -- *finished = true; -- -- return 0; --} -- --static int qca808x_get_features(struct phy_device *phydev) --{ -- int ret; -- -- ret = genphy_c45_pma_read_abilities(phydev); -- if (ret) -- return ret; -- -- /* The autoneg ability is not existed in bit3 of MMD7.1, -- * but it is supported by qca808x PHY, so we add it here -- * manually. -- */ -- linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported); -- -- /* As for the qca8081 1G version chip, the 2500baseT ability is also -- * existed in the bit0 of MMD1.21, we need to remove it manually if -- * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d. -- */ -- ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE); -- if (ret < 0) -- return ret; -- -- if (QCA808X_PHY_CHIP_TYPE_1G & ret) -- linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); -- -- return 0; --} -- --static int qca808x_config_aneg(struct phy_device *phydev) --{ -- int phy_ctrl = 0; -- int ret; -- -- ret = at803x_prepare_config_aneg(phydev); -- if (ret) -- return ret; -- -- /* The reg MII_BMCR also needs to be configured for force mode, the -- * genphy_config_aneg is also needed. -- */ -- if (phydev->autoneg == AUTONEG_DISABLE) -- genphy_c45_pma_setup_forced(phydev); -- -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising)) -- phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G; -- -- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, -- MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl); -- if (ret < 0) -- return ret; -- -- return __genphy_config_aneg(phydev, ret); --} -- --static void qca808x_link_change_notify(struct phy_device *phydev) --{ -- /* Assert interface sgmii fifo on link down, deassert it on link up, -- * the interface device address is always phy address added by 1. -- */ -- mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1, -- MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL, -- QCA8081_PHY_FIFO_RSTN, -- phydev->link ? QCA8081_PHY_FIFO_RSTN : 0); --} -- --static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules, -- u16 *offload_trigger) --{ -- /* Parsing specific to netdev trigger */ -- if (test_bit(TRIGGER_NETDEV_TX, &rules)) -- *offload_trigger |= QCA808X_LED_TX_BLINK; -- if (test_bit(TRIGGER_NETDEV_RX, &rules)) -- *offload_trigger |= QCA808X_LED_RX_BLINK; -- if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) -- *offload_trigger |= QCA808X_LED_SPEED10_ON; -- if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) -- *offload_trigger |= QCA808X_LED_SPEED100_ON; -- if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) -- *offload_trigger |= QCA808X_LED_SPEED1000_ON; -- if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules)) -- *offload_trigger |= QCA808X_LED_SPEED2500_ON; -- if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) -- *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON; -- if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) -- *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON; -- -- if (rules && !*offload_trigger) -- return -EOPNOTSUPP; -- -- /* Enable BLINK_CHECK_BYPASS by default to make the LED -- * blink even with duplex or speed mode not enabled. -- */ -- *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS; -- -- return 0; --} -- --static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index) --{ -- u16 reg; -- -- if (index > 2) -- return -EINVAL; -- -- reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_FORCE_EN); --} -- --static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index, -- unsigned long rules) --{ -- u16 offload_trigger = 0; -- -- if (index > 2) -- return -EINVAL; -- -- return qca808x_led_parse_netdev(phydev, rules, &offload_trigger); --} -- --static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index, -- unsigned long rules) --{ -- u16 reg, offload_trigger = 0; -- int ret; -- -- if (index > 2) -- return -EINVAL; -- -- reg = QCA808X_MMD7_LED_CTRL(index); -- -- ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger); -- if (ret) -- return ret; -- -- ret = qca808x_led_hw_control_enable(phydev, index); -- if (ret) -- return ret; -- -- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_PATTERN_MASK, -- offload_trigger); --} -- --static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index) --{ -- u16 reg; -- int val; -- -- if (index > 2) -- return false; -- -- reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -- -- return !(val & QCA808X_LED_FORCE_EN); --} -- --static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index, -- unsigned long *rules) --{ -- u16 reg; -- int val; -- -- if (index > 2) -- return -EINVAL; -- -- /* Check if we have hw control enabled */ -- if (qca808x_led_hw_control_status(phydev, index)) -- return -EINVAL; -- -- reg = QCA808X_MMD7_LED_CTRL(index); -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -- if (val & QCA808X_LED_TX_BLINK) -- set_bit(TRIGGER_NETDEV_TX, rules); -- if (val & QCA808X_LED_RX_BLINK) -- set_bit(TRIGGER_NETDEV_RX, rules); -- if (val & QCA808X_LED_SPEED10_ON) -- set_bit(TRIGGER_NETDEV_LINK_10, rules); -- if (val & QCA808X_LED_SPEED100_ON) -- set_bit(TRIGGER_NETDEV_LINK_100, rules); -- if (val & QCA808X_LED_SPEED1000_ON) -- set_bit(TRIGGER_NETDEV_LINK_1000, rules); -- if (val & QCA808X_LED_SPEED2500_ON) -- set_bit(TRIGGER_NETDEV_LINK_2500, rules); -- if (val & QCA808X_LED_HALF_DUPLEX_ON) -- set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); -- if (val & QCA808X_LED_FULL_DUPLEX_ON) -- set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); -- -- return 0; --} -- --static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index) --{ -- u16 reg; -- -- if (index > 2) -- return -EINVAL; -- -- reg = QCA808X_MMD7_LED_CTRL(index); -- -- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_PATTERN_MASK); --} -- --static int qca808x_led_brightness_set(struct phy_device *phydev, -- u8 index, enum led_brightness value) --{ -- u16 reg; -- int ret; -- -- if (index > 2) -- return -EINVAL; -- -- if (!value) { -- ret = qca808x_led_hw_control_reset(phydev, index); -- if (ret) -- return ret; -- } -- -- reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -- QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON : -- QCA808X_LED_FORCE_OFF); --} -- --static int qca808x_led_blink_set(struct phy_device *phydev, u8 index, -- unsigned long *delay_on, -- unsigned long *delay_off) --{ -- int ret; -- u16 reg; -- -- if (index > 2) -- return -EINVAL; -- -- reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- /* Set blink to 50% off, 50% on at 4Hz by default */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, -- QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, -- QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); -- if (ret) -- return ret; -- -- /* We use BLINK_1 for normal blinking */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); -- if (ret) -- return ret; -- -- /* We set blink to 4Hz, aka 250ms */ -- *delay_on = 250 / 2; -- *delay_off = 250 / 2; -- -- return 0; --} -- --static int qca808x_led_polarity_set(struct phy_device *phydev, int index, -- unsigned long modes) --{ -- struct at803x_priv *priv = phydev->priv; -- bool active_low = false; -- u32 mode; -- -- for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { -- switch (mode) { -- case PHY_LED_ACTIVE_LOW: -- active_low = true; -- break; -- default: -- return -EINVAL; -- } -- } -- -- /* PHY polarity is global and can't be set per LED. -- * To detect this, check if last requested polarity mode -- * match the new one. -- */ -- if (priv->led_polarity_mode >= 0 && -- priv->led_polarity_mode != active_low) { -- phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n"); -- return -EINVAL; -- } -- -- /* Save the last PHY polarity mode */ -- priv->led_polarity_mode = active_low; -- -- return phy_modify_mmd(phydev, MDIO_MMD_AN, -- QCA808X_MMD7_LED_POLARITY_CTRL, -- QCA808X_LED_ACTIVE_HIGH, -- active_low ? 0 : QCA808X_LED_ACTIVE_HIGH); --} -- --static struct phy_driver at803x_driver[] = { --{ -- /* Qualcomm Atheros AR8035 */ -- PHY_ID_MATCH_EXACT(ATH8035_PHY_ID), -- .name = "Qualcomm Atheros AR8035", -- .flags = PHY_POLL_CABLE_TEST, -- .probe = at8035_probe, -- .config_aneg = at803x_config_aneg, -- .config_init = at803x_config_init, -- .soft_reset = genphy_soft_reset, -- .set_wol = at803x_set_wol, -- .get_wol = at803x_get_wol, -- .suspend = at803x_suspend, -- .resume = at803x_resume, -- /* PHY_GBIT_FEATURES */ -- .read_status = at803x_read_status, -- .config_intr = at803x_config_intr, -- .handle_interrupt = at803x_handle_interrupt, -- .get_tunable = at803x_get_tunable, -- .set_tunable = at803x_set_tunable, -- .cable_test_start = at8031_cable_test_start, -- .cable_test_get_status = at8031_cable_test_get_status, --}, { -- /* Qualcomm Atheros AR8030 */ -- .phy_id = ATH8030_PHY_ID, -- .name = "Qualcomm Atheros AR8030", -- .phy_id_mask = AT8030_PHY_ID_MASK, -- .probe = at8035_probe, -- .config_init = at803x_config_init, -- .link_change_notify = at803x_link_change_notify, -- .set_wol = at803x_set_wol, -- .get_wol = at803x_get_wol, -- .suspend = at803x_suspend, -- .resume = at803x_resume, -- /* PHY_BASIC_FEATURES */ -- .config_intr = at803x_config_intr, -- .handle_interrupt = at803x_handle_interrupt, --}, { -- /* Qualcomm Atheros AR8031/AR8033 */ -- PHY_ID_MATCH_EXACT(ATH8031_PHY_ID), -- .name = "Qualcomm Atheros AR8031/AR8033", -- .flags = PHY_POLL_CABLE_TEST, -- .probe = at8031_probe, -- .config_init = at8031_config_init, -- .config_aneg = at803x_config_aneg, -- .soft_reset = genphy_soft_reset, -- .set_wol = at8031_set_wol, -- .get_wol = at803x_get_wol, -- .suspend = at803x_suspend, -- .resume = at803x_resume, -- .read_page = at803x_read_page, -- .write_page = at803x_write_page, -- .get_features = at803x_get_features, -- .read_status = at8031_read_status, -- .config_intr = at8031_config_intr, -- .handle_interrupt = at803x_handle_interrupt, -- .get_tunable = at803x_get_tunable, -- .set_tunable = at803x_set_tunable, -- .cable_test_start = at8031_cable_test_start, -- .cable_test_get_status = at8031_cable_test_get_status, --}, { -- /* Qualcomm Atheros AR8032 */ -- PHY_ID_MATCH_EXACT(ATH8032_PHY_ID), -- .name = "Qualcomm Atheros AR8032", -- .probe = at803x_probe, -- .flags = PHY_POLL_CABLE_TEST, -- .config_init = at803x_config_init, -- .link_change_notify = at803x_link_change_notify, -- .suspend = at803x_suspend, -- .resume = at803x_resume, -- /* PHY_BASIC_FEATURES */ -- .config_intr = at803x_config_intr, -- .handle_interrupt = at803x_handle_interrupt, -- .cable_test_start = at803x_cable_test_start, -- .cable_test_get_status = at8032_cable_test_get_status, --}, { -- /* ATHEROS AR9331 */ -- PHY_ID_MATCH_EXACT(ATH9331_PHY_ID), -- .name = "Qualcomm Atheros AR9331 built-in PHY", -- .probe = at803x_probe, -- .suspend = at803x_suspend, -- .resume = at803x_resume, -- .flags = PHY_POLL_CABLE_TEST, -- /* PHY_BASIC_FEATURES */ -- .config_intr = at803x_config_intr, -- .handle_interrupt = at803x_handle_interrupt, -- .cable_test_start = at803x_cable_test_start, -- .cable_test_get_status = at8032_cable_test_get_status, -- .read_status = at803x_read_status, -- .soft_reset = genphy_soft_reset, -- .config_aneg = at803x_config_aneg, --}, { -- /* Qualcomm Atheros QCA9561 */ -- PHY_ID_MATCH_EXACT(QCA9561_PHY_ID), -- .name = "Qualcomm Atheros QCA9561 built-in PHY", -- .probe = at803x_probe, -- .suspend = at803x_suspend, -- .resume = at803x_resume, -- .flags = PHY_POLL_CABLE_TEST, -- /* PHY_BASIC_FEATURES */ -- .config_intr = at803x_config_intr, -- .handle_interrupt = at803x_handle_interrupt, -- .cable_test_start = at803x_cable_test_start, -- .cable_test_get_status = at8032_cable_test_get_status, -- .read_status = at803x_read_status, -- .soft_reset = genphy_soft_reset, -- .config_aneg = at803x_config_aneg, --}, { -- /* QCA8337 */ -- .phy_id = QCA8337_PHY_ID, -- .phy_id_mask = QCA8K_PHY_ID_MASK, -- .name = "Qualcomm Atheros 8337 internal PHY", -- /* PHY_GBIT_FEATURES */ -- .probe = at803x_probe, -- .flags = PHY_IS_INTERNAL, -- .config_init = qca83xx_config_init, -- .soft_reset = genphy_soft_reset, -- .get_sset_count = qca83xx_get_sset_count, -- .get_strings = qca83xx_get_strings, -- .get_stats = qca83xx_get_stats, -- .suspend = qca8337_suspend, -- .resume = qca83xx_resume, --}, { -- /* QCA8327-A from switch QCA8327-AL1A */ -- .phy_id = QCA8327_A_PHY_ID, -- .phy_id_mask = QCA8K_PHY_ID_MASK, -- .name = "Qualcomm Atheros 8327-A internal PHY", -- /* PHY_GBIT_FEATURES */ -- .link_change_notify = qca83xx_link_change_notify, -- .probe = at803x_probe, -- .flags = PHY_IS_INTERNAL, -- .config_init = qca8327_config_init, -- .soft_reset = genphy_soft_reset, -- .get_sset_count = qca83xx_get_sset_count, -- .get_strings = qca83xx_get_strings, -- .get_stats = qca83xx_get_stats, -- .suspend = qca8327_suspend, -- .resume = qca83xx_resume, --}, { -- /* QCA8327-B from switch QCA8327-BL1A */ -- .phy_id = QCA8327_B_PHY_ID, -- .phy_id_mask = QCA8K_PHY_ID_MASK, -- .name = "Qualcomm Atheros 8327-B internal PHY", -- /* PHY_GBIT_FEATURES */ -- .link_change_notify = qca83xx_link_change_notify, -- .probe = at803x_probe, -- .flags = PHY_IS_INTERNAL, -- .config_init = qca8327_config_init, -- .soft_reset = genphy_soft_reset, -- .get_sset_count = qca83xx_get_sset_count, -- .get_strings = qca83xx_get_strings, -- .get_stats = qca83xx_get_stats, -- .suspend = qca8327_suspend, -- .resume = qca83xx_resume, --}, { -- /* Qualcomm QCA8081 */ -- PHY_ID_MATCH_EXACT(QCA8081_PHY_ID), -- .name = "Qualcomm QCA8081", -- .flags = PHY_POLL_CABLE_TEST, -- .probe = at803x_probe, -- .config_intr = at803x_config_intr, -- .handle_interrupt = at803x_handle_interrupt, -- .get_tunable = at803x_get_tunable, -- .set_tunable = at803x_set_tunable, -- .set_wol = at803x_set_wol, -- .get_wol = at803x_get_wol, -- .get_features = qca808x_get_features, -- .config_aneg = qca808x_config_aneg, -- .suspend = genphy_suspend, -- .resume = genphy_resume, -- .read_status = qca808x_read_status, -- .config_init = qca808x_config_init, -- .soft_reset = qca808x_soft_reset, -- .cable_test_start = qca808x_cable_test_start, -- .cable_test_get_status = qca808x_cable_test_get_status, -- .link_change_notify = qca808x_link_change_notify, -- .led_brightness_set = qca808x_led_brightness_set, -- .led_blink_set = qca808x_led_blink_set, -- .led_hw_is_supported = qca808x_led_hw_is_supported, -- .led_hw_control_set = qca808x_led_hw_control_set, -- .led_hw_control_get = qca808x_led_hw_control_get, -- .led_polarity_set = qca808x_led_polarity_set, --}, }; -- --module_phy_driver(at803x_driver); -- --static struct mdio_device_id __maybe_unused atheros_tbl[] = { -- { ATH8030_PHY_ID, AT8030_PHY_ID_MASK }, -- { PHY_ID_MATCH_EXACT(ATH8031_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) }, -- { } --}; -- --MODULE_DEVICE_TABLE(mdio, atheros_tbl); ---- /dev/null -+++ b/drivers/net/phy/qcom/at803x.c -@@ -0,0 +1,2759 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * drivers/net/phy/at803x.c -+ * -+ * Driver for Qualcomm Atheros AR803x PHY -+ * -+ * Author: Matus Ujhelyi -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10 -+#define AT803X_SFC_ASSERT_CRS BIT(11) -+#define AT803X_SFC_FORCE_LINK BIT(10) -+#define AT803X_SFC_MDI_CROSSOVER_MODE_M GENMASK(6, 5) -+#define AT803X_SFC_AUTOMATIC_CROSSOVER 0x3 -+#define AT803X_SFC_MANUAL_MDIX 0x1 -+#define AT803X_SFC_MANUAL_MDI 0x0 -+#define AT803X_SFC_SQE_TEST BIT(2) -+#define AT803X_SFC_POLARITY_REVERSAL BIT(1) -+#define AT803X_SFC_DISABLE_JABBER BIT(0) -+ -+#define AT803X_SPECIFIC_STATUS 0x11 -+#define AT803X_SS_SPEED_MASK GENMASK(15, 14) -+#define AT803X_SS_SPEED_1000 2 -+#define AT803X_SS_SPEED_100 1 -+#define AT803X_SS_SPEED_10 0 -+#define AT803X_SS_DUPLEX BIT(13) -+#define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11) -+#define AT803X_SS_MDIX BIT(6) -+ -+#define QCA808X_SS_SPEED_MASK GENMASK(9, 7) -+#define QCA808X_SS_SPEED_2500 4 -+ -+#define AT803X_INTR_ENABLE 0x12 -+#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15) -+#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14) -+#define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13) -+#define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12) -+#define AT803X_INTR_ENABLE_LINK_FAIL BIT(11) -+#define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10) -+#define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8) -+#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7) -+#define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5) -+#define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1) -+#define AT803X_INTR_ENABLE_WOL BIT(0) -+ -+#define AT803X_INTR_STATUS 0x13 -+ -+#define AT803X_SMART_SPEED 0x14 -+#define AT803X_SMART_SPEED_ENABLE BIT(5) -+#define AT803X_SMART_SPEED_RETRY_LIMIT_MASK GENMASK(4, 2) -+#define AT803X_SMART_SPEED_BYPASS_TIMER BIT(1) -+#define AT803X_CDT 0x16 -+#define AT803X_CDT_MDI_PAIR_MASK GENMASK(9, 8) -+#define AT803X_CDT_ENABLE_TEST BIT(0) -+#define AT803X_CDT_STATUS 0x1c -+#define AT803X_CDT_STATUS_STAT_NORMAL 0 -+#define AT803X_CDT_STATUS_STAT_SHORT 1 -+#define AT803X_CDT_STATUS_STAT_OPEN 2 -+#define AT803X_CDT_STATUS_STAT_FAIL 3 -+#define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8) -+#define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0) -+#define AT803X_LED_CONTROL 0x18 -+ -+#define AT803X_PHY_MMD3_WOL_CTRL 0x8012 -+#define AT803X_WOL_EN BIT(5) -+#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C -+#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B -+#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A -+#define AT803X_REG_CHIP_CONFIG 0x1f -+#define AT803X_BT_BX_REG_SEL 0x8000 -+ -+#define AT803X_DEBUG_ADDR 0x1D -+#define AT803X_DEBUG_DATA 0x1E -+ -+#define AT803X_MODE_CFG_MASK 0x0F -+#define AT803X_MODE_CFG_BASET_RGMII 0x00 -+#define AT803X_MODE_CFG_BASET_SGMII 0x01 -+#define AT803X_MODE_CFG_BX1000_RGMII_50OHM 0x02 -+#define AT803X_MODE_CFG_BX1000_RGMII_75OHM 0x03 -+#define AT803X_MODE_CFG_BX1000_CONV_50OHM 0x04 -+#define AT803X_MODE_CFG_BX1000_CONV_75OHM 0x05 -+#define AT803X_MODE_CFG_FX100_RGMII_50OHM 0x06 -+#define AT803X_MODE_CFG_FX100_CONV_50OHM 0x07 -+#define AT803X_MODE_CFG_RGMII_AUTO_MDET 0x0B -+#define AT803X_MODE_CFG_FX100_RGMII_75OHM 0x0E -+#define AT803X_MODE_CFG_FX100_CONV_75OHM 0x0F -+ -+#define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/ -+#define AT803X_PSSR_MR_AN_COMPLETE 0x0200 -+ -+#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00 -+#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2) -+#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2) -+#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) -+ -+#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05 -+#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) -+ -+#define AT803X_DEBUG_REG_HIB_CTRL 0x0b -+#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10) -+#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13) -+#define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15) -+ -+#define AT803X_DEBUG_REG_3C 0x3C -+ -+#define AT803X_DEBUG_REG_GREEN 0x3D -+#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6) -+ -+#define AT803X_DEBUG_REG_1F 0x1F -+#define AT803X_DEBUG_PLL_ON BIT(2) -+#define AT803X_DEBUG_RGMII_1V8 BIT(3) -+ -+#define MDIO_AZ_DEBUG 0x800D -+ -+/* AT803x supports either the XTAL input pad, an internal PLL or the -+ * DSP as clock reference for the clock output pad. The XTAL reference -+ * is only used for 25 MHz output, all other frequencies need the PLL. -+ * The DSP as a clock reference is used in synchronous ethernet -+ * applications. -+ * -+ * By default the PLL is only enabled if there is a link. Otherwise -+ * the PHY will go into low power state and disabled the PLL. You can -+ * set the PLL_ON bit (see debug register 0x1f) to keep the PLL always -+ * enabled. -+ */ -+#define AT803X_MMD7_CLK25M 0x8016 -+#define AT803X_CLK_OUT_MASK GENMASK(4, 2) -+#define AT803X_CLK_OUT_25MHZ_XTAL 0 -+#define AT803X_CLK_OUT_25MHZ_DSP 1 -+#define AT803X_CLK_OUT_50MHZ_PLL 2 -+#define AT803X_CLK_OUT_50MHZ_DSP 3 -+#define AT803X_CLK_OUT_62_5MHZ_PLL 4 -+#define AT803X_CLK_OUT_62_5MHZ_DSP 5 -+#define AT803X_CLK_OUT_125MHZ_PLL 6 -+#define AT803X_CLK_OUT_125MHZ_DSP 7 -+ -+/* The AR8035 has another mask which is compatible with the AR8031/AR8033 mask -+ * but doesn't support choosing between XTAL/PLL and DSP. -+ */ -+#define AT8035_CLK_OUT_MASK GENMASK(4, 3) -+ -+#define AT803X_CLK_OUT_STRENGTH_MASK GENMASK(8, 7) -+#define AT803X_CLK_OUT_STRENGTH_FULL 0 -+#define AT803X_CLK_OUT_STRENGTH_HALF 1 -+#define AT803X_CLK_OUT_STRENGTH_QUARTER 2 -+ -+#define AT803X_DEFAULT_DOWNSHIFT 5 -+#define AT803X_MIN_DOWNSHIFT 2 -+#define AT803X_MAX_DOWNSHIFT 9 -+ -+#define AT803X_MMD3_SMARTEEE_CTL1 0x805b -+#define AT803X_MMD3_SMARTEEE_CTL2 0x805c -+#define AT803X_MMD3_SMARTEEE_CTL3 0x805d -+#define AT803X_MMD3_SMARTEEE_CTL3_LPI_EN BIT(8) -+ -+#define ATH9331_PHY_ID 0x004dd041 -+#define ATH8030_PHY_ID 0x004dd076 -+#define ATH8031_PHY_ID 0x004dd074 -+#define ATH8032_PHY_ID 0x004dd023 -+#define ATH8035_PHY_ID 0x004dd072 -+#define AT8030_PHY_ID_MASK 0xffffffef -+ -+#define QCA8081_PHY_ID 0x004dd101 -+ -+#define QCA8327_A_PHY_ID 0x004dd033 -+#define QCA8327_B_PHY_ID 0x004dd034 -+#define QCA8337_PHY_ID 0x004dd036 -+#define QCA9561_PHY_ID 0x004dd042 -+#define QCA8K_PHY_ID_MASK 0xffffffff -+ -+#define QCA8K_DEVFLAGS_REVISION_MASK GENMASK(2, 0) -+ -+#define AT803X_PAGE_FIBER 0 -+#define AT803X_PAGE_COPPER 1 -+ -+/* don't turn off internal PLL */ -+#define AT803X_KEEP_PLL_ENABLED BIT(0) -+#define AT803X_DISABLE_SMARTEEE BIT(1) -+ -+/* disable hibernation mode */ -+#define AT803X_DISABLE_HIBERNATION_MODE BIT(2) -+ -+/* ADC threshold */ -+#define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80 -+#define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0) -+#define QCA808X_ADC_THRESHOLD_80MV 0 -+#define QCA808X_ADC_THRESHOLD_100MV 0xf0 -+#define QCA808X_ADC_THRESHOLD_200MV 0x0f -+#define QCA808X_ADC_THRESHOLD_300MV 0xff -+ -+/* CLD control */ -+#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007 -+#define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4) -+#define QCA808X_8023AZ_AFE_EN 0x90 -+ -+/* AZ control */ -+#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008 -+#define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32 -+ -+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014 -+#define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529 -+ -+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E -+#define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341 -+ -+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E -+#define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419 -+ -+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020 -+#define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341 -+ -+#define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c -+#define QCA808X_TOP_OPTION1_DATA 0x0 -+ -+#define QCA808X_PHY_MMD3_DEBUG_1 0xa100 -+#define QCA808X_MMD3_DEBUG_1_VALUE 0x9203 -+#define QCA808X_PHY_MMD3_DEBUG_2 0xa101 -+#define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad -+#define QCA808X_PHY_MMD3_DEBUG_3 0xa103 -+#define QCA808X_MMD3_DEBUG_3_VALUE 0x1698 -+#define QCA808X_PHY_MMD3_DEBUG_4 0xa105 -+#define QCA808X_MMD3_DEBUG_4_VALUE 0x8001 -+#define QCA808X_PHY_MMD3_DEBUG_5 0xa106 -+#define QCA808X_MMD3_DEBUG_5_VALUE 0x1111 -+#define QCA808X_PHY_MMD3_DEBUG_6 0xa011 -+#define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85 -+ -+/* master/slave seed config */ -+#define QCA808X_PHY_DEBUG_LOCAL_SEED 9 -+#define QCA808X_MASTER_SLAVE_SEED_ENABLE BIT(1) -+#define QCA808X_MASTER_SLAVE_SEED_CFG GENMASK(12, 2) -+#define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32 -+ -+/* Hibernation yields lower power consumpiton in contrast with normal operation mode. -+ * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s. -+ */ -+#define QCA808X_DBG_AN_TEST 0xb -+#define QCA808X_HIBERNATION_EN BIT(15) -+ -+#define QCA808X_CDT_ENABLE_TEST BIT(15) -+#define QCA808X_CDT_INTER_CHECK_DIS BIT(13) -+#define QCA808X_CDT_STATUS BIT(11) -+#define QCA808X_CDT_LENGTH_UNIT BIT(10) -+ -+#define QCA808X_MMD3_CDT_STATUS 0x8064 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 -+#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) -+#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) -+ -+#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) -+#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) -+#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) -+#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) -+ -+#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) -+#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) -+#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) -+#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) -+#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) -+ -+#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) -+#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) -+#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) -+#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) -+ -+/* NORMAL are MDI with type set to 0 */ -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI1) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI1) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI2) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI2) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI3) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI3) -+ -+/* Added for reference of existence but should be handled by wait_for_completion already */ -+#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) -+ -+#define QCA808X_MMD7_LED_GLOBAL 0x8073 -+#define QCA808X_LED_BLINK_1 GENMASK(11, 6) -+#define QCA808X_LED_BLINK_2 GENMASK(5, 0) -+/* Values are the same for both BLINK_1 and BLINK_2 */ -+#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) -+#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) -+#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) -+#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) -+#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) -+#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) -+#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) -+#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) -+#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) -+#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) -+#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) -+#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) -+#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) -+#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) -+#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) -+#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) -+#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) -+#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) -+ -+#define QCA808X_MMD7_LED2_CTRL 0x8074 -+#define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075 -+#define QCA808X_MMD7_LED1_CTRL 0x8076 -+#define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077 -+#define QCA808X_MMD7_LED0_CTRL 0x8078 -+#define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2)) -+ -+/* LED hw control pattern is the same for every LED */ -+#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) -+#define QCA808X_LED_SPEED2500_ON BIT(15) -+#define QCA808X_LED_SPEED2500_BLINK BIT(14) -+/* Follow blink trigger even if duplex or speed condition doesn't match */ -+#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) -+#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) -+#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) -+#define QCA808X_LED_TX_BLINK BIT(10) -+#define QCA808X_LED_RX_BLINK BIT(9) -+#define QCA808X_LED_TX_ON_10MS BIT(8) -+#define QCA808X_LED_RX_ON_10MS BIT(7) -+#define QCA808X_LED_SPEED1000_ON BIT(6) -+#define QCA808X_LED_SPEED100_ON BIT(5) -+#define QCA808X_LED_SPEED10_ON BIT(4) -+#define QCA808X_LED_COLLISION_BLINK BIT(3) -+#define QCA808X_LED_SPEED1000_BLINK BIT(2) -+#define QCA808X_LED_SPEED100_BLINK BIT(1) -+#define QCA808X_LED_SPEED10_BLINK BIT(0) -+ -+#define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079 -+#define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2)) -+ -+/* LED force ctrl is the same for every LED -+ * No documentation exist for this, not even internal one -+ * with NDA as QCOM gives only info about configuring -+ * hw control pattern rules and doesn't indicate any way -+ * to force the LED to specific mode. -+ * These define comes from reverse and testing and maybe -+ * lack of some info or some info are not entirely correct. -+ * For the basic LED control and hw control these finding -+ * are enough to support LED control in all the required APIs. -+ * -+ * On doing some comparison with implementation with qca807x, -+ * it was found that it's 1:1 equal to it and confirms all the -+ * reverse done. It was also found further specification with the -+ * force mode and the blink modes. -+ */ -+#define QCA808X_LED_FORCE_EN BIT(15) -+#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) -+#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) -+#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) -+#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) -+#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) -+ -+#define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a -+/* QSDK sets by default 0x46 to this reg that sets BIT 6 for -+ * LED to active high. It's not clear what BIT 3 and BIT 4 does. -+ */ -+#define QCA808X_LED_ACTIVE_HIGH BIT(6) -+ -+/* QCA808X 1G chip type */ -+#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d -+#define QCA808X_PHY_CHIP_TYPE_1G BIT(0) -+ -+#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072 -+#define QCA8081_PHY_FIFO_RSTN BIT(11) -+ -+MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver"); -+MODULE_AUTHOR("Matus Ujhelyi"); -+MODULE_LICENSE("GPL"); -+ -+enum stat_access_type { -+ PHY, -+ MMD -+}; -+ -+struct at803x_hw_stat { -+ const char *string; -+ u8 reg; -+ u32 mask; -+ enum stat_access_type access_type; -+}; -+ -+static struct at803x_hw_stat qca83xx_hw_stats[] = { -+ { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY}, -+ { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY}, -+ { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD}, -+}; -+ -+struct at803x_ss_mask { -+ u16 speed_mask; -+ u8 speed_shift; -+}; -+ -+struct at803x_priv { -+ int flags; -+ u16 clk_25m_reg; -+ u16 clk_25m_mask; -+ u8 smarteee_lpi_tw_1g; -+ u8 smarteee_lpi_tw_100m; -+ bool is_fiber; -+ bool is_1000basex; -+ struct regulator_dev *vddio_rdev; -+ struct regulator_dev *vddh_rdev; -+ u64 stats[ARRAY_SIZE(qca83xx_hw_stats)]; -+ int led_polarity_mode; -+}; -+ -+struct at803x_context { -+ u16 bmcr; -+ u16 advertise; -+ u16 control1000; -+ u16 int_enable; -+ u16 smart_speed; -+ u16 led_control; -+}; -+ -+static int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data) -+{ -+ int ret; -+ -+ ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); -+ if (ret < 0) -+ return ret; -+ -+ return phy_write(phydev, AT803X_DEBUG_DATA, data); -+} -+ -+static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg) -+{ -+ int ret; -+ -+ ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); -+ if (ret < 0) -+ return ret; -+ -+ return phy_read(phydev, AT803X_DEBUG_DATA); -+} -+ -+static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, -+ u16 clear, u16 set) -+{ -+ u16 val; -+ int ret; -+ -+ ret = at803x_debug_reg_read(phydev, reg); -+ if (ret < 0) -+ return ret; -+ -+ val = ret & 0xffff; -+ val &= ~clear; -+ val |= set; -+ -+ return phy_write(phydev, AT803X_DEBUG_DATA, val); -+} -+ -+static int at803x_write_page(struct phy_device *phydev, int page) -+{ -+ int mask; -+ int set; -+ -+ if (page == AT803X_PAGE_COPPER) { -+ set = AT803X_BT_BX_REG_SEL; -+ mask = 0; -+ } else { -+ set = 0; -+ mask = AT803X_BT_BX_REG_SEL; -+ } -+ -+ return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set); -+} -+ -+static int at803x_read_page(struct phy_device *phydev) -+{ -+ int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG); -+ -+ if (ccr < 0) -+ return ccr; -+ -+ if (ccr & AT803X_BT_BX_REG_SEL) -+ return AT803X_PAGE_COPPER; -+ -+ return AT803X_PAGE_FIBER; -+} -+ -+static int at803x_enable_rx_delay(struct phy_device *phydev) -+{ -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0, -+ AT803X_DEBUG_RX_CLK_DLY_EN); -+} -+ -+static int at803x_enable_tx_delay(struct phy_device *phydev) -+{ -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0, -+ AT803X_DEBUG_TX_CLK_DLY_EN); -+} -+ -+static int at803x_disable_rx_delay(struct phy_device *phydev) -+{ -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -+ AT803X_DEBUG_RX_CLK_DLY_EN, 0); -+} -+ -+static int at803x_disable_tx_delay(struct phy_device *phydev) -+{ -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, -+ AT803X_DEBUG_TX_CLK_DLY_EN, 0); -+} -+ -+/* save relevant PHY registers to private copy */ -+static void at803x_context_save(struct phy_device *phydev, -+ struct at803x_context *context) -+{ -+ context->bmcr = phy_read(phydev, MII_BMCR); -+ context->advertise = phy_read(phydev, MII_ADVERTISE); -+ context->control1000 = phy_read(phydev, MII_CTRL1000); -+ context->int_enable = phy_read(phydev, AT803X_INTR_ENABLE); -+ context->smart_speed = phy_read(phydev, AT803X_SMART_SPEED); -+ context->led_control = phy_read(phydev, AT803X_LED_CONTROL); -+} -+ -+/* restore relevant PHY registers from private copy */ -+static void at803x_context_restore(struct phy_device *phydev, -+ const struct at803x_context *context) -+{ -+ phy_write(phydev, MII_BMCR, context->bmcr); -+ phy_write(phydev, MII_ADVERTISE, context->advertise); -+ phy_write(phydev, MII_CTRL1000, context->control1000); -+ phy_write(phydev, AT803X_INTR_ENABLE, context->int_enable); -+ phy_write(phydev, AT803X_SMART_SPEED, context->smart_speed); -+ phy_write(phydev, AT803X_LED_CONTROL, context->led_control); -+} -+ -+static int at803x_set_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol) -+{ -+ int ret, irq_enabled; -+ -+ if (wol->wolopts & WAKE_MAGIC) { -+ struct net_device *ndev = phydev->attached_dev; -+ const u8 *mac; -+ unsigned int i; -+ static const unsigned int offsets[] = { -+ AT803X_LOC_MAC_ADDR_32_47_OFFSET, -+ AT803X_LOC_MAC_ADDR_16_31_OFFSET, -+ AT803X_LOC_MAC_ADDR_0_15_OFFSET, -+ }; -+ -+ if (!ndev) -+ return -ENODEV; -+ -+ mac = (const u8 *)ndev->dev_addr; -+ -+ if (!is_valid_ether_addr(mac)) -+ return -EINVAL; -+ -+ for (i = 0; i < 3; i++) -+ phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i], -+ mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); -+ -+ /* Enable WOL interrupt */ -+ ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL); -+ if (ret) -+ return ret; -+ } else { -+ /* Disable WOL interrupt */ -+ ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0); -+ if (ret) -+ return ret; -+ } -+ -+ /* Clear WOL status */ -+ ret = phy_read(phydev, AT803X_INTR_STATUS); -+ if (ret < 0) -+ return ret; -+ -+ /* Check if there are other interrupts except for WOL triggered when PHY is -+ * in interrupt mode, only the interrupts enabled by AT803X_INTR_ENABLE can -+ * be passed up to the interrupt PIN. -+ */ -+ irq_enabled = phy_read(phydev, AT803X_INTR_ENABLE); -+ if (irq_enabled < 0) -+ return irq_enabled; -+ -+ irq_enabled &= ~AT803X_INTR_ENABLE_WOL; -+ if (ret & irq_enabled && !phy_polling_mode(phydev)) -+ phy_trigger_machine(phydev); -+ -+ return 0; -+} -+ -+static void at803x_get_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol) -+{ -+ int value; -+ -+ wol->supported = WAKE_MAGIC; -+ wol->wolopts = 0; -+ -+ value = phy_read(phydev, AT803X_INTR_ENABLE); -+ if (value < 0) -+ return; -+ -+ if (value & AT803X_INTR_ENABLE_WOL) -+ wol->wolopts |= WAKE_MAGIC; -+} -+ -+static int qca83xx_get_sset_count(struct phy_device *phydev) -+{ -+ return ARRAY_SIZE(qca83xx_hw_stats); -+} -+ -+static void qca83xx_get_strings(struct phy_device *phydev, u8 *data) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) { -+ strscpy(data + i * ETH_GSTRING_LEN, -+ qca83xx_hw_stats[i].string, ETH_GSTRING_LEN); -+ } -+} -+ -+static u64 qca83xx_get_stat(struct phy_device *phydev, int i) -+{ -+ struct at803x_hw_stat stat = qca83xx_hw_stats[i]; -+ struct at803x_priv *priv = phydev->priv; -+ int val; -+ u64 ret; -+ -+ if (stat.access_type == MMD) -+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg); -+ else -+ val = phy_read(phydev, stat.reg); -+ -+ if (val < 0) { -+ ret = U64_MAX; -+ } else { -+ val = val & stat.mask; -+ priv->stats[i] += val; -+ ret = priv->stats[i]; -+ } -+ -+ return ret; -+} -+ -+static void qca83xx_get_stats(struct phy_device *phydev, -+ struct ethtool_stats *stats, u64 *data) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) -+ data[i] = qca83xx_get_stat(phydev, i); -+} -+ -+static int at803x_suspend(struct phy_device *phydev) -+{ -+ int value; -+ int wol_enabled; -+ -+ value = phy_read(phydev, AT803X_INTR_ENABLE); -+ wol_enabled = value & AT803X_INTR_ENABLE_WOL; -+ -+ if (wol_enabled) -+ value = BMCR_ISOLATE; -+ else -+ value = BMCR_PDOWN; -+ -+ phy_modify(phydev, MII_BMCR, 0, value); -+ -+ return 0; -+} -+ -+static int at803x_resume(struct phy_device *phydev) -+{ -+ return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0); -+} -+ -+static int at803x_parse_dt(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ struct at803x_priv *priv = phydev->priv; -+ u32 freq, strength, tw; -+ unsigned int sel; -+ int ret; -+ -+ if (!IS_ENABLED(CONFIG_OF_MDIO)) -+ return 0; -+ -+ if (of_property_read_bool(node, "qca,disable-smarteee")) -+ priv->flags |= AT803X_DISABLE_SMARTEEE; -+ -+ if (of_property_read_bool(node, "qca,disable-hibernation-mode")) -+ priv->flags |= AT803X_DISABLE_HIBERNATION_MODE; -+ -+ if (!of_property_read_u32(node, "qca,smarteee-tw-us-1g", &tw)) { -+ if (!tw || tw > 255) { -+ phydev_err(phydev, "invalid qca,smarteee-tw-us-1g\n"); -+ return -EINVAL; -+ } -+ priv->smarteee_lpi_tw_1g = tw; -+ } -+ -+ if (!of_property_read_u32(node, "qca,smarteee-tw-us-100m", &tw)) { -+ if (!tw || tw > 255) { -+ phydev_err(phydev, "invalid qca,smarteee-tw-us-100m\n"); -+ return -EINVAL; -+ } -+ priv->smarteee_lpi_tw_100m = tw; -+ } -+ -+ ret = of_property_read_u32(node, "qca,clk-out-frequency", &freq); -+ if (!ret) { -+ switch (freq) { -+ case 25000000: -+ sel = AT803X_CLK_OUT_25MHZ_XTAL; -+ break; -+ case 50000000: -+ sel = AT803X_CLK_OUT_50MHZ_PLL; -+ break; -+ case 62500000: -+ sel = AT803X_CLK_OUT_62_5MHZ_PLL; -+ break; -+ case 125000000: -+ sel = AT803X_CLK_OUT_125MHZ_PLL; -+ break; -+ default: -+ phydev_err(phydev, "invalid qca,clk-out-frequency\n"); -+ return -EINVAL; -+ } -+ -+ priv->clk_25m_reg |= FIELD_PREP(AT803X_CLK_OUT_MASK, sel); -+ priv->clk_25m_mask |= AT803X_CLK_OUT_MASK; -+ } -+ -+ ret = of_property_read_u32(node, "qca,clk-out-strength", &strength); -+ if (!ret) { -+ priv->clk_25m_mask |= AT803X_CLK_OUT_STRENGTH_MASK; -+ switch (strength) { -+ case AR803X_STRENGTH_FULL: -+ priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_FULL; -+ break; -+ case AR803X_STRENGTH_HALF: -+ priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_HALF; -+ break; -+ case AR803X_STRENGTH_QUARTER: -+ priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_QUARTER; -+ break; -+ default: -+ phydev_err(phydev, "invalid qca,clk-out-strength\n"); -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ -+static int at803x_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct at803x_priv *priv; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ /* Init LED polarity mode to -1 */ -+ priv->led_polarity_mode = -1; -+ -+ phydev->priv = priv; -+ -+ ret = at803x_parse_dt(phydev); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int at803x_get_features(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ int err; -+ -+ err = genphy_read_abilities(phydev); -+ if (err) -+ return err; -+ -+ if (phydev->drv->phy_id != ATH8031_PHY_ID) -+ return 0; -+ -+ /* AR8031/AR8033 have different status registers -+ * for copper and fiber operation. However, the -+ * extended status register is the same for both -+ * operation modes. -+ * -+ * As a result of that, ESTATUS_1000_XFULL is set -+ * to 1 even when operating in copper TP mode. -+ * -+ * Remove this mode from the supported link modes -+ * when not operating in 1000BaseX mode. -+ */ -+ if (!priv->is_1000basex) -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, -+ phydev->supported); -+ -+ return 0; -+} -+ -+static int at803x_smarteee_config(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ u16 mask = 0, val = 0; -+ int ret; -+ -+ if (priv->flags & AT803X_DISABLE_SMARTEEE) -+ return phy_modify_mmd(phydev, MDIO_MMD_PCS, -+ AT803X_MMD3_SMARTEEE_CTL3, -+ AT803X_MMD3_SMARTEEE_CTL3_LPI_EN, 0); -+ -+ if (priv->smarteee_lpi_tw_1g) { -+ mask |= 0xff00; -+ val |= priv->smarteee_lpi_tw_1g << 8; -+ } -+ if (priv->smarteee_lpi_tw_100m) { -+ mask |= 0x00ff; -+ val |= priv->smarteee_lpi_tw_100m; -+ } -+ if (!mask) -+ return 0; -+ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL1, -+ mask, val); -+ if (ret) -+ return ret; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL3, -+ AT803X_MMD3_SMARTEEE_CTL3_LPI_EN, -+ AT803X_MMD3_SMARTEEE_CTL3_LPI_EN); -+} -+ -+static int at803x_clk_out_config(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ -+ if (!priv->clk_25m_mask) -+ return 0; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, AT803X_MMD7_CLK25M, -+ priv->clk_25m_mask, priv->clk_25m_reg); -+} -+ -+static int at8031_pll_config(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ -+ /* The default after hardware reset is PLL OFF. After a soft reset, the -+ * values are retained. -+ */ -+ if (priv->flags & AT803X_KEEP_PLL_ENABLED) -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -+ 0, AT803X_DEBUG_PLL_ON); -+ else -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -+ AT803X_DEBUG_PLL_ON, 0); -+} -+ -+static int at803x_hibernation_mode_config(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ -+ /* The default after hardware reset is hibernation mode enabled. After -+ * software reset, the value is retained. -+ */ -+ if (!(priv->flags & AT803X_DISABLE_HIBERNATION_MODE)) -+ return 0; -+ -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL, -+ AT803X_DEBUG_HIB_CTRL_PS_HIB_EN, 0); -+} -+ -+static int at803x_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* The RX and TX delay default is: -+ * after HW reset: RX delay enabled and TX delay disabled -+ * after SW reset: RX delay enabled, while TX delay retains the -+ * value before reset. -+ */ -+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || -+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) -+ ret = at803x_enable_rx_delay(phydev); -+ else -+ ret = at803x_disable_rx_delay(phydev); -+ if (ret < 0) -+ return ret; -+ -+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || -+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) -+ ret = at803x_enable_tx_delay(phydev); -+ else -+ ret = at803x_disable_tx_delay(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ret = at803x_smarteee_config(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ret = at803x_clk_out_config(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ret = at803x_hibernation_mode_config(phydev); -+ if (ret < 0) -+ return ret; -+ -+ /* Ar803x extended next page bit is enabled by default. Cisco -+ * multigig switches read this bit and attempt to negotiate 10Gbps -+ * rates even if the next page bit is disabled. This is incorrect -+ * behaviour but we still need to accommodate it. XNP is only needed -+ * for 10Gbps support, so disable XNP. -+ */ -+ return phy_modify(phydev, MII_ADVERTISE, MDIO_AN_CTRL1_XNP, 0); -+} -+ -+static int at803x_ack_interrupt(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = phy_read(phydev, AT803X_INTR_STATUS); -+ -+ return (err < 0) ? err : 0; -+} -+ -+static int at803x_config_intr(struct phy_device *phydev) -+{ -+ int err; -+ int value; -+ -+ value = phy_read(phydev, AT803X_INTR_ENABLE); -+ -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { -+ /* Clear any pending interrupts */ -+ err = at803x_ack_interrupt(phydev); -+ if (err) -+ return err; -+ -+ value |= AT803X_INTR_ENABLE_AUTONEG_ERR; -+ value |= AT803X_INTR_ENABLE_SPEED_CHANGED; -+ value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED; -+ value |= AT803X_INTR_ENABLE_LINK_FAIL; -+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS; -+ -+ err = phy_write(phydev, AT803X_INTR_ENABLE, value); -+ } else { -+ err = phy_write(phydev, AT803X_INTR_ENABLE, 0); -+ if (err) -+ return err; -+ -+ /* Clear any pending interrupts */ -+ err = at803x_ack_interrupt(phydev); -+ } -+ -+ return err; -+} -+ -+static irqreturn_t at803x_handle_interrupt(struct phy_device *phydev) -+{ -+ int irq_status, int_enabled; -+ -+ irq_status = phy_read(phydev, AT803X_INTR_STATUS); -+ if (irq_status < 0) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ /* Read the current enabled interrupts */ -+ int_enabled = phy_read(phydev, AT803X_INTR_ENABLE); -+ if (int_enabled < 0) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ /* See if this was one of our enabled interrupts */ -+ if (!(irq_status & int_enabled)) -+ return IRQ_NONE; -+ -+ phy_trigger_machine(phydev); -+ -+ return IRQ_HANDLED; -+} -+ -+static void at803x_link_change_notify(struct phy_device *phydev) -+{ -+ /* -+ * Conduct a hardware reset for AT8030 every time a link loss is -+ * signalled. This is necessary to circumvent a hardware bug that -+ * occurs when the cable is unplugged while TX packets are pending -+ * in the FIFO. In such cases, the FIFO enters an error mode it -+ * cannot recover from by software. -+ */ -+ if (phydev->state == PHY_NOLINK && phydev->mdio.reset_gpio) { -+ struct at803x_context context; -+ -+ at803x_context_save(phydev, &context); -+ -+ phy_device_reset(phydev, 1); -+ usleep_range(1000, 2000); -+ phy_device_reset(phydev, 0); -+ usleep_range(1000, 2000); -+ -+ at803x_context_restore(phydev, &context); -+ -+ phydev_dbg(phydev, "%s(): phy was reset\n", __func__); -+ } -+} -+ -+static int at803x_read_specific_status(struct phy_device *phydev, -+ struct at803x_ss_mask ss_mask) -+{ -+ int ss; -+ -+ /* Read the AT8035 PHY-Specific Status register, which indicates the -+ * speed and duplex that the PHY is actually using, irrespective of -+ * whether we are in autoneg mode or not. -+ */ -+ ss = phy_read(phydev, AT803X_SPECIFIC_STATUS); -+ if (ss < 0) -+ return ss; -+ -+ if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) { -+ int sfc, speed; -+ -+ sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL); -+ if (sfc < 0) -+ return sfc; -+ -+ speed = ss & ss_mask.speed_mask; -+ speed >>= ss_mask.speed_shift; -+ -+ switch (speed) { -+ case AT803X_SS_SPEED_10: -+ phydev->speed = SPEED_10; -+ break; -+ case AT803X_SS_SPEED_100: -+ phydev->speed = SPEED_100; -+ break; -+ case AT803X_SS_SPEED_1000: -+ phydev->speed = SPEED_1000; -+ break; -+ case QCA808X_SS_SPEED_2500: -+ phydev->speed = SPEED_2500; -+ break; -+ } -+ if (ss & AT803X_SS_DUPLEX) -+ phydev->duplex = DUPLEX_FULL; -+ else -+ phydev->duplex = DUPLEX_HALF; -+ -+ if (ss & AT803X_SS_MDIX) -+ phydev->mdix = ETH_TP_MDI_X; -+ else -+ phydev->mdix = ETH_TP_MDI; -+ -+ switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) { -+ case AT803X_SFC_MANUAL_MDI: -+ phydev->mdix_ctrl = ETH_TP_MDI; -+ break; -+ case AT803X_SFC_MANUAL_MDIX: -+ phydev->mdix_ctrl = ETH_TP_MDI_X; -+ break; -+ case AT803X_SFC_AUTOMATIC_CROSSOVER: -+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO; -+ break; -+ } -+ } -+ -+ return 0; -+} -+ -+static int at803x_read_status(struct phy_device *phydev) -+{ -+ struct at803x_ss_mask ss_mask = { 0 }; -+ int err, old_link = phydev->link; -+ -+ /* Update the link, but return if there was an error */ -+ err = genphy_update_link(phydev); -+ if (err) -+ return err; -+ -+ /* why bother the PHY if nothing can have changed */ -+ if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) -+ return 0; -+ -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->duplex = DUPLEX_UNKNOWN; -+ phydev->pause = 0; -+ phydev->asym_pause = 0; -+ -+ err = genphy_read_lpa(phydev); -+ if (err < 0) -+ return err; -+ -+ ss_mask.speed_mask = AT803X_SS_SPEED_MASK; -+ ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK); -+ err = at803x_read_specific_status(phydev, ss_mask); -+ if (err < 0) -+ return err; -+ -+ if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) -+ phy_resolve_aneg_pause(phydev); -+ -+ return 0; -+} -+ -+static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl) -+{ -+ u16 val; -+ -+ switch (ctrl) { -+ case ETH_TP_MDI: -+ val = AT803X_SFC_MANUAL_MDI; -+ break; -+ case ETH_TP_MDI_X: -+ val = AT803X_SFC_MANUAL_MDIX; -+ break; -+ case ETH_TP_MDI_AUTO: -+ val = AT803X_SFC_AUTOMATIC_CROSSOVER; -+ break; -+ default: -+ return 0; -+ } -+ -+ return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL, -+ AT803X_SFC_MDI_CROSSOVER_MODE_M, -+ FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val)); -+} -+ -+static int at803x_prepare_config_aneg(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); -+ if (ret < 0) -+ return ret; -+ -+ /* Changes of the midx bits are disruptive to the normal operation; -+ * therefore any changes to these registers must be followed by a -+ * software reset to take effect. -+ */ -+ if (ret == 1) { -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int at803x_config_aneg(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ int ret; -+ -+ ret = at803x_prepare_config_aneg(phydev); -+ if (ret) -+ return ret; -+ -+ if (priv->is_1000basex) -+ return genphy_c37_config_aneg(phydev); -+ -+ return genphy_config_aneg(phydev); -+} -+ -+static int at803x_get_downshift(struct phy_device *phydev, u8 *d) -+{ -+ int val; -+ -+ val = phy_read(phydev, AT803X_SMART_SPEED); -+ if (val < 0) -+ return val; -+ -+ if (val & AT803X_SMART_SPEED_ENABLE) -+ *d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2; -+ else -+ *d = DOWNSHIFT_DEV_DISABLE; -+ -+ return 0; -+} -+ -+static int at803x_set_downshift(struct phy_device *phydev, u8 cnt) -+{ -+ u16 mask, set; -+ int ret; -+ -+ switch (cnt) { -+ case DOWNSHIFT_DEV_DEFAULT_COUNT: -+ cnt = AT803X_DEFAULT_DOWNSHIFT; -+ fallthrough; -+ case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT: -+ set = AT803X_SMART_SPEED_ENABLE | -+ AT803X_SMART_SPEED_BYPASS_TIMER | -+ FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2); -+ mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK; -+ break; -+ case DOWNSHIFT_DEV_DISABLE: -+ set = 0; -+ mask = AT803X_SMART_SPEED_ENABLE | -+ AT803X_SMART_SPEED_BYPASS_TIMER; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set); -+ -+ /* After changing the smart speed settings, we need to perform a -+ * software reset, use phy_init_hw() to make sure we set the -+ * reapply any values which might got lost during software reset. -+ */ -+ if (ret == 1) -+ ret = phy_init_hw(phydev); -+ -+ return ret; -+} -+ -+static int at803x_get_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, void *data) -+{ -+ switch (tuna->id) { -+ case ETHTOOL_PHY_DOWNSHIFT: -+ return at803x_get_downshift(phydev, data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int at803x_set_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, const void *data) -+{ -+ switch (tuna->id) { -+ case ETHTOOL_PHY_DOWNSHIFT: -+ return at803x_set_downshift(phydev, *(const u8 *)data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int at803x_cable_test_result_trans(u16 status) -+{ -+ switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) { -+ case AT803X_CDT_STATUS_STAT_NORMAL: -+ return ETHTOOL_A_CABLE_RESULT_CODE_OK; -+ case AT803X_CDT_STATUS_STAT_SHORT: -+ return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; -+ case AT803X_CDT_STATUS_STAT_OPEN: -+ return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; -+ case AT803X_CDT_STATUS_STAT_FAIL: -+ default: -+ return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; -+ } -+} -+ -+static bool at803x_cdt_test_failed(u16 status) -+{ -+ return FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status) == -+ AT803X_CDT_STATUS_STAT_FAIL; -+} -+ -+static bool at803x_cdt_fault_length_valid(u16 status) -+{ -+ switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) { -+ case AT803X_CDT_STATUS_STAT_OPEN: -+ case AT803X_CDT_STATUS_STAT_SHORT: -+ return true; -+ } -+ return false; -+} -+ -+static int at803x_cdt_fault_length(int dt) -+{ -+ /* According to the datasheet the distance to the fault is -+ * DELTA_TIME * 0.824 meters. -+ * -+ * The author suspect the correct formula is: -+ * -+ * fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2 -+ * -+ * where c is the speed of light, VF is the velocity factor of -+ * the twisted pair cable, 125MHz the counter frequency and -+ * we need to divide by 2 because the hardware will measure the -+ * round trip time to the fault and back to the PHY. -+ * -+ * With a VF of 0.69 we get the factor 0.824 mentioned in the -+ * datasheet. -+ */ -+ return (dt * 824) / 10; -+} -+ -+static int at803x_cdt_start(struct phy_device *phydev, -+ u32 cdt_start) -+{ -+ return phy_write(phydev, AT803X_CDT, cdt_start); -+} -+ -+static int at803x_cdt_wait_for_completion(struct phy_device *phydev, -+ u32 cdt_en) -+{ -+ int val, ret; -+ -+ /* One test run takes about 25ms */ -+ ret = phy_read_poll_timeout(phydev, AT803X_CDT, val, -+ !(val & cdt_en), -+ 30000, 100000, true); -+ -+ return ret < 0 ? ret : 0; -+} -+ -+static int at803x_cable_test_one_pair(struct phy_device *phydev, int pair) -+{ -+ static const int ethtool_pair[] = { -+ ETHTOOL_A_CABLE_PAIR_A, -+ ETHTOOL_A_CABLE_PAIR_B, -+ ETHTOOL_A_CABLE_PAIR_C, -+ ETHTOOL_A_CABLE_PAIR_D, -+ }; -+ int ret, val; -+ -+ val = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) | -+ AT803X_CDT_ENABLE_TEST; -+ ret = at803x_cdt_start(phydev, val); -+ if (ret) -+ return ret; -+ -+ ret = at803x_cdt_wait_for_completion(phydev, AT803X_CDT_ENABLE_TEST); -+ if (ret) -+ return ret; -+ -+ val = phy_read(phydev, AT803X_CDT_STATUS); -+ if (val < 0) -+ return val; -+ -+ if (at803x_cdt_test_failed(val)) -+ return 0; -+ -+ ethnl_cable_test_result(phydev, ethtool_pair[pair], -+ at803x_cable_test_result_trans(val)); -+ -+ if (at803x_cdt_fault_length_valid(val)) { -+ val = FIELD_GET(AT803X_CDT_STATUS_DELTA_TIME_MASK, val); -+ ethnl_cable_test_fault_length(phydev, ethtool_pair[pair], -+ at803x_cdt_fault_length(val)); -+ } -+ -+ return 1; -+} -+ -+static int at803x_cable_test_get_status(struct phy_device *phydev, -+ bool *finished, unsigned long pair_mask) -+{ -+ int retries = 20; -+ int pair, ret; -+ -+ *finished = false; -+ -+ /* According to the datasheet the CDT can be performed when -+ * there is no link partner or when the link partner is -+ * auto-negotiating. Starting the test will restart the AN -+ * automatically. It seems that doing this repeatedly we will -+ * get a slot where our link partner won't disturb our -+ * measurement. -+ */ -+ while (pair_mask && retries--) { -+ for_each_set_bit(pair, &pair_mask, 4) { -+ ret = at803x_cable_test_one_pair(phydev, pair); -+ if (ret < 0) -+ return ret; -+ if (ret) -+ clear_bit(pair, &pair_mask); -+ } -+ if (pair_mask) -+ msleep(250); -+ } -+ -+ *finished = true; -+ -+ return 0; -+} -+ -+static void at803x_cable_test_autoneg(struct phy_device *phydev) -+{ -+ /* Enable auto-negotiation, but advertise no capabilities, no link -+ * will be established. A restart of the auto-negotiation is not -+ * required, because the cable test will automatically break the link. -+ */ -+ phy_write(phydev, MII_BMCR, BMCR_ANENABLE); -+ phy_write(phydev, MII_ADVERTISE, ADVERTISE_CSMA); -+} -+ -+static int at803x_cable_test_start(struct phy_device *phydev) -+{ -+ at803x_cable_test_autoneg(phydev); -+ /* we do all the (time consuming) work later */ -+ return 0; -+} -+ -+static int at8031_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev, -+ unsigned int selector) -+{ -+ struct phy_device *phydev = rdev_get_drvdata(rdev); -+ -+ if (selector) -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -+ 0, AT803X_DEBUG_RGMII_1V8); -+ else -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, -+ AT803X_DEBUG_RGMII_1V8, 0); -+} -+ -+static int at8031_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev) -+{ -+ struct phy_device *phydev = rdev_get_drvdata(rdev); -+ int val; -+ -+ val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F); -+ if (val < 0) -+ return val; -+ -+ return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0; -+} -+ -+static const struct regulator_ops vddio_regulator_ops = { -+ .list_voltage = regulator_list_voltage_table, -+ .set_voltage_sel = at8031_rgmii_reg_set_voltage_sel, -+ .get_voltage_sel = at8031_rgmii_reg_get_voltage_sel, -+}; -+ -+static const unsigned int vddio_voltage_table[] = { -+ 1500000, -+ 1800000, -+}; -+ -+static const struct regulator_desc vddio_desc = { -+ .name = "vddio", -+ .of_match = of_match_ptr("vddio-regulator"), -+ .n_voltages = ARRAY_SIZE(vddio_voltage_table), -+ .volt_table = vddio_voltage_table, -+ .ops = &vddio_regulator_ops, -+ .type = REGULATOR_VOLTAGE, -+ .owner = THIS_MODULE, -+}; -+ -+static const struct regulator_ops vddh_regulator_ops = { -+}; -+ -+static const struct regulator_desc vddh_desc = { -+ .name = "vddh", -+ .of_match = of_match_ptr("vddh-regulator"), -+ .n_voltages = 1, -+ .fixed_uV = 2500000, -+ .ops = &vddh_regulator_ops, -+ .type = REGULATOR_VOLTAGE, -+ .owner = THIS_MODULE, -+}; -+ -+static int at8031_register_regulators(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ struct device *dev = &phydev->mdio.dev; -+ struct regulator_config config = { }; -+ -+ config.dev = dev; -+ config.driver_data = phydev; -+ -+ priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config); -+ if (IS_ERR(priv->vddio_rdev)) { -+ phydev_err(phydev, "failed to register VDDIO regulator\n"); -+ return PTR_ERR(priv->vddio_rdev); -+ } -+ -+ priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config); -+ if (IS_ERR(priv->vddh_rdev)) { -+ phydev_err(phydev, "failed to register VDDH regulator\n"); -+ return PTR_ERR(priv->vddh_rdev); -+ } -+ -+ return 0; -+} -+ -+static int at8031_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) -+{ -+ struct phy_device *phydev = upstream; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support); -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support); -+ DECLARE_PHY_INTERFACE_MASK(interfaces); -+ phy_interface_t iface; -+ -+ linkmode_zero(phy_support); -+ phylink_set(phy_support, 1000baseX_Full); -+ phylink_set(phy_support, 1000baseT_Full); -+ phylink_set(phy_support, Autoneg); -+ phylink_set(phy_support, Pause); -+ phylink_set(phy_support, Asym_Pause); -+ -+ linkmode_zero(sfp_support); -+ sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces); -+ /* Some modules support 10G modes as well as others we support. -+ * Mask out non-supported modes so the correct interface is picked. -+ */ -+ linkmode_and(sfp_support, phy_support, sfp_support); -+ -+ if (linkmode_empty(sfp_support)) { -+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n"); -+ return -EINVAL; -+ } -+ -+ iface = sfp_select_interface(phydev->sfp_bus, sfp_support); -+ -+ /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes -+ * interface for use with SFP modules. -+ * However, some copper modules detected as having a preferred SGMII -+ * interface do default to and function in 1000Base-X mode, so just -+ * print a warning and allow such modules, as they may have some chance -+ * of working. -+ */ -+ if (iface == PHY_INTERFACE_MODE_SGMII) -+ dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n"); -+ else if (iface != PHY_INTERFACE_MODE_1000BASEX) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static const struct sfp_upstream_ops at8031_sfp_ops = { -+ .attach = phy_sfp_attach, -+ .detach = phy_sfp_detach, -+ .module_insert = at8031_sfp_insert, -+}; -+ -+static int at8031_parse_dt(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ struct at803x_priv *priv = phydev->priv; -+ int ret; -+ -+ if (of_property_read_bool(node, "qca,keep-pll-enabled")) -+ priv->flags |= AT803X_KEEP_PLL_ENABLED; -+ -+ ret = at8031_register_regulators(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ret = devm_regulator_get_enable_optional(&phydev->mdio.dev, -+ "vddio"); -+ if (ret) { -+ phydev_err(phydev, "failed to get VDDIO regulator\n"); -+ return ret; -+ } -+ -+ /* Only AR8031/8033 support 1000Base-X for SFP modules */ -+ return phy_sfp_probe(phydev, &at8031_sfp_ops); -+} -+ -+static int at8031_probe(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ int mode_cfg; -+ int ccr; -+ int ret; -+ -+ ret = at803x_probe(phydev); -+ if (ret) -+ return ret; -+ -+ /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping -+ * options. -+ */ -+ ret = at8031_parse_dt(phydev); -+ if (ret) -+ return ret; -+ -+ ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); -+ if (ccr < 0) -+ return ccr; -+ mode_cfg = ccr & AT803X_MODE_CFG_MASK; -+ -+ switch (mode_cfg) { -+ case AT803X_MODE_CFG_BX1000_RGMII_50OHM: -+ case AT803X_MODE_CFG_BX1000_RGMII_75OHM: -+ priv->is_1000basex = true; -+ fallthrough; -+ case AT803X_MODE_CFG_FX100_RGMII_50OHM: -+ case AT803X_MODE_CFG_FX100_RGMII_75OHM: -+ priv->is_fiber = true; -+ break; -+ } -+ -+ /* Disable WoL in 1588 register which is enabled -+ * by default -+ */ -+ return phy_modify_mmd(phydev, MDIO_MMD_PCS, -+ AT803X_PHY_MMD3_WOL_CTRL, -+ AT803X_WOL_EN, 0); -+} -+ -+static int at8031_config_init(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ int ret; -+ -+ /* Some bootloaders leave the fiber page selected. -+ * Switch to the appropriate page (fiber or copper), as otherwise we -+ * read the PHY capabilities from the wrong page. -+ */ -+ phy_lock_mdio_bus(phydev); -+ ret = at803x_write_page(phydev, -+ priv->is_fiber ? AT803X_PAGE_FIBER : -+ AT803X_PAGE_COPPER); -+ phy_unlock_mdio_bus(phydev); -+ if (ret) -+ return ret; -+ -+ ret = at8031_pll_config(phydev); -+ if (ret < 0) -+ return ret; -+ -+ return at803x_config_init(phydev); -+} -+ -+static int at8031_set_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol) -+{ -+ int ret; -+ -+ /* First setup MAC address and enable WOL interrupt */ -+ ret = at803x_set_wol(phydev, wol); -+ if (ret) -+ return ret; -+ -+ if (wol->wolopts & WAKE_MAGIC) -+ /* Enable WOL function for 1588 */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -+ AT803X_PHY_MMD3_WOL_CTRL, -+ 0, AT803X_WOL_EN); -+ else -+ /* Disable WoL function for 1588 */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, -+ AT803X_PHY_MMD3_WOL_CTRL, -+ AT803X_WOL_EN, 0); -+ -+ return ret; -+} -+ -+static int at8031_config_intr(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ int err, value = 0; -+ -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED && -+ priv->is_fiber) { -+ /* Clear any pending interrupts */ -+ err = at803x_ack_interrupt(phydev); -+ if (err) -+ return err; -+ -+ value |= AT803X_INTR_ENABLE_LINK_FAIL_BX; -+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX; -+ -+ err = phy_set_bits(phydev, AT803X_INTR_ENABLE, value); -+ if (err) -+ return err; -+ } -+ -+ return at803x_config_intr(phydev); -+} -+ -+/* AR8031 and AR8033 share the same read status logic */ -+static int at8031_read_status(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ -+ if (priv->is_1000basex) -+ return genphy_c37_read_status(phydev); -+ -+ return at803x_read_status(phydev); -+} -+ -+/* AR8031 and AR8035 share the same cable test get status reg */ -+static int at8031_cable_test_get_status(struct phy_device *phydev, -+ bool *finished) -+{ -+ return at803x_cable_test_get_status(phydev, finished, 0xf); -+} -+ -+/* AR8031 and AR8035 share the same cable test start logic */ -+static int at8031_cable_test_start(struct phy_device *phydev) -+{ -+ at803x_cable_test_autoneg(phydev); -+ phy_write(phydev, MII_CTRL1000, 0); -+ /* we do all the (time consuming) work later */ -+ return 0; -+} -+ -+/* AR8032, AR9331 and QCA9561 share the same cable test get status reg */ -+static int at8032_cable_test_get_status(struct phy_device *phydev, -+ bool *finished) -+{ -+ return at803x_cable_test_get_status(phydev, finished, 0x3); -+} -+ -+static int at8035_parse_dt(struct phy_device *phydev) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ -+ /* Mask is set by the generic at803x_parse_dt -+ * if property is set. Assume property is set -+ * with the mask not zero. -+ */ -+ if (priv->clk_25m_mask) { -+ /* Fixup for the AR8030/AR8035. This chip has another mask and -+ * doesn't support the DSP reference. Eg. the lowest bit of the -+ * mask. The upper two bits select the same frequencies. Mask -+ * the lowest bit here. -+ * -+ * Warning: -+ * There was no datasheet for the AR8030 available so this is -+ * just a guess. But the AR8035 is listed as pin compatible -+ * to the AR8030 so there might be a good chance it works on -+ * the AR8030 too. -+ */ -+ priv->clk_25m_reg &= AT8035_CLK_OUT_MASK; -+ priv->clk_25m_mask &= AT8035_CLK_OUT_MASK; -+ } -+ -+ return 0; -+} -+ -+/* AR8030 and AR8035 shared the same special mask for clk_25m */ -+static int at8035_probe(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = at803x_probe(phydev); -+ if (ret) -+ return ret; -+ -+ return at8035_parse_dt(phydev); -+} -+ -+static int qca83xx_config_init(struct phy_device *phydev) -+{ -+ u8 switch_revision; -+ -+ switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK; -+ -+ switch (switch_revision) { -+ case 1: -+ /* For 100M waveform */ -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea); -+ /* Turn on Gigabit clock */ -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0); -+ break; -+ -+ case 2: -+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0); -+ fallthrough; -+ case 4: -+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f); -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860); -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46); -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000); -+ break; -+ } -+ -+ /* Following original QCA sourcecode set port to prefer master */ -+ phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER); -+ -+ return 0; -+} -+ -+static int qca8327_config_init(struct phy_device *phydev) -+{ -+ /* QCA8327 require DAC amplitude adjustment for 100m set to +6%. -+ * Disable on init and enable only with 100m speed following -+ * qca original source code. -+ */ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -+ QCA8327_DEBUG_MANU_CTRL_EN, 0); -+ -+ return qca83xx_config_init(phydev); -+} -+ -+static void qca83xx_link_change_notify(struct phy_device *phydev) -+{ -+ /* Set DAC Amplitude adjustment to +6% for 100m on link running */ -+ if (phydev->state == PHY_RUNNING) { -+ if (phydev->speed == SPEED_100) -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -+ QCA8327_DEBUG_MANU_CTRL_EN, -+ QCA8327_DEBUG_MANU_CTRL_EN); -+ } else { -+ /* Reset DAC Amplitude adjustment */ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -+ QCA8327_DEBUG_MANU_CTRL_EN, 0); -+ } -+} -+ -+static int qca83xx_resume(struct phy_device *phydev) -+{ -+ int ret, val; -+ -+ /* Skip reset if not suspended */ -+ if (!phydev->suspended) -+ return 0; -+ -+ /* Reinit the port, reset values set by suspend */ -+ qca83xx_config_init(phydev); -+ -+ /* Reset the port on port resume */ -+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); -+ -+ /* On resume from suspend the switch execute a reset and -+ * restart auto-negotiation. Wait for reset to complete. -+ */ -+ ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET), -+ 50000, 600000, true); -+ if (ret) -+ return ret; -+ -+ usleep_range(1000, 2000); -+ -+ return 0; -+} -+ -+static int qca83xx_suspend(struct phy_device *phydev) -+{ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN, -+ AT803X_DEBUG_GATE_CLK_IN1000, 0); -+ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL, -+ AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE | -+ AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0); -+ -+ return 0; -+} -+ -+static int qca8337_suspend(struct phy_device *phydev) -+{ -+ /* Only QCA8337 support actual suspend. */ -+ genphy_suspend(phydev); -+ -+ return qca83xx_suspend(phydev); -+} -+ -+static int qca8327_suspend(struct phy_device *phydev) -+{ -+ u16 mask = 0; -+ -+ /* QCA8327 cause port unreliability when phy suspend -+ * is set. -+ */ -+ mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX); -+ phy_modify(phydev, MII_BMCR, mask, 0); -+ -+ return qca83xx_suspend(phydev); -+} -+ -+static int qca808x_phy_fast_retrain_config(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Enable fast retrain */ -+ ret = genphy_c45_fast_retrain(phydev, true); -+ if (ret) -+ return ret; -+ -+ phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1, -+ QCA808X_TOP_OPTION1_DATA); -+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB, -+ QCA808X_MSE_THRESHOLD_20DB_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB, -+ QCA808X_MSE_THRESHOLD_17DB_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB, -+ QCA808X_MSE_THRESHOLD_27DB_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB, -+ QCA808X_MSE_THRESHOLD_28DB_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1, -+ QCA808X_MMD3_DEBUG_1_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4, -+ QCA808X_MMD3_DEBUG_4_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5, -+ QCA808X_MMD3_DEBUG_5_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3, -+ QCA808X_MMD3_DEBUG_3_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6, -+ QCA808X_MMD3_DEBUG_6_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2, -+ QCA808X_MMD3_DEBUG_2_VALUE); -+ -+ return 0; -+} -+ -+static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable) -+{ -+ u16 seed_value; -+ -+ if (!enable) -+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -+ QCA808X_MASTER_SLAVE_SEED_ENABLE, 0); -+ -+ seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE); -+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -+ QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE, -+ FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) | -+ QCA808X_MASTER_SLAVE_SEED_ENABLE); -+} -+ -+static bool qca808x_is_prefer_master(struct phy_device *phydev) -+{ -+ return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) || -+ (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED); -+} -+ -+static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev) -+{ -+ return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); -+} -+ -+static int qca808x_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Active adc&vga on 802.3az for the link 1000M and 100M */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7, -+ QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN); -+ if (ret) -+ return ret; -+ -+ /* Adjust the threshold on 802.3az for the link 1000M */ -+ ret = phy_write_mmd(phydev, MDIO_MMD_PCS, -+ QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, -+ QCA808X_MMD3_AZ_TRAINING_VAL); -+ if (ret) -+ return ret; -+ -+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { -+ /* Config the fast retrain for the link 2500M */ -+ ret = qca808x_phy_fast_retrain_config(phydev); -+ if (ret) -+ return ret; -+ -+ ret = genphy_read_master_slave(phydev); -+ if (ret < 0) -+ return ret; -+ -+ if (!qca808x_is_prefer_master(phydev)) { -+ /* Enable seed and configure lower ramdom seed to make phy -+ * linked as slave mode. -+ */ -+ ret = qca808x_phy_ms_seed_enable(phydev, true); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ /* Configure adc threshold as 100mv for the link 10M */ -+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD, -+ QCA808X_ADC_THRESHOLD_MASK, -+ QCA808X_ADC_THRESHOLD_100MV); -+} -+ -+static int qca808x_read_status(struct phy_device *phydev) -+{ -+ struct at803x_ss_mask ss_mask = { 0 }; -+ int ret; -+ -+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); -+ if (ret < 0) -+ return ret; -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising, -+ ret & MDIO_AN_10GBT_STAT_LP2_5G); -+ -+ ret = genphy_read_status(phydev); -+ if (ret) -+ return ret; -+ -+ /* qca8081 takes the different bits for speed value from at803x */ -+ ss_mask.speed_mask = QCA808X_SS_SPEED_MASK; -+ ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK); -+ ret = at803x_read_specific_status(phydev, ss_mask); -+ if (ret < 0) -+ return ret; -+ -+ if (phydev->link) { -+ if (phydev->speed == SPEED_2500) -+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -+ else -+ phydev->interface = PHY_INTERFACE_MODE_SGMII; -+ } else { -+ /* generate seed as a lower random value to make PHY linked as SLAVE easily, -+ * except for master/slave configuration fault detected or the master mode -+ * preferred. -+ * -+ * the reason for not putting this code into the function link_change_notify is -+ * the corner case where the link partner is also the qca8081 PHY and the seed -+ * value is configured as the same value, the link can't be up and no link change -+ * occurs. -+ */ -+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { -+ if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR || -+ qca808x_is_prefer_master(phydev)) { -+ qca808x_phy_ms_seed_enable(phydev, false); -+ } else { -+ qca808x_phy_ms_seed_enable(phydev, true); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static int qca808x_soft_reset(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) -+ return ret; -+ -+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) -+ ret = qca808x_phy_ms_seed_enable(phydev, true); -+ -+ return ret; -+} -+ -+static bool qca808x_cdt_fault_length_valid(int cdt_code) -+{ -+ switch (cdt_code) { -+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+static int qca808x_cable_test_result_trans(int cdt_code) -+{ -+ switch (cdt_code) { -+ case QCA808X_CDT_STATUS_STAT_NORMAL: -+ return ETHTOOL_A_CABLE_RESULT_CODE_OK; -+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -+ return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; -+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -+ return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -+ return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; -+ case QCA808X_CDT_STATUS_STAT_FAIL: -+ default: -+ return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; -+ } -+} -+ -+static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, -+ int result) -+{ -+ int val; -+ u32 cdt_length_reg = 0; -+ -+ switch (pair) { -+ case ETHTOOL_A_CABLE_PAIR_A: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; -+ break; -+ case ETHTOOL_A_CABLE_PAIR_B: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; -+ break; -+ case ETHTOOL_A_CABLE_PAIR_C: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; -+ break; -+ case ETHTOOL_A_CABLE_PAIR_D: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); -+ if (val < 0) -+ return val; -+ -+ if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) -+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); -+ else -+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); -+ -+ return at803x_cdt_fault_length(val); -+} -+ -+static int qca808x_cable_test_start(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* perform CDT with the following configs: -+ * 1. disable hibernation. -+ * 2. force PHY working in MDI mode. -+ * 3. for PHY working in 1000BaseT. -+ * 4. configure the threshold. -+ */ -+ -+ ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0); -+ if (ret < 0) -+ return ret; -+ -+ ret = at803x_config_mdix(phydev, ETH_TP_MDI); -+ if (ret < 0) -+ return ret; -+ -+ /* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */ -+ phydev->duplex = DUPLEX_FULL; -+ phydev->speed = SPEED_1000; -+ ret = genphy_c45_pma_setup_forced(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ret = genphy_setup_forced(phydev); -+ if (ret < 0) -+ return ret; -+ -+ /* configure the thresholds for open, short, pair ok test */ -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060); -+ -+ return 0; -+} -+ -+static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, -+ u16 status) -+{ -+ int length, result; -+ u16 pair_code; -+ -+ switch (pair) { -+ case ETHTOOL_A_CABLE_PAIR_A: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_B: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_C: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_D: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ result = qca808x_cable_test_result_trans(pair_code); -+ ethnl_cable_test_result(phydev, pair, result); -+ -+ if (qca808x_cdt_fault_length_valid(pair_code)) { -+ length = qca808x_cdt_fault_length(phydev, pair, result); -+ ethnl_cable_test_fault_length(phydev, pair, length); -+ } -+ -+ return 0; -+} -+ -+static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) -+{ -+ int ret, val; -+ -+ *finished = false; -+ -+ val = QCA808X_CDT_ENABLE_TEST | -+ QCA808X_CDT_LENGTH_UNIT; -+ ret = at803x_cdt_start(phydev, val); -+ if (ret) -+ return ret; -+ -+ ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); -+ if (ret) -+ return ret; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); -+ if (val < 0) -+ return val; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); -+ if (ret) -+ return ret; -+ -+ *finished = true; -+ -+ return 0; -+} -+ -+static int qca808x_get_features(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = genphy_c45_pma_read_abilities(phydev); -+ if (ret) -+ return ret; -+ -+ /* The autoneg ability is not existed in bit3 of MMD7.1, -+ * but it is supported by qca808x PHY, so we add it here -+ * manually. -+ */ -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported); -+ -+ /* As for the qca8081 1G version chip, the 2500baseT ability is also -+ * existed in the bit0 of MMD1.21, we need to remove it manually if -+ * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d. -+ */ -+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE); -+ if (ret < 0) -+ return ret; -+ -+ if (QCA808X_PHY_CHIP_TYPE_1G & ret) -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); -+ -+ return 0; -+} -+ -+static int qca808x_config_aneg(struct phy_device *phydev) -+{ -+ int phy_ctrl = 0; -+ int ret; -+ -+ ret = at803x_prepare_config_aneg(phydev); -+ if (ret) -+ return ret; -+ -+ /* The reg MII_BMCR also needs to be configured for force mode, the -+ * genphy_config_aneg is also needed. -+ */ -+ if (phydev->autoneg == AUTONEG_DISABLE) -+ genphy_c45_pma_setup_forced(phydev); -+ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising)) -+ phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G; -+ -+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, -+ MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl); -+ if (ret < 0) -+ return ret; -+ -+ return __genphy_config_aneg(phydev, ret); -+} -+ -+static void qca808x_link_change_notify(struct phy_device *phydev) -+{ -+ /* Assert interface sgmii fifo on link down, deassert it on link up, -+ * the interface device address is always phy address added by 1. -+ */ -+ mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1, -+ MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL, -+ QCA8081_PHY_FIFO_RSTN, -+ phydev->link ? QCA8081_PHY_FIFO_RSTN : 0); -+} -+ -+static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules, -+ u16 *offload_trigger) -+{ -+ /* Parsing specific to netdev trigger */ -+ if (test_bit(TRIGGER_NETDEV_TX, &rules)) -+ *offload_trigger |= QCA808X_LED_TX_BLINK; -+ if (test_bit(TRIGGER_NETDEV_RX, &rules)) -+ *offload_trigger |= QCA808X_LED_RX_BLINK; -+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED10_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED100_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED1000_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED2500_ON; -+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) -+ *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON; -+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) -+ *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON; -+ -+ if (rules && !*offload_trigger) -+ return -EOPNOTSUPP; -+ -+ /* Enable BLINK_CHECK_BYPASS by default to make the LED -+ * blink even with duplex or speed mode not enabled. -+ */ -+ *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS; -+ -+ return 0; -+} -+ -+static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN); -+} -+ -+static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 offload_trigger = 0; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ return qca808x_led_parse_netdev(phydev, rules, &offload_trigger); -+} -+ -+static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 reg, offload_trigger = 0; -+ int ret; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_CTRL(index); -+ -+ ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_led_hw_control_enable(phydev, index); -+ if (ret) -+ return ret; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_PATTERN_MASK, -+ offload_trigger); -+} -+ -+static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ int val; -+ -+ if (index > 2) -+ return false; -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -+ -+ return !(val & QCA808X_LED_FORCE_EN); -+} -+ -+static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ u16 reg; -+ int val; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ /* Check if we have hw control enabled */ -+ if (qca808x_led_hw_control_status(phydev, index)) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_CTRL(index); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -+ if (val & QCA808X_LED_TX_BLINK) -+ set_bit(TRIGGER_NETDEV_TX, rules); -+ if (val & QCA808X_LED_RX_BLINK) -+ set_bit(TRIGGER_NETDEV_RX, rules); -+ if (val & QCA808X_LED_SPEED10_ON) -+ set_bit(TRIGGER_NETDEV_LINK_10, rules); -+ if (val & QCA808X_LED_SPEED100_ON) -+ set_bit(TRIGGER_NETDEV_LINK_100, rules); -+ if (val & QCA808X_LED_SPEED1000_ON) -+ set_bit(TRIGGER_NETDEV_LINK_1000, rules); -+ if (val & QCA808X_LED_SPEED2500_ON) -+ set_bit(TRIGGER_NETDEV_LINK_2500, rules); -+ if (val & QCA808X_LED_HALF_DUPLEX_ON) -+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); -+ if (val & QCA808X_LED_FULL_DUPLEX_ON) -+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); -+ -+ return 0; -+} -+ -+static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_CTRL(index); -+ -+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_PATTERN_MASK); -+} -+ -+static int qca808x_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ u16 reg; -+ int ret; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ if (!value) { -+ ret = qca808x_led_hw_control_reset(phydev, index); -+ if (ret) -+ return ret; -+ } -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -+ QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON : -+ QCA808X_LED_FORCE_OFF); -+} -+ -+static int qca808x_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ int ret; -+ u16 reg; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ /* Set blink to 50% off, 50% on at 4Hz by default */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, -+ QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, -+ QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); -+ if (ret) -+ return ret; -+ -+ /* We use BLINK_1 for normal blinking */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); -+ if (ret) -+ return ret; -+ -+ /* We set blink to 4Hz, aka 250ms */ -+ *delay_on = 250 / 2; -+ *delay_off = 250 / 2; -+ -+ return 0; -+} -+ -+static int qca808x_led_polarity_set(struct phy_device *phydev, int index, -+ unsigned long modes) -+{ -+ struct at803x_priv *priv = phydev->priv; -+ bool active_low = false; -+ u32 mode; -+ -+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { -+ switch (mode) { -+ case PHY_LED_ACTIVE_LOW: -+ active_low = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ /* PHY polarity is global and can't be set per LED. -+ * To detect this, check if last requested polarity mode -+ * match the new one. -+ */ -+ if (priv->led_polarity_mode >= 0 && -+ priv->led_polarity_mode != active_low) { -+ phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n"); -+ return -EINVAL; -+ } -+ -+ /* Save the last PHY polarity mode */ -+ priv->led_polarity_mode = active_low; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, -+ QCA808X_MMD7_LED_POLARITY_CTRL, -+ QCA808X_LED_ACTIVE_HIGH, -+ active_low ? 0 : QCA808X_LED_ACTIVE_HIGH); -+} -+ -+static struct phy_driver at803x_driver[] = { -+{ -+ /* Qualcomm Atheros AR8035 */ -+ PHY_ID_MATCH_EXACT(ATH8035_PHY_ID), -+ .name = "Qualcomm Atheros AR8035", -+ .flags = PHY_POLL_CABLE_TEST, -+ .probe = at8035_probe, -+ .config_aneg = at803x_config_aneg, -+ .config_init = at803x_config_init, -+ .soft_reset = genphy_soft_reset, -+ .set_wol = at803x_set_wol, -+ .get_wol = at803x_get_wol, -+ .suspend = at803x_suspend, -+ .resume = at803x_resume, -+ /* PHY_GBIT_FEATURES */ -+ .read_status = at803x_read_status, -+ .config_intr = at803x_config_intr, -+ .handle_interrupt = at803x_handle_interrupt, -+ .get_tunable = at803x_get_tunable, -+ .set_tunable = at803x_set_tunable, -+ .cable_test_start = at8031_cable_test_start, -+ .cable_test_get_status = at8031_cable_test_get_status, -+}, { -+ /* Qualcomm Atheros AR8030 */ -+ .phy_id = ATH8030_PHY_ID, -+ .name = "Qualcomm Atheros AR8030", -+ .phy_id_mask = AT8030_PHY_ID_MASK, -+ .probe = at8035_probe, -+ .config_init = at803x_config_init, -+ .link_change_notify = at803x_link_change_notify, -+ .set_wol = at803x_set_wol, -+ .get_wol = at803x_get_wol, -+ .suspend = at803x_suspend, -+ .resume = at803x_resume, -+ /* PHY_BASIC_FEATURES */ -+ .config_intr = at803x_config_intr, -+ .handle_interrupt = at803x_handle_interrupt, -+}, { -+ /* Qualcomm Atheros AR8031/AR8033 */ -+ PHY_ID_MATCH_EXACT(ATH8031_PHY_ID), -+ .name = "Qualcomm Atheros AR8031/AR8033", -+ .flags = PHY_POLL_CABLE_TEST, -+ .probe = at8031_probe, -+ .config_init = at8031_config_init, -+ .config_aneg = at803x_config_aneg, -+ .soft_reset = genphy_soft_reset, -+ .set_wol = at8031_set_wol, -+ .get_wol = at803x_get_wol, -+ .suspend = at803x_suspend, -+ .resume = at803x_resume, -+ .read_page = at803x_read_page, -+ .write_page = at803x_write_page, -+ .get_features = at803x_get_features, -+ .read_status = at8031_read_status, -+ .config_intr = at8031_config_intr, -+ .handle_interrupt = at803x_handle_interrupt, -+ .get_tunable = at803x_get_tunable, -+ .set_tunable = at803x_set_tunable, -+ .cable_test_start = at8031_cable_test_start, -+ .cable_test_get_status = at8031_cable_test_get_status, -+}, { -+ /* Qualcomm Atheros AR8032 */ -+ PHY_ID_MATCH_EXACT(ATH8032_PHY_ID), -+ .name = "Qualcomm Atheros AR8032", -+ .probe = at803x_probe, -+ .flags = PHY_POLL_CABLE_TEST, -+ .config_init = at803x_config_init, -+ .link_change_notify = at803x_link_change_notify, -+ .suspend = at803x_suspend, -+ .resume = at803x_resume, -+ /* PHY_BASIC_FEATURES */ -+ .config_intr = at803x_config_intr, -+ .handle_interrupt = at803x_handle_interrupt, -+ .cable_test_start = at803x_cable_test_start, -+ .cable_test_get_status = at8032_cable_test_get_status, -+}, { -+ /* ATHEROS AR9331 */ -+ PHY_ID_MATCH_EXACT(ATH9331_PHY_ID), -+ .name = "Qualcomm Atheros AR9331 built-in PHY", -+ .probe = at803x_probe, -+ .suspend = at803x_suspend, -+ .resume = at803x_resume, -+ .flags = PHY_POLL_CABLE_TEST, -+ /* PHY_BASIC_FEATURES */ -+ .config_intr = at803x_config_intr, -+ .handle_interrupt = at803x_handle_interrupt, -+ .cable_test_start = at803x_cable_test_start, -+ .cable_test_get_status = at8032_cable_test_get_status, -+ .read_status = at803x_read_status, -+ .soft_reset = genphy_soft_reset, -+ .config_aneg = at803x_config_aneg, -+}, { -+ /* Qualcomm Atheros QCA9561 */ -+ PHY_ID_MATCH_EXACT(QCA9561_PHY_ID), -+ .name = "Qualcomm Atheros QCA9561 built-in PHY", -+ .probe = at803x_probe, -+ .suspend = at803x_suspend, -+ .resume = at803x_resume, -+ .flags = PHY_POLL_CABLE_TEST, -+ /* PHY_BASIC_FEATURES */ -+ .config_intr = at803x_config_intr, -+ .handle_interrupt = at803x_handle_interrupt, -+ .cable_test_start = at803x_cable_test_start, -+ .cable_test_get_status = at8032_cable_test_get_status, -+ .read_status = at803x_read_status, -+ .soft_reset = genphy_soft_reset, -+ .config_aneg = at803x_config_aneg, -+}, { -+ /* QCA8337 */ -+ .phy_id = QCA8337_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "Qualcomm Atheros 8337 internal PHY", -+ /* PHY_GBIT_FEATURES */ -+ .probe = at803x_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca83xx_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = qca83xx_get_sset_count, -+ .get_strings = qca83xx_get_strings, -+ .get_stats = qca83xx_get_stats, -+ .suspend = qca8337_suspend, -+ .resume = qca83xx_resume, -+}, { -+ /* QCA8327-A from switch QCA8327-AL1A */ -+ .phy_id = QCA8327_A_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "Qualcomm Atheros 8327-A internal PHY", -+ /* PHY_GBIT_FEATURES */ -+ .link_change_notify = qca83xx_link_change_notify, -+ .probe = at803x_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca8327_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = qca83xx_get_sset_count, -+ .get_strings = qca83xx_get_strings, -+ .get_stats = qca83xx_get_stats, -+ .suspend = qca8327_suspend, -+ .resume = qca83xx_resume, -+}, { -+ /* QCA8327-B from switch QCA8327-BL1A */ -+ .phy_id = QCA8327_B_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "Qualcomm Atheros 8327-B internal PHY", -+ /* PHY_GBIT_FEATURES */ -+ .link_change_notify = qca83xx_link_change_notify, -+ .probe = at803x_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca8327_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = qca83xx_get_sset_count, -+ .get_strings = qca83xx_get_strings, -+ .get_stats = qca83xx_get_stats, -+ .suspend = qca8327_suspend, -+ .resume = qca83xx_resume, -+}, { -+ /* Qualcomm QCA8081 */ -+ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID), -+ .name = "Qualcomm QCA8081", -+ .flags = PHY_POLL_CABLE_TEST, -+ .probe = at803x_probe, -+ .config_intr = at803x_config_intr, -+ .handle_interrupt = at803x_handle_interrupt, -+ .get_tunable = at803x_get_tunable, -+ .set_tunable = at803x_set_tunable, -+ .set_wol = at803x_set_wol, -+ .get_wol = at803x_get_wol, -+ .get_features = qca808x_get_features, -+ .config_aneg = qca808x_config_aneg, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .read_status = qca808x_read_status, -+ .config_init = qca808x_config_init, -+ .soft_reset = qca808x_soft_reset, -+ .cable_test_start = qca808x_cable_test_start, -+ .cable_test_get_status = qca808x_cable_test_get_status, -+ .link_change_notify = qca808x_link_change_notify, -+ .led_brightness_set = qca808x_led_brightness_set, -+ .led_blink_set = qca808x_led_blink_set, -+ .led_hw_is_supported = qca808x_led_hw_is_supported, -+ .led_hw_control_set = qca808x_led_hw_control_set, -+ .led_hw_control_get = qca808x_led_hw_control_get, -+ .led_polarity_set = qca808x_led_polarity_set, -+}, }; -+ -+module_phy_driver(at803x_driver); -+ -+static struct mdio_device_id __maybe_unused atheros_tbl[] = { -+ { ATH8030_PHY_ID, AT8030_PHY_ID_MASK }, -+ { PHY_ID_MATCH_EXACT(ATH8031_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(mdio, atheros_tbl); diff --git a/target/linux/generic/backport-6.1/713-v6.9-02-net-phy-qcom-create-and-move-functions-to-shared-lib.patch b/target/linux/generic/backport-6.1/713-v6.9-02-net-phy-qcom-create-and-move-functions-to-shared-lib.patch deleted file mode 100644 index 7d0e1f4a285dea..00000000000000 --- a/target/linux/generic/backport-6.1/713-v6.9-02-net-phy-qcom-create-and-move-functions-to-shared-lib.patch +++ /dev/null @@ -1,243 +0,0 @@ -From 6fb760972c49490b03f3db2ad64cf30bdd28c54a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 Jan 2024 15:15:20 +0100 -Subject: [PATCH 2/5] net: phy: qcom: create and move functions to shared - library - -Create and move functions to shared library in preparation for qca83xx -PHY Family to be detached from at803x driver. - -Only the shared defines are moved to the shared qcom.h header. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240129141600.2592-3-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/qcom/Kconfig | 4 ++ - drivers/net/phy/qcom/Makefile | 1 + - drivers/net/phy/qcom/at803x.c | 69 +---------------------------- - drivers/net/phy/qcom/qcom-phy-lib.c | 53 ++++++++++++++++++++++ - drivers/net/phy/qcom/qcom.h | 34 ++++++++++++++ - 5 files changed, 94 insertions(+), 67 deletions(-) - create mode 100644 drivers/net/phy/qcom/qcom-phy-lib.c - create mode 100644 drivers/net/phy/qcom/qcom.h - ---- a/drivers/net/phy/qcom/Kconfig -+++ b/drivers/net/phy/qcom/Kconfig -@@ -1,6 +1,10 @@ - # SPDX-License-Identifier: GPL-2.0-only -+config QCOM_NET_PHYLIB -+ tristate -+ - config AT803X_PHY - tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs" -+ select QCOM_NET_PHYLIB - depends on REGULATOR - help - Currently supports the AR8030, AR8031, AR8033, AR8035 and internal ---- a/drivers/net/phy/qcom/Makefile -+++ b/drivers/net/phy/qcom/Makefile -@@ -1,2 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 -+obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-phy-lib.o - obj-$(CONFIG_AT803X_PHY) += at803x.o ---- a/drivers/net/phy/qcom/at803x.c -+++ b/drivers/net/phy/qcom/at803x.c -@@ -22,6 +22,8 @@ - #include - #include - -+#include "qcom.h" -+ - #define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10 - #define AT803X_SFC_ASSERT_CRS BIT(11) - #define AT803X_SFC_FORCE_LINK BIT(10) -@@ -84,9 +86,6 @@ - #define AT803X_REG_CHIP_CONFIG 0x1f - #define AT803X_BT_BX_REG_SEL 0x8000 - --#define AT803X_DEBUG_ADDR 0x1D --#define AT803X_DEBUG_DATA 0x1E -- - #define AT803X_MODE_CFG_MASK 0x0F - #define AT803X_MODE_CFG_BASET_RGMII 0x00 - #define AT803X_MODE_CFG_BASET_SGMII 0x01 -@@ -103,19 +102,6 @@ - #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/ - #define AT803X_PSSR_MR_AN_COMPLETE 0x0200 - --#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00 --#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2) --#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2) --#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) -- --#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05 --#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) -- --#define AT803X_DEBUG_REG_HIB_CTRL 0x0b --#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10) --#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13) --#define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15) -- - #define AT803X_DEBUG_REG_3C 0x3C - - #define AT803X_DEBUG_REG_GREEN 0x3D -@@ -393,18 +379,6 @@ MODULE_DESCRIPTION("Qualcomm Atheros AR8 - MODULE_AUTHOR("Matus Ujhelyi"); - MODULE_LICENSE("GPL"); - --enum stat_access_type { -- PHY, -- MMD --}; -- --struct at803x_hw_stat { -- const char *string; -- u8 reg; -- u32 mask; -- enum stat_access_type access_type; --}; -- - static struct at803x_hw_stat qca83xx_hw_stats[] = { - { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY}, - { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY}, -@@ -439,45 +413,6 @@ struct at803x_context { - u16 led_control; - }; - --static int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data) --{ -- int ret; -- -- ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); -- if (ret < 0) -- return ret; -- -- return phy_write(phydev, AT803X_DEBUG_DATA, data); --} -- --static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg) --{ -- int ret; -- -- ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); -- if (ret < 0) -- return ret; -- -- return phy_read(phydev, AT803X_DEBUG_DATA); --} -- --static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, -- u16 clear, u16 set) --{ -- u16 val; -- int ret; -- -- ret = at803x_debug_reg_read(phydev, reg); -- if (ret < 0) -- return ret; -- -- val = ret & 0xffff; -- val &= ~clear; -- val |= set; -- -- return phy_write(phydev, AT803X_DEBUG_DATA, val); --} -- - static int at803x_write_page(struct phy_device *phydev, int page) - { - int mask; ---- /dev/null -+++ b/drivers/net/phy/qcom/qcom-phy-lib.c -@@ -0,0 +1,53 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+ -+#include "qcom.h" -+ -+MODULE_DESCRIPTION("Qualcomm PHY driver Common Functions"); -+MODULE_AUTHOR("Matus Ujhelyi"); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_LICENSE("GPL"); -+ -+int at803x_debug_reg_read(struct phy_device *phydev, u16 reg) -+{ -+ int ret; -+ -+ ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); -+ if (ret < 0) -+ return ret; -+ -+ return phy_read(phydev, AT803X_DEBUG_DATA); -+} -+EXPORT_SYMBOL_GPL(at803x_debug_reg_read); -+ -+int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, -+ u16 clear, u16 set) -+{ -+ u16 val; -+ int ret; -+ -+ ret = at803x_debug_reg_read(phydev, reg); -+ if (ret < 0) -+ return ret; -+ -+ val = ret & 0xffff; -+ val &= ~clear; -+ val |= set; -+ -+ return phy_write(phydev, AT803X_DEBUG_DATA, val); -+} -+EXPORT_SYMBOL_GPL(at803x_debug_reg_mask); -+ -+int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data) -+{ -+ int ret; -+ -+ ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); -+ if (ret < 0) -+ return ret; -+ -+ return phy_write(phydev, AT803X_DEBUG_DATA, data); -+} -+EXPORT_SYMBOL_GPL(at803x_debug_reg_write); ---- /dev/null -+++ b/drivers/net/phy/qcom/qcom.h -@@ -0,0 +1,34 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+#define AT803X_DEBUG_ADDR 0x1D -+#define AT803X_DEBUG_DATA 0x1E -+ -+#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00 -+#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2) -+#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2) -+#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) -+ -+#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05 -+#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) -+ -+#define AT803X_DEBUG_REG_HIB_CTRL 0x0b -+#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10) -+#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13) -+#define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15) -+ -+enum stat_access_type { -+ PHY, -+ MMD -+}; -+ -+struct at803x_hw_stat { -+ const char *string; -+ u8 reg; -+ u32 mask; -+ enum stat_access_type access_type; -+}; -+ -+int at803x_debug_reg_read(struct phy_device *phydev, u16 reg); -+int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, -+ u16 clear, u16 set); -+int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data); diff --git a/target/linux/generic/backport-6.1/713-v6.9-03-net-phy-qcom-deatch-qca83xx-PHY-driver-from-at803x.patch b/target/linux/generic/backport-6.1/713-v6.9-03-net-phy-qcom-deatch-qca83xx-PHY-driver-from-at803x.patch deleted file mode 100644 index 6ac09dcb9ab922..00000000000000 --- a/target/linux/generic/backport-6.1/713-v6.9-03-net-phy-qcom-deatch-qca83xx-PHY-driver-from-at803x.patch +++ /dev/null @@ -1,638 +0,0 @@ -From 2e45d404d99d43bb7127b74b5dea8818df64996c Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 Jan 2024 15:15:21 +0100 -Subject: [PATCH 3/5] net: phy: qcom: deatch qca83xx PHY driver from at803x - -Deatch qca83xx PHY driver from at803x. - -The QCA83xx PHYs implement specific function and doesn't use generic -at803x so it can be detached from the driver and moved to a dedicated -one. - -Probe function and priv struct is reimplemented to allocate and use -only the qca83xx specific data. Unused data from at803x PHY driver -are dropped from at803x priv struct. - -This is to make slimmer PHY drivers instead of including lots of bloat -that would never be used in specific SoC. - -A new Kconfig flag QCA83XX_PHY is introduced to compile the new -introduced PHY driver. - -As the Kconfig name starts with Qualcomm the same order is kept. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240129141600.2592-4-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/qcom/Kconfig | 11 +- - drivers/net/phy/qcom/Makefile | 1 + - drivers/net/phy/qcom/at803x.c | 235 ---------------------------- - drivers/net/phy/qcom/qca83xx.c | 275 +++++++++++++++++++++++++++++++++ - 4 files changed, 284 insertions(+), 238 deletions(-) - create mode 100644 drivers/net/phy/qcom/qca83xx.c - ---- a/drivers/net/phy/qcom/Kconfig -+++ b/drivers/net/phy/qcom/Kconfig -@@ -3,9 +3,14 @@ config QCOM_NET_PHYLIB - tristate - - config AT803X_PHY -- tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs" -+ tristate "Qualcomm Atheros AR803X PHYs" - select QCOM_NET_PHYLIB - depends on REGULATOR - help -- Currently supports the AR8030, AR8031, AR8033, AR8035 and internal -- QCA8337(Internal qca8k PHY) model -+ Currently supports the AR8030, AR8031, AR8033, AR8035 model -+ -+config QCA83XX_PHY -+ tristate "Qualcomm Atheros QCA833x PHYs" -+ select QCOM_NET_PHYLIB -+ help -+ Currently supports the internal QCA8337(Internal qca8k PHY) model ---- a/drivers/net/phy/qcom/Makefile -+++ b/drivers/net/phy/qcom/Makefile -@@ -1,3 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 - obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-phy-lib.o - obj-$(CONFIG_AT803X_PHY) += at803x.o -+obj-$(CONFIG_QCA83XX_PHY) += qca83xx.o ---- a/drivers/net/phy/qcom/at803x.c -+++ b/drivers/net/phy/qcom/at803x.c -@@ -102,17 +102,10 @@ - #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/ - #define AT803X_PSSR_MR_AN_COMPLETE 0x0200 - --#define AT803X_DEBUG_REG_3C 0x3C -- --#define AT803X_DEBUG_REG_GREEN 0x3D --#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6) -- - #define AT803X_DEBUG_REG_1F 0x1F - #define AT803X_DEBUG_PLL_ON BIT(2) - #define AT803X_DEBUG_RGMII_1V8 BIT(3) - --#define MDIO_AZ_DEBUG 0x800D -- - /* AT803x supports either the XTAL input pad, an internal PLL or the - * DSP as clock reference for the clock output pad. The XTAL reference - * is only used for 25 MHz output, all other frequencies need the PLL. -@@ -163,13 +156,7 @@ - - #define QCA8081_PHY_ID 0x004dd101 - --#define QCA8327_A_PHY_ID 0x004dd033 --#define QCA8327_B_PHY_ID 0x004dd034 --#define QCA8337_PHY_ID 0x004dd036 - #define QCA9561_PHY_ID 0x004dd042 --#define QCA8K_PHY_ID_MASK 0xffffffff -- --#define QCA8K_DEVFLAGS_REVISION_MASK GENMASK(2, 0) - - #define AT803X_PAGE_FIBER 0 - #define AT803X_PAGE_COPPER 1 -@@ -379,12 +366,6 @@ MODULE_DESCRIPTION("Qualcomm Atheros AR8 - MODULE_AUTHOR("Matus Ujhelyi"); - MODULE_LICENSE("GPL"); - --static struct at803x_hw_stat qca83xx_hw_stats[] = { -- { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY}, -- { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY}, -- { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD}, --}; -- - struct at803x_ss_mask { - u16 speed_mask; - u8 speed_shift; -@@ -400,7 +381,6 @@ struct at803x_priv { - bool is_1000basex; - struct regulator_dev *vddio_rdev; - struct regulator_dev *vddh_rdev; -- u64 stats[ARRAY_SIZE(qca83xx_hw_stats)]; - int led_polarity_mode; - }; - -@@ -564,53 +544,6 @@ static void at803x_get_wol(struct phy_de - wol->wolopts |= WAKE_MAGIC; - } - --static int qca83xx_get_sset_count(struct phy_device *phydev) --{ -- return ARRAY_SIZE(qca83xx_hw_stats); --} -- --static void qca83xx_get_strings(struct phy_device *phydev, u8 *data) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) { -- strscpy(data + i * ETH_GSTRING_LEN, -- qca83xx_hw_stats[i].string, ETH_GSTRING_LEN); -- } --} -- --static u64 qca83xx_get_stat(struct phy_device *phydev, int i) --{ -- struct at803x_hw_stat stat = qca83xx_hw_stats[i]; -- struct at803x_priv *priv = phydev->priv; -- int val; -- u64 ret; -- -- if (stat.access_type == MMD) -- val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg); -- else -- val = phy_read(phydev, stat.reg); -- -- if (val < 0) { -- ret = U64_MAX; -- } else { -- val = val & stat.mask; -- priv->stats[i] += val; -- ret = priv->stats[i]; -- } -- -- return ret; --} -- --static void qca83xx_get_stats(struct phy_device *phydev, -- struct ethtool_stats *stats, u64 *data) --{ -- int i; -- -- for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) -- data[i] = qca83xx_get_stat(phydev, i); --} -- - static int at803x_suspend(struct phy_device *phydev) - { - int value; -@@ -1707,124 +1640,6 @@ static int at8035_probe(struct phy_devic - return at8035_parse_dt(phydev); - } - --static int qca83xx_config_init(struct phy_device *phydev) --{ -- u8 switch_revision; -- -- switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK; -- -- switch (switch_revision) { -- case 1: -- /* For 100M waveform */ -- at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea); -- /* Turn on Gigabit clock */ -- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0); -- break; -- -- case 2: -- phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0); -- fallthrough; -- case 4: -- phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f); -- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860); -- at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46); -- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000); -- break; -- } -- -- /* Following original QCA sourcecode set port to prefer master */ -- phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER); -- -- return 0; --} -- --static int qca8327_config_init(struct phy_device *phydev) --{ -- /* QCA8327 require DAC amplitude adjustment for 100m set to +6%. -- * Disable on init and enable only with 100m speed following -- * qca original source code. -- */ -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -- QCA8327_DEBUG_MANU_CTRL_EN, 0); -- -- return qca83xx_config_init(phydev); --} -- --static void qca83xx_link_change_notify(struct phy_device *phydev) --{ -- /* Set DAC Amplitude adjustment to +6% for 100m on link running */ -- if (phydev->state == PHY_RUNNING) { -- if (phydev->speed == SPEED_100) -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -- QCA8327_DEBUG_MANU_CTRL_EN, -- QCA8327_DEBUG_MANU_CTRL_EN); -- } else { -- /* Reset DAC Amplitude adjustment */ -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -- QCA8327_DEBUG_MANU_CTRL_EN, 0); -- } --} -- --static int qca83xx_resume(struct phy_device *phydev) --{ -- int ret, val; -- -- /* Skip reset if not suspended */ -- if (!phydev->suspended) -- return 0; -- -- /* Reinit the port, reset values set by suspend */ -- qca83xx_config_init(phydev); -- -- /* Reset the port on port resume */ -- phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); -- -- /* On resume from suspend the switch execute a reset and -- * restart auto-negotiation. Wait for reset to complete. -- */ -- ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET), -- 50000, 600000, true); -- if (ret) -- return ret; -- -- usleep_range(1000, 2000); -- -- return 0; --} -- --static int qca83xx_suspend(struct phy_device *phydev) --{ -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN, -- AT803X_DEBUG_GATE_CLK_IN1000, 0); -- -- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL, -- AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE | -- AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0); -- -- return 0; --} -- --static int qca8337_suspend(struct phy_device *phydev) --{ -- /* Only QCA8337 support actual suspend. */ -- genphy_suspend(phydev); -- -- return qca83xx_suspend(phydev); --} -- --static int qca8327_suspend(struct phy_device *phydev) --{ -- u16 mask = 0; -- -- /* QCA8327 cause port unreliability when phy suspend -- * is set. -- */ -- mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX); -- phy_modify(phydev, MII_BMCR, mask, 0); -- -- return qca83xx_suspend(phydev); --} -- - static int qca808x_phy_fast_retrain_config(struct phy_device *phydev) - { - int ret; -@@ -2599,53 +2414,6 @@ static struct phy_driver at803x_driver[] - .soft_reset = genphy_soft_reset, - .config_aneg = at803x_config_aneg, - }, { -- /* QCA8337 */ -- .phy_id = QCA8337_PHY_ID, -- .phy_id_mask = QCA8K_PHY_ID_MASK, -- .name = "Qualcomm Atheros 8337 internal PHY", -- /* PHY_GBIT_FEATURES */ -- .probe = at803x_probe, -- .flags = PHY_IS_INTERNAL, -- .config_init = qca83xx_config_init, -- .soft_reset = genphy_soft_reset, -- .get_sset_count = qca83xx_get_sset_count, -- .get_strings = qca83xx_get_strings, -- .get_stats = qca83xx_get_stats, -- .suspend = qca8337_suspend, -- .resume = qca83xx_resume, --}, { -- /* QCA8327-A from switch QCA8327-AL1A */ -- .phy_id = QCA8327_A_PHY_ID, -- .phy_id_mask = QCA8K_PHY_ID_MASK, -- .name = "Qualcomm Atheros 8327-A internal PHY", -- /* PHY_GBIT_FEATURES */ -- .link_change_notify = qca83xx_link_change_notify, -- .probe = at803x_probe, -- .flags = PHY_IS_INTERNAL, -- .config_init = qca8327_config_init, -- .soft_reset = genphy_soft_reset, -- .get_sset_count = qca83xx_get_sset_count, -- .get_strings = qca83xx_get_strings, -- .get_stats = qca83xx_get_stats, -- .suspend = qca8327_suspend, -- .resume = qca83xx_resume, --}, { -- /* QCA8327-B from switch QCA8327-BL1A */ -- .phy_id = QCA8327_B_PHY_ID, -- .phy_id_mask = QCA8K_PHY_ID_MASK, -- .name = "Qualcomm Atheros 8327-B internal PHY", -- /* PHY_GBIT_FEATURES */ -- .link_change_notify = qca83xx_link_change_notify, -- .probe = at803x_probe, -- .flags = PHY_IS_INTERNAL, -- .config_init = qca8327_config_init, -- .soft_reset = genphy_soft_reset, -- .get_sset_count = qca83xx_get_sset_count, -- .get_strings = qca83xx_get_strings, -- .get_stats = qca83xx_get_stats, -- .suspend = qca8327_suspend, -- .resume = qca83xx_resume, --}, { - /* Qualcomm QCA8081 */ - PHY_ID_MATCH_EXACT(QCA8081_PHY_ID), - .name = "Qualcomm QCA8081", -@@ -2683,9 +2451,6 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) }, - { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) }, - { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) }, - { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) }, - { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) }, - { } ---- /dev/null -+++ b/drivers/net/phy/qcom/qca83xx.c -@@ -0,0 +1,275 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+ -+#include -+#include -+ -+#include "qcom.h" -+ -+#define AT803X_DEBUG_REG_3C 0x3C -+ -+#define AT803X_DEBUG_REG_GREEN 0x3D -+#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6) -+ -+#define MDIO_AZ_DEBUG 0x800D -+ -+#define QCA8327_A_PHY_ID 0x004dd033 -+#define QCA8327_B_PHY_ID 0x004dd034 -+#define QCA8337_PHY_ID 0x004dd036 -+#define QCA8K_PHY_ID_MASK 0xffffffff -+ -+#define QCA8K_DEVFLAGS_REVISION_MASK GENMASK(2, 0) -+ -+static struct at803x_hw_stat qca83xx_hw_stats[] = { -+ { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY}, -+ { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY}, -+ { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD}, -+}; -+ -+struct qca83xx_priv { -+ u64 stats[ARRAY_SIZE(qca83xx_hw_stats)]; -+}; -+ -+MODULE_DESCRIPTION("Qualcomm Atheros QCA83XX PHY driver"); -+MODULE_AUTHOR("Matus Ujhelyi"); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_LICENSE("GPL"); -+ -+static int qca83xx_get_sset_count(struct phy_device *phydev) -+{ -+ return ARRAY_SIZE(qca83xx_hw_stats); -+} -+ -+static void qca83xx_get_strings(struct phy_device *phydev, u8 *data) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) { -+ strscpy(data + i * ETH_GSTRING_LEN, -+ qca83xx_hw_stats[i].string, ETH_GSTRING_LEN); -+ } -+} -+ -+static u64 qca83xx_get_stat(struct phy_device *phydev, int i) -+{ -+ struct at803x_hw_stat stat = qca83xx_hw_stats[i]; -+ struct qca83xx_priv *priv = phydev->priv; -+ int val; -+ u64 ret; -+ -+ if (stat.access_type == MMD) -+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg); -+ else -+ val = phy_read(phydev, stat.reg); -+ -+ if (val < 0) { -+ ret = U64_MAX; -+ } else { -+ val = val & stat.mask; -+ priv->stats[i] += val; -+ ret = priv->stats[i]; -+ } -+ -+ return ret; -+} -+ -+static void qca83xx_get_stats(struct phy_device *phydev, -+ struct ethtool_stats *stats, u64 *data) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(qca83xx_hw_stats); i++) -+ data[i] = qca83xx_get_stat(phydev, i); -+} -+ -+static int qca83xx_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct qca83xx_priv *priv; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ phydev->priv = priv; -+ -+ return 0; -+} -+ -+static int qca83xx_config_init(struct phy_device *phydev) -+{ -+ u8 switch_revision; -+ -+ switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK; -+ -+ switch (switch_revision) { -+ case 1: -+ /* For 100M waveform */ -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea); -+ /* Turn on Gigabit clock */ -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0); -+ break; -+ -+ case 2: -+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0); -+ fallthrough; -+ case 4: -+ phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f); -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860); -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46); -+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000); -+ break; -+ } -+ -+ /* Following original QCA sourcecode set port to prefer master */ -+ phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER); -+ -+ return 0; -+} -+ -+static int qca8327_config_init(struct phy_device *phydev) -+{ -+ /* QCA8327 require DAC amplitude adjustment for 100m set to +6%. -+ * Disable on init and enable only with 100m speed following -+ * qca original source code. -+ */ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -+ QCA8327_DEBUG_MANU_CTRL_EN, 0); -+ -+ return qca83xx_config_init(phydev); -+} -+ -+static void qca83xx_link_change_notify(struct phy_device *phydev) -+{ -+ /* Set DAC Amplitude adjustment to +6% for 100m on link running */ -+ if (phydev->state == PHY_RUNNING) { -+ if (phydev->speed == SPEED_100) -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -+ QCA8327_DEBUG_MANU_CTRL_EN, -+ QCA8327_DEBUG_MANU_CTRL_EN); -+ } else { -+ /* Reset DAC Amplitude adjustment */ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, -+ QCA8327_DEBUG_MANU_CTRL_EN, 0); -+ } -+} -+ -+static int qca83xx_resume(struct phy_device *phydev) -+{ -+ int ret, val; -+ -+ /* Skip reset if not suspended */ -+ if (!phydev->suspended) -+ return 0; -+ -+ /* Reinit the port, reset values set by suspend */ -+ qca83xx_config_init(phydev); -+ -+ /* Reset the port on port resume */ -+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); -+ -+ /* On resume from suspend the switch execute a reset and -+ * restart auto-negotiation. Wait for reset to complete. -+ */ -+ ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET), -+ 50000, 600000, true); -+ if (ret) -+ return ret; -+ -+ usleep_range(1000, 2000); -+ -+ return 0; -+} -+ -+static int qca83xx_suspend(struct phy_device *phydev) -+{ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN, -+ AT803X_DEBUG_GATE_CLK_IN1000, 0); -+ -+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL, -+ AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE | -+ AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0); -+ -+ return 0; -+} -+ -+static int qca8337_suspend(struct phy_device *phydev) -+{ -+ /* Only QCA8337 support actual suspend. */ -+ genphy_suspend(phydev); -+ -+ return qca83xx_suspend(phydev); -+} -+ -+static int qca8327_suspend(struct phy_device *phydev) -+{ -+ u16 mask = 0; -+ -+ /* QCA8327 cause port unreliability when phy suspend -+ * is set. -+ */ -+ mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX); -+ phy_modify(phydev, MII_BMCR, mask, 0); -+ -+ return qca83xx_suspend(phydev); -+} -+ -+static struct phy_driver qca83xx_driver[] = { -+{ -+ /* QCA8337 */ -+ .phy_id = QCA8337_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "Qualcomm Atheros 8337 internal PHY", -+ /* PHY_GBIT_FEATURES */ -+ .probe = qca83xx_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca83xx_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = qca83xx_get_sset_count, -+ .get_strings = qca83xx_get_strings, -+ .get_stats = qca83xx_get_stats, -+ .suspend = qca8337_suspend, -+ .resume = qca83xx_resume, -+}, { -+ /* QCA8327-A from switch QCA8327-AL1A */ -+ .phy_id = QCA8327_A_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "Qualcomm Atheros 8327-A internal PHY", -+ /* PHY_GBIT_FEATURES */ -+ .link_change_notify = qca83xx_link_change_notify, -+ .probe = qca83xx_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca8327_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = qca83xx_get_sset_count, -+ .get_strings = qca83xx_get_strings, -+ .get_stats = qca83xx_get_stats, -+ .suspend = qca8327_suspend, -+ .resume = qca83xx_resume, -+}, { -+ /* QCA8327-B from switch QCA8327-BL1A */ -+ .phy_id = QCA8327_B_PHY_ID, -+ .phy_id_mask = QCA8K_PHY_ID_MASK, -+ .name = "Qualcomm Atheros 8327-B internal PHY", -+ /* PHY_GBIT_FEATURES */ -+ .link_change_notify = qca83xx_link_change_notify, -+ .probe = qca83xx_probe, -+ .flags = PHY_IS_INTERNAL, -+ .config_init = qca8327_config_init, -+ .soft_reset = genphy_soft_reset, -+ .get_sset_count = qca83xx_get_sset_count, -+ .get_strings = qca83xx_get_strings, -+ .get_stats = qca83xx_get_stats, -+ .suspend = qca8327_suspend, -+ .resume = qca83xx_resume, -+}, }; -+ -+module_phy_driver(qca83xx_driver); -+ -+static struct mdio_device_id __maybe_unused qca83xx_tbl[] = { -+ { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) }, -+ { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(mdio, qca83xx_tbl); diff --git a/target/linux/generic/backport-6.1/713-v6.9-04-net-phy-qcom-move-additional-functions-to-shared-lib.patch b/target/linux/generic/backport-6.1/713-v6.9-04-net-phy-qcom-move-additional-functions-to-shared-lib.patch deleted file mode 100644 index 9c43ad13b4434f..00000000000000 --- a/target/linux/generic/backport-6.1/713-v6.9-04-net-phy-qcom-move-additional-functions-to-shared-lib.patch +++ /dev/null @@ -1,1014 +0,0 @@ -From 249d2b80e4db0e38503ed0ec2af6c7401bc099b9 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 Jan 2024 15:15:22 +0100 -Subject: [PATCH 4/5] net: phy: qcom: move additional functions to shared - library - -Move additional functions to shared library in preparation for qca808x -PHY Family to be detached from at803x driver. - -Only the shared defines are moved to the shared qcom.h header. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240129141600.2592-5-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/qcom/at803x.c | 426 +--------------------------- - drivers/net/phy/qcom/qcom-phy-lib.c | 376 ++++++++++++++++++++++++ - drivers/net/phy/qcom/qcom.h | 86 ++++++ - 3 files changed, 463 insertions(+), 425 deletions(-) - ---- a/drivers/net/phy/qcom/at803x.c -+++ b/drivers/net/phy/qcom/at803x.c -@@ -24,65 +24,11 @@ - - #include "qcom.h" - --#define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10 --#define AT803X_SFC_ASSERT_CRS BIT(11) --#define AT803X_SFC_FORCE_LINK BIT(10) --#define AT803X_SFC_MDI_CROSSOVER_MODE_M GENMASK(6, 5) --#define AT803X_SFC_AUTOMATIC_CROSSOVER 0x3 --#define AT803X_SFC_MANUAL_MDIX 0x1 --#define AT803X_SFC_MANUAL_MDI 0x0 --#define AT803X_SFC_SQE_TEST BIT(2) --#define AT803X_SFC_POLARITY_REVERSAL BIT(1) --#define AT803X_SFC_DISABLE_JABBER BIT(0) -- --#define AT803X_SPECIFIC_STATUS 0x11 --#define AT803X_SS_SPEED_MASK GENMASK(15, 14) --#define AT803X_SS_SPEED_1000 2 --#define AT803X_SS_SPEED_100 1 --#define AT803X_SS_SPEED_10 0 --#define AT803X_SS_DUPLEX BIT(13) --#define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11) --#define AT803X_SS_MDIX BIT(6) -- --#define QCA808X_SS_SPEED_MASK GENMASK(9, 7) --#define QCA808X_SS_SPEED_2500 4 -- --#define AT803X_INTR_ENABLE 0x12 --#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15) --#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14) --#define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13) --#define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12) --#define AT803X_INTR_ENABLE_LINK_FAIL BIT(11) --#define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10) --#define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8) --#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7) --#define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5) --#define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1) --#define AT803X_INTR_ENABLE_WOL BIT(0) -- --#define AT803X_INTR_STATUS 0x13 -- --#define AT803X_SMART_SPEED 0x14 --#define AT803X_SMART_SPEED_ENABLE BIT(5) --#define AT803X_SMART_SPEED_RETRY_LIMIT_MASK GENMASK(4, 2) --#define AT803X_SMART_SPEED_BYPASS_TIMER BIT(1) --#define AT803X_CDT 0x16 --#define AT803X_CDT_MDI_PAIR_MASK GENMASK(9, 8) --#define AT803X_CDT_ENABLE_TEST BIT(0) --#define AT803X_CDT_STATUS 0x1c --#define AT803X_CDT_STATUS_STAT_NORMAL 0 --#define AT803X_CDT_STATUS_STAT_SHORT 1 --#define AT803X_CDT_STATUS_STAT_OPEN 2 --#define AT803X_CDT_STATUS_STAT_FAIL 3 --#define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8) --#define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0) - #define AT803X_LED_CONTROL 0x18 - - #define AT803X_PHY_MMD3_WOL_CTRL 0x8012 - #define AT803X_WOL_EN BIT(5) --#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C --#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B --#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A -+ - #define AT803X_REG_CHIP_CONFIG 0x1f - #define AT803X_BT_BX_REG_SEL 0x8000 - -@@ -138,10 +84,6 @@ - #define AT803X_CLK_OUT_STRENGTH_HALF 1 - #define AT803X_CLK_OUT_STRENGTH_QUARTER 2 - --#define AT803X_DEFAULT_DOWNSHIFT 5 --#define AT803X_MIN_DOWNSHIFT 2 --#define AT803X_MAX_DOWNSHIFT 9 -- - #define AT803X_MMD3_SMARTEEE_CTL1 0x805b - #define AT803X_MMD3_SMARTEEE_CTL2 0x805c - #define AT803X_MMD3_SMARTEEE_CTL3 0x805d -@@ -366,11 +308,6 @@ MODULE_DESCRIPTION("Qualcomm Atheros AR8 - MODULE_AUTHOR("Matus Ujhelyi"); - MODULE_LICENSE("GPL"); - --struct at803x_ss_mask { -- u16 speed_mask; -- u8 speed_shift; --}; -- - struct at803x_priv { - int flags; - u16 clk_25m_reg; -@@ -470,80 +407,6 @@ static void at803x_context_restore(struc - phy_write(phydev, AT803X_LED_CONTROL, context->led_control); - } - --static int at803x_set_wol(struct phy_device *phydev, -- struct ethtool_wolinfo *wol) --{ -- int ret, irq_enabled; -- -- if (wol->wolopts & WAKE_MAGIC) { -- struct net_device *ndev = phydev->attached_dev; -- const u8 *mac; -- unsigned int i; -- static const unsigned int offsets[] = { -- AT803X_LOC_MAC_ADDR_32_47_OFFSET, -- AT803X_LOC_MAC_ADDR_16_31_OFFSET, -- AT803X_LOC_MAC_ADDR_0_15_OFFSET, -- }; -- -- if (!ndev) -- return -ENODEV; -- -- mac = (const u8 *)ndev->dev_addr; -- -- if (!is_valid_ether_addr(mac)) -- return -EINVAL; -- -- for (i = 0; i < 3; i++) -- phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i], -- mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); -- -- /* Enable WOL interrupt */ -- ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL); -- if (ret) -- return ret; -- } else { -- /* Disable WOL interrupt */ -- ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0); -- if (ret) -- return ret; -- } -- -- /* Clear WOL status */ -- ret = phy_read(phydev, AT803X_INTR_STATUS); -- if (ret < 0) -- return ret; -- -- /* Check if there are other interrupts except for WOL triggered when PHY is -- * in interrupt mode, only the interrupts enabled by AT803X_INTR_ENABLE can -- * be passed up to the interrupt PIN. -- */ -- irq_enabled = phy_read(phydev, AT803X_INTR_ENABLE); -- if (irq_enabled < 0) -- return irq_enabled; -- -- irq_enabled &= ~AT803X_INTR_ENABLE_WOL; -- if (ret & irq_enabled && !phy_polling_mode(phydev)) -- phy_trigger_machine(phydev); -- -- return 0; --} -- --static void at803x_get_wol(struct phy_device *phydev, -- struct ethtool_wolinfo *wol) --{ -- int value; -- -- wol->supported = WAKE_MAGIC; -- wol->wolopts = 0; -- -- value = phy_read(phydev, AT803X_INTR_ENABLE); -- if (value < 0) -- return; -- -- if (value & AT803X_INTR_ENABLE_WOL) -- wol->wolopts |= WAKE_MAGIC; --} -- - static int at803x_suspend(struct phy_device *phydev) - { - int value; -@@ -816,73 +679,6 @@ static int at803x_config_init(struct phy - return phy_modify(phydev, MII_ADVERTISE, MDIO_AN_CTRL1_XNP, 0); - } - --static int at803x_ack_interrupt(struct phy_device *phydev) --{ -- int err; -- -- err = phy_read(phydev, AT803X_INTR_STATUS); -- -- return (err < 0) ? err : 0; --} -- --static int at803x_config_intr(struct phy_device *phydev) --{ -- int err; -- int value; -- -- value = phy_read(phydev, AT803X_INTR_ENABLE); -- -- if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { -- /* Clear any pending interrupts */ -- err = at803x_ack_interrupt(phydev); -- if (err) -- return err; -- -- value |= AT803X_INTR_ENABLE_AUTONEG_ERR; -- value |= AT803X_INTR_ENABLE_SPEED_CHANGED; -- value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED; -- value |= AT803X_INTR_ENABLE_LINK_FAIL; -- value |= AT803X_INTR_ENABLE_LINK_SUCCESS; -- -- err = phy_write(phydev, AT803X_INTR_ENABLE, value); -- } else { -- err = phy_write(phydev, AT803X_INTR_ENABLE, 0); -- if (err) -- return err; -- -- /* Clear any pending interrupts */ -- err = at803x_ack_interrupt(phydev); -- } -- -- return err; --} -- --static irqreturn_t at803x_handle_interrupt(struct phy_device *phydev) --{ -- int irq_status, int_enabled; -- -- irq_status = phy_read(phydev, AT803X_INTR_STATUS); -- if (irq_status < 0) { -- phy_error(phydev); -- return IRQ_NONE; -- } -- -- /* Read the current enabled interrupts */ -- int_enabled = phy_read(phydev, AT803X_INTR_ENABLE); -- if (int_enabled < 0) { -- phy_error(phydev); -- return IRQ_NONE; -- } -- -- /* See if this was one of our enabled interrupts */ -- if (!(irq_status & int_enabled)) -- return IRQ_NONE; -- -- phy_trigger_machine(phydev); -- -- return IRQ_HANDLED; --} -- - static void at803x_link_change_notify(struct phy_device *phydev) - { - /* -@@ -908,69 +704,6 @@ static void at803x_link_change_notify(st - } - } - --static int at803x_read_specific_status(struct phy_device *phydev, -- struct at803x_ss_mask ss_mask) --{ -- int ss; -- -- /* Read the AT8035 PHY-Specific Status register, which indicates the -- * speed and duplex that the PHY is actually using, irrespective of -- * whether we are in autoneg mode or not. -- */ -- ss = phy_read(phydev, AT803X_SPECIFIC_STATUS); -- if (ss < 0) -- return ss; -- -- if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) { -- int sfc, speed; -- -- sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL); -- if (sfc < 0) -- return sfc; -- -- speed = ss & ss_mask.speed_mask; -- speed >>= ss_mask.speed_shift; -- -- switch (speed) { -- case AT803X_SS_SPEED_10: -- phydev->speed = SPEED_10; -- break; -- case AT803X_SS_SPEED_100: -- phydev->speed = SPEED_100; -- break; -- case AT803X_SS_SPEED_1000: -- phydev->speed = SPEED_1000; -- break; -- case QCA808X_SS_SPEED_2500: -- phydev->speed = SPEED_2500; -- break; -- } -- if (ss & AT803X_SS_DUPLEX) -- phydev->duplex = DUPLEX_FULL; -- else -- phydev->duplex = DUPLEX_HALF; -- -- if (ss & AT803X_SS_MDIX) -- phydev->mdix = ETH_TP_MDI_X; -- else -- phydev->mdix = ETH_TP_MDI; -- -- switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) { -- case AT803X_SFC_MANUAL_MDI: -- phydev->mdix_ctrl = ETH_TP_MDI; -- break; -- case AT803X_SFC_MANUAL_MDIX: -- phydev->mdix_ctrl = ETH_TP_MDI_X; -- break; -- case AT803X_SFC_AUTOMATIC_CROSSOVER: -- phydev->mdix_ctrl = ETH_TP_MDI_AUTO; -- break; -- } -- } -- -- return 0; --} -- - static int at803x_read_status(struct phy_device *phydev) - { - struct at803x_ss_mask ss_mask = { 0 }; -@@ -1006,50 +739,6 @@ static int at803x_read_status(struct phy - return 0; - } - --static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl) --{ -- u16 val; -- -- switch (ctrl) { -- case ETH_TP_MDI: -- val = AT803X_SFC_MANUAL_MDI; -- break; -- case ETH_TP_MDI_X: -- val = AT803X_SFC_MANUAL_MDIX; -- break; -- case ETH_TP_MDI_AUTO: -- val = AT803X_SFC_AUTOMATIC_CROSSOVER; -- break; -- default: -- return 0; -- } -- -- return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL, -- AT803X_SFC_MDI_CROSSOVER_MODE_M, -- FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val)); --} -- --static int at803x_prepare_config_aneg(struct phy_device *phydev) --{ -- int ret; -- -- ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); -- if (ret < 0) -- return ret; -- -- /* Changes of the midx bits are disruptive to the normal operation; -- * therefore any changes to these registers must be followed by a -- * software reset to take effect. -- */ -- if (ret == 1) { -- ret = genphy_soft_reset(phydev); -- if (ret < 0) -- return ret; -- } -- -- return 0; --} -- - static int at803x_config_aneg(struct phy_device *phydev) - { - struct at803x_priv *priv = phydev->priv; -@@ -1065,80 +754,6 @@ static int at803x_config_aneg(struct phy - return genphy_config_aneg(phydev); - } - --static int at803x_get_downshift(struct phy_device *phydev, u8 *d) --{ -- int val; -- -- val = phy_read(phydev, AT803X_SMART_SPEED); -- if (val < 0) -- return val; -- -- if (val & AT803X_SMART_SPEED_ENABLE) -- *d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2; -- else -- *d = DOWNSHIFT_DEV_DISABLE; -- -- return 0; --} -- --static int at803x_set_downshift(struct phy_device *phydev, u8 cnt) --{ -- u16 mask, set; -- int ret; -- -- switch (cnt) { -- case DOWNSHIFT_DEV_DEFAULT_COUNT: -- cnt = AT803X_DEFAULT_DOWNSHIFT; -- fallthrough; -- case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT: -- set = AT803X_SMART_SPEED_ENABLE | -- AT803X_SMART_SPEED_BYPASS_TIMER | -- FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2); -- mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK; -- break; -- case DOWNSHIFT_DEV_DISABLE: -- set = 0; -- mask = AT803X_SMART_SPEED_ENABLE | -- AT803X_SMART_SPEED_BYPASS_TIMER; -- break; -- default: -- return -EINVAL; -- } -- -- ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set); -- -- /* After changing the smart speed settings, we need to perform a -- * software reset, use phy_init_hw() to make sure we set the -- * reapply any values which might got lost during software reset. -- */ -- if (ret == 1) -- ret = phy_init_hw(phydev); -- -- return ret; --} -- --static int at803x_get_tunable(struct phy_device *phydev, -- struct ethtool_tunable *tuna, void *data) --{ -- switch (tuna->id) { -- case ETHTOOL_PHY_DOWNSHIFT: -- return at803x_get_downshift(phydev, data); -- default: -- return -EOPNOTSUPP; -- } --} -- --static int at803x_set_tunable(struct phy_device *phydev, -- struct ethtool_tunable *tuna, const void *data) --{ -- switch (tuna->id) { -- case ETHTOOL_PHY_DOWNSHIFT: -- return at803x_set_downshift(phydev, *(const u8 *)data); -- default: -- return -EOPNOTSUPP; -- } --} -- - static int at803x_cable_test_result_trans(u16 status) - { - switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) { -@@ -1170,45 +785,6 @@ static bool at803x_cdt_fault_length_vali - return false; - } - --static int at803x_cdt_fault_length(int dt) --{ -- /* According to the datasheet the distance to the fault is -- * DELTA_TIME * 0.824 meters. -- * -- * The author suspect the correct formula is: -- * -- * fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2 -- * -- * where c is the speed of light, VF is the velocity factor of -- * the twisted pair cable, 125MHz the counter frequency and -- * we need to divide by 2 because the hardware will measure the -- * round trip time to the fault and back to the PHY. -- * -- * With a VF of 0.69 we get the factor 0.824 mentioned in the -- * datasheet. -- */ -- return (dt * 824) / 10; --} -- --static int at803x_cdt_start(struct phy_device *phydev, -- u32 cdt_start) --{ -- return phy_write(phydev, AT803X_CDT, cdt_start); --} -- --static int at803x_cdt_wait_for_completion(struct phy_device *phydev, -- u32 cdt_en) --{ -- int val, ret; -- -- /* One test run takes about 25ms */ -- ret = phy_read_poll_timeout(phydev, AT803X_CDT, val, -- !(val & cdt_en), -- 30000, 100000, true); -- -- return ret < 0 ? ret : 0; --} -- - static int at803x_cable_test_one_pair(struct phy_device *phydev, int pair) - { - static const int ethtool_pair[] = { ---- a/drivers/net/phy/qcom/qcom-phy-lib.c -+++ b/drivers/net/phy/qcom/qcom-phy-lib.c -@@ -3,6 +3,9 @@ - #include - #include - -+#include -+#include -+ - #include "qcom.h" - - MODULE_DESCRIPTION("Qualcomm PHY driver Common Functions"); -@@ -51,3 +54,376 @@ int at803x_debug_reg_write(struct phy_de - return phy_write(phydev, AT803X_DEBUG_DATA, data); - } - EXPORT_SYMBOL_GPL(at803x_debug_reg_write); -+ -+int at803x_set_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol) -+{ -+ int ret, irq_enabled; -+ -+ if (wol->wolopts & WAKE_MAGIC) { -+ struct net_device *ndev = phydev->attached_dev; -+ const u8 *mac; -+ unsigned int i; -+ static const unsigned int offsets[] = { -+ AT803X_LOC_MAC_ADDR_32_47_OFFSET, -+ AT803X_LOC_MAC_ADDR_16_31_OFFSET, -+ AT803X_LOC_MAC_ADDR_0_15_OFFSET, -+ }; -+ -+ if (!ndev) -+ return -ENODEV; -+ -+ mac = (const u8 *)ndev->dev_addr; -+ -+ if (!is_valid_ether_addr(mac)) -+ return -EINVAL; -+ -+ for (i = 0; i < 3; i++) -+ phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i], -+ mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); -+ -+ /* Enable WOL interrupt */ -+ ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL); -+ if (ret) -+ return ret; -+ } else { -+ /* Disable WOL interrupt */ -+ ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0); -+ if (ret) -+ return ret; -+ } -+ -+ /* Clear WOL status */ -+ ret = phy_read(phydev, AT803X_INTR_STATUS); -+ if (ret < 0) -+ return ret; -+ -+ /* Check if there are other interrupts except for WOL triggered when PHY is -+ * in interrupt mode, only the interrupts enabled by AT803X_INTR_ENABLE can -+ * be passed up to the interrupt PIN. -+ */ -+ irq_enabled = phy_read(phydev, AT803X_INTR_ENABLE); -+ if (irq_enabled < 0) -+ return irq_enabled; -+ -+ irq_enabled &= ~AT803X_INTR_ENABLE_WOL; -+ if (ret & irq_enabled && !phy_polling_mode(phydev)) -+ phy_trigger_machine(phydev); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(at803x_set_wol); -+ -+void at803x_get_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol) -+{ -+ int value; -+ -+ wol->supported = WAKE_MAGIC; -+ wol->wolopts = 0; -+ -+ value = phy_read(phydev, AT803X_INTR_ENABLE); -+ if (value < 0) -+ return; -+ -+ if (value & AT803X_INTR_ENABLE_WOL) -+ wol->wolopts |= WAKE_MAGIC; -+} -+EXPORT_SYMBOL_GPL(at803x_get_wol); -+ -+int at803x_ack_interrupt(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = phy_read(phydev, AT803X_INTR_STATUS); -+ -+ return (err < 0) ? err : 0; -+} -+EXPORT_SYMBOL_GPL(at803x_ack_interrupt); -+ -+int at803x_config_intr(struct phy_device *phydev) -+{ -+ int err; -+ int value; -+ -+ value = phy_read(phydev, AT803X_INTR_ENABLE); -+ -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { -+ /* Clear any pending interrupts */ -+ err = at803x_ack_interrupt(phydev); -+ if (err) -+ return err; -+ -+ value |= AT803X_INTR_ENABLE_AUTONEG_ERR; -+ value |= AT803X_INTR_ENABLE_SPEED_CHANGED; -+ value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED; -+ value |= AT803X_INTR_ENABLE_LINK_FAIL; -+ value |= AT803X_INTR_ENABLE_LINK_SUCCESS; -+ -+ err = phy_write(phydev, AT803X_INTR_ENABLE, value); -+ } else { -+ err = phy_write(phydev, AT803X_INTR_ENABLE, 0); -+ if (err) -+ return err; -+ -+ /* Clear any pending interrupts */ -+ err = at803x_ack_interrupt(phydev); -+ } -+ -+ return err; -+} -+EXPORT_SYMBOL_GPL(at803x_config_intr); -+ -+irqreturn_t at803x_handle_interrupt(struct phy_device *phydev) -+{ -+ int irq_status, int_enabled; -+ -+ irq_status = phy_read(phydev, AT803X_INTR_STATUS); -+ if (irq_status < 0) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ /* Read the current enabled interrupts */ -+ int_enabled = phy_read(phydev, AT803X_INTR_ENABLE); -+ if (int_enabled < 0) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ /* See if this was one of our enabled interrupts */ -+ if (!(irq_status & int_enabled)) -+ return IRQ_NONE; -+ -+ phy_trigger_machine(phydev); -+ -+ return IRQ_HANDLED; -+} -+EXPORT_SYMBOL_GPL(at803x_handle_interrupt); -+ -+int at803x_read_specific_status(struct phy_device *phydev, -+ struct at803x_ss_mask ss_mask) -+{ -+ int ss; -+ -+ /* Read the AT8035 PHY-Specific Status register, which indicates the -+ * speed and duplex that the PHY is actually using, irrespective of -+ * whether we are in autoneg mode or not. -+ */ -+ ss = phy_read(phydev, AT803X_SPECIFIC_STATUS); -+ if (ss < 0) -+ return ss; -+ -+ if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) { -+ int sfc, speed; -+ -+ sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL); -+ if (sfc < 0) -+ return sfc; -+ -+ speed = ss & ss_mask.speed_mask; -+ speed >>= ss_mask.speed_shift; -+ -+ switch (speed) { -+ case AT803X_SS_SPEED_10: -+ phydev->speed = SPEED_10; -+ break; -+ case AT803X_SS_SPEED_100: -+ phydev->speed = SPEED_100; -+ break; -+ case AT803X_SS_SPEED_1000: -+ phydev->speed = SPEED_1000; -+ break; -+ case QCA808X_SS_SPEED_2500: -+ phydev->speed = SPEED_2500; -+ break; -+ } -+ if (ss & AT803X_SS_DUPLEX) -+ phydev->duplex = DUPLEX_FULL; -+ else -+ phydev->duplex = DUPLEX_HALF; -+ -+ if (ss & AT803X_SS_MDIX) -+ phydev->mdix = ETH_TP_MDI_X; -+ else -+ phydev->mdix = ETH_TP_MDI; -+ -+ switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) { -+ case AT803X_SFC_MANUAL_MDI: -+ phydev->mdix_ctrl = ETH_TP_MDI; -+ break; -+ case AT803X_SFC_MANUAL_MDIX: -+ phydev->mdix_ctrl = ETH_TP_MDI_X; -+ break; -+ case AT803X_SFC_AUTOMATIC_CROSSOVER: -+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO; -+ break; -+ } -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(at803x_read_specific_status); -+ -+int at803x_config_mdix(struct phy_device *phydev, u8 ctrl) -+{ -+ u16 val; -+ -+ switch (ctrl) { -+ case ETH_TP_MDI: -+ val = AT803X_SFC_MANUAL_MDI; -+ break; -+ case ETH_TP_MDI_X: -+ val = AT803X_SFC_MANUAL_MDIX; -+ break; -+ case ETH_TP_MDI_AUTO: -+ val = AT803X_SFC_AUTOMATIC_CROSSOVER; -+ break; -+ default: -+ return 0; -+ } -+ -+ return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL, -+ AT803X_SFC_MDI_CROSSOVER_MODE_M, -+ FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val)); -+} -+EXPORT_SYMBOL_GPL(at803x_config_mdix); -+ -+int at803x_prepare_config_aneg(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); -+ if (ret < 0) -+ return ret; -+ -+ /* Changes of the midx bits are disruptive to the normal operation; -+ * therefore any changes to these registers must be followed by a -+ * software reset to take effect. -+ */ -+ if (ret == 1) { -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(at803x_prepare_config_aneg); -+ -+static int at803x_get_downshift(struct phy_device *phydev, u8 *d) -+{ -+ int val; -+ -+ val = phy_read(phydev, AT803X_SMART_SPEED); -+ if (val < 0) -+ return val; -+ -+ if (val & AT803X_SMART_SPEED_ENABLE) -+ *d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2; -+ else -+ *d = DOWNSHIFT_DEV_DISABLE; -+ -+ return 0; -+} -+ -+static int at803x_set_downshift(struct phy_device *phydev, u8 cnt) -+{ -+ u16 mask, set; -+ int ret; -+ -+ switch (cnt) { -+ case DOWNSHIFT_DEV_DEFAULT_COUNT: -+ cnt = AT803X_DEFAULT_DOWNSHIFT; -+ fallthrough; -+ case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT: -+ set = AT803X_SMART_SPEED_ENABLE | -+ AT803X_SMART_SPEED_BYPASS_TIMER | -+ FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2); -+ mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK; -+ break; -+ case DOWNSHIFT_DEV_DISABLE: -+ set = 0; -+ mask = AT803X_SMART_SPEED_ENABLE | -+ AT803X_SMART_SPEED_BYPASS_TIMER; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set); -+ -+ /* After changing the smart speed settings, we need to perform a -+ * software reset, use phy_init_hw() to make sure we set the -+ * reapply any values which might got lost during software reset. -+ */ -+ if (ret == 1) -+ ret = phy_init_hw(phydev); -+ -+ return ret; -+} -+ -+int at803x_get_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, void *data) -+{ -+ switch (tuna->id) { -+ case ETHTOOL_PHY_DOWNSHIFT: -+ return at803x_get_downshift(phydev, data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+EXPORT_SYMBOL_GPL(at803x_get_tunable); -+ -+int at803x_set_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, const void *data) -+{ -+ switch (tuna->id) { -+ case ETHTOOL_PHY_DOWNSHIFT: -+ return at803x_set_downshift(phydev, *(const u8 *)data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+EXPORT_SYMBOL_GPL(at803x_set_tunable); -+ -+int at803x_cdt_fault_length(int dt) -+{ -+ /* According to the datasheet the distance to the fault is -+ * DELTA_TIME * 0.824 meters. -+ * -+ * The author suspect the correct formula is: -+ * -+ * fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2 -+ * -+ * where c is the speed of light, VF is the velocity factor of -+ * the twisted pair cable, 125MHz the counter frequency and -+ * we need to divide by 2 because the hardware will measure the -+ * round trip time to the fault and back to the PHY. -+ * -+ * With a VF of 0.69 we get the factor 0.824 mentioned in the -+ * datasheet. -+ */ -+ return (dt * 824) / 10; -+} -+EXPORT_SYMBOL_GPL(at803x_cdt_fault_length); -+ -+int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start) -+{ -+ return phy_write(phydev, AT803X_CDT, cdt_start); -+} -+EXPORT_SYMBOL_GPL(at803x_cdt_start); -+ -+int at803x_cdt_wait_for_completion(struct phy_device *phydev, -+ u32 cdt_en) -+{ -+ int val, ret; -+ -+ /* One test run takes about 25ms */ -+ ret = phy_read_poll_timeout(phydev, AT803X_CDT, val, -+ !(val & cdt_en), -+ 30000, 100000, true); -+ -+ return ret < 0 ? ret : 0; -+} -+EXPORT_SYMBOL_GPL(at803x_cdt_wait_for_completion); ---- a/drivers/net/phy/qcom/qcom.h -+++ b/drivers/net/phy/qcom/qcom.h -@@ -1,5 +1,63 @@ - /* SPDX-License-Identifier: GPL-2.0 */ - -+#define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10 -+#define AT803X_SFC_ASSERT_CRS BIT(11) -+#define AT803X_SFC_FORCE_LINK BIT(10) -+#define AT803X_SFC_MDI_CROSSOVER_MODE_M GENMASK(6, 5) -+#define AT803X_SFC_AUTOMATIC_CROSSOVER 0x3 -+#define AT803X_SFC_MANUAL_MDIX 0x1 -+#define AT803X_SFC_MANUAL_MDI 0x0 -+#define AT803X_SFC_SQE_TEST BIT(2) -+#define AT803X_SFC_POLARITY_REVERSAL BIT(1) -+#define AT803X_SFC_DISABLE_JABBER BIT(0) -+ -+#define AT803X_SPECIFIC_STATUS 0x11 -+#define AT803X_SS_SPEED_MASK GENMASK(15, 14) -+#define AT803X_SS_SPEED_1000 2 -+#define AT803X_SS_SPEED_100 1 -+#define AT803X_SS_SPEED_10 0 -+#define AT803X_SS_DUPLEX BIT(13) -+#define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11) -+#define AT803X_SS_MDIX BIT(6) -+ -+#define QCA808X_SS_SPEED_MASK GENMASK(9, 7) -+#define QCA808X_SS_SPEED_2500 4 -+ -+#define AT803X_INTR_ENABLE 0x12 -+#define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15) -+#define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14) -+#define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13) -+#define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12) -+#define AT803X_INTR_ENABLE_LINK_FAIL BIT(11) -+#define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10) -+#define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8) -+#define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7) -+#define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5) -+#define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1) -+#define AT803X_INTR_ENABLE_WOL BIT(0) -+ -+#define AT803X_INTR_STATUS 0x13 -+ -+#define AT803X_SMART_SPEED 0x14 -+#define AT803X_SMART_SPEED_ENABLE BIT(5) -+#define AT803X_SMART_SPEED_RETRY_LIMIT_MASK GENMASK(4, 2) -+#define AT803X_SMART_SPEED_BYPASS_TIMER BIT(1) -+ -+#define AT803X_CDT 0x16 -+#define AT803X_CDT_MDI_PAIR_MASK GENMASK(9, 8) -+#define AT803X_CDT_ENABLE_TEST BIT(0) -+#define AT803X_CDT_STATUS 0x1c -+#define AT803X_CDT_STATUS_STAT_NORMAL 0 -+#define AT803X_CDT_STATUS_STAT_SHORT 1 -+#define AT803X_CDT_STATUS_STAT_OPEN 2 -+#define AT803X_CDT_STATUS_STAT_FAIL 3 -+#define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8) -+#define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0) -+ -+#define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C -+#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B -+#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A -+ - #define AT803X_DEBUG_ADDR 0x1D - #define AT803X_DEBUG_DATA 0x1E - -@@ -16,6 +74,10 @@ - #define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13) - #define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15) - -+#define AT803X_DEFAULT_DOWNSHIFT 5 -+#define AT803X_MIN_DOWNSHIFT 2 -+#define AT803X_MAX_DOWNSHIFT 9 -+ - enum stat_access_type { - PHY, - MMD -@@ -28,7 +90,31 @@ struct at803x_hw_stat { - enum stat_access_type access_type; - }; - -+struct at803x_ss_mask { -+ u16 speed_mask; -+ u8 speed_shift; -+}; -+ - int at803x_debug_reg_read(struct phy_device *phydev, u16 reg); - int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, - u16 clear, u16 set); - int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data); -+int at803x_set_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol); -+void at803x_get_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol); -+int at803x_ack_interrupt(struct phy_device *phydev); -+int at803x_config_intr(struct phy_device *phydev); -+irqreturn_t at803x_handle_interrupt(struct phy_device *phydev); -+int at803x_read_specific_status(struct phy_device *phydev, -+ struct at803x_ss_mask ss_mask); -+int at803x_config_mdix(struct phy_device *phydev, u8 ctrl); -+int at803x_prepare_config_aneg(struct phy_device *phydev); -+int at803x_get_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, void *data); -+int at803x_set_tunable(struct phy_device *phydev, -+ struct ethtool_tunable *tuna, const void *data); -+int at803x_cdt_fault_length(int dt); -+int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start); -+int at803x_cdt_wait_for_completion(struct phy_device *phydev, -+ u32 cdt_en); diff --git a/target/linux/generic/backport-6.1/713-v6.9-05-net-phy-qcom-detach-qca808x-PHY-driver-from-at803x.patch b/target/linux/generic/backport-6.1/713-v6.9-05-net-phy-qcom-detach-qca808x-PHY-driver-from-at803x.patch deleted file mode 100644 index 597dcea4c06955..00000000000000 --- a/target/linux/generic/backport-6.1/713-v6.9-05-net-phy-qcom-detach-qca808x-PHY-driver-from-at803x.patch +++ /dev/null @@ -1,1936 +0,0 @@ -From c89414adf2ec7cd9e7080c419aa5847f1db1009c Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 Jan 2024 15:15:23 +0100 -Subject: [PATCH 5/5] net: phy: qcom: detach qca808x PHY driver from at803x - -Almost all the QCA8081 PHY driver OPs are specific and only some of them -use the generic at803x. - -To make the at803x code slimmer, move all the specific qca808x regs and -functions to a dedicated PHY driver. - -Probe function and priv struct is reworked to allocate and use only the -qca808x specific data. Unused data from at803x PHY driver are dropped -from at803x priv struct. - -Also a new Kconfig is introduced QCA808X_PHY, to compile the newly -introduced PHY driver for QCA8081 PHY. - -As the Kconfig name starts with Qualcomm the same order is kept. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240129141600.2592-6-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/qcom/Kconfig | 6 + - drivers/net/phy/qcom/Makefile | 1 + - drivers/net/phy/qcom/at803x.c | 897 +------------------------------ - drivers/net/phy/qcom/qca808x.c | 934 +++++++++++++++++++++++++++++++++ - 4 files changed, 942 insertions(+), 896 deletions(-) - create mode 100644 drivers/net/phy/qcom/qca808x.c - ---- a/drivers/net/phy/qcom/Kconfig -+++ b/drivers/net/phy/qcom/Kconfig -@@ -14,3 +14,9 @@ config QCA83XX_PHY - select QCOM_NET_PHYLIB - help - Currently supports the internal QCA8337(Internal qca8k PHY) model -+ -+config QCA808X_PHY -+ tristate "Qualcomm QCA808x PHYs" -+ select QCOM_NET_PHYLIB -+ help -+ Currently supports the QCA8081 model ---- a/drivers/net/phy/qcom/Makefile -+++ b/drivers/net/phy/qcom/Makefile -@@ -2,3 +2,4 @@ - obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-phy-lib.o - obj-$(CONFIG_AT803X_PHY) += at803x.o - obj-$(CONFIG_QCA83XX_PHY) += qca83xx.o -+obj-$(CONFIG_QCA808X_PHY) += qca808x.o ---- a/drivers/net/phy/qcom/at803x.c -+++ b/drivers/net/phy/qcom/at803x.c -@@ -96,8 +96,6 @@ - #define ATH8035_PHY_ID 0x004dd072 - #define AT8030_PHY_ID_MASK 0xffffffef - --#define QCA8081_PHY_ID 0x004dd101 -- - #define QCA9561_PHY_ID 0x004dd042 - - #define AT803X_PAGE_FIBER 0 -@@ -110,201 +108,7 @@ - /* disable hibernation mode */ - #define AT803X_DISABLE_HIBERNATION_MODE BIT(2) - --/* ADC threshold */ --#define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80 --#define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0) --#define QCA808X_ADC_THRESHOLD_80MV 0 --#define QCA808X_ADC_THRESHOLD_100MV 0xf0 --#define QCA808X_ADC_THRESHOLD_200MV 0x0f --#define QCA808X_ADC_THRESHOLD_300MV 0xff -- --/* CLD control */ --#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007 --#define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4) --#define QCA808X_8023AZ_AFE_EN 0x90 -- --/* AZ control */ --#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008 --#define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32 -- --#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014 --#define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529 -- --#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E --#define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341 -- --#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E --#define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419 -- --#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020 --#define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341 -- --#define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c --#define QCA808X_TOP_OPTION1_DATA 0x0 -- --#define QCA808X_PHY_MMD3_DEBUG_1 0xa100 --#define QCA808X_MMD3_DEBUG_1_VALUE 0x9203 --#define QCA808X_PHY_MMD3_DEBUG_2 0xa101 --#define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad --#define QCA808X_PHY_MMD3_DEBUG_3 0xa103 --#define QCA808X_MMD3_DEBUG_3_VALUE 0x1698 --#define QCA808X_PHY_MMD3_DEBUG_4 0xa105 --#define QCA808X_MMD3_DEBUG_4_VALUE 0x8001 --#define QCA808X_PHY_MMD3_DEBUG_5 0xa106 --#define QCA808X_MMD3_DEBUG_5_VALUE 0x1111 --#define QCA808X_PHY_MMD3_DEBUG_6 0xa011 --#define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85 -- --/* master/slave seed config */ --#define QCA808X_PHY_DEBUG_LOCAL_SEED 9 --#define QCA808X_MASTER_SLAVE_SEED_ENABLE BIT(1) --#define QCA808X_MASTER_SLAVE_SEED_CFG GENMASK(12, 2) --#define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32 -- --/* Hibernation yields lower power consumpiton in contrast with normal operation mode. -- * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s. -- */ --#define QCA808X_DBG_AN_TEST 0xb --#define QCA808X_HIBERNATION_EN BIT(15) -- --#define QCA808X_CDT_ENABLE_TEST BIT(15) --#define QCA808X_CDT_INTER_CHECK_DIS BIT(13) --#define QCA808X_CDT_STATUS BIT(11) --#define QCA808X_CDT_LENGTH_UNIT BIT(10) -- --#define QCA808X_MMD3_CDT_STATUS 0x8064 --#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 --#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 --#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 --#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 --#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) --#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) -- --#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) --#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) --#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) --#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) -- --#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) --#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) --#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) --#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) --#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) -- --#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) --#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) --#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) --#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) -- --/* NORMAL are MDI with type set to 0 */ --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -- QCA808X_CDT_STATUS_STAT_MDI1) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -- QCA808X_CDT_STATUS_STAT_MDI1) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -- QCA808X_CDT_STATUS_STAT_MDI2) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -- QCA808X_CDT_STATUS_STAT_MDI2) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -- QCA808X_CDT_STATUS_STAT_MDI3) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -- QCA808X_CDT_STATUS_STAT_MDI3) -- --/* Added for reference of existence but should be handled by wait_for_completion already */ --#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) -- --#define QCA808X_MMD7_LED_GLOBAL 0x8073 --#define QCA808X_LED_BLINK_1 GENMASK(11, 6) --#define QCA808X_LED_BLINK_2 GENMASK(5, 0) --/* Values are the same for both BLINK_1 and BLINK_2 */ --#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) --#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) --#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) --#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) --#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) --#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) --#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) --#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) --#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) --#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) --#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) --#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) --#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) --#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) --#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) --#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) --#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) --#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) -- --#define QCA808X_MMD7_LED2_CTRL 0x8074 --#define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075 --#define QCA808X_MMD7_LED1_CTRL 0x8076 --#define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077 --#define QCA808X_MMD7_LED0_CTRL 0x8078 --#define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2)) -- --/* LED hw control pattern is the same for every LED */ --#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) --#define QCA808X_LED_SPEED2500_ON BIT(15) --#define QCA808X_LED_SPEED2500_BLINK BIT(14) --/* Follow blink trigger even if duplex or speed condition doesn't match */ --#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) --#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) --#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) --#define QCA808X_LED_TX_BLINK BIT(10) --#define QCA808X_LED_RX_BLINK BIT(9) --#define QCA808X_LED_TX_ON_10MS BIT(8) --#define QCA808X_LED_RX_ON_10MS BIT(7) --#define QCA808X_LED_SPEED1000_ON BIT(6) --#define QCA808X_LED_SPEED100_ON BIT(5) --#define QCA808X_LED_SPEED10_ON BIT(4) --#define QCA808X_LED_COLLISION_BLINK BIT(3) --#define QCA808X_LED_SPEED1000_BLINK BIT(2) --#define QCA808X_LED_SPEED100_BLINK BIT(1) --#define QCA808X_LED_SPEED10_BLINK BIT(0) -- --#define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079 --#define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2)) -- --/* LED force ctrl is the same for every LED -- * No documentation exist for this, not even internal one -- * with NDA as QCOM gives only info about configuring -- * hw control pattern rules and doesn't indicate any way -- * to force the LED to specific mode. -- * These define comes from reverse and testing and maybe -- * lack of some info or some info are not entirely correct. -- * For the basic LED control and hw control these finding -- * are enough to support LED control in all the required APIs. -- * -- * On doing some comparison with implementation with qca807x, -- * it was found that it's 1:1 equal to it and confirms all the -- * reverse done. It was also found further specification with the -- * force mode and the blink modes. -- */ --#define QCA808X_LED_FORCE_EN BIT(15) --#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) --#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) --#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) --#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) --#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) -- --#define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a --/* QSDK sets by default 0x46 to this reg that sets BIT 6 for -- * LED to active high. It's not clear what BIT 3 and BIT 4 does. -- */ --#define QCA808X_LED_ACTIVE_HIGH BIT(6) -- --/* QCA808X 1G chip type */ --#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d --#define QCA808X_PHY_CHIP_TYPE_1G BIT(0) -- --#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072 --#define QCA8081_PHY_FIFO_RSTN BIT(11) -- --MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver"); -+MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver"); - MODULE_AUTHOR("Matus Ujhelyi"); - MODULE_LICENSE("GPL"); - -@@ -318,7 +122,6 @@ struct at803x_priv { - bool is_1000basex; - struct regulator_dev *vddio_rdev; - struct regulator_dev *vddh_rdev; -- int led_polarity_mode; - }; - - struct at803x_context { -@@ -519,9 +322,6 @@ static int at803x_probe(struct phy_devic - if (!priv) - return -ENOMEM; - -- /* Init LED polarity mode to -1 */ -- priv->led_polarity_mode = -1; -- - phydev->priv = priv; - - ret = at803x_parse_dt(phydev); -@@ -1216,672 +1016,6 @@ static int at8035_probe(struct phy_devic - return at8035_parse_dt(phydev); - } - --static int qca808x_phy_fast_retrain_config(struct phy_device *phydev) --{ -- int ret; -- -- /* Enable fast retrain */ -- ret = genphy_c45_fast_retrain(phydev, true); -- if (ret) -- return ret; -- -- phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1, -- QCA808X_TOP_OPTION1_DATA); -- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB, -- QCA808X_MSE_THRESHOLD_20DB_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB, -- QCA808X_MSE_THRESHOLD_17DB_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB, -- QCA808X_MSE_THRESHOLD_27DB_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB, -- QCA808X_MSE_THRESHOLD_28DB_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1, -- QCA808X_MMD3_DEBUG_1_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4, -- QCA808X_MMD3_DEBUG_4_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5, -- QCA808X_MMD3_DEBUG_5_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3, -- QCA808X_MMD3_DEBUG_3_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6, -- QCA808X_MMD3_DEBUG_6_VALUE); -- phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2, -- QCA808X_MMD3_DEBUG_2_VALUE); -- -- return 0; --} -- --static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable) --{ -- u16 seed_value; -- -- if (!enable) -- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -- QCA808X_MASTER_SLAVE_SEED_ENABLE, 0); -- -- seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE); -- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -- QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE, -- FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) | -- QCA808X_MASTER_SLAVE_SEED_ENABLE); --} -- --static bool qca808x_is_prefer_master(struct phy_device *phydev) --{ -- return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) || -- (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED); --} -- --static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev) --{ -- return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); --} -- --static int qca808x_config_init(struct phy_device *phydev) --{ -- int ret; -- -- /* Active adc&vga on 802.3az for the link 1000M and 100M */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7, -- QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN); -- if (ret) -- return ret; -- -- /* Adjust the threshold on 802.3az for the link 1000M */ -- ret = phy_write_mmd(phydev, MDIO_MMD_PCS, -- QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, -- QCA808X_MMD3_AZ_TRAINING_VAL); -- if (ret) -- return ret; -- -- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { -- /* Config the fast retrain for the link 2500M */ -- ret = qca808x_phy_fast_retrain_config(phydev); -- if (ret) -- return ret; -- -- ret = genphy_read_master_slave(phydev); -- if (ret < 0) -- return ret; -- -- if (!qca808x_is_prefer_master(phydev)) { -- /* Enable seed and configure lower ramdom seed to make phy -- * linked as slave mode. -- */ -- ret = qca808x_phy_ms_seed_enable(phydev, true); -- if (ret) -- return ret; -- } -- } -- -- /* Configure adc threshold as 100mv for the link 10M */ -- return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD, -- QCA808X_ADC_THRESHOLD_MASK, -- QCA808X_ADC_THRESHOLD_100MV); --} -- --static int qca808x_read_status(struct phy_device *phydev) --{ -- struct at803x_ss_mask ss_mask = { 0 }; -- int ret; -- -- ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); -- if (ret < 0) -- return ret; -- -- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising, -- ret & MDIO_AN_10GBT_STAT_LP2_5G); -- -- ret = genphy_read_status(phydev); -- if (ret) -- return ret; -- -- /* qca8081 takes the different bits for speed value from at803x */ -- ss_mask.speed_mask = QCA808X_SS_SPEED_MASK; -- ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK); -- ret = at803x_read_specific_status(phydev, ss_mask); -- if (ret < 0) -- return ret; -- -- if (phydev->link) { -- if (phydev->speed == SPEED_2500) -- phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -- else -- phydev->interface = PHY_INTERFACE_MODE_SGMII; -- } else { -- /* generate seed as a lower random value to make PHY linked as SLAVE easily, -- * except for master/slave configuration fault detected or the master mode -- * preferred. -- * -- * the reason for not putting this code into the function link_change_notify is -- * the corner case where the link partner is also the qca8081 PHY and the seed -- * value is configured as the same value, the link can't be up and no link change -- * occurs. -- */ -- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { -- if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR || -- qca808x_is_prefer_master(phydev)) { -- qca808x_phy_ms_seed_enable(phydev, false); -- } else { -- qca808x_phy_ms_seed_enable(phydev, true); -- } -- } -- } -- -- return 0; --} -- --static int qca808x_soft_reset(struct phy_device *phydev) --{ -- int ret; -- -- ret = genphy_soft_reset(phydev); -- if (ret < 0) -- return ret; -- -- if (qca808x_has_fast_retrain_or_slave_seed(phydev)) -- ret = qca808x_phy_ms_seed_enable(phydev, true); -- -- return ret; --} -- --static bool qca808x_cdt_fault_length_valid(int cdt_code) --{ -- switch (cdt_code) { -- case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -- return true; -- default: -- return false; -- } --} -- --static int qca808x_cable_test_result_trans(int cdt_code) --{ -- switch (cdt_code) { -- case QCA808X_CDT_STATUS_STAT_NORMAL: -- return ETHTOOL_A_CABLE_RESULT_CODE_OK; -- case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -- return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; -- case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -- return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -- return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; -- case QCA808X_CDT_STATUS_STAT_FAIL: -- default: -- return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; -- } --} -- --static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, -- int result) --{ -- int val; -- u32 cdt_length_reg = 0; -- -- switch (pair) { -- case ETHTOOL_A_CABLE_PAIR_A: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; -- break; -- case ETHTOOL_A_CABLE_PAIR_B: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; -- break; -- case ETHTOOL_A_CABLE_PAIR_C: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; -- break; -- case ETHTOOL_A_CABLE_PAIR_D: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; -- break; -- default: -- return -EINVAL; -- } -- -- val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); -- if (val < 0) -- return val; -- -- if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) -- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); -- else -- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); -- -- return at803x_cdt_fault_length(val); --} -- --static int qca808x_cable_test_start(struct phy_device *phydev) --{ -- int ret; -- -- /* perform CDT with the following configs: -- * 1. disable hibernation. -- * 2. force PHY working in MDI mode. -- * 3. for PHY working in 1000BaseT. -- * 4. configure the threshold. -- */ -- -- ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0); -- if (ret < 0) -- return ret; -- -- ret = at803x_config_mdix(phydev, ETH_TP_MDI); -- if (ret < 0) -- return ret; -- -- /* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */ -- phydev->duplex = DUPLEX_FULL; -- phydev->speed = SPEED_1000; -- ret = genphy_c45_pma_setup_forced(phydev); -- if (ret < 0) -- return ret; -- -- ret = genphy_setup_forced(phydev); -- if (ret < 0) -- return ret; -- -- /* configure the thresholds for open, short, pair ok test */ -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040); -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040); -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060); -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050); -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060); -- phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060); -- -- return 0; --} -- --static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, -- u16 status) --{ -- int length, result; -- u16 pair_code; -- -- switch (pair) { -- case ETHTOOL_A_CABLE_PAIR_A: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); -- break; -- case ETHTOOL_A_CABLE_PAIR_B: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); -- break; -- case ETHTOOL_A_CABLE_PAIR_C: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); -- break; -- case ETHTOOL_A_CABLE_PAIR_D: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); -- break; -- default: -- return -EINVAL; -- } -- -- result = qca808x_cable_test_result_trans(pair_code); -- ethnl_cable_test_result(phydev, pair, result); -- -- if (qca808x_cdt_fault_length_valid(pair_code)) { -- length = qca808x_cdt_fault_length(phydev, pair, result); -- ethnl_cable_test_fault_length(phydev, pair, length); -- } -- -- return 0; --} -- --static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) --{ -- int ret, val; -- -- *finished = false; -- -- val = QCA808X_CDT_ENABLE_TEST | -- QCA808X_CDT_LENGTH_UNIT; -- ret = at803x_cdt_start(phydev, val); -- if (ret) -- return ret; -- -- ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); -- if (ret) -- return ret; -- -- val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); -- if (val < 0) -- return val; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); -- if (ret) -- return ret; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); -- if (ret) -- return ret; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); -- if (ret) -- return ret; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); -- if (ret) -- return ret; -- -- *finished = true; -- -- return 0; --} -- --static int qca808x_get_features(struct phy_device *phydev) --{ -- int ret; -- -- ret = genphy_c45_pma_read_abilities(phydev); -- if (ret) -- return ret; -- -- /* The autoneg ability is not existed in bit3 of MMD7.1, -- * but it is supported by qca808x PHY, so we add it here -- * manually. -- */ -- linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported); -- -- /* As for the qca8081 1G version chip, the 2500baseT ability is also -- * existed in the bit0 of MMD1.21, we need to remove it manually if -- * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d. -- */ -- ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE); -- if (ret < 0) -- return ret; -- -- if (QCA808X_PHY_CHIP_TYPE_1G & ret) -- linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); -- -- return 0; --} -- --static int qca808x_config_aneg(struct phy_device *phydev) --{ -- int phy_ctrl = 0; -- int ret; -- -- ret = at803x_prepare_config_aneg(phydev); -- if (ret) -- return ret; -- -- /* The reg MII_BMCR also needs to be configured for force mode, the -- * genphy_config_aneg is also needed. -- */ -- if (phydev->autoneg == AUTONEG_DISABLE) -- genphy_c45_pma_setup_forced(phydev); -- -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising)) -- phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G; -- -- ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, -- MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl); -- if (ret < 0) -- return ret; -- -- return __genphy_config_aneg(phydev, ret); --} -- --static void qca808x_link_change_notify(struct phy_device *phydev) --{ -- /* Assert interface sgmii fifo on link down, deassert it on link up, -- * the interface device address is always phy address added by 1. -- */ -- mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1, -- MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL, -- QCA8081_PHY_FIFO_RSTN, -- phydev->link ? QCA8081_PHY_FIFO_RSTN : 0); --} -- --static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules, -- u16 *offload_trigger) --{ -- /* Parsing specific to netdev trigger */ -- if (test_bit(TRIGGER_NETDEV_TX, &rules)) -- *offload_trigger |= QCA808X_LED_TX_BLINK; -- if (test_bit(TRIGGER_NETDEV_RX, &rules)) -- *offload_trigger |= QCA808X_LED_RX_BLINK; -- if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) -- *offload_trigger |= QCA808X_LED_SPEED10_ON; -- if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) -- *offload_trigger |= QCA808X_LED_SPEED100_ON; -- if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) -- *offload_trigger |= QCA808X_LED_SPEED1000_ON; -- if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules)) -- *offload_trigger |= QCA808X_LED_SPEED2500_ON; -- if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) -- *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON; -- if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) -- *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON; -- -- if (rules && !*offload_trigger) -- return -EOPNOTSUPP; -- -- /* Enable BLINK_CHECK_BYPASS by default to make the LED -- * blink even with duplex or speed mode not enabled. -- */ -- *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS; -- -- return 0; --} -- --static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index) --{ -- u16 reg; -- -- if (index > 2) -- return -EINVAL; -- -- reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_FORCE_EN); --} -- --static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index, -- unsigned long rules) --{ -- u16 offload_trigger = 0; -- -- if (index > 2) -- return -EINVAL; -- -- return qca808x_led_parse_netdev(phydev, rules, &offload_trigger); --} -- --static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index, -- unsigned long rules) --{ -- u16 reg, offload_trigger = 0; -- int ret; -- -- if (index > 2) -- return -EINVAL; -- -- reg = QCA808X_MMD7_LED_CTRL(index); -- -- ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger); -- if (ret) -- return ret; -- -- ret = qca808x_led_hw_control_enable(phydev, index); -- if (ret) -- return ret; -- -- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_PATTERN_MASK, -- offload_trigger); --} -- --static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index) --{ -- u16 reg; -- int val; -- -- if (index > 2) -- return false; -- -- reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -- -- return !(val & QCA808X_LED_FORCE_EN); --} -- --static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index, -- unsigned long *rules) --{ -- u16 reg; -- int val; -- -- if (index > 2) -- return -EINVAL; -- -- /* Check if we have hw control enabled */ -- if (qca808x_led_hw_control_status(phydev, index)) -- return -EINVAL; -- -- reg = QCA808X_MMD7_LED_CTRL(index); -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -- if (val & QCA808X_LED_TX_BLINK) -- set_bit(TRIGGER_NETDEV_TX, rules); -- if (val & QCA808X_LED_RX_BLINK) -- set_bit(TRIGGER_NETDEV_RX, rules); -- if (val & QCA808X_LED_SPEED10_ON) -- set_bit(TRIGGER_NETDEV_LINK_10, rules); -- if (val & QCA808X_LED_SPEED100_ON) -- set_bit(TRIGGER_NETDEV_LINK_100, rules); -- if (val & QCA808X_LED_SPEED1000_ON) -- set_bit(TRIGGER_NETDEV_LINK_1000, rules); -- if (val & QCA808X_LED_SPEED2500_ON) -- set_bit(TRIGGER_NETDEV_LINK_2500, rules); -- if (val & QCA808X_LED_HALF_DUPLEX_ON) -- set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); -- if (val & QCA808X_LED_FULL_DUPLEX_ON) -- set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); -- -- return 0; --} -- --static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index) --{ -- u16 reg; -- -- if (index > 2) -- return -EINVAL; -- -- reg = QCA808X_MMD7_LED_CTRL(index); -- -- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_PATTERN_MASK); --} -- --static int qca808x_led_brightness_set(struct phy_device *phydev, -- u8 index, enum led_brightness value) --{ -- u16 reg; -- int ret; -- -- if (index > 2) -- return -EINVAL; -- -- if (!value) { -- ret = qca808x_led_hw_control_reset(phydev, index); -- if (ret) -- return ret; -- } -- -- reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -- QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON : -- QCA808X_LED_FORCE_OFF); --} -- --static int qca808x_led_blink_set(struct phy_device *phydev, u8 index, -- unsigned long *delay_on, -- unsigned long *delay_off) --{ -- int ret; -- u16 reg; -- -- if (index > 2) -- return -EINVAL; -- -- reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- /* Set blink to 50% off, 50% on at 4Hz by default */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, -- QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, -- QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); -- if (ret) -- return ret; -- -- /* We use BLINK_1 for normal blinking */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); -- if (ret) -- return ret; -- -- /* We set blink to 4Hz, aka 250ms */ -- *delay_on = 250 / 2; -- *delay_off = 250 / 2; -- -- return 0; --} -- --static int qca808x_led_polarity_set(struct phy_device *phydev, int index, -- unsigned long modes) --{ -- struct at803x_priv *priv = phydev->priv; -- bool active_low = false; -- u32 mode; -- -- for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { -- switch (mode) { -- case PHY_LED_ACTIVE_LOW: -- active_low = true; -- break; -- default: -- return -EINVAL; -- } -- } -- -- /* PHY polarity is global and can't be set per LED. -- * To detect this, check if last requested polarity mode -- * match the new one. -- */ -- if (priv->led_polarity_mode >= 0 && -- priv->led_polarity_mode != active_low) { -- phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n"); -- return -EINVAL; -- } -- -- /* Save the last PHY polarity mode */ -- priv->led_polarity_mode = active_low; -- -- return phy_modify_mmd(phydev, MDIO_MMD_AN, -- QCA808X_MMD7_LED_POLARITY_CTRL, -- QCA808X_LED_ACTIVE_HIGH, -- active_low ? 0 : QCA808X_LED_ACTIVE_HIGH); --} -- - static struct phy_driver at803x_driver[] = { - { - /* Qualcomm Atheros AR8035 */ -@@ -1989,34 +1123,6 @@ static struct phy_driver at803x_driver[] - .read_status = at803x_read_status, - .soft_reset = genphy_soft_reset, - .config_aneg = at803x_config_aneg, --}, { -- /* Qualcomm QCA8081 */ -- PHY_ID_MATCH_EXACT(QCA8081_PHY_ID), -- .name = "Qualcomm QCA8081", -- .flags = PHY_POLL_CABLE_TEST, -- .probe = at803x_probe, -- .config_intr = at803x_config_intr, -- .handle_interrupt = at803x_handle_interrupt, -- .get_tunable = at803x_get_tunable, -- .set_tunable = at803x_set_tunable, -- .set_wol = at803x_set_wol, -- .get_wol = at803x_get_wol, -- .get_features = qca808x_get_features, -- .config_aneg = qca808x_config_aneg, -- .suspend = genphy_suspend, -- .resume = genphy_resume, -- .read_status = qca808x_read_status, -- .config_init = qca808x_config_init, -- .soft_reset = qca808x_soft_reset, -- .cable_test_start = qca808x_cable_test_start, -- .cable_test_get_status = qca808x_cable_test_get_status, -- .link_change_notify = qca808x_link_change_notify, -- .led_brightness_set = qca808x_led_brightness_set, -- .led_blink_set = qca808x_led_blink_set, -- .led_hw_is_supported = qca808x_led_hw_is_supported, -- .led_hw_control_set = qca808x_led_hw_control_set, -- .led_hw_control_get = qca808x_led_hw_control_get, -- .led_polarity_set = qca808x_led_polarity_set, - }, }; - - module_phy_driver(at803x_driver); -@@ -2028,7 +1134,6 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) }, - { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) }, - { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) }, -- { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) }, - { } - }; - ---- /dev/null -+++ b/drivers/net/phy/qcom/qca808x.c -@@ -0,0 +1,934 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+ -+#include -+#include -+#include -+ -+#include "qcom.h" -+ -+/* ADC threshold */ -+#define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80 -+#define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0) -+#define QCA808X_ADC_THRESHOLD_80MV 0 -+#define QCA808X_ADC_THRESHOLD_100MV 0xf0 -+#define QCA808X_ADC_THRESHOLD_200MV 0x0f -+#define QCA808X_ADC_THRESHOLD_300MV 0xff -+ -+/* CLD control */ -+#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007 -+#define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4) -+#define QCA808X_8023AZ_AFE_EN 0x90 -+ -+/* AZ control */ -+#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008 -+#define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32 -+ -+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014 -+#define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529 -+ -+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E -+#define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341 -+ -+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E -+#define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419 -+ -+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020 -+#define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341 -+ -+#define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c -+#define QCA808X_TOP_OPTION1_DATA 0x0 -+ -+#define QCA808X_PHY_MMD3_DEBUG_1 0xa100 -+#define QCA808X_MMD3_DEBUG_1_VALUE 0x9203 -+#define QCA808X_PHY_MMD3_DEBUG_2 0xa101 -+#define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad -+#define QCA808X_PHY_MMD3_DEBUG_3 0xa103 -+#define QCA808X_MMD3_DEBUG_3_VALUE 0x1698 -+#define QCA808X_PHY_MMD3_DEBUG_4 0xa105 -+#define QCA808X_MMD3_DEBUG_4_VALUE 0x8001 -+#define QCA808X_PHY_MMD3_DEBUG_5 0xa106 -+#define QCA808X_MMD3_DEBUG_5_VALUE 0x1111 -+#define QCA808X_PHY_MMD3_DEBUG_6 0xa011 -+#define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85 -+ -+/* master/slave seed config */ -+#define QCA808X_PHY_DEBUG_LOCAL_SEED 9 -+#define QCA808X_MASTER_SLAVE_SEED_ENABLE BIT(1) -+#define QCA808X_MASTER_SLAVE_SEED_CFG GENMASK(12, 2) -+#define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32 -+ -+/* Hibernation yields lower power consumpiton in contrast with normal operation mode. -+ * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s. -+ */ -+#define QCA808X_DBG_AN_TEST 0xb -+#define QCA808X_HIBERNATION_EN BIT(15) -+ -+#define QCA808X_CDT_ENABLE_TEST BIT(15) -+#define QCA808X_CDT_INTER_CHECK_DIS BIT(13) -+#define QCA808X_CDT_STATUS BIT(11) -+#define QCA808X_CDT_LENGTH_UNIT BIT(10) -+ -+#define QCA808X_MMD3_CDT_STATUS 0x8064 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 -+#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) -+#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) -+ -+#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) -+#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) -+#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) -+#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) -+ -+#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) -+#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) -+#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) -+#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) -+#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) -+ -+#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) -+#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) -+#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) -+#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) -+ -+/* NORMAL are MDI with type set to 0 */ -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI1) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI1) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI2) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI2) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI3) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI3) -+ -+/* Added for reference of existence but should be handled by wait_for_completion already */ -+#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) -+ -+#define QCA808X_MMD7_LED_GLOBAL 0x8073 -+#define QCA808X_LED_BLINK_1 GENMASK(11, 6) -+#define QCA808X_LED_BLINK_2 GENMASK(5, 0) -+/* Values are the same for both BLINK_1 and BLINK_2 */ -+#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) -+#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) -+#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) -+#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) -+#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) -+#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) -+#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) -+#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) -+#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) -+#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) -+#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) -+#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) -+#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) -+#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) -+#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) -+#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) -+#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) -+#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) -+ -+#define QCA808X_MMD7_LED2_CTRL 0x8074 -+#define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075 -+#define QCA808X_MMD7_LED1_CTRL 0x8076 -+#define QCA808X_MMD7_LED1_FORCE_CTRL 0x8077 -+#define QCA808X_MMD7_LED0_CTRL 0x8078 -+#define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2)) -+ -+/* LED hw control pattern is the same for every LED */ -+#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) -+#define QCA808X_LED_SPEED2500_ON BIT(15) -+#define QCA808X_LED_SPEED2500_BLINK BIT(14) -+/* Follow blink trigger even if duplex or speed condition doesn't match */ -+#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) -+#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) -+#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) -+#define QCA808X_LED_TX_BLINK BIT(10) -+#define QCA808X_LED_RX_BLINK BIT(9) -+#define QCA808X_LED_TX_ON_10MS BIT(8) -+#define QCA808X_LED_RX_ON_10MS BIT(7) -+#define QCA808X_LED_SPEED1000_ON BIT(6) -+#define QCA808X_LED_SPEED100_ON BIT(5) -+#define QCA808X_LED_SPEED10_ON BIT(4) -+#define QCA808X_LED_COLLISION_BLINK BIT(3) -+#define QCA808X_LED_SPEED1000_BLINK BIT(2) -+#define QCA808X_LED_SPEED100_BLINK BIT(1) -+#define QCA808X_LED_SPEED10_BLINK BIT(0) -+ -+#define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079 -+#define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2)) -+ -+/* LED force ctrl is the same for every LED -+ * No documentation exist for this, not even internal one -+ * with NDA as QCOM gives only info about configuring -+ * hw control pattern rules and doesn't indicate any way -+ * to force the LED to specific mode. -+ * These define comes from reverse and testing and maybe -+ * lack of some info or some info are not entirely correct. -+ * For the basic LED control and hw control these finding -+ * are enough to support LED control in all the required APIs. -+ * -+ * On doing some comparison with implementation with qca807x, -+ * it was found that it's 1:1 equal to it and confirms all the -+ * reverse done. It was also found further specification with the -+ * force mode and the blink modes. -+ */ -+#define QCA808X_LED_FORCE_EN BIT(15) -+#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) -+#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) -+#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) -+#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) -+#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) -+ -+#define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a -+/* QSDK sets by default 0x46 to this reg that sets BIT 6 for -+ * LED to active high. It's not clear what BIT 3 and BIT 4 does. -+ */ -+#define QCA808X_LED_ACTIVE_HIGH BIT(6) -+ -+/* QCA808X 1G chip type */ -+#define QCA808X_PHY_MMD7_CHIP_TYPE 0x901d -+#define QCA808X_PHY_CHIP_TYPE_1G BIT(0) -+ -+#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072 -+#define QCA8081_PHY_FIFO_RSTN BIT(11) -+ -+#define QCA8081_PHY_ID 0x004dd101 -+ -+MODULE_DESCRIPTION("Qualcomm Atheros QCA808X PHY driver"); -+MODULE_AUTHOR("Matus Ujhelyi"); -+MODULE_LICENSE("GPL"); -+ -+struct qca808x_priv { -+ int led_polarity_mode; -+}; -+ -+static int qca808x_phy_fast_retrain_config(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Enable fast retrain */ -+ ret = genphy_c45_fast_retrain(phydev, true); -+ if (ret) -+ return ret; -+ -+ phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1, -+ QCA808X_TOP_OPTION1_DATA); -+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB, -+ QCA808X_MSE_THRESHOLD_20DB_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB, -+ QCA808X_MSE_THRESHOLD_17DB_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB, -+ QCA808X_MSE_THRESHOLD_27DB_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB, -+ QCA808X_MSE_THRESHOLD_28DB_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1, -+ QCA808X_MMD3_DEBUG_1_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4, -+ QCA808X_MMD3_DEBUG_4_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5, -+ QCA808X_MMD3_DEBUG_5_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3, -+ QCA808X_MMD3_DEBUG_3_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6, -+ QCA808X_MMD3_DEBUG_6_VALUE); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2, -+ QCA808X_MMD3_DEBUG_2_VALUE); -+ -+ return 0; -+} -+ -+static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable) -+{ -+ u16 seed_value; -+ -+ if (!enable) -+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -+ QCA808X_MASTER_SLAVE_SEED_ENABLE, 0); -+ -+ seed_value = prandom_u32_max(QCA808X_MASTER_SLAVE_SEED_RANGE); -+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, -+ QCA808X_MASTER_SLAVE_SEED_CFG | QCA808X_MASTER_SLAVE_SEED_ENABLE, -+ FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value) | -+ QCA808X_MASTER_SLAVE_SEED_ENABLE); -+} -+ -+static bool qca808x_is_prefer_master(struct phy_device *phydev) -+{ -+ return (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_FORCE) || -+ (phydev->master_slave_get == MASTER_SLAVE_CFG_MASTER_PREFERRED); -+} -+ -+static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev) -+{ -+ return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); -+} -+ -+static int qca808x_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct qca808x_priv *priv; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ /* Init LED polarity mode to -1 */ -+ priv->led_polarity_mode = -1; -+ -+ phydev->priv = priv; -+ -+ return 0; -+} -+ -+static int qca808x_config_init(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Active adc&vga on 802.3az for the link 1000M and 100M */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7, -+ QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN); -+ if (ret) -+ return ret; -+ -+ /* Adjust the threshold on 802.3az for the link 1000M */ -+ ret = phy_write_mmd(phydev, MDIO_MMD_PCS, -+ QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, -+ QCA808X_MMD3_AZ_TRAINING_VAL); -+ if (ret) -+ return ret; -+ -+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { -+ /* Config the fast retrain for the link 2500M */ -+ ret = qca808x_phy_fast_retrain_config(phydev); -+ if (ret) -+ return ret; -+ -+ ret = genphy_read_master_slave(phydev); -+ if (ret < 0) -+ return ret; -+ -+ if (!qca808x_is_prefer_master(phydev)) { -+ /* Enable seed and configure lower ramdom seed to make phy -+ * linked as slave mode. -+ */ -+ ret = qca808x_phy_ms_seed_enable(phydev, true); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ /* Configure adc threshold as 100mv for the link 10M */ -+ return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD, -+ QCA808X_ADC_THRESHOLD_MASK, -+ QCA808X_ADC_THRESHOLD_100MV); -+} -+ -+static int qca808x_read_status(struct phy_device *phydev) -+{ -+ struct at803x_ss_mask ss_mask = { 0 }; -+ int ret; -+ -+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); -+ if (ret < 0) -+ return ret; -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising, -+ ret & MDIO_AN_10GBT_STAT_LP2_5G); -+ -+ ret = genphy_read_status(phydev); -+ if (ret) -+ return ret; -+ -+ /* qca8081 takes the different bits for speed value from at803x */ -+ ss_mask.speed_mask = QCA808X_SS_SPEED_MASK; -+ ss_mask.speed_shift = __bf_shf(QCA808X_SS_SPEED_MASK); -+ ret = at803x_read_specific_status(phydev, ss_mask); -+ if (ret < 0) -+ return ret; -+ -+ if (phydev->link) { -+ if (phydev->speed == SPEED_2500) -+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -+ else -+ phydev->interface = PHY_INTERFACE_MODE_SGMII; -+ } else { -+ /* generate seed as a lower random value to make PHY linked as SLAVE easily, -+ * except for master/slave configuration fault detected or the master mode -+ * preferred. -+ * -+ * the reason for not putting this code into the function link_change_notify is -+ * the corner case where the link partner is also the qca8081 PHY and the seed -+ * value is configured as the same value, the link can't be up and no link change -+ * occurs. -+ */ -+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) { -+ if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR || -+ qca808x_is_prefer_master(phydev)) { -+ qca808x_phy_ms_seed_enable(phydev, false); -+ } else { -+ qca808x_phy_ms_seed_enable(phydev, true); -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static int qca808x_soft_reset(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = genphy_soft_reset(phydev); -+ if (ret < 0) -+ return ret; -+ -+ if (qca808x_has_fast_retrain_or_slave_seed(phydev)) -+ ret = qca808x_phy_ms_seed_enable(phydev, true); -+ -+ return ret; -+} -+ -+static bool qca808x_cdt_fault_length_valid(int cdt_code) -+{ -+ switch (cdt_code) { -+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+static int qca808x_cable_test_result_trans(int cdt_code) -+{ -+ switch (cdt_code) { -+ case QCA808X_CDT_STATUS_STAT_NORMAL: -+ return ETHTOOL_A_CABLE_RESULT_CODE_OK; -+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -+ return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; -+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -+ return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -+ return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; -+ case QCA808X_CDT_STATUS_STAT_FAIL: -+ default: -+ return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; -+ } -+} -+ -+static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, -+ int result) -+{ -+ int val; -+ u32 cdt_length_reg = 0; -+ -+ switch (pair) { -+ case ETHTOOL_A_CABLE_PAIR_A: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; -+ break; -+ case ETHTOOL_A_CABLE_PAIR_B: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; -+ break; -+ case ETHTOOL_A_CABLE_PAIR_C: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; -+ break; -+ case ETHTOOL_A_CABLE_PAIR_D: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); -+ if (val < 0) -+ return val; -+ -+ if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) -+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); -+ else -+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); -+ -+ return at803x_cdt_fault_length(val); -+} -+ -+static int qca808x_cable_test_start(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* perform CDT with the following configs: -+ * 1. disable hibernation. -+ * 2. force PHY working in MDI mode. -+ * 3. for PHY working in 1000BaseT. -+ * 4. configure the threshold. -+ */ -+ -+ ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0); -+ if (ret < 0) -+ return ret; -+ -+ ret = at803x_config_mdix(phydev, ETH_TP_MDI); -+ if (ret < 0) -+ return ret; -+ -+ /* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */ -+ phydev->duplex = DUPLEX_FULL; -+ phydev->speed = SPEED_1000; -+ ret = genphy_c45_pma_setup_forced(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ret = genphy_setup_forced(phydev); -+ if (ret < 0) -+ return ret; -+ -+ /* configure the thresholds for open, short, pair ok test */ -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060); -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060); -+ -+ return 0; -+} -+ -+static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, -+ u16 status) -+{ -+ int length, result; -+ u16 pair_code; -+ -+ switch (pair) { -+ case ETHTOOL_A_CABLE_PAIR_A: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_B: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_C: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_D: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ result = qca808x_cable_test_result_trans(pair_code); -+ ethnl_cable_test_result(phydev, pair, result); -+ -+ if (qca808x_cdt_fault_length_valid(pair_code)) { -+ length = qca808x_cdt_fault_length(phydev, pair, result); -+ ethnl_cable_test_fault_length(phydev, pair, length); -+ } -+ -+ return 0; -+} -+ -+static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) -+{ -+ int ret, val; -+ -+ *finished = false; -+ -+ val = QCA808X_CDT_ENABLE_TEST | -+ QCA808X_CDT_LENGTH_UNIT; -+ ret = at803x_cdt_start(phydev, val); -+ if (ret) -+ return ret; -+ -+ ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); -+ if (ret) -+ return ret; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); -+ if (val < 0) -+ return val; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); -+ if (ret) -+ return ret; -+ -+ *finished = true; -+ -+ return 0; -+} -+ -+static int qca808x_get_features(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = genphy_c45_pma_read_abilities(phydev); -+ if (ret) -+ return ret; -+ -+ /* The autoneg ability is not existed in bit3 of MMD7.1, -+ * but it is supported by qca808x PHY, so we add it here -+ * manually. -+ */ -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported); -+ -+ /* As for the qca8081 1G version chip, the 2500baseT ability is also -+ * existed in the bit0 of MMD1.21, we need to remove it manually if -+ * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d. -+ */ -+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE); -+ if (ret < 0) -+ return ret; -+ -+ if (QCA808X_PHY_CHIP_TYPE_1G & ret) -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); -+ -+ return 0; -+} -+ -+static int qca808x_config_aneg(struct phy_device *phydev) -+{ -+ int phy_ctrl = 0; -+ int ret; -+ -+ ret = at803x_prepare_config_aneg(phydev); -+ if (ret) -+ return ret; -+ -+ /* The reg MII_BMCR also needs to be configured for force mode, the -+ * genphy_config_aneg is also needed. -+ */ -+ if (phydev->autoneg == AUTONEG_DISABLE) -+ genphy_c45_pma_setup_forced(phydev); -+ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising)) -+ phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G; -+ -+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, -+ MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl); -+ if (ret < 0) -+ return ret; -+ -+ return __genphy_config_aneg(phydev, ret); -+} -+ -+static void qca808x_link_change_notify(struct phy_device *phydev) -+{ -+ /* Assert interface sgmii fifo on link down, deassert it on link up, -+ * the interface device address is always phy address added by 1. -+ */ -+ mdiobus_c45_modify_changed(phydev->mdio.bus, phydev->mdio.addr + 1, -+ MDIO_MMD_PMAPMD, QCA8081_PHY_SERDES_MMD1_FIFO_CTRL, -+ QCA8081_PHY_FIFO_RSTN, -+ phydev->link ? QCA8081_PHY_FIFO_RSTN : 0); -+} -+ -+static int qca808x_led_parse_netdev(struct phy_device *phydev, unsigned long rules, -+ u16 *offload_trigger) -+{ -+ /* Parsing specific to netdev trigger */ -+ if (test_bit(TRIGGER_NETDEV_TX, &rules)) -+ *offload_trigger |= QCA808X_LED_TX_BLINK; -+ if (test_bit(TRIGGER_NETDEV_RX, &rules)) -+ *offload_trigger |= QCA808X_LED_RX_BLINK; -+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED10_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED100_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED1000_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_2500, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED2500_ON; -+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) -+ *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON; -+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) -+ *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON; -+ -+ if (rules && !*offload_trigger) -+ return -EOPNOTSUPP; -+ -+ /* Enable BLINK_CHECK_BYPASS by default to make the LED -+ * blink even with duplex or speed mode not enabled. -+ */ -+ *offload_trigger |= QCA808X_LED_BLINK_CHECK_BYPASS; -+ -+ return 0; -+} -+ -+static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN); -+} -+ -+static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 offload_trigger = 0; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ return qca808x_led_parse_netdev(phydev, rules, &offload_trigger); -+} -+ -+static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 reg, offload_trigger = 0; -+ int ret; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_CTRL(index); -+ -+ ret = qca808x_led_parse_netdev(phydev, rules, &offload_trigger); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_led_hw_control_enable(phydev, index); -+ if (ret) -+ return ret; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_PATTERN_MASK, -+ offload_trigger); -+} -+ -+static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ int val; -+ -+ if (index > 2) -+ return false; -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -+ -+ return !(val & QCA808X_LED_FORCE_EN); -+} -+ -+static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ u16 reg; -+ int val; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ /* Check if we have hw control enabled */ -+ if (qca808x_led_hw_control_status(phydev, index)) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_CTRL(index); -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -+ if (val & QCA808X_LED_TX_BLINK) -+ set_bit(TRIGGER_NETDEV_TX, rules); -+ if (val & QCA808X_LED_RX_BLINK) -+ set_bit(TRIGGER_NETDEV_RX, rules); -+ if (val & QCA808X_LED_SPEED10_ON) -+ set_bit(TRIGGER_NETDEV_LINK_10, rules); -+ if (val & QCA808X_LED_SPEED100_ON) -+ set_bit(TRIGGER_NETDEV_LINK_100, rules); -+ if (val & QCA808X_LED_SPEED1000_ON) -+ set_bit(TRIGGER_NETDEV_LINK_1000, rules); -+ if (val & QCA808X_LED_SPEED2500_ON) -+ set_bit(TRIGGER_NETDEV_LINK_2500, rules); -+ if (val & QCA808X_LED_HALF_DUPLEX_ON) -+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); -+ if (val & QCA808X_LED_FULL_DUPLEX_ON) -+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); -+ -+ return 0; -+} -+ -+static int qca808x_led_hw_control_reset(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_CTRL(index); -+ -+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_PATTERN_MASK); -+} -+ -+static int qca808x_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ u16 reg; -+ int ret; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ if (!value) { -+ ret = qca808x_led_hw_control_reset(phydev, index); -+ if (ret) -+ return ret; -+ } -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -+ QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON : -+ QCA808X_LED_FORCE_OFF); -+} -+ -+static int qca808x_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ int ret; -+ u16 reg; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -+ -+ /* Set blink to 50% off, 50% on at 4Hz by default */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, -+ QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, -+ QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); -+ if (ret) -+ return ret; -+ -+ /* We use BLINK_1 for normal blinking */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); -+ if (ret) -+ return ret; -+ -+ /* We set blink to 4Hz, aka 250ms */ -+ *delay_on = 250 / 2; -+ *delay_off = 250 / 2; -+ -+ return 0; -+} -+ -+static int qca808x_led_polarity_set(struct phy_device *phydev, int index, -+ unsigned long modes) -+{ -+ struct qca808x_priv *priv = phydev->priv; -+ bool active_low = false; -+ u32 mode; -+ -+ for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { -+ switch (mode) { -+ case PHY_LED_ACTIVE_LOW: -+ active_low = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ /* PHY polarity is global and can't be set per LED. -+ * To detect this, check if last requested polarity mode -+ * match the new one. -+ */ -+ if (priv->led_polarity_mode >= 0 && -+ priv->led_polarity_mode != active_low) { -+ phydev_err(phydev, "PHY polarity is global. Mismatched polarity on different LED\n"); -+ return -EINVAL; -+ } -+ -+ /* Save the last PHY polarity mode */ -+ priv->led_polarity_mode = active_low; -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, -+ QCA808X_MMD7_LED_POLARITY_CTRL, -+ QCA808X_LED_ACTIVE_HIGH, -+ active_low ? 0 : QCA808X_LED_ACTIVE_HIGH); -+} -+ -+static struct phy_driver qca808x_driver[] = { -+{ -+ /* Qualcomm QCA8081 */ -+ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID), -+ .name = "Qualcomm QCA8081", -+ .flags = PHY_POLL_CABLE_TEST, -+ .probe = qca808x_probe, -+ .config_intr = at803x_config_intr, -+ .handle_interrupt = at803x_handle_interrupt, -+ .get_tunable = at803x_get_tunable, -+ .set_tunable = at803x_set_tunable, -+ .set_wol = at803x_set_wol, -+ .get_wol = at803x_get_wol, -+ .get_features = qca808x_get_features, -+ .config_aneg = qca808x_config_aneg, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .read_status = qca808x_read_status, -+ .config_init = qca808x_config_init, -+ .soft_reset = qca808x_soft_reset, -+ .cable_test_start = qca808x_cable_test_start, -+ .cable_test_get_status = qca808x_cable_test_get_status, -+ .link_change_notify = qca808x_link_change_notify, -+ .led_brightness_set = qca808x_led_brightness_set, -+ .led_blink_set = qca808x_led_blink_set, -+ .led_hw_is_supported = qca808x_led_hw_is_supported, -+ .led_hw_control_set = qca808x_led_hw_control_set, -+ .led_hw_control_get = qca808x_led_hw_control_get, -+ .led_polarity_set = qca808x_led_polarity_set, -+}, }; -+ -+module_phy_driver(qca808x_driver); -+ -+static struct mdio_device_id __maybe_unused qca808x_tbl[] = { -+ { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(mdio, qca808x_tbl); diff --git a/target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch b/target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch deleted file mode 100644 index 80c870159ba810..00000000000000 --- a/target/linux/generic/backport-6.1/714-net-pcs-add-driver-for-MediaTek-SGMII-PCS.patch +++ /dev/null @@ -1,394 +0,0 @@ -From 4765a9722e09765866e131ec31f7b9cf4c1f4854 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 19 Mar 2023 12:57:50 +0000 -Subject: [PATCH] net: pcs: add driver for MediaTek SGMII PCS - -The SGMII core found in several MediaTek SoCs is identical to what can -also be found in MediaTek's MT7531 Ethernet switch IC. -As this has not always been clear, both drivers developed different -implementations to deal with the PCS. -Recently Alexander Couzens pointed out this fact which lead to the -development of this shared driver. - -Add a dedicated driver, mostly by copying the code now found in the -Ethernet driver. The now redundant code will be removed by a follow-up -commit. - -Suggested-by: Alexander Couzens -Suggested-by: Russell King (Oracle) -Signed-off-by: Daniel Golle -Tested-by: Frank Wunderlich -Reviewed-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - MAINTAINERS | 8 + - drivers/net/pcs/Kconfig | 7 + - drivers/net/pcs/Makefile | 1 + - drivers/net/pcs/pcs-mtk-lynxi.c | 305 ++++++++++++++++++++++++++++++ - include/linux/pcs/pcs-mtk-lynxi.h | 13 ++ - 5 files changed, 334 insertions(+) - create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c - create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -12935,6 +12935,14 @@ L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/ethernet/mediatek/ - -+MEDIATEK ETHERNET PCS DRIVER -+M: Alexander Couzens -+M: Daniel Golle -+L: netdev@vger.kernel.org -+S: Maintained -+F: drivers/net/pcs/pcs-mtk-lynxi.c -+F: include/linux/pcs/pcs-mtk-lynxi.h -+ - MEDIATEK I2C CONTROLLER DRIVER - M: Qii Wang - L: linux-i2c@vger.kernel.org ---- a/drivers/net/pcs/Kconfig -+++ b/drivers/net/pcs/Kconfig -@@ -32,4 +32,11 @@ config PCS_ALTERA_TSE - This module provides helper functions for the Altera Triple Speed - Ethernet SGMII PCS, that can be found on the Intel Socfpga family. - -+config PCS_MTK_LYNXI -+ tristate -+ select REGMAP -+ help -+ This module provides helpers to phylink for managing the LynxI PCS -+ which is part of MediaTek's SoC and Ethernet switch ICs. -+ - endmenu ---- a/drivers/net/pcs/Makefile -+++ b/drivers/net/pcs/Makefile -@@ -7,3 +7,4 @@ obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o - obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o - obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o - obj-$(CONFIG_PCS_ALTERA_TSE) += pcs-altera-tse.o -+obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o ---- /dev/null -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -0,0 +1,305 @@ -+// SPDX-License-Identifier: GPL-2.0 -+// Copyright (c) 2018-2019 MediaTek Inc. -+/* A library for MediaTek SGMII circuit -+ * -+ * Author: Sean Wang -+ * Author: Alexander Couzens -+ * Author: Daniel Golle -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/* SGMII subsystem config registers */ -+/* BMCR (low 16) BMSR (high 16) */ -+#define SGMSYS_PCS_CONTROL_1 0x0 -+#define SGMII_BMCR GENMASK(15, 0) -+#define SGMII_BMSR GENMASK(31, 16) -+ -+#define SGMSYS_PCS_DEVICE_ID 0x4 -+#define SGMII_LYNXI_DEV_ID 0x4d544950 -+ -+#define SGMSYS_PCS_ADVERTISE 0x8 -+#define SGMII_ADVERTISE GENMASK(15, 0) -+#define SGMII_LPA GENMASK(31, 16) -+ -+#define SGMSYS_PCS_SCRATCH 0x14 -+#define SGMII_DEV_VERSION GENMASK(31, 16) -+ -+/* Register to programmable link timer, the unit in 2 * 8ns */ -+#define SGMSYS_PCS_LINK_TIMER 0x18 -+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0) -+#define SGMII_LINK_TIMER_VAL(ns) FIELD_PREP(SGMII_LINK_TIMER_MASK, \ -+ ((ns) / 2 / 8)) -+ -+/* Register to control remote fault */ -+#define SGMSYS_SGMII_MODE 0x20 -+#define SGMII_IF_MODE_SGMII BIT(0) -+#define SGMII_SPEED_DUPLEX_AN BIT(1) -+#define SGMII_SPEED_MASK GENMASK(3, 2) -+#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) -+#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) -+#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) -+#define SGMII_DUPLEX_HALF BIT(4) -+#define SGMII_REMOTE_FAULT_DIS BIT(8) -+ -+/* Register to reset SGMII design */ -+#define SGMSYS_RESERVED_0 0x34 -+#define SGMII_SW_RESET BIT(0) -+ -+/* Register to set SGMII speed, ANA RG_ Control Signals III */ -+#define SGMII_PHY_SPEED_MASK GENMASK(3, 2) -+#define SGMII_PHY_SPEED_1_25G FIELD_PREP(SGMII_PHY_SPEED_MASK, 0) -+#define SGMII_PHY_SPEED_3_125G FIELD_PREP(SGMII_PHY_SPEED_MASK, 1) -+ -+/* Register to power up QPHY */ -+#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 -+#define SGMII_PHYA_PWD BIT(4) -+ -+/* Register to QPHY wrapper control */ -+#define SGMSYS_QPHY_WRAP_CTRL 0xec -+#define SGMII_PN_SWAP_MASK GENMASK(1, 0) -+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) -+ -+/* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated -+ * data -+ * @regmap: The register map pointing at the range used to setup -+ * SGMII modes -+ * @dev: Pointer to device owning the PCS -+ * @ana_rgc3: The offset of register ANA_RGC3 relative to regmap -+ * @interface: Currently configured interface mode -+ * @pcs: Phylink PCS structure -+ * @flags: Flags indicating hardware properties -+ */ -+struct mtk_pcs_lynxi { -+ struct regmap *regmap; -+ u32 ana_rgc3; -+ phy_interface_t interface; -+ struct phylink_pcs pcs; -+ u32 flags; -+}; -+ -+static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs) -+{ -+ return container_of(pcs, struct mtk_pcs_lynxi, pcs); -+} -+ -+static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ unsigned int bm, adv; -+ -+ /* Read the BMSR and LPA */ -+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); -+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -+ -+ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), -+ FIELD_GET(SGMII_LPA, adv)); -+} -+ -+static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ bool mode_changed = false, changed, use_an; -+ unsigned int rgc3, sgm_mode, bmcr; -+ int advertise, link_timer; -+ -+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface, -+ advertising); -+ if (advertise < 0) -+ return advertise; -+ -+ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and -+ * we assume that fixes it's speed at bitrate = line rate (in -+ * other words, 1000Mbps or 2500Mbps). -+ */ -+ if (interface == PHY_INTERFACE_MODE_SGMII) { -+ sgm_mode = SGMII_IF_MODE_SGMII; -+ if (phylink_autoneg_inband(mode)) { -+ sgm_mode |= SGMII_REMOTE_FAULT_DIS | -+ SGMII_SPEED_DUPLEX_AN; -+ use_an = true; -+ } else { -+ use_an = false; -+ } -+ } else if (phylink_autoneg_inband(mode)) { -+ /* 1000base-X or 2500base-X autoneg */ -+ sgm_mode = SGMII_REMOTE_FAULT_DIS; -+ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ advertising); -+ } else { -+ /* 1000base-X or 2500base-X without autoneg */ -+ sgm_mode = 0; -+ use_an = false; -+ } -+ -+ if (use_an) -+ bmcr = BMCR_ANENABLE; -+ else -+ bmcr = 0; -+ -+ if (mpcs->interface != interface) { -+ link_timer = phylink_get_link_timer_ns(interface); -+ if (link_timer < 0) -+ return link_timer; -+ -+ /* PHYA power down */ -+ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -+ SGMII_PHYA_PWD); -+ -+ /* Reset SGMII PCS state */ -+ regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0, -+ SGMII_SW_RESET); -+ -+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP) -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, -+ SGMII_PN_SWAP_MASK, -+ SGMII_PN_SWAP_TX_RX); -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ rgc3 = SGMII_PHY_SPEED_3_125G; -+ else -+ rgc3 = SGMII_PHY_SPEED_1_25G; -+ -+ /* Configure the underlying interface speed */ -+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -+ SGMII_PHY_SPEED_MASK, rgc3); -+ -+ /* Setup the link timer */ -+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, -+ SGMII_LINK_TIMER_VAL(link_timer)); -+ -+ mpcs->interface = interface; -+ mode_changed = true; -+ } -+ -+ /* Update the advertisement, noting whether it has changed */ -+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, -+ SGMII_ADVERTISE, advertise, &changed); -+ -+ /* Update the sgmsys mode register */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | -+ SGMII_IF_MODE_SGMII, sgm_mode); -+ -+ /* Update the BMCR */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -+ BMCR_ANENABLE, bmcr); -+ -+ /* Release PHYA power down state -+ * Only removing bit SGMII_PHYA_PWD isn't enough. -+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which -+ * prevents SGMII from working. The SGMII still shows link but no traffic -+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was -+ * taken from a good working state of the SGMII interface. -+ * Unknown how much the QPHY needs but it is racy without a sleep. -+ * Tested on mt7622 & mt7986. -+ */ -+ usleep_range(50, 100); -+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); -+ -+ return changed || mode_changed; -+} -+ -+static void mtk_pcs_lynxi_restart_an(struct phylink_pcs *pcs) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ -+ regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART); -+} -+ -+static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, int speed, -+ int duplex) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ unsigned int sgm_mode; -+ -+ if (!phylink_autoneg_inband(mode)) { -+ /* Force the speed and duplex setting */ -+ if (speed == SPEED_10) -+ sgm_mode = SGMII_SPEED_10; -+ else if (speed == SPEED_100) -+ sgm_mode = SGMII_SPEED_100; -+ else -+ sgm_mode = SGMII_SPEED_1000; -+ -+ if (duplex != DUPLEX_FULL) -+ sgm_mode |= SGMII_DUPLEX_HALF; -+ -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, -+ sgm_mode); -+ } -+} -+ -+static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { -+ .pcs_get_state = mtk_pcs_lynxi_get_state, -+ .pcs_config = mtk_pcs_lynxi_config, -+ .pcs_an_restart = mtk_pcs_lynxi_restart_an, -+ .pcs_link_up = mtk_pcs_lynxi_link_up, -+}; -+ -+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, -+ struct regmap *regmap, u32 ana_rgc3, -+ u32 flags) -+{ -+ struct mtk_pcs_lynxi *mpcs; -+ u32 id, ver; -+ int ret; -+ -+ ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id); -+ if (ret < 0) -+ return NULL; -+ -+ if (id != SGMII_LYNXI_DEV_ID) { -+ dev_err(dev, "unknown PCS device id %08x\n", id); -+ return NULL; -+ } -+ -+ ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver); -+ if (ret < 0) -+ return NULL; -+ -+ ver = FIELD_GET(SGMII_DEV_VERSION, ver); -+ if (ver != 0x1) { -+ dev_err(dev, "unknown PCS device version %04x\n", ver); -+ return NULL; -+ } -+ -+ dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id, -+ ver); -+ -+ mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); -+ if (!mpcs) -+ return NULL; -+ -+ mpcs->ana_rgc3 = ana_rgc3; -+ mpcs->regmap = regmap; -+ mpcs->flags = flags; -+ mpcs->pcs.ops = &mtk_pcs_lynxi_ops; -+ mpcs->pcs.poll = true; -+ mpcs->interface = PHY_INTERFACE_MODE_NA; -+ -+ return &mpcs->pcs; -+} -+EXPORT_SYMBOL(mtk_pcs_lynxi_create); -+ -+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs) -+{ -+ if (!pcs) -+ return; -+ -+ kfree(pcs_to_mtk_pcs_lynxi(pcs)); -+} -+EXPORT_SYMBOL(mtk_pcs_lynxi_destroy); -+ -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/include/linux/pcs/pcs-mtk-lynxi.h -@@ -0,0 +1,13 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __LINUX_PCS_MTK_LYNXI_H -+#define __LINUX_PCS_MTK_LYNXI_H -+ -+#include -+#include -+ -+#define MTK_SGMII_FLAG_PN_SWAP BIT(0) -+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, -+ struct regmap *regmap, -+ u32 ana_rgc3, u32 flags); -+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs); -+#endif diff --git a/target/linux/generic/backport-6.1/714-v6.8-01-net-phy-make-addr-type-u8-in-phy_package_shared-stru.patch b/target/linux/generic/backport-6.1/714-v6.8-01-net-phy-make-addr-type-u8-in-phy_package_shared-stru.patch deleted file mode 100644 index 6decc3430b0da2..00000000000000 --- a/target/linux/generic/backport-6.1/714-v6.8-01-net-phy-make-addr-type-u8-in-phy_package_shared-stru.patch +++ /dev/null @@ -1,28 +0,0 @@ -From ebb30ccbbdbd6fae5177b676da4f4ac92bb4f635 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 15 Dec 2023 14:15:31 +0100 -Subject: [PATCH 1/4] net: phy: make addr type u8 in phy_package_shared struct - -Switch addr type in phy_package_shared struct to u8. - -The value is already checked to be non negative and to be less than -PHY_MAX_ADDR, hence u8 is better suited than using int. - -Signed-off-by: Christian Marangi -Reviewed-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - include/linux/phy.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -330,7 +330,7 @@ struct mdio_bus_stats { - * phy_package_leave(). - */ - struct phy_package_shared { -- int addr; -+ u8 addr; - refcount_t refcnt; - unsigned long flags; - size_t priv_size; diff --git a/target/linux/generic/backport-6.1/714-v6.8-02-net-phy-extend-PHY-package-API-to-support-multiple-g.patch b/target/linux/generic/backport-6.1/714-v6.8-02-net-phy-extend-PHY-package-API-to-support-multiple-g.patch deleted file mode 100644 index 0cf01df3d35dcf..00000000000000 --- a/target/linux/generic/backport-6.1/714-v6.8-02-net-phy-extend-PHY-package-API-to-support-multiple-g.patch +++ /dev/null @@ -1,341 +0,0 @@ -From 9eea577eb1155fe4a183bc5e7bf269b0b2e7a6ba Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 15 Dec 2023 14:15:32 +0100 -Subject: [PATCH 2/4] net: phy: extend PHY package API to support multiple - global address - -Current API for PHY package are limited to single address to configure -global settings for the PHY package. - -It was found that some PHY package (for example the qca807x, a PHY -package that is shipped with a bundle of 5 PHY) requires multiple PHY -address to configure global settings. An example scenario is a PHY that -have a dedicated PHY for PSGMII/serdes calibrarion and have a specific -PHY in the package where the global PHY mode is set and affects every -other PHY in the package. - -Change the API in the following way: -- Change phy_package_join() to take the base addr of the PHY package - instead of the global PHY addr. -- Make __/phy_package_write/read() require an additional arg that - select what global PHY address to use by passing the offset from the - base addr passed on phy_package_join(). - -Each user of this API is updated to follow this new implementation -following a pattern where an enum is defined to declare the offset of the -addr. - -We also drop the check if shared is defined as any user of the -phy_package_read/write is expected to use phy_package_join first. Misuse -of this will correctly trigger a kernel panic for NULL pointer -exception. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/bcm54140.c | 16 ++++++-- - drivers/net/phy/mscc/mscc.h | 5 +++ - drivers/net/phy/mscc/mscc_main.c | 4 +- - drivers/net/phy/phy_device.c | 35 +++++++++-------- - include/linux/phy.h | 64 +++++++++++++++++++++----------- - 5 files changed, 80 insertions(+), 44 deletions(-) - ---- a/drivers/net/phy/bcm54140.c -+++ b/drivers/net/phy/bcm54140.c -@@ -128,6 +128,10 @@ - #define BCM54140_DEFAULT_DOWNSHIFT 5 - #define BCM54140_MAX_DOWNSHIFT 9 - -+enum bcm54140_global_phy { -+ BCM54140_BASE_ADDR = 0, -+}; -+ - struct bcm54140_priv { - int port; - int base_addr; -@@ -429,11 +433,13 @@ static int bcm54140_base_read_rdb(struct - int ret; - - phy_lock_mdio_bus(phydev); -- ret = __phy_package_write(phydev, MII_BCM54XX_RDB_ADDR, rdb); -+ ret = __phy_package_write(phydev, BCM54140_BASE_ADDR, -+ MII_BCM54XX_RDB_ADDR, rdb); - if (ret < 0) - goto out; - -- ret = __phy_package_read(phydev, MII_BCM54XX_RDB_DATA); -+ ret = __phy_package_read(phydev, BCM54140_BASE_ADDR, -+ MII_BCM54XX_RDB_DATA); - - out: - phy_unlock_mdio_bus(phydev); -@@ -446,11 +452,13 @@ static int bcm54140_base_write_rdb(struc - int ret; - - phy_lock_mdio_bus(phydev); -- ret = __phy_package_write(phydev, MII_BCM54XX_RDB_ADDR, rdb); -+ ret = __phy_package_write(phydev, BCM54140_BASE_ADDR, -+ MII_BCM54XX_RDB_ADDR, rdb); - if (ret < 0) - goto out; - -- ret = __phy_package_write(phydev, MII_BCM54XX_RDB_DATA, val); -+ ret = __phy_package_write(phydev, BCM54140_BASE_ADDR, -+ MII_BCM54XX_RDB_DATA, val); - - out: - phy_unlock_mdio_bus(phydev); ---- a/drivers/net/phy/mscc/mscc.h -+++ b/drivers/net/phy/mscc/mscc.h -@@ -414,6 +414,11 @@ struct vsc8531_private { - * gpio_lock: used for PHC operations. Common for all PHYs as the load/save GPIO - * is shared. - */ -+ -+enum vsc85xx_global_phy { -+ VSC88XX_BASE_ADDR = 0, -+}; -+ - struct vsc85xx_shared_private { - struct mutex gpio_lock; - }; ---- a/drivers/net/phy/mscc/mscc_main.c -+++ b/drivers/net/phy/mscc/mscc_main.c -@@ -700,7 +700,7 @@ int phy_base_write(struct phy_device *ph - dump_stack(); - } - -- return __phy_package_write(phydev, regnum, val); -+ return __phy_package_write(phydev, VSC88XX_BASE_ADDR, regnum, val); - } - - /* phydev->bus->mdio_lock should be locked when using this function */ -@@ -711,7 +711,7 @@ int phy_base_read(struct phy_device *phy - dump_stack(); - } - -- return __phy_package_read(phydev, regnum); -+ return __phy_package_read(phydev, VSC88XX_BASE_ADDR, regnum); - } - - u32 vsc85xx_csr_read(struct phy_device *phydev, ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -1602,20 +1602,22 @@ EXPORT_SYMBOL_GPL(phy_driver_is_genphy_1 - /** - * phy_package_join - join a common PHY group - * @phydev: target phy_device struct -- * @addr: cookie and PHY address for global register access -+ * @base_addr: cookie and base PHY address of PHY package for offset -+ * calculation of global register access - * @priv_size: if non-zero allocate this amount of bytes for private data - * - * This joins a PHY group and provides a shared storage for all phydevs in - * this group. This is intended to be used for packages which contain - * more than one PHY, for example a quad PHY transceiver. - * -- * The addr parameter serves as a cookie which has to have the same value -- * for all members of one group and as a PHY address to access generic -- * registers of a PHY package. Usually, one of the PHY addresses of the -- * different PHYs in the package provides access to these global registers. -+ * The base_addr parameter serves as cookie which has to have the same values -+ * for all members of one group and as the base PHY address of the PHY package -+ * for offset calculation to access generic registers of a PHY package. -+ * Usually, one of the PHY addresses of the different PHYs in the package -+ * provides access to these global registers. - * The address which is given here, will be used in the phy_package_read() -- * and phy_package_write() convenience functions. If your PHY doesn't have -- * global registers you can just pick any of the PHY addresses. -+ * and phy_package_write() convenience functions as base and added to the -+ * passed offset in those functions. - * - * This will set the shared pointer of the phydev to the shared storage. - * If this is the first call for a this cookie the shared storage will be -@@ -1625,17 +1627,17 @@ EXPORT_SYMBOL_GPL(phy_driver_is_genphy_1 - * Returns < 1 on error, 0 on success. Esp. calling phy_package_join() - * with the same cookie but a different priv_size is an error. - */ --int phy_package_join(struct phy_device *phydev, int addr, size_t priv_size) -+int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size) - { - struct mii_bus *bus = phydev->mdio.bus; - struct phy_package_shared *shared; - int ret; - -- if (addr < 0 || addr >= PHY_MAX_ADDR) -+ if (base_addr < 0 || base_addr >= PHY_MAX_ADDR) - return -EINVAL; - - mutex_lock(&bus->shared_lock); -- shared = bus->shared[addr]; -+ shared = bus->shared[base_addr]; - if (!shared) { - ret = -ENOMEM; - shared = kzalloc(sizeof(*shared), GFP_KERNEL); -@@ -1647,9 +1649,9 @@ int phy_package_join(struct phy_device * - goto err_free; - shared->priv_size = priv_size; - } -- shared->addr = addr; -+ shared->base_addr = base_addr; - refcount_set(&shared->refcnt, 1); -- bus->shared[addr] = shared; -+ bus->shared[base_addr] = shared; - } else { - ret = -EINVAL; - if (priv_size && priv_size != shared->priv_size) -@@ -1687,7 +1689,7 @@ void phy_package_leave(struct phy_device - return; - - if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) { -- bus->shared[shared->addr] = NULL; -+ bus->shared[shared->base_addr] = NULL; - mutex_unlock(&bus->shared_lock); - kfree(shared->priv); - kfree(shared); -@@ -1706,7 +1708,8 @@ static void devm_phy_package_leave(struc - * devm_phy_package_join - resource managed phy_package_join() - * @dev: device that is registering this PHY package - * @phydev: target phy_device struct -- * @addr: cookie and PHY address for global register access -+ * @base_addr: cookie and base PHY address of PHY package for offset -+ * calculation of global register access - * @priv_size: if non-zero allocate this amount of bytes for private data - * - * Managed phy_package_join(). Shared storage fetched by this function, -@@ -1714,7 +1717,7 @@ static void devm_phy_package_leave(struc - * phy_package_join() for more information. - */ - int devm_phy_package_join(struct device *dev, struct phy_device *phydev, -- int addr, size_t priv_size) -+ int base_addr, size_t priv_size) - { - struct phy_device **ptr; - int ret; -@@ -1724,7 +1727,7 @@ int devm_phy_package_join(struct device - if (!ptr) - return -ENOMEM; - -- ret = phy_package_join(phydev, addr, priv_size); -+ ret = phy_package_join(phydev, base_addr, priv_size); - - if (!ret) { - *ptr = phydev; ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -319,7 +319,8 @@ struct mdio_bus_stats { - - /** - * struct phy_package_shared - Shared information in PHY packages -- * @addr: Common PHY address used to combine PHYs in one package -+ * @base_addr: Base PHY address of PHY package used to combine PHYs -+ * in one package and for offset calculation of phy_package_read/write - * @refcnt: Number of PHYs connected to this shared data - * @flags: Initialization of PHY package - * @priv_size: Size of the shared private data @priv -@@ -330,7 +331,7 @@ struct mdio_bus_stats { - * phy_package_leave(). - */ - struct phy_package_shared { -- u8 addr; -+ u8 base_addr; - refcount_t refcnt; - unsigned long flags; - size_t priv_size; -@@ -1763,10 +1764,10 @@ int phy_ethtool_get_link_ksettings(struc - int phy_ethtool_set_link_ksettings(struct net_device *ndev, - const struct ethtool_link_ksettings *cmd); - int phy_ethtool_nway_reset(struct net_device *ndev); --int phy_package_join(struct phy_device *phydev, int addr, size_t priv_size); -+int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size); - void phy_package_leave(struct phy_device *phydev); - int devm_phy_package_join(struct device *dev, struct phy_device *phydev, -- int addr, size_t priv_size); -+ int base_addr, size_t priv_size); - - #if IS_ENABLED(CONFIG_PHYLIB) - int __init mdio_bus_init(void); -@@ -1778,46 +1779,65 @@ int phy_ethtool_get_sset_count(struct ph - int phy_ethtool_get_stats(struct phy_device *phydev, - struct ethtool_stats *stats, u64 *data); - --static inline int phy_package_read(struct phy_device *phydev, u32 regnum) -+static inline int phy_package_address(struct phy_device *phydev, -+ unsigned int addr_offset) - { - struct phy_package_shared *shared = phydev->shared; -+ u8 base_addr = shared->base_addr; - -- if (!shared) -+ if (addr_offset >= PHY_MAX_ADDR - base_addr) - return -EIO; - -- return mdiobus_read(phydev->mdio.bus, shared->addr, regnum); -+ /* we know that addr will be in the range 0..31 and thus the -+ * implicit cast to a signed int is not a problem. -+ */ -+ return base_addr + addr_offset; - } - --static inline int __phy_package_read(struct phy_device *phydev, u32 regnum) -+static inline int phy_package_read(struct phy_device *phydev, -+ unsigned int addr_offset, u32 regnum) - { -- struct phy_package_shared *shared = phydev->shared; -+ int addr = phy_package_address(phydev, addr_offset); - -- if (!shared) -- return -EIO; -+ if (addr < 0) -+ return addr; -+ -+ return mdiobus_read(phydev->mdio.bus, addr, regnum); -+} -+ -+static inline int __phy_package_read(struct phy_device *phydev, -+ unsigned int addr_offset, u32 regnum) -+{ -+ int addr = phy_package_address(phydev, addr_offset); -+ -+ if (addr < 0) -+ return addr; - -- return __mdiobus_read(phydev->mdio.bus, shared->addr, regnum); -+ return __mdiobus_read(phydev->mdio.bus, addr, regnum); - } - - static inline int phy_package_write(struct phy_device *phydev, -- u32 regnum, u16 val) -+ unsigned int addr_offset, u32 regnum, -+ u16 val) - { -- struct phy_package_shared *shared = phydev->shared; -+ int addr = phy_package_address(phydev, addr_offset); - -- if (!shared) -- return -EIO; -+ if (addr < 0) -+ return addr; - -- return mdiobus_write(phydev->mdio.bus, shared->addr, regnum, val); -+ return mdiobus_write(phydev->mdio.bus, addr, regnum, val); - } - - static inline int __phy_package_write(struct phy_device *phydev, -- u32 regnum, u16 val) -+ unsigned int addr_offset, u32 regnum, -+ u16 val) - { -- struct phy_package_shared *shared = phydev->shared; -+ int addr = phy_package_address(phydev, addr_offset); - -- if (!shared) -- return -EIO; -+ if (addr < 0) -+ return addr; - -- return __mdiobus_write(phydev->mdio.bus, shared->addr, regnum, val); -+ return __mdiobus_write(phydev->mdio.bus, addr, regnum, val); - } - - static inline bool __phy_package_set_once(struct phy_device *phydev, diff --git a/target/linux/generic/backport-6.1/714-v6.8-03-net-phy-restructure-__phy_write-read_mmd-to-helper-a.patch b/target/linux/generic/backport-6.1/714-v6.8-03-net-phy-restructure-__phy_write-read_mmd-to-helper-a.patch deleted file mode 100644 index 4a17d4645344bb..00000000000000 --- a/target/linux/generic/backport-6.1/714-v6.8-03-net-phy-restructure-__phy_write-read_mmd-to-helper-a.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 028672bd1d73cf65249a420c1de75e8d2acd2f6a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 15 Dec 2023 14:15:33 +0100 -Subject: [PATCH 3/4] net: phy: restructure __phy_write/read_mmd to helper and - phydev user - -Restructure phy_write_mmd and phy_read_mmd to implement generic helper -for direct mdiobus access for mmd and use these helper for phydev user. - -This is needed in preparation of PHY package API that requires generic -access to the mdiobus and are deatched from phydev struct but instead -access them based on PHY package base_addr and offsets. - -Signed-off-by: Christian Marangi -Reviewed-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/phy-core.c | 64 ++++++++++++++++++-------------------- - 1 file changed, 30 insertions(+), 34 deletions(-) - ---- a/drivers/net/phy/phy-core.c -+++ b/drivers/net/phy/phy-core.c -@@ -528,6 +528,28 @@ static void mmd_phy_indirect(struct mii_ - devad | MII_MMD_CTRL_NOINCR); - } - -+static int mmd_phy_read(struct mii_bus *bus, int phy_addr, bool is_c45, -+ int devad, u32 regnum) -+{ -+ if (is_c45) -+ return __mdiobus_c45_read(bus, phy_addr, devad, regnum); -+ -+ mmd_phy_indirect(bus, phy_addr, devad, regnum); -+ /* Read the content of the MMD's selected register */ -+ return __mdiobus_read(bus, phy_addr, MII_MMD_DATA); -+} -+ -+static int mmd_phy_write(struct mii_bus *bus, int phy_addr, bool is_c45, -+ int devad, u32 regnum, u16 val) -+{ -+ if (is_c45) -+ return __mdiobus_c45_write(bus, phy_addr, devad, regnum, val); -+ -+ mmd_phy_indirect(bus, phy_addr, devad, regnum); -+ /* Write the data into MMD's selected register */ -+ return __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val); -+} -+ - /** - * __phy_read_mmd - Convenience function for reading a register - * from an MMD on a given PHY. -@@ -539,26 +561,14 @@ static void mmd_phy_indirect(struct mii_ - */ - int __phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum) - { -- int val; -- - if (regnum > (u16)~0 || devad > 32) - return -EINVAL; - -- if (phydev->drv && phydev->drv->read_mmd) { -- val = phydev->drv->read_mmd(phydev, devad, regnum); -- } else if (phydev->is_c45) { -- val = __mdiobus_c45_read(phydev->mdio.bus, phydev->mdio.addr, -- devad, regnum); -- } else { -- struct mii_bus *bus = phydev->mdio.bus; -- int phy_addr = phydev->mdio.addr; -- -- mmd_phy_indirect(bus, phy_addr, devad, regnum); -- -- /* Read the content of the MMD's selected register */ -- val = __mdiobus_read(bus, phy_addr, MII_MMD_DATA); -- } -- return val; -+ if (phydev->drv && phydev->drv->read_mmd) -+ return phydev->drv->read_mmd(phydev, devad, regnum); -+ -+ return mmd_phy_read(phydev->mdio.bus, phydev->mdio.addr, -+ phydev->is_c45, devad, regnum); - } - EXPORT_SYMBOL(__phy_read_mmd); - -@@ -595,28 +605,14 @@ EXPORT_SYMBOL(phy_read_mmd); - */ - int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val) - { -- int ret; -- - if (regnum > (u16)~0 || devad > 32) - return -EINVAL; - -- if (phydev->drv && phydev->drv->write_mmd) { -- ret = phydev->drv->write_mmd(phydev, devad, regnum, val); -- } else if (phydev->is_c45) { -- ret = __mdiobus_c45_write(phydev->mdio.bus, phydev->mdio.addr, -- devad, regnum, val); -- } else { -- struct mii_bus *bus = phydev->mdio.bus; -- int phy_addr = phydev->mdio.addr; -+ if (phydev->drv && phydev->drv->write_mmd) -+ return phydev->drv->write_mmd(phydev, devad, regnum, val); - -- mmd_phy_indirect(bus, phy_addr, devad, regnum); -- -- /* Write the data into MMD's selected register */ -- __mdiobus_write(bus, phy_addr, MII_MMD_DATA, val); -- -- ret = 0; -- } -- return ret; -+ return mmd_phy_write(phydev->mdio.bus, phydev->mdio.addr, -+ phydev->is_c45, devad, regnum, val); - } - EXPORT_SYMBOL(__phy_write_mmd); - diff --git a/target/linux/generic/backport-6.1/714-v6.8-04-net-phy-add-support-for-PHY-package-MMD-read-write.patch b/target/linux/generic/backport-6.1/714-v6.8-04-net-phy-add-support-for-PHY-package-MMD-read-write.patch deleted file mode 100644 index a628a37929190f..00000000000000 --- a/target/linux/generic/backport-6.1/714-v6.8-04-net-phy-add-support-for-PHY-package-MMD-read-write.patch +++ /dev/null @@ -1,196 +0,0 @@ -From d63710fc0f1a501fd75a7025e3070a96ffa1645f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 15 Dec 2023 14:15:34 +0100 -Subject: [PATCH 4/4] net: phy: add support for PHY package MMD read/write - -Some PHY in PHY package may require to read/write MMD regs to correctly -configure the PHY package. - -Add support for these additional required function in both lock and no -lock variant. - -It's assumed that the entire PHY package is either C22 or C45. We use -C22 or C45 way of writing/reading to mmd regs based on the passed phydev -whether it's C22 or C45. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/phy-core.c | 140 +++++++++++++++++++++++++++++++++++++ - include/linux/phy.h | 16 +++++ - 2 files changed, 156 insertions(+) - ---- a/drivers/net/phy/phy-core.c -+++ b/drivers/net/phy/phy-core.c -@@ -639,6 +639,146 @@ int phy_write_mmd(struct phy_device *phy - EXPORT_SYMBOL(phy_write_mmd); - - /** -+ * __phy_package_read_mmd - read MMD reg relative to PHY package base addr -+ * @phydev: The phy_device struct -+ * @addr_offset: The offset to be added to PHY package base_addr -+ * @devad: The MMD to read from -+ * @regnum: The register on the MMD to read -+ * -+ * Convenience helper for reading a register of an MMD on a given PHY -+ * using the PHY package base address. The base address is added to -+ * the addr_offset value. -+ * -+ * Same calling rules as for __phy_read(); -+ * -+ * NOTE: It's assumed that the entire PHY package is either C22 or C45. -+ */ -+int __phy_package_read_mmd(struct phy_device *phydev, -+ unsigned int addr_offset, int devad, -+ u32 regnum) -+{ -+ int addr = phy_package_address(phydev, addr_offset); -+ -+ if (addr < 0) -+ return addr; -+ -+ if (regnum > (u16)~0 || devad > 32) -+ return -EINVAL; -+ -+ return mmd_phy_read(phydev->mdio.bus, addr, phydev->is_c45, devad, -+ regnum); -+} -+EXPORT_SYMBOL(__phy_package_read_mmd); -+ -+/** -+ * phy_package_read_mmd - read MMD reg relative to PHY package base addr -+ * @phydev: The phy_device struct -+ * @addr_offset: The offset to be added to PHY package base_addr -+ * @devad: The MMD to read from -+ * @regnum: The register on the MMD to read -+ * -+ * Convenience helper for reading a register of an MMD on a given PHY -+ * using the PHY package base address. The base address is added to -+ * the addr_offset value. -+ * -+ * Same calling rules as for phy_read(); -+ * -+ * NOTE: It's assumed that the entire PHY package is either C22 or C45. -+ */ -+int phy_package_read_mmd(struct phy_device *phydev, -+ unsigned int addr_offset, int devad, -+ u32 regnum) -+{ -+ int addr = phy_package_address(phydev, addr_offset); -+ int val; -+ -+ if (addr < 0) -+ return addr; -+ -+ if (regnum > (u16)~0 || devad > 32) -+ return -EINVAL; -+ -+ phy_lock_mdio_bus(phydev); -+ val = mmd_phy_read(phydev->mdio.bus, addr, phydev->is_c45, devad, -+ regnum); -+ phy_unlock_mdio_bus(phydev); -+ -+ return val; -+} -+EXPORT_SYMBOL(phy_package_read_mmd); -+ -+/** -+ * __phy_package_write_mmd - write MMD reg relative to PHY package base addr -+ * @phydev: The phy_device struct -+ * @addr_offset: The offset to be added to PHY package base_addr -+ * @devad: The MMD to write to -+ * @regnum: The register on the MMD to write -+ * @val: value to write to @regnum -+ * -+ * Convenience helper for writing a register of an MMD on a given PHY -+ * using the PHY package base address. The base address is added to -+ * the addr_offset value. -+ * -+ * Same calling rules as for __phy_write(); -+ * -+ * NOTE: It's assumed that the entire PHY package is either C22 or C45. -+ */ -+int __phy_package_write_mmd(struct phy_device *phydev, -+ unsigned int addr_offset, int devad, -+ u32 regnum, u16 val) -+{ -+ int addr = phy_package_address(phydev, addr_offset); -+ -+ if (addr < 0) -+ return addr; -+ -+ if (regnum > (u16)~0 || devad > 32) -+ return -EINVAL; -+ -+ return mmd_phy_write(phydev->mdio.bus, addr, phydev->is_c45, devad, -+ regnum, val); -+} -+EXPORT_SYMBOL(__phy_package_write_mmd); -+ -+/** -+ * phy_package_write_mmd - write MMD reg relative to PHY package base addr -+ * @phydev: The phy_device struct -+ * @addr_offset: The offset to be added to PHY package base_addr -+ * @devad: The MMD to write to -+ * @regnum: The register on the MMD to write -+ * @val: value to write to @regnum -+ * -+ * Convenience helper for writing a register of an MMD on a given PHY -+ * using the PHY package base address. The base address is added to -+ * the addr_offset value. -+ * -+ * Same calling rules as for phy_write(); -+ * -+ * NOTE: It's assumed that the entire PHY package is either C22 or C45. -+ */ -+int phy_package_write_mmd(struct phy_device *phydev, -+ unsigned int addr_offset, int devad, -+ u32 regnum, u16 val) -+{ -+ int addr = phy_package_address(phydev, addr_offset); -+ int ret; -+ -+ if (addr < 0) -+ return addr; -+ -+ if (regnum > (u16)~0 || devad > 32) -+ return -EINVAL; -+ -+ phy_lock_mdio_bus(phydev); -+ ret = mmd_phy_write(phydev->mdio.bus, addr, phydev->is_c45, devad, -+ regnum, val); -+ phy_unlock_mdio_bus(phydev); -+ -+ return ret; -+} -+EXPORT_SYMBOL(phy_package_write_mmd); -+ -+/** - * phy_modify_changed - Function for modifying a PHY register - * @phydev: the phy_device struct - * @regnum: register number to modify ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -1840,6 +1840,22 @@ static inline int __phy_package_write(st - return __mdiobus_write(phydev->mdio.bus, addr, regnum, val); - } - -+int __phy_package_read_mmd(struct phy_device *phydev, -+ unsigned int addr_offset, int devad, -+ u32 regnum); -+ -+int phy_package_read_mmd(struct phy_device *phydev, -+ unsigned int addr_offset, int devad, -+ u32 regnum); -+ -+int __phy_package_write_mmd(struct phy_device *phydev, -+ unsigned int addr_offset, int devad, -+ u32 regnum, u16 val); -+ -+int phy_package_write_mmd(struct phy_device *phydev, -+ unsigned int addr_offset, int devad, -+ u32 regnum, u16 val); -+ - static inline bool __phy_package_set_once(struct phy_device *phydev, - unsigned int b) - { diff --git a/target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch b/target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch deleted file mode 100644 index 2886123f2d8f08..00000000000000 --- a/target/linux/generic/backport-6.1/715-01-v6.2-net-fman-memac-Add-serdes-support.patch +++ /dev/null @@ -1,103 +0,0 @@ -From affa013f494486079c3c5ad2d00cebc41a3d7445 Mon Sep 17 00:00:00 2001 -From: Sean Anderson -Date: Mon, 17 Oct 2022 16:22:36 -0400 -Subject: [PATCH 01/21] net: fman: memac: Add serdes support - -This adds support for using a serdes which has to be configured. This is -primarly in preparation for phylink conversion, which will then change the -serdes mode dynamically. - -Signed-off-by: Sean Anderson -Signed-off-by: David S. Miller ---- - .../net/ethernet/freescale/fman/fman_memac.c | 49 ++++++++++++++++++- - 1 file changed, 47 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/fman/fman_memac.c -+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - - /* PCS registers */ -@@ -324,6 +325,7 @@ struct fman_mac { - void *fm; - struct fman_rev_info fm_rev_info; - bool basex_if; -+ struct phy *serdes; - struct phy_device *pcsphy; - bool allmulti_enabled; - }; -@@ -1203,17 +1205,56 @@ int memac_initialization(struct mac_devi - } - } - -+ memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes"); -+ err = PTR_ERR(memac->serdes); -+ if (err == -ENODEV || err == -ENOSYS) { -+ dev_dbg(mac_dev->dev, "could not get (optional) serdes\n"); -+ memac->serdes = NULL; -+ } else if (IS_ERR(memac->serdes)) { -+ dev_err_probe(mac_dev->dev, err, "could not get serdes\n"); -+ goto _return_fm_mac_free; -+ } else { -+ err = phy_init(memac->serdes); -+ if (err) { -+ dev_err_probe(mac_dev->dev, err, -+ "could not initialize serdes\n"); -+ goto _return_fm_mac_free; -+ } -+ -+ err = phy_power_on(memac->serdes); -+ if (err) { -+ dev_err_probe(mac_dev->dev, err, -+ "could not power on serdes\n"); -+ goto _return_phy_exit; -+ } -+ -+ if (memac->phy_if == PHY_INTERFACE_MODE_SGMII || -+ memac->phy_if == PHY_INTERFACE_MODE_1000BASEX || -+ memac->phy_if == PHY_INTERFACE_MODE_2500BASEX || -+ memac->phy_if == PHY_INTERFACE_MODE_QSGMII || -+ memac->phy_if == PHY_INTERFACE_MODE_XGMII) { -+ err = phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET, -+ memac->phy_if); -+ if (err) { -+ dev_err_probe(mac_dev->dev, err, -+ "could not set serdes mode to %s\n", -+ phy_modes(memac->phy_if)); -+ goto _return_phy_power_off; -+ } -+ } -+ } -+ - if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) { - struct phy_device *phy; - - err = of_phy_register_fixed_link(mac_node); - if (err) -- goto _return_fm_mac_free; -+ goto _return_phy_power_off; - - fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL); - if (!fixed_link) { - err = -ENOMEM; -- goto _return_fm_mac_free; -+ goto _return_phy_power_off; - } - - mac_dev->phy_node = of_node_get(mac_node); -@@ -1242,6 +1283,10 @@ int memac_initialization(struct mac_devi - - goto _return; - -+_return_phy_power_off: -+ phy_power_off(memac->serdes); -+_return_phy_exit: -+ phy_exit(memac->serdes); - _return_fixed_link_free: - kfree(fixed_link); - _return_fm_mac_free: diff --git a/target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch b/target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch deleted file mode 100644 index 873debc0807e99..00000000000000 --- a/target/linux/generic/backport-6.1/715-02-v6.2-net-fman-memac-Use-lynx-pcs-driver.patch +++ /dev/null @@ -1,384 +0,0 @@ -From fe60e7154d3a35af975c5e6570d6ec31aab9a731 Mon Sep 17 00:00:00 2001 -From: Sean Anderson -Date: Mon, 17 Oct 2022 16:22:37 -0400 -Subject: [PATCH 02/21] net: fman: memac: Use lynx pcs driver - -Although not stated in the datasheet, as far as I can tell PCS for mEMACs -is a "Lynx." By reusing the existing driver, we can remove the PCS -management code from the memac driver. This requires calling some PCS -functions manually which phylink would usually do for us, but we will let -it do that soon. - -One problem is that we don't actually have a PCS for QSGMII. We pretend -that each mEMAC's MDIO bus has four QSGMII PCSs, but this is not the case. -Only the "base" mEMAC's MDIO bus has the four QSGMII PCSs. This is not an -issue yet, because we never get the PCS state. However, it will be once the -conversion to phylink is complete, since the links will appear to never -come up. To get around this, we allow specifying multiple PCSs in pcsphy. -This breaks backwards compatibility with old device trees, but only for -QSGMII. IMO this is the only reasonable way to figure out what the actual -QSGMII PCS is. - -Additionally, we now also support a separate XFI PCS. This can allow the -SerDes driver to set different addresses for the SGMII and XFI PCSs so they -can be accessed at the same time. - -Signed-off-by: Sean Anderson -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/freescale/fman/Kconfig | 3 + - .../net/ethernet/freescale/fman/fman_memac.c | 258 +++++++----------- - 2 files changed, 105 insertions(+), 156 deletions(-) - ---- a/drivers/net/ethernet/freescale/fman/Kconfig -+++ b/drivers/net/ethernet/freescale/fman/Kconfig -@@ -4,6 +4,9 @@ config FSL_FMAN - depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST - select GENERIC_ALLOCATOR - select PHYLIB -+ select PHYLINK -+ select PCS -+ select PCS_LYNX - select CRC32 - default n - help ---- a/drivers/net/ethernet/freescale/fman/fman_memac.c -+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c -@@ -11,43 +11,12 @@ - - #include - #include -+#include - #include - #include - #include - #include - --/* PCS registers */ --#define MDIO_SGMII_CR 0x00 --#define MDIO_SGMII_DEV_ABIL_SGMII 0x04 --#define MDIO_SGMII_LINK_TMR_L 0x12 --#define MDIO_SGMII_LINK_TMR_H 0x13 --#define MDIO_SGMII_IF_MODE 0x14 -- --/* SGMII Control defines */ --#define SGMII_CR_AN_EN 0x1000 --#define SGMII_CR_RESTART_AN 0x0200 --#define SGMII_CR_FD 0x0100 --#define SGMII_CR_SPEED_SEL1_1G 0x0040 --#define SGMII_CR_DEF_VAL (SGMII_CR_AN_EN | SGMII_CR_FD | \ -- SGMII_CR_SPEED_SEL1_1G) -- --/* SGMII Device Ability for SGMII defines */ --#define MDIO_SGMII_DEV_ABIL_SGMII_MODE 0x4001 --#define MDIO_SGMII_DEV_ABIL_BASEX_MODE 0x01A0 -- --/* Link timer define */ --#define LINK_TMR_L 0xa120 --#define LINK_TMR_H 0x0007 --#define LINK_TMR_L_BASEX 0xaf08 --#define LINK_TMR_H_BASEX 0x002f -- --/* SGMII IF Mode defines */ --#define IF_MODE_USE_SGMII_AN 0x0002 --#define IF_MODE_SGMII_EN 0x0001 --#define IF_MODE_SGMII_SPEED_100M 0x0004 --#define IF_MODE_SGMII_SPEED_1G 0x0008 --#define IF_MODE_SGMII_DUPLEX_HALF 0x0010 -- - /* Num of additional exact match MAC adr regs */ - #define MEMAC_NUM_OF_PADDRS 7 - -@@ -326,7 +295,9 @@ struct fman_mac { - struct fman_rev_info fm_rev_info; - bool basex_if; - struct phy *serdes; -- struct phy_device *pcsphy; -+ struct phylink_pcs *sgmii_pcs; -+ struct phylink_pcs *qsgmii_pcs; -+ struct phylink_pcs *xfi_pcs; - bool allmulti_enabled; - }; - -@@ -487,91 +458,22 @@ static u32 get_mac_addr_hash_code(u64 et - return xor_val; - } - --static void setup_sgmii_internal_phy(struct fman_mac *memac, -- struct fixed_phy_status *fixed_link) --{ -- u16 tmp_reg16; -- -- if (WARN_ON(!memac->pcsphy)) -- return; -- -- /* SGMII mode */ -- tmp_reg16 = IF_MODE_SGMII_EN; -- if (!fixed_link) -- /* AN enable */ -- tmp_reg16 |= IF_MODE_USE_SGMII_AN; -- else { -- switch (fixed_link->speed) { -- case 10: -- /* For 10M: IF_MODE[SPEED_10M] = 0 */ -- break; -- case 100: -- tmp_reg16 |= IF_MODE_SGMII_SPEED_100M; -- break; -- case 1000: -- default: -- tmp_reg16 |= IF_MODE_SGMII_SPEED_1G; -- break; -- } -- if (!fixed_link->duplex) -- tmp_reg16 |= IF_MODE_SGMII_DUPLEX_HALF; -- } -- phy_write(memac->pcsphy, MDIO_SGMII_IF_MODE, tmp_reg16); -- -- /* Device ability according to SGMII specification */ -- tmp_reg16 = MDIO_SGMII_DEV_ABIL_SGMII_MODE; -- phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16); -- -- /* Adjust link timer for SGMII - -- * According to Cisco SGMII specification the timer should be 1.6 ms. -- * The link_timer register is configured in units of the clock. -- * - When running as 1G SGMII, Serdes clock is 125 MHz, so -- * unit = 1 / (125*10^6 Hz) = 8 ns. -- * 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2*10^5 = 0x30d40 -- * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so -- * unit = 1 / (312.5*10^6 Hz) = 3.2 ns. -- * 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5*10^5 = 0x7a120. -- * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, -- * we always set up here a value of 2.5 SGMII. -- */ -- phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H); -- phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L); -- -- if (!fixed_link) -- /* Restart AN */ -- tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN; -+static void setup_sgmii_internal(struct fman_mac *memac, -+ struct phylink_pcs *pcs, -+ struct fixed_phy_status *fixed_link) -+{ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); -+ phy_interface_t iface = memac->basex_if ? PHY_INTERFACE_MODE_1000BASEX : -+ PHY_INTERFACE_MODE_SGMII; -+ unsigned int mode = fixed_link ? MLO_AN_FIXED : MLO_AN_INBAND; -+ -+ linkmode_set_pause(advertising, true, true); -+ pcs->ops->pcs_config(pcs, mode, iface, advertising, true); -+ if (fixed_link) -+ pcs->ops->pcs_link_up(pcs, mode, iface, fixed_link->speed, -+ fixed_link->duplex); - else -- /* AN disabled */ -- tmp_reg16 = SGMII_CR_DEF_VAL & ~SGMII_CR_AN_EN; -- phy_write(memac->pcsphy, 0x0, tmp_reg16); --} -- --static void setup_sgmii_internal_phy_base_x(struct fman_mac *memac) --{ -- u16 tmp_reg16; -- -- /* AN Device capability */ -- tmp_reg16 = MDIO_SGMII_DEV_ABIL_BASEX_MODE; -- phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16); -- -- /* Adjust link timer for SGMII - -- * For Serdes 1000BaseX auto-negotiation the timer should be 10 ms. -- * The link_timer register is configured in units of the clock. -- * - When running as 1G SGMII, Serdes clock is 125 MHz, so -- * unit = 1 / (125*10^6 Hz) = 8 ns. -- * 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0 -- * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so -- * unit = 1 / (312.5*10^6 Hz) = 3.2 ns. -- * 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08. -- * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, -- * we always set up here a value of 2.5 SGMII. -- */ -- phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H_BASEX); -- phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L_BASEX); -- -- /* Restart AN */ -- tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN; -- phy_write(memac->pcsphy, 0x0, tmp_reg16); -+ pcs->ops->pcs_an_restart(pcs); - } - - static int check_init_parameters(struct fman_mac *memac) -@@ -983,7 +885,6 @@ static int memac_set_exception(struct fm - static int memac_init(struct fman_mac *memac) - { - struct memac_cfg *memac_drv_param; -- u8 i; - enet_addr_t eth_addr; - bool slow_10g_if = false; - struct fixed_phy_status *fixed_link = NULL; -@@ -1036,32 +937,10 @@ static int memac_init(struct fman_mac *m - iowrite32be(reg32, &memac->regs->command_config); - } - -- if (memac->phy_if == PHY_INTERFACE_MODE_SGMII) { -- /* Configure internal SGMII PHY */ -- if (memac->basex_if) -- setup_sgmii_internal_phy_base_x(memac); -- else -- setup_sgmii_internal_phy(memac, fixed_link); -- } else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII) { -- /* Configure 4 internal SGMII PHYs */ -- for (i = 0; i < 4; i++) { -- u8 qsmgii_phy_addr, phy_addr; -- /* QSGMII PHY address occupies 3 upper bits of 5-bit -- * phy_address; the lower 2 bits are used to extend -- * register address space and access each one of 4 -- * ports inside QSGMII. -- */ -- phy_addr = memac->pcsphy->mdio.addr; -- qsmgii_phy_addr = (u8)((phy_addr << 2) | i); -- memac->pcsphy->mdio.addr = qsmgii_phy_addr; -- if (memac->basex_if) -- setup_sgmii_internal_phy_base_x(memac); -- else -- setup_sgmii_internal_phy(memac, fixed_link); -- -- memac->pcsphy->mdio.addr = phy_addr; -- } -- } -+ if (memac->phy_if == PHY_INTERFACE_MODE_SGMII) -+ setup_sgmii_internal(memac, memac->sgmii_pcs, fixed_link); -+ else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII) -+ setup_sgmii_internal(memac, memac->qsgmii_pcs, fixed_link); - - /* Max Frame Length */ - err = fman_set_mac_max_frame(memac->fm, memac->mac_id, -@@ -1097,12 +976,25 @@ static int memac_init(struct fman_mac *m - return 0; - } - -+static void pcs_put(struct phylink_pcs *pcs) -+{ -+ struct mdio_device *mdiodev; -+ -+ if (IS_ERR_OR_NULL(pcs)) -+ return; -+ -+ mdiodev = lynx_get_mdio_device(pcs); -+ lynx_pcs_destroy(pcs); -+ mdio_device_free(mdiodev); -+} -+ - static int memac_free(struct fman_mac *memac) - { - free_init_resources(memac); - -- if (memac->pcsphy) -- put_device(&memac->pcsphy->mdio.dev); -+ pcs_put(memac->sgmii_pcs); -+ pcs_put(memac->qsgmii_pcs); -+ pcs_put(memac->xfi_pcs); - - kfree(memac->memac_drv_param); - kfree(memac); -@@ -1153,12 +1045,31 @@ static struct fman_mac *memac_config(str - return memac; - } - -+static struct phylink_pcs *memac_pcs_create(struct device_node *mac_node, -+ int index) -+{ -+ struct device_node *node; -+ struct mdio_device *mdiodev = NULL; -+ struct phylink_pcs *pcs; -+ -+ node = of_parse_phandle(mac_node, "pcsphy-handle", index); -+ if (node && of_device_is_available(node)) -+ mdiodev = of_mdio_find_device(node); -+ of_node_put(node); -+ -+ if (!mdiodev) -+ return ERR_PTR(-EPROBE_DEFER); -+ -+ pcs = lynx_pcs_create(mdiodev); -+ return pcs; -+} -+ - int memac_initialization(struct mac_device *mac_dev, - struct device_node *mac_node, - struct fman_mac_params *params) - { - int err; -- struct device_node *phy_node; -+ struct phylink_pcs *pcs; - struct fixed_phy_status *fixed_link; - struct fman_mac *memac; - -@@ -1188,23 +1099,58 @@ int memac_initialization(struct mac_devi - memac = mac_dev->fman_mac; - memac->memac_drv_param->max_frame_length = fman_get_max_frm(); - memac->memac_drv_param->reset_on_init = true; -- if (memac->phy_if == PHY_INTERFACE_MODE_SGMII || -- memac->phy_if == PHY_INTERFACE_MODE_QSGMII) { -- phy_node = of_parse_phandle(mac_node, "pcsphy-handle", 0); -- if (!phy_node) { -- pr_err("PCS PHY node is not available\n"); -- err = -EINVAL; -+ -+ err = of_property_match_string(mac_node, "pcs-handle-names", "xfi"); -+ if (err >= 0) { -+ memac->xfi_pcs = memac_pcs_create(mac_node, err); -+ if (IS_ERR(memac->xfi_pcs)) { -+ err = PTR_ERR(memac->xfi_pcs); -+ dev_err_probe(mac_dev->dev, err, "missing xfi pcs\n"); - goto _return_fm_mac_free; - } -+ } else if (err != -EINVAL && err != -ENODATA) { -+ goto _return_fm_mac_free; -+ } - -- memac->pcsphy = of_phy_find_device(phy_node); -- if (!memac->pcsphy) { -- pr_err("of_phy_find_device (PCS PHY) failed\n"); -- err = -EINVAL; -+ err = of_property_match_string(mac_node, "pcs-handle-names", "qsgmii"); -+ if (err >= 0) { -+ memac->qsgmii_pcs = memac_pcs_create(mac_node, err); -+ if (IS_ERR(memac->qsgmii_pcs)) { -+ err = PTR_ERR(memac->qsgmii_pcs); -+ dev_err_probe(mac_dev->dev, err, -+ "missing qsgmii pcs\n"); - goto _return_fm_mac_free; - } -+ } else if (err != -EINVAL && err != -ENODATA) { -+ goto _return_fm_mac_free; -+ } -+ -+ /* For compatibility, if pcs-handle-names is missing, we assume this -+ * phy is the first one in pcsphy-handle -+ */ -+ err = of_property_match_string(mac_node, "pcs-handle-names", "sgmii"); -+ if (err == -EINVAL || err == -ENODATA) -+ pcs = memac_pcs_create(mac_node, 0); -+ else if (err < 0) -+ goto _return_fm_mac_free; -+ else -+ pcs = memac_pcs_create(mac_node, err); -+ -+ if (!pcs) { -+ dev_err(mac_dev->dev, "missing pcs\n"); -+ err = -ENOENT; -+ goto _return_fm_mac_free; - } - -+ /* If err is set here, it means that pcs-handle-names was missing above -+ * (and therefore that xfi_pcs cannot be set). If we are defaulting to -+ * XGMII, assume this is for XFI. Otherwise, assume it is for SGMII. -+ */ -+ if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) -+ memac->xfi_pcs = pcs; -+ else -+ memac->sgmii_pcs = pcs; -+ - memac->serdes = devm_of_phy_get(mac_dev->dev, mac_node, "serdes"); - err = PTR_ERR(memac->serdes); - if (err == -ENODEV || err == -ENOSYS) { diff --git a/target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch b/target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch deleted file mode 100644 index 63b651bb2dd309..00000000000000 --- a/target/linux/generic/backport-6.1/715-03-v6.2-net-dpaa-Convert-to-phylink.patch +++ /dev/null @@ -1,2451 +0,0 @@ -From 38e50fc3d43882a43115b4f1ca3eb88255163c5b Mon Sep 17 00:00:00 2001 -From: Sean Anderson -Date: Mon, 17 Oct 2022 16:22:38 -0400 -Subject: [PATCH 03/21] net: dpaa: Convert to phylink - -This converts DPAA to phylink. All macs are converted. This should work -with no device tree modifications (including those made in this series), -except for QSGMII (as noted previously). - -The mEMAC configuration is one of the tricker areas. I have tried to -capture all the restrictions across the various models. Most of the time, -we assume that if the serdes supports a mode or the phy-interface-mode -specifies it, then we support it. The only place we can't do this is -(RG)MII, since there's no serdes. In that case, we rely on a (new) -devicetree property. There are also several cases where half-duplex is -broken. Unfortunately, only a single compatible is used for the MAC, so we -have to use the board compatible instead. - -The 10GEC conversion is very straightforward, since it only supports XAUI. -There is generally nothing to configure. - -The dTSEC conversion is broadly similar to mEMAC, but is simpler because we -don't support configuring the SerDes (though this can be easily added) and -we don't have multiple PCSs. From what I can tell, there's nothing -different in the driver or documentation between SGMII and 1000BASE-X -except for the advertising. Similarly, I couldn't find anything about -2500BASE-X. In both cases, I treat them like SGMII. These modes aren't used -by any in-tree boards. Similarly, despite being mentioned in the driver, I -couldn't find any documented SoCs which supported QSGMII. I have left it -unimplemented for now. - -Signed-off-by: Sean Anderson -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/freescale/dpaa/Kconfig | 4 +- - .../net/ethernet/freescale/dpaa/dpaa_eth.c | 89 +-- - .../ethernet/freescale/dpaa/dpaa_ethtool.c | 90 +-- - drivers/net/ethernet/freescale/fman/Kconfig | 1 - - .../net/ethernet/freescale/fman/fman_dtsec.c | 458 +++++++-------- - .../net/ethernet/freescale/fman/fman_mac.h | 10 - - .../net/ethernet/freescale/fman/fman_memac.c | 547 +++++++++--------- - .../net/ethernet/freescale/fman/fman_tgec.c | 131 ++--- - drivers/net/ethernet/freescale/fman/mac.c | 168 +----- - drivers/net/ethernet/freescale/fman/mac.h | 23 +- - 10 files changed, 612 insertions(+), 909 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa/Kconfig -+++ b/drivers/net/ethernet/freescale/dpaa/Kconfig -@@ -2,8 +2,8 @@ - menuconfig FSL_DPAA_ETH - tristate "DPAA Ethernet" - depends on FSL_DPAA && FSL_FMAN -- select PHYLIB -- select FIXED_PHY -+ select PHYLINK -+ select PCS_LYNX - help - Data Path Acceleration Architecture Ethernet driver, - supporting the Freescale QorIQ chips. ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -264,8 +264,19 @@ static int dpaa_netdev_init(struct net_d - net_dev->needed_headroom = priv->tx_headroom; - net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout); - -- mac_dev->net_dev = net_dev; -+ /* The rest of the config is filled in by the mac device already */ -+ mac_dev->phylink_config.dev = &net_dev->dev; -+ mac_dev->phylink_config.type = PHYLINK_NETDEV; - mac_dev->update_speed = dpaa_eth_cgr_set_speed; -+ mac_dev->phylink = phylink_create(&mac_dev->phylink_config, -+ dev_fwnode(mac_dev->dev), -+ mac_dev->phy_if, -+ mac_dev->phylink_ops); -+ if (IS_ERR(mac_dev->phylink)) { -+ err = PTR_ERR(mac_dev->phylink); -+ dev_err_probe(dev, err, "Could not create phylink\n"); -+ return err; -+ } - - /* start without the RUNNING flag, phylib controls it later */ - netif_carrier_off(net_dev); -@@ -273,6 +284,7 @@ static int dpaa_netdev_init(struct net_d - err = register_netdev(net_dev); - if (err < 0) { - dev_err(dev, "register_netdev() = %d\n", err); -+ phylink_destroy(mac_dev->phylink); - return err; - } - -@@ -295,8 +307,7 @@ static int dpaa_stop(struct net_device * - */ - msleep(200); - -- if (mac_dev->phy_dev) -- phy_stop(mac_dev->phy_dev); -+ phylink_stop(mac_dev->phylink); - mac_dev->disable(mac_dev->fman_mac); - - for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) { -@@ -305,8 +316,7 @@ static int dpaa_stop(struct net_device * - err = error; - } - -- if (net_dev->phydev) -- phy_disconnect(net_dev->phydev); -+ phylink_disconnect_phy(mac_dev->phylink); - net_dev->phydev = NULL; - - msleep(200); -@@ -834,10 +844,10 @@ static int dpaa_eth_cgr_init(struct dpaa - - /* Set different thresholds based on the configured MAC speed. - * This may turn suboptimal if the MAC is reconfigured at another -- * speed, so MACs must call dpaa_eth_cgr_set_speed in their adjust_link -+ * speed, so MACs must call dpaa_eth_cgr_set_speed in their link_up - * callback. - */ -- if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full) -+ if (priv->mac_dev->phylink_config.mac_capabilities & MAC_10000FD) - cs_th = DPAA_CS_THRESHOLD_10G; - else - cs_th = DPAA_CS_THRESHOLD_1G; -@@ -866,7 +876,7 @@ out_error: - - static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed) - { -- struct net_device *net_dev = mac_dev->net_dev; -+ struct net_device *net_dev = to_net_dev(mac_dev->phylink_config.dev); - struct dpaa_priv *priv = netdev_priv(net_dev); - struct qm_mcc_initcgr opts = { }; - u32 cs_th; -@@ -2905,58 +2915,6 @@ static void dpaa_eth_napi_disable(struct - } - } - --static void dpaa_adjust_link(struct net_device *net_dev) --{ -- struct mac_device *mac_dev; -- struct dpaa_priv *priv; -- -- priv = netdev_priv(net_dev); -- mac_dev = priv->mac_dev; -- mac_dev->adjust_link(mac_dev); --} -- --/* The Aquantia PHYs are capable of performing rate adaptation */ --#define PHY_VEND_AQUANTIA 0x03a1b400 --#define PHY_VEND_AQUANTIA2 0x31c31c00 -- --static int dpaa_phy_init(struct net_device *net_dev) --{ -- __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -- struct mac_device *mac_dev; -- struct phy_device *phy_dev; -- struct dpaa_priv *priv; -- u32 phy_vendor; -- -- priv = netdev_priv(net_dev); -- mac_dev = priv->mac_dev; -- -- phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, -- &dpaa_adjust_link, 0, -- mac_dev->phy_if); -- if (!phy_dev) { -- netif_err(priv, ifup, net_dev, "init_phy() failed\n"); -- return -ENODEV; -- } -- -- phy_vendor = phy_dev->drv->phy_id & GENMASK(31, 10); -- /* Unless the PHY is capable of rate adaptation */ -- if (mac_dev->phy_if != PHY_INTERFACE_MODE_XGMII || -- (phy_vendor != PHY_VEND_AQUANTIA && -- phy_vendor != PHY_VEND_AQUANTIA2)) { -- /* remove any features not supported by the controller */ -- ethtool_convert_legacy_u32_to_link_mode(mask, -- mac_dev->if_support); -- linkmode_and(phy_dev->supported, phy_dev->supported, mask); -- } -- -- phy_support_asym_pause(phy_dev); -- -- mac_dev->phy_dev = phy_dev; -- net_dev->phydev = phy_dev; -- -- return 0; --} -- - static int dpaa_open(struct net_device *net_dev) - { - struct mac_device *mac_dev; -@@ -2967,7 +2925,8 @@ static int dpaa_open(struct net_device * - mac_dev = priv->mac_dev; - dpaa_eth_napi_enable(priv); - -- err = dpaa_phy_init(net_dev); -+ err = phylink_of_phy_connect(mac_dev->phylink, -+ mac_dev->dev->of_node, 0); - if (err) - goto phy_init_failed; - -@@ -2982,7 +2941,7 @@ static int dpaa_open(struct net_device * - netif_err(priv, ifup, net_dev, "mac_dev->enable() = %d\n", err); - goto mac_start_failed; - } -- phy_start(priv->mac_dev->phy_dev); -+ phylink_start(mac_dev->phylink); - - netif_tx_start_all_queues(net_dev); - -@@ -2991,6 +2950,7 @@ static int dpaa_open(struct net_device * - mac_start_failed: - for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) - fman_port_disable(mac_dev->port[i]); -+ phylink_disconnect_phy(mac_dev->phylink); - - phy_init_failed: - dpaa_eth_napi_disable(priv); -@@ -3146,10 +3106,12 @@ static int dpaa_ts_ioctl(struct net_devi - static int dpaa_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd) - { - int ret = -EINVAL; -+ struct dpaa_priv *priv = netdev_priv(net_dev); - - if (cmd == SIOCGMIIREG) { - if (net_dev->phydev) -- return phy_mii_ioctl(net_dev->phydev, rq, cmd); -+ return phylink_mii_ioctl(priv->mac_dev->phylink, rq, -+ cmd); - } - - if (cmd == SIOCSHWTSTAMP) -@@ -3552,6 +3514,7 @@ static int dpaa_remove(struct platform_d - - dev_set_drvdata(dev, NULL); - unregister_netdev(net_dev); -+ phylink_destroy(priv->mac_dev->phylink); - - err = dpaa_fq_free(dev, &priv->dpaa_fq_list); - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c -@@ -54,27 +54,19 @@ static char dpaa_stats_global[][ETH_GSTR - static int dpaa_get_link_ksettings(struct net_device *net_dev, - struct ethtool_link_ksettings *cmd) - { -- if (!net_dev->phydev) -- return 0; -+ struct dpaa_priv *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; - -- phy_ethtool_ksettings_get(net_dev->phydev, cmd); -- -- return 0; -+ return phylink_ethtool_ksettings_get(mac_dev->phylink, cmd); - } - - static int dpaa_set_link_ksettings(struct net_device *net_dev, - const struct ethtool_link_ksettings *cmd) - { -- int err; -- -- if (!net_dev->phydev) -- return -ENODEV; -+ struct dpaa_priv *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; - -- err = phy_ethtool_ksettings_set(net_dev->phydev, cmd); -- if (err < 0) -- netdev_err(net_dev, "phy_ethtool_ksettings_set() = %d\n", err); -- -- return err; -+ return phylink_ethtool_ksettings_set(mac_dev->phylink, cmd); - } - - static void dpaa_get_drvinfo(struct net_device *net_dev, -@@ -99,80 +91,28 @@ static void dpaa_set_msglevel(struct net - - static int dpaa_nway_reset(struct net_device *net_dev) - { -- int err; -- -- if (!net_dev->phydev) -- return -ENODEV; -+ struct dpaa_priv *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; - -- err = 0; -- if (net_dev->phydev->autoneg) { -- err = phy_start_aneg(net_dev->phydev); -- if (err < 0) -- netdev_err(net_dev, "phy_start_aneg() = %d\n", -- err); -- } -- -- return err; -+ return phylink_ethtool_nway_reset(mac_dev->phylink); - } - - static void dpaa_get_pauseparam(struct net_device *net_dev, - struct ethtool_pauseparam *epause) - { -- struct mac_device *mac_dev; -- struct dpaa_priv *priv; -- -- priv = netdev_priv(net_dev); -- mac_dev = priv->mac_dev; -- -- if (!net_dev->phydev) -- return; -+ struct dpaa_priv *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; - -- epause->autoneg = mac_dev->autoneg_pause; -- epause->rx_pause = mac_dev->rx_pause_active; -- epause->tx_pause = mac_dev->tx_pause_active; -+ phylink_ethtool_get_pauseparam(mac_dev->phylink, epause); - } - - static int dpaa_set_pauseparam(struct net_device *net_dev, - struct ethtool_pauseparam *epause) - { -- struct mac_device *mac_dev; -- struct phy_device *phydev; -- bool rx_pause, tx_pause; -- struct dpaa_priv *priv; -- int err; -- -- priv = netdev_priv(net_dev); -- mac_dev = priv->mac_dev; -- -- phydev = net_dev->phydev; -- if (!phydev) { -- netdev_err(net_dev, "phy device not initialized\n"); -- return -ENODEV; -- } -- -- if (!phy_validate_pause(phydev, epause)) -- return -EINVAL; -- -- /* The MAC should know how to handle PAUSE frame autonegotiation before -- * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE -- * settings. -- */ -- mac_dev->autoneg_pause = !!epause->autoneg; -- mac_dev->rx_pause_req = !!epause->rx_pause; -- mac_dev->tx_pause_req = !!epause->tx_pause; -- -- /* Determine the sym/asym advertised PAUSE capabilities from the desired -- * rx/tx pause settings. -- */ -- -- phy_set_asym_pause(phydev, epause->rx_pause, epause->tx_pause); -- -- fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause); -- err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause); -- if (err < 0) -- netdev_err(net_dev, "set_mac_active_pause() = %d\n", err); -+ struct dpaa_priv *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; - -- return err; -+ return phylink_ethtool_set_pauseparam(mac_dev->phylink, epause); - } - - static int dpaa_get_sset_count(struct net_device *net_dev, int type) ---- a/drivers/net/ethernet/freescale/fman/Kconfig -+++ b/drivers/net/ethernet/freescale/fman/Kconfig -@@ -3,7 +3,6 @@ config FSL_FMAN - tristate "FMan support" - depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST - select GENERIC_ALLOCATOR -- select PHYLIB - select PHYLINK - select PCS - select PCS_LYNX ---- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c -+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - /* TBI register addresses */ - #define MII_TBICON 0x11 -@@ -29,9 +30,6 @@ - #define TBICON_CLK_SELECT 0x0020 /* Clock select */ - #define TBICON_MI_MODE 0x0010 /* GMII mode (TBI if not set) */ - --#define TBIANA_SGMII 0x4001 --#define TBIANA_1000X 0x01a0 -- - /* Interrupt Mask Register (IMASK) */ - #define DTSEC_IMASK_BREN 0x80000000 - #define DTSEC_IMASK_RXCEN 0x40000000 -@@ -92,9 +90,10 @@ - - #define DTSEC_ECNTRL_GMIIM 0x00000040 - #define DTSEC_ECNTRL_TBIM 0x00000020 --#define DTSEC_ECNTRL_SGMIIM 0x00000002 - #define DTSEC_ECNTRL_RPM 0x00000010 - #define DTSEC_ECNTRL_R100M 0x00000008 -+#define DTSEC_ECNTRL_RMM 0x00000004 -+#define DTSEC_ECNTRL_SGMIIM 0x00000002 - #define DTSEC_ECNTRL_QSGMIIM 0x00000001 - - #define TCTRL_TTSE 0x00000040 -@@ -318,7 +317,8 @@ struct fman_mac { - void *fm; - struct fman_rev_info fm_rev_info; - bool basex_if; -- struct phy_device *tbiphy; -+ struct mdio_device *tbidev; -+ struct phylink_pcs pcs; - }; - - static void set_dflts(struct dtsec_cfg *cfg) -@@ -356,56 +356,14 @@ static int init(struct dtsec_regs __iome - phy_interface_t iface, u16 iface_speed, u64 addr, - u32 exception_mask, u8 tbi_addr) - { -- bool is_rgmii, is_sgmii, is_qsgmii; - enet_addr_t eth_addr; -- u32 tmp; -+ u32 tmp = 0; - int i; - - /* Soft reset */ - iowrite32be(MACCFG1_SOFT_RESET, ®s->maccfg1); - iowrite32be(0, ®s->maccfg1); - -- /* dtsec_id2 */ -- tmp = ioread32be(®s->tsec_id2); -- -- /* check RGMII support */ -- if (iface == PHY_INTERFACE_MODE_RGMII || -- iface == PHY_INTERFACE_MODE_RGMII_ID || -- iface == PHY_INTERFACE_MODE_RGMII_RXID || -- iface == PHY_INTERFACE_MODE_RGMII_TXID || -- iface == PHY_INTERFACE_MODE_RMII) -- if (tmp & DTSEC_ID2_INT_REDUCED_OFF) -- return -EINVAL; -- -- if (iface == PHY_INTERFACE_MODE_SGMII || -- iface == PHY_INTERFACE_MODE_MII) -- if (tmp & DTSEC_ID2_INT_REDUCED_OFF) -- return -EINVAL; -- -- is_rgmii = iface == PHY_INTERFACE_MODE_RGMII || -- iface == PHY_INTERFACE_MODE_RGMII_ID || -- iface == PHY_INTERFACE_MODE_RGMII_RXID || -- iface == PHY_INTERFACE_MODE_RGMII_TXID; -- is_sgmii = iface == PHY_INTERFACE_MODE_SGMII; -- is_qsgmii = iface == PHY_INTERFACE_MODE_QSGMII; -- -- tmp = 0; -- if (is_rgmii || iface == PHY_INTERFACE_MODE_GMII) -- tmp |= DTSEC_ECNTRL_GMIIM; -- if (is_sgmii) -- tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM); -- if (is_qsgmii) -- tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM | -- DTSEC_ECNTRL_QSGMIIM); -- if (is_rgmii) -- tmp |= DTSEC_ECNTRL_RPM; -- if (iface_speed == SPEED_100) -- tmp |= DTSEC_ECNTRL_R100M; -- -- iowrite32be(tmp, ®s->ecntrl); -- -- tmp = 0; -- - if (cfg->tx_pause_time) - tmp |= cfg->tx_pause_time; - if (cfg->tx_pause_time_extd) -@@ -446,17 +404,10 @@ static int init(struct dtsec_regs __iome - - tmp = 0; - -- if (iface_speed < SPEED_1000) -- tmp |= MACCFG2_NIBBLE_MODE; -- else if (iface_speed == SPEED_1000) -- tmp |= MACCFG2_BYTE_MODE; -- - tmp |= (cfg->preamble_len << MACCFG2_PREAMBLE_LENGTH_SHIFT) & - MACCFG2_PREAMBLE_LENGTH_MASK; - if (cfg->tx_pad_crc) - tmp |= MACCFG2_PAD_CRC_EN; -- /* Full Duplex */ -- tmp |= MACCFG2_FULL_DUPLEX; - iowrite32be(tmp, ®s->maccfg2); - - tmp = (((cfg->non_back_to_back_ipg1 << -@@ -525,10 +476,6 @@ static void set_bucket(struct dtsec_regs - - static int check_init_parameters(struct fman_mac *dtsec) - { -- if (dtsec->max_speed >= SPEED_10000) { -- pr_err("1G MAC driver supports 1G or lower speeds\n"); -- return -EINVAL; -- } - if ((dtsec->dtsec_drv_param)->rx_prepend > - MAX_PACKET_ALIGNMENT) { - pr_err("packetAlignmentPadding can't be > than %d\n", -@@ -630,22 +577,10 @@ static int get_exception_flag(enum fman_ - return bit_mask; - } - --static bool is_init_done(struct dtsec_cfg *dtsec_drv_params) --{ -- /* Checks if dTSEC driver parameters were initialized */ -- if (!dtsec_drv_params) -- return true; -- -- return false; --} -- - static u16 dtsec_get_max_frame_length(struct fman_mac *dtsec) - { - struct dtsec_regs __iomem *regs = dtsec->regs; - -- if (is_init_done(dtsec->dtsec_drv_param)) -- return 0; -- - return (u16)ioread32be(®s->maxfrm); - } - -@@ -682,6 +617,7 @@ static void dtsec_isr(void *handle) - dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_COL_RET_LMT); - if (event & DTSEC_IMASK_XFUNEN) { - /* FM_TX_LOCKUP_ERRATA_DTSEC6 Errata workaround */ -+ /* FIXME: This races with the rest of the driver! */ - if (dtsec->fm_rev_info.major == 2) { - u32 tpkt1, tmp_reg1, tpkt2, tmp_reg2, i; - /* a. Write 0x00E0_0C00 to DTSEC_ID -@@ -814,6 +750,43 @@ static void free_init_resources(struct f - dtsec->unicast_addr_hash = NULL; - } - -+static struct fman_mac *pcs_to_dtsec(struct phylink_pcs *pcs) -+{ -+ return container_of(pcs, struct fman_mac, pcs); -+} -+ -+static void dtsec_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct fman_mac *dtsec = pcs_to_dtsec(pcs); -+ -+ phylink_mii_c22_pcs_get_state(dtsec->tbidev, state); -+} -+ -+static int dtsec_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct fman_mac *dtsec = pcs_to_dtsec(pcs); -+ -+ return phylink_mii_c22_pcs_config(dtsec->tbidev, mode, interface, -+ advertising); -+} -+ -+static void dtsec_pcs_an_restart(struct phylink_pcs *pcs) -+{ -+ struct fman_mac *dtsec = pcs_to_dtsec(pcs); -+ -+ phylink_mii_c22_pcs_an_restart(dtsec->tbidev); -+} -+ -+static const struct phylink_pcs_ops dtsec_pcs_ops = { -+ .pcs_get_state = dtsec_pcs_get_state, -+ .pcs_config = dtsec_pcs_config, -+ .pcs_an_restart = dtsec_pcs_an_restart, -+}; -+ - static void graceful_start(struct fman_mac *dtsec) - { - struct dtsec_regs __iomem *regs = dtsec->regs; -@@ -854,36 +827,11 @@ static void graceful_stop(struct fman_ma - - static int dtsec_enable(struct fman_mac *dtsec) - { -- struct dtsec_regs __iomem *regs = dtsec->regs; -- u32 tmp; -- -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- -- /* Enable */ -- tmp = ioread32be(®s->maccfg1); -- tmp |= MACCFG1_RX_EN | MACCFG1_TX_EN; -- iowrite32be(tmp, ®s->maccfg1); -- -- /* Graceful start - clear the graceful Rx/Tx stop bit */ -- graceful_start(dtsec); -- - return 0; - } - - static void dtsec_disable(struct fman_mac *dtsec) - { -- struct dtsec_regs __iomem *regs = dtsec->regs; -- u32 tmp; -- -- WARN_ON_ONCE(!is_init_done(dtsec->dtsec_drv_param)); -- -- /* Graceful stop - Assert the graceful Rx/Tx stop bit */ -- graceful_stop(dtsec); -- -- tmp = ioread32be(®s->maccfg1); -- tmp &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN); -- iowrite32be(tmp, ®s->maccfg1); - } - - static int dtsec_set_tx_pause_frames(struct fman_mac *dtsec, -@@ -894,11 +842,6 @@ static int dtsec_set_tx_pause_frames(str - struct dtsec_regs __iomem *regs = dtsec->regs; - u32 ptv = 0; - -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- -- graceful_stop(dtsec); -- - if (pause_time) { - /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 Errata workaround */ - if (dtsec->fm_rev_info.major == 2 && pause_time <= 320) { -@@ -919,8 +862,6 @@ static int dtsec_set_tx_pause_frames(str - iowrite32be(ioread32be(®s->maccfg1) & ~MACCFG1_TX_FLOW, - ®s->maccfg1); - -- graceful_start(dtsec); -- - return 0; - } - -@@ -929,11 +870,6 @@ static int dtsec_accept_rx_pause_frames( - struct dtsec_regs __iomem *regs = dtsec->regs; - u32 tmp; - -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- -- graceful_stop(dtsec); -- - tmp = ioread32be(®s->maccfg1); - if (en) - tmp |= MACCFG1_RX_FLOW; -@@ -941,17 +877,125 @@ static int dtsec_accept_rx_pause_frames( - tmp &= ~MACCFG1_RX_FLOW; - iowrite32be(tmp, ®s->maccfg1); - -+ return 0; -+} -+ -+static struct phylink_pcs *dtsec_select_pcs(struct phylink_config *config, -+ phy_interface_t iface) -+{ -+ struct fman_mac *dtsec = fman_config_to_mac(config)->fman_mac; -+ -+ switch (iface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ return &dtsec->pcs; -+ default: -+ return NULL; -+ } -+} -+ -+static void dtsec_mac_config(struct phylink_config *config, unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+ struct mac_device *mac_dev = fman_config_to_mac(config); -+ struct dtsec_regs __iomem *regs = mac_dev->fman_mac->regs; -+ u32 tmp; -+ -+ switch (state->interface) { -+ case PHY_INTERFACE_MODE_RMII: -+ tmp = DTSEC_ECNTRL_RMM; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ tmp = DTSEC_ECNTRL_GMIIM | DTSEC_ECNTRL_RPM; -+ break; -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ tmp = DTSEC_ECNTRL_TBIM | DTSEC_ECNTRL_SGMIIM; -+ break; -+ default: -+ dev_warn(mac_dev->dev, "cannot configure dTSEC for %s\n", -+ phy_modes(state->interface)); -+ return; -+ } -+ -+ iowrite32be(tmp, ®s->ecntrl); -+} -+ -+static void dtsec_link_up(struct phylink_config *config, struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct mac_device *mac_dev = fman_config_to_mac(config); -+ struct fman_mac *dtsec = mac_dev->fman_mac; -+ struct dtsec_regs __iomem *regs = dtsec->regs; -+ u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE : -+ FSL_FM_PAUSE_TIME_DISABLE; -+ u32 tmp; -+ -+ dtsec_set_tx_pause_frames(dtsec, 0, pause_time, 0); -+ dtsec_accept_rx_pause_frames(dtsec, rx_pause); -+ -+ tmp = ioread32be(®s->ecntrl); -+ if (speed == SPEED_100) -+ tmp |= DTSEC_ECNTRL_R100M; -+ else -+ tmp &= ~DTSEC_ECNTRL_R100M; -+ iowrite32be(tmp, ®s->ecntrl); -+ -+ tmp = ioread32be(®s->maccfg2); -+ tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE | MACCFG2_FULL_DUPLEX); -+ if (speed >= SPEED_1000) -+ tmp |= MACCFG2_BYTE_MODE; -+ else -+ tmp |= MACCFG2_NIBBLE_MODE; -+ -+ if (duplex == DUPLEX_FULL) -+ tmp |= MACCFG2_FULL_DUPLEX; -+ -+ iowrite32be(tmp, ®s->maccfg2); -+ -+ mac_dev->update_speed(mac_dev, speed); -+ -+ /* Enable */ -+ tmp = ioread32be(®s->maccfg1); -+ tmp |= MACCFG1_RX_EN | MACCFG1_TX_EN; -+ iowrite32be(tmp, ®s->maccfg1); -+ -+ /* Graceful start - clear the graceful Rx/Tx stop bit */ - graceful_start(dtsec); -+} - -- return 0; -+static void dtsec_link_down(struct phylink_config *config, unsigned int mode, -+ phy_interface_t interface) -+{ -+ struct fman_mac *dtsec = fman_config_to_mac(config)->fman_mac; -+ struct dtsec_regs __iomem *regs = dtsec->regs; -+ u32 tmp; -+ -+ /* Graceful stop - Assert the graceful Rx/Tx stop bit */ -+ graceful_stop(dtsec); -+ -+ tmp = ioread32be(®s->maccfg1); -+ tmp &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN); -+ iowrite32be(tmp, ®s->maccfg1); - } - -+static const struct phylink_mac_ops dtsec_mac_ops = { -+ .validate = phylink_generic_validate, -+ .mac_select_pcs = dtsec_select_pcs, -+ .mac_config = dtsec_mac_config, -+ .mac_link_up = dtsec_link_up, -+ .mac_link_down = dtsec_link_down, -+}; -+ - static int dtsec_modify_mac_address(struct fman_mac *dtsec, - const enet_addr_t *enet_addr) - { -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- - graceful_stop(dtsec); - - /* Initialize MAC Station Address registers (1 & 2) -@@ -975,9 +1019,6 @@ static int dtsec_add_hash_mac_address(st - u32 crc = 0xFFFFFFFF; - bool mcast, ghtx; - -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- - addr = ENET_ADDR_TO_UINT64(*eth_addr); - - ghtx = (bool)((ioread32be(®s->rctrl) & RCTRL_GHTX) ? true : false); -@@ -1037,9 +1078,6 @@ static int dtsec_set_allmulti(struct fma - u32 tmp; - struct dtsec_regs __iomem *regs = dtsec->regs; - -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- - tmp = ioread32be(®s->rctrl); - if (enable) - tmp |= RCTRL_MPROM; -@@ -1056,9 +1094,6 @@ static int dtsec_set_tstamp(struct fman_ - struct dtsec_regs __iomem *regs = dtsec->regs; - u32 rctrl, tctrl; - -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- - rctrl = ioread32be(®s->rctrl); - tctrl = ioread32be(®s->tctrl); - -@@ -1087,9 +1122,6 @@ static int dtsec_del_hash_mac_address(st - u32 crc = 0xFFFFFFFF; - bool mcast, ghtx; - -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- - addr = ENET_ADDR_TO_UINT64(*eth_addr); - - ghtx = (bool)((ioread32be(®s->rctrl) & RCTRL_GHTX) ? true : false); -@@ -1153,9 +1185,6 @@ static int dtsec_set_promiscuous(struct - struct dtsec_regs __iomem *regs = dtsec->regs; - u32 tmp; - -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- - /* Set unicast promiscuous */ - tmp = ioread32be(®s->rctrl); - if (new_val) -@@ -1177,90 +1206,12 @@ static int dtsec_set_promiscuous(struct - return 0; - } - --static int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed) --{ -- struct dtsec_regs __iomem *regs = dtsec->regs; -- u32 tmp; -- -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- -- graceful_stop(dtsec); -- -- tmp = ioread32be(®s->maccfg2); -- -- /* Full Duplex */ -- tmp |= MACCFG2_FULL_DUPLEX; -- -- tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE); -- if (speed < SPEED_1000) -- tmp |= MACCFG2_NIBBLE_MODE; -- else if (speed == SPEED_1000) -- tmp |= MACCFG2_BYTE_MODE; -- iowrite32be(tmp, ®s->maccfg2); -- -- tmp = ioread32be(®s->ecntrl); -- if (speed == SPEED_100) -- tmp |= DTSEC_ECNTRL_R100M; -- else -- tmp &= ~DTSEC_ECNTRL_R100M; -- iowrite32be(tmp, ®s->ecntrl); -- -- graceful_start(dtsec); -- -- return 0; --} -- --static int dtsec_restart_autoneg(struct fman_mac *dtsec) --{ -- u16 tmp_reg16; -- -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- -- tmp_reg16 = phy_read(dtsec->tbiphy, MII_BMCR); -- -- tmp_reg16 &= ~(BMCR_SPEED100 | BMCR_SPEED1000); -- tmp_reg16 |= (BMCR_ANENABLE | BMCR_ANRESTART | -- BMCR_FULLDPLX | BMCR_SPEED1000); -- -- phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16); -- -- return 0; --} -- --static void adjust_link_dtsec(struct mac_device *mac_dev) --{ -- struct phy_device *phy_dev = mac_dev->phy_dev; -- struct fman_mac *fman_mac; -- bool rx_pause, tx_pause; -- int err; -- -- fman_mac = mac_dev->fman_mac; -- if (!phy_dev->link) { -- dtsec_restart_autoneg(fman_mac); -- -- return; -- } -- -- dtsec_adjust_link(fman_mac, phy_dev->speed); -- mac_dev->update_speed(mac_dev, phy_dev->speed); -- fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause); -- err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause); -- if (err < 0) -- dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n", -- err); --} -- - static int dtsec_set_exception(struct fman_mac *dtsec, - enum fman_mac_exceptions exception, bool enable) - { - struct dtsec_regs __iomem *regs = dtsec->regs; - u32 bit_mask = 0; - -- if (!is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- - if (exception != FM_MAC_EX_1G_1588_TS_RX_ERR) { - bit_mask = get_exception_flag(exception); - if (bit_mask) { -@@ -1310,12 +1261,9 @@ static int dtsec_init(struct fman_mac *d - { - struct dtsec_regs __iomem *regs = dtsec->regs; - struct dtsec_cfg *dtsec_drv_param; -- u16 max_frm_ln; -+ u16 max_frm_ln, tbicon; - int err; - -- if (is_init_done(dtsec->dtsec_drv_param)) -- return -EINVAL; -- - if (DEFAULT_RESET_ON_INIT && - (fman_reset_mac(dtsec->fm, dtsec->mac_id) != 0)) { - pr_err("Can't reset MAC!\n"); -@@ -1330,38 +1278,19 @@ static int dtsec_init(struct fman_mac *d - - err = init(dtsec->regs, dtsec_drv_param, dtsec->phy_if, - dtsec->max_speed, dtsec->addr, dtsec->exceptions, -- dtsec->tbiphy->mdio.addr); -+ dtsec->tbidev->addr); - if (err) { - free_init_resources(dtsec); - pr_err("DTSEC version doesn't support this i/f mode\n"); - return err; - } - -- if (dtsec->phy_if == PHY_INTERFACE_MODE_SGMII) { -- u16 tmp_reg16; -- -- /* Configure the TBI PHY Control Register */ -- tmp_reg16 = TBICON_CLK_SELECT | TBICON_SOFT_RESET; -- phy_write(dtsec->tbiphy, MII_TBICON, tmp_reg16); -- -- tmp_reg16 = TBICON_CLK_SELECT; -- phy_write(dtsec->tbiphy, MII_TBICON, tmp_reg16); -- -- tmp_reg16 = (BMCR_RESET | BMCR_ANENABLE | -- BMCR_FULLDPLX | BMCR_SPEED1000); -- phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16); -- -- if (dtsec->basex_if) -- tmp_reg16 = TBIANA_1000X; -- else -- tmp_reg16 = TBIANA_SGMII; -- phy_write(dtsec->tbiphy, MII_ADVERTISE, tmp_reg16); -+ /* Configure the TBI PHY Control Register */ -+ tbicon = TBICON_CLK_SELECT | TBICON_SOFT_RESET; -+ mdiodev_write(dtsec->tbidev, MII_TBICON, tbicon); - -- tmp_reg16 = (BMCR_ANENABLE | BMCR_ANRESTART | -- BMCR_FULLDPLX | BMCR_SPEED1000); -- -- phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16); -- } -+ tbicon = TBICON_CLK_SELECT; -+ mdiodev_write(dtsec->tbidev, MII_TBICON, tbicon); - - /* Max Frame Length */ - max_frm_ln = (u16)ioread32be(®s->maxfrm); -@@ -1406,6 +1335,8 @@ static int dtsec_free(struct fman_mac *d - - kfree(dtsec->dtsec_drv_param); - dtsec->dtsec_drv_param = NULL; -+ if (!IS_ERR_OR_NULL(dtsec->tbidev)) -+ put_device(&dtsec->tbidev->dev); - kfree(dtsec); - - return 0; -@@ -1434,7 +1365,6 @@ static struct fman_mac *dtsec_config(str - - dtsec->regs = mac_dev->vaddr; - dtsec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr); -- dtsec->max_speed = params->max_speed; - dtsec->phy_if = mac_dev->phy_if; - dtsec->mac_id = params->mac_id; - dtsec->exceptions = (DTSEC_IMASK_BREN | -@@ -1457,7 +1387,6 @@ static struct fman_mac *dtsec_config(str - dtsec->en_tsu_err_exception = dtsec->dtsec_drv_param->ptp_exception_en; - - dtsec->fm = params->fm; -- dtsec->basex_if = params->basex_if; - - /* Save FMan revision */ - fman_get_revision(dtsec->fm, &dtsec->fm_rev_info); -@@ -1476,18 +1405,18 @@ int dtsec_initialization(struct mac_devi - int err; - struct fman_mac *dtsec; - struct device_node *phy_node; -+ unsigned long capabilities; -+ unsigned long *supported; - -+ mac_dev->phylink_ops = &dtsec_mac_ops; - mac_dev->set_promisc = dtsec_set_promiscuous; - mac_dev->change_addr = dtsec_modify_mac_address; - mac_dev->add_hash_mac_addr = dtsec_add_hash_mac_address; - mac_dev->remove_hash_mac_addr = dtsec_del_hash_mac_address; -- mac_dev->set_tx_pause = dtsec_set_tx_pause_frames; -- mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames; - mac_dev->set_exception = dtsec_set_exception; - mac_dev->set_allmulti = dtsec_set_allmulti; - mac_dev->set_tstamp = dtsec_set_tstamp; - mac_dev->set_multi = fman_set_multi; -- mac_dev->adjust_link = adjust_link_dtsec; - mac_dev->enable = dtsec_enable; - mac_dev->disable = dtsec_disable; - -@@ -1502,19 +1431,56 @@ int dtsec_initialization(struct mac_devi - dtsec->dtsec_drv_param->tx_pad_crc = true; - - phy_node = of_parse_phandle(mac_node, "tbi-handle", 0); -- if (!phy_node) { -- pr_err("TBI PHY node is not available\n"); -+ if (!phy_node || of_device_is_available(phy_node)) { -+ of_node_put(phy_node); - err = -EINVAL; -+ dev_err_probe(mac_dev->dev, err, -+ "TBI PCS node is not available\n"); - goto _return_fm_mac_free; - } - -- dtsec->tbiphy = of_phy_find_device(phy_node); -- if (!dtsec->tbiphy) { -- pr_err("of_phy_find_device (TBI PHY) failed\n"); -- err = -EINVAL; -+ dtsec->tbidev = of_mdio_find_device(phy_node); -+ of_node_put(phy_node); -+ if (!dtsec->tbidev) { -+ err = -EPROBE_DEFER; -+ dev_err_probe(mac_dev->dev, err, -+ "could not find mdiodev for PCS\n"); - goto _return_fm_mac_free; - } -- put_device(&dtsec->tbiphy->mdio.dev); -+ dtsec->pcs.ops = &dtsec_pcs_ops; -+ dtsec->pcs.poll = true; -+ -+ supported = mac_dev->phylink_config.supported_interfaces; -+ -+ /* FIXME: Can we use DTSEC_ID2_INT_FULL_OFF to determine if these are -+ * supported? If not, we can determine support via the phy if SerDes -+ * support is added. -+ */ -+ if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII || -+ mac_dev->phy_if == PHY_INTERFACE_MODE_1000BASEX) { -+ __set_bit(PHY_INTERFACE_MODE_SGMII, supported); -+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported); -+ } else if (mac_dev->phy_if == PHY_INTERFACE_MODE_2500BASEX) { -+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported); -+ } -+ -+ if (!(ioread32be(&dtsec->regs->tsec_id2) & DTSEC_ID2_INT_REDUCED_OFF)) { -+ phy_interface_set_rgmii(supported); -+ -+ /* DTSEC_ID2_INT_REDUCED_OFF indicates that the dTSEC supports -+ * RMII and RGMII. However, the only SoCs which support RMII -+ * are the P1017 and P1023. Avoid advertising this mode on -+ * other SoCs. This is a bit of a moot point, since there's no -+ * in-tree support for ethernet on these platforms... -+ */ -+ if (of_machine_is_compatible("fsl,P1023") || -+ of_machine_is_compatible("fsl,P1023RDB")) -+ __set_bit(PHY_INTERFACE_MODE_RMII, supported); -+ } -+ -+ capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE; -+ capabilities |= MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD; -+ mac_dev->phylink_config.mac_capabilities = capabilities; - - err = dtsec_init(dtsec); - if (err < 0) ---- a/drivers/net/ethernet/freescale/fman/fman_mac.h -+++ b/drivers/net/ethernet/freescale/fman/fman_mac.h -@@ -170,20 +170,10 @@ struct fman_mac_params { - * 0 - FM_MAX_NUM_OF_10G_MACS - */ - u8 mac_id; -- /* Note that the speed should indicate the maximum rate that -- * this MAC should support rather than the actual speed; -- */ -- u16 max_speed; - /* A handle to the FM object this port related to */ - void *fm; - fman_mac_exception_cb *event_cb; /* MDIO Events Callback Routine */ - fman_mac_exception_cb *exception_cb;/* Exception Callback Routine */ -- /* SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC -- * and phy or backplane; Note: 1000BaseX auto-negotiation relates only -- * to interface between MAC and phy/backplane, SGMII phy can still -- * synchronize with far-end phy at 10Mbps, 100Mbps or 1000Mbps -- */ -- bool basex_if; - }; - - struct eth_hash_t { ---- a/drivers/net/ethernet/freescale/fman/fman_memac.c -+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c -@@ -278,9 +278,6 @@ struct fman_mac { - struct memac_regs __iomem *regs; - /* MAC address of device */ - u64 addr; -- /* Ethernet physical interface */ -- phy_interface_t phy_if; -- u16 max_speed; - struct mac_device *dev_id; /* device cookie used by the exception cbs */ - fman_mac_exception_cb *exception_cb; - fman_mac_exception_cb *event_cb; -@@ -293,12 +290,12 @@ struct fman_mac { - struct memac_cfg *memac_drv_param; - void *fm; - struct fman_rev_info fm_rev_info; -- bool basex_if; - struct phy *serdes; - struct phylink_pcs *sgmii_pcs; - struct phylink_pcs *qsgmii_pcs; - struct phylink_pcs *xfi_pcs; - bool allmulti_enabled; -+ bool rgmii_no_half_duplex; - }; - - static void add_addr_in_paddr(struct memac_regs __iomem *regs, const u8 *adr, -@@ -356,7 +353,6 @@ static void set_exception(struct memac_r - } - - static int init(struct memac_regs __iomem *regs, struct memac_cfg *cfg, -- phy_interface_t phy_if, u16 speed, bool slow_10g_if, - u32 exceptions) - { - u32 tmp; -@@ -384,41 +380,6 @@ static int init(struct memac_regs __iome - iowrite32be((u32)cfg->pause_quanta, ®s->pause_quanta[0]); - iowrite32be((u32)0, ®s->pause_thresh[0]); - -- /* IF_MODE */ -- tmp = 0; -- switch (phy_if) { -- case PHY_INTERFACE_MODE_XGMII: -- tmp |= IF_MODE_10G; -- break; -- case PHY_INTERFACE_MODE_MII: -- tmp |= IF_MODE_MII; -- break; -- default: -- tmp |= IF_MODE_GMII; -- if (phy_if == PHY_INTERFACE_MODE_RGMII || -- phy_if == PHY_INTERFACE_MODE_RGMII_ID || -- phy_if == PHY_INTERFACE_MODE_RGMII_RXID || -- phy_if == PHY_INTERFACE_MODE_RGMII_TXID) -- tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO; -- } -- iowrite32be(tmp, ®s->if_mode); -- -- /* TX_FIFO_SECTIONS */ -- tmp = 0; -- if (phy_if == PHY_INTERFACE_MODE_XGMII) { -- if (slow_10g_if) { -- tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G | -- TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G); -- } else { -- tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G | -- TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G); -- } -- } else { -- tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G | -- TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G); -- } -- iowrite32be(tmp, ®s->tx_fifo_sections); -- - /* clear all pending events and set-up interrupts */ - iowrite32be(0xffffffff, ®s->ievent); - set_exception(regs, exceptions, true); -@@ -458,24 +419,6 @@ static u32 get_mac_addr_hash_code(u64 et - return xor_val; - } - --static void setup_sgmii_internal(struct fman_mac *memac, -- struct phylink_pcs *pcs, -- struct fixed_phy_status *fixed_link) --{ -- __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); -- phy_interface_t iface = memac->basex_if ? PHY_INTERFACE_MODE_1000BASEX : -- PHY_INTERFACE_MODE_SGMII; -- unsigned int mode = fixed_link ? MLO_AN_FIXED : MLO_AN_INBAND; -- -- linkmode_set_pause(advertising, true, true); -- pcs->ops->pcs_config(pcs, mode, iface, advertising, true); -- if (fixed_link) -- pcs->ops->pcs_link_up(pcs, mode, iface, fixed_link->speed, -- fixed_link->duplex); -- else -- pcs->ops->pcs_an_restart(pcs); --} -- - static int check_init_parameters(struct fman_mac *memac) - { - if (!memac->exception_cb) { -@@ -581,41 +524,31 @@ static void free_init_resources(struct f - memac->unicast_addr_hash = NULL; - } - --static bool is_init_done(struct memac_cfg *memac_drv_params) --{ -- /* Checks if mEMAC driver parameters were initialized */ -- if (!memac_drv_params) -- return true; -- -- return false; --} -- - static int memac_enable(struct fman_mac *memac) - { -- struct memac_regs __iomem *regs = memac->regs; -- u32 tmp; -+ int ret; - -- if (!is_init_done(memac->memac_drv_param)) -- return -EINVAL; -+ ret = phy_init(memac->serdes); -+ if (ret) { -+ dev_err(memac->dev_id->dev, -+ "could not initialize serdes: %pe\n", ERR_PTR(ret)); -+ return ret; -+ } - -- tmp = ioread32be(®s->command_config); -- tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN; -- iowrite32be(tmp, ®s->command_config); -+ ret = phy_power_on(memac->serdes); -+ if (ret) { -+ dev_err(memac->dev_id->dev, -+ "could not power on serdes: %pe\n", ERR_PTR(ret)); -+ phy_exit(memac->serdes); -+ } - -- return 0; -+ return ret; - } - - static void memac_disable(struct fman_mac *memac) -- - { -- struct memac_regs __iomem *regs = memac->regs; -- u32 tmp; -- -- WARN_ON_ONCE(!is_init_done(memac->memac_drv_param)); -- -- tmp = ioread32be(®s->command_config); -- tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN); -- iowrite32be(tmp, ®s->command_config); -+ phy_power_off(memac->serdes); -+ phy_exit(memac->serdes); - } - - static int memac_set_promiscuous(struct fman_mac *memac, bool new_val) -@@ -623,9 +556,6 @@ static int memac_set_promiscuous(struct - struct memac_regs __iomem *regs = memac->regs; - u32 tmp; - -- if (!is_init_done(memac->memac_drv_param)) -- return -EINVAL; -- - tmp = ioread32be(®s->command_config); - if (new_val) - tmp |= CMD_CFG_PROMIS_EN; -@@ -637,73 +567,12 @@ static int memac_set_promiscuous(struct - return 0; - } - --static int memac_adjust_link(struct fman_mac *memac, u16 speed) --{ -- struct memac_regs __iomem *regs = memac->regs; -- u32 tmp; -- -- if (!is_init_done(memac->memac_drv_param)) -- return -EINVAL; -- -- tmp = ioread32be(®s->if_mode); -- -- /* Set full duplex */ -- tmp &= ~IF_MODE_HD; -- -- if (phy_interface_mode_is_rgmii(memac->phy_if)) { -- /* Configure RGMII in manual mode */ -- tmp &= ~IF_MODE_RGMII_AUTO; -- tmp &= ~IF_MODE_RGMII_SP_MASK; -- /* Full duplex */ -- tmp |= IF_MODE_RGMII_FD; -- -- switch (speed) { -- case SPEED_1000: -- tmp |= IF_MODE_RGMII_1000; -- break; -- case SPEED_100: -- tmp |= IF_MODE_RGMII_100; -- break; -- case SPEED_10: -- tmp |= IF_MODE_RGMII_10; -- break; -- default: -- break; -- } -- } -- -- iowrite32be(tmp, ®s->if_mode); -- -- return 0; --} -- --static void adjust_link_memac(struct mac_device *mac_dev) --{ -- struct phy_device *phy_dev = mac_dev->phy_dev; -- struct fman_mac *fman_mac; -- bool rx_pause, tx_pause; -- int err; -- -- fman_mac = mac_dev->fman_mac; -- memac_adjust_link(fman_mac, phy_dev->speed); -- mac_dev->update_speed(mac_dev, phy_dev->speed); -- -- fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause); -- err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause); -- if (err < 0) -- dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n", -- err); --} -- - static int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority, - u16 pause_time, u16 thresh_time) - { - struct memac_regs __iomem *regs = memac->regs; - u32 tmp; - -- if (!is_init_done(memac->memac_drv_param)) -- return -EINVAL; -- - tmp = ioread32be(®s->tx_fifo_sections); - - GET_TX_EMPTY_DEFAULT_VALUE(tmp); -@@ -738,9 +607,6 @@ static int memac_accept_rx_pause_frames( - struct memac_regs __iomem *regs = memac->regs; - u32 tmp; - -- if (!is_init_done(memac->memac_drv_param)) -- return -EINVAL; -- - tmp = ioread32be(®s->command_config); - if (en) - tmp &= ~CMD_CFG_PAUSE_IGNORE; -@@ -752,12 +618,175 @@ static int memac_accept_rx_pause_frames( - return 0; - } - -+static void memac_validate(struct phylink_config *config, -+ unsigned long *supported, -+ struct phylink_link_state *state) -+{ -+ struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; -+ unsigned long caps = config->mac_capabilities; -+ -+ if (phy_interface_mode_is_rgmii(state->interface) && -+ memac->rgmii_no_half_duplex) -+ caps &= ~(MAC_10HD | MAC_100HD); -+ -+ phylink_validate_mask_caps(supported, state, caps); -+} -+ -+/** -+ * memac_if_mode() - Convert an interface mode into an IF_MODE config -+ * @interface: A phy interface mode -+ * -+ * Return: A configuration word, suitable for programming into the lower bits -+ * of %IF_MODE. -+ */ -+static u32 memac_if_mode(phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_MII: -+ return IF_MODE_MII; -+ case PHY_INTERFACE_MODE_RGMII: -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ return IF_MODE_GMII | IF_MODE_RGMII; -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_QSGMII: -+ return IF_MODE_GMII; -+ case PHY_INTERFACE_MODE_10GBASER: -+ return IF_MODE_10G; -+ default: -+ WARN_ON_ONCE(1); -+ return 0; -+ } -+} -+ -+static struct phylink_pcs *memac_select_pcs(struct phylink_config *config, -+ phy_interface_t iface) -+{ -+ struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; -+ -+ switch (iface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ return memac->sgmii_pcs; -+ case PHY_INTERFACE_MODE_QSGMII: -+ return memac->qsgmii_pcs; -+ case PHY_INTERFACE_MODE_10GBASER: -+ return memac->xfi_pcs; -+ default: -+ return NULL; -+ } -+} -+ -+static int memac_prepare(struct phylink_config *config, unsigned int mode, -+ phy_interface_t iface) -+{ -+ struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; -+ -+ switch (iface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_QSGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ return phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET, -+ iface); -+ default: -+ return 0; -+ } -+} -+ -+static void memac_mac_config(struct phylink_config *config, unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+ struct mac_device *mac_dev = fman_config_to_mac(config); -+ struct memac_regs __iomem *regs = mac_dev->fman_mac->regs; -+ u32 tmp = ioread32be(®s->if_mode); -+ -+ tmp &= ~(IF_MODE_MASK | IF_MODE_RGMII); -+ tmp |= memac_if_mode(state->interface); -+ if (phylink_autoneg_inband(mode)) -+ tmp |= IF_MODE_RGMII_AUTO; -+ iowrite32be(tmp, ®s->if_mode); -+} -+ -+static void memac_link_up(struct phylink_config *config, struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct mac_device *mac_dev = fman_config_to_mac(config); -+ struct fman_mac *memac = mac_dev->fman_mac; -+ struct memac_regs __iomem *regs = memac->regs; -+ u32 tmp = memac_if_mode(interface); -+ u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE : -+ FSL_FM_PAUSE_TIME_DISABLE; -+ -+ memac_set_tx_pause_frames(memac, 0, pause_time, 0); -+ memac_accept_rx_pause_frames(memac, rx_pause); -+ -+ if (duplex == DUPLEX_HALF) -+ tmp |= IF_MODE_HD; -+ -+ switch (speed) { -+ case SPEED_1000: -+ tmp |= IF_MODE_RGMII_1000; -+ break; -+ case SPEED_100: -+ tmp |= IF_MODE_RGMII_100; -+ break; -+ case SPEED_10: -+ tmp |= IF_MODE_RGMII_10; -+ break; -+ } -+ iowrite32be(tmp, ®s->if_mode); -+ -+ /* TODO: EEE? */ -+ -+ if (speed == SPEED_10000) { -+ if (memac->fm_rev_info.major == 6 && -+ memac->fm_rev_info.minor == 4) -+ tmp = TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G; -+ else -+ tmp = TX_FIFO_SECTIONS_TX_AVAIL_10G; -+ tmp |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G; -+ } else { -+ tmp = TX_FIFO_SECTIONS_TX_AVAIL_1G | -+ TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G; -+ } -+ iowrite32be(tmp, ®s->tx_fifo_sections); -+ -+ mac_dev->update_speed(mac_dev, speed); -+ -+ tmp = ioread32be(®s->command_config); -+ tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN; -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+static void memac_link_down(struct phylink_config *config, unsigned int mode, -+ phy_interface_t interface) -+{ -+ struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; -+ struct memac_regs __iomem *regs = memac->regs; -+ u32 tmp; -+ -+ /* TODO: graceful */ -+ tmp = ioread32be(®s->command_config); -+ tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN); -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+static const struct phylink_mac_ops memac_mac_ops = { -+ .validate = memac_validate, -+ .mac_select_pcs = memac_select_pcs, -+ .mac_prepare = memac_prepare, -+ .mac_config = memac_mac_config, -+ .mac_link_up = memac_link_up, -+ .mac_link_down = memac_link_down, -+}; -+ - static int memac_modify_mac_address(struct fman_mac *memac, - const enet_addr_t *enet_addr) - { -- if (!is_init_done(memac->memac_drv_param)) -- return -EINVAL; -- - add_addr_in_paddr(memac->regs, (const u8 *)(*enet_addr), 0); - - return 0; -@@ -771,9 +800,6 @@ static int memac_add_hash_mac_address(st - u32 hash; - u64 addr; - -- if (!is_init_done(memac->memac_drv_param)) -- return -EINVAL; -- - addr = ENET_ADDR_TO_UINT64(*eth_addr); - - if (!(addr & GROUP_ADDRESS)) { -@@ -802,9 +828,6 @@ static int memac_set_allmulti(struct fma - u32 entry; - struct memac_regs __iomem *regs = memac->regs; - -- if (!is_init_done(memac->memac_drv_param)) -- return -EINVAL; -- - if (enable) { - for (entry = 0; entry < HASH_TABLE_SIZE; entry++) - iowrite32be(entry | HASH_CTRL_MCAST_EN, -@@ -834,9 +857,6 @@ static int memac_del_hash_mac_address(st - u32 hash; - u64 addr; - -- if (!is_init_done(memac->memac_drv_param)) -- return -EINVAL; -- - addr = ENET_ADDR_TO_UINT64(*eth_addr); - - hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK; -@@ -864,9 +884,6 @@ static int memac_set_exception(struct fm - { - u32 bit_mask = 0; - -- if (!is_init_done(memac->memac_drv_param)) -- return -EINVAL; -- - bit_mask = get_exception_flag(exception); - if (bit_mask) { - if (enable) -@@ -886,23 +903,15 @@ static int memac_init(struct fman_mac *m - { - struct memac_cfg *memac_drv_param; - enet_addr_t eth_addr; -- bool slow_10g_if = false; -- struct fixed_phy_status *fixed_link = NULL; - int err; - u32 reg32 = 0; - -- if (is_init_done(memac->memac_drv_param)) -- return -EINVAL; -- - err = check_init_parameters(memac); - if (err) - return err; - - memac_drv_param = memac->memac_drv_param; - -- if (memac->fm_rev_info.major == 6 && memac->fm_rev_info.minor == 4) -- slow_10g_if = true; -- - /* First, reset the MAC if desired. */ - if (memac_drv_param->reset_on_init) { - err = reset(memac->regs); -@@ -918,10 +927,7 @@ static int memac_init(struct fman_mac *m - add_addr_in_paddr(memac->regs, (const u8 *)eth_addr, 0); - } - -- fixed_link = memac_drv_param->fixed_link; -- -- init(memac->regs, memac->memac_drv_param, memac->phy_if, -- memac->max_speed, slow_10g_if, memac->exceptions); -+ init(memac->regs, memac->memac_drv_param, memac->exceptions); - - /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 errata workaround - * Exists only in FMan 6.0 and 6.3. -@@ -937,11 +943,6 @@ static int memac_init(struct fman_mac *m - iowrite32be(reg32, &memac->regs->command_config); - } - -- if (memac->phy_if == PHY_INTERFACE_MODE_SGMII) -- setup_sgmii_internal(memac, memac->sgmii_pcs, fixed_link); -- else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII) -- setup_sgmii_internal(memac, memac->qsgmii_pcs, fixed_link); -- - /* Max Frame Length */ - err = fman_set_mac_max_frame(memac->fm, memac->mac_id, - memac_drv_param->max_frame_length); -@@ -970,9 +971,6 @@ static int memac_init(struct fman_mac *m - fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, - FMAN_INTR_TYPE_NORMAL, memac_exception, memac); - -- kfree(memac_drv_param); -- memac->memac_drv_param = NULL; -- - return 0; - } - -@@ -995,7 +993,6 @@ static int memac_free(struct fman_mac *m - pcs_put(memac->sgmii_pcs); - pcs_put(memac->qsgmii_pcs); - pcs_put(memac->xfi_pcs); -- - kfree(memac->memac_drv_param); - kfree(memac); - -@@ -1028,8 +1025,6 @@ static struct fman_mac *memac_config(str - memac->addr = ENET_ADDR_TO_UINT64(mac_dev->addr); - - memac->regs = mac_dev->vaddr; -- memac->max_speed = params->max_speed; -- memac->phy_if = mac_dev->phy_if; - memac->mac_id = params->mac_id; - memac->exceptions = (MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | - MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI); -@@ -1037,7 +1032,6 @@ static struct fman_mac *memac_config(str - memac->event_cb = params->event_cb; - memac->dev_id = mac_dev; - memac->fm = params->fm; -- memac->basex_if = params->basex_if; - - /* Save FMan revision */ - fman_get_revision(memac->fm, &memac->fm_rev_info); -@@ -1064,37 +1058,44 @@ static struct phylink_pcs *memac_pcs_cre - return pcs; - } - -+static bool memac_supports(struct mac_device *mac_dev, phy_interface_t iface) -+{ -+ /* If there's no serdes device, assume that it's been configured for -+ * whatever the default interface mode is. -+ */ -+ if (!mac_dev->fman_mac->serdes) -+ return mac_dev->phy_if == iface; -+ /* Otherwise, ask the serdes */ -+ return !phy_validate(mac_dev->fman_mac->serdes, PHY_MODE_ETHERNET, -+ iface, NULL); -+} -+ - int memac_initialization(struct mac_device *mac_dev, - struct device_node *mac_node, - struct fman_mac_params *params) - { - int err; -+ struct device_node *fixed; - struct phylink_pcs *pcs; -- struct fixed_phy_status *fixed_link; - struct fman_mac *memac; -+ unsigned long capabilities; -+ unsigned long *supported; - -+ mac_dev->phylink_ops = &memac_mac_ops; - mac_dev->set_promisc = memac_set_promiscuous; - mac_dev->change_addr = memac_modify_mac_address; - mac_dev->add_hash_mac_addr = memac_add_hash_mac_address; - mac_dev->remove_hash_mac_addr = memac_del_hash_mac_address; -- mac_dev->set_tx_pause = memac_set_tx_pause_frames; -- mac_dev->set_rx_pause = memac_accept_rx_pause_frames; - mac_dev->set_exception = memac_set_exception; - mac_dev->set_allmulti = memac_set_allmulti; - mac_dev->set_tstamp = memac_set_tstamp; - mac_dev->set_multi = fman_set_multi; -- mac_dev->adjust_link = adjust_link_memac; - mac_dev->enable = memac_enable; - mac_dev->disable = memac_disable; - -- if (params->max_speed == SPEED_10000) -- mac_dev->phy_if = PHY_INTERFACE_MODE_XGMII; -- - mac_dev->fman_mac = memac_config(mac_dev, params); -- if (!mac_dev->fman_mac) { -- err = -EINVAL; -- goto _return; -- } -+ if (!mac_dev->fman_mac) -+ return -EINVAL; - - memac = mac_dev->fman_mac; - memac->memac_drv_param->max_frame_length = fman_get_max_frm(); -@@ -1136,9 +1137,9 @@ int memac_initialization(struct mac_devi - else - pcs = memac_pcs_create(mac_node, err); - -- if (!pcs) { -- dev_err(mac_dev->dev, "missing pcs\n"); -- err = -ENOENT; -+ if (IS_ERR(pcs)) { -+ err = PTR_ERR(pcs); -+ dev_err_probe(mac_dev->dev, err, "missing pcs\n"); - goto _return_fm_mac_free; - } - -@@ -1159,84 +1160,100 @@ int memac_initialization(struct mac_devi - } else if (IS_ERR(memac->serdes)) { - dev_err_probe(mac_dev->dev, err, "could not get serdes\n"); - goto _return_fm_mac_free; -- } else { -- err = phy_init(memac->serdes); -- if (err) { -- dev_err_probe(mac_dev->dev, err, -- "could not initialize serdes\n"); -- goto _return_fm_mac_free; -- } -- -- err = phy_power_on(memac->serdes); -- if (err) { -- dev_err_probe(mac_dev->dev, err, -- "could not power on serdes\n"); -- goto _return_phy_exit; -- } -- -- if (memac->phy_if == PHY_INTERFACE_MODE_SGMII || -- memac->phy_if == PHY_INTERFACE_MODE_1000BASEX || -- memac->phy_if == PHY_INTERFACE_MODE_2500BASEX || -- memac->phy_if == PHY_INTERFACE_MODE_QSGMII || -- memac->phy_if == PHY_INTERFACE_MODE_XGMII) { -- err = phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET, -- memac->phy_if); -- if (err) { -- dev_err_probe(mac_dev->dev, err, -- "could not set serdes mode to %s\n", -- phy_modes(memac->phy_if)); -- goto _return_phy_power_off; -- } -- } - } - -- if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) { -- struct phy_device *phy; -- -- err = of_phy_register_fixed_link(mac_node); -- if (err) -- goto _return_phy_power_off; -- -- fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL); -- if (!fixed_link) { -- err = -ENOMEM; -- goto _return_phy_power_off; -- } -+ /* The internal connection to the serdes is XGMII, but this isn't -+ * really correct for the phy mode (which is the external connection). -+ * However, this is how all older device trees say that they want -+ * 10GBASE-R (aka XFI), so just convert it for them. -+ */ -+ if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) -+ mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER; - -- mac_dev->phy_node = of_node_get(mac_node); -- phy = of_phy_find_device(mac_dev->phy_node); -- if (!phy) { -- err = -EINVAL; -- of_node_put(mac_dev->phy_node); -- goto _return_fixed_link_free; -- } -+ /* TODO: The following interface modes are supported by (some) hardware -+ * but not by this driver: -+ * - 1000BASE-KX -+ * - 10GBASE-KR -+ * - XAUI/HiGig -+ */ -+ supported = mac_dev->phylink_config.supported_interfaces; - -- fixed_link->link = phy->link; -- fixed_link->speed = phy->speed; -- fixed_link->duplex = phy->duplex; -- fixed_link->pause = phy->pause; -- fixed_link->asym_pause = phy->asym_pause; -+ /* Note that half duplex is only supported on 10/100M interfaces. */ - -- put_device(&phy->mdio.dev); -- memac->memac_drv_param->fixed_link = fixed_link; -+ if (memac->sgmii_pcs && -+ (memac_supports(mac_dev, PHY_INTERFACE_MODE_SGMII) || -+ memac_supports(mac_dev, PHY_INTERFACE_MODE_1000BASEX))) { -+ __set_bit(PHY_INTERFACE_MODE_SGMII, supported); -+ __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported); -+ } -+ -+ if (memac->sgmii_pcs && -+ memac_supports(mac_dev, PHY_INTERFACE_MODE_2500BASEX)) -+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported); -+ -+ if (memac->qsgmii_pcs && -+ memac_supports(mac_dev, PHY_INTERFACE_MODE_QSGMII)) -+ __set_bit(PHY_INTERFACE_MODE_QSGMII, supported); -+ else if (mac_dev->phy_if == PHY_INTERFACE_MODE_QSGMII) -+ dev_warn(mac_dev->dev, "no QSGMII pcs specified\n"); -+ -+ if (memac->xfi_pcs && -+ memac_supports(mac_dev, PHY_INTERFACE_MODE_10GBASER)) { -+ __set_bit(PHY_INTERFACE_MODE_10GBASER, supported); -+ } else { -+ /* From what I can tell, no 10g macs support RGMII. */ -+ phy_interface_set_rgmii(supported); -+ __set_bit(PHY_INTERFACE_MODE_MII, supported); - } - -+ capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10 | MAC_100; -+ capabilities |= MAC_1000FD | MAC_2500FD | MAC_10000FD; -+ -+ /* These SoCs don't support half duplex at all; there's no different -+ * FMan version or compatible, so we just have to check the machine -+ * compatible instead -+ */ -+ if (of_machine_is_compatible("fsl,ls1043a") || -+ of_machine_is_compatible("fsl,ls1046a") || -+ of_machine_is_compatible("fsl,B4QDS")) -+ capabilities &= ~(MAC_10HD | MAC_100HD); -+ -+ mac_dev->phylink_config.mac_capabilities = capabilities; -+ -+ /* The T2080 and T4240 don't support half duplex RGMII. There is no -+ * other way to identify these SoCs, so just use the machine -+ * compatible. -+ */ -+ if (of_machine_is_compatible("fsl,T2080QDS") || -+ of_machine_is_compatible("fsl,T2080RDB") || -+ of_machine_is_compatible("fsl,T2081QDS") || -+ of_machine_is_compatible("fsl,T4240QDS") || -+ of_machine_is_compatible("fsl,T4240RDB")) -+ memac->rgmii_no_half_duplex = true; -+ -+ /* Most boards should use MLO_AN_INBAND, but existing boards don't have -+ * a managed property. Default to MLO_AN_INBAND if nothing else is -+ * specified. We need to be careful and not enable this if we have a -+ * fixed link or if we are using MII or RGMII, since those -+ * configurations modes don't use in-band autonegotiation. -+ */ -+ fixed = of_get_child_by_name(mac_node, "fixed-link"); -+ if (!fixed && !of_property_read_bool(mac_node, "fixed-link") && -+ !of_property_read_bool(mac_node, "managed") && -+ mac_dev->phy_if != PHY_INTERFACE_MODE_MII && -+ !phy_interface_mode_is_rgmii(mac_dev->phy_if)) -+ mac_dev->phylink_config.ovr_an_inband = true; -+ of_node_put(fixed); -+ - err = memac_init(mac_dev->fman_mac); - if (err < 0) -- goto _return_fixed_link_free; -+ goto _return_fm_mac_free; - - dev_info(mac_dev->dev, "FMan MEMAC\n"); - -- goto _return; -+ return 0; - --_return_phy_power_off: -- phy_power_off(memac->serdes); --_return_phy_exit: -- phy_exit(memac->serdes); --_return_fixed_link_free: -- kfree(fixed_link); - _return_fm_mac_free: - memac_free(mac_dev->fman_mac); --_return: - return err; - } ---- a/drivers/net/ethernet/freescale/fman/fman_tgec.c -+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - /* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */ - #define TGEC_TX_IPG_LENGTH_MASK 0x000003ff -@@ -243,10 +244,6 @@ static int init(struct tgec_regs __iomem - - static int check_init_parameters(struct fman_mac *tgec) - { -- if (tgec->max_speed < SPEED_10000) { -- pr_err("10G MAC driver only support 10G speed\n"); -- return -EINVAL; -- } - if (!tgec->exception_cb) { - pr_err("uninitialized exception_cb\n"); - return -EINVAL; -@@ -384,40 +381,13 @@ static void free_init_resources(struct f - tgec->unicast_addr_hash = NULL; - } - --static bool is_init_done(struct tgec_cfg *cfg) --{ -- /* Checks if tGEC driver parameters were initialized */ -- if (!cfg) -- return true; -- -- return false; --} -- - static int tgec_enable(struct fman_mac *tgec) - { -- struct tgec_regs __iomem *regs = tgec->regs; -- u32 tmp; -- -- if (!is_init_done(tgec->cfg)) -- return -EINVAL; -- -- tmp = ioread32be(®s->command_config); -- tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN; -- iowrite32be(tmp, ®s->command_config); -- - return 0; - } - - static void tgec_disable(struct fman_mac *tgec) - { -- struct tgec_regs __iomem *regs = tgec->regs; -- u32 tmp; -- -- WARN_ON_ONCE(!is_init_done(tgec->cfg)); -- -- tmp = ioread32be(®s->command_config); -- tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN); -- iowrite32be(tmp, ®s->command_config); - } - - static int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val) -@@ -425,9 +395,6 @@ static int tgec_set_promiscuous(struct f - struct tgec_regs __iomem *regs = tgec->regs; - u32 tmp; - -- if (!is_init_done(tgec->cfg)) -- return -EINVAL; -- - tmp = ioread32be(®s->command_config); - if (new_val) - tmp |= CMD_CFG_PROMIS_EN; -@@ -444,9 +411,6 @@ static int tgec_set_tx_pause_frames(stru - { - struct tgec_regs __iomem *regs = tgec->regs; - -- if (!is_init_done(tgec->cfg)) -- return -EINVAL; -- - iowrite32be((u32)pause_time, ®s->pause_quant); - - return 0; -@@ -457,9 +421,6 @@ static int tgec_accept_rx_pause_frames(s - struct tgec_regs __iomem *regs = tgec->regs; - u32 tmp; - -- if (!is_init_done(tgec->cfg)) -- return -EINVAL; -- - tmp = ioread32be(®s->command_config); - if (!en) - tmp |= CMD_CFG_PAUSE_IGNORE; -@@ -470,12 +431,53 @@ static int tgec_accept_rx_pause_frames(s - return 0; - } - -+static void tgec_mac_config(struct phylink_config *config, unsigned int mode, -+ const struct phylink_link_state *state) -+{ -+} -+ -+static void tgec_link_up(struct phylink_config *config, struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct mac_device *mac_dev = fman_config_to_mac(config); -+ struct fman_mac *tgec = mac_dev->fman_mac; -+ struct tgec_regs __iomem *regs = tgec->regs; -+ u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE : -+ FSL_FM_PAUSE_TIME_DISABLE; -+ u32 tmp; -+ -+ tgec_set_tx_pause_frames(tgec, 0, pause_time, 0); -+ tgec_accept_rx_pause_frames(tgec, rx_pause); -+ mac_dev->update_speed(mac_dev, speed); -+ -+ tmp = ioread32be(®s->command_config); -+ tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN; -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+static void tgec_link_down(struct phylink_config *config, unsigned int mode, -+ phy_interface_t interface) -+{ -+ struct fman_mac *tgec = fman_config_to_mac(config)->fman_mac; -+ struct tgec_regs __iomem *regs = tgec->regs; -+ u32 tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN); -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+static const struct phylink_mac_ops tgec_mac_ops = { -+ .validate = phylink_generic_validate, -+ .mac_config = tgec_mac_config, -+ .mac_link_up = tgec_link_up, -+ .mac_link_down = tgec_link_down, -+}; -+ - static int tgec_modify_mac_address(struct fman_mac *tgec, - const enet_addr_t *p_enet_addr) - { -- if (!is_init_done(tgec->cfg)) -- return -EINVAL; -- - tgec->addr = ENET_ADDR_TO_UINT64(*p_enet_addr); - set_mac_address(tgec->regs, (const u8 *)(*p_enet_addr)); - -@@ -490,9 +492,6 @@ static int tgec_add_hash_mac_address(str - u32 crc = 0xFFFFFFFF, hash; - u64 addr; - -- if (!is_init_done(tgec->cfg)) -- return -EINVAL; -- - addr = ENET_ADDR_TO_UINT64(*eth_addr); - - if (!(addr & GROUP_ADDRESS)) { -@@ -525,9 +524,6 @@ static int tgec_set_allmulti(struct fman - u32 entry; - struct tgec_regs __iomem *regs = tgec->regs; - -- if (!is_init_done(tgec->cfg)) -- return -EINVAL; -- - if (enable) { - for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++) - iowrite32be(entry | TGEC_HASH_MCAST_EN, -@@ -548,9 +544,6 @@ static int tgec_set_tstamp(struct fman_m - struct tgec_regs __iomem *regs = tgec->regs; - u32 tmp; - -- if (!is_init_done(tgec->cfg)) -- return -EINVAL; -- - tmp = ioread32be(®s->command_config); - - if (enable) -@@ -572,9 +565,6 @@ static int tgec_del_hash_mac_address(str - u32 crc = 0xFFFFFFFF, hash; - u64 addr; - -- if (!is_init_done(tgec->cfg)) -- return -EINVAL; -- - addr = ((*(u64 *)eth_addr) >> 16); - - /* CRC calculation */ -@@ -601,22 +591,12 @@ static int tgec_del_hash_mac_address(str - return 0; - } - --static void tgec_adjust_link(struct mac_device *mac_dev) --{ -- struct phy_device *phy_dev = mac_dev->phy_dev; -- -- mac_dev->update_speed(mac_dev, phy_dev->speed); --} -- - static int tgec_set_exception(struct fman_mac *tgec, - enum fman_mac_exceptions exception, bool enable) - { - struct tgec_regs __iomem *regs = tgec->regs; - u32 bit_mask = 0; - -- if (!is_init_done(tgec->cfg)) -- return -EINVAL; -- - bit_mask = get_exception_flag(exception); - if (bit_mask) { - if (enable) -@@ -641,9 +621,6 @@ static int tgec_init(struct fman_mac *tg - enet_addr_t eth_addr; - int err; - -- if (is_init_done(tgec->cfg)) -- return -EINVAL; -- - if (DEFAULT_RESET_ON_INIT && - (fman_reset_mac(tgec->fm, tgec->mac_id) != 0)) { - pr_err("Can't reset MAC!\n"); -@@ -753,7 +730,6 @@ static struct fman_mac *tgec_config(stru - - tgec->regs = mac_dev->vaddr; - tgec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr); -- tgec->max_speed = params->max_speed; - tgec->mac_id = params->mac_id; - tgec->exceptions = (TGEC_IMASK_MDIO_SCAN_EVENT | - TGEC_IMASK_REM_FAULT | -@@ -788,17 +764,15 @@ int tgec_initialization(struct mac_devic - int err; - struct fman_mac *tgec; - -+ mac_dev->phylink_ops = &tgec_mac_ops; - mac_dev->set_promisc = tgec_set_promiscuous; - mac_dev->change_addr = tgec_modify_mac_address; - mac_dev->add_hash_mac_addr = tgec_add_hash_mac_address; - mac_dev->remove_hash_mac_addr = tgec_del_hash_mac_address; -- mac_dev->set_tx_pause = tgec_set_tx_pause_frames; -- mac_dev->set_rx_pause = tgec_accept_rx_pause_frames; - mac_dev->set_exception = tgec_set_exception; - mac_dev->set_allmulti = tgec_set_allmulti; - mac_dev->set_tstamp = tgec_set_tstamp; - mac_dev->set_multi = fman_set_multi; -- mac_dev->adjust_link = tgec_adjust_link; - mac_dev->enable = tgec_enable; - mac_dev->disable = tgec_disable; - -@@ -808,6 +782,19 @@ int tgec_initialization(struct mac_devic - goto _return; - } - -+ /* The internal connection to the serdes is XGMII, but this isn't -+ * really correct for the phy mode (which is the external connection). -+ * However, this is how all older device trees say that they want -+ * XAUI, so just convert it for them. -+ */ -+ if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) -+ mac_dev->phy_if = PHY_INTERFACE_MODE_XAUI; -+ -+ __set_bit(PHY_INTERFACE_MODE_XAUI, -+ mac_dev->phylink_config.supported_interfaces); -+ mac_dev->phylink_config.mac_capabilities = -+ MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10000FD; -+ - tgec = mac_dev->fman_mac; - tgec->cfg->max_frame_length = fman_get_max_frm(); - err = tgec_init(tgec); ---- a/drivers/net/ethernet/freescale/fman/mac.c -+++ b/drivers/net/ethernet/freescale/fman/mac.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -93,130 +94,8 @@ int fman_set_multi(struct net_device *ne - return 0; - } - --/** -- * fman_set_mac_active_pause -- * @mac_dev: A pointer to the MAC device -- * @rx: Pause frame setting for RX -- * @tx: Pause frame setting for TX -- * -- * Set the MAC RX/TX PAUSE frames settings -- * -- * Avoid redundant calls to FMD, if the MAC driver already contains the desired -- * active PAUSE settings. Otherwise, the new active settings should be reflected -- * in FMan. -- * -- * Return: 0 on success; Error code otherwise. -- */ --int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx) --{ -- struct fman_mac *fman_mac = mac_dev->fman_mac; -- int err = 0; -- -- if (rx != mac_dev->rx_pause_active) { -- err = mac_dev->set_rx_pause(fman_mac, rx); -- if (likely(err == 0)) -- mac_dev->rx_pause_active = rx; -- } -- -- if (tx != mac_dev->tx_pause_active) { -- u16 pause_time = (tx ? FSL_FM_PAUSE_TIME_ENABLE : -- FSL_FM_PAUSE_TIME_DISABLE); -- -- err = mac_dev->set_tx_pause(fman_mac, 0, pause_time, 0); -- -- if (likely(err == 0)) -- mac_dev->tx_pause_active = tx; -- } -- -- return err; --} --EXPORT_SYMBOL(fman_set_mac_active_pause); -- --/** -- * fman_get_pause_cfg -- * @mac_dev: A pointer to the MAC device -- * @rx_pause: Return value for RX setting -- * @tx_pause: Return value for TX setting -- * -- * Determine the MAC RX/TX PAUSE frames settings based on PHY -- * autonegotiation or values set by eththool. -- * -- * Return: Pointer to FMan device. -- */ --void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, -- bool *tx_pause) --{ -- struct phy_device *phy_dev = mac_dev->phy_dev; -- u16 lcl_adv, rmt_adv; -- u8 flowctrl; -- -- *rx_pause = *tx_pause = false; -- -- if (!phy_dev->duplex) -- return; -- -- /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings -- * are those set by ethtool. -- */ -- if (!mac_dev->autoneg_pause) { -- *rx_pause = mac_dev->rx_pause_req; -- *tx_pause = mac_dev->tx_pause_req; -- return; -- } -- -- /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE -- * settings depend on the result of the link negotiation. -- */ -- -- /* get local capabilities */ -- lcl_adv = linkmode_adv_to_lcl_adv_t(phy_dev->advertising); -- -- /* get link partner capabilities */ -- rmt_adv = 0; -- if (phy_dev->pause) -- rmt_adv |= LPA_PAUSE_CAP; -- if (phy_dev->asym_pause) -- rmt_adv |= LPA_PAUSE_ASYM; -- -- /* Calculate TX/RX settings based on local and peer advertised -- * symmetric/asymmetric PAUSE capabilities. -- */ -- flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); -- if (flowctrl & FLOW_CTRL_RX) -- *rx_pause = true; -- if (flowctrl & FLOW_CTRL_TX) -- *tx_pause = true; --} --EXPORT_SYMBOL(fman_get_pause_cfg); -- --#define DTSEC_SUPPORTED \ -- (SUPPORTED_10baseT_Half \ -- | SUPPORTED_10baseT_Full \ -- | SUPPORTED_100baseT_Half \ -- | SUPPORTED_100baseT_Full \ -- | SUPPORTED_Autoneg \ -- | SUPPORTED_Pause \ -- | SUPPORTED_Asym_Pause \ -- | SUPPORTED_FIBRE \ -- | SUPPORTED_MII) -- - static DEFINE_MUTEX(eth_lock); - --static const u16 phy2speed[] = { -- [PHY_INTERFACE_MODE_MII] = SPEED_100, -- [PHY_INTERFACE_MODE_GMII] = SPEED_1000, -- [PHY_INTERFACE_MODE_SGMII] = SPEED_1000, -- [PHY_INTERFACE_MODE_TBI] = SPEED_1000, -- [PHY_INTERFACE_MODE_RMII] = SPEED_100, -- [PHY_INTERFACE_MODE_RGMII] = SPEED_1000, -- [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000, -- [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000, -- [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000, -- [PHY_INTERFACE_MODE_RTBI] = SPEED_1000, -- [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000, -- [PHY_INTERFACE_MODE_XGMII] = SPEED_10000 --}; -- - static struct platform_device *dpaa_eth_add_device(int fman_id, - struct mac_device *mac_dev) - { -@@ -263,8 +142,8 @@ no_mem: - } - - static const struct of_device_id mac_match[] = { -- { .compatible = "fsl,fman-dtsec", .data = dtsec_initialization }, -- { .compatible = "fsl,fman-xgec", .data = tgec_initialization }, -+ { .compatible = "fsl,fman-dtsec", .data = dtsec_initialization }, -+ { .compatible = "fsl,fman-xgec", .data = tgec_initialization }, - { .compatible = "fsl,fman-memac", .data = memac_initialization }, - {} - }; -@@ -295,6 +174,7 @@ static int mac_probe(struct platform_dev - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; -+ platform_set_drvdata(_of_dev, mac_dev); - - /* Save private information */ - mac_dev->priv = priv; -@@ -424,57 +304,21 @@ static int mac_probe(struct platform_dev - } - mac_dev->phy_if = phy_if; - -- priv->speed = phy2speed[mac_dev->phy_if]; -- params.max_speed = priv->speed; -- mac_dev->if_support = DTSEC_SUPPORTED; -- /* We don't support half-duplex in SGMII mode */ -- if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) -- mac_dev->if_support &= ~(SUPPORTED_10baseT_Half | -- SUPPORTED_100baseT_Half); -- -- /* Gigabit support (no half-duplex) */ -- if (params.max_speed == 1000) -- mac_dev->if_support |= SUPPORTED_1000baseT_Full; -- -- /* The 10G interface only supports one mode */ -- if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) -- mac_dev->if_support = SUPPORTED_10000baseT_Full; -- -- /* Get the rest of the PHY information */ -- mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0); -- -- params.basex_if = false; - params.mac_id = priv->cell_index; - params.fm = (void *)priv->fman; - params.exception_cb = mac_exception; - params.event_cb = mac_exception; - - err = init(mac_dev, mac_node, ¶ms); -- if (err < 0) { -- dev_err(dev, "mac_dev->init() = %d\n", err); -- of_node_put(mac_dev->phy_node); -- return err; -- } -- -- /* pause frame autonegotiation enabled */ -- mac_dev->autoneg_pause = true; -- -- /* By intializing the values to false, force FMD to enable PAUSE frames -- * on RX and TX -- */ -- mac_dev->rx_pause_req = true; -- mac_dev->tx_pause_req = true; -- mac_dev->rx_pause_active = false; -- mac_dev->tx_pause_active = false; -- err = fman_set_mac_active_pause(mac_dev, true, true); - if (err < 0) -- dev_err(dev, "fman_set_mac_active_pause() = %d\n", err); -+ return err; - - if (!is_zero_ether_addr(mac_dev->addr)) - dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr); - - priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev); - if (IS_ERR(priv->eth_dev)) { -+ err = PTR_ERR(priv->eth_dev); - dev_err(dev, "failed to add Ethernet platform device for MAC %d\n", - priv->cell_index); - priv->eth_dev = NULL; ---- a/drivers/net/ethernet/freescale/fman/mac.h -+++ b/drivers/net/ethernet/freescale/fman/mac.h -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - - #include "fman_port.h" -@@ -24,32 +25,22 @@ struct mac_device { - struct resource *res; - u8 addr[ETH_ALEN]; - struct fman_port *port[2]; -- u32 if_support; -- struct phy_device *phy_dev; -+ struct phylink *phylink; -+ struct phylink_config phylink_config; - phy_interface_t phy_if; -- struct device_node *phy_node; -- struct net_device *net_dev; - -- bool autoneg_pause; -- bool rx_pause_req; -- bool tx_pause_req; -- bool rx_pause_active; -- bool tx_pause_active; - bool promisc; - bool allmulti; - -+ const struct phylink_mac_ops *phylink_ops; - int (*enable)(struct fman_mac *mac_dev); - void (*disable)(struct fman_mac *mac_dev); -- void (*adjust_link)(struct mac_device *mac_dev); - int (*set_promisc)(struct fman_mac *mac_dev, bool enable); - int (*change_addr)(struct fman_mac *mac_dev, const enet_addr_t *enet_addr); - int (*set_allmulti)(struct fman_mac *mac_dev, bool enable); - int (*set_tstamp)(struct fman_mac *mac_dev, bool enable); - int (*set_multi)(struct net_device *net_dev, - struct mac_device *mac_dev); -- int (*set_rx_pause)(struct fman_mac *mac_dev, bool en); -- int (*set_tx_pause)(struct fman_mac *mac_dev, u8 priority, -- u16 pause_time, u16 thresh_time); - int (*set_exception)(struct fman_mac *mac_dev, - enum fman_mac_exceptions exception, bool enable); - int (*add_hash_mac_addr)(struct fman_mac *mac_dev, -@@ -63,6 +54,12 @@ struct mac_device { - struct mac_priv_s *priv; - }; - -+static inline struct mac_device -+*fman_config_to_mac(struct phylink_config *config) -+{ -+ return container_of(config, struct mac_device, phylink_config); -+} -+ - struct dpaa_eth_data { - struct mac_device *mac_dev; - int mac_hw_id; diff --git a/target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch b/target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch deleted file mode 100644 index 06c348b1cdfa78..00000000000000 --- a/target/linux/generic/backport-6.1/715-04-v6.2-net-phylink-provide-phylink_validate_mask_caps-helpe.patch +++ /dev/null @@ -1,93 +0,0 @@ -From bf4de031052fe7c5309e8956c342d4e5ce79038e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 17 Oct 2022 16:22:35 -0400 -Subject: [PATCH 04/21] net: phylink: provide phylink_validate_mask_caps() - helper - -Provide a helper that restricts the link modes according to the -phylink capabilities. - -Signed-off-by: Russell King (Oracle) -[rebased on net-next/master and added documentation] -Signed-off-by: Sean Anderson -Signed-off-by: David S. Miller ---- - drivers/net/phy/phylink.c | 41 +++++++++++++++++++++++++++------------ - include/linux/phylink.h | 3 +++ - 2 files changed, 32 insertions(+), 12 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -564,31 +564,48 @@ unsigned long phylink_get_capabilities(p - EXPORT_SYMBOL_GPL(phylink_get_capabilities); - - /** -- * phylink_generic_validate() - generic validate() callback implementation -- * @config: a pointer to a &struct phylink_config. -+ * phylink_validate_mask_caps() - Restrict link modes based on caps - * @supported: ethtool bitmask for supported link modes. -- * @state: a pointer to a &struct phylink_link_state. -+ * @state: an (optional) pointer to a &struct phylink_link_state. -+ * @mac_capabilities: bitmask of MAC capabilities - * -- * Generic implementation of the validate() callback that MAC drivers can -- * use when they pass the range of supported interfaces and MAC capabilities. -- * This makes use of phylink_get_linkmodes(). -+ * Calculate the supported link modes based on @mac_capabilities, and restrict -+ * @supported and @state based on that. Use this function if your capabiliies -+ * aren't constant, such as if they vary depending on the interface. - */ --void phylink_generic_validate(struct phylink_config *config, -- unsigned long *supported, -- struct phylink_link_state *state) -+void phylink_validate_mask_caps(unsigned long *supported, -+ struct phylink_link_state *state, -+ unsigned long mac_capabilities) - { - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - unsigned long caps; - - phylink_set_port_modes(mask); - phylink_set(mask, Autoneg); -- caps = phylink_get_capabilities(state->interface, -- config->mac_capabilities, -+ caps = phylink_get_capabilities(state->interface, mac_capabilities, - state->rate_matching); - phylink_caps_to_linkmodes(mask, caps); - - linkmode_and(supported, supported, mask); -- linkmode_and(state->advertising, state->advertising, mask); -+ if (state) -+ linkmode_and(state->advertising, state->advertising, mask); -+} -+EXPORT_SYMBOL_GPL(phylink_validate_mask_caps); -+ -+/** -+ * phylink_generic_validate() - generic validate() callback implementation -+ * @config: a pointer to a &struct phylink_config. -+ * @supported: ethtool bitmask for supported link modes. -+ * @state: a pointer to a &struct phylink_link_state. -+ * -+ * Generic implementation of the validate() callback that MAC drivers can -+ * use when they pass the range of supported interfaces and MAC capabilities. -+ */ -+void phylink_generic_validate(struct phylink_config *config, -+ unsigned long *supported, -+ struct phylink_link_state *state) -+{ -+ phylink_validate_mask_caps(supported, state, config->mac_capabilities); - } - EXPORT_SYMBOL_GPL(phylink_generic_validate); - ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -558,6 +558,9 @@ void phylink_caps_to_linkmodes(unsigned - unsigned long phylink_get_capabilities(phy_interface_t interface, - unsigned long mac_capabilities, - int rate_matching); -+void phylink_validate_mask_caps(unsigned long *supported, -+ struct phylink_link_state *state, -+ unsigned long caps); - void phylink_generic_validate(struct phylink_config *config, - unsigned long *supported, - struct phylink_link_state *state); diff --git a/target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch b/target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch deleted file mode 100644 index e3a1dda688ab5f..00000000000000 --- a/target/linux/generic/backport-6.1/715-05-v6.2-phylink-require-valid-state-argument-to-phylink_vali.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 2bf7e4a68c42eed909f3c29582e1fb85cb157e35 Mon Sep 17 00:00:00 2001 -From: Jakub Kicinski -Date: Tue, 25 Oct 2022 11:51:26 -0700 -Subject: [PATCH 05/21] phylink: require valid state argument to - phylink_validate_mask_caps() - -state is deferenced earlier in the function, the NULL check -is pointless. Since we don't have any crash reports presumably -it's safe to assume state is not NULL. - -Fixes: f392a1846489 ("net: phylink: provide phylink_validate_mask_caps() helper") -Reviewed-by: Sean Anderson -Link: https://lore.kernel.org/r/20221025185126.1720553-1-kuba@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -566,7 +566,7 @@ EXPORT_SYMBOL_GPL(phylink_get_capabiliti - /** - * phylink_validate_mask_caps() - Restrict link modes based on caps - * @supported: ethtool bitmask for supported link modes. -- * @state: an (optional) pointer to a &struct phylink_link_state. -+ * @state: pointer to a &struct phylink_link_state. - * @mac_capabilities: bitmask of MAC capabilities - * - * Calculate the supported link modes based on @mac_capabilities, and restrict -@@ -587,8 +587,7 @@ void phylink_validate_mask_caps(unsigned - phylink_caps_to_linkmodes(mask, caps); - - linkmode_and(supported, supported, mask); -- if (state) -- linkmode_and(state->advertising, state->advertising, mask); -+ linkmode_and(state->advertising, state->advertising, mask); - } - EXPORT_SYMBOL_GPL(phylink_validate_mask_caps); - diff --git a/target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch b/target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch deleted file mode 100644 index c217ed87b51d6f..00000000000000 --- a/target/linux/generic/backport-6.1/715-06-v6.2-net-phylink-add-phylink_get_link_timer_ns-helper.patch +++ /dev/null @@ -1,48 +0,0 @@ -From f8fc363bf0c023e4736a0328174b4a24b44ab23a Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:10:37 +0100 -Subject: [PATCH 06/21] net: phylink: add phylink_get_link_timer_ns() helper - -Add a helper to convert the PHY interface mode to the required link -timer setting as stated by the appropriate standard. Inappropriate -interface modes return an error. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - include/linux/phylink.h | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -617,6 +617,30 @@ int phylink_speed_up(struct phylink *pl) - - void phylink_set_port_modes(unsigned long *bits); - -+/** -+ * phylink_get_link_timer_ns - return the PCS link timer value -+ * @interface: link &typedef phy_interface_t mode -+ * -+ * Return the PCS link timer setting in nanoseconds for the PHY @interface -+ * mode, or -EINVAL if not appropriate. -+ */ -+static inline int phylink_get_link_timer_ns(phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ case PHY_INTERFACE_MODE_USXGMII: -+ return 1600000; -+ -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ return 10000000; -+ -+ default: -+ return -EINVAL; -+ } -+} -+ - void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state, - u16 bmsr, u16 lpa); - void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs, diff --git a/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch b/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch deleted file mode 100644 index 90a29ccc36533b..00000000000000 --- a/target/linux/generic/backport-6.1/715-07-v6.2-net-remove-explicit-phylink_generic_validate-referen.patch +++ /dev/null @@ -1,250 +0,0 @@ -From b45b773a96b0e9e8d51e5d005485f4e376d6ce9a Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 4 Nov 2022 17:13:01 +0000 -Subject: [PATCH 07/21] net: remove explicit phylink_generic_validate() - references - -Virtually all conventional network drivers are now converted to use -phylink_generic_validate() - only DSA drivers and fman_memac remain, -so lets remove the necessity for network drivers to explicitly set -this member, and default to phylink_generic_validate() when unset. -This is possible as .validate must currently be set. - -Any remaining instances that have not been addressed by this patch can -be fixed up later. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/E1or0FZ-001tRa-DI@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/altera/altera_tse_main.c | 1 - - drivers/net/ethernet/atheros/ag71xx.c | 1 - - drivers/net/ethernet/cadence/macb_main.c | 1 - - drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 1 - - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 1 - - drivers/net/ethernet/freescale/fman/fman_dtsec.c | 1 - - drivers/net/ethernet/freescale/fman/fman_tgec.c | 1 - - drivers/net/ethernet/marvell/mvneta.c | 1 - - drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 - - drivers/net/ethernet/marvell/prestera/prestera_main.c | 1 - - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 - - drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c | 1 - - drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c | 1 - - drivers/net/ethernet/mscc/ocelot_net.c | 1 - - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 - - drivers/net/ethernet/ti/am65-cpsw-nuss.c | 1 - - drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 1 - - drivers/net/phy/phylink.c | 5 ++++- - drivers/net/usb/asix_devices.c | 1 - - include/linux/phylink.h | 5 +++++ - 20 files changed, 9 insertions(+), 19 deletions(-) - ---- a/drivers/net/ethernet/altera/altera_tse_main.c -+++ b/drivers/net/ethernet/altera/altera_tse_main.c -@@ -1096,7 +1096,6 @@ static struct phylink_pcs *alt_tse_selec - } - - static const struct phylink_mac_ops alt_tse_phylink_ops = { -- .validate = phylink_generic_validate, - .mac_an_restart = alt_tse_mac_an_restart, - .mac_config = alt_tse_mac_config, - .mac_link_down = alt_tse_mac_link_down, ---- a/drivers/net/ethernet/atheros/ag71xx.c -+++ b/drivers/net/ethernet/atheros/ag71xx.c -@@ -1086,7 +1086,6 @@ static void ag71xx_mac_link_up(struct ph - } - - static const struct phylink_mac_ops ag71xx_phylink_mac_ops = { -- .validate = phylink_generic_validate, - .mac_config = ag71xx_mac_config, - .mac_link_down = ag71xx_mac_link_down, - .mac_link_up = ag71xx_mac_link_up, ---- a/drivers/net/ethernet/cadence/macb_main.c -+++ b/drivers/net/ethernet/cadence/macb_main.c -@@ -752,7 +752,6 @@ static struct phylink_pcs *macb_mac_sele - } - - static const struct phylink_mac_ops macb_phylink_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = macb_mac_select_pcs, - .mac_config = macb_mac_config, - .mac_link_down = macb_mac_link_down, ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c -@@ -235,7 +235,6 @@ static void dpaa2_mac_link_down(struct p - } - - static const struct phylink_mac_ops dpaa2_mac_phylink_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = dpaa2_mac_select_pcs, - .mac_config = dpaa2_mac_config, - .mac_link_up = dpaa2_mac_link_up, ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -1111,7 +1111,6 @@ static void enetc_pl_mac_link_down(struc - } - - static const struct phylink_mac_ops enetc_mac_phylink_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = enetc_pl_mac_select_pcs, - .mac_config = enetc_pl_mac_config, - .mac_link_up = enetc_pl_mac_link_up, ---- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c -+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c -@@ -986,7 +986,6 @@ static void dtsec_link_down(struct phyli - } - - static const struct phylink_mac_ops dtsec_mac_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = dtsec_select_pcs, - .mac_config = dtsec_mac_config, - .mac_link_up = dtsec_link_up, ---- a/drivers/net/ethernet/freescale/fman/fman_tgec.c -+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c -@@ -469,7 +469,6 @@ static void tgec_link_down(struct phylin - } - - static const struct phylink_mac_ops tgec_mac_ops = { -- .validate = phylink_generic_validate, - .mac_config = tgec_mac_config, - .mac_link_up = tgec_link_up, - .mac_link_down = tgec_link_down, ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -4228,7 +4228,6 @@ static void mvneta_mac_link_up(struct ph - } - - static const struct phylink_mac_ops mvneta_phylink_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = mvneta_mac_select_pcs, - .mac_prepare = mvneta_mac_prepare, - .mac_config = mvneta_mac_config, ---- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -@@ -6633,7 +6633,6 @@ static void mvpp2_mac_link_down(struct p - } - - static const struct phylink_mac_ops mvpp2_phylink_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = mvpp2_select_pcs, - .mac_prepare = mvpp2_mac_prepare, - .mac_config = mvpp2_mac_config, ---- a/drivers/net/ethernet/marvell/prestera/prestera_main.c -+++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c -@@ -360,7 +360,6 @@ static void prestera_pcs_an_restart(stru - } - - static const struct phylink_mac_ops prestera_mac_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = prestera_mac_select_pcs, - .mac_config = prestera_mac_config, - .mac_link_down = prestera_mac_link_down, ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -653,7 +653,6 @@ static void mtk_mac_link_up(struct phyli - } - - static const struct phylink_mac_ops mtk_phylink_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = mtk_mac_select_pcs, - .mac_pcs_get_state = mtk_mac_pcs_get_state, - .mac_config = mtk_mac_config, ---- a/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c -+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_phylink.c -@@ -125,7 +125,6 @@ static void lan966x_pcs_aneg_restart(str - } - - const struct phylink_mac_ops lan966x_phylink_mac_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = lan966x_phylink_mac_select, - .mac_config = lan966x_phylink_mac_config, - .mac_prepare = lan966x_phylink_mac_prepare, ---- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c -+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c -@@ -138,7 +138,6 @@ const struct phylink_pcs_ops sparx5_phyl - }; - - const struct phylink_mac_ops sparx5_phylink_mac_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = sparx5_phylink_mac_select_pcs, - .mac_config = sparx5_phylink_mac_config, - .mac_link_down = sparx5_phylink_mac_link_down, ---- a/drivers/net/ethernet/mscc/ocelot_net.c -+++ b/drivers/net/ethernet/mscc/ocelot_net.c -@@ -1737,7 +1737,6 @@ static void vsc7514_phylink_mac_link_up( - } - - static const struct phylink_mac_ops ocelot_phylink_ops = { -- .validate = phylink_generic_validate, - .mac_config = vsc7514_phylink_mac_config, - .mac_link_down = vsc7514_phylink_mac_link_down, - .mac_link_up = vsc7514_phylink_mac_link_up, ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -1090,7 +1090,6 @@ static void stmmac_mac_link_up(struct ph - } - - static const struct phylink_mac_ops stmmac_phylink_mac_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = stmmac_mac_select_pcs, - .mac_config = stmmac_mac_config, - .mac_link_down = stmmac_mac_link_down, ---- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c -+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c -@@ -1493,7 +1493,6 @@ static void am65_cpsw_nuss_mac_link_up(s - } - - static const struct phylink_mac_ops am65_cpsw_phylink_mac_ops = { -- .validate = phylink_generic_validate, - .mac_config = am65_cpsw_nuss_mac_config, - .mac_link_down = am65_cpsw_nuss_mac_link_down, - .mac_link_up = am65_cpsw_nuss_mac_link_up, ---- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -@@ -1737,7 +1737,6 @@ static void axienet_mac_link_up(struct p - } - - static const struct phylink_mac_ops axienet_phylink_ops = { -- .validate = phylink_generic_validate, - .mac_select_pcs = axienet_mac_select_pcs, - .mac_config = axienet_mac_config, - .mac_link_down = axienet_mac_link_down, ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -651,7 +651,10 @@ static int phylink_validate_mac_and_pcs( - } - - /* Then validate the link parameters with the MAC */ -- pl->mac_ops->validate(pl->config, supported, state); -+ if (pl->mac_ops->validate) -+ pl->mac_ops->validate(pl->config, supported, state); -+ else -+ phylink_generic_validate(pl->config, supported, state); - - return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; - } ---- a/drivers/net/usb/asix_devices.c -+++ b/drivers/net/usb/asix_devices.c -@@ -787,7 +787,6 @@ static void ax88772_mac_link_up(struct p - } - - static const struct phylink_mac_ops ax88772_phylink_mac_ops = { -- .validate = phylink_generic_validate, - .mac_config = ax88772_mac_config, - .mac_link_down = ax88772_mac_link_down, - .mac_link_up = ax88772_mac_link_up, ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -207,6 +207,11 @@ struct phylink_mac_ops { - * - * If the @state->interface mode is not supported, then the @supported - * mask must be cleared. -+ * -+ * This member is optional; if not set, the generic validator will be -+ * used making use of @config->mac_capabilities and -+ * @config->supported_interfaces to determine which link modes are -+ * supported. - */ - void validate(struct phylink_config *config, unsigned long *supported, - struct phylink_link_state *state); diff --git a/target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch b/target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch deleted file mode 100644 index 37d82b2cd7db93..00000000000000 --- a/target/linux/generic/backport-6.1/715-08-net-sfp-make-sfp_bus_find_fwnode-take-a-const-fwnode.patch +++ /dev/null @@ -1,48 +0,0 @@ -From a90ac762d345890b40d88a1385a34a2449c2d75e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 24 Mar 2023 09:23:42 +0000 -Subject: [PATCH] net: sfp: make sfp_bus_find_fwnode() take a const fwnode - -sfp_bus_find_fwnode() does not write to the fwnode, so let's make it -const. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/phy/sfp-bus.c | 2 +- - include/linux/sfp.h | 5 +++-- - 2 files changed, 4 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/sfp-bus.c -+++ b/drivers/net/phy/sfp-bus.c -@@ -603,7 +603,7 @@ static void sfp_upstream_clear(struct sf - * - %-ENOMEM if we failed to allocate the bus. - * - an error from the upstream's connect_phy() method. - */ --struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode) -+struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode) - { - struct fwnode_reference_args ref; - struct sfp_bus *bus; ---- a/include/linux/sfp.h -+++ b/include/linux/sfp.h -@@ -548,7 +548,7 @@ int sfp_get_module_eeprom_by_page(struct - void sfp_upstream_start(struct sfp_bus *bus); - void sfp_upstream_stop(struct sfp_bus *bus); - void sfp_bus_put(struct sfp_bus *bus); --struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode); -+struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode); - int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, - const struct sfp_upstream_ops *ops); - void sfp_bus_del_upstream(struct sfp_bus *bus); -@@ -610,7 +610,8 @@ static inline void sfp_bus_put(struct sf - { - } - --static inline struct sfp_bus *sfp_bus_find_fwnode(struct fwnode_handle *fwnode) -+static inline struct sfp_bus * -+sfp_bus_find_fwnode(const struct fwnode_handle *fwnode) - { - return NULL; - } diff --git a/target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch b/target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch deleted file mode 100644 index 290cb8d161d632..00000000000000 --- a/target/linux/generic/backport-6.1/715-09-v6.4-net-pcs-lynx-don-t-print-an_enabled-in-pcs_get_state.patch +++ /dev/null @@ -1,31 +0,0 @@ -From ecec0ebbc6381a5a375f1cf10c4858f24e91e2ef Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 15 Mar 2023 14:46:49 +0000 -Subject: [PATCH] net: pcs: lynx: don't print an_enabled in pcs_get_state() - -an_enabled will be going away, and in any case, pcs_get_state() should -not be updating this member. Remove the print. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Steen Hegelund -Signed-off-by: David S. Miller ---- - drivers/net/pcs/pcs-lynx.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/pcs/pcs-lynx.c -+++ b/drivers/net/pcs/pcs-lynx.c -@@ -115,11 +115,11 @@ static void lynx_pcs_get_state(struct ph - } - - dev_dbg(&lynx->mdio->dev, -- "mode=%s/%s/%s link=%u an_enabled=%u an_complete=%u\n", -+ "mode=%s/%s/%s link=%u an_complete=%u\n", - phy_modes(state->interface), - phy_speed_to_str(state->speed), - phy_duplex_to_str(state->duplex), -- state->link, state->an_enabled, state->an_complete); -+ state->link, state->an_complete); - } - - static int lynx_pcs_config_giga(struct mdio_device *pcs, unsigned int mode, diff --git a/target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch b/target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch deleted file mode 100644 index 38ea2654760798..00000000000000 --- a/target/linux/generic/backport-6.1/715-10-v6.4-net-dpaa2-mac-use-Autoneg-bit-rather-than-an_enabled.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 99d0f3a1095f4c938b1665025c29411edafe8a01 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 21 Mar 2023 15:58:44 +0000 -Subject: [PATCH] net: dpaa2-mac: use Autoneg bit rather than an_enabled - -The Autoneg bit in the advertising bitmap and state->an_enabled are -always identical. Thus, we will be removing state->an_enabled. - -Use the Autoneg bit in the advertising bitmap to indicate whether -autonegotiation should be used, rather than using the an_enabled -member which will be going away. This means we use the same condition -as phylink_mii_c22_pcs_config(). - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Simon Horman -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c -@@ -158,7 +158,8 @@ static void dpaa2_mac_config(struct phyl - struct dpmac_link_state *dpmac_state = &mac->state; - int err; - -- if (state->an_enabled) -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ state->advertising)) - dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG; - else - dpmac_state->options &= ~DPMAC_LINK_OPT_AUTONEG; diff --git a/target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch b/target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch deleted file mode 100644 index cb9c411cfb0d35..00000000000000 --- a/target/linux/generic/backport-6.1/715-11-v6.4-net-phylink-support-validated-pause-and-autoneg-in-f.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 471c40bde606ec0b1ce8c616f7998739c7a783a6 Mon Sep 17 00:00:00 2001 -From: Ivan Bornyakov -Date: Fri, 10 Feb 2023 18:46:27 +0300 -Subject: [PATCH 10/21] net: phylink: support validated pause and autoneg in - fixed-link - -In fixed-link setup phylink_parse_fixedlink() unconditionally sets -Pause, Asym_Pause and Autoneg bits to "supported" bitmap, while MAC may -not support these. - -This leads to ethtool reporting: - - > Supported pause frame use: Symmetric Receive-only - > Supports auto-negotiation: Yes - -regardless of what is actually supported. - -Instead of unconditionally set Pause, Asym_Pause and Autoneg it is -sensible to set them according to validated "supported" bitmap, i.e. the -result of phylink_validate(). - -Signed-off-by: Ivan Bornyakov -Signed-off-by: David S. Miller ---- - drivers/net/phy/phylink.c | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -709,6 +709,7 @@ static int phylink_parse_fixedlink(struc - struct fwnode_handle *fwnode) - { - struct fwnode_handle *fixed_node; -+ bool pause, asym_pause, autoneg; - const struct phy_setting *s; - struct gpio_desc *desc; - u32 speed; -@@ -781,13 +782,23 @@ static int phylink_parse_fixedlink(struc - linkmode_copy(pl->link_config.advertising, pl->supported); - phylink_validate(pl, pl->supported, &pl->link_config); - -+ pause = phylink_test(pl->supported, Pause); -+ asym_pause = phylink_test(pl->supported, Asym_Pause); -+ autoneg = phylink_test(pl->supported, Autoneg); - s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex, - pl->supported, true); - linkmode_zero(pl->supported); - phylink_set(pl->supported, MII); -- phylink_set(pl->supported, Pause); -- phylink_set(pl->supported, Asym_Pause); -- phylink_set(pl->supported, Autoneg); -+ -+ if (pause) -+ phylink_set(pl->supported, Pause); -+ -+ if (asym_pause) -+ phylink_set(pl->supported, Asym_Pause); -+ -+ if (autoneg) -+ phylink_set(pl->supported, Autoneg); -+ - if (s) { - __set_bit(s->bit, pl->supported); - __set_bit(s->bit, pl->link_config.lp_advertising); diff --git a/target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch b/target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch deleted file mode 100644 index 03b4f9d0c4cc2a..00000000000000 --- a/target/linux/generic/backport-6.1/715-12-v6.4-net-phylink-remove-an_enabled.patch +++ /dev/null @@ -1,177 +0,0 @@ -From 7211ffd70941933a7825a56cf480f07ee81c321c Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 21 Mar 2023 15:58:54 +0000 -Subject: [PATCH 11/21] net: phylink: remove an_enabled - -The Autoneg bit in the advertising bitmap and state->an_enabled are -always identical. state->an_enabled is now no longer used by any -drivers, so lets kill this duplication. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Simon Horman -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 37 +++++++++++++++++-------------------- - include/linux/phylink.h | 2 -- - 2 files changed, 17 insertions(+), 22 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -841,7 +841,6 @@ static int phylink_parse_mode(struct phy - phylink_set(pl->supported, Autoneg); - phylink_set(pl->supported, Asym_Pause); - phylink_set(pl->supported, Pause); -- pl->link_config.an_enabled = true; - pl->cfg_link_an_mode = MLO_AN_INBAND; - - switch (pl->link_config.interface) { -@@ -944,9 +943,6 @@ static int phylink_parse_mode(struct phy - "failed to validate link configuration for in-band status\n"); - return -EINVAL; - } -- -- /* Check if MAC/PCS also supports Autoneg. */ -- pl->link_config.an_enabled = phylink_test(pl->supported, Autoneg); - } - - return 0; -@@ -956,7 +952,8 @@ static void phylink_apply_manual_flow(st - struct phylink_link_state *state) - { - /* If autoneg is disabled, pause AN is also disabled */ -- if (!state->an_enabled) -+ if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ state->advertising)) - state->pause &= ~MLO_PAUSE_AN; - - /* Manual configuration of pause modes */ -@@ -996,21 +993,22 @@ static void phylink_mac_config(struct ph - const struct phylink_link_state *state) - { - phylink_dbg(pl, -- "%s: mode=%s/%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n", -+ "%s: mode=%s/%s/%s/%s/%s adv=%*pb pause=%02x link=%u\n", - __func__, phylink_an_mode_str(pl->cur_link_an_mode), - phy_modes(state->interface), - phy_speed_to_str(state->speed), - phy_duplex_to_str(state->duplex), - phy_rate_matching_to_str(state->rate_matching), - __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising, -- state->pause, state->link, state->an_enabled); -+ state->pause, state->link); - - pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, state); - } - - static void phylink_mac_pcs_an_restart(struct phylink *pl) - { -- if (pl->link_config.an_enabled && -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ pl->link_config.advertising) && - phy_interface_mode_is_8023z(pl->link_config.interface) && - phylink_autoneg_inband(pl->cur_link_an_mode)) { - if (pl->pcs) -@@ -1137,9 +1135,9 @@ static void phylink_mac_pcs_get_state(st - linkmode_copy(state->advertising, pl->link_config.advertising); - linkmode_zero(state->lp_advertising); - state->interface = pl->link_config.interface; -- state->an_enabled = pl->link_config.an_enabled; - state->rate_matching = pl->link_config.rate_matching; -- if (state->an_enabled) { -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ state->advertising)) { - state->speed = SPEED_UNKNOWN; - state->duplex = DUPLEX_UNKNOWN; - state->pause = MLO_PAUSE_NONE; -@@ -1531,7 +1529,6 @@ struct phylink *phylink_create(struct ph - pl->link_config.pause = MLO_PAUSE_AN; - pl->link_config.speed = SPEED_UNKNOWN; - pl->link_config.duplex = DUPLEX_UNKNOWN; -- pl->link_config.an_enabled = true; - pl->mac_ops = mac_ops; - __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); - timer_setup(&pl->link_poll, phylink_fixed_poll, 0); -@@ -2155,8 +2152,9 @@ static void phylink_get_ksettings(const - kset->base.speed = state->speed; - kset->base.duplex = state->duplex; - } -- kset->base.autoneg = state->an_enabled ? AUTONEG_ENABLE : -- AUTONEG_DISABLE; -+ kset->base.autoneg = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ state->advertising) ? -+ AUTONEG_ENABLE : AUTONEG_DISABLE; - } - - /** -@@ -2303,9 +2301,8 @@ int phylink_ethtool_ksettings_set(struct - /* We have ruled out the case with a PHY attached, and the - * fixed-link cases. All that is left are in-band links. - */ -- config.an_enabled = kset->base.autoneg == AUTONEG_ENABLE; - linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising, -- config.an_enabled); -+ kset->base.autoneg == AUTONEG_ENABLE); - - /* If this link is with an SFP, ensure that changes to advertised modes - * also cause the associated interface to be selected such that the -@@ -2339,13 +2336,14 @@ int phylink_ethtool_ksettings_set(struct - } - - /* If autonegotiation is enabled, we must have an advertisement */ -- if (config.an_enabled && phylink_is_empty_linkmode(config.advertising)) -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ config.advertising) && -+ phylink_is_empty_linkmode(config.advertising)) - return -EINVAL; - - mutex_lock(&pl->state_mutex); - pl->link_config.speed = config.speed; - pl->link_config.duplex = config.duplex; -- pl->link_config.an_enabled = config.an_enabled; - - if (pl->link_config.interface != config.interface) { - /* The interface changed, e.g. 1000base-X <-> 2500base-X */ -@@ -2951,7 +2949,6 @@ static int phylink_sfp_config_phy(struct - config.speed = SPEED_UNKNOWN; - config.duplex = DUPLEX_UNKNOWN; - config.pause = MLO_PAUSE_AN; -- config.an_enabled = pl->link_config.an_enabled; - - /* Ignore errors if we're expecting a PHY to attach later */ - ret = phylink_validate(pl, support, &config); -@@ -3020,7 +3017,6 @@ static int phylink_sfp_config_optical(st - config.speed = SPEED_UNKNOWN; - config.duplex = DUPLEX_UNKNOWN; - config.pause = MLO_PAUSE_AN; -- config.an_enabled = true; - - /* For all the interfaces that are supported, reduce the sfp_support - * mask to only those link modes that can be supported. -@@ -3354,7 +3350,8 @@ void phylink_mii_c22_pcs_decode_state(st - /* If there is no link or autonegotiation is disabled, the LP advertisement - * data is not meaningful, so don't go any further. - */ -- if (!state->link || !state->an_enabled) -+ if (!state->link || !linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ state->advertising)) - return; - - switch (state->interface) { ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -93,7 +93,6 @@ static inline bool phylink_autoneg_inban - * the medium link mode (@speed and @duplex) and the speed/duplex of the phy - * interface mode (@interface) are different. - * @link: true if the link is up. -- * @an_enabled: true if autonegotiation is enabled/desired. - * @an_complete: true if autonegotiation has completed. - */ - struct phylink_link_state { -@@ -105,7 +104,6 @@ struct phylink_link_state { - int pause; - int rate_matching; - unsigned int link:1; -- unsigned int an_enabled:1; - unsigned int an_complete:1; - }; - diff --git a/target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch b/target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch deleted file mode 100644 index c06a367b8be370..00000000000000 --- a/target/linux/generic/backport-6.1/715-13-v6.5-net-phylink-constify-fwnode-arguments.patch +++ /dev/null @@ -1,88 +0,0 @@ -From a3555d1f5c208f0a63eafee77381f68d304a0512 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 12 May 2023 17:58:37 +0100 -Subject: [PATCH 12/21] net: phylink: constify fwnode arguments - -Both phylink_create() and phylink_fwnode_phy_connect() do not modify -the fwnode argument that they are passed, so lets constify these. - -Reviewed-by: Simon Horman -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/phylink.c | 11 ++++++----- - include/linux/phylink.h | 9 +++++---- - 2 files changed, 11 insertions(+), 9 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -706,7 +706,7 @@ static int phylink_validate(struct phyli - } - - static int phylink_parse_fixedlink(struct phylink *pl, -- struct fwnode_handle *fwnode) -+ const struct fwnode_handle *fwnode) - { - struct fwnode_handle *fixed_node; - bool pause, asym_pause, autoneg; -@@ -817,7 +817,8 @@ static int phylink_parse_fixedlink(struc - return 0; - } - --static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode) -+static int phylink_parse_mode(struct phylink *pl, -+ const struct fwnode_handle *fwnode) - { - struct fwnode_handle *dn; - const char *managed; -@@ -1440,7 +1441,7 @@ static void phylink_fixed_poll(struct ti - static const struct sfp_upstream_ops sfp_phylink_ops; - - static int phylink_register_sfp(struct phylink *pl, -- struct fwnode_handle *fwnode) -+ const struct fwnode_handle *fwnode) - { - struct sfp_bus *bus; - int ret; -@@ -1479,7 +1480,7 @@ static int phylink_register_sfp(struct p - * must use IS_ERR() to check for errors from this function. - */ - struct phylink *phylink_create(struct phylink_config *config, -- struct fwnode_handle *fwnode, -+ const struct fwnode_handle *fwnode, - phy_interface_t iface, - const struct phylink_mac_ops *mac_ops) - { -@@ -1809,7 +1810,7 @@ EXPORT_SYMBOL_GPL(phylink_of_phy_connect - * Returns 0 on success or a negative errno. - */ - int phylink_fwnode_phy_connect(struct phylink *pl, -- struct fwnode_handle *fwnode, -+ const struct fwnode_handle *fwnode, - u32 flags) - { - struct fwnode_handle *phy_fwnode; ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -568,16 +568,17 @@ void phylink_generic_validate(struct phy - unsigned long *supported, - struct phylink_link_state *state); - --struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *, -- phy_interface_t iface, -- const struct phylink_mac_ops *mac_ops); -+struct phylink *phylink_create(struct phylink_config *, -+ const struct fwnode_handle *, -+ phy_interface_t, -+ const struct phylink_mac_ops *); - void phylink_destroy(struct phylink *); - bool phylink_expects_phy(struct phylink *pl); - - int phylink_connect_phy(struct phylink *, struct phy_device *); - int phylink_of_phy_connect(struct phylink *, struct device_node *, u32 flags); - int phylink_fwnode_phy_connect(struct phylink *pl, -- struct fwnode_handle *fwnode, -+ const struct fwnode_handle *fwnode, - u32 flags); - void phylink_disconnect_phy(struct phylink *); - diff --git a/target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch b/target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch deleted file mode 100644 index 2649634dc7ba0b..00000000000000 --- a/target/linux/generic/backport-6.1/715-14-v6.3-net-phy-constify-fwnode_get_phy_node-fwnode-argument.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 4a0faa02d419a6728abef0f1d8a32d8c35ef95e6 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 24 Mar 2023 09:23:53 +0000 -Subject: [PATCH] net: phy: constify fwnode_get_phy_node() fwnode argument - -fwnode_get_phy_node() does not motify the fwnode structure, so make -the argument const, - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/phy/phy_device.c | 2 +- - include/linux/phy.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -3003,7 +3003,7 @@ EXPORT_SYMBOL_GPL(device_phy_find_device - * and "phy-device" are not supported in ACPI. DT supports all the three - * named references to the phy node. - */ --struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode) -+struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode) - { - struct fwnode_handle *phy_node; - ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -1473,7 +1473,7 @@ int fwnode_get_phy_id(struct fwnode_hand - struct mdio_device *fwnode_mdio_find_device(struct fwnode_handle *fwnode); - struct phy_device *fwnode_phy_find_device(struct fwnode_handle *phy_fwnode); - struct phy_device *device_phy_find_device(struct device *dev); --struct fwnode_handle *fwnode_get_phy_node(struct fwnode_handle *fwnode); -+struct fwnode_handle *fwnode_get_phy_node(const struct fwnode_handle *fwnode); - struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45); - int phy_device_register(struct phy_device *phy); - void phy_device_free(struct phy_device *phydev); diff --git a/target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch b/target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch deleted file mode 100644 index 5eba18b0260544..00000000000000 --- a/target/linux/generic/backport-6.1/715-15-v6.4-net-phylink-fix-ksettings_set-ethtool-call.patch +++ /dev/null @@ -1,44 +0,0 @@ -From cc73de0411f7d3cdd157564a78f7a39058420ff8 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Sat, 13 May 2023 22:03:45 +0100 -Subject: [PATCH 13/21] net: phylink: fix ksettings_set() ethtool call - -While testing a Fiberstore SFP-10G-T module (which uses 10GBASE-R with -rate adaption) in a Clearfog platform (which can't do that) it was -found that the PHYs advertisement was not limited according to the -hosts capabilities when using ethtool to change it. - -Fix this by ensuring that we mask the advertisement with the computed -support mask as the very first thing we do. - -Fixes: cbc1bb1e4689 ("net: phylink: simplify phy case for ksettings_set method") -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/phylink.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -2226,6 +2226,10 @@ int phylink_ethtool_ksettings_set(struct - - ASSERT_RTNL(); - -+ /* Mask out unsupported advertisements */ -+ linkmode_and(config.advertising, kset->link_modes.advertising, -+ pl->supported); -+ - if (pl->phydev) { - /* We can rely on phylib for this update; we also do not need - * to update the pl->link_config settings: -@@ -2250,10 +2254,6 @@ int phylink_ethtool_ksettings_set(struct - - config = pl->link_config; - -- /* Mask out unsupported advertisements */ -- linkmode_and(config.advertising, kset->link_modes.advertising, -- pl->supported); -- - /* FIXME: should we reject autoneg if phy/mac does not support it? */ - switch (kset->base.autoneg) { - case AUTONEG_DISABLE: diff --git a/target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch b/target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch deleted file mode 100644 index f9670539fca92c..00000000000000 --- a/target/linux/generic/backport-6.1/715-16-v6.5-net-sfp-add-support-for-setting-signalling-rate.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 0100d1c5789018ba77bf2f4fab3bd91ecece7b3b Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 17 May 2023 11:38:12 +0100 -Subject: [PATCH 14/21] net: sfp: add support for setting signalling rate - -Add support to the SFP layer to allow phylink to set the signalling -rate for a SFP module. The rate given will be in units of kilo-baud -(1000 baud). - -Reviewed-by: Simon Horman -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 24 ++++++++++++++++++++++++ - drivers/net/phy/sfp-bus.c | 20 ++++++++++++++++++++ - drivers/net/phy/sfp.c | 5 +++++ - drivers/net/phy/sfp.h | 1 + - include/linux/sfp.h | 6 ++++++ - 5 files changed, 56 insertions(+) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -156,6 +156,23 @@ static const char *phylink_an_mode_str(u - return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown"; - } - -+static unsigned int phylink_interface_signal_rate(phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_1000BASEX: /* 1.25Mbd */ -+ return 1250; -+ case PHY_INTERFACE_MODE_2500BASEX: /* 3.125Mbd */ -+ return 3125; -+ case PHY_INTERFACE_MODE_5GBASER: /* 5.15625Mbd */ -+ return 5156; -+ case PHY_INTERFACE_MODE_10GBASER: /* 10.3125Mbd */ -+ return 10313; -+ default: -+ return 0; -+ } -+} -+ - /** - * phylink_interface_max_speed() - get the maximum speed of a phy interface - * @interface: phy interface mode defined by &typedef phy_interface_t -@@ -1024,6 +1041,7 @@ static void phylink_major_config(struct - { - struct phylink_pcs *pcs = NULL; - bool pcs_changed = false; -+ unsigned int rate_kbd; - int err; - - phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); -@@ -1083,6 +1101,12 @@ static void phylink_major_config(struct - ERR_PTR(err)); - } - -+ if (pl->sfp_bus) { -+ rate_kbd = phylink_interface_signal_rate(state->interface); -+ if (rate_kbd) -+ sfp_upstream_set_signal_rate(pl->sfp_bus, rate_kbd); -+ } -+ - phylink_pcs_poll_start(pl); - } - ---- a/drivers/net/phy/sfp-bus.c -+++ b/drivers/net/phy/sfp-bus.c -@@ -586,6 +586,26 @@ static void sfp_upstream_clear(struct sf - } - - /** -+ * sfp_upstream_set_signal_rate() - set data signalling rate -+ * @bus: a pointer to the &struct sfp_bus structure for the sfp module -+ * @rate_kbd: signalling rate in units of 1000 baud -+ * -+ * Configure the rate select settings on the SFP module for the signalling -+ * rate (not the same as the data rate). -+ * -+ * Locks that may be held: -+ * Phylink's state_mutex -+ * rtnl lock -+ * SFP's sm_mutex -+ */ -+void sfp_upstream_set_signal_rate(struct sfp_bus *bus, unsigned int rate_kbd) -+{ -+ if (bus->registered) -+ bus->socket_ops->set_signal_rate(bus->sfp, rate_kbd); -+} -+EXPORT_SYMBOL_GPL(sfp_upstream_set_signal_rate); -+ -+/** - * sfp_bus_find_fwnode() - parse and locate the SFP bus from fwnode - * @fwnode: firmware node for the parent device (MAC or PHY) - * ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -2473,6 +2473,10 @@ static void sfp_stop(struct sfp *sfp) - sfp_sm_event(sfp, SFP_E_DEV_DOWN); - } - -+static void sfp_set_signal_rate(struct sfp *sfp, unsigned int rate_kbd) -+{ -+} -+ - static int sfp_module_info(struct sfp *sfp, struct ethtool_modinfo *modinfo) - { - /* locking... and check module is present */ -@@ -2551,6 +2555,7 @@ static const struct sfp_socket_ops sfp_m - .detach = sfp_detach, - .start = sfp_start, - .stop = sfp_stop, -+ .set_signal_rate = sfp_set_signal_rate, - .module_info = sfp_module_info, - .module_eeprom = sfp_module_eeprom, - .module_eeprom_by_page = sfp_module_eeprom_by_page, ---- a/drivers/net/phy/sfp.h -+++ b/drivers/net/phy/sfp.h -@@ -19,6 +19,7 @@ struct sfp_socket_ops { - void (*detach)(struct sfp *sfp); - void (*start)(struct sfp *sfp); - void (*stop)(struct sfp *sfp); -+ void (*set_signal_rate)(struct sfp *sfp, unsigned int rate_kbd); - int (*module_info)(struct sfp *sfp, struct ethtool_modinfo *modinfo); - int (*module_eeprom)(struct sfp *sfp, struct ethtool_eeprom *ee, - u8 *data); ---- a/include/linux/sfp.h -+++ b/include/linux/sfp.h -@@ -547,6 +547,7 @@ int sfp_get_module_eeprom_by_page(struct - struct netlink_ext_ack *extack); - void sfp_upstream_start(struct sfp_bus *bus); - void sfp_upstream_stop(struct sfp_bus *bus); -+void sfp_upstream_set_signal_rate(struct sfp_bus *bus, unsigned int rate_kbd); - void sfp_bus_put(struct sfp_bus *bus); - struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode); - int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream, -@@ -606,6 +607,11 @@ static inline void sfp_upstream_stop(str - { - } - -+static inline void sfp_upstream_set_signal_rate(struct sfp_bus *bus, -+ unsigned int rate_kbd) -+{ -+} -+ - static inline void sfp_bus_put(struct sfp_bus *bus) - { - } diff --git a/target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch b/target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch deleted file mode 100644 index 8a694c86dafc1a..00000000000000 --- a/target/linux/generic/backport-6.1/715-17-v6.5-net-phy-add-helpers-for-comparing-phy-IDs.patch +++ /dev/null @@ -1,147 +0,0 @@ -From b84acdb07222a701bfc6403b374249c86f97d18d Mon Sep 17 00:00:00 2001 -From: Russell King -Date: Fri, 19 May 2023 14:03:59 +0100 -Subject: [PATCH 15/21] net: phy: add helpers for comparing phy IDs - -There are several places which open code comparing PHY IDs. Provide a -couple of helpers to assist with this, using a slightly simpler test -than the original: - -- phy_id_compare() compares two arbitary PHY IDs and a mask of the - significant bits in the ID. -- phydev_id_compare() compares the bound phydev with the specified - PHY ID, using the bound driver's mask. - -Signed-off-by: Russell King -Reviewed-by: Simon Horman -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/micrel.c | 6 +++--- - drivers/net/phy/phy_device.c | 16 +++++++--------- - drivers/net/phy/phylink.c | 4 ++-- - include/linux/phy.h | 28 ++++++++++++++++++++++++++++ - 4 files changed, 40 insertions(+), 14 deletions(-) - ---- a/drivers/net/phy/micrel.c -+++ b/drivers/net/phy/micrel.c -@@ -620,7 +620,7 @@ static int ksz8051_ksz8795_match_phy_dev - { - int ret; - -- if ((phydev->phy_id & MICREL_PHY_ID_MASK) != PHY_ID_KSZ8051) -+ if (!phy_id_compare(phydev->phy_id, PHY_ID_KSZ8051, MICREL_PHY_ID_MASK)) - return 0; - - ret = phy_read(phydev, MII_BMSR); -@@ -1455,7 +1455,7 @@ static int ksz9x31_cable_test_fault_leng - * - * distance to fault = (VCT_DATA - 22) * 4 / cable propagation velocity - */ -- if ((phydev->phy_id & MICREL_PHY_ID_MASK) == PHY_ID_KSZ9131) -+ if (phydev_id_compare(phydev, PHY_ID_KSZ9131)) - dt = clamp(dt - 22, 0, 255); - - return (dt * 400) / 10; -@@ -1887,7 +1887,7 @@ static __always_inline int ksz886x_cable - */ - dt = FIELD_GET(data_mask, status); - -- if ((phydev->phy_id & MICREL_PHY_ID_MASK) == PHY_ID_LAN8814) -+ if (phydev_id_compare(phydev, PHY_ID_LAN8814)) - return ((dt - 22) * 800) / 10; - else - return (dt * 400) / 10; ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -422,8 +422,7 @@ int phy_unregister_fixup(const char *bus - fixup = list_entry(pos, struct phy_fixup, list); - - if ((!strcmp(fixup->bus_id, bus_id)) && -- ((fixup->phy_uid & phy_uid_mask) == -- (phy_uid & phy_uid_mask))) { -+ phy_id_compare(fixup->phy_uid, phy_uid, phy_uid_mask)) { - list_del(&fixup->list); - kfree(fixup); - ret = 0; -@@ -459,8 +458,8 @@ static int phy_needs_fixup(struct phy_de - if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0) - return 0; - -- if ((fixup->phy_uid & fixup->phy_uid_mask) != -- (phydev->phy_id & fixup->phy_uid_mask)) -+ if (!phy_id_compare(phydev->phy_id, fixup->phy_uid, -+ fixup->phy_uid_mask)) - if (fixup->phy_uid != PHY_ANY_UID) - return 0; - -@@ -507,15 +506,14 @@ static int phy_bus_match(struct device * - if (phydev->c45_ids.device_ids[i] == 0xffffffff) - continue; - -- if ((phydrv->phy_id & phydrv->phy_id_mask) == -- (phydev->c45_ids.device_ids[i] & -- phydrv->phy_id_mask)) -+ if (phy_id_compare(phydev->c45_ids.device_ids[i], -+ phydrv->phy_id, phydrv->phy_id_mask)) - return 1; - } - return 0; - } else { -- return (phydrv->phy_id & phydrv->phy_id_mask) == -- (phydev->phy_id & phydrv->phy_id_mask); -+ return phy_id_compare(phydev->phy_id, phydrv->phy_id, -+ phydrv->phy_id_mask); - } - } - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -3151,8 +3151,8 @@ static void phylink_sfp_link_up(void *up - */ - static bool phylink_phy_no_inband(struct phy_device *phy) - { -- return phy->is_c45 && -- (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150; -+ return phy->is_c45 && phy_id_compare(phy->c45_ids.device_ids[1], -+ 0xae025150, 0xfffffff0); - } - - static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy) ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -993,6 +993,34 @@ struct phy_driver { - #define PHY_ID_MATCH_MODEL(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 4) - #define PHY_ID_MATCH_VENDOR(id) .phy_id = (id), .phy_id_mask = GENMASK(31, 10) - -+/** -+ * phy_id_compare - compare @id1 with @id2 taking account of @mask -+ * @id1: first PHY ID -+ * @id2: second PHY ID -+ * @mask: the PHY ID mask, set bits are significant in matching -+ * -+ * Return true if the bits from @id1 and @id2 specified by @mask match. -+ * This uses an equivalent test to (@id & @mask) == (@phy_id & @mask). -+ */ -+static inline bool phy_id_compare(u32 id1, u32 id2, u32 mask) -+{ -+ return !((id1 ^ id2) & mask); -+} -+ -+/** -+ * phydev_id_compare - compare @id with the PHY's Clause 22 ID -+ * @phydev: the PHY device -+ * @id: the PHY ID to be matched -+ * -+ * Compare the @phydev clause 22 ID with the provided @id and return true or -+ * false depending whether it matches, using the bound driver mask. The -+ * @phydev must be bound to a driver. -+ */ -+static inline bool phydev_id_compare(struct phy_device *phydev, u32 id) -+{ -+ return phy_id_compare(id, phydev->phy_id, phydev->drv->phy_id_mask); -+} -+ - /* A Structure for boards to register fixups with the PHY Lib */ - struct phy_fixup { - struct list_head list; diff --git a/target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch b/target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch deleted file mode 100644 index 5970355a6c21d1..00000000000000 --- a/target/linux/generic/backport-6.1/715-18-v6.5-net-phylink-require-supported_interfaces-to-be-fille.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 441e1e44301fc5762a06737f8ec04bf1ce3fb039 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Sat, 20 May 2023 11:41:42 +0100 -Subject: [PATCH 16/21] net: phylink: require supported_interfaces to be filled - -We have been requiring the supported_interfaces bitmap to be filled in -by MAC drivers that have a mac_select_pcs() method. Now that all MAC -drivers fill in the supported_interfaces bitmap, it is time to enforce -this. We have already required supported_interfaces to be set in order -for optical SFPs to be configured in commit f81fa96d8a6c ("net: phylink: -use phy_interface_t bitmaps for optical modules"). - -Refuse phylink creation if supported_interfaces is empty, and remove -code to deal with cases where this mask is empty. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/E1q0K1u-006EIP-ET@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 26 +++++++++++--------------- - 1 file changed, 11 insertions(+), 15 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -710,14 +710,11 @@ static int phylink_validate(struct phyli - { - const unsigned long *interfaces = pl->config->supported_interfaces; - -- if (!phy_interface_empty(interfaces)) { -- if (state->interface == PHY_INTERFACE_MODE_NA) -- return phylink_validate_mask(pl, supported, state, -- interfaces); -+ if (state->interface == PHY_INTERFACE_MODE_NA) -+ return phylink_validate_mask(pl, supported, state, interfaces); - -- if (!test_bit(state->interface, interfaces)) -- return -EINVAL; -- } -+ if (!test_bit(state->interface, interfaces)) -+ return -EINVAL; - - return phylink_validate_mac_and_pcs(pl, supported, state); - } -@@ -1512,19 +1509,18 @@ struct phylink *phylink_create(struct ph - struct phylink *pl; - int ret; - -- if (mac_ops->mac_select_pcs && -- mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) != -- ERR_PTR(-EOPNOTSUPP)) -- using_mac_select_pcs = true; -- - /* Validate the supplied configuration */ -- if (using_mac_select_pcs && -- phy_interface_empty(config->supported_interfaces)) { -+ if (phy_interface_empty(config->supported_interfaces)) { - dev_err(config->dev, -- "phylink: error: empty supported_interfaces but mac_select_pcs() method present\n"); -+ "phylink: error: empty supported_interfaces\n"); - return ERR_PTR(-EINVAL); - } - -+ if (mac_ops->mac_select_pcs && -+ mac_ops->mac_select_pcs(config, PHY_INTERFACE_MODE_NA) != -+ ERR_PTR(-EOPNOTSUPP)) -+ using_mac_select_pcs = true; -+ - pl = kzalloc(sizeof(*pl), GFP_KERNEL); - if (!pl) - return ERR_PTR(-ENOMEM); diff --git a/target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch b/target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch deleted file mode 100644 index 3a26b4b6006ffb..00000000000000 --- a/target/linux/generic/backport-6.1/715-19-v6.5-net-phylink-remove-duplicated-linkmode-pause-resolut.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 4b624a39f2ab523ca6a6ad9448fab1deb7b101e2 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 23 May 2023 11:15:53 +0100 -Subject: [PATCH 17/21] net: phylink: remove duplicated linkmode pause - resolution - -Phylink had two chunks of code virtually the same for resolving the -negotiated pause modes. Factor this down to one function. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 15 ++++----------- - 1 file changed, 4 insertions(+), 11 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -976,11 +976,10 @@ static void phylink_apply_manual_flow(st - state->pause = pl->link_config.pause; - } - --static void phylink_resolve_flow(struct phylink_link_state *state) -+static void phylink_resolve_an_pause(struct phylink_link_state *state) - { - bool tx_pause, rx_pause; - -- state->pause = MLO_PAUSE_NONE; - if (state->duplex == DUPLEX_FULL) { - linkmode_resolve_pause(state->advertising, - state->lp_advertising, -@@ -1192,7 +1191,8 @@ static void phylink_get_fixed_state(stru - else if (pl->link_gpio) - state->link = !!gpiod_get_value_cansleep(pl->link_gpio); - -- phylink_resolve_flow(state); -+ state->pause = MLO_PAUSE_NONE; -+ phylink_resolve_an_pause(state); - } - - static void phylink_mac_initial_config(struct phylink *pl, bool force_restart) -@@ -3215,7 +3215,6 @@ static const struct sfp_upstream_ops sfp - static void phylink_decode_c37_word(struct phylink_link_state *state, - uint16_t config_reg, int speed) - { -- bool tx_pause, rx_pause; - int fd_bit; - - if (speed == SPEED_2500) -@@ -3234,13 +3233,7 @@ static void phylink_decode_c37_word(stru - state->link = false; - } - -- linkmode_resolve_pause(state->advertising, state->lp_advertising, -- &tx_pause, &rx_pause); -- -- if (tx_pause) -- state->pause |= MLO_PAUSE_TX; -- if (rx_pause) -- state->pause |= MLO_PAUSE_RX; -+ phylink_resolve_an_pause(state); - } - - static void phylink_decode_sgmii_word(struct phylink_link_state *state, diff --git a/target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch b/target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch deleted file mode 100644 index 2b2634f80c006c..00000000000000 --- a/target/linux/generic/backport-6.1/715-20-v6.5-net-phylink-add-function-to-resolve-clause-73-negoti.patch +++ /dev/null @@ -1,76 +0,0 @@ -From aa8b6bd2b1f235b262bd27f317a0516f196c2c6a Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 23 May 2023 11:15:58 +0100 -Subject: [PATCH 18/21] net: phylink: add function to resolve clause 73 - negotiation - -Add a function to resolve clause 73 negotiation according to the -priority resolution function described in clause 73.3.6. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Andrew Lunn -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 39 +++++++++++++++++++++++++++++++++++++++ - include/linux/phylink.h | 2 ++ - 2 files changed, 41 insertions(+) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -3212,6 +3212,45 @@ static const struct sfp_upstream_ops sfp - - /* Helpers for MAC drivers */ - -+static struct { -+ int bit; -+ int speed; -+} phylink_c73_priority_resolution[] = { -+ { ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, SPEED_100000 }, -+ { ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, SPEED_100000 }, -+ /* 100GBASE-KP4 and 100GBASE-CR10 not supported */ -+ { ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, SPEED_40000 }, -+ { ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, SPEED_40000 }, -+ { ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, SPEED_10000 }, -+ { ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, SPEED_10000 }, -+ /* 5GBASE-KR not supported */ -+ { ETHTOOL_LINK_MODE_2500baseX_Full_BIT, SPEED_2500 }, -+ { ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, SPEED_1000 }, -+}; -+ -+void phylink_resolve_c73(struct phylink_link_state *state) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(phylink_c73_priority_resolution); i++) { -+ int bit = phylink_c73_priority_resolution[i].bit; -+ if (linkmode_test_bit(bit, state->advertising) && -+ linkmode_test_bit(bit, state->lp_advertising)) -+ break; -+ } -+ -+ if (i < ARRAY_SIZE(phylink_c73_priority_resolution)) { -+ state->speed = phylink_c73_priority_resolution[i].speed; -+ state->duplex = DUPLEX_FULL; -+ } else { -+ /* negotiation failure */ -+ state->link = false; -+ } -+ -+ phylink_resolve_an_pause(state); -+} -+EXPORT_SYMBOL_GPL(phylink_resolve_c73); -+ - static void phylink_decode_c37_word(struct phylink_link_state *state, - uint16_t config_reg, int speed) - { ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -656,6 +656,8 @@ int phylink_mii_c22_pcs_config(struct md - const unsigned long *advertising); - void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs); - -+void phylink_resolve_c73(struct phylink_link_state *state); -+ - void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs, - struct phylink_link_state *state); - diff --git a/target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch b/target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch deleted file mode 100644 index eea99a5d782e83..00000000000000 --- a/target/linux/generic/backport-6.1/715-21-v6.5-net-phylink-provide-phylink_pcs_config-and-phylink_p.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 796d709363135a6bd6a8ccc07b509c939e5b855f Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 23 May 2023 16:31:50 +0100 -Subject: [PATCH 19/21] net: phylink: provide phylink_pcs_config() and - phylink_pcs_link_up() - -Add two helper functions for calling PCS methods. phylink_pcs_config() -allows us to handle PCS configuration specifics in one location, rather -than the two call sites. phylink_pcs_link_up() gives us consistency. - -Signed-off-by: Russell King (Oracle) -Link: https://lore.kernel.org/r/E1q1TzK-007Exd-Rs@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 53 ++++++++++++++++++++++++--------------- - 1 file changed, 33 insertions(+), 20 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -991,6 +991,25 @@ static void phylink_resolve_an_pause(str - } - } - -+static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+ const struct phylink_link_state *state, -+ bool permit_pause_to_mac) -+{ -+ if (!pcs) -+ return 0; -+ -+ return pcs->ops->pcs_config(pcs, mode, state->interface, -+ state->advertising, permit_pause_to_mac); -+} -+ -+static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -+ phy_interface_t interface, int speed, -+ int duplex) -+{ -+ if (pcs && pcs->ops->pcs_link_up) -+ pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex); -+} -+ - static void phylink_pcs_poll_stop(struct phylink *pl) - { - if (pl->cfg_link_an_mode == MLO_AN_INBAND) -@@ -1074,18 +1093,15 @@ static void phylink_major_config(struct - - phylink_mac_config(pl, state); - -- if (pl->pcs) { -- err = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode, -- state->interface, -- state->advertising, -- !!(pl->link_config.pause & -- MLO_PAUSE_AN)); -- if (err < 0) -- phylink_err(pl, "pcs_config failed: %pe\n", -- ERR_PTR(err)); -- if (err > 0) -- restart = true; -- } -+ err = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode, state, -+ !!(pl->link_config.pause & -+ MLO_PAUSE_AN)); -+ if (err < 0) -+ phylink_err(pl, "pcs_config failed: %pe\n", -+ ERR_PTR(err)); -+ else if (err > 0) -+ restart = true; -+ - if (restart) - phylink_mac_pcs_an_restart(pl); - -@@ -1136,11 +1152,9 @@ static int phylink_change_inband_advert( - * restart negotiation if the pcs_config() helper indicates that - * the programmed advertisement has changed. - */ -- ret = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode, -- pl->link_config.interface, -- pl->link_config.advertising, -- !!(pl->link_config.pause & -- MLO_PAUSE_AN)); -+ ret = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode, -+ &pl->link_config, -+ !!(pl->link_config.pause & MLO_PAUSE_AN)); - if (ret < 0) - return ret; - -@@ -1272,9 +1286,8 @@ static void phylink_link_up(struct phyli - - pl->cur_interface = link_state.interface; - -- if (pl->pcs && pl->pcs->ops->pcs_link_up) -- pl->pcs->ops->pcs_link_up(pl->pcs, pl->cur_link_an_mode, -- pl->cur_interface, speed, duplex); -+ phylink_pcs_link_up(pl->pcs, pl->cur_link_an_mode, pl->cur_interface, -+ speed, duplex); - - pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode, - pl->cur_interface, speed, duplex, diff --git a/target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch b/target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch deleted file mode 100644 index 2f7f7a5737fcab..00000000000000 --- a/target/linux/generic/backport-6.1/715-23-v6.4-net-phylink-actually-fix-ksettings_set-ethtool-call.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 11933aa76865621d8e82553c8f3bc07796a5aaa2 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 1 Jun 2023 10:12:06 +0100 -Subject: [PATCH 20/21] net: phylink: actually fix ksettings_set() ethtool call - -Raju Lakkaraju reported that the below commit caused a regression -with Lan743x drivers and a 2.5G SFP. Sadly, this is because the commit -was utterly wrong. Let's fix this properly by not moving the -linkmode_and(), but instead copying the link ksettings and then -modifying the advertising mask before passing the modified link -ksettings to phylib. - -Fixes: df0acdc59b09 ("net: phylink: fix ksettings_set() ethtool call") -Signed-off-by: Russell King (Oracle) -Link: https://lore.kernel.org/r/E1q4eLm-00Ayxk-GZ@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -2259,11 +2259,13 @@ int phylink_ethtool_ksettings_set(struct - - ASSERT_RTNL(); - -- /* Mask out unsupported advertisements */ -- linkmode_and(config.advertising, kset->link_modes.advertising, -- pl->supported); -- - if (pl->phydev) { -+ struct ethtool_link_ksettings phy_kset = *kset; -+ -+ linkmode_and(phy_kset.link_modes.advertising, -+ phy_kset.link_modes.advertising, -+ pl->supported); -+ - /* We can rely on phylib for this update; we also do not need - * to update the pl->link_config settings: - * - the configuration returned via ksettings_get() will come -@@ -2282,10 +2284,13 @@ int phylink_ethtool_ksettings_set(struct - * the presence of a PHY, this should not be changed as that - * should be determined from the media side advertisement. - */ -- return phy_ethtool_ksettings_set(pl->phydev, kset); -+ return phy_ethtool_ksettings_set(pl->phydev, &phy_kset); - } - - config = pl->link_config; -+ /* Mask out unsupported advertisements */ -+ linkmode_and(config.advertising, kset->link_modes.advertising, -+ pl->supported); - - /* FIXME: should we reject autoneg if phy/mac does not support it? */ - switch (kset->base.autoneg) { diff --git a/target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch b/target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch deleted file mode 100644 index e1a8539aae425e..00000000000000 --- a/target/linux/generic/backport-6.1/715-24-v6.5-net-phylink-add-PCS-negotiation-mode.patch +++ /dev/null @@ -1,324 +0,0 @@ -From 79b07c3e9c4a2272927be8848c26b372516e1958 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 16 Jun 2023 13:06:22 +0100 -Subject: [PATCH 21/21] net: phylink: add PCS negotiation mode - -PCS have to work out whether they should enable PCS negotiation by -looking at the "mode" and "interface" arguments, and the Autoneg bit -in the advertising mask. - -This leads to some complex logic, so lets pull that out into phylink -and instead pass a "neg_mode" argument to the PCS configuration and -link up methods, instead of the "mode" argument. - -In order to transition drivers, add a "neg_mode" flag to the phylink -PCS structure to PCS can indicate whether they want to be passed the -neg_mode or the old mode argument. - -Signed-off-by: Russell King (Oracle) -Link: https://lore.kernel.org/r/E1qA8De-00EaFA-Ht@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 45 +++++++++++++---- - include/linux/phylink.h | 104 +++++++++++++++++++++++++++++++++++--- - 2 files changed, 132 insertions(+), 17 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -71,6 +71,7 @@ struct phylink { - struct mutex state_mutex; - struct phylink_link_state phy_state; - struct work_struct resolve; -+ unsigned int pcs_neg_mode; - - bool mac_link_dropped; - bool using_mac_select_pcs; -@@ -991,23 +992,23 @@ static void phylink_resolve_an_pause(str - } - } - --static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, - const struct phylink_link_state *state, - bool permit_pause_to_mac) - { - if (!pcs) - return 0; - -- return pcs->ops->pcs_config(pcs, mode, state->interface, -+ return pcs->ops->pcs_config(pcs, neg_mode, state->interface, - state->advertising, permit_pause_to_mac); - } - --static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -+static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, int speed, - int duplex) - { - if (pcs && pcs->ops->pcs_link_up) -- pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex); -+ pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex); - } - - static void phylink_pcs_poll_stop(struct phylink *pl) -@@ -1057,10 +1058,15 @@ static void phylink_major_config(struct - struct phylink_pcs *pcs = NULL; - bool pcs_changed = false; - unsigned int rate_kbd; -+ unsigned int neg_mode; - int err; - - phylink_dbg(pl, "major config %s\n", phy_modes(state->interface)); - -+ pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode, -+ state->interface, -+ state->advertising); -+ - if (pl->using_mac_select_pcs) { - pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); - if (IS_ERR(pcs)) { -@@ -1093,9 +1099,12 @@ static void phylink_major_config(struct - - phylink_mac_config(pl, state); - -- err = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode, state, -- !!(pl->link_config.pause & -- MLO_PAUSE_AN)); -+ neg_mode = pl->cur_link_an_mode; -+ if (pl->pcs && pl->pcs->neg_mode) -+ neg_mode = pl->pcs_neg_mode; -+ -+ err = phylink_pcs_config(pl->pcs, neg_mode, state, -+ !!(pl->link_config.pause & MLO_PAUSE_AN)); - if (err < 0) - phylink_err(pl, "pcs_config failed: %pe\n", - ERR_PTR(err)); -@@ -1130,6 +1139,7 @@ static void phylink_major_config(struct - */ - static int phylink_change_inband_advert(struct phylink *pl) - { -+ unsigned int neg_mode; - int ret; - - if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) -@@ -1148,12 +1158,20 @@ static int phylink_change_inband_advert( - __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising, - pl->link_config.pause); - -+ /* Recompute the PCS neg mode */ -+ pl->pcs_neg_mode = phylink_pcs_neg_mode(pl->cur_link_an_mode, -+ pl->link_config.interface, -+ pl->link_config.advertising); -+ -+ neg_mode = pl->cur_link_an_mode; -+ if (pl->pcs->neg_mode) -+ neg_mode = pl->pcs_neg_mode; -+ - /* Modern PCS-based method; update the advert at the PCS, and - * restart negotiation if the pcs_config() helper indicates that - * the programmed advertisement has changed. - */ -- ret = phylink_pcs_config(pl->pcs, pl->cur_link_an_mode, -- &pl->link_config, -+ ret = phylink_pcs_config(pl->pcs, neg_mode, &pl->link_config, - !!(pl->link_config.pause & MLO_PAUSE_AN)); - if (ret < 0) - return ret; -@@ -1256,6 +1274,7 @@ static void phylink_link_up(struct phyli - struct phylink_link_state link_state) - { - struct net_device *ndev = pl->netdev; -+ unsigned int neg_mode; - int speed, duplex; - bool rx_pause; - -@@ -1286,8 +1305,12 @@ static void phylink_link_up(struct phyli - - pl->cur_interface = link_state.interface; - -- phylink_pcs_link_up(pl->pcs, pl->cur_link_an_mode, pl->cur_interface, -- speed, duplex); -+ neg_mode = pl->cur_link_an_mode; -+ if (pl->pcs && pl->pcs->neg_mode) -+ neg_mode = pl->pcs_neg_mode; -+ -+ phylink_pcs_link_up(pl->pcs, neg_mode, pl->cur_interface, speed, -+ duplex); - - pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode, - pl->cur_interface, speed, duplex, ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -21,6 +21,24 @@ enum { - MLO_AN_FIXED, /* Fixed-link mode */ - MLO_AN_INBAND, /* In-band protocol */ - -+ /* PCS "negotiation" mode. -+ * PHYLINK_PCS_NEG_NONE - protocol has no inband capability -+ * PHYLINK_PCS_NEG_OUTBAND - some out of band or fixed link setting -+ * PHYLINK_PCS_NEG_INBAND_DISABLED - inband mode disabled, e.g. -+ * 1000base-X with autoneg off -+ * PHYLINK_PCS_NEG_INBAND_ENABLED - inband mode enabled -+ * Additionally, this can be tested using bitmasks: -+ * PHYLINK_PCS_NEG_INBAND - inband mode selected -+ * PHYLINK_PCS_NEG_ENABLED - negotiation mode enabled -+ */ -+ PHYLINK_PCS_NEG_NONE = 0, -+ PHYLINK_PCS_NEG_ENABLED = BIT(4), -+ PHYLINK_PCS_NEG_OUTBAND = BIT(5), -+ PHYLINK_PCS_NEG_INBAND = BIT(6), -+ PHYLINK_PCS_NEG_INBAND_DISABLED = PHYLINK_PCS_NEG_INBAND, -+ PHYLINK_PCS_NEG_INBAND_ENABLED = PHYLINK_PCS_NEG_INBAND | -+ PHYLINK_PCS_NEG_ENABLED, -+ - /* MAC_SYM_PAUSE and MAC_ASYM_PAUSE are used when configuring our - * autonegotiation advertisement. They correspond to the PAUSE and - * ASM_DIR bits defined by 802.3, respectively. -@@ -80,6 +98,70 @@ static inline bool phylink_autoneg_inban - } - - /** -+ * phylink_pcs_neg_mode() - helper to determine PCS inband mode -+ * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND. -+ * @interface: interface mode to be used -+ * @advertising: adertisement ethtool link mode mask -+ * -+ * Determines the negotiation mode to be used by the PCS, and returns -+ * one of: -+ * %PHYLINK_PCS_NEG_NONE: interface mode does not support inband -+ * %PHYLINK_PCS_NEG_OUTBAND: an out of band mode (e.g. reading the PHY) -+ * will be used. -+ * %PHYLINK_PCS_NEG_INBAND_DISABLED: inband mode selected but autoneg disabled -+ * %PHYLINK_PCS_NEG_INBAND_ENABLED: inband mode selected and autoneg enabled -+ * -+ * Note: this is for cases where the PCS itself is involved in negotiation -+ * (e.g. Clause 37, SGMII and similar) not Clause 73. -+ */ -+static inline unsigned int phylink_pcs_neg_mode(unsigned int mode, -+ phy_interface_t interface, -+ const unsigned long *advertising) -+{ -+ unsigned int neg_mode; -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ case PHY_INTERFACE_MODE_QUSGMII: -+ case PHY_INTERFACE_MODE_USXGMII: -+ /* These protocols are designed for use with a PHY which -+ * communicates its negotiation result back to the MAC via -+ * inband communication. Note: there exist PHYs that run -+ * with SGMII but do not send the inband data. -+ */ -+ if (!phylink_autoneg_inband(mode)) -+ neg_mode = PHYLINK_PCS_NEG_OUTBAND; -+ else -+ neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; -+ break; -+ -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ /* 1000base-X is designed for use media-side for Fibre -+ * connections, and thus the Autoneg bit needs to be -+ * taken into account. We also do this for 2500base-X -+ * as well, but drivers may not support this, so may -+ * need to override this. -+ */ -+ if (!phylink_autoneg_inband(mode)) -+ neg_mode = PHYLINK_PCS_NEG_OUTBAND; -+ else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ advertising)) -+ neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; -+ else -+ neg_mode = PHYLINK_PCS_NEG_INBAND_DISABLED; -+ break; -+ -+ default: -+ neg_mode = PHYLINK_PCS_NEG_NONE; -+ break; -+ } -+ -+ return neg_mode; -+} -+ -+/** - * struct phylink_link_state - link state structure - * @advertising: ethtool bitmask containing advertised link modes - * @lp_advertising: ethtool bitmask containing link partner advertised link -@@ -436,6 +518,7 @@ struct phylink_pcs_ops; - /** - * struct phylink_pcs - PHYLINK PCS instance - * @ops: a pointer to the &struct phylink_pcs_ops structure -+ * @neg_mode: provide PCS neg mode via "mode" argument - * @poll: poll the PCS for link changes - * - * This structure is designed to be embedded within the PCS private data, -@@ -443,6 +526,7 @@ struct phylink_pcs_ops; - */ - struct phylink_pcs { - const struct phylink_pcs_ops *ops; -+ bool neg_mode; - bool poll; - }; - -@@ -460,12 +544,12 @@ struct phylink_pcs_ops { - const struct phylink_link_state *state); - void (*pcs_get_state)(struct phylink_pcs *pcs, - struct phylink_link_state *state); -- int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode, -+ int (*pcs_config)(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, - const unsigned long *advertising, - bool permit_pause_to_mac); - void (*pcs_an_restart)(struct phylink_pcs *pcs); -- void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int mode, -+ void (*pcs_link_up)(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, int speed, int duplex); - }; - -@@ -508,7 +592,7 @@ void pcs_get_state(struct phylink_pcs *p - /** - * pcs_config() - Configure the PCS mode and advertisement - * @pcs: a pointer to a &struct phylink_pcs. -- * @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND. -+ * @neg_mode: link negotiation mode (see below) - * @interface: interface mode to be used - * @advertising: adertisement ethtool link mode mask - * @permit_pause_to_mac: permit forwarding pause resolution to MAC -@@ -526,8 +610,12 @@ void pcs_get_state(struct phylink_pcs *p - * For 1000BASE-X, the advertisement should be programmed into the PCS. - * - * For most 10GBASE-R, there is no advertisement. -+ * -+ * The %neg_mode argument should be tested via the phylink_mode_*() family of -+ * functions, or for PCS that set pcs->neg_mode true, should be tested -+ * against the %PHYLINK_PCS_NEG_* definitions. - */ --int pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+int pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, const unsigned long *advertising, - bool permit_pause_to_mac); - -@@ -543,7 +631,7 @@ void pcs_an_restart(struct phylink_pcs * - /** - * pcs_link_up() - program the PCS for the resolved link configuration - * @pcs: a pointer to a &struct phylink_pcs. -- * @mode: link autonegotiation mode -+ * @neg_mode: link negotiation mode (see below) - * @interface: link &typedef phy_interface_t mode - * @speed: link speed - * @duplex: link duplex -@@ -552,8 +640,12 @@ void pcs_an_restart(struct phylink_pcs * - * the resolved link parameters. For example, a PCS operating in SGMII - * mode without in-band AN needs to be manually configured for the link - * and duplex setting. Otherwise, this should be a no-op. -+ * -+ * The %mode argument should be tested via the phylink_mode_*() family of -+ * functions, or for PCS that set pcs->neg_mode true, should be tested -+ * against the %PHYLINK_PCS_NEG_* definitions. - */ --void pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -+void pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, int speed, int duplex); - #endif - diff --git a/target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch b/target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch deleted file mode 100644 index 473e9d5836d1c2..00000000000000 --- a/target/linux/generic/backport-6.1/715-25-v6.5-net-phylink-convert-phylink_mii_c22_pcs_config-to-ne.patch +++ /dev/null @@ -1,45 +0,0 @@ -From cdb08aa0473730315dbc088d5394e59622314034 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 16 Jun 2023 13:06:27 +0100 -Subject: [PATCH 1/2] net: phylink: convert phylink_mii_c22_pcs_config() to - neg_mode - -Use phylink_pcs_neg_mode() for phylink_mii_c22_pcs_config(). This -results in no functional change. - -Signed-off-by: Russell King (Oracle) -Link: https://lore.kernel.org/r/E1qA8Dj-00EaFG-Mt@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -3558,6 +3558,7 @@ int phylink_mii_c22_pcs_config(struct md - phy_interface_t interface, - const unsigned long *advertising) - { -+ unsigned int neg_mode; - bool changed = 0; - u16 bmcr; - int ret, adv; -@@ -3571,15 +3572,13 @@ int phylink_mii_c22_pcs_config(struct md - changed = ret; - } - -- /* Ensure ISOLATE bit is disabled */ -- if (mode == MLO_AN_INBAND && -- (interface == PHY_INTERFACE_MODE_SGMII || -- interface == PHY_INTERFACE_MODE_QSGMII || -- linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, advertising))) -+ neg_mode = phylink_pcs_neg_mode(mode, interface, advertising); -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) - bmcr = BMCR_ANENABLE; - else - bmcr = 0; - -+ /* Configure the inband state. Ensure ISOLATE bit is disabled */ - ret = mdiodev_modify(pcs, MII_BMCR, BMCR_ANENABLE | BMCR_ISOLATE, bmcr); - if (ret < 0) - return ret; diff --git a/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch b/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch deleted file mode 100644 index 07e879098a7370..00000000000000 --- a/target/linux/generic/backport-6.1/715-26-v6.5-net-phylink-pass-neg_mode-into-phylink_mii_c22_pcs_c.patch +++ /dev/null @@ -1,187 +0,0 @@ -From febf2aaf05641f3258cc30e072aff65cffc7c82c Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 16 Jun 2023 13:06:32 +0100 -Subject: [PATCH 2/2] net: phylink: pass neg_mode into - phylink_mii_c22_pcs_config() - -Convert fman_dtsec, xilinx_axienet and pcs-lynx to pass the neg_mode -into phylink_mii_c22_pcs_config(). Where appropriate, drivers are -updated to have neg_mode passed into their pcs_config() and -pcs_link_up() functions. For other drivers, we just hoist the call -to phylink_pcs_neg_mode() to their pcs_config() method out of -phylink_mii_c22_pcs_config(). - -Signed-off-by: Russell King (Oracle) -Link: https://lore.kernel.org/r/E1qA8Do-00EaFM-Ra@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - .../net/ethernet/freescale/fman/fman_dtsec.c | 7 ++++--- - .../net/ethernet/xilinx/xilinx_axienet_main.c | 6 ++++-- - drivers/net/pcs/pcs-lynx.c | 18 ++++++++++++------ - drivers/net/phy/phylink.c | 9 ++++----- - include/linux/phylink.h | 5 +++-- - 5 files changed, 27 insertions(+), 18 deletions(-) - ---- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c -+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c -@@ -763,15 +763,15 @@ static void dtsec_pcs_get_state(struct p - phylink_mii_c22_pcs_get_state(dtsec->tbidev, state); - } - --static int dtsec_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+static int dtsec_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, - const unsigned long *advertising, - bool permit_pause_to_mac) - { - struct fman_mac *dtsec = pcs_to_dtsec(pcs); - -- return phylink_mii_c22_pcs_config(dtsec->tbidev, mode, interface, -- advertising); -+ return phylink_mii_c22_pcs_config(dtsec->tbidev, interface, -+ advertising, neg_mode); - } - - static void dtsec_pcs_an_restart(struct phylink_pcs *pcs) -@@ -1447,6 +1447,7 @@ int dtsec_initialization(struct mac_devi - goto _return_fm_mac_free; - } - dtsec->pcs.ops = &dtsec_pcs_ops; -+ dtsec->pcs.neg_mode = true; - dtsec->pcs.poll = true; - - supported = mac_dev->phylink_config.supported_interfaces; ---- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -@@ -1632,7 +1632,7 @@ static void axienet_pcs_an_restart(struc - phylink_mii_c22_pcs_an_restart(pcs_phy); - } - --static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, - const unsigned long *advertising, - bool permit_pause_to_mac) -@@ -1654,7 +1654,8 @@ static int axienet_pcs_config(struct phy - } - } - -- ret = phylink_mii_c22_pcs_config(pcs_phy, mode, interface, advertising); -+ ret = phylink_mii_c22_pcs_config(pcs_phy, interface, advertising, -+ neg_mode); - if (ret < 0) - netdev_warn(ndev, "Failed to configure PCS: %d\n", ret); - -@@ -2130,6 +2131,7 @@ static int axienet_probe(struct platform - } - of_node_put(np); - lp->pcs.ops = &axienet_pcs_ops; -+ lp->pcs.neg_mode = true; - lp->pcs.poll = true; - } - ---- a/drivers/net/pcs/pcs-lynx.c -+++ b/drivers/net/pcs/pcs-lynx.c -@@ -122,9 +122,10 @@ static void lynx_pcs_get_state(struct ph - state->link, state->an_complete); - } - --static int lynx_pcs_config_giga(struct mdio_device *pcs, unsigned int mode, -+static int lynx_pcs_config_giga(struct mdio_device *pcs, - phy_interface_t interface, -- const unsigned long *advertising) -+ const unsigned long *advertising, -+ unsigned int neg_mode) - { - u32 link_timer; - u16 if_mode; -@@ -137,8 +138,9 @@ static int lynx_pcs_config_giga(struct m - - if_mode = 0; - } else { -+ /* SGMII and QSGMII */ - if_mode = IF_MODE_SGMII_EN; -- if (mode == MLO_AN_INBAND) { -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { - if_mode |= IF_MODE_USE_SGMII_AN; - - /* Adjust link timer for SGMII */ -@@ -154,7 +156,8 @@ static int lynx_pcs_config_giga(struct m - if (err) - return err; - -- return phylink_mii_c22_pcs_config(pcs, mode, interface, advertising); -+ return phylink_mii_c22_pcs_config(pcs, interface, advertising, -+ neg_mode); - } - - static int lynx_pcs_config_usxgmii(struct mdio_device *pcs, unsigned int mode, -@@ -181,13 +184,16 @@ static int lynx_pcs_config(struct phylin - bool permit) - { - struct lynx_pcs *lynx = phylink_pcs_to_lynx(pcs); -+ unsigned int neg_mode; -+ -+ neg_mode = phylink_pcs_neg_mode(mode, ifmode, advertising); - - switch (ifmode) { - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_QSGMII: -- return lynx_pcs_config_giga(lynx->mdio, mode, ifmode, -- advertising); -+ return lynx_pcs_config_giga(lynx->mdio, ifmode, advertising, -+ neg_mode); - case PHY_INTERFACE_MODE_2500BASEX: - if (phylink_autoneg_inband(mode)) { - dev_err(&lynx->mdio->dev, ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -3545,20 +3545,20 @@ EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_en - /** - * phylink_mii_c22_pcs_config() - configure clause 22 PCS - * @pcs: a pointer to a &struct mdio_device. -- * @mode: link autonegotiation mode - * @interface: the PHY interface mode being configured - * @advertising: the ethtool advertisement mask -+ * @neg_mode: PCS negotiation mode - * - * Configure a Clause 22 PCS PHY with the appropriate negotiation - * parameters for the @mode, @interface and @advertising parameters. - * Returns negative error number on failure, zero if the advertisement - * has not changed, or positive if there is a change. - */ --int phylink_mii_c22_pcs_config(struct mdio_device *pcs, unsigned int mode, -+int phylink_mii_c22_pcs_config(struct mdio_device *pcs, - phy_interface_t interface, -- const unsigned long *advertising) -+ const unsigned long *advertising, -+ unsigned int neg_mode) - { -- unsigned int neg_mode; - bool changed = 0; - u16 bmcr; - int ret, adv; -@@ -3572,7 +3572,6 @@ int phylink_mii_c22_pcs_config(struct md - changed = ret; - } - -- neg_mode = phylink_pcs_neg_mode(mode, interface, advertising); - if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) - bmcr = BMCR_ANENABLE; - else ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -743,9 +743,10 @@ void phylink_mii_c22_pcs_get_state(struc - struct phylink_link_state *state); - int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface, - const unsigned long *advertising); --int phylink_mii_c22_pcs_config(struct mdio_device *pcs, unsigned int mode, -+int phylink_mii_c22_pcs_config(struct mdio_device *pcs, - phy_interface_t interface, -- const unsigned long *advertising); -+ const unsigned long *advertising, -+ unsigned int neg_mode); - void phylink_mii_c22_pcs_an_restart(struct mdio_device *pcs); - - void phylink_resolve_c73(struct phylink_link_state *state); diff --git a/target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch b/target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch deleted file mode 100644 index 5e0128766ca8de..00000000000000 --- a/target/linux/generic/backport-6.1/715-27-v6.5-net-pcs-lynxi-update-PCS-driver-to-use-neg_mode.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 3b2de56a146f34e3f70a84cc3a1897064e445d16 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 16 Jun 2023 13:06:43 +0100 -Subject: [PATCH] net: pcs: lynxi: update PCS driver to use neg_mode - -Update the Lynxi PCS driver to use neg_mode rather than the mode -argument. This ensures that the link_up() method will always program -the speed and duplex when negotiation is disabled. - -Signed-off-by: Russell King (Oracle) -Link: https://lore.kernel.org/r/E1qA8Dz-00EaFY-5A@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/pcs/pcs-mtk-lynxi.c | 39 ++++++++++++++------------------- - 1 file changed, 16 insertions(+), 23 deletions(-) - ---- a/drivers/net/pcs/pcs-mtk-lynxi.c -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -102,13 +102,13 @@ static void mtk_pcs_lynxi_get_state(stru - FIELD_GET(SGMII_LPA, adv)); - } - --static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode, -+static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, - const unsigned long *advertising, - bool permit_pause_to_mac) - { - struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -- bool mode_changed = false, changed, use_an; -+ bool mode_changed = false, changed; - unsigned int rgc3, sgm_mode, bmcr; - int advertise, link_timer; - -@@ -121,30 +121,22 @@ static int mtk_pcs_lynxi_config(struct p - * we assume that fixes it's speed at bitrate = line rate (in - * other words, 1000Mbps or 2500Mbps). - */ -- if (interface == PHY_INTERFACE_MODE_SGMII) { -+ if (interface == PHY_INTERFACE_MODE_SGMII) - sgm_mode = SGMII_IF_MODE_SGMII; -- if (phylink_autoneg_inband(mode)) { -- sgm_mode |= SGMII_REMOTE_FAULT_DIS | -- SGMII_SPEED_DUPLEX_AN; -- use_an = true; -- } else { -- use_an = false; -- } -- } else if (phylink_autoneg_inband(mode)) { -- /* 1000base-X or 2500base-X autoneg */ -- sgm_mode = SGMII_REMOTE_FAULT_DIS; -- use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -- advertising); -- } else { -+ else - /* 1000base-X or 2500base-X without autoneg */ - sgm_mode = 0; -- use_an = false; -- } - -- if (use_an) -+ if (neg_mode & PHYLINK_PCS_NEG_INBAND) -+ sgm_mode |= SGMII_REMOTE_FAULT_DIS; -+ -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { -+ if (interface == PHY_INTERFACE_MODE_SGMII) -+ sgm_mode |= SGMII_SPEED_DUPLEX_AN; - bmcr = BMCR_ANENABLE; -- else -+ } else { - bmcr = 0; -+ } - - if (mpcs->interface != interface) { - link_timer = phylink_get_link_timer_ns(interface); -@@ -216,14 +208,15 @@ static void mtk_pcs_lynxi_restart_an(str - regmap_set_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, BMCR_ANRESTART); - } - --static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, unsigned int mode, -+static void mtk_pcs_lynxi_link_up(struct phylink_pcs *pcs, -+ unsigned int neg_mode, - phy_interface_t interface, int speed, - int duplex) - { - struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); - unsigned int sgm_mode; - -- if (!phylink_autoneg_inband(mode)) { -+ if (neg_mode != PHYLINK_PCS_NEG_INBAND_ENABLED) { - /* Force the speed and duplex setting */ - if (speed == SPEED_10) - sgm_mode = SGMII_SPEED_10; -@@ -286,6 +279,7 @@ struct phylink_pcs *mtk_pcs_lynxi_create - mpcs->regmap = regmap; - mpcs->flags = flags; - mpcs->pcs.ops = &mtk_pcs_lynxi_ops; -+ mpcs->pcs.neg_mode = true; - mpcs->pcs.poll = true; - mpcs->interface = PHY_INTERFACE_MODE_NA; - diff --git a/target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch b/target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch deleted file mode 100644 index 3dd22d29160fed..00000000000000 --- a/target/linux/generic/backport-6.1/715-28-v6.4-net-pcs-xpcs-use-Autoneg-bit-rather-than-an_enabled.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 459fd2f11204c962e3153020f4f56748e0e10afb Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 21 Mar 2023 15:58:49 +0000 -Subject: [PATCH] net: pcs: xpcs: use Autoneg bit rather than an_enabled - -The Autoneg bit in the advertising bitmap and state->an_enabled are -always identical. Thus, we will be removing state->an_enabled. - -Use the Autoneg bit in the advertising bitmap to indicate whether -autonegotiation should be used, rather than using the an_enabled -member which will be going away. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Simon Horman -Signed-off-by: Jakub Kicinski ---- - drivers/net/pcs/pcs-xpcs.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - ---- a/drivers/net/pcs/pcs-xpcs.c -+++ b/drivers/net/pcs/pcs-xpcs.c -@@ -931,6 +931,7 @@ static int xpcs_get_state_c73(struct dw_ - struct phylink_link_state *state, - const struct xpcs_compat *compat) - { -+ bool an_enabled; - int ret; - - /* Link needs to be read first ... */ -@@ -948,11 +949,13 @@ static int xpcs_get_state_c73(struct dw_ - return xpcs_do_config(xpcs, state->interface, MLO_AN_INBAND, NULL); - } - -- if (state->an_enabled && xpcs_aneg_done_c73(xpcs, state, compat)) { -+ an_enabled = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ state->advertising); -+ if (an_enabled && xpcs_aneg_done_c73(xpcs, state, compat)) { - state->an_complete = true; - xpcs_read_lpa_c73(xpcs, state); - xpcs_resolve_lpa_c73(xpcs, state); -- } else if (state->an_enabled) { -+ } else if (an_enabled) { - state->link = 0; - } else if (state->link) { - xpcs_resolve_pma(xpcs, state); -@@ -1007,7 +1010,8 @@ static int xpcs_get_state_c37_1000basex( - { - int lpa, bmsr; - -- if (state->an_enabled) { -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ state->advertising)) { - /* Reset link state */ - state->link = false; - diff --git a/target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch b/target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch deleted file mode 100644 index 7cae8515fa1e8d..00000000000000 --- a/target/linux/generic/backport-6.1/715-29-v6.4-net-pcs-xpcs-fix-incorrect-number-of-interfaces.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 43fb622d91a9f408322735d2f736495c1009f575 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Tue, 9 May 2023 12:50:04 +0100 -Subject: [PATCH] net: pcs: xpcs: fix incorrect number of interfaces - -In synopsys_xpcs_compat[], the DW_XPCS_2500BASEX entry was setting -the number of interfaces using the xpcs_2500basex_features array -rather than xpcs_2500basex_interfaces. This causes us to overflow -the array of interfaces. Fix this. - -Fixes: f27abde3042a ("net: pcs: add 2500BASEX support for Intel mGbE controller") -Signed-off-by: Russell King (Oracle) -Reviewed-by: Andrew Lunn -Reviewed-by: Leon Romanovsky -Signed-off-by: David S. Miller ---- - drivers/net/pcs/pcs-xpcs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/pcs/pcs-xpcs.c -+++ b/drivers/net/pcs/pcs-xpcs.c -@@ -1211,7 +1211,7 @@ static const struct xpcs_compat synopsys - [DW_XPCS_2500BASEX] = { - .supported = xpcs_2500basex_features, - .interface = xpcs_2500basex_interfaces, -- .num_interfaces = ARRAY_SIZE(xpcs_2500basex_features), -+ .num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces), - .an_mode = DW_2500BASEX, - }, - }; diff --git a/target/linux/generic/backport-6.1/715-v6.9-01-net-phy-qcom-qca808x-fix-logic-error-in-LED-brightne.patch b/target/linux/generic/backport-6.1/715-v6.9-01-net-phy-qcom-qca808x-fix-logic-error-in-LED-brightne.patch deleted file mode 100644 index 0a7b5358f13607..00000000000000 --- a/target/linux/generic/backport-6.1/715-v6.9-01-net-phy-qcom-qca808x-fix-logic-error-in-LED-brightne.patch +++ /dev/null @@ -1,36 +0,0 @@ -From f2ec98566775dd4341ec1dcf93aa5859c60de826 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 1 Feb 2024 14:46:00 +0100 -Subject: [PATCH 1/2] net: phy: qcom: qca808x: fix logic error in LED - brightness set - -In switching to using phy_modify_mmd and a more short version of the -LED ON/OFF condition in later revision, it was made a logic error where - -value ? QCA808X_LED_FORCE_ON : QCA808X_LED_FORCE_OFF is always true as -value is always OR with QCA808X_LED_FORCE_EN due to missing () -resulting in the testing condition being QCA808X_LED_FORCE_EN | value. - -Add the () to apply the correct condition and restore correct -functionality of the brightness ON/OFF. - -Fixes: 7196062b64ee ("net: phy: at803x: add LED support for qca808x") -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/qcom/qca808x.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/qcom/qca808x.c -+++ b/drivers/net/phy/qcom/qca808x.c -@@ -820,8 +820,8 @@ static int qca808x_led_brightness_set(st - - return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, - QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -- QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON : -- QCA808X_LED_FORCE_OFF); -+ QCA808X_LED_FORCE_EN | (value ? QCA808X_LED_FORCE_ON : -+ QCA808X_LED_FORCE_OFF)); - } - - static int qca808x_led_blink_set(struct phy_device *phydev, u8 index, diff --git a/target/linux/generic/backport-6.1/715-v6.9-02-net-phy-qcom-qca808x-default-to-LED-active-High-if-n.patch b/target/linux/generic/backport-6.1/715-v6.9-02-net-phy-qcom-qca808x-default-to-LED-active-High-if-n.patch deleted file mode 100644 index e32ed7f7772415..00000000000000 --- a/target/linux/generic/backport-6.1/715-v6.9-02-net-phy-qcom-qca808x-default-to-LED-active-High-if-n.patch +++ /dev/null @@ -1,41 +0,0 @@ -From f203c8c77c7616c099647636f4c67d59a45fe8a2 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 1 Feb 2024 14:46:01 +0100 -Subject: [PATCH 2/2] net: phy: qcom: qca808x: default to LED active High if - not set - -qca808x PHY provide support for the led_polarity_set OP to configure -and apply the active-low property but on PHY reset, the Active High bit -is not set resulting in the LED driven as active-low. - -To fix this, check if active-low is not set in DT and enable Active High -polarity by default to restore correct funcionality of the LED. - -Fixes: 7196062b64ee ("net: phy: at803x: add LED support for qca808x") -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/qcom/qca808x.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/net/phy/qcom/qca808x.c -+++ b/drivers/net/phy/qcom/qca808x.c -@@ -290,8 +290,18 @@ static int qca808x_probe(struct phy_devi - - static int qca808x_config_init(struct phy_device *phydev) - { -+ struct qca808x_priv *priv = phydev->priv; - int ret; - -+ /* Default to LED Active High if active-low not in DT */ -+ if (priv->led_polarity_mode == -1) { -+ ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, -+ QCA808X_MMD7_LED_POLARITY_CTRL, -+ QCA808X_LED_ACTIVE_HIGH); -+ if (ret) -+ return ret; -+ } -+ - /* Active adc&vga on 802.3az for the link 1000M and 100M */ - ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7, - QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN); diff --git a/target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch b/target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch deleted file mode 100644 index b355031aa5ebcc..00000000000000 --- a/target/linux/generic/backport-6.1/716-v6.9-02-net-phy-add-support-for-scanning-PHY-in-PHY-packages.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 385ef48f468696d6d172eb367656a3466fa0408d Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 6 Feb 2024 18:31:05 +0100 -Subject: [PATCH 02/10] net: phy: add support for scanning PHY in PHY packages - nodes - -Add support for scanning PHY in PHY package nodes. PHY packages nodes -are just container for actual PHY on the MDIO bus. - -Their PHY address defined in the PHY package node are absolute and -reflect the address on the MDIO bus. - -mdio_bus.c and of_mdio.c is updated to now support and parse also -PHY package subnode by checking if the node name match -"ethernet-phy-package". - -As PHY package reg is mandatory and each PHY in the PHY package must -have a reg, every invalid PHY Package node is ignored and will be -skipped by the autoscan fallback. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/mdio/of_mdio.c | 79 +++++++++++++++++++++++++++----------- - drivers/net/phy/mdio_bus.c | 44 +++++++++++++++++---- - 2 files changed, 92 insertions(+), 31 deletions(-) - ---- a/drivers/net/mdio/of_mdio.c -+++ b/drivers/net/mdio/of_mdio.c -@@ -138,6 +138,53 @@ bool of_mdiobus_child_is_phy(struct devi - } - EXPORT_SYMBOL(of_mdiobus_child_is_phy); - -+static int __of_mdiobus_parse_phys(struct mii_bus *mdio, struct device_node *np, -+ bool *scanphys) -+{ -+ struct device_node *child; -+ int addr, rc = 0; -+ -+ /* Loop over the child nodes and register a phy_device for each phy */ -+ for_each_available_child_of_node(np, child) { -+ if (of_node_name_eq(child, "ethernet-phy-package")) { -+ /* Ignore invalid ethernet-phy-package node */ -+ if (!of_find_property(child, "reg", NULL)) -+ continue; -+ -+ rc = __of_mdiobus_parse_phys(mdio, child, NULL); -+ if (rc && rc != -ENODEV) -+ goto exit; -+ -+ continue; -+ } -+ -+ addr = of_mdio_parse_addr(&mdio->dev, child); -+ if (addr < 0) { -+ /* Skip scanning for invalid ethernet-phy-package node */ -+ if (scanphys) -+ *scanphys = true; -+ continue; -+ } -+ -+ if (of_mdiobus_child_is_phy(child)) -+ rc = of_mdiobus_register_phy(mdio, child, addr); -+ else -+ rc = of_mdiobus_register_device(mdio, child, addr); -+ -+ if (rc == -ENODEV) -+ dev_err(&mdio->dev, -+ "MDIO device at address %d is missing.\n", -+ addr); -+ else if (rc) -+ goto exit; -+ } -+ -+ return 0; -+exit: -+ of_node_put(child); -+ return rc; -+} -+ - /** - * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree - * @mdio: pointer to mii_bus structure -@@ -179,33 +226,18 @@ int __of_mdiobus_register(struct mii_bus - return rc; - - /* Loop over the child nodes and register a phy_device for each phy */ -- for_each_available_child_of_node(np, child) { -- addr = of_mdio_parse_addr(&mdio->dev, child); -- if (addr < 0) { -- scanphys = true; -- continue; -- } -- -- if (of_mdiobus_child_is_phy(child)) -- rc = of_mdiobus_register_phy(mdio, child, addr); -- else -- rc = of_mdiobus_register_device(mdio, child, addr); -- -- if (rc == -ENODEV) -- dev_err(&mdio->dev, -- "MDIO device at address %d is missing.\n", -- addr); -- else if (rc) -- goto unregister; -- } -+ rc = __of_mdiobus_parse_phys(mdio, np, &scanphys); -+ if (rc) -+ goto unregister; - - if (!scanphys) - return 0; - - /* auto scan for PHYs with empty reg property */ - for_each_available_child_of_node(np, child) { -- /* Skip PHYs with reg property set */ -- if (of_find_property(child, "reg", NULL)) -+ /* Skip PHYs with reg property set or ethernet-phy-package node */ -+ if (of_find_property(child, "reg", NULL) || -+ of_node_name_eq(child, "ethernet-phy-package")) - continue; - - for (addr = 0; addr < PHY_MAX_ADDR; addr++) { -@@ -226,15 +258,16 @@ int __of_mdiobus_register(struct mii_bus - if (!rc) - break; - if (rc != -ENODEV) -- goto unregister; -+ goto put_unregister; - } - } - } - - return 0; - --unregister: -+put_unregister: - of_node_put(child); -+unregister: - mdiobus_unregister(mdio); - return rc; - } ---- a/drivers/net/phy/mdio_bus.c -+++ b/drivers/net/phy/mdio_bus.c -@@ -448,19 +448,34 @@ EXPORT_SYMBOL(of_mdio_find_bus); - * found, set the of_node pointer for the mdio device. This allows - * auto-probed phy devices to be supplied with information passed in - * via DT. -+ * If a PHY package is found, PHY is searched also there. - */ --static void of_mdiobus_link_mdiodev(struct mii_bus *bus, -- struct mdio_device *mdiodev) -+static int of_mdiobus_find_phy(struct device *dev, struct mdio_device *mdiodev, -+ struct device_node *np) - { -- struct device *dev = &mdiodev->dev; - struct device_node *child; - -- if (dev->of_node || !bus->dev.of_node) -- return; -- -- for_each_available_child_of_node(bus->dev.of_node, child) { -+ for_each_available_child_of_node(np, child) { - int addr; - -+ if (of_node_name_eq(child, "ethernet-phy-package")) { -+ /* Validate PHY package reg presence */ -+ if (!of_find_property(child, "reg", NULL)) { -+ of_node_put(child); -+ return -EINVAL; -+ } -+ -+ if (!of_mdiobus_find_phy(dev, mdiodev, child)) { -+ /* The refcount for the PHY package will be -+ * incremented later when PHY join the Package. -+ */ -+ of_node_put(child); -+ return 0; -+ } -+ -+ continue; -+ } -+ - addr = of_mdio_parse_addr(dev, child); - if (addr < 0) - continue; -@@ -470,9 +485,22 @@ static void of_mdiobus_link_mdiodev(stru - /* The refcount on "child" is passed to the mdio - * device. Do _not_ use of_node_put(child) here. - */ -- return; -+ return 0; - } - } -+ -+ return -ENODEV; -+} -+ -+static void of_mdiobus_link_mdiodev(struct mii_bus *bus, -+ struct mdio_device *mdiodev) -+{ -+ struct device *dev = &mdiodev->dev; -+ -+ if (dev->of_node || !bus->dev.of_node) -+ return; -+ -+ of_mdiobus_find_phy(dev, mdiodev, bus->dev.of_node); - } - #else /* !IS_ENABLED(CONFIG_OF_MDIO) */ - static inline void of_mdiobus_link_mdiodev(struct mii_bus *mdio, diff --git a/target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch b/target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch deleted file mode 100644 index 3c7bf6c132ff57..00000000000000 --- a/target/linux/generic/backport-6.1/716-v6.9-03-net-phy-add-devm-of_phy_package_join-helper.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 471e8fd3afcef5a9f9089f0bd21965ad9ba35c91 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 6 Feb 2024 18:31:06 +0100 -Subject: [PATCH 03/10] net: phy: add devm/of_phy_package_join helper - -Add devm/of_phy_package_join helper to join PHYs in a PHY package. These -are variant of the manual phy_package_join with the difference that -these will use DT nodes to derive the base_addr instead of manually -passing an hardcoded value. - -An additional value is added in phy_package_shared, "np" to reference -the PHY package node pointer in specific PHY driver probe_once and -config_init_once functions to make use of additional specific properties -defined in the PHY package node in DT. - -The np value is filled only with of_phy_package_join if a valid PHY -package node is found. A valid PHY package node must have the node name -set to "ethernet-phy-package". - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/phy_device.c | 96 ++++++++++++++++++++++++++++++++++++ - include/linux/phy.h | 6 +++ - 2 files changed, 102 insertions(+) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -1648,6 +1648,7 @@ int phy_package_join(struct phy_device * - shared->priv_size = priv_size; - } - shared->base_addr = base_addr; -+ shared->np = NULL; - refcount_set(&shared->refcnt, 1); - bus->shared[base_addr] = shared; - } else { -@@ -1671,6 +1672,63 @@ err_unlock: - EXPORT_SYMBOL_GPL(phy_package_join); - - /** -+ * of_phy_package_join - join a common PHY group in PHY package -+ * @phydev: target phy_device struct -+ * @priv_size: if non-zero allocate this amount of bytes for private data -+ * -+ * This is a variant of phy_package_join for PHY package defined in DT. -+ * -+ * The parent node of the @phydev is checked as a valid PHY package node -+ * structure (by matching the node name "ethernet-phy-package") and the -+ * base_addr for the PHY package is passed to phy_package_join. -+ * -+ * With this configuration the shared struct will also have the np value -+ * filled to use additional DT defined properties in PHY specific -+ * probe_once and config_init_once PHY package OPs. -+ * -+ * Returns < 0 on error, 0 on success. Esp. calling phy_package_join() -+ * with the same cookie but a different priv_size is an error. Or a parent -+ * node is not detected or is not valid or doesn't match the expected node -+ * name for PHY package. -+ */ -+int of_phy_package_join(struct phy_device *phydev, size_t priv_size) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ struct device_node *package_node; -+ u32 base_addr; -+ int ret; -+ -+ if (!node) -+ return -EINVAL; -+ -+ package_node = of_get_parent(node); -+ if (!package_node) -+ return -EINVAL; -+ -+ if (!of_node_name_eq(package_node, "ethernet-phy-package")) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ if (of_property_read_u32(package_node, "reg", &base_addr)) { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ ret = phy_package_join(phydev, base_addr, priv_size); -+ if (ret) -+ goto exit; -+ -+ phydev->shared->np = package_node; -+ -+ return 0; -+exit: -+ of_node_put(package_node); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(of_phy_package_join); -+ -+/** - * phy_package_leave - leave a common PHY group - * @phydev: target phy_device struct - * -@@ -1686,6 +1744,10 @@ void phy_package_leave(struct phy_device - if (!shared) - return; - -+ /* Decrease the node refcount on leave if present */ -+ if (shared->np) -+ of_node_put(shared->np); -+ - if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) { - bus->shared[shared->base_addr] = NULL; - mutex_unlock(&bus->shared_lock); -@@ -1739,6 +1801,40 @@ int devm_phy_package_join(struct device - EXPORT_SYMBOL_GPL(devm_phy_package_join); - - /** -+ * devm_of_phy_package_join - resource managed of_phy_package_join() -+ * @dev: device that is registering this PHY package -+ * @phydev: target phy_device struct -+ * @priv_size: if non-zero allocate this amount of bytes for private data -+ * -+ * Managed of_phy_package_join(). Shared storage fetched by this function, -+ * phy_package_leave() is automatically called on driver detach. See -+ * of_phy_package_join() for more information. -+ */ -+int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev, -+ size_t priv_size) -+{ -+ struct phy_device **ptr; -+ int ret; -+ -+ ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr), -+ GFP_KERNEL); -+ if (!ptr) -+ return -ENOMEM; -+ -+ ret = of_phy_package_join(phydev, priv_size); -+ -+ if (!ret) { -+ *ptr = phydev; -+ devres_add(dev, ptr); -+ } else { -+ devres_free(ptr); -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(devm_of_phy_package_join); -+ -+/** - * phy_detach - detach a PHY device from its network device - * @phydev: target phy_device struct - * ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -321,6 +321,7 @@ struct mdio_bus_stats { - * struct phy_package_shared - Shared information in PHY packages - * @base_addr: Base PHY address of PHY package used to combine PHYs - * in one package and for offset calculation of phy_package_read/write -+ * @np: Pointer to the Device Node if PHY package defined in DT - * @refcnt: Number of PHYs connected to this shared data - * @flags: Initialization of PHY package - * @priv_size: Size of the shared private data @priv -@@ -332,6 +333,8 @@ struct mdio_bus_stats { - */ - struct phy_package_shared { - u8 base_addr; -+ /* With PHY package defined in DT this points to the PHY package node */ -+ struct device_node *np; - refcount_t refcnt; - unsigned long flags; - size_t priv_size; -@@ -1793,9 +1796,12 @@ int phy_ethtool_set_link_ksettings(struc - const struct ethtool_link_ksettings *cmd); - int phy_ethtool_nway_reset(struct net_device *ndev); - int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size); -+int of_phy_package_join(struct phy_device *phydev, size_t priv_size); - void phy_package_leave(struct phy_device *phydev); - int devm_phy_package_join(struct device *dev, struct phy_device *phydev, - int base_addr, size_t priv_size); -+int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev, -+ size_t priv_size); - - #if IS_ENABLED(CONFIG_PHYLIB) - int __init mdio_bus_init(void); diff --git a/target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch b/target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch deleted file mode 100644 index e935725630c445..00000000000000 --- a/target/linux/generic/backport-6.1/716-v6.9-04-net-phy-qcom-move-more-function-to-shared-library.patch +++ /dev/null @@ -1,583 +0,0 @@ -From 737eb75a815f9c08dcbb6631db57f4f4b0540a5b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 6 Feb 2024 18:31:07 +0100 -Subject: [PATCH 04/10] net: phy: qcom: move more function to shared library - -Move more function to shared library in preparation for introduction of -new PHY Family qca807x that will make use of both functions from at803x -and qca808x as it's a transition PHY with some implementation of at803x -and some from the new qca808x. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/qcom/at803x.c | 35 ----- - drivers/net/phy/qcom/qca808x.c | 205 ---------------------------- - drivers/net/phy/qcom/qcom-phy-lib.c | 193 ++++++++++++++++++++++++++ - drivers/net/phy/qcom/qcom.h | 51 +++++++ - 4 files changed, 244 insertions(+), 240 deletions(-) - ---- a/drivers/net/phy/qcom/at803x.c -+++ b/drivers/net/phy/qcom/at803x.c -@@ -504,41 +504,6 @@ static void at803x_link_change_notify(st - } - } - --static int at803x_read_status(struct phy_device *phydev) --{ -- struct at803x_ss_mask ss_mask = { 0 }; -- int err, old_link = phydev->link; -- -- /* Update the link, but return if there was an error */ -- err = genphy_update_link(phydev); -- if (err) -- return err; -- -- /* why bother the PHY if nothing can have changed */ -- if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) -- return 0; -- -- phydev->speed = SPEED_UNKNOWN; -- phydev->duplex = DUPLEX_UNKNOWN; -- phydev->pause = 0; -- phydev->asym_pause = 0; -- -- err = genphy_read_lpa(phydev); -- if (err < 0) -- return err; -- -- ss_mask.speed_mask = AT803X_SS_SPEED_MASK; -- ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK); -- err = at803x_read_specific_status(phydev, ss_mask); -- if (err < 0) -- return err; -- -- if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) -- phy_resolve_aneg_pause(phydev); -- -- return 0; --} -- - static int at803x_config_aneg(struct phy_device *phydev) - { - struct at803x_priv *priv = phydev->priv; ---- a/drivers/net/phy/qcom/qca808x.c -+++ b/drivers/net/phy/qcom/qca808x.c -@@ -2,7 +2,6 @@ - - #include - #include --#include - - #include "qcom.h" - -@@ -63,55 +62,6 @@ - #define QCA808X_DBG_AN_TEST 0xb - #define QCA808X_HIBERNATION_EN BIT(15) - --#define QCA808X_CDT_ENABLE_TEST BIT(15) --#define QCA808X_CDT_INTER_CHECK_DIS BIT(13) --#define QCA808X_CDT_STATUS BIT(11) --#define QCA808X_CDT_LENGTH_UNIT BIT(10) -- --#define QCA808X_MMD3_CDT_STATUS 0x8064 --#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 --#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 --#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 --#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 --#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) --#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) -- --#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) --#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) --#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) --#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) -- --#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) --#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) --#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) --#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) --#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) -- --#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) --#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) --#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) --#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) -- --/* NORMAL are MDI with type set to 0 */ --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -- QCA808X_CDT_STATUS_STAT_MDI1) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -- QCA808X_CDT_STATUS_STAT_MDI1) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -- QCA808X_CDT_STATUS_STAT_MDI2) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -- QCA808X_CDT_STATUS_STAT_MDI2) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -- QCA808X_CDT_STATUS_STAT_MDI3) --#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -- QCA808X_CDT_STATUS_STAT_MDI3) -- --/* Added for reference of existence but should be handled by wait_for_completion already */ --#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) -- - #define QCA808X_MMD7_LED_GLOBAL 0x8073 - #define QCA808X_LED_BLINK_1 GENMASK(11, 6) - #define QCA808X_LED_BLINK_2 GENMASK(5, 0) -@@ -406,86 +356,6 @@ static int qca808x_soft_reset(struct phy - return ret; - } - --static bool qca808x_cdt_fault_length_valid(int cdt_code) --{ -- switch (cdt_code) { -- case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -- return true; -- default: -- return false; -- } --} -- --static int qca808x_cable_test_result_trans(int cdt_code) --{ -- switch (cdt_code) { -- case QCA808X_CDT_STATUS_STAT_NORMAL: -- return ETHTOOL_A_CABLE_RESULT_CODE_OK; -- case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -- return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; -- case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -- return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -- case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -- return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; -- case QCA808X_CDT_STATUS_STAT_FAIL: -- default: -- return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; -- } --} -- --static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, -- int result) --{ -- int val; -- u32 cdt_length_reg = 0; -- -- switch (pair) { -- case ETHTOOL_A_CABLE_PAIR_A: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; -- break; -- case ETHTOOL_A_CABLE_PAIR_B: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; -- break; -- case ETHTOOL_A_CABLE_PAIR_C: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; -- break; -- case ETHTOOL_A_CABLE_PAIR_D: -- cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; -- break; -- default: -- return -EINVAL; -- } -- -- val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); -- if (val < 0) -- return val; -- -- if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) -- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); -- else -- val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); -- -- return at803x_cdt_fault_length(val); --} -- - static int qca808x_cable_test_start(struct phy_device *phydev) - { - int ret; -@@ -526,81 +396,6 @@ static int qca808x_cable_test_start(stru - - return 0; - } -- --static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, -- u16 status) --{ -- int length, result; -- u16 pair_code; -- -- switch (pair) { -- case ETHTOOL_A_CABLE_PAIR_A: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); -- break; -- case ETHTOOL_A_CABLE_PAIR_B: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); -- break; -- case ETHTOOL_A_CABLE_PAIR_C: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); -- break; -- case ETHTOOL_A_CABLE_PAIR_D: -- pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); -- break; -- default: -- return -EINVAL; -- } -- -- result = qca808x_cable_test_result_trans(pair_code); -- ethnl_cable_test_result(phydev, pair, result); -- -- if (qca808x_cdt_fault_length_valid(pair_code)) { -- length = qca808x_cdt_fault_length(phydev, pair, result); -- ethnl_cable_test_fault_length(phydev, pair, length); -- } -- -- return 0; --} -- --static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) --{ -- int ret, val; -- -- *finished = false; -- -- val = QCA808X_CDT_ENABLE_TEST | -- QCA808X_CDT_LENGTH_UNIT; -- ret = at803x_cdt_start(phydev, val); -- if (ret) -- return ret; -- -- ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); -- if (ret) -- return ret; -- -- val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); -- if (val < 0) -- return val; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); -- if (ret) -- return ret; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); -- if (ret) -- return ret; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); -- if (ret) -- return ret; -- -- ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); -- if (ret) -- return ret; -- -- *finished = true; -- -- return 0; --} - - static int qca808x_get_features(struct phy_device *phydev) - { ---- a/drivers/net/phy/qcom/qcom-phy-lib.c -+++ b/drivers/net/phy/qcom/qcom-phy-lib.c -@@ -5,6 +5,7 @@ - - #include - #include -+#include - - #include "qcom.h" - -@@ -311,6 +312,42 @@ int at803x_prepare_config_aneg(struct ph - } - EXPORT_SYMBOL_GPL(at803x_prepare_config_aneg); - -+int at803x_read_status(struct phy_device *phydev) -+{ -+ struct at803x_ss_mask ss_mask = { 0 }; -+ int err, old_link = phydev->link; -+ -+ /* Update the link, but return if there was an error */ -+ err = genphy_update_link(phydev); -+ if (err) -+ return err; -+ -+ /* why bother the PHY if nothing can have changed */ -+ if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) -+ return 0; -+ -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->duplex = DUPLEX_UNKNOWN; -+ phydev->pause = 0; -+ phydev->asym_pause = 0; -+ -+ err = genphy_read_lpa(phydev); -+ if (err < 0) -+ return err; -+ -+ ss_mask.speed_mask = AT803X_SS_SPEED_MASK; -+ ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK); -+ err = at803x_read_specific_status(phydev, ss_mask); -+ if (err < 0) -+ return err; -+ -+ if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) -+ phy_resolve_aneg_pause(phydev); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(at803x_read_status); -+ - static int at803x_get_downshift(struct phy_device *phydev, u8 *d) - { - int val; -@@ -427,3 +464,159 @@ int at803x_cdt_wait_for_completion(struc - return ret < 0 ? ret : 0; - } - EXPORT_SYMBOL_GPL(at803x_cdt_wait_for_completion); -+ -+static bool qca808x_cdt_fault_length_valid(int cdt_code) -+{ -+ switch (cdt_code) { -+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+static int qca808x_cable_test_result_trans(int cdt_code) -+{ -+ switch (cdt_code) { -+ case QCA808X_CDT_STATUS_STAT_NORMAL: -+ return ETHTOOL_A_CABLE_RESULT_CODE_OK; -+ case QCA808X_CDT_STATUS_STAT_SAME_SHORT: -+ return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; -+ case QCA808X_CDT_STATUS_STAT_SAME_OPEN: -+ return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: -+ case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: -+ return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; -+ case QCA808X_CDT_STATUS_STAT_FAIL: -+ default: -+ return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; -+ } -+} -+ -+static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, -+ int result) -+{ -+ int val; -+ u32 cdt_length_reg = 0; -+ -+ switch (pair) { -+ case ETHTOOL_A_CABLE_PAIR_A: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; -+ break; -+ case ETHTOOL_A_CABLE_PAIR_B: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; -+ break; -+ case ETHTOOL_A_CABLE_PAIR_C: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; -+ break; -+ case ETHTOOL_A_CABLE_PAIR_D: -+ cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); -+ if (val < 0) -+ return val; -+ -+ if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) -+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); -+ else -+ val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); -+ -+ return at803x_cdt_fault_length(val); -+} -+ -+static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, -+ u16 status) -+{ -+ int length, result; -+ u16 pair_code; -+ -+ switch (pair) { -+ case ETHTOOL_A_CABLE_PAIR_A: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_B: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_C: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); -+ break; -+ case ETHTOOL_A_CABLE_PAIR_D: -+ pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ result = qca808x_cable_test_result_trans(pair_code); -+ ethnl_cable_test_result(phydev, pair, result); -+ -+ if (qca808x_cdt_fault_length_valid(pair_code)) { -+ length = qca808x_cdt_fault_length(phydev, pair, result); -+ ethnl_cable_test_fault_length(phydev, pair, length); -+ } -+ -+ return 0; -+} -+ -+int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) -+{ -+ int ret, val; -+ -+ *finished = false; -+ -+ val = QCA808X_CDT_ENABLE_TEST | -+ QCA808X_CDT_LENGTH_UNIT; -+ ret = at803x_cdt_start(phydev, val); -+ if (ret) -+ return ret; -+ -+ ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); -+ if (ret) -+ return ret; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); -+ if (val < 0) -+ return val; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); -+ if (ret) -+ return ret; -+ -+ ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); -+ if (ret) -+ return ret; -+ -+ *finished = true; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(qca808x_cable_test_get_status); ---- a/drivers/net/phy/qcom/qcom.h -+++ b/drivers/net/phy/qcom/qcom.h -@@ -54,6 +54,55 @@ - #define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8) - #define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0) - -+#define QCA808X_CDT_ENABLE_TEST BIT(15) -+#define QCA808X_CDT_INTER_CHECK_DIS BIT(13) -+#define QCA808X_CDT_STATUS BIT(11) -+#define QCA808X_CDT_LENGTH_UNIT BIT(10) -+ -+#define QCA808X_MMD3_CDT_STATUS 0x8064 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 -+#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 -+#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) -+#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) -+ -+#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) -+#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) -+#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) -+#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) -+ -+#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) -+#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) -+#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) -+#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) -+#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) -+ -+#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) -+#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) -+#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) -+#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) -+ -+/* NORMAL are MDI with type set to 0 */ -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI1) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI1) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI2) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI2) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ -+ QCA808X_CDT_STATUS_STAT_MDI3) -+#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ -+ QCA808X_CDT_STATUS_STAT_MDI3) -+ -+/* Added for reference of existence but should be handled by wait_for_completion already */ -+#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) -+ - #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C - #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B - #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A -@@ -110,6 +159,7 @@ int at803x_read_specific_status(struct p - struct at803x_ss_mask ss_mask); - int at803x_config_mdix(struct phy_device *phydev, u8 ctrl); - int at803x_prepare_config_aneg(struct phy_device *phydev); -+int at803x_read_status(struct phy_device *phydev); - int at803x_get_tunable(struct phy_device *phydev, - struct ethtool_tunable *tuna, void *data); - int at803x_set_tunable(struct phy_device *phydev, -@@ -118,3 +168,4 @@ int at803x_cdt_fault_length(int dt); - int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start); - int at803x_cdt_wait_for_completion(struct phy_device *phydev, - u32 cdt_en); -+int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished); diff --git a/target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch b/target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch deleted file mode 100644 index acaa4a644ee419..00000000000000 --- a/target/linux/generic/backport-6.1/716-v6.9-06-net-phy-provide-whether-link-has-changed-in-c37_read.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 9b1d5e055508393561e26bd1720f4c2639b03b1a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 6 Feb 2024 18:31:09 +0100 -Subject: [PATCH 06/10] net: phy: provide whether link has changed in - c37_read_status - -Some PHY driver might require additional regs call after -genphy_c37_read_status() is called. - -Expand genphy_c37_read_status to provide a bool wheather the link has -changed or not to permit PHY driver to skip additional regs call if -nothing has changed. - -Every user of genphy_c37_read_status() is updated with the new -additional bool. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/broadcom.c | 3 ++- - drivers/net/phy/phy_device.c | 11 +++++++++-- - drivers/net/phy/qcom/at803x.c | 3 ++- - include/linux/phy.h | 2 +- - 4 files changed, 14 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/broadcom.c -+++ b/drivers/net/phy/broadcom.c -@@ -609,10 +609,11 @@ static int bcm54616s_config_aneg(struct - static int bcm54616s_read_status(struct phy_device *phydev) - { - struct bcm54616s_phy_priv *priv = phydev->priv; -+ bool changed; - int err; - - if (priv->mode_1000bx_en) -- err = genphy_c37_read_status(phydev); -+ err = genphy_c37_read_status(phydev, &changed); - else - err = genphy_read_status(phydev); - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -2549,12 +2549,15 @@ EXPORT_SYMBOL(genphy_read_status); - /** - * genphy_c37_read_status - check the link status and update current link state - * @phydev: target phy_device struct -+ * @changed: pointer where to store if link changed - * - * Description: Check the link, then figure out the current state - * by comparing what we advertise with what the link partner - * advertises. This function is for Clause 37 1000Base-X mode. -+ * -+ * If link has changed, @changed is set to true, false otherwise. - */ --int genphy_c37_read_status(struct phy_device *phydev) -+int genphy_c37_read_status(struct phy_device *phydev, bool *changed) - { - int lpa, err, old_link = phydev->link; - -@@ -2564,9 +2567,13 @@ int genphy_c37_read_status(struct phy_de - return err; - - /* why bother the PHY if nothing can have changed */ -- if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) -+ if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) { -+ *changed = false; - return 0; -+ } - -+ /* Signal link has changed */ -+ *changed = true; - phydev->duplex = DUPLEX_UNKNOWN; - phydev->pause = 0; - phydev->asym_pause = 0; ---- a/drivers/net/phy/qcom/at803x.c -+++ b/drivers/net/phy/qcom/at803x.c -@@ -912,9 +912,10 @@ static int at8031_config_intr(struct phy - static int at8031_read_status(struct phy_device *phydev) - { - struct at803x_priv *priv = phydev->priv; -+ bool changed; - - if (priv->is_1000basex) -- return genphy_c37_read_status(phydev); -+ return genphy_c37_read_status(phydev, &changed); - - return at803x_read_status(phydev); - } ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -1688,7 +1688,7 @@ int genphy_write_mmd_unsupported(struct - - /* Clause 37 */ - int genphy_c37_config_aneg(struct phy_device *phydev); --int genphy_c37_read_status(struct phy_device *phydev); -+int genphy_c37_read_status(struct phy_device *phydev, bool *changed); - - /* Clause 45 PHY */ - int genphy_c45_restart_aneg(struct phy_device *phydev); diff --git a/target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch b/target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch deleted file mode 100644 index bbf0f76d68cc87..00000000000000 --- a/target/linux/generic/backport-6.1/716-v6.9-07-net-phy-qcom-add-support-for-QCA807x-PHY-Family.patch +++ /dev/null @@ -1,668 +0,0 @@ -From d1cb613efbd3cd7d0c000167816beb3f248f5eb8 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Tue, 6 Feb 2024 18:31:10 +0100 -Subject: [PATCH 07/10] net: phy: qcom: add support for QCA807x PHY Family - -This adds driver for the Qualcomm QCA8072 and QCA8075 PHY-s. - -They are 2 or 5 port IEEE 802.3 clause 22 compliant 10BASE-Te, -100BASE-TX and 1000BASE-T PHY-s. - -They feature 2 SerDes, one for PSGMII or QSGMII connection with -MAC, while second one is SGMII for connection to MAC or fiber. - -Both models have a combo port that supports 1000BASE-X and -100BASE-FX fiber. - -PHY package can be configured in 3 mode following this table: - - First Serdes mode Second Serdes mode -Option 1 PSGMII for copper Disabled - ports 0-4 -Option 2 PSGMII for copper 1000BASE-X / 100BASE-FX - ports 0-4 -Option 3 QSGMII for copper SGMII for - ports 0-3 copper port 4 - -Each PHY inside of QCA807x series has 4 digitally controlled -output only pins that natively drive LED-s. -But some vendors used these to driver generic LED-s controlled -by userspace, so lets enable registering each PHY as GPIO -controller and add driver for it. - -These are commonly used in Qualcomm IPQ40xx, IPQ60xx and IPQ807x -boards. - -Co-developed-by: Christian Marangi -Signed-off-by: Robert Marko -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/qcom/Kconfig | 8 + - drivers/net/phy/qcom/Makefile | 1 + - drivers/net/phy/qcom/qca807x.c | 597 +++++++++++++++++++++++++++++++++ - 3 files changed, 606 insertions(+) - create mode 100644 drivers/net/phy/qcom/qca807x.c - ---- a/drivers/net/phy/qcom/Kconfig -+++ b/drivers/net/phy/qcom/Kconfig -@@ -20,3 +20,11 @@ config QCA808X_PHY - select QCOM_NET_PHYLIB - help - Currently supports the QCA8081 model -+ -+config QCA807X_PHY -+ tristate "Qualcomm QCA807x PHYs" -+ select QCOM_NET_PHYLIB -+ depends on OF_MDIO -+ help -+ Currently supports the Qualcomm QCA8072, QCA8075 and the PSGMII -+ control PHY. ---- a/drivers/net/phy/qcom/Makefile -+++ b/drivers/net/phy/qcom/Makefile -@@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-ph - obj-$(CONFIG_AT803X_PHY) += at803x.o - obj-$(CONFIG_QCA83XX_PHY) += qca83xx.o - obj-$(CONFIG_QCA808X_PHY) += qca808x.o -+obj-$(CONFIG_QCA807X_PHY) += qca807x.o ---- /dev/null -+++ b/drivers/net/phy/qcom/qca807x.c -@@ -0,0 +1,597 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (c) 2023 Sartura Ltd. -+ * -+ * Author: Robert Marko -+ * Christian Marangi -+ * -+ * Qualcomm QCA8072 and QCA8075 PHY driver -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "qcom.h" -+ -+#define QCA807X_CHIP_CONFIGURATION 0x1f -+#define QCA807X_BT_BX_REG_SEL BIT(15) -+#define QCA807X_BT_BX_REG_SEL_FIBER 0 -+#define QCA807X_BT_BX_REG_SEL_COPPER 1 -+#define QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK GENMASK(3, 0) -+#define QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII 4 -+#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER 3 -+#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER 0 -+ -+#define QCA807X_MEDIA_SELECT_STATUS 0x1a -+#define QCA807X_MEDIA_DETECTED_COPPER BIT(5) -+#define QCA807X_MEDIA_DETECTED_1000_BASE_X BIT(4) -+#define QCA807X_MEDIA_DETECTED_100_BASE_FX BIT(3) -+ -+#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION 0x807e -+#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN BIT(0) -+ -+#define QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH 0x801a -+#define QCA807X_CONTROL_DAC_MASK GENMASK(2, 0) -+/* List of tweaks enabled by this bit: -+ * - With both FULL amplitude and FULL bias current: bias current -+ * is set to half. -+ * - With only DSP amplitude: bias current is set to half and -+ * is set to 1/4 with cable < 10m. -+ * - With DSP bias current (included both DSP amplitude and -+ * DSP bias current): bias current is half the detected current -+ * with cable < 10m. -+ */ -+#define QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK BIT(2) -+#define QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT BIT(1) -+#define QCA807X_CONTROL_DAC_DSP_AMPLITUDE BIT(0) -+ -+#define QCA807X_MMD7_LED_100N_1 0x8074 -+#define QCA807X_MMD7_LED_100N_2 0x8075 -+#define QCA807X_MMD7_LED_1000N_1 0x8076 -+#define QCA807X_MMD7_LED_1000N_2 0x8077 -+ -+#define QCA807X_MMD7_LED_CTRL(x) (0x8074 + ((x) * 2)) -+#define QCA807X_MMD7_LED_FORCE_CTRL(x) (0x8075 + ((x) * 2)) -+ -+#define QCA807X_GPIO_FORCE_EN BIT(15) -+#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13) -+ -+#define QCA807X_FUNCTION_CONTROL 0x10 -+#define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5) -+#define QCA807X_FC_MDI_CROSSOVER_AUTO 3 -+#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDIX 1 -+#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDI 0 -+ -+/* PQSGMII Analog PHY specific */ -+#define PQSGMII_CTRL_REG 0x0 -+#define PQSGMII_ANALOG_SW_RESET BIT(6) -+#define PQSGMII_DRIVE_CONTROL_1 0xb -+#define PQSGMII_TX_DRIVER_MASK GENMASK(7, 4) -+#define PQSGMII_TX_DRIVER_140MV 0x0 -+#define PQSGMII_TX_DRIVER_160MV 0x1 -+#define PQSGMII_TX_DRIVER_180MV 0x2 -+#define PQSGMII_TX_DRIVER_200MV 0x3 -+#define PQSGMII_TX_DRIVER_220MV 0x4 -+#define PQSGMII_TX_DRIVER_240MV 0x5 -+#define PQSGMII_TX_DRIVER_260MV 0x6 -+#define PQSGMII_TX_DRIVER_280MV 0x7 -+#define PQSGMII_TX_DRIVER_300MV 0x8 -+#define PQSGMII_TX_DRIVER_320MV 0x9 -+#define PQSGMII_TX_DRIVER_400MV 0xa -+#define PQSGMII_TX_DRIVER_500MV 0xb -+#define PQSGMII_TX_DRIVER_600MV 0xc -+#define PQSGMII_MODE_CTRL 0x6d -+#define PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK BIT(0) -+#define PQSGMII_MMD3_SERDES_CONTROL 0x805a -+ -+#define PHY_ID_QCA8072 0x004dd0b2 -+#define PHY_ID_QCA8075 0x004dd0b1 -+ -+#define QCA807X_COMBO_ADDR_OFFSET 4 -+#define QCA807X_PQSGMII_ADDR_OFFSET 5 -+#define SERDES_RESET_SLEEP 100 -+ -+enum qca807x_global_phy { -+ QCA807X_COMBO_ADDR = 4, -+ QCA807X_PQSGMII_ADDR = 5, -+}; -+ -+struct qca807x_shared_priv { -+ unsigned int package_mode; -+ u32 tx_drive_strength; -+}; -+ -+struct qca807x_gpio_priv { -+ struct phy_device *phy; -+}; -+ -+struct qca807x_priv { -+ bool dac_full_amplitude; -+ bool dac_full_bias_current; -+ bool dac_disable_bias_current_tweak; -+}; -+ -+static int qca807x_cable_test_start(struct phy_device *phydev) -+{ -+ /* we do all the (time consuming) work later */ -+ return 0; -+} -+ -+#ifdef CONFIG_GPIOLIB -+static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) -+{ -+ return GPIO_LINE_DIRECTION_OUT; -+} -+ -+static int qca807x_gpio_get(struct gpio_chip *gc, unsigned int offset) -+{ -+ struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); -+ u16 reg; -+ int val; -+ -+ reg = QCA807X_MMD7_LED_FORCE_CTRL(offset); -+ val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg); -+ -+ return FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val); -+} -+ -+static void qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) -+{ -+ struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); -+ u16 reg; -+ int val; -+ -+ reg = QCA807X_MMD7_LED_FORCE_CTRL(offset); -+ -+ val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg); -+ val &= ~QCA807X_GPIO_FORCE_MODE_MASK; -+ val |= QCA807X_GPIO_FORCE_EN; -+ val |= FIELD_PREP(QCA807X_GPIO_FORCE_MODE_MASK, value); -+ -+ phy_write_mmd(priv->phy, MDIO_MMD_AN, reg, val); -+} -+ -+static int qca807x_gpio_dir_out(struct gpio_chip *gc, unsigned int offset, int value) -+{ -+ qca807x_gpio_set(gc, offset, value); -+ -+ return 0; -+} -+ -+static int qca807x_gpio(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct qca807x_gpio_priv *priv; -+ struct gpio_chip *gc; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->phy = phydev; -+ -+ gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); -+ if (!gc) -+ return -ENOMEM; -+ -+ gc->label = dev_name(dev); -+ gc->base = -1; -+ gc->ngpio = 2; -+ gc->parent = dev; -+ gc->owner = THIS_MODULE; -+ gc->can_sleep = true; -+ gc->get_direction = qca807x_gpio_get_direction; -+ gc->direction_output = qca807x_gpio_dir_out; -+ gc->get = qca807x_gpio_get; -+ gc->set = qca807x_gpio_set; -+ -+ return devm_gpiochip_add_data(dev, gc, priv); -+} -+#endif -+ -+static int qca807x_read_fiber_status(struct phy_device *phydev) -+{ -+ bool changed; -+ int ss, err; -+ -+ err = genphy_c37_read_status(phydev, &changed); -+ if (err || !changed) -+ return err; -+ -+ /* Read the QCA807x PHY-Specific Status register fiber page, -+ * which indicates the speed and duplex that the PHY is actually -+ * using, irrespective of whether we are in autoneg mode or not. -+ */ -+ ss = phy_read(phydev, AT803X_SPECIFIC_STATUS); -+ if (ss < 0) -+ return ss; -+ -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->duplex = DUPLEX_UNKNOWN; -+ if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) { -+ switch (FIELD_GET(AT803X_SS_SPEED_MASK, ss)) { -+ case AT803X_SS_SPEED_100: -+ phydev->speed = SPEED_100; -+ break; -+ case AT803X_SS_SPEED_1000: -+ phydev->speed = SPEED_1000; -+ break; -+ } -+ -+ if (ss & AT803X_SS_DUPLEX) -+ phydev->duplex = DUPLEX_FULL; -+ else -+ phydev->duplex = DUPLEX_HALF; -+ } -+ -+ return 0; -+} -+ -+static int qca807x_read_status(struct phy_device *phydev) -+{ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported)) { -+ switch (phydev->port) { -+ case PORT_FIBRE: -+ return qca807x_read_fiber_status(phydev); -+ case PORT_TP: -+ return at803x_read_status(phydev); -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ return at803x_read_status(phydev); -+} -+ -+static int qca807x_phy_package_probe_once(struct phy_device *phydev) -+{ -+ struct phy_package_shared *shared = phydev->shared; -+ struct qca807x_shared_priv *priv = shared->priv; -+ unsigned int tx_drive_strength; -+ const char *package_mode_name; -+ -+ /* Default to 600mw if not defined */ -+ if (of_property_read_u32(shared->np, "qcom,tx-drive-strength-milliwatt", -+ &tx_drive_strength)) -+ tx_drive_strength = 600; -+ -+ switch (tx_drive_strength) { -+ case 140: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_140MV; -+ break; -+ case 160: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_160MV; -+ break; -+ case 180: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_180MV; -+ break; -+ case 200: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_200MV; -+ break; -+ case 220: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_220MV; -+ break; -+ case 240: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_240MV; -+ break; -+ case 260: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_260MV; -+ break; -+ case 280: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_280MV; -+ break; -+ case 300: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_300MV; -+ break; -+ case 320: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_320MV; -+ break; -+ case 400: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_400MV; -+ break; -+ case 500: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_500MV; -+ break; -+ case 600: -+ priv->tx_drive_strength = PQSGMII_TX_DRIVER_600MV; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ priv->package_mode = PHY_INTERFACE_MODE_NA; -+ if (!of_property_read_string(shared->np, "qcom,package-mode", -+ &package_mode_name)) { -+ if (!strcasecmp(package_mode_name, -+ phy_modes(PHY_INTERFACE_MODE_PSGMII))) -+ priv->package_mode = PHY_INTERFACE_MODE_PSGMII; -+ else if (!strcasecmp(package_mode_name, -+ phy_modes(PHY_INTERFACE_MODE_QSGMII))) -+ priv->package_mode = PHY_INTERFACE_MODE_QSGMII; -+ else -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int qca807x_phy_package_config_init_once(struct phy_device *phydev) -+{ -+ struct phy_package_shared *shared = phydev->shared; -+ struct qca807x_shared_priv *priv = shared->priv; -+ int val, ret; -+ -+ phy_lock_mdio_bus(phydev); -+ -+ /* Set correct PHY package mode */ -+ val = __phy_package_read(phydev, QCA807X_COMBO_ADDR, -+ QCA807X_CHIP_CONFIGURATION); -+ val &= ~QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK; -+ /* package_mode can be QSGMII or PSGMII and we validate -+ * this in probe_once. -+ * With package_mode to NA, we default to PSGMII. -+ */ -+ switch (priv->package_mode) { -+ case PHY_INTERFACE_MODE_QSGMII: -+ val |= QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII; -+ break; -+ case PHY_INTERFACE_MODE_PSGMII: -+ default: -+ val |= QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER; -+ } -+ ret = __phy_package_write(phydev, QCA807X_COMBO_ADDR, -+ QCA807X_CHIP_CONFIGURATION, val); -+ if (ret) -+ goto exit; -+ -+ /* After mode change Serdes reset is required */ -+ val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, -+ PQSGMII_CTRL_REG); -+ val &= ~PQSGMII_ANALOG_SW_RESET; -+ ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, -+ PQSGMII_CTRL_REG, val); -+ if (ret) -+ goto exit; -+ -+ msleep(SERDES_RESET_SLEEP); -+ -+ val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, -+ PQSGMII_CTRL_REG); -+ val |= PQSGMII_ANALOG_SW_RESET; -+ ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, -+ PQSGMII_CTRL_REG, val); -+ if (ret) -+ goto exit; -+ -+ /* Workaround to enable AZ transmitting ability */ -+ val = __phy_package_read_mmd(phydev, QCA807X_PQSGMII_ADDR, -+ MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL); -+ val &= ~PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK; -+ ret = __phy_package_write_mmd(phydev, QCA807X_PQSGMII_ADDR, -+ MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL, val); -+ if (ret) -+ goto exit; -+ -+ /* Set PQSGMII TX AMP strength */ -+ val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, -+ PQSGMII_DRIVE_CONTROL_1); -+ val &= ~PQSGMII_TX_DRIVER_MASK; -+ val |= FIELD_PREP(PQSGMII_TX_DRIVER_MASK, priv->tx_drive_strength); -+ ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, -+ PQSGMII_DRIVE_CONTROL_1, val); -+ if (ret) -+ goto exit; -+ -+ /* Prevent PSGMII going into hibernation via PSGMII self test */ -+ val = __phy_package_read_mmd(phydev, QCA807X_COMBO_ADDR, -+ MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL); -+ val &= ~BIT(1); -+ ret = __phy_package_write_mmd(phydev, QCA807X_COMBO_ADDR, -+ MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL, val); -+ -+exit: -+ phy_unlock_mdio_bus(phydev); -+ -+ return ret; -+} -+ -+static int qca807x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) -+{ -+ struct phy_device *phydev = upstream; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; -+ phy_interface_t iface; -+ int ret; -+ DECLARE_PHY_INTERFACE_MASK(interfaces); -+ -+ sfp_parse_support(phydev->sfp_bus, id, support, interfaces); -+ iface = sfp_select_interface(phydev->sfp_bus, support); -+ -+ dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface)); -+ -+ switch (iface) { -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_100BASEX: -+ /* Set PHY mode to PSGMII combo (1/4 copper + combo ports) mode */ -+ ret = phy_modify(phydev, -+ QCA807X_CHIP_CONFIGURATION, -+ QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK, -+ QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER); -+ /* Enable fiber mode autodection (1000Base-X or 100Base-FX) */ -+ ret = phy_set_bits_mmd(phydev, -+ MDIO_MMD_AN, -+ QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION, -+ QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN); -+ /* Select fiber page */ -+ ret = phy_clear_bits(phydev, -+ QCA807X_CHIP_CONFIGURATION, -+ QCA807X_BT_BX_REG_SEL); -+ -+ phydev->port = PORT_FIBRE; -+ break; -+ default: -+ dev_err(&phydev->mdio.dev, "Incompatible SFP module inserted\n"); -+ return -EINVAL; -+ } -+ -+ return ret; -+} -+ -+static void qca807x_sfp_remove(void *upstream) -+{ -+ struct phy_device *phydev = upstream; -+ -+ /* Select copper page */ -+ phy_set_bits(phydev, -+ QCA807X_CHIP_CONFIGURATION, -+ QCA807X_BT_BX_REG_SEL); -+ -+ phydev->port = PORT_TP; -+} -+ -+static const struct sfp_upstream_ops qca807x_sfp_ops = { -+ .attach = phy_sfp_attach, -+ .detach = phy_sfp_detach, -+ .module_insert = qca807x_sfp_insert, -+ .module_remove = qca807x_sfp_remove, -+}; -+ -+static int qca807x_probe(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ struct qca807x_shared_priv *shared_priv; -+ struct device *dev = &phydev->mdio.dev; -+ struct phy_package_shared *shared; -+ struct qca807x_priv *priv; -+ int ret; -+ -+ ret = devm_of_phy_package_join(dev, phydev, sizeof(*shared_priv)); -+ if (ret) -+ return ret; -+ -+ if (phy_package_probe_once(phydev)) { -+ ret = qca807x_phy_package_probe_once(phydev); -+ if (ret) -+ return ret; -+ } -+ -+ shared = phydev->shared; -+ shared_priv = shared->priv; -+ -+ /* Make sure PHY follow PHY package mode if enforced */ -+ if (shared_priv->package_mode != PHY_INTERFACE_MODE_NA && -+ phydev->interface != shared_priv->package_mode) -+ return -EINVAL; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->dac_full_amplitude = of_property_read_bool(node, "qcom,dac-full-amplitude"); -+ priv->dac_full_bias_current = of_property_read_bool(node, "qcom,dac-full-bias-current"); -+ priv->dac_disable_bias_current_tweak = of_property_read_bool(node, -+ "qcom,dac-disable-bias-current-tweak"); -+ -+ if (IS_ENABLED(CONFIG_GPIOLIB)) { -+ /* Do not register a GPIO controller unless flagged for it */ -+ if (of_property_read_bool(node, "gpio-controller")) { -+ ret = qca807x_gpio(phydev); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ /* Attach SFP bus on combo port*/ -+ if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) { -+ ret = phy_sfp_probe(phydev, &qca807x_sfp_ops); -+ if (ret) -+ return ret; -+ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->advertising); -+ } -+ -+ phydev->priv = priv; -+ -+ return 0; -+} -+ -+static int qca807x_config_init(struct phy_device *phydev) -+{ -+ struct qca807x_priv *priv = phydev->priv; -+ u16 control_dac; -+ int ret; -+ -+ if (phy_package_init_once(phydev)) { -+ ret = qca807x_phy_package_config_init_once(phydev); -+ if (ret) -+ return ret; -+ } -+ -+ control_dac = phy_read_mmd(phydev, MDIO_MMD_AN, -+ QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH); -+ control_dac &= ~QCA807X_CONTROL_DAC_MASK; -+ if (!priv->dac_full_amplitude) -+ control_dac |= QCA807X_CONTROL_DAC_DSP_AMPLITUDE; -+ if (!priv->dac_full_amplitude) -+ control_dac |= QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT; -+ if (!priv->dac_disable_bias_current_tweak) -+ control_dac |= QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK; -+ return phy_write_mmd(phydev, MDIO_MMD_AN, -+ QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH, -+ control_dac); -+} -+ -+static struct phy_driver qca807x_drivers[] = { -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_QCA8072), -+ .name = "Qualcomm QCA8072", -+ .flags = PHY_POLL_CABLE_TEST, -+ /* PHY_GBIT_FEATURES */ -+ .probe = qca807x_probe, -+ .config_init = qca807x_config_init, -+ .read_status = qca807x_read_status, -+ .config_intr = at803x_config_intr, -+ .handle_interrupt = at803x_handle_interrupt, -+ .soft_reset = genphy_soft_reset, -+ .get_tunable = at803x_get_tunable, -+ .set_tunable = at803x_set_tunable, -+ .resume = genphy_resume, -+ .suspend = genphy_suspend, -+ .cable_test_start = qca807x_cable_test_start, -+ .cable_test_get_status = qca808x_cable_test_get_status, -+ }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_QCA8075), -+ .name = "Qualcomm QCA8075", -+ .flags = PHY_POLL_CABLE_TEST, -+ /* PHY_GBIT_FEATURES */ -+ .probe = qca807x_probe, -+ .config_init = qca807x_config_init, -+ .read_status = qca807x_read_status, -+ .config_intr = at803x_config_intr, -+ .handle_interrupt = at803x_handle_interrupt, -+ .soft_reset = genphy_soft_reset, -+ .get_tunable = at803x_get_tunable, -+ .set_tunable = at803x_set_tunable, -+ .resume = genphy_resume, -+ .suspend = genphy_suspend, -+ .cable_test_start = qca807x_cable_test_start, -+ .cable_test_get_status = qca808x_cable_test_get_status, -+ }, -+}; -+module_phy_driver(qca807x_drivers); -+ -+static struct mdio_device_id __maybe_unused qca807x_tbl[] = { -+ { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072) }, -+ { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075) }, -+ { } -+}; -+ -+MODULE_AUTHOR("Robert Marko "); -+MODULE_AUTHOR("Christian Marangi "); -+MODULE_DESCRIPTION("Qualcomm QCA807x PHY driver"); -+MODULE_DEVICE_TABLE(mdio, qca807x_tbl); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch b/target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch deleted file mode 100644 index cf4d74e8c523c2..00000000000000 --- a/target/linux/generic/backport-6.1/716-v6.9-08-net-phy-qcom-move-common-qca808x-LED-define-to-share.patch +++ /dev/null @@ -1,179 +0,0 @@ -From ee9d9807bee0e6af8ca2a4db6f0d1dc0e5b41f44 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 6 Feb 2024 18:31:11 +0100 -Subject: [PATCH 08/10] net: phy: qcom: move common qca808x LED define to - shared header - -The LED implementation of qca808x and qca807x is the same but qca807x -supports also Fiber port and have different hw control bits for Fiber -port. - -In preparation for qca807x introduction, move all the common define to -shared header. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/qcom/qca808x.c | 65 ---------------------------------- - drivers/net/phy/qcom/qcom.h | 65 ++++++++++++++++++++++++++++++++++ - 2 files changed, 65 insertions(+), 65 deletions(-) - ---- a/drivers/net/phy/qcom/qca808x.c -+++ b/drivers/net/phy/qcom/qca808x.c -@@ -62,29 +62,6 @@ - #define QCA808X_DBG_AN_TEST 0xb - #define QCA808X_HIBERNATION_EN BIT(15) - --#define QCA808X_MMD7_LED_GLOBAL 0x8073 --#define QCA808X_LED_BLINK_1 GENMASK(11, 6) --#define QCA808X_LED_BLINK_2 GENMASK(5, 0) --/* Values are the same for both BLINK_1 and BLINK_2 */ --#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) --#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) --#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) --#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) --#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) --#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) --#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) --#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) --#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) --#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) --#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) --#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) --#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) --#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) --#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) --#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) --#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) --#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) -- - #define QCA808X_MMD7_LED2_CTRL 0x8074 - #define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075 - #define QCA808X_MMD7_LED1_CTRL 0x8076 -@@ -92,51 +69,9 @@ - #define QCA808X_MMD7_LED0_CTRL 0x8078 - #define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2)) - --/* LED hw control pattern is the same for every LED */ --#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) --#define QCA808X_LED_SPEED2500_ON BIT(15) --#define QCA808X_LED_SPEED2500_BLINK BIT(14) --/* Follow blink trigger even if duplex or speed condition doesn't match */ --#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) --#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) --#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) --#define QCA808X_LED_TX_BLINK BIT(10) --#define QCA808X_LED_RX_BLINK BIT(9) --#define QCA808X_LED_TX_ON_10MS BIT(8) --#define QCA808X_LED_RX_ON_10MS BIT(7) --#define QCA808X_LED_SPEED1000_ON BIT(6) --#define QCA808X_LED_SPEED100_ON BIT(5) --#define QCA808X_LED_SPEED10_ON BIT(4) --#define QCA808X_LED_COLLISION_BLINK BIT(3) --#define QCA808X_LED_SPEED1000_BLINK BIT(2) --#define QCA808X_LED_SPEED100_BLINK BIT(1) --#define QCA808X_LED_SPEED10_BLINK BIT(0) -- - #define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079 - #define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2)) - --/* LED force ctrl is the same for every LED -- * No documentation exist for this, not even internal one -- * with NDA as QCOM gives only info about configuring -- * hw control pattern rules and doesn't indicate any way -- * to force the LED to specific mode. -- * These define comes from reverse and testing and maybe -- * lack of some info or some info are not entirely correct. -- * For the basic LED control and hw control these finding -- * are enough to support LED control in all the required APIs. -- * -- * On doing some comparison with implementation with qca807x, -- * it was found that it's 1:1 equal to it and confirms all the -- * reverse done. It was also found further specification with the -- * force mode and the blink modes. -- */ --#define QCA808X_LED_FORCE_EN BIT(15) --#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) --#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) --#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) --#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) --#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) -- - #define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a - /* QSDK sets by default 0x46 to this reg that sets BIT 6 for - * LED to active high. It's not clear what BIT 3 and BIT 4 does. ---- a/drivers/net/phy/qcom/qcom.h -+++ b/drivers/net/phy/qcom/qcom.h -@@ -103,6 +103,71 @@ - /* Added for reference of existence but should be handled by wait_for_completion already */ - #define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) - -+#define QCA808X_MMD7_LED_GLOBAL 0x8073 -+#define QCA808X_LED_BLINK_1 GENMASK(11, 6) -+#define QCA808X_LED_BLINK_2 GENMASK(5, 0) -+/* Values are the same for both BLINK_1 and BLINK_2 */ -+#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) -+#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) -+#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) -+#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) -+#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) -+#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) -+#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) -+#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) -+#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) -+#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) -+#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) -+#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) -+#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) -+#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) -+#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) -+#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) -+#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) -+#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) -+ -+/* LED hw control pattern is the same for every LED */ -+#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) -+#define QCA808X_LED_SPEED2500_ON BIT(15) -+#define QCA808X_LED_SPEED2500_BLINK BIT(14) -+/* Follow blink trigger even if duplex or speed condition doesn't match */ -+#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) -+#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) -+#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) -+#define QCA808X_LED_TX_BLINK BIT(10) -+#define QCA808X_LED_RX_BLINK BIT(9) -+#define QCA808X_LED_TX_ON_10MS BIT(8) -+#define QCA808X_LED_RX_ON_10MS BIT(7) -+#define QCA808X_LED_SPEED1000_ON BIT(6) -+#define QCA808X_LED_SPEED100_ON BIT(5) -+#define QCA808X_LED_SPEED10_ON BIT(4) -+#define QCA808X_LED_COLLISION_BLINK BIT(3) -+#define QCA808X_LED_SPEED1000_BLINK BIT(2) -+#define QCA808X_LED_SPEED100_BLINK BIT(1) -+#define QCA808X_LED_SPEED10_BLINK BIT(0) -+ -+/* LED force ctrl is the same for every LED -+ * No documentation exist for this, not even internal one -+ * with NDA as QCOM gives only info about configuring -+ * hw control pattern rules and doesn't indicate any way -+ * to force the LED to specific mode. -+ * These define comes from reverse and testing and maybe -+ * lack of some info or some info are not entirely correct. -+ * For the basic LED control and hw control these finding -+ * are enough to support LED control in all the required APIs. -+ * -+ * On doing some comparison with implementation with qca807x, -+ * it was found that it's 1:1 equal to it and confirms all the -+ * reverse done. It was also found further specification with the -+ * force mode and the blink modes. -+ */ -+#define QCA808X_LED_FORCE_EN BIT(15) -+#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) -+#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) -+#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) -+#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) -+#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) -+ - #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C - #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B - #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A diff --git a/target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch b/target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch deleted file mode 100644 index da73c1d3b8981b..00000000000000 --- a/target/linux/generic/backport-6.1/716-v6.9-09-net-phy-qcom-generalize-some-qca808x-LED-functions.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 47b930d0dd437af927145dba50a2e2ea1ba97c67 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 6 Feb 2024 18:31:12 +0100 -Subject: [PATCH 09/10] net: phy: qcom: generalize some qca808x LED functions - -Generalize some qca808x LED functions in preparation for qca807x LED -support. - -The LED implementation of qca808x and qca807x is the same but qca807x -supports also Fiber port and have different hw control bits for Fiber -port. To limit code duplication introduce micro functions that takes reg -instead of LED index to tweak all the supported LED modes. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/qcom/qca808x.c | 38 +++----------------- - drivers/net/phy/qcom/qcom-phy-lib.c | 54 +++++++++++++++++++++++++++++ - drivers/net/phy/qcom/qcom.h | 7 ++++ - 3 files changed, 65 insertions(+), 34 deletions(-) - ---- a/drivers/net/phy/qcom/qca808x.c -+++ b/drivers/net/phy/qcom/qca808x.c -@@ -437,9 +437,7 @@ static int qca808x_led_hw_control_enable - return -EINVAL; - - reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_FORCE_EN); -+ return qca808x_led_reg_hw_control_enable(phydev, reg); - } - - static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index, -@@ -480,16 +478,12 @@ static int qca808x_led_hw_control_set(st - static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index) - { - u16 reg; -- int val; - - if (index > 2) - return false; - - reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -- -- return !(val & QCA808X_LED_FORCE_EN); -+ return qca808x_led_reg_hw_control_status(phydev, reg); - } - - static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index, -@@ -557,44 +551,20 @@ static int qca808x_led_brightness_set(st - } - - reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -- QCA808X_LED_FORCE_EN | (value ? QCA808X_LED_FORCE_ON : -- QCA808X_LED_FORCE_OFF)); -+ return qca808x_led_reg_brightness_set(phydev, reg, value); - } - - static int qca808x_led_blink_set(struct phy_device *phydev, u8 index, - unsigned long *delay_on, - unsigned long *delay_off) - { -- int ret; - u16 reg; - - if (index > 2) - return -EINVAL; - - reg = QCA808X_MMD7_LED_FORCE_CTRL(index); -- -- /* Set blink to 50% off, 50% on at 4Hz by default */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, -- QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, -- QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); -- if (ret) -- return ret; -- -- /* We use BLINK_1 for normal blinking */ -- ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -- QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); -- if (ret) -- return ret; -- -- /* We set blink to 4Hz, aka 250ms */ -- *delay_on = 250 / 2; -- *delay_off = 250 / 2; -- -- return 0; -+ return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off); - } - - static int qca808x_led_polarity_set(struct phy_device *phydev, int index, ---- a/drivers/net/phy/qcom/qcom-phy-lib.c -+++ b/drivers/net/phy/qcom/qcom-phy-lib.c -@@ -620,3 +620,57 @@ int qca808x_cable_test_get_status(struct - return 0; - } - EXPORT_SYMBOL_GPL(qca808x_cable_test_get_status); -+ -+int qca808x_led_reg_hw_control_enable(struct phy_device *phydev, u16 reg) -+{ -+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN); -+} -+EXPORT_SYMBOL_GPL(qca808x_led_reg_hw_control_enable); -+ -+bool qca808x_led_reg_hw_control_status(struct phy_device *phydev, u16 reg) -+{ -+ int val; -+ -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -+ return !(val & QCA808X_LED_FORCE_EN); -+} -+EXPORT_SYMBOL_GPL(qca808x_led_reg_hw_control_status); -+ -+int qca808x_led_reg_brightness_set(struct phy_device *phydev, -+ u16 reg, enum led_brightness value) -+{ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -+ QCA808X_LED_FORCE_EN | (value ? QCA808X_LED_FORCE_ON : -+ QCA808X_LED_FORCE_OFF)); -+} -+EXPORT_SYMBOL_GPL(qca808x_led_reg_brightness_set); -+ -+int qca808x_led_reg_blink_set(struct phy_device *phydev, u16 reg, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ int ret; -+ -+ /* Set blink to 50% off, 50% on at 4Hz by default */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, -+ QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, -+ QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); -+ if (ret) -+ return ret; -+ -+ /* We use BLINK_1 for normal blinking */ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, -+ QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); -+ if (ret) -+ return ret; -+ -+ /* We set blink to 4Hz, aka 250ms */ -+ *delay_on = 250 / 2; -+ *delay_off = 250 / 2; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(qca808x_led_reg_blink_set); ---- a/drivers/net/phy/qcom/qcom.h -+++ b/drivers/net/phy/qcom/qcom.h -@@ -234,3 +234,10 @@ int at803x_cdt_start(struct phy_device * - int at803x_cdt_wait_for_completion(struct phy_device *phydev, - u32 cdt_en); - int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished); -+int qca808x_led_reg_hw_control_enable(struct phy_device *phydev, u16 reg); -+bool qca808x_led_reg_hw_control_status(struct phy_device *phydev, u16 reg); -+int qca808x_led_reg_brightness_set(struct phy_device *phydev, -+ u16 reg, enum led_brightness value); -+int qca808x_led_reg_blink_set(struct phy_device *phydev, u16 reg, -+ unsigned long *delay_on, -+ unsigned long *delay_off); diff --git a/target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch b/target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch deleted file mode 100644 index 3bd36f6ffe2f7a..00000000000000 --- a/target/linux/generic/backport-6.1/716-v6.9-10-net-phy-qca807x-add-support-for-configurable-LED.patch +++ /dev/null @@ -1,326 +0,0 @@ -From f508a226b517a6a8afd78a317de46bc83e3e3d51 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 6 Feb 2024 18:31:13 +0100 -Subject: [PATCH 10/10] net: phy: qca807x: add support for configurable LED - -QCA8072/5 have up to 2 LEDs attached for PHY. - -LEDs can be configured to be ON/hw blink or be set to HW control. - -Hw blink mode is set to blink at 4Hz or 250ms. - -PHY can support both copper (TP) or fiber (FIBRE) kind and supports -different HW control modes based on the port type. - -HW control modes supported for netdev trigger for copper ports are: -- LINK_10 -- LINK_100 -- LINK_1000 -- TX -- RX -- FULL_DUPLEX -- HALF_DUPLEX - -HW control modes supported for netdev trigger for fiber ports are: -- LINK_100 -- LINK_1000 -- TX -- RX -- FULL_DUPLEX -- HALF_DUPLEX - -LED support conflicts with GPIO controller feature and must be disabled -if gpio-controller is used for the PHY. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/phy/qcom/qca807x.c | 256 ++++++++++++++++++++++++++++++++- - 1 file changed, 254 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/qcom/qca807x.c -+++ b/drivers/net/phy/qcom/qca807x.c -@@ -57,8 +57,18 @@ - #define QCA807X_MMD7_LED_CTRL(x) (0x8074 + ((x) * 2)) - #define QCA807X_MMD7_LED_FORCE_CTRL(x) (0x8075 + ((x) * 2)) - --#define QCA807X_GPIO_FORCE_EN BIT(15) --#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13) -+/* LED hw control pattern for fiber port */ -+#define QCA807X_LED_FIBER_PATTERN_MASK GENMASK(11, 1) -+#define QCA807X_LED_FIBER_TXACT_BLK_EN BIT(10) -+#define QCA807X_LED_FIBER_RXACT_BLK_EN BIT(9) -+#define QCA807X_LED_FIBER_FDX_ON_EN BIT(6) -+#define QCA807X_LED_FIBER_HDX_ON_EN BIT(5) -+#define QCA807X_LED_FIBER_1000BX_ON_EN BIT(2) -+#define QCA807X_LED_FIBER_100FX_ON_EN BIT(1) -+ -+/* Some device repurpose the LED as GPIO out */ -+#define QCA807X_GPIO_FORCE_EN QCA808X_LED_FORCE_EN -+#define QCA807X_GPIO_FORCE_MODE_MASK QCA808X_LED_FORCE_MODE_MASK - - #define QCA807X_FUNCTION_CONTROL 0x10 - #define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5) -@@ -121,6 +131,233 @@ static int qca807x_cable_test_start(stru - return 0; - } - -+static int qca807x_led_parse_netdev(struct phy_device *phydev, unsigned long rules, -+ u16 *offload_trigger) -+{ -+ /* Parsing specific to netdev trigger */ -+ switch (phydev->port) { -+ case PORT_TP: -+ if (test_bit(TRIGGER_NETDEV_TX, &rules)) -+ *offload_trigger |= QCA808X_LED_TX_BLINK; -+ if (test_bit(TRIGGER_NETDEV_RX, &rules)) -+ *offload_trigger |= QCA808X_LED_RX_BLINK; -+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED10_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED100_ON; -+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) -+ *offload_trigger |= QCA808X_LED_SPEED1000_ON; -+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) -+ *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON; -+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) -+ *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON; -+ break; -+ case PORT_FIBRE: -+ if (test_bit(TRIGGER_NETDEV_TX, &rules)) -+ *offload_trigger |= QCA807X_LED_FIBER_TXACT_BLK_EN; -+ if (test_bit(TRIGGER_NETDEV_RX, &rules)) -+ *offload_trigger |= QCA807X_LED_FIBER_RXACT_BLK_EN; -+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) -+ *offload_trigger |= QCA807X_LED_FIBER_100FX_ON_EN; -+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) -+ *offload_trigger |= QCA807X_LED_FIBER_1000BX_ON_EN; -+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) -+ *offload_trigger |= QCA807X_LED_FIBER_HDX_ON_EN; -+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) -+ *offload_trigger |= QCA807X_LED_FIBER_FDX_ON_EN; -+ break; -+ default: -+ return -EOPNOTSUPP; -+ } -+ -+ if (rules && !*offload_trigger) -+ return -EOPNOTSUPP; -+ -+ return 0; -+} -+ -+static int qca807x_led_hw_control_enable(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); -+ return qca808x_led_reg_hw_control_enable(phydev, reg); -+} -+ -+static int qca807x_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 offload_trigger = 0; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ return qca807x_led_parse_netdev(phydev, rules, &offload_trigger); -+} -+ -+static int qca807x_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ u16 reg, mask, offload_trigger = 0; -+ int ret; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ ret = qca807x_led_parse_netdev(phydev, rules, &offload_trigger); -+ if (ret) -+ return ret; -+ -+ ret = qca807x_led_hw_control_enable(phydev, index); -+ if (ret) -+ return ret; -+ -+ switch (phydev->port) { -+ case PORT_TP: -+ reg = QCA807X_MMD7_LED_CTRL(index); -+ mask = QCA808X_LED_PATTERN_MASK; -+ break; -+ case PORT_FIBRE: -+ /* HW control pattern bits are in LED FORCE reg */ -+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); -+ mask = QCA807X_LED_FIBER_PATTERN_MASK; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, mask, -+ offload_trigger); -+} -+ -+static bool qca807x_led_hw_control_status(struct phy_device *phydev, u8 index) -+{ -+ u16 reg; -+ -+ if (index > 1) -+ return false; -+ -+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); -+ return qca808x_led_reg_hw_control_status(phydev, reg); -+} -+ -+static int qca807x_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ u16 reg; -+ int val; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ /* Check if we have hw control enabled */ -+ if (qca807x_led_hw_control_status(phydev, index)) -+ return -EINVAL; -+ -+ /* Parsing specific to netdev trigger */ -+ switch (phydev->port) { -+ case PORT_TP: -+ reg = QCA807X_MMD7_LED_CTRL(index); -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -+ if (val & QCA808X_LED_TX_BLINK) -+ set_bit(TRIGGER_NETDEV_TX, rules); -+ if (val & QCA808X_LED_RX_BLINK) -+ set_bit(TRIGGER_NETDEV_RX, rules); -+ if (val & QCA808X_LED_SPEED10_ON) -+ set_bit(TRIGGER_NETDEV_LINK_10, rules); -+ if (val & QCA808X_LED_SPEED100_ON) -+ set_bit(TRIGGER_NETDEV_LINK_100, rules); -+ if (val & QCA808X_LED_SPEED1000_ON) -+ set_bit(TRIGGER_NETDEV_LINK_1000, rules); -+ if (val & QCA808X_LED_HALF_DUPLEX_ON) -+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); -+ if (val & QCA808X_LED_FULL_DUPLEX_ON) -+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); -+ break; -+ case PORT_FIBRE: -+ /* HW control pattern bits are in LED FORCE reg */ -+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); -+ val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); -+ if (val & QCA807X_LED_FIBER_TXACT_BLK_EN) -+ set_bit(TRIGGER_NETDEV_TX, rules); -+ if (val & QCA807X_LED_FIBER_RXACT_BLK_EN) -+ set_bit(TRIGGER_NETDEV_RX, rules); -+ if (val & QCA807X_LED_FIBER_100FX_ON_EN) -+ set_bit(TRIGGER_NETDEV_LINK_100, rules); -+ if (val & QCA807X_LED_FIBER_1000BX_ON_EN) -+ set_bit(TRIGGER_NETDEV_LINK_1000, rules); -+ if (val & QCA807X_LED_FIBER_HDX_ON_EN) -+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); -+ if (val & QCA807X_LED_FIBER_FDX_ON_EN) -+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int qca807x_led_hw_control_reset(struct phy_device *phydev, u8 index) -+{ -+ u16 reg, mask; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ switch (phydev->port) { -+ case PORT_TP: -+ reg = QCA807X_MMD7_LED_CTRL(index); -+ mask = QCA808X_LED_PATTERN_MASK; -+ break; -+ case PORT_FIBRE: -+ /* HW control pattern bits are in LED FORCE reg */ -+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); -+ mask = QCA807X_LED_FIBER_PATTERN_MASK; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, mask); -+} -+ -+static int qca807x_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ u16 reg; -+ int ret; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ /* If we are setting off the LED reset any hw control rule */ -+ if (!value) { -+ ret = qca807x_led_hw_control_reset(phydev, index); -+ if (ret) -+ return ret; -+ } -+ -+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); -+ return qca808x_led_reg_brightness_set(phydev, reg, value); -+} -+ -+static int qca807x_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ u16 reg; -+ -+ if (index > 1) -+ return -EINVAL; -+ -+ reg = QCA807X_MMD7_LED_FORCE_CTRL(index); -+ return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off); -+} -+ - #ifdef CONFIG_GPIOLIB - static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) - { -@@ -496,6 +733,16 @@ static int qca807x_probe(struct phy_devi - "qcom,dac-disable-bias-current-tweak"); - - if (IS_ENABLED(CONFIG_GPIOLIB)) { -+ /* Make sure we don't have mixed leds node and gpio-controller -+ * to prevent registering leds and having gpio-controller usage -+ * conflicting with them. -+ */ -+ if (of_find_property(node, "leds", NULL) && -+ of_find_property(node, "gpio-controller", NULL)) { -+ phydev_err(phydev, "Invalid property detected. LEDs and gpio-controller are mutually exclusive."); -+ return -EINVAL; -+ } -+ - /* Do not register a GPIO controller unless flagged for it */ - if (of_property_read_bool(node, "gpio-controller")) { - ret = qca807x_gpio(phydev); -@@ -580,6 +827,11 @@ static struct phy_driver qca807x_drivers - .suspend = genphy_suspend, - .cable_test_start = qca807x_cable_test_start, - .cable_test_get_status = qca808x_cable_test_get_status, -+ .led_brightness_set = qca807x_led_brightness_set, -+ .led_blink_set = qca807x_led_blink_set, -+ .led_hw_is_supported = qca807x_led_hw_is_supported, -+ .led_hw_control_set = qca807x_led_hw_control_set, -+ .led_hw_control_get = qca807x_led_hw_control_get, - }, - }; - module_phy_driver(qca807x_drivers); diff --git a/target/linux/generic/backport-6.1/717-v6.9-net-phy-qca807x-move-interface-mode-check-to-.config.patch b/target/linux/generic/backport-6.1/717-v6.9-net-phy-qca807x-move-interface-mode-check-to-.config.patch deleted file mode 100644 index 53652c38fc0561..00000000000000 --- a/target/linux/generic/backport-6.1/717-v6.9-net-phy-qca807x-move-interface-mode-check-to-.config.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 3be0d950b62852a693182cb678948f481de02825 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Mon, 12 Feb 2024 12:49:34 +0100 -Subject: [PATCH] net: phy: qca807x: move interface mode check to - .config_init_once - -Currently, we are checking whether the PHY package mode matches the -individual PHY interface modes at PHY package probe time, but at that time -we only know the PHY package mode and not the individual PHY interface -modes as of_get_phy_mode() that populates it will only get called once the -netdev to which PHY-s are attached to is being probed and thus this check -will always fail and return -EINVAL. - -So, lets move this check to .config_init_once as at that point individual -PHY interface modes should be populated. - -Fixes: d1cb613efbd3 ("net: phy: qcom: add support for QCA807x PHY Family") -Signed-off-by: Robert Marko -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240212115043.1725918-1-robimarko@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/qcom/qca807x.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/qcom/qca807x.c -+++ b/drivers/net/phy/qcom/qca807x.c -@@ -562,6 +562,11 @@ static int qca807x_phy_package_config_in - struct qca807x_shared_priv *priv = shared->priv; - int val, ret; - -+ /* Make sure PHY follow PHY package mode if enforced */ -+ if (priv->package_mode != PHY_INTERFACE_MODE_NA && -+ phydev->interface != priv->package_mode) -+ return -EINVAL; -+ - phy_lock_mdio_bus(phydev); - - /* Set correct PHY package mode */ -@@ -718,11 +723,6 @@ static int qca807x_probe(struct phy_devi - shared = phydev->shared; - shared_priv = shared->priv; - -- /* Make sure PHY follow PHY package mode if enforced */ -- if (shared_priv->package_mode != PHY_INTERFACE_MODE_NA && -- phydev->interface != shared_priv->package_mode) -- return -EINVAL; -- - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; diff --git a/target/linux/generic/backport-6.1/718-v6.9-net-phy-qcom-at803x-fix-kernel-panic-with-at8031_pro.patch b/target/linux/generic/backport-6.1/718-v6.9-net-phy-qcom-at803x-fix-kernel-panic-with-at8031_pro.patch deleted file mode 100644 index 9b9ce2a3cd01eb..00000000000000 --- a/target/linux/generic/backport-6.1/718-v6.9-net-phy-qcom-at803x-fix-kernel-panic-with-at8031_pro.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 6a4aee277740d04ac0fd54cfa17cc28261932ddc Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 25 Mar 2024 20:06:19 +0100 -Subject: [PATCH] net: phy: qcom: at803x: fix kernel panic with at8031_probe - -On reworking and splitting the at803x driver, in splitting function of -at803x PHYs it was added a NULL dereference bug where priv is referenced -before it's actually allocated and then is tried to write to for the -is_1000basex and is_fiber variables in the case of at8031, writing on -the wrong address. - -Fix this by correctly setting priv local variable only after -at803x_probe is called and actually allocates priv in the phydev struct. - -Reported-by: William Wortel -Cc: -Fixes: 25d2ba94005f ("net: phy: at803x: move specific at8031 probe mode check to dedicated probe") -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240325190621.2665-1-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/qcom/at803x.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/qcom/at803x.c -+++ b/drivers/net/phy/qcom/at803x.c -@@ -797,7 +797,7 @@ static int at8031_parse_dt(struct phy_de - - static int at8031_probe(struct phy_device *phydev) - { -- struct at803x_priv *priv = phydev->priv; -+ struct at803x_priv *priv; - int mode_cfg; - int ccr; - int ret; -@@ -806,6 +806,8 @@ static int at8031_probe(struct phy_devic - if (ret) - return ret; - -+ priv = phydev->priv; -+ - /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping - * options. - */ diff --git a/target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch b/target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch deleted file mode 100644 index e6a240dbdae9ea..00000000000000 --- a/target/linux/generic/backport-6.1/720-v6.9-net-mdio-ipq4019-add-support-for-clock-frequency-pro.patch +++ /dev/null @@ -1,205 +0,0 @@ -From bdce82e960d1205d118662f575cec39379984e34 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 31 Jan 2024 03:26:04 +0100 -Subject: [PATCH] net: mdio: ipq4019: add support for clock-frequency property - -The IPQ4019 MDIO internally divide the clock feed by AHB based on the -MDIO_MODE reg. On reset or power up, the default value for the -divider is 0xff that reflect the divider set to /256. - -This makes the MDC run at a very low rate, that is, considering AHB is -always fixed to 100Mhz, a value of 390KHz. - -This hasn't have been a problem as MDIO wasn't used for time sensitive -operation, it is now that on IPQ807x is usually mounted with PHY that -requires MDIO to load their firmware (example Aquantia PHY). - -To handle this problem and permit to set the correct designed MDC -frequency for the SoC add support for the standard "clock-frequency" -property for the MDIO node. - -The divider supports value from /1 to /256 and the common value are to -set it to /16 to reflect 6.25Mhz or to /8 on newer platform to reflect -12.5Mhz. - -To scan if the requested rate is supported by the divider, loop with -each supported divider and stop when the requested rate match the final -rate with the current divider. An error is returned if the rate doesn't -match any value. - -On MDIO reset, the divider is restored to the requested value to prevent -any kind of downclocking caused by the divider reverting to a default -value. - -To follow 802.3 spec of 2.5MHz of default value, if divider is set at -/256 and "clock-frequency" is not set in DT, assume nobody set the -divider and try to find the closest MDC rate to 2.5MHz. (in the case of -AHB set to 100MHz, it's 1.5625MHz) - -While at is also document other bits of the MDIO_MODE reg to have a -clear idea of what is actually applied there. - -Documentation of some BITs is skipped as they are marked as reserved and -their usage is not clear (RES 11:9 GENPHY 16:13 RES1 19:17) - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/mdio/mdio-ipq4019.c | 109 ++++++++++++++++++++++++++++++-- - 1 file changed, 103 insertions(+), 6 deletions(-) - ---- a/drivers/net/mdio/mdio-ipq4019.c -+++ b/drivers/net/mdio/mdio-ipq4019.c -@@ -14,6 +14,20 @@ - #include - - #define MDIO_MODE_REG 0x40 -+#define MDIO_MODE_MDC_MODE BIT(12) -+/* 0 = Clause 22, 1 = Clause 45 */ -+#define MDIO_MODE_C45 BIT(8) -+#define MDIO_MODE_DIV_MASK GENMASK(7, 0) -+#define MDIO_MODE_DIV(x) FIELD_PREP(MDIO_MODE_DIV_MASK, (x) - 1) -+#define MDIO_MODE_DIV_1 0x0 -+#define MDIO_MODE_DIV_2 0x1 -+#define MDIO_MODE_DIV_4 0x3 -+#define MDIO_MODE_DIV_8 0x7 -+#define MDIO_MODE_DIV_16 0xf -+#define MDIO_MODE_DIV_32 0x1f -+#define MDIO_MODE_DIV_64 0x3f -+#define MDIO_MODE_DIV_128 0x7f -+#define MDIO_MODE_DIV_256 0xff - #define MDIO_ADDR_REG 0x44 - #define MDIO_DATA_WRITE_REG 0x48 - #define MDIO_DATA_READ_REG 0x4c -@@ -26,9 +40,6 @@ - #define MDIO_CMD_ACCESS_CODE_C45_WRITE 1 - #define MDIO_CMD_ACCESS_CODE_C45_READ 2 - --/* 0 = Clause 22, 1 = Clause 45 */ --#define MDIO_MODE_C45 BIT(8) -- - #define IPQ4019_MDIO_TIMEOUT 10000 - #define IPQ4019_MDIO_SLEEP 10 - -@@ -41,6 +52,7 @@ struct ipq4019_mdio_data { - void __iomem *membase; - void __iomem *eth_ldo_rdy; - struct clk *mdio_clk; -+ unsigned int mdc_rate; - }; - - static int ipq4019_mdio_wait_busy(struct mii_bus *bus) -@@ -179,6 +191,38 @@ static int ipq4019_mdio_write(struct mii - return 0; - } - -+static int ipq4019_mdio_set_div(struct ipq4019_mdio_data *priv) -+{ -+ unsigned long ahb_rate; -+ int div; -+ u32 val; -+ -+ /* If we don't have a clock for AHB use the fixed value */ -+ ahb_rate = IPQ_MDIO_CLK_RATE; -+ if (priv->mdio_clk) -+ ahb_rate = clk_get_rate(priv->mdio_clk); -+ -+ /* MDC rate is ahb_rate/(MDIO_MODE_DIV + 1) -+ * While supported, internal documentation doesn't -+ * assure correct functionality of the MDIO bus -+ * with divider of 1, 2 or 4. -+ */ -+ for (div = 8; div <= 256; div *= 2) { -+ /* The requested rate is supported by the div */ -+ if (priv->mdc_rate == DIV_ROUND_UP(ahb_rate, div)) { -+ val = readl(priv->membase + MDIO_MODE_REG); -+ val &= ~MDIO_MODE_DIV_MASK; -+ val |= MDIO_MODE_DIV(div); -+ writel(val, priv->membase + MDIO_MODE_REG); -+ -+ return 0; -+ } -+ } -+ -+ /* The requested rate is not supported */ -+ return -EINVAL; -+} -+ - static int ipq_mdio_reset(struct mii_bus *bus) - { - struct ipq4019_mdio_data *priv = bus->priv; -@@ -201,10 +245,58 @@ static int ipq_mdio_reset(struct mii_bus - return ret; - - ret = clk_prepare_enable(priv->mdio_clk); -- if (ret == 0) -- mdelay(10); -+ if (ret) -+ return ret; -+ -+ mdelay(10); - -- return ret; -+ /* Restore MDC rate */ -+ return ipq4019_mdio_set_div(priv); -+} -+ -+static void ipq4019_mdio_select_mdc_rate(struct platform_device *pdev, -+ struct ipq4019_mdio_data *priv) -+{ -+ unsigned long ahb_rate; -+ int div; -+ u32 val; -+ -+ /* MDC rate defined in DT, we don't have to decide a default value */ -+ if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency", -+ &priv->mdc_rate)) -+ return; -+ -+ /* If we don't have a clock for AHB use the fixed value */ -+ ahb_rate = IPQ_MDIO_CLK_RATE; -+ if (priv->mdio_clk) -+ ahb_rate = clk_get_rate(priv->mdio_clk); -+ -+ /* Check what is the current div set */ -+ val = readl(priv->membase + MDIO_MODE_REG); -+ div = FIELD_GET(MDIO_MODE_DIV_MASK, val); -+ -+ /* div is not set to the default value of /256 -+ * Probably someone changed that (bootloader, other drivers) -+ * Keep this and don't overwrite it. -+ */ -+ if (div != MDIO_MODE_DIV_256) { -+ priv->mdc_rate = DIV_ROUND_UP(ahb_rate, div + 1); -+ return; -+ } -+ -+ /* If div is /256 assume nobody have set this value and -+ * try to find one MDC rate that is close the 802.3 spec of -+ * 2.5MHz -+ */ -+ for (div = 256; div >= 8; div /= 2) { -+ /* Stop as soon as we found a divider that -+ * reached the closest value to 2.5MHz -+ */ -+ if (DIV_ROUND_UP(ahb_rate, div) > 2500000) -+ break; -+ -+ priv->mdc_rate = DIV_ROUND_UP(ahb_rate, div); -+ } - } - - static int ipq4019_mdio_probe(struct platform_device *pdev) -@@ -228,6 +320,11 @@ static int ipq4019_mdio_probe(struct pla - if (IS_ERR(priv->mdio_clk)) - return PTR_ERR(priv->mdio_clk); - -+ ipq4019_mdio_select_mdc_rate(pdev, priv); -+ ret = ipq4019_mdio_set_div(priv); -+ if (ret) -+ return ret; -+ - /* The platform resource is provided on the chipset IPQ5018 */ - /* This resource is optional */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); diff --git a/target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch b/target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch deleted file mode 100644 index d32a7edf93cdcb..00000000000000 --- a/target/linux/generic/backport-6.1/721-v6.7-net-phy-aquantia-drop-wrong-endianness-conversion-fo.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 7edce370d87a23e8ed46af5b76a9fef1e341b67b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 28 Nov 2023 14:59:28 +0100 -Subject: [PATCH] net: phy: aquantia: drop wrong endianness conversion for addr - and CRC - -On further testing on BE target with kernel test robot, it was notice -that the endianness conversion for addr and CRC in fw_load_memory was -wrong. - -Drop the cpu_to_le32 conversion for addr load as it's not needed. - -Use get_unaligned_le32 instead of get_unaligned for FW data word load to -correctly convert data in the correct order to follow system endian. - -Also drop the cpu_to_be32 for CRC calculation as it's wrong and would -cause different CRC on BE system. -The loaded word is swapped internally and MAILBOX calculates the CRC on -the swapped word. To correctly calculate the CRC to be later matched -with the one from MAILBOX, use an u8 struct and swap the word there to -keep the same order on both LE and BE for crc_ccitt_false function. -Also add additional comments on how the CRC verification for the loaded -section works. - -CRC is calculated as we load the section and verified with the MAILBOX -only after the entire section is loaded to skip additional slowdown by -loop the section data again. - -Reported-by: kernel test robot -Closes: https://lore.kernel.org/oe-kbuild-all/202311210414.sEJZjlcD-lkp@intel.com/ -Fixes: e93984ebc1c8 ("net: phy: aquantia: add firmware load support") -Tested-by: Robert Marko # ipq8072 LE device -Signed-off-by: Christian Marangi -Link: https://lore.kernel.org/r/20231128135928.9841-1-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/aquantia/aquantia_firmware.c | 24 ++++++++++++-------- - 1 file changed, 14 insertions(+), 10 deletions(-) - ---- a/drivers/net/phy/aquantia/aquantia_firmware.c -+++ b/drivers/net/phy/aquantia/aquantia_firmware.c -@@ -93,9 +93,6 @@ static int aqr_fw_load_memory(struct phy - u16 crc = 0, up_crc; - size_t pos; - -- /* PHY expect addr in LE */ -- addr = (__force u32)cpu_to_le32(addr); -- - phy_write_mmd(phydev, MDIO_MMD_VEND1, - VEND1_GLOBAL_MAILBOX_INTERFACE1, - VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET); -@@ -110,10 +107,11 @@ static int aqr_fw_load_memory(struct phy - * If a firmware that is not word aligned is found, please report upstream. - */ - for (pos = 0; pos < len; pos += sizeof(u32)) { -+ u8 crc_data[4]; - u32 word; - - /* FW data is always stored in little-endian */ -- word = get_unaligned((const u32 *)(data + pos)); -+ word = get_unaligned_le32((const u32 *)(data + pos)); - - phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE5, - VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(word)); -@@ -124,15 +122,21 @@ static int aqr_fw_load_memory(struct phy - VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE | - VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE); - -- /* calculate CRC as we load data to the mailbox. -- * We convert word to big-endian as PHY is BE and mailbox will -- * return a BE CRC. -+ /* Word is swapped internally and MAILBOX CRC is calculated -+ * using big-endian order. Mimic what the PHY does to have a -+ * matching CRC... - */ -- word = (__force u32)cpu_to_be32(word); -- crc = crc_ccitt_false(crc, (u8 *)&word, sizeof(word)); -- } -+ crc_data[0] = word >> 24; -+ crc_data[1] = word >> 16; -+ crc_data[2] = word >> 8; -+ crc_data[3] = word; - -+ /* ...calculate CRC as we load data... */ -+ crc = crc_ccitt_false(crc, crc_data, sizeof(crc_data)); -+ } -+ /* ...gets CRC from MAILBOX after we have loaded the entire section... */ - up_crc = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE2); -+ /* ...and make sure it does match our calculated CRC */ - if (crc != up_crc) { - phydev_err(phydev, "CRC mismatch: calculated 0x%04x PHY 0x%04x\n", - crc, up_crc); diff --git a/target/linux/generic/backport-6.1/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch b/target/linux/generic/backport-6.1/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch deleted file mode 100644 index cf0d2a3a8920a5..00000000000000 --- a/target/linux/generic/backport-6.1/724-v6.2-net-ethernet-mtk_eth_soc-enable-flow-offloading-supp.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 1b9827ceab08450308f7971d6fd700ec88b6ce67 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 3 Dec 2022 14:20:37 +0100 -Subject: [PATCH 098/250] net: mtk_eth_soc: enable flow offload support for - MT7986 SoC - -Since Wireless Ethernet Dispatcher is now available for mt7986 in mt76, -enable hw flow support for MT7986 SoC. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/fdcaacd827938e6a8c4aa1ac2c13e46d2c08c821.1670072898.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4332,6 +4332,7 @@ static const struct mtk_soc_data mt7986_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7986_CLKS_BITMAP, - .required_pctl = false, -+ .offload_version = 2, - .hash_offset = 4, - .foe_entry_size = sizeof(struct mtk_foe_entry), - .txrx = { diff --git a/target/linux/generic/backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch b/target/linux/generic/backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch deleted file mode 100644 index c48613929d1272..00000000000000 --- a/target/linux/generic/backport-6.1/729-01-v6.1-net-ethernet-mtk_wed-introduce-wed-mcu-support.patch +++ /dev/null @@ -1,591 +0,0 @@ -From: Sujuan Chen -Date: Sat, 5 Nov 2022 23:36:18 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: introduce wed mcu support - -Introduce WED mcu support used to configure WED WO chip. -This is a preliminary patch in order to add RX Wireless -Ethernet Dispatch available on MT7986 SoC. - -Tested-by: Daniel Golle -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: David S. Miller ---- - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_mcu.c - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.h - ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -5,7 +5,7 @@ - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o - mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o --mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o -+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o - ifdef CONFIG_DEBUG_FS - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o - endif ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -0,0 +1,359 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* Copyright (C) 2022 MediaTek Inc. -+ * -+ * Author: Lorenzo Bianconi -+ * Sujuan Chen -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtk_wed_regs.h" -+#include "mtk_wed_wo.h" -+#include "mtk_wed.h" -+ -+static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg) -+{ -+ return readl(wo->boot.addr + reg); -+} -+ -+static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val) -+{ -+ writel(val, wo->boot.addr + reg); -+} -+ -+static struct sk_buff * -+mtk_wed_mcu_msg_alloc(const void *data, int data_len) -+{ -+ int length = sizeof(struct mtk_wed_mcu_hdr) + data_len; -+ struct sk_buff *skb; -+ -+ skb = alloc_skb(length, GFP_KERNEL); -+ if (!skb) -+ return NULL; -+ -+ memset(skb->head, 0, length); -+ skb_reserve(skb, sizeof(struct mtk_wed_mcu_hdr)); -+ if (data && data_len) -+ skb_put_data(skb, data, data_len); -+ -+ return skb; -+} -+ -+static struct sk_buff * -+mtk_wed_mcu_get_response(struct mtk_wed_wo *wo, unsigned long expires) -+{ -+ if (!time_is_after_jiffies(expires)) -+ return NULL; -+ -+ wait_event_timeout(wo->mcu.wait, !skb_queue_empty(&wo->mcu.res_q), -+ expires - jiffies); -+ return skb_dequeue(&wo->mcu.res_q); -+} -+ -+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb) -+{ -+ skb_queue_tail(&wo->mcu.res_q, skb); -+ wake_up(&wo->mcu.wait); -+} -+ -+void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, -+ struct sk_buff *skb) -+{ -+ struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data; -+ -+ switch (hdr->cmd) { -+ case MTK_WED_WO_EVT_LOG_DUMP: { -+ const char *msg = (const char *)(skb->data + sizeof(*hdr)); -+ -+ dev_notice(wo->hw->dev, "%s\n", msg); -+ break; -+ } -+ case MTK_WED_WO_EVT_PROFILING: { -+ struct mtk_wed_wo_log_info *info; -+ u32 count = (skb->len - sizeof(*hdr)) / sizeof(*info); -+ int i; -+ -+ info = (struct mtk_wed_wo_log_info *)(skb->data + sizeof(*hdr)); -+ for (i = 0 ; i < count ; i++) -+ dev_notice(wo->hw->dev, -+ "SN:%u latency: total=%u, rro:%u, mod:%u\n", -+ le32_to_cpu(info[i].sn), -+ le32_to_cpu(info[i].total), -+ le32_to_cpu(info[i].rro), -+ le32_to_cpu(info[i].mod)); -+ break; -+ } -+ case MTK_WED_WO_EVT_RXCNT_INFO: -+ break; -+ default: -+ break; -+ } -+ -+ dev_kfree_skb(skb); -+} -+ -+static int -+mtk_wed_mcu_skb_send_msg(struct mtk_wed_wo *wo, struct sk_buff *skb, -+ int id, int cmd, u16 *wait_seq, bool wait_resp) -+{ -+ struct mtk_wed_mcu_hdr *hdr; -+ -+ /* TODO: make it dynamic based on cmd */ -+ wo->mcu.timeout = 20 * HZ; -+ -+ hdr = (struct mtk_wed_mcu_hdr *)skb_push(skb, sizeof(*hdr)); -+ hdr->cmd = cmd; -+ hdr->length = cpu_to_le16(skb->len); -+ -+ if (wait_resp && wait_seq) { -+ u16 seq = ++wo->mcu.seq; -+ -+ if (!seq) -+ seq = ++wo->mcu.seq; -+ *wait_seq = seq; -+ -+ hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_NEED_RSP); -+ hdr->seq = cpu_to_le16(seq); -+ } -+ if (id == MTK_WED_MODULE_ID_WO) -+ hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_FROM_TO_WO); -+ -+ dev_kfree_skb(skb); -+ return 0; -+} -+ -+static int -+mtk_wed_mcu_parse_response(struct mtk_wed_wo *wo, struct sk_buff *skb, -+ int cmd, int seq) -+{ -+ struct mtk_wed_mcu_hdr *hdr; -+ -+ if (!skb) { -+ dev_err(wo->hw->dev, "Message %08x (seq %d) timeout\n", -+ cmd, seq); -+ return -ETIMEDOUT; -+ } -+ -+ hdr = (struct mtk_wed_mcu_hdr *)skb->data; -+ if (le16_to_cpu(hdr->seq) != seq) -+ return -EAGAIN; -+ -+ skb_pull(skb, sizeof(*hdr)); -+ switch (cmd) { -+ case MTK_WED_WO_CMD_RXCNT_INFO: -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, -+ const void *data, int len, bool wait_resp) -+{ -+ unsigned long expires; -+ struct sk_buff *skb; -+ u16 seq; -+ int ret; -+ -+ skb = mtk_wed_mcu_msg_alloc(data, len); -+ if (!skb) -+ return -ENOMEM; -+ -+ mutex_lock(&wo->mcu.mutex); -+ -+ ret = mtk_wed_mcu_skb_send_msg(wo, skb, id, cmd, &seq, wait_resp); -+ if (ret || !wait_resp) -+ goto unlock; -+ -+ expires = jiffies + wo->mcu.timeout; -+ do { -+ skb = mtk_wed_mcu_get_response(wo, expires); -+ ret = mtk_wed_mcu_parse_response(wo, skb, cmd, seq); -+ dev_kfree_skb(skb); -+ } while (ret == -EAGAIN); -+ -+unlock: -+ mutex_unlock(&wo->mcu.mutex); -+ -+ return ret; -+} -+ -+static int -+mtk_wed_get_memory_region(struct mtk_wed_wo *wo, -+ struct mtk_wed_wo_memory_region *region) -+{ -+ struct reserved_mem *rmem; -+ struct device_node *np; -+ int index; -+ -+ index = of_property_match_string(wo->hw->node, "memory-region-names", -+ region->name); -+ if (index < 0) -+ return index; -+ -+ np = of_parse_phandle(wo->hw->node, "memory-region", index); -+ if (!np) -+ return -ENODEV; -+ -+ rmem = of_reserved_mem_lookup(np); -+ of_node_put(np); -+ -+ if (!rmem) -+ return -ENODEV; -+ -+ region->phy_addr = rmem->base; -+ region->size = rmem->size; -+ region->addr = devm_ioremap(wo->hw->dev, region->phy_addr, region->size); -+ -+ return !region->addr ? -EINVAL : 0; -+} -+ -+static int -+mtk_wed_mcu_run_firmware(struct mtk_wed_wo *wo, const struct firmware *fw, -+ struct mtk_wed_wo_memory_region *region) -+{ -+ const u8 *first_region_ptr, *region_ptr, *trailer_ptr, *ptr = fw->data; -+ const struct mtk_wed_fw_trailer *trailer; -+ const struct mtk_wed_fw_region *fw_region; -+ -+ trailer_ptr = fw->data + fw->size - sizeof(*trailer); -+ trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr; -+ region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region); -+ first_region_ptr = region_ptr; -+ -+ while (region_ptr < trailer_ptr) { -+ u32 length; -+ -+ fw_region = (const struct mtk_wed_fw_region *)region_ptr; -+ length = le32_to_cpu(fw_region->len); -+ -+ if (region->phy_addr != le32_to_cpu(fw_region->addr)) -+ goto next; -+ -+ if (region->size < length) -+ goto next; -+ -+ if (first_region_ptr < ptr + length) -+ goto next; -+ -+ if (region->shared && region->consumed) -+ return 0; -+ -+ if (!region->shared || !region->consumed) { -+ memcpy_toio(region->addr, ptr, length); -+ region->consumed = true; -+ return 0; -+ } -+next: -+ region_ptr += sizeof(*fw_region); -+ ptr += length; -+ } -+ -+ return -EINVAL; -+} -+ -+static int -+mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) -+{ -+ static struct mtk_wed_wo_memory_region mem_region[] = { -+ [MTK_WED_WO_REGION_EMI] = { -+ .name = "wo-emi", -+ }, -+ [MTK_WED_WO_REGION_ILM] = { -+ .name = "wo-ilm", -+ }, -+ [MTK_WED_WO_REGION_DATA] = { -+ .name = "wo-data", -+ .shared = true, -+ }, -+ }; -+ const struct mtk_wed_fw_trailer *trailer; -+ const struct firmware *fw; -+ const char *fw_name; -+ u32 val, boot_cr; -+ int ret, i; -+ -+ /* load firmware region metadata */ -+ for (i = 0; i < ARRAY_SIZE(mem_region); i++) { -+ ret = mtk_wed_get_memory_region(wo, &mem_region[i]); -+ if (ret) -+ return ret; -+ } -+ -+ wo->boot.name = "wo-boot"; -+ ret = mtk_wed_get_memory_region(wo, &wo->boot); -+ if (ret) -+ return ret; -+ -+ /* set dummy cr */ -+ wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL, -+ wo->hw->index + 1); -+ -+ /* load firmware */ -+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; -+ ret = request_firmware(&fw, fw_name, wo->hw->dev); -+ if (ret) -+ return ret; -+ -+ trailer = (void *)(fw->data + fw->size - -+ sizeof(struct mtk_wed_fw_trailer)); -+ dev_info(wo->hw->dev, -+ "MTK WED WO Firmware Version: %.10s, Build Time: %.15s\n", -+ trailer->fw_ver, trailer->build_date); -+ dev_info(wo->hw->dev, "MTK WED WO Chip ID %02x Region %d\n", -+ trailer->chip_id, trailer->num_region); -+ -+ for (i = 0; i < ARRAY_SIZE(mem_region); i++) { -+ ret = mtk_wed_mcu_run_firmware(wo, fw, &mem_region[i]); -+ if (ret) -+ goto out; -+ } -+ -+ /* set the start address */ -+ boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR -+ : MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR; -+ wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16); -+ /* wo firmware reset */ -+ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00); -+ -+ val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR); -+ val |= wo->hw->index ? MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK -+ : MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK; -+ wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val); -+out: -+ release_firmware(fw); -+ -+ return ret; -+} -+ -+static u32 -+mtk_wed_mcu_read_fw_dl(struct mtk_wed_wo *wo) -+{ -+ return wed_r32(wo->hw->wed_dev, -+ MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL); -+} -+ -+int mtk_wed_mcu_init(struct mtk_wed_wo *wo) -+{ -+ u32 val; -+ int ret; -+ -+ skb_queue_head_init(&wo->mcu.res_q); -+ init_waitqueue_head(&wo->mcu.wait); -+ mutex_init(&wo->mcu.mutex); -+ -+ ret = mtk_wed_mcu_load_firmware(wo); -+ if (ret) -+ return ret; -+ -+ return readx_poll_timeout(mtk_wed_mcu_read_fw_dl, wo, val, !val, -+ 100, MTK_FW_DL_TIMEOUT); -+} -+ -+MODULE_FIRMWARE(MT7986_FIRMWARE_WO0); -+MODULE_FIRMWARE(MT7986_FIRMWARE_WO1); ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -152,6 +152,7 @@ struct mtk_wdma_desc { - - #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10) - -+#define MTK_WED_SCR0 0x3c0 - #define MTK_WED_WPDMA_INT_TRIGGER 0x504 - #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1) - #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4) ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -0,0 +1,150 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* Copyright (C) 2022 Lorenzo Bianconi */ -+ -+#ifndef __MTK_WED_WO_H -+#define __MTK_WED_WO_H -+ -+#include -+#include -+ -+struct mtk_wed_hw; -+ -+struct mtk_wed_mcu_hdr { -+ /* DW0 */ -+ u8 version; -+ u8 cmd; -+ __le16 length; -+ -+ /* DW1 */ -+ __le16 seq; -+ __le16 flag; -+ -+ /* DW2 */ -+ __le32 status; -+ -+ /* DW3 */ -+ u8 rsv[20]; -+}; -+ -+struct mtk_wed_wo_log_info { -+ __le32 sn; -+ __le32 total; -+ __le32 rro; -+ __le32 mod; -+}; -+ -+enum mtk_wed_wo_event { -+ MTK_WED_WO_EVT_LOG_DUMP = 0x1, -+ MTK_WED_WO_EVT_PROFILING = 0x2, -+ MTK_WED_WO_EVT_RXCNT_INFO = 0x3, -+}; -+ -+#define MTK_WED_MODULE_ID_WO 1 -+#define MTK_FW_DL_TIMEOUT 4000000 /* us */ -+#define MTK_WOCPU_TIMEOUT 2000000 /* us */ -+ -+enum { -+ MTK_WED_WARP_CMD_FLAG_RSP = BIT(0), -+ MTK_WED_WARP_CMD_FLAG_NEED_RSP = BIT(1), -+ MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2), -+}; -+ -+enum { -+ MTK_WED_WO_REGION_EMI, -+ MTK_WED_WO_REGION_ILM, -+ MTK_WED_WO_REGION_DATA, -+ MTK_WED_WO_REGION_BOOT, -+ __MTK_WED_WO_REGION_MAX, -+}; -+ -+enum mtk_wed_dummy_cr_idx { -+ MTK_WED_DUMMY_CR_FWDL, -+ MTK_WED_DUMMY_CR_WO_STATUS, -+}; -+ -+#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" -+#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" -+ -+#define MTK_WO_MCU_CFG_LS_BASE 0 -+#define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000) -+#define MTK_WO_MCU_CFG_LS_FW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x004) -+#define MTK_WO_MCU_CFG_LS_CFG_DBG1_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x00c) -+#define MTK_WO_MCU_CFG_LS_CFG_DBG2_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x010) -+#define MTK_WO_MCU_CFG_LS_WF_MCCR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x014) -+#define MTK_WO_MCU_CFG_LS_WF_MCCR_SET_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x018) -+#define MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x01c) -+#define MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x050) -+#define MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x060) -+#define MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x064) -+ -+#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5) -+#define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0) -+ -+struct mtk_wed_wo_memory_region { -+ const char *name; -+ void __iomem *addr; -+ phys_addr_t phy_addr; -+ u32 size; -+ bool shared:1; -+ bool consumed:1; -+}; -+ -+struct mtk_wed_fw_region { -+ __le32 decomp_crc; -+ __le32 decomp_len; -+ __le32 decomp_blk_sz; -+ u8 rsv0[4]; -+ __le32 addr; -+ __le32 len; -+ u8 feature_set; -+ u8 rsv1[15]; -+} __packed; -+ -+struct mtk_wed_fw_trailer { -+ u8 chip_id; -+ u8 eco_code; -+ u8 num_region; -+ u8 format_ver; -+ u8 format_flag; -+ u8 rsv[2]; -+ char fw_ver[10]; -+ char build_date[15]; -+ u32 crc; -+}; -+ -+struct mtk_wed_wo { -+ struct mtk_wed_hw *hw; -+ struct mtk_wed_wo_memory_region boot; -+ -+ struct { -+ struct mutex mutex; -+ int timeout; -+ u16 seq; -+ -+ struct sk_buff_head res_q; -+ wait_queue_head_t wait; -+ } mcu; -+}; -+ -+static inline int -+mtk_wed_mcu_check_msg(struct mtk_wed_wo *wo, struct sk_buff *skb) -+{ -+ struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data; -+ -+ if (hdr->version) -+ return -EINVAL; -+ -+ if (skb->len < sizeof(*hdr) || skb->len != le16_to_cpu(hdr->length)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+void mtk_wed_mcu_rx_event(struct mtk_wed_wo *wo, struct sk_buff *skb); -+void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, -+ struct sk_buff *skb); -+int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, -+ const void *data, int len, bool wait_resp); -+int mtk_wed_mcu_init(struct mtk_wed_wo *wo); -+ -+#endif /* __MTK_WED_WO_H */ ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -11,6 +11,35 @@ - struct mtk_wed_hw; - struct mtk_wdma_desc; - -+enum mtk_wed_wo_cmd { -+ MTK_WED_WO_CMD_WED_CFG, -+ MTK_WED_WO_CMD_WED_RX_STAT, -+ MTK_WED_WO_CMD_RRO_SER, -+ MTK_WED_WO_CMD_DBG_INFO, -+ MTK_WED_WO_CMD_DEV_INFO, -+ MTK_WED_WO_CMD_BSS_INFO, -+ MTK_WED_WO_CMD_STA_REC, -+ MTK_WED_WO_CMD_DEV_INFO_DUMP, -+ MTK_WED_WO_CMD_BSS_INFO_DUMP, -+ MTK_WED_WO_CMD_STA_REC_DUMP, -+ MTK_WED_WO_CMD_BA_INFO_DUMP, -+ MTK_WED_WO_CMD_FBCMD_Q_DUMP, -+ MTK_WED_WO_CMD_FW_LOG_CTRL, -+ MTK_WED_WO_CMD_LOG_FLUSH, -+ MTK_WED_WO_CMD_CHANGE_STATE, -+ MTK_WED_WO_CMD_CPU_STATS_ENABLE, -+ MTK_WED_WO_CMD_CPU_STATS_DUMP, -+ MTK_WED_WO_CMD_EXCEPTION_INIT, -+ MTK_WED_WO_CMD_PROF_CTRL, -+ MTK_WED_WO_CMD_STA_BA_DUMP, -+ MTK_WED_WO_CMD_BA_CTRL_DUMP, -+ MTK_WED_WO_CMD_RXCNT_CTRL, -+ MTK_WED_WO_CMD_RXCNT_INFO, -+ MTK_WED_WO_CMD_SET_CAP, -+ MTK_WED_WO_CMD_CCIF_RING_DUMP, -+ MTK_WED_WO_CMD_WED_END -+}; -+ - enum mtk_wed_bus_tye { - MTK_WED_BUS_PCIE, - MTK_WED_BUS_AXI, diff --git a/target/linux/generic/backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch b/target/linux/generic/backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch deleted file mode 100644 index fd5f45df2aaa27..00000000000000 --- a/target/linux/generic/backport-6.1/729-02-v6.1-net-ethernet-mtk_wed-introduce-wed-wo-support.patch +++ /dev/null @@ -1,737 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 5 Nov 2022 23:36:19 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: introduce wed wo support - -Introduce WO chip support to mtk wed driver. MTK WED WO is used to -implement RX Wireless Ethernet Dispatch and offload traffic received by -wlan nic to the wired interface. - -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - create mode 100644 drivers/net/ethernet/mediatek/mtk_wed_wo.c - ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -5,7 +5,7 @@ - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o - mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o --mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o -+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o - ifdef CONFIG_DEBUG_FS - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o - endif ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -16,6 +16,7 @@ - #include "mtk_wed_regs.h" - #include "mtk_wed.h" - #include "mtk_ppe.h" -+#include "mtk_wed_wo.h" - - #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000) - -@@ -355,6 +356,8 @@ mtk_wed_detach(struct mtk_wed_device *de - - mtk_wed_free_buffer(dev); - mtk_wed_free_tx_rings(dev); -+ if (hw->version != 1) -+ mtk_wed_wo_deinit(hw); - - if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { - struct device_node *wlan_node; -@@ -878,9 +881,11 @@ mtk_wed_attach(struct mtk_wed_device *de - } - - mtk_wed_hw_init_early(dev); -- if (hw->hifsys) -+ if (hw->version == 1) - regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, - BIT(hw->index), 0); -+ else -+ ret = mtk_wed_wo_init(hw); - - out: - mutex_unlock(&hw_lock); ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -10,6 +10,7 @@ - #include - - struct mtk_eth; -+struct mtk_wed_wo; - - struct mtk_wed_hw { - struct device_node *node; -@@ -22,6 +23,7 @@ struct mtk_wed_hw { - struct regmap *mirror; - struct dentry *debugfs_dir; - struct mtk_wed_device *wed_dev; -+ struct mtk_wed_wo *wed_wo; - u32 debugfs_reg; - u32 num_flows; - u8 version; ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -122,8 +122,7 @@ mtk_wed_mcu_skb_send_msg(struct mtk_wed_ - if (id == MTK_WED_MODULE_ID_WO) - hdr->flag |= cpu_to_le16(MTK_WED_WARP_CMD_FLAG_FROM_TO_WO); - -- dev_kfree_skb(skb); -- return 0; -+ return mtk_wed_wo_queue_tx_skb(wo, &wo->q_tx, skb); - } - - static int ---- /dev/null -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c -@@ -0,0 +1,508 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* Copyright (C) 2022 MediaTek Inc. -+ * -+ * Author: Lorenzo Bianconi -+ * Sujuan Chen -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mtk_wed.h" -+#include "mtk_wed_regs.h" -+#include "mtk_wed_wo.h" -+ -+static u32 -+mtk_wed_mmio_r32(struct mtk_wed_wo *wo, u32 reg) -+{ -+ u32 val; -+ -+ if (regmap_read(wo->mmio.regs, reg, &val)) -+ val = ~0; -+ -+ return val; -+} -+ -+static void -+mtk_wed_mmio_w32(struct mtk_wed_wo *wo, u32 reg, u32 val) -+{ -+ regmap_write(wo->mmio.regs, reg, val); -+} -+ -+static u32 -+mtk_wed_wo_get_isr(struct mtk_wed_wo *wo) -+{ -+ u32 val = mtk_wed_mmio_r32(wo, MTK_WED_WO_CCIF_RCHNUM); -+ -+ return val & MTK_WED_WO_CCIF_RCHNUM_MASK; -+} -+ -+static void -+mtk_wed_wo_set_isr(struct mtk_wed_wo *wo, u32 mask) -+{ -+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_IRQ0_MASK, mask); -+} -+ -+static void -+mtk_wed_wo_set_ack(struct mtk_wed_wo *wo, u32 mask) -+{ -+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_ACK, mask); -+} -+ -+static void -+mtk_wed_wo_set_isr_mask(struct mtk_wed_wo *wo, u32 mask, u32 val, bool set) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&wo->mmio.lock, flags); -+ wo->mmio.irq_mask &= ~mask; -+ wo->mmio.irq_mask |= val; -+ if (set) -+ mtk_wed_wo_set_isr(wo, wo->mmio.irq_mask); -+ spin_unlock_irqrestore(&wo->mmio.lock, flags); -+} -+ -+static void -+mtk_wed_wo_irq_enable(struct mtk_wed_wo *wo, u32 mask) -+{ -+ mtk_wed_wo_set_isr_mask(wo, 0, mask, false); -+ tasklet_schedule(&wo->mmio.irq_tasklet); -+} -+ -+static void -+mtk_wed_wo_irq_disable(struct mtk_wed_wo *wo, u32 mask) -+{ -+ mtk_wed_wo_set_isr_mask(wo, mask, 0, true); -+} -+ -+static void -+mtk_wed_wo_kickout(struct mtk_wed_wo *wo) -+{ -+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_BUSY, 1 << MTK_WED_WO_TXCH_NUM); -+ mtk_wed_mmio_w32(wo, MTK_WED_WO_CCIF_TCHNUM, MTK_WED_WO_TXCH_NUM); -+} -+ -+static void -+mtk_wed_wo_queue_kick(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, -+ u32 val) -+{ -+ wmb(); -+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, val); -+} -+ -+static void * -+mtk_wed_wo_dequeue(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, u32 *len, -+ bool flush) -+{ -+ int buf_len = SKB_WITH_OVERHEAD(q->buf_size); -+ int index = (q->tail + 1) % q->n_desc; -+ struct mtk_wed_wo_queue_entry *entry; -+ struct mtk_wed_wo_queue_desc *desc; -+ void *buf; -+ -+ if (!q->queued) -+ return NULL; -+ -+ if (flush) -+ q->desc[index].ctrl |= cpu_to_le32(MTK_WED_WO_CTL_DMA_DONE); -+ else if (!(q->desc[index].ctrl & cpu_to_le32(MTK_WED_WO_CTL_DMA_DONE))) -+ return NULL; -+ -+ q->tail = index; -+ q->queued--; -+ -+ desc = &q->desc[index]; -+ entry = &q->entry[index]; -+ buf = entry->buf; -+ if (len) -+ *len = FIELD_GET(MTK_WED_WO_CTL_SD_LEN0, -+ le32_to_cpu(READ_ONCE(desc->ctrl))); -+ if (buf) -+ dma_unmap_single(wo->hw->dev, entry->addr, buf_len, -+ DMA_FROM_DEVICE); -+ entry->buf = NULL; -+ -+ return buf; -+} -+ -+static int -+mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, -+ gfp_t gfp, bool rx) -+{ -+ enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE; -+ int n_buf = 0; -+ -+ spin_lock_bh(&q->lock); -+ while (q->queued < q->n_desc) { -+ void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp); -+ struct mtk_wed_wo_queue_entry *entry; -+ dma_addr_t addr; -+ -+ if (!buf) -+ break; -+ -+ addr = dma_map_single(wo->hw->dev, buf, q->buf_size, dir); -+ if (unlikely(dma_mapping_error(wo->hw->dev, addr))) { -+ skb_free_frag(buf); -+ break; -+ } -+ -+ q->head = (q->head + 1) % q->n_desc; -+ entry = &q->entry[q->head]; -+ entry->addr = addr; -+ entry->len = q->buf_size; -+ q->entry[q->head].buf = buf; -+ -+ if (rx) { -+ struct mtk_wed_wo_queue_desc *desc = &q->desc[q->head]; -+ u32 ctrl = MTK_WED_WO_CTL_LAST_SEC0 | -+ FIELD_PREP(MTK_WED_WO_CTL_SD_LEN0, -+ entry->len); -+ -+ WRITE_ONCE(desc->buf0, cpu_to_le32(addr)); -+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); -+ } -+ q->queued++; -+ n_buf++; -+ } -+ spin_unlock_bh(&q->lock); -+ -+ return n_buf; -+} -+ -+static void -+mtk_wed_wo_rx_complete(struct mtk_wed_wo *wo) -+{ -+ mtk_wed_wo_set_ack(wo, MTK_WED_WO_RXCH_INT_MASK); -+ mtk_wed_wo_irq_enable(wo, MTK_WED_WO_RXCH_INT_MASK); -+} -+ -+static void -+mtk_wed_wo_rx_run_queue(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) -+{ -+ for (;;) { -+ struct mtk_wed_mcu_hdr *hdr; -+ struct sk_buff *skb; -+ void *data; -+ u32 len; -+ -+ data = mtk_wed_wo_dequeue(wo, q, &len, false); -+ if (!data) -+ break; -+ -+ skb = build_skb(data, q->buf_size); -+ if (!skb) { -+ skb_free_frag(data); -+ continue; -+ } -+ -+ __skb_put(skb, len); -+ if (mtk_wed_mcu_check_msg(wo, skb)) { -+ dev_kfree_skb(skb); -+ continue; -+ } -+ -+ hdr = (struct mtk_wed_mcu_hdr *)skb->data; -+ if (hdr->flag & cpu_to_le16(MTK_WED_WARP_CMD_FLAG_RSP)) -+ mtk_wed_mcu_rx_event(wo, skb); -+ else -+ mtk_wed_mcu_rx_unsolicited_event(wo, skb); -+ } -+ -+ if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) { -+ u32 index = (q->head - 1) % q->n_desc; -+ -+ mtk_wed_wo_queue_kick(wo, q, index); -+ } -+} -+ -+static irqreturn_t -+mtk_wed_wo_irq_handler(int irq, void *data) -+{ -+ struct mtk_wed_wo *wo = data; -+ -+ mtk_wed_wo_set_isr(wo, 0); -+ tasklet_schedule(&wo->mmio.irq_tasklet); -+ -+ return IRQ_HANDLED; -+} -+ -+static void mtk_wed_wo_irq_tasklet(struct tasklet_struct *t) -+{ -+ struct mtk_wed_wo *wo = from_tasklet(wo, t, mmio.irq_tasklet); -+ u32 intr, mask; -+ -+ /* disable interrupts */ -+ mtk_wed_wo_set_isr(wo, 0); -+ -+ intr = mtk_wed_wo_get_isr(wo); -+ intr &= wo->mmio.irq_mask; -+ mask = intr & (MTK_WED_WO_RXCH_INT_MASK | MTK_WED_WO_EXCEPTION_INT_MASK); -+ mtk_wed_wo_irq_disable(wo, mask); -+ -+ if (intr & MTK_WED_WO_RXCH_INT_MASK) { -+ mtk_wed_wo_rx_run_queue(wo, &wo->q_rx); -+ mtk_wed_wo_rx_complete(wo); -+ } -+} -+ -+/* mtk wed wo hw queues */ -+ -+static int -+mtk_wed_wo_queue_alloc(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, -+ int n_desc, int buf_size, int index, -+ struct mtk_wed_wo_queue_regs *regs) -+{ -+ spin_lock_init(&q->lock); -+ q->regs = *regs; -+ q->n_desc = n_desc; -+ q->buf_size = buf_size; -+ -+ q->desc = dmam_alloc_coherent(wo->hw->dev, n_desc * sizeof(*q->desc), -+ &q->desc_dma, GFP_KERNEL); -+ if (!q->desc) -+ return -ENOMEM; -+ -+ q->entry = devm_kzalloc(wo->hw->dev, n_desc * sizeof(*q->entry), -+ GFP_KERNEL); -+ if (!q->entry) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+static void -+mtk_wed_wo_queue_free(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) -+{ -+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, 0); -+ dma_free_coherent(wo->hw->dev, q->n_desc * sizeof(*q->desc), q->desc, -+ q->desc_dma); -+} -+ -+static void -+mtk_wed_wo_queue_tx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) -+{ -+ struct page *page; -+ int i; -+ -+ spin_lock_bh(&q->lock); -+ for (i = 0; i < q->n_desc; i++) { -+ struct mtk_wed_wo_queue_entry *entry = &q->entry[i]; -+ -+ dma_unmap_single(wo->hw->dev, entry->addr, entry->len, -+ DMA_TO_DEVICE); -+ skb_free_frag(entry->buf); -+ entry->buf = NULL; -+ } -+ spin_unlock_bh(&q->lock); -+ -+ if (!q->cache.va) -+ return; -+ -+ page = virt_to_page(q->cache.va); -+ __page_frag_cache_drain(page, q->cache.pagecnt_bias); -+ memset(&q->cache, 0, sizeof(q->cache)); -+} -+ -+static void -+mtk_wed_wo_queue_rx_clean(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) -+{ -+ struct page *page; -+ -+ spin_lock_bh(&q->lock); -+ for (;;) { -+ void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true); -+ -+ if (!buf) -+ break; -+ -+ skb_free_frag(buf); -+ } -+ spin_unlock_bh(&q->lock); -+ -+ if (!q->cache.va) -+ return; -+ -+ page = virt_to_page(q->cache.va); -+ __page_frag_cache_drain(page, q->cache.pagecnt_bias); -+ memset(&q->cache, 0, sizeof(q->cache)); -+} -+ -+static void -+mtk_wed_wo_queue_reset(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q) -+{ -+ mtk_wed_mmio_w32(wo, q->regs.cpu_idx, 0); -+ mtk_wed_mmio_w32(wo, q->regs.desc_base, q->desc_dma); -+ mtk_wed_mmio_w32(wo, q->regs.ring_size, q->n_desc); -+} -+ -+int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, -+ struct sk_buff *skb) -+{ -+ struct mtk_wed_wo_queue_entry *entry; -+ struct mtk_wed_wo_queue_desc *desc; -+ int ret = 0, index; -+ u32 ctrl; -+ -+ spin_lock_bh(&q->lock); -+ -+ q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx); -+ index = (q->head + 1) % q->n_desc; -+ if (q->tail == index) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ entry = &q->entry[index]; -+ if (skb->len > entry->len) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ desc = &q->desc[index]; -+ q->head = index; -+ -+ dma_sync_single_for_cpu(wo->hw->dev, entry->addr, skb->len, -+ DMA_TO_DEVICE); -+ memcpy(entry->buf, skb->data, skb->len); -+ dma_sync_single_for_device(wo->hw->dev, entry->addr, skb->len, -+ DMA_TO_DEVICE); -+ -+ ctrl = FIELD_PREP(MTK_WED_WO_CTL_SD_LEN0, skb->len) | -+ MTK_WED_WO_CTL_LAST_SEC0 | MTK_WED_WO_CTL_DMA_DONE; -+ WRITE_ONCE(desc->buf0, cpu_to_le32(entry->addr)); -+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); -+ -+ mtk_wed_wo_queue_kick(wo, q, q->head); -+ mtk_wed_wo_kickout(wo); -+out: -+ spin_unlock_bh(&q->lock); -+ -+ dev_kfree_skb(skb); -+ -+ return ret; -+} -+ -+static int -+mtk_wed_wo_exception_init(struct mtk_wed_wo *wo) -+{ -+ return 0; -+} -+ -+static int -+mtk_wed_wo_hardware_init(struct mtk_wed_wo *wo) -+{ -+ struct mtk_wed_wo_queue_regs regs; -+ struct device_node *np; -+ int ret; -+ -+ np = of_parse_phandle(wo->hw->node, "mediatek,wo-ccif", 0); -+ if (!np) -+ return -ENODEV; -+ -+ wo->mmio.regs = syscon_regmap_lookup_by_phandle(np, NULL); -+ if (IS_ERR_OR_NULL(wo->mmio.regs)) -+ return PTR_ERR(wo->mmio.regs); -+ -+ wo->mmio.irq = irq_of_parse_and_map(np, 0); -+ wo->mmio.irq_mask = MTK_WED_WO_ALL_INT_MASK; -+ spin_lock_init(&wo->mmio.lock); -+ tasklet_setup(&wo->mmio.irq_tasklet, mtk_wed_wo_irq_tasklet); -+ -+ ret = devm_request_irq(wo->hw->dev, wo->mmio.irq, -+ mtk_wed_wo_irq_handler, IRQF_TRIGGER_HIGH, -+ KBUILD_MODNAME, wo); -+ if (ret) -+ goto error; -+ -+ regs.desc_base = MTK_WED_WO_CCIF_DUMMY1; -+ regs.ring_size = MTK_WED_WO_CCIF_DUMMY2; -+ regs.dma_idx = MTK_WED_WO_CCIF_SHADOW4; -+ regs.cpu_idx = MTK_WED_WO_CCIF_DUMMY3; -+ -+ ret = mtk_wed_wo_queue_alloc(wo, &wo->q_tx, MTK_WED_WO_RING_SIZE, -+ MTK_WED_WO_CMD_LEN, MTK_WED_WO_TXCH_NUM, -+ ®s); -+ if (ret) -+ goto error; -+ -+ mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false); -+ mtk_wed_wo_queue_reset(wo, &wo->q_tx); -+ -+ regs.desc_base = MTK_WED_WO_CCIF_DUMMY5; -+ regs.ring_size = MTK_WED_WO_CCIF_DUMMY6; -+ regs.dma_idx = MTK_WED_WO_CCIF_SHADOW8; -+ regs.cpu_idx = MTK_WED_WO_CCIF_DUMMY7; -+ -+ ret = mtk_wed_wo_queue_alloc(wo, &wo->q_rx, MTK_WED_WO_RING_SIZE, -+ MTK_WED_WO_CMD_LEN, MTK_WED_WO_RXCH_NUM, -+ ®s); -+ if (ret) -+ goto error; -+ -+ mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true); -+ mtk_wed_wo_queue_reset(wo, &wo->q_rx); -+ -+ /* rx queue irqmask */ -+ mtk_wed_wo_set_isr(wo, wo->mmio.irq_mask); -+ -+ return 0; -+ -+error: -+ devm_free_irq(wo->hw->dev, wo->mmio.irq, wo); -+ -+ return ret; -+} -+ -+static void -+mtk_wed_wo_hw_deinit(struct mtk_wed_wo *wo) -+{ -+ /* disable interrupts */ -+ mtk_wed_wo_set_isr(wo, 0); -+ -+ tasklet_disable(&wo->mmio.irq_tasklet); -+ -+ disable_irq(wo->mmio.irq); -+ devm_free_irq(wo->hw->dev, wo->mmio.irq, wo); -+ -+ mtk_wed_wo_queue_tx_clean(wo, &wo->q_tx); -+ mtk_wed_wo_queue_rx_clean(wo, &wo->q_rx); -+ mtk_wed_wo_queue_free(wo, &wo->q_tx); -+ mtk_wed_wo_queue_free(wo, &wo->q_rx); -+} -+ -+int mtk_wed_wo_init(struct mtk_wed_hw *hw) -+{ -+ struct mtk_wed_wo *wo; -+ int ret; -+ -+ wo = devm_kzalloc(hw->dev, sizeof(*wo), GFP_KERNEL); -+ if (!wo) -+ return -ENOMEM; -+ -+ hw->wed_wo = wo; -+ wo->hw = hw; -+ -+ ret = mtk_wed_wo_hardware_init(wo); -+ if (ret) -+ return ret; -+ -+ ret = mtk_wed_mcu_init(wo); -+ if (ret) -+ return ret; -+ -+ return mtk_wed_wo_exception_init(wo); -+} -+ -+void mtk_wed_wo_deinit(struct mtk_wed_hw *hw) -+{ -+ struct mtk_wed_wo *wo = hw->wed_wo; -+ -+ mtk_wed_wo_hw_deinit(wo); -+} ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -80,6 +80,54 @@ enum mtk_wed_dummy_cr_idx { - #define MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK BIT(5) - #define MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK BIT(0) - -+#define MTK_WED_WO_RING_SIZE 256 -+#define MTK_WED_WO_CMD_LEN 1504 -+ -+#define MTK_WED_WO_TXCH_NUM 0 -+#define MTK_WED_WO_RXCH_NUM 1 -+#define MTK_WED_WO_RXCH_WO_EXCEPTION 7 -+ -+#define MTK_WED_WO_TXCH_INT_MASK BIT(0) -+#define MTK_WED_WO_RXCH_INT_MASK BIT(1) -+#define MTK_WED_WO_EXCEPTION_INT_MASK BIT(7) -+#define MTK_WED_WO_ALL_INT_MASK (MTK_WED_WO_RXCH_INT_MASK | \ -+ MTK_WED_WO_EXCEPTION_INT_MASK) -+ -+#define MTK_WED_WO_CCIF_BUSY 0x004 -+#define MTK_WED_WO_CCIF_START 0x008 -+#define MTK_WED_WO_CCIF_TCHNUM 0x00c -+#define MTK_WED_WO_CCIF_RCHNUM 0x010 -+#define MTK_WED_WO_CCIF_RCHNUM_MASK GENMASK(7, 0) -+ -+#define MTK_WED_WO_CCIF_ACK 0x014 -+#define MTK_WED_WO_CCIF_IRQ0_MASK 0x018 -+#define MTK_WED_WO_CCIF_IRQ1_MASK 0x01c -+#define MTK_WED_WO_CCIF_DUMMY1 0x020 -+#define MTK_WED_WO_CCIF_DUMMY2 0x024 -+#define MTK_WED_WO_CCIF_DUMMY3 0x028 -+#define MTK_WED_WO_CCIF_DUMMY4 0x02c -+#define MTK_WED_WO_CCIF_SHADOW1 0x030 -+#define MTK_WED_WO_CCIF_SHADOW2 0x034 -+#define MTK_WED_WO_CCIF_SHADOW3 0x038 -+#define MTK_WED_WO_CCIF_SHADOW4 0x03c -+#define MTK_WED_WO_CCIF_DUMMY5 0x050 -+#define MTK_WED_WO_CCIF_DUMMY6 0x054 -+#define MTK_WED_WO_CCIF_DUMMY7 0x058 -+#define MTK_WED_WO_CCIF_DUMMY8 0x05c -+#define MTK_WED_WO_CCIF_SHADOW5 0x060 -+#define MTK_WED_WO_CCIF_SHADOW6 0x064 -+#define MTK_WED_WO_CCIF_SHADOW7 0x068 -+#define MTK_WED_WO_CCIF_SHADOW8 0x06c -+ -+#define MTK_WED_WO_CTL_SD_LEN1 GENMASK(13, 0) -+#define MTK_WED_WO_CTL_LAST_SEC1 BIT(14) -+#define MTK_WED_WO_CTL_BURST BIT(15) -+#define MTK_WED_WO_CTL_SD_LEN0_SHIFT 16 -+#define MTK_WED_WO_CTL_SD_LEN0 GENMASK(29, 16) -+#define MTK_WED_WO_CTL_LAST_SEC0 BIT(30) -+#define MTK_WED_WO_CTL_DMA_DONE BIT(31) -+#define MTK_WED_WO_INFO_WINFO GENMASK(15, 0) -+ - struct mtk_wed_wo_memory_region { - const char *name; - void __iomem *addr; -@@ -112,10 +160,53 @@ struct mtk_wed_fw_trailer { - u32 crc; - }; - -+struct mtk_wed_wo_queue_regs { -+ u32 desc_base; -+ u32 ring_size; -+ u32 cpu_idx; -+ u32 dma_idx; -+}; -+ -+struct mtk_wed_wo_queue_desc { -+ __le32 buf0; -+ __le32 ctrl; -+ __le32 buf1; -+ __le32 info; -+ __le32 reserved[4]; -+} __packed __aligned(32); -+ -+struct mtk_wed_wo_queue_entry { -+ dma_addr_t addr; -+ void *buf; -+ u32 len; -+}; -+ -+struct mtk_wed_wo_queue { -+ struct mtk_wed_wo_queue_regs regs; -+ -+ struct page_frag_cache cache; -+ spinlock_t lock; -+ -+ struct mtk_wed_wo_queue_desc *desc; -+ dma_addr_t desc_dma; -+ -+ struct mtk_wed_wo_queue_entry *entry; -+ -+ u16 head; -+ u16 tail; -+ int n_desc; -+ int queued; -+ int buf_size; -+ -+}; -+ - struct mtk_wed_wo { - struct mtk_wed_hw *hw; - struct mtk_wed_wo_memory_region boot; - -+ struct mtk_wed_wo_queue q_tx; -+ struct mtk_wed_wo_queue q_rx; -+ - struct { - struct mutex mutex; - int timeout; -@@ -124,6 +215,15 @@ struct mtk_wed_wo { - struct sk_buff_head res_q; - wait_queue_head_t wait; - } mcu; -+ -+ struct { -+ struct regmap *regs; -+ -+ spinlock_t lock; -+ struct tasklet_struct irq_tasklet; -+ int irq; -+ u32 irq_mask; -+ } mmio; - }; - - static inline int -@@ -146,5 +246,9 @@ void mtk_wed_mcu_rx_unsolicited_event(st - int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, - const void *data, int len, bool wait_resp); - int mtk_wed_mcu_init(struct mtk_wed_wo *wo); -+int mtk_wed_wo_init(struct mtk_wed_hw *hw); -+void mtk_wed_wo_deinit(struct mtk_wed_hw *hw); -+int mtk_wed_wo_queue_tx_skb(struct mtk_wed_wo *dev, struct mtk_wed_wo_queue *q, -+ struct sk_buff *skb); - - #endif /* __MTK_WED_WO_H */ diff --git a/target/linux/generic/backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch b/target/linux/generic/backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch deleted file mode 100644 index a002a5f85163d4..00000000000000 --- a/target/linux/generic/backport-6.1/729-03-v6.1-net-ethernet-mtk_wed-rename-tx_wdma-array-in-rx_wdma.patch +++ /dev/null @@ -1,79 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 5 Nov 2022 23:36:20 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: rename tx_wdma array in rx_wdma - -Rename tx_wdma queue array in rx_wdma since this is rx side of wdma soc. -Moreover rename mtk_wed_wdma_ring_setup routine in -mtk_wed_wdma_rx_ring_setup() - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -253,8 +253,8 @@ mtk_wed_free_tx_rings(struct mtk_wed_dev - - for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) - mtk_wed_free_ring(dev, &dev->tx_ring[i]); -- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -- mtk_wed_free_ring(dev, &dev->tx_wdma[i]); -+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) -+ mtk_wed_free_ring(dev, &dev->rx_wdma[i]); - } - - static void -@@ -688,10 +688,10 @@ mtk_wed_ring_alloc(struct mtk_wed_device - } - - static int --mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size) -+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size) - { - u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; -- struct mtk_wed_ring *wdma = &dev->tx_wdma[idx]; -+ struct mtk_wed_ring *wdma = &dev->rx_wdma[idx]; - - if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size)) - return -ENOMEM; -@@ -805,9 +805,9 @@ mtk_wed_start(struct mtk_wed_device *dev - { - int i; - -- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) -- if (!dev->tx_wdma[i].desc) -- mtk_wed_wdma_ring_setup(dev, i, 16); -+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) -+ if (!dev->rx_wdma[i].desc) -+ mtk_wed_wdma_rx_ring_setup(dev, i, 16); - - mtk_wed_hw_init(dev); - mtk_wed_configure_irq(dev, irq_mask); -@@ -916,7 +916,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - sizeof(*ring->desc))) - return -ENOMEM; - -- if (mtk_wed_wdma_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) - return -ENOMEM; - - ring->reg_base = MTK_WED_RING_TX(idx); ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -7,6 +7,7 @@ - #include - - #define MTK_WED_TX_QUEUES 2 -+#define MTK_WED_RX_QUEUES 2 - - struct mtk_wed_hw; - struct mtk_wdma_desc; -@@ -66,7 +67,7 @@ struct mtk_wed_device { - - struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; - struct mtk_wed_ring txfree_ring; -- struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; -+ struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES]; - - struct { - int size; diff --git a/target/linux/generic/backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch b/target/linux/generic/backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch deleted file mode 100644 index eca29739b4ae38..00000000000000 --- a/target/linux/generic/backport-6.1/729-04-v6.1-net-ethernet-mtk_wed-add-configure-wed-wo-support.patch +++ /dev/null @@ -1,1521 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 5 Nov 2022 23:36:21 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add configure wed wo support - -Enable RX Wireless Ethernet Dispatch available on MT7986 Soc. - -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -23,6 +24,7 @@ - #define MTK_WED_PKT_SIZE 1900 - #define MTK_WED_BUF_SIZE 2048 - #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048) -+#define MTK_WED_RX_RING_SIZE 1536 - - #define MTK_WED_TX_RING_SIZE 2048 - #define MTK_WED_WDMA_RING_SIZE 1024 -@@ -31,6 +33,10 @@ - #define MTK_WED_PER_GROUP_PKT 128 - - #define MTK_WED_FBUF_SIZE 128 -+#define MTK_WED_MIOD_CNT 16 -+#define MTK_WED_FB_CMD_CNT 1024 -+#define MTK_WED_RRO_QUE_CNT 8192 -+#define MTK_WED_MIOD_ENTRY_CNT 128 - - static struct mtk_wed_hw *hw_list[2]; - static DEFINE_MUTEX(hw_lock); -@@ -65,12 +71,76 @@ wdma_set(struct mtk_wed_device *dev, u32 - wdma_m32(dev, reg, 0, mask); - } - -+static void -+wdma_clr(struct mtk_wed_device *dev, u32 reg, u32 mask) -+{ -+ wdma_m32(dev, reg, mask, 0); -+} -+ -+static u32 -+wifi_r32(struct mtk_wed_device *dev, u32 reg) -+{ -+ return readl(dev->wlan.base + reg); -+} -+ -+static void -+wifi_w32(struct mtk_wed_device *dev, u32 reg, u32 val) -+{ -+ writel(val, dev->wlan.base + reg); -+} -+ - static u32 - mtk_wed_read_reset(struct mtk_wed_device *dev) - { - return wed_r32(dev, MTK_WED_RESET); - } - -+static u32 -+mtk_wdma_read_reset(struct mtk_wed_device *dev) -+{ -+ return wdma_r32(dev, MTK_WDMA_GLO_CFG); -+} -+ -+static void -+mtk_wdma_rx_reset(struct mtk_wed_device *dev) -+{ -+ u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY; -+ int i; -+ -+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN); -+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, -+ !(status & mask), 0, 1000)) -+ dev_err(dev->hw->dev, "rx reset failed\n"); -+ -+ for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) { -+ if (dev->rx_wdma[i].desc) -+ continue; -+ -+ wdma_w32(dev, -+ MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); -+ } -+} -+ -+static void -+mtk_wdma_tx_reset(struct mtk_wed_device *dev) -+{ -+ u32 status, mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY; -+ int i; -+ -+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); -+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, -+ !(status & mask), 0, 1000)) -+ dev_err(dev->hw->dev, "tx reset failed\n"); -+ -+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) { -+ if (dev->tx_wdma[i].desc) -+ continue; -+ -+ wdma_w32(dev, -+ MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); -+ } -+} -+ - static void - mtk_wed_reset(struct mtk_wed_device *dev, u32 mask) - { -@@ -82,6 +152,54 @@ mtk_wed_reset(struct mtk_wed_device *dev - WARN_ON_ONCE(1); - } - -+static u32 -+mtk_wed_wo_read_status(struct mtk_wed_device *dev) -+{ -+ return wed_r32(dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_WO_STATUS); -+} -+ -+static void -+mtk_wed_wo_reset(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_wo *wo = dev->hw->wed_wo; -+ u8 state = MTK_WED_WO_STATE_DISABLE; -+ void __iomem *reg; -+ u32 val; -+ -+ mtk_wdma_tx_reset(dev); -+ mtk_wed_reset(dev, MTK_WED_RESET_WED); -+ -+ mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -+ MTK_WED_WO_CMD_CHANGE_STATE, &state, -+ sizeof(state), false); -+ -+ if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val, -+ val == MTK_WED_WOIF_DISABLE_DONE, -+ 100, MTK_WOCPU_TIMEOUT)) -+ dev_err(dev->hw->dev, "failed to disable wed-wo\n"); -+ -+ reg = ioremap(MTK_WED_WO_CPU_MCUSYS_RESET_ADDR, 4); -+ -+ val = readl(reg); -+ switch (dev->hw->index) { -+ case 0: -+ val |= MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK; -+ writel(val, reg); -+ val &= ~MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK; -+ writel(val, reg); -+ break; -+ case 1: -+ val |= MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK; -+ writel(val, reg); -+ val &= ~MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK; -+ writel(val, reg); -+ break; -+ default: -+ break; -+ } -+ iounmap(reg); -+} -+ - static struct mtk_wed_hw * - mtk_wed_assign(struct mtk_wed_device *dev) - { -@@ -116,7 +234,7 @@ out: - } - - static int --mtk_wed_buffer_alloc(struct mtk_wed_device *dev) -+mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) - { - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -@@ -133,16 +251,16 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi - if (!page_list) - return -ENOMEM; - -- dev->buf_ring.size = ring_size; -- dev->buf_ring.pages = page_list; -+ dev->tx_buf_ring.size = ring_size; -+ dev->tx_buf_ring.pages = page_list; - - desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc), - &desc_phys, GFP_KERNEL); - if (!desc) - return -ENOMEM; - -- dev->buf_ring.desc = desc; -- dev->buf_ring.desc_phys = desc_phys; -+ dev->tx_buf_ring.desc = desc; -+ dev->tx_buf_ring.desc_phys = desc_phys; - - for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) { - dma_addr_t page_phys, buf_phys; -@@ -203,10 +321,10 @@ mtk_wed_buffer_alloc(struct mtk_wed_devi - } - - static void --mtk_wed_free_buffer(struct mtk_wed_device *dev) -+mtk_wed_free_tx_buffer(struct mtk_wed_device *dev) - { -- struct mtk_wdma_desc *desc = dev->buf_ring.desc; -- void **page_list = dev->buf_ring.pages; -+ struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc; -+ void **page_list = dev->tx_buf_ring.pages; - int page_idx; - int i; - -@@ -216,7 +334,8 @@ mtk_wed_free_buffer(struct mtk_wed_devic - if (!desc) - goto free_pagelist; - -- for (i = 0, page_idx = 0; i < dev->buf_ring.size; i += MTK_WED_BUF_PER_PAGE) { -+ for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size; -+ i += MTK_WED_BUF_PER_PAGE) { - void *page = page_list[page_idx++]; - dma_addr_t buf_addr; - -@@ -229,13 +348,59 @@ mtk_wed_free_buffer(struct mtk_wed_devic - __free_page(page); - } - -- dma_free_coherent(dev->hw->dev, dev->buf_ring.size * sizeof(*desc), -- desc, dev->buf_ring.desc_phys); -+ dma_free_coherent(dev->hw->dev, dev->tx_buf_ring.size * sizeof(*desc), -+ desc, dev->tx_buf_ring.desc_phys); - - free_pagelist: - kfree(page_list); - } - -+static int -+mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev) -+{ -+ struct mtk_rxbm_desc *desc; -+ dma_addr_t desc_phys; -+ -+ dev->rx_buf_ring.size = dev->wlan.rx_nbuf; -+ desc = dma_alloc_coherent(dev->hw->dev, -+ dev->wlan.rx_nbuf * sizeof(*desc), -+ &desc_phys, GFP_KERNEL); -+ if (!desc) -+ return -ENOMEM; -+ -+ dev->rx_buf_ring.desc = desc; -+ dev->rx_buf_ring.desc_phys = desc_phys; -+ dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt); -+ -+ return 0; -+} -+ -+static void -+mtk_wed_free_rx_buffer(struct mtk_wed_device *dev) -+{ -+ struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc; -+ -+ if (!desc) -+ return; -+ -+ dev->wlan.release_rx_buf(dev); -+ dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc), -+ desc, dev->rx_buf_ring.desc_phys); -+} -+ -+static void -+mtk_wed_rx_buffer_hw_init(struct mtk_wed_device *dev) -+{ -+ wed_w32(dev, MTK_WED_RX_BM_RX_DMAD, -+ FIELD_PREP(MTK_WED_RX_BM_RX_DMAD_SDL0, dev->wlan.rx_size)); -+ wed_w32(dev, MTK_WED_RX_BM_BASE, dev->rx_buf_ring.desc_phys); -+ wed_w32(dev, MTK_WED_RX_BM_INIT_PTR, MTK_WED_RX_BM_INIT_SW_TAIL | -+ FIELD_PREP(MTK_WED_RX_BM_SW_TAIL, dev->wlan.rx_npkt)); -+ wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH, -+ FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff)); -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); -+} -+ - static void - mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring) - { -@@ -247,6 +412,13 @@ mtk_wed_free_ring(struct mtk_wed_device - } - - static void -+mtk_wed_free_rx_rings(struct mtk_wed_device *dev) -+{ -+ mtk_wed_free_rx_buffer(dev); -+ mtk_wed_free_ring(dev, &dev->rro.ring); -+} -+ -+static void - mtk_wed_free_tx_rings(struct mtk_wed_device *dev) - { - int i; -@@ -291,6 +463,38 @@ mtk_wed_set_512_support(struct mtk_wed_d - } - } - -+#define MTK_WFMDA_RX_DMA_EN BIT(2) -+static void -+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx) -+{ -+ u32 val; -+ int i; -+ -+ if (!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED)) -+ return; /* queue is not configured by mt76 */ -+ -+ for (i = 0; i < 3; i++) { -+ u32 cur_idx; -+ -+ cur_idx = wed_r32(dev, -+ MTK_WED_WPDMA_RING_RX_DATA(idx) + -+ MTK_WED_RING_OFS_CPU_IDX); -+ if (cur_idx == MTK_WED_RX_RING_SIZE - 1) -+ break; -+ -+ usleep_range(100000, 200000); -+ } -+ -+ if (i == 3) { -+ dev_err(dev->hw->dev, "rx dma enable failed\n"); -+ return; -+ } -+ -+ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) | -+ MTK_WFMDA_RX_DMA_EN; -+ wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val); -+} -+ - static void - mtk_wed_dma_disable(struct mtk_wed_device *dev) - { -@@ -304,20 +508,25 @@ mtk_wed_dma_disable(struct mtk_wed_devic - MTK_WED_GLO_CFG_TX_DMA_EN | - MTK_WED_GLO_CFG_RX_DMA_EN); - -- wdma_m32(dev, MTK_WDMA_GLO_CFG, -+ wdma_clr(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_TX_DMA_EN | - MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES, 0); -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); - - if (dev->hw->version == 1) { - regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); -- wdma_m32(dev, MTK_WDMA_GLO_CFG, -- MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0); -+ wdma_clr(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); - } else { - wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); - -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RX_DRV_EN); -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); -+ - mtk_wed_set_512_support(dev, false); - } - } -@@ -338,6 +547,13 @@ mtk_wed_stop(struct mtk_wed_device *dev) - wdma_w32(dev, MTK_WDMA_INT_MASK, 0); - wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); -+ -+ if (dev->hw->version == 1) -+ return; -+ -+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); -+ wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0); -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); - } - - static void -@@ -353,11 +569,21 @@ mtk_wed_detach(struct mtk_wed_device *de - wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); - - mtk_wed_reset(dev, MTK_WED_RESET_WED); -+ if (mtk_wed_get_rx_capa(dev)) { -+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -+ } - -- mtk_wed_free_buffer(dev); -+ mtk_wed_free_tx_buffer(dev); - mtk_wed_free_tx_rings(dev); -- if (hw->version != 1) -+ -+ if (mtk_wed_get_rx_capa(dev)) { -+ mtk_wed_wo_reset(dev); -+ mtk_wed_free_rx_rings(dev); - mtk_wed_wo_deinit(hw); -+ mtk_wdma_rx_reset(dev); -+ } - - if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { - struct device_node *wlan_node; -@@ -434,10 +660,12 @@ mtk_wed_set_wpdma(struct mtk_wed_device - } else { - mtk_wed_bus_init(dev); - -- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); -- wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); -- wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); -- wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); -+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); -+ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx); - } - } - -@@ -487,6 +715,132 @@ mtk_wed_hw_init_early(struct mtk_wed_dev - } - } - -+static int -+mtk_wed_rro_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, -+ int size) -+{ -+ ring->desc = dma_alloc_coherent(dev->hw->dev, -+ size * sizeof(*ring->desc), -+ &ring->desc_phys, GFP_KERNEL); -+ if (!ring->desc) -+ return -ENOMEM; -+ -+ ring->desc_size = sizeof(*ring->desc); -+ ring->size = size; -+ memset(ring->desc, 0, size); -+ -+ return 0; -+} -+ -+#define MTK_WED_MIOD_COUNT (MTK_WED_MIOD_ENTRY_CNT * MTK_WED_MIOD_CNT) -+static int -+mtk_wed_rro_alloc(struct mtk_wed_device *dev) -+{ -+ struct reserved_mem *rmem; -+ struct device_node *np; -+ int index; -+ -+ index = of_property_match_string(dev->hw->node, "memory-region-names", -+ "wo-dlm"); -+ if (index < 0) -+ return index; -+ -+ np = of_parse_phandle(dev->hw->node, "memory-region", index); -+ if (!np) -+ return -ENODEV; -+ -+ rmem = of_reserved_mem_lookup(np); -+ of_node_put(np); -+ -+ if (!rmem) -+ return -ENODEV; -+ -+ dev->rro.miod_phys = rmem->base; -+ dev->rro.fdbk_phys = MTK_WED_MIOD_COUNT + dev->rro.miod_phys; -+ -+ return mtk_wed_rro_ring_alloc(dev, &dev->rro.ring, -+ MTK_WED_RRO_QUE_CNT); -+} -+ -+static int -+mtk_wed_rro_cfg(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_wo *wo = dev->hw->wed_wo; -+ struct { -+ struct { -+ __le32 base; -+ __le32 cnt; -+ __le32 unit; -+ } ring[2]; -+ __le32 wed; -+ u8 version; -+ } req = { -+ .ring[0] = { -+ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE), -+ .cnt = cpu_to_le32(MTK_WED_MIOD_CNT), -+ .unit = cpu_to_le32(MTK_WED_MIOD_ENTRY_CNT), -+ }, -+ .ring[1] = { -+ .base = cpu_to_le32(MTK_WED_WOCPU_VIEW_MIOD_BASE + -+ MTK_WED_MIOD_COUNT), -+ .cnt = cpu_to_le32(MTK_WED_FB_CMD_CNT), -+ .unit = cpu_to_le32(4), -+ }, -+ }; -+ -+ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -+ MTK_WED_WO_CMD_WED_CFG, -+ &req, sizeof(req), true); -+} -+ -+static void -+mtk_wed_rro_hw_init(struct mtk_wed_device *dev) -+{ -+ wed_w32(dev, MTK_WED_RROQM_MIOD_CFG, -+ FIELD_PREP(MTK_WED_RROQM_MIOD_MID_DW, 0x70 >> 2) | -+ FIELD_PREP(MTK_WED_RROQM_MIOD_MOD_DW, 0x10 >> 2) | -+ FIELD_PREP(MTK_WED_RROQM_MIOD_ENTRY_DW, -+ MTK_WED_MIOD_ENTRY_CNT >> 2)); -+ -+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL0, dev->rro.miod_phys); -+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL1, -+ FIELD_PREP(MTK_WED_RROQM_MIOD_CNT, MTK_WED_MIOD_CNT)); -+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL0, dev->rro.fdbk_phys); -+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL1, -+ FIELD_PREP(MTK_WED_RROQM_FDBK_CNT, MTK_WED_FB_CMD_CNT)); -+ wed_w32(dev, MTK_WED_RROQM_FDBK_CTRL2, 0); -+ wed_w32(dev, MTK_WED_RROQ_BASE_L, dev->rro.ring.desc_phys); -+ -+ wed_set(dev, MTK_WED_RROQM_RST_IDX, -+ MTK_WED_RROQM_RST_IDX_MIOD | -+ MTK_WED_RROQM_RST_IDX_FDBK); -+ -+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0); -+ wed_w32(dev, MTK_WED_RROQM_MIOD_CTRL2, MTK_WED_MIOD_CNT - 1); -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN); -+} -+ -+static void -+mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev) -+{ -+ wed_w32(dev, MTK_WED_RESET, MTK_WED_RESET_RX_ROUTE_QM); -+ -+ for (;;) { -+ usleep_range(100, 200); -+ if (!(wed_r32(dev, MTK_WED_RESET) & MTK_WED_RESET_RX_ROUTE_QM)) -+ break; -+ } -+ -+ /* configure RX_ROUTE_QM */ -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT); -+ wed_set(dev, MTK_WED_RTQM_GLO_CFG, -+ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index)); -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ /* enable RX_ROUTE_QM */ -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); -+} -+ - static void - mtk_wed_hw_init(struct mtk_wed_device *dev) - { -@@ -498,11 +852,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d - wed_w32(dev, MTK_WED_TX_BM_CTRL, - MTK_WED_TX_BM_CTRL_PAUSE | - FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, -- dev->buf_ring.size / 128) | -+ dev->tx_buf_ring.size / 128) | - FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, - MTK_WED_TX_RING_SIZE / 256)); - -- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys); -+ wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys); - - wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); - -@@ -529,9 +883,9 @@ mtk_wed_hw_init(struct mtk_wed_device *d - wed_w32(dev, MTK_WED_TX_TKID_CTRL, - MTK_WED_TX_TKID_CTRL_PAUSE | - FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM, -- dev->buf_ring.size / 128) | -+ dev->tx_buf_ring.size / 128) | - FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM, -- dev->buf_ring.size / 128)); -+ dev->tx_buf_ring.size / 128)); - wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, - FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | - MTK_WED_TX_TKID_DYN_THR_HI); -@@ -539,18 +893,28 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - -- if (dev->hw->version == 1) -+ if (dev->hw->version == 1) { - wed_set(dev, MTK_WED_CTRL, - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -- else -+ } else { - wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); -+ /* rx hw init */ -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -+ -+ mtk_wed_rx_buffer_hw_init(dev); -+ mtk_wed_rro_hw_init(dev); -+ mtk_wed_route_qm_hw_init(dev); -+ } - - wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); - } - - static void --mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size) -+mtk_wed_ring_reset(struct mtk_wed_ring *ring, int size, bool tx) - { - void *head = (void *)ring->desc; - int i; -@@ -560,7 +924,10 @@ mtk_wed_ring_reset(struct mtk_wed_ring * - - desc = (struct mtk_wdma_desc *)(head + i * ring->desc_size); - desc->buf0 = 0; -- desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ if (tx) -+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ else -+ desc->ctrl = cpu_to_le32(MTK_WFDMA_DESC_CTRL_TO_HOST); - desc->buf1 = 0; - desc->info = 0; - } -@@ -616,7 +983,8 @@ mtk_wed_reset_dma(struct mtk_wed_device - if (!dev->tx_ring[i].desc) - continue; - -- mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE); -+ mtk_wed_ring_reset(&dev->tx_ring[i], MTK_WED_TX_RING_SIZE, -+ true); - } - - if (mtk_wed_poll_busy(dev)) -@@ -634,6 +1002,9 @@ mtk_wed_reset_dma(struct mtk_wed_device - wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); - wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); - -+ if (mtk_wed_get_rx_capa(dev)) -+ mtk_wdma_rx_reset(dev); -+ - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV); -@@ -668,12 +1039,11 @@ mtk_wed_reset_dma(struct mtk_wed_device - MTK_WED_WPDMA_RESET_IDX_RX); - wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0); - } -- - } - - static int - mtk_wed_ring_alloc(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, -- int size, u32 desc_size) -+ int size, u32 desc_size, bool tx) - { - ring->desc = dma_alloc_coherent(dev->hw->dev, size * desc_size, - &ring->desc_phys, GFP_KERNEL); -@@ -682,7 +1052,7 @@ mtk_wed_ring_alloc(struct mtk_wed_device - - ring->desc_size = desc_size; - ring->size = size; -- mtk_wed_ring_reset(ring, size); -+ mtk_wed_ring_reset(ring, size, tx); - - return 0; - } -@@ -691,9 +1061,14 @@ static int - mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size) - { - u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; -- struct mtk_wed_ring *wdma = &dev->rx_wdma[idx]; -+ struct mtk_wed_ring *wdma; - -- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size)) -+ if (idx >= ARRAY_SIZE(dev->rx_wdma)) -+ return -EINVAL; -+ -+ wdma = &dev->rx_wdma[idx]; -+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, -+ true)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -@@ -710,6 +1085,60 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we - return 0; - } - -+static int -+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size) -+{ -+ u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; -+ struct mtk_wed_ring *wdma; -+ -+ if (idx >= ARRAY_SIZE(dev->tx_wdma)) -+ return -EINVAL; -+ -+ wdma = &dev->tx_wdma[idx]; -+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, -+ true)) -+ return -ENOMEM; -+ -+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, -+ wdma->desc_phys); -+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT, -+ size); -+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0); -+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0); -+ -+ if (!idx) { -+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE, -+ wdma->desc_phys); -+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_COUNT, -+ size); -+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_CPU_IDX, -+ 0); -+ wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_DMA_IDX, -+ 0); -+ } -+ -+ return 0; -+} -+ -+static void -+mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb, -+ u32 reason, u32 hash) -+{ -+ struct mtk_eth *eth = dev->hw->eth; -+ struct ethhdr *eh; -+ -+ if (!skb) -+ return; -+ -+ if (reason != MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -+ return; -+ -+ skb_set_mac_header(skb, 0); -+ eh = eth_hdr(skb); -+ skb->protocol = eh->h_proto; -+ mtk_ppe_check_skb(eth->ppe[dev->hw->index], skb, hash); -+} -+ - static void - mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask) - { -@@ -732,6 +1161,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev - - wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); - } else { -+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE, -+ GENMASK(1, 0)); - /* initail tx interrupt trigger */ - wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, - MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | -@@ -750,6 +1181,16 @@ mtk_wed_configure_irq(struct mtk_wed_dev - FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG, - dev->wlan.txfree_tbit)); - -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX, -+ MTK_WED_WPDMA_INT_CTRL_RX0_EN | -+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR | -+ MTK_WED_WPDMA_INT_CTRL_RX1_EN | -+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG, -+ dev->wlan.rx_tbit[0]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG, -+ dev->wlan.rx_tbit[1])); -+ - wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask); - wed_set(dev, MTK_WED_WDMA_INT_CTRL, - FIELD_PREP(MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL, -@@ -787,9 +1228,15 @@ mtk_wed_dma_enable(struct mtk_wed_device - wdma_set(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); - } else { -+ int i; -+ - wed_set(dev, MTK_WED_WPDMA_CTRL, - MTK_WED_WPDMA_CTRL_SDL1_FIXED); - -+ wed_set(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); -+ - wed_set(dev, MTK_WED_WPDMA_GLO_CFG, - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -@@ -797,6 +1244,15 @@ mtk_wed_dma_enable(struct mtk_wed_device - wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, - MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | - MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); -+ -+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RX_DRV_EN | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, -+ 0x2)); -+ -+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) -+ mtk_wed_check_wfdma_rx_fill(dev, i); - } - } - -@@ -822,7 +1278,19 @@ mtk_wed_start(struct mtk_wed_device *dev - val |= BIT(0) | (BIT(1) * !!dev->hw->index); - regmap_write(dev->hw->mirror, dev->hw->index * 4, val); - } else { -- mtk_wed_set_512_support(dev, true); -+ /* driver set mid ready and only once */ -+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, -+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); -+ wed_w32(dev, MTK_WED_EXT_INT_MASK2, -+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); -+ -+ wed_r32(dev, MTK_WED_EXT_INT_MASK1); -+ wed_r32(dev, MTK_WED_EXT_INT_MASK2); -+ -+ if (mtk_wed_rro_cfg(dev)) -+ return; -+ -+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512); - } - - mtk_wed_dma_enable(dev); -@@ -856,7 +1324,7 @@ mtk_wed_attach(struct mtk_wed_device *de - if (!hw) { - module_put(THIS_MODULE); - ret = -ENODEV; -- goto out; -+ goto unlock; - } - - device = dev->wlan.bus_type == MTK_WED_BUS_PCIE -@@ -869,15 +1337,24 @@ mtk_wed_attach(struct mtk_wed_device *de - dev->dev = hw->dev; - dev->irq = hw->irq; - dev->wdma_idx = hw->index; -+ dev->version = hw->version; - - if (hw->eth->dma_dev == hw->eth->dev && - of_dma_is_coherent(hw->eth->dev->of_node)) - mtk_eth_set_dma_device(hw->eth, hw->dev); - -- ret = mtk_wed_buffer_alloc(dev); -- if (ret) { -- mtk_wed_detach(dev); -+ ret = mtk_wed_tx_buffer_alloc(dev); -+ if (ret) - goto out; -+ -+ if (mtk_wed_get_rx_capa(dev)) { -+ ret = mtk_wed_rx_buffer_alloc(dev); -+ if (ret) -+ goto out; -+ -+ ret = mtk_wed_rro_alloc(dev); -+ if (ret) -+ goto out; - } - - mtk_wed_hw_init_early(dev); -@@ -886,8 +1363,10 @@ mtk_wed_attach(struct mtk_wed_device *de - BIT(hw->index), 0); - else - ret = mtk_wed_wo_init(hw); -- - out: -+ if (ret) -+ mtk_wed_detach(dev); -+unlock: - mutex_unlock(&hw_lock); - - return ret; -@@ -910,10 +1389,11 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - * WDMA RX. - */ - -- BUG_ON(idx >= ARRAY_SIZE(dev->tx_ring)); -+ if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring))) -+ return -EINVAL; - - if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, -- sizeof(*ring->desc))) -+ sizeof(*ring->desc), true)) - return -ENOMEM; - - if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -@@ -960,6 +1440,37 @@ mtk_wed_txfree_ring_setup(struct mtk_wed - return 0; - } - -+static int -+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) -+{ -+ struct mtk_wed_ring *ring = &dev->rx_ring[idx]; -+ -+ if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring))) -+ return -EINVAL; -+ -+ if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, -+ sizeof(*ring->desc), false)) -+ return -ENOMEM; -+ -+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -+ return -ENOMEM; -+ -+ ring->reg_base = MTK_WED_RING_RX_DATA(idx); -+ ring->wpdma = regs; -+ ring->flags |= MTK_WED_RING_CONFIGURED; -+ -+ /* WPDMA -> WED */ -+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys); -+ wpdma_rx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_RX_RING_SIZE); -+ -+ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_BASE, -+ ring->desc_phys); -+ wed_w32(dev, MTK_WED_WPDMA_RING_RX_DATA(idx) + MTK_WED_RING_OFS_COUNT, -+ MTK_WED_RX_RING_SIZE); -+ -+ return 0; -+} -+ - static u32 - mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) - { -@@ -1056,7 +1567,9 @@ void mtk_wed_add_hw(struct device_node * - static const struct mtk_wed_ops wed_ops = { - .attach = mtk_wed_attach, - .tx_ring_setup = mtk_wed_tx_ring_setup, -+ .rx_ring_setup = mtk_wed_rx_ring_setup, - .txfree_ring_setup = mtk_wed_txfree_ring_setup, -+ .msg_update = mtk_wed_mcu_msg_update, - .start = mtk_wed_start, - .stop = mtk_wed_stop, - .reset_dma = mtk_wed_reset_dma, -@@ -1065,6 +1578,7 @@ void mtk_wed_add_hw(struct device_node * - .irq_get = mtk_wed_irq_get, - .irq_set_mask = mtk_wed_irq_set_mask, - .detach = mtk_wed_detach, -+ .ppe_check = mtk_wed_ppe_check, - }; - struct device_node *eth_np = eth->dev->of_node; - struct platform_device *pdev; ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -87,6 +87,24 @@ wpdma_tx_w32(struct mtk_wed_device *dev, - } - - static inline u32 -+wpdma_rx_r32(struct mtk_wed_device *dev, int ring, u32 reg) -+{ -+ if (!dev->rx_ring[ring].wpdma) -+ return 0; -+ -+ return readl(dev->rx_ring[ring].wpdma + reg); -+} -+ -+static inline void -+wpdma_rx_w32(struct mtk_wed_device *dev, int ring, u32 reg, u32 val) -+{ -+ if (!dev->rx_ring[ring].wpdma) -+ return; -+ -+ writel(val, dev->rx_ring[ring].wpdma + reg); -+} -+ -+static inline u32 - wpdma_txfree_r32(struct mtk_wed_device *dev, u32 reg) - { - if (!dev->txfree_ring.wpdma) -@@ -128,6 +146,7 @@ static inline int mtk_wed_flow_add(int i - static inline void mtk_wed_flow_remove(int index) - { - } -+ - #endif - - #ifdef CONFIG_DEBUG_FS ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #include "mtk_wed_regs.h" - #include "mtk_wed_wo.h" -@@ -60,24 +61,37 @@ void mtk_wed_mcu_rx_event(struct mtk_wed - wake_up(&wo->mcu.wait); - } - -+static void -+mtk_wed_update_rx_stats(struct mtk_wed_device *wed, struct sk_buff *skb) -+{ -+ u32 count = get_unaligned_le32(skb->data); -+ struct mtk_wed_wo_rx_stats *stats; -+ int i; -+ -+ if (count * sizeof(*stats) > skb->len - sizeof(u32)) -+ return; -+ -+ stats = (struct mtk_wed_wo_rx_stats *)(skb->data + sizeof(u32)); -+ for (i = 0 ; i < count ; i++) -+ wed->wlan.update_wo_rx_stats(wed, &stats[i]); -+} -+ - void mtk_wed_mcu_rx_unsolicited_event(struct mtk_wed_wo *wo, - struct sk_buff *skb) - { - struct mtk_wed_mcu_hdr *hdr = (struct mtk_wed_mcu_hdr *)skb->data; - -- switch (hdr->cmd) { -- case MTK_WED_WO_EVT_LOG_DUMP: { -- const char *msg = (const char *)(skb->data + sizeof(*hdr)); -+ skb_pull(skb, sizeof(*hdr)); - -- dev_notice(wo->hw->dev, "%s\n", msg); -+ switch (hdr->cmd) { -+ case MTK_WED_WO_EVT_LOG_DUMP: -+ dev_notice(wo->hw->dev, "%s\n", skb->data); - break; -- } - case MTK_WED_WO_EVT_PROFILING: { -- struct mtk_wed_wo_log_info *info; -- u32 count = (skb->len - sizeof(*hdr)) / sizeof(*info); -+ struct mtk_wed_wo_log_info *info = (void *)skb->data; -+ u32 count = skb->len / sizeof(*info); - int i; - -- info = (struct mtk_wed_wo_log_info *)(skb->data + sizeof(*hdr)); - for (i = 0 ; i < count ; i++) - dev_notice(wo->hw->dev, - "SN:%u latency: total=%u, rro:%u, mod:%u\n", -@@ -88,6 +102,7 @@ void mtk_wed_mcu_rx_unsolicited_event(st - break; - } - case MTK_WED_WO_EVT_RXCNT_INFO: -+ mtk_wed_update_rx_stats(wo->hw->wed_dev, skb); - break; - default: - break; -@@ -144,6 +159,8 @@ mtk_wed_mcu_parse_response(struct mtk_we - skb_pull(skb, sizeof(*hdr)); - switch (cmd) { - case MTK_WED_WO_CMD_RXCNT_INFO: -+ mtk_wed_update_rx_stats(wo->hw->wed_dev, skb); -+ break; - default: - break; - } -@@ -182,6 +199,18 @@ unlock: - return ret; - } - -+int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, -+ int len) -+{ -+ struct mtk_wed_wo *wo = dev->hw->wed_wo; -+ -+ if (dev->hw->version == 1) -+ return 0; -+ -+ return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len, -+ true); -+} -+ - static int - mtk_wed_get_memory_region(struct mtk_wed_wo *wo, - struct mtk_wed_wo_memory_region *region) ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -4,6 +4,7 @@ - #ifndef __MTK_WED_REGS_H - #define __MTK_WED_REGS_H - -+#define MTK_WFDMA_DESC_CTRL_TO_HOST BIT(8) - #define MTK_WDMA_DESC_CTRL_LEN1 GENMASK(14, 0) - #define MTK_WDMA_DESC_CTRL_LEN1_V2 GENMASK(13, 0) - #define MTK_WDMA_DESC_CTRL_LAST_SEG1 BIT(15) -@@ -28,6 +29,8 @@ struct mtk_wdma_desc { - #define MTK_WED_RESET_WED_TX_DMA BIT(12) - #define MTK_WED_RESET_WDMA_RX_DRV BIT(17) - #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19) -+#define MTK_WED_RESET_RX_RRO_QM BIT(20) -+#define MTK_WED_RESET_RX_ROUTE_QM BIT(21) - #define MTK_WED_RESET_WED BIT(31) - - #define MTK_WED_CTRL 0x00c -@@ -39,8 +42,12 @@ struct mtk_wdma_desc { - #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9) - #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10) - #define MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY BIT(11) --#define MTK_WED_CTRL_RESERVE_EN BIT(12) --#define MTK_WED_CTRL_RESERVE_BUSY BIT(13) -+#define MTK_WED_CTRL_WED_RX_BM_EN BIT(12) -+#define MTK_WED_CTRL_WED_RX_BM_BUSY BIT(13) -+#define MTK_WED_CTRL_RX_RRO_QM_EN BIT(14) -+#define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15) -+#define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16) -+#define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17) - #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24) - #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25) - #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28) -@@ -62,6 +69,9 @@ struct mtk_wdma_desc { - #define MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR BIT(22) - #define MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR BIT(23) - #define MTK_WED_EXT_INT_STATUS_RX_DRV_DMA_RECYCLE BIT(24) -+#define MTK_WED_EXT_INT_STATUS_RX_DRV_GET_BM_DMAD_SKIP BIT(25) -+#define MTK_WED_EXT_INT_STATUS_WPDMA_RX_D_DRV_ERR BIT(26) -+#define MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY BIT(27) - #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \ - MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \ - MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \ -@@ -71,6 +81,8 @@ struct mtk_wdma_desc { - MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR) - - #define MTK_WED_EXT_INT_MASK 0x028 -+#define MTK_WED_EXT_INT_MASK1 0x02c -+#define MTK_WED_EXT_INT_MASK2 0x030 - - #define MTK_WED_STATUS 0x060 - #define MTK_WED_STATUS_TX GENMASK(15, 8) -@@ -151,6 +163,7 @@ struct mtk_wdma_desc { - #define MTK_WED_RING_TX(_n) (0x300 + (_n) * 0x10) - - #define MTK_WED_RING_RX(_n) (0x400 + (_n) * 0x10) -+#define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10) - - #define MTK_WED_SCR0 0x3c0 - #define MTK_WED_WPDMA_INT_TRIGGER 0x504 -@@ -213,6 +226,12 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_INT_CTRL_TX1_DONE_TRIG GENMASK(14, 10) - - #define MTK_WED_WPDMA_INT_CTRL_RX 0x534 -+#define MTK_WED_WPDMA_INT_CTRL_RX0_EN BIT(0) -+#define MTK_WED_WPDMA_INT_CTRL_RX0_CLR BIT(1) -+#define MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG GENMASK(6, 2) -+#define MTK_WED_WPDMA_INT_CTRL_RX1_EN BIT(8) -+#define MTK_WED_WPDMA_INT_CTRL_RX1_CLR BIT(9) -+#define MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG GENMASK(14, 10) - - #define MTK_WED_WPDMA_INT_CTRL_TX_FREE 0x538 - #define MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_EN BIT(0) -@@ -242,11 +261,34 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10) - #define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10) -+#define MTK_WED_WPDMA_RING_RX_DATA(_n) (0x730 + (_n) * 0x10) -+ -+#define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c -+#define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0) -+#define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7) -+#define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24) -+ -+#define MTK_WED_WPDMA_RX_D_RST_IDX 0x760 -+#define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16) -+#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24) -+ -+#define MTK_WED_WPDMA_RX_GLO_CFG 0x76c -+#define MTK_WED_WPDMA_RX_RING 0x770 -+ -+#define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4) -+#define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4) -+#define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c -+ -+#define MTK_WED_WDMA_RING_TX 0x800 -+ -+#define MTK_WED_WDMA_TX_MIB 0x810 -+ - #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10) - #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4) - - #define MTK_WED_WDMA_GLO_CFG 0xa04 - #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0) -+#define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1) - #define MTK_WED_WDMA_GLO_CFG_RX_DRV_EN BIT(2) - #define MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY BIT(3) - #define MTK_WED_WDMA_GLO_CFG_BT_SIZE GENMASK(5, 4) -@@ -291,6 +333,20 @@ struct mtk_wdma_desc { - #define MTK_WED_WDMA_RX_RECYCLE_MIB(_n) (0xae8 + (_n) * 4) - #define MTK_WED_WDMA_RX_PROCESSED_MIB(_n) (0xaf0 + (_n) * 4) - -+#define MTK_WED_RX_BM_RX_DMAD 0xd80 -+#define MTK_WED_RX_BM_RX_DMAD_SDL0 GENMASK(13, 0) -+ -+#define MTK_WED_RX_BM_BASE 0xd84 -+#define MTK_WED_RX_BM_INIT_PTR 0xd88 -+#define MTK_WED_RX_BM_SW_TAIL GENMASK(15, 0) -+#define MTK_WED_RX_BM_INIT_SW_TAIL BIT(16) -+ -+#define MTK_WED_RX_PTR 0xd8c -+ -+#define MTK_WED_RX_BM_DYN_ALLOC_TH 0xdb4 -+#define MTK_WED_RX_BM_DYN_ALLOC_TH_H GENMASK(31, 16) -+#define MTK_WED_RX_BM_DYN_ALLOC_TH_L GENMASK(15, 0) -+ - #define MTK_WED_RING_OFS_BASE 0x00 - #define MTK_WED_RING_OFS_COUNT 0x04 - #define MTK_WED_RING_OFS_CPU_IDX 0x08 -@@ -301,7 +357,9 @@ struct mtk_wdma_desc { - - #define MTK_WDMA_GLO_CFG 0x204 - #define MTK_WDMA_GLO_CFG_TX_DMA_EN BIT(0) -+#define MTK_WDMA_GLO_CFG_TX_DMA_BUSY BIT(1) - #define MTK_WDMA_GLO_CFG_RX_DMA_EN BIT(2) -+#define MTK_WDMA_GLO_CFG_RX_DMA_BUSY BIT(3) - #define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES BIT(26) - #define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES BIT(27) - #define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES BIT(28) -@@ -330,4 +388,70 @@ struct mtk_wdma_desc { - /* DMA channel mapping */ - #define HIFSYS_DMA_AG_MAP 0x008 - -+#define MTK_WED_RTQM_GLO_CFG 0xb00 -+#define MTK_WED_RTQM_BUSY BIT(1) -+#define MTK_WED_RTQM_Q_RST BIT(2) -+#define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5) -+#define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20) -+ -+#define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4) -+#define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4) -+#define MTK_WED_RTQM_Q2N_MIB 0xb80 -+#define MTK_WED_RTQM_Q2H_MIB(_n) (0xb84 + (_n) * 0x4) -+ -+#define MTK_WED_RTQM_Q2B_MIB 0xb8c -+#define MTK_WED_RTQM_PFDBK_MIB 0xb90 -+ -+#define MTK_WED_RROQM_GLO_CFG 0xc04 -+#define MTK_WED_RROQM_RST_IDX 0xc08 -+#define MTK_WED_RROQM_RST_IDX_MIOD BIT(0) -+#define MTK_WED_RROQM_RST_IDX_FDBK BIT(4) -+ -+#define MTK_WED_RROQM_MIOD_CTRL0 0xc40 -+#define MTK_WED_RROQM_MIOD_CTRL1 0xc44 -+#define MTK_WED_RROQM_MIOD_CNT GENMASK(11, 0) -+ -+#define MTK_WED_RROQM_MIOD_CTRL2 0xc48 -+#define MTK_WED_RROQM_MIOD_CTRL3 0xc4c -+ -+#define MTK_WED_RROQM_FDBK_CTRL0 0xc50 -+#define MTK_WED_RROQM_FDBK_CTRL1 0xc54 -+#define MTK_WED_RROQM_FDBK_CNT GENMASK(11, 0) -+ -+#define MTK_WED_RROQM_FDBK_CTRL2 0xc58 -+ -+#define MTK_WED_RROQ_BASE_L 0xc80 -+#define MTK_WED_RROQ_BASE_H 0xc84 -+ -+#define MTK_WED_RROQM_MIOD_CFG 0xc8c -+#define MTK_WED_RROQM_MIOD_MID_DW GENMASK(5, 0) -+#define MTK_WED_RROQM_MIOD_MOD_DW GENMASK(13, 8) -+#define MTK_WED_RROQM_MIOD_ENTRY_DW GENMASK(22, 16) -+ -+#define MTK_WED_RROQM_MID_MIB 0xcc0 -+#define MTK_WED_RROQM_MOD_MIB 0xcc4 -+#define MTK_WED_RROQM_MOD_COHERENT_MIB 0xcc8 -+#define MTK_WED_RROQM_FDBK_MIB 0xcd0 -+#define MTK_WED_RROQM_FDBK_COHERENT_MIB 0xcd4 -+#define MTK_WED_RROQM_FDBK_IND_MIB 0xce0 -+#define MTK_WED_RROQM_FDBK_ENQ_MIB 0xce4 -+#define MTK_WED_RROQM_FDBK_ANC_MIB 0xce8 -+#define MTK_WED_RROQM_FDBK_ANC2H_MIB 0xcec -+ -+#define MTK_WED_RX_BM_RX_DMAD 0xd80 -+#define MTK_WED_RX_BM_BASE 0xd84 -+#define MTK_WED_RX_BM_INIT_PTR 0xd88 -+#define MTK_WED_RX_BM_PTR 0xd8c -+#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16) -+#define MTK_WED_RX_BM_PTR_TAIL GENMASK(15, 0) -+ -+#define MTK_WED_RX_BM_BLEN 0xd90 -+#define MTK_WED_RX_BM_STS 0xd94 -+#define MTK_WED_RX_BM_INTF2 0xd98 -+#define MTK_WED_RX_BM_INTF 0xd9c -+#define MTK_WED_RX_BM_ERR_STS 0xda8 -+ -+#define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000 -+#define MTK_WED_PCIE_INT_MASK 0x0 -+ - #endif ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -49,6 +49,10 @@ enum { - MTK_WED_WARP_CMD_FLAG_FROM_TO_WO = BIT(2), - }; - -+#define MTK_WED_WO_CPU_MCUSYS_RESET_ADDR 0x15194050 -+#define MTK_WED_WO_CPU_WO0_MCUSYS_RESET_MASK 0x20 -+#define MTK_WED_WO_CPU_WO1_MCUSYS_RESET_MASK 0x1 -+ - enum { - MTK_WED_WO_REGION_EMI, - MTK_WED_WO_REGION_ILM, -@@ -57,6 +61,28 @@ enum { - __MTK_WED_WO_REGION_MAX, - }; - -+enum mtk_wed_wo_state { -+ MTK_WED_WO_STATE_UNDEFINED, -+ MTK_WED_WO_STATE_INIT, -+ MTK_WED_WO_STATE_ENABLE, -+ MTK_WED_WO_STATE_DISABLE, -+ MTK_WED_WO_STATE_HALT, -+ MTK_WED_WO_STATE_GATING, -+ MTK_WED_WO_STATE_SER_RESET, -+ MTK_WED_WO_STATE_WF_RESET, -+}; -+ -+enum mtk_wed_wo_done_state { -+ MTK_WED_WOIF_UNDEFINED, -+ MTK_WED_WOIF_DISABLE_DONE, -+ MTK_WED_WOIF_TRIGGER_ENABLE, -+ MTK_WED_WOIF_ENABLE_DONE, -+ MTK_WED_WOIF_TRIGGER_GATING, -+ MTK_WED_WOIF_GATING_DONE, -+ MTK_WED_WOIF_TRIGGER_HALT, -+ MTK_WED_WOIF_HALT_DONE, -+}; -+ - enum mtk_wed_dummy_cr_idx { - MTK_WED_DUMMY_CR_FWDL, - MTK_WED_DUMMY_CR_WO_STATUS, -@@ -245,6 +271,8 @@ void mtk_wed_mcu_rx_unsolicited_event(st - struct sk_buff *skb); - int mtk_wed_mcu_send_msg(struct mtk_wed_wo *wo, int id, int cmd, - const void *data, int len, bool wait_resp); -+int mtk_wed_mcu_msg_update(struct mtk_wed_device *dev, int id, void *data, -+ int len); - int mtk_wed_mcu_init(struct mtk_wed_wo *wo); - int mtk_wed_wo_init(struct mtk_wed_hw *hw); - void mtk_wed_wo_deinit(struct mtk_wed_hw *hw); ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -5,10 +5,13 @@ - #include - #include - #include -+#include - - #define MTK_WED_TX_QUEUES 2 - #define MTK_WED_RX_QUEUES 2 - -+#define WED_WO_STA_REC 0x6 -+ - struct mtk_wed_hw; - struct mtk_wdma_desc; - -@@ -41,21 +44,37 @@ enum mtk_wed_wo_cmd { - MTK_WED_WO_CMD_WED_END - }; - -+struct mtk_rxbm_desc { -+ __le32 buf0; -+ __le32 token; -+} __packed __aligned(4); -+ - enum mtk_wed_bus_tye { - MTK_WED_BUS_PCIE, - MTK_WED_BUS_AXI, - }; - -+#define MTK_WED_RING_CONFIGURED BIT(0) - struct mtk_wed_ring { - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; - u32 desc_size; - int size; -+ u32 flags; - - u32 reg_base; - void __iomem *wpdma; - }; - -+struct mtk_wed_wo_rx_stats { -+ __le16 wlan_idx; -+ __le16 tid; -+ __le32 rx_pkt_cnt; -+ __le32 rx_byte_cnt; -+ __le32 rx_err_cnt; -+ __le32 rx_drop_cnt; -+}; -+ - struct mtk_wed_device { - #ifdef CONFIG_NET_MEDIATEK_SOC_WED - const struct mtk_wed_ops *ops; -@@ -64,9 +83,12 @@ struct mtk_wed_device { - bool init_done, running; - int wdma_idx; - int irq; -+ u8 version; - - struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; -+ struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES]; - struct mtk_wed_ring txfree_ring; -+ struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; - struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES]; - - struct { -@@ -74,7 +96,20 @@ struct mtk_wed_device { - void **pages; - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -- } buf_ring; -+ } tx_buf_ring; -+ -+ struct { -+ int size; -+ struct page_frag_cache rx_page; -+ struct mtk_rxbm_desc *desc; -+ dma_addr_t desc_phys; -+ } rx_buf_ring; -+ -+ struct { -+ struct mtk_wed_ring ring; -+ dma_addr_t miod_phys; -+ dma_addr_t fdbk_phys; -+ } rro; - - /* filled by driver: */ - struct { -@@ -83,22 +118,36 @@ struct mtk_wed_device { - struct pci_dev *pci_dev; - }; - enum mtk_wed_bus_tye bus_type; -+ void __iomem *base; -+ u32 phy_base; - - u32 wpdma_phys; - u32 wpdma_int; - u32 wpdma_mask; - u32 wpdma_tx; - u32 wpdma_txfree; -+ u32 wpdma_rx_glo; -+ u32 wpdma_rx; -+ -+ bool wcid_512; - - u16 token_start; - unsigned int nbuf; -+ unsigned int rx_nbuf; -+ unsigned int rx_npkt; -+ unsigned int rx_size; - - u8 tx_tbit[MTK_WED_TX_QUEUES]; -+ u8 rx_tbit[MTK_WED_RX_QUEUES]; - u8 txfree_tbit; - - u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); - int (*offload_enable)(struct mtk_wed_device *wed); - void (*offload_disable)(struct mtk_wed_device *wed); -+ u32 (*init_rx_buf)(struct mtk_wed_device *wed, int size); -+ void (*release_rx_buf)(struct mtk_wed_device *wed); -+ void (*update_wo_rx_stats)(struct mtk_wed_device *wed, -+ struct mtk_wed_wo_rx_stats *stats); - } wlan; - #endif - }; -@@ -107,9 +156,15 @@ struct mtk_wed_ops { - int (*attach)(struct mtk_wed_device *dev); - int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, - void __iomem *regs); -+ int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, -+ void __iomem *regs); - int (*txfree_ring_setup)(struct mtk_wed_device *dev, - void __iomem *regs); -+ int (*msg_update)(struct mtk_wed_device *dev, int cmd_id, -+ void *data, int len); - void (*detach)(struct mtk_wed_device *dev); -+ void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb, -+ u32 reason, u32 hash); - - void (*stop)(struct mtk_wed_device *dev); - void (*start)(struct mtk_wed_device *dev, u32 irq_mask); -@@ -144,6 +199,16 @@ mtk_wed_device_attach(struct mtk_wed_dev - return ret; - } - -+static inline bool -+mtk_wed_get_rx_capa(struct mtk_wed_device *dev) -+{ -+#ifdef CONFIG_NET_MEDIATEK_SOC_WED -+ return dev->version != 1; -+#else -+ return false; -+#endif -+} -+ - #ifdef CONFIG_NET_MEDIATEK_SOC_WED - #define mtk_wed_device_active(_dev) !!(_dev)->ops - #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) -@@ -160,6 +225,12 @@ mtk_wed_device_attach(struct mtk_wed_dev - (_dev)->ops->irq_get(_dev, _mask) - #define mtk_wed_device_irq_set_mask(_dev, _mask) \ - (_dev)->ops->irq_set_mask(_dev, _mask) -+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \ -+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \ -+ (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) -+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ -+ (_dev)->ops->msg_update(_dev, _id, _msg, _len) - #else - static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) - { -@@ -173,6 +244,9 @@ static inline bool mtk_wed_device_active - #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) - #define mtk_wed_device_irq_get(_dev, _mask) 0 - #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0) -+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) -+#define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV - #endif - - #endif diff --git a/target/linux/generic/backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch b/target/linux/generic/backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch deleted file mode 100644 index bb1066deceaa46..00000000000000 --- a/target/linux/generic/backport-6.1/729-05-v6.1-net-ethernet-mtk_wed-add-rx-mib-counters.patch +++ /dev/null @@ -1,149 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 5 Nov 2022 23:36:22 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add rx mib counters - -Introduce WED RX MIB counters support available on MT7986a SoC. - -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -2,6 +2,7 @@ - /* Copyright (C) 2021 Felix Fietkau */ - - #include -+#include - #include "mtk_wed.h" - #include "mtk_wed_regs.h" - -@@ -18,6 +19,8 @@ enum { - DUMP_TYPE_WDMA, - DUMP_TYPE_WPDMA_TX, - DUMP_TYPE_WPDMA_TXFREE, -+ DUMP_TYPE_WPDMA_RX, -+ DUMP_TYPE_WED_RRO, - }; - - #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING } -@@ -36,6 +39,9 @@ enum { - - #define DUMP_WPDMA_TX_RING(_n) DUMP_RING("WPDMA_TX" #_n, 0, DUMP_TYPE_WPDMA_TX, _n) - #define DUMP_WPDMA_TXFREE_RING DUMP_RING("WPDMA_RX1", 0, DUMP_TYPE_WPDMA_TXFREE) -+#define DUMP_WPDMA_RX_RING(_n) DUMP_RING("WPDMA_RX" #_n, 0, DUMP_TYPE_WPDMA_RX, _n) -+#define DUMP_WED_RRO_RING(_base)DUMP_RING("WED_RRO_MIOD", MTK_##_base, DUMP_TYPE_WED_RRO) -+#define DUMP_WED_RRO_FDBK(_base)DUMP_RING("WED_RRO_FDBK", MTK_##_base, DUMP_TYPE_WED_RRO) - - static void - print_reg_val(struct seq_file *s, const char *name, u32 val) -@@ -57,6 +63,7 @@ dump_wed_regs(struct seq_file *s, struct - cur > regs ? "\n" : "", - cur->name); - continue; -+ case DUMP_TYPE_WED_RRO: - case DUMP_TYPE_WED: - val = wed_r32(dev, cur->offset); - break; -@@ -69,6 +76,9 @@ dump_wed_regs(struct seq_file *s, struct - case DUMP_TYPE_WPDMA_TXFREE: - val = wpdma_txfree_r32(dev, cur->offset); - break; -+ case DUMP_TYPE_WPDMA_RX: -+ val = wpdma_rx_r32(dev, cur->base, cur->offset); -+ break; - } - print_reg_val(s, cur->name, val); - } -@@ -132,6 +142,80 @@ wed_txinfo_show(struct seq_file *s, void - } - DEFINE_SHOW_ATTRIBUTE(wed_txinfo); - -+static int -+wed_rxinfo_show(struct seq_file *s, void *data) -+{ -+ static const struct reg_dump regs[] = { -+ DUMP_STR("WPDMA RX"), -+ DUMP_WPDMA_RX_RING(0), -+ DUMP_WPDMA_RX_RING(1), -+ -+ DUMP_STR("WPDMA RX"), -+ DUMP_WED(WED_WPDMA_RX_D_MIB(0)), -+ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(0)), -+ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(0)), -+ DUMP_WED(WED_WPDMA_RX_D_MIB(1)), -+ DUMP_WED_RING(WED_WPDMA_RING_RX_DATA(1)), -+ DUMP_WED(WED_WPDMA_RX_D_PROCESSED_MIB(1)), -+ DUMP_WED(WED_WPDMA_RX_D_COHERENT_MIB), -+ -+ DUMP_STR("WED RX"), -+ DUMP_WED_RING(WED_RING_RX_DATA(0)), -+ DUMP_WED_RING(WED_RING_RX_DATA(1)), -+ -+ DUMP_STR("WED RRO"), -+ DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0), -+ DUMP_WED(WED_RROQM_MID_MIB), -+ DUMP_WED(WED_RROQM_MOD_MIB), -+ DUMP_WED(WED_RROQM_MOD_COHERENT_MIB), -+ DUMP_WED_RRO_FDBK(WED_RROQM_FDBK_CTRL0), -+ DUMP_WED(WED_RROQM_FDBK_IND_MIB), -+ DUMP_WED(WED_RROQM_FDBK_ENQ_MIB), -+ DUMP_WED(WED_RROQM_FDBK_ANC_MIB), -+ DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB), -+ -+ DUMP_STR("WED Route QM"), -+ DUMP_WED(WED_RTQM_R2H_MIB(0)), -+ DUMP_WED(WED_RTQM_R2Q_MIB(0)), -+ DUMP_WED(WED_RTQM_Q2H_MIB(0)), -+ DUMP_WED(WED_RTQM_R2H_MIB(1)), -+ DUMP_WED(WED_RTQM_R2Q_MIB(1)), -+ DUMP_WED(WED_RTQM_Q2H_MIB(1)), -+ DUMP_WED(WED_RTQM_Q2N_MIB), -+ DUMP_WED(WED_RTQM_Q2B_MIB), -+ DUMP_WED(WED_RTQM_PFDBK_MIB), -+ -+ DUMP_STR("WED WDMA TX"), -+ DUMP_WED(WED_WDMA_TX_MIB), -+ DUMP_WED_RING(WED_WDMA_RING_TX), -+ -+ DUMP_STR("WDMA TX"), -+ DUMP_WDMA(WDMA_GLO_CFG), -+ DUMP_WDMA_RING(WDMA_RING_TX(0)), -+ DUMP_WDMA_RING(WDMA_RING_TX(1)), -+ -+ DUMP_STR("WED RX BM"), -+ DUMP_WED(WED_RX_BM_BASE), -+ DUMP_WED(WED_RX_BM_RX_DMAD), -+ DUMP_WED(WED_RX_BM_PTR), -+ DUMP_WED(WED_RX_BM_TKID_MIB), -+ DUMP_WED(WED_RX_BM_BLEN), -+ DUMP_WED(WED_RX_BM_STS), -+ DUMP_WED(WED_RX_BM_INTF2), -+ DUMP_WED(WED_RX_BM_INTF), -+ DUMP_WED(WED_RX_BM_ERR_STS), -+ }; -+ struct mtk_wed_hw *hw = s->private; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (!dev) -+ return 0; -+ -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(wed_rxinfo); - - static int - mtk_wed_reg_set(void *data, u64 val) -@@ -175,4 +259,7 @@ void mtk_wed_hw_add_debugfs(struct mtk_w - debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg); - debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval); - debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops); -+ if (hw->version != 1) -+ debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, -+ &wed_rxinfo_fops); - } diff --git a/target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch b/target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch deleted file mode 100644 index 5a79242e3bb89a..00000000000000 --- a/target/linux/generic/backport-6.1/729-07-v6.1-net-ethernet-mtk_eth_soc-remove-cpu_relax-in-mtk_pen.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 17 Nov 2022 00:58:46 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: remove cpu_relax in - mtk_pending_work - -Get rid of cpu_relax in mtk_pending_work routine since MTK_RESETTING is -set only in mtk_pending_work() and it runs holding rtnl lock - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3479,11 +3479,8 @@ static void mtk_pending_work(struct work - rtnl_lock(); - - dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__); -+ set_bit(MTK_RESETTING, ð->state); - -- while (test_and_set_bit_lock(MTK_RESETTING, ð->state)) -- cpu_relax(); -- -- dev_dbg(eth->dev, "[%s][%d] mtk_stop starts\n", __func__, __LINE__); - /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { - if (!eth->netdev[i]) -@@ -3517,7 +3514,7 @@ static void mtk_pending_work(struct work - - dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__); - -- clear_bit_unlock(MTK_RESETTING, ð->state); -+ clear_bit(MTK_RESETTING, ð->state); - - rtnl_unlock(); - } diff --git a/target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch b/target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch deleted file mode 100644 index 117ccc090258ea..00000000000000 --- a/target/linux/generic/backport-6.1/729-09-v6.2-net-ethernet-mtk_wed-add-wcid-overwritten-support-fo.patch +++ /dev/null @@ -1,80 +0,0 @@ -From: Sujuan Chen -Date: Thu, 24 Nov 2022 11:18:14 +0800 -Subject: [PATCH] net: ethernet: mtk_wed: add wcid overwritten support for wed - v1 - -All wed versions should enable the wcid overwritten feature, -since the wcid size is controlled by the wlan driver. - -Tested-by: Sujuan Chen -Co-developed-by: Bo Jiao -Signed-off-by: Bo Jiao -Signed-off-by: Sujuan Chen -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -526,9 +526,9 @@ mtk_wed_dma_disable(struct mtk_wed_devic - MTK_WED_WPDMA_RX_D_RX_DRV_EN); - wed_clr(dev, MTK_WED_WDMA_GLO_CFG, - MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); -- -- mtk_wed_set_512_support(dev, false); - } -+ -+ mtk_wed_set_512_support(dev, false); - } - - static void -@@ -1290,9 +1290,10 @@ mtk_wed_start(struct mtk_wed_device *dev - if (mtk_wed_rro_cfg(dev)) - return; - -- mtk_wed_set_512_support(dev, dev->wlan.wcid_512); - } - -+ mtk_wed_set_512_support(dev, dev->wlan.wcid_512); -+ - mtk_wed_dma_enable(dev); - dev->running = true; - } -@@ -1358,11 +1359,13 @@ mtk_wed_attach(struct mtk_wed_device *de - } - - mtk_wed_hw_init_early(dev); -- if (hw->version == 1) -+ if (hw->version == 1) { - regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, - BIT(hw->index), 0); -- else -+ } else { -+ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID); - ret = mtk_wed_wo_init(hw); -+ } - out: - if (ret) - mtk_wed_detach(dev); ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -20,6 +20,8 @@ struct mtk_wdma_desc { - __le32 info; - } __packed __aligned(4); - -+#define MTK_WED_REV_ID 0x004 -+ - #define MTK_WED_RESET 0x008 - #define MTK_WED_RESET_TX_BM BIT(0) - #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -85,6 +85,9 @@ struct mtk_wed_device { - int irq; - u8 version; - -+ /* used by wlan driver */ -+ u32 rev_id; -+ - struct mtk_wed_ring tx_ring[MTK_WED_TX_QUEUES]; - struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES]; - struct mtk_wed_ring txfree_ring; diff --git a/target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch b/target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch deleted file mode 100644 index ec58c3fc572400..00000000000000 --- a/target/linux/generic/backport-6.1/729-10-v6.2-net-ethernet-mtk_wed-return-status-value-in-mtk_wdma.patch +++ /dev/null @@ -1,85 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Nov 2022 16:22:51 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: return status value in - mtk_wdma_rx_reset - -Move MTK_WDMA_RESET_IDX configuration in mtk_wdma_rx_reset routine. -Increase poll timeout to 10ms in order to be aligned with vendor sdk. -This is a preliminary patch to add Wireless Ethernet Dispatcher reset -support. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -101,17 +101,21 @@ mtk_wdma_read_reset(struct mtk_wed_devic - return wdma_r32(dev, MTK_WDMA_GLO_CFG); - } - --static void -+static int - mtk_wdma_rx_reset(struct mtk_wed_device *dev) - { - u32 status, mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY; -- int i; -+ int i, ret; - - wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN); -- if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, -- !(status & mask), 0, 1000)) -+ ret = readx_poll_timeout(mtk_wdma_read_reset, dev, status, -+ !(status & mask), 0, 10000); -+ if (ret) - dev_err(dev->hw->dev, "rx reset failed\n"); - -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -+ - for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) { - if (dev->rx_wdma[i].desc) - continue; -@@ -119,6 +123,8 @@ mtk_wdma_rx_reset(struct mtk_wed_device - wdma_w32(dev, - MTK_WDMA_RING_RX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); - } -+ -+ return ret; - } - - static void -@@ -565,9 +571,7 @@ mtk_wed_detach(struct mtk_wed_device *de - - mtk_wed_stop(dev); - -- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); -- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -- -+ mtk_wdma_rx_reset(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); - if (mtk_wed_get_rx_capa(dev)) { - wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); -@@ -582,7 +586,6 @@ mtk_wed_detach(struct mtk_wed_device *de - mtk_wed_wo_reset(dev); - mtk_wed_free_rx_rings(dev); - mtk_wed_wo_deinit(hw); -- mtk_wdma_rx_reset(dev); - } - - if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { -@@ -999,11 +1002,7 @@ mtk_wed_reset_dma(struct mtk_wed_device - wed_w32(dev, MTK_WED_RESET_IDX, 0); - } - -- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); -- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -- -- if (mtk_wed_get_rx_capa(dev)) -- mtk_wdma_rx_reset(dev); -+ mtk_wdma_rx_reset(dev); - - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); diff --git a/target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch b/target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch deleted file mode 100644 index 10c1732c969a9b..00000000000000 --- a/target/linux/generic/backport-6.1/729-11-v6.2-net-ethernet-mtk_wed-move-MTK_WDMA_RESET_IDX_TX-conf.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Nov 2022 16:22:52 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: move MTK_WDMA_RESET_IDX_TX - configuration in mtk_wdma_tx_reset - -Remove duplicated code. Increase poll timeout to 10ms in order to be -aligned with vendor sdk. -This is a preliminary patch to add Wireless Ethernet Dispatcher reset -support. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -135,16 +135,15 @@ mtk_wdma_tx_reset(struct mtk_wed_device - - wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); - if (readx_poll_timeout(mtk_wdma_read_reset, dev, status, -- !(status & mask), 0, 1000)) -+ !(status & mask), 0, 10000)) - dev_err(dev->hw->dev, "tx reset failed\n"); - -- for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) { -- if (dev->tx_wdma[i].desc) -- continue; -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); -+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); - -+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) - wdma_w32(dev, - MTK_WDMA_RING_TX(i) + MTK_WED_RING_OFS_CPU_IDX, 0); -- } - } - - static void -@@ -573,12 +572,6 @@ mtk_wed_detach(struct mtk_wed_device *de - - mtk_wdma_rx_reset(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); -- if (mtk_wed_get_rx_capa(dev)) { -- wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); -- wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); -- wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); -- } -- - mtk_wed_free_tx_buffer(dev); - mtk_wed_free_tx_rings(dev); - diff --git a/target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch b/target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch deleted file mode 100644 index f4e842d515a8e1..00000000000000 --- a/target/linux/generic/backport-6.1/729-12-v6.2-net-ethernet-mtk_wed-update-mtk_wed_stop.patch +++ /dev/null @@ -1,98 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Nov 2022 16:22:53 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: update mtk_wed_stop - -Update mtk_wed_stop routine and rename old mtk_wed_stop() to -mtk_wed_deinit(). This is a preliminary patch to add Wireless Ethernet -Dispatcher reset support. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -539,14 +539,8 @@ mtk_wed_dma_disable(struct mtk_wed_devic - static void - mtk_wed_stop(struct mtk_wed_device *dev) - { -- mtk_wed_dma_disable(dev); - mtk_wed_set_ext_int(dev, false); - -- wed_clr(dev, MTK_WED_CTRL, -- MTK_WED_CTRL_WDMA_INT_AGENT_EN | -- MTK_WED_CTRL_WPDMA_INT_AGENT_EN | -- MTK_WED_CTRL_WED_TX_BM_EN | -- MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0); - wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0); - wdma_w32(dev, MTK_WDMA_INT_MASK, 0); -@@ -558,7 +552,27 @@ mtk_wed_stop(struct mtk_wed_device *dev) - - wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); - wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0); -- wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); -+} -+ -+static void -+mtk_wed_deinit(struct mtk_wed_device *dev) -+{ -+ mtk_wed_stop(dev); -+ mtk_wed_dma_disable(dev); -+ -+ wed_clr(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WDMA_INT_AGENT_EN | -+ MTK_WED_CTRL_WPDMA_INT_AGENT_EN | -+ MTK_WED_CTRL_WED_TX_BM_EN | -+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ -+ if (dev->hw->version == 1) -+ return; -+ -+ wed_clr(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_RX_ROUTE_QM_EN | -+ MTK_WED_CTRL_WED_RX_BM_EN | -+ MTK_WED_CTRL_RX_RRO_QM_EN); - } - - static void -@@ -568,7 +582,7 @@ mtk_wed_detach(struct mtk_wed_device *de - - mutex_lock(&hw_lock); - -- mtk_wed_stop(dev); -+ mtk_wed_deinit(dev); - - mtk_wdma_rx_reset(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); -@@ -670,7 +684,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev - { - u32 mask, set; - -- mtk_wed_stop(dev); -+ mtk_wed_deinit(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); - mtk_wed_set_wpdma(dev); - ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -234,6 +234,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic - (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) - #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ - (_dev)->ops->msg_update(_dev, _id, _msg, _len) -+#define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) -+#define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) - #else - static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) - { -@@ -250,6 +252,8 @@ static inline bool mtk_wed_device_active - #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV - #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) - #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV -+#define mtk_wed_device_stop(_dev) do {} while (0) -+#define mtk_wed_device_dma_reset(_dev) do {} while (0) - #endif - - #endif diff --git a/target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch b/target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch deleted file mode 100644 index a0fc9da99e7fd5..00000000000000 --- a/target/linux/generic/backport-6.1/729-13-v6.2-net-ethernet-mtk_wed-add-mtk_wed_rx_reset-routine.patch +++ /dev/null @@ -1,309 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Nov 2022 16:22:54 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_rx_reset routine - -Introduce mtk_wed_rx_reset routine in order to reset rx DMA for Wireless -Ethernet Dispatcher available on MT7986 SoC. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -944,42 +944,130 @@ mtk_wed_ring_reset(struct mtk_wed_ring * - } - - static u32 --mtk_wed_check_busy(struct mtk_wed_device *dev) -+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) - { -- if (wed_r32(dev, MTK_WED_GLO_CFG) & MTK_WED_GLO_CFG_TX_DMA_BUSY) -- return true; -- -- if (wed_r32(dev, MTK_WED_WPDMA_GLO_CFG) & -- MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY) -- return true; -- -- if (wed_r32(dev, MTK_WED_CTRL) & MTK_WED_CTRL_WDMA_INT_AGENT_BUSY) -- return true; -- -- if (wed_r32(dev, MTK_WED_WDMA_GLO_CFG) & -- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY) -- return true; -- -- if (wdma_r32(dev, MTK_WDMA_GLO_CFG) & -- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY) -- return true; -- -- if (wed_r32(dev, MTK_WED_CTRL) & -- (MTK_WED_CTRL_WED_TX_BM_BUSY | MTK_WED_CTRL_WED_TX_FREE_AGENT_BUSY)) -- return true; -- -- return false; -+ return !!(wed_r32(dev, reg) & mask); - } - - static int --mtk_wed_poll_busy(struct mtk_wed_device *dev) -+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) - { - int sleep = 15000; - int timeout = 100 * sleep; - u32 val; - - return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep, -- timeout, false, dev); -+ timeout, false, dev, reg, mask); -+} -+ -+static int -+mtk_wed_rx_reset(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_wo *wo = dev->hw->wed_wo; -+ u8 val = MTK_WED_WO_STATE_SER_RESET; -+ int i, ret; -+ -+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -+ MTK_WED_WO_CMD_CHANGE_STATE, &val, -+ sizeof(val), true); -+ if (ret) -+ return ret; -+ -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN); -+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY); -+ if (ret) { -+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); -+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV); -+ } else { -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -+ -+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE | -+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE); -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE | -+ MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE); -+ -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -+ } -+ -+ /* reset rro qm */ -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_RRO_QM_EN); -+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_RX_RRO_QM_BUSY); -+ if (ret) { -+ mtk_wed_reset(dev, MTK_WED_RESET_RX_RRO_QM); -+ } else { -+ wed_set(dev, MTK_WED_RROQM_RST_IDX, -+ MTK_WED_RROQM_RST_IDX_MIOD | -+ MTK_WED_RROQM_RST_IDX_FDBK); -+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0); -+ } -+ -+ /* reset route qm */ -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); -+ ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_RX_ROUTE_QM_BUSY); -+ if (ret) -+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM); -+ else -+ wed_set(dev, MTK_WED_RTQM_GLO_CFG, -+ MTK_WED_RTQM_Q_RST); -+ -+ /* reset tx wdma */ -+ mtk_wdma_tx_reset(dev); -+ -+ /* reset tx wdma drv */ -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY); -+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV); -+ -+ /* reset wed rx dma */ -+ ret = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG, -+ MTK_WED_GLO_CFG_RX_DMA_BUSY); -+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_RX_DMA_EN); -+ if (ret) { -+ mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA); -+ } else { -+ struct mtk_eth *eth = dev->hw->eth; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ wed_set(dev, MTK_WED_RESET_IDX, -+ MTK_WED_RESET_IDX_RX_V2); -+ else -+ wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX); -+ wed_w32(dev, MTK_WED_RESET_IDX, 0); -+ } -+ -+ /* reset rx bm */ -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WED_RX_BM_BUSY); -+ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM); -+ -+ /* wo change to enable state */ -+ val = MTK_WED_WO_STATE_ENABLE; -+ ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -+ MTK_WED_WO_CMD_CHANGE_STATE, &val, -+ sizeof(val), true); -+ if (ret) -+ return ret; -+ -+ /* wed_rx_ring_reset */ -+ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++) { -+ if (!dev->rx_ring[i].desc) -+ continue; -+ -+ mtk_wed_ring_reset(&dev->rx_ring[i], MTK_WED_RX_RING_SIZE, -+ false); -+ } -+ mtk_wed_free_rx_buffer(dev); -+ -+ return 0; - } - - static void -@@ -997,19 +1085,23 @@ mtk_wed_reset_dma(struct mtk_wed_device - true); - } - -- if (mtk_wed_poll_busy(dev)) -- busy = mtk_wed_check_busy(dev); -- -+ /* 1. reset WED tx DMA */ -+ wed_clr(dev, MTK_WED_GLO_CFG, MTK_WED_GLO_CFG_TX_DMA_EN); -+ busy = mtk_wed_poll_busy(dev, MTK_WED_GLO_CFG, -+ MTK_WED_GLO_CFG_TX_DMA_BUSY); - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA); - } else { -- wed_w32(dev, MTK_WED_RESET_IDX, -- MTK_WED_RESET_IDX_TX | -- MTK_WED_RESET_IDX_RX); -+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX); - wed_w32(dev, MTK_WED_RESET_IDX, 0); - } - -- mtk_wdma_rx_reset(dev); -+ /* 2. reset WDMA rx DMA */ -+ busy = !!mtk_wdma_rx_reset(dev); -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); -+ if (!busy) -+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY); - - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); -@@ -1026,6 +1118,9 @@ mtk_wed_reset_dma(struct mtk_wed_device - MTK_WED_WDMA_GLO_CFG_RST_INIT_COMPLETE); - } - -+ /* 3. reset WED WPDMA tx */ -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -+ - for (i = 0; i < 100; i++) { - val = wed_r32(dev, MTK_WED_TX_BM_INTF); - if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40) -@@ -1033,8 +1128,19 @@ mtk_wed_reset_dma(struct mtk_wed_device - } - - mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT); -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_BM_EN); - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - -+ /* 4. reset WED WPDMA tx */ -+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY); -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -+ if (!busy) -+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY); -+ - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV); -@@ -1045,6 +1151,17 @@ mtk_wed_reset_dma(struct mtk_wed_device - MTK_WED_WPDMA_RESET_IDX_RX); - wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, 0); - } -+ -+ dev->init_done = false; -+ if (dev->hw->version == 1) -+ return; -+ -+ if (!busy) { -+ wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_WPDMA_IDX_RX); -+ wed_w32(dev, MTK_WED_RESET_IDX, 0); -+ } -+ -+ mtk_wed_rx_reset(dev); - } - - static int -@@ -1267,6 +1384,9 @@ mtk_wed_start(struct mtk_wed_device *dev - { - int i; - -+ if (mtk_wed_get_rx_capa(dev) && mtk_wed_rx_buffer_alloc(dev)) -+ return; -+ - for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) - if (!dev->rx_wdma[i].desc) - mtk_wed_wdma_rx_ring_setup(dev, i, 16); -@@ -1355,10 +1475,6 @@ mtk_wed_attach(struct mtk_wed_device *de - goto out; - - if (mtk_wed_get_rx_capa(dev)) { -- ret = mtk_wed_rx_buffer_alloc(dev); -- if (ret) -- goto out; -- - ret = mtk_wed_rro_alloc(dev); - if (ret) - goto out; ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -24,11 +24,15 @@ struct mtk_wdma_desc { - - #define MTK_WED_RESET 0x008 - #define MTK_WED_RESET_TX_BM BIT(0) -+#define MTK_WED_RESET_RX_BM BIT(1) - #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) - #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8) - #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9) -+#define MTK_WED_RESET_WPDMA_RX_D_DRV BIT(10) - #define MTK_WED_RESET_WPDMA_INT_AGENT BIT(11) - #define MTK_WED_RESET_WED_TX_DMA BIT(12) -+#define MTK_WED_RESET_WED_RX_DMA BIT(13) -+#define MTK_WED_RESET_WDMA_TX_DRV BIT(16) - #define MTK_WED_RESET_WDMA_RX_DRV BIT(17) - #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19) - #define MTK_WED_RESET_RX_RRO_QM BIT(20) -@@ -158,6 +162,8 @@ struct mtk_wdma_desc { - #define MTK_WED_RESET_IDX 0x20c - #define MTK_WED_RESET_IDX_TX GENMASK(3, 0) - #define MTK_WED_RESET_IDX_RX GENMASK(17, 16) -+#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6) -+#define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30) - - #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) - #define MTK_WED_RX_MIB(_n) (0x2e0 + (_n) * 4) -@@ -267,6 +273,9 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_RX_D_GLO_CFG 0x75c - #define MTK_WED_WPDMA_RX_D_RX_DRV_EN BIT(0) -+#define MTK_WED_WPDMA_RX_D_RX_DRV_BUSY BIT(1) -+#define MTK_WED_WPDMA_RX_D_FSM_RETURN_IDLE BIT(3) -+#define MTK_WED_WPDMA_RX_D_RST_INIT_COMPLETE BIT(4) - #define MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL GENMASK(11, 7) - #define MTK_WED_WPDMA_RX_D_RXD_READ_LEN GENMASK(31, 24) - diff --git a/target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch b/target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch deleted file mode 100644 index 4404971cc74dde..00000000000000 --- a/target/linux/generic/backport-6.1/729-14-v6.2-net-ethernet-mtk_wed-add-reset-to-tx_ring_setup-call.patch +++ /dev/null @@ -1,103 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Nov 2022 16:22:55 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add reset to tx_ring_setup callback - -Introduce reset parameter to mtk_wed_tx_ring_setup signature. -This is a preliminary patch to add Wireless Ethernet Dispatcher reset -support. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1181,7 +1181,8 @@ mtk_wed_ring_alloc(struct mtk_wed_device - } - - static int --mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size) -+mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size, -+ bool reset) - { - u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; - struct mtk_wed_ring *wdma; -@@ -1190,8 +1191,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we - return -EINVAL; - - wdma = &dev->rx_wdma[idx]; -- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, -- true)) -+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, -+ desc_size, true)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -@@ -1389,7 +1390,7 @@ mtk_wed_start(struct mtk_wed_device *dev - - for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) - if (!dev->rx_wdma[i].desc) -- mtk_wed_wdma_rx_ring_setup(dev, i, 16); -+ mtk_wed_wdma_rx_ring_setup(dev, i, 16, false); - - mtk_wed_hw_init(dev); - mtk_wed_configure_irq(dev, irq_mask); -@@ -1498,7 +1499,8 @@ unlock: - } - - static int --mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) -+mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs, -+ bool reset) - { - struct mtk_wed_ring *ring = &dev->tx_ring[idx]; - -@@ -1517,11 +1519,12 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - if (WARN_ON(idx >= ARRAY_SIZE(dev->tx_ring))) - return -EINVAL; - -- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, -- sizeof(*ring->desc), true)) -+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_TX_RING_SIZE, -+ sizeof(*ring->desc), true)) - return -ENOMEM; - -- if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, -+ reset)) - return -ENOMEM; - - ring->reg_base = MTK_WED_RING_TX(idx); ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -158,7 +158,7 @@ struct mtk_wed_device { - struct mtk_wed_ops { - int (*attach)(struct mtk_wed_device *dev); - int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, -- void __iomem *regs); -+ void __iomem *regs, bool reset); - int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, - void __iomem *regs); - int (*txfree_ring_setup)(struct mtk_wed_device *dev, -@@ -216,8 +216,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic - #define mtk_wed_device_active(_dev) !!(_dev)->ops - #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev) - #define mtk_wed_device_start(_dev, _mask) (_dev)->ops->start(_dev, _mask) --#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) \ -- (_dev)->ops->tx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) \ -+ (_dev)->ops->tx_ring_setup(_dev, _ring, _regs, _reset) - #define mtk_wed_device_txfree_ring_setup(_dev, _regs) \ - (_dev)->ops->txfree_ring_setup(_dev, _regs) - #define mtk_wed_device_reg_read(_dev, _reg) \ -@@ -243,7 +243,7 @@ static inline bool mtk_wed_device_active - } - #define mtk_wed_device_detach(_dev) do {} while (0) - #define mtk_wed_device_start(_dev, _mask) do {} while (0) --#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV - #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV - #define mtk_wed_device_reg_read(_dev, _reg) 0 - #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) diff --git a/target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch b/target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch deleted file mode 100644 index f9b11326b1c88e..00000000000000 --- a/target/linux/generic/backport-6.1/729-15-v6.2-net-ethernet-mtk_wed-fix-sleep-while-atomic-in-mtk_w.patch +++ /dev/null @@ -1,103 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 1 Dec 2022 16:26:53 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: fix sleep while atomic in - mtk_wed_wo_queue_refill - -In order to fix the following sleep while atomic bug always alloc pages -with GFP_ATOMIC in mtk_wed_wo_queue_refill since page_frag_alloc runs in -spin_lock critical section. - -[ 9.049719] Hardware name: MediaTek MT7986a RFB (DT) -[ 9.054665] Call trace: -[ 9.057096] dump_backtrace+0x0/0x154 -[ 9.060751] show_stack+0x14/0x1c -[ 9.064052] dump_stack_lvl+0x64/0x7c -[ 9.067702] dump_stack+0x14/0x2c -[ 9.071001] ___might_sleep+0xec/0x120 -[ 9.074736] __might_sleep+0x4c/0x9c -[ 9.078296] __alloc_pages+0x184/0x2e4 -[ 9.082030] page_frag_alloc_align+0x98/0x1ac -[ 9.086369] mtk_wed_wo_queue_refill+0x134/0x234 -[ 9.090974] mtk_wed_wo_init+0x174/0x2c0 -[ 9.094881] mtk_wed_attach+0x7c8/0x7e0 -[ 9.098701] mt7915_mmio_wed_init+0x1f0/0x3a0 [mt7915e] -[ 9.103940] mt7915_pci_probe+0xec/0x3bc [mt7915e] -[ 9.108727] pci_device_probe+0xac/0x13c -[ 9.112638] really_probe.part.0+0x98/0x2f4 -[ 9.116807] __driver_probe_device+0x94/0x13c -[ 9.121147] driver_probe_device+0x40/0x114 -[ 9.125314] __driver_attach+0x7c/0x180 -[ 9.129133] bus_for_each_dev+0x5c/0x90 -[ 9.132953] driver_attach+0x20/0x2c -[ 9.136513] bus_add_driver+0x104/0x1fc -[ 9.140333] driver_register+0x74/0x120 -[ 9.144153] __pci_register_driver+0x40/0x50 -[ 9.148407] mt7915_init+0x5c/0x1000 [mt7915e] -[ 9.152848] do_one_initcall+0x40/0x25c -[ 9.156669] do_init_module+0x44/0x230 -[ 9.160403] load_module+0x1f30/0x2750 -[ 9.164135] __do_sys_init_module+0x150/0x200 -[ 9.168475] __arm64_sys_init_module+0x18/0x20 -[ 9.172901] invoke_syscall.constprop.0+0x4c/0xe0 -[ 9.177589] do_el0_svc+0x48/0xe0 -[ 9.180889] el0_svc+0x14/0x50 -[ 9.183929] el0t_64_sync_handler+0x9c/0x120 -[ 9.188183] el0t_64_sync+0x158/0x15c - -Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Pavan Chebbi -Link: https://lore.kernel.org/r/67ca94bdd3d9eaeb86e52b3050fbca0bcf7bb02f.1669908312.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c -@@ -133,17 +133,18 @@ mtk_wed_wo_dequeue(struct mtk_wed_wo *wo - - static int - mtk_wed_wo_queue_refill(struct mtk_wed_wo *wo, struct mtk_wed_wo_queue *q, -- gfp_t gfp, bool rx) -+ bool rx) - { - enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - int n_buf = 0; - - spin_lock_bh(&q->lock); - while (q->queued < q->n_desc) { -- void *buf = page_frag_alloc(&q->cache, q->buf_size, gfp); - struct mtk_wed_wo_queue_entry *entry; - dma_addr_t addr; -+ void *buf; - -+ buf = page_frag_alloc(&q->cache, q->buf_size, GFP_ATOMIC); - if (!buf) - break; - -@@ -215,7 +216,7 @@ mtk_wed_wo_rx_run_queue(struct mtk_wed_w - mtk_wed_mcu_rx_unsolicited_event(wo, skb); - } - -- if (mtk_wed_wo_queue_refill(wo, q, GFP_ATOMIC, true)) { -+ if (mtk_wed_wo_queue_refill(wo, q, true)) { - u32 index = (q->head - 1) % q->n_desc; - - mtk_wed_wo_queue_kick(wo, q, index); -@@ -432,7 +433,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_ - if (ret) - goto error; - -- mtk_wed_wo_queue_refill(wo, &wo->q_tx, GFP_KERNEL, false); -+ mtk_wed_wo_queue_refill(wo, &wo->q_tx, false); - mtk_wed_wo_queue_reset(wo, &wo->q_tx); - - regs.desc_base = MTK_WED_WO_CCIF_DUMMY5; -@@ -446,7 +447,7 @@ mtk_wed_wo_hardware_init(struct mtk_wed_ - if (ret) - goto error; - -- mtk_wed_wo_queue_refill(wo, &wo->q_rx, GFP_KERNEL, true); -+ mtk_wed_wo_queue_refill(wo, &wo->q_rx, true); - mtk_wed_wo_queue_reset(wo, &wo->q_rx); - - /* rx queue irqmask */ diff --git a/target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch b/target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch deleted file mode 100644 index fa6f56dbe7249d..00000000000000 --- a/target/linux/generic/backport-6.1/729-16-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-rx-qu.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Lorenzo Bianconi -Date: Tue, 10 Jan 2023 10:31:26 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for rx queue - -Queue spinlock is currently held in mtk_wed_wo_queue_rx_clean and -mtk_wed_wo_queue_refill routines for MTK Wireless Ethernet Dispatcher -MCU rx queue. mtk_wed_wo_queue_refill() is running during initialization -and in rx tasklet while mtk_wed_wo_queue_rx_clean() is running in -mtk_wed_wo_hw_deinit() during hw de-init phase after rx tasklet has been -disabled. Since mtk_wed_wo_queue_rx_clean and mtk_wed_wo_queue_refill -routines can't run concurrently get rid of spinlock for mcu rx queue. - -Reviewed-by: Alexander Duyck -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/36ec3b729542ea60898471d890796f745479ba32.1673342990.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c -@@ -138,7 +138,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w - enum dma_data_direction dir = rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE; - int n_buf = 0; - -- spin_lock_bh(&q->lock); - while (q->queued < q->n_desc) { - struct mtk_wed_wo_queue_entry *entry; - dma_addr_t addr; -@@ -172,7 +171,6 @@ mtk_wed_wo_queue_refill(struct mtk_wed_w - q->queued++; - n_buf++; - } -- spin_unlock_bh(&q->lock); - - return n_buf; - } -@@ -316,7 +314,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed - { - struct page *page; - -- spin_lock_bh(&q->lock); - for (;;) { - void *buf = mtk_wed_wo_dequeue(wo, q, NULL, true); - -@@ -325,7 +322,6 @@ mtk_wed_wo_queue_rx_clean(struct mtk_wed - - skb_free_frag(buf); - } -- spin_unlock_bh(&q->lock); - - if (!q->cache.va) - return; diff --git a/target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch b/target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch deleted file mode 100644 index 9b1e4c3250705f..00000000000000 --- a/target/linux/generic/backport-6.1/729-17-v6.3-net-ethernet-mtk_wed-get-rid-of-queue-lock-for-tx-qu.patch +++ /dev/null @@ -1,75 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 12 Jan 2023 10:21:29 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: get rid of queue lock for tx queue - -Similar to MTK Wireless Ethernet Dispatcher (WED) MCU rx queue, -we do not need to protect WED MCU tx queue with a spin lock since -the tx queue is accessed in the two following routines: -- mtk_wed_wo_queue_tx_skb(): - it is run at initialization and during mt7915 normal operation. - Moreover MCU messages are serialized through MCU mutex. -- mtk_wed_wo_queue_tx_clean(): - it runs just at mt7915 driver module unload when no more messages - are sent to the MCU. - -Remove tx queue spinlock. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/7bd0337b2a13ab1a63673b7c03fd35206b3b284e.1673515140.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.c -@@ -258,7 +258,6 @@ mtk_wed_wo_queue_alloc(struct mtk_wed_wo - int n_desc, int buf_size, int index, - struct mtk_wed_wo_queue_regs *regs) - { -- spin_lock_init(&q->lock); - q->regs = *regs; - q->n_desc = n_desc; - q->buf_size = buf_size; -@@ -290,7 +289,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed - struct page *page; - int i; - -- spin_lock_bh(&q->lock); - for (i = 0; i < q->n_desc; i++) { - struct mtk_wed_wo_queue_entry *entry = &q->entry[i]; - -@@ -299,7 +297,6 @@ mtk_wed_wo_queue_tx_clean(struct mtk_wed - skb_free_frag(entry->buf); - entry->buf = NULL; - } -- spin_unlock_bh(&q->lock); - - if (!q->cache.va) - return; -@@ -347,8 +344,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w - int ret = 0, index; - u32 ctrl; - -- spin_lock_bh(&q->lock); -- - q->tail = mtk_wed_mmio_r32(wo, q->regs.dma_idx); - index = (q->head + 1) % q->n_desc; - if (q->tail == index) { -@@ -379,8 +374,6 @@ int mtk_wed_wo_queue_tx_skb(struct mtk_w - mtk_wed_wo_queue_kick(wo, q, q->head); - mtk_wed_wo_kickout(wo); - out: -- spin_unlock_bh(&q->lock); -- - dev_kfree_skb(skb); - - return ret; ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -211,7 +211,6 @@ struct mtk_wed_wo_queue { - struct mtk_wed_wo_queue_regs regs; - - struct page_frag_cache cache; -- spinlock_t lock; - - struct mtk_wed_wo_queue_desc *desc; - dma_addr_t desc_dma; diff --git a/target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch b/target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch deleted file mode 100644 index fde0af25df8af9..00000000000000 --- a/target/linux/generic/backport-6.1/729-18-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_reset-util.patch +++ /dev/null @@ -1,70 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 14 Jan 2023 18:01:28 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_reset utility - routine - -This is a preliminary patch to add Wireless Ethernet Dispatcher reset -support. - -Reviewed-by: Leon Romanovsky -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3255,6 +3255,27 @@ static void mtk_set_mcr_max_rx(struct mt - mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_hw_reset(struct mtk_eth *eth) -+{ -+ u32 val; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); -+ val = RSTCTRL_PPE0_V2; -+ } else { -+ val = RSTCTRL_PPE0; -+ } -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= RSTCTRL_PPE1; -+ -+ ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, -+ 0x3ffffff); -+} -+ - static int mtk_hw_init(struct mtk_eth *eth) - { - u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | -@@ -3294,22 +3315,9 @@ static int mtk_hw_init(struct mtk_eth *e - return 0; - } - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); -- val = RSTCTRL_PPE0_V2; -- } else { -- val = RSTCTRL_PPE0; -- } -- -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- val |= RSTCTRL_PPE1; -- -- ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); -+ mtk_hw_reset(eth); - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -- regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, -- 0x3ffffff); -- - /* Set FE to PDMAv2 if necessary */ - val = mtk_r32(eth, MTK_FE_GLO_MISC); - mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); diff --git a/target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch b/target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch deleted file mode 100644 index e6a94f616e39ef..00000000000000 --- a/target/linux/generic/backport-6.1/729-19-v6.3-net-ethernet-mtk_eth_soc-introduce-mtk_hw_warm_reset.patch +++ /dev/null @@ -1,107 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 14 Jan 2023 18:01:29 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: introduce mtk_hw_warm_reset - support - -Introduce mtk_hw_warm_reset utility routine. This is a preliminary patch -to align reset procedure to vendor sdk and avoid to power down the chip -during hw reset. - -Reviewed-by: Leon Romanovsky -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3276,7 +3276,54 @@ static void mtk_hw_reset(struct mtk_eth - 0x3ffffff); - } - --static int mtk_hw_init(struct mtk_eth *eth) -+static u32 mtk_hw_reset_read(struct mtk_eth *eth) -+{ -+ u32 val; -+ -+ regmap_read(eth->ethsys, ETHSYS_RSTCTRL, &val); -+ return val; -+} -+ -+static void mtk_hw_warm_reset(struct mtk_eth *eth) -+{ -+ u32 rst_mask, val; -+ -+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, RSTCTRL_FE, -+ RSTCTRL_FE); -+ if (readx_poll_timeout_atomic(mtk_hw_reset_read, eth, val, -+ val & RSTCTRL_FE, 1, 1000)) { -+ dev_err(eth->dev, "warm reset failed\n"); -+ mtk_hw_reset(eth); -+ return; -+ } -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; -+ else -+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ rst_mask |= RSTCTRL_PPE1; -+ -+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask); -+ -+ udelay(1); -+ val = mtk_hw_reset_read(eth); -+ if (!(val & rst_mask)) -+ dev_err(eth->dev, "warm reset stage0 failed %08x (%08x)\n", -+ val, rst_mask); -+ -+ rst_mask |= RSTCTRL_FE; -+ regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, ~rst_mask); -+ -+ udelay(1); -+ val = mtk_hw_reset_read(eth); -+ if (val & rst_mask) -+ dev_err(eth->dev, "warm reset stage1 failed %08x (%08x)\n", -+ val, rst_mask); -+} -+ -+static int mtk_hw_init(struct mtk_eth *eth, bool reset) - { - u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | - ETHSYS_DMA_AG_MAP_PPE; -@@ -3315,7 +3362,12 @@ static int mtk_hw_init(struct mtk_eth *e - return 0; - } - -- mtk_hw_reset(eth); -+ msleep(100); -+ -+ if (reset) -+ mtk_hw_warm_reset(eth); -+ else -+ mtk_hw_reset(eth); - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - /* Set FE to PDMAv2 if necessary */ -@@ -3506,7 +3558,7 @@ static void mtk_pending_work(struct work - if (eth->dev->pins) - pinctrl_select_state(eth->dev->pins->p, - eth->dev->pins->default_state); -- mtk_hw_init(eth); -+ mtk_hw_init(eth, true); - - /* restart DMA and enable IRQs */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -@@ -4108,7 +4160,7 @@ static int mtk_probe(struct platform_dev - eth->msg_enable = netif_msg_init(mtk_msg_level, MTK_DEFAULT_MSG_ENABLE); - INIT_WORK(ð->pending_work, mtk_pending_work); - -- err = mtk_hw_init(eth); -+ err = mtk_hw_init(eth, false); - if (err) - goto err_wed_exit; - diff --git a/target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch b/target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch deleted file mode 100644 index 7fdf7aa581edab..00000000000000 --- a/target/linux/generic/backport-6.1/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch +++ /dev/null @@ -1,262 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 14 Jan 2023 18:01:30 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: align reset procedure to vendor - sdk - -Avoid to power-down the ethernet chip during hw reset and align reset -procedure to vendor sdk. - -Reviewed-by: Leon Romanovsky -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -2843,14 +2843,29 @@ static void mtk_dma_free(struct mtk_eth - kfree(eth->scratch_head); - } - -+static bool mtk_hw_reset_check(struct mtk_eth *eth) -+{ -+ u32 val = mtk_r32(eth, MTK_INT_STATUS2); -+ -+ return (val & MTK_FE_INT_FQ_EMPTY) || (val & MTK_FE_INT_RFIFO_UF) || -+ (val & MTK_FE_INT_RFIFO_OV) || (val & MTK_FE_INT_TSO_FAIL) || -+ (val & MTK_FE_INT_TSO_ALIGN) || (val & MTK_FE_INT_TSO_ILLEGAL); -+} -+ - static void mtk_tx_timeout(struct net_device *dev, unsigned int txqueue) - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - -+ if (test_bit(MTK_RESETTING, ð->state)) -+ return; -+ -+ if (!mtk_hw_reset_check(eth)) -+ return; -+ - eth->netdev[mac->id]->stats.tx_errors++; -- netif_err(eth, tx_err, dev, -- "transmit timed out\n"); -+ netif_err(eth, tx_err, dev, "transmit timed out\n"); -+ - schedule_work(ð->pending_work); - } - -@@ -3330,15 +3345,17 @@ static int mtk_hw_init(struct mtk_eth *e - const struct mtk_reg_map *reg_map = eth->soc->reg_map; - int i, val, ret; - -- if (test_and_set_bit(MTK_HW_INIT, ð->state)) -+ if (!reset && test_and_set_bit(MTK_HW_INIT, ð->state)) - return 0; - -- pm_runtime_enable(eth->dev); -- pm_runtime_get_sync(eth->dev); -+ if (!reset) { -+ pm_runtime_enable(eth->dev); -+ pm_runtime_get_sync(eth->dev); - -- ret = mtk_clk_enable(eth); -- if (ret) -- goto err_disable_pm; -+ ret = mtk_clk_enable(eth); -+ if (ret) -+ goto err_disable_pm; -+ } - - if (eth->ethsys) - regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, dma_mask, -@@ -3467,8 +3484,10 @@ static int mtk_hw_init(struct mtk_eth *e - return 0; - - err_disable_pm: -- pm_runtime_put_sync(eth->dev); -- pm_runtime_disable(eth->dev); -+ if (!reset) { -+ pm_runtime_put_sync(eth->dev); -+ pm_runtime_disable(eth->dev); -+ } - - return ret; - } -@@ -3530,30 +3549,53 @@ static int mtk_do_ioctl(struct net_devic - return -EOPNOTSUPP; - } - -+static void mtk_prepare_for_reset(struct mtk_eth *eth) -+{ -+ u32 val; -+ int i; -+ -+ /* disabe FE P3 and P4 */ -+ val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= MTK_FE_LINK_DOWN_P4; -+ mtk_w32(eth, val, MTK_FE_GLO_CFG); -+ -+ /* adjust PPE configurations to prepare for reset */ -+ for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) -+ mtk_ppe_prepare_reset(eth->ppe[i]); -+ -+ /* disable NETSYS interrupts */ -+ mtk_w32(eth, 0, MTK_FE_INT_ENABLE); -+ -+ /* force link down GMAC */ -+ for (i = 0; i < 2; i++) { -+ val = mtk_r32(eth, MTK_MAC_MCR(i)) & ~MAC_MCR_FORCE_LINK; -+ mtk_w32(eth, val, MTK_MAC_MCR(i)); -+ } -+} -+ - static void mtk_pending_work(struct work_struct *work) - { - struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work); -- int err, i; - unsigned long restart = 0; -+ u32 val; -+ int i; - - rtnl_lock(); -- -- dev_dbg(eth->dev, "[%s][%d] reset\n", __func__, __LINE__); - set_bit(MTK_RESETTING, ð->state); - -+ mtk_prepare_for_reset(eth); -+ - /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!eth->netdev[i]) -+ if (!eth->netdev[i] || !netif_running(eth->netdev[i])) - continue; -+ - mtk_stop(eth->netdev[i]); - __set_bit(i, &restart); - } -- dev_dbg(eth->dev, "[%s][%d] mtk_stop ends\n", __func__, __LINE__); - -- /* restart underlying hardware such as power, clock, pin mux -- * and the connected phy -- */ -- mtk_hw_deinit(eth); -+ usleep_range(15000, 16000); - - if (eth->dev->pins) - pinctrl_select_state(eth->dev->pins->p, -@@ -3564,15 +3606,19 @@ static void mtk_pending_work(struct work - for (i = 0; i < MTK_MAC_COUNT; i++) { - if (!test_bit(i, &restart)) - continue; -- err = mtk_open(eth->netdev[i]); -- if (err) { -+ -+ if (mtk_open(eth->netdev[i])) { - netif_alert(eth, ifup, eth->netdev[i], -- "Driver up/down cycle failed, closing device.\n"); -+ "Driver up/down cycle failed\n"); - dev_close(eth->netdev[i]); - } - } - -- dev_dbg(eth->dev, "[%s][%d] reset done\n", __func__, __LINE__); -+ /* enabe FE P3 and P4 */ -+ val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val &= ~MTK_FE_LINK_DOWN_P4; -+ mtk_w32(eth, val, MTK_FE_GLO_CFG); - - clear_bit(MTK_RESETTING, ð->state); - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -72,12 +72,24 @@ - #define MTK_HW_LRO_REPLACE_DELTA 1000 - #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 - -+/* Frame Engine Global Configuration */ -+#define MTK_FE_GLO_CFG 0x00 -+#define MTK_FE_LINK_DOWN_P3 BIT(11) -+#define MTK_FE_LINK_DOWN_P4 BIT(12) -+ - /* Frame Engine Global Reset Register */ - #define MTK_RST_GL 0x04 - #define RST_GL_PSE BIT(0) - - /* Frame Engine Interrupt Status Register */ - #define MTK_INT_STATUS2 0x08 -+#define MTK_FE_INT_ENABLE 0x0c -+#define MTK_FE_INT_FQ_EMPTY BIT(8) -+#define MTK_FE_INT_TSO_FAIL BIT(12) -+#define MTK_FE_INT_TSO_ILLEGAL BIT(13) -+#define MTK_FE_INT_TSO_ALIGN BIT(14) -+#define MTK_FE_INT_RFIFO_OV BIT(18) -+#define MTK_FE_INT_RFIFO_UF BIT(19) - #define MTK_GDM1_AF BIT(28) - #define MTK_GDM2_AF BIT(29) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -710,6 +710,33 @@ int mtk_foe_entry_idle_time(struct mtk_p - return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); - } - -+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) -+{ -+ if (!ppe) -+ return -EINVAL; -+ -+ /* disable KA */ -+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE); -+ ppe_clear(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE); -+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0); -+ usleep_range(10000, 11000); -+ -+ /* set KA timer to maximum */ -+ ppe_set(ppe, MTK_PPE_BIND_LMT1, MTK_PPE_NTU_KEEPALIVE); -+ ppe_w32(ppe, MTK_PPE_KEEPALIVE, 0xffffffff); -+ -+ /* set KA tick select */ -+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_TICK_SEL); -+ ppe_set(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_KEEPALIVE); -+ usleep_range(10000, 11000); -+ -+ /* disable scan mode */ -+ ppe_clear(ppe, MTK_PPE_TB_CFG, MTK_PPE_TB_CFG_SCAN_MODE); -+ usleep_range(10000, 11000); -+ -+ return mtk_ppe_wait_busy(ppe); -+} -+ - struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, - int version, int index) - { ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -306,6 +306,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - void mtk_ppe_deinit(struct mtk_eth *eth); - void mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); -+int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -@@ -58,6 +58,12 @@ - #define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16) - #define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18) - #define MTK_PPE_TB_CFG_INFO_SEL BIT(20) -+#define MTK_PPE_TB_TICK_SEL BIT(24) -+ -+#define MTK_PPE_BIND_LMT1 0x230 -+#define MTK_PPE_NTU_KEEPALIVE GENMASK(23, 16) -+ -+#define MTK_PPE_KEEPALIVE 0x234 - - enum { - MTK_PPE_SCAN_MODE_DISABLED, diff --git a/target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch b/target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch deleted file mode 100644 index a77f3da7f8cd14..00000000000000 --- a/target/linux/generic/backport-6.1/729-21-v6.3-net-ethernet-mtk_eth_soc-add-dma-checks-to-mtk_hw_re.patch +++ /dev/null @@ -1,249 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 14 Jan 2023 18:01:31 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add dma checks to - mtk_hw_reset_check - -Introduce mtk_hw_check_dma_hang routine to monitor possible dma hangs. - -Reviewed-by: Leon Romanovsky -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -50,6 +50,7 @@ static const struct mtk_reg_map mtk_reg_ - .delay_irq = 0x0a0c, - .irq_status = 0x0a20, - .irq_mask = 0x0a28, -+ .adma_rx_dbg0 = 0x0a38, - .int_grp = 0x0a50, - }, - .qdma = { -@@ -79,6 +80,8 @@ static const struct mtk_reg_map mtk_reg_ - [0] = 0x2800, - [1] = 0x2c00, - }, -+ .pse_iq_sta = 0x0110, -+ .pse_oq_sta = 0x0118, - }; - - static const struct mtk_reg_map mt7628_reg_map = { -@@ -109,6 +112,7 @@ static const struct mtk_reg_map mt7986_r - .delay_irq = 0x620c, - .irq_status = 0x6220, - .irq_mask = 0x6228, -+ .adma_rx_dbg0 = 0x6238, - .int_grp = 0x6250, - }, - .qdma = { -@@ -138,6 +142,8 @@ static const struct mtk_reg_map mt7986_r - [0] = 0x4800, - [1] = 0x4c00, - }, -+ .pse_iq_sta = 0x0180, -+ .pse_oq_sta = 0x01a0, - }; - - /* strings used by ethtool */ -@@ -3338,6 +3344,102 @@ static void mtk_hw_warm_reset(struct mtk - val, rst_mask); - } - -+static bool mtk_hw_check_dma_hang(struct mtk_eth *eth) -+{ -+ const struct mtk_reg_map *reg_map = eth->soc->reg_map; -+ bool gmac1_tx, gmac2_tx, gdm1_tx, gdm2_tx; -+ bool oq_hang, cdm1_busy, adma_busy; -+ bool wtx_busy, cdm_full, oq_free; -+ u32 wdidx, val, gdm1_fc, gdm2_fc; -+ bool qfsm_hang, qfwd_hang; -+ bool ret = false; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) -+ return false; -+ -+ /* WDMA sanity checks */ -+ wdidx = mtk_r32(eth, reg_map->wdma_base[0] + 0xc); -+ -+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x204); -+ wtx_busy = FIELD_GET(MTK_TX_DMA_BUSY, val); -+ -+ val = mtk_r32(eth, reg_map->wdma_base[0] + 0x230); -+ cdm_full = !FIELD_GET(MTK_CDM_TXFIFO_RDY, val); -+ -+ oq_free = (!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(24, 16)) && -+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x4) & GENMASK(8, 0)) && -+ !(mtk_r32(eth, reg_map->pse_oq_sta + 0x10) & GENMASK(24, 16))); -+ -+ if (wdidx == eth->reset.wdidx && wtx_busy && cdm_full && oq_free) { -+ if (++eth->reset.wdma_hang_count > 2) { -+ eth->reset.wdma_hang_count = 0; -+ ret = true; -+ } -+ goto out; -+ } -+ -+ /* QDMA sanity checks */ -+ qfsm_hang = !!mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x234); -+ qfwd_hang = !mtk_r32(eth, reg_map->qdma.qtx_cfg + 0x308); -+ -+ gdm1_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM1_FSM)) > 0; -+ gdm2_tx = FIELD_GET(GENMASK(31, 16), mtk_r32(eth, MTK_FE_GDM2_FSM)) > 0; -+ gmac1_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(0))) != 1; -+ gmac2_tx = FIELD_GET(GENMASK(31, 24), mtk_r32(eth, MTK_MAC_FSM(1))) != 1; -+ gdm1_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x24); -+ gdm2_fc = mtk_r32(eth, reg_map->gdm1_cnt + 0x64); -+ -+ if (qfsm_hang && qfwd_hang && -+ ((gdm1_tx && gmac1_tx && gdm1_fc < 1) || -+ (gdm2_tx && gmac2_tx && gdm2_fc < 1))) { -+ if (++eth->reset.qdma_hang_count > 2) { -+ eth->reset.qdma_hang_count = 0; -+ ret = true; -+ } -+ goto out; -+ } -+ -+ /* ADMA sanity checks */ -+ oq_hang = !!(mtk_r32(eth, reg_map->pse_oq_sta) & GENMASK(8, 0)); -+ cdm1_busy = !!(mtk_r32(eth, MTK_FE_CDM1_FSM) & GENMASK(31, 16)); -+ adma_busy = !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & GENMASK(4, 0)) && -+ !(mtk_r32(eth, reg_map->pdma.adma_rx_dbg0) & BIT(6)); -+ -+ if (oq_hang && cdm1_busy && adma_busy) { -+ if (++eth->reset.adma_hang_count > 2) { -+ eth->reset.adma_hang_count = 0; -+ ret = true; -+ } -+ goto out; -+ } -+ -+ eth->reset.wdma_hang_count = 0; -+ eth->reset.qdma_hang_count = 0; -+ eth->reset.adma_hang_count = 0; -+out: -+ eth->reset.wdidx = wdidx; -+ -+ return ret; -+} -+ -+static void mtk_hw_reset_monitor_work(struct work_struct *work) -+{ -+ struct delayed_work *del_work = to_delayed_work(work); -+ struct mtk_eth *eth = container_of(del_work, struct mtk_eth, -+ reset.monitor_work); -+ -+ if (test_bit(MTK_RESETTING, ð->state)) -+ goto out; -+ -+ /* DMA stuck checks */ -+ if (mtk_hw_check_dma_hang(eth)) -+ schedule_work(ð->pending_work); -+ -+out: -+ schedule_delayed_work(ð->reset.monitor_work, -+ MTK_DMA_MONITOR_TIMEOUT); -+} -+ - static int mtk_hw_init(struct mtk_eth *eth, bool reset) - { - u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | -@@ -3656,6 +3758,7 @@ static int mtk_cleanup(struct mtk_eth *e - mtk_unreg_dev(eth); - mtk_free_dev(eth); - cancel_work_sync(ð->pending_work); -+ cancel_delayed_work_sync(ð->reset.monitor_work); - - return 0; - } -@@ -4093,6 +4196,7 @@ static int mtk_probe(struct platform_dev - - eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; - INIT_WORK(ð->rx_dim.work, mtk_dim_rx); -+ INIT_DELAYED_WORK(ð->reset.monitor_work, mtk_hw_reset_monitor_work); - - eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; - INIT_WORK(ð->tx_dim.work, mtk_dim_tx); -@@ -4295,6 +4399,8 @@ static int mtk_probe(struct platform_dev - netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx); - - platform_set_drvdata(pdev, eth); -+ schedule_delayed_work(ð->reset.monitor_work, -+ MTK_DMA_MONITOR_TIMEOUT); - - return 0; - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -257,6 +257,8 @@ - - #define MTK_RX_DONE_INT_V2 BIT(14) - -+#define MTK_CDM_TXFIFO_RDY BIT(7) -+ - /* QDMA Interrupt grouping registers */ - #define MTK_RLS_DONE_INT BIT(0) - -@@ -542,6 +544,17 @@ - #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) - #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) - -+#define MTK_FE_CDM1_FSM 0x220 -+#define MTK_FE_CDM2_FSM 0x224 -+#define MTK_FE_CDM3_FSM 0x238 -+#define MTK_FE_CDM4_FSM 0x298 -+#define MTK_FE_CDM5_FSM 0x318 -+#define MTK_FE_CDM6_FSM 0x328 -+#define MTK_FE_GDM1_FSM 0x228 -+#define MTK_FE_GDM2_FSM 0x22C -+ -+#define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) -+ - struct mtk_rx_dma { - unsigned int rxd1; - unsigned int rxd2; -@@ -938,6 +951,7 @@ struct mtk_reg_map { - u32 delay_irq; /* delay interrupt */ - u32 irq_status; /* interrupt status */ - u32 irq_mask; /* interrupt mask */ -+ u32 adma_rx_dbg0; - u32 int_grp; - } pdma; - struct { -@@ -964,6 +978,8 @@ struct mtk_reg_map { - u32 gdma_to_ppe; - u32 ppe_base; - u32 wdma_base[2]; -+ u32 pse_iq_sta; -+ u32 pse_oq_sta; - }; - - /* struct mtk_eth_data - This is the structure holding all differences -@@ -1006,6 +1022,8 @@ struct mtk_soc_data { - } txrx; - }; - -+#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) -+ - /* currently no SoC has more than 2 macs */ - #define MTK_MAX_DEVS 2 - -@@ -1128,6 +1146,14 @@ struct mtk_eth { - struct rhashtable flow_table; - - struct bpf_prog __rcu *prog; -+ -+ struct { -+ struct delayed_work monitor_work; -+ u32 wdidx; -+ u8 wdma_hang_count; -+ u8 qdma_hang_count; -+ u8 adma_hang_count; -+ } reset; - }; - - /* struct mtk_mac - the structure that holds the info about the MACs of the diff --git a/target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch b/target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch deleted file mode 100644 index 3f047da758920a..00000000000000 --- a/target/linux/generic/backport-6.1/729-22-v6.3-net-ethernet-mtk_wed-add-reset-reset_complete-callba.patch +++ /dev/null @@ -1,124 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 14 Jan 2023 18:01:32 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add reset/reset_complete callbacks - -Introduce reset and reset_complete wlan callback to schedule WLAN driver -reset when ethernet/wed driver is resetting. - -Tested-by: Daniel Golle -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3687,6 +3687,11 @@ static void mtk_pending_work(struct work - set_bit(MTK_RESETTING, ð->state); - - mtk_prepare_for_reset(eth); -+ mtk_wed_fe_reset(); -+ /* Run again reset preliminary configuration in order to avoid any -+ * possible race during FE reset since it can run releasing RTNL lock. -+ */ -+ mtk_prepare_for_reset(eth); - - /* stop all devices to make sure that dma is properly shut down */ - for (i = 0; i < MTK_MAC_COUNT; i++) { -@@ -3724,6 +3729,8 @@ static void mtk_pending_work(struct work - - clear_bit(MTK_RESETTING, ð->state); - -+ mtk_wed_fe_reset_complete(); -+ - rtnl_unlock(); - } - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -205,6 +205,48 @@ mtk_wed_wo_reset(struct mtk_wed_device * - iounmap(reg); - } - -+void mtk_wed_fe_reset(void) -+{ -+ int i; -+ -+ mutex_lock(&hw_lock); -+ -+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { -+ struct mtk_wed_hw *hw = hw_list[i]; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ int err; -+ -+ if (!dev || !dev->wlan.reset) -+ continue; -+ -+ /* reset callback blocks until WLAN reset is completed */ -+ err = dev->wlan.reset(dev); -+ if (err) -+ dev_err(dev->dev, "wlan reset failed: %d\n", err); -+ } -+ -+ mutex_unlock(&hw_lock); -+} -+ -+void mtk_wed_fe_reset_complete(void) -+{ -+ int i; -+ -+ mutex_lock(&hw_lock); -+ -+ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { -+ struct mtk_wed_hw *hw = hw_list[i]; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (!dev || !dev->wlan.reset_complete) -+ continue; -+ -+ dev->wlan.reset_complete(dev); -+ } -+ -+ mutex_unlock(&hw_lock); -+} -+ - static struct mtk_wed_hw * - mtk_wed_assign(struct mtk_wed_device *dev) - { ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -128,6 +128,8 @@ void mtk_wed_add_hw(struct device_node * - void mtk_wed_exit(void); - int mtk_wed_flow_add(int index); - void mtk_wed_flow_remove(int index); -+void mtk_wed_fe_reset(void); -+void mtk_wed_fe_reset_complete(void); - #else - static inline void - mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, -@@ -147,6 +149,13 @@ static inline void mtk_wed_flow_remove(i - { - } - -+static inline void mtk_wed_fe_reset(void) -+{ -+} -+ -+static inline void mtk_wed_fe_reset_complete(void) -+{ -+} - #endif - - #ifdef CONFIG_DEBUG_FS ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -151,6 +151,8 @@ struct mtk_wed_device { - void (*release_rx_buf)(struct mtk_wed_device *wed); - void (*update_wo_rx_stats)(struct mtk_wed_device *wed, - struct mtk_wed_wo_rx_stats *stats); -+ int (*reset)(struct mtk_wed_device *wed); -+ void (*reset_complete)(struct mtk_wed_device *wed); - } wlan; - #endif - }; diff --git a/target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch b/target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch deleted file mode 100644 index c63628da99da81..00000000000000 --- a/target/linux/generic/backport-6.1/729-23-v6.3-net-ethernet-mtk_wed-add-reset-to-rx_ring_setup-call.patch +++ /dev/null @@ -1,106 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 5 Dec 2022 12:34:42 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: add reset to rx_ring_setup callback - -This patch adds reset parameter to mtk_wed_rx_ring_setup signature -in order to align rx_ring_setup callback to tx_ring_setup one introduced -in 'commit 23dca7a90017 ("net: ethernet: mtk_wed: add reset to -tx_ring_setup callback")' - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Leon Romanovsky -Link: https://lore.kernel.org/r/29c6e7a5469e784406cf3e2920351d1207713d05.1670239984.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1252,7 +1252,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we - } - - static int --mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size) -+mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size, -+ bool reset) - { - u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; - struct mtk_wed_ring *wdma; -@@ -1261,8 +1262,8 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we - return -EINVAL; - - wdma = &dev->tx_wdma[idx]; -- if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, desc_size, -- true)) -+ if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, -+ desc_size, true)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, -@@ -1272,6 +1273,9 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_CPU_IDX, 0); - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0); - -+ if (reset) -+ mtk_wed_ring_reset(wdma, MTK_WED_WDMA_RING_SIZE, true); -+ - if (!idx) { - wed_w32(dev, MTK_WED_WDMA_RING_TX + MTK_WED_RING_OFS_BASE, - wdma->desc_phys); -@@ -1611,18 +1615,20 @@ mtk_wed_txfree_ring_setup(struct mtk_wed - } - - static int --mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) -+mtk_wed_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs, -+ bool reset) - { - struct mtk_wed_ring *ring = &dev->rx_ring[idx]; - - if (WARN_ON(idx >= ARRAY_SIZE(dev->rx_ring))) - return -EINVAL; - -- if (mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, -- sizeof(*ring->desc), false)) -+ if (!reset && mtk_wed_ring_alloc(dev, ring, MTK_WED_RX_RING_SIZE, -+ sizeof(*ring->desc), false)) - return -ENOMEM; - -- if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE)) -+ if (mtk_wed_wdma_tx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, -+ reset)) - return -ENOMEM; - - ring->reg_base = MTK_WED_RING_RX_DATA(idx); ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -162,7 +162,7 @@ struct mtk_wed_ops { - int (*tx_ring_setup)(struct mtk_wed_device *dev, int ring, - void __iomem *regs, bool reset); - int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring, -- void __iomem *regs); -+ void __iomem *regs, bool reset); - int (*txfree_ring_setup)(struct mtk_wed_device *dev, - void __iomem *regs); - int (*msg_update)(struct mtk_wed_device *dev, int cmd_id, -@@ -230,8 +230,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic - (_dev)->ops->irq_get(_dev, _mask) - #define mtk_wed_device_irq_set_mask(_dev, _mask) \ - (_dev)->ops->irq_set_mask(_dev, _mask) --#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) \ -- (_dev)->ops->rx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \ -+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset) - #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \ - (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash) - #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \ -@@ -251,7 +251,7 @@ static inline bool mtk_wed_device_active - #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0) - #define mtk_wed_device_irq_get(_dev, _mask) 0 - #define mtk_wed_device_irq_set_mask(_dev, _mask) do {} while (0) --#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV - #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) do {} while (0) - #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV - #define mtk_wed_device_stop(_dev) do {} while (0) diff --git a/target/linux/generic/backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch b/target/linux/generic/backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch deleted file mode 100644 index 45af898cf003b8..00000000000000 --- a/target/linux/generic/backport-6.1/730-01-v6.3-net-ethernet-mtk_eth_soc-account-for-vlan-in-rx-head.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Date: Thu, 27 Oct 2022 19:50:31 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: account for vlan in rx - header length - -The network stack assumes that devices can handle an extra VLAN tag without -increasing the MTU - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -29,7 +29,7 @@ - #define MTK_TX_DMA_BUF_LEN_V2 0xffff - #define MTK_DMA_SIZE 512 - #define MTK_MAC_COUNT 2 --#define MTK_RX_ETH_HLEN (ETH_HLEN + ETH_FCS_LEN) -+#define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN) - #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN) - #define MTK_DMA_DUMMY_DESC 0xffffffff - #define MTK_DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | \ diff --git a/target/linux/generic/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch b/target/linux/generic/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch deleted file mode 100644 index 41d1bceac447fe..00000000000000 --- a/target/linux/generic/backport-6.1/730-02-v6.3-net-ethernet-mtk_eth_soc-increase-tx-ring-side-for-Q.patch +++ /dev/null @@ -1,143 +0,0 @@ -From: Felix Fietkau -Date: Thu, 27 Oct 2022 19:53:57 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: increase tx ring side for - QDMA devices - -In order to use the hardware traffic shaper feature, a larger tx ring is -needed, especially for the scratch ring, which the hardware shaper uses to -reorder packets. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -943,7 +943,7 @@ static int mtk_init_fq_dma(struct mtk_et - { - const struct mtk_soc_data *soc = eth->soc; - dma_addr_t phy_ring_tail; -- int cnt = MTK_DMA_SIZE; -+ int cnt = MTK_QDMA_RING_SIZE; - dma_addr_t dma_addr; - int i; - -@@ -2207,19 +2207,25 @@ static int mtk_tx_alloc(struct mtk_eth * - struct mtk_tx_ring *ring = ð->tx_ring; - int i, sz = soc->txrx.txd_size; - struct mtk_tx_dma_v2 *txd; -+ int ring_size; - -- ring->buf = kcalloc(MTK_DMA_SIZE, sizeof(*ring->buf), -+ if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) -+ ring_size = MTK_QDMA_RING_SIZE; -+ else -+ ring_size = MTK_DMA_SIZE; -+ -+ ring->buf = kcalloc(ring_size, sizeof(*ring->buf), - GFP_KERNEL); - if (!ring->buf) - goto no_tx_mem; - -- ring->dma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, -+ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, - &ring->phys, GFP_KERNEL); - if (!ring->dma) - goto no_tx_mem; - -- for (i = 0; i < MTK_DMA_SIZE; i++) { -- int next = (i + 1) % MTK_DMA_SIZE; -+ for (i = 0; i < ring_size; i++) { -+ int next = (i + 1) % ring_size; - u32 next_ptr = ring->phys + next * sz; - - txd = ring->dma + i * sz; -@@ -2239,22 +2245,22 @@ static int mtk_tx_alloc(struct mtk_eth * - * descriptors in ring->dma_pdma. - */ - if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { -- ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, MTK_DMA_SIZE * sz, -+ ring->dma_pdma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, - &ring->phys_pdma, GFP_KERNEL); - if (!ring->dma_pdma) - goto no_tx_mem; - -- for (i = 0; i < MTK_DMA_SIZE; i++) { -+ for (i = 0; i < ring_size; i++) { - ring->dma_pdma[i].txd2 = TX_DMA_DESP2_DEF; - ring->dma_pdma[i].txd4 = 0; - } - } - -- ring->dma_size = MTK_DMA_SIZE; -- atomic_set(&ring->free_count, MTK_DMA_SIZE - 2); -+ ring->dma_size = ring_size; -+ atomic_set(&ring->free_count, ring_size - 2); - ring->next_free = ring->dma; - ring->last_free = (void *)txd; -- ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz)); -+ ring->last_free_ptr = (u32)(ring->phys + ((ring_size - 1) * sz)); - ring->thresh = MAX_SKB_FRAGS; - - /* make sure that all changes to the dma ring are flushed before we -@@ -2266,14 +2272,14 @@ static int mtk_tx_alloc(struct mtk_eth * - mtk_w32(eth, ring->phys, soc->reg_map->qdma.ctx_ptr); - mtk_w32(eth, ring->phys, soc->reg_map->qdma.dtx_ptr); - mtk_w32(eth, -- ring->phys + ((MTK_DMA_SIZE - 1) * sz), -+ ring->phys + ((ring_size - 1) * sz), - soc->reg_map->qdma.crx_ptr); - mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr); - mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, - soc->reg_map->qdma.qtx_cfg); - } else { - mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); -- mtk_w32(eth, MTK_DMA_SIZE, MT7628_TX_MAX_CNT0); -+ mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0); - mtk_w32(eth, 0, MT7628_TX_CTX_IDX0); - mtk_w32(eth, MT7628_PST_DTX_IDX0, soc->reg_map->pdma.rst_idx); - } -@@ -2291,7 +2297,7 @@ static void mtk_tx_clean(struct mtk_eth - int i; - - if (ring->buf) { -- for (i = 0; i < MTK_DMA_SIZE; i++) -+ for (i = 0; i < ring->dma_size; i++) - mtk_tx_unmap(eth, &ring->buf[i], NULL, false); - kfree(ring->buf); - ring->buf = NULL; -@@ -2299,14 +2305,14 @@ static void mtk_tx_clean(struct mtk_eth - - if (ring->dma) { - dma_free_coherent(eth->dma_dev, -- MTK_DMA_SIZE * soc->txrx.txd_size, -+ ring->dma_size * soc->txrx.txd_size, - ring->dma, ring->phys); - ring->dma = NULL; - } - - if (ring->dma_pdma) { - dma_free_coherent(eth->dma_dev, -- MTK_DMA_SIZE * soc->txrx.txd_size, -+ ring->dma_size * soc->txrx.txd_size, - ring->dma_pdma, ring->phys_pdma); - ring->dma_pdma = NULL; - } -@@ -2831,7 +2837,7 @@ static void mtk_dma_free(struct mtk_eth - netdev_reset_queue(eth->netdev[i]); - if (eth->scratch_ring) { - dma_free_coherent(eth->dma_dev, -- MTK_DMA_SIZE * soc->txrx.txd_size, -+ MTK_QDMA_RING_SIZE * soc->txrx.txd_size, - eth->scratch_ring, eth->phy_scratch_ring); - eth->scratch_ring = NULL; - eth->phy_scratch_ring = 0; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -27,6 +27,7 @@ - #define MTK_MAX_RX_LENGTH_2K 2048 - #define MTK_TX_DMA_BUF_LEN 0x3fff - #define MTK_TX_DMA_BUF_LEN_V2 0xffff -+#define MTK_QDMA_RING_SIZE 2048 - #define MTK_DMA_SIZE 512 - #define MTK_MAC_COUNT 2 - #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN) diff --git a/target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch b/target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch deleted file mode 100644 index c9823daa1d2eb4..00000000000000 --- a/target/linux/generic/backport-6.1/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Felix Fietkau -Date: Fri, 4 Nov 2022 19:49:08 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: avoid port_mg assignment on - MT7622 and newer - -On newer chips, this field is unused and contains some bits related to queue -assignment. Initialize it to 0 in those cases. -Fix offload_version on MT7621 and MT7623, which still need the previous value. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4478,7 +4478,7 @@ static const struct mtk_soc_data mt7621_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7621_CLKS_BITMAP, - .required_pctl = false, -- .offload_version = 2, -+ .offload_version = 1, - .hash_offset = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { -@@ -4517,7 +4517,7 @@ static const struct mtk_soc_data mt7623_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, -- .offload_version = 2, -+ .offload_version = 1, - .hash_offset = 2, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -175,6 +175,8 @@ int mtk_foe_entry_prepare(struct mtk_eth - val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, pse_port) | - FIELD_PREP(MTK_FOE_IB2_PORT_AG_V2, 0xf); - } else { -+ int port_mg = eth->soc->offload_version > 1 ? 0 : 0x3f; -+ - val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | - FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | - FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | -@@ -182,7 +184,7 @@ int mtk_foe_entry_prepare(struct mtk_eth - entry->ib1 = val; - - val = FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port) | -- FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | -+ FIELD_PREP(MTK_FOE_IB2_PORT_MG, port_mg) | - FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f); - } - diff --git a/target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch b/target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch deleted file mode 100644 index 0d462b0c85ffed..00000000000000 --- a/target/linux/generic/backport-6.1/730-04-v6.3-net-ethernet-mtk_eth_soc-implement-multi-queue-suppo.patch +++ /dev/null @@ -1,654 +0,0 @@ -From: Felix Fietkau -Date: Thu, 27 Oct 2022 20:17:27 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: implement multi-queue - support for per-port queues - -When sending traffic to multiple ports with different link speeds, queued -packets to one port can drown out tx to other ports. -In order to better handle transmission to multiple ports, use the hardware -shaper feature to implement weighted fair queueing between ports. -Weight and maximum rate are automatically adjusted based on the link speed -of the port. -The first 3 queues are unrestricted and reserved for non-DSA direct tx on -GMAC ports. The following queues are automatically assigned by the MTK DSA -tag driver based on the target port number. -The PPE offload code configures the queues for offloaded traffic in the same -way. -This feature is only supported on devices supporting QDMA. All queues still -share the same DMA ring and descriptor pool. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -55,6 +55,7 @@ static const struct mtk_reg_map mtk_reg_ - }, - .qdma = { - .qtx_cfg = 0x1800, -+ .qtx_sch = 0x1804, - .rx_ptr = 0x1900, - .rx_cnt_cfg = 0x1904, - .qcrx_ptr = 0x1908, -@@ -62,6 +63,7 @@ static const struct mtk_reg_map mtk_reg_ - .rst_idx = 0x1a08, - .delay_irq = 0x1a0c, - .fc_th = 0x1a10, -+ .tx_sch_rate = 0x1a14, - .int_grp = 0x1a20, - .hred = 0x1a44, - .ctx_ptr = 0x1b00, -@@ -117,6 +119,7 @@ static const struct mtk_reg_map mt7986_r - }, - .qdma = { - .qtx_cfg = 0x4400, -+ .qtx_sch = 0x4404, - .rx_ptr = 0x4500, - .rx_cnt_cfg = 0x4504, - .qcrx_ptr = 0x4508, -@@ -134,6 +137,7 @@ static const struct mtk_reg_map mt7986_r - .fq_tail = 0x4724, - .fq_count = 0x4728, - .fq_blen = 0x472c, -+ .tx_sch_rate = 0x4798, - }, - .gdm1_cnt = 0x1c00, - .gdma_to_ppe = 0x3333, -@@ -619,6 +623,75 @@ static void mtk_mac_link_down(struct phy - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, -+ int speed) -+{ -+ const struct mtk_soc_data *soc = eth->soc; -+ u32 ofs, val; -+ -+ if (!MTK_HAS_CAPS(soc->caps, MTK_QDMA)) -+ return; -+ -+ val = MTK_QTX_SCH_MIN_RATE_EN | -+ /* minimum: 10 Mbps */ -+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | -+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | -+ MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; -+ -+ if (IS_ENABLED(CONFIG_SOC_MT7621)) { -+ switch (speed) { -+ case SPEED_10: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 2) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); -+ break; -+ case SPEED_100: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 103) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 3); -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); -+ break; -+ case SPEED_1000: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 105) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10); -+ break; -+ default: -+ break; -+ } -+ } else { -+ switch (speed) { -+ case SPEED_10: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 4) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); -+ break; -+ case SPEED_100: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 1) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5); -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 1); -+ break; -+ case SPEED_1000: -+ val |= MTK_QTX_SCH_MAX_RATE_EN | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_MAN, 10) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_EXP, 5) | -+ FIELD_PREP(MTK_QTX_SCH_MAX_RATE_WEIGHT, 10); -+ break; -+ default: -+ break; -+ } -+ } -+ -+ ofs = MTK_QTX_OFFSET * idx; -+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); -+} -+ - static void mtk_mac_link_up(struct phylink_config *config, - struct phy_device *phy, - unsigned int mode, phy_interface_t interface, -@@ -644,6 +717,8 @@ static void mtk_mac_link_up(struct phyli - break; - } - -+ mtk_set_queue_speed(mac->hw, mac->id, speed); -+ - /* Configure duplex */ - if (duplex == DUPLEX_FULL) - mcr |= MAC_MCR_FORCE_DPX; -@@ -1104,7 +1179,8 @@ static void mtk_tx_set_dma_desc_v1(struc - - WRITE_ONCE(desc->txd1, info->addr); - -- data = TX_DMA_SWC | TX_DMA_PLEN0(info->size); -+ data = TX_DMA_SWC | TX_DMA_PLEN0(info->size) | -+ FIELD_PREP(TX_DMA_PQID, info->qid); - if (info->last) - data |= TX_DMA_LS0; - WRITE_ONCE(desc->txd3, data); -@@ -1138,9 +1214,6 @@ static void mtk_tx_set_dma_desc_v2(struc - data |= TX_DMA_LS0; - WRITE_ONCE(desc->txd3, data); - -- if (!info->qid && mac->id) -- info->qid = MTK_QDMA_GMAC2_QID; -- - data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ - data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); - WRITE_ONCE(desc->txd4, data); -@@ -1184,11 +1257,12 @@ static int mtk_tx_map(struct sk_buff *sk - .gso = gso, - .csum = skb->ip_summed == CHECKSUM_PARTIAL, - .vlan = skb_vlan_tag_present(skb), -- .qid = skb->mark & MTK_QDMA_TX_MASK, -+ .qid = skb_get_queue_mapping(skb), - .vlan_tci = skb_vlan_tag_get(skb), - .first = true, - .last = !skb_is_nonlinear(skb), - }; -+ struct netdev_queue *txq; - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - const struct mtk_soc_data *soc = eth->soc; -@@ -1196,8 +1270,10 @@ static int mtk_tx_map(struct sk_buff *sk - struct mtk_tx_dma *itxd_pdma, *txd_pdma; - struct mtk_tx_buf *itx_buf, *tx_buf; - int i, n_desc = 1; -+ int queue = skb_get_queue_mapping(skb); - int k = 0; - -+ txq = netdev_get_tx_queue(dev, queue); - itxd = ring->next_free; - itxd_pdma = qdma_to_pdma(ring, itxd); - if (itxd == ring->last_free) -@@ -1246,7 +1322,7 @@ static int mtk_tx_map(struct sk_buff *sk - memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); - txd_info.size = min_t(unsigned int, frag_size, - soc->txrx.dma_max_len); -- txd_info.qid = skb->mark & MTK_QDMA_TX_MASK; -+ txd_info.qid = queue; - txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 && - !(frag_size - txd_info.size); - txd_info.addr = skb_frag_dma_map(eth->dma_dev, frag, -@@ -1285,7 +1361,7 @@ static int mtk_tx_map(struct sk_buff *sk - txd_pdma->txd2 |= TX_DMA_LS1; - } - -- netdev_sent_queue(dev, skb->len); -+ netdev_tx_sent_queue(txq, skb->len); - skb_tx_timestamp(skb); - - ring->next_free = mtk_qdma_phys_to_virt(ring, txd->txd2); -@@ -1297,8 +1373,7 @@ static int mtk_tx_map(struct sk_buff *sk - wmb(); - - if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) { -- if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || -- !netdev_xmit_more()) -+ if (netif_xmit_stopped(txq) || !netdev_xmit_more()) - mtk_w32(eth, txd->txd2, soc->reg_map->qdma.ctx_ptr); - } else { - int next_idx; -@@ -1367,7 +1442,7 @@ static void mtk_wake_queue(struct mtk_et - for (i = 0; i < MTK_MAC_COUNT; i++) { - if (!eth->netdev[i]) - continue; -- netif_wake_queue(eth->netdev[i]); -+ netif_tx_wake_all_queues(eth->netdev[i]); - } - } - -@@ -1391,7 +1466,7 @@ static netdev_tx_t mtk_start_xmit(struct - - tx_num = mtk_cal_txd_req(eth, skb); - if (unlikely(atomic_read(&ring->free_count) <= tx_num)) { -- netif_stop_queue(dev); -+ netif_tx_stop_all_queues(dev); - netif_err(eth, tx_queued, dev, - "Tx Ring full when queue awake!\n"); - spin_unlock(ð->page_lock); -@@ -1417,7 +1492,7 @@ static netdev_tx_t mtk_start_xmit(struct - goto drop; - - if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) -- netif_stop_queue(dev); -+ netif_tx_stop_all_queues(dev); - - spin_unlock(ð->page_lock); - -@@ -1584,10 +1659,12 @@ static int mtk_xdp_submit_frame(struct m - struct skb_shared_info *sinfo = xdp_get_shared_info_from_frame(xdpf); - const struct mtk_soc_data *soc = eth->soc; - struct mtk_tx_ring *ring = ð->tx_ring; -+ struct mtk_mac *mac = netdev_priv(dev); - struct mtk_tx_dma_desc_info txd_info = { - .size = xdpf->len, - .first = true, - .last = !xdp_frame_has_frags(xdpf), -+ .qid = mac->id, - }; - int err, index = 0, n_desc = 1, nr_frags; - struct mtk_tx_buf *htx_buf, *tx_buf; -@@ -1637,6 +1714,7 @@ static int mtk_xdp_submit_frame(struct m - memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); - txd_info.size = skb_frag_size(&sinfo->frags[index]); - txd_info.last = index + 1 == nr_frags; -+ txd_info.qid = mac->id; - data = skb_frag_address(&sinfo->frags[index]); - - index++; -@@ -1991,8 +2069,46 @@ rx_done: - return done; - } - -+struct mtk_poll_state { -+ struct netdev_queue *txq; -+ unsigned int total; -+ unsigned int done; -+ unsigned int bytes; -+}; -+ -+static void -+mtk_poll_tx_done(struct mtk_eth *eth, struct mtk_poll_state *state, u8 mac, -+ struct sk_buff *skb) -+{ -+ struct netdev_queue *txq; -+ struct net_device *dev; -+ unsigned int bytes = skb->len; -+ -+ state->total++; -+ eth->tx_packets++; -+ eth->tx_bytes += bytes; -+ -+ dev = eth->netdev[mac]; -+ if (!dev) -+ return; -+ -+ txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); -+ if (state->txq == txq) { -+ state->done++; -+ state->bytes += bytes; -+ return; -+ } -+ -+ if (state->txq) -+ netdev_tx_completed_queue(state->txq, state->done, state->bytes); -+ -+ state->txq = txq; -+ state->done = 1; -+ state->bytes = bytes; -+} -+ - static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget, -- unsigned int *done, unsigned int *bytes) -+ struct mtk_poll_state *state) - { - const struct mtk_reg_map *reg_map = eth->soc->reg_map; - struct mtk_tx_ring *ring = ð->tx_ring; -@@ -2024,12 +2140,9 @@ static int mtk_poll_tx_qdma(struct mtk_e - break; - - if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -- if (tx_buf->type == MTK_TYPE_SKB) { -- struct sk_buff *skb = tx_buf->data; -+ if (tx_buf->type == MTK_TYPE_SKB) -+ mtk_poll_tx_done(eth, state, mac, tx_buf->data); - -- bytes[mac] += skb->len; -- done[mac]++; -- } - budget--; - } - mtk_tx_unmap(eth, tx_buf, &bq, true); -@@ -2048,7 +2161,7 @@ static int mtk_poll_tx_qdma(struct mtk_e - } - - static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget, -- unsigned int *done, unsigned int *bytes) -+ struct mtk_poll_state *state) - { - struct mtk_tx_ring *ring = ð->tx_ring; - struct mtk_tx_buf *tx_buf; -@@ -2066,12 +2179,8 @@ static int mtk_poll_tx_pdma(struct mtk_e - break; - - if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { -- if (tx_buf->type == MTK_TYPE_SKB) { -- struct sk_buff *skb = tx_buf->data; -- -- bytes[0] += skb->len; -- done[0]++; -- } -+ if (tx_buf->type == MTK_TYPE_SKB) -+ mtk_poll_tx_done(eth, state, 0, tx_buf->data); - budget--; - } - mtk_tx_unmap(eth, tx_buf, &bq, true); -@@ -2093,26 +2202,15 @@ static int mtk_poll_tx(struct mtk_eth *e - { - struct mtk_tx_ring *ring = ð->tx_ring; - struct dim_sample dim_sample = {}; -- unsigned int done[MTK_MAX_DEVS]; -- unsigned int bytes[MTK_MAX_DEVS]; -- int total = 0, i; -- -- memset(done, 0, sizeof(done)); -- memset(bytes, 0, sizeof(bytes)); -+ struct mtk_poll_state state = {}; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -- budget = mtk_poll_tx_qdma(eth, budget, done, bytes); -+ budget = mtk_poll_tx_qdma(eth, budget, &state); - else -- budget = mtk_poll_tx_pdma(eth, budget, done, bytes); -+ budget = mtk_poll_tx_pdma(eth, budget, &state); - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!eth->netdev[i] || !done[i]) -- continue; -- netdev_completed_queue(eth->netdev[i], done[i], bytes[i]); -- total += done[i]; -- eth->tx_packets += done[i]; -- eth->tx_bytes += bytes[i]; -- } -+ if (state.txq) -+ netdev_tx_completed_queue(state.txq, state.done, state.bytes); - - dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes, - &dim_sample); -@@ -2122,7 +2220,7 @@ static int mtk_poll_tx(struct mtk_eth *e - (atomic_read(&ring->free_count) > ring->thresh)) - mtk_wake_queue(eth); - -- return total; -+ return state.total; - } - - static void mtk_handle_status_irq(struct mtk_eth *eth) -@@ -2208,6 +2306,7 @@ static int mtk_tx_alloc(struct mtk_eth * - int i, sz = soc->txrx.txd_size; - struct mtk_tx_dma_v2 *txd; - int ring_size; -+ u32 ofs, val; - - if (MTK_HAS_CAPS(soc->caps, MTK_QDMA)) - ring_size = MTK_QDMA_RING_SIZE; -@@ -2275,8 +2374,25 @@ static int mtk_tx_alloc(struct mtk_eth * - ring->phys + ((ring_size - 1) * sz), - soc->reg_map->qdma.crx_ptr); - mtk_w32(eth, ring->last_free_ptr, soc->reg_map->qdma.drx_ptr); -- mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, -- soc->reg_map->qdma.qtx_cfg); -+ -+ for (i = 0, ofs = 0; i < MTK_QDMA_NUM_QUEUES; i++) { -+ val = (QDMA_RES_THRES << 8) | QDMA_RES_THRES; -+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_cfg + ofs); -+ -+ val = MTK_QTX_SCH_MIN_RATE_EN | -+ /* minimum: 10 Mbps */ -+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | -+ FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | -+ MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; -+ mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); -+ ofs += MTK_QTX_OFFSET; -+ } -+ val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16); -+ mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4); - } else { - mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); - mtk_w32(eth, ring_size, MT7628_TX_MAX_CNT0); -@@ -2961,7 +3077,7 @@ static int mtk_start_dma(struct mtk_eth - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) - val |= MTK_MUTLI_CNT | MTK_RESV_BUF | - MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | -- MTK_CHK_DDONE_EN; -+ MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; - else - val |= MTK_RX_BT_32DWORDS; - mtk_w32(eth, val, reg_map->qdma.glo_cfg); -@@ -3007,6 +3123,45 @@ static void mtk_gdm_config(struct mtk_et - mtk_w32(eth, 0, MTK_RST_GL); - } - -+static int mtk_device_event(struct notifier_block *n, unsigned long event, void *ptr) -+{ -+ struct mtk_mac *mac = container_of(n, struct mtk_mac, device_notifier); -+ struct mtk_eth *eth = mac->hw; -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ struct ethtool_link_ksettings s; -+ struct net_device *ldev; -+ struct list_head *iter; -+ struct dsa_port *dp; -+ -+ if (event != NETDEV_CHANGE) -+ return NOTIFY_DONE; -+ -+ netdev_for_each_lower_dev(dev, ldev, iter) { -+ if (netdev_priv(ldev) == mac) -+ goto found; -+ } -+ -+ return NOTIFY_DONE; -+ -+found: -+ if (!dsa_slave_dev_check(dev)) -+ return NOTIFY_DONE; -+ -+ if (__ethtool_get_link_ksettings(dev, &s)) -+ return NOTIFY_DONE; -+ -+ if (s.base.speed == 0 || s.base.speed == ((__u32)-1)) -+ return NOTIFY_DONE; -+ -+ dp = dsa_port_from_netdev(dev); -+ if (dp->index >= MTK_QDMA_NUM_QUEUES) -+ return NOTIFY_DONE; -+ -+ mtk_set_queue_speed(eth, dp->index + 3, s.base.speed); -+ -+ return NOTIFY_DONE; -+} -+ - static int mtk_open(struct net_device *dev) - { - struct mtk_mac *mac = netdev_priv(dev); -@@ -3049,7 +3204,8 @@ static int mtk_open(struct net_device *d - refcount_inc(ð->dma_refcnt); - - phylink_start(mac->phylink); -- netif_start_queue(dev); -+ netif_tx_start_all_queues(dev); -+ - return 0; - } - -@@ -3758,8 +3914,12 @@ static int mtk_unreg_dev(struct mtk_eth - int i; - - for (i = 0; i < MTK_MAC_COUNT; i++) { -+ struct mtk_mac *mac; - if (!eth->netdev[i]) - continue; -+ mac = netdev_priv(eth->netdev[i]); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -+ unregister_netdevice_notifier(&mac->device_notifier); - unregister_netdev(eth->netdev[i]); - } - -@@ -3976,6 +4136,23 @@ static int mtk_set_rxnfc(struct net_devi - return ret; - } - -+static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb, -+ struct net_device *sb_dev) -+{ -+ struct mtk_mac *mac = netdev_priv(dev); -+ unsigned int queue = 0; -+ -+ if (netdev_uses_dsa(dev)) -+ queue = skb_get_queue_mapping(skb) + 3; -+ else -+ queue = mac->id; -+ -+ if (queue >= dev->num_tx_queues) -+ queue = 0; -+ -+ return queue; -+} -+ - static const struct ethtool_ops mtk_ethtool_ops = { - .get_link_ksettings = mtk_get_link_ksettings, - .set_link_ksettings = mtk_set_link_ksettings, -@@ -4010,6 +4187,7 @@ static const struct net_device_ops mtk_n - .ndo_setup_tc = mtk_eth_setup_tc, - .ndo_bpf = mtk_xdp, - .ndo_xdp_xmit = mtk_xdp_xmit, -+ .ndo_select_queue = mtk_select_queue, - }; - - static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) -@@ -4019,6 +4197,7 @@ static int mtk_add_mac(struct mtk_eth *e - struct phylink *phylink; - struct mtk_mac *mac; - int id, err; -+ int txqs = 1; - - if (!_id) { - dev_err(eth->dev, "missing mac id\n"); -@@ -4036,7 +4215,10 @@ static int mtk_add_mac(struct mtk_eth *e - return -EINVAL; - } - -- eth->netdev[id] = alloc_etherdev(sizeof(*mac)); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -+ txqs = MTK_QDMA_NUM_QUEUES; -+ -+ eth->netdev[id] = alloc_etherdev_mqs(sizeof(*mac), txqs, 1); - if (!eth->netdev[id]) { - dev_err(eth->dev, "alloc_etherdev failed\n"); - return -ENOMEM; -@@ -4144,6 +4326,11 @@ static int mtk_add_mac(struct mtk_eth *e - else - eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN; - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { -+ mac->device_notifier.notifier_call = mtk_device_event; -+ register_netdevice_notifier(&mac->device_notifier); -+ } -+ - return 0; - - free_netdev: ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -22,6 +22,7 @@ - #include - #include "mtk_ppe.h" - -+#define MTK_QDMA_NUM_QUEUES 16 - #define MTK_QDMA_PAGE_SIZE 2048 - #define MTK_MAX_RX_LENGTH 1536 - #define MTK_MAX_RX_LENGTH_2K 2048 -@@ -216,8 +217,26 @@ - #define MTK_RING_MAX_AGG_CNT_H ((MTK_HW_LRO_MAX_AGG_CNT >> 6) & 0x3) - - /* QDMA TX Queue Configuration Registers */ -+#define MTK_QTX_OFFSET 0x10 - #define QDMA_RES_THRES 4 - -+/* QDMA Tx Queue Scheduler Configuration Registers */ -+#define MTK_QTX_SCH_TX_SEL BIT(31) -+#define MTK_QTX_SCH_TX_SEL_V2 GENMASK(31, 30) -+ -+#define MTK_QTX_SCH_LEAKY_BUCKET_EN BIT(30) -+#define MTK_QTX_SCH_LEAKY_BUCKET_SIZE GENMASK(29, 28) -+#define MTK_QTX_SCH_MIN_RATE_EN BIT(27) -+#define MTK_QTX_SCH_MIN_RATE_MAN GENMASK(26, 20) -+#define MTK_QTX_SCH_MIN_RATE_EXP GENMASK(19, 16) -+#define MTK_QTX_SCH_MAX_RATE_WEIGHT GENMASK(15, 12) -+#define MTK_QTX_SCH_MAX_RATE_EN BIT(11) -+#define MTK_QTX_SCH_MAX_RATE_MAN GENMASK(10, 4) -+#define MTK_QTX_SCH_MAX_RATE_EXP GENMASK(3, 0) -+ -+/* QDMA TX Scheduler Rate Control Register */ -+#define MTK_QDMA_TX_SCH_MAX_WFQ BIT(15) -+ - /* QDMA Global Configuration Register */ - #define MTK_RX_2B_OFFSET BIT(31) - #define MTK_RX_BT_32DWORDS (3 << 11) -@@ -236,6 +255,7 @@ - #define MTK_WCOMP_EN BIT(24) - #define MTK_RESV_BUF (0x40 << 16) - #define MTK_MUTLI_CNT (0x4 << 12) -+#define MTK_LEAKY_BUCKET_EN BIT(11) - - /* QDMA Flow Control Register */ - #define FC_THRES_DROP_MODE BIT(20) -@@ -266,8 +286,6 @@ - #define MTK_STAT_OFFSET 0x40 - - /* QDMA TX NUM */ --#define MTK_QDMA_TX_NUM 16 --#define MTK_QDMA_TX_MASK (MTK_QDMA_TX_NUM - 1) - #define QID_BITS_V2(x) (((x) & 0x3f) << 16) - #define MTK_QDMA_GMAC2_QID 8 - -@@ -297,6 +315,7 @@ - #define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) - #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) - #define TX_DMA_SWC BIT(14) -+#define TX_DMA_PQID GENMASK(3, 0) - - /* PDMA on MT7628 */ - #define TX_DMA_DONE BIT(31) -@@ -957,6 +976,7 @@ struct mtk_reg_map { - } pdma; - struct { - u32 qtx_cfg; /* tx queue configuration */ -+ u32 qtx_sch; /* tx queue scheduler configuration */ - u32 rx_ptr; /* rx base pointer */ - u32 rx_cnt_cfg; /* rx max count configuration */ - u32 qcrx_ptr; /* rx cpu pointer */ -@@ -974,6 +994,7 @@ struct mtk_reg_map { - u32 fq_tail; /* fq tail pointer */ - u32 fq_count; /* fq free page count */ - u32 fq_blen; /* fq free page buffer length */ -+ u32 tx_sch_rate; /* tx scheduler rate control registers */ - } qdma; - u32 gdm1_cnt; - u32 gdma_to_ppe; -@@ -1177,6 +1198,7 @@ struct mtk_mac { - __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; - int hwlro_ip_cnt; - unsigned int syscfg0; -+ struct notifier_block device_notifier; - }; - - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ diff --git a/target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch b/target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch deleted file mode 100644 index 186df4bdc924d4..00000000000000 --- a/target/linux/generic/backport-6.1/730-05-v6.3-net-dsa-tag_mtk-assign-per-port-queues.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Felix Fietkau -Date: Fri, 28 Oct 2022 18:16:03 +0200 -Subject: [PATCH] net: dsa: tag_mtk: assign per-port queues - -Keeps traffic sent to the switch within link speed limits - -Signed-off-by: Felix Fietkau ---- - ---- a/net/dsa/tag_mtk.c -+++ b/net/dsa/tag_mtk.c -@@ -25,6 +25,8 @@ static struct sk_buff *mtk_tag_xmit(stru - u8 xmit_tpid; - u8 *mtk_tag; - -+ skb_set_queue_mapping(skb, dp->index); -+ - /* 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 diff --git a/target/linux/generic/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch b/target/linux/generic/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch deleted file mode 100644 index d29177eee722e8..00000000000000 --- a/target/linux/generic/backport-6.1/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch +++ /dev/null @@ -1,93 +0,0 @@ -From: Felix Fietkau -Date: Thu, 3 Nov 2022 17:49:44 +0100 -Subject: [PATCH] net: ethernet: mediatek: ppe: assign per-port queues - for offloaded traffic - -Keeps traffic sent to the switch within link speed limits - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -399,6 +399,24 @@ int mtk_foe_entry_set_wdma(struct mtk_et - return 0; - } - -+int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ unsigned int queue) -+{ -+ u32 *ib2 = mtk_foe_entry_ib2(eth, entry); -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ *ib2 &= ~MTK_FOE_IB2_QID_V2; -+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue); -+ *ib2 |= MTK_FOE_IB2_PSE_QOS_V2; -+ } else { -+ *ib2 &= ~MTK_FOE_IB2_QID; -+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID, queue); -+ *ib2 |= MTK_FOE_IB2_PSE_QOS; -+ } -+ -+ return 0; -+} -+ - static bool - mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, - struct mtk_foe_entry *data) ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -68,7 +68,9 @@ enum { - #define MTK_FOE_IB2_DSCP GENMASK(31, 24) - - /* CONFIG_MEDIATEK_NETSYS_V2 */ -+#define MTK_FOE_IB2_QID_V2 GENMASK(6, 0) - #define MTK_FOE_IB2_PORT_MG_V2 BIT(7) -+#define MTK_FOE_IB2_PSE_QOS_V2 BIT(8) - #define MTK_FOE_IB2_DEST_PORT_V2 GENMASK(12, 9) - #define MTK_FOE_IB2_MULTICAST_V2 BIT(13) - #define MTK_FOE_IB2_WDMA_WINFO_V2 BIT(19) -@@ -351,6 +353,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e - int sid); - int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, - int wdma_idx, int txq, int bss, int wcid); -+int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, -+ unsigned int queue); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -188,7 +188,7 @@ mtk_flow_set_output_device(struct mtk_et - int *wed_index) - { - struct mtk_wdma_info info = {}; -- int pse_port, dsa_port; -+ int pse_port, dsa_port, queue; - - if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { - mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, -@@ -212,8 +212,6 @@ mtk_flow_set_output_device(struct mtk_et - } - - dsa_port = mtk_flow_get_dsa_port(&dev); -- if (dsa_port >= 0) -- mtk_foe_entry_set_dsa(eth, foe, dsa_port); - - if (dev == eth->netdev[0]) - pse_port = 1; -@@ -222,6 +220,14 @@ mtk_flow_set_output_device(struct mtk_et - else - return -EOPNOTSUPP; - -+ if (dsa_port >= 0) { -+ mtk_foe_entry_set_dsa(eth, foe, dsa_port); -+ queue = 3 + dsa_port; -+ } else { -+ queue = pse_port - 1; -+ } -+ mtk_foe_entry_set_queue(eth, foe, queue); -+ - out: - mtk_foe_entry_set_pse_port(eth, foe, pse_port); - diff --git a/target/linux/generic/backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch b/target/linux/generic/backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch deleted file mode 100644 index 6b7f3d6018c583..00000000000000 --- a/target/linux/generic/backport-6.1/730-08-v6.3-net-dsa-add-support-for-DSA-rx-offloading-via-metada.patch +++ /dev/null @@ -1,72 +0,0 @@ -From: Felix Fietkau -Date: Tue, 8 Nov 2022 15:03:15 +0100 -Subject: [PATCH] net: dsa: add support for DSA rx offloading via - metadata dst - -If a metadata dst is present with the type METADATA_HW_PORT_MUX on a dsa cpu -port netdev, assume that it carries the port number and that there is no DSA -tag present in the skb data. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/core/flow_dissector.c -+++ b/net/core/flow_dissector.c -@@ -971,12 +971,14 @@ bool __skb_flow_dissect(const struct net - #if IS_ENABLED(CONFIG_NET_DSA) - if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) && - proto == htons(ETH_P_XDSA))) { -+ struct metadata_dst *md_dst = skb_metadata_dst(skb); - const struct dsa_device_ops *ops; - int offset = 0; - - ops = skb->dev->dsa_ptr->tag_ops; - /* Only DSA header taggers break flow dissection */ -- if (ops->needed_headroom) { -+ if (ops->needed_headroom && -+ (!md_dst || md_dst->type != METADATA_HW_PORT_MUX)) { - if (ops->flow_dissect) - ops->flow_dissect(skb, &proto, &offset); - else ---- a/net/dsa/dsa.c -+++ b/net/dsa/dsa.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - - #include "dsa_priv.h" - -@@ -216,6 +217,7 @@ static bool dsa_skb_defer_rx_timestamp(s - static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *unused) - { -+ struct metadata_dst *md_dst = skb_metadata_dst(skb); - struct dsa_port *cpu_dp = dev->dsa_ptr; - struct sk_buff *nskb = NULL; - struct dsa_slave_priv *p; -@@ -229,7 +231,22 @@ static int dsa_switch_rcv(struct sk_buff - if (!skb) - return 0; - -- nskb = cpu_dp->rcv(skb, dev); -+ if (md_dst && md_dst->type == METADATA_HW_PORT_MUX) { -+ unsigned int port = md_dst->u.port_info.port_id; -+ -+ skb_dst_drop(skb); -+ if (!skb_has_extensions(skb)) -+ skb->slow_gro = 0; -+ -+ skb->dev = dsa_master_find_slave(dev, 0, port); -+ if (likely(skb->dev)) { -+ dsa_default_offload_fwd_mark(skb); -+ nskb = skb; -+ } -+ } else { -+ nskb = cpu_dp->rcv(skb, dev); -+ } -+ - if (!nskb) { - kfree_skb(skb); - return 0; diff --git a/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch b/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch deleted file mode 100644 index 53d8ff472ef0ef..00000000000000 --- a/target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch +++ /dev/null @@ -1,192 +0,0 @@ -From: Felix Fietkau -Date: Fri, 28 Oct 2022 11:01:12 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix VLAN rx hardware - acceleration - -- enable VLAN untagging for PDMA rx -- make it possible to disable the feature via ethtool -- pass VLAN tag to the DSA driver -- untag special tag on PDMA only if no non-DSA devices are in use -- disable special tag untagging on 7986 for now, since it's not working yet - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include "mtk_eth_soc.h" - #include "mtk_wed.h" -@@ -2020,16 +2021,22 @@ static int mtk_poll_rx(struct napi_struc - htons(RX_DMA_VPID(trxd.rxd4)), - RX_DMA_VID(trxd.rxd4)); - } else if (trxd.rxd2 & RX_DMA_VTAG) { -- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), -+ __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)), - RX_DMA_VID(trxd.rxd3)); - } -+ } -+ -+ /* When using VLAN untagging in combination with DSA, the -+ * hardware treats the MTK special tag as a VLAN and untags it. -+ */ -+ if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) { -+ unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0); - -- /* If the device is attached to a dsa switch, the special -- * tag inserted in VLAN field by hw switch can * be offloaded -- * by RX HW VLAN offload. Clear vlan info. -- */ -- if (netdev_uses_dsa(netdev)) -- __vlan_hwaccel_clear_tag(skb); -+ if (port < ARRAY_SIZE(eth->dsa_meta) && -+ eth->dsa_meta[port]) -+ skb_dst_set_noref(skb, ð->dsa_meta[port]->dst); -+ -+ __vlan_hwaccel_clear_tag(skb); - } - - skb_record_rx_queue(skb, 0); -@@ -2857,15 +2864,30 @@ static netdev_features_t mtk_fix_feature - - static int mtk_set_features(struct net_device *dev, netdev_features_t features) - { -- int err = 0; -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ netdev_features_t diff = dev->features ^ features; -+ int i; -+ -+ if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO)) -+ mtk_hwlro_netdev_disable(dev); - -- if (!((dev->features ^ features) & NETIF_F_LRO)) -+ /* Set RX VLAN offloading */ -+ if (!(diff & NETIF_F_HW_VLAN_CTAG_RX)) - return 0; - -- if (!(features & NETIF_F_LRO)) -- mtk_hwlro_netdev_disable(dev); -+ mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX), -+ MTK_CDMP_EG_CTRL); - -- return err; -+ /* sync features with other MAC */ -+ for (i = 0; i < MTK_MAC_COUNT; i++) { -+ if (!eth->netdev[i] || eth->netdev[i] == dev) -+ continue; -+ eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX; -+ eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX; -+ } -+ -+ return 0; - } - - /* wait for DMA to finish whatever it is doing before we start using it again */ -@@ -3162,11 +3184,45 @@ found: - return NOTIFY_DONE; - } - -+static bool mtk_uses_dsa(struct net_device *dev) -+{ -+#if IS_ENABLED(CONFIG_NET_DSA) -+ return netdev_uses_dsa(dev) && -+ dev->dsa_ptr->tag_ops->proto == DSA_TAG_PROTO_MTK; -+#else -+ return false; -+#endif -+} -+ - static int mtk_open(struct net_device *dev) - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; -- int err; -+ int i, err; -+ -+ if (mtk_uses_dsa(dev) && !eth->prog) { -+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { -+ struct metadata_dst *md_dst = eth->dsa_meta[i]; -+ -+ if (md_dst) -+ continue; -+ -+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, -+ GFP_KERNEL); -+ if (!md_dst) -+ return -ENOMEM; -+ -+ md_dst->u.port_info.port_id = i; -+ eth->dsa_meta[i] = md_dst; -+ } -+ } else { -+ /* Hardware special tag parsing needs to be disabled if at least -+ * one MAC does not use DSA. -+ */ -+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); -+ val &= ~MTK_CDMP_STAG_EN; -+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL); -+ } - - err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); - if (err) { -@@ -3687,6 +3743,10 @@ static int mtk_hw_init(struct mtk_eth *e - */ - val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); - mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ val = mtk_r32(eth, MTK_CDMP_IG_CTRL); -+ mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); -+ } - - /* Enable RX VLan Offloading */ - mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -@@ -3906,6 +3966,12 @@ static int mtk_free_dev(struct mtk_eth * - free_netdev(eth->netdev[i]); - } - -+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { -+ if (!eth->dsa_meta[i]) -+ break; -+ metadata_dst_free(eth->dsa_meta[i]); -+ } -+ - return 0; - } - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -22,6 +22,9 @@ - #include - #include "mtk_ppe.h" - -+#define MTK_MAX_DSA_PORTS 7 -+#define MTK_DSA_PORT_MASK GENMASK(2, 0) -+ - #define MTK_QDMA_NUM_QUEUES 16 - #define MTK_QDMA_PAGE_SIZE 2048 - #define MTK_MAX_RX_LENGTH 1536 -@@ -105,6 +108,9 @@ - #define MTK_CDMQ_IG_CTRL 0x1400 - #define MTK_CDMQ_STAG_EN BIT(0) - -+/* CDMQ Exgress Control Register */ -+#define MTK_CDMQ_EG_CTRL 0x1404 -+ - /* CDMP Ingress Control Register */ - #define MTK_CDMP_IG_CTRL 0x400 - #define MTK_CDMP_STAG_EN BIT(0) -@@ -1164,6 +1170,8 @@ struct mtk_eth { - - int ip_align; - -+ struct metadata_dst *dsa_meta[MTK_MAX_DSA_PORTS]; -+ - struct mtk_ppe *ppe[2]; - struct rhashtable flow_table; - diff --git a/target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch b/target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch deleted file mode 100644 index 08d72fc82093a1..00000000000000 --- a/target/linux/generic/backport-6.1/730-12-v6.3-net-ethernet-mtk_eth_soc-disable-hardware-DSA-untagg.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Sat, 28 Jan 2023 12:42:32 +0300 -Subject: [PATCH] net: ethernet: mtk_eth_soc: disable hardware DSA untagging - for second MAC -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -According to my tests on MT7621AT and MT7623NI SoCs, hardware DSA untagging -won't work on the second MAC. Therefore, disable this feature when the -second MAC of the MT7621 and MT7623 SoCs is being used. - -Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging") -Link: https://lore.kernel.org/netdev/6249fc14-b38a-c770-36b4-5af6d41c21d3@arinc9.com/ -Tested-by: Arınç ÜNAL -Signed-off-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/20230128094232.2451947-1-arinc.unal@arinc9.com -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3200,7 +3200,8 @@ static int mtk_open(struct net_device *d - struct mtk_eth *eth = mac->hw; - int i, err; - -- if (mtk_uses_dsa(dev) && !eth->prog) { -+ if ((mtk_uses_dsa(dev) && !eth->prog) && -+ !(mac->id == 1 && MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC1_TRGMII))) { - for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { - struct metadata_dst *md_dst = eth->dsa_meta[i]; - -@@ -3217,7 +3218,8 @@ static int mtk_open(struct net_device *d - } - } else { - /* Hardware special tag parsing needs to be disabled if at least -- * one MAC does not use DSA. -+ * one MAC does not use DSA, or the second MAC of the MT7621 and -+ * MT7623 SoCs is being used. - */ - u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - val &= ~MTK_CDMP_STAG_EN; diff --git a/target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch b/target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch deleted file mode 100644 index 30c32d5cce0411..00000000000000 --- a/target/linux/generic/backport-6.1/730-13-v6.3-net-ethernet-mtk_eth_soc-enable-special-tag-when-any.patch +++ /dev/null @@ -1,54 +0,0 @@ -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Sun, 5 Feb 2023 20:53:31 +0300 -Subject: [PATCH] net: ethernet: mtk_eth_soc: enable special tag when any MAC - uses DSA -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The special tag is only enabled when the first MAC uses DSA. However, it -must be enabled when any MAC uses DSA. Change the check accordingly. - -This fixes hardware DSA untagging not working on the second MAC of the -MT7621 and MT7623 SoCs, and likely other SoCs too. Therefore, remove the -check that disables hardware DSA untagging for the second MAC of the MT7621 -and MT7623 SoCs. - -Fixes: a1f47752fd62 ("net: ethernet: mtk_eth_soc: disable hardware DSA untagging for second MAC") -Co-developed-by: Richard van Schagen -Signed-off-by: Richard van Schagen -Signed-off-by: Arınç ÜNAL -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3135,7 +3135,7 @@ static void mtk_gdm_config(struct mtk_et - - val |= config; - -- if (!i && eth->netdev[0] && netdev_uses_dsa(eth->netdev[0])) -+ if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i])) - val |= MTK_GDMA_SPECIAL_TAG; - - mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); -@@ -3200,8 +3200,7 @@ static int mtk_open(struct net_device *d - struct mtk_eth *eth = mac->hw; - int i, err; - -- if ((mtk_uses_dsa(dev) && !eth->prog) && -- !(mac->id == 1 && MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC1_TRGMII))) { -+ if (mtk_uses_dsa(dev) && !eth->prog) { - for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { - struct metadata_dst *md_dst = eth->dsa_meta[i]; - -@@ -3218,8 +3217,7 @@ static int mtk_open(struct net_device *d - } - } else { - /* Hardware special tag parsing needs to be disabled if at least -- * one MAC does not use DSA, or the second MAC of the MT7621 and -- * MT7623 SoCs is being used. -+ * one MAC does not use DSA. - */ - u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - val &= ~MTK_CDMP_STAG_EN; diff --git a/target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch b/target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch deleted file mode 100644 index eb3b0c63bca832..00000000000000 --- a/target/linux/generic/backport-6.1/730-14-v6.3-net-ethernet-mtk_eth_soc-fix-DSA-TX-tag-hwaccel-for-.patch +++ /dev/null @@ -1,129 +0,0 @@ -From: Vladimir Oltean -Date: Tue, 7 Feb 2023 12:30:27 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix DSA TX tag hwaccel for switch - port 0 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Arınç reports that on his MT7621AT Unielec U7621-06 board and MT7623NI -Bananapi BPI-R2, packets received by the CPU over mt7530 switch port 0 -(of which this driver acts as the DSA master) are not processed -correctly by software. More precisely, they arrive without a DSA tag -(in packet or in the hwaccel area - skb_metadata_dst()), so DSA cannot -demux them towards the switch's interface for port 0. Traffic from other -ports receives a skb_metadata_dst() with the correct port and is demuxed -properly. - -Looking at mtk_poll_rx(), it becomes apparent that this driver uses the -skb vlan hwaccel area: - - union { - u32 vlan_all; - struct { - __be16 vlan_proto; - __u16 vlan_tci; - }; - }; - -as a temporary storage for the VLAN hwaccel tag, or the DSA hwaccel tag. -If this is a DSA master it's a DSA hwaccel tag, and finally clears up -the skb VLAN hwaccel header. - -I'm guessing that the problem is the (mis)use of API. -skb_vlan_tag_present() looks like this: - - #define skb_vlan_tag_present(__skb) (!!(__skb)->vlan_all) - -So if both vlan_proto and vlan_tci are zeroes, skb_vlan_tag_present() -returns precisely false. I don't know for sure what is the format of the -DSA hwaccel tag, but I surely know that lowermost 3 bits of vlan_proto -are 0 when receiving from port 0: - - unsigned int port = vlan_proto & GENMASK(2, 0); - -If the RX descriptor has no other bits set to non-zero values in -RX_DMA_VTAG, then the call to __vlan_hwaccel_put_tag() will not, in -fact, make the subsequent skb_vlan_tag_present() return true, because -it's implemented like this: - -static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb, - __be16 vlan_proto, u16 vlan_tci) -{ - skb->vlan_proto = vlan_proto; - skb->vlan_tci = vlan_tci; -} - -What we need to do to fix this problem (assuming this is the problem) is -to stop using skb->vlan_all as temporary storage for driver affairs, and -just create some local variables that serve the same purpose, but -hopefully better. Instead of calling skb_vlan_tag_present(), let's look -at a boolean has_hwaccel_tag which we set to true when the RX DMA -descriptors have something. Disambiguate based on netdev_uses_dsa() -whether this is a VLAN or DSA hwaccel tag, and only call -__vlan_hwaccel_put_tag() if we're certain it's a VLAN tag. - -Arınç confirms that the treatment works, so this validates the -assumption. - -Link: https://lore.kernel.org/netdev/704f3a72-fc9e-714a-db54-272e17612637@arinc9.com/ -Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging") -Reported-by: Arınç ÜNAL -Tested-by: Arınç ÜNAL -Signed-off-by: Vladimir Oltean -Reviewed-by: Felix Fietkau -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1876,7 +1876,9 @@ static int mtk_poll_rx(struct napi_struc - - while (done < budget) { - unsigned int pktlen, *rxdcsum; -+ bool has_hwaccel_tag = false; - struct net_device *netdev; -+ u16 vlan_proto, vlan_tci; - dma_addr_t dma_addr; - u32 hash, reason; - int mac = 0; -@@ -2016,27 +2018,29 @@ static int mtk_poll_rx(struct napi_struc - - if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -- if (trxd.rxd3 & RX_DMA_VTAG_V2) -- __vlan_hwaccel_put_tag(skb, -- htons(RX_DMA_VPID(trxd.rxd4)), -- RX_DMA_VID(trxd.rxd4)); -+ if (trxd.rxd3 & RX_DMA_VTAG_V2) { -+ vlan_proto = RX_DMA_VPID(trxd.rxd4); -+ vlan_tci = RX_DMA_VID(trxd.rxd4); -+ has_hwaccel_tag = true; -+ } - } else if (trxd.rxd2 & RX_DMA_VTAG) { -- __vlan_hwaccel_put_tag(skb, htons(RX_DMA_VPID(trxd.rxd3)), -- RX_DMA_VID(trxd.rxd3)); -+ vlan_proto = RX_DMA_VPID(trxd.rxd3); -+ vlan_tci = RX_DMA_VID(trxd.rxd3); -+ has_hwaccel_tag = true; - } - } - - /* When using VLAN untagging in combination with DSA, the - * hardware treats the MTK special tag as a VLAN and untags it. - */ -- if (skb_vlan_tag_present(skb) && netdev_uses_dsa(netdev)) { -- unsigned int port = ntohs(skb->vlan_proto) & GENMASK(2, 0); -+ if (has_hwaccel_tag && netdev_uses_dsa(netdev)) { -+ unsigned int port = vlan_proto & GENMASK(2, 0); - - if (port < ARRAY_SIZE(eth->dsa_meta) && - eth->dsa_meta[port]) - skb_dst_set_noref(skb, ð->dsa_meta[port]->dst); -- -- __vlan_hwaccel_clear_tag(skb); -+ } else if (has_hwaccel_tag) { -+ __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci); - } - - skb_record_rx_queue(skb, 0); diff --git a/target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch b/target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch deleted file mode 100644 index a3bb1c5db77ed1..00000000000000 --- a/target/linux/generic/backport-6.1/730-15-v6.3-net-ethernet-mtk_wed-No-need-to-clear-memory-after-a.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Christophe JAILLET -Date: Sun, 12 Feb 2023 07:51:51 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: No need to clear memory after a - dma_alloc_coherent() call - -dma_alloc_coherent() already clears the allocated memory, there is no need -to explicitly call memset(). - -Moreover, it is likely that the size in the memset() is incorrect and -should be "size * sizeof(*ring->desc)". - -Signed-off-by: Christophe JAILLET -Link: https://lore.kernel.org/r/d5acce7dd108887832c9719f62c7201b4c83b3fb.1676184599.git.christophe.jaillet@wanadoo.fr -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -779,7 +779,6 @@ mtk_wed_rro_ring_alloc(struct mtk_wed_de - - ring->desc_size = sizeof(*ring->desc); - ring->size = size; -- memset(ring->desc, 0, size); - - return 0; - } diff --git a/target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch b/target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch deleted file mode 100644 index e043a681da40f6..00000000000000 --- a/target/linux/generic/backport-6.1/730-16-v6.3-net-ethernet-mtk_wed-fix-some-possible-NULL-pointer-.patch +++ /dev/null @@ -1,61 +0,0 @@ -From: Lorenzo Bianconi -Date: Wed, 7 Dec 2022 15:04:54 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: fix some possible NULL pointer - dereferences - -Fix possible NULL pointer dereference in mtk_wed_detach routine checking -wo pointer is properly allocated before running mtk_wed_wo_reset() and -mtk_wed_wo_deinit(). -Even if it is just a theoretical issue at the moment check wo pointer is -not NULL in mtk_wed_mcu_msg_update. -Moreover, honor mtk_wed_mcu_send_msg return value in mtk_wed_wo_reset() - -Fixes: 799684448e3e ("net: ethernet: mtk_wed: introduce wed wo support") -Fixes: 4c5de09eb0d0 ("net: ethernet: mtk_wed: add configure wed wo support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Leon Romanovsky -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -174,9 +174,10 @@ mtk_wed_wo_reset(struct mtk_wed_device * - mtk_wdma_tx_reset(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); - -- mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -- MTK_WED_WO_CMD_CHANGE_STATE, &state, -- sizeof(state), false); -+ if (mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -+ MTK_WED_WO_CMD_CHANGE_STATE, &state, -+ sizeof(state), false)) -+ return; - - if (readx_poll_timeout(mtk_wed_wo_read_status, dev, val, - val == MTK_WED_WOIF_DISABLE_DONE, -@@ -632,9 +633,11 @@ mtk_wed_detach(struct mtk_wed_device *de - mtk_wed_free_tx_rings(dev); - - if (mtk_wed_get_rx_capa(dev)) { -- mtk_wed_wo_reset(dev); -+ if (hw->wed_wo) -+ mtk_wed_wo_reset(dev); - mtk_wed_free_rx_rings(dev); -- mtk_wed_wo_deinit(hw); -+ if (hw->wed_wo) -+ mtk_wed_wo_deinit(hw); - } - - if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -207,6 +207,9 @@ int mtk_wed_mcu_msg_update(struct mtk_we - if (dev->hw->version == 1) - return 0; - -+ if (WARN_ON(!wo)) -+ return -ENODEV; -+ - return mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, id, data, len, - true); - } diff --git a/target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch b/target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch deleted file mode 100644 index 0afe7106e5478b..00000000000000 --- a/target/linux/generic/backport-6.1/730-17-v6.3-net-ethernet-mtk_wed-fix-possible-deadlock-if-mtk_we.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Lorenzo Bianconi -Date: Wed, 7 Dec 2022 15:04:55 +0100 -Subject: [PATCH] net: ethernet: mtk_wed: fix possible deadlock if - mtk_wed_wo_init fails - -Introduce __mtk_wed_detach() in order to avoid a deadlock in -mtk_wed_attach routine if mtk_wed_wo_init fails since both -mtk_wed_attach and mtk_wed_detach run holding hw_lock mutex. - -Fixes: 4c5de09eb0d0 ("net: ethernet: mtk_wed: add configure wed wo support") -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Leon Romanovsky -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -619,12 +619,10 @@ mtk_wed_deinit(struct mtk_wed_device *de - } - - static void --mtk_wed_detach(struct mtk_wed_device *dev) -+__mtk_wed_detach(struct mtk_wed_device *dev) - { - struct mtk_wed_hw *hw = dev->hw; - -- mutex_lock(&hw_lock); -- - mtk_wed_deinit(dev); - - mtk_wdma_rx_reset(dev); -@@ -657,6 +655,13 @@ mtk_wed_detach(struct mtk_wed_device *de - module_put(THIS_MODULE); - - hw->wed_dev = NULL; -+} -+ -+static void -+mtk_wed_detach(struct mtk_wed_device *dev) -+{ -+ mutex_lock(&hw_lock); -+ __mtk_wed_detach(dev); - mutex_unlock(&hw_lock); - } - -@@ -1538,8 +1543,10 @@ mtk_wed_attach(struct mtk_wed_device *de - ret = mtk_wed_wo_init(hw); - } - out: -- if (ret) -- mtk_wed_detach(dev); -+ if (ret) { -+ dev_err(dev->hw->dev, "failed to attach wed device\n"); -+ __mtk_wed_detach(dev); -+ } - unlock: - mutex_unlock(&hw_lock); - diff --git a/target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch b/target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch deleted file mode 100644 index f6d91d30806d1a..00000000000000 --- a/target/linux/generic/backport-6.1/730-18-v6.3-net-ethernet-mtk_eth_soc-fix-tx-throughput-regressio.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Felix Fietkau -Date: Fri, 24 Mar 2023 14:56:58 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix tx throughput regression with - direct 1G links - -Using the QDMA tx scheduler to throttle tx to line speed works fine for -switch ports, but apparently caused a regression on non-switch ports. - -Based on a number of tests, it seems that this throttling can be safely -dropped without re-introducing the issues on switch ports that the -tx scheduling changes resolved. - -Link: https://lore.kernel.org/netdev/trinity-92c3826f-c2c8-40af-8339-bc6d0d3ffea4-1678213958520@3c-app-gmx-bs16/ -Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues") -Reported-by: Frank Wunderlich -Reported-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -718,8 +718,6 @@ static void mtk_mac_link_up(struct phyli - break; - } - -- mtk_set_queue_speed(mac->hw, mac->id, speed); -- - /* Configure duplex */ - if (duplex == DUPLEX_FULL) - mcr |= MAC_MCR_FORCE_DPX; diff --git a/target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch b/target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch deleted file mode 100644 index 850b806410ca4d..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-02-net-mtk_eth_soc-add-definitions-for-PCS.patch +++ /dev/null @@ -1,55 +0,0 @@ -From b6a709cb51f7bdc55c01cec886098a9753ce8c28 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:10:42 +0100 -Subject: [PATCH 01/10] net: mtk_eth_soc: add definitions for PCS - -As a result of help from Frank Wunderlich to investigate and test, we -know a bit more about the PCS on the Mediatek platforms. Update the -definitions from this investigation. - -This PCS appears similar, but not identical to the Lynx PCS. - -Although not included in this patch, but for future reference, the PHY -ID registers at offset 4 read as 0x4d544950 'MTIP'. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -504,8 +504,10 @@ - #define ETHSYS_DMA_AG_MAP_PPE BIT(2) - - /* SGMII subsystem config registers */ --/* Register to auto-negotiation restart */ -+/* BMCR (low 16) BMSR (high 16) */ - #define SGMSYS_PCS_CONTROL_1 0x0 -+#define SGMII_BMCR GENMASK(15, 0) -+#define SGMII_BMSR GENMASK(31, 16) - #define SGMII_AN_RESTART BIT(9) - #define SGMII_ISOLATE BIT(10) - #define SGMII_AN_ENABLE BIT(12) -@@ -515,13 +517,18 @@ - #define SGMII_PCS_FAULT BIT(23) - #define SGMII_AN_EXPANSION_CLR BIT(30) - -+#define SGMSYS_PCS_ADVERTISE 0x8 -+#define SGMII_ADVERTISE GENMASK(15, 0) -+#define SGMII_LPA GENMASK(31, 16) -+ - /* Register to programmable link timer, the unit in 2 * 8ns */ - #define SGMSYS_PCS_LINK_TIMER 0x18 --#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & GENMASK(19, 0)) -+#define SGMII_LINK_TIMER_MASK GENMASK(19, 0) -+#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK) - - /* Register to control remote fault */ - #define SGMSYS_SGMII_MODE 0x20 --#define SGMII_IF_MODE_BIT0 BIT(0) -+#define SGMII_IF_MODE_SGMII BIT(0) - #define SGMII_SPEED_DUPLEX_AN BIT(1) - #define SGMII_SPEED_MASK GENMASK(3, 2) - #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) diff --git a/target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch b/target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch deleted file mode 100644 index 4ea428c9d6b1c2..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-03-net-mtk_eth_soc-eliminate-unnecessary-error-handling.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 5cf7797526ee81bea0f627bccaa3d887f48f53e0 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:10:47 +0100 -Subject: [PATCH 02/10] net: mtk_eth_soc: eliminate unnecessary error handling - -The functions called by the pcs_config() method always return zero, so -there is no point trying to handle an error from these functions. Make -these functions void, eliminate the "err" variable and simply return -zero from the pcs_config() function itself. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -20,7 +20,7 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st - } - - /* For SGMII interface mode */ --static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) -+static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) - { - unsigned int val; - -@@ -39,16 +39,13 @@ static int mtk_pcs_setup_mode_an(struct - regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); - val &= ~SGMII_PHYA_PWD; - regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); -- -- return 0; -- - } - - /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a - * fixed speed. - */ --static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, -- phy_interface_t interface) -+static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, -+ phy_interface_t interface) - { - unsigned int val; - -@@ -73,8 +70,6 @@ static int mtk_pcs_setup_mode_force(stru - regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); - val &= ~SGMII_PHYA_PWD; - regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); -- -- return 0; - } - - static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -83,15 +78,14 @@ static int mtk_pcs_config(struct phylink - bool permit_pause_to_mac) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- int err = 0; - - /* Setup SGMIISYS with the determined property */ - if (interface != PHY_INTERFACE_MODE_SGMII) -- err = mtk_pcs_setup_mode_force(mpcs, interface); -+ mtk_pcs_setup_mode_force(mpcs, interface); - else if (phylink_autoneg_inband(mode)) -- err = mtk_pcs_setup_mode_an(mpcs); -+ mtk_pcs_setup_mode_an(mpcs); - -- return err; -+ return 0; - } - - static void mtk_pcs_restart_an(struct phylink_pcs *pcs) diff --git a/target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch b/target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch deleted file mode 100644 index 64a4a72fa6ae96..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-04-net-mtk_eth_soc-add-pcs_get_state-implementation.patch +++ /dev/null @@ -1,46 +0,0 @@ -From c000dca098002da193b98099df051c9ead0cacb4 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:10:52 +0100 -Subject: [PATCH 03/10] net: mtk_eth_soc: add pcs_get_state() implementation - -Add a pcs_get_state() implementation which uses the advertisements -to compute the resulting link modes, and BMSR contents to determine -negotiation and link status. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -19,6 +19,20 @@ static struct mtk_pcs *pcs_to_mtk_pcs(st - return container_of(pcs, struct mtk_pcs, pcs); - } - -+static void mtk_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -+ unsigned int bm, adv; -+ -+ /* Read the BMSR and LPA */ -+ regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); -+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -+ -+ phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), -+ FIELD_GET(SGMII_LPA, adv)); -+} -+ - /* For SGMII interface mode */ - static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) - { -@@ -117,6 +131,7 @@ static void mtk_pcs_link_up(struct phyli - } - - static const struct phylink_pcs_ops mtk_pcs_ops = { -+ .pcs_get_state = mtk_pcs_get_state, - .pcs_config = mtk_pcs_config, - .pcs_an_restart = mtk_pcs_restart_an, - .pcs_link_up = mtk_pcs_link_up, diff --git a/target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch b/target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch deleted file mode 100644 index 24610fe11e1f4d..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-05-net-mtk_eth_soc-convert-mtk_sgmii-to-use-regmap_upda.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 0d2351dc2768061689abd4de1529fa206bbd574e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:10:58 +0100 -Subject: [PATCH 04/10] net: mtk_eth_soc: convert mtk_sgmii to use - regmap_update_bits() - -mtk_sgmii does a lot of read-modify-write operations, for which there -is a specific regmap function. Use this function instead of open-coding -the operations. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 61 ++++++++++------------- - 1 file changed, 26 insertions(+), 35 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -36,23 +36,18 @@ static void mtk_pcs_get_state(struct phy - /* For SGMII interface mode */ - static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) - { -- unsigned int val; -- - /* Setup the link timer and QPHY power up inside SGMIISYS */ - regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, - SGMII_LINK_TIMER_DEFAULT); - -- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); -- val |= SGMII_REMOTE_FAULT_DIS; -- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); -- -- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); -- val |= SGMII_AN_RESTART; -- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); -- -- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); -- val &= ~SGMII_PHYA_PWD; -- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS); -+ -+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -+ SGMII_AN_RESTART, SGMII_AN_RESTART); -+ -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -+ SGMII_PHYA_PWD, 0); - } - - /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a -@@ -61,29 +56,26 @@ static void mtk_pcs_setup_mode_an(struct - static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, - phy_interface_t interface) - { -- unsigned int val; -+ unsigned int rgc3; - -- regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val); -- val &= ~RG_PHY_SPEED_MASK; - if (interface == PHY_INTERFACE_MODE_2500BASEX) -- val |= RG_PHY_SPEED_3_125G; -- regmap_write(mpcs->regmap, mpcs->ana_rgc3, val); -+ rgc3 = RG_PHY_SPEED_3_125G; -+ -+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -+ RG_PHY_SPEED_3_125G, rgc3); - - /* Disable SGMII AN */ -- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); -- val &= ~SGMII_AN_ENABLE; -- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -+ SGMII_AN_ENABLE, 0); - - /* Set the speed etc but leave the duplex unchanged */ -- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); -- val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK; -- val |= SGMII_SPEED_1000; -- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL, -+ SGMII_SPEED_1000); - - /* Release PHYA power down state */ -- regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val); -- val &= ~SGMII_PHYA_PWD; -- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -+ SGMII_PHYA_PWD, 0); - } - - static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -105,29 +97,28 @@ static int mtk_pcs_config(struct phylink - static void mtk_pcs_restart_an(struct phylink_pcs *pcs) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- unsigned int val; - -- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val); -- val |= SGMII_AN_RESTART; -- regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -+ SGMII_AN_RESTART, SGMII_AN_RESTART); - } - - static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, - phy_interface_t interface, int speed, int duplex) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- unsigned int val; -+ unsigned int sgm_mode; - - if (!phy_interface_mode_is_8023z(interface)) - return; - - /* SGMII force duplex setting */ -- regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val); -- val &= ~SGMII_DUPLEX_FULL; - if (duplex == DUPLEX_FULL) -- val |= SGMII_DUPLEX_FULL; -+ sgm_mode = SGMII_DUPLEX_FULL; -+ else -+ sgm_mode = 0; - -- regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val); -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_DUPLEX_FULL, sgm_mode); - } - - static const struct phylink_pcs_ops mtk_pcs_ops = { diff --git a/target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch b/target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch deleted file mode 100644 index ba76ca40ffaaa8..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-06-net-mtk_eth_soc-add-out-of-band-forcing-of-speed-and.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 12198c3a410fe69843e335c1bbf6d4c2a4d48e4e Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:03 +0100 -Subject: [PATCH 05/10] net: mtk_eth_soc: add out of band forcing of speed and - duplex in pcs_link_up - -Add support for forcing the link speed and duplex setting in the -pcs_link_up() method for out of band modes, which will be useful when -we finish converting the pcs_config() method. Until then, we still have -to force duplex for 802.3z modes to work correctly. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 28 ++++++++++++++--------- - 1 file changed, 17 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -108,17 +108,23 @@ static void mtk_pcs_link_up(struct phyli - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - unsigned int sgm_mode; - -- if (!phy_interface_mode_is_8023z(interface)) -- return; -+ if (!phylink_autoneg_inband(mode) || -+ phy_interface_mode_is_8023z(interface)) { -+ /* Force the speed and duplex setting */ -+ if (speed == SPEED_10) -+ sgm_mode = SGMII_SPEED_10; -+ else if (speed == SPEED_100) -+ sgm_mode = SGMII_SPEED_100; -+ else -+ sgm_mode = SGMII_SPEED_1000; - -- /* SGMII force duplex setting */ -- if (duplex == DUPLEX_FULL) -- sgm_mode = SGMII_DUPLEX_FULL; -- else -- sgm_mode = 0; -+ if (duplex == DUPLEX_FULL) -+ sgm_mode |= SGMII_DUPLEX_FULL; - -- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_DUPLEX_FULL, sgm_mode); -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_DUPLEX_FULL | SGMII_SPEED_MASK, -+ sgm_mode); -+ } - } - - static const struct phylink_pcs_ops mtk_pcs_ops = { diff --git a/target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch b/target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch deleted file mode 100644 index b76e15927505cb..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-07-net-mtk_eth_soc-move-PHY-power-up.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 6f38fffe2179dd29612aea2c67c46ed6682b4e46 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:08 +0100 -Subject: [PATCH 06/10] net: mtk_eth_soc: move PHY power up - -The PHY power up is common to both configuration paths, so move it into -the parent function. We need to do this for all serdes modes. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 11 ++++------- - 1 file changed, 4 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -45,9 +45,6 @@ static void mtk_pcs_setup_mode_an(struct - - regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, - SGMII_AN_RESTART, SGMII_AN_RESTART); -- -- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -- SGMII_PHYA_PWD, 0); - } - - /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a -@@ -72,10 +69,6 @@ static void mtk_pcs_setup_mode_force(str - regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, - SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL, - SGMII_SPEED_1000); -- -- /* Release PHYA power down state */ -- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -- SGMII_PHYA_PWD, 0); - } - - static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -@@ -91,6 +84,10 @@ static int mtk_pcs_config(struct phylink - else if (phylink_autoneg_inband(mode)) - mtk_pcs_setup_mode_an(mpcs); - -+ /* Release PHYA power down state */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -+ SGMII_PHYA_PWD, 0); -+ - return 0; - } - diff --git a/target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch b/target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch deleted file mode 100644 index cd9f0699b3ebc7..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-08-net-mtk_eth_soc-move-interface-speed-selection.patch +++ /dev/null @@ -1,48 +0,0 @@ -From f752c0df13dfeb721c11d3debb79f08cf437344f Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:13 +0100 -Subject: [PATCH 07/10] net: mtk_eth_soc: move interface speed selection - -Move the selection of the underlying interface speed to the pcs_config -function, so we always program the interface speed. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -53,14 +53,6 @@ static void mtk_pcs_setup_mode_an(struct - static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, - phy_interface_t interface) - { -- unsigned int rgc3; -- -- if (interface == PHY_INTERFACE_MODE_2500BASEX) -- rgc3 = RG_PHY_SPEED_3_125G; -- -- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -- RG_PHY_SPEED_3_125G, rgc3); -- - /* Disable SGMII AN */ - regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, - SGMII_AN_ENABLE, 0); -@@ -77,6 +69,16 @@ static int mtk_pcs_config(struct phylink - bool permit_pause_to_mac) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -+ unsigned int rgc3; -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ rgc3 = RG_PHY_SPEED_3_125G; -+ else -+ rgc3 = 0; -+ -+ /* Configure the underlying interface speed */ -+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -+ RG_PHY_SPEED_3_125G, rgc3); - - /* Setup SGMIISYS with the determined property */ - if (interface != PHY_INTERFACE_MODE_SGMII) diff --git a/target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch b/target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch deleted file mode 100644 index f08358e963d53a..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-09-net-mtk_eth_soc-add-advertisement-programming.patch +++ /dev/null @@ -1,52 +0,0 @@ -From c125c66ea71b9377ae2478c4f1b87b180cc5c6ef Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:18 +0100 -Subject: [PATCH 08/10] net: mtk_eth_soc: add advertisement programming - -Program the advertisement into the mtk PCS block. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -70,16 +70,27 @@ static int mtk_pcs_config(struct phylink - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - unsigned int rgc3; -+ int advertise; -+ bool changed; - - if (interface == PHY_INTERFACE_MODE_2500BASEX) - rgc3 = RG_PHY_SPEED_3_125G; - else - rgc3 = 0; - -+ advertise = phylink_mii_c22_pcs_encode_advertisement(interface, -+ advertising); -+ if (advertise < 0) -+ return advertise; -+ - /* Configure the underlying interface speed */ - regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, - RG_PHY_SPEED_3_125G, rgc3); - -+ /* Update the advertisement, noting whether it has changed */ -+ regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, -+ SGMII_ADVERTISE, advertise, &changed); -+ - /* Setup SGMIISYS with the determined property */ - if (interface != PHY_INTERFACE_MODE_SGMII) - mtk_pcs_setup_mode_force(mpcs, interface); -@@ -90,7 +101,7 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, - SGMII_PHYA_PWD, 0); - -- return 0; -+ return changed; - } - - static void mtk_pcs_restart_an(struct phylink_pcs *pcs) diff --git a/target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch b/target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch deleted file mode 100644 index 602d52c6f46a3a..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-10-net-mtk_eth_soc-move-and-correct-link-timer-programm.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3027d89f87707e7f3e5b683e0d37a32afb5bde96 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:23 +0100 -Subject: [PATCH 09/10] net: mtk_eth_soc: move and correct link timer - programming - -Program the link timer appropriately for the interface mode being -used, using the newly introduced phylink helper that provides the -nanosecond link timer interval. - -The intervals are 1.6ms for SGMII based protocols and 10ms for -802.3z based protocols. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -36,10 +36,6 @@ static void mtk_pcs_get_state(struct phy - /* For SGMII interface mode */ - static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) - { -- /* Setup the link timer and QPHY power up inside SGMIISYS */ -- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, -- SGMII_LINK_TIMER_DEFAULT); -- - regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, - SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS); - -@@ -69,8 +65,8 @@ static int mtk_pcs_config(struct phylink - bool permit_pause_to_mac) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -+ int advertise, link_timer; - unsigned int rgc3; -- int advertise; - bool changed; - - if (interface == PHY_INTERFACE_MODE_2500BASEX) -@@ -83,6 +79,10 @@ static int mtk_pcs_config(struct phylink - if (advertise < 0) - return advertise; - -+ link_timer = phylink_get_link_timer_ns(interface); -+ if (link_timer < 0) -+ return link_timer; -+ - /* Configure the underlying interface speed */ - regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, - RG_PHY_SPEED_3_125G, rgc3); -@@ -91,6 +91,9 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, - SGMII_ADVERTISE, advertise, &changed); - -+ /* Setup the link timer and QPHY power up inside SGMIISYS */ -+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); -+ - /* Setup SGMIISYS with the determined property */ - if (interface != PHY_INTERFACE_MODE_SGMII) - mtk_pcs_setup_mode_force(mpcs, interface); diff --git a/target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch b/target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch deleted file mode 100644 index 0e9a0535a7b260..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-11-net-mtk_eth_soc-add-support-for-in-band-802.3z-negot.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 81b0f12a2a8a1699a7d49c3995e5f71e4ec018e6 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 27 Oct 2022 14:11:28 +0100 -Subject: [PATCH 10/10] net: mtk_eth_soc: add support for in-band 802.3z - negotiation - -As a result of help from Frank Wunderlich to investigate and test, we -now know how to program this PCS for in-band 802.3z negotiation. Add -support for this by moving the contents of the two functions into the -common mtk_pcs_config() function and adding the register settings for -802.3z negotiation. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 77 ++++++++++++----------- - 1 file changed, 42 insertions(+), 35 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -33,41 +33,15 @@ static void mtk_pcs_get_state(struct phy - FIELD_GET(SGMII_LPA, adv)); - } - --/* For SGMII interface mode */ --static void mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs) --{ -- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_REMOTE_FAULT_DIS, SGMII_REMOTE_FAULT_DIS); -- -- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -- SGMII_AN_RESTART, SGMII_AN_RESTART); --} -- --/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a -- * fixed speed. -- */ --static void mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs, -- phy_interface_t interface) --{ -- /* Disable SGMII AN */ -- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -- SGMII_AN_ENABLE, 0); -- -- /* Set the speed etc but leave the duplex unchanged */ -- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_IF_MODE_MASK & ~SGMII_DUPLEX_FULL, -- SGMII_SPEED_1000); --} -- - static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, - phy_interface_t interface, - const unsigned long *advertising, - bool permit_pause_to_mac) - { - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -+ unsigned int rgc3, sgm_mode, bmcr; - int advertise, link_timer; -- unsigned int rgc3; -- bool changed; -+ bool changed, use_an; - - if (interface == PHY_INTERFACE_MODE_2500BASEX) - rgc3 = RG_PHY_SPEED_3_125G; -@@ -83,6 +57,37 @@ static int mtk_pcs_config(struct phylink - if (link_timer < 0) - return link_timer; - -+ /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and -+ * we assume that fixes it's speed at bitrate = line rate (in -+ * other words, 1000Mbps or 2500Mbps). -+ */ -+ if (interface == PHY_INTERFACE_MODE_SGMII) { -+ sgm_mode = SGMII_IF_MODE_SGMII; -+ if (phylink_autoneg_inband(mode)) { -+ sgm_mode |= SGMII_REMOTE_FAULT_DIS | -+ SGMII_SPEED_DUPLEX_AN; -+ use_an = true; -+ } else { -+ use_an = false; -+ } -+ } else if (phylink_autoneg_inband(mode)) { -+ /* 1000base-X or 2500base-X autoneg */ -+ sgm_mode = SGMII_REMOTE_FAULT_DIS; -+ use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ advertising); -+ } else { -+ /* 1000base-X or 2500base-X without autoneg */ -+ sgm_mode = 0; -+ use_an = false; -+ } -+ -+ if (use_an) { -+ /* FIXME: Do we need to set AN_RESTART here? */ -+ bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE; -+ } else { -+ bmcr = 0; -+ } -+ - /* Configure the underlying interface speed */ - regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, - RG_PHY_SPEED_3_125G, rgc3); -@@ -94,11 +99,14 @@ static int mtk_pcs_config(struct phylink - /* Setup the link timer and QPHY power up inside SGMIISYS */ - regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); - -- /* Setup SGMIISYS with the determined property */ -- if (interface != PHY_INTERFACE_MODE_SGMII) -- mtk_pcs_setup_mode_force(mpcs, interface); -- else if (phylink_autoneg_inband(mode)) -- mtk_pcs_setup_mode_an(mpcs); -+ /* Update the sgmsys mode register */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -+ SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | -+ SGMII_IF_MODE_SGMII, sgm_mode); -+ -+ /* Update the BMCR */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -+ SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr); - - /* Release PHYA power down state */ - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -@@ -121,8 +129,7 @@ static void mtk_pcs_link_up(struct phyli - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - unsigned int sgm_mode; - -- if (!phylink_autoneg_inband(mode) || -- phy_interface_mode_is_8023z(interface)) { -+ if (!phylink_autoneg_inband(mode)) { - /* Force the speed and duplex setting */ - if (speed == SPEED_10) - sgm_mode = SGMII_SPEED_10; diff --git a/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch b/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch deleted file mode 100644 index a02c583deba4fa..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 7ff82416de8295c61423ef6fd75f052d3837d2f7 Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Wed, 1 Feb 2023 19:23:29 +0100 -Subject: [PATCH 11/13] net: mediatek: sgmii: ensure the SGMII PHY is powered - down on configuration -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The code expect the PHY to be in power down which is only true after reset. -Allow changes of the SGMII parameters more than once. - -Only power down when reconfiguring to avoid bouncing the link when there's -no reason to - based on code from Russell King. - -There are cases when the SGMII_PHYA_PWD register contains 0x9 which -prevents SGMII from working. The SGMII still shows link but no traffic -can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was -taken from a good working state of the SGMII interface. - -Fixes: 42c03844e93d ("net-next: mediatek: add support for MediaTek MT7622 SoC") -Suggested-by: Russell King (Oracle) -Signed-off-by: Alexander Couzens -[ bmork: rebased and squashed into one patch ] -Reviewed-by: Russell King (Oracle) -Signed-off-by: Bjørn Mork -Acked-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 ++ - drivers/net/ethernet/mediatek/mtk_sgmii.c | 39 +++++++++++++++------ - 2 files changed, 30 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1067,11 +1067,13 @@ struct mtk_soc_data { - * @regmap: The register map pointing at the range used to setup - * SGMII modes - * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap -+ * @interface: Currently configured interface mode - * @pcs: Phylink PCS structure - */ - struct mtk_pcs { - struct regmap *regmap; - u32 ana_rgc3; -+ phy_interface_t interface; - struct phylink_pcs pcs; - }; - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -43,11 +43,6 @@ static int mtk_pcs_config(struct phylink - int advertise, link_timer; - bool changed, use_an; - -- if (interface == PHY_INTERFACE_MODE_2500BASEX) -- rgc3 = RG_PHY_SPEED_3_125G; -- else -- rgc3 = 0; -- - advertise = phylink_mii_c22_pcs_encode_advertisement(interface, - advertising); - if (advertise < 0) -@@ -88,9 +83,22 @@ static int mtk_pcs_config(struct phylink - bmcr = 0; - } - -- /* Configure the underlying interface speed */ -- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -- RG_PHY_SPEED_3_125G, rgc3); -+ if (mpcs->interface != interface) { -+ /* PHYA power down */ -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -+ SGMII_PHYA_PWD, SGMII_PHYA_PWD); -+ -+ if (interface == PHY_INTERFACE_MODE_2500BASEX) -+ rgc3 = RG_PHY_SPEED_3_125G; -+ else -+ rgc3 = 0; -+ -+ /* Configure the underlying interface speed */ -+ regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -+ RG_PHY_SPEED_3_125G, rgc3); -+ -+ mpcs->interface = interface; -+ } - - /* Update the advertisement, noting whether it has changed */ - regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, -@@ -108,9 +116,17 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, - SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr); - -- /* Release PHYA power down state */ -- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -- SGMII_PHYA_PWD, 0); -+ /* Release PHYA power down state -+ * Only removing bit SGMII_PHYA_PWD isn't enough. -+ * There are cases when the SGMII_PHYA_PWD register contains 0x9 which -+ * prevents SGMII from working. The SGMII still shows link but no traffic -+ * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was -+ * taken from a good working state of the SGMII interface. -+ * Unknown how much the QPHY needs but it is racy without a sleep. -+ * Tested on mt7622 & mt7986. -+ */ -+ usleep_range(50, 100); -+ regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); - - return changed; - } -@@ -171,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - return PTR_ERR(ss->pcs[i].regmap); - - ss->pcs[i].pcs.ops = &mtk_pcs_ops; -+ ss->pcs[i].interface = PHY_INTERFACE_MODE_NA; - } - - return 0; diff --git a/target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch b/target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch deleted file mode 100644 index a06298c0a9cc89..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-13-net-mediatek-sgmii-fix-duplex-configuration.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 9d32637122de88f1ef614c29703f0e050cad342e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= -Date: Wed, 1 Feb 2023 19:23:30 +0100 -Subject: [PATCH 12/13] net: mediatek: sgmii: fix duplex configuration -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The logic of the duplex bit is inverted. Setting it means half -duplex, not full duplex. - -Fix and rename macro to avoid confusion. - -Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII") -Reviewed-by: Russell King (Oracle) -Signed-off-by: Bjørn Mork -Acked-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 6 +++--- - 2 files changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -534,7 +534,7 @@ - #define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) - #define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) - #define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) --#define SGMII_DUPLEX_FULL BIT(4) -+#define SGMII_DUPLEX_HALF BIT(4) - #define SGMII_IF_MODE_BIT5 BIT(5) - #define SGMII_REMOTE_FAULT_DIS BIT(8) - #define SGMII_CODE_SYNC_SET_VAL BIT(9) ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -154,11 +154,11 @@ static void mtk_pcs_link_up(struct phyli - else - sgm_mode = SGMII_SPEED_1000; - -- if (duplex == DUPLEX_FULL) -- sgm_mode |= SGMII_DUPLEX_FULL; -+ if (duplex != DUPLEX_FULL) -+ sgm_mode |= SGMII_DUPLEX_HALF; - - regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_DUPLEX_FULL | SGMII_SPEED_MASK, -+ SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, - sgm_mode); - } - } diff --git a/target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch b/target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch deleted file mode 100644 index 56d7a1348fb17d..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.2-14-mtk_sgmii-enable-PCS-polling-to-allow-SFP-work.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 3337a6e04ddf2923a1bdcf3d31b3b52412bf82dd Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Wed, 1 Feb 2023 19:23:31 +0100 -Subject: [PATCH 13/13] mtk_sgmii: enable PCS polling to allow SFP work -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently there is no IRQ handling (even the SGMII supports it). -Enable polling to support SFP ports. - -Fixes: 14a44ab0330d ("net: mtk_eth_soc: partially convert to phylink_pcs") -Reviewed-by: Russell King (Oracle) -Signed-off-by: Alexander Couzens -[ bmork: changed "1" => "true" ] -Signed-off-by: Bjørn Mork -Acked-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -187,6 +187,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - return PTR_ERR(ss->pcs[i].regmap); - - ss->pcs[i].pcs.ops = &mtk_pcs_ops; -+ ss->pcs[i].pcs.poll = true; - ss->pcs[i].interface = PHY_INTERFACE_MODE_NA; - } - diff --git a/target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch b/target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch deleted file mode 100644 index 6acc62d4abca43..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.3-15-net-ethernet-mtk_eth_soc-reset-PCS-state.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 611e2dabb4b3243d176739fd6a5a34d007fa3f86 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 14 Mar 2023 00:34:26 +0000 -Subject: [PATCH 1/2] net: ethernet: mtk_eth_soc: reset PCS state -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Reset the internal PCS state machine when changing interface mode. -This prevents confusing the state machine when changing interface -modes, e.g. from SGMII to 2500Base-X or vice-versa. - -Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII") -Reviewed-by: Russell King (Oracle) -Tested-by: Bjørn Mork -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++ - drivers/net/ethernet/mediatek/mtk_sgmii.c | 4 ++++ - 2 files changed, 8 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -542,6 +542,10 @@ - #define SGMII_SEND_AN_ERROR_EN BIT(11) - #define SGMII_IF_MODE_MASK GENMASK(5, 1) - -+/* Register to reset SGMII design */ -+#define SGMII_RESERVED_0 0x34 -+#define SGMII_SW_RESET BIT(0) -+ - /* Register to set SGMII speed, ANA RG_ Control Signals III*/ - #define SGMSYS_ANA_RG_CS3 0x2028 - #define RG_PHY_SPEED_MASK (BIT(2) | BIT(3)) ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -88,6 +88,10 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, - SGMII_PHYA_PWD, SGMII_PHYA_PWD); - -+ /* Reset SGMII PCS state */ -+ regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0, -+ SGMII_SW_RESET, SGMII_SW_RESET); -+ - if (interface == PHY_INTERFACE_MODE_2500BASEX) - rgc3 = RG_PHY_SPEED_3_125G; - else diff --git a/target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch b/target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch deleted file mode 100644 index 0fabeea20c07ae..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.3-16-net-ethernet-mtk_eth_soc-only-write-values-if-needed.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 6e933a804c7db8be64f367f33e63cd7dcc302ebb Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 14 Mar 2023 00:34:45 +0000 -Subject: [PATCH 2/2] net: ethernet: mtk_eth_soc: only write values if needed -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Only restart auto-negotiation and write link timer if actually -necessary. This prevents losing the link in case of minor -changes. - -Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII") -Reviewed-by: Russell King (Oracle) -Tested-by: Bjørn Mork -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++++++++------------ - 1 file changed, 12 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink - const unsigned long *advertising, - bool permit_pause_to_mac) - { -+ bool mode_changed = false, changed, use_an; - struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); - unsigned int rgc3, sgm_mode, bmcr; - int advertise, link_timer; -- bool changed, use_an; - - advertise = phylink_mii_c22_pcs_encode_advertisement(interface, - advertising); - if (advertise < 0) - return advertise; - -- link_timer = phylink_get_link_timer_ns(interface); -- if (link_timer < 0) -- return link_timer; -- - /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and - * we assume that fixes it's speed at bitrate = line rate (in - * other words, 1000Mbps or 2500Mbps). -@@ -77,13 +73,16 @@ static int mtk_pcs_config(struct phylink - } - - if (use_an) { -- /* FIXME: Do we need to set AN_RESTART here? */ -- bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE; -+ bmcr = SGMII_AN_ENABLE; - } else { - bmcr = 0; - } - - if (mpcs->interface != interface) { -+ link_timer = phylink_get_link_timer_ns(interface); -+ if (link_timer < 0) -+ return link_timer; -+ - /* PHYA power down */ - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, - SGMII_PHYA_PWD, SGMII_PHYA_PWD); -@@ -101,16 +100,17 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, - RG_PHY_SPEED_3_125G, rgc3); - -+ /* Setup the link timer */ -+ regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); -+ - mpcs->interface = interface; -+ mode_changed = true; - } - - /* Update the advertisement, noting whether it has changed */ - regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, - SGMII_ADVERTISE, advertise, &changed); - -- /* Setup the link timer and QPHY power up inside SGMIISYS */ -- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); -- - /* Update the sgmsys mode register */ - regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, - SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | -@@ -118,7 +118,7 @@ static int mtk_pcs_config(struct phylink - - /* Update the BMCR */ - regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -- SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr); -+ SGMII_AN_ENABLE, bmcr); - - /* Release PHYA power down state - * Only removing bit SGMII_PHYA_PWD isn't enough. -@@ -132,7 +132,7 @@ static int mtk_pcs_config(struct phylink - usleep_range(50, 100); - regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); - -- return changed; -+ return changed || mode_changed; - } - - static void mtk_pcs_restart_an(struct phylink_pcs *pcs) diff --git a/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch b/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch deleted file mode 100644 index 3f3f73183e9004..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch +++ /dev/null @@ -1,206 +0,0 @@ -From f5d43ddd334b7c32fcaed9ba46afbd85cb467f1f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 19 Mar 2023 12:56:28 +0000 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for MT7981 SoC - -The MediaTek MT7981 SoC comes with two 1G/2.5G SGMII ports, just like -MT7986. - -In addition MT7981 is equipped with a built-in 1000Base-T PHY which can -be used with GMAC1. - -As many MT7981 boards make use of inverting SGMII signal polarity, add -new device-tree attribute 'mediatek,pn_swap' to support them. - -Signed-off-by: Daniel Golle -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 31 ++++++++++++++++++++ - drivers/net/ethernet/mediatek/mtk_sgmii.c | 10 +++++++ - 4 files changed, 73 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -96,12 +96,20 @@ static int set_mux_gmac2_gmac0_to_gephy( - - static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path) - { -- unsigned int val = 0; -+ unsigned int val = 0, mask = 0, reg = 0; - bool updated = true; - - switch (path) { - case MTK_ETH_PATH_GMAC2_SGMII: -- val = CO_QPHY_SEL; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_U3_COPHY_V2)) { -+ reg = USB_PHY_SWITCH_REG; -+ val = SGMII_QPHY_SEL; -+ mask = QPHY_SEL_MASK; -+ } else { -+ reg = INFRA_MISC2; -+ val = CO_QPHY_SEL; -+ mask = val; -+ } - break; - default: - updated = false; -@@ -109,7 +117,7 @@ static int set_mux_u3_gmac2_to_qphy(stru - } - - if (updated) -- regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val); -+ regmap_update_bits(eth->infra, reg, mask, val); - - dev_dbg(eth->dev, "path %s in %s updated = %d\n", - mtk_eth_path_name(path), __func__, updated); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4802,6 +4802,26 @@ static const struct mtk_soc_data mt7629_ - }, - }; - -+static const struct mtk_soc_data mt7981_data = { -+ .reg_map = &mt7986_reg_map, -+ .ana_rgc3 = 0x128, -+ .caps = MT7981_CAPS, -+ .hw_features = MTK_HW_FEATURES, -+ .required_clks = MT7981_CLKS_BITMAP, -+ .required_pctl = false, -+ .offload_version = 2, -+ .hash_offset = 4, -+ .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma_v2), -+ .rxd_size = sizeof(struct mtk_rx_dma_v2), -+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, -+ .dma_len_offset = 8, -+ }, -+}; -+ - static const struct mtk_soc_data mt7986_data = { - .reg_map = &mt7986_reg_map, - .ana_rgc3 = 0x128, -@@ -4844,6 +4864,7 @@ const struct of_device_id of_mtk_match[] - { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, - { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, - { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, -+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data}, - { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, - { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, - {}, ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -556,11 +556,22 @@ - #define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 - #define SGMII_PHYA_PWD BIT(4) - -+/* Register to QPHY wrapper control */ -+#define SGMSYS_QPHY_WRAP_CTRL 0xec -+#define SGMII_PN_SWAP_MASK GENMASK(1, 0) -+#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) -+#define MTK_SGMII_FLAG_PN_SWAP BIT(0) -+ - /* Infrasys subsystem config registers */ - #define INFRA_MISC2 0x70c - #define CO_QPHY_SEL BIT(0) - #define GEPHY_MAC_SEL BIT(1) - -+/* Top misc registers */ -+#define USB_PHY_SWITCH_REG 0x218 -+#define QPHY_SEL_MASK GENMASK(1, 0) -+#define SGMII_QPHY_SEL 0x2 -+ - /* MT7628/88 specific stuff */ - #define MT7628_PDMA_OFFSET 0x0800 - #define MT7628_SDM_OFFSET 0x0c00 -@@ -741,6 +752,17 @@ enum mtk_clks_map { - BIT(MTK_CLK_SGMII2_CDR_FB) | \ - BIT(MTK_CLK_SGMII_CK) | \ - BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) -+#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -+ BIT(MTK_CLK_WOCPU0) | \ -+ BIT(MTK_CLK_SGMII_TX_250M) | \ -+ BIT(MTK_CLK_SGMII_RX_250M) | \ -+ BIT(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT(MTK_CLK_SGMII2_CDR_FB) | \ -+ BIT(MTK_CLK_SGMII_CK)) - #define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ - BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ - BIT(MTK_CLK_SGMII_TX_250M) | \ -@@ -854,6 +876,7 @@ enum mkt_eth_capabilities { - MTK_NETSYS_V2_BIT, - MTK_SOC_MT7628_BIT, - MTK_RSTCTRL_PPE1_BIT, -+ MTK_U3_COPHY_V2_BIT, - - /* MUX BITS*/ - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, -@@ -888,6 +911,7 @@ enum mkt_eth_capabilities { - #define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) - #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) - #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) -+#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ - BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -@@ -960,6 +984,11 @@ enum mkt_eth_capabilities { - MTK_MUX_U3_GMAC2_TO_QPHY | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA) - -+#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ -+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ -+ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ -+ MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -+ - #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -@@ -1073,12 +1102,14 @@ struct mtk_soc_data { - * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap - * @interface: Currently configured interface mode - * @pcs: Phylink PCS structure -+ * @flags: Flags indicating hardware properties - */ - struct mtk_pcs { - struct regmap *regmap; - u32 ana_rgc3; - phy_interface_t interface; - struct phylink_pcs pcs; -+ u32 flags; - }; - - /* struct mtk_sgmii - This is the structure holding sgmii regmap and its ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c -@@ -87,6 +87,11 @@ static int mtk_pcs_config(struct phylink - regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, - SGMII_PHYA_PWD, SGMII_PHYA_PWD); - -+ if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP) -+ regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, -+ SGMII_PN_SWAP_MASK, -+ SGMII_PN_SWAP_TX_RX); -+ - /* Reset SGMII PCS state */ - regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0, - SGMII_SW_RESET, SGMII_SW_RESET); -@@ -186,6 +191,11 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, - - ss->pcs[i].ana_rgc3 = ana_rgc3; - ss->pcs[i].regmap = syscon_node_to_regmap(np); -+ -+ ss->pcs[i].flags = 0; -+ if (of_property_read_bool(np, "mediatek,pnswap")) -+ ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP; -+ - of_node_put(np); - if (IS_ERR(ss->pcs[i].regmap)) - return PTR_ERR(ss->pcs[i].regmap); diff --git a/target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch b/target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch deleted file mode 100644 index c60a4337efe2cb..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.3-19-net-ethernet-mtk_eth_soc-set-MDIO-bus-clock-frequenc.patch +++ /dev/null @@ -1,76 +0,0 @@ -From c0a440031d4314d1023c1b87f43a4233634eebdb Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 19 Mar 2023 12:57:15 +0000 -Subject: [PATCH] net: ethernet: mtk_eth_soc: set MDIO bus clock frequency -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Set MDIO bus clock frequency and allow setting a custom maximum -frequency from device tree. - -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Tested-by: Bjørn Mork -Signed-off-by: Daniel Golle -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++++++++++ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 7 +++++++ - 2 files changed, 28 insertions(+) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -743,8 +743,10 @@ static const struct phylink_mac_ops mtk_ - - static int mtk_mdio_init(struct mtk_eth *eth) - { -+ unsigned int max_clk = 2500000, divider; - struct device_node *mii_np; - int ret; -+ u32 val; - - mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus"); - if (!mii_np) { -@@ -771,6 +773,25 @@ static int mtk_mdio_init(struct mtk_eth - eth->mii_bus->parent = eth->dev; - - snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np); -+ -+ if (!of_property_read_u32(mii_np, "clock-frequency", &val)) { -+ if (val > MDC_MAX_FREQ || val < MDC_MAX_FREQ / MDC_MAX_DIVIDER) { -+ dev_err(eth->dev, "MDIO clock frequency out of range"); -+ ret = -EINVAL; -+ goto err_put_node; -+ } -+ max_clk = val; -+ } -+ divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63); -+ -+ /* Configure MDC Divider */ -+ val = mtk_r32(eth, MTK_PPSC); -+ val &= ~PPSC_MDC_CFG; -+ val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO; -+ mtk_w32(eth, val, MTK_PPSC); -+ -+ dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider); -+ - ret = of_mdiobus_register(eth->mii_bus, mii_np); - - err_put_node: ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -363,6 +363,13 @@ - #define RX_DMA_VTAG_V2 BIT(0) - #define RX_DMA_L4_VALID_V2 BIT(2) - -+/* PHY Polling and SMI Master Control registers */ -+#define MTK_PPSC 0x10000 -+#define PPSC_MDC_CFG GENMASK(29, 24) -+#define PPSC_MDC_TURBO BIT(20) -+#define MDC_MAX_FREQ 25000000 -+#define MDC_MAX_DIVIDER 63 -+ - /* PHY Indirect Access Control registers */ - #define MTK_PHY_IAC 0x10004 - #define PHY_IAC_ACCESS BIT(31) diff --git a/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch b/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch deleted file mode 100644 index d73eccedbbd24d..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch +++ /dev/null @@ -1,512 +0,0 @@ -From 2a3ec7ae313310c1092e4256208cc04d1958e469 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 19 Mar 2023 12:58:02 +0000 -Subject: [PATCH] net: ethernet: mtk_eth_soc: switch to external PCS driver - -Now that we got a PCS driver, use it and remove the now redundant -PCS code and it's header macros from the Ethernet driver. - -Signed-off-by: Daniel Golle -Tested-by: Frank Wunderlich -Reviewed-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/Kconfig | 2 + - drivers/net/ethernet/mediatek/Makefile | 2 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 61 +++++- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 93 +-------- - drivers/net/ethernet/mediatek/mtk_sgmii.c | 217 -------------------- - 5 files changed, 56 insertions(+), 319 deletions(-) - delete mode 100644 drivers/net/ethernet/mediatek/mtk_sgmii.c - ---- a/drivers/net/ethernet/mediatek/Kconfig -+++ b/drivers/net/ethernet/mediatek/Kconfig -@@ -19,6 +19,8 @@ config NET_MEDIATEK_SOC - select DIMLIB - select PAGE_POOL - select PAGE_POOL_STATS -+ select PCS_MTK_LYNXI -+ select REGMAP_MMIO - help - This driver supports the gigabit ethernet MACs in the - MediaTek SoC family. ---- a/drivers/net/ethernet/mediatek/Makefile -+++ b/drivers/net/ethernet/mediatek/Makefile -@@ -4,7 +4,7 @@ - # - - obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o --mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o -+mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o - ifdef CONFIG_DEBUG_FS - mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -400,7 +401,7 @@ static struct phylink_pcs *mtk_mac_selec - sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? - 0 : mac->id; - -- return mtk_sgmii_select_pcs(eth->sgmii, sid); -+ return eth->sgmii_pcs[sid]; - } - - return NULL; -@@ -4015,8 +4016,17 @@ static int mtk_unreg_dev(struct mtk_eth - return 0; - } - -+static void mtk_sgmii_destroy(struct mtk_eth *eth) -+{ -+ int i; -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) -+ mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]); -+} -+ - static int mtk_cleanup(struct mtk_eth *eth) - { -+ mtk_sgmii_destroy(eth); - mtk_unreg_dev(eth); - mtk_free_dev(eth); - cancel_work_sync(ð->pending_work); -@@ -4456,6 +4466,36 @@ void mtk_eth_set_dma_device(struct mtk_e - rtnl_unlock(); - } - -+static int mtk_sgmii_init(struct mtk_eth *eth) -+{ -+ struct device_node *np; -+ struct regmap *regmap; -+ u32 flags; -+ int i; -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i); -+ if (!np) -+ break; -+ -+ regmap = syscon_node_to_regmap(np); -+ flags = 0; -+ if (of_property_read_bool(np, "mediatek,pnswap")) -+ flags |= MTK_SGMII_FLAG_PN_SWAP; -+ -+ of_node_put(np); -+ -+ if (IS_ERR(regmap)) -+ return PTR_ERR(regmap); -+ -+ eth->sgmii_pcs[i] = mtk_pcs_lynxi_create(eth->dev, regmap, -+ eth->soc->ana_rgc3, -+ flags); -+ } -+ -+ return 0; -+} -+ - static int mtk_probe(struct platform_device *pdev) - { - struct resource *res = NULL; -@@ -4519,13 +4559,7 @@ static int mtk_probe(struct platform_dev - } - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { -- eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii), -- GFP_KERNEL); -- if (!eth->sgmii) -- return -ENOMEM; -- -- err = mtk_sgmii_init(eth->sgmii, pdev->dev.of_node, -- eth->soc->ana_rgc3); -+ err = mtk_sgmii_init(eth); - - if (err) - return err; -@@ -4536,14 +4570,17 @@ static int mtk_probe(struct platform_dev - "mediatek,pctl"); - if (IS_ERR(eth->pctl)) { - dev_err(&pdev->dev, "no pctl regmap found\n"); -- return PTR_ERR(eth->pctl); -+ err = PTR_ERR(eth->pctl); -+ goto err_destroy_sgmii; - } - } - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (!res) -- return -EINVAL; -+ if (!res) { -+ err = -EINVAL; -+ goto err_destroy_sgmii; -+ } - } - - if (eth->soc->offload_version) { -@@ -4702,6 +4739,8 @@ err_deinit_hw: - mtk_hw_deinit(eth); - err_wed_exit: - mtk_wed_exit(); -+err_destroy_sgmii: -+ mtk_sgmii_destroy(eth); - - return err; - } ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -510,65 +510,6 @@ - #define ETHSYS_DMA_AG_MAP_QDMA BIT(1) - #define ETHSYS_DMA_AG_MAP_PPE BIT(2) - --/* SGMII subsystem config registers */ --/* BMCR (low 16) BMSR (high 16) */ --#define SGMSYS_PCS_CONTROL_1 0x0 --#define SGMII_BMCR GENMASK(15, 0) --#define SGMII_BMSR GENMASK(31, 16) --#define SGMII_AN_RESTART BIT(9) --#define SGMII_ISOLATE BIT(10) --#define SGMII_AN_ENABLE BIT(12) --#define SGMII_LINK_STATYS BIT(18) --#define SGMII_AN_ABILITY BIT(19) --#define SGMII_AN_COMPLETE BIT(21) --#define SGMII_PCS_FAULT BIT(23) --#define SGMII_AN_EXPANSION_CLR BIT(30) -- --#define SGMSYS_PCS_ADVERTISE 0x8 --#define SGMII_ADVERTISE GENMASK(15, 0) --#define SGMII_LPA GENMASK(31, 16) -- --/* Register to programmable link timer, the unit in 2 * 8ns */ --#define SGMSYS_PCS_LINK_TIMER 0x18 --#define SGMII_LINK_TIMER_MASK GENMASK(19, 0) --#define SGMII_LINK_TIMER_DEFAULT (0x186a0 & SGMII_LINK_TIMER_MASK) -- --/* Register to control remote fault */ --#define SGMSYS_SGMII_MODE 0x20 --#define SGMII_IF_MODE_SGMII BIT(0) --#define SGMII_SPEED_DUPLEX_AN BIT(1) --#define SGMII_SPEED_MASK GENMASK(3, 2) --#define SGMII_SPEED_10 FIELD_PREP(SGMII_SPEED_MASK, 0) --#define SGMII_SPEED_100 FIELD_PREP(SGMII_SPEED_MASK, 1) --#define SGMII_SPEED_1000 FIELD_PREP(SGMII_SPEED_MASK, 2) --#define SGMII_DUPLEX_HALF BIT(4) --#define SGMII_IF_MODE_BIT5 BIT(5) --#define SGMII_REMOTE_FAULT_DIS BIT(8) --#define SGMII_CODE_SYNC_SET_VAL BIT(9) --#define SGMII_CODE_SYNC_SET_EN BIT(10) --#define SGMII_SEND_AN_ERROR_EN BIT(11) --#define SGMII_IF_MODE_MASK GENMASK(5, 1) -- --/* Register to reset SGMII design */ --#define SGMII_RESERVED_0 0x34 --#define SGMII_SW_RESET BIT(0) -- --/* Register to set SGMII speed, ANA RG_ Control Signals III*/ --#define SGMSYS_ANA_RG_CS3 0x2028 --#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3)) --#define RG_PHY_SPEED_1_25G 0x0 --#define RG_PHY_SPEED_3_125G BIT(2) -- --/* Register to power up QPHY */ --#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 --#define SGMII_PHYA_PWD BIT(4) -- --/* Register to QPHY wrapper control */ --#define SGMSYS_QPHY_WRAP_CTRL 0xec --#define SGMII_PN_SWAP_MASK GENMASK(1, 0) --#define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) --#define MTK_SGMII_FLAG_PN_SWAP BIT(0) -- - /* Infrasys subsystem config registers */ - #define INFRA_MISC2 0x70c - #define CO_QPHY_SEL BIT(0) -@@ -1102,31 +1043,6 @@ struct mtk_soc_data { - /* currently no SoC has more than 2 macs */ - #define MTK_MAX_DEVS 2 - --/* struct mtk_pcs - This structure holds each sgmii regmap and associated -- * data -- * @regmap: The register map pointing at the range used to setup -- * SGMII modes -- * @ana_rgc3: The offset refers to register ANA_RGC3 related to regmap -- * @interface: Currently configured interface mode -- * @pcs: Phylink PCS structure -- * @flags: Flags indicating hardware properties -- */ --struct mtk_pcs { -- struct regmap *regmap; -- u32 ana_rgc3; -- phy_interface_t interface; -- struct phylink_pcs pcs; -- u32 flags; --}; -- --/* struct mtk_sgmii - This is the structure holding sgmii regmap and its -- * characteristics -- * @pcs Array of individual PCS structures -- */ --struct mtk_sgmii { -- struct mtk_pcs pcs[MTK_MAX_DEVS]; --}; -- - /* struct mtk_eth - This is the main datasructure for holding the state - * of the driver - * @dev: The device pointer -@@ -1146,6 +1062,7 @@ struct mtk_sgmii { - * MII modes - * @infra: The register map pointing at the range used to setup - * SGMII and GePHY path -+ * @sgmii_pcs: Pointers to mtk-pcs-lynxi phylink_pcs instances - * @pctl: The register map pointing at the range used to setup - * GMAC port drive/slew values - * @dma_refcnt: track how many netdevs are using the DMA engine -@@ -1186,8 +1103,8 @@ struct mtk_eth { - u32 msg_enable; - unsigned long sysclk; - struct regmap *ethsys; -- struct regmap *infra; -- struct mtk_sgmii *sgmii; -+ struct regmap *infra; -+ struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS]; - struct regmap *pctl; - bool hwlro; - refcount_t dma_refcnt; -@@ -1349,10 +1266,6 @@ void mtk_stats_update_mac(struct mtk_mac - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); - u32 mtk_r32(struct mtk_eth *eth, unsigned reg); - --struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id); --int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np, -- u32 ana_rgc3); -- - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); ---- a/drivers/net/ethernet/mediatek/mtk_sgmii.c -+++ /dev/null -@@ -1,217 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0 --// Copyright (c) 2018-2019 MediaTek Inc. -- --/* A library for MediaTek SGMII circuit -- * -- * Author: Sean Wang -- * -- */ -- --#include --#include --#include --#include -- --#include "mtk_eth_soc.h" -- --static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs) --{ -- return container_of(pcs, struct mtk_pcs, pcs); --} -- --static void mtk_pcs_get_state(struct phylink_pcs *pcs, -- struct phylink_link_state *state) --{ -- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- unsigned int bm, adv; -- -- /* Read the BMSR and LPA */ -- regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); -- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -- -- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), -- FIELD_GET(SGMII_LPA, adv)); --} -- --static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -- phy_interface_t interface, -- const unsigned long *advertising, -- bool permit_pause_to_mac) --{ -- bool mode_changed = false, changed, use_an; -- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- unsigned int rgc3, sgm_mode, bmcr; -- int advertise, link_timer; -- -- advertise = phylink_mii_c22_pcs_encode_advertisement(interface, -- advertising); -- if (advertise < 0) -- return advertise; -- -- /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and -- * we assume that fixes it's speed at bitrate = line rate (in -- * other words, 1000Mbps or 2500Mbps). -- */ -- if (interface == PHY_INTERFACE_MODE_SGMII) { -- sgm_mode = SGMII_IF_MODE_SGMII; -- if (phylink_autoneg_inband(mode)) { -- sgm_mode |= SGMII_REMOTE_FAULT_DIS | -- SGMII_SPEED_DUPLEX_AN; -- use_an = true; -- } else { -- use_an = false; -- } -- } else if (phylink_autoneg_inband(mode)) { -- /* 1000base-X or 2500base-X autoneg */ -- sgm_mode = SGMII_REMOTE_FAULT_DIS; -- use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -- advertising); -- } else { -- /* 1000base-X or 2500base-X without autoneg */ -- sgm_mode = 0; -- use_an = false; -- } -- -- if (use_an) { -- bmcr = SGMII_AN_ENABLE; -- } else { -- bmcr = 0; -- } -- -- if (mpcs->interface != interface) { -- link_timer = phylink_get_link_timer_ns(interface); -- if (link_timer < 0) -- return link_timer; -- -- /* PHYA power down */ -- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, -- SGMII_PHYA_PWD, SGMII_PHYA_PWD); -- -- if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP) -- regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL, -- SGMII_PN_SWAP_MASK, -- SGMII_PN_SWAP_TX_RX); -- -- /* Reset SGMII PCS state */ -- regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0, -- SGMII_SW_RESET, SGMII_SW_RESET); -- -- if (interface == PHY_INTERFACE_MODE_2500BASEX) -- rgc3 = RG_PHY_SPEED_3_125G; -- else -- rgc3 = 0; -- -- /* Configure the underlying interface speed */ -- regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3, -- RG_PHY_SPEED_3_125G, rgc3); -- -- /* Setup the link timer */ -- regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8); -- -- mpcs->interface = interface; -- mode_changed = true; -- } -- -- /* Update the advertisement, noting whether it has changed */ -- regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE, -- SGMII_ADVERTISE, advertise, &changed); -- -- /* Update the sgmsys mode register */ -- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN | -- SGMII_IF_MODE_SGMII, sgm_mode); -- -- /* Update the BMCR */ -- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -- SGMII_AN_ENABLE, bmcr); -- -- /* Release PHYA power down state -- * Only removing bit SGMII_PHYA_PWD isn't enough. -- * There are cases when the SGMII_PHYA_PWD register contains 0x9 which -- * prevents SGMII from working. The SGMII still shows link but no traffic -- * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was -- * taken from a good working state of the SGMII interface. -- * Unknown how much the QPHY needs but it is racy without a sleep. -- * Tested on mt7622 & mt7986. -- */ -- usleep_range(50, 100); -- regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0); -- -- return changed || mode_changed; --} -- --static void mtk_pcs_restart_an(struct phylink_pcs *pcs) --{ -- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- -- regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1, -- SGMII_AN_RESTART, SGMII_AN_RESTART); --} -- --static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -- phy_interface_t interface, int speed, int duplex) --{ -- struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs); -- unsigned int sgm_mode; -- -- if (!phylink_autoneg_inband(mode)) { -- /* Force the speed and duplex setting */ -- if (speed == SPEED_10) -- sgm_mode = SGMII_SPEED_10; -- else if (speed == SPEED_100) -- sgm_mode = SGMII_SPEED_100; -- else -- sgm_mode = SGMII_SPEED_1000; -- -- if (duplex != DUPLEX_FULL) -- sgm_mode |= SGMII_DUPLEX_HALF; -- -- regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE, -- SGMII_DUPLEX_HALF | SGMII_SPEED_MASK, -- sgm_mode); -- } --} -- --static const struct phylink_pcs_ops mtk_pcs_ops = { -- .pcs_get_state = mtk_pcs_get_state, -- .pcs_config = mtk_pcs_config, -- .pcs_an_restart = mtk_pcs_restart_an, -- .pcs_link_up = mtk_pcs_link_up, --}; -- --int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) --{ -- struct device_node *np; -- int i; -- -- for (i = 0; i < MTK_MAX_DEVS; i++) { -- np = of_parse_phandle(r, "mediatek,sgmiisys", i); -- if (!np) -- break; -- -- ss->pcs[i].ana_rgc3 = ana_rgc3; -- ss->pcs[i].regmap = syscon_node_to_regmap(np); -- -- ss->pcs[i].flags = 0; -- if (of_property_read_bool(np, "mediatek,pnswap")) -- ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP; -- -- of_node_put(np); -- if (IS_ERR(ss->pcs[i].regmap)) -- return PTR_ERR(ss->pcs[i].regmap); -- -- ss->pcs[i].pcs.ops = &mtk_pcs_ops; -- ss->pcs[i].pcs.poll = true; -- ss->pcs[i].interface = PHY_INTERFACE_MODE_NA; -- } -- -- return 0; --} -- --struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id) --{ -- if (!ss->pcs[id].regmap) -- return NULL; -- -- return &ss->pcs[id].pcs; --} diff --git a/target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch b/target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch deleted file mode 100644 index 9ce2735951c897..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch +++ /dev/null @@ -1,46 +0,0 @@ -From f5af7931d2a2cae66d0f9dad4ba517b1b00620b3 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 19 Apr 2023 19:07:23 +0100 -Subject: [PATCH] net: mtk_eth_soc: use WO firmware for MT7981 - -In order to support wireless offloading on MT7981 we need to load the -appropriate firmware. Recognize MT7981 and load mt7981_wo.bin. - -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 7 ++++++- - drivers/net/ethernet/mediatek/mtk_wed_wo.h | 1 + - 2 files changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -326,7 +326,11 @@ mtk_wed_mcu_load_firmware(struct mtk_wed - wo->hw->index + 1); - - /* load firmware */ -- fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; -+ if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed")) -+ fw_name = MT7981_FIRMWARE_WO; -+ else -+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; -+ - ret = request_firmware(&fw, fw_name, wo->hw->dev); - if (ret) - return ret; -@@ -386,5 +390,6 @@ int mtk_wed_mcu_init(struct mtk_wed_wo * - 100, MTK_FW_DL_TIMEOUT); - } - -+MODULE_FIRMWARE(MT7981_FIRMWARE_WO); - MODULE_FIRMWARE(MT7986_FIRMWARE_WO0); - MODULE_FIRMWARE(MT7986_FIRMWARE_WO1); ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -88,6 +88,7 @@ enum mtk_wed_dummy_cr_idx { - MTK_WED_DUMMY_CR_WO_STATUS, - }; - -+#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin" - #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" - #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" - diff --git a/target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch b/target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch deleted file mode 100644 index d715c4aa6867b9..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 7c83e28f10830aa5105c25eaabe890e3adac36aa Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 9 May 2023 03:20:06 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix NULL pointer dereference - -Check for NULL pointer to avoid kernel crashing in case of missing WO -firmware in case only a single WEDv2 device has been initialized, e.g. on -MT7981 which can connect just one wireless frontend. - -Fixes: 86ce0d09e424 ("net: ethernet: mtk_eth_soc: use WO firmware for MT7981") -Signed-off-by: Daniel Golle -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -647,7 +647,7 @@ __mtk_wed_detach(struct mtk_wed_device * - BIT(hw->index), BIT(hw->index)); - } - -- if (!hw_list[!hw->index]->wed_dev && -+ if ((!hw_list[!hw->index] || !hw_list[!hw->index]->wed_dev) && - hw->eth->dma_dev != hw->eth->dev) - mtk_eth_set_dma_device(hw->eth, hw->eth->dev); - diff --git a/target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch b/target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch deleted file mode 100644 index 5c3de5759186d9..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch +++ /dev/null @@ -1,403 +0,0 @@ -From f601293f37c4be618c5efaef85d2ee21f97e82e0 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 19 Mar 2023 12:57:35 +0000 -Subject: [PATCH 092/250] net: ethernet: mtk_eth_soc: ppe: add support for flow - accounting -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The PPE units found in MT7622 and newer support packet and byte -accounting of hw-offloaded flows. Add support for reading those counters -as found in MediaTek's SDK[1]. - -[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92 -Tested-by: Bjørn Mork -Signed-off-by: Daniel Golle -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 + - drivers/net/ethernet/mediatek/mtk_ppe.c | 114 +++++++++++++++++- - drivers/net/ethernet/mediatek/mtk_ppe.h | 25 +++- - .../net/ethernet/mediatek/mtk_ppe_debugfs.c | 9 +- - .../net/ethernet/mediatek/mtk_ppe_offload.c | 8 ++ - drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 14 +++ - 7 files changed, 172 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4690,8 +4690,8 @@ static int mtk_probe(struct platform_dev - for (i = 0; i < num_ppe; i++) { - u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; - -- eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, -- eth->soc->offload_version, i); -+ eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i); -+ - if (!eth->ppe[i]) { - err = -ENOMEM; - goto err_deinit_ppe; -@@ -4815,6 +4815,7 @@ static const struct mtk_soc_data mt7622_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 2, -+ .has_accounting = true, - .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), -@@ -4852,6 +4853,7 @@ static const struct mtk_soc_data mt7629_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7629_CLKS_BITMAP, - .required_pctl = false, -+ .has_accounting = true, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4872,6 +4874,7 @@ static const struct mtk_soc_data mt7981_ - .offload_version = 2, - .hash_offset = 4, - .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .has_accounting = true, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), -@@ -4892,6 +4895,7 @@ static const struct mtk_soc_data mt7986_ - .offload_version = 2, - .hash_offset = 4, - .foe_entry_size = sizeof(struct mtk_foe_entry), -+ .has_accounting = true, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1011,6 +1011,8 @@ struct mtk_reg_map { - * the extra setup for those pins used by GMAC. - * @hash_offset Flow table hash offset. - * @foe_entry_size Foe table entry size. -+ * @has_accounting Bool indicating support for accounting of -+ * offloaded flows. - * @txd_size Tx DMA descriptor size. - * @rxd_size Rx DMA descriptor size. - * @rx_irq_done_mask Rx irq done register mask. -@@ -1028,6 +1030,7 @@ struct mtk_soc_data { - u8 hash_offset; - u16 foe_entry_size; - netdev_features_t hw_features; -+ bool has_accounting; - struct { - u32 txd_size; - u32 rxd_size; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_ - return ret; - } - -+static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe) -+{ -+ int ret; -+ u32 val; -+ -+ ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val, -+ !(val & MTK_PPE_MIB_SER_CR_ST), -+ 20, MTK_PPE_WAIT_TIMEOUT_US); -+ -+ if (ret) -+ dev_err(ppe->dev, "MIB table busy"); -+ -+ return ret; -+} -+ -+static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) -+{ -+ u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high; -+ u32 val, cnt_r0, cnt_r1, cnt_r2; -+ int ret; -+ -+ val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST; -+ ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val); -+ -+ ret = mtk_ppe_mib_wait_busy(ppe); -+ if (ret) -+ return ret; -+ -+ cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0); -+ cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); -+ cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2); -+ -+ byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); -+ byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); -+ pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); -+ pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -+ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -+ *packets = (pkt_cnt_high << 16) | pkt_cnt_low; -+ -+ return 0; -+} -+ - static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) - { - ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR); -@@ -459,6 +501,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); - dma_wmb(); - mtk_ppe_cache_clear(ppe); -+ if (ppe->accounting) { -+ struct mtk_foe_accounting *acct; -+ -+ acct = ppe->acct_table + entry->hash * sizeof(*acct); -+ acct->packets = 0; -+ acct->bytes = 0; -+ } - } - entry->hash = 0xffff; - -@@ -566,6 +615,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - wmb(); - hwe->ib1 = entry->ib1; - -+ if (ppe->accounting) -+ *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT; -+ - dma_wmb(); - - mtk_ppe_cache_clear(ppe); -@@ -757,11 +809,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe - return mtk_ppe_wait_busy(ppe); - } - --struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, -- int version, int index) -+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -+ struct mtk_foe_accounting *diff) -+{ -+ struct mtk_foe_accounting *acct; -+ int size = sizeof(struct mtk_foe_accounting); -+ u64 bytes, packets; -+ -+ if (!ppe->accounting) -+ return NULL; -+ -+ if (mtk_mib_entry_read(ppe, index, &bytes, &packets)) -+ return NULL; -+ -+ acct = ppe->acct_table + index * size; -+ -+ acct->bytes += bytes; -+ acct->packets += packets; -+ -+ if (diff) { -+ diff->bytes = bytes; -+ diff->packets = packets; -+ } -+ -+ return acct; -+} -+ -+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) - { -+ bool accounting = eth->soc->has_accounting; - const struct mtk_soc_data *soc = eth->soc; -+ struct mtk_foe_accounting *acct; - struct device *dev = eth->dev; -+ struct mtk_mib_entry *mib; - struct mtk_ppe *ppe; - u32 foe_flow_size; - void *foe; -@@ -778,7 +858,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - ppe->base = base; - ppe->eth = eth; - ppe->dev = dev; -- ppe->version = version; -+ ppe->version = eth->soc->offload_version; -+ ppe->accounting = accounting; - - foe = dmam_alloc_coherent(ppe->dev, - MTK_PPE_ENTRIES * soc->foe_entry_size, -@@ -794,6 +875,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_ - if (!ppe->foe_flow) - goto err_free_l2_flows; - -+ if (accounting) { -+ mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib), -+ &ppe->mib_phys, GFP_KERNEL); -+ if (!mib) -+ return NULL; -+ -+ ppe->mib_table = mib; -+ -+ acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct), -+ GFP_KERNEL); -+ -+ if (!acct) -+ return NULL; -+ -+ ppe->acct_table = acct; -+ } -+ - mtk_ppe_debugfs_init(ppe, index); - - return ppe; -@@ -923,6 +1021,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); - ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); - } -+ -+ if (ppe->accounting && ppe->mib_phys) { -+ ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys); -+ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN, -+ MTK_PPE_MIB_CFG_EN); -+ ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR, -+ MTK_PPE_MIB_CFG_RD_CLR); -+ ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN, -+ MTK_PPE_MIB_CFG_RD_CLR); -+ } - } - - int mtk_ppe_stop(struct mtk_ppe *ppe) ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -57,6 +57,7 @@ enum { - #define MTK_FOE_IB2_MULTICAST BIT(8) - - #define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12) -+#define MTK_FOE_IB2_MIB_CNT BIT(15) - #define MTK_FOE_IB2_WDMA_DEVIDX BIT(16) - #define MTK_FOE_IB2_WDMA_WINFO BIT(17) - -@@ -285,16 +286,34 @@ struct mtk_flow_entry { - unsigned long cookie; - }; - -+struct mtk_mib_entry { -+ u32 byt_cnt_l; -+ u16 byt_cnt_h; -+ u32 pkt_cnt_l; -+ u8 pkt_cnt_h; -+ u8 _rsv0; -+ u32 _rsv1; -+} __packed; -+ -+struct mtk_foe_accounting { -+ u64 bytes; -+ u64 packets; -+}; -+ - struct mtk_ppe { - struct mtk_eth *eth; - struct device *dev; - void __iomem *base; - int version; - char dirname[5]; -+ bool accounting; - - void *foe_table; - dma_addr_t foe_phys; - -+ struct mtk_mib_entry *mib_table; -+ dma_addr_t mib_phys; -+ - u16 foe_check_time[MTK_PPE_ENTRIES]; - struct hlist_head *foe_flow; - -@@ -303,8 +322,8 @@ struct mtk_ppe { - void *acct_table; - }; - --struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, -- int version, int index); -+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index); -+ - void mtk_ppe_deinit(struct mtk_eth *eth); - void mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); -@@ -359,5 +378,7 @@ int mtk_foe_entry_commit(struct mtk_ppe - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); -+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -+ struct mtk_foe_accounting *diff); - - #endif ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file - struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i); - struct mtk_foe_mac_info *l2; - struct mtk_flow_addr_info ai = {}; -+ struct mtk_foe_accounting *acct; - unsigned char h_source[ETH_ALEN]; - unsigned char h_dest[ETH_ALEN]; - int type, state; -@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file - if (bind && state != MTK_FOE_STATE_BIND) - continue; - -+ acct = mtk_foe_entry_get_mib(ppe, i, NULL); -+ - type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); - seq_printf(m, "%05x %s %7s", i, - mtk_foe_entry_state_str(state), -@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file - *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo); - - seq_printf(m, " eth=%pM->%pM etype=%04x" -- " vlan=%d,%d ib1=%08x ib2=%08x\n", -+ " vlan=%d,%d ib1=%08x ib2=%08x" -+ " packets=%llu bytes=%llu\n", - h_source, h_dest, ntohs(l2->etype), -- l2->vlan1, l2->vlan2, entry->ib1, ib2); -+ l2->vlan1, l2->vlan2, entry->ib1, ib2, -+ acct ? acct->packets : 0, acct ? acct->bytes : 0); - } - - return 0; ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -497,6 +497,7 @@ static int - mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) - { - struct mtk_flow_entry *entry; -+ struct mtk_foe_accounting diff; - u32 idle; - - entry = rhashtable_lookup(ð->flow_table, &f->cookie, -@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *e - idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); - f->stats.lastused = jiffies - idle * HZ; - -+ if (entry->hash != 0xFFFF && -+ mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash, -+ &diff)) { -+ f->stats.pkts += diff.packets; -+ f->stats.bytes += diff.bytes; -+ } -+ - return 0; - } - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -@@ -149,6 +149,20 @@ enum { - - #define MTK_PPE_MIB_TB_BASE 0x338 - -+#define MTK_PPE_MIB_SER_CR 0x33C -+#define MTK_PPE_MIB_SER_CR_ST BIT(16) -+#define MTK_PPE_MIB_SER_CR_ADDR GENMASK(13, 0) -+ -+#define MTK_PPE_MIB_SER_R0 0x340 -+#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW GENMASK(31, 0) -+ -+#define MTK_PPE_MIB_SER_R1 0x344 -+#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW GENMASK(31, 16) -+#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH GENMASK(15, 0) -+ -+#define MTK_PPE_MIB_SER_R2 0x348 -+#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0) -+ - #define MTK_PPE_MIB_CACHE_CTL 0x350 - #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) - #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) diff --git a/target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch deleted file mode 100644 index 64352426ae54fc..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 88a0fd5927b7c2c7aecd6dc747d898eb38043d2b Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Thu, 20 Apr 2023 22:06:42 +0100 -Subject: [PATCH 093/250] net: mtk_eth_soc: mediatek: fix ppe flow accounting - for v1 hardware - -Older chips (like MT7622) use a different bit in ib2 to enable hardware -counter support. Add macros for both and select the appropriate bit. - -Fixes: 3fbe4d8c0e53 ("net: ethernet: mtk_eth_soc: ppe: add support for flow accounting") -Signed-off-by: Felix Fietkau -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 10 ++++++++-- - drivers/net/ethernet/mediatek/mtk_ppe.h | 3 ++- - 2 files changed, 10 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -599,6 +599,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - struct mtk_eth *eth = ppe->eth; - u16 timestamp = mtk_eth_timestamp(eth); - struct mtk_foe_entry *hwe; -+ u32 val; - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; -@@ -615,8 +616,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - wmb(); - hwe->ib1 = entry->ib1; - -- if (ppe->accounting) -- *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT; -+ if (ppe->accounting) { -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ val = MTK_FOE_IB2_MIB_CNT_V2; -+ else -+ val = MTK_FOE_IB2_MIB_CNT; -+ *mtk_foe_entry_ib2(eth, hwe) |= val; -+ } - - dma_wmb(); - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -55,9 +55,10 @@ enum { - #define MTK_FOE_IB2_PSE_QOS BIT(4) - #define MTK_FOE_IB2_DEST_PORT GENMASK(7, 5) - #define MTK_FOE_IB2_MULTICAST BIT(8) -+#define MTK_FOE_IB2_MIB_CNT BIT(10) - - #define MTK_FOE_IB2_WDMA_QID2 GENMASK(13, 12) --#define MTK_FOE_IB2_MIB_CNT BIT(15) -+#define MTK_FOE_IB2_MIB_CNT_V2 BIT(15) - #define MTK_FOE_IB2_WDMA_DEVIDX BIT(16) - #define MTK_FOE_IB2_WDMA_WINFO BIT(17) - diff --git a/target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch deleted file mode 100644 index 7e3d5a33083990..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch +++ /dev/null @@ -1,201 +0,0 @@ -From: Felix Fietkau -Date: Sun, 20 Nov 2022 23:01:00 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: drop generic vlan rx offload, - only use DSA untagging - -Through testing I found out that hardware vlan rx offload support seems to -have some hardware issues. At least when using multiple MACs and when receiving -tagged packets on the secondary MAC, the hardware can sometimes start to emit -wrong tags on the first MAC as well. - -In order to avoid such issues, drop the feature configuration and use the -offload feature only for DSA hardware untagging on MT7621/MT7622 devices which -only use one MAC. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1896,9 +1896,7 @@ static int mtk_poll_rx(struct napi_struc - - while (done < budget) { - unsigned int pktlen, *rxdcsum; -- bool has_hwaccel_tag = false; - struct net_device *netdev; -- u16 vlan_proto, vlan_tci; - dma_addr_t dma_addr; - u32 hash, reason; - int mac = 0; -@@ -2033,36 +2031,21 @@ static int mtk_poll_rx(struct napi_struc - skb_checksum_none_assert(skb); - skb->protocol = eth_type_trans(skb, netdev); - -- if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -- mtk_ppe_check_skb(eth->ppe[0], skb, hash); -- -- if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -- if (trxd.rxd3 & RX_DMA_VTAG_V2) { -- vlan_proto = RX_DMA_VPID(trxd.rxd4); -- vlan_tci = RX_DMA_VID(trxd.rxd4); -- has_hwaccel_tag = true; -- } -- } else if (trxd.rxd2 & RX_DMA_VTAG) { -- vlan_proto = RX_DMA_VPID(trxd.rxd3); -- vlan_tci = RX_DMA_VID(trxd.rxd3); -- has_hwaccel_tag = true; -- } -- } -- - /* When using VLAN untagging in combination with DSA, the - * hardware treats the MTK special tag as a VLAN and untags it. - */ -- if (has_hwaccel_tag && netdev_uses_dsa(netdev)) { -- unsigned int port = vlan_proto & GENMASK(2, 0); -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && -+ (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) { -+ unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0); - - if (port < ARRAY_SIZE(eth->dsa_meta) && - eth->dsa_meta[port]) - skb_dst_set_noref(skb, ð->dsa_meta[port]->dst); -- } else if (has_hwaccel_tag) { -- __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci); - } - -+ if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED) -+ mtk_ppe_check_skb(eth->ppe[0], skb, hash); -+ - skb_record_rx_queue(skb, 0); - napi_gro_receive(napi, skb); - -@@ -2888,29 +2871,11 @@ static netdev_features_t mtk_fix_feature - - static int mtk_set_features(struct net_device *dev, netdev_features_t features) - { -- struct mtk_mac *mac = netdev_priv(dev); -- struct mtk_eth *eth = mac->hw; - netdev_features_t diff = dev->features ^ features; -- int i; - - if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO)) - mtk_hwlro_netdev_disable(dev); - -- /* Set RX VLAN offloading */ -- if (!(diff & NETIF_F_HW_VLAN_CTAG_RX)) -- return 0; -- -- mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX), -- MTK_CDMP_EG_CTRL); -- -- /* sync features with other MAC */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!eth->netdev[i] || eth->netdev[i] == dev) -- continue; -- eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX; -- eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX; -- } -- - return 0; - } - -@@ -3224,30 +3189,6 @@ static int mtk_open(struct net_device *d - struct mtk_eth *eth = mac->hw; - int i, err; - -- if (mtk_uses_dsa(dev) && !eth->prog) { -- for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { -- struct metadata_dst *md_dst = eth->dsa_meta[i]; -- -- if (md_dst) -- continue; -- -- md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, -- GFP_KERNEL); -- if (!md_dst) -- return -ENOMEM; -- -- md_dst->u.port_info.port_id = i; -- eth->dsa_meta[i] = md_dst; -- } -- } else { -- /* Hardware special tag parsing needs to be disabled if at least -- * one MAC does not use DSA. -- */ -- u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); -- val &= ~MTK_CDMP_STAG_EN; -- mtk_w32(eth, val, MTK_CDMP_IG_CTRL); -- } -- - err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); - if (err) { - netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -@@ -3286,6 +3227,35 @@ static int mtk_open(struct net_device *d - phylink_start(mac->phylink); - netif_tx_start_all_queues(dev); - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ return 0; -+ -+ if (mtk_uses_dsa(dev) && !eth->prog) { -+ for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) { -+ struct metadata_dst *md_dst = eth->dsa_meta[i]; -+ -+ if (md_dst) -+ continue; -+ -+ md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, -+ GFP_KERNEL); -+ if (!md_dst) -+ return -ENOMEM; -+ -+ md_dst->u.port_info.port_id = i; -+ eth->dsa_meta[i] = md_dst; -+ } -+ } else { -+ /* Hardware special tag parsing needs to be disabled if at least -+ * one MAC does not use DSA. -+ */ -+ u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL); -+ val &= ~MTK_CDMP_STAG_EN; -+ mtk_w32(eth, val, MTK_CDMP_IG_CTRL); -+ -+ mtk_w32(eth, 0, MTK_CDMP_EG_CTRL); -+ } -+ - return 0; - } - -@@ -3770,10 +3740,9 @@ static int mtk_hw_init(struct mtk_eth *e - if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { - val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); -- } - -- /* Enable RX VLan Offloading */ -- mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -+ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); -+ } - - /* set interrupt delays based on current Net DIM sample */ - mtk_dim_rx(ð->rx_dim.work); -@@ -4413,7 +4382,7 @@ static int mtk_add_mac(struct mtk_eth *e - eth->netdev[id]->hw_features |= NETIF_F_LRO; - - eth->netdev[id]->vlan_features = eth->soc->hw_features & -- ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX); -+ ~NETIF_F_HW_VLAN_CTAG_TX; - eth->netdev[id]->features |= eth->soc->hw_features; - eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops; - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -48,7 +48,6 @@ - #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \ - NETIF_F_RXCSUM | \ - NETIF_F_HW_VLAN_CTAG_TX | \ -- NETIF_F_HW_VLAN_CTAG_RX | \ - NETIF_F_SG | NETIF_F_TSO | \ - NETIF_F_TSO6 | \ - NETIF_F_IPV6_CSUM |\ diff --git a/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch b/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch deleted file mode 100644 index 2704faec12b011..00000000000000 --- a/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b804f765485109f9644cc05d1e8fc79ca6c6e4aa Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 19 Jul 2023 01:39:36 +0100 -Subject: [PATCH 094/250] net: ethernet: mtk_eth_soc: always - mtk_get_ib1_pkt_type - -entries and bind debugfs files would display wrong data on NETSYS_V2 and -later because instead of using mtk_get_ib1_pkt_type the driver would use -MTK_FOE_IB1_PACKET_TYPE which corresponds to NETSYS_V1(.x) SoCs. -Use mtk_get_ib1_pkt_type so entries and bind records display correctly. - -Fixes: 03a3180e5c09e ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986") -Signed-off-by: Daniel Golle -Acked-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/c0ae03d0182f4d27b874cbdf0059bc972c317f3c.1689727134.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file - - acct = mtk_foe_entry_get_mib(ppe, i, NULL); - -- type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); -+ type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); - seq_printf(m, "%05x %s %7s", i, - mtk_foe_entry_state_str(state), - mtk_foe_pkt_type_str(type)); diff --git a/target/linux/generic/backport-6.1/734-v6.8-net-phy-bcm54612e-add-suspend-resume.patch b/target/linux/generic/backport-6.1/734-v6.8-net-phy-bcm54612e-add-suspend-resume.patch deleted file mode 100644 index 64d1b160d3d3e4..00000000000000 --- a/target/linux/generic/backport-6.1/734-v6.8-net-phy-bcm54612e-add-suspend-resume.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 380b50ae3a04222334a3779b3787eba844b1177f Mon Sep 17 00:00:00 2001 -From: Marco von Rosenberg -Date: Thu, 16 Nov 2023 20:32:31 +0100 -Subject: net: phy: broadcom: Wire suspend/resume for BCM54612E - -The BCM54612E ethernet PHY supports IDDQ-SR. -Therefore wire-up the suspend and resume callbacks -to point to bcm54xx_suspend() and bcm54xx_resume(). - -Signed-off-by: Marco von Rosenberg -Acked-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/broadcom.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/phy/broadcom.c -+++ b/drivers/net/phy/broadcom.c -@@ -942,6 +942,8 @@ static struct phy_driver broadcom_driver - .config_intr = bcm_phy_config_intr, - .handle_interrupt = bcm_phy_handle_interrupt, - .link_change_notify = bcm54xx_link_change_notify, -+ .suspend = bcm54xx_suspend, -+ .resume = bcm54xx_resume, - }, { - .phy_id = PHY_ID_BCM54616S, - .phy_id_mask = 0xfffffff0, diff --git a/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch b/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch deleted file mode 100644 index afce0cf04c0a4b..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 5ea0e1312bcfebc06b5f91d1bb82b823d6395125 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Wed, 19 Jul 2023 12:29:49 +0200 -Subject: [PATCH 095/250] net: ethernet: mtk_ppe: add MTK_FOE_ENTRY_V{1,2}_SIZE - macros - -Introduce MTK_FOE_ENTRY_V{1,2}_SIZE macros in order to make more -explicit foe_entry size for different chipset revisions. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +++++----- - drivers/net/ethernet/mediatek/mtk_ppe.h | 3 +++ - 2 files changed, 8 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4764,7 +4764,7 @@ static const struct mtk_soc_data mt7621_ - .required_pctl = false, - .offload_version = 1, - .hash_offset = 2, -- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, -+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4785,7 +4785,7 @@ static const struct mtk_soc_data mt7622_ - .offload_version = 2, - .hash_offset = 2, - .has_accounting = true, -- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, -+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4804,7 +4804,7 @@ static const struct mtk_soc_data mt7623_ - .required_pctl = true, - .offload_version = 1, - .hash_offset = 2, -- .foe_entry_size = sizeof(struct mtk_foe_entry) - 16, -+ .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4842,8 +4842,8 @@ static const struct mtk_soc_data mt7981_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 4, -- .foe_entry_size = sizeof(struct mtk_foe_entry), - .has_accounting = true, -+ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), -@@ -4863,8 +4863,8 @@ static const struct mtk_soc_data mt7986_ - .required_pctl = false, - .offload_version = 2, - .hash_offset = 4, -- .foe_entry_size = sizeof(struct mtk_foe_entry), - .has_accounting = true, -+ .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -216,6 +216,9 @@ struct mtk_foe_ipv6_6rd { - struct mtk_foe_mac_info l2; - }; - -+#define MTK_FOE_ENTRY_V1_SIZE 80 -+#define MTK_FOE_ENTRY_V2_SIZE 96 -+ - struct mtk_foe_entry { - u32 ib1; - diff --git a/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch b/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch deleted file mode 100644 index 28bf2b6d5f3ea4..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 8cfa2576d79f9379d167a8994f0fca935c07a8bc Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Sat, 22 Jul 2023 21:32:49 +0100 -Subject: [PATCH 096/250] net: ethernet: mtk_eth_soc: remove incorrect PLL - configuration - -MT7623 GMAC0 attempts to configure the system clocking according to the -required speed in the .mac_config callback for non-SGMII, non-baseX and -non-TRGMII modes. - -state->speed setting has never been reliable in the .mac_config -callback - there are cases where this is not the link speed, -particularly via ethtool paths, so this has always been unreliable (as -detailed in phylink's documentation.) - -There is the additional issue that mtk_gmac0_rgmii_adjust() will only -be called if state->interface changes, which means it only configures -the system clocking on the very first .mac_config call, which will be -made when the network device is first brought up before any link is -established. - -Essentially, this code is incredibly buggy, and probably never worked. - -Moreover, checking the in-kernel DT files, it seems no platform makes -use of this code path. - -Therefore, let's remove it, and disable interface modes for port 0 that -are not SGMII, 1000base-X, 2500base-X or TRGMII on the MT7623. - -Reviewed-by: Daniel Golle -Tested-by: Daniel Golle -Tested-by: Frank Wunderlich -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 54 ++++++--------------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 + - 2 files changed, 17 insertions(+), 38 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -352,7 +352,7 @@ static int mt7621_gmac0_rgmii_adjust(str - } - - static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth, -- phy_interface_t interface, int speed) -+ phy_interface_t interface) - { - u32 val; - int ret; -@@ -366,26 +366,7 @@ static void mtk_gmac0_rgmii_adjust(struc - return; - } - -- val = (speed == SPEED_1000) ? -- INTF_MODE_RGMII_1000 : INTF_MODE_RGMII_10_100; -- mtk_w32(eth, val, INTF_MODE); -- -- regmap_update_bits(eth->ethsys, ETHSYS_CLKCFG0, -- ETHSYS_TRGMII_CLK_SEL362_5, -- ETHSYS_TRGMII_CLK_SEL362_5); -- -- val = (speed == SPEED_1000) ? 250000000 : 500000000; -- ret = clk_set_rate(eth->clks[MTK_CLK_TRGPLL], val); -- if (ret) -- dev_err(eth->dev, "Failed to set trgmii pll: %d\n", ret); -- -- val = (speed == SPEED_1000) ? -- RCK_CTRL_RGMII_1000 : RCK_CTRL_RGMII_10_100; -- mtk_w32(eth, val, TRGMII_RCK_CTRL); -- -- val = (speed == SPEED_1000) ? -- TCK_CTRL_RGMII_1000 : TCK_CTRL_RGMII_10_100; -- mtk_w32(eth, val, TRGMII_TCK_CTRL); -+ dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n"); - } - - static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, -@@ -471,17 +452,8 @@ static void mtk_mac_config(struct phylin - state->interface)) - goto err_phy; - } else { -- /* FIXME: this is incorrect. Not only does it -- * use state->speed (which is not guaranteed -- * to be correct) but it also makes use of it -- * in a code path that will only be reachable -- * when the PHY interface mode changes, not -- * when the speed changes. Consequently, RGMII -- * is probably broken. -- */ - mtk_gmac0_rgmii_adjust(mac->hw, -- state->interface, -- state->speed); -+ state->interface); - - /* mt7623_pad_clk_setup */ - for (i = 0 ; i < NUM_TRGMII_CTRL; i++) -@@ -4341,13 +4313,19 @@ static int mtk_add_mac(struct mtk_eth *e - mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; - -- __set_bit(PHY_INTERFACE_MODE_MII, -- mac->phylink_config.supported_interfaces); -- __set_bit(PHY_INTERFACE_MODE_GMII, -- mac->phylink_config.supported_interfaces); -+ /* MT7623 gmac0 is now missing its speed-specific PLL configuration -+ * in its .mac_config method (since state->speed is not valid there. -+ * Disable support for MII, GMII and RGMII. -+ */ -+ if (!mac->hw->soc->disable_pll_modes || mac->id != 0) { -+ __set_bit(PHY_INTERFACE_MODE_MII, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_GMII, -+ mac->phylink_config.supported_interfaces); - -- if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) -- phy_interface_set_rgmii(mac->phylink_config.supported_interfaces); -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) -+ phy_interface_set_rgmii(mac->phylink_config.supported_interfaces); -+ } - - if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id) - __set_bit(PHY_INTERFACE_MODE_TRGMII, -@@ -4805,6 +4783,7 @@ static const struct mtk_soc_data mt7623_ - .offload_version = 1, - .hash_offset = 2, - .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, -+ .disable_pll_modes = true, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1030,6 +1030,7 @@ struct mtk_soc_data { - u16 foe_entry_size; - netdev_features_t hw_features; - bool has_accounting; -+ bool disable_pll_modes; - struct { - u32 txd_size; - u32 rxd_size; diff --git a/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch b/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch deleted file mode 100644 index fd458a67bce2a7..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch +++ /dev/null @@ -1,81 +0,0 @@ -From a4c2233b1e4359b6c64b6f9ba98c8718a11fffee Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Sat, 22 Jul 2023 21:32:54 +0100 -Subject: [PATCH 097/250] net: ethernet: mtk_eth_soc: remove mac_pcs_get_state - and modernise - -Remove the .mac_pcs_get_state function, since as far as I can tell is -never called - no DT appears to specify an in-band-status management -nor SFP support for this driver. - -Removal of this, along with the previous patch to remove the incorrect -clocking configuration, means that the driver becomes non-legacy, so -we can remove the "legacy_pre_march2020" status from this driver. - -Reviewed-by: Daniel Golle -Tested-by: Daniel Golle -Tested-by: Frank Wunderlich -Signed-off-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 --------------------- - 1 file changed, 35 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -554,38 +554,6 @@ static int mtk_mac_finish(struct phylink - return 0; - } - --static void mtk_mac_pcs_get_state(struct phylink_config *config, -- struct phylink_link_state *state) --{ -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); -- u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id)); -- -- state->link = (pmsr & MAC_MSR_LINK); -- state->duplex = (pmsr & MAC_MSR_DPX) >> 1; -- -- switch (pmsr & (MAC_MSR_SPEED_1000 | MAC_MSR_SPEED_100)) { -- case 0: -- state->speed = SPEED_10; -- break; -- case MAC_MSR_SPEED_100: -- state->speed = SPEED_100; -- break; -- case MAC_MSR_SPEED_1000: -- state->speed = SPEED_1000; -- break; -- default: -- state->speed = SPEED_UNKNOWN; -- break; -- } -- -- state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX); -- if (pmsr & MAC_MSR_RX_FC) -- state->pause |= MLO_PAUSE_RX; -- if (pmsr & MAC_MSR_TX_FC) -- state->pause |= MLO_PAUSE_TX; --} -- - static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode, - phy_interface_t interface) - { -@@ -707,7 +675,6 @@ static void mtk_mac_link_up(struct phyli - - static const struct phylink_mac_ops mtk_phylink_ops = { - .mac_select_pcs = mtk_mac_select_pcs, -- .mac_pcs_get_state = mtk_mac_pcs_get_state, - .mac_config = mtk_mac_config, - .mac_finish = mtk_mac_finish, - .mac_link_down = mtk_mac_link_down, -@@ -4308,8 +4275,6 @@ static int mtk_add_mac(struct mtk_eth *e - - mac->phylink_config.dev = ð->netdev[id]->dev; - mac->phylink_config.type = PHYLINK_NETDEV; -- /* This driver makes use of state->speed in mac_config */ -- mac->phylink_config.legacy_pre_march2020 = true; - mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD; - diff --git a/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch b/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch deleted file mode 100644 index aa259e71759274..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch +++ /dev/null @@ -1,550 +0,0 @@ -From 5d8d05fbf804b4485646d39551ac27452e45afd3 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:52:02 +0100 -Subject: [PATCH 099/250] net: ethernet: mtk_eth_soc: add version in - mtk_soc_data - -Introduce version field in mtk_soc_data data structure in order to -make mtk_eth driver easier to maintain for chipset configuration -codebase. Get rid of MTK_NETSYS_V2 bit in chip capabilities. -This is a preliminary patch to introduce support for MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/e52fae302ca135436e5cdd26d38d87be2da63055.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 55 +++++++++++-------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 36 +++++++----- - drivers/net/ethernet/mediatek/mtk_ppe.c | 18 +++--- - .../net/ethernet/mediatek/mtk_ppe_offload.c | 2 +- - drivers/net/ethernet/mediatek/mtk_wed.c | 4 +- - 5 files changed, 66 insertions(+), 49 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -579,7 +579,7 @@ static void mtk_set_queue_speed(struct m - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | - MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v1(eth)) - val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; - - if (IS_ENABLED(CONFIG_SOC_MT7621)) { -@@ -954,7 +954,7 @@ static bool mtk_rx_get_desc(struct mtk_e - rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); - rxd->rxd3 = READ_ONCE(dma_rxd->rxd3); - rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - rxd->rxd5 = READ_ONCE(dma_rxd->rxd5); - rxd->rxd6 = READ_ONCE(dma_rxd->rxd6); - } -@@ -1012,7 +1012,7 @@ static int mtk_init_fq_dma(struct mtk_et - - txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE); - txd->txd4 = 0; -- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - txd->txd5 = 0; - txd->txd6 = 0; - txd->txd7 = 0; -@@ -1203,7 +1203,7 @@ static void mtk_tx_set_dma_desc(struct n - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - mtk_tx_set_dma_desc_v2(dev, txd, info); - else - mtk_tx_set_dma_desc_v1(dev, txd, info); -@@ -1510,7 +1510,7 @@ static void mtk_update_rx_cpu_idx(struct - - static bool mtk_page_pool_enabled(struct mtk_eth *eth) - { -- return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2); -+ return eth->soc->version == 2; - } - - static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, -@@ -1852,7 +1852,7 @@ static int mtk_poll_rx(struct napi_struc - break; - - /* find out which mac the packet come from. values start at 1 */ -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; - else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && - !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) -@@ -1948,7 +1948,7 @@ static int mtk_poll_rx(struct napi_struc - skb->dev = netdev; - bytes += skb->len; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); - hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; - if (hash != MTK_RXD5_FOE_ENTRY) -@@ -1973,8 +1973,8 @@ static int mtk_poll_rx(struct napi_struc - /* When using VLAN untagging in combination with DSA, the - * hardware treats the MTK special tag as a VLAN and untags it. - */ -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) && -- (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) { -+ if (mtk_is_netsys_v1(eth) && (trxd.rxd2 & RX_DMA_VTAG) && -+ netdev_uses_dsa(netdev)) { - unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0); - - if (port < ARRAY_SIZE(eth->dsa_meta) && -@@ -2284,7 +2284,7 @@ static int mtk_tx_alloc(struct mtk_eth * - txd->txd2 = next_ptr; - txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; - txd->txd4 = 0; -- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - txd->txd5 = 0; - txd->txd6 = 0; - txd->txd7 = 0; -@@ -2337,14 +2337,14 @@ static int mtk_tx_alloc(struct mtk_eth * - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) | - FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) | - MTK_QTX_SCH_LEAKY_BUCKET_SIZE; -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v1(eth)) - val |= MTK_QTX_SCH_LEAKY_BUCKET_EN; - mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); - ofs += MTK_QTX_OFFSET; - } - val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16); - mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate); -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4); - } else { - mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0); -@@ -2473,7 +2473,7 @@ static int mtk_rx_alloc(struct mtk_eth * - - rxd->rxd3 = 0; - rxd->rxd4 = 0; -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - rxd->rxd5 = 0; - rxd->rxd6 = 0; - rxd->rxd7 = 0; -@@ -3024,7 +3024,7 @@ static int mtk_start_dma(struct mtk_eth - MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | - MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - val |= MTK_MUTLI_CNT | MTK_RESV_BUF | - MTK_WCOMP_EN | MTK_DMAD_WR_WDONE | - MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN; -@@ -3166,7 +3166,7 @@ static int mtk_open(struct net_device *d - phylink_start(mac->phylink); - netif_tx_start_all_queues(dev); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return 0; - - if (mtk_uses_dsa(dev) && !eth->prog) { -@@ -3431,7 +3431,7 @@ static void mtk_hw_reset(struct mtk_eth - { - u32 val; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); - val = RSTCTRL_PPE0_V2; - } else { -@@ -3443,7 +3443,7 @@ static void mtk_hw_reset(struct mtk_eth - - ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, - 0x3ffffff); - } -@@ -3469,7 +3469,7 @@ static void mtk_hw_warm_reset(struct mtk - return; - } - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; - else - rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; -@@ -3639,7 +3639,7 @@ static int mtk_hw_init(struct mtk_eth *e - else - mtk_hw_reset(eth); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - /* Set FE to PDMAv2 if necessary */ - val = mtk_r32(eth, MTK_FE_GLO_MISC); - mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); -@@ -3676,7 +3676,7 @@ static int mtk_hw_init(struct mtk_eth *e - */ - val = mtk_r32(eth, MTK_CDMQ_IG_CTRL); - mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL); -- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v1(eth)) { - val = mtk_r32(eth, MTK_CDMP_IG_CTRL); - mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL); - -@@ -3698,7 +3698,7 @@ static int mtk_hw_init(struct mtk_eth *e - mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); - mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - /* PSE should not drop port8 and port9 packets from WDMA Tx */ - mtk_w32(eth, 0x00000300, PSE_DROP_CFG); - -@@ -4487,7 +4487,7 @@ static int mtk_probe(struct platform_dev - } - } - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - err = -EINVAL; -@@ -4595,9 +4595,8 @@ static int mtk_probe(struct platform_dev - } - - if (eth->soc->offload_version) { -- u32 num_ppe; -+ u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1; - -- num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; - num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe); - for (i = 0; i < num_ppe; i++) { - u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400; -@@ -4689,6 +4688,7 @@ static const struct mtk_soc_data mt2701_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, -+ .version = 1, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4705,6 +4705,7 @@ static const struct mtk_soc_data mt7621_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7621_CLKS_BITMAP, - .required_pctl = false, -+ .version = 1, - .offload_version = 1, - .hash_offset = 2, - .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, -@@ -4725,6 +4726,7 @@ static const struct mtk_soc_data mt7622_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7622_CLKS_BITMAP, - .required_pctl = false, -+ .version = 1, - .offload_version = 2, - .hash_offset = 2, - .has_accounting = true, -@@ -4745,6 +4747,7 @@ static const struct mtk_soc_data mt7623_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7623_CLKS_BITMAP, - .required_pctl = true, -+ .version = 1, - .offload_version = 1, - .hash_offset = 2, - .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, -@@ -4767,6 +4770,7 @@ static const struct mtk_soc_data mt7629_ - .required_clks = MT7629_CLKS_BITMAP, - .required_pctl = false, - .has_accounting = true, -+ .version = 1, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), -@@ -4784,6 +4788,7 @@ static const struct mtk_soc_data mt7981_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7981_CLKS_BITMAP, - .required_pctl = false, -+ .version = 2, - .offload_version = 2, - .hash_offset = 4, - .has_accounting = true, -@@ -4805,6 +4810,7 @@ static const struct mtk_soc_data mt7986_ - .hw_features = MTK_HW_FEATURES, - .required_clks = MT7986_CLKS_BITMAP, - .required_pctl = false, -+ .version = 2, - .offload_version = 2, - .hash_offset = 4, - .has_accounting = true, -@@ -4825,6 +4831,7 @@ static const struct mtk_soc_data rt5350_ - .hw_features = MTK_HW_FEATURES_MT7628, - .required_clks = MT7628_CLKS_BITMAP, - .required_pctl = false, -+ .version = 1, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma), - .rxd_size = sizeof(struct mtk_rx_dma), ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -820,7 +820,6 @@ enum mkt_eth_capabilities { - MTK_SHARED_INT_BIT, - MTK_TRGMII_MT7621_CLK_BIT, - MTK_QDMA_BIT, -- MTK_NETSYS_V2_BIT, - MTK_SOC_MT7628_BIT, - MTK_RSTCTRL_PPE1_BIT, - MTK_U3_COPHY_V2_BIT, -@@ -855,7 +854,6 @@ enum mkt_eth_capabilities { - #define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) - #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) - #define MTK_QDMA BIT(MTK_QDMA_BIT) --#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) - #define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) - #define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) - #define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) -@@ -934,11 +932,11 @@ enum mkt_eth_capabilities { - #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ -- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -+ MTK_RSTCTRL_PPE1) - - #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ -- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1) -+ MTK_RSTCTRL_PPE1) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1009,6 +1007,7 @@ struct mtk_reg_map { - * @required_pctl A bool value to show whether the SoC requires - * the extra setup for those pins used by GMAC. - * @hash_offset Flow table hash offset. -+ * @version SoC version. - * @foe_entry_size Foe table entry size. - * @has_accounting Bool indicating support for accounting of - * offloaded flows. -@@ -1027,6 +1026,7 @@ struct mtk_soc_data { - bool required_pctl; - u8 offload_version; - u8 hash_offset; -+ u8 version; - u16 foe_entry_size; - netdev_features_t hw_features; - bool has_accounting; -@@ -1183,6 +1183,16 @@ struct mtk_mac { - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ - extern const struct of_device_id of_mtk_match[]; - -+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) -+{ -+ return eth->soc->version == 1; -+} -+ -+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) -+{ -+ return eth->soc->version > 1; -+} -+ - static inline struct mtk_foe_entry * - mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) - { -@@ -1193,7 +1203,7 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u - - static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB1_BIND_TIMESTAMP_V2; - - return MTK_FOE_IB1_BIND_TIMESTAMP; -@@ -1201,7 +1211,7 @@ static inline u32 mtk_get_ib1_ts_mask(st - - static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB1_BIND_PPPOE_V2; - - return MTK_FOE_IB1_BIND_PPPOE; -@@ -1209,7 +1219,7 @@ static inline u32 mtk_get_ib1_ppoe_mask( - - static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB1_BIND_VLAN_TAG_V2; - - return MTK_FOE_IB1_BIND_VLAN_TAG; -@@ -1217,7 +1227,7 @@ static inline u32 mtk_get_ib1_vlan_tag_m - - static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB1_BIND_VLAN_LAYER_V2; - - return MTK_FOE_IB1_BIND_VLAN_LAYER; -@@ -1225,7 +1235,7 @@ static inline u32 mtk_get_ib1_vlan_layer - - static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); - - return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val); -@@ -1233,7 +1243,7 @@ static inline u32 mtk_prep_ib1_vlan_laye - - static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val); - - return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val); -@@ -1241,7 +1251,7 @@ static inline u32 mtk_get_ib1_vlan_layer - - static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB1_PACKET_TYPE_V2; - - return MTK_FOE_IB1_PACKET_TYPE; -@@ -1249,7 +1259,7 @@ static inline u32 mtk_get_ib1_pkt_type_m - - static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val); - - return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val); -@@ -1257,7 +1267,7 @@ static inline u32 mtk_get_ib1_pkt_type(s - - static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth) - { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - return MTK_FOE_IB2_MULTICAST_V2; - - return MTK_FOE_IB2_MULTICAST; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -207,7 +207,7 @@ int mtk_foe_entry_prepare(struct mtk_eth - - memset(entry, 0, sizeof(*entry)); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | - FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) | - FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | -@@ -271,7 +271,7 @@ int mtk_foe_entry_set_pse_port(struct mt - u32 *ib2 = mtk_foe_entry_ib2(eth, entry); - u32 val = *ib2; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - val &= ~MTK_FOE_IB2_DEST_PORT_V2; - val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port); - } else { -@@ -422,7 +422,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et - struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - u32 *ib2 = mtk_foe_entry_ib2(eth, entry); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; - *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | - MTK_FOE_IB2_WDMA_WINFO_V2; -@@ -446,7 +446,7 @@ int mtk_foe_entry_set_queue(struct mtk_e - { - u32 *ib2 = mtk_foe_entry_ib2(eth, entry); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - *ib2 &= ~MTK_FOE_IB2_QID_V2; - *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue); - *ib2 |= MTK_FOE_IB2_PSE_QOS_V2; -@@ -601,7 +601,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - struct mtk_foe_entry *hwe; - u32 val; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2; - entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2, - timestamp); -@@ -617,7 +617,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - hwe->ib1 = entry->ib1; - - if (ppe->accounting) { -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - val = MTK_FOE_IB2_MIB_CNT_V2; - else - val = MTK_FOE_IB2_MIB_CNT; -@@ -965,7 +965,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_SCAN_MODE_CHECK_AGE) | - FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, - MTK_PPE_ENTRIES_SHIFT); -- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(ppe->eth)) - val |= MTK_PPE_TB_CFG_INFO_SEL; - ppe_w32(ppe, MTK_PPE_TB_CFG, val); - -@@ -981,7 +981,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_FLOW_CFG_IP4_NAPT | - MTK_PPE_FLOW_CFG_IP4_DSLITE | - MTK_PPE_FLOW_CFG_IP4_NAT_FRAG; -- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(ppe->eth)) - val |= MTK_PPE_MD_TOAP_BYP_CRSN0 | - MTK_PPE_MD_TOAP_BYP_CRSN1 | - MTK_PPE_MD_TOAP_BYP_CRSN2 | -@@ -1023,7 +1023,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - - ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); - -- if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(ppe->eth)) { - ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777); - ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f); - } ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -193,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et - if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { - mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, - info.bss, info.wcid); -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) { - switch (info.wdma_idx) { - case 0: - pse_port = 8; ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1084,7 +1084,7 @@ mtk_wed_rx_reset(struct mtk_wed_device * - } else { - struct mtk_eth *eth = dev->hw->eth; - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) -+ if (mtk_is_netsys_v2_or_greater(eth)) - wed_set(dev, MTK_WED_RESET_IDX, - MTK_WED_RESET_IDX_RX_V2); - else -@@ -1806,7 +1806,7 @@ void mtk_wed_add_hw(struct device_node * - hw->wdma = wdma; - hw->index = index; - hw->irq = irq; -- hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1; -+ hw->version = mtk_is_netsys_v1(eth) ? 1 : 2; - - if (hw->version == 1) { - hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, diff --git a/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch b/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch deleted file mode 100644 index 7b945bb869b1b3..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch +++ /dev/null @@ -1,29 +0,0 @@ -From f8fb8dbd158c585be7574faf92db7d614b6722ff Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:52:27 +0100 -Subject: [PATCH 100/250] net: ethernet: mtk_eth_soc: increase MAX_DEVS to 3 - -This is a preliminary patch to add MT7988 SoC support since it runs 3 -macs instead of 2. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/3563e5fab367e7d79a7f1296fabaa5c20f202d7a.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1043,8 +1043,8 @@ struct mtk_soc_data { - - #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) - --/* currently no SoC has more than 2 macs */ --#define MTK_MAX_DEVS 2 -+/* currently no SoC has more than 3 macs */ -+#define MTK_MAX_DEVS 3 - - /* struct mtk_eth - This is the main datasructure for holding the state - * of the driver diff --git a/target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch b/target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch deleted file mode 100644 index 3db23f78971061..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 856be974290f28d7943be2ac5a382c4139486196 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:52:44 +0100 -Subject: [PATCH 101/250] net: ethernet: mtk_eth_soc: rely on MTK_MAX_DEVS and - remove MTK_MAC_COUNT - -Get rid of MTK_MAC_COUNT since it is a duplicated of MTK_MAX_DEVS. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/1856f4266f2fc80677807b1bad867659e7b00c65.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++++++--------- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 - - 2 files changed, 27 insertions(+), 23 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -880,7 +880,7 @@ static void mtk_stats_update(struct mtk_ - { - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->mac[i] || !eth->mac[i]->hw_stats) - continue; - if (spin_trylock(ð->mac[i]->hw_stats->stats_lock)) { -@@ -1385,7 +1385,7 @@ static int mtk_queue_stopped(struct mtk_ - { - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->netdev[i]) - continue; - if (netif_queue_stopped(eth->netdev[i])) -@@ -1399,7 +1399,7 @@ static void mtk_wake_queue(struct mtk_et - { - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->netdev[i]) - continue; - netif_tx_wake_all_queues(eth->netdev[i]); -@@ -1858,7 +1858,7 @@ static int mtk_poll_rx(struct napi_struc - !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) - mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1; - -- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT || -+ if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS || - !eth->netdev[mac])) - goto release_desc; - -@@ -2898,7 +2898,7 @@ static void mtk_dma_free(struct mtk_eth - const struct mtk_soc_data *soc = eth->soc; - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) -+ for (i = 0; i < MTK_MAX_DEVS; i++) - if (eth->netdev[i]) - netdev_reset_queue(eth->netdev[i]); - if (eth->scratch_ring) { -@@ -3052,8 +3052,13 @@ static void mtk_gdm_config(struct mtk_et - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - return; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -- u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ u32 val; -+ -+ if (!eth->netdev[i]) -+ continue; -+ -+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i)); - - /* default setup the forward port to send frame to PDMA */ - val &= ~0xffff; -@@ -3063,7 +3068,7 @@ static void mtk_gdm_config(struct mtk_et - - val |= config; - -- if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i])) -+ if (netdev_uses_dsa(eth->netdev[i])) - val |= MTK_GDMA_SPECIAL_TAG; - - mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); -@@ -3660,15 +3665,15 @@ static int mtk_hw_init(struct mtk_eth *e - * up with the more appropriate value when mtk_mac_config call is being - * invoked. - */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - struct net_device *dev = eth->netdev[i]; - -- mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); -- if (dev) { -- struct mtk_mac *mac = netdev_priv(dev); -+ if (!dev) -+ continue; - -- mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN); -- } -+ mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i)); -+ mtk_set_mcr_max_rx(netdev_priv(dev), -+ dev->mtu + MTK_RX_ETH_HLEN); - } - - /* Indicates CDM to parse the MTK special tag from CPU -@@ -3848,7 +3853,7 @@ static void mtk_pending_work(struct work - mtk_prepare_for_reset(eth); - - /* stop all devices to make sure that dma is properly shut down */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->netdev[i] || !netif_running(eth->netdev[i])) - continue; - -@@ -3864,8 +3869,8 @@ static void mtk_pending_work(struct work - mtk_hw_init(eth, true); - - /* restart DMA and enable IRQs */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -- if (!test_bit(i, &restart)) -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ if (!eth->netdev[i] || !test_bit(i, &restart)) - continue; - - if (mtk_open(eth->netdev[i])) { -@@ -3892,7 +3897,7 @@ static int mtk_free_dev(struct mtk_eth * - { - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->netdev[i]) - continue; - free_netdev(eth->netdev[i]); -@@ -3911,7 +3916,7 @@ static int mtk_unreg_dev(struct mtk_eth - { - int i; - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - struct mtk_mac *mac; - if (!eth->netdev[i]) - continue; -@@ -4212,7 +4217,7 @@ static int mtk_add_mac(struct mtk_eth *e - } - - id = be32_to_cpup(_id); -- if (id >= MTK_MAC_COUNT) { -+ if (id >= MTK_MAX_DEVS) { - dev_err(eth->dev, "%d is not a valid mac id\n", id); - return -EINVAL; - } -@@ -4357,7 +4362,7 @@ void mtk_eth_set_dma_device(struct mtk_e - - rtnl_lock(); - -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - dev = eth->netdev[i]; - - if (!dev || !(dev->flags & IFF_UP)) -@@ -4663,7 +4668,7 @@ static int mtk_remove(struct platform_de - int i; - - /* stop all devices to make sure that dma is properly shut down */ -- for (i = 0; i < MTK_MAC_COUNT; i++) { -+ for (i = 0; i < MTK_MAX_DEVS; i++) { - if (!eth->netdev[i]) - continue; - mtk_stop(eth->netdev[i]); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -33,7 +33,6 @@ - #define MTK_TX_DMA_BUF_LEN_V2 0xffff - #define MTK_QDMA_RING_SIZE 2048 - #define MTK_DMA_SIZE 512 --#define MTK_MAC_COUNT 2 - #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN) - #define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN) - #define MTK_DMA_DUMMY_DESC 0xffffffff diff --git a/target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch b/target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch deleted file mode 100644 index e40dc3d0a9f88a..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch +++ /dev/null @@ -1,307 +0,0 @@ -From a41d535855976838d246c079143c948dcf0f7931 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:52:59 +0100 -Subject: [PATCH 102/250] net: ethernet: mtk_eth_soc: add NETSYS_V3 version - support - -Introduce NETSYS_V3 chipset version support. -This is a preliminary patch to introduce support for MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 ++++++++++++++------ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 48 +++++++-- - 2 files changed, 116 insertions(+), 37 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -860,17 +860,32 @@ void mtk_stats_update_mac(struct mtk_mac - mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs); - hw_stats->rx_flow_control_packets += - mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs); -- hw_stats->tx_skip += -- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs); -- hw_stats->tx_collisions += -- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs); -- hw_stats->tx_bytes += -- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs); -- stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs); -- if (stats) -- hw_stats->tx_bytes += (stats << 32); -- hw_stats->tx_packets += -- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs); -+ -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ hw_stats->tx_skip += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs); -+ hw_stats->tx_collisions += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs); -+ hw_stats->tx_bytes += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs); -+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs); -+ if (stats) -+ hw_stats->tx_bytes += (stats << 32); -+ hw_stats->tx_packets += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs); -+ } else { -+ hw_stats->tx_skip += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs); -+ hw_stats->tx_collisions += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs); -+ hw_stats->tx_bytes += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs); -+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs); -+ if (stats) -+ hw_stats->tx_bytes += (stats << 32); -+ hw_stats->tx_packets += -+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs); -+ } - } - - u64_stats_update_end(&hw_stats->syncp); -@@ -1174,7 +1189,10 @@ static void mtk_tx_set_dma_desc_v2(struc - data |= TX_DMA_LS0; - WRITE_ONCE(desc->txd3, data); - -- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ -+ if (mac->id == MTK_GMAC3_ID) -+ data = PSE_GDM3_PORT; -+ else -+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ - data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); - WRITE_ONCE(desc->txd4, data); - -@@ -1185,6 +1203,8 @@ static void mtk_tx_set_dma_desc_v2(struc - /* tx checksum offload */ - if (info->csum) - data |= TX_DMA_CHKSUM_V2; -+ if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev)) -+ data |= TX_DMA_SPTAG_V3; - } - WRITE_ONCE(desc->txd5, data); - -@@ -1250,8 +1270,7 @@ static int mtk_tx_map(struct sk_buff *sk - mtk_tx_set_dma_desc(dev, itxd, &txd_info); - - itx_buf->flags |= MTK_TX_FLAGS_SINGLE0; -- itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : -- MTK_TX_FLAGS_FPORT1; -+ itx_buf->mac_id = mac->id; - setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size, - k++); - -@@ -1299,8 +1318,7 @@ static int mtk_tx_map(struct sk_buff *sk - memset(tx_buf, 0, sizeof(*tx_buf)); - tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; - tx_buf->flags |= MTK_TX_FLAGS_PAGE0; -- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 : -- MTK_TX_FLAGS_FPORT1; -+ tx_buf->mac_id = mac->id; - - setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr, - txd_info.size, k++); -@@ -1602,7 +1620,7 @@ static int mtk_xdp_frame_map(struct mtk_ - } - mtk_tx_set_dma_desc(dev, txd, txd_info); - -- tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1; -+ tx_buf->mac_id = mac->id; - tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX; - tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; - -@@ -1852,11 +1870,24 @@ static int mtk_poll_rx(struct napi_struc - break; - - /* find out which mac the packet come from. values start at 1 */ -- if (mtk_is_netsys_v2_or_greater(eth)) -- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1; -- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && -- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) -+ if (mtk_is_netsys_v2_or_greater(eth)) { -+ u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5); -+ -+ switch (val) { -+ case PSE_GDM1_PORT: -+ case PSE_GDM2_PORT: -+ mac = val - 1; -+ break; -+ case PSE_GDM3_PORT: -+ mac = MTK_GMAC3_ID; -+ break; -+ default: -+ break; -+ } -+ } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && -+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) { - mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1; -+ } - - if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS || - !eth->netdev[mac])) -@@ -2078,7 +2109,6 @@ static int mtk_poll_tx_qdma(struct mtk_e - - while ((cpu != dma) && budget) { - u32 next_cpu = desc->txd2; -- int mac = 0; - - desc = mtk_qdma_phys_to_virt(ring, desc->txd2); - if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0) -@@ -2086,15 +2116,13 @@ static int mtk_poll_tx_qdma(struct mtk_e - - tx_buf = mtk_desc_to_tx_buf(ring, desc, - eth->soc->txrx.txd_size); -- if (tx_buf->flags & MTK_TX_FLAGS_FPORT1) -- mac = 1; -- - if (!tx_buf->data) - break; - - if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) { - if (tx_buf->type == MTK_TYPE_SKB) -- mtk_poll_tx_done(eth, state, mac, tx_buf->data); -+ mtk_poll_tx_done(eth, state, tx_buf->mac_id, -+ tx_buf->data); - - budget--; - } -@@ -3703,7 +3731,24 @@ static int mtk_hw_init(struct mtk_eth *e - mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); - mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); - -- if (mtk_is_netsys_v2_or_greater(eth)) { -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ /* PSE should not drop port1, port8 and port9 packets */ -+ mtk_w32(eth, 0x00000302, PSE_DROP_CFG); -+ -+ /* GDM and CDM Threshold */ -+ mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES); -+ mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES); -+ -+ /* Disable GDM1 RX CRC stripping */ -+ mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0)); -+ -+ /* PSE GDM3 MIB counter has incorrect hw default values, -+ * so the driver ought to read clear the values beforehand -+ * in case ethtool retrieve wrong mib values. -+ */ -+ for (i = 0; i < 0x80; i += 0x4) -+ mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i); -+ } else if (!mtk_is_netsys_v1(eth)) { - /* PSE should not drop port8 and port9 packets from WDMA Tx */ - mtk_w32(eth, 0x00000300, PSE_DROP_CFG); - -@@ -4265,7 +4310,11 @@ static int mtk_add_mac(struct mtk_eth *e - } - spin_lock_init(&mac->hw_stats->stats_lock); - u64_stats_init(&mac->hw_stats->syncp); -- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET; -+ -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mac->hw_stats->reg_offset = id * 0x80; -+ else -+ mac->hw_stats->reg_offset = id * 0x40; - - /* phylink create */ - err = of_get_phy_mode(np, &phy_mode); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -122,6 +122,7 @@ - #define MTK_GDMA_ICS_EN BIT(22) - #define MTK_GDMA_TCS_EN BIT(21) - #define MTK_GDMA_UCS_EN BIT(20) -+#define MTK_GDMA_STRP_CRC BIT(16) - #define MTK_GDMA_TO_PDMA 0x0 - #define MTK_GDMA_DROP_ALL 0x7777 - -@@ -287,8 +288,6 @@ - /* QDMA Interrupt grouping registers */ - #define MTK_RLS_DONE_INT BIT(0) - --#define MTK_STAT_OFFSET 0x40 -- - /* QDMA TX NUM */ - #define QID_BITS_V2(x) (((x) & 0x3f) << 16) - #define MTK_QDMA_GMAC2_QID 8 -@@ -301,6 +300,8 @@ - #define TX_DMA_CHKSUM_V2 (0x7 << 28) - #define TX_DMA_TSO_V2 BIT(31) - -+#define TX_DMA_SPTAG_V3 BIT(27) -+ - /* QDMA V2 descriptor txd4 */ - #define TX_DMA_FPORT_SHIFT_V2 8 - #define TX_DMA_FPORT_MASK_V2 0xf -@@ -634,12 +635,6 @@ enum mtk_tx_flags { - */ - MTK_TX_FLAGS_SINGLE0 = 0x01, - MTK_TX_FLAGS_PAGE0 = 0x02, -- -- /* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted -- * SKB out instead of looking up through hardware TX descriptor. -- */ -- MTK_TX_FLAGS_FPORT0 = 0x04, -- MTK_TX_FLAGS_FPORT1 = 0x08, - }; - - /* This enum allows us to identify how the clock is defined on the array of the -@@ -725,6 +720,35 @@ enum mtk_dev_state { - MTK_RESETTING - }; - -+/* PSE Port Definition */ -+enum mtk_pse_port { -+ PSE_ADMA_PORT = 0, -+ PSE_GDM1_PORT, -+ PSE_GDM2_PORT, -+ PSE_PPE0_PORT, -+ PSE_PPE1_PORT, -+ PSE_QDMA_TX_PORT, -+ PSE_QDMA_RX_PORT, -+ PSE_DROP_PORT, -+ PSE_WDMA0_PORT, -+ PSE_WDMA1_PORT, -+ PSE_TDMA_PORT, -+ PSE_NONE_PORT, -+ PSE_PPE2_PORT, -+ PSE_WDMA2_PORT, -+ PSE_EIP197_PORT, -+ PSE_GDM3_PORT, -+ PSE_PORT_MAX -+}; -+ -+/* GMAC Identifier */ -+enum mtk_gmac_id { -+ MTK_GMAC1_ID = 0, -+ MTK_GMAC2_ID, -+ MTK_GMAC3_ID, -+ MTK_GMAC_ID_MAX -+}; -+ - enum mtk_tx_buf_type { - MTK_TYPE_SKB, - MTK_TYPE_XDP_TX, -@@ -743,7 +767,8 @@ struct mtk_tx_buf { - enum mtk_tx_buf_type type; - void *data; - -- u32 flags; -+ u16 mac_id; -+ u16 flags; - DEFINE_DMA_UNMAP_ADDR(dma_addr0); - DEFINE_DMA_UNMAP_LEN(dma_len0); - DEFINE_DMA_UNMAP_ADDR(dma_addr1); -@@ -1192,6 +1217,11 @@ static inline bool mtk_is_netsys_v2_or_g - return eth->soc->version > 1; - } - -+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) -+{ -+ return eth->soc->version > 2; -+} -+ - static inline struct mtk_foe_entry * - mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) - { diff --git a/target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch b/target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch deleted file mode 100644 index 7a0b285f2ca3a3..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch +++ /dev/null @@ -1,193 +0,0 @@ -From db797ae0542220a98658229397da464c383c991c Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:53:13 +0100 -Subject: [PATCH 103/250] net: ethernet: mtk_eth_soc: convert caps in - mtk_soc_data struct to u64 - -This is a preliminary patch to introduce support for MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/9499ac3670b2fc5b444404b84e8a4a169beabbf2.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 ++++---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 56 ++++++++++---------- - 2 files changed, 39 insertions(+), 39 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -15,10 +15,10 @@ - struct mtk_eth_muxc { - const char *name; - int cap_bit; -- int (*set_path)(struct mtk_eth *eth, int path); -+ int (*set_path)(struct mtk_eth *eth, u64 path); - }; - --static const char *mtk_eth_path_name(int path) -+static const char *mtk_eth_path_name(u64 path) - { - switch (path) { - case MTK_ETH_PATH_GMAC1_RGMII: -@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int - } - } - --static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path) -+static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path) - { - bool updated = true; - u32 val, mask, set; -@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str - return 0; - } - --static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path) -+static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy( - return 0; - } - --static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path) -+static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0, mask = 0, reg = 0; - bool updated = true; -@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru - return 0; - } - --static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path) -+static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_ - return 0; - } - --static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path) -+static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth - }, - }; - --static int mtk_eth_mux_setup(struct mtk_eth *eth, int path) -+static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path) - { - int i, err = 0; - -@@ -249,7 +249,7 @@ out: - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id) - { -- int path; -+ u64 path; - - path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII : - MTK_ETH_PATH_GMAC2_SGMII; -@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk - - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id) - { -- int path = 0; -+ u64 path = 0; - - if (mac_id == 1) - path = MTK_ETH_PATH_GMAC2_GEPHY; -@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk - - int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id) - { -- int path; -+ u64 path; - - path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_RGMII : - MTK_ETH_PATH_GMAC2_RGMII; ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -866,41 +866,41 @@ enum mkt_eth_capabilities { - }; - - /* Supported hardware group on SoCs */ --#define MTK_RGMII BIT(MTK_RGMII_BIT) --#define MTK_TRGMII BIT(MTK_TRGMII_BIT) --#define MTK_SGMII BIT(MTK_SGMII_BIT) --#define MTK_ESW BIT(MTK_ESW_BIT) --#define MTK_GEPHY BIT(MTK_GEPHY_BIT) --#define MTK_MUX BIT(MTK_MUX_BIT) --#define MTK_INFRA BIT(MTK_INFRA_BIT) --#define MTK_SHARED_SGMII BIT(MTK_SHARED_SGMII_BIT) --#define MTK_HWLRO BIT(MTK_HWLRO_BIT) --#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT) --#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) --#define MTK_QDMA BIT(MTK_QDMA_BIT) --#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT) --#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT) --#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT) -+#define MTK_RGMII BIT_ULL(MTK_RGMII_BIT) -+#define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) -+#define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) -+#define MTK_ESW BIT_ULL(MTK_ESW_BIT) -+#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) -+#define MTK_MUX BIT_ULL(MTK_MUX_BIT) -+#define MTK_INFRA BIT_ULL(MTK_INFRA_BIT) -+#define MTK_SHARED_SGMII BIT_ULL(MTK_SHARED_SGMII_BIT) -+#define MTK_HWLRO BIT_ULL(MTK_HWLRO_BIT) -+#define MTK_SHARED_INT BIT_ULL(MTK_SHARED_INT_BIT) -+#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT) -+#define MTK_QDMA BIT_ULL(MTK_QDMA_BIT) -+#define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT) -+#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) -+#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ -- BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -+ BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) - #define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY \ -- BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) -+ BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) - #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \ -- BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) -+ BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) - #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \ -- BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) -+ BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) - #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ -- BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) -+ BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) - - /* Supported path present on SoCs */ --#define MTK_ETH_PATH_GMAC1_RGMII BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT) --#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT) --#define MTK_ETH_PATH_GMAC1_SGMII BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT) --#define MTK_ETH_PATH_GMAC2_RGMII BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT) --#define MTK_ETH_PATH_GMAC2_SGMII BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT) --#define MTK_ETH_PATH_GMAC2_GEPHY BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT) --#define MTK_ETH_PATH_GDM1_ESW BIT(MTK_ETH_PATH_GDM1_ESW_BIT) -+#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) -+#define MTK_ETH_PATH_GMAC1_TRGMII BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT) -+#define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) -+#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) - - #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) - #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) -@@ -1045,7 +1045,7 @@ struct mtk_reg_map { - struct mtk_soc_data { - const struct mtk_reg_map *reg_map; - u32 ana_rgc3; -- u32 caps; -+ u64 caps; - u32 required_clks; - bool required_pctl; - u8 offload_version; diff --git a/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch b/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch deleted file mode 100644 index 5947d385f25601..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch +++ /dev/null @@ -1,132 +0,0 @@ -From a1c9f7d1d24e90294f6a6755b137fcf306851e93 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 25 Jul 2023 01:53:28 +0100 -Subject: [PATCH 104/250] net: ethernet: mtk_eth_soc: convert clock bitmap to - u64 - -The to-be-added MT7988 SoC adds many new clocks which need to be -controlled by the Ethernet driver, which will result in their total -number exceeding 32. -Prepare by converting clock bitmaps into 64-bit types. - -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/6960a39bb0078cf84d7642a9558e6a91c6cc9df3.1690246066.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 96 +++++++++++---------- - 1 file changed, 49 insertions(+), 47 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -666,54 +666,56 @@ enum mtk_clks_map { - MTK_CLK_MAX - }; - --#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \ -- BIT(MTK_CLK_TRGPLL)) --#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_GP2) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK) | \ -- BIT(MTK_CLK_ETH2PLL)) -+#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_TRGPLL)) -+#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK) | \ -+ BIT_ULL(MTK_CLK_ETH2PLL)) - #define MT7621_CLKS_BITMAP (0) - #define MT7628_CLKS_BITMAP (0) --#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \ -- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK) | \ -- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP)) --#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_WOCPU0) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB) | \ -- BIT(MTK_CLK_SGMII_CK)) --#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \ -- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \ -- BIT(MTK_CLK_SGMII_TX_250M) | \ -- BIT(MTK_CLK_SGMII_RX_250M) | \ -- BIT(MTK_CLK_SGMII_CDR_REF) | \ -- BIT(MTK_CLK_SGMII_CDR_FB) | \ -- BIT(MTK_CLK_SGMII2_TX_250M) | \ -- BIT(MTK_CLK_SGMII2_RX_250M) | \ -- BIT(MTK_CLK_SGMII2_CDR_REF) | \ -- BIT(MTK_CLK_SGMII2_CDR_FB)) -+#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK) | \ -+ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP)) -+#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII_CK)) -+#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_GP1) | \ -+ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ -+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB)) - - enum mtk_dev_state { - MTK_HW_INIT, -@@ -1046,7 +1048,7 @@ struct mtk_soc_data { - const struct mtk_reg_map *reg_map; - u32 ana_rgc3; - u64 caps; -- u32 required_clks; -+ u64 required_clks; - bool required_pctl; - u8 offload_version; - u8 hash_offset; diff --git a/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch b/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch deleted file mode 100644 index 8b1493ce14409e..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch +++ /dev/null @@ -1,477 +0,0 @@ -From 94f825a7eadfc8b4c8828efdb7705d9703f9c73e Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Tue, 25 Jul 2023 01:57:42 +0100 -Subject: [PATCH 105/250] net: ethernet: mtk_eth_soc: add basic support for - MT7988 SoC - -Introduce support for ethernet chip available in MT7988 SoC to -mtk_eth_soc driver. As a first step support only the first GMAC which -is hard-wired to the internal DSA switch having 4 built-in gigabit -Ethernet PHYs. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/25c8377095b95d186872eeda7aa055da83e8f0ca.1690246605.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 201 +++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 86 +++++++- - 3 files changed, 273 insertions(+), 28 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -43,7 +43,7 @@ static const char *mtk_eth_path_name(u64 - static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path) - { - bool updated = true; -- u32 val, mask, set; -+ u32 mask, set, reg; - - switch (path) { - case MTK_ETH_PATH_GMAC1_SGMII: -@@ -59,11 +59,13 @@ static int set_mux_gdm1_to_gmac1_esw(str - break; - } - -- if (updated) { -- val = mtk_r32(eth, MTK_MAC_MISC); -- val = (val & mask) | set; -- mtk_w32(eth, val, MTK_MAC_MISC); -- } -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ reg = MTK_MAC_MISC_V3; -+ else -+ reg = MTK_MAC_MISC; -+ -+ if (updated) -+ mtk_m32(eth, mask, set, reg); - - dev_dbg(eth->dev, "path %s in %s updated = %d\n", - mtk_eth_path_name(path), __func__, updated); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r - .pse_oq_sta = 0x01a0, - }; - -+static const struct mtk_reg_map mt7988_reg_map = { -+ .tx_irq_mask = 0x461c, -+ .tx_irq_status = 0x4618, -+ .pdma = { -+ .rx_ptr = 0x6900, -+ .rx_cnt_cfg = 0x6904, -+ .pcrx_ptr = 0x6908, -+ .glo_cfg = 0x6a04, -+ .rst_idx = 0x6a08, -+ .delay_irq = 0x6a0c, -+ .irq_status = 0x6a20, -+ .irq_mask = 0x6a28, -+ .adma_rx_dbg0 = 0x6a38, -+ .int_grp = 0x6a50, -+ }, -+ .qdma = { -+ .qtx_cfg = 0x4400, -+ .qtx_sch = 0x4404, -+ .rx_ptr = 0x4500, -+ .rx_cnt_cfg = 0x4504, -+ .qcrx_ptr = 0x4508, -+ .glo_cfg = 0x4604, -+ .rst_idx = 0x4608, -+ .delay_irq = 0x460c, -+ .fc_th = 0x4610, -+ .int_grp = 0x4620, -+ .hred = 0x4644, -+ .ctx_ptr = 0x4700, -+ .dtx_ptr = 0x4704, -+ .crx_ptr = 0x4710, -+ .drx_ptr = 0x4714, -+ .fq_head = 0x4720, -+ .fq_tail = 0x4724, -+ .fq_count = 0x4728, -+ .fq_blen = 0x472c, -+ .tx_sch_rate = 0x4798, -+ }, -+ .gdm1_cnt = 0x1c00, -+ .gdma_to_ppe = 0x3333, -+ .ppe_base = 0x2000, -+ .wdma_base = { -+ [0] = 0x4800, -+ [1] = 0x4c00, -+ }, -+ .pse_iq_sta = 0x0180, -+ .pse_oq_sta = 0x01a0, -+}; -+ - /* strings used by ethtool */ - static const struct mtk_ethtool_stats { - char str[ETH_GSTRING_LEN]; -@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats { - }; - - static const char * const mtk_clks_source_name[] = { -- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll", -- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb", -- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb", -- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1" -+ "ethif", -+ "sgmiitop", -+ "esw", -+ "gp0", -+ "gp1", -+ "gp2", -+ "gp3", -+ "xgp1", -+ "xgp2", -+ "xgp3", -+ "crypto", -+ "fe", -+ "trgpll", -+ "sgmii_tx250m", -+ "sgmii_rx250m", -+ "sgmii_cdr_ref", -+ "sgmii_cdr_fb", -+ "sgmii2_tx250m", -+ "sgmii2_rx250m", -+ "sgmii2_cdr_ref", -+ "sgmii2_cdr_fb", -+ "sgmii_ck", -+ "eth2pll", -+ "wocpu0", -+ "wocpu1", -+ "netsys0", -+ "netsys1", -+ "ethwarp_wocpu2", -+ "ethwarp_wocpu1", -+ "ethwarp_wocpu0", -+ "top_usxgmii0_sel", -+ "top_usxgmii1_sel", -+ "top_sgm0_sel", -+ "top_sgm1_sel", -+ "top_xfi_phy0_xtal_sel", -+ "top_xfi_phy1_xtal_sel", -+ "top_eth_gmii_sel", -+ "top_eth_refck_50m_sel", -+ "top_eth_sys_200m_sel", -+ "top_eth_sys_sel", -+ "top_eth_xgmii_sel", -+ "top_eth_mii_sel", -+ "top_netsys_sel", -+ "top_netsys_500m_sel", -+ "top_netsys_pao_2x_sel", -+ "top_netsys_sync_250m_sel", -+ "top_netsys_ppefb_250m_sel", -+ "top_netsys_warp_sel", - }; - - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg) -@@ -195,7 +287,7 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne - return __raw_readl(eth->base + reg); - } - --static u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg) -+u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg) - { - u32 val; - -@@ -369,6 +461,19 @@ static void mtk_gmac0_rgmii_adjust(struc - dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n"); - } - -+static void mtk_setup_bridge_switch(struct mtk_eth *eth) -+{ -+ /* Force Port1 XGMAC Link Up */ -+ mtk_m32(eth, 0, MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID), -+ MTK_XGMAC_STS(MTK_GMAC1_ID)); -+ -+ /* Adjust GSW bridge IPG to 11 */ -+ mtk_m32(eth, GSWTX_IPG_MASK | GSWRX_IPG_MASK, -+ (GSW_IPG_11 << GSWTX_IPG_SHIFT) | -+ (GSW_IPG_11 << GSWRX_IPG_SHIFT), -+ MTK_GSW_CFG); -+} -+ - static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, - phy_interface_t interface) - { -@@ -438,6 +543,8 @@ static void mtk_mac_config(struct phylin - goto init_err; - } - break; -+ case PHY_INTERFACE_MODE_INTERNAL: -+ break; - default: - goto err_phy; - } -@@ -515,6 +622,15 @@ static void mtk_mac_config(struct phylin - return; - } - -+ /* Setup gmac */ -+ if (mtk_is_netsys_v3_or_greater(eth) && -+ mac->interface == PHY_INTERFACE_MODE_INTERNAL) { -+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); -+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); -+ -+ mtk_setup_bridge_switch(eth); -+ } -+ - return; - - err_phy: -@@ -724,11 +840,15 @@ static int mtk_mdio_init(struct mtk_eth - } - divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63); - -+ /* Configure MDC Turbo Mode */ -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3); -+ - /* Configure MDC Divider */ -- val = mtk_r32(eth, MTK_PPSC); -- val &= ~PPSC_MDC_CFG; -- val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO; -- mtk_w32(eth, val, MTK_PPSC); -+ val = FIELD_PREP(PPSC_MDC_CFG, divider); -+ if (!mtk_is_netsys_v3_or_greater(eth)) -+ val |= PPSC_MDC_TURBO; -+ mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC); - - dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider); - -@@ -1189,10 +1309,19 @@ static void mtk_tx_set_dma_desc_v2(struc - data |= TX_DMA_LS0; - WRITE_ONCE(desc->txd3, data); - -- if (mac->id == MTK_GMAC3_ID) -- data = PSE_GDM3_PORT; -- else -- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */ -+ /* set forward port */ -+ switch (mac->id) { -+ case MTK_GMAC1_ID: -+ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ case MTK_GMAC2_ID: -+ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ case MTK_GMAC3_ID: -+ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2; -+ break; -+ } -+ - data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid); - WRITE_ONCE(desc->txd4, data); - -@@ -4359,6 +4488,17 @@ static int mtk_add_mac(struct mtk_eth *e - mac->phylink_config.supported_interfaces); - } - -+ if (mtk_is_netsys_v3_or_greater(mac->hw) && -+ MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW_BIT) && -+ id == MTK_GMAC1_ID) { -+ mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | -+ MAC_SYM_PAUSE | -+ MAC_10000FD; -+ phy_interface_zero(mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ mac->phylink_config.supported_interfaces); -+ } -+ - phylink = phylink_create(&mac->phylink_config, - of_fwnode_handle(mac->of_node), - phy_mode, &mtk_phylink_ops); -@@ -4879,6 +5019,24 @@ static const struct mtk_soc_data mt7986_ - }, - }; - -+static const struct mtk_soc_data mt7988_data = { -+ .reg_map = &mt7988_reg_map, -+ .ana_rgc3 = 0x128, -+ .caps = MT7988_CAPS, -+ .hw_features = MTK_HW_FEATURES, -+ .required_clks = MT7988_CLKS_BITMAP, -+ .required_pctl = false, -+ .version = 3, -+ .txrx = { -+ .txd_size = sizeof(struct mtk_tx_dma_v2), -+ .rxd_size = sizeof(struct mtk_rx_dma_v2), -+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2, -+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2, -+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2, -+ .dma_len_offset = 8, -+ }, -+}; -+ - static const struct mtk_soc_data rt5350_data = { - .reg_map = &mt7628_reg_map, - .caps = MT7628_CAPS, -@@ -4897,14 +5055,15 @@ static const struct mtk_soc_data rt5350_ - }; - - const struct of_device_id of_mtk_match[] = { -- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data}, -- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data}, -- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data}, -- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data}, -- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data}, -- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data}, -- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data}, -- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data}, -+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data }, -+ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data }, -+ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data }, -+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data }, -+ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data }, -+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data }, -+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data }, -+ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data }, -+ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data }, - {}, - }; - MODULE_DEVICE_TABLE(of, of_mtk_match); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -117,7 +117,8 @@ - #define MTK_CDMP_EG_CTRL 0x404 - - /* GDM Exgress Control Register */ --#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000)) -+#define MTK_GDMA_FWD_CFG(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ -+ 0x540 : 0x500 + (_x * 0x1000); }) - #define MTK_GDMA_SPECIAL_TAG BIT(24) - #define MTK_GDMA_ICS_EN BIT(22) - #define MTK_GDMA_TCS_EN BIT(21) -@@ -126,6 +127,11 @@ - #define MTK_GDMA_TO_PDMA 0x0 - #define MTK_GDMA_DROP_ALL 0x7777 - -+/* GDM Egress Control Register */ -+#define MTK_GDMA_EG_CTRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ -+ 0x544 : 0x504 + (_x * 0x1000); }) -+#define MTK_GDMA_XGDM_SEL BIT(31) -+ - /* Unicast Filter MAC Address Register - Low */ - #define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) - -@@ -389,7 +395,26 @@ - #define PHY_IAC_TIMEOUT HZ - - #define MTK_MAC_MISC 0x1000c -+#define MTK_MAC_MISC_V3 0x10010 - #define MTK_MUX_TO_ESW BIT(0) -+#define MISC_MDC_TURBO BIT(4) -+ -+/* XMAC status registers */ -+#define MTK_XGMAC_STS(x) (((x) == MTK_GMAC3_ID) ? 0x1001C : 0x1000C) -+#define MTK_XGMAC_FORCE_LINK(x) (((x) == MTK_GMAC2_ID) ? BIT(31) : BIT(15)) -+#define MTK_USXGMII_PCS_LINK BIT(8) -+#define MTK_XGMAC_RX_FC BIT(5) -+#define MTK_XGMAC_TX_FC BIT(4) -+#define MTK_USXGMII_PCS_MODE GENMASK(3, 1) -+#define MTK_XGMAC_LINK_STS BIT(0) -+ -+/* GSW bridge registers */ -+#define MTK_GSW_CFG (0x10080) -+#define GSWTX_IPG_MASK GENMASK(19, 16) -+#define GSWTX_IPG_SHIFT 16 -+#define GSWRX_IPG_MASK GENMASK(3, 0) -+#define GSWRX_IPG_SHIFT 0 -+#define GSW_IPG_11 11 - - /* Mac control registers */ - #define MTK_MAC_MCR(x) (0x10100 + (x * 0x100)) -@@ -647,6 +672,11 @@ enum mtk_clks_map { - MTK_CLK_GP0, - MTK_CLK_GP1, - MTK_CLK_GP2, -+ MTK_CLK_GP3, -+ MTK_CLK_XGP1, -+ MTK_CLK_XGP2, -+ MTK_CLK_XGP3, -+ MTK_CLK_CRYPTO, - MTK_CLK_FE, - MTK_CLK_TRGPLL, - MTK_CLK_SGMII_TX_250M, -@@ -663,6 +693,27 @@ enum mtk_clks_map { - MTK_CLK_WOCPU1, - MTK_CLK_NETSYS0, - MTK_CLK_NETSYS1, -+ MTK_CLK_ETHWARP_WOCPU2, -+ MTK_CLK_ETHWARP_WOCPU1, -+ MTK_CLK_ETHWARP_WOCPU0, -+ MTK_CLK_TOP_USXGMII_SBUS_0_SEL, -+ MTK_CLK_TOP_USXGMII_SBUS_1_SEL, -+ MTK_CLK_TOP_SGM_0_SEL, -+ MTK_CLK_TOP_SGM_1_SEL, -+ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL, -+ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL, -+ MTK_CLK_TOP_ETH_GMII_SEL, -+ MTK_CLK_TOP_ETH_REFCK_50M_SEL, -+ MTK_CLK_TOP_ETH_SYS_200M_SEL, -+ MTK_CLK_TOP_ETH_SYS_SEL, -+ MTK_CLK_TOP_ETH_XGMII_SEL, -+ MTK_CLK_TOP_ETH_MII_SEL, -+ MTK_CLK_TOP_NETSYS_SEL, -+ MTK_CLK_TOP_NETSYS_500M_SEL, -+ MTK_CLK_TOP_NETSYS_PAO_2X_SEL, -+ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL, -+ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL, -+ MTK_CLK_TOP_NETSYS_WARP_SEL, - MTK_CLK_MAX - }; - -@@ -716,6 +767,36 @@ enum mtk_clks_map { - BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ - BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \ - BIT_ULL(MTK_CLK_SGMII2_CDR_FB)) -+#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \ -+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \ -+ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \ -+ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \ -+ BIT_ULL(MTK_CLK_CRYPTO) | \ -+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \ -+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \ -+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \ -+ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL)) - - enum mtk_dev_state { - MTK_HW_INIT, -@@ -964,6 +1045,8 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_RSTCTRL_PPE1) - -+#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1) -+ - struct mtk_tx_dma_desc_info { - dma_addr_t addr; - u32 size; -@@ -1309,6 +1392,7 @@ void mtk_stats_update_mac(struct mtk_mac - - void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg); - u32 mtk_r32(struct mtk_eth *eth, unsigned reg); -+u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); diff --git a/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch b/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch deleted file mode 100644 index bb48dadec0f46f..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 38a7eb76220731eff40602cf433f24880be0a6c2 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 27 Jul 2023 09:02:26 +0200 -Subject: [PATCH 106/250] net: ethernet: mtk_eth_soc: enable page_pool support - for MT7988 SoC - -In order to recycle pages, enable page_pool allocator for MT7988 SoC. - -Tested-by: Daniel Golle -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/fd4e8693980e47385a543e7b002eec0b88bd09df.1690440675.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1657,7 +1657,7 @@ static void mtk_update_rx_cpu_idx(struct - - static bool mtk_page_pool_enabled(struct mtk_eth *eth) - { -- return eth->soc->version == 2; -+ return mtk_is_netsys_v2_or_greater(eth); - } - - static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth, diff --git a/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch b/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch deleted file mode 100644 index bb8deb9846e02c..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 199e7d5a7f03dd377f3a7a458360dbedd71d50ba Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Thu, 27 Jul 2023 09:07:28 +0200 -Subject: [PATCH 107/250] net: ethernet: mtk_eth_soc: enable nft hw - flowtable_offload for MT7988 SoC - -Enable hw Packet Process Engine (PPE) for MT7988 SoC. - -Tested-by: Daniel Golle -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/5e86341b0220a49620dadc02d77970de5ded9efc.1690441576.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +++ - drivers/net/ethernet/mediatek/mtk_ppe.c | 19 +++++++++++++++---- - drivers/net/ethernet/mediatek/mtk_ppe.h | 19 ++++++++++++++++++- - 3 files changed, 36 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -5027,6 +5027,9 @@ static const struct mtk_soc_data mt7988_ - .required_clks = MT7988_CLKS_BITMAP, - .required_pctl = false, - .version = 3, -+ .offload_version = 2, -+ .hash_offset = 4, -+ .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), - .rxd_size = sizeof(struct mtk_rx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -422,13 +422,22 @@ int mtk_foe_entry_set_wdma(struct mtk_et - struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - u32 *ib2 = mtk_foe_entry_ib2(eth, entry); - -- if (mtk_is_netsys_v2_or_greater(eth)) { -+ switch (eth->soc->version) { -+ case 3: -+ *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; -+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | -+ MTK_FOE_IB2_WDMA_WINFO_V2; -+ l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) | -+ FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss); -+ break; -+ case 2: - *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; - *ib2 |= FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) | - MTK_FOE_IB2_WDMA_WINFO_V2; - l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) | - FIELD_PREP(MTK_FOE_WINFO_BSS, bss); -- } else { -+ break; -+ default: - *ib2 &= ~MTK_FOE_IB2_PORT_MG; - *ib2 |= MTK_FOE_IB2_WDMA_WINFO; - if (wdma_idx) -@@ -436,6 +445,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et - l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) | - FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) | - FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq); -+ break; - } - - return 0; -@@ -950,8 +960,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - mtk_ppe_init_foe_table(ppe); - ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys); - -- val = MTK_PPE_TB_CFG_ENTRY_80B | -- MTK_PPE_TB_CFG_AGE_NON_L4 | -+ val = MTK_PPE_TB_CFG_AGE_NON_L4 | - MTK_PPE_TB_CFG_AGE_UNBIND | - MTK_PPE_TB_CFG_AGE_TCP | - MTK_PPE_TB_CFG_AGE_UDP | -@@ -967,6 +976,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe) - MTK_PPE_ENTRIES_SHIFT); - if (mtk_is_netsys_v2_or_greater(ppe->eth)) - val |= MTK_PPE_TB_CFG_INFO_SEL; -+ if (!mtk_is_netsys_v3_or_greater(ppe->eth)) -+ val |= MTK_PPE_TB_CFG_ENTRY_80B; - ppe_w32(ppe, MTK_PPE_TB_CFG, val); - - ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK, ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -85,6 +85,17 @@ enum { - #define MTK_FOE_WINFO_BSS GENMASK(5, 0) - #define MTK_FOE_WINFO_WCID GENMASK(15, 6) - -+#define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16) -+#define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0) -+ -+#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0) -+#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16) -+#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20) -+#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21) -+#define MTK_FOE_WINFO_PAO_IS_SP BIT(22) -+#define MTK_FOE_WINFO_PAO_HF BIT(23) -+#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24) -+ - enum { - MTK_FOE_STATE_INVALID, - MTK_FOE_STATE_UNBIND, -@@ -106,8 +117,13 @@ struct mtk_foe_mac_info { - u16 pppoe_id; - u16 src_mac_lo; - -+ /* netsys_v2 */ - u16 minfo; - u16 winfo; -+ -+ /* netsys_v3 */ -+ u32 w3info; -+ u32 wpao; - }; - - /* software-only entry type */ -@@ -218,6 +234,7 @@ struct mtk_foe_ipv6_6rd { - - #define MTK_FOE_ENTRY_V1_SIZE 80 - #define MTK_FOE_ENTRY_V2_SIZE 96 -+#define MTK_FOE_ENTRY_V3_SIZE 128 - - struct mtk_foe_entry { - u32 ib1; -@@ -228,7 +245,7 @@ struct mtk_foe_entry { - struct mtk_foe_ipv4_dslite dslite; - struct mtk_foe_ipv6 ipv6; - struct mtk_foe_ipv6_6rd ipv6_6rd; -- u32 data[23]; -+ u32 data[31]; - }; - }; - diff --git a/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch b/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch deleted file mode 100644 index c985b6a9c7c85b..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0c024632c1e7ff69914329bfd87bec749b9c0aed Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 2 Aug 2023 04:31:09 +0100 -Subject: [PATCH 108/250] net: ethernet: mtk_eth_soc: support per-flow - accounting on MT7988 - -NETSYS_V3 uses 64 bits for each counters while older SoCs are using -48/40 bits for each counter. -Support reading per-flow byte and package counters on NETSYS_V3. - -Signed-off-by: Daniel Golle -Reviewed-by: Simon Horman -Link: https://lore.kernel.org/r/37a0928fa8c1253b197884c68ce1f54239421ac5.1690946442.git.daniel@makrotopia.org -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + - drivers/net/ethernet/mediatek/mtk_ppe.c | 21 +++++++++++++------- - drivers/net/ethernet/mediatek/mtk_ppe_regs.h | 2 ++ - 3 files changed, 17 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -5029,6 +5029,7 @@ static const struct mtk_soc_data mt7988_ - .version = 3, - .offload_version = 2, - .hash_offset = 4, -+ .has_accounting = true, - .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, - .txrx = { - .txd_size = sizeof(struct mtk_tx_dma_v2), ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -91,7 +91,6 @@ static int mtk_ppe_mib_wait_busy(struct - - static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) - { -- u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high; - u32 val, cnt_r0, cnt_r1, cnt_r2; - int ret; - -@@ -106,12 +105,20 @@ static int mtk_mib_entry_read(struct mtk - cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); - cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2); - -- byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); -- byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); -- pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); -- pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; -+ if (mtk_is_netsys_v3_or_greater(ppe->eth)) { -+ /* 64 bit for each counter */ -+ u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3); -+ *bytes = ((u64)cnt_r1 << 32) | cnt_r0; -+ *packets = ((u64)cnt_r3 << 32) | cnt_r2; -+ } else { -+ /* 48 bit byte counter, 40 bit packet counter */ -+ u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); -+ u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); -+ u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); -+ u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -+ *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -+ *packets = (pkt_cnt_high << 16) | pkt_cnt_low; -+ } - - return 0; - } ---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h -@@ -163,6 +163,8 @@ enum { - #define MTK_PPE_MIB_SER_R2 0x348 - #define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH GENMASK(23, 0) - -+#define MTK_PPE_MIB_SER_R3 0x34c -+ - #define MTK_PPE_MIB_CACHE_CTL 0x350 - #define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) - #define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) diff --git a/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch b/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch deleted file mode 100644 index 6f1639a5720abc..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 3b12f42772c26869d60398c1710aa27b27cd945c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 21 Aug 2023 17:12:44 +0100 -Subject: [PATCH 109/250] net: ethernet: mtk_eth_soc: fix NULL pointer on hw - reset - -When a hardware reset is triggered on devices not initializing WED the -calls to mtk_wed_fe_reset and mtk_wed_fe_reset_complete dereference a -pointer on uninitialized stack memory. -Break out of both functions in case a hw_list entry is 0. - -Fixes: 08a764a7c51b ("net: ethernet: mtk_wed: add reset/reset_complete callbacks") -Signed-off-by: Daniel Golle -Reviewed-by: Simon Horman -Acked-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/5465c1609b464cc7407ae1530c40821dcdf9d3e6.1692634266.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_wed.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -214,9 +214,13 @@ void mtk_wed_fe_reset(void) - - for (i = 0; i < ARRAY_SIZE(hw_list); i++) { - struct mtk_wed_hw *hw = hw_list[i]; -- struct mtk_wed_device *dev = hw->wed_dev; -+ struct mtk_wed_device *dev; - int err; - -+ if (!hw) -+ break; -+ -+ dev = hw->wed_dev; - if (!dev || !dev->wlan.reset) - continue; - -@@ -237,8 +241,12 @@ void mtk_wed_fe_reset_complete(void) - - for (i = 0; i < ARRAY_SIZE(hw_list); i++) { - struct mtk_wed_hw *hw = hw_list[i]; -- struct mtk_wed_device *dev = hw->wed_dev; -+ struct mtk_wed_device *dev; -+ -+ if (!hw) -+ break; - -+ dev = hw->wed_dev; - if (!dev || !dev->wlan.reset_complete) - continue; - diff --git a/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch b/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch deleted file mode 100644 index 2190761fdd499b..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 489aea123d74a846ce746bfdb3efe1e7ad512e0d Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 22 Aug 2023 17:31:24 +0100 -Subject: [PATCH 110/250] net: ethernet: mtk_eth_soc: fix register definitions - for MT7988 - -More register macros need to be adjusted for the 3rd GMAC on MT7988. -Account for added bit in SYSCFG0_SGMII_MASK. - -Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC") -Signed-off-by: Daniel Golle -Reviewed-by: Simon Horman -Link: https://lore.kernel.org/r/1c8da012e2ca80939906d85f314138c552139f0f.1692721443.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -133,10 +133,12 @@ - #define MTK_GDMA_XGDM_SEL BIT(31) - - /* Unicast Filter MAC Address Register - Low */ --#define MTK_GDMA_MAC_ADRL(x) (0x508 + (x * 0x1000)) -+#define MTK_GDMA_MAC_ADRL(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ -+ 0x548 : 0x508 + (_x * 0x1000); }) - - /* Unicast Filter MAC Address Register - High */ --#define MTK_GDMA_MAC_ADRH(x) (0x50C + (x * 0x1000)) -+#define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ -+ 0x54C : 0x50C + (_x * 0x1000); }) - - /* FE global misc reg*/ - #define MTK_FE_GLO_MISC 0x124 -@@ -503,7 +505,7 @@ - #define ETHSYS_SYSCFG0 0x14 - #define SYSCFG0_GE_MASK 0x3 - #define SYSCFG0_GE_MODE(x, y) (x << (12 + (y * 2))) --#define SYSCFG0_SGMII_MASK GENMASK(9, 8) -+#define SYSCFG0_SGMII_MASK GENMASK(9, 7) - #define SYSCFG0_SGMII_GMAC1 ((2 << 8) & SYSCFG0_SGMII_MASK) - #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) - #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) diff --git a/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch b/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch deleted file mode 100644 index e87e0f25225e3b..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 15a84d1c44ae8c1451c265ee60500588a24e8cd6 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 22 Aug 2023 17:32:03 +0100 -Subject: [PATCH 111/250] net: ethernet: mtk_eth_soc: add reset bits for MT7988 - -Add bits needed to reset the frame engine on MT7988. - -Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC") -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/89b6c38380e7a3800c1362aa7575600717bc7543.1692721443.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 76 +++++++++++++++------ - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++-- - 2 files changed, 68 insertions(+), 24 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -3593,19 +3593,34 @@ static void mtk_hw_reset(struct mtk_eth - { - u32 val; - -- if (mtk_is_netsys_v2_or_greater(eth)) { -+ if (mtk_is_netsys_v2_or_greater(eth)) - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0); -+ -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ val = RSTCTRL_PPE0_V3; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= RSTCTRL_PPE1_V3; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) -+ val |= RSTCTRL_PPE2; -+ -+ val |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2; -+ } else if (mtk_is_netsys_v2_or_greater(eth)) { - val = RSTCTRL_PPE0_V2; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= RSTCTRL_PPE1; - } else { - val = RSTCTRL_PPE0; - } - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- val |= RSTCTRL_PPE1; -- - ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val); - -- if (mtk_is_netsys_v2_or_greater(eth)) -+ if (mtk_is_netsys_v3_or_greater(eth)) -+ regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, -+ 0x6f8ff); -+ else if (mtk_is_netsys_v2_or_greater(eth)) - regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, - 0x3ffffff); - } -@@ -3631,13 +3646,21 @@ static void mtk_hw_warm_reset(struct mtk - return; - } - -- if (mtk_is_netsys_v2_or_greater(eth)) -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V3; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ rst_mask |= RSTCTRL_PPE1_V3; -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) -+ rst_mask |= RSTCTRL_PPE2; -+ -+ rst_mask |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2; -+ } else if (mtk_is_netsys_v2_or_greater(eth)) { - rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2; -- else -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ rst_mask |= RSTCTRL_PPE1; -+ } else { - rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0; -- -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- rst_mask |= RSTCTRL_PPE1; -+ } - - regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask); - -@@ -3989,11 +4012,17 @@ static void mtk_prepare_for_reset(struct - u32 val; - int i; - -- /* disabe FE P3 and P4 */ -- val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3; -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- val |= MTK_FE_LINK_DOWN_P4; -- mtk_w32(eth, val, MTK_FE_GLO_CFG); -+ /* set FE PPE ports link down */ -+ for (i = MTK_GMAC1_ID; -+ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID); -+ i += 2) { -+ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) | MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val |= MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) -+ val |= MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT); -+ mtk_w32(eth, val, MTK_FE_GLO_CFG(i)); -+ } - - /* adjust PPE configurations to prepare for reset */ - for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) -@@ -4054,11 +4083,18 @@ static void mtk_pending_work(struct work - } - } - -- /* enabe FE P3 and P4 */ -- val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3; -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -- val &= ~MTK_FE_LINK_DOWN_P4; -- mtk_w32(eth, val, MTK_FE_GLO_CFG); -+ /* set FE PPE ports link up */ -+ for (i = MTK_GMAC1_ID; -+ i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID); -+ i += 2) { -+ val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) & ~MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1)) -+ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2)) -+ val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT); -+ -+ mtk_w32(eth, val, MTK_FE_GLO_CFG(i)); -+ } - - clear_bit(MTK_RESETTING, ð->state); - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -76,9 +76,8 @@ - #define MTK_HW_LRO_SDL_REMAIN_ROOM 1522 - - /* Frame Engine Global Configuration */ --#define MTK_FE_GLO_CFG 0x00 --#define MTK_FE_LINK_DOWN_P3 BIT(11) --#define MTK_FE_LINK_DOWN_P4 BIT(12) -+#define MTK_FE_GLO_CFG(x) (((x) == MTK_GMAC3_ID) ? 0x24 : 0x00) -+#define MTK_FE_LINK_DOWN_P(x) BIT(((x) + 8) % 16) - - /* Frame Engine Global Reset Register */ - #define MTK_RST_GL 0x04 -@@ -522,9 +521,15 @@ - /* ethernet reset control register */ - #define ETHSYS_RSTCTRL 0x34 - #define RSTCTRL_FE BIT(6) -+#define RSTCTRL_WDMA0 BIT(24) -+#define RSTCTRL_WDMA1 BIT(25) -+#define RSTCTRL_WDMA2 BIT(26) - #define RSTCTRL_PPE0 BIT(31) - #define RSTCTRL_PPE0_V2 BIT(30) - #define RSTCTRL_PPE1 BIT(31) -+#define RSTCTRL_PPE0_V3 BIT(29) -+#define RSTCTRL_PPE1_V3 BIT(30) -+#define RSTCTRL_PPE2 BIT(31) - #define RSTCTRL_ETH BIT(23) - - /* ethernet reset check idle register */ -@@ -931,6 +936,7 @@ enum mkt_eth_capabilities { - MTK_QDMA_BIT, - MTK_SOC_MT7628_BIT, - MTK_RSTCTRL_PPE1_BIT, -+ MTK_RSTCTRL_PPE2_BIT, - MTK_U3_COPHY_V2_BIT, - - /* MUX BITS*/ -@@ -965,6 +971,7 @@ enum mkt_eth_capabilities { - #define MTK_QDMA BIT_ULL(MTK_QDMA_BIT) - #define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT) - #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) -+#define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) - #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ -@@ -1047,7 +1054,8 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_RSTCTRL_PPE1) - --#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1) -+#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ -+ MTK_RSTCTRL_PPE2) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; diff --git a/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch b/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch deleted file mode 100644 index 2d0951a9ecd493..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 25ce45fe40b574e5d7ffa407f7f2db03e7d5a910 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 22 Aug 2023 17:32:54 +0100 -Subject: [PATCH 112/250] net: ethernet: mtk_eth_soc: add support for in-SoC - SRAM - -MT7981, MT7986 and MT7988 come with in-SoC SRAM dedicated for Ethernet -DMA rings. Support using the SRAM without breaking existing device tree -bindings, ie. only new SoC starting from MT7988 will have the SRAM -declared as additional resource in device tree. For MT7981 and MT7986 -an offset on top of the main I/O base is used. - -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/e45e0f230c63ad58869e8fe35b95a2fb8925b625.1692721443.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 88 ++++++++++++++++----- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++- - 2 files changed, 78 insertions(+), 22 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1117,10 +1117,13 @@ static int mtk_init_fq_dma(struct mtk_et - dma_addr_t dma_addr; - int i; - -- eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, -- cnt * soc->txrx.txd_size, -- ð->phy_scratch_ring, -- GFP_KERNEL); -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) -+ eth->scratch_ring = eth->sram_base; -+ else -+ eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, -+ cnt * soc->txrx.txd_size, -+ ð->phy_scratch_ring, -+ GFP_KERNEL); - if (unlikely(!eth->scratch_ring)) - return -ENOMEM; - -@@ -2428,8 +2431,14 @@ static int mtk_tx_alloc(struct mtk_eth * - if (!ring->buf) - goto no_tx_mem; - -- ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, -- &ring->phys, GFP_KERNEL); -+ if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) { -+ ring->dma = eth->sram_base + ring_size * sz; -+ ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz; -+ } else { -+ ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz, -+ &ring->phys, GFP_KERNEL); -+ } -+ - if (!ring->dma) - goto no_tx_mem; - -@@ -2528,8 +2537,7 @@ static void mtk_tx_clean(struct mtk_eth - kfree(ring->buf); - ring->buf = NULL; - } -- -- if (ring->dma) { -+ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) { - dma_free_coherent(eth->dma_dev, - ring->dma_size * soc->txrx.txd_size, - ring->dma, ring->phys); -@@ -2548,9 +2556,14 @@ static int mtk_rx_alloc(struct mtk_eth * - { - const struct mtk_reg_map *reg_map = eth->soc->reg_map; - struct mtk_rx_ring *ring; -- int rx_data_len, rx_dma_size; -+ int rx_data_len, rx_dma_size, tx_ring_size; - int i; - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) -+ tx_ring_size = MTK_QDMA_RING_SIZE; -+ else -+ tx_ring_size = MTK_DMA_SIZE; -+ - if (rx_flag == MTK_RX_FLAGS_QDMA) { - if (ring_no) - return -EINVAL; -@@ -2585,9 +2598,20 @@ static int mtk_rx_alloc(struct mtk_eth * - ring->page_pool = pp; - } - -- ring->dma = dma_alloc_coherent(eth->dma_dev, -- rx_dma_size * eth->soc->txrx.rxd_size, -- &ring->phys, GFP_KERNEL); -+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) || -+ rx_flag != MTK_RX_FLAGS_NORMAL) { -+ ring->dma = dma_alloc_coherent(eth->dma_dev, -+ rx_dma_size * eth->soc->txrx.rxd_size, -+ &ring->phys, GFP_KERNEL); -+ } else { -+ struct mtk_tx_ring *tx_ring = ð->tx_ring; -+ -+ ring->dma = tx_ring->dma + tx_ring_size * -+ eth->soc->txrx.txd_size * (ring_no + 1); -+ ring->phys = tx_ring->phys + tx_ring_size * -+ eth->soc->txrx.txd_size * (ring_no + 1); -+ } -+ - if (!ring->dma) - return -ENOMEM; - -@@ -2672,7 +2696,7 @@ static int mtk_rx_alloc(struct mtk_eth * - return 0; - } - --static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring) -+static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram) - { - int i; - -@@ -2695,7 +2719,7 @@ static void mtk_rx_clean(struct mtk_eth - ring->data = NULL; - } - -- if (ring->dma) { -+ if (!in_sram && ring->dma) { - dma_free_coherent(eth->dma_dev, - ring->dma_size * eth->soc->txrx.rxd_size, - ring->dma, ring->phys); -@@ -3058,7 +3082,7 @@ static void mtk_dma_free(struct mtk_eth - for (i = 0; i < MTK_MAX_DEVS; i++) - if (eth->netdev[i]) - netdev_reset_queue(eth->netdev[i]); -- if (eth->scratch_ring) { -+ if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) { - dma_free_coherent(eth->dma_dev, - MTK_QDMA_RING_SIZE * soc->txrx.txd_size, - eth->scratch_ring, eth->phy_scratch_ring); -@@ -3066,13 +3090,13 @@ static void mtk_dma_free(struct mtk_eth - eth->phy_scratch_ring = 0; - } - mtk_tx_clean(eth); -- mtk_rx_clean(eth, ð->rx_ring[0]); -- mtk_rx_clean(eth, ð->rx_ring_qdma); -+ mtk_rx_clean(eth, ð->rx_ring[0], MTK_HAS_CAPS(soc->caps, MTK_SRAM)); -+ mtk_rx_clean(eth, ð->rx_ring_qdma, false); - - if (eth->hwlro) { - mtk_hwlro_rx_uninit(eth); - for (i = 1; i < MTK_MAX_RX_RING_NUM; i++) -- mtk_rx_clean(eth, ð->rx_ring[i]); -+ mtk_rx_clean(eth, ð->rx_ring[i], false); - } - - kfree(eth->scratch_head); -@@ -4640,7 +4664,7 @@ static int mtk_sgmii_init(struct mtk_eth - - static int mtk_probe(struct platform_device *pdev) - { -- struct resource *res = NULL; -+ struct resource *res = NULL, *res_sram; - struct device_node *mac_np; - struct mtk_eth *eth; - int err, i; -@@ -4660,6 +4684,20 @@ static int mtk_probe(struct platform_dev - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) - eth->ip_align = NET_IP_ALIGN; - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) { -+ /* SRAM is actual memory and supports transparent access just like DRAM. -+ * Hence we don't require __iomem being set and don't need to use accessor -+ * functions to read from or write to SRAM. -+ */ -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ eth->sram_base = (void __force *)devm_platform_ioremap_resource(pdev, 1); -+ if (IS_ERR(eth->sram_base)) -+ return PTR_ERR(eth->sram_base); -+ } else { -+ eth->sram_base = (void __force *)eth->base + MTK_ETH_SRAM_OFFSET; -+ } -+ } -+ - spin_lock_init(ð->page_lock); - spin_lock_init(ð->tx_irq_lock); - spin_lock_init(ð->rx_irq_lock); -@@ -4723,6 +4761,18 @@ static int mtk_probe(struct platform_dev - err = -EINVAL; - goto err_destroy_sgmii; - } -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) { -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ res_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (!res_sram) { -+ err = -EINVAL; -+ goto err_destroy_sgmii; -+ } -+ eth->phy_scratch_ring = res_sram->start; -+ } else { -+ eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET; -+ } -+ } - } - - if (eth->soc->offload_version) { ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -139,6 +139,9 @@ - #define MTK_GDMA_MAC_ADRH(x) ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ? \ - 0x54C : 0x50C + (_x * 0x1000); }) - -+/* Internal SRAM offset */ -+#define MTK_ETH_SRAM_OFFSET 0x40000 -+ - /* FE global misc reg*/ - #define MTK_FE_GLO_MISC 0x124 - -@@ -938,6 +941,7 @@ enum mkt_eth_capabilities { - MTK_RSTCTRL_PPE1_BIT, - MTK_RSTCTRL_PPE2_BIT, - MTK_U3_COPHY_V2_BIT, -+ MTK_SRAM_BIT, - - /* MUX BITS*/ - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, -@@ -973,6 +977,7 @@ enum mkt_eth_capabilities { - #define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT) - #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) - #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) -+#define MTK_SRAM BIT_ULL(MTK_SRAM_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ - BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -@@ -1048,14 +1053,14 @@ enum mkt_eth_capabilities { - #define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \ -- MTK_RSTCTRL_PPE1) -+ MTK_RSTCTRL_PPE1 | MTK_SRAM) - - #define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \ - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ -- MTK_RSTCTRL_PPE1) -+ MTK_RSTCTRL_PPE1 | MTK_SRAM) - - #define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ -- MTK_RSTCTRL_PPE2) -+ MTK_RSTCTRL_PPE2 | MTK_SRAM) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1215,6 +1220,7 @@ struct mtk_eth { - struct device *dev; - struct device *dma_dev; - void __iomem *base; -+ void *sram_base; - spinlock_t page_lock; - spinlock_t tx_irq_lock; - spinlock_t rx_irq_lock; diff --git a/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch b/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch deleted file mode 100644 index 416c4f48efc49f..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 0b0d606eb9650fa01dd5621e072aa29a10544399 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 22 Aug 2023 17:33:12 +0100 -Subject: [PATCH 113/250] net: ethernet: mtk_eth_soc: support 36-bit DMA - addressing on MT7988 - -Systems having 4 GiB of RAM and more require DMA addressing beyond the -current 32-bit limit. Starting from MT7988 the hardware now supports -36-bit DMA addressing, let's use that new capability in the driver to -avoid running into swiotlb on systems with 4 GiB of RAM or more. - -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/95b919c98876c9e49761e44662e7c937479eecb8.1692721443.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 22 +++++++++++++-- - 2 files changed, 48 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1310,6 +1310,10 @@ static void mtk_tx_set_dma_desc_v2(struc - data = TX_DMA_PLEN0(info->size); - if (info->last) - data |= TX_DMA_LS0; -+ -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ data |= TX_DMA_PREP_ADDR64(info->addr); -+ - WRITE_ONCE(desc->txd3, data); - - /* set forward port */ -@@ -1979,6 +1983,7 @@ static int mtk_poll_rx(struct napi_struc - bool xdp_flush = false; - int idx; - struct sk_buff *skb; -+ u64 addr64 = 0; - u8 *data, *new_data; - struct mtk_rx_dma_v2 *rxd, trxd; - int done = 0, bytes = 0; -@@ -2094,7 +2099,10 @@ static int mtk_poll_rx(struct napi_struc - goto release_desc; - } - -- dma_unmap_single(eth->dma_dev, trxd.rxd1, -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ addr64 = RX_DMA_GET_ADDR64(trxd.rxd2); -+ -+ dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64), - ring->buf_size, DMA_FROM_DEVICE); - - skb = build_skb(data, ring->frag_size); -@@ -2160,6 +2168,9 @@ release_desc: - else - rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); -+ - ring->calc_idx = idx; - done++; - } -@@ -2652,6 +2663,9 @@ static int mtk_rx_alloc(struct mtk_eth * - else - rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); -+ - rxd->rxd3 = 0; - rxd->rxd4 = 0; - if (mtk_is_netsys_v2_or_greater(eth)) { -@@ -2698,6 +2712,7 @@ static int mtk_rx_alloc(struct mtk_eth * - - static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram) - { -+ u64 addr64 = 0; - int i; - - if (ring->data && ring->dma) { -@@ -2711,7 +2726,10 @@ static void mtk_rx_clean(struct mtk_eth - if (!rxd->rxd1) - continue; - -- dma_unmap_single(eth->dma_dev, rxd->rxd1, -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ addr64 = RX_DMA_GET_ADDR64(rxd->rxd2); -+ -+ dma_unmap_single(eth->dma_dev, ((u64)rxd->rxd1 | addr64), - ring->buf_size, DMA_FROM_DEVICE); - mtk_rx_put_buff(ring, ring->data[i], false); - } -@@ -4698,6 +4716,14 @@ static int mtk_probe(struct platform_dev - } - } - -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { -+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); -+ if (err) { -+ dev_err(&pdev->dev, "Wrong DMA config\n"); -+ return -EINVAL; -+ } -+ } -+ - spin_lock_init(ð->page_lock); - spin_lock_init(ð->tx_irq_lock); - spin_lock_init(ð->rx_irq_lock); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -331,6 +331,14 @@ - #define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) - #define TX_DMA_SWC BIT(14) - #define TX_DMA_PQID GENMASK(3, 0) -+#define TX_DMA_ADDR64_MASK GENMASK(3, 0) -+#if IS_ENABLED(CONFIG_64BIT) -+# define TX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(TX_DMA_ADDR64_MASK, (x))) << 32) -+# define TX_DMA_PREP_ADDR64(x) FIELD_PREP(TX_DMA_ADDR64_MASK, ((x) >> 32)) -+#else -+# define TX_DMA_GET_ADDR64(x) (0) -+# define TX_DMA_PREP_ADDR64(x) (0) -+#endif - - /* PDMA on MT7628 */ - #define TX_DMA_DONE BIT(31) -@@ -343,6 +351,14 @@ - #define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) - #define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len) - #define RX_DMA_VTAG BIT(15) -+#define RX_DMA_ADDR64_MASK GENMASK(3, 0) -+#if IS_ENABLED(CONFIG_64BIT) -+# define RX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(RX_DMA_ADDR64_MASK, (x))) << 32) -+# define RX_DMA_PREP_ADDR64(x) FIELD_PREP(RX_DMA_ADDR64_MASK, ((x) >> 32)) -+#else -+# define RX_DMA_GET_ADDR64(x) (0) -+# define RX_DMA_PREP_ADDR64(x) (0) -+#endif - - /* QDMA descriptor rxd3 */ - #define RX_DMA_VID(x) ((x) & VLAN_VID_MASK) -@@ -942,6 +958,7 @@ enum mkt_eth_capabilities { - MTK_RSTCTRL_PPE2_BIT, - MTK_U3_COPHY_V2_BIT, - MTK_SRAM_BIT, -+ MTK_36BIT_DMA_BIT, - - /* MUX BITS*/ - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, -@@ -978,6 +995,7 @@ enum mkt_eth_capabilities { - #define MTK_RSTCTRL_PPE2 BIT_ULL(MTK_RSTCTRL_PPE2_BIT) - #define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT) - #define MTK_SRAM BIT_ULL(MTK_SRAM_BIT) -+#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT) - - #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \ - BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT) -@@ -1059,8 +1077,8 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_RSTCTRL_PPE1 | MTK_SRAM) - --#define MT7988_CAPS (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \ -- MTK_RSTCTRL_PPE2 | MTK_SRAM) -+#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \ -+ MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; diff --git a/target/linux/generic/backport-6.1/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch b/target/linux/generic/backport-6.1/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch deleted file mode 100644 index d761866d0d8f71..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-20-net-ethernet-mtk_eth_soc-fix-uninitialized-variable.patch +++ /dev/null @@ -1,44 +0,0 @@ -From e10a35abb3da12b812cfb6fc6137926a0c81e39a Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 10 Sep 2023 22:40:30 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix uninitialized variable - -Variable dma_addr in function mtk_poll_rx can be uninitialized on -some of the error paths. In practise this doesn't matter, even random -data present in uninitialized stack memory can safely be used in the -way it happens in the error path. - -However, in order to make Smatch happy make sure the variable is -always initialized. - -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1987,11 +1987,11 @@ static int mtk_poll_rx(struct napi_struc - u8 *data, *new_data; - struct mtk_rx_dma_v2 *rxd, trxd; - int done = 0, bytes = 0; -+ dma_addr_t dma_addr = DMA_MAPPING_ERROR; - - while (done < budget) { - unsigned int pktlen, *rxdcsum; - struct net_device *netdev; -- dma_addr_t dma_addr; - u32 hash, reason; - int mac = 0; - -@@ -2168,7 +2168,8 @@ release_desc: - else - rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size); - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA) && -+ likely(dma_addr != DMA_MAPPING_ERROR)) - rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr); - - ring->calc_idx = idx; diff --git a/target/linux/generic/backport-6.1/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch b/target/linux/generic/backport-6.1/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch deleted file mode 100644 index ac3e3a3e67691a..00000000000000 --- a/target/linux/generic/backport-6.1/750-v6.5-21-net-ethernet-mtk_eth_soc-fix-pse_port-configuration-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5a124b1fd3e6cb15a943f0cdfe96aa8f6d3d2f39 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Sat, 9 Sep 2023 20:41:56 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix pse_port configuration for - MT7988 - -MT7988 SoC support 3 NICs. Fix pse_port configuration in -mtk_flow_set_output_device routine if the traffic is offloaded to eth2. -Rely on mtk_pse_port definitions. - -Fixes: 88efedf517e6 ("net: ethernet: mtk_eth_soc: enable nft hw flowtable_offload for MT7988 SoC") -Signed-off-by: Lorenzo Bianconi -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -214,9 +214,11 @@ mtk_flow_set_output_device(struct mtk_et - dsa_port = mtk_flow_get_dsa_port(&dev); - - if (dev == eth->netdev[0]) -- pse_port = 1; -+ pse_port = PSE_GDM1_PORT; - else if (dev == eth->netdev[1]) -- pse_port = 2; -+ pse_port = PSE_GDM2_PORT; -+ else if (dev == eth->netdev[2]) -+ pse_port = PSE_GDM3_PORT; - else - return -EOPNOTSUPP; - diff --git a/target/linux/generic/backport-6.1/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch b/target/linux/generic/backport-6.1/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch deleted file mode 100644 index 46da5b283fa85f..00000000000000 --- a/target/linux/generic/backport-6.1/751-01-v6.4-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch +++ /dev/null @@ -1,271 +0,0 @@ -From: Felix Fietkau -Date: Mon, 20 Mar 2023 11:44:30 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add code for offloading flows - from wlan devices - -WED version 2 (on MT7986 and later) can offload flows originating from wireless -devices. In order to make that work, ndo_setup_tc needs to be implemented on -the netdevs. This adds the required code to offload flows coming in from WED, -while keeping track of the incoming wed index used for selecting the correct -PPE device. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 + - .../net/ethernet/mediatek/mtk_ppe_offload.c | 37 ++++--- - drivers/net/ethernet/mediatek/mtk_wed.c | 101 ++++++++++++++++++ - include/linux/soc/mediatek/mtk_wed.h | 6 ++ - 4 files changed, 133 insertions(+), 14 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1435,6 +1435,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk - int mtk_eth_offload_init(struct mtk_eth *eth); - int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, - void *type_data); -+int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls, -+ int ppe_index); -+void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list); - void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev); - - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -237,7 +237,8 @@ out: - } - - static int --mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f) -+mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f, -+ int ppe_index) - { - struct flow_rule *rule = flow_cls_offload_flow_rule(f); - struct flow_action_entry *act; -@@ -454,6 +455,7 @@ mtk_flow_offload_replace(struct mtk_eth - entry->cookie = f->cookie; - memcpy(&entry->data, &foe, sizeof(entry->data)); - entry->wed_index = wed_index; -+ entry->ppe_index = ppe_index; - - err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry); - if (err < 0) -@@ -522,25 +524,15 @@ mtk_flow_offload_stats(struct mtk_eth *e - - static DEFINE_MUTEX(mtk_flow_offload_mutex); - --static int --mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) -+int mtk_flow_offload_cmd(struct mtk_eth *eth, struct flow_cls_offload *cls, -+ int ppe_index) - { -- struct flow_cls_offload *cls = type_data; -- struct net_device *dev = cb_priv; -- struct mtk_mac *mac = netdev_priv(dev); -- struct mtk_eth *eth = mac->hw; - int err; - -- if (!tc_can_offload(dev)) -- return -EOPNOTSUPP; -- -- if (type != TC_SETUP_CLSFLOWER) -- return -EOPNOTSUPP; -- - mutex_lock(&mtk_flow_offload_mutex); - switch (cls->command) { - case FLOW_CLS_REPLACE: -- err = mtk_flow_offload_replace(eth, cls); -+ err = mtk_flow_offload_replace(eth, cls, ppe_index); - break; - case FLOW_CLS_DESTROY: - err = mtk_flow_offload_destroy(eth, cls); -@@ -558,6 +550,23 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_ - } - - static int -+mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) -+{ -+ struct flow_cls_offload *cls = type_data; -+ struct net_device *dev = cb_priv; -+ struct mtk_mac *mac = netdev_priv(dev); -+ struct mtk_eth *eth = mac->hw; -+ -+ if (!tc_can_offload(dev)) -+ return -EOPNOTSUPP; -+ -+ if (type != TC_SETUP_CLSFLOWER) -+ return -EOPNOTSUPP; -+ -+ return mtk_flow_offload_cmd(eth, cls, 0); -+} -+ -+static int - mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f) - { - struct mtk_mac *mac = netdev_priv(dev); ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -13,6 +13,8 @@ - #include - #include - #include -+#include -+#include - #include "mtk_eth_soc.h" - #include "mtk_wed_regs.h" - #include "mtk_wed.h" -@@ -41,6 +43,11 @@ - static struct mtk_wed_hw *hw_list[2]; - static DEFINE_MUTEX(hw_lock); - -+struct mtk_wed_flow_block_priv { -+ struct mtk_wed_hw *hw; -+ struct net_device *dev; -+}; -+ - static void - wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) - { -@@ -1753,6 +1760,99 @@ out: - mutex_unlock(&hw_lock); - } - -+static int -+mtk_wed_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) -+{ -+ struct mtk_wed_flow_block_priv *priv = cb_priv; -+ struct flow_cls_offload *cls = type_data; -+ struct mtk_wed_hw *hw = priv->hw; -+ -+ if (!tc_can_offload(priv->dev)) -+ return -EOPNOTSUPP; -+ -+ if (type != TC_SETUP_CLSFLOWER) -+ return -EOPNOTSUPP; -+ -+ return mtk_flow_offload_cmd(hw->eth, cls, hw->index); -+} -+ -+static int -+mtk_wed_setup_tc_block(struct mtk_wed_hw *hw, struct net_device *dev, -+ struct flow_block_offload *f) -+{ -+ struct mtk_wed_flow_block_priv *priv; -+ static LIST_HEAD(block_cb_list); -+ struct flow_block_cb *block_cb; -+ struct mtk_eth *eth = hw->eth; -+ flow_setup_cb_t *cb; -+ -+ if (!eth->soc->offload_version) -+ return -EOPNOTSUPP; -+ -+ if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) -+ return -EOPNOTSUPP; -+ -+ cb = mtk_wed_setup_tc_block_cb; -+ f->driver_block_list = &block_cb_list; -+ -+ switch (f->command) { -+ case FLOW_BLOCK_BIND: -+ block_cb = flow_block_cb_lookup(f->block, cb, dev); -+ if (block_cb) { -+ flow_block_cb_incref(block_cb); -+ return 0; -+ } -+ -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->hw = hw; -+ priv->dev = dev; -+ block_cb = flow_block_cb_alloc(cb, dev, priv, NULL); -+ if (IS_ERR(block_cb)) { -+ kfree(priv); -+ return PTR_ERR(block_cb); -+ } -+ -+ flow_block_cb_incref(block_cb); -+ flow_block_cb_add(block_cb, f); -+ list_add_tail(&block_cb->driver_list, &block_cb_list); -+ return 0; -+ case FLOW_BLOCK_UNBIND: -+ block_cb = flow_block_cb_lookup(f->block, cb, dev); -+ if (!block_cb) -+ return -ENOENT; -+ -+ if (!flow_block_cb_decref(block_cb)) { -+ flow_block_cb_remove(block_cb, f); -+ list_del(&block_cb->driver_list); -+ kfree(block_cb->cb_priv); -+ } -+ return 0; -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static int -+mtk_wed_setup_tc(struct mtk_wed_device *wed, struct net_device *dev, -+ enum tc_setup_type type, void *type_data) -+{ -+ struct mtk_wed_hw *hw = wed->hw; -+ -+ if (hw->version < 2) -+ return -EOPNOTSUPP; -+ -+ switch (type) { -+ case TC_SETUP_BLOCK: -+ case TC_SETUP_FT: -+ return mtk_wed_setup_tc_block(hw, dev, type_data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ - void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, - void __iomem *wdma, phys_addr_t wdma_phy, - int index) -@@ -1772,6 +1872,7 @@ void mtk_wed_add_hw(struct device_node * - .irq_set_mask = mtk_wed_irq_set_mask, - .detach = mtk_wed_detach, - .ppe_check = mtk_wed_ppe_check, -+ .setup_tc = mtk_wed_setup_tc, - }; - struct device_node *eth_np = eth->dev->of_node; - struct platform_device *pdev; ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -6,6 +6,7 @@ - #include - #include - #include -+#include - - #define MTK_WED_TX_QUEUES 2 - #define MTK_WED_RX_QUEUES 2 -@@ -180,6 +181,8 @@ struct mtk_wed_ops { - - u32 (*irq_get)(struct mtk_wed_device *dev, u32 mask); - void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); -+ int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev, -+ enum tc_setup_type type, void *type_data); - }; - - extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; -@@ -238,6 +241,8 @@ mtk_wed_get_rx_capa(struct mtk_wed_devic - (_dev)->ops->msg_update(_dev, _id, _msg, _len) - #define mtk_wed_device_stop(_dev) (_dev)->ops->stop(_dev) - #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) -+#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \ -+ (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data) - #else - static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) - { -@@ -256,6 +261,7 @@ static inline bool mtk_wed_device_active - #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) -ENODEV - #define mtk_wed_device_stop(_dev) do {} while (0) - #define mtk_wed_device_dma_reset(_dev) do {} while (0) -+#define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP - #endif - - #endif diff --git a/target/linux/generic/backport-6.1/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch b/target/linux/generic/backport-6.1/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch deleted file mode 100644 index b1796641a33e0a..00000000000000 --- a/target/linux/generic/backport-6.1/751-02-v6.4-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Felix Fietkau -Date: Mon, 20 Mar 2023 15:37:55 +0100 -Subject: [PATCH] net: ethernet: mediatek: mtk_ppe: prefer newly added l2 - flows over existing ones - -When a device is roaming between interfaces and a new flow entry is created, -we should assume that its output device is more up to date than whatever -entry existed already. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -656,10 +656,20 @@ void mtk_foe_entry_clear(struct mtk_ppe - static int - mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -+ struct mtk_flow_entry *prev; -+ - entry->type = MTK_FLOW_TYPE_L2; - -- return rhashtable_insert_fast(&ppe->l2_flows, &entry->l2_node, -- mtk_flow_l2_ht_params); -+ prev = rhashtable_lookup_get_insert_fast(&ppe->l2_flows, &entry->l2_node, -+ mtk_flow_l2_ht_params); -+ if (likely(!prev)) -+ return 0; -+ -+ if (IS_ERR(prev)) -+ return PTR_ERR(prev); -+ -+ return rhashtable_replace_fast(&ppe->l2_flows, &prev->l2_node, -+ &entry->l2_node, mtk_flow_l2_ht_params); - } - - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) diff --git a/target/linux/generic/backport-6.1/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch b/target/linux/generic/backport-6.1/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch deleted file mode 100644 index 8b8a8e11c7fafc..00000000000000 --- a/target/linux/generic/backport-6.1/751-03-v6.4-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch +++ /dev/null @@ -1,334 +0,0 @@ -From: Felix Fietkau -Date: Thu, 23 Mar 2023 10:24:11 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: improve keeping track of - offloaded flows - -Unify tracking of L2 and L3 flows. Use the generic list field in struct -mtk_foe_entry for tracking L2 subflows. Preparation for improving -flow accounting support. - -Signed-off-by: Felix Fietkau ---- - drivers/net/ethernet/mediatek/mtk_ppe.c | 162 ++++++++++++------------ - drivers/net/ethernet/mediatek/mtk_ppe.h | 15 +-- - 2 files changed, 86 insertions(+), 91 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -476,42 +476,43 @@ int mtk_foe_entry_set_queue(struct mtk_e - return 0; - } - -+static int -+mtk_flow_entry_match_len(struct mtk_eth *eth, struct mtk_foe_entry *entry) -+{ -+ int type = mtk_get_ib1_pkt_type(eth, entry->ib1); -+ -+ if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) -+ return offsetof(struct mtk_foe_entry, ipv6._rsv); -+ else -+ return offsetof(struct mtk_foe_entry, ipv4.ib2); -+} -+ - static bool - mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry, -- struct mtk_foe_entry *data) -+ struct mtk_foe_entry *data, int len) - { -- int type, len; -- - if ((data->ib1 ^ entry->data.ib1) & MTK_FOE_IB1_UDP) - return false; - -- type = mtk_get_ib1_pkt_type(eth, entry->data.ib1); -- if (type > MTK_PPE_PKT_TYPE_IPV4_DSLITE) -- len = offsetof(struct mtk_foe_entry, ipv6._rsv); -- else -- len = offsetof(struct mtk_foe_entry, ipv4.ib2); -- - return !memcmp(&entry->data.data, &data->data, len - 4); - } - - static void --__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+__mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ bool set_state) - { -- struct hlist_head *head; - struct hlist_node *tmp; - - if (entry->type == MTK_FLOW_TYPE_L2) { - rhashtable_remove_fast(&ppe->l2_flows, &entry->l2_node, - mtk_flow_l2_ht_params); - -- head = &entry->l2_flows; -- hlist_for_each_entry_safe(entry, tmp, head, l2_data.list) -- __mtk_foe_entry_clear(ppe, entry); -+ hlist_for_each_entry_safe(entry, tmp, &entry->l2_flows, l2_list) -+ __mtk_foe_entry_clear(ppe, entry, set_state); - return; - } - -- hlist_del_init(&entry->list); -- if (entry->hash != 0xffff) { -+ if (entry->hash != 0xffff && set_state) { - struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash); - - hwe->ib1 &= ~MTK_FOE_IB1_STATE; -@@ -531,7 +532,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW) - return; - -- hlist_del_init(&entry->l2_data.list); -+ hlist_del_init(&entry->l2_list); -+ hlist_del_init(&entry->list); - kfree(entry); - } - -@@ -547,66 +549,55 @@ static int __mtk_foe_entry_idle_time(str - return now - timestamp; - } - -+static bool -+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+{ -+ struct mtk_foe_entry foe = {}; -+ struct mtk_foe_entry *hwe; -+ u16 hash = entry->hash; -+ int len; -+ -+ if (hash == 0xffff) -+ return false; -+ -+ hwe = mtk_foe_get_entry(ppe, hash); -+ len = mtk_flow_entry_match_len(ppe->eth, &entry->data); -+ memcpy(&foe, hwe, len); -+ -+ if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || -+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) -+ return false; -+ -+ entry->data.ib1 = foe.ib1; -+ -+ return true; -+} -+ - static void - mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); - struct mtk_flow_entry *cur; -- struct mtk_foe_entry *hwe; - struct hlist_node *tmp; - int idle; - - idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -- hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_data.list) { -+ hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { - int cur_idle; -- u32 ib1; -- -- hwe = mtk_foe_get_entry(ppe, cur->hash); -- ib1 = READ_ONCE(hwe->ib1); - -- if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) { -- cur->hash = 0xffff; -- __mtk_foe_entry_clear(ppe, cur); -+ if (!mtk_flow_entry_update(ppe, cur)) { -+ __mtk_foe_entry_clear(ppe, entry, false); - continue; - } - -- cur_idle = __mtk_foe_entry_idle_time(ppe, ib1); -+ cur_idle = __mtk_foe_entry_idle_time(ppe, cur->data.ib1); - if (cur_idle >= idle) - continue; - - idle = cur_idle; - entry->data.ib1 &= ~ib1_ts_mask; -- entry->data.ib1 |= hwe->ib1 & ib1_ts_mask; -- } --} -- --static void --mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) --{ -- struct mtk_foe_entry foe = {}; -- struct mtk_foe_entry *hwe; -- -- spin_lock_bh(&ppe_lock); -- -- if (entry->type == MTK_FLOW_TYPE_L2) { -- mtk_flow_entry_update_l2(ppe, entry); -- goto out; -+ entry->data.ib1 |= cur->data.ib1 & ib1_ts_mask; - } -- -- if (entry->hash == 0xffff) -- goto out; -- -- hwe = mtk_foe_get_entry(ppe, entry->hash); -- memcpy(&foe, hwe, ppe->eth->soc->foe_entry_size); -- if (!mtk_flow_entry_match(ppe->eth, entry, &foe)) { -- entry->hash = 0xffff; -- goto out; -- } -- -- entry->data.ib1 = foe.ib1; -- --out: -- spin_unlock_bh(&ppe_lock); - } - - static void -@@ -649,7 +640,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - spin_lock_bh(&ppe_lock); -- __mtk_foe_entry_clear(ppe, entry); -+ __mtk_foe_entry_clear(ppe, entry, true); -+ hlist_del_init(&entry->list); - spin_unlock_bh(&ppe_lock); - } - -@@ -696,8 +688,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ - { - const struct mtk_soc_data *soc = ppe->eth->soc; - struct mtk_flow_entry *flow_info; -- struct mtk_foe_entry foe = {}, *hwe; - struct mtk_foe_mac_info *l2; -+ struct mtk_foe_entry *hwe; - u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; - int type; - -@@ -705,30 +697,30 @@ mtk_foe_entry_commit_subflow(struct mtk_ - if (!flow_info) - return; - -- flow_info->l2_data.base_flow = entry; - flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW; - flow_info->hash = hash; - hlist_add_head(&flow_info->list, - &ppe->foe_flow[hash / soc->hash_offset]); -- hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows); -+ hlist_add_head(&flow_info->l2_list, &entry->l2_flows); - - hwe = mtk_foe_get_entry(ppe, hash); -- memcpy(&foe, hwe, soc->foe_entry_size); -- foe.ib1 &= ib1_mask; -- foe.ib1 |= entry->data.ib1 & ~ib1_mask; -+ memcpy(&flow_info->data, hwe, soc->foe_entry_size); -+ flow_info->data.ib1 &= ib1_mask; -+ flow_info->data.ib1 |= entry->data.ib1 & ~ib1_mask; - -- l2 = mtk_foe_entry_l2(ppe->eth, &foe); -+ l2 = mtk_foe_entry_l2(ppe->eth, &flow_info->data); - memcpy(l2, &entry->data.bridge.l2, sizeof(*l2)); - -- type = mtk_get_ib1_pkt_type(ppe->eth, foe.ib1); -+ type = mtk_get_ib1_pkt_type(ppe->eth, flow_info->data.ib1); - if (type == MTK_PPE_PKT_TYPE_IPV4_HNAPT) -- memcpy(&foe.ipv4.new, &foe.ipv4.orig, sizeof(foe.ipv4.new)); -+ memcpy(&flow_info->data.ipv4.new, &flow_info->data.ipv4.orig, -+ sizeof(flow_info->data.ipv4.new)); - else if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T && l2->etype == ETH_P_IP) - l2->etype = ETH_P_IPV6; - -- *mtk_foe_entry_ib2(ppe->eth, &foe) = entry->data.bridge.ib2; -+ *mtk_foe_entry_ib2(ppe->eth, &flow_info->data) = entry->data.bridge.ib2; - -- __mtk_foe_entry_commit(ppe, &foe, hash); -+ __mtk_foe_entry_commit(ppe, &flow_info->data, hash); - } - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash) -@@ -738,9 +730,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe - struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash); - struct mtk_flow_entry *entry; - struct mtk_foe_bridge key = {}; -+ struct mtk_foe_entry foe = {}; - struct hlist_node *n; - struct ethhdr *eh; - bool found = false; -+ int entry_len; - u8 *tag; - - spin_lock_bh(&ppe_lock); -@@ -748,20 +742,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe - if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND) - goto out; - -- hlist_for_each_entry_safe(entry, n, head, list) { -- if (entry->type == MTK_FLOW_TYPE_L2_SUBFLOW) { -- if (unlikely(FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == -- MTK_FOE_STATE_BIND)) -- continue; -- -- entry->hash = 0xffff; -- __mtk_foe_entry_clear(ppe, entry); -- continue; -- } -+ entry_len = mtk_flow_entry_match_len(ppe->eth, hwe); -+ memcpy(&foe, hwe, entry_len); - -- if (found || !mtk_flow_entry_match(ppe->eth, entry, hwe)) { -+ hlist_for_each_entry_safe(entry, n, head, list) { -+ if (found || -+ !mtk_flow_entry_match(ppe->eth, entry, &foe, entry_len)) { - if (entry->hash != 0xffff) -- entry->hash = 0xffff; -+ __mtk_foe_entry_clear(ppe, entry, false); - continue; - } - -@@ -810,9 +798,17 @@ out: - - int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { -- mtk_flow_entry_update(ppe, entry); -+ int idle; -+ -+ spin_lock_bh(&ppe_lock); -+ if (entry->type == MTK_FLOW_TYPE_L2) -+ mtk_flow_entry_update_l2(ppe, entry); -+ else -+ mtk_flow_entry_update(ppe, entry); -+ idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ spin_unlock_bh(&ppe_lock); - -- return __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ return idle; - } - - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -286,7 +286,12 @@ enum { - - struct mtk_flow_entry { - union { -- struct hlist_node list; -+ /* regular flows + L2 subflows */ -+ struct { -+ struct hlist_node list; -+ struct hlist_node l2_list; -+ }; -+ /* L2 flows */ - struct { - struct rhash_head l2_node; - struct hlist_head l2_flows; -@@ -296,13 +301,7 @@ struct mtk_flow_entry { - s8 wed_index; - u8 ppe_index; - u16 hash; -- union { -- struct mtk_foe_entry data; -- struct { -- struct mtk_flow_entry *base_flow; -- struct hlist_node list; -- } l2_data; -- }; -+ struct mtk_foe_entry data; - struct rhash_head node; - unsigned long cookie; - }; diff --git a/target/linux/generic/backport-6.1/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch b/target/linux/generic/backport-6.1/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch deleted file mode 100644 index e20f94f1d4e5c8..00000000000000 --- a/target/linux/generic/backport-6.1/751-04-v6.4-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch +++ /dev/null @@ -1,342 +0,0 @@ -From: Felix Fietkau -Date: Thu, 23 Mar 2023 11:05:22 +0100 -Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for L2 - flows - -For L2 flows, the packet/byte counters should report the sum of the -counters of their subflows, both current and expired. -In order to make this work, change the way that accounting data is tracked. -Reset counters when a flow enters bind. Once it expires (or enters unbind), -store the last counter value in struct mtk_flow_entry. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -79,9 +79,9 @@ static int mtk_ppe_mib_wait_busy(struct - int ret; - u32 val; - -- ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val, -- !(val & MTK_PPE_MIB_SER_CR_ST), -- 20, MTK_PPE_WAIT_TIMEOUT_US); -+ ret = readl_poll_timeout_atomic(ppe->base + MTK_PPE_MIB_SER_CR, val, -+ !(val & MTK_PPE_MIB_SER_CR_ST), -+ 20, MTK_PPE_WAIT_TIMEOUT_US); - - if (ret) - dev_err(ppe->dev, "MIB table busy"); -@@ -89,17 +89,31 @@ static int mtk_ppe_mib_wait_busy(struct - return ret; - } - --static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets) -+static inline struct mtk_foe_accounting * -+mtk_ppe_acct_data(struct mtk_ppe *ppe, u16 index) -+{ -+ if (!ppe->acct_table) -+ return NULL; -+ -+ return ppe->acct_table + index * sizeof(struct mtk_foe_accounting); -+} -+ -+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index) - { - u32 val, cnt_r0, cnt_r1, cnt_r2; -+ struct mtk_foe_accounting *acct; - int ret; - - val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST; - ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val); - -+ acct = mtk_ppe_acct_data(ppe, index); -+ if (!acct) -+ return NULL; -+ - ret = mtk_ppe_mib_wait_busy(ppe); - if (ret) -- return ret; -+ return acct; - - cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0); - cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1); -@@ -108,19 +122,19 @@ static int mtk_mib_entry_read(struct mtk - if (mtk_is_netsys_v3_or_greater(ppe->eth)) { - /* 64 bit for each counter */ - u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3); -- *bytes = ((u64)cnt_r1 << 32) | cnt_r0; -- *packets = ((u64)cnt_r3 << 32) | cnt_r2; -+ acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0; -+ acct->packets += ((u64)cnt_r3 << 32) | cnt_r2; - } else { - /* 48 bit byte counter, 40 bit packet counter */ - u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0); - u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1); - u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1); - u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2); -- *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low; -- *packets = (pkt_cnt_high << 16) | pkt_cnt_low; -+ acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low; -+ acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low; - } - -- return 0; -+ return acct; - } - - static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) -@@ -519,13 +533,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp - hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID); - dma_wmb(); - mtk_ppe_cache_clear(ppe); -- if (ppe->accounting) { -- struct mtk_foe_accounting *acct; -- -- acct = ppe->acct_table + entry->hash * sizeof(*acct); -- acct->packets = 0; -- acct->bytes = 0; -- } - } - entry->hash = 0xffff; - -@@ -550,11 +557,14 @@ static int __mtk_foe_entry_idle_time(str - } - - static bool --mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) -+mtk_flow_entry_update(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ u64 *packets, u64 *bytes) - { -+ struct mtk_foe_accounting *acct; - struct mtk_foe_entry foe = {}; - struct mtk_foe_entry *hwe; - u16 hash = entry->hash; -+ bool ret = false; - int len; - - if (hash == 0xffff) -@@ -565,18 +575,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp - memcpy(&foe, hwe, len); - - if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) || -- FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) -- return false; -+ FIELD_GET(MTK_FOE_IB1_STATE, foe.ib1) != MTK_FOE_STATE_BIND) { -+ acct = mtk_ppe_acct_data(ppe, hash); -+ if (acct) { -+ entry->prev_packets += acct->packets; -+ entry->prev_bytes += acct->bytes; -+ } -+ -+ goto out; -+ } - - entry->data.ib1 = foe.ib1; -+ acct = mtk_ppe_mib_entry_read(ppe, hash); -+ ret = true; -+ -+out: -+ if (acct) { -+ *packets += acct->packets; -+ *bytes += acct->bytes; -+ } - -- return true; -+ return ret; - } - - static void - mtk_flow_entry_update_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) - { - u32 ib1_ts_mask = mtk_get_ib1_ts_mask(ppe->eth); -+ u64 *packets = &entry->packets; -+ u64 *bytes = &entry->bytes; - struct mtk_flow_entry *cur; - struct hlist_node *tmp; - int idle; -@@ -585,7 +612,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe - hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) { - int cur_idle; - -- if (!mtk_flow_entry_update(ppe, cur)) { -+ if (!mtk_flow_entry_update(ppe, cur, packets, bytes)) { -+ entry->prev_packets += cur->prev_packets; -+ entry->prev_bytes += cur->prev_bytes; - __mtk_foe_entry_clear(ppe, entry, false); - continue; - } -@@ -600,10 +629,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe - } - } - -+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ int *idle) -+{ -+ entry->packets = entry->prev_packets; -+ entry->bytes = entry->prev_bytes; -+ -+ spin_lock_bh(&ppe_lock); -+ -+ if (entry->type == MTK_FLOW_TYPE_L2) -+ mtk_flow_entry_update_l2(ppe, entry); -+ else -+ mtk_flow_entry_update(ppe, entry, &entry->packets, &entry->bytes); -+ -+ *idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -+ -+ spin_unlock_bh(&ppe_lock); -+} -+ - static void - __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, - u16 hash) - { -+ struct mtk_foe_accounting *acct; - struct mtk_eth *eth = ppe->eth; - u16 timestamp = mtk_eth_timestamp(eth); - struct mtk_foe_entry *hwe; -@@ -634,6 +682,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p - - dma_wmb(); - -+ acct = mtk_ppe_mib_entry_read(ppe, hash); -+ if (acct) { -+ acct->packets = 0; -+ acct->bytes = 0; -+ } -+ - mtk_ppe_cache_clear(ppe); - } - -@@ -796,21 +850,6 @@ out: - spin_unlock_bh(&ppe_lock); - } - --int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry) --{ -- int idle; -- -- spin_lock_bh(&ppe_lock); -- if (entry->type == MTK_FLOW_TYPE_L2) -- mtk_flow_entry_update_l2(ppe, entry); -- else -- mtk_flow_entry_update(ppe, entry); -- idle = __mtk_foe_entry_idle_time(ppe, entry->data.ib1); -- spin_unlock_bh(&ppe_lock); -- -- return idle; --} -- - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe) - { - if (!ppe) -@@ -838,32 +877,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe - return mtk_ppe_wait_busy(ppe); - } - --struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -- struct mtk_foe_accounting *diff) --{ -- struct mtk_foe_accounting *acct; -- int size = sizeof(struct mtk_foe_accounting); -- u64 bytes, packets; -- -- if (!ppe->accounting) -- return NULL; -- -- if (mtk_mib_entry_read(ppe, index, &bytes, &packets)) -- return NULL; -- -- acct = ppe->acct_table + index * size; -- -- acct->bytes += bytes; -- acct->packets += packets; -- -- if (diff) { -- diff->bytes = bytes; -- diff->packets = packets; -- } -- -- return acct; --} -- - struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index) - { - bool accounting = eth->soc->has_accounting; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -304,6 +304,8 @@ struct mtk_flow_entry { - struct mtk_foe_entry data; - struct rhash_head node; - unsigned long cookie; -+ u64 prev_packets, prev_bytes; -+ u64 packets, bytes; - }; - - struct mtk_mib_entry { -@@ -348,6 +350,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth) - void mtk_ppe_start(struct mtk_ppe *ppe); - int mtk_ppe_stop(struct mtk_ppe *ppe); - int mtk_ppe_prepare_reset(struct mtk_ppe *ppe); -+struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index); - - void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash); - -@@ -396,9 +399,8 @@ int mtk_foe_entry_set_queue(struct mtk_e - unsigned int queue); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); --int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); - int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index); --struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index, -- struct mtk_foe_accounting *diff); -+void mtk_foe_entry_get_stats(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, -+ int *idle); - - #endif ---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c -@@ -96,7 +96,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file - if (bind && state != MTK_FOE_STATE_BIND) - continue; - -- acct = mtk_foe_entry_get_mib(ppe, i, NULL); -+ acct = mtk_ppe_mib_entry_read(ppe, i); - - type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); - seq_printf(m, "%05x %s %7s", i, ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -501,24 +501,21 @@ static int - mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) - { - struct mtk_flow_entry *entry; -- struct mtk_foe_accounting diff; -- u32 idle; -+ u64 packets, bytes; -+ int idle; - - entry = rhashtable_lookup(ð->flow_table, &f->cookie, - mtk_flow_ht_params); - if (!entry) - return -ENOENT; - -- idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry); -+ packets = entry->packets; -+ bytes = entry->bytes; -+ mtk_foe_entry_get_stats(eth->ppe[entry->ppe_index], entry, &idle); -+ f->stats.pkts += entry->packets - packets; -+ f->stats.bytes += entry->bytes - bytes; - f->stats.lastused = jiffies - idle * HZ; - -- if (entry->hash != 0xFFFF && -- mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash, -- &diff)) { -- f->stats.pkts += diff.packets; -- f->stats.bytes += diff.bytes; -- } -- - return 0; - } - diff --git a/target/linux/generic/backport-6.1/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch b/target/linux/generic/backport-6.1/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch deleted file mode 100644 index a224b626243c9c..00000000000000 --- a/target/linux/generic/backport-6.1/752-01-v6.6-net-ethernet-mtk_wed-add-some-more-info-in-wed_txinf.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Lorenzo Bianconi -Date: Sun, 27 Aug 2023 19:31:41 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: add some more info in wed_txinfo_show - handler - -Add some new info in Wireless Ethernet Dispatcher wed_txinfo_show -debugfs handler useful during debugging. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/3390292655d568180b73d2a25576f61aa63310e5.1693157377.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -127,8 +127,17 @@ wed_txinfo_show(struct seq_file *s, void - DUMP_WDMA_RING(WDMA_RING_RX(0)), - DUMP_WDMA_RING(WDMA_RING_RX(1)), - -- DUMP_STR("TX FREE"), -+ DUMP_STR("WED TX FREE"), - DUMP_WED(WED_RX_MIB(0)), -+ DUMP_WED_RING(WED_RING_RX(0)), -+ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(0)), -+ DUMP_WED(WED_RX_MIB(1)), -+ DUMP_WED_RING(WED_RING_RX(1)), -+ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(1)), -+ -+ DUMP_STR("WED WPDMA TX FREE"), -+ DUMP_WED_RING(WED_WPDMA_RING_RX(0)), -+ DUMP_WED_RING(WED_WPDMA_RING_RX(1)), - }; - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -266,6 +266,8 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_TX_MIB(_n) (0x5a0 + (_n) * 4) - #define MTK_WED_WPDMA_TX_COHERENT_MIB(_n) (0x5d0 + (_n) * 4) -+#define MTK_WED_WPDMA_RX_MIB(_n) (0x5e0 + (_n) * 4) -+#define MTK_WED_WPDMA_RX_COHERENT_MIB(_n) (0x5f0 + (_n) * 4) - - #define MTK_WED_WPDMA_RING_TX(_n) (0x600 + (_n) * 0x10) - #define MTK_WED_WPDMA_RING_RX(_n) (0x700 + (_n) * 0x10) diff --git a/target/linux/generic/backport-6.1/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch b/target/linux/generic/backport-6.1/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch deleted file mode 100644 index df6edfdf94333f..00000000000000 --- a/target/linux/generic/backport-6.1/752-02-v6.6-net-ethernet-mtk_wed-minor-change-in-wed_-tx-rx-info.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Lorenzo Bianconi -Date: Sun, 27 Aug 2023 19:33:47 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: minor change in wed_{tx,rx}info_show - -No functional changes, just cosmetic ones. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/71e046c72a978745f0435af265dda610aa9bfbcf.1693157578.git.lorenzo@kernel.org -Signed-off-by: Jakub Kicinski ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -84,7 +84,6 @@ dump_wed_regs(struct seq_file *s, struct - } - } - -- - static int - wed_txinfo_show(struct seq_file *s, void *data) - { -@@ -142,10 +141,8 @@ wed_txinfo_show(struct seq_file *s, void - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; - -- if (!dev) -- return 0; -- -- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ if (dev) -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); - - return 0; - } -@@ -217,10 +214,8 @@ wed_rxinfo_show(struct seq_file *s, void - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; - -- if (!dev) -- return 0; -- -- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ if (dev) -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); - - return 0; - } diff --git a/target/linux/generic/backport-6.1/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch b/target/linux/generic/backport-6.1/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch deleted file mode 100644 index 0bf9dea24f0a16..00000000000000 --- a/target/linux/generic/backport-6.1/752-03-v6.6-net-ethernet-mtk_eth_soc-rely-on-mtk_pse_port-defini.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Lorenzo Bianconi -Date: Tue, 12 Sep 2023 10:22:56 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: rely on mtk_pse_port definitions - in mtk_flow_set_output_device - -Similar to ethernet ports, rely on mtk_pse_port definitions for -pse wdma ports as well. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://lore.kernel.org/r/b86bdb717e963e3246c1dec5f736c810703cf056.1694506814.git.lorenzo@kernel.org -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -196,10 +196,10 @@ mtk_flow_set_output_device(struct mtk_et - if (mtk_is_netsys_v2_or_greater(eth)) { - switch (info.wdma_idx) { - case 0: -- pse_port = 8; -+ pse_port = PSE_WDMA0_PORT; - break; - case 1: -- pse_port = 9; -+ pse_port = PSE_WDMA1_PORT; - break; - default: - return -EINVAL; diff --git a/target/linux/generic/backport-6.1/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch b/target/linux/generic/backport-6.1/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch deleted file mode 100644 index c99e1334d41e00..00000000000000 --- a/target/linux/generic/backport-6.1/752-04-v6.6-net-ethernet-mtk_wed-check-update_wo_rx_stats-in-mtk.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Lorenzo Bianconi -Date: Tue, 12 Sep 2023 10:28:00 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: check update_wo_rx_stats in - mtk_wed_update_rx_stats() - -Check if update_wo_rx_stats function pointer is properly set in -mtk_wed_update_rx_stats routine before accessing it. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Link: https://lore.kernel.org/r/b0d233386e059bccb59f18f69afb79a7806e5ded.1694507226.git.lorenzo@kernel.org -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -68,6 +68,9 @@ mtk_wed_update_rx_stats(struct mtk_wed_d - struct mtk_wed_wo_rx_stats *stats; - int i; - -+ if (!wed->wlan.update_wo_rx_stats) -+ return; -+ - if (count * sizeof(*stats) > skb->len - sizeof(u32)) - return; - diff --git a/target/linux/generic/backport-6.1/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch b/target/linux/generic/backport-6.1/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch deleted file mode 100644 index cd7fb92e2090f5..00000000000000 --- a/target/linux/generic/backport-6.1/752-05-v6.7-net-ethernet-mtk_wed-do-not-assume-offload-callbacks.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Lorenzo Bianconi -Date: Wed, 13 Sep 2023 20:42:47 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: do not assume offload callbacks are - always set - -Check if wlan.offload_enable and wlan.offload_disable callbacks are set -in mtk_wed_flow_add/mtk_wed_flow_remove since mt7996 will not rely -on them. - -Signed-off-by: Lorenzo Bianconi -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -1712,19 +1712,20 @@ mtk_wed_irq_set_mask(struct mtk_wed_devi - int mtk_wed_flow_add(int index) - { - struct mtk_wed_hw *hw = hw_list[index]; -- int ret; -+ int ret = 0; - -- if (!hw || !hw->wed_dev) -- return -ENODEV; -+ mutex_lock(&hw_lock); - -- if (hw->num_flows) { -- hw->num_flows++; -- return 0; -+ if (!hw || !hw->wed_dev) { -+ ret = -ENODEV; -+ goto out; - } - -- mutex_lock(&hw_lock); -- if (!hw->wed_dev) { -- ret = -ENODEV; -+ if (!hw->wed_dev->wlan.offload_enable) -+ goto out; -+ -+ if (hw->num_flows) { -+ hw->num_flows++; - goto out; - } - -@@ -1743,14 +1744,15 @@ void mtk_wed_flow_remove(int index) - { - struct mtk_wed_hw *hw = hw_list[index]; - -- if (!hw) -- return; -+ mutex_lock(&hw_lock); - -- if (--hw->num_flows) -- return; -+ if (!hw || !hw->wed_dev) -+ goto out; - -- mutex_lock(&hw_lock); -- if (!hw->wed_dev) -+ if (!hw->wed_dev->wlan.offload_disable) -+ goto out; -+ -+ if (--hw->num_flows) - goto out; - - hw->wed_dev->wlan.offload_disable(hw->wed_dev); diff --git a/target/linux/generic/backport-6.1/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch b/target/linux/generic/backport-6.1/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch deleted file mode 100644 index 29481886503363..00000000000000 --- a/target/linux/generic/backport-6.1/752-06-v6.7-net-ethernet-mtk_wed-introduce-versioning-utility-ro.patch +++ /dev/null @@ -1,232 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:05 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: introduce versioning utility routines - -Similar to mtk_eth_soc, introduce the following wed versioning -utility routines: -- mtk_wed_is_v1 -- mtk_wed_is_v2 - -This is a preliminary patch to introduce WED support for MT7988 SoC - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -277,7 +277,7 @@ mtk_wed_assign(struct mtk_wed_device *de - if (!hw->wed_dev) - goto out; - -- if (hw->version == 1) -+ if (mtk_wed_is_v1(hw)) - return NULL; - - /* MT7986 WED devices do not have any pcie slot restrictions */ -@@ -358,7 +358,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d - desc->buf0 = cpu_to_le32(buf_phys); - desc->buf1 = cpu_to_le32(buf_phys + txd_size); - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | - FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, - MTK_WED_BUF_SIZE - txd_size) | -@@ -497,7 +497,7 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - { - u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; - else - mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -@@ -576,7 +576,7 @@ mtk_wed_dma_disable(struct mtk_wed_devic - MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | - MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - regmap_write(dev->hw->mirror, dev->hw->index * 4, 0); - wdma_clr(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -@@ -605,7 +605,7 @@ mtk_wed_stop(struct mtk_wed_device *dev) - wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - return; - - wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); -@@ -624,7 +624,7 @@ mtk_wed_deinit(struct mtk_wed_device *de - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - return; - - wed_clr(dev, MTK_WED_CTRL, -@@ -730,7 +730,7 @@ mtk_wed_bus_init(struct mtk_wed_device * - static void - mtk_wed_set_wpdma(struct mtk_wed_device *dev) - { -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); - } else { - mtk_wed_bus_init(dev); -@@ -761,7 +761,7 @@ mtk_wed_hw_init_early(struct mtk_wed_dev - MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; - wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - u32 offset = dev->hw->index ? 0x04000400 : 0; - - wdma_set(dev, MTK_WDMA_GLO_CFG, -@@ -934,7 +934,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - wed_w32(dev, MTK_WED_TX_BM_TKID, - FIELD_PREP(MTK_WED_TX_BM_TKID_START, - dev->wlan.token_start) | -@@ -967,7 +967,7 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - wed_set(dev, MTK_WED_CTRL, - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -@@ -1217,7 +1217,7 @@ mtk_wed_reset_dma(struct mtk_wed_device - } - - dev->init_done = false; -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - return; - - if (!busy) { -@@ -1343,7 +1343,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, - MTK_WED_PCIE_INT_TRIGGER_STATUS); - -@@ -1416,7 +1416,7 @@ mtk_wed_dma_enable(struct mtk_wed_device - MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | - MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - wdma_set(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); - } else { -@@ -1465,7 +1465,7 @@ mtk_wed_start(struct mtk_wed_device *dev - - mtk_wed_set_ext_int(dev, true); - -- if (dev->hw->version == 1) { -+ if (mtk_wed_is_v1(dev->hw)) { - u32 val = dev->wlan.wpdma_phys | MTK_PCIE_MIRROR_MAP_EN | - FIELD_PREP(MTK_PCIE_MIRROR_MAP_WED_ID, - dev->hw->index); -@@ -1550,7 +1550,7 @@ mtk_wed_attach(struct mtk_wed_device *de - } - - mtk_wed_hw_init_early(dev); -- if (hw->version == 1) { -+ if (mtk_wed_is_v1(hw)) { - regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, - BIT(hw->index), 0); - } else { -@@ -1618,7 +1618,7 @@ static int - mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs) - { - struct mtk_wed_ring *ring = &dev->txfree_ring; -- int i, index = dev->hw->version == 1; -+ int i, index = mtk_wed_is_v1(dev->hw); - - /* - * For txfree event handling, the same DMA ring is shared between WED -@@ -1676,7 +1676,7 @@ mtk_wed_irq_get(struct mtk_wed_device *d - { - u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; - else - ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -@@ -1843,7 +1843,7 @@ mtk_wed_setup_tc(struct mtk_wed_device * - { - struct mtk_wed_hw *hw = wed->hw; - -- if (hw->version < 2) -+ if (mtk_wed_is_v1(hw)) - return -EOPNOTSUPP; - - switch (type) { -@@ -1917,9 +1917,9 @@ void mtk_wed_add_hw(struct device_node * - hw->wdma = wdma; - hw->index = index; - hw->irq = irq; -- hw->version = mtk_is_netsys_v1(eth) ? 1 : 2; -+ hw->version = eth->soc->version; - -- if (hw->version == 1) { -+ if (mtk_wed_is_v1(hw)) { - hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, - "mediatek,pcie-mirror"); - hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -40,6 +40,16 @@ struct mtk_wdma_info { - }; - - #ifdef CONFIG_NET_MEDIATEK_SOC_WED -+static inline bool mtk_wed_is_v1(struct mtk_wed_hw *hw) -+{ -+ return hw->version == 1; -+} -+ -+static inline bool mtk_wed_is_v2(struct mtk_wed_hw *hw) -+{ -+ return hw->version == 2; -+} -+ - static inline void - wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val) - { ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -263,7 +263,7 @@ void mtk_wed_hw_add_debugfs(struct mtk_w - debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg); - debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval); - debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops); -- if (hw->version != 1) -+ if (!mtk_wed_is_v1(hw)) - debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, - &wed_rxinfo_fops); - } ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -207,7 +207,7 @@ int mtk_wed_mcu_msg_update(struct mtk_we - { - struct mtk_wed_wo *wo = dev->hw->wed_wo; - -- if (dev->hw->version == 1) -+ if (mtk_wed_is_v1(dev->hw)) - return 0; - - if (WARN_ON(!wo)) diff --git a/target/linux/generic/backport-6.1/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch b/target/linux/generic/backport-6.1/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch deleted file mode 100644 index bc34aa33a9f2a0..00000000000000 --- a/target/linux/generic/backport-6.1/752-07-v6.7-net-ethernet-mtk_wed-do-not-configure-rx-offload-if-.patch +++ /dev/null @@ -1,234 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:06 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: do not configure rx offload if not - supported - -Check if rx offload is supported running mtk_wed_get_rx_capa routine -before configuring it. This is a preliminary patch to introduce Wireless -Ethernet Dispatcher (WED) support for MT7988 SoC. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -605,7 +605,7 @@ mtk_wed_stop(struct mtk_wed_device *dev) - wdma_w32(dev, MTK_WDMA_INT_GRP2, 0); - wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0); - -- if (mtk_wed_is_v1(dev->hw)) -+ if (!mtk_wed_get_rx_capa(dev)) - return; - - wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0); -@@ -732,16 +732,21 @@ mtk_wed_set_wpdma(struct mtk_wed_device - { - if (mtk_wed_is_v1(dev->hw)) { - wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); -- } else { -- mtk_wed_bus_init(dev); -- -- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); -- wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); -- wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); -- wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); -- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); -- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx); -+ return; - } -+ -+ mtk_wed_bus_init(dev); -+ -+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx); -+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree); -+ -+ if (!mtk_wed_get_rx_capa(dev)) -+ return; -+ -+ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); -+ wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx); - } - - static void -@@ -973,15 +978,17 @@ mtk_wed_hw_init(struct mtk_wed_device *d - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - } else { - wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); -- /* rx hw init */ -- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -- MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -- MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -- -- mtk_wed_rx_buffer_hw_init(dev); -- mtk_wed_rro_hw_init(dev); -- mtk_wed_route_qm_hw_init(dev); -+ if (mtk_wed_get_rx_capa(dev)) { -+ /* rx hw init */ -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -+ -+ mtk_wed_rx_buffer_hw_init(dev); -+ mtk_wed_rro_hw_init(dev); -+ mtk_wed_route_qm_hw_init(dev); -+ } - } - - wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); -@@ -1353,8 +1360,6 @@ mtk_wed_configure_irq(struct mtk_wed_dev - - wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); - } else { -- wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE, -- GENMASK(1, 0)); - /* initail tx interrupt trigger */ - wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, - MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | -@@ -1373,15 +1378,20 @@ mtk_wed_configure_irq(struct mtk_wed_dev - FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG, - dev->wlan.txfree_tbit)); - -- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX, -- MTK_WED_WPDMA_INT_CTRL_RX0_EN | -- MTK_WED_WPDMA_INT_CTRL_RX0_CLR | -- MTK_WED_WPDMA_INT_CTRL_RX1_EN | -- MTK_WED_WPDMA_INT_CTRL_RX1_CLR | -- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG, -- dev->wlan.rx_tbit[0]) | -- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG, -- dev->wlan.rx_tbit[1])); -+ if (mtk_wed_get_rx_capa(dev)) { -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX, -+ MTK_WED_WPDMA_INT_CTRL_RX0_EN | -+ MTK_WED_WPDMA_INT_CTRL_RX0_CLR | -+ MTK_WED_WPDMA_INT_CTRL_RX1_EN | -+ MTK_WED_WPDMA_INT_CTRL_RX1_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG, -+ dev->wlan.rx_tbit[0]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG, -+ dev->wlan.rx_tbit[1])); -+ -+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE, -+ GENMASK(1, 0)); -+ } - - wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask); - wed_set(dev, MTK_WED_WDMA_INT_CTRL, -@@ -1400,6 +1410,8 @@ mtk_wed_configure_irq(struct mtk_wed_dev - static void - mtk_wed_dma_enable(struct mtk_wed_device *dev) - { -+ int i; -+ - wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); - - wed_set(dev, MTK_WED_GLO_CFG, -@@ -1419,33 +1431,33 @@ mtk_wed_dma_enable(struct mtk_wed_device - if (mtk_wed_is_v1(dev->hw)) { - wdma_set(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); -- } else { -- int i; -+ return; -+ } - -- wed_set(dev, MTK_WED_WPDMA_CTRL, -- MTK_WED_WPDMA_CTRL_SDL1_FIXED); -+ wed_set(dev, MTK_WED_WPDMA_CTRL, -+ MTK_WED_WPDMA_CTRL_SDL1_FIXED); -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | -+ MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); - -- wed_set(dev, MTK_WED_WDMA_GLO_CFG, -- MTK_WED_WDMA_GLO_CFG_TX_DRV_EN | -- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); -+ if (!mtk_wed_get_rx_capa(dev)) -+ return; - -- wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | -- MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -- -- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -- MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | -- MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); -+ wed_set(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); - -- wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -- MTK_WED_WPDMA_RX_D_RX_DRV_EN | -- FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) | -- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, -- 0x2)); -+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, -+ MTK_WED_WPDMA_RX_D_RX_DRV_EN | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, -+ 0x2)); - -- for (i = 0; i < MTK_WED_RX_QUEUES; i++) -- mtk_wed_check_wfdma_rx_fill(dev, i); -- } -+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) -+ mtk_wed_check_wfdma_rx_fill(dev, i); - } - - static void -@@ -1472,7 +1484,7 @@ mtk_wed_start(struct mtk_wed_device *dev - - val |= BIT(0) | (BIT(1) * !!dev->hw->index); - regmap_write(dev->hw->mirror, dev->hw->index * 4, val); -- } else { -+ } else if (mtk_wed_get_rx_capa(dev)) { - /* driver set mid ready and only once */ - wed_w32(dev, MTK_WED_EXT_INT_MASK1, - MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); -@@ -1484,7 +1496,6 @@ mtk_wed_start(struct mtk_wed_device *dev - - if (mtk_wed_rro_cfg(dev)) - return; -- - } - - mtk_wed_set_512_support(dev, dev->wlan.wcid_512); -@@ -1550,13 +1561,14 @@ mtk_wed_attach(struct mtk_wed_device *de - } - - mtk_wed_hw_init_early(dev); -- if (mtk_wed_is_v1(hw)) { -+ if (mtk_wed_is_v1(hw)) - regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP, - BIT(hw->index), 0); -- } else { -+ else - dev->rev_id = wed_r32(dev, MTK_WED_REV_ID); -+ -+ if (mtk_wed_get_rx_capa(dev)) - ret = mtk_wed_wo_init(hw); -- } - out: - if (ret) { - dev_err(dev->hw->dev, "failed to attach wed device\n"); ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -207,7 +207,7 @@ int mtk_wed_mcu_msg_update(struct mtk_we - { - struct mtk_wed_wo *wo = dev->hw->wed_wo; - -- if (mtk_wed_is_v1(dev->hw)) -+ if (!mtk_wed_get_rx_capa(dev)) - return 0; - - if (WARN_ON(!wo)) diff --git a/target/linux/generic/backport-6.1/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch b/target/linux/generic/backport-6.1/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch deleted file mode 100644 index d83434fb2c7d08..00000000000000 --- a/target/linux/generic/backport-6.1/752-08-v6.7-net-ethernet-mtk_wed-rename-mtk_rxbm_desc-in-mtk_wed.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:07 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: rename mtk_rxbm_desc in - mtk_wed_bm_desc - -Rename mtk_rxbm_desc structure in mtk_wed_bm_desc since it will be used -even on tx side by MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -421,7 +421,7 @@ free_pagelist: - static int - mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev) - { -- struct mtk_rxbm_desc *desc; -+ struct mtk_wed_bm_desc *desc; - dma_addr_t desc_phys; - - dev->rx_buf_ring.size = dev->wlan.rx_nbuf; -@@ -441,7 +441,7 @@ mtk_wed_rx_buffer_alloc(struct mtk_wed_d - static void - mtk_wed_free_rx_buffer(struct mtk_wed_device *dev) - { -- struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc; -+ struct mtk_wed_bm_desc *desc = dev->rx_buf_ring.desc; - - if (!desc) - return; ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -45,7 +45,7 @@ enum mtk_wed_wo_cmd { - MTK_WED_WO_CMD_WED_END - }; - --struct mtk_rxbm_desc { -+struct mtk_wed_bm_desc { - __le32 buf0; - __le32 token; - } __packed __aligned(4); -@@ -105,7 +105,7 @@ struct mtk_wed_device { - struct { - int size; - struct page_frag_cache rx_page; -- struct mtk_rxbm_desc *desc; -+ struct mtk_wed_bm_desc *desc; - dma_addr_t desc_phys; - } rx_buf_ring; - diff --git a/target/linux/generic/backport-6.1/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch b/target/linux/generic/backport-6.1/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch deleted file mode 100644 index 8000a8759e5b50..00000000000000 --- a/target/linux/generic/backport-6.1/752-09-v6.7-net-ethernet-mtk_wed-introduce-mtk_wed_buf-structure.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:08 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: introduce mtk_wed_buf structure - -Introduce mtk_wed_buf structure to store both virtual and physical -addresses allocated in mtk_wed_tx_buffer_alloc() routine. This is a -preliminary patch to add WED support for MT7988 SoC since it relies on a -different dma descriptor layout not storing page dma addresses. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -299,9 +299,9 @@ out: - static int - mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) - { -+ struct mtk_wed_buf *page_list; - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -- void **page_list; - int token = dev->wlan.token_start; - int ring_size; - int n_pages; -@@ -342,7 +342,8 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d - return -ENOMEM; - } - -- page_list[page_idx++] = page; -+ page_list[page_idx].p = page; -+ page_list[page_idx++].phy_addr = page_phys; - dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE, - DMA_BIDIRECTIONAL); - -@@ -386,8 +387,8 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d - static void - mtk_wed_free_tx_buffer(struct mtk_wed_device *dev) - { -+ struct mtk_wed_buf *page_list = dev->tx_buf_ring.pages; - struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc; -- void **page_list = dev->tx_buf_ring.pages; - int page_idx; - int i; - -@@ -399,13 +400,12 @@ mtk_wed_free_tx_buffer(struct mtk_wed_de - - for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size; - i += MTK_WED_BUF_PER_PAGE) { -- void *page = page_list[page_idx++]; -- dma_addr_t buf_addr; -+ dma_addr_t buf_addr = page_list[page_idx].phy_addr; -+ void *page = page_list[page_idx++].p; - - if (!page) - break; - -- buf_addr = le32_to_cpu(desc[i].buf0); - dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE, - DMA_BIDIRECTIONAL); - __free_page(page); ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -76,6 +76,11 @@ struct mtk_wed_wo_rx_stats { - __le32 rx_drop_cnt; - }; - -+struct mtk_wed_buf { -+ void *p; -+ dma_addr_t phy_addr; -+}; -+ - struct mtk_wed_device { - #ifdef CONFIG_NET_MEDIATEK_SOC_WED - const struct mtk_wed_ops *ops; -@@ -97,7 +102,7 @@ struct mtk_wed_device { - - struct { - int size; -- void **pages; -+ struct mtk_wed_buf *pages; - struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; - } tx_buf_ring; diff --git a/target/linux/generic/backport-6.1/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch b/target/linux/generic/backport-6.1/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch deleted file mode 100644 index 98d782b1d07409..00000000000000 --- a/target/linux/generic/backport-6.1/752-10-v6.7-net-ethernet-mtk_wed-move-mem_region-array-out-of-mt.patch +++ /dev/null @@ -1,88 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:09 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: move mem_region array out of - mtk_wed_mcu_load_firmware - -Remove mtk_wed_wo_memory_region boot structure in mtk_wed_wo. -This is a preliminary patch to introduce WED support for MT7988 SoC. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -16,14 +16,30 @@ - #include "mtk_wed_wo.h" - #include "mtk_wed.h" - -+static struct mtk_wed_wo_memory_region mem_region[] = { -+ [MTK_WED_WO_REGION_EMI] = { -+ .name = "wo-emi", -+ }, -+ [MTK_WED_WO_REGION_ILM] = { -+ .name = "wo-ilm", -+ }, -+ [MTK_WED_WO_REGION_DATA] = { -+ .name = "wo-data", -+ .shared = true, -+ }, -+ [MTK_WED_WO_REGION_BOOT] = { -+ .name = "wo-boot", -+ }, -+}; -+ - static u32 wo_r32(struct mtk_wed_wo *wo, u32 reg) - { -- return readl(wo->boot.addr + reg); -+ return readl(mem_region[MTK_WED_WO_REGION_BOOT].addr + reg); - } - - static void wo_w32(struct mtk_wed_wo *wo, u32 reg, u32 val) - { -- writel(val, wo->boot.addr + reg); -+ writel(val, mem_region[MTK_WED_WO_REGION_BOOT].addr + reg); - } - - static struct sk_buff * -@@ -294,18 +310,6 @@ next: - static int - mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo) - { -- static struct mtk_wed_wo_memory_region mem_region[] = { -- [MTK_WED_WO_REGION_EMI] = { -- .name = "wo-emi", -- }, -- [MTK_WED_WO_REGION_ILM] = { -- .name = "wo-ilm", -- }, -- [MTK_WED_WO_REGION_DATA] = { -- .name = "wo-data", -- .shared = true, -- }, -- }; - const struct mtk_wed_fw_trailer *trailer; - const struct firmware *fw; - const char *fw_name; -@@ -319,11 +323,6 @@ mtk_wed_mcu_load_firmware(struct mtk_wed - return ret; - } - -- wo->boot.name = "wo-boot"; -- ret = mtk_wed_get_memory_region(wo, &wo->boot); -- if (ret) -- return ret; -- - /* set dummy cr */ - wed_w32(wo->hw->wed_dev, MTK_WED_SCR0 + 4 * MTK_WED_DUMMY_CR_FWDL, - wo->hw->index + 1); ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -228,7 +228,6 @@ struct mtk_wed_wo_queue { - - struct mtk_wed_wo { - struct mtk_wed_hw *hw; -- struct mtk_wed_wo_memory_region boot; - - struct mtk_wed_wo_queue q_tx; - struct mtk_wed_wo_queue q_rx; diff --git a/target/linux/generic/backport-6.1/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch b/target/linux/generic/backport-6.1/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch deleted file mode 100644 index 48b0d02049194d..00000000000000 --- a/target/linux/generic/backport-6.1/752-11-v6.7-net-ethernet-mtk_wed-make-memory-region-optional.patch +++ /dev/null @@ -1,71 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:10 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: make memory region optional - -Make mtk_wed_wo_memory_region optionals. -This is a preliminary patch to introduce Wireless Ethernet Dispatcher -support for MT7988 SoC since MT7988 WED fw image will have a different -layout. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -234,19 +234,13 @@ int mtk_wed_mcu_msg_update(struct mtk_we - } - - static int --mtk_wed_get_memory_region(struct mtk_wed_wo *wo, -+mtk_wed_get_memory_region(struct mtk_wed_hw *hw, int index, - struct mtk_wed_wo_memory_region *region) - { - struct reserved_mem *rmem; - struct device_node *np; -- int index; - -- index = of_property_match_string(wo->hw->node, "memory-region-names", -- region->name); -- if (index < 0) -- return index; -- -- np = of_parse_phandle(wo->hw->node, "memory-region", index); -+ np = of_parse_phandle(hw->node, "memory-region", index); - if (!np) - return -ENODEV; - -@@ -258,7 +252,7 @@ mtk_wed_get_memory_region(struct mtk_wed - - region->phy_addr = rmem->base; - region->size = rmem->size; -- region->addr = devm_ioremap(wo->hw->dev, region->phy_addr, region->size); -+ region->addr = devm_ioremap(hw->dev, region->phy_addr, region->size); - - return !region->addr ? -EINVAL : 0; - } -@@ -271,6 +265,9 @@ mtk_wed_mcu_run_firmware(struct mtk_wed_ - const struct mtk_wed_fw_trailer *trailer; - const struct mtk_wed_fw_region *fw_region; - -+ if (!region->phy_addr || !region->size) -+ return 0; -+ - trailer_ptr = fw->data + fw->size - sizeof(*trailer); - trailer = (const struct mtk_wed_fw_trailer *)trailer_ptr; - region_ptr = trailer_ptr - trailer->num_region * sizeof(*fw_region); -@@ -318,7 +315,13 @@ mtk_wed_mcu_load_firmware(struct mtk_wed - - /* load firmware region metadata */ - for (i = 0; i < ARRAY_SIZE(mem_region); i++) { -- ret = mtk_wed_get_memory_region(wo, &mem_region[i]); -+ int index = of_property_match_string(wo->hw->node, -+ "memory-region-names", -+ mem_region[i].name); -+ if (index < 0) -+ continue; -+ -+ ret = mtk_wed_get_memory_region(wo->hw, index, &mem_region[i]); - if (ret) - return ret; - } diff --git a/target/linux/generic/backport-6.1/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch b/target/linux/generic/backport-6.1/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch deleted file mode 100644 index c43114fb5b15b4..00000000000000 --- a/target/linux/generic/backport-6.1/752-13-v6.7-net-ethernet-mtk_wed-add-mtk_wed_soc_data-structure.patch +++ /dev/null @@ -1,217 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:12 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: add mtk_wed_soc_data structure - -Introduce mtk_wed_soc_data utility structure to contain per-SoC -definitions. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -48,6 +48,26 @@ struct mtk_wed_flow_block_priv { - struct net_device *dev; - }; - -+static const struct mtk_wed_soc_data mt7622_data = { -+ .regmap = { -+ .tx_bm_tkid = 0x088, -+ .wpdma_rx_ring0 = 0x770, -+ .reset_idx_tx_mask = GENMASK(3, 0), -+ .reset_idx_rx_mask = GENMASK(17, 16), -+ }, -+ .wdma_desc_size = sizeof(struct mtk_wdma_desc), -+}; -+ -+static const struct mtk_wed_soc_data mt7986_data = { -+ .regmap = { -+ .tx_bm_tkid = 0x0c8, -+ .wpdma_rx_ring0 = 0x770, -+ .reset_idx_tx_mask = GENMASK(1, 0), -+ .reset_idx_rx_mask = GENMASK(7, 6), -+ }, -+ .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc), -+}; -+ - static void - wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val) - { -@@ -746,7 +766,7 @@ mtk_wed_set_wpdma(struct mtk_wed_device - return; - - wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); -- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx); -+ wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx); - } - - static void -@@ -940,22 +960,10 @@ mtk_wed_hw_init(struct mtk_wed_device *d - wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); - - if (mtk_wed_is_v1(dev->hw)) { -- wed_w32(dev, MTK_WED_TX_BM_TKID, -- FIELD_PREP(MTK_WED_TX_BM_TKID_START, -- dev->wlan.token_start) | -- FIELD_PREP(MTK_WED_TX_BM_TKID_END, -- dev->wlan.token_start + -- dev->wlan.nbuf - 1)); - wed_w32(dev, MTK_WED_TX_BM_DYN_THR, - FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | - MTK_WED_TX_BM_DYN_THR_HI); - } else { -- wed_w32(dev, MTK_WED_TX_BM_TKID_V2, -- FIELD_PREP(MTK_WED_TX_BM_TKID_START, -- dev->wlan.token_start) | -- FIELD_PREP(MTK_WED_TX_BM_TKID_END, -- dev->wlan.token_start + -- dev->wlan.nbuf - 1)); - wed_w32(dev, MTK_WED_TX_BM_DYN_THR, - FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) | - MTK_WED_TX_BM_DYN_THR_HI_V2); -@@ -970,6 +978,11 @@ mtk_wed_hw_init(struct mtk_wed_device *d - MTK_WED_TX_TKID_DYN_THR_HI); - } - -+ wed_w32(dev, dev->hw->soc->regmap.tx_bm_tkid, -+ FIELD_PREP(MTK_WED_TX_BM_TKID_START, dev->wlan.token_start) | -+ FIELD_PREP(MTK_WED_TX_BM_TKID_END, -+ dev->wlan.token_start + dev->wlan.nbuf - 1)); -+ - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - - if (mtk_wed_is_v1(dev->hw)) { -@@ -1104,13 +1117,8 @@ mtk_wed_rx_reset(struct mtk_wed_device * - if (ret) { - mtk_wed_reset(dev, MTK_WED_RESET_WED_RX_DMA); - } else { -- struct mtk_eth *eth = dev->hw->eth; -- -- if (mtk_is_netsys_v2_or_greater(eth)) -- wed_set(dev, MTK_WED_RESET_IDX, -- MTK_WED_RESET_IDX_RX_V2); -- else -- wed_set(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_RX); -+ wed_set(dev, MTK_WED_RESET_IDX, -+ dev->hw->soc->regmap.reset_idx_rx_mask); - wed_w32(dev, MTK_WED_RESET_IDX, 0); - } - -@@ -1163,7 +1171,8 @@ mtk_wed_reset_dma(struct mtk_wed_device - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WED_TX_DMA); - } else { -- wed_w32(dev, MTK_WED_RESET_IDX, MTK_WED_RESET_IDX_TX); -+ wed_w32(dev, MTK_WED_RESET_IDX, -+ dev->hw->soc->regmap.reset_idx_tx_mask); - wed_w32(dev, MTK_WED_RESET_IDX, 0); - } - -@@ -1255,7 +1264,6 @@ static int - mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev, int idx, int size, - bool reset) - { -- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; - struct mtk_wed_ring *wdma; - - if (idx >= ARRAY_SIZE(dev->rx_wdma)) -@@ -1263,7 +1271,7 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we - - wdma = &dev->rx_wdma[idx]; - if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, -- desc_size, true)) -+ dev->hw->soc->wdma_desc_size, true)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, -@@ -1284,7 +1292,6 @@ static int - mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev, int idx, int size, - bool reset) - { -- u32 desc_size = sizeof(struct mtk_wdma_desc) * dev->hw->version; - struct mtk_wed_ring *wdma; - - if (idx >= ARRAY_SIZE(dev->tx_wdma)) -@@ -1292,7 +1299,7 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we - - wdma = &dev->tx_wdma[idx]; - if (!reset && mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE, -- desc_size, true)) -+ dev->hw->soc->wdma_desc_size, true)) - return -ENOMEM; - - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, -@@ -1931,7 +1938,12 @@ void mtk_wed_add_hw(struct device_node * - hw->irq = irq; - hw->version = eth->soc->version; - -- if (mtk_wed_is_v1(hw)) { -+ switch (hw->version) { -+ case 2: -+ hw->soc = &mt7986_data; -+ break; -+ default: -+ case 1: - hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, - "mediatek,pcie-mirror"); - hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np, -@@ -1945,6 +1957,8 @@ void mtk_wed_add_hw(struct device_node * - regmap_write(hw->mirror, 0, 0); - regmap_write(hw->mirror, 4, 0); - } -+ hw->soc = &mt7622_data; -+ break; - } - - mtk_wed_hw_add_debugfs(hw); ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -12,7 +12,18 @@ - struct mtk_eth; - struct mtk_wed_wo; - -+struct mtk_wed_soc_data { -+ struct { -+ u32 tx_bm_tkid; -+ u32 wpdma_rx_ring0; -+ u32 reset_idx_tx_mask; -+ u32 reset_idx_rx_mask; -+ } regmap; -+ u32 wdma_desc_size; -+}; -+ - struct mtk_wed_hw { -+ const struct mtk_wed_soc_data *soc; - struct device_node *node; - struct mtk_eth *eth; - struct regmap *regs; ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -100,8 +100,6 @@ struct mtk_wdma_desc { - - #define MTK_WED_TX_BM_BASE 0x084 - --#define MTK_WED_TX_BM_TKID 0x088 --#define MTK_WED_TX_BM_TKID_V2 0x0c8 - #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0) - #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16) - -@@ -160,9 +158,6 @@ struct mtk_wdma_desc { - #define MTK_WED_GLO_CFG_RX_2B_OFFSET BIT(31) - - #define MTK_WED_RESET_IDX 0x20c --#define MTK_WED_RESET_IDX_TX GENMASK(3, 0) --#define MTK_WED_RESET_IDX_RX GENMASK(17, 16) --#define MTK_WED_RESET_IDX_RX_V2 GENMASK(7, 6) - #define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30) - - #define MTK_WED_TX_MIB(_n) (0x2a0 + (_n) * 4) -@@ -286,7 +281,6 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24) - - #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c --#define MTK_WED_WPDMA_RX_RING 0x770 - - #define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4) - #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4) diff --git a/target/linux/generic/backport-6.1/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch b/target/linux/generic/backport-6.1/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch deleted file mode 100644 index f874899c5bdc5f..00000000000000 --- a/target/linux/generic/backport-6.1/752-14-v6.7-net-ethernet-mtk_wed-introduce-WED-support-for-MT798.patch +++ /dev/null @@ -1,1280 +0,0 @@ -From: Sujuan Chen -Date: Mon, 18 Sep 2023 12:29:13 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: introduce WED support for MT7988 - -Similar to MT7986 and MT7622, enable Wireless Ethernet Ditpatcher for -MT7988 in order to offload traffic forwarded from LAN/WLAN to WLAN/LAN - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -195,6 +195,7 @@ static const struct mtk_reg_map mt7988_r - .wdma_base = { - [0] = 0x4800, - [1] = 0x4c00, -+ [2] = 0x5000, - }, - .pse_iq_sta = 0x0180, - .pse_oq_sta = 0x01a0, ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1132,7 +1132,7 @@ struct mtk_reg_map { - u32 gdm1_cnt; - u32 gdma_to_ppe; - u32 ppe_base; -- u32 wdma_base[2]; -+ u32 wdma_base[3]; - u32 pse_iq_sta; - u32 pse_oq_sta; - }; ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -201,6 +201,9 @@ mtk_flow_set_output_device(struct mtk_et - case 1: - pse_port = PSE_WDMA1_PORT; - break; -+ case 2: -+ pse_port = PSE_WDMA2_PORT; -+ break; - default: - return -EINVAL; - } ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -16,17 +16,19 @@ - #include - #include - #include "mtk_eth_soc.h" --#include "mtk_wed_regs.h" - #include "mtk_wed.h" - #include "mtk_ppe.h" - #include "mtk_wed_wo.h" - - #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000) - --#define MTK_WED_PKT_SIZE 1900 -+#define MTK_WED_PKT_SIZE 1920 - #define MTK_WED_BUF_SIZE 2048 -+#define MTK_WED_PAGE_BUF_SIZE 128 - #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048) -+#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128) - #define MTK_WED_RX_RING_SIZE 1536 -+#define MTK_WED_RX_PG_BM_CNT 8192 - - #define MTK_WED_TX_RING_SIZE 2048 - #define MTK_WED_WDMA_RING_SIZE 1024 -@@ -40,7 +42,10 @@ - #define MTK_WED_RRO_QUE_CNT 8192 - #define MTK_WED_MIOD_ENTRY_CNT 128 - --static struct mtk_wed_hw *hw_list[2]; -+#define MTK_WED_TX_BM_DMA_SIZE 65536 -+#define MTK_WED_TX_BM_PKT_CNT 32768 -+ -+static struct mtk_wed_hw *hw_list[3]; - static DEFINE_MUTEX(hw_lock); - - struct mtk_wed_flow_block_priv { -@@ -55,6 +60,7 @@ static const struct mtk_wed_soc_data mt7 - .reset_idx_tx_mask = GENMASK(3, 0), - .reset_idx_rx_mask = GENMASK(17, 16), - }, -+ .tx_ring_desc_size = sizeof(struct mtk_wdma_desc), - .wdma_desc_size = sizeof(struct mtk_wdma_desc), - }; - -@@ -65,6 +71,18 @@ static const struct mtk_wed_soc_data mt7 - .reset_idx_tx_mask = GENMASK(1, 0), - .reset_idx_rx_mask = GENMASK(7, 6), - }, -+ .tx_ring_desc_size = sizeof(struct mtk_wdma_desc), -+ .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc), -+}; -+ -+static const struct mtk_wed_soc_data mt7988_data = { -+ .regmap = { -+ .tx_bm_tkid = 0x0c8, -+ .wpdma_rx_ring0 = 0x7d0, -+ .reset_idx_tx_mask = GENMASK(1, 0), -+ .reset_idx_rx_mask = GENMASK(7, 6), -+ }, -+ .tx_ring_desc_size = sizeof(struct mtk_wed_bm_desc), - .wdma_desc_size = 2 * sizeof(struct mtk_wdma_desc), - }; - -@@ -319,33 +337,38 @@ out: - static int - mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) - { -+ u32 desc_size = dev->hw->soc->tx_ring_desc_size; -+ int i, page_idx = 0, n_pages, ring_size; -+ int token = dev->wlan.token_start; - struct mtk_wed_buf *page_list; -- struct mtk_wdma_desc *desc; - dma_addr_t desc_phys; -- int token = dev->wlan.token_start; -- int ring_size; -- int n_pages; -- int i, page_idx; -+ void *desc_ptr; - -- ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1); -- n_pages = ring_size / MTK_WED_BUF_PER_PAGE; -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) { -+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1); -+ dev->tx_buf_ring.size = ring_size; -+ } else { -+ dev->tx_buf_ring.size = MTK_WED_TX_BM_DMA_SIZE; -+ ring_size = MTK_WED_TX_BM_PKT_CNT; -+ } -+ n_pages = dev->tx_buf_ring.size / MTK_WED_BUF_PER_PAGE; - - page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL); - if (!page_list) - return -ENOMEM; - -- dev->tx_buf_ring.size = ring_size; - dev->tx_buf_ring.pages = page_list; - -- desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc), -- &desc_phys, GFP_KERNEL); -- if (!desc) -+ desc_ptr = dma_alloc_coherent(dev->hw->dev, -+ dev->tx_buf_ring.size * desc_size, -+ &desc_phys, GFP_KERNEL); -+ if (!desc_ptr) - return -ENOMEM; - -- dev->tx_buf_ring.desc = desc; -+ dev->tx_buf_ring.desc = desc_ptr; - dev->tx_buf_ring.desc_phys = desc_phys; - -- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) { -+ for (i = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) { - dma_addr_t page_phys, buf_phys; - struct page *page; - void *buf; -@@ -371,28 +394,31 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d - buf_phys = page_phys; - - for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) { -- u32 txd_size; -- u32 ctrl; -- -- txd_size = dev->wlan.init_buf(buf, buf_phys, token++); -+ struct mtk_wdma_desc *desc = desc_ptr; - - desc->buf0 = cpu_to_le32(buf_phys); -- desc->buf1 = cpu_to_le32(buf_phys + txd_size); -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) { -+ u32 txd_size, ctrl; - -- if (mtk_wed_is_v1(dev->hw)) -- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -- MTK_WED_BUF_SIZE - txd_size) | -- MTK_WDMA_DESC_CTRL_LAST_SEG1; -- else -- ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size) | -- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2, -- MTK_WED_BUF_SIZE - txd_size) | -- MTK_WDMA_DESC_CTRL_LAST_SEG0; -- desc->ctrl = cpu_to_le32(ctrl); -- desc->info = 0; -- desc++; -+ txd_size = dev->wlan.init_buf(buf, buf_phys, -+ token++); -+ desc->buf1 = cpu_to_le32(buf_phys + txd_size); -+ ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0, txd_size); -+ if (mtk_wed_is_v1(dev->hw)) -+ ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG1 | -+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1, -+ MTK_WED_BUF_SIZE - txd_size); -+ else -+ ctrl |= MTK_WDMA_DESC_CTRL_LAST_SEG0 | -+ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1_V2, -+ MTK_WED_BUF_SIZE - txd_size); -+ desc->ctrl = cpu_to_le32(ctrl); -+ desc->info = 0; -+ } else { -+ desc->ctrl = cpu_to_le32(token << 16); -+ } - -+ desc_ptr += desc_size; - buf += MTK_WED_BUF_SIZE; - buf_phys += MTK_WED_BUF_SIZE; - } -@@ -408,31 +434,31 @@ static void - mtk_wed_free_tx_buffer(struct mtk_wed_device *dev) - { - struct mtk_wed_buf *page_list = dev->tx_buf_ring.pages; -- struct mtk_wdma_desc *desc = dev->tx_buf_ring.desc; -- int page_idx; -- int i; -+ struct mtk_wed_hw *hw = dev->hw; -+ int i, page_idx = 0; - - if (!page_list) - return; - -- if (!desc) -+ if (!dev->tx_buf_ring.desc) - goto free_pagelist; - -- for (i = 0, page_idx = 0; i < dev->tx_buf_ring.size; -- i += MTK_WED_BUF_PER_PAGE) { -- dma_addr_t buf_addr = page_list[page_idx].phy_addr; -+ for (i = 0; i < dev->tx_buf_ring.size; i += MTK_WED_BUF_PER_PAGE) { -+ dma_addr_t page_phy = page_list[page_idx].phy_addr; - void *page = page_list[page_idx++].p; - - if (!page) - break; - -- dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE, -+ dma_unmap_page(dev->hw->dev, page_phy, PAGE_SIZE, - DMA_BIDIRECTIONAL); - __free_page(page); - } - -- dma_free_coherent(dev->hw->dev, dev->tx_buf_ring.size * sizeof(*desc), -- desc, dev->tx_buf_ring.desc_phys); -+ dma_free_coherent(dev->hw->dev, -+ dev->tx_buf_ring.size * hw->soc->tx_ring_desc_size, -+ dev->tx_buf_ring.desc, -+ dev->tx_buf_ring.desc_phys); - - free_pagelist: - kfree(page_list); -@@ -517,13 +543,23 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - { - u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; - -- if (mtk_wed_is_v1(dev->hw)) -+ switch (dev->hw->version) { -+ case 1: - mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; -- else -+ break; -+ case 2: - mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | - MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | - MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | - MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; -+ break; -+ case 3: -+ mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | -+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; -+ break; -+ default: -+ break; -+ } - - if (!dev->hw->num_flows) - mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; -@@ -535,6 +571,9 @@ mtk_wed_set_ext_int(struct mtk_wed_devic - static void - mtk_wed_set_512_support(struct mtk_wed_device *dev, bool enable) - { -+ if (!mtk_wed_is_v2(dev->hw)) -+ return; -+ - if (enable) { - wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR); - wed_w32(dev, MTK_WED_TXP_DW1, -@@ -609,6 +648,14 @@ mtk_wed_dma_disable(struct mtk_wed_devic - MTK_WED_WPDMA_RX_D_RX_DRV_EN); - wed_clr(dev, MTK_WED_WDMA_GLO_CFG, - MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); -+ -+ if (mtk_wed_is_v3_or_greater(dev->hw) && -+ mtk_wed_get_rx_capa(dev)) { -+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, -+ MTK_WDMA_PREF_TX_CFG_PREF_EN); -+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, -+ MTK_WDMA_PREF_RX_CFG_PREF_EN); -+ } - } - - mtk_wed_set_512_support(dev, false); -@@ -651,6 +698,14 @@ mtk_wed_deinit(struct mtk_wed_device *de - MTK_WED_CTRL_RX_ROUTE_QM_EN | - MTK_WED_CTRL_WED_RX_BM_EN | - MTK_WED_CTRL_RX_RRO_QM_EN); -+ -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN); -+ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_TX_AMSDU); -+ wed_clr(dev, MTK_WED_PCIE_INT_CTRL, -+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | -+ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER); -+ } - } - - static void -@@ -700,21 +755,37 @@ mtk_wed_detach(struct mtk_wed_device *de - mutex_unlock(&hw_lock); - } - --#define PCIE_BASE_ADDR0 0x11280000 - static void - mtk_wed_bus_init(struct mtk_wed_device *dev) - { - switch (dev->wlan.bus_type) { - case MTK_WED_BUS_PCIE: { - struct device_node *np = dev->hw->eth->dev->of_node; -- struct regmap *regs; - -- regs = syscon_regmap_lookup_by_phandle(np, -- "mediatek,wed-pcie"); -- if (IS_ERR(regs)) -- break; -+ if (mtk_wed_is_v2(dev->hw)) { -+ struct regmap *regs; -+ -+ regs = syscon_regmap_lookup_by_phandle(np, -+ "mediatek,wed-pcie"); -+ if (IS_ERR(regs)) -+ break; - -- regmap_update_bits(regs, 0, BIT(0), BIT(0)); -+ regmap_update_bits(regs, 0, BIT(0), BIT(0)); -+ } -+ -+ if (dev->wlan.msi) { -+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, -+ dev->hw->pcie_base | 0xc08); -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, -+ dev->hw->pcie_base | 0xc04); -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(8)); -+ } else { -+ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, -+ dev->hw->pcie_base | 0x180); -+ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, -+ dev->hw->pcie_base | 0x184); -+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); -+ } - - wed_w32(dev, MTK_WED_PCIE_INT_CTRL, - FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2)); -@@ -722,19 +793,9 @@ mtk_wed_bus_init(struct mtk_wed_device * - /* pcie interrupt control: pola/source selection */ - wed_set(dev, MTK_WED_PCIE_INT_CTRL, - MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA | -- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1)); -- wed_r32(dev, MTK_WED_PCIE_INT_CTRL); -- -- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180); -- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184); -- -- /* pcie interrupt status trigger register */ -- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24)); -- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER); -- -- /* pola setting */ -- wed_set(dev, MTK_WED_PCIE_INT_CTRL, -- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA); -+ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER | -+ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, -+ dev->hw->index)); - break; - } - case MTK_WED_BUS_AXI: -@@ -772,18 +833,19 @@ mtk_wed_set_wpdma(struct mtk_wed_device - static void - mtk_wed_hw_init_early(struct mtk_wed_device *dev) - { -- u32 mask, set; -+ u32 set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2); -+ u32 mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE; - - mtk_wed_deinit(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); - mtk_wed_set_wpdma(dev); - -- mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE | -- MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE | -- MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE; -- set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) | -- MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP | -- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) { -+ mask |= MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE | -+ MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE; -+ set |= MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP | -+ MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY; -+ } - wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set); - - if (mtk_wed_is_v1(dev->hw)) { -@@ -931,11 +993,18 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_ - } - - /* configure RX_ROUTE_QM */ -- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT); -- wed_set(dev, MTK_WED_RTQM_GLO_CFG, -- FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index)); -- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ if (mtk_wed_is_v2(dev->hw)) { -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT); -+ wed_set(dev, MTK_WED_RTQM_GLO_CFG, -+ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, -+ 0x3 + dev->hw->index)); -+ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ } else { -+ wed_set(dev, MTK_WED_RTQM_ENQ_CFG0, -+ FIELD_PREP(MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT, -+ 0x3 + dev->hw->index)); -+ } - /* enable RX_ROUTE_QM */ - wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); - } -@@ -948,22 +1017,30 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - dev->init_done = true; - mtk_wed_set_ext_int(dev, false); -- wed_w32(dev, MTK_WED_TX_BM_CTRL, -- MTK_WED_TX_BM_CTRL_PAUSE | -- FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, -- dev->tx_buf_ring.size / 128) | -- FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, -- MTK_WED_TX_RING_SIZE / 256)); - - wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys); -- - wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE); - - if (mtk_wed_is_v1(dev->hw)) { -+ wed_w32(dev, MTK_WED_TX_BM_CTRL, -+ MTK_WED_TX_BM_CTRL_PAUSE | -+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, -+ dev->tx_buf_ring.size / 128) | -+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, -+ MTK_WED_TX_RING_SIZE / 256)); - wed_w32(dev, MTK_WED_TX_BM_DYN_THR, - FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, 1) | - MTK_WED_TX_BM_DYN_THR_HI); -- } else { -+ } else if (mtk_wed_is_v2(dev->hw)) { -+ wed_w32(dev, MTK_WED_TX_BM_CTRL, -+ MTK_WED_TX_BM_CTRL_PAUSE | -+ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, -+ dev->tx_buf_ring.size / 128) | -+ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, -+ MTK_WED_TX_RING_SIZE / 256)); -+ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, -+ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | -+ MTK_WED_TX_TKID_DYN_THR_HI); - wed_w32(dev, MTK_WED_TX_BM_DYN_THR, - FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO_V2, 0) | - MTK_WED_TX_BM_DYN_THR_HI_V2); -@@ -973,9 +1050,6 @@ mtk_wed_hw_init(struct mtk_wed_device *d - dev->tx_buf_ring.size / 128) | - FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM, - dev->tx_buf_ring.size / 128)); -- wed_w32(dev, MTK_WED_TX_TKID_DYN_THR, -- FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) | -- MTK_WED_TX_TKID_DYN_THR_HI); - } - - wed_w32(dev, dev->hw->soc->regmap.tx_bm_tkid, -@@ -985,26 +1059,62 @@ mtk_wed_hw_init(struct mtk_wed_device *d - - mtk_wed_reset(dev, MTK_WED_RESET_TX_BM); - -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ /* switch to new bm architecture */ -+ wed_clr(dev, MTK_WED_TX_BM_CTRL, -+ MTK_WED_TX_BM_CTRL_LEGACY_EN); -+ -+ wed_w32(dev, MTK_WED_TX_TKID_CTRL, -+ MTK_WED_TX_TKID_CTRL_PAUSE | -+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3, -+ dev->wlan.nbuf / 128) | -+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3, -+ dev->wlan.nbuf / 128)); -+ /* return SKBID + SDP back to bm */ -+ wed_set(dev, MTK_WED_TX_TKID_CTRL, -+ MTK_WED_TX_TKID_CTRL_FREE_FORMAT); -+ -+ wed_w32(dev, MTK_WED_TX_BM_INIT_PTR, -+ MTK_WED_TX_BM_PKT_CNT | -+ MTK_WED_TX_BM_INIT_SW_TAIL_IDX); -+ } -+ - if (mtk_wed_is_v1(dev->hw)) { - wed_set(dev, MTK_WED_CTRL, - MTK_WED_CTRL_WED_TX_BM_EN | - MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); -- } else { -- wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); -- if (mtk_wed_get_rx_capa(dev)) { -- /* rx hw init */ -- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -- MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -- MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -- wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -- -- mtk_wed_rx_buffer_hw_init(dev); -- mtk_wed_rro_hw_init(dev); -- mtk_wed_route_qm_hw_init(dev); -- } -+ } else if (mtk_wed_get_rx_capa(dev)) { -+ /* rx hw init */ -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX | -+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0); -+ -+ /* reset prefetch index of ring */ -+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX, -+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR); -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX, -+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR); -+ -+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX, -+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR); -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX, -+ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR); -+ -+ /* reset prefetch FIFO of ring */ -+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG, -+ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR | -+ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR); -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG, 0); -+ -+ mtk_wed_rx_buffer_hw_init(dev); -+ mtk_wed_rro_hw_init(dev); -+ mtk_wed_route_qm_hw_init(dev); - } - - wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE); -+ if (!mtk_wed_is_v1(dev->hw)) -+ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE); - } - - static void -@@ -1302,6 +1412,24 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we - dev->hw->soc->wdma_desc_size, true)) - return -ENOMEM; - -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ struct mtk_wdma_desc *desc = wdma->desc; -+ int i; -+ -+ for (i = 0; i < MTK_WED_WDMA_RING_SIZE; i++) { -+ desc->buf0 = 0; -+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ desc->buf1 = 0; -+ desc->info = cpu_to_le32(MTK_WDMA_TXD0_DESC_INFO_DMA_DONE); -+ desc++; -+ desc->buf0 = 0; -+ desc->ctrl = cpu_to_le32(MTK_WDMA_DESC_CTRL_DMA_DONE); -+ desc->buf1 = 0; -+ desc->info = cpu_to_le32(MTK_WDMA_TXD1_DESC_INFO_DMA_DONE); -+ desc++; -+ } -+ } -+ - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, - wdma->desc_phys); - wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT, -@@ -1367,6 +1495,9 @@ mtk_wed_configure_irq(struct mtk_wed_dev - - wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask); - } else { -+ if (mtk_wed_is_v3_or_greater(dev->hw)) -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_TKID_ALI_EN); -+ - /* initail tx interrupt trigger */ - wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX, - MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN | -@@ -1419,33 +1550,60 @@ mtk_wed_dma_enable(struct mtk_wed_device - { - int i; - -- wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL, -+ MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV); -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -+ wdma_set(dev, MTK_WDMA_GLO_CFG, -+ MTK_WDMA_GLO_CFG_TX_DMA_EN | -+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -+ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); -+ wed_set(dev, MTK_WED_WPDMA_CTRL, MTK_WED_WPDMA_CTRL_SDL1_FIXED); -+ } else { -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN | -+ MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR); -+ wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN); -+ } - - wed_set(dev, MTK_WED_GLO_CFG, - MTK_WED_GLO_CFG_TX_DMA_EN | - MTK_WED_GLO_CFG_RX_DMA_EN); -- wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -- MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN | -- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN); -+ - wed_set(dev, MTK_WED_WDMA_GLO_CFG, - MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); - -- wdma_set(dev, MTK_WDMA_GLO_CFG, -- MTK_WDMA_GLO_CFG_TX_DMA_EN | -- MTK_WDMA_GLO_CFG_RX_INFO1_PRERES | -- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES); -- - if (mtk_wed_is_v1(dev->hw)) { - wdma_set(dev, MTK_WDMA_GLO_CFG, - MTK_WDMA_GLO_CFG_RX_INFO3_PRERES); - return; - } - -- wed_set(dev, MTK_WED_WPDMA_CTRL, -- MTK_WED_WPDMA_CTRL_SDL1_FIXED); - wed_set(dev, MTK_WED_WPDMA_GLO_CFG, - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC | - MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC); -+ -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ FIELD_PREP(MTK_WED_WDMA_RX_PREF_BURST_SIZE, 0x10) | -+ FIELD_PREP(MTK_WED_WDMA_RX_PREF_LOW_THRES, 0x8)); -+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_DDONE2_EN); -+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN); -+ -+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST); -+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, -+ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK | -+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4); -+ -+ wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); -+ } -+ - wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, - MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP | - MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV); -@@ -1457,11 +1615,22 @@ mtk_wed_dma_enable(struct mtk_wed_device - MTK_WED_WDMA_GLO_CFG_TX_DRV_EN | - MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK); - -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RXD_READ_LEN); - wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, - MTK_WED_WPDMA_RX_D_RX_DRV_EN | - FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) | -- FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, -- 0x2)); -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL, 0x2)); -+ -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, -+ MTK_WED_WPDMA_RX_D_PREF_EN | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE, 0x10) | -+ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_LOW_THRES, 0x8)); -+ -+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN); -+ wdma_set(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN); -+ wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); -+ } - - for (i = 0; i < MTK_WED_RX_QUEUES; i++) - mtk_wed_check_wfdma_rx_fill(dev, i); -@@ -1501,6 +1670,12 @@ mtk_wed_start(struct mtk_wed_device *dev - wed_r32(dev, MTK_WED_EXT_INT_MASK1); - wed_r32(dev, MTK_WED_EXT_INT_MASK2); - -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_w32(dev, MTK_WED_EXT_INT_MASK3, -+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY); -+ wed_r32(dev, MTK_WED_EXT_INT_MASK3); -+ } -+ - if (mtk_wed_rro_cfg(dev)) - return; - } -@@ -1552,6 +1727,7 @@ mtk_wed_attach(struct mtk_wed_device *de - dev->irq = hw->irq; - dev->wdma_idx = hw->index; - dev->version = hw->version; -+ dev->hw->pcie_base = mtk_wed_get_pcie_base(dev); - - if (hw->eth->dma_dev == hw->eth->dev && - of_dma_is_coherent(hw->eth->dev->of_node)) -@@ -1619,6 +1795,23 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev - ring->reg_base = MTK_WED_RING_TX(idx); - ring->wpdma = regs; - -+ if (mtk_wed_is_v3_or_greater(dev->hw) && idx == 1) { -+ /* reset prefetch index */ -+ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR | -+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR); -+ -+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR | -+ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR); -+ -+ /* reset prefetch FIFO */ -+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, -+ MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR | -+ MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR); -+ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, 0); -+ } -+ - /* WED -> WPDMA */ - wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys); - wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_COUNT, MTK_WED_TX_RING_SIZE); -@@ -1693,15 +1886,13 @@ mtk_wed_rx_ring_setup(struct mtk_wed_dev - static u32 - mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask) - { -- u32 val, ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; -+ u32 val, ext_mask; - -- if (mtk_wed_is_v1(dev->hw)) -- ext_mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR; -+ if (mtk_wed_is_v3_or_greater(dev->hw)) -+ ext_mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | -+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD; - else -- ext_mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH | -- MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH | -- MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT | -- MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR; -+ ext_mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK; - - val = wed_r32(dev, MTK_WED_EXT_INT_STATUS); - wed_w32(dev, MTK_WED_EXT_INT_STATUS, val); -@@ -1942,6 +2133,9 @@ void mtk_wed_add_hw(struct device_node * - case 2: - hw->soc = &mt7986_data; - break; -+ case 3: -+ hw->soc = &mt7988_data; -+ break; - default: - case 1: - hw->mirror = syscon_regmap_lookup_by_phandle(eth_np, ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -9,6 +9,8 @@ - #include - #include - -+#include "mtk_wed_regs.h" -+ - struct mtk_eth; - struct mtk_wed_wo; - -@@ -19,6 +21,7 @@ struct mtk_wed_soc_data { - u32 reset_idx_tx_mask; - u32 reset_idx_rx_mask; - } regmap; -+ u32 tx_ring_desc_size; - u32 wdma_desc_size; - }; - -@@ -35,6 +38,7 @@ struct mtk_wed_hw { - struct dentry *debugfs_dir; - struct mtk_wed_device *wed_dev; - struct mtk_wed_wo *wed_wo; -+ u32 pcie_base; - u32 debugfs_reg; - u32 num_flows; - u8 version; -@@ -61,6 +65,16 @@ static inline bool mtk_wed_is_v2(struct - return hw->version == 2; - } - -+static inline bool mtk_wed_is_v3(struct mtk_wed_hw *hw) -+{ -+ return hw->version == 3; -+} -+ -+static inline bool mtk_wed_is_v3_or_greater(struct mtk_wed_hw *hw) -+{ -+ return hw->version > 2; -+} -+ - static inline void - wed_w32(struct mtk_wed_device *dev, u32 reg, u32 val) - { -@@ -143,6 +157,21 @@ wpdma_txfree_w32(struct mtk_wed_device * - writel(val, dev->txfree_ring.wpdma + reg); - } - -+static inline u32 mtk_wed_get_pcie_base(struct mtk_wed_device *dev) -+{ -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) -+ return MTK_WED_PCIE_BASE; -+ -+ switch (dev->hw->index) { -+ case 1: -+ return MTK_WED_PCIE_BASE1; -+ case 2: -+ return MTK_WED_PCIE_BASE2; -+ default: -+ return MTK_WED_PCIE_BASE0; -+ } -+} -+ - void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, - void __iomem *wdma, phys_addr_t wdma_phy, - int index); ---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c -@@ -331,10 +331,22 @@ mtk_wed_mcu_load_firmware(struct mtk_wed - wo->hw->index + 1); - - /* load firmware */ -- if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed")) -- fw_name = MT7981_FIRMWARE_WO; -- else -- fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0; -+ switch (wo->hw->version) { -+ case 2: -+ if (of_device_is_compatible(wo->hw->node, -+ "mediatek,mt7981-wed")) -+ fw_name = MT7981_FIRMWARE_WO; -+ else -+ fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 -+ : MT7986_FIRMWARE_WO0; -+ break; -+ case 3: -+ fw_name = wo->hw->index ? MT7988_FIRMWARE_WO1 -+ : MT7988_FIRMWARE_WO0; -+ break; -+ default: -+ return -EINVAL; -+ } - - ret = request_firmware(&fw, fw_name, wo->hw->dev); - if (ret) -@@ -355,15 +367,16 @@ mtk_wed_mcu_load_firmware(struct mtk_wed - } - - /* set the start address */ -- boot_cr = wo->hw->index ? MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR -- : MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR; -+ if (!mtk_wed_is_v3_or_greater(wo->hw) && wo->hw->index) -+ boot_cr = MTK_WO_MCU_CFG_LS_WA_BOOT_ADDR_ADDR; -+ else -+ boot_cr = MTK_WO_MCU_CFG_LS_WM_BOOT_ADDR_ADDR; - wo_w32(wo, boot_cr, mem_region[MTK_WED_WO_REGION_EMI].phy_addr >> 16); - /* wo firmware reset */ - wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCCR_CLR_ADDR, 0xc00); - -- val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR); -- val |= wo->hw->index ? MTK_WO_MCU_CFG_LS_WF_WM_WA_WA_CPU_RSTB_MASK -- : MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK; -+ val = wo_r32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR) | -+ MTK_WO_MCU_CFG_LS_WF_WM_WA_WM_CPU_RSTB_MASK; - wo_w32(wo, MTK_WO_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val); - out: - release_firmware(fw); -@@ -398,3 +411,5 @@ int mtk_wed_mcu_init(struct mtk_wed_wo * - MODULE_FIRMWARE(MT7981_FIRMWARE_WO); - MODULE_FIRMWARE(MT7986_FIRMWARE_WO0); - MODULE_FIRMWARE(MT7986_FIRMWARE_WO1); -+MODULE_FIRMWARE(MT7988_FIRMWARE_WO0); -+MODULE_FIRMWARE(MT7988_FIRMWARE_WO1); ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -13,6 +13,9 @@ - #define MTK_WDMA_DESC_CTRL_LAST_SEG0 BIT(30) - #define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31) - -+#define MTK_WDMA_TXD0_DESC_INFO_DMA_DONE BIT(29) -+#define MTK_WDMA_TXD1_DESC_INFO_DMA_DONE BIT(31) -+ - struct mtk_wdma_desc { - __le32 buf0; - __le32 ctrl; -@@ -37,6 +40,7 @@ struct mtk_wdma_desc { - #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19) - #define MTK_WED_RESET_RX_RRO_QM BIT(20) - #define MTK_WED_RESET_RX_ROUTE_QM BIT(21) -+#define MTK_WED_RESET_TX_AMSDU BIT(22) - #define MTK_WED_RESET_WED BIT(31) - - #define MTK_WED_CTRL 0x00c -@@ -44,6 +48,9 @@ struct mtk_wdma_desc { - #define MTK_WED_CTRL_WPDMA_INT_AGENT_BUSY BIT(1) - #define MTK_WED_CTRL_WDMA_INT_AGENT_EN BIT(2) - #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3) -+#define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5) -+#define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6) -+#define MTK_WED_CTRL_WED_RX_PG_BM_BUSY BIT(7) - #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8) - #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9) - #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10) -@@ -54,9 +61,14 @@ struct mtk_wdma_desc { - #define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15) - #define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16) - #define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17) -+#define MTK_WED_CTRL_TX_TKID_ALI_EN BIT(20) -+#define MTK_WED_CTRL_TX_TKID_ALI_BUSY BIT(21) -+#define MTK_WED_CTRL_TX_AMSDU_EN BIT(22) -+#define MTK_WED_CTRL_TX_AMSDU_BUSY BIT(23) - #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24) - #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25) - #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28) -+#define MTK_WED_CTRL_FLD_MIB_RD_CLR BIT(28) - - #define MTK_WED_EXT_INT_STATUS 0x020 - #define MTK_WED_EXT_INT_STATUS_TF_LEN_ERR BIT(0) -@@ -89,6 +101,7 @@ struct mtk_wdma_desc { - #define MTK_WED_EXT_INT_MASK 0x028 - #define MTK_WED_EXT_INT_MASK1 0x02c - #define MTK_WED_EXT_INT_MASK2 0x030 -+#define MTK_WED_EXT_INT_MASK3 0x034 - - #define MTK_WED_STATUS 0x060 - #define MTK_WED_STATUS_TX GENMASK(15, 8) -@@ -96,9 +109,14 @@ struct mtk_wdma_desc { - #define MTK_WED_TX_BM_CTRL 0x080 - #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0) - #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16) -+#define MTK_WED_TX_BM_CTRL_LEGACY_EN BIT(26) -+#define MTK_WED_TX_TKID_CTRL_FREE_FORMAT BIT(27) - #define MTK_WED_TX_BM_CTRL_PAUSE BIT(28) - - #define MTK_WED_TX_BM_BASE 0x084 -+#define MTK_WED_TX_BM_INIT_PTR 0x088 -+#define MTK_WED_TX_BM_SW_TAIL_IDX GENMASK(16, 0) -+#define MTK_WED_TX_BM_INIT_SW_TAIL_IDX BIT(16) - - #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0) - #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16) -@@ -122,6 +140,9 @@ struct mtk_wdma_desc { - #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16) - #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28) - -+#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3 GENMASK(7, 0) -+#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3 GENMASK(23, 16) -+ - #define MTK_WED_TX_TKID_DYN_THR 0x0e0 - #define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0) - #define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16) -@@ -199,12 +220,15 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_PKT_PROC BIT(5) - #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC BIT(6) - #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_CRX_SYNC BIT(7) --#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(18, 16) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(15, 12) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4 BIT(18) - #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNSUPPORT_FMT BIT(19) --#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UEVENT_PKT_FMT_CHK BIT(20) -+#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK BIT(20) - #define MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR BIT(21) - #define MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP BIT(24) -+#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST BIT(25) - #define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28) -+#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK BIT(30) - - #define MTK_WED_WPDMA_RESET_IDX 0x50c - #define MTK_WED_WPDMA_RESET_IDX_TX GENMASK(3, 0) -@@ -250,9 +274,10 @@ struct mtk_wdma_desc { - #define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16) - - #define MTK_WED_PCIE_INT_CTRL 0x57c --#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20) --#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16) - #define MTK_WED_PCIE_INT_CTRL_POLL_EN GENMASK(13, 12) -+#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16) -+#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20) -+#define MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER BIT(21) - - #define MTK_WED_WPDMA_CFG_BASE 0x580 - #define MTK_WED_WPDMA_CFG_INT_MASK 0x584 -@@ -286,6 +311,20 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4) - #define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c - -+#define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4 -+#define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0) -+#define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8) -+#define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16) -+ -+#define MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX 0x7b8 -+#define MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR BIT(15) -+ -+#define MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX 0x7bc -+ -+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG 0x7c0 -+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR BIT(0) -+#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR BIT(16) -+ - #define MTK_WED_WDMA_RING_TX 0x800 - - #define MTK_WED_WDMA_TX_MIB 0x810 -@@ -293,6 +332,18 @@ struct mtk_wdma_desc { - #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10) - #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4) - -+#define MTK_WED_WDMA_RX_PREF_CFG 0x950 -+#define MTK_WED_WDMA_RX_PREF_EN BIT(0) -+#define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8) -+#define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16) -+#define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24) -+#define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25) -+#define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26) -+ -+#define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C -+#define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0) -+#define MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR BIT(16) -+ - #define MTK_WED_WDMA_GLO_CFG 0xa04 - #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0) - #define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1) -@@ -325,6 +376,7 @@ struct mtk_wdma_desc { - #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16) - - #define MTK_WED_WDMA_INT_CTRL 0xa2c -+#define MTK_WED_WDMA_INT_POLL_PRD GENMASK(7, 0) - #define MTK_WED_WDMA_INT_CTRL_POLL_SRC_SEL GENMASK(17, 16) - - #define MTK_WED_WDMA_CFG_BASE 0xaa0 -@@ -388,6 +440,18 @@ struct mtk_wdma_desc { - #define MTK_WDMA_INT_GRP1 0x250 - #define MTK_WDMA_INT_GRP2 0x254 - -+#define MTK_WDMA_PREF_TX_CFG 0x2d0 -+#define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0) -+ -+#define MTK_WDMA_PREF_RX_CFG 0x2dc -+#define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0) -+ -+#define MTK_WDMA_WRBK_TX_CFG 0x300 -+#define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30) -+ -+#define MTK_WDMA_WRBK_RX_CFG 0x344 -+#define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30) -+ - #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0) - #define MTK_PCIE_MIRROR_MAP_EN BIT(0) - #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1) -@@ -401,6 +465,30 @@ struct mtk_wdma_desc { - #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5) - #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20) - -+#define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c -+#define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28 -+#define MTK_WED_RTQM_IGRS0_I2H_PKT_CNT(_n) (0xb2c + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS0_FDROP_CNT 0xb34 -+ -+#define MTK_WED_RTQM_IGRS1_I2HW_DMAD_CNT 0xb44 -+#define MTK_WED_RTQM_IGRS1_I2H_DMAD_CNT(_n) (0xb48 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS1_I2HW_PKT_CNT 0xb50 -+#define MTK_WED_RTQM_IGRS1_I2H_PKT_CNT(_n) (0xb54 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS1_FDROP_CNT 0xb5c -+ -+#define MTK_WED_RTQM_IGRS2_I2HW_DMAD_CNT 0xb6c -+#define MTK_WED_RTQM_IGRS2_I2H_DMAD_CNT(_n) (0xb70 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS2_I2HW_PKT_CNT 0xb78 -+#define MTK_WED_RTQM_IGRS2_I2H_PKT_CNT(_n) (0xb7c + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS2_FDROP_CNT 0xb84 -+ -+#define MTK_WED_RTQM_IGRS3_I2HW_DMAD_CNT 0xb94 -+#define MTK_WED_RTQM_IGRS3_I2H_DMAD_CNT(_n) (0xb98 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS3_I2HW_PKT_CNT 0xba0 -+#define MTK_WED_RTQM_IGRS3_I2H_PKT_CNT(_n) (0xba4 + (_n) * 0x4) -+#define MTK_WED_RTQM_IGRS3_FDROP_CNT 0xbac -+ - #define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4) - #define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4) - #define MTK_WED_RTQM_Q2N_MIB 0xb80 -@@ -409,6 +497,24 @@ struct mtk_wdma_desc { - #define MTK_WED_RTQM_Q2B_MIB 0xb8c - #define MTK_WED_RTQM_PFDBK_MIB 0xb90 - -+#define MTK_WED_RTQM_ENQ_CFG0 0xbb8 -+#define MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT GENMASK(15, 12) -+ -+#define MTK_WED_RTQM_FDROP_MIB 0xb84 -+#define MTK_WED_RTQM_ENQ_I2Q_DMAD_CNT 0xbbc -+#define MTK_WED_RTQM_ENQ_I2N_DMAD_CNT 0xbc0 -+#define MTK_WED_RTQM_ENQ_I2Q_PKT_CNT 0xbc4 -+#define MTK_WED_RTQM_ENQ_I2N_PKT_CNT 0xbc8 -+#define MTK_WED_RTQM_ENQ_USED_ENTRY_CNT 0xbcc -+#define MTK_WED_RTQM_ENQ_ERR_CNT 0xbd0 -+ -+#define MTK_WED_RTQM_DEQ_DMAD_CNT 0xbd8 -+#define MTK_WED_RTQM_DEQ_Q2I_DMAD_CNT 0xbdc -+#define MTK_WED_RTQM_DEQ_PKT_CNT 0xbe0 -+#define MTK_WED_RTQM_DEQ_Q2I_PKT_CNT 0xbe4 -+#define MTK_WED_RTQM_DEQ_USED_PFDBK_CNT 0xbe8 -+#define MTK_WED_RTQM_DEQ_ERR_CNT 0xbec -+ - #define MTK_WED_RROQM_GLO_CFG 0xc04 - #define MTK_WED_RROQM_RST_IDX 0xc08 - #define MTK_WED_RROQM_RST_IDX_MIOD BIT(0) -@@ -458,7 +564,116 @@ struct mtk_wdma_desc { - #define MTK_WED_RX_BM_INTF 0xd9c - #define MTK_WED_RX_BM_ERR_STS 0xda8 - -+#define MTK_RRO_IND_CMD_SIGNATURE 0xe00 -+#define MTK_RRO_IND_CMD_DMA_IDX GENMASK(11, 0) -+#define MTK_RRO_IND_CMD_MAGIC_CNT GENMASK(30, 28) -+ -+#define MTK_WED_IND_CMD_RX_CTRL0 0xe04 -+#define MTK_WED_IND_CMD_PROC_IDX GENMASK(11, 0) -+#define MTK_WED_IND_CMD_PREFETCH_FREE_CNT GENMASK(19, 16) -+#define MTK_WED_IND_CMD_MAGIC_CNT GENMASK(30, 28) -+ -+#define MTK_WED_IND_CMD_RX_CTRL1 0xe08 -+#define MTK_WED_IND_CMD_RX_CTRL2 0xe0c -+#define MTK_WED_IND_CMD_MAX_CNT GENMASK(11, 0) -+#define MTK_WED_IND_CMD_BASE_M GENMASK(19, 16) -+ -+#define MTK_WED_RRO_CFG0 0xe10 -+#define MTK_WED_RRO_CFG1 0xe14 -+#define MTK_WED_RRO_CFG1_MAX_WIN_SZ GENMASK(31, 29) -+#define MTK_WED_RRO_CFG1_ACK_SN_BASE_M GENMASK(19, 16) -+#define MTK_WED_RRO_CFG1_PARTICL_SE_ID GENMASK(11, 0) -+ -+#define MTK_WED_ADDR_ELEM_CFG0 0xe18 -+#define MTK_WED_ADDR_ELEM_CFG1 0xe1c -+#define MTK_WED_ADDR_ELEM_PREFETCH_FREE_CNT GENMASK(19, 16) -+ -+#define MTK_WED_ADDR_ELEM_TBL_CFG 0xe20 -+#define MTK_WED_ADDR_ELEM_TBL_OFFSET GENMASK(6, 0) -+#define MTK_WED_ADDR_ELEM_TBL_RD_RDY BIT(28) -+#define MTK_WED_ADDR_ELEM_TBL_WR_RDY BIT(29) -+#define MTK_WED_ADDR_ELEM_TBL_RD BIT(30) -+#define MTK_WED_ADDR_ELEM_TBL_WR BIT(31) -+ -+#define MTK_WED_RADDR_ELEM_TBL_WDATA 0xe24 -+#define MTK_WED_RADDR_ELEM_TBL_RDATA 0xe28 -+ -+#define MTK_WED_PN_CHECK_CFG 0xe30 -+#define MTK_WED_PN_CHECK_SE_ID GENMASK(11, 0) -+#define MTK_WED_PN_CHECK_RD_RDY BIT(28) -+#define MTK_WED_PN_CHECK_WR_RDY BIT(29) -+#define MTK_WED_PN_CHECK_RD BIT(30) -+#define MTK_WED_PN_CHECK_WR BIT(31) -+ -+#define MTK_WED_PN_CHECK_WDATA_M 0xe38 -+#define MTK_WED_PN_CHECK_IS_FIRST BIT(17) -+ -+#define MTK_WED_RRO_MSDU_PG_RING_CFG(_n) (0xe44 + (_n) * 0x8) -+ -+#define MTK_WED_RRO_MSDU_PG_RING2_CFG 0xe58 -+#define MTK_WED_RRO_MSDU_PG_DRV_CLR BIT(26) -+#define MTK_WED_RRO_MSDU_PG_DRV_EN BIT(31) -+ -+#define MTK_WED_RRO_MSDU_PG_CTRL0(_n) (0xe5c + (_n) * 0xc) -+#define MTK_WED_RRO_MSDU_PG_CTRL1(_n) (0xe60 + (_n) * 0xc) -+#define MTK_WED_RRO_MSDU_PG_CTRL2(_n) (0xe64 + (_n) * 0xc) -+ -+#define MTK_WED_RRO_RX_D_RX(_n) (0xe80 + (_n) * 0x10) -+ -+#define MTK_WED_RRO_RX_MAGIC_CNT BIT(13) -+ -+#define MTK_WED_RRO_RX_D_CFG(_n) (0xea0 + (_n) * 0x4) -+#define MTK_WED_RRO_RX_D_DRV_CLR BIT(26) -+#define MTK_WED_RRO_RX_D_DRV_EN BIT(31) -+ -+#define MTK_WED_RRO_PG_BM_RX_DMAM 0xeb0 -+#define MTK_WED_RRO_PG_BM_RX_SDL0 GENMASK(13, 0) -+ -+#define MTK_WED_RRO_PG_BM_BASE 0xeb4 -+#define MTK_WED_RRO_PG_BM_INIT_PTR 0xeb8 -+#define MTK_WED_RRO_PG_BM_SW_TAIL_IDX GENMASK(15, 0) -+#define MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX BIT(16) -+ -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX 0xeec -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN BIT(0) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR BIT(1) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG GENMASK(6, 2) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN BIT(8) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR BIT(9) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG GENMASK(14, 10) -+ -+#define MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG 0xef4 -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN BIT(0) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR BIT(1) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG GENMASK(6, 2) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN BIT(8) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR BIT(9) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG GENMASK(14, 10) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN BIT(16) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17) -+#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18) -+ -+#define MTK_WED_RX_IND_CMD_CNT0 0xf20 -+#define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31) -+ -+#define MTK_WED_RX_IND_CMD_CNT(_n) (0xf20 + (_n) * 0x4) -+#define MTK_WED_IND_CMD_MAGIC_CNT_FAIL_CNT GENMASK(15, 0) -+ -+#define MTK_WED_RX_ADDR_ELEM_CNT(_n) (0xf48 + (_n) * 0x4) -+#define MTK_WED_ADDR_ELEM_SIG_FAIL_CNT GENMASK(15, 0) -+#define MTK_WED_ADDR_ELEM_FIRST_SIG_FAIL_CNT GENMASK(31, 16) -+#define MTK_WED_ADDR_ELEM_ACKSN_CNT GENMASK(27, 0) -+ -+#define MTK_WED_RX_MSDU_PG_CNT(_n) (0xf5c + (_n) * 0x4) -+ -+#define MTK_WED_RX_PN_CHK_CNT 0xf70 -+#define MTK_WED_PN_CHK_FAIL_CNT GENMASK(15, 0) -+ - #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000 - #define MTK_WED_PCIE_INT_MASK 0x0 - -+#define MTK_WED_PCIE_BASE 0x11280000 -+#define MTK_WED_PCIE_BASE0 0x11300000 -+#define MTK_WED_PCIE_BASE1 0x11310000 -+#define MTK_WED_PCIE_BASE2 0x11290000 - #endif ---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h -@@ -91,6 +91,8 @@ enum mtk_wed_dummy_cr_idx { - #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin" - #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" - #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" -+#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin" -+#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin" - - #define MTK_WO_MCU_CFG_LS_BASE 0 - #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000) ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -139,6 +139,8 @@ struct mtk_wed_device { - u32 wpdma_rx; - - bool wcid_512; -+ bool hw_rro; -+ bool msi; - - u16 token_start; - unsigned int nbuf; -@@ -212,10 +214,12 @@ mtk_wed_device_attach(struct mtk_wed_dev - return ret; - } - --static inline bool --mtk_wed_get_rx_capa(struct mtk_wed_device *dev) -+static inline bool mtk_wed_get_rx_capa(struct mtk_wed_device *dev) - { - #ifdef CONFIG_NET_MEDIATEK_SOC_WED -+ if (dev->version == 3) -+ return dev->wlan.hw_rro; -+ - return dev->version != 1; - #else - return false; diff --git a/target/linux/generic/backport-6.1/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch b/target/linux/generic/backport-6.1/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch deleted file mode 100644 index e91ae69d0811de..00000000000000 --- a/target/linux/generic/backport-6.1/752-15-v6.7-net-ethernet-mtk_wed-refactor-mtk_wed_check_wfdma_rx.patch +++ /dev/null @@ -1,95 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:14 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: refactor mtk_wed_check_wfdma_rx_fill - routine - -Refactor mtk_wed_check_wfdma_rx_fill() in order to be reused adding HW -receive offload support for MT7988 SoC. - -Co-developed-by: Sujuan Chen -Signed-off-by: Sujuan Chen -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -585,22 +585,15 @@ mtk_wed_set_512_support(struct mtk_wed_d - } - } - --#define MTK_WFMDA_RX_DMA_EN BIT(2) --static void --mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx) -+static int -+mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, -+ struct mtk_wed_ring *ring) - { -- u32 val; - int i; - -- if (!(dev->rx_ring[idx].flags & MTK_WED_RING_CONFIGURED)) -- return; /* queue is not configured by mt76 */ -- - for (i = 0; i < 3; i++) { -- u32 cur_idx; -+ u32 cur_idx = readl(ring->wpdma + MTK_WED_RING_OFS_CPU_IDX); - -- cur_idx = wed_r32(dev, -- MTK_WED_WPDMA_RING_RX_DATA(idx) + -- MTK_WED_RING_OFS_CPU_IDX); - if (cur_idx == MTK_WED_RX_RING_SIZE - 1) - break; - -@@ -609,12 +602,10 @@ mtk_wed_check_wfdma_rx_fill(struct mtk_w - - if (i == 3) { - dev_err(dev->hw->dev, "rx dma enable failed\n"); -- return; -+ return -ETIMEDOUT; - } - -- val = wifi_r32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base) | -- MTK_WFMDA_RX_DMA_EN; -- wifi_w32(dev, dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, val); -+ return 0; - } - - static void -@@ -1545,6 +1536,7 @@ mtk_wed_configure_irq(struct mtk_wed_dev - wed_w32(dev, MTK_WED_INT_MASK, irq_mask); - } - -+#define MTK_WFMDA_RX_DMA_EN BIT(2) - static void - mtk_wed_dma_enable(struct mtk_wed_device *dev) - { -@@ -1632,8 +1624,26 @@ mtk_wed_dma_enable(struct mtk_wed_device - wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); - } - -- for (i = 0; i < MTK_WED_RX_QUEUES; i++) -- mtk_wed_check_wfdma_rx_fill(dev, i); -+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) { -+ struct mtk_wed_ring *ring = &dev->rx_ring[i]; -+ u32 val; -+ -+ if (!(ring->flags & MTK_WED_RING_CONFIGURED)) -+ continue; /* queue is not configured by mt76 */ -+ -+ if (mtk_wed_check_wfdma_rx_fill(dev, ring)) { -+ dev_err(dev->hw->dev, -+ "rx_ring(%d) dma enable failed\n", i); -+ continue; -+ } -+ -+ val = wifi_r32(dev, -+ dev->wlan.wpdma_rx_glo - -+ dev->wlan.phy_base) | MTK_WFMDA_RX_DMA_EN; -+ wifi_w32(dev, -+ dev->wlan.wpdma_rx_glo - dev->wlan.phy_base, -+ val); -+ } - } - - static void diff --git a/target/linux/generic/backport-6.1/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch b/target/linux/generic/backport-6.1/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch deleted file mode 100644 index 6534d73d8e7698..00000000000000 --- a/target/linux/generic/backport-6.1/752-16-v6.7-net-ethernet-mtk_wed-introduce-partial-AMSDU-offload.patch +++ /dev/null @@ -1,465 +0,0 @@ -From: Sujuan Chen -Date: Mon, 18 Sep 2023 12:29:15 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: introduce partial AMSDU offload - support for MT7988 - -Introduce partial AMSDU offload support for MT7988 SoC in order to merge -in hw packets belonging to the same AMSDU before passing them to the -WLAN nic. - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -438,7 +438,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e - } - - int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, -- int wdma_idx, int txq, int bss, int wcid) -+ int wdma_idx, int txq, int bss, int wcid, -+ bool amsdu_en) - { - struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry); - u32 *ib2 = mtk_foe_entry_ib2(eth, entry); -@@ -450,6 +451,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et - MTK_FOE_IB2_WDMA_WINFO_V2; - l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) | - FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss); -+ l2->amsdu = FIELD_PREP(MTK_FOE_WINFO_AMSDU_EN, amsdu_en); - break; - case 2: - *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2; ---- a/drivers/net/ethernet/mediatek/mtk_ppe.h -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h -@@ -88,13 +88,13 @@ enum { - #define MTK_FOE_WINFO_BSS_V3 GENMASK(23, 16) - #define MTK_FOE_WINFO_WCID_V3 GENMASK(15, 0) - --#define MTK_FOE_WINFO_PAO_USR_INFO GENMASK(15, 0) --#define MTK_FOE_WINFO_PAO_TID GENMASK(19, 16) --#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE BIT(20) --#define MTK_FOE_WINFO_PAO_IS_PRIOR BIT(21) --#define MTK_FOE_WINFO_PAO_IS_SP BIT(22) --#define MTK_FOE_WINFO_PAO_HF BIT(23) --#define MTK_FOE_WINFO_PAO_AMSDU_EN BIT(24) -+#define MTK_FOE_WINFO_AMSDU_USR_INFO GENMASK(15, 0) -+#define MTK_FOE_WINFO_AMSDU_TID GENMASK(19, 16) -+#define MTK_FOE_WINFO_AMSDU_IS_FIXEDRATE BIT(20) -+#define MTK_FOE_WINFO_AMSDU_IS_PRIOR BIT(21) -+#define MTK_FOE_WINFO_AMSDU_IS_SP BIT(22) -+#define MTK_FOE_WINFO_AMSDU_HF BIT(23) -+#define MTK_FOE_WINFO_AMSDU_EN BIT(24) - - enum { - MTK_FOE_STATE_INVALID, -@@ -123,7 +123,7 @@ struct mtk_foe_mac_info { - - /* netsys_v3 */ - u32 w3info; -- u32 wpao; -+ u32 amsdu; - }; - - /* software-only entry type */ -@@ -394,7 +394,8 @@ int mtk_foe_entry_set_vlan(struct mtk_et - int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry, - int sid); - int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry, -- int wdma_idx, int txq, int bss, int wcid); -+ int wdma_idx, int txq, int bss, int wcid, -+ bool amsdu_en); - int mtk_foe_entry_set_queue(struct mtk_eth *eth, struct mtk_foe_entry *entry, - unsigned int queue); - int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry); ---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c -@@ -111,6 +111,7 @@ mtk_flow_get_wdma_info(struct net_device - info->queue = path->mtk_wdma.queue; - info->bss = path->mtk_wdma.bss; - info->wcid = path->mtk_wdma.wcid; -+ info->amsdu = path->mtk_wdma.amsdu; - - return 0; - } -@@ -192,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et - - if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) { - mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue, -- info.bss, info.wcid); -+ info.bss, info.wcid, info.amsdu); - if (mtk_is_netsys_v2_or_greater(eth)) { - switch (info.wdma_idx) { - case 0: ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -29,6 +29,8 @@ - #define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128) - #define MTK_WED_RX_RING_SIZE 1536 - #define MTK_WED_RX_PG_BM_CNT 8192 -+#define MTK_WED_AMSDU_BUF_SIZE (PAGE_SIZE << 4) -+#define MTK_WED_AMSDU_NPAGES 32 - - #define MTK_WED_TX_RING_SIZE 2048 - #define MTK_WED_WDMA_RING_SIZE 1024 -@@ -172,6 +174,23 @@ mtk_wdma_rx_reset(struct mtk_wed_device - return ret; - } - -+static u32 -+mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) -+{ -+ return !!(wed_r32(dev, reg) & mask); -+} -+ -+static int -+mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) -+{ -+ int sleep = 15000; -+ int timeout = 100 * sleep; -+ u32 val; -+ -+ return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep, -+ timeout, false, dev, reg, mask); -+} -+ - static void - mtk_wdma_tx_reset(struct mtk_wed_device *dev) - { -@@ -335,6 +354,118 @@ out: - } - - static int -+mtk_wed_amsdu_buffer_alloc(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_hw *hw = dev->hw; -+ struct mtk_wed_amsdu *wed_amsdu; -+ int i; -+ -+ if (!mtk_wed_is_v3_or_greater(hw)) -+ return 0; -+ -+ wed_amsdu = devm_kcalloc(hw->dev, MTK_WED_AMSDU_NPAGES, -+ sizeof(*wed_amsdu), GFP_KERNEL); -+ if (!wed_amsdu) -+ return -ENOMEM; -+ -+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) { -+ void *ptr; -+ -+ /* each segment is 64K */ -+ ptr = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | -+ __GFP_ZERO | __GFP_COMP | -+ GFP_DMA32, -+ get_order(MTK_WED_AMSDU_BUF_SIZE)); -+ if (!ptr) -+ goto error; -+ -+ wed_amsdu[i].txd = ptr; -+ wed_amsdu[i].txd_phy = dma_map_single(hw->dev, ptr, -+ MTK_WED_AMSDU_BUF_SIZE, -+ DMA_TO_DEVICE); -+ if (dma_mapping_error(hw->dev, wed_amsdu[i].txd_phy)) -+ goto error; -+ } -+ dev->hw->wed_amsdu = wed_amsdu; -+ -+ return 0; -+ -+error: -+ for (i--; i >= 0; i--) -+ dma_unmap_single(hw->dev, wed_amsdu[i].txd_phy, -+ MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE); -+ return -ENOMEM; -+} -+ -+static void -+mtk_wed_amsdu_free_buffer(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu; -+ int i; -+ -+ if (!wed_amsdu) -+ return; -+ -+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) { -+ dma_unmap_single(dev->hw->dev, wed_amsdu[i].txd_phy, -+ MTK_WED_AMSDU_BUF_SIZE, DMA_TO_DEVICE); -+ free_pages((unsigned long)wed_amsdu[i].txd, -+ get_order(MTK_WED_AMSDU_BUF_SIZE)); -+ } -+} -+ -+static int -+mtk_wed_amsdu_init(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_amsdu *wed_amsdu = dev->hw->wed_amsdu; -+ int i, ret; -+ -+ if (!wed_amsdu) -+ return 0; -+ -+ for (i = 0; i < MTK_WED_AMSDU_NPAGES; i++) -+ wed_w32(dev, MTK_WED_AMSDU_HIFTXD_BASE_L(i), -+ wed_amsdu[i].txd_phy); -+ -+ /* init all sta parameter */ -+ wed_w32(dev, MTK_WED_AMSDU_STA_INFO_INIT, MTK_WED_AMSDU_STA_RMVL | -+ MTK_WED_AMSDU_STA_WTBL_HDRT_MODE | -+ FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_LEN, -+ dev->wlan.amsdu_max_len >> 8) | -+ FIELD_PREP(MTK_WED_AMSDU_STA_MAX_AMSDU_NUM, -+ dev->wlan.amsdu_max_subframes)); -+ -+ wed_w32(dev, MTK_WED_AMSDU_STA_INFO, MTK_WED_AMSDU_STA_INFO_DO_INIT); -+ -+ ret = mtk_wed_poll_busy(dev, MTK_WED_AMSDU_STA_INFO, -+ MTK_WED_AMSDU_STA_INFO_DO_INIT); -+ if (ret) { -+ dev_err(dev->hw->dev, "amsdu initialization failed\n"); -+ return ret; -+ } -+ -+ /* init partial amsdu offload txd src */ -+ wed_set(dev, MTK_WED_AMSDU_HIFTXD_CFG, -+ FIELD_PREP(MTK_WED_AMSDU_HIFTXD_SRC, dev->hw->index)); -+ -+ /* init qmem */ -+ wed_set(dev, MTK_WED_AMSDU_PSE, MTK_WED_AMSDU_PSE_RESET); -+ ret = mtk_wed_poll_busy(dev, MTK_WED_MON_AMSDU_QMEM_STS1, BIT(29)); -+ if (ret) { -+ pr_info("%s: amsdu qmem initialization failed\n", __func__); -+ return ret; -+ } -+ -+ /* eagle E1 PCIE1 tx ring 22 flow control issue */ -+ if (dev->wlan.id == 0x7991) -+ wed_clr(dev, MTK_WED_AMSDU_FIFO, MTK_WED_AMSDU_IS_PRIOR0_RING); -+ -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN); -+ -+ return 0; -+} -+ -+static int - mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) - { - u32 desc_size = dev->hw->soc->tx_ring_desc_size; -@@ -708,6 +839,7 @@ __mtk_wed_detach(struct mtk_wed_device * - - mtk_wdma_rx_reset(dev); - mtk_wed_reset(dev, MTK_WED_RESET_WED); -+ mtk_wed_amsdu_free_buffer(dev); - mtk_wed_free_tx_buffer(dev); - mtk_wed_free_tx_rings(dev); - -@@ -1128,23 +1260,6 @@ mtk_wed_ring_reset(struct mtk_wed_ring * - } - } - --static u32 --mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) --{ -- return !!(wed_r32(dev, reg) & mask); --} -- --static int --mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask) --{ -- int sleep = 15000; -- int timeout = 100 * sleep; -- u32 val; -- -- return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep, -- timeout, false, dev, reg, mask); --} -- - static int - mtk_wed_rx_reset(struct mtk_wed_device *dev) - { -@@ -1691,6 +1806,7 @@ mtk_wed_start(struct mtk_wed_device *dev - } - - mtk_wed_set_512_support(dev, dev->wlan.wcid_512); -+ mtk_wed_amsdu_init(dev); - - mtk_wed_dma_enable(dev); - dev->running = true; -@@ -1747,6 +1863,10 @@ mtk_wed_attach(struct mtk_wed_device *de - if (ret) - goto out; - -+ ret = mtk_wed_amsdu_buffer_alloc(dev); -+ if (ret) -+ goto out; -+ - if (mtk_wed_get_rx_capa(dev)) { - ret = mtk_wed_rro_alloc(dev); - if (ret) ---- a/drivers/net/ethernet/mediatek/mtk_wed.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed.h -@@ -25,6 +25,11 @@ struct mtk_wed_soc_data { - u32 wdma_desc_size; - }; - -+struct mtk_wed_amsdu { -+ void *txd; -+ dma_addr_t txd_phy; -+}; -+ - struct mtk_wed_hw { - const struct mtk_wed_soc_data *soc; - struct device_node *node; -@@ -38,6 +43,7 @@ struct mtk_wed_hw { - struct dentry *debugfs_dir; - struct mtk_wed_device *wed_dev; - struct mtk_wed_wo *wed_wo; -+ struct mtk_wed_amsdu *wed_amsdu; - u32 pcie_base; - u32 debugfs_reg; - u32 num_flows; -@@ -52,6 +58,7 @@ struct mtk_wdma_info { - u8 queue; - u16 wcid; - u8 bss; -+ u8 amsdu; - }; - - #ifdef CONFIG_NET_MEDIATEK_SOC_WED ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -672,6 +672,82 @@ struct mtk_wdma_desc { - #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000 - #define MTK_WED_PCIE_INT_MASK 0x0 - -+#define MTK_WED_AMSDU_FIFO 0x1800 -+#define MTK_WED_AMSDU_IS_PRIOR0_RING BIT(10) -+ -+#define MTK_WED_AMSDU_STA_INFO 0x01810 -+#define MTK_WED_AMSDU_STA_INFO_DO_INIT BIT(0) -+#define MTK_WED_AMSDU_STA_INFO_SET_INIT BIT(1) -+ -+#define MTK_WED_AMSDU_STA_INFO_INIT 0x01814 -+#define MTK_WED_AMSDU_STA_WTBL_HDRT_MODE BIT(0) -+#define MTK_WED_AMSDU_STA_RMVL BIT(1) -+#define MTK_WED_AMSDU_STA_MAX_AMSDU_LEN GENMASK(7, 2) -+#define MTK_WED_AMSDU_STA_MAX_AMSDU_NUM GENMASK(11, 8) -+ -+#define MTK_WED_AMSDU_HIFTXD_BASE_L(_n) (0x1980 + (_n) * 0x4) -+ -+#define MTK_WED_AMSDU_PSE 0x1910 -+#define MTK_WED_AMSDU_PSE_RESET BIT(16) -+ -+#define MTK_WED_AMSDU_HIFTXD_CFG 0x1968 -+#define MTK_WED_AMSDU_HIFTXD_SRC GENMASK(16, 15) -+ -+#define MTK_WED_MON_AMSDU_FIFO_DMAD 0x1a34 -+ -+#define MTK_WED_MON_AMSDU_ENG_DMAD(_n) (0x1a80 + (_n) * 0x50) -+#define MTK_WED_MON_AMSDU_ENG_QFPL(_n) (0x1a84 + (_n) * 0x50) -+#define MTK_WED_MON_AMSDU_ENG_QENI(_n) (0x1a88 + (_n) * 0x50) -+#define MTK_WED_MON_AMSDU_ENG_QENO(_n) (0x1a8c + (_n) * 0x50) -+#define MTK_WED_MON_AMSDU_ENG_MERG(_n) (0x1a90 + (_n) * 0x50) -+ -+#define MTK_WED_MON_AMSDU_ENG_CNT8(_n) (0x1a94 + (_n) * 0x50) -+#define MTK_WED_AMSDU_ENG_MAX_QGPP_CNT GENMASK(10, 0) -+#define MTK_WED_AMSDU_ENG_MAX_PL_CNT GENMASK(27, 16) -+ -+#define MTK_WED_MON_AMSDU_ENG_CNT9(_n) (0x1a98 + (_n) * 0x50) -+#define MTK_WED_AMSDU_ENG_CUR_ENTRY GENMASK(10, 0) -+#define MTK_WED_AMSDU_ENG_MAX_BUF_MERGED GENMASK(20, 16) -+#define MTK_WED_AMSDU_ENG_MAX_MSDU_MERGED GENMASK(28, 24) -+ -+#define MTK_WED_MON_AMSDU_QMEM_STS1 0x1e04 -+ -+#define MTK_WED_MON_AMSDU_QMEM_CNT(_n) (0x1e0c + (_n) * 0x4) -+#define MTK_WED_AMSDU_QMEM_FQ_CNT GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_SP_QCNT GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID0_QCNT GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID1_QCNT GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID2_QCNT GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID3_QCNT GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID4_QCNT GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID5_QCNT GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID6_QCNT GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID7_QCNT GENMASK(11, 0) -+ -+#define MTK_WED_MON_AMSDU_QMEM_PTR(_n) (0x1e20 + (_n) * 0x4) -+#define MTK_WED_AMSDU_QMEM_FQ_HEAD GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_SP_QHEAD GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID0_QHEAD GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID1_QHEAD GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID2_QHEAD GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID3_QHEAD GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID4_QHEAD GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID5_QHEAD GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID6_QHEAD GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID7_QHEAD GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_FQ_TAIL GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_SP_QTAIL GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID0_QTAIL GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID1_QTAIL GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID2_QTAIL GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID3_QTAIL GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID4_QTAIL GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID5_QTAIL GENMASK(11, 0) -+#define MTK_WED_AMSDU_QMEM_TID6_QTAIL GENMASK(27, 16) -+#define MTK_WED_AMSDU_QMEM_TID7_QTAIL GENMASK(11, 0) -+ -+#define MTK_WED_MON_AMSDU_HIFTXD_FETCH_MSDU(_n) (0x1ec4 + (_n) * 0x4) -+ - #define MTK_WED_PCIE_BASE 0x11280000 - #define MTK_WED_PCIE_BASE0 0x11300000 - #define MTK_WED_PCIE_BASE1 0x11310000 ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -928,6 +928,7 @@ struct net_device_path { - u8 queue; - u16 wcid; - u8 bss; -+ u8 amsdu; - } mtk_wdma; - }; - }; ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -129,6 +129,7 @@ struct mtk_wed_device { - enum mtk_wed_bus_tye bus_type; - void __iomem *base; - u32 phy_base; -+ u32 id; - - u32 wpdma_phys; - u32 wpdma_int; -@@ -147,10 +148,12 @@ struct mtk_wed_device { - unsigned int rx_nbuf; - unsigned int rx_npkt; - unsigned int rx_size; -+ unsigned int amsdu_max_len; - - u8 tx_tbit[MTK_WED_TX_QUEUES]; - u8 rx_tbit[MTK_WED_RX_QUEUES]; - u8 txfree_tbit; -+ u8 amsdu_max_subframes; - - u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); - int (*offload_enable)(struct mtk_wed_device *wed); -@@ -224,6 +227,15 @@ static inline bool mtk_wed_get_rx_capa(s - #else - return false; - #endif -+} -+ -+static inline bool mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev) -+{ -+#ifdef CONFIG_NET_MEDIATEK_SOC_WED -+ return dev->version == 3; -+#else -+ return false; -+#endif - } - - #ifdef CONFIG_NET_MEDIATEK_SOC_WED diff --git a/target/linux/generic/backport-6.1/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch b/target/linux/generic/backport-6.1/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch deleted file mode 100644 index 0cf4c188757ec7..00000000000000 --- a/target/linux/generic/backport-6.1/752-17-v6.7-net-ethernet-mtk_wed-introduce-hw_rro-support-for-MT.patch +++ /dev/null @@ -1,483 +0,0 @@ -From: Sujuan Chen -Date: Mon, 18 Sep 2023 12:29:16 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: introduce hw_rro support for MT7988 - -MT7988 SoC support 802.11 receive reordering offload in hw while -MT7986 SoC implements it through the firmware running on the mcu. - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -26,7 +26,7 @@ - #define MTK_WED_BUF_SIZE 2048 - #define MTK_WED_PAGE_BUF_SIZE 128 - #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048) --#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128) -+#define MTK_WED_RX_BUF_PER_PAGE (PAGE_SIZE / MTK_WED_PAGE_BUF_SIZE) - #define MTK_WED_RX_RING_SIZE 1536 - #define MTK_WED_RX_PG_BM_CNT 8192 - #define MTK_WED_AMSDU_BUF_SIZE (PAGE_SIZE << 4) -@@ -596,6 +596,68 @@ free_pagelist: - } - - static int -+mtk_wed_hwrro_buffer_alloc(struct mtk_wed_device *dev) -+{ -+ int n_pages = MTK_WED_RX_PG_BM_CNT / MTK_WED_RX_BUF_PER_PAGE; -+ struct mtk_wed_buf *page_list; -+ struct mtk_wed_bm_desc *desc; -+ dma_addr_t desc_phys; -+ int i, page_idx = 0; -+ -+ if (!dev->wlan.hw_rro) -+ return 0; -+ -+ page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL); -+ if (!page_list) -+ return -ENOMEM; -+ -+ dev->hw_rro.size = dev->wlan.rx_nbuf & ~(MTK_WED_BUF_PER_PAGE - 1); -+ dev->hw_rro.pages = page_list; -+ desc = dma_alloc_coherent(dev->hw->dev, -+ dev->wlan.rx_nbuf * sizeof(*desc), -+ &desc_phys, GFP_KERNEL); -+ if (!desc) -+ return -ENOMEM; -+ -+ dev->hw_rro.desc = desc; -+ dev->hw_rro.desc_phys = desc_phys; -+ -+ for (i = 0; i < MTK_WED_RX_PG_BM_CNT; i += MTK_WED_RX_BUF_PER_PAGE) { -+ dma_addr_t page_phys, buf_phys; -+ struct page *page; -+ int s; -+ -+ page = __dev_alloc_page(GFP_KERNEL); -+ if (!page) -+ return -ENOMEM; -+ -+ page_phys = dma_map_page(dev->hw->dev, page, 0, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ if (dma_mapping_error(dev->hw->dev, page_phys)) { -+ __free_page(page); -+ return -ENOMEM; -+ } -+ -+ page_list[page_idx].p = page; -+ page_list[page_idx++].phy_addr = page_phys; -+ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ -+ buf_phys = page_phys; -+ for (s = 0; s < MTK_WED_RX_BUF_PER_PAGE; s++) { -+ desc->buf0 = cpu_to_le32(buf_phys); -+ buf_phys += MTK_WED_PAGE_BUF_SIZE; -+ desc++; -+ } -+ -+ dma_sync_single_for_device(dev->hw->dev, page_phys, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ } -+ -+ return 0; -+} -+ -+static int - mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev) - { - struct mtk_wed_bm_desc *desc; -@@ -612,7 +674,42 @@ mtk_wed_rx_buffer_alloc(struct mtk_wed_d - dev->rx_buf_ring.desc_phys = desc_phys; - dev->wlan.init_rx_buf(dev, dev->wlan.rx_npkt); - -- return 0; -+ return mtk_wed_hwrro_buffer_alloc(dev); -+} -+ -+static void -+mtk_wed_hwrro_free_buffer(struct mtk_wed_device *dev) -+{ -+ struct mtk_wed_buf *page_list = dev->hw_rro.pages; -+ struct mtk_wed_bm_desc *desc = dev->hw_rro.desc; -+ int i, page_idx = 0; -+ -+ if (!dev->wlan.hw_rro) -+ return; -+ -+ if (!page_list) -+ return; -+ -+ if (!desc) -+ goto free_pagelist; -+ -+ for (i = 0; i < MTK_WED_RX_PG_BM_CNT; i += MTK_WED_RX_BUF_PER_PAGE) { -+ dma_addr_t buf_addr = page_list[page_idx].phy_addr; -+ void *page = page_list[page_idx++].p; -+ -+ if (!page) -+ break; -+ -+ dma_unmap_page(dev->hw->dev, buf_addr, PAGE_SIZE, -+ DMA_BIDIRECTIONAL); -+ __free_page(page); -+ } -+ -+ dma_free_coherent(dev->hw->dev, dev->hw_rro.size * sizeof(*desc), -+ desc, dev->hw_rro.desc_phys); -+ -+free_pagelist: -+ kfree(page_list); - } - - static void -@@ -626,6 +723,28 @@ mtk_wed_free_rx_buffer(struct mtk_wed_de - dev->wlan.release_rx_buf(dev); - dma_free_coherent(dev->hw->dev, dev->rx_buf_ring.size * sizeof(*desc), - desc, dev->rx_buf_ring.desc_phys); -+ -+ mtk_wed_hwrro_free_buffer(dev); -+} -+ -+static void -+mtk_wed_hwrro_init(struct mtk_wed_device *dev) -+{ -+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro) -+ return; -+ -+ wed_set(dev, MTK_WED_RRO_PG_BM_RX_DMAM, -+ FIELD_PREP(MTK_WED_RRO_PG_BM_RX_SDL0, 128)); -+ -+ wed_w32(dev, MTK_WED_RRO_PG_BM_BASE, dev->hw_rro.desc_phys); -+ -+ wed_w32(dev, MTK_WED_RRO_PG_BM_INIT_PTR, -+ MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX | -+ FIELD_PREP(MTK_WED_RRO_PG_BM_SW_TAIL_IDX, -+ MTK_WED_RX_PG_BM_CNT)); -+ -+ /* enable rx_page_bm to fetch dmad */ -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN); - } - - static void -@@ -639,6 +758,8 @@ mtk_wed_rx_buffer_hw_init(struct mtk_wed - wed_w32(dev, MTK_WED_RX_BM_DYN_ALLOC_TH, - FIELD_PREP(MTK_WED_RX_BM_DYN_ALLOC_TH_H, 0xffff)); - wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN); -+ -+ mtk_wed_hwrro_init(dev); - } - - static void -@@ -934,6 +1055,8 @@ mtk_wed_bus_init(struct mtk_wed_device * - static void - mtk_wed_set_wpdma(struct mtk_wed_device *dev) - { -+ int i; -+ - if (mtk_wed_is_v1(dev->hw)) { - wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys); - return; -@@ -951,6 +1074,15 @@ mtk_wed_set_wpdma(struct mtk_wed_device - - wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo); - wed_w32(dev, dev->hw->soc->regmap.wpdma_rx_ring0, dev->wlan.wpdma_rx); -+ -+ if (!dev->wlan.hw_rro) -+ return; -+ -+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(0), dev->wlan.wpdma_rx_rro[0]); -+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(1), dev->wlan.wpdma_rx_rro[1]); -+ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) -+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING_CFG(i), -+ dev->wlan.wpdma_rx_pg + i * 0x10); - } - - static void -@@ -1762,6 +1894,165 @@ mtk_wed_dma_enable(struct mtk_wed_device - } - - static void -+mtk_wed_start_hw_rro(struct mtk_wed_device *dev, u32 irq_mask, bool reset) -+{ -+ int i; -+ -+ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask); -+ wed_w32(dev, MTK_WED_INT_MASK, irq_mask); -+ -+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro) -+ return; -+ -+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR); -+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_CLR); -+ -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_RX, -+ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN | -+ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR | -+ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN | -+ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG, -+ dev->wlan.rro_rx_tbit[0]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG, -+ dev->wlan.rro_rx_tbit[1])); -+ -+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG, -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN | -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR | -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN | -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR | -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN | -+ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG, -+ dev->wlan.rx_pg_tbit[0]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG, -+ dev->wlan.rx_pg_tbit[1]) | -+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG, -+ dev->wlan.rx_pg_tbit[2])); -+ -+ /* RRO_MSDU_PG_RING2_CFG1_FLD_DRV_EN should be enabled after -+ * WM FWDL completed, otherwise RRO_MSDU_PG ring may broken -+ */ -+ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_EN); -+ -+ for (i = 0; i < MTK_WED_RX_QUEUES; i++) { -+ struct mtk_wed_ring *ring = &dev->rx_rro_ring[i]; -+ -+ if (!(ring->flags & MTK_WED_RING_CONFIGURED)) -+ continue; -+ -+ if (mtk_wed_check_wfdma_rx_fill(dev, ring)) -+ dev_err(dev->hw->dev, -+ "rx_rro_ring(%d) initialization failed\n", i); -+ } -+ -+ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) { -+ struct mtk_wed_ring *ring = &dev->rx_page_ring[i]; -+ -+ if (!(ring->flags & MTK_WED_RING_CONFIGURED)) -+ continue; -+ -+ if (mtk_wed_check_wfdma_rx_fill(dev, ring)) -+ dev_err(dev->hw->dev, -+ "rx_page_ring(%d) initialization failed\n", i); -+ } -+} -+ -+static void -+mtk_wed_rro_rx_ring_setup(struct mtk_wed_device *dev, int idx, -+ void __iomem *regs) -+{ -+ struct mtk_wed_ring *ring = &dev->rx_rro_ring[idx]; -+ -+ ring->wpdma = regs; -+ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_BASE, -+ readl(regs)); -+ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_COUNT, -+ readl(regs + MTK_WED_RING_OFS_COUNT)); -+ ring->flags |= MTK_WED_RING_CONFIGURED; -+} -+ -+static void -+mtk_wed_msdu_pg_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs) -+{ -+ struct mtk_wed_ring *ring = &dev->rx_page_ring[idx]; -+ -+ ring->wpdma = regs; -+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_BASE, -+ readl(regs)); -+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_COUNT, -+ readl(regs + MTK_WED_RING_OFS_COUNT)); -+ ring->flags |= MTK_WED_RING_CONFIGURED; -+} -+ -+static int -+mtk_wed_ind_rx_ring_setup(struct mtk_wed_device *dev, void __iomem *regs) -+{ -+ struct mtk_wed_ring *ring = &dev->ind_cmd_ring; -+ u32 val = readl(regs + MTK_WED_RING_OFS_COUNT); -+ int i, count = 0; -+ -+ ring->wpdma = regs; -+ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_BASE, -+ readl(regs) & 0xfffffff0); -+ -+ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_COUNT, -+ readl(regs + MTK_WED_RING_OFS_COUNT)); -+ -+ /* ack sn cr */ -+ wed_w32(dev, MTK_WED_RRO_CFG0, dev->wlan.phy_base + -+ dev->wlan.ind_cmd.ack_sn_addr); -+ wed_w32(dev, MTK_WED_RRO_CFG1, -+ FIELD_PREP(MTK_WED_RRO_CFG1_MAX_WIN_SZ, -+ dev->wlan.ind_cmd.win_size) | -+ FIELD_PREP(MTK_WED_RRO_CFG1_PARTICL_SE_ID, -+ dev->wlan.ind_cmd.particular_sid)); -+ -+ /* particular session addr element */ -+ wed_w32(dev, MTK_WED_ADDR_ELEM_CFG0, -+ dev->wlan.ind_cmd.particular_se_phys); -+ -+ for (i = 0; i < dev->wlan.ind_cmd.se_group_nums; i++) { -+ wed_w32(dev, MTK_WED_RADDR_ELEM_TBL_WDATA, -+ dev->wlan.ind_cmd.addr_elem_phys[i] >> 4); -+ wed_w32(dev, MTK_WED_ADDR_ELEM_TBL_CFG, -+ MTK_WED_ADDR_ELEM_TBL_WR | (i & 0x7f)); -+ -+ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG); -+ while (!(val & MTK_WED_ADDR_ELEM_TBL_WR_RDY) && count++ < 100) -+ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG); -+ if (count >= 100) -+ dev_err(dev->hw->dev, -+ "write ba session base failed\n"); -+ } -+ -+ /* pn check init */ -+ for (i = 0; i < dev->wlan.ind_cmd.particular_sid; i++) { -+ wed_w32(dev, MTK_WED_PN_CHECK_WDATA_M, -+ MTK_WED_PN_CHECK_IS_FIRST); -+ -+ wed_w32(dev, MTK_WED_PN_CHECK_CFG, MTK_WED_PN_CHECK_WR | -+ FIELD_PREP(MTK_WED_PN_CHECK_SE_ID, i)); -+ -+ count = 0; -+ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG); -+ while (!(val & MTK_WED_PN_CHECK_WR_RDY) && count++ < 100) -+ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG); -+ if (count >= 100) -+ dev_err(dev->hw->dev, -+ "session(%d) initialization failed\n", i); -+ } -+ -+ wed_w32(dev, MTK_WED_RX_IND_CMD_CNT0, MTK_WED_RX_IND_CMD_DBG_CNT_EN); -+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN); -+ -+ return 0; -+} -+ -+static void - mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask) - { - int i; -@@ -2215,6 +2506,10 @@ void mtk_wed_add_hw(struct device_node * - .detach = mtk_wed_detach, - .ppe_check = mtk_wed_ppe_check, - .setup_tc = mtk_wed_setup_tc, -+ .start_hw_rro = mtk_wed_start_hw_rro, -+ .rro_rx_ring_setup = mtk_wed_rro_rx_ring_setup, -+ .msdu_pg_rx_ring_setup = mtk_wed_msdu_pg_rx_ring_setup, -+ .ind_rx_ring_setup = mtk_wed_ind_rx_ring_setup, - }; - struct device_node *eth_np = eth->dev->of_node; - struct platform_device *pdev; ---- a/include/linux/soc/mediatek/mtk_wed.h -+++ b/include/linux/soc/mediatek/mtk_wed.h -@@ -10,6 +10,7 @@ - - #define MTK_WED_TX_QUEUES 2 - #define MTK_WED_RX_QUEUES 2 -+#define MTK_WED_RX_PAGE_QUEUES 3 - - #define WED_WO_STA_REC 0x6 - -@@ -99,6 +100,9 @@ struct mtk_wed_device { - struct mtk_wed_ring txfree_ring; - struct mtk_wed_ring tx_wdma[MTK_WED_TX_QUEUES]; - struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES]; -+ struct mtk_wed_ring rx_rro_ring[MTK_WED_RX_QUEUES]; -+ struct mtk_wed_ring rx_page_ring[MTK_WED_RX_PAGE_QUEUES]; -+ struct mtk_wed_ring ind_cmd_ring; - - struct { - int size; -@@ -120,6 +124,13 @@ struct mtk_wed_device { - dma_addr_t fdbk_phys; - } rro; - -+ struct { -+ int size; -+ struct mtk_wed_buf *pages; -+ struct mtk_wed_bm_desc *desc; -+ dma_addr_t desc_phys; -+ } hw_rro; -+ - /* filled by driver: */ - struct { - union { -@@ -138,6 +149,8 @@ struct mtk_wed_device { - u32 wpdma_txfree; - u32 wpdma_rx_glo; - u32 wpdma_rx; -+ u32 wpdma_rx_rro[MTK_WED_RX_QUEUES]; -+ u32 wpdma_rx_pg; - - bool wcid_512; - bool hw_rro; -@@ -152,9 +165,20 @@ struct mtk_wed_device { - - u8 tx_tbit[MTK_WED_TX_QUEUES]; - u8 rx_tbit[MTK_WED_RX_QUEUES]; -+ u8 rro_rx_tbit[MTK_WED_RX_QUEUES]; -+ u8 rx_pg_tbit[MTK_WED_RX_PAGE_QUEUES]; - u8 txfree_tbit; - u8 amsdu_max_subframes; - -+ struct { -+ u8 se_group_nums; -+ u16 win_size; -+ u16 particular_sid; -+ u32 ack_sn_addr; -+ dma_addr_t particular_se_phys; -+ dma_addr_t addr_elem_phys[1024]; -+ } ind_cmd; -+ - u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id); - int (*offload_enable)(struct mtk_wed_device *wed); - void (*offload_disable)(struct mtk_wed_device *wed); -@@ -193,6 +217,14 @@ struct mtk_wed_ops { - void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask); - int (*setup_tc)(struct mtk_wed_device *wed, struct net_device *dev, - enum tc_setup_type type, void *type_data); -+ void (*start_hw_rro)(struct mtk_wed_device *dev, u32 irq_mask, -+ bool reset); -+ void (*rro_rx_ring_setup)(struct mtk_wed_device *dev, int ring, -+ void __iomem *regs); -+ void (*msdu_pg_rx_ring_setup)(struct mtk_wed_device *dev, int ring, -+ void __iomem *regs); -+ int (*ind_rx_ring_setup)(struct mtk_wed_device *dev, -+ void __iomem *regs); - }; - - extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops; -@@ -264,6 +296,15 @@ static inline bool mtk_wed_is_amsdu_supp - #define mtk_wed_device_dma_reset(_dev) (_dev)->ops->reset_dma(_dev) - #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) \ - (_dev)->ops->setup_tc(_dev, _netdev, _type, _type_data) -+#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) \ -+ (_dev)->ops->start_hw_rro(_dev, _mask, _reset) -+#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) \ -+ (_dev)->ops->rro_rx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) \ -+ (_dev)->ops->msdu_pg_rx_ring_setup(_dev, _ring, _regs) -+#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) \ -+ (_dev)->ops->ind_rx_ring_setup(_dev, _regs) -+ - #else - static inline bool mtk_wed_device_active(struct mtk_wed_device *dev) - { -@@ -283,6 +324,10 @@ static inline bool mtk_wed_device_active - #define mtk_wed_device_stop(_dev) do {} while (0) - #define mtk_wed_device_dma_reset(_dev) do {} while (0) - #define mtk_wed_device_setup_tc(_dev, _netdev, _type, _type_data) -EOPNOTSUPP -+#define mtk_wed_device_start_hw_rro(_dev, _mask, _reset) do {} while (0) -+#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) -ENODEV -+#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) -ENODEV - #endif - - #endif diff --git a/target/linux/generic/backport-6.1/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch b/target/linux/generic/backport-6.1/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch deleted file mode 100644 index 5ea43a444569a1..00000000000000 --- a/target/linux/generic/backport-6.1/752-18-v6.7-net-ethernet-mtk_wed-debugfs-move-wed_v2-specific-re.patch +++ /dev/null @@ -1,78 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 18 Sep 2023 12:29:17 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: debugfs: move wed_v2 specific regs - out of regs array - -Move specific WED2.0 debugfs entries out of regs array. This is a -preliminary patch to introduce WED 3.0 debugfs info. - -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -151,7 +151,7 @@ DEFINE_SHOW_ATTRIBUTE(wed_txinfo); - static int - wed_rxinfo_show(struct seq_file *s, void *data) - { -- static const struct reg_dump regs[] = { -+ static const struct reg_dump regs_common[] = { - DUMP_STR("WPDMA RX"), - DUMP_WPDMA_RX_RING(0), - DUMP_WPDMA_RX_RING(1), -@@ -169,7 +169,7 @@ wed_rxinfo_show(struct seq_file *s, void - DUMP_WED_RING(WED_RING_RX_DATA(0)), - DUMP_WED_RING(WED_RING_RX_DATA(1)), - -- DUMP_STR("WED RRO"), -+ DUMP_STR("WED WO RRO"), - DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0), - DUMP_WED(WED_RROQM_MID_MIB), - DUMP_WED(WED_RROQM_MOD_MIB), -@@ -180,17 +180,6 @@ wed_rxinfo_show(struct seq_file *s, void - DUMP_WED(WED_RROQM_FDBK_ANC_MIB), - DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB), - -- DUMP_STR("WED Route QM"), -- DUMP_WED(WED_RTQM_R2H_MIB(0)), -- DUMP_WED(WED_RTQM_R2Q_MIB(0)), -- DUMP_WED(WED_RTQM_Q2H_MIB(0)), -- DUMP_WED(WED_RTQM_R2H_MIB(1)), -- DUMP_WED(WED_RTQM_R2Q_MIB(1)), -- DUMP_WED(WED_RTQM_Q2H_MIB(1)), -- DUMP_WED(WED_RTQM_Q2N_MIB), -- DUMP_WED(WED_RTQM_Q2B_MIB), -- DUMP_WED(WED_RTQM_PFDBK_MIB), -- - DUMP_STR("WED WDMA TX"), - DUMP_WED(WED_WDMA_TX_MIB), - DUMP_WED_RING(WED_WDMA_RING_TX), -@@ -211,11 +200,25 @@ wed_rxinfo_show(struct seq_file *s, void - DUMP_WED(WED_RX_BM_INTF), - DUMP_WED(WED_RX_BM_ERR_STS), - }; -+ static const struct reg_dump regs_wed_v2[] = { -+ DUMP_STR("WED Route QM"), -+ DUMP_WED(WED_RTQM_R2H_MIB(0)), -+ DUMP_WED(WED_RTQM_R2Q_MIB(0)), -+ DUMP_WED(WED_RTQM_Q2H_MIB(0)), -+ DUMP_WED(WED_RTQM_R2H_MIB(1)), -+ DUMP_WED(WED_RTQM_R2Q_MIB(1)), -+ DUMP_WED(WED_RTQM_Q2H_MIB(1)), -+ DUMP_WED(WED_RTQM_Q2N_MIB), -+ DUMP_WED(WED_RTQM_Q2B_MIB), -+ DUMP_WED(WED_RTQM_PFDBK_MIB), -+ }; - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; - -- if (dev) -- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ if (dev) { -+ dump_wed_regs(s, dev, regs_common, ARRAY_SIZE(regs_common)); -+ dump_wed_regs(s, dev, regs_wed_v2, ARRAY_SIZE(regs_wed_v2)); -+ } - - return 0; - } diff --git a/target/linux/generic/backport-6.1/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch b/target/linux/generic/backport-6.1/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch deleted file mode 100644 index f491d2fd80cf35..00000000000000 --- a/target/linux/generic/backport-6.1/752-19-v6.7-net-ethernet-mtk_wed-debugfs-add-WED-3.0-debugfs-ent.patch +++ /dev/null @@ -1,432 +0,0 @@ -From: Sujuan Chen -Date: Mon, 18 Sep 2023 12:29:18 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: debugfs: add WED 3.0 debugfs entries - -Introduce WED3.0 debugfs entries useful for debugging. - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c -@@ -11,6 +11,7 @@ struct reg_dump { - u16 offset; - u8 type; - u8 base; -+ u32 mask; - }; - - enum { -@@ -25,6 +26,8 @@ enum { - - #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING } - #define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ } -+#define DUMP_REG_MASK(_reg, _mask) \ -+ { #_mask, MTK_##_reg, DUMP_TYPE_WED, 0, MTK_##_mask } - #define DUMP_RING(_prefix, _base, ...) \ - { _prefix " BASE", _base, __VA_ARGS__ }, \ - { _prefix " CNT", _base + 0x4, __VA_ARGS__ }, \ -@@ -32,6 +35,7 @@ enum { - { _prefix " DIDX", _base + 0xc, __VA_ARGS__ } - - #define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED) -+#define DUMP_WED_MASK(_reg, _mask) DUMP_REG_MASK(_reg, _mask) - #define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED) - - #define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA) -@@ -212,12 +216,58 @@ wed_rxinfo_show(struct seq_file *s, void - DUMP_WED(WED_RTQM_Q2B_MIB), - DUMP_WED(WED_RTQM_PFDBK_MIB), - }; -+ static const struct reg_dump regs_wed_v3[] = { -+ DUMP_STR("WED RX RRO DATA"), -+ DUMP_WED_RING(WED_RRO_RX_D_RX(0)), -+ DUMP_WED_RING(WED_RRO_RX_D_RX(1)), -+ -+ DUMP_STR("WED RX MSDU PAGE"), -+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(0)), -+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(1)), -+ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(2)), -+ -+ DUMP_STR("WED RX IND CMD"), -+ DUMP_WED(WED_IND_CMD_RX_CTRL1), -+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_MAX_CNT), -+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_PROC_IDX), -+ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_DMA_IDX), -+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_MAGIC_CNT), -+ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_MAGIC_CNT), -+ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, -+ WED_IND_CMD_PREFETCH_FREE_CNT), -+ DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_PARTICL_SE_ID), -+ -+ DUMP_STR("WED ADDR ELEM"), -+ DUMP_WED(WED_ADDR_ELEM_CFG0), -+ DUMP_WED_MASK(WED_ADDR_ELEM_CFG1, -+ WED_ADDR_ELEM_PREFETCH_FREE_CNT), -+ -+ DUMP_STR("WED Route QM"), -+ DUMP_WED(WED_RTQM_ENQ_I2Q_DMAD_CNT), -+ DUMP_WED(WED_RTQM_ENQ_I2N_DMAD_CNT), -+ DUMP_WED(WED_RTQM_ENQ_I2Q_PKT_CNT), -+ DUMP_WED(WED_RTQM_ENQ_I2N_PKT_CNT), -+ DUMP_WED(WED_RTQM_ENQ_USED_ENTRY_CNT), -+ DUMP_WED(WED_RTQM_ENQ_ERR_CNT), -+ -+ DUMP_WED(WED_RTQM_DEQ_DMAD_CNT), -+ DUMP_WED(WED_RTQM_DEQ_Q2I_DMAD_CNT), -+ DUMP_WED(WED_RTQM_DEQ_PKT_CNT), -+ DUMP_WED(WED_RTQM_DEQ_Q2I_PKT_CNT), -+ DUMP_WED(WED_RTQM_DEQ_USED_PFDBK_CNT), -+ DUMP_WED(WED_RTQM_DEQ_ERR_CNT), -+ }; - struct mtk_wed_hw *hw = s->private; - struct mtk_wed_device *dev = hw->wed_dev; - - if (dev) { - dump_wed_regs(s, dev, regs_common, ARRAY_SIZE(regs_common)); -- dump_wed_regs(s, dev, regs_wed_v2, ARRAY_SIZE(regs_wed_v2)); -+ if (mtk_wed_is_v2(hw)) -+ dump_wed_regs(s, dev, -+ regs_wed_v2, ARRAY_SIZE(regs_wed_v2)); -+ else -+ dump_wed_regs(s, dev, -+ regs_wed_v3, ARRAY_SIZE(regs_wed_v3)); - } - - return 0; -@@ -225,6 +275,314 @@ wed_rxinfo_show(struct seq_file *s, void - DEFINE_SHOW_ATTRIBUTE(wed_rxinfo); - - static int -+wed_amsdu_show(struct seq_file *s, void *data) -+{ -+ static const struct reg_dump regs[] = { -+ DUMP_STR("WED AMDSU INFO"), -+ DUMP_WED(WED_MON_AMSDU_FIFO_DMAD), -+ -+ DUMP_STR("WED AMDSU ENG0 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(0)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(0)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(0)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(0)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(0)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(0), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(0), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG1 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(1)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(1)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(1)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(1)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(1)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(1), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(1), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG2 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(2)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(2)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(2)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(2)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(2)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(2), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(2), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG3 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(3)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(3)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(3)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(3)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(3)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(3), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(3), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG4 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(4)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(4)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(4)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(4)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(4)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(4), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG5 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(5)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(5)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(5)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(5)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(5)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(5), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(5), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG6 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(6)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(6)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(6)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(6)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(6)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(6), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(6), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG7 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(7)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(7)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(7)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(7)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(7)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(7), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(7), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(4), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED AMDSU ENG8 INFO"), -+ DUMP_WED(WED_MON_AMSDU_ENG_DMAD(8)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QFPL(8)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENI(8)), -+ DUMP_WED(WED_MON_AMSDU_ENG_QENO(8)), -+ DUMP_WED(WED_MON_AMSDU_ENG_MERG(8)), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8), -+ WED_AMSDU_ENG_MAX_PL_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT8(8), -+ WED_AMSDU_ENG_MAX_QGPP_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8), -+ WED_AMSDU_ENG_CUR_ENTRY), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8), -+ WED_AMSDU_ENG_MAX_BUF_MERGED), -+ DUMP_WED_MASK(WED_MON_AMSDU_ENG_CNT9(8), -+ WED_AMSDU_ENG_MAX_MSDU_MERGED), -+ -+ DUMP_STR("WED QMEM INFO"), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_FQ_CNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(0), WED_AMSDU_QMEM_SP_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID0_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(1), WED_AMSDU_QMEM_TID1_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID2_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(2), WED_AMSDU_QMEM_TID3_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID4_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(3), WED_AMSDU_QMEM_TID5_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID6_QCNT), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_CNT(4), WED_AMSDU_QMEM_TID7_QCNT), -+ -+ DUMP_STR("WED QMEM HEAD INFO"), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_FQ_HEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(0), WED_AMSDU_QMEM_SP_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID0_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(1), WED_AMSDU_QMEM_TID1_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID2_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(2), WED_AMSDU_QMEM_TID3_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID4_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(3), WED_AMSDU_QMEM_TID5_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID6_QHEAD), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(4), WED_AMSDU_QMEM_TID7_QHEAD), -+ -+ DUMP_STR("WED QMEM TAIL INFO"), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_FQ_TAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(5), WED_AMSDU_QMEM_SP_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID0_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(6), WED_AMSDU_QMEM_TID1_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID2_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(7), WED_AMSDU_QMEM_TID3_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID4_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(8), WED_AMSDU_QMEM_TID5_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID6_QTAIL), -+ DUMP_WED_MASK(WED_MON_AMSDU_QMEM_PTR(9), WED_AMSDU_QMEM_TID7_QTAIL), -+ -+ DUMP_STR("WED HIFTXD MSDU INFO"), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(1)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(2)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(3)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(4)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(5)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(6)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(7)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(8)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(9)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(10)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(11)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(12)), -+ DUMP_WED(WED_MON_AMSDU_HIFTXD_FETCH_MSDU(13)), -+ }; -+ struct mtk_wed_hw *hw = s->private; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (dev) -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(wed_amsdu); -+ -+static int -+wed_rtqm_show(struct seq_file *s, void *data) -+{ -+ static const struct reg_dump regs[] = { -+ DUMP_STR("WED Route QM IGRS0(N2H + Recycle)"), -+ DUMP_WED(WED_RTQM_IGRS0_I2HW_DMAD_CNT), -+ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS0_I2HW_PKT_CNT), -+ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS0_FDROP_CNT), -+ -+ DUMP_STR("WED Route QM IGRS1(Legacy)"), -+ DUMP_WED(WED_RTQM_IGRS1_I2HW_DMAD_CNT), -+ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS1_I2HW_PKT_CNT), -+ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS1_FDROP_CNT), -+ -+ DUMP_STR("WED Route QM IGRS2(RRO3.0)"), -+ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT), -+ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS2_I2HW_PKT_CNT), -+ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS2_FDROP_CNT), -+ -+ DUMP_STR("WED Route QM IGRS3(DEBUG)"), -+ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT), -+ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS3_I2HW_PKT_CNT), -+ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(0)), -+ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(1)), -+ DUMP_WED(WED_RTQM_IGRS3_FDROP_CNT), -+ }; -+ struct mtk_wed_hw *hw = s->private; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (dev) -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(wed_rtqm); -+ -+static int -+wed_rro_show(struct seq_file *s, void *data) -+{ -+ static const struct reg_dump regs[] = { -+ DUMP_STR("RRO/IND CMD CNT"), -+ DUMP_WED(WED_RX_IND_CMD_CNT(1)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(2)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(3)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(4)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(5)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(6)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(7)), -+ DUMP_WED(WED_RX_IND_CMD_CNT(8)), -+ DUMP_WED_MASK(WED_RX_IND_CMD_CNT(9), -+ WED_IND_CMD_MAGIC_CNT_FAIL_CNT), -+ -+ DUMP_WED(WED_RX_ADDR_ELEM_CNT(0)), -+ DUMP_WED_MASK(WED_RX_ADDR_ELEM_CNT(1), -+ WED_ADDR_ELEM_SIG_FAIL_CNT), -+ DUMP_WED(WED_RX_MSDU_PG_CNT(1)), -+ DUMP_WED(WED_RX_MSDU_PG_CNT(2)), -+ DUMP_WED(WED_RX_MSDU_PG_CNT(3)), -+ DUMP_WED(WED_RX_MSDU_PG_CNT(4)), -+ DUMP_WED(WED_RX_MSDU_PG_CNT(5)), -+ DUMP_WED_MASK(WED_RX_PN_CHK_CNT, -+ WED_PN_CHK_FAIL_CNT), -+ }; -+ struct mtk_wed_hw *hw = s->private; -+ struct mtk_wed_device *dev = hw->wed_dev; -+ -+ if (dev) -+ dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs)); -+ -+ return 0; -+} -+DEFINE_SHOW_ATTRIBUTE(wed_rro); -+ -+static int - mtk_wed_reg_set(void *data, u64 val) - { - struct mtk_wed_hw *hw = data; -@@ -266,7 +624,16 @@ void mtk_wed_hw_add_debugfs(struct mtk_w - debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg); - debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval); - debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops); -- if (!mtk_wed_is_v1(hw)) -+ if (!mtk_wed_is_v1(hw)) { - debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, - &wed_rxinfo_fops); -+ if (mtk_wed_is_v3_or_greater(hw)) { -+ debugfs_create_file_unsafe("amsdu", 0400, dir, hw, -+ &wed_amsdu_fops); -+ debugfs_create_file_unsafe("rtqm", 0400, dir, hw, -+ &wed_rtqm_fops); -+ debugfs_create_file_unsafe("rro", 0400, dir, hw, -+ &wed_rro_fops); -+ } -+ } - } diff --git a/target/linux/generic/backport-6.1/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch b/target/linux/generic/backport-6.1/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch deleted file mode 100644 index aaaabf05e8b276..00000000000000 --- a/target/linux/generic/backport-6.1/752-20-v6.7-net-ethernet-mtk_wed-add-wed-3.0-reset-support.patch +++ /dev/null @@ -1,587 +0,0 @@ -From: Sujuan Chen -Date: Mon, 18 Sep 2023 12:29:19 +0200 -Subject: [PATCH] net: ethernet: mtk_wed: add wed 3.0 reset support - -Introduce support for resetting Wireless Ethernet Dispatcher 3.0 -available on MT988 SoC. - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Signed-off-by: Sujuan Chen -Signed-off-by: Paolo Abeni ---- - ---- a/drivers/net/ethernet/mediatek/mtk_wed.c -+++ b/drivers/net/ethernet/mediatek/mtk_wed.c -@@ -148,6 +148,90 @@ mtk_wdma_read_reset(struct mtk_wed_devic - return wdma_r32(dev, MTK_WDMA_GLO_CFG); - } - -+static void -+mtk_wdma_v3_rx_reset(struct mtk_wed_device *dev) -+{ -+ u32 status; -+ -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) -+ return; -+ -+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN); -+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_PREF_TX_CFG)) -+ dev_err(dev->hw->dev, "rx reset failed\n"); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_PREF_RX_CFG)) -+ dev_err(dev->hw->dev, "rx reset failed\n"); -+ -+ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); -+ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_WRBK_TX_CFG)) -+ dev_err(dev->hw->dev, "rx reset failed\n"); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_WRBK_RX_CFG)) -+ dev_err(dev->hw->dev, "rx reset failed\n"); -+ -+ /* prefetch FIFO */ -+ wdma_w32(dev, MTK_WDMA_PREF_RX_FIFO_CFG, -+ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR | -+ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR); -+ wdma_clr(dev, MTK_WDMA_PREF_RX_FIFO_CFG, -+ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR | -+ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR); -+ -+ /* core FIFO */ -+ wdma_w32(dev, MTK_WDMA_XDMA_RX_FIFO_CFG, -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR); -+ wdma_clr(dev, MTK_WDMA_XDMA_RX_FIFO_CFG, -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR | -+ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR); -+ -+ /* writeback FIFO */ -+ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0), -+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); -+ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1), -+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); -+ -+ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0), -+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1), -+ MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR); -+ -+ /* prefetch ring status */ -+ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG, -+ MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG, -+ MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR); -+ -+ /* writeback ring status */ -+ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG, -+ MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG, -+ MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR); -+} -+ - static int - mtk_wdma_rx_reset(struct mtk_wed_device *dev) - { -@@ -160,6 +244,7 @@ mtk_wdma_rx_reset(struct mtk_wed_device - if (ret) - dev_err(dev->hw->dev, "rx reset failed\n"); - -+ mtk_wdma_v3_rx_reset(dev); - wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX); - wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); - -@@ -192,6 +277,84 @@ mtk_wed_poll_busy(struct mtk_wed_device - } - - static void -+mtk_wdma_v3_tx_reset(struct mtk_wed_device *dev) -+{ -+ u32 status; -+ -+ if (!mtk_wed_is_v3_or_greater(dev->hw)) -+ return; -+ -+ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN); -+ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_PREF_TX_CFG)) -+ dev_err(dev->hw->dev, "tx reset failed\n"); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_PREF_RX_CFG)) -+ dev_err(dev->hw->dev, "tx reset failed\n"); -+ -+ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN); -+ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_WRBK_TX_CFG)) -+ dev_err(dev->hw->dev, "tx reset failed\n"); -+ -+ if (read_poll_timeout(wdma_r32, status, -+ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY), -+ 0, 10000, false, dev, MTK_WDMA_WRBK_RX_CFG)) -+ dev_err(dev->hw->dev, "tx reset failed\n"); -+ -+ /* prefetch FIFO */ -+ wdma_w32(dev, MTK_WDMA_PREF_TX_FIFO_CFG, -+ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR | -+ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR); -+ wdma_clr(dev, MTK_WDMA_PREF_TX_FIFO_CFG, -+ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR | -+ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR); -+ -+ /* core FIFO */ -+ wdma_w32(dev, MTK_WDMA_XDMA_TX_FIFO_CFG, -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR); -+ wdma_clr(dev, MTK_WDMA_XDMA_TX_FIFO_CFG, -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR | -+ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR); -+ -+ /* writeback FIFO */ -+ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0), -+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); -+ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1), -+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); -+ -+ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0), -+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1), -+ MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR); -+ -+ /* prefetch ring status */ -+ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG, -+ MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG, -+ MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR); -+ -+ /* writeback ring status */ -+ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG, -+ MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR); -+ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG, -+ MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR); -+} -+ -+static void - mtk_wdma_tx_reset(struct mtk_wed_device *dev) - { - u32 status, mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY; -@@ -202,6 +365,7 @@ mtk_wdma_tx_reset(struct mtk_wed_device - !(status & mask), 0, 10000)) - dev_err(dev->hw->dev, "tx reset failed\n"); - -+ mtk_wdma_v3_tx_reset(dev); - wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX); - wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); - -@@ -1405,13 +1569,33 @@ mtk_wed_rx_reset(struct mtk_wed_device * - if (ret) - return ret; - -+ if (dev->wlan.hw_rro) { -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_HW_STS, -+ MTK_WED_RX_IND_CMD_BUSY); -+ mtk_wed_reset(dev, MTK_WED_RESET_RRO_RX_TO_PG); -+ } -+ - wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN); - ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, - MTK_WED_WPDMA_RX_D_RX_DRV_BUSY); -+ if (!ret && mtk_wed_is_v3_or_greater(dev->hw)) -+ ret = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, -+ MTK_WED_WPDMA_RX_D_PREF_BUSY); - if (ret) { - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV); - } else { -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ /* 1.a. disable prefetch HW */ -+ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, -+ MTK_WED_WPDMA_RX_D_PREF_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, -+ MTK_WED_WPDMA_RX_D_PREF_BUSY); -+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, -+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL); -+ } -+ - wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, - MTK_WED_WPDMA_RX_D_RST_CRX_IDX | - MTK_WED_WPDMA_RX_D_RST_DRV_IDX); -@@ -1439,23 +1623,52 @@ mtk_wed_rx_reset(struct mtk_wed_device * - wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0); - } - -+ if (dev->wlan.hw_rro) { -+ /* disable rro msdu page drv */ -+ wed_clr(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_EN); -+ -+ /* disable rro data drv */ -+ wed_clr(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN); -+ -+ /* rro msdu page drv reset */ -+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_CLR); -+ mtk_wed_poll_busy(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_CLR); -+ -+ /* rro data drv reset */ -+ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(2), -+ MTK_WED_RRO_RX_D_DRV_CLR); -+ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_D_CFG(2), -+ MTK_WED_RRO_RX_D_DRV_CLR); -+ } -+ - /* reset route qm */ - wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN); - ret = mtk_wed_poll_busy(dev, MTK_WED_CTRL, - MTK_WED_CTRL_RX_ROUTE_QM_BUSY); -- if (ret) -+ if (ret) { - mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM); -- else -- wed_set(dev, MTK_WED_RTQM_GLO_CFG, -- MTK_WED_RTQM_Q_RST); -+ } else if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ wed_set(dev, MTK_WED_RTQM_RST, BIT(0)); -+ wed_clr(dev, MTK_WED_RTQM_RST, BIT(0)); -+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM); -+ } else { -+ wed_set(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST); -+ } - - /* reset tx wdma */ - mtk_wdma_tx_reset(dev); - - /* reset tx wdma drv */ - wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN); -- mtk_wed_poll_busy(dev, MTK_WED_CTRL, -- MTK_WED_CTRL_WDMA_INT_AGENT_BUSY); -+ if (mtk_wed_is_v3_or_greater(dev->hw)) -+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_STATUS, -+ MTK_WED_WPDMA_STATUS_TX_DRV); -+ else -+ mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY); - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV); - - /* reset wed rx dma */ -@@ -1476,6 +1689,14 @@ mtk_wed_rx_reset(struct mtk_wed_device * - MTK_WED_CTRL_WED_RX_BM_BUSY); - mtk_wed_reset(dev, MTK_WED_RESET_RX_BM); - -+ if (dev->wlan.hw_rro) { -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_CTRL, -+ MTK_WED_CTRL_WED_RX_PG_BM_BUSY); -+ wed_set(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM); -+ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM); -+ } -+ - /* wo change to enable state */ - val = MTK_WED_WO_STATE_ENABLE; - ret = mtk_wed_mcu_send_msg(wo, MTK_WED_MODULE_ID_WO, -@@ -1493,6 +1714,7 @@ mtk_wed_rx_reset(struct mtk_wed_device * - false); - } - mtk_wed_free_rx_buffer(dev); -+ mtk_wed_hwrro_free_buffer(dev); - - return 0; - } -@@ -1526,15 +1748,41 @@ mtk_wed_reset_dma(struct mtk_wed_device - - /* 2. reset WDMA rx DMA */ - busy = !!mtk_wdma_rx_reset(dev); -- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ val = MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE | -+ wed_r32(dev, MTK_WED_WDMA_GLO_CFG); -+ val &= ~MTK_WED_WDMA_GLO_CFG_RX_DRV_EN; -+ wed_w32(dev, MTK_WED_WDMA_GLO_CFG, val); -+ } else { -+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, -+ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN); -+ } -+ - if (!busy) - busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG, - MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY); -+ if (!busy && mtk_wed_is_v3_or_greater(dev->hw)) -+ busy = mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_BUSY); - - if (busy) { - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT); - mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV); - } else { -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ /* 1.a. disable prefetch HW */ -+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_EN); -+ mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_BUSY); -+ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, -+ MTK_WED_WDMA_RX_PREF_DDONE2_EN); -+ -+ /* 2. Reset dma index */ -+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX, -+ MTK_WED_WDMA_RESET_IDX_RX_ALL); -+ } -+ - wed_w32(dev, MTK_WED_WDMA_RESET_IDX, - MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV); - wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0); -@@ -1550,8 +1798,13 @@ mtk_wed_reset_dma(struct mtk_wed_device - wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_TX_FREE_AGENT_EN); - - for (i = 0; i < 100; i++) { -- val = wed_r32(dev, MTK_WED_TX_BM_INTF); -- if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40) -+ if (mtk_wed_is_v1(dev->hw)) -+ val = FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, -+ wed_r32(dev, MTK_WED_TX_BM_INTF)); -+ else -+ val = FIELD_GET(MTK_WED_TX_TKID_INTF_TKFIFO_FDEP, -+ wed_r32(dev, MTK_WED_TX_TKID_INTF)); -+ if (val == 0x40) - break; - } - -@@ -1573,6 +1826,8 @@ mtk_wed_reset_dma(struct mtk_wed_device - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT); - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV); - mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV); -+ if (mtk_wed_is_v3_or_greater(dev->hw)) -+ wed_w32(dev, MTK_WED_RX1_CTRL2, 0); - } else { - wed_w32(dev, MTK_WED_WPDMA_RESET_IDX, - MTK_WED_WPDMA_RESET_IDX_TX | -@@ -1589,7 +1844,14 @@ mtk_wed_reset_dma(struct mtk_wed_device - wed_w32(dev, MTK_WED_RESET_IDX, 0); - } - -- mtk_wed_rx_reset(dev); -+ if (mtk_wed_is_v3_or_greater(dev->hw)) { -+ /* reset amsdu engine */ -+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_AMSDU_EN); -+ mtk_wed_reset(dev, MTK_WED_RESET_TX_AMSDU); -+ } -+ -+ if (mtk_wed_get_rx_capa(dev)) -+ mtk_wed_rx_reset(dev); - } - - static int -@@ -1841,6 +2103,7 @@ mtk_wed_dma_enable(struct mtk_wed_device - MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4); - - wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN); -+ wdma_set(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN); - } - - wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, -@@ -1904,6 +2167,12 @@ mtk_wed_start_hw_rro(struct mtk_wed_devi - if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hw_rro) - return; - -+ if (reset) { -+ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, -+ MTK_WED_RRO_MSDU_PG_DRV_EN); -+ return; -+ } -+ - wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR); - wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, - MTK_WED_RRO_MSDU_PG_DRV_CLR); ---- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h -+++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h -@@ -28,6 +28,8 @@ struct mtk_wdma_desc { - #define MTK_WED_RESET 0x008 - #define MTK_WED_RESET_TX_BM BIT(0) - #define MTK_WED_RESET_RX_BM BIT(1) -+#define MTK_WED_RESET_RX_PG_BM BIT(2) -+#define MTK_WED_RESET_RRO_RX_TO_PG BIT(3) - #define MTK_WED_RESET_TX_FREE_AGENT BIT(4) - #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8) - #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9) -@@ -106,6 +108,9 @@ struct mtk_wdma_desc { - #define MTK_WED_STATUS 0x060 - #define MTK_WED_STATUS_TX GENMASK(15, 8) - -+#define MTK_WED_WPDMA_STATUS 0x068 -+#define MTK_WED_WPDMA_STATUS_TX_DRV GENMASK(15, 8) -+ - #define MTK_WED_TX_BM_CTRL 0x080 - #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0) - #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16) -@@ -140,6 +145,9 @@ struct mtk_wdma_desc { - #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16) - #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28) - -+#define MTK_WED_TX_TKID_INTF 0x0dc -+#define MTK_WED_TX_TKID_INTF_TKFIFO_FDEP GENMASK(25, 16) -+ - #define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM_V3 GENMASK(7, 0) - #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM_V3 GENMASK(23, 16) - -@@ -190,6 +198,7 @@ struct mtk_wdma_desc { - #define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10) - - #define MTK_WED_SCR0 0x3c0 -+#define MTK_WED_RX1_CTRL2 0x418 - #define MTK_WED_WPDMA_INT_TRIGGER 0x504 - #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1) - #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4) -@@ -303,6 +312,7 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_RX_D_RST_IDX 0x760 - #define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16) -+#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL BIT(20) - #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24) - - #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c -@@ -313,6 +323,7 @@ struct mtk_wdma_desc { - - #define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4 - #define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0) -+#define MTK_WED_WPDMA_RX_D_PREF_BUSY BIT(1) - #define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8) - #define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16) - -@@ -334,11 +345,13 @@ struct mtk_wdma_desc { - - #define MTK_WED_WDMA_RX_PREF_CFG 0x950 - #define MTK_WED_WDMA_RX_PREF_EN BIT(0) -+#define MTK_WED_WDMA_RX_PREF_BUSY BIT(1) - #define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8) - #define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16) - #define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24) - #define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25) - #define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26) -+#define MTK_WED_WDMA_RX_PREF_DDONE2_BUSY BIT(27) - - #define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C - #define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0) -@@ -367,6 +380,7 @@ struct mtk_wdma_desc { - - #define MTK_WED_WDMA_RESET_IDX 0xa08 - #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16) -+#define MTK_WED_WDMA_RESET_IDX_RX_ALL BIT(20) - #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24) - - #define MTK_WED_WDMA_INT_CLR 0xa24 -@@ -437,21 +451,62 @@ struct mtk_wdma_desc { - #define MTK_WDMA_INT_MASK_RX_DELAY BIT(30) - #define MTK_WDMA_INT_MASK_RX_COHERENT BIT(31) - -+#define MTK_WDMA_XDMA_TX_FIFO_CFG 0x238 -+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR BIT(0) -+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR BIT(4) -+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR BIT(8) -+#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR BIT(12) -+ -+#define MTK_WDMA_XDMA_RX_FIFO_CFG 0x23c -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR BIT(0) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR BIT(4) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR BIT(8) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR BIT(12) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR BIT(15) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR BIT(18) -+#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR BIT(21) -+ - #define MTK_WDMA_INT_GRP1 0x250 - #define MTK_WDMA_INT_GRP2 0x254 - - #define MTK_WDMA_PREF_TX_CFG 0x2d0 - #define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0) -+#define MTK_WDMA_PREF_TX_CFG_PREF_BUSY BIT(1) - - #define MTK_WDMA_PREF_RX_CFG 0x2dc - #define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0) -+#define MTK_WDMA_PREF_RX_CFG_PREF_BUSY BIT(1) -+ -+#define MTK_WDMA_PREF_RX_FIFO_CFG 0x2e0 -+#define MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR BIT(0) -+#define MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR BIT(16) -+ -+#define MTK_WDMA_PREF_TX_FIFO_CFG 0x2d4 -+#define MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR BIT(0) -+#define MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR BIT(16) -+ -+#define MTK_WDMA_PREF_SIDX_CFG 0x2e4 -+#define MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0) -+#define MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4) - - #define MTK_WDMA_WRBK_TX_CFG 0x300 -+#define MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY BIT(0) - #define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30) - -+#define MTK_WDMA_WRBK_TX_FIFO_CFG(_n) (0x304 + (_n) * 0x4) -+#define MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR BIT(0) -+ - #define MTK_WDMA_WRBK_RX_CFG 0x344 -+#define MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY BIT(0) - #define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30) - -+#define MTK_WDMA_WRBK_RX_FIFO_CFG(_n) (0x348 + (_n) * 0x4) -+#define MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR BIT(0) -+ -+#define MTK_WDMA_WRBK_SIDX_CFG 0x388 -+#define MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0) -+#define MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4) -+ - #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0) - #define MTK_PCIE_MIRROR_MAP_EN BIT(0) - #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1) -@@ -465,6 +520,8 @@ struct mtk_wdma_desc { - #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5) - #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20) - -+#define MTK_WED_RTQM_RST 0xb04 -+ - #define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c - #define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4) - #define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28 -@@ -653,6 +710,9 @@ struct mtk_wdma_desc { - #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17) - #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18) - -+#define MTK_WED_RRO_RX_HW_STS 0xf00 -+#define MTK_WED_RX_IND_CMD_BUSY GENMASK(31, 0) -+ - #define MTK_WED_RX_IND_CMD_CNT0 0xf20 - #define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31) - diff --git a/target/linux/generic/backport-6.1/760-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch b/target/linux/generic/backport-6.1/760-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch deleted file mode 100644 index 32ac37e8d02ede..00000000000000 --- a/target/linux/generic/backport-6.1/760-v6.9-net-phy-aquantia-add-AQR111-and-AQR111B0-PHY-ID.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 038ba1dc4e54d51d953f5618d8eb5dd39bd9de25 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 13 Feb 2024 14:35:51 +0100 -Subject: [PATCH] net: phy: aquantia: add AQR111 and AQR111B0 PHY ID - -Add Aquantia AQR111 and AQR111B0 PHY ID. These PHY advertise 10G speed -but actually supports up to 5G speed, hence some manual fixup is needed. - -The Aquantia AQR111B0 PHY is just a variant of the AQR111 with smaller -chip size. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240213133558.1836-1-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/aquantia/aquantia_main.c | 52 ++++++++++++++++++++++++ - 1 file changed, 52 insertions(+) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -22,6 +22,8 @@ - #define PHY_ID_AQR107 0x03a1b4e0 - #define PHY_ID_AQCS109 0x03a1b5c2 - #define PHY_ID_AQR405 0x03a1b4b0 -+#define PHY_ID_AQR111 0x03a1b610 -+#define PHY_ID_AQR111B0 0x03a1b612 - #define PHY_ID_AQR113C 0x31c31c12 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 -@@ -670,6 +672,16 @@ static int aqr107_probe(struct phy_devic - return aqr_hwmon_probe(phydev); - } - -+static int aqr111_config_init(struct phy_device *phydev) -+{ -+ /* AQR111 reports supporting speed up to 10G, -+ * however only speeds up to 5G are supported. -+ */ -+ phy_set_max_speed(phydev, SPEED_5000); -+ -+ return aqr107_config_init(phydev); -+} -+ - static struct phy_driver aqr_driver[] = { - { - PHY_ID_MATCH_MODEL(PHY_ID_AQ1202), -@@ -744,6 +756,44 @@ static struct phy_driver aqr_driver[] = - .link_change_notify = aqr107_link_change_notify, - }, - { -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR111), -+ .name = "Aquantia AQR111", -+ .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, -+ .config_init = aqr111_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0), -+ .name = "Aquantia AQR111B0", -+ .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, -+ .config_init = aqr111_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+{ - PHY_ID_MATCH_MODEL(PHY_ID_AQR405), - .name = "Aquantia AQR405", - .config_aneg = aqr_config_aneg, -@@ -782,6 +832,8 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR111) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, - { } - }; diff --git a/target/linux/generic/backport-6.1/761-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch b/target/linux/generic/backport-6.1/761-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch deleted file mode 100644 index 073bbbd49d03c9..00000000000000 --- a/target/linux/generic/backport-6.1/761-v6.9-net-phy-aquantia-add-AQR113-PHY-ID.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 71b605d32017e5b8d257db7344bc2f8e8fcc973e Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 15 Feb 2024 16:30:05 +0100 -Subject: [PATCH] net: phy: aquantia: add AQR113 PHY ID - -Add Aquantia AQR113 PHY ID. Aquantia AQR113 is just a chip size variant of -the already supported AQR133C where the only difference is the PHY ID -and the hw chip size. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/aquantia/aquantia_main.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -24,6 +24,7 @@ - #define PHY_ID_AQR405 0x03a1b4b0 - #define PHY_ID_AQR111 0x03a1b610 - #define PHY_ID_AQR111B0 0x03a1b612 -+#define PHY_ID_AQR113 0x31c31c40 - #define PHY_ID_AQR113C 0x31c31c12 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 -@@ -802,6 +803,25 @@ static struct phy_driver aqr_driver[] = - .read_status = aqr_read_status, - }, - { -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR113), -+ .name = "Aquantia AQR113", -+ .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, -+ .config_init = aqr107_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, -+{ - PHY_ID_MATCH_MODEL(PHY_ID_AQR113C), - .name = "Aquantia AQR113C", - .probe = aqr107_probe, -@@ -834,6 +854,7 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR111) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, - { } - }; diff --git a/target/linux/generic/backport-6.1/762-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch b/target/linux/generic/backport-6.1/762-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch deleted file mode 100644 index 965b8c91b28248..00000000000000 --- a/target/linux/generic/backport-6.1/762-v6.9-net-phy-aquantia-add-AQR813-PHY-ID.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 6d47302a3f0ba31445478d518d98bd55918bc8ab Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 15 Feb 2024 22:43:30 +0100 -Subject: [PATCH] net: phy: aquantia: add AQR813 PHY ID - -Aquantia AQR813 is the Octal Port variant of the AQR113. Add PHY ID for -it to provide support for it. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/aquantia/aquantia_main.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -26,6 +26,7 @@ - #define PHY_ID_AQR111B0 0x03a1b612 - #define PHY_ID_AQR113 0x31c31c40 - #define PHY_ID_AQR113C 0x31c31c12 -+#define PHY_ID_AQR813 0x31c31cb2 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -@@ -840,6 +841,25 @@ static struct phy_driver aqr_driver[] = - .get_stats = aqr107_get_stats, - .link_change_notify = aqr107_link_change_notify, - }, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR813), -+ .name = "Aquantia AQR813", -+ .probe = aqr107_probe, -+ .get_rate_matching = aqr107_get_rate_matching, -+ .config_init = aqr107_config_init, -+ .config_aneg = aqr_config_aneg, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_tunable = aqr107_get_tunable, -+ .set_tunable = aqr107_set_tunable, -+ .suspend = aqr107_suspend, -+ .resume = aqr107_resume, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+ .link_change_notify = aqr107_link_change_notify, -+}, - }; - - module_phy_driver(aqr_driver); -@@ -856,6 +876,7 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, - { } - }; - diff --git a/target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch b/target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch deleted file mode 100644 index 4cef7194ebef94..00000000000000 --- a/target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch +++ /dev/null @@ -1,99 +0,0 @@ -From f13b2b33c7674fa0988dfaa9adb95d7d912b489f Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 10 Apr 2024 20:42:38 +0100 -Subject: [PATCH 1/2] net: dsa: introduce dsa_phylink_to_port() - -We convert from a phylink_config struct to a dsa_port struct in many -places, let's provide a helper for this. - -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Signed-off-by: Russell King (Oracle) -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/E1rudqA-006K9B-85@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - include/net/dsa.h | 6 ++++++ - net/dsa/port.c | 12 ++++++------ - 2 files changed, 12 insertions(+), 6 deletions(-) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -337,6 +337,12 @@ struct dsa_port { - struct list_head vlans; - }; - -+static inline struct dsa_port * -+dsa_phylink_to_port(struct phylink_config *config) -+{ -+ return container_of(config, struct dsa_port, pl_config); -+} -+ - /* TODO: ideally DSA ports would have a single dp->link_dp member, - * and no dst->rtable nor this struct dsa_link would be needed, - * but this would require some more complex tree walking, ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -1552,7 +1552,7 @@ static void dsa_port_phylink_validate(st - unsigned long *supported, - struct phylink_link_state *state) - { -- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); -+ struct dsa_port *dp = dsa_phylink_to_port(config); - struct dsa_switch *ds = dp->ds; - - if (!ds->ops->phylink_validate) { -@@ -1567,7 +1567,7 @@ static void dsa_port_phylink_validate(st - static void dsa_port_phylink_mac_pcs_get_state(struct phylink_config *config, - struct phylink_link_state *state) - { -- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); -+ struct dsa_port *dp = dsa_phylink_to_port(config); - struct dsa_switch *ds = dp->ds; - int err; - -@@ -1589,7 +1589,7 @@ static struct phylink_pcs * - dsa_port_phylink_mac_select_pcs(struct phylink_config *config, - phy_interface_t interface) - { -- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); -+ struct dsa_port *dp = dsa_phylink_to_port(config); - struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP); - struct dsa_switch *ds = dp->ds; - -@@ -1603,7 +1603,7 @@ static void dsa_port_phylink_mac_config( - unsigned int mode, - const struct phylink_link_state *state) - { -- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); -+ struct dsa_port *dp = dsa_phylink_to_port(config); - struct dsa_switch *ds = dp->ds; - - if (!ds->ops->phylink_mac_config) -@@ -1614,7 +1614,7 @@ static void dsa_port_phylink_mac_config( - - static void dsa_port_phylink_mac_an_restart(struct phylink_config *config) - { -- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); -+ struct dsa_port *dp = dsa_phylink_to_port(config); - struct dsa_switch *ds = dp->ds; - - if (!ds->ops->phylink_mac_an_restart) -@@ -1627,7 +1627,7 @@ static void dsa_port_phylink_mac_link_do - unsigned int mode, - phy_interface_t interface) - { -- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); -+ struct dsa_port *dp = dsa_phylink_to_port(config); - struct phy_device *phydev = NULL; - struct dsa_switch *ds = dp->ds; - -@@ -1650,7 +1650,7 @@ static void dsa_port_phylink_mac_link_up - int speed, int duplex, - bool tx_pause, bool rx_pause) - { -- struct dsa_port *dp = container_of(config, struct dsa_port, pl_config); -+ struct dsa_port *dp = dsa_phylink_to_port(config); - struct dsa_switch *ds = dp->ds; - - if (!ds->ops->phylink_mac_link_up) { diff --git a/target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch b/target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch deleted file mode 100644 index 0119925ab03795..00000000000000 --- a/target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch +++ /dev/null @@ -1,117 +0,0 @@ -From c22d8240fcd73a1c3ec8dcb055bd583fb970c375 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 10 Apr 2024 20:42:43 +0100 -Subject: [PATCH 2/2] net: dsa: allow DSA switch drivers to provide their own - phylink mac ops - -Rather than having a shim for each and every phylink MAC operation, -allow DSA switch drivers to provide their own ops structure. When a -DSA driver provides the phylink MAC operations, the shimmed ops must -not be provided, so fail an attempt to register a switch with both -the phylink_mac_ops in struct dsa_switch and the phylink_mac_* -operations populated in dsa_switch_ops populated. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Link: https://lore.kernel.org/r/E1rudqF-006K9H-Cc@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - include/net/dsa.h | 5 +++++ - net/dsa/dsa.c | 11 +++++++++++ - net/dsa/port.c | 26 ++++++++++++++++++++------ - 3 files changed, 36 insertions(+), 6 deletions(-) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -468,6 +468,11 @@ struct dsa_switch { - const struct dsa_switch_ops *ops; - - /* -+ * Allow a DSA switch driver to override the phylink MAC ops -+ */ -+ const struct phylink_mac_ops *phylink_mac_ops; -+ -+ /* - * Slave mii_bus and devices for the individual ports. - */ - u32 phys_mii_mask; ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -1675,6 +1675,7 @@ static const struct phylink_mac_ops dsa_ - - int dsa_port_phylink_create(struct dsa_port *dp) - { -+ const struct phylink_mac_ops *mac_ops; - struct dsa_switch *ds = dp->ds; - phy_interface_t mode; - struct phylink *pl; -@@ -1694,8 +1695,12 @@ int dsa_port_phylink_create(struct dsa_p - if (ds->ops->phylink_get_caps) - ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config); - -- pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), -- mode, &dsa_port_phylink_mac_ops); -+ mac_ops = &dsa_port_phylink_mac_ops; -+ if (ds->phylink_mac_ops) -+ mac_ops = ds->phylink_mac_ops; -+ -+ pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode, -+ mac_ops); - if (IS_ERR(pl)) { - pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl)); - return PTR_ERR(pl); -@@ -1961,12 +1966,23 @@ static void dsa_shared_port_validate_of( - dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index); - } - -+static void dsa_shared_port_link_down(struct dsa_port *dp) -+{ -+ struct dsa_switch *ds = dp->ds; -+ -+ if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down) -+ ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED, -+ PHY_INTERFACE_MODE_NA); -+ else if (ds->ops->phylink_mac_link_down) -+ ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED, -+ PHY_INTERFACE_MODE_NA); -+} -+ - int dsa_shared_port_link_register_of(struct dsa_port *dp) - { - struct dsa_switch *ds = dp->ds; - bool missing_link_description; - bool missing_phy_mode; -- int port = dp->index; - - dsa_shared_port_validate_of(dp, &missing_phy_mode, - &missing_link_description); -@@ -1982,9 +1998,7 @@ int dsa_shared_port_link_register_of(str - "Skipping phylink registration for %s port %d\n", - dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index); - } else { -- if (ds->ops->phylink_mac_link_down) -- ds->ops->phylink_mac_link_down(ds, port, -- MLO_AN_FIXED, PHY_INTERFACE_MODE_NA); -+ dsa_shared_port_link_down(dp); - - return dsa_shared_port_phylink_register(dp); - } ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -1758,6 +1758,15 @@ static int dsa_switch_probe(struct dsa_s - if (!ds->num_ports) - return -EINVAL; - -+ if (ds->phylink_mac_ops) { -+ if (ds->ops->phylink_mac_select_pcs || -+ ds->ops->phylink_mac_config || -+ ds->ops->phylink_mac_link_down || -+ ds->ops->phylink_mac_link_up || -+ ds->ops->adjust_link) -+ return -EINVAL; -+ } -+ - if (np) { - err = dsa_switch_parse_of(ds, np); - if (err) diff --git a/target/linux/generic/backport-6.1/770-net-introduce-napi_is_scheduled-helper.patch b/target/linux/generic/backport-6.1/770-net-introduce-napi_is_scheduled-helper.patch deleted file mode 100644 index 789b93e9f93a0d..00000000000000 --- a/target/linux/generic/backport-6.1/770-net-introduce-napi_is_scheduled-helper.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 7f3eb2174512fe6c9c0f062e96eccb0d3cc6d5cd Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 18 Oct 2023 14:35:47 +0200 -Subject: [PATCH] net: introduce napi_is_scheduled helper - -We currently have napi_if_scheduled_mark_missed that can be used to -check if napi is scheduled but that does more thing than simply checking -it and return a bool. Some driver already implement custom function to -check if napi is scheduled. - -Drop these custom function and introduce napi_is_scheduled that simply -check if napi is scheduled atomically. - -Update any driver and code that implement a similar check and instead -use this new helper. - -Signed-off-by: Christian Marangi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/chelsio/cxgb3/sge.c | 8 -------- - drivers/net/wireless/realtek/rtw89/core.c | 2 +- - include/linux/netdevice.h | 23 +++++++++++++++++++++++ - net/core/dev.c | 2 +- - 4 files changed, 25 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/chelsio/cxgb3/sge.c -+++ b/drivers/net/ethernet/chelsio/cxgb3/sge.c -@@ -2507,14 +2507,6 @@ static int napi_rx_handler(struct napi_s - return work_done; - } - --/* -- * Returns true if the device is already scheduled for polling. -- */ --static inline int napi_is_scheduled(struct napi_struct *napi) --{ -- return test_bit(NAPI_STATE_SCHED, &napi->state); --} -- - /** - * process_pure_responses - process pure responses from a response queue - * @adap: the adapter ---- a/drivers/net/wireless/realtek/rtw89/core.c -+++ b/drivers/net/wireless/realtek/rtw89/core.c -@@ -1479,7 +1479,7 @@ static void rtw89_core_rx_to_mac80211(st - struct napi_struct *napi = &rtwdev->napi; - - /* In low power mode, napi isn't scheduled. Receive it to netif. */ -- if (unlikely(!test_bit(NAPI_STATE_SCHED, &napi->state))) -+ if (unlikely(!napi_is_scheduled(napi))) - napi = NULL; - - rtw89_core_hw_to_sband_rate(rx_status); ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -468,6 +468,29 @@ static inline bool napi_prefer_busy_poll - return test_bit(NAPI_STATE_PREFER_BUSY_POLL, &n->state); - } - -+/** -+ * napi_is_scheduled - test if NAPI is scheduled -+ * @n: NAPI context -+ * -+ * This check is "best-effort". With no locking implemented, -+ * a NAPI can be scheduled or terminate right after this check -+ * and produce not precise results. -+ * -+ * NAPI_STATE_SCHED is an internal state, napi_is_scheduled -+ * should not be used normally and napi_schedule should be -+ * used instead. -+ * -+ * Use only if the driver really needs to check if a NAPI -+ * is scheduled for example in the context of delayed timer -+ * that can be skipped if a NAPI is already scheduled. -+ * -+ * Return True if NAPI is scheduled, False otherwise. -+ */ -+static inline bool napi_is_scheduled(struct napi_struct *n) -+{ -+ return test_bit(NAPI_STATE_SCHED, &n->state); -+} -+ - bool napi_schedule_prep(struct napi_struct *n); - - /** ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -6533,7 +6533,7 @@ static int __napi_poll(struct napi_struc - * accidentally calling ->poll() when NAPI is not scheduled. - */ - work = 0; -- if (test_bit(NAPI_STATE_SCHED, &n->state)) { -+ if (napi_is_scheduled(n)) { - work = n->poll(n, weight); - trace_napi_poll(n, work, weight); - } diff --git a/target/linux/generic/backport-6.1/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch b/target/linux/generic/backport-6.1/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch deleted file mode 100644 index aa0d730bc8a0fa..00000000000000 --- a/target/linux/generic/backport-6.1/771-v6.7-01-net-stmmac-improve-TX-timer-arm-logic.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 2d1a42cf7f77cda54dbbee18d00b1200e7bc22aa Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 18 Oct 2023 14:35:48 +0200 -Subject: [PATCH 1/3] net: stmmac: improve TX timer arm logic - -There is currently a problem with the TX timer getting armed multiple -unnecessary times causing big performance regression on some device that -suffer from heavy handling of hrtimer rearm. - -The use of the TX timer is an old implementation that predates the napi -implementation and the interrupt enable/disable handling. - -Due to stmmac being a very old code, the TX timer was never evaluated -again with this new implementation and was kept there causing -performance regression. The performance regression started to appear -with kernel version 4.19 with 8fce33317023 ("net: stmmac: Rework coalesce -timer and fix multi-queue races") where the timer was reduced to 1ms -causing it to be armed 40 times more than before. - -Decreasing the timer made the problem more present and caused the -regression in the other of 600-700mbps on some device (regression where -this was notice is ipq806x). - -The problem is in the fact that handling the hrtimer on some target is -expensive and recent kernel made the timer armed much more times. -A solution that was proposed was reverting the hrtimer change and use -mod_timer but such solution would still hide the real problem in the -current implementation. - -To fix the regression, apply some additional logic and skip arming the -timer when not needed. - -Arm the timer ONLY if a napi is not already scheduled. Running the timer -is redundant since the same function (stmmac_tx_clean) will run in the -napi TX poll. Also try to cancel any timer if a napi is scheduled to -prevent redundant run of TX call. - -With the following new logic the original performance are restored while -keeping using the hrtimer. - -Signed-off-by: Christian Marangi -Signed-off-by: Paolo Abeni ---- - .../net/ethernet/stmicro/stmmac/stmmac_main.c | 18 +++++++++++++++--- - 1 file changed, 15 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -2974,13 +2974,25 @@ static void stmmac_tx_timer_arm(struct s - { - struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - u32 tx_coal_timer = priv->tx_coal_timer[queue]; -+ struct stmmac_channel *ch; -+ struct napi_struct *napi; - - if (!tx_coal_timer) - return; - -- hrtimer_start(&tx_q->txtimer, -- STMMAC_COAL_TIMER(tx_coal_timer), -- HRTIMER_MODE_REL); -+ ch = &priv->channel[tx_q->queue_index]; -+ napi = tx_q->xsk_pool ? &ch->rxtx_napi : &ch->tx_napi; -+ -+ /* Arm timer only if napi is not already scheduled. -+ * Try to cancel any timer if napi is scheduled, timer will be armed -+ * again in the next scheduled napi. -+ */ -+ if (unlikely(!napi_is_scheduled(napi))) -+ hrtimer_start(&tx_q->txtimer, -+ STMMAC_COAL_TIMER(tx_coal_timer), -+ HRTIMER_MODE_REL); -+ else -+ hrtimer_try_to_cancel(&tx_q->txtimer); - } - - /** diff --git a/target/linux/generic/backport-6.1/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch b/target/linux/generic/backport-6.1/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch deleted file mode 100644 index 87361206540aad..00000000000000 --- a/target/linux/generic/backport-6.1/771-v6.7-02-net-stmmac-move-TX-timer-arm-after-DMA-enable.patch +++ /dev/null @@ -1,96 +0,0 @@ -From a594166387fe08e6f5a32130c400249a35b298f9 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 18 Oct 2023 14:35:49 +0200 -Subject: [PATCH 2/3] net: stmmac: move TX timer arm after DMA enable - -Move TX timer arm call after DMA interrupt is enabled again. - -The TX timer arm function changed logic and now is skipped if a napi is -already scheduled. By moving the TX timer arm call after DMA is enabled, -we permit to correctly skip if a DMA interrupt has been fired and a napi -has been scheduled again. - -Signed-off-by: Christian Marangi -Signed-off-by: Paolo Abeni ---- - .../net/ethernet/stmicro/stmmac/stmmac_main.c | 22 +++++++++++++++---- - 1 file changed, 18 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -2527,9 +2527,13 @@ static void stmmac_bump_dma_threshold(st - * @priv: driver private structure - * @budget: napi budget limiting this functions packet handling - * @queue: TX queue index -+ * @pending_packets: signal to arm the TX coal timer - * Description: it reclaims the transmit resources after transmission completes. -+ * If some packets still needs to be handled, due to TX coalesce, set -+ * pending_packets to true to make NAPI arm the TX coal timer. - */ --static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue) -+static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue, -+ bool *pending_packets) - { - struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; - unsigned int bytes_compl = 0, pkts_compl = 0; -@@ -2692,7 +2696,7 @@ static int stmmac_tx_clean(struct stmmac - - /* We still have pending packets, let's call for a new scheduling */ - if (tx_q->dirty_tx != tx_q->cur_tx) -- stmmac_tx_timer_arm(priv, queue); -+ *pending_packets = true; - - __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue)); - -@@ -5490,12 +5494,13 @@ static int stmmac_napi_poll_tx(struct na - struct stmmac_channel *ch = - container_of(napi, struct stmmac_channel, tx_napi); - struct stmmac_priv *priv = ch->priv_data; -+ bool pending_packets = false; - u32 chan = ch->index; - int work_done; - - priv->xstats.napi_poll++; - -- work_done = stmmac_tx_clean(priv, budget, chan); -+ work_done = stmmac_tx_clean(priv, budget, chan, &pending_packets); - work_done = min(work_done, budget); - - if (work_done < budget && napi_complete_done(napi, work_done)) { -@@ -5506,6 +5511,10 @@ static int stmmac_napi_poll_tx(struct na - spin_unlock_irqrestore(&ch->lock, flags); - } - -+ /* TX still have packet to handle, check if we need to arm tx timer */ -+ if (pending_packets) -+ stmmac_tx_timer_arm(priv, chan); -+ - return work_done; - } - -@@ -5514,12 +5523,13 @@ static int stmmac_napi_poll_rxtx(struct - struct stmmac_channel *ch = - container_of(napi, struct stmmac_channel, rxtx_napi); - struct stmmac_priv *priv = ch->priv_data; -+ bool tx_pending_packets = false; - int rx_done, tx_done, rxtx_done; - u32 chan = ch->index; - - priv->xstats.napi_poll++; - -- tx_done = stmmac_tx_clean(priv, budget, chan); -+ tx_done = stmmac_tx_clean(priv, budget, chan, &tx_pending_packets); - tx_done = min(tx_done, budget); - - rx_done = stmmac_rx_zc(priv, budget, chan); -@@ -5544,6 +5554,10 @@ static int stmmac_napi_poll_rxtx(struct - spin_unlock_irqrestore(&ch->lock, flags); - } - -+ /* TX still have packet to handle, check if we need to arm tx timer */ -+ if (tx_pending_packets) -+ stmmac_tx_timer_arm(priv, chan); -+ - return min(rxtx_done, budget - 1); - } - diff --git a/target/linux/generic/backport-6.1/771-v6.7-03-net-stmmac-increase-TX-coalesce-timer-to-5ms.patch b/target/linux/generic/backport-6.1/771-v6.7-03-net-stmmac-increase-TX-coalesce-timer-to-5ms.patch deleted file mode 100644 index bce54eba4f0679..00000000000000 --- a/target/linux/generic/backport-6.1/771-v6.7-03-net-stmmac-increase-TX-coalesce-timer-to-5ms.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 039550960a2235cfe2dfaa773df9f98f8da31a0c Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 18 Oct 2023 14:35:50 +0200 -Subject: [PATCH 3/3] net: stmmac: increase TX coalesce timer to 5ms - -Commit 8fce33317023 ("net: stmmac: Rework coalesce timer and fix -multi-queue races") decreased the TX coalesce timer from 40ms to 1ms. - -This caused some performance regression on some target (regression was -reported at least on ipq806x) in the order of 600mbps dropping from -gigabit handling to only 200mbps. - -The problem was identified in the TX timer getting armed too much time. -While this was fixed and improved in another commit, performance can be -improved even further by increasing the timer delay a bit moving from -1ms to 5ms. - -The value is a good balance between battery saving by prevending too -much interrupt to be generated and permitting good performance for -internet oriented devices. - -Signed-off-by: Christian Marangi -Signed-off-by: Paolo Abeni ---- - drivers/net/ethernet/stmicro/stmmac/common.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/common.h -+++ b/drivers/net/ethernet/stmicro/stmmac/common.h -@@ -287,7 +287,7 @@ struct stmmac_safety_stats { - #define MIN_DMA_RIWT 0x10 - #define DEF_DMA_RIWT 0xa0 - /* Tx coalesce parameters */ --#define STMMAC_COAL_TX_TIMER 1000 -+#define STMMAC_COAL_TX_TIMER 5000 - #define STMMAC_MAX_COAL_TX_TICK 100000 - #define STMMAC_TX_MAX_FRAMES 256 - #define STMMAC_TX_FRAMES 25 diff --git a/target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch b/target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch deleted file mode 100644 index c0320ad6f9d8ab..00000000000000 --- a/target/linux/generic/backport-6.1/777-v6.2-04-net-dsa-qca8k-introduce-single-mii-read-write-lo-hi.patch +++ /dev/null @@ -1,150 +0,0 @@ -From cfbd6de588ef659c198083205dc954a6d3ed2aec Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 29 Dec 2022 17:33:35 +0100 -Subject: [PATCH 4/5] net: dsa: qca8k: introduce single mii read/write lo/hi - -It may be useful to read/write just the lo or hi half of a reg. - -This is especially useful for phy poll with the use of mdio master. -The mdio master reg is composed by the first 16 bit related to setup and -the other half with the returned data or data to write. - -Refactor the mii function to permit single mii read/write of lo or hi -half of the reg. - -Tested-by: Ronald Wahl -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 106 ++++++++++++++++++++++++------- - 1 file changed, 84 insertions(+), 22 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -37,42 +37,104 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u - } - - static int --qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) -+qca8k_mii_write_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) - { - int ret; -+ u16 lo; - -- ret = bus->read(bus, phy_id, regnum); -- if (ret >= 0) { -- *val = ret; -- ret = bus->read(bus, phy_id, regnum + 1); -- *val |= ret << 16; -- } -+ lo = val & 0xffff; -+ ret = bus->write(bus, phy_id, regnum, lo); -+ if (ret < 0) -+ dev_err_ratelimited(&bus->dev, -+ "failed to write qca8k 32bit lo register\n"); -+ -+ return ret; -+} - -- if (ret < 0) { -+static int -+qca8k_mii_write_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) -+{ -+ int ret; -+ u16 hi; -+ -+ hi = (u16)(val >> 16); -+ ret = bus->write(bus, phy_id, regnum, hi); -+ if (ret < 0) - dev_err_ratelimited(&bus->dev, -- "failed to read qca8k 32bit register\n"); -- *val = 0; -- return ret; -- } -+ "failed to write qca8k 32bit hi register\n"); - -+ return ret; -+} -+ -+static int -+qca8k_mii_read_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) -+{ -+ int ret; -+ -+ ret = bus->read(bus, phy_id, regnum); -+ if (ret < 0) -+ goto err; -+ -+ *val = ret & 0xffff; - return 0; -+ -+err: -+ dev_err_ratelimited(&bus->dev, -+ "failed to read qca8k 32bit lo register\n"); -+ *val = 0; -+ -+ return ret; - } - --static void --qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) -+static int -+qca8k_mii_read_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) - { -- u16 lo, hi; - int ret; - -- lo = val & 0xffff; -- hi = (u16)(val >> 16); -+ ret = bus->read(bus, phy_id, regnum); -+ if (ret < 0) -+ goto err; - -- ret = bus->write(bus, phy_id, regnum, lo); -- if (ret >= 0) -- ret = bus->write(bus, phy_id, regnum + 1, hi); -+ *val = ret << 16; -+ return 0; -+ -+err: -+ dev_err_ratelimited(&bus->dev, -+ "failed to read qca8k 32bit hi register\n"); -+ *val = 0; -+ -+ return ret; -+} -+ -+static int -+qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val) -+{ -+ u32 hi, lo; -+ int ret; -+ -+ *val = 0; -+ -+ ret = qca8k_mii_read_lo(bus, phy_id, regnum, &lo); - if (ret < 0) -- dev_err_ratelimited(&bus->dev, -- "failed to write qca8k 32bit register\n"); -+ goto err; -+ -+ ret = qca8k_mii_read_hi(bus, phy_id, regnum + 1, &hi); -+ if (ret < 0) -+ goto err; -+ -+ *val = lo | hi; -+ -+err: -+ return ret; -+} -+ -+static void -+qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) -+{ -+ if (qca8k_mii_write_lo(bus, phy_id, regnum, val) < 0) -+ return; -+ -+ qca8k_mii_write_hi(bus, phy_id, regnum + 1, val); - } - - static int diff --git a/target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch b/target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch deleted file mode 100644 index dcafad0fd5edfa..00000000000000 --- a/target/linux/generic/backport-6.1/777-v6.2-05-net-dsa-qca8k-improve-mdio-master-read-write-by-usin.patch +++ /dev/null @@ -1,73 +0,0 @@ -From a4165830ca237f2b3318faf62562bce8ce12a389 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 29 Dec 2022 17:33:36 +0100 -Subject: [PATCH 5/5] net: dsa: qca8k: improve mdio master read/write by using - single lo/hi - -Improve mdio master read/write by using singe mii read/write lo/hi. - -In a read and write we need to poll the mdio master regs in a busy loop -to check for a specific bit present in the upper half of the reg. We can -ignore the other half since it won't contain useful data. This will save -an additional useless read for each read and write operation. - -In a read operation the returned data is present in the mdio master reg -lower half. We can ignore the other half since it won't contain useful -data. This will save an additional useless read for each read operation. - -In a read operation it's needed to just set the hi half of the mdio -master reg as the lo half will be replaced by the result. This will save -an additional useless write for each read operation. - -Tested-by: Ronald Wahl -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -754,9 +754,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus - - qca8k_split_addr(reg, &r1, &r2, &page); - -- ret = read_poll_timeout(qca8k_mii_read32, ret1, !(val & mask), 0, -+ ret = read_poll_timeout(qca8k_mii_read_hi, ret1, !(val & mask), 0, - QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false, -- bus, 0x10 | r2, r1, &val); -+ bus, 0x10 | r2, r1 + 1, &val); - - /* Check if qca8k_read has failed for a different reason - * before returnting -ETIMEDOUT -@@ -798,7 +798,7 @@ qca8k_mdio_write(struct qca8k_priv *priv - - exit: - /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(bus, 0x10 | r2, r1, 0); -+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0); - - mutex_unlock(&bus->mdio_lock); - -@@ -828,18 +828,18 @@ qca8k_mdio_read(struct qca8k_priv *priv, - if (ret) - goto exit; - -- qca8k_mii_write32(bus, 0x10 | r2, r1, val); -+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, val); - - ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL, - QCA8K_MDIO_MASTER_BUSY); - if (ret) - goto exit; - -- ret = qca8k_mii_read32(bus, 0x10 | r2, r1, &val); -+ ret = qca8k_mii_read_lo(bus, 0x10 | r2, r1, &val); - - exit: - /* even if the busy_wait timeouts try to clear the MASTER_EN */ -- qca8k_mii_write32(bus, 0x10 | r2, r1, 0); -+ qca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0); - - mutex_unlock(&bus->mdio_lock); - diff --git a/target/linux/generic/backport-6.1/778-v6.3-01-net-dsa-qca8k-add-QCA8K_ATU_TABLE_SIZE-define-for-fd.patch b/target/linux/generic/backport-6.1/778-v6.3-01-net-dsa-qca8k-add-QCA8K_ATU_TABLE_SIZE-define-for-fd.patch deleted file mode 100644 index 9331fd536d9a8e..00000000000000 --- a/target/linux/generic/backport-6.1/778-v6.3-01-net-dsa-qca8k-add-QCA8K_ATU_TABLE_SIZE-define-for-fd.patch +++ /dev/null @@ -1,63 +0,0 @@ -From e03cea60c3db8c6b011cc36ecef9281dff8377f3 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 25 Jan 2023 21:35:16 +0100 -Subject: [PATCH] net: dsa: qca8k: add QCA8K_ATU_TABLE_SIZE define for fdb - access - -Add and use QCA8K_ATU_TABLE_SIZE instead of hardcoding the ATU size with -a pure number and using sizeof on the array. - -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-common.c | 10 ++++++---- - drivers/net/dsa/qca/qca8k.h | 2 ++ - 2 files changed, 8 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -150,11 +150,12 @@ static int qca8k_busy_wait(struct qca8k_ - - static int qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) - { -- u32 reg[3]; -+ u32 reg[QCA8K_ATU_TABLE_SIZE]; - int ret; - - /* load the ARL table into an array */ -- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -+ ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, -+ QCA8K_ATU_TABLE_SIZE * sizeof(u32)); - if (ret) - return ret; - -@@ -178,7 +179,7 @@ static int qca8k_fdb_read(struct qca8k_p - static void qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, - const u8 *mac, u8 aging) - { -- u32 reg[3] = { 0 }; -+ u32 reg[QCA8K_ATU_TABLE_SIZE] = { 0 }; - - /* vid - 83:72 */ - reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid); -@@ -195,7 +196,8 @@ static void qca8k_fdb_write(struct qca8k - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); - - /* load the array into the ARL table */ -- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg)); -+ qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, -+ QCA8K_ATU_TABLE_SIZE * sizeof(u32)); - } - - static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -148,6 +148,8 @@ - #define QCA8K_REG_IPV4_PRI_ADDR_MASK 0x474 - - /* Lookup registers */ -+#define QCA8K_ATU_TABLE_SIZE 3 /* 12 bytes wide table / sizeof(u32) */ -+ - #define QCA8K_REG_ATU_DATA0 0x600 - #define QCA8K_ATU_ADDR2_MASK GENMASK(31, 24) - #define QCA8K_ATU_ADDR3_MASK GENMASK(23, 16) diff --git a/target/linux/generic/backport-6.1/778-v6.3-02-net-dsa-qca8k-convert-to-regmap-read-write-API.patch b/target/linux/generic/backport-6.1/778-v6.3-02-net-dsa-qca8k-convert-to-regmap-read-write-API.patch deleted file mode 100644 index b8f8071b0a14f3..00000000000000 --- a/target/linux/generic/backport-6.1/778-v6.3-02-net-dsa-qca8k-convert-to-regmap-read-write-API.patch +++ /dev/null @@ -1,261 +0,0 @@ -From c766e077d927e1775902c18827205ea2ade3a35d Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 25 Jan 2023 21:35:17 +0100 -Subject: [PATCH] net: dsa: qca8k: convert to regmap read/write API - -Convert qca8k to regmap read/write bulk API. The mgmt eth can write up -to 32 bytes of data at times. Currently we use a custom function to do -it but regmap now supports declaration of read/write bulk even without a -bus. - -Drop the custom function and rework the regmap function to this new -implementation. - -Rework the qca8k_fdb_read/write function to use the new -regmap_bulk_read/write as the old qca8k_bulk_read/write are now dropped. - -Cc: Mark Brown -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 92 ++++++++++++++++++++++++------ - drivers/net/dsa/qca/qca8k-common.c | 47 ++------------- - drivers/net/dsa/qca/qca8k.h | 3 - - 3 files changed, 77 insertions(+), 65 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -425,16 +425,12 @@ qca8k_regmap_update_bits_eth(struct qca8 - } - - static int --qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) -+qca8k_read_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t *val) - { -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; - struct mii_bus *bus = priv->bus; - u16 r1, r2, page; - int ret; - -- if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) -- return 0; -- - qca8k_split_addr(reg, &r1, &r2, &page); - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -@@ -451,16 +447,12 @@ exit: - } - - static int --qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) -+qca8k_write_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t val) - { -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; - struct mii_bus *bus = priv->bus; - u16 r1, r2, page; - int ret; - -- if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) -- return 0; -- - qca8k_split_addr(reg, &r1, &r2, &page); - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -@@ -477,17 +469,14 @@ exit: - } - - static int --qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) -+qca8k_regmap_update_bits_mii(struct qca8k_priv *priv, uint32_t reg, -+ uint32_t mask, uint32_t write_val) - { -- struct qca8k_priv *priv = (struct qca8k_priv *)ctx; - struct mii_bus *bus = priv->bus; - u16 r1, r2, page; - u32 val; - int ret; - -- if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) -- return 0; -- - qca8k_split_addr(reg, &r1, &r2, &page); - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -@@ -510,17 +499,84 @@ exit: - return ret; - } - -+static int -+qca8k_bulk_read(void *ctx, const void *reg_buf, size_t reg_len, -+ void *val_buf, size_t val_len) -+{ -+ int i, count = val_len / sizeof(u32), ret; -+ u32 reg = *(u32 *)reg_buf & U16_MAX; -+ struct qca8k_priv *priv = ctx; -+ -+ if (priv->mgmt_master && -+ !qca8k_read_eth(priv, reg, val_buf, val_len)) -+ return 0; -+ -+ /* loop count times and increment reg of 4 */ -+ for (i = 0; i < count; i++, reg += sizeof(u32)) { -+ ret = qca8k_read_mii(priv, reg, val_buf + i); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_bulk_gather_write(void *ctx, const void *reg_buf, size_t reg_len, -+ const void *val_buf, size_t val_len) -+{ -+ int i, count = val_len / sizeof(u32), ret; -+ u32 reg = *(u32 *)reg_buf & U16_MAX; -+ struct qca8k_priv *priv = ctx; -+ u32 *val = (u32 *)val_buf; -+ -+ if (priv->mgmt_master && -+ !qca8k_write_eth(priv, reg, val, val_len)) -+ return 0; -+ -+ /* loop count times, increment reg of 4 and increment val ptr to -+ * the next value -+ */ -+ for (i = 0; i < count; i++, reg += sizeof(u32), val++) { -+ ret = qca8k_write_mii(priv, reg, *val); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_bulk_write(void *ctx, const void *data, size_t bytes) -+{ -+ return qca8k_bulk_gather_write(ctx, data, sizeof(u16), data + sizeof(u16), -+ bytes - sizeof(u16)); -+} -+ -+static int -+qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) -+{ -+ struct qca8k_priv *priv = ctx; -+ -+ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) -+ return 0; -+ -+ return qca8k_regmap_update_bits_mii(priv, reg, mask, write_val); -+} -+ - static struct regmap_config qca8k_regmap_config = { - .reg_bits = 16, - .val_bits = 32, - .reg_stride = 4, - .max_register = 0x16ac, /* end MIB - Port6 range */ -- .reg_read = qca8k_regmap_read, -- .reg_write = qca8k_regmap_write, -+ .read = qca8k_bulk_read, -+ .write = qca8k_bulk_write, - .reg_update_bits = qca8k_regmap_update_bits, - .rd_table = &qca8k_readable_table, - .disable_locking = true, /* Locking is handled by qca8k read/write */ - .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ -+ .max_raw_read = 32, /* mgmt eth can read/write up to 8 registers at time */ -+ .max_raw_write = 32, - }; - - static int -@@ -2112,8 +2168,6 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, - - static const struct qca8k_info_ops qca8xxx_ops = { - .autocast_mib = qca8k_get_ethtool_stats_eth, -- .read_eth = qca8k_read_eth, -- .write_eth = qca8k_write_eth, - }; - - static const struct qca8k_match_data qca8327 = { ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -101,45 +101,6 @@ const struct regmap_access_table qca8k_r - .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), - }; - --/* TODO: remove these extra ops when we can support regmap bulk read/write */ --static int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- int i, count = len / sizeof(u32), ret; -- -- if (priv->mgmt_master && priv->info->ops->read_eth && -- !priv->info->ops->read_eth(priv, reg, val, len)) -- return 0; -- -- for (i = 0; i < count; i++) { -- ret = regmap_read(priv->regmap, reg + (i * 4), val + i); -- if (ret < 0) -- return ret; -- } -- -- return 0; --} -- --/* TODO: remove these extra ops when we can support regmap bulk read/write */ --static int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) --{ -- int i, count = len / sizeof(u32), ret; -- u32 tmp; -- -- if (priv->mgmt_master && priv->info->ops->write_eth && -- !priv->info->ops->write_eth(priv, reg, val, len)) -- return 0; -- -- for (i = 0; i < count; i++) { -- tmp = val[i]; -- -- ret = regmap_write(priv->regmap, reg + (i * 4), tmp); -- if (ret < 0) -- return ret; -- } -- -- return 0; --} -- - static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) - { - u32 val; -@@ -154,8 +115,8 @@ static int qca8k_fdb_read(struct qca8k_p - int ret; - - /* load the ARL table into an array */ -- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, -- QCA8K_ATU_TABLE_SIZE * sizeof(u32)); -+ ret = regmap_bulk_read(priv->regmap, QCA8K_REG_ATU_DATA0, reg, -+ QCA8K_ATU_TABLE_SIZE); - if (ret) - return ret; - -@@ -196,8 +157,8 @@ static void qca8k_fdb_write(struct qca8k - reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); - - /* load the array into the ARL table */ -- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, -- QCA8K_ATU_TABLE_SIZE * sizeof(u32)); -+ regmap_bulk_write(priv->regmap, QCA8K_REG_ATU_DATA0, reg, -+ QCA8K_ATU_TABLE_SIZE); - } - - static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -330,9 +330,6 @@ struct qca8k_priv; - - struct qca8k_info_ops { - int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data); -- /* TODO: remove these extra ops when we can support regmap bulk read/write */ -- int (*read_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len); -- int (*write_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len); - }; - - struct qca8k_match_data { diff --git a/target/linux/generic/backport-6.1/779-v6.5-net-dsa-qca8k-enable-use_single_write-for-qca8xxx.patch b/target/linux/generic/backport-6.1/779-v6.5-net-dsa-qca8k-enable-use_single_write-for-qca8xxx.patch deleted file mode 100644 index 3619440f075ade..00000000000000 --- a/target/linux/generic/backport-6.1/779-v6.5-net-dsa-qca8k-enable-use_single_write-for-qca8xxx.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 2c39dd025da489cf87d26469d9f5ff19715324a0 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 24 Jul 2023 05:25:28 +0200 -Subject: [PATCH 1/4] net: dsa: qca8k: enable use_single_write for qca8xxx - -The qca8xxx switch supports 2 way to write reg values, a slow way using -mdio and a fast way by sending specially crafted mgmt packet to -read/write reg. - -The fast way can support up to 32 bytes of data as eth packet are used -to send/receive. - -This correctly works for almost the entire regmap of the switch but with -the use of some kernel selftests for dsa drivers it was found a funny -and interesting hw defect/limitation. - -For some specific reg, bulk write won't work and will result in writing -only part of the requested regs resulting in half data written. This was -especially hard to track and discover due to the total strangeness of -the problem and also by the specific regs where this occurs. - -This occurs in the specific regs of the ATU table, where multiple entry -needs to be written to compose the entire entry. -It was discovered that with a bulk write of 12 bytes on -QCA8K_REG_ATU_DATA0 only QCA8K_REG_ATU_DATA0 and QCA8K_REG_ATU_DATA2 -were written, but QCA8K_REG_ATU_DATA1 was always zero. -Tcpdump was used to make sure the specially crafted packet was correct -and this was confirmed. - -The problem was hard to track as the lack of QCA8K_REG_ATU_DATA1 -resulted in an entry somehow possible as the first bytes of the mac -address are set in QCA8K_REG_ATU_DATA0 and the entry type is set in -QCA8K_REG_ATU_DATA2. - -Funlly enough writing QCA8K_REG_ATU_DATA1 results in the same problem -with QCA8K_REG_ATU_DATA2 empty and QCA8K_REG_ATU_DATA1 and -QCA8K_REG_ATU_FUNC correctly written. -A speculation on the problem might be that there are some kind of -indirection internally when accessing these regs and they can't be -accessed all together, due to the fact that it's really a table mapped -somewhere in the switch SRAM. - -Even more funny is the fact that every other reg was tested with all -kind of combination and they are not affected by this problem. Read -operation was also tested and always worked so it's not affected by this -problem. - -The problem is not present if we limit writing a single reg at times. - -To handle this hardware defect, enable use_single_write so that bulk -api can correctly split the write in multiple different operation -effectively reverting to a non-bulk write. - -Cc: Mark Brown -Fixes: c766e077d927 ("net: dsa: qca8k: convert to regmap read/write API") -Signed-off-by: Christian Marangi -Cc: stable@vger.kernel.org -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -575,8 +575,11 @@ static struct regmap_config qca8k_regmap - .rd_table = &qca8k_readable_table, - .disable_locking = true, /* Locking is handled by qca8k read/write */ - .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ -- .max_raw_read = 32, /* mgmt eth can read/write up to 8 registers at time */ -- .max_raw_write = 32, -+ .max_raw_read = 32, /* mgmt eth can read up to 8 registers at time */ -+ /* ATU regs suffer from a bug where some data are not correctly -+ * written. Disable bulk write to correctly write ATU entry. -+ */ -+ .use_single_write = true, - }; - - static int diff --git a/target/linux/generic/backport-6.1/780-v6.6-01-net-dsa-qca8k-make-learning-configurable-and-keep-of.patch b/target/linux/generic/backport-6.1/780-v6.6-01-net-dsa-qca8k-make-learning-configurable-and-keep-of.patch deleted file mode 100644 index d31789370e8c6b..00000000000000 --- a/target/linux/generic/backport-6.1/780-v6.6-01-net-dsa-qca8k-make-learning-configurable-and-keep-of.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 23cfc7172e5297d0bee49ac6f6f8248d1cf0820d Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 30 Jul 2023 09:41:10 +0200 -Subject: [PATCH 1/4] net: dsa: qca8k: make learning configurable and keep off - if standalone - -Address learning should initially be turned off by the driver for port -operation in standalone mode, then the DSA core handles changes to it -via ds->ops->port_bridge_flags(). - -Currently this is not the case for qca8k where learning is enabled -unconditionally in qca8k_setup for every user port. - -Handle ports configured in standalone mode by making the learning -configurable and not enabling it by default. - -Implement .port_pre_bridge_flags and .port_bridge_flags dsa ops to -enable learning for bridge that request it and tweak -.port_stp_state_set to correctly disable learning when port is -configured in standalone mode. - -Signed-off-by: Christian Marangi -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Link: https://lore.kernel.org/r/20230730074113.21889-2-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++-- - drivers/net/dsa/qca/qca8k-common.c | 48 ++++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 6 ++++ - 3 files changed, 58 insertions(+), 3 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1905,9 +1905,8 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -- /* Enable ARP Auto-learning by default */ -- ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_LEARN); -+ ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), -+ QCA8K_PORT_LOOKUP_LEARN); - if (ret) - return ret; - -@@ -2013,6 +2012,8 @@ static const struct dsa_switch_ops qca8k - .port_change_mtu = qca8k_port_change_mtu, - .port_max_mtu = qca8k_port_max_mtu, - .port_stp_state_set = qca8k_port_stp_state_set, -+ .port_pre_bridge_flags = qca8k_port_pre_bridge_flags, -+ .port_bridge_flags = qca8k_port_bridge_flags, - .port_bridge_join = qca8k_port_bridge_join, - .port_bridge_leave = qca8k_port_bridge_leave, - .port_fast_age = qca8k_port_fast_age, ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -565,9 +565,26 @@ int qca8k_get_mac_eee(struct dsa_switch - return 0; - } - -+static int qca8k_port_configure_learning(struct dsa_switch *ds, int port, -+ bool learning) -+{ -+ struct qca8k_priv *priv = ds->priv; -+ -+ if (learning) -+ return regmap_set_bits(priv->regmap, -+ QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_LEARN); -+ else -+ return regmap_clear_bits(priv->regmap, -+ QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_LEARN); -+} -+ - void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) - { -+ struct dsa_port *dp = dsa_to_port(ds, port); - struct qca8k_priv *priv = ds->priv; -+ bool learning = false; - u32 stp_state; - - switch (state) { -@@ -582,8 +599,11 @@ void qca8k_port_stp_state_set(struct dsa - break; - case BR_STATE_LEARNING: - stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; -+ learning = dp->learning; - break; - case BR_STATE_FORWARDING: -+ learning = dp->learning; -+ fallthrough; - default: - stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; - break; -@@ -591,6 +611,34 @@ void qca8k_port_stp_state_set(struct dsa - - qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), - QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); -+ -+ qca8k_port_configure_learning(ds, port, learning); -+} -+ -+int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port, -+ struct switchdev_brport_flags flags, -+ struct netlink_ext_ack *extack) -+{ -+ if (flags.mask & ~BR_LEARNING) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+int qca8k_port_bridge_flags(struct dsa_switch *ds, int port, -+ struct switchdev_brport_flags flags, -+ struct netlink_ext_ack *extack) -+{ -+ int ret; -+ -+ if (flags.mask & BR_LEARNING) { -+ ret = qca8k_port_configure_learning(ds, port, -+ flags.val & BR_LEARNING); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; - } - - int qca8k_port_bridge_join(struct dsa_switch *ds, int port, ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -448,6 +448,12 @@ int qca8k_get_mac_eee(struct dsa_switch - - /* Common bridge function */ - void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state); -+int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port, -+ struct switchdev_brport_flags flags, -+ struct netlink_ext_ack *extack); -+int qca8k_port_bridge_flags(struct dsa_switch *ds, int port, -+ struct switchdev_brport_flags flags, -+ struct netlink_ext_ack *extack); - int qca8k_port_bridge_join(struct dsa_switch *ds, int port, - struct dsa_bridge bridge, - bool *tx_fwd_offload, diff --git a/target/linux/generic/backport-6.1/780-v6.6-02-net-dsa-qca8k-limit-user-ports-access-to-the-first-C.patch b/target/linux/generic/backport-6.1/780-v6.6-02-net-dsa-qca8k-limit-user-ports-access-to-the-first-C.patch deleted file mode 100644 index 4b457f67de8a6c..00000000000000 --- a/target/linux/generic/backport-6.1/780-v6.6-02-net-dsa-qca8k-limit-user-ports-access-to-the-first-C.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 18e8feae4a807994e4906d659116d249bfecd4c5 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 30 Jul 2023 09:41:11 +0200 -Subject: [PATCH 2/4] net: dsa: qca8k: limit user ports access to the first CPU - port on setup - -In preparation for multi-CPU support, set CPU port LOOKUP MEMBER outside -the port loop and setup the LOOKUP MEMBER mask for user ports only to -the first CPU port. - -This is to handle flooding condition where every CPU port is set as -target and prevent packet duplication for unknown frames from user ports. - -Secondary CPU port LOOKUP MEMBER mask will be setup later when -port_change_master will be implemented. - -Signed-off-by: Christian Marangi -Reviewed-by: Simon Horman -Reviewed-by: Florian Fainelli -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/20230730074113.21889-3-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 14 ++++++-------- - 1 file changed, 6 insertions(+), 8 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1885,18 +1885,16 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -+ /* CPU port gets connected to all user ports of the switch */ -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port), -+ QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); -+ if (ret) -+ return ret; -+ - /* Setup connection between CPU port & user ports - * Configure specific switch configuration for ports - */ - for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- /* CPU port gets connected to all user ports of the switch */ -- if (dsa_is_cpu_port(ds, i)) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); -- if (ret) -- return ret; -- } -- - /* Individual user ports get connected to CPU port only */ - if (dsa_is_user_port(ds, i)) { - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), diff --git a/target/linux/generic/backport-6.1/780-v6.6-03-net-dsa-qca8k-move-qca8xxx-hol-fixup-to-separate-fun.patch b/target/linux/generic/backport-6.1/780-v6.6-03-net-dsa-qca8k-move-qca8xxx-hol-fixup-to-separate-fun.patch deleted file mode 100644 index f556628b5b5dea..00000000000000 --- a/target/linux/generic/backport-6.1/780-v6.6-03-net-dsa-qca8k-move-qca8xxx-hol-fixup-to-separate-fun.patch +++ /dev/null @@ -1,111 +0,0 @@ -From a9108b0712bf018dc69020864b21485b71b17dfc Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 30 Jul 2023 09:41:12 +0200 -Subject: [PATCH 3/4] net: dsa: qca8k: move qca8xxx hol fixup to separate - function - -Move qca8xxx hol fixup to separate function to tidy things up and to -permit using a more efficent loop in future patch. - -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Link: https://lore.kernel.org/r/20230730074113.21889-4-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 78 +++++++++++++++++--------------- - 1 file changed, 42 insertions(+), 36 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1795,6 +1795,46 @@ static int qca8k_connect_tag_protocol(st - return 0; - } - -+static void qca8k_setup_hol_fixup(struct qca8k_priv *priv, int port) -+{ -+ u32 mask; -+ -+ switch (port) { -+ /* The 2 CPU port and port 5 requires some different -+ * priority than any other ports. -+ */ -+ case 0: -+ case 5: -+ case 6: -+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | -+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); -+ break; -+ default: -+ mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | -+ QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | -+ QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); -+ } -+ regmap_write(priv->regmap, QCA8K_REG_PORT_HOL_CTRL0(port), mask); -+ -+ mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | -+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_WRED_EN; -+ regmap_update_bits(priv->regmap, QCA8K_REG_PORT_HOL_CTRL1(port), -+ QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | -+ QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -+ QCA8K_PORT_HOL_CTRL1_WRED_EN, -+ mask); -+} -+ - static int - qca8k_setup(struct dsa_switch *ds) - { -@@ -1930,42 +1970,8 @@ qca8k_setup(struct dsa_switch *ds) - * missing settings to improve switch stability under load condition. - * This problem is limited to qca8337 and other qca8k switch are not affected. - */ -- if (priv->switch_id == QCA8K_ID_QCA8337) { -- switch (i) { -- /* The 2 CPU port and port 5 requires some different -- * priority than any other ports. -- */ -- case 0: -- case 5: -- case 6: -- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI4(0x6) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI5(0x8) | -- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x1e); -- break; -- default: -- mask = QCA8K_PORT_HOL_CTRL0_EG_PRI0(0x3) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI1(0x4) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI2(0x6) | -- QCA8K_PORT_HOL_CTRL0_EG_PRI3(0x8) | -- QCA8K_PORT_HOL_CTRL0_EG_PORT(0x19); -- } -- qca8k_write(priv, QCA8K_REG_PORT_HOL_CTRL0(i), mask); -- -- mask = QCA8K_PORT_HOL_CTRL1_ING(0x6) | -- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_WRED_EN; -- qca8k_rmw(priv, QCA8K_REG_PORT_HOL_CTRL1(i), -- QCA8K_PORT_HOL_CTRL1_ING_BUF_MASK | -- QCA8K_PORT_HOL_CTRL1_EG_PRI_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_EG_PORT_BUF_EN | -- QCA8K_PORT_HOL_CTRL1_WRED_EN, -- mask); -- } -+ if (priv->switch_id == QCA8K_ID_QCA8337) -+ qca8k_setup_hol_fixup(priv, i); - } - - /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ diff --git a/target/linux/generic/backport-6.1/780-v6.6-04-net-dsa-qca8k-use-dsa_for_each-macro-instead-of-for-.patch b/target/linux/generic/backport-6.1/780-v6.6-04-net-dsa-qca8k-use-dsa_for_each-macro-instead-of-for-.patch deleted file mode 100644 index faa0142ca997ba..00000000000000 --- a/target/linux/generic/backport-6.1/780-v6.6-04-net-dsa-qca8k-use-dsa_for_each-macro-instead-of-for-.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 01e6f8ad8d26ced14b0cf288c42e55d03a7c5070 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 30 Jul 2023 09:41:13 +0200 -Subject: [PATCH 4/4] net: dsa: qca8k: use dsa_for_each macro instead of for - loop - -Convert for loop to dsa_for_each macro to save some redundant write on -unconnected/unused port and tidy things up. - -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Link: https://lore.kernel.org/r/20230730074113.21889-5-ansuelsmth@gmail.com -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 107 ++++++++++++++++--------------- - 1 file changed, 54 insertions(+), 53 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1839,7 +1839,8 @@ static int - qca8k_setup(struct dsa_switch *ds) - { - struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -- int cpu_port, ret, i; -+ struct dsa_port *dp; -+ int cpu_port, ret; - u32 mask; - - cpu_port = qca8k_find_cpu_port(ds); -@@ -1890,27 +1891,27 @@ qca8k_setup(struct dsa_switch *ds) - dev_warn(priv->dev, "mib init failed"); - - /* Initial setup of all ports */ -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -+ dsa_switch_for_each_port(dp, ds) { - /* Disable forwarding by default on all ports */ -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(dp->index), - QCA8K_PORT_LOOKUP_MEMBER, 0); - if (ret) - return ret; -+ } - -- /* Enable QCA header mode on all cpu ports */ -- if (dsa_is_cpu_port(ds, i)) { -- ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(i), -- FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | -- FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); -- if (ret) { -- dev_err(priv->dev, "failed enabling QCA header mode"); -- return ret; -- } -+ /* Disable MAC by default on all user ports */ -+ dsa_switch_for_each_user_port(dp, ds) -+ qca8k_port_set_status(priv, dp->index, 0); -+ -+ /* Enable QCA header mode on all cpu ports */ -+ dsa_switch_for_each_cpu_port(dp, ds) { -+ ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(dp->index), -+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_TX_MASK, QCA8K_PORT_HDR_CTRL_ALL) | -+ FIELD_PREP(QCA8K_PORT_HDR_CTRL_RX_MASK, QCA8K_PORT_HDR_CTRL_ALL)); -+ if (ret) { -+ dev_err(priv->dev, "failed enabling QCA header mode on port %d", dp->index); -+ return ret; - } -- -- /* Disable MAC by default on all user ports */ -- if (dsa_is_user_port(ds, i)) -- qca8k_port_set_status(priv, i, 0); - } - - /* Forward all unknown frames to CPU port for Linux processing -@@ -1932,48 +1933,48 @@ qca8k_setup(struct dsa_switch *ds) - return ret; - - /* Setup connection between CPU port & user ports -- * Configure specific switch configuration for ports -+ * Individual user ports get connected to CPU port only - */ -- for (i = 0; i < QCA8K_NUM_PORTS; i++) { -- /* Individual user ports get connected to CPU port only */ -- if (dsa_is_user_port(ds, i)) { -- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_MEMBER, -- BIT(cpu_port)); -- if (ret) -- return ret; -- -- ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i), -- QCA8K_PORT_LOOKUP_LEARN); -- if (ret) -- return ret; -- -- /* For port based vlans to work we need to set the -- * default egress vid -- */ -- ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), -- QCA8K_EGREES_VLAN_PORT_MASK(i), -- QCA8K_EGREES_VLAN_PORT(i, QCA8K_PORT_VID_DEF)); -- if (ret) -- return ret; -- -- ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), -- QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | -- QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); -- if (ret) -- return ret; -- } -+ dsa_switch_for_each_user_port(dp, ds) { -+ u8 port = dp->index; - -- /* The port 5 of the qca8337 have some problem in flood condition. The -- * original legacy driver had some specific buffer and priority settings -- * for the different port suggested by the QCA switch team. Add this -- * missing settings to improve switch stability under load condition. -- * This problem is limited to qca8337 and other qca8k switch are not affected. -+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_MEMBER, -+ BIT(cpu_port)); -+ if (ret) -+ return ret; -+ -+ ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_LEARN); -+ if (ret) -+ return ret; -+ -+ /* For port based vlans to work we need to set the -+ * default egress vid - */ -- if (priv->switch_id == QCA8K_ID_QCA8337) -- qca8k_setup_hol_fixup(priv, i); -+ ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port), -+ QCA8K_EGREES_VLAN_PORT_MASK(port), -+ QCA8K_EGREES_VLAN_PORT(port, QCA8K_PORT_VID_DEF)); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port), -+ QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) | -+ QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF)); -+ if (ret) -+ return ret; - } - -+ /* The port 5 of the qca8337 have some problem in flood condition. The -+ * original legacy driver had some specific buffer and priority settings -+ * for the different port suggested by the QCA switch team. Add this -+ * missing settings to improve switch stability under load condition. -+ * This problem is limited to qca8337 and other qca8k switch are not affected. -+ */ -+ if (priv->switch_id == QCA8K_ID_QCA8337) -+ dsa_switch_for_each_available_port(dp, ds) -+ qca8k_setup_hol_fixup(priv, dp->index); -+ - /* Special GLOBAL_FC_THRESH value are needed for ar8327 switch */ - if (priv->switch_id == QCA8K_ID_QCA8327) { - mask = QCA8K_GLOBAL_FC_GOL_XON_THRES(288) | diff --git a/target/linux/generic/backport-6.1/781-v6.6-01-net-dsa-qca8k-fix-regmap-bulk-read-write-methods-on-.patch b/target/linux/generic/backport-6.1/781-v6.6-01-net-dsa-qca8k-fix-regmap-bulk-read-write-methods-on-.patch deleted file mode 100644 index 632f422d1ff7e8..00000000000000 --- a/target/linux/generic/backport-6.1/781-v6.6-01-net-dsa-qca8k-fix-regmap-bulk-read-write-methods-on-.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 5652d1741574eb89cc02576e50ee3e348bd6dd77 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Wed, 4 Oct 2023 11:19:03 +0200 -Subject: [PATCH 1/2] net: dsa: qca8k: fix regmap bulk read/write methods on - big endian systems -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit c766e077d927 ("net: dsa: qca8k: convert to regmap read/write -API") introduced bulk read/write methods to qca8k's regmap. - -The regmap bulk read/write methods get the register address in a buffer -passed as a void pointer parameter (the same buffer contains also the -read/written values). The register address occupies only as many bytes -as it requires at the beginning of this buffer. For example if the -.reg_bits member in regmap_config is 16 (as is the case for this -driver), the register address occupies only the first 2 bytes in this -buffer, so it can be cast to u16. - -But the original commit implementing these bulk read/write methods cast -the buffer to u32: - u32 reg = *(u32 *)reg_buf & U16_MAX; -taking the first 4 bytes. This works on little endian systems where the -first 2 bytes of the buffer correspond to the low 16-bits, but it -obviously cannot work on big endian systems. - -Fix this by casting the beginning of the buffer to u16 as - u32 reg = *(u16 *)reg_buf; - -Fixes: c766e077d927 ("net: dsa: qca8k: convert to regmap read/write API") -Signed-off-by: Marek Behún -Tested-by: Christian Marangi -Reviewed-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -504,8 +504,8 @@ qca8k_bulk_read(void *ctx, const void *r - void *val_buf, size_t val_len) - { - int i, count = val_len / sizeof(u32), ret; -- u32 reg = *(u32 *)reg_buf & U16_MAX; - struct qca8k_priv *priv = ctx; -+ u32 reg = *(u16 *)reg_buf; - - if (priv->mgmt_master && - !qca8k_read_eth(priv, reg, val_buf, val_len)) -@@ -526,8 +526,8 @@ qca8k_bulk_gather_write(void *ctx, const - const void *val_buf, size_t val_len) - { - int i, count = val_len / sizeof(u32), ret; -- u32 reg = *(u32 *)reg_buf & U16_MAX; - struct qca8k_priv *priv = ctx; -+ u32 reg = *(u16 *)reg_buf; - u32 *val = (u32 *)val_buf; - - if (priv->mgmt_master && diff --git a/target/linux/generic/backport-6.1/790-01-v6.2-net-dsa-mt7530-remove-redundant-assignment.patch b/target/linux/generic/backport-6.1/790-01-v6.2-net-dsa-mt7530-remove-redundant-assignment.patch deleted file mode 100644 index e0319fd355a5d1..00000000000000 --- a/target/linux/generic/backport-6.1/790-01-v6.2-net-dsa-mt7530-remove-redundant-assignment.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 27b692012840f658c84a3102c0aeca2676f03132 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 15 Dec 2022 03:47:59 +0000 -Subject: [PATCH 01/48] net: dsa: mt7530: remove redundant assignment - -Russell King correctly pointed out that the MAC_2500FD capability is -already added for port 5 (if not in RGMII mode) and port 6 (which only -supports SGMII) by mt7531_mac_port_get_caps. Remove the reduntant -setting of this capability flag which was added by a previous commit. - -Fixes: e19de30d2080 ("net: dsa: mt7530: add support for in-band link status") -Reported-by: Russell King (Oracle) -Reviewed-by: Russell King (Oracle) -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/Y5qY7x6la5TxZxzX@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 3 --- - 1 file changed, 3 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3198,9 +3198,6 @@ static void mt753x_phylink_get_caps(stru - config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000FD; - -- if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port)) -- config->mac_capabilities |= MAC_2500FD; -- - /* This driver does not make use of the speed, duplex, pause or the - * advertisement in its mac_config, so it is safe to mark this driver - * as non-legacy. diff --git a/target/linux/generic/backport-6.1/790-02-v6.4-net-dsa-mt7530-use-external-PCS-driver.patch b/target/linux/generic/backport-6.1/790-02-v6.4-net-dsa-mt7530-use-external-PCS-driver.patch deleted file mode 100644 index 2697f2e563244b..00000000000000 --- a/target/linux/generic/backport-6.1/790-02-v6.4-net-dsa-mt7530-use-external-PCS-driver.patch +++ /dev/null @@ -1,477 +0,0 @@ -From 05dc5ea089f947a69a5db092ef4cad6a0f3c96ce Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 19 Mar 2023 12:58:43 +0000 -Subject: [PATCH 02/48] net: dsa: mt7530: use external PCS driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Implement regmap access wrappers, for now only to be used by the -pcs-mtk-lynxi driver. -Make use of this external PCS driver and drop the now reduntant -implementation in mt7530.c. -As a nice side effect the SGMII registers can now also more easily be -inspected for debugging via /sys/kernel/debug/regmap. - -Tested-by: Bjørn Mork -Signed-off-by: Daniel Golle -Tested-by: Frank Wunderlich -Reviewed-by: Russell King (Oracle) -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/Kconfig | 1 + - drivers/net/dsa/mt7530.c | 277 ++++++++++----------------------------- - drivers/net/dsa/mt7530.h | 47 +------ - 3 files changed, 71 insertions(+), 254 deletions(-) - ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -37,6 +37,7 @@ config NET_DSA_MT7530 - tristate "MediaTek MT753x and MT7621 Ethernet switch support" - select NET_DSA_TAG_MTK - select MEDIATEK_GE_PHY -+ select PCS_MTK_LYNXI - help - This enables support for the MediaTek MT7530, MT7531, and MT7621 - Ethernet switch chips. ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2839,128 +2840,11 @@ static int mt7531_rgmii_setup(struct mt7 - return 0; - } - --static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, -- phy_interface_t interface, int speed, int duplex) --{ -- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; -- int port = pcs_to_mt753x_pcs(pcs)->port; -- unsigned int val; -- -- /* For adjusting speed and duplex of SGMII force mode. */ -- if (interface != PHY_INTERFACE_MODE_SGMII || -- phylink_autoneg_inband(mode)) -- return; -- -- /* SGMII force mode setting */ -- val = mt7530_read(priv, MT7531_SGMII_MODE(port)); -- val &= ~MT7531_SGMII_IF_MODE_MASK; -- -- switch (speed) { -- case SPEED_10: -- val |= MT7531_SGMII_FORCE_SPEED_10; -- break; -- case SPEED_100: -- val |= MT7531_SGMII_FORCE_SPEED_100; -- break; -- case SPEED_1000: -- val |= MT7531_SGMII_FORCE_SPEED_1000; -- break; -- } -- -- /* MT7531 SGMII 1G force mode can only work in full duplex mode, -- * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. -- * -- * The speed check is unnecessary as the MAC capabilities apply -- * this restriction. --rmk -- */ -- if ((speed == SPEED_10 || speed == SPEED_100) && -- duplex != DUPLEX_FULL) -- val |= MT7531_SGMII_FORCE_HALF_DUPLEX; -- -- mt7530_write(priv, MT7531_SGMII_MODE(port), val); --} -- - static bool mt753x_is_mac_port(u32 port) - { - return (port == 5 || port == 6); - } - --static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port, -- phy_interface_t interface) --{ -- u32 val; -- -- if (!mt753x_is_mac_port(port)) -- return -EINVAL; -- -- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port), -- MT7531_SGMII_PHYA_PWD); -- -- val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port)); -- val &= ~MT7531_RG_TPHY_SPEED_MASK; -- /* Setup 2.5 times faster clock for 2.5Gbps data speeds with 10B/8B -- * encoding. -- */ -- val |= (interface == PHY_INTERFACE_MODE_2500BASEX) ? -- MT7531_RG_TPHY_SPEED_3_125G : MT7531_RG_TPHY_SPEED_1_25G; -- mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val); -- -- mt7530_clear(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE); -- -- /* MT7531 SGMII 1G and 2.5G force mode can only work in full duplex -- * mode, no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not. -- */ -- mt7530_rmw(priv, MT7531_SGMII_MODE(port), -- MT7531_SGMII_IF_MODE_MASK | MT7531_SGMII_REMOTE_FAULT_DIS, -- MT7531_SGMII_FORCE_SPEED_1000); -- -- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0); -- -- return 0; --} -- --static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port, -- phy_interface_t interface) --{ -- if (!mt753x_is_mac_port(port)) -- return -EINVAL; -- -- mt7530_set(priv, MT7531_QPHY_PWR_STATE_CTRL(port), -- MT7531_SGMII_PHYA_PWD); -- -- mt7530_rmw(priv, MT7531_PHYA_CTRL_SIGNAL3(port), -- MT7531_RG_TPHY_SPEED_MASK, MT7531_RG_TPHY_SPEED_1_25G); -- -- mt7530_set(priv, MT7531_SGMII_MODE(port), -- MT7531_SGMII_REMOTE_FAULT_DIS | -- MT7531_SGMII_SPEED_DUPLEX_AN); -- -- mt7530_rmw(priv, MT7531_PCS_SPEED_ABILITY(port), -- MT7531_SGMII_TX_CONFIG_MASK, 1); -- -- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_ENABLE); -- -- mt7530_set(priv, MT7531_PCS_CONTROL_1(port), MT7531_SGMII_AN_RESTART); -- -- mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), 0); -- -- return 0; --} -- --static void mt7531_pcs_an_restart(struct phylink_pcs *pcs) --{ -- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; -- int port = pcs_to_mt753x_pcs(pcs)->port; -- u32 val; -- -- /* Only restart AN when AN is enabled */ -- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); -- if (val & MT7531_SGMII_AN_ENABLE) { -- val |= MT7531_SGMII_AN_RESTART; -- mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val); -- } --} -- - static int - mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - phy_interface_t interface) -@@ -2983,11 +2867,11 @@ mt7531_mac_config(struct dsa_switch *ds, - phydev = dp->slave->phydev; - return mt7531_rgmii_setup(priv, port, interface, phydev); - case PHY_INTERFACE_MODE_SGMII: -- return mt7531_sgmii_setup_mode_an(priv, port, interface); - case PHY_INTERFACE_MODE_NA: - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_2500BASEX: -- return mt7531_sgmii_setup_mode_force(priv, port, interface); -+ /* handled in SGMII PCS driver */ -+ return 0; - default: - return -EINVAL; - } -@@ -3012,11 +2896,11 @@ mt753x_phylink_mac_select_pcs(struct dsa - - switch (interface) { - case PHY_INTERFACE_MODE_TRGMII: -+ return &priv->pcs[port].pcs; - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_2500BASEX: -- return &priv->pcs[port].pcs; -- -+ return priv->ports[port].sgmii_pcs; - default: - return NULL; - } -@@ -3254,86 +3138,6 @@ static void mt7530_pcs_get_state(struct - state->pause |= MLO_PAUSE_TX; - } - --static int --mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port, -- struct phylink_link_state *state) --{ -- u32 status, val; -- u16 config_reg; -- -- status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); -- state->link = !!(status & MT7531_SGMII_LINK_STATUS); -- state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE); -- if (state->interface == PHY_INTERFACE_MODE_SGMII && -- (status & MT7531_SGMII_AN_ENABLE)) { -- val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port)); -- config_reg = val >> 16; -- -- switch (config_reg & LPA_SGMII_SPD_MASK) { -- case LPA_SGMII_1000: -- state->speed = SPEED_1000; -- break; -- case LPA_SGMII_100: -- state->speed = SPEED_100; -- break; -- case LPA_SGMII_10: -- state->speed = SPEED_10; -- break; -- default: -- dev_err(priv->dev, "invalid sgmii PHY speed\n"); -- state->link = false; -- return -EINVAL; -- } -- -- if (config_reg & LPA_SGMII_FULL_DUPLEX) -- state->duplex = DUPLEX_FULL; -- else -- state->duplex = DUPLEX_HALF; -- } -- -- return 0; --} -- --static void --mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port, -- struct phylink_link_state *state) --{ -- unsigned int val; -- -- val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port)); -- state->link = !!(val & MT7531_SGMII_LINK_STATUS); -- if (!state->link) -- return; -- -- state->an_complete = state->link; -- -- if (state->interface == PHY_INTERFACE_MODE_2500BASEX) -- state->speed = SPEED_2500; -- else -- state->speed = SPEED_1000; -- -- state->duplex = DUPLEX_FULL; -- state->pause = MLO_PAUSE_NONE; --} -- --static void mt7531_pcs_get_state(struct phylink_pcs *pcs, -- struct phylink_link_state *state) --{ -- struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv; -- int port = pcs_to_mt753x_pcs(pcs)->port; -- -- if (state->interface == PHY_INTERFACE_MODE_SGMII) { -- mt7531_sgmii_pcs_get_state_an(priv, port, state); -- return; -- } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) || -- (state->interface == PHY_INTERFACE_MODE_2500BASEX)) { -- mt7531_sgmii_pcs_get_state_inband(priv, port, state); -- return; -- } -- -- state->link = false; --} -- - static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, - phy_interface_t interface, - const unsigned long *advertising, -@@ -3353,18 +3157,57 @@ static const struct phylink_pcs_ops mt75 - .pcs_an_restart = mt7530_pcs_an_restart, - }; - --static const struct phylink_pcs_ops mt7531_pcs_ops = { -- .pcs_validate = mt753x_pcs_validate, -- .pcs_get_state = mt7531_pcs_get_state, -- .pcs_config = mt753x_pcs_config, -- .pcs_an_restart = mt7531_pcs_an_restart, -- .pcs_link_up = mt7531_pcs_link_up, -+static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) -+{ -+ struct mt7530_priv *priv = context; -+ -+ *val = mt7530_read(priv, reg); -+ return 0; -+}; -+ -+static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) -+{ -+ struct mt7530_priv *priv = context; -+ -+ mt7530_write(priv, reg, val); -+ return 0; -+}; -+ -+static int mt7530_regmap_update_bits(void *context, unsigned int reg, -+ unsigned int mask, unsigned int val) -+{ -+ struct mt7530_priv *priv = context; -+ -+ mt7530_rmw(priv, reg, mask, val); -+ return 0; -+}; -+ -+static const struct regmap_bus mt7531_regmap_bus = { -+ .reg_write = mt7530_regmap_write, -+ .reg_read = mt7530_regmap_read, -+ .reg_update_bits = mt7530_regmap_update_bits, -+}; -+ -+#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \ -+ { \ -+ .name = _name, \ -+ .reg_bits = 16, \ -+ .val_bits = 32, \ -+ .reg_stride = 4, \ -+ .reg_base = _reg_base, \ -+ .max_register = 0x17c, \ -+ } -+ -+static const struct regmap_config mt7531_pcs_config[] = { -+ MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)), -+ MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)), - }; - - static int - mt753x_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; -+ struct regmap *regmap; - int i, ret; - - /* Initialise the PCS devices */ -@@ -3372,8 +3215,6 @@ mt753x_setup(struct dsa_switch *ds) - priv->pcs[i].pcs.ops = priv->info->pcs_ops; - priv->pcs[i].priv = priv; - priv->pcs[i].port = i; -- if (mt753x_is_mac_port(i)) -- priv->pcs[i].pcs.poll = 1; - } - - ret = priv->info->sw_setup(ds); -@@ -3388,6 +3229,16 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -+ if (priv->id == ID_MT7531) -+ for (i = 0; i < 2; i++) { -+ regmap = devm_regmap_init(ds->dev, -+ &mt7531_regmap_bus, priv, -+ &mt7531_pcs_config[i]); -+ priv->ports[5 + i].sgmii_pcs = -+ mtk_pcs_lynxi_create(ds->dev, regmap, -+ MT7531_PHYA_CTRL_SIGNAL3, 0); -+ } -+ - return ret; - } - -@@ -3480,7 +3331,7 @@ static const struct mt753x_info mt753x_t - }, - [ID_MT7531] = { - .id = ID_MT7531, -- .pcs_ops = &mt7531_pcs_ops, -+ .pcs_ops = &mt7530_pcs_ops, - .sw_setup = mt7531_setup, - .phy_read = mt7531_ind_phy_read, - .phy_write = mt7531_ind_phy_write, -@@ -3588,7 +3439,7 @@ static void - mt7530_remove(struct mdio_device *mdiodev) - { - struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -- int ret = 0; -+ int ret = 0, i; - - if (!priv) - return; -@@ -3607,6 +3458,10 @@ mt7530_remove(struct mdio_device *mdiode - mt7530_free_irq(priv); - - dsa_unregister_switch(priv->ds); -+ -+ for (i = 0; i < 2; ++i) -+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs); -+ - mutex_destroy(&priv->reg_mutex); - } - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -401,47 +401,8 @@ enum mt7530_vlan_port_acc_frm { - CCR_TX_OCT_CNT_BAD) - - /* MT7531 SGMII register group */ --#define MT7531_SGMII_REG_BASE 0x5000 --#define MT7531_SGMII_REG(p, r) (MT7531_SGMII_REG_BASE + \ -- ((p) - 5) * 0x1000 + (r)) -- --/* Register forSGMII PCS_CONTROL_1 */ --#define MT7531_PCS_CONTROL_1(p) MT7531_SGMII_REG(p, 0x00) --#define MT7531_SGMII_LINK_STATUS BIT(18) --#define MT7531_SGMII_AN_ENABLE BIT(12) --#define MT7531_SGMII_AN_RESTART BIT(9) --#define MT7531_SGMII_AN_COMPLETE BIT(21) -- --/* Register for SGMII PCS_SPPED_ABILITY */ --#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08) --#define MT7531_SGMII_TX_CONFIG_MASK GENMASK(15, 0) --#define MT7531_SGMII_TX_CONFIG BIT(0) -- --/* Register for SGMII_MODE */ --#define MT7531_SGMII_MODE(p) MT7531_SGMII_REG(p, 0x20) --#define MT7531_SGMII_REMOTE_FAULT_DIS BIT(8) --#define MT7531_SGMII_IF_MODE_MASK GENMASK(5, 1) --#define MT7531_SGMII_FORCE_DUPLEX BIT(4) --#define MT7531_SGMII_FORCE_SPEED_MASK GENMASK(3, 2) --#define MT7531_SGMII_FORCE_SPEED_1000 BIT(3) --#define MT7531_SGMII_FORCE_SPEED_100 BIT(2) --#define MT7531_SGMII_FORCE_SPEED_10 0 --#define MT7531_SGMII_SPEED_DUPLEX_AN BIT(1) -- --enum mt7531_sgmii_force_duplex { -- MT7531_SGMII_FORCE_FULL_DUPLEX = 0, -- MT7531_SGMII_FORCE_HALF_DUPLEX = 0x10, --}; -- --/* Fields of QPHY_PWR_STATE_CTRL */ --#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8) --#define MT7531_SGMII_PHYA_PWD BIT(4) -- --/* Values of SGMII SPEED */ --#define MT7531_PHYA_CTRL_SIGNAL3(p) MT7531_SGMII_REG(p, 0x128) --#define MT7531_RG_TPHY_SPEED_MASK (BIT(2) | BIT(3)) --#define MT7531_RG_TPHY_SPEED_1_25G 0x0 --#define MT7531_RG_TPHY_SPEED_3_125G BIT(2) -+#define MT7531_SGMII_REG_BASE(p) (0x5000 + ((p) - 5) * 0x1000) -+#define MT7531_PHYA_CTRL_SIGNAL3 0x128 - - /* Register for system reset */ - #define MT7530_SYS_CTRL 0x7000 -@@ -741,13 +702,13 @@ struct mt7530_fdb { - * @pm: The matrix used to show all connections with the port. - * @pvid: The VLAN specified is to be considered a PVID at ingress. Any - * untagged frames will be assigned to the related VLAN. -- * @vlan_filtering: The flags indicating whether the port that can recognize -- * VLAN-tagged frames. -+ * @sgmii_pcs: Pointer to PCS instance for SerDes ports - */ - struct mt7530_port { - bool enable; - u32 pm; - u16 pvid; -+ struct phylink_pcs *sgmii_pcs; - }; - - /* Port 5 interface select definitions */ diff --git a/target/linux/generic/backport-6.1/790-03-v6.4-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch b/target/linux/generic/backport-6.1/790-03-v6.4-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch deleted file mode 100644 index d8f559b4162691..00000000000000 --- a/target/linux/generic/backport-6.1/790-03-v6.4-net-dsa-mt7530-make-some-noise-if-register-read-fail.patch +++ /dev/null @@ -1,32 +0,0 @@ -From cafbb70e148e7a4e318dcc1e36a96643815b6245 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:17:19 +0100 -Subject: [PATCH 03/48] net: dsa: mt7530: make some noise if register read - fails - -Simply returning the negative error value instead of the read value -doesn't seem like a good idea. Return 0 instead and add WARN_ON_ONCE(1) -so this kind of error will not go unnoticed. - -Suggested-by: Andrew Lunn -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -224,9 +224,10 @@ mt7530_mii_read(struct mt7530_priv *priv - /* MT7530 uses 31 as the pseudo port */ - ret = bus->write(bus, 0x1f, 0x1f, page); - if (ret < 0) { -+ WARN_ON_ONCE(1); - dev_err(&bus->dev, - "failed to read mt7530 register\n"); -- return ret; -+ return 0; - } - - lo = bus->read(bus, 0x1f, r); diff --git a/target/linux/generic/backport-6.1/790-04-v6.4-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch b/target/linux/generic/backport-6.1/790-04-v6.4-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch deleted file mode 100644 index 1bf19a813e6e33..00000000000000 --- a/target/linux/generic/backport-6.1/790-04-v6.4-net-dsa-mt7530-refactor-SGMII-PCS-creation.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 8f83ad87e2df26ddf9b8afd4d2873644a872d929 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:17:30 +0100 -Subject: [PATCH 04/48] net: dsa: mt7530: refactor SGMII PCS creation - -Instead of macro templates use a dedidated function and allocated -regmap_config when creating the regmaps for the pcs-mtk-lynxi -instances. -This is in preparation to switching to use unlocked regmap accessors -and have regmap's locking API handle locking for us. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 74 +++++++++++++++++++++++++++------------- - 1 file changed, 50 insertions(+), 24 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3189,26 +3189,56 @@ static const struct regmap_bus mt7531_re - .reg_update_bits = mt7530_regmap_update_bits, - }; - --#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \ -- { \ -- .name = _name, \ -- .reg_bits = 16, \ -- .val_bits = 32, \ -- .reg_stride = 4, \ -- .reg_base = _reg_base, \ -- .max_register = 0x17c, \ -+static int -+mt7531_create_sgmii(struct mt7530_priv *priv) -+{ -+ struct regmap_config *mt7531_pcs_config[2]; -+ struct phylink_pcs *pcs; -+ struct regmap *regmap; -+ int i, ret = 0; -+ -+ for (i = 0; i < 2; i++) { -+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev, -+ sizeof(struct regmap_config), -+ GFP_KERNEL); -+ if (!mt7531_pcs_config[i]) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ mt7531_pcs_config[i]->name = i ? "port6" : "port5"; -+ mt7531_pcs_config[i]->reg_bits = 16; -+ mt7531_pcs_config[i]->val_bits = 32; -+ mt7531_pcs_config[i]->reg_stride = 4; -+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); -+ mt7531_pcs_config[i]->max_register = 0x17c; -+ -+ regmap = devm_regmap_init(priv->dev, -+ &mt7531_regmap_bus, priv, -+ mt7531_pcs_config[i]); -+ if (IS_ERR(regmap)) { -+ ret = PTR_ERR(regmap); -+ break; -+ } -+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap, -+ MT7531_PHYA_CTRL_SIGNAL3, 0); -+ if (!pcs) { -+ ret = -ENXIO; -+ break; -+ } -+ priv->ports[5 + i].sgmii_pcs = pcs; - } - --static const struct regmap_config mt7531_pcs_config[] = { -- MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)), -- MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)), --}; -+ if (ret && i) -+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs); -+ -+ return ret; -+} - - static int - mt753x_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; -- struct regmap *regmap; - int i, ret; - - /* Initialise the PCS devices */ -@@ -3230,15 +3260,11 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -- if (priv->id == ID_MT7531) -- for (i = 0; i < 2; i++) { -- regmap = devm_regmap_init(ds->dev, -- &mt7531_regmap_bus, priv, -- &mt7531_pcs_config[i]); -- priv->ports[5 + i].sgmii_pcs = -- mtk_pcs_lynxi_create(ds->dev, regmap, -- MT7531_PHYA_CTRL_SIGNAL3, 0); -- } -+ if (priv->id == ID_MT7531) { -+ ret = mt7531_create_sgmii(priv); -+ if (ret && priv->irq) -+ mt7530_free_irq_common(priv); -+ } - - return ret; - } diff --git a/target/linux/generic/backport-6.1/790-05-v6.4-net-dsa-mt7530-use-unlocked-regmap-accessors.patch b/target/linux/generic/backport-6.1/790-05-v6.4-net-dsa-mt7530-use-unlocked-regmap-accessors.patch deleted file mode 100644 index bd28b4be76ab73..00000000000000 --- a/target/linux/generic/backport-6.1/790-05-v6.4-net-dsa-mt7530-use-unlocked-regmap-accessors.patch +++ /dev/null @@ -1,74 +0,0 @@ -From efb41b8e9b7bbb08ace1930373bff63d4f5cc6e2 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:17:40 +0100 -Subject: [PATCH 05/48] net: dsa: mt7530: use unlocked regmap accessors - -Instead of wrapping the locked register accessor functions, use the -unlocked variants and add locking wrapper functions to let regmap -handle the locking. - -This is a preparation towards being able to always use regmap to -access switch registers instead of open-coded accessor functions. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 23 ++++++++++++++--------- - 1 file changed, 14 insertions(+), 9 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3162,7 +3162,7 @@ static int mt7530_regmap_read(void *cont - { - struct mt7530_priv *priv = context; - -- *val = mt7530_read(priv, reg); -+ *val = mt7530_mii_read(priv, reg); - return 0; - }; - -@@ -3170,23 +3170,25 @@ static int mt7530_regmap_write(void *con - { - struct mt7530_priv *priv = context; - -- mt7530_write(priv, reg, val); -+ mt7530_mii_write(priv, reg, val); - return 0; - }; - --static int mt7530_regmap_update_bits(void *context, unsigned int reg, -- unsigned int mask, unsigned int val) -+static void -+mt7530_mdio_regmap_lock(void *mdio_lock) - { -- struct mt7530_priv *priv = context; -+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED); -+} - -- mt7530_rmw(priv, reg, mask, val); -- return 0; --}; -+static void -+mt7530_mdio_regmap_unlock(void *mdio_lock) -+{ -+ mutex_unlock(mdio_lock); -+} - - static const struct regmap_bus mt7531_regmap_bus = { - .reg_write = mt7530_regmap_write, - .reg_read = mt7530_regmap_read, -- .reg_update_bits = mt7530_regmap_update_bits, - }; - - static int -@@ -3212,6 +3214,9 @@ mt7531_create_sgmii(struct mt7530_priv * - mt7531_pcs_config[i]->reg_stride = 4; - mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); - mt7531_pcs_config[i]->max_register = 0x17c; -+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock; -+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock; -+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; - - regmap = devm_regmap_init(priv->dev, - &mt7531_regmap_bus, priv, diff --git a/target/linux/generic/backport-6.1/790-06-v6.4-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch b/target/linux/generic/backport-6.1/790-06-v6.4-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch deleted file mode 100644 index 42c225d91cb1ec..00000000000000 --- a/target/linux/generic/backport-6.1/790-06-v6.4-net-dsa-mt7530-use-regmap-to-access-switch-register-.patch +++ /dev/null @@ -1,224 +0,0 @@ -From c7945d11a060797c31b3f47d9c9e515b0bf2082f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:17:52 +0100 -Subject: [PATCH 06/48] net: dsa: mt7530: use regmap to access switch register - space - -Use regmap API to access the switch register space. - -Signed-off-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++++---------------- - drivers/net/dsa/mt7530.h | 2 + - 2 files changed, 62 insertions(+), 39 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -183,9 +183,9 @@ core_clear(struct mt7530_priv *priv, u32 - } - - static int --mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val) -+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) - { -- struct mii_bus *bus = priv->bus; -+ struct mii_bus *bus = context; - u16 page, r, lo, hi; - int ret; - -@@ -197,24 +197,34 @@ mt7530_mii_write(struct mt7530_priv *pri - /* MT7530 uses 31 as the pseudo port */ - ret = bus->write(bus, 0x1f, 0x1f, page); - if (ret < 0) -- goto err; -+ return ret; - - ret = bus->write(bus, 0x1f, r, lo); - if (ret < 0) -- goto err; -+ return ret; - - ret = bus->write(bus, 0x1f, 0x10, hi); --err: -+ return ret; -+} -+ -+static int -+mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val) -+{ -+ int ret; -+ -+ ret = regmap_write(priv->regmap, reg, val); -+ - if (ret < 0) -- dev_err(&bus->dev, -+ dev_err(priv->dev, - "failed to write mt7530 register\n"); -+ - return ret; - } - --static u32 --mt7530_mii_read(struct mt7530_priv *priv, u32 reg) -+static int -+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) - { -- struct mii_bus *bus = priv->bus; -+ struct mii_bus *bus = context; - u16 page, r, lo, hi; - int ret; - -@@ -223,17 +233,32 @@ mt7530_mii_read(struct mt7530_priv *priv - - /* MT7530 uses 31 as the pseudo port */ - ret = bus->write(bus, 0x1f, 0x1f, page); -- if (ret < 0) { -+ if (ret < 0) -+ return ret; -+ -+ lo = bus->read(bus, 0x1f, r); -+ hi = bus->read(bus, 0x1f, 0x10); -+ -+ *val = (hi << 16) | (lo & 0xffff); -+ -+ return 0; -+} -+ -+static u32 -+mt7530_mii_read(struct mt7530_priv *priv, u32 reg) -+{ -+ int ret; -+ u32 val; -+ -+ ret = regmap_read(priv->regmap, reg, &val); -+ if (ret) { - WARN_ON_ONCE(1); -- dev_err(&bus->dev, -+ dev_err(priv->dev, - "failed to read mt7530 register\n"); - return 0; - } - -- lo = bus->read(bus, 0x1f, r); -- hi = bus->read(bus, 0x1f, 0x10); -- -- return (hi << 16) | (lo & 0xffff); -+ return val; - } - - static void -@@ -283,14 +308,10 @@ mt7530_rmw(struct mt7530_priv *priv, u32 - u32 mask, u32 set) - { - struct mii_bus *bus = priv->bus; -- u32 val; - - mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); - -- val = mt7530_mii_read(priv, reg); -- val &= ~mask; -- val |= set; -- mt7530_mii_write(priv, reg, val); -+ regmap_update_bits(priv->regmap, reg, mask, set); - - mutex_unlock(&bus->mdio_lock); - } -@@ -298,7 +319,7 @@ mt7530_rmw(struct mt7530_priv *priv, u32 - static void - mt7530_set(struct mt7530_priv *priv, u32 reg, u32 val) - { -- mt7530_rmw(priv, reg, 0, val); -+ mt7530_rmw(priv, reg, val, val); - } - - static void -@@ -3158,22 +3179,6 @@ static const struct phylink_pcs_ops mt75 - .pcs_an_restart = mt7530_pcs_an_restart, - }; - --static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) --{ -- struct mt7530_priv *priv = context; -- -- *val = mt7530_mii_read(priv, reg); -- return 0; --}; -- --static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) --{ -- struct mt7530_priv *priv = context; -- -- mt7530_mii_write(priv, reg, val); -- return 0; --}; -- - static void - mt7530_mdio_regmap_lock(void *mdio_lock) - { -@@ -3186,7 +3191,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc - mutex_unlock(mdio_lock); - } - --static const struct regmap_bus mt7531_regmap_bus = { -+static const struct regmap_bus mt7530_regmap_bus = { - .reg_write = mt7530_regmap_write, - .reg_read = mt7530_regmap_read, - }; -@@ -3219,7 +3224,7 @@ mt7531_create_sgmii(struct mt7530_priv * - mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; - - regmap = devm_regmap_init(priv->dev, -- &mt7531_regmap_bus, priv, -+ &mt7530_regmap_bus, priv->bus, - mt7531_pcs_config[i]); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); -@@ -3385,6 +3390,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match) - static int - mt7530_probe(struct mdio_device *mdiodev) - { -+ static struct regmap_config *regmap_config; - struct mt7530_priv *priv; - struct device_node *dn; - -@@ -3464,6 +3470,21 @@ mt7530_probe(struct mdio_device *mdiodev - mutex_init(&priv->reg_mutex); - dev_set_drvdata(&mdiodev->dev, priv); - -+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config), -+ GFP_KERNEL); -+ if (!regmap_config) -+ return -ENOMEM; -+ -+ regmap_config->reg_bits = 16; -+ regmap_config->val_bits = 32; -+ regmap_config->reg_stride = 4; -+ regmap_config->max_register = MT7530_CREV; -+ regmap_config->disable_locking = true; -+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, -+ priv->bus, regmap_config); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); -+ - return dsa_register_switch(priv->ds); - } - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -785,6 +785,7 @@ struct mt753x_info { - * @dev: The device pointer - * @ds: The pointer to the dsa core structure - * @bus: The bus used for the device and built-in PHY -+ * @regmap: The regmap instance representing all switch registers - * @rstc: The pointer to reset control used by MCM - * @core_pwr: The power supplied into the core - * @io_pwr: The power supplied into the I/O -@@ -805,6 +806,7 @@ struct mt7530_priv { - struct device *dev; - struct dsa_switch *ds; - struct mii_bus *bus; -+ struct regmap *regmap; - struct reset_control *rstc; - struct regulator *core_pwr; - struct regulator *io_pwr; diff --git a/target/linux/generic/backport-6.1/790-07-v6.4-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch b/target/linux/generic/backport-6.1/790-07-v6.4-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch deleted file mode 100644 index 9cd817c05680be..00000000000000 --- a/target/linux/generic/backport-6.1/790-07-v6.4-net-dsa-mt7530-move-SGMII-PCS-creation-to-mt7530_pro.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 6b64b5bc3045a7e1ee5278df4f4ff315cd43d88a Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:18:04 +0100 -Subject: [PATCH 07/48] net: dsa: mt7530: move SGMII PCS creation to - mt7530_probe function - -Move creating the SGMII PCS from mt753x_setup() to the more appropriate -mt7530_probe() function. -This is done also in preparation of moving all functions related to -MDIO-connected MT753x switches to a separate module. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3270,12 +3270,6 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -- if (priv->id == ID_MT7531) { -- ret = mt7531_create_sgmii(priv); -- if (ret && priv->irq) -- mt7530_free_irq_common(priv); -- } -- - return ret; - } - -@@ -3393,6 +3387,7 @@ mt7530_probe(struct mdio_device *mdiodev - static struct regmap_config *regmap_config; - struct mt7530_priv *priv; - struct device_node *dn; -+ int ret; - - dn = mdiodev->dev.of_node; - -@@ -3485,6 +3480,12 @@ mt7530_probe(struct mdio_device *mdiodev - if (IS_ERR(priv->regmap)) - return PTR_ERR(priv->regmap); - -+ if (priv->id == ID_MT7531) { -+ ret = mt7531_create_sgmii(priv); -+ if (ret) -+ return ret; -+ } -+ - return dsa_register_switch(priv->ds); - } - diff --git a/target/linux/generic/backport-6.1/790-08-v6.4-net-dsa-mt7530-introduce-mutex-helpers.patch b/target/linux/generic/backport-6.1/790-08-v6.4-net-dsa-mt7530-introduce-mutex-helpers.patch deleted file mode 100644 index 4f77078eef9673..00000000000000 --- a/target/linux/generic/backport-6.1/790-08-v6.4-net-dsa-mt7530-introduce-mutex-helpers.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 504d39cbda402df3e6fd123d040520393b6a6297 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:18:16 +0100 -Subject: [PATCH 08/48] net: dsa: mt7530: introduce mutex helpers - -As the MDIO bus lock only needs to be involved if actually operating -on an MDIO-connected switch we will need to skip locking for built-in -switches which are accessed via MMIO. -Create helper functions which simplify that upcoming change. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 73 ++++++++++++++++++++-------------------- - 1 file changed, 36 insertions(+), 37 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -143,31 +143,40 @@ err: - } - - static void --core_write(struct mt7530_priv *priv, u32 reg, u32 val) -+mt7530_mutex_lock(struct mt7530_priv *priv) - { -- struct mii_bus *bus = priv->bus; -+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); -+} - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+static void -+mt7530_mutex_unlock(struct mt7530_priv *priv) -+{ -+ mutex_unlock(&priv->bus->mdio_lock); -+} -+ -+static void -+core_write(struct mt7530_priv *priv, u32 reg, u32 val) -+{ -+ mt7530_mutex_lock(priv); - - core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - } - - static void - core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set) - { -- struct mii_bus *bus = priv->bus; - u32 val; - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2); - val &= ~mask; - val |= set; - core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - } - - static void -@@ -264,13 +273,11 @@ mt7530_mii_read(struct mt7530_priv *priv - static void - mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val) - { -- struct mii_bus *bus = priv->bus; -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - mt7530_mii_write(priv, reg, val); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - } - - static u32 -@@ -282,14 +289,13 @@ _mt7530_unlocked_read(struct mt7530_dumm - static u32 - _mt7530_read(struct mt7530_dummy_poll *p) - { -- struct mii_bus *bus = p->priv->bus; - u32 val; - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(p->priv); - - val = mt7530_mii_read(p->priv, p->reg); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(p->priv); - - return val; - } -@@ -307,13 +313,11 @@ static void - mt7530_rmw(struct mt7530_priv *priv, u32 reg, - u32 mask, u32 set) - { -- struct mii_bus *bus = priv->bus; -- -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - regmap_update_bits(priv->regmap, reg, mask, set); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - } - - static void -@@ -659,14 +663,13 @@ static int - mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad, - int regnum) - { -- struct mii_bus *bus = priv->bus; - struct mt7530_dummy_poll p; - u32 reg, val; - int ret; - - INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, - !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -699,7 +702,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr - - ret = val & MT7531_MDIO_RW_DATA_MASK; - out: -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - return ret; - } -@@ -708,14 +711,13 @@ static int - mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad, - int regnum, u32 data) - { -- struct mii_bus *bus = priv->bus; - struct mt7530_dummy_poll p; - u32 val, reg; - int ret; - - INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, - !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -747,7 +749,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p - } - - out: -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - return ret; - } -@@ -755,14 +757,13 @@ out: - static int - mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum) - { -- struct mii_bus *bus = priv->bus; - struct mt7530_dummy_poll p; - int ret; - u32 val; - - INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val, - !(val & MT7531_PHY_ACS_ST), 20, 100000); -@@ -785,7 +786,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr - - ret = val & MT7531_MDIO_RW_DATA_MASK; - out: -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - return ret; - } -@@ -794,14 +795,13 @@ static int - mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum, - u16 data) - { -- struct mii_bus *bus = priv->bus; - struct mt7530_dummy_poll p; - int ret; - u32 reg; - - INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC); - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg, - !(reg & MT7531_PHY_ACS_ST), 20, 100000); -@@ -823,7 +823,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p - } - - out: -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - return ret; - } -@@ -1343,7 +1343,6 @@ static int - mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu) - { - struct mt7530_priv *priv = ds->priv; -- struct mii_bus *bus = priv->bus; - int length; - u32 val; - -@@ -1354,7 +1353,7 @@ mt7530_port_change_mtu(struct dsa_switch - if (!dsa_is_cpu_port(ds, port)) - return 0; - -- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - - val = mt7530_mii_read(priv, MT7530_GMACCR); - val &= ~MAX_RX_PKT_LEN_MASK; -@@ -1375,7 +1374,7 @@ mt7530_port_change_mtu(struct dsa_switch - - mt7530_mii_write(priv, MT7530_GMACCR, val); - -- mutex_unlock(&bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - return 0; - } -@@ -2176,10 +2175,10 @@ mt7530_irq_thread_fn(int irq, void *dev_ - u32 val; - int p; - -- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - val = mt7530_mii_read(priv, MT7530_SYS_INT_STS); - mt7530_mii_write(priv, MT7530_SYS_INT_STS, val); -- mutex_unlock(&priv->bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - - for (p = 0; p < MT7530_NUM_PHYS; p++) { - if (BIT(p) & val) { -@@ -2215,7 +2214,7 @@ mt7530_irq_bus_lock(struct irq_data *d) - { - struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); - -- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); -+ mt7530_mutex_lock(priv); - } - - static void -@@ -2224,7 +2223,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da - struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); - - mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable); -- mutex_unlock(&priv->bus->mdio_lock); -+ mt7530_mutex_unlock(priv); - } - - static struct irq_chip mt7530_irq_chip = { diff --git a/target/linux/generic/backport-6.1/790-09-v6.4-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch b/target/linux/generic/backport-6.1/790-09-v6.4-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch deleted file mode 100644 index 9cb0b2dd61e16c..00000000000000 --- a/target/linux/generic/backport-6.1/790-09-v6.4-net-dsa-mt7530-move-p5_intf_modes-function-to-mt7530.patch +++ /dev/null @@ -1,75 +0,0 @@ -From dbef24b66807eef7498740fa8b8441bee64a96c4 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:18:28 +0100 -Subject: [PATCH 09/48] net: dsa: mt7530: move p5_intf_modes() function to - mt7530.c - -In preparation of splitting mt7530.c into a driver for MDIO-connected -as well as MDIO-accessed built-in switches on one hand and MMIO-accessed -built-in switches move the p5_inft_modes() function from mt7530.h to -mt7530.c. The function is only needed there and will trigger a compiler -warning about a defined but unused function otherwise when including -mt7530.h in the to-be-introduced bus-specific drivers. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 18 ++++++++++++++++++ - drivers/net/dsa/mt7530.h | 18 ------------------ - 2 files changed, 18 insertions(+), 18 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -964,6 +964,24 @@ mt7530_set_ageing_time(struct dsa_switch - return 0; - } - -+static const char *p5_intf_modes(unsigned int p5_interface) -+{ -+ switch (p5_interface) { -+ case P5_DISABLED: -+ return "DISABLED"; -+ case P5_INTF_SEL_PHY_P0: -+ return "PHY P0"; -+ case P5_INTF_SEL_PHY_P4: -+ return "PHY P4"; -+ case P5_INTF_SEL_GMAC5: -+ return "GMAC5"; -+ case P5_INTF_SEL_GMAC5_SGMII: -+ return "GMAC5_SGMII"; -+ default: -+ return "unknown"; -+ } -+} -+ - static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface) - { - struct mt7530_priv *priv = ds->priv; ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -720,24 +720,6 @@ enum p5_interface_select { - P5_INTF_SEL_GMAC5_SGMII, - }; - --static const char *p5_intf_modes(unsigned int p5_interface) --{ -- switch (p5_interface) { -- case P5_DISABLED: -- return "DISABLED"; -- case P5_INTF_SEL_PHY_P0: -- return "PHY P0"; -- case P5_INTF_SEL_PHY_P4: -- return "PHY P4"; -- case P5_INTF_SEL_GMAC5: -- return "GMAC5"; -- case P5_INTF_SEL_GMAC5_SGMII: -- return "GMAC5_SGMII"; -- default: -- return "unknown"; -- } --} -- - struct mt7530_priv; - - struct mt753x_pcs { diff --git a/target/linux/generic/backport-6.1/790-10-v6.4-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch b/target/linux/generic/backport-6.1/790-10-v6.4-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch deleted file mode 100644 index a6af6828264e30..00000000000000 --- a/target/linux/generic/backport-6.1/790-10-v6.4-net-dsa-mt7530-introduce-mt7530_probe_common-helper-.patch +++ /dev/null @@ -1,155 +0,0 @@ -From a0c6527a38d518ff175c1b6ce248e9b06cc98d3b Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:18:39 +0100 -Subject: [PATCH 10/48] net: dsa: mt7530: introduce mt7530_probe_common helper - function - -Move commonly used parts from mt7530_probe into new mt7530_probe_common -helper function which will be used by both, mt7530_probe and the -to-be-introduced mt7988_probe. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 98 ++++++++++++++++++++++------------------ - 1 file changed, 54 insertions(+), 44 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3399,44 +3399,21 @@ static const struct of_device_id mt7530_ - MODULE_DEVICE_TABLE(of, mt7530_of_match); - - static int --mt7530_probe(struct mdio_device *mdiodev) -+mt7530_probe_common(struct mt7530_priv *priv) - { -- static struct regmap_config *regmap_config; -- struct mt7530_priv *priv; -- struct device_node *dn; -- int ret; -+ struct device *dev = priv->dev; - -- dn = mdiodev->dev.of_node; -- -- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- -- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL); -+ priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL); - if (!priv->ds) - return -ENOMEM; - -- priv->ds->dev = &mdiodev->dev; -+ priv->ds->dev = dev; - priv->ds->num_ports = MT7530_NUM_PORTS; - -- /* Use medatek,mcm property to distinguish hardware type that would -- * casues a little bit differences on power-on sequence. -- */ -- priv->mcm = of_property_read_bool(dn, "mediatek,mcm"); -- if (priv->mcm) { -- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n"); -- -- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm"); -- if (IS_ERR(priv->rstc)) { -- dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -- return PTR_ERR(priv->rstc); -- } -- } -- - /* Get the hardware identifier from the devicetree node. - * We will need it for some of the clock and regulator setup. - */ -- priv->info = of_device_get_match_data(&mdiodev->dev); -+ priv->info = of_device_get_match_data(dev); - if (!priv->info) - return -EINVAL; - -@@ -3450,23 +3427,53 @@ mt7530_probe(struct mdio_device *mdiodev - return -EINVAL; - - priv->id = priv->info->id; -+ priv->dev = dev; -+ priv->ds->priv = priv; -+ priv->ds->ops = &mt7530_switch_ops; -+ mutex_init(&priv->reg_mutex); -+ dev_set_drvdata(dev, priv); - -- if (priv->id == ID_MT7530) { -- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); -- if (IS_ERR(priv->core_pwr)) -- return PTR_ERR(priv->core_pwr); -+ return 0; -+} - -- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io"); -- if (IS_ERR(priv->io_pwr)) -- return PTR_ERR(priv->io_pwr); -- } -+static int -+mt7530_probe(struct mdio_device *mdiodev) -+{ -+ static struct regmap_config *regmap_config; -+ struct mt7530_priv *priv; -+ struct device_node *dn; -+ int ret; -+ -+ dn = mdiodev->dev.of_node; -+ -+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; - -- /* Not MCM that indicates switch works as the remote standalone -+ priv->bus = mdiodev->bus; -+ priv->dev = &mdiodev->dev; -+ -+ ret = mt7530_probe_common(priv); -+ if (ret) -+ return ret; -+ -+ /* Use medatek,mcm property to distinguish hardware type that would -+ * cause a little bit differences on power-on sequence. -+ * Not MCM that indicates switch works as the remote standalone - * integrated circuit so the GPIO pin would be used to complete - * the reset, otherwise memory-mapped register accessing used - * through syscon provides in the case of MCM. - */ -- if (!priv->mcm) { -+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm"); -+ if (priv->mcm) { -+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n"); -+ -+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm"); -+ if (IS_ERR(priv->rstc)) { -+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -+ return PTR_ERR(priv->rstc); -+ } -+ } else { - priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", - GPIOD_OUT_LOW); - if (IS_ERR(priv->reset)) { -@@ -3475,12 +3482,15 @@ mt7530_probe(struct mdio_device *mdiodev - } - } - -- priv->bus = mdiodev->bus; -- priv->dev = &mdiodev->dev; -- priv->ds->priv = priv; -- priv->ds->ops = &mt7530_switch_ops; -- mutex_init(&priv->reg_mutex); -- dev_set_drvdata(&mdiodev->dev, priv); -+ if (priv->id == ID_MT7530) { -+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); -+ if (IS_ERR(priv->core_pwr)) -+ return PTR_ERR(priv->core_pwr); -+ -+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io"); -+ if (IS_ERR(priv->io_pwr)) -+ return PTR_ERR(priv->io_pwr); -+ } - - regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config), - GFP_KERNEL); diff --git a/target/linux/generic/backport-6.1/790-11-v6.4-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch b/target/linux/generic/backport-6.1/790-11-v6.4-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch deleted file mode 100644 index 4192753e89b30c..00000000000000 --- a/target/linux/generic/backport-6.1/790-11-v6.4-net-dsa-mt7530-introduce-mt7530_remove_common-helper.patch +++ /dev/null @@ -1,54 +0,0 @@ -From a7783b0b6f3b38abd34cecf515811691714dee57 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:18:50 +0100 -Subject: [PATCH 11/48] net: dsa: mt7530: introduce mt7530_remove_common helper - function - -Move commonly used parts from mt7530_remove into new -mt7530_remove_common helper function which will be used by both, -mt7530_remove and the to-be-introduced mt7988_remove. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 18 ++++++++++++------ - 1 file changed, 12 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3517,6 +3517,17 @@ mt7530_probe(struct mdio_device *mdiodev - } - - static void -+mt7530_remove_common(struct mt7530_priv *priv) -+{ -+ if (priv->irq) -+ mt7530_free_irq(priv); -+ -+ dsa_unregister_switch(priv->ds); -+ -+ mutex_destroy(&priv->reg_mutex); -+} -+ -+static void - mt7530_remove(struct mdio_device *mdiodev) - { - struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -@@ -3535,15 +3546,10 @@ mt7530_remove(struct mdio_device *mdiode - dev_err(priv->dev, "Failed to disable io pwr: %d\n", - ret); - -- if (priv->irq) -- mt7530_free_irq(priv); -- -- dsa_unregister_switch(priv->ds); -+ mt7530_remove_common(priv); - - for (i = 0; i < 2; ++i) - mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs); -- -- mutex_destroy(&priv->reg_mutex); - } - - static void mt7530_shutdown(struct mdio_device *mdiodev) diff --git a/target/linux/generic/backport-6.1/790-12-v6.4-net-dsa-mt7530-introduce-separate-MDIO-driver.patch b/target/linux/generic/backport-6.1/790-12-v6.4-net-dsa-mt7530-introduce-separate-MDIO-driver.patch deleted file mode 100644 index 72a499381f404f..00000000000000 --- a/target/linux/generic/backport-6.1/790-12-v6.4-net-dsa-mt7530-introduce-separate-MDIO-driver.patch +++ /dev/null @@ -1,695 +0,0 @@ -From 5313432ca1e1a0677ad7b4f17a7e0186473f47aa Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:19:13 +0100 -Subject: [PATCH 12/48] net: dsa: mt7530: introduce separate MDIO driver - -Split MT7530 switch driver into a common part and a part specific -for MDIO connected switches and multi-chip modules. -Move MDIO-specific functions to newly introduced mt7530-mdio.c while -keeping the common parts in mt7530.c. -Introduce new Kconfig symbol CONFIG_NET_DSA_MT7530_MDIO which is -implied by CONFIG_NET_DSA_MT7530. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - MAINTAINERS | 1 + - drivers/net/dsa/Kconfig | 18 ++- - drivers/net/dsa/Makefile | 1 + - drivers/net/dsa/mt7530-mdio.c | 271 ++++++++++++++++++++++++++++++++++ - drivers/net/dsa/mt7530.c | 264 +-------------------------------- - drivers/net/dsa/mt7530.h | 6 + - 6 files changed, 302 insertions(+), 259 deletions(-) - create mode 100644 drivers/net/dsa/mt7530-mdio.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -13069,6 +13069,7 @@ M: Landen Chao - L: netdev@vger.kernel.org - S: Maintained -+F: drivers/net/dsa/mt7530-mdio.c - F: drivers/net/dsa/mt7530.* - F: net/dsa/tag_mtk.c - ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -34,13 +34,25 @@ config NET_DSA_LANTIQ_GSWIP - the xrx200 / VR9 SoC. - - config NET_DSA_MT7530 -- tristate "MediaTek MT753x and MT7621 Ethernet switch support" -+ tristate "MediaTek MT7530 and MT7531 Ethernet switch support" - select NET_DSA_TAG_MTK -+ imply NET_DSA_MT7530_MDIO -+ help -+ This enables support for the MediaTek MT7530 and MT7531 Ethernet -+ switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT, -+ MT7621ST and MT7623AI SoCs, and built-in switch in MT7988 SoC are -+ supported as well. -+ -+config NET_DSA_MT7530_MDIO -+ tristate "MediaTek MT7530 MDIO interface driver" -+ depends on NET_DSA_MT7530 - select MEDIATEK_GE_PHY - select PCS_MTK_LYNXI - help -- This enables support for the MediaTek MT7530, MT7531, and MT7621 -- Ethernet switch chips. -+ This enables support for the MediaTek MT7530 and MT7531 switch -+ chips which are connected via MDIO, as well as multi-chip -+ module MT7530 which can be found in the MT7621AT, MT7621DAT, -+ MT7621ST and MT7623AI SoCs. - - config NET_DSA_MV88E6060 - tristate "Marvell 88E6060 ethernet switch chip support" ---- a/drivers/net/dsa/Makefile -+++ b/drivers/net/dsa/Makefile -@@ -7,6 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdi - endif - obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o - obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o -+obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o - obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o - obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o - obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o ---- /dev/null -+++ b/drivers/net/dsa/mt7530-mdio.c -@@ -0,0 +1,271 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mt7530.h" -+ -+static int -+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) -+{ -+ struct mii_bus *bus = context; -+ u16 page, r, lo, hi; -+ int ret; -+ -+ page = (reg >> 6) & 0x3ff; -+ r = (reg >> 2) & 0xf; -+ lo = val & 0xffff; -+ hi = val >> 16; -+ -+ /* MT7530 uses 31 as the pseudo port */ -+ ret = bus->write(bus, 0x1f, 0x1f, page); -+ if (ret < 0) -+ return ret; -+ -+ ret = bus->write(bus, 0x1f, r, lo); -+ if (ret < 0) -+ return ret; -+ -+ ret = bus->write(bus, 0x1f, 0x10, hi); -+ return ret; -+} -+ -+static int -+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) -+{ -+ struct mii_bus *bus = context; -+ u16 page, r, lo, hi; -+ int ret; -+ -+ page = (reg >> 6) & 0x3ff; -+ r = (reg >> 2) & 0xf; -+ -+ /* MT7530 uses 31 as the pseudo port */ -+ ret = bus->write(bus, 0x1f, 0x1f, page); -+ if (ret < 0) -+ return ret; -+ -+ lo = bus->read(bus, 0x1f, r); -+ hi = bus->read(bus, 0x1f, 0x10); -+ -+ *val = (hi << 16) | (lo & 0xffff); -+ -+ return 0; -+} -+ -+static void -+mt7530_mdio_regmap_lock(void *mdio_lock) -+{ -+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED); -+} -+ -+static void -+mt7530_mdio_regmap_unlock(void *mdio_lock) -+{ -+ mutex_unlock(mdio_lock); -+} -+ -+static const struct regmap_bus mt7530_regmap_bus = { -+ .reg_write = mt7530_regmap_write, -+ .reg_read = mt7530_regmap_read, -+}; -+ -+static int -+mt7531_create_sgmii(struct mt7530_priv *priv) -+{ -+ struct regmap_config *mt7531_pcs_config[2]; -+ struct phylink_pcs *pcs; -+ struct regmap *regmap; -+ int i, ret = 0; -+ -+ for (i = 0; i < 2; i++) { -+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev, -+ sizeof(struct regmap_config), -+ GFP_KERNEL); -+ if (!mt7531_pcs_config[i]) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ mt7531_pcs_config[i]->name = i ? "port6" : "port5"; -+ mt7531_pcs_config[i]->reg_bits = 16; -+ mt7531_pcs_config[i]->val_bits = 32; -+ mt7531_pcs_config[i]->reg_stride = 4; -+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); -+ mt7531_pcs_config[i]->max_register = 0x17c; -+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock; -+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock; -+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; -+ -+ regmap = devm_regmap_init(priv->dev, -+ &mt7530_regmap_bus, priv->bus, -+ mt7531_pcs_config[i]); -+ if (IS_ERR(regmap)) { -+ ret = PTR_ERR(regmap); -+ break; -+ } -+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap, -+ MT7531_PHYA_CTRL_SIGNAL3, 0); -+ if (!pcs) { -+ ret = -ENXIO; -+ break; -+ } -+ priv->ports[5 + i].sgmii_pcs = pcs; -+ } -+ -+ if (ret && i) -+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs); -+ -+ return ret; -+} -+ -+static const struct of_device_id mt7530_of_match[] = { -+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], }, -+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], }, -+ { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, mt7530_of_match); -+ -+static int -+mt7530_probe(struct mdio_device *mdiodev) -+{ -+ static struct regmap_config *regmap_config; -+ struct mt7530_priv *priv; -+ struct device_node *dn; -+ int ret; -+ -+ dn = mdiodev->dev.of_node; -+ -+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->bus = mdiodev->bus; -+ priv->dev = &mdiodev->dev; -+ -+ ret = mt7530_probe_common(priv); -+ if (ret) -+ return ret; -+ -+ /* Use medatek,mcm property to distinguish hardware type that would -+ * cause a little bit differences on power-on sequence. -+ * Not MCM that indicates switch works as the remote standalone -+ * integrated circuit so the GPIO pin would be used to complete -+ * the reset, otherwise memory-mapped register accessing used -+ * through syscon provides in the case of MCM. -+ */ -+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm"); -+ if (priv->mcm) { -+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n"); -+ -+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm"); -+ if (IS_ERR(priv->rstc)) { -+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -+ return PTR_ERR(priv->rstc); -+ } -+ } else { -+ priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", -+ GPIOD_OUT_LOW); -+ if (IS_ERR(priv->reset)) { -+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -+ return PTR_ERR(priv->reset); -+ } -+ } -+ -+ if (priv->id == ID_MT7530) { -+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); -+ if (IS_ERR(priv->core_pwr)) -+ return PTR_ERR(priv->core_pwr); -+ -+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io"); -+ if (IS_ERR(priv->io_pwr)) -+ return PTR_ERR(priv->io_pwr); -+ } -+ -+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config), -+ GFP_KERNEL); -+ if (!regmap_config) -+ return -ENOMEM; -+ -+ regmap_config->reg_bits = 16; -+ regmap_config->val_bits = 32; -+ regmap_config->reg_stride = 4; -+ regmap_config->max_register = MT7530_CREV; -+ regmap_config->disable_locking = true; -+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, -+ priv->bus, regmap_config); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); -+ -+ if (priv->id == ID_MT7531) { -+ ret = mt7531_create_sgmii(priv); -+ if (ret) -+ return ret; -+ } -+ -+ return dsa_register_switch(priv->ds); -+} -+ -+static void -+mt7530_remove(struct mdio_device *mdiodev) -+{ -+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -+ int ret = 0, i; -+ -+ if (!priv) -+ return; -+ -+ ret = regulator_disable(priv->core_pwr); -+ if (ret < 0) -+ dev_err(priv->dev, -+ "Failed to disable core power: %d\n", ret); -+ -+ ret = regulator_disable(priv->io_pwr); -+ if (ret < 0) -+ dev_err(priv->dev, "Failed to disable io pwr: %d\n", -+ ret); -+ -+ mt7530_remove_common(priv); -+ -+ for (i = 0; i < 2; ++i) -+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs); -+} -+ -+static void mt7530_shutdown(struct mdio_device *mdiodev) -+{ -+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -+ -+ if (!priv) -+ return; -+ -+ dsa_switch_shutdown(priv->ds); -+ -+ dev_set_drvdata(&mdiodev->dev, NULL); -+} -+ -+static struct mdio_driver mt7530_mdio_driver = { -+ .probe = mt7530_probe, -+ .remove = mt7530_remove, -+ .shutdown = mt7530_shutdown, -+ .mdiodrv.driver = { -+ .name = "mt7530-mdio", -+ .of_match_table = mt7530_of_match, -+ }, -+}; -+ -+mdio_module_driver(mt7530_mdio_driver); -+ -+MODULE_AUTHOR("Sean Wang "); -+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MDIO)"); -+MODULE_LICENSE("GPL"); ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -14,7 +14,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -192,31 +191,6 @@ core_clear(struct mt7530_priv *priv, u32 - } - - static int --mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) --{ -- struct mii_bus *bus = context; -- u16 page, r, lo, hi; -- int ret; -- -- page = (reg >> 6) & 0x3ff; -- r = (reg >> 2) & 0xf; -- lo = val & 0xffff; -- hi = val >> 16; -- -- /* MT7530 uses 31 as the pseudo port */ -- ret = bus->write(bus, 0x1f, 0x1f, page); -- if (ret < 0) -- return ret; -- -- ret = bus->write(bus, 0x1f, r, lo); -- if (ret < 0) -- return ret; -- -- ret = bus->write(bus, 0x1f, 0x10, hi); -- return ret; --} -- --static int - mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val) - { - int ret; -@@ -230,29 +204,6 @@ mt7530_mii_write(struct mt7530_priv *pri - return ret; - } - --static int --mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) --{ -- struct mii_bus *bus = context; -- u16 page, r, lo, hi; -- int ret; -- -- page = (reg >> 6) & 0x3ff; -- r = (reg >> 2) & 0xf; -- -- /* MT7530 uses 31 as the pseudo port */ -- ret = bus->write(bus, 0x1f, 0x1f, page); -- if (ret < 0) -- return ret; -- -- lo = bus->read(bus, 0x1f, r); -- hi = bus->read(bus, 0x1f, 0x10); -- -- *val = (hi << 16) | (lo & 0xffff); -- -- return 0; --} -- - static u32 - mt7530_mii_read(struct mt7530_priv *priv, u32 reg) - { -@@ -3196,72 +3147,6 @@ static const struct phylink_pcs_ops mt75 - .pcs_an_restart = mt7530_pcs_an_restart, - }; - --static void --mt7530_mdio_regmap_lock(void *mdio_lock) --{ -- mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED); --} -- --static void --mt7530_mdio_regmap_unlock(void *mdio_lock) --{ -- mutex_unlock(mdio_lock); --} -- --static const struct regmap_bus mt7530_regmap_bus = { -- .reg_write = mt7530_regmap_write, -- .reg_read = mt7530_regmap_read, --}; -- --static int --mt7531_create_sgmii(struct mt7530_priv *priv) --{ -- struct regmap_config *mt7531_pcs_config[2]; -- struct phylink_pcs *pcs; -- struct regmap *regmap; -- int i, ret = 0; -- -- for (i = 0; i < 2; i++) { -- mt7531_pcs_config[i] = devm_kzalloc(priv->dev, -- sizeof(struct regmap_config), -- GFP_KERNEL); -- if (!mt7531_pcs_config[i]) { -- ret = -ENOMEM; -- break; -- } -- -- mt7531_pcs_config[i]->name = i ? "port6" : "port5"; -- mt7531_pcs_config[i]->reg_bits = 16; -- mt7531_pcs_config[i]->val_bits = 32; -- mt7531_pcs_config[i]->reg_stride = 4; -- mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i); -- mt7531_pcs_config[i]->max_register = 0x17c; -- mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock; -- mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock; -- mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; -- -- regmap = devm_regmap_init(priv->dev, -- &mt7530_regmap_bus, priv->bus, -- mt7531_pcs_config[i]); -- if (IS_ERR(regmap)) { -- ret = PTR_ERR(regmap); -- break; -- } -- pcs = mtk_pcs_lynxi_create(priv->dev, regmap, -- MT7531_PHYA_CTRL_SIGNAL3, 0); -- if (!pcs) { -- ret = -ENXIO; -- break; -- } -- priv->ports[5 + i].sgmii_pcs = pcs; -- } -- -- if (ret && i) -- mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs); -- -- return ret; --} -- - static int - mt753x_setup(struct dsa_switch *ds) - { -@@ -3320,7 +3205,7 @@ static int mt753x_set_mac_eee(struct dsa - return 0; - } - --static const struct dsa_switch_ops mt7530_switch_ops = { -+const struct dsa_switch_ops mt7530_switch_ops = { - .get_tag_protocol = mtk_get_tag_protocol, - .setup = mt753x_setup, - .preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port, -@@ -3355,8 +3240,9 @@ static const struct dsa_switch_ops mt753 - .get_mac_eee = mt753x_get_mac_eee, - .set_mac_eee = mt753x_set_mac_eee, - }; -+EXPORT_SYMBOL_GPL(mt7530_switch_ops); - --static const struct mt753x_info mt753x_table[] = { -+const struct mt753x_info mt753x_table[] = { - [ID_MT7621] = { - .id = ID_MT7621, - .pcs_ops = &mt7530_pcs_ops, -@@ -3389,16 +3275,9 @@ static const struct mt753x_info mt753x_t - .mac_port_config = mt7531_mac_config, - }, - }; -+EXPORT_SYMBOL_GPL(mt753x_table); - --static const struct of_device_id mt7530_of_match[] = { -- { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], }, -- { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], }, -- { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], }, -- { /* sentinel */ }, --}; --MODULE_DEVICE_TABLE(of, mt7530_of_match); -- --static int -+int - mt7530_probe_common(struct mt7530_priv *priv) - { - struct device *dev = priv->dev; -@@ -3435,88 +3314,9 @@ mt7530_probe_common(struct mt7530_priv * - - return 0; - } -+EXPORT_SYMBOL_GPL(mt7530_probe_common); - --static int --mt7530_probe(struct mdio_device *mdiodev) --{ -- static struct regmap_config *regmap_config; -- struct mt7530_priv *priv; -- struct device_node *dn; -- int ret; -- -- dn = mdiodev->dev.of_node; -- -- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- -- priv->bus = mdiodev->bus; -- priv->dev = &mdiodev->dev; -- -- ret = mt7530_probe_common(priv); -- if (ret) -- return ret; -- -- /* Use medatek,mcm property to distinguish hardware type that would -- * cause a little bit differences on power-on sequence. -- * Not MCM that indicates switch works as the remote standalone -- * integrated circuit so the GPIO pin would be used to complete -- * the reset, otherwise memory-mapped register accessing used -- * through syscon provides in the case of MCM. -- */ -- priv->mcm = of_property_read_bool(dn, "mediatek,mcm"); -- if (priv->mcm) { -- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n"); -- -- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm"); -- if (IS_ERR(priv->rstc)) { -- dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -- return PTR_ERR(priv->rstc); -- } -- } else { -- priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", -- GPIOD_OUT_LOW); -- if (IS_ERR(priv->reset)) { -- dev_err(&mdiodev->dev, "Couldn't get our reset line\n"); -- return PTR_ERR(priv->reset); -- } -- } -- -- if (priv->id == ID_MT7530) { -- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core"); -- if (IS_ERR(priv->core_pwr)) -- return PTR_ERR(priv->core_pwr); -- -- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io"); -- if (IS_ERR(priv->io_pwr)) -- return PTR_ERR(priv->io_pwr); -- } -- -- regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config), -- GFP_KERNEL); -- if (!regmap_config) -- return -ENOMEM; -- -- regmap_config->reg_bits = 16; -- regmap_config->val_bits = 32; -- regmap_config->reg_stride = 4; -- regmap_config->max_register = MT7530_CREV; -- regmap_config->disable_locking = true; -- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, -- priv->bus, regmap_config); -- if (IS_ERR(priv->regmap)) -- return PTR_ERR(priv->regmap); -- -- if (priv->id == ID_MT7531) { -- ret = mt7531_create_sgmii(priv); -- if (ret) -- return ret; -- } -- -- return dsa_register_switch(priv->ds); --} -- --static void -+void - mt7530_remove_common(struct mt7530_priv *priv) - { - if (priv->irq) -@@ -3526,55 +3326,7 @@ mt7530_remove_common(struct mt7530_priv - - mutex_destroy(&priv->reg_mutex); - } -- --static void --mt7530_remove(struct mdio_device *mdiodev) --{ -- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -- int ret = 0, i; -- -- if (!priv) -- return; -- -- ret = regulator_disable(priv->core_pwr); -- if (ret < 0) -- dev_err(priv->dev, -- "Failed to disable core power: %d\n", ret); -- -- ret = regulator_disable(priv->io_pwr); -- if (ret < 0) -- dev_err(priv->dev, "Failed to disable io pwr: %d\n", -- ret); -- -- mt7530_remove_common(priv); -- -- for (i = 0; i < 2; ++i) -- mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs); --} -- --static void mt7530_shutdown(struct mdio_device *mdiodev) --{ -- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev); -- -- if (!priv) -- return; -- -- dsa_switch_shutdown(priv->ds); -- -- dev_set_drvdata(&mdiodev->dev, NULL); --} -- --static struct mdio_driver mt7530_mdio_driver = { -- .probe = mt7530_probe, -- .remove = mt7530_remove, -- .shutdown = mt7530_shutdown, -- .mdiodrv.driver = { -- .name = "mt7530", -- .of_match_table = mt7530_of_match, -- }, --}; -- --mdio_module_driver(mt7530_mdio_driver); -+EXPORT_SYMBOL_GPL(mt7530_remove_common); - - MODULE_AUTHOR("Sean Wang "); - MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch"); ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -845,4 +845,10 @@ static inline void INIT_MT7530_DUMMY_POL - p->reg = reg; - } - -+int mt7530_probe_common(struct mt7530_priv *priv); -+void mt7530_remove_common(struct mt7530_priv *priv); -+ -+extern const struct dsa_switch_ops mt7530_switch_ops; -+extern const struct mt753x_info mt753x_table[]; -+ - #endif /* __MT7530_H */ diff --git a/target/linux/generic/backport-6.1/790-13-v6.4-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch b/target/linux/generic/backport-6.1/790-13-v6.4-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch deleted file mode 100644 index dae7dd4a48c4cb..00000000000000 --- a/target/linux/generic/backport-6.1/790-13-v6.4-net-dsa-mt7530-skip-locking-if-MDIO-bus-isn-t-presen.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 86e1168a214b7ab0883acf1e7a6885a7a949e3e7 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:19:28 +0100 -Subject: [PATCH 13/48] net: dsa: mt7530: skip locking if MDIO bus isn't - present - -As MT7530 and MT7531 internally use 32-bit wide registers, each access -to any register of the switch requires several operations on the MDIO -bus. Hence if there is congruent access, e.g. due to PCS or PHY -polling, this can mess up and interfere with another ongoing register -access sequence. - -However, the MDIO bus mutex is only relevant for MDIO-connected -switches. Prepare switches which have there registers directly mapped -into the SoCs register space via MMIO which do not require such -locking. There we can simply use regmap's default locking mechanism. - -Hence guard mutex operations to only be performed in case of MDIO -connected switches. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -144,13 +144,15 @@ err: - static void - mt7530_mutex_lock(struct mt7530_priv *priv) - { -- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); -+ if (priv->bus) -+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); - } - - static void - mt7530_mutex_unlock(struct mt7530_priv *priv) - { -- mutex_unlock(&priv->bus->mdio_lock); -+ if (priv->bus) -+ mutex_unlock(&priv->bus->mdio_lock); - } - - static void diff --git a/target/linux/generic/backport-6.1/790-14-v6.4-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch b/target/linux/generic/backport-6.1/790-14-v6.4-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch deleted file mode 100644 index f5573fc6c458d9..00000000000000 --- a/target/linux/generic/backport-6.1/790-14-v6.4-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch +++ /dev/null @@ -1,421 +0,0 @@ -From a1b87b6322db9186c8689710fe3e98f59e540949 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 02:19:40 +0100 -Subject: [PATCH 14/48] net: dsa: mt7530: introduce driver for MT7988 built-in - switch - -Add driver for the built-in Gigabit Ethernet switch which can be found -in the MediaTek MT7988 SoC. - -The switch shares most of its design with MT7530 and MT7531, but has -it's registers mapped into the SoCs register space rather than being -connected externally or internally via MDIO. - -Introduce a new platform driver to support that. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - MAINTAINERS | 2 + - drivers/net/dsa/Kconfig | 12 +++ - drivers/net/dsa/Makefile | 1 + - drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++ - drivers/net/dsa/mt7530.c | 135 +++++++++++++++++++++++++++++++++- - drivers/net/dsa/mt7530.h | 12 +-- - 6 files changed, 253 insertions(+), 10 deletions(-) - create mode 100644 drivers/net/dsa/mt7530-mmio.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -13067,9 +13067,11 @@ MEDIATEK SWITCH DRIVER - M: Sean Wang - M: Landen Chao - M: DENG Qingfang -+M: Daniel Golle - L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/dsa/mt7530-mdio.c -+F: drivers/net/dsa/mt7530-mmio.c - F: drivers/net/dsa/mt7530.* - F: net/dsa/tag_mtk.c - ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -37,6 +37,7 @@ config NET_DSA_MT7530 - tristate "MediaTek MT7530 and MT7531 Ethernet switch support" - select NET_DSA_TAG_MTK - imply NET_DSA_MT7530_MDIO -+ imply NET_DSA_MT7530_MMIO - help - This enables support for the MediaTek MT7530 and MT7531 Ethernet - switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT, -@@ -54,6 +55,17 @@ config NET_DSA_MT7530_MDIO - module MT7530 which can be found in the MT7621AT, MT7621DAT, - MT7621ST and MT7623AI SoCs. - -+config NET_DSA_MT7530_MMIO -+ tristate "MediaTek MT7530 MMIO interface driver" -+ depends on NET_DSA_MT7530 -+ depends on HAS_IOMEM -+ help -+ This enables support for the built-in Ethernet switch found -+ in the MediaTek MT7988 SoC. -+ The switch is a similar design as MT7531, but the switch registers -+ are directly mapped into the SoCs register space rather than being -+ accessible via MDIO. -+ - config NET_DSA_MV88E6060 - tristate "Marvell 88E6060 ethernet switch chip support" - select NET_DSA_TAG_TRAILER ---- a/drivers/net/dsa/Makefile -+++ b/drivers/net/dsa/Makefile -@@ -8,6 +8,7 @@ endif - obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o - obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o - obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o -+obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o - obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o - obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o - obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o ---- /dev/null -+++ b/drivers/net/dsa/mt7530-mmio.c -@@ -0,0 +1,101 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mt7530.h" -+ -+static const struct of_device_id mt7988_of_match[] = { -+ { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, mt7988_of_match); -+ -+static int -+mt7988_probe(struct platform_device *pdev) -+{ -+ static struct regmap_config *sw_regmap_config; -+ struct mt7530_priv *priv; -+ void __iomem *base_addr; -+ int ret; -+ -+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->bus = NULL; -+ priv->dev = &pdev->dev; -+ -+ ret = mt7530_probe_common(priv); -+ if (ret) -+ return ret; -+ -+ priv->rstc = devm_reset_control_get(&pdev->dev, NULL); -+ if (IS_ERR(priv->rstc)) { -+ dev_err(&pdev->dev, "Couldn't get our reset line\n"); -+ return PTR_ERR(priv->rstc); -+ } -+ -+ base_addr = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(base_addr)) { -+ dev_err(&pdev->dev, "cannot request I/O memory space\n"); -+ return -ENXIO; -+ } -+ -+ sw_regmap_config = devm_kzalloc(&pdev->dev, sizeof(*sw_regmap_config), GFP_KERNEL); -+ if (!sw_regmap_config) -+ return -ENOMEM; -+ -+ sw_regmap_config->name = "switch"; -+ sw_regmap_config->reg_bits = 16; -+ sw_regmap_config->val_bits = 32; -+ sw_regmap_config->reg_stride = 4; -+ sw_regmap_config->max_register = MT7530_CREV; -+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base_addr, sw_regmap_config); -+ if (IS_ERR(priv->regmap)) -+ return PTR_ERR(priv->regmap); -+ -+ return dsa_register_switch(priv->ds); -+} -+ -+static int -+mt7988_remove(struct platform_device *pdev) -+{ -+ struct mt7530_priv *priv = platform_get_drvdata(pdev); -+ -+ if (priv) -+ mt7530_remove_common(priv); -+ -+ return 0; -+} -+ -+static void mt7988_shutdown(struct platform_device *pdev) -+{ -+ struct mt7530_priv *priv = platform_get_drvdata(pdev); -+ -+ if (!priv) -+ return; -+ -+ dsa_switch_shutdown(priv->ds); -+ -+ dev_set_drvdata(&pdev->dev, NULL); -+} -+ -+static struct platform_driver mt7988_platform_driver = { -+ .probe = mt7988_probe, -+ .remove = mt7988_remove, -+ .shutdown = mt7988_shutdown, -+ .driver = { -+ .name = "mt7530-mmio", -+ .of_match_table = mt7988_of_match, -+ }, -+}; -+module_platform_driver(mt7988_platform_driver); -+ -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MMIO)"); -+MODULE_LICENSE("GPL"); ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2223,6 +2223,47 @@ static const struct irq_domain_ops mt753 - }; - - static void -+mt7988_irq_mask(struct irq_data *d) -+{ -+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); -+ -+ priv->irq_enable &= ~BIT(d->hwirq); -+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable); -+} -+ -+static void -+mt7988_irq_unmask(struct irq_data *d) -+{ -+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d); -+ -+ priv->irq_enable |= BIT(d->hwirq); -+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable); -+} -+ -+static struct irq_chip mt7988_irq_chip = { -+ .name = KBUILD_MODNAME, -+ .irq_mask = mt7988_irq_mask, -+ .irq_unmask = mt7988_irq_unmask, -+}; -+ -+static int -+mt7988_irq_map(struct irq_domain *domain, unsigned int irq, -+ irq_hw_number_t hwirq) -+{ -+ irq_set_chip_data(irq, domain->host_data); -+ irq_set_chip_and_handler(irq, &mt7988_irq_chip, handle_simple_irq); -+ irq_set_nested_thread(irq, true); -+ irq_set_noprobe(irq); -+ -+ return 0; -+} -+ -+static const struct irq_domain_ops mt7988_irq_domain_ops = { -+ .map = mt7988_irq_map, -+ .xlate = irq_domain_xlate_onecell, -+}; -+ -+static void - mt7530_setup_mdio_irq(struct mt7530_priv *priv) - { - struct dsa_switch *ds = priv->ds; -@@ -2256,8 +2297,15 @@ mt7530_setup_irq(struct mt7530_priv *pri - return priv->irq ? : -EINVAL; - } - -- priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS, -- &mt7530_irq_domain_ops, priv); -+ if (priv->id == ID_MT7988) -+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS, -+ &mt7988_irq_domain_ops, -+ priv); -+ else -+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS, -+ &mt7530_irq_domain_ops, -+ priv); -+ - if (!priv->irq_domain) { - dev_err(dev, "failed to create IRQ domain\n"); - return -ENOMEM; -@@ -2762,6 +2810,25 @@ static void mt7531_mac_port_get_caps(str - } - } - -+static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port, -+ struct phylink_config *config) -+{ -+ phy_interface_zero(config->supported_interfaces); -+ -+ switch (port) { -+ case 0 ... 4: /* Internal phy */ -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ config->supported_interfaces); -+ break; -+ -+ case 6: -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ config->supported_interfaces); -+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -+ MAC_10000FD; -+ } -+} -+ - static int - mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) - { -@@ -2838,6 +2905,17 @@ static bool mt753x_is_mac_port(u32 port) - } - - static int -+mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode, -+ phy_interface_t interface) -+{ -+ if (dsa_is_cpu_port(ds, port) && -+ interface == PHY_INTERFACE_MODE_INTERNAL) -+ return 0; -+ -+ return -EINVAL; -+} -+ -+static int - mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - phy_interface_t interface) - { -@@ -2907,7 +2985,8 @@ mt753x_phylink_mac_config(struct dsa_swi - - switch (port) { - case 0 ... 4: /* Internal phy */ -- if (state->interface != PHY_INTERFACE_MODE_GMII) -+ if (state->interface != PHY_INTERFACE_MODE_GMII && -+ state->interface != PHY_INTERFACE_MODE_INTERNAL) - goto unsupported; - break; - case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -@@ -2985,7 +3064,8 @@ static void mt753x_phylink_mac_link_up(s - /* MT753x MAC works in 1G full duplex mode for all up-clocked - * variants. - */ -- if (interface == PHY_INTERFACE_MODE_TRGMII || -+ if (interface == PHY_INTERFACE_MODE_INTERNAL || -+ interface == PHY_INTERFACE_MODE_TRGMII || - (phy_interface_mode_is_8023z(interface))) { - speed = SPEED_1000; - duplex = DUPLEX_FULL; -@@ -3065,6 +3145,21 @@ mt7531_cpu_port_config(struct dsa_switch - return 0; - } - -+static int -+mt7988_cpu_port_config(struct dsa_switch *ds, int port) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ mt7530_write(priv, MT7530_PMCR_P(port), -+ PMCR_CPU_PORT_SETTING(priv->id)); -+ -+ mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, -+ PHY_INTERFACE_MODE_INTERNAL, NULL, -+ SPEED_10000, DUPLEX_FULL, true, true); -+ -+ return 0; -+} -+ - static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, - struct phylink_config *config) - { -@@ -3207,6 +3302,27 @@ static int mt753x_set_mac_eee(struct dsa - return 0; - } - -+static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface) -+{ -+ return 0; -+} -+ -+static int mt7988_setup(struct dsa_switch *ds) -+{ -+ struct mt7530_priv *priv = ds->priv; -+ -+ /* Reset the switch */ -+ reset_control_assert(priv->rstc); -+ usleep_range(20, 50); -+ reset_control_deassert(priv->rstc); -+ usleep_range(20, 50); -+ -+ /* Reset the switch PHYs */ -+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST); -+ -+ return mt7531_setup_common(ds); -+} -+ - const struct dsa_switch_ops mt7530_switch_ops = { - .get_tag_protocol = mtk_get_tag_protocol, - .setup = mt753x_setup, -@@ -3276,6 +3392,17 @@ const struct mt753x_info mt753x_table[] - .mac_port_get_caps = mt7531_mac_port_get_caps, - .mac_port_config = mt7531_mac_config, - }, -+ [ID_MT7988] = { -+ .id = ID_MT7988, -+ .pcs_ops = &mt7530_pcs_ops, -+ .sw_setup = mt7988_setup, -+ .phy_read = mt7531_ind_phy_read, -+ .phy_write = mt7531_ind_phy_write, -+ .pad_setup = mt7988_pad_setup, -+ .cpu_port_config = mt7988_cpu_port_config, -+ .mac_port_get_caps = mt7988_mac_port_get_caps, -+ .mac_port_config = mt7988_mac_config, -+ }, - }; - EXPORT_SYMBOL_GPL(mt753x_table); - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -18,6 +18,7 @@ enum mt753x_id { - ID_MT7530 = 0, - ID_MT7621 = 1, - ID_MT7531 = 2, -+ ID_MT7988 = 3, - }; - - #define NUM_TRGMII_CTRL 5 -@@ -59,11 +60,11 @@ enum mt753x_id { - #define MT7531_CPU_PMAP_MASK GENMASK(7, 0) - #define MT7531_CPU_PMAP(x) FIELD_PREP(MT7531_CPU_PMAP_MASK, x) - --#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \ -+#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ - MT7531_CFC : MT7530_MFC) --#define MT753X_MIRROR_EN(id) (((id) == ID_MT7531) ? \ -+#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ - MT7531_MIRROR_EN : MIRROR_EN) --#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \ -+#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ - MT7531_MIRROR_MASK : MIRROR_MASK) - - /* Registers for BPDU and PAE frame control*/ -@@ -332,9 +333,8 @@ enum mt7530_vlan_port_acc_frm { - MT7531_FORCE_DPX | \ - MT7531_FORCE_RX_FC | \ - MT7531_FORCE_TX_FC) --#define PMCR_FORCE_MODE_ID(id) (((id) == ID_MT7531) ? \ -- MT7531_FORCE_MODE : \ -- PMCR_FORCE_MODE) -+#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ -+ MT7531_FORCE_MODE : PMCR_FORCE_MODE) - #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \ - PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \ - PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ diff --git a/target/linux/generic/backport-6.1/790-15-v6.4-net-dsa-mt7530-fix-support-for-MT7531BE.patch b/target/linux/generic/backport-6.1/790-15-v6.4-net-dsa-mt7530-fix-support-for-MT7531BE.patch deleted file mode 100644 index 40209b030583b8..00000000000000 --- a/target/linux/generic/backport-6.1/790-15-v6.4-net-dsa-mt7530-fix-support-for-MT7531BE.patch +++ /dev/null @@ -1,118 +0,0 @@ -From ed01748319b25456c5226ed0cb5e49e970da0e4f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 16 Apr 2023 13:08:14 +0100 -Subject: [PATCH 15/48] net: dsa: mt7530: fix support for MT7531BE -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There are two variants of the MT7531 switch IC which got different -features (and pins) regarding port 5: - * MT7531AE: SGMII/1000Base-X/2500Base-X SerDes PCS - * MT7531BE: RGMII - -Moving the creation of the SerDes PCS from mt753x_setup to mt7530_probe -with commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation -to mt7530_probe function") works fine for MT7531AE which got two -instances of mtk-pcs-lynxi, however, MT7531BE requires mt7531_pll_setup -to setup clocks before the single PCS on port 6 (usually used as CPU -port) starts to work and hence the PCS creation failed on MT7531BE. - -Fix this by introducing a pointer to mt7531_create_sgmii function in -struct mt7530_priv and call it again at the end of mt753x_setup like it -was before commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS -creation to mt7530_probe function"). - -Fixes: 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation to mt7530_probe function") -Signed-off-by: Daniel Golle -Acked-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/ZDvlLhhqheobUvOK@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530-mdio.c | 16 ++++++++-------- - drivers/net/dsa/mt7530.c | 6 ++++++ - drivers/net/dsa/mt7530.h | 4 ++-- - 3 files changed, 16 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/mt7530-mdio.c -+++ b/drivers/net/dsa/mt7530-mdio.c -@@ -81,14 +81,17 @@ static const struct regmap_bus mt7530_re - }; - - static int --mt7531_create_sgmii(struct mt7530_priv *priv) -+mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii) - { -- struct regmap_config *mt7531_pcs_config[2]; -+ struct regmap_config *mt7531_pcs_config[2] = {}; - struct phylink_pcs *pcs; - struct regmap *regmap; - int i, ret = 0; - -- for (i = 0; i < 2; i++) { -+ /* MT7531AE has two SGMII units for port 5 and port 6 -+ * MT7531BE has only one SGMII unit for port 6 -+ */ -+ for (i = dual_sgmii ? 0 : 1; i < 2; i++) { - mt7531_pcs_config[i] = devm_kzalloc(priv->dev, - sizeof(struct regmap_config), - GFP_KERNEL); -@@ -208,11 +211,8 @@ mt7530_probe(struct mdio_device *mdiodev - if (IS_ERR(priv->regmap)) - return PTR_ERR(priv->regmap); - -- if (priv->id == ID_MT7531) { -- ret = mt7531_create_sgmii(priv); -- if (ret) -- return ret; -- } -+ if (priv->id == ID_MT7531) -+ priv->create_sgmii = mt7531_create_sgmii; - - return dsa_register_switch(priv->ds); - } ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3269,6 +3269,12 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -+ if (priv->create_sgmii) { -+ ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv)); -+ if (ret && priv->irq) -+ mt7530_free_irq(priv); -+ } -+ - return ret; - } - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -779,10 +779,10 @@ struct mt753x_info { - * registers - * @p6_interface Holding the current port 6 interface - * @p5_intf_sel: Holding the current port 5 interface select -- * - * @irq: IRQ number of the switch - * @irq_domain: IRQ domain of the switch irq_chip - * @irq_enable: IRQ enable bits, synced to SYS_INT_EN -+ * @create_sgmii: Pointer to function creating SGMII PCS instance(s) - */ - struct mt7530_priv { - struct device *dev; -@@ -801,7 +801,6 @@ struct mt7530_priv { - unsigned int p5_intf_sel; - u8 mirror_rx; - u8 mirror_tx; -- - struct mt7530_port ports[MT7530_NUM_PORTS]; - struct mt753x_pcs pcs[MT7530_NUM_PORTS]; - /* protect among processes for registers access*/ -@@ -809,6 +808,7 @@ struct mt7530_priv { - int irq; - struct irq_domain *irq_domain; - u32 irq_enable; -+ int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii); - }; - - struct mt7530_hw_vlan_entry { diff --git a/target/linux/generic/backport-6.1/790-17-v6.5-net-dsa-mt7530-update-PCS-driver-to-use-neg_mode.patch b/target/linux/generic/backport-6.1/790-17-v6.5-net-dsa-mt7530-update-PCS-driver-to-use-neg_mode.patch deleted file mode 100644 index 78e332b1c2ae51..00000000000000 --- a/target/linux/generic/backport-6.1/790-17-v6.5-net-dsa-mt7530-update-PCS-driver-to-use-neg_mode.patch +++ /dev/null @@ -1,35 +0,0 @@ -From fb6858e2c3b931433ea4d25871c272ee4c01bd99 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 16 Jun 2023 13:07:29 +0100 -Subject: [PATCH 17/48] net: dsa: mt7530: update PCS driver to use neg_mode - -Update mt7530's embedded PCS driver to use neg_mode, even though it -makes no use of it or the "mode" argument. This makes the driver -consistent with converted drivers. - -Signed-off-by: Russell King (Oracle) -Link: https://lore.kernel.org/r/E1qA8Ej-00EaGR-Fk@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3225,7 +3225,7 @@ static void mt7530_pcs_get_state(struct - state->pause |= MLO_PAUSE_TX; - } - --static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode, -+static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, - const unsigned long *advertising, - bool permit_pause_to_mac) -@@ -3253,6 +3253,7 @@ mt753x_setup(struct dsa_switch *ds) - /* Initialise the PCS devices */ - for (i = 0; i < priv->ds->num_ports; i++) { - priv->pcs[i].pcs.ops = priv->info->pcs_ops; -+ priv->pcs[i].pcs.neg_mode = true; - priv->pcs[i].priv = priv; - priv->pcs[i].port = i; - } diff --git a/target/linux/generic/backport-6.1/790-18-v6.7-net-dsa-mt7530-Convert-to-platform-remove-callback-r.patch b/target/linux/generic/backport-6.1/790-18-v6.7-net-dsa-mt7530-Convert-to-platform-remove-callback-r.patch deleted file mode 100644 index ffcf51dab5eaaa..00000000000000 --- a/target/linux/generic/backport-6.1/790-18-v6.7-net-dsa-mt7530-Convert-to-platform-remove-callback-r.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 03ede98ecc29b59fb364f735d6de0e6a4c1735fc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= -Date: Mon, 18 Sep 2023 21:19:12 +0200 -Subject: [PATCH 18/48] net: dsa: mt7530: Convert to platform remove callback - returning void -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The .remove() callback for a platform driver returns an int which makes -many driver authors wrongly assume it's possible to do error handling by -returning an error code. However the value returned is ignored (apart -from emitting a warning) and this typically results in resource leaks. -To improve here there is a quest to make the remove callback return -void. In the first step of this quest all drivers are converted to -.remove_new() which already returns void. Eventually after all drivers -are converted, .remove_new() is renamed to .remove(). - -Trivially convert this driver from always returning zero in the remove -callback to the void returning variant. - -Signed-off-by: Uwe Kleine-König -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Acked-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530-mmio.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - ---- a/drivers/net/dsa/mt7530-mmio.c -+++ b/drivers/net/dsa/mt7530-mmio.c -@@ -62,15 +62,12 @@ mt7988_probe(struct platform_device *pde - return dsa_register_switch(priv->ds); - } - --static int --mt7988_remove(struct platform_device *pdev) -+static void mt7988_remove(struct platform_device *pdev) - { - struct mt7530_priv *priv = platform_get_drvdata(pdev); - - if (priv) - mt7530_remove_common(priv); -- -- return 0; - } - - static void mt7988_shutdown(struct platform_device *pdev) -@@ -87,7 +84,7 @@ static void mt7988_shutdown(struct platf - - static struct platform_driver mt7988_platform_driver = { - .probe = mt7988_probe, -- .remove = mt7988_remove, -+ .remove_new = mt7988_remove, - .shutdown = mt7988_shutdown, - .driver = { - .name = "mt7530-mmio", diff --git a/target/linux/generic/backport-6.1/790-19-v6.7-net-dsa-mt753x-remove-mt753x_phylink_pcs_link_up.patch b/target/linux/generic/backport-6.1/790-19-v6.7-net-dsa-mt753x-remove-mt753x_phylink_pcs_link_up.patch deleted file mode 100644 index d69ee7f104d11d..00000000000000 --- a/target/linux/generic/backport-6.1/790-19-v6.7-net-dsa-mt753x-remove-mt753x_phylink_pcs_link_up.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 1a1a723d47c046d6c251651c9ade589040dafacf Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Wed, 27 Sep 2023 13:13:56 +0100 -Subject: [PATCH 19/48] net: dsa: mt753x: remove mt753x_phylink_pcs_link_up() - -Remove the mt753x_phylink_pcs_link_up() function for two reasons: - -1) priv->pcs[i].pcs.neg_mode is set true, meaning it doesn't take a - MLO_AN_FIXED anymore, but one of PHYLINK_PCS_NEG_*. However, this - is inconsequential due to... -2) priv->pcs[port].pcs.ops is always initialised to point at - mt7530_pcs_ops, which does not have a pcs_link_up() member. - -So, let's remove mt753x_phylink_pcs_link_up() entirely. - -Signed-off-by: Russell King (Oracle) -Reviewed-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Link: https://lore.kernel.org/r/E1qlTQS-008BWe-Va@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 11 ----------- - 1 file changed, 11 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3040,15 +3040,6 @@ static void mt753x_phylink_mac_link_down - mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); - } - --static void mt753x_phylink_pcs_link_up(struct phylink_pcs *pcs, -- unsigned int mode, -- phy_interface_t interface, -- int speed, int duplex) --{ -- if (pcs->ops->pcs_link_up) -- pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex); --} -- - static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, - unsigned int mode, - phy_interface_t interface, -@@ -3137,8 +3128,6 @@ mt7531_cpu_port_config(struct dsa_switch - return ret; - mt7530_write(priv, MT7530_PMCR_P(port), - PMCR_CPU_PORT_SETTING(priv->id)); -- mt753x_phylink_pcs_link_up(&priv->pcs[port].pcs, MLO_AN_FIXED, -- interface, speed, DUPLEX_FULL); - mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL, - speed, DUPLEX_FULL, true, true); - diff --git a/target/linux/generic/backport-6.1/790-20-v6.7-net-dsa-mt7530-replace-deprecated-strncpy-with-ethto.patch b/target/linux/generic/backport-6.1/790-20-v6.7-net-dsa-mt7530-replace-deprecated-strncpy-with-ethto.patch deleted file mode 100644 index 8af6820270c5c3..00000000000000 --- a/target/linux/generic/backport-6.1/790-20-v6.7-net-dsa-mt7530-replace-deprecated-strncpy-with-ethto.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 51e9c79a4d40fa3a64c0fbdab1ebbebf7cce2dba Mon Sep 17 00:00:00 2001 -From: Justin Stitt -Date: Mon, 9 Oct 2023 18:29:19 +0000 -Subject: [PATCH 20/48] net: dsa: mt7530: replace deprecated strncpy with - ethtool_sprintf - -`strncpy` is deprecated for use on NUL-terminated destination strings -[1] and as such we should prefer more robust and less ambiguous string -interfaces. - -ethtool_sprintf() is designed specifically for get_strings() usage. -Let's replace strncpy in favor of this more robust and easier to -understand interface. - -Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1] -Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2] -Link: https://github.com/KSPP/linux/issues/90 -Signed-off-by: Justin Stitt -Reviewed-by: Kees Cook -Acked-by: Daniel Golle -Reviewed-by: Florian Fainelli -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20231009-strncpy-drivers-net-dsa-mt7530-c-v1-1-ec6677a6436a@google.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -843,8 +843,7 @@ mt7530_get_strings(struct dsa_switch *ds - return; - - for (i = 0; i < ARRAY_SIZE(mt7530_mib); i++) -- strncpy(data + i * ETH_GSTRING_LEN, mt7530_mib[i].name, -- ETH_GSTRING_LEN); -+ ethtool_sprintf(&data, "%s", mt7530_mib[i].name); - } - - static void diff --git a/target/linux/generic/backport-6.1/790-21-v6.9-net-dsa-mt7530-support-OF-based-registration-of-swit.patch b/target/linux/generic/backport-6.1/790-21-v6.9-net-dsa-mt7530-support-OF-based-registration-of-swit.patch deleted file mode 100644 index 4c6c0577391ee7..00000000000000 --- a/target/linux/generic/backport-6.1/790-21-v6.9-net-dsa-mt7530-support-OF-based-registration-of-swit.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 38be6fdf7e93431e91aac3884837b22236325f68 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Jan 2024 08:34:31 +0300 -Subject: [PATCH 21/48] net: dsa: mt7530: support OF-based registration of - switch MDIO bus -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently the MDIO bus of the switches the MT7530 DSA subdriver controls -can only be registered as non-OF-based. Bring support for registering the -bus OF-based. - -The subdrivers that control switches [with MDIO bus] probed on OF must -follow this logic to support all cases properly: - -No switch MDIO bus defined: Populate ds->user_mii_bus, register the MDIO -bus, set the interrupts for PHYs if "interrupt-controller" is defined at -the switch node. This case should only be covered for the switches which -their dt-bindings documentation didn't document the MDIO bus from the -start. This is to keep supporting the device trees that do not describe the -MDIO bus on the device tree but the MDIO bus is being used nonetheless. - -Switch MDIO bus defined: Don't populate ds->user_mii_bus, register the MDIO -bus, set the interrupts for PHYs if ["interrupt-controller" is defined at -the switch node and "interrupts" is defined at the PHY nodes under the -switch MDIO bus node]. - -Switch MDIO bus defined but explicitly disabled: If the device tree says -status = "disabled" for the MDIO bus, we shouldn't need an MDIO bus at all. -Instead, just exit as early as possible and do not call any MDIO API. - -The use of ds->user_mii_bus is inappropriate when the MDIO bus of the -switch is described on the device tree [1], which is why we don't populate -ds->user_mii_bus in that case. - -Link: https://lore.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/ [1] -Suggested-by: David Bauer -Signed-off-by: Arınç ÜNAL -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/20240122053431.7751-1-arinc.unal@arinc9.com -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 34 ++++++++++++++++++++++++++-------- - 1 file changed, 26 insertions(+), 8 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2350,24 +2350,40 @@ mt7530_free_irq_common(struct mt7530_pri - static void - mt7530_free_irq(struct mt7530_priv *priv) - { -- mt7530_free_mdio_irq(priv); -+ struct device_node *mnp, *np = priv->dev->of_node; -+ -+ mnp = of_get_child_by_name(np, "mdio"); -+ if (!mnp) -+ mt7530_free_mdio_irq(priv); -+ of_node_put(mnp); -+ - mt7530_free_irq_common(priv); - } - - static int - mt7530_setup_mdio(struct mt7530_priv *priv) - { -+ struct device_node *mnp, *np = priv->dev->of_node; - struct dsa_switch *ds = priv->ds; - struct device *dev = priv->dev; - struct mii_bus *bus; - static int idx; -- int ret; -+ int ret = 0; -+ -+ mnp = of_get_child_by_name(np, "mdio"); -+ -+ if (mnp && !of_device_is_available(mnp)) -+ goto out; - - bus = devm_mdiobus_alloc(dev); -- if (!bus) -- return -ENOMEM; -+ if (!bus) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ if (!mnp) -+ ds->slave_mii_bus = bus; - -- ds->slave_mii_bus = bus; - bus->priv = priv; - bus->name = KBUILD_MODNAME "-mii"; - snprintf(bus->id, MII_BUS_ID_SIZE, KBUILD_MODNAME "-%d", idx++); -@@ -2376,16 +2392,18 @@ mt7530_setup_mdio(struct mt7530_priv *pr - bus->parent = dev; - bus->phy_mask = ~ds->phys_mii_mask; - -- if (priv->irq) -+ if (priv->irq && !mnp) - mt7530_setup_mdio_irq(priv); - -- ret = devm_mdiobus_register(dev, bus); -+ ret = devm_of_mdiobus_register(dev, bus, mnp); - if (ret) { - dev_err(dev, "failed to register MDIO bus: %d\n", ret); -- if (priv->irq) -+ if (priv->irq && !mnp) - mt7530_free_mdio_irq(priv); - } - -+out: -+ of_node_put(mnp); - return ret; - } - diff --git a/target/linux/generic/backport-6.1/790-22-v6.8-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch b/target/linux/generic/backport-6.1/790-22-v6.8-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch deleted file mode 100644 index 0b141b4a3f09b0..00000000000000 --- a/target/linux/generic/backport-6.1/790-22-v6.8-net-dsa-mt7530-fix-10M-100M-speed-on-MT7988-switch.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 022a254fafce88367914dfc8168fe687fc528cdb Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 24 Jan 2024 05:17:25 +0000 -Subject: [PATCH 22/48] net: dsa: mt7530: fix 10M/100M speed on MT7988 switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Setup PMCR port register for actual speed and duplex on internally -connected PHYs of the MT7988 built-in switch. This fixes links with -speeds other than 1000M. - -Fixes: 110c18bfed41 ("net: dsa: mt7530: introduce driver for MT7988 built-in switch") -Signed-off-by: Daniel Golle -Reviewed-by: Vladimir Oltean -Acked-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/a5b04dfa8256d8302f402545a51ac4c626fdba25.1706071272.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3072,8 +3072,7 @@ static void mt753x_phylink_mac_link_up(s - /* MT753x MAC works in 1G full duplex mode for all up-clocked - * variants. - */ -- if (interface == PHY_INTERFACE_MODE_INTERNAL || -- interface == PHY_INTERFACE_MODE_TRGMII || -+ if (interface == PHY_INTERFACE_MODE_TRGMII || - (phy_interface_mode_is_8023z(interface))) { - speed = SPEED_1000; - duplex = DUPLEX_FULL; diff --git a/target/linux/generic/backport-6.1/790-23-v6.9-net-dsa-mt7530-always-trap-frames-to-active-CPU-port.patch b/target/linux/generic/backport-6.1/790-23-v6.9-net-dsa-mt7530-always-trap-frames-to-active-CPU-port.patch deleted file mode 100644 index 44d8e07c12eea1..00000000000000 --- a/target/linux/generic/backport-6.1/790-23-v6.9-net-dsa-mt7530-always-trap-frames-to-active-CPU-port.patch +++ /dev/null @@ -1,125 +0,0 @@ -From a385398f77fad9eabe7cdc253e1a356484acc316 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Jan 2024 08:35:52 +0300 -Subject: [PATCH 23/48] net: dsa: mt7530: always trap frames to active CPU port - on MT7530 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On the MT7530 switch, the CPU_PORT field indicates which CPU port to trap -frames to, regardless of the affinity of the inbound user port. - -When multiple CPU ports are in use, if the DSA conduit interface is down, -trapped frames won't be passed to the conduit interface. - -To make trapping frames work including this case, implement -ds->ops->conduit_state_change() on this subdriver and set the CPU_PORT -field to the numerically smallest CPU port whose conduit interface is up. -Introduce the active_cpu_ports field to store the information of the active -CPU ports. Correct the macros, CPU_PORT is bits 4 through 6 of the -register. - -Add a comment to explain frame trapping for this switch. - -Currently, the driver doesn't support the use of multiple CPU ports so this -is not necessarily a bug fix. - -Suggested-by: Vladimir Oltean -Suggested-by: Russell King (Oracle) -Signed-off-by: Arınç ÜNAL -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-1-042401f2b279@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 35 +++++++++++++++++++++++++++++++---- - drivers/net/dsa/mt7530.h | 6 ++++-- - 2 files changed, 35 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1239,10 +1239,6 @@ mt753x_cpu_port_enable(struct dsa_switch - mt7530_set(priv, MT7530_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) | - UNU_FFP(BIT(port))); - -- /* Set CPU port number */ -- if (priv->id == ID_MT7530 || priv->id == ID_MT7621) -- mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port)); -- - /* Add the CPU port to the CPU port bitmap for MT7531. Trapped frames - * will be forwarded to the CPU port that is affine to the inbound user - * port. -@@ -3314,6 +3310,36 @@ static int mt753x_set_mac_eee(struct dsa - return 0; - } - -+static void -+mt753x_conduit_state_change(struct dsa_switch *ds, -+ const struct net_device *conduit, -+ bool operational) -+{ -+ struct dsa_port *cpu_dp = conduit->dsa_ptr; -+ struct mt7530_priv *priv = ds->priv; -+ int val = 0; -+ u8 mask; -+ -+ /* Set the CPU port to trap frames to for MT7530. Trapped frames will be -+ * forwarded to the numerically smallest CPU port whose conduit -+ * interface is up. -+ */ -+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621) -+ return; -+ -+ mask = BIT(cpu_dp->index); -+ -+ if (operational) -+ priv->active_cpu_ports |= mask; -+ else -+ priv->active_cpu_ports &= ~mask; -+ -+ if (priv->active_cpu_ports) -+ val = CPU_EN | CPU_PORT(__ffs(priv->active_cpu_ports)); -+ -+ mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val); -+} -+ - static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface) - { - return 0; -@@ -3369,6 +3395,7 @@ const struct dsa_switch_ops mt7530_switc - .phylink_mac_link_up = mt753x_phylink_mac_link_up, - .get_mac_eee = mt753x_get_mac_eee, - .set_mac_eee = mt753x_set_mac_eee, -+ .master_state_change = mt753x_conduit_state_change, - }; - EXPORT_SYMBOL_GPL(mt7530_switch_ops); - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -45,8 +45,8 @@ enum mt753x_id { - #define UNU_FFP(x) (((x) & 0xff) << 8) - #define UNU_FFP_MASK UNU_FFP(~0) - #define CPU_EN BIT(7) --#define CPU_PORT(x) ((x) << 4) --#define CPU_MASK (0xf << 4) -+#define CPU_PORT_MASK GENMASK(6, 4) -+#define CPU_PORT(x) FIELD_PREP(CPU_PORT_MASK, x) - #define MIRROR_EN BIT(3) - #define MIRROR_PORT(x) ((x) & 0x7) - #define MIRROR_MASK 0x7 -@@ -783,6 +783,7 @@ struct mt753x_info { - * @irq_domain: IRQ domain of the switch irq_chip - * @irq_enable: IRQ enable bits, synced to SYS_INT_EN - * @create_sgmii: Pointer to function creating SGMII PCS instance(s) -+ * @active_cpu_ports: Holding the active CPU ports - */ - struct mt7530_priv { - struct device *dev; -@@ -809,6 +810,7 @@ struct mt7530_priv { - struct irq_domain *irq_domain; - u32 irq_enable; - int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii); -+ u8 active_cpu_ports; - }; - - struct mt7530_hw_vlan_entry { diff --git a/target/linux/generic/backport-6.1/790-24-v6.9-net-dsa-mt7530-use-p5_interface_select-as-data-type-.patch b/target/linux/generic/backport-6.1/790-24-v6.9-net-dsa-mt7530-use-p5_interface_select-as-data-type-.patch deleted file mode 100644 index 3454948b865113..00000000000000 --- a/target/linux/generic/backport-6.1/790-24-v6.9-net-dsa-mt7530-use-p5_interface_select-as-data-type-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From e3c8f69af69e6c4022094309445c009faf5e8cef Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Jan 2024 08:35:53 +0300 -Subject: [PATCH 24/48] net: dsa: mt7530: use p5_interface_select as data type - for p5_intf_sel -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the p5_interface_select enumeration as the data type for the -p5_intf_sel field. This ensures p5_intf_sel can only take the values -defined in the p5_interface_select enumeration. - -Remove the explicit assignment of 0 to P5_DISABLED as the first enum item -is automatically assigned 0. - -Signed-off-by: Arınç ÜNAL -Acked-by: Daniel Golle -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-2-042401f2b279@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -713,7 +713,7 @@ struct mt7530_port { - - /* Port 5 interface select definitions */ - enum p5_interface_select { -- P5_DISABLED = 0, -+ P5_DISABLED, - P5_INTF_SEL_PHY_P0, - P5_INTF_SEL_PHY_P4, - P5_INTF_SEL_GMAC5, -@@ -799,7 +799,7 @@ struct mt7530_priv { - bool mcm; - phy_interface_t p6_interface; - phy_interface_t p5_interface; -- unsigned int p5_intf_sel; -+ enum p5_interface_select p5_intf_sel; - u8 mirror_rx; - u8 mirror_tx; - struct mt7530_port ports[MT7530_NUM_PORTS]; diff --git a/target/linux/generic/backport-6.1/790-25-v6.9-net-dsa-mt7530-store-port-5-SGMII-capability-of-MT75.patch b/target/linux/generic/backport-6.1/790-25-v6.9-net-dsa-mt7530-store-port-5-SGMII-capability-of-MT75.patch deleted file mode 100644 index 357579e2bdf1b3..00000000000000 --- a/target/linux/generic/backport-6.1/790-25-v6.9-net-dsa-mt7530-store-port-5-SGMII-capability-of-MT75.patch +++ /dev/null @@ -1,227 +0,0 @@ -From b0d590a5cdd95ed863717b279751d6166083889f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Jan 2024 08:35:54 +0300 -Subject: [PATCH 25/48] net: dsa: mt7530: store port 5 SGMII capability of - MT7531 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Introduce the p5_sgmii field to store the information for whether port 5 -has got SGMII or not. Instead of reading the MT7531_TOP_SIG_SR register -multiple times, the register will be read once and the value will be -stored on the p5_sgmii field. This saves unnecessary reads of the -register. - -Move the comment about MT7531AE and MT7531BE to mt7531_setup(), where the -switch is identified. - -Get rid of mt7531_dual_sgmii_supported() now that priv->p5_sgmii stores the -information. Address the code where mt7531_dual_sgmii_supported() is used. - -Get rid of mt7531_is_rgmii_port() which just prints the opposite of -priv->p5_sgmii. - -Instead of calling mt7531_pll_setup() then returning, do not call it if -port 5 is SGMII. - -Remove P5_INTF_SEL_GMAC5_SGMII. The p5_interface_select enum is supposed to -represent the mode that port 5 is being used in, not the hardware -information of port 5. Set p5_intf_sel to P5_INTF_SEL_GMAC5 instead, if -port 5 is not dsa_is_unused_port(). - -Signed-off-by: Arınç ÜNAL -Acked-by: Daniel Golle -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-3-042401f2b279@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530-mdio.c | 7 ++--- - drivers/net/dsa/mt7530.c | 48 ++++++++++++----------------------- - drivers/net/dsa/mt7530.h | 6 +++-- - 3 files changed, 22 insertions(+), 39 deletions(-) - ---- a/drivers/net/dsa/mt7530-mdio.c -+++ b/drivers/net/dsa/mt7530-mdio.c -@@ -81,17 +81,14 @@ static const struct regmap_bus mt7530_re - }; - - static int --mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii) -+mt7531_create_sgmii(struct mt7530_priv *priv) - { - struct regmap_config *mt7531_pcs_config[2] = {}; - struct phylink_pcs *pcs; - struct regmap *regmap; - int i, ret = 0; - -- /* MT7531AE has two SGMII units for port 5 and port 6 -- * MT7531BE has only one SGMII unit for port 6 -- */ -- for (i = dual_sgmii ? 0 : 1; i < 2; i++) { -+ for (i = priv->p5_sgmii ? 0 : 1; i < 2; i++) { - mt7531_pcs_config[i] = devm_kzalloc(priv->dev, - sizeof(struct regmap_config), - GFP_KERNEL); ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -487,15 +487,6 @@ mt7530_pad_clk_setup(struct dsa_switch * - return 0; - } - --static bool mt7531_dual_sgmii_supported(struct mt7530_priv *priv) --{ -- u32 val; -- -- val = mt7530_read(priv, MT7531_TOP_SIG_SR); -- -- return (val & PAD_DUAL_SGMII_EN) != 0; --} -- - static int - mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface) - { -@@ -510,9 +501,6 @@ mt7531_pll_setup(struct mt7530_priv *pri - u32 xtal; - u32 val; - -- if (mt7531_dual_sgmii_supported(priv)) -- return; -- - val = mt7530_read(priv, MT7531_CREV); - top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR); - hwstrap = mt7530_read(priv, MT7531_HWTRAP); -@@ -927,8 +915,6 @@ static const char *p5_intf_modes(unsigne - return "PHY P4"; - case P5_INTF_SEL_GMAC5: - return "GMAC5"; -- case P5_INTF_SEL_GMAC5_SGMII: -- return "GMAC5_SGMII"; - default: - return "unknown"; - } -@@ -2697,6 +2683,12 @@ mt7531_setup(struct dsa_switch *ds) - return -ENODEV; - } - -+ /* MT7531AE has got two SGMII units. One for port 5, one for port 6. -+ * MT7531BE has got only one SGMII unit which is for port 6. -+ */ -+ val = mt7530_read(priv, MT7531_TOP_SIG_SR); -+ priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN); -+ - /* all MACs must be forced link-down before sw reset */ - for (i = 0; i < MT7530_NUM_PORTS; i++) - mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK); -@@ -2706,21 +2698,18 @@ mt7531_setup(struct dsa_switch *ds) - SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST | - SYS_CTRL_REG_RST); - -- mt7531_pll_setup(priv); -- -- if (mt7531_dual_sgmii_supported(priv)) { -- priv->p5_intf_sel = P5_INTF_SEL_GMAC5_SGMII; -- -+ if (!priv->p5_sgmii) { -+ mt7531_pll_setup(priv); -+ } else { - /* Let ds->slave_mii_bus be able to access external phy. */ - mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK, - MT7531_EXT_P_MDC_11); - mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK, - MT7531_EXT_P_MDIO_12); -- } else { -- priv->p5_intf_sel = P5_INTF_SEL_GMAC5; - } -- dev_dbg(ds->dev, "P5 support %s interface\n", -- p5_intf_modes(priv->p5_intf_sel)); -+ -+ if (!dsa_is_unused_port(ds, 5)) -+ priv->p5_intf_sel = P5_INTF_SEL_GMAC5; - - mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK, - MT7531_GPIO0_INTERRUPT); -@@ -2787,11 +2776,6 @@ static void mt7530_mac_port_get_caps(str - } - } - --static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port) --{ -- return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII); --} -- - static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port, - struct phylink_config *config) - { -@@ -2804,7 +2788,7 @@ static void mt7531_mac_port_get_caps(str - break; - - case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */ -- if (mt7531_is_rgmii_port(priv, port)) { -+ if (!priv->p5_sgmii) { - phy_interface_set_rgmii(config->supported_interfaces); - break; - } -@@ -2871,7 +2855,7 @@ static int mt7531_rgmii_setup(struct mt7 - { - u32 val; - -- if (!mt7531_is_rgmii_port(priv, port)) { -+ if (priv->p5_sgmii) { - dev_err(priv->dev, "RGMII mode is not available for port %d\n", - port); - return -EINVAL; -@@ -3114,7 +3098,7 @@ mt7531_cpu_port_config(struct dsa_switch - - switch (port) { - case 5: -- if (mt7531_is_rgmii_port(priv, port)) -+ if (!priv->p5_sgmii) - interface = PHY_INTERFACE_MODE_RGMII; - else - interface = PHY_INTERFACE_MODE_2500BASEX; -@@ -3272,7 +3256,7 @@ mt753x_setup(struct dsa_switch *ds) - mt7530_free_irq_common(priv); - - if (priv->create_sgmii) { -- ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv)); -+ ret = priv->create_sgmii(priv); - if (ret && priv->irq) - mt7530_free_irq(priv); - } ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -717,7 +717,6 @@ enum p5_interface_select { - P5_INTF_SEL_PHY_P0, - P5_INTF_SEL_PHY_P4, - P5_INTF_SEL_GMAC5, -- P5_INTF_SEL_GMAC5_SGMII, - }; - - struct mt7530_priv; -@@ -779,6 +778,8 @@ struct mt753x_info { - * registers - * @p6_interface Holding the current port 6 interface - * @p5_intf_sel: Holding the current port 5 interface select -+ * @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch -+ * has got SGMII - * @irq: IRQ number of the switch - * @irq_domain: IRQ domain of the switch irq_chip - * @irq_enable: IRQ enable bits, synced to SYS_INT_EN -@@ -800,6 +801,7 @@ struct mt7530_priv { - phy_interface_t p6_interface; - phy_interface_t p5_interface; - enum p5_interface_select p5_intf_sel; -+ bool p5_sgmii; - u8 mirror_rx; - u8 mirror_tx; - struct mt7530_port ports[MT7530_NUM_PORTS]; -@@ -809,7 +811,7 @@ struct mt7530_priv { - int irq; - struct irq_domain *irq_domain; - u32 irq_enable; -- int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii); -+ int (*create_sgmii)(struct mt7530_priv *priv); - u8 active_cpu_ports; - }; - diff --git a/target/linux/generic/backport-6.1/790-26-v6.9-net-dsa-mt7530-improve-comments-regarding-switch-por.patch b/target/linux/generic/backport-6.1/790-26-v6.9-net-dsa-mt7530-improve-comments-regarding-switch-por.patch deleted file mode 100644 index 46dbd53ede48db..00000000000000 --- a/target/linux/generic/backport-6.1/790-26-v6.9-net-dsa-mt7530-improve-comments-regarding-switch-por.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 0dcde4c1e7c47822a6b00d6f96b7f19e51536026 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Jan 2024 08:35:55 +0300 -Subject: [PATCH 26/48] net: dsa: mt7530: improve comments regarding switch - ports -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There's no logic to numerically order the CPU ports. Just state the port -number instead. - -Remove the irrelevant PHY muxing information from -mt7530_mac_port_get_caps(). Explain the supported MII modes instead. - -Remove the out of place PHY muxing information from -mt753x_phylink_mac_config(). The function is for MT7530, MT7531, and the -switch on the MT7988 SoC but there's no PHY muxing on MT7531 or the switch -on the MT7988 SoC. - -These comments were gradually introduced with the commits below. -commit ca366d6c889b ("net: dsa: mt7530: Convert to PHYLINK API") -commit 38f790a80560 ("net: dsa: mt7530: Add support for port 5") -commit 88bdef8be9f6 ("net: dsa: mt7530: Extend device data ready for adding -a new hardware") -commit c288575f7810 ("net: dsa: mt7530: Add the support of MT7531 switch") - -Signed-off-by: Arınç ÜNAL -Acked-by: Daniel Golle -Reviewed-by: Andrew Lunn -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-4-042401f2b279@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 30 ++++++++++++++++++++---------- - 1 file changed, 20 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2754,12 +2754,14 @@ static void mt7530_mac_port_get_caps(str - struct phylink_config *config) - { - switch (port) { -- case 0 ... 4: /* Internal phy */ -+ /* Ports which are connected to switch PHYs. There is no MII pinout. */ -+ case 0 ... 4: - __set_bit(PHY_INTERFACE_MODE_GMII, - config->supported_interfaces); - break; - -- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -+ /* Port 5 supports rgmii with delays, mii, and gmii. */ -+ case 5: - phy_interface_set_rgmii(config->supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_MII, - config->supported_interfaces); -@@ -2767,7 +2769,8 @@ static void mt7530_mac_port_get_caps(str - config->supported_interfaces); - break; - -- case 6: /* 1st cpu port */ -+ /* Port 6 supports rgmii and trgmii. */ -+ case 6: - __set_bit(PHY_INTERFACE_MODE_RGMII, - config->supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_TRGMII, -@@ -2782,19 +2785,24 @@ static void mt7531_mac_port_get_caps(str - struct mt7530_priv *priv = ds->priv; - - switch (port) { -- case 0 ... 4: /* Internal phy */ -+ /* Ports which are connected to switch PHYs. There is no MII pinout. */ -+ case 0 ... 4: - __set_bit(PHY_INTERFACE_MODE_GMII, - config->supported_interfaces); - break; - -- case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */ -+ /* Port 5 supports rgmii with delays on MT7531BE, sgmii/802.3z on -+ * MT7531AE. -+ */ -+ case 5: - if (!priv->p5_sgmii) { - phy_interface_set_rgmii(config->supported_interfaces); - break; - } - fallthrough; - -- case 6: /* 1st cpu port supports sgmii/8023z only */ -+ /* Port 6 supports sgmii/802.3z. */ -+ case 6: - __set_bit(PHY_INTERFACE_MODE_SGMII, - config->supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_1000BASEX, -@@ -2813,11 +2821,13 @@ static void mt7988_mac_port_get_caps(str - phy_interface_zero(config->supported_interfaces); - - switch (port) { -- case 0 ... 4: /* Internal phy */ -+ /* Ports which are connected to switch PHYs. There is no MII pinout. */ -+ case 0 ... 4: - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - config->supported_interfaces); - break; - -+ /* Port 6 is connected to SoC's XGMII MAC. There is no MII pinout. */ - case 6: - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - config->supported_interfaces); -@@ -2981,12 +2991,12 @@ mt753x_phylink_mac_config(struct dsa_swi - u32 mcr_cur, mcr_new; - - switch (port) { -- case 0 ... 4: /* Internal phy */ -+ case 0 ... 4: - if (state->interface != PHY_INTERFACE_MODE_GMII && - state->interface != PHY_INTERFACE_MODE_INTERNAL) - goto unsupported; - break; -- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */ -+ case 5: - if (priv->p5_interface == state->interface) - break; - -@@ -2996,7 +3006,7 @@ mt753x_phylink_mac_config(struct dsa_swi - if (priv->p5_intf_sel != P5_DISABLED) - priv->p5_interface = state->interface; - break; -- case 6: /* 1st cpu port */ -+ case 6: - if (priv->p6_interface == state->interface) - break; - diff --git a/target/linux/generic/backport-6.1/790-27-v6.9-net-dsa-mt7530-improve-code-path-for-setting-up-port.patch b/target/linux/generic/backport-6.1/790-27-v6.9-net-dsa-mt7530-improve-code-path-for-setting-up-port.patch deleted file mode 100644 index 43f629b2431d1c..00000000000000 --- a/target/linux/generic/backport-6.1/790-27-v6.9-net-dsa-mt7530-improve-code-path-for-setting-up-port.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0f03d9bfa1da1d26cb950e4b35b1ff7b9be1828f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Jan 2024 08:35:56 +0300 -Subject: [PATCH 27/48] net: dsa: mt7530: improve code path for setting up port - 5 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There're two code paths for setting up port 5: - -mt7530_setup() --> mt7530_setup_port5() - -mt753x_phylink_mac_config() --> mt753x_mac_config() - -> mt7530_mac_config() - -> mt7530_setup_port5() - -Currently mt7530_setup_port5() from mt7530_setup() always runs. If port 5 -is used as a CPU, DSA, or user port, mt7530_setup_port5() from -mt753x_phylink_mac_config() won't run. That is because priv->p5_interface -set on mt7530_setup_port5() will match state->interface on -mt753x_phylink_mac_config() which will stop running mt7530_setup_port5() -again. - -Therefore, mt7530_setup_port5() will never run from -mt753x_phylink_mac_config(). - -Address this by not running mt7530_setup_port5() from mt7530_setup() if -port 5 is used as a CPU, DSA, or user port. This driver isn't in the -dsa_switches_apply_workarounds[] array so phylink will always be present. - -To keep the cases where port 5 isn't controlled by phylink working as -before, preserve the mt7530_setup_port5() call from mt7530_setup(). - -Do not set priv->p5_intf_sel to P5_DISABLED. It is already set to that when -"priv" is allocated. - -Move setting the interface to a more specific location. It's supposed to be -overwritten if PHY muxing is detected. - -Improve the comment which explains the process. - -Signed-off-by: Arınç ÜNAL -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-5-042401f2b279@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 17 ++++++++--------- - 1 file changed, 8 insertions(+), 9 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2532,16 +2532,15 @@ mt7530_setup(struct dsa_switch *ds) - return ret; - - /* Setup port 5 */ -- priv->p5_intf_sel = P5_DISABLED; -- interface = PHY_INTERFACE_MODE_NA; -- - if (!dsa_is_unused_port(ds, 5)) { - priv->p5_intf_sel = P5_INTF_SEL_GMAC5; -- ret = of_get_phy_mode(dsa_to_port(ds, 5)->dn, &interface); -- if (ret && ret != -ENODEV) -- return ret; - } else { -- /* Scan the ethernet nodes. look for GMAC1, lookup used phy */ -+ /* Scan the ethernet nodes. Look for GMAC1, lookup the used PHY. -+ * Set priv->p5_intf_sel to the appropriate value if PHY muxing -+ * is detected. -+ */ -+ interface = PHY_INTERFACE_MODE_NA; -+ - for_each_child_of_node(dn, mac_np) { - if (!of_device_is_compatible(mac_np, - "mediatek,eth-mac")) -@@ -2572,6 +2571,8 @@ mt7530_setup(struct dsa_switch *ds) - of_node_put(phy_node); - break; - } -+ -+ mt7530_setup_port5(ds, interface); - } - - #ifdef CONFIG_GPIOLIB -@@ -2582,8 +2583,6 @@ mt7530_setup(struct dsa_switch *ds) - } - #endif /* CONFIG_GPIOLIB */ - -- mt7530_setup_port5(ds, interface); -- - /* Flush the FDB table */ - ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL); - if (ret < 0) diff --git a/target/linux/generic/backport-6.1/790-28-v6.9-net-dsa-mt7530-do-not-set-priv-p5_interface-on-mt753.patch b/target/linux/generic/backport-6.1/790-28-v6.9-net-dsa-mt7530-do-not-set-priv-p5_interface-on-mt753.patch deleted file mode 100644 index 385d587729ee02..00000000000000 --- a/target/linux/generic/backport-6.1/790-28-v6.9-net-dsa-mt7530-do-not-set-priv-p5_interface-on-mt753.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 120581c81ad19704a9325505c83a82b7e760e96e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Jan 2024 08:35:57 +0300 -Subject: [PATCH 28/48] net: dsa: mt7530: do not set priv->p5_interface on - mt7530_setup_port5() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Running mt7530_setup_port5() from mt7530_setup() used to handle all cases -of configuring port 5, including phylink. - -Setting priv->p5_interface under mt7530_setup_port5() makes sure that -mt7530_setup_port5() from mt753x_phylink_mac_config() won't run. - -The commit ("net: dsa: mt7530: improve code path for setting up port 5") -makes so that mt7530_setup_port5() from mt7530_setup() runs only on -non-phylink cases. - -Get rid of unnecessarily setting priv->p5_interface under -mt7530_setup_port5() as port 5 phylink configuration will be done by -running mt7530_setup_port5() from mt753x_phylink_mac_config() now. - -Signed-off-by: Arınç ÜNAL -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-6-042401f2b279@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -985,8 +985,6 @@ static void mt7530_setup_port5(struct ds - dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n", - val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface)); - -- priv->p5_interface = interface; -- - unlock_exit: - mutex_unlock(&priv->reg_mutex); - } diff --git a/target/linux/generic/backport-6.1/790-29-v6.9-net-dsa-mt7530-do-not-run-mt7530_setup_port5-if-port.patch b/target/linux/generic/backport-6.1/790-29-v6.9-net-dsa-mt7530-do-not-run-mt7530_setup_port5-if-port.patch deleted file mode 100644 index b4c0b75c49c7f0..00000000000000 --- a/target/linux/generic/backport-6.1/790-29-v6.9-net-dsa-mt7530-do-not-run-mt7530_setup_port5-if-port.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 3b423061eb3a62e59b57939ae1e1234756a0f6a1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Jan 2024 08:35:58 +0300 -Subject: [PATCH 29/48] net: dsa: mt7530: do not run mt7530_setup_port5() if - port 5 is disabled -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There's no need to run all the code on mt7530_setup_port5() if port 5 is -disabled. The only case for calling mt7530_setup_port5() from -mt7530_setup() is when PHY muxing is enabled. That is because port 5 is not -defined as a port on the devicetree, therefore, it cannot be controlled by -phylink. - -Because of this, run mt7530_setup_port5() if priv->p5_intf_sel is -P5_INTF_SEL_PHY_P0 or P5_INTF_SEL_PHY_P4. Remove the P5_DISABLED case from -mt7530_setup_port5(). - -Stop initialising the interface variable as the remaining cases will always -call mt7530_setup_port5() with it initialised. - -Signed-off-by: Arınç ÜNAL -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/20240122-for-netnext-mt7530-improvements-1-v3-7-042401f2b279@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -949,9 +949,6 @@ static void mt7530_setup_port5(struct ds - /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */ - val &= ~MHWTRAP_P5_DIS; - break; -- case P5_DISABLED: -- interface = PHY_INTERFACE_MODE_NA; -- break; - default: - dev_err(ds->dev, "Unsupported p5_intf_sel %d\n", - priv->p5_intf_sel); -@@ -2537,8 +2534,6 @@ mt7530_setup(struct dsa_switch *ds) - * Set priv->p5_intf_sel to the appropriate value if PHY muxing - * is detected. - */ -- interface = PHY_INTERFACE_MODE_NA; -- - for_each_child_of_node(dn, mac_np) { - if (!of_device_is_compatible(mac_np, - "mediatek,eth-mac")) -@@ -2570,7 +2565,9 @@ mt7530_setup(struct dsa_switch *ds) - break; - } - -- mt7530_setup_port5(ds, interface); -+ if (priv->p5_intf_sel == P5_INTF_SEL_PHY_P0 || -+ priv->p5_intf_sel == P5_INTF_SEL_PHY_P4) -+ mt7530_setup_port5(ds, interface); - } - - #ifdef CONFIG_GPIOLIB diff --git a/target/linux/generic/backport-6.1/790-30-v6.9-net-dsa-mt7530-empty-default-case-on-mt7530_setup_po.patch b/target/linux/generic/backport-6.1/790-30-v6.9-net-dsa-mt7530-empty-default-case-on-mt7530_setup_po.patch deleted file mode 100644 index 89527e2b39a3b2..00000000000000 --- a/target/linux/generic/backport-6.1/790-30-v6.9-net-dsa-mt7530-empty-default-case-on-mt7530_setup_po.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 959f4ac4940bebb84bdd25ac61470b3965e1e475 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Tue, 6 Feb 2024 01:08:02 +0300 -Subject: [PATCH 30/48] net: dsa: mt7530: empty default case on - mt7530_setup_port5() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There're two code paths for setting up port 5: - -mt7530_setup() --> mt7530_setup_port5() - -mt753x_phylink_mac_config() --> mt753x_mac_config() - -> mt7530_mac_config() - -> mt7530_setup_port5() - -On the first code path, priv->p5_intf_sel is either set to -P5_INTF_SEL_PHY_P0 or P5_INTF_SEL_PHY_P4 when mt7530_setup_port5() is run. - -On the second code path, priv->p5_intf_sel is set to P5_INTF_SEL_GMAC5 when -mt7530_setup_port5() is run. - -Empty the default case which will never run but is needed nonetheless to -handle all the remaining enumeration values. - -Reviewed-by: Vladimir Oltean -Reviewed-by: Russell King (Oracle) -Signed-off-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-1-d7d92a185cb1@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -950,9 +950,7 @@ static void mt7530_setup_port5(struct ds - val &= ~MHWTRAP_P5_DIS; - break; - default: -- dev_err(ds->dev, "Unsupported p5_intf_sel %d\n", -- priv->p5_intf_sel); -- goto unlock_exit; -+ break; - } - - /* Setup RGMII settings */ -@@ -982,7 +980,6 @@ static void mt7530_setup_port5(struct ds - dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n", - val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface)); - --unlock_exit: - mutex_unlock(&priv->reg_mutex); - } - diff --git a/target/linux/generic/backport-6.1/790-31-v6.9-net-dsa-mt7530-move-XTAL-check-to-mt7530_setup.patch b/target/linux/generic/backport-6.1/790-31-v6.9-net-dsa-mt7530-move-XTAL-check-to-mt7530_setup.patch deleted file mode 100644 index 0dc4baf0c76af4..00000000000000 --- a/target/linux/generic/backport-6.1/790-31-v6.9-net-dsa-mt7530-move-XTAL-check-to-mt7530_setup.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 9ec0a800c8e0850e1358b7402d6af557af81cb38 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Tue, 6 Feb 2024 01:08:03 +0300 -Subject: [PATCH 31/48] net: dsa: mt7530: move XTAL check to mt7530_setup() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The crystal frequency concerns the switch core. The frequency should be -checked when the switch is being set up so the driver can reject the -unsupported hardware earlier and without requiring port 6 to be used. - -Move it to mt7530_setup(). Drop the unnecessary function printing. - -Reviewed-by: Andrew Lunn -Reviewed-by: Vladimir Oltean -Reviewed-by: Russell King (Oracle) -Signed-off-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-2-d7d92a185cb1@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -422,13 +422,6 @@ mt7530_pad_clk_setup(struct dsa_switch * - - xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK; - -- if (xtal == HWTRAP_XTAL_20MHZ) { -- dev_err(priv->dev, -- "%s: MT7530 with a 20MHz XTAL is not supported!\n", -- __func__); -- return -EINVAL; -- } -- - switch (interface) { - case PHY_INTERFACE_MODE_RGMII: - trgint = 0; -@@ -2461,6 +2454,12 @@ mt7530_setup(struct dsa_switch *ds) - return -ENODEV; - } - -+ if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_20MHZ) { -+ dev_err(priv->dev, -+ "MT7530 with a 20MHz XTAL is not supported!\n"); -+ return -EINVAL; -+ } -+ - /* Reset the switch through internal reset */ - mt7530_write(priv, MT7530_SYS_CTRL, - SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST | diff --git a/target/linux/generic/backport-6.1/790-32-v6.9-net-dsa-mt7530-simplify-mt7530_pad_clk_setup.patch b/target/linux/generic/backport-6.1/790-32-v6.9-net-dsa-mt7530-simplify-mt7530_pad_clk_setup.patch deleted file mode 100644 index 46e1b50f246e6c..00000000000000 --- a/target/linux/generic/backport-6.1/790-32-v6.9-net-dsa-mt7530-simplify-mt7530_pad_clk_setup.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 7199c736aa8cd9c69ae681a9c733408372c2ce76 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Tue, 6 Feb 2024 01:08:04 +0300 -Subject: [PATCH 32/48] net: dsa: mt7530: simplify mt7530_pad_clk_setup() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This code is from before this driver was converted to phylink API. Phylink -deals with the unsupported interface cases before mt7530_pad_clk_setup() is -run. Therefore, the default case would never run. However, it must be -defined nonetheless to handle all the remaining enumeration values, the -phy-modes. - -Switch to if statement for RGMII and return which simplifies the code and -saves an indent. - -Set P6_INTF_MODE, which is the three least significant bits of the -MT7530_P6ECR register, to 0 for RGMII even though it will already be 0 -after reset. This is to keep supporting dynamic reconfiguration of the port -in the case the interface changes from TRGMII to RGMII. - -Disable the TRGMII clocks for all cases. They will be enabled if TRGMII is -being used. - -Read XTAL after checking for RGMII as it's only needed for the TRGMII -interface mode. - -Reviewed-by: Daniel Golle -Reviewed-by: Russell King (Oracle) -Signed-off-by: Arınç ÜNAL -Reviewed-by: Vladimir Oltean -Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-3-d7d92a185cb1@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 91 ++++++++++++++++++---------------------- - 1 file changed, 40 insertions(+), 51 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -418,65 +418,54 @@ static int - mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface) - { - struct mt7530_priv *priv = ds->priv; -- u32 ncpo1, ssc_delta, trgint, xtal; -+ u32 ncpo1, ssc_delta, xtal; - -- xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK; -+ /* Disable the MT7530 TRGMII clocks */ -+ core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN); - -- switch (interface) { -- case PHY_INTERFACE_MODE_RGMII: -- trgint = 0; -- break; -- case PHY_INTERFACE_MODE_TRGMII: -- trgint = 1; -- if (xtal == HWTRAP_XTAL_25MHZ) -- ssc_delta = 0x57; -- else -- ssc_delta = 0x87; -- if (priv->id == ID_MT7621) { -- /* PLL frequency: 125MHz: 1.0GBit */ -- if (xtal == HWTRAP_XTAL_40MHZ) -- ncpo1 = 0x0640; -- if (xtal == HWTRAP_XTAL_25MHZ) -- ncpo1 = 0x0a00; -- } else { /* PLL frequency: 250MHz: 2.0Gbit */ -- if (xtal == HWTRAP_XTAL_40MHZ) -- ncpo1 = 0x0c80; -- if (xtal == HWTRAP_XTAL_25MHZ) -- ncpo1 = 0x1400; -- } -- break; -- default: -- dev_err(priv->dev, "xMII interface %d not supported\n", -- interface); -- return -EINVAL; -+ if (interface == PHY_INTERFACE_MODE_RGMII) { -+ mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, -+ P6_INTF_MODE(0)); -+ return 0; - } - -- mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, -- P6_INTF_MODE(trgint)); -+ mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1)); - -- if (trgint) { -- /* Disable the MT7530 TRGMII clocks */ -- core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN); -- -- /* Setup the MT7530 TRGMII Tx Clock */ -- core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1)); -- core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0)); -- core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta)); -- core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta)); -- core_write(priv, CORE_PLL_GROUP4, -- RG_SYSPLL_DDSFBK_EN | RG_SYSPLL_BIAS_EN | -- RG_SYSPLL_BIAS_LPF_EN); -- core_write(priv, CORE_PLL_GROUP2, -- RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN | -- RG_SYSPLL_POSDIV(1)); -- core_write(priv, CORE_PLL_GROUP7, -- RG_LCDDS_PCW_NCPO_CHG | RG_LCCDS_C(3) | -- RG_LCDDS_PWDB | RG_LCDDS_ISO_EN); -+ xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK; - -- /* Enable the MT7530 TRGMII clocks */ -- core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN); -+ if (xtal == HWTRAP_XTAL_25MHZ) -+ ssc_delta = 0x57; -+ else -+ ssc_delta = 0x87; -+ -+ if (priv->id == ID_MT7621) { -+ /* PLL frequency: 125MHz: 1.0GBit */ -+ if (xtal == HWTRAP_XTAL_40MHZ) -+ ncpo1 = 0x0640; -+ if (xtal == HWTRAP_XTAL_25MHZ) -+ ncpo1 = 0x0a00; -+ } else { /* PLL frequency: 250MHz: 2.0Gbit */ -+ if (xtal == HWTRAP_XTAL_40MHZ) -+ ncpo1 = 0x0c80; -+ if (xtal == HWTRAP_XTAL_25MHZ) -+ ncpo1 = 0x1400; - } - -+ /* Setup the MT7530 TRGMII Tx Clock */ -+ core_write(priv, CORE_PLL_GROUP5, RG_LCDDS_PCW_NCPO1(ncpo1)); -+ core_write(priv, CORE_PLL_GROUP6, RG_LCDDS_PCW_NCPO0(0)); -+ core_write(priv, CORE_PLL_GROUP10, RG_LCDDS_SSC_DELTA(ssc_delta)); -+ core_write(priv, CORE_PLL_GROUP11, RG_LCDDS_SSC_DELTA1(ssc_delta)); -+ core_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN | -+ RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN); -+ core_write(priv, CORE_PLL_GROUP2, RG_SYSPLL_EN_NORMAL | -+ RG_SYSPLL_VODEN | RG_SYSPLL_POSDIV(1)); -+ core_write(priv, CORE_PLL_GROUP7, RG_LCDDS_PCW_NCPO_CHG | -+ RG_LCCDS_C(3) | RG_LCDDS_PWDB | RG_LCDDS_ISO_EN); -+ -+ /* Enable the MT7530 TRGMII clocks */ -+ core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN); -+ - return 0; - } - diff --git a/target/linux/generic/backport-6.1/790-33-v6.9-net-dsa-mt7530-call-port-6-setup-from-mt7530_mac_con.patch b/target/linux/generic/backport-6.1/790-33-v6.9-net-dsa-mt7530-call-port-6-setup-from-mt7530_mac_con.patch deleted file mode 100644 index 7d78b7df70ec52..00000000000000 --- a/target/linux/generic/backport-6.1/790-33-v6.9-net-dsa-mt7530-call-port-6-setup-from-mt7530_mac_con.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 921a7deee767aa157b5372863a4c1cac53e5c53a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Tue, 6 Feb 2024 01:08:05 +0300 -Subject: [PATCH 33/48] net: dsa: mt7530: call port 6 setup from - mt7530_mac_config() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mt7530_pad_clk_setup() is called if port 6 is enabled. It used to do more -things than setting up port 6. That part was moved to more appropriate -locations, mt7530_setup() and mt7530_pll_setup(). - -Now that all it does is set up port 6, rename it to mt7530_setup_port6(), -and move it to a more appropriate location, under mt7530_mac_config(). - -Change mt7530_setup_port6() to void as there're no error cases. - -Leave an empty mt7530_pad_clk_setup() to satisfy the pad_setup function -pointer. - -This is the code path for setting up the ports before: - -dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config() --> mt753x_mac_config() - -> mt753x_info :: mac_port_config() -> mt7530_mac_config() - -> mt7530_setup_port5() --> mt753x_pad_setup() - -> mt753x_info :: pad_setup() -> mt7530_pad_clk_setup() - -This is after: - -dsa_switch_ops :: phylink_mac_config() -> mt753x_phylink_mac_config() --> mt753x_mac_config() - -> mt753x_info :: mac_port_config() -> mt7530_mac_config() - -> mt7530_setup_port5() - -> mt7530_setup_port6() - -Reviewed-by: Vladimir Oltean -Reviewed-by: Russell King (Oracle) -Signed-off-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-4-d7d92a185cb1@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -414,8 +414,8 @@ mt753x_preferred_default_local_cpu_port( - } - - /* Setup port 6 interface mode and TRGMII TX circuit */ --static int --mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface) -+static void -+mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface) - { - struct mt7530_priv *priv = ds->priv; - u32 ncpo1, ssc_delta, xtal; -@@ -426,7 +426,7 @@ mt7530_pad_clk_setup(struct dsa_switch * - if (interface == PHY_INTERFACE_MODE_RGMII) { - mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, - P6_INTF_MODE(0)); -- return 0; -+ return; - } - - mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1)); -@@ -465,7 +465,11 @@ mt7530_pad_clk_setup(struct dsa_switch * - - /* Enable the MT7530 TRGMII clocks */ - core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN); -+} - -+static int -+mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface) -+{ - return 0; - } - -@@ -2829,11 +2833,10 @@ mt7530_mac_config(struct dsa_switch *ds, - { - struct mt7530_priv *priv = ds->priv; - -- /* Only need to setup port5. */ -- if (port != 5) -- return 0; -- -- mt7530_setup_port5(priv->ds, interface); -+ if (port == 5) -+ mt7530_setup_port5(priv->ds, interface); -+ else if (port == 6) -+ mt7530_setup_port6(priv->ds, interface); - - return 0; - } diff --git a/target/linux/generic/backport-6.1/790-34-v6.9-net-dsa-mt7530-remove-pad_setup-function-pointer.patch b/target/linux/generic/backport-6.1/790-34-v6.9-net-dsa-mt7530-remove-pad_setup-function-pointer.patch deleted file mode 100644 index 725830e769d61a..00000000000000 --- a/target/linux/generic/backport-6.1/790-34-v6.9-net-dsa-mt7530-remove-pad_setup-function-pointer.patch +++ /dev/null @@ -1,148 +0,0 @@ -From fcbc5d900fa53f79963fe4626069739ee5567b4b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Tue, 6 Feb 2024 01:08:06 +0300 -Subject: [PATCH 34/48] net: dsa: mt7530: remove pad_setup function pointer -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The pad_setup function pointer was introduced with 88bdef8be9f6 ("net: dsa: -mt7530: Extend device data ready for adding a new hardware"). It was being -used to set up the core clock and port 6 of the MT7530 switch, and pll of -the MT7531 switch. - -All of these were moved to more appropriate locations, and it was never -used for the switch on the MT7988 SoC. Therefore, this function pointer -hasn't got a use anymore. Remove it. - -Acked-by: Daniel Golle -Reviewed-by: Vladimir Oltean -Reviewed-by: Russell King (Oracle) -Signed-off-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-5-d7d92a185cb1@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 36 ++---------------------------------- - drivers/net/dsa/mt7530.h | 3 --- - 2 files changed, 2 insertions(+), 37 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -467,18 +467,6 @@ mt7530_setup_port6(struct dsa_switch *ds - core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_TRGMIICK_EN); - } - --static int --mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface) --{ -- return 0; --} -- --static int --mt7531_pad_setup(struct dsa_switch *ds, phy_interface_t interface) --{ -- return 0; --} -- - static void - mt7531_pll_setup(struct mt7530_priv *priv) - { -@@ -2820,14 +2808,6 @@ static void mt7988_mac_port_get_caps(str - } - - static int --mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state) --{ -- struct mt7530_priv *priv = ds->priv; -- -- return priv->info->pad_setup(ds, state->interface); --} -- --static int - mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - phy_interface_t interface) - { -@@ -2992,8 +2972,6 @@ mt753x_phylink_mac_config(struct dsa_swi - if (priv->p6_interface == state->interface) - break; - -- mt753x_pad_setup(ds, state); -- - if (mt753x_mac_config(ds, port, mode, state) < 0) - goto unsupported; - -@@ -3316,11 +3294,6 @@ mt753x_conduit_state_change(struct dsa_s - mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val); - } - --static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface) --{ -- return 0; --} -- - static int mt7988_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; -@@ -3382,7 +3355,6 @@ const struct mt753x_info mt753x_table[] - .sw_setup = mt7530_setup, - .phy_read = mt7530_phy_read, - .phy_write = mt7530_phy_write, -- .pad_setup = mt7530_pad_clk_setup, - .mac_port_get_caps = mt7530_mac_port_get_caps, - .mac_port_config = mt7530_mac_config, - }, -@@ -3392,7 +3364,6 @@ const struct mt753x_info mt753x_table[] - .sw_setup = mt7530_setup, - .phy_read = mt7530_phy_read, - .phy_write = mt7530_phy_write, -- .pad_setup = mt7530_pad_clk_setup, - .mac_port_get_caps = mt7530_mac_port_get_caps, - .mac_port_config = mt7530_mac_config, - }, -@@ -3402,7 +3373,6 @@ const struct mt753x_info mt753x_table[] - .sw_setup = mt7531_setup, - .phy_read = mt7531_ind_phy_read, - .phy_write = mt7531_ind_phy_write, -- .pad_setup = mt7531_pad_setup, - .cpu_port_config = mt7531_cpu_port_config, - .mac_port_get_caps = mt7531_mac_port_get_caps, - .mac_port_config = mt7531_mac_config, -@@ -3413,7 +3383,6 @@ const struct mt753x_info mt753x_table[] - .sw_setup = mt7988_setup, - .phy_read = mt7531_ind_phy_read, - .phy_write = mt7531_ind_phy_write, -- .pad_setup = mt7988_pad_setup, - .cpu_port_config = mt7988_cpu_port_config, - .mac_port_get_caps = mt7988_mac_port_get_caps, - .mac_port_config = mt7988_mac_config, -@@ -3443,9 +3412,8 @@ mt7530_probe_common(struct mt7530_priv * - /* Sanity check if these required device operations are filled - * properly. - */ -- if (!priv->info->sw_setup || !priv->info->pad_setup || -- !priv->info->phy_read || !priv->info->phy_write || -- !priv->info->mac_port_get_caps || -+ if (!priv->info->sw_setup || !priv->info->phy_read || -+ !priv->info->phy_write || !priv->info->mac_port_get_caps || - !priv->info->mac_port_config) - return -EINVAL; - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -732,8 +732,6 @@ struct mt753x_pcs { - * @sw_setup: Holding the handler to a device initialization - * @phy_read: Holding the way reading PHY port - * @phy_write: Holding the way writing PHY port -- * @pad_setup: Holding the way setting up the bus pad for a certain -- * MAC port - * @phy_mode_supported: Check if the PHY type is being supported on a certain - * port - * @mac_port_validate: Holding the way to set addition validate type for a -@@ -749,7 +747,6 @@ struct mt753x_info { - int (*sw_setup)(struct dsa_switch *ds); - int (*phy_read)(struct mt7530_priv *priv, int port, int regnum); - int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val); -- int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface); - int (*cpu_port_config)(struct dsa_switch *ds, int port); - void (*mac_port_get_caps)(struct dsa_switch *ds, int port, - struct phylink_config *config); diff --git a/target/linux/generic/backport-6.1/790-35-v6.9-net-dsa-mt7530-correct-port-capabilities-of-MT7988.patch b/target/linux/generic/backport-6.1/790-35-v6.9-net-dsa-mt7530-correct-port-capabilities-of-MT7988.patch deleted file mode 100644 index 606c48234c18bc..00000000000000 --- a/target/linux/generic/backport-6.1/790-35-v6.9-net-dsa-mt7530-correct-port-capabilities-of-MT7988.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 58a94eb63233bb2ede13b183b6a6a03aa0a2dfc3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Tue, 6 Feb 2024 01:08:07 +0300 -Subject: [PATCH 35/48] net: dsa: mt7530: correct port capabilities of MT7988 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On the switch on the MT7988 SoC, as shown in Block Diagram 8.1.1.3 on page -125 of "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open -Version) v0.1", there are only 4 PHYs. That's port 0 to 3. Set the case for -ports which connect to switch PHYs to '0 ... 3'. - -Port 4 and 5 are not used at all in this design. - -Link: https://wiki.banana-pi.org/Banana_Pi_BPI-R4#Documents [1] -Acked-by: Daniel Golle -Reviewed-by: Vladimir Oltean -Signed-off-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-6-d7d92a185cb1@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2793,7 +2793,7 @@ static void mt7988_mac_port_get_caps(str - - switch (port) { - /* Ports which are connected to switch PHYs. There is no MII pinout. */ -- case 0 ... 4: -+ case 0 ... 3: - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - config->supported_interfaces); - break; diff --git a/target/linux/generic/backport-6.1/790-36-v6.9-net-dsa-mt7530-do-not-clear-config-supported_interfa.patch b/target/linux/generic/backport-6.1/790-36-v6.9-net-dsa-mt7530-do-not-clear-config-supported_interfa.patch deleted file mode 100644 index e2f1f23435cca9..00000000000000 --- a/target/linux/generic/backport-6.1/790-36-v6.9-net-dsa-mt7530-do-not-clear-config-supported_interfa.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 4440ce33074be6bd55d1a0c8b5f4b6d433ae2c74 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Tue, 6 Feb 2024 01:08:08 +0300 -Subject: [PATCH 36/48] net: dsa: mt7530: do not clear - config->supported_interfaces -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There's no need to clear the config->supported_interfaces bitmap before -reporting the supported interfaces as all bits in the bitmap will already -be initialized to zero when the phylink_config structure is allocated. The -"config" pointer points to &dp->phylink_config, and "dp" is allocated by -dsa_port_touch() with kzalloc(), so all its fields are filled with zeroes. - -There's no code that would change the bitmap beforehand. Remove it. - -Acked-by: Daniel Golle -Reviewed-by: Vladimir Oltean -Reviewed-by: Russell King (Oracle) -Signed-off-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/20240206-for-netnext-mt7530-improvements-2-v5-7-d7d92a185cb1@arinc9.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mt7530.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2789,8 +2789,6 @@ static void mt7531_mac_port_get_caps(str - static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port, - struct phylink_config *config) - { -- phy_interface_zero(config->supported_interfaces); -- - switch (port) { - /* Ports which are connected to switch PHYs. There is no MII pinout. */ - case 0 ... 3: diff --git a/target/linux/generic/backport-6.1/790-37-v6.9-net-dsa-mt7530-remove-.mac_port_config-for-MT7988-an.patch b/target/linux/generic/backport-6.1/790-37-v6.9-net-dsa-mt7530-remove-.mac_port_config-for-MT7988-an.patch deleted file mode 100644 index be6fe39f38ff63..00000000000000 --- a/target/linux/generic/backport-6.1/790-37-v6.9-net-dsa-mt7530-remove-.mac_port_config-for-MT7988-an.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 2f507aaeb1a12044f2376a255c2afff1f7432b0b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Fri, 1 Mar 2024 12:42:57 +0200 -Subject: [PATCH 37/48] net: dsa: mt7530: remove .mac_port_config for MT7988 - and make it optional -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -For the switch on the MT7988 SoC, the mac_port_config member for ID_MT7988 -in mt753x_table is not needed as the interfaces of all MACs are already -handled on mt7988_mac_port_get_caps(). - -Therefore, remove the mac_port_config member from ID_MT7988 in -mt753x_table. Before calling priv->info->mac_port_config(), if there's no -mac_port_config member in mt753x_table, exit mt753x_mac_config() -successfully. - -Remove calling priv->info->mac_port_config() from the sanity check as the -sanity check requires a pointer to a mac_port_config function to be -non-NULL. This will fail for MT7988 as mac_port_config won't be a member of -its info table. - -Co-developed-by: Daniel Golle -Signed-off-by: Daniel Golle -Signed-off-by: Arınç ÜNAL -Reviewed-by: Vladimir Oltean -Reviewed-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 18 ++++-------------- - 1 file changed, 4 insertions(+), 14 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2872,17 +2872,6 @@ static bool mt753x_is_mac_port(u32 port) - } - - static int --mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode, -- phy_interface_t interface) --{ -- if (dsa_is_cpu_port(ds, port) && -- interface == PHY_INTERFACE_MODE_INTERNAL) -- return 0; -- -- return -EINVAL; --} -- --static int - mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - phy_interface_t interface) - { -@@ -2922,6 +2911,9 @@ mt753x_mac_config(struct dsa_switch *ds, - { - struct mt7530_priv *priv = ds->priv; - -+ if (!priv->info->mac_port_config) -+ return 0; -+ - return priv->info->mac_port_config(ds, port, mode, state->interface); - } - -@@ -3383,7 +3375,6 @@ const struct mt753x_info mt753x_table[] - .phy_write = mt7531_ind_phy_write, - .cpu_port_config = mt7988_cpu_port_config, - .mac_port_get_caps = mt7988_mac_port_get_caps, -- .mac_port_config = mt7988_mac_config, - }, - }; - EXPORT_SYMBOL_GPL(mt753x_table); -@@ -3411,8 +3402,7 @@ mt7530_probe_common(struct mt7530_priv * - * properly. - */ - if (!priv->info->sw_setup || !priv->info->phy_read || -- !priv->info->phy_write || !priv->info->mac_port_get_caps || -- !priv->info->mac_port_config) -+ !priv->info->phy_write || !priv->info->mac_port_get_caps) - return -EINVAL; - - priv->id = priv->info->id; diff --git a/target/linux/generic/backport-6.1/790-38-v6.9-net-dsa-mt7530-set-interrupt-register-only-for-MT753.patch b/target/linux/generic/backport-6.1/790-38-v6.9-net-dsa-mt7530-set-interrupt-register-only-for-MT753.patch deleted file mode 100644 index b8473ed1285e8b..00000000000000 --- a/target/linux/generic/backport-6.1/790-38-v6.9-net-dsa-mt7530-set-interrupt-register-only-for-MT753.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0e297b1c662825f7dcd97272323c81f502987e0f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Fri, 1 Mar 2024 12:42:58 +0200 -Subject: [PATCH 38/48] net: dsa: mt7530: set interrupt register only for - MT7530 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Setting this register related to interrupts is only needed for the MT7530 -switch. Make an exclusive check to ensure this. - -Signed-off-by: Arınç ÜNAL -Acked-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2259,7 +2259,7 @@ mt7530_setup_irq(struct mt7530_priv *pri - } - - /* This register must be set for MT7530 to properly fire interrupts */ -- if (priv->id != ID_MT7531) -+ if (priv->id == ID_MT7530 || priv->id == ID_MT7621) - mt7530_set(priv, MT7530_TOP_SIG_CTRL, TOP_SIG_CTRL_NORMAL); - - ret = request_threaded_irq(priv->irq, NULL, mt7530_irq_thread_fn, diff --git a/target/linux/generic/backport-6.1/790-39-v6.9-net-dsa-mt7530-do-not-use-SW_PHY_RST-to-reset-MT7531.patch b/target/linux/generic/backport-6.1/790-39-v6.9-net-dsa-mt7530-do-not-use-SW_PHY_RST-to-reset-MT7531.patch deleted file mode 100644 index 216a781087ddba..00000000000000 --- a/target/linux/generic/backport-6.1/790-39-v6.9-net-dsa-mt7530-do-not-use-SW_PHY_RST-to-reset-MT7531.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0eb6bc551371070325b6606cc3bed6734ecad87d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Fri, 1 Mar 2024 12:42:59 +0200 -Subject: [PATCH 39/48] net: dsa: mt7530: do not use SW_PHY_RST to reset MT7531 - switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -According to the document MT7531 Reference Manual for Development Board -v1.0, the SW_PHY_RST bit on the SYS_CTRL register doesn't exist for -MT7531. This is likely why forcing link down on all ports is necessary for -MT7531. - -Therefore, do not set SW_PHY_RST on mt7531_setup(). - -Signed-off-by: Arınç ÜNAL -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2660,14 +2660,12 @@ mt7531_setup(struct dsa_switch *ds) - val = mt7530_read(priv, MT7531_TOP_SIG_SR); - priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN); - -- /* all MACs must be forced link-down before sw reset */ -+ /* Force link down on all ports before internal reset */ - for (i = 0; i < MT7530_NUM_PORTS; i++) - mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK); - - /* Reset the switch through internal reset */ -- mt7530_write(priv, MT7530_SYS_CTRL, -- SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST | -- SYS_CTRL_REG_RST); -+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST); - - if (!priv->p5_sgmii) { - mt7531_pll_setup(priv); diff --git a/target/linux/generic/backport-6.1/790-40-v6.9-net-dsa-mt7530-get-rid-of-useless-error-returns-on-p.patch b/target/linux/generic/backport-6.1/790-40-v6.9-net-dsa-mt7530-get-rid-of-useless-error-returns-on-p.patch deleted file mode 100644 index f920a6604d5ab7..00000000000000 --- a/target/linux/generic/backport-6.1/790-40-v6.9-net-dsa-mt7530-get-rid-of-useless-error-returns-on-p.patch +++ /dev/null @@ -1,217 +0,0 @@ -From bb20b1b4d832de4eb98ec7c22906db7c04e3f7c5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Fri, 1 Mar 2024 12:43:00 +0200 -Subject: [PATCH 40/48] net: dsa: mt7530: get rid of useless error returns on - phylink code path -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Remove error returns on the cases where they are already handled with the -function the mac_port_get_caps member in mt753x_table points to. - -mt7531_mac_config() is also called from mt7531_cpu_port_config() outside of -phylink but the port and interface modes are already handled there. - -Change the functions and the mac_port_config function pointer to void now -that there're no error returns anymore. - -Remove mt753x_is_mac_port() that used to help the said error returns. - -On mt7531_mac_config(), switch to if statements to simplify the code. - -Remove internal phy cases from mt753x_phylink_mac_config(), there is no -need to check the interface mode as that's already handled with the -function the mac_port_get_caps member in mt753x_table points to. - -Acked-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Arınç ÜNAL -Reviewed-by: Russell King (Oracle) -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 81 ++++++++-------------------------------- - drivers/net/dsa/mt7530.h | 6 +-- - 2 files changed, 19 insertions(+), 68 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2803,7 +2803,7 @@ static void mt7988_mac_port_get_caps(str - } - } - --static int -+static void - mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - phy_interface_t interface) - { -@@ -2813,22 +2813,14 @@ mt7530_mac_config(struct dsa_switch *ds, - mt7530_setup_port5(priv->ds, interface); - else if (port == 6) - mt7530_setup_port6(priv->ds, interface); -- -- return 0; - } - --static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port, -- phy_interface_t interface, -- struct phy_device *phydev) -+static void mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port, -+ phy_interface_t interface, -+ struct phy_device *phydev) - { - u32 val; - -- if (priv->p5_sgmii) { -- dev_err(priv->dev, "RGMII mode is not available for port %d\n", -- port); -- return -EINVAL; -- } -- - val = mt7530_read(priv, MT7531_CLKGEN_CTRL); - val |= GP_CLK_EN; - val &= ~GP_MODE_MASK; -@@ -2856,20 +2848,14 @@ static int mt7531_rgmii_setup(struct mt7 - case PHY_INTERFACE_MODE_RGMII_ID: - break; - default: -- return -EINVAL; -+ break; - } - } -- mt7530_write(priv, MT7531_CLKGEN_CTRL, val); - -- return 0; --} -- --static bool mt753x_is_mac_port(u32 port) --{ -- return (port == 5 || port == 6); -+ mt7530_write(priv, MT7531_CLKGEN_CTRL, val); - } - --static int -+static void - mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - phy_interface_t interface) - { -@@ -2877,42 +2863,21 @@ mt7531_mac_config(struct dsa_switch *ds, - struct phy_device *phydev; - struct dsa_port *dp; - -- if (!mt753x_is_mac_port(port)) { -- dev_err(priv->dev, "port %d is not a MAC port\n", port); -- return -EINVAL; -- } -- -- switch (interface) { -- case PHY_INTERFACE_MODE_RGMII: -- case PHY_INTERFACE_MODE_RGMII_ID: -- case PHY_INTERFACE_MODE_RGMII_RXID: -- case PHY_INTERFACE_MODE_RGMII_TXID: -+ if (phy_interface_mode_is_rgmii(interface)) { - dp = dsa_to_port(ds, port); - phydev = dp->slave->phydev; -- return mt7531_rgmii_setup(priv, port, interface, phydev); -- case PHY_INTERFACE_MODE_SGMII: -- case PHY_INTERFACE_MODE_NA: -- case PHY_INTERFACE_MODE_1000BASEX: -- case PHY_INTERFACE_MODE_2500BASEX: -- /* handled in SGMII PCS driver */ -- return 0; -- default: -- return -EINVAL; -+ mt7531_rgmii_setup(priv, port, interface, phydev); - } -- -- return -EINVAL; - } - --static int -+static void - mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode, - const struct phylink_link_state *state) - { - struct mt7530_priv *priv = ds->priv; - -- if (!priv->info->mac_port_config) -- return 0; -- -- return priv->info->mac_port_config(ds, port, mode, state->interface); -+ if (priv->info->mac_port_config) -+ priv->info->mac_port_config(ds, port, mode, state->interface); - } - - static struct phylink_pcs * -@@ -2941,17 +2906,11 @@ mt753x_phylink_mac_config(struct dsa_swi - u32 mcr_cur, mcr_new; - - switch (port) { -- case 0 ... 4: -- if (state->interface != PHY_INTERFACE_MODE_GMII && -- state->interface != PHY_INTERFACE_MODE_INTERNAL) -- goto unsupported; -- break; - case 5: - if (priv->p5_interface == state->interface) - break; - -- if (mt753x_mac_config(ds, port, mode, state) < 0) -- goto unsupported; -+ mt753x_mac_config(ds, port, mode, state); - - if (priv->p5_intf_sel != P5_DISABLED) - priv->p5_interface = state->interface; -@@ -2960,16 +2919,10 @@ mt753x_phylink_mac_config(struct dsa_swi - if (priv->p6_interface == state->interface) - break; - -- if (mt753x_mac_config(ds, port, mode, state) < 0) -- goto unsupported; -+ mt753x_mac_config(ds, port, mode, state); - - priv->p6_interface = state->interface; - break; -- default: --unsupported: -- dev_err(ds->dev, "%s: unsupported %s port: %i\n", -- __func__, phy_modes(state->interface), port); -- return; - } - - mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); -@@ -3052,7 +3005,6 @@ mt7531_cpu_port_config(struct dsa_switch - struct mt7530_priv *priv = ds->priv; - phy_interface_t interface; - int speed; -- int ret; - - switch (port) { - case 5: -@@ -3077,9 +3029,8 @@ mt7531_cpu_port_config(struct dsa_switch - else - speed = SPEED_1000; - -- ret = mt7531_mac_config(ds, port, MLO_AN_FIXED, interface); -- if (ret) -- return ret; -+ mt7531_mac_config(ds, port, MLO_AN_FIXED, interface); -+ - mt7530_write(priv, MT7530_PMCR_P(port), - PMCR_CPU_PORT_SETTING(priv->id)); - mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL, ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -753,9 +753,9 @@ struct mt753x_info { - void (*mac_port_validate)(struct dsa_switch *ds, int port, - phy_interface_t interface, - unsigned long *supported); -- int (*mac_port_config)(struct dsa_switch *ds, int port, -- unsigned int mode, -- phy_interface_t interface); -+ void (*mac_port_config)(struct dsa_switch *ds, int port, -+ unsigned int mode, -+ phy_interface_t interface); - }; - - /* struct mt7530_priv - This is the main data structure for holding the state diff --git a/target/linux/generic/backport-6.1/790-41-v6.9-net-dsa-mt7530-get-rid-of-priv-info-cpu_port_config.patch b/target/linux/generic/backport-6.1/790-41-v6.9-net-dsa-mt7530-get-rid-of-priv-info-cpu_port_config.patch deleted file mode 100644 index eb0a5706ecab17..00000000000000 --- a/target/linux/generic/backport-6.1/790-41-v6.9-net-dsa-mt7530-get-rid-of-priv-info-cpu_port_config.patch +++ /dev/null @@ -1,305 +0,0 @@ -From 8554f6a7914d28b179671540f527897d85c88809 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Fri, 1 Mar 2024 12:43:01 +0200 -Subject: [PATCH 41/48] net: dsa: mt7530: get rid of - priv->info->cpu_port_config() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -priv->info->cpu_port_config() is used for MT7531 and the switch on the -MT7988 SoC. It sets up the ports described as a CPU port earlier than the -phylink code path would do. - -This function is useless as: -- Configuring the MACs can be done from the phylink_mac_config code path - instead. -- All the link configuration it does on the CPU ports are later undone with - the port_enable, phylink_mac_config, and then phylink_mac_link_up code - path [1]. - -priv->p5_interface and priv->p6_interface were being used to prevent -configuring the MACs from the phylink_mac_config code path. Remove them now -that they hold no purpose. - -Remove priv->info->cpu_port_config(). On mt753x_phylink_mac_config, switch -to if statements to simplify the code. - -Remove the overwriting of the speed and duplex interfaces for certain -interface modes. Phylink already provides the speed and duplex variables -with proper values. Phylink already sets the max speed of TRGMII to -SPEED_1000. Add SPEED_2500 for PHY_INTERFACE_MODE_2500BASEX to where the -speed and EEE bits are set instead. - -On the switch on the MT7988 SoC, PHY_INTERFACE_MODE_INTERNAL is being used -to describe the interface mode of the 10G MAC, which is of port 6. On -mt7988_cpu_port_config() PMCR_FORCE_SPEED_1000 was set via the -PMCR_CPU_PORT_SETTING() mask. Add SPEED_10000 case to where the speed bits -are set to cover this. No need to add it to where the EEE bits are set as -the "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version) -v0.1" document shows that these bits don't exist on the MT7530_PMCR_P(6) -register. - -Remove the definition of PMCR_CPU_PORT_SETTING() now that it holds no -purpose. - -Change mt753x_cpu_port_enable() to void now that there're no error cases -left. - -Link: https://lore.kernel.org/netdev/ZHy2jQLesdYFMQtO@shell.armlinux.org.uk/ [1] -Suggested-by: Russell King (Oracle) -Signed-off-by: Arınç ÜNAL -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 114 +++------------------------------------ - drivers/net/dsa/mt7530.h | 11 ---- - 2 files changed, 7 insertions(+), 118 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1170,18 +1170,10 @@ mt753x_trap_frames(struct mt7530_priv *p - MT753X_BPDU_CPU_ONLY); - } - --static int -+static void - mt753x_cpu_port_enable(struct dsa_switch *ds, int port) - { - struct mt7530_priv *priv = ds->priv; -- int ret; -- -- /* Setup max capability of CPU port at first */ -- if (priv->info->cpu_port_config) { -- ret = priv->info->cpu_port_config(ds, port); -- if (ret) -- return ret; -- } - - /* Enable Mediatek header mode on the cpu port */ - mt7530_write(priv, MT7530_PVC_P(port), -@@ -1207,8 +1199,6 @@ mt753x_cpu_port_enable(struct dsa_switch - /* Set to fallback mode for independent VLAN learning */ - mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, - MT7530_PORT_FALLBACK_MODE); -- -- return 0; - } - - static int -@@ -2461,8 +2451,6 @@ mt7530_setup(struct dsa_switch *ds) - val |= MHWTRAP_MANUAL; - mt7530_write(priv, MT7530_MHWTRAP, val); - -- priv->p6_interface = PHY_INTERFACE_MODE_NA; -- - if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_40MHZ) - mt7530_pll_setup(priv); - -@@ -2480,9 +2468,7 @@ mt7530_setup(struct dsa_switch *ds) - mt7530_set(priv, MT7530_PSC_P(i), SA_DIS); - - if (dsa_is_cpu_port(ds, i)) { -- ret = mt753x_cpu_port_enable(ds, i); -- if (ret) -- return ret; -+ mt753x_cpu_port_enable(ds, i); - } else { - mt7530_port_disable(ds, i); - -@@ -2589,9 +2575,7 @@ mt7531_setup_common(struct dsa_switch *d - mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR); - - if (dsa_is_cpu_port(ds, i)) { -- ret = mt753x_cpu_port_enable(ds, i); -- if (ret) -- return ret; -+ mt753x_cpu_port_enable(ds, i); - } else { - mt7530_port_disable(ds, i); - -@@ -2683,10 +2667,6 @@ mt7531_setup(struct dsa_switch *ds) - mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK, - MT7531_GPIO0_INTERRUPT); - -- /* Let phylink decide the interface later. */ -- priv->p5_interface = PHY_INTERFACE_MODE_NA; -- priv->p6_interface = PHY_INTERFACE_MODE_NA; -- - /* Enable Energy-Efficient Ethernet (EEE) and PHY core PLL, since - * phy_device has not yet been created provided for - * phy_[read,write]_mmd_indirect is called, we provide our own -@@ -2905,26 +2885,9 @@ mt753x_phylink_mac_config(struct dsa_swi - struct mt7530_priv *priv = ds->priv; - u32 mcr_cur, mcr_new; - -- switch (port) { -- case 5: -- if (priv->p5_interface == state->interface) -- break; -- -+ if (port == 5 || port == 6) - mt753x_mac_config(ds, port, mode, state); - -- if (priv->p5_intf_sel != P5_DISABLED) -- priv->p5_interface = state->interface; -- break; -- case 6: -- if (priv->p6_interface == state->interface) -- break; -- -- mt753x_mac_config(ds, port, mode, state); -- -- priv->p6_interface = state->interface; -- break; -- } -- - mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); - mcr_new = mcr_cur; - mcr_new &= ~PMCR_LINK_SETTINGS_MASK; -@@ -2960,17 +2923,10 @@ static void mt753x_phylink_mac_link_up(s - - mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK; - -- /* MT753x MAC works in 1G full duplex mode for all up-clocked -- * variants. -- */ -- if (interface == PHY_INTERFACE_MODE_TRGMII || -- (phy_interface_mode_is_8023z(interface))) { -- speed = SPEED_1000; -- duplex = DUPLEX_FULL; -- } -- - switch (speed) { - case SPEED_1000: -+ case SPEED_2500: -+ case SPEED_10000: - mcr |= PMCR_FORCE_SPEED_1000; - break; - case SPEED_100: -@@ -2988,6 +2944,7 @@ static void mt753x_phylink_mac_link_up(s - if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) { - switch (speed) { - case SPEED_1000: -+ case SPEED_2500: - mcr |= PMCR_FORCE_EEE1G; - break; - case SPEED_100: -@@ -2999,61 +2956,6 @@ static void mt753x_phylink_mac_link_up(s - mt7530_set(priv, MT7530_PMCR_P(port), mcr); - } - --static int --mt7531_cpu_port_config(struct dsa_switch *ds, int port) --{ -- struct mt7530_priv *priv = ds->priv; -- phy_interface_t interface; -- int speed; -- -- switch (port) { -- case 5: -- if (!priv->p5_sgmii) -- interface = PHY_INTERFACE_MODE_RGMII; -- else -- interface = PHY_INTERFACE_MODE_2500BASEX; -- -- priv->p5_interface = interface; -- break; -- case 6: -- interface = PHY_INTERFACE_MODE_2500BASEX; -- -- priv->p6_interface = interface; -- break; -- default: -- return -EINVAL; -- } -- -- if (interface == PHY_INTERFACE_MODE_2500BASEX) -- speed = SPEED_2500; -- else -- speed = SPEED_1000; -- -- mt7531_mac_config(ds, port, MLO_AN_FIXED, interface); -- -- mt7530_write(priv, MT7530_PMCR_P(port), -- PMCR_CPU_PORT_SETTING(priv->id)); -- mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL, -- speed, DUPLEX_FULL, true, true); -- -- return 0; --} -- --static int --mt7988_cpu_port_config(struct dsa_switch *ds, int port) --{ -- struct mt7530_priv *priv = ds->priv; -- -- mt7530_write(priv, MT7530_PMCR_P(port), -- PMCR_CPU_PORT_SETTING(priv->id)); -- -- mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, -- PHY_INTERFACE_MODE_INTERNAL, NULL, -- SPEED_10000, DUPLEX_FULL, true, true); -- -- return 0; --} -- - static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, - struct phylink_config *config) - { -@@ -3312,7 +3214,6 @@ const struct mt753x_info mt753x_table[] - .sw_setup = mt7531_setup, - .phy_read = mt7531_ind_phy_read, - .phy_write = mt7531_ind_phy_write, -- .cpu_port_config = mt7531_cpu_port_config, - .mac_port_get_caps = mt7531_mac_port_get_caps, - .mac_port_config = mt7531_mac_config, - }, -@@ -3322,7 +3223,6 @@ const struct mt753x_info mt753x_table[] - .sw_setup = mt7988_setup, - .phy_read = mt7531_ind_phy_read, - .phy_write = mt7531_ind_phy_write, -- .cpu_port_config = mt7988_cpu_port_config, - .mac_port_get_caps = mt7988_mac_port_get_caps, - }, - }; ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -340,13 +340,6 @@ enum mt7530_vlan_port_acc_frm { - PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ - PMCR_FORCE_FDX | PMCR_FORCE_LNK | \ - PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100) --#define PMCR_CPU_PORT_SETTING(id) (PMCR_FORCE_MODE_ID((id)) | \ -- PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | \ -- PMCR_BACKOFF_EN | PMCR_BACKPR_EN | \ -- PMCR_TX_EN | PMCR_RX_EN | \ -- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ -- PMCR_FORCE_SPEED_1000 | \ -- PMCR_FORCE_FDX | PMCR_FORCE_LNK) - - #define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100) - #define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24) -@@ -747,7 +740,6 @@ struct mt753x_info { - int (*sw_setup)(struct dsa_switch *ds); - int (*phy_read)(struct mt7530_priv *priv, int port, int regnum); - int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val); -- int (*cpu_port_config)(struct dsa_switch *ds, int port); - void (*mac_port_get_caps)(struct dsa_switch *ds, int port, - struct phylink_config *config); - void (*mac_port_validate)(struct dsa_switch *ds, int port, -@@ -773,7 +765,6 @@ struct mt753x_info { - * @ports: Holding the state among ports - * @reg_mutex: The lock for protecting among process accessing - * registers -- * @p6_interface Holding the current port 6 interface - * @p5_intf_sel: Holding the current port 5 interface select - * @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch - * has got SGMII -@@ -795,8 +786,6 @@ struct mt7530_priv { - const struct mt753x_info *info; - unsigned int id; - bool mcm; -- phy_interface_t p6_interface; -- phy_interface_t p5_interface; - enum p5_interface_select p5_intf_sel; - bool p5_sgmii; - u8 mirror_rx; diff --git a/target/linux/generic/backport-6.1/790-42-v6.9-net-dsa-mt7530-get-rid-of-mt753x_mac_config.patch b/target/linux/generic/backport-6.1/790-42-v6.9-net-dsa-mt7530-get-rid-of-mt753x_mac_config.patch deleted file mode 100644 index c83a6278089476..00000000000000 --- a/target/linux/generic/backport-6.1/790-42-v6.9-net-dsa-mt7530-get-rid-of-mt753x_mac_config.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0c282205ef8c6dd6d2c145fac1fb6aba3e65c02d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Fri, 1 Mar 2024 12:43:02 +0200 -Subject: [PATCH 42/48] net: dsa: mt7530: get rid of mt753x_mac_config() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There is no need for a separate function to call -priv->info->mac_port_config(). Call it from mt753x_phylink_mac_config() -instead and remove mt753x_mac_config(). - -Signed-off-by: Arınç ÜNAL -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 14 ++------------ - 1 file changed, 2 insertions(+), 12 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2850,16 +2850,6 @@ mt7531_mac_config(struct dsa_switch *ds, - } - } - --static void --mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode, -- const struct phylink_link_state *state) --{ -- struct mt7530_priv *priv = ds->priv; -- -- if (priv->info->mac_port_config) -- priv->info->mac_port_config(ds, port, mode, state->interface); --} -- - static struct phylink_pcs * - mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port, - phy_interface_t interface) -@@ -2885,8 +2875,8 @@ mt753x_phylink_mac_config(struct dsa_swi - struct mt7530_priv *priv = ds->priv; - u32 mcr_cur, mcr_new; - -- if (port == 5 || port == 6) -- mt753x_mac_config(ds, port, mode, state); -+ if ((port == 5 || port == 6) && priv->info->mac_port_config) -+ priv->info->mac_port_config(ds, port, mode, state->interface); - - mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); - mcr_new = mcr_cur; diff --git a/target/linux/generic/backport-6.1/790-43-v6.9-net-dsa-mt7530-put-initialising-PCS-devices-code-bac.patch b/target/linux/generic/backport-6.1/790-43-v6.9-net-dsa-mt7530-put-initialising-PCS-devices-code-bac.patch deleted file mode 100644 index 84ee7416bff4e1..00000000000000 --- a/target/linux/generic/backport-6.1/790-43-v6.9-net-dsa-mt7530-put-initialising-PCS-devices-code-bac.patch +++ /dev/null @@ -1,57 +0,0 @@ -From d55c300aa1fe240aa3eba18550ba6c4e2c4bd157 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Fri, 1 Mar 2024 12:43:03 +0200 -Subject: [PATCH 43/48] net: dsa: mt7530: put initialising PCS devices code - back to original order -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The commit fae463084032 ("net: dsa: mt753x: fix pcs conversion regression") -fixes regression caused by cpu_port_config manually calling phylink -operations. cpu_port_config was deemed useless and was removed. Therefore, -put initialising PCS devices code back to its original order. - -Signed-off-by: Arınç ÜNAL -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3034,17 +3034,9 @@ static int - mt753x_setup(struct dsa_switch *ds) - { - struct mt7530_priv *priv = ds->priv; -- int i, ret; -+ int ret = priv->info->sw_setup(ds); -+ int i; - -- /* Initialise the PCS devices */ -- for (i = 0; i < priv->ds->num_ports; i++) { -- priv->pcs[i].pcs.ops = priv->info->pcs_ops; -- priv->pcs[i].pcs.neg_mode = true; -- priv->pcs[i].priv = priv; -- priv->pcs[i].port = i; -- } -- -- ret = priv->info->sw_setup(ds); - if (ret) - return ret; - -@@ -3056,6 +3048,14 @@ mt753x_setup(struct dsa_switch *ds) - if (ret && priv->irq) - mt7530_free_irq_common(priv); - -+ /* Initialise the PCS devices */ -+ for (i = 0; i < priv->ds->num_ports; i++) { -+ priv->pcs[i].pcs.ops = priv->info->pcs_ops; -+ priv->pcs[i].pcs.neg_mode = true; -+ priv->pcs[i].priv = priv; -+ priv->pcs[i].port = i; -+ } -+ - if (priv->create_sgmii) { - ret = priv->create_sgmii(priv); - if (ret && priv->irq) diff --git a/target/linux/generic/backport-6.1/790-44-v6.9-net-dsa-mt7530-sort-link-settings-ops-and-force-link.patch b/target/linux/generic/backport-6.1/790-44-v6.9-net-dsa-mt7530-sort-link-settings-ops-and-force-link.patch deleted file mode 100644 index 814a9d06e70213..00000000000000 --- a/target/linux/generic/backport-6.1/790-44-v6.9-net-dsa-mt7530-sort-link-settings-ops-and-force-link.patch +++ /dev/null @@ -1,68 +0,0 @@ -From a9544caa482a7ed215117a902f04185216997831 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Fri, 1 Mar 2024 12:43:04 +0200 -Subject: [PATCH 44/48] net: dsa: mt7530: sort link settings ops and force link - down on all ports -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -port_enable and port_disable clears the link settings. Move that to -mt7530_setup() and mt7531_setup_common() which set up the switches. This -way, the link settings are cleared on all ports at setup, and then only -once with phylink_mac_link_down() when a link goes down. - -Enable force mode at setup to apply the force part of the link settings. -This ensures that disabled ports will have their link down. - -Suggested-by: Vladimir Oltean -Signed-off-by: Arınç ÜNAL -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1222,7 +1222,6 @@ mt7530_port_enable(struct dsa_switch *ds - priv->ports[port].enable = true; - mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, - priv->ports[port].pm); -- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); - - mutex_unlock(&priv->reg_mutex); - -@@ -1242,7 +1241,6 @@ mt7530_port_disable(struct dsa_switch *d - priv->ports[port].enable = false; - mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK, - PCR_MATRIX_CLR); -- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); - - mutex_unlock(&priv->reg_mutex); - } -@@ -2460,6 +2458,12 @@ mt7530_setup(struct dsa_switch *ds) - mt7530_mib_reset(ds); - - for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ /* Clear link settings and enable force mode to force link down -+ * on all ports until they're enabled later. -+ */ -+ mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK | -+ PMCR_FORCE_MODE, PMCR_FORCE_MODE); -+ - /* Disable forwarding by default on all ports */ - mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, - PCR_MATRIX_CLR); -@@ -2565,6 +2569,12 @@ mt7531_setup_common(struct dsa_switch *d - UNU_FFP_MASK); - - for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ /* Clear link settings and enable force mode to force link down -+ * on all ports until they're enabled later. -+ */ -+ mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK | -+ MT7531_FORCE_MODE, MT7531_FORCE_MODE); -+ - /* Disable forwarding by default on all ports */ - mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, - PCR_MATRIX_CLR); diff --git a/target/linux/generic/backport-6.1/790-45-v6.9-net-dsa-mt7530-simplify-link-operations.patch b/target/linux/generic/backport-6.1/790-45-v6.9-net-dsa-mt7530-simplify-link-operations.patch deleted file mode 100644 index d9f91a932ad1db..00000000000000 --- a/target/linux/generic/backport-6.1/790-45-v6.9-net-dsa-mt7530-simplify-link-operations.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 89017cac5f6fbaab23955818c31b3c7f1eb26f4a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Fri, 1 Mar 2024 12:43:05 +0200 -Subject: [PATCH 45/48] net: dsa: mt7530: simplify link operations -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The "MT7621 Giga Switch Programming Guide v0.3", "MT7531 Reference Manual -for Development Board v1.0", and "MT7988A Wi-Fi 7 Generation Router -Platform: Datasheet (Open Version) v0.1" documents show that these bits are -enabled at reset: - -PMCR_IFG_XMIT(1) (not part of PMCR_LINK_SETTINGS_MASK) -PMCR_MAC_MODE (not part of PMCR_LINK_SETTINGS_MASK) -PMCR_TX_EN -PMCR_RX_EN -PMCR_BACKOFF_EN (not part of PMCR_LINK_SETTINGS_MASK) -PMCR_BACKPR_EN (not part of PMCR_LINK_SETTINGS_MASK) -PMCR_TX_FC_EN -PMCR_RX_FC_EN - -These bits also don't exist on the MT7530_PMCR_P(6) register of the switch -on the MT7988 SoC: - -PMCR_IFG_XMIT() -PMCR_MAC_MODE -PMCR_BACKOFF_EN -PMCR_BACKPR_EN - -Remove the setting of the bits not part of PMCR_LINK_SETTINGS_MASK on -phylink_mac_config as they're already set. - -The bit for setting the port on force mode is already done on -mt7530_setup() and mt7531_setup_common(). So get rid of -PMCR_FORCE_MODE_ID() which helped determine which bit to use for the switch -model. - -Signed-off-by: Arınç ÜNAL -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 12 +----------- - drivers/net/dsa/mt7530.h | 2 -- - 2 files changed, 1 insertion(+), 13 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2883,23 +2883,13 @@ mt753x_phylink_mac_config(struct dsa_swi - const struct phylink_link_state *state) - { - struct mt7530_priv *priv = ds->priv; -- u32 mcr_cur, mcr_new; - - if ((port == 5 || port == 6) && priv->info->mac_port_config) - priv->info->mac_port_config(ds, port, mode, state->interface); - -- mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port)); -- mcr_new = mcr_cur; -- mcr_new &= ~PMCR_LINK_SETTINGS_MASK; -- mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN | -- PMCR_BACKPR_EN | PMCR_FORCE_MODE_ID(priv->id); -- - /* Are we connected to external phy */ - if (port == 5 && dsa_is_user_port(ds, 5)) -- mcr_new |= PMCR_EXT_PHY; -- -- if (mcr_new != mcr_cur) -- mt7530_write(priv, MT7530_PMCR_P(port), mcr_new); -+ mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY); - } - - static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port, ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -333,8 +333,6 @@ enum mt7530_vlan_port_acc_frm { - MT7531_FORCE_DPX | \ - MT7531_FORCE_RX_FC | \ - MT7531_FORCE_TX_FC) --#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ -- MT7531_FORCE_MODE : PMCR_FORCE_MODE) - #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \ - PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \ - PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ diff --git a/target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch b/target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch deleted file mode 100644 index 8962e560f71ca8..00000000000000 --- a/target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 5754b3bdcd872aa229881b8f07f84a8404c7d72a Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 12 Apr 2024 16:15:34 +0100 -Subject: [PATCH 1/5] net: dsa: mt7530: provide own phylink MAC operations -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Convert mt753x to provide its own phylink MAC operations, thus avoiding -the shim layer in DSA's port.c - -Signed-off-by: Russell King (Oracle) -Tested-by: Arınç ÜNAL -Link: https://lore.kernel.org/r/E1rvIco-006bQu-Fq@rmk-PC.armlinux.org.uk -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 46 +++++++++++++++++++++++++--------------- - 1 file changed, 29 insertions(+), 17 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2861,28 +2861,34 @@ mt7531_mac_config(struct dsa_switch *ds, - } - - static struct phylink_pcs * --mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port, -+mt753x_phylink_mac_select_pcs(struct phylink_config *config, - phy_interface_t interface) - { -- struct mt7530_priv *priv = ds->priv; -+ struct dsa_port *dp = dsa_phylink_to_port(config); -+ struct mt7530_priv *priv = dp->ds->priv; - - switch (interface) { - case PHY_INTERFACE_MODE_TRGMII: -- return &priv->pcs[port].pcs; -+ return &priv->pcs[dp->index].pcs; - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_1000BASEX: - case PHY_INTERFACE_MODE_2500BASEX: -- return priv->ports[port].sgmii_pcs; -+ return priv->ports[dp->index].sgmii_pcs; - default: - return NULL; - } - } - - static void --mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, -+mt753x_phylink_mac_config(struct phylink_config *config, unsigned int mode, - const struct phylink_link_state *state) - { -- struct mt7530_priv *priv = ds->priv; -+ struct dsa_port *dp = dsa_phylink_to_port(config); -+ struct dsa_switch *ds = dp->ds; -+ struct mt7530_priv *priv; -+ int port = dp->index; -+ -+ priv = ds->priv; - - if ((port == 5 || port == 6) && priv->info->mac_port_config) - priv->info->mac_port_config(ds, port, mode, state->interface); -@@ -2892,23 +2898,25 @@ mt753x_phylink_mac_config(struct dsa_swi - mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY); - } - --static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port, -+static void mt753x_phylink_mac_link_down(struct phylink_config *config, - unsigned int mode, - phy_interface_t interface) - { -- struct mt7530_priv *priv = ds->priv; -+ struct dsa_port *dp = dsa_phylink_to_port(config); -+ struct mt7530_priv *priv = dp->ds->priv; - -- mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK); -+ mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK); - } - --static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port, -+static void mt753x_phylink_mac_link_up(struct phylink_config *config, -+ struct phy_device *phydev, - unsigned int mode, - phy_interface_t interface, -- struct phy_device *phydev, - int speed, int duplex, - bool tx_pause, bool rx_pause) - { -- struct mt7530_priv *priv = ds->priv; -+ struct dsa_port *dp = dsa_phylink_to_port(config); -+ struct mt7530_priv *priv = dp->ds->priv; - u32 mcr; - - mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK; -@@ -2943,7 +2951,7 @@ static void mt753x_phylink_mac_link_up(s - } - } - -- mt7530_set(priv, MT7530_PMCR_P(port), mcr); -+ mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr); - } - - static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, -@@ -3169,16 +3177,19 @@ const struct dsa_switch_ops mt7530_switc - .port_mirror_add = mt753x_port_mirror_add, - .port_mirror_del = mt753x_port_mirror_del, - .phylink_get_caps = mt753x_phylink_get_caps, -- .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs, -- .phylink_mac_config = mt753x_phylink_mac_config, -- .phylink_mac_link_down = mt753x_phylink_mac_link_down, -- .phylink_mac_link_up = mt753x_phylink_mac_link_up, - .get_mac_eee = mt753x_get_mac_eee, - .set_mac_eee = mt753x_set_mac_eee, - .master_state_change = mt753x_conduit_state_change, - }; - EXPORT_SYMBOL_GPL(mt7530_switch_ops); - -+static const struct phylink_mac_ops mt753x_phylink_mac_ops = { -+ .mac_select_pcs = mt753x_phylink_mac_select_pcs, -+ .mac_config = mt753x_phylink_mac_config, -+ .mac_link_down = mt753x_phylink_mac_link_down, -+ .mac_link_up = mt753x_phylink_mac_link_up, -+}; -+ - const struct mt753x_info mt753x_table[] = { - [ID_MT7621] = { - .id = ID_MT7621, -@@ -3248,6 +3259,7 @@ mt7530_probe_common(struct mt7530_priv * - priv->dev = dev; - priv->ds->priv = priv; - priv->ds->ops = &mt7530_switch_ops; -+ priv->ds->phylink_mac_ops = &mt753x_phylink_mac_ops; - mutex_init(&priv->reg_mutex); - dev_set_drvdata(dev, priv); - diff --git a/target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch b/target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch deleted file mode 100644 index cd5b7b287d3912..00000000000000 --- a/target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 019a17a5e76940ea86114838d1d638d4dc8d3750 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Sat, 13 Apr 2024 16:01:40 +0300 -Subject: [PATCH 3/5] net: dsa: mt7530: fix port mirroring for MT7988 SoC - switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version) -v0.1" document shows bits 16 to 18 as the MIRROR_PORT field of the CPU -forward control register. Currently, the MT7530 DSA subdriver configures -bits 0 to 2 of the CPU forward control register which breaks the port -mirroring feature for the MT7988 SoC switch. - -Fix this by using the MT7531_MIRROR_PORT_GET() and MT7531_MIRROR_PORT_SET() -macros which utilise the correct bits. - -Fixes: 110c18bfed41 ("net: dsa: mt7530: introduce driver for MT7988 built-in switch") -Signed-off-by: Arınç ÜNAL -Acked-by: Daniel Golle -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mt7530.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1890,14 +1890,16 @@ mt7530_port_vlan_del(struct dsa_switch * - - static int mt753x_mirror_port_get(unsigned int id, u32 val) - { -- return (id == ID_MT7531) ? MT7531_MIRROR_PORT_GET(val) : -- MIRROR_PORT(val); -+ return (id == ID_MT7531 || id == ID_MT7988) ? -+ MT7531_MIRROR_PORT_GET(val) : -+ MIRROR_PORT(val); - } - - static int mt753x_mirror_port_set(unsigned int id, u32 val) - { -- return (id == ID_MT7531) ? MT7531_MIRROR_PORT_SET(val) : -- MIRROR_PORT(val); -+ return (id == ID_MT7531 || id == ID_MT7988) ? -+ MT7531_MIRROR_PORT_SET(val) : -+ MIRROR_PORT(val); - } - - static int mt753x_port_mirror_add(struct dsa_switch *ds, int port, diff --git a/target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch b/target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch deleted file mode 100644 index e9c8f955c9fe72..00000000000000 --- a/target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch +++ /dev/null @@ -1,238 +0,0 @@ -From 5053a6cf1d50d785078562470d2a63695a9f3bf2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Thu, 18 Apr 2024 08:35:30 +0300 -Subject: [PATCH 4/5] net: dsa: mt7530-mdio: read PHY address of switch from - device tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Read the PHY address the switch listens on from the reg property of the -switch node on the device tree. This change brings support for MT7530 -switches on boards with such bootstrapping configuration where the switch -listens on a different PHY address than the hardcoded PHY address on the -driver, 31. - -As described on the "MT7621 Programming Guide v0.4" document, the MT7530 -switch and its PHYs can be configured to listen on the range of 7-12, -15-20, 23-28, and 31 and 0-4 PHY addresses. - -There are operations where the switch PHY registers are used. For the PHY -address of the control PHY, transform the MT753X_CTRL_PHY_ADDR constant -into a macro and use it. The PHY address for the control PHY is 0 when the -switch listens on 31. In any other case, it is one greater than the PHY -address the switch listens on. - -Reviewed-by: Daniel Golle -Tested-by: Daniel Golle -Reviewed-by: Florian Fainelli -Signed-off-by: Arınç ÜNAL -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530-mdio.c | 28 +++++++++++++------------- - drivers/net/dsa/mt7530.c | 37 +++++++++++++++++++++++------------ - drivers/net/dsa/mt7530.h | 4 +++- - 3 files changed, 41 insertions(+), 28 deletions(-) - ---- a/drivers/net/dsa/mt7530-mdio.c -+++ b/drivers/net/dsa/mt7530-mdio.c -@@ -18,7 +18,8 @@ - static int - mt7530_regmap_write(void *context, unsigned int reg, unsigned int val) - { -- struct mii_bus *bus = context; -+ struct mt7530_priv *priv = context; -+ struct mii_bus *bus = priv->bus; - u16 page, r, lo, hi; - int ret; - -@@ -27,36 +28,35 @@ mt7530_regmap_write(void *context, unsig - lo = val & 0xffff; - hi = val >> 16; - -- /* MT7530 uses 31 as the pseudo port */ -- ret = bus->write(bus, 0x1f, 0x1f, page); -+ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page); - if (ret < 0) - return ret; - -- ret = bus->write(bus, 0x1f, r, lo); -+ ret = bus->write(bus, priv->mdiodev->addr, r, lo); - if (ret < 0) - return ret; - -- ret = bus->write(bus, 0x1f, 0x10, hi); -+ ret = bus->write(bus, priv->mdiodev->addr, 0x10, hi); - return ret; - } - - static int - mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val) - { -- struct mii_bus *bus = context; -+ struct mt7530_priv *priv = context; -+ struct mii_bus *bus = priv->bus; - u16 page, r, lo, hi; - int ret; - - page = (reg >> 6) & 0x3ff; - r = (reg >> 2) & 0xf; - -- /* MT7530 uses 31 as the pseudo port */ -- ret = bus->write(bus, 0x1f, 0x1f, page); -+ ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page); - if (ret < 0) - return ret; - -- lo = bus->read(bus, 0x1f, r); -- hi = bus->read(bus, 0x1f, 0x10); -+ lo = bus->read(bus, priv->mdiodev->addr, r); -+ hi = bus->read(bus, priv->mdiodev->addr, 0x10); - - *val = (hi << 16) | (lo & 0xffff); - -@@ -107,8 +107,7 @@ mt7531_create_sgmii(struct mt7530_priv * - mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock; - mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock; - -- regmap = devm_regmap_init(priv->dev, -- &mt7530_regmap_bus, priv->bus, -+ regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv, - mt7531_pcs_config[i]); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); -@@ -153,6 +152,7 @@ mt7530_probe(struct mdio_device *mdiodev - - priv->bus = mdiodev->bus; - priv->dev = &mdiodev->dev; -+ priv->mdiodev = mdiodev; - - ret = mt7530_probe_common(priv); - if (ret) -@@ -203,8 +203,8 @@ mt7530_probe(struct mdio_device *mdiodev - regmap_config->reg_stride = 4; - regmap_config->max_register = MT7530_CREV; - regmap_config->disable_locking = true; -- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, -- priv->bus, regmap_config); -+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv, -+ regmap_config); - if (IS_ERR(priv->regmap)) - return PTR_ERR(priv->regmap); - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -86,22 +86,26 @@ core_read_mmd_indirect(struct mt7530_pri - int value, ret; - - /* Write the desired MMD Devad */ -- ret = bus->write(bus, 0, MII_MMD_CTRL, devad); -+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MII_MMD_CTRL, devad); - if (ret < 0) - goto err; - - /* Write the desired MMD register address */ -- ret = bus->write(bus, 0, MII_MMD_DATA, prtad); -+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MII_MMD_DATA, prtad); - if (ret < 0) - goto err; - - /* Select the Function : DATA with no post increment */ -- ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); -+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR); - if (ret < 0) - goto err; - - /* Read the content of the MMD's selected register */ -- value = bus->read(bus, 0, MII_MMD_DATA); -+ value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MII_MMD_DATA); - - return value; - err: -@@ -118,22 +122,26 @@ core_write_mmd_indirect(struct mt7530_pr - int ret; - - /* Write the desired MMD Devad */ -- ret = bus->write(bus, 0, MII_MMD_CTRL, devad); -+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MII_MMD_CTRL, devad); - if (ret < 0) - goto err; - - /* Write the desired MMD register address */ -- ret = bus->write(bus, 0, MII_MMD_DATA, prtad); -+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MII_MMD_DATA, prtad); - if (ret < 0) - goto err; - - /* Select the Function : DATA with no post increment */ -- ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR)); -+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR); - if (ret < 0) - goto err; - - /* Write the data into MMD's selected register */ -- ret = bus->write(bus, 0, MII_MMD_DATA, data); -+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MII_MMD_DATA, data); - err: - if (ret < 0) - dev_err(&bus->dev, -@@ -2684,16 +2692,19 @@ mt7531_setup(struct dsa_switch *ds) - * phy_[read,write]_mmd_indirect is called, we provide our own - * mt7531_ind_mmd_phy_[read,write] to complete this function. - */ -- val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR, -+ val = mt7531_ind_c45_phy_read(priv, -+ MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), - MDIO_MMD_VEND2, CORE_PLL_GROUP4); - val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE; - val &= ~MT7531_PHY_PLL_OFF; -- mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2, -- CORE_PLL_GROUP4, val); -+ mt7531_ind_c45_phy_write(priv, -+ MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MDIO_MMD_VEND2, CORE_PLL_GROUP4, val); - - /* Disable EEE advertisement on the switch PHYs. */ -- for (i = MT753X_CTRL_PHY_ADDR; -- i < MT753X_CTRL_PHY_ADDR + MT7530_NUM_PHYS; i++) { -+ for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr); -+ i < MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr) + MT7530_NUM_PHYS; -+ i++) { - mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV, - 0); - } ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -629,7 +629,7 @@ enum mt7531_clk_skew { - #define MT7531_PHY_PLL_OFF BIT(5) - #define MT7531_PHY_PLL_BYPASS_MODE BIT(4) - --#define MT753X_CTRL_PHY_ADDR 0 -+#define MT753X_CTRL_PHY_ADDR(addr) ((addr + 1) & 0x1f) - - #define CORE_PLL_GROUP5 0x404 - #define RG_LCDDS_PCW_NCPO1(x) ((x) & 0xffff) -@@ -771,6 +771,7 @@ struct mt753x_info { - * @irq_enable: IRQ enable bits, synced to SYS_INT_EN - * @create_sgmii: Pointer to function creating SGMII PCS instance(s) - * @active_cpu_ports: Holding the active CPU ports -+ * @mdiodev: The pointer to the MDIO device structure - */ - struct mt7530_priv { - struct device *dev; -@@ -797,6 +798,7 @@ struct mt7530_priv { - u32 irq_enable; - int (*create_sgmii)(struct mt7530_priv *priv); - u8 active_cpu_ports; -+ struct mdio_device *mdiodev; - }; - - struct mt7530_hw_vlan_entry { diff --git a/target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch b/target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch deleted file mode 100644 index d9d70f1d4df032..00000000000000 --- a/target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 9764a08b3d260f4e7799d34bbfe64463db940d74 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Thu, 18 Apr 2024 08:35:31 +0300 -Subject: [PATCH 5/5] net: dsa: mt7530: simplify core operations -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The core_rmw() function calls core_read_mmd_indirect() to read the -requested register, and then calls core_write_mmd_indirect() to write the -requested value to the register. Because Clause 22 is used to access Clause -45 registers, some operations on core_write_mmd_indirect() are -unnecessarily run. Get rid of core_read_mmd_indirect() and -core_write_mmd_indirect(), and run only the necessary operations on -core_write() and core_rmw(). - -Reviewed-by: Daniel Golle -Tested-by: Daniel Golle -Signed-off-by: Arınç ÜNAL -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 108 ++++++++++++++++----------------------- - 1 file changed, 43 insertions(+), 65 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -74,116 +74,94 @@ static const struct mt7530_mib_desc mt75 - MIB_DESC(1, 0xb8, "RxArlDrop"), - }; - --/* Since phy_device has not yet been created and -- * phy_{read,write}_mmd_indirect is not available, we provide our own -- * core_{read,write}_mmd_indirect with core_{clear,write,set} wrappers -- * to complete this function. -- */ --static int --core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad) -+static void -+mt7530_mutex_lock(struct mt7530_priv *priv) -+{ -+ if (priv->bus) -+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); -+} -+ -+static void -+mt7530_mutex_unlock(struct mt7530_priv *priv) -+{ -+ if (priv->bus) -+ mutex_unlock(&priv->bus->mdio_lock); -+} -+ -+static void -+core_write(struct mt7530_priv *priv, u32 reg, u32 val) - { - struct mii_bus *bus = priv->bus; -- int value, ret; -+ int ret; -+ -+ mt7530_mutex_lock(priv); - - /* Write the desired MMD Devad */ - ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -- MII_MMD_CTRL, devad); -+ MII_MMD_CTRL, MDIO_MMD_VEND2); - if (ret < 0) - goto err; - - /* Write the desired MMD register address */ - ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -- MII_MMD_DATA, prtad); -+ MII_MMD_DATA, reg); - if (ret < 0) - goto err; - - /* Select the Function : DATA with no post increment */ - ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -- MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR); -+ MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR); - if (ret < 0) - goto err; - -- /* Read the content of the MMD's selected register */ -- value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -- MII_MMD_DATA); -- -- return value; -+ /* Write the data into MMD's selected register */ -+ ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MII_MMD_DATA, val); - err: -- dev_err(&bus->dev, "failed to read mmd register\n"); -+ if (ret < 0) -+ dev_err(&bus->dev, "failed to write mmd register\n"); - -- return ret; -+ mt7530_mutex_unlock(priv); - } - --static int --core_write_mmd_indirect(struct mt7530_priv *priv, int prtad, -- int devad, u32 data) -+static void -+core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set) - { - struct mii_bus *bus = priv->bus; -+ u32 val; - int ret; - -+ mt7530_mutex_lock(priv); -+ - /* Write the desired MMD Devad */ - ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -- MII_MMD_CTRL, devad); -+ MII_MMD_CTRL, MDIO_MMD_VEND2); - if (ret < 0) - goto err; - - /* Write the desired MMD register address */ - ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -- MII_MMD_DATA, prtad); -+ MII_MMD_DATA, reg); - if (ret < 0) - goto err; - - /* Select the Function : DATA with no post increment */ - ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -- MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR); -+ MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR); - if (ret < 0) - goto err; - -+ /* Read the content of the MMD's selected register */ -+ val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -+ MII_MMD_DATA); -+ val &= ~mask; -+ val |= set; - /* Write the data into MMD's selected register */ - ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr), -- MII_MMD_DATA, data); -+ MII_MMD_DATA, val); - err: - if (ret < 0) -- dev_err(&bus->dev, -- "failed to write mmd register\n"); -- return ret; --} -- --static void --mt7530_mutex_lock(struct mt7530_priv *priv) --{ -- if (priv->bus) -- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); --} -- --static void --mt7530_mutex_unlock(struct mt7530_priv *priv) --{ -- if (priv->bus) -- mutex_unlock(&priv->bus->mdio_lock); --} -- --static void --core_write(struct mt7530_priv *priv, u32 reg, u32 val) --{ -- mt7530_mutex_lock(priv); -- -- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val); -- -- mt7530_mutex_unlock(priv); --} -- --static void --core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set) --{ -- u32 val; -- -- mt7530_mutex_lock(priv); -- -- val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2); -- val &= ~mask; -- val |= set; -- core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val); -+ dev_err(&bus->dev, "failed to write mmd register\n"); - - mt7530_mutex_unlock(priv); - } diff --git a/target/linux/generic/backport-6.1/790-54-v6.10-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch b/target/linux/generic/backport-6.1/790-54-v6.10-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch deleted file mode 100644 index 44cf60cf1487a6..00000000000000 --- a/target/linux/generic/backport-6.1/790-54-v6.10-net-dsa-mt7530-disable-EEE-abilities-on-failure-on-M.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 856e8954a0a88d1a4d2b43e9002b9249131a156f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:08 +0300 -Subject: [PATCH 01/15] net: dsa: mt7530: disable EEE abilities on failure on - MT7531 and MT7988 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT7531_FORCE_EEE1G and MT7531_FORCE_EEE100 bits let the -PMCR_FORCE_EEE1G and PMCR_FORCE_EEE100 bits determine the 1G/100 EEE -abilities of the MAC. If MT7531_FORCE_EEE1G and MT7531_FORCE_EEE100 are -unset, the abilities are left to be determined by PHY auto polling. - -The commit 40b5d2f15c09 ("net: dsa: mt7530: Add support for EEE features") -made it so that the PMCR_FORCE_EEE1G and PMCR_FORCE_EEE100 bits are set on -mt753x_phylink_mac_link_up(). But it did not set the MT7531_FORCE_EEE1G and -MT7531_FORCE_EEE100 bits. Because of this, the EEE abilities will be -determined by PHY auto polling, regardless of the result of phy_init_eee(). - -Define these bits and add them to the MT7531_FORCE_MODE mask which is set -in mt7531_setup_common(). With this, there won't be any EEE abilities set -when phy_init_eee() returns a negative value. - -Thanks to Russell for explaining when phy_init_eee() could return a -negative value below. - -Looking at phy_init_eee(), it could return a negative value when: - -1. phydev->drv is NULL -2. if genphy_c45_eee_is_active() returns negative -3. if genphy_c45_eee_is_active() returns zero, it returns -EPROTONOSUPPORT -4. if phy_set_bits_mmd() fails (e.g. communication error with the PHY) - -If we then look at genphy_c45_eee_is_active(), then: - -genphy_c45_read_eee_adv() and genphy_c45_read_eee_lpa() propagate their -non-zero return values, otherwise this function returns zero or positive -integer. - -If we then look at genphy_c45_read_eee_adv(), then a failure of -phy_read_mmd() would cause a negative value to be returned. - -Looking at genphy_c45_read_eee_lpa(), the same is true. - -So, it can be summarised as: - -- phydev->drv is NULL -- there is a communication error accessing the PHY -- EEE is not active - -otherwise, it returns zero on success. - -If one wishes to determine whether an error occurred vs EEE not being -supported through negotiation for the negotiated speed, if it returns --EPROTONOSUPPORT in the latter case. Other error codes mean either the -driver has been unloaded or communication error. - -In conclusion, determining the EEE abilities by PHY auto polling shouldn't -result in having any EEE abilities enabled, when one of the last two -situations in the summary happens. And it seems that if phydev->drv is -NULL, there would be bigger problems with the device than a broken link. So -this is not a bugfix. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.h | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -328,11 +328,15 @@ enum mt7530_vlan_port_acc_frm { - #define MT7531_FORCE_DPX BIT(29) - #define MT7531_FORCE_RX_FC BIT(28) - #define MT7531_FORCE_TX_FC BIT(27) -+#define MT7531_FORCE_EEE100 BIT(26) -+#define MT7531_FORCE_EEE1G BIT(25) - #define MT7531_FORCE_MODE (MT7531_FORCE_LNK | \ - MT7531_FORCE_SPD | \ - MT7531_FORCE_DPX | \ - MT7531_FORCE_RX_FC | \ -- MT7531_FORCE_TX_FC) -+ MT7531_FORCE_TX_FC | \ -+ MT7531_FORCE_EEE100 | \ -+ MT7531_FORCE_EEE1G) - #define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \ - PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \ - PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ diff --git a/target/linux/generic/backport-6.1/790-55-v6.10-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch b/target/linux/generic/backport-6.1/790-55-v6.10-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch deleted file mode 100644 index 158e5f8c00808d..00000000000000 --- a/target/linux/generic/backport-6.1/790-55-v6.10-net-dsa-mt7530-refactor-MT7530_PMCR_P.patch +++ /dev/null @@ -1,200 +0,0 @@ -From 712ad00d2f43814c81a7abfcbc339690a05fb6a0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:09 +0300 -Subject: [PATCH 02/15] net: dsa: mt7530: refactor MT7530_PMCR_P() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT7530_PMCR_P() registers are on MT7530, MT7531, and the switch on the -MT7988 SoC. Rename the definition for them to MT753X_PMCR_P(). Bit 15 is -for MT7530 only. Add MT7530 prefix to the definition for bit 15. - -Use GENMASK and FIELD_PREP for PMCR_IFG_XMIT(). - -Rename PMCR_TX_EN and PMCR_RX_EN to PMCR_MAC_TX_EN and PMCR_MAC_TX_EN to -follow the naming on the "MT7621 Giga Switch Programming Guide v0.3", -"MT7531 Reference Manual for Development Board v1.0", and "MT7988A Wi-Fi 7 -Generation Router Platform: Datasheet (Open Version) v0.1" documents. - -These documents show that PMCR_RX_FC_EN is at bit 5. Correct this along -with renaming it to PMCR_FORCE_RX_FC_EN, and the same for PMCR_TX_FC_EN. - -Remove PMCR_SPEED_MASK which doesn't have a use. - -Rename the force mode definitions for MT7531 to FORCE_MODE. Add MASK at the -end for the mask that includes all force mode definitions. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 24 ++++++++--------- - drivers/net/dsa/mt7530.h | 58 +++++++++++++++++++++------------------- - 2 files changed, 42 insertions(+), 40 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -903,7 +903,7 @@ static void mt7530_setup_port5(struct ds - val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS; - - /* Setup the MAC by default for the cpu port */ -- mt7530_write(priv, MT7530_PMCR_P(5), 0x56300); -+ mt7530_write(priv, MT753X_PMCR_P(5), 0x56300); - break; - case P5_INTF_SEL_GMAC5: - /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */ -@@ -2449,8 +2449,8 @@ mt7530_setup(struct dsa_switch *ds) - /* Clear link settings and enable force mode to force link down - * on all ports until they're enabled later. - */ -- mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK | -- PMCR_FORCE_MODE, PMCR_FORCE_MODE); -+ mt7530_rmw(priv, MT753X_PMCR_P(i), PMCR_LINK_SETTINGS_MASK | -+ MT7530_FORCE_MODE, MT7530_FORCE_MODE); - - /* Disable forwarding by default on all ports */ - mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, -@@ -2560,8 +2560,8 @@ mt7531_setup_common(struct dsa_switch *d - /* Clear link settings and enable force mode to force link down - * on all ports until they're enabled later. - */ -- mt7530_rmw(priv, MT7530_PMCR_P(i), PMCR_LINK_SETTINGS_MASK | -- MT7531_FORCE_MODE, MT7531_FORCE_MODE); -+ mt7530_rmw(priv, MT753X_PMCR_P(i), PMCR_LINK_SETTINGS_MASK | -+ MT7531_FORCE_MODE_MASK, MT7531_FORCE_MODE_MASK); - - /* Disable forwarding by default on all ports */ - mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, -@@ -2644,7 +2644,7 @@ mt7531_setup(struct dsa_switch *ds) - - /* Force link down on all ports before internal reset */ - for (i = 0; i < MT7530_NUM_PORTS; i++) -- mt7530_write(priv, MT7530_PMCR_P(i), MT7531_FORCE_LNK); -+ mt7530_write(priv, MT753X_PMCR_P(i), MT7531_FORCE_MODE_LNK); - - /* Reset the switch through internal reset */ - mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_SW_RST | SYS_CTRL_REG_RST); -@@ -2886,7 +2886,7 @@ mt753x_phylink_mac_config(struct phylink - - /* Are we connected to external phy */ - if (port == 5 && dsa_is_user_port(ds, 5)) -- mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY); -+ mt7530_set(priv, MT753X_PMCR_P(port), PMCR_EXT_PHY); - } - - static void mt753x_phylink_mac_link_down(struct phylink_config *config, -@@ -2896,7 +2896,7 @@ static void mt753x_phylink_mac_link_down - struct dsa_port *dp = dsa_phylink_to_port(config); - struct mt7530_priv *priv = dp->ds->priv; - -- mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK); -+ mt7530_clear(priv, MT753X_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK); - } - - static void mt753x_phylink_mac_link_up(struct phylink_config *config, -@@ -2910,7 +2910,7 @@ static void mt753x_phylink_mac_link_up(s - struct mt7530_priv *priv = dp->ds->priv; - u32 mcr; - -- mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK; -+ mcr = PMCR_MAC_RX_EN | PMCR_MAC_TX_EN | PMCR_FORCE_LNK; - - switch (speed) { - case SPEED_1000: -@@ -2925,9 +2925,9 @@ static void mt753x_phylink_mac_link_up(s - if (duplex == DUPLEX_FULL) { - mcr |= PMCR_FORCE_FDX; - if (tx_pause) -- mcr |= PMCR_TX_FC_EN; -+ mcr |= PMCR_FORCE_TX_FC_EN; - if (rx_pause) -- mcr |= PMCR_RX_FC_EN; -+ mcr |= PMCR_FORCE_RX_FC_EN; - } - - if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) { -@@ -2942,7 +2942,7 @@ static void mt753x_phylink_mac_link_up(s - } - } - -- mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr); -+ mt7530_set(priv, MT753X_PMCR_P(dp->index), mcr); - } - - static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port, ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -304,44 +304,46 @@ enum mt7530_vlan_port_acc_frm { - #define G0_PORT_VID_DEF G0_PORT_VID(0) - - /* Register for port MAC control register */ --#define MT7530_PMCR_P(x) (0x3000 + ((x) * 0x100)) --#define PMCR_IFG_XMIT(x) (((x) & 0x3) << 18) -+#define MT753X_PMCR_P(x) (0x3000 + ((x) * 0x100)) -+#define PMCR_IFG_XMIT_MASK GENMASK(19, 18) -+#define PMCR_IFG_XMIT(x) FIELD_PREP(PMCR_IFG_XMIT_MASK, x) - #define PMCR_EXT_PHY BIT(17) - #define PMCR_MAC_MODE BIT(16) --#define PMCR_FORCE_MODE BIT(15) --#define PMCR_TX_EN BIT(14) --#define PMCR_RX_EN BIT(13) -+#define MT7530_FORCE_MODE BIT(15) -+#define PMCR_MAC_TX_EN BIT(14) -+#define PMCR_MAC_RX_EN BIT(13) - #define PMCR_BACKOFF_EN BIT(9) - #define PMCR_BACKPR_EN BIT(8) - #define PMCR_FORCE_EEE1G BIT(7) - #define PMCR_FORCE_EEE100 BIT(6) --#define PMCR_TX_FC_EN BIT(5) --#define PMCR_RX_FC_EN BIT(4) -+#define PMCR_FORCE_RX_FC_EN BIT(5) -+#define PMCR_FORCE_TX_FC_EN BIT(4) - #define PMCR_FORCE_SPEED_1000 BIT(3) - #define PMCR_FORCE_SPEED_100 BIT(2) - #define PMCR_FORCE_FDX BIT(1) - #define PMCR_FORCE_LNK BIT(0) --#define PMCR_SPEED_MASK (PMCR_FORCE_SPEED_100 | \ -- PMCR_FORCE_SPEED_1000) --#define MT7531_FORCE_LNK BIT(31) --#define MT7531_FORCE_SPD BIT(30) --#define MT7531_FORCE_DPX BIT(29) --#define MT7531_FORCE_RX_FC BIT(28) --#define MT7531_FORCE_TX_FC BIT(27) --#define MT7531_FORCE_EEE100 BIT(26) --#define MT7531_FORCE_EEE1G BIT(25) --#define MT7531_FORCE_MODE (MT7531_FORCE_LNK | \ -- MT7531_FORCE_SPD | \ -- MT7531_FORCE_DPX | \ -- MT7531_FORCE_RX_FC | \ -- MT7531_FORCE_TX_FC | \ -- MT7531_FORCE_EEE100 | \ -- MT7531_FORCE_EEE1G) --#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \ -- PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \ -- PMCR_TX_FC_EN | PMCR_RX_FC_EN | \ -- PMCR_FORCE_FDX | PMCR_FORCE_LNK | \ -- PMCR_FORCE_EEE1G | PMCR_FORCE_EEE100) -+#define MT7531_FORCE_MODE_LNK BIT(31) -+#define MT7531_FORCE_MODE_SPD BIT(30) -+#define MT7531_FORCE_MODE_DPX BIT(29) -+#define MT7531_FORCE_MODE_RX_FC BIT(28) -+#define MT7531_FORCE_MODE_TX_FC BIT(27) -+#define MT7531_FORCE_MODE_EEE100 BIT(26) -+#define MT7531_FORCE_MODE_EEE1G BIT(25) -+#define MT7531_FORCE_MODE_MASK (MT7531_FORCE_MODE_LNK | \ -+ MT7531_FORCE_MODE_SPD | \ -+ MT7531_FORCE_MODE_DPX | \ -+ MT7531_FORCE_MODE_RX_FC | \ -+ MT7531_FORCE_MODE_TX_FC | \ -+ MT7531_FORCE_MODE_EEE100 | \ -+ MT7531_FORCE_MODE_EEE1G) -+#define PMCR_LINK_SETTINGS_MASK (PMCR_MAC_TX_EN | PMCR_MAC_RX_EN | \ -+ PMCR_FORCE_EEE1G | \ -+ PMCR_FORCE_EEE100 | \ -+ PMCR_FORCE_RX_FC_EN | \ -+ PMCR_FORCE_TX_FC_EN | \ -+ PMCR_FORCE_SPEED_1000 | \ -+ PMCR_FORCE_SPEED_100 | \ -+ PMCR_FORCE_FDX | PMCR_FORCE_LNK) - - #define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100) - #define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24) diff --git a/target/linux/generic/backport-6.1/790-56-v6.10-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch b/target/linux/generic/backport-6.1/790-56-v6.10-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch deleted file mode 100644 index 9a0ce7c36c70f3..00000000000000 --- a/target/linux/generic/backport-6.1/790-56-v6.10-net-dsa-mt7530-rename-p5_intf_sel-and-use-only-for-M.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 875ec5b67ab88e969b171e6e9ea803e3ed759614 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:10 +0300 -Subject: [PATCH 03/15] net: dsa: mt7530: rename p5_intf_sel and use only for - MT7530 switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The p5_intf_sel pointer is used to store the information of whether PHY -muxing is used or not. PHY muxing is a feature specific to port 5 of the -MT7530 switch. Do not use it for other switch models. - -Rename the pointer to p5_mode to store the mode the port is being used in. -Rename the p5_interface_select enum to mt7530_p5_mode, the string -representation to mt7530_p5_mode_str, and the enum elements. - -If PHY muxing is not detected, the default mode, GMAC5, will be used. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 62 +++++++++++++++++----------------------- - drivers/net/dsa/mt7530.h | 15 +++++----- - 2 files changed, 33 insertions(+), 44 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -864,19 +864,15 @@ mt7530_set_ageing_time(struct dsa_switch - return 0; - } - --static const char *p5_intf_modes(unsigned int p5_interface) -+static const char *mt7530_p5_mode_str(unsigned int mode) - { -- switch (p5_interface) { -- case P5_DISABLED: -- return "DISABLED"; -- case P5_INTF_SEL_PHY_P0: -- return "PHY P0"; -- case P5_INTF_SEL_PHY_P4: -- return "PHY P4"; -- case P5_INTF_SEL_GMAC5: -- return "GMAC5"; -+ switch (mode) { -+ case MUX_PHY_P0: -+ return "MUX PHY P0"; -+ case MUX_PHY_P4: -+ return "MUX PHY P4"; - default: -- return "unknown"; -+ return "GMAC5"; - } - } - -@@ -893,23 +889,23 @@ static void mt7530_setup_port5(struct ds - val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS; - val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL; - -- switch (priv->p5_intf_sel) { -- case P5_INTF_SEL_PHY_P0: -- /* MT7530_P5_MODE_GPHY_P0: 2nd GMAC -> P5 -> P0 */ -+ switch (priv->p5_mode) { -+ /* MUX_PHY_P0: P0 -> P5 -> SoC MAC */ -+ case MUX_PHY_P0: - val |= MHWTRAP_PHY0_SEL; - fallthrough; -- case P5_INTF_SEL_PHY_P4: -- /* MT7530_P5_MODE_GPHY_P4: 2nd GMAC -> P5 -> P4 */ -+ -+ /* MUX_PHY_P4: P4 -> P5 -> SoC MAC */ -+ case MUX_PHY_P4: - val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS; - - /* Setup the MAC by default for the cpu port */ - mt7530_write(priv, MT753X_PMCR_P(5), 0x56300); - break; -- case P5_INTF_SEL_GMAC5: -- /* MT7530_P5_MODE_GMAC: P5 -> External phy or 2nd GMAC */ -- val &= ~MHWTRAP_P5_DIS; -- break; -+ -+ /* GMAC5: P5 -> SoC MAC or external PHY */ - default: -+ val &= ~MHWTRAP_P5_DIS; - break; - } - -@@ -937,8 +933,8 @@ static void mt7530_setup_port5(struct ds - - mt7530_write(priv, MT7530_MHWTRAP, val); - -- dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, intf_sel=%s, phy-mode=%s\n", -- val, p5_intf_modes(priv->p5_intf_sel), phy_modes(interface)); -+ dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, mode=%s, phy-mode=%s\n", val, -+ mt7530_p5_mode_str(priv->p5_mode), phy_modes(interface)); - - mutex_unlock(&priv->reg_mutex); - } -@@ -2481,13 +2477,11 @@ mt7530_setup(struct dsa_switch *ds) - if (ret) - return ret; - -- /* Setup port 5 */ -- if (!dsa_is_unused_port(ds, 5)) { -- priv->p5_intf_sel = P5_INTF_SEL_GMAC5; -- } else { -+ /* Check for PHY muxing on port 5 */ -+ if (dsa_is_unused_port(ds, 5)) { - /* Scan the ethernet nodes. Look for GMAC1, lookup the used PHY. -- * Set priv->p5_intf_sel to the appropriate value if PHY muxing -- * is detected. -+ * Set priv->p5_mode to the appropriate value if PHY muxing is -+ * detected. - */ - for_each_child_of_node(dn, mac_np) { - if (!of_device_is_compatible(mac_np, -@@ -2511,17 +2505,16 @@ mt7530_setup(struct dsa_switch *ds) - } - id = of_mdio_parse_addr(ds->dev, phy_node); - if (id == 0) -- priv->p5_intf_sel = P5_INTF_SEL_PHY_P0; -+ priv->p5_mode = MUX_PHY_P0; - if (id == 4) -- priv->p5_intf_sel = P5_INTF_SEL_PHY_P4; -+ priv->p5_mode = MUX_PHY_P4; - } - of_node_put(mac_np); - of_node_put(phy_node); - break; - } - -- if (priv->p5_intf_sel == P5_INTF_SEL_PHY_P0 || -- priv->p5_intf_sel == P5_INTF_SEL_PHY_P4) -+ if (priv->p5_mode == MUX_PHY_P0 || priv->p5_mode == MUX_PHY_P4) - mt7530_setup_port5(ds, interface); - } - -@@ -2659,9 +2652,6 @@ mt7531_setup(struct dsa_switch *ds) - MT7531_EXT_P_MDIO_12); - } - -- if (!dsa_is_unused_port(ds, 5)) -- priv->p5_intf_sel = P5_INTF_SEL_GMAC5; -- - mt7530_rmw(priv, MT7531_GPIO_MODE0, MT7531_GPIO0_MASK, - MT7531_GPIO0_INTERRUPT); - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -708,12 +708,11 @@ struct mt7530_port { - struct phylink_pcs *sgmii_pcs; - }; - --/* Port 5 interface select definitions */ --enum p5_interface_select { -- P5_DISABLED, -- P5_INTF_SEL_PHY_P0, -- P5_INTF_SEL_PHY_P4, -- P5_INTF_SEL_GMAC5, -+/* Port 5 mode definitions of the MT7530 switch */ -+enum mt7530_p5_mode { -+ GMAC5, -+ MUX_PHY_P0, -+ MUX_PHY_P4, - }; - - struct mt7530_priv; -@@ -769,7 +768,7 @@ struct mt753x_info { - * @ports: Holding the state among ports - * @reg_mutex: The lock for protecting among process accessing - * registers -- * @p5_intf_sel: Holding the current port 5 interface select -+ * @p5_mode: Holding the current mode of port 5 of the MT7530 switch - * @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch - * has got SGMII - * @irq: IRQ number of the switch -@@ -791,7 +790,7 @@ struct mt7530_priv { - const struct mt753x_info *info; - unsigned int id; - bool mcm; -- enum p5_interface_select p5_intf_sel; -+ enum mt7530_p5_mode p5_mode; - bool p5_sgmii; - u8 mirror_rx; - u8 mirror_tx; diff --git a/target/linux/generic/backport-6.1/790-57-v6.10-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch b/target/linux/generic/backport-6.1/790-57-v6.10-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch deleted file mode 100644 index c8ffd5f07c2731..00000000000000 --- a/target/linux/generic/backport-6.1/790-57-v6.10-net-dsa-mt7530-rename-mt753x_bpdu_port_fw-enum-to-mt.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 83fe3df057e641cd0e88425e579d7a5a370ca430 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:11 +0300 -Subject: [PATCH 04/15] net: dsa: mt7530: rename mt753x_bpdu_port_fw enum to - mt753x_to_cpu_fw -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The mt753x_bpdu_port_fw enum is globally used for manipulating the process -of deciding the forwardable ports, specifically concerning the CPU port(s). -Therefore, rename it and the values in it to mt753x_to_cpu_fw. - -Change FOLLOW_MFC to SYSTEM_DEFAULT to be on par with the switch documents. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 44 ++++++++++------------- - drivers/net/dsa/mt7530.h | 76 ++++++++++++++++++++-------------------- - 2 files changed, 56 insertions(+), 64 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1114,42 +1114,34 @@ mt753x_trap_frames(struct mt7530_priv *p - * VLAN-untagged. - */ - mt7530_rmw(priv, MT753X_BPC, -- MT753X_PAE_BPDU_FR | MT753X_PAE_EG_TAG_MASK | -- MT753X_PAE_PORT_FW_MASK | MT753X_BPDU_EG_TAG_MASK | -- MT753X_BPDU_PORT_FW_MASK, -- MT753X_PAE_BPDU_FR | -- MT753X_PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY) | -- MT753X_BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_BPDU_CPU_ONLY); -+ PAE_BPDU_FR | PAE_EG_TAG_MASK | PAE_PORT_FW_MASK | -+ BPDU_EG_TAG_MASK | BPDU_PORT_FW_MASK, -+ PAE_BPDU_FR | PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ PAE_PORT_FW(TO_CPU_FW_CPU_ONLY) | -+ BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ TO_CPU_FW_CPU_ONLY); - - /* Trap frames with :01 and :02 MAC DAs to the CPU port(s) and egress - * them VLAN-untagged. - */ - mt7530_rmw(priv, MT753X_RGAC1, -- MT753X_R02_BPDU_FR | MT753X_R02_EG_TAG_MASK | -- MT753X_R02_PORT_FW_MASK | MT753X_R01_BPDU_FR | -- MT753X_R01_EG_TAG_MASK | MT753X_R01_PORT_FW_MASK, -- MT753X_R02_BPDU_FR | -- MT753X_R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_R02_PORT_FW(MT753X_BPDU_CPU_ONLY) | -- MT753X_R01_BPDU_FR | -- MT753X_R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_BPDU_CPU_ONLY); -+ R02_BPDU_FR | R02_EG_TAG_MASK | R02_PORT_FW_MASK | -+ R01_BPDU_FR | R01_EG_TAG_MASK | R01_PORT_FW_MASK, -+ R02_BPDU_FR | R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ R02_PORT_FW(TO_CPU_FW_CPU_ONLY) | R01_BPDU_FR | -+ R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ TO_CPU_FW_CPU_ONLY); - - /* Trap frames with :03 and :0E MAC DAs to the CPU port(s) and egress - * them VLAN-untagged. - */ - mt7530_rmw(priv, MT753X_RGAC2, -- MT753X_R0E_BPDU_FR | MT753X_R0E_EG_TAG_MASK | -- MT753X_R0E_PORT_FW_MASK | MT753X_R03_BPDU_FR | -- MT753X_R03_EG_TAG_MASK | MT753X_R03_PORT_FW_MASK, -- MT753X_R0E_BPDU_FR | -- MT753X_R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY) | -- MT753X_R03_BPDU_FR | -- MT753X_R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -- MT753X_BPDU_CPU_ONLY); -+ R0E_BPDU_FR | R0E_EG_TAG_MASK | R0E_PORT_FW_MASK | -+ R03_BPDU_FR | R03_EG_TAG_MASK | R03_PORT_FW_MASK, -+ R0E_BPDU_FR | R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ R0E_PORT_FW(TO_CPU_FW_CPU_ONLY) | R03_BPDU_FR | -+ R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) | -+ TO_CPU_FW_CPU_ONLY); - } - - static void ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -67,47 +67,47 @@ enum mt753x_id { - #define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ - MT7531_MIRROR_MASK : MIRROR_MASK) - --/* Registers for BPDU and PAE frame control*/ -+/* Register for BPDU and PAE frame control */ - #define MT753X_BPC 0x24 --#define MT753X_PAE_BPDU_FR BIT(25) --#define MT753X_PAE_EG_TAG_MASK GENMASK(24, 22) --#define MT753X_PAE_EG_TAG(x) FIELD_PREP(MT753X_PAE_EG_TAG_MASK, x) --#define MT753X_PAE_PORT_FW_MASK GENMASK(18, 16) --#define MT753X_PAE_PORT_FW(x) FIELD_PREP(MT753X_PAE_PORT_FW_MASK, x) --#define MT753X_BPDU_EG_TAG_MASK GENMASK(8, 6) --#define MT753X_BPDU_EG_TAG(x) FIELD_PREP(MT753X_BPDU_EG_TAG_MASK, x) --#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0) -+#define PAE_BPDU_FR BIT(25) -+#define PAE_EG_TAG_MASK GENMASK(24, 22) -+#define PAE_EG_TAG(x) FIELD_PREP(PAE_EG_TAG_MASK, x) -+#define PAE_PORT_FW_MASK GENMASK(18, 16) -+#define PAE_PORT_FW(x) FIELD_PREP(PAE_PORT_FW_MASK, x) -+#define BPDU_EG_TAG_MASK GENMASK(8, 6) -+#define BPDU_EG_TAG(x) FIELD_PREP(BPDU_EG_TAG_MASK, x) -+#define BPDU_PORT_FW_MASK GENMASK(2, 0) - --/* Register for :01 and :02 MAC DA frame control */ -+/* Register for 01-80-C2-00-00-[01,02] MAC DA frame control */ - #define MT753X_RGAC1 0x28 --#define MT753X_R02_BPDU_FR BIT(25) --#define MT753X_R02_EG_TAG_MASK GENMASK(24, 22) --#define MT753X_R02_EG_TAG(x) FIELD_PREP(MT753X_R02_EG_TAG_MASK, x) --#define MT753X_R02_PORT_FW_MASK GENMASK(18, 16) --#define MT753X_R02_PORT_FW(x) FIELD_PREP(MT753X_R02_PORT_FW_MASK, x) --#define MT753X_R01_BPDU_FR BIT(9) --#define MT753X_R01_EG_TAG_MASK GENMASK(8, 6) --#define MT753X_R01_EG_TAG(x) FIELD_PREP(MT753X_R01_EG_TAG_MASK, x) --#define MT753X_R01_PORT_FW_MASK GENMASK(2, 0) -+#define R02_BPDU_FR BIT(25) -+#define R02_EG_TAG_MASK GENMASK(24, 22) -+#define R02_EG_TAG(x) FIELD_PREP(R02_EG_TAG_MASK, x) -+#define R02_PORT_FW_MASK GENMASK(18, 16) -+#define R02_PORT_FW(x) FIELD_PREP(R02_PORT_FW_MASK, x) -+#define R01_BPDU_FR BIT(9) -+#define R01_EG_TAG_MASK GENMASK(8, 6) -+#define R01_EG_TAG(x) FIELD_PREP(R01_EG_TAG_MASK, x) -+#define R01_PORT_FW_MASK GENMASK(2, 0) - --/* Register for :03 and :0E MAC DA frame control */ -+/* Register for 01-80-C2-00-00-[03,0E] MAC DA frame control */ - #define MT753X_RGAC2 0x2c --#define MT753X_R0E_BPDU_FR BIT(25) --#define MT753X_R0E_EG_TAG_MASK GENMASK(24, 22) --#define MT753X_R0E_EG_TAG(x) FIELD_PREP(MT753X_R0E_EG_TAG_MASK, x) --#define MT753X_R0E_PORT_FW_MASK GENMASK(18, 16) --#define MT753X_R0E_PORT_FW(x) FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x) --#define MT753X_R03_BPDU_FR BIT(9) --#define MT753X_R03_EG_TAG_MASK GENMASK(8, 6) --#define MT753X_R03_EG_TAG(x) FIELD_PREP(MT753X_R03_EG_TAG_MASK, x) --#define MT753X_R03_PORT_FW_MASK GENMASK(2, 0) -+#define R0E_BPDU_FR BIT(25) -+#define R0E_EG_TAG_MASK GENMASK(24, 22) -+#define R0E_EG_TAG(x) FIELD_PREP(R0E_EG_TAG_MASK, x) -+#define R0E_PORT_FW_MASK GENMASK(18, 16) -+#define R0E_PORT_FW(x) FIELD_PREP(R0E_PORT_FW_MASK, x) -+#define R03_BPDU_FR BIT(9) -+#define R03_EG_TAG_MASK GENMASK(8, 6) -+#define R03_EG_TAG(x) FIELD_PREP(R03_EG_TAG_MASK, x) -+#define R03_PORT_FW_MASK GENMASK(2, 0) - --enum mt753x_bpdu_port_fw { -- MT753X_BPDU_FOLLOW_MFC, -- MT753X_BPDU_CPU_EXCLUDE = 4, -- MT753X_BPDU_CPU_INCLUDE = 5, -- MT753X_BPDU_CPU_ONLY = 6, -- MT753X_BPDU_DROP = 7, -+enum mt753x_to_cpu_fw { -+ TO_CPU_FW_SYSTEM_DEFAULT, -+ TO_CPU_FW_CPU_EXCLUDE = 4, -+ TO_CPU_FW_CPU_INCLUDE = 5, -+ TO_CPU_FW_CPU_ONLY = 6, -+ TO_CPU_FW_DROP = 7, - }; - - /* Registers for address table access */ diff --git a/target/linux/generic/backport-6.1/790-58-v6.10-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch b/target/linux/generic/backport-6.1/790-58-v6.10-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch deleted file mode 100644 index c977fe46cd91bb..00000000000000 --- a/target/linux/generic/backport-6.1/790-58-v6.10-net-dsa-mt7530-refactor-MT7530_MFC-and-MT7531_CFC-ad.patch +++ /dev/null @@ -1,201 +0,0 @@ -From 1dbc1bdc2869e6d2929235c70d64e393aa5a5fa2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:12 +0300 -Subject: [PATCH 05/15] net: dsa: mt7530: refactor MT7530_MFC and MT7531_CFC, - add MT7531_QRY_FFP -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT7530_MFC register is on MT7530, MT7531, and the switch on the MT7988 -SoC. Rename it to MT753X_MFC. Bit 7 to 0 differs between MT7530 and -MT7531/MT7988. Add MT7530 prefix to these definitions, and define the -IGMP/MLD Query Frame Flooding Ports mask for MT7531. - -Rename the cases of MIRROR_MASK to MIRROR_PORT_MASK. - -Move mt753x_mirror_port_get() and mt753x_port_mirror_set() to mt7530.h as -macros. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 38 ++++++++-------------- - drivers/net/dsa/mt7530.h | 69 +++++++++++++++++++++++++--------------- - 2 files changed, 57 insertions(+), 50 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1154,7 +1154,7 @@ mt753x_cpu_port_enable(struct dsa_switch - PORT_SPEC_TAG); - - /* Enable flooding on the CPU port */ -- mt7530_set(priv, MT7530_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) | -+ mt7530_set(priv, MT753X_MFC, BC_FFP(BIT(port)) | UNM_FFP(BIT(port)) | - UNU_FFP(BIT(port))); - - /* Add the CPU port to the CPU port bitmap for MT7531. Trapped frames -@@ -1318,15 +1318,15 @@ mt7530_port_bridge_flags(struct dsa_swit - flags.val & BR_LEARNING ? 0 : SA_DIS); - - if (flags.mask & BR_FLOOD) -- mt7530_rmw(priv, MT7530_MFC, UNU_FFP(BIT(port)), -+ mt7530_rmw(priv, MT753X_MFC, UNU_FFP(BIT(port)), - flags.val & BR_FLOOD ? UNU_FFP(BIT(port)) : 0); - - if (flags.mask & BR_MCAST_FLOOD) -- mt7530_rmw(priv, MT7530_MFC, UNM_FFP(BIT(port)), -+ mt7530_rmw(priv, MT753X_MFC, UNM_FFP(BIT(port)), - flags.val & BR_MCAST_FLOOD ? UNM_FFP(BIT(port)) : 0); - - if (flags.mask & BR_BCAST_FLOOD) -- mt7530_rmw(priv, MT7530_MFC, BC_FFP(BIT(port)), -+ mt7530_rmw(priv, MT753X_MFC, BC_FFP(BIT(port)), - flags.val & BR_BCAST_FLOOD ? BC_FFP(BIT(port)) : 0); - - return 0; -@@ -1862,20 +1862,6 @@ mt7530_port_vlan_del(struct dsa_switch * - return 0; - } - --static int mt753x_mirror_port_get(unsigned int id, u32 val) --{ -- return (id == ID_MT7531 || id == ID_MT7988) ? -- MT7531_MIRROR_PORT_GET(val) : -- MIRROR_PORT(val); --} -- --static int mt753x_mirror_port_set(unsigned int id, u32 val) --{ -- return (id == ID_MT7531 || id == ID_MT7988) ? -- MT7531_MIRROR_PORT_SET(val) : -- MIRROR_PORT(val); --} -- - static int mt753x_port_mirror_add(struct dsa_switch *ds, int port, - struct dsa_mall_mirror_tc_entry *mirror, - bool ingress, struct netlink_ext_ack *extack) -@@ -1891,14 +1877,14 @@ static int mt753x_port_mirror_add(struct - val = mt7530_read(priv, MT753X_MIRROR_REG(priv->id)); - - /* MT7530 only supports one monitor port */ -- monitor_port = mt753x_mirror_port_get(priv->id, val); -+ monitor_port = MT753X_MIRROR_PORT_GET(priv->id, val); - if (val & MT753X_MIRROR_EN(priv->id) && - monitor_port != mirror->to_local_port) - return -EEXIST; - - val |= MT753X_MIRROR_EN(priv->id); -- val &= ~MT753X_MIRROR_MASK(priv->id); -- val |= mt753x_mirror_port_set(priv->id, mirror->to_local_port); -+ val &= ~MT753X_MIRROR_PORT_MASK(priv->id); -+ val |= MT753X_MIRROR_PORT_SET(priv->id, mirror->to_local_port); - mt7530_write(priv, MT753X_MIRROR_REG(priv->id), val); - - val = mt7530_read(priv, MT7530_PCR_P(port)); -@@ -2538,7 +2524,7 @@ mt7531_setup_common(struct dsa_switch *d - mt7530_mib_reset(ds); - - /* Disable flooding on all ports */ -- mt7530_clear(priv, MT7530_MFC, BC_FFP_MASK | UNM_FFP_MASK | -+ mt7530_clear(priv, MT753X_MFC, BC_FFP_MASK | UNM_FFP_MASK | - UNU_FFP_MASK); - - for (i = 0; i < MT7530_NUM_PORTS; i++) { -@@ -3100,10 +3086,12 @@ mt753x_conduit_state_change(struct dsa_s - else - priv->active_cpu_ports &= ~mask; - -- if (priv->active_cpu_ports) -- val = CPU_EN | CPU_PORT(__ffs(priv->active_cpu_ports)); -+ if (priv->active_cpu_ports) { -+ val = MT7530_CPU_EN | -+ MT7530_CPU_PORT(__ffs(priv->active_cpu_ports)); -+ } - -- mt7530_rmw(priv, MT7530_MFC, CPU_EN | CPU_PORT_MASK, val); -+ mt7530_rmw(priv, MT753X_MFC, MT7530_CPU_EN | MT7530_CPU_PORT_MASK, val); - } - - static int mt7988_setup(struct dsa_switch *ds) ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -36,36 +36,55 @@ enum mt753x_id { - #define MT753X_AGC 0xc - #define LOCAL_EN BIT(7) - --/* Registers to mac forward control for unknown frames */ --#define MT7530_MFC 0x10 --#define BC_FFP(x) (((x) & 0xff) << 24) --#define BC_FFP_MASK BC_FFP(~0) --#define UNM_FFP(x) (((x) & 0xff) << 16) --#define UNM_FFP_MASK UNM_FFP(~0) --#define UNU_FFP(x) (((x) & 0xff) << 8) --#define UNU_FFP_MASK UNU_FFP(~0) --#define CPU_EN BIT(7) --#define CPU_PORT_MASK GENMASK(6, 4) --#define CPU_PORT(x) FIELD_PREP(CPU_PORT_MASK, x) --#define MIRROR_EN BIT(3) --#define MIRROR_PORT(x) ((x) & 0x7) --#define MIRROR_MASK 0x7 -+/* Register for MAC forward control */ -+#define MT753X_MFC 0x10 -+#define BC_FFP_MASK GENMASK(31, 24) -+#define BC_FFP(x) FIELD_PREP(BC_FFP_MASK, x) -+#define UNM_FFP_MASK GENMASK(23, 16) -+#define UNM_FFP(x) FIELD_PREP(UNM_FFP_MASK, x) -+#define UNU_FFP_MASK GENMASK(15, 8) -+#define UNU_FFP(x) FIELD_PREP(UNU_FFP_MASK, x) -+#define MT7530_CPU_EN BIT(7) -+#define MT7530_CPU_PORT_MASK GENMASK(6, 4) -+#define MT7530_CPU_PORT(x) FIELD_PREP(MT7530_CPU_PORT_MASK, x) -+#define MT7530_MIRROR_EN BIT(3) -+#define MT7530_MIRROR_PORT_MASK GENMASK(2, 0) -+#define MT7530_MIRROR_PORT_GET(x) FIELD_GET(MT7530_MIRROR_PORT_MASK, x) -+#define MT7530_MIRROR_PORT_SET(x) FIELD_PREP(MT7530_MIRROR_PORT_MASK, x) -+#define MT7531_QRY_FFP_MASK GENMASK(7, 0) -+#define MT7531_QRY_FFP(x) FIELD_PREP(MT7531_QRY_FFP_MASK, x) - --/* Registers for CPU forward control */ -+/* Register for CPU forward control */ - #define MT7531_CFC 0x4 - #define MT7531_MIRROR_EN BIT(19) --#define MT7531_MIRROR_MASK (MIRROR_MASK << 16) --#define MT7531_MIRROR_PORT_GET(x) (((x) >> 16) & MIRROR_MASK) --#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16) -+#define MT7531_MIRROR_PORT_MASK GENMASK(18, 16) -+#define MT7531_MIRROR_PORT_GET(x) FIELD_GET(MT7531_MIRROR_PORT_MASK, x) -+#define MT7531_MIRROR_PORT_SET(x) FIELD_PREP(MT7531_MIRROR_PORT_MASK, x) - #define MT7531_CPU_PMAP_MASK GENMASK(7, 0) - #define MT7531_CPU_PMAP(x) FIELD_PREP(MT7531_CPU_PMAP_MASK, x) - --#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ -- MT7531_CFC : MT7530_MFC) --#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ -- MT7531_MIRROR_EN : MIRROR_EN) --#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \ -- MT7531_MIRROR_MASK : MIRROR_MASK) -+#define MT753X_MIRROR_REG(id) ((id == ID_MT7531 || \ -+ id == ID_MT7988) ? \ -+ MT7531_CFC : MT753X_MFC) -+ -+#define MT753X_MIRROR_EN(id) ((id == ID_MT7531 || \ -+ id == ID_MT7988) ? \ -+ MT7531_MIRROR_EN : MT7530_MIRROR_EN) -+ -+#define MT753X_MIRROR_PORT_MASK(id) ((id == ID_MT7531 || \ -+ id == ID_MT7988) ? \ -+ MT7531_MIRROR_PORT_MASK : \ -+ MT7530_MIRROR_PORT_MASK) -+ -+#define MT753X_MIRROR_PORT_GET(id, val) ((id == ID_MT7531 || \ -+ id == ID_MT7988) ? \ -+ MT7531_MIRROR_PORT_GET(val) : \ -+ MT7530_MIRROR_PORT_GET(val)) -+ -+#define MT753X_MIRROR_PORT_SET(id, val) ((id == ID_MT7531 || \ -+ id == ID_MT7988) ? \ -+ MT7531_MIRROR_PORT_SET(val) : \ -+ MT7530_MIRROR_PORT_SET(val)) - - /* Register for BPDU and PAE frame control */ - #define MT753X_BPC 0x24 diff --git a/target/linux/generic/backport-6.1/790-59-v6.10-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch b/target/linux/generic/backport-6.1/790-59-v6.10-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch deleted file mode 100644 index 3c487d21f685b4..00000000000000 --- a/target/linux/generic/backport-6.1/790-59-v6.10-net-dsa-mt7530-refactor-MT7530_HWTRAP-and-MT7530_MHW.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 3ccf67597d35c06a7319e407b1c42f78a7966779 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:13 +0300 -Subject: [PATCH 06/15] net: dsa: mt7530: refactor MT7530_HWTRAP and - MT7530_MHWTRAP -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT7530_HWTRAP and MT7530_MHWTRAP registers are on MT7530 and MT7531. -It's called hardware trap on MT7530, software trap on MT7531. That's -because some bits of the trap on MT7530 cannot be modified by software -whilst all bits of the trap on MT7531 can. Rename the definitions for them -to MT753X_TRAP and MT753X_MTRAP. Add MT7530 and MT7531 prefixes to the -definitions specific to the switch model. - -Remove the extra parentheses from MT7530_XTAL_40MHZ and MT7530_XTAL_20MHZ. - -Rename MHWTRAP_PHY0_SEL, MHWTRAP_MANUAL, and MHWTRAP_PHY_ACCESS to be on -par with the "MT7621 Giga Switch Programming Guide v0.3" document. - -Make an enumaration for the XTAL frequency. Set the data type of the xtal -variable on mt7531_pll_setup() to it. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 59 ++++++++++++++++++++-------------------- - drivers/net/dsa/mt7530.h | 50 ++++++++++++++++------------------ - 2 files changed, 54 insertions(+), 55 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -417,23 +417,23 @@ mt7530_setup_port6(struct dsa_switch *ds - - mt7530_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_MASK, P6_INTF_MODE(1)); - -- xtal = mt7530_read(priv, MT7530_MHWTRAP) & HWTRAP_XTAL_MASK; -+ xtal = mt7530_read(priv, MT753X_MTRAP) & MT7530_XTAL_MASK; - -- if (xtal == HWTRAP_XTAL_25MHZ) -+ if (xtal == MT7530_XTAL_25MHZ) - ssc_delta = 0x57; - else - ssc_delta = 0x87; - - if (priv->id == ID_MT7621) { - /* PLL frequency: 125MHz: 1.0GBit */ -- if (xtal == HWTRAP_XTAL_40MHZ) -+ if (xtal == MT7530_XTAL_40MHZ) - ncpo1 = 0x0640; -- if (xtal == HWTRAP_XTAL_25MHZ) -+ if (xtal == MT7530_XTAL_25MHZ) - ncpo1 = 0x0a00; - } else { /* PLL frequency: 250MHz: 2.0Gbit */ -- if (xtal == HWTRAP_XTAL_40MHZ) -+ if (xtal == MT7530_XTAL_40MHZ) - ncpo1 = 0x0c80; -- if (xtal == HWTRAP_XTAL_25MHZ) -+ if (xtal == MT7530_XTAL_25MHZ) - ncpo1 = 0x1400; - } - -@@ -456,19 +456,20 @@ mt7530_setup_port6(struct dsa_switch *ds - static void - mt7531_pll_setup(struct mt7530_priv *priv) - { -+ enum mt7531_xtal_fsel xtal; - u32 top_sig; - u32 hwstrap; -- u32 xtal; - u32 val; - - val = mt7530_read(priv, MT7531_CREV); - top_sig = mt7530_read(priv, MT7531_TOP_SIG_SR); -- hwstrap = mt7530_read(priv, MT7531_HWTRAP); -+ hwstrap = mt7530_read(priv, MT753X_TRAP); - if ((val & CHIP_REV_M) > 0) -- xtal = (top_sig & PAD_MCM_SMI_EN) ? HWTRAP_XTAL_FSEL_40MHZ : -- HWTRAP_XTAL_FSEL_25MHZ; -+ xtal = (top_sig & PAD_MCM_SMI_EN) ? MT7531_XTAL_FSEL_40MHZ : -+ MT7531_XTAL_FSEL_25MHZ; - else -- xtal = hwstrap & HWTRAP_XTAL_FSEL_MASK; -+ xtal = (hwstrap & MT7531_XTAL25) ? MT7531_XTAL_FSEL_25MHZ : -+ MT7531_XTAL_FSEL_40MHZ; - - /* Step 1 : Disable MT7531 COREPLL */ - val = mt7530_read(priv, MT7531_PLLGP_EN); -@@ -497,13 +498,13 @@ mt7531_pll_setup(struct mt7530_priv *pri - usleep_range(25, 35); - - switch (xtal) { -- case HWTRAP_XTAL_FSEL_25MHZ: -+ case MT7531_XTAL_FSEL_25MHZ: - val = mt7530_read(priv, MT7531_PLLGP_CR0); - val &= ~RG_COREPLL_SDM_PCW_M; - val |= 0x140000 << RG_COREPLL_SDM_PCW_S; - mt7530_write(priv, MT7531_PLLGP_CR0, val); - break; -- case HWTRAP_XTAL_FSEL_40MHZ: -+ case MT7531_XTAL_FSEL_40MHZ: - val = mt7530_read(priv, MT7531_PLLGP_CR0); - val &= ~RG_COREPLL_SDM_PCW_M; - val |= 0x190000 << RG_COREPLL_SDM_PCW_S; -@@ -884,20 +885,20 @@ static void mt7530_setup_port5(struct ds - - mutex_lock(&priv->reg_mutex); - -- val = mt7530_read(priv, MT7530_MHWTRAP); -+ val = mt7530_read(priv, MT753X_MTRAP); - -- val |= MHWTRAP_MANUAL | MHWTRAP_P5_MAC_SEL | MHWTRAP_P5_DIS; -- val &= ~MHWTRAP_P5_RGMII_MODE & ~MHWTRAP_PHY0_SEL; -+ val |= MT7530_CHG_TRAP | MT7530_P5_MAC_SEL | MT7530_P5_DIS; -+ val &= ~MT7530_P5_RGMII_MODE & ~MT7530_P5_PHY0_SEL; - - switch (priv->p5_mode) { - /* MUX_PHY_P0: P0 -> P5 -> SoC MAC */ - case MUX_PHY_P0: -- val |= MHWTRAP_PHY0_SEL; -+ val |= MT7530_P5_PHY0_SEL; - fallthrough; - - /* MUX_PHY_P4: P4 -> P5 -> SoC MAC */ - case MUX_PHY_P4: -- val &= ~MHWTRAP_P5_MAC_SEL & ~MHWTRAP_P5_DIS; -+ val &= ~MT7530_P5_MAC_SEL & ~MT7530_P5_DIS; - - /* Setup the MAC by default for the cpu port */ - mt7530_write(priv, MT753X_PMCR_P(5), 0x56300); -@@ -905,13 +906,13 @@ static void mt7530_setup_port5(struct ds - - /* GMAC5: P5 -> SoC MAC or external PHY */ - default: -- val &= ~MHWTRAP_P5_DIS; -+ val &= ~MT7530_P5_DIS; - break; - } - - /* Setup RGMII settings */ - if (phy_interface_mode_is_rgmii(interface)) { -- val |= MHWTRAP_P5_RGMII_MODE; -+ val |= MT7530_P5_RGMII_MODE; - - /* P5 RGMII RX Clock Control: delay setting for 1000M */ - mt7530_write(priv, MT7530_P5RGMIIRXCR, CSR_RGMII_EDGE_ALIGN); -@@ -931,7 +932,7 @@ static void mt7530_setup_port5(struct ds - P5_IO_CLK_DRV(1) | P5_IO_DATA_DRV(1)); - } - -- mt7530_write(priv, MT7530_MHWTRAP, val); -+ mt7530_write(priv, MT753X_MTRAP, val); - - dev_dbg(ds->dev, "Setup P5, HWTRAP=0x%x, mode=%s, phy-mode=%s\n", val, - mt7530_p5_mode_str(priv->p5_mode), phy_modes(interface)); -@@ -2370,7 +2371,7 @@ mt7530_setup(struct dsa_switch *ds) - } - - /* Waiting for MT7530 got to stable */ -- INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP); -+ INIT_MT7530_DUMMY_POLL(&p, priv, MT753X_TRAP); - ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0, - 20, 1000000); - if (ret < 0) { -@@ -2385,7 +2386,7 @@ mt7530_setup(struct dsa_switch *ds) - return -ENODEV; - } - -- if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_20MHZ) { -+ if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_20MHZ) { - dev_err(priv->dev, - "MT7530 with a 20MHz XTAL is not supported!\n"); - return -EINVAL; -@@ -2406,12 +2407,12 @@ mt7530_setup(struct dsa_switch *ds) - RD_TAP_MASK, RD_TAP(16)); - - /* Enable port 6 */ -- val = mt7530_read(priv, MT7530_MHWTRAP); -- val &= ~MHWTRAP_P6_DIS & ~MHWTRAP_PHY_ACCESS; -- val |= MHWTRAP_MANUAL; -- mt7530_write(priv, MT7530_MHWTRAP, val); -+ val = mt7530_read(priv, MT753X_MTRAP); -+ val &= ~MT7530_P6_DIS & ~MT7530_PHY_INDIRECT_ACCESS; -+ val |= MT7530_CHG_TRAP; -+ mt7530_write(priv, MT753X_MTRAP, val); - -- if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_40MHZ) -+ if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ) - mt7530_pll_setup(priv); - - mt753x_trap_frames(priv); -@@ -2591,7 +2592,7 @@ mt7531_setup(struct dsa_switch *ds) - } - - /* Waiting for MT7530 got to stable */ -- INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP); -+ INIT_MT7530_DUMMY_POLL(&p, priv, MT753X_TRAP); - ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0, - 20, 1000000); - if (ret < 0) { ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -495,32 +495,30 @@ enum mt7531_clk_skew { - MT7531_CLK_SKEW_REVERSE = 3, - }; - --/* Register for hw trap status */ --#define MT7530_HWTRAP 0x7800 --#define HWTRAP_XTAL_MASK (BIT(10) | BIT(9)) --#define HWTRAP_XTAL_25MHZ (BIT(10) | BIT(9)) --#define HWTRAP_XTAL_40MHZ (BIT(10)) --#define HWTRAP_XTAL_20MHZ (BIT(9)) -+/* Register for trap status */ -+#define MT753X_TRAP 0x7800 -+#define MT7530_XTAL_MASK (BIT(10) | BIT(9)) -+#define MT7530_XTAL_25MHZ (BIT(10) | BIT(9)) -+#define MT7530_XTAL_40MHZ BIT(10) -+#define MT7530_XTAL_20MHZ BIT(9) -+#define MT7531_XTAL25 BIT(7) - --#define MT7531_HWTRAP 0x7800 --#define HWTRAP_XTAL_FSEL_MASK BIT(7) --#define HWTRAP_XTAL_FSEL_25MHZ BIT(7) --#define HWTRAP_XTAL_FSEL_40MHZ 0 --/* Unique fields of (M)HWSTRAP for MT7531 */ --#define XTAL_FSEL_S 7 --#define XTAL_FSEL_M BIT(7) --#define PHY_EN BIT(6) --#define CHG_STRAP BIT(8) -+/* Register for trap modification */ -+#define MT753X_MTRAP 0x7804 -+#define MT7530_P5_PHY0_SEL BIT(20) -+#define MT7530_CHG_TRAP BIT(16) -+#define MT7530_P5_MAC_SEL BIT(13) -+#define MT7530_P6_DIS BIT(8) -+#define MT7530_P5_RGMII_MODE BIT(7) -+#define MT7530_P5_DIS BIT(6) -+#define MT7530_PHY_INDIRECT_ACCESS BIT(5) -+#define MT7531_CHG_STRAP BIT(8) -+#define MT7531_PHY_EN BIT(6) - --/* Register for hw trap modification */ --#define MT7530_MHWTRAP 0x7804 --#define MHWTRAP_PHY0_SEL BIT(20) --#define MHWTRAP_MANUAL BIT(16) --#define MHWTRAP_P5_MAC_SEL BIT(13) --#define MHWTRAP_P6_DIS BIT(8) --#define MHWTRAP_P5_RGMII_MODE BIT(7) --#define MHWTRAP_P5_DIS BIT(6) --#define MHWTRAP_PHY_ACCESS BIT(5) -+enum mt7531_xtal_fsel { -+ MT7531_XTAL_FSEL_25MHZ, -+ MT7531_XTAL_FSEL_40MHZ, -+}; - - /* Register for TOP signal control */ - #define MT7530_TOP_SIG_CTRL 0x7808 diff --git a/target/linux/generic/backport-6.1/790-60-v6.10-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch b/target/linux/generic/backport-6.1/790-60-v6.10-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch deleted file mode 100644 index cfc38f81d07536..00000000000000 --- a/target/linux/generic/backport-6.1/790-60-v6.10-net-dsa-mt7530-move-MT753X_MTRAP-operations-for-MT75.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 2982f395c9a513b168f1e685588f70013cba2f5f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:14 +0300 -Subject: [PATCH 07/15] net: dsa: mt7530: move MT753X_MTRAP operations for - MT7530 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On MT7530, the media-independent interfaces of port 5 and 6 are controlled -by the MT7530_P5_DIS and MT7530_P6_DIS bits of the hardware trap. Deal with -these bits only when the relevant port is being enabled or disabled. This -ensures that these ports will be disabled when they are not in use. - -Do not set MT7530_CHG_TRAP on mt7530_setup_port5() as that's already being -done on mt7530_setup(). - -Instead of globally setting MT7530_P5_MAC_SEL, clear it, then set it only -on the appropriate case. - -If PHY muxing is detected, clear MT7530_P5_DIS before calling -mt7530_setup_port5(). - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 38 +++++++++++++++++++++++++++----------- - 1 file changed, 27 insertions(+), 11 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -887,8 +887,7 @@ static void mt7530_setup_port5(struct ds - - val = mt7530_read(priv, MT753X_MTRAP); - -- val |= MT7530_CHG_TRAP | MT7530_P5_MAC_SEL | MT7530_P5_DIS; -- val &= ~MT7530_P5_RGMII_MODE & ~MT7530_P5_PHY0_SEL; -+ val &= ~MT7530_P5_PHY0_SEL & ~MT7530_P5_MAC_SEL & ~MT7530_P5_RGMII_MODE; - - switch (priv->p5_mode) { - /* MUX_PHY_P0: P0 -> P5 -> SoC MAC */ -@@ -898,15 +897,13 @@ static void mt7530_setup_port5(struct ds - - /* MUX_PHY_P4: P4 -> P5 -> SoC MAC */ - case MUX_PHY_P4: -- val &= ~MT7530_P5_MAC_SEL & ~MT7530_P5_DIS; -- - /* Setup the MAC by default for the cpu port */ - mt7530_write(priv, MT753X_PMCR_P(5), 0x56300); - break; - - /* GMAC5: P5 -> SoC MAC or external PHY */ - default: -- val &= ~MT7530_P5_DIS; -+ val |= MT7530_P5_MAC_SEL; - break; - } - -@@ -1200,6 +1197,14 @@ mt7530_port_enable(struct dsa_switch *ds - - mutex_unlock(&priv->reg_mutex); - -+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621) -+ return 0; -+ -+ if (port == 5) -+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P5_DIS); -+ else if (port == 6) -+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P6_DIS); -+ - return 0; - } - -@@ -1218,6 +1223,14 @@ mt7530_port_disable(struct dsa_switch *d - PCR_MATRIX_CLR); - - mutex_unlock(&priv->reg_mutex); -+ -+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621) -+ return; -+ -+ if (port == 5) -+ mt7530_set(priv, MT753X_MTRAP, MT7530_P5_DIS); -+ else if (port == 6) -+ mt7530_set(priv, MT753X_MTRAP, MT7530_P6_DIS); - } - - static int -@@ -2406,11 +2419,11 @@ mt7530_setup(struct dsa_switch *ds) - mt7530_rmw(priv, MT7530_TRGMII_RD(i), - RD_TAP_MASK, RD_TAP(16)); - -- /* Enable port 6 */ -- val = mt7530_read(priv, MT753X_MTRAP); -- val &= ~MT7530_P6_DIS & ~MT7530_PHY_INDIRECT_ACCESS; -- val |= MT7530_CHG_TRAP; -- mt7530_write(priv, MT753X_MTRAP, val); -+ /* Allow modifying the trap and directly access PHY registers via the -+ * MDIO bus the switch is on. -+ */ -+ mt7530_rmw(priv, MT753X_MTRAP, MT7530_CHG_TRAP | -+ MT7530_PHY_INDIRECT_ACCESS, MT7530_CHG_TRAP); - - if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ) - mt7530_pll_setup(priv); -@@ -2493,8 +2506,11 @@ mt7530_setup(struct dsa_switch *ds) - break; - } - -- if (priv->p5_mode == MUX_PHY_P0 || priv->p5_mode == MUX_PHY_P4) -+ if (priv->p5_mode == MUX_PHY_P0 || -+ priv->p5_mode == MUX_PHY_P4) { -+ mt7530_clear(priv, MT753X_MTRAP, MT7530_P5_DIS); - mt7530_setup_port5(ds, interface); -+ } - } - - #ifdef CONFIG_GPIOLIB diff --git a/target/linux/generic/backport-6.1/790-61-v6.10-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch b/target/linux/generic/backport-6.1/790-61-v6.10-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch deleted file mode 100644 index 178ac8022ffc9d..00000000000000 --- a/target/linux/generic/backport-6.1/790-61-v6.10-net-dsa-mt7530-return-mt7530_setup_mdio-mt7531_setup.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1f5669efca65564c7533704917f79003c6b36c9c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:15 +0300 -Subject: [PATCH 08/15] net: dsa: mt7530: return mt7530_setup_mdio & - mt7531_setup_common on error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The mt7530_setup_mdio() and mt7531_setup_common() functions should be -checked for errors. Return if the functions return a non-zero value. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2672,7 +2672,9 @@ mt7531_setup(struct dsa_switch *ds) - 0); - } - -- mt7531_setup_common(ds); -+ ret = mt7531_setup_common(ds); -+ if (ret) -+ return ret; - - /* Setup VLAN ID 0 for VLAN-unaware bridges */ - ret = mt7530_setup_vlan0(priv); -@@ -3031,6 +3033,8 @@ mt753x_setup(struct dsa_switch *ds) - ret = mt7530_setup_mdio(priv); - if (ret && priv->irq) - mt7530_free_irq_common(priv); -+ if (ret) -+ return ret; - - /* Initialise the PCS devices */ - for (i = 0; i < priv->ds->num_ports; i++) { diff --git a/target/linux/generic/backport-6.1/790-62-v6.10-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch b/target/linux/generic/backport-6.1/790-62-v6.10-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch deleted file mode 100644 index af8edf5a4273d7..00000000000000 --- a/target/linux/generic/backport-6.1/790-62-v6.10-net-dsa-mt7530-define-MAC-speed-capabilities-per-swi.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 6cc2d4ccd77509df74b7b8ef46bbc6ba0a571318 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:16 +0300 -Subject: [PATCH 09/15] net: dsa: mt7530: define MAC speed capabilities per - switch model -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With the support of the MT7988 SoC switch, the MAC speed capabilities -defined on mt753x_phylink_get_caps() won't apply to all switch models -anymore. Move them to more appropriate locations instead of overwriting -config->mac_capabilities. - -Remove the comment on mt753x_phylink_get_caps() as it's become invalid with -the support of MT7531 and MT7988 SoC switch. - -Add break to case 6 of mt7988_mac_port_get_caps() to be explicit. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2690,6 +2690,8 @@ mt7531_setup(struct dsa_switch *ds) - static void mt7530_mac_port_get_caps(struct dsa_switch *ds, int port, - struct phylink_config *config) - { -+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD; -+ - switch (port) { - /* Ports which are connected to switch PHYs. There is no MII pinout. */ - case 0 ... 4: -@@ -2721,6 +2723,8 @@ static void mt7531_mac_port_get_caps(str - { - struct mt7530_priv *priv = ds->priv; - -+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD; -+ - switch (port) { - /* Ports which are connected to switch PHYs. There is no MII pinout. */ - case 0 ... 4: -@@ -2760,14 +2764,17 @@ static void mt7988_mac_port_get_caps(str - case 0 ... 3: - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - config->supported_interfaces); -+ -+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD; - break; - - /* Port 6 is connected to SoC's XGMII MAC. There is no MII pinout. */ - case 6: - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - config->supported_interfaces); -- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -- MAC_10000FD; -+ -+ config->mac_capabilities |= MAC_10000FD; -+ break; - } - } - -@@ -2937,9 +2944,7 @@ static void mt753x_phylink_get_caps(stru - { - struct mt7530_priv *priv = ds->priv; - -- /* This switch only supports full-duplex at 1Gbps */ -- config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | -- MAC_10 | MAC_100 | MAC_1000FD; -+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE; - - /* This driver does not make use of the speed, duplex, pause or the - * advertisement in its mac_config, so it is safe to mark this driver diff --git a/target/linux/generic/backport-6.1/790-63-v6.10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch b/target/linux/generic/backport-6.1/790-63-v6.10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch deleted file mode 100644 index 3825952dc31243..00000000000000 --- a/target/linux/generic/backport-6.1/790-63-v6.10-net-dsa-mt7530-get-rid-of-function-sanity-check.patch +++ /dev/null @@ -1,33 +0,0 @@ -From dd0f15fc877c10567699190bce0f55e96f4ad6b5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:17 +0300 -Subject: [PATCH 10/15] net: dsa: mt7530: get rid of function sanity check -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Get rid of checking whether functions are filled properly. priv->info which -is an mt753x_info structure is filled and checked for before this check. -It's unnecessary checking whether it's filled properly. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3235,13 +3235,6 @@ mt7530_probe_common(struct mt7530_priv * - if (!priv->info) - return -EINVAL; - -- /* Sanity check if these required device operations are filled -- * properly. -- */ -- if (!priv->info->sw_setup || !priv->info->phy_read || -- !priv->info->phy_write || !priv->info->mac_port_get_caps) -- return -EINVAL; -- - priv->id = priv->info->id; - priv->dev = dev; - priv->ds->priv = priv; diff --git a/target/linux/generic/backport-6.1/790-64-v6.10-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch b/target/linux/generic/backport-6.1/790-64-v6.10-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch deleted file mode 100644 index df474580141088..00000000000000 --- a/target/linux/generic/backport-6.1/790-64-v6.10-net-dsa-mt7530-refactor-MT7530_PMEEECR_P.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 2dff9759602b069f97ccc939e15a47ca051b2983 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:18 +0300 -Subject: [PATCH 11/15] net: dsa: mt7530: refactor MT7530_PMEEECR_P() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT7530_PMEEECR_P() register is on MT7530, MT7531, and the switch on the -MT7988 SoC. Rename the definition for them to MT753X_PMEEECR_P(). Use the -FIELD_PREP and FIELD_GET macros. Rename GET_LPI_THRESH() and -SET_LPI_THRESH() to LPI_THRESH_GET() and LPI_THRESH_SET(). - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 8 ++++---- - drivers/net/dsa/mt7530.h | 13 +++++++------ - 2 files changed, 11 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -3062,10 +3062,10 @@ static int mt753x_get_mac_eee(struct dsa - struct ethtool_eee *e) - { - struct mt7530_priv *priv = ds->priv; -- u32 eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port)); -+ u32 eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port)); - - e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN); -- e->tx_lpi_timer = GET_LPI_THRESH(eeecr); -+ e->tx_lpi_timer = LPI_THRESH_GET(eeecr); - - return 0; - } -@@ -3079,11 +3079,11 @@ static int mt753x_set_mac_eee(struct dsa - if (e->tx_lpi_timer > 0xFFF) - return -EINVAL; - -- set = SET_LPI_THRESH(e->tx_lpi_timer); -+ set = LPI_THRESH_SET(e->tx_lpi_timer); - if (!e->tx_lpi_enabled) - /* Force LPI Mode without a delay */ - set |= LPI_MODE_EN; -- mt7530_rmw(priv, MT7530_PMEEECR_P(port), mask, set); -+ mt7530_rmw(priv, MT753X_PMEEECR_P(port), mask, set); - - return 0; - } ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -364,13 +364,14 @@ enum mt7530_vlan_port_acc_frm { - PMCR_FORCE_SPEED_100 | \ - PMCR_FORCE_FDX | PMCR_FORCE_LNK) - --#define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100) --#define WAKEUP_TIME_1000(x) (((x) & 0xFF) << 24) --#define WAKEUP_TIME_100(x) (((x) & 0xFF) << 16) -+#define MT753X_PMEEECR_P(x) (0x3004 + (x) * 0x100) -+#define WAKEUP_TIME_1000_MASK GENMASK(31, 24) -+#define WAKEUP_TIME_1000(x) FIELD_PREP(WAKEUP_TIME_1000_MASK, x) -+#define WAKEUP_TIME_100_MASK GENMASK(23, 16) -+#define WAKEUP_TIME_100(x) FIELD_PREP(WAKEUP_TIME_100_MASK, x) - #define LPI_THRESH_MASK GENMASK(15, 4) --#define LPI_THRESH_SHT 4 --#define SET_LPI_THRESH(x) (((x) << LPI_THRESH_SHT) & LPI_THRESH_MASK) --#define GET_LPI_THRESH(x) (((x) & LPI_THRESH_MASK) >> LPI_THRESH_SHT) -+#define LPI_THRESH_GET(x) FIELD_GET(LPI_THRESH_MASK, x) -+#define LPI_THRESH_SET(x) FIELD_PREP(LPI_THRESH_MASK, x) - #define LPI_MODE_EN BIT(0) - - #define MT7530_PMSR_P(x) (0x3008 + (x) * 0x100) diff --git a/target/linux/generic/backport-6.1/790-65-v6.10-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch b/target/linux/generic/backport-6.1/790-65-v6.10-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch deleted file mode 100644 index 7ce2d4c04e4c7f..00000000000000 --- a/target/linux/generic/backport-6.1/790-65-v6.10-net-dsa-mt7530-get-rid-of-mac_port_validate-member-o.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 21d67c2fabfe40baf33202d3287b67b6c16f8382 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:19 +0300 -Subject: [PATCH 12/15] net: dsa: mt7530: get rid of mac_port_validate member - of mt753x_info -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The mac_port_validate member of the mt753x_info structure is not being -used, remove it. Improve the member description section in the process. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.h | 10 +++------- - 1 file changed, 3 insertions(+), 7 deletions(-) - ---- a/drivers/net/dsa/mt7530.h -+++ b/drivers/net/dsa/mt7530.h -@@ -743,13 +743,12 @@ struct mt753x_pcs { - - /* struct mt753x_info - This is the main data structure for holding the specific - * part for each supported device -+ * @id: Holding the identifier to a switch model -+ * @pcs_ops: Holding the pointer to the MAC PCS operations structure - * @sw_setup: Holding the handler to a device initialization - * @phy_read: Holding the way reading PHY port - * @phy_write: Holding the way writing PHY port -- * @phy_mode_supported: Check if the PHY type is being supported on a certain -- * port -- * @mac_port_validate: Holding the way to set addition validate type for a -- * certan MAC port -+ * @mac_port_get_caps: Holding the handler that provides MAC capabilities - * @mac_port_config: Holding the way setting up the PHY attribute to a - * certain MAC port - */ -@@ -763,9 +762,6 @@ struct mt753x_info { - int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val); - void (*mac_port_get_caps)(struct dsa_switch *ds, int port, - struct phylink_config *config); -- void (*mac_port_validate)(struct dsa_switch *ds, int port, -- phy_interface_t interface, -- unsigned long *supported); - void (*mac_port_config)(struct dsa_switch *ds, int port, - unsigned int mode, - phy_interface_t interface); diff --git a/target/linux/generic/backport-6.1/790-66-v6.10-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch b/target/linux/generic/backport-6.1/790-66-v6.10-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch deleted file mode 100644 index e9512421c22275..00000000000000 --- a/target/linux/generic/backport-6.1/790-66-v6.10-net-dsa-mt7530-use-priv-ds-num_ports-instead-of-MT75.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 6efc8ae3eb0363328f479191a0cf0dc12a16e090 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:20 +0300 -Subject: [PATCH 13/15] net: dsa: mt7530: use priv->ds->num_ports instead of - MT7530_NUM_PORTS -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use priv->ds->num_ports on all for loops which configure the switch -registers. In the future, the value of MT7530_NUM_PORTS will depend on -priv->id. Therefore, this change prepares the subdriver for a simpler -implementation. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1418,7 +1418,7 @@ mt7530_port_set_vlan_unaware(struct dsa_ - mt7530_rmw(priv, MT7530_PPBV1_P(port), G0_PORT_VID_MASK, - G0_PORT_VID_DEF); - -- for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ for (i = 0; i < priv->ds->num_ports; i++) { - if (dsa_is_user_port(ds, i) && - dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) { - all_user_ports_removed = false; -@@ -2433,7 +2433,7 @@ mt7530_setup(struct dsa_switch *ds) - /* Enable and reset MIB counters */ - mt7530_mib_reset(ds); - -- for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ for (i = 0; i < priv->ds->num_ports; i++) { - /* Clear link settings and enable force mode to force link down - * on all ports until they're enabled later. - */ -@@ -2544,7 +2544,7 @@ mt7531_setup_common(struct dsa_switch *d - mt7530_clear(priv, MT753X_MFC, BC_FFP_MASK | UNM_FFP_MASK | - UNU_FFP_MASK); - -- for (i = 0; i < MT7530_NUM_PORTS; i++) { -+ for (i = 0; i < priv->ds->num_ports; i++) { - /* Clear link settings and enable force mode to force link down - * on all ports until they're enabled later. - */ -@@ -2631,7 +2631,7 @@ mt7531_setup(struct dsa_switch *ds) - priv->p5_sgmii = !!(val & PAD_DUAL_SGMII_EN); - - /* Force link down on all ports before internal reset */ -- for (i = 0; i < MT7530_NUM_PORTS; i++) -+ for (i = 0; i < priv->ds->num_ports; i++) - mt7530_write(priv, MT753X_PMCR_P(i), MT7531_FORCE_MODE_LNK); - - /* Reset the switch through internal reset */ diff --git a/target/linux/generic/backport-6.1/790-67-v6.10-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch b/target/linux/generic/backport-6.1/790-67-v6.10-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch deleted file mode 100644 index 3b3330bdce8083..00000000000000 --- a/target/linux/generic/backport-6.1/790-67-v6.10-net-dsa-mt7530-do-not-pass-port-variable-to-mt7531_r.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 4794c12e3aefe05dd0063c2b6b0101854b143bac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:21 +0300 -Subject: [PATCH 14/15] net: dsa: mt7530: do not pass port variable to - mt7531_rgmii_setup() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The mt7531_rgmii_setup() function does not use the port variable, do not -pass the variable to it. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2790,7 +2790,7 @@ mt7530_mac_config(struct dsa_switch *ds, - mt7530_setup_port6(priv->ds, interface); - } - --static void mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port, -+static void mt7531_rgmii_setup(struct mt7530_priv *priv, - phy_interface_t interface, - struct phy_device *phydev) - { -@@ -2841,7 +2841,7 @@ mt7531_mac_config(struct dsa_switch *ds, - if (phy_interface_mode_is_rgmii(interface)) { - dp = dsa_to_port(ds, port); - phydev = dp->slave->phydev; -- mt7531_rgmii_setup(priv, port, interface, phydev); -+ mt7531_rgmii_setup(priv, interface, phydev); - } - } - diff --git a/target/linux/generic/backport-6.1/790-68-v6.10-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch b/target/linux/generic/backport-6.1/790-68-v6.10-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch deleted file mode 100644 index 6d28e5b5f970a9..00000000000000 --- a/target/linux/generic/backport-6.1/790-68-v6.10-net-dsa-mt7530-explain-exposing-MDIO-bus-of-MT7531AE.patch +++ /dev/null @@ -1,33 +0,0 @@ -From c45832fe783f468aaaace09ae95a30cbf0acf724 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Mon, 22 Apr 2024 10:15:22 +0300 -Subject: [PATCH 15/15] net: dsa: mt7530: explain exposing MDIO bus of MT7531AE - better -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Unlike MT7531BE, the GPIO 6-12 pins are not used for RGMII on MT7531AE. -Therefore, the GPIO 11-12 pins are set to function as MDC and MDIO to -expose the MDIO bus of the switch. Replace the comment with a better -explanation. - -Signed-off-by: Arınç ÜNAL ---- - drivers/net/dsa/mt7530.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2640,7 +2640,10 @@ mt7531_setup(struct dsa_switch *ds) - if (!priv->p5_sgmii) { - mt7531_pll_setup(priv); - } else { -- /* Let ds->slave_mii_bus be able to access external phy. */ -+ /* Unlike MT7531BE, the GPIO 6-12 pins are not used for RGMII on -+ * MT7531AE. Set the GPIO 11-12 pins to function as MDC and MDIO -+ * to expose the MDIO bus of the switch. -+ */ - mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO11_RG_RXD2_MASK, - MT7531_EXT_P_MDC_11); - mt7530_rmw(priv, MT7531_GPIO_MODE1, MT7531_GPIO12_RG_RXD3_MASK, diff --git a/target/linux/generic/backport-6.1/790-69-v6.10-net-dsa-mt7530-do-not-set-MT7530_P5_DIS-when-PHY-.patch b/target/linux/generic/backport-6.1/790-69-v6.10-net-dsa-mt7530-do-not-set-MT7530_P5_DIS-when-PHY-.patch deleted file mode 100644 index 29079e03c599d0..00000000000000 --- a/target/linux/generic/backport-6.1/790-69-v6.10-net-dsa-mt7530-do-not-set-MT7530_P5_DIS-when-PHY-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 16e6592cd5c5bd74d8890973489f60176c692614 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Sun, 28 Apr 2024 12:19:58 +0300 -Subject: [PATCH] net: dsa: mt7530: do not set MT7530_P5_DIS when PHY muxing is - being used -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -DSA initalises the ds->num_ports amount of ports in -dsa_switch_touch_ports(). When the PHY muxing feature is in use, port 5 -won't be defined in the device tree. Because of this, the type member of -the dsa_port structure for this port will be assigned DSA_PORT_TYPE_UNUSED. -The dsa_port_setup() function calls ds->ops->port_disable() when the port -type is DSA_PORT_TYPE_UNUSED. - -The MT7530_P5_DIS bit is unset in mt7530_setup() when PHY muxing is being -used. mt7530_port_disable() which is assigned to ds->ops->port_disable() is -called afterwards. Currently, mt7530_port_disable() sets MT7530_P5_DIS -which breaks network connectivity when PHY muxing is being used. - -Therefore, do not set MT7530_P5_DIS when PHY muxing is being used. - -Fixes: 377174c5760c ("net: dsa: mt7530: move MT753X_MTRAP operations for MT7530") -Reported-by: Daniel Golle -Signed-off-by: Arınç ÜNAL -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240428-for-netnext-mt7530-do-not-disable-port5-when-phy-muxing-v2-1-bb7c37d293f8@arinc9.com -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -1227,7 +1227,8 @@ mt7530_port_disable(struct dsa_switch *d - if (priv->id != ID_MT7530 && priv->id != ID_MT7621) - return; - -- if (port == 5) -+ /* Do not set MT7530_P5_DIS when port 5 is being used for PHY muxing. */ -+ if (port == 5 && priv->p5_mode == GMAC5) - mt7530_set(priv, MT753X_MTRAP, MT7530_P5_DIS); - else if (port == 6) - mt7530_set(priv, MT753X_MTRAP, MT7530_P6_DIS); diff --git a/target/linux/generic/backport-6.1/790-70-v6.10-796-net-dsa-mt7530-detect-PHY-muxing-when-PHY-is-defined.patch b/target/linux/generic/backport-6.1/790-70-v6.10-796-net-dsa-mt7530-detect-PHY-muxing-when-PHY-is-defined.patch deleted file mode 100644 index 69bbb8e22924d0..00000000000000 --- a/target/linux/generic/backport-6.1/790-70-v6.10-796-net-dsa-mt7530-detect-PHY-muxing-when-PHY-is-defined.patch +++ /dev/null @@ -1,45 +0,0 @@ -From d8dcf5bd6d0eace9f7c1daa14b63b3925b09d033 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= -Date: Tue, 30 Apr 2024 08:01:33 +0300 -Subject: [PATCH] net: dsa: mt7530: detect PHY muxing when PHY is defined on - switch MDIO bus -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently, the MT7530 DSA subdriver configures the MT7530 switch to provide -direct access to switch PHYs, meaning, the switch PHYs listen on the MDIO -bus the switch listens on. The PHY muxing feature makes use of this. - -This is problematic as the PHY may be attached before the switch is -initialised, in which case, the PHY will fail to be attached. - -Since commit 91374ba537bd ("net: dsa: mt7530: support OF-based registration -of switch MDIO bus"), we can describe the switch PHYs on the MDIO bus of -the switch on the device tree. Extend the check to detect PHY muxing when -the PHY is defined on the MDIO bus of the switch on the device tree. - -When the PHY is described this way, the switch will be initialised first, -then the switch MDIO bus will be registered. Only after these steps, the -PHY will be attached. - -Signed-off-by: Arınç ÜNAL -Reviewed-by: Daniel Golle -Link: https://lore.kernel.org/r/20240430-b4-for-netnext-mt7530-use-switch-mdio-bus-for-phy-muxing-v2-1-9104d886d0db@arinc9.com -Signed-off-by: Paolo Abeni ---- - drivers/net/dsa/mt7530.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/mt7530.c -+++ b/drivers/net/dsa/mt7530.c -@@ -2489,7 +2489,8 @@ mt7530_setup(struct dsa_switch *ds) - if (!phy_node) - continue; - -- if (phy_node->parent == priv->dev->of_node->parent) { -+ if (phy_node->parent == priv->dev->of_node->parent || -+ phy_node->parent->parent == priv->dev->of_node) { - ret = of_get_phy_mode(mac_np, &interface); - if (ret && ret != -ENODEV) { - of_node_put(mac_np); diff --git a/target/linux/generic/backport-6.1/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch b/target/linux/generic/backport-6.1/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch deleted file mode 100644 index 3cf98acc85800b..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.2-01-net-phy-Add-driver-for-Motorcomm-yt8521-gigabit-ethernet.patch +++ /dev/null @@ -1,1724 +0,0 @@ -From 70479a40954cf353e87a486997a3477108c75aa9 Mon Sep 17 00:00:00 2001 -From: Frank -Date: Fri, 28 Oct 2022 17:26:21 +0800 -Subject: [PATCH] net: phy: Add driver for Motorcomm yt8521 gigabit ethernet - phy - -Add a driver for the motorcomm yt8521 gigabit ethernet phy. We have verified - the driver on StarFive VisionFive development board, which is developed by - Shanghai StarFive Technology Co., Ltd.. On the board, yt8521 gigabit ethernet - phy works in utp mode, RGMII interface, supports 1000M/100M/10M speeds, and - wol(magic package). - -Signed-off-by: Frank -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - MAINTAINERS | 1 + - drivers/net/phy/Kconfig | 2 +- - drivers/net/phy/motorcomm.c | 1635 ++++++++++++++++++++++++++++++++++- - 3 files changed, 1635 insertions(+), 3 deletions(-) - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -13971,6 +13971,7 @@ F: include/uapi/linux/meye.h - - MOTORCOMM PHY DRIVER - M: Peter Geis -+M: Frank - L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/phy/motorcomm.c ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -257,7 +257,7 @@ config MOTORCOMM_PHY - tristate "Motorcomm PHYs" - help - Enables support for Motorcomm network PHYs. -- Currently supports the YT8511 gigabit PHY. -+ Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs. - - config NATIONAL_PHY - tristate "National Semiconductor PHYs" ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1,15 +1,106 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* -- * Driver for Motorcomm PHYs -+ * Motorcomm 8511/8521 PHY driver. - * - * Author: Peter Geis -+ * Author: Frank - */ - -+#include - #include - #include - #include - - #define PHY_ID_YT8511 0x0000010a -+#define PHY_ID_YT8521 0x0000011A -+ -+/* YT8521 Register Overview -+ * UTP Register space | FIBER Register space -+ * ------------------------------------------------------------ -+ * | UTP MII | FIBER MII | -+ * | UTP MMD | | -+ * | UTP Extended | FIBER Extended | -+ * ------------------------------------------------------------ -+ * | Common Extended | -+ * ------------------------------------------------------------ -+ */ -+ -+/* 0x10 ~ 0x15 , 0x1E and 0x1F are common MII registers of yt phy */ -+ -+/* Specific Function Control Register */ -+#define YTPHY_SPECIFIC_FUNCTION_CONTROL_REG 0x10 -+ -+/* 2b00 Manual MDI configuration -+ * 2b01 Manual MDIX configuration -+ * 2b10 Reserved -+ * 2b11 Enable automatic crossover for all modes *default* -+ */ -+#define YTPHY_SFCR_MDI_CROSSOVER_MODE_MASK (BIT(6) | BIT(5)) -+#define YTPHY_SFCR_CROSSOVER_EN BIT(3) -+#define YTPHY_SFCR_SQE_TEST_EN BIT(2) -+#define YTPHY_SFCR_POLARITY_REVERSAL_EN BIT(1) -+#define YTPHY_SFCR_JABBER_DIS BIT(0) -+ -+/* Specific Status Register */ -+#define YTPHY_SPECIFIC_STATUS_REG 0x11 -+#define YTPHY_SSR_SPEED_MODE_OFFSET 14 -+ -+#define YTPHY_SSR_SPEED_MODE_MASK (BIT(15) | BIT(14)) -+#define YTPHY_SSR_SPEED_10M 0x0 -+#define YTPHY_SSR_SPEED_100M 0x1 -+#define YTPHY_SSR_SPEED_1000M 0x2 -+#define YTPHY_SSR_DUPLEX_OFFSET 13 -+#define YTPHY_SSR_DUPLEX BIT(13) -+#define YTPHY_SSR_PAGE_RECEIVED BIT(12) -+#define YTPHY_SSR_SPEED_DUPLEX_RESOLVED BIT(11) -+#define YTPHY_SSR_LINK BIT(10) -+#define YTPHY_SSR_MDIX_CROSSOVER BIT(6) -+#define YTPHY_SSR_DOWNGRADE BIT(5) -+#define YTPHY_SSR_TRANSMIT_PAUSE BIT(3) -+#define YTPHY_SSR_RECEIVE_PAUSE BIT(2) -+#define YTPHY_SSR_POLARITY BIT(1) -+#define YTPHY_SSR_JABBER BIT(0) -+ -+/* Interrupt enable Register */ -+#define YTPHY_INTERRUPT_ENABLE_REG 0x12 -+#define YTPHY_IER_WOL BIT(6) -+ -+/* Interrupt Status Register */ -+#define YTPHY_INTERRUPT_STATUS_REG 0x13 -+#define YTPHY_ISR_AUTONEG_ERR BIT(15) -+#define YTPHY_ISR_SPEED_CHANGED BIT(14) -+#define YTPHY_ISR_DUPLEX_CHANGED BIT(13) -+#define YTPHY_ISR_PAGE_RECEIVED BIT(12) -+#define YTPHY_ISR_LINK_FAILED BIT(11) -+#define YTPHY_ISR_LINK_SUCCESSED BIT(10) -+#define YTPHY_ISR_WOL BIT(6) -+#define YTPHY_ISR_WIRESPEED_DOWNGRADE BIT(5) -+#define YTPHY_ISR_SERDES_LINK_FAILED BIT(3) -+#define YTPHY_ISR_SERDES_LINK_SUCCESSED BIT(2) -+#define YTPHY_ISR_POLARITY_CHANGED BIT(1) -+#define YTPHY_ISR_JABBER_HAPPENED BIT(0) -+ -+/* Speed Auto Downgrade Control Register */ -+#define YTPHY_SPEED_AUTO_DOWNGRADE_CONTROL_REG 0x14 -+#define YTPHY_SADCR_SPEED_DOWNGRADE_EN BIT(5) -+ -+/* If these bits are set to 3, the PHY attempts five times ( 3(set value) + -+ * additional 2) before downgrading, default 0x3 -+ */ -+#define YTPHY_SADCR_SPEED_RETRY_LIMIT (0x3 << 2) -+ -+/* Rx Error Counter Register */ -+#define YTPHY_RX_ERROR_COUNTER_REG 0x15 -+ -+/* Extended Register's Address Offset Register */ -+#define YTPHY_PAGE_SELECT 0x1E -+ -+/* Extended Register's Data Register */ -+#define YTPHY_PAGE_DATA 0x1F -+ -+/* FIBER Auto-Negotiation link partner ability */ -+#define YTPHY_FLPA_PAUSE (0x3 << 7) -+#define YTPHY_FLPA_ASYM_PAUSE (0x2 << 7) - - #define YT8511_PAGE_SELECT 0x1e - #define YT8511_PAGE 0x1f -@@ -38,6 +129,352 @@ - #define YT8511_DELAY_FE_TX_EN (0xf << 12) - #define YT8511_DELAY_FE_TX_DIS (0x2 << 12) - -+/* Extended register is different from MMD Register and MII Register. -+ * We can use ytphy_read_ext/ytphy_write_ext/ytphy_modify_ext function to -+ * operate extended register. -+ * Extended Register start -+ */ -+ -+/* Phy gmii clock gating Register */ -+#define YT8521_CLOCK_GATING_REG 0xC -+#define YT8521_CGR_RX_CLK_EN BIT(12) -+ -+#define YT8521_EXTREG_SLEEP_CONTROL1_REG 0x27 -+#define YT8521_ESC1R_SLEEP_SW BIT(15) -+#define YT8521_ESC1R_PLLON_SLP BIT(14) -+ -+/* Phy fiber Link timer cfg2 Register */ -+#define YT8521_LINK_TIMER_CFG2_REG 0xA5 -+#define YT8521_LTCR_EN_AUTOSEN BIT(15) -+ -+/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers -+ * of yt8521 phy. There is no need to switch reg space when operating these -+ * registers. -+ */ -+ -+#define YT8521_REG_SPACE_SELECT_REG 0xA000 -+#define YT8521_RSSR_SPACE_MASK BIT(1) -+#define YT8521_RSSR_FIBER_SPACE (0x1 << 1) -+#define YT8521_RSSR_UTP_SPACE (0x0 << 1) -+#define YT8521_RSSR_TO_BE_ARBITRATED (0xFF) -+ -+#define YT8521_CHIP_CONFIG_REG 0xA001 -+#define YT8521_CCR_SW_RST BIT(15) -+ -+#define YT8521_CCR_MODE_SEL_MASK (BIT(2) | BIT(1) | BIT(0)) -+#define YT8521_CCR_MODE_UTP_TO_RGMII 0 -+#define YT8521_CCR_MODE_FIBER_TO_RGMII 1 -+#define YT8521_CCR_MODE_UTP_FIBER_TO_RGMII 2 -+#define YT8521_CCR_MODE_UTP_TO_SGMII 3 -+#define YT8521_CCR_MODE_SGPHY_TO_RGMAC 4 -+#define YT8521_CCR_MODE_SGMAC_TO_RGPHY 5 -+#define YT8521_CCR_MODE_UTP_TO_FIBER_AUTO 6 -+#define YT8521_CCR_MODE_UTP_TO_FIBER_FORCE 7 -+ -+/* 3 phy polling modes,poll mode combines utp and fiber mode*/ -+#define YT8521_MODE_FIBER 0x1 -+#define YT8521_MODE_UTP 0x2 -+#define YT8521_MODE_POLL 0x3 -+ -+#define YT8521_RGMII_CONFIG1_REG 0xA003 -+ -+/* TX Gig-E Delay is bits 3:0, default 0x1 -+ * TX Fast-E Delay is bits 7:4, default 0xf -+ * RX Delay is bits 13:10, default 0x0 -+ * Delay = 150ps * N -+ * On = 2250ps, off = 0ps -+ */ -+#define YT8521_RC1R_RX_DELAY_MASK (0xF << 10) -+#define YT8521_RC1R_RX_DELAY_EN (0xF << 10) -+#define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10) -+#define YT8521_RC1R_FE_TX_DELAY_MASK (0xF << 4) -+#define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4) -+#define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4) -+#define YT8521_RC1R_GE_TX_DELAY_MASK (0xF << 0) -+#define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0) -+#define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0) -+ -+#define YTPHY_MISC_CONFIG_REG 0xA006 -+#define YTPHY_MCR_FIBER_SPEED_MASK BIT(0) -+#define YTPHY_MCR_FIBER_1000BX (0x1 << 0) -+#define YTPHY_MCR_FIBER_100FX (0x0 << 0) -+ -+/* WOL MAC ADDR: MACADDR2(highest), MACADDR1(middle), MACADDR0(lowest) */ -+#define YTPHY_WOL_MACADDR2_REG 0xA007 -+#define YTPHY_WOL_MACADDR1_REG 0xA008 -+#define YTPHY_WOL_MACADDR0_REG 0xA009 -+ -+#define YTPHY_WOL_CONFIG_REG 0xA00A -+#define YTPHY_WCR_INTR_SEL BIT(6) -+#define YTPHY_WCR_ENABLE BIT(3) -+ -+/* 2b00 84ms -+ * 2b01 168ms *default* -+ * 2b10 336ms -+ * 2b11 672ms -+ */ -+#define YTPHY_WCR_PULSE_WIDTH_MASK (BIT(2) | BIT(1)) -+#define YTPHY_WCR_PULSE_WIDTH_672MS (BIT(2) | BIT(1)) -+ -+/* 1b0 Interrupt and WOL events is level triggered and active LOW *default* -+ * 1b1 Interrupt and WOL events is pulse triggered and active LOW -+ */ -+#define YTPHY_WCR_TYPE_PULSE BIT(0) -+ -+/* Extended Register end */ -+ -+struct yt8521_priv { -+ /* combo_advertising is used for case of YT8521 in combo mode, -+ * this means that yt8521 may work in utp or fiber mode which depends -+ * on which media is connected (YT8521_RSSR_TO_BE_ARBITRATED). -+ */ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(combo_advertising); -+ -+ /* YT8521_MODE_FIBER / YT8521_MODE_UTP / YT8521_MODE_POLL*/ -+ u8 polling_mode; -+ u8 strap_mode; /* 8 working modes */ -+ /* current reg page of yt8521 phy: -+ * YT8521_RSSR_UTP_SPACE -+ * YT8521_RSSR_FIBER_SPACE -+ * YT8521_RSSR_TO_BE_ARBITRATED -+ */ -+ u8 reg_page; -+}; -+ -+/** -+ * ytphy_read_ext() - read a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to read -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns the value of regnum reg or negative error code -+ */ -+static int ytphy_read_ext(struct phy_device *phydev, u16 regnum) -+{ -+ int ret; -+ -+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum); -+ if (ret < 0) -+ return ret; -+ -+ return __phy_read(phydev, YTPHY_PAGE_DATA); -+} -+ -+/** -+ * ytphy_read_ext_with_lock() - read a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to read -+ * -+ * returns the value of regnum reg or negative error code -+ */ -+static int ytphy_read_ext_with_lock(struct phy_device *phydev, u16 regnum) -+{ -+ int ret; -+ -+ phy_lock_mdio_bus(phydev); -+ ret = ytphy_read_ext(phydev, regnum); -+ phy_unlock_mdio_bus(phydev); -+ -+ return ret; -+} -+ -+/** -+ * ytphy_write_ext() - write a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to write -+ * @val: value to write to @regnum -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative error code -+ */ -+static int ytphy_write_ext(struct phy_device *phydev, u16 regnum, u16 val) -+{ -+ int ret; -+ -+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum); -+ if (ret < 0) -+ return ret; -+ -+ return __phy_write(phydev, YTPHY_PAGE_DATA, val); -+} -+ -+/** -+ * ytphy_write_ext_with_lock() - write a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to write -+ * @val: value to write to @regnum -+ * -+ * returns 0 or negative error code -+ */ -+static int ytphy_write_ext_with_lock(struct phy_device *phydev, u16 regnum, -+ u16 val) -+{ -+ int ret; -+ -+ phy_lock_mdio_bus(phydev); -+ ret = ytphy_write_ext(phydev, regnum, val); -+ phy_unlock_mdio_bus(phydev); -+ -+ return ret; -+} -+ -+/** -+ * ytphy_modify_ext() - bits modify a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to write -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ * -+ * NOTE: Convenience function which allows a PHY's extended register to be -+ * modified as new register value = (old register value & ~mask) | set. -+ * The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative error code -+ */ -+static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask, -+ u16 set) -+{ -+ int ret; -+ -+ ret = __phy_write(phydev, YTPHY_PAGE_SELECT, regnum); -+ if (ret < 0) -+ return ret; -+ -+ return __phy_modify(phydev, YTPHY_PAGE_DATA, mask, set); -+} -+ -+/** -+ * ytphy_modify_ext_with_lock() - bits modify a PHY's extended register -+ * @phydev: a pointer to a &struct phy_device -+ * @regnum: register number to write -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ * -+ * NOTE: Convenience function which allows a PHY's extended register to be -+ * modified as new register value = (old register value & ~mask) | set. -+ * -+ * returns 0 or negative error code -+ */ -+static int ytphy_modify_ext_with_lock(struct phy_device *phydev, u16 regnum, -+ u16 mask, u16 set) -+{ -+ int ret; -+ -+ phy_lock_mdio_bus(phydev); -+ ret = ytphy_modify_ext(phydev, regnum, mask, set); -+ phy_unlock_mdio_bus(phydev); -+ -+ return ret; -+} -+ -+/** -+ * ytphy_get_wol() - report whether wake-on-lan is enabled -+ * @phydev: a pointer to a &struct phy_device -+ * @wol: a pointer to a &struct ethtool_wolinfo -+ * -+ * NOTE: YTPHY_WOL_CONFIG_REG is common ext reg. -+ */ -+static void ytphy_get_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol) -+{ -+ int wol_config; -+ -+ wol->supported = WAKE_MAGIC; -+ wol->wolopts = 0; -+ -+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG); -+ if (wol_config < 0) -+ return; -+ -+ if (wol_config & YTPHY_WCR_ENABLE) -+ wol->wolopts |= WAKE_MAGIC; -+} -+ -+/** -+ * ytphy_set_wol() - turn wake-on-lan on or off -+ * @phydev: a pointer to a &struct phy_device -+ * @wol: a pointer to a &struct ethtool_wolinfo -+ * -+ * NOTE: YTPHY_WOL_CONFIG_REG, YTPHY_WOL_MACADDR2_REG, YTPHY_WOL_MACADDR1_REG -+ * and YTPHY_WOL_MACADDR0_REG are common ext reg. The -+ * YTPHY_INTERRUPT_ENABLE_REG of UTP is special, fiber also use this register. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol) -+{ -+ struct net_device *p_attached_dev; -+ const u16 mac_addr_reg[] = { -+ YTPHY_WOL_MACADDR2_REG, -+ YTPHY_WOL_MACADDR1_REG, -+ YTPHY_WOL_MACADDR0_REG, -+ }; -+ const u8 *mac_addr; -+ int old_page; -+ int ret = 0; -+ u16 mask; -+ u16 val; -+ u8 i; -+ -+ if (wol->wolopts & WAKE_MAGIC) { -+ p_attached_dev = phydev->attached_dev; -+ if (!p_attached_dev) -+ return -ENODEV; -+ -+ mac_addr = (const u8 *)p_attached_dev->dev_addr; -+ if (!is_valid_ether_addr(mac_addr)) -+ return -EINVAL; -+ -+ /* lock mdio bus then switch to utp reg space */ -+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ /* Store the device address for the magic packet */ -+ for (i = 0; i < 3; i++) { -+ ret = ytphy_write_ext(phydev, mac_addr_reg[i], -+ ((mac_addr[i * 2] << 8)) | -+ (mac_addr[i * 2 + 1])); -+ if (ret < 0) -+ goto err_restore_page; -+ } -+ -+ /* Enable WOL feature */ -+ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL; -+ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; -+ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS; -+ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, val); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ /* Enable WOL interrupt */ -+ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0, -+ YTPHY_IER_WOL); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ } else { -+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ /* Disable WOL feature */ -+ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; -+ ret = ytphy_modify_ext(phydev, YTPHY_WOL_CONFIG_REG, mask, 0); -+ -+ /* Disable WOL interrupt */ -+ ret = __phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, -+ YTPHY_IER_WOL, 0); -+ if (ret < 0) -+ goto err_restore_page; -+ } -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ - static int yt8511_read_page(struct phy_device *phydev) - { - return __phy_read(phydev, YT8511_PAGE_SELECT); -@@ -111,6 +548,1181 @@ err_restore_page: - return phy_restore_page(phydev, oldpage, ret); - } - -+/** -+ * yt8521_read_page() - read reg page -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns current reg space of yt8521 (YT8521_RSSR_FIBER_SPACE/ -+ * YT8521_RSSR_UTP_SPACE) or negative errno code -+ */ -+static int yt8521_read_page(struct phy_device *phydev) -+{ -+ int old_page; -+ -+ old_page = ytphy_read_ext(phydev, YT8521_REG_SPACE_SELECT_REG); -+ if (old_page < 0) -+ return old_page; -+ -+ if ((old_page & YT8521_RSSR_SPACE_MASK) == YT8521_RSSR_FIBER_SPACE) -+ return YT8521_RSSR_FIBER_SPACE; -+ -+ return YT8521_RSSR_UTP_SPACE; -+}; -+ -+/** -+ * yt8521_write_page() - write reg page -+ * @phydev: a pointer to a &struct phy_device -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to write. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_write_page(struct phy_device *phydev, int page) -+{ -+ int mask = YT8521_RSSR_SPACE_MASK; -+ int set; -+ -+ if ((page & YT8521_RSSR_SPACE_MASK) == YT8521_RSSR_FIBER_SPACE) -+ set = YT8521_RSSR_FIBER_SPACE; -+ else -+ set = YT8521_RSSR_UTP_SPACE; -+ -+ return ytphy_modify_ext(phydev, YT8521_REG_SPACE_SELECT_REG, mask, set); -+}; -+ -+/** -+ * yt8521_probe() - read chip config then set suitable polling_mode -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct yt8521_priv *priv; -+ int chip_config; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ phydev->priv = priv; -+ -+ chip_config = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG); -+ if (chip_config < 0) -+ return chip_config; -+ -+ priv->strap_mode = chip_config & YT8521_CCR_MODE_SEL_MASK; -+ switch (priv->strap_mode) { -+ case YT8521_CCR_MODE_FIBER_TO_RGMII: -+ case YT8521_CCR_MODE_SGPHY_TO_RGMAC: -+ case YT8521_CCR_MODE_SGMAC_TO_RGPHY: -+ priv->polling_mode = YT8521_MODE_FIBER; -+ priv->reg_page = YT8521_RSSR_FIBER_SPACE; -+ phydev->port = PORT_FIBRE; -+ break; -+ case YT8521_CCR_MODE_UTP_FIBER_TO_RGMII: -+ case YT8521_CCR_MODE_UTP_TO_FIBER_AUTO: -+ case YT8521_CCR_MODE_UTP_TO_FIBER_FORCE: -+ priv->polling_mode = YT8521_MODE_POLL; -+ priv->reg_page = YT8521_RSSR_TO_BE_ARBITRATED; -+ phydev->port = PORT_NONE; -+ break; -+ case YT8521_CCR_MODE_UTP_TO_SGMII: -+ case YT8521_CCR_MODE_UTP_TO_RGMII: -+ priv->polling_mode = YT8521_MODE_UTP; -+ priv->reg_page = YT8521_RSSR_UTP_SPACE; -+ phydev->port = PORT_TP; -+ break; -+ } -+ /* set default reg space */ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ ret = ytphy_write_ext_with_lock(phydev, -+ YT8521_REG_SPACE_SELECT_REG, -+ priv->reg_page); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/** -+ * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_utp_read_lpa(struct phy_device *phydev) -+{ -+ int lpa, lpagb; -+ -+ if (phydev->autoneg == AUTONEG_ENABLE) { -+ if (!phydev->autoneg_complete) { -+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, -+ 0); -+ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0); -+ return 0; -+ } -+ -+ if (phydev->is_gigabit_capable) { -+ lpagb = __phy_read(phydev, MII_STAT1000); -+ if (lpagb < 0) -+ return lpagb; -+ -+ if (lpagb & LPA_1000MSFAIL) { -+ int adv = __phy_read(phydev, MII_CTRL1000); -+ -+ if (adv < 0) -+ return adv; -+ -+ if (adv & CTL1000_ENABLE_MASTER) -+ phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); -+ else -+ phydev_err(phydev, "Master/Slave resolution failed\n"); -+ return -ENOLINK; -+ } -+ -+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, -+ lpagb); -+ } -+ -+ lpa = __phy_read(phydev, MII_LPA); -+ if (lpa < 0) -+ return lpa; -+ -+ mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa); -+ } else { -+ linkmode_zero(phydev->lp_advertising); -+ } -+ -+ return 0; -+} -+ -+/** -+ * yt8521_adjust_status() - update speed and duplex to phydev. when in fiber -+ * mode, adjust speed and duplex. -+ * @phydev: a pointer to a &struct phy_device -+ * @status: yt8521 status read from YTPHY_SPECIFIC_STATUS_REG -+ * @is_utp: false(yt8521 work in fiber mode) or true(yt8521 work in utp mode) -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 -+ */ -+static int yt8521_adjust_status(struct phy_device *phydev, int status, -+ bool is_utp) -+{ -+ int speed_mode, duplex; -+ int speed; -+ int err; -+ int lpa; -+ -+ if (is_utp) -+ duplex = (status & YTPHY_SSR_DUPLEX) >> YTPHY_SSR_DUPLEX_OFFSET; -+ else -+ duplex = DUPLEX_FULL; /* for fiber, it always DUPLEX_FULL */ -+ -+ speed_mode = (status & YTPHY_SSR_SPEED_MODE_MASK) >> -+ YTPHY_SSR_SPEED_MODE_OFFSET; -+ -+ switch (speed_mode) { -+ case YTPHY_SSR_SPEED_10M: -+ if (is_utp) -+ speed = SPEED_10; -+ else -+ /* for fiber, it will never run here, default to -+ * SPEED_UNKNOWN -+ */ -+ speed = SPEED_UNKNOWN; -+ break; -+ case YTPHY_SSR_SPEED_100M: -+ speed = SPEED_100; -+ break; -+ case YTPHY_SSR_SPEED_1000M: -+ speed = SPEED_1000; -+ break; -+ default: -+ speed = SPEED_UNKNOWN; -+ break; -+ } -+ -+ phydev->speed = speed; -+ phydev->duplex = duplex; -+ -+ if (is_utp) { -+ err = ytphy_utp_read_lpa(phydev); -+ if (err < 0) -+ return err; -+ -+ phy_resolve_aneg_pause(phydev); -+ } else { -+ lpa = __phy_read(phydev, MII_LPA); -+ if (lpa < 0) -+ return lpa; -+ -+ /* only support 1000baseX Full */ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, -+ phydev->lp_advertising, lpa & LPA_1000XFULL); -+ -+ if (!(lpa & YTPHY_FLPA_PAUSE)) { -+ phydev->pause = 0; -+ phydev->asym_pause = 0; -+ } else if ((lpa & YTPHY_FLPA_ASYM_PAUSE)) { -+ phydev->pause = 1; -+ phydev->asym_pause = 1; -+ } else { -+ phydev->pause = 1; -+ phydev->asym_pause = 0; -+ } -+ } -+ -+ return 0; -+} -+ -+/** -+ * yt8521_read_status_paged() - determines the speed and duplex of one page -+ * @phydev: a pointer to a &struct phy_device -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to -+ * operate. -+ * -+ * returns 1 (utp or fiber link),0 (no link) or negative errno code -+ */ -+static int yt8521_read_status_paged(struct phy_device *phydev, int page) -+{ -+ int fiber_latch_val; -+ int fiber_curr_val; -+ int old_page; -+ int ret = 0; -+ int status; -+ int link; -+ -+ linkmode_zero(phydev->lp_advertising); -+ phydev->duplex = DUPLEX_UNKNOWN; -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->asym_pause = 0; -+ phydev->pause = 0; -+ -+ /* YT8521 has two reg space (utp/fiber) for linkup with utp/fiber -+ * respectively. but for utp/fiber combo mode, reg space should be -+ * arbitrated based on media priority. by default, utp takes -+ * priority. reg space should be properly set before read -+ * YTPHY_SPECIFIC_STATUS_REG. -+ */ -+ -+ page &= YT8521_RSSR_SPACE_MASK; -+ old_page = phy_select_page(phydev, page); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ /* Read YTPHY_SPECIFIC_STATUS_REG, which indicates the speed and duplex -+ * of the PHY is actually using. -+ */ -+ ret = __phy_read(phydev, YTPHY_SPECIFIC_STATUS_REG); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ status = ret; -+ link = !!(status & YTPHY_SSR_LINK); -+ -+ /* When PHY is in fiber mode, speed transferred from 1000Mbps to -+ * 100Mbps,there is not link down from YTPHY_SPECIFIC_STATUS_REG, so -+ * we need check MII_BMSR to identify such case. -+ */ -+ if (page == YT8521_RSSR_FIBER_SPACE) { -+ ret = __phy_read(phydev, MII_BMSR); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ fiber_latch_val = ret; -+ ret = __phy_read(phydev, MII_BMSR); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ fiber_curr_val = ret; -+ if (link && fiber_latch_val != fiber_curr_val) { -+ link = 0; -+ phydev_info(phydev, -+ "%s, fiber link down detect, latch = %04x, curr = %04x\n", -+ __func__, fiber_latch_val, fiber_curr_val); -+ } -+ } else { -+ /* Read autonegotiation status */ -+ ret = __phy_read(phydev, MII_BMSR); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ phydev->autoneg_complete = ret & BMSR_ANEGCOMPLETE ? 1 : 0; -+ } -+ -+ if (link) { -+ if (page == YT8521_RSSR_UTP_SPACE) -+ yt8521_adjust_status(phydev, status, true); -+ else -+ yt8521_adjust_status(phydev, status, false); -+ } -+ return phy_restore_page(phydev, old_page, link); -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_read_status() - determines the negotiated speed and duplex -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_read_status(struct phy_device *phydev) -+{ -+ struct yt8521_priv *priv = phydev->priv; -+ int link_fiber = 0; -+ int link_utp; -+ int link; -+ int ret; -+ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ link = yt8521_read_status_paged(phydev, priv->reg_page); -+ if (link < 0) -+ return link; -+ } else { -+ /* when page is YT8521_RSSR_TO_BE_ARBITRATED, arbitration is -+ * needed. by default, utp is higher priority. -+ */ -+ -+ link_utp = yt8521_read_status_paged(phydev, -+ YT8521_RSSR_UTP_SPACE); -+ if (link_utp < 0) -+ return link_utp; -+ -+ if (!link_utp) { -+ link_fiber = yt8521_read_status_paged(phydev, -+ YT8521_RSSR_FIBER_SPACE); -+ if (link_fiber < 0) -+ return link_fiber; -+ } -+ -+ link = link_utp || link_fiber; -+ } -+ -+ if (link) { -+ if (phydev->link == 0) { -+ /* arbitrate reg space based on linkup media type. */ -+ if (priv->polling_mode == YT8521_MODE_POLL && -+ priv->reg_page == YT8521_RSSR_TO_BE_ARBITRATED) { -+ if (link_fiber) -+ priv->reg_page = -+ YT8521_RSSR_FIBER_SPACE; -+ else -+ priv->reg_page = YT8521_RSSR_UTP_SPACE; -+ -+ ret = ytphy_write_ext_with_lock(phydev, -+ YT8521_REG_SPACE_SELECT_REG, -+ priv->reg_page); -+ if (ret < 0) -+ return ret; -+ -+ phydev->port = link_fiber ? PORT_FIBRE : PORT_TP; -+ -+ phydev_info(phydev, "%s, link up, media: %s\n", -+ __func__, -+ (phydev->port == PORT_TP) ? -+ "UTP" : "Fiber"); -+ } -+ } -+ phydev->link = 1; -+ } else { -+ if (phydev->link == 1) { -+ phydev_info(phydev, "%s, link down, media: %s\n", -+ __func__, (phydev->port == PORT_TP) ? -+ "UTP" : "Fiber"); -+ -+ /* When in YT8521_MODE_POLL mode, need prepare for next -+ * arbitration. -+ */ -+ if (priv->polling_mode == YT8521_MODE_POLL) { -+ priv->reg_page = YT8521_RSSR_TO_BE_ARBITRATED; -+ phydev->port = PORT_NONE; -+ } -+ } -+ -+ phydev->link = 0; -+ } -+ -+ return 0; -+} -+ -+/** -+ * yt8521_modify_bmcr_paged - bits modify a PHY's BMCR register of one page -+ * @phydev: the phy_device struct -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to operate -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ * -+ * NOTE: Convenience function which allows a PHY's BMCR register to be -+ * modified as new register value = (old register value & ~mask) | set. -+ * YT8521 has two space (utp/fiber) and three mode (utp/fiber/poll), each space -+ * has MII_BMCR. poll mode combines utp and faber,so need do both. -+ * If it is reset, it will wait for completion. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_modify_bmcr_paged(struct phy_device *phydev, int page, -+ u16 mask, u16 set) -+{ -+ int max_cnt = 500; /* the max wait time of reset ~ 500 ms */ -+ int old_page; -+ int ret = 0; -+ -+ old_page = phy_select_page(phydev, page & YT8521_RSSR_SPACE_MASK); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ ret = __phy_modify(phydev, MII_BMCR, mask, set); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ /* If it is reset, need to wait for the reset to complete */ -+ if (set == BMCR_RESET) { -+ while (max_cnt--) { -+ usleep_range(1000, 1100); -+ ret = __phy_read(phydev, MII_BMCR); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ if (!(ret & BMCR_RESET)) -+ return phy_restore_page(phydev, old_page, 0); -+ } -+ } -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_modify_utp_fiber_bmcr - bits modify a PHY's BMCR register -+ * @phydev: the phy_device struct -+ * @mask: bit mask of bits to clear -+ * @set: bit mask of bits to set -+ * -+ * NOTE: Convenience function which allows a PHY's BMCR register to be -+ * modified as new register value = (old register value & ~mask) | set. -+ * YT8521 has two space (utp/fiber) and three mode (utp/fiber/poll), each space -+ * has MII_BMCR. poll mode combines utp and faber,so need do both. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_modify_utp_fiber_bmcr(struct phy_device *phydev, u16 mask, -+ u16 set) -+{ -+ struct yt8521_priv *priv = phydev->priv; -+ int ret; -+ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ ret = yt8521_modify_bmcr_paged(phydev, priv->reg_page, mask, -+ set); -+ if (ret < 0) -+ return ret; -+ } else { -+ ret = yt8521_modify_bmcr_paged(phydev, YT8521_RSSR_UTP_SPACE, -+ mask, set); -+ if (ret < 0) -+ return ret; -+ -+ ret = yt8521_modify_bmcr_paged(phydev, YT8521_RSSR_FIBER_SPACE, -+ mask, set); -+ if (ret < 0) -+ return ret; -+ } -+ return 0; -+} -+ -+/** -+ * yt8521_soft_reset() - called to issue a PHY software reset -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_soft_reset(struct phy_device *phydev) -+{ -+ return yt8521_modify_utp_fiber_bmcr(phydev, 0, BMCR_RESET); -+} -+ -+/** -+ * yt8521_suspend() - suspend the hardware -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_suspend(struct phy_device *phydev) -+{ -+ int wol_config; -+ -+ /* YTPHY_WOL_CONFIG_REG is common ext reg */ -+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG); -+ if (wol_config < 0) -+ return wol_config; -+ -+ /* if wol enable, do nothing */ -+ if (wol_config & YTPHY_WCR_ENABLE) -+ return 0; -+ -+ return yt8521_modify_utp_fiber_bmcr(phydev, 0, BMCR_PDOWN); -+} -+ -+/** -+ * yt8521_resume() - resume the hardware -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_resume(struct phy_device *phydev) -+{ -+ int ret; -+ int wol_config; -+ -+ /* disable auto sleep */ -+ ret = ytphy_modify_ext_with_lock(phydev, -+ YT8521_EXTREG_SLEEP_CONTROL1_REG, -+ YT8521_ESC1R_SLEEP_SW, 0); -+ if (ret < 0) -+ return ret; -+ -+ wol_config = ytphy_read_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG); -+ if (wol_config < 0) -+ return wol_config; -+ -+ /* if wol enable, do nothing */ -+ if (wol_config & YTPHY_WCR_ENABLE) -+ return 0; -+ -+ return yt8521_modify_utp_fiber_bmcr(phydev, BMCR_PDOWN, 0); -+} -+ -+/** -+ * yt8521_config_init() - called to initialize the PHY -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_config_init(struct phy_device *phydev) -+{ -+ int old_page; -+ int ret = 0; -+ u16 val; -+ -+ old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS; -+ val |= YT8521_RC1R_RX_DELAY_DIS; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS; -+ val |= YT8521_RC1R_RX_DELAY_EN; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN; -+ val |= YT8521_RC1R_RX_DELAY_DIS; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN; -+ val |= YT8521_RC1R_RX_DELAY_EN; -+ break; -+ case PHY_INTERFACE_MODE_SGMII: -+ break; -+ default: /* do not support other modes */ -+ ret = -EOPNOTSUPP; -+ goto err_restore_page; -+ } -+ -+ /* set rgmii delay mode */ -+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII) { -+ ret = ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, -+ (YT8521_RC1R_RX_DELAY_MASK | -+ YT8521_RC1R_FE_TX_DELAY_MASK | -+ YT8521_RC1R_GE_TX_DELAY_MASK), -+ val); -+ if (ret < 0) -+ goto err_restore_page; -+ } -+ -+ /* disable auto sleep */ -+ ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG, -+ YT8521_ESC1R_SLEEP_SW, 0); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ /* enable RXC clock when no wire plug */ -+ ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG, -+ YT8521_CGR_RX_CLK_EN, 0); -+ if (ret < 0) -+ goto err_restore_page; -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_prepare_fiber_features() - A small helper function that setup -+ * fiber's features. -+ * @phydev: a pointer to a &struct phy_device -+ * @dst: a pointer to store fiber's features -+ */ -+static void yt8521_prepare_fiber_features(struct phy_device *phydev, -+ unsigned long *dst) -+{ -+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, dst); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, dst); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, dst); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, dst); -+} -+ -+/** -+ * yt8521_fiber_setup_forced - configures/forces speed from @phydev -+ * @phydev: target phy_device struct -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_fiber_setup_forced(struct phy_device *phydev) -+{ -+ u16 val; -+ int ret; -+ -+ if (phydev->speed == SPEED_1000) -+ val = YTPHY_MCR_FIBER_1000BX; -+ else if (phydev->speed == SPEED_100) -+ val = YTPHY_MCR_FIBER_100FX; -+ else -+ return -EINVAL; -+ -+ ret = __phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0); -+ if (ret < 0) -+ return ret; -+ -+ /* disable Fiber auto sensing */ -+ ret = ytphy_modify_ext(phydev, YT8521_LINK_TIMER_CFG2_REG, -+ YT8521_LTCR_EN_AUTOSEN, 0); -+ if (ret < 0) -+ return ret; -+ -+ ret = ytphy_modify_ext(phydev, YTPHY_MISC_CONFIG_REG, -+ YTPHY_MCR_FIBER_SPEED_MASK, val); -+ if (ret < 0) -+ return ret; -+ -+ return ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG, -+ YT8521_CCR_SW_RST, 0); -+} -+ -+/** -+ * ytphy_check_and_restart_aneg - Enable and restart auto-negotiation -+ * @phydev: target phy_device struct -+ * @restart: whether aneg restart is requested -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_check_and_restart_aneg(struct phy_device *phydev, bool restart) -+{ -+ int ret; -+ -+ if (!restart) { -+ /* Advertisement hasn't changed, but maybe aneg was never on to -+ * begin with? Or maybe phy was isolated? -+ */ -+ ret = __phy_read(phydev, MII_BMCR); -+ if (ret < 0) -+ return ret; -+ -+ if (!(ret & BMCR_ANENABLE) || (ret & BMCR_ISOLATE)) -+ restart = true; -+ } -+ /* Enable and Restart Autonegotiation -+ * Don't isolate the PHY if we're negotiating -+ */ -+ if (restart) -+ return __phy_modify(phydev, MII_BMCR, BMCR_ISOLATE, -+ BMCR_ANENABLE | BMCR_ANRESTART); -+ -+ return 0; -+} -+ -+/** -+ * yt8521_fiber_config_aneg - restart auto-negotiation or write -+ * YTPHY_MISC_CONFIG_REG. -+ * @phydev: target phy_device struct -+ * -+ * NOTE:The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_fiber_config_aneg(struct phy_device *phydev) -+{ -+ int err, changed = 0; -+ int bmcr; -+ u16 adv; -+ -+ if (phydev->autoneg != AUTONEG_ENABLE) -+ return yt8521_fiber_setup_forced(phydev); -+ -+ /* enable Fiber auto sensing */ -+ err = ytphy_modify_ext(phydev, YT8521_LINK_TIMER_CFG2_REG, -+ 0, YT8521_LTCR_EN_AUTOSEN); -+ if (err < 0) -+ return err; -+ -+ err = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG, -+ YT8521_CCR_SW_RST, 0); -+ if (err < 0) -+ return err; -+ -+ bmcr = __phy_read(phydev, MII_BMCR); -+ if (bmcr < 0) -+ return bmcr; -+ -+ /* When it is coming from fiber forced mode, add bmcr power down -+ * and power up to let aneg work fine. -+ */ -+ if (!(bmcr & BMCR_ANENABLE)) { -+ __phy_modify(phydev, MII_BMCR, 0, BMCR_PDOWN); -+ usleep_range(1000, 1100); -+ __phy_modify(phydev, MII_BMCR, BMCR_PDOWN, 0); -+ } -+ -+ adv = linkmode_adv_to_mii_adv_x(phydev->advertising, -+ ETHTOOL_LINK_MODE_1000baseX_Full_BIT); -+ -+ /* Setup fiber advertisement */ -+ err = __phy_modify_changed(phydev, MII_ADVERTISE, -+ ADVERTISE_1000XHALF | ADVERTISE_1000XFULL | -+ ADVERTISE_1000XPAUSE | -+ ADVERTISE_1000XPSE_ASYM, -+ adv); -+ if (err < 0) -+ return err; -+ -+ if (err > 0) -+ changed = 1; -+ -+ return ytphy_check_and_restart_aneg(phydev, changed); -+} -+ -+/** -+ * ytphy_setup_master_slave -+ * @phydev: target phy_device struct -+ * -+ * NOTE: The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_setup_master_slave(struct phy_device *phydev) -+{ -+ u16 ctl = 0; -+ -+ if (!phydev->is_gigabit_capable) -+ return 0; -+ -+ switch (phydev->master_slave_set) { -+ case MASTER_SLAVE_CFG_MASTER_PREFERRED: -+ ctl |= CTL1000_PREFER_MASTER; -+ break; -+ case MASTER_SLAVE_CFG_SLAVE_PREFERRED: -+ break; -+ case MASTER_SLAVE_CFG_MASTER_FORCE: -+ ctl |= CTL1000_AS_MASTER; -+ fallthrough; -+ case MASTER_SLAVE_CFG_SLAVE_FORCE: -+ ctl |= CTL1000_ENABLE_MASTER; -+ break; -+ case MASTER_SLAVE_CFG_UNKNOWN: -+ case MASTER_SLAVE_CFG_UNSUPPORTED: -+ return 0; -+ default: -+ phydev_warn(phydev, "Unsupported Master/Slave mode\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ return __phy_modify_changed(phydev, MII_CTRL1000, -+ (CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER | -+ CTL1000_PREFER_MASTER), ctl); -+} -+ -+/** -+ * ytphy_utp_config_advert - sanitize and advertise auto-negotiation parameters -+ * @phydev: target phy_device struct -+ * -+ * NOTE: Writes MII_ADVERTISE with the appropriate values, -+ * after sanitizing the values to make sure we only advertise -+ * what is supported. Returns < 0 on error, 0 if the PHY's advertisement -+ * hasn't changed, and > 0 if it has changed. -+ * The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_utp_config_advert(struct phy_device *phydev) -+{ -+ int err, bmsr, changed = 0; -+ u32 adv; -+ -+ /* Only allow advertising what this PHY supports */ -+ linkmode_and(phydev->advertising, phydev->advertising, -+ phydev->supported); -+ -+ adv = linkmode_adv_to_mii_adv_t(phydev->advertising); -+ -+ /* Setup standard advertisement */ -+ err = __phy_modify_changed(phydev, MII_ADVERTISE, -+ ADVERTISE_ALL | ADVERTISE_100BASE4 | -+ ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM, -+ adv); -+ if (err < 0) -+ return err; -+ if (err > 0) -+ changed = 1; -+ -+ bmsr = __phy_read(phydev, MII_BMSR); -+ if (bmsr < 0) -+ return bmsr; -+ -+ /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all -+ * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a -+ * logical 1. -+ */ -+ if (!(bmsr & BMSR_ESTATEN)) -+ return changed; -+ -+ adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); -+ -+ err = __phy_modify_changed(phydev, MII_CTRL1000, -+ ADVERTISE_1000FULL | ADVERTISE_1000HALF, -+ adv); -+ if (err < 0) -+ return err; -+ if (err > 0) -+ changed = 1; -+ -+ return changed; -+} -+ -+/** -+ * ytphy_utp_config_aneg - restart auto-negotiation or write BMCR -+ * @phydev: target phy_device struct -+ * @changed: whether autoneg is requested -+ * -+ * NOTE: If auto-negotiation is enabled, we configure the -+ * advertising, and then restart auto-negotiation. If it is not -+ * enabled, then we write the BMCR. -+ * The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_utp_config_aneg(struct phy_device *phydev, bool changed) -+{ -+ int err; -+ u16 ctl; -+ -+ err = ytphy_setup_master_slave(phydev); -+ if (err < 0) -+ return err; -+ else if (err) -+ changed = true; -+ -+ if (phydev->autoneg != AUTONEG_ENABLE) { -+ /* configures/forces speed/duplex from @phydev */ -+ -+ ctl = mii_bmcr_encode_fixed(phydev->speed, phydev->duplex); -+ -+ return __phy_modify(phydev, MII_BMCR, ~(BMCR_LOOPBACK | -+ BMCR_ISOLATE | BMCR_PDOWN), ctl); -+ } -+ -+ err = ytphy_utp_config_advert(phydev); -+ if (err < 0) /* error */ -+ return err; -+ else if (err) -+ changed = true; -+ -+ return ytphy_check_and_restart_aneg(phydev, changed); -+} -+ -+/** -+ * yt8521_config_aneg_paged() - switch reg space then call genphy_config_aneg -+ * of one page -+ * @phydev: a pointer to a &struct phy_device -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to -+ * operate. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_config_aneg_paged(struct phy_device *phydev, int page) -+{ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(fiber_supported); -+ struct yt8521_priv *priv = phydev->priv; -+ int old_page; -+ int ret = 0; -+ -+ page &= YT8521_RSSR_SPACE_MASK; -+ -+ old_page = phy_select_page(phydev, page); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ /* If reg_page is YT8521_RSSR_TO_BE_ARBITRATED, -+ * phydev->advertising should be updated. -+ */ -+ if (priv->reg_page == YT8521_RSSR_TO_BE_ARBITRATED) { -+ linkmode_zero(fiber_supported); -+ yt8521_prepare_fiber_features(phydev, fiber_supported); -+ -+ /* prepare fiber_supported, then setup advertising. */ -+ if (page == YT8521_RSSR_FIBER_SPACE) { -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, -+ fiber_supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, -+ fiber_supported); -+ linkmode_and(phydev->advertising, -+ priv->combo_advertising, fiber_supported); -+ } else { -+ /* ETHTOOL_LINK_MODE_Autoneg_BIT is also used in utp */ -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ fiber_supported); -+ linkmode_andnot(phydev->advertising, -+ priv->combo_advertising, -+ fiber_supported); -+ } -+ } -+ -+ if (page == YT8521_RSSR_FIBER_SPACE) -+ ret = yt8521_fiber_config_aneg(phydev); -+ else -+ ret = ytphy_utp_config_aneg(phydev, false); -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_config_aneg() - change reg space then call yt8521_config_aneg_paged -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_config_aneg(struct phy_device *phydev) -+{ -+ struct yt8521_priv *priv = phydev->priv; -+ int ret; -+ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ ret = yt8521_config_aneg_paged(phydev, priv->reg_page); -+ if (ret < 0) -+ return ret; -+ } else { -+ /* If reg_page is YT8521_RSSR_TO_BE_ARBITRATED, -+ * phydev->advertising need to be saved at first run. -+ * Because it contains the advertising which supported by both -+ * mac and yt8521(utp and fiber). -+ */ -+ if (linkmode_empty(priv->combo_advertising)) { -+ linkmode_copy(priv->combo_advertising, -+ phydev->advertising); -+ } -+ -+ ret = yt8521_config_aneg_paged(phydev, YT8521_RSSR_UTP_SPACE); -+ if (ret < 0) -+ return ret; -+ -+ ret = yt8521_config_aneg_paged(phydev, YT8521_RSSR_FIBER_SPACE); -+ if (ret < 0) -+ return ret; -+ -+ /* we don't known which will be link, so restore -+ * phydev->advertising as default value. -+ */ -+ linkmode_copy(phydev->advertising, priv->combo_advertising); -+ } -+ return 0; -+} -+ -+/** -+ * yt8521_aneg_done_paged() - determines the auto negotiation result of one -+ * page. -+ * @phydev: a pointer to a &struct phy_device -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to -+ * operate. -+ * -+ * returns 0(no link)or 1(fiber or utp link) or negative errno code -+ */ -+static int yt8521_aneg_done_paged(struct phy_device *phydev, int page) -+{ -+ int old_page; -+ int ret = 0; -+ int link; -+ -+ old_page = phy_select_page(phydev, page & YT8521_RSSR_SPACE_MASK); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ ret = __phy_read(phydev, YTPHY_SPECIFIC_STATUS_REG); -+ if (ret < 0) -+ goto err_restore_page; -+ -+ link = !!(ret & YTPHY_SSR_LINK); -+ ret = link; -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_aneg_done() - determines the auto negotiation result -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0(no link)or 1(fiber or utp link) or negative errno code -+ */ -+static int yt8521_aneg_done(struct phy_device *phydev) -+{ -+ struct yt8521_priv *priv = phydev->priv; -+ int link_fiber = 0; -+ int link_utp; -+ int link; -+ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ link = yt8521_aneg_done_paged(phydev, priv->reg_page); -+ } else { -+ link_utp = yt8521_aneg_done_paged(phydev, -+ YT8521_RSSR_UTP_SPACE); -+ if (link_utp < 0) -+ return link_utp; -+ -+ if (!link_utp) { -+ link_fiber = yt8521_aneg_done_paged(phydev, -+ YT8521_RSSR_FIBER_SPACE); -+ if (link_fiber < 0) -+ return link_fiber; -+ } -+ link = link_fiber || link_utp; -+ phydev_info(phydev, "%s, link_fiber: %d, link_utp: %d\n", -+ __func__, link_fiber, link_utp); -+ } -+ -+ return link; -+} -+ -+/** -+ * ytphy_utp_read_abilities - read PHY abilities from Clause 22 registers -+ * @phydev: target phy_device struct -+ * -+ * NOTE: Reads the PHY's abilities and populates -+ * phydev->supported accordingly. -+ * The caller must have taken the MDIO bus lock. -+ * -+ * returns 0 or negative errno code -+ */ -+static int ytphy_utp_read_abilities(struct phy_device *phydev) -+{ -+ int val; -+ -+ linkmode_set_bit_array(phy_basic_ports_array, -+ ARRAY_SIZE(phy_basic_ports_array), -+ phydev->supported); -+ -+ val = __phy_read(phydev, MII_BMSR); -+ if (val < 0) -+ return val; -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported, -+ val & BMSR_ANEGCAPABLE); -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported, -+ val & BMSR_100FULL); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, phydev->supported, -+ val & BMSR_100HALF); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, phydev->supported, -+ val & BMSR_10FULL); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, phydev->supported, -+ val & BMSR_10HALF); -+ -+ if (val & BMSR_ESTATEN) { -+ val = __phy_read(phydev, MII_ESTATUS); -+ if (val < 0) -+ return val; -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, -+ phydev->supported, val & ESTATUS_1000_TFULL); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, -+ phydev->supported, val & ESTATUS_1000_THALF); -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, -+ phydev->supported, val & ESTATUS_1000_XFULL); -+ } -+ -+ return 0; -+} -+ -+/** -+ * yt8521_get_features_paged() - read supported link modes for one page -+ * @phydev: a pointer to a &struct phy_device -+ * @page: The reg page(YT8521_RSSR_FIBER_SPACE/YT8521_RSSR_UTP_SPACE) to -+ * operate. -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_get_features_paged(struct phy_device *phydev, int page) -+{ -+ int old_page; -+ int ret = 0; -+ -+ page &= YT8521_RSSR_SPACE_MASK; -+ old_page = phy_select_page(phydev, page); -+ if (old_page < 0) -+ goto err_restore_page; -+ -+ if (page == YT8521_RSSR_FIBER_SPACE) { -+ linkmode_zero(phydev->supported); -+ yt8521_prepare_fiber_features(phydev, phydev->supported); -+ } else { -+ ret = ytphy_utp_read_abilities(phydev); -+ if (ret < 0) -+ goto err_restore_page; -+ } -+ -+err_restore_page: -+ return phy_restore_page(phydev, old_page, ret); -+} -+ -+/** -+ * yt8521_get_features - switch reg space then call yt8521_get_features_paged -+ * @phydev: target phy_device struct -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8521_get_features(struct phy_device *phydev) -+{ -+ struct yt8521_priv *priv = phydev->priv; -+ int ret; -+ -+ if (priv->reg_page != YT8521_RSSR_TO_BE_ARBITRATED) { -+ ret = yt8521_get_features_paged(phydev, priv->reg_page); -+ } else { -+ ret = yt8521_get_features_paged(phydev, -+ YT8521_RSSR_UTP_SPACE); -+ if (ret < 0) -+ return ret; -+ -+ /* add fiber's features to phydev->supported */ -+ yt8521_prepare_fiber_features(phydev, phydev->supported); -+ } -+ return ret; -+} -+ - static struct phy_driver motorcomm_phy_drvs[] = { - { - PHY_ID_MATCH_EXACT(PHY_ID_YT8511), -@@ -121,16 +1733,35 @@ static struct phy_driver motorcomm_phy_d - .read_page = yt8511_read_page, - .write_page = yt8511_write_page, - }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_YT8521), -+ .name = "YT8521 Gigabit Ethernet", -+ .get_features = yt8521_get_features, -+ .probe = yt8521_probe, -+ .read_page = yt8521_read_page, -+ .write_page = yt8521_write_page, -+ .get_wol = ytphy_get_wol, -+ .set_wol = ytphy_set_wol, -+ .config_aneg = yt8521_config_aneg, -+ .aneg_done = yt8521_aneg_done, -+ .config_init = yt8521_config_init, -+ .read_status = yt8521_read_status, -+ .soft_reset = yt8521_soft_reset, -+ .suspend = yt8521_suspend, -+ .resume = yt8521_resume, -+ }, - }; - - module_phy_driver(motorcomm_phy_drvs); - --MODULE_DESCRIPTION("Motorcomm PHY driver"); -+MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver"); - MODULE_AUTHOR("Peter Geis"); -+MODULE_AUTHOR("Frank"); - MODULE_LICENSE("GPL"); - - static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { - { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, -+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, - { /* sentinal */ } - }; - diff --git a/target/linux/generic/backport-6.1/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch b/target/linux/generic/backport-6.1/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch deleted file mode 100644 index cce71c8d84bfd7..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.2-02-net-phy-fix-yt8521-duplicated-argument-to-or.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 4e0243e7128c9b25ea2739136076a95d6adaba5e Mon Sep 17 00:00:00 2001 -From: Frank -Date: Fri, 4 Nov 2022 16:44:41 +0800 -Subject: [PATCH] net: phy: fix yt8521 duplicated argument to & or | - -cocci warnings: (new ones prefixed by >>) ->> drivers/net/phy/motorcomm.c:1122:8-35: duplicated argument to & or | - drivers/net/phy/motorcomm.c:1126:8-35: duplicated argument to & or | - drivers/net/phy/motorcomm.c:1130:8-34: duplicated argument to & or | - drivers/net/phy/motorcomm.c:1134:8-34: duplicated argument to & or | - - The second YT8521_RC1R_GE_TX_DELAY_xx should be YT8521_RC1R_FE_TX_DELAY_xx. - -Fixes: 70479a40954c ("net: phy: Add driver for Motorcomm yt8521 gigabit ethernet phy") -Reported-by: kernel test robot -Reported-by: Julia Lawall -Signed-off-by: Frank -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/motorcomm.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1119,19 +1119,19 @@ static int yt8521_config_init(struct phy - - switch (phydev->interface) { - case PHY_INTERFACE_MODE_RGMII: -- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS; -+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; - val |= YT8521_RC1R_RX_DELAY_DIS; - break; - case PHY_INTERFACE_MODE_RGMII_RXID: -- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_GE_TX_DELAY_DIS; -+ val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; - val |= YT8521_RC1R_RX_DELAY_EN; - break; - case PHY_INTERFACE_MODE_RGMII_TXID: -- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN; -+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; - val |= YT8521_RC1R_RX_DELAY_DIS; - break; - case PHY_INTERFACE_MODE_RGMII_ID: -- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_GE_TX_DELAY_EN; -+ val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; - val |= YT8521_RC1R_RX_DELAY_EN; - break; - case PHY_INTERFACE_MODE_SGMII: diff --git a/target/linux/generic/backport-6.1/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch b/target/linux/generic/backport-6.1/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch deleted file mode 100644 index d22cc69425d4f9..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.2-03-net-phy-add-Motorcomm-YT8531S-phy-id.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 813abcd98fb1b2cccf850cdfa092a4bfc50b2363 Mon Sep 17 00:00:00 2001 -From: Frank -Date: Tue, 22 Nov 2022 16:42:32 +0800 -Subject: [PATCH] net: phy: add Motorcomm YT8531S phy id. - -We added patch for motorcomm.c to support YT8531S. This patch has -been tested on AM335x platform which has one YT8531S interface -card and passed all test cases. -The tested cases indluding: YT8531S UTP function with support of -10M/100M/1000M; YT8531S Fiber function with support of 100M/1000M; -and YT8531S Combo function that supports auto detection of media type. - -Since most functions of YT8531S are similar to YT8521 and we reuse some -codes for YT8521 in the patch file. - -Signed-off-by: Frank -Signed-off-by: David S. Miller ---- - drivers/net/phy/Kconfig | 2 +- - drivers/net/phy/motorcomm.c | 52 +++++++++++++++++++++++++++++++++---- - 2 files changed, 48 insertions(+), 6 deletions(-) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -257,7 +257,7 @@ config MOTORCOMM_PHY - tristate "Motorcomm PHYs" - help - Enables support for Motorcomm network PHYs. -- Currently supports the YT8511, YT8521 Gigabit Ethernet PHYs. -+ Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs. - - config NATIONAL_PHY - tristate "National Semiconductor PHYs" ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* -- * Motorcomm 8511/8521 PHY driver. -+ * Motorcomm 8511/8521/8531S PHY driver. - * - * Author: Peter Geis - * Author: Frank -@@ -12,9 +12,10 @@ - #include - - #define PHY_ID_YT8511 0x0000010a --#define PHY_ID_YT8521 0x0000011A -+#define PHY_ID_YT8521 0x0000011A -+#define PHY_ID_YT8531S 0x4F51E91A - --/* YT8521 Register Overview -+/* YT8521/YT8531S Register Overview - * UTP Register space | FIBER Register space - * ------------------------------------------------------------ - * | UTP MII | FIBER MII | -@@ -147,7 +148,7 @@ - #define YT8521_LINK_TIMER_CFG2_REG 0xA5 - #define YT8521_LTCR_EN_AUTOSEN BIT(15) - --/* 0xA000, 0xA001, 0xA003 ,and 0xA006 ~ 0xA00A are common ext registers -+/* 0xA000, 0xA001, 0xA003, 0xA006 ~ 0xA00A and 0xA012 are common ext registers - * of yt8521 phy. There is no need to switch reg space when operating these - * registers. - */ -@@ -221,6 +222,9 @@ - */ - #define YTPHY_WCR_TYPE_PULSE BIT(0) - -+#define YT8531S_SYNCE_CFG_REG 0xA012 -+#define YT8531S_SCR_SYNCE_ENABLE BIT(6) -+ - /* Extended Register end */ - - struct yt8521_priv { -@@ -648,6 +652,26 @@ static int yt8521_probe(struct phy_devic - } - - /** -+ * yt8531s_probe() - read chip config then set suitable polling_mode -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * returns 0 or negative errno code -+ */ -+static int yt8531s_probe(struct phy_device *phydev) -+{ -+ int ret; -+ -+ /* Disable SyncE clock output by default */ -+ ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG, -+ YT8531S_SCR_SYNCE_ENABLE, 0); -+ if (ret < 0) -+ return ret; -+ -+ /* same as yt8521_probe */ -+ return yt8521_probe(phydev); -+} -+ -+/** - * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp - * @phydev: a pointer to a &struct phy_device - * -@@ -1750,11 +1774,28 @@ static struct phy_driver motorcomm_phy_d - .suspend = yt8521_suspend, - .resume = yt8521_resume, - }, -+ { -+ PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), -+ .name = "YT8531S Gigabit Ethernet", -+ .get_features = yt8521_get_features, -+ .probe = yt8531s_probe, -+ .read_page = yt8521_read_page, -+ .write_page = yt8521_write_page, -+ .get_wol = ytphy_get_wol, -+ .set_wol = ytphy_set_wol, -+ .config_aneg = yt8521_config_aneg, -+ .aneg_done = yt8521_aneg_done, -+ .config_init = yt8521_config_init, -+ .read_status = yt8521_read_status, -+ .soft_reset = yt8521_soft_reset, -+ .suspend = yt8521_suspend, -+ .resume = yt8521_resume, -+ }, - }; - - module_phy_driver(motorcomm_phy_drvs); - --MODULE_DESCRIPTION("Motorcomm 8511/8521 PHY driver"); -+MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver"); - MODULE_AUTHOR("Peter Geis"); - MODULE_AUTHOR("Frank"); - MODULE_LICENSE("GPL"); -@@ -1762,6 +1803,7 @@ MODULE_LICENSE("GPL"); - static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { - { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, - { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, -+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, - { /* sentinal */ } - }; - diff --git a/target/linux/generic/backport-6.1/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch b/target/linux/generic/backport-6.1/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch deleted file mode 100644 index 94fc32aadb320d..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.3-04-net-phy-fix-the-spelling-problem-of-Sentinel.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 4104a713204d62aca482eebb0c6226d82a0721eb Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Sat, 28 Jan 2023 14:35:57 +0800 -Subject: [PATCH] net: phy: fix the spelling problem of Sentinel - -CHECK: 'sentinal' may be misspelled - perhaps 'sentinel'? - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20230128063558.5850-1-Frank.Sae@motor-comm.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/motorcomm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1804,7 +1804,7 @@ static const struct mdio_device_id __may - { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, - { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, - { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, -- { /* sentinal */ } -+ { /* sentinel */ } - }; - - MODULE_DEVICE_TABLE(mdio, motorcomm_tbl); diff --git a/target/linux/generic/backport-6.1/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch b/target/linux/generic/backport-6.1/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch deleted file mode 100644 index 076fa82d267fce..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.3-05-net-phy-motorcomm-change-the-phy-id-of-yt8521-and-yt8531s.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 3c1dc22162d673d595855d24f95200ed2643f88f Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Sat, 28 Jan 2023 14:35:58 +0800 -Subject: [PATCH] net: phy: motorcomm: change the phy id of yt8521 and yt8531s - to lowercase - -The phy id is usually defined in lower case. - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20230128063558.5850-2-Frank.Sae@motor-comm.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/motorcomm.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -12,8 +12,8 @@ - #include - - #define PHY_ID_YT8511 0x0000010a --#define PHY_ID_YT8521 0x0000011A --#define PHY_ID_YT8531S 0x4F51E91A -+#define PHY_ID_YT8521 0x0000011a -+#define PHY_ID_YT8531S 0x4f51e91a - - /* YT8521/YT8531S Register Overview - * UTP Register space | FIBER Register space diff --git a/target/linux/generic/backport-6.1/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch b/target/linux/generic/backport-6.1/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch deleted file mode 100644 index ba9a6ab4ccba3b..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.3-06-net-phy-Add-BIT-macro-for-Motorcomm-yt8521-yt8531-gigabit.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 4869a146cd60fc8115230f0a45e15e534c531922 Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Thu, 2 Feb 2023 11:00:34 +0800 -Subject: [PATCH] net: phy: Add BIT macro for Motorcomm yt8521/yt8531 gigabit - ethernet phy - -Add BIT macro for Motorcomm yt8521/yt8531 gigabit ethernet phy. - This is a preparatory patch. Add BIT macro for 0xA012 reg, and - supplement for 0xA001 and 0xA003 reg. These will be used to support dts. - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/motorcomm.c | 55 ++++++++++++++++++++++++++++++++++--- - 1 file changed, 51 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -161,6 +161,11 @@ - - #define YT8521_CHIP_CONFIG_REG 0xA001 - #define YT8521_CCR_SW_RST BIT(15) -+/* 1b0 disable 1.9ns rxc clock delay *default* -+ * 1b1 enable 1.9ns rxc clock delay -+ */ -+#define YT8521_CCR_RXC_DLY_EN BIT(8) -+#define YT8521_CCR_RXC_DLY_1_900_NS 1900 - - #define YT8521_CCR_MODE_SEL_MASK (BIT(2) | BIT(1) | BIT(0)) - #define YT8521_CCR_MODE_UTP_TO_RGMII 0 -@@ -178,22 +183,41 @@ - #define YT8521_MODE_POLL 0x3 - - #define YT8521_RGMII_CONFIG1_REG 0xA003 -- -+/* 1b0 use original tx_clk_rgmii *default* -+ * 1b1 use inverted tx_clk_rgmii. -+ */ -+#define YT8521_RC1R_TX_CLK_SEL_INVERTED BIT(14) - /* TX Gig-E Delay is bits 3:0, default 0x1 - * TX Fast-E Delay is bits 7:4, default 0xf - * RX Delay is bits 13:10, default 0x0 - * Delay = 150ps * N - * On = 2250ps, off = 0ps - */ --#define YT8521_RC1R_RX_DELAY_MASK (0xF << 10) -+#define YT8521_RC1R_RX_DELAY_MASK GENMASK(13, 10) - #define YT8521_RC1R_RX_DELAY_EN (0xF << 10) - #define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10) --#define YT8521_RC1R_FE_TX_DELAY_MASK (0xF << 4) -+#define YT8521_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4) - #define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4) - #define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4) --#define YT8521_RC1R_GE_TX_DELAY_MASK (0xF << 0) -+#define YT8521_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0) - #define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0) - #define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0) -+#define YT8521_RC1R_RGMII_0_000_NS 0 -+#define YT8521_RC1R_RGMII_0_150_NS 1 -+#define YT8521_RC1R_RGMII_0_300_NS 2 -+#define YT8521_RC1R_RGMII_0_450_NS 3 -+#define YT8521_RC1R_RGMII_0_600_NS 4 -+#define YT8521_RC1R_RGMII_0_750_NS 5 -+#define YT8521_RC1R_RGMII_0_900_NS 6 -+#define YT8521_RC1R_RGMII_1_050_NS 7 -+#define YT8521_RC1R_RGMII_1_200_NS 8 -+#define YT8521_RC1R_RGMII_1_350_NS 9 -+#define YT8521_RC1R_RGMII_1_500_NS 10 -+#define YT8521_RC1R_RGMII_1_650_NS 11 -+#define YT8521_RC1R_RGMII_1_800_NS 12 -+#define YT8521_RC1R_RGMII_1_950_NS 13 -+#define YT8521_RC1R_RGMII_2_100_NS 14 -+#define YT8521_RC1R_RGMII_2_250_NS 15 - - #define YTPHY_MISC_CONFIG_REG 0xA006 - #define YTPHY_MCR_FIBER_SPEED_MASK BIT(0) -@@ -222,6 +246,29 @@ - */ - #define YTPHY_WCR_TYPE_PULSE BIT(0) - -+#define YTPHY_SYNCE_CFG_REG 0xA012 -+#define YT8521_SCR_SYNCE_ENABLE BIT(5) -+/* 1b0 output 25m clock -+ * 1b1 output 125m clock *default* -+ */ -+#define YT8521_SCR_CLK_FRE_SEL_125M BIT(3) -+#define YT8521_SCR_CLK_SRC_MASK GENMASK(2, 1) -+#define YT8521_SCR_CLK_SRC_PLL_125M 0 -+#define YT8521_SCR_CLK_SRC_UTP_RX 1 -+#define YT8521_SCR_CLK_SRC_SDS_RX 2 -+#define YT8521_SCR_CLK_SRC_REF_25M 3 -+#define YT8531_SCR_SYNCE_ENABLE BIT(6) -+/* 1b0 output 25m clock *default* -+ * 1b1 output 125m clock -+ */ -+#define YT8531_SCR_CLK_FRE_SEL_125M BIT(4) -+#define YT8531_SCR_CLK_SRC_MASK GENMASK(3, 1) -+#define YT8531_SCR_CLK_SRC_PLL_125M 0 -+#define YT8531_SCR_CLK_SRC_UTP_RX 1 -+#define YT8531_SCR_CLK_SRC_SDS_RX 2 -+#define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3 -+#define YT8531_SCR_CLK_SRC_REF_25M 4 -+#define YT8531_SCR_CLK_SRC_SSC_25M 5 - #define YT8531S_SYNCE_CFG_REG 0xA012 - #define YT8531S_SCR_SYNCE_ENABLE BIT(6) - diff --git a/target/linux/generic/backport-6.1/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch b/target/linux/generic/backport-6.1/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch deleted file mode 100644 index 6d89fae84ccc2f..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.3-07-net-phy-Add-dts-support-for-Motorcomm-yt8521-gigabit.patch +++ /dev/null @@ -1,343 +0,0 @@ -From a6e68f0f8769f79c67cdcfb6302feecd36197dec Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Thu, 2 Feb 2023 11:00:35 +0800 -Subject: [PATCH] net: phy: Add dts support for Motorcomm yt8521 gigabit - ethernet phy - -Add dts support for Motorcomm yt8521 gigabit ethernet phy. - Add ytphy_rgmii_clk_delay_config function to support dst config for - the delay of rgmii clk. This funciont is common for yt8521, yt8531s - and yt8531. - This patch has been verified on AM335x platform. - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/motorcomm.c | 253 ++++++++++++++++++++++++++++-------- - 1 file changed, 199 insertions(+), 54 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #define PHY_ID_YT8511 0x0000010a - #define PHY_ID_YT8521 0x0000011a -@@ -187,21 +188,9 @@ - * 1b1 use inverted tx_clk_rgmii. - */ - #define YT8521_RC1R_TX_CLK_SEL_INVERTED BIT(14) --/* TX Gig-E Delay is bits 3:0, default 0x1 -- * TX Fast-E Delay is bits 7:4, default 0xf -- * RX Delay is bits 13:10, default 0x0 -- * Delay = 150ps * N -- * On = 2250ps, off = 0ps -- */ - #define YT8521_RC1R_RX_DELAY_MASK GENMASK(13, 10) --#define YT8521_RC1R_RX_DELAY_EN (0xF << 10) --#define YT8521_RC1R_RX_DELAY_DIS (0x0 << 10) - #define YT8521_RC1R_FE_TX_DELAY_MASK GENMASK(7, 4) --#define YT8521_RC1R_FE_TX_DELAY_EN (0xF << 4) --#define YT8521_RC1R_FE_TX_DELAY_DIS (0x0 << 4) - #define YT8521_RC1R_GE_TX_DELAY_MASK GENMASK(3, 0) --#define YT8521_RC1R_GE_TX_DELAY_EN (0xF << 0) --#define YT8521_RC1R_GE_TX_DELAY_DIS (0x0 << 0) - #define YT8521_RC1R_RGMII_0_000_NS 0 - #define YT8521_RC1R_RGMII_0_150_NS 1 - #define YT8521_RC1R_RGMII_0_300_NS 2 -@@ -274,6 +263,10 @@ - - /* Extended Register end */ - -+#define YTPHY_DTS_OUTPUT_CLK_DIS 0 -+#define YTPHY_DTS_OUTPUT_CLK_25M 25000000 -+#define YTPHY_DTS_OUTPUT_CLK_125M 125000000 -+ - struct yt8521_priv { - /* combo_advertising is used for case of YT8521 in combo mode, - * this means that yt8521 may work in utp or fiber mode which depends -@@ -641,6 +634,142 @@ static int yt8521_write_page(struct phy_ - }; - - /** -+ * struct ytphy_cfg_reg_map - map a config value to a register value -+ * @cfg: value in device configuration -+ * @reg: value in the register -+ */ -+struct ytphy_cfg_reg_map { -+ u32 cfg; -+ u32 reg; -+}; -+ -+static const struct ytphy_cfg_reg_map ytphy_rgmii_delays[] = { -+ /* for tx delay / rx delay with YT8521_CCR_RXC_DLY_EN is not set. */ -+ { 0, YT8521_RC1R_RGMII_0_000_NS }, -+ { 150, YT8521_RC1R_RGMII_0_150_NS }, -+ { 300, YT8521_RC1R_RGMII_0_300_NS }, -+ { 450, YT8521_RC1R_RGMII_0_450_NS }, -+ { 600, YT8521_RC1R_RGMII_0_600_NS }, -+ { 750, YT8521_RC1R_RGMII_0_750_NS }, -+ { 900, YT8521_RC1R_RGMII_0_900_NS }, -+ { 1050, YT8521_RC1R_RGMII_1_050_NS }, -+ { 1200, YT8521_RC1R_RGMII_1_200_NS }, -+ { 1350, YT8521_RC1R_RGMII_1_350_NS }, -+ { 1500, YT8521_RC1R_RGMII_1_500_NS }, -+ { 1650, YT8521_RC1R_RGMII_1_650_NS }, -+ { 1800, YT8521_RC1R_RGMII_1_800_NS }, -+ { 1950, YT8521_RC1R_RGMII_1_950_NS }, /* default tx/rx delay */ -+ { 2100, YT8521_RC1R_RGMII_2_100_NS }, -+ { 2250, YT8521_RC1R_RGMII_2_250_NS }, -+ -+ /* only for rx delay with YT8521_CCR_RXC_DLY_EN is set. */ -+ { 0 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_000_NS }, -+ { 150 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_150_NS }, -+ { 300 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_300_NS }, -+ { 450 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_450_NS }, -+ { 600 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_600_NS }, -+ { 750 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_750_NS }, -+ { 900 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_0_900_NS }, -+ { 1050 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_050_NS }, -+ { 1200 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_200_NS }, -+ { 1350 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_350_NS }, -+ { 1500 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_500_NS }, -+ { 1650 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_650_NS }, -+ { 1800 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_800_NS }, -+ { 1950 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_1_950_NS }, -+ { 2100 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_2_100_NS }, -+ { 2250 + YT8521_CCR_RXC_DLY_1_900_NS, YT8521_RC1R_RGMII_2_250_NS } -+}; -+ -+static u32 ytphy_get_delay_reg_value(struct phy_device *phydev, -+ const char *prop_name, -+ const struct ytphy_cfg_reg_map *tbl, -+ int tb_size, -+ u16 *rxc_dly_en, -+ u32 dflt) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ int tb_size_half = tb_size / 2; -+ u32 val; -+ int i; -+ -+ if (of_property_read_u32(node, prop_name, &val)) -+ goto err_dts_val; -+ -+ /* when rxc_dly_en is NULL, it is get the delay for tx, only half of -+ * tb_size is valid. -+ */ -+ if (!rxc_dly_en) -+ tb_size = tb_size_half; -+ -+ for (i = 0; i < tb_size; i++) { -+ if (tbl[i].cfg == val) { -+ if (rxc_dly_en && i < tb_size_half) -+ *rxc_dly_en = 0; -+ return tbl[i].reg; -+ } -+ } -+ -+ phydev_warn(phydev, "Unsupported value %d for %s using default (%u)\n", -+ val, prop_name, dflt); -+ -+err_dts_val: -+ /* when rxc_dly_en is not NULL, it is get the delay for rx. -+ * The rx default in dts and ytphy_rgmii_clk_delay_config is 1950 ps, -+ * so YT8521_CCR_RXC_DLY_EN should not be set. -+ */ -+ if (rxc_dly_en) -+ *rxc_dly_en = 0; -+ -+ return dflt; -+} -+ -+static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev) -+{ -+ int tb_size = ARRAY_SIZE(ytphy_rgmii_delays); -+ u16 rxc_dly_en = YT8521_CCR_RXC_DLY_EN; -+ u32 rx_reg, tx_reg; -+ u16 mask, val = 0; -+ int ret; -+ -+ rx_reg = ytphy_get_delay_reg_value(phydev, "rx-internal-delay-ps", -+ ytphy_rgmii_delays, tb_size, -+ &rxc_dly_en, -+ YT8521_RC1R_RGMII_1_950_NS); -+ tx_reg = ytphy_get_delay_reg_value(phydev, "tx-internal-delay-ps", -+ ytphy_rgmii_delays, tb_size, NULL, -+ YT8521_RC1R_RGMII_1_950_NS); -+ -+ switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ rxc_dly_en = 0; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg); -+ break; -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ rxc_dly_en = 0; -+ val |= FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg); -+ break; -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg) | -+ FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg); -+ break; -+ default: /* do not support other modes */ -+ return -EOPNOTSUPP; -+ } -+ -+ ret = ytphy_modify_ext(phydev, YT8521_CHIP_CONFIG_REG, -+ YT8521_CCR_RXC_DLY_EN, rxc_dly_en); -+ if (ret < 0) -+ return ret; -+ -+ /* Generally, it is not necessary to adjust YT8521_RC1R_FE_TX_DELAY */ -+ mask = YT8521_RC1R_RX_DELAY_MASK | YT8521_RC1R_GE_TX_DELAY_MASK; -+ return ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, mask, val); -+} -+ -+/** - * yt8521_probe() - read chip config then set suitable polling_mode - * @phydev: a pointer to a &struct phy_device - * -@@ -648,9 +777,12 @@ static int yt8521_write_page(struct phy_ - */ - static int yt8521_probe(struct phy_device *phydev) - { -+ struct device_node *node = phydev->mdio.dev.of_node; - struct device *dev = &phydev->mdio.dev; - struct yt8521_priv *priv; - int chip_config; -+ u16 mask, val; -+ u32 freq; - int ret; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -@@ -695,7 +827,45 @@ static int yt8521_probe(struct phy_devic - return ret; - } - -- return 0; -+ if (of_property_read_u32(node, "motorcomm,clk-out-frequency-hz", &freq)) -+ freq = YTPHY_DTS_OUTPUT_CLK_DIS; -+ -+ if (phydev->drv->phy_id == PHY_ID_YT8521) { -+ switch (freq) { -+ case YTPHY_DTS_OUTPUT_CLK_DIS: -+ mask = YT8521_SCR_SYNCE_ENABLE; -+ val = 0; -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_25M: -+ mask = YT8521_SCR_SYNCE_ENABLE | -+ YT8521_SCR_CLK_SRC_MASK | -+ YT8521_SCR_CLK_FRE_SEL_125M; -+ val = YT8521_SCR_SYNCE_ENABLE | -+ FIELD_PREP(YT8521_SCR_CLK_SRC_MASK, -+ YT8521_SCR_CLK_SRC_REF_25M); -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_125M: -+ mask = YT8521_SCR_SYNCE_ENABLE | -+ YT8521_SCR_CLK_SRC_MASK | -+ YT8521_SCR_CLK_FRE_SEL_125M; -+ val = YT8521_SCR_SYNCE_ENABLE | -+ YT8521_SCR_CLK_FRE_SEL_125M | -+ FIELD_PREP(YT8521_SCR_CLK_SRC_MASK, -+ YT8521_SCR_CLK_SRC_PLL_125M); -+ break; -+ default: -+ phydev_warn(phydev, "Freq err:%u\n", freq); -+ return -EINVAL; -+ } -+ } else if (phydev->drv->phy_id == PHY_ID_YT8531S) { -+ return 0; -+ } else { -+ phydev_warn(phydev, "PHY id err\n"); -+ return -EINVAL; -+ } -+ -+ return ytphy_modify_ext_with_lock(phydev, YTPHY_SYNCE_CFG_REG, mask, -+ val); - } - - /** -@@ -1180,61 +1350,36 @@ static int yt8521_resume(struct phy_devi - */ - static int yt8521_config_init(struct phy_device *phydev) - { -+ struct device_node *node = phydev->mdio.dev.of_node; - int old_page; - int ret = 0; -- u16 val; - - old_page = phy_select_page(phydev, YT8521_RSSR_UTP_SPACE); - if (old_page < 0) - goto err_restore_page; - -- switch (phydev->interface) { -- case PHY_INTERFACE_MODE_RGMII: -- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; -- val |= YT8521_RC1R_RX_DELAY_DIS; -- break; -- case PHY_INTERFACE_MODE_RGMII_RXID: -- val = YT8521_RC1R_GE_TX_DELAY_DIS | YT8521_RC1R_FE_TX_DELAY_DIS; -- val |= YT8521_RC1R_RX_DELAY_EN; -- break; -- case PHY_INTERFACE_MODE_RGMII_TXID: -- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; -- val |= YT8521_RC1R_RX_DELAY_DIS; -- break; -- case PHY_INTERFACE_MODE_RGMII_ID: -- val = YT8521_RC1R_GE_TX_DELAY_EN | YT8521_RC1R_FE_TX_DELAY_EN; -- val |= YT8521_RC1R_RX_DELAY_EN; -- break; -- case PHY_INTERFACE_MODE_SGMII: -- break; -- default: /* do not support other modes */ -- ret = -EOPNOTSUPP; -- goto err_restore_page; -- } -- - /* set rgmii delay mode */ - if (phydev->interface != PHY_INTERFACE_MODE_SGMII) { -- ret = ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, -- (YT8521_RC1R_RX_DELAY_MASK | -- YT8521_RC1R_FE_TX_DELAY_MASK | -- YT8521_RC1R_GE_TX_DELAY_MASK), -- val); -+ ret = ytphy_rgmii_clk_delay_config(phydev); - if (ret < 0) - goto err_restore_page; - } - -- /* disable auto sleep */ -- ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG, -- YT8521_ESC1R_SLEEP_SW, 0); -- if (ret < 0) -- goto err_restore_page; -- -- /* enable RXC clock when no wire plug */ -- ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG, -- YT8521_CGR_RX_CLK_EN, 0); -- if (ret < 0) -- goto err_restore_page; -+ if (of_property_read_bool(node, "motorcomm,auto-sleep-disabled")) { -+ /* disable auto sleep */ -+ ret = ytphy_modify_ext(phydev, YT8521_EXTREG_SLEEP_CONTROL1_REG, -+ YT8521_ESC1R_SLEEP_SW, 0); -+ if (ret < 0) -+ goto err_restore_page; -+ } - -+ if (of_property_read_bool(node, "motorcomm,keep-pll-enabled")) { -+ /* enable RXC clock when no wire plug */ -+ ret = ytphy_modify_ext(phydev, YT8521_CLOCK_GATING_REG, -+ YT8521_CGR_RX_CLK_EN, 0); -+ if (ret < 0) -+ goto err_restore_page; -+ } - err_restore_page: - return phy_restore_page(phydev, old_page, ret); - } diff --git a/target/linux/generic/backport-6.1/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch b/target/linux/generic/backport-6.1/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch deleted file mode 100644 index 86fc04695c8ec2..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.3-08-net-phy-Add-dts-support-for-Motorcomm-yt8531s-gigabit.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 36152f87dda4af221b16258751451d9cd3d0fb0b Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Thu, 2 Feb 2023 11:00:36 +0800 -Subject: [PATCH] net: phy: Add dts support for Motorcomm yt8531s gigabit - ethernet phy - -Add dts support for Motorcomm yt8531s gigabit ethernet phy. - Change yt8521_probe to support clk config of yt8531s. Becase - yt8521_probe does the things which yt8531s is needed, so - removed yt8531s function. - This patch has been verified on AM335x platform with yt8531s board. - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/motorcomm.c | 51 ++++++++++++++++++++----------------- - 1 file changed, 27 insertions(+), 24 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -258,8 +258,6 @@ - #define YT8531_SCR_CLK_SRC_CLOCK_FROM_DIGITAL 3 - #define YT8531_SCR_CLK_SRC_REF_25M 4 - #define YT8531_SCR_CLK_SRC_SSC_25M 5 --#define YT8531S_SYNCE_CFG_REG 0xA012 --#define YT8531S_SCR_SYNCE_ENABLE BIT(6) - - /* Extended Register end */ - -@@ -858,7 +856,32 @@ static int yt8521_probe(struct phy_devic - return -EINVAL; - } - } else if (phydev->drv->phy_id == PHY_ID_YT8531S) { -- return 0; -+ switch (freq) { -+ case YTPHY_DTS_OUTPUT_CLK_DIS: -+ mask = YT8531_SCR_SYNCE_ENABLE; -+ val = 0; -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_25M: -+ mask = YT8531_SCR_SYNCE_ENABLE | -+ YT8531_SCR_CLK_SRC_MASK | -+ YT8531_SCR_CLK_FRE_SEL_125M; -+ val = YT8531_SCR_SYNCE_ENABLE | -+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK, -+ YT8531_SCR_CLK_SRC_REF_25M); -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_125M: -+ mask = YT8531_SCR_SYNCE_ENABLE | -+ YT8531_SCR_CLK_SRC_MASK | -+ YT8531_SCR_CLK_FRE_SEL_125M; -+ val = YT8531_SCR_SYNCE_ENABLE | -+ YT8531_SCR_CLK_FRE_SEL_125M | -+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK, -+ YT8531_SCR_CLK_SRC_PLL_125M); -+ break; -+ default: -+ phydev_warn(phydev, "Freq err:%u\n", freq); -+ return -EINVAL; -+ } - } else { - phydev_warn(phydev, "PHY id err\n"); - return -EINVAL; -@@ -869,26 +892,6 @@ static int yt8521_probe(struct phy_devic - } - - /** -- * yt8531s_probe() - read chip config then set suitable polling_mode -- * @phydev: a pointer to a &struct phy_device -- * -- * returns 0 or negative errno code -- */ --static int yt8531s_probe(struct phy_device *phydev) --{ -- int ret; -- -- /* Disable SyncE clock output by default */ -- ret = ytphy_modify_ext_with_lock(phydev, YT8531S_SYNCE_CFG_REG, -- YT8531S_SCR_SYNCE_ENABLE, 0); -- if (ret < 0) -- return ret; -- -- /* same as yt8521_probe */ -- return yt8521_probe(phydev); --} -- --/** - * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp - * @phydev: a pointer to a &struct phy_device - * -@@ -1970,7 +1973,7 @@ static struct phy_driver motorcomm_phy_d - PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), - .name = "YT8531S Gigabit Ethernet", - .get_features = yt8521_get_features, -- .probe = yt8531s_probe, -+ .probe = yt8521_probe, - .read_page = yt8521_read_page, - .write_page = yt8521_write_page, - .get_wol = ytphy_get_wol, diff --git a/target/linux/generic/backport-6.1/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch b/target/linux/generic/backport-6.1/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch deleted file mode 100644 index 60eea4fa477ec2..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.3-09-net-phy-Add-driver-for-Motorcomm-yt8531-gigabit-ethernet.patch +++ /dev/null @@ -1,302 +0,0 @@ -From 4ac94f728a588e7096dd5010cd7141a309ea7805 Mon Sep 17 00:00:00 2001 -From: Frank Sae -Date: Thu, 2 Feb 2023 11:00:37 +0800 -Subject: [PATCH] net: phy: Add driver for Motorcomm yt8531 gigabit ethernet - phy - -Add a driver for the motorcomm yt8531 gigabit ethernet phy. We have - verified the driver on AM335x platform with yt8531 board. On the - board, yt8531 gigabit ethernet phy works in utp mode, RGMII - interface, supports 1000M/100M/10M speeds, and wol(magic package). - -Signed-off-by: Frank Sae -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/Kconfig | 2 +- - drivers/net/phy/motorcomm.c | 208 +++++++++++++++++++++++++++++++++++- - 2 files changed, 207 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -257,7 +257,7 @@ config MOTORCOMM_PHY - tristate "Motorcomm PHYs" - help - Enables support for Motorcomm network PHYs. -- Currently supports the YT8511, YT8521, YT8531S Gigabit Ethernet PHYs. -+ Currently supports YT85xx Gigabit Ethernet PHYs. - - config NATIONAL_PHY - tristate "National Semiconductor PHYs" ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* -- * Motorcomm 8511/8521/8531S PHY driver. -+ * Motorcomm 8511/8521/8531/8531S PHY driver. - * - * Author: Peter Geis - * Author: Frank -@@ -14,6 +14,7 @@ - - #define PHY_ID_YT8511 0x0000010a - #define PHY_ID_YT8521 0x0000011a -+#define PHY_ID_YT8531 0x4f51e91b - #define PHY_ID_YT8531S 0x4f51e91a - - /* YT8521/YT8531S Register Overview -@@ -517,6 +518,61 @@ err_restore_page: - return phy_restore_page(phydev, old_page, ret); - } - -+static int yt8531_set_wol(struct phy_device *phydev, -+ struct ethtool_wolinfo *wol) -+{ -+ const u16 mac_addr_reg[] = { -+ YTPHY_WOL_MACADDR2_REG, -+ YTPHY_WOL_MACADDR1_REG, -+ YTPHY_WOL_MACADDR0_REG, -+ }; -+ const u8 *mac_addr; -+ u16 mask, val; -+ int ret; -+ u8 i; -+ -+ if (wol->wolopts & WAKE_MAGIC) { -+ mac_addr = phydev->attached_dev->dev_addr; -+ -+ /* Store the device address for the magic packet */ -+ for (i = 0; i < 3; i++) { -+ ret = ytphy_write_ext_with_lock(phydev, mac_addr_reg[i], -+ ((mac_addr[i * 2] << 8)) | -+ (mac_addr[i * 2 + 1])); -+ if (ret < 0) -+ return ret; -+ } -+ -+ /* Enable WOL feature */ -+ mask = YTPHY_WCR_PULSE_WIDTH_MASK | YTPHY_WCR_INTR_SEL; -+ val = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; -+ val |= YTPHY_WCR_TYPE_PULSE | YTPHY_WCR_PULSE_WIDTH_672MS; -+ ret = ytphy_modify_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG, -+ mask, val); -+ if (ret < 0) -+ return ret; -+ -+ /* Enable WOL interrupt */ -+ ret = phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, 0, -+ YTPHY_IER_WOL); -+ if (ret < 0) -+ return ret; -+ } else { -+ /* Disable WOL feature */ -+ mask = YTPHY_WCR_ENABLE | YTPHY_WCR_INTR_SEL; -+ ret = ytphy_modify_ext_with_lock(phydev, YTPHY_WOL_CONFIG_REG, -+ mask, 0); -+ -+ /* Disable WOL interrupt */ -+ ret = phy_modify(phydev, YTPHY_INTERRUPT_ENABLE_REG, -+ YTPHY_IER_WOL, 0); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ - static int yt8511_read_page(struct phy_device *phydev) - { - return __phy_read(phydev, YT8511_PAGE_SELECT); -@@ -767,6 +823,17 @@ static int ytphy_rgmii_clk_delay_config( - return ytphy_modify_ext(phydev, YT8521_RGMII_CONFIG1_REG, mask, val); - } - -+static int ytphy_rgmii_clk_delay_config_with_lock(struct phy_device *phydev) -+{ -+ int ret; -+ -+ phy_lock_mdio_bus(phydev); -+ ret = ytphy_rgmii_clk_delay_config(phydev); -+ phy_unlock_mdio_bus(phydev); -+ -+ return ret; -+} -+ - /** - * yt8521_probe() - read chip config then set suitable polling_mode - * @phydev: a pointer to a &struct phy_device -@@ -891,6 +958,43 @@ static int yt8521_probe(struct phy_devic - val); - } - -+static int yt8531_probe(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ u16 mask, val; -+ u32 freq; -+ -+ if (of_property_read_u32(node, "motorcomm,clk-out-frequency-hz", &freq)) -+ freq = YTPHY_DTS_OUTPUT_CLK_DIS; -+ -+ switch (freq) { -+ case YTPHY_DTS_OUTPUT_CLK_DIS: -+ mask = YT8531_SCR_SYNCE_ENABLE; -+ val = 0; -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_25M: -+ mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK | -+ YT8531_SCR_CLK_FRE_SEL_125M; -+ val = YT8531_SCR_SYNCE_ENABLE | -+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK, -+ YT8531_SCR_CLK_SRC_REF_25M); -+ break; -+ case YTPHY_DTS_OUTPUT_CLK_125M: -+ mask = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_SRC_MASK | -+ YT8531_SCR_CLK_FRE_SEL_125M; -+ val = YT8531_SCR_SYNCE_ENABLE | YT8531_SCR_CLK_FRE_SEL_125M | -+ FIELD_PREP(YT8531_SCR_CLK_SRC_MASK, -+ YT8531_SCR_CLK_SRC_PLL_125M); -+ break; -+ default: -+ phydev_warn(phydev, "Freq err:%u\n", freq); -+ return -EINVAL; -+ } -+ -+ return ytphy_modify_ext_with_lock(phydev, YTPHY_SYNCE_CFG_REG, mask, -+ val); -+} -+ - /** - * ytphy_utp_read_lpa() - read LPA then setup lp_advertising for utp - * @phydev: a pointer to a &struct phy_device -@@ -1387,6 +1491,94 @@ err_restore_page: - return phy_restore_page(phydev, old_page, ret); - } - -+static int yt8531_config_init(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ int ret; -+ -+ ret = ytphy_rgmii_clk_delay_config_with_lock(phydev); -+ if (ret < 0) -+ return ret; -+ -+ if (of_property_read_bool(node, "motorcomm,auto-sleep-disabled")) { -+ /* disable auto sleep */ -+ ret = ytphy_modify_ext_with_lock(phydev, -+ YT8521_EXTREG_SLEEP_CONTROL1_REG, -+ YT8521_ESC1R_SLEEP_SW, 0); -+ if (ret < 0) -+ return ret; -+ } -+ -+ if (of_property_read_bool(node, "motorcomm,keep-pll-enabled")) { -+ /* enable RXC clock when no wire plug */ -+ ret = ytphy_modify_ext_with_lock(phydev, -+ YT8521_CLOCK_GATING_REG, -+ YT8521_CGR_RX_CLK_EN, 0); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+/** -+ * yt8531_link_change_notify() - Adjust the tx clock direction according to -+ * the current speed and dts config. -+ * @phydev: a pointer to a &struct phy_device -+ * -+ * NOTE: This function is only used to adapt to VF2 with JH7110 SoC. Please -+ * keep "motorcomm,tx-clk-adj-enabled" not exist in dts when the soc is not -+ * JH7110. -+ */ -+static void yt8531_link_change_notify(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ bool tx_clk_adj_enabled = false; -+ bool tx_clk_1000_inverted; -+ bool tx_clk_100_inverted; -+ bool tx_clk_10_inverted; -+ u16 val = 0; -+ int ret; -+ -+ if (of_property_read_bool(node, "motorcomm,tx-clk-adj-enabled")) -+ tx_clk_adj_enabled = true; -+ -+ if (!tx_clk_adj_enabled) -+ return; -+ -+ if (of_property_read_bool(node, "motorcomm,tx-clk-10-inverted")) -+ tx_clk_10_inverted = true; -+ if (of_property_read_bool(node, "motorcomm,tx-clk-100-inverted")) -+ tx_clk_100_inverted = true; -+ if (of_property_read_bool(node, "motorcomm,tx-clk-1000-inverted")) -+ tx_clk_1000_inverted = true; -+ -+ if (phydev->speed < 0) -+ return; -+ -+ switch (phydev->speed) { -+ case SPEED_1000: -+ if (tx_clk_1000_inverted) -+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED; -+ break; -+ case SPEED_100: -+ if (tx_clk_100_inverted) -+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED; -+ break; -+ case SPEED_10: -+ if (tx_clk_10_inverted) -+ val = YT8521_RC1R_TX_CLK_SEL_INVERTED; -+ break; -+ default: -+ return; -+ } -+ -+ ret = ytphy_modify_ext_with_lock(phydev, YT8521_RGMII_CONFIG1_REG, -+ YT8521_RC1R_TX_CLK_SEL_INVERTED, val); -+ if (ret < 0) -+ phydev_warn(phydev, "Modify TX_CLK_SEL err:%d\n", ret); -+} -+ - /** - * yt8521_prepare_fiber_features() - A small helper function that setup - * fiber's features. -@@ -1970,6 +2162,17 @@ static struct phy_driver motorcomm_phy_d - .resume = yt8521_resume, - }, - { -+ PHY_ID_MATCH_EXACT(PHY_ID_YT8531), -+ .name = "YT8531 Gigabit Ethernet", -+ .probe = yt8531_probe, -+ .config_init = yt8531_config_init, -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .get_wol = ytphy_get_wol, -+ .set_wol = yt8531_set_wol, -+ .link_change_notify = yt8531_link_change_notify, -+ }, -+ { - PHY_ID_MATCH_EXACT(PHY_ID_YT8531S), - .name = "YT8531S Gigabit Ethernet", - .get_features = yt8521_get_features, -@@ -1990,7 +2193,7 @@ static struct phy_driver motorcomm_phy_d - - module_phy_driver(motorcomm_phy_drvs); - --MODULE_DESCRIPTION("Motorcomm 8511/8521/8531S PHY driver"); -+MODULE_DESCRIPTION("Motorcomm 8511/8521/8531/8531S PHY driver"); - MODULE_AUTHOR("Peter Geis"); - MODULE_AUTHOR("Frank"); - MODULE_LICENSE("GPL"); -@@ -1998,6 +2201,7 @@ MODULE_LICENSE("GPL"); - static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = { - { PHY_ID_MATCH_EXACT(PHY_ID_YT8511) }, - { PHY_ID_MATCH_EXACT(PHY_ID_YT8521) }, -+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8531) }, - { PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) }, - { /* sentinel */ } - }; diff --git a/target/linux/generic/backport-6.1/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch b/target/linux/generic/backport-6.1/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch deleted file mode 100644 index 29ae86dbbc2c0c..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.3-10-net-phy-motorcomm-uninitialized-variables-in.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 9753613f7399601f9bae6ee81e9d4274246c98ab Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Wed, 15 Feb 2023 07:21:47 +0300 -Subject: [PATCH] net: phy: motorcomm: uninitialized variables in - yt8531_link_change_notify() - -These booleans are never set to false, but are just used without being -initialized. - -Fixes: 4ac94f728a58 ("net: phy: Add driver for Motorcomm yt8531 gigabit ethernet phy") -Signed-off-by: Dan Carpenter -Reviewed-by: Frank Sae -Link: https://lore.kernel.org/r/Y+xd2yJet2ImHLoQ@kili -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/motorcomm.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -1533,10 +1533,10 @@ static int yt8531_config_init(struct phy - static void yt8531_link_change_notify(struct phy_device *phydev) - { - struct device_node *node = phydev->mdio.dev.of_node; -+ bool tx_clk_1000_inverted = false; -+ bool tx_clk_100_inverted = false; -+ bool tx_clk_10_inverted = false; - bool tx_clk_adj_enabled = false; -- bool tx_clk_1000_inverted; -- bool tx_clk_100_inverted; -- bool tx_clk_10_inverted; - u16 val = 0; - int ret; - diff --git a/target/linux/generic/backport-6.1/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch b/target/linux/generic/backport-6.1/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch deleted file mode 100644 index 010ca9b68aac75..00000000000000 --- a/target/linux/generic/backport-6.1/791-v6.6-11-net-phy-motorcomm-Add-pad-drive-strength-cfg-support.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 7a561e9351ae7e3fb1f08584d40b49c1e55dde60 Mon Sep 17 00:00:00 2001 -From: Samin Guo -Date: Thu, 20 Jul 2023 19:15:09 +0800 -Subject: [PATCH] net: phy: motorcomm: Add pad drive strength cfg support - -The motorcomm phy (YT8531) supports the ability to adjust the drive -strength of the rx_clk/rx_data, and the default strength may not be -suitable for all boards. So add configurable options to better match -the boards.(e.g. StarFive VisionFive 2) - -When we configure the drive strength, we need to read the current -LDO voltage value to ensure that it is a legal value at that LDO -voltage. - -Reviewed-by: Hal Feng -Signed-off-by: Samin Guo -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/motorcomm.c | 118 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 118 insertions(+) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -163,6 +163,10 @@ - - #define YT8521_CHIP_CONFIG_REG 0xA001 - #define YT8521_CCR_SW_RST BIT(15) -+#define YT8531_RGMII_LDO_VOL_MASK GENMASK(5, 4) -+#define YT8531_LDO_VOL_3V3 0x0 -+#define YT8531_LDO_VOL_1V8 0x2 -+ - /* 1b0 disable 1.9ns rxc clock delay *default* - * 1b1 enable 1.9ns rxc clock delay - */ -@@ -236,6 +240,12 @@ - */ - #define YTPHY_WCR_TYPE_PULSE BIT(0) - -+#define YTPHY_PAD_DRIVE_STRENGTH_REG 0xA010 -+#define YT8531_RGMII_RXC_DS_MASK GENMASK(15, 13) -+#define YT8531_RGMII_RXD_DS_HI_MASK BIT(12) /* Bit 2 of rxd_ds */ -+#define YT8531_RGMII_RXD_DS_LOW_MASK GENMASK(5, 4) /* Bit 1/0 of rxd_ds */ -+#define YT8531_RGMII_RX_DS_DEFAULT 0x3 -+ - #define YTPHY_SYNCE_CFG_REG 0xA012 - #define YT8521_SCR_SYNCE_ENABLE BIT(5) - /* 1b0 output 25m clock -@@ -835,6 +845,110 @@ static int ytphy_rgmii_clk_delay_config_ - } - - /** -+ * struct ytphy_ldo_vol_map - map a current value to a register value -+ * @vol: ldo voltage -+ * @ds: value in the register -+ * @cur: value in device configuration -+ */ -+struct ytphy_ldo_vol_map { -+ u32 vol; -+ u32 ds; -+ u32 cur; -+}; -+ -+static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = { -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 0, .cur = 1200}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 1, .cur = 2100}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 2, .cur = 2700}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 3, .cur = 2910}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 4, .cur = 3110}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 5, .cur = 3600}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 6, .cur = 3970}, -+ {.vol = YT8531_LDO_VOL_1V8, .ds = 7, .cur = 4350}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 0, .cur = 3070}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 1, .cur = 4080}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 2, .cur = 4370}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 3, .cur = 4680}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 4, .cur = 5020}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 5, .cur = 5450}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 6, .cur = 5740}, -+ {.vol = YT8531_LDO_VOL_3V3, .ds = 7, .cur = 6140}, -+}; -+ -+static u32 yt8531_get_ldo_vol(struct phy_device *phydev) -+{ -+ u32 val; -+ -+ val = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG); -+ val = FIELD_GET(YT8531_RGMII_LDO_VOL_MASK, val); -+ -+ return val <= YT8531_LDO_VOL_1V8 ? val : YT8531_LDO_VOL_1V8; -+} -+ -+static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur) -+{ -+ u32 vol; -+ int i; -+ -+ vol = yt8531_get_ldo_vol(phydev); -+ for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) { -+ if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur) -+ return yt8531_ldo_vol[i].ds; -+ } -+ -+ return -EINVAL; -+} -+ -+static int yt8531_set_ds(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ u32 ds_field_low, ds_field_hi, val; -+ int ret, ds; -+ -+ /* set rgmii rx clk driver strength */ -+ if (!of_property_read_u32(node, "motorcomm,rx-clk-drv-microamp", &val)) { -+ ds = yt8531_get_ds_map(phydev, val); -+ if (ds < 0) -+ return dev_err_probe(&phydev->mdio.dev, ds, -+ "No matching current value was found.\n"); -+ } else { -+ ds = YT8531_RGMII_RX_DS_DEFAULT; -+ } -+ -+ ret = ytphy_modify_ext_with_lock(phydev, -+ YTPHY_PAD_DRIVE_STRENGTH_REG, -+ YT8531_RGMII_RXC_DS_MASK, -+ FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds)); -+ if (ret < 0) -+ return ret; -+ -+ /* set rgmii rx data driver strength */ -+ if (!of_property_read_u32(node, "motorcomm,rx-data-drv-microamp", &val)) { -+ ds = yt8531_get_ds_map(phydev, val); -+ if (ds < 0) -+ return dev_err_probe(&phydev->mdio.dev, ds, -+ "No matching current value was found.\n"); -+ } else { -+ ds = YT8531_RGMII_RX_DS_DEFAULT; -+ } -+ -+ ds_field_hi = FIELD_GET(BIT(2), ds); -+ ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi); -+ -+ ds_field_low = FIELD_GET(GENMASK(1, 0), ds); -+ ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low); -+ -+ ret = ytphy_modify_ext_with_lock(phydev, -+ YTPHY_PAD_DRIVE_STRENGTH_REG, -+ YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK, -+ ds_field_low | ds_field_hi); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+/** - * yt8521_probe() - read chip config then set suitable polling_mode - * @phydev: a pointer to a &struct phy_device - * -@@ -1518,6 +1632,10 @@ static int yt8531_config_init(struct phy - return ret; - } - -+ ret = yt8531_set_ds(phydev); -+ if (ret < 0) -+ return ret; -+ - return 0; - } - diff --git a/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch b/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch deleted file mode 100644 index f82c8fc622b99d..00000000000000 --- a/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 90ef0a7b0622c62758b2638604927867775479ea Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Thu, 13 Jul 2023 09:42:07 +0100 -Subject: [PATCH] net: phylink: add pcs_enable()/pcs_disable() methods - -Add phylink PCS enable/disable callbacks that will allow us to place -IEEE 802.3 register compliant PCS in power-down mode while not being -used. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/phylink.c | 48 +++++++++++++++++++++++++++++++-------- - include/linux/phylink.h | 16 +++++++++++++ - 2 files changed, 55 insertions(+), 9 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -34,6 +34,10 @@ enum { - PHYLINK_DISABLE_STOPPED, - PHYLINK_DISABLE_LINK, - PHYLINK_DISABLE_MAC_WOL, -+ -+ PCS_STATE_DOWN = 0, -+ PCS_STATE_STARTING, -+ PCS_STATE_STARTED, - }; - - /** -@@ -72,6 +76,7 @@ struct phylink { - struct phylink_link_state phy_state; - struct work_struct resolve; - unsigned int pcs_neg_mode; -+ unsigned int pcs_state; - - bool mac_link_dropped; - bool using_mac_select_pcs; -@@ -992,6 +997,22 @@ static void phylink_resolve_an_pause(str - } - } - -+static void phylink_pcs_disable(struct phylink_pcs *pcs) -+{ -+ if (pcs && pcs->ops->pcs_disable) -+ pcs->ops->pcs_disable(pcs); -+} -+ -+static int phylink_pcs_enable(struct phylink_pcs *pcs) -+{ -+ int err = 0; -+ -+ if (pcs && pcs->ops->pcs_enable) -+ err = pcs->ops->pcs_enable(pcs); -+ -+ return err; -+} -+ - static int phylink_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, - const struct phylink_link_state *state, - bool permit_pause_to_mac) -@@ -1094,11 +1115,17 @@ static void phylink_major_config(struct - /* If we have a new PCS, switch to the new PCS after preparing the MAC - * for the change. - */ -- if (pcs_changed) -+ if (pcs_changed) { -+ phylink_pcs_disable(pl->pcs); -+ - pl->pcs = pcs; -+ } - - phylink_mac_config(pl, state); - -+ if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) -+ phylink_pcs_enable(pl->pcs); -+ - neg_mode = pl->cur_link_an_mode; - if (pl->pcs && pl->pcs->neg_mode) - neg_mode = pl->pcs_neg_mode; -@@ -1586,6 +1613,7 @@ struct phylink *phylink_create(struct ph - pl->link_config.pause = MLO_PAUSE_AN; - pl->link_config.speed = SPEED_UNKNOWN; - pl->link_config.duplex = DUPLEX_UNKNOWN; -+ pl->pcs_state = PCS_STATE_DOWN; - pl->mac_ops = mac_ops; - __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); - timer_setup(&pl->link_poll, phylink_fixed_poll, 0); -@@ -1987,6 +2015,8 @@ void phylink_start(struct phylink *pl) - if (pl->netdev) - netif_carrier_off(pl->netdev); - -+ pl->pcs_state = PCS_STATE_STARTING; -+ - /* Apply the link configuration to the MAC when starting. This allows - * a fixed-link to start with the correct parameters, and also - * ensures that we set the appropriate advertisement for Serdes links. -@@ -1997,6 +2027,8 @@ void phylink_start(struct phylink *pl) - */ - phylink_mac_initial_config(pl, true); - -+ pl->pcs_state = PCS_STATE_STARTED; -+ - phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_STOPPED); - - if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { -@@ -2015,15 +2047,9 @@ void phylink_start(struct phylink *pl) - poll = true; - } - -- switch (pl->cfg_link_an_mode) { -- case MLO_AN_FIXED: -+ if (pl->cfg_link_an_mode == MLO_AN_FIXED) - poll |= pl->config->poll_fixed_state; -- break; -- case MLO_AN_INBAND: -- if (pl->pcs) -- poll |= pl->pcs->poll; -- break; -- } -+ - if (poll) - mod_timer(&pl->link_poll, jiffies + HZ); - if (pl->phydev) -@@ -2060,6 +2086,10 @@ void phylink_stop(struct phylink *pl) - } - - phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED); -+ -+ pl->pcs_state = PCS_STATE_DOWN; -+ -+ phylink_pcs_disable(pl->pcs); - } - EXPORT_SYMBOL_GPL(phylink_stop); - ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -533,6 +533,8 @@ struct phylink_pcs { - /** - * struct phylink_pcs_ops - MAC PCS operations structure. - * @pcs_validate: validate the link configuration. -+ * @pcs_enable: enable the PCS. -+ * @pcs_disable: disable the PCS. - * @pcs_get_state: read the current MAC PCS link state from the hardware. - * @pcs_config: configure the MAC PCS for the selected mode and state. - * @pcs_an_restart: restart 802.3z BaseX autonegotiation. -@@ -542,6 +544,8 @@ struct phylink_pcs { - struct phylink_pcs_ops { - int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported, - const struct phylink_link_state *state); -+ int (*pcs_enable)(struct phylink_pcs *pcs); -+ void (*pcs_disable)(struct phylink_pcs *pcs); - void (*pcs_get_state)(struct phylink_pcs *pcs, - struct phylink_link_state *state); - int (*pcs_config)(struct phylink_pcs *pcs, unsigned int neg_mode, -@@ -572,6 +576,18 @@ int pcs_validate(struct phylink_pcs *pcs - const struct phylink_link_state *state); - - /** -+ * pcs_enable() - enable the PCS. -+ * @pcs: a pointer to a &struct phylink_pcs. -+ */ -+int pcs_enable(struct phylink_pcs *pcs); -+ -+/** -+ * pcs_disable() - disable the PCS. -+ * @pcs: a pointer to a &struct phylink_pcs. -+ */ -+void pcs_disable(struct phylink_pcs *pcs); -+ -+/** - * pcs_get_state() - Read the current inband link state from the hardware - * @pcs: a pointer to a &struct phylink_pcs. - * @state: a pointer to a &struct phylink_link_state. diff --git a/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch b/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch deleted file mode 100644 index 6b6369761a185e..00000000000000 --- a/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch +++ /dev/null @@ -1,44 +0,0 @@ -From e4ccdfb78a47132f2d215658aab8902fc457c4b4 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 18 Aug 2023 04:07:46 +0100 -Subject: [PATCH 082/125] net: pcs: lynxi: implement pcs_disable op - -When switching from 10GBase-R/5GBase-R/USXGMII to one of the interface -modes provided by mtk-pcs-lynxi we need to make sure to always perform -a full configuration of the PHYA. - -Implement pcs_disable op which resets the stored interface mode to -PHY_INTERFACE_MODE_NA to trigger a full reconfiguration once the LynxI -PCS driver had previously been deselected in favor of another PCS -driver such as the to-be-added driver for the USXGMII PCS found in -MT7988. - -Signed-off-by: Daniel Golle -Link: https://lore.kernel.org/r/f23d1a60d2c9d2fb72e32dcb0eaa5f7e867a3d68.1692327891.git.daniel@makrotopia.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/pcs/pcs-mtk-lynxi.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/net/pcs/pcs-mtk-lynxi.c -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -234,11 +234,19 @@ static void mtk_pcs_lynxi_link_up(struct - } - } - -+static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ -+ mpcs->interface = PHY_INTERFACE_MODE_NA; -+} -+ - static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = { - .pcs_get_state = mtk_pcs_lynxi_get_state, - .pcs_config = mtk_pcs_lynxi_config, - .pcs_an_restart = mtk_pcs_lynxi_restart_an, - .pcs_link_up = mtk_pcs_lynxi_link_up, -+ .pcs_disable = mtk_pcs_lynxi_disable, - }; - - struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, diff --git a/target/linux/generic/backport-6.1/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch b/target/linux/generic/backport-6.1/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch deleted file mode 100644 index c4141eee933f43..00000000000000 --- a/target/linux/generic/backport-6.1/794-v6.2-net-core-Allow-live-renaming-when-an-interface-is-up.patch +++ /dev/null @@ -1,136 +0,0 @@ -From: Andy Ren -Date: Mon, 7 Nov 2022 09:42:42 -0800 -Subject: [PATCH] net/core: Allow live renaming when an interface is up - -Allow a network interface to be renamed when the interface -is up. - -As described in the netconsole documentation [1], when netconsole is -used as a built-in, it will bring up the specified interface as soon as -possible. As a result, user space will not be able to rename the -interface since the kernel disallows renaming of interfaces that are -administratively up unless the 'IFF_LIVE_RENAME_OK' private flag was set -by the kernel. - -The original solution [2] to this problem was to add a new parameter to -the netconsole configuration parameters that allows renaming of -the interface used by netconsole while it is administratively up. -However, during the discussion that followed, it became apparent that we -have no reason to keep the current restriction and instead we should -allow user space to rename interfaces regardless of their administrative -state: - -1. The restriction was put in place over 20 years ago when renaming was -only possible via IOCTL and before rtnetlink started notifying user -space about such changes like it does today. - -2. The 'IFF_LIVE_RENAME_OK' flag was added over 3 years ago in version -5.2 and no regressions were reported. - -3. In-kernel listeners to 'NETDEV_CHANGENAME' do not seem to care about -the administrative state of interface. - -Therefore, allow user space to rename running interfaces by removing the -restriction and the associated 'IFF_LIVE_RENAME_OK' flag. Help in -possible triage by emitting a message to the kernel log that an -interface was renamed while UP. - -[1] https://www.kernel.org/doc/Documentation/networking/netconsole.rst -[2] https://lore.kernel.org/netdev/20221102002420.2613004-1-andy.ren@getcruise.com/ - -Signed-off-by: Andy Ren -Reviewed-by: Ido Schimmel -Reviewed-by: David Ahern -Signed-off-by: David S. Miller ---- - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1691,7 +1691,6 @@ struct net_device_ops { - * @IFF_FAILOVER: device is a failover master device - * @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device - * @IFF_L3MDEV_RX_HANDLER: only invoke the rx handler of L3 master device -- * @IFF_LIVE_RENAME_OK: rename is allowed while device is up and running - * @IFF_TX_SKB_NO_LINEAR: device/driver is capable of xmitting frames with - * skb_headlen(skb) == 0 (data starts from frag0) - * @IFF_CHANGE_PROTO_DOWN: device supports setting carrier via IFLA_PROTO_DOWN -@@ -1727,7 +1726,7 @@ enum netdev_priv_flags { - IFF_FAILOVER = 1<<27, - IFF_FAILOVER_SLAVE = 1<<28, - IFF_L3MDEV_RX_HANDLER = 1<<29, -- IFF_LIVE_RENAME_OK = 1<<30, -+ /* was IFF_LIVE_RENAME_OK */ - IFF_TX_SKB_NO_LINEAR = BIT_ULL(31), - IFF_CHANGE_PROTO_DOWN = BIT_ULL(32), - }; -@@ -1762,7 +1761,6 @@ enum netdev_priv_flags { - #define IFF_FAILOVER IFF_FAILOVER - #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE - #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER --#define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK - #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR - - /* Specifies the type of the struct net_device::ml_priv pointer */ ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -1188,22 +1188,6 @@ int dev_change_name(struct net_device *d - - net = dev_net(dev); - -- /* Some auto-enslaved devices e.g. failover slaves are -- * special, as userspace might rename the device after -- * the interface had been brought up and running since -- * the point kernel initiated auto-enslavement. Allow -- * live name change even when these slave devices are -- * up and running. -- * -- * Typically, users of these auto-enslaving devices -- * don't actually care about slave name change, as -- * they are supposed to operate on master interface -- * directly. -- */ -- if (dev->flags & IFF_UP && -- likely(!(dev->priv_flags & IFF_LIVE_RENAME_OK))) -- return -EBUSY; -- - down_write(&devnet_rename_sem); - - if (strncmp(newname, dev->name, IFNAMSIZ) == 0) { -@@ -1220,7 +1204,8 @@ int dev_change_name(struct net_device *d - } - - if (oldname[0] && !strchr(oldname, '%')) -- netdev_info(dev, "renamed from %s\n", oldname); -+ netdev_info(dev, "renamed from %s%s\n", oldname, -+ dev->flags & IFF_UP ? " (while UP)" : ""); - - old_assign_type = dev->name_assign_type; - dev->name_assign_type = NET_NAME_RENAMED; ---- a/net/core/failover.c -+++ b/net/core/failover.c -@@ -80,14 +80,14 @@ static int failover_slave_register(struc - goto err_upper_link; - } - -- slave_dev->priv_flags |= (IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK); -+ slave_dev->priv_flags |= IFF_FAILOVER_SLAVE; - - if (fops && fops->slave_register && - !fops->slave_register(slave_dev, failover_dev)) - return NOTIFY_OK; - - netdev_upper_dev_unlink(slave_dev, failover_dev); -- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK); -+ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE; - err_upper_link: - netdev_rx_handler_unregister(slave_dev); - done: -@@ -121,7 +121,7 @@ int failover_slave_unregister(struct net - - netdev_rx_handler_unregister(slave_dev); - netdev_upper_dev_unlink(slave_dev, failover_dev); -- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK); -+ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE; - - if (fops && fops->slave_unregister && - !fops->slave_unregister(slave_dev, failover_dev)) diff --git a/target/linux/generic/backport-6.1/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch b/target/linux/generic/backport-6.1/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch deleted file mode 100644 index 17131c16d39f72..00000000000000 --- a/target/linux/generic/backport-6.1/795-v6.3-02-cdc_ether-no-need-to-blacklist-any-r8152-devices.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 69649ef8405320f81497f4757faac8234f61b167 Mon Sep 17 00:00:00 2001 -From: Bjørn Mork -Date: Fri, 6 Jan 2023 17:07:39 +0100 -Subject: [PATCH] cdc_ether: no need to blacklist any r8152 devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The r8152 driver does not need this anymore. - -Dropping blacklist entries adds optional support for these -devices in ECM mode. - -The 8153 devices are handled by the r8153_ecm driver when -in ECM mode, and must still be blacklisted here. - -Signed-off-by: Bjørn Mork -Signed-off-by: David S. Miller ---- - drivers/net/usb/cdc_ether.c | 114 ------------------------------------ - 1 file changed, 114 deletions(-) - ---- a/drivers/net/usb/cdc_ether.c -+++ b/drivers/net/usb/cdc_ether.c -@@ -768,13 +768,6 @@ static const struct usb_device_id produc - .driver_info = 0, - }, - --/* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- - /* Realtek RTL8153 Based USB 3.0 Ethernet Adapters */ - { - USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM, -@@ -782,119 +775,12 @@ static const struct usb_device_id produc - .driver_info = 0, - }, - --/* Samsung USB Ethernet Adapters */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, 0xa101, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --#if IS_ENABLED(CONFIG_USB_RTL8152) --/* Linksys USB3GIGV1 Ethernet Adapter */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LINKSYS_VENDOR_ID, 0x0041, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, --#endif -- --/* Lenovo ThinkPad OneLink+ Dock (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3054, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* ThinkPad USB-C Dock (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* ThinkPad Thunderbolt 3 Dock (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3069, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* ThinkPad Thunderbolt 3 Dock Gen 2 (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3082, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Lenovo USB C to Ethernet Adapter (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x720c, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Lenovo USB-C Travel Hub (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7214, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- - /* Lenovo Powered USB-C Travel Hub (4X90S92381, based on Realtek RTL8153) */ - { - USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x721e, USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), - .driver_info = 0, - }, -- --/* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0xa387, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* NVIDIA Tegra USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(NVIDIA_VENDOR_ID, 0x09ff, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Microsoft Surface 2 dock (based on Realtek RTL8152) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07ab, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07c6, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153B) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x0927, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, -- --/* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ --{ -- USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM, -- USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), -- .driver_info = 0, --}, - - /* Aquantia AQtion USB to 5GbE Controller (based on AQC111U) */ - { diff --git a/target/linux/generic/backport-6.1/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch b/target/linux/generic/backport-6.1/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch deleted file mode 100644 index 565fbb3074f979..00000000000000 --- a/target/linux/generic/backport-6.1/795-v6.3-05-r8152-reduce-the-control-transfer-of-rtl8152_get_ver.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 02767440e1dda9861a11ca1dbe0f19a760b1d5c2 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Thu, 19 Jan 2023 15:40:43 +0800 -Subject: [PATCH] r8152: reduce the control transfer of rtl8152_get_version() - -Reduce the control transfer by moving calling rtl8152_get_version() in -rtl8152_probe(). This could prevent from calling rtl8152_get_version() -for unnecessary situations. For example, after setting config #2 for the -device, there are two interfaces and rtl8152_probe() may be called -twice. However, we don't need to call rtl8152_get_version() for this -situation. - -Signed-off-by: Hayes Wang -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -9638,20 +9638,21 @@ static int rtl8152_probe(struct usb_inte - const struct usb_device_id *id) - { - struct usb_device *udev = interface_to_usbdev(intf); -- u8 version = rtl8152_get_version(intf); - struct r8152 *tp; - struct net_device *netdev; -+ u8 version; - int ret; - -- if (version == RTL_VER_UNKNOWN) -- return -ENODEV; -- - if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) - return -ENODEV; - - if (!rtl_check_vendor_ok(intf)) - return -ENODEV; - -+ version = rtl8152_get_version(intf); -+ if (version == RTL_VER_UNKNOWN) -+ return -ENODEV; -+ - usb_reset_device(udev); - netdev = alloc_etherdev(sizeof(struct r8152)); - if (!netdev) { diff --git a/target/linux/generic/backport-6.1/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch b/target/linux/generic/backport-6.1/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch deleted file mode 100644 index cdabca36d2a8a9..00000000000000 --- a/target/linux/generic/backport-6.1/795-v6.3-06-r8152-Add-__GFP_NOWARN-to-big-allocations.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 5cc33f139e11b893ff6dc60d8a0ae865a65521ac Mon Sep 17 00:00:00 2001 -From: Douglas Anderson -Date: Thu, 6 Apr 2023 17:14:26 -0700 -Subject: [PATCH] r8152: Add __GFP_NOWARN to big allocations - -When memory is a little tight on my system, it's pretty easy to see -warnings that look like this. - - ksoftirqd/0: page allocation failure: order:3, mode:0x40a20(GFP_ATOMIC|__GFP_COMP), nodemask=(null),cpuset=/,mems_allowed=0 - ... - Call trace: - dump_backtrace+0x0/0x1e8 - show_stack+0x20/0x2c - dump_stack_lvl+0x60/0x78 - dump_stack+0x18/0x38 - warn_alloc+0x104/0x174 - __alloc_pages+0x588/0x67c - alloc_rx_agg+0xa0/0x190 [r8152 ...] - r8152_poll+0x270/0x760 [r8152 ...] - __napi_poll+0x44/0x1ec - net_rx_action+0x100/0x300 - __do_softirq+0xec/0x38c - run_ksoftirqd+0x38/0xec - smpboot_thread_fn+0xb8/0x248 - kthread+0x134/0x154 - ret_from_fork+0x10/0x20 - -On a fragmented system it's normal that order 3 allocations will -sometimes fail, especially atomic ones. The driver handles these -failures fine and the WARN just creates spam in the logs for this -case. The __GFP_NOWARN flag is exactly for this situation, so add it -to the allocation. - -NOTE: my testing is on a 5.15 system, but there should be no reason -that this would be fundamentally different on a mainline kernel. - -Signed-off-by: Douglas Anderson -Acked-by: Hayes Wang -Link: https://lore.kernel.org/r/20230406171411.1.I84dbef45786af440fd269b71e9436a96a8e7a152@changeid -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -1947,7 +1947,7 @@ static struct rx_agg *alloc_rx_agg(struc - if (!rx_agg) - return NULL; - -- rx_agg->page = alloc_pages(mflags | __GFP_COMP, order); -+ rx_agg->page = alloc_pages(mflags | __GFP_COMP | __GFP_NOWARN, order); - if (!rx_agg->page) - goto free_rx; - diff --git a/target/linux/generic/backport-6.1/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch b/target/linux/generic/backport-6.1/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch deleted file mode 100644 index 3ba79d6cc6a383..00000000000000 --- a/target/linux/generic/backport-6.1/795-v6.6-08-r8152-adjust-generic_ocp_write-function.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 57df0fb9d511f91202114813e90128d65c0589f0 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Wed, 26 Jul 2023 11:08:07 +0800 -Subject: [PATCH] r8152: adjust generic_ocp_write function - -Reduce the control transfer if all bytes of first or the last DWORD are -written. - -The original method is to split the control transfer into three parts -(the first DWORD, middle continuous data, and the last DWORD). However, -they could be combined if whole bytes of the first DWORD or last DWORD -are written. That is, the first DWORD or the last DWORD could be combined -with the middle continuous data, if the byte_en is 0xff. - -Signed-off-by: Hayes Wang -Link: https://lore.kernel.org/r/20230726030808.9093-418-nic_swsd@realtek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 29 ++++++++++++++++++----------- - 1 file changed, 18 insertions(+), 11 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -1313,16 +1313,24 @@ static int generic_ocp_write(struct r815 - byteen_end = byteen & BYTE_EN_END_MASK; - - byen = byteen_start | (byteen_start << 4); -- ret = set_registers(tp, index, type | byen, 4, data); -- if (ret < 0) -- goto error1; -- -- index += 4; -- data += 4; -- size -= 4; - -- if (size) { -+ /* Split the first DWORD if the byte_en is not 0xff */ -+ if (byen != BYTE_EN_DWORD) { -+ ret = set_registers(tp, index, type | byen, 4, data); -+ if (ret < 0) -+ goto error1; -+ -+ index += 4; -+ data += 4; - size -= 4; -+ } -+ -+ if (size) { -+ byen = byteen_end | (byteen_end >> 4); -+ -+ /* Split the last DWORD if the byte_en is not 0xff */ -+ if (byen != BYTE_EN_DWORD) -+ size -= 4; - - while (size) { - if (size > limit) { -@@ -1349,10 +1357,9 @@ static int generic_ocp_write(struct r815 - } - } - -- byen = byteen_end | (byteen_end >> 4); -- ret = set_registers(tp, index, type | byen, 4, data); -- if (ret < 0) -- goto error1; -+ /* Set the last DWORD */ -+ if (byen != BYTE_EN_DWORD) -+ ret = set_registers(tp, index, type | byen, 4, data); - } - - error1: diff --git a/target/linux/generic/backport-6.1/795-v6.6-09-r8152-set-bp-in-bulk.patch b/target/linux/generic/backport-6.1/795-v6.6-09-r8152-set-bp-in-bulk.patch deleted file mode 100644 index bc70c5af02c708..00000000000000 --- a/target/linux/generic/backport-6.1/795-v6.6-09-r8152-set-bp-in-bulk.patch +++ /dev/null @@ -1,129 +0,0 @@ -From e5c266a61186b462c388c53a3564c375e72f2244 Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Wed, 26 Jul 2023 11:08:08 +0800 -Subject: [PATCH] r8152: set bp in bulk - -PLA_BP_0 ~ PLA_BP_15 (0xfc28 ~ 0xfc46) are continuous registers, so we -could combine the control transfers into one control transfer. - -Signed-off-by: Hayes Wang -Link: https://lore.kernel.org/r/20230726030808.9093-419-nic_swsd@realtek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 75 ++++++++++++++--------------------------- - 1 file changed, 25 insertions(+), 50 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -3990,29 +3990,10 @@ static void rtl_reset_bmu(struct r8152 * - /* Clear the bp to stop the firmware before loading a new one */ - static void rtl_clear_bp(struct r8152 *tp, u16 type) - { -- switch (tp->version) { -- case RTL_VER_01: -- case RTL_VER_02: -- case RTL_VER_07: -- break; -- case RTL_VER_03: -- case RTL_VER_04: -- case RTL_VER_05: -- case RTL_VER_06: -- ocp_write_byte(tp, type, PLA_BP_EN, 0); -- break; -- case RTL_VER_14: -- ocp_write_word(tp, type, USB_BP2_EN, 0); -+ u16 bp[16] = {0}; -+ u16 bp_num; - -- ocp_write_word(tp, type, USB_BP_8, 0); -- ocp_write_word(tp, type, USB_BP_9, 0); -- ocp_write_word(tp, type, USB_BP_10, 0); -- ocp_write_word(tp, type, USB_BP_11, 0); -- ocp_write_word(tp, type, USB_BP_12, 0); -- ocp_write_word(tp, type, USB_BP_13, 0); -- ocp_write_word(tp, type, USB_BP_14, 0); -- ocp_write_word(tp, type, USB_BP_15, 0); -- break; -+ switch (tp->version) { - case RTL_VER_08: - case RTL_VER_09: - case RTL_VER_10: -@@ -4020,32 +4001,31 @@ static void rtl_clear_bp(struct r8152 *t - case RTL_VER_12: - case RTL_VER_13: - case RTL_VER_15: -- default: - if (type == MCU_TYPE_USB) { - ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0); -- -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0); -- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0); -- } else { -- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0); -+ bp_num = 16; -+ break; - } -+ fallthrough; -+ case RTL_VER_03: -+ case RTL_VER_04: -+ case RTL_VER_05: -+ case RTL_VER_06: -+ ocp_write_byte(tp, type, PLA_BP_EN, 0); -+ fallthrough; -+ case RTL_VER_01: -+ case RTL_VER_02: -+ case RTL_VER_07: -+ bp_num = 8; -+ break; -+ case RTL_VER_14: -+ default: -+ ocp_write_word(tp, type, USB_BP2_EN, 0); -+ bp_num = 16; - break; - } - -- ocp_write_word(tp, type, PLA_BP_0, 0); -- ocp_write_word(tp, type, PLA_BP_1, 0); -- ocp_write_word(tp, type, PLA_BP_2, 0); -- ocp_write_word(tp, type, PLA_BP_3, 0); -- ocp_write_word(tp, type, PLA_BP_4, 0); -- ocp_write_word(tp, type, PLA_BP_5, 0); -- ocp_write_word(tp, type, PLA_BP_6, 0); -- ocp_write_word(tp, type, PLA_BP_7, 0); -+ generic_ocp_write(tp, PLA_BP_0, BYTE_EN_DWORD, bp_num << 1, bp, type); - - /* wait 3 ms to make sure the firmware is stopped */ - usleep_range(3000, 6000); -@@ -5022,10 +5002,9 @@ static void rtl8152_fw_phy_nc_apply(stru - - static void rtl8152_fw_mac_apply(struct r8152 *tp, struct fw_mac *mac) - { -- u16 bp_en_addr, bp_index, type, bp_num, fw_ver_reg; -+ u16 bp_en_addr, type, fw_ver_reg; - u32 length; - u8 *data; -- int i; - - switch (__le32_to_cpu(mac->blk_hdr.type)) { - case RTL_FW_PLA: -@@ -5067,12 +5046,8 @@ static void rtl8152_fw_mac_apply(struct - ocp_write_word(tp, type, __le16_to_cpu(mac->bp_ba_addr), - __le16_to_cpu(mac->bp_ba_value)); - -- bp_index = __le16_to_cpu(mac->bp_start); -- bp_num = __le16_to_cpu(mac->bp_num); -- for (i = 0; i < bp_num; i++) { -- ocp_write_word(tp, type, bp_index, __le16_to_cpu(mac->bp[i])); -- bp_index += 2; -- } -+ generic_ocp_write(tp, __le16_to_cpu(mac->bp_start), BYTE_EN_DWORD, -+ __le16_to_cpu(mac->bp_num) << 1, mac->bp, type); - - bp_en_addr = __le16_to_cpu(mac->bp_en_addr); - if (bp_en_addr) diff --git a/target/linux/generic/backport-6.1/795-v6.6-10-eth-r8152-try-to-use-a-normal-budget.patch b/target/linux/generic/backport-6.1/795-v6.6-10-eth-r8152-try-to-use-a-normal-budget.patch deleted file mode 100644 index d7fdcdb2c63000..00000000000000 --- a/target/linux/generic/backport-6.1/795-v6.6-10-eth-r8152-try-to-use-a-normal-budget.patch +++ /dev/null @@ -1,39 +0,0 @@ -From cf74eb5a5bc867258e7d0b0d1c3c4a60e1e3de2f Mon Sep 17 00:00:00 2001 -From: Jakub Kicinski -Date: Mon, 14 Aug 2023 08:35:21 -0700 -Subject: [PATCH] eth: r8152: try to use a normal budget - -Mario reports that loading r8152 on his system leads to a: - - netif_napi_add_weight() called with weight 256 - -warning getting printed. We don't have any solid data -on why such high budget was chosen, and it may cause -stalls in processing other softirqs and rt threads. -So try to switch back to the default (64) weight. - -If this slows down someone's system we should investigate -which part of stopping starting the NAPI poll in this -driver are expensive. - -Reported-by: Mario Limonciello -Link: https://lore.kernel.org/all/0bfd445a-81f7-f702-08b0-bd5a72095e49@amd.com/ -Acked-by: Hayes Wang -Link: https://lore.kernel.org/r/20230814153521.2697982-1-kuba@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -9784,8 +9784,7 @@ static int rtl8152_probe(struct usb_inte - - usb_set_intfdata(intf, tp); - -- netif_napi_add_weight(netdev, &tp->napi, r8152_poll, -- tp->support_2500full ? 256 : 64); -+ netif_napi_add(netdev, &tp->napi, r8152_poll); - - ret = register_netdev(netdev); - if (ret != 0) { diff --git a/target/linux/generic/backport-6.1/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch b/target/linux/generic/backport-6.1/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch deleted file mode 100644 index 8901767be5239e..00000000000000 --- a/target/linux/generic/backport-6.1/795-v6.6-13-r8152-Block-future-register-access-if-register-acces.patch +++ /dev/null @@ -1,398 +0,0 @@ -From d9962b0d42029bcb40fe3c38bce06d1870fa4df4 Mon Sep 17 00:00:00 2001 -From: Douglas Anderson -Date: Fri, 20 Oct 2023 14:06:59 -0700 -Subject: [PATCH] r8152: Block future register access if register access fails - -Even though the functions to read/write registers can fail, most of -the places in the r8152 driver that read/write register values don't -check error codes. The lack of error code checking is problematic in -at least two ways. - -The first problem is that the r8152 driver often uses code patterns -similar to this: - x = read_register() - x = x | SOME_BIT; - write_register(x); - -...with the above pattern, if the read_register() fails and returns -garbage then we'll end up trying to write modified garbage back to the -Realtek adapter. If the write_register() succeeds that's bad. Note -that as of commit f53a7ad18959 ("r8152: Set memory to all 0xFFs on -failed reg reads") the "garbage" returned by read_register() will at -least be consistent garbage, but it is still garbage. - -It turns out that this problem is very serious. Writing garbage to -some of the hardware registers on the Ethernet adapter can put the -adapter in such a bad state that it needs to be power cycled (fully -unplugged and plugged in again) before it can enumerate again. - -The second problem is that the r8152 driver generally has functions -that are long sequences of register writes. Assuming everything will -be OK if a random register write fails in the middle isn't a great -assumption. - -One might wonder if the above two problems are real. You could ask if -we would really have a successful write after a failed read. It turns -out that the answer appears to be "yes, this can happen". In fact, -we've seen at least two distinct failure modes where this happens. - -On a sc7180-trogdor Chromebook if you drop into kdb for a while and -then resume, you can see: -1. We get a "Tx timeout" -2. The "Tx timeout" queues up a USB reset. -3. In rtl8152_pre_reset() we try to reinit the hardware. -4. The first several (2-9) register accesses fail with a timeout, then - things recover. - -The above test case was actually fixed by the patch ("r8152: Increase -USB control msg timeout to 5000ms as per spec") but at least shows -that we really can see successful calls after failed ones. - -On a different (AMD) based Chromebook with a particular adapter, we -found that during reboot tests we'd also sometimes get a transitory -failure. In this case we saw -EPIPE being returned sometimes. Retrying -worked, but retrying is not always safe for all register accesses -since reading/writing some registers might have side effects (like -registers that clear on read). - -Let's fully lock out all register access if a register access fails. -When we do this, we'll try to queue up a USB reset and try to unlock -register access after the reset. This is slightly tricker than it -sounds since the r8152 driver has an optimized reset sequence that -only works reliably after probe happens. In order to handle this, we -avoid the optimized reset if probe didn't finish. Instead, we simply -retry the probe routine in this case. - -When locking out access, we'll use the existing infrastructure that -the driver was using when it detected we were unplugged. This keeps us -from getting stuck in delay loops in some parts of the driver. - -Signed-off-by: Douglas Anderson -Reviewed-by: Grant Grundler -Signed-off-by: David S. Miller ---- - drivers/net/usb/r8152.c | 207 ++++++++++++++++++++++++++++++++++------ - 1 file changed, 176 insertions(+), 31 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -772,6 +772,9 @@ enum rtl8152_flags { - SCHEDULE_TASKLET, - GREEN_ETHERNET, - RX_EPROTO, -+ IN_PRE_RESET, -+ PROBED_WITH_NO_ERRORS, -+ PROBE_SHOULD_RETRY, - }; - - #define DEVICE_ID_LENOVO_USB_C_TRAVEL_HUB 0x721e -@@ -952,6 +955,8 @@ struct r8152 { - u8 version; - u8 duplex; - u8 autoneg; -+ -+ unsigned int reg_access_reset_count; - }; - - /** -@@ -1199,6 +1204,96 @@ static unsigned int agg_buf_sz = 16384; - - #define RTL_LIMITED_TSO_SIZE (size_to_mtu(agg_buf_sz) - sizeof(struct tx_desc)) - -+/* If register access fails then we block access and issue a reset. If this -+ * happens too many times in a row without a successful access then we stop -+ * trying to reset and just leave access blocked. -+ */ -+#define REGISTER_ACCESS_MAX_RESETS 3 -+ -+static void rtl_set_inaccessible(struct r8152 *tp) -+{ -+ set_bit(RTL8152_INACCESSIBLE, &tp->flags); -+ smp_mb__after_atomic(); -+} -+ -+static void rtl_set_accessible(struct r8152 *tp) -+{ -+ clear_bit(RTL8152_INACCESSIBLE, &tp->flags); -+ smp_mb__after_atomic(); -+} -+ -+static -+int r8152_control_msg(struct r8152 *tp, unsigned int pipe, __u8 request, -+ __u8 requesttype, __u16 value, __u16 index, void *data, -+ __u16 size, const char *msg_tag) -+{ -+ struct usb_device *udev = tp->udev; -+ int ret; -+ -+ if (test_bit(RTL8152_INACCESSIBLE, &tp->flags)) -+ return -ENODEV; -+ -+ ret = usb_control_msg(udev, pipe, request, requesttype, -+ value, index, data, size, -+ USB_CTRL_GET_TIMEOUT); -+ -+ /* No need to issue a reset to report an error if the USB device got -+ * unplugged; just return immediately. -+ */ -+ if (ret == -ENODEV) -+ return ret; -+ -+ /* If the write was successful then we're done */ -+ if (ret >= 0) { -+ tp->reg_access_reset_count = 0; -+ return ret; -+ } -+ -+ dev_err(&udev->dev, -+ "Failed to %s %d bytes at %#06x/%#06x (%d)\n", -+ msg_tag, size, value, index, ret); -+ -+ /* Block all future register access until we reset. Much of the code -+ * in the driver doesn't check for errors. Notably, many parts of the -+ * driver do a read/modify/write of a register value without -+ * confirming that the read succeeded. Writing back modified garbage -+ * like this can fully wedge the adapter, requiring a power cycle. -+ */ -+ rtl_set_inaccessible(tp); -+ -+ /* If probe hasn't yet finished, then we'll request a retry of the -+ * whole probe routine if we get any control transfer errors. We -+ * never have to clear this bit since we free/reallocate the whole "tp" -+ * structure if we retry probe. -+ */ -+ if (!test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) { -+ set_bit(PROBE_SHOULD_RETRY, &tp->flags); -+ return ret; -+ } -+ -+ /* Failing to access registers in pre-reset is not surprising since we -+ * wouldn't be resetting if things were behaving normally. The register -+ * access we do in pre-reset isn't truly mandatory--we're just reusing -+ * the disable() function and trying to be nice by powering the -+ * adapter down before resetting it. Thus, if we're in pre-reset, -+ * we'll return right away and not try to queue up yet another reset. -+ * We know the post-reset is already coming. -+ */ -+ if (test_bit(IN_PRE_RESET, &tp->flags)) -+ return ret; -+ -+ if (tp->reg_access_reset_count < REGISTER_ACCESS_MAX_RESETS) { -+ usb_queue_reset_device(tp->intf); -+ tp->reg_access_reset_count++; -+ } else if (tp->reg_access_reset_count == REGISTER_ACCESS_MAX_RESETS) { -+ dev_err(&udev->dev, -+ "Tried to reset %d times; giving up.\n", -+ REGISTER_ACCESS_MAX_RESETS); -+ } -+ -+ return ret; -+} -+ - static - int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) - { -@@ -1209,9 +1304,10 @@ int get_registers(struct r8152 *tp, u16 - if (!tmp) - return -ENOMEM; - -- ret = usb_control_msg(tp->udev, tp->pipe_ctrl_in, -- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, -- value, index, tmp, size, USB_CTRL_GET_TIMEOUT); -+ ret = r8152_control_msg(tp, tp->pipe_ctrl_in, -+ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, -+ value, index, tmp, size, "read"); -+ - if (ret < 0) - memset(data, 0xff, size); - else -@@ -1232,9 +1328,9 @@ int set_registers(struct r8152 *tp, u16 - if (!tmp) - return -ENOMEM; - -- ret = usb_control_msg(tp->udev, tp->pipe_ctrl_out, -- RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, -- value, index, tmp, size, USB_CTRL_SET_TIMEOUT); -+ ret = r8152_control_msg(tp, tp->pipe_ctrl_out, -+ RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, -+ value, index, tmp, size, "write"); - - kfree(tmp); - -@@ -1243,10 +1339,8 @@ int set_registers(struct r8152 *tp, u16 - - static void rtl_set_unplug(struct r8152 *tp) - { -- if (tp->udev->state == USB_STATE_NOTATTACHED) { -- set_bit(RTL8152_INACCESSIBLE, &tp->flags); -- smp_mb__after_atomic(); -- } -+ if (tp->udev->state == USB_STATE_NOTATTACHED) -+ rtl_set_inaccessible(tp); - } - - static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, -@@ -8275,7 +8369,7 @@ static int rtl8152_pre_reset(struct usb_ - struct r8152 *tp = usb_get_intfdata(intf); - struct net_device *netdev; - -- if (!tp) -+ if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) - return 0; - - netdev = tp->netdev; -@@ -8290,7 +8384,9 @@ static int rtl8152_pre_reset(struct usb_ - napi_disable(&tp->napi); - if (netif_carrier_ok(netdev)) { - mutex_lock(&tp->control); -+ set_bit(IN_PRE_RESET, &tp->flags); - tp->rtl_ops.disable(tp); -+ clear_bit(IN_PRE_RESET, &tp->flags); - mutex_unlock(&tp->control); - } - -@@ -8303,9 +8399,11 @@ static int rtl8152_post_reset(struct usb - struct net_device *netdev; - struct sockaddr sa; - -- if (!tp) -+ if (!tp || !test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) - return 0; - -+ rtl_set_accessible(tp); -+ - /* reset the MAC address in case of policy change */ - if (determine_ethernet_addr(tp, &sa) >= 0) { - rtnl_lock(); -@@ -9507,17 +9605,29 @@ static u8 __rtl_get_hw_ver(struct usb_de - __le32 *tmp; - u8 version; - int ret; -+ int i; - - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); - if (!tmp) - return 0; - -- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), -- RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, -- PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), -- USB_CTRL_GET_TIMEOUT); -- if (ret > 0) -- ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK; -+ /* Retry up to 3 times in case there is a transitory error. We do this -+ * since retrying a read of the version is always safe and this -+ * function doesn't take advantage of r8152_control_msg(). -+ */ -+ for (i = 0; i < 3; i++) { -+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), -+ RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, -+ PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), -+ USB_CTRL_GET_TIMEOUT); -+ if (ret > 0) { -+ ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK; -+ break; -+ } -+ } -+ -+ if (i != 0 && ret > 0) -+ dev_warn(&udev->dev, "Needed %d retries to read version\n", i); - - kfree(tmp); - -@@ -9616,25 +9726,14 @@ static bool rtl8152_supports_lenovo_macp - return 0; - } - --static int rtl8152_probe(struct usb_interface *intf, -- const struct usb_device_id *id) -+static int rtl8152_probe_once(struct usb_interface *intf, -+ const struct usb_device_id *id, u8 version) - { - struct usb_device *udev = interface_to_usbdev(intf); - struct r8152 *tp; - struct net_device *netdev; -- u8 version; - int ret; - -- if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) -- return -ENODEV; -- -- if (!rtl_check_vendor_ok(intf)) -- return -ENODEV; -- -- version = rtl8152_get_version(intf); -- if (version == RTL_VER_UNKNOWN) -- return -ENODEV; -- - usb_reset_device(udev); - netdev = alloc_etherdev(sizeof(struct r8152)); - if (!netdev) { -@@ -9797,10 +9896,20 @@ static int rtl8152_probe(struct usb_inte - else - device_set_wakeup_enable(&udev->dev, false); - -+ /* If we saw a control transfer error while probing then we may -+ * want to try probe() again. Consider this an error. -+ */ -+ if (test_bit(PROBE_SHOULD_RETRY, &tp->flags)) -+ goto out2; -+ -+ set_bit(PROBED_WITH_NO_ERRORS, &tp->flags); - netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION); - - return 0; - -+out2: -+ unregister_netdev(netdev); -+ - out1: - tasklet_kill(&tp->tx_tl); - cancel_delayed_work_sync(&tp->hw_phy_work); -@@ -9809,10 +9918,46 @@ out1: - rtl8152_release_firmware(tp); - usb_set_intfdata(intf, NULL); - out: -+ if (test_bit(PROBE_SHOULD_RETRY, &tp->flags)) -+ ret = -EAGAIN; -+ - free_netdev(netdev); - return ret; - } - -+#define RTL8152_PROBE_TRIES 3 -+ -+static int rtl8152_probe(struct usb_interface *intf, -+ const struct usb_device_id *id) -+{ -+ u8 version; -+ int ret; -+ int i; -+ -+ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) -+ return -ENODEV; -+ -+ if (!rtl_check_vendor_ok(intf)) -+ return -ENODEV; -+ -+ version = rtl8152_get_version(intf); -+ if (version == RTL_VER_UNKNOWN) -+ return -ENODEV; -+ -+ for (i = 0; i < RTL8152_PROBE_TRIES; i++) { -+ ret = rtl8152_probe_once(intf, id, version); -+ if (ret != -EAGAIN) -+ break; -+ } -+ if (ret == -EAGAIN) { -+ dev_err(&intf->dev, -+ "r8152 failed probe after %d tries; giving up\n", i); -+ return -ENODEV; -+ } -+ -+ return ret; -+} -+ - static void rtl8152_disconnect(struct usb_interface *intf) - { - struct r8152 *tp = usb_get_intfdata(intf); diff --git a/target/linux/generic/backport-6.1/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch b/target/linux/generic/backport-6.1/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch deleted file mode 100644 index 7bbd1be82085aa..00000000000000 --- a/target/linux/generic/backport-6.1/795-v6.6-14-r8152-break-the-loop-when-the-budget-is-exhausted.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 66eee612a1ba39f9a76a9ace4a34d012044767fb Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Tue, 26 Sep 2023 19:17:13 +0800 -Subject: [PATCH] r8152: break the loop when the budget is exhausted - -[ Upstream commit 2cf51f931797d9a47e75d999d0993a68cbd2a560 ] - -A bulk transfer of the USB may contain many packets. And, the total -number of the packets in the bulk transfer may be more than budget. - -Originally, only budget packets would be handled by napi_gro_receive(), -and the other packets would be queued in the driver for next schedule. - -This patch would break the loop about getting next bulk transfer, when -the budget is exhausted. That is, only the current bulk transfer would -be handled, and the other bulk transfers would be queued for next -schedule. Besides, the packets which are more than the budget in the -current bulk trasnfer would be still queued in the driver, as the -original method. - -In addition, a bulk transfer wouldn't contain more than 400 packets, so -the check of queue length is unnecessary. Therefore, I replace it with -WARN_ON_ONCE(). - -Fixes: cf74eb5a5bc8 ("eth: r8152: try to use a normal budget") -Signed-off-by: Hayes Wang -Link: https://lore.kernel.org/r/20230926111714.9448-433-nic_swsd@realtek.com -Signed-off-by: Jakub Kicinski -Signed-off-by: Sasha Levin ---- - drivers/net/usb/r8152.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -2542,7 +2542,7 @@ static int rx_bottom(struct r8152 *tp, i - } - } - -- if (list_empty(&tp->rx_done)) -+ if (list_empty(&tp->rx_done) || work_done >= budget) - goto out1; - - clear_bit(RX_EPROTO, &tp->flags); -@@ -2558,6 +2558,15 @@ static int rx_bottom(struct r8152 *tp, i - struct urb *urb; - u8 *rx_data; - -+ /* A bulk transfer of USB may contain may packets, so the -+ * total packets may more than the budget. Deal with all -+ * packets in current bulk transfer, and stop to handle the -+ * next bulk transfer until next schedule, if budget is -+ * exhausted. -+ */ -+ if (work_done >= budget) -+ break; -+ - list_del_init(cursor); - - agg = list_entry(cursor, struct rx_agg, list); -@@ -2577,9 +2586,7 @@ static int rx_bottom(struct r8152 *tp, i - unsigned int pkt_len, rx_frag_head_sz; - struct sk_buff *skb; - -- /* limit the skb numbers for rx_queue */ -- if (unlikely(skb_queue_len(&tp->rx_queue) >= 1000)) -- break; -+ WARN_ON_ONCE(skb_queue_len(&tp->rx_queue) >= 1000); - - pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; - if (pkt_len < ETH_ZLEN) -@@ -2657,9 +2664,10 @@ submit: - } - } - -+ /* Splice the remained list back to rx_done for next schedule */ - if (!list_empty(&rx_queue)) { - spin_lock_irqsave(&tp->rx_lock, flags); -- list_splice_tail(&rx_queue, &tp->rx_done); -+ list_splice(&rx_queue, &tp->rx_done); - spin_unlock_irqrestore(&tp->rx_lock, flags); - } - diff --git a/target/linux/generic/backport-6.1/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch b/target/linux/generic/backport-6.1/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch deleted file mode 100644 index c858152067c96a..00000000000000 --- a/target/linux/generic/backport-6.1/795-v6.6-15-net-usb-cdc_ether-add-u-blox-0x1313-composition.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 1b0fce8c8e69485e49a7d34aac3d4c2a2aa15d62 Mon Sep 17 00:00:00 2001 -From: Davide Tronchin -Date: Thu, 29 Jun 2023 12:37:36 +0200 -Subject: [PATCH] net: usb: cdc_ether: add u-blox 0x1313 composition. - -Add CDC-ECM support for LARA-R6 01B. - -The new LARA-R6 product variant identified by the "01B" string can be -configured (by AT interface) in three different USB modes: -* Default mode (Vendor ID: 0x1546 Product ID: 0x1311) with 4 serial -interfaces -* RmNet mode (Vendor ID: 0x1546 Product ID: 0x1312) with 4 serial -interfaces and 1 RmNet virtual network interface -* CDC-ECM mode (Vendor ID: 0x1546 Product ID: 0x1313) with 4 serial -interface and 1 CDC-ECM virtual network interface -The first 4 interfaces of all the 3 configurations (default, RmNet, ECM) -are the same. - -In CDC-ECM mode LARA-R6 01B exposes the following interfaces: -If 0: Diagnostic -If 1: AT parser -If 2: AT parser -If 3: AT parset/alternative functions -If 4: CDC-ECM interface - -Signed-off-by: Davide Tronchin -Reviewed-by: Simon Horman -Signed-off-by: David S. Miller ---- - drivers/net/usb/cdc_ether.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/usb/cdc_ether.c -+++ b/drivers/net/usb/cdc_ether.c -@@ -879,6 +879,12 @@ static const struct usb_device_id produc - USB_CDC_PROTO_NONE), - .driver_info = (unsigned long)&wwan_info, - }, { -+ /* U-blox LARA-R6 01B */ -+ USB_DEVICE_AND_INTERFACE_INFO(UBLOX_VENDOR_ID, 0x1313, USB_CLASS_COMM, -+ USB_CDC_SUBCLASS_ETHERNET, -+ USB_CDC_PROTO_NONE), -+ .driver_info = (unsigned long)&wwan_info, -+}, { - /* ZTE modules */ - USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, diff --git a/target/linux/generic/backport-6.1/795-v6.7-16-r8152-use-napi_gro_frags.patch b/target/linux/generic/backport-6.1/795-v6.7-16-r8152-use-napi_gro_frags.patch deleted file mode 100644 index 3c9680a2790ae4..00000000000000 --- a/target/linux/generic/backport-6.1/795-v6.7-16-r8152-use-napi_gro_frags.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 788d30daa8f97f06166b6a63f0e51f2a4c2f036a Mon Sep 17 00:00:00 2001 -From: Hayes Wang -Date: Tue, 26 Sep 2023 19:17:14 +0800 -Subject: [PATCH] r8152: use napi_gro_frags - -Use napi_gro_frags() for the skb of fragments when the work_done is less -than budget. - -Signed-off-by: Hayes Wang -Link: https://lore.kernel.org/r/20230926111714.9448-434-nic_swsd@realtek.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/usb/r8152.c | 67 ++++++++++++++++++++++++++++++----------- - 1 file changed, 50 insertions(+), 17 deletions(-) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -2583,8 +2583,9 @@ static int rx_bottom(struct r8152 *tp, i - while (urb->actual_length > len_used) { - struct net_device *netdev = tp->netdev; - struct net_device_stats *stats = &netdev->stats; -- unsigned int pkt_len, rx_frag_head_sz; -+ unsigned int pkt_len, rx_frag_head_sz, len; - struct sk_buff *skb; -+ bool use_frags; - - WARN_ON_ONCE(skb_queue_len(&tp->rx_queue) >= 1000); - -@@ -2597,45 +2598,77 @@ static int rx_bottom(struct r8152 *tp, i - break; - - pkt_len -= ETH_FCS_LEN; -+ len = pkt_len; - rx_data += sizeof(struct rx_desc); - -- if (!agg_free || tp->rx_copybreak > pkt_len) -- rx_frag_head_sz = pkt_len; -+ if (!agg_free || tp->rx_copybreak > len) -+ use_frags = false; - else -- rx_frag_head_sz = tp->rx_copybreak; -+ use_frags = true; -+ -+ if (use_frags) { -+ /* If the budget is exhausted, the packet -+ * would be queued in the driver. That is, -+ * napi_gro_frags() wouldn't be called, so -+ * we couldn't use napi_get_frags(). -+ */ -+ if (work_done >= budget) { -+ rx_frag_head_sz = tp->rx_copybreak; -+ skb = napi_alloc_skb(napi, -+ rx_frag_head_sz); -+ } else { -+ rx_frag_head_sz = 0; -+ skb = napi_get_frags(napi); -+ } -+ } else { -+ rx_frag_head_sz = 0; -+ skb = napi_alloc_skb(napi, len); -+ } - -- skb = napi_alloc_skb(napi, rx_frag_head_sz); - if (!skb) { - stats->rx_dropped++; - goto find_next_rx; - } - - skb->ip_summed = r8152_rx_csum(tp, rx_desc); -- memcpy(skb->data, rx_data, rx_frag_head_sz); -- skb_put(skb, rx_frag_head_sz); -- pkt_len -= rx_frag_head_sz; -- rx_data += rx_frag_head_sz; -- if (pkt_len) { -+ rtl_rx_vlan_tag(rx_desc, skb); -+ -+ if (use_frags) { -+ if (rx_frag_head_sz) { -+ memcpy(skb->data, rx_data, -+ rx_frag_head_sz); -+ skb_put(skb, rx_frag_head_sz); -+ len -= rx_frag_head_sz; -+ rx_data += rx_frag_head_sz; -+ skb->protocol = eth_type_trans(skb, -+ netdev); -+ } -+ - skb_add_rx_frag(skb, 0, agg->page, - agg_offset(agg, rx_data), -- pkt_len, -- SKB_DATA_ALIGN(pkt_len)); -+ len, SKB_DATA_ALIGN(len)); - get_page(agg->page); -+ } else { -+ memcpy(skb->data, rx_data, len); -+ skb_put(skb, len); -+ skb->protocol = eth_type_trans(skb, netdev); - } - -- skb->protocol = eth_type_trans(skb, netdev); -- rtl_rx_vlan_tag(rx_desc, skb); - if (work_done < budget) { -+ if (use_frags) -+ napi_gro_frags(napi); -+ else -+ napi_gro_receive(napi, skb); -+ - work_done++; - stats->rx_packets++; -- stats->rx_bytes += skb->len; -- napi_gro_receive(napi, skb); -+ stats->rx_bytes += pkt_len; - } else { - __skb_queue_tail(&tp->rx_queue, skb); - } - - find_next_rx: -- rx_data = rx_agg_align(rx_data + pkt_len + ETH_FCS_LEN); -+ rx_data = rx_agg_align(rx_data + len + ETH_FCS_LEN); - rx_desc = (struct rx_desc *)rx_data; - len_used = agg_offset(agg, rx_data); - len_used += sizeof(struct rx_desc); diff --git a/target/linux/generic/backport-6.1/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch b/target/linux/generic/backport-6.1/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch deleted file mode 100644 index d9d6f36fcef385..00000000000000 --- a/target/linux/generic/backport-6.1/796-v6.5-01-usbnet-ipheth-fix-risk-of-NULL-pointer-deallocation.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 2203718c2f59ffdd6c78d54e5add594aebb4461e Mon Sep 17 00:00:00 2001 -From: Georgi Valkov -Date: Wed, 7 Jun 2023 15:56:59 +0200 -Subject: [PATCH 1/4] usbnet: ipheth: fix risk of NULL pointer deallocation - -The cleanup precedure in ipheth_probe will attempt to free a -NULL pointer in dev->ctrl_buf if the memory allocation for -this buffer is not successful. While kfree ignores NULL pointers, -and the existing code is safe, it is a better design to rearrange -the goto labels and avoid this. - -Signed-off-by: Georgi Valkov -Signed-off-by: Foster Snowhill -Signed-off-by: David S. Miller ---- - drivers/net/usb/ipheth.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/usb/ipheth.c -+++ b/drivers/net/usb/ipheth.c -@@ -510,8 +510,8 @@ err_register_netdev: - ipheth_free_urbs(dev); - err_alloc_urbs: - err_get_macaddr: --err_alloc_ctrl_buf: - kfree(dev->ctrl_buf); -+err_alloc_ctrl_buf: - err_endpoints: - free_netdev(netdev); - return retval; diff --git a/target/linux/generic/backport-6.1/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch b/target/linux/generic/backport-6.1/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch deleted file mode 100644 index adfec356d9faee..00000000000000 --- a/target/linux/generic/backport-6.1/796-v6.5-02-usbnet-ipheth-transmit-URBs-without-trailing-padding.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 3e65efcca87a9bb5f3b864e0a43d167bc0a8688c Mon Sep 17 00:00:00 2001 -From: Foster Snowhill -Date: Wed, 7 Jun 2023 15:57:00 +0200 -Subject: [PATCH 2/4] usbnet: ipheth: transmit URBs without trailing padding - -The behaviour of the official iOS tethering driver on macOS is to not -transmit any trailing padding at the end of URBs. This is applicable -to both NCM and legacy modes, including older devices. - -Adapt the driver to not include trailing padding in TX URBs, matching -the behaviour of the official macOS driver. - -Signed-off-by: Foster Snowhill -Tested-by: Georgi Valkov -Signed-off-by: David S. Miller ---- - drivers/net/usb/ipheth.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/net/usb/ipheth.c -+++ b/drivers/net/usb/ipheth.c -@@ -373,12 +373,10 @@ static netdev_tx_t ipheth_tx(struct sk_b - } - - memcpy(dev->tx_buf, skb->data, skb->len); -- if (skb->len < IPHETH_BUF_SIZE) -- memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len); - - usb_fill_bulk_urb(dev->tx_urb, udev, - usb_sndbulkpipe(udev, dev->bulk_out), -- dev->tx_buf, IPHETH_BUF_SIZE, -+ dev->tx_buf, skb->len, - ipheth_sndbulk_callback, - dev); - dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; diff --git a/target/linux/generic/backport-6.1/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch b/target/linux/generic/backport-6.1/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch deleted file mode 100644 index e3f2b9c3311e2f..00000000000000 --- a/target/linux/generic/backport-6.1/796-v6.5-03-usbnet-ipheth-add-CDC-NCM-support.patch +++ /dev/null @@ -1,326 +0,0 @@ -From a2d274c62e44b1995c170595db3865c6fe701226 Mon Sep 17 00:00:00 2001 -From: Foster Snowhill -Date: Wed, 7 Jun 2023 15:57:01 +0200 -Subject: [PATCH 3/4] usbnet: ipheth: add CDC NCM support - -Recent iOS releases support CDC NCM encapsulation on RX. This mode is -the default on macOS and Windows. In this mode, an iOS device may include -one or more Ethernet frames inside a single URB. - -Freshly booted iOS devices start in legacy mode, but are put into -NCM mode by the official Apple driver. When reconnecting such a device -from a macOS/Windows machine to a Linux host, the device stays in -NCM mode, making it unusable with the legacy ipheth driver code. - -To correctly support such a device, the driver has to either support -the NCM mode too, or put the device back into legacy mode. - -To match the behaviour of the macOS/Windows driver, and since there -is no documented control command to revert to legacy mode, implement -NCM support. The device is attempted to be put into NCM mode by default, -and falls back to legacy mode if the attempt fails. - -Signed-off-by: Foster Snowhill -Tested-by: Georgi Valkov -Signed-off-by: David S. Miller ---- - drivers/net/usb/ipheth.c | 180 +++++++++++++++++++++++++++++++++------ - 1 file changed, 155 insertions(+), 25 deletions(-) - ---- a/drivers/net/usb/ipheth.c -+++ b/drivers/net/usb/ipheth.c -@@ -52,6 +52,7 @@ - #include - #include - #include -+#include - - #define USB_VENDOR_APPLE 0x05ac - -@@ -59,8 +60,12 @@ - #define IPHETH_USBINTF_SUBCLASS 253 - #define IPHETH_USBINTF_PROTO 1 - --#define IPHETH_BUF_SIZE 1514 - #define IPHETH_IP_ALIGN 2 /* padding at front of URB */ -+#define IPHETH_NCM_HEADER_SIZE (12 + 96) /* NCMH + NCM0 */ -+#define IPHETH_TX_BUF_SIZE ETH_FRAME_LEN -+#define IPHETH_RX_BUF_SIZE_LEGACY (IPHETH_IP_ALIGN + ETH_FRAME_LEN) -+#define IPHETH_RX_BUF_SIZE_NCM 65536 -+ - #define IPHETH_TX_TIMEOUT (5 * HZ) - - #define IPHETH_INTFNUM 2 -@@ -71,6 +76,7 @@ - #define IPHETH_CTRL_TIMEOUT (5 * HZ) - - #define IPHETH_CMD_GET_MACADDR 0x00 -+#define IPHETH_CMD_ENABLE_NCM 0x04 - #define IPHETH_CMD_CARRIER_CHECK 0x45 - - #define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ) -@@ -97,6 +103,8 @@ struct ipheth_device { - u8 bulk_out; - struct delayed_work carrier_work; - bool confirmed_pairing; -+ int (*rcvbulk_callback)(struct urb *urb); -+ size_t rx_buf_len; - }; - - static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags); -@@ -116,12 +124,12 @@ static int ipheth_alloc_urbs(struct iphe - if (rx_urb == NULL) - goto free_tx_urb; - -- tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE, -+ tx_buf = usb_alloc_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, - GFP_KERNEL, &tx_urb->transfer_dma); - if (tx_buf == NULL) - goto free_rx_urb; - -- rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, -+ rx_buf = usb_alloc_coherent(iphone->udev, iphone->rx_buf_len, - GFP_KERNEL, &rx_urb->transfer_dma); - if (rx_buf == NULL) - goto free_tx_buf; -@@ -134,7 +142,7 @@ static int ipheth_alloc_urbs(struct iphe - return 0; - - free_tx_buf: -- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, tx_buf, -+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, tx_buf, - tx_urb->transfer_dma); - free_rx_urb: - usb_free_urb(rx_urb); -@@ -146,9 +154,9 @@ error_nomem: - - static void ipheth_free_urbs(struct ipheth_device *iphone) - { -- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, iphone->rx_buf, -+ usb_free_coherent(iphone->udev, iphone->rx_buf_len, iphone->rx_buf, - iphone->rx_urb->transfer_dma); -- usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf, -+ usb_free_coherent(iphone->udev, IPHETH_TX_BUF_SIZE, iphone->tx_buf, - iphone->tx_urb->transfer_dma); - usb_free_urb(iphone->rx_urb); - usb_free_urb(iphone->tx_urb); -@@ -160,15 +168,106 @@ static void ipheth_kill_urbs(struct iphe - usb_kill_urb(dev->rx_urb); - } - --static void ipheth_rcvbulk_callback(struct urb *urb) -+static int ipheth_consume_skb(char *buf, int len, struct ipheth_device *dev) - { -- struct ipheth_device *dev; - struct sk_buff *skb; -- int status; -+ -+ skb = dev_alloc_skb(len); -+ if (!skb) { -+ dev->net->stats.rx_dropped++; -+ return -ENOMEM; -+ } -+ -+ skb_put_data(skb, buf, len); -+ skb->dev = dev->net; -+ skb->protocol = eth_type_trans(skb, dev->net); -+ -+ dev->net->stats.rx_packets++; -+ dev->net->stats.rx_bytes += len; -+ netif_rx(skb); -+ -+ return 0; -+} -+ -+static int ipheth_rcvbulk_callback_legacy(struct urb *urb) -+{ -+ struct ipheth_device *dev; -+ char *buf; -+ int len; -+ -+ dev = urb->context; -+ -+ if (urb->actual_length <= IPHETH_IP_ALIGN) { -+ dev->net->stats.rx_length_errors++; -+ return -EINVAL; -+ } -+ len = urb->actual_length - IPHETH_IP_ALIGN; -+ buf = urb->transfer_buffer + IPHETH_IP_ALIGN; -+ -+ return ipheth_consume_skb(buf, len, dev); -+} -+ -+static int ipheth_rcvbulk_callback_ncm(struct urb *urb) -+{ -+ struct usb_cdc_ncm_nth16 *ncmh; -+ struct usb_cdc_ncm_ndp16 *ncm0; -+ struct usb_cdc_ncm_dpe16 *dpe; -+ struct ipheth_device *dev; -+ int retval = -EINVAL; - char *buf; - int len; - - dev = urb->context; -+ -+ if (urb->actual_length < IPHETH_NCM_HEADER_SIZE) { -+ dev->net->stats.rx_length_errors++; -+ return retval; -+ } -+ -+ ncmh = urb->transfer_buffer; -+ if (ncmh->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN) || -+ le16_to_cpu(ncmh->wNdpIndex) >= urb->actual_length) { -+ dev->net->stats.rx_errors++; -+ return retval; -+ } -+ -+ ncm0 = urb->transfer_buffer + le16_to_cpu(ncmh->wNdpIndex); -+ if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN) || -+ le16_to_cpu(ncmh->wHeaderLength) + le16_to_cpu(ncm0->wLength) >= -+ urb->actual_length) { -+ dev->net->stats.rx_errors++; -+ return retval; -+ } -+ -+ dpe = ncm0->dpe16; -+ while (le16_to_cpu(dpe->wDatagramIndex) != 0 && -+ le16_to_cpu(dpe->wDatagramLength) != 0) { -+ if (le16_to_cpu(dpe->wDatagramIndex) >= urb->actual_length || -+ le16_to_cpu(dpe->wDatagramIndex) + -+ le16_to_cpu(dpe->wDatagramLength) > urb->actual_length) { -+ dev->net->stats.rx_length_errors++; -+ return retval; -+ } -+ -+ buf = urb->transfer_buffer + le16_to_cpu(dpe->wDatagramIndex); -+ len = le16_to_cpu(dpe->wDatagramLength); -+ -+ retval = ipheth_consume_skb(buf, len, dev); -+ if (retval != 0) -+ return retval; -+ -+ dpe++; -+ } -+ -+ return 0; -+} -+ -+static void ipheth_rcvbulk_callback(struct urb *urb) -+{ -+ struct ipheth_device *dev; -+ int retval, status; -+ -+ dev = urb->context; - if (dev == NULL) - return; - -@@ -191,25 +290,27 @@ static void ipheth_rcvbulk_callback(stru - dev->net->stats.rx_length_errors++; - return; - } -- len = urb->actual_length - IPHETH_IP_ALIGN; -- buf = urb->transfer_buffer + IPHETH_IP_ALIGN; - -- skb = dev_alloc_skb(len); -- if (!skb) { -- dev_err(&dev->intf->dev, "%s: dev_alloc_skb: -ENOMEM\n", -- __func__); -- dev->net->stats.rx_dropped++; -+ /* RX URBs starting with 0x00 0x01 do not encapsulate Ethernet frames, -+ * but rather are control frames. Their purpose is not documented, and -+ * they don't affect driver functionality, okay to drop them. -+ * There is usually just one 4-byte control frame as the very first -+ * URB received from the bulk IN endpoint. -+ */ -+ if (unlikely -+ (((char *)urb->transfer_buffer)[0] == 0 && -+ ((char *)urb->transfer_buffer)[1] == 1)) -+ goto rx_submit; -+ -+ retval = dev->rcvbulk_callback(urb); -+ if (retval != 0) { -+ dev_err(&dev->intf->dev, "%s: callback retval: %d\n", -+ __func__, retval); - return; - } - -- skb_put_data(skb, buf, len); -- skb->dev = dev->net; -- skb->protocol = eth_type_trans(skb, dev->net); -- -- dev->net->stats.rx_packets++; -- dev->net->stats.rx_bytes += len; -+rx_submit: - dev->confirmed_pairing = true; -- netif_rx(skb); - ipheth_rx_submit(dev, GFP_ATOMIC); - } - -@@ -310,6 +411,27 @@ static int ipheth_get_macaddr(struct iph - return retval; - } - -+static int ipheth_enable_ncm(struct ipheth_device *dev) -+{ -+ struct usb_device *udev = dev->udev; -+ int retval; -+ -+ retval = usb_control_msg(udev, -+ usb_sndctrlpipe(udev, IPHETH_CTRL_ENDP), -+ IPHETH_CMD_ENABLE_NCM, /* request */ -+ 0x41, /* request type */ -+ 0x00, /* value */ -+ 0x02, /* index */ -+ NULL, -+ 0, -+ IPHETH_CTRL_TIMEOUT); -+ -+ dev_info(&dev->intf->dev, "%s: usb_control_msg: %d\n", -+ __func__, retval); -+ -+ return retval; -+} -+ - static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags) - { - struct usb_device *udev = dev->udev; -@@ -317,7 +439,7 @@ static int ipheth_rx_submit(struct iphet - - usb_fill_bulk_urb(dev->rx_urb, udev, - usb_rcvbulkpipe(udev, dev->bulk_in), -- dev->rx_buf, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, -+ dev->rx_buf, dev->rx_buf_len, - ipheth_rcvbulk_callback, - dev); - dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -@@ -365,7 +487,7 @@ static netdev_tx_t ipheth_tx(struct sk_b - int retval; - - /* Paranoid */ -- if (skb->len > IPHETH_BUF_SIZE) { -+ if (skb->len > IPHETH_TX_BUF_SIZE) { - WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len); - dev->net->stats.tx_dropped++; - dev_kfree_skb_any(skb); -@@ -448,6 +570,8 @@ static int ipheth_probe(struct usb_inter - dev->net = netdev; - dev->intf = intf; - dev->confirmed_pairing = false; -+ dev->rx_buf_len = IPHETH_RX_BUF_SIZE_LEGACY; -+ dev->rcvbulk_callback = ipheth_rcvbulk_callback_legacy; - /* Set up endpoints */ - hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM); - if (hintf == NULL) { -@@ -479,6 +603,12 @@ static int ipheth_probe(struct usb_inter - if (retval) - goto err_get_macaddr; - -+ retval = ipheth_enable_ncm(dev); -+ if (!retval) { -+ dev->rx_buf_len = IPHETH_RX_BUF_SIZE_NCM; -+ dev->rcvbulk_callback = ipheth_rcvbulk_callback_ncm; -+ } -+ - INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work); - - retval = ipheth_alloc_urbs(dev); diff --git a/target/linux/generic/backport-6.1/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch b/target/linux/generic/backport-6.1/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch deleted file mode 100644 index 9089c4d8c34a81..00000000000000 --- a/target/linux/generic/backport-6.1/796-v6.5-04-usbnet-ipheth-update-Kconfig-description.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0c6e9d32ef0ccfcf2d875cbcff23bf345a54d585 Mon Sep 17 00:00:00 2001 -From: Foster Snowhill -Date: Wed, 7 Jun 2023 15:57:02 +0200 -Subject: [PATCH 4/4] usbnet: ipheth: update Kconfig description - -This module has for a long time not been limited to iPhone <= 3GS. -Update description to match the actual state of the driver. - -Remove dead link from 2010, instead reference an existing userspace -iOS device pairing implementation as part of libimobiledevice. - -Signed-off-by: Foster Snowhill -Signed-off-by: David S. Miller ---- - drivers/net/usb/Kconfig | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - ---- a/drivers/net/usb/Kconfig -+++ b/drivers/net/usb/Kconfig -@@ -583,12 +583,10 @@ config USB_IPHETH - default n - help - Module used to share Internet connection (tethering) from your -- iPhone (Original, 3G and 3GS) to your system. -- Note that you need userspace libraries and programs that are needed -- to pair your device with your system and that understand the iPhone -- protocol. -- -- For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver -+ iPhone to your system. -+ Note that you need a corresponding userspace library/program -+ to pair your device with your system, for example usbmuxd -+ . - - config USB_SIERRA_NET - tristate "USB-to-WWAN Driver for Sierra Wireless modems" diff --git a/target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch b/target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch deleted file mode 100644 index 0afc69fa44cf5c..00000000000000 --- a/target/linux/generic/backport-6.1/797-6.7-net-dsa-mv88e6xxx-fix-marvell-6350-switch-probing.patch +++ /dev/null @@ -1,89 +0,0 @@ -From b3f1a164c7f742503dc7159011f7ad6b092b660e Mon Sep 17 00:00:00 2001 -From: Greg Ungerer -Date: Fri, 24 Nov 2023 14:15:28 +1000 -Subject: [PATCH] net: dsa: mv88e6xxx: fix marvell 6350 switch probing - -As of commit de5c9bf40c45 ("net: phylink: require supported_interfaces to -be filled") Marvell 88e6350 switches fail to be probed: - - ... - mv88e6085 d0072004.mdio-mii:11: switch 0x3710 detected: Marvell 88E6350, revision 2 - mv88e6085 d0072004.mdio-mii:11: phylink: error: empty supported_interfaces - error creating PHYLINK: -22 - mv88e6085: probe of d0072004.mdio-mii:11 failed with error -22 - ... - -The problem stems from the use of mv88e6185_phylink_get_caps() to get -the device capabilities. Create a new dedicated phylink_get_caps for the -6351 family (which the 6350 is one of) to properly support their set of -capabilities. - -According to chip.h the 6351 switch family includes the 6171, 6175, 6350 -and 6351 switches, so update each of these to use the correct -phylink_get_caps. - -Fixes: de5c9bf40c45 ("net: phylink: require supported_interfaces to be filled") -Signed-off-by: Greg Ungerer -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/mv88e6xxx/chip.c | 20 ++++++++++++++++---- - 1 file changed, 16 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -652,6 +652,18 @@ static void mv88e6250_phylink_get_caps(s - config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100; - } - -+static void mv88e6351_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, -+ struct phylink_config *config) -+{ -+ unsigned long *supported = config->supported_interfaces; -+ -+ /* Translate the default cmode */ -+ mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); -+ -+ config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | -+ MAC_1000FD; -+} -+ - static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip) - { - u16 reg, val; -@@ -4502,7 +4514,7 @@ static const struct mv88e6xxx_ops mv88e6 - .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, - .stu_getnext = mv88e6352_g1_stu_getnext, - .stu_loadpurge = mv88e6352_g1_stu_loadpurge, -- .phylink_get_caps = mv88e6185_phylink_get_caps, -+ .phylink_get_caps = mv88e6351_phylink_get_caps, - }; - - static const struct mv88e6xxx_ops mv88e6172_ops = { -@@ -4605,7 +4617,7 @@ static const struct mv88e6xxx_ops mv88e6 - .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, - .stu_getnext = mv88e6352_g1_stu_getnext, - .stu_loadpurge = mv88e6352_g1_stu_loadpurge, -- .phylink_get_caps = mv88e6185_phylink_get_caps, -+ .phylink_get_caps = mv88e6351_phylink_get_caps, - }; - - static const struct mv88e6xxx_ops mv88e6176_ops = { -@@ -5282,7 +5294,7 @@ static const struct mv88e6xxx_ops mv88e6 - .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, - .stu_getnext = mv88e6352_g1_stu_getnext, - .stu_loadpurge = mv88e6352_g1_stu_loadpurge, -- .phylink_get_caps = mv88e6185_phylink_get_caps, -+ .phylink_get_caps = mv88e6351_phylink_get_caps, - }; - - static const struct mv88e6xxx_ops mv88e6351_ops = { -@@ -5328,7 +5340,7 @@ static const struct mv88e6xxx_ops mv88e6 - .stu_loadpurge = mv88e6352_g1_stu_loadpurge, - .avb_ops = &mv88e6352_avb_ops, - .ptp_ops = &mv88e6352_ptp_ops, -- .phylink_get_caps = mv88e6185_phylink_get_caps, -+ .phylink_get_caps = mv88e6351_phylink_get_caps, - }; - - static const struct mv88e6xxx_ops mv88e6352_ops = { diff --git a/target/linux/generic/backport-6.1/798-v6.10-net-phy-air_en8811h-Add-the-Airoha-EN8811H-PHY-drive.patch b/target/linux/generic/backport-6.1/798-v6.10-net-phy-air_en8811h-Add-the-Airoha-EN8811H-PHY-drive.patch deleted file mode 100644 index 7f963b3cf66e72..00000000000000 --- a/target/linux/generic/backport-6.1/798-v6.10-net-phy-air_en8811h-Add-the-Airoha-EN8811H-PHY-drive.patch +++ /dev/null @@ -1,1140 +0,0 @@ -From 71e79430117d56c409c5ea485a263bc0d8083390 Mon Sep 17 00:00:00 2001 -From: Eric Woudstra -Date: Tue, 26 Mar 2024 17:23:05 +0100 -Subject: [PATCH] net: phy: air_en8811h: Add the Airoha EN8811H PHY driver - -Add the driver for the Airoha EN8811H 2.5 Gigabit PHY. The phy supports -100/1000/2500 Mbps with auto negotiation only. - -The driver uses two firmware files, for which updated versions are added to -linux-firmware already. - -Note: At phy-address + 8 there is another device on the mdio bus, that -belongs to the EN881H. While the original driver writes to it, Airoha -has confirmed this is not needed. Therefore, communication with this -device is not included in this driver. - -Signed-off-by: Eric Woudstra -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240326162305.303598-3-ericwouds@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/Kconfig | 5 + - drivers/net/phy/Makefile | 1 + - drivers/net/phy/air_en8811h.c | 1086 +++++++++++++++++++++++++++++++++ - 3 files changed, 1092 insertions(+) - create mode 100644 drivers/net/phy/air_en8811h.c - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -63,6 +63,11 @@ config SFP - - comment "MII PHY device drivers" - -+config AIR_EN8811H_PHY -+ tristate "Airoha EN8811H 2.5 Gigabit PHY" -+ help -+ Currently supports the Airoha EN8811H PHY. -+ - config AMD_PHY - tristate "AMD PHYs" - help ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -32,6 +32,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m) - - obj-$(CONFIG_ADIN_PHY) += adin.o - obj-$(CONFIG_ADIN1100_PHY) += adin1100.o -+obj-$(CONFIG_AIR_EN8811H_PHY) += air_en8811h.o - obj-$(CONFIG_AMD_PHY) += amd.o - obj-$(CONFIG_AQUANTIA_PHY) += aquantia/ - obj-$(CONFIG_AX88796B_PHY) += ax88796b.o ---- /dev/null -+++ b/drivers/net/phy/air_en8811h.c -@@ -0,0 +1,1086 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Driver for the Airoha EN8811H 2.5 Gigabit PHY. -+ * -+ * Limitations of the EN8811H: -+ * - Only full duplex supported -+ * - Forced speed (AN off) is not supported by hardware (100Mbps) -+ * -+ * Source originated from airoha's en8811h.c and en8811h.h v1.2.1 -+ * -+ * Copyright (C) 2023 Airoha Technology Corp. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define EN8811H_PHY_ID 0x03a2a411 -+ -+#define EN8811H_MD32_DM "airoha/EthMD32.dm.bin" -+#define EN8811H_MD32_DSP "airoha/EthMD32.DSP.bin" -+ -+#define AIR_FW_ADDR_DM 0x00000000 -+#define AIR_FW_ADDR_DSP 0x00100000 -+ -+/* MII Registers */ -+#define AIR_AUX_CTRL_STATUS 0x1d -+#define AIR_AUX_CTRL_STATUS_SPEED_MASK GENMASK(4, 2) -+#define AIR_AUX_CTRL_STATUS_SPEED_100 0x4 -+#define AIR_AUX_CTRL_STATUS_SPEED_1000 0x8 -+#define AIR_AUX_CTRL_STATUS_SPEED_2500 0xc -+ -+#define AIR_EXT_PAGE_ACCESS 0x1f -+#define AIR_PHY_PAGE_STANDARD 0x0000 -+#define AIR_PHY_PAGE_EXTENDED_4 0x0004 -+ -+/* MII Registers Page 4*/ -+#define AIR_BPBUS_MODE 0x10 -+#define AIR_BPBUS_MODE_ADDR_FIXED 0x0000 -+#define AIR_BPBUS_MODE_ADDR_INCR BIT(15) -+#define AIR_BPBUS_WR_ADDR_HIGH 0x11 -+#define AIR_BPBUS_WR_ADDR_LOW 0x12 -+#define AIR_BPBUS_WR_DATA_HIGH 0x13 -+#define AIR_BPBUS_WR_DATA_LOW 0x14 -+#define AIR_BPBUS_RD_ADDR_HIGH 0x15 -+#define AIR_BPBUS_RD_ADDR_LOW 0x16 -+#define AIR_BPBUS_RD_DATA_HIGH 0x17 -+#define AIR_BPBUS_RD_DATA_LOW 0x18 -+ -+/* Registers on MDIO_MMD_VEND1 */ -+#define EN8811H_PHY_FW_STATUS 0x8009 -+#define EN8811H_PHY_READY 0x02 -+ -+#define AIR_PHY_MCU_CMD_1 0x800c -+#define AIR_PHY_MCU_CMD_1_MODE1 0x0 -+#define AIR_PHY_MCU_CMD_2 0x800d -+#define AIR_PHY_MCU_CMD_2_MODE1 0x0 -+#define AIR_PHY_MCU_CMD_3 0x800e -+#define AIR_PHY_MCU_CMD_3_MODE1 0x1101 -+#define AIR_PHY_MCU_CMD_3_DOCMD 0x1100 -+#define AIR_PHY_MCU_CMD_4 0x800f -+#define AIR_PHY_MCU_CMD_4_MODE1 0x0002 -+#define AIR_PHY_MCU_CMD_4_INTCLR 0x00e4 -+ -+/* Registers on MDIO_MMD_VEND2 */ -+#define AIR_PHY_LED_BCR 0x021 -+#define AIR_PHY_LED_BCR_MODE_MASK GENMASK(1, 0) -+#define AIR_PHY_LED_BCR_TIME_TEST BIT(2) -+#define AIR_PHY_LED_BCR_CLK_EN BIT(3) -+#define AIR_PHY_LED_BCR_EXT_CTRL BIT(15) -+ -+#define AIR_PHY_LED_DUR_ON 0x022 -+ -+#define AIR_PHY_LED_DUR_BLINK 0x023 -+ -+#define AIR_PHY_LED_ON(i) (0x024 + ((i) * 2)) -+#define AIR_PHY_LED_ON_MASK (GENMASK(6, 0) | BIT(8)) -+#define AIR_PHY_LED_ON_LINK1000 BIT(0) -+#define AIR_PHY_LED_ON_LINK100 BIT(1) -+#define AIR_PHY_LED_ON_LINK10 BIT(2) -+#define AIR_PHY_LED_ON_LINKDOWN BIT(3) -+#define AIR_PHY_LED_ON_FDX BIT(4) /* Full duplex */ -+#define AIR_PHY_LED_ON_HDX BIT(5) /* Half duplex */ -+#define AIR_PHY_LED_ON_FORCE_ON BIT(6) -+#define AIR_PHY_LED_ON_LINK2500 BIT(8) -+#define AIR_PHY_LED_ON_POLARITY BIT(14) -+#define AIR_PHY_LED_ON_ENABLE BIT(15) -+ -+#define AIR_PHY_LED_BLINK(i) (0x025 + ((i) * 2)) -+#define AIR_PHY_LED_BLINK_1000TX BIT(0) -+#define AIR_PHY_LED_BLINK_1000RX BIT(1) -+#define AIR_PHY_LED_BLINK_100TX BIT(2) -+#define AIR_PHY_LED_BLINK_100RX BIT(3) -+#define AIR_PHY_LED_BLINK_10TX BIT(4) -+#define AIR_PHY_LED_BLINK_10RX BIT(5) -+#define AIR_PHY_LED_BLINK_COLLISION BIT(6) -+#define AIR_PHY_LED_BLINK_RX_CRC_ERR BIT(7) -+#define AIR_PHY_LED_BLINK_RX_IDLE_ERR BIT(8) -+#define AIR_PHY_LED_BLINK_FORCE_BLINK BIT(9) -+#define AIR_PHY_LED_BLINK_2500TX BIT(10) -+#define AIR_PHY_LED_BLINK_2500RX BIT(11) -+ -+/* Registers on BUCKPBUS */ -+#define EN8811H_2P5G_LPA 0x3b30 -+#define EN8811H_2P5G_LPA_2P5G BIT(0) -+ -+#define EN8811H_FW_VERSION 0x3b3c -+ -+#define EN8811H_POLARITY 0xca0f8 -+#define EN8811H_POLARITY_TX_NORMAL BIT(0) -+#define EN8811H_POLARITY_RX_REVERSE BIT(1) -+ -+#define EN8811H_GPIO_OUTPUT 0xcf8b8 -+#define EN8811H_GPIO_OUTPUT_345 (BIT(3) | BIT(4) | BIT(5)) -+ -+#define EN8811H_FW_CTRL_1 0x0f0018 -+#define EN8811H_FW_CTRL_1_START 0x0 -+#define EN8811H_FW_CTRL_1_FINISH 0x1 -+#define EN8811H_FW_CTRL_2 0x800000 -+#define EN8811H_FW_CTRL_2_LOADING BIT(11) -+ -+/* Led definitions */ -+#define EN8811H_LED_COUNT 3 -+ -+/* Default LED setup: -+ * GPIO5 <-> LED0 On: Link detected, blink Rx/Tx -+ * GPIO4 <-> LED1 On: Link detected at 2500 or 1000 Mbps -+ * GPIO3 <-> LED2 On: Link detected at 2500 or 100 Mbps -+ */ -+#define AIR_DEFAULT_TRIGGER_LED0 (BIT(TRIGGER_NETDEV_LINK) | \ -+ BIT(TRIGGER_NETDEV_RX) | \ -+ BIT(TRIGGER_NETDEV_TX)) -+#define AIR_DEFAULT_TRIGGER_LED1 (BIT(TRIGGER_NETDEV_LINK_2500) | \ -+ BIT(TRIGGER_NETDEV_LINK_1000)) -+#define AIR_DEFAULT_TRIGGER_LED2 (BIT(TRIGGER_NETDEV_LINK_2500) | \ -+ BIT(TRIGGER_NETDEV_LINK_100)) -+ -+struct led { -+ unsigned long rules; -+ unsigned long state; -+}; -+ -+struct en8811h_priv { -+ u32 firmware_version; -+ bool mcu_needs_restart; -+ struct led led[EN8811H_LED_COUNT]; -+}; -+ -+enum { -+ AIR_PHY_LED_STATE_FORCE_ON, -+ AIR_PHY_LED_STATE_FORCE_BLINK, -+}; -+ -+enum { -+ AIR_PHY_LED_DUR_BLINK_32MS, -+ AIR_PHY_LED_DUR_BLINK_64MS, -+ AIR_PHY_LED_DUR_BLINK_128MS, -+ AIR_PHY_LED_DUR_BLINK_256MS, -+ AIR_PHY_LED_DUR_BLINK_512MS, -+ AIR_PHY_LED_DUR_BLINK_1024MS, -+}; -+ -+enum { -+ AIR_LED_DISABLE, -+ AIR_LED_ENABLE, -+}; -+ -+enum { -+ AIR_ACTIVE_LOW, -+ AIR_ACTIVE_HIGH, -+}; -+ -+enum { -+ AIR_LED_MODE_DISABLE, -+ AIR_LED_MODE_USER_DEFINE, -+}; -+ -+#define AIR_PHY_LED_DUR_UNIT 1024 -+#define AIR_PHY_LED_DUR (AIR_PHY_LED_DUR_UNIT << AIR_PHY_LED_DUR_BLINK_64MS) -+ -+static const unsigned long en8811h_led_trig = BIT(TRIGGER_NETDEV_FULL_DUPLEX) | -+ BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000) | -+ BIT(TRIGGER_NETDEV_LINK_2500) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX); -+ -+static int air_phy_read_page(struct phy_device *phydev) -+{ -+ return __phy_read(phydev, AIR_EXT_PAGE_ACCESS); -+} -+ -+static int air_phy_write_page(struct phy_device *phydev, int page) -+{ -+ return __phy_write(phydev, AIR_EXT_PAGE_ACCESS, page); -+} -+ -+static int __air_buckpbus_reg_write(struct phy_device *phydev, -+ u32 pbus_address, u32 pbus_data) -+{ -+ int ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_HIGH, -+ upper_16_bits(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_LOW, -+ lower_16_bits(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_HIGH, -+ upper_16_bits(pbus_data)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_LOW, -+ lower_16_bits(pbus_data)); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int air_buckpbus_reg_write(struct phy_device *phydev, -+ u32 pbus_address, u32 pbus_data) -+{ -+ int saved_page; -+ int ret = 0; -+ -+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); -+ -+ if (saved_page >= 0) { -+ ret = __air_buckpbus_reg_write(phydev, pbus_address, -+ pbus_data); -+ if (ret < 0) -+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__, -+ pbus_address, ret); -+ } -+ -+ return phy_restore_page(phydev, saved_page, ret); -+} -+ -+static int __air_buckpbus_reg_read(struct phy_device *phydev, -+ u32 pbus_address, u32 *pbus_data) -+{ -+ int pbus_data_low, pbus_data_high; -+ int ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_HIGH, -+ upper_16_bits(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_LOW, -+ lower_16_bits(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH); -+ if (pbus_data_high < 0) -+ return ret; -+ -+ pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW); -+ if (pbus_data_low < 0) -+ return ret; -+ -+ *pbus_data = pbus_data_low | (pbus_data_high << 16); -+ return 0; -+} -+ -+static int air_buckpbus_reg_read(struct phy_device *phydev, -+ u32 pbus_address, u32 *pbus_data) -+{ -+ int saved_page; -+ int ret = 0; -+ -+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); -+ -+ if (saved_page >= 0) { -+ ret = __air_buckpbus_reg_read(phydev, pbus_address, pbus_data); -+ if (ret < 0) -+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__, -+ pbus_address, ret); -+ } -+ -+ return phy_restore_page(phydev, saved_page, ret); -+} -+ -+static int __air_buckpbus_reg_modify(struct phy_device *phydev, -+ u32 pbus_address, u32 mask, u32 set) -+{ -+ int pbus_data_low, pbus_data_high; -+ u32 pbus_data_old, pbus_data_new; -+ int ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_HIGH, -+ upper_16_bits(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_RD_ADDR_LOW, -+ lower_16_bits(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH); -+ if (pbus_data_high < 0) -+ return ret; -+ -+ pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW); -+ if (pbus_data_low < 0) -+ return ret; -+ -+ pbus_data_old = pbus_data_low | (pbus_data_high << 16); -+ pbus_data_new = (pbus_data_old & ~mask) | set; -+ if (pbus_data_new == pbus_data_old) -+ return 0; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_HIGH, -+ upper_16_bits(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_LOW, -+ lower_16_bits(pbus_address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_HIGH, -+ upper_16_bits(pbus_data_new)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_LOW, -+ lower_16_bits(pbus_data_new)); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int air_buckpbus_reg_modify(struct phy_device *phydev, -+ u32 pbus_address, u32 mask, u32 set) -+{ -+ int saved_page; -+ int ret = 0; -+ -+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); -+ -+ if (saved_page >= 0) { -+ ret = __air_buckpbus_reg_modify(phydev, pbus_address, mask, -+ set); -+ if (ret < 0) -+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__, -+ pbus_address, ret); -+ } -+ -+ return phy_restore_page(phydev, saved_page, ret); -+} -+ -+static int __air_write_buf(struct phy_device *phydev, u32 address, -+ const struct firmware *fw) -+{ -+ unsigned int offset; -+ int ret; -+ u16 val; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_INCR); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_HIGH, -+ upper_16_bits(address)); -+ if (ret < 0) -+ return ret; -+ -+ ret = __phy_write(phydev, AIR_BPBUS_WR_ADDR_LOW, -+ lower_16_bits(address)); -+ if (ret < 0) -+ return ret; -+ -+ for (offset = 0; offset < fw->size; offset += 4) { -+ val = get_unaligned_le16(&fw->data[offset + 2]); -+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_HIGH, val); -+ if (ret < 0) -+ return ret; -+ -+ val = get_unaligned_le16(&fw->data[offset]); -+ ret = __phy_write(phydev, AIR_BPBUS_WR_DATA_LOW, val); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int air_write_buf(struct phy_device *phydev, u32 address, -+ const struct firmware *fw) -+{ -+ int saved_page; -+ int ret = 0; -+ -+ saved_page = phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); -+ -+ if (saved_page >= 0) { -+ ret = __air_write_buf(phydev, address, fw); -+ if (ret < 0) -+ phydev_err(phydev, "%s 0x%08x failed: %d\n", __func__, -+ address, ret); -+ } -+ -+ return phy_restore_page(phydev, saved_page, ret); -+} -+ -+static int en8811h_wait_mcu_ready(struct phy_device *phydev) -+{ -+ int ret, reg_value; -+ -+ /* Because of mdio-lock, may have to wait for multiple loads */ -+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -+ EN8811H_PHY_FW_STATUS, reg_value, -+ reg_value == EN8811H_PHY_READY, -+ 20000, 7500000, true); -+ if (ret) { -+ phydev_err(phydev, "MCU not ready: 0x%x\n", reg_value); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static int en8811h_load_firmware(struct phy_device *phydev) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ struct device *dev = &phydev->mdio.dev; -+ const struct firmware *fw1, *fw2; -+ int ret; -+ -+ ret = request_firmware_direct(&fw1, EN8811H_MD32_DM, dev); -+ if (ret < 0) -+ return ret; -+ -+ ret = request_firmware_direct(&fw2, EN8811H_MD32_DSP, dev); -+ if (ret < 0) -+ goto en8811h_load_firmware_rel1; -+ -+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, -+ EN8811H_FW_CTRL_1_START); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2, -+ EN8811H_FW_CTRL_2_LOADING, -+ EN8811H_FW_CTRL_2_LOADING); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = air_write_buf(phydev, AIR_FW_ADDR_DM, fw1); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = air_write_buf(phydev, AIR_FW_ADDR_DSP, fw2); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2, -+ EN8811H_FW_CTRL_2_LOADING, 0); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, -+ EN8811H_FW_CTRL_1_FINISH); -+ if (ret < 0) -+ goto en8811h_load_firmware_out; -+ -+ ret = en8811h_wait_mcu_ready(phydev); -+ -+ air_buckpbus_reg_read(phydev, EN8811H_FW_VERSION, -+ &priv->firmware_version); -+ phydev_info(phydev, "MD32 firmware version: %08x\n", -+ priv->firmware_version); -+ -+en8811h_load_firmware_out: -+ release_firmware(fw2); -+ -+en8811h_load_firmware_rel1: -+ release_firmware(fw1); -+ -+ if (ret < 0) -+ phydev_err(phydev, "Load firmware failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int en8811h_restart_mcu(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, -+ EN8811H_FW_CTRL_1_START); -+ if (ret < 0) -+ return ret; -+ -+ ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, -+ EN8811H_FW_CTRL_1_FINISH); -+ if (ret < 0) -+ return ret; -+ -+ return en8811h_wait_mcu_ready(phydev); -+} -+ -+static int air_hw_led_on_set(struct phy_device *phydev, u8 index, bool on) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ bool changed; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ if (on) -+ changed = !test_and_set_bit(AIR_PHY_LED_STATE_FORCE_ON, -+ &priv->led[index].state); -+ else -+ changed = !!test_and_clear_bit(AIR_PHY_LED_STATE_FORCE_ON, -+ &priv->led[index].state); -+ -+ changed |= (priv->led[index].rules != 0); -+ -+ if (changed) -+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, -+ AIR_PHY_LED_ON(index), -+ AIR_PHY_LED_ON_MASK, -+ on ? AIR_PHY_LED_ON_FORCE_ON : 0); -+ -+ return 0; -+} -+ -+static int air_hw_led_blink_set(struct phy_device *phydev, u8 index, -+ bool blinking) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ bool changed; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ if (blinking) -+ changed = !test_and_set_bit(AIR_PHY_LED_STATE_FORCE_BLINK, -+ &priv->led[index].state); -+ else -+ changed = !!test_and_clear_bit(AIR_PHY_LED_STATE_FORCE_BLINK, -+ &priv->led[index].state); -+ -+ changed |= (priv->led[index].rules != 0); -+ -+ if (changed) -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, -+ AIR_PHY_LED_BLINK(index), -+ blinking ? -+ AIR_PHY_LED_BLINK_FORCE_BLINK : 0); -+ else -+ return 0; -+} -+ -+static int air_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ bool blinking = false; -+ int err; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) { -+ blinking = true; -+ *delay_on = 50; -+ *delay_off = 50; -+ } -+ -+ err = air_hw_led_blink_set(phydev, index, blinking); -+ if (err) -+ return err; -+ -+ /* led-blink set, so switch led-on off */ -+ err = air_hw_led_on_set(phydev, index, false); -+ if (err) -+ return err; -+ -+ /* hw-control is off*/ -+ if (!!test_bit(AIR_PHY_LED_STATE_FORCE_BLINK, &priv->led[index].state)) -+ priv->led[index].rules = 0; -+ -+ return 0; -+} -+ -+static int air_led_brightness_set(struct phy_device *phydev, u8 index, -+ enum led_brightness value) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ int err; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ /* led-on set, so switch led-blink off */ -+ err = air_hw_led_blink_set(phydev, index, false); -+ if (err) -+ return err; -+ -+ err = air_hw_led_on_set(phydev, index, (value != LED_OFF)); -+ if (err) -+ return err; -+ -+ /* hw-control is off */ -+ if (!!test_bit(AIR_PHY_LED_STATE_FORCE_ON, &priv->led[index].state)) -+ priv->led[index].rules = 0; -+ -+ return 0; -+} -+ -+static int air_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ *rules = priv->led[index].rules; -+ -+ return 0; -+}; -+ -+static int air_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ u16 on = 0, blink = 0; -+ int ret; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ priv->led[index].rules = rules; -+ -+ if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) -+ on |= AIR_PHY_LED_ON_FDX; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= AIR_PHY_LED_ON_LINK10; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= AIR_PHY_LED_ON_LINK100; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= AIR_PHY_LED_ON_LINK1000; -+ -+ if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK))) -+ on |= AIR_PHY_LED_ON_LINK2500; -+ -+ if (rules & BIT(TRIGGER_NETDEV_RX)) { -+ blink |= AIR_PHY_LED_BLINK_10RX | -+ AIR_PHY_LED_BLINK_100RX | -+ AIR_PHY_LED_BLINK_1000RX | -+ AIR_PHY_LED_BLINK_2500RX; -+ } -+ -+ if (rules & BIT(TRIGGER_NETDEV_TX)) { -+ blink |= AIR_PHY_LED_BLINK_10TX | -+ AIR_PHY_LED_BLINK_100TX | -+ AIR_PHY_LED_BLINK_1000TX | -+ AIR_PHY_LED_BLINK_2500TX; -+ } -+ -+ if (blink || on) { -+ /* switch hw-control on, so led-on and led-blink are off */ -+ clear_bit(AIR_PHY_LED_STATE_FORCE_ON, -+ &priv->led[index].state); -+ clear_bit(AIR_PHY_LED_STATE_FORCE_BLINK, -+ &priv->led[index].state); -+ } else { -+ priv->led[index].rules = 0; -+ } -+ -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index), -+ AIR_PHY_LED_ON_MASK, on); -+ -+ if (ret < 0) -+ return ret; -+ -+ return phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BLINK(index), -+ blink); -+}; -+ -+static int air_led_init(struct phy_device *phydev, u8 index, u8 state, u8 pol) -+{ -+ int val = 0; -+ int err; -+ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ if (state == AIR_LED_ENABLE) -+ val |= AIR_PHY_LED_ON_ENABLE; -+ else -+ val &= ~AIR_PHY_LED_ON_ENABLE; -+ -+ if (pol == AIR_ACTIVE_HIGH) -+ val |= AIR_PHY_LED_ON_POLARITY; -+ else -+ val &= ~AIR_PHY_LED_ON_POLARITY; -+ -+ err = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index), -+ AIR_PHY_LED_ON_ENABLE | -+ AIR_PHY_LED_ON_POLARITY, val); -+ -+ if (err < 0) -+ return err; -+ -+ return 0; -+} -+ -+static int air_leds_init(struct phy_device *phydev, int num, int dur, int mode) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ int ret, i; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_BLINK, -+ dur); -+ if (ret < 0) -+ return ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_DUR_ON, -+ dur >> 1); -+ if (ret < 0) -+ return ret; -+ -+ switch (mode) { -+ case AIR_LED_MODE_DISABLE: -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR, -+ AIR_PHY_LED_BCR_EXT_CTRL | -+ AIR_PHY_LED_BCR_MODE_MASK, 0); -+ if (ret < 0) -+ return ret; -+ break; -+ case AIR_LED_MODE_USER_DEFINE: -+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR, -+ AIR_PHY_LED_BCR_EXT_CTRL | -+ AIR_PHY_LED_BCR_CLK_EN, -+ AIR_PHY_LED_BCR_EXT_CTRL | -+ AIR_PHY_LED_BCR_CLK_EN); -+ if (ret < 0) -+ return ret; -+ break; -+ default: -+ phydev_err(phydev, "LED mode %d is not supported\n", mode); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < num; ++i) { -+ ret = air_led_init(phydev, i, AIR_LED_ENABLE, AIR_ACTIVE_HIGH); -+ if (ret < 0) { -+ phydev_err(phydev, "LED%d init failed: %d\n", i, ret); -+ return ret; -+ } -+ air_led_hw_control_set(phydev, i, priv->led[i].rules); -+ } -+ -+ return 0; -+} -+ -+static int en8811h_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ if (index >= EN8811H_LED_COUNT) -+ return -EINVAL; -+ -+ /* All combinations of the supported triggers are allowed */ -+ if (rules & ~en8811h_led_trig) -+ return -EOPNOTSUPP; -+ -+ return 0; -+}; -+ -+static int en8811h_probe(struct phy_device *phydev) -+{ -+ struct en8811h_priv *priv; -+ int ret; -+ -+ priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct en8811h_priv), -+ GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ phydev->priv = priv; -+ -+ ret = en8811h_load_firmware(phydev); -+ if (ret < 0) -+ return ret; -+ -+ /* mcu has just restarted after firmware load */ -+ priv->mcu_needs_restart = false; -+ -+ priv->led[0].rules = AIR_DEFAULT_TRIGGER_LED0; -+ priv->led[1].rules = AIR_DEFAULT_TRIGGER_LED1; -+ priv->led[2].rules = AIR_DEFAULT_TRIGGER_LED2; -+ -+ /* MDIO_DEVS1/2 empty, so set mmds_present bits here */ -+ phydev->c45_ids.mmds_present |= MDIO_DEVS_PMAPMD | MDIO_DEVS_AN; -+ -+ ret = air_leds_init(phydev, EN8811H_LED_COUNT, AIR_PHY_LED_DUR, -+ AIR_LED_MODE_DISABLE); -+ if (ret < 0) { -+ phydev_err(phydev, "Failed to disable leds: %d\n", ret); -+ return ret; -+ } -+ -+ /* Configure led gpio pins as output */ -+ ret = air_buckpbus_reg_modify(phydev, EN8811H_GPIO_OUTPUT, -+ EN8811H_GPIO_OUTPUT_345, -+ EN8811H_GPIO_OUTPUT_345); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static int en8811h_config_init(struct phy_device *phydev) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ struct device *dev = &phydev->mdio.dev; -+ u32 pbus_value; -+ int ret; -+ -+ /* If restart happened in .probe(), no need to restart now */ -+ if (priv->mcu_needs_restart) { -+ ret = en8811h_restart_mcu(phydev); -+ if (ret < 0) -+ return ret; -+ } else { -+ /* Next calls to .config_init() mcu needs to restart */ -+ priv->mcu_needs_restart = true; -+ } -+ -+ /* Select mode 1, the only mode supported. -+ * Configures the SerDes for 2500Base-X with rate adaptation -+ */ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_1, -+ AIR_PHY_MCU_CMD_1_MODE1); -+ if (ret < 0) -+ return ret; -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_2, -+ AIR_PHY_MCU_CMD_2_MODE1); -+ if (ret < 0) -+ return ret; -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_3, -+ AIR_PHY_MCU_CMD_3_MODE1); -+ if (ret < 0) -+ return ret; -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_4, -+ AIR_PHY_MCU_CMD_4_MODE1); -+ if (ret < 0) -+ return ret; -+ -+ /* Serdes polarity */ -+ pbus_value = 0; -+ if (device_property_read_bool(dev, "airoha,pnswap-rx")) -+ pbus_value |= EN8811H_POLARITY_RX_REVERSE; -+ else -+ pbus_value &= ~EN8811H_POLARITY_RX_REVERSE; -+ if (device_property_read_bool(dev, "airoha,pnswap-tx")) -+ pbus_value &= ~EN8811H_POLARITY_TX_NORMAL; -+ else -+ pbus_value |= EN8811H_POLARITY_TX_NORMAL; -+ ret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY, -+ EN8811H_POLARITY_RX_REVERSE | -+ EN8811H_POLARITY_TX_NORMAL, pbus_value); -+ if (ret < 0) -+ return ret; -+ -+ ret = air_leds_init(phydev, EN8811H_LED_COUNT, AIR_PHY_LED_DUR, -+ AIR_LED_MODE_USER_DEFINE); -+ if (ret < 0) { -+ phydev_err(phydev, "Failed to initialize leds: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int en8811h_get_features(struct phy_device *phydev) -+{ -+ linkmode_set_bit_array(phy_basic_ports_array, -+ ARRAY_SIZE(phy_basic_ports_array), -+ phydev->supported); -+ -+ return genphy_c45_pma_read_abilities(phydev); -+} -+ -+static int en8811h_get_rate_matching(struct phy_device *phydev, -+ phy_interface_t iface) -+{ -+ return RATE_MATCH_PAUSE; -+} -+ -+static int en8811h_config_aneg(struct phy_device *phydev) -+{ -+ bool changed = false; -+ int ret; -+ u32 adv; -+ -+ if (phydev->autoneg == AUTONEG_DISABLE) { -+ phydev_warn(phydev, "Disabling autoneg is not supported\n"); -+ return -EINVAL; -+ } -+ -+ adv = linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising); -+ -+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, -+ MDIO_AN_10GBT_CTRL_ADV2_5G, adv); -+ if (ret < 0) -+ return ret; -+ if (ret > 0) -+ changed = true; -+ -+ return __genphy_config_aneg(phydev, changed); -+} -+ -+static int en8811h_read_status(struct phy_device *phydev) -+{ -+ struct en8811h_priv *priv = phydev->priv; -+ u32 pbus_value; -+ int ret, val; -+ -+ ret = genphy_update_link(phydev); -+ if (ret) -+ return ret; -+ -+ phydev->master_slave_get = MASTER_SLAVE_CFG_UNSUPPORTED; -+ phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED; -+ phydev->speed = SPEED_UNKNOWN; -+ phydev->duplex = DUPLEX_UNKNOWN; -+ phydev->pause = 0; -+ phydev->asym_pause = 0; -+ phydev->rate_matching = RATE_MATCH_PAUSE; -+ -+ ret = genphy_read_master_slave(phydev); -+ if (ret < 0) -+ return ret; -+ -+ ret = genphy_read_lpa(phydev); -+ if (ret < 0) -+ return ret; -+ -+ /* Get link partner 2.5GBASE-T ability from vendor register */ -+ ret = air_buckpbus_reg_read(phydev, EN8811H_2P5G_LPA, &pbus_value); -+ if (ret < 0) -+ return ret; -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ phydev->lp_advertising, -+ pbus_value & EN8811H_2P5G_LPA_2P5G); -+ -+ if (phydev->autoneg_complete) -+ phy_resolve_aneg_pause(phydev); -+ -+ if (!phydev->link) -+ return 0; -+ -+ /* Get real speed from vendor register */ -+ val = phy_read(phydev, AIR_AUX_CTRL_STATUS); -+ if (val < 0) -+ return val; -+ switch (val & AIR_AUX_CTRL_STATUS_SPEED_MASK) { -+ case AIR_AUX_CTRL_STATUS_SPEED_2500: -+ phydev->speed = SPEED_2500; -+ break; -+ case AIR_AUX_CTRL_STATUS_SPEED_1000: -+ phydev->speed = SPEED_1000; -+ break; -+ case AIR_AUX_CTRL_STATUS_SPEED_100: -+ phydev->speed = SPEED_100; -+ break; -+ } -+ -+ /* Firmware before version 24011202 has no vendor register 2P5G_LPA. -+ * Assume link partner advertised it if connected at 2500Mbps. -+ */ -+ if (priv->firmware_version < 0x24011202) { -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -+ phydev->lp_advertising, -+ phydev->speed == SPEED_2500); -+ } -+ -+ /* Only supports full duplex */ -+ phydev->duplex = DUPLEX_FULL; -+ -+ return 0; -+} -+ -+static int en8811h_clear_intr(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_3, -+ AIR_PHY_MCU_CMD_3_DOCMD); -+ if (ret < 0) -+ return ret; -+ -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, AIR_PHY_MCU_CMD_4, -+ AIR_PHY_MCU_CMD_4_INTCLR); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ -+static irqreturn_t en8811h_handle_interrupt(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = en8811h_clear_intr(phydev); -+ if (ret < 0) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ phy_trigger_machine(phydev); -+ -+ return IRQ_HANDLED; -+} -+ -+static struct phy_driver en8811h_driver[] = { -+{ -+ PHY_ID_MATCH_MODEL(EN8811H_PHY_ID), -+ .name = "Airoha EN8811H", -+ .probe = en8811h_probe, -+ .get_features = en8811h_get_features, -+ .config_init = en8811h_config_init, -+ .get_rate_matching = en8811h_get_rate_matching, -+ .config_aneg = en8811h_config_aneg, -+ .read_status = en8811h_read_status, -+ .config_intr = en8811h_clear_intr, -+ .handle_interrupt = en8811h_handle_interrupt, -+ .led_hw_is_supported = en8811h_led_hw_is_supported, -+ .read_page = air_phy_read_page, -+ .write_page = air_phy_write_page, -+ .led_blink_set = air_led_blink_set, -+ .led_brightness_set = air_led_brightness_set, -+ .led_hw_control_set = air_led_hw_control_set, -+ .led_hw_control_get = air_led_hw_control_get, -+} }; -+ -+module_phy_driver(en8811h_driver); -+ -+static struct mdio_device_id __maybe_unused en8811h_tbl[] = { -+ { PHY_ID_MATCH_MODEL(EN8811H_PHY_ID) }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(mdio, en8811h_tbl); -+MODULE_FIRMWARE(EN8811H_MD32_DM); -+MODULE_FIRMWARE(EN8811H_MD32_DSP); -+ -+MODULE_DESCRIPTION("Airoha EN8811H PHY drivers"); -+MODULE_AUTHOR("Airoha"); -+MODULE_AUTHOR("Eric Woudstra "); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.1/799-v6.10-net-phy-air_en8811h-fix-some-error-codes.patch b/target/linux/generic/backport-6.1/799-v6.10-net-phy-air_en8811h-fix-some-error-codes.patch deleted file mode 100644 index 1bd0eefe77b512..00000000000000 --- a/target/linux/generic/backport-6.1/799-v6.10-net-phy-air_en8811h-fix-some-error-codes.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 87c33315af380ca12a2e59ac94edad4fe0481b4c Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Fri, 5 Apr 2024 13:08:59 +0300 -Subject: [PATCH] net: phy: air_en8811h: fix some error codes - -These error paths accidentally return "ret" which is zero/success -instead of the correct error code. - -Fixes: 71e79430117d ("net: phy: air_en8811h: Add the Airoha EN8811H PHY driver") -Signed-off-by: Dan Carpenter -Reviewed-by: Simon Horman -Link: https://lore.kernel.org/r/7ef2e230-dfb7-4a77-8973-9e5be1a99fc2@moroto.mountain -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/air_en8811h.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/air_en8811h.c -+++ b/drivers/net/phy/air_en8811h.c -@@ -272,11 +272,11 @@ static int __air_buckpbus_reg_read(struc - - pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH); - if (pbus_data_high < 0) -- return ret; -+ return pbus_data_high; - - pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW); - if (pbus_data_low < 0) -- return ret; -+ return pbus_data_low; - - *pbus_data = pbus_data_low | (pbus_data_high << 16); - return 0; -@@ -323,11 +323,11 @@ static int __air_buckpbus_reg_modify(str - - pbus_data_high = __phy_read(phydev, AIR_BPBUS_RD_DATA_HIGH); - if (pbus_data_high < 0) -- return ret; -+ return pbus_data_high; - - pbus_data_low = __phy_read(phydev, AIR_BPBUS_RD_DATA_LOW); - if (pbus_data_low < 0) -- return ret; -+ return pbus_data_low; - - pbus_data_old = pbus_data_low | (pbus_data_high << 16); - pbus_data_new = (pbus_data_old & ~mask) | set; diff --git a/target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch b/target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch deleted file mode 100644 index 592111fb9545be..00000000000000 --- a/target/linux/generic/backport-6.1/800-v6.3-leds-Move-led_init_default_state_get-to-the-global-h.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 156a5bb89ca6f3edd2be0bfd0de15e575442927e Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Tue, 3 Jan 2023 15:12:47 +0200 -Subject: [PATCH] leds: Move led_init_default_state_get() to the global header - -There are users inside and outside LED framework that have implemented -a local copy of led_init_default_state_get(). In order to deduplicate -that, as the first step move the declaration from LED header to the -global one. - -Signed-off-by: Andy Shevchenko -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230103131256.33894-3-andriy.shevchenko@linux.intel.com ---- - drivers/leds/leds.h | 1 - - include/linux/leds.h | 2 ++ - 2 files changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/leds/leds.h -+++ b/drivers/leds/leds.h -@@ -27,7 +27,6 @@ ssize_t led_trigger_read(struct file *fi - ssize_t led_trigger_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, char *buf, - loff_t pos, size_t count); --enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); - - extern struct rw_semaphore leds_list_lock; - extern struct list_head leds_list; ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -63,6 +63,8 @@ struct led_init_data { - bool devname_mandatory; - }; - -+enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); -+ - struct led_hw_trigger_type { - int dummy; - }; diff --git a/target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch b/target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch deleted file mode 100644 index f6a025fa12a3a8..00000000000000 --- a/target/linux/generic/backport-6.1/801-v6.4-01-net-dsa-qca8k-move-qca8k_port_to_phy-to-header.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 3e8b4d6277fd19d98c817576954dd6a4ff3caa2b Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 17 Apr 2023 17:17:23 +0200 -Subject: [PATCH 1/9] net: dsa: qca8k: move qca8k_port_to_phy() to header - -Move qca8k_port_to_phy() to qca8k header as it's useful for future -reference in Switch LEDs module since the same logic is applied to get -the right index of the switch port. -Make it inline as it's simple function that just decrease the port. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Reviewed-by: Michal Kubiak -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 15 --------------- - drivers/net/dsa/qca/qca8k.h | 14 ++++++++++++++ - 2 files changed, 14 insertions(+), 15 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -789,21 +789,6 @@ err_clear_skb: - return ret; - } - --static u32 --qca8k_port_to_phy(int port) --{ -- /* From Andrew Lunn: -- * Port 0 has no internal phy. -- * Port 1 has an internal PHY at MDIO address 0. -- * Port 2 has an internal PHY at MDIO address 1. -- * ... -- * Port 5 has an internal PHY at MDIO address 4. -- * Port 6 has no internal PHY. -- */ -- -- return port - 1; --} -- - static int - qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask) - { ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -421,6 +421,20 @@ struct qca8k_fdb { - u8 mac[6]; - }; - -+static inline u32 qca8k_port_to_phy(int port) -+{ -+ /* From Andrew Lunn: -+ * Port 0 has no internal phy. -+ * Port 1 has an internal PHY at MDIO address 0. -+ * Port 2 has an internal PHY at MDIO address 1. -+ * ... -+ * Port 5 has an internal PHY at MDIO address 4. -+ * Port 6 has no internal PHY. -+ */ -+ -+ return port - 1; -+} -+ - /* Common setup function */ - extern const struct qca8k_mib_desc ar8327_mib[]; - extern const struct regmap_access_table qca8k_readable_table; diff --git a/target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch b/target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch deleted file mode 100644 index 409fe9c7a19c79..00000000000000 --- a/target/linux/generic/backport-6.1/801-v6.4-02-net-dsa-qca8k-add-LEDs-basic-support.patch +++ /dev/null @@ -1,435 +0,0 @@ -From 1e264f9d2918b5737023c44a23ae04def1095210 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 17 Apr 2023 17:17:24 +0200 -Subject: [PATCH 2/9] net: dsa: qca8k: add LEDs basic support - -Add LEDs basic support for qca8k Switch Family by adding basic -brightness_set() support. - -Since these LEDs refelect port status, the default label is set to -":port". DT binding should describe the color and function of the -LEDs using standard LEDs api. -Each LED always have the device name as prefix. The device name is -composed from the mii bus id and the PHY addr resulting in example -names like: -- qca8k-0.0:00:amber:lan -- qca8k-0.0:00:white:lan -- qca8k-0.0:01:amber:lan -- qca8k-0.0:01:white:lan - -These LEDs supports only blocking variant of the brightness_set() -function since they can sleep during access of the switch leds to set -the brightness. - -While at it add to the qca8k header file each mode defined by the Switch -Documentation for future use. - -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/Kconfig | 8 ++ - drivers/net/dsa/qca/Makefile | 3 + - drivers/net/dsa/qca/qca8k-8xxx.c | 5 + - drivers/net/dsa/qca/qca8k-leds.c | 239 +++++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 60 ++++++++ - drivers/net/dsa/qca/qca8k_leds.h | 16 +++ - 6 files changed, 331 insertions(+) - create mode 100644 drivers/net/dsa/qca/qca8k-leds.c - create mode 100644 drivers/net/dsa/qca/qca8k_leds.h - ---- a/drivers/net/dsa/qca/Kconfig -+++ b/drivers/net/dsa/qca/Kconfig -@@ -15,3 +15,11 @@ config NET_DSA_QCA8K - help - This enables support for the Qualcomm Atheros QCA8K Ethernet - switch chips. -+ -+config NET_DSA_QCA8K_LEDS_SUPPORT -+ bool "Qualcomm Atheros QCA8K Ethernet switch family LEDs support" -+ depends on NET_DSA_QCA8K -+ depends on LEDS_CLASS -+ help -+ This enabled support for LEDs present on the Qualcomm Atheros -+ QCA8K Ethernet switch chips. ---- a/drivers/net/dsa/qca/Makefile -+++ b/drivers/net/dsa/qca/Makefile -@@ -2,3 +2,6 @@ - obj-$(CONFIG_NET_DSA_AR9331) += ar9331.o - obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o - qca8k-y += qca8k-common.o qca8k-8xxx.o -+ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT -+qca8k-y += qca8k-leds.o -+endif ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -22,6 +22,7 @@ - #include - - #include "qca8k.h" -+#include "qca8k_leds.h" - - static void - qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) -@@ -1851,6 +1852,10 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -+ ret = qca8k_setup_led_ctrl(priv); -+ if (ret) -+ return ret; -+ - qca8k_setup_pcs(priv, &priv->pcs_port_0, 0); - qca8k_setup_pcs(priv, &priv->pcs_port_6, 6); - ---- /dev/null -+++ b/drivers/net/dsa/qca/qca8k-leds.c -@@ -0,0 +1,239 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include -+#include -+ -+#include "qca8k.h" -+#include "qca8k_leds.h" -+ -+static int -+qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) -+{ -+ switch (port_num) { -+ case 0: -+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); -+ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT; -+ break; -+ case 1: -+ case 2: -+ case 3: -+ /* Port 123 are controlled on a different reg */ -+ reg_info->reg = QCA8K_LED_CTRL3_REG; -+ reg_info->shift = QCA8K_LED_PHY123_PATTERN_EN_SHIFT(port_num, led_num); -+ break; -+ case 4: -+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); -+ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int -+qca8k_led_brightness_set(struct qca8k_led *led, -+ enum led_brightness brightness) -+{ -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 mask, val; -+ -+ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); -+ -+ val = QCA8K_LED_ALWAYS_OFF; -+ if (brightness) -+ val = QCA8K_LED_ALWAYS_ON; -+ -+ /* HW regs to control brightness is special and port 1-2-3 -+ * are placed in a different reg. -+ * -+ * To control port 0 brightness: -+ * - the 2 bit (15, 14) of: -+ * - QCA8K_LED_CTRL0_REG for led1 -+ * - QCA8K_LED_CTRL1_REG for led2 -+ * - QCA8K_LED_CTRL2_REG for led3 -+ * -+ * To control port 4: -+ * - the 2 bit (31, 30) of: -+ * - QCA8K_LED_CTRL0_REG for led1 -+ * - QCA8K_LED_CTRL1_REG for led2 -+ * - QCA8K_LED_CTRL2_REG for led3 -+ * -+ * To control port 1: -+ * - the 2 bit at (9, 8) of QCA8K_LED_CTRL3_REG are used for led1 -+ * - the 2 bit at (11, 10) of QCA8K_LED_CTRL3_REG are used for led2 -+ * - the 2 bit at (13, 12) of QCA8K_LED_CTRL3_REG are used for led3 -+ * -+ * To control port 2: -+ * - the 2 bit at (15, 14) of QCA8K_LED_CTRL3_REG are used for led1 -+ * - the 2 bit at (17, 16) of QCA8K_LED_CTRL3_REG are used for led2 -+ * - the 2 bit at (19, 18) of QCA8K_LED_CTRL3_REG are used for led3 -+ * -+ * To control port 3: -+ * - the 2 bit at (21, 20) of QCA8K_LED_CTRL3_REG are used for led1 -+ * - the 2 bit at (23, 22) of QCA8K_LED_CTRL3_REG are used for led2 -+ * - the 2 bit at (25, 24) of QCA8K_LED_CTRL3_REG are used for led3 -+ * -+ * To abstract this and have less code, we use the port and led numm -+ * to calculate the shift and the correct reg due to this problem of -+ * not having a 1:1 map of LED with the regs. -+ */ -+ if (led->port_num == 0 || led->port_num == 4) { -+ mask = QCA8K_LED_PATTERN_EN_MASK; -+ val <<= QCA8K_LED_PATTERN_EN_SHIFT; -+ } else { -+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; -+ } -+ -+ return regmap_update_bits(priv->regmap, reg_info.reg, -+ mask << reg_info.shift, -+ val << reg_info.shift); -+} -+ -+static int -+qca8k_cled_brightness_set_blocking(struct led_classdev *ldev, -+ enum led_brightness brightness) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ -+ return qca8k_led_brightness_set(led, brightness); -+} -+ -+static enum led_brightness -+qca8k_led_brightness_get(struct qca8k_led *led) -+{ -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 val; -+ int ret; -+ -+ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); -+ -+ ret = regmap_read(priv->regmap, reg_info.reg, &val); -+ if (ret) -+ return 0; -+ -+ val >>= reg_info.shift; -+ -+ if (led->port_num == 0 || led->port_num == 4) { -+ val &= QCA8K_LED_PATTERN_EN_MASK; -+ val >>= QCA8K_LED_PATTERN_EN_SHIFT; -+ } else { -+ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK; -+ } -+ -+ /* Assume brightness ON only when the LED is set to always ON */ -+ return val == QCA8K_LED_ALWAYS_ON; -+} -+ -+static int -+qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) -+{ -+ struct fwnode_handle *led = NULL, *leds = NULL; -+ struct led_init_data init_data = { }; -+ struct dsa_switch *ds = priv->ds; -+ enum led_default_state state; -+ struct qca8k_led *port_led; -+ int led_num, led_index; -+ int ret; -+ -+ leds = fwnode_get_named_child_node(port, "leds"); -+ if (!leds) { -+ dev_dbg(priv->dev, "No Leds node specified in device tree for port %d!\n", -+ port_num); -+ return 0; -+ } -+ -+ fwnode_for_each_child_node(leds, led) { -+ /* Reg represent the led number of the port. -+ * Each port can have at most 3 leds attached -+ * Commonly: -+ * 1. is gigabit led -+ * 2. is mbit led -+ * 3. additional status led -+ */ -+ if (fwnode_property_read_u32(led, "reg", &led_num)) -+ continue; -+ -+ if (led_num >= QCA8K_LED_PORT_COUNT) { -+ dev_warn(priv->dev, "Invalid LED reg %d defined for port %d", -+ led_num, port_num); -+ continue; -+ } -+ -+ led_index = QCA8K_LED_PORT_INDEX(port_num, led_num); -+ -+ port_led = &priv->ports_led[led_index]; -+ port_led->port_num = port_num; -+ port_led->led_num = led_num; -+ port_led->priv = priv; -+ -+ state = led_init_default_state_get(led); -+ switch (state) { -+ case LEDS_DEFSTATE_ON: -+ port_led->cdev.brightness = 1; -+ qca8k_led_brightness_set(port_led, 1); -+ break; -+ case LEDS_DEFSTATE_KEEP: -+ port_led->cdev.brightness = -+ qca8k_led_brightness_get(port_led); -+ break; -+ default: -+ port_led->cdev.brightness = 0; -+ qca8k_led_brightness_set(port_led, 0); -+ } -+ -+ port_led->cdev.max_brightness = 1; -+ port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; -+ init_data.default_label = ":port"; -+ init_data.fwnode = led; -+ init_data.devname_mandatory = true; -+ init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d", ds->slave_mii_bus->id, -+ port_num); -+ if (!init_data.devicename) -+ return -ENOMEM; -+ -+ ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data); -+ if (ret) -+ dev_warn(priv->dev, "Failed to init LED %d for port %d", led_num, port_num); -+ -+ kfree(init_data.devicename); -+ } -+ -+ return 0; -+} -+ -+int -+qca8k_setup_led_ctrl(struct qca8k_priv *priv) -+{ -+ struct fwnode_handle *ports, *port; -+ int port_num; -+ int ret; -+ -+ ports = device_get_named_child_node(priv->dev, "ports"); -+ if (!ports) { -+ dev_info(priv->dev, "No ports node specified in device tree!"); -+ return 0; -+ } -+ -+ fwnode_for_each_child_node(ports, port) { -+ if (fwnode_property_read_u32(port, "reg", &port_num)) -+ continue; -+ -+ /* Skip checking for CPU port 0 and CPU port 6 as not supported */ -+ if (port_num == 0 || port_num == 6) -+ continue; -+ -+ /* Each port can have at most 3 different leds attached. -+ * Switch port starts from 0 to 6, but port 0 and 6 are CPU -+ * port. The port index needs to be decreased by one to identify -+ * the correct port for LED setup. -+ */ -+ ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num)); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - - #define QCA8K_ETHERNET_MDIO_PRIORITY 7 -@@ -85,6 +86,51 @@ - #define QCA8K_MDIO_MASTER_DATA(x) FIELD_PREP(QCA8K_MDIO_MASTER_DATA_MASK, x) - #define QCA8K_MDIO_MASTER_MAX_PORTS 5 - #define QCA8K_MDIO_MASTER_MAX_REG 32 -+ -+/* LED control register */ -+#define QCA8K_LED_PORT_COUNT 3 -+#define QCA8K_LED_COUNT ((QCA8K_NUM_PORTS - QCA8K_NUM_CPU_PORTS) * QCA8K_LED_PORT_COUNT) -+#define QCA8K_LED_RULE_COUNT 6 -+#define QCA8K_LED_RULE_MAX 11 -+#define QCA8K_LED_PORT_INDEX(_phy, _led) (((_phy) * QCA8K_LED_PORT_COUNT) + (_led)) -+ -+#define QCA8K_LED_PHY123_PATTERN_EN_SHIFT(_phy, _led) ((((_phy) - 1) * 6) + 8 + (2 * (_led))) -+#define QCA8K_LED_PHY123_PATTERN_EN_MASK GENMASK(1, 0) -+ -+#define QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT 0 -+#define QCA8K_LED_PHY4_CONTROL_RULE_SHIFT 16 -+ -+#define QCA8K_LED_CTRL_REG(_i) (0x050 + (_i) * 4) -+#define QCA8K_LED_CTRL0_REG 0x50 -+#define QCA8K_LED_CTRL1_REG 0x54 -+#define QCA8K_LED_CTRL2_REG 0x58 -+#define QCA8K_LED_CTRL3_REG 0x5C -+#define QCA8K_LED_CTRL_SHIFT(_i) (((_i) % 2) * 16) -+#define QCA8K_LED_CTRL_MASK GENMASK(15, 0) -+#define QCA8K_LED_RULE_MASK GENMASK(13, 0) -+#define QCA8K_LED_BLINK_FREQ_MASK GENMASK(1, 0) -+#define QCA8K_LED_BLINK_FREQ_SHITF 0 -+#define QCA8K_LED_BLINK_2HZ 0 -+#define QCA8K_LED_BLINK_4HZ 1 -+#define QCA8K_LED_BLINK_8HZ 2 -+#define QCA8K_LED_BLINK_AUTO 3 -+#define QCA8K_LED_LINKUP_OVER_MASK BIT(2) -+#define QCA8K_LED_TX_BLINK_MASK BIT(4) -+#define QCA8K_LED_RX_BLINK_MASK BIT(5) -+#define QCA8K_LED_COL_BLINK_MASK BIT(7) -+#define QCA8K_LED_LINK_10M_EN_MASK BIT(8) -+#define QCA8K_LED_LINK_100M_EN_MASK BIT(9) -+#define QCA8K_LED_LINK_1000M_EN_MASK BIT(10) -+#define QCA8K_LED_POWER_ON_LIGHT_MASK BIT(11) -+#define QCA8K_LED_HALF_DUPLEX_MASK BIT(12) -+#define QCA8K_LED_FULL_DUPLEX_MASK BIT(13) -+#define QCA8K_LED_PATTERN_EN_MASK GENMASK(15, 14) -+#define QCA8K_LED_PATTERN_EN_SHIFT 14 -+#define QCA8K_LED_ALWAYS_OFF 0 -+#define QCA8K_LED_ALWAYS_BLINK_4HZ 1 -+#define QCA8K_LED_ALWAYS_ON 2 -+#define QCA8K_LED_RULE_CONTROLLED 3 -+ - #define QCA8K_GOL_MAC_ADDR0 0x60 - #define QCA8K_GOL_MAC_ADDR1 0x64 - #define QCA8K_MAX_FRAME_SIZE 0x78 -@@ -382,6 +428,19 @@ struct qca8k_pcs { - int port; - }; - -+struct qca8k_led_pattern_en { -+ u32 reg; -+ u8 shift; -+}; -+ -+struct qca8k_led { -+ u8 port_num; -+ u8 led_num; -+ u16 old_rule; -+ struct qca8k_priv *priv; -+ struct led_classdev cdev; -+}; -+ - struct qca8k_priv { - u8 switch_id; - u8 switch_revision; -@@ -406,6 +465,7 @@ struct qca8k_priv { - struct qca8k_pcs pcs_port_0; - struct qca8k_pcs pcs_port_6; - const struct qca8k_match_data *info; -+ struct qca8k_led ports_led[QCA8K_LED_COUNT]; - }; - - struct qca8k_mib_desc { ---- /dev/null -+++ b/drivers/net/dsa/qca/qca8k_leds.h -@@ -0,0 +1,16 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#ifndef __QCA8K_LEDS_H -+#define __QCA8K_LEDS_H -+ -+/* Leds Support function */ -+#ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT -+int qca8k_setup_led_ctrl(struct qca8k_priv *priv); -+#else -+static inline int qca8k_setup_led_ctrl(struct qca8k_priv *priv) -+{ -+ return 0; -+} -+#endif -+ -+#endif /* __QCA8K_LEDS_H */ diff --git a/target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch b/target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch deleted file mode 100644 index 231c4156df8e06..00000000000000 --- a/target/linux/generic/backport-6.1/801-v6.4-03-net-dsa-qca8k-add-LEDs-blink_set-support.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 91acadcc6e599dfc62717abcdad58a459cfb1684 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 17 Apr 2023 17:17:25 +0200 -Subject: [PATCH 3/9] net: dsa: qca8k: add LEDs blink_set() support - -Add LEDs blink_set() support to qca8k Switch Family. -These LEDs support hw accellerated blinking at a fixed rate -of 4Hz. - -Reject any other value since not supported by the LEDs switch. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Acked-by: Pavel Machek -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-leds.c | 38 ++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - ---- a/drivers/net/dsa/qca/qca8k-leds.c -+++ b/drivers/net/dsa/qca/qca8k-leds.c -@@ -128,6 +128,43 @@ qca8k_led_brightness_get(struct qca8k_le - } - - static int -+qca8k_cled_blink_set(struct led_classdev *ldev, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ u32 mask, val = QCA8K_LED_ALWAYS_BLINK_4HZ; -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ -+ if (*delay_on == 0 && *delay_off == 0) { -+ *delay_on = 125; -+ *delay_off = 125; -+ } -+ -+ if (*delay_on != 125 || *delay_off != 125) { -+ /* The hardware only supports blinking at 4Hz. Fall back -+ * to software implementation in other cases. -+ */ -+ return -EINVAL; -+ } -+ -+ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); -+ -+ if (led->port_num == 0 || led->port_num == 4) { -+ mask = QCA8K_LED_PATTERN_EN_MASK; -+ val <<= QCA8K_LED_PATTERN_EN_SHIFT; -+ } else { -+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; -+ } -+ -+ regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift, -+ val << reg_info.shift); -+ -+ return 0; -+} -+ -+static int - qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) - { - struct fwnode_handle *led = NULL, *leds = NULL; -@@ -186,6 +223,7 @@ qca8k_parse_port_leds(struct qca8k_priv - - port_led->cdev.max_brightness = 1; - port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; -+ port_led->cdev.blink_set = qca8k_cled_blink_set; - init_data.default_label = ":port"; - init_data.fwnode = led; - init_data.devname_mandatory = true; diff --git a/target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch b/target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch deleted file mode 100644 index bc905b4468c1b2..00000000000000 --- a/target/linux/generic/backport-6.1/801-v6.4-04-leds-Provide-stubs-for-when-CLASS_LED-NEW_LEDS-are-d.patch +++ /dev/null @@ -1,59 +0,0 @@ -From e5029edd53937a29801ef507cee12e657ff31ea9 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:26 +0200 -Subject: [PATCH 4/9] leds: Provide stubs for when CLASS_LED & NEW_LEDS are - disabled - -Provide stubs for devm_led_classdev_register_ext() and -led_init_default_state_get() so that LED drivers embedded within other -drivers such as PHYs and Ethernet switches still build when LEDS_CLASS -or NEW_LEDS are disabled. This also helps with Kconfig dependencies, -which are somewhat hairy for phylib and mdio and only get worse when -adding a dependency on LED_CLASS. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - include/linux/leds.h | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -63,7 +63,15 @@ struct led_init_data { - bool devname_mandatory; - }; - -+#if IS_ENABLED(CONFIG_NEW_LEDS) - enum led_default_state led_init_default_state_get(struct fwnode_handle *fwnode); -+#else -+static inline enum led_default_state -+led_init_default_state_get(struct fwnode_handle *fwnode) -+{ -+ return LEDS_DEFSTATE_OFF; -+} -+#endif - - struct led_hw_trigger_type { - int dummy; -@@ -198,9 +206,19 @@ static inline int led_classdev_register( - return led_classdev_register_ext(parent, led_cdev, NULL); - } - -+#if IS_ENABLED(CONFIG_LEDS_CLASS) - int devm_led_classdev_register_ext(struct device *parent, - struct led_classdev *led_cdev, - struct led_init_data *init_data); -+#else -+static inline int -+devm_led_classdev_register_ext(struct device *parent, -+ struct led_classdev *led_cdev, -+ struct led_init_data *init_data) -+{ -+ return 0; -+} -+#endif - - static inline int devm_led_classdev_register(struct device *parent, - struct led_classdev *led_cdev) diff --git a/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch b/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch deleted file mode 100644 index 0d2c0bcd83f26f..00000000000000 --- a/target/linux/generic/backport-6.1/801-v6.4-05-net-phy-Add-a-binding-for-PHY-LEDs.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 01e5b728e9e43ae444e0369695a5f72209906464 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:27 +0200 -Subject: [PATCH 5/9] net: phy: Add a binding for PHY LEDs - -Define common binding parsing for all PHY drivers with LEDs using -phylib. Parse the DT as part of the phy_probe and add LEDs to the -linux LED class infrastructure. For the moment, provide a dummy -brightness function, which will later be replaced with a call into the -PHY driver. This allows testing since the LED core might otherwise -reject an LED whose brightness cannot be set. - -Add a dependency on LED_CLASS. It either needs to be built in, or not -enabled, since a modular build can result in linker errors. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/Kconfig | 1 + - drivers/net/phy/phy_device.c | 76 ++++++++++++++++++++++++++++++++++++ - include/linux/phy.h | 16 ++++++++ - 3 files changed, 93 insertions(+) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -18,6 +18,7 @@ menuconfig PHYLIB - depends on NETDEVICES - select MDIO_DEVICE - select MDIO_DEVRES -+ depends on LEDS_CLASS || LEDS_CLASS=n - help - Ethernet controllers are usually attached to PHY - devices. This option provides infrastructure for ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -19,10 +19,12 @@ - #include - #include - #include -+#include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -642,6 +644,7 @@ struct phy_device *phy_device_create(str - device_initialize(&mdiodev->dev); - - dev->state = PHY_DOWN; -+ INIT_LIST_HEAD(&dev->leds); - - mutex_init(&dev->lock); - INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); -@@ -3035,6 +3038,74 @@ static bool phy_drv_supports_irq(struct - return phydrv->config_intr && phydrv->handle_interrupt; - } - -+/* Dummy implementation until calls into PHY driver are added */ -+static int phy_led_set_brightness(struct led_classdev *led_cdev, -+ enum led_brightness value) -+{ -+ return 0; -+} -+ -+static int of_phy_led(struct phy_device *phydev, -+ struct device_node *led) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ struct led_init_data init_data = {}; -+ struct led_classdev *cdev; -+ struct phy_led *phyled; -+ int err; -+ -+ phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL); -+ if (!phyled) -+ return -ENOMEM; -+ -+ cdev = &phyled->led_cdev; -+ -+ err = of_property_read_u8(led, "reg", &phyled->index); -+ if (err) -+ return err; -+ -+ cdev->brightness_set_blocking = phy_led_set_brightness; -+ cdev->max_brightness = 1; -+ init_data.devicename = dev_name(&phydev->mdio.dev); -+ init_data.fwnode = of_fwnode_handle(led); -+ init_data.devname_mandatory = true; -+ -+ err = devm_led_classdev_register_ext(dev, cdev, &init_data); -+ if (err) -+ return err; -+ -+ list_add(&phyled->list, &phydev->leds); -+ -+ return 0; -+} -+ -+static int of_phy_leds(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ struct device_node *leds, *led; -+ int err; -+ -+ if (!IS_ENABLED(CONFIG_OF_MDIO)) -+ return 0; -+ -+ if (!node) -+ return 0; -+ -+ leds = of_get_child_by_name(node, "leds"); -+ if (!leds) -+ return 0; -+ -+ for_each_available_child_of_node(leds, led) { -+ err = of_phy_led(phydev, led); -+ if (err) { -+ of_node_put(led); -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ - /** - * fwnode_mdio_find_device - Given a fwnode, find the mdio_device - * @fwnode: pointer to the mdio_device's fwnode -@@ -3213,6 +3284,11 @@ static int phy_probe(struct device *dev) - /* Set the state to READY by default */ - phydev->state = PHY_READY; - -+ /* Get the LEDs from the device tree, and instantiate standard -+ * LEDs for them. -+ */ -+ err = of_phy_leds(phydev); -+ - out: - /* Re-assert the reset signal on error */ - if (err) ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -606,6 +607,7 @@ struct macsec_ops; - * @phy_num_led_triggers: Number of triggers in @phy_led_triggers - * @led_link_trigger: LED trigger for link up/down - * @last_triggered: last LED trigger for link speed -+ * @leds: list of PHY LED structures - * @master_slave_set: User requested master/slave configuration - * @master_slave_get: Current master/slave advertisement - * @master_slave_state: Current master/slave configuration -@@ -698,6 +700,7 @@ struct phy_device { - - struct phy_led_trigger *led_link_trigger; - #endif -+ struct list_head leds; - - /* - * Interrupt number for this PHY -@@ -772,6 +775,19 @@ struct phy_tdr_config { - #define PHY_PAIR_ALL -1 - - /** -+ * struct phy_led: An LED driven by the PHY -+ * -+ * @list: List of LEDs -+ * @led_cdev: Standard LED class structure -+ * @index: Number of the LED -+ */ -+struct phy_led { -+ struct list_head list; -+ struct led_classdev led_cdev; -+ u8 index; -+}; -+ -+/** - * struct phy_driver - Driver structure for a particular PHY type - * - * @mdiodrv: Data common to all MDIO devices diff --git a/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch deleted file mode 100644 index 4873c40a7766b3..00000000000000 --- a/target/linux/generic/backport-6.1/801-v6.4-06-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 684818189b04b095b34964ed4a3ea5249a840eab Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:28 +0200 -Subject: [PATCH 6/9] net: phy: phy_device: Call into the PHY driver to set LED - brightness - -Linux LEDs can be software controlled via the brightness file in /sys. -LED drivers need to implement a brightness_set function which the core -will call. Implement an intermediary in phy_device, which will call -into the phy driver if it implements the necessary function. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/phy_device.c | 15 ++++++++++++--- - include/linux/phy.h | 13 +++++++++++++ - 2 files changed, 25 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -3038,11 +3038,18 @@ static bool phy_drv_supports_irq(struct - return phydrv->config_intr && phydrv->handle_interrupt; - } - --/* Dummy implementation until calls into PHY driver are added */ - static int phy_led_set_brightness(struct led_classdev *led_cdev, - enum led_brightness value) - { -- return 0; -+ struct phy_led *phyled = to_phy_led(led_cdev); -+ struct phy_device *phydev = phyled->phydev; -+ int err; -+ -+ mutex_lock(&phydev->lock); -+ err = phydev->drv->led_brightness_set(phydev, phyled->index, value); -+ mutex_unlock(&phydev->lock); -+ -+ return err; - } - - static int of_phy_led(struct phy_device *phydev, -@@ -3059,12 +3066,14 @@ static int of_phy_led(struct phy_device - return -ENOMEM; - - cdev = &phyled->led_cdev; -+ phyled->phydev = phydev; - - err = of_property_read_u8(led, "reg", &phyled->index); - if (err) - return err; - -- cdev->brightness_set_blocking = phy_led_set_brightness; -+ if (phydev->drv->led_brightness_set) -+ cdev->brightness_set_blocking = phy_led_set_brightness; - cdev->max_brightness = 1; - init_data.devicename = dev_name(&phydev->mdio.dev); - init_data.fwnode = of_fwnode_handle(led); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -778,15 +778,19 @@ struct phy_tdr_config { - * struct phy_led: An LED driven by the PHY - * - * @list: List of LEDs -+ * @phydev: PHY this LED is attached to - * @led_cdev: Standard LED class structure - * @index: Number of the LED - */ - struct phy_led { - struct list_head list; -+ struct phy_device *phydev; - struct led_classdev led_cdev; - u8 index; - }; - -+#define to_phy_led(d) container_of(d, struct phy_led, led_cdev) -+ - /** - * struct phy_driver - Driver structure for a particular PHY type - * -@@ -1001,6 +1005,15 @@ struct phy_driver { - int (*get_sqi)(struct phy_device *dev); - /** @get_sqi_max: Get the maximum signal quality indication */ - int (*get_sqi_max)(struct phy_device *dev); -+ -+ /** -+ * @led_brightness_set: Set a PHY LED brightness. Index -+ * indicates which of the PHYs led should be set. Value -+ * follows the standard LED class meaning, e.g. LED_OFF, -+ * LED_HALF, LED_FULL. -+ */ -+ int (*led_brightness_set)(struct phy_device *dev, -+ u8 index, enum led_brightness value); - }; - #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ - struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch b/target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch deleted file mode 100644 index 5114c0e6da21c0..00000000000000 --- a/target/linux/generic/backport-6.1/801-v6.4-07-net-phy-marvell-Add-software-control-of-the-LEDs.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 2d3960e58ef7c83fe1dbf952f056b9e906cb6df8 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:29 +0200 -Subject: [PATCH 7/9] net: phy: marvell: Add software control of the LEDs - -Add a brightness function, so the LEDs can be controlled from -software using the standard Linux LED infrastructure. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/marvell.c | 45 ++++++++++++++++++++++++++++++++++----- - 1 file changed, 40 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -144,11 +144,13 @@ - /* WOL Event Interrupt Enable */ - #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7) - --/* LED Timer Control Register */ --#define MII_88E1318S_PHY_LED_TCR 0x12 --#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) --#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) --#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) -+#define MII_88E1318S_PHY_LED_FUNC 0x10 -+#define MII_88E1318S_PHY_LED_FUNC_OFF (0x8) -+#define MII_88E1318S_PHY_LED_FUNC_ON (0x9) -+#define MII_88E1318S_PHY_LED_TCR 0x12 -+#define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) -+#define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) -+#define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW BIT(11) - - /* Magic Packet MAC address registers */ - #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2 0x17 -@@ -2832,6 +2834,34 @@ static int marvell_hwmon_probe(struct ph - } - #endif - -+static int m88e1318_led_brightness_set(struct phy_device *phydev, -+ u8 index, enum led_brightness value) -+{ -+ int reg; -+ -+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC); -+ if (reg < 0) -+ return reg; -+ -+ switch (index) { -+ case 0: -+ case 1: -+ case 2: -+ reg &= ~(0xf << (4 * index)); -+ if (value == LED_OFF) -+ reg |= MII_88E1318S_PHY_LED_FUNC_OFF << (4 * index); -+ else -+ reg |= MII_88E1318S_PHY_LED_FUNC_ON << (4 * index); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC, reg); -+} -+ - static int marvell_probe(struct phy_device *phydev) - { - struct marvell_priv *priv; -@@ -3081,6 +3111,7 @@ static struct phy_driver marvell_drivers - .get_sset_count = marvell_get_sset_count, - .get_strings = marvell_get_strings, - .get_stats = marvell_get_stats, -+ .led_brightness_set = m88e1318_led_brightness_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1145, -@@ -3187,6 +3218,7 @@ static struct phy_driver marvell_drivers - .cable_test_start = marvell_vct7_cable_test_start, - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, -+ .led_brightness_set = m88e1318_led_brightness_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1540, -@@ -3213,6 +3245,7 @@ static struct phy_driver marvell_drivers - .cable_test_start = marvell_vct7_cable_test_start, - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, -+ .led_brightness_set = m88e1318_led_brightness_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1545, -@@ -3239,6 +3272,7 @@ static struct phy_driver marvell_drivers - .cable_test_start = marvell_vct7_cable_test_start, - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, -+ .led_brightness_set = m88e1318_led_brightness_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E3016, -@@ -3380,6 +3414,7 @@ static struct phy_driver marvell_drivers - .get_stats = marvell_get_stats, - .get_tunable = m88e1540_get_tunable, - .set_tunable = m88e1540_set_tunable, -+ .led_brightness_set = m88e1318_led_brightness_set, - }, - }; - diff --git a/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch deleted file mode 100644 index 00bdcc54689ce6..00000000000000 --- a/target/linux/generic/backport-6.1/801-v6.4-08-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 4e901018432e38eab35d2a352661ce4727795be1 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:30 +0200 -Subject: [PATCH 8/9] net: phy: phy_device: Call into the PHY driver to set LED - blinking - -Linux LEDs can be requested to perform hardware accelerated -blinking. Pass this to the PHY driver, if it implements the op. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/phy_device.c | 18 ++++++++++++++++++ - include/linux/phy.h | 12 ++++++++++++ - 2 files changed, 30 insertions(+) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -3052,6 +3052,22 @@ static int phy_led_set_brightness(struct - return err; - } - -+static int phy_led_blink_set(struct led_classdev *led_cdev, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ struct phy_led *phyled = to_phy_led(led_cdev); -+ struct phy_device *phydev = phyled->phydev; -+ int err; -+ -+ mutex_lock(&phydev->lock); -+ err = phydev->drv->led_blink_set(phydev, phyled->index, -+ delay_on, delay_off); -+ mutex_unlock(&phydev->lock); -+ -+ return err; -+} -+ - static int of_phy_led(struct phy_device *phydev, - struct device_node *led) - { -@@ -3074,6 +3090,8 @@ static int of_phy_led(struct phy_device - - if (phydev->drv->led_brightness_set) - cdev->brightness_set_blocking = phy_led_set_brightness; -+ if (phydev->drv->led_blink_set) -+ cdev->blink_set = phy_led_blink_set; - cdev->max_brightness = 1; - init_data.devicename = dev_name(&phydev->mdio.dev); - init_data.fwnode = of_fwnode_handle(led); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -1014,6 +1014,18 @@ struct phy_driver { - */ - int (*led_brightness_set)(struct phy_device *dev, - u8 index, enum led_brightness value); -+ -+ /** -+ * @led_blink_set: Set a PHY LED brightness. Index indicates -+ * which of the PHYs led should be configured to blink. Delays -+ * are in milliseconds and if both are zero then a sensible -+ * default should be chosen. The call should adjust the -+ * timings in that case and if it can't match the values -+ * specified exactly. -+ */ -+ int (*led_blink_set)(struct phy_device *dev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off); - }; - #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ - struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch b/target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch deleted file mode 100644 index 8d5081a43c1039..00000000000000 --- a/target/linux/generic/backport-6.1/801-v6.4-09-net-phy-marvell-Implement-led_blink_set.patch +++ /dev/null @@ -1,104 +0,0 @@ -From ea9e86485decb2ac1750005bd96c166c9b780406 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 17 Apr 2023 17:17:31 +0200 -Subject: [PATCH 9/9] net: phy: marvell: Implement led_blink_set() - -The Marvell PHY can blink the LEDs, simple on/off. All LEDs blink at -the same rate, and the reset default is 84ms per blink, which is -around 12Hz. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/phy/marvell.c | 36 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -147,6 +147,8 @@ - #define MII_88E1318S_PHY_LED_FUNC 0x10 - #define MII_88E1318S_PHY_LED_FUNC_OFF (0x8) - #define MII_88E1318S_PHY_LED_FUNC_ON (0x9) -+#define MII_88E1318S_PHY_LED_FUNC_HI_Z (0xa) -+#define MII_88E1318S_PHY_LED_FUNC_BLINK (0xb) - #define MII_88E1318S_PHY_LED_TCR 0x12 - #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15) - #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE BIT(7) -@@ -2862,6 +2864,35 @@ static int m88e1318_led_brightness_set(s - MII_88E1318S_PHY_LED_FUNC, reg); - } - -+static int m88e1318_led_blink_set(struct phy_device *phydev, u8 index, -+ unsigned long *delay_on, -+ unsigned long *delay_off) -+{ -+ int reg; -+ -+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC); -+ if (reg < 0) -+ return reg; -+ -+ switch (index) { -+ case 0: -+ case 1: -+ case 2: -+ reg &= ~(0xf << (4 * index)); -+ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); -+ /* Reset default is 84ms */ -+ *delay_on = 84 / 2; -+ *delay_off = 84 / 2; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC, reg); -+} -+ - static int marvell_probe(struct phy_device *phydev) - { - struct marvell_priv *priv; -@@ -3112,6 +3143,7 @@ static struct phy_driver marvell_drivers - .get_strings = marvell_get_strings, - .get_stats = marvell_get_stats, - .led_brightness_set = m88e1318_led_brightness_set, -+ .led_blink_set = m88e1318_led_blink_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1145, -@@ -3219,6 +3251,7 @@ static struct phy_driver marvell_drivers - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, - .led_brightness_set = m88e1318_led_brightness_set, -+ .led_blink_set = m88e1318_led_blink_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1540, -@@ -3246,6 +3279,7 @@ static struct phy_driver marvell_drivers - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, - .led_brightness_set = m88e1318_led_brightness_set, -+ .led_blink_set = m88e1318_led_blink_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E1545, -@@ -3273,6 +3307,7 @@ static struct phy_driver marvell_drivers - .cable_test_tdr_start = marvell_vct5_cable_test_tdr_start, - .cable_test_get_status = marvell_vct7_cable_test_get_status, - .led_brightness_set = m88e1318_led_brightness_set, -+ .led_blink_set = m88e1318_led_blink_set, - }, - { - .phy_id = MARVELL_PHY_ID_88E3016, -@@ -3415,6 +3450,7 @@ static struct phy_driver marvell_drivers - .get_tunable = m88e1540_get_tunable, - .set_tunable = m88e1540_set_tunable, - .led_brightness_set = m88e1318_led_brightness_set, -+ .led_blink_set = m88e1318_led_blink_set, - }, - }; - diff --git a/target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch b/target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch deleted file mode 100644 index 56df3f095e4c5c..00000000000000 --- a/target/linux/generic/backport-6.1/802-v6.4-net-phy-marvell-Fix-inconsistent-indenting-in-led_bl.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 4774ad841bef97cc51df90195338c5b2573dd4cb Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 23 Apr 2023 19:28:00 +0200 -Subject: [PATCH] net: phy: marvell: Fix inconsistent indenting in - led_blink_set - -Fix inconsistent indeinting in m88e1318_led_blink_set reported by kernel -test robot, probably done by the presence of an if condition dropped in -later revision of the same code. - -Reported-by: kernel test robot -Link: https://lore.kernel.org/oe-kbuild-all/202304240007.0VEX8QYG-lkp@intel.com/ -Fixes: ea9e86485dec ("net: phy: marvell: Implement led_blink_set()") -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20230423172800.3470-1-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/marvell.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -2880,10 +2880,10 @@ static int m88e1318_led_blink_set(struct - case 1: - case 2: - reg &= ~(0xf << (4 * index)); -- reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); -- /* Reset default is 84ms */ -- *delay_on = 84 / 2; -- *delay_off = 84 / 2; -+ reg |= MII_88E1318S_PHY_LED_FUNC_BLINK << (4 * index); -+ /* Reset default is 84ms */ -+ *delay_on = 84 / 2; -+ *delay_off = 84 / 2; - break; - default: - return -EINVAL; diff --git a/target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch b/target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch deleted file mode 100644 index 3170c260580a4e..00000000000000 --- a/target/linux/generic/backport-6.1/803-v6.5-02-leds-trigger-netdev-Drop-NETDEV_LED_MODE_LINKUP-from.patch +++ /dev/null @@ -1,87 +0,0 @@ -From e2f24cb1b5daf9a4f6f3ba574c1fa74aab9807a4 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 19 Apr 2023 23:07:40 +0200 -Subject: [PATCH 2/5] leds: trigger: netdev: Drop NETDEV_LED_MODE_LINKUP from - mode - -Putting NETDEV_LED_MODE_LINKUP in the same list of the netdev trigger -modes is wrong as it's used to set the link state of the device and not -to set a blink mode as it's done by NETDEV_LED_LINK, NETDEV_LED_TX and -NETDEV_LED_RX. It's also wrong to put this state in the same bitmap of the -netdev trigger mode and should be external to it. - -Drop NETDEV_LED_MODE_LINKUP from mode list and convert to a simple bool -that will be true or false based on the carrier link. No functional -change intended. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230419210743.3594-3-ansuelsmth@gmail.com ---- - drivers/leds/trigger/ledtrig-netdev.c | 19 ++++++++----------- - 1 file changed, 8 insertions(+), 11 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -50,10 +50,10 @@ struct led_netdev_data { - unsigned int last_activity; - - unsigned long mode; -+ bool carrier_link_up; - #define NETDEV_LED_LINK 0 - #define NETDEV_LED_TX 1 - #define NETDEV_LED_RX 2 --#define NETDEV_LED_MODE_LINKUP 3 - }; - - enum netdev_led_attr { -@@ -73,9 +73,9 @@ static void set_baseline_state(struct le - if (!led_cdev->blink_brightness) - led_cdev->blink_brightness = led_cdev->max_brightness; - -- if (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode)) -+ if (!trigger_data->carrier_link_up) { - led_set_brightness(led_cdev, LED_OFF); -- else { -+ } else { - if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) - led_set_brightness(led_cdev, - led_cdev->blink_brightness); -@@ -131,10 +131,9 @@ static ssize_t device_name_store(struct - trigger_data->net_dev = - dev_get_by_name(&init_net, trigger_data->device_name); - -- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ trigger_data->carrier_link_up = false; - if (trigger_data->net_dev != NULL) -- if (netif_carrier_ok(trigger_data->net_dev)) -- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev); - - trigger_data->last_activity = 0; - -@@ -315,11 +314,10 @@ static int netdev_trig_notify(struct not - - spin_lock_bh(&trigger_data->lock); - -- clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ trigger_data->carrier_link_up = false; - switch (evt) { - case NETDEV_CHANGENAME: -- if (netif_carrier_ok(dev)) -- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ trigger_data->carrier_link_up = netif_carrier_ok(dev); - fallthrough; - case NETDEV_REGISTER: - if (trigger_data->net_dev) -@@ -333,8 +331,7 @@ static int netdev_trig_notify(struct not - break; - case NETDEV_UP: - case NETDEV_CHANGE: -- if (netif_carrier_ok(dev)) -- set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); -+ trigger_data->carrier_link_up = netif_carrier_ok(dev); - break; - } - diff --git a/target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch b/target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch deleted file mode 100644 index 19cc1d7c9edc16..00000000000000 --- a/target/linux/generic/backport-6.1/803-v6.5-03-leds-trigger-netdev-Rename-add-namespace-to-netdev-t.patch +++ /dev/null @@ -1,149 +0,0 @@ -From bdec9cb83936e0ac4cb87fed5b49fad0175f7dec Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 19 Apr 2023 23:07:41 +0200 -Subject: [PATCH 3/5] leds: trigger: netdev: Rename add namespace to netdev - trigger enum modes - -Rename NETDEV trigger enum modes to a more symbolic name and add a -namespace to them. - -Also add __TRIGGER_NETDEV_MAX to identify the max modes of the netdev -trigger. - -This is a cleanup to drop the define and no behaviour change are -intended. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230419210743.3594-4-ansuelsmth@gmail.com ---- - drivers/leds/trigger/ledtrig-netdev.c | 58 ++++++++++++--------------- - 1 file changed, 25 insertions(+), 33 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -51,15 +51,15 @@ struct led_netdev_data { - - unsigned long mode; - bool carrier_link_up; --#define NETDEV_LED_LINK 0 --#define NETDEV_LED_TX 1 --#define NETDEV_LED_RX 2 - }; - --enum netdev_led_attr { -- NETDEV_ATTR_LINK, -- NETDEV_ATTR_TX, -- NETDEV_ATTR_RX -+enum led_trigger_netdev_modes { -+ TRIGGER_NETDEV_LINK = 0, -+ TRIGGER_NETDEV_TX, -+ TRIGGER_NETDEV_RX, -+ -+ /* Keep last */ -+ __TRIGGER_NETDEV_MAX, - }; - - static void set_baseline_state(struct led_netdev_data *trigger_data) -@@ -76,7 +76,7 @@ static void set_baseline_state(struct le - if (!trigger_data->carrier_link_up) { - led_set_brightness(led_cdev, LED_OFF); - } else { -- if (test_bit(NETDEV_LED_LINK, &trigger_data->mode)) -+ if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode)) - led_set_brightness(led_cdev, - led_cdev->blink_brightness); - else -@@ -85,8 +85,8 @@ static void set_baseline_state(struct le - /* If we are looking for RX/TX start periodically - * checking stats - */ -- if (test_bit(NETDEV_LED_TX, &trigger_data->mode) || -- test_bit(NETDEV_LED_RX, &trigger_data->mode)) -+ if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) || -+ test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) - schedule_delayed_work(&trigger_data->work, 0); - } - } -@@ -146,20 +146,16 @@ static ssize_t device_name_store(struct - static DEVICE_ATTR_RW(device_name); - - static ssize_t netdev_led_attr_show(struct device *dev, char *buf, -- enum netdev_led_attr attr) -+ enum led_trigger_netdev_modes attr) - { - struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); - int bit; - - switch (attr) { -- case NETDEV_ATTR_LINK: -- bit = NETDEV_LED_LINK; -- break; -- case NETDEV_ATTR_TX: -- bit = NETDEV_LED_TX; -- break; -- case NETDEV_ATTR_RX: -- bit = NETDEV_LED_RX; -+ case TRIGGER_NETDEV_LINK: -+ case TRIGGER_NETDEV_TX: -+ case TRIGGER_NETDEV_RX: -+ bit = attr; - break; - default: - return -EINVAL; -@@ -169,7 +165,7 @@ static ssize_t netdev_led_attr_show(stru - } - - static ssize_t netdev_led_attr_store(struct device *dev, const char *buf, -- size_t size, enum netdev_led_attr attr) -+ size_t size, enum led_trigger_netdev_modes attr) - { - struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); - unsigned long state; -@@ -181,14 +177,10 @@ static ssize_t netdev_led_attr_store(str - return ret; - - switch (attr) { -- case NETDEV_ATTR_LINK: -- bit = NETDEV_LED_LINK; -- break; -- case NETDEV_ATTR_TX: -- bit = NETDEV_LED_TX; -- break; -- case NETDEV_ATTR_RX: -- bit = NETDEV_LED_RX; -+ case TRIGGER_NETDEV_LINK: -+ case TRIGGER_NETDEV_TX: -+ case TRIGGER_NETDEV_RX: -+ bit = attr; - break; - default: - return -EINVAL; -@@ -360,21 +352,21 @@ static void netdev_trig_work(struct work - } - - /* If we are not looking for RX/TX then return */ -- if (!test_bit(NETDEV_LED_TX, &trigger_data->mode) && -- !test_bit(NETDEV_LED_RX, &trigger_data->mode)) -+ if (!test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) && -+ !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) - return; - - dev_stats = dev_get_stats(trigger_data->net_dev, &temp); - new_activity = -- (test_bit(NETDEV_LED_TX, &trigger_data->mode) ? -+ (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ? - dev_stats->tx_packets : 0) + -- (test_bit(NETDEV_LED_RX, &trigger_data->mode) ? -+ (test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ? - dev_stats->rx_packets : 0); - - if (trigger_data->last_activity != new_activity) { - led_stop_software_blink(trigger_data->led_cdev); - -- invert = test_bit(NETDEV_LED_LINK, &trigger_data->mode); -+ invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode); - interval = jiffies_to_msecs( - atomic_read(&trigger_data->interval)); - /* base state is ON (link present) */ diff --git a/target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch b/target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch deleted file mode 100644 index 3b45951f5706ad..00000000000000 --- a/target/linux/generic/backport-6.1/803-v6.5-04-leds-trigger-netdev-Convert-device-attr-to-macro.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 164b67d53476a9d114be85c885bd31f783835be4 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 19 Apr 2023 23:07:42 +0200 -Subject: [PATCH 4/5] leds: trigger: netdev: Convert device attr to macro - -Convert link tx and rx device attr to a common macro to reduce common -code and in preparation for additional attr. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230419210743.3594-5-ansuelsmth@gmail.com ---- - drivers/leds/trigger/ledtrig-netdev.c | 57 ++++++++------------------- - 1 file changed, 16 insertions(+), 41 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -198,47 +198,22 @@ static ssize_t netdev_led_attr_store(str - return size; - } - --static ssize_t link_show(struct device *dev, -- struct device_attribute *attr, char *buf) --{ -- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_LINK); --} -- --static ssize_t link_store(struct device *dev, -- struct device_attribute *attr, const char *buf, size_t size) --{ -- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_LINK); --} -- --static DEVICE_ATTR_RW(link); -- --static ssize_t tx_show(struct device *dev, -- struct device_attribute *attr, char *buf) --{ -- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_TX); --} -- --static ssize_t tx_store(struct device *dev, -- struct device_attribute *attr, const char *buf, size_t size) --{ -- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_TX); --} -- --static DEVICE_ATTR_RW(tx); -- --static ssize_t rx_show(struct device *dev, -- struct device_attribute *attr, char *buf) --{ -- return netdev_led_attr_show(dev, buf, NETDEV_ATTR_RX); --} -- --static ssize_t rx_store(struct device *dev, -- struct device_attribute *attr, const char *buf, size_t size) --{ -- return netdev_led_attr_store(dev, buf, size, NETDEV_ATTR_RX); --} -- --static DEVICE_ATTR_RW(rx); -+#define DEFINE_NETDEV_TRIGGER(trigger_name, trigger) \ -+ static ssize_t trigger_name##_show(struct device *dev, \ -+ struct device_attribute *attr, char *buf) \ -+ { \ -+ return netdev_led_attr_show(dev, buf, trigger); \ -+ } \ -+ static ssize_t trigger_name##_store(struct device *dev, \ -+ struct device_attribute *attr, const char *buf, size_t size) \ -+ { \ -+ return netdev_led_attr_store(dev, buf, size, trigger); \ -+ } \ -+ static DEVICE_ATTR_RW(trigger_name) -+ -+DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK); -+DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); -+DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); - - static ssize_t interval_show(struct device *dev, - struct device_attribute *attr, char *buf) diff --git a/target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch b/target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch deleted file mode 100644 index 180bee96128a5d..00000000000000 --- a/target/linux/generic/backport-6.1/803-v6.5-05-leds-trigger-netdev-Use-mutex-instead-of-spinlocks.patch +++ /dev/null @@ -1,106 +0,0 @@ -From d1b9e1391ab2dc80e9db87fe8b2de015c651e4c9 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 19 Apr 2023 23:07:43 +0200 -Subject: [PATCH 5/5] leds: trigger: netdev: Use mutex instead of spinlocks - -Some LEDs may require to sleep while doing some operation like setting -brightness and other cleanup. - -For this reason, using a spinlock will cause a sleep under spinlock -warning. - -It should be safe to convert this to a sleepable lock since: -- sysfs read/write can sleep -- netdev_trig_work is a work queue and can sleep -- netdev _trig_notify can sleep - -The spinlock was used when brightness didn't support sleeping, but this -changed and now it supported with brightness_set_blocking(). - -Convert to mutex lock to permit sleeping using brightness_set_blocking(). - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230419210743.3594-6-ansuelsmth@gmail.com ---- - drivers/leds/trigger/ledtrig-netdev.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -20,7 +20,7 @@ - #include - #include - #include --#include -+#include - #include - #include "../leds.h" - -@@ -37,7 +37,7 @@ - */ - - struct led_netdev_data { -- spinlock_t lock; -+ struct mutex lock; - - struct delayed_work work; - struct notifier_block notifier; -@@ -97,9 +97,9 @@ static ssize_t device_name_show(struct d - struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); - ssize_t len; - -- spin_lock_bh(&trigger_data->lock); -+ mutex_lock(&trigger_data->lock); - len = sprintf(buf, "%s\n", trigger_data->device_name); -- spin_unlock_bh(&trigger_data->lock); -+ mutex_unlock(&trigger_data->lock); - - return len; - } -@@ -115,7 +115,7 @@ static ssize_t device_name_store(struct - - cancel_delayed_work_sync(&trigger_data->work); - -- spin_lock_bh(&trigger_data->lock); -+ mutex_lock(&trigger_data->lock); - - if (trigger_data->net_dev) { - dev_put(trigger_data->net_dev); -@@ -138,7 +138,7 @@ static ssize_t device_name_store(struct - trigger_data->last_activity = 0; - - set_baseline_state(trigger_data); -- spin_unlock_bh(&trigger_data->lock); -+ mutex_unlock(&trigger_data->lock); - - return size; - } -@@ -279,7 +279,7 @@ static int netdev_trig_notify(struct not - - cancel_delayed_work_sync(&trigger_data->work); - -- spin_lock_bh(&trigger_data->lock); -+ mutex_lock(&trigger_data->lock); - - trigger_data->carrier_link_up = false; - switch (evt) { -@@ -304,7 +304,7 @@ static int netdev_trig_notify(struct not - - set_baseline_state(trigger_data); - -- spin_unlock_bh(&trigger_data->lock); -+ mutex_unlock(&trigger_data->lock); - - return NOTIFY_DONE; - } -@@ -365,7 +365,7 @@ static int netdev_trig_activate(struct l - if (!trigger_data) - return -ENOMEM; - -- spin_lock_init(&trigger_data->lock); -+ mutex_init(&trigger_data->lock); - - trigger_data->notifier.notifier_call = netdev_trig_notify; - trigger_data->notifier.priority = 10; diff --git a/target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch b/target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch deleted file mode 100644 index ac186117338ff5..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-01-leds-add-APIs-for-LEDs-hw-control.patch +++ /dev/null @@ -1,74 +0,0 @@ -From ed554d3f945179c5b159bddfad7be34b403fe11a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:31 +0200 -Subject: [PATCH 01/13] leds: add APIs for LEDs hw control - -Add an option to permit LED driver to declare support for a specific -trigger to use hw control and setup the LED to blink based on specific -provided modes. - -Add APIs for LEDs hw control. These functions will be used to activate -hardware control where a LED will use the provided flags, from an -unique defined supported trigger, to setup the LED to be driven by -hardware. - -Add hw_control_is_supported() to ask the LED driver if the requested -mode by the trigger are supported and the LED can be setup to follow -the requested modes. - -Deactivate hardware blink control by setting brightness to LED_OFF via -the brightness_set() callback. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - include/linux/leds.h | 37 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -164,6 +164,43 @@ struct led_classdev { - - /* LEDs that have private triggers have this set */ - struct led_hw_trigger_type *trigger_type; -+ -+ /* Unique trigger name supported by LED set in hw control mode */ -+ const char *hw_control_trigger; -+ /* -+ * Check if the LED driver supports the requested mode provided by the -+ * defined supported trigger to setup the LED to hw control mode. -+ * -+ * Return 0 on success. Return -EOPNOTSUPP when the passed flags are not -+ * supported and software fallback needs to be used. -+ * Return a negative error number on any other case for check fail due -+ * to various reason like device not ready or timeouts. -+ */ -+ int (*hw_control_is_supported)(struct led_classdev *led_cdev, -+ unsigned long flags); -+ /* -+ * Activate hardware control, LED driver will use the provided flags -+ * from the supported trigger and setup the LED to be driven by hardware -+ * following the requested mode from the trigger flags. -+ * Deactivate hardware blink control by setting brightness to LED_OFF via -+ * the brightness_set() callback. -+ * -+ * Return 0 on success, a negative error number on flags apply fail. -+ */ -+ int (*hw_control_set)(struct led_classdev *led_cdev, -+ unsigned long flags); -+ /* -+ * Get from the LED driver the current mode that the LED is set in hw -+ * control mode and put them in flags. -+ * Trigger can use this to get the initial state of a LED already set in -+ * hardware blink control. -+ * -+ * Return 0 on success, a negative error number on failing parsing the -+ * initial mode. Error from this function is NOT FATAL as the device -+ * may be in a not supported initial state by the attached LED trigger. -+ */ -+ int (*hw_control_get)(struct led_classdev *led_cdev, -+ unsigned long *flags); - #endif - - #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED diff --git a/target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch b/target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch deleted file mode 100644 index 1a221727a01d7d..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-02-leds-add-API-to-get-attached-device-for-LED-hw-contr.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 052c38eb17e866c5b4cd43924e7a5e20167b55c0 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 29 May 2023 18:32:32 +0200 -Subject: [PATCH 02/13] leds: add API to get attached device for LED hw control - -Some specific LED triggers blink the LED based on events from a device -or subsystem. -For example, an LED could be blinked to indicate a network device is -receiving packets, or a disk is reading blocks. To correctly enable and -request the hw control of the LED, the trigger has to check if the -network interface or block device configured via a /sys/class/led file -match the one the LED driver provide for hw control for. - -Provide an API call to get the device which the LED blinks for. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - include/linux/leds.h | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -201,6 +201,12 @@ struct led_classdev { - */ - int (*hw_control_get)(struct led_classdev *led_cdev, - unsigned long *flags); -+ /* -+ * Get the device this LED blinks in response to. -+ * e.g. for a PHY LED, it is the network device. If the LED is -+ * not yet associated to a device, return NULL. -+ */ -+ struct device *(*hw_control_get_device)(struct led_classdev *led_cdev); - #endif - - #ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED diff --git a/target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch b/target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch deleted file mode 100644 index af9fb7fdc36526..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-03-Documentation-leds-leds-class-Document-new-Hardware-.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 8aa2fd7b66980ecd2e45e95af61cf7eafede1211 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:33 +0200 -Subject: [PATCH 03/13] Documentation: leds: leds-class: Document new Hardware - driven LEDs APIs - -Document new Hardware driven LEDs APIs. - -Some LEDs can be programmed to be driven by hardware. This is not -limited to blink but also to turn off or on autonomously. -To support this feature, a LED needs to implement various additional -ops and needs to declare specific support for the supported triggers. - -Add documentation for each required value and API to make hw control -possible and implementable by both LEDs and triggers. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - Documentation/leds/leds-class.rst | 81 +++++++++++++++++++++++++++++++ - 1 file changed, 81 insertions(+) - ---- a/Documentation/leds/leds-class.rst -+++ b/Documentation/leds/leds-class.rst -@@ -169,6 +169,87 @@ Setting the brightness to zero with brig - should completely turn off the LED and cancel the previously programmed - hardware blinking function, if any. - -+Hardware driven LEDs -+==================== -+ -+Some LEDs can be programmed to be driven by hardware. This is not -+limited to blink but also to turn off or on autonomously. -+To support this feature, a LED needs to implement various additional -+ops and needs to declare specific support for the supported triggers. -+ -+With hw control we refer to the LED driven by hardware. -+ -+LED driver must define the following value to support hw control: -+ -+ - hw_control_trigger: -+ unique trigger name supported by the LED in hw control -+ mode. -+ -+LED driver must implement the following API to support hw control: -+ - hw_control_is_supported: -+ check if the flags passed by the supported trigger can -+ be parsed and activate hw control on the LED. -+ -+ Return 0 if the passed flags mask is supported and -+ can be set with hw_control_set(). -+ -+ If the passed flags mask is not supported -EOPNOTSUPP -+ must be returned, the LED trigger will use software -+ fallback in this case. -+ -+ Return a negative error in case of any other error like -+ device not ready or timeouts. -+ -+ - hw_control_set: -+ activate hw control. LED driver will use the provided -+ flags passed from the supported trigger, parse them to -+ a set of mode and setup the LED to be driven by hardware -+ following the requested modes. -+ -+ Set LED_OFF via the brightness_set to deactivate hw control. -+ -+ Return 0 on success, a negative error number on failing to -+ apply flags. -+ -+ - hw_control_get: -+ get active modes from a LED already in hw control, parse -+ them and set in flags the current active flags for the -+ supported trigger. -+ -+ Return 0 on success, a negative error number on failing -+ parsing the initial mode. -+ Error from this function is NOT FATAL as the device may -+ be in a not supported initial state by the attached LED -+ trigger. -+ -+ - hw_control_get_device: -+ return the device associated with the LED driver in -+ hw control. A trigger might use this to match the -+ returned device from this function with a configured -+ device for the trigger as the source for blinking -+ events and correctly enable hw control. -+ (example a netdev trigger configured to blink for a -+ particular dev match the returned dev from get_device -+ to set hw control) -+ -+ Returns a pointer to a struct device or NULL if nothing -+ is currently attached. -+ -+LED driver can activate additional modes by default to workaround the -+impossibility of supporting each different mode on the supported trigger. -+Examples are hardcoding the blink speed to a set interval, enable special -+feature like bypassing blink if some requirements are not met. -+ -+A trigger should first check if the hw control API are supported by the LED -+driver and check if the trigger is supported to verify if hw control is possible, -+use hw_control_is_supported to check if the flags are supported and only at -+the end use hw_control_set to activate hw control. -+ -+A trigger can use hw_control_get to check if a LED is already in hw control -+and init their flags. -+ -+When the LED is in hw control, no software blink is possible and doing so -+will effectively disable hw control. - - Known Issues - ============ diff --git a/target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch b/target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch deleted file mode 100644 index 3c804c0b412e3c..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-04-leds-trigger-netdev-refactor-code-setting-device-nam.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 28a6a2ef18ad840a390d519840c303b03040961c Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 29 May 2023 18:32:34 +0200 -Subject: [PATCH 04/13] leds: trigger: netdev: refactor code setting device - name - -Move the code into a helper, ready for it to be called at -other times. No intended behaviour change. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 29 ++++++++++++++++++--------- - 1 file changed, 20 insertions(+), 9 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -104,15 +104,9 @@ static ssize_t device_name_show(struct d - return len; - } - --static ssize_t device_name_store(struct device *dev, -- struct device_attribute *attr, const char *buf, -- size_t size) -+static int set_device_name(struct led_netdev_data *trigger_data, -+ const char *name, size_t size) - { -- struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); -- -- if (size >= IFNAMSIZ) -- return -EINVAL; -- - cancel_delayed_work_sync(&trigger_data->work); - - mutex_lock(&trigger_data->lock); -@@ -122,7 +116,7 @@ static ssize_t device_name_store(struct - trigger_data->net_dev = NULL; - } - -- memcpy(trigger_data->device_name, buf, size); -+ memcpy(trigger_data->device_name, name, size); - trigger_data->device_name[size] = 0; - if (size > 0 && trigger_data->device_name[size - 1] == '\n') - trigger_data->device_name[size - 1] = 0; -@@ -140,6 +134,23 @@ static ssize_t device_name_store(struct - set_baseline_state(trigger_data); - mutex_unlock(&trigger_data->lock); - -+ return 0; -+} -+ -+static ssize_t device_name_store(struct device *dev, -+ struct device_attribute *attr, const char *buf, -+ size_t size) -+{ -+ struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); -+ int ret; -+ -+ if (size >= IFNAMSIZ) -+ return -EINVAL; -+ -+ ret = set_device_name(trigger_data, buf, size); -+ -+ if (ret < 0) -+ return ret; - return size; - } - diff --git a/target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch b/target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch deleted file mode 100644 index 284b519482cfed..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-05-leds-trigger-netdev-introduce-check-for-possible-hw-.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 4fd1b6d47a7a38e81fdc6f8be2ccd4216b3f93db Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:35 +0200 -Subject: [PATCH 05/13] leds: trigger: netdev: introduce check for possible hw - control - -Introduce function to check if the requested mode can use hw control in -preparation for hw control support. Currently everything is handled in -software so can_hw_control will always return false. - -Add knob with the new value hw_control in trigger_data struct to -set hw control possible. Useful for future implementation to implement -in set_baseline_state() the required function to set the requested mode -using LEDs hw control ops and in other function to reject set if hw -control is currently active. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -51,6 +51,7 @@ struct led_netdev_data { - - unsigned long mode; - bool carrier_link_up; -+ bool hw_control; - }; - - enum led_trigger_netdev_modes { -@@ -91,6 +92,11 @@ static void set_baseline_state(struct le - } - } - -+static bool can_hw_control(struct led_netdev_data *trigger_data) -+{ -+ return false; -+} -+ - static ssize_t device_name_show(struct device *dev, - struct device_attribute *attr, char *buf) - { -@@ -204,6 +210,8 @@ static ssize_t netdev_led_attr_store(str - else - clear_bit(bit, &trigger_data->mode); - -+ trigger_data->hw_control = can_hw_control(trigger_data); -+ - set_baseline_state(trigger_data); - - return size; diff --git a/target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch b/target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch deleted file mode 100644 index 09759bc623e9c0..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-06-leds-trigger-netdev-add-basic-check-for-hw-control-s.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6352f25f9fadba59d5df2ba7139495759ccc81d5 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:36 +0200 -Subject: [PATCH 06/13] leds: trigger: netdev: add basic check for hw control - support - -Add basic check for hw control support. Check if the required API are -defined and check if the defined trigger supported in hw control for the -LED driver match netdev. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -92,8 +92,22 @@ static void set_baseline_state(struct le - } - } - -+static bool supports_hw_control(struct led_classdev *led_cdev) -+{ -+ if (!led_cdev->hw_control_get || !led_cdev->hw_control_set || -+ !led_cdev->hw_control_is_supported) -+ return false; -+ -+ return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name); -+} -+ - static bool can_hw_control(struct led_netdev_data *trigger_data) - { -+ struct led_classdev *led_cdev = trigger_data->led_cdev; -+ -+ if (!supports_hw_control(led_cdev)) -+ return false; -+ - return false; - } - diff --git a/target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch b/target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch deleted file mode 100644 index 66349068003149..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-07-leds-trigger-netdev-reject-interval-store-for-hw_con.patch +++ /dev/null @@ -1,28 +0,0 @@ -From c84c80c7388f887b10dafd70fc55bc6c5fe9fa5a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:37 +0200 -Subject: [PATCH 07/13] leds: trigger: netdev: reject interval store for - hw_control - -Reject interval store with hw_control enabled. It's are currently not -supported and MUST be set to the default value with hw control enabled. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -265,6 +265,9 @@ static ssize_t interval_store(struct dev - unsigned long value; - int ret; - -+ if (trigger_data->hw_control) -+ return -EINVAL; -+ - ret = kstrtoul(buf, 0, &value); - if (ret) - return ret; diff --git a/target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch b/target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch deleted file mode 100644 index 52faa4809b2ae0..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-08-leds-trigger-netdev-add-support-for-LED-hw-control.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 7c145a34ba6e380616af93262fcab9fc7261d851 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:38 +0200 -Subject: [PATCH 08/13] leds: trigger: netdev: add support for LED hw control - -Add support for LED hw control for the netdev trigger. - -The trigger on calling set_baseline_state to configure a new mode, will -do various check to verify if hw control can be used for the requested -mode in can_hw_control() function. - -It will first check if the LED driver supports hw control for the netdev -trigger, then will use hw_control_is_supported() and finally will call -hw_control_set() to apply the requested mode. - -To use such mode, interval MUST be set to the default value and net_dev -MUST be set. If one of these 2 value are not valid, hw control will -never be used and normal software fallback is used. - -The default interval value is moved to a define to make sure they are -always synced. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 43 +++++++++++++++++++++++++-- - 1 file changed, 41 insertions(+), 2 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -24,6 +24,8 @@ - #include - #include "../leds.h" - -+#define NETDEV_LED_DEFAULT_INTERVAL 50 -+ - /* - * Configurable sysfs attributes: - * -@@ -68,6 +70,13 @@ static void set_baseline_state(struct le - int current_brightness; - struct led_classdev *led_cdev = trigger_data->led_cdev; - -+ /* Already validated, hw control is possible with the requested mode */ -+ if (trigger_data->hw_control) { -+ led_cdev->hw_control_set(led_cdev, trigger_data->mode); -+ -+ return; -+ } -+ - current_brightness = led_cdev->brightness; - if (current_brightness) - led_cdev->blink_brightness = current_brightness; -@@ -103,12 +112,42 @@ static bool supports_hw_control(struct l - - static bool can_hw_control(struct led_netdev_data *trigger_data) - { -+ unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL); -+ unsigned int interval = atomic_read(&trigger_data->interval); - struct led_classdev *led_cdev = trigger_data->led_cdev; -+ int ret; - - if (!supports_hw_control(led_cdev)) - return false; - -- return false; -+ /* -+ * Interval must be set to the default -+ * value. Any different value is rejected if in hw -+ * control. -+ */ -+ if (interval != default_interval) -+ return false; -+ -+ /* -+ * net_dev must be set with hw control, otherwise no -+ * blinking can be happening and there is nothing to -+ * offloaded. -+ */ -+ if (!trigger_data->net_dev) -+ return false; -+ -+ /* Check if the requested mode is supported */ -+ ret = led_cdev->hw_control_is_supported(led_cdev, trigger_data->mode); -+ /* Fall back to software blinking if not supported */ -+ if (ret == -EOPNOTSUPP) -+ return false; -+ if (ret) { -+ dev_warn(led_cdev->dev, -+ "Current mode check failed with error %d\n", ret); -+ return false; -+ } -+ -+ return true; - } - - static ssize_t device_name_show(struct device *dev, -@@ -413,7 +452,7 @@ static int netdev_trig_activate(struct l - trigger_data->device_name[0] = 0; - - trigger_data->mode = 0; -- atomic_set(&trigger_data->interval, msecs_to_jiffies(50)); -+ atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL)); - trigger_data->last_activity = 0; - - led_set_trigger_data(led_cdev, trigger_data); diff --git a/target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch b/target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch deleted file mode 100644 index c129ffa4f5944c..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-09-leds-trigger-netdev-validate-configured-netdev.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 33ec0b53befff2c0a7f3aa19ff08556d60585d6b Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 29 May 2023 18:32:39 +0200 -Subject: [PATCH 09/13] leds: trigger: netdev: validate configured netdev - -The netdev which the LED should blink for is configurable in -/sys/class/led/foo/device_name. Ensure when offloading that the -configured netdev is the same as the netdev the LED is associated -with. If it is not, only perform software blinking. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 24 ++++++++++++++++++++++-- - 1 file changed, 22 insertions(+), 2 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -110,6 +110,24 @@ static bool supports_hw_control(struct l - return !strcmp(led_cdev->hw_control_trigger, led_cdev->trigger->name); - } - -+/* -+ * Validate the configured netdev is the same as the one associated with -+ * the LED driver in hw control. -+ */ -+static bool validate_net_dev(struct led_classdev *led_cdev, -+ struct net_device *net_dev) -+{ -+ struct device *dev = led_cdev->hw_control_get_device(led_cdev); -+ struct net_device *ndev; -+ -+ if (!dev) -+ return false; -+ -+ ndev = to_net_dev(dev); -+ -+ return ndev == net_dev; -+} -+ - static bool can_hw_control(struct led_netdev_data *trigger_data) - { - unsigned long default_interval = msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL); -@@ -131,9 +149,11 @@ static bool can_hw_control(struct led_ne - /* - * net_dev must be set with hw control, otherwise no - * blinking can be happening and there is nothing to -- * offloaded. -+ * offloaded. Additionally, for hw control to be -+ * valid, the configured netdev must be the same as -+ * netdev associated to the LED. - */ -- if (!trigger_data->net_dev) -+ if (!validate_net_dev(led_cdev, trigger_data->net_dev)) - return false; - - /* Check if the requested mode is supported */ diff --git a/target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch b/target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch deleted file mode 100644 index e20594c99a3eaa..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-10-leds-trigger-netdev-init-mode-if-hw-control-already-.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0316cc5629d15880dd3f097d221c55ca648bcd61 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:40 +0200 -Subject: [PATCH 10/13] leds: trigger: netdev: init mode if hw control already - active - -On netdev trigger activation, hw control may be already active by -default. If this is the case and a device is actually provided by -hw_control_get_device(), init the already active mode and set the -bool to hw_control bool to true to reflect the already set mode in the -trigger_data. - -Co-developed-by: Andrew Lunn -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -454,6 +454,8 @@ static void netdev_trig_work(struct work - static int netdev_trig_activate(struct led_classdev *led_cdev) - { - struct led_netdev_data *trigger_data; -+ unsigned long mode; -+ struct device *dev; - int rc; - - trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); -@@ -475,6 +477,21 @@ static int netdev_trig_activate(struct l - atomic_set(&trigger_data->interval, msecs_to_jiffies(NETDEV_LED_DEFAULT_INTERVAL)); - trigger_data->last_activity = 0; - -+ /* Check if hw control is active by default on the LED. -+ * Init already enabled mode in hw control. -+ */ -+ if (supports_hw_control(led_cdev) && -+ !led_cdev->hw_control_get(led_cdev, &mode)) { -+ dev = led_cdev->hw_control_get_device(led_cdev); -+ if (dev) { -+ const char *name = dev_name(dev); -+ -+ set_device_name(trigger_data, name, strlen(name)); -+ trigger_data->hw_control = true; -+ trigger_data->mode = mode; -+ } -+ } -+ - led_set_trigger_data(led_cdev, trigger_data); - - rc = register_netdevice_notifier(&trigger_data->notifier); diff --git a/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch b/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch deleted file mode 100644 index f23504b1d03256..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-11-leds-trigger-netdev-expose-netdev-trigger-modes-in-l.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 947acacab5ea151291b861cdfbde16ff5cf1b08c Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:41 +0200 -Subject: [PATCH 11/13] leds: trigger: netdev: expose netdev trigger modes in - linux include - -Expose netdev trigger modes to make them accessible by LED driver that -will support netdev trigger for hw control. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 9 --------- - include/linux/leds.h | 10 ++++++++++ - 2 files changed, 10 insertions(+), 9 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -56,15 +56,6 @@ struct led_netdev_data { - bool hw_control; - }; - --enum led_trigger_netdev_modes { -- TRIGGER_NETDEV_LINK = 0, -- TRIGGER_NETDEV_TX, -- TRIGGER_NETDEV_RX, -- -- /* Keep last */ -- __TRIGGER_NETDEV_MAX, --}; -- - static void set_baseline_state(struct led_netdev_data *trigger_data) - { - int current_brightness; ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -525,6 +525,16 @@ led_trigger_get_brightness(const struct - - #endif /* CONFIG_LEDS_TRIGGERS */ - -+/* Trigger specific enum */ -+enum led_trigger_netdev_modes { -+ TRIGGER_NETDEV_LINK = 0, -+ TRIGGER_NETDEV_TX, -+ TRIGGER_NETDEV_RX, -+ -+ /* Keep last */ -+ __TRIGGER_NETDEV_MAX, -+}; -+ - /* Trigger specific functions */ - #ifdef CONFIG_LEDS_TRIGGER_DISK - void ledtrig_disk_activity(bool write); diff --git a/target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch b/target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch deleted file mode 100644 index ad76d89b7bf842..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-12-net-dsa-qca8k-implement-hw_control-ops.patch +++ /dev/null @@ -1,200 +0,0 @@ -From e0256648c831af13cbfe4a1787327fcec01c2807 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 29 May 2023 18:32:42 +0200 -Subject: [PATCH 12/13] net: dsa: qca8k: implement hw_control ops - -Implement hw_control ops to drive Switch LEDs based on hardware events. - -Netdev trigger is the declared supported trigger for hw control -operation and supports the following mode: -- tx -- rx - -When hw_control_set is called, LEDs are set to follow the requested -mode. -Each LEDs will blink at 4Hz by default. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-leds.c | 154 +++++++++++++++++++++++++++++++ - 1 file changed, 154 insertions(+) - ---- a/drivers/net/dsa/qca/qca8k-leds.c -+++ b/drivers/net/dsa/qca/qca8k-leds.c -@@ -32,6 +32,43 @@ qca8k_get_enable_led_reg(int port_num, i - } - - static int -+qca8k_get_control_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) -+{ -+ reg_info->reg = QCA8K_LED_CTRL_REG(led_num); -+ -+ /* 6 total control rule: -+ * 3 control rules for phy0-3 that applies to all their leds -+ * 3 control rules for phy4 -+ */ -+ if (port_num == 4) -+ reg_info->shift = QCA8K_LED_PHY4_CONTROL_RULE_SHIFT; -+ else -+ reg_info->shift = QCA8K_LED_PHY0123_CONTROL_RULE_SHIFT; -+ -+ return 0; -+} -+ -+static int -+qca8k_parse_netdev(unsigned long rules, u32 *offload_trigger) -+{ -+ /* Parsing specific to netdev trigger */ -+ if (test_bit(TRIGGER_NETDEV_TX, &rules)) -+ *offload_trigger |= QCA8K_LED_TX_BLINK_MASK; -+ if (test_bit(TRIGGER_NETDEV_RX, &rules)) -+ *offload_trigger |= QCA8K_LED_RX_BLINK_MASK; -+ -+ if (rules && !*offload_trigger) -+ return -EOPNOTSUPP; -+ -+ /* Enable some default rule by default to the requested mode: -+ * - Blink at 4Hz by default -+ */ -+ *offload_trigger |= QCA8K_LED_BLINK_4HZ; -+ -+ return 0; -+} -+ -+static int - qca8k_led_brightness_set(struct qca8k_led *led, - enum led_brightness brightness) - { -@@ -165,6 +202,119 @@ qca8k_cled_blink_set(struct led_classdev - } - - static int -+qca8k_cled_trigger_offload(struct led_classdev *ldev, bool enable) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 mask, val = QCA8K_LED_ALWAYS_OFF; -+ -+ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); -+ -+ if (enable) -+ val = QCA8K_LED_RULE_CONTROLLED; -+ -+ if (led->port_num == 0 || led->port_num == 4) { -+ mask = QCA8K_LED_PATTERN_EN_MASK; -+ val <<= QCA8K_LED_PATTERN_EN_SHIFT; -+ } else { -+ mask = QCA8K_LED_PHY123_PATTERN_EN_MASK; -+ } -+ -+ return regmap_update_bits(priv->regmap, reg_info.reg, mask << reg_info.shift, -+ val << reg_info.shift); -+} -+ -+static bool -+qca8k_cled_hw_control_status(struct led_classdev *ldev) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 val; -+ -+ qca8k_get_enable_led_reg(led->port_num, led->led_num, ®_info); -+ -+ regmap_read(priv->regmap, reg_info.reg, &val); -+ -+ val >>= reg_info.shift; -+ -+ if (led->port_num == 0 || led->port_num == 4) { -+ val &= QCA8K_LED_PATTERN_EN_MASK; -+ val >>= QCA8K_LED_PATTERN_EN_SHIFT; -+ } else { -+ val &= QCA8K_LED_PHY123_PATTERN_EN_MASK; -+ } -+ -+ return val == QCA8K_LED_RULE_CONTROLLED; -+} -+ -+static int -+qca8k_cled_hw_control_is_supported(struct led_classdev *ldev, unsigned long rules) -+{ -+ u32 offload_trigger = 0; -+ -+ return qca8k_parse_netdev(rules, &offload_trigger); -+} -+ -+static int -+qca8k_cled_hw_control_set(struct led_classdev *ldev, unsigned long rules) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 offload_trigger = 0; -+ int ret; -+ -+ ret = qca8k_parse_netdev(rules, &offload_trigger); -+ if (ret) -+ return ret; -+ -+ ret = qca8k_cled_trigger_offload(ldev, true); -+ if (ret) -+ return ret; -+ -+ qca8k_get_control_led_reg(led->port_num, led->led_num, ®_info); -+ -+ return regmap_update_bits(priv->regmap, reg_info.reg, -+ QCA8K_LED_RULE_MASK << reg_info.shift, -+ offload_trigger << reg_info.shift); -+} -+ -+static int -+qca8k_cled_hw_control_get(struct led_classdev *ldev, unsigned long *rules) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ struct qca8k_led_pattern_en reg_info; -+ struct qca8k_priv *priv = led->priv; -+ u32 val; -+ int ret; -+ -+ /* With hw control not active return err */ -+ if (!qca8k_cled_hw_control_status(ldev)) -+ return -EINVAL; -+ -+ qca8k_get_control_led_reg(led->port_num, led->led_num, ®_info); -+ -+ ret = regmap_read(priv->regmap, reg_info.reg, &val); -+ if (ret) -+ return ret; -+ -+ val >>= reg_info.shift; -+ val &= QCA8K_LED_RULE_MASK; -+ -+ /* Parsing specific to netdev trigger */ -+ if (val & QCA8K_LED_TX_BLINK_MASK) -+ set_bit(TRIGGER_NETDEV_TX, rules); -+ if (val & QCA8K_LED_RX_BLINK_MASK) -+ set_bit(TRIGGER_NETDEV_RX, rules); -+ -+ return 0; -+} -+ -+static int - qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) - { - struct fwnode_handle *led = NULL, *leds = NULL; -@@ -224,6 +374,10 @@ qca8k_parse_port_leds(struct qca8k_priv - port_led->cdev.max_brightness = 1; - port_led->cdev.brightness_set_blocking = qca8k_cled_brightness_set_blocking; - port_led->cdev.blink_set = qca8k_cled_blink_set; -+ port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported; -+ port_led->cdev.hw_control_set = qca8k_cled_hw_control_set; -+ port_led->cdev.hw_control_get = qca8k_cled_hw_control_get; -+ port_led->cdev.hw_control_trigger = "netdev"; - init_data.default_label = ":port"; - init_data.fwnode = led; - init_data.devname_mandatory = true; diff --git a/target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch b/target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch deleted file mode 100644 index feb6b9e1e4e8e4..00000000000000 --- a/target/linux/generic/backport-6.1/804-v6.5-13-net-dsa-qca8k-add-op-to-get-ports-netdev.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 4f53c27f772e27e4cf4e5507d6f4d5980002cb6a Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Mon, 29 May 2023 18:32:43 +0200 -Subject: [PATCH 13/13] net: dsa: qca8k: add op to get ports netdev - -In order that the LED trigger can blink the switch MAC ports LED, it -needs to know the netdev associated to the port. Add the callback to -return the struct device of the netdev. - -Add an helper function qca8k_phy_to_port() to convert the phy back to -dsa_port index, as we reference LED port based on the internal PHY -index and needs to be converted back. - -Signed-off-by: Andrew Lunn -Signed-off-by: Christian Marangi -Signed-off-by: David S. Miller ---- - drivers/net/dsa/qca/qca8k-leds.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - ---- a/drivers/net/dsa/qca/qca8k-leds.c -+++ b/drivers/net/dsa/qca/qca8k-leds.c -@@ -5,6 +5,18 @@ - #include "qca8k.h" - #include "qca8k_leds.h" - -+static u32 qca8k_phy_to_port(int phy) -+{ -+ /* Internal PHY 0 has port at index 1. -+ * Internal PHY 1 has port at index 2. -+ * Internal PHY 2 has port at index 3. -+ * Internal PHY 3 has port at index 4. -+ * Internal PHY 4 has port at index 5. -+ */ -+ -+ return phy + 1; -+} -+ - static int - qca8k_get_enable_led_reg(int port_num, int led_num, struct qca8k_led_pattern_en *reg_info) - { -@@ -314,6 +326,20 @@ qca8k_cled_hw_control_get(struct led_cla - return 0; - } - -+static struct device *qca8k_cled_hw_control_get_device(struct led_classdev *ldev) -+{ -+ struct qca8k_led *led = container_of(ldev, struct qca8k_led, cdev); -+ struct qca8k_priv *priv = led->priv; -+ struct dsa_port *dp; -+ -+ dp = dsa_to_port(priv->ds, qca8k_phy_to_port(led->port_num)); -+ if (!dp) -+ return NULL; -+ if (dp->slave) -+ return &dp->slave->dev; -+ return NULL; -+} -+ - static int - qca8k_parse_port_leds(struct qca8k_priv *priv, struct fwnode_handle *port, int port_num) - { -@@ -377,6 +403,7 @@ qca8k_parse_port_leds(struct qca8k_priv - port_led->cdev.hw_control_is_supported = qca8k_cled_hw_control_is_supported; - port_led->cdev.hw_control_set = qca8k_cled_hw_control_set; - port_led->cdev.hw_control_get = qca8k_cled_hw_control_get; -+ port_led->cdev.hw_control_get_device = qca8k_cled_hw_control_get_device; - port_led->cdev.hw_control_trigger = "netdev"; - init_data.default_label = ":port"; - init_data.fwnode = led; diff --git a/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch b/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch deleted file mode 100644 index 38989a2a631696..00000000000000 --- a/target/linux/generic/backport-6.1/805-v6.5-01-leds-trigger-netdev-add-additional-specific-link-spe.patch +++ /dev/null @@ -1,242 +0,0 @@ -From d5e01266e7f5fa12400d4c8aa4e86fe89dcc61e9 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 19 Jun 2023 22:46:58 +0200 -Subject: [PATCH 1/3] leds: trigger: netdev: add additional specific link speed - mode - -Add additional modes for specific link speed. Use ethtool APIs to get the -current link speed and enable the LED accordingly. Under netdev event -handler the rtnl lock is already held and is not needed to be set to -access ethtool APIs. - -This is especially useful for PHY and Switch that supports LEDs hw -control for specific link speed. (example scenario a PHY that have 2 LED -connected one green and one orange where the green is turned on with -1000mbps speed and orange is turned on with 10mpbs speed) - -On mode set from sysfs we check if we have enabled split link speed mode -and reject enabling generic link mode to prevent wrong and redundant -configuration. - -Rework logic on the set baseline state to support these new modes to -select if we need to turn on or off the LED. - -Add additional modes: -- link_10: Turn on LED when link speed is 10mbps -- link_100: Turn on LED when link speed is 100mbps -- link_1000: Turn on LED when link speed is 1000mbps - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Acked-by: Lee Jones -Signed-off-by: Jakub Kicinski ---- - drivers/leds/trigger/ledtrig-netdev.c | 80 +++++++++++++++++++++++---- - include/linux/leds.h | 3 + - 2 files changed, 73 insertions(+), 10 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -21,6 +22,7 @@ - #include - #include - #include -+#include - #include - #include "../leds.h" - -@@ -52,6 +54,8 @@ struct led_netdev_data { - unsigned int last_activity; - - unsigned long mode; -+ int link_speed; -+ - bool carrier_link_up; - bool hw_control; - }; -@@ -77,7 +81,24 @@ static void set_baseline_state(struct le - if (!trigger_data->carrier_link_up) { - led_set_brightness(led_cdev, LED_OFF); - } else { -+ bool blink_on = false; -+ - if (test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode)) -+ blink_on = true; -+ -+ if (test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) && -+ trigger_data->link_speed == SPEED_10) -+ blink_on = true; -+ -+ if (test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) && -+ trigger_data->link_speed == SPEED_100) -+ blink_on = true; -+ -+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) && -+ trigger_data->link_speed == SPEED_1000) -+ blink_on = true; -+ -+ if (blink_on) - led_set_brightness(led_cdev, - led_cdev->blink_brightness); - else -@@ -161,6 +182,18 @@ static bool can_hw_control(struct led_ne - return true; - } - -+static void get_device_state(struct led_netdev_data *trigger_data) -+{ -+ struct ethtool_link_ksettings cmd; -+ -+ trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev); -+ if (!trigger_data->carrier_link_up) -+ return; -+ -+ if (!__ethtool_get_link_ksettings(trigger_data->net_dev, &cmd)) -+ trigger_data->link_speed = cmd.base.speed; -+} -+ - static ssize_t device_name_show(struct device *dev, - struct device_attribute *attr, char *buf) - { -@@ -196,8 +229,12 @@ static int set_device_name(struct led_ne - dev_get_by_name(&init_net, trigger_data->device_name); - - trigger_data->carrier_link_up = false; -- if (trigger_data->net_dev != NULL) -- trigger_data->carrier_link_up = netif_carrier_ok(trigger_data->net_dev); -+ trigger_data->link_speed = SPEED_UNKNOWN; -+ if (trigger_data->net_dev != NULL) { -+ rtnl_lock(); -+ get_device_state(trigger_data); -+ rtnl_unlock(); -+ } - - trigger_data->last_activity = 0; - -@@ -234,6 +271,9 @@ static ssize_t netdev_led_attr_show(stru - - switch (attr) { - case TRIGGER_NETDEV_LINK: -+ case TRIGGER_NETDEV_LINK_10: -+ case TRIGGER_NETDEV_LINK_100: -+ case TRIGGER_NETDEV_LINK_1000: - case TRIGGER_NETDEV_TX: - case TRIGGER_NETDEV_RX: - bit = attr; -@@ -249,7 +289,7 @@ static ssize_t netdev_led_attr_store(str - size_t size, enum led_trigger_netdev_modes attr) - { - struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); -- unsigned long state; -+ unsigned long state, mode = trigger_data->mode; - int ret; - int bit; - -@@ -259,6 +299,9 @@ static ssize_t netdev_led_attr_store(str - - switch (attr) { - case TRIGGER_NETDEV_LINK: -+ case TRIGGER_NETDEV_LINK_10: -+ case TRIGGER_NETDEV_LINK_100: -+ case TRIGGER_NETDEV_LINK_1000: - case TRIGGER_NETDEV_TX: - case TRIGGER_NETDEV_RX: - bit = attr; -@@ -267,13 +310,20 @@ static ssize_t netdev_led_attr_store(str - return -EINVAL; - } - -- cancel_delayed_work_sync(&trigger_data->work); -- - if (state) -- set_bit(bit, &trigger_data->mode); -+ set_bit(bit, &mode); - else -- clear_bit(bit, &trigger_data->mode); -+ clear_bit(bit, &mode); -+ -+ if (test_bit(TRIGGER_NETDEV_LINK, &mode) && -+ (test_bit(TRIGGER_NETDEV_LINK_10, &mode) || -+ test_bit(TRIGGER_NETDEV_LINK_100, &mode) || -+ test_bit(TRIGGER_NETDEV_LINK_1000, &mode))) -+ return -EINVAL; -+ -+ cancel_delayed_work_sync(&trigger_data->work); - -+ trigger_data->mode = mode; - trigger_data->hw_control = can_hw_control(trigger_data); - - set_baseline_state(trigger_data); -@@ -295,6 +345,9 @@ static ssize_t netdev_led_attr_store(str - static DEVICE_ATTR_RW(trigger_name) - - DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETDEV_LINK); -+DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10); -+DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100); -+DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000); - DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); - DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); - -@@ -338,6 +391,9 @@ static DEVICE_ATTR_RW(interval); - static struct attribute *netdev_trig_attrs[] = { - &dev_attr_device_name.attr, - &dev_attr_link.attr, -+ &dev_attr_link_10.attr, -+ &dev_attr_link_100.attr, -+ &dev_attr_link_1000.attr, - &dev_attr_rx.attr, - &dev_attr_tx.attr, - &dev_attr_interval.attr, -@@ -368,9 +424,10 @@ static int netdev_trig_notify(struct not - mutex_lock(&trigger_data->lock); - - trigger_data->carrier_link_up = false; -+ trigger_data->link_speed = SPEED_UNKNOWN; - switch (evt) { - case NETDEV_CHANGENAME: -- trigger_data->carrier_link_up = netif_carrier_ok(dev); -+ get_device_state(trigger_data); - fallthrough; - case NETDEV_REGISTER: - if (trigger_data->net_dev) -@@ -384,7 +441,7 @@ static int netdev_trig_notify(struct not - break; - case NETDEV_UP: - case NETDEV_CHANGE: -- trigger_data->carrier_link_up = netif_carrier_ok(dev); -+ get_device_state(trigger_data); - break; - } - -@@ -427,7 +484,10 @@ static void netdev_trig_work(struct work - if (trigger_data->last_activity != new_activity) { - led_stop_software_blink(trigger_data->led_cdev); - -- invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode); -+ invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode) || -+ test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) || -+ test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) || -+ test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode); - interval = jiffies_to_msecs( - atomic_read(&trigger_data->interval)); - /* base state is ON (link present) */ ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -528,6 +528,9 @@ led_trigger_get_brightness(const struct - /* Trigger specific enum */ - enum led_trigger_netdev_modes { - TRIGGER_NETDEV_LINK = 0, -+ TRIGGER_NETDEV_LINK_10, -+ TRIGGER_NETDEV_LINK_100, -+ TRIGGER_NETDEV_LINK_1000, - TRIGGER_NETDEV_TX, - TRIGGER_NETDEV_RX, - diff --git a/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch b/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch deleted file mode 100644 index 90213269914247..00000000000000 --- a/target/linux/generic/backport-6.1/805-v6.5-02-leds-trigger-netdev-add-additional-specific-link-dup.patch +++ /dev/null @@ -1,138 +0,0 @@ -From f22f95b9ff1551c9bab13104131929f33d51f23f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 19 Jun 2023 22:46:59 +0200 -Subject: [PATCH 2/3] leds: trigger: netdev: add additional specific link - duplex mode - -Add additional modes for specific link duplex. Use ethtool APIs to get the -current link duplex and enable the LED accordingly. Under netdev event -handler the rtnl lock is already held and is not needed to be set to -access ethtool APIs. - -This is especially useful for PHY and Switch that supports LEDs hw -control for specific link duplex. - -Add additional modes: -- half_duplex: Turn on LED when link is half duplex -- full_duplex: Turn on LED when link is full duplex - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Acked-by: Lee Jones -Signed-off-by: Jakub Kicinski ---- - drivers/leds/trigger/ledtrig-netdev.c | 27 +++++++++++++++++++++++++-- - include/linux/leds.h | 2 ++ - 2 files changed, 27 insertions(+), 2 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -55,6 +55,7 @@ struct led_netdev_data { - - unsigned long mode; - int link_speed; -+ u8 duplex; - - bool carrier_link_up; - bool hw_control; -@@ -98,6 +99,14 @@ static void set_baseline_state(struct le - trigger_data->link_speed == SPEED_1000) - blink_on = true; - -+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) && -+ trigger_data->duplex == DUPLEX_HALF) -+ blink_on = true; -+ -+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode) && -+ trigger_data->duplex == DUPLEX_FULL) -+ blink_on = true; -+ - if (blink_on) - led_set_brightness(led_cdev, - led_cdev->blink_brightness); -@@ -190,8 +199,10 @@ static void get_device_state(struct led_ - if (!trigger_data->carrier_link_up) - return; - -- if (!__ethtool_get_link_ksettings(trigger_data->net_dev, &cmd)) -+ if (!__ethtool_get_link_ksettings(trigger_data->net_dev, &cmd)) { - trigger_data->link_speed = cmd.base.speed; -+ trigger_data->duplex = cmd.base.duplex; -+ } - } - - static ssize_t device_name_show(struct device *dev, -@@ -230,6 +241,7 @@ static int set_device_name(struct led_ne - - trigger_data->carrier_link_up = false; - trigger_data->link_speed = SPEED_UNKNOWN; -+ trigger_data->duplex = DUPLEX_UNKNOWN; - if (trigger_data->net_dev != NULL) { - rtnl_lock(); - get_device_state(trigger_data); -@@ -274,6 +286,8 @@ static ssize_t netdev_led_attr_show(stru - case TRIGGER_NETDEV_LINK_10: - case TRIGGER_NETDEV_LINK_100: - case TRIGGER_NETDEV_LINK_1000: -+ case TRIGGER_NETDEV_HALF_DUPLEX: -+ case TRIGGER_NETDEV_FULL_DUPLEX: - case TRIGGER_NETDEV_TX: - case TRIGGER_NETDEV_RX: - bit = attr; -@@ -302,6 +316,8 @@ static ssize_t netdev_led_attr_store(str - case TRIGGER_NETDEV_LINK_10: - case TRIGGER_NETDEV_LINK_100: - case TRIGGER_NETDEV_LINK_1000: -+ case TRIGGER_NETDEV_HALF_DUPLEX: -+ case TRIGGER_NETDEV_FULL_DUPLEX: - case TRIGGER_NETDEV_TX: - case TRIGGER_NETDEV_RX: - bit = attr; -@@ -348,6 +364,8 @@ DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETD - DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10); - DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100); - DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000); -+DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX); -+DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX); - DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); - DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); - -@@ -394,6 +412,8 @@ static struct attribute *netdev_trig_att - &dev_attr_link_10.attr, - &dev_attr_link_100.attr, - &dev_attr_link_1000.attr, -+ &dev_attr_full_duplex.attr, -+ &dev_attr_half_duplex.attr, - &dev_attr_rx.attr, - &dev_attr_tx.attr, - &dev_attr_interval.attr, -@@ -425,6 +445,7 @@ static int netdev_trig_notify(struct not - - trigger_data->carrier_link_up = false; - trigger_data->link_speed = SPEED_UNKNOWN; -+ trigger_data->duplex = DUPLEX_UNKNOWN; - switch (evt) { - case NETDEV_CHANGENAME: - get_device_state(trigger_data); -@@ -487,7 +508,9 @@ static void netdev_trig_work(struct work - invert = test_bit(TRIGGER_NETDEV_LINK, &trigger_data->mode) || - test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) || - test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) || -- test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode); -+ test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) || -+ test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) || -+ test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode); - interval = jiffies_to_msecs( - atomic_read(&trigger_data->interval)); - /* base state is ON (link present) */ ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -531,6 +531,8 @@ enum led_trigger_netdev_modes { - TRIGGER_NETDEV_LINK_10, - TRIGGER_NETDEV_LINK_100, - TRIGGER_NETDEV_LINK_1000, -+ TRIGGER_NETDEV_HALF_DUPLEX, -+ TRIGGER_NETDEV_FULL_DUPLEX, - TRIGGER_NETDEV_TX, - TRIGGER_NETDEV_RX, - diff --git a/target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch b/target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch deleted file mode 100644 index 67528cafe095a9..00000000000000 --- a/target/linux/generic/backport-6.1/805-v6.5-03-leds-trigger-netdev-expose-hw_control-status-via-sys.patch +++ /dev/null @@ -1,45 +0,0 @@ -From b655892ffd6d89b0c7407e099c40dbde82ee3f03 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Mon, 19 Jun 2023 22:47:00 +0200 -Subject: [PATCH 3/3] leds: trigger: netdev: expose hw_control status via sysfs - -Expose hw_control status via sysfs for the netdev trigger to give -userspace better understanding of the current state of the trigger and -the LED. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Reviewed-by: Kalesh AP -Acked-by: Lee Jones -Signed-off-by: Jakub Kicinski ---- - drivers/leds/trigger/ledtrig-netdev.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -406,6 +406,16 @@ static ssize_t interval_store(struct dev - - static DEVICE_ATTR_RW(interval); - -+static ssize_t hw_control_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); -+ -+ return sprintf(buf, "%d\n", trigger_data->hw_control); -+} -+ -+static DEVICE_ATTR_RO(hw_control); -+ - static struct attribute *netdev_trig_attrs[] = { - &dev_attr_device_name.attr, - &dev_attr_link.attr, -@@ -417,6 +427,7 @@ static struct attribute *netdev_trig_att - &dev_attr_rx.attr, - &dev_attr_tx.attr, - &dev_attr_interval.attr, -+ &dev_attr_hw_control.attr, - NULL - }; - ATTRIBUTE_GROUPS(netdev_trig); diff --git a/target/linux/generic/backport-6.1/806-v6.5-net-dsa-qca8k-add-support-for-additional-modes-for-n.patch b/target/linux/generic/backport-6.1/806-v6.5-net-dsa-qca8k-add-support-for-additional-modes-for-n.patch deleted file mode 100644 index ac322e19390afb..00000000000000 --- a/target/linux/generic/backport-6.1/806-v6.5-net-dsa-qca8k-add-support-for-additional-modes-for-n.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 2555f35a4f428a9bfdf09aa0459dbfdf59a24a9a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 21 Jun 2023 11:54:09 +0200 -Subject: [PATCH] net: dsa: qca8k: add support for additional modes for netdev - trigger - -The QCA8K switch supports additional modes that can be handled in -hardware for the LED netdev trigger. - -Add these additional modes to further support the Switch LEDs and -offload more blink modes. - -Add additional modes: -- link_10 -- link_100 -- link_1000 -- half_duplex -- full_duplex - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Link: https://lore.kernel.org/r/20230621095409.25859-1-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/qca/qca8k-leds.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - ---- a/drivers/net/dsa/qca/qca8k-leds.c -+++ b/drivers/net/dsa/qca/qca8k-leds.c -@@ -68,6 +68,16 @@ qca8k_parse_netdev(unsigned long rules, - *offload_trigger |= QCA8K_LED_TX_BLINK_MASK; - if (test_bit(TRIGGER_NETDEV_RX, &rules)) - *offload_trigger |= QCA8K_LED_RX_BLINK_MASK; -+ if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) -+ *offload_trigger |= QCA8K_LED_LINK_10M_EN_MASK; -+ if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) -+ *offload_trigger |= QCA8K_LED_LINK_100M_EN_MASK; -+ if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) -+ *offload_trigger |= QCA8K_LED_LINK_1000M_EN_MASK; -+ if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) -+ *offload_trigger |= QCA8K_LED_HALF_DUPLEX_MASK; -+ if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) -+ *offload_trigger |= QCA8K_LED_FULL_DUPLEX_MASK; - - if (rules && !*offload_trigger) - return -EOPNOTSUPP; -@@ -322,6 +332,16 @@ qca8k_cled_hw_control_get(struct led_cla - set_bit(TRIGGER_NETDEV_TX, rules); - if (val & QCA8K_LED_RX_BLINK_MASK) - set_bit(TRIGGER_NETDEV_RX, rules); -+ if (val & QCA8K_LED_LINK_10M_EN_MASK) -+ set_bit(TRIGGER_NETDEV_LINK_10, rules); -+ if (val & QCA8K_LED_LINK_100M_EN_MASK) -+ set_bit(TRIGGER_NETDEV_LINK_100, rules); -+ if (val & QCA8K_LED_LINK_1000M_EN_MASK) -+ set_bit(TRIGGER_NETDEV_LINK_1000, rules); -+ if (val & QCA8K_LED_HALF_DUPLEX_MASK) -+ set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); -+ if (val & QCA8K_LED_FULL_DUPLEX_MASK) -+ set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); - - return 0; - } diff --git a/target/linux/generic/backport-6.1/807-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch b/target/linux/generic/backport-6.1/807-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch deleted file mode 100644 index 8c062dc3b4c6eb..00000000000000 --- a/target/linux/generic/backport-6.1/807-v6.5-01-net-dsa-mv88e6xxx-pass-directly-chip-structure-to-mv.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 4f86eb098e18fd0f032877dfa1a7e8c1503ca409 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:41 +0200 -Subject: [PATCH 1/6] net: dsa: mv88e6xxx: pass directly chip structure to - mv88e6xxx_phy_is_internal -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since this function is a simple helper, we do not need to pass a full -dsa_switch structure, we can directly pass the mv88e6xxx_chip structure. -Doing so will allow to share this function with any other function -not manipulating dsa_switch structure but needing info about number of -internal phys - -Signed-off-by: Alexis Lothoré -Reviewed-by: Russell King (Oracle) -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mv88e6xxx/chip.c | 10 ++++------ - 1 file changed, 4 insertions(+), 6 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -470,10 +470,8 @@ restore_link: - return err; - } - --static int mv88e6xxx_phy_is_internal(struct dsa_switch *ds, int port) -+static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port) - { -- struct mv88e6xxx_chip *chip = ds->priv; -- - return port < chip->info->num_internal_phys; - } - -@@ -591,7 +589,7 @@ static void mv88e6095_phylink_get_caps(s - - config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100; - -- if (mv88e6xxx_phy_is_internal(chip->ds, port)) { -+ if (mv88e6xxx_phy_is_internal(chip, port)) { - __set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces); - } else { - if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) && -@@ -851,7 +849,7 @@ static void mv88e6xxx_get_caps(struct ds - chip->info->ops->phylink_get_caps(chip, port, config); - mv88e6xxx_reg_unlock(chip); - -- if (mv88e6xxx_phy_is_internal(ds, port)) { -+ if (mv88e6xxx_phy_is_internal(chip, port)) { - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - config->supported_interfaces); - /* Internal ports with no phy-mode need GMII for PHYLIB */ -@@ -872,7 +870,7 @@ static void mv88e6xxx_mac_config(struct - - mv88e6xxx_reg_lock(chip); - -- if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(ds, port)) { -+ if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(chip, port)) { - /* In inband mode, the link may come up at any time while the - * link is not forced down. Force the link down while we - * reconfigure the interface mode. diff --git a/target/linux/generic/backport-6.1/807-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch b/target/linux/generic/backport-6.1/807-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch deleted file mode 100644 index 75a21a931d5e78..00000000000000 --- a/target/linux/generic/backport-6.1/807-v6.5-02-net-dsa-mv88e6xxx-use-mv88e6xxx_phy_is_internal-in-m.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 73cbfad9296eed004992806e056db5b48583ca41 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:42 +0200 -Subject: [PATCH 2/6] net: dsa: mv88e6xxx: use mv88e6xxx_phy_is_internal in - mv88e6xxx_port_ppu_updates -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make sure to use existing helper to get internal PHYs count instead of -redoing it manually - -Signed-off-by: Alexis Lothoré -Reviewed-by: Russell King (Oracle) -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mv88e6xxx/chip.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -484,7 +484,7 @@ static int mv88e6xxx_port_ppu_updates(st - * report whether the port is internal. - */ - if (chip->info->family == MV88E6XXX_FAMILY_6250) -- return port < chip->info->num_internal_phys; -+ return mv88e6xxx_phy_is_internal(chip, port); - - err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®); - if (err) { diff --git a/target/linux/generic/backport-6.1/807-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch b/target/linux/generic/backport-6.1/807-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch deleted file mode 100644 index e24dca819b10d3..00000000000000 --- a/target/linux/generic/backport-6.1/807-v6.5-03-net-dsa-mv88e6xxx-add-field-to-specify-internal-phys.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 1414d30660d201f515a9d877571ceea9ca190b6a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:43 +0200 -Subject: [PATCH 3/6] net: dsa: mv88e6xxx: add field to specify internal phys - layout -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -mv88e6xxx currently assumes that switch equipped with internal phys have -those phys mapped contiguously starting from port 0 (see -mv88e6xxx_phy_is_internal). However, some switches have internal PHYs but -NOT starting from port 0. For example 88e6393X, 88E6193X and 88E6191X have -integrated PHYs available on ports 1 to 8 -To properly support this offset, add a new field to allow specifying an -internal PHYs layout. If field is not set, default layout is assumed (start -at port 0) - -Signed-off-by: Alexis Lothoré -Reviewed-by: Andrew Lunn -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mv88e6xxx/chip.c | 4 +++- - drivers/net/dsa/mv88e6xxx/chip.h | 5 +++++ - drivers/net/dsa/mv88e6xxx/global2.c | 5 ++++- - 3 files changed, 12 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -472,7 +472,9 @@ restore_link: - - static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port) - { -- return port < chip->info->num_internal_phys; -+ return port >= chip->info->internal_phys_offset && -+ port < chip->info->num_internal_phys + -+ chip->info->internal_phys_offset; - } - - static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port) ---- a/drivers/net/dsa/mv88e6xxx/chip.h -+++ b/drivers/net/dsa/mv88e6xxx/chip.h -@@ -167,6 +167,11 @@ struct mv88e6xxx_info { - - /* Supports PTP */ - bool ptp_support; -+ -+ /* Internal PHY start index. 0 means that internal PHYs range starts at -+ * port 0, 1 means internal PHYs range starts at port 1, etc -+ */ -+ unsigned int internal_phys_offset; - }; - - struct mv88e6xxx_atu_entry { ---- a/drivers/net/dsa/mv88e6xxx/global2.c -+++ b/drivers/net/dsa/mv88e6xxx/global2.c -@@ -1185,8 +1185,11 @@ int mv88e6xxx_g2_irq_mdio_setup(struct m - struct mii_bus *bus) - { - int phy, irq, err, err_phy; -+ int phy_start = chip->info->internal_phys_offset; -+ int phy_end = chip->info->internal_phys_offset + -+ chip->info->num_internal_phys; - -- for (phy = 0; phy < chip->info->num_internal_phys; phy++) { -+ for (phy = phy_start; phy < phy_end; phy++) { - irq = irq_find_mapping(chip->g2_irq.domain, phy); - if (irq < 0) { - err = irq; diff --git a/target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch b/target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch deleted file mode 100644 index 428b7c9b799002..00000000000000 --- a/target/linux/generic/backport-6.1/807-v6.5-04-net-dsa-mv88e6xxx-fix-88E6393X-family-internal-phys-.patch +++ /dev/null @@ -1,52 +0,0 @@ -From eb8c75f82a6711387f3b9e03e28923f3e75a761b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:44 +0200 -Subject: [PATCH 4/6] net: dsa: mv88e6xxx: fix 88E6393X family internal phys - layout -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -88E6393X/88E6193X/88E6191X switches have in fact 8 internal PHYs, but those -are not present starting at port 0: supported ports go from 1 to 8 - -Signed-off-by: Alexis Lothoré -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mv88e6xxx/chip.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -5999,7 +5999,8 @@ static const struct mv88e6xxx_info mv88e - .name = "Marvell 88E6191X", - .num_databases = 4096, - .num_ports = 11, /* 10 + Z80 */ -- .num_internal_phys = 9, -+ .num_internal_phys = 8, -+ .internal_phys_offset = 1, - .max_vid = 8191, - .max_sid = 63, - .port_base_addr = 0x0, -@@ -6022,7 +6023,8 @@ static const struct mv88e6xxx_info mv88e - .name = "Marvell 88E6193X", - .num_databases = 4096, - .num_ports = 11, /* 10 + Z80 */ -- .num_internal_phys = 9, -+ .num_internal_phys = 8, -+ .internal_phys_offset = 1, - .max_vid = 8191, - .max_sid = 63, - .port_base_addr = 0x0, -@@ -6341,7 +6343,8 @@ static const struct mv88e6xxx_info mv88e - .name = "Marvell 88E6393X", - .num_databases = 4096, - .num_ports = 11, /* 10 + Z80 */ -- .num_internal_phys = 9, -+ .num_internal_phys = 8, -+ .internal_phys_offset = 1, - .max_vid = 8191, - .max_sid = 63, - .port_base_addr = 0x0, diff --git a/target/linux/generic/backport-6.1/807-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch b/target/linux/generic/backport-6.1/807-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch deleted file mode 100644 index e2d3b57cccc1d9..00000000000000 --- a/target/linux/generic/backport-6.1/807-v6.5-05-net-dsa-mv88e6xxx-pass-mv88e6xxx_chip-structure-to-p.patch +++ /dev/null @@ -1,110 +0,0 @@ -From cef945452c8468efce75ba0dc8420510a5b84af9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:45 +0200 -Subject: [PATCH 5/6] net: dsa: mv88e6xxx: pass mv88e6xxx_chip structure to - port_max_speed_mode -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some switches families have minor differences on supported link speed for -ports. Instead of redefining a new port_max_speed_mode for each different -configuration, allow to pass mv88e6xxx_chip structure to allow -differentiating those chips by known chip id - -Signed-off-by: Alexis Lothoré -Reviewed-by: Florian Fainelli -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mv88e6xxx/chip.c | 2 +- - drivers/net/dsa/mv88e6xxx/chip.h | 3 ++- - drivers/net/dsa/mv88e6xxx/port.c | 12 ++++++++---- - drivers/net/dsa/mv88e6xxx/port.h | 12 ++++++++---- - 4 files changed, 19 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -3350,7 +3350,7 @@ static int mv88e6xxx_setup_port(struct m - caps = pl_config.mac_capabilities; - - if (chip->info->ops->port_max_speed_mode) -- mode = chip->info->ops->port_max_speed_mode(port); -+ mode = chip->info->ops->port_max_speed_mode(chip, port); - else - mode = PHY_INTERFACE_MODE_NA; - ---- a/drivers/net/dsa/mv88e6xxx/chip.h -+++ b/drivers/net/dsa/mv88e6xxx/chip.h -@@ -514,7 +514,8 @@ struct mv88e6xxx_ops { - int speed, int duplex); - - /* What interface mode should be used for maximum speed? */ -- phy_interface_t (*port_max_speed_mode)(int port); -+ phy_interface_t (*port_max_speed_mode)(struct mv88e6xxx_chip *chip, -+ int port); - - int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port); - ---- a/drivers/net/dsa/mv88e6xxx/port.c -+++ b/drivers/net/dsa/mv88e6xxx/port.c -@@ -342,7 +342,8 @@ int mv88e6341_port_set_speed_duplex(stru - duplex); - } - --phy_interface_t mv88e6341_port_max_speed_mode(int port) -+phy_interface_t mv88e6341_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port) - { - if (port == 5) - return PHY_INTERFACE_MODE_2500BASEX; -@@ -381,7 +382,8 @@ int mv88e6390_port_set_speed_duplex(stru - duplex); - } - --phy_interface_t mv88e6390_port_max_speed_mode(int port) -+phy_interface_t mv88e6390_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port) - { - if (port == 9 || port == 10) - return PHY_INTERFACE_MODE_2500BASEX; -@@ -403,7 +405,8 @@ int mv88e6390x_port_set_speed_duplex(str - duplex); - } - --phy_interface_t mv88e6390x_port_max_speed_mode(int port) -+phy_interface_t mv88e6390x_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port) - { - if (port == 9 || port == 10) - return PHY_INTERFACE_MODE_XAUI; -@@ -500,7 +503,8 @@ int mv88e6393x_port_set_speed_duplex(str - return 0; - } - --phy_interface_t mv88e6393x_port_max_speed_mode(int port) -+phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port) - { - if (port == 0 || port == 9 || port == 10) - return PHY_INTERFACE_MODE_10GBASER; ---- a/drivers/net/dsa/mv88e6xxx/port.h -+++ b/drivers/net/dsa/mv88e6xxx/port.h -@@ -359,10 +359,14 @@ int mv88e6390x_port_set_speed_duplex(str - int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port, - int speed, int duplex); - --phy_interface_t mv88e6341_port_max_speed_mode(int port); --phy_interface_t mv88e6390_port_max_speed_mode(int port); --phy_interface_t mv88e6390x_port_max_speed_mode(int port); --phy_interface_t mv88e6393x_port_max_speed_mode(int port); -+phy_interface_t mv88e6341_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port); -+phy_interface_t mv88e6390_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port); -+phy_interface_t mv88e6390x_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port); -+phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip, -+ int port); - - int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state); - diff --git a/target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch b/target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch deleted file mode 100644 index 9a294b59fcbfd3..00000000000000 --- a/target/linux/generic/backport-6.1/807-v6.5-06-net-dsa-mv88e6xxx-enable-support-for-88E6361-switch.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 23680321789863bab2d60af507858ce50ff9f56a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Alexis=20Lothor=C3=A9?= -Date: Mon, 29 May 2023 10:02:46 +0200 -Subject: [PATCH 6/6] net: dsa: mv88e6xxx: enable support for 88E6361 switch -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Marvell 88E6361 is an 8-port switch derived from the -88E6393X/88E9193X/88E6191X switches family. It can benefit from the -existing mv88e6xxx driver by simply adding the proper switch description in -the driver. Main differences with other switches from this -family are: -- 8 ports exposed (instead of 11): ports 1, 2 and 8 not available -- No 5GBase-x nor SFI/USXGMII support - -Signed-off-by: Alexis Lothoré -Reviewed-by: Andrew Lunn -Signed-off-by: Jakub Kicinski ---- - drivers/net/dsa/mv88e6xxx/chip.c | 42 ++++++++++++++++++++++++++++---- - drivers/net/dsa/mv88e6xxx/chip.h | 3 ++- - drivers/net/dsa/mv88e6xxx/port.c | 14 ++++++++--- - drivers/net/dsa/mv88e6xxx/port.h | 1 + - 4 files changed, 51 insertions(+), 9 deletions(-) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -809,6 +809,8 @@ static void mv88e6393x_phylink_get_caps( - unsigned long *supported = config->supported_interfaces; - bool is_6191x = - chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X; -+ bool is_6361 = -+ chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361; - - mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); - -@@ -823,13 +825,17 @@ static void mv88e6393x_phylink_get_caps( - /* 6191X supports >1G modes only on port 10 */ - if (!is_6191x || port == 10) { - __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported); -- __set_bit(PHY_INTERFACE_MODE_5GBASER, supported); -- __set_bit(PHY_INTERFACE_MODE_10GBASER, supported); -+ config->mac_capabilities |= MAC_2500FD; -+ -+ /* 6361 only supports up to 2500BaseX */ -+ if (!is_6361) { -+ __set_bit(PHY_INTERFACE_MODE_5GBASER, supported); -+ __set_bit(PHY_INTERFACE_MODE_10GBASER, supported); -+ config->mac_capabilities |= MAC_5000FD | -+ MAC_10000FD; -+ } - /* FIXME: USXGMII is not supported yet */ - /* __set_bit(PHY_INTERFACE_MODE_USXGMII, supported); */ -- -- config->mac_capabilities |= MAC_2500FD | MAC_5000FD | -- MAC_10000FD; - } - } - -@@ -6286,6 +6292,32 @@ static const struct mv88e6xxx_info mv88e - .ptp_support = true, - .ops = &mv88e6352_ops, - }, -+ [MV88E6361] = { -+ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361, -+ .family = MV88E6XXX_FAMILY_6393, -+ .name = "Marvell 88E6361", -+ .num_databases = 4096, -+ .num_macs = 16384, -+ .num_ports = 11, -+ /* Ports 1, 2 and 8 are not routed */ -+ .invalid_port_mask = BIT(1) | BIT(2) | BIT(8), -+ .num_internal_phys = 5, -+ .internal_phys_offset = 3, -+ .max_vid = 4095, -+ .max_sid = 63, -+ .port_base_addr = 0x0, -+ .phy_base_addr = 0x0, -+ .global1_addr = 0x1b, -+ .global2_addr = 0x1c, -+ .age_time_coeff = 3750, -+ .g1_irqs = 10, -+ .g2_irqs = 14, -+ .atu_move_port_mask = 0x1f, -+ .pvt = true, -+ .multi_chip = true, -+ .ptp_support = true, -+ .ops = &mv88e6393x_ops, -+ }, - [MV88E6390] = { - .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390, - .family = MV88E6XXX_FAMILY_6390, ---- a/drivers/net/dsa/mv88e6xxx/chip.h -+++ b/drivers/net/dsa/mv88e6xxx/chip.h -@@ -82,6 +82,7 @@ enum mv88e6xxx_model { - MV88E6350, - MV88E6351, - MV88E6352, -+ MV88E6361, - MV88E6390, - MV88E6390X, - MV88E6393X, -@@ -100,7 +101,7 @@ enum mv88e6xxx_family { - MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */ - MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */ - MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */ -- MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6393X */ -+ MV88E6XXX_FAMILY_6393, /* 6191X 6193X 6361 6393X */ - }; - - /** ---- a/drivers/net/dsa/mv88e6xxx/port.c -+++ b/drivers/net/dsa/mv88e6xxx/port.c -@@ -424,6 +424,10 @@ int mv88e6393x_port_set_speed_duplex(str - u16 reg, ctrl; - int err; - -+ if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361 && -+ speed > 2500) -+ return -EOPNOTSUPP; -+ - if (speed == 200 && port != 0) - return -EOPNOTSUPP; - -@@ -506,10 +510,14 @@ int mv88e6393x_port_set_speed_duplex(str - phy_interface_t mv88e6393x_port_max_speed_mode(struct mv88e6xxx_chip *chip, - int port) - { -- if (port == 0 || port == 9 || port == 10) -- return PHY_INTERFACE_MODE_10GBASER; - -- return PHY_INTERFACE_MODE_NA; -+ if (port != 0 && port != 9 && port != 10) -+ return PHY_INTERFACE_MODE_NA; -+ -+ if (chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361) -+ return PHY_INTERFACE_MODE_2500BASEX; -+ -+ return PHY_INTERFACE_MODE_10GBASER; - } - - static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, ---- a/drivers/net/dsa/mv88e6xxx/port.h -+++ b/drivers/net/dsa/mv88e6xxx/port.h -@@ -133,6 +133,7 @@ - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6220 0x2200 - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6240 0x2400 - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6250 0x2500 -+#define MV88E6XXX_PORT_SWITCH_ID_PROD_6361 0x2610 - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6290 0x2900 - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6321 0x3100 - #define MV88E6XXX_PORT_SWITCH_ID_PROD_6141 0x3400 diff --git a/target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch b/target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch deleted file mode 100644 index 33759632ebe4f4..00000000000000 --- a/target/linux/generic/backport-6.1/808-v6.2-0001-nvmem-stm32-move-STM32MP15_BSEC_NUM_LOWER-in-config.patch +++ /dev/null @@ -1,82 +0,0 @@ -From fbfc4ca465a1f8d81bf2d67d95bf7fc67c3cf0c2 Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Fri, 18 Nov 2022 06:39:20 +0000 -Subject: [PATCH] nvmem: stm32: move STM32MP15_BSEC_NUM_LOWER in config - -Support STM32MP15_BSEC_NUM_LOWER in stm32 romem config to prepare -the next SoC in STM32MP family. - -Signed-off-by: Patrick Delaunay -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 21 ++++++++++++++++----- - 1 file changed, 16 insertions(+), 5 deletions(-) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -22,16 +22,15 @@ - /* shadow registers offest */ - #define STM32MP15_BSEC_DATA0 0x200 - --/* 32 (x 32-bits) lower shadow registers */ --#define STM32MP15_BSEC_NUM_LOWER 32 -- - struct stm32_romem_cfg { - int size; -+ u8 lower; - }; - - struct stm32_romem_priv { - void __iomem *base; - struct nvmem_config cfg; -+ u8 lower; - }; - - static int stm32_romem_read(void *context, unsigned int offset, void *buf, -@@ -85,7 +84,7 @@ static int stm32_bsec_read(void *context - for (i = roffset; (i < roffset + rbytes); i += 4) { - u32 otp = i >> 2; - -- if (otp < STM32MP15_BSEC_NUM_LOWER) { -+ if (otp < priv->lower) { - /* read lower data from shadow registers */ - val = readl_relaxed( - priv->base + STM32MP15_BSEC_DATA0 + i); -@@ -159,6 +158,8 @@ static int stm32_romem_probe(struct plat - priv->cfg.priv = priv; - priv->cfg.owner = THIS_MODULE; - -+ priv->lower = 0; -+ - cfg = (const struct stm32_romem_cfg *) - of_match_device(dev->driver->of_match_table, dev)->data; - if (!cfg) { -@@ -167,6 +168,7 @@ static int stm32_romem_probe(struct plat - priv->cfg.reg_read = stm32_romem_read; - } else { - priv->cfg.size = cfg->size; -+ priv->lower = cfg->lower; - priv->cfg.reg_read = stm32_bsec_read; - priv->cfg.reg_write = stm32_bsec_write; - } -@@ -174,8 +176,17 @@ static int stm32_romem_probe(struct plat - return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); - } - -+/* -+ * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) -+ * => 96 x 32-bits data words -+ * - Lower: 1K bits, 2:1 redundancy, incremental bit programming -+ * => 32 (x 32-bits) lower shadow registers = words 0 to 31 -+ * - Upper: 2K bits, ECC protection, word programming only -+ * => 64 (x 32-bits) = words 32 to 95 -+ */ - static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { -- .size = 384, /* 96 x 32-bits data words */ -+ .size = 384, -+ .lower = 32, - }; - - static const struct of_device_id stm32_romem_of_match[] = { diff --git a/target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch b/target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch deleted file mode 100644 index 5791df2606ffe3..00000000000000 --- a/target/linux/generic/backport-6.1/808-v6.2-0002-nvmem-stm32-add-warning-when-upper-OTPs-are-updated.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d61784e6410f3df2028e6eb91b06ffed37a660e0 Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Fri, 18 Nov 2022 06:39:21 +0000 -Subject: [PATCH] nvmem: stm32: add warning when upper OTPs are updated - -As the upper OTPs are ECC protected, they support only one 32 bits word -programming. -For a second modification of this word, these ECC become invalid and -this OTP will be no more accessible, the shadowed value is invalid. - -This patch adds a warning to indicate an upper OTP update, because this -operation is dangerous as OTP is not locked by the driver after the first -update to avoid a second update. - -Signed-off-by: Patrick Delaunay -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -132,6 +132,9 @@ static int stm32_bsec_write(void *contex - } - } - -+ if (offset + bytes >= priv->lower * 4) -+ dev_warn(dev, "Update of upper OTPs with ECC protection (word programming, only once)\n"); -+ - return 0; - } - diff --git a/target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch b/target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch deleted file mode 100644 index b83ad69c6b4ebb..00000000000000 --- a/target/linux/generic/backport-6.1/808-v6.2-0003-nvmem-stm32-add-nvmem-type-attribute.patch +++ /dev/null @@ -1,26 +0,0 @@ -From a3816a7d7c097c1da46aad5f5d1e229b607dce04 Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Fri, 18 Nov 2022 06:39:22 +0000 -Subject: [PATCH] nvmem: stm32: add nvmem type attribute - -Inform NVMEM framework of type attribute for stm32-romem as NVMEM_TYPE_OTP -so userspace is able to know how the data is stored in BSEC. - -Signed-off-by: Patrick Delaunay -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -160,6 +160,7 @@ static int stm32_romem_probe(struct plat - priv->cfg.dev = dev; - priv->cfg.priv = priv; - priv->cfg.owner = THIS_MODULE; -+ priv->cfg.type = NVMEM_TYPE_OTP; - - priv->lower = 0; - diff --git a/target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch b/target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch deleted file mode 100644 index 52ba1e65b567fa..00000000000000 --- a/target/linux/generic/backport-6.1/808-v6.2-0004-nvmem-stm32-fix-spelling-typo-in-comment.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 06aac0e11960a7ddccc1888326b5906d017e0f24 Mon Sep 17 00:00:00 2001 -From: Jiangshan Yi -Date: Fri, 18 Nov 2022 06:39:24 +0000 -Subject: [PATCH] nvmem: stm32: fix spelling typo in comment - -Fix spelling typo in comment. - -Reported-by: k2ci -Signed-off-by: Jiangshan Yi -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -19,7 +19,7 @@ - #define STM32_SMC_WRITE_SHADOW 0x03 - #define STM32_SMC_READ_OTP 0x04 - --/* shadow registers offest */ -+/* shadow registers offset */ - #define STM32MP15_BSEC_DATA0 0x200 - - struct stm32_romem_cfg { diff --git a/target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch b/target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch deleted file mode 100644 index 8f024f4c1acb8b..00000000000000 --- a/target/linux/generic/backport-6.1/808-v6.2-0005-nvmem-Kconfig-Fix-spelling-mistake-controlls-control.patch +++ /dev/null @@ -1,27 +0,0 @@ -From fb817c4ef63e8cfb6e77ae4a2875ae854c80708f Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Fri, 18 Nov 2022 06:39:26 +0000 -Subject: [PATCH] nvmem: Kconfig: Fix spelling mistake "controlls" -> - "controls" - -There is a spelling mistake in a Kconfig description. Fix it. - -Signed-off-by: Colin Ian King -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -164,7 +164,7 @@ config NVMEM_MICROCHIP_OTPC - depends on ARCH_AT91 || COMPILE_TEST - help - This driver enable the OTP controller available on Microchip SAMA7G5 -- SoCs. It controlls the access to the OTP memory connected to it. -+ SoCs. It controls the access to the OTP memory connected to it. - - config NVMEM_MTK_EFUSE - tristate "Mediatek SoCs EFUSE support" diff --git a/target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch b/target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch deleted file mode 100644 index 861386ad310b59..00000000000000 --- a/target/linux/generic/backport-6.1/808-v6.2-0006-nvmem-u-boot-env-add-Broadcom-format-support.patch +++ /dev/null @@ -1,67 +0,0 @@ -From ada84d07af6097b2addd18262668ce6cb9e15206 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 18 Nov 2022 06:39:27 +0000 -Subject: [PATCH] nvmem: u-boot-env: add Broadcom format support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Broadcom uses U-Boot for a lot of their bcmbca familiy chipsets. They -decided to store U-Boot environment data inside U-Boot partition and to -use a custom header (with "uEnv" magic and env data length). - -Add support for Broadcom's specific binding and their custom format. - -Ref: 6b0584c19d87 ("dt-bindings: nvmem: u-boot,env: add Broadcom's variant binding") -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20221118063932.6418-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -16,6 +16,7 @@ - enum u_boot_env_format { - U_BOOT_FORMAT_SINGLE, - U_BOOT_FORMAT_REDUNDANT, -+ U_BOOT_FORMAT_BROADCOM, - }; - - struct u_boot_env { -@@ -40,6 +41,13 @@ struct u_boot_env_image_redundant { - uint8_t data[]; - } __packed; - -+struct u_boot_env_image_broadcom { -+ __le32 magic; -+ __le32 len; -+ __le32 crc32; -+ uint8_t data[0]; -+} __packed; -+ - static int u_boot_env_read(void *context, unsigned int offset, void *val, - size_t bytes) - { -@@ -138,6 +146,11 @@ static int u_boot_env_parse(struct u_boo - crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); - data_offset = offsetof(struct u_boot_env_image_redundant, data); - break; -+ case U_BOOT_FORMAT_BROADCOM: -+ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32); -+ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data); -+ data_offset = offsetof(struct u_boot_env_image_broadcom, data); -+ break; - } - crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); - crc32_data_len = priv->mtd->size - crc32_data_offset; -@@ -202,6 +215,7 @@ static const struct of_device_id u_boot_ - { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, }, - { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, - { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, -+ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, }, - {}, - }; - diff --git a/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch b/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch deleted file mode 100644 index 9eec0bc48fefe8..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0001-nvmem-core-remove-spurious-white-space.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 2e8dc541ae207349b51c65391be625ffe1f86e0c Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Mon, 6 Feb 2023 13:43:41 +0000 -Subject: [PATCH] nvmem: core: remove spurious white space - -Remove a spurious white space in for the ida_alloc() call. - -Signed-off-by: Russell King (Oracle) -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -763,7 +763,7 @@ struct nvmem_device *nvmem_register(cons - if (!nvmem) - return ERR_PTR(-ENOMEM); - -- rval = ida_alloc(&nvmem_ida, GFP_KERNEL); -+ rval = ida_alloc(&nvmem_ida, GFP_KERNEL); - if (rval < 0) { - kfree(nvmem); - return ERR_PTR(rval); diff --git a/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch b/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch deleted file mode 100644 index 84ee69b8151a39..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0002-nvmem-core-add-an-index-parameter-to-the-cell.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 5d8e6e6c10a3d37486d263b16ddc15991a7e4a88 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:46 +0000 -Subject: [PATCH] nvmem: core: add an index parameter to the cell - -Sometimes a cell can represend multiple values. For example, a base -ethernet address stored in the NVMEM can be expanded into multiple -discreet ones by adding an offset. - -For this use case, introduce an index parameter which is then used to -distiguish between values. This parameter will then be passed to the -post process hook which can then use it to create different values -during reading. - -At the moment, there is only support for the device tree path. You can -add the index to the phandle, e.g. - - &net { - nvmem-cells = <&base_mac_address 2>; - nvmem-cell-names = "mac-address"; - }; - - &nvmem_provider { - base_mac_address: base-mac-address@0 { - #nvmem-cell-cells = <1>; - reg = <0 6>; - }; - }; - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-13-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 37 ++++++++++++++++++++++++---------- - drivers/nvmem/imx-ocotp.c | 4 ++-- - include/linux/nvmem-provider.h | 4 ++-- - 3 files changed, 30 insertions(+), 15 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -60,6 +60,7 @@ struct nvmem_cell_entry { - struct nvmem_cell { - struct nvmem_cell_entry *entry; - const char *id; -+ int index; - }; - - static DEFINE_MUTEX(nvmem_mutex); -@@ -1121,7 +1122,8 @@ struct nvmem_device *devm_nvmem_device_g - } - EXPORT_SYMBOL_GPL(devm_nvmem_device_get); - --static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id) -+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, -+ const char *id, int index) - { - struct nvmem_cell *cell; - const char *name = NULL; -@@ -1140,6 +1142,7 @@ static struct nvmem_cell *nvmem_create_c - - cell->id = name; - cell->entry = entry; -+ cell->index = index; - - return cell; - } -@@ -1178,7 +1181,7 @@ nvmem_cell_get_from_lookup(struct device - __nvmem_device_put(nvmem); - cell = ERR_PTR(-ENOENT); - } else { -- cell = nvmem_create_cell(cell_entry, con_id); -+ cell = nvmem_create_cell(cell_entry, con_id, 0); - if (IS_ERR(cell)) - __nvmem_device_put(nvmem); - } -@@ -1226,15 +1229,27 @@ struct nvmem_cell *of_nvmem_cell_get(str - struct nvmem_device *nvmem; - struct nvmem_cell_entry *cell_entry; - struct nvmem_cell *cell; -+ struct of_phandle_args cell_spec; - int index = 0; -+ int cell_index = 0; -+ int ret; - - /* if cell name exists, find index to the name */ - if (id) - index = of_property_match_string(np, "nvmem-cell-names", id); - -- cell_np = of_parse_phandle(np, "nvmem-cells", index); -- if (!cell_np) -- return ERR_PTR(-ENOENT); -+ ret = of_parse_phandle_with_optional_args(np, "nvmem-cells", -+ "#nvmem-cell-cells", -+ index, &cell_spec); -+ if (ret) -+ return ERR_PTR(ret); -+ -+ if (cell_spec.args_count > 1) -+ return ERR_PTR(-EINVAL); -+ -+ cell_np = cell_spec.np; -+ if (cell_spec.args_count) -+ cell_index = cell_spec.args[0]; - - nvmem_np = of_get_parent(cell_np); - if (!nvmem_np) { -@@ -1256,7 +1271,7 @@ struct nvmem_cell *of_nvmem_cell_get(str - return ERR_PTR(-ENOENT); - } - -- cell = nvmem_create_cell(cell_entry, id); -+ cell = nvmem_create_cell(cell_entry, id, cell_index); - if (IS_ERR(cell)) - __nvmem_device_put(nvmem); - -@@ -1409,8 +1424,8 @@ static void nvmem_shift_read_buffer_in_p - } - - static int __nvmem_cell_read(struct nvmem_device *nvmem, -- struct nvmem_cell_entry *cell, -- void *buf, size_t *len, const char *id) -+ struct nvmem_cell_entry *cell, -+ void *buf, size_t *len, const char *id, int index) - { - int rc; - -@@ -1424,7 +1439,7 @@ static int __nvmem_cell_read(struct nvme - nvmem_shift_read_buffer_in_place(cell, buf); - - if (nvmem->cell_post_process) { -- rc = nvmem->cell_post_process(nvmem->priv, id, -+ rc = nvmem->cell_post_process(nvmem->priv, id, index, - cell->offset, buf, cell->bytes); - if (rc) - return rc; -@@ -1459,7 +1474,7 @@ void *nvmem_cell_read(struct nvmem_cell - if (!buf) - return ERR_PTR(-ENOMEM); - -- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id); -+ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index); - if (rc) { - kfree(buf); - return ERR_PTR(rc); -@@ -1772,7 +1787,7 @@ ssize_t nvmem_device_cell_read(struct nv - if (rc) - return rc; - -- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL); -+ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0); - if (rc) - return rc; - ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -222,8 +222,8 @@ read_end: - return ret; - } - --static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset, -- void *data, size_t bytes) -+static int imx_ocotp_cell_pp(void *context, const char *id, int index, -+ unsigned int offset, void *data, size_t bytes) - { - struct ocotp_priv *priv = context; - ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -20,8 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *pr - typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, - void *val, size_t bytes); - /* used for vendor specific post processing of cell data */ --typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset, -- void *buf, size_t bytes); -+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, -+ unsigned int offset, void *buf, size_t bytes); - - enum nvmem_type { - NVMEM_TYPE_UNKNOWN = 0, diff --git a/target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch b/target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch deleted file mode 100644 index f3829b3e17f4f6..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0003-nvmem-core-move-struct-nvmem_cell_info-to-nvmem-prov.patch +++ /dev/null @@ -1,78 +0,0 @@ -From fbd03d27776c6121a483921601418e3c8f0ff37e Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:47 +0000 -Subject: [PATCH] nvmem: core: move struct nvmem_cell_info to nvmem-provider.h - -struct nvmem_cell_info is used to describe a cell. Thus this should -really be in the nvmem-provider's header. There are two (unused) nvmem -access methods which use the nvmem_cell_info to describe the cell to be -accesses. One can argue, that they will create a cell before accessing, -thus they are both a provider and a consumer. - -struct nvmem_cell_info will get used more and more by nvmem-providers, -don't force them to also include the consumer header, although they are -not. - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-14-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - include/linux/nvmem-consumer.h | 10 +--------- - include/linux/nvmem-provider.h | 19 ++++++++++++++++++- - 2 files changed, 19 insertions(+), 10 deletions(-) - ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -18,15 +18,7 @@ struct device_node; - /* consumer cookie */ - struct nvmem_cell; - struct nvmem_device; -- --struct nvmem_cell_info { -- const char *name; -- unsigned int offset; -- unsigned int bytes; -- unsigned int bit_offset; -- unsigned int nbits; -- struct device_node *np; --}; -+struct nvmem_cell_info; - - /** - * struct nvmem_cell_lookup - cell lookup entry ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -14,7 +14,6 @@ - #include - - struct nvmem_device; --struct nvmem_cell_info; - typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, - void *val, size_t bytes); - typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset, -@@ -48,6 +47,24 @@ struct nvmem_keepout { - }; - - /** -+ * struct nvmem_cell_info - NVMEM cell description -+ * @name: Name. -+ * @offset: Offset within the NVMEM device. -+ * @bytes: Length of the cell. -+ * @bit_offset: Bit offset if cell is smaller than a byte. -+ * @nbits: Number of bits. -+ * @np: Optional device_node pointer. -+ */ -+struct nvmem_cell_info { -+ const char *name; -+ unsigned int offset; -+ unsigned int bytes; -+ unsigned int bit_offset; -+ unsigned int nbits; -+ struct device_node *np; -+}; -+ -+/** - * struct nvmem_config - NVMEM device configuration - * - * @dev: Parent device. diff --git a/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch b/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch deleted file mode 100644 index b20c500e7ce01b..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0004-nvmem-core-drop-the-removal-of-the-cells-in-nvmem_ad.patch +++ /dev/null @@ -1,65 +0,0 @@ -From cc5bdd323dde6494623f3ffe3a5b887fa21cd375 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:48 +0000 -Subject: [PATCH] nvmem: core: drop the removal of the cells in - nvmem_add_cells() - -If nvmem_add_cells() fails, the whole nvmem_register() will fail -and the cells will then be removed anyway. This is a preparation -to introduce a nvmem_add_one_cell() which can then be used by -nvmem_add_cells(). - -This is then the same to what nvmem_add_cells_from_table() and -nvmem_add_cells_from_of() do. - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-15-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 14 ++++---------- - 1 file changed, 4 insertions(+), 10 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -514,7 +514,7 @@ static int nvmem_add_cells(struct nvmem_ - int ncells) - { - struct nvmem_cell_entry **cells; -- int i, rval; -+ int i, rval = 0; - - cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); - if (!cells) -@@ -524,28 +524,22 @@ static int nvmem_add_cells(struct nvmem_ - cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); - if (!cells[i]) { - rval = -ENOMEM; -- goto err; -+ goto out; - } - - rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); - if (rval) { - kfree(cells[i]); -- goto err; -+ goto out; - } - - nvmem_cell_entry_add(cells[i]); - } - -+out: - /* remove tmp array */ - kfree(cells); - -- return 0; --err: -- while (i--) -- nvmem_cell_entry_drop(cells[i]); -- -- kfree(cells); -- - return rval; - } - diff --git a/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch b/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch deleted file mode 100644 index df4a02b8c50092..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0005-nvmem-core-add-nvmem_add_one_cell.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 2ded6830d376d5e7bf43d59f7f7fdf1a59abc676 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:49 +0000 -Subject: [PATCH] nvmem: core: add nvmem_add_one_cell() - -Add a new function to add exactly one cell. This will be used by the -nvmem layout drivers to add custom cells. In contrast to the -nvmem_add_cells(), this has the advantage that we don't have to assemble -a list of cells on runtime. - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-16-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 59 ++++++++++++++++++++-------------- - include/linux/nvmem-provider.h | 8 +++++ - 2 files changed, 43 insertions(+), 24 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -501,6 +501,36 @@ static int nvmem_cell_info_to_nvmem_cell - } - - /** -+ * nvmem_add_one_cell() - Add one cell information to an nvmem device -+ * -+ * @nvmem: nvmem device to add cells to. -+ * @info: nvmem cell info to add to the device -+ * -+ * Return: 0 or negative error code on failure. -+ */ -+int nvmem_add_one_cell(struct nvmem_device *nvmem, -+ const struct nvmem_cell_info *info) -+{ -+ struct nvmem_cell_entry *cell; -+ int rval; -+ -+ cell = kzalloc(sizeof(*cell), GFP_KERNEL); -+ if (!cell) -+ return -ENOMEM; -+ -+ rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, info, cell); -+ if (rval) { -+ kfree(cell); -+ return rval; -+ } -+ -+ nvmem_cell_entry_add(cell); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(nvmem_add_one_cell); -+ -+/** - * nvmem_add_cells() - Add cell information to an nvmem device - * - * @nvmem: nvmem device to add cells to. -@@ -513,34 +543,15 @@ static int nvmem_add_cells(struct nvmem_ - const struct nvmem_cell_info *info, - int ncells) - { -- struct nvmem_cell_entry **cells; -- int i, rval = 0; -- -- cells = kcalloc(ncells, sizeof(*cells), GFP_KERNEL); -- if (!cells) -- return -ENOMEM; -+ int i, rval; - - for (i = 0; i < ncells; i++) { -- cells[i] = kzalloc(sizeof(**cells), GFP_KERNEL); -- if (!cells[i]) { -- rval = -ENOMEM; -- goto out; -- } -- -- rval = nvmem_cell_info_to_nvmem_cell_entry(nvmem, &info[i], cells[i]); -- if (rval) { -- kfree(cells[i]); -- goto out; -- } -- -- nvmem_cell_entry_add(cells[i]); -+ rval = nvmem_add_one_cell(nvmem, &info[i]); -+ if (rval) -+ return rval; - } - --out: -- /* remove tmp array */ -- kfree(cells); -- -- return rval; -+ return 0; - } - - /** ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -153,6 +153,9 @@ struct nvmem_device *devm_nvmem_register - void nvmem_add_cell_table(struct nvmem_cell_table *table); - void nvmem_del_cell_table(struct nvmem_cell_table *table); - -+int nvmem_add_one_cell(struct nvmem_device *nvmem, -+ const struct nvmem_cell_info *info); -+ - #else - - static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) -@@ -170,6 +173,11 @@ devm_nvmem_register(struct device *dev, - - static inline void nvmem_add_cell_table(struct nvmem_cell_table *table) {} - static inline void nvmem_del_cell_table(struct nvmem_cell_table *table) {} -+static inline int nvmem_add_one_cell(struct nvmem_device *nvmem, -+ const struct nvmem_cell_info *info) -+{ -+ return -EOPNOTSUPP; -+} - - #endif /* CONFIG_NVMEM */ - #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch b/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch deleted file mode 100644 index 1b4a3f3ef319d7..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0006-nvmem-core-use-nvmem_add_one_cell-in-nvmem_add_cells.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 50014d659617dc58780a5d31ceb76c82779a9d8b Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:50 +0000 -Subject: [PATCH] nvmem: core: use nvmem_add_one_cell() in - nvmem_add_cells_from_of() - -Convert nvmem_add_cells_from_of() to use the new nvmem_add_one_cell(). -This will remove duplicate code and it will make it possible to add a -hook to a nvmem layout in between, which can change fields before the -cell is finally added. - -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-17-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 45 ++++++++++++++------------------------------ - 1 file changed, 14 insertions(+), 31 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -687,15 +687,14 @@ static int nvmem_validate_keepouts(struc - - static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) - { -- struct device_node *parent, *child; - struct device *dev = &nvmem->dev; -- struct nvmem_cell_entry *cell; -+ struct device_node *child; - const __be32 *addr; -- int len; -+ int len, ret; - -- parent = dev->of_node; -+ for_each_child_of_node(dev->of_node, child) { -+ struct nvmem_cell_info info = {0}; - -- for_each_child_of_node(parent, child) { - addr = of_get_property(child, "reg", &len); - if (!addr) - continue; -@@ -705,40 +704,24 @@ static int nvmem_add_cells_from_of(struc - return -EINVAL; - } - -- cell = kzalloc(sizeof(*cell), GFP_KERNEL); -- if (!cell) { -- of_node_put(child); -- return -ENOMEM; -- } -- -- cell->nvmem = nvmem; -- cell->offset = be32_to_cpup(addr++); -- cell->bytes = be32_to_cpup(addr); -- cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); -+ info.offset = be32_to_cpup(addr++); -+ info.bytes = be32_to_cpup(addr); -+ info.name = kasprintf(GFP_KERNEL, "%pOFn", child); - - addr = of_get_property(child, "bits", &len); - if (addr && len == (2 * sizeof(u32))) { -- cell->bit_offset = be32_to_cpup(addr++); -- cell->nbits = be32_to_cpup(addr); -+ info.bit_offset = be32_to_cpup(addr++); -+ info.nbits = be32_to_cpup(addr); - } - -- if (cell->nbits) -- cell->bytes = DIV_ROUND_UP( -- cell->nbits + cell->bit_offset, -- BITS_PER_BYTE); -- -- if (!IS_ALIGNED(cell->offset, nvmem->stride)) { -- dev_err(dev, "cell %s unaligned to nvmem stride %d\n", -- cell->name, nvmem->stride); -- /* Cells already added will be freed later. */ -- kfree_const(cell->name); -- kfree(cell); -+ info.np = of_node_get(child); -+ -+ ret = nvmem_add_one_cell(nvmem, &info); -+ kfree(info.name); -+ if (ret) { - of_node_put(child); -- return -EINVAL; -+ return ret; - } -- -- cell->np = of_node_get(child); -- nvmem_cell_entry_add(cell); - } - - return 0; diff --git a/target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch b/target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch deleted file mode 100644 index 172a78b76af1a6..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0007-nvmem-stm32-add-OP-TEE-support-for-STM32MP13x.patch +++ /dev/null @@ -1,562 +0,0 @@ -From 6a0bc3522e746025e2d9a63ab2cb5d7062c2d39c Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Mon, 6 Feb 2023 13:43:51 +0000 -Subject: [PATCH] nvmem: stm32: add OP-TEE support for STM32MP13x - -For boot with OP-TEE on STM32MP13, the communication with the secure -world no more use STMicroelectronics SMC but communication with the -STM32MP BSEC TA, for data access (read/write) or lock operation: -- all the request are sent to OP-TEE trusted application, -- for upper OTP with ECC protection and with word programming only - each OTP are permanently locked when programmed to avoid ECC error - on the second write operation - -Signed-off-by: Patrick Delaunay -Reviewed-by: Etienne Carriere -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-18-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 11 + - drivers/nvmem/Makefile | 1 + - drivers/nvmem/stm32-bsec-optee-ta.c | 298 ++++++++++++++++++++++++++++ - drivers/nvmem/stm32-bsec-optee-ta.h | 80 ++++++++ - drivers/nvmem/stm32-romem.c | 54 ++++- - 5 files changed, 441 insertions(+), 3 deletions(-) - create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.c - create mode 100644 drivers/nvmem/stm32-bsec-optee-ta.h - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -290,9 +290,20 @@ config NVMEM_SPRD_EFUSE - This driver can also be built as a module. If so, the module - will be called nvmem-sprd-efuse. - -+config NVMEM_STM32_BSEC_OPTEE_TA -+ bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver" -+ depends on OPTEE -+ help -+ Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE -+ trusted application STM32MP BSEC. -+ -+ This library is a used by stm32-romem driver or included in the module -+ called nvmem-stm32-romem. -+ - config NVMEM_STM32_ROMEM - tristate "STMicroelectronics STM32 factory-programmed memory support" - depends on ARCH_STM32 || COMPILE_TEST -+ imply NVMEM_STM32_BSEC_OPTEE_TA - help - Say y here to enable read-only access for STMicroelectronics STM32 - factory-programmed memory area. ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -61,6 +61,7 @@ obj-$(CONFIG_NVMEM_SPRD_EFUSE) += nvmem - nvmem_sprd_efuse-y := sprd-efuse.o - obj-$(CONFIG_NVMEM_STM32_ROMEM) += nvmem_stm32_romem.o - nvmem_stm32_romem-y := stm32-romem.o -+nvmem_stm32_romem-$(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) += stm32-bsec-optee-ta.o - obj-$(CONFIG_NVMEM_SUNPLUS_OCOTP) += nvmem_sunplus_ocotp.o - nvmem_sunplus_ocotp-y := sunplus-ocotp.o - obj-$(CONFIG_NVMEM_SUNXI_SID) += nvmem_sunxi_sid.o ---- /dev/null -+++ b/drivers/nvmem/stm32-bsec-optee-ta.c -@@ -0,0 +1,298 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver -+ * -+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved -+ */ -+ -+#include -+ -+#include "stm32-bsec-optee-ta.h" -+ -+/* -+ * Read OTP memory -+ * -+ * [in] value[0].a OTP start offset in byte -+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) -+ * [out] memref[1].buffer Output buffer to store read values -+ * [out] memref[1].size Size of OTP to be read -+ * -+ * Return codes: -+ * TEE_SUCCESS - Invoke command success -+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param -+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller -+ */ -+#define PTA_BSEC_READ_MEM 0x0 -+ -+/* -+ * Write OTP memory -+ * -+ * [in] value[0].a OTP start offset in byte -+ * [in] value[0].b Access type (0:shadow, 1:fuse, 2:lock) -+ * [in] memref[1].buffer Input buffer to read values -+ * [in] memref[1].size Size of OTP to be written -+ * -+ * Return codes: -+ * TEE_SUCCESS - Invoke command success -+ * TEE_ERROR_BAD_PARAMETERS - Incorrect input param -+ * TEE_ERROR_ACCESS_DENIED - OTP not accessible by caller -+ */ -+#define PTA_BSEC_WRITE_MEM 0x1 -+ -+/* value of PTA_BSEC access type = value[in] b */ -+#define SHADOW_ACCESS 0 -+#define FUSE_ACCESS 1 -+#define LOCK_ACCESS 2 -+ -+/* Bitfield definition for LOCK status */ -+#define LOCK_PERM BIT(30) -+ -+/* OP-TEE STM32MP BSEC TA UUID */ -+static const uuid_t stm32mp_bsec_ta_uuid = -+ UUID_INIT(0x94cf71ad, 0x80e6, 0x40b5, -+ 0xa7, 0xc6, 0x3d, 0xc5, 0x01, 0xeb, 0x28, 0x03); -+ -+/* -+ * Check whether this driver supports the BSEC TA in the TEE instance -+ * represented by the params (ver/data) to this function. -+ */ -+static int stm32_bsec_optee_ta_match(struct tee_ioctl_version_data *ver, -+ const void *data) -+{ -+ /* Currently this driver only supports GP compliant, OP-TEE based TA */ -+ if ((ver->impl_id == TEE_IMPL_ID_OPTEE) && -+ (ver->gen_caps & TEE_GEN_CAP_GP)) -+ return 1; -+ else -+ return 0; -+} -+ -+/* Open a session to OP-TEE for STM32MP BSEC TA */ -+static int stm32_bsec_ta_open_session(struct tee_context *ctx, u32 *id) -+{ -+ struct tee_ioctl_open_session_arg sess_arg; -+ int rc; -+ -+ memset(&sess_arg, 0, sizeof(sess_arg)); -+ export_uuid(sess_arg.uuid, &stm32mp_bsec_ta_uuid); -+ sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; -+ sess_arg.num_params = 0; -+ -+ rc = tee_client_open_session(ctx, &sess_arg, NULL); -+ if ((rc < 0) || (sess_arg.ret != 0)) { -+ pr_err("%s: tee_client_open_session failed err:%#x, ret:%#x\n", -+ __func__, sess_arg.ret, rc); -+ if (!rc) -+ rc = -EINVAL; -+ } else { -+ *id = sess_arg.session; -+ } -+ -+ return rc; -+} -+ -+/* close a session to OP-TEE for STM32MP BSEC TA */ -+static void stm32_bsec_ta_close_session(void *ctx, u32 id) -+{ -+ tee_client_close_session(ctx, id); -+} -+ -+/* stm32_bsec_optee_ta_open() - initialize the STM32MP BSEC TA */ -+int stm32_bsec_optee_ta_open(struct tee_context **ctx) -+{ -+ struct tee_context *tee_ctx; -+ u32 session_id; -+ int rc; -+ -+ /* Open context with TEE driver */ -+ tee_ctx = tee_client_open_context(NULL, stm32_bsec_optee_ta_match, NULL, NULL); -+ if (IS_ERR(tee_ctx)) { -+ rc = PTR_ERR(tee_ctx); -+ if (rc == -ENOENT) -+ return -EPROBE_DEFER; -+ pr_err("%s: tee_client_open_context failed (%d)\n", __func__, rc); -+ -+ return rc; -+ } -+ -+ /* Check STM32MP BSEC TA presence */ -+ rc = stm32_bsec_ta_open_session(tee_ctx, &session_id); -+ if (rc) { -+ tee_client_close_context(tee_ctx); -+ return rc; -+ } -+ -+ stm32_bsec_ta_close_session(tee_ctx, session_id); -+ -+ *ctx = tee_ctx; -+ -+ return 0; -+} -+ -+/* stm32_bsec_optee_ta_open() - release the PTA STM32MP BSEC TA */ -+void stm32_bsec_optee_ta_close(void *ctx) -+{ -+ tee_client_close_context(ctx); -+} -+ -+/* stm32_bsec_optee_ta_read() - nvmem read access using PTA client driver */ -+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ struct tee_shm *shm; -+ struct tee_ioctl_invoke_arg arg; -+ struct tee_param param[2]; -+ u8 *shm_buf; -+ u32 start, num_bytes; -+ int ret; -+ u32 session_id; -+ -+ ret = stm32_bsec_ta_open_session(ctx, &session_id); -+ if (ret) -+ return ret; -+ -+ memset(&arg, 0, sizeof(arg)); -+ memset(¶m, 0, sizeof(param)); -+ -+ arg.func = PTA_BSEC_READ_MEM; -+ arg.session = session_id; -+ arg.num_params = 2; -+ -+ /* align access on 32bits */ -+ start = ALIGN_DOWN(offset, 4); -+ num_bytes = round_up(offset + bytes - start, 4); -+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; -+ param[0].u.value.a = start; -+ param[0].u.value.b = SHADOW_ACCESS; -+ -+ shm = tee_shm_alloc_kernel_buf(ctx, num_bytes); -+ if (IS_ERR(shm)) { -+ ret = PTR_ERR(shm); -+ goto out_tee_session; -+ } -+ -+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; -+ param[1].u.memref.shm = shm; -+ param[1].u.memref.size = num_bytes; -+ -+ ret = tee_client_invoke_func(ctx, &arg, param); -+ if (ret < 0 || arg.ret != 0) { -+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", -+ arg.ret, ret); -+ if (!ret) -+ ret = -EIO; -+ } -+ if (!ret) { -+ shm_buf = tee_shm_get_va(shm, 0); -+ if (IS_ERR(shm_buf)) { -+ ret = PTR_ERR(shm_buf); -+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret); -+ } else { -+ /* read data from 32 bits aligned buffer */ -+ memcpy(buf, &shm_buf[offset % 4], bytes); -+ } -+ } -+ -+ tee_shm_free(shm); -+ -+out_tee_session: -+ stm32_bsec_ta_close_session(ctx, session_id); -+ -+ return ret; -+} -+ -+/* stm32_bsec_optee_ta_write() - nvmem write access using PTA client driver */ -+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower, -+ unsigned int offset, void *buf, size_t bytes) -+{ struct tee_shm *shm; -+ struct tee_ioctl_invoke_arg arg; -+ struct tee_param param[2]; -+ u8 *shm_buf; -+ int ret; -+ u32 session_id; -+ -+ ret = stm32_bsec_ta_open_session(ctx, &session_id); -+ if (ret) -+ return ret; -+ -+ /* Allow only writing complete 32-bits aligned words */ -+ if ((bytes % 4) || (offset % 4)) -+ return -EINVAL; -+ -+ memset(&arg, 0, sizeof(arg)); -+ memset(¶m, 0, sizeof(param)); -+ -+ arg.func = PTA_BSEC_WRITE_MEM; -+ arg.session = session_id; -+ arg.num_params = 2; -+ -+ param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; -+ param[0].u.value.a = offset; -+ param[0].u.value.b = FUSE_ACCESS; -+ -+ shm = tee_shm_alloc_kernel_buf(ctx, bytes); -+ if (IS_ERR(shm)) { -+ ret = PTR_ERR(shm); -+ goto out_tee_session; -+ } -+ -+ param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; -+ param[1].u.memref.shm = shm; -+ param[1].u.memref.size = bytes; -+ -+ shm_buf = tee_shm_get_va(shm, 0); -+ if (IS_ERR(shm_buf)) { -+ ret = PTR_ERR(shm_buf); -+ pr_err("tee_shm_get_va failed for transmit (%d)\n", ret); -+ tee_shm_free(shm); -+ -+ goto out_tee_session; -+ } -+ -+ memcpy(shm_buf, buf, bytes); -+ -+ ret = tee_client_invoke_func(ctx, &arg, param); -+ if (ret < 0 || arg.ret != 0) { -+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret); -+ if (!ret) -+ ret = -EIO; -+ } -+ pr_debug("Write OTPs %d to %zu, ret=%d\n", offset / 4, (offset + bytes) / 4, ret); -+ -+ /* Lock the upper OTPs with ECC protection, word programming only */ -+ if (!ret && ((offset + bytes) >= (lower * 4))) { -+ u32 start, nb_lock; -+ u32 *lock = (u32 *)shm_buf; -+ int i; -+ -+ /* -+ * don't lock the lower OTPs, no ECC protection and incremental -+ * bit programming, a second write is allowed -+ */ -+ start = max_t(u32, offset, lower * 4); -+ nb_lock = (offset + bytes - start) / 4; -+ -+ param[0].u.value.a = start; -+ param[0].u.value.b = LOCK_ACCESS; -+ param[1].u.memref.size = nb_lock * 4; -+ -+ for (i = 0; i < nb_lock; i++) -+ lock[i] = LOCK_PERM; -+ -+ ret = tee_client_invoke_func(ctx, &arg, param); -+ if (ret < 0 || arg.ret != 0) { -+ pr_err("TA_BSEC invoke failed TEE err:%#x, ret:%#x\n", arg.ret, ret); -+ if (!ret) -+ ret = -EIO; -+ } -+ pr_debug("Lock upper OTPs %d to %d, ret=%d\n", -+ start / 4, start / 4 + nb_lock, ret); -+ } -+ -+ tee_shm_free(shm); -+ -+out_tee_session: -+ stm32_bsec_ta_close_session(ctx, session_id); -+ -+ return ret; -+} ---- /dev/null -+++ b/drivers/nvmem/stm32-bsec-optee-ta.h -@@ -0,0 +1,80 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+/* -+ * OP-TEE STM32MP BSEC PTA interface, used by STM32 ROMEM driver -+ * -+ * Copyright (C) 2022, STMicroelectronics - All Rights Reserved -+ */ -+ -+#if IS_ENABLED(CONFIG_NVMEM_STM32_BSEC_OPTEE_TA) -+/** -+ * stm32_bsec_optee_ta_open() - initialize the STM32 BSEC TA -+ * @ctx: the OP-TEE context on success -+ * -+ * Return: -+ * On success, 0. On failure, -errno. -+ */ -+int stm32_bsec_optee_ta_open(struct tee_context **ctx); -+ -+/** -+ * stm32_bsec_optee_ta_close() - release the STM32 BSEC TA -+ * @ctx: the OP-TEE context -+ * -+ * This function used to clean the OP-TEE resources initialized in -+ * stm32_bsec_optee_ta_open(); it can be used as callback to -+ * devm_add_action_or_reset() -+ */ -+void stm32_bsec_optee_ta_close(void *ctx); -+ -+/** -+ * stm32_bsec_optee_ta_read() - nvmem read access using TA client driver -+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open -+ * @offset: nvmem offset -+ * @buf: buffer to fill with nvem values -+ * @bytes: number of bytes to read -+ * -+ * Return: -+ * On success, 0. On failure, -errno. -+ */ -+int stm32_bsec_optee_ta_read(struct tee_context *ctx, unsigned int offset, -+ void *buf, size_t bytes); -+ -+/** -+ * stm32_bsec_optee_ta_write() - nvmem write access using TA client driver -+ * @ctx: the OP-TEE context provided by stm32_bsec_optee_ta_open -+ * @lower: number of lower OTP, not protected by ECC -+ * @offset: nvmem offset -+ * @buf: buffer with nvem values -+ * @bytes: number of bytes to write -+ * -+ * Return: -+ * On success, 0. On failure, -errno. -+ */ -+int stm32_bsec_optee_ta_write(struct tee_context *ctx, unsigned int lower, -+ unsigned int offset, void *buf, size_t bytes); -+ -+#else -+ -+static inline int stm32_bsec_optee_ta_open(struct tee_context **ctx) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void stm32_bsec_optee_ta_close(void *ctx) -+{ -+} -+ -+static inline int stm32_bsec_optee_ta_read(struct tee_context *ctx, -+ unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline int stm32_bsec_optee_ta_write(struct tee_context *ctx, -+ unsigned int lower, -+ unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ return -EOPNOTSUPP; -+} -+#endif /* CONFIG_NVMEM_STM32_BSEC_OPTEE_TA */ ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -11,6 +11,9 @@ - #include - #include - #include -+#include -+ -+#include "stm32-bsec-optee-ta.h" - - /* BSEC secure service access from non-secure */ - #define STM32_SMC_BSEC 0x82001003 -@@ -25,12 +28,14 @@ - struct stm32_romem_cfg { - int size; - u8 lower; -+ bool ta; - }; - - struct stm32_romem_priv { - void __iomem *base; - struct nvmem_config cfg; - u8 lower; -+ struct tee_context *ctx; - }; - - static int stm32_romem_read(void *context, unsigned int offset, void *buf, -@@ -138,12 +143,29 @@ static int stm32_bsec_write(void *contex - return 0; - } - -+static int stm32_bsec_pta_read(void *context, unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ struct stm32_romem_priv *priv = context; -+ -+ return stm32_bsec_optee_ta_read(priv->ctx, offset, buf, bytes); -+} -+ -+static int stm32_bsec_pta_write(void *context, unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ struct stm32_romem_priv *priv = context; -+ -+ return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes); -+} -+ - static int stm32_romem_probe(struct platform_device *pdev) - { - const struct stm32_romem_cfg *cfg; - struct device *dev = &pdev->dev; - struct stm32_romem_priv *priv; - struct resource *res; -+ int rc; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -173,15 +195,31 @@ static int stm32_romem_probe(struct plat - } else { - priv->cfg.size = cfg->size; - priv->lower = cfg->lower; -- priv->cfg.reg_read = stm32_bsec_read; -- priv->cfg.reg_write = stm32_bsec_write; -+ if (cfg->ta) { -+ rc = stm32_bsec_optee_ta_open(&priv->ctx); -+ /* wait for OP-TEE client driver to be up and ready */ -+ if (rc) -+ return rc; -+ } -+ if (priv->ctx) { -+ rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx); -+ if (rc) { -+ dev_err(dev, "devm_add_action_or_reset() failed (%d)\n", rc); -+ return rc; -+ } -+ priv->cfg.reg_read = stm32_bsec_pta_read; -+ priv->cfg.reg_write = stm32_bsec_pta_write; -+ } else { -+ priv->cfg.reg_read = stm32_bsec_read; -+ priv->cfg.reg_write = stm32_bsec_write; -+ } - } - - return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &priv->cfg)); - } - - /* -- * STM32MP15 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) -+ * STM32MP15/13 BSEC OTP regions: 4096 OTP bits (with 3072 effective bits) - * => 96 x 32-bits data words - * - Lower: 1K bits, 2:1 redundancy, incremental bit programming - * => 32 (x 32-bits) lower shadow registers = words 0 to 31 -@@ -191,6 +229,13 @@ static int stm32_romem_probe(struct plat - static const struct stm32_romem_cfg stm32mp15_bsec_cfg = { - .size = 384, - .lower = 32, -+ .ta = false, -+}; -+ -+static const struct stm32_romem_cfg stm32mp13_bsec_cfg = { -+ .size = 384, -+ .lower = 32, -+ .ta = true, - }; - - static const struct of_device_id stm32_romem_of_match[] = { -@@ -198,7 +243,10 @@ static const struct of_device_id stm32_r - .compatible = "st,stm32mp15-bsec", - .data = (void *)&stm32mp15_bsec_cfg, - }, { -+ .compatible = "st,stm32mp13-bsec", -+ .data = (void *)&stm32mp13_bsec_cfg, - }, -+ { /* sentinel */ }, - }; - MODULE_DEVICE_TABLE(of, stm32_romem_of_match); - diff --git a/target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch b/target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch deleted file mode 100644 index cea8e93858fc7d..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0008-nvmem-stm32-detect-bsec-pta-presence-for-STM32MP15x.patch +++ /dev/null @@ -1,85 +0,0 @@ -From df2f34ef1d924125ffaf29dfdaf7cdbd3183c321 Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Mon, 6 Feb 2023 13:43:52 +0000 -Subject: [PATCH] nvmem: stm32: detect bsec pta presence for STM32MP15x - -On STM32MP15x SoC, the SMC backend is optional when OP-TEE is used; -the PTA BSEC should be used as it is done on STM32MP13x platform, -but the BSEC SMC can be also used: it is a legacy mode in OP-TEE, -not recommended but used in previous OP-TEE firmware. - -The presence of OP-TEE is dynamically detected in STM32MP15x device tree -and the supported NVMEM backend is dynamically detected: -- PTA with stm32_bsec_pta_find -- SMC with stm32_bsec_check - -With OP-TEE but without PTA and SMC detection, the probe is deferred for -STM32MP15x devices. - -On STM32MP13x platform, only the PTA is supported with cfg->ta = true -and this detection is skipped. - -Signed-off-by: Patrick Delaunay -Reviewed-by: Etienne Carriere -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-19-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 38 +++++++++++++++++++++++++++++++++---- - 1 file changed, 34 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -159,6 +159,31 @@ static int stm32_bsec_pta_write(void *co - return stm32_bsec_optee_ta_write(priv->ctx, priv->lower, offset, buf, bytes); - } - -+static bool stm32_bsec_smc_check(void) -+{ -+ u32 val; -+ int ret; -+ -+ /* check that the OP-TEE support the BSEC SMC (legacy mode) */ -+ ret = stm32_bsec_smc(STM32_SMC_READ_SHADOW, 0, 0, &val); -+ -+ return !ret; -+} -+ -+static bool optee_presence_check(void) -+{ -+ struct device_node *np; -+ bool tee_detected = false; -+ -+ /* check that the OP-TEE node is present and available. */ -+ np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz"); -+ if (np && of_device_is_available(np)) -+ tee_detected = true; -+ of_node_put(np); -+ -+ return tee_detected; -+} -+ - static int stm32_romem_probe(struct platform_device *pdev) - { - const struct stm32_romem_cfg *cfg; -@@ -195,11 +220,16 @@ static int stm32_romem_probe(struct plat - } else { - priv->cfg.size = cfg->size; - priv->lower = cfg->lower; -- if (cfg->ta) { -+ if (cfg->ta || optee_presence_check()) { - rc = stm32_bsec_optee_ta_open(&priv->ctx); -- /* wait for OP-TEE client driver to be up and ready */ -- if (rc) -- return rc; -+ if (rc) { -+ /* wait for OP-TEE client driver to be up and ready */ -+ if (rc == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ /* BSEC PTA is required or SMC not supported */ -+ if (cfg->ta || !stm32_bsec_smc_check()) -+ return rc; -+ } - } - if (priv->ctx) { - rc = devm_add_action_or_reset(dev, stm32_bsec_optee_ta_close, priv->ctx); diff --git a/target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch b/target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch deleted file mode 100644 index 9d6275a737bccb..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0009-nvmem-rave-sp-eeprm-fix-kernel-doc-bad-line-warning.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3e5ac22aa564026e99defc3a8e02082521a5b231 Mon Sep 17 00:00:00 2001 -From: Randy Dunlap -Date: Mon, 6 Feb 2023 13:43:53 +0000 -Subject: [PATCH] nvmem: rave-sp-eeprm: fix kernel-doc bad line warning - -Convert an empty line to " *" to avoid a kernel-doc warning: - -drivers/nvmem/rave-sp-eeprom.c:48: warning: bad line: - -Signed-off-by: Randy Dunlap -Cc: Srinivas Kandagatla -Cc: Andrey Vostrikov -Cc: Nikita Yushchenko -Cc: Andrey Smirnov -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-20-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rave-sp-eeprom.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/rave-sp-eeprom.c -+++ b/drivers/nvmem/rave-sp-eeprom.c -@@ -45,7 +45,7 @@ enum rave_sp_eeprom_header_size { - * @type: Access type (see enum rave_sp_eeprom_access_type) - * @success: Success flag (Success = 1, Failure = 0) - * @data: Read data -- -+ * - * Note this structure corresponds to RSP_*_EEPROM payload from RAVE - * SP ICD - */ diff --git a/target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch b/target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch deleted file mode 100644 index 1ab9e609d33c91..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0010-nvmem-qcom-spmi-sdam-register-at-device-init-time.patch +++ /dev/null @@ -1,43 +0,0 @@ -From eb7dda20f42a9137e9ee53d5ed3b743d49338cb5 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Mon, 6 Feb 2023 13:43:54 +0000 -Subject: [PATCH] nvmem: qcom-spmi-sdam: register at device init time - -There are currently no in-tree users of the Qualcomm SDAM nvmem driver -and there is generally no point in registering a driver that can be -built as a module at subsys init time. - -Register the driver at the normal device init time instead and let -driver core sort out the probe order. - -Signed-off-by: Johan Hovold -Reviewed-by: Bjorn Andersson -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-21-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/qcom-spmi-sdam.c | 13 +------------ - 1 file changed, 1 insertion(+), 12 deletions(-) - ---- a/drivers/nvmem/qcom-spmi-sdam.c -+++ b/drivers/nvmem/qcom-spmi-sdam.c -@@ -175,18 +175,7 @@ static struct platform_driver sdam_drive - }, - .probe = sdam_probe, - }; -- --static int __init sdam_init(void) --{ -- return platform_driver_register(&sdam_driver); --} --subsys_initcall(sdam_init); -- --static void __exit sdam_exit(void) --{ -- return platform_driver_unregister(&sdam_driver); --} --module_exit(sdam_exit); -+module_platform_driver(sdam_driver); - - MODULE_DESCRIPTION("QCOM SPMI SDAM driver"); - MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch b/target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch deleted file mode 100644 index dcf704c6ffbbfa..00000000000000 --- a/target/linux/generic/backport-6.1/809-v6.3-0011-nvmem-stm32-fix-OPTEE-dependency.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 1dc7e37bb0ec1c997fac82031332a38c7610352f Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Mon, 6 Feb 2023 13:43:56 +0000 -Subject: [PATCH] nvmem: stm32: fix OPTEE dependency - -The stm32 nvmem driver fails to link as built-in when OPTEE -is a loadable module: - -aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec: -stm32-bsec-optee-ta.c:(.text+0xc8): undefined reference to `tee_client_open_session' -aarch64-linux-ld: drivers/nvmem/stm32-bsec-optee-ta.o: in function `stm32_bsec: -stm32-bsec-optee-ta.c:(.text+0x1fc): undefined reference to `tee_client_open_context' - -Change the CONFIG_NVMEM_STM32_ROMEM definition so it can only -be built-in if OPTEE is either built-in or disabled, and -make NVMEM_STM32_BSEC_OPTEE_TA a hidden symbol instead. - -Signed-off-by: Arnd Bergmann -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-23-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -291,8 +291,7 @@ config NVMEM_SPRD_EFUSE - will be called nvmem-sprd-efuse. - - config NVMEM_STM32_BSEC_OPTEE_TA -- bool "STM32MP BSEC OP-TEE TA support for nvmem-stm32-romem driver" -- depends on OPTEE -+ def_bool NVMEM_STM32_ROMEM && OPTEE - help - Say y here to enable the accesses to STM32MP SoC OTPs by the OP-TEE - trusted application STM32MP BSEC. -@@ -303,7 +302,7 @@ config NVMEM_STM32_BSEC_OPTEE_TA - config NVMEM_STM32_ROMEM - tristate "STMicroelectronics STM32 factory-programmed memory support" - depends on ARCH_STM32 || COMPILE_TEST -- imply NVMEM_STM32_BSEC_OPTEE_TA -+ depends on OPTEE || !OPTEE - help - Say y here to enable read-only access for STMicroelectronics STM32 - factory-programmed memory area. diff --git a/target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch b/target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch deleted file mode 100644 index 998e4534436781..00000000000000 --- a/target/linux/generic/backport-6.1/810-v6.3-i915-Move-list_count-to-list.h-as-list_count_nodes-f.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 4d70c74659d9746502b23d055dba03d1d28ec388 Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Wed, 30 Nov 2022 15:48:35 +0200 -Subject: [PATCH] i915: Move list_count() to list.h as list_count_nodes() for - broader use - -Some of the existing users, and definitely will be new ones, want to -count existing nodes in the list. Provide a generic API for that by -moving code from i915 to list.h. - -Reviewed-by: Lucas De Marchi -Acked-by: Jani Nikula -Signed-off-by: Andy Shevchenko -Link: https://lore.kernel.org/r/20221130134838.23805-1-andriy.shevchenko@linux.intel.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/gpu/drm/i915/gt/intel_engine_cs.c | 15 ++------------- - include/linux/list.h | 15 +++++++++++++++ - 2 files changed, 17 insertions(+), 13 deletions(-) - ---- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c -+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c -@@ -4153,17 +4153,6 @@ void intel_execlists_show_requests(struc - spin_unlock_irqrestore(&sched_engine->lock, flags); - } - --static unsigned long list_count(struct list_head *list) --{ -- struct list_head *pos; -- unsigned long count = 0; -- -- list_for_each(pos, list) -- count++; -- -- return count; --} -- - void intel_execlists_dump_active_requests(struct intel_engine_cs *engine, - struct i915_request *hung_rq, - struct drm_printer *m) -@@ -4174,8 +4163,8 @@ void intel_execlists_dump_active_request - - intel_engine_dump_active_requests(&engine->sched_engine->requests, hung_rq, m); - -- drm_printf(m, "\tOn hold?: %lu\n", -- list_count(&engine->sched_engine->hold)); -+ drm_printf(m, "\tOn hold?: %zu\n", -+ list_count_nodes(&engine->sched_engine->hold)); - - spin_unlock_irqrestore(&engine->sched_engine->lock, flags); - } ---- a/include/linux/list.h -+++ b/include/linux/list.h -@@ -656,6 +656,21 @@ static inline void list_splice_tail_init - pos = n, n = pos->prev) - - /** -+ * list_count_nodes - count nodes in the list -+ * @head: the head for your list. -+ */ -+static inline size_t list_count_nodes(struct list_head *head) -+{ -+ struct list_head *pos; -+ size_t count = 0; -+ -+ list_for_each(pos, head) -+ count++; -+ -+ return count; -+} -+ -+/** - * list_entry_is_head - test if the entry points to the head of the list - * @pos: the type * to cursor - * @head: the head for your list. diff --git a/target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch b/target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch deleted file mode 100644 index 8328e87c0af7a4..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0001-nvmem-xilinx-zynqmp-make-modular.patch +++ /dev/null @@ -1,35 +0,0 @@ -From bcd1fe07def0f070eb5f31594620aaee6f81d31a Mon Sep 17 00:00:00 2001 -From: Nick Alcock -Date: Tue, 4 Apr 2023 18:21:11 +0100 -Subject: [PATCH] nvmem: xilinx: zynqmp: make modular - -This driver has a MODULE_LICENSE but is not tristate so cannot be -built as a module, unlike all its peers: make it modular to match. - -Signed-off-by: Nick Alcock -Suggested-by: Michal Simek -Cc: Luis Chamberlain -Cc: linux-modules@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Cc: Hitomi Hasegawa -Cc: Srinivas Kandagatla -Cc: Michal Simek -Cc: linux-arm-kernel@lists.infradead.org -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -368,7 +368,7 @@ config NVMEM_VF610_OCOTP - be called nvmem-vf610-ocotp. - - config NVMEM_ZYNQMP -- bool "Xilinx ZYNQMP SoC nvmem firmware support" -+ tristate "Xilinx ZYNQMP SoC nvmem firmware support" - depends on ARCH_ZYNQMP - help - This is a driver to access hardware related data like diff --git a/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch b/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch deleted file mode 100644 index 77d2af7269c277..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0002-nvmem-core-introduce-NVMEM-layouts.patch +++ /dev/null @@ -1,387 +0,0 @@ -From 266570f496b90dea8fda893c2cf7c28d63ae2bd9 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:21 +0100 -Subject: [PATCH] nvmem: core: introduce NVMEM layouts - -NVMEM layouts are used to generate NVMEM cells during runtime. Think of -an EEPROM with a well-defined conent. For now, the content can be -described by a device tree or a board file. But this only works if the -offsets and lengths are static and don't change. One could also argue -that putting the layout of the EEPROM in the device tree is the wrong -place. Instead, the device tree should just have a specific compatible -string. - -Right now there are two use cases: - (1) The NVMEM cell needs special processing. E.g. if it only specifies - a base MAC address offset and you need to add an offset, or it - needs to parse a MAC from ASCII format or some proprietary format. - (Post processing of cells is added in a later commit). - (2) u-boot environment parsing. The cells don't have a particular - offset but it needs parsing the content to determine the offsets - and length. - -Co-developed-by: Miquel Raynal -Signed-off-by: Miquel Raynal -Signed-off-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-14-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - Documentation/driver-api/nvmem.rst | 15 ++++ - drivers/nvmem/Kconfig | 4 + - drivers/nvmem/Makefile | 1 + - drivers/nvmem/core.c | 120 +++++++++++++++++++++++++++++ - drivers/nvmem/layouts/Kconfig | 5 ++ - drivers/nvmem/layouts/Makefile | 4 + - include/linux/nvmem-consumer.h | 7 ++ - include/linux/nvmem-provider.h | 51 ++++++++++++ - 8 files changed, 207 insertions(+) - create mode 100644 drivers/nvmem/layouts/Kconfig - create mode 100644 drivers/nvmem/layouts/Makefile - ---- a/Documentation/driver-api/nvmem.rst -+++ b/Documentation/driver-api/nvmem.rst -@@ -185,3 +185,18 @@ ex:: - ===================== - - See Documentation/devicetree/bindings/nvmem/nvmem.txt -+ -+8. NVMEM layouts -+================ -+ -+NVMEM layouts are yet another mechanism to create cells. With the device -+tree binding it is possible to specify simple cells by using an offset -+and a length. Sometimes, the cells doesn't have a static offset, but -+the content is still well defined, e.g. tag-length-values. In this case, -+the NVMEM device content has to be first parsed and the cells need to -+be added accordingly. Layouts let you read the content of the NVMEM device -+and let you add cells dynamically. -+ -+Another use case for layouts is the post processing of cells. With layouts, -+it is possible to associate a custom post processing hook to a cell. It -+even possible to add this hook to cells not created by the layout itself. ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -21,6 +21,10 @@ config NVMEM_SYSFS - This interface is mostly used by userspace applications to - read/write directly into nvmem. - -+# Layouts -+ -+source "drivers/nvmem/layouts/Kconfig" -+ - # Devices - - config NVMEM_APPLE_EFUSES ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -5,6 +5,7 @@ - - obj-$(CONFIG_NVMEM) += nvmem_core.o - nvmem_core-y := core.o -+obj-y += layouts/ - - # Devices - obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -40,6 +40,7 @@ struct nvmem_device { - nvmem_reg_write_t reg_write; - nvmem_cell_post_process_t cell_post_process; - struct gpio_desc *wp_gpio; -+ struct nvmem_layout *layout; - void *priv; - }; - -@@ -74,6 +75,9 @@ static LIST_HEAD(nvmem_lookup_list); - - static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); - -+static DEFINE_SPINLOCK(nvmem_layout_lock); -+static LIST_HEAD(nvmem_layouts); -+ - static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, - void *val, size_t bytes) - { -@@ -727,6 +731,101 @@ static int nvmem_add_cells_from_of(struc - return 0; - } - -+int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner) -+{ -+ layout->owner = owner; -+ -+ spin_lock(&nvmem_layout_lock); -+ list_add(&layout->node, &nvmem_layouts); -+ spin_unlock(&nvmem_layout_lock); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(__nvmem_layout_register); -+ -+void nvmem_layout_unregister(struct nvmem_layout *layout) -+{ -+ spin_lock(&nvmem_layout_lock); -+ list_del(&layout->node); -+ spin_unlock(&nvmem_layout_lock); -+} -+EXPORT_SYMBOL_GPL(nvmem_layout_unregister); -+ -+static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) -+{ -+ struct device_node *layout_np, *np = nvmem->dev.of_node; -+ struct nvmem_layout *l, *layout = NULL; -+ -+ layout_np = of_get_child_by_name(np, "nvmem-layout"); -+ if (!layout_np) -+ return NULL; -+ -+ spin_lock(&nvmem_layout_lock); -+ -+ list_for_each_entry(l, &nvmem_layouts, node) { -+ if (of_match_node(l->of_match_table, layout_np)) { -+ if (try_module_get(l->owner)) -+ layout = l; -+ -+ break; -+ } -+ } -+ -+ spin_unlock(&nvmem_layout_lock); -+ of_node_put(layout_np); -+ -+ return layout; -+} -+ -+static void nvmem_layout_put(struct nvmem_layout *layout) -+{ -+ if (layout) -+ module_put(layout->owner); -+} -+ -+static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem) -+{ -+ struct nvmem_layout *layout = nvmem->layout; -+ int ret; -+ -+ if (layout && layout->add_cells) { -+ ret = layout->add_cells(&nvmem->dev, nvmem, layout); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+#if IS_ENABLED(CONFIG_OF) -+/** -+ * of_nvmem_layout_get_container() - Get OF node to layout container. -+ * -+ * @nvmem: nvmem device. -+ * -+ * Return: a node pointer with refcount incremented or NULL if no -+ * container exists. Use of_node_put() on it when done. -+ */ -+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) -+{ -+ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); -+} -+EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container); -+#endif -+ -+const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout) -+{ -+ struct device_node __maybe_unused *layout_np; -+ const struct of_device_id *match; -+ -+ layout_np = of_nvmem_layout_get_container(nvmem); -+ match = of_match_node(layout->of_match_table, layout_np); -+ -+ return match ? match->data : NULL; -+} -+EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data); -+ - /** - * nvmem_register() - Register a nvmem device for given nvmem_config. - * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem -@@ -833,6 +932,12 @@ struct nvmem_device *nvmem_register(cons - goto err_put_device; - } - -+ /* -+ * If the driver supplied a layout by config->layout, the module -+ * pointer will be NULL and nvmem_layout_put() will be a noop. -+ */ -+ nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); -+ - if (config->cells) { - rval = nvmem_add_cells(nvmem, config->cells, config->ncells); - if (rval) -@@ -853,12 +958,17 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -+ rval = nvmem_add_cells_from_layout(nvmem); -+ if (rval) -+ goto err_remove_cells; -+ - blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); - - return nvmem; - - err_remove_cells: - nvmem_device_remove_all_cells(nvmem); -+ nvmem_layout_put(nvmem->layout); - if (config->compat) - nvmem_sysfs_remove_compat(nvmem, config); - err_put_device: -@@ -880,6 +990,7 @@ static void nvmem_device_release(struct - device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); - - nvmem_device_remove_all_cells(nvmem); -+ nvmem_layout_put(nvmem->layout); - device_unregister(&nvmem->dev); - } - -@@ -1245,6 +1356,15 @@ struct nvmem_cell *of_nvmem_cell_get(str - return ERR_PTR(-EINVAL); - } - -+ /* nvmem layouts produce cells within the nvmem-layout container */ -+ if (of_node_name_eq(nvmem_np, "nvmem-layout")) { -+ nvmem_np = of_get_next_parent(nvmem_np); -+ if (!nvmem_np) { -+ of_node_put(cell_np); -+ return ERR_PTR(-EINVAL); -+ } -+ } -+ - nvmem = __nvmem_device_get(nvmem_np, device_match_of_node); - of_node_put(nvmem_np); - if (IS_ERR(nvmem)) { ---- /dev/null -+++ b/drivers/nvmem/layouts/Kconfig -@@ -0,0 +1,5 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+menu "Layout Types" -+ -+endmenu ---- /dev/null -+++ b/drivers/nvmem/layouts/Makefile -@@ -0,0 +1,4 @@ -+# SPDX-License-Identifier: GPL-2.0 -+# -+# Makefile for nvmem layouts. -+# ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -239,6 +239,7 @@ struct nvmem_cell *of_nvmem_cell_get(str - const char *id); - struct nvmem_device *of_nvmem_device_get(struct device_node *np, - const char *name); -+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem); - #else - static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, - const char *id) -@@ -251,6 +252,12 @@ static inline struct nvmem_device *of_nv - { - return ERR_PTR(-EOPNOTSUPP); - } -+ -+static inline struct device_node * -+of_nvmem_layout_get_container(struct nvmem_device *nvmem) -+{ -+ return ERR_PTR(-EOPNOTSUPP); -+} - #endif /* CONFIG_NVMEM && CONFIG_OF */ - - #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */ ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -88,6 +88,7 @@ struct nvmem_cell_info { - * @stride: Minimum read/write access stride. - * @priv: User context passed to read/write callbacks. - * @ignore_wp: Write Protect pin is managed by the provider. -+ * @layout: Fixed layout associated with this nvmem device. - * - * Note: A default "nvmem" name will be assigned to the device if - * no name is specified in its configuration. In such case "" is -@@ -109,6 +110,7 @@ struct nvmem_config { - bool read_only; - bool root_only; - bool ignore_wp; -+ struct nvmem_layout *layout; - struct device_node *of_node; - bool no_of_node; - nvmem_reg_read_t reg_read; -@@ -142,6 +144,33 @@ struct nvmem_cell_table { - struct list_head node; - }; - -+/** -+ * struct nvmem_layout - NVMEM layout definitions -+ * -+ * @name: Layout name. -+ * @of_match_table: Open firmware match table. -+ * @add_cells: Will be called if a nvmem device is found which -+ * has this layout. The function will add layout -+ * specific cells with nvmem_add_one_cell(). -+ * @owner: Pointer to struct module. -+ * @node: List node. -+ * -+ * A nvmem device can hold a well defined structure which can just be -+ * evaluated during runtime. For example a TLV list, or a list of "name=val" -+ * pairs. A nvmem layout can parse the nvmem device and add appropriate -+ * cells. -+ */ -+struct nvmem_layout { -+ const char *name; -+ const struct of_device_id *of_match_table; -+ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, -+ struct nvmem_layout *layout); -+ -+ /* private */ -+ struct module *owner; -+ struct list_head node; -+}; -+ - #if IS_ENABLED(CONFIG_NVMEM) - - struct nvmem_device *nvmem_register(const struct nvmem_config *cfg); -@@ -156,6 +185,14 @@ void nvmem_del_cell_table(struct nvmem_c - int nvmem_add_one_cell(struct nvmem_device *nvmem, - const struct nvmem_cell_info *info); - -+int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner); -+#define nvmem_layout_register(layout) \ -+ __nvmem_layout_register(layout, THIS_MODULE) -+void nvmem_layout_unregister(struct nvmem_layout *layout); -+ -+const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout); -+ - #else - - static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) -@@ -179,5 +216,19 @@ static inline int nvmem_add_one_cell(str - return -EOPNOTSUPP; - } - -+static inline int nvmem_layout_register(struct nvmem_layout *layout) -+{ -+ return -EOPNOTSUPP; -+} -+ -+static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {} -+ -+static inline const void * -+nvmem_layout_get_match_data(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout) -+{ -+ return NULL; -+} -+ - #endif /* CONFIG_NVMEM */ - #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch b/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch deleted file mode 100644 index 40ce320b6e3368..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 6468a6f45148fb5e95c86b4efebf63f9abcd2137 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:22 +0100 -Subject: [PATCH] nvmem: core: handle the absence of expected layouts - -Make nvmem_layout_get() return -EPROBE_DEFER while the expected layout -is not available. This condition cannot be triggered today as nvmem -layout drivers are initialed as part of an early init call, but soon -these drivers will be converted into modules and be initialized with a -standard priority, so the unavailability of the drivers might become a -reality that must be taken care of. - -Let's anticipate this by telling the caller the layout might not yet be -available. A probe deferral is requested in this case. - -Please note this does not affect any nvmem device not using layouts, -because an early check against the "nvmem-layout" container presence -will return NULL in this case. - -Signed-off-by: Miquel Raynal -Tested-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-15-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -754,7 +754,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste - static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) - { - struct device_node *layout_np, *np = nvmem->dev.of_node; -- struct nvmem_layout *l, *layout = NULL; -+ struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER); - - layout_np = of_get_child_by_name(np, "nvmem-layout"); - if (!layout_np) -@@ -937,6 +937,13 @@ struct nvmem_device *nvmem_register(cons - * pointer will be NULL and nvmem_layout_put() will be a noop. - */ - nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); -+ if (IS_ERR(nvmem->layout)) { -+ rval = PTR_ERR(nvmem->layout); -+ nvmem->layout = NULL; -+ -+ if (rval == -EPROBE_DEFER) -+ goto err_teardown_compat; -+ } - - if (config->cells) { - rval = nvmem_add_cells(nvmem, config->cells, config->ncells); -@@ -969,6 +976,7 @@ struct nvmem_device *nvmem_register(cons - err_remove_cells: - nvmem_device_remove_all_cells(nvmem); - nvmem_layout_put(nvmem->layout); -+err_teardown_compat: - if (config->compat) - nvmem_sysfs_remove_compat(nvmem, config); - err_put_device: diff --git a/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch b/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch deleted file mode 100644 index 13712d76c65960..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0004-nvmem-core-request-layout-modules-loading.patch +++ /dev/null @@ -1,52 +0,0 @@ -From b1c37bec1ccfe5ccab72bc0ddc0dfa45c43e2de2 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:23 +0100 -Subject: [PATCH] nvmem: core: request layout modules loading - -When a storage device like an eeprom or an mtd device probes, it -registers an nvmem device if the nvmem subsystem has been enabled (bool -symbol). During nvmem registration, if the device is using layouts to -expose dynamic nvmem cells, the core will first try to get a reference -over the layout driver callbacks. In practice there is not relationship -that can be described between the storage driver and the nvmem -layout. So there is no way we can enforce both drivers will be built-in -or both will be modules. If the storage device driver is built-in but -the layout is built as a module, instead of badly failing with an -endless probe deferral loop, lets just make a modprobe call in case the -driver was made available in an initramfs with -of_device_node_request_module(), and offer a fully functional system to -the user. - -Signed-off-by: Miquel Raynal -Tested-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-16-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - - struct nvmem_device { -@@ -760,6 +761,13 @@ static struct nvmem_layout *nvmem_layout - if (!layout_np) - return NULL; - -+ /* -+ * In case the nvmem device was built-in while the layout was built as a -+ * module, we shall manually request the layout driver loading otherwise -+ * we'll never have any match. -+ */ -+ of_request_module(layout_np); -+ - spin_lock(&nvmem_layout_lock); - - list_for_each_entry(l, &nvmem_layouts, node) { diff --git a/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch b/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch deleted file mode 100644 index 50f3504132b612..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0005-nvmem-core-add-per-cell-post-processing.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 345ec382cd4b736c36e01f155d08c913b225b736 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:24 +0100 -Subject: [PATCH] nvmem: core: add per-cell post processing - -Instead of relying on the name the consumer is using for the cell, like -it is done for the nvmem .cell_post_process configuration parameter, -provide a per-cell post processing hook. This can then be populated by -the NVMEM provider (or the NVMEM layout) when adding the cell. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-17-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 17 +++++++++++++++++ - include/linux/nvmem-provider.h | 3 +++ - 2 files changed, 20 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -54,6 +54,7 @@ struct nvmem_cell_entry { - int bytes; - int bit_offset; - int nbits; -+ nvmem_cell_post_process_t read_post_process; - struct device_node *np; - struct nvmem_device *nvmem; - struct list_head node; -@@ -469,6 +470,7 @@ static int nvmem_cell_info_to_nvmem_cell - cell->offset = info->offset; - cell->bytes = info->bytes; - cell->name = info->name; -+ cell->read_post_process = info->read_post_process; - - cell->bit_offset = info->bit_offset; - cell->nbits = info->nbits; -@@ -1562,6 +1564,13 @@ static int __nvmem_cell_read(struct nvme - if (cell->bit_offset || cell->nbits) - nvmem_shift_read_buffer_in_place(cell, buf); - -+ if (cell->read_post_process) { -+ rc = cell->read_post_process(nvmem->priv, id, index, -+ cell->offset, buf, cell->bytes); -+ if (rc) -+ return rc; -+ } -+ - if (nvmem->cell_post_process) { - rc = nvmem->cell_post_process(nvmem->priv, id, index, - cell->offset, buf, cell->bytes); -@@ -1670,6 +1679,14 @@ static int __nvmem_cell_entry_write(stru - (cell->bit_offset == 0 && len != cell->bytes)) - return -EINVAL; - -+ /* -+ * Any cells which have a read_post_process hook are read-only because -+ * we cannot reverse the operation and it might affect other cells, -+ * too. -+ */ -+ if (cell->read_post_process) -+ return -EINVAL; -+ - if (cell->bit_offset || cell->nbits) { - buf = nvmem_cell_prepare_write_buffer(cell, buf, len); - if (IS_ERR(buf)) ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -54,6 +54,8 @@ struct nvmem_keepout { - * @bit_offset: Bit offset if cell is smaller than a byte. - * @nbits: Number of bits. - * @np: Optional device_node pointer. -+ * @read_post_process: Callback for optional post processing of cell data -+ * on reads. - */ - struct nvmem_cell_info { - const char *name; -@@ -62,6 +64,7 @@ struct nvmem_cell_info { - unsigned int bit_offset; - unsigned int nbits; - struct device_node *np; -+ nvmem_cell_post_process_t read_post_process; - }; - - /** diff --git a/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch b/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch deleted file mode 100644 index 1b77992a2bf6df..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0006-nvmem-core-allow-to-modify-a-cell-before-adding-it.patch +++ /dev/null @@ -1,59 +0,0 @@ -From de12c9691501ccba41a154c223869f82be4c12fd Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:25 +0100 -Subject: [PATCH] nvmem: core: allow to modify a cell before adding it - -Provide a way to modify a cell before it will get added. This is useful -to attach a custom post processing hook via a layout. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-18-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 4 ++++ - include/linux/nvmem-provider.h | 5 +++++ - 2 files changed, 9 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -694,6 +694,7 @@ static int nvmem_validate_keepouts(struc - - static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) - { -+ struct nvmem_layout *layout = nvmem->layout; - struct device *dev = &nvmem->dev; - struct device_node *child; - const __be32 *addr; -@@ -723,6 +724,9 @@ static int nvmem_add_cells_from_of(struc - - info.np = of_node_get(child); - -+ if (layout && layout->fixup_cell_info) -+ layout->fixup_cell_info(nvmem, layout, &info); -+ - ret = nvmem_add_one_cell(nvmem, &info); - kfree(info.name); - if (ret) { ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -155,6 +155,8 @@ struct nvmem_cell_table { - * @add_cells: Will be called if a nvmem device is found which - * has this layout. The function will add layout - * specific cells with nvmem_add_one_cell(). -+ * @fixup_cell_info: Will be called before a cell is added. Can be -+ * used to modify the nvmem_cell_info. - * @owner: Pointer to struct module. - * @node: List node. - * -@@ -168,6 +170,9 @@ struct nvmem_layout { - const struct of_device_id *of_match_table; - int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, - struct nvmem_layout *layout); -+ void (*fixup_cell_info)(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout, -+ struct nvmem_cell_info *cell); - - /* private */ - struct module *owner; diff --git a/target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch b/target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch deleted file mode 100644 index 2a5fa618ea6529..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0007-nvmem-imx-ocotp-replace-global-post-processing-with-.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 6c56a82d7895a213a43182a5d01a21a906a79847 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:26 +0100 -Subject: [PATCH] nvmem: imx-ocotp: replace global post processing with layouts - -In preparation of retiring the global post processing hook change this -driver to use layouts. The layout will be supplied during registration -and will be used to add the post processing hook to all added cells. - -Signed-off-by: Michael Walle -Tested-by: Michael Walle # on kontron-pitx-imx8m -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-19-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/imx-ocotp.c | 30 +++++++++++++++++++----------- - 1 file changed, 19 insertions(+), 11 deletions(-) - ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -225,18 +225,13 @@ read_end: - static int imx_ocotp_cell_pp(void *context, const char *id, int index, - unsigned int offset, void *data, size_t bytes) - { -- struct ocotp_priv *priv = context; -+ u8 *buf = data; -+ int i; - - /* Deal with some post processing of nvmem cell data */ -- if (id && !strcmp(id, "mac-address")) { -- if (priv->params->reverse_mac_address) { -- u8 *buf = data; -- int i; -- -- for (i = 0; i < bytes/2; i++) -- swap(buf[i], buf[bytes - i - 1]); -- } -- } -+ if (id && !strcmp(id, "mac-address")) -+ for (i = 0; i < bytes / 2; i++) -+ swap(buf[i], buf[bytes - i - 1]); - - return 0; - } -@@ -488,7 +483,6 @@ static struct nvmem_config imx_ocotp_nvm - .stride = 1, - .reg_read = imx_ocotp_read, - .reg_write = imx_ocotp_write, -- .cell_post_process = imx_ocotp_cell_pp, - }; - - static const struct ocotp_params imx6q_params = { -@@ -595,6 +589,17 @@ static const struct of_device_id imx_oco - }; - MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids); - -+static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout, -+ struct nvmem_cell_info *cell) -+{ -+ cell->read_post_process = imx_ocotp_cell_pp; -+} -+ -+struct nvmem_layout imx_ocotp_layout = { -+ .fixup_cell_info = imx_ocotp_fixup_cell_info, -+}; -+ - static int imx_ocotp_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -619,6 +624,9 @@ static int imx_ocotp_probe(struct platfo - imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; - imx_ocotp_nvmem_config.dev = dev; - imx_ocotp_nvmem_config.priv = priv; -+ if (priv->params->reverse_mac_address) -+ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; -+ - priv->config = &imx_ocotp_nvmem_config; - - clk_prepare_enable(priv->clk); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch b/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch deleted file mode 100644 index e6f4be261cd894..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0008-nvmem-cell-drop-global-cell_post_process.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 011e40a166fdaa65fb9946b7cd91efec85b70dbb Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:27 +0100 -Subject: [PATCH] nvmem: cell: drop global cell_post_process - -There are no users anymore for the global cell_post_process callback -anymore. New users should use proper nvmem layouts. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-20-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 9 --------- - include/linux/nvmem-provider.h | 2 -- - 2 files changed, 11 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -39,7 +39,6 @@ struct nvmem_device { - unsigned int nkeepout; - nvmem_reg_read_t reg_read; - nvmem_reg_write_t reg_write; -- nvmem_cell_post_process_t cell_post_process; - struct gpio_desc *wp_gpio; - struct nvmem_layout *layout; - void *priv; -@@ -902,7 +901,6 @@ struct nvmem_device *nvmem_register(cons - nvmem->type = config->type; - nvmem->reg_read = config->reg_read; - nvmem->reg_write = config->reg_write; -- nvmem->cell_post_process = config->cell_post_process; - nvmem->keepout = config->keepout; - nvmem->nkeepout = config->nkeepout; - if (config->of_node) -@@ -1574,13 +1572,6 @@ static int __nvmem_cell_read(struct nvme - if (rc) - return rc; - } -- -- if (nvmem->cell_post_process) { -- rc = nvmem->cell_post_process(nvmem->priv, id, index, -- cell->offset, buf, cell->bytes); -- if (rc) -- return rc; -- } - - if (len) - *len = cell->bytes; ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -85,7 +85,6 @@ struct nvmem_cell_info { - * @no_of_node: Device should not use the parent's of_node even if it's !NULL. - * @reg_read: Callback to read data. - * @reg_write: Callback to write data. -- * @cell_post_process: Callback for vendor specific post processing of cell data - * @size: Device size. - * @word_size: Minimum read/write access granularity. - * @stride: Minimum read/write access stride. -@@ -118,7 +117,6 @@ struct nvmem_config { - bool no_of_node; - nvmem_reg_read_t reg_read; - nvmem_reg_write_t reg_write; -- nvmem_cell_post_process_t cell_post_process; - int size; - int word_size; - int stride; diff --git a/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch b/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch deleted file mode 100644 index b39626f6e78a3e..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0009-nvmem-core-provide-own-priv-pointer-in-post-process-.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 8a134fd9f9323f4c39ec27055b3d3723cfb5c1e9 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:28 +0100 -Subject: [PATCH] nvmem: core: provide own priv pointer in post process - callback - -It doesn't make any more sense to have a opaque pointer set up by the -nvmem device. Usually, the layout isn't associated with a particular -nvmem device. Instead, let the caller who set the post process callback -provide the priv pointer. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-21-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 4 +++- - include/linux/nvmem-provider.h | 5 ++++- - 2 files changed, 7 insertions(+), 2 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -54,6 +54,7 @@ struct nvmem_cell_entry { - int bit_offset; - int nbits; - nvmem_cell_post_process_t read_post_process; -+ void *priv; - struct device_node *np; - struct nvmem_device *nvmem; - struct list_head node; -@@ -470,6 +471,7 @@ static int nvmem_cell_info_to_nvmem_cell - cell->bytes = info->bytes; - cell->name = info->name; - cell->read_post_process = info->read_post_process; -+ cell->priv = info->priv; - - cell->bit_offset = info->bit_offset; - cell->nbits = info->nbits; -@@ -1567,7 +1569,7 @@ static int __nvmem_cell_read(struct nvme - nvmem_shift_read_buffer_in_place(cell, buf); - - if (cell->read_post_process) { -- rc = cell->read_post_process(nvmem->priv, id, index, -+ rc = cell->read_post_process(cell->priv, id, index, - cell->offset, buf, cell->bytes); - if (rc) - return rc; ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -20,7 +20,8 @@ typedef int (*nvmem_reg_write_t)(void *p - void *val, size_t bytes); - /* used for vendor specific post processing of cell data */ - typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index, -- unsigned int offset, void *buf, size_t bytes); -+ unsigned int offset, void *buf, -+ size_t bytes); - - enum nvmem_type { - NVMEM_TYPE_UNKNOWN = 0, -@@ -56,6 +57,7 @@ struct nvmem_keepout { - * @np: Optional device_node pointer. - * @read_post_process: Callback for optional post processing of cell data - * on reads. -+ * @priv: Opaque data passed to the read_post_process hook. - */ - struct nvmem_cell_info { - const char *name; -@@ -65,6 +67,7 @@ struct nvmem_cell_info { - unsigned int nbits; - struct device_node *np; - nvmem_cell_post_process_t read_post_process; -+ void *priv; - }; - - /** diff --git a/target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch b/target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch deleted file mode 100644 index 7d97658b60e289..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0010-nvmem-layouts-sl28vpd-Add-new-layout-driver.patch +++ /dev/null @@ -1,215 +0,0 @@ -From d9fae023fe86069750092fc1c2f3a73e2fb18512 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Tue, 4 Apr 2023 18:21:29 +0100 -Subject: [PATCH] nvmem: layouts: sl28vpd: Add new layout driver - -This layout applies to the VPD of the Kontron sl28 boards. The VPD only -contains a base MAC address. Therefore, we have to add an individual -offset to it. This is done by taking the second argument of the nvmem -phandle into account. Also this let us checking the VPD version and the -checksum. - -Signed-off-by: Michael Walle -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-22-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/Kconfig | 9 ++ - drivers/nvmem/layouts/Makefile | 2 + - drivers/nvmem/layouts/sl28vpd.c | 165 ++++++++++++++++++++++++++++++++ - 3 files changed, 176 insertions(+) - create mode 100644 drivers/nvmem/layouts/sl28vpd.c - ---- a/drivers/nvmem/layouts/Kconfig -+++ b/drivers/nvmem/layouts/Kconfig -@@ -2,4 +2,13 @@ - - menu "Layout Types" - -+config NVMEM_LAYOUT_SL28_VPD -+ tristate "Kontron sl28 VPD layout support" -+ select CRC8 -+ help -+ Say Y here if you want to support the VPD layout of the Kontron -+ SMARC-sAL28 boards. -+ -+ If unsure, say N. -+ - endmenu ---- a/drivers/nvmem/layouts/Makefile -+++ b/drivers/nvmem/layouts/Makefile -@@ -2,3 +2,5 @@ - # - # Makefile for nvmem layouts. - # -+ -+obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o ---- /dev/null -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -0,0 +1,165 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define SL28VPD_MAGIC 'V' -+ -+struct sl28vpd_header { -+ u8 magic; -+ u8 version; -+} __packed; -+ -+struct sl28vpd_v1 { -+ struct sl28vpd_header header; -+ char serial_number[15]; -+ u8 base_mac_address[ETH_ALEN]; -+ u8 crc8; -+} __packed; -+ -+static int sl28vpd_mac_address_pp(void *priv, const char *id, int index, -+ unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ if (bytes != ETH_ALEN) -+ return -EINVAL; -+ -+ if (index < 0) -+ return -EINVAL; -+ -+ if (!is_valid_ether_addr(buf)) -+ return -EINVAL; -+ -+ eth_addr_add(buf, index); -+ -+ return 0; -+} -+ -+static const struct nvmem_cell_info sl28vpd_v1_entries[] = { -+ { -+ .name = "serial-number", -+ .offset = offsetof(struct sl28vpd_v1, serial_number), -+ .bytes = sizeof_field(struct sl28vpd_v1, serial_number), -+ }, -+ { -+ .name = "base-mac-address", -+ .offset = offsetof(struct sl28vpd_v1, base_mac_address), -+ .bytes = sizeof_field(struct sl28vpd_v1, base_mac_address), -+ .read_post_process = sl28vpd_mac_address_pp, -+ }, -+}; -+ -+static int sl28vpd_v1_check_crc(struct device *dev, struct nvmem_device *nvmem) -+{ -+ struct sl28vpd_v1 data_v1; -+ u8 table[CRC8_TABLE_SIZE]; -+ int ret; -+ u8 crc; -+ -+ crc8_populate_msb(table, 0x07); -+ -+ ret = nvmem_device_read(nvmem, 0, sizeof(data_v1), &data_v1); -+ if (ret < 0) -+ return ret; -+ else if (ret != sizeof(data_v1)) -+ return -EIO; -+ -+ crc = crc8(table, (void *)&data_v1, sizeof(data_v1) - 1, 0); -+ -+ if (crc != data_v1.crc8) { -+ dev_err(dev, -+ "Checksum is invalid (got %02x, expected %02x).\n", -+ crc, data_v1.crc8); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem, -+ struct nvmem_layout *layout) -+{ -+ const struct nvmem_cell_info *pinfo; -+ struct nvmem_cell_info info = {0}; -+ struct device_node *layout_np; -+ struct sl28vpd_header hdr; -+ int ret, i; -+ -+ /* check header */ -+ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); -+ if (ret < 0) -+ return ret; -+ else if (ret != sizeof(hdr)) -+ return -EIO; -+ -+ if (hdr.magic != SL28VPD_MAGIC) { -+ dev_err(dev, "Invalid magic value (%02x)\n", hdr.magic); -+ return -EINVAL; -+ } -+ -+ if (hdr.version != 1) { -+ dev_err(dev, "Version %d is unsupported.\n", hdr.version); -+ return -EINVAL; -+ } -+ -+ ret = sl28vpd_v1_check_crc(dev, nvmem); -+ if (ret) -+ return ret; -+ -+ layout_np = of_nvmem_layout_get_container(nvmem); -+ if (!layout_np) -+ return -ENOENT; -+ -+ for (i = 0; i < ARRAY_SIZE(sl28vpd_v1_entries); i++) { -+ pinfo = &sl28vpd_v1_entries[i]; -+ -+ info.name = pinfo->name; -+ info.offset = pinfo->offset; -+ info.bytes = pinfo->bytes; -+ info.read_post_process = pinfo->read_post_process; -+ info.np = of_get_child_by_name(layout_np, pinfo->name); -+ -+ ret = nvmem_add_one_cell(nvmem, &info); -+ if (ret) { -+ of_node_put(layout_np); -+ return ret; -+ } -+ } -+ -+ of_node_put(layout_np); -+ -+ return 0; -+} -+ -+static const struct of_device_id sl28vpd_of_match_table[] = { -+ { .compatible = "kontron,sl28-vpd" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); -+ -+struct nvmem_layout sl28vpd_layout = { -+ .name = "sl28-vpd", -+ .of_match_table = sl28vpd_of_match_table, -+ .add_cells = sl28vpd_add_cells, -+}; -+ -+static int __init sl28vpd_init(void) -+{ -+ return nvmem_layout_register(&sl28vpd_layout); -+} -+ -+static void __exit sl28vpd_exit(void) -+{ -+ nvmem_layout_unregister(&sl28vpd_layout); -+} -+ -+module_init(sl28vpd_init); -+module_exit(sl28vpd_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Michael Walle "); -+MODULE_DESCRIPTION("NVMEM layout driver for the VPD of Kontron sl28 boards"); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch b/target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch deleted file mode 100644 index ca8b4bc069146b..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0011-nvmem-layouts-onie-tlv-Add-new-layout-driver.patch +++ /dev/null @@ -1,306 +0,0 @@ -From d3c0d12f6474216bf386101e2449cc73e5c5b61d Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:31 +0100 -Subject: [PATCH] nvmem: layouts: onie-tlv: Add new layout driver - -This layout applies on top of any non volatile storage device containing -an ONIE table factory flashed. This table follows the tlv -(type-length-value) organization described in the link below. We cannot -afford using regular parsers because the content of these tables is -manufacturer specific and must be dynamically discovered. - -Link: https://opencomputeproject.github.io/onie/design-spec/hw_requirements.html -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-24-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/Kconfig | 9 ++ - drivers/nvmem/layouts/Makefile | 1 + - drivers/nvmem/layouts/onie-tlv.c | 257 +++++++++++++++++++++++++++++++ - 3 files changed, 267 insertions(+) - create mode 100644 drivers/nvmem/layouts/onie-tlv.c - ---- a/drivers/nvmem/layouts/Kconfig -+++ b/drivers/nvmem/layouts/Kconfig -@@ -11,4 +11,13 @@ config NVMEM_LAYOUT_SL28_VPD - - If unsure, say N. - -+config NVMEM_LAYOUT_ONIE_TLV -+ tristate "ONIE tlv support" -+ select CRC32 -+ help -+ Say Y here if you want to support the Open Compute Project ONIE -+ Type-Length-Value standard table. -+ -+ If unsure, say N. -+ - endmenu ---- a/drivers/nvmem/layouts/Makefile -+++ b/drivers/nvmem/layouts/Makefile -@@ -4,3 +4,4 @@ - # - - obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o -+obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o ---- /dev/null -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -0,0 +1,257 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * ONIE tlv NVMEM cells provider -+ * -+ * Copyright (C) 2022 Open Compute Group ONIE -+ * Author: Miquel Raynal -+ * Based on the nvmem driver written by: Vadym Kochan -+ * Inspired by the first layout written by: Rafał Miłecki -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define ONIE_TLV_MAX_LEN 2048 -+#define ONIE_TLV_CRC_FIELD_SZ 6 -+#define ONIE_TLV_CRC_SZ 4 -+#define ONIE_TLV_HDR_ID "TlvInfo" -+ -+struct onie_tlv_hdr { -+ u8 id[8]; -+ u8 version; -+ __be16 data_len; -+} __packed; -+ -+struct onie_tlv { -+ u8 type; -+ u8 len; -+} __packed; -+ -+static const char *onie_tlv_cell_name(u8 type) -+{ -+ switch (type) { -+ case 0x21: -+ return "product-name"; -+ case 0x22: -+ return "part-number"; -+ case 0x23: -+ return "serial-number"; -+ case 0x24: -+ return "mac-address"; -+ case 0x25: -+ return "manufacture-date"; -+ case 0x26: -+ return "device-version"; -+ case 0x27: -+ return "label-revision"; -+ case 0x28: -+ return "platform-name"; -+ case 0x29: -+ return "onie-version"; -+ case 0x2A: -+ return "num-macs"; -+ case 0x2B: -+ return "manufacturer"; -+ case 0x2C: -+ return "country-code"; -+ case 0x2D: -+ return "vendor"; -+ case 0x2E: -+ return "diag-version"; -+ case 0x2F: -+ return "service-tag"; -+ case 0xFD: -+ return "vendor-extension"; -+ case 0xFE: -+ return "crc32"; -+ default: -+ break; -+ } -+ -+ return NULL; -+} -+ -+static int onie_tlv_mac_read_cb(void *priv, const char *id, int index, -+ unsigned int offset, void *buf, -+ size_t bytes) -+{ -+ eth_addr_add(buf, index); -+ -+ return 0; -+} -+ -+static nvmem_cell_post_process_t onie_tlv_read_cb(u8 type, u8 *buf) -+{ -+ switch (type) { -+ case 0x24: -+ return &onie_tlv_mac_read_cb; -+ default: -+ break; -+ } -+ -+ return NULL; -+} -+ -+static int onie_tlv_add_cells(struct device *dev, struct nvmem_device *nvmem, -+ size_t data_len, u8 *data) -+{ -+ struct nvmem_cell_info cell = {}; -+ struct device_node *layout; -+ struct onie_tlv tlv; -+ unsigned int hdr_len = sizeof(struct onie_tlv_hdr); -+ unsigned int offset = 0; -+ int ret; -+ -+ layout = of_nvmem_layout_get_container(nvmem); -+ if (!layout) -+ return -ENOENT; -+ -+ while (offset < data_len) { -+ memcpy(&tlv, data + offset, sizeof(tlv)); -+ if (offset + tlv.len >= data_len) { -+ dev_err(dev, "Out of bounds field (0x%x bytes at 0x%x)\n", -+ tlv.len, hdr_len + offset); -+ break; -+ } -+ -+ cell.name = onie_tlv_cell_name(tlv.type); -+ if (!cell.name) -+ continue; -+ -+ cell.offset = hdr_len + offset + sizeof(tlv.type) + sizeof(tlv.len); -+ cell.bytes = tlv.len; -+ cell.np = of_get_child_by_name(layout, cell.name); -+ cell.read_post_process = onie_tlv_read_cb(tlv.type, data + offset + sizeof(tlv)); -+ -+ ret = nvmem_add_one_cell(nvmem, &cell); -+ if (ret) { -+ of_node_put(layout); -+ return ret; -+ } -+ -+ offset += sizeof(tlv) + tlv.len; -+ } -+ -+ of_node_put(layout); -+ -+ return 0; -+} -+ -+static bool onie_tlv_hdr_is_valid(struct device *dev, struct onie_tlv_hdr *hdr) -+{ -+ if (memcmp(hdr->id, ONIE_TLV_HDR_ID, sizeof(hdr->id))) { -+ dev_err(dev, "Invalid header\n"); -+ return false; -+ } -+ -+ if (hdr->version != 0x1) { -+ dev_err(dev, "Invalid version number\n"); -+ return false; -+ } -+ -+ return true; -+} -+ -+static bool onie_tlv_crc_is_valid(struct device *dev, size_t table_len, u8 *table) -+{ -+ struct onie_tlv crc_hdr; -+ u32 read_crc, calc_crc; -+ __be32 crc_be; -+ -+ memcpy(&crc_hdr, table + table_len - ONIE_TLV_CRC_FIELD_SZ, sizeof(crc_hdr)); -+ if (crc_hdr.type != 0xfe || crc_hdr.len != ONIE_TLV_CRC_SZ) { -+ dev_err(dev, "Invalid CRC field\n"); -+ return false; -+ } -+ -+ /* The table contains a JAMCRC, which is XOR'ed compared to the original -+ * CRC32 implementation as known in the Ethernet world. -+ */ -+ memcpy(&crc_be, table + table_len - ONIE_TLV_CRC_SZ, ONIE_TLV_CRC_SZ); -+ read_crc = be32_to_cpu(crc_be); -+ calc_crc = crc32(~0, table, table_len - ONIE_TLV_CRC_SZ) ^ 0xFFFFFFFF; -+ if (read_crc != calc_crc) { -+ dev_err(dev, "Invalid CRC read: 0x%08x, expected: 0x%08x\n", -+ read_crc, calc_crc); -+ return false; -+ } -+ -+ return true; -+} -+ -+static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem, -+ struct nvmem_layout *layout) -+{ -+ struct onie_tlv_hdr hdr; -+ size_t table_len, data_len, hdr_len; -+ u8 *table, *data; -+ int ret; -+ -+ ret = nvmem_device_read(nvmem, 0, sizeof(hdr), &hdr); -+ if (ret < 0) -+ return ret; -+ -+ if (!onie_tlv_hdr_is_valid(dev, &hdr)) { -+ dev_err(dev, "Invalid ONIE TLV header\n"); -+ return -EINVAL; -+ } -+ -+ hdr_len = sizeof(hdr.id) + sizeof(hdr.version) + sizeof(hdr.data_len); -+ data_len = be16_to_cpu(hdr.data_len); -+ table_len = hdr_len + data_len; -+ if (table_len > ONIE_TLV_MAX_LEN) { -+ dev_err(dev, "Invalid ONIE TLV data length\n"); -+ return -EINVAL; -+ } -+ -+ table = devm_kmalloc(dev, table_len, GFP_KERNEL); -+ if (!table) -+ return -ENOMEM; -+ -+ ret = nvmem_device_read(nvmem, 0, table_len, table); -+ if (ret != table_len) -+ return ret; -+ -+ if (!onie_tlv_crc_is_valid(dev, table_len, table)) -+ return -EINVAL; -+ -+ data = table + hdr_len; -+ ret = onie_tlv_add_cells(dev, nvmem, data_len, data); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static const struct of_device_id onie_tlv_of_match_table[] = { -+ { .compatible = "onie,tlv-layout", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table); -+ -+static struct nvmem_layout onie_tlv_layout = { -+ .name = "ONIE tlv layout", -+ .of_match_table = onie_tlv_of_match_table, -+ .add_cells = onie_tlv_parse_table, -+}; -+ -+static int __init onie_tlv_init(void) -+{ -+ return nvmem_layout_register(&onie_tlv_layout); -+} -+ -+static void __exit onie_tlv_exit(void) -+{ -+ nvmem_layout_unregister(&onie_tlv_layout); -+} -+ -+module_init(onie_tlv_init); -+module_exit(onie_tlv_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Miquel Raynal "); -+MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing"); -+MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing"); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch b/target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch deleted file mode 100644 index 94a0911d73cc76..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0012-nvmem-stm32-romem-mark-OF-related-data-as-maybe-unus.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a4fb434ef96ace5af758ca2c52c3a3f8f3abc87c Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 4 Apr 2023 18:21:34 +0100 -Subject: [PATCH] nvmem: stm32-romem: mark OF related data as maybe unused -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The driver can be compile tested with !CONFIG_OF making certain data -unused: - - drivers/nvmem/stm32-romem.c:271:34: error: ‘stm32_romem_of_match’ defined but not used [-Werror=unused-const-variable=] - -Signed-off-by: Krzysztof Kozlowski -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-27-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -268,7 +268,7 @@ static const struct stm32_romem_cfg stm3 - .ta = true, - }; - --static const struct of_device_id stm32_romem_of_match[] = { -+static const struct of_device_id stm32_romem_of_match[] __maybe_unused = { - { .compatible = "st,stm32f4-otp", }, { - .compatible = "st,stm32mp15-bsec", - .data = (void *)&stm32mp15_bsec_cfg, diff --git a/target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch b/target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch deleted file mode 100644 index abda402bddb07a..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0013-nvmem-mtk-efuse-Support-postprocessing-for-GPU-speed.patch +++ /dev/null @@ -1,120 +0,0 @@ -From de6e05097f7db066afb0ad4c88b730949f7b7749 Mon Sep 17 00:00:00 2001 -From: AngeloGioacchino Del Regno -Date: Tue, 4 Apr 2023 18:21:35 +0100 -Subject: [PATCH] nvmem: mtk-efuse: Support postprocessing for GPU speed - binning data - -On some MediaTek SoCs GPU speed binning data is available for read -in the SoC's eFuse array but it has a format that is incompatible -with what the OPP API expects, as we read a number from 0 to 7 but -opp-supported-hw is expecting a bitmask to enable an OPP entry: -being what we read limited to 0-7, it's straightforward to simply -convert the value to BIT(value) as a post-processing action. - -So, introduce post-processing support and enable it by evaluating -the newly introduced platform data's `uses_post_processing` member, -currently enabled only for MT8186. - -Signed-off-by: AngeloGioacchino Del Regno -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-28-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/mtk-efuse.c | 53 +++++++++++++++++++++++++++++++++++++-- - 1 file changed, 51 insertions(+), 2 deletions(-) - ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -10,6 +10,11 @@ - #include - #include - #include -+#include -+ -+struct mtk_efuse_pdata { -+ bool uses_post_processing; -+}; - - struct mtk_efuse_priv { - void __iomem *base; -@@ -29,6 +34,37 @@ static int mtk_reg_read(void *context, - return 0; - } - -+static int mtk_efuse_gpu_speedbin_pp(void *context, const char *id, int index, -+ unsigned int offset, void *data, size_t bytes) -+{ -+ u8 *val = data; -+ -+ if (val[0] < 8) -+ val[0] = BIT(val[0]); -+ -+ return 0; -+} -+ -+static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem, -+ struct nvmem_layout *layout, -+ struct nvmem_cell_info *cell) -+{ -+ size_t sz = strlen(cell->name); -+ -+ /* -+ * On some SoCs, the GPU speedbin is not read as bitmask but as -+ * a number with range [0-7] (max 3 bits): post process to use -+ * it in OPP tables to describe supported-hw. -+ */ -+ if (cell->nbits <= 3 && -+ strncmp(cell->name, "gpu-speedbin", min(sz, strlen("gpu-speedbin"))) == 0) -+ cell->read_post_process = mtk_efuse_gpu_speedbin_pp; -+} -+ -+static struct nvmem_layout mtk_efuse_layout = { -+ .fixup_cell_info = mtk_efuse_fixup_cell_info, -+}; -+ - static int mtk_efuse_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -36,6 +72,7 @@ static int mtk_efuse_probe(struct platfo - struct nvmem_device *nvmem; - struct nvmem_config econfig = {}; - struct mtk_efuse_priv *priv; -+ const struct mtk_efuse_pdata *pdata; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -45,20 +82,32 @@ static int mtk_efuse_probe(struct platfo - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - -+ pdata = device_get_match_data(dev); - econfig.stride = 1; - econfig.word_size = 1; - econfig.reg_read = mtk_reg_read; - econfig.size = resource_size(res); - econfig.priv = priv; - econfig.dev = dev; -+ if (pdata->uses_post_processing) -+ econfig.layout = &mtk_efuse_layout; - nvmem = devm_nvmem_register(dev, &econfig); - - return PTR_ERR_OR_ZERO(nvmem); - } - -+static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = { -+ .uses_post_processing = true, -+}; -+ -+static const struct mtk_efuse_pdata mtk_efuse_pdata = { -+ .uses_post_processing = false, -+}; -+ - static const struct of_device_id mtk_efuse_of_match[] = { -- { .compatible = "mediatek,mt8173-efuse",}, -- { .compatible = "mediatek,efuse",}, -+ { .compatible = "mediatek,mt8173-efuse", .data = &mtk_efuse_pdata }, -+ { .compatible = "mediatek,mt8186-efuse", .data = &mtk_mt8186_efuse_pdata }, -+ { .compatible = "mediatek,efuse", .data = &mtk_efuse_pdata }, - {/* sentinel */}, - }; - MODULE_DEVICE_TABLE(of, mtk_efuse_of_match); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch b/target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch deleted file mode 100644 index 200eb1928f8c4a..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0014-nvmem-bcm-ocotp-Use-devm_platform_ioremap_resource.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1dc552fa33cf98af3e784dbc0500da93cae3b24a Mon Sep 17 00:00:00 2001 -From: Yang Li -Date: Tue, 4 Apr 2023 18:21:38 +0100 -Subject: [PATCH] nvmem: bcm-ocotp: Use devm_platform_ioremap_resource() - -According to commit 7945f929f1a7 ("drivers: provide -devm_platform_ioremap_resource()"), convert platform_get_resource(), -devm_ioremap_resource() to a single call to use -devm_platform_ioremap_resource(), as this is exactly what this function -does. - -Signed-off-by: Yang Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-31-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/bcm-ocotp.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/nvmem/bcm-ocotp.c -+++ b/drivers/nvmem/bcm-ocotp.c -@@ -244,7 +244,6 @@ MODULE_DEVICE_TABLE(acpi, bcm_otpc_acpi_ - static int bcm_otpc_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -- struct resource *res; - struct otpc_priv *priv; - struct nvmem_device *nvmem; - int err; -@@ -259,8 +258,7 @@ static int bcm_otpc_probe(struct platfor - return -ENODEV; - - /* Get OTP base address register. */ -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->base = devm_ioremap_resource(dev, res); -+ priv->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->base)) { - dev_err(dev, "unable to map I/O memory\n"); - return PTR_ERR(priv->base); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch b/target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch deleted file mode 100644 index 890dacd08dbef8..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0015-nvmem-nintendo-otp-Use-devm_platform_ioremap_resourc.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 649409990d2e93fac657be7c6960c28a2c601d65 Mon Sep 17 00:00:00 2001 -From: Yang Li -Date: Tue, 4 Apr 2023 18:21:39 +0100 -Subject: [PATCH] nvmem: nintendo-otp: Use devm_platform_ioremap_resource() - -According to commit 7945f929f1a7 ("drivers: provide -devm_platform_ioremap_resource()"), convert platform_get_resource(), -devm_ioremap_resource() to a single call to use -devm_platform_ioremap_resource(), as this is exactly what this function -does. - -Signed-off-by: Yang Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-32-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/nintendo-otp.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/nvmem/nintendo-otp.c -+++ b/drivers/nvmem/nintendo-otp.c -@@ -76,7 +76,6 @@ static int nintendo_otp_probe(struct pla - struct device *dev = &pdev->dev; - const struct of_device_id *of_id = - of_match_device(nintendo_otp_of_table, dev); -- struct resource *res; - struct nvmem_device *nvmem; - struct nintendo_otp_priv *priv; - -@@ -92,8 +91,7 @@ static int nintendo_otp_probe(struct pla - if (!priv) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->regs = devm_ioremap_resource(dev, res); -+ priv->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(priv->regs)) - return PTR_ERR(priv->regs); - diff --git a/target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch deleted file mode 100644 index 3f5d3c1ad4c121..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0016-nvmem-vf610-ocotp-Use-devm_platform_get_and_ioremap_.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c2367aa60d5e34d48582362c6de34b4131d92be7 Mon Sep 17 00:00:00 2001 -From: Yang Li -Date: Tue, 4 Apr 2023 18:21:40 +0100 -Subject: [PATCH] nvmem: vf610-ocotp: Use - devm_platform_get_and_ioremap_resource() - -According to commit 890cc39a8799 ("drivers: provide -devm_platform_get_and_ioremap_resource()"), convert -platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -Signed-off-by: Yang Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-33-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/vf610-ocotp.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/vf610-ocotp.c -+++ b/drivers/nvmem/vf610-ocotp.c -@@ -219,8 +219,7 @@ static int vf610_ocotp_probe(struct plat - if (!ocotp_dev) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- ocotp_dev->base = devm_ioremap_resource(dev, res); -+ ocotp_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(ocotp_dev->base)) - return PTR_ERR(ocotp_dev->base); - diff --git a/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch b/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch deleted file mode 100644 index a1ebd53d074b88..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0017-nvmem-core-support-specifying-both-cell-raw-data-pos.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 55d4980ce55b6bb4be66877de4dbec513911b988 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 4 Apr 2023 18:21:42 +0100 -Subject: [PATCH] nvmem: core: support specifying both: cell raw data & post - read lengths -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Callback .read_post_process() is designed to modify raw cell content -before providing it to the consumer. So far we were dealing with -modifications that didn't affect cell size (length). In some cases -however cell content needs to be reformatted and resized. - -It's required e.g. to provide properly formatted MAC address in case -it's stored in a non-binary format (e.g. using ASCII). - -There were few discussions how to optimally handle that. Following -possible solutions were considered: -1. Allow .read_post_process() to realloc (resize) content buffer -2. Allow .read_post_process() to adjust (decrease) just buffer length -3. Register NVMEM cells using post-read sizes - -The preferred solution was the last one. The problem is that simply -adjusting "bytes" in NVMEM providers would result in core code NOT -passing whole raw data to .read_post_process() callbacks. It means -callback functions couldn't do their job without somehow manually -reading original cell content on their own. - -This patch deals with that by registering NVMEM cells with both lengths: -raw content one and post read one. It allows: -1. Core code to read whole raw cell content -2. Callbacks to return content they want - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-35-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 11 +++++++---- - include/linux/nvmem-provider.h | 2 ++ - 2 files changed, 9 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -50,6 +50,7 @@ struct nvmem_device { - struct nvmem_cell_entry { - const char *name; - int offset; -+ size_t raw_len; - int bytes; - int bit_offset; - int nbits; -@@ -468,6 +469,7 @@ static int nvmem_cell_info_to_nvmem_cell - { - cell->nvmem = nvmem; - cell->offset = info->offset; -+ cell->raw_len = info->raw_len ?: info->bytes; - cell->bytes = info->bytes; - cell->name = info->name; - cell->read_post_process = info->read_post_process; -@@ -1559,7 +1561,7 @@ static int __nvmem_cell_read(struct nvme - { - int rc; - -- rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->bytes); -+ rc = nvmem_reg_read(nvmem, cell->offset, buf, cell->raw_len); - - if (rc) - return rc; -@@ -1570,7 +1572,7 @@ static int __nvmem_cell_read(struct nvme - - if (cell->read_post_process) { - rc = cell->read_post_process(cell->priv, id, index, -- cell->offset, buf, cell->bytes); -+ cell->offset, buf, cell->raw_len); - if (rc) - return rc; - } -@@ -1593,14 +1595,15 @@ static int __nvmem_cell_read(struct nvme - */ - void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len) - { -- struct nvmem_device *nvmem = cell->entry->nvmem; -+ struct nvmem_cell_entry *entry = cell->entry; -+ struct nvmem_device *nvmem = entry->nvmem; - u8 *buf; - int rc; - - if (!nvmem) - return ERR_PTR(-EINVAL); - -- buf = kzalloc(cell->entry->bytes, GFP_KERNEL); -+ buf = kzalloc(max_t(size_t, entry->raw_len, entry->bytes), GFP_KERNEL); - if (!buf) - return ERR_PTR(-ENOMEM); - ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -51,6 +51,7 @@ struct nvmem_keepout { - * struct nvmem_cell_info - NVMEM cell description - * @name: Name. - * @offset: Offset within the NVMEM device. -+ * @raw_len: Length of raw data (without post processing). - * @bytes: Length of the cell. - * @bit_offset: Bit offset if cell is smaller than a byte. - * @nbits: Number of bits. -@@ -62,6 +63,7 @@ struct nvmem_keepout { - struct nvmem_cell_info { - const char *name; - unsigned int offset; -+ size_t raw_len; - unsigned int bytes; - unsigned int bit_offset; - unsigned int nbits; diff --git a/target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch b/target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch deleted file mode 100644 index adde0ffc4b1786..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0018-nvmem-u-boot-env-post-process-ethaddr-env-variable.patch +++ /dev/null @@ -1,81 +0,0 @@ -From c49f1a8af6bcf6d18576bca898f8083ca4b129e1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 4 Apr 2023 18:21:43 +0100 -Subject: [PATCH] nvmem: u-boot-env: post-process "ethaddr" env variable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -U-Boot environment variables are stored in ASCII format so "ethaddr" -requires parsing into binary to make it work with Ethernet interfaces. - -This includes support for indexes to support #nvmem-cell-cells = <1>. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-36-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 1 + - drivers/nvmem/u-boot-env.c | 26 ++++++++++++++++++++++++++ - 2 files changed, 27 insertions(+) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -340,6 +340,7 @@ config NVMEM_U_BOOT_ENV - tristate "U-Boot environment variables support" - depends on OF && MTD - select CRC32 -+ select GENERIC_NET_UTILS - help - U-Boot stores its setup as environment variables. This driver adds - support for verifying & exporting such data. It also exposes variables ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -4,6 +4,8 @@ - */ - - #include -+#include -+#include - #include - #include - #include -@@ -70,6 +72,25 @@ static int u_boot_env_read(void *context - return 0; - } - -+static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, -+ unsigned int offset, void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (bytes != 3 * ETH_ALEN - 1) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ - static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, - size_t data_offset, size_t data_len) - { -@@ -101,6 +122,11 @@ static int u_boot_env_add_cells(struct u - priv->cells[idx].offset = data_offset + value - data; - priv->cells[idx].bytes = strlen(value); - priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); -+ if (!strcmp(var, "ethaddr")) { -+ priv->cells[idx].raw_len = strlen(value); -+ priv->cells[idx].bytes = ETH_ALEN; -+ priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr; -+ } - } - - if (WARN_ON(idx != priv->ncells)) diff --git a/target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch b/target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch deleted file mode 100644 index 7c6fe22b5f3a69..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0019-nvmem-Add-macro-to-register-nvmem-layout-drivers.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 814c978f02db17f16e6aa2efa2a929372f06da09 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:44 +0100 -Subject: [PATCH] nvmem: Add macro to register nvmem layout drivers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Provide a module_nvmem_layout_driver() macro at the end of the -nvmem-provider.h header to reduce the boilerplate when registering nvmem -layout drivers. - -Suggested-by: Srinivas Kandagatla -Signed-off-by: Miquel Raynal -Acked-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-37-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - include/linux/nvmem-provider.h | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -9,6 +9,7 @@ - #ifndef _LINUX_NVMEM_PROVIDER_H - #define _LINUX_NVMEM_PROVIDER_H - -+#include - #include - #include - #include -@@ -242,4 +243,9 @@ nvmem_layout_get_match_data(struct nvmem - } - - #endif /* CONFIG_NVMEM */ -+ -+#define module_nvmem_layout_driver(__layout_driver) \ -+ module_driver(__layout_driver, nvmem_layout_register, \ -+ nvmem_layout_unregister) -+ - #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch b/target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch deleted file mode 100644 index 06646dd68bf67b..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0020-nvmem-layouts-sl28vpd-Use-module_nvmem_layout_driver.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0abdf99fe0c86252ba274703425f8d543d7e7f0d Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:45 +0100 -Subject: [PATCH] nvmem: layouts: sl28vpd: Use module_nvmem_layout_driver() - -Stop open-coding the module init/exit functions. Use the -module_nvmem_layout_driver() instead. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-38-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/sl28vpd.c | 14 +------------- - 1 file changed, 1 insertion(+), 13 deletions(-) - ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -146,19 +146,7 @@ struct nvmem_layout sl28vpd_layout = { - .of_match_table = sl28vpd_of_match_table, - .add_cells = sl28vpd_add_cells, - }; -- --static int __init sl28vpd_init(void) --{ -- return nvmem_layout_register(&sl28vpd_layout); --} -- --static void __exit sl28vpd_exit(void) --{ -- nvmem_layout_unregister(&sl28vpd_layout); --} -- --module_init(sl28vpd_init); --module_exit(sl28vpd_exit); -+module_nvmem_layout_driver(sl28vpd_layout); - - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Michael Walle "); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch b/target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch deleted file mode 100644 index 826f4378c2fabf..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0021-nvmem-layouts-onie-tlv-Use-module_nvmem_layout_drive.patch +++ /dev/null @@ -1,39 +0,0 @@ -From d119eb38faab61125aaa4f63c74eef61585cf34c Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:46 +0100 -Subject: [PATCH] nvmem: layouts: onie-tlv: Use module_nvmem_layout_driver() - -Stop open-coding the module init/exit functions. Use the -module_nvmem_layout_driver() instead. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-39-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/onie-tlv.c | 14 +------------- - 1 file changed, 1 insertion(+), 13 deletions(-) - ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -237,19 +237,7 @@ static struct nvmem_layout onie_tlv_layo - .of_match_table = onie_tlv_of_match_table, - .add_cells = onie_tlv_parse_table, - }; -- --static int __init onie_tlv_init(void) --{ -- return nvmem_layout_register(&onie_tlv_layout); --} -- --static void __exit onie_tlv_exit(void) --{ -- nvmem_layout_unregister(&onie_tlv_layout); --} -- --module_init(onie_tlv_init); --module_exit(onie_tlv_exit); -+module_nvmem_layout_driver(onie_tlv_layout); - - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Miquel Raynal "); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch b/target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch deleted file mode 100644 index f20db85ceb6ff6..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0022-nvmem-layouts-onie-tlv-Drop-wrong-module-alias.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 6b13e4b6a9a45028ac730e550380077df1845912 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:47 +0100 -Subject: [PATCH] nvmem: layouts: onie-tlv: Drop wrong module alias - -The MODULE_ALIAS macro is misused here as it carries the -description. There is currently no relevant alias to provide so let's -just drop it. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-40-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/onie-tlv.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -242,4 +242,3 @@ module_nvmem_layout_driver(onie_tlv_layo - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Miquel Raynal "); - MODULE_DESCRIPTION("NVMEM layout driver for Onie TLV table parsing"); --MODULE_ALIAS("NVMEM layout driver for Onie TLV table parsing"); diff --git a/target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch b/target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch deleted file mode 100644 index 5cf847b57ae130..00000000000000 --- a/target/linux/generic/backport-6.1/811-v6.4-0023-nvmem-layouts-sl28vpd-set-varaiable-sl28vpd_layout-s.patch +++ /dev/null @@ -1,31 +0,0 @@ -From a8642cd11635a35a5f1dc31857887900d6610778 Mon Sep 17 00:00:00 2001 -From: Tom Rix -Date: Tue, 4 Apr 2023 18:21:48 +0100 -Subject: [PATCH] nvmem: layouts: sl28vpd: set varaiable sl28vpd_layout - storage-class-specifier to static - -smatch reports -drivers/nvmem/layouts/sl28vpd.c:144:21: warning: symbol - 'sl28vpd_layout' was not declared. Should it be static? - -This variable is only used in one file so it should be static. - -Signed-off-by: Tom Rix -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-41-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/sl28vpd.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -141,7 +141,7 @@ static const struct of_device_id sl28vpd - }; - MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); - --struct nvmem_layout sl28vpd_layout = { -+static struct nvmem_layout sl28vpd_layout = { - .name = "sl28-vpd", - .of_match_table = sl28vpd_of_match_table, - .add_cells = sl28vpd_add_cells, diff --git a/target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch b/target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch deleted file mode 100644 index 13ee2d42293f91..00000000000000 --- a/target/linux/generic/backport-6.1/812-v6.2-firmware-nvram-bcm47xx-support-init-from-IO-memory.patch +++ /dev/null @@ -1,100 +0,0 @@ -From a5be5ce0e25439fae3cd42e3d775979547926812 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 3 Nov 2022 09:25:29 +0100 -Subject: [PATCH] firmware/nvram: bcm47xx: support init from IO memory -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Provide NVMEM content to the NVRAM driver from a simple -memory resource. This is necessary to use NVRAM in a memory- -mapped flash device. Patch taken from OpenWrts development -tree. - -This patch makes it possible to use memory-mapped NVRAM -on the D-Link DWL-8610AP and the D-Link DIR-890L. - -Cc: Hauke Mehrtens -Cc: linux-mips@vger.kernel.org -Cc: Florian Fainelli -Cc: bcm-kernel-feedback-list@broadcom.com -Cc: Thomas Bogendoerfer -Signed-off-by: Rafał Miłecki -[Added an export for modules potentially using the init symbol] -Signed-off-by: Linus Walleij -Link: https://lore.kernel.org/r/20221103082529.359084-1-linus.walleij@linaro.org -Signed-off-by: Florian Fainelli ---- - drivers/firmware/broadcom/bcm47xx_nvram.c | 18 ++++++++++++++++++ - drivers/nvmem/brcm_nvram.c | 3 +++ - include/linux/bcm47xx_nvram.h | 6 ++++++ - 3 files changed, 27 insertions(+) - ---- a/drivers/firmware/broadcom/bcm47xx_nvram.c -+++ b/drivers/firmware/broadcom/bcm47xx_nvram.c -@@ -110,6 +110,24 @@ found: - return 0; - } - -+int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size) -+{ -+ if (nvram_len) { -+ pr_warn("nvram already initialized\n"); -+ return -EEXIST; -+ } -+ -+ if (!bcm47xx_nvram_is_valid(nvram_start)) { -+ pr_err("No valid NVRAM found\n"); -+ return -ENOENT; -+ } -+ -+ bcm47xx_nvram_copy(nvram_start, res_size); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(bcm47xx_nvram_init_from_iomem); -+ - /* - * On bcm47xx we need access to the NVRAM very early, so we can't use mtd - * subsystem to access flash. We can't even use platform device / driver to ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -3,6 +3,7 @@ - * Copyright (C) 2021 Rafał Miłecki - */ - -+#include - #include - #include - #include -@@ -139,6 +140,8 @@ static int brcm_nvram_probe(struct platf - if (err) - return err; - -+ bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res)); -+ - config.dev = dev; - config.cells = priv->cells; - config.ncells = priv->ncells; ---- a/include/linux/bcm47xx_nvram.h -+++ b/include/linux/bcm47xx_nvram.h -@@ -11,6 +11,7 @@ - #include - - #ifdef CONFIG_BCM47XX_NVRAM -+int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size); - int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); - int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); - int bcm47xx_nvram_gpio_pin(const char *name); -@@ -20,6 +21,11 @@ static inline void bcm47xx_nvram_release - vfree(nvram); - }; - #else -+static inline int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, -+ size_t res_size) -+{ -+ return -ENOTSUPP; -+} - static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) - { - return -ENOTSUPP; diff --git a/target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch b/target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch deleted file mode 100644 index 38cfccd5ef9b29..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0001-nvmem-imx-ocotp-set-varaiable-imx_ocotp_layout-stora.patch +++ /dev/null @@ -1,31 +0,0 @@ -From eebc6573ad940b62a87776db3917e912b4f52d78 Mon Sep 17 00:00:00 2001 -From: Tom Rix -Date: Sun, 11 Jun 2023 15:03:05 +0100 -Subject: [PATCH] nvmem: imx-ocotp: set varaiable imx_ocotp_layout - storage-class-specifier to static - -smatch reports -drivers/nvmem/imx-ocotp.c:599:21: warning: symbol - 'imx_ocotp_layout' was not declared. Should it be static? - -This variable is only used in one file so should be static. - -Signed-off-by: Tom Rix -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-2-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/imx-ocotp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -596,7 +596,7 @@ static void imx_ocotp_fixup_cell_info(st - cell->read_post_process = imx_ocotp_cell_pp; - } - --struct nvmem_layout imx_ocotp_layout = { -+static struct nvmem_layout imx_ocotp_layout = { - .fixup_cell_info = imx_ocotp_fixup_cell_info, - }; - diff --git a/target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch b/target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch deleted file mode 100644 index 7523e5ebf645a7..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0002-nvmem-imx-ocotp-Reverse-MAC-addresses-on-all-i.MX-de.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 8a00fc606312c68b98add8fe8e6f7a013ce29e78 Mon Sep 17 00:00:00 2001 -From: Alexander Stein -Date: Sun, 11 Jun 2023 15:03:06 +0100 -Subject: [PATCH] nvmem: imx-ocotp: Reverse MAC addresses on all i.MX derivates - -Not just i.MX8M, but all i.MX6/7 (and subtypes) need to reverse the -MAC address read from fuses. Exceptions are i.MX6SLL and i.MX7ULP which -do not support ethernet at all. - -Fixes: d0221a780cbc ("nvmem: imx-ocotp: add support for post processing") -Signed-off-by: Alexander Stein -Tested-by: Richard Leitner # imx6q -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-3-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/imx-ocotp.c | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -97,7 +97,6 @@ struct ocotp_params { - unsigned int bank_address_words; - void (*set_timing)(struct ocotp_priv *priv); - struct ocotp_ctrl_reg ctrl; -- bool reverse_mac_address; - }; - - static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags) -@@ -545,7 +544,6 @@ static const struct ocotp_params imx8mq_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -- .reverse_mac_address = true, - }; - - static const struct ocotp_params imx8mm_params = { -@@ -553,7 +551,6 @@ static const struct ocotp_params imx8mm_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -- .reverse_mac_address = true, - }; - - static const struct ocotp_params imx8mn_params = { -@@ -561,7 +558,6 @@ static const struct ocotp_params imx8mn_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_DEFAULT, -- .reverse_mac_address = true, - }; - - static const struct ocotp_params imx8mp_params = { -@@ -569,7 +565,6 @@ static const struct ocotp_params imx8mp_ - .bank_address_words = 0, - .set_timing = imx_ocotp_set_imx6_timing, - .ctrl = IMX_OCOTP_BM_CTRL_8MP, -- .reverse_mac_address = true, - }; - - static const struct of_device_id imx_ocotp_dt_ids[] = { -@@ -624,8 +619,7 @@ static int imx_ocotp_probe(struct platfo - imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; - imx_ocotp_nvmem_config.dev = dev; - imx_ocotp_nvmem_config.priv = priv; -- if (priv->params->reverse_mac_address) -- imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; -+ imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; - - priv->config = &imx_ocotp_nvmem_config; - diff --git a/target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch b/target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch deleted file mode 100644 index fb4d346a95add1..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0003-nvmem-brcm_nvram-add-.read_post_process-for-MACs.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 73bcd133c910bff3b6d3b3834d0d14be9444e90a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 11 Jun 2023 15:03:08 +0100 -Subject: [PATCH] nvmem: brcm_nvram: add .read_post_process() for MACs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -1. Parse ASCII MAC format into byte based -2. Calculate relative addresses based on index argument - -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-5-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 1 + - drivers/nvmem/brcm_nvram.c | 28 ++++++++++++++++++++++++++++ - 2 files changed, 29 insertions(+) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -55,6 +55,7 @@ config NVMEM_BRCM_NVRAM - tristate "Broadcom's NVRAM support" - depends on ARCH_BCM_5301X || COMPILE_TEST - depends on HAS_IOMEM -+ select GENERIC_NET_UTILS - help - This driver provides support for Broadcom's NVRAM that can be accessed - using I/O mapping. ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -4,6 +4,8 @@ - */ - - #include -+#include -+#include - #include - #include - #include -@@ -42,6 +44,25 @@ static int brcm_nvram_read(void *context - return 0; - } - -+static int brcm_nvram_read_post_process_macaddr(void *context, const char *id, int index, -+ unsigned int offset, void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (bytes != 3 * ETH_ALEN - 1) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ - static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data, - size_t len) - { -@@ -75,6 +96,13 @@ static int brcm_nvram_add_cells(struct b - priv->cells[idx].offset = value - (char *)data; - priv->cells[idx].bytes = strlen(value); - priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); -+ if (!strcmp(var, "et0macaddr") || -+ !strcmp(var, "et1macaddr") || -+ !strcmp(var, "et2macaddr")) { -+ priv->cells[idx].raw_len = strlen(value); -+ priv->cells[idx].bytes = ETH_ALEN; -+ priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr; -+ } - } - - return 0; diff --git a/target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch b/target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch deleted file mode 100644 index 3b6e6e57f52b44..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0004-nvmem-rockchip-otp-Add-clks-and-reg_read-to-rockchip.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 8dc61364164e79e44c07fa2ac0a7b6939f00d5db Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sun, 11 Jun 2023 15:03:13 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Add clks and reg_read to rockchip_data - -In preparation to support new Rockchip OTP memory devices with different -clock configurations and register layout, extend rockchip_data struct -with the related members: clks, num_clks, reg_read. - -Additionally, to avoid managing redundant driver data, drop num_clks -member from rockchip_otp struct and update all references to point to -the equivalent member in rockchip_data. - -Signed-off-by: Cristian Ciocaltea -Tested-by: Vincent Legoll -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-10-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 79 ++++++++++++++++++++++-------------- - 1 file changed, 49 insertions(+), 30 deletions(-) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -54,21 +54,19 @@ - - #define OTPC_TIMEOUT 10000 - -+struct rockchip_data { -+ int size; -+ const char * const *clks; -+ int num_clks; -+ nvmem_reg_read_t reg_read; -+}; -+ - struct rockchip_otp { - struct device *dev; - void __iomem *base; -- struct clk_bulk_data *clks; -- int num_clks; -+ struct clk_bulk_data *clks; - struct reset_control *rst; --}; -- --/* list of required clocks */ --static const char * const rockchip_otp_clocks[] = { -- "otp", "apb_pclk", "phy", --}; -- --struct rockchip_data { -- int size; -+ const struct rockchip_data *data; - }; - - static int rockchip_otp_reset(struct rockchip_otp *otp) -@@ -132,29 +130,23 @@ static int rockchip_otp_ecc_enable(struc - return ret; - } - --static int rockchip_otp_read(void *context, unsigned int offset, -- void *val, size_t bytes) -+static int px30_otp_read(void *context, unsigned int offset, -+ void *val, size_t bytes) - { - struct rockchip_otp *otp = context; - u8 *buf = val; -- int ret = 0; -- -- ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks); -- if (ret < 0) { -- dev_err(otp->dev, "failed to prepare/enable clks\n"); -- return ret; -- } -+ int ret; - - ret = rockchip_otp_reset(otp); - if (ret) { - dev_err(otp->dev, "failed to reset otp phy\n"); -- goto disable_clks; -+ return ret; - } - - ret = rockchip_otp_ecc_enable(otp, false); - if (ret < 0) { - dev_err(otp->dev, "rockchip_otp_ecc_enable err\n"); -- goto disable_clks; -+ return ret; - } - - writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); -@@ -174,8 +166,28 @@ static int rockchip_otp_read(void *conte - - read_end: - writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL); --disable_clks: -- clk_bulk_disable_unprepare(otp->num_clks, otp->clks); -+ -+ return ret; -+} -+ -+static int rockchip_otp_read(void *context, unsigned int offset, -+ void *val, size_t bytes) -+{ -+ struct rockchip_otp *otp = context; -+ int ret; -+ -+ if (!otp->data || !otp->data->reg_read) -+ return -EINVAL; -+ -+ ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks); -+ if (ret < 0) { -+ dev_err(otp->dev, "failed to prepare/enable clks\n"); -+ return ret; -+ } -+ -+ ret = otp->data->reg_read(context, offset, val, bytes); -+ -+ clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks); - - return ret; - } -@@ -189,8 +201,15 @@ static struct nvmem_config otp_config = - .reg_read = rockchip_otp_read, - }; - -+static const char * const px30_otp_clocks[] = { -+ "otp", "apb_pclk", "phy", -+}; -+ - static const struct rockchip_data px30_data = { - .size = 0x40, -+ .clks = px30_otp_clocks, -+ .num_clks = ARRAY_SIZE(px30_otp_clocks), -+ .reg_read = px30_otp_read, - }; - - static const struct of_device_id rockchip_otp_match[] = { -@@ -225,21 +244,21 @@ static int rockchip_otp_probe(struct pla - if (!otp) - return -ENOMEM; - -+ otp->data = data; - otp->dev = dev; - otp->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(otp->base)) - return PTR_ERR(otp->base); - -- otp->num_clks = ARRAY_SIZE(rockchip_otp_clocks); -- otp->clks = devm_kcalloc(dev, otp->num_clks, -- sizeof(*otp->clks), GFP_KERNEL); -+ otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks), -+ GFP_KERNEL); - if (!otp->clks) - return -ENOMEM; - -- for (i = 0; i < otp->num_clks; ++i) -- otp->clks[i].id = rockchip_otp_clocks[i]; -+ for (i = 0; i < data->num_clks; ++i) -+ otp->clks[i].id = data->clks[i]; - -- ret = devm_clk_bulk_get(dev, otp->num_clks, otp->clks); -+ ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks); - if (ret) - return ret; - diff --git a/target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch b/target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch deleted file mode 100644 index b5b66cfc5ac0d1..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0005-nvmem-rockchip-otp-Generalize-rockchip_otp_wait_stat.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 30fd21cfb1e64ef20035559a8246f5fbf682c40e Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sun, 11 Jun 2023 15:03:14 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Generalize rockchip_otp_wait_status() - -In preparation to support additional Rockchip OTP memory devices with -different register layout, generalize rockchip_otp_wait_status() to -accept a new parameter for specifying the offset of the status register. - -Signed-off-by: Cristian Ciocaltea -Tested-by: Vincent Legoll -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-11-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -90,18 +90,19 @@ static int rockchip_otp_reset(struct roc - return 0; - } - --static int rockchip_otp_wait_status(struct rockchip_otp *otp, u32 flag) -+static int rockchip_otp_wait_status(struct rockchip_otp *otp, -+ unsigned int reg, u32 flag) - { - u32 status = 0; - int ret; - -- ret = readl_poll_timeout_atomic(otp->base + OTPC_INT_STATUS, status, -+ ret = readl_poll_timeout_atomic(otp->base + reg, status, - (status & flag), 1, OTPC_TIMEOUT); - if (ret) - return ret; - - /* clean int status */ -- writel(flag, otp->base + OTPC_INT_STATUS); -+ writel(flag, otp->base + reg); - - return 0; - } -@@ -123,7 +124,7 @@ static int rockchip_otp_ecc_enable(struc - - writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL); - -- ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE); -+ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_SBPI_DONE); - if (ret < 0) - dev_err(otp->dev, "timeout during ecc_enable\n"); - -@@ -156,7 +157,7 @@ static int px30_otp_read(void *context, - otp->base + OTPC_USER_ADDR); - writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK, - otp->base + OTPC_USER_ENABLE); -- ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE); -+ ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_USER_DONE); - if (ret < 0) { - dev_err(otp->dev, "timeout during read setup\n"); - goto read_end; diff --git a/target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch b/target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch deleted file mode 100644 index 3a17479d959ba2..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0006-nvmem-rockchip-otp-Use-devm_reset_control_array_get_.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d325c9dd2b6e94040ca722ddcadcd6af358dd2be Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sun, 11 Jun 2023 15:03:15 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Use - devm_reset_control_array_get_exclusive() - -In preparation to support new Rockchip OTP memory devices having -specific reset configurations, switch devm_reset_control_get() to -devm_reset_control_array_get_exclusive(). - -Signed-off-by: Cristian Ciocaltea -Tested-by: Vincent Legoll -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-12-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -263,7 +263,7 @@ static int rockchip_otp_probe(struct pla - if (ret) - return ret; - -- otp->rst = devm_reset_control_get(dev, "phy"); -+ otp->rst = devm_reset_control_array_get_exclusive(dev); - if (IS_ERR(otp->rst)) - return PTR_ERR(otp->rst); - diff --git a/target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch b/target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch deleted file mode 100644 index 37cb927b100220..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0007-nvmem-rockchip-otp-Improve-probe-error-handling.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 912517345b867a69542dc9f5c2cc3e9d8beaccf5 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sun, 11 Jun 2023 15:03:16 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Improve probe error handling - -Enhance error handling in the probe function by making use of -dev_err_probe(), which ensures the error code is always printed, in -addition to the specified error message. - -Signed-off-by: Cristian Ciocaltea -Tested-by: Vincent Legoll -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-13-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -235,10 +235,8 @@ static int rockchip_otp_probe(struct pla - int ret, i; - - data = of_device_get_match_data(dev); -- if (!data) { -- dev_err(dev, "failed to get match data\n"); -- return -EINVAL; -- } -+ if (!data) -+ return dev_err_probe(dev, -EINVAL, "failed to get match data\n"); - - otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp), - GFP_KERNEL); -@@ -249,7 +247,8 @@ static int rockchip_otp_probe(struct pla - otp->dev = dev; - otp->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(otp->base)) -- return PTR_ERR(otp->base); -+ return dev_err_probe(dev, PTR_ERR(otp->base), -+ "failed to ioremap resource\n"); - - otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks), - GFP_KERNEL); -@@ -261,18 +260,22 @@ static int rockchip_otp_probe(struct pla - - ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks); - if (ret) -- return ret; -+ return dev_err_probe(dev, ret, "failed to get clocks\n"); - - otp->rst = devm_reset_control_array_get_exclusive(dev); - if (IS_ERR(otp->rst)) -- return PTR_ERR(otp->rst); -+ return dev_err_probe(dev, PTR_ERR(otp->rst), -+ "failed to get resets\n"); - - otp_config.size = data->size; - otp_config.priv = otp; - otp_config.dev = dev; -- nvmem = devm_nvmem_register(dev, &otp_config); - -- return PTR_ERR_OR_ZERO(nvmem); -+ nvmem = devm_nvmem_register(dev, &otp_config); -+ if (IS_ERR(nvmem)) -+ return dev_err_probe(dev, PTR_ERR(nvmem), -+ "failed to register nvmem device\n"); -+ return 0; - } - - static struct platform_driver rockchip_otp_driver = { diff --git a/target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch b/target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch deleted file mode 100644 index c1e2231c9ec940..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0008-nvmem-rockchip-otp-Add-support-for-RK3588.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 8ab099fafbbc8c9607c399d21a774784a6cb8b45 Mon Sep 17 00:00:00 2001 -From: Cristian Ciocaltea -Date: Sun, 11 Jun 2023 15:03:17 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3588 - -Add support for the OTP memory device found on the Rockchip RK3588 SoC. - -While here, remove the unnecessary 'void *' casts in the OF device ID -table. - -Co-developed-by: Finley Xiao -Signed-off-by: Finley Xiao -Signed-off-by: Cristian Ciocaltea -Tested-by: Vincent Legoll -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-14-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++- - 1 file changed, 76 insertions(+), 2 deletions(-) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -54,6 +54,19 @@ - - #define OTPC_TIMEOUT 10000 - -+/* RK3588 Register */ -+#define RK3588_OTPC_AUTO_CTRL 0x04 -+#define RK3588_OTPC_AUTO_EN 0x08 -+#define RK3588_OTPC_INT_ST 0x84 -+#define RK3588_OTPC_DOUT0 0x20 -+#define RK3588_NO_SECURE_OFFSET 0x300 -+#define RK3588_NBYTES 4 -+#define RK3588_BURST_NUM 1 -+#define RK3588_BURST_SHIFT 8 -+#define RK3588_ADDR_SHIFT 16 -+#define RK3588_AUTO_EN BIT(0) -+#define RK3588_RD_DONE BIT(1) -+ - struct rockchip_data { - int size; - const char * const *clks; -@@ -171,6 +184,52 @@ read_end: - return ret; - } - -+static int rk3588_otp_read(void *context, unsigned int offset, -+ void *val, size_t bytes) -+{ -+ struct rockchip_otp *otp = context; -+ unsigned int addr_start, addr_end, addr_len; -+ int ret, i = 0; -+ u32 data; -+ u8 *buf; -+ -+ addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES; -+ addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES; -+ addr_len = addr_end - addr_start; -+ addr_start += RK3588_NO_SECURE_OFFSET; -+ -+ buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ while (addr_len--) { -+ writel((addr_start << RK3588_ADDR_SHIFT) | -+ (RK3588_BURST_NUM << RK3588_BURST_SHIFT), -+ otp->base + RK3588_OTPC_AUTO_CTRL); -+ writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN); -+ -+ ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST, -+ RK3588_RD_DONE); -+ if (ret < 0) { -+ dev_err(otp->dev, "timeout during read setup\n"); -+ goto read_end; -+ } -+ -+ data = readl(otp->base + RK3588_OTPC_DOUT0); -+ memcpy(&buf[i], &data, RK3588_NBYTES); -+ -+ i += RK3588_NBYTES; -+ addr_start++; -+ } -+ -+ memcpy(val, buf + offset % RK3588_NBYTES, bytes); -+ -+read_end: -+ kfree(buf); -+ -+ return ret; -+} -+ - static int rockchip_otp_read(void *context, unsigned int offset, - void *val, size_t bytes) - { -@@ -213,14 +272,29 @@ static const struct rockchip_data px30_d - .reg_read = px30_otp_read, - }; - -+static const char * const rk3588_otp_clocks[] = { -+ "otp", "apb_pclk", "phy", "arb", -+}; -+ -+static const struct rockchip_data rk3588_data = { -+ .size = 0x400, -+ .clks = rk3588_otp_clocks, -+ .num_clks = ARRAY_SIZE(rk3588_otp_clocks), -+ .reg_read = rk3588_otp_read, -+}; -+ - static const struct of_device_id rockchip_otp_match[] = { - { - .compatible = "rockchip,px30-otp", -- .data = (void *)&px30_data, -+ .data = &px30_data, - }, - { - .compatible = "rockchip,rk3308-otp", -- .data = (void *)&px30_data, -+ .data = &px30_data, -+ }, -+ { -+ .compatible = "rockchip,rk3588-otp", -+ .data = &rk3588_data, - }, - { /* sentinel */ }, - }; diff --git a/target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch b/target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch deleted file mode 100644 index 220e3e9a05f303..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0009-nvmem-zynqmp-Switch-xilinx.com-emails-to-amd.com.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9734408969e978a1c0d5d752be63dd638288e374 Mon Sep 17 00:00:00 2001 -From: Michal Simek -Date: Sun, 11 Jun 2023 15:03:23 +0100 -Subject: [PATCH] nvmem: zynqmp: Switch @xilinx.com emails to @amd.com - -@xilinx.com is still working but better to switch to new amd.com after -AMD/Xilinx acquisition. - -Signed-off-by: Michal Simek -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-20-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/zynqmp_nvmem.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/zynqmp_nvmem.c -+++ b/drivers/nvmem/zynqmp_nvmem.c -@@ -76,6 +76,6 @@ static struct platform_driver zynqmp_nvm - - module_platform_driver(zynqmp_nvmem_driver); - --MODULE_AUTHOR("Michal Simek , Nava kishore Manne "); -+MODULE_AUTHOR("Michal Simek , Nava kishore Manne "); - MODULE_DESCRIPTION("ZynqMP NVMEM driver"); - MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch b/target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch deleted file mode 100644 index f8e6be4241604a..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0010-nvmem-imx-support-i.MX93-OCOTP.patch +++ /dev/null @@ -1,230 +0,0 @@ -From 22e9e6fcfb5042cb6d6c7874c459b034800092f1 Mon Sep 17 00:00:00 2001 -From: Peng Fan -Date: Sun, 11 Jun 2023 15:03:25 +0100 -Subject: [PATCH] nvmem: imx: support i.MX93 OCOTP - -Add i.MX93 OCOTP support. i.MX93 OCOTP has two parts: Fuse shadow -block(fsb) and fuse managed by ELE. The FSB part could be directly -accessed with MMIO, the ELE could only be accessed with ELE API. - -Currently the ELE API is not ready, so NULL function callback is used, -but it was tested with downstream ELE API. - -Signed-off-by: Peng Fan -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-22-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 9 ++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/imx-ocotp-ele.c | 175 ++++++++++++++++++++++++++++++++++ - 3 files changed, 186 insertions(+) - create mode 100644 drivers/nvmem/imx-ocotp-ele.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -83,6 +83,15 @@ config NVMEM_IMX_OCOTP - This driver can also be built as a module. If so, the module - will be called nvmem-imx-ocotp. - -+config NVMEM_IMX_OCOTP_ELE -+ tristate "i.MX On-Chip OTP Controller support" -+ depends on ARCH_MXC || COMPILE_TEST -+ depends on HAS_IOMEM -+ depends on OF -+ help -+ This is a driver for the On-Chip OTP Controller (OCOTP) -+ available on i.MX SoCs which has ELE. -+ - config NVMEM_IMX_OCOTP_SCU - tristate "i.MX8 SCU On-Chip OTP Controller support" - depends on IMX_SCU ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -18,6 +18,8 @@ obj-$(CONFIG_NVMEM_IMX_IIM) += nvmem-im - nvmem-imx-iim-y := imx-iim.o - obj-$(CONFIG_NVMEM_IMX_OCOTP) += nvmem-imx-ocotp.o - nvmem-imx-ocotp-y := imx-ocotp.o -+obj-$(CONFIG_NVMEM_IMX_OCOTP_ELE) += nvmem-imx-ocotp-ele.o -+nvmem-imx-ocotp-ele-y := imx-ocotp-ele.o - obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU) += nvmem-imx-ocotp-scu.o - nvmem-imx-ocotp-scu-y := imx-ocotp-scu.o - obj-$(CONFIG_NVMEM_JZ4780_EFUSE) += nvmem_jz4780_efuse.o ---- /dev/null -+++ b/drivers/nvmem/imx-ocotp-ele.c -@@ -0,0 +1,175 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * i.MX9 OCOTP fusebox driver -+ * -+ * Copyright 2023 NXP -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+enum fuse_type { -+ FUSE_FSB = 1, -+ FUSE_ELE = 2, -+ FUSE_INVALID = -1 -+}; -+ -+struct ocotp_map_entry { -+ u32 start; /* start word */ -+ u32 num; /* num words */ -+ enum fuse_type type; -+}; -+ -+struct ocotp_devtype_data { -+ u32 reg_off; -+ char *name; -+ u32 size; -+ u32 num_entry; -+ u32 flag; -+ nvmem_reg_read_t reg_read; -+ struct ocotp_map_entry entry[]; -+}; -+ -+struct imx_ocotp_priv { -+ struct device *dev; -+ void __iomem *base; -+ struct nvmem_config config; -+ struct mutex lock; -+ const struct ocotp_devtype_data *data; -+}; -+ -+static enum fuse_type imx_ocotp_fuse_type(void *context, u32 index) -+{ -+ struct imx_ocotp_priv *priv = context; -+ const struct ocotp_devtype_data *data = priv->data; -+ u32 start, end; -+ int i; -+ -+ for (i = 0; i < data->num_entry; i++) { -+ start = data->entry[i].start; -+ end = data->entry[i].start + data->entry[i].num; -+ -+ if (index >= start && index < end) -+ return data->entry[i].type; -+ } -+ -+ return FUSE_INVALID; -+} -+ -+static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, size_t bytes) -+{ -+ struct imx_ocotp_priv *priv = context; -+ void __iomem *reg = priv->base + priv->data->reg_off; -+ u32 count, index, num_bytes; -+ enum fuse_type type; -+ u32 *buf; -+ void *p; -+ int i; -+ -+ index = offset; -+ num_bytes = round_up(bytes, 4); -+ count = num_bytes >> 2; -+ -+ if (count > ((priv->data->size >> 2) - index)) -+ count = (priv->data->size >> 2) - index; -+ -+ p = kzalloc(num_bytes, GFP_KERNEL); -+ if (!p) -+ return -ENOMEM; -+ -+ mutex_lock(&priv->lock); -+ -+ buf = p; -+ -+ for (i = index; i < (index + count); i++) { -+ type = imx_ocotp_fuse_type(context, i); -+ if (type == FUSE_INVALID || type == FUSE_ELE) { -+ *buf++ = 0; -+ continue; -+ } -+ -+ *buf++ = readl_relaxed(reg + (i << 2)); -+ } -+ -+ memcpy(val, (u8 *)p, bytes); -+ -+ mutex_unlock(&priv->lock); -+ -+ kfree(p); -+ -+ return 0; -+}; -+ -+static int imx_ele_ocotp_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct imx_ocotp_priv *priv; -+ struct nvmem_device *nvmem; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->data = of_device_get_match_data(dev); -+ -+ priv->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(priv->base)) -+ return PTR_ERR(priv->base); -+ -+ priv->config.dev = dev; -+ priv->config.name = "ELE-OCOTP"; -+ priv->config.id = NVMEM_DEVID_AUTO; -+ priv->config.owner = THIS_MODULE; -+ priv->config.size = priv->data->size; -+ priv->config.reg_read = priv->data->reg_read; -+ priv->config.word_size = 4; -+ priv->config.stride = 1; -+ priv->config.priv = priv; -+ priv->config.read_only = true; -+ mutex_init(&priv->lock); -+ -+ nvmem = devm_nvmem_register(dev, &priv->config); -+ if (IS_ERR(nvmem)) -+ return PTR_ERR(nvmem); -+ -+ return 0; -+} -+ -+static const struct ocotp_devtype_data imx93_ocotp_data = { -+ .reg_off = 0x8000, -+ .reg_read = imx_ocotp_reg_read, -+ .size = 2048, -+ .num_entry = 6, -+ .entry = { -+ { 0, 52, FUSE_FSB }, -+ { 63, 1, FUSE_ELE}, -+ { 128, 16, FUSE_ELE }, -+ { 182, 1, FUSE_ELE }, -+ { 188, 1, FUSE_ELE }, -+ { 312, 200, FUSE_FSB } -+ }, -+}; -+ -+static const struct of_device_id imx_ele_ocotp_dt_ids[] = { -+ { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids); -+ -+static struct platform_driver imx_ele_ocotp_driver = { -+ .driver = { -+ .name = "imx_ele_ocotp", -+ .of_match_table = imx_ele_ocotp_dt_ids, -+ }, -+ .probe = imx_ele_ocotp_probe, -+}; -+module_platform_driver(imx_ele_ocotp_driver); -+ -+MODULE_DESCRIPTION("i.MX OCOTP/ELE driver"); -+MODULE_AUTHOR("Peng Fan "); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch b/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch deleted file mode 100644 index 3b4654822a4712..00000000000000 --- a/target/linux/generic/backport-6.1/813-v6.5-0011-nvmem-core-add-support-for-fixed-cells-layout.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 27f699e578b1a72df89dfa3bc42e093a01dc8d10 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 11 Jun 2023 15:03:29 +0100 -Subject: [PATCH] nvmem: core: add support for fixed cells *layout* -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This adds support for the "fixed-layout" NVMEM layout binding. It allows -defining NVMEM cells in a layout DT node named "nvmem-layout". - -While NVMEM subsystem supports layout drivers it has been discussed that -"fixed-layout" may actually be supperted internally. It's because: -1. It's a very basic layout -2. It allows sharing code with legacy syntax parsing -3. It's safer for soc_device_match() due to -EPROBE_DEFER -4. This will make the syntax transition easier - -Signed-off-by: Rafał Miłecki -Reviewed-by: Michael Walle -Signed-off-by: Srinivas Kandagatla -Message-ID: <20230611140330.154222-26-srinivas.kandagatla@linaro.org> -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 32 +++++++++++++++++++++++++++++--- - 1 file changed, 29 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -695,7 +695,7 @@ static int nvmem_validate_keepouts(struc - return 0; - } - --static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) -+static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) - { - struct nvmem_layout *layout = nvmem->layout; - struct device *dev = &nvmem->dev; -@@ -703,7 +703,7 @@ static int nvmem_add_cells_from_of(struc - const __be32 *addr; - int len, ret; - -- for_each_child_of_node(dev->of_node, child) { -+ for_each_child_of_node(np, child) { - struct nvmem_cell_info info = {0}; - - addr = of_get_property(child, "reg", &len); -@@ -741,6 +741,28 @@ static int nvmem_add_cells_from_of(struc - return 0; - } - -+static int nvmem_add_cells_from_legacy_of(struct nvmem_device *nvmem) -+{ -+ return nvmem_add_cells_from_dt(nvmem, nvmem->dev.of_node); -+} -+ -+static int nvmem_add_cells_from_fixed_layout(struct nvmem_device *nvmem) -+{ -+ struct device_node *layout_np; -+ int err = 0; -+ -+ layout_np = of_nvmem_layout_get_container(nvmem); -+ if (!layout_np) -+ return 0; -+ -+ if (of_device_is_compatible(layout_np, "fixed-layout")) -+ err = nvmem_add_cells_from_dt(nvmem, layout_np); -+ -+ of_node_put(layout_np); -+ -+ return err; -+} -+ - int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner) - { - layout->owner = owner; -@@ -971,7 +993,7 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -- rval = nvmem_add_cells_from_of(nvmem); -+ rval = nvmem_add_cells_from_legacy_of(nvmem); - if (rval) - goto err_remove_cells; - -@@ -981,6 +1003,10 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -+ rval = nvmem_add_cells_from_fixed_layout(nvmem); -+ if (rval) -+ goto err_remove_cells; -+ - rval = nvmem_add_cells_from_layout(nvmem); - if (rval) - goto err_remove_cells; diff --git a/target/linux/generic/backport-6.1/814-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch b/target/linux/generic/backport-6.1/814-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch deleted file mode 100644 index bf7a816bb225cc..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0001-nvmem-sunxi_sid-Convert-to-devm_platform_ioremap_res.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 9ccfcbeb8f32ff89e99b36cb9cdebaa0d1b44ed1 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:24 +0100 -Subject: [PATCH] nvmem: sunxi_sid: Convert to devm_platform_ioremap_resource() - -Use devm_platform_ioremap_resource() to simplify code. - -Signed-off-by: Yangtao Li -Acked-by: Jernej Skrabec -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sunxi_sid.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/nvmem/sunxi_sid.c -+++ b/drivers/nvmem/sunxi_sid.c -@@ -125,7 +125,6 @@ static int sun8i_sid_read_by_reg(void *c - static int sunxi_sid_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -- struct resource *res; - struct nvmem_config *nvmem_cfg; - struct nvmem_device *nvmem; - struct sunxi_sid *sid; -@@ -142,8 +141,7 @@ static int sunxi_sid_probe(struct platfo - return -EINVAL; - sid->value_offset = cfg->value_offset; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- sid->base = devm_ioremap_resource(dev, res); -+ sid->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(sid->base)) - return PTR_ERR(sid->base); - diff --git a/target/linux/generic/backport-6.1/814-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch b/target/linux/generic/backport-6.1/814-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch deleted file mode 100644 index f142d735de38c0..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0002-nvmem-brcm_nvram-Use-devm_platform_get_and_ioremap_r.patch +++ /dev/null @@ -1,30 +0,0 @@ -From cfadd0e7d9225566f320bc4dc716682be910be6c Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:25 +0100 -Subject: [PATCH] nvmem: brcm_nvram: Use - devm_platform_get_and_ioremap_resource() - -Convert platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/brcm_nvram.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -159,8 +159,7 @@ static int brcm_nvram_probe(struct platf - return -ENOMEM; - priv->dev = dev; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->base = devm_ioremap_resource(dev, res); -+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - diff --git a/target/linux/generic/backport-6.1/814-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch b/target/linux/generic/backport-6.1/814-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch deleted file mode 100644 index 0395bbf8bcef3e..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0003-nvmem-lpc18xx_otp-Convert-to-devm_platform_ioremap_r.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0b49178e2b6b4aac3c7fa3ce8d8c02208a13b988 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:26 +0100 -Subject: [PATCH] nvmem: lpc18xx_otp: Convert to - devm_platform_ioremap_resource() - -Use devm_platform_ioremap_resource() to simplify code. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/lpc18xx_otp.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/nvmem/lpc18xx_otp.c -+++ b/drivers/nvmem/lpc18xx_otp.c -@@ -68,14 +68,12 @@ static int lpc18xx_otp_probe(struct plat - { - struct nvmem_device *nvmem; - struct lpc18xx_otp *otp; -- struct resource *res; - - otp = devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL); - if (!otp) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- otp->base = devm_ioremap_resource(&pdev->dev, res); -+ otp->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(otp->base)) - return PTR_ERR(otp->base); - diff --git a/target/linux/generic/backport-6.1/814-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch b/target/linux/generic/backport-6.1/814-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch deleted file mode 100644 index da077eb4b745f6..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0004-nvmem-meson-mx-efuse-Convert-to-devm_platform_iorema.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0a223a097709b99a0ba738d6be5b4f52c04ffb64 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:27 +0100 -Subject: [PATCH] nvmem: meson-mx-efuse: Convert to - devm_platform_ioremap_resource() - -Use devm_platform_ioremap_resource() to simplify code. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/meson-mx-efuse.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/nvmem/meson-mx-efuse.c -+++ b/drivers/nvmem/meson-mx-efuse.c -@@ -194,7 +194,6 @@ static int meson_mx_efuse_probe(struct p - { - const struct meson_mx_efuse_platform_data *drvdata; - struct meson_mx_efuse *efuse; -- struct resource *res; - - drvdata = of_device_get_match_data(&pdev->dev); - if (!drvdata) -@@ -204,8 +203,7 @@ static int meson_mx_efuse_probe(struct p - if (!efuse) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- efuse->base = devm_ioremap_resource(&pdev->dev, res); -+ efuse->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(efuse->base)) - return PTR_ERR(efuse->base); - diff --git a/target/linux/generic/backport-6.1/814-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch b/target/linux/generic/backport-6.1/814-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch deleted file mode 100644 index dc144ddfbdfa86..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0005-nvmem-rockchip-efuse-Use-devm_platform_get_and_iorem.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 94904db28db49ac8fbb2a273d25156db26a3a985 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:28 +0100 -Subject: [PATCH] nvmem: rockchip-efuse: Use - devm_platform_get_and_ioremap_resource() - -Convert platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -Signed-off-by: Yangtao Li -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-efuse.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/rockchip-efuse.c -+++ b/drivers/nvmem/rockchip-efuse.c -@@ -267,8 +267,7 @@ static int rockchip_efuse_probe(struct p - if (!efuse) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- efuse->base = devm_ioremap_resource(dev, res); -+ efuse->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(efuse->base)) - return PTR_ERR(efuse->base); - diff --git a/target/linux/generic/backport-6.1/814-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch b/target/linux/generic/backport-6.1/814-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch deleted file mode 100644 index 99e20939ccf09f..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0006-nvmem-stm32-romem-Use-devm_platform_get_and_ioremap_.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0a4a8c0d238fec1fa4b85591524ef42ad261cb97 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:29 +0100 -Subject: [PATCH] nvmem: stm32-romem: Use - devm_platform_get_and_ioremap_resource() - -Convert platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -196,8 +196,7 @@ static int stm32_romem_probe(struct plat - if (!priv) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->base = devm_ioremap_resource(dev, res); -+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - diff --git a/target/linux/generic/backport-6.1/814-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch b/target/linux/generic/backport-6.1/814-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch deleted file mode 100644 index 6d93752e27177f..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0007-nvmem-qfprom-do-some-cleanup.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0bc0d6dc2a9a05ae6729b4622f09782d9f230815 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:30 +0100 -Subject: [PATCH] nvmem: qfprom: do some cleanup - -Use devm_platform_ioremap_resource() and -devm_platform_get_and_ioremap_resource() to simplify code. -BTW convert to use dev_err_probe() instead of open it. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/qfprom.c | 17 +++++------------ - 1 file changed, 5 insertions(+), 12 deletions(-) - ---- a/drivers/nvmem/qfprom.c -+++ b/drivers/nvmem/qfprom.c -@@ -374,8 +374,7 @@ static int qfprom_probe(struct platform_ - return -ENOMEM; - - /* The corrected section is always provided */ -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->qfpcorrected = devm_ioremap_resource(dev, res); -+ priv->qfpcorrected = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(priv->qfpcorrected)) - return PTR_ERR(priv->qfpcorrected); - -@@ -402,12 +401,10 @@ static int qfprom_probe(struct platform_ - priv->qfpraw = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->qfpraw)) - return PTR_ERR(priv->qfpraw); -- res = platform_get_resource(pdev, IORESOURCE_MEM, 2); -- priv->qfpconf = devm_ioremap_resource(dev, res); -+ priv->qfpconf = devm_platform_ioremap_resource(pdev, 2); - if (IS_ERR(priv->qfpconf)) - return PTR_ERR(priv->qfpconf); -- res = platform_get_resource(pdev, IORESOURCE_MEM, 3); -- priv->qfpsecurity = devm_ioremap_resource(dev, res); -+ priv->qfpsecurity = devm_platform_ioremap_resource(pdev, 3); - if (IS_ERR(priv->qfpsecurity)) - return PTR_ERR(priv->qfpsecurity); - -@@ -427,12 +424,8 @@ static int qfprom_probe(struct platform_ - return PTR_ERR(priv->vcc); - - priv->secclk = devm_clk_get(dev, "core"); -- if (IS_ERR(priv->secclk)) { -- ret = PTR_ERR(priv->secclk); -- if (ret != -EPROBE_DEFER) -- dev_err(dev, "Error getting clock: %d\n", ret); -- return ret; -- } -+ if (IS_ERR(priv->secclk)) -+ return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n"); - - /* Only enable writing if we have SoC data. */ - if (priv->soc_data) diff --git a/target/linux/generic/backport-6.1/814-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch b/target/linux/generic/backport-6.1/814-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch deleted file mode 100644 index 3e328a4c99914b..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0008-nvmem-uniphier-Use-devm_platform_get_and_ioremap_res.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 6ac41c556e22a0d7d267c9b9d48681d73af4b368 Mon Sep 17 00:00:00 2001 -From: Yangtao Li -Date: Wed, 23 Aug 2023 14:27:31 +0100 -Subject: [PATCH] nvmem: uniphier: Use devm_platform_get_and_ioremap_resource() - -Convert platform_get_resource(), devm_ioremap_resource() to a single -call to devm_platform_get_and_ioremap_resource(), as this is exactly -what this function does. - -Signed-off-by: Yangtao Li -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230823132744.350618-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/uniphier-efuse.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/nvmem/uniphier-efuse.c -+++ b/drivers/nvmem/uniphier-efuse.c -@@ -41,8 +41,7 @@ static int uniphier_efuse_probe(struct p - if (!priv) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- priv->base = devm_ioremap_resource(dev, res); -+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - diff --git a/target/linux/generic/backport-6.1/814-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch b/target/linux/generic/backport-6.1/814-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch deleted file mode 100644 index acbe18e270001f..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0009-nvmem-add-new-NXP-QorIQ-eFuse-driver.patch +++ /dev/null @@ -1,133 +0,0 @@ -From c8efcf7a86ebf2ff48584d270b3070a7075bc345 Mon Sep 17 00:00:00 2001 -From: Richard Alpe -Date: Mon, 10 Apr 2023 10:20:51 +0200 -Subject: [PATCH] nvmem: add new NXP QorIQ eFuse driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add SFP (Security Fuse Processor) read support for NXP (Freescale) -QorIQ series SOC's. - -This patch adds support for the T1023 SOC using the SFP offset from -the existing T1023 device tree. In theory this should also work for -T1024, T1014 and T1013 which uses the same SFP base offset. - -Signed-off-by: Richard Alpe -Reviewed-by: Niklas Söderlund -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/Kconfig | 12 ++++++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/qoriq-efuse.c | 78 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 92 insertions(+) - create mode 100644 drivers/nvmem/qoriq-efuse.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -392,4 +392,16 @@ config NVMEM_ZYNQMP - - If sure, say yes. If unsure, say no. - -+config NVMEM_QORIQ_EFUSE -+ tristate "NXP QorIQ eFuse support" -+ depends on PPC_85xx || COMPILE_TEST -+ depends on HAS_IOMEM -+ help -+ This driver provides read support for the eFuses (SFP) on NXP QorIQ -+ series SoC's. This includes secure boot settings, the globally unique -+ NXP ID 'FUIDR' and the OEM unique ID 'OUIDR'. -+ -+ This driver can also be built as a module. If so, the module -+ will be called nvmem_qoriq_efuse. -+ - endif ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -77,3 +77,5 @@ obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvme - nvmem-vf610-ocotp-y := vf610-ocotp.o - obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o - nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o -+obj-$(CONFIG_NVMEM_QORIQ_EFUSE) += nvmem-qoriq-efuse.o -+nvmem-qoriq-efuse-y := qoriq-efuse.o ---- /dev/null -+++ b/drivers/nvmem/qoriq-efuse.c -@@ -0,0 +1,78 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2023 Westermo Network Technologies AB -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct qoriq_efuse_priv { -+ void __iomem *base; -+}; -+ -+static int qoriq_efuse_read(void *context, unsigned int offset, void *val, -+ size_t bytes) -+{ -+ struct qoriq_efuse_priv *priv = context; -+ -+ /* .stride = 4 so offset is guaranteed to be aligned */ -+ __ioread32_copy(val, priv->base + offset, bytes / 4); -+ -+ /* Ignore trailing bytes (there shouldn't be any) */ -+ -+ return 0; -+} -+ -+static int qoriq_efuse_probe(struct platform_device *pdev) -+{ -+ struct nvmem_config config = { -+ .dev = &pdev->dev, -+ .read_only = true, -+ .reg_read = qoriq_efuse_read, -+ .stride = sizeof(u32), -+ .word_size = sizeof(u32), -+ .name = "qoriq_efuse_read", -+ .id = NVMEM_DEVID_AUTO, -+ .root_only = true, -+ }; -+ struct qoriq_efuse_priv *priv; -+ struct nvmem_device *nvmem; -+ struct resource *res; -+ -+ priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); -+ if (IS_ERR(priv->base)) -+ return PTR_ERR(priv->base); -+ -+ config.size = resource_size(res); -+ config.priv = priv; -+ nvmem = devm_nvmem_register(config.dev, &config); -+ -+ return PTR_ERR_OR_ZERO(nvmem); -+} -+ -+static const struct of_device_id qoriq_efuse_of_match[] = { -+ { .compatible = "fsl,t1023-sfp", }, -+ {/* sentinel */}, -+}; -+MODULE_DEVICE_TABLE(of, qoriq_efuse_of_match); -+ -+static struct platform_driver qoriq_efuse_driver = { -+ .probe = qoriq_efuse_probe, -+ .driver = { -+ .name = "qoriq-efuse", -+ .of_match_table = qoriq_efuse_of_match, -+ }, -+}; -+module_platform_driver(qoriq_efuse_driver); -+ -+MODULE_AUTHOR("Richard Alpe "); -+MODULE_DESCRIPTION("NXP QorIQ Security Fuse Processor (SFP) Reader"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.1/814-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch b/target/linux/generic/backport-6.1/814-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch deleted file mode 100644 index 67f30e34a2346f..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0011-nvmem-Kconfig-Fix-typo-drive-driver.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 9d53d595f688c9837e88a919229cc61a165c7b9e Mon Sep 17 00:00:00 2001 -From: Diederik de Haas -Date: Mon, 24 Jul 2023 13:36:22 +0200 -Subject: [PATCH] nvmem: Kconfig: Fix typo "drive" -> "driver" - -Fix typo where "driver" was meant instead of "drive". -While at it, also capitalize "OTP". - -Signed-off-by: Diederik de Haas -Reviewed-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/Kconfig | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -247,7 +247,7 @@ config NVMEM_ROCKCHIP_EFUSE - depends on ARCH_ROCKCHIP || COMPILE_TEST - depends on HAS_IOMEM - help -- This is a simple drive to dump specified values of Rockchip SoC -+ This is a simple driver to dump specified values of Rockchip SoC - from eFuse, such as cpu-leakage. - - This driver can also be built as a module. If so, the module -@@ -258,8 +258,8 @@ config NVMEM_ROCKCHIP_OTP - depends on ARCH_ROCKCHIP || COMPILE_TEST - depends on HAS_IOMEM - help -- This is a simple drive to dump specified values of Rockchip SoC -- from otp, such as cpu-leakage. -+ This is a simple driver to dump specified values of Rockchip SoC -+ from OTP, such as cpu-leakage. - - This driver can also be built as a module. If so, the module - will be called nvmem_rockchip_otp. diff --git a/target/linux/generic/backport-6.1/814-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch b/target/linux/generic/backport-6.1/814-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch deleted file mode 100644 index af4a2926dc273c..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0012-nvmem-sec-qfprom-Add-Qualcomm-secure-QFPROM-support.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0a9ec38c47c1ca4528aa058e2b9ea61901a7e632 Mon Sep 17 00:00:00 2001 -From: Komal Bajaj -Date: Tue, 1 Aug 2023 12:10:25 +0530 -Subject: [PATCH] nvmem: sec-qfprom: Add Qualcomm secure QFPROM support - -For some of the Qualcomm SoC's, it is possible that -some of the fuse regions or entire qfprom region is -protected from non-secure access. In such situations, -the OS will have to use secure calls to read the region. -With that motivation, add secure qfprom driver. - -Signed-off-by: Komal Bajaj -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/Kconfig | 13 ++++++ - drivers/nvmem/Makefile | 2 + - drivers/nvmem/sec-qfprom.c | 96 ++++++++++++++++++++++++++++++++++++++ - 3 files changed, 111 insertions(+) - create mode 100644 drivers/nvmem/sec-qfprom.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -226,6 +226,19 @@ config NVMEM_QCOM_QFPROM - This driver can also be built as a module. If so, the module - will be called nvmem_qfprom. - -+config NVMEM_QCOM_SEC_QFPROM -+ tristate "QCOM SECURE QFPROM Support" -+ depends on ARCH_QCOM || COMPILE_TEST -+ depends on HAS_IOMEM -+ depends on OF -+ select QCOM_SCM -+ help -+ Say y here to enable secure QFPROM support. The secure QFPROM provides access -+ functions for QFPROM data to rest of the drivers via nvmem interface. -+ -+ This driver can also be built as a module. If so, the module will be called -+ nvmem_sec_qfprom. -+ - config NVMEM_RAVE_SP_EEPROM - tristate "Rave SP EEPROM Support" - depends on RAVE_SP_CORE ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -46,6 +46,8 @@ obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvme - nvmem-nintendo-otp-y := nintendo-otp.o - obj-$(CONFIG_NVMEM_QCOM_QFPROM) += nvmem_qfprom.o - nvmem_qfprom-y := qfprom.o -+obj-$(CONFIG_NVMEM_QCOM_SEC_QFPROM) += nvmem_sec_qfprom.o -+nvmem_sec_qfprom-y := sec-qfprom.o - obj-$(CONFIG_NVMEM_RAVE_SP_EEPROM) += nvmem-rave-sp-eeprom.o - nvmem-rave-sp-eeprom-y := rave-sp-eeprom.o - obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o ---- /dev/null -+++ b/drivers/nvmem/sec-qfprom.c -@@ -0,0 +1,96 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * struct sec_qfprom - structure holding secure qfprom attributes -+ * -+ * @base: starting physical address for secure qfprom corrected address space. -+ * @dev: qfprom device structure. -+ */ -+struct sec_qfprom { -+ phys_addr_t base; -+ struct device *dev; -+}; -+ -+static int sec_qfprom_reg_read(void *context, unsigned int reg, void *_val, size_t bytes) -+{ -+ struct sec_qfprom *priv = context; -+ unsigned int i; -+ u8 *val = _val; -+ u32 read_val; -+ u8 *tmp; -+ -+ for (i = 0; i < bytes; i++, reg++) { -+ if (i == 0 || reg % 4 == 0) { -+ if (qcom_scm_io_readl(priv->base + (reg & ~3), &read_val)) { -+ dev_err(priv->dev, "Couldn't access fuse register\n"); -+ return -EINVAL; -+ } -+ tmp = (u8 *)&read_val; -+ } -+ -+ val[i] = tmp[reg & 3]; -+ } -+ -+ return 0; -+} -+ -+static int sec_qfprom_probe(struct platform_device *pdev) -+{ -+ struct nvmem_config econfig = { -+ .name = "sec-qfprom", -+ .stride = 1, -+ .word_size = 1, -+ .id = NVMEM_DEVID_AUTO, -+ .reg_read = sec_qfprom_reg_read, -+ }; -+ struct device *dev = &pdev->dev; -+ struct nvmem_device *nvmem; -+ struct sec_qfprom *priv; -+ struct resource *res; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -EINVAL; -+ -+ priv->base = res->start; -+ -+ econfig.size = resource_size(res); -+ econfig.dev = dev; -+ econfig.priv = priv; -+ -+ priv->dev = dev; -+ -+ nvmem = devm_nvmem_register(dev, &econfig); -+ -+ return PTR_ERR_OR_ZERO(nvmem); -+} -+ -+static const struct of_device_id sec_qfprom_of_match[] = { -+ { .compatible = "qcom,sec-qfprom" }, -+ {/* sentinel */}, -+}; -+MODULE_DEVICE_TABLE(of, sec_qfprom_of_match); -+ -+static struct platform_driver qfprom_driver = { -+ .probe = sec_qfprom_probe, -+ .driver = { -+ .name = "qcom_sec_qfprom", -+ .of_match_table = sec_qfprom_of_match, -+ }, -+}; -+module_platform_driver(qfprom_driver); -+MODULE_DESCRIPTION("Qualcomm Secure QFPROM driver"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.1/814-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch b/target/linux/generic/backport-6.1/814-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch deleted file mode 100644 index dab8ec2c241dfe..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0013-nvmem-u-boot-env-Replace-zero-length-array-with-DECL.patch +++ /dev/null @@ -1,30 +0,0 @@ -From c32f2186acc9abb4d766361255d7ddf07d15eeb2 Mon Sep 17 00:00:00 2001 -From: Atul Raut -Date: Sun, 30 Jul 2023 15:39:15 -0700 -Subject: [PATCH] nvmem: u-boot-env:: Replace zero-length array with - DECLARE_FLEX_ARRAY() helper - -We are moving toward replacing zero-length arrays with C99 flexible-array -members since they are deprecated. Therefore, the new DECLARE_FLEX_ARRAY() -helper macro should be used to replace the zero-length array declaration. - -This fixes warnings such as: -./drivers/nvmem/u-boot-env.c:50:9-13: WARNING use flexible-array member instead (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays) - -Signed-off-by: Atul Raut -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/u-boot-env.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -47,7 +47,7 @@ struct u_boot_env_image_broadcom { - __le32 magic; - __le32 len; - __le32 crc32; -- uint8_t data[0]; -+ DECLARE_FLEX_ARRAY(uint8_t, data); - } __packed; - - static int u_boot_env_read(void *context, unsigned int offset, void *val, diff --git a/target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch b/target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch deleted file mode 100644 index 990ce8ecf1c7d4..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0014-nvmem-core-Create-all-cells-before-adding-the-nvmem-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 104af6a5b199eb4dc7970d1304aef38ac5a6ed54 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 8 Aug 2023 08:29:26 +0200 -Subject: [PATCH] nvmem: core: Create all cells before adding the nvmem device - -Let's pack all the cells creation in one place, so they are all created -before we add the nvmem device. - -Signed-off-by: Miquel Raynal -Reviewed-by: Michael Walle -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/core.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -997,17 +997,17 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -- dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); -- -- rval = device_add(&nvmem->dev); -+ rval = nvmem_add_cells_from_fixed_layout(nvmem); - if (rval) - goto err_remove_cells; - -- rval = nvmem_add_cells_from_fixed_layout(nvmem); -+ rval = nvmem_add_cells_from_layout(nvmem); - if (rval) - goto err_remove_cells; - -- rval = nvmem_add_cells_from_layout(nvmem); -+ dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); -+ -+ rval = device_add(&nvmem->dev); - if (rval) - goto err_remove_cells; - diff --git a/target/linux/generic/backport-6.1/814-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch b/target/linux/generic/backport-6.1/814-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch deleted file mode 100644 index 8f64d0c28b8599..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0015-nvmem-core-Return-NULL-when-no-nvmem-layout-is-found.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6c7f48ea2e663b679aa8e60d8d8e1e6306a644f9 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 8 Aug 2023 08:29:27 +0200 -Subject: [PATCH] nvmem: core: Return NULL when no nvmem layout is found - -Currently, of_nvmem_layout_get_container() returns NULL on error, or an -error pointer if either CONFIG_NVMEM or CONFIG_OF is turned off. We -should likely avoid this kind of mix for two reasons: to clarify the -intend and anyway fix the !CONFIG_OF which will likely always if we use -this helper somewhere else. Let's just return NULL when no layout is -found, we don't need an error value here. - -Link: https://staticthinking.wordpress.com/2022/08/01/mixing-error-pointers-and-null/ -Fixes: 266570f496b9 ("nvmem: core: introduce NVMEM layouts") -Reported-by: kernel test robot -Reported-by: Dan Carpenter -Closes: https://lore.kernel.org/r/202308030002.DnSFOrMB-lkp@intel.com/ -Signed-off-by: Miquel Raynal -Reviewed-by: Michael Walle -Signed-off-by: Srinivas Kandagatla ---- - include/linux/nvmem-consumer.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -256,7 +256,7 @@ static inline struct nvmem_device *of_nv - static inline struct device_node * - of_nvmem_layout_get_container(struct nvmem_device *nvmem) - { -- return ERR_PTR(-EOPNOTSUPP); -+ return NULL; - } - #endif /* CONFIG_NVMEM && CONFIG_OF */ - diff --git a/target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch b/target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch deleted file mode 100644 index 4ebf229695d258..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0016-nvmem-core-Do-not-open-code-existing-functions.patch +++ /dev/null @@ -1,29 +0,0 @@ -From b8257f61b4ddac6d7d0e19a5a4e8b07afb3b4ed3 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 8 Aug 2023 08:29:28 +0200 -Subject: [PATCH] nvmem: core: Do not open-code existing functions - -Use of_nvmem_layout_get_container() instead of hardcoding it. - -Signed-off-by: Miquel Raynal -Reviewed-by: Michael Walle -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/core.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -785,10 +785,10 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste - - static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) - { -- struct device_node *layout_np, *np = nvmem->dev.of_node; -+ struct device_node *layout_np; - struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER); - -- layout_np = of_get_child_by_name(np, "nvmem-layout"); -+ layout_np = of_nvmem_layout_get_container(nvmem); - if (!layout_np) - return NULL; - diff --git a/target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch b/target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch deleted file mode 100644 index 6803397d60b720..00000000000000 --- a/target/linux/generic/backport-6.1/814-v6.6-0017-nvmem-core-Notify-when-a-new-layout-is-registered.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0991afbe4b1805e7f0113ef10d7c5f0698a739e4 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 8 Aug 2023 08:29:29 +0200 -Subject: [PATCH] nvmem: core: Notify when a new layout is registered - -Tell listeners a new layout was introduced and is now available. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla ---- - drivers/nvmem/core.c | 4 ++++ - include/linux/nvmem-consumer.h | 2 ++ - 2 files changed, 6 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -771,12 +771,16 @@ int __nvmem_layout_register(struct nvmem - list_add(&layout->node, &nvmem_layouts); - spin_unlock(&nvmem_layout_lock); - -+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_ADD, layout); -+ - return 0; - } - EXPORT_SYMBOL_GPL(__nvmem_layout_register); - - void nvmem_layout_unregister(struct nvmem_layout *layout) - { -+ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_REMOVE, layout); -+ - spin_lock(&nvmem_layout_lock); - list_del(&layout->node); - spin_unlock(&nvmem_layout_lock); ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -43,6 +43,8 @@ enum { - NVMEM_REMOVE, - NVMEM_CELL_ADD, - NVMEM_CELL_REMOVE, -+ NVMEM_LAYOUT_ADD, -+ NVMEM_LAYOUT_REMOVE, - }; - - #if IS_ENABLED(CONFIG_NVMEM) diff --git a/target/linux/generic/backport-6.1/815-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch b/target/linux/generic/backport-6.1/815-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch deleted file mode 100644 index e17be439b24db1..00000000000000 --- a/target/linux/generic/backport-6.1/815-v6.6-1-leds-turris-omnia-Use-sysfs_emit-instead-of-sprintf.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a75b58a46423cfd9b1f73581f4bd2ac2ae743996 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Wed, 2 Aug 2023 18:07:45 +0200 -Subject: [PATCH 1/6] leds: turris-omnia: Use sysfs_emit() instead of sprintf() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use the dedicated sysfs_emit() function instead of sprintf() in sysfs -attribute accessor brightness_show(). - -Signed-off-by: Marek Behún -Link: https://lore.kernel.org/r/20230802160748.11208-4-kabel@kernel.org -Signed-off-by: Lee Jones ---- - drivers/leds/leds-turris-omnia.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -194,7 +194,7 @@ static ssize_t brightness_show(struct de - if (ret < 0) - return ret; - -- return sprintf(buf, "%d\n", ret); -+ return sysfs_emit(buf, "%d\n", ret); - } - - static ssize_t brightness_store(struct device *dev, struct device_attribute *a, diff --git a/target/linux/generic/backport-6.1/815-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch b/target/linux/generic/backport-6.1/815-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch deleted file mode 100644 index d84ad671259100..00000000000000 --- a/target/linux/generic/backport-6.1/815-v6.7-2-leds-turris-omnia-Make-set_brightness-more-efficient.patch +++ /dev/null @@ -1,207 +0,0 @@ -From a64c3c1357275b1fd61bc9734f638cdb5d8a8bbb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Mon, 18 Sep 2023 18:11:02 +0200 -Subject: [PATCH 4/6] leds: turris-omnia: Make set_brightness() more efficient -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Implement caching of the LED color and state values that are sent to MCU -in order to make the set_brightness() operation more efficient by -avoiding I2C transactions which are not needed. - -On Turris Omnia's MCU, which acts as the RGB LED controller, each LED -has a RGB color, and a ON/OFF state, which are configurable via I2C -commands CMD_LED_COLOR and CMD_LED_STATE. - -The CMD_LED_COLOR command sends 5 bytes and the CMD_LED_STATE command 2 -bytes over the I2C bus, which operates at 100 kHz. With I2C overhead -this allows ~1670 color changing commands and ~3200 state changing -commands per second (or around 1000 color + state changes per second). -This may seem more than enough, but the issue is that the I2C bus is -shared with another peripheral, the MCU. The MCU exposes an interrupt -interface, and it can trigger hundreds of interrupts per second. Each -time, we need to read the interrupt state register over this I2C bus. -Whenever we are sending a LED color/state changing command, the -interrupt reading is waiting. - -Currently, every time LED brightness or LED multi intensity is changed, -we send a CMD_LED_STATE command, and if the computed color (brightness -adjusted multi_intensity) is non-zero, we also send a CMD_LED_COLOR -command. - -Consider for example the situation when we have a netdev trigger enabled -for a LED. The netdev trigger does not change the LED color, only the -brightness (either to 0 or to currently configured brightness), and so -there is no need to send the CMD_LED_COLOR command. But each change of -brightness to 0 sends one CMD_LED_STATE command, and each change of -brightness to max_brightness sends one CMD_LED_STATE command and one -CMD_LED_COLOR command: - set_brightness(0) -> CMD_LED_STATE - set_brightness(255) -> CMD_LED_STATE + CMD_LED_COLOR - (unnecessary) - -We can avoid the unnecessary I2C transactions if we cache the values of -state and color that are sent to the controller. If the color does not -change from the one previously sent, there is no need to do the -CMD_LED_COLOR I2C transaction, and if the state does not change, there -is no need to do the CMD_LED_STATE transaction. - -Because we need to make sure that our cached values are consistent with -the controller state, add explicit setting of the LED color to white at -probe time (this is the default setting when MCU resets, but does not -necessarily need to be the case, for example if U-Boot played with the -LED colors). - -Signed-off-by: Marek Behún -Link: https://lore.kernel.org/r/20230918161104.20860-3-kabel@kernel.org -Signed-off-by: Lee Jones ---- - drivers/leds/leds-turris-omnia.c | 96 ++++++++++++++++++++++++++------ - 1 file changed, 78 insertions(+), 18 deletions(-) - ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -30,6 +30,8 @@ - struct omnia_led { - struct led_classdev_mc mc_cdev; - struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS]; -+ u8 cached_channels[OMNIA_LED_NUM_CHANNELS]; -+ bool on; - int reg; - }; - -@@ -72,36 +74,82 @@ static int omnia_cmd_read_u8(const struc - return -EIO; - } - -+static int omnia_led_send_color_cmd(const struct i2c_client *client, -+ struct omnia_led *led) -+{ -+ char cmd[5]; -+ int ret; -+ -+ cmd[0] = CMD_LED_COLOR; -+ cmd[1] = led->reg; -+ cmd[2] = led->subled_info[0].brightness; -+ cmd[3] = led->subled_info[1].brightness; -+ cmd[4] = led->subled_info[2].brightness; -+ -+ /* Send the color change command */ -+ ret = i2c_master_send(client, cmd, 5); -+ if (ret < 0) -+ return ret; -+ -+ /* Cache the RGB channel brightnesses */ -+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i) -+ led->cached_channels[i] = led->subled_info[i].brightness; -+ -+ return 0; -+} -+ -+/* Determine if the computed RGB channels are different from the cached ones */ -+static bool omnia_led_channels_changed(struct omnia_led *led) -+{ -+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i) -+ if (led->subled_info[i].brightness != led->cached_channels[i]) -+ return true; -+ -+ return false; -+} -+ - static int omnia_led_brightness_set_blocking(struct led_classdev *cdev, - enum led_brightness brightness) - { - struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); - struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); - struct omnia_led *led = to_omnia_led(mc_cdev); -- u8 buf[5], state; -- int ret; -+ int err = 0; - - mutex_lock(&leds->lock); - -- led_mc_calc_color_components(&led->mc_cdev, brightness); -+ /* -+ * Only recalculate RGB brightnesses from intensities if brightness is -+ * non-zero. Otherwise we won't be using them and we can save ourselves -+ * some software divisions (Omnia's CPU does not implement the division -+ * instruction). -+ */ -+ if (brightness) { -+ led_mc_calc_color_components(mc_cdev, brightness); -+ -+ /* -+ * Send color command only if brightness is non-zero and the RGB -+ * channel brightnesses changed. -+ */ -+ if (omnia_led_channels_changed(led)) -+ err = omnia_led_send_color_cmd(leds->client, led); -+ } - -- buf[0] = CMD_LED_COLOR; -- buf[1] = led->reg; -- buf[2] = mc_cdev->subled_info[0].brightness; -- buf[3] = mc_cdev->subled_info[1].brightness; -- buf[4] = mc_cdev->subled_info[2].brightness; -- -- state = CMD_LED_STATE_LED(led->reg); -- if (buf[2] || buf[3] || buf[4]) -- state |= CMD_LED_STATE_ON; -- -- ret = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state); -- if (ret >= 0 && (state & CMD_LED_STATE_ON)) -- ret = i2c_master_send(leds->client, buf, 5); -+ /* Send on/off state change only if (bool)brightness changed */ -+ if (!err && !brightness != !led->on) { -+ u8 state = CMD_LED_STATE_LED(led->reg); -+ -+ if (brightness) -+ state |= CMD_LED_STATE_ON; -+ -+ err = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state); -+ if (!err) -+ led->on = !!brightness; -+ } - - mutex_unlock(&leds->lock); - -- return ret; -+ return err; - } - - static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, -@@ -129,11 +177,15 @@ static int omnia_led_register(struct i2c - } - - led->subled_info[0].color_index = LED_COLOR_ID_RED; -- led->subled_info[0].channel = 0; - led->subled_info[1].color_index = LED_COLOR_ID_GREEN; -- led->subled_info[1].channel = 1; - led->subled_info[2].color_index = LED_COLOR_ID_BLUE; -- led->subled_info[2].channel = 2; -+ -+ /* Initial color is white */ -+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i) { -+ led->subled_info[i].intensity = 255; -+ led->subled_info[i].brightness = 255; -+ led->subled_info[i].channel = i; -+ } - - led->mc_cdev.subled_info = led->subled_info; - led->mc_cdev.num_colors = OMNIA_LED_NUM_CHANNELS; -@@ -162,6 +214,14 @@ static int omnia_led_register(struct i2c - return ret; - } - -+ /* Set initial color and cache it */ -+ ret = omnia_led_send_color_cmd(client, led); -+ if (ret < 0) { -+ dev_err(dev, "Cannot set LED %pOF initial color: %i\n", np, -+ ret); -+ return ret; -+ } -+ - ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev, - &init_data); - if (ret < 0) { diff --git a/target/linux/generic/backport-6.1/815-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch b/target/linux/generic/backport-6.1/815-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch deleted file mode 100644 index 00773ab0f63293..00000000000000 --- a/target/linux/generic/backport-6.1/815-v6.7-3-leds-turris-omnia-Support-HW-controlled-mode-via-pri.patch +++ /dev/null @@ -1,202 +0,0 @@ -From e965e0f6de60874fc0a0caed9a9e0122999e0c7b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Mon, 18 Sep 2023 18:11:03 +0200 -Subject: [PATCH 5/6] leds: turris-omnia: Support HW controlled mode via - private trigger -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add support for enabling MCU controlled mode of the Turris Omnia LEDs -via a LED private trigger called "omnia-mcu". Recall that private LED -triggers will only be listed in the sysfs trigger file for LEDs that -support them (currently there is no user of this mechanism). - -When in MCU controlled mode, the user can still set LED color, but the -blinking is done by MCU, which does different things for different LEDs: -- WAN LED is blinked according to the LED[0] pin of the WAN PHY -- LAN LEDs are blinked according to the LED[0] output of the - corresponding port of the LAN switch -- PCIe LEDs are blinked according to the logical OR of the MiniPCIe port - LED pins - -In the future I want to make the netdev trigger to transparently offload -the blinking to the HW if user sets compatible settings for the netdev -trigger (for LEDs associated with network devices). -There was some work on this already, and hopefully we will be able to -complete it sometime, but for now there are still multiple blockers for -this, and even if there weren't, we still would not be able to configure -HW controlled mode for the LEDs associated with MiniPCIe ports. - -In the meantime let's support HW controlled mode via the private LED -trigger mechanism. If, in the future, we manage to complete the netdev -trigger offloading, we can still keep this private trigger for backwards -compatibility, if needed. - -We also set "omnia-mcu" to cdev->default_trigger, so that the MCU keeps -control until the user first wants to take over it. If a different -default trigger is specified in device-tree via the -'linux,default-trigger' property, LED class will overwrite -cdev->default_trigger, and so the DT property will be respected. - -Signed-off-by: Marek Behún -Link: https://lore.kernel.org/r/20230918161104.20860-4-kabel@kernel.org -Signed-off-by: Lee Jones ---- - drivers/leds/Kconfig | 1 + - drivers/leds/leds-turris-omnia.c | 98 +++++++++++++++++++++++++++++--- - 2 files changed, 91 insertions(+), 8 deletions(-) - ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -164,6 +164,7 @@ config LEDS_TURRIS_OMNIA - depends on I2C - depends on MACH_ARMADA_38X || COMPILE_TEST - depends on OF -+ select LEDS_TRIGGERS - help - This option enables basic support for the LEDs found on the front - side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -31,7 +31,7 @@ struct omnia_led { - struct led_classdev_mc mc_cdev; - struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS]; - u8 cached_channels[OMNIA_LED_NUM_CHANNELS]; -- bool on; -+ bool on, hwtrig; - int reg; - }; - -@@ -120,12 +120,14 @@ static int omnia_led_brightness_set_bloc - - /* - * Only recalculate RGB brightnesses from intensities if brightness is -- * non-zero. Otherwise we won't be using them and we can save ourselves -- * some software divisions (Omnia's CPU does not implement the division -- * instruction). -+ * non-zero (if it is zero and the LED is in HW blinking mode, we use -+ * max_brightness as brightness). Otherwise we won't be using them and -+ * we can save ourselves some software divisions (Omnia's CPU does not -+ * implement the division instruction). - */ -- if (brightness) { -- led_mc_calc_color_components(mc_cdev, brightness); -+ if (brightness || led->hwtrig) { -+ led_mc_calc_color_components(mc_cdev, brightness ?: -+ cdev->max_brightness); - - /* - * Send color command only if brightness is non-zero and the RGB -@@ -135,8 +137,11 @@ static int omnia_led_brightness_set_bloc - err = omnia_led_send_color_cmd(leds->client, led); - } - -- /* Send on/off state change only if (bool)brightness changed */ -- if (!err && !brightness != !led->on) { -+ /* -+ * Send on/off state change only if (bool)brightness changed and the LED -+ * is not being blinked by HW. -+ */ -+ if (!err && !led->hwtrig && !brightness != !led->on) { - u8 state = CMD_LED_STATE_LED(led->reg); - - if (brightness) -@@ -152,6 +157,71 @@ static int omnia_led_brightness_set_bloc - return err; - } - -+static struct led_hw_trigger_type omnia_hw_trigger_type; -+ -+static int omnia_hwtrig_activate(struct led_classdev *cdev) -+{ -+ struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); -+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); -+ struct omnia_led *led = to_omnia_led(mc_cdev); -+ int err = 0; -+ -+ mutex_lock(&leds->lock); -+ -+ if (!led->on) { -+ /* -+ * If the LED is off (brightness was set to 0), the last -+ * configured color was not necessarily sent to the MCU. -+ * Recompute with max_brightness and send if needed. -+ */ -+ led_mc_calc_color_components(mc_cdev, cdev->max_brightness); -+ -+ if (omnia_led_channels_changed(led)) -+ err = omnia_led_send_color_cmd(leds->client, led); -+ } -+ -+ if (!err) { -+ /* Put the LED into MCU controlled mode */ -+ err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE, -+ CMD_LED_MODE_LED(led->reg)); -+ if (!err) -+ led->hwtrig = true; -+ } -+ -+ mutex_unlock(&leds->lock); -+ -+ return err; -+} -+ -+static void omnia_hwtrig_deactivate(struct led_classdev *cdev) -+{ -+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); -+ struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev)); -+ int err; -+ -+ mutex_lock(&leds->lock); -+ -+ led->hwtrig = false; -+ -+ /* Put the LED into software mode */ -+ err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE, -+ CMD_LED_MODE_LED(led->reg) | -+ CMD_LED_MODE_USER); -+ -+ mutex_unlock(&leds->lock); -+ -+ if (err < 0) -+ dev_err(cdev->dev, "Cannot put LED to software mode: %i\n", -+ err); -+} -+ -+static struct led_trigger omnia_hw_trigger = { -+ .name = "omnia-mcu", -+ .activate = omnia_hwtrig_activate, -+ .deactivate = omnia_hwtrig_deactivate, -+ .trigger_type = &omnia_hw_trigger_type, -+}; -+ - static int omnia_led_register(struct i2c_client *client, struct omnia_led *led, - struct device_node *np) - { -@@ -195,6 +265,12 @@ static int omnia_led_register(struct i2c - cdev = &led->mc_cdev.led_cdev; - cdev->max_brightness = 255; - cdev->brightness_set_blocking = omnia_led_brightness_set_blocking; -+ cdev->trigger_type = &omnia_hw_trigger_type; -+ /* -+ * Use the omnia-mcu trigger as the default trigger. It may be rewritten -+ * by LED class from the linux,default-trigger property. -+ */ -+ cdev->default_trigger = omnia_hw_trigger.name; - - /* put the LED into software mode */ - ret = omnia_cmd_write_u8(client, CMD_LED_MODE, -@@ -309,6 +385,12 @@ static int omnia_leds_probe(struct i2c_c - - mutex_init(&leds->lock); - -+ ret = devm_led_trigger_register(dev, &omnia_hw_trigger); -+ if (ret < 0) { -+ dev_err(dev, "Cannot register private LED trigger: %d\n", ret); -+ return ret; -+ } -+ - led = &leds->leds[0]; - for_each_available_child_of_node(np, child) { - ret = omnia_led_register(client, led, child); diff --git a/target/linux/generic/backport-6.1/815-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch b/target/linux/generic/backport-6.1/815-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch deleted file mode 100644 index e98397922d286b..00000000000000 --- a/target/linux/generic/backport-6.1/815-v6.7-4-leds-turris-omnia-Add-support-for-enabling-disabling.patch +++ /dev/null @@ -1,244 +0,0 @@ -From 0efb3f9609d3de5a7d8c31e3835d7eb3e6adce79 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Mon, 18 Sep 2023 18:11:04 +0200 -Subject: [PATCH 6/6] leds: turris-omnia: Add support for enabling/disabling HW - gamma correction -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If the MCU on Turris Omnia is running newer firmware versions, the LED -controller supports RGB gamma correction (and enables it by default for -newer boards). - -Determine whether the gamma correction setting feature is supported and -add the ability to set it via sysfs attribute file. - -Signed-off-by: Marek Behún -Link: https://lore.kernel.org/r/20230918161104.20860-5-kabel@kernel.org -Signed-off-by: Lee Jones ---- - .../sysfs-class-led-driver-turris-omnia | 14 ++ - drivers/leds/leds-turris-omnia.c | 137 +++++++++++++++--- - 2 files changed, 134 insertions(+), 17 deletions(-) - ---- a/Documentation/ABI/testing/sysfs-class-led-driver-turris-omnia -+++ b/Documentation/ABI/testing/sysfs-class-led-driver-turris-omnia -@@ -12,3 +12,17 @@ Description: (RW) On the front panel of - able to change this setting from software. - - Format: %i -+ -+What: /sys/class/leds//device/gamma_correction -+Date: August 2023 -+KernelVersion: 6.6 -+Contact: Marek Behún -+Description: (RW) Newer versions of the microcontroller firmware of the -+ Turris Omnia router support gamma correction for the RGB LEDs. -+ This feature can be enabled/disabled by writing to this file. -+ -+ If the feature is not supported because the MCU firmware is too -+ old, the file always reads as 0, and writing to the file results -+ in the EOPNOTSUPP error. -+ -+ Format: %i ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -15,17 +15,30 @@ - #define OMNIA_BOARD_LEDS 12 - #define OMNIA_LED_NUM_CHANNELS 3 - --#define CMD_LED_MODE 3 --#define CMD_LED_MODE_LED(l) ((l) & 0x0f) --#define CMD_LED_MODE_USER 0x10 -- --#define CMD_LED_STATE 4 --#define CMD_LED_STATE_LED(l) ((l) & 0x0f) --#define CMD_LED_STATE_ON 0x10 -- --#define CMD_LED_COLOR 5 --#define CMD_LED_SET_BRIGHTNESS 7 --#define CMD_LED_GET_BRIGHTNESS 8 -+/* MCU controller commands at I2C address 0x2a */ -+#define OMNIA_MCU_I2C_ADDR 0x2a -+ -+#define CMD_GET_STATUS_WORD 0x01 -+#define STS_FEATURES_SUPPORTED BIT(2) -+ -+#define CMD_GET_FEATURES 0x10 -+#define FEAT_LED_GAMMA_CORRECTION BIT(5) -+ -+/* LED controller commands at I2C address 0x2b */ -+#define CMD_LED_MODE 0x03 -+#define CMD_LED_MODE_LED(l) ((l) & 0x0f) -+#define CMD_LED_MODE_USER 0x10 -+ -+#define CMD_LED_STATE 0x04 -+#define CMD_LED_STATE_LED(l) ((l) & 0x0f) -+#define CMD_LED_STATE_ON 0x10 -+ -+#define CMD_LED_COLOR 0x05 -+#define CMD_LED_SET_BRIGHTNESS 0x07 -+#define CMD_LED_GET_BRIGHTNESS 0x08 -+ -+#define CMD_SET_GAMMA_CORRECTION 0x30 -+#define CMD_GET_GAMMA_CORRECTION 0x31 - - struct omnia_led { - struct led_classdev_mc mc_cdev; -@@ -40,6 +53,7 @@ struct omnia_led { - struct omnia_leds { - struct i2c_client *client; - struct mutex lock; -+ bool has_gamma_correction; - struct omnia_led leds[]; - }; - -@@ -50,30 +64,42 @@ static int omnia_cmd_write_u8(const stru - return i2c_master_send(client, buf, sizeof(buf)); - } - --static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd) -+static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd, -+ void *reply, size_t len) - { - struct i2c_msg msgs[2]; -- u8 reply; - int ret; - -- msgs[0].addr = client->addr; -+ msgs[0].addr = addr; - msgs[0].flags = 0; - msgs[0].len = 1; - msgs[0].buf = &cmd; -- msgs[1].addr = client->addr; -+ msgs[1].addr = addr; - msgs[1].flags = I2C_M_RD; -- msgs[1].len = 1; -- msgs[1].buf = &reply; -+ msgs[1].len = len; -+ msgs[1].buf = reply; - -- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); -+ ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)); - if (likely(ret == ARRAY_SIZE(msgs))) -- return reply; -+ return len; - else if (ret < 0) - return ret; - else - return -EIO; - } - -+static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd) -+{ -+ u8 reply; -+ int ret; -+ -+ ret = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1); -+ if (ret < 0) -+ return ret; -+ -+ return reply; -+} -+ - static int omnia_led_send_color_cmd(const struct i2c_client *client, - struct omnia_led *led) - { -@@ -352,12 +378,74 @@ static ssize_t brightness_store(struct d - } - static DEVICE_ATTR_RW(brightness); - -+static ssize_t gamma_correction_show(struct device *dev, -+ struct device_attribute *a, char *buf) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct omnia_leds *leds = i2c_get_clientdata(client); -+ int ret; -+ -+ if (leds->has_gamma_correction) { -+ ret = omnia_cmd_read_u8(client, CMD_GET_GAMMA_CORRECTION); -+ if (ret < 0) -+ return ret; -+ } else { -+ ret = 0; -+ } -+ -+ return sysfs_emit(buf, "%d\n", !!ret); -+} -+ -+static ssize_t gamma_correction_store(struct device *dev, -+ struct device_attribute *a, -+ const char *buf, size_t count) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct omnia_leds *leds = i2c_get_clientdata(client); -+ bool val; -+ int ret; -+ -+ if (!leds->has_gamma_correction) -+ return -EOPNOTSUPP; -+ -+ if (kstrtobool(buf, &val) < 0) -+ return -EINVAL; -+ -+ ret = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val); -+ -+ return ret < 0 ? ret : count; -+} -+static DEVICE_ATTR_RW(gamma_correction); -+ - static struct attribute *omnia_led_controller_attrs[] = { - &dev_attr_brightness.attr, -+ &dev_attr_gamma_correction.attr, - NULL, - }; - ATTRIBUTE_GROUPS(omnia_led_controller); - -+static int omnia_mcu_get_features(const struct i2c_client *client) -+{ -+ u16 reply; -+ int err; -+ -+ err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR, -+ CMD_GET_STATUS_WORD, &reply, sizeof(reply)); -+ if (err < 0) -+ return err; -+ -+ /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */ -+ if (!(le16_to_cpu(reply) & STS_FEATURES_SUPPORTED)) -+ return 0; -+ -+ err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR, -+ CMD_GET_FEATURES, &reply, sizeof(reply)); -+ if (err < 0) -+ return err; -+ -+ return le16_to_cpu(reply); -+} -+ - static int omnia_leds_probe(struct i2c_client *client, - const struct i2c_device_id *id) - { -@@ -383,6 +471,21 @@ static int omnia_leds_probe(struct i2c_c - leds->client = client; - i2c_set_clientdata(client, leds); - -+ ret = omnia_mcu_get_features(client); -+ if (ret < 0) { -+ dev_err(dev, "Cannot determine MCU supported features: %d\n", -+ ret); -+ return ret; -+ } -+ -+ leds->has_gamma_correction = ret & FEAT_LED_GAMMA_CORRECTION; -+ if (!leds->has_gamma_correction) { -+ dev_info(dev, -+ "Your board's MCU firmware does not support the LED gamma correction feature.\n"); -+ dev_info(dev, -+ "Consider upgrading MCU firmware with the omnia-mcutool utility.\n"); -+ } -+ - mutex_init(&leds->lock); - - ret = devm_led_trigger_register(dev, &omnia_hw_trigger); diff --git a/target/linux/generic/backport-6.1/815-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch b/target/linux/generic/backport-6.1/815-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch deleted file mode 100644 index b0cebdcf149005..00000000000000 --- a/target/linux/generic/backport-6.1/815-v6.7-5-leds-turris-omnia-Fix-brightness-setting-and-trigger.patch +++ /dev/null @@ -1,167 +0,0 @@ -From ffec49d391c5f0195360912b216aa24dbc9b53c8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Mon, 16 Oct 2023 16:15:38 +0200 -Subject: [PATCH] leds: turris-omnia: Fix brightness setting and trigger - activating -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -I have improperly refactored commits - 4d5ed2621c24 ("leds: turris-omnia: Make set_brightness() more efficient") -and - aaf38273cf76 ("leds: turris-omnia: Support HW controlled mode via private trigger") -after Lee requested a change in API semantics of the new functions I -introduced in commit - 28350bc0ac77 ("leds: turris-omnia: Do not use SMBUS calls"). - -Before the change, the function omnia_cmd_write_u8() returned 0 on -success, and afterwards it returned a positive value (number of bytes -written). The latter version was applied, but the following commits did -not properly account for this change. - -This results in non-functional LED's .brightness_set_blocking() and -trigger's .activate() methods. - -The main reasoning behind the semantics change was that read/write -methods should return the number of read/written bytes on success. -It was pointed to me [1] that this is not always true (for example the -regmap API does not do so), and since the driver never uses this number -of read/written bytes information, I decided to fix this issue by -changing the functions to the original semantics (return 0 on success). - -[1] https://lore.kernel.org/linux-gpio/ZQnn+Gi0xVlsGCYA@smile.fi.intel.com/ - -Fixes: 28350bc0ac77 ("leds: turris-omnia: Do not use SMBUS calls") -Signed-off-by: Marek Behún ---- - drivers/leds/leds-turris-omnia.c | 37 +++++++++++++++++--------------- - 1 file changed, 20 insertions(+), 17 deletions(-) - ---- a/drivers/leds/leds-turris-omnia.c -+++ b/drivers/leds/leds-turris-omnia.c -@@ -60,8 +60,11 @@ struct omnia_leds { - static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val) - { - u8 buf[2] = { cmd, val }; -+ int ret; -+ -+ ret = i2c_master_send(client, buf, sizeof(buf)); - -- return i2c_master_send(client, buf, sizeof(buf)); -+ return ret < 0 ? ret : 0; - } - - static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd, -@@ -81,7 +84,7 @@ static int omnia_cmd_read_raw(struct i2c - - ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)); - if (likely(ret == ARRAY_SIZE(msgs))) -- return len; -+ return 0; - else if (ret < 0) - return ret; - else -@@ -91,11 +94,11 @@ static int omnia_cmd_read_raw(struct i2c - static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd) - { - u8 reply; -- int ret; -+ int err; - -- ret = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1); -- if (ret < 0) -- return ret; -+ err = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1); -+ if (err) -+ return err; - - return reply; - } -@@ -236,7 +239,7 @@ static void omnia_hwtrig_deactivate(stru - - mutex_unlock(&leds->lock); - -- if (err < 0) -+ if (err) - dev_err(cdev->dev, "Cannot put LED to software mode: %i\n", - err); - } -@@ -302,7 +305,7 @@ static int omnia_led_register(struct i2c - ret = omnia_cmd_write_u8(client, CMD_LED_MODE, - CMD_LED_MODE_LED(led->reg) | - CMD_LED_MODE_USER); -- if (ret < 0) { -+ if (ret) { - dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np, - ret); - return ret; -@@ -311,7 +314,7 @@ static int omnia_led_register(struct i2c - /* disable the LED */ - ret = omnia_cmd_write_u8(client, CMD_LED_STATE, - CMD_LED_STATE_LED(led->reg)); -- if (ret < 0) { -+ if (ret) { - dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret); - return ret; - } -@@ -364,7 +367,7 @@ static ssize_t brightness_store(struct d - { - struct i2c_client *client = to_i2c_client(dev); - unsigned long brightness; -- int ret; -+ int err; - - if (kstrtoul(buf, 10, &brightness)) - return -EINVAL; -@@ -372,9 +375,9 @@ static ssize_t brightness_store(struct d - if (brightness > 100) - return -EINVAL; - -- ret = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness); -+ err = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness); - -- return ret < 0 ? ret : count; -+ return err ?: count; - } - static DEVICE_ATTR_RW(brightness); - -@@ -403,7 +406,7 @@ static ssize_t gamma_correction_store(st - struct i2c_client *client = to_i2c_client(dev); - struct omnia_leds *leds = i2c_get_clientdata(client); - bool val; -- int ret; -+ int err; - - if (!leds->has_gamma_correction) - return -EOPNOTSUPP; -@@ -411,9 +414,9 @@ static ssize_t gamma_correction_store(st - if (kstrtobool(buf, &val) < 0) - return -EINVAL; - -- ret = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val); -+ err = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val); - -- return ret < 0 ? ret : count; -+ return err ?: count; - } - static DEVICE_ATTR_RW(gamma_correction); - -@@ -431,7 +434,7 @@ static int omnia_mcu_get_features(const - - err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR, - CMD_GET_STATUS_WORD, &reply, sizeof(reply)); -- if (err < 0) -+ if (err) - return err; - - /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */ -@@ -440,7 +443,7 @@ static int omnia_mcu_get_features(const - - err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR, - CMD_GET_FEATURES, &reply, sizeof(reply)); -- if (err < 0) -+ if (err) - return err; - - return le16_to_cpu(reply); diff --git a/target/linux/generic/backport-6.1/816-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch b/target/linux/generic/backport-6.1/816-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch deleted file mode 100644 index 66d402814057c4..00000000000000 --- a/target/linux/generic/backport-6.1/816-v6.7-0001-nvmem-qfprom-Mark-core-clk-as-optional.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 16724d6ea40a2c9315f5a0d81005dfa4d7a6da24 Mon Sep 17 00:00:00 2001 -From: Luca Weiss -Date: Fri, 20 Oct 2023 11:55:40 +0100 -Subject: [PATCH] nvmem: qfprom: Mark core clk as optional - -On some platforms like sc7280 on non-ChromeOS devices the core clock -cannot be touched by Linux so we cannot provide it. Mark it as optional -as accessing qfprom for reading works without it but we still prohibit -writing if we cannot provide the clock. - -Signed-off-by: Luca Weiss -Reviewed-by: Douglas Anderson -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231020105545.216052-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/qfprom.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/qfprom.c -+++ b/drivers/nvmem/qfprom.c -@@ -423,12 +423,12 @@ static int qfprom_probe(struct platform_ - if (IS_ERR(priv->vcc)) - return PTR_ERR(priv->vcc); - -- priv->secclk = devm_clk_get(dev, "core"); -+ priv->secclk = devm_clk_get_optional(dev, "core"); - if (IS_ERR(priv->secclk)) - return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n"); - -- /* Only enable writing if we have SoC data. */ -- if (priv->soc_data) -+ /* Only enable writing if we have SoC data and a valid clock */ -+ if (priv->soc_data && priv->secclk) - econfig.reg_write = qfprom_reg_write; - } - diff --git a/target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch b/target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch deleted file mode 100644 index 547122ae48b1f4..00000000000000 --- a/target/linux/generic/backport-6.1/816-v6.7-0002-nvmem-add-explicit-config-option-to-read-old-syntax-.patch +++ /dev/null @@ -1,330 +0,0 @@ -From 2cc3b37f5b6df8189d55d0e812d9658ce256dfec Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 20 Oct 2023 11:55:41 +0100 -Subject: [PATCH] nvmem: add explicit config option to read old syntax fixed OF - cells -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Binding for fixed NVMEM cells defined directly as NVMEM device subnodes -has been deprecated. It has been replaced by the "fixed-layout" NVMEM -layout binding. - -New syntax is meant to be clearer and should help avoiding imprecise -bindings. - -NVMEM subsystem already supports the new binding. It should be a good -idea to limit support for old syntax to existing drivers that actually -support & use it (we can't break backward compatibility!). That way we -additionally encourage new bindings & drivers to ignore deprecated -binding. - -It wasn't clear (to me) if rtc and w1 code actually uses old syntax -fixed cells. I enabled them to don't risk any breakage. - -Signed-off-by: Rafał Miłecki -[for meson-{efuse,mx-efuse}.c] -Acked-by: Martin Blumenstingl -[for mtk-efuse.c, nvmem/core.c, nvmem-provider.h] -Reviewed-by: AngeloGioacchino Del Regno -[MT8192, MT8195 Chromebooks] -Tested-by: AngeloGioacchino Del Regno -[for microchip-otpc.c] -Reviewed-by: Claudiu Beznea -[SAMA7G5-EK] -Tested-by: Claudiu Beznea -Acked-by: Jernej Skrabec -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231020105545.216052-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/mtd/mtdcore.c | 2 ++ - drivers/nvmem/apple-efuses.c | 1 + - drivers/nvmem/core.c | 8 +++++--- - drivers/nvmem/imx-ocotp-scu.c | 1 + - drivers/nvmem/imx-ocotp.c | 1 + - drivers/nvmem/meson-efuse.c | 1 + - drivers/nvmem/meson-mx-efuse.c | 1 + - drivers/nvmem/microchip-otpc.c | 1 + - drivers/nvmem/mtk-efuse.c | 1 + - drivers/nvmem/qcom-spmi-sdam.c | 1 + - drivers/nvmem/qfprom.c | 1 + - drivers/nvmem/rave-sp-eeprom.c | 1 + - drivers/nvmem/rockchip-efuse.c | 1 + - drivers/nvmem/sc27xx-efuse.c | 1 + - drivers/nvmem/sec-qfprom.c | 1 + - drivers/nvmem/sprd-efuse.c | 1 + - drivers/nvmem/stm32-romem.c | 1 + - drivers/nvmem/sunplus-ocotp.c | 1 + - drivers/nvmem/sunxi_sid.c | 1 + - drivers/nvmem/uniphier-efuse.c | 1 + - drivers/nvmem/zynqmp_nvmem.c | 1 + - drivers/rtc/nvmem.c | 1 + - drivers/w1/slaves/w1_ds250x.c | 1 + - include/linux/nvmem-provider.h | 2 ++ - 24 files changed, 30 insertions(+), 3 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -523,6 +523,7 @@ static int mtd_nvmem_add(struct mtd_info - config.dev = &mtd->dev; - config.name = dev_name(&mtd->dev); - config.owner = THIS_MODULE; -+ config.add_legacy_fixed_of_cells = of_device_is_compatible(node, "nvmem-cells"); - config.reg_read = mtd_nvmem_reg_read; - config.size = mtd->size; - config.word_size = 1; -@@ -891,6 +892,7 @@ static struct nvmem_device *mtd_otp_nvme - config.name = compatible; - config.id = NVMEM_DEVID_AUTO; - config.owner = THIS_MODULE; -+ config.add_legacy_fixed_of_cells = true; - config.type = NVMEM_TYPE_OTP; - config.root_only = true; - config.ignore_wp = true; ---- a/drivers/nvmem/apple-efuses.c -+++ b/drivers/nvmem/apple-efuses.c -@@ -36,6 +36,7 @@ static int apple_efuses_probe(struct pla - struct resource *res; - struct nvmem_config config = { - .dev = &pdev->dev, -+ .add_legacy_fixed_of_cells = true, - .read_only = true, - .reg_read = apple_efuses_read, - .stride = sizeof(u32), ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -997,9 +997,11 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -- rval = nvmem_add_cells_from_legacy_of(nvmem); -- if (rval) -- goto err_remove_cells; -+ if (config->add_legacy_fixed_of_cells) { -+ rval = nvmem_add_cells_from_legacy_of(nvmem); -+ if (rval) -+ goto err_remove_cells; -+ } - - rval = nvmem_add_cells_from_fixed_layout(nvmem); - if (rval) ---- a/drivers/nvmem/imx-ocotp-scu.c -+++ b/drivers/nvmem/imx-ocotp-scu.c -@@ -220,6 +220,7 @@ static int imx_scu_ocotp_write(void *con - - static struct nvmem_config imx_scu_ocotp_nvmem_config = { - .name = "imx-scu-ocotp", -+ .add_legacy_fixed_of_cells = true, - .read_only = false, - .word_size = 4, - .stride = 1, ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -616,6 +616,7 @@ static int imx_ocotp_probe(struct platfo - return PTR_ERR(priv->clk); - - priv->params = of_device_get_match_data(&pdev->dev); -+ imx_ocotp_nvmem_config.add_legacy_fixed_of_cells = true; - imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; - imx_ocotp_nvmem_config.dev = dev; - imx_ocotp_nvmem_config.priv = priv; ---- a/drivers/nvmem/meson-efuse.c -+++ b/drivers/nvmem/meson-efuse.c -@@ -80,6 +80,7 @@ static int meson_efuse_probe(struct plat - - econfig->dev = dev; - econfig->name = dev_name(dev); -+ econfig->add_legacy_fixed_of_cells = true; - econfig->stride = 1; - econfig->word_size = 1; - econfig->reg_read = meson_efuse_read; ---- a/drivers/nvmem/meson-mx-efuse.c -+++ b/drivers/nvmem/meson-mx-efuse.c -@@ -211,6 +211,7 @@ static int meson_mx_efuse_probe(struct p - efuse->config.owner = THIS_MODULE; - efuse->config.dev = &pdev->dev; - efuse->config.priv = efuse; -+ efuse->config.add_legacy_fixed_of_cells = true; - efuse->config.stride = drvdata->word_size; - efuse->config.word_size = drvdata->word_size; - efuse->config.size = SZ_512; ---- a/drivers/nvmem/microchip-otpc.c -+++ b/drivers/nvmem/microchip-otpc.c -@@ -261,6 +261,7 @@ static int mchp_otpc_probe(struct platfo - return ret; - - mchp_nvmem_config.dev = otpc->dev; -+ mchp_nvmem_config.add_legacy_fixed_of_cells = true; - mchp_nvmem_config.size = size; - mchp_nvmem_config.priv = otpc; - nvmem = devm_nvmem_register(&pdev->dev, &mchp_nvmem_config); ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -83,6 +83,7 @@ static int mtk_efuse_probe(struct platfo - return PTR_ERR(priv->base); - - pdata = device_get_match_data(dev); -+ econfig.add_legacy_fixed_of_cells = true; - econfig.stride = 1; - econfig.word_size = 1; - econfig.reg_read = mtk_reg_read; ---- a/drivers/nvmem/qcom-spmi-sdam.c -+++ b/drivers/nvmem/qcom-spmi-sdam.c -@@ -142,6 +142,7 @@ static int sdam_probe(struct platform_de - sdam->sdam_config.name = "spmi_sdam"; - sdam->sdam_config.id = NVMEM_DEVID_AUTO; - sdam->sdam_config.owner = THIS_MODULE; -+ sdam->sdam_config.add_legacy_fixed_of_cells = true; - sdam->sdam_config.stride = 1; - sdam->sdam_config.word_size = 1; - sdam->sdam_config.reg_read = sdam_read; ---- a/drivers/nvmem/qfprom.c -+++ b/drivers/nvmem/qfprom.c -@@ -357,6 +357,7 @@ static int qfprom_probe(struct platform_ - { - struct nvmem_config econfig = { - .name = "qfprom", -+ .add_legacy_fixed_of_cells = true, - .stride = 1, - .word_size = 1, - .id = NVMEM_DEVID_AUTO, ---- a/drivers/nvmem/rave-sp-eeprom.c -+++ b/drivers/nvmem/rave-sp-eeprom.c -@@ -328,6 +328,7 @@ static int rave_sp_eeprom_probe(struct p - of_property_read_string(np, "zii,eeprom-name", &config.name); - config.priv = eeprom; - config.dev = dev; -+ config.add_legacy_fixed_of_cells = true; - config.size = size; - config.reg_read = rave_sp_eeprom_reg_read; - config.reg_write = rave_sp_eeprom_reg_write; ---- a/drivers/nvmem/rockchip-efuse.c -+++ b/drivers/nvmem/rockchip-efuse.c -@@ -205,6 +205,7 @@ static int rockchip_rk3399_efuse_read(vo - - static struct nvmem_config econfig = { - .name = "rockchip-efuse", -+ .add_legacy_fixed_of_cells = true, - .stride = 1, - .word_size = 1, - .read_only = true, ---- a/drivers/nvmem/sc27xx-efuse.c -+++ b/drivers/nvmem/sc27xx-efuse.c -@@ -248,6 +248,7 @@ static int sc27xx_efuse_probe(struct pla - econfig.reg_read = sc27xx_efuse_read; - econfig.priv = efuse; - econfig.dev = &pdev->dev; -+ econfig.add_legacy_fixed_of_cells = true; - nvmem = devm_nvmem_register(&pdev->dev, &econfig); - if (IS_ERR(nvmem)) { - dev_err(&pdev->dev, "failed to register nvmem config\n"); ---- a/drivers/nvmem/sec-qfprom.c -+++ b/drivers/nvmem/sec-qfprom.c -@@ -47,6 +47,7 @@ static int sec_qfprom_probe(struct platf - { - struct nvmem_config econfig = { - .name = "sec-qfprom", -+ .add_legacy_fixed_of_cells = true, - .stride = 1, - .word_size = 1, - .id = NVMEM_DEVID_AUTO, ---- a/drivers/nvmem/sprd-efuse.c -+++ b/drivers/nvmem/sprd-efuse.c -@@ -408,6 +408,7 @@ static int sprd_efuse_probe(struct platf - econfig.read_only = false; - econfig.name = "sprd-efuse"; - econfig.size = efuse->data->blk_nums * SPRD_EFUSE_BLOCK_WIDTH; -+ econfig.add_legacy_fixed_of_cells = true; - econfig.reg_read = sprd_efuse_read; - econfig.reg_write = sprd_efuse_write; - econfig.priv = efuse; ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -207,6 +207,7 @@ static int stm32_romem_probe(struct plat - priv->cfg.priv = priv; - priv->cfg.owner = THIS_MODULE; - priv->cfg.type = NVMEM_TYPE_OTP; -+ priv->cfg.add_legacy_fixed_of_cells = true; - - priv->lower = 0; - ---- a/drivers/nvmem/sunplus-ocotp.c -+++ b/drivers/nvmem/sunplus-ocotp.c -@@ -145,6 +145,7 @@ disable_clk: - - static struct nvmem_config sp_ocotp_nvmem_config = { - .name = "sp-ocotp", -+ .add_legacy_fixed_of_cells = true, - .read_only = true, - .word_size = 1, - .size = QAC628_OTP_SIZE, ---- a/drivers/nvmem/sunxi_sid.c -+++ b/drivers/nvmem/sunxi_sid.c -@@ -154,6 +154,7 @@ static int sunxi_sid_probe(struct platfo - nvmem_cfg->dev = dev; - nvmem_cfg->name = "sunxi-sid"; - nvmem_cfg->type = NVMEM_TYPE_OTP; -+ nvmem_cfg->add_legacy_fixed_of_cells = true; - nvmem_cfg->read_only = true; - nvmem_cfg->size = cfg->size; - nvmem_cfg->word_size = 1; ---- a/drivers/nvmem/uniphier-efuse.c -+++ b/drivers/nvmem/uniphier-efuse.c -@@ -52,6 +52,7 @@ static int uniphier_efuse_probe(struct p - econfig.size = resource_size(res); - econfig.priv = priv; - econfig.dev = dev; -+ econfig.add_legacy_fixed_of_cells = true; - nvmem = devm_nvmem_register(dev, &econfig); - - return PTR_ERR_OR_ZERO(nvmem); ---- a/drivers/nvmem/zynqmp_nvmem.c -+++ b/drivers/nvmem/zynqmp_nvmem.c -@@ -58,6 +58,7 @@ static int zynqmp_nvmem_probe(struct pla - - priv->dev = dev; - econfig.dev = dev; -+ econfig.add_legacy_fixed_of_cells = true; - econfig.reg_read = zynqmp_nvmem_read; - econfig.priv = priv; - ---- a/drivers/rtc/nvmem.c -+++ b/drivers/rtc/nvmem.c -@@ -21,6 +21,7 @@ int devm_rtc_nvmem_register(struct rtc_d - - nvmem_config->dev = dev; - nvmem_config->owner = rtc->owner; -+ nvmem_config->add_legacy_fixed_of_cells = true; - nvmem = devm_nvmem_register(dev, nvmem_config); - if (IS_ERR(nvmem)) - dev_err(dev, "failed to register nvmem device for RTC\n"); ---- a/drivers/w1/slaves/w1_ds250x.c -+++ b/drivers/w1/slaves/w1_ds250x.c -@@ -168,6 +168,7 @@ static int w1_eprom_add_slave(struct w1_ - struct nvmem_device *nvmem; - struct nvmem_config nvmem_cfg = { - .dev = &sl->dev, -+ .add_legacy_fixed_of_cells = true, - .reg_read = w1_nvmem_read, - .type = NVMEM_TYPE_OTP, - .read_only = true, ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -82,6 +82,7 @@ struct nvmem_cell_info { - * @owner: Pointer to exporter module. Used for refcounting. - * @cells: Optional array of pre-defined NVMEM cells. - * @ncells: Number of elements in cells. -+ * @add_legacy_fixed_of_cells: Read fixed NVMEM cells from old OF syntax. - * @keepout: Optional array of keepout ranges (sorted ascending by start). - * @nkeepout: Number of elements in the keepout array. - * @type: Type of the nvmem storage -@@ -112,6 +113,7 @@ struct nvmem_config { - struct module *owner; - const struct nvmem_cell_info *cells; - int ncells; -+ bool add_legacy_fixed_of_cells; - const struct nvmem_keepout *keepout; - unsigned int nkeepout; - enum nvmem_type type; diff --git a/target/linux/generic/backport-6.1/816-v6.7-0003-nvmem-Use-device_get_match_data.patch b/target/linux/generic/backport-6.1/816-v6.7-0003-nvmem-Use-device_get_match_data.patch deleted file mode 100644 index 84c0293982459f..00000000000000 --- a/target/linux/generic/backport-6.1/816-v6.7-0003-nvmem-Use-device_get_match_data.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0720219f4d34a88a9badb4de70cfad7585687d48 Mon Sep 17 00:00:00 2001 -From: Rob Herring -Date: Fri, 20 Oct 2023 11:55:45 +0100 -Subject: [PATCH] nvmem: Use device_get_match_data() - -Use preferred device_get_match_data() instead of of_match_device() to -get the driver match data. With this, adjust the includes to explicitly -include the correct headers. - -Signed-off-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231020105545.216052-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/mxs-ocotp.c | 10 ++++------ - drivers/nvmem/stm32-romem.c | 7 ++++--- - 2 files changed, 8 insertions(+), 9 deletions(-) - ---- a/drivers/nvmem/mxs-ocotp.c -+++ b/drivers/nvmem/mxs-ocotp.c -@@ -13,8 +13,9 @@ - #include - #include - #include --#include -+#include - #include -+#include - #include - #include - -@@ -140,11 +141,10 @@ static int mxs_ocotp_probe(struct platfo - struct device *dev = &pdev->dev; - const struct mxs_data *data; - struct mxs_ocotp *otp; -- const struct of_device_id *match; - int ret; - -- match = of_match_device(dev->driver->of_match_table, dev); -- if (!match || !match->data) -+ data = device_get_match_data(dev); -+ if (!data) - return -EINVAL; - - otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL); -@@ -169,8 +169,6 @@ static int mxs_ocotp_probe(struct platfo - if (ret) - return ret; - -- data = match->data; -- - ocotp_config.size = data->size; - ocotp_config.priv = otp; - ocotp_config.dev = dev; ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -10,7 +10,9 @@ - #include - #include - #include --#include -+#include -+#include -+#include - #include - - #include "stm32-bsec-optee-ta.h" -@@ -211,8 +213,7 @@ static int stm32_romem_probe(struct plat - - priv->lower = 0; - -- cfg = (const struct stm32_romem_cfg *) -- of_match_device(dev->driver->of_match_table, dev)->data; -+ cfg = device_get_match_data(dev); - if (!cfg) { - priv->cfg.read_only = true; - priv->cfg.size = resource_size(res); diff --git a/target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch b/target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch deleted file mode 100644 index 1ed7c4333220bd..00000000000000 --- a/target/linux/generic/backport-6.1/816-v6.7-0004-Revert-nvmem-add-new-config-option.patch +++ /dev/null @@ -1,77 +0,0 @@ -From f4cf4e5db331a5ce69e3f0b21d322cac0f4e4b5d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 23 Oct 2023 12:27:59 +0200 -Subject: [PATCH] Revert "nvmem: add new config option" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit 517f14d9cf3533d5ab4fded195ab6f80a92e378f. - -Config option "no_of_node" is no longer needed since adding a more -explicit and targeted option "add_legacy_fixed_of_cells". - -That "no_of_node" config option was needed *earlier* to help mtd's case. - -DT nodes of MTD partitions (that are also NVMEM devices) may contain -subnodes. Those SHOULD NOT be treated as NVMEM fixed cells. - -To prevent NVMEM core code from parsing subnodes a "no_of_node" option -was added (and set to true in mtd) to make for_each_child_of_node() in -NVMEM a no-op. That was a bit hacky because it was messing with -"of_node" pointer to achieve some side-effect. - -With the introduction of "add_legacy_fixed_of_cells" config option -things got more explicit. MTD subsystem simply tells NVMEM when to look -for fixed cells and there is no need to hack "of_node" pointer anymore. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231023102759.31529-1-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/mtd/mtdcore.c | 1 - - drivers/nvmem/core.c | 2 +- - include/linux/nvmem-provider.h | 2 -- - 3 files changed, 1 insertion(+), 4 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -531,7 +531,6 @@ static int mtd_nvmem_add(struct mtd_info - config.read_only = true; - config.root_only = true; - config.ignore_wp = true; -- config.no_of_node = !of_device_is_compatible(node, "nvmem-cells"); - config.priv = mtd; - - mtd->nvmem = nvmem_register(&config); ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -935,7 +935,7 @@ struct nvmem_device *nvmem_register(cons - nvmem->nkeepout = config->nkeepout; - if (config->of_node) - nvmem->dev.of_node = config->of_node; -- else if (!config->no_of_node) -+ else - nvmem->dev.of_node = config->dev->of_node; - - switch (config->id) { ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -89,7 +89,6 @@ struct nvmem_cell_info { - * @read_only: Device is read-only. - * @root_only: Device is accessibly to root only. - * @of_node: If given, this will be used instead of the parent's of_node. -- * @no_of_node: Device should not use the parent's of_node even if it's !NULL. - * @reg_read: Callback to read data. - * @reg_write: Callback to write data. - * @size: Device size. -@@ -122,7 +121,6 @@ struct nvmem_config { - bool ignore_wp; - struct nvmem_layout *layout; - struct device_node *of_node; -- bool no_of_node; - nvmem_reg_read_t reg_read; - nvmem_reg_write_t reg_write; - int size; diff --git a/target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch b/target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch deleted file mode 100644 index 65b8878310e668..00000000000000 --- a/target/linux/generic/backport-6.1/816-v6.7-0005-nvmem-Do-not-expect-fixed-layouts-to-grab-a-layout-d.patch +++ /dev/null @@ -1,45 +0,0 @@ -From b7c1e53751cb3990153084f31c41f25fde3b629c Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 24 Nov 2023 20:38:14 +0100 -Subject: [PATCH] nvmem: Do not expect fixed layouts to grab a layout driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Two series lived in parallel for some time, which led to this situation: -- The nvmem-layout container is used for dynamic layouts -- We now expect fixed layouts to also use the nvmem-layout container but -this does not require any additional driver, the support is built-in the -nvmem core. - -Ensure we don't refuse to probe for wrong reasons. - -Fixes: 27f699e578b1 ("nvmem: core: add support for fixed cells *layout*") -Cc: stable@vger.kernel.org -Reported-by: Luca Ceresoli -Signed-off-by: Miquel Raynal -Tested-by: Rafał Miłecki -Tested-by: Luca Ceresoli -Reviewed-by: Luca Ceresoli - -Link: https://lore.kernel.org/r/20231124193814.360552-1-miquel.raynal@bootlin.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -796,6 +796,12 @@ static struct nvmem_layout *nvmem_layout - if (!layout_np) - return NULL; - -+ /* Fixed layouts don't have a matching driver */ -+ if (of_device_is_compatible(layout_np, "fixed-layout")) { -+ of_node_put(layout_np); -+ return NULL; -+ } -+ - /* - * In case the nvmem device was built-in while the layout was built as a - * module, we shall manually request the layout driver loading otherwise diff --git a/target/linux/generic/backport-6.1/816-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch b/target/linux/generic/backport-6.1/816-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch deleted file mode 100644 index d49a20599dc2b0..00000000000000 --- a/target/linux/generic/backport-6.1/816-v6.7-0006-nvmem-brcm_nvram-store-a-copy-of-NVRAM-content.patch +++ /dev/null @@ -1,261 +0,0 @@ -From 1e37bf84afacd5ba17b7a13a18ca2bc78aff05c0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 15 Dec 2023 11:13:58 +0000 -Subject: [PATCH] nvmem: brcm_nvram: store a copy of NVRAM content -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This driver uses MMIO access for reading NVRAM from a flash device. -Underneath there is a flash controller that reads data and provides -mapping window. - -Using MMIO interface affects controller configuration and may break real -controller driver. It was reported by multiple users of devices with -NVRAM stored on NAND. - -Modify driver to read & cache NVRAM content during init and use that -copy to provide NVMEM data when requested. On NAND flashes due to their -alignment NVRAM partitions can be quite big (1 MiB and more) while -actual NVRAM content stays quite small (usually 16 to 32 KiB). To avoid -allocating so much memory check for actual data length. - -Link: https://lore.kernel.org/linux-mtd/CACna6rwf3_9QVjYcM+847biTX=K0EoWXuXcSMkJO1Vy_5vmVqA@mail.gmail.com/ -Fixes: 3fef9ed0627a ("nvmem: brcm_nvram: new driver exposing Broadcom's NVRAM") -Cc: -Cc: Arınç ÜNAL -Cc: Florian Fainelli -Cc: Scott Branden -Signed-off-by: Rafał Miłecki -Acked-by: Arınç ÜNAL -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111358.316727-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/brcm_nvram.c | 134 ++++++++++++++++++++++++++----------- - 1 file changed, 94 insertions(+), 40 deletions(-) - ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -17,9 +17,23 @@ - - #define NVRAM_MAGIC "FLSH" - -+/** -+ * struct brcm_nvram - driver state internal struct -+ * -+ * @dev: NVMEM device pointer -+ * @nvmem_size: Size of the whole space available for NVRAM -+ * @data: NVRAM data copy stored to avoid poking underlaying flash controller -+ * @data_len: NVRAM data size -+ * @padding_byte: Padding value used to fill remaining space -+ * @cells: Array of discovered NVMEM cells -+ * @ncells: Number of elements in cells -+ */ - struct brcm_nvram { - struct device *dev; -- void __iomem *base; -+ size_t nvmem_size; -+ uint8_t *data; -+ size_t data_len; -+ uint8_t padding_byte; - struct nvmem_cell_info *cells; - int ncells; - }; -@@ -36,10 +50,47 @@ static int brcm_nvram_read(void *context - size_t bytes) - { - struct brcm_nvram *priv = context; -- u8 *dst = val; -+ size_t to_copy; -+ -+ if (offset + bytes > priv->data_len) -+ to_copy = max_t(ssize_t, (ssize_t)priv->data_len - offset, 0); -+ else -+ to_copy = bytes; -+ -+ memcpy(val, priv->data + offset, to_copy); -+ -+ memset((uint8_t *)val + to_copy, priv->padding_byte, bytes - to_copy); -+ -+ return 0; -+} -+ -+static int brcm_nvram_copy_data(struct brcm_nvram *priv, struct platform_device *pdev) -+{ -+ struct resource *res; -+ void __iomem *base; -+ -+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ priv->nvmem_size = resource_size(res); -+ -+ priv->padding_byte = readb(base + priv->nvmem_size - 1); -+ for (priv->data_len = priv->nvmem_size; -+ priv->data_len; -+ priv->data_len--) { -+ if (readb(base + priv->data_len - 1) != priv->padding_byte) -+ break; -+ } -+ WARN(priv->data_len > SZ_128K, "Unexpected (big) NVRAM size: %zu B\n", priv->data_len); - -- while (bytes--) -- *dst++ = readb(priv->base + offset++); -+ priv->data = devm_kzalloc(priv->dev, priv->data_len, GFP_KERNEL); -+ if (!priv->data) -+ return -ENOMEM; -+ -+ memcpy_fromio(priv->data, base, priv->data_len); -+ -+ bcm47xx_nvram_init_from_iomem(base, priv->data_len); - - return 0; - } -@@ -67,8 +118,13 @@ static int brcm_nvram_add_cells(struct b - size_t len) - { - struct device *dev = priv->dev; -- char *var, *value, *eq; -+ char *var, *value; -+ uint8_t tmp; - int idx; -+ int err = 0; -+ -+ tmp = priv->data[len - 1]; -+ priv->data[len - 1] = '\0'; - - priv->ncells = 0; - for (var = data + sizeof(struct brcm_nvram_header); -@@ -78,67 +134,68 @@ static int brcm_nvram_add_cells(struct b - } - - priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL); -- if (!priv->cells) -- return -ENOMEM; -+ if (!priv->cells) { -+ err = -ENOMEM; -+ goto out; -+ } - - for (var = data + sizeof(struct brcm_nvram_header), idx = 0; - var < (char *)data + len && *var; - var = value + strlen(value) + 1, idx++) { -+ char *eq, *name; -+ - eq = strchr(var, '='); - if (!eq) - break; - *eq = '\0'; -+ name = devm_kstrdup(dev, var, GFP_KERNEL); -+ *eq = '='; -+ if (!name) { -+ err = -ENOMEM; -+ goto out; -+ } - value = eq + 1; - -- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL); -- if (!priv->cells[idx].name) -- return -ENOMEM; -+ priv->cells[idx].name = name; - priv->cells[idx].offset = value - (char *)data; - priv->cells[idx].bytes = strlen(value); - priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); -- if (!strcmp(var, "et0macaddr") || -- !strcmp(var, "et1macaddr") || -- !strcmp(var, "et2macaddr")) { -+ if (!strcmp(name, "et0macaddr") || -+ !strcmp(name, "et1macaddr") || -+ !strcmp(name, "et2macaddr")) { - priv->cells[idx].raw_len = strlen(value); - priv->cells[idx].bytes = ETH_ALEN; - priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr; - } - } - -- return 0; -+out: -+ priv->data[len - 1] = tmp; -+ return err; - } - - static int brcm_nvram_parse(struct brcm_nvram *priv) - { -+ struct brcm_nvram_header *header = (struct brcm_nvram_header *)priv->data; - struct device *dev = priv->dev; -- struct brcm_nvram_header header; -- uint8_t *data; - size_t len; - int err; - -- memcpy_fromio(&header, priv->base, sizeof(header)); -- -- if (memcmp(header.magic, NVRAM_MAGIC, 4)) { -+ if (memcmp(header->magic, NVRAM_MAGIC, 4)) { - dev_err(dev, "Invalid NVRAM magic\n"); - return -EINVAL; - } - -- len = le32_to_cpu(header.len); -- -- data = kzalloc(len, GFP_KERNEL); -- if (!data) -- return -ENOMEM; -- -- memcpy_fromio(data, priv->base, len); -- data[len - 1] = '\0'; -- -- err = brcm_nvram_add_cells(priv, data, len); -- if (err) { -- dev_err(dev, "Failed to add cells: %d\n", err); -- return err; -+ len = le32_to_cpu(header->len); -+ if (len > priv->nvmem_size) { -+ dev_err(dev, "NVRAM length (%zd) exceeds mapped size (%zd)\n", len, -+ priv->nvmem_size); -+ return -EINVAL; - } - -- kfree(data); -+ err = brcm_nvram_add_cells(priv, priv->data, len); -+ if (err) -+ dev_err(dev, "Failed to add cells: %d\n", err); - - return 0; - } -@@ -150,7 +207,6 @@ static int brcm_nvram_probe(struct platf - .reg_read = brcm_nvram_read, - }; - struct device *dev = &pdev->dev; -- struct resource *res; - struct brcm_nvram *priv; - int err; - -@@ -159,21 +215,19 @@ static int brcm_nvram_probe(struct platf - return -ENOMEM; - priv->dev = dev; - -- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); -- if (IS_ERR(priv->base)) -- return PTR_ERR(priv->base); -+ err = brcm_nvram_copy_data(priv, pdev); -+ if (err) -+ return err; - - err = brcm_nvram_parse(priv); - if (err) - return err; - -- bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res)); -- - config.dev = dev; - config.cells = priv->cells; - config.ncells = priv->ncells; - config.priv = priv; -- config.size = resource_size(res); -+ config.size = priv->nvmem_size; - - return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config)); - } diff --git a/target/linux/generic/backport-6.1/817-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch b/target/linux/generic/backport-6.1/817-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch deleted file mode 100644 index bf36e19fcc7c37..00000000000000 --- a/target/linux/generic/backport-6.1/817-v6.9-0001-dt-bindings-leds-Add-FUNCTION-defines-for-per-band-W.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ec18a2a83b8b9f7e39c80105ea148c769c46227b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Wed, 17 Jan 2024 16:17:36 +0100 -Subject: [PATCH] dt-bindings: leds: Add FUNCTION defines for per-band WLANs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Most wireless routers and access points can operate in multiple bands -simultaneously. Vendors often equip their devices with per-band LEDs. - -Add defines for those very common functions to allow cleaner & clearer -bindings. - -Signed-off-by: Rafał Miłecki -Acked-by: Rob Herring -Link: https://lore.kernel.org/r/20240117151736.27440-1-zajec5@gmail.com -Signed-off-by: Lee Jones ---- - include/dt-bindings/leds/common.h | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/include/dt-bindings/leds/common.h -+++ b/include/dt-bindings/leds/common.h -@@ -101,6 +101,9 @@ - #define LED_FUNCTION_USB "usb" - #define LED_FUNCTION_WAN "wan" - #define LED_FUNCTION_WLAN "wlan" -+#define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz" -+#define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz" -+#define LED_FUNCTION_WLAN_6GHZ "wlan-6ghz" - #define LED_FUNCTION_WPS "wps" - - #endif /* __DT_BINDINGS_LEDS_H */ diff --git a/target/linux/generic/backport-6.1/817-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch b/target/linux/generic/backport-6.1/817-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch deleted file mode 100644 index eabb9bbe9ad54c..00000000000000 --- a/target/linux/generic/backport-6.1/817-v6.9-0002-dt-bindings-leds-Add-LED_FUNCTION_WAN_ONLINE-for-Int.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 64e558500d2d04878b8a6d6578850c475171d6ba Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Fri, 23 Feb 2024 12:22:23 +0100 -Subject: [PATCH] dt-bindings: leds: Add LED_FUNCTION_WAN_ONLINE for Internet - access -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It's common for routers to have LED indicating link on the WAN port. - -Some devices however have an extra LED that's meant to be used if WAN -connection is actually "online" (there is Internet access available). - -It was suggested to add #define for such use case. - -Link: https://lore.kernel.org/linux-devicetree/80e92209-5578-44e7-bd4b-603a29053ddf@collabora.com/T/#u -Signed-off-by: Rafał Miłecki -Reviewed-by: AngeloGioacchino Del Regno -Link: https://lore.kernel.org/r/20240223112223.1368-1-zajec5@gmail.com -Signed-off-by: Lee Jones ---- - include/dt-bindings/leds/common.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/dt-bindings/leds/common.h -+++ b/include/dt-bindings/leds/common.h -@@ -100,6 +100,7 @@ - #define LED_FUNCTION_TX "tx" - #define LED_FUNCTION_USB "usb" - #define LED_FUNCTION_WAN "wan" -+#define LED_FUNCTION_WAN_ONLINE "wan-online" - #define LED_FUNCTION_WLAN "wlan" - #define LED_FUNCTION_WLAN_2GHZ "wlan-2ghz" - #define LED_FUNCTION_WLAN_5GHZ "wlan-5ghz" diff --git a/target/linux/generic/backport-6.1/818-v6.8-of-device-Export-of_device_make_bus_id.patch b/target/linux/generic/backport-6.1/818-v6.8-of-device-Export-of_device_make_bus_id.patch deleted file mode 100644 index 564fe9822d8cec..00000000000000 --- a/target/linux/generic/backport-6.1/818-v6.8-of-device-Export-of_device_make_bus_id.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 7f38b70042fcaa49219045bd1a9a2836e27a58ac Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:27 +0000 -Subject: [PATCH] of: device: Export of_device_make_bus_id() - -This helper is really handy to create unique device names based on their -device tree path, we may need it outside of the OF core (in the NVMEM -subsystem) so let's export it. As this helper has nothing patform -specific, let's move it to of/device.c instead of of/platform.c so we -can add its prototype to of_device.h. - -Signed-off-by: Miquel Raynal -Acked-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/device.c | 41 +++++++++++++++++++++++++++++++++++++++ - drivers/of/platform.c | 40 -------------------------------------- - include/linux/of_device.h | 6 ++++++ - 3 files changed, 47 insertions(+), 40 deletions(-) - ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -395,3 +395,44 @@ int of_device_uevent_modalias(struct dev - return 0; - } - EXPORT_SYMBOL_GPL(of_device_uevent_modalias); -+ -+/** -+ * of_device_make_bus_id - Use the device node data to assign a unique name -+ * @dev: pointer to device structure that is linked to a device tree node -+ * -+ * This routine will first try using the translated bus address to -+ * derive a unique name. If it cannot, then it will prepend names from -+ * parent nodes until a unique name can be derived. -+ */ -+void of_device_make_bus_id(struct device *dev) -+{ -+ struct device_node *node = dev->of_node; -+ const __be32 *reg; -+ u64 addr; -+ u32 mask; -+ -+ /* Construct the name, using parent nodes if necessary to ensure uniqueness */ -+ while (node->parent) { -+ /* -+ * If the address can be translated, then that is as much -+ * uniqueness as we need. Make it the first component and return -+ */ -+ reg = of_get_property(node, "reg", NULL); -+ if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) { -+ if (!of_property_read_u32(node, "mask", &mask)) -+ dev_set_name(dev, dev_name(dev) ? "%llx.%x.%pOFn:%s" : "%llx.%x.%pOFn", -+ addr, ffs(mask) - 1, node, dev_name(dev)); -+ -+ else -+ dev_set_name(dev, dev_name(dev) ? "%llx.%pOFn:%s" : "%llx.%pOFn", -+ addr, node, dev_name(dev)); -+ return; -+ } -+ -+ /* format arguments only used if dev_name() resolves to NULL */ -+ dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s", -+ kbasename(node->full_name), dev_name(dev)); -+ node = node->parent; -+ } -+} -+EXPORT_SYMBOL_GPL(of_device_make_bus_id); ---- a/drivers/of/platform.c -+++ b/drivers/of/platform.c -@@ -64,46 +64,6 @@ EXPORT_SYMBOL(of_find_device_by_node); - */ - - /** -- * of_device_make_bus_id - Use the device node data to assign a unique name -- * @dev: pointer to device structure that is linked to a device tree node -- * -- * This routine will first try using the translated bus address to -- * derive a unique name. If it cannot, then it will prepend names from -- * parent nodes until a unique name can be derived. -- */ --static void of_device_make_bus_id(struct device *dev) --{ -- struct device_node *node = dev->of_node; -- const __be32 *reg; -- u64 addr; -- u32 mask; -- -- /* Construct the name, using parent nodes if necessary to ensure uniqueness */ -- while (node->parent) { -- /* -- * If the address can be translated, then that is as much -- * uniqueness as we need. Make it the first component and return -- */ -- reg = of_get_property(node, "reg", NULL); -- if (reg && (addr = of_translate_address(node, reg)) != OF_BAD_ADDR) { -- if (!of_property_read_u32(node, "mask", &mask)) -- dev_set_name(dev, dev_name(dev) ? "%llx.%x.%pOFn:%s" : "%llx.%x.%pOFn", -- addr, ffs(mask) - 1, node, dev_name(dev)); -- -- else -- dev_set_name(dev, dev_name(dev) ? "%llx.%pOFn:%s" : "%llx.%pOFn", -- addr, node, dev_name(dev)); -- return; -- } -- -- /* format arguments only used if dev_name() resolves to NULL */ -- dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s", -- kbasename(node->full_name), dev_name(dev)); -- node = node->parent; -- } --} -- --/** - * of_device_alloc - Allocate and initialize an of_device - * @np: device node to assign to device - * @bus_id: Name to assign to the device. May be null to use default name. ---- a/include/linux/of_device.h -+++ b/include/linux/of_device.h -@@ -56,6 +56,9 @@ static inline int of_dma_configure(struc - { - return of_dma_configure_id(dev, np, force_dma, NULL); - } -+ -+void of_device_make_bus_id(struct device *dev); -+ - #else /* CONFIG_OF */ - - static inline int of_driver_match_device(struct device *dev, -@@ -113,6 +116,9 @@ static inline int of_dma_configure(struc - { - return 0; - } -+ -+static inline void of_device_make_bus_id(struct device *dev) {} -+ - #endif /* CONFIG_OF */ - - #endif /* _LINUX_OF_DEVICE_H */ diff --git a/target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch b/target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch deleted file mode 100644 index 59175c8051d571..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0001-nvmem-Move-of_nvmem_layout_get_container-in-another-.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 4a1a40233b4a9fc159a5c7a27dc34c5c7bc5be55 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:28 +0000 -Subject: [PATCH] nvmem: Move of_nvmem_layout_get_container() in another header - -nvmem-consumer.h is included by consumer devices, extracting data from -NVMEM devices whereas nvmem-provider.h is included by devices providing -NVMEM content. - -The only users of of_nvmem_layout_get_container() outside of the core -are layout drivers, so better move its prototype to nvmem-provider.h. - -While we do so, we also move the kdoc associated with the function to -the header rather than the .c file. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 8 -------- - include/linux/nvmem-consumer.h | 7 ------- - include/linux/nvmem-provider.h | 21 +++++++++++++++++++++ - 3 files changed, 21 insertions(+), 15 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -847,14 +847,6 @@ static int nvmem_add_cells_from_layout(s - } - - #if IS_ENABLED(CONFIG_OF) --/** -- * of_nvmem_layout_get_container() - Get OF node to layout container. -- * -- * @nvmem: nvmem device. -- * -- * Return: a node pointer with refcount incremented or NULL if no -- * container exists. Use of_node_put() on it when done. -- */ - struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) - { - return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -241,7 +241,6 @@ struct nvmem_cell *of_nvmem_cell_get(str - const char *id); - struct nvmem_device *of_nvmem_device_get(struct device_node *np, - const char *name); --struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem); - #else - static inline struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, - const char *id) -@@ -254,12 +253,6 @@ static inline struct nvmem_device *of_nv - { - return ERR_PTR(-EOPNOTSUPP); - } -- --static inline struct device_node * --of_nvmem_layout_get_container(struct nvmem_device *nvmem) --{ -- return NULL; --} - #endif /* CONFIG_NVMEM && CONFIG_OF */ - - #endif /* ifndef _LINUX_NVMEM_CONSUMER_H */ ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -244,6 +244,27 @@ nvmem_layout_get_match_data(struct nvmem - - #endif /* CONFIG_NVMEM */ - -+#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF) -+ -+/** -+ * of_nvmem_layout_get_container() - Get OF node of layout container -+ * -+ * @nvmem: nvmem device -+ * -+ * Return: a node pointer with refcount incremented or NULL if no -+ * container exists. Use of_node_put() on it when done. -+ */ -+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem); -+ -+#else /* CONFIG_NVMEM && CONFIG_OF */ -+ -+static inline struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) -+{ -+ return NULL; -+} -+ -+#endif /* CONFIG_NVMEM && CONFIG_OF */ -+ - #define module_nvmem_layout_driver(__layout_driver) \ - module_driver(__layout_driver, nvmem_layout_register, \ - nvmem_layout_unregister) diff --git a/target/linux/generic/backport-6.1/819-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch b/target/linux/generic/backport-6.1/819-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch deleted file mode 100644 index e722109f919552..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0002-nvmem-Create-a-header-for-internal-sharing.patch +++ /dev/null @@ -1,91 +0,0 @@ -From ec9c08a1cb8dc5e8e003f95f5f62de41dde235bb Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:29 +0000 -Subject: [PATCH] nvmem: Create a header for internal sharing - -Before adding all the NVMEM layout bus infrastructure to the core, let's -move the main nvmem_device structure in an internal header, only -available to the core. This way all the additional code can be added in -a dedicated file in order to keep the current core file tidy. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 24 +----------------------- - drivers/nvmem/internals.h | 35 +++++++++++++++++++++++++++++++++++ - 2 files changed, 36 insertions(+), 23 deletions(-) - create mode 100644 drivers/nvmem/internals.h - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -20,29 +20,7 @@ - #include - #include - --struct nvmem_device { -- struct module *owner; -- struct device dev; -- int stride; -- int word_size; -- int id; -- struct kref refcnt; -- size_t size; -- bool read_only; -- bool root_only; -- int flags; -- enum nvmem_type type; -- struct bin_attribute eeprom; -- struct device *base_dev; -- struct list_head cells; -- const struct nvmem_keepout *keepout; -- unsigned int nkeepout; -- nvmem_reg_read_t reg_read; -- nvmem_reg_write_t reg_write; -- struct gpio_desc *wp_gpio; -- struct nvmem_layout *layout; -- void *priv; --}; -+#include "internals.h" - - #define to_nvmem_device(d) container_of(d, struct nvmem_device, dev) - ---- /dev/null -+++ b/drivers/nvmem/internals.h -@@ -0,0 +1,35 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+ -+#ifndef _LINUX_NVMEM_INTERNALS_H -+#define _LINUX_NVMEM_INTERNALS_H -+ -+#include -+#include -+#include -+ -+struct nvmem_device { -+ struct module *owner; -+ struct device dev; -+ struct list_head node; -+ int stride; -+ int word_size; -+ int id; -+ struct kref refcnt; -+ size_t size; -+ bool read_only; -+ bool root_only; -+ int flags; -+ enum nvmem_type type; -+ struct bin_attribute eeprom; -+ struct device *base_dev; -+ struct list_head cells; -+ const struct nvmem_keepout *keepout; -+ unsigned int nkeepout; -+ nvmem_reg_read_t reg_read; -+ nvmem_reg_write_t reg_write; -+ struct gpio_desc *wp_gpio; -+ struct nvmem_layout *layout; -+ void *priv; -+}; -+ -+#endif /* ifndef _LINUX_NVMEM_INTERNALS_H */ diff --git a/target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch b/target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch deleted file mode 100644 index 1f39dfea2f9689..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0003-nvmem-Simplify-the-add_cells-hook.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 1b7c298a4ecbc28cc6ee94005734bff55eb83d22 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:30 +0000 -Subject: [PATCH] nvmem: Simplify the ->add_cells() hook - -The layout entry is not used and will anyway be made useless by the new -layout bus infrastructure coming next, so drop it. While at it, clarify -the kdoc entry. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - drivers/nvmem/layouts/onie-tlv.c | 3 +-- - drivers/nvmem/layouts/sl28vpd.c | 3 +-- - include/linux/nvmem-provider.h | 8 +++----- - 4 files changed, 6 insertions(+), 10 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -816,7 +816,7 @@ static int nvmem_add_cells_from_layout(s - int ret; - - if (layout && layout->add_cells) { -- ret = layout->add_cells(&nvmem->dev, nvmem, layout); -+ ret = layout->add_cells(&nvmem->dev, nvmem); - if (ret) - return ret; - } ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -182,8 +182,7 @@ static bool onie_tlv_crc_is_valid(struct - return true; - } - --static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem, -- struct nvmem_layout *layout) -+static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem) - { - struct onie_tlv_hdr hdr; - size_t table_len, data_len, hdr_len; ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -80,8 +80,7 @@ static int sl28vpd_v1_check_crc(struct d - return 0; - } - --static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem, -- struct nvmem_layout *layout) -+static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem) - { - const struct nvmem_cell_info *pinfo; - struct nvmem_cell_info info = {0}; ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -156,9 +156,8 @@ struct nvmem_cell_table { - * - * @name: Layout name. - * @of_match_table: Open firmware match table. -- * @add_cells: Will be called if a nvmem device is found which -- * has this layout. The function will add layout -- * specific cells with nvmem_add_one_cell(). -+ * @add_cells: Called to populate the layout using -+ * nvmem_add_one_cell(). - * @fixup_cell_info: Will be called before a cell is added. Can be - * used to modify the nvmem_cell_info. - * @owner: Pointer to struct module. -@@ -172,8 +171,7 @@ struct nvmem_cell_table { - struct nvmem_layout { - const char *name; - const struct of_device_id *of_match_table; -- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem, -- struct nvmem_layout *layout); -+ int (*add_cells)(struct device *dev, struct nvmem_device *nvmem); - void (*fixup_cell_info)(struct nvmem_device *nvmem, - struct nvmem_layout *layout, - struct nvmem_cell_info *cell); diff --git a/target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch b/target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch deleted file mode 100644 index c2968f2c6750d8..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0004-nvmem-Move-and-rename-fixup_cell_info.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 1172460e716784ac7e1049a537bdca8edbf97360 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:31 +0000 -Subject: [PATCH] nvmem: Move and rename ->fixup_cell_info() - -This hook is meant to be used by any provider and instantiating a layout -just for this is useless. Let's instead move this hook to the nvmem -device and add it to the config structure to be easily shared by the -providers. - -While at moving this hook, rename it ->fixup_dt_cell_info() to clarify -its main intended purpose. - -Signed-off-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 6 +++--- - drivers/nvmem/imx-ocotp.c | 11 +++-------- - drivers/nvmem/internals.h | 2 ++ - drivers/nvmem/mtk-efuse.c | 11 +++-------- - include/linux/nvmem-provider.h | 9 ++++----- - 5 files changed, 15 insertions(+), 24 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -675,7 +675,6 @@ static int nvmem_validate_keepouts(struc - - static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) - { -- struct nvmem_layout *layout = nvmem->layout; - struct device *dev = &nvmem->dev; - struct device_node *child; - const __be32 *addr; -@@ -705,8 +704,8 @@ static int nvmem_add_cells_from_dt(struc - - info.np = of_node_get(child); - -- if (layout && layout->fixup_cell_info) -- layout->fixup_cell_info(nvmem, layout, &info); -+ if (nvmem->fixup_dt_cell_info) -+ nvmem->fixup_dt_cell_info(nvmem, &info); - - ret = nvmem_add_one_cell(nvmem, &info); - kfree(info.name); -@@ -895,6 +894,7 @@ struct nvmem_device *nvmem_register(cons - - kref_init(&nvmem->refcnt); - INIT_LIST_HEAD(&nvmem->cells); -+ nvmem->fixup_dt_cell_info = config->fixup_dt_cell_info; - - nvmem->owner = config->owner; - if (!nvmem->owner && config->dev->driver) ---- a/drivers/nvmem/imx-ocotp.c -+++ b/drivers/nvmem/imx-ocotp.c -@@ -584,17 +584,12 @@ static const struct of_device_id imx_oco - }; - MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids); - --static void imx_ocotp_fixup_cell_info(struct nvmem_device *nvmem, -- struct nvmem_layout *layout, -- struct nvmem_cell_info *cell) -+static void imx_ocotp_fixup_dt_cell_info(struct nvmem_device *nvmem, -+ struct nvmem_cell_info *cell) - { - cell->read_post_process = imx_ocotp_cell_pp; - } - --static struct nvmem_layout imx_ocotp_layout = { -- .fixup_cell_info = imx_ocotp_fixup_cell_info, --}; -- - static int imx_ocotp_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -620,7 +615,7 @@ static int imx_ocotp_probe(struct platfo - imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; - imx_ocotp_nvmem_config.dev = dev; - imx_ocotp_nvmem_config.priv = priv; -- imx_ocotp_nvmem_config.layout = &imx_ocotp_layout; -+ imx_ocotp_nvmem_config.fixup_dt_cell_info = &imx_ocotp_fixup_dt_cell_info; - - priv->config = &imx_ocotp_nvmem_config; - ---- a/drivers/nvmem/internals.h -+++ b/drivers/nvmem/internals.h -@@ -23,6 +23,8 @@ struct nvmem_device { - struct bin_attribute eeprom; - struct device *base_dev; - struct list_head cells; -+ void (*fixup_dt_cell_info)(struct nvmem_device *nvmem, -+ struct nvmem_cell_info *cell); - const struct nvmem_keepout *keepout; - unsigned int nkeepout; - nvmem_reg_read_t reg_read; ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -45,9 +45,8 @@ static int mtk_efuse_gpu_speedbin_pp(voi - return 0; - } - --static void mtk_efuse_fixup_cell_info(struct nvmem_device *nvmem, -- struct nvmem_layout *layout, -- struct nvmem_cell_info *cell) -+static void mtk_efuse_fixup_dt_cell_info(struct nvmem_device *nvmem, -+ struct nvmem_cell_info *cell) - { - size_t sz = strlen(cell->name); - -@@ -61,10 +60,6 @@ static void mtk_efuse_fixup_cell_info(st - cell->read_post_process = mtk_efuse_gpu_speedbin_pp; - } - --static struct nvmem_layout mtk_efuse_layout = { -- .fixup_cell_info = mtk_efuse_fixup_cell_info, --}; -- - static int mtk_efuse_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -@@ -91,7 +86,7 @@ static int mtk_efuse_probe(struct platfo - econfig.priv = priv; - econfig.dev = dev; - if (pdata->uses_post_processing) -- econfig.layout = &mtk_efuse_layout; -+ econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info; - nvmem = devm_nvmem_register(dev, &econfig); - - return PTR_ERR_OR_ZERO(nvmem); ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -83,6 +83,8 @@ struct nvmem_cell_info { - * @cells: Optional array of pre-defined NVMEM cells. - * @ncells: Number of elements in cells. - * @add_legacy_fixed_of_cells: Read fixed NVMEM cells from old OF syntax. -+ * @fixup_dt_cell_info: Will be called before a cell is added. Can be -+ * used to modify the nvmem_cell_info. - * @keepout: Optional array of keepout ranges (sorted ascending by start). - * @nkeepout: Number of elements in the keepout array. - * @type: Type of the nvmem storage -@@ -113,6 +115,8 @@ struct nvmem_config { - const struct nvmem_cell_info *cells; - int ncells; - bool add_legacy_fixed_of_cells; -+ void (*fixup_dt_cell_info)(struct nvmem_device *nvmem, -+ struct nvmem_cell_info *cell); - const struct nvmem_keepout *keepout; - unsigned int nkeepout; - enum nvmem_type type; -@@ -158,8 +162,6 @@ struct nvmem_cell_table { - * @of_match_table: Open firmware match table. - * @add_cells: Called to populate the layout using - * nvmem_add_one_cell(). -- * @fixup_cell_info: Will be called before a cell is added. Can be -- * used to modify the nvmem_cell_info. - * @owner: Pointer to struct module. - * @node: List node. - * -@@ -172,9 +174,6 @@ struct nvmem_layout { - const char *name; - const struct of_device_id *of_match_table; - int (*add_cells)(struct device *dev, struct nvmem_device *nvmem); -- void (*fixup_cell_info)(struct nvmem_device *nvmem, -- struct nvmem_layout *layout, -- struct nvmem_cell_info *cell); - - /* private */ - struct module *owner; diff --git a/target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch b/target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch deleted file mode 100644 index 9a19dc44524e21..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0005-nvmem-core-Rework-layouts-to-become-regular-devices.patch +++ /dev/null @@ -1,763 +0,0 @@ -From fc29fd821d9ac2ae3d32a722fac39ce874efb883 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:32 +0000 -Subject: [PATCH] nvmem: core: Rework layouts to become regular devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Current layout support was initially written without modules support in -mind. When the requirement for module support rose, the existing base -was improved to adopt modularization support, but kind of a design flaw -was introduced. With the existing implementation, when a storage device -registers into NVMEM, the core tries to hook a layout (if any) and -populates its cells immediately. This means, if the hardware description -expects a layout to be hooked up, but no driver was provided for that, -the storage medium will fail to probe and try later from -scratch. Even if we consider that the hardware description shall be -correct, we could still probe the storage device (especially if it -contains the rootfs). - -One way to overcome this situation is to consider the layouts as -devices, and leverage the native notifier mechanism. When a new NVMEM -device is registered, we can populate its nvmem-layout child, if any, -and wait for the matching to be done in order to get the cells (the -waiting can be easily done with the NVMEM notifiers). If the layout -driver is compiled as a module, it should automatically be loaded. This -way, there is no strong order to enforce, any NVMEM device creation -or NVMEM layout driver insertion will be observed as a new event which -may lead to the creation of additional cells, without disturbing the -probes with costly (and sometimes endless) deferrals. - -In order to achieve that goal we create a new bus for the nvmem-layouts -with minimal logic to match nvmem-layout devices with nvmem-layout -drivers. All this infrastructure code is created in the layouts.c file. - -Signed-off-by: Miquel Raynal -Tested-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/Kconfig | 1 + - drivers/nvmem/Makefile | 2 + - drivers/nvmem/core.c | 170 ++++++++++---------------- - drivers/nvmem/internals.h | 21 ++++ - drivers/nvmem/layouts.c | 201 +++++++++++++++++++++++++++++++ - drivers/nvmem/layouts/Kconfig | 8 ++ - drivers/nvmem/layouts/onie-tlv.c | 24 +++- - drivers/nvmem/layouts/sl28vpd.c | 24 +++- - include/linux/nvmem-provider.h | 38 +++--- - 9 files changed, 354 insertions(+), 135 deletions(-) - create mode 100644 drivers/nvmem/layouts.c - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - menuconfig NVMEM - bool "NVMEM Support" -+ imply NVMEM_LAYOUTS - help - Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES... - ---- a/drivers/nvmem/Makefile -+++ b/drivers/nvmem/Makefile -@@ -5,6 +5,8 @@ - - obj-$(CONFIG_NVMEM) += nvmem_core.o - nvmem_core-y := core.o -+obj-$(CONFIG_NVMEM_LAYOUTS) += nvmem_layouts.o -+nvmem_layouts-y := layouts.o - obj-y += layouts/ - - # Devices ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -56,9 +56,6 @@ static LIST_HEAD(nvmem_lookup_list); - - static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); - --static DEFINE_SPINLOCK(nvmem_layout_lock); --static LIST_HEAD(nvmem_layouts); -- - static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, - void *val, size_t bytes) - { -@@ -740,97 +737,22 @@ static int nvmem_add_cells_from_fixed_la - return err; - } - --int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner) -+int nvmem_layout_register(struct nvmem_layout *layout) - { -- layout->owner = owner; -- -- spin_lock(&nvmem_layout_lock); -- list_add(&layout->node, &nvmem_layouts); -- spin_unlock(&nvmem_layout_lock); -- -- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_ADD, layout); -+ if (!layout->add_cells) -+ return -EINVAL; - -- return 0; -+ /* Populate the cells */ -+ return layout->add_cells(&layout->nvmem->dev, layout->nvmem); - } --EXPORT_SYMBOL_GPL(__nvmem_layout_register); -+EXPORT_SYMBOL_GPL(nvmem_layout_register); - - void nvmem_layout_unregister(struct nvmem_layout *layout) - { -- blocking_notifier_call_chain(&nvmem_notifier, NVMEM_LAYOUT_REMOVE, layout); -- -- spin_lock(&nvmem_layout_lock); -- list_del(&layout->node); -- spin_unlock(&nvmem_layout_lock); -+ /* Keep the API even with an empty stub in case we need it later */ - } - EXPORT_SYMBOL_GPL(nvmem_layout_unregister); - --static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem) --{ -- struct device_node *layout_np; -- struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER); -- -- layout_np = of_nvmem_layout_get_container(nvmem); -- if (!layout_np) -- return NULL; -- -- /* Fixed layouts don't have a matching driver */ -- if (of_device_is_compatible(layout_np, "fixed-layout")) { -- of_node_put(layout_np); -- return NULL; -- } -- -- /* -- * In case the nvmem device was built-in while the layout was built as a -- * module, we shall manually request the layout driver loading otherwise -- * we'll never have any match. -- */ -- of_request_module(layout_np); -- -- spin_lock(&nvmem_layout_lock); -- -- list_for_each_entry(l, &nvmem_layouts, node) { -- if (of_match_node(l->of_match_table, layout_np)) { -- if (try_module_get(l->owner)) -- layout = l; -- -- break; -- } -- } -- -- spin_unlock(&nvmem_layout_lock); -- of_node_put(layout_np); -- -- return layout; --} -- --static void nvmem_layout_put(struct nvmem_layout *layout) --{ -- if (layout) -- module_put(layout->owner); --} -- --static int nvmem_add_cells_from_layout(struct nvmem_device *nvmem) --{ -- struct nvmem_layout *layout = nvmem->layout; -- int ret; -- -- if (layout && layout->add_cells) { -- ret = layout->add_cells(&nvmem->dev, nvmem); -- if (ret) -- return ret; -- } -- -- return 0; --} -- --#if IS_ENABLED(CONFIG_OF) --struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) --{ -- return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); --} --EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container); --#endif -- - const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, - struct nvmem_layout *layout) - { -@@ -838,7 +760,7 @@ const void *nvmem_layout_get_match_data( - const struct of_device_id *match; - - layout_np = of_nvmem_layout_get_container(nvmem); -- match = of_match_node(layout->of_match_table, layout_np); -+ match = of_match_node(layout->dev.driver->of_match_table, layout_np); - - return match ? match->data : NULL; - } -@@ -950,19 +872,6 @@ struct nvmem_device *nvmem_register(cons - goto err_put_device; - } - -- /* -- * If the driver supplied a layout by config->layout, the module -- * pointer will be NULL and nvmem_layout_put() will be a noop. -- */ -- nvmem->layout = config->layout ?: nvmem_layout_get(nvmem); -- if (IS_ERR(nvmem->layout)) { -- rval = PTR_ERR(nvmem->layout); -- nvmem->layout = NULL; -- -- if (rval == -EPROBE_DEFER) -- goto err_teardown_compat; -- } -- - if (config->cells) { - rval = nvmem_add_cells(nvmem, config->cells, config->ncells); - if (rval) -@@ -983,24 +892,24 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_cells; - -- rval = nvmem_add_cells_from_layout(nvmem); -- if (rval) -- goto err_remove_cells; -- - dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name); - - rval = device_add(&nvmem->dev); - if (rval) - goto err_remove_cells; - -+ rval = nvmem_populate_layout(nvmem); -+ if (rval) -+ goto err_remove_dev; -+ - blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); - - return nvmem; - -+err_remove_dev: -+ device_del(&nvmem->dev); - err_remove_cells: - nvmem_device_remove_all_cells(nvmem); -- nvmem_layout_put(nvmem->layout); --err_teardown_compat: - if (config->compat) - nvmem_sysfs_remove_compat(nvmem, config); - err_put_device: -@@ -1022,7 +931,7 @@ static void nvmem_device_release(struct - device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); - - nvmem_device_remove_all_cells(nvmem); -- nvmem_layout_put(nvmem->layout); -+ nvmem_destroy_layout(nvmem); - device_unregister(&nvmem->dev); - } - -@@ -1324,6 +1233,12 @@ nvmem_cell_get_from_lookup(struct device - return cell; - } - -+static void nvmem_layout_module_put(struct nvmem_device *nvmem) -+{ -+ if (nvmem->layout && nvmem->layout->dev.driver) -+ module_put(nvmem->layout->dev.driver->owner); -+} -+ - #if IS_ENABLED(CONFIG_OF) - static struct nvmem_cell_entry * - nvmem_find_cell_entry_by_node(struct nvmem_device *nvmem, struct device_node *np) -@@ -1342,6 +1257,18 @@ nvmem_find_cell_entry_by_node(struct nvm - return cell; - } - -+static int nvmem_layout_module_get_optional(struct nvmem_device *nvmem) -+{ -+ if (!nvmem->layout) -+ return 0; -+ -+ if (!nvmem->layout->dev.driver || -+ !try_module_get(nvmem->layout->dev.driver->owner)) -+ return -EPROBE_DEFER; -+ -+ return 0; -+} -+ - /** - * of_nvmem_cell_get() - Get a nvmem cell from given device node and cell id - * -@@ -1404,16 +1331,29 @@ struct nvmem_cell *of_nvmem_cell_get(str - return ERR_CAST(nvmem); - } - -+ ret = nvmem_layout_module_get_optional(nvmem); -+ if (ret) { -+ of_node_put(cell_np); -+ __nvmem_device_put(nvmem); -+ return ERR_PTR(ret); -+ } -+ - cell_entry = nvmem_find_cell_entry_by_node(nvmem, cell_np); - of_node_put(cell_np); - if (!cell_entry) { - __nvmem_device_put(nvmem); -- return ERR_PTR(-ENOENT); -+ nvmem_layout_module_put(nvmem); -+ if (nvmem->layout) -+ return ERR_PTR(-EPROBE_DEFER); -+ else -+ return ERR_PTR(-ENOENT); - } - - cell = nvmem_create_cell(cell_entry, id, cell_index); -- if (IS_ERR(cell)) -+ if (IS_ERR(cell)) { - __nvmem_device_put(nvmem); -+ nvmem_layout_module_put(nvmem); -+ } - - return cell; - } -@@ -1527,6 +1467,7 @@ void nvmem_cell_put(struct nvmem_cell *c - - kfree(cell); - __nvmem_device_put(nvmem); -+ nvmem_layout_module_put(nvmem); - } - EXPORT_SYMBOL_GPL(nvmem_cell_put); - -@@ -2104,11 +2045,22 @@ EXPORT_SYMBOL_GPL(nvmem_dev_name); - - static int __init nvmem_init(void) - { -- return bus_register(&nvmem_bus_type); -+ int ret; -+ -+ ret = bus_register(&nvmem_bus_type); -+ if (ret) -+ return ret; -+ -+ ret = nvmem_layout_bus_register(); -+ if (ret) -+ bus_unregister(&nvmem_bus_type); -+ -+ return ret; - } - - static void __exit nvmem_exit(void) - { -+ nvmem_layout_bus_unregister(); - bus_unregister(&nvmem_bus_type); - } - ---- a/drivers/nvmem/internals.h -+++ b/drivers/nvmem/internals.h -@@ -34,4 +34,25 @@ struct nvmem_device { - void *priv; - }; - -+#if IS_ENABLED(CONFIG_OF) -+int nvmem_layout_bus_register(void); -+void nvmem_layout_bus_unregister(void); -+int nvmem_populate_layout(struct nvmem_device *nvmem); -+void nvmem_destroy_layout(struct nvmem_device *nvmem); -+#else /* CONFIG_OF */ -+static inline int nvmem_layout_bus_register(void) -+{ -+ return 0; -+} -+ -+static inline void nvmem_layout_bus_unregister(void) {} -+ -+static inline int nvmem_populate_layout(struct nvmem_device *nvmem) -+{ -+ return 0; -+} -+ -+static inline void nvmem_destroy_layout(struct nvmem_device *nvmem) { } -+#endif /* CONFIG_OF */ -+ - #endif /* ifndef _LINUX_NVMEM_INTERNALS_H */ ---- /dev/null -+++ b/drivers/nvmem/layouts.c -@@ -0,0 +1,201 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * NVMEM layout bus handling -+ * -+ * Copyright (C) 2023 Bootlin -+ * Author: Miquel Raynal -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "internals.h" -+ -+#define to_nvmem_layout_driver(drv) \ -+ (container_of((drv), struct nvmem_layout_driver, driver)) -+#define to_nvmem_layout_device(_dev) \ -+ container_of((_dev), struct nvmem_layout, dev) -+ -+static int nvmem_layout_bus_match(struct device *dev, struct device_driver *drv) -+{ -+ return of_driver_match_device(dev, drv); -+} -+ -+static int nvmem_layout_bus_probe(struct device *dev) -+{ -+ struct nvmem_layout_driver *drv = to_nvmem_layout_driver(dev->driver); -+ struct nvmem_layout *layout = to_nvmem_layout_device(dev); -+ -+ if (!drv->probe || !drv->remove) -+ return -EINVAL; -+ -+ return drv->probe(layout); -+} -+ -+static void nvmem_layout_bus_remove(struct device *dev) -+{ -+ struct nvmem_layout_driver *drv = to_nvmem_layout_driver(dev->driver); -+ struct nvmem_layout *layout = to_nvmem_layout_device(dev); -+ -+ return drv->remove(layout); -+} -+ -+static struct bus_type nvmem_layout_bus_type = { -+ .name = "nvmem-layout", -+ .match = nvmem_layout_bus_match, -+ .probe = nvmem_layout_bus_probe, -+ .remove = nvmem_layout_bus_remove, -+}; -+ -+int nvmem_layout_driver_register(struct nvmem_layout_driver *drv) -+{ -+ drv->driver.bus = &nvmem_layout_bus_type; -+ -+ return driver_register(&drv->driver); -+} -+EXPORT_SYMBOL_GPL(nvmem_layout_driver_register); -+ -+void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv) -+{ -+ driver_unregister(&drv->driver); -+} -+EXPORT_SYMBOL_GPL(nvmem_layout_driver_unregister); -+ -+static void nvmem_layout_release_device(struct device *dev) -+{ -+ struct nvmem_layout *layout = to_nvmem_layout_device(dev); -+ -+ of_node_put(layout->dev.of_node); -+ kfree(layout); -+} -+ -+static int nvmem_layout_create_device(struct nvmem_device *nvmem, -+ struct device_node *np) -+{ -+ struct nvmem_layout *layout; -+ struct device *dev; -+ int ret; -+ -+ layout = kzalloc(sizeof(*layout), GFP_KERNEL); -+ if (!layout) -+ return -ENOMEM; -+ -+ /* Create a bidirectional link */ -+ layout->nvmem = nvmem; -+ nvmem->layout = layout; -+ -+ /* Device model registration */ -+ dev = &layout->dev; -+ device_initialize(dev); -+ dev->parent = &nvmem->dev; -+ dev->bus = &nvmem_layout_bus_type; -+ dev->release = nvmem_layout_release_device; -+ dev->coherent_dma_mask = DMA_BIT_MASK(32); -+ dev->dma_mask = &dev->coherent_dma_mask; -+ device_set_node(dev, of_fwnode_handle(of_node_get(np))); -+ of_device_make_bus_id(dev); -+ of_msi_configure(dev, dev->of_node); -+ -+ ret = device_add(dev); -+ if (ret) { -+ put_device(dev); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id of_nvmem_layout_skip_table[] = { -+ { .compatible = "fixed-layout", }, -+ {} -+}; -+ -+static int nvmem_layout_bus_populate(struct nvmem_device *nvmem, -+ struct device_node *layout_dn) -+{ -+ int ret; -+ -+ /* Make sure it has a compatible property */ -+ if (!of_get_property(layout_dn, "compatible", NULL)) { -+ pr_debug("%s() - skipping %pOF, no compatible prop\n", -+ __func__, layout_dn); -+ return 0; -+ } -+ -+ /* Fixed layouts are parsed manually somewhere else for now */ -+ if (of_match_node(of_nvmem_layout_skip_table, layout_dn)) { -+ pr_debug("%s() - skipping %pOF node\n", __func__, layout_dn); -+ return 0; -+ } -+ -+ if (of_node_check_flag(layout_dn, OF_POPULATED_BUS)) { -+ pr_debug("%s() - skipping %pOF, already populated\n", -+ __func__, layout_dn); -+ -+ return 0; -+ } -+ -+ /* NVMEM layout buses expect only a single device representing the layout */ -+ ret = nvmem_layout_create_device(nvmem, layout_dn); -+ if (ret) -+ return ret; -+ -+ of_node_set_flag(layout_dn, OF_POPULATED_BUS); -+ -+ return 0; -+} -+ -+struct device_node *of_nvmem_layout_get_container(struct nvmem_device *nvmem) -+{ -+ return of_get_child_by_name(nvmem->dev.of_node, "nvmem-layout"); -+} -+EXPORT_SYMBOL_GPL(of_nvmem_layout_get_container); -+ -+/* -+ * Returns the number of devices populated, 0 if the operation was not relevant -+ * for this nvmem device, an error code otherwise. -+ */ -+int nvmem_populate_layout(struct nvmem_device *nvmem) -+{ -+ struct device_node *layout_dn; -+ int ret; -+ -+ layout_dn = of_nvmem_layout_get_container(nvmem); -+ if (!layout_dn) -+ return 0; -+ -+ /* Populate the layout device */ -+ device_links_supplier_sync_state_pause(); -+ ret = nvmem_layout_bus_populate(nvmem, layout_dn); -+ device_links_supplier_sync_state_resume(); -+ -+ of_node_put(layout_dn); -+ return ret; -+} -+ -+void nvmem_destroy_layout(struct nvmem_device *nvmem) -+{ -+ struct device *dev; -+ -+ if (!nvmem->layout) -+ return; -+ -+ dev = &nvmem->layout->dev; -+ of_node_clear_flag(dev->of_node, OF_POPULATED_BUS); -+ device_unregister(dev); -+} -+ -+int nvmem_layout_bus_register(void) -+{ -+ return bus_register(&nvmem_layout_bus_type); -+} -+ -+void nvmem_layout_bus_unregister(void) -+{ -+ bus_unregister(&nvmem_layout_bus_type); -+} ---- a/drivers/nvmem/layouts/Kconfig -+++ b/drivers/nvmem/layouts/Kconfig -@@ -1,5 +1,11 @@ - # SPDX-License-Identifier: GPL-2.0 - -+config NVMEM_LAYOUTS -+ bool -+ depends on OF -+ -+if NVMEM_LAYOUTS -+ - menu "Layout Types" - - config NVMEM_LAYOUT_SL28_VPD -@@ -21,3 +27,5 @@ config NVMEM_LAYOUT_ONIE_TLV - If unsure, say N. - - endmenu -+ -+endif ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -225,16 +225,32 @@ static int onie_tlv_parse_table(struct d - return 0; - } - -+static int onie_tlv_probe(struct nvmem_layout *layout) -+{ -+ layout->add_cells = onie_tlv_parse_table; -+ -+ return nvmem_layout_register(layout); -+} -+ -+static void onie_tlv_remove(struct nvmem_layout *layout) -+{ -+ nvmem_layout_unregister(layout); -+} -+ - static const struct of_device_id onie_tlv_of_match_table[] = { - { .compatible = "onie,tlv-layout", }, - {}, - }; - MODULE_DEVICE_TABLE(of, onie_tlv_of_match_table); - --static struct nvmem_layout onie_tlv_layout = { -- .name = "ONIE tlv layout", -- .of_match_table = onie_tlv_of_match_table, -- .add_cells = onie_tlv_parse_table, -+static struct nvmem_layout_driver onie_tlv_layout = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "onie-tlv-layout", -+ .of_match_table = onie_tlv_of_match_table, -+ }, -+ .probe = onie_tlv_probe, -+ .remove = onie_tlv_remove, - }; - module_nvmem_layout_driver(onie_tlv_layout); - ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -134,16 +134,32 @@ static int sl28vpd_add_cells(struct devi - return 0; - } - -+static int sl28vpd_probe(struct nvmem_layout *layout) -+{ -+ layout->add_cells = sl28vpd_add_cells; -+ -+ return nvmem_layout_register(layout); -+} -+ -+static void sl28vpd_remove(struct nvmem_layout *layout) -+{ -+ nvmem_layout_unregister(layout); -+} -+ - static const struct of_device_id sl28vpd_of_match_table[] = { - { .compatible = "kontron,sl28-vpd" }, - {}, - }; - MODULE_DEVICE_TABLE(of, sl28vpd_of_match_table); - --static struct nvmem_layout sl28vpd_layout = { -- .name = "sl28-vpd", -- .of_match_table = sl28vpd_of_match_table, -- .add_cells = sl28vpd_add_cells, -+static struct nvmem_layout_driver sl28vpd_layout = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = "kontron-sl28vpd-layout", -+ .of_match_table = sl28vpd_of_match_table, -+ }, -+ .probe = sl28vpd_probe, -+ .remove = sl28vpd_remove, - }; - module_nvmem_layout_driver(sl28vpd_layout); - ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -9,6 +9,7 @@ - #ifndef _LINUX_NVMEM_PROVIDER_H - #define _LINUX_NVMEM_PROVIDER_H - -+#include - #include - #include - #include -@@ -158,12 +159,11 @@ struct nvmem_cell_table { - /** - * struct nvmem_layout - NVMEM layout definitions - * -- * @name: Layout name. -- * @of_match_table: Open firmware match table. -- * @add_cells: Called to populate the layout using -- * nvmem_add_one_cell(). -- * @owner: Pointer to struct module. -- * @node: List node. -+ * @dev: Device-model layout device. -+ * @nvmem: The underlying NVMEM device -+ * @add_cells: Will be called if a nvmem device is found which -+ * has this layout. The function will add layout -+ * specific cells with nvmem_add_one_cell(). - * - * A nvmem device can hold a well defined structure which can just be - * evaluated during runtime. For example a TLV list, or a list of "name=val" -@@ -171,13 +171,15 @@ struct nvmem_cell_table { - * cells. - */ - struct nvmem_layout { -- const char *name; -- const struct of_device_id *of_match_table; -+ struct device dev; -+ struct nvmem_device *nvmem; - int (*add_cells)(struct device *dev, struct nvmem_device *nvmem); -+}; - -- /* private */ -- struct module *owner; -- struct list_head node; -+struct nvmem_layout_driver { -+ struct device_driver driver; -+ int (*probe)(struct nvmem_layout *layout); -+ void (*remove)(struct nvmem_layout *layout); - }; - - #if IS_ENABLED(CONFIG_NVMEM) -@@ -194,11 +196,15 @@ void nvmem_del_cell_table(struct nvmem_c - int nvmem_add_one_cell(struct nvmem_device *nvmem, - const struct nvmem_cell_info *info); - --int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner); --#define nvmem_layout_register(layout) \ -- __nvmem_layout_register(layout, THIS_MODULE) -+int nvmem_layout_register(struct nvmem_layout *layout); - void nvmem_layout_unregister(struct nvmem_layout *layout); - -+int nvmem_layout_driver_register(struct nvmem_layout_driver *drv); -+void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv); -+#define module_nvmem_layout_driver(__nvmem_layout_driver) \ -+ module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \ -+ nvmem_layout_driver_unregister) -+ - const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, - struct nvmem_layout *layout); - -@@ -262,8 +268,4 @@ static inline struct device_node *of_nvm - - #endif /* CONFIG_NVMEM && CONFIG_OF */ - --#define module_nvmem_layout_driver(__layout_driver) \ -- module_driver(__layout_driver, nvmem_layout_register, \ -- nvmem_layout_unregister) -- - #endif /* ifndef _LINUX_NVMEM_PROVIDER_H */ diff --git a/target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch b/target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch deleted file mode 100644 index 07e44d7b21cdaf..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0006-nvmem-core-Expose-cells-through-sysfs.patch +++ /dev/null @@ -1,240 +0,0 @@ -From 0331c611949fffdf486652450901a4dc52bc5cca Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Fri, 15 Dec 2023 11:15:34 +0000 -Subject: [PATCH] nvmem: core: Expose cells through sysfs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The binary content of nvmem devices is available to the user so in the -easiest cases, finding the content of a cell is rather easy as it is -just a matter of looking at a known and fixed offset. However, nvmem -layouts have been recently introduced to cope with more advanced -situations, where the offset and size of the cells is not known in -advance or is dynamic. When using layouts, more advanced parsers are -used by the kernel in order to give direct access to the content of each -cell, regardless of its position/size in the underlying -device. Unfortunately, these information are not accessible by users, -unless by fully re-implementing the parser logic in userland. - -Let's expose the cells and their content through sysfs to avoid these -situations. Of course the relevant NVMEM sysfs Kconfig option must be -enabled for this support to be available. - -Not all nvmem devices expose cells. Indeed, the .bin_attrs attribute -group member will be filled at runtime only when relevant and will -remain empty otherwise. In this case, as the cells attribute group will -be empty, it will not lead to any additional folder/file creation. - -Exposed cells are read-only. There is, in practice, everything in the -core to support a write path, but as I don't see any need for that, I -prefer to keep the interface simple (and probably safer). The interface -is documented as being in the "testing" state which means we can later -add a write attribute if though relevant. - -Signed-off-by: Miquel Raynal -Tested-by: Rafał Miłecki -Tested-by: Chen-Yu Tsai -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 135 +++++++++++++++++++++++++++++++++++++- - drivers/nvmem/internals.h | 1 + - 2 files changed, 135 insertions(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -300,6 +300,43 @@ static umode_t nvmem_bin_attr_is_visible - return nvmem_bin_attr_get_umode(nvmem); - } - -+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, -+ const char *id, int index); -+ -+static ssize_t nvmem_cell_attr_read(struct file *filp, struct kobject *kobj, -+ struct bin_attribute *attr, char *buf, -+ loff_t pos, size_t count) -+{ -+ struct nvmem_cell_entry *entry; -+ struct nvmem_cell *cell = NULL; -+ size_t cell_sz, read_len; -+ void *content; -+ -+ entry = attr->private; -+ cell = nvmem_create_cell(entry, entry->name, 0); -+ if (IS_ERR(cell)) -+ return PTR_ERR(cell); -+ -+ if (!cell) -+ return -EINVAL; -+ -+ content = nvmem_cell_read(cell, &cell_sz); -+ if (IS_ERR(content)) { -+ read_len = PTR_ERR(content); -+ goto destroy_cell; -+ } -+ -+ read_len = min_t(unsigned int, cell_sz - pos, count); -+ memcpy(buf, content + pos, read_len); -+ kfree(content); -+ -+destroy_cell: -+ kfree_const(cell->id); -+ kfree(cell); -+ -+ return read_len; -+} -+ - /* default read/write permissions */ - static struct bin_attribute bin_attr_rw_nvmem = { - .attr = { -@@ -321,11 +358,21 @@ static const struct attribute_group nvme - .is_bin_visible = nvmem_bin_attr_is_visible, - }; - -+/* Cell attributes will be dynamically allocated */ -+static struct attribute_group nvmem_cells_group = { -+ .name = "cells", -+}; -+ - static const struct attribute_group *nvmem_dev_groups[] = { - &nvmem_bin_group, - NULL, - }; - -+static const struct attribute_group *nvmem_cells_groups[] = { -+ &nvmem_cells_group, -+ NULL, -+}; -+ - static struct bin_attribute bin_attr_nvmem_eeprom_compat = { - .attr = { - .name = "eeprom", -@@ -380,6 +427,68 @@ static void nvmem_sysfs_remove_compat(st - device_remove_bin_file(nvmem->base_dev, &nvmem->eeprom); - } - -+static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem) -+{ -+ struct bin_attribute **cells_attrs, *attrs; -+ struct nvmem_cell_entry *entry; -+ unsigned int ncells = 0, i = 0; -+ int ret = 0; -+ -+ mutex_lock(&nvmem_mutex); -+ -+ if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) { -+ nvmem_cells_group.bin_attrs = NULL; -+ goto unlock_mutex; -+ } -+ -+ /* Allocate an array of attributes with a sentinel */ -+ ncells = list_count_nodes(&nvmem->cells); -+ cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1, -+ sizeof(struct bin_attribute *), GFP_KERNEL); -+ if (!cells_attrs) { -+ ret = -ENOMEM; -+ goto unlock_mutex; -+ } -+ -+ attrs = devm_kcalloc(&nvmem->dev, ncells, sizeof(struct bin_attribute), GFP_KERNEL); -+ if (!attrs) { -+ ret = -ENOMEM; -+ goto unlock_mutex; -+ } -+ -+ /* Initialize each attribute to take the name and size of the cell */ -+ list_for_each_entry(entry, &nvmem->cells, node) { -+ sysfs_bin_attr_init(&attrs[i]); -+ attrs[i].attr.name = devm_kasprintf(&nvmem->dev, GFP_KERNEL, -+ "%s@%x", entry->name, -+ entry->offset); -+ attrs[i].attr.mode = 0444; -+ attrs[i].size = entry->bytes; -+ attrs[i].read = &nvmem_cell_attr_read; -+ attrs[i].private = entry; -+ if (!attrs[i].attr.name) { -+ ret = -ENOMEM; -+ goto unlock_mutex; -+ } -+ -+ cells_attrs[i] = &attrs[i]; -+ i++; -+ } -+ -+ nvmem_cells_group.bin_attrs = cells_attrs; -+ -+ ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups); -+ if (ret) -+ goto unlock_mutex; -+ -+ nvmem->sysfs_cells_populated = true; -+ -+unlock_mutex: -+ mutex_unlock(&nvmem_mutex); -+ -+ return ret; -+} -+ - #else /* CONFIG_NVMEM_SYSFS */ - - static int nvmem_sysfs_setup_compat(struct nvmem_device *nvmem, -@@ -739,11 +848,25 @@ static int nvmem_add_cells_from_fixed_la - - int nvmem_layout_register(struct nvmem_layout *layout) - { -+ int ret; -+ - if (!layout->add_cells) - return -EINVAL; - - /* Populate the cells */ -- return layout->add_cells(&layout->nvmem->dev, layout->nvmem); -+ ret = layout->add_cells(&layout->nvmem->dev, layout->nvmem); -+ if (ret) -+ return ret; -+ -+#ifdef CONFIG_NVMEM_SYSFS -+ ret = nvmem_populate_sysfs_cells(layout->nvmem); -+ if (ret) { -+ nvmem_device_remove_all_cells(layout->nvmem); -+ return ret; -+ } -+#endif -+ -+ return 0; - } - EXPORT_SYMBOL_GPL(nvmem_layout_register); - -@@ -902,10 +1025,20 @@ struct nvmem_device *nvmem_register(cons - if (rval) - goto err_remove_dev; - -+#ifdef CONFIG_NVMEM_SYSFS -+ rval = nvmem_populate_sysfs_cells(nvmem); -+ if (rval) -+ goto err_destroy_layout; -+#endif -+ - blocking_notifier_call_chain(&nvmem_notifier, NVMEM_ADD, nvmem); - - return nvmem; - -+#ifdef CONFIG_NVMEM_SYSFS -+err_destroy_layout: -+ nvmem_destroy_layout(nvmem); -+#endif - err_remove_dev: - device_del(&nvmem->dev); - err_remove_cells: ---- a/drivers/nvmem/internals.h -+++ b/drivers/nvmem/internals.h -@@ -32,6 +32,7 @@ struct nvmem_device { - struct gpio_desc *wp_gpio; - struct nvmem_layout *layout; - void *priv; -+ bool sysfs_cells_populated; - }; - - #if IS_ENABLED(CONFIG_OF) diff --git a/target/linux/generic/backport-6.1/819-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch b/target/linux/generic/backport-6.1/819-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch deleted file mode 100644 index f686222f881075..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0007-nvmem-stm32-add-support-for-STM32MP25-BSEC-to-contro.patch +++ /dev/null @@ -1,65 +0,0 @@ -From f0ac5b23039610619ca4a4805528553ecb6bc815 Mon Sep 17 00:00:00 2001 -From: Patrick Delaunay -Date: Fri, 15 Dec 2023 11:15:36 +0000 -Subject: [PATCH] nvmem: stm32: add support for STM32MP25 BSEC to control OTP - data - -On STM32MP25, OTP area may be read/written by using BSEC (boot, security -and OTP control). The BSEC internal peripheral is only managed by the -secure world. - -The 12 Kbits of OTP (effective) are organized into the following regions: -- lower OTP (OTP0 to OTP127) = 4096 lower OTP bits, - bitwise (1-bit) programmable -- mid OTP (OTP128 to OTP255) = 4096 middle OTP bits, - bulk (32-bit) programmable -- upper OTP (OTP256 to OTP383) = 4096 upper OTP bits, - bulk (32-bit) programmable, - only accessible when BSEC is in closed state. - -As HWKEY and ECIES key are only accessible by ROM code; -only 368 OTP words are managed in this driver (OTP0 to OTP267). - -This patch adds the STM32MP25 configuration for reading and writing -the OTP data using the OP-TEE BSEC TA services. - -Signed-off-by: Patrick Delaunay -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20231215111536.316972-11-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/stm32-romem.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/drivers/nvmem/stm32-romem.c -+++ b/drivers/nvmem/stm32-romem.c -@@ -269,6 +269,19 @@ static const struct stm32_romem_cfg stm3 - .ta = true, - }; - -+/* -+ * STM32MP25 BSEC OTP: 3 regions of 32-bits data words -+ * lower OTP (OTP0 to OTP127), bitwise (1-bit) programmable -+ * mid OTP (OTP128 to OTP255), bulk (32-bit) programmable -+ * upper OTP (OTP256 to OTP383), bulk (32-bit) programmable -+ * but no access to HWKEY and ECIES key: limited at OTP367 -+ */ -+static const struct stm32_romem_cfg stm32mp25_bsec_cfg = { -+ .size = 368 * 4, -+ .lower = 127, -+ .ta = true, -+}; -+ - static const struct of_device_id stm32_romem_of_match[] __maybe_unused = { - { .compatible = "st,stm32f4-otp", }, { - .compatible = "st,stm32mp15-bsec", -@@ -276,6 +289,9 @@ static const struct of_device_id stm32_r - }, { - .compatible = "st,stm32mp13-bsec", - .data = (void *)&stm32mp13_bsec_cfg, -+ }, { -+ .compatible = "st,stm32mp25-bsec", -+ .data = (void *)&stm32mp25_bsec_cfg, - }, - { /* sentinel */ }, - }; diff --git a/target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch b/target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch deleted file mode 100644 index 400004c617cb0f..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0008-nvmem-layouts-refactor-.add_cells-callback-arguments.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 401df0d4f4098ecc9c5278da2f50756d62e5b37d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 19 Dec 2023 13:01:03 +0100 -Subject: [PATCH] nvmem: layouts: refactor .add_cells() callback arguments -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Simply pass whole "struct nvmem_layout" instead of single variables. -There is nothing in "struct nvmem_layout" that we have to hide from -layout drivers. They also access it during .probe() and .remove(). - -Thanks to this change: - -1. API gets more consistent - All layouts drivers callbacks get the same argument - -2. Layouts get correct device - Before this change NVMEM core code was passing NVMEM device instead - of layout device. That resulted in: - * Confusing prints - * Calling devm_*() helpers on wrong device - * Helpers like of_device_get_match_data() dereferencing NULLs - -3. It gets possible to get match data - First of all nvmem_layout_get_match_data() requires passing "struct - nvmem_layout" which .add_cells() callback didn't have before this. It - doesn't matter much as it's rather useless now anyway (and will be - dropped). - What's more important however is that of_device_get_match_data() can - be used now thanks to owning a proper device pointer. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Reviewed-by: Michael Walle -Link: https://lore.kernel.org/r/20231219120104.3422-1-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - drivers/nvmem/layouts/onie-tlv.c | 4 +++- - drivers/nvmem/layouts/sl28vpd.c | 4 +++- - include/linux/nvmem-provider.h | 2 +- - 4 files changed, 8 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -854,7 +854,7 @@ int nvmem_layout_register(struct nvmem_l - return -EINVAL; - - /* Populate the cells */ -- ret = layout->add_cells(&layout->nvmem->dev, layout->nvmem); -+ ret = layout->add_cells(layout); - if (ret) - return ret; - ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -182,8 +182,10 @@ static bool onie_tlv_crc_is_valid(struct - return true; - } - --static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem) -+static int onie_tlv_parse_table(struct nvmem_layout *layout) - { -+ struct nvmem_device *nvmem = layout->nvmem; -+ struct device *dev = &layout->dev; - struct onie_tlv_hdr hdr; - size_t table_len, data_len, hdr_len; - u8 *table, *data; ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -80,8 +80,10 @@ static int sl28vpd_v1_check_crc(struct d - return 0; - } - --static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem) -+static int sl28vpd_add_cells(struct nvmem_layout *layout) - { -+ struct nvmem_device *nvmem = layout->nvmem; -+ struct device *dev = &layout->dev; - const struct nvmem_cell_info *pinfo; - struct nvmem_cell_info info = {0}; - struct device_node *layout_np; ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -173,7 +173,7 @@ struct nvmem_cell_table { - struct nvmem_layout { - struct device dev; - struct nvmem_device *nvmem; -- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem); -+ int (*add_cells)(struct nvmem_layout *layout); - }; - - struct nvmem_layout_driver { diff --git a/target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch b/target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch deleted file mode 100644 index 510f3dd8417418..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0009-nvmem-drop-nvmem_layout_get_match_data.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 43f60e3fb62edc7bd8891de8779fb422f4ae23ae Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 19 Dec 2023 13:01:04 +0100 -Subject: [PATCH] nvmem: drop nvmem_layout_get_match_data() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Thanks for layouts refactoring we now have "struct device" associated -with layout. Also its OF pointer points directly to the "nvmem-layout" -DT node. - -All it takes to get match data is a generic of_device_get_match_data(). - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Reviewed-by: Michael Walle -Link: https://lore.kernel.org/r/20231219120104.3422-2-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 13 ------------- - include/linux/nvmem-provider.h | 10 ---------- - 2 files changed, 23 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -876,19 +876,6 @@ void nvmem_layout_unregister(struct nvme - } - EXPORT_SYMBOL_GPL(nvmem_layout_unregister); - --const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, -- struct nvmem_layout *layout) --{ -- struct device_node __maybe_unused *layout_np; -- const struct of_device_id *match; -- -- layout_np = of_nvmem_layout_get_container(nvmem); -- match = of_match_node(layout->dev.driver->of_match_table, layout_np); -- -- return match ? match->data : NULL; --} --EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data); -- - /** - * nvmem_register() - Register a nvmem device for given nvmem_config. - * Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -205,9 +205,6 @@ void nvmem_layout_driver_unregister(stru - module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \ - nvmem_layout_driver_unregister) - --const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem, -- struct nvmem_layout *layout); -- - #else - - static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c) -@@ -238,13 +235,6 @@ static inline int nvmem_layout_register( - - static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {} - --static inline const void * --nvmem_layout_get_match_data(struct nvmem_device *nvmem, -- struct nvmem_layout *layout) --{ -- return NULL; --} -- - #endif /* CONFIG_NVMEM */ - - #if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF) diff --git a/target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch b/target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch deleted file mode 100644 index ccdcc09736d843..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0010-nvmem-core-add-nvmem_dev_size-helper.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 33cf42e68efc8ff529a7eee08a4f0ba8c8d0a207 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 21 Dec 2023 18:34:17 +0100 -Subject: [PATCH] nvmem: core: add nvmem_dev_size() helper -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is required by layouts that need to read whole NVMEM content. It's -especially useful for NVMEM devices without hardcoded layout (like -U-Boot environment data block). - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Link: https://lore.kernel.org/r/20231221173421.13737-2-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 13 +++++++++++++ - include/linux/nvmem-consumer.h | 1 + - 2 files changed, 14 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -2163,6 +2163,19 @@ const char *nvmem_dev_name(struct nvmem_ - } - EXPORT_SYMBOL_GPL(nvmem_dev_name); - -+/** -+ * nvmem_dev_size() - Get the size of a given nvmem device. -+ * -+ * @nvmem: nvmem device. -+ * -+ * Return: size of the nvmem device. -+ */ -+size_t nvmem_dev_size(struct nvmem_device *nvmem) -+{ -+ return nvmem->size; -+} -+EXPORT_SYMBOL_GPL(nvmem_dev_size); -+ - static int __init nvmem_init(void) - { - int ret; ---- a/include/linux/nvmem-consumer.h -+++ b/include/linux/nvmem-consumer.h -@@ -81,6 +81,7 @@ int nvmem_device_cell_write(struct nvmem - struct nvmem_cell_info *info, void *buf); - - const char *nvmem_dev_name(struct nvmem_device *nvmem); -+size_t nvmem_dev_size(struct nvmem_device *nvmem); - - void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries, - size_t nentries); diff --git a/target/linux/generic/backport-6.1/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch b/target/linux/generic/backport-6.1/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch deleted file mode 100644 index fc826f3f7e4e87..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0011-nvmem-u-boot-env-use-nvmem_add_one_cell-nvmem-subsys.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 7c8979b42b1a9c5604f431ba804928e55919263c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 21 Dec 2023 18:34:18 +0100 -Subject: [PATCH] nvmem: u-boot-env: use nvmem_add_one_cell() nvmem subsystem - helper -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Simplify adding NVMEM cells. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Link: https://lore.kernel.org/r/20231221173421.13737-3-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 55 +++++++++++++++----------------------- - 1 file changed, 21 insertions(+), 34 deletions(-) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -23,13 +23,10 @@ enum u_boot_env_format { - - struct u_boot_env { - struct device *dev; -+ struct nvmem_device *nvmem; - enum u_boot_env_format format; - - struct mtd_info *mtd; -- -- /* Cells */ -- struct nvmem_cell_info *cells; -- int ncells; - }; - - struct u_boot_env_image_single { -@@ -94,43 +91,36 @@ static int u_boot_env_read_post_process_ - static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, - size_t data_offset, size_t data_len) - { -+ struct nvmem_device *nvmem = priv->nvmem; - struct device *dev = priv->dev; - char *data = buf + data_offset; - char *var, *value, *eq; -- int idx; -- -- priv->ncells = 0; -- for (var = data; var < data + data_len && *var; var += strlen(var) + 1) -- priv->ncells++; -- -- priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL); -- if (!priv->cells) -- return -ENOMEM; - -- for (var = data, idx = 0; -+ for (var = data; - var < data + data_len && *var; -- var = value + strlen(value) + 1, idx++) { -+ var = value + strlen(value) + 1) { -+ struct nvmem_cell_info info = {}; -+ - eq = strchr(var, '='); - if (!eq) - break; - *eq = '\0'; - value = eq + 1; - -- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL); -- if (!priv->cells[idx].name) -+ info.name = devm_kstrdup(dev, var, GFP_KERNEL); -+ if (!info.name) - return -ENOMEM; -- priv->cells[idx].offset = data_offset + value - data; -- priv->cells[idx].bytes = strlen(value); -- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name); -+ info.offset = data_offset + value - data; -+ info.bytes = strlen(value); -+ info.np = of_get_child_by_name(dev->of_node, info.name); - if (!strcmp(var, "ethaddr")) { -- priv->cells[idx].raw_len = strlen(value); -- priv->cells[idx].bytes = ETH_ALEN; -- priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr; -+ info.raw_len = strlen(value); -+ info.bytes = ETH_ALEN; -+ info.read_post_process = u_boot_env_read_post_process_ethaddr; - } -- } - -- if (WARN_ON(idx != priv->ncells)) -- priv->ncells = idx; -+ nvmem_add_one_cell(nvmem, &info); -+ } - - return 0; - } -@@ -209,7 +199,6 @@ static int u_boot_env_probe(struct platf - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - struct u_boot_env *priv; -- int err; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -224,17 +213,15 @@ static int u_boot_env_probe(struct platf - return PTR_ERR(priv->mtd); - } - -- err = u_boot_env_parse(priv); -- if (err) -- return err; -- - config.dev = dev; -- config.cells = priv->cells; -- config.ncells = priv->ncells; - config.priv = priv; - config.size = priv->mtd->size; - -- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config)); -+ priv->nvmem = devm_nvmem_register(dev, &config); -+ if (IS_ERR(priv->nvmem)) -+ return PTR_ERR(priv->nvmem); -+ -+ return u_boot_env_parse(priv); - } - - static const struct of_device_id u_boot_env_of_match_table[] = { diff --git a/target/linux/generic/backport-6.1/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch b/target/linux/generic/backport-6.1/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch deleted file mode 100644 index 70abc7cf1439f7..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0012-nvmem-u-boot-env-use-nvmem-device-helpers.patch +++ /dev/null @@ -1,81 +0,0 @@ -From a832556d23c5a11115f300011a5874d6107a0d62 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 21 Dec 2023 18:34:19 +0100 -Subject: [PATCH] nvmem: u-boot-env: use nvmem device helpers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use nvmem_dev_size() and nvmem_device_read() to make this driver less -mtd dependent. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Link: https://lore.kernel.org/r/20231221173421.13737-4-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 23 +++++++++++++++-------- - 1 file changed, 15 insertions(+), 8 deletions(-) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -127,27 +127,34 @@ static int u_boot_env_add_cells(struct u - - static int u_boot_env_parse(struct u_boot_env *priv) - { -+ struct nvmem_device *nvmem = priv->nvmem; - struct device *dev = priv->dev; - size_t crc32_data_offset; - size_t crc32_data_len; - size_t crc32_offset; - size_t data_offset; - size_t data_len; -+ size_t dev_size; - uint32_t crc32; - uint32_t calc; -- size_t bytes; - uint8_t *buf; -+ int bytes; - int err; - -- buf = kcalloc(1, priv->mtd->size, GFP_KERNEL); -+ dev_size = nvmem_dev_size(nvmem); -+ -+ buf = kcalloc(1, dev_size, GFP_KERNEL); - if (!buf) { - err = -ENOMEM; - goto err_out; - } - -- err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf); -- if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) { -- dev_err(dev, "Failed to read from mtd: %d\n", err); -+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf); -+ if (bytes < 0) { -+ err = bytes; -+ goto err_kfree; -+ } else if (bytes != dev_size) { -+ err = -EIO; - goto err_kfree; - } - -@@ -169,8 +176,8 @@ static int u_boot_env_parse(struct u_boo - break; - } - crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); -- crc32_data_len = priv->mtd->size - crc32_data_offset; -- data_len = priv->mtd->size - data_offset; -+ crc32_data_len = dev_size - crc32_data_offset; -+ data_len = dev_size - data_offset; - - calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; - if (calc != crc32) { -@@ -179,7 +186,7 @@ static int u_boot_env_parse(struct u_boo - goto err_kfree; - } - -- buf[priv->mtd->size - 1] = '\0'; -+ buf[dev_size - 1] = '\0'; - err = u_boot_env_add_cells(priv, buf, data_offset, data_len); - if (err) - dev_err(dev, "Failed to add cells: %d\n", err); diff --git a/target/linux/generic/backport-6.1/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch b/target/linux/generic/backport-6.1/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch deleted file mode 100644 index 273cfed8743c04..00000000000000 --- a/target/linux/generic/backport-6.1/819-v6.8-0013-nvmem-u-boot-env-improve-coding-style.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 6bafe07c930676d6430be471310958070816a595 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 21 Dec 2023 18:34:20 +0100 -Subject: [PATCH] nvmem: u-boot-env: improve coding style -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -1. Prefer kzalloc() over kcalloc() - See memory-allocation.rst which says: "to be on the safe side it's - best to use routines that set memory to zero, like kzalloc()" -2. Drop dev_err() for u_boot_env_add_cells() fail - It can fail only on -ENOMEM. We don't want to print error then. -3. Add extra "crc32_addr" variable - It makes code reading header's crc32 easier to understand / review. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Link: https://lore.kernel.org/r/20231221173421.13737-5-zajec5@gmail.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -132,6 +132,7 @@ static int u_boot_env_parse(struct u_boo - size_t crc32_data_offset; - size_t crc32_data_len; - size_t crc32_offset; -+ __le32 *crc32_addr; - size_t data_offset; - size_t data_len; - size_t dev_size; -@@ -143,7 +144,7 @@ static int u_boot_env_parse(struct u_boo - - dev_size = nvmem_dev_size(nvmem); - -- buf = kcalloc(1, dev_size, GFP_KERNEL); -+ buf = kzalloc(dev_size, GFP_KERNEL); - if (!buf) { - err = -ENOMEM; - goto err_out; -@@ -175,7 +176,8 @@ static int u_boot_env_parse(struct u_boo - data_offset = offsetof(struct u_boot_env_image_broadcom, data); - break; - } -- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset)); -+ crc32_addr = (__le32 *)(buf + crc32_offset); -+ crc32 = le32_to_cpu(*crc32_addr); - crc32_data_len = dev_size - crc32_data_offset; - data_len = dev_size - data_offset; - -@@ -188,8 +190,6 @@ static int u_boot_env_parse(struct u_boo - - buf[dev_size - 1] = '\0'; - err = u_boot_env_add_cells(priv, buf, data_offset, data_len); -- if (err) -- dev_err(dev, "Failed to add cells: %d\n", err); - - err_kfree: - kfree(buf); diff --git a/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch b/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch deleted file mode 100644 index 3b68403690c679..00000000000000 --- a/target/linux/generic/backport-6.1/820-v6.4-net-phy-fix-circular-LEDS_CLASS-dependencies.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 4bb7aac70b5d8a4bddf4ee0791b834f9f56883d2 Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Thu, 20 Apr 2023 10:45:51 +0200 -Subject: [PATCH] net: phy: fix circular LEDS_CLASS dependencies - -The CONFIG_PHYLIB symbol is selected by a number of device drivers that -need PHY support, but it now has a dependency on CONFIG_LEDS_CLASS, -which may not be enabled, causing build failures. - -Avoid the risk of missing and circular dependencies by guarding the -phylib LED support itself in another Kconfig symbol that can only be -enabled if the dependency is met. - -This could be made a hidden symbol and always enabled when both CONFIG_OF -and CONFIG_LEDS_CLASS are reachable from the phylib, but there may be an -advantage in having users see this option when they have a misconfigured -kernel without built-in LED support. - -Fixes: 01e5b728e9e4 ("net: phy: Add a binding for PHY LEDs") -Signed-off-by: Arnd Bergmann -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20230420084624.3005701-1-arnd@kernel.org -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/Kconfig | 9 ++++++++- - drivers/net/phy/phy_device.c | 3 ++- - 2 files changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -18,7 +18,6 @@ menuconfig PHYLIB - depends on NETDEVICES - select MDIO_DEVICE - select MDIO_DEVRES -- depends on LEDS_CLASS || LEDS_CLASS=n - help - Ethernet controllers are usually attached to PHY - devices. This option provides infrastructure for -@@ -45,6 +44,14 @@ config LED_TRIGGER_PHY - Mbps OR Gbps OR link - for any speed known to the PHY. - -+config PHYLIB_LEDS -+ bool "Support probing LEDs from device tree" -+ depends on LEDS_CLASS=y || LEDS_CLASS=PHYLIB -+ depends on OF -+ default y -+ help -+ When LED class support is enabled, phylib can automatically -+ probe LED setting from device tree. - - config FIXED_PHY - tristate "MDIO Bus/PHY emulation with fixed speed/link PHYs" ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -3314,7 +3314,8 @@ static int phy_probe(struct device *dev) - /* Get the LEDs from the device tree, and instantiate standard - * LEDs for them. - */ -- err = of_phy_leds(phydev); -+ if (IS_ENABLED(CONFIG_PHYLIB_LEDS)) -+ err = of_phy_leds(phydev); - - out: - /* Re-assert the reset signal on error */ diff --git a/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch b/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch deleted file mode 100644 index 622bb9e94a9e31..00000000000000 --- a/target/linux/generic/backport-6.1/821-v6.4-net-phy-Fix-reading-LED-reg-property.patch +++ /dev/null @@ -1,43 +0,0 @@ -From aed8fdad2152d946add50bec00a6b07c457bdcdf Mon Sep 17 00:00:00 2001 -From: Alexander Stein -Date: Mon, 24 Apr 2023 16:16:48 +0200 -Subject: [PATCH] net: phy: Fix reading LED reg property - -'reg' is always encoded in 32 bits, thus it has to be read using the -function with the corresponding bit width. - -Fixes: 01e5b728e9e4 ("net: phy: Add a binding for PHY LEDs") -Signed-off-by: Alexander Stein -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Link: https://lore.kernel.org/r/20230424141648.317944-1-alexander.stein@ew.tq-group.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phy_device.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -3075,6 +3075,7 @@ static int of_phy_led(struct phy_device - struct led_init_data init_data = {}; - struct led_classdev *cdev; - struct phy_led *phyled; -+ u32 index; - int err; - - phyled = devm_kzalloc(dev, sizeof(*phyled), GFP_KERNEL); -@@ -3084,10 +3085,13 @@ static int of_phy_led(struct phy_device - cdev = &phyled->led_cdev; - phyled->phydev = phydev; - -- err = of_property_read_u8(led, "reg", &phyled->index); -+ err = of_property_read_u32(led, "reg", &index); - if (err) - return err; -+ if (index > U8_MAX) -+ return -EINVAL; - -+ phyled->index = index; - if (phydev->drv->led_brightness_set) - cdev->brightness_set_blocking = phy_led_set_brightness; - if (phydev->drv->led_blink_set) diff --git a/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch b/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch deleted file mode 100644 index 80197e963b8483..00000000000000 --- a/target/linux/generic/backport-6.1/822-v6.4-net-phy-Manual-remove-LEDs-to-ensure-correct-orderin.patch +++ /dev/null @@ -1,67 +0,0 @@ -From c938ab4da0eb1620ae3243b0b24c572ddfc318fc Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Sat, 17 Jun 2023 17:55:00 +0200 -Subject: [PATCH] net: phy: Manual remove LEDs to ensure correct ordering - -If the core is left to remove the LEDs via devm_, it is performed too -late, after the PHY driver is removed from the PHY. This results in -dereferencing a NULL pointer when the LED core tries to turn the LED -off before destroying the LED. - -Manually unregister the LEDs at a safe point in phy_remove. - -Cc: stable@vger.kernel.org -Reported-by: Florian Fainelli -Suggested-by: Florian Fainelli -Fixes: 01e5b728e9e4 ("net: phy: Add a binding for PHY LEDs") -Signed-off-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/phy/phy_device.c | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -3068,6 +3068,15 @@ static int phy_led_blink_set(struct led_ - return err; - } - -+static void phy_leds_unregister(struct phy_device *phydev) -+{ -+ struct phy_led *phyled; -+ -+ list_for_each_entry(phyled, &phydev->leds, list) { -+ led_classdev_unregister(&phyled->led_cdev); -+ } -+} -+ - static int of_phy_led(struct phy_device *phydev, - struct device_node *led) - { -@@ -3101,7 +3110,7 @@ static int of_phy_led(struct phy_device - init_data.fwnode = of_fwnode_handle(led); - init_data.devname_mandatory = true; - -- err = devm_led_classdev_register_ext(dev, cdev, &init_data); -+ err = led_classdev_register_ext(dev, cdev, &init_data); - if (err) - return err; - -@@ -3130,6 +3139,7 @@ static int of_phy_leds(struct phy_device - err = of_phy_led(phydev, led); - if (err) { - of_node_put(led); -+ phy_leds_unregister(phydev); - return err; - } - } -@@ -3335,6 +3345,9 @@ static int phy_remove(struct device *dev - - cancel_delayed_work_sync(&phydev->state_queue); - -+ if (IS_ENABLED(CONFIG_PHYLIB_LEDS)) -+ phy_leds_unregister(phydev); -+ - phydev->state = PHY_DOWN; - - sfp_bus_del_upstream(phydev->sfp_bus); diff --git a/target/linux/generic/backport-6.1/823-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch b/target/linux/generic/backport-6.1/823-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch deleted file mode 100644 index 8e7c8233e224ff..00000000000000 --- a/target/linux/generic/backport-6.1/823-v6.9-0002-nvmem-mtk-efuse-Register-MediaTek-socinfo-driver-fro.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 998f0633773b3432829fe45d2cd2ffb842f3c78e Mon Sep 17 00:00:00 2001 -From: William-tw Lin -Date: Sat, 24 Feb 2024 11:45:07 +0000 -Subject: [PATCH] nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse - -The socinfo driver reads chip information from eFuses and does not need -any devicetree node. Register it from mtk-efuse. - -While at it, also add the name for this driver's nvmem_config. - -Signed-off-by: William-tw Lin -Reviewed-by: AngeloGioacchino Del Regno -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240224114516.86365-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/mtk-efuse.c | 21 ++++++++++++++++++++- - 1 file changed, 20 insertions(+), 1 deletion(-) - ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -68,6 +68,7 @@ static int mtk_efuse_probe(struct platfo - struct nvmem_config econfig = {}; - struct mtk_efuse_priv *priv; - const struct mtk_efuse_pdata *pdata; -+ struct platform_device *socinfo; - - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -85,11 +86,20 @@ static int mtk_efuse_probe(struct platfo - econfig.size = resource_size(res); - econfig.priv = priv; - econfig.dev = dev; -+ econfig.name = "mtk-efuse"; - if (pdata->uses_post_processing) - econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info; - nvmem = devm_nvmem_register(dev, &econfig); -+ if (IS_ERR(nvmem)) -+ return PTR_ERR(nvmem); - -- return PTR_ERR_OR_ZERO(nvmem); -+ socinfo = platform_device_register_data(&pdev->dev, "mtk-socinfo", -+ PLATFORM_DEVID_AUTO, NULL, 0); -+ if (IS_ERR(socinfo)) -+ dev_info(dev, "MediaTek SoC Information will be unavailable\n"); -+ -+ platform_set_drvdata(pdev, socinfo); -+ return 0; - } - - static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = { -@@ -108,8 +118,17 @@ static const struct of_device_id mtk_efu - }; - MODULE_DEVICE_TABLE(of, mtk_efuse_of_match); - -+static void mtk_efuse_remove(struct platform_device *pdev) -+{ -+ struct platform_device *socinfo = platform_get_drvdata(pdev); -+ -+ if (!IS_ERR_OR_NULL(socinfo)) -+ platform_device_unregister(socinfo); -+} -+ - static struct platform_driver mtk_efuse_driver = { - .probe = mtk_efuse_probe, -+ .remove_new = mtk_efuse_remove, - .driver = { - .name = "mediatek,efuse", - .of_match_table = mtk_efuse_of_match, diff --git a/target/linux/generic/backport-6.1/823-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch b/target/linux/generic/backport-6.1/823-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch deleted file mode 100644 index 0f90e548a2a66b..00000000000000 --- a/target/linux/generic/backport-6.1/823-v6.9-0003-nvmem-zynqmp_nvmem-zynqmp_nvmem_probe-cleanup.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 29be47fcd6a06ea2e79eeeca6e69ad1e23254a69 Mon Sep 17 00:00:00 2001 -From: Praveen Teja Kundanala -Date: Sat, 24 Feb 2024 11:45:11 +0000 -Subject: [PATCH] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup - -- Remove static nvmem_config declaration -- Remove zynqmp_nvmem_data - -Signed-off-by: Praveen Teja Kundanala -Acked-by: Kalyani Akula -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240224114516.86365-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------ - 1 file changed, 12 insertions(+), 25 deletions(-) - ---- a/drivers/nvmem/zynqmp_nvmem.c -+++ b/drivers/nvmem/zynqmp_nvmem.c -@@ -1,6 +1,7 @@ - // SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright (C) 2019 Xilinx, Inc. -+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. - */ - - #include -@@ -11,36 +12,25 @@ - - #define SILICON_REVISION_MASK 0xF - --struct zynqmp_nvmem_data { -- struct device *dev; -- struct nvmem_device *nvmem; --}; - - static int zynqmp_nvmem_read(void *context, unsigned int offset, - void *val, size_t bytes) - { -+ struct device *dev = context; - int ret; -- int idcode, version; -- struct zynqmp_nvmem_data *priv = context; -+ int idcode; -+ int version; - - ret = zynqmp_pm_get_chipid(&idcode, &version); - if (ret < 0) - return ret; - -- dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version); -+ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version); - *(int *)val = version & SILICON_REVISION_MASK; - - return 0; - } - --static struct nvmem_config econfig = { -- .name = "zynqmp-nvmem", -- .owner = THIS_MODULE, -- .word_size = 1, -- .size = 1, -- .read_only = true, --}; -- - static const struct of_device_id zynqmp_nvmem_match[] = { - { .compatible = "xlnx,zynqmp-nvmem-fw", }, - { /* sentinel */ }, -@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_mat - static int zynqmp_nvmem_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; -- struct zynqmp_nvmem_data *priv; -+ struct nvmem_config econfig = {}; - -- priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL); -- if (!priv) -- return -ENOMEM; -- -- priv->dev = dev; -+ econfig.name = "zynqmp-nvmem"; -+ econfig.owner = THIS_MODULE; -+ econfig.word_size = 1; -+ econfig.size = 1; - econfig.dev = dev; - econfig.add_legacy_fixed_of_cells = true; -+ econfig.read_only = true; - econfig.reg_read = zynqmp_nvmem_read; -- econfig.priv = priv; -- -- priv->nvmem = devm_nvmem_register(dev, &econfig); - -- return PTR_ERR_OR_ZERO(priv->nvmem); -+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig)); - } - - static struct platform_driver zynqmp_nvmem_driver = { diff --git a/target/linux/generic/backport-6.1/823-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch b/target/linux/generic/backport-6.1/823-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch deleted file mode 100644 index 39c2f178350bf1..00000000000000 --- a/target/linux/generic/backport-6.1/823-v6.9-0004-nvmem-zynqmp_nvmem-Add-support-to-access-efuse.patch +++ /dev/null @@ -1,243 +0,0 @@ -From 737c0c8d07b5f671c0a33cec95965fcb2d2ea893 Mon Sep 17 00:00:00 2001 -From: Praveen Teja Kundanala -Date: Sat, 24 Feb 2024 11:45:12 +0000 -Subject: [PATCH] nvmem: zynqmp_nvmem: Add support to access efuse - -Add support to read/write efuse memory map of ZynqMP. -Below are the offsets of ZynqMP efuse memory map - 0 - SOC version(read only) - 0xC - 0xFC -ZynqMP specific purpose efuses - 0x100 - 0x17F - Physical Unclonable Function(PUF) - efuses repurposed as user efuses - -Signed-off-by: Praveen Teja Kundanala -Acked-by: Kalyani Akula -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240224114516.86365-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/zynqmp_nvmem.c | 186 +++++++++++++++++++++++++++++++++-- - 1 file changed, 176 insertions(+), 10 deletions(-) - ---- a/drivers/nvmem/zynqmp_nvmem.c -+++ b/drivers/nvmem/zynqmp_nvmem.c -@@ -4,6 +4,7 @@ - * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. - */ - -+#include - #include - #include - #include -@@ -11,24 +12,189 @@ - #include - - #define SILICON_REVISION_MASK 0xF -+#define P_USER_0_64_UPPER_MASK GENMASK(31, 16) -+#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0) -+#define WORD_INBYTES 4 -+#define SOC_VER_SIZE 0x4 -+#define EFUSE_MEMORY_SIZE 0x177 -+#define UNUSED_SPACE 0x8 -+#define ZYNQMP_NVMEM_SIZE (SOC_VER_SIZE + UNUSED_SPACE + \ -+ EFUSE_MEMORY_SIZE) -+#define SOC_VERSION_OFFSET 0x0 -+#define EFUSE_START_OFFSET 0xC -+#define EFUSE_END_OFFSET 0xFC -+#define EFUSE_PUF_START_OFFSET 0x100 -+#define EFUSE_PUF_MID_OFFSET 0x140 -+#define EFUSE_PUF_END_OFFSET 0x17F -+#define EFUSE_NOT_ENABLED 29 - -+/* -+ * efuse access type -+ */ -+enum efuse_access { -+ EFUSE_READ = 0, -+ EFUSE_WRITE -+}; -+ -+/** -+ * struct xilinx_efuse - the basic structure -+ * @src: address of the buffer to store the data to be write/read -+ * @size: read/write word count -+ * @offset: read/write offset -+ * @flag: 0 - represents efuse read and 1- represents efuse write -+ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write -+ * 1 - represents puf user fuse row number. -+ * -+ * this structure stores all the required details to -+ * read/write efuse memory. -+ */ -+struct xilinx_efuse { -+ u64 src; -+ u32 size; -+ u32 offset; -+ enum efuse_access flag; -+ u32 pufuserfuse; -+}; -+ -+static int zynqmp_efuse_access(void *context, unsigned int offset, -+ void *val, size_t bytes, enum efuse_access flag, -+ unsigned int pufflag) -+{ -+ struct device *dev = context; -+ struct xilinx_efuse *efuse; -+ dma_addr_t dma_addr; -+ dma_addr_t dma_buf; -+ size_t words = bytes / WORD_INBYTES; -+ int ret; -+ int value; -+ char *data; - --static int zynqmp_nvmem_read(void *context, unsigned int offset, -- void *val, size_t bytes) -+ if (bytes % WORD_INBYTES != 0) { -+ dev_err(dev, "Bytes requested should be word aligned\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (pufflag == 0 && offset % WORD_INBYTES) { -+ dev_err(dev, "Offset requested should be word aligned\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (pufflag == 1 && flag == EFUSE_WRITE) { -+ memcpy(&value, val, bytes); -+ if ((offset == EFUSE_PUF_START_OFFSET || -+ offset == EFUSE_PUF_MID_OFFSET) && -+ value & P_USER_0_64_UPPER_MASK) { -+ dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ if (offset == EFUSE_PUF_END_OFFSET && -+ (value & P_USER_127_LOWER_4_BIT_MASK)) { -+ dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n"); -+ return -EOPNOTSUPP; -+ } -+ } -+ -+ efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse), -+ &dma_addr, GFP_KERNEL); -+ if (!efuse) -+ return -ENOMEM; -+ -+ data = dma_alloc_coherent(dev, sizeof(bytes), -+ &dma_buf, GFP_KERNEL); -+ if (!data) { -+ ret = -ENOMEM; -+ goto efuse_data_fail; -+ } -+ -+ if (flag == EFUSE_WRITE) { -+ memcpy(data, val, bytes); -+ efuse->flag = EFUSE_WRITE; -+ } else { -+ efuse->flag = EFUSE_READ; -+ } -+ -+ efuse->src = dma_buf; -+ efuse->size = words; -+ efuse->offset = offset; -+ efuse->pufuserfuse = pufflag; -+ -+ zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret); -+ if (ret != 0) { -+ if (ret == EFUSE_NOT_ENABLED) { -+ dev_err(dev, "efuse access is not enabled\n"); -+ ret = -EOPNOTSUPP; -+ } else { -+ dev_err(dev, "Error in efuse read %x\n", ret); -+ ret = -EPERM; -+ } -+ goto efuse_access_err; -+ } -+ -+ if (flag == EFUSE_READ) -+ memcpy(val, data, bytes); -+efuse_access_err: -+ dma_free_coherent(dev, sizeof(bytes), -+ data, dma_buf); -+efuse_data_fail: -+ dma_free_coherent(dev, sizeof(struct xilinx_efuse), -+ efuse, dma_addr); -+ -+ return ret; -+} -+ -+static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size_t bytes) - { - struct device *dev = context; - int ret; -+ int pufflag = 0; - int idcode; - int version; - -- ret = zynqmp_pm_get_chipid(&idcode, &version); -- if (ret < 0) -- return ret; -+ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET) -+ pufflag = 1; -+ -+ switch (offset) { -+ /* Soc version offset is zero */ -+ case SOC_VERSION_OFFSET: -+ if (bytes != SOC_VER_SIZE) -+ return -EOPNOTSUPP; -+ -+ ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32 *)&version); -+ if (ret < 0) -+ return ret; -+ -+ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version); -+ *(int *)val = version & SILICON_REVISION_MASK; -+ break; -+ /* Efuse offset starts from 0xc */ -+ case EFUSE_START_OFFSET ... EFUSE_END_OFFSET: -+ case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET: -+ ret = zynqmp_efuse_access(context, offset, val, -+ bytes, EFUSE_READ, pufflag); -+ break; -+ default: -+ *(u32 *)val = 0xDEADBEEF; -+ ret = 0; -+ break; -+ } -+ -+ return ret; -+} -+ -+static int zynqmp_nvmem_write(void *context, -+ unsigned int offset, void *val, size_t bytes) -+{ -+ int pufflag = 0; -+ -+ if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET) -+ return -EOPNOTSUPP; - -- dev_dbg(dev, "Read chipid val %x %x\n", idcode, version); -- *(int *)val = version & SILICON_REVISION_MASK; -+ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET) -+ pufflag = 1; - -- return 0; -+ return zynqmp_efuse_access(context, offset, -+ val, bytes, EFUSE_WRITE, pufflag); - } - - static const struct of_device_id zynqmp_nvmem_match[] = { -@@ -45,11 +211,11 @@ static int zynqmp_nvmem_probe(struct pla - econfig.name = "zynqmp-nvmem"; - econfig.owner = THIS_MODULE; - econfig.word_size = 1; -- econfig.size = 1; -+ econfig.size = ZYNQMP_NVMEM_SIZE; - econfig.dev = dev; - econfig.add_legacy_fixed_of_cells = true; -- econfig.read_only = true; - econfig.reg_read = zynqmp_nvmem_read; -+ econfig.reg_write = zynqmp_nvmem_write; - - return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig)); - } diff --git a/target/linux/generic/backport-6.1/823-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch b/target/linux/generic/backport-6.1/823-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch deleted file mode 100644 index c67399cb13d076..00000000000000 --- a/target/linux/generic/backport-6.1/823-v6.9-0005-nvmem-mtk-efuse-Drop-NVMEM-device-name.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 76c345edef754b16cab81ad9452cc49c09e67066 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Sat, 24 Feb 2024 11:45:14 +0000 -Subject: [PATCH] nvmem: mtk-efuse: Drop NVMEM device name -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The MT8183 has not one but two efuse devices. The static name and ID -causes the second efuse device to fail to probe, due to duplicate sysfs -entries. - -With the rework of the mtk-socinfo driver, lookup by name is no longer -necessary. The custom name can simply be dropped. - -Signed-off-by: Chen-Yu Tsai -Reviewed-by: AngeloGioacchino Del Regno -Tested-by: "Nícolas F. R. A. Prado" -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240224114516.86365-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/mtk-efuse.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/nvmem/mtk-efuse.c -+++ b/drivers/nvmem/mtk-efuse.c -@@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platfo - econfig.size = resource_size(res); - econfig.priv = priv; - econfig.dev = dev; -- econfig.name = "mtk-efuse"; - if (pdata->uses_post_processing) - econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info; - nvmem = devm_nvmem_register(dev, &econfig); diff --git a/target/linux/generic/backport-6.1/823-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch b/target/linux/generic/backport-6.1/823-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch deleted file mode 100644 index 17bab2480261e4..00000000000000 --- a/target/linux/generic/backport-6.1/823-v6.9-0007-nvmem-core-Print-error-on-wrong-bits-DT-property.patch +++ /dev/null @@ -1,32 +0,0 @@ -From def3173d4f17b37cecbd74d7c269a080b0b01598 Mon Sep 17 00:00:00 2001 -From: Markus Schneider-Pargmann -Date: Sat, 24 Feb 2024 11:45:16 +0000 -Subject: [PATCH] nvmem: core: Print error on wrong bits DT property - -The algorithms in nvmem core are built with the constraint that -bit_offset < 8. If bit_offset is greater the results are wrong. Print an -error if the devicetree 'bits' property is outside of the valid range -and abort parsing. - -Signed-off-by: Markus Schneider-Pargmann -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240224114516.86365-12-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -806,6 +806,11 @@ static int nvmem_add_cells_from_dt(struc - if (addr && len == (2 * sizeof(u32))) { - info.bit_offset = be32_to_cpup(addr++); - info.nbits = be32_to_cpup(addr); -+ if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) { -+ dev_err(dev, "nvmem: invalid bits on %pOF\n", child); -+ of_node_put(child); -+ return -EINVAL; -+ } - } - - info.np = of_node_get(child); diff --git a/target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch b/target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch deleted file mode 100644 index 609115b04aaa87..00000000000000 --- a/target/linux/generic/backport-6.1/824-v6.5-leds-trigger-netdev-Remove-NULL-check-before-dev_-pu.patch +++ /dev/null @@ -1,44 +0,0 @@ -From af7320ecae0ce646fd2c4a88341a3fbc243553da Mon Sep 17 00:00:00 2001 -From: Yang Li -Date: Thu, 11 May 2023 15:08:20 +0800 -Subject: [PATCH] leds: trigger: netdev: Remove NULL check before dev_{put, - hold} - -The call netdev_{put, hold} of dev_{put, hold} will check NULL, -so there is no need to check before using dev_{put, hold}, -remove it to silence the warnings: - -./drivers/leds/trigger/ledtrig-netdev.c:291:3-10: WARNING: NULL check before dev_{put, hold} functions is not needed. -./drivers/leds/trigger/ledtrig-netdev.c:401:2-9: WARNING: NULL check before dev_{put, hold} functions is not needed. - -Reported-by: Abaci Robot -Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=4929 -Signed-off-by: Yang Li -Link: https://lore.kernel.org/r/20230511070820.52731-1-yang.lee@linux.alibaba.com -Signed-off-by: Lee Jones ---- - drivers/leds/trigger/ledtrig-netdev.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -462,8 +462,7 @@ static int netdev_trig_notify(struct not - get_device_state(trigger_data); - fallthrough; - case NETDEV_REGISTER: -- if (trigger_data->net_dev) -- dev_put(trigger_data->net_dev); -+ dev_put(trigger_data->net_dev); - dev_hold(dev); - trigger_data->net_dev = dev; - break; -@@ -594,8 +593,7 @@ static void netdev_trig_deactivate(struc - - cancel_delayed_work_sync(&trigger_data->work); - -- if (trigger_data->net_dev) -- dev_put(trigger_data->net_dev); -+ dev_put(trigger_data->net_dev); - - kfree(trigger_data); - } diff --git a/target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch b/target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch deleted file mode 100644 index 2f7a6ced9011ac..00000000000000 --- a/target/linux/generic/backport-6.1/825-v6.5-leds-trigger-netdev-uninitialized-variable-in-netdev.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 97c5209b3d374a25ebdb4c2ea9e9c1b121768da0 Mon Sep 17 00:00:00 2001 -From: Dan Carpenter -Date: Wed, 14 Jun 2023 10:03:59 +0300 -Subject: [PATCH] leds: trigger: netdev: uninitialized variable in - netdev_trig_activate() - -The qca8k_cled_hw_control_get() function which implements ->hw_control_get -sets the appropriate bits but does not clear them. This leads to an -uninitialized variable bug. Fix this by setting mode to zero at the -start. - -Fixes: e0256648c831 ("net: dsa: qca8k: implement hw_control ops") -Signed-off-by: Dan Carpenter -Reviewed-by: Andrew Lunn -Acked-by: Lee Jones -Signed-off-by: David S. Miller ---- - drivers/leds/trigger/ledtrig-netdev.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -538,7 +538,7 @@ static void netdev_trig_work(struct work - static int netdev_trig_activate(struct led_classdev *led_cdev) - { - struct led_netdev_data *trigger_data; -- unsigned long mode; -+ unsigned long mode = 0; - struct device *dev; - int rc; - diff --git a/target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch b/target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch deleted file mode 100644 index dedf84c64bfe90..00000000000000 --- a/target/linux/generic/backport-6.1/826-v6.6-01-led-trig-netdev-Fix-requesting-offload-device.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 7df1f14c04cbb1950e79c19793420f87227c3e80 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Tue, 8 Aug 2023 23:04:33 +0200 -Subject: [PATCH 1/4] led: trig: netdev: Fix requesting offload device - -When the netdev trigger is activates, it tries to determine what -device the LED blinks for, and what the current blink mode is. - -The documentation for hw_control_get() says: - - * Return 0 on success, a negative error number on failing parsing the - * initial mode. Error from this function is NOT FATAL as the device - * may be in a not supported initial state by the attached LED trigger. - */ - -For the Marvell PHY and the Armada 370-rd board, the initial LED blink -mode is not supported by the trigger, so it returns an error. This -resulted in not getting the device the LED is blinking for. As a -result, the device is unknown and offloaded is never performed. - -Change to condition to always get the device if offloading is -supported, and reduce the scope of testing for an error from -hw_control_get() to skip setting trigger internal state if there is an -error. - -Reviewed-by: Simon Horman -Signed-off-by: Andrew Lunn -Tested-by: Daniel Golle -Link: https://lore.kernel.org/r/20230808210436.838995-2-andrew@lunn.ch -Signed-off-by: Jakub Kicinski ---- - drivers/leds/trigger/ledtrig-netdev.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -564,15 +564,17 @@ static int netdev_trig_activate(struct l - /* Check if hw control is active by default on the LED. - * Init already enabled mode in hw control. - */ -- if (supports_hw_control(led_cdev) && -- !led_cdev->hw_control_get(led_cdev, &mode)) { -+ if (supports_hw_control(led_cdev)) { - dev = led_cdev->hw_control_get_device(led_cdev); - if (dev) { - const char *name = dev_name(dev); - - set_device_name(trigger_data, name, strlen(name)); - trigger_data->hw_control = true; -- trigger_data->mode = mode; -+ -+ rc = led_cdev->hw_control_get(led_cdev, &mode); -+ if (!rc) -+ trigger_data->mode = mode; - } - } - diff --git a/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch b/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch deleted file mode 100644 index 505513a53fe31f..00000000000000 --- a/target/linux/generic/backport-6.1/826-v6.6-02-net-phy-phy_device-Call-into-the-PHY-driver-to-set-L.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 1dcc03c9a7a824a31eaaecdfaa03542fb25feb6c Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Tue, 8 Aug 2023 23:04:34 +0200 -Subject: [PATCH 2/4] net: phy: phy_device: Call into the PHY driver to set LED - offload - -Linux LEDs can be requested to perform hardware accelerated blinking -to indicate link, RX, TX etc. Pass the rules for blinking to the PHY -driver, if it implements the ops needed to determine if a given -pattern can be offloaded, to offload it, and what the current offload -is. Additionally implement the op needed to get what device the LED is -for. - -Reviewed-by: Simon Horman -Signed-off-by: Andrew Lunn -Tested-by: Daniel Golle -Link: https://lore.kernel.org/r/20230808210436.838995-3-andrew@lunn.ch -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phy_device.c | 68 ++++++++++++++++++++++++++++++++++++ - include/linux/phy.h | 33 +++++++++++++++++ - 2 files changed, 101 insertions(+) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -3068,6 +3068,61 @@ static int phy_led_blink_set(struct led_ - return err; - } - -+static __maybe_unused struct device * -+phy_led_hw_control_get_device(struct led_classdev *led_cdev) -+{ -+ struct phy_led *phyled = to_phy_led(led_cdev); -+ struct phy_device *phydev = phyled->phydev; -+ -+ if (phydev->attached_dev) -+ return &phydev->attached_dev->dev; -+ return NULL; -+} -+ -+static int __maybe_unused -+phy_led_hw_control_get(struct led_classdev *led_cdev, -+ unsigned long *rules) -+{ -+ struct phy_led *phyled = to_phy_led(led_cdev); -+ struct phy_device *phydev = phyled->phydev; -+ int err; -+ -+ mutex_lock(&phydev->lock); -+ err = phydev->drv->led_hw_control_get(phydev, phyled->index, rules); -+ mutex_unlock(&phydev->lock); -+ -+ return err; -+} -+ -+static int __maybe_unused -+phy_led_hw_control_set(struct led_classdev *led_cdev, -+ unsigned long rules) -+{ -+ struct phy_led *phyled = to_phy_led(led_cdev); -+ struct phy_device *phydev = phyled->phydev; -+ int err; -+ -+ mutex_lock(&phydev->lock); -+ err = phydev->drv->led_hw_control_set(phydev, phyled->index, rules); -+ mutex_unlock(&phydev->lock); -+ -+ return err; -+} -+ -+static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev, -+ unsigned long rules) -+{ -+ struct phy_led *phyled = to_phy_led(led_cdev); -+ struct phy_device *phydev = phyled->phydev; -+ int err; -+ -+ mutex_lock(&phydev->lock); -+ err = phydev->drv->led_hw_is_supported(phydev, phyled->index, rules); -+ mutex_unlock(&phydev->lock); -+ -+ return err; -+} -+ - static void phy_leds_unregister(struct phy_device *phydev) - { - struct phy_led *phyled; -@@ -3105,6 +3160,19 @@ static int of_phy_led(struct phy_device - cdev->brightness_set_blocking = phy_led_set_brightness; - if (phydev->drv->led_blink_set) - cdev->blink_set = phy_led_blink_set; -+ -+#ifdef CONFIG_LEDS_TRIGGERS -+ if (phydev->drv->led_hw_is_supported && -+ phydev->drv->led_hw_control_set && -+ phydev->drv->led_hw_control_get) { -+ cdev->hw_control_is_supported = phy_led_hw_is_supported; -+ cdev->hw_control_set = phy_led_hw_control_set; -+ cdev->hw_control_get = phy_led_hw_control_get; -+ cdev->hw_control_trigger = "netdev"; -+ } -+ -+ cdev->hw_control_get_device = phy_led_hw_control_get_device; -+#endif - cdev->max_brightness = 1; - init_data.devicename = dev_name(&phydev->mdio.dev); - init_data.fwnode = of_fwnode_handle(led); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -1026,6 +1026,39 @@ struct phy_driver { - int (*led_blink_set)(struct phy_device *dev, u8 index, - unsigned long *delay_on, - unsigned long *delay_off); -+ /** -+ * @led_hw_is_supported: Can the HW support the given rules. -+ * @dev: PHY device which has the LED -+ * @index: Which LED of the PHY device -+ * @rules The core is interested in these rules -+ * -+ * Return 0 if yes, -EOPNOTSUPP if not, or an error code. -+ */ -+ int (*led_hw_is_supported)(struct phy_device *dev, u8 index, -+ unsigned long rules); -+ /** -+ * @led_hw_control_set: Set the HW to control the LED -+ * @dev: PHY device which has the LED -+ * @index: Which LED of the PHY device -+ * @rules The rules used to control the LED -+ * -+ * Returns 0, or a an error code. -+ */ -+ int (*led_hw_control_set)(struct phy_device *dev, u8 index, -+ unsigned long rules); -+ /** -+ * @led_hw_control_get: Get how the HW is controlling the LED -+ * @dev: PHY device which has the LED -+ * @index: Which LED of the PHY device -+ * @rules Pointer to the rules used to control the LED -+ * -+ * Set *@rules to how the HW is currently blinking. Returns 0 -+ * on success, or a error code if the current blinking cannot -+ * be represented in rules, or some other error happens. -+ */ -+ int (*led_hw_control_get)(struct phy_device *dev, u8 index, -+ unsigned long *rules); -+ - }; - #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ - struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch b/target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch deleted file mode 100644 index 1300583b665a66..00000000000000 --- a/target/linux/generic/backport-6.1/826-v6.6-03-net-phy-marvell-Add-support-for-offloading-LED-blink.patch +++ /dev/null @@ -1,344 +0,0 @@ -From 460b0b648fab24f576c481424e0de5479ffb9786 Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Tue, 8 Aug 2023 23:04:35 +0200 -Subject: [PATCH 3/4] net: phy: marvell: Add support for offloading LED - blinking - -Add the code needed to indicate if a given blinking pattern can be -offloaded, to offload a pattern and to try to return the current -pattern. - -Reviewed-by: Simon Horman -Signed-off-by: Andrew Lunn -Tested-by: Daniel Golle -Link: https://lore.kernel.org/r/20230808210436.838995-4-andrew@lunn.ch -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/marvell.c | 281 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 281 insertions(+) - ---- a/drivers/net/phy/marvell.c -+++ b/drivers/net/phy/marvell.c -@@ -2893,6 +2893,272 @@ static int m88e1318_led_blink_set(struct - MII_88E1318S_PHY_LED_FUNC, reg); - } - -+struct marvell_led_rules { -+ int mode; -+ unsigned long rules; -+}; -+ -+static const struct marvell_led_rules marvell_led0[] = { -+ { -+ .mode = 0, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ }, -+ { -+ .mode = 1, -+ .rules = (BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)), -+ }, -+ { -+ .mode = 3, -+ .rules = (BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)), -+ }, -+ { -+ .mode = 4, -+ .rules = (BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)), -+ }, -+ { -+ .mode = 5, -+ .rules = BIT(TRIGGER_NETDEV_TX), -+ }, -+ { -+ .mode = 6, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ }, -+ { -+ .mode = 7, -+ .rules = BIT(TRIGGER_NETDEV_LINK_1000), -+ }, -+ { -+ .mode = 8, -+ .rules = 0, -+ }, -+}; -+ -+static const struct marvell_led_rules marvell_led1[] = { -+ { -+ .mode = 1, -+ .rules = (BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)), -+ }, -+ { -+ .mode = 2, -+ .rules = (BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_RX)), -+ }, -+ { -+ .mode = 3, -+ .rules = (BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)), -+ }, -+ { -+ .mode = 4, -+ .rules = (BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)), -+ }, -+ { -+ .mode = 6, -+ .rules = (BIT(TRIGGER_NETDEV_LINK_100) | -+ BIT(TRIGGER_NETDEV_LINK_1000)), -+ }, -+ { -+ .mode = 7, -+ .rules = BIT(TRIGGER_NETDEV_LINK_100), -+ }, -+ { -+ .mode = 8, -+ .rules = 0, -+ }, -+}; -+ -+static const struct marvell_led_rules marvell_led2[] = { -+ { -+ .mode = 0, -+ .rules = BIT(TRIGGER_NETDEV_LINK), -+ }, -+ { -+ .mode = 1, -+ .rules = (BIT(TRIGGER_NETDEV_LINK) | -+ BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)), -+ }, -+ { -+ .mode = 3, -+ .rules = (BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)), -+ }, -+ { -+ .mode = 4, -+ .rules = (BIT(TRIGGER_NETDEV_RX) | -+ BIT(TRIGGER_NETDEV_TX)), -+ }, -+ { -+ .mode = 5, -+ .rules = BIT(TRIGGER_NETDEV_TX), -+ }, -+ { -+ .mode = 6, -+ .rules = (BIT(TRIGGER_NETDEV_LINK_10) | -+ BIT(TRIGGER_NETDEV_LINK_1000)), -+ }, -+ { -+ .mode = 7, -+ .rules = BIT(TRIGGER_NETDEV_LINK_10), -+ }, -+ { -+ .mode = 8, -+ .rules = 0, -+ }, -+}; -+ -+static int marvell_find_led_mode(unsigned long rules, -+ const struct marvell_led_rules *marvell_rules, -+ int count, -+ int *mode) -+{ -+ int i; -+ -+ for (i = 0; i < count; i++) { -+ if (marvell_rules[i].rules == rules) { -+ *mode = marvell_rules[i].mode; -+ return 0; -+ } -+ } -+ return -EOPNOTSUPP; -+} -+ -+static int marvell_get_led_mode(u8 index, unsigned long rules, int *mode) -+{ -+ int ret; -+ -+ switch (index) { -+ case 0: -+ ret = marvell_find_led_mode(rules, marvell_led0, -+ ARRAY_SIZE(marvell_led0), mode); -+ break; -+ case 1: -+ ret = marvell_find_led_mode(rules, marvell_led1, -+ ARRAY_SIZE(marvell_led1), mode); -+ break; -+ case 2: -+ ret = marvell_find_led_mode(rules, marvell_led2, -+ ARRAY_SIZE(marvell_led2), mode); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+static int marvell_find_led_rules(unsigned long *rules, -+ const struct marvell_led_rules *marvell_rules, -+ int count, -+ int mode) -+{ -+ int i; -+ -+ for (i = 0; i < count; i++) { -+ if (marvell_rules[i].mode == mode) { -+ *rules = marvell_rules[i].rules; -+ return 0; -+ } -+ } -+ return -EOPNOTSUPP; -+} -+ -+static int marvell_get_led_rules(u8 index, unsigned long *rules, int mode) -+{ -+ int ret; -+ -+ switch (index) { -+ case 0: -+ ret = marvell_find_led_rules(rules, marvell_led0, -+ ARRAY_SIZE(marvell_led0), mode); -+ break; -+ case 1: -+ ret = marvell_find_led_rules(rules, marvell_led1, -+ ARRAY_SIZE(marvell_led1), mode); -+ break; -+ case 2: -+ ret = marvell_find_led_rules(rules, marvell_led2, -+ ARRAY_SIZE(marvell_led2), mode); -+ break; -+ default: -+ ret = -EOPNOTSUPP; -+ } -+ -+ return ret; -+} -+ -+static int m88e1318_led_hw_is_supported(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ int mode, ret; -+ -+ switch (index) { -+ case 0: -+ case 1: -+ case 2: -+ ret = marvell_get_led_mode(index, rules, &mode); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+static int m88e1318_led_hw_control_set(struct phy_device *phydev, u8 index, -+ unsigned long rules) -+{ -+ int mode, ret, reg; -+ -+ switch (index) { -+ case 0: -+ case 1: -+ case 2: -+ ret = marvell_get_led_mode(index, rules, &mode); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ -+ if (ret < 0) -+ return ret; -+ -+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC); -+ if (reg < 0) -+ return reg; -+ -+ reg &= ~(0xf << (4 * index)); -+ reg |= mode << (4 * index); -+ return phy_write_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC, reg); -+} -+ -+static int m88e1318_led_hw_control_get(struct phy_device *phydev, u8 index, -+ unsigned long *rules) -+{ -+ int mode, reg; -+ -+ if (index > 2) -+ return -EINVAL; -+ -+ reg = phy_read_paged(phydev, MII_MARVELL_LED_PAGE, -+ MII_88E1318S_PHY_LED_FUNC); -+ if (reg < 0) -+ return reg; -+ -+ mode = (reg >> (4 * index)) & 0xf; -+ -+ return marvell_get_led_rules(index, rules, mode); -+} -+ - static int marvell_probe(struct phy_device *phydev) - { - struct marvell_priv *priv; -@@ -3144,6 +3410,9 @@ static struct phy_driver marvell_drivers - .get_stats = marvell_get_stats, - .led_brightness_set = m88e1318_led_brightness_set, - .led_blink_set = m88e1318_led_blink_set, -+ .led_hw_is_supported = m88e1318_led_hw_is_supported, -+ .led_hw_control_set = m88e1318_led_hw_control_set, -+ .led_hw_control_get = m88e1318_led_hw_control_get, - }, - { - .phy_id = MARVELL_PHY_ID_88E1145, -@@ -3252,6 +3521,9 @@ static struct phy_driver marvell_drivers - .cable_test_get_status = marvell_vct7_cable_test_get_status, - .led_brightness_set = m88e1318_led_brightness_set, - .led_blink_set = m88e1318_led_blink_set, -+ .led_hw_is_supported = m88e1318_led_hw_is_supported, -+ .led_hw_control_set = m88e1318_led_hw_control_set, -+ .led_hw_control_get = m88e1318_led_hw_control_get, - }, - { - .phy_id = MARVELL_PHY_ID_88E1540, -@@ -3280,6 +3552,9 @@ static struct phy_driver marvell_drivers - .cable_test_get_status = marvell_vct7_cable_test_get_status, - .led_brightness_set = m88e1318_led_brightness_set, - .led_blink_set = m88e1318_led_blink_set, -+ .led_hw_is_supported = m88e1318_led_hw_is_supported, -+ .led_hw_control_set = m88e1318_led_hw_control_set, -+ .led_hw_control_get = m88e1318_led_hw_control_get, - }, - { - .phy_id = MARVELL_PHY_ID_88E1545, -@@ -3308,6 +3583,9 @@ static struct phy_driver marvell_drivers - .cable_test_get_status = marvell_vct7_cable_test_get_status, - .led_brightness_set = m88e1318_led_brightness_set, - .led_blink_set = m88e1318_led_blink_set, -+ .led_hw_is_supported = m88e1318_led_hw_is_supported, -+ .led_hw_control_set = m88e1318_led_hw_control_set, -+ .led_hw_control_get = m88e1318_led_hw_control_get, - }, - { - .phy_id = MARVELL_PHY_ID_88E3016, -@@ -3451,6 +3729,9 @@ static struct phy_driver marvell_drivers - .set_tunable = m88e1540_set_tunable, - .led_brightness_set = m88e1318_led_brightness_set, - .led_blink_set = m88e1318_led_blink_set, -+ .led_hw_is_supported = m88e1318_led_hw_is_supported, -+ .led_hw_control_set = m88e1318_led_hw_control_set, -+ .led_hw_control_get = m88e1318_led_hw_control_get, - }, - }; - diff --git a/target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch b/target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch deleted file mode 100644 index d6a69aa9ca2d15..00000000000000 --- a/target/linux/generic/backport-6.1/826-v6.6-04-leds-trig-netdev-Disable-offload-on-deactivation-of-.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e8fbcc47a8e935f36f044d85f21a99acecbd7bfb Mon Sep 17 00:00:00 2001 -From: Andrew Lunn -Date: Tue, 8 Aug 2023 23:04:36 +0200 -Subject: [PATCH 4/4] leds: trig-netdev: Disable offload on deactivation of - trigger - -Ensure that the offloading of blinking is stopped when the trigger is -deactivated. Calling led_set_brightness() is documented as stopping -offload and setting the LED to a constant brightness. - -Suggested-by: Daniel Golle -Signed-off-by: Andrew Lunn -Reviewed-by: Simon Horman -Tested-by: Daniel Golle -Link: https://lore.kernel.org/r/20230808210436.838995-5-andrew@lunn.ch -Signed-off-by: Jakub Kicinski ---- - drivers/leds/trigger/ledtrig-netdev.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -595,6 +595,8 @@ static void netdev_trig_deactivate(struc - - cancel_delayed_work_sync(&trigger_data->work); - -+ led_set_brightness(led_cdev, LED_OFF); -+ - dev_put(trigger_data->net_dev); - - kfree(trigger_data); diff --git a/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch b/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch deleted file mode 100644 index b4cb96d24832ef..00000000000000 --- a/target/linux/generic/backport-6.1/827-v6.3-0001-of-base-add-of_parse_phandle_with_optional_args.patch +++ /dev/null @@ -1,58 +0,0 @@ -From c5d264d4b527c96ae8903376a4b195df47b05203 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:43 +0000 -Subject: [PATCH] of: base: add of_parse_phandle_with_optional_args() - -Add a new variant of the of_parse_phandle_with_args() which treats the -cells name as optional. If it's missing, it is assumed that the phandle -has no arguments. - -Up until now, a nvmem node didn't have any arguments, so all the device -trees haven't any '#*-cells' property. But there is a need for an -additional argument for the phandle, for which we need a '#*-cells' -property. Therefore, we need to support nvmem nodes with and without -this property. - -Signed-off-by: Michael Walle -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - include/linux/of.h | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -1011,6 +1011,31 @@ static inline int of_parse_phandle_with_ - } - - /** -+ * of_parse_phandle_with_optional_args() - Find a node pointed by phandle in a list -+ * @np: pointer to a device tree node containing a list -+ * @list_name: property name that contains a list -+ * @cells_name: property name that specifies phandles' arguments count -+ * @index: index of a phandle to parse out -+ * @out_args: optional pointer to output arguments structure (will be filled) -+ * -+ * Same as of_parse_phandle_with_args() except that if the cells_name property -+ * is not found, cell_count of 0 is assumed. -+ * -+ * This is used to useful, if you have a phandle which didn't have arguments -+ * before and thus doesn't have a '#*-cells' property but is now migrated to -+ * having arguments while retaining backwards compatibility. -+ */ -+static inline int of_parse_phandle_with_optional_args(const struct device_node *np, -+ const char *list_name, -+ const char *cells_name, -+ int index, -+ struct of_phandle_args *out_args) -+{ -+ return __of_parse_phandle_with_args(np, list_name, cells_name, -+ 0, index, out_args); -+} -+ -+/** - * of_property_count_u8_elems - Count the number of u8 elements in a property - * - * @np: device node from which the property value is to be read. diff --git a/target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch b/target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch deleted file mode 100644 index 66c29126b6be8e..00000000000000 --- a/target/linux/generic/backport-6.1/827-v6.3-0002-of-property-make-.-cells-optional-for-simple-props.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ff24fed10ba414d19579e26e60b126fad2f2bb07 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:44 +0000 -Subject: [PATCH] of: property: make #.*-cells optional for simple props - -Sometimes, future bindings for phandles will get additional arguments. -Thus the target node of the phandle will need a new #.*-cells property. -To be backwards compatible, this needs to be optional. - -Prepare the DEFINE_SIMPLE_PROPS() to handle the cells name as optional. - -Signed-off-by: Michael Walle -Tested-by: Miquel Raynal -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-11-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/property.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/of/property.c -+++ b/drivers/of/property.c -@@ -1146,8 +1146,8 @@ static struct device_node *parse_prop_ce - if (strcmp(prop_name, list_name)) - return NULL; - -- if (of_parse_phandle_with_args(np, list_name, cells_name, index, -- &sup_args)) -+ if (__of_parse_phandle_with_args(np, list_name, cells_name, 0, index, -+ &sup_args)) - return NULL; - - return sup_args.np; diff --git a/target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch b/target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch deleted file mode 100644 index 07354d7da7c003..00000000000000 --- a/target/linux/generic/backport-6.1/827-v6.3-0003-of-property-add-nvmem-cell-cells-property.patch +++ /dev/null @@ -1,30 +0,0 @@ -From e2d8172043d2e50df19fcd59c11e5593de8188d7 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Mon, 6 Feb 2023 13:43:45 +0000 -Subject: [PATCH] of: property: add #nvmem-cell-cells property - -Bindings describe the new '#nvmem-cell-cells' property. Now that the -arguments count property is optional, we just add this property to the -nvmem-cells. - -Signed-off-by: Michael Walle -Tested-by: Miquel Raynal -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230206134356.839737-12-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/property.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/of/property.c -+++ b/drivers/of/property.c -@@ -1251,7 +1251,7 @@ DEFINE_SIMPLE_PROP(dmas, "dmas", "#dma-c - DEFINE_SIMPLE_PROP(power_domains, "power-domains", "#power-domain-cells") - DEFINE_SIMPLE_PROP(hwlocks, "hwlocks", "#hwlock-cells") - DEFINE_SIMPLE_PROP(extcon, "extcon", NULL) --DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", NULL) -+DEFINE_SIMPLE_PROP(nvmem_cells, "nvmem-cells", "#nvmem-cell-cells") - DEFINE_SIMPLE_PROP(phys, "phys", "#phy-cells") - DEFINE_SIMPLE_PROP(wakeup_parent, "wakeup-parent", NULL) - DEFINE_SIMPLE_PROP(pinctrl0, "pinctrl-0", NULL) diff --git a/target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch b/target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch deleted file mode 100644 index 8dc370618e6bce..00000000000000 --- a/target/linux/generic/backport-6.1/827-v6.3-0004-of-device-Ignore-modalias-of-reused-nodes.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 553bd29700145e1849698985e9800f14e967da49 Mon Sep 17 00:00:00 2001 -From: Alexander Stein -Date: Tue, 7 Feb 2023 12:05:29 +0100 -Subject: [PATCH] of: device: Ignore modalias of reused nodes - -If of_node is reused, do not use that node's modalias. This will hide -the name of the actual device. This is rather prominent in USB glue -drivers creating a platform device for the host controller. - -Signed-off-by: Alexander Stein -Reviewed-by: Rob Herring -Link: https://lore.kernel.org/r/20230207110531.1060252-2-alexander.stein@ew.tq-group.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/device.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -256,7 +256,7 @@ static ssize_t of_device_get_modalias(st - ssize_t csize; - ssize_t tsize; - -- if ((!dev) || (!dev->of_node)) -+ if ((!dev) || (!dev->of_node) || dev->of_node_reused) - return -ENODEV; - - /* Name & Type */ -@@ -379,7 +379,7 @@ int of_device_uevent_modalias(struct dev - { - int sl; - -- if ((!dev) || (!dev->of_node)) -+ if ((!dev) || (!dev->of_node) || dev->of_node_reused) - return -ENODEV; - - /* Devicetree modalias is tricky, we add it in 2 steps */ diff --git a/target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch b/target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch deleted file mode 100644 index dcdc2313ba6ab3..00000000000000 --- a/target/linux/generic/backport-6.1/827-v6.3-0005-of-device-Do-not-ignore-error-code-in-of_device_ueve.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 2295bed9bebe8d1eef276194fed5b5fbe89c5363 Mon Sep 17 00:00:00 2001 -From: Alexander Stein -Date: Tue, 7 Feb 2023 12:05:30 +0100 -Subject: [PATCH] of: device: Do not ignore error code in - of_device_uevent_modalias - -of_device_get_modalias might return an error code, propagate that one. -Otherwise the negative, signed integer is propagated to unsigned integer -for the comparison resulting in a huge 'sl' size. - -Signed-off-by: Alexander Stein -Reviewed-by: Rob Herring -Link: https://lore.kernel.org/r/20230207110531.1060252-3-alexander.stein@ew.tq-group.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/device.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -388,6 +388,8 @@ int of_device_uevent_modalias(struct dev - - sl = of_device_get_modalias(dev, &env->buf[env->buflen-1], - sizeof(env->buf) - env->buflen); -+ if (sl < 0) -+ return sl; - if (sl >= (sizeof(env->buf) - env->buflen)) - return -ENOMEM; - env->buflen += sl; diff --git a/target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch b/target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch deleted file mode 100644 index 280ed9085c7a80..00000000000000 --- a/target/linux/generic/backport-6.1/828-v6.4-0002-of-Update-of_device_get_modalias.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 5c3d15e127ebfc0754cd18def7124633b6d46672 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:15 +0100 -Subject: [PATCH] of: Update of_device_get_modalias() - -This function only needs a "struct device_node" to work, but for -convenience the author (and only user) of this helper did use a "struct -device" and put it in device.c. - -Let's convert this helper to take a "struct device node" instead. This -change asks for two additional changes: renaming it "of_modalias()" -to fit the current naming, and moving it outside of device.c which will -be done in a follow-up commit. - -Signed-off-by: Miquel Raynal -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/device.c | 29 +++++++++++++++++------------ - 1 file changed, 17 insertions(+), 12 deletions(-) - ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -248,7 +248,7 @@ const void *of_device_get_match_data(con - } - EXPORT_SYMBOL(of_device_get_match_data); - --static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) -+static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) - { - const char *compat; - char *c; -@@ -256,19 +256,16 @@ static ssize_t of_device_get_modalias(st - ssize_t csize; - ssize_t tsize; - -- if ((!dev) || (!dev->of_node) || dev->of_node_reused) -- return -ENODEV; -- - /* Name & Type */ - /* %p eats all alphanum characters, so %c must be used here */ -- csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T', -- of_node_get_device_type(dev->of_node)); -+ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', -+ of_node_get_device_type(np)); - tsize = csize; - len -= csize; - if (str) - str += csize; - -- of_property_for_each_string(dev->of_node, "compatible", p, compat) { -+ of_property_for_each_string(np, "compatible", p, compat) { - csize = strlen(compat) + 1; - tsize += csize; - if (csize > len) -@@ -293,7 +290,10 @@ int of_device_request_module(struct devi - ssize_t size; - int ret; - -- size = of_device_get_modalias(dev, NULL, 0); -+ if (!dev || !dev->of_node) -+ return -ENODEV; -+ -+ size = of_modalias(dev->of_node, NULL, 0); - if (size < 0) - return size; - -@@ -304,7 +304,7 @@ int of_device_request_module(struct devi - if (!str) - return -ENOMEM; - -- of_device_get_modalias(dev, str, size); -+ of_modalias(dev->of_node, str, size); - str[size - 1] = '\0'; - ret = request_module(str); - kfree(str); -@@ -321,7 +321,12 @@ EXPORT_SYMBOL_GPL(of_device_request_modu - */ - ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len) - { -- ssize_t sl = of_device_get_modalias(dev, str, len - 2); -+ ssize_t sl; -+ -+ if (!dev || !dev->of_node || dev->of_node_reused) -+ return -ENODEV; -+ -+ sl = of_modalias(dev->of_node, str, len - 2); - if (sl < 0) - return sl; - if (sl > len - 2) -@@ -386,8 +391,8 @@ int of_device_uevent_modalias(struct dev - if (add_uevent_var(env, "MODALIAS=")) - return -ENOMEM; - -- sl = of_device_get_modalias(dev, &env->buf[env->buflen-1], -- sizeof(env->buf) - env->buflen); -+ sl = of_modalias(dev->of_node, &env->buf[env->buflen-1], -+ sizeof(env->buf) - env->buflen); - if (sl < 0) - return sl; - if (sl >= (sizeof(env->buf) - env->buflen)) diff --git a/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch b/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch deleted file mode 100644 index 69d316b8fa3ce7..00000000000000 --- a/target/linux/generic/backport-6.1/828-v6.4-0003-of-Rename-of_modalias_node.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 673aa1ed1c9b6710bf24e3f0957d85e2f46c77db Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:16 +0100 -Subject: [PATCH] of: Rename of_modalias_node() - -This helper does not produce a real modalias, but tries to get the -"product" compatible part of the "vendor,product" compatibles only. It -is far from creating a purely useful modalias string and does not seem -to be used like that directly anyway, so let's try to give this helper a -more meaningful name before moving there a real modalias helper (already -existing under of/device.c). - -Also update the various documentations to refer to the strings as -"aliases" rather than "modaliases" which has a real meaning in the Linux -kernel. - -There is no functional change. - -Cc: Rafael J. Wysocki -Cc: Len Brown -Cc: Maarten Lankhorst -Cc: Maxime Ripard -Cc: Thomas Zimmermann -Cc: Sebastian Reichel -Cc: Wolfram Sang -Cc: Mark Brown -Signed-off-by: Miquel Raynal -Reviewed-by: Rob Herring -Acked-by: Mark Brown -Signed-off-by: Srinivas Kandagatla -Acked-by: Sebastian Reichel -Link: https://lore.kernel.org/r/20230404172148.82422-9-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/acpi/bus.c | 7 ++++--- - drivers/gpu/drm/drm_mipi_dsi.c | 2 +- - drivers/hsi/hsi_core.c | 2 +- - drivers/i2c/busses/i2c-powermac.c | 2 +- - drivers/i2c/i2c-core-of.c | 2 +- - drivers/of/base.c | 18 +++++++++++------- - drivers/spi/spi.c | 4 ++-- - include/linux/of.h | 3 ++- - 8 files changed, 23 insertions(+), 17 deletions(-) - ---- a/drivers/acpi/bus.c -+++ b/drivers/acpi/bus.c -@@ -806,9 +806,10 @@ static bool acpi_of_modalias(struct acpi - * @modalias: Pointer to buffer that modalias value will be copied into - * @len: Length of modalias buffer - * -- * This is a counterpart of of_modalias_node() for struct acpi_device objects. -- * If there is a compatible string for @adev, it will be copied to @modalias -- * with the vendor prefix stripped; otherwise, @default_id will be used. -+ * This is a counterpart of of_alias_from_compatible() for struct acpi_device -+ * objects. If there is a compatible string for @adev, it will be copied to -+ * @modalias with the vendor prefix stripped; otherwise, @default_id will be -+ * used. - */ - void acpi_set_modalias(struct acpi_device *adev, const char *default_id, - char *modalias, size_t len) ---- a/drivers/gpu/drm/drm_mipi_dsi.c -+++ b/drivers/gpu/drm/drm_mipi_dsi.c -@@ -160,7 +160,7 @@ of_mipi_dsi_device_add(struct mipi_dsi_h - int ret; - u32 reg; - -- if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { -+ if (of_alias_from_compatible(node, info.type, sizeof(info.type)) < 0) { - drm_err(host, "modalias failure on %pOF\n", node); - return ERR_PTR(-EINVAL); - } ---- a/drivers/hsi/hsi_core.c -+++ b/drivers/hsi/hsi_core.c -@@ -207,7 +207,7 @@ static void hsi_add_client_from_dt(struc - if (!cl) - return; - -- err = of_modalias_node(client, name, sizeof(name)); -+ err = of_alias_from_compatible(client, name, sizeof(name)); - if (err) - goto err; - ---- a/drivers/i2c/busses/i2c-powermac.c -+++ b/drivers/i2c/busses/i2c-powermac.c -@@ -284,7 +284,7 @@ static bool i2c_powermac_get_type(struct - */ - - /* First try proper modalias */ -- if (of_modalias_node(node, tmp, sizeof(tmp)) >= 0) { -+ if (of_alias_from_compatible(node, tmp, sizeof(tmp)) >= 0) { - snprintf(type, type_size, "MAC,%s", tmp); - return true; - } ---- a/drivers/i2c/i2c-core-of.c -+++ b/drivers/i2c/i2c-core-of.c -@@ -27,7 +27,7 @@ int of_i2c_get_board_info(struct device - - memset(info, 0, sizeof(*info)); - -- if (of_modalias_node(node, info->type, sizeof(info->type)) < 0) { -+ if (of_alias_from_compatible(node, info->type, sizeof(info->type)) < 0) { - dev_err(dev, "of_i2c: modalias failure on %pOF\n", node); - return -EINVAL; - } ---- a/drivers/of/base.c -+++ b/drivers/of/base.c -@@ -1208,19 +1208,23 @@ struct device_node *of_find_matching_nod - EXPORT_SYMBOL(of_find_matching_node_and_match); - - /** -- * of_modalias_node - Lookup appropriate modalias for a device node -+ * of_alias_from_compatible - Lookup appropriate alias for a device node -+ * depending on compatible - * @node: pointer to a device tree node -- * @modalias: Pointer to buffer that modalias value will be copied into -- * @len: Length of modalias value -+ * @alias: Pointer to buffer that alias value will be copied into -+ * @len: Length of alias value - * - * Based on the value of the compatible property, this routine will attempt -- * to choose an appropriate modalias value for a particular device tree node. -+ * to choose an appropriate alias value for a particular device tree node. - * It does this by stripping the manufacturer prefix (as delimited by a ',') - * from the first entry in the compatible list property. - * -+ * Note: The matching on just the "product" side of the compatible is a relic -+ * from I2C and SPI. Please do not add any new user. -+ * - * Return: This routine returns 0 on success, <0 on failure. - */ --int of_modalias_node(struct device_node *node, char *modalias, int len) -+int of_alias_from_compatible(const struct device_node *node, char *alias, int len) - { - const char *compatible, *p; - int cplen; -@@ -1229,10 +1233,10 @@ int of_modalias_node(struct device_node - if (!compatible || strlen(compatible) > cplen) - return -ENODEV; - p = strchr(compatible, ','); -- strscpy(modalias, p ? p + 1 : compatible, len); -+ strscpy(alias, p ? p + 1 : compatible, len); - return 0; - } --EXPORT_SYMBOL_GPL(of_modalias_node); -+EXPORT_SYMBOL_GPL(of_alias_from_compatible); - - /** - * of_find_node_by_phandle - Find a node given a phandle ---- a/drivers/spi/spi.c -+++ b/drivers/spi/spi.c -@@ -2334,8 +2334,8 @@ of_register_spi_device(struct spi_contro - } - - /* Select device driver */ -- rc = of_modalias_node(nc, spi->modalias, -- sizeof(spi->modalias)); -+ rc = of_alias_from_compatible(nc, spi->modalias, -+ sizeof(spi->modalias)); - if (rc < 0) { - dev_err(&ctlr->dev, "cannot find modalias for %pOF\n", nc); - goto err_out; ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -364,7 +364,8 @@ extern int of_n_addr_cells(struct device - extern int of_n_size_cells(struct device_node *np); - extern const struct of_device_id *of_match_node( - const struct of_device_id *matches, const struct device_node *node); --extern int of_modalias_node(struct device_node *node, char *modalias, int len); -+extern int of_alias_from_compatible(const struct device_node *node, char *alias, -+ int len); - extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args); - extern int __of_parse_phandle_with_args(const struct device_node *np, - const char *list_name, const char *cells_name, int cell_count, diff --git a/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch b/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch deleted file mode 100644 index 16baed118750e7..00000000000000 --- a/target/linux/generic/backport-6.1/828-v6.4-0004-of-Move-of_modalias-to-module.c.patch +++ /dev/null @@ -1,160 +0,0 @@ -From bd7a7ed774afd1a4174df34227626c95573be517 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:17 +0100 -Subject: [PATCH] of: Move of_modalias() to module.c - -Create a specific .c file for OF related module handling. -Move of_modalias() inside as a first step. - -The helper is exposed through of.h even though it is only used by core -files because the users from device.c will soon be split into an OF-only -helper in module.c as well as a device-oriented inline helper in -of_device.h. Putting this helper in of_private.h would require to -include of_private.h from of_device.h, which is not acceptable. - -Suggested-by: Rob Herring -Signed-off-by: Miquel Raynal -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/Makefile | 2 +- - drivers/of/device.c | 37 ------------------------------------- - drivers/of/module.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ - include/linux/of.h | 9 +++++++++ - 4 files changed, 54 insertions(+), 38 deletions(-) - create mode 100644 drivers/of/module.c - ---- a/drivers/of/Makefile -+++ b/drivers/of/Makefile -@@ -1,5 +1,5 @@ - # SPDX-License-Identifier: GPL-2.0 --obj-y = base.o device.o platform.o property.o -+obj-y = base.o device.o module.o platform.o property.o - obj-$(CONFIG_OF_KOBJ) += kobj.o - obj-$(CONFIG_OF_DYNAMIC) += dynamic.o - obj-$(CONFIG_OF_FLATTREE) += fdt.o ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -1,5 +1,4 @@ - // SPDX-License-Identifier: GPL-2.0 --#include - #include - #include - #include -@@ -248,42 +247,6 @@ const void *of_device_get_match_data(con - } - EXPORT_SYMBOL(of_device_get_match_data); - --static ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) --{ -- const char *compat; -- char *c; -- struct property *p; -- ssize_t csize; -- ssize_t tsize; -- -- /* Name & Type */ -- /* %p eats all alphanum characters, so %c must be used here */ -- csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', -- of_node_get_device_type(np)); -- tsize = csize; -- len -= csize; -- if (str) -- str += csize; -- -- of_property_for_each_string(np, "compatible", p, compat) { -- csize = strlen(compat) + 1; -- tsize += csize; -- if (csize > len) -- continue; -- -- csize = snprintf(str, len, "C%s", compat); -- for (c = str; c; ) { -- c = strchr(c, ' '); -- if (c) -- *c++ = '_'; -- } -- len -= csize; -- str += csize; -- } -- -- return tsize; --} -- - int of_device_request_module(struct device *dev) - { - char *str; ---- /dev/null -+++ b/drivers/of/module.c -@@ -0,0 +1,44 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Linux kernel module helpers. -+ */ -+ -+#include -+#include -+#include -+ -+ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len) -+{ -+ const char *compat; -+ char *c; -+ struct property *p; -+ ssize_t csize; -+ ssize_t tsize; -+ -+ /* Name & Type */ -+ /* %p eats all alphanum characters, so %c must be used here */ -+ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', -+ of_node_get_device_type(np)); -+ tsize = csize; -+ len -= csize; -+ if (str) -+ str += csize; -+ -+ of_property_for_each_string(np, "compatible", p, compat) { -+ csize = strlen(compat) + 1; -+ tsize += csize; -+ if (csize > len) -+ continue; -+ -+ csize = snprintf(str, len, "C%s", compat); -+ for (c = str; c; ) { -+ c = strchr(c, ' '); -+ if (c) -+ *c++ = '_'; -+ } -+ len -= csize; -+ str += csize; -+ } -+ -+ return tsize; -+} ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -376,6 +376,9 @@ extern int of_parse_phandle_with_args_ma - extern int of_count_phandle_with_args(const struct device_node *np, - const char *list_name, const char *cells_name); - -+/* module functions */ -+extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len); -+ - /* phandle iterator functions */ - extern int of_phandle_iterator_init(struct of_phandle_iterator *it, - const struct device_node *np, -@@ -733,6 +736,12 @@ static inline int of_count_phandle_with_ - return -ENOSYS; - } - -+static inline ssize_t of_modalias(const struct device_node *np, char *str, -+ ssize_t len) -+{ -+ return -ENODEV; -+} -+ - static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, - const struct device_node *np, - const char *list_name, diff --git a/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch b/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch deleted file mode 100644 index 67dcea0d19d0fc..00000000000000 --- a/target/linux/generic/backport-6.1/828-v6.4-0005-of-Move-the-request-module-helper-logic-to-module.c.patch +++ /dev/null @@ -1,131 +0,0 @@ -From e6506f06d5e82765666902ccf9e9162f3e31d518 Mon Sep 17 00:00:00 2001 -From: Miquel Raynal -Date: Tue, 4 Apr 2023 18:21:18 +0100 -Subject: [PATCH] of: Move the request module helper logic to module.c - -Depending on device.c for pure OF handling is considered -backwards. Let's extract the content of of_device_request_module() to -have the real logic under module.c. - -The next step will be to convert users of of_device_request_module() to -use the new helper. - -Signed-off-by: Miquel Raynal -Reviewed-by: Rob Herring -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20230404172148.82422-11-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/of/device.c | 25 ++----------------------- - drivers/of/module.c | 30 ++++++++++++++++++++++++++++++ - include/linux/of.h | 6 ++++++ - 3 files changed, 38 insertions(+), 23 deletions(-) - ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -8,7 +8,6 @@ - #include /* for bus_dma_region */ - #include - #include --#include - #include - #include - #include -@@ -249,30 +248,10 @@ EXPORT_SYMBOL(of_device_get_match_data); - - int of_device_request_module(struct device *dev) - { -- char *str; -- ssize_t size; -- int ret; -- -- if (!dev || !dev->of_node) -+ if (!dev) - return -ENODEV; - -- size = of_modalias(dev->of_node, NULL, 0); -- if (size < 0) -- return size; -- -- /* Reserve an additional byte for the trailing '\0' */ -- size++; -- -- str = kmalloc(size, GFP_KERNEL); -- if (!str) -- return -ENOMEM; -- -- of_modalias(dev->of_node, str, size); -- str[size - 1] = '\0'; -- ret = request_module(str); -- kfree(str); -- -- return ret; -+ return of_request_module(dev->of_node); - } - EXPORT_SYMBOL_GPL(of_device_request_module); - ---- a/drivers/of/module.c -+++ b/drivers/of/module.c -@@ -4,6 +4,7 @@ - */ - - #include -+#include - #include - #include - -@@ -42,3 +43,32 @@ ssize_t of_modalias(const struct device_ - - return tsize; - } -+ -+int of_request_module(const struct device_node *np) -+{ -+ char *str; -+ ssize_t size; -+ int ret; -+ -+ if (!np) -+ return -ENODEV; -+ -+ size = of_modalias(np, NULL, 0); -+ if (size < 0) -+ return size; -+ -+ /* Reserve an additional byte for the trailing '\0' */ -+ size++; -+ -+ str = kmalloc(size, GFP_KERNEL); -+ if (!str) -+ return -ENOMEM; -+ -+ of_modalias(np, str, size); -+ str[size - 1] = '\0'; -+ ret = request_module(str); -+ kfree(str); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(of_request_module); ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -378,6 +378,7 @@ extern int of_count_phandle_with_args(co - - /* module functions */ - extern ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len); -+extern int of_request_module(const struct device_node *np); - - /* phandle iterator functions */ - extern int of_phandle_iterator_init(struct of_phandle_iterator *it, -@@ -741,6 +742,11 @@ static inline ssize_t of_modalias(const - { - return -ENODEV; - } -+ -+static inline int of_request_module(const struct device_node *np) -+{ -+ return -ENODEV; -+} - - static inline int of_phandle_iterator_init(struct of_phandle_iterator *it, - const struct device_node *np, diff --git a/target/linux/generic/backport-6.1/829-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch b/target/linux/generic/backport-6.1/829-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch deleted file mode 100644 index c15b4b2265e73a..00000000000000 --- a/target/linux/generic/backport-6.1/829-v6.10-0001-nvmem-layouts-store-owner-from-modules-with-nvmem_la.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 6d0ca4a2a7e25f9ad07c1f335f20b4d9e048cdd5 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Apr 2024 09:49:11 +0100 -Subject: [PATCH] nvmem: layouts: store owner from modules with - nvmem_layout_driver_register() - -Modules registering driver with nvmem_layout_driver_register() might -forget to set .owner field. The field is used by some of other kernel -parts for reference counting (try_module_get()), so it is expected that -drivers will set it. - -Solve the problem by moving this task away from the drivers to the core -code, just like we did for platform_driver in -commit 9447057eaff8 ("platform_device: use a macro instead of -platform_driver_register"). - -Signed-off-by: Krzysztof Kozlowski -Reviewed-by: Michael Walle -Reviewed-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts.c | 6 ++++-- - include/linux/nvmem-provider.h | 5 ++++- - 2 files changed, 8 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/layouts.c -+++ b/drivers/nvmem/layouts.c -@@ -52,13 +52,15 @@ static struct bus_type nvmem_layout_bus_ - .remove = nvmem_layout_bus_remove, - }; - --int nvmem_layout_driver_register(struct nvmem_layout_driver *drv) -+int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv, -+ struct module *owner) - { - drv->driver.bus = &nvmem_layout_bus_type; -+ drv->driver.owner = owner; - - return driver_register(&drv->driver); - } --EXPORT_SYMBOL_GPL(nvmem_layout_driver_register); -+EXPORT_SYMBOL_GPL(__nvmem_layout_driver_register); - - void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv) - { ---- a/include/linux/nvmem-provider.h -+++ b/include/linux/nvmem-provider.h -@@ -199,7 +199,10 @@ int nvmem_add_one_cell(struct nvmem_devi - int nvmem_layout_register(struct nvmem_layout *layout); - void nvmem_layout_unregister(struct nvmem_layout *layout); - --int nvmem_layout_driver_register(struct nvmem_layout_driver *drv); -+#define nvmem_layout_driver_register(drv) \ -+ __nvmem_layout_driver_register(drv, THIS_MODULE) -+int __nvmem_layout_driver_register(struct nvmem_layout_driver *drv, -+ struct module *owner); - void nvmem_layout_driver_unregister(struct nvmem_layout_driver *drv); - #define module_nvmem_layout_driver(__nvmem_layout_driver) \ - module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \ diff --git a/target/linux/generic/backport-6.1/829-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch b/target/linux/generic/backport-6.1/829-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch deleted file mode 100644 index b483dd243b94b3..00000000000000 --- a/target/linux/generic/backport-6.1/829-v6.10-0002-nvmem-layouts-onie-tlv-drop-driver-owner-initializat.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 21833338eccb91194fec6ba7548d9c454824eca0 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Apr 2024 09:49:12 +0100 -Subject: [PATCH] nvmem: layouts: onie-tlv: drop driver owner initialization - -Core in nvmem_layout_driver_register() already sets the .owner, so -driver does not need to. - -Signed-off-by: Krzysztof Kozlowski -Reviewed-by: Michael Walle -Acked-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/onie-tlv.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/nvmem/layouts/onie-tlv.c -+++ b/drivers/nvmem/layouts/onie-tlv.c -@@ -247,7 +247,6 @@ MODULE_DEVICE_TABLE(of, onie_tlv_of_matc - - static struct nvmem_layout_driver onie_tlv_layout = { - .driver = { -- .owner = THIS_MODULE, - .name = "onie-tlv-layout", - .of_match_table = onie_tlv_of_match_table, - }, diff --git a/target/linux/generic/backport-6.1/829-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch b/target/linux/generic/backport-6.1/829-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch deleted file mode 100644 index 472a65feca0c54..00000000000000 --- a/target/linux/generic/backport-6.1/829-v6.10-0003-nvmem-layouts-sl28vpd-drop-driver-owner-initializati.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 23fd602f21953c03c0714257d36685cd6b486f04 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Apr 2024 09:49:13 +0100 -Subject: [PATCH] nvmem: layouts: sl28vpd: drop driver owner initialization - -Core in nvmem_layout_driver_register() already sets the .owner, so -driver does not need to. - -Signed-off-by: Krzysztof Kozlowski -Reviewed-by: Michael Walle -Reviewed-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/layouts/sl28vpd.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/nvmem/layouts/sl28vpd.c -+++ b/drivers/nvmem/layouts/sl28vpd.c -@@ -156,7 +156,6 @@ MODULE_DEVICE_TABLE(of, sl28vpd_of_match - - static struct nvmem_layout_driver sl28vpd_layout = { - .driver = { -- .owner = THIS_MODULE, - .name = "kontron-sl28vpd-layout", - .of_match_table = sl28vpd_of_match_table, - }, diff --git a/target/linux/generic/backport-6.1/829-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch b/target/linux/generic/backport-6.1/829-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch deleted file mode 100644 index 2aa13a5c6463b3..00000000000000 --- a/target/linux/generic/backport-6.1/829-v6.10-0004-nvmem-sc27xx-fix-module-autoloading.patch +++ /dev/null @@ -1,26 +0,0 @@ -From dc3d88ade857ba3dca34f008e0b0aed3ef79cb15 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Apr 2024 09:49:14 +0100 -Subject: [PATCH] nvmem: sc27xx: fix module autoloading - -Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded -based on the alias from of_device_id table. - -Signed-off-by: Krzysztof Kozlowski -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sc27xx-efuse.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/sc27xx-efuse.c -+++ b/drivers/nvmem/sc27xx-efuse.c -@@ -263,6 +263,7 @@ static const struct of_device_id sc27xx_ - { .compatible = "sprd,sc2730-efuse", .data = &sc2730_edata}, - { } - }; -+MODULE_DEVICE_TABLE(of, sc27xx_efuse_of_match); - - static struct platform_driver sc27xx_efuse_driver = { - .probe = sc27xx_efuse_probe, diff --git a/target/linux/generic/backport-6.1/829-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch b/target/linux/generic/backport-6.1/829-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch deleted file mode 100644 index 0953c92340c320..00000000000000 --- a/target/linux/generic/backport-6.1/829-v6.10-0005-nvmem-sprd-fix-module-autoloading.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 154c1ec943e34f3188c9305b0c91d5e7dc1373b8 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Apr 2024 09:49:15 +0100 -Subject: [PATCH] nvmem: sprd: fix module autoloading - -Add MODULE_DEVICE_TABLE(), so the module could be properly autoloaded -based on the alias from of_device_id table. - -Signed-off-by: Krzysztof Kozlowski -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sprd-efuse.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/sprd-efuse.c -+++ b/drivers/nvmem/sprd-efuse.c -@@ -426,6 +426,7 @@ static const struct of_device_id sprd_ef - { .compatible = "sprd,ums312-efuse", .data = &ums312_data }, - { } - }; -+MODULE_DEVICE_TABLE(of, sprd_efuse_of_match); - - static struct platform_driver sprd_efuse_driver = { - .probe = sprd_efuse_probe, diff --git a/target/linux/generic/backport-6.1/829-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch b/target/linux/generic/backport-6.1/829-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch deleted file mode 100644 index 4de97af6acbe82..00000000000000 --- a/target/linux/generic/backport-6.1/829-v6.10-0006-nvmem-core-switch-to-use-device_add_groups.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 8d8fc146dd7a0d6a6b37695747a524310dfb9d57 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Tue, 30 Apr 2024 09:49:16 +0100 -Subject: [PATCH] nvmem: core: switch to use device_add_groups() - -devm_device_add_groups() is being removed from the kernel, so move the -nvmem driver to use device_add_groups() instead. The logic is -identical, when the device is removed the driver core will properly -clean up and remove the groups, and the memory used by the attribute -groups will be freed because it was created with dev_* calls, so this is -functionally identical overall. - -Cc: Srinivas Kandagatla -Signed-off-by: Srinivas Kandagatla -Signed-off-by: Greg Kroah-Hartman -Link: https://lore.kernel.org/r/20240430084921.33387-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -477,7 +477,7 @@ static int nvmem_populate_sysfs_cells(st - - nvmem_cells_group.bin_attrs = cells_attrs; - -- ret = devm_device_add_groups(&nvmem->dev, nvmem_cells_groups); -+ ret = device_add_groups(&nvmem->dev, nvmem_cells_groups); - if (ret) - goto unlock_mutex; - diff --git a/target/linux/generic/backport-6.1/829-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch b/target/linux/generic/backport-6.1/829-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch deleted file mode 100644 index 27d9270d31ee39..00000000000000 --- a/target/linux/generic/backport-6.1/829-v6.10-0007-nvmem-lpc18xx_eeprom-Convert-to-platform-remove-call.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 693d2f629962628ddefc88f4b6b453edda5ac32e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= -Date: Tue, 30 Apr 2024 09:49:17 +0100 -Subject: [PATCH] nvmem: lpc18xx_eeprom: Convert to platform remove callback - returning void -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The .remove() callback for a platform driver returns an int which makes -many driver authors wrongly assume it's possible to do error handling by -returning an error code. However the value returned is ignored (apart -from emitting a warning) and this typically results in resource leaks. - -To improve here there is a quest to make the remove callback return -void. In the first step of this quest all drivers are converted to -.remove_new(), which already returns void. Eventually after all drivers -are converted, .remove_new() will be renamed to .remove(). - -Trivially convert this driver from always returning zero in the remove -callback to the void returning variant. - -Signed-off-by: Uwe Kleine-König -Acked-by: Vladimir Zapolskiy -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/lpc18xx_eeprom.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/drivers/nvmem/lpc18xx_eeprom.c -+++ b/drivers/nvmem/lpc18xx_eeprom.c -@@ -249,13 +249,11 @@ err_clk: - return ret; - } - --static int lpc18xx_eeprom_remove(struct platform_device *pdev) -+static void lpc18xx_eeprom_remove(struct platform_device *pdev) - { - struct lpc18xx_eeprom_dev *eeprom = platform_get_drvdata(pdev); - - clk_disable_unprepare(eeprom->clk); -- -- return 0; - } - - static const struct of_device_id lpc18xx_eeprom_of_match[] = { -@@ -266,7 +264,7 @@ MODULE_DEVICE_TABLE(of, lpc18xx_eeprom_o - - static struct platform_driver lpc18xx_eeprom_driver = { - .probe = lpc18xx_eeprom_probe, -- .remove = lpc18xx_eeprom_remove, -+ .remove_new = lpc18xx_eeprom_remove, - .driver = { - .name = "lpc18xx-eeprom", - .of_match_table = lpc18xx_eeprom_of_match, diff --git a/target/linux/generic/backport-6.1/829-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch b/target/linux/generic/backport-6.1/829-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch deleted file mode 100644 index 7770052d97d6cf..00000000000000 --- a/target/linux/generic/backport-6.1/829-v6.10-0008-nvmem-meson-mx-efuse-Remove-nvmem_device-from-efuse-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 2a1ad6b75292d38aa2f6ded7335979e0632521da Mon Sep 17 00:00:00 2001 -From: Mukesh Ojha -Date: Tue, 30 Apr 2024 09:49:21 +0100 -Subject: [PATCH] nvmem: meson-mx-efuse: Remove nvmem_device from efuse struct - -nvmem_device is used at one place while registering nvmem -device and it is not required to be present in efuse struct -for just this purpose. - -Drop nvmem_device and manage with nvmem device stack variable. - -Signed-off-by: Mukesh Ojha -Reviewed-by: Martin Blumenstingl -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240430084921.33387-12-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/meson-mx-efuse.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/meson-mx-efuse.c -+++ b/drivers/nvmem/meson-mx-efuse.c -@@ -44,7 +44,6 @@ struct meson_mx_efuse_platform_data { - struct meson_mx_efuse { - void __iomem *base; - struct clk *core_clk; -- struct nvmem_device *nvmem; - struct nvmem_config config; - }; - -@@ -194,6 +193,7 @@ static int meson_mx_efuse_probe(struct p - { - const struct meson_mx_efuse_platform_data *drvdata; - struct meson_mx_efuse *efuse; -+ struct nvmem_device *nvmem; - - drvdata = of_device_get_match_data(&pdev->dev); - if (!drvdata) -@@ -224,9 +224,9 @@ static int meson_mx_efuse_probe(struct p - return PTR_ERR(efuse->core_clk); - } - -- efuse->nvmem = devm_nvmem_register(&pdev->dev, &efuse->config); -+ nvmem = devm_nvmem_register(&pdev->dev, &efuse->config); - -- return PTR_ERR_OR_ZERO(efuse->nvmem); -+ return PTR_ERR_OR_ZERO(nvmem); - } - - static struct platform_driver meson_mx_efuse_driver = { diff --git a/target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch b/target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch deleted file mode 100644 index 3319f431baccac..00000000000000 --- a/target/linux/generic/backport-6.1/830-00-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 77faa07c185c969e742cbb3e6aa487a11b0b616c Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Tue, 30 Aug 2022 09:57:42 +0300 -Subject: [PATCH] dt-bindings: arm: qcom: document qcom,msm-id and - qcom,board-id - -The top level qcom,msm-id and qcom,board-id properties are utilized by -bootloaders on Qualcomm MSM platforms to determine which device tree -should be used and passed to the kernel. - -The commit b32e592d3c28 ("devicetree: bindings: Document qcom board -compatible format") from 2015 was a consensus during discussion about -upstreaming qcom,msm-id and qcom,board-id fields. There are however still -problems with that consensus: -1. It was reached 7 years ago but it turned out its implementation did - not reach all possible products. - -2. Initially additional tool (dtbTool) was needed for parsing these - fields to create a QCDT image consisting of multiple DTBs, later the - bootloaders were improved and they use these qcom,msm-id and - qcom,board-id properties directly. - -3. Extracting relevant information from the board compatible requires - this additional tool (dtbTool), which makes the build process more - complicated and not easily reproducible (DTBs are modified after the - kernel build). - -4. Some versions of Qualcomm bootloaders expect these properties even - when booting with a single DTB. The community is stuck with these - bootloaders thus they require properties in the DTBs. - -Since several upstreamed Qualcomm SoC-based boards require these -properties to properly boot and the properties are reportedly used by -bootloaders, document them along with the bindings header with constants -used by: bootloader, some DTS and socinfo driver. - -Link: https://lore.kernel.org/r/a3c932d1-a102-ce18-deea-18cbbd05ecab@linaro.org/ -Co-developed-by: Kumar Gala -Signed-off-by: Kumar Gala -Signed-off-by: Krzysztof Kozlowski -Reviewed-by: Dmitry Baryshkov -Reviewed-by: Rob Herring -Signed-off-by: Bjorn Andersson -Link: https://lore.kernel.org/r/20220830065744.161163-2-krzysztof.kozlowski@linaro.org ---- - include/dt-bindings/arm/qcom,ids.h | 155 +++++++++++++++++++++++++++++ - 1 file changed, 155 insertions(+) - create mode 100644 include/dt-bindings/arm/qcom,ids.h - ---- /dev/null -+++ b/include/dt-bindings/arm/qcom,ids.h -@@ -0,0 +1,155 @@ -+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ -+/* -+ * Copyright (c) 2015, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2022 Linaro Ltd -+ * Author: Krzysztof Kozlowski based on previous work of Kumar Gala. -+ */ -+#ifndef _DT_BINDINGS_ARM_QCOM_IDS_H -+#define _DT_BINDINGS_ARM_QCOM_IDS_H -+ -+/* -+ * The MSM chipset and hardware revision used by Qualcomm bootloaders, DTS for -+ * older chipsets (qcom,msm-id) and in socinfo driver: -+ */ -+#define QCOM_ID_MSM8960 87 -+#define QCOM_ID_APQ8064 109 -+#define QCOM_ID_MSM8660A 122 -+#define QCOM_ID_MSM8260A 123 -+#define QCOM_ID_APQ8060A 124 -+#define QCOM_ID_MSM8974 126 -+#define QCOM_ID_MPQ8064 130 -+#define QCOM_ID_MSM8960AB 138 -+#define QCOM_ID_APQ8060AB 139 -+#define QCOM_ID_MSM8260AB 140 -+#define QCOM_ID_MSM8660AB 141 -+#define QCOM_ID_MSM8626 145 -+#define QCOM_ID_MSM8610 147 -+#define QCOM_ID_APQ8064AB 153 -+#define QCOM_ID_MSM8226 158 -+#define QCOM_ID_MSM8526 159 -+#define QCOM_ID_MSM8110 161 -+#define QCOM_ID_MSM8210 162 -+#define QCOM_ID_MSM8810 163 -+#define QCOM_ID_MSM8212 164 -+#define QCOM_ID_MSM8612 165 -+#define QCOM_ID_MSM8112 166 -+#define QCOM_ID_MSM8225Q 168 -+#define QCOM_ID_MSM8625Q 169 -+#define QCOM_ID_MSM8125Q 170 -+#define QCOM_ID_APQ8064AA 172 -+#define QCOM_ID_APQ8084 178 -+#define QCOM_ID_APQ8074 184 -+#define QCOM_ID_MSM8274 185 -+#define QCOM_ID_MSM8674 186 -+#define QCOM_ID_MSM8974PRO_AC 194 -+#define QCOM_ID_MSM8126 198 -+#define QCOM_ID_APQ8026 199 -+#define QCOM_ID_MSM8926 200 -+#define QCOM_ID_MSM8326 205 -+#define QCOM_ID_MSM8916 206 -+#define QCOM_ID_MSM8994 207 -+#define QCOM_ID_APQ8074PRO_AA 208 -+#define QCOM_ID_APQ8074PRO_AB 209 -+#define QCOM_ID_APQ8074PRO_AC 210 -+#define QCOM_ID_MSM8274PRO_AA 211 -+#define QCOM_ID_MSM8274PRO_AB 212 -+#define QCOM_ID_MSM8274PRO_AC 213 -+#define QCOM_ID_MSM8674PRO_AA 214 -+#define QCOM_ID_MSM8674PRO_AB 215 -+#define QCOM_ID_MSM8674PRO_AC 216 -+#define QCOM_ID_MSM8974PRO_AA 217 -+#define QCOM_ID_MSM8974PRO_AB 218 -+#define QCOM_ID_APQ8028 219 -+#define QCOM_ID_MSM8128 220 -+#define QCOM_ID_MSM8228 221 -+#define QCOM_ID_MSM8528 222 -+#define QCOM_ID_MSM8628 223 -+#define QCOM_ID_MSM8928 224 -+#define QCOM_ID_MSM8510 225 -+#define QCOM_ID_MSM8512 226 -+#define QCOM_ID_MSM8936 233 -+#define QCOM_ID_MSM8939 239 -+#define QCOM_ID_APQ8036 240 -+#define QCOM_ID_APQ8039 241 -+#define QCOM_ID_MSM8996 246 -+#define QCOM_ID_APQ8016 247 -+#define QCOM_ID_MSM8216 248 -+#define QCOM_ID_MSM8116 249 -+#define QCOM_ID_MSM8616 250 -+#define QCOM_ID_MSM8992 251 -+#define QCOM_ID_APQ8094 253 -+#define QCOM_ID_MDM9607 290 -+#define QCOM_ID_APQ8096 291 -+#define QCOM_ID_MSM8998 292 -+#define QCOM_ID_MSM8953 293 -+#define QCOM_ID_MDM8207 296 -+#define QCOM_ID_MDM9207 297 -+#define QCOM_ID_MDM9307 298 -+#define QCOM_ID_MDM9628 299 -+#define QCOM_ID_APQ8053 304 -+#define QCOM_ID_MSM8996SG 305 -+#define QCOM_ID_MSM8996AU 310 -+#define QCOM_ID_APQ8096AU 311 -+#define QCOM_ID_APQ8096SG 312 -+#define QCOM_ID_SDM660 317 -+#define QCOM_ID_SDM630 318 -+#define QCOM_ID_APQ8098 319 -+#define QCOM_ID_SDM845 321 -+#define QCOM_ID_MDM9206 322 -+#define QCOM_ID_IPQ8074 323 -+#define QCOM_ID_SDA660 324 -+#define QCOM_ID_SDM658 325 -+#define QCOM_ID_SDA658 326 -+#define QCOM_ID_SDA630 327 -+#define QCOM_ID_SDM450 338 -+#define QCOM_ID_SDA845 341 -+#define QCOM_ID_IPQ8072 342 -+#define QCOM_ID_IPQ8076 343 -+#define QCOM_ID_IPQ8078 344 -+#define QCOM_ID_SDM636 345 -+#define QCOM_ID_SDA636 346 -+#define QCOM_ID_SDM632 349 -+#define QCOM_ID_SDA632 350 -+#define QCOM_ID_SDA450 351 -+#define QCOM_ID_SM8250 356 -+#define QCOM_ID_IPQ8070 375 -+#define QCOM_ID_IPQ8071 376 -+#define QCOM_ID_IPQ8072A 389 -+#define QCOM_ID_IPQ8074A 390 -+#define QCOM_ID_IPQ8076A 391 -+#define QCOM_ID_IPQ8078A 392 -+#define QCOM_ID_SM6125 394 -+#define QCOM_ID_IPQ8070A 395 -+#define QCOM_ID_IPQ8071A 396 -+#define QCOM_ID_IPQ6018 402 -+#define QCOM_ID_IPQ6028 403 -+#define QCOM_ID_IPQ6000 421 -+#define QCOM_ID_IPQ6010 422 -+#define QCOM_ID_SC7180 425 -+#define QCOM_ID_SM6350 434 -+#define QCOM_ID_SM8350 439 -+#define QCOM_ID_SC8280XP 449 -+#define QCOM_ID_IPQ6005 453 -+#define QCOM_ID_QRB5165 455 -+#define QCOM_ID_SM8450 457 -+#define QCOM_ID_SM7225 459 -+#define QCOM_ID_SA8295P 460 -+#define QCOM_ID_SA8540P 461 -+#define QCOM_ID_SM8450_2 480 -+#define QCOM_ID_SM8450_3 482 -+#define QCOM_ID_SC7280 487 -+#define QCOM_ID_SC7180P 495 -+#define QCOM_ID_SM6375 507 -+ -+/* -+ * The board type and revision information, used by Qualcomm bootloaders and -+ * DTS for older chipsets (qcom,board-id): -+ */ -+#define QCOM_BOARD_ID(a, major, minor) \ -+ (((major & 0xff) << 16) | ((minor & 0xff) << 8) | QCOM_BOARD_ID_##a) -+ -+#define QCOM_BOARD_ID_MTP 8 -+#define QCOM_BOARD_ID_DRAGONBOARD 10 -+#define QCOM_BOARD_ID_SBC 24 -+ -+#endif /* _DT_BINDINGS_ARM_QCOM_IDS_H */ diff --git a/target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch b/target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch deleted file mode 100644 index 394087a27a4d5e..00000000000000 --- a/target/linux/generic/backport-6.1/830-01-v6.5-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 7cbff3c3f867ff3b24de674f44ca03f54e416a37 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sat, 31 Dec 2022 00:27:42 +0100 -Subject: [PATCH] soc: qcom: socinfo: move SMEM item struct and defines to a - header - -Move SMEM item struct and related defines to a header in order to be able -to reuse them in the Qualcomm NVMEM CPUFreq driver instead of duplicating -them. - -Signed-off-by: Robert Marko -Reviewed-by: Konrad Dybcio -Signed-off-by: Bjorn Andersson -Link: https://lore.kernel.org/r/20230526204802.3081168-1-robimarko@gmail.com ---- - drivers/soc/qcom/socinfo.c | 58 +-------------------------- - include/linux/soc/qcom/socinfo.h | 67 ++++++++++++++++++++++++++++++++ - 2 files changed, 68 insertions(+), 57 deletions(-) - create mode 100644 include/linux/soc/qcom/socinfo.h - ---- a/drivers/soc/qcom/socinfo.c -+++ b/drivers/soc/qcom/socinfo.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -25,15 +26,6 @@ - #define SOCINFO_MINOR(ver) ((ver) & 0xffff) - #define SOCINFO_VERSION(maj, min) ((((maj) & 0xffff) << 16)|((min) & 0xffff)) - --#define SMEM_SOCINFO_BUILD_ID_LENGTH 32 --#define SMEM_SOCINFO_CHIP_ID_LENGTH 32 -- --/* -- * SMEM item id, used to acquire handles to respective -- * SMEM region. -- */ --#define SMEM_HW_SW_BUILD_ID 137 -- - #ifdef CONFIG_DEBUG_FS - #define SMEM_IMAGE_VERSION_BLOCKS_COUNT 32 - #define SMEM_IMAGE_VERSION_SIZE 4096 -@@ -116,54 +108,6 @@ static const char *const pmic_models[] = - }; - #endif /* CONFIG_DEBUG_FS */ - --/* Socinfo SMEM item structure */ --struct socinfo { -- __le32 fmt; -- __le32 id; -- __le32 ver; -- char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH]; -- /* Version 2 */ -- __le32 raw_id; -- __le32 raw_ver; -- /* Version 3 */ -- __le32 hw_plat; -- /* Version 4 */ -- __le32 plat_ver; -- /* Version 5 */ -- __le32 accessory_chip; -- /* Version 6 */ -- __le32 hw_plat_subtype; -- /* Version 7 */ -- __le32 pmic_model; -- __le32 pmic_die_rev; -- /* Version 8 */ -- __le32 pmic_model_1; -- __le32 pmic_die_rev_1; -- __le32 pmic_model_2; -- __le32 pmic_die_rev_2; -- /* Version 9 */ -- __le32 foundry_id; -- /* Version 10 */ -- __le32 serial_num; -- /* Version 11 */ -- __le32 num_pmics; -- __le32 pmic_array_offset; -- /* Version 12 */ -- __le32 chip_family; -- __le32 raw_device_family; -- __le32 raw_device_num; -- /* Version 13 */ -- __le32 nproduct_id; -- char chip_id[SMEM_SOCINFO_CHIP_ID_LENGTH]; -- /* Version 14 */ -- __le32 num_clusters; -- __le32 ncluster_array_offset; -- __le32 num_defective_parts; -- __le32 ndefective_parts_array_offset; -- /* Version 15 */ -- __le32 nmodem_supported; --}; -- - #ifdef CONFIG_DEBUG_FS - struct socinfo_params { - u32 raw_device_family; ---- /dev/null -+++ b/include/linux/soc/qcom/socinfo.h -@@ -0,0 +1,67 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved. -+ * Copyright (c) 2017-2019, Linaro Ltd. -+ */ -+ -+#ifndef __QCOM_SOCINFO_H__ -+#define __QCOM_SOCINFO_H__ -+ -+/* -+ * SMEM item id, used to acquire handles to respective -+ * SMEM region. -+ */ -+#define SMEM_HW_SW_BUILD_ID 137 -+ -+#define SMEM_SOCINFO_BUILD_ID_LENGTH 32 -+#define SMEM_SOCINFO_CHIP_ID_LENGTH 32 -+ -+/* Socinfo SMEM item structure */ -+struct socinfo { -+ __le32 fmt; -+ __le32 id; -+ __le32 ver; -+ char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH]; -+ /* Version 2 */ -+ __le32 raw_id; -+ __le32 raw_ver; -+ /* Version 3 */ -+ __le32 hw_plat; -+ /* Version 4 */ -+ __le32 plat_ver; -+ /* Version 5 */ -+ __le32 accessory_chip; -+ /* Version 6 */ -+ __le32 hw_plat_subtype; -+ /* Version 7 */ -+ __le32 pmic_model; -+ __le32 pmic_die_rev; -+ /* Version 8 */ -+ __le32 pmic_model_1; -+ __le32 pmic_die_rev_1; -+ __le32 pmic_model_2; -+ __le32 pmic_die_rev_2; -+ /* Version 9 */ -+ __le32 foundry_id; -+ /* Version 10 */ -+ __le32 serial_num; -+ /* Version 11 */ -+ __le32 num_pmics; -+ __le32 pmic_array_offset; -+ /* Version 12 */ -+ __le32 chip_family; -+ __le32 raw_device_family; -+ __le32 raw_device_num; -+ /* Version 13 */ -+ __le32 nproduct_id; -+ char chip_id[SMEM_SOCINFO_CHIP_ID_LENGTH]; -+ /* Version 14 */ -+ __le32 num_clusters; -+ __le32 ncluster_array_offset; -+ __le32 num_defective_parts; -+ __le32 ndefective_parts_array_offset; -+ /* Version 15 */ -+ __le32 nmodem_supported; -+}; -+ -+#endif diff --git a/target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch b/target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch deleted file mode 100644 index 7c7c3f3635cd89..00000000000000 --- a/target/linux/generic/backport-6.1/830-02-v6.5-soc-qcom-smem-Switch-to-EXPORT_SYMBOL_GPL.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 9f1bbff157a69db7684f5da2f73b2325c638a90e Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 26 May 2023 22:47:59 +0200 -Subject: [PATCH] soc: qcom: smem: Switch to EXPORT_SYMBOL_GPL() - -SMEM has been GPL licensed from the start, and there is no reason to use -EXPORT_SYMBOL() so switch to the GPL version. - -Signed-off-by: Robert Marko -Reviewed-by: Konrad Dybcio -Reviewed-by: Trilok Soni -Signed-off-by: Bjorn Andersson -Link: https://lore.kernel.org/r/20230526204802.3081168-2-robimarko@gmail.com ---- - drivers/soc/qcom/smem.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/soc/qcom/smem.c -+++ b/drivers/soc/qcom/smem.c -@@ -500,7 +500,7 @@ int qcom_smem_alloc(unsigned host, unsig - - return ret; - } --EXPORT_SYMBOL(qcom_smem_alloc); -+EXPORT_SYMBOL_GPL(qcom_smem_alloc); - - static void *qcom_smem_get_global(struct qcom_smem *smem, - unsigned item, -@@ -674,7 +674,7 @@ void *qcom_smem_get(unsigned host, unsig - return ptr; - - } --EXPORT_SYMBOL(qcom_smem_get); -+EXPORT_SYMBOL_GPL(qcom_smem_get); - - /** - * qcom_smem_get_free_space() - retrieve amount of free space in a partition -@@ -719,7 +719,7 @@ int qcom_smem_get_free_space(unsigned ho - - return ret; - } --EXPORT_SYMBOL(qcom_smem_get_free_space); -+EXPORT_SYMBOL_GPL(qcom_smem_get_free_space); - - static bool addr_in_range(void __iomem *base, size_t size, void *addr) - { -@@ -770,7 +770,7 @@ phys_addr_t qcom_smem_virt_to_phys(void - - return 0; - } --EXPORT_SYMBOL(qcom_smem_virt_to_phys); -+EXPORT_SYMBOL_GPL(qcom_smem_virt_to_phys); - - static int qcom_smem_get_sbl_version(struct qcom_smem *smem) - { diff --git a/target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch b/target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch deleted file mode 100644 index 4a816bb0f9763f..00000000000000 --- a/target/linux/generic/backport-6.1/830-03-v6.5-soc-qcom-smem-introduce-qcom_smem_get_soc_id.patch +++ /dev/null @@ -1,70 +0,0 @@ -From c3ecf2602a32d9b9e5fc997076c0d2836495c085 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 26 May 2023 22:48:00 +0200 -Subject: [PATCH] soc: qcom: smem: introduce qcom_smem_get_soc_id() - -Introduce a helper to return the SoC SMEM ID, which is used to identify the -exact SoC model as there may be differences in the same SoC family. - -Currently, cpufreq-nvmem does this completely in the driver and there has -been more interest expresed for other drivers to use this information so -lets expose a common helper to prevent redoing it in individual drivers -since this field is present on every SMEM table version. - -Signed-off-by: Robert Marko -Reviewed-by: Konrad Dybcio -Signed-off-by: Bjorn Andersson -Link: https://lore.kernel.org/r/20230526204802.3081168-3-robimarko@gmail.com ---- - drivers/soc/qcom/smem.c | 23 +++++++++++++++++++++++ - include/linux/soc/qcom/smem.h | 2 ++ - 2 files changed, 25 insertions(+) - ---- a/drivers/soc/qcom/smem.c -+++ b/drivers/soc/qcom/smem.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - - /* - * The Qualcomm shared memory system is a allocate only heap structure that -@@ -772,6 +773,28 @@ phys_addr_t qcom_smem_virt_to_phys(void - } - EXPORT_SYMBOL_GPL(qcom_smem_virt_to_phys); - -+/** -+ * qcom_smem_get_soc_id() - return the SoC ID -+ * @id: On success, we return the SoC ID here. -+ * -+ * Look up SoC ID from HW/SW build ID and return it. -+ * -+ * Return: 0 on success, negative errno on failure. -+ */ -+int qcom_smem_get_soc_id(u32 *id) -+{ -+ struct socinfo *info; -+ -+ info = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_HW_SW_BUILD_ID, NULL); -+ if (IS_ERR(info)) -+ return PTR_ERR(info); -+ -+ *id = __le32_to_cpu(info->id); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(qcom_smem_get_soc_id); -+ - static int qcom_smem_get_sbl_version(struct qcom_smem *smem) - { - struct smem_header *header; ---- a/include/linux/soc/qcom/smem.h -+++ b/include/linux/soc/qcom/smem.h -@@ -11,4 +11,6 @@ int qcom_smem_get_free_space(unsigned ho - - phys_addr_t qcom_smem_virt_to_phys(void *p); - -+int qcom_smem_get_soc_id(u32 *id); -+ - #endif diff --git a/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch b/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch deleted file mode 100644 index 25a718bd7eb4f2..00000000000000 --- a/target/linux/generic/backport-6.1/830-04-v6.5-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 2b8634d1468ff498cc91b6adf993c27ae6fa079d Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 26 May 2023 22:48:01 +0200 -Subject: [PATCH] cpufreq: qcom-nvmem: use SoC ID-s from bindings - -SMEM SoC ID-s are now stored in DT bindings so lets use those instead of -defining them in the driver again. - -Signed-off-by: Robert Marko -Reviewed-by: Konrad Dybcio -Reviewed-by: Bjorn Andersson -Acked-by: Viresh Kumar -Signed-off-by: Bjorn Andersson -Link: https://lore.kernel.org/r/20230526204802.3081168-4-robimarko@gmail.com ---- - drivers/cpufreq/qcom-cpufreq-nvmem.c | 15 +++++---------- - 1 file changed, 5 insertions(+), 10 deletions(-) - ---- a/drivers/cpufreq/qcom-cpufreq-nvmem.c -+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c -@@ -30,12 +30,7 @@ - - #define MSM_ID_SMEM 137 - --enum _msm_id { -- MSM8996V3 = 0xF6ul, -- APQ8096V3 = 0x123ul, -- MSM8996SG = 0x131ul, -- APQ8096SG = 0x138ul, --}; -+#include - - enum _msm8996_version { - MSM8996_V3, -@@ -157,12 +152,12 @@ static enum _msm8996_version qcom_cpufre - msm_id++; - - switch ((enum _msm_id)*msm_id) { -- case MSM8996V3: -- case APQ8096V3: -+ case QCOM_ID_MSM8996: -+ case QCOM_ID_APQ8096: - version = MSM8996_V3; - break; -- case MSM8996SG: -- case APQ8096SG: -+ case QCOM_ID_MSM8996SG: -+ case QCOM_ID_APQ8096SG: - version = MSM8996_SG; - break; - default: diff --git a/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch b/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch deleted file mode 100644 index 49d222662c9a81..00000000000000 --- a/target/linux/generic/backport-6.1/830-05-v6.5-cpufreq-qcom-nvmem-use-helper-to-get-SMEM-SoC-ID.patch +++ /dev/null @@ -1,109 +0,0 @@ -From e7992615acacc27baeec310197108143afc77337 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Fri, 26 May 2023 22:48:02 +0200 -Subject: [PATCH] cpufreq: qcom-nvmem: use helper to get SMEM SoC ID - -Now that SMEM exports a helper to get the SMEM SoC ID lets utilize it. -Currently qcom_cpufreq_get_msm_id() is encoding the returned SMEM SoC ID -into an enum, however there is no reason to do so and we can just match -directly on the SMEM SoC ID as returned by qcom_smem_get_soc_id(). - -Signed-off-by: Robert Marko -Acked-by: Viresh Kumar -Reviewed-by: Konrad Dybcio -Signed-off-by: Bjorn Andersson -Link: https://lore.kernel.org/r/20230526204802.3081168-5-robimarko@gmail.com ---- - drivers/cpufreq/qcom-cpufreq-nvmem.c | 56 +++++----------------------- - 1 file changed, 10 insertions(+), 46 deletions(-) - ---- a/drivers/cpufreq/qcom-cpufreq-nvmem.c -+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c -@@ -28,16 +28,8 @@ - #include - #include - --#define MSM_ID_SMEM 137 -- - #include - --enum _msm8996_version { -- MSM8996_V3, -- MSM8996_SG, -- NUM_OF_MSM8996_VERSIONS, --}; -- - struct qcom_cpufreq_drv; - - struct qcom_cpufreq_match_data { -@@ -138,60 +130,32 @@ static void get_krait_bin_format_b(struc - dev_dbg(cpu_dev, "PVS version: %d\n", *pvs_ver); - } - --static enum _msm8996_version qcom_cpufreq_get_msm_id(void) --{ -- size_t len; -- u32 *msm_id; -- enum _msm8996_version version; -- -- msm_id = qcom_smem_get(QCOM_SMEM_HOST_ANY, MSM_ID_SMEM, &len); -- if (IS_ERR(msm_id)) -- return NUM_OF_MSM8996_VERSIONS; -- -- /* The first 4 bytes are format, next to them is the actual msm-id */ -- msm_id++; -- -- switch ((enum _msm_id)*msm_id) { -- case QCOM_ID_MSM8996: -- case QCOM_ID_APQ8096: -- version = MSM8996_V3; -- break; -- case QCOM_ID_MSM8996SG: -- case QCOM_ID_APQ8096SG: -- version = MSM8996_SG; -- break; -- default: -- version = NUM_OF_MSM8996_VERSIONS; -- } -- -- return version; --} -- - static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev, - struct nvmem_cell *speedbin_nvmem, - char **pvs_name, - struct qcom_cpufreq_drv *drv) - { - size_t len; -+ u32 msm_id; - u8 *speedbin; -- enum _msm8996_version msm8996_version; -+ int ret; - *pvs_name = NULL; - -- msm8996_version = qcom_cpufreq_get_msm_id(); -- if (NUM_OF_MSM8996_VERSIONS == msm8996_version) { -- dev_err(cpu_dev, "Not Snapdragon 820/821!"); -- return -ENODEV; -- } -+ ret = qcom_smem_get_soc_id(&msm_id); -+ if (ret) -+ return ret; - - speedbin = nvmem_cell_read(speedbin_nvmem, &len); - if (IS_ERR(speedbin)) - return PTR_ERR(speedbin); - -- switch (msm8996_version) { -- case MSM8996_V3: -+ switch (msm_id) { -+ case QCOM_ID_MSM8996: -+ case QCOM_ID_APQ8096: - drv->versions = 1 << (unsigned int)(*speedbin); - break; -- case MSM8996_SG: -+ case QCOM_ID_MSM8996SG: -+ case QCOM_ID_APQ8096SG: - drv->versions = 1 << ((unsigned int)(*speedbin) + 4); - break; - default: diff --git a/target/linux/generic/backport-6.1/831-v6.7-rtc-rtc7301-Support-byte-addressed-IO.patch b/target/linux/generic/backport-6.1/831-v6.7-rtc-rtc7301-Support-byte-addressed-IO.patch deleted file mode 100644 index ddda6e4e783283..00000000000000 --- a/target/linux/generic/backport-6.1/831-v6.7-rtc-rtc7301-Support-byte-addressed-IO.patch +++ /dev/null @@ -1,93 +0,0 @@ -From edd25a77e69b7c546c28077e5dffe72c54c0afe8 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Thu, 21 Sep 2023 22:18:12 +0200 -Subject: [PATCH 2/4] rtc: rtc7301: Support byte-addressed IO - -The old RTC7301 driver in OpenWrt used byte access, but the -current mainline Linux driver uses 32bit word access. - -Make this configurable using device properties using the -standard property "reg-io-width" in e.g. device tree. - -This is needed for the USRobotics USR8200 which has the -chip connected using byte accesses. - -Debugging and testing by Howard Harte. - -Signed-off-by: Linus Walleij ---- - drivers/rtc/rtc-r7301.c | 35 +++++++++++++++++++++++++++++++++-- - 1 file changed, 33 insertions(+), 2 deletions(-) - ---- a/drivers/rtc/rtc-r7301.c -+++ b/drivers/rtc/rtc-r7301.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -55,12 +56,23 @@ struct rtc7301_priv { - u8 bank; - }; - --static const struct regmap_config rtc7301_regmap_config = { -+/* -+ * When the device is memory-mapped, some platforms pack the registers into -+ * 32-bit access using the lower 8 bits at each 4-byte stride, while others -+ * expose them as simply consecutive bytes. -+ */ -+static const struct regmap_config rtc7301_regmap_32_config = { - .reg_bits = 32, - .val_bits = 8, - .reg_stride = 4, - }; - -+static const struct regmap_config rtc7301_regmap_8_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .reg_stride = 1, -+}; -+ - static u8 rtc7301_read(struct rtc7301_priv *priv, unsigned int reg) - { - int reg_stride = regmap_get_reg_stride(priv->regmap); -@@ -356,7 +368,9 @@ static int __init rtc7301_rtc_probe(stru - void __iomem *regs; - struct rtc7301_priv *priv; - struct rtc_device *rtc; -+ static const struct regmap_config *mapconf; - int ret; -+ u32 val; - - priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) -@@ -366,8 +380,25 @@ static int __init rtc7301_rtc_probe(stru - if (IS_ERR(regs)) - return PTR_ERR(regs); - -+ ret = device_property_read_u32(&dev->dev, "reg-io-width", &val); -+ if (ret) -+ /* Default to 32bit accesses */ -+ val = 4; -+ -+ switch (val) { -+ case 1: -+ mapconf = &rtc7301_regmap_8_config; -+ break; -+ case 4: -+ mapconf = &rtc7301_regmap_32_config; -+ break; -+ default: -+ dev_err(&dev->dev, "invalid reg-io-width %d\n", val); -+ return -EINVAL; -+ } -+ - priv->regmap = devm_regmap_init_mmio(&dev->dev, regs, -- &rtc7301_regmap_config); -+ mapconf); - if (IS_ERR(priv->regmap)) - return PTR_ERR(priv->regmap); - diff --git a/target/linux/generic/backport-6.1/832-v6.7-net-phy-amd-Support-the-Altima-AMI101L.patch b/target/linux/generic/backport-6.1/832-v6.7-net-phy-amd-Support-the-Altima-AMI101L.patch deleted file mode 100644 index e8e73c1e5f04ac..00000000000000 --- a/target/linux/generic/backport-6.1/832-v6.7-net-phy-amd-Support-the-Altima-AMI101L.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 49e5663b505070424e18099841943f34342aa405 Mon Sep 17 00:00:00 2001 -From: Linus Walleij -Date: Sun, 24 Sep 2023 01:09:01 +0200 -Subject: [PATCH] net: phy: amd: Support the Altima AMI101L - -The Altima AC101L is obviously compatible with the AMD PHY, -as seen by reading the datasheet. - -Datasheet: https://docs.broadcom.com/doc/AC101L-DS05-405-RDS.pdf - -Signed-off-by: Linus Walleij ---- - drivers/net/phy/Kconfig | 4 ++-- - drivers/net/phy/amd.c | 33 +++++++++++++++++++++++---------- - 2 files changed, 25 insertions(+), 12 deletions(-) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -77,9 +77,9 @@ config AIR_EN8811H_PHY - Currently supports the Airoha EN8811H PHY. - - config AMD_PHY -- tristate "AMD PHYs" -+ tristate "AMD and Altima PHYs" - help -- Currently supports the am79c874 -+ Currently supports the AMD am79c874 and Altima AC101L. - - config MESON_GXL_PHY - tristate "Amlogic Meson GXL Internal PHY" ---- a/drivers/net/phy/amd.c -+++ b/drivers/net/phy/amd.c -@@ -13,6 +13,7 @@ - #include - #include - -+#define PHY_ID_AC101L 0x00225520 - #define PHY_ID_AM79C874 0x0022561b - - #define MII_AM79C_IR 17 /* Interrupt Status/Control Register */ -@@ -87,19 +88,31 @@ static irqreturn_t am79c_handle_interrup - return IRQ_HANDLED; - } - --static struct phy_driver am79c_driver[] = { { -- .phy_id = PHY_ID_AM79C874, -- .name = "AM79C874", -- .phy_id_mask = 0xfffffff0, -- /* PHY_BASIC_FEATURES */ -- .config_init = am79c_config_init, -- .config_intr = am79c_config_intr, -- .handle_interrupt = am79c_handle_interrupt, --} }; -+static struct phy_driver am79c_drivers[] = { -+ { -+ .phy_id = PHY_ID_AM79C874, -+ .name = "AM79C874", -+ .phy_id_mask = 0xfffffff0, -+ /* PHY_BASIC_FEATURES */ -+ .config_init = am79c_config_init, -+ .config_intr = am79c_config_intr, -+ .handle_interrupt = am79c_handle_interrupt, -+ }, -+ { -+ .phy_id = PHY_ID_AC101L, -+ .name = "AC101L", -+ .phy_id_mask = 0xfffffff0, -+ /* PHY_BASIC_FEATURES */ -+ .config_init = am79c_config_init, -+ .config_intr = am79c_config_intr, -+ .handle_interrupt = am79c_handle_interrupt, -+ }, -+}; - --module_phy_driver(am79c_driver); -+module_phy_driver(am79c_drivers); - - static struct mdio_device_id __maybe_unused amd_tbl[] = { -+ { PHY_ID_AC101L, 0xfffffff0 }, - { PHY_ID_AM79C874, 0xfffffff0 }, - { } - }; diff --git a/target/linux/generic/backport-6.1/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch b/target/linux/generic/backport-6.1/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch deleted file mode 100644 index b71df6fa5726da..00000000000000 --- a/target/linux/generic/backport-6.1/833-v6.8-leds-core-Add-more-colors-from-DT-bindings-to-led_co.patch.patch +++ /dev/null @@ -1,29 +0,0 @@ -From a067943129b4ec6b835e02cfd5fbef01093c1471 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 8 Oct 2023 16:40:13 +0200 -Subject: [PATCH] leds: core: Add more colors from DT bindings to led_colors - -The colors are already part of DT bindings. Make sure the kernel is -able to convert them to strings. - -Signed-off-by: Ondrej Jirman -Link: https://lore.kernel.org/r/20231008144014.1180334-1-megi@xff.cz -Signed-off-by: Lee Jones ---- - drivers/leds/led-core.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/leds/led-core.c -+++ b/drivers/leds/led-core.c -@@ -36,6 +36,11 @@ const char * const led_colors[LED_COLOR_ - [LED_COLOR_ID_IR] = "ir", - [LED_COLOR_ID_MULTI] = "multicolor", - [LED_COLOR_ID_RGB] = "rgb", -+ [LED_COLOR_ID_PURPLE] = "purple", -+ [LED_COLOR_ID_ORANGE] = "orange", -+ [LED_COLOR_ID_PINK] = "pink", -+ [LED_COLOR_ID_CYAN] = "cyan", -+ [LED_COLOR_ID_LIME] = "lime", - }; - EXPORT_SYMBOL_GPL(led_colors); - diff --git a/target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch b/target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch deleted file mode 100644 index 9d5a928f5f7cb2..00000000000000 --- a/target/linux/generic/backport-6.1/834-v6.8-leds-trigger-netdev-Extend-speeds-up-to-10G.patch +++ /dev/null @@ -1,111 +0,0 @@ -From bc8e1da69a68d9871773b657d18400a7941cbdef Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 28 Nov 2023 04:00:10 +0000 -Subject: [PATCH] leds: trigger: netdev: Extend speeds up to 10G - -Add 2.5G, 5G and 10G as available speeds to the netdev LED trigger. - -Signed-off-by: Daniel Golle -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/99e7d3304c6bba7f4863a4a80764a869855f2085.1701143925.git.daniel@makrotopia.org -Signed-off-by: Lee Jones ---- - drivers/leds/trigger/ledtrig-netdev.c | 32 ++++++++++++++++++++++++++- - include/linux/leds.h | 3 +++ - 2 files changed, 34 insertions(+), 1 deletion(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -99,6 +99,18 @@ static void set_baseline_state(struct le - trigger_data->link_speed == SPEED_1000) - blink_on = true; - -+ if (test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) && -+ trigger_data->link_speed == SPEED_2500) -+ blink_on = true; -+ -+ if (test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) && -+ trigger_data->link_speed == SPEED_5000) -+ blink_on = true; -+ -+ if (test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) && -+ trigger_data->link_speed == SPEED_10000) -+ blink_on = true; -+ - if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) && - trigger_data->duplex == DUPLEX_HALF) - blink_on = true; -@@ -286,6 +298,9 @@ static ssize_t netdev_led_attr_show(stru - case TRIGGER_NETDEV_LINK_10: - case TRIGGER_NETDEV_LINK_100: - case TRIGGER_NETDEV_LINK_1000: -+ case TRIGGER_NETDEV_LINK_2500: -+ case TRIGGER_NETDEV_LINK_5000: -+ case TRIGGER_NETDEV_LINK_10000: - case TRIGGER_NETDEV_HALF_DUPLEX: - case TRIGGER_NETDEV_FULL_DUPLEX: - case TRIGGER_NETDEV_TX: -@@ -316,6 +331,9 @@ static ssize_t netdev_led_attr_store(str - case TRIGGER_NETDEV_LINK_10: - case TRIGGER_NETDEV_LINK_100: - case TRIGGER_NETDEV_LINK_1000: -+ case TRIGGER_NETDEV_LINK_2500: -+ case TRIGGER_NETDEV_LINK_5000: -+ case TRIGGER_NETDEV_LINK_10000: - case TRIGGER_NETDEV_HALF_DUPLEX: - case TRIGGER_NETDEV_FULL_DUPLEX: - case TRIGGER_NETDEV_TX: -@@ -334,7 +352,10 @@ static ssize_t netdev_led_attr_store(str - if (test_bit(TRIGGER_NETDEV_LINK, &mode) && - (test_bit(TRIGGER_NETDEV_LINK_10, &mode) || - test_bit(TRIGGER_NETDEV_LINK_100, &mode) || -- test_bit(TRIGGER_NETDEV_LINK_1000, &mode))) -+ test_bit(TRIGGER_NETDEV_LINK_1000, &mode) || -+ test_bit(TRIGGER_NETDEV_LINK_2500, &mode) || -+ test_bit(TRIGGER_NETDEV_LINK_5000, &mode) || -+ test_bit(TRIGGER_NETDEV_LINK_10000, &mode))) - return -EINVAL; - - cancel_delayed_work_sync(&trigger_data->work); -@@ -364,6 +385,9 @@ DEFINE_NETDEV_TRIGGER(link, TRIGGER_NETD - DEFINE_NETDEV_TRIGGER(link_10, TRIGGER_NETDEV_LINK_10); - DEFINE_NETDEV_TRIGGER(link_100, TRIGGER_NETDEV_LINK_100); - DEFINE_NETDEV_TRIGGER(link_1000, TRIGGER_NETDEV_LINK_1000); -+DEFINE_NETDEV_TRIGGER(link_2500, TRIGGER_NETDEV_LINK_2500); -+DEFINE_NETDEV_TRIGGER(link_5000, TRIGGER_NETDEV_LINK_5000); -+DEFINE_NETDEV_TRIGGER(link_10000, TRIGGER_NETDEV_LINK_10000); - DEFINE_NETDEV_TRIGGER(half_duplex, TRIGGER_NETDEV_HALF_DUPLEX); - DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX); - DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); -@@ -422,6 +446,9 @@ static struct attribute *netdev_trig_att - &dev_attr_link_10.attr, - &dev_attr_link_100.attr, - &dev_attr_link_1000.attr, -+ &dev_attr_link_2500.attr, -+ &dev_attr_link_5000.attr, -+ &dev_attr_link_10000.attr, - &dev_attr_full_duplex.attr, - &dev_attr_half_duplex.attr, - &dev_attr_rx.attr, -@@ -519,6 +546,9 @@ static void netdev_trig_work(struct work - test_bit(TRIGGER_NETDEV_LINK_10, &trigger_data->mode) || - test_bit(TRIGGER_NETDEV_LINK_100, &trigger_data->mode) || - test_bit(TRIGGER_NETDEV_LINK_1000, &trigger_data->mode) || -+ test_bit(TRIGGER_NETDEV_LINK_2500, &trigger_data->mode) || -+ test_bit(TRIGGER_NETDEV_LINK_5000, &trigger_data->mode) || -+ test_bit(TRIGGER_NETDEV_LINK_10000, &trigger_data->mode) || - test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &trigger_data->mode) || - test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &trigger_data->mode); - interval = jiffies_to_msecs( ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -531,6 +531,9 @@ enum led_trigger_netdev_modes { - TRIGGER_NETDEV_LINK_10, - TRIGGER_NETDEV_LINK_100, - TRIGGER_NETDEV_LINK_1000, -+ TRIGGER_NETDEV_LINK_2500, -+ TRIGGER_NETDEV_LINK_5000, -+ TRIGGER_NETDEV_LINK_10000, - TRIGGER_NETDEV_HALF_DUPLEX, - TRIGGER_NETDEV_FULL_DUPLEX, - TRIGGER_NETDEV_TX, diff --git a/target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch b/target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch deleted file mode 100644 index 0182e6d1a203b0..00000000000000 --- a/target/linux/generic/backport-6.1/835-v6.9-net-phy-add-support-for-PHY-LEDs-polarity-modes.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 7ae215ee7bb855f13c80565470fc7f67db4ba82f Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 25 Jan 2024 21:36:59 +0100 -Subject: [PATCH 3/5] net: phy: add support for PHY LEDs polarity modes - -Add support for PHY LEDs polarity modes. Some PHY require LED to be set -to active low to be turned ON. Adds support for this by declaring -active-low property in DT. - -PHY driver needs to declare .led_polarity_set() to configure LED -polarity modes. Function will pass the index with the LED index and a -bitmap with all the required modes to set. - -Current supported modes are: -- active-low with the flag PHY_LED_ACTIVE_LOW. LED is set to active-low - to turn it ON. -- inactive-high-impedance with the flag PHY_LED_INACTIVE_HIGH_IMPEDANCE. - LED is set to high impedance to turn it OFF. - -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240125203702.4552-4-ansuelsmth@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phy_device.c | 16 ++++++++++++++++ - include/linux/phy.h | 22 ++++++++++++++++++++++ - 2 files changed, 38 insertions(+) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -3138,6 +3138,7 @@ static int of_phy_led(struct phy_device - struct device *dev = &phydev->mdio.dev; - struct led_init_data init_data = {}; - struct led_classdev *cdev; -+ unsigned long modes = 0; - struct phy_led *phyled; - u32 index; - int err; -@@ -3155,6 +3156,21 @@ static int of_phy_led(struct phy_device - if (index > U8_MAX) - return -EINVAL; - -+ if (of_property_read_bool(led, "active-low")) -+ set_bit(PHY_LED_ACTIVE_LOW, &modes); -+ if (of_property_read_bool(led, "inactive-high-impedance")) -+ set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes); -+ -+ if (modes) { -+ /* Return error if asked to set polarity modes but not supported */ -+ if (!phydev->drv->led_polarity_set) -+ return -EINVAL; -+ -+ err = phydev->drv->led_polarity_set(phydev, index, modes); -+ if (err) -+ return err; -+ } -+ - phyled->index = index; - if (phydev->drv->led_brightness_set) - cdev->brightness_set_blocking = phy_led_set_brightness; ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -791,6 +791,15 @@ struct phy_led { - - #define to_phy_led(d) container_of(d, struct phy_led, led_cdev) - -+/* Modes for PHY LED configuration */ -+enum phy_led_modes { -+ PHY_LED_ACTIVE_LOW = 0, -+ PHY_LED_INACTIVE_HIGH_IMPEDANCE = 1, -+ -+ /* keep it last */ -+ __PHY_LED_MODES_NUM, -+}; -+ - /** - * struct phy_driver - Driver structure for a particular PHY type - * -@@ -1059,6 +1068,19 @@ struct phy_driver { - int (*led_hw_control_get)(struct phy_device *dev, u8 index, - unsigned long *rules); - -+ /** -+ * @led_polarity_set: Set the LED polarity modes -+ * @dev: PHY device which has the LED -+ * @index: Which LED of the PHY device -+ * @modes: bitmap of LED polarity modes -+ * -+ * Configure LED with all the required polarity modes in @modes -+ * to make it correctly turn ON or OFF. -+ * -+ * Returns 0, or an error code. -+ */ -+ int (*led_polarity_set)(struct phy_device *dev, int index, -+ unsigned long modes); - }; - #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ - struct phy_driver, mdiodrv) diff --git a/target/linux/generic/backport-6.1/836-v6.7-leds-trigger-netdev-fix-RTNL-handling-to-prevent-pot.patch b/target/linux/generic/backport-6.1/836-v6.7-leds-trigger-netdev-fix-RTNL-handling-to-prevent-pot.patch deleted file mode 100644 index cbb9172032326c..00000000000000 --- a/target/linux/generic/backport-6.1/836-v6.7-leds-trigger-netdev-fix-RTNL-handling-to-prevent-pot.patch +++ /dev/null @@ -1,170 +0,0 @@ -From fe2b1226656afae56702d1d84c6900f6b67df297 Mon Sep 17 00:00:00 2001 -From: Heiner Kallweit -Date: Fri, 1 Dec 2023 11:23:22 +0100 -Subject: [PATCH] leds: trigger: netdev: fix RTNL handling to prevent potential - deadlock - -When working on LED support for r8169 I got the following lockdep -warning. Easiest way to prevent this scenario seems to be to take -the RTNL lock before the trigger_data lock in set_device_name(). - -====================================================== -WARNING: possible circular locking dependency detected -6.7.0-rc2-next-20231124+ #2 Not tainted ------------------------------------------------------- -bash/383 is trying to acquire lock: -ffff888103aa1c68 (&trigger_data->lock){+.+.}-{3:3}, at: netdev_trig_notify+0xec/0x190 [ledtrig_netdev] - -but task is already holding lock: -ffffffff8cddf808 (rtnl_mutex){+.+.}-{3:3}, at: rtnl_lock+0x12/0x20 - -which lock already depends on the new lock. - -the existing dependency chain (in reverse order) is: - --> #1 (rtnl_mutex){+.+.}-{3:3}: - __mutex_lock+0x9b/0xb50 - mutex_lock_nested+0x16/0x20 - rtnl_lock+0x12/0x20 - set_device_name+0xa9/0x120 [ledtrig_netdev] - netdev_trig_activate+0x1a1/0x230 [ledtrig_netdev] - led_trigger_set+0x172/0x2c0 - led_trigger_write+0xf1/0x140 - sysfs_kf_bin_write+0x5d/0x80 - kernfs_fop_write_iter+0x15d/0x210 - vfs_write+0x1f0/0x510 - ksys_write+0x6c/0xf0 - __x64_sys_write+0x14/0x20 - do_syscall_64+0x3f/0xf0 - entry_SYSCALL_64_after_hwframe+0x6c/0x74 - --> #0 (&trigger_data->lock){+.+.}-{3:3}: - __lock_acquire+0x1459/0x25a0 - lock_acquire+0xc8/0x2d0 - __mutex_lock+0x9b/0xb50 - mutex_lock_nested+0x16/0x20 - netdev_trig_notify+0xec/0x190 [ledtrig_netdev] - call_netdevice_register_net_notifiers+0x5a/0x100 - register_netdevice_notifier+0x85/0x120 - netdev_trig_activate+0x1d4/0x230 [ledtrig_netdev] - led_trigger_set+0x172/0x2c0 - led_trigger_write+0xf1/0x140 - sysfs_kf_bin_write+0x5d/0x80 - kernfs_fop_write_iter+0x15d/0x210 - vfs_write+0x1f0/0x510 - ksys_write+0x6c/0xf0 - __x64_sys_write+0x14/0x20 - do_syscall_64+0x3f/0xf0 - entry_SYSCALL_64_after_hwframe+0x6c/0x74 - -other info that might help us debug this: - - Possible unsafe locking scenario: - - CPU0 CPU1 - ---- ---- - lock(rtnl_mutex); - lock(&trigger_data->lock); - lock(rtnl_mutex); - lock(&trigger_data->lock); - - *** DEADLOCK *** - -8 locks held by bash/383: - #0: ffff888103ff33f0 (sb_writers#3){.+.+}-{0:0}, at: ksys_write+0x6c/0xf0 - #1: ffff888103aa1e88 (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x114/0x210 - #2: ffff8881036f1890 (kn->active#82){.+.+}-{0:0}, at: kernfs_fop_write_iter+0x11d/0x210 - #3: ffff888108e2c358 (&led_cdev->led_access){+.+.}-{3:3}, at: led_trigger_write+0x30/0x140 - #4: ffffffff8cdd9e10 (triggers_list_lock){++++}-{3:3}, at: led_trigger_write+0x75/0x140 - #5: ffff888108e2c270 (&led_cdev->trigger_lock){++++}-{3:3}, at: led_trigger_write+0xe3/0x140 - #6: ffffffff8cdde3d0 (pernet_ops_rwsem){++++}-{3:3}, at: register_netdevice_notifier+0x1c/0x120 - #7: ffffffff8cddf808 (rtnl_mutex){+.+.}-{3:3}, at: rtnl_lock+0x12/0x20 - -stack backtrace: -CPU: 0 PID: 383 Comm: bash Not tainted 6.7.0-rc2-next-20231124+ #2 -Hardware name: Default string Default string/Default string, BIOS ADLN.M6.SODIMM.ZB.CY.015 08/08/2023 -Call Trace: - - dump_stack_lvl+0x5c/0xd0 - dump_stack+0x10/0x20 - print_circular_bug+0x2dd/0x410 - check_noncircular+0x131/0x150 - __lock_acquire+0x1459/0x25a0 - lock_acquire+0xc8/0x2d0 - ? netdev_trig_notify+0xec/0x190 [ledtrig_netdev] - __mutex_lock+0x9b/0xb50 - ? netdev_trig_notify+0xec/0x190 [ledtrig_netdev] - ? __this_cpu_preempt_check+0x13/0x20 - ? netdev_trig_notify+0xec/0x190 [ledtrig_netdev] - ? __cancel_work_timer+0x11c/0x1b0 - ? __mutex_lock+0x123/0xb50 - mutex_lock_nested+0x16/0x20 - ? mutex_lock_nested+0x16/0x20 - netdev_trig_notify+0xec/0x190 [ledtrig_netdev] - call_netdevice_register_net_notifiers+0x5a/0x100 - register_netdevice_notifier+0x85/0x120 - netdev_trig_activate+0x1d4/0x230 [ledtrig_netdev] - led_trigger_set+0x172/0x2c0 - ? preempt_count_add+0x49/0xc0 - led_trigger_write+0xf1/0x140 - sysfs_kf_bin_write+0x5d/0x80 - kernfs_fop_write_iter+0x15d/0x210 - vfs_write+0x1f0/0x510 - ksys_write+0x6c/0xf0 - __x64_sys_write+0x14/0x20 - do_syscall_64+0x3f/0xf0 - entry_SYSCALL_64_after_hwframe+0x6c/0x74 -RIP: 0033:0x7f269055d034 -Code: c7 00 16 00 00 00 b8 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 80 3d 35 c3 0d 00 00 74 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 48 83 ec 28 48 89 54 24 18 48 -RSP: 002b:00007ffddb7ef748 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 -RAX: ffffffffffffffda RBX: 0000000000000007 RCX: 00007f269055d034 -RDX: 0000000000000007 RSI: 000055bf5f4af3c0 RDI: 0000000000000001 -RBP: 000055bf5f4af3c0 R08: 0000000000000073 R09: 0000000000000001 -R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000007 -R13: 00007f26906325c0 R14: 00007f269062ff20 R15: 0000000000000000 - - -Fixes: d5e01266e7f5 ("leds: trigger: netdev: add additional specific link speed mode") -Cc: stable@vger.kernel.org -Signed-off-by: Heiner Kallweit -Reviewed-by: Andrew Lunn -Acked-by: Lee Jones -Link: https://lore.kernel.org/r/fb5c8294-2a10-4bf5-8f10-3d2b77d2757e@gmail.com -Signed-off-by: Jakub Kicinski ---- - drivers/leds/trigger/ledtrig-netdev.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -235,6 +235,11 @@ static int set_device_name(struct led_ne - { - cancel_delayed_work_sync(&trigger_data->work); - -+ /* -+ * Take RTNL lock before trigger_data lock to prevent potential -+ * deadlock with netdev notifier registration. -+ */ -+ rtnl_lock(); - mutex_lock(&trigger_data->lock); - - if (trigger_data->net_dev) { -@@ -254,16 +259,14 @@ static int set_device_name(struct led_ne - trigger_data->carrier_link_up = false; - trigger_data->link_speed = SPEED_UNKNOWN; - trigger_data->duplex = DUPLEX_UNKNOWN; -- if (trigger_data->net_dev != NULL) { -- rtnl_lock(); -+ if (trigger_data->net_dev) - get_device_state(trigger_data); -- rtnl_unlock(); -- } - - trigger_data->last_activity = 0; - - set_baseline_state(trigger_data); - mutex_unlock(&trigger_data->lock); -+ rtnl_unlock(); - - return 0; - } diff --git a/target/linux/generic/backport-6.1/837-v6.4-net-phy-hide-the-PHYLIB_LEDS-knob.patch b/target/linux/generic/backport-6.1/837-v6.4-net-phy-hide-the-PHYLIB_LEDS-knob.patch deleted file mode 100644 index 51b4bbbfcb1402..00000000000000 --- a/target/linux/generic/backport-6.1/837-v6.4-net-phy-hide-the-PHYLIB_LEDS-knob.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 9b78d919632b7149d311aaad5a977e4b48b10321 Mon Sep 17 00:00:00 2001 -From: Paolo Abeni -Date: Wed, 26 Apr 2023 10:15:31 +0200 -Subject: [PATCH] net: phy: hide the PHYLIB_LEDS knob - -commit 4bb7aac70b5d ("net: phy: fix circular LEDS_CLASS dependencies") -solved a build failure, but introduces a new config knob with a default -'y' value: PHYLIB_LEDS. - -The latter is against the current new config policy. The exception -was raised to allow the user to catch bad configurations without led -support. - -Anyway the current definition of PHYLIB_LEDS does not fit the above -goal: if LEDS_CLASS is disabled, the new config will be available -only with PHYLIB disabled, too. - -Hide the mentioned config, to preserve the randconfig testing done so -far, while respecting the mentioned policy. - -Suggested-by: Andrew Lunn -Suggested-by: Arnd Bergmann -Signed-off-by: Paolo Abeni -Link: https://lore.kernel.org/r/d82489be8ed911c383c3447e9abf469995ccf39a.1682496488.git.pabeni@redhat.com -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/Kconfig | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -45,10 +45,8 @@ config LED_TRIGGER_PHY - for any speed known to the PHY. - - config PHYLIB_LEDS -- bool "Support probing LEDs from device tree" -+ def_bool OF - depends on LEDS_CLASS=y || LEDS_CLASS=PHYLIB -- depends on OF -- default y - help - When LED class support is enabled, phylib can automatically - probe LED setting from device tree. diff --git a/target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch b/target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch deleted file mode 100644 index 8d391678ffb7c8..00000000000000 --- a/target/linux/generic/backport-6.1/838-v6.9-leds-trigger-netdev-Fix-kernel-panic-on-interface-re.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 12ce20e02e532f101b725d71c52a36c5cc8ad1e6 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sun, 4 Feb 2024 00:54:01 +0100 -Subject: [PATCH] leds: trigger: netdev: Fix kernel panic on interface rename - trig notify - -Commit d5e01266e7f5 ("leds: trigger: netdev: add additional specific link -speed mode") in the various changes, reworked the way to set the LINKUP -mode in commit cee4bd16c319 ("leds: trigger: netdev: Recheck -NETDEV_LED_MODE_LINKUP on dev rename") and moved it to a generic function. - -This changed the logic where, in the previous implementation the dev -from the trigger event was used to check if the carrier was ok, but in -the new implementation with the generic function, the dev in -trigger_data is used instead. - -This is problematic and cause a possible kernel panic due to the fact -that the dev in the trigger_data still reference the old one as the -new one (passed from the trigger event) still has to be hold and saved -in the trigger_data struct (done in the NETDEV_REGISTER case). - -On calling of get_device_state(), an invalid net_dev is used and this -cause a kernel panic. - -To handle this correctly, move the call to get_device_state() after the -new net_dev is correctly set in trigger_data (in the NETDEV_REGISTER -case) and correctly parse the new dev. - -Fixes: d5e01266e7f5 ("leds: trigger: netdev: add additional specific link speed mode") -Cc: stable@vger.kernel.org -Signed-off-by: Christian Marangi -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/20240203235413.1146-1-ansuelsmth@gmail.com -Signed-off-by: Lee Jones ---- - drivers/leds/trigger/ledtrig-netdev.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/leds/trigger/ledtrig-netdev.c -+++ b/drivers/leds/trigger/ledtrig-netdev.c -@@ -489,12 +489,12 @@ static int netdev_trig_notify(struct not - trigger_data->duplex = DUPLEX_UNKNOWN; - switch (evt) { - case NETDEV_CHANGENAME: -- get_device_state(trigger_data); -- fallthrough; - case NETDEV_REGISTER: - dev_put(trigger_data->net_dev); - dev_hold(dev); - trigger_data->net_dev = dev; -+ if (evt == NETDEV_CHANGENAME) -+ get_device_state(trigger_data); - break; - case NETDEV_UNREGISTER: - dev_put(trigger_data->net_dev); diff --git a/target/linux/generic/backport-6.1/839-v6.9-net-phy-aquantia-clear-PMD-Global-Transmit-Disable-b.patch b/target/linux/generic/backport-6.1/839-v6.9-net-phy-aquantia-clear-PMD-Global-Transmit-Disable-b.patch deleted file mode 100644 index 802cf8a128ccb8..00000000000000 --- a/target/linux/generic/backport-6.1/839-v6.9-net-phy-aquantia-clear-PMD-Global-Transmit-Disable-b.patch +++ /dev/null @@ -1,103 +0,0 @@ -From cffac22c9215f1883d3848c788f9b03656dced27 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sun, 11 Feb 2024 18:39:19 +0100 -Subject: [PATCH] net: phy: aquantia: clear PMD Global Transmit Disable bit - during init - -PMD Global Transmit Disable bit should be cleared for normal operation. -This should be HW default, however I found that on Asus RT-AX89X that uses -AQR113C PHY and firmware 5.4 this bit is set by default. - -With this bit set the AQR cannot achieve a link with its link-partner and -it took me multiple hours of digging through the vendor GPL source to find -this out, so lets always clear this bit during .config_init() to avoid a -situation like this in the future. - -aqr107_wait_processor_intensive_op() is moved up because datasheet notes -that any changes to this bit are processor intensive. - -Signed-off-by: Robert Marko ---- - drivers/net/phy/aquantia/aquantia_main.c | 57 ++++++++++++++---------- - 1 file changed, 33 insertions(+), 24 deletions(-) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -507,6 +507,30 @@ static void aqr107_chip_info(struct phy_ - fw_major, fw_minor, build_id, prov_id); - } - -+static int aqr107_wait_processor_intensive_op(struct phy_device *phydev) -+{ -+ int val, err; -+ -+ /* The datasheet notes to wait at least 1ms after issuing a -+ * processor intensive operation before checking. -+ * We cannot use the 'sleep_before_read' parameter of read_poll_timeout -+ * because that just determines the maximum time slept, not the minimum. -+ */ -+ usleep_range(1000, 5000); -+ -+ err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -+ VEND1_GLOBAL_GEN_STAT2, val, -+ !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG), -+ AQR107_OP_IN_PROG_SLEEP, -+ AQR107_OP_IN_PROG_TIMEOUT, false); -+ if (err) { -+ phydev_err(phydev, "timeout: processor-intensive MDIO operation\n"); -+ return err; -+ } -+ -+ return 0; -+} -+ - static int aqr107_config_init(struct phy_device *phydev) - { - int ret; -@@ -530,6 +554,15 @@ static int aqr107_config_init(struct phy - if (!ret) - aqr107_chip_info(phydev); - -+ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, -+ MDIO_PMD_TXDIS_GLOBAL); -+ if (ret) -+ return ret; -+ -+ ret = aqr107_wait_processor_intensive_op(phydev); -+ if (ret) -+ return ret; -+ - return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); - } - -@@ -600,30 +633,6 @@ static void aqr107_link_change_notify(st - phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n"); - } - --static int aqr107_wait_processor_intensive_op(struct phy_device *phydev) --{ -- int val, err; -- -- /* The datasheet notes to wait at least 1ms after issuing a -- * processor intensive operation before checking. -- * We cannot use the 'sleep_before_read' parameter of read_poll_timeout -- * because that just determines the maximum time slept, not the minimum. -- */ -- usleep_range(1000, 5000); -- -- err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, -- VEND1_GLOBAL_GEN_STAT2, val, -- !(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG), -- AQR107_OP_IN_PROG_SLEEP, -- AQR107_OP_IN_PROG_TIMEOUT, false); -- if (err) { -- phydev_err(phydev, "timeout: processor-intensive MDIO operation\n"); -- return err; -- } -- -- return 0; --} -- - static int aqr107_get_rate_matching(struct phy_device *phydev, - phy_interface_t iface) - { diff --git a/target/linux/generic/backport-6.1/840-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch b/target/linux/generic/backport-6.1/840-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch deleted file mode 100644 index a8ce832408f834..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0001-nvmem-add-missing-MODULE_DESCRIPTION-macros.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c553bad4c5fc5ae44bd2fcaa73e1d6bedfb1c35c Mon Sep 17 00:00:00 2001 -From: Jeff Johnson -Date: Fri, 5 Jul 2024 08:48:38 +0100 -Subject: [PATCH] nvmem: add missing MODULE_DESCRIPTION() macros - -make allmodconfig && make W=1 C=1 reports: -WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem-apple-efuses.o -WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_brcm_nvram.o -WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/nvmem/nvmem_u-boot-env.o - -Add the missing invocations of the MODULE_DESCRIPTION() macro. - -Signed-off-by: Jeff Johnson -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/apple-efuses.c | 1 + - drivers/nvmem/brcm_nvram.c | 1 + - drivers/nvmem/u-boot-env.c | 1 + - 3 files changed, 3 insertions(+) - ---- a/drivers/nvmem/apple-efuses.c -+++ b/drivers/nvmem/apple-efuses.c -@@ -78,4 +78,5 @@ static struct platform_driver apple_efus - module_platform_driver(apple_efuses_driver); - - MODULE_AUTHOR("Sven Peter "); -+MODULE_DESCRIPTION("Apple SoC eFuse driver"); - MODULE_LICENSE("GPL"); ---- a/drivers/nvmem/brcm_nvram.c -+++ b/drivers/nvmem/brcm_nvram.c -@@ -253,5 +253,6 @@ static int __init brcm_nvram_init(void) - subsys_initcall_sync(brcm_nvram_init); - - MODULE_AUTHOR("Rafał Miłecki"); -+MODULE_DESCRIPTION("Broadcom I/O-mapped NVRAM support driver"); - MODULE_LICENSE("GPL"); - MODULE_DEVICE_TABLE(of, brcm_nvram_of_match_table); ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -249,5 +249,6 @@ static struct platform_driver u_boot_env - module_platform_driver(u_boot_env_driver); - - MODULE_AUTHOR("Rafał Miłecki"); -+MODULE_DESCRIPTION("U-Boot environment variables support module"); - MODULE_LICENSE("GPL"); - MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table); diff --git a/target/linux/generic/backport-6.1/840-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch b/target/linux/generic/backport-6.1/840-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch deleted file mode 100644 index 05c82dbf6f560a..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0002-nvmem-meson-efuse-Replacing-the-use-of-of_node_put-t.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 5fecb932607d83d37a703c731268e9d9051457f5 Mon Sep 17 00:00:00 2001 -From: MarileneGarcia -Date: Fri, 5 Jul 2024 08:48:40 +0100 -Subject: [PATCH] nvmem: meson-efuse: Replacing the use of of_node_put to - __free - -Use __free for device_node values, and thus drop calls to -of_node_put. - -The goal is to reduce memory management issues by using this -scope-based of_node_put() cleanup to simplify function exit -handling. When using __free a resource is allocated within a -block, it is automatically freed at the end of the block. - -Suggested-by: Julia Lawall -Signed-off-by: MarileneGarcia -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-4-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/meson-efuse.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/meson-efuse.c -+++ b/drivers/nvmem/meson-efuse.c -@@ -48,20 +48,19 @@ static int meson_efuse_probe(struct plat - { - struct device *dev = &pdev->dev; - struct meson_sm_firmware *fw; -- struct device_node *sm_np; - struct nvmem_device *nvmem; - struct nvmem_config *econfig; - struct clk *clk; - unsigned int size; -+ struct device_node *sm_np __free(device_node) = -+ of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0); - -- sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0); - if (!sm_np) { - dev_err(&pdev->dev, "no secure-monitor node\n"); - return -ENODEV; - } - - fw = meson_sm_get(sm_np); -- of_node_put(sm_np); - if (!fw) - return -EPROBE_DEFER; - diff --git a/target/linux/generic/backport-6.1/840-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch b/target/linux/generic/backport-6.1/840-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch deleted file mode 100644 index a8a30fc8103ef7..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0003-nvmem-rockchip-otp-set-add_legacy_fixed_of_cells-con.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2933e79db3c00a8cdc56f6bb050a857fec1875ad Mon Sep 17 00:00:00 2001 -From: Heiko Stuebner -Date: Fri, 5 Jul 2024 08:48:41 +0100 -Subject: [PATCH] nvmem: rockchip-otp: set add_legacy_fixed_of_cells config - option - -The Rockchip OTP describes its layout via devicetree subnodes, -so set the appropriate property. - -Fixes: 2cc3b37f5b6d ("nvmem: add explicit config option to read old syntax fixed OF cells") -Signed-off-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -255,6 +255,7 @@ static int rockchip_otp_read(void *conte - static struct nvmem_config otp_config = { - .name = "rockchip-otp", - .owner = THIS_MODULE, -+ .add_legacy_fixed_of_cells = true, - .read_only = true, - .stride = 1, - .word_size = 1, diff --git a/target/linux/generic/backport-6.1/840-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch b/target/linux/generic/backport-6.1/840-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch deleted file mode 100644 index 8491eb3c9ce2fb..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0004-nvmem-rockchip-otp-Set-type-to-OTP.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 39f95600d8c53355b212a117e91a6ba15e0cac47 Mon Sep 17 00:00:00 2001 -From: Heiko Stuebner -Date: Fri, 5 Jul 2024 08:48:42 +0100 -Subject: [PATCH] nvmem: rockchip-otp: Set type to OTP - -The Rockchip OTP is obviously an OTP memory, so document this fact. - -Signed-off-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-6-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-otp.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/rockchip-otp.c -+++ b/drivers/nvmem/rockchip-otp.c -@@ -256,6 +256,7 @@ static struct nvmem_config otp_config = - .name = "rockchip-otp", - .owner = THIS_MODULE, - .add_legacy_fixed_of_cells = true, -+ .type = NVMEM_TYPE_OTP, - .read_only = true, - .stride = 1, - .word_size = 1, diff --git a/target/linux/generic/backport-6.1/840-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch b/target/linux/generic/backport-6.1/840-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch deleted file mode 100644 index 260b03eb035fb6..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0005-nvmem-rockchip-efuse-set-type-to-OTP.patch +++ /dev/null @@ -1,26 +0,0 @@ -From ba64a04474d2989f397982c48e405cfd785e2dd5 Mon Sep 17 00:00:00 2001 -From: Heiko Stuebner -Date: Fri, 5 Jul 2024 08:48:43 +0100 -Subject: [PATCH] nvmem: rockchip-efuse: set type to OTP - -This device currently reports an "Unknown" type in sysfs. -Since it is an eFuse hardware device, set its type to OTP. - -Signed-off-by: Heiko Stuebner -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-7-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/rockchip-efuse.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/nvmem/rockchip-efuse.c -+++ b/drivers/nvmem/rockchip-efuse.c -@@ -206,6 +206,7 @@ static int rockchip_rk3399_efuse_read(vo - static struct nvmem_config econfig = { - .name = "rockchip-efuse", - .add_legacy_fixed_of_cells = true, -+ .type = NVMEM_TYPE_OTP, - .stride = 1, - .word_size = 1, - .read_only = true, diff --git a/target/linux/generic/backport-6.1/840-v6.11-0006-nvmem-core-add-single-sysfs-group.patch b/target/linux/generic/backport-6.1/840-v6.11-0006-nvmem-core-add-single-sysfs-group.patch deleted file mode 100644 index 4fb2afd2fa33c9..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0006-nvmem-core-add-single-sysfs-group.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6188f233161c6a5b2d1c396a221dfafc77dc9eec Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= -Date: Fri, 5 Jul 2024 08:48:46 +0100 -Subject: [PATCH] nvmem: core: add single sysfs group -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The sysfs core provides a function to easily register a single group. -Use it and remove the now unnecessary nvmem_cells_groups array. - -Signed-off-by: Thomas Weißschuh -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-10-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -368,11 +368,6 @@ static const struct attribute_group *nvm - NULL, - }; - --static const struct attribute_group *nvmem_cells_groups[] = { -- &nvmem_cells_group, -- NULL, --}; -- - static struct bin_attribute bin_attr_nvmem_eeprom_compat = { - .attr = { - .name = "eeprom", -@@ -477,7 +472,7 @@ static int nvmem_populate_sysfs_cells(st - - nvmem_cells_group.bin_attrs = cells_attrs; - -- ret = device_add_groups(&nvmem->dev, nvmem_cells_groups); -+ ret = device_add_group(&nvmem->dev, &nvmem_cells_group); - if (ret) - goto unlock_mutex; - diff --git a/target/linux/generic/backport-6.1/840-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch b/target/linux/generic/backport-6.1/840-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch deleted file mode 100644 index ef626d37a03182..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0007-nvmem-core-remove-global-nvmem_cells_group.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 6839fed062b7898665983368c88269a6fb1fc10f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= -Date: Fri, 5 Jul 2024 08:48:47 +0100 -Subject: [PATCH] nvmem: core: remove global nvmem_cells_group -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -nvmem_cells_groups is a global variable that is also mutated. -This is complicated and error-prone. - -Instead use a normal stack variable. - -Signed-off-by: Thomas Weißschuh -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-11-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 26 ++++++++++---------------- - 1 file changed, 10 insertions(+), 16 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -358,11 +358,6 @@ static const struct attribute_group nvme - .is_bin_visible = nvmem_bin_attr_is_visible, - }; - --/* Cell attributes will be dynamically allocated */ --static struct attribute_group nvmem_cells_group = { -- .name = "cells", --}; -- - static const struct attribute_group *nvmem_dev_groups[] = { - &nvmem_bin_group, - NULL, -@@ -424,23 +419,24 @@ static void nvmem_sysfs_remove_compat(st - - static int nvmem_populate_sysfs_cells(struct nvmem_device *nvmem) - { -- struct bin_attribute **cells_attrs, *attrs; -+ struct attribute_group group = { -+ .name = "cells", -+ }; - struct nvmem_cell_entry *entry; -+ struct bin_attribute *attrs; - unsigned int ncells = 0, i = 0; - int ret = 0; - - mutex_lock(&nvmem_mutex); - -- if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) { -- nvmem_cells_group.bin_attrs = NULL; -+ if (list_empty(&nvmem->cells) || nvmem->sysfs_cells_populated) - goto unlock_mutex; -- } - - /* Allocate an array of attributes with a sentinel */ - ncells = list_count_nodes(&nvmem->cells); -- cells_attrs = devm_kcalloc(&nvmem->dev, ncells + 1, -- sizeof(struct bin_attribute *), GFP_KERNEL); -- if (!cells_attrs) { -+ group.bin_attrs = devm_kcalloc(&nvmem->dev, ncells + 1, -+ sizeof(struct bin_attribute *), GFP_KERNEL); -+ if (!group.bin_attrs) { - ret = -ENOMEM; - goto unlock_mutex; - } -@@ -466,13 +462,11 @@ static int nvmem_populate_sysfs_cells(st - goto unlock_mutex; - } - -- cells_attrs[i] = &attrs[i]; -+ group.bin_attrs[i] = &attrs[i]; - i++; - } - -- nvmem_cells_group.bin_attrs = cells_attrs; -- -- ret = device_add_group(&nvmem->dev, &nvmem_cells_group); -+ ret = device_add_group(&nvmem->dev, &group); - if (ret) - goto unlock_mutex; - diff --git a/target/linux/generic/backport-6.1/840-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch b/target/linux/generic/backport-6.1/840-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch deleted file mode 100644 index 9b6251b919eba9..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0008-nvmem-core-drop-unnecessary-range-checks-in-sysfs-ca.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 588773802c386d38f9c4e91acd47369e89d95a30 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= -Date: Fri, 5 Jul 2024 08:48:48 +0100 -Subject: [PATCH] nvmem: core: drop unnecessary range checks in sysfs callbacks -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The same checks have already been done in sysfs_kf_bin_write() and -sysfs_kf_bin_read() just before the callbacks are invoked. - -Signed-off-by: Thomas Weißschuh -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-12-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 14 -------------- - 1 file changed, 14 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -204,19 +204,12 @@ static ssize_t bin_attr_nvmem_read(struc - dev = kobj_to_dev(kobj); - nvmem = to_nvmem_device(dev); - -- /* Stop the user from reading */ -- if (pos >= nvmem->size) -- return 0; -- - if (!IS_ALIGNED(pos, nvmem->stride)) - return -EINVAL; - - if (count < nvmem->word_size) - return -EINVAL; - -- if (pos + count > nvmem->size) -- count = nvmem->size - pos; -- - count = round_down(count, nvmem->word_size); - - if (!nvmem->reg_read) -@@ -244,19 +237,12 @@ static ssize_t bin_attr_nvmem_write(stru - dev = kobj_to_dev(kobj); - nvmem = to_nvmem_device(dev); - -- /* Stop the user from writing */ -- if (pos >= nvmem->size) -- return -EFBIG; -- - if (!IS_ALIGNED(pos, nvmem->stride)) - return -EINVAL; - - if (count < nvmem->word_size) - return -EINVAL; - -- if (pos + count > nvmem->size) -- count = nvmem->size - pos; -- - count = round_down(count, nvmem->word_size); - - if (!nvmem->reg_write) diff --git a/target/linux/generic/backport-6.1/840-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch b/target/linux/generic/backport-6.1/840-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch deleted file mode 100644 index 3da1febaf10453..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0009-nvmem-Use-sysfs_emit-for-type-attribute.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 08c367e45b6d322956878774f0b88bf5e52c6d54 Mon Sep 17 00:00:00 2001 -From: Marek Vasut -Date: Fri, 5 Jul 2024 08:48:51 +0100 -Subject: [PATCH] nvmem: Use sysfs_emit() for type attribute - -Use sysfs_emit() instead of sprintf() to follow best practice per -Documentation/filesystems/sysfs.rst -" -show() should only use sysfs_emit()... -" - -Signed-off-by: Marek Vasut -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-15-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -180,7 +180,7 @@ static ssize_t type_show(struct device * - { - struct nvmem_device *nvmem = to_nvmem_device(dev); - -- return sprintf(buf, "%s\n", nvmem_type_str[nvmem->type]); -+ return sysfs_emit(buf, "%s\n", nvmem_type_str[nvmem->type]); - } - - static DEVICE_ATTR_RO(type); diff --git a/target/linux/generic/backport-6.1/840-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch b/target/linux/generic/backport-6.1/840-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch deleted file mode 100644 index ac7dda1bdf4298..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0010-nvmem-core-Implement-force_ro-sysfs-attribute.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 9d7eb234ac7a56b88aea8a52ed81553a730fe25c Mon Sep 17 00:00:00 2001 -From: Marek Vasut -Date: Fri, 5 Jul 2024 08:48:52 +0100 -Subject: [PATCH] nvmem: core: Implement force_ro sysfs attribute - -Implement "force_ro" sysfs attribute to allow users to set read-write -devices as read-only and back to read-write from userspace. The choice -of the name is based on MMC core 'force_ro' attribute. - -This solves a situation where an AT24 I2C EEPROM with GPIO based nWP -signal may have to be occasionally updated. Such I2C EEPROM device is -usually set as read-only during most of the regular system operation, -but in case it has to be updated in a controlled manner, it could be -unlocked using this new "force_ro" sysfs attribute and then re-locked -again. - -The "read-only" DT property and config->read_only configuration is -respected and is used to set default state of the device, read-only -or read-write, for devices which do implement .reg_write function. -For devices which do not implement .reg_write function, the device -is unconditionally read-only and the "force_ro" attribute is not -visible. - -Signed-off-by: Marek Vasut -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240705074852.423202-16-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - Documentation/ABI/stable/sysfs-bus-nvmem | 17 ++++++++++ - drivers/nvmem/core.c | 43 ++++++++++++++++++++++++ - 2 files changed, 60 insertions(+) - ---- a/Documentation/ABI/stable/sysfs-bus-nvmem -+++ b/Documentation/ABI/stable/sysfs-bus-nvmem -@@ -1,3 +1,20 @@ -+What: /sys/bus/nvmem/devices/.../force_ro -+Date: June 2024 -+KernelVersion: 6.11 -+Contact: Marek Vasut -+Description: -+ This read/write attribute allows users to set read-write -+ devices as read-only and back to read-write from userspace. -+ This can be used to unlock and relock write-protection of -+ devices which are generally locked, except during sporadic -+ programming operation. -+ Read returns '0' or '1' for read-write or read-only modes -+ respectively. -+ Write parses one of 'YyTt1NnFf0', or [oO][NnFf] for "on" -+ and "off", i.e. what kstrbool() supports. -+ Note: This file is only present if CONFIG_NVMEM_SYSFS -+ is enabled. -+ - What: /sys/bus/nvmem/devices/.../nvmem - Date: July 2015 - KernelVersion: 4.2 ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -185,7 +185,30 @@ static ssize_t type_show(struct device * - - static DEVICE_ATTR_RO(type); - -+static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct nvmem_device *nvmem = to_nvmem_device(dev); -+ -+ return sysfs_emit(buf, "%d\n", nvmem->read_only); -+} -+ -+static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct nvmem_device *nvmem = to_nvmem_device(dev); -+ int ret = kstrtobool(buf, &nvmem->read_only); -+ -+ if (ret < 0) -+ return ret; -+ -+ return count; -+} -+ -+static DEVICE_ATTR_RW(force_ro); -+ - static struct attribute *nvmem_attrs[] = { -+ &dev_attr_force_ro.attr, - &dev_attr_type.attr, - NULL, - }; -@@ -286,6 +309,25 @@ static umode_t nvmem_bin_attr_is_visible - return nvmem_bin_attr_get_umode(nvmem); - } - -+static umode_t nvmem_attr_is_visible(struct kobject *kobj, -+ struct attribute *attr, int i) -+{ -+ struct device *dev = kobj_to_dev(kobj); -+ struct nvmem_device *nvmem = to_nvmem_device(dev); -+ -+ /* -+ * If the device has no .reg_write operation, do not allow -+ * configuration as read-write. -+ * If the device is set as read-only by configuration, it -+ * can be forced into read-write mode using the 'force_ro' -+ * attribute. -+ */ -+ if (attr == &dev_attr_force_ro.attr && !nvmem->reg_write) -+ return 0; /* Attribute not visible */ -+ -+ return attr->mode; -+} -+ - static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, - const char *id, int index); - -@@ -342,6 +384,7 @@ static const struct attribute_group nvme - .bin_attrs = nvmem_bin_attributes, - .attrs = nvmem_attrs, - .is_bin_visible = nvmem_bin_attr_is_visible, -+ .is_visible = nvmem_attr_is_visible, - }; - - static const struct attribute_group *nvmem_dev_groups[] = { diff --git a/target/linux/generic/backport-6.1/840-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch b/target/linux/generic/backport-6.1/840-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch deleted file mode 100644 index 70d420f205fb63..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0011-nvmem-u-boot-env-error-if-NVMEM-device-is-too-small.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 8679e8b4a1ebdb40c4429e49368d29353e07b601 Mon Sep 17 00:00:00 2001 -From: John Thomson -Date: Mon, 2 Sep 2024 15:25:08 +0100 -Subject: [PATCH] nvmem: u-boot-env: error if NVMEM device is too small -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Verify data size before trying to parse it to avoid reading out of -buffer. This could happen in case of problems at MTD level or invalid DT -bindings. - -Signed-off-by: John Thomson -Cc: stable -Fixes: d5542923f200 ("nvmem: add driver handling U-Boot environment variables") -[rmilecki: simplify commit description & rebase] -Signed-off-by: Rafał Miłecki -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240902142510.71096-2-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/u-boot-env.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -176,6 +176,13 @@ static int u_boot_env_parse(struct u_boo - data_offset = offsetof(struct u_boot_env_image_broadcom, data); - break; - } -+ -+ if (dev_size < data_offset) { -+ dev_err(dev, "Device too small for u-boot-env\n"); -+ err = -EIO; -+ goto err_kfree; -+ } -+ - crc32_addr = (__le32 *)(buf + crc32_offset); - crc32 = le32_to_cpu(*crc32_addr); - crc32_data_len = dev_size - crc32_data_offset; diff --git a/target/linux/generic/backport-6.1/840-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch b/target/linux/generic/backport-6.1/840-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch deleted file mode 100644 index 08f627884993ca..00000000000000 --- a/target/linux/generic/backport-6.1/840-v6.11-0012-nvmem-Fix-return-type-of-devm_nvmem_device_get-in-ke.patch +++ /dev/null @@ -1,37 +0,0 @@ -From c69f37f6559a8948d70badd2b179db7714dedd62 Mon Sep 17 00:00:00 2001 -From: Geert Uytterhoeven -Date: Mon, 2 Sep 2024 15:25:09 +0100 -Subject: [PATCH] nvmem: Fix return type of devm_nvmem_device_get() in - kerneldoc - -devm_nvmem_device_get() returns an nvmem device, not an nvmem cell. - -Fixes: e2a5402ec7c6d044 ("nvmem: Add nvmem_device based consumer apis.") -Cc: stable -Signed-off-by: Geert Uytterhoeven -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240902142510.71096-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/core.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -1276,13 +1276,13 @@ void nvmem_device_put(struct nvmem_devic - EXPORT_SYMBOL_GPL(nvmem_device_put); - - /** -- * devm_nvmem_device_get() - Get nvmem cell of device form a given id -+ * devm_nvmem_device_get() - Get nvmem device of device form a given id - * - * @dev: Device that requests the nvmem device. - * @id: name id for the requested nvmem device. - * -- * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_cell -- * on success. The nvmem_cell will be freed by the automatically once the -+ * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device -+ * on success. The nvmem_device will be freed by the automatically once the - * device is freed. - */ - struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id) diff --git a/target/linux/generic/backport-6.1/841-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch b/target/linux/generic/backport-6.1/841-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch deleted file mode 100644 index c19931b3fa01e6..00000000000000 --- a/target/linux/generic/backport-6.1/841-v6.12-0001-nvmem-imx-ocotp-ele-support-i.MX95.patch +++ /dev/null @@ -1,73 +0,0 @@ -From c3f9b7b4e5f9de319d00784577cda42036ff243a Mon Sep 17 00:00:00 2001 -From: Peng Fan -Date: Mon, 2 Sep 2024 15:29:45 +0100 -Subject: [PATCH] nvmem: imx-ocotp-ele: support i.MX95 - -i.MX95 OCOTP has same accessing method, so add an entry for i.MX95, but -some fuse has ECC feature, so only read out the lower 16bits for ECC fuses. - -Signed-off-by: Peng Fan -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240902142952.71639-3-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/imx-ocotp-ele.c | 32 +++++++++++++++++++++++++++++--- - 1 file changed, 29 insertions(+), 3 deletions(-) - ---- a/drivers/nvmem/imx-ocotp-ele.c -+++ b/drivers/nvmem/imx-ocotp-ele.c -@@ -14,8 +14,9 @@ - #include - - enum fuse_type { -- FUSE_FSB = 1, -- FUSE_ELE = 2, -+ FUSE_FSB = BIT(0), -+ FUSE_ELE = BIT(1), -+ FUSE_ECC = BIT(2), - FUSE_INVALID = -1 - }; - -@@ -93,7 +94,10 @@ static int imx_ocotp_reg_read(void *cont - continue; - } - -- *buf++ = readl_relaxed(reg + (i << 2)); -+ if (type & FUSE_ECC) -+ *buf++ = readl_relaxed(reg + (i << 2)) & GENMASK(15, 0); -+ else -+ *buf++ = readl_relaxed(reg + (i << 2)); - } - - memcpy(val, (u8 *)p, bytes); -@@ -155,8 +159,30 @@ static const struct ocotp_devtype_data i - }, - }; - -+static const struct ocotp_devtype_data imx95_ocotp_data = { -+ .reg_off = 0x8000, -+ .reg_read = imx_ocotp_reg_read, -+ .size = 2048, -+ .num_entry = 12, -+ .entry = { -+ { 0, 1, FUSE_FSB | FUSE_ECC }, -+ { 7, 1, FUSE_FSB | FUSE_ECC }, -+ { 9, 3, FUSE_FSB | FUSE_ECC }, -+ { 12, 24, FUSE_FSB }, -+ { 36, 2, FUSE_FSB | FUSE_ECC }, -+ { 38, 14, FUSE_FSB }, -+ { 63, 1, FUSE_ELE }, -+ { 128, 16, FUSE_ELE }, -+ { 188, 1, FUSE_ELE }, -+ { 317, 2, FUSE_FSB | FUSE_ECC }, -+ { 320, 7, FUSE_FSB }, -+ { 328, 184, FUSE_FSB } -+ }, -+}; -+ - static const struct of_device_id imx_ele_ocotp_dt_ids[] = { - { .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, }, -+ { .compatible = "fsl,imx95-ocotp", .data = &imx95_ocotp_data, }, - {}, - }; - MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids); diff --git a/target/linux/generic/backport-6.1/841-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch b/target/linux/generic/backport-6.1/841-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch deleted file mode 100644 index 13ef50b1579600..00000000000000 --- a/target/linux/generic/backport-6.1/841-v6.12-0002-nvmem-sunplus-ocotp-Use-devm_platform_ioremap_resour.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 98ee46391baf35987227236d0c3bb30ab6e758c8 Mon Sep 17 00:00:00 2001 -From: Zhang Zekun -Date: Mon, 2 Sep 2024 15:29:50 +0100 -Subject: [PATCH] nvmem: sunplus-ocotp: Use - devm_platform_ioremap_resource_byname() helper function - -platform_get_resource_byname() and devm_ioremap_resource() can be -replaced by devm_platform_ioremap_resource_byname(), which can -simplify the code logic a bit, No functional change here. - -Signed-off-by: Zhang Zekun -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240902142952.71639-8-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - drivers/nvmem/sunplus-ocotp.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - ---- a/drivers/nvmem/sunplus-ocotp.c -+++ b/drivers/nvmem/sunplus-ocotp.c -@@ -159,7 +159,6 @@ static int sp_ocotp_probe(struct platfor - struct device *dev = &pdev->dev; - struct nvmem_device *nvmem; - struct sp_ocotp_priv *otp; -- struct resource *res; - int ret; - - otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL); -@@ -168,13 +167,11 @@ static int sp_ocotp_probe(struct platfor - - otp->dev = dev; - -- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hb_gpio"); -- otp->base[HB_GPIO] = devm_ioremap_resource(dev, res); -+ otp->base[HB_GPIO] = devm_platform_ioremap_resource_byname(pdev, "hb_gpio"); - if (IS_ERR(otp->base[HB_GPIO])) - return PTR_ERR(otp->base[HB_GPIO]); - -- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otprx"); -- otp->base[OTPRX] = devm_ioremap_resource(dev, res); -+ otp->base[OTPRX] = devm_platform_ioremap_resource_byname(pdev, "otprx"); - if (IS_ERR(otp->base[OTPRX])) - return PTR_ERR(otp->base[OTPRX]); - diff --git a/target/linux/generic/backport-6.1/841-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch b/target/linux/generic/backport-6.1/841-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch deleted file mode 100644 index e711c84c8d0790..00000000000000 --- a/target/linux/generic/backport-6.1/841-v6.12-0003-nvmem-layouts-add-U-Boot-env-layout.patch +++ /dev/null @@ -1,525 +0,0 @@ -From 5f15811286aff4664bf275a7ede64e1b8858151b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 2 Sep 2024 15:29:47 +0100 -Subject: [PATCH] nvmem: layouts: add U-Boot env layout -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -U-Boot environment variables are stored in a specific format. Actual -data can be placed in various storage sources (MTD, UBI volume, EEPROM, -NVRAM, etc.). - -Move all generic (NVMEM device independent) code from NVMEM device -driver to an NVMEM layout driver. Then add a simple NVMEM layout code on -top of it. - -This allows using NVMEM layout for parsing U-Boot env data stored in any -kind of NVMEM device. - -The old NVMEM glue driver stays in place for handling bindings in the -MTD context. To avoid code duplication it uses exported layout parsing -function. Please note that handling MTD & NVMEM layout bindings may be -refactored in the future. - -Signed-off-by: Rafał Miłecki -Reviewed-by: Miquel Raynal -Signed-off-by: Srinivas Kandagatla -Link: https://lore.kernel.org/r/20240902142952.71639-5-srinivas.kandagatla@linaro.org -Signed-off-by: Greg Kroah-Hartman ---- - MAINTAINERS | 1 + - drivers/nvmem/Kconfig | 3 +- - drivers/nvmem/layouts/Kconfig | 11 ++ - drivers/nvmem/layouts/Makefile | 1 + - drivers/nvmem/layouts/u-boot-env.c | 211 +++++++++++++++++++++++++++++ - drivers/nvmem/layouts/u-boot-env.h | 15 ++ - drivers/nvmem/u-boot-env.c | 165 +--------------------- - 7 files changed, 242 insertions(+), 165 deletions(-) - create mode 100644 drivers/nvmem/layouts/u-boot-env.c - create mode 100644 drivers/nvmem/layouts/u-boot-env.h - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -21033,6 +21033,7 @@ U-BOOT ENVIRONMENT VARIABLES - M: Rafał Miłecki - S: Maintained - F: Documentation/devicetree/bindings/nvmem/u-boot,env.yaml -+F: drivers/nvmem/layouts/u-boot-env.c - F: drivers/nvmem/u-boot-env.c - - UACCE ACCELERATOR FRAMEWORK ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -363,8 +363,7 @@ config NVMEM_SUNXI_SID - config NVMEM_U_BOOT_ENV - tristate "U-Boot environment variables support" - depends on OF && MTD -- select CRC32 -- select GENERIC_NET_UTILS -+ select NVMEM_LAYOUT_U_BOOT_ENV - help - U-Boot stores its setup as environment variables. This driver adds - support for verifying & exporting such data. It also exposes variables ---- a/drivers/nvmem/layouts/Kconfig -+++ b/drivers/nvmem/layouts/Kconfig -@@ -26,6 +26,17 @@ config NVMEM_LAYOUT_ONIE_TLV - - If unsure, say N. - -+config NVMEM_LAYOUT_U_BOOT_ENV -+ tristate "U-Boot environment variables layout" -+ select CRC32 -+ select GENERIC_NET_UTILS -+ help -+ U-Boot stores its setup as environment variables. This driver adds -+ support for verifying & exporting such data. It also exposes variables -+ as NVMEM cells so they can be referenced by other drivers. -+ -+ If unsure, say N. -+ - endmenu - - endif ---- a/drivers/nvmem/layouts/Makefile -+++ b/drivers/nvmem/layouts/Makefile -@@ -5,3 +5,4 @@ - - obj-$(CONFIG_NVMEM_LAYOUT_SL28_VPD) += sl28vpd.o - obj-$(CONFIG_NVMEM_LAYOUT_ONIE_TLV) += onie-tlv.o -+obj-$(CONFIG_NVMEM_LAYOUT_U_BOOT_ENV) += u-boot-env.o ---- /dev/null -+++ b/drivers/nvmem/layouts/u-boot-env.c -@@ -0,0 +1,211 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Copyright (C) 2022 - 2023 Rafał Miłecki -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "u-boot-env.h" -+ -+struct u_boot_env_image_single { -+ __le32 crc32; -+ uint8_t data[]; -+} __packed; -+ -+struct u_boot_env_image_redundant { -+ __le32 crc32; -+ u8 mark; -+ uint8_t data[]; -+} __packed; -+ -+struct u_boot_env_image_broadcom { -+ __le32 magic; -+ __le32 len; -+ __le32 crc32; -+ DECLARE_FLEX_ARRAY(uint8_t, data); -+} __packed; -+ -+static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, -+ unsigned int offset, void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (bytes != 3 * ETH_ALEN - 1) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ -+static int u_boot_env_parse_cells(struct device *dev, struct nvmem_device *nvmem, uint8_t *buf, -+ size_t data_offset, size_t data_len) -+{ -+ char *data = buf + data_offset; -+ char *var, *value, *eq; -+ -+ for (var = data; -+ var < data + data_len && *var; -+ var = value + strlen(value) + 1) { -+ struct nvmem_cell_info info = {}; -+ -+ eq = strchr(var, '='); -+ if (!eq) -+ break; -+ *eq = '\0'; -+ value = eq + 1; -+ -+ info.name = devm_kstrdup(dev, var, GFP_KERNEL); -+ if (!info.name) -+ return -ENOMEM; -+ info.offset = data_offset + value - data; -+ info.bytes = strlen(value); -+ info.np = of_get_child_by_name(dev->of_node, info.name); -+ if (!strcmp(var, "ethaddr")) { -+ info.raw_len = strlen(value); -+ info.bytes = ETH_ALEN; -+ info.read_post_process = u_boot_env_read_post_process_ethaddr; -+ } -+ -+ nvmem_add_one_cell(nvmem, &info); -+ } -+ -+ return 0; -+} -+ -+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem, -+ enum u_boot_env_format format) -+{ -+ size_t crc32_data_offset; -+ size_t crc32_data_len; -+ size_t crc32_offset; -+ __le32 *crc32_addr; -+ size_t data_offset; -+ size_t data_len; -+ size_t dev_size; -+ uint32_t crc32; -+ uint32_t calc; -+ uint8_t *buf; -+ int bytes; -+ int err; -+ -+ dev_size = nvmem_dev_size(nvmem); -+ -+ buf = kzalloc(dev_size, GFP_KERNEL); -+ if (!buf) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ -+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf); -+ if (bytes < 0) { -+ err = bytes; -+ goto err_kfree; -+ } else if (bytes != dev_size) { -+ err = -EIO; -+ goto err_kfree; -+ } -+ -+ switch (format) { -+ case U_BOOT_FORMAT_SINGLE: -+ crc32_offset = offsetof(struct u_boot_env_image_single, crc32); -+ crc32_data_offset = offsetof(struct u_boot_env_image_single, data); -+ data_offset = offsetof(struct u_boot_env_image_single, data); -+ break; -+ case U_BOOT_FORMAT_REDUNDANT: -+ crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32); -+ crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); -+ data_offset = offsetof(struct u_boot_env_image_redundant, data); -+ break; -+ case U_BOOT_FORMAT_BROADCOM: -+ crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32); -+ crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data); -+ data_offset = offsetof(struct u_boot_env_image_broadcom, data); -+ break; -+ } -+ -+ if (dev_size < data_offset) { -+ dev_err(dev, "Device too small for u-boot-env\n"); -+ err = -EIO; -+ goto err_kfree; -+ } -+ -+ crc32_addr = (__le32 *)(buf + crc32_offset); -+ crc32 = le32_to_cpu(*crc32_addr); -+ crc32_data_len = dev_size - crc32_data_offset; -+ data_len = dev_size - data_offset; -+ -+ calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; -+ if (calc != crc32) { -+ dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); -+ err = -EINVAL; -+ goto err_kfree; -+ } -+ -+ buf[dev_size - 1] = '\0'; -+ err = u_boot_env_parse_cells(dev, nvmem, buf, data_offset, data_len); -+ -+err_kfree: -+ kfree(buf); -+err_out: -+ return err; -+} -+EXPORT_SYMBOL_GPL(u_boot_env_parse); -+ -+static int u_boot_env_add_cells(struct nvmem_layout *layout) -+{ -+ struct device *dev = &layout->dev; -+ enum u_boot_env_format format; -+ -+ format = (uintptr_t)device_get_match_data(dev); -+ -+ return u_boot_env_parse(dev, layout->nvmem, format); -+} -+ -+static int u_boot_env_probe(struct nvmem_layout *layout) -+{ -+ layout->add_cells = u_boot_env_add_cells; -+ -+ return nvmem_layout_register(layout); -+} -+ -+static void u_boot_env_remove(struct nvmem_layout *layout) -+{ -+ nvmem_layout_unregister(layout); -+} -+ -+static const struct of_device_id u_boot_env_of_match_table[] = { -+ { .compatible = "u-boot,env", .data = (void *)U_BOOT_FORMAT_SINGLE, }, -+ { .compatible = "u-boot,env-redundant-bool", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, -+ { .compatible = "u-boot,env-redundant-count", .data = (void *)U_BOOT_FORMAT_REDUNDANT, }, -+ { .compatible = "brcm,env", .data = (void *)U_BOOT_FORMAT_BROADCOM, }, -+ {}, -+}; -+ -+static struct nvmem_layout_driver u_boot_env_layout = { -+ .driver = { -+ .name = "u-boot-env-layout", -+ .of_match_table = u_boot_env_of_match_table, -+ }, -+ .probe = u_boot_env_probe, -+ .remove = u_boot_env_remove, -+}; -+module_nvmem_layout_driver(u_boot_env_layout); -+ -+MODULE_AUTHOR("Rafał Miłecki"); -+MODULE_LICENSE("GPL"); -+MODULE_DEVICE_TABLE(of, u_boot_env_of_match_table); -+MODULE_DESCRIPTION("NVMEM layout driver for U-Boot environment variables"); ---- /dev/null -+++ b/drivers/nvmem/layouts/u-boot-env.h -@@ -0,0 +1,15 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H -+#define _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H -+ -+enum u_boot_env_format { -+ U_BOOT_FORMAT_SINGLE, -+ U_BOOT_FORMAT_REDUNDANT, -+ U_BOOT_FORMAT_BROADCOM, -+}; -+ -+int u_boot_env_parse(struct device *dev, struct nvmem_device *nvmem, -+ enum u_boot_env_format format); -+ -+#endif /* ifndef _LINUX_NVMEM_LAYOUTS_U_BOOT_ENV_H */ ---- a/drivers/nvmem/u-boot-env.c -+++ b/drivers/nvmem/u-boot-env.c -@@ -3,23 +3,15 @@ - * Copyright (C) 2022 Rafał Miłecki - */ - --#include --#include --#include - #include - #include - #include --#include - #include - #include - #include - #include - --enum u_boot_env_format { -- U_BOOT_FORMAT_SINGLE, -- U_BOOT_FORMAT_REDUNDANT, -- U_BOOT_FORMAT_BROADCOM, --}; -+#include "layouts/u-boot-env.h" - - struct u_boot_env { - struct device *dev; -@@ -29,24 +21,6 @@ struct u_boot_env { - struct mtd_info *mtd; - }; - --struct u_boot_env_image_single { -- __le32 crc32; -- uint8_t data[]; --} __packed; -- --struct u_boot_env_image_redundant { -- __le32 crc32; -- u8 mark; -- uint8_t data[]; --} __packed; -- --struct u_boot_env_image_broadcom { -- __le32 magic; -- __le32 len; -- __le32 crc32; -- DECLARE_FLEX_ARRAY(uint8_t, data); --} __packed; -- - static int u_boot_env_read(void *context, unsigned int offset, void *val, - size_t bytes) - { -@@ -69,141 +43,6 @@ static int u_boot_env_read(void *context - return 0; - } - --static int u_boot_env_read_post_process_ethaddr(void *context, const char *id, int index, -- unsigned int offset, void *buf, size_t bytes) --{ -- u8 mac[ETH_ALEN]; -- -- if (bytes != 3 * ETH_ALEN - 1) -- return -EINVAL; -- -- if (!mac_pton(buf, mac)) -- return -EINVAL; -- -- if (index) -- eth_addr_add(mac, index); -- -- ether_addr_copy(buf, mac); -- -- return 0; --} -- --static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf, -- size_t data_offset, size_t data_len) --{ -- struct nvmem_device *nvmem = priv->nvmem; -- struct device *dev = priv->dev; -- char *data = buf + data_offset; -- char *var, *value, *eq; -- -- for (var = data; -- var < data + data_len && *var; -- var = value + strlen(value) + 1) { -- struct nvmem_cell_info info = {}; -- -- eq = strchr(var, '='); -- if (!eq) -- break; -- *eq = '\0'; -- value = eq + 1; -- -- info.name = devm_kstrdup(dev, var, GFP_KERNEL); -- if (!info.name) -- return -ENOMEM; -- info.offset = data_offset + value - data; -- info.bytes = strlen(value); -- info.np = of_get_child_by_name(dev->of_node, info.name); -- if (!strcmp(var, "ethaddr")) { -- info.raw_len = strlen(value); -- info.bytes = ETH_ALEN; -- info.read_post_process = u_boot_env_read_post_process_ethaddr; -- } -- -- nvmem_add_one_cell(nvmem, &info); -- } -- -- return 0; --} -- --static int u_boot_env_parse(struct u_boot_env *priv) --{ -- struct nvmem_device *nvmem = priv->nvmem; -- struct device *dev = priv->dev; -- size_t crc32_data_offset; -- size_t crc32_data_len; -- size_t crc32_offset; -- __le32 *crc32_addr; -- size_t data_offset; -- size_t data_len; -- size_t dev_size; -- uint32_t crc32; -- uint32_t calc; -- uint8_t *buf; -- int bytes; -- int err; -- -- dev_size = nvmem_dev_size(nvmem); -- -- buf = kzalloc(dev_size, GFP_KERNEL); -- if (!buf) { -- err = -ENOMEM; -- goto err_out; -- } -- -- bytes = nvmem_device_read(nvmem, 0, dev_size, buf); -- if (bytes < 0) { -- err = bytes; -- goto err_kfree; -- } else if (bytes != dev_size) { -- err = -EIO; -- goto err_kfree; -- } -- -- switch (priv->format) { -- case U_BOOT_FORMAT_SINGLE: -- crc32_offset = offsetof(struct u_boot_env_image_single, crc32); -- crc32_data_offset = offsetof(struct u_boot_env_image_single, data); -- data_offset = offsetof(struct u_boot_env_image_single, data); -- break; -- case U_BOOT_FORMAT_REDUNDANT: -- crc32_offset = offsetof(struct u_boot_env_image_redundant, crc32); -- crc32_data_offset = offsetof(struct u_boot_env_image_redundant, data); -- data_offset = offsetof(struct u_boot_env_image_redundant, data); -- break; -- case U_BOOT_FORMAT_BROADCOM: -- crc32_offset = offsetof(struct u_boot_env_image_broadcom, crc32); -- crc32_data_offset = offsetof(struct u_boot_env_image_broadcom, data); -- data_offset = offsetof(struct u_boot_env_image_broadcom, data); -- break; -- } -- -- if (dev_size < data_offset) { -- dev_err(dev, "Device too small for u-boot-env\n"); -- err = -EIO; -- goto err_kfree; -- } -- -- crc32_addr = (__le32 *)(buf + crc32_offset); -- crc32 = le32_to_cpu(*crc32_addr); -- crc32_data_len = dev_size - crc32_data_offset; -- data_len = dev_size - data_offset; -- -- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; -- if (calc != crc32) { -- dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); -- err = -EINVAL; -- goto err_kfree; -- } -- -- buf[dev_size - 1] = '\0'; -- err = u_boot_env_add_cells(priv, buf, data_offset, data_len); -- --err_kfree: -- kfree(buf); --err_out: -- return err; --} -- - static int u_boot_env_probe(struct platform_device *pdev) - { - struct nvmem_config config = { -@@ -235,7 +74,7 @@ static int u_boot_env_probe(struct platf - if (IS_ERR(priv->nvmem)) - return PTR_ERR(priv->nvmem); - -- return u_boot_env_parse(priv); -+ return u_boot_env_parse(dev, priv->nvmem, priv->format); - } - - static const struct of_device_id u_boot_env_of_match_table[] = { diff --git a/target/linux/generic/backport-6.1/850-v6.2-bus-mhi-host-pci_generic-add-support-for-sc8280xp-cr.patch b/target/linux/generic/backport-6.1/850-v6.2-bus-mhi-host-pci_generic-add-support-for-sc8280xp-cr.patch deleted file mode 100644 index 1bf5196790b56a..00000000000000 --- a/target/linux/generic/backport-6.1/850-v6.2-bus-mhi-host-pci_generic-add-support-for-sc8280xp-cr.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a38a6e5d2dc41feeaa839cd61196f86c0ee223b8 Mon Sep 17 00:00:00 2001 -From: Johan Hovold -Date: Fri, 4 Nov 2022 10:39:13 +0100 -Subject: [PATCH 01/13] bus: mhi: host: pci_generic: add support for - sc8280xp-crd SDX55 variant - -The SC8280XP Compute Reference Design (CRD) has an on-PCB SDX55 modem -which uses MBIM. - -The exact channel configuration is not known but the Foxconn SDX55 -configuration allows the modem to be used so reuse that one for now. - -Signed-off-by: Johan Hovold -Reviewed-by: Manivannan Sadhasivam -Link: https://lore.kernel.org/r/20221104093913.23347-1-johan+linaro@kernel.org -[mani: modified the subject to format "bus: mhi: host"] -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -542,6 +542,8 @@ static const struct mhi_pci_dev_info mhi - static const struct pci_device_id mhi_pci_id_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304), - .driver_data = (kernel_ulong_t) &mhi_qcom_sdx24_info }, -+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, PCI_VENDOR_ID_QCOM, 0x010c), -+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info }, - /* EM919x (sdx55), use the same vid:pid as qcom-sdx55m */ - { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, 0x18d7, 0x0200), - .driver_data = (kernel_ulong_t) &mhi_sierra_em919x_info }, diff --git a/target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch b/target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch deleted file mode 100644 index 6f9fc71a710956..00000000000000 --- a/target/linux/generic/backport-6.1/851-v6.2-bus-mhi-host-pci_generic-Add-HP-variant-of-T99W175.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 6a150325917a6df9467beeaa6518ab91ada81d97 Mon Sep 17 00:00:00 2001 -From: Song Fuchang -Date: Mon, 7 Nov 2022 19:18:35 +0530 -Subject: [PATCH 02/13] bus: mhi: host: pci_generic: Add HP variant of T99W175 - -The Foxconn T99W175 modem has an HP variant, which has -the following output from lspci: - -01:00.0 Wireless controller [0d40]: Device 03f0:0a6c - -It also has some HP-specific serial numbers on the -metal case. It works well with this driver, so add -support for this to the pci_generic driver. - -Signed-off-by: Song Fuchang -Reviewed-by: Manivannan Sadhasivam -[mani: manually applied the patch] -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -599,6 +599,9 @@ static const struct pci_device_id mhi_pc - /* MV32-WB (Cinterion) */ - { PCI_DEVICE(0x1269, 0x00bb), - .driver_data = (kernel_ulong_t) &mhi_mv32_info }, -+ /* T99W175 (sdx55), HP variant */ -+ { PCI_DEVICE(0x03f0, 0x0a6c), -+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info }, - { } - }; - MODULE_DEVICE_TABLE(pci, mhi_pci_id_table); diff --git a/target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch b/target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch deleted file mode 100644 index 12419fbe397ec7..00000000000000 --- a/target/linux/generic/backport-6.1/852-v6.2-bus-mhi-host-pci_generic-Add-definition-for-some-VID.patch +++ /dev/null @@ -1,66 +0,0 @@ -From e8bc362f158f45185778e2bec081146aeeb283b5 Mon Sep 17 00:00:00 2001 -From: Slark Xiao -Date: Mon, 7 Nov 2022 19:27:00 +0800 -Subject: [PATCH 03/13] bus: mhi: host: pci_generic: Add definition for some - VIDs - -To make code neat and for convenience purpose, add definition for some -VIDs. Adding it locally until these VIDs are used in multiple places. - -Signed-off-by: Slark Xiao -Reviewed-by: Manivannan Sadhasivam -Link: https://lore.kernel.org/r/20221107112700.773-1-slark_xiao@163.com -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -24,6 +24,10 @@ - - #define HEALTH_CHECK_PERIOD (HZ * 2) - -+/* PCI VID definitions */ -+#define PCI_VENDOR_ID_THALES 0x1269 -+#define PCI_VENDOR_ID_QUECTEL 0x1eac -+ - /** - * struct mhi_pci_dev_info - MHI PCI device specific information - * @config: MHI controller configuration -@@ -560,11 +564,11 @@ static const struct pci_device_id mhi_pc - .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308), - .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info }, -- { PCI_DEVICE(0x1eac, 0x1001), /* EM120R-GL (sdx24) */ -+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1001), /* EM120R-GL (sdx24) */ - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, -- { PCI_DEVICE(0x1eac, 0x1002), /* EM160R-GL (sdx24) */ -+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */ - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, -- { PCI_DEVICE(0x1eac, 0x2001), /* EM120R-GL for FCCL (sdx24) */ -+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x2001), /* EM120R-GL for FCCL (sdx24) */ - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, - /* T99W175 (sdx55), Both for eSIM and Non-eSIM */ - { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0ab), -@@ -588,16 +592,16 @@ static const struct pci_device_id mhi_pc - { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d9), - .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info }, - /* MV31-W (Cinterion) */ -- { PCI_DEVICE(0x1269, 0x00b3), -+ { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b3), - .driver_data = (kernel_ulong_t) &mhi_mv31_info }, - /* MV31-W (Cinterion), based on new baseline */ -- { PCI_DEVICE(0x1269, 0x00b4), -+ { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b4), - .driver_data = (kernel_ulong_t) &mhi_mv31_info }, - /* MV32-WA (Cinterion) */ -- { PCI_DEVICE(0x1269, 0x00ba), -+ { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00ba), - .driver_data = (kernel_ulong_t) &mhi_mv32_info }, - /* MV32-WB (Cinterion) */ -- { PCI_DEVICE(0x1269, 0x00bb), -+ { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00bb), - .driver_data = (kernel_ulong_t) &mhi_mv32_info }, - /* T99W175 (sdx55), HP variant */ - { PCI_DEVICE(0x03f0, 0x0a6c), diff --git a/target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch b/target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch deleted file mode 100644 index 943227d2a809f6..00000000000000 --- a/target/linux/generic/backport-6.1/853-v6.2-bus-mhi-host-pci_generic-Drop-redundant-pci_enable_p.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 6c00e1e4e9817e85b8ba83024cfa88382f898841 Mon Sep 17 00:00:00 2001 -From: Bjorn Helgaas -Date: Tue, 7 Mar 2023 14:16:25 -0600 -Subject: [PATCH 04/13] bus: mhi: host: pci_generic: Drop redundant - pci_enable_pcie_error_reporting() - -pci_enable_pcie_error_reporting() enables the device to send ERR_* -Messages. Since commit ("PCI/AER: Enable error reporting -when AER is native"), the PCI core does this for all devices during -enumeration, so the driver doesn't need to do it itself. - -Remove the redundant pci_enable_pcie_error_reporting() call from the -driver. Also remove the corresponding pci_disable_pcie_error_reporting() -from the driver .remove() path. - -Note that this only controls ERR_* Messages from the device. An ERR_* -Message may cause the Root Port to generate an interrupt, depending on the -AER Root Error Command register managed by the AER service driver. - -Signed-off-by: Bjorn Helgaas -Reviewed-by: Manivannan Sadhasivam -Reviewed-by: Jeffrey Hugo -Link: https://lore.kernel.org/r/20230307201625.879567-1-helgaas@kernel.org -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -8,7 +8,6 @@ - * Copyright (C) 2020 Linaro Ltd - */ - --#include - #include - #include - #include -@@ -904,11 +903,9 @@ static int mhi_pci_probe(struct pci_dev - mhi_pdev->pci_state = pci_store_saved_state(pdev); - pci_load_saved_state(pdev, NULL); - -- pci_enable_pcie_error_reporting(pdev); -- - err = mhi_register_controller(mhi_cntrl, mhi_cntrl_config); - if (err) -- goto err_disable_reporting; -+ return err; - - /* MHI bus does not power up the controller by default */ - err = mhi_prepare_for_power_up(mhi_cntrl); -@@ -942,8 +939,6 @@ err_unprepare: - mhi_unprepare_after_power_down(mhi_cntrl); - err_unregister: - mhi_unregister_controller(mhi_cntrl); --err_disable_reporting: -- pci_disable_pcie_error_reporting(pdev); - - return err; - } -@@ -966,7 +961,6 @@ static void mhi_pci_remove(struct pci_de - pm_runtime_get_noresume(&pdev->dev); - - mhi_unregister_controller(mhi_cntrl); -- pci_disable_pcie_error_reporting(pdev); - } - - static void mhi_pci_shutdown(struct pci_dev *pdev) diff --git a/target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch b/target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch deleted file mode 100644 index 8ec6f3e76fe3e2..00000000000000 --- a/target/linux/generic/backport-6.1/854-v6.4-bus-mhi-pci_generic-Add-Foxconn-T99W510.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 537350abfcc6b639884d1ef7bff35d31a624549b Mon Sep 17 00:00:00 2001 -From: Slark Xiao -Date: Wed, 29 Mar 2023 15:22:39 +0800 -Subject: [PATCH 05/13] bus: mhi: pci_generic: Add Foxconn T99W510 - -The Foxconn T99W510 device is designed based on Qualcomm -SDX24. Add 3 variants for different potential customer. - -Signed-off-by: Slark Xiao -Link: https://lore.kernel.org/r/20230329072239.93632-1-slark_xiao@163.com -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -363,6 +363,15 @@ static const struct mhi_controller_confi - .event_cfg = mhi_foxconn_sdx55_events, - }; - -+static const struct mhi_pci_dev_info mhi_foxconn_sdx24_info = { -+ .name = "foxconn-sdx24", -+ .config = &modem_foxconn_sdx55_config, -+ .bar_num = MHI_PCI_DEFAULT_BAR_NUM, -+ .dma_data_width = 32, -+ .mru_default = 32768, -+ .sideband_wake = false, -+}; -+ - static const struct mhi_pci_dev_info mhi_foxconn_sdx55_info = { - .name = "foxconn-sdx55", - .fw = "qcom/sdx55m/sbl1.mbn", -@@ -590,6 +599,15 @@ static const struct pci_device_id mhi_pc - /* T99W373 (sdx62) */ - { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d9), - .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info }, -+ /* T99W510 (sdx24), variant 1 */ -+ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f0), -+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx24_info }, -+ /* T99W510 (sdx24), variant 2 */ -+ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f1), -+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx24_info }, -+ /* T99W510 (sdx24), variant 3 */ -+ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f2), -+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx24_info }, - /* MV31-W (Cinterion) */ - { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b3), - .driver_data = (kernel_ulong_t) &mhi_mv31_info }, diff --git a/target/linux/generic/backport-6.1/855-v6.6-bus-mhi-host-pci_generic-Add-support-for-IP_SW0-chan.patch b/target/linux/generic/backport-6.1/855-v6.6-bus-mhi-host-pci_generic-Add-support-for-IP_SW0-chan.patch deleted file mode 100644 index 8c319ebeb7a408..00000000000000 --- a/target/linux/generic/backport-6.1/855-v6.6-bus-mhi-host-pci_generic-Add-support-for-IP_SW0-chan.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 440b01a2a9a62352cfa355354d3a4de6c5d96adf Mon Sep 17 00:00:00 2001 -From: Manivannan Sadhasivam -Date: Fri, 19 May 2023 19:28:03 +0530 -Subject: [PATCH 06/13] bus: mhi: host: pci_generic: Add support for IP_SW0 - channels - -IP_SW0 channels are used to transfer data over the networking interface -between MHI endpoint and the host. Define the channels in the MHI v1 -channel config along with dedicated event rings. - -Reviewed-by: Loic Poulain -Link: https://lore.kernel.org/r/20230519135803.13850-1-manivannan.sadhasivam@linaro.org -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 26 ++++++++++++++++++++++---- - 1 file changed, 22 insertions(+), 4 deletions(-) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -212,6 +212,19 @@ struct mhi_pci_dev_info { - .offload_channel = false, \ - } - -+#define MHI_EVENT_CONFIG_SW_DATA(ev_ring, el_count) \ -+ { \ -+ .num_elements = el_count, \ -+ .irq_moderation_ms = 0, \ -+ .irq = (ev_ring) + 1, \ -+ .priority = 1, \ -+ .mode = MHI_DB_BRST_DISABLE, \ -+ .data_type = MHI_ER_DATA, \ -+ .hardware_event = false, \ -+ .client_managed = false, \ -+ .offload_channel = false, \ -+ } -+ - #define MHI_EVENT_CONFIG_HW_DATA(ev_ring, el_count, ch_num) \ - { \ - .num_elements = el_count, \ -@@ -237,8 +250,10 @@ static const struct mhi_channel_config m - MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 8, 0), - MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0), - MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), -- MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 2), -- MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 3), -+ MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 64, 2), -+ MHI_CHANNEL_CONFIG_DL(47, "IP_SW0", 64, 3), -+ MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 4), -+ MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 5), - }; - - static struct mhi_event_config modem_qcom_v1_mhi_events[] = { -@@ -246,9 +261,12 @@ static struct mhi_event_config modem_qco - MHI_EVENT_CONFIG_CTRL(0, 64), - /* DIAG dedicated event ring */ - MHI_EVENT_CONFIG_DATA(1, 128), -+ /* Software channels dedicated event ring */ -+ MHI_EVENT_CONFIG_SW_DATA(2, 64), -+ MHI_EVENT_CONFIG_SW_DATA(3, 64), - /* Hardware channels request dedicated hardware event rings */ -- MHI_EVENT_CONFIG_HW_DATA(2, 1024, 100), -- MHI_EVENT_CONFIG_HW_DATA(3, 2048, 101) -+ MHI_EVENT_CONFIG_HW_DATA(4, 1024, 100), -+ MHI_EVENT_CONFIG_HW_DATA(5, 2048, 101) - }; - - static const struct mhi_controller_config modem_qcom_v1_mhiv_config = { diff --git a/target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch b/target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch deleted file mode 100644 index 2e01d4fd650250..00000000000000 --- a/target/linux/generic/backport-6.1/856-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-EM1.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 2dc36ddb6ca4eeda21204dc9e57750494c74c06d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Duke=20Xin=20=28=E8=BE=9B=E5=AE=89=E6=96=87=29?= - -Date: Thu, 8 Jun 2023 02:29:27 -0700 -Subject: [PATCH 07/13] bus: mhi: host: pci_generic: Add support for Quectel - EM160R-GL modem -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This modem is identical to the previous EM160R-GL modem with same product -name. But this one is designed for a specific laptop usecase, hence Quectel -got a new PID. - -Signed-off-by: Duke Xin(辛安文) -Reviewed-by: Manivannan Sadhasivam -Link: https://lore.kernel.org/r/20230608092927.2893-1-duke_xinanwen@163.com -[mani: modified the commit message and subject] -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -594,6 +594,8 @@ static const struct pci_device_id mhi_pc - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */ - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, -+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x100d), /* EM160R-GL (sdx24) */ -+ .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x2001), /* EM120R-GL for FCCL (sdx24) */ - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, - /* T99W175 (sdx55), Both for eSIM and Non-eSIM */ diff --git a/target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch b/target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch deleted file mode 100644 index f547eb972ffadf..00000000000000 --- a/target/linux/generic/backport-6.1/857-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 7e2f6cb11c24799b6851142c4a5ce69bdc630364 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Duke=20Xin=20=28=E8=BE=9B=E5=AE=89=E6=96=87=29?= - -Date: Thu, 29 Jun 2023 23:23:18 -0700 -Subject: [PATCH 08/13] bus: mhi: host: pci_generic: Add support for Quectel - RM520N-GL modem -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add MHI interface definition for RM520 product based on Qualcomm SDX6X chip - -Signed-off-by: Duke Xin(辛安文) -Reviewed-by: Manivannan Sadhasivam -Link: https://lore.kernel.org/r/20230630062318.12114-1-duke_xinanwen@163.com -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -352,6 +352,16 @@ static const struct mhi_pci_dev_info mhi - .sideband_wake = true, - }; - -+static const struct mhi_pci_dev_info mhi_quectel_rm5xx_info = { -+ .name = "quectel-rm5xx", -+ .edl = "qcom/prog_firehose_sdx6x.elf", -+ .config = &modem_quectel_em1xx_config, -+ .bar_num = MHI_PCI_DEFAULT_BAR_NUM, -+ .dma_data_width = 32, -+ .mru_default = 32768, -+ .sideband_wake = true, -+}; -+ - static const struct mhi_channel_config mhi_foxconn_sdx55_channels[] = { - MHI_CHANNEL_CONFIG_UL(0, "LOOPBACK", 32, 0), - MHI_CHANNEL_CONFIG_DL(1, "LOOPBACK", 32, 0), -@@ -594,6 +604,9 @@ static const struct pci_device_id mhi_pc - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */ - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, -+ /* RM520N-GL (sdx6x), eSIM */ -+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1004), -+ .driver_data = (kernel_ulong_t) &mhi_quectel_rm5xx_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x100d), /* EM160R-GL (sdx24) */ - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x2001), /* EM120R-GL for FCCL (sdx24) */ diff --git a/target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch b/target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch deleted file mode 100644 index ba0e156a8cdbea..00000000000000 --- a/target/linux/generic/backport-6.1/858-v6.6-bus-mhi-host-pci_generic-Add-support-for-Dell-DW5932.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5e20ac8e7d3221e079e87066c4e8f4b64bd58ccb Mon Sep 17 00:00:00 2001 -From: Slark Xiao -Date: Wed, 12 Jul 2023 16:37:41 +0800 -Subject: [PATCH 09/13] bus: mhi: host: pci_generic: Add support for Dell - DW5932e - -The DW5932e has 2 variants: eSIM(DW5932e-eSIM) and non-eSIM(DW5932e). -Both of them are designed based on Qualcomm SDX62 and it will -align with the Foxconn sdx65 settings. - -Signed-off-by: Slark Xiao -Reviewed-by: Loic Poulain -Reviewed-by: Manivannan Sadhasivam -Link: https://lore.kernel.org/r/20230712083741.7615-1-slark_xiao@163.com -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -641,6 +641,12 @@ static const struct pci_device_id mhi_pc - /* T99W510 (sdx24), variant 3 */ - { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f2), - .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx24_info }, -+ /* DW5932e-eSIM (sdx62), With eSIM */ -+ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f5), -+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info }, -+ /* DW5932e (sdx62), Non-eSIM */ -+ { PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0f9), -+ .driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info }, - /* MV31-W (Cinterion) */ - { PCI_DEVICE(PCI_VENDOR_ID_THALES, 0x00b3), - .driver_data = (kernel_ulong_t) &mhi_mv31_info }, diff --git a/target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch b/target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch deleted file mode 100644 index a09ae6fa478a46..00000000000000 --- a/target/linux/generic/backport-6.1/859-v6.6-bus-mhi-host-pci_generic-Add-support-for-Quectel-RM5.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 8be9e92a2c8f26fd7482acc2323c6dc2a4ad43aa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Duke=20Xin=20=28=E8=BE=9B=E5=AE=89=E6=96=87=29?= - -Date: Sun, 6 Aug 2023 20:04:54 -0700 -Subject: [PATCH 10/13] bus: mhi: host: pci_generic: Add support for Quectel - RM520N-GL Lenovo variant -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Quectel's RM520N-GL Lenovo variant is same as that of the existing -RM520N-GL modem and uses the same config. But this one is designed for -Lenovo laptop usecase, hence Quectel got a new PID. - -Signed-off-by: Duke Xin(辛安文) -Reviewed-by: Manivannan Sadhasivam -Reviewed-by: Loic Poulain -Link: https://lore.kernel.org/r/20230807030454.37255-1-duke_xinanwen@163.com -[mani: tweaked subject and commit message a bit] -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -607,6 +607,9 @@ static const struct pci_device_id mhi_pc - /* RM520N-GL (sdx6x), eSIM */ - { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1004), - .driver_data = (kernel_ulong_t) &mhi_quectel_rm5xx_info }, -+ /* RM520N-GL (sdx6x), Lenovo variant */ -+ { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1007), -+ .driver_data = (kernel_ulong_t) &mhi_quectel_rm5xx_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x100d), /* EM160R-GL (sdx24) */ - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x2001), /* EM120R-GL for FCCL (sdx24) */ diff --git a/target/linux/generic/backport-6.1/861-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch b/target/linux/generic/backport-6.1/861-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch deleted file mode 100644 index 30d833adffddcd..00000000000000 --- a/target/linux/generic/backport-6.1/861-v6.8-bus-mhi-host-Add-a-separate-timeout-parameter-for-wa.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 6ab3d50b106c9aea123a80551a6c9deace83b914 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Tue, 7 Nov 2023 16:14:49 +0800 -Subject: [PATCH] bus: mhi: host: Add a separate timeout parameter for waiting - ready - -Some devices(eg. SDX75) take longer than expected (default, 8 seconds) to -set ready after reboot. Hence add optional ready timeout parameter and pass -the appropriate timeout value to mhi_poll_reg_field() to wait enough for -device ready as part of power up sequence. - -Signed-off-by: Qiang Yu -Reviewed-by: Manivannan Sadhasivam -Link: https://lore.kernel.org/r/1699344890-87076-2-git-send-email-quic_qianyu@quicinc.com -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/init.c | 1 + - drivers/bus/mhi/host/internal.h | 2 +- - drivers/bus/mhi/host/main.c | 5 +++-- - drivers/bus/mhi/host/pm.c | 24 +++++++++++++++++------- - include/linux/mhi.h | 4 ++++ - 5 files changed, 26 insertions(+), 10 deletions(-) - ---- a/drivers/bus/mhi/host/init.c -+++ b/drivers/bus/mhi/host/init.c -@@ -882,6 +882,7 @@ static int parse_config(struct mhi_contr - if (!mhi_cntrl->timeout_ms) - mhi_cntrl->timeout_ms = MHI_TIMEOUT_MS; - -+ mhi_cntrl->ready_timeout_ms = config->ready_timeout_ms; - mhi_cntrl->bounce_buf = config->use_bounce_buf; - mhi_cntrl->buffer_len = config->buf_len; - if (!mhi_cntrl->buffer_len) ---- a/drivers/bus/mhi/host/internal.h -+++ b/drivers/bus/mhi/host/internal.h -@@ -324,7 +324,7 @@ int __must_check mhi_read_reg_field(stru - u32 *out); - int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl, - void __iomem *base, u32 offset, u32 mask, -- u32 val, u32 delayus); -+ u32 val, u32 delayus, u32 timeout_ms); - void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base, - u32 offset, u32 val); - int __must_check mhi_write_reg_field(struct mhi_controller *mhi_cntrl, ---- a/drivers/bus/mhi/host/main.c -+++ b/drivers/bus/mhi/host/main.c -@@ -40,10 +40,11 @@ int __must_check mhi_read_reg_field(stru - - int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl, - void __iomem *base, u32 offset, -- u32 mask, u32 val, u32 delayus) -+ u32 mask, u32 val, u32 delayus, -+ u32 timeout_ms) - { - int ret; -- u32 out, retry = (mhi_cntrl->timeout_ms * 1000) / delayus; -+ u32 out, retry = (timeout_ms * 1000) / delayus; - - while (retry--) { - ret = mhi_read_reg_field(mhi_cntrl, base, offset, mask, &out); ---- a/drivers/bus/mhi/host/pm.c -+++ b/drivers/bus/mhi/host/pm.c -@@ -171,6 +171,7 @@ int mhi_ready_state_transition(struct mh - enum mhi_pm_state cur_state; - struct device *dev = &mhi_cntrl->mhi_dev->dev; - u32 interval_us = 25000; /* poll register field every 25 milliseconds */ -+ u32 timeout_ms; - int ret, i; - - /* Check if device entered error state */ -@@ -181,14 +182,18 @@ int mhi_ready_state_transition(struct mh - - /* Wait for RESET to be cleared and READY bit to be set by the device */ - ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, -- MHICTRL_RESET_MASK, 0, interval_us); -+ MHICTRL_RESET_MASK, 0, interval_us, -+ mhi_cntrl->timeout_ms); - if (ret) { - dev_err(dev, "Device failed to clear MHI Reset\n"); - return ret; - } - -+ timeout_ms = mhi_cntrl->ready_timeout_ms ? -+ mhi_cntrl->ready_timeout_ms : mhi_cntrl->timeout_ms; - ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS, -- MHISTATUS_READY_MASK, 1, interval_us); -+ MHISTATUS_READY_MASK, 1, interval_us, -+ timeout_ms); - if (ret) { - dev_err(dev, "Device failed to enter MHI Ready\n"); - return ret; -@@ -487,7 +492,7 @@ static void mhi_pm_disable_transition(st - - /* Wait for the reset bit to be cleared by the device */ - ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, -- MHICTRL_RESET_MASK, 0, 25000); -+ MHICTRL_RESET_MASK, 0, 25000, mhi_cntrl->timeout_ms); - if (ret) - dev_err(dev, "Device failed to clear MHI Reset\n"); - -@@ -500,8 +505,8 @@ static void mhi_pm_disable_transition(st - if (!MHI_IN_PBL(mhi_get_exec_env(mhi_cntrl))) { - /* wait for ready to be set */ - ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, -- MHISTATUS, -- MHISTATUS_READY_MASK, 1, 25000); -+ MHISTATUS, MHISTATUS_READY_MASK, -+ 1, 25000, mhi_cntrl->timeout_ms); - if (ret) - dev_err(dev, "Device failed to enter READY state\n"); - } -@@ -1125,7 +1130,8 @@ int mhi_async_power_up(struct mhi_contro - if (state == MHI_STATE_SYS_ERR) { - mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); - ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, -- MHICTRL_RESET_MASK, 0, interval_us); -+ MHICTRL_RESET_MASK, 0, interval_us, -+ mhi_cntrl->timeout_ms); - if (ret) { - dev_info(dev, "Failed to reset MHI due to syserr state\n"); - goto error_exit; -@@ -1216,14 +1222,18 @@ EXPORT_SYMBOL_GPL(mhi_power_down); - int mhi_sync_power_up(struct mhi_controller *mhi_cntrl) - { - int ret = mhi_async_power_up(mhi_cntrl); -+ u32 timeout_ms; - - if (ret) - return ret; - -+ /* Some devices need more time to set ready during power up */ -+ timeout_ms = mhi_cntrl->ready_timeout_ms ? -+ mhi_cntrl->ready_timeout_ms : mhi_cntrl->timeout_ms; - wait_event_timeout(mhi_cntrl->state_event, - MHI_IN_MISSION_MODE(mhi_cntrl->ee) || - MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), -- msecs_to_jiffies(mhi_cntrl->timeout_ms)); -+ msecs_to_jiffies(timeout_ms)); - - ret = (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) ? 0 : -ETIMEDOUT; - if (ret) ---- a/include/linux/mhi.h -+++ b/include/linux/mhi.h -@@ -266,6 +266,7 @@ struct mhi_event_config { - * struct mhi_controller_config - Root MHI controller configuration - * @max_channels: Maximum number of channels supported - * @timeout_ms: Timeout value for operations. 0 means use default -+ * @ready_timeout_ms: Timeout value for waiting device to be ready (optional) - * @buf_len: Size of automatically allocated buffers. 0 means use default - * @num_channels: Number of channels defined in @ch_cfg - * @ch_cfg: Array of defined channels -@@ -277,6 +278,7 @@ struct mhi_event_config { - struct mhi_controller_config { - u32 max_channels; - u32 timeout_ms; -+ u32 ready_timeout_ms; - u32 buf_len; - u32 num_channels; - const struct mhi_channel_config *ch_cfg; -@@ -326,6 +328,7 @@ struct mhi_controller_config { - * @pm_mutex: Mutex for suspend/resume operation - * @pm_lock: Lock for protecting MHI power management state - * @timeout_ms: Timeout in ms for state transitions -+ * @ready_timeout_ms: Timeout in ms for waiting device to be ready (optional) - * @pm_state: MHI power management state - * @db_access: DB access states - * @ee: MHI device execution environment -@@ -413,6 +416,7 @@ struct mhi_controller { - struct mutex pm_mutex; - rwlock_t pm_lock; - u32 timeout_ms; -+ u32 ready_timeout_ms; - u32 pm_state; - u32 db_access; - enum mhi_ee_type ee; diff --git a/target/linux/generic/backport-6.1/862-v6.8-bus-mhi-host-pci_generic-Add-SDX75-based-modem-suppo.patch b/target/linux/generic/backport-6.1/862-v6.8-bus-mhi-host-pci_generic-Add-SDX75-based-modem-suppo.patch deleted file mode 100644 index 944747ac561641..00000000000000 --- a/target/linux/generic/backport-6.1/862-v6.8-bus-mhi-host-pci_generic-Add-SDX75-based-modem-suppo.patch +++ /dev/null @@ -1,62 +0,0 @@ -From b2f401efbff8878be31b2bce6e8d7bdad23e6f12 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Tue, 7 Nov 2023 16:14:50 +0800 -Subject: [PATCH 12/13] bus: mhi: host: pci_generic: Add SDX75 based modem - support - -Add generic info for SDX75 based modems. SDX75 takes longer to set ready -during power up. Hence use separate configuration. - -Signed-off-by: Qiang Yu -Reviewed-by: Manivannan Sadhasivam -Link: https://lore.kernel.org/r/1699344890-87076-3-git-send-email-quic_qianyu@quicinc.com -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -269,6 +269,16 @@ static struct mhi_event_config modem_qco - MHI_EVENT_CONFIG_HW_DATA(5, 2048, 101) - }; - -+static const struct mhi_controller_config modem_qcom_v2_mhiv_config = { -+ .max_channels = 128, -+ .timeout_ms = 8000, -+ .ready_timeout_ms = 50000, -+ .num_channels = ARRAY_SIZE(modem_qcom_v1_mhi_channels), -+ .ch_cfg = modem_qcom_v1_mhi_channels, -+ .num_events = ARRAY_SIZE(modem_qcom_v1_mhi_events), -+ .event_cfg = modem_qcom_v1_mhi_events, -+}; -+ - static const struct mhi_controller_config modem_qcom_v1_mhiv_config = { - .max_channels = 128, - .timeout_ms = 8000, -@@ -278,6 +288,16 @@ static const struct mhi_controller_confi - .event_cfg = modem_qcom_v1_mhi_events, - }; - -+static const struct mhi_pci_dev_info mhi_qcom_sdx75_info = { -+ .name = "qcom-sdx75m", -+ .fw = "qcom/sdx75m/xbl.elf", -+ .edl = "qcom/sdx75m/edl.mbn", -+ .config = &modem_qcom_v2_mhiv_config, -+ .bar_num = MHI_PCI_DEFAULT_BAR_NUM, -+ .dma_data_width = 32, -+ .sideband_wake = false, -+}; -+ - static const struct mhi_pci_dev_info mhi_qcom_sdx65_info = { - .name = "qcom-sdx65m", - .fw = "qcom/sdx65m/xbl.elf", -@@ -600,6 +620,8 @@ static const struct pci_device_id mhi_pc - .driver_data = (kernel_ulong_t) &mhi_telit_fn990_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308), - .driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info }, -+ { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0309), -+ .driver_data = (kernel_ulong_t) &mhi_qcom_sdx75_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1001), /* EM120R-GL (sdx24) */ - .driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info }, - { PCI_DEVICE(PCI_VENDOR_ID_QUECTEL, 0x1002), /* EM160R-GL (sdx24) */ diff --git a/target/linux/generic/backport-6.1/863-stable-bus-mhi-host-pci_generic-constify-modem_telit_fn980_.patch b/target/linux/generic/backport-6.1/863-stable-bus-mhi-host-pci_generic-constify-modem_telit_fn980_.patch deleted file mode 100644 index 085e8862ae6a22..00000000000000 --- a/target/linux/generic/backport-6.1/863-stable-bus-mhi-host-pci_generic-constify-modem_telit_fn980_.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 5f157aa89b876e82d6aafb2d009979118d0bdd2b Mon Sep 17 00:00:00 2001 -From: Jeff Johnson -Date: Thu, 22 Feb 2024 18:00:23 -0800 -Subject: [PATCH 13/13] bus: mhi: host: pci_generic: constify - modem_telit_fn980_hw_v1_config - -MHI expects the controller configs to be const, and all of the other ones -in this file already are, so constify modem_telit_fn980_hw_v1_config. - -Signed-off-by: Jeff Johnson -Reviewed-by: Manivannan Sadhasivam -Link: https://lore.kernel.org/r/20240222-mhi-const-bus-mhi-host-pci_generic-v1-1-d4c9b0b0a7a5@quicinc.com -Signed-off-by: Manivannan Sadhasivam ---- - drivers/bus/mhi/host/pci_generic.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/bus/mhi/host/pci_generic.c -+++ b/drivers/bus/mhi/host/pci_generic.c -@@ -538,7 +538,7 @@ static struct mhi_event_config mhi_telit - MHI_EVENT_CONFIG_HW_DATA(2, 2048, 101) - }; - --static struct mhi_controller_config modem_telit_fn980_hw_v1_config = { -+static const struct mhi_controller_config modem_telit_fn980_hw_v1_config = { - .max_channels = 128, - .timeout_ms = 20000, - .num_channels = ARRAY_SIZE(mhi_telit_fn980_hw_v1_channels), diff --git a/target/linux/generic/backport-6.1/864-v6.6-bus-mhi-host-allow-MHI-client-drivers-to-provide-the.patch b/target/linux/generic/backport-6.1/864-v6.6-bus-mhi-host-allow-MHI-client-drivers-to-provide-the.patch deleted file mode 100644 index a04b19b157342d..00000000000000 --- a/target/linux/generic/backport-6.1/864-v6.6-bus-mhi-host-allow-MHI-client-drivers-to-provide-the.patch +++ /dev/null @@ -1,142 +0,0 @@ -From: Kalle Valo -Date: Thu, 27 Jul 2023 13:04:28 +0300 -Subject: [PATCH] bus: mhi: host: allow MHI client drivers to provide the - firmware via a pointer - -Currently MHI loads the firmware image from the path provided by client -devices. ath11k needs to support firmware image embedded along with meta -data (named as firmware-2.bin). So allow the client driver to request the -firmware file from user space on it's own and provide the firmware image -data and size to MHI via a pointer struct mhi_controller::fw_data. - -This is an optional feature, if fw_data is NULL MHI load the firmware using -the name from struct mhi_controller::fw_image string as before. - -Tested with ath11k and WCN6855 hw2.0. - -Signed-off-by: Kalle Valo -Reviewed-by: Manivannan Sadhasivam -Reviewed-by: Jeffrey Hugo -Link: https://lore.kernel.org/r/20230727100430.3603551-2-kvalo@kernel.org -[mani: wrapped commit message to 75 columns] -Signed-off-by: Manivannan Sadhasivam ---- - ---- a/drivers/bus/mhi/host/boot.c -+++ b/drivers/bus/mhi/host/boot.c -@@ -367,12 +367,10 @@ error_alloc_mhi_buf: - } - - static void mhi_firmware_copy(struct mhi_controller *mhi_cntrl, -- const struct firmware *firmware, -+ const u8 *buf, size_t remainder, - struct image_info *img_info) - { -- size_t remainder = firmware->size; - size_t to_cpy; -- const u8 *buf = firmware->data; - struct mhi_buf *mhi_buf = img_info->mhi_buf; - struct bhi_vec_entry *bhi_vec = img_info->bhi_vec; - -@@ -395,9 +393,10 @@ void mhi_fw_load_handler(struct mhi_cont - struct device *dev = &mhi_cntrl->mhi_dev->dev; - enum mhi_pm_state new_state; - const char *fw_name; -+ const u8 *fw_data; - void *buf; - dma_addr_t dma_addr; -- size_t size; -+ size_t size, fw_sz; - int i, ret; - - if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { -@@ -427,6 +426,20 @@ void mhi_fw_load_handler(struct mhi_cont - fw_name = (mhi_cntrl->ee == MHI_EE_EDL) ? - mhi_cntrl->edl_image : mhi_cntrl->fw_image; - -+ /* check if the driver has already provided the firmware data */ -+ if (!fw_name && mhi_cntrl->fbc_download && -+ mhi_cntrl->fw_data && mhi_cntrl->fw_sz) { -+ if (!mhi_cntrl->sbl_size) { -+ dev_err(dev, "fw_data provided but no sbl_size\n"); -+ goto error_fw_load; -+ } -+ -+ size = mhi_cntrl->sbl_size; -+ fw_data = mhi_cntrl->fw_data; -+ fw_sz = mhi_cntrl->fw_sz; -+ goto skip_req_fw; -+ } -+ - if (!fw_name || (mhi_cntrl->fbc_download && (!mhi_cntrl->sbl_size || - !mhi_cntrl->seg_len))) { - dev_err(dev, -@@ -446,6 +459,10 @@ void mhi_fw_load_handler(struct mhi_cont - if (size > firmware->size) - size = firmware->size; - -+ fw_data = firmware->data; -+ fw_sz = firmware->size; -+ -+skip_req_fw: - buf = dma_alloc_coherent(mhi_cntrl->cntrl_dev, size, &dma_addr, - GFP_KERNEL); - if (!buf) { -@@ -454,7 +471,7 @@ void mhi_fw_load_handler(struct mhi_cont - } - - /* Download image using BHI */ -- memcpy(buf, firmware->data, size); -+ memcpy(buf, fw_data, size); - ret = mhi_fw_load_bhi(mhi_cntrl, dma_addr, size); - dma_free_coherent(mhi_cntrl->cntrl_dev, size, buf, dma_addr); - -@@ -466,7 +483,7 @@ void mhi_fw_load_handler(struct mhi_cont - } - - /* Wait for ready since EDL image was loaded */ -- if (fw_name == mhi_cntrl->edl_image) { -+ if (fw_name && fw_name == mhi_cntrl->edl_image) { - release_firmware(firmware); - goto fw_load_ready_state; - } -@@ -480,15 +497,14 @@ void mhi_fw_load_handler(struct mhi_cont - * device transitioning into MHI READY state - */ - if (mhi_cntrl->fbc_download) { -- ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, -- firmware->size); -+ ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, fw_sz); - if (ret) { - release_firmware(firmware); - goto error_fw_load; - } - - /* Load the firmware into BHIE vec table */ -- mhi_firmware_copy(mhi_cntrl, firmware, mhi_cntrl->fbc_image); -+ mhi_firmware_copy(mhi_cntrl, fw_data, fw_sz, mhi_cntrl->fbc_image); - } - - release_firmware(firmware); ---- a/include/linux/mhi.h -+++ b/include/linux/mhi.h -@@ -301,6 +301,10 @@ struct mhi_controller_config { - * @iova_start: IOMMU starting address for data (required) - * @iova_stop: IOMMU stop address for data (required) - * @fw_image: Firmware image name for normal booting (optional) -+ * @fw_data: Firmware image data content for normal booting, used only -+ * if fw_image is NULL and fbc_download is true (optional) -+ * @fw_sz: Firmware image data size for normal booting, used only if fw_image -+ * is NULL and fbc_download is true (optional) - * @edl_image: Firmware image name for emergency download mode (optional) - * @rddm_size: RAM dump size that host should allocate for debugging purpose - * @sbl_size: SBL image size downloaded through BHIe (optional) -@@ -387,6 +391,8 @@ struct mhi_controller { - dma_addr_t iova_start; - dma_addr_t iova_stop; - const char *fw_image; -+ const u8 *fw_data; -+ size_t fw_sz; - const char *edl_image; - size_t rddm_size; - size_t sbl_size; diff --git a/target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch b/target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch deleted file mode 100644 index 23681ba93747f8..00000000000000 --- a/target/linux/generic/backport-6.1/880-v6.3-mfd-axp20x-Fix-order-of-pek-rise-and-fall-events.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 8781ba7f45695af3ab8e8d1b55a31f527c9201a3 Mon Sep 17 00:00:00 2001 -From: Aren Moynihan -Date: Thu, 8 Dec 2022 17:02:26 -0500 -Subject: [PATCH] mfd: axp20x: Fix order of pek rise and fall events - -The power button can get "stuck" if the rising edge and falling edge irq -are read in the same pass. This can often be triggered when resuming -from suspend if the power button is released before the kernel handles -the interrupt. - -Swapping the order of the rise and fall events makes sure that the press -event is handled first, which prevents this situation. - -Signed-off-by: Aren Moynihan -Reviewed-by: Samuel Holland -Tested-by: Samuel Holland -Acked-by: Chen-Yu Tsai -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20221208220225.635414-1-aren@peacevolution.org ---- - include/linux/mfd/axp20x.h | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - ---- a/include/linux/mfd/axp20x.h -+++ b/include/linux/mfd/axp20x.h -@@ -432,8 +432,9 @@ enum { - AXP152_IRQ_PEK_SHORT, - AXP152_IRQ_PEK_LONG, - AXP152_IRQ_TIMER, -- AXP152_IRQ_PEK_RIS_EDGE, -+ /* out of bit order to make sure the press event is handled first */ - AXP152_IRQ_PEK_FAL_EDGE, -+ AXP152_IRQ_PEK_RIS_EDGE, - AXP152_IRQ_GPIO3_INPUT, - AXP152_IRQ_GPIO2_INPUT, - AXP152_IRQ_GPIO1_INPUT, -@@ -472,8 +473,9 @@ enum { - AXP20X_IRQ_LOW_PWR_LVL1, - AXP20X_IRQ_LOW_PWR_LVL2, - AXP20X_IRQ_TIMER, -- AXP20X_IRQ_PEK_RIS_EDGE, -+ /* out of bit order to make sure the press event is handled first */ - AXP20X_IRQ_PEK_FAL_EDGE, -+ AXP20X_IRQ_PEK_RIS_EDGE, - AXP20X_IRQ_GPIO3_INPUT, - AXP20X_IRQ_GPIO2_INPUT, - AXP20X_IRQ_GPIO1_INPUT, -@@ -502,8 +504,9 @@ enum axp22x_irqs { - AXP22X_IRQ_LOW_PWR_LVL1, - AXP22X_IRQ_LOW_PWR_LVL2, - AXP22X_IRQ_TIMER, -- AXP22X_IRQ_PEK_RIS_EDGE, -+ /* out of bit order to make sure the press event is handled first */ - AXP22X_IRQ_PEK_FAL_EDGE, -+ AXP22X_IRQ_PEK_RIS_EDGE, - AXP22X_IRQ_GPIO1_INPUT, - AXP22X_IRQ_GPIO0_INPUT, - }; -@@ -571,8 +574,9 @@ enum axp803_irqs { - AXP803_IRQ_LOW_PWR_LVL1, - AXP803_IRQ_LOW_PWR_LVL2, - AXP803_IRQ_TIMER, -- AXP803_IRQ_PEK_RIS_EDGE, -+ /* out of bit order to make sure the press event is handled first */ - AXP803_IRQ_PEK_FAL_EDGE, -+ AXP803_IRQ_PEK_RIS_EDGE, - AXP803_IRQ_PEK_SHORT, - AXP803_IRQ_PEK_LONG, - AXP803_IRQ_PEK_OVER_OFF, -@@ -623,8 +627,9 @@ enum axp809_irqs { - AXP809_IRQ_LOW_PWR_LVL1, - AXP809_IRQ_LOW_PWR_LVL2, - AXP809_IRQ_TIMER, -- AXP809_IRQ_PEK_RIS_EDGE, -+ /* out of bit order to make sure the press event is handled first */ - AXP809_IRQ_PEK_FAL_EDGE, -+ AXP809_IRQ_PEK_RIS_EDGE, - AXP809_IRQ_PEK_SHORT, - AXP809_IRQ_PEK_LONG, - AXP809_IRQ_PEK_OVER_OFF, diff --git a/target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch b/target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch deleted file mode 100644 index b742276c8ad434..00000000000000 --- a/target/linux/generic/backport-6.1/881-v6.3-mfd-axp20x-Switch-to-the-sys-off-handler-API.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 1b1305e95e85624f538ec56db9acf88e2d3d7397 Mon Sep 17 00:00:00 2001 -From: Samuel Holland -Date: Wed, 28 Dec 2022 10:27:52 -0600 -Subject: [PATCH] mfd: axp20x: Switch to the sys-off handler API - -This removes a layer of indirection through pm_power_off() and allows -the PMIC handler to be used as a fallback when firmware power off fails. -This happens on boards like the Clockwork DevTerm R-01 where OpenSBI -does not know how to use the PMIC to power off the board. - -Move the check for AXP288 to avoid registering a dummy handler. - -Signed-off-by: Samuel Holland -[Lee: Removed superfluous new line] -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20221228162752.14204-1-samuel@sholland.org ---- - drivers/mfd/axp20x.c | 27 +++++++++++---------------- - 1 file changed, 11 insertions(+), 16 deletions(-) - ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -23,7 +23,7 @@ - #include - #include - #include --#include -+#include - #include - #include - -@@ -832,17 +832,16 @@ static const struct mfd_cell axp813_cell - }, - }; - --static struct axp20x_dev *axp20x_pm_power_off; --static void axp20x_power_off(void) -+static int axp20x_power_off(struct sys_off_data *data) - { -- if (axp20x_pm_power_off->variant == AXP288_ID) -- return; -+ struct axp20x_dev *axp20x = data->cb_data; - -- regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, -- AXP20X_OFF); -+ regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF); - - /* Give capacitors etc. time to drain to avoid kernel panic msg. */ - mdelay(500); -+ -+ return NOTIFY_DONE; - } - - int axp20x_match_device(struct axp20x_dev *axp20x) -@@ -1009,10 +1008,11 @@ int axp20x_device_probe(struct axp20x_de - return ret; - } - -- if (!pm_power_off) { -- axp20x_pm_power_off = axp20x; -- pm_power_off = axp20x_power_off; -- } -+ if (axp20x->variant != AXP288_ID) -+ devm_register_sys_off_handler(axp20x->dev, -+ SYS_OFF_MODE_POWER_OFF, -+ SYS_OFF_PRIO_DEFAULT, -+ axp20x_power_off, axp20x); - - dev_info(axp20x->dev, "AXP20X driver loaded\n"); - -@@ -1022,11 +1022,6 @@ EXPORT_SYMBOL(axp20x_device_probe); - - void axp20x_device_remove(struct axp20x_dev *axp20x) - { -- if (axp20x == axp20x_pm_power_off) { -- axp20x_pm_power_off = NULL; -- pm_power_off = NULL; -- } -- - mfd_remove_devices(axp20x->dev); - regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc); - } diff --git a/target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch b/target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch deleted file mode 100644 index b84815e1a854cc..00000000000000 --- a/target/linux/generic/backport-6.1/882-v6.3-mfd-axp20x-Fix-axp288-writable-ranges.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2405fbfb384ef39e9560d76d3f6e4c90519f90aa Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 29 Mar 2023 22:55:44 +0200 -Subject: [PATCH] mfd: axp20x: Fix axp288 writable-ranges - -Register AXP288_POWER_REASON is writable and needs to be written -to reset the reset- / power-on-reason bits. - -Add it to the axp288 writable-ranges so that the extcon-axp288 -driver can properly clear the reset- / power-on-reason bits. - -Signed-off-by: Hans de Goede -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/20230329205544.1051393-1-hdegoede@redhat.com ---- - drivers/mfd/axp20x.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -119,6 +119,7 @@ static const struct regmap_access_table - - /* AXP288 ranges are shared with the AXP803, as they cover the same range */ - static const struct regmap_range axp288_writeable_ranges[] = { -+ regmap_reg_range(AXP288_POWER_REASON, AXP288_POWER_REASON), - regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE), - regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5), - }; diff --git a/target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch b/target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch deleted file mode 100644 index 83ef60aecd7c46..00000000000000 --- a/target/linux/generic/backport-6.1/883-v6.4-mfd-axp20x-Add-support-for-AXP15060-PMIC.patch +++ /dev/null @@ -1,343 +0,0 @@ -From e0f8ad2a705367518b5c56bf9d6da89681467c02 Mon Sep 17 00:00:00 2001 -From: Shengyu Qu -Date: Fri, 21 Apr 2023 23:08:15 +0800 -Subject: [PATCH] mfd: axp20x: Add support for AXP15060 PMIC - -The AXP15060 is a PMIC chip produced by X-Powers, and could be connected -via an I2C bus. - -Describe the regmap and the MFD bits, along with the registers exposed -via I2C. Eventually advertise the device using a new compatible string -and add support for power off the system. - -The driver would disable PEK function if IRQ is not configured in device -tree, since some boards (For example, Starfive Visionfive 2) didn't -connect IRQ line of PMIC to SOC. - -GPIO function isn't enabled in this commit, since its configuration -operation is different from any existing AXP PMICs and needs -logic modification on existing driver. GPIO support might come in later -patches. - -Signed-off-by: Shengyu Qu -Reviewed-by: Krzysztof Kozlowski -Signed-off-by: Lee Jones -Link: https://lore.kernel.org/r/TY3P286MB261162D57695AC8164ED50E298609@TY3P286MB2611.JPNP286.PROD.OUTLOOK.COM ---- - drivers/mfd/axp20x-i2c.c | 2 + - drivers/mfd/axp20x.c | 107 +++++++++++++++++++++++++++++++++++++ - include/linux/mfd/axp20x.h | 85 +++++++++++++++++++++++++++++ - 3 files changed, 194 insertions(+) - ---- a/drivers/mfd/axp20x-i2c.c -+++ b/drivers/mfd/axp20x-i2c.c -@@ -66,6 +66,7 @@ static const struct of_device_id axp20x_ - { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID }, - { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID }, - { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID }, -+ { .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID }, - { }, - }; - MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match); -@@ -79,6 +80,7 @@ static const struct i2c_device_id axp20x - { "axp223", 0 }, - { "axp803", 0 }, - { "axp806", 0 }, -+ { "axp15060", 0 }, - { }, - }; - MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id); ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -43,6 +43,7 @@ static const char * const axp20x_model_n - "AXP806", - "AXP809", - "AXP813", -+ "AXP15060", - }; - - static const struct regmap_range axp152_writeable_ranges[] = { -@@ -169,6 +170,31 @@ static const struct regmap_access_table - .n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges), - }; - -+static const struct regmap_range axp15060_writeable_ranges[] = { -+ regmap_reg_range(AXP15060_PWR_OUT_CTRL1, AXP15060_DCDC_MODE_CTRL2), -+ regmap_reg_range(AXP15060_OUTPUT_MONITOR_DISCHARGE, AXP15060_CPUSLDO_V_CTRL), -+ regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ), -+ regmap_reg_range(AXP15060_PEK_KEY, AXP15060_PEK_KEY), -+ regmap_reg_range(AXP15060_IRQ1_EN, AXP15060_IRQ2_EN), -+ regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE), -+}; -+ -+static const struct regmap_range axp15060_volatile_ranges[] = { -+ regmap_reg_range(AXP15060_STARTUP_SRC, AXP15060_STARTUP_SRC), -+ regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ), -+ regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE), -+}; -+ -+static const struct regmap_access_table axp15060_writeable_table = { -+ .yes_ranges = axp15060_writeable_ranges, -+ .n_yes_ranges = ARRAY_SIZE(axp15060_writeable_ranges), -+}; -+ -+static const struct regmap_access_table axp15060_volatile_table = { -+ .yes_ranges = axp15060_volatile_ranges, -+ .n_yes_ranges = ARRAY_SIZE(axp15060_volatile_ranges), -+}; -+ - static const struct resource axp152_pek_resources[] = { - DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"), - DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"), -@@ -237,6 +263,11 @@ static const struct resource axp809_pek_ - DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"), - }; - -+static const struct resource axp15060_pek_resources[] = { -+ DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_RIS_EDGE, "PEK_DBR"), -+ DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_FAL_EDGE, "PEK_DBF"), -+}; -+ - static const struct regmap_config axp152_regmap_config = { - .reg_bits = 8, - .val_bits = 8, -@@ -282,6 +313,15 @@ static const struct regmap_config axp806 - .cache_type = REGCACHE_RBTREE, - }; - -+static const struct regmap_config axp15060_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .wr_table = &axp15060_writeable_table, -+ .volatile_table = &axp15060_volatile_table, -+ .max_register = AXP15060_IRQ2_STATE, -+ .cache_type = REGCACHE_RBTREE, -+}; -+ - #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \ - [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } - -@@ -503,6 +543,23 @@ static const struct regmap_irq axp809_re - INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT, 4, 0), - }; - -+static const struct regmap_irq axp15060_regmap_irqs[] = { -+ INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV1, 0, 0), -+ INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV2, 0, 1), -+ INIT_REGMAP_IRQ(AXP15060, DCDC1_V_LOW, 0, 2), -+ INIT_REGMAP_IRQ(AXP15060, DCDC2_V_LOW, 0, 3), -+ INIT_REGMAP_IRQ(AXP15060, DCDC3_V_LOW, 0, 4), -+ INIT_REGMAP_IRQ(AXP15060, DCDC4_V_LOW, 0, 5), -+ INIT_REGMAP_IRQ(AXP15060, DCDC5_V_LOW, 0, 6), -+ INIT_REGMAP_IRQ(AXP15060, DCDC6_V_LOW, 0, 7), -+ INIT_REGMAP_IRQ(AXP15060, PEK_LONG, 1, 0), -+ INIT_REGMAP_IRQ(AXP15060, PEK_SHORT, 1, 1), -+ INIT_REGMAP_IRQ(AXP15060, GPIO1_INPUT, 1, 2), -+ INIT_REGMAP_IRQ(AXP15060, PEK_FAL_EDGE, 1, 3), -+ INIT_REGMAP_IRQ(AXP15060, PEK_RIS_EDGE, 1, 4), -+ INIT_REGMAP_IRQ(AXP15060, GPIO2_INPUT, 1, 5), -+}; -+ - static const struct regmap_irq_chip axp152_regmap_irq_chip = { - .name = "axp152_irq_chip", - .status_base = AXP152_IRQ1_STATE, -@@ -589,6 +646,17 @@ static const struct regmap_irq_chip axp8 - .num_regs = 5, - }; - -+static const struct regmap_irq_chip axp15060_regmap_irq_chip = { -+ .name = "axp15060", -+ .status_base = AXP15060_IRQ1_STATE, -+ .ack_base = AXP15060_IRQ1_STATE, -+ .unmask_base = AXP15060_IRQ1_EN, -+ .init_ack_masked = true, -+ .irqs = axp15060_regmap_irqs, -+ .num_irqs = ARRAY_SIZE(axp15060_regmap_irqs), -+ .num_regs = 2, -+}; -+ - static const struct mfd_cell axp20x_cells[] = { - { - .name = "axp20x-gpio", -@@ -833,6 +901,23 @@ static const struct mfd_cell axp813_cell - }, - }; - -+static const struct mfd_cell axp15060_cells[] = { -+ { -+ .name = "axp221-pek", -+ .num_resources = ARRAY_SIZE(axp15060_pek_resources), -+ .resources = axp15060_pek_resources, -+ }, { -+ .name = "axp20x-regulator", -+ }, -+}; -+ -+/* For boards that don't have IRQ line connected to SOC. */ -+static const struct mfd_cell axp_regulator_only_cells[] = { -+ { -+ .name = "axp20x-regulator", -+ }, -+}; -+ - static int axp20x_power_off(struct sys_off_data *data) - { - struct axp20x_dev *axp20x = data->cb_data; -@@ -942,6 +1027,28 @@ int axp20x_match_device(struct axp20x_de - */ - axp20x->regmap_irq_chip = &axp803_regmap_irq_chip; - break; -+ case AXP15060_ID: -+ /* -+ * Don't register the power key part if there is no interrupt -+ * line. -+ * -+ * Since most use cases of AXP PMICs are Allwinner SOCs, board -+ * designers follow Allwinner's reference design and connects -+ * IRQ line to SOC, there's no need for those variants to deal -+ * with cases that IRQ isn't connected. However, AXP15660 is -+ * used by some other vendors' SOCs that didn't connect IRQ -+ * line, we need to deal with this case. -+ */ -+ if (axp20x->irq > 0) { -+ axp20x->nr_cells = ARRAY_SIZE(axp15060_cells); -+ axp20x->cells = axp15060_cells; -+ } else { -+ axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells); -+ axp20x->cells = axp_regulator_only_cells; -+ } -+ axp20x->regmap_cfg = &axp15060_regmap_config; -+ axp20x->regmap_irq_chip = &axp15060_regmap_irq_chip; -+ break; - default: - dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant); - return -EINVAL; ---- a/include/linux/mfd/axp20x.h -+++ b/include/linux/mfd/axp20x.h -@@ -21,6 +21,7 @@ enum axp20x_variants { - AXP806_ID, - AXP809_ID, - AXP813_ID, -+ AXP15060_ID, - NR_AXP20X_VARIANTS, - }; - -@@ -131,6 +132,39 @@ enum axp20x_variants { - /* Other DCDC regulator control registers are the same as AXP803 */ - #define AXP813_DCDC7_V_OUT 0x26 - -+#define AXP15060_STARTUP_SRC 0x00 -+#define AXP15060_PWR_OUT_CTRL1 0x10 -+#define AXP15060_PWR_OUT_CTRL2 0x11 -+#define AXP15060_PWR_OUT_CTRL3 0x12 -+#define AXP15060_DCDC1_V_CTRL 0x13 -+#define AXP15060_DCDC2_V_CTRL 0x14 -+#define AXP15060_DCDC3_V_CTRL 0x15 -+#define AXP15060_DCDC4_V_CTRL 0x16 -+#define AXP15060_DCDC5_V_CTRL 0x17 -+#define AXP15060_DCDC6_V_CTRL 0x18 -+#define AXP15060_ALDO1_V_CTRL 0x19 -+#define AXP15060_DCDC_MODE_CTRL1 0x1a -+#define AXP15060_DCDC_MODE_CTRL2 0x1b -+#define AXP15060_OUTPUT_MONITOR_DISCHARGE 0x1e -+#define AXP15060_IRQ_PWROK_VOFF 0x1f -+#define AXP15060_ALDO2_V_CTRL 0x20 -+#define AXP15060_ALDO3_V_CTRL 0x21 -+#define AXP15060_ALDO4_V_CTRL 0x22 -+#define AXP15060_ALDO5_V_CTRL 0x23 -+#define AXP15060_BLDO1_V_CTRL 0x24 -+#define AXP15060_BLDO2_V_CTRL 0x25 -+#define AXP15060_BLDO3_V_CTRL 0x26 -+#define AXP15060_BLDO4_V_CTRL 0x27 -+#define AXP15060_BLDO5_V_CTRL 0x28 -+#define AXP15060_CLDO1_V_CTRL 0x29 -+#define AXP15060_CLDO2_V_CTRL 0x2a -+#define AXP15060_CLDO3_V_CTRL 0x2b -+#define AXP15060_CLDO4_V_CTRL 0x2d -+#define AXP15060_CPUSLDO_V_CTRL 0x2e -+#define AXP15060_PWR_WAKEUP_CTRL 0x31 -+#define AXP15060_PWR_DISABLE_DOWN_SEQ 0x32 -+#define AXP15060_PEK_KEY 0x36 -+ - /* Interrupt */ - #define AXP152_IRQ1_EN 0x40 - #define AXP152_IRQ2_EN 0x41 -@@ -152,6 +186,11 @@ enum axp20x_variants { - #define AXP20X_IRQ5_STATE 0x4c - #define AXP20X_IRQ6_STATE 0x4d - -+#define AXP15060_IRQ1_EN 0x40 -+#define AXP15060_IRQ2_EN 0x41 -+#define AXP15060_IRQ1_STATE 0x48 -+#define AXP15060_IRQ2_STATE 0x49 -+ - /* ADC */ - #define AXP20X_ACIN_V_ADC_H 0x56 - #define AXP20X_ACIN_V_ADC_L 0x57 -@@ -222,6 +261,8 @@ enum axp20x_variants { - #define AXP22X_GPIO_STATE 0x94 - #define AXP22X_GPIO_PULL_DOWN 0x95 - -+#define AXP15060_CLDO4_GPIO2_MODESET 0x2c -+ - /* Battery */ - #define AXP20X_CHRG_CC_31_24 0xb0 - #define AXP20X_CHRG_CC_23_16 0xb1 -@@ -419,6 +460,33 @@ enum { - AXP813_REG_ID_MAX, - }; - -+enum { -+ AXP15060_DCDC1 = 0, -+ AXP15060_DCDC2, -+ AXP15060_DCDC3, -+ AXP15060_DCDC4, -+ AXP15060_DCDC5, -+ AXP15060_DCDC6, -+ AXP15060_ALDO1, -+ AXP15060_ALDO2, -+ AXP15060_ALDO3, -+ AXP15060_ALDO4, -+ AXP15060_ALDO5, -+ AXP15060_BLDO1, -+ AXP15060_BLDO2, -+ AXP15060_BLDO3, -+ AXP15060_BLDO4, -+ AXP15060_BLDO5, -+ AXP15060_CLDO1, -+ AXP15060_CLDO2, -+ AXP15060_CLDO3, -+ AXP15060_CLDO4, -+ AXP15060_CPUSLDO, -+ AXP15060_SW, -+ AXP15060_RTC_LDO, -+ AXP15060_REG_ID_MAX, -+}; -+ - /* IRQs */ - enum { - AXP152_IRQ_LDO0IN_CONNECT = 1, -@@ -637,6 +705,23 @@ enum axp809_irqs { - AXP809_IRQ_GPIO0_INPUT, - }; - -+enum axp15060_irqs { -+ AXP15060_IRQ_DIE_TEMP_HIGH_LV1 = 1, -+ AXP15060_IRQ_DIE_TEMP_HIGH_LV2, -+ AXP15060_IRQ_DCDC1_V_LOW, -+ AXP15060_IRQ_DCDC2_V_LOW, -+ AXP15060_IRQ_DCDC3_V_LOW, -+ AXP15060_IRQ_DCDC4_V_LOW, -+ AXP15060_IRQ_DCDC5_V_LOW, -+ AXP15060_IRQ_DCDC6_V_LOW, -+ AXP15060_IRQ_PEK_LONG, -+ AXP15060_IRQ_PEK_SHORT, -+ AXP15060_IRQ_GPIO1_INPUT, -+ AXP15060_IRQ_PEK_FAL_EDGE, -+ AXP15060_IRQ_PEK_RIS_EDGE, -+ AXP15060_IRQ_GPIO2_INPUT, -+}; -+ - struct axp20x_dev { - struct device *dev; - int irq; diff --git a/target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch b/target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch deleted file mode 100644 index c9470eacec73b9..00000000000000 --- a/target/linux/generic/backport-6.1/884-v6.5-mfd-axp20x-Add-support-for-AXP313a-PMIC.patch +++ /dev/null @@ -1,256 +0,0 @@ -From 75c8cb2f4cb218aaf4ea68cab08d6dbc96eeae15 Mon Sep 17 00:00:00 2001 -From: Martin Botka -Date: Wed, 24 May 2023 01:00:10 +0100 -Subject: [PATCH] mfd: axp20x: Add support for AXP313a PMIC - -The AXP313a is a PMIC chip produced by X-Powers, it can be connected via -an I2C bus. -The name AXP1530 seems to appear as well, and this is what is used in -the BSP driver. From all we know it's the same chip, just a different -name. However we have only seen AXP313a chips in the wild, so go with -this name. - -Compared to the other AXP PMICs it's a rather simple affair: just three -DCDC converters, three LDOs, and no battery charging support. - -Describe the regmap and the MFD bits, along with the registers exposed -via I2C. Aside from the various regulators, also describe the power key -interrupts, and adjust the shutdown handler routine to use a different -register than the other PMICs. -Eventually advertise the device using the new compatible string. - -Signed-off-by: Martin Botka -Signed-off-by: Andre Przywara -Reviewed-by: Chen-Yu Tsai -Link: https://lore.kernel.org/r/20230524000012.15028-2-andre.przywara@arm.com -Signed-off-by: Lee Jones ---- - drivers/mfd/axp20x-i2c.c | 2 + - drivers/mfd/axp20x.c | 78 +++++++++++++++++++++++++++++++++++++- - include/linux/mfd/axp20x.h | 32 ++++++++++++++++ - 3 files changed, 111 insertions(+), 1 deletion(-) - ---- a/drivers/mfd/axp20x-i2c.c -+++ b/drivers/mfd/axp20x-i2c.c -@@ -64,6 +64,7 @@ static const struct of_device_id axp20x_ - { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID }, - { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID }, - { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID }, -+ { .compatible = "x-powers,axp313a", .data = (void *)AXP313A_ID }, - { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID }, - { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID }, - { .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID }, -@@ -78,6 +79,7 @@ static const struct i2c_device_id axp20x - { "axp209", 0 }, - { "axp221", 0 }, - { "axp223", 0 }, -+ { "axp313a", 0 }, - { "axp803", 0 }, - { "axp806", 0 }, - { "axp15060", 0 }, ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -39,6 +39,7 @@ static const char * const axp20x_model_n - "AXP221", - "AXP223", - "AXP288", -+ "AXP313a", - "AXP803", - "AXP806", - "AXP809", -@@ -156,6 +157,25 @@ static const struct regmap_range axp806_ - regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT), - }; - -+static const struct regmap_range axp313a_writeable_ranges[] = { -+ regmap_reg_range(AXP313A_ON_INDICATE, AXP313A_IRQ_STATE), -+}; -+ -+static const struct regmap_range axp313a_volatile_ranges[] = { -+ regmap_reg_range(AXP313A_SHUTDOWN_CTRL, AXP313A_SHUTDOWN_CTRL), -+ regmap_reg_range(AXP313A_IRQ_STATE, AXP313A_IRQ_STATE), -+}; -+ -+static const struct regmap_access_table axp313a_writeable_table = { -+ .yes_ranges = axp313a_writeable_ranges, -+ .n_yes_ranges = ARRAY_SIZE(axp313a_writeable_ranges), -+}; -+ -+static const struct regmap_access_table axp313a_volatile_table = { -+ .yes_ranges = axp313a_volatile_ranges, -+ .n_yes_ranges = ARRAY_SIZE(axp313a_volatile_ranges), -+}; -+ - static const struct regmap_range axp806_volatile_ranges[] = { - regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE), - }; -@@ -248,6 +268,11 @@ static const struct resource axp288_fuel - DEFINE_RES_IRQ(AXP288_IRQ_WL1), - }; - -+static const struct resource axp313a_pek_resources[] = { -+ DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_RIS_EDGE, "PEK_DBR"), -+ DEFINE_RES_IRQ_NAMED(AXP313A_IRQ_PEK_FAL_EDGE, "PEK_DBF"), -+}; -+ - static const struct resource axp803_pek_resources[] = { - DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"), - DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"), -@@ -304,6 +329,15 @@ static const struct regmap_config axp288 - .cache_type = REGCACHE_RBTREE, - }; - -+static const struct regmap_config axp313a_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .wr_table = &axp313a_writeable_table, -+ .volatile_table = &axp313a_volatile_table, -+ .max_register = AXP313A_IRQ_STATE, -+ .cache_type = REGCACHE_RBTREE, -+}; -+ - static const struct regmap_config axp806_regmap_config = { - .reg_bits = 8, - .val_bits = 8, -@@ -456,6 +490,16 @@ static const struct regmap_irq axp288_re - INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1), - }; - -+static const struct regmap_irq axp313a_regmap_irqs[] = { -+ INIT_REGMAP_IRQ(AXP313A, PEK_RIS_EDGE, 0, 7), -+ INIT_REGMAP_IRQ(AXP313A, PEK_FAL_EDGE, 0, 6), -+ INIT_REGMAP_IRQ(AXP313A, PEK_SHORT, 0, 5), -+ INIT_REGMAP_IRQ(AXP313A, PEK_LONG, 0, 4), -+ INIT_REGMAP_IRQ(AXP313A, DCDC3_V_LOW, 0, 3), -+ INIT_REGMAP_IRQ(AXP313A, DCDC2_V_LOW, 0, 2), -+ INIT_REGMAP_IRQ(AXP313A, DIE_TEMP_HIGH, 0, 0), -+}; -+ - static const struct regmap_irq axp803_regmap_irqs[] = { - INIT_REGMAP_IRQ(AXP803, ACIN_OVER_V, 0, 7), - INIT_REGMAP_IRQ(AXP803, ACIN_PLUGIN, 0, 6), -@@ -610,6 +654,17 @@ static const struct regmap_irq_chip axp2 - - }; - -+static const struct regmap_irq_chip axp313a_regmap_irq_chip = { -+ .name = "axp313a_irq_chip", -+ .status_base = AXP313A_IRQ_STATE, -+ .ack_base = AXP313A_IRQ_STATE, -+ .unmask_base = AXP313A_IRQ_EN, -+ .init_ack_masked = true, -+ .irqs = axp313a_regmap_irqs, -+ .num_irqs = ARRAY_SIZE(axp313a_regmap_irqs), -+ .num_regs = 1, -+}; -+ - static const struct regmap_irq_chip axp803_regmap_irq_chip = { - .name = "axp803", - .status_base = AXP20X_IRQ1_STATE, -@@ -752,6 +807,11 @@ static const struct mfd_cell axp152_cell - }, - }; - -+static struct mfd_cell axp313a_cells[] = { -+ MFD_CELL_NAME("axp20x-regulator"), -+ MFD_CELL_RES("axp313a-pek", axp313a_pek_resources), -+}; -+ - static const struct resource axp288_adc_resources[] = { - DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"), - }; -@@ -921,8 +981,18 @@ static const struct mfd_cell axp_regulat - static int axp20x_power_off(struct sys_off_data *data) - { - struct axp20x_dev *axp20x = data->cb_data; -+ unsigned int shutdown_reg; - -- regmap_write(axp20x->regmap, AXP20X_OFF_CTRL, AXP20X_OFF); -+ switch (axp20x->variant) { -+ case AXP313A_ID: -+ shutdown_reg = AXP313A_SHUTDOWN_CTRL; -+ break; -+ default: -+ shutdown_reg = AXP20X_OFF_CTRL; -+ break; -+ } -+ -+ regmap_write(axp20x->regmap, shutdown_reg, AXP20X_OFF); - - /* Give capacitors etc. time to drain to avoid kernel panic msg. */ - mdelay(500); -@@ -985,6 +1055,12 @@ int axp20x_match_device(struct axp20x_de - axp20x->regmap_irq_chip = &axp288_regmap_irq_chip; - axp20x->irq_flags = IRQF_TRIGGER_LOW; - break; -+ case AXP313A_ID: -+ axp20x->nr_cells = ARRAY_SIZE(axp313a_cells); -+ axp20x->cells = axp313a_cells; -+ axp20x->regmap_cfg = &axp313a_regmap_config; -+ axp20x->regmap_irq_chip = &axp313a_regmap_irq_chip; -+ break; - case AXP803_ID: - axp20x->nr_cells = ARRAY_SIZE(axp803_cells); - axp20x->cells = axp803_cells; ---- a/include/linux/mfd/axp20x.h -+++ b/include/linux/mfd/axp20x.h -@@ -17,6 +17,7 @@ enum axp20x_variants { - AXP221_ID, - AXP223_ID, - AXP288_ID, -+ AXP313A_ID, - AXP803_ID, - AXP806_ID, - AXP809_ID, -@@ -92,6 +93,17 @@ enum axp20x_variants { - #define AXP22X_ALDO3_V_OUT 0x2a - #define AXP22X_CHRG_CTRL3 0x35 - -+#define AXP313A_ON_INDICATE 0x00 -+#define AXP313A_OUTPUT_CONTROL 0x10 -+#define AXP313A_DCDC1_CONRTOL 0x13 -+#define AXP313A_DCDC2_CONRTOL 0x14 -+#define AXP313A_DCDC3_CONRTOL 0x15 -+#define AXP313A_ALDO1_CONRTOL 0x16 -+#define AXP313A_DLDO1_CONRTOL 0x17 -+#define AXP313A_SHUTDOWN_CTRL 0x1a -+#define AXP313A_IRQ_EN 0x20 -+#define AXP313A_IRQ_STATE 0x21 -+ - #define AXP806_STARTUP_SRC 0x00 - #define AXP806_CHIP_ID 0x03 - #define AXP806_PWR_OUT_CTRL1 0x10 -@@ -364,6 +376,16 @@ enum { - }; - - enum { -+ AXP313A_DCDC1 = 0, -+ AXP313A_DCDC2, -+ AXP313A_DCDC3, -+ AXP313A_ALDO1, -+ AXP313A_DLDO1, -+ AXP313A_RTC_LDO, -+ AXP313A_REG_ID_MAX, -+}; -+ -+enum { - AXP806_DCDCA = 0, - AXP806_DCDCB, - AXP806_DCDCC, -@@ -616,6 +638,16 @@ enum axp288_irqs { - AXP288_IRQ_BC_USB_CHNG, - }; - -+enum axp313a_irqs { -+ AXP313A_IRQ_DIE_TEMP_HIGH, -+ AXP313A_IRQ_DCDC2_V_LOW = 2, -+ AXP313A_IRQ_DCDC3_V_LOW, -+ AXP313A_IRQ_PEK_LONG, -+ AXP313A_IRQ_PEK_SHORT, -+ AXP313A_IRQ_PEK_FAL_EDGE, -+ AXP313A_IRQ_PEK_RIS_EDGE, -+}; -+ - enum axp803_irqs { - AXP803_IRQ_ACIN_OVER_V = 1, - AXP803_IRQ_ACIN_PLUGIN, diff --git a/target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch b/target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch deleted file mode 100644 index 91f1b398244a50..00000000000000 --- a/target/linux/generic/backport-6.1/885-v6.5-regulator-axp20x-Add-support-for-AXP313a-variant.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 60fd7eb89670d2636ac3156881acbd103c6eba6a Mon Sep 17 00:00:00 2001 -From: Martin Botka -Date: Wed, 24 May 2023 01:00:11 +0100 -Subject: [PATCH] regulator: axp20x: Add support for AXP313a variant - -The AXP313a is your typical I2C controlled PMIC, although in a lighter -fashion compared to the other X-Powers PMICs: it has only three DCDC -rails, three LDOs, and no battery charging support. - -The AXP313a datasheet does not describe a register to change the DCDC -switching frequency, and talks of it being fixed at 3 MHz. Check that -the property allowing to change that frequency is absent from the DT, -and bail out otherwise. - -The third LDO, RTCLDO, is fixed, and cannot even be turned on or off, -programmatically. On top of that, its voltage is customisable (either -1.8V or 3.3V), which we cannot describe easily using the existing -regulator wrapper functions. This should be fixed properly, using -regulator-{min,max}-microvolt in the DT, but this requires more changes -to the code. As some other PMICs (AXP2xx, AXP803) seem to paper over the -same problem as well, we follow suit here and pretend it's a fixed 1.8V -regulator. A proper fix can follow later. The BSP code seems to ignore -this regulator altogether. - -Describe the AXP313A's voltage settings and switch registers, how the -voltages are encoded, and connect this to the MFD device via its -regulator ID. - -Signed-off-by: Martin Botka -Signed-off-by: Andre Przywara -Reviewed-by: Chen-Yu Tsai -Reviewed-by: Mark Brown -Tested-by: Shengyu Qu -Link: https://lore.kernel.org/r/20230524000012.15028-3-andre.przywara@arm.com -Signed-off-by: Mark Brown ---- - drivers/regulator/axp20x-regulator.c | 60 ++++++++++++++++++++++++++++ - 1 file changed, 60 insertions(+) - ---- a/drivers/regulator/axp20x-regulator.c -+++ b/drivers/regulator/axp20x-regulator.c -@@ -134,6 +134,11 @@ - #define AXP22X_PWR_OUT_DLDO4_MASK BIT_MASK(6) - #define AXP22X_PWR_OUT_ALDO3_MASK BIT_MASK(7) - -+#define AXP313A_DCDC1_NUM_VOLTAGES 107 -+#define AXP313A_DCDC23_NUM_VOLTAGES 88 -+#define AXP313A_DCDC_V_OUT_MASK GENMASK(6, 0) -+#define AXP313A_LDO_V_OUT_MASK GENMASK(4, 0) -+ - #define AXP803_PWR_OUT_DCDC1_MASK BIT_MASK(0) - #define AXP803_PWR_OUT_DCDC2_MASK BIT_MASK(1) - #define AXP803_PWR_OUT_DCDC3_MASK BIT_MASK(2) -@@ -638,6 +643,48 @@ static const struct regulator_desc axp22 - .ops = &axp20x_ops_sw, - }; - -+static const struct linear_range axp313a_dcdc1_ranges[] = { -+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000), -+ REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000), -+ REGULATOR_LINEAR_RANGE(1600000, 88, 106, 100000), -+}; -+ -+static const struct linear_range axp313a_dcdc2_ranges[] = { -+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000), -+ REGULATOR_LINEAR_RANGE(1220000, 71, 87, 20000), -+}; -+ -+/* -+ * This is deviating from the datasheet. The values here are taken from the -+ * BSP driver and have been confirmed by measurements. -+ */ -+static const struct linear_range axp313a_dcdc3_ranges[] = { -+ REGULATOR_LINEAR_RANGE(500000, 0, 70, 10000), -+ REGULATOR_LINEAR_RANGE(1220000, 71, 102, 20000), -+}; -+ -+static const struct regulator_desc axp313a_regulators[] = { -+ AXP_DESC_RANGES(AXP313A, DCDC1, "dcdc1", "vin1", -+ axp313a_dcdc1_ranges, AXP313A_DCDC1_NUM_VOLTAGES, -+ AXP313A_DCDC1_CONRTOL, AXP313A_DCDC_V_OUT_MASK, -+ AXP313A_OUTPUT_CONTROL, BIT(0)), -+ AXP_DESC_RANGES(AXP313A, DCDC2, "dcdc2", "vin2", -+ axp313a_dcdc2_ranges, AXP313A_DCDC23_NUM_VOLTAGES, -+ AXP313A_DCDC2_CONRTOL, AXP313A_DCDC_V_OUT_MASK, -+ AXP313A_OUTPUT_CONTROL, BIT(1)), -+ AXP_DESC_RANGES(AXP313A, DCDC3, "dcdc3", "vin3", -+ axp313a_dcdc3_ranges, AXP313A_DCDC23_NUM_VOLTAGES, -+ AXP313A_DCDC3_CONRTOL, AXP313A_DCDC_V_OUT_MASK, -+ AXP313A_OUTPUT_CONTROL, BIT(2)), -+ AXP_DESC(AXP313A, ALDO1, "aldo1", "vin1", 500, 3500, 100, -+ AXP313A_ALDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK, -+ AXP313A_OUTPUT_CONTROL, BIT(3)), -+ AXP_DESC(AXP313A, DLDO1, "dldo1", "vin1", 500, 3500, 100, -+ AXP313A_DLDO1_CONRTOL, AXP313A_LDO_V_OUT_MASK, -+ AXP313A_OUTPUT_CONTROL, BIT(4)), -+ AXP_DESC_FIXED(AXP313A, RTC_LDO, "rtc-ldo", "vin1", 1800), -+}; -+ - /* DCDC ranges shared with AXP813 */ - static const struct linear_range axp803_dcdc234_ranges[] = { - REGULATOR_LINEAR_RANGE(500000, -@@ -1040,6 +1087,15 @@ static int axp20x_set_dcdc_freq(struct p - def = 3000; - step = 150; - break; -+ case AXP313A_ID: -+ /* The DCDC PWM frequency seems to be fixed to 3 MHz. */ -+ if (dcdcfreq != 0) { -+ dev_err(&pdev->dev, -+ "DCDC frequency on AXP313a is fixed to 3 MHz.\n"); -+ return -EINVAL; -+ } -+ -+ return 0; - default: - dev_err(&pdev->dev, - "Setting DCDC frequency for unsupported AXP variant\n"); -@@ -1232,6 +1288,10 @@ static int axp20x_regulator_probe(struct - drivevbus = of_property_read_bool(pdev->dev.parent->of_node, - "x-powers,drive-vbus-en"); - break; -+ case AXP313A_ID: -+ regulators = axp313a_regulators; -+ nregulators = AXP313A_REG_ID_MAX; -+ break; - case AXP803_ID: - regulators = axp803_regulators; - nregulators = AXP803_REG_ID_MAX; diff --git a/target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch b/target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch deleted file mode 100644 index 6af09204af2e5c..00000000000000 --- a/target/linux/generic/backport-6.1/886-v6.5-regulator-axp20x-Add-AXP15060-support.patch +++ /dev/null @@ -1,367 +0,0 @@ -From 9e72869d0fe12aba8cd489e485d93912b3f5c248 Mon Sep 17 00:00:00 2001 -From: Shengyu Qu -Date: Wed, 24 May 2023 01:00:12 +0100 -Subject: [PATCH] regulator: axp20x: Add AXP15060 support - -The AXP15060 is a typical I2C-controlled PMIC, seen on multiple boards -with different default register value. Current driver is tested on -Starfive Visionfive 2. - -The RTCLDO is fixed, and cannot even be turned on or off. On top of -that, its voltage is customisable (either 1.8V or 3.3V). We pretend it's -a fixed 1.8V regulator since other AXP driver also do like this. Also, -BSP code ignores this regulator and it's not used according to VF2 -schematic. - -Describe the AXP15060's voltage settings and switch registers, how the -voltages are encoded, and connect this to the MFD device via its -regulator ID. - -Signed-off-by: Shengyu Qu -Signed-off-by: Andre Przywara -Reviewed-by: Mark Brown -Tested-by: Shengyu Qu -Link: https://lore.kernel.org/r/20230524000012.15028-4-andre.przywara@arm.com -Signed-off-by: Mark Brown ---- - drivers/regulator/axp20x-regulator.c | 232 +++++++++++++++++++++++++-- - 1 file changed, 223 insertions(+), 9 deletions(-) - ---- a/drivers/regulator/axp20x-regulator.c -+++ b/drivers/regulator/axp20x-regulator.c -@@ -275,6 +275,74 @@ - - #define AXP813_PWR_OUT_DCDC7_MASK BIT_MASK(6) - -+#define AXP15060_DCDC1_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_DCDC2_V_CTRL_MASK GENMASK(6, 0) -+#define AXP15060_DCDC3_V_CTRL_MASK GENMASK(6, 0) -+#define AXP15060_DCDC4_V_CTRL_MASK GENMASK(6, 0) -+#define AXP15060_DCDC5_V_CTRL_MASK GENMASK(6, 0) -+#define AXP15060_DCDC6_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_ALDO1_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_ALDO2_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_ALDO3_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_ALDO4_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_ALDO5_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_BLDO1_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_BLDO2_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_BLDO3_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_BLDO4_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_BLDO5_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_CLDO1_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_CLDO2_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_CLDO3_V_CTRL_MASK GENMASK(4, 0) -+#define AXP15060_CLDO4_V_CTRL_MASK GENMASK(5, 0) -+#define AXP15060_CPUSLDO_V_CTRL_MASK GENMASK(3, 0) -+ -+#define AXP15060_PWR_OUT_DCDC1_MASK BIT_MASK(0) -+#define AXP15060_PWR_OUT_DCDC2_MASK BIT_MASK(1) -+#define AXP15060_PWR_OUT_DCDC3_MASK BIT_MASK(2) -+#define AXP15060_PWR_OUT_DCDC4_MASK BIT_MASK(3) -+#define AXP15060_PWR_OUT_DCDC5_MASK BIT_MASK(4) -+#define AXP15060_PWR_OUT_DCDC6_MASK BIT_MASK(5) -+#define AXP15060_PWR_OUT_ALDO1_MASK BIT_MASK(0) -+#define AXP15060_PWR_OUT_ALDO2_MASK BIT_MASK(1) -+#define AXP15060_PWR_OUT_ALDO3_MASK BIT_MASK(2) -+#define AXP15060_PWR_OUT_ALDO4_MASK BIT_MASK(3) -+#define AXP15060_PWR_OUT_ALDO5_MASK BIT_MASK(4) -+#define AXP15060_PWR_OUT_BLDO1_MASK BIT_MASK(5) -+#define AXP15060_PWR_OUT_BLDO2_MASK BIT_MASK(6) -+#define AXP15060_PWR_OUT_BLDO3_MASK BIT_MASK(7) -+#define AXP15060_PWR_OUT_BLDO4_MASK BIT_MASK(0) -+#define AXP15060_PWR_OUT_BLDO5_MASK BIT_MASK(1) -+#define AXP15060_PWR_OUT_CLDO1_MASK BIT_MASK(2) -+#define AXP15060_PWR_OUT_CLDO2_MASK BIT_MASK(3) -+#define AXP15060_PWR_OUT_CLDO3_MASK BIT_MASK(4) -+#define AXP15060_PWR_OUT_CLDO4_MASK BIT_MASK(5) -+#define AXP15060_PWR_OUT_CPUSLDO_MASK BIT_MASK(6) -+#define AXP15060_PWR_OUT_SW_MASK BIT_MASK(7) -+ -+#define AXP15060_DCDC23_POLYPHASE_DUAL_MASK BIT_MASK(6) -+#define AXP15060_DCDC46_POLYPHASE_DUAL_MASK BIT_MASK(7) -+ -+#define AXP15060_DCDC234_500mV_START 0x00 -+#define AXP15060_DCDC234_500mV_STEPS 70 -+#define AXP15060_DCDC234_500mV_END \ -+ (AXP15060_DCDC234_500mV_START + AXP15060_DCDC234_500mV_STEPS) -+#define AXP15060_DCDC234_1220mV_START 0x47 -+#define AXP15060_DCDC234_1220mV_STEPS 16 -+#define AXP15060_DCDC234_1220mV_END \ -+ (AXP15060_DCDC234_1220mV_START + AXP15060_DCDC234_1220mV_STEPS) -+#define AXP15060_DCDC234_NUM_VOLTAGES 88 -+ -+#define AXP15060_DCDC5_800mV_START 0x00 -+#define AXP15060_DCDC5_800mV_STEPS 32 -+#define AXP15060_DCDC5_800mV_END \ -+ (AXP15060_DCDC5_800mV_START + AXP15060_DCDC5_800mV_STEPS) -+#define AXP15060_DCDC5_1140mV_START 0x21 -+#define AXP15060_DCDC5_1140mV_STEPS 35 -+#define AXP15060_DCDC5_1140mV_END \ -+ (AXP15060_DCDC5_1140mV_START + AXP15060_DCDC5_1140mV_STEPS) -+#define AXP15060_DCDC5_NUM_VOLTAGES 69 -+ - #define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg, \ - _vmask, _ereg, _emask, _enable_val, _disable_val) \ - [_family##_##_id] = { \ -@@ -1048,6 +1116,104 @@ static const struct regulator_desc axp81 - AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DC1SW_MASK), - }; - -+static const struct linear_range axp15060_dcdc234_ranges[] = { -+ REGULATOR_LINEAR_RANGE(500000, -+ AXP15060_DCDC234_500mV_START, -+ AXP15060_DCDC234_500mV_END, -+ 10000), -+ REGULATOR_LINEAR_RANGE(1220000, -+ AXP15060_DCDC234_1220mV_START, -+ AXP15060_DCDC234_1220mV_END, -+ 20000), -+}; -+ -+static const struct linear_range axp15060_dcdc5_ranges[] = { -+ REGULATOR_LINEAR_RANGE(800000, -+ AXP15060_DCDC5_800mV_START, -+ AXP15060_DCDC5_800mV_END, -+ 10000), -+ REGULATOR_LINEAR_RANGE(1140000, -+ AXP15060_DCDC5_1140mV_START, -+ AXP15060_DCDC5_1140mV_END, -+ 20000), -+}; -+ -+static const struct regulator_desc axp15060_regulators[] = { -+ AXP_DESC(AXP15060, DCDC1, "dcdc1", "vin1", 1500, 3400, 100, -+ AXP15060_DCDC1_V_CTRL, AXP15060_DCDC1_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC1_MASK), -+ AXP_DESC_RANGES(AXP15060, DCDC2, "dcdc2", "vin2", -+ axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES, -+ AXP15060_DCDC2_V_CTRL, AXP15060_DCDC2_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC2_MASK), -+ AXP_DESC_RANGES(AXP15060, DCDC3, "dcdc3", "vin3", -+ axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES, -+ AXP15060_DCDC3_V_CTRL, AXP15060_DCDC3_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC3_MASK), -+ AXP_DESC_RANGES(AXP15060, DCDC4, "dcdc4", "vin4", -+ axp15060_dcdc234_ranges, AXP15060_DCDC234_NUM_VOLTAGES, -+ AXP15060_DCDC4_V_CTRL, AXP15060_DCDC4_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC4_MASK), -+ AXP_DESC_RANGES(AXP15060, DCDC5, "dcdc5", "vin5", -+ axp15060_dcdc5_ranges, AXP15060_DCDC5_NUM_VOLTAGES, -+ AXP15060_DCDC5_V_CTRL, AXP15060_DCDC5_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC5_MASK), -+ AXP_DESC(AXP15060, DCDC6, "dcdc6", "vin6", 500, 3400, 100, -+ AXP15060_DCDC6_V_CTRL, AXP15060_DCDC6_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL1, AXP15060_PWR_OUT_DCDC6_MASK), -+ AXP_DESC(AXP15060, ALDO1, "aldo1", "aldoin", 700, 3300, 100, -+ AXP15060_ALDO1_V_CTRL, AXP15060_ALDO1_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO1_MASK), -+ AXP_DESC(AXP15060, ALDO2, "aldo2", "aldoin", 700, 3300, 100, -+ AXP15060_ALDO2_V_CTRL, AXP15060_ALDO2_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO2_MASK), -+ AXP_DESC(AXP15060, ALDO3, "aldo3", "aldoin", 700, 3300, 100, -+ AXP15060_ALDO3_V_CTRL, AXP15060_ALDO3_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO3_MASK), -+ AXP_DESC(AXP15060, ALDO4, "aldo4", "aldoin", 700, 3300, 100, -+ AXP15060_ALDO4_V_CTRL, AXP15060_ALDO4_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO4_MASK), -+ AXP_DESC(AXP15060, ALDO5, "aldo5", "aldoin", 700, 3300, 100, -+ AXP15060_ALDO5_V_CTRL, AXP15060_ALDO5_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_ALDO5_MASK), -+ AXP_DESC(AXP15060, BLDO1, "bldo1", "bldoin", 700, 3300, 100, -+ AXP15060_BLDO1_V_CTRL, AXP15060_BLDO1_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO1_MASK), -+ AXP_DESC(AXP15060, BLDO2, "bldo2", "bldoin", 700, 3300, 100, -+ AXP15060_BLDO2_V_CTRL, AXP15060_BLDO2_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO2_MASK), -+ AXP_DESC(AXP15060, BLDO3, "bldo3", "bldoin", 700, 3300, 100, -+ AXP15060_BLDO3_V_CTRL, AXP15060_BLDO3_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL2, AXP15060_PWR_OUT_BLDO3_MASK), -+ AXP_DESC(AXP15060, BLDO4, "bldo4", "bldoin", 700, 3300, 100, -+ AXP15060_BLDO4_V_CTRL, AXP15060_BLDO4_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_BLDO4_MASK), -+ AXP_DESC(AXP15060, BLDO5, "bldo5", "bldoin", 700, 3300, 100, -+ AXP15060_BLDO5_V_CTRL, AXP15060_BLDO5_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_BLDO5_MASK), -+ AXP_DESC(AXP15060, CLDO1, "cldo1", "cldoin", 700, 3300, 100, -+ AXP15060_CLDO1_V_CTRL, AXP15060_CLDO1_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO1_MASK), -+ AXP_DESC(AXP15060, CLDO2, "cldo2", "cldoin", 700, 3300, 100, -+ AXP15060_CLDO2_V_CTRL, AXP15060_CLDO2_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO2_MASK), -+ AXP_DESC(AXP15060, CLDO3, "cldo3", "cldoin", 700, 3300, 100, -+ AXP15060_CLDO3_V_CTRL, AXP15060_CLDO3_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO3_MASK), -+ AXP_DESC(AXP15060, CLDO4, "cldo4", "cldoin", 700, 4200, 100, -+ AXP15060_CLDO4_V_CTRL, AXP15060_CLDO4_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CLDO4_MASK), -+ /* Supply comes from DCDC5 */ -+ AXP_DESC(AXP15060, CPUSLDO, "cpusldo", NULL, 700, 1400, 50, -+ AXP15060_CPUSLDO_V_CTRL, AXP15060_CPUSLDO_V_CTRL_MASK, -+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_CPUSLDO_MASK), -+ /* Supply comes from DCDC1 */ -+ AXP_DESC_SW(AXP15060, SW, "sw", NULL, -+ AXP15060_PWR_OUT_CTRL3, AXP15060_PWR_OUT_SW_MASK), -+ /* Supply comes from ALDO1 */ -+ AXP_DESC_FIXED(AXP15060, RTC_LDO, "rtc-ldo", NULL, 1800), -+}; -+ - static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) - { - struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); -@@ -1088,10 +1254,11 @@ static int axp20x_set_dcdc_freq(struct p - step = 150; - break; - case AXP313A_ID: -+ case AXP15060_ID: - /* The DCDC PWM frequency seems to be fixed to 3 MHz. */ - if (dcdcfreq != 0) { - dev_err(&pdev->dev, -- "DCDC frequency on AXP313a is fixed to 3 MHz.\n"); -+ "DCDC frequency on this PMIC is fixed to 3 MHz.\n"); - return -EINVAL; - } - -@@ -1201,6 +1368,15 @@ static int axp20x_set_dcdc_workmode(stru - workmode <<= id - AXP813_DCDC1; - break; - -+ case AXP15060_ID: -+ reg = AXP15060_DCDC_MODE_CTRL2; -+ if (id < AXP15060_DCDC1 || id > AXP15060_DCDC6) -+ return -EINVAL; -+ -+ mask = AXP22X_WORKMODE_DCDCX_MASK(id - AXP15060_DCDC1); -+ workmode <<= id - AXP15060_DCDC1; -+ break; -+ - default: - /* should not happen */ - WARN_ON(1); -@@ -1220,7 +1396,7 @@ static bool axp20x_is_polyphase_slave(st - - /* - * Currently in our supported AXP variants, only AXP803, AXP806, -- * and AXP813 have polyphase regulators. -+ * AXP813 and AXP15060 have polyphase regulators. - */ - switch (axp20x->variant) { - case AXP803_ID: -@@ -1252,6 +1428,17 @@ static bool axp20x_is_polyphase_slave(st - } - break; - -+ case AXP15060_ID: -+ regmap_read(axp20x->regmap, AXP15060_DCDC_MODE_CTRL1, ®); -+ -+ switch (id) { -+ case AXP15060_DCDC3: -+ return !!(reg & AXP15060_DCDC23_POLYPHASE_DUAL_MASK); -+ case AXP15060_DCDC6: -+ return !!(reg & AXP15060_DCDC46_POLYPHASE_DUAL_MASK); -+ } -+ break; -+ - default: - return false; - } -@@ -1273,6 +1460,7 @@ static int axp20x_regulator_probe(struct - u32 workmode; - const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name; - const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name; -+ const char *aldo1_name = axp15060_regulators[AXP15060_ALDO1].name; - bool drivevbus = false; - - switch (axp20x->variant) { -@@ -1312,6 +1500,10 @@ static int axp20x_regulator_probe(struct - drivevbus = of_property_read_bool(pdev->dev.parent->of_node, - "x-powers,drive-vbus-en"); - break; -+ case AXP15060_ID: -+ regulators = axp15060_regulators; -+ nregulators = AXP15060_REG_ID_MAX; -+ break; - default: - dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n", - axp20x->variant); -@@ -1338,8 +1530,9 @@ static int axp20x_regulator_probe(struct - continue; - - /* -- * Regulators DC1SW and DC5LDO are connected internally, -- * so we have to handle their supply names separately. -+ * Regulators DC1SW, DC5LDO and RTCLDO on AXP15060 are -+ * connected internally, so we have to handle their supply -+ * names separately. - * - * We always register the regulators in proper sequence, - * so the supply names are correctly read. See the last -@@ -1348,7 +1541,8 @@ static int axp20x_regulator_probe(struct - */ - if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) || - (regulators == axp803_regulators && i == AXP803_DC1SW) || -- (regulators == axp809_regulators && i == AXP809_DC1SW)) { -+ (regulators == axp809_regulators && i == AXP809_DC1SW) || -+ (regulators == axp15060_regulators && i == AXP15060_SW)) { - new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), - GFP_KERNEL); - if (!new_desc) -@@ -1360,7 +1554,8 @@ static int axp20x_regulator_probe(struct - } - - if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) || -- (regulators == axp809_regulators && i == AXP809_DC5LDO)) { -+ (regulators == axp809_regulators && i == AXP809_DC5LDO) || -+ (regulators == axp15060_regulators && i == AXP15060_CPUSLDO)) { - new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), - GFP_KERNEL); - if (!new_desc) -@@ -1371,6 +1566,18 @@ static int axp20x_regulator_probe(struct - desc = new_desc; - } - -+ -+ if (regulators == axp15060_regulators && i == AXP15060_RTC_LDO) { -+ new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), -+ GFP_KERNEL); -+ if (!new_desc) -+ return -ENOMEM; -+ -+ *new_desc = regulators[i]; -+ new_desc->supply_name = aldo1_name; -+ desc = new_desc; -+ } -+ - rdev = devm_regulator_register(&pdev->dev, desc, &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "Failed to register %s\n", -@@ -1389,19 +1596,26 @@ static int axp20x_regulator_probe(struct - } - - /* -- * Save AXP22X DCDC1 / DCDC5 regulator names for later. -+ * Save AXP22X DCDC1 / DCDC5 / AXP15060 ALDO1 regulator names for later. - */ - if ((regulators == axp22x_regulators && i == AXP22X_DCDC1) || -- (regulators == axp809_regulators && i == AXP809_DCDC1)) -+ (regulators == axp809_regulators && i == AXP809_DCDC1) || -+ (regulators == axp15060_regulators && i == AXP15060_DCDC1)) - of_property_read_string(rdev->dev.of_node, - "regulator-name", - &dcdc1_name); - - if ((regulators == axp22x_regulators && i == AXP22X_DCDC5) || -- (regulators == axp809_regulators && i == AXP809_DCDC5)) -+ (regulators == axp809_regulators && i == AXP809_DCDC5) || -+ (regulators == axp15060_regulators && i == AXP15060_DCDC5)) - of_property_read_string(rdev->dev.of_node, - "regulator-name", - &dcdc5_name); -+ -+ if (regulators == axp15060_regulators && i == AXP15060_ALDO1) -+ of_property_read_string(rdev->dev.of_node, -+ "regulator-name", -+ &aldo1_name); - } - - if (drivevbus) { diff --git a/target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch b/target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch deleted file mode 100644 index d75b4e74534798..00000000000000 --- a/target/linux/generic/backport-6.1/887-v6.5-mfd-axp20x-Add-support-for-AXP192.patch +++ /dev/null @@ -1,383 +0,0 @@ -From 63eeabbc9dbddd7381409feccd9082e5ffabfe59 Mon Sep 17 00:00:00 2001 -From: Aidan MacDonald -Date: Thu, 11 May 2023 10:26:08 +0100 -Subject: [PATCH] mfd: axp20x: Add support for AXP192 - -The AXP192 PMIC is similar to the AXP202/AXP209, but with different -regulators, additional GPIOs, and a different IRQ register layout. - -Signed-off-by: Aidan MacDonald -Link: https://lore.kernel.org/r/20230511092609.76183-1-aidanmacdonald.0x0@gmail.com -Signed-off-by: Lee Jones ---- - drivers/mfd/axp20x-i2c.c | 2 + - drivers/mfd/axp20x.c | 141 +++++++++++++++++++++++++++++++++++++ - include/linux/mfd/axp20x.h | 84 ++++++++++++++++++++++ - 3 files changed, 227 insertions(+) - ---- a/drivers/mfd/axp20x-i2c.c -+++ b/drivers/mfd/axp20x-i2c.c -@@ -60,6 +60,7 @@ static void axp20x_i2c_remove(struct i2c - #ifdef CONFIG_OF - static const struct of_device_id axp20x_i2c_of_match[] = { - { .compatible = "x-powers,axp152", .data = (void *)AXP152_ID }, -+ { .compatible = "x-powers,axp192", .data = (void *)AXP192_ID }, - { .compatible = "x-powers,axp202", .data = (void *)AXP202_ID }, - { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID }, - { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID }, -@@ -75,6 +76,7 @@ MODULE_DEVICE_TABLE(of, axp20x_i2c_of_ma - - static const struct i2c_device_id axp20x_i2c_id[] = { - { "axp152", 0 }, -+ { "axp192", 0 }, - { "axp202", 0 }, - { "axp209", 0 }, - { "axp221", 0 }, ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -34,6 +34,7 @@ - - static const char * const axp20x_model_names[] = { - "AXP152", -+ "AXP192", - "AXP202", - "AXP209", - "AXP221", -@@ -94,6 +95,35 @@ static const struct regmap_access_table - .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), - }; - -+static const struct regmap_range axp192_writeable_ranges[] = { -+ regmap_reg_range(AXP192_DATACACHE(0), AXP192_DATACACHE(5)), -+ regmap_reg_range(AXP192_PWR_OUT_CTRL, AXP192_IRQ5_STATE), -+ regmap_reg_range(AXP20X_DCDC_MODE, AXP192_N_RSTO_CTRL), -+ regmap_reg_range(AXP20X_CC_CTRL, AXP20X_CC_CTRL), -+}; -+ -+static const struct regmap_range axp192_volatile_ranges[] = { -+ regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP192_USB_OTG_STATUS), -+ regmap_reg_range(AXP192_IRQ1_STATE, AXP192_IRQ4_STATE), -+ regmap_reg_range(AXP192_IRQ5_STATE, AXP192_IRQ5_STATE), -+ regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L), -+ regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL), -+ regmap_reg_range(AXP192_GPIO2_0_STATE, AXP192_GPIO2_0_STATE), -+ regmap_reg_range(AXP192_GPIO4_3_STATE, AXP192_GPIO4_3_STATE), -+ regmap_reg_range(AXP192_N_RSTO_CTRL, AXP192_N_RSTO_CTRL), -+ regmap_reg_range(AXP20X_CHRG_CC_31_24, AXP20X_CC_CTRL), -+}; -+ -+static const struct regmap_access_table axp192_writeable_table = { -+ .yes_ranges = axp192_writeable_ranges, -+ .n_yes_ranges = ARRAY_SIZE(axp192_writeable_ranges), -+}; -+ -+static const struct regmap_access_table axp192_volatile_table = { -+ .yes_ranges = axp192_volatile_ranges, -+ .n_yes_ranges = ARRAY_SIZE(axp192_volatile_ranges), -+}; -+ - /* AXP22x ranges are shared with the AXP809, as they cover the same range */ - static const struct regmap_range axp22x_writeable_ranges[] = { - regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), -@@ -220,6 +250,19 @@ static const struct resource axp152_pek_ - DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"), - }; - -+static const struct resource axp192_ac_power_supply_resources[] = { -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"), -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"), -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_ACIN_OVER_V, "ACIN_OVER_V"), -+}; -+ -+static const struct resource axp192_usb_power_supply_resources[] = { -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_VALID, "VBUS_VALID"), -+ DEFINE_RES_IRQ_NAMED(AXP192_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"), -+}; -+ - static const struct resource axp20x_ac_power_supply_resources[] = { - DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"), - DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"), -@@ -302,6 +345,15 @@ static const struct regmap_config axp152 - .cache_type = REGCACHE_RBTREE, - }; - -+static const struct regmap_config axp192_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ .wr_table = &axp192_writeable_table, -+ .volatile_table = &axp192_volatile_table, -+ .max_register = AXP20X_CC_CTRL, -+ .cache_type = REGCACHE_RBTREE, -+}; -+ - static const struct regmap_config axp20x_regmap_config = { - .reg_bits = 8, - .val_bits = 8, -@@ -379,6 +431,42 @@ static const struct regmap_irq axp152_re - INIT_REGMAP_IRQ(AXP152, GPIO0_INPUT, 2, 0), - }; - -+static const struct regmap_irq axp192_regmap_irqs[] = { -+ INIT_REGMAP_IRQ(AXP192, ACIN_OVER_V, 0, 7), -+ INIT_REGMAP_IRQ(AXP192, ACIN_PLUGIN, 0, 6), -+ INIT_REGMAP_IRQ(AXP192, ACIN_REMOVAL, 0, 5), -+ INIT_REGMAP_IRQ(AXP192, VBUS_OVER_V, 0, 4), -+ INIT_REGMAP_IRQ(AXP192, VBUS_PLUGIN, 0, 3), -+ INIT_REGMAP_IRQ(AXP192, VBUS_REMOVAL, 0, 2), -+ INIT_REGMAP_IRQ(AXP192, VBUS_V_LOW, 0, 1), -+ INIT_REGMAP_IRQ(AXP192, BATT_PLUGIN, 1, 7), -+ INIT_REGMAP_IRQ(AXP192, BATT_REMOVAL, 1, 6), -+ INIT_REGMAP_IRQ(AXP192, BATT_ENT_ACT_MODE, 1, 5), -+ INIT_REGMAP_IRQ(AXP192, BATT_EXIT_ACT_MODE, 1, 4), -+ INIT_REGMAP_IRQ(AXP192, CHARG, 1, 3), -+ INIT_REGMAP_IRQ(AXP192, CHARG_DONE, 1, 2), -+ INIT_REGMAP_IRQ(AXP192, BATT_TEMP_HIGH, 1, 1), -+ INIT_REGMAP_IRQ(AXP192, BATT_TEMP_LOW, 1, 0), -+ INIT_REGMAP_IRQ(AXP192, DIE_TEMP_HIGH, 2, 7), -+ INIT_REGMAP_IRQ(AXP192, CHARG_I_LOW, 2, 6), -+ INIT_REGMAP_IRQ(AXP192, DCDC1_V_LONG, 2, 5), -+ INIT_REGMAP_IRQ(AXP192, DCDC2_V_LONG, 2, 4), -+ INIT_REGMAP_IRQ(AXP192, DCDC3_V_LONG, 2, 3), -+ INIT_REGMAP_IRQ(AXP192, PEK_SHORT, 2, 1), -+ INIT_REGMAP_IRQ(AXP192, PEK_LONG, 2, 0), -+ INIT_REGMAP_IRQ(AXP192, N_OE_PWR_ON, 3, 7), -+ INIT_REGMAP_IRQ(AXP192, N_OE_PWR_OFF, 3, 6), -+ INIT_REGMAP_IRQ(AXP192, VBUS_VALID, 3, 5), -+ INIT_REGMAP_IRQ(AXP192, VBUS_NOT_VALID, 3, 4), -+ INIT_REGMAP_IRQ(AXP192, VBUS_SESS_VALID, 3, 3), -+ INIT_REGMAP_IRQ(AXP192, VBUS_SESS_END, 3, 2), -+ INIT_REGMAP_IRQ(AXP192, LOW_PWR_LVL, 3, 0), -+ INIT_REGMAP_IRQ(AXP192, TIMER, 4, 7), -+ INIT_REGMAP_IRQ(AXP192, GPIO2_INPUT, 4, 2), -+ INIT_REGMAP_IRQ(AXP192, GPIO1_INPUT, 4, 1), -+ INIT_REGMAP_IRQ(AXP192, GPIO0_INPUT, 4, 0), -+}; -+ - static const struct regmap_irq axp20x_regmap_irqs[] = { - INIT_REGMAP_IRQ(AXP20X, ACIN_OVER_V, 0, 7), - INIT_REGMAP_IRQ(AXP20X, ACIN_PLUGIN, 0, 6), -@@ -616,6 +704,32 @@ static const struct regmap_irq_chip axp1 - .num_regs = 3, - }; - -+static unsigned int axp192_get_irq_reg(struct regmap_irq_chip_data *data, -+ unsigned int base, int index) -+{ -+ /* linear mapping for IRQ1 to IRQ4 */ -+ if (index < 4) -+ return base + index; -+ -+ /* handle IRQ5 separately */ -+ if (base == AXP192_IRQ1_EN) -+ return AXP192_IRQ5_EN; -+ -+ return AXP192_IRQ5_STATE; -+} -+ -+static const struct regmap_irq_chip axp192_regmap_irq_chip = { -+ .name = "axp192_irq_chip", -+ .status_base = AXP192_IRQ1_STATE, -+ .ack_base = AXP192_IRQ1_STATE, -+ .unmask_base = AXP192_IRQ1_EN, -+ .init_ack_masked = true, -+ .irqs = axp192_regmap_irqs, -+ .num_irqs = ARRAY_SIZE(axp192_regmap_irqs), -+ .num_regs = 5, -+ .get_irq_reg = axp192_get_irq_reg, -+}; -+ - static const struct regmap_irq_chip axp20x_regmap_irq_chip = { - .name = "axp20x_irq_chip", - .status_base = AXP20X_IRQ1_STATE, -@@ -712,6 +826,27 @@ static const struct regmap_irq_chip axp1 - .num_regs = 2, - }; - -+static const struct mfd_cell axp192_cells[] = { -+ { -+ .name = "axp192-adc", -+ .of_compatible = "x-powers,axp192-adc", -+ }, { -+ .name = "axp20x-battery-power-supply", -+ .of_compatible = "x-powers,axp192-battery-power-supply", -+ }, { -+ .name = "axp20x-ac-power-supply", -+ .of_compatible = "x-powers,axp202-ac-power-supply", -+ .num_resources = ARRAY_SIZE(axp192_ac_power_supply_resources), -+ .resources = axp192_ac_power_supply_resources, -+ }, { -+ .name = "axp20x-usb-power-supply", -+ .of_compatible = "x-powers,axp192-usb-power-supply", -+ .num_resources = ARRAY_SIZE(axp192_usb_power_supply_resources), -+ .resources = axp192_usb_power_supply_resources, -+ }, -+ { .name = "axp20x-regulator" }, -+}; -+ - static const struct mfd_cell axp20x_cells[] = { - { - .name = "axp20x-gpio", -@@ -1029,6 +1164,12 @@ int axp20x_match_device(struct axp20x_de - axp20x->regmap_cfg = &axp152_regmap_config; - axp20x->regmap_irq_chip = &axp152_regmap_irq_chip; - break; -+ case AXP192_ID: -+ axp20x->nr_cells = ARRAY_SIZE(axp192_cells); -+ axp20x->cells = axp192_cells; -+ axp20x->regmap_cfg = &axp192_regmap_config; -+ axp20x->regmap_irq_chip = &axp192_regmap_irq_chip; -+ break; - case AXP202_ID: - case AXP209_ID: - axp20x->nr_cells = ARRAY_SIZE(axp20x_cells); ---- a/include/linux/mfd/axp20x.h -+++ b/include/linux/mfd/axp20x.h -@@ -12,6 +12,7 @@ - - enum axp20x_variants { - AXP152_ID = 0, -+ AXP192_ID, - AXP202_ID, - AXP209_ID, - AXP221_ID, -@@ -26,6 +27,7 @@ enum axp20x_variants { - NR_AXP20X_VARIANTS, - }; - -+#define AXP192_DATACACHE(m) (0x06 + (m)) - #define AXP20X_DATACACHE(m) (0x04 + (m)) - - /* Power supply */ -@@ -47,6 +49,13 @@ enum axp20x_variants { - #define AXP152_DCDC_FREQ 0x37 - #define AXP152_DCDC_MODE 0x80 - -+#define AXP192_USB_OTG_STATUS 0x04 -+#define AXP192_PWR_OUT_CTRL 0x12 -+#define AXP192_DCDC2_V_OUT 0x23 -+#define AXP192_DCDC1_V_OUT 0x26 -+#define AXP192_DCDC3_V_OUT 0x27 -+#define AXP192_LDO2_3_V_OUT 0x28 -+ - #define AXP20X_PWR_INPUT_STATUS 0x00 - #define AXP20X_PWR_OP_MODE 0x01 - #define AXP20X_USB_OTG_STATUS 0x02 -@@ -185,6 +194,17 @@ enum axp20x_variants { - #define AXP152_IRQ2_STATE 0x49 - #define AXP152_IRQ3_STATE 0x4a - -+#define AXP192_IRQ1_EN 0x40 -+#define AXP192_IRQ2_EN 0x41 -+#define AXP192_IRQ3_EN 0x42 -+#define AXP192_IRQ4_EN 0x43 -+#define AXP192_IRQ1_STATE 0x44 -+#define AXP192_IRQ2_STATE 0x45 -+#define AXP192_IRQ3_STATE 0x46 -+#define AXP192_IRQ4_STATE 0x47 -+#define AXP192_IRQ5_EN 0x4a -+#define AXP192_IRQ5_STATE 0x4d -+ - #define AXP20X_IRQ1_EN 0x40 - #define AXP20X_IRQ2_EN 0x41 - #define AXP20X_IRQ3_EN 0x42 -@@ -204,6 +224,11 @@ enum axp20x_variants { - #define AXP15060_IRQ2_STATE 0x49 - - /* ADC */ -+#define AXP192_GPIO2_V_ADC_H 0x68 -+#define AXP192_GPIO2_V_ADC_L 0x69 -+#define AXP192_GPIO3_V_ADC_H 0x6a -+#define AXP192_GPIO3_V_ADC_L 0x6b -+ - #define AXP20X_ACIN_V_ADC_H 0x56 - #define AXP20X_ACIN_V_ADC_L 0x57 - #define AXP20X_ACIN_I_ADC_H 0x58 -@@ -233,6 +258,8 @@ enum axp20x_variants { - #define AXP20X_IPSOUT_V_HIGH_L 0x7f - - /* Power supply */ -+#define AXP192_GPIO30_IN_RANGE 0x85 -+ - #define AXP20X_DCDC_MODE 0x80 - #define AXP20X_ADC_EN1 0x82 - #define AXP20X_ADC_EN2 0x83 -@@ -261,6 +288,16 @@ enum axp20x_variants { - #define AXP152_PWM1_FREQ_Y 0x9c - #define AXP152_PWM1_DUTY_CYCLE 0x9d - -+#define AXP192_GPIO0_CTRL 0x90 -+#define AXP192_LDO_IO0_V_OUT 0x91 -+#define AXP192_GPIO1_CTRL 0x92 -+#define AXP192_GPIO2_CTRL 0x93 -+#define AXP192_GPIO2_0_STATE 0x94 -+#define AXP192_GPIO4_3_CTRL 0x95 -+#define AXP192_GPIO4_3_STATE 0x96 -+#define AXP192_GPIO2_0_PULL 0x97 -+#define AXP192_N_RSTO_CTRL 0x9e -+ - #define AXP20X_GPIO0_CTRL 0x90 - #define AXP20X_LDO5_V_OUT 0x91 - #define AXP20X_GPIO1_CTRL 0x92 -@@ -341,6 +378,17 @@ enum axp20x_variants { - - /* Regulators IDs */ - enum { -+ AXP192_DCDC1 = 0, -+ AXP192_DCDC2, -+ AXP192_DCDC3, -+ AXP192_LDO1, -+ AXP192_LDO2, -+ AXP192_LDO3, -+ AXP192_LDO_IO0, -+ AXP192_REG_ID_MAX -+}; -+ -+enum { - AXP20X_LDO1 = 0, - AXP20X_LDO2, - AXP20X_LDO3, -@@ -531,6 +579,42 @@ enum { - AXP152_IRQ_GPIO0_INPUT, - }; - -+enum axp192_irqs { -+ AXP192_IRQ_ACIN_OVER_V = 1, -+ AXP192_IRQ_ACIN_PLUGIN, -+ AXP192_IRQ_ACIN_REMOVAL, -+ AXP192_IRQ_VBUS_OVER_V, -+ AXP192_IRQ_VBUS_PLUGIN, -+ AXP192_IRQ_VBUS_REMOVAL, -+ AXP192_IRQ_VBUS_V_LOW, -+ AXP192_IRQ_BATT_PLUGIN, -+ AXP192_IRQ_BATT_REMOVAL, -+ AXP192_IRQ_BATT_ENT_ACT_MODE, -+ AXP192_IRQ_BATT_EXIT_ACT_MODE, -+ AXP192_IRQ_CHARG, -+ AXP192_IRQ_CHARG_DONE, -+ AXP192_IRQ_BATT_TEMP_HIGH, -+ AXP192_IRQ_BATT_TEMP_LOW, -+ AXP192_IRQ_DIE_TEMP_HIGH, -+ AXP192_IRQ_CHARG_I_LOW, -+ AXP192_IRQ_DCDC1_V_LONG, -+ AXP192_IRQ_DCDC2_V_LONG, -+ AXP192_IRQ_DCDC3_V_LONG, -+ AXP192_IRQ_PEK_SHORT = 22, -+ AXP192_IRQ_PEK_LONG, -+ AXP192_IRQ_N_OE_PWR_ON, -+ AXP192_IRQ_N_OE_PWR_OFF, -+ AXP192_IRQ_VBUS_VALID, -+ AXP192_IRQ_VBUS_NOT_VALID, -+ AXP192_IRQ_VBUS_SESS_VALID, -+ AXP192_IRQ_VBUS_SESS_END, -+ AXP192_IRQ_LOW_PWR_LVL = 31, -+ AXP192_IRQ_TIMER, -+ AXP192_IRQ_GPIO2_INPUT = 37, -+ AXP192_IRQ_GPIO1_INPUT, -+ AXP192_IRQ_GPIO0_INPUT, -+}; -+ - enum { - AXP20X_IRQ_ACIN_OVER_V = 1, - AXP20X_IRQ_ACIN_PLUGIN, diff --git a/target/linux/generic/backport-6.1/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch b/target/linux/generic/backport-6.1/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch deleted file mode 100644 index 38fbc3a3d73f33..00000000000000 --- a/target/linux/generic/backport-6.1/890-v6.2-mtd-spinand-winbond-fix-flash-detection.patch +++ /dev/null @@ -1,40 +0,0 @@ -From dbf70fc204d2fbb0d8ad8f42038a60846502efda Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Mon, 10 Oct 2022 13:51:09 +0300 -Subject: [PATCH] mtd: spinand: winbond: fix flash identification - -Winbond uses 3 bytes to identify flash: vendor_id, dev_id_0, dev_id_1, -but current driver uses only first 2 bytes of it for devices -identification. As result Winbond W25N02KV flash (id_bytes: EF, AA, 22) -is identified as W25N01GV (id_bytes: EF, AA, 21). - -Fix this by adding missed identification bytes. - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: Frieder Schrempf -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221010105110.446674-1-mikhail.kshevetskiy@iopsys.eu ---- - drivers/mtd/nand/spi/winbond.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/mtd/nand/spi/winbond.c -+++ b/drivers/mtd/nand/spi/winbond.c -@@ -76,7 +76,7 @@ static int w25m02gv_select_target(struct - - static const struct spinand_info winbond_spinand_table[] = { - SPINAND_INFO("W25M02GV", -- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab), -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21), - NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2), - NAND_ECCREQ(1, 512), - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -@@ -86,7 +86,7 @@ static const struct spinand_info winbond - SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), - SPINAND_SELECT_TARGET(w25m02gv_select_target)), - SPINAND_INFO("W25N01GV", -- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa), -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21), - NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), - NAND_ECCREQ(1, 512), - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, diff --git a/target/linux/generic/backport-6.1/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch b/target/linux/generic/backport-6.1/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch deleted file mode 100644 index d75a1acc57c765..00000000000000 --- a/target/linux/generic/backport-6.1/891-v6.2-mtd-spinand-winbond-add-W25N02KV.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 6154c7a583483d7b69f53bea868efdc369edd563 Mon Sep 17 00:00:00 2001 -From: Mikhail Kshevetskiy -Date: Mon, 10 Oct 2022 13:51:10 +0300 -Subject: [PATCH] mtd: spinand: winbond: add Winbond W25N02KV flash support - -Add support of Winbond W25N02KV flash - -Signed-off-by: Mikhail Kshevetskiy -Reviewed-by: Frieder Schrempf -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/20221010105110.446674-2-mikhail.kshevetskiy@iopsys.eu ---- - drivers/mtd/nand/spi/winbond.c | 75 ++++++++++++++++++++++++++++++++++ - 1 file changed, 75 insertions(+) - ---- a/drivers/mtd/nand/spi/winbond.c -+++ b/drivers/mtd/nand/spi/winbond.c -@@ -74,6 +74,72 @@ static int w25m02gv_select_target(struct - return spi_mem_exec_op(spinand->spimem, &op); - } - -+static int w25n02kv_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section > 3) -+ return -ERANGE; -+ -+ region->offset = 64 + (16 * section); -+ region->length = 13; -+ -+ return 0; -+} -+ -+static int w25n02kv_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section > 3) -+ return -ERANGE; -+ -+ region->offset = (16 * section) + 2; -+ region->length = 14; -+ -+ return 0; -+} -+ -+static const struct mtd_ooblayout_ops w25n02kv_ooblayout = { -+ .ecc = w25n02kv_ooblayout_ecc, -+ .free = w25n02kv_ooblayout_free, -+}; -+ -+static int w25n02kv_ecc_get_status(struct spinand_device *spinand, -+ u8 status) -+{ -+ struct nand_device *nand = spinand_to_nand(spinand); -+ u8 mbf = 0; -+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); -+ -+ switch (status & STATUS_ECC_MASK) { -+ case STATUS_ECC_NO_BITFLIPS: -+ return 0; -+ -+ case STATUS_ECC_UNCOR_ERROR: -+ return -EBADMSG; -+ -+ case STATUS_ECC_HAS_BITFLIPS: -+ /* -+ * Let's try to retrieve the real maximum number of bitflips -+ * in order to avoid forcing the wear-leveling layer to move -+ * data around if it's not necessary. -+ */ -+ if (spi_mem_exec_op(spinand->spimem, &op)) -+ return nanddev_get_ecc_conf(nand)->strength; -+ -+ mbf >>= 4; -+ -+ if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) -+ return nanddev_get_ecc_conf(nand)->strength; -+ -+ return mbf; -+ -+ default: -+ break; -+ } -+ -+ return -EINVAL; -+} -+ - static const struct spinand_info winbond_spinand_table[] = { - SPINAND_INFO("W25M02GV", - SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21), -@@ -94,6 +160,15 @@ static const struct spinand_info winbond - &update_cache_variants), - 0, - SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)), -+ SPINAND_INFO("W25N02KV", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22), -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ 0, -+ SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), - }; - - static int winbond_spinand_init(struct spinand_device *spinand) diff --git a/target/linux/generic/backport-6.1/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch b/target/linux/generic/backport-6.1/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch deleted file mode 100644 index 2f408f5a30090d..00000000000000 --- a/target/linux/generic/backport-6.1/892-v6.5-mtd-spinand-winbond-Fix-ecc_get_status.patch +++ /dev/null @@ -1,49 +0,0 @@ -From f5a05060670a4d8d6523afc7963eb559c2e3615f Mon Sep 17 00:00:00 2001 -From: Olivier Maignial -Date: Fri, 23 Jun 2023 17:33:37 +0200 -Subject: [PATCH] mtd: spinand: winbond: Fix ecc_get_status - -Reading ECC status is failing. - -w25n02kv_ecc_get_status() is using on-stack buffer for -SPINAND_GET_FEATURE_OP() output. It is not suitable for -DMA needs of spi-mem. - -Fix this by using the spi-mem operations dedicated buffer -spinand->scratchbuf. - -See -spinand->scratchbuf: -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/mtd/spinand.h?h=v6.3#n418 -spi_mem_check_op(): -https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-mem.c?h=v6.3#n199 - -Fixes: 6154c7a58348 ("mtd: spinand: winbond: add Winbond W25N02KV flash support") -Cc: stable@vger.kernel.org -Signed-off-by: Olivier Maignial -Signed-off-by: Miquel Raynal -Link: https://lore.kernel.org/linux-mtd/DB4P250MB1032EDB9E36B764A33769039FE23A@DB4P250MB1032.EURP250.PROD.OUTLOOK.COM ---- - drivers/mtd/nand/spi/winbond.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/mtd/nand/spi/winbond.c -+++ b/drivers/mtd/nand/spi/winbond.c -@@ -108,7 +108,7 @@ static int w25n02kv_ecc_get_status(struc - { - struct nand_device *nand = spinand_to_nand(spinand); - u8 mbf = 0; -- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); -+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf); - - switch (status & STATUS_ECC_MASK) { - case STATUS_ECC_NO_BITFLIPS: -@@ -126,7 +126,7 @@ static int w25n02kv_ecc_get_status(struc - if (spi_mem_exec_op(spinand->spimem, &op)) - return nanddev_get_ecc_conf(nand)->strength; - -- mbf >>= 4; -+ mbf = *(spinand->scratchbuf) >> 4; - - if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) - return nanddev_get_ecc_conf(nand)->strength; diff --git a/target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch b/target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch deleted file mode 100644 index 379a4fc7c074ae..00000000000000 --- a/target/linux/generic/backport-6.1/894-v6.8-net-ethtool-implement-ethtool_puts.patch +++ /dev/null @@ -1,139 +0,0 @@ -From mboxrd@z Thu Jan 1 00:00:00 1970 -Authentication-Results: smtp.subspace.kernel.org; - dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="sMUeie/T" -Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84BB8D6D - for ; Wed, 6 Dec 2023 15:16:16 -0800 (PST) -Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-db5416d0fccso403298276.1 - for ; Wed, 06 Dec 2023 15:16:16 -0800 (PST) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=google.com; s=20230601; t=1701904575; x=1702509375; darn=vger.kernel.org; - h=cc:to:from:subject:message-id:references:mime-version:in-reply-to - :date:from:to:cc:subject:date:message-id:reply-to; - bh=/7eYcPC4ZNNyPcPPs0B5tDplF0arxw3r0vINNNou0rY=; - b=sMUeie/TxdytzC0EyT11QWi1TqTtiv7KCTs1F2vLmUUvPKNA3+1MHFo8ECW+0gQuDE - FGrgdZKGK5mXQgkF0N3JiSLvKO8tpQOIB57JLCG5IVy5dr2vVv0ExU3Dag2Cc4oBIBIO - w/cH95O1oPlvluIpATmAsxenVr7mFomU63BqYiRGLaEhWeb2hJ636GO8lubtsDfdFFoi - GPOL2tQwV93VnqmywBBpFaNAULN0UoCFhfkKv5prvpkXq19sWI7zyorVZ+rdTYem5m4T - dXsDaLXPtC3Dh2JOad1duSQIah/wCHYYUcV3IoFhwj2y0Uk/TTCrnZPORweSADcEy6Ho - vDrA== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20230601; t=1701904575; x=1702509375; - h=cc:to:from:subject:message-id:references:mime-version:in-reply-to - :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; - bh=/7eYcPC4ZNNyPcPPs0B5tDplF0arxw3r0vINNNou0rY=; - b=Dmc6aSntxPlxAk72zVO1G9WoZnFtLolxENlLscYYAHG3VE+PQ8gGN2rPzcGoKb2Btb - 4b0PvjOzSlPQyghahdhdlz04RtAeeGG/MkfNiYjFql5OifIoovb51kroiPYrVsa7Ps7Y - +Pxug0+NPdTm5s9TNz940ZKl3GRME8UTmVxpWJRX03XMOqb6Wgsh2SK9ahXKc4yRsi62 - 3a3J72WmmSgvimxwM/99fXwvoUQpiv2J1xCoqc1Ng4q4qSuZvzmHN7ZTGaUhLxOqLeLK - 3W4RKHW6rZ7UjppuB6I3NXW+D344By2rdKp1sRXpjdQ0GS3YUcvlRETcJBXJudHfQP5Y - CLOw== -X-Gm-Message-State: AOJu0YzdCTLdwny+N99zeMgyKqFsEZhfIhL2cbgKA6zC1U/OLkxxRLoM - XrYVBC9DmxCGmP4o+M/Z/kHUew/9faHlCiLGxw== -X-Google-Smtp-Source: AGHT+IFRXxBV6JuX5Cl/k2o1+WKkCwkR8j20MJSkmoGCedPAtqFttH8OVh1/6vdfnq8MPN++A2h89peZQhyG8OsJ8A== -X-Received: from jstitt-linux1.c.googlers.com ([fda3:e722:ac3:cc00:2b:ff92:c0a8:23b5]) - (user=justinstitt job=sendgmr) by 2002:a25:dac7:0:b0:da0:3117:f35 with SMTP - id n190-20020a25dac7000000b00da031170f35mr28652ybf.3.1701904575576; Wed, 06 - Dec 2023 15:16:15 -0800 (PST) -Date: Wed, 06 Dec 2023 23:16:10 +0000 -In-Reply-To: <20231206-ethtool_puts_impl-v5-0-5a2528e17bf8@google.com> -Precedence: bulk -X-Mailing-List: bpf@vger.kernel.org -List-Id: -List-Subscribe: -List-Unsubscribe: -Mime-Version: 1.0 -References: <20231206-ethtool_puts_impl-v5-0-5a2528e17bf8@google.com> -X-Developer-Key: i=justinstitt@google.com; a=ed25519; pk=tC3hNkJQTpNX/gLKxTNQKDmiQl6QjBNCGKJINqAdJsE= -X-Developer-Signature: v=1; a=ed25519-sha256; t=1701904573; l=1840; - i=justinstitt@google.com; s=20230717; h=from:subject:message-id; - bh=UMdetIL2ZsPIkSodqhw2fM21NHJVjCu0lRImFuNhVoM=; b=a8rMnXfVVQ5gsxHWG4WRMwOLxZgflqXZtNuKx26vv4DwYvvCtCiYjl3f1frOjV/Ul2kaxq5g/ - b/UOv678JKCDASVokxG5GJifAnU7/kqRxdhcwfRkrD8RUfcsmiZOfyF -X-Mailer: b4 0.12.3 -Message-ID: <20231206-ethtool_puts_impl-v5-1-5a2528e17bf8@google.com> -Subject: [PATCH net-next v5 1/3] ethtool: Implement ethtool_puts() -From: justinstitt@google.com -To: "David S. Miller" , Eric Dumazet , - Jakub Kicinski , Paolo Abeni , Shay Agroskin , - Arthur Kiyanovski , David Arinzon , Noam Dagan , - Saeed Bishara , Rasesh Mody , - Sudarsana Kalluru , GR-Linux-NIC-Dev@marvell.com, - Dimitris Michailidis , Yisen Zhuang , - Salil Mehta , Jesse Brandeburg , - Tony Nguyen , Louis Peens , - Shannon Nelson , Brett Creeley , drivers@pensando.io, - "K. Y. Srinivasan" , Haiyang Zhang , Wei Liu , - Dexuan Cui , Ronak Doshi , - VMware PV-Drivers Reviewers , Andy Whitcroft , Joe Perches , - Dwaipayan Ray , Lukas Bulwahn , - Hauke Mehrtens , Andrew Lunn , - Florian Fainelli , Vladimir Oltean , - "=?utf-8?q?Ar=C4=B1n=C3=A7_=C3=9CNAL?=" , Daniel Golle , - Landen Chao , DENG Qingfang , - Sean Wang , Matthias Brugger , - AngeloGioacchino Del Regno , - Linus Walleij , - "=?utf-8?q?Alvin_=C5=A0ipraga?=" , Wei Fang , - Shenwei Wang , Clark Wang , - NXP Linux Team , Lars Povlsen , - Steen Hegelund , Daniel Machon , - UNGLinuxDriver@microchip.com, Jiawen Wu , - Mengyuan Lou , Heiner Kallweit , - Russell King , Alexei Starovoitov , - Daniel Borkmann , Jesper Dangaard Brouer , - John Fastabend -Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, - Nick Desaulniers , Nathan Chancellor , - Kees Cook , intel-wired-lan@lists.osuosl.org, - oss-drivers@corigine.com, linux-hyperv@vger.kernel.org, - linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, - bpf@vger.kernel.org, Justin Stitt -Content-Type: text/plain; charset="utf-8" - -Use strscpy() to implement ethtool_puts(). - -Functionally the same as ethtool_sprintf() when it's used with two -arguments or with just "%s" format specifier. - -Signed-off-by: Justin Stitt ---- - include/linux/ethtool.h | 13 +++++++++++++ - net/ethtool/ioctl.c | 7 +++++++ - 2 files changed, 20 insertions(+) - ---- a/include/linux/ethtool.h -+++ b/include/linux/ethtool.h -@@ -843,4 +843,17 @@ int ethtool_get_phc_vclocks(struct net_d - * next string. - */ - extern __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...); -+ -+/** -+ * ethtool_puts - Write string to ethtool string data -+ * @data: Pointer to a pointer to the start of string to update -+ * @str: String to write -+ * -+ * Write string to *data without a trailing newline. Update *data -+ * to point at start of next string. -+ * -+ * Prefer this function to ethtool_sprintf() when given only -+ * two arguments or if @fmt is just "%s". -+ */ -+extern void ethtool_puts(u8 **data, const char *str); - #endif /* _LINUX_ETHTOOL_H */ ---- a/net/ethtool/ioctl.c -+++ b/net/ethtool/ioctl.c -@@ -1977,6 +1977,13 @@ __printf(2, 3) void ethtool_sprintf(u8 * - } - EXPORT_SYMBOL(ethtool_sprintf); - -+void ethtool_puts(u8 **data, const char *str) -+{ -+ strscpy(*data, str, ETH_GSTRING_LEN); -+ *data += ETH_GSTRING_LEN; -+} -+EXPORT_SYMBOL(ethtool_puts); -+ - static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) - { - struct ethtool_value id; diff --git a/target/linux/generic/backport-6.1/895-01-v6.8-net-phy-add-possible-interfaces.patch b/target/linux/generic/backport-6.1/895-01-v6.8-net-phy-add-possible-interfaces.patch deleted file mode 100644 index 3a9b856a2065f1..00000000000000 --- a/target/linux/generic/backport-6.1/895-01-v6.8-net-phy-add-possible-interfaces.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 1a7aa058bc92f0edae7a0d1ef1a7b05aec0c643a Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 24 Nov 2023 12:27:52 +0000 -Subject: [PATCH 1/7] net: phy: add possible interfaces - -Add a possible_interfaces member to struct phy_device to indicate which -interfaces a clause 45 PHY may switch between depending on the media. -This must be populated by the PHY driver by the time the .config_init() -method completes according to the PHYs host-side configuration. - -For example, the Marvell 88x3310 PHY can switch between 10GBASE-R, -5GBASE-R, 2500BASE-X, and SGMII on the host side depending on the media -side speed, so all these interface modes are set in the -possible_interfaces member. - -This allows phylib users (such as phylink) to know in advance which -interface modes to expect, which allows them to appropriately restrict -the advertised link modes according to the capabilities of other parts -of the link. - -Tested-by: Luo Jie -Signed-off-by: Russell King (Oracle) -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/E1r6VHk-00DDLN-I7@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phy_device.c | 2 ++ - include/linux/phy.h | 3 +++ - 2 files changed, 5 insertions(+) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -1215,6 +1215,8 @@ int phy_init_hw(struct phy_device *phyde - if (ret < 0) - return ret; - -+ phy_interface_zero(phydev->possible_interfaces); -+ - if (phydev->drv->config_init) { - ret = phydev->drv->config_init(phydev); - if (ret < 0) ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -600,6 +600,8 @@ struct macsec_ops; - * @irq_rerun: Flag indicating interrupts occurred while PHY was suspended, - * requiring a rerun of the interrupt handler after resume - * @interface: enum phy_interface_t value -+ * @possible_interfaces: bitmap if interface modes that the attached PHY -+ * will switch between depending on media speed. - * @skb: Netlink message for cable diagnostics - * @nest: Netlink nest used for cable diagnostics - * @ehdr: nNtlink header for cable diagnostics -@@ -665,6 +667,7 @@ struct phy_device { - u32 dev_flags; - - phy_interface_t interface; -+ DECLARE_PHY_INTERFACE_MASK(possible_interfaces); - - /* - * forced speed & duplex (no autoneg) diff --git a/target/linux/generic/backport-6.1/895-02-v6.8-net-phylink-use-for_each_set_bit.patch b/target/linux/generic/backport-6.1/895-02-v6.8-net-phylink-use-for_each_set_bit.patch deleted file mode 100644 index 155ec1c2d9a64d..00000000000000 --- a/target/linux/generic/backport-6.1/895-02-v6.8-net-phylink-use-for_each_set_bit.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 85631f5b33f2acce7d42dec1d0a062ab40de95b8 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Sun, 19 Nov 2023 21:07:43 +0000 -Subject: [PATCH 2/7] net: phylink: use for_each_set_bit() - -Use for_each_set_bit() rather than open coding the for() test_bit() -loop. - -Reviewed-by: Andrew Lunn -Signed-off-by: Russell King (Oracle) -Reviewed-by: Wojciech Drewek -Link: https://lore.kernel.org/r/E1r4p15-00Cpxe-C7@rmk-PC.armlinux.org.uk -Signed-off-by: Paolo Abeni ---- - drivers/net/phy/phylink.c | 18 ++++++++---------- - 1 file changed, 8 insertions(+), 10 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -690,18 +690,16 @@ static int phylink_validate_mask(struct - __ETHTOOL_DECLARE_LINK_MODE_MASK(all_s) = { 0, }; - __ETHTOOL_DECLARE_LINK_MODE_MASK(s); - struct phylink_link_state t; -- int intf; -+ int interface; - -- for (intf = 0; intf < PHY_INTERFACE_MODE_MAX; intf++) { -- if (test_bit(intf, interfaces)) { -- linkmode_copy(s, supported); -+ for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX) { -+ linkmode_copy(s, supported); - -- t = *state; -- t.interface = intf; -- if (!phylink_validate_mac_and_pcs(pl, s, &t)) { -- linkmode_or(all_s, all_s, s); -- linkmode_or(all_adv, all_adv, t.advertising); -- } -+ t = *state; -+ t.interface = interface; -+ if (!phylink_validate_mac_and_pcs(pl, s, &t)) { -+ linkmode_or(all_s, all_s, s); -+ linkmode_or(all_adv, all_adv, t.advertising); - } - } - diff --git a/target/linux/generic/backport-6.1/895-03-v6.8-net-phylink-split-out-per-interface-validation.patch b/target/linux/generic/backport-6.1/895-03-v6.8-net-phylink-split-out-per-interface-validation.patch deleted file mode 100644 index 163cb953f78202..00000000000000 --- a/target/linux/generic/backport-6.1/895-03-v6.8-net-phylink-split-out-per-interface-validation.patch +++ /dev/null @@ -1,76 +0,0 @@ -From d4788b4383ce5caeb4e68818357c81a02117a3f9 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 24 Nov 2023 12:28:19 +0000 -Subject: [PATCH 3/7] net: phylink: split out per-interface validation - -Split out the internals of phylink_validate_mask() to make the code -easier to read. - -Tested-by: Luo Jie -Signed-off-by: Russell King (Oracle) -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/E1r6VIB-00DDLr-7g@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 42 ++++++++++++++++++++++++++++----------- - 1 file changed, 30 insertions(+), 12 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -682,26 +682,44 @@ static int phylink_validate_mac_and_pcs( - return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; - } - -+static void phylink_validate_one(struct phylink *pl, -+ const unsigned long *supported, -+ const struct phylink_link_state *state, -+ phy_interface_t interface, -+ unsigned long *accum_supported, -+ unsigned long *accum_advertising) -+{ -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(tmp_supported); -+ struct phylink_link_state tmp_state; -+ -+ linkmode_copy(tmp_supported, supported); -+ -+ tmp_state = *state; -+ tmp_state.interface = interface; -+ -+ if (!phylink_validate_mac_and_pcs(pl, tmp_supported, &tmp_state)) { -+ phylink_dbg(pl, " interface %u (%s) rate match %s supports %*pbl\n", -+ interface, phy_modes(interface), -+ phy_rate_matching_to_str(tmp_state.rate_matching), -+ __ETHTOOL_LINK_MODE_MASK_NBITS, tmp_supported); -+ -+ linkmode_or(accum_supported, accum_supported, tmp_supported); -+ linkmode_or(accum_advertising, accum_advertising, -+ tmp_state.advertising); -+ } -+} -+ - static int phylink_validate_mask(struct phylink *pl, unsigned long *supported, - struct phylink_link_state *state, - const unsigned long *interfaces) - { - __ETHTOOL_DECLARE_LINK_MODE_MASK(all_adv) = { 0, }; - __ETHTOOL_DECLARE_LINK_MODE_MASK(all_s) = { 0, }; -- __ETHTOOL_DECLARE_LINK_MODE_MASK(s); -- struct phylink_link_state t; - int interface; - -- for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX) { -- linkmode_copy(s, supported); -- -- t = *state; -- t.interface = interface; -- if (!phylink_validate_mac_and_pcs(pl, s, &t)) { -- linkmode_or(all_s, all_s, s); -- linkmode_or(all_adv, all_adv, t.advertising); -- } -- } -+ for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX) -+ phylink_validate_one(pl, supported, state, interface, -+ all_s, all_adv); - - linkmode_copy(supported, all_s); - linkmode_copy(state->advertising, all_adv); diff --git a/target/linux/generic/backport-6.1/895-04-v6.8-net-phylink-pass-PHY-into-phylink_validate_one.patch b/target/linux/generic/backport-6.1/895-04-v6.8-net-phylink-pass-PHY-into-phylink_validate_one.patch deleted file mode 100644 index 501202067626ae..00000000000000 --- a/target/linux/generic/backport-6.1/895-04-v6.8-net-phylink-pass-PHY-into-phylink_validate_one.patch +++ /dev/null @@ -1,47 +0,0 @@ -From ce7273c31fadb3143fc80c96a72a42adc19c2757 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 24 Nov 2023 12:28:24 +0000 -Subject: [PATCH 4/7] net: phylink: pass PHY into phylink_validate_one() - -Pass the phy (if any) into phylink_validate_one() so that we can -validate each interface with its rate matching setting. - -Tested-by: Luo Jie -Signed-off-by: Russell King (Oracle) -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/E1r6VIG-00DDLx-Cb@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -682,7 +682,7 @@ static int phylink_validate_mac_and_pcs( - return phylink_is_empty_linkmode(supported) ? -EINVAL : 0; - } - --static void phylink_validate_one(struct phylink *pl, -+static void phylink_validate_one(struct phylink *pl, struct phy_device *phy, - const unsigned long *supported, - const struct phylink_link_state *state, - phy_interface_t interface, -@@ -697,6 +697,9 @@ static void phylink_validate_one(struct - tmp_state = *state; - tmp_state.interface = interface; - -+ if (phy) -+ tmp_state.rate_matching = phy_get_rate_matching(phy, interface); -+ - if (!phylink_validate_mac_and_pcs(pl, tmp_supported, &tmp_state)) { - phylink_dbg(pl, " interface %u (%s) rate match %s supports %*pbl\n", - interface, phy_modes(interface), -@@ -718,7 +721,7 @@ static int phylink_validate_mask(struct - int interface; - - for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX) -- phylink_validate_one(pl, supported, state, interface, -+ phylink_validate_one(pl, NULL, supported, state, interface, - all_s, all_adv); - - linkmode_copy(supported, all_s); diff --git a/target/linux/generic/backport-6.1/895-05-v6.8-net-phylink-pass-PHY-into-phylink_validate_mask.patch b/target/linux/generic/backport-6.1/895-05-v6.8-net-phylink-pass-PHY-into-phylink_validate_mask.patch deleted file mode 100644 index 997c74346cb385..00000000000000 --- a/target/linux/generic/backport-6.1/895-05-v6.8-net-phylink-pass-PHY-into-phylink_validate_mask.patch +++ /dev/null @@ -1,58 +0,0 @@ -From c6fec66d3cd76d797f70b30f1511bed10ba45a96 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 24 Nov 2023 12:28:29 +0000 -Subject: [PATCH 5/7] net: phylink: pass PHY into phylink_validate_mask() - -Pass the phy (if any) into phylink_validate_mask() so that we can -validate each interface with its rate matching setting. - -Tested-by: Luo Jie -Signed-off-by: Russell King (Oracle) -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/E1r6VIL-00DDM3-HJ@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -712,7 +712,8 @@ static void phylink_validate_one(struct - } - } - --static int phylink_validate_mask(struct phylink *pl, unsigned long *supported, -+static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy, -+ unsigned long *supported, - struct phylink_link_state *state, - const unsigned long *interfaces) - { -@@ -721,7 +722,7 @@ static int phylink_validate_mask(struct - int interface; - - for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX) -- phylink_validate_one(pl, NULL, supported, state, interface, -+ phylink_validate_one(pl, phy, supported, state, interface, - all_s, all_adv); - - linkmode_copy(supported, all_s); -@@ -736,7 +737,8 @@ static int phylink_validate(struct phyli - const unsigned long *interfaces = pl->config->supported_interfaces; - - if (state->interface == PHY_INTERFACE_MODE_NA) -- return phylink_validate_mask(pl, supported, state, interfaces); -+ return phylink_validate_mask(pl, NULL, supported, state, -+ interfaces); - - if (!test_bit(state->interface, interfaces)) - return -EINVAL; -@@ -3132,7 +3134,8 @@ static int phylink_sfp_config_optical(st - /* For all the interfaces that are supported, reduce the sfp_support - * mask to only those link modes that can be supported. - */ -- ret = phylink_validate_mask(pl, pl->sfp_support, &config, interfaces); -+ ret = phylink_validate_mask(pl, NULL, pl->sfp_support, &config, -+ interfaces); - if (ret) { - phylink_err(pl, "unsupported SFP module: validation with support %*pb failed\n", - __ETHTOOL_LINK_MODE_MASK_NBITS, support); diff --git a/target/linux/generic/backport-6.1/895-06-v6.8-net-phylink-split-out-PHY-validation-from-phylink_br.patch b/target/linux/generic/backport-6.1/895-06-v6.8-net-phylink-split-out-PHY-validation-from-phylink_br.patch deleted file mode 100644 index d3d24c58fbb3e3..00000000000000 --- a/target/linux/generic/backport-6.1/895-06-v6.8-net-phylink-split-out-PHY-validation-from-phylink_br.patch +++ /dev/null @@ -1,95 +0,0 @@ -From ee0e0ddb910e7e989b65a19d72b6435baa641fc7 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 24 Nov 2023 12:28:34 +0000 -Subject: [PATCH 6/7] net: phylink: split out PHY validation from - phylink_bringup_phy() - -When bringing up a PHY, we need to work out which ethtool link modes it -should support and advertise. Clause 22 PHYs operate in a single -interface mode, which can be easily dealt with. However, clause 45 PHYs -tend to switch interface mode depending on the media. We need more -flexible validation at this point, so this patch splits out that code -in preparation to changing it. - -Tested-by: Luo Jie -Signed-off-by: Russell King (Oracle) -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/E1r6VIQ-00DDM9-LK@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 56 ++++++++++++++++++++++----------------- - 1 file changed, 31 insertions(+), 25 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1738,6 +1738,35 @@ static void phylink_phy_change(struct ph - phylink_pause_to_str(pl->phy_state.pause)); - } - -+static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy, -+ unsigned long *supported, -+ struct phylink_link_state *state) -+{ -+ /* Check whether we would use rate matching for the proposed interface -+ * mode. -+ */ -+ state->rate_matching = phy_get_rate_matching(phy, state->interface); -+ -+ /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R, -+ * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching. -+ * For some interface modes (e.g. RXAUI, XAUI and USXGMII) switching -+ * their Serdes is either unnecessary or not reasonable. -+ * -+ * For these which switch interface modes, we really need to know which -+ * interface modes the PHY supports to properly work out which ethtool -+ * linkmodes can be supported. For now, as a work-around, we validate -+ * against all interface modes, which may lead to more ethtool link -+ * modes being advertised than are actually supported. -+ */ -+ if (phy->is_c45 && state->rate_matching == RATE_MATCH_NONE && -+ state->interface != PHY_INTERFACE_MODE_RXAUI && -+ state->interface != PHY_INTERFACE_MODE_XAUI && -+ state->interface != PHY_INTERFACE_MODE_USXGMII) -+ state->interface = PHY_INTERFACE_MODE_NA; -+ -+ return phylink_validate(pl, supported, state); -+} -+ - static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, - phy_interface_t interface) - { -@@ -1758,32 +1787,9 @@ static int phylink_bringup_phy(struct ph - memset(&config, 0, sizeof(config)); - linkmode_copy(supported, phy->supported); - linkmode_copy(config.advertising, phy->advertising); -+ config.interface = interface; - -- /* Check whether we would use rate matching for the proposed interface -- * mode. -- */ -- config.rate_matching = phy_get_rate_matching(phy, interface); -- -- /* Clause 45 PHYs may switch their Serdes lane between, e.g. 10GBASE-R, -- * 5GBASE-R, 2500BASE-X and SGMII if they are not using rate matching. -- * For some interface modes (e.g. RXAUI, XAUI and USXGMII) switching -- * their Serdes is either unnecessary or not reasonable. -- * -- * For these which switch interface modes, we really need to know which -- * interface modes the PHY supports to properly work out which ethtool -- * linkmodes can be supported. For now, as a work-around, we validate -- * against all interface modes, which may lead to more ethtool link -- * modes being advertised than are actually supported. -- */ -- if (phy->is_c45 && config.rate_matching == RATE_MATCH_NONE && -- interface != PHY_INTERFACE_MODE_RXAUI && -- interface != PHY_INTERFACE_MODE_XAUI && -- interface != PHY_INTERFACE_MODE_USXGMII) -- config.interface = PHY_INTERFACE_MODE_NA; -- else -- config.interface = interface; -- -- ret = phylink_validate(pl, supported, &config); -+ ret = phylink_validate_phy(pl, phy, supported, &config); - if (ret) { - phylink_warn(pl, "validation of %s with support %*pb and advertisement %*pb failed: %pe\n", - phy_modes(config.interface), diff --git a/target/linux/generic/backport-6.1/895-07-v6.8-net-phylink-use-the-PHY-s-possible_interfaces-if-pop.patch b/target/linux/generic/backport-6.1/895-07-v6.8-net-phylink-use-the-PHY-s-possible_interfaces-if-pop.patch deleted file mode 100644 index 201afbb7cff541..00000000000000 --- a/target/linux/generic/backport-6.1/895-07-v6.8-net-phylink-use-the-PHY-s-possible_interfaces-if-pop.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 8f7a9799c5949f94ecc3acfd71b36437a7ade73b Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -Date: Fri, 24 Nov 2023 12:28:39 +0000 -Subject: [PATCH 7/7] net: phylink: use the PHY's possible_interfaces if - populated - -Some PHYs such as Aquantia, Broadcom 84881, and Marvell 88X33x0 can -switch between a set of interface types depending on the negotiated -media speed, or can use rate adaption for some or all of these -interface types. - -We currently assume that these are Clause 45 PHYs that are configured -not to use a specific set of interface modes, which has worked so far, -but is just a work-around. In this workaround, we validate using all -interfaces that the MAC supports, which can lead to extra modes being -advertised that can not be supported. - -To properly address this, switch to using the newly introduced PHY -possible_interfaces bitmap which indicates which interface modes will -be used by the PHY as configured. We calculate the union of the PHY's -possible interfaces and MACs supported interfaces, checking that is -non-empty. If the PHY is on a SFP, we further reduce the set by those -which can be used on a SFP module, again checking that is non-empty. -Finally, we validate the subset of interfaces, taking account of -whether rate matching will be used for each individual interface mode. - -This becomes independent of whether the PHY is clause 22 or clause 45. - -It is encouraged that all PHYs that switch interface modes or use -rate matching should populate phydev->possible_interfaces. - -Tested-by: Luo Jie -Signed-off-by: Russell King (Oracle) -Reviewed-by: Andrew Lunn -Link: https://lore.kernel.org/r/E1r6VIV-00DDMF-Pi@rmk-PC.armlinux.org.uk -Signed-off-by: Jakub Kicinski ---- - drivers/net/phy/phylink.c | 67 +++++++++++++++++++++++++++++++-------- - 1 file changed, 54 insertions(+), 13 deletions(-) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -121,6 +121,19 @@ do { \ - }) - #endif - -+static const phy_interface_t phylink_sfp_interface_preference[] = { -+ PHY_INTERFACE_MODE_25GBASER, -+ PHY_INTERFACE_MODE_USXGMII, -+ PHY_INTERFACE_MODE_10GBASER, -+ PHY_INTERFACE_MODE_5GBASER, -+ PHY_INTERFACE_MODE_2500BASEX, -+ PHY_INTERFACE_MODE_SGMII, -+ PHY_INTERFACE_MODE_1000BASEX, -+ PHY_INTERFACE_MODE_100BASEX, -+}; -+ -+static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces); -+ - /** - * phylink_set_port_modes() - set the port type modes in the ethtool mask - * @mask: ethtool link mode mask -@@ -1742,6 +1755,47 @@ static int phylink_validate_phy(struct p - unsigned long *supported, - struct phylink_link_state *state) - { -+ DECLARE_PHY_INTERFACE_MASK(interfaces); -+ -+ /* If the PHY provides a bitmap of the interfaces it will be using -+ * depending on the negotiated media speeds, use this to validate -+ * which ethtool link modes can be used. -+ */ -+ if (!phy_interface_empty(phy->possible_interfaces)) { -+ /* We only care about the union of the PHY's interfaces and -+ * those which the host supports. -+ */ -+ phy_interface_and(interfaces, phy->possible_interfaces, -+ pl->config->supported_interfaces); -+ -+ if (phy_interface_empty(interfaces)) { -+ phylink_err(pl, "PHY has no common interfaces\n"); -+ return -EINVAL; -+ } -+ -+ if (phy_on_sfp(phy)) { -+ /* If the PHY is on a SFP, limit the interfaces to -+ * those that can be used with a SFP module. -+ */ -+ phy_interface_and(interfaces, interfaces, -+ phylink_sfp_interfaces); -+ -+ if (phy_interface_empty(interfaces)) { -+ phylink_err(pl, "SFP PHY's possible interfaces becomes empty\n"); -+ return -EINVAL; -+ } -+ } -+ -+ phylink_dbg(pl, "PHY %s uses interfaces %*pbl, validating %*pbl\n", -+ phydev_name(phy), -+ (int)PHY_INTERFACE_MODE_MAX, -+ phy->possible_interfaces, -+ (int)PHY_INTERFACE_MODE_MAX, interfaces); -+ -+ return phylink_validate_mask(pl, phy, supported, state, -+ interfaces); -+ } -+ - /* Check whether we would use rate matching for the proposed interface - * mode. - */ -@@ -2985,19 +3039,6 @@ static void phylink_sfp_detach(void *ups - pl->netdev->sfp_bus = NULL; - } - --static const phy_interface_t phylink_sfp_interface_preference[] = { -- PHY_INTERFACE_MODE_25GBASER, -- PHY_INTERFACE_MODE_USXGMII, -- PHY_INTERFACE_MODE_10GBASER, -- PHY_INTERFACE_MODE_5GBASER, -- PHY_INTERFACE_MODE_2500BASEX, -- PHY_INTERFACE_MODE_SGMII, -- PHY_INTERFACE_MODE_1000BASEX, -- PHY_INTERFACE_MODE_100BASEX, --}; -- --static DECLARE_PHY_INTERFACE_MASK(phylink_sfp_interfaces); -- - static phy_interface_t phylink_choose_sfp_interface(struct phylink *pl, - const unsigned long *intf) - { diff --git a/target/linux/generic/backport-6.1/897-01-v6.9-net-phy-qcom-qca808x-add-helper-for-checking-for-1G-.patch b/target/linux/generic/backport-6.1/897-01-v6.9-net-phy-qcom-qca808x-add-helper-for-checking-for-1G-.patch deleted file mode 100644 index a11e8049581e0c..00000000000000 --- a/target/linux/generic/backport-6.1/897-01-v6.9-net-phy-qcom-qca808x-add-helper-for-checking-for-1G-.patch +++ /dev/null @@ -1,50 +0,0 @@ -From f058b2dd70b1a5503dff899010aeb53b436091e5 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Wed, 28 Feb 2024 18:24:09 +0100 -Subject: [PATCH 1/2] net: phy: qcom: qca808x: add helper for checking for 1G - only model - -There are 2 versions of QCA808x, one 2.5G capable and one 1G capable. -Currently, this matter only in the .get_features call however, it will -be required for filling supported interface modes so lets add a helper -that can be reused. - -Signed-off-by: Robert Marko -Signed-off-by: David S. Miller ---- - drivers/net/phy/qcom/qca808x.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) - ---- a/drivers/net/phy/qcom/qca808x.c -+++ b/drivers/net/phy/qcom/qca808x.c -@@ -156,6 +156,17 @@ static bool qca808x_has_fast_retrain_or_ - return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); - } - -+static bool qca808x_is_1g_only(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE); -+ if (ret < 0) -+ return true; -+ -+ return !!(QCA808X_PHY_CHIP_TYPE_1G & ret); -+} -+ - static int qca808x_probe(struct phy_device *phydev) - { - struct device *dev = &phydev->mdio.dev; -@@ -350,11 +361,7 @@ static int qca808x_get_features(struct p - * existed in the bit0 of MMD1.21, we need to remove it manually if - * it is the qca8081 1G chip according to the bit0 of MMD7.0x901d. - */ -- ret = phy_read_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_CHIP_TYPE); -- if (ret < 0) -- return ret; -- -- if (QCA808X_PHY_CHIP_TYPE_1G & ret) -+ if (qca808x_is_1g_only(phydev)) - linkmode_clear_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported); - - return 0; diff --git a/target/linux/generic/backport-6.1/897-02-v6.9-net-phy-qcom-qca808x-fill-in-possible_interfaces.patch b/target/linux/generic/backport-6.1/897-02-v6.9-net-phy-qcom-qca808x-fill-in-possible_interfaces.patch deleted file mode 100644 index c162fc734812ea..00000000000000 --- a/target/linux/generic/backport-6.1/897-02-v6.9-net-phy-qcom-qca808x-fill-in-possible_interfaces.patch +++ /dev/null @@ -1,44 +0,0 @@ -From cb28f702960695e26597c332b0e46776e825cc34 Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Wed, 28 Feb 2024 18:24:10 +0100 -Subject: [PATCH 2/2] net: phy: qcom: qca808x: fill in possible_interfaces - -Currently QCA808x driver does not fill the possible_interfaces. -2.5G QCA808x support SGMII and 2500Base-X while 1G model only supports -SGMII, so fill the possible_interfaces accordingly. - -Signed-off-by: Robert Marko -Reviewed-by: Russell King (Oracle) -Signed-off-by: David S. Miller ---- - drivers/net/phy/qcom/qca808x.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/drivers/net/phy/qcom/qca808x.c -+++ b/drivers/net/phy/qcom/qca808x.c -@@ -167,6 +167,16 @@ static bool qca808x_is_1g_only(struct ph - return !!(QCA808X_PHY_CHIP_TYPE_1G & ret); - } - -+static void qca808x_fill_possible_interfaces(struct phy_device *phydev) -+{ -+ unsigned long *possible = phydev->possible_interfaces; -+ -+ __set_bit(PHY_INTERFACE_MODE_SGMII, possible); -+ -+ if (!qca808x_is_1g_only(phydev)) -+ __set_bit(PHY_INTERFACE_MODE_2500BASEX, possible); -+} -+ - static int qca808x_probe(struct phy_device *phydev) - { - struct device *dev = &phydev->mdio.dev; -@@ -231,6 +241,8 @@ static int qca808x_config_init(struct ph - } - } - -+ qca808x_fill_possible_interfaces(phydev); -+ - /* Configure adc threshold as 100mv for the link 10M */ - return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD, - QCA808X_ADC_THRESHOLD_MASK, diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1 deleted file mode 100644 index f6163e32944499..00000000000000 --- a/target/linux/generic/config-6.1 +++ /dev/null @@ -1,7955 +0,0 @@ -# CONFIG_104_QUAD_8 is not set -CONFIG_32BIT=y -CONFIG_64BIT_TIME=y -# CONFIG_6LOWPAN is not set -# CONFIG_6LOWPAN_DEBUGFS is not set -# CONFIG_6PACK is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_9P_FS is not set -# CONFIG_AB3100_CORE is not set -# CONFIG_AB8500_CORE is not set -# CONFIG_ABP060MG is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_ACCESSIBILITY is not set -# CONFIG_ACENIC is not set -# CONFIG_ACERHDF is not set -# CONFIG_ACER_WIRELESS is not set -# CONFIG_ACORN_PARTITION is not set -# CONFIG_ACPI_ALS is not set -# CONFIG_ACPI_APEI is not set -# CONFIG_ACPI_APEI_PCIEAER is not set -# CONFIG_ACPI_BUTTON is not set -# CONFIG_ACPI_CONFIGFS is not set -# CONFIG_ACPI_CUSTOM_METHOD is not set -# CONFIG_ACPI_EXTLOG is not set -# CONFIG_ACPI_HED is not set -# CONFIG_ACPI_NFIT is not set -# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set -# CONFIG_ACPI_TABLE_UPGRADE is not set -# CONFIG_ACPI_VIDEO is not set -# CONFIG_AD2S1200 is not set -# CONFIG_AD2S1210 is not set -# CONFIG_AD2S90 is not set -# CONFIG_AD3552R is not set -# CONFIG_AD5064 is not set -# CONFIG_AD5110 is not set -# CONFIG_AD525X_DPOT is not set -# CONFIG_AD5272 is not set -# CONFIG_AD5360 is not set -# CONFIG_AD5380 is not set -# CONFIG_AD5421 is not set -# CONFIG_AD5446 is not set -# CONFIG_AD5449 is not set -# CONFIG_AD5504 is not set -# CONFIG_AD5592R is not set -# CONFIG_AD5593R is not set -# CONFIG_AD5624R_SPI is not set -# CONFIG_AD5686 is not set -# CONFIG_AD5686_SPI is not set -# CONFIG_AD5696_I2C is not set -# CONFIG_AD5755 is not set -# CONFIG_AD5758 is not set -# CONFIG_AD5761 is not set -# CONFIG_AD5764 is not set -# CONFIG_AD5766 is not set -# CONFIG_AD5770R is not set -# CONFIG_AD5791 is not set -# CONFIG_AD5933 is not set -# CONFIG_AD7091R5 is not set -# CONFIG_AD7124 is not set -# CONFIG_AD7150 is not set -# CONFIG_AD7152 is not set -# CONFIG_AD7192 is not set -# CONFIG_AD7266 is not set -# CONFIG_AD7280 is not set -# CONFIG_AD7291 is not set -# CONFIG_AD7292 is not set -# CONFIG_AD7293 is not set -# CONFIG_AD7298 is not set -# CONFIG_AD7303 is not set -# CONFIG_AD74413R is not set -# CONFIG_AD7476 is not set -# CONFIG_AD7606 is not set -# CONFIG_AD7606_IFACE_PARALLEL is not set -# CONFIG_AD7606_IFACE_SPI is not set -# CONFIG_AD7746 is not set -# CONFIG_AD7766 is not set -# CONFIG_AD7768_1 is not set -# CONFIG_AD7780 is not set -# CONFIG_AD7791 is not set -# CONFIG_AD7793 is not set -# CONFIG_AD7816 is not set -# CONFIG_AD7887 is not set -# CONFIG_AD7923 is not set -# CONFIG_AD7949 is not set -# CONFIG_AD799X is not set -# CONFIG_AD8366 is not set -# CONFIG_AD8801 is not set -# CONFIG_AD9467 is not set -# CONFIG_AD9523 is not set -# CONFIG_AD9832 is not set -# CONFIG_AD9834 is not set -# CONFIG_ADA4250 is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_ADE7854 is not set -# CONFIG_ADF4350 is not set -# CONFIG_ADF4371 is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADIN1100_PHY is not set -# CONFIG_ADIN1110 is not set -# CONFIG_ADIN_PHY is not set -# CONFIG_ADIS16080 is not set -# CONFIG_ADIS16130 is not set -# CONFIG_ADIS16136 is not set -# CONFIG_ADIS16201 is not set -# CONFIG_ADIS16203 is not set -# CONFIG_ADIS16209 is not set -# CONFIG_ADIS16240 is not set -# CONFIG_ADIS16260 is not set -# CONFIG_ADIS16400 is not set -# CONFIG_ADIS16460 is not set -# CONFIG_ADIS16475 is not set -# CONFIG_ADIS16480 is not set -# CONFIG_ADI_AXI_ADC is not set -# CONFIG_ADJD_S311 is not set -# CONFIG_ADM6996_PHY is not set -# CONFIG_ADM8211 is not set -# CONFIG_ADMV1013 is not set -# CONFIG_ADMV1014 is not set -# CONFIG_ADMV4420 is not set -# CONFIG_ADMV8818 is not set -# CONFIG_ADRF6780 is not set -# CONFIG_ADT7316 is not set -# CONFIG_ADUX1020 is not set -CONFIG_ADVISE_SYSCALLS=y -# CONFIG_ADXL313_I2C is not set -# CONFIG_ADXL313_SPI is not set -# CONFIG_ADXL345_I2C is not set -# CONFIG_ADXL345_SPI is not set -# CONFIG_ADXL355_I2C is not set -# CONFIG_ADXL355_SPI is not set -# CONFIG_ADXL367_I2C is not set -# CONFIG_ADXL367_SPI is not set -# CONFIG_ADXL372_I2C is not set -# CONFIG_ADXL372_SPI is not set -# CONFIG_ADXRS290 is not set -# CONFIG_ADXRS450 is not set -CONFIG_AEABI=y -# CONFIG_AFE4403 is not set -# CONFIG_AFE4404 is not set -# CONFIG_AFFS_FS is not set -# CONFIG_AFS_DEBUG_CURSOR is not set -# CONFIG_AFS_FS is not set -# CONFIG_AF_KCM is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_AF_RXRPC_INJECT_LOSS is not set -# CONFIG_AF_RXRPC_IPV6 is not set -CONFIG_AF_UNIX_OOB=y -# CONFIG_AGP is not set -# CONFIG_AHCI_BRCM is not set -# CONFIG_AHCI_CEVA is not set -# CONFIG_AHCI_DWC is not set -# CONFIG_AHCI_IMX is not set -# CONFIG_AHCI_MVEBU is not set -# CONFIG_AHCI_QORIQ is not set -# CONFIG_AHCI_XGENE is not set -CONFIG_AIO=y -# CONFIG_AIRO is not set -# CONFIG_AIRO_CS is not set -# CONFIG_AIR_EN8811H_PHY is not set -# CONFIG_AIX_PARTITION is not set -# CONFIG_AK09911 is not set -# CONFIG_AK8974 is not set -# CONFIG_AK8975 is not set -# CONFIG_AL3010 is not set -# CONFIG_AL3320A is not set -# CONFIG_ALIM7101_WDT is not set -CONFIG_ALLOW_DEV_COREDUMP=y -# CONFIG_ALTERA_MBOX is not set -# CONFIG_ALTERA_MSGDMA is not set -# CONFIG_ALTERA_STAPL is not set -# CONFIG_ALTERA_TSE is not set -# CONFIG_ALX is not set -# CONFIG_AL_FIC is not set -# CONFIG_AM2315 is not set -# CONFIG_AM335X_PHY_USB is not set -# CONFIG_AMBA_PL08X is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_AMD_MEM_ENCRYPT is not set -# CONFIG_AMD_PHY is not set -# CONFIG_AMD_XGBE is not set -# CONFIG_AMD_XGBE_HAVE_ECC is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_AMILO_RFKILL is not set -# CONFIG_AMPERE_ERRATUM_AC03_CPU_38 is not set -# CONFIG_AMT is not set -# CONFIG_ANDROID is not set -# CONFIG_ANDROID_BINDER_IPC is not set -CONFIG_ANON_INODES=y -# CONFIG_ANON_VMA_NAME is not set -# CONFIG_APDS9300 is not set -# CONFIG_APDS9802ALS is not set -# CONFIG_APDS9960 is not set -# CONFIG_APM8018X is not set -# CONFIG_APM_EMULATION is not set -# CONFIG_APPLE_GMUX is not set -# CONFIG_APPLE_MFI_FASTCHARGE is not set -# CONFIG_APPLE_PROPERTIES is not set -# CONFIG_APPLICOM is not set -# CONFIG_AQTION is not set -# CONFIG_AQUANTIA_PHY is not set -# CONFIG_AR5523 is not set -# CONFIG_AR7 is not set -# CONFIG_AR8216_PHY is not set -# CONFIG_AR8216_PHY_LEDS is not set -# CONFIG_ARCH_ACTIONS is not set -# CONFIG_ARCH_AGILEX is not set -# CONFIG_ARCH_AIROHA is not set -# CONFIG_ARCH_ALPINE is not set -# CONFIG_ARCH_APPLE is not set -# CONFIG_ARCH_ARTPEC is not set -# CONFIG_ARCH_ASPEED is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_AXXIA is not set -# CONFIG_ARCH_BCM is not set -# CONFIG_ARCH_BCM2835 is not set -# CONFIG_ARCH_BCM4908 is not set -# CONFIG_ARCH_BCMBCA is not set -# CONFIG_ARCH_BCM_21664 is not set -# CONFIG_ARCH_BCM_23550 is not set -# CONFIG_ARCH_BCM_281XX is not set -# CONFIG_ARCH_BCM_5301X is not set -# CONFIG_ARCH_BCM_53573 is not set -# CONFIG_ARCH_BCM_63XX is not set -# CONFIG_ARCH_BCM_CYGNUS is not set -# CONFIG_ARCH_BCM_HR2 is not set -# CONFIG_ARCH_BCM_IPROC is not set -# CONFIG_ARCH_BCM_NSP is not set -# CONFIG_ARCH_BERLIN is not set -CONFIG_ARCH_BINFMT_ELF_STATE=y -# CONFIG_ARCH_BITMAIN is not set -# CONFIG_ARCH_BRCMSTB is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CNS3XXX is not set -# CONFIG_ARCH_DAVINCI is not set -# CONFIG_ARCH_DIGICOLOR is not set -# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set -# CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_EXYNOS is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -# CONFIG_ARCH_FOOTBRIDGE is not set -CONFIG_ARCH_FORCE_MAX_ORDER=11 -# CONFIG_ARCH_GEMINI is not set -# CONFIG_ARCH_HI3xxx is not set -# CONFIG_ARCH_HIGHBANK is not set -# CONFIG_ARCH_HISI is not set -# CONFIG_ARCH_HPE is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_INTEL_SOCFPGA is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_K3 is not set -# CONFIG_ARCH_KEEMBAY is not set -# CONFIG_ARCH_KEYSTONE is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_LAYERSCAPE is not set -# CONFIG_ARCH_LG1K is not set -# CONFIG_ARCH_LPC32XX is not set -# CONFIG_ARCH_MEDIATEK is not set -# CONFIG_ARCH_MESON is not set -# CONFIG_ARCH_MILBEAUT is not set -CONFIG_ARCH_MMAP_RND_BITS=8 -CONFIG_ARCH_MMAP_RND_BITS_MAX=16 -CONFIG_ARCH_MMAP_RND_BITS_MIN=8 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 -# CONFIG_ARCH_MMP is not set -# CONFIG_ARCH_MSTARV7 is not set -# CONFIG_ARCH_MULTIPLATFORM is not set -# CONFIG_ARCH_MULTI_V6 is not set -# CONFIG_ARCH_MULTI_V7 is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_MVEBU is not set -# CONFIG_ARCH_MXC is not set -# CONFIG_ARCH_MXS is not set -# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_NOMADIK is not set -# CONFIG_ARCH_NPCM is not set -# CONFIG_ARCH_NSPIRE is not set -# CONFIG_ARCH_NXP is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_OMAP1 is not set -# CONFIG_ARCH_OMAP2 is not set -# CONFIG_ARCH_OMAP2PLUS is not set -# CONFIG_ARCH_OMAP3 is not set -# CONFIG_ARCH_OMAP4 is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_OXNAS is not set -# CONFIG_ARCH_PICOXCELL is not set -# CONFIG_ARCH_PRIMA2 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_QCOM is not set -# CONFIG_ARCH_RANDOM is not set -# CONFIG_ARCH_RDA is not set -# CONFIG_ARCH_REALTEK is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_RENESAS is not set -# CONFIG_ARCH_ROCKCHIP is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_S32 is not set -# CONFIG_ARCH_S3C24XX is not set -# CONFIG_ARCH_S3C64XX is not set -# CONFIG_ARCH_S5PV210 is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_SEATTLE is not set -# CONFIG_ARCH_SHMOBILE is not set -# CONFIG_ARCH_SIRF is not set -# CONFIG_ARCH_SOCFPGA is not set -# CONFIG_ARCH_SPARX5 is not set -# CONFIG_ARCH_SPRD is not set -# CONFIG_ARCH_STI is not set -# CONFIG_ARCH_STM32 is not set -# CONFIG_ARCH_STRATIX10 is not set -# CONFIG_ARCH_SUNPLUS is not set -# CONFIG_ARCH_SUNXI is not set -# CONFIG_ARCH_SYNQUACER is not set -# CONFIG_ARCH_TANGO is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_ARCH_THUNDER is not set -# CONFIG_ARCH_THUNDER2 is not set -# CONFIG_ARCH_U300 is not set -# CONFIG_ARCH_U8500 is not set -# CONFIG_ARCH_UNIPHIER is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_VEXPRESS is not set -# CONFIG_ARCH_VIRT is not set -# CONFIG_ARCH_VISCONTI is not set -# CONFIG_ARCH_VT8500 is not set -# CONFIG_ARCH_VULCAN is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_WANTS_THP_SWAP is not set -# CONFIG_ARCH_WM8505 is not set -# CONFIG_ARCH_WM8750 is not set -# CONFIG_ARCH_WM8850 is not set -# CONFIG_ARCH_XGENE is not set -# CONFIG_ARCH_ZX is not set -# CONFIG_ARCH_ZYNQ is not set -# CONFIG_ARCH_ZYNQMP is not set -# CONFIG_ARCNET is not set -# CONFIG_ARC_EMAC is not set -# CONFIG_ARC_IRQ_NO_AUTOSAVE is not set -# CONFIG_ARM64_16K_PAGES is not set -# CONFIG_ARM64_64K_PAGES is not set -# CONFIG_ARM64_AMU_EXTN is not set -# CONFIG_ARM64_BTI is not set -CONFIG_ARM64_CNP=y -# CONFIG_ARM64_CRYPTO is not set -# CONFIG_ARM64_E0PD is not set -# CONFIG_ARM64_EPAN is not set -# CONFIG_ARM64_ERRATUM_1024718 is not set -# CONFIG_ARM64_ERRATUM_1165522 is not set -# CONFIG_ARM64_ERRATUM_1286807 is not set -# CONFIG_ARM64_ERRATUM_1319367 is not set -# CONFIG_ARM64_ERRATUM_1418040 is not set -# CONFIG_ARM64_ERRATUM_1463225 is not set -# CONFIG_ARM64_ERRATUM_1508412 is not set -# CONFIG_ARM64_ERRATUM_1530923 is not set -# CONFIG_ARM64_ERRATUM_1542419 is not set -# CONFIG_ARM64_ERRATUM_1742098 is not set -# CONFIG_ARM64_ERRATUM_2051678 is not set -# CONFIG_ARM64_ERRATUM_2054223 is not set -# CONFIG_ARM64_ERRATUM_2067961 is not set -# CONFIG_ARM64_ERRATUM_2077057 is not set -# CONFIG_ARM64_ERRATUM_2441007 is not set -# CONFIG_ARM64_ERRATUM_2441009 is not set -# CONFIG_ARM64_ERRATUM_2658417 is not set -# CONFIG_ARM64_ERRATUM_2966298 is not set -# CONFIG_ARM64_ERRATUM_3194386 is not set -# CONFIG_ARM64_ERRATUM_3312417 is not set -# CONFIG_ARM64_ERRATUM_819472 is not set -# CONFIG_ARM64_ERRATUM_824069 is not set -# CONFIG_ARM64_ERRATUM_826319 is not set -# CONFIG_ARM64_ERRATUM_827319 is not set -# CONFIG_ARM64_ERRATUM_832075 is not set -# CONFIG_ARM64_ERRATUM_834220 is not set -# CONFIG_ARM64_ERRATUM_843419 is not set -# CONFIG_ARM64_ERRATUM_845719 is not set -# CONFIG_ARM64_ERRATUM_858921 is not set -# CONFIG_ARM64_HW_AFDBM is not set -# CONFIG_ARM64_LSE_ATOMICS is not set -CONFIG_ARM64_MODULE_PLTS=y -# CONFIG_ARM64_MTE is not set -CONFIG_ARM64_PAN=y -# CONFIG_ARM64_PMEM is not set -# CONFIG_ARM64_PSEUDO_NMI is not set -# CONFIG_ARM64_PTDUMP_DEBUGFS is not set -# CONFIG_ARM64_PTR_AUTH is not set -# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -# CONFIG_ARM64_RAS_EXTN is not set -# CONFIG_ARM64_RELOC_TEST is not set -# CONFIG_ARM64_SME is not set -# CONFIG_ARM64_SVE is not set -CONFIG_ARM64_SW_TTBR0_PAN=y -# CONFIG_ARM64_TLB_RANGE is not set -# CONFIG_ARM64_UAO is not set -# CONFIG_ARM64_USE_LSE_ATOMICS is not set -# CONFIG_ARM64_VA_BITS_48 is not set -# CONFIG_ARM64_VHE is not set -# CONFIG_ARM_APPENDED_DTB is not set -# CONFIG_ARM_ARCH_TIMER is not set -# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set -# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set -# CONFIG_ARM_CCI is not set -# CONFIG_ARM_CCI400_PMU is not set -# CONFIG_ARM_CCI5xx_PMU is not set -# CONFIG_ARM_CCI_PMU is not set -# CONFIG_ARM_CCN is not set -# CONFIG_ARM_CMN is not set -# CONFIG_ARM_CPUIDLE is not set -CONFIG_ARM_CPU_TOPOLOGY=y -# CONFIG_ARM_CRYPTO is not set -CONFIG_ARM_DMA_MEM_BUFFERABLE=y -# CONFIG_ARM_DSU_PMU is not set -# CONFIG_ARM_ERRATA_326103 is not set -# CONFIG_ARM_ERRATA_364296 is not set -# CONFIG_ARM_ERRATA_411920 is not set -# CONFIG_ARM_ERRATA_430973 is not set -# CONFIG_ARM_ERRATA_458693 is not set -# CONFIG_ARM_ERRATA_460075 is not set -# CONFIG_ARM_ERRATA_643719 is not set -# CONFIG_ARM_ERRATA_720789 is not set -# CONFIG_ARM_ERRATA_742230 is not set -# CONFIG_ARM_ERRATA_742231 is not set -# CONFIG_ARM_ERRATA_743622 is not set -# CONFIG_ARM_ERRATA_751472 is not set -# CONFIG_ARM_ERRATA_754322 is not set -# CONFIG_ARM_ERRATA_754327 is not set -# CONFIG_ARM_ERRATA_764319 is not set -# CONFIG_ARM_ERRATA_764369 is not set -# CONFIG_ARM_ERRATA_773022 is not set -# CONFIG_ARM_ERRATA_775420 is not set -# CONFIG_ARM_ERRATA_798181 is not set -# CONFIG_ARM_ERRATA_814220 is not set -# CONFIG_ARM_ERRATA_818325_852422 is not set -# CONFIG_ARM_ERRATA_821420 is not set -# CONFIG_ARM_ERRATA_825619 is not set -# CONFIG_ARM_ERRATA_852421 is not set -# CONFIG_ARM_ERRATA_852423 is not set -# CONFIG_ARM_ERRATA_857271 is not set -# CONFIG_ARM_ERRATA_857272 is not set -# CONFIG_ARM_FFA_TRANSPORT is not set -CONFIG_ARM_GIC_MAX_NR=1 -# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set -# CONFIG_ARM_KPROBES_TEST is not set -# CONFIG_ARM_LPAE is not set -# CONFIG_ARM_MEDIATEK_CPUFREQ_HW is not set -# CONFIG_ARM_MHU is not set -CONFIG_ARM_MODULE_PLTS=y -# CONFIG_ARM_PATCH_PHYS_VIRT is not set -# CONFIG_ARM_PSCI is not set -# CONFIG_ARM_PSCI_CHECKER is not set -# CONFIG_ARM_PSCI_CPUIDLE is not set -# CONFIG_ARM_PTDUMP_DEBUGFS is not set -# CONFIG_ARM_SBSA_WATCHDOG is not set -# CONFIG_ARM_SCMI_PROTOCOL is not set -# CONFIG_ARM_SCPI_PROTOCOL is not set -# CONFIG_ARM_SDE_INTERFACE is not set -# CONFIG_ARM_SMCCC_SOC_ID is not set -# CONFIG_ARM_SMC_WATCHDOG is not set -# CONFIG_ARM_SP805_WATCHDOG is not set -# CONFIG_ARM_SPE_PMU is not set -# CONFIG_ARM_THUMBEE is not set -# CONFIG_ARM_TIMER_SP804 is not set -# CONFIG_ARM_UNWIND is not set -# CONFIG_ARM_VIRT_EXT is not set -# CONFIG_AS3935 is not set -# CONFIG_AS73211 is not set -# CONFIG_ASM9260_TIMER is not set -# CONFIG_ASN1 is not set -# CONFIG_ASUS_LAPTOP is not set -# CONFIG_ASUS_WIRELESS is not set -# CONFIG_ASYMMETRIC_KEY_TYPE is not set -# CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE is not set -# CONFIG_ASYNC_RAID6_TEST is not set -# CONFIG_ASYNC_TX_DMA is not set -# CONFIG_AT76C50X_USB is not set -# CONFIG_AT803X_PHY is not set -# CONFIG_AT91_SAMA5D2_ADC is not set -# CONFIG_ATA is not set -# CONFIG_ATAGS is not set -CONFIG_ATAGS_PROC=y -# CONFIG_ATALK is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_ATA_ACPI is not set -CONFIG_ATA_BMDMA=y -# CONFIG_ATA_FORCE is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_ATA_LEDS is not set -# CONFIG_ATA_NONSTANDARD is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_ATA_PIIX is not set -CONFIG_ATA_SFF=y -# CONFIG_ATA_VERBOSE_ERROR is not set -# CONFIG_ATH10K is not set -# CONFIG_ATH25 is not set -# CONFIG_ATH5K is not set -# CONFIG_ATH6KL is not set -# CONFIG_ATH79 is not set -# CONFIG_ATH9K is not set -# CONFIG_ATH9K_HTC is not set -# CONFIG_ATH_DEBUG is not set -# CONFIG_ATL1 is not set -# CONFIG_ATL1C is not set -# CONFIG_ATL1E is not set -# CONFIG_ATL2 is not set -# CONFIG_ATLAS_EZO_SENSOR is not set -# CONFIG_ATLAS_PH_SENSOR is not set -# CONFIG_ATM is not set -# CONFIG_ATMEL is not set -# CONFIG_ATMEL_PIT is not set -# CONFIG_ATMEL_SSC is not set -# CONFIG_ATM_AMBASSADOR is not set -# CONFIG_ATM_BR2684 is not set -CONFIG_ATM_BR2684_IPFILTER=y -# CONFIG_ATM_CLIP is not set -CONFIG_ATM_CLIP_NO_ICMP=y -# CONFIG_ATM_DRIVERS is not set -# CONFIG_ATM_DUMMY is not set -# CONFIG_ATM_ENI is not set -# CONFIG_ATM_FIRESTREAM is not set -# CONFIG_ATM_FORE200E is not set -# CONFIG_ATM_HE is not set -# CONFIG_ATM_HORIZON is not set -# CONFIG_ATM_IA is not set -# CONFIG_ATM_IDT77252 is not set -# CONFIG_ATM_LANAI is not set -# CONFIG_ATM_LANE is not set -# CONFIG_ATM_MPOA is not set -# CONFIG_ATM_NICSTAR is not set -# CONFIG_ATM_SOLOS is not set -# CONFIG_ATM_TCP is not set -# CONFIG_ATM_ZATM is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_ATP is not set -# CONFIG_AUDIT is not set -# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set -# CONFIG_AURORA_NB8800 is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTO_ZRELADDR is not set -# CONFIG_AUXDISPLAY is not set -# CONFIG_AX25 is not set -# CONFIG_AX25_DAMA_SLAVE is not set -# CONFIG_AX88796 is not set -# CONFIG_AX88796B_PHY is not set -# CONFIG_AXP20X_ADC is not set -# CONFIG_AXP20X_POWER is not set -# CONFIG_AXP288_ADC is not set -# CONFIG_AXP288_FUEL_GAUGE is not set -# CONFIG_B43 is not set -# CONFIG_B43LEGACY is not set -# CONFIG_B44 is not set -# CONFIG_B53 is not set -# CONFIG_B53_MDIO_DRIVER is not set -# CONFIG_B53_MMAP_DRIVER is not set -# CONFIG_B53_SERDES is not set -# CONFIG_B53_SPI_DRIVER is not set -# CONFIG_B53_SRAB_DRIVER is not set -# CONFIG_BACKLIGHT_ADP8860 is not set -# CONFIG_BACKLIGHT_ADP8870 is not set -# CONFIG_BACKLIGHT_APPLE is not set -# CONFIG_BACKLIGHT_ARCXCNN is not set -# CONFIG_BACKLIGHT_BD6107 is not set -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -# CONFIG_BACKLIGHT_GENERIC is not set -# CONFIG_BACKLIGHT_GPIO is not set -# CONFIG_BACKLIGHT_KTD253 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -# CONFIG_BACKLIGHT_LED is not set -# CONFIG_BACKLIGHT_LM3630A is not set -# CONFIG_BACKLIGHT_LM3639 is not set -# CONFIG_BACKLIGHT_LP855X is not set -# CONFIG_BACKLIGHT_LV5207LP is not set -# CONFIG_BACKLIGHT_PANDORA is not set -# CONFIG_BACKLIGHT_PM8941_WLED is not set -# CONFIG_BACKLIGHT_PWM is not set -# CONFIG_BACKLIGHT_QCOM_WLED is not set -# CONFIG_BACKLIGHT_RPI is not set -# CONFIG_BACKLIGHT_SAHARA is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_BACKTRACE_VERBOSE is not set -# CONFIG_BAREUDP is not set -CONFIG_BASE_FULL=y -CONFIG_BASE_SMALL=0 -# CONFIG_BATMAN_ADV is not set -# CONFIG_BATTERY_BQ27XXX is not set -# CONFIG_BATTERY_BQ27XXX_HDQ is not set -# CONFIG_BATTERY_CW2015 is not set -# CONFIG_BATTERY_DS2760 is not set -# CONFIG_BATTERY_DS2780 is not set -# CONFIG_BATTERY_DS2781 is not set -# CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_GAUGE_LTC2941 is not set -# CONFIG_BATTERY_GOLDFISH is not set -# CONFIG_BATTERY_LEGO_EV3 is not set -# CONFIG_BATTERY_MAX17040 is not set -# CONFIG_BATTERY_MAX17042 is not set -# CONFIG_BATTERY_MAX1721X is not set -# CONFIG_BATTERY_RT5033 is not set -# CONFIG_BATTERY_SAMSUNG_SDI is not set -# CONFIG_BATTERY_SBS is not set -# CONFIG_BATTERY_UG3105 is not set -# CONFIG_BAYCOM_EPP is not set -# CONFIG_BAYCOM_PAR is not set -# CONFIG_BAYCOM_SER_FDX is not set -# CONFIG_BAYCOM_SER_HDX is not set -# CONFIG_BCACHE is not set -# CONFIG_BCM2712_MIP is not set -# CONFIG_BCM47XX is not set -# CONFIG_BCM54140_PHY is not set -# CONFIG_BCM63XX is not set -# CONFIG_BCM63XX_PHY is not set -# CONFIG_BCM7038_L1_IRQ is not set -# CONFIG_BCM7038_WDT is not set -# CONFIG_BCM7120_L2_IRQ is not set -# CONFIG_BCM7XXX_PHY is not set -# CONFIG_BCM84881_PHY is not set -# CONFIG_BCM87XX_PHY is not set -# CONFIG_BCMA is not set -# CONFIG_BCMA_DRIVER_GPIO is not set -CONFIG_BCMA_POSSIBLE=y -# CONFIG_BCMGENET is not set -# CONFIG_BCM_IPROC_ADC is not set -# CONFIG_BCM_KONA_USB2_PHY is not set -# CONFIG_BCM_SBA_RAID is not set -# CONFIG_BCM_VK is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_BE2ISCSI is not set -# CONFIG_BE2NET is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_BGMAC is not set -# CONFIG_BH1750 is not set -# CONFIG_BH1780 is not set -# CONFIG_BIG_KEYS is not set -# CONFIG_BIG_LITTLE is not set -CONFIG_BINARY_PRINTF=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_ELF_FDPIC is not set -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set -CONFIG_BINFMT_SCRIPT=y -CONFIG_BITREVERSE=y -# CONFIG_BLK_CGROUP_IOCOST is not set -# CONFIG_BLK_CGROUP_IOLATENCY is not set -# CONFIG_BLK_CGROUP_IOPRIO is not set -# CONFIG_BLK_CMDLINE_PARSER is not set -# CONFIG_BLK_DEBUG_FS is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_BLK_DEV_4DRIVES is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI14XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_ATIIXP is not set -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_BLK_DEV_BSGLIB is not set -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_CS5535 is not set -# CONFIG_BLK_DEV_CS5536 is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_DELKIN is not set -# CONFIG_BLK_DEV_DM is not set -# CONFIG_BLK_DEV_DRBD is not set -# CONFIG_BLK_DEV_DTC2278 is not set -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_HT6560B is not set -# CONFIG_BLK_DEV_IDEACPI is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDECS is not set -# CONFIG_BLK_DEV_IDEPCI is not set -# CONFIG_BLK_DEV_IDEPNP is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDE_AU1XXX is not set -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_INITRD=y -# CONFIG_BLK_DEV_INTEGRITY is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_IT8172 is not set -# CONFIG_BLK_DEV_IT8213 is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_LOOP is not set -CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 -# CONFIG_BLK_DEV_MD is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_NULL_BLK is not set -# CONFIG_BLK_DEV_NVME is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_PLATFORM is not set -# CONFIG_BLK_DEV_PMEM is not set -# CONFIG_BLK_DEV_QD65XX is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_RBD is not set -# CONFIG_BLK_DEV_RSXX is not set -# CONFIG_BLK_DEV_RZ1000 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_SD is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SIS5513 is not set -# CONFIG_BLK_DEV_SKD is not set -# CONFIG_BLK_DEV_SL82C105 is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_TC86C001 is not set -# CONFIG_BLK_DEV_THROTTLING is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_UBLK is not set -# CONFIG_BLK_DEV_UMC8672 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_BLK_DEV_ZONED is not set -# CONFIG_BLK_INLINE_ENCRYPTION is not set -# CONFIG_BLK_NVMEM is not set -# CONFIG_BLK_SED_OPAL is not set -# CONFIG_BLK_WBT is not set -CONFIG_BLOCK=y -# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set -# CONFIG_BMA180 is not set -# CONFIG_BMA220 is not set -# CONFIG_BMA400 is not set -# CONFIG_BMC150_ACCEL is not set -# CONFIG_BMC150_MAGN is not set -# CONFIG_BMC150_MAGN_I2C is not set -# CONFIG_BMC150_MAGN_SPI is not set -# CONFIG_BME680 is not set -# CONFIG_BMG160 is not set -# CONFIG_BMI088_ACCEL is not set -# CONFIG_BMI160_I2C is not set -# CONFIG_BMI160_SPI is not set -# CONFIG_BMIPS_GENERIC is not set -# CONFIG_BMP280 is not set -# CONFIG_BNA is not set -# CONFIG_BNX2 is not set -# CONFIG_BNX2X is not set -# CONFIG_BNX2X_SRIOV is not set -# CONFIG_BNXT is not set -# CONFIG_BONDING is not set -# CONFIG_BOOKE_WDT is not set -CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3 -# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -# CONFIG_BOOTTIME_TRACING is not set -# CONFIG_BOOT_CONFIG is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -CONFIG_BOOT_RAW=y -# CONFIG_BOSCH_BNO055_I2C is not set -# CONFIG_BOSCH_BNO055_SERIAL is not set -# CONFIG_BOUNCE is not set -CONFIG_BPF=y -# CONFIG_BPFILTER is not set -CONFIG_BPF_JIT=y -# CONFIG_BPF_JIT_ALWAYS_ON is not set -CONFIG_BPF_JIT_DEFAULT_ON=y -# CONFIG_BPF_PRELOAD is not set -# CONFIG_BPF_STREAM_PARSER is not set -CONFIG_BPF_SYSCALL=y -CONFIG_BPF_UNPRIV_DEFAULT_OFF=y -# CONFIG_BPQETHER is not set -CONFIG_BQL=y -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_BRCMFMAC is not set -# CONFIG_BRCMSMAC is not set -# CONFIG_BRCMSTB_GISB_ARB is not set -# CONFIG_BRCMSTB_L2_IRQ is not set -CONFIG_BRIDGE=y -# CONFIG_BRIDGE_CFM is not set -# CONFIG_BRIDGE_EBT_802_3 is not set -# CONFIG_BRIDGE_EBT_AMONG is not set -# CONFIG_BRIDGE_EBT_ARP is not set -# CONFIG_BRIDGE_EBT_ARPREPLY is not set -# CONFIG_BRIDGE_EBT_BROUTE is not set -# CONFIG_BRIDGE_EBT_DNAT is not set -# CONFIG_BRIDGE_EBT_IP is not set -# CONFIG_BRIDGE_EBT_IP6 is not set -# CONFIG_BRIDGE_EBT_LIMIT is not set -# CONFIG_BRIDGE_EBT_LOG is not set -# CONFIG_BRIDGE_EBT_MARK is not set -# CONFIG_BRIDGE_EBT_MARK_T is not set -# CONFIG_BRIDGE_EBT_NFLOG is not set -# CONFIG_BRIDGE_EBT_PKTTYPE is not set -# CONFIG_BRIDGE_EBT_REDIRECT is not set -# CONFIG_BRIDGE_EBT_SNAT is not set -# CONFIG_BRIDGE_EBT_STP is not set -# CONFIG_BRIDGE_EBT_T_FILTER is not set -# CONFIG_BRIDGE_EBT_T_NAT is not set -# CONFIG_BRIDGE_EBT_VLAN is not set -CONFIG_BRIDGE_IGMP_SNOOPING=y -# CONFIG_BRIDGE_MRP is not set -# CONFIG_BRIDGE_NETFILTER is not set -# CONFIG_BRIDGE_NF_EBTABLES is not set -CONFIG_BRIDGE_VLAN_FILTERING=y -# CONFIG_BROADCOM_PHY is not set -CONFIG_BROKEN_ON_SMP=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_BT is not set -# CONFIG_BTRFS_ASSERT is not set -# CONFIG_BTRFS_DEBUG is not set -# CONFIG_BTRFS_FS is not set -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set -# CONFIG_BTRFS_FS_POSIX_ACL is not set -# CONFIG_BTRFS_FS_REF_VERIFY is not set -# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set -# CONFIG_BT_AOSPEXT is not set -# CONFIG_BT_ATH3K is not set -# CONFIG_BT_BNEP is not set -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -# CONFIG_BT_BREDR is not set -# CONFIG_BT_CMTP is not set -# CONFIG_BT_FEATURE_DEBUG is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBFUSB is not set -# CONFIG_BT_HCIBLUECARD is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBT3C is not set -# CONFIG_BT_HCIBTSDIO is not set -# CONFIG_BT_HCIBTUSB is not set -# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set -# CONFIG_BT_HCIBTUSB_MTK is not set -# CONFIG_BT_HCIBTUSB_RTL is not set -# CONFIG_BT_HCIDTL1 is not set -# CONFIG_BT_HCIUART is not set -# CONFIG_BT_HCIUART_3WIRE is not set -# CONFIG_BT_HCIUART_AG6XX is not set -# CONFIG_BT_HCIUART_ATH3K is not set -CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_H4=y -# CONFIG_BT_HCIUART_LL is not set -# CONFIG_BT_HCIUART_MRVL is not set -# CONFIG_BT_HCIUART_QCA is not set -# CONFIG_BT_HCIUART_RTL is not set -# CONFIG_BT_HCIVHCI is not set -# CONFIG_BT_HIDP is not set -# CONFIG_BT_HS is not set -# CONFIG_BT_LE is not set -# CONFIG_BT_LEDS is not set -# CONFIG_BT_MRVL is not set -# CONFIG_BT_MSFTEXT is not set -# CONFIG_BT_MTKSDIO is not set -# CONFIG_BT_MTKUART is not set -# CONFIG_BT_RFCOMM is not set -CONFIG_BT_RFCOMM_TTY=y -# CONFIG_BT_SELFTEST is not set -# CONFIG_BT_VIRTIO is not set -CONFIG_BUG=y -# CONFIG_BUG_ON_DATA_CORRUPTION is not set -CONFIG_BUILDTIME_EXTABLE_SORT=y -CONFIG_BUILDTIME_TABLE_SORT=y -# CONFIG_BUILD_BIN2C is not set -CONFIG_BUILD_SALT="" -# CONFIG_C2PORT is not set -CONFIG_CACHE_L2X0_PMU=y -# CONFIG_CADENCE_WATCHDOG is not set -# CONFIG_CAIF is not set -# CONFIG_CAN is not set -# CONFIG_CAN_BCM is not set -# CONFIG_CAN_CAN327 is not set -# CONFIG_CAN_CTUCANFD_PCI is not set -# CONFIG_CAN_CTUCANFD_PLATFORM is not set -# CONFIG_CAN_DEBUG_DEVICES is not set -# CONFIG_CAN_DEV is not set -# CONFIG_CAN_ESD_USB is not set -# CONFIG_CAN_ETAS_ES58X is not set -# CONFIG_CAN_GS_USB is not set -# CONFIG_CAN_GW is not set -# CONFIG_CAN_HI311X is not set -# CONFIG_CAN_IFI_CANFD is not set -# CONFIG_CAN_ISOTP is not set -# CONFIG_CAN_J1939 is not set -# CONFIG_CAN_KVASER_PCIEFD is not set -# CONFIG_CAN_MCBA_USB is not set -# CONFIG_CAN_MCP251XFD is not set -# CONFIG_CAN_M_CAN is not set -# CONFIG_CAN_NETLINK is not set -# CONFIG_CAN_PEAK_PCIEFD is not set -# CONFIG_CAN_RAW is not set -# CONFIG_CAN_RCAR is not set -# CONFIG_CAN_RCAR_CANFD is not set -# CONFIG_CAN_SLCAN is not set -# CONFIG_CAN_SUN4I is not set -# CONFIG_CAN_UCAN is not set -# CONFIG_CAN_VCAN is not set -# CONFIG_CAN_VXCAN is not set -# CONFIG_CAPI_AVM is not set -# CONFIG_CAPI_EICON is not set -# CONFIG_CAPI_TRACE is not set -CONFIG_CARDBUS=y -# CONFIG_CARDMAN_4000 is not set -# CONFIG_CARDMAN_4040 is not set -# CONFIG_CARL9170 is not set -# CONFIG_CASSINI is not set -# CONFIG_CAVIUM_CPT is not set -# CONFIG_CAVIUM_ERRATUM_22375 is not set -# CONFIG_CAVIUM_ERRATUM_23144 is not set -# CONFIG_CAVIUM_ERRATUM_23154 is not set -# CONFIG_CAVIUM_ERRATUM_27456 is not set -# CONFIG_CAVIUM_ERRATUM_30115 is not set -# CONFIG_CAVIUM_OCTEON_SOC is not set -# CONFIG_CAVIUM_PTP is not set -# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set -# CONFIG_CB710_CORE is not set -# CONFIG_CC10001_ADC is not set -# CONFIG_CCS811 is not set -CONFIG_CC_CAN_LINK=y -CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_CEPH_FS is not set -# CONFIG_CEPH_LIB is not set -# CONFIG_CFG80211 is not set -# CONFIG_CFG80211_CERTIFICATION_ONUS is not set -CONFIG_CFG80211_HEADERS=y -# CONFIG_CGROUPS is not set -# CONFIG_CGROUP_FAVOR_DYNMODS is not set -# CONFIG_CGROUP_MISC is not set -# CONFIG_CHARGER_ADP5061 is not set -# CONFIG_CHARGER_BD99954 is not set -# CONFIG_CHARGER_BQ2415X is not set -# CONFIG_CHARGER_BQ24190 is not set -# CONFIG_CHARGER_BQ24257 is not set -# CONFIG_CHARGER_BQ24735 is not set -# CONFIG_CHARGER_BQ2515X is not set -# CONFIG_CHARGER_BQ256XX is not set -# CONFIG_CHARGER_BQ25890 is not set -# CONFIG_CHARGER_BQ25980 is not set -# CONFIG_CHARGER_DETECTOR_MAX14656 is not set -# CONFIG_CHARGER_GPIO is not set -# CONFIG_CHARGER_ISP1704 is not set -# CONFIG_CHARGER_LP8727 is not set -# CONFIG_CHARGER_LT3651 is not set -# CONFIG_CHARGER_LTC3651 is not set -# CONFIG_CHARGER_LTC4162L is not set -# CONFIG_CHARGER_MANAGER is not set -# CONFIG_CHARGER_MAX77976 is not set -# CONFIG_CHARGER_MAX8903 is not set -# CONFIG_CHARGER_QCOM_SMBB is not set -# CONFIG_CHARGER_RT9455 is not set -# CONFIG_CHARGER_SBS is not set -# CONFIG_CHARGER_SMB347 is not set -# CONFIG_CHARGER_TWL4030 is not set -# CONFIG_CHARGER_UCS1002 is not set -# CONFIG_CHASH_SELFTEST is not set -# CONFIG_CHASH_STATS is not set -# CONFIG_CHECKPOINT_RESTORE is not set -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_CHELSIO_T4 is not set -# CONFIG_CHELSIO_T4VF is not set -# CONFIG_CHROME_PLATFORMS is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_CIFS is not set -# CONFIG_CIFS_ACL is not set -CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y -# CONFIG_CIFS_DEBUG is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_FSCACHE is not set -# CONFIG_CIFS_NFSD_EXPORT is not set -CONFIG_CIFS_POSIX=y -# CONFIG_CIFS_SMB2 is not set -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_STATS2 is not set -# CONFIG_CIFS_SWN_UPCALL is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -CONFIG_CIFS_XATTR=y -# CONFIG_CIO_DAC is not set -# CONFIG_CLEANCACHE is not set -# CONFIG_CLKSRC_PISTACHIO is not set -# CONFIG_CLKSRC_VERSATILE is not set -# CONFIG_CLK_GFM_LPASS_SM8250 is not set -# CONFIG_CLK_HSDK is not set -# CONFIG_CLK_ICST is not set -# CONFIG_CLK_QORIQ is not set -# CONFIG_CLK_SP810 is not set -# CONFIG_CLOCK_THERMAL is not set -CONFIG_CLS_U32_MARK=y -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CM32181 is not set -# CONFIG_CM3232 is not set -# CONFIG_CM3323 is not set -# CONFIG_CM3605 is not set -# CONFIG_CM36651 is not set -# CONFIG_CMA is not set -CONFIG_CMDLINE="" -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_CMDLINE_EXTEND is not set -# CONFIG_CMDLINE_FORCE is not set -# CONFIG_CMDLINE_FROM_BOOTLOADER is not set -# CONFIG_CMDLINE_PARTITION is not set -# CONFIG_CNIC is not set -# CONFIG_CODA_FS is not set -# CONFIG_CODE_PATCHING_SELFTEST is not set -# CONFIG_COMEDI is not set -# CONFIG_COMMON_CLK_AXI_CLKGEN is not set -# CONFIG_COMMON_CLK_BOSTON is not set -# CONFIG_COMMON_CLK_CDCE706 is not set -# CONFIG_COMMON_CLK_CDCE925 is not set -# CONFIG_COMMON_CLK_CS2000_CP is not set -# CONFIG_COMMON_CLK_FIXED_MMIO is not set -# CONFIG_COMMON_CLK_IPROC is not set -# CONFIG_COMMON_CLK_MAX9485 is not set -# CONFIG_COMMON_CLK_MT6765 is not set -# CONFIG_COMMON_CLK_MT8167 is not set -# CONFIG_COMMON_CLK_MT8167_AUDSYS is not set -# CONFIG_COMMON_CLK_MT8167_IMGSYS is not set -# CONFIG_COMMON_CLK_MT8167_MFGCFG is not set -# CONFIG_COMMON_CLK_MT8167_MMSYS is not set -# CONFIG_COMMON_CLK_MT8167_VDECSYS is not set -# CONFIG_COMMON_CLK_MT8192 is not set -# CONFIG_COMMON_CLK_NXP is not set -# CONFIG_COMMON_CLK_PIC32 is not set -# CONFIG_COMMON_CLK_PISTACHIO is not set -# CONFIG_COMMON_CLK_PWM is not set -# CONFIG_COMMON_CLK_PXA is not set -# CONFIG_COMMON_CLK_QCOM is not set -# CONFIG_COMMON_CLK_RP1 is not set -# CONFIG_COMMON_CLK_RP1_SDIO is not set -# CONFIG_COMMON_CLK_RS9_PCIE is not set -# CONFIG_COMMON_CLK_SI514 is not set -# CONFIG_COMMON_CLK_SI5341 is not set -# CONFIG_COMMON_CLK_SI5351 is not set -# CONFIG_COMMON_CLK_SI544 is not set -# CONFIG_COMMON_CLK_SI570 is not set -# CONFIG_COMMON_CLK_VC5 is not set -# CONFIG_COMMON_CLK_VC7 is not set -# CONFIG_COMMON_CLK_XGENE is not set -# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set -CONFIG_COMPACTION=y -# CONFIG_COMPAL_LAPTOP is not set -# CONFIG_COMPAT is not set -# CONFIG_COMPAT_BRK is not set -# CONFIG_COMPILE_TEST is not set -# CONFIG_CONFIGFS_FS is not set -# CONFIG_CONNECTOR is not set -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 -CONFIG_CONSOLE_LOGLEVEL_QUIET=4 -CONFIG_CONSTRUCTORS=y -# CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_COPS is not set -# CONFIG_CORDIC is not set -# CONFIG_COREDUMP is not set -# CONFIG_CORESIGHT is not set -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_CORTINA_PHY is not set -# CONFIG_COUNTER is not set -# CONFIG_CPA_DEBUG is not set -# CONFIG_CPU_BIG_ENDIAN is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set -# CONFIG_CPU_FREQ_STAT_DETAILS is not set -# CONFIG_CPU_FREQ_THERMAL is not set -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set -# CONFIG_CPU_IDLE is not set -# CONFIG_CPU_IDLE_GOV_LADDER is not set -# CONFIG_CPU_IDLE_GOV_MENU is not set -# CONFIG_CPU_IDLE_GOV_TEO is not set -# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set -# CONFIG_CPU_ISOLATION is not set -# CONFIG_CPU_LITTLE_ENDIAN is not set -# CONFIG_CPU_NO_EFFICIENT_FFS is not set -CONFIG_CPU_SW_DOMAIN_PAN=y -# CONFIG_CPU_THERMAL is not set -# CONFIG_CRAMFS is not set -CONFIG_CRAMFS_BLOCKDEV=y -# CONFIG_CRAMFS_MTD is not set -# CONFIG_CRASH_DUMP is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_CRC32_BIT is not set -# CONFIG_CRC32_SARWATE is not set -# CONFIG_CRC32_SELFTEST is not set -# CONFIG_CRC32_SLICEBY4 is not set -CONFIG_CRC32_SLICEBY8=y -# CONFIG_CRC4 is not set -# CONFIG_CRC64 is not set -# CONFIG_CRC64_ROCKSOFT is not set -# CONFIG_CRC7 is not set -# CONFIG_CRC8 is not set -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC_ITU_T is not set -# CONFIG_CRC_T10DIF is not set -CONFIG_CROSS_COMPILE="" -# CONFIG_CROSS_MEMORY_ATTACH is not set -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_842 is not set -CONFIG_CRYPTO_ACOMP2=y -# CONFIG_CRYPTO_ADIANTUM is not set -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -# CONFIG_CRYPTO_AEGIS128 is not set -# CONFIG_CRYPTO_AEGIS128L is not set -# CONFIG_CRYPTO_AEGIS128L_AESNI_SSE2 is not set -# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set -# CONFIG_CRYPTO_AEGIS256 is not set -# CONFIG_CRYPTO_AEGIS256_AESNI_SSE2 is not set -CONFIG_CRYPTO_AES=y -# CONFIG_CRYPTO_AES_586 is not set -# CONFIG_CRYPTO_AES_ARM is not set -# CONFIG_CRYPTO_AES_ARM64 is not set -# CONFIG_CRYPTO_AES_ARM64_BS is not set -# CONFIG_CRYPTO_AES_ARM64_CE is not set -# CONFIG_CRYPTO_AES_ARM64_CE_BLK is not set -# CONFIG_CRYPTO_AES_ARM64_CE_CCM is not set -# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set -# CONFIG_CRYPTO_AES_ARM_BS is not set -# CONFIG_CRYPTO_AES_ARM_CE is not set -# CONFIG_CRYPTO_AES_NI_INTEL is not set -# CONFIG_CRYPTO_AES_TI is not set -CONFIG_CRYPTO_AKCIPHER=y -CONFIG_CRYPTO_AKCIPHER2=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_ARIA is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_BLAKE2B is not set -# CONFIG_CRYPTO_BLAKE2B_NEON is not set -# CONFIG_CRYPTO_BLAKE2S_ARM is not set -# CONFIG_CRYPTO_BLAKE2S_X86 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_CBC is not set -CONFIG_CRYPTO_CCM=y -# CONFIG_CRYPTO_CFB is not set -# CONFIG_CRYPTO_CHACHA20 is not set -# CONFIG_CRYPTO_CHACHA20POLY1305 is not set -# CONFIG_CRYPTO_CHACHA20_NEON is not set -# CONFIG_CRYPTO_CHACHA20_X86_64 is not set -# CONFIG_CRYPTO_CHACHA_MIPS is not set -# CONFIG_CRYPTO_CMAC is not set -# CONFIG_CRYPTO_CRC32 is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CRC32C_INTEL is not set -# CONFIG_CRYPTO_CRC32_ARM_CE is not set -# CONFIG_CRYPTO_CRCT10DIF is not set -# CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set -# CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set -# CONFIG_CRYPTO_CRYPTD is not set -CONFIG_CRYPTO_CTR=y -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_CURVE25519 is not set -# CONFIG_CRYPTO_CURVE25519_NEON is not set -# CONFIG_CRYPTO_CURVE25519_X86 is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set -# CONFIG_CRYPTO_DEV_ATMEL_AES is not set -# CONFIG_CRYPTO_DEV_ATMEL_AUTHENC is not set -# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set -# CONFIG_CRYPTO_DEV_ATMEL_SHA is not set -# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set -# CONFIG_CRYPTO_DEV_ATMEL_TDES is not set -# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set -# CONFIG_CRYPTO_DEV_CCP is not set -# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set -# CONFIG_CRYPTO_DEV_CCREE is not set -# CONFIG_CRYPTO_DEV_FSL_CAAM is not set -# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set -# CONFIG_CRYPTO_DEV_HIFN_795X is not set -# CONFIG_CRYPTO_DEV_HISI_SEC is not set -# CONFIG_CRYPTO_DEV_HISI_ZIP is not set -# CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set -# CONFIG_CRYPTO_DEV_MARVELL_CESA is not set -# CONFIG_CRYPTO_DEV_MEDIATEK is not set -# CONFIG_CRYPTO_DEV_MV_CESA is not set -# CONFIG_CRYPTO_DEV_MXC_SCC is not set -# CONFIG_CRYPTO_DEV_MXS_DCP is not set -# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set -# CONFIG_CRYPTO_DEV_OCTEONTX_CPT is not set -# CONFIG_CRYPTO_DEV_QAT_4XXX is not set -# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set -# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set -# CONFIG_CRYPTO_DEV_QAT_C62X is not set -# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set -# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set -# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set -# CONFIG_CRYPTO_DEV_QCE is not set -# CONFIG_CRYPTO_DEV_S5P is not set -# CONFIG_CRYPTO_DEV_SAFEXCEL is not set -# CONFIG_CRYPTO_DEV_SAHARA is not set -# CONFIG_CRYPTO_DEV_SP_PSP is not set -# CONFIG_CRYPTO_DEV_TALITOS is not set -# CONFIG_CRYPTO_DEV_VIRTIO is not set -# CONFIG_CRYPTO_DH is not set -# CONFIG_CRYPTO_DRBG_CTR is not set -# CONFIG_CRYPTO_DRBG_HASH is not set -# CONFIG_CRYPTO_DRBG_MENU is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_ECDH is not set -# CONFIG_CRYPTO_ECDSA is not set -# CONFIG_CRYPTO_ECHAINIV is not set -# CONFIG_CRYPTO_ECRDSA is not set -# CONFIG_CRYPTO_ESSIV is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_FIPS is not set -CONFIG_CRYPTO_GCM=y -CONFIG_CRYPTO_GF128MUL=y -CONFIG_CRYPTO_GHASH=y -# CONFIG_CRYPTO_GHASH_ARM64_CE is not set -# CONFIG_CRYPTO_GHASH_ARM_CE is not set -# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -# CONFIG_CRYPTO_HCTR2 is not set -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_HW is not set -# CONFIG_CRYPTO_JITTERENTROPY is not set -# CONFIG_CRYPTO_KEYWRAP is not set -# CONFIG_CRYPTO_KHAZAD is not set -CONFIG_CRYPTO_KPP=y -CONFIG_CRYPTO_KPP2=y -CONFIG_CRYPTO_LIB_AES=y -CONFIG_CRYPTO_LIB_ARC4=y -# CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC is not set -# CONFIG_CRYPTO_LIB_CHACHA is not set -# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set -# CONFIG_CRYPTO_LIB_CURVE25519 is not set -# CONFIG_CRYPTO_LIB_POLY1305 is not set -CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_LZ4 is not set -# CONFIG_CRYPTO_LZ4HC is not set -# CONFIG_CRYPTO_LZO is not set -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y -# CONFIG_CRYPTO_MCRYPTD is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_MORUS1280 is not set -# CONFIG_CRYPTO_MORUS1280_AVX2 is not set -# CONFIG_CRYPTO_MORUS1280_SSE2 is not set -# CONFIG_CRYPTO_MORUS640 is not set -# CONFIG_CRYPTO_MORUS640_SSE2 is not set -# CONFIG_CRYPTO_NHPOLY1305_NEON is not set -CONFIG_CRYPTO_NULL=y -CONFIG_CRYPTO_NULL2=y -# CONFIG_CRYPTO_OFB is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_PCOMP is not set -# CONFIG_CRYPTO_PCOMP2 is not set -CONFIG_CRYPTO_PCRYPT=y -# CONFIG_CRYPTO_POLY1305 is not set -# CONFIG_CRYPTO_POLY1305_ARM is not set -# CONFIG_CRYPTO_POLY1305_MIPS is not set -# CONFIG_CRYPTO_POLY1305_NEON is not set -# CONFIG_CRYPTO_POLY1305_X86_64 is not set -# CONFIG_CRYPTO_POLYVAL_ARM64_CE is not set -# CONFIG_CRYPTO_RMD160 is not set -# CONFIG_CRYPTO_RNG is not set -# CONFIG_CRYPTO_RSA is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SEQIV is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA1_ARM is not set -# CONFIG_CRYPTO_SHA1_ARM64_CE is not set -# CONFIG_CRYPTO_SHA1_ARM_CE is not set -# CONFIG_CRYPTO_SHA1_ARM_NEON is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA256_ARM is not set -# CONFIG_CRYPTO_SHA256_ARM64 is not set -# CONFIG_CRYPTO_SHA2_ARM64_CE is not set -# CONFIG_CRYPTO_SHA2_ARM_CE is not set -# CONFIG_CRYPTO_SHA3 is not set -# CONFIG_CRYPTO_SHA3_ARM64 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_SHA512_ARM is not set -# CONFIG_CRYPTO_SHA512_ARM64 is not set -# CONFIG_CRYPTO_SHA512_ARM64_CE is not set -# CONFIG_CRYPTO_SIMD is not set -CONFIG_CRYPTO_SKCIPHER=y -CONFIG_CRYPTO_SKCIPHER2=y -# CONFIG_CRYPTO_SM2 is not set -# CONFIG_CRYPTO_SM3 is not set -# CONFIG_CRYPTO_SM3_ARM64_CE is not set -# CONFIG_CRYPTO_SM3_GENERIC is not set -# CONFIG_CRYPTO_SM3_NEON is not set -# CONFIG_CRYPTO_SM4 is not set -# CONFIG_CRYPTO_SM4_ARM64_CE is not set -# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set -# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set -# CONFIG_CRYPTO_SM4_GENERIC is not set -# CONFIG_CRYPTO_SPECK is not set -# CONFIG_CRYPTO_STATS is not set -# CONFIG_CRYPTO_STREEBOG is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TEST is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_TWOFISH_586 is not set -# CONFIG_CRYPTO_TWOFISH_COMMON is not set -# CONFIG_CRYPTO_USER is not set -# CONFIG_CRYPTO_USER_API_AEAD is not set -# CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set -# CONFIG_CRYPTO_USER_API_HASH is not set -# CONFIG_CRYPTO_USER_API_RNG is not set -# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set -# CONFIG_CRYPTO_USER_API_SKCIPHER is not set -# CONFIG_CRYPTO_VMAC is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_CRYPTO_XXHASH is not set -# CONFIG_CRYPTO_ZLIB is not set -# CONFIG_CRYPTO_ZSTD is not set -# CONFIG_CS5535_MFGPT is not set -# CONFIG_CS89x0 is not set -# CONFIG_CS89x0_PLATFORM is not set -# CONFIG_CSD_LOCK_WAIT_DEBUG is not set -# CONFIG_CUSE is not set -# CONFIG_CW1200 is not set -# CONFIG_CXD2880_SPI_DRV is not set -# CONFIG_CXL_AFU_DRIVER_OPS is not set -# CONFIG_CXL_BASE is not set -# CONFIG_CXL_BUS is not set -# CONFIG_CXL_EEH is not set -# CONFIG_CXL_KERNEL_API is not set -# CONFIG_CXL_LIB is not set -# CONFIG_CYPRESS_FIRMWARE is not set -# CONFIG_DA280 is not set -# CONFIG_DA311 is not set -# CONFIG_DAMON is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_DAX is not set -# CONFIG_DCB is not set -# CONFIG_DDR is not set -# CONFIG_DEBUG_ALIGN_RODATA is not set -# CONFIG_DEBUG_ATOMIC_SLEEP is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_CREDENTIALS is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_EFI is not set -# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B is not set -# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_FS_ALLOW_ALL=y -# CONFIG_DEBUG_FS_ALLOW_NONE is not set -# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set -# CONFIG_DEBUG_GPIO is not set -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_ICEDCC is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_INFO_BTF is not set -# CONFIG_DEBUG_INFO_COMPRESSED is not set -# CONFIG_DEBUG_INFO_DWARF4 is not set -# CONFIG_DEBUG_INFO_DWARF5 is not set -CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y -# CONFIG_DEBUG_INFO_NONE is not set -# CONFIG_DEBUG_INFO_REDUCED is not set -# CONFIG_DEBUG_INFO_SPLIT is not set -# CONFIG_DEBUG_IRQFLAGS is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_KMAP_LOCAL is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_KOBJECT_RELEASE is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_LL is not set -# CONFIG_DEBUG_LL_UART_8250 is not set -# CONFIG_DEBUG_LL_UART_PL01X is not set -# CONFIG_DEBUG_LOCKDEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_DEBUG_MAPLE_TREE is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_MISC is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_NET is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_NX_TEST is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_DEBUG_PAGE_REF is not set -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -# CONFIG_DEBUG_PER_CPU_MAPS is not set -# CONFIG_DEBUG_PINCTRL is not set -# CONFIG_DEBUG_PI_LIST is not set -# CONFIG_DEBUG_PLIST is not set -# CONFIG_DEBUG_PREEMPT is not set -# CONFIG_DEBUG_RODATA_TEST is not set -# CONFIG_DEBUG_RSEQ is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -# CONFIG_DEBUG_SEMIHOSTING is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_SHIRQ is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set -# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set -# CONFIG_DEBUG_TIMEKEEPING is not set -# CONFIG_DEBUG_UART_8250_PALMCHIP is not set -# CONFIG_DEBUG_UART_8250_WORD is not set -# CONFIG_DEBUG_UART_BCM63XX is not set -# CONFIG_DEBUG_UART_FLOW_CONTROL is not set -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_VIRTUAL is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_VM_PGFLAGS is not set -# CONFIG_DEBUG_VM_PGTABLE is not set -# CONFIG_DEBUG_VM_RB is not set -# CONFIG_DEBUG_VM_VMACACHE is not set -# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -# CONFIG_DEBUG_WX is not set -# CONFIG_DEBUG_ZBOOT is not set -# CONFIG_DECNET is not set -# CONFIG_DEFAULT_CODEL is not set -CONFIG_DEFAULT_CUBIC=y -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_FQ is not set -CONFIG_DEFAULT_FQ_CODEL=y -# CONFIG_DEFAULT_FQ_PIE is not set -CONFIG_DEFAULT_HOSTNAME="(none)" -CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 -CONFIG_DEFAULT_INIT="" -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_DEFAULT_NET_SCH="fq_codel" -# CONFIG_DEFAULT_NOOP is not set -# CONFIG_DEFAULT_PFIFO_FAST is not set -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_SECURITY="" -CONFIG_DEFAULT_SECURITY_DAC=y -# CONFIG_DEFAULT_SECURITY_SELINUX is not set -# CONFIG_DEFAULT_SFQ is not set -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set -# CONFIG_DELL_LAPTOP is not set -# CONFIG_DELL_RBTN is not set -# CONFIG_DELL_SMBIOS is not set -# CONFIG_DELL_SMO8800 is not set -# CONFIG_DEPRECATED_PARAM_STRUCT is not set -# CONFIG_DETECT_HUNG_TASK is not set -# CONFIG_DEVKMEM is not set -# CONFIG_DEVMEM is not set -CONFIG_DEVPORT=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_DEVTMPFS is not set -# CONFIG_DEVTMPFS_MOUNT is not set -# CONFIG_DEVTMPFS_SAFE is not set -# CONFIG_DEV_DAX is not set -# CONFIG_DGAP is not set -# CONFIG_DGNC is not set -# CONFIG_DHT11 is not set -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_DISPLAY_CONNECTOR_ANALOG_TV is not set -# CONFIG_DISPLAY_CONNECTOR_DVI is not set -# CONFIG_DISPLAY_CONNECTOR_HDMI is not set -# CONFIG_DISPLAY_ENCODER_TFP410 is not set -# CONFIG_DISPLAY_ENCODER_TPD12S015 is not set -# CONFIG_DISPLAY_PANEL_DPI is not set -# CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02 is not set -# CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1 is not set -# CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1 is not set -# CONFIG_DL2K is not set -# CONFIG_DLHL60D is not set -# CONFIG_DLM is not set -# CONFIG_DM9000 is not set -# CONFIG_DM9051 is not set -# CONFIG_DMABUF_DEBUG is not set -# CONFIG_DMABUF_HEAPS is not set -# CONFIG_DMABUF_MOVE_NOTIFY is not set -# CONFIG_DMABUF_SELFTESTS is not set -# CONFIG_DMABUF_SYSFS_STATS is not set -# CONFIG_DMADEVICES is not set -# CONFIG_DMADEVICES_DEBUG is not set -# CONFIG_DMARD06 is not set -# CONFIG_DMARD09 is not set -# CONFIG_DMARD10 is not set -# CONFIG_DMASCC is not set -# CONFIG_DMATEST is not set -# CONFIG_DMA_API_DEBUG is not set -CONFIG_DMA_COHERENT_POOL=y -CONFIG_DMA_DECLARE_COHERENT=y -# CONFIG_DMA_ENGINE is not set -# CONFIG_DMA_FENCE_TRACE is not set -# CONFIG_DMA_JZ4780 is not set -# CONFIG_DMA_MAP_BENCHMARK is not set -CONFIG_DMA_NONCOHERENT_MMAP=y -# CONFIG_DMA_NOOP_OPS is not set -# CONFIG_DMA_PERNUMA_CMA is not set -# CONFIG_DMA_RESTRICTED_POOL is not set -# CONFIG_DMA_SHARED_BUFFER is not set -# CONFIG_DMA_VIRT_OPS is not set -# CONFIG_DM_CACHE is not set -# CONFIG_DM_CLONE is not set -# CONFIG_DM_DEBUG is not set -# CONFIG_DM_DELAY is not set -# CONFIG_DM_DUST is not set -# CONFIG_DM_EBS is not set -# CONFIG_DM_ERA is not set -# CONFIG_DM_FLAKEY is not set -# CONFIG_DM_INTEGRITY is not set -# CONFIG_DM_LOG_USERSPACE is not set -# CONFIG_DM_LOG_WRITES is not set -# CONFIG_DM_MQ_DEFAULT is not set -# CONFIG_DM_MULTIPATH is not set -# CONFIG_DM_RAID is not set -# CONFIG_DM_SWITCH is not set -# CONFIG_DM_THIN_PROVISIONING is not set -# CONFIG_DM_UEVENT is not set -# CONFIG_DM_UNSTRIPED is not set -# CONFIG_DM_VERITY is not set -# CONFIG_DM_WRITECACHE is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DNET is not set -# CONFIG_DNOTIFY is not set -# CONFIG_DNS_RESOLVER is not set -CONFIG_DOUBLEFAULT=y -# CONFIG_DP83640_PHY is not set -# CONFIG_DP83822_PHY is not set -# CONFIG_DP83848_PHY is not set -# CONFIG_DP83867_PHY is not set -# CONFIG_DP83869_PHY is not set -# CONFIG_DP83TC811_PHY is not set -# CONFIG_DP83TD510_PHY is not set -# CONFIG_DPOT_DAC is not set -# CONFIG_DPS310 is not set -CONFIG_DQL=y -# CONFIG_DRAGONRISE_FF is not set -# CONFIG_DRM is not set -# CONFIG_DRM_AMDGPU is not set -# CONFIG_DRM_AMDGPU_CIK is not set -# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set -# CONFIG_DRM_AMDGPU_SI is not set -# CONFIG_DRM_AMDGPU_USERPTR is not set -# CONFIG_DRM_AMD_ACP is not set -# CONFIG_DRM_AMD_DC_DCN2_0 is not set -# CONFIG_DRM_AMD_DC_DCN3_0 is not set -# CONFIG_DRM_AMD_DC_HDCP is not set -# CONFIG_DRM_AMD_DC_SI is not set -# CONFIG_DRM_AMD_SECURE_DISPLAY is not set -# CONFIG_DRM_ANALOGIX_ANX6345 is not set -# CONFIG_DRM_ANALOGIX_ANX7625 is not set -# CONFIG_DRM_ANALOGIX_ANX78XX is not set -# CONFIG_DRM_ARCPGU is not set -# CONFIG_DRM_ARMADA is not set -# CONFIG_DRM_AST is not set -# CONFIG_DRM_ATMEL_HLCDC is not set -# CONFIG_DRM_BOCHS is not set -# CONFIG_DRM_CDNS_DSI is not set -# CONFIG_DRM_CDNS_MHDP8546 is not set -# CONFIG_DRM_CHIPONE_ICN6211 is not set -# CONFIG_DRM_CHRONTEL_CH7033 is not set -# CONFIG_DRM_CIRRUS_QEMU is not set -# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set -# CONFIG_DRM_DEBUG_MM is not set -# CONFIG_DRM_DEBUG_MODESET_LOCK is not set -# CONFIG_DRM_DEBUG_SELFTEST is not set -# CONFIG_DRM_DISPLAY_CONNECTOR is not set -# CONFIG_DRM_DP_AUX_CHARDEV is not set -# CONFIG_DRM_DP_CEC is not set -# CONFIG_DRM_DUMB_VGA_DAC is not set -# CONFIG_DRM_DW_HDMI_CEC is not set -# CONFIG_DRM_ETNAVIV is not set -# CONFIG_DRM_EXYNOS is not set -# CONFIG_DRM_FBDEV_EMULATION is not set -# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set -# CONFIG_DRM_FSL_DCU is not set -# CONFIG_DRM_GM12U320 is not set -# CONFIG_DRM_GMA500 is not set -# CONFIG_DRM_GUD is not set -# CONFIG_DRM_HDLCD is not set -# CONFIG_DRM_HISI_HIBMC is not set -# CONFIG_DRM_HISI_KIRIN is not set -# CONFIG_DRM_I2C_ADV7511 is not set -# CONFIG_DRM_I2C_CH7006 is not set -# CONFIG_DRM_I2C_NXP_TDA9950 is not set -# CONFIG_DRM_I2C_NXP_TDA998X is not set -# CONFIG_DRM_I2C_SIL164 is not set -# CONFIG_DRM_I915 is not set -# CONFIG_DRM_IMX_LCDIF is not set -# CONFIG_DRM_ITE_IT6505 is not set -# CONFIG_DRM_ITE_IT66121 is not set -# CONFIG_DRM_KOMEDA is not set -# CONFIG_DRM_LEGACY is not set -# CONFIG_DRM_LIB_RANDOM is not set -# CONFIG_DRM_LIMA is not set -# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set -# CONFIG_DRM_LOGICVC is not set -# CONFIG_DRM_LONTIUM_LT8912B is not set -# CONFIG_DRM_LONTIUM_LT9211 is not set -# CONFIG_DRM_LONTIUM_LT9611 is not set -# CONFIG_DRM_LONTIUM_LT9611UXC is not set -# CONFIG_DRM_LVDS_CODEC is not set -# CONFIG_DRM_LVDS_ENCODER is not set -# CONFIG_DRM_MALI_DISPLAY is not set -# CONFIG_DRM_MCDE is not set -# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set -# CONFIG_DRM_MGAG200 is not set -# CONFIG_DRM_MXSFB is not set -# CONFIG_DRM_NOUVEAU is not set -# CONFIG_DRM_NWL_MIPI_DSI is not set -# CONFIG_DRM_NXP_PTN3460 is not set -# CONFIG_DRM_OMAP is not set -# CONFIG_DRM_PANEL_ABT_Y030XX067A is not set -# CONFIG_DRM_PANEL_ARM_VERSATILE is not set -# CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596 is not set -# CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0 is not set -# CONFIG_DRM_PANEL_BOE_HIMAX8279D is not set -# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set -# CONFIG_DRM_PANEL_DSI_CM is not set -# CONFIG_DRM_PANEL_EBBG_FT8719 is not set -# CONFIG_DRM_PANEL_EDP is not set -# CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set -# CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02 is not set -# CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set -# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set -# CONFIG_DRM_PANEL_ILITEK_ILI9341 is not set -# CONFIG_DRM_PANEL_ILITEK_ILI9806E is not set -# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set -# CONFIG_DRM_PANEL_INNOLUX_EJ030NA is not set -# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set -# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set -# CONFIG_DRM_PANEL_JDI_R63452 is not set -# CONFIG_DRM_PANEL_KHADAS_TS050 is not set -# CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set -# CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W is not set -# CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829 is not set -# CONFIG_DRM_PANEL_LG_LB035Q02 is not set -# CONFIG_DRM_PANEL_LG_LG4573 is not set -# CONFIG_DRM_PANEL_LVDS is not set -# CONFIG_DRM_PANEL_MANTIX_MLAF057WE51 is not set -# CONFIG_DRM_PANEL_MIPI_DBI is not set -# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set -# CONFIG_DRM_PANEL_NEWVISION_NV3052C is not set -# CONFIG_DRM_PANEL_NOVATEK_NT35510 is not set -# CONFIG_DRM_PANEL_NOVATEK_NT35560 is not set -# CONFIG_DRM_PANEL_NOVATEK_NT35950 is not set -# CONFIG_DRM_PANEL_NOVATEK_NT36672A is not set -# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set -# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set -# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set -# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set -# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set -# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set -# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set -# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set -# CONFIG_DRM_PANEL_ROCKTECH_JH057N00900 is not set -# CONFIG_DRM_PANEL_RONBO_RB070D30 is not set -# CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20 is not set -# CONFIG_DRM_PANEL_SAMSUNG_DB7430 is not set -# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6D27A1 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set -# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set -# CONFIG_DRM_PANEL_SAMSUNG_SOFEF00 is not set -# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set -# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set -# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set -# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set -# CONFIG_DRM_PANEL_SHARP_LS060T1SX01 is not set -# CONFIG_DRM_PANEL_SIMPLE is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set -# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set -# CONFIG_DRM_PANEL_SONY_ACX424AKP is not set -# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set -# CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521 is not set -# CONFIG_DRM_PANEL_TDO_TL070WSH30 is not set -# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set -# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set -# CONFIG_DRM_PANEL_TPO_TPG110 is not set -# CONFIG_DRM_PANEL_TPO_Y17P is not set -# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set -# CONFIG_DRM_PANEL_VISIONOX_RM69299 is not set -# CONFIG_DRM_PANEL_WAVESHARE_TOUCHSCREEN is not set -# CONFIG_DRM_PANEL_WIDECHIPS_WS2401 is not set -# CONFIG_DRM_PANEL_XINPENG_XPP055C272 is not set -# CONFIG_DRM_PANFROST is not set -# CONFIG_DRM_PARADE_PS8622 is not set -# CONFIG_DRM_PARADE_PS8640 is not set -# CONFIG_DRM_PL111 is not set -# CONFIG_DRM_QXL is not set -# CONFIG_DRM_RADEON is not set -# CONFIG_DRM_RADEON_USERPTR is not set -# CONFIG_DRM_RCAR_DW_HDMI is not set -# CONFIG_DRM_RCAR_LVDS is not set -# CONFIG_DRM_RCAR_USE_LVDS is not set -# CONFIG_DRM_RCAR_USE_MIPI_DSI is not set -# CONFIG_DRM_ROCKCHIP is not set -# CONFIG_DRM_RP1_DPI is not set -# CONFIG_DRM_RP1_DSI is not set -# CONFIG_DRM_RP1_VEC is not set -# CONFIG_DRM_SII902X is not set -# CONFIG_DRM_SII9234 is not set -# CONFIG_DRM_SIL_SII8620 is not set -# CONFIG_DRM_SIMPLEDRM is not set -# CONFIG_DRM_SIMPLE_BRIDGE is not set -# CONFIG_DRM_SSD130X is not set -# CONFIG_DRM_STI is not set -# CONFIG_DRM_STM is not set -# CONFIG_DRM_SUN4I is not set -# CONFIG_DRM_THINE_THC63LVD1024 is not set -# CONFIG_DRM_TIDSS is not set -# CONFIG_DRM_TILCDC is not set -# CONFIG_DRM_TINYDRM is not set -# CONFIG_DRM_TI_DLPC3433 is not set -# CONFIG_DRM_TI_SN65DSI83 is not set -# CONFIG_DRM_TI_SN65DSI86 is not set -# CONFIG_DRM_TI_TFP410 is not set -# CONFIG_DRM_TI_TPD12S015 is not set -# CONFIG_DRM_TOSHIBA_TC358762 is not set -# CONFIG_DRM_TOSHIBA_TC358764 is not set -# CONFIG_DRM_TOSHIBA_TC358767 is not set -# CONFIG_DRM_TOSHIBA_TC358768 is not set -# CONFIG_DRM_TOSHIBA_TC358775 is not set -# CONFIG_DRM_TVE200 is not set -# CONFIG_DRM_UDL is not set -# CONFIG_DRM_V3D is not set -# CONFIG_DRM_VBOXVIDEO is not set -# CONFIG_DRM_VC4_HDMI_CEC is not set -# CONFIG_DRM_VGEM is not set -# CONFIG_DRM_VIRTIO_GPU is not set -# CONFIG_DRM_VKMS is not set -# CONFIG_DRM_VMWGFX is not set -# CONFIG_DRM_XEN is not set -# CONFIG_DRM_XEN_FRONTEND is not set -# CONFIG_DS1682 is not set -# CONFIG_DS1803 is not set -# CONFIG_DS4424 is not set -# CONFIG_DST_CACHE is not set -# CONFIG_DTLK is not set -# CONFIG_DUMMY is not set -CONFIG_DUMMY_CONSOLE_COLUMNS=80 -CONFIG_DUMMY_CONSOLE_ROWS=25 -# CONFIG_DUMMY_IRQ is not set -# CONFIG_DVB_A8293 is not set -# CONFIG_DVB_AF9013 is not set -# CONFIG_DVB_AF9033 is not set -# CONFIG_DVB_AS102 is not set -# CONFIG_DVB_ASCOT2E is not set -# CONFIG_DVB_ATBM8830 is not set -# CONFIG_DVB_AU8522_DTV is not set -# CONFIG_DVB_AU8522_V4L is not set -# CONFIG_DVB_B2C2_FLEXCOP_PCI is not set -# CONFIG_DVB_B2C2_FLEXCOP_USB is not set -# CONFIG_DVB_BCM3510 is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DVB_CX22700 is not set -# CONFIG_DVB_CX22702 is not set -# CONFIG_DVB_CX24110 is not set -# CONFIG_DVB_CX24116 is not set -# CONFIG_DVB_CX24117 is not set -# CONFIG_DVB_CX24120 is not set -# CONFIG_DVB_CX24123 is not set -# CONFIG_DVB_CXD2099 is not set -# CONFIG_DVB_CXD2820R is not set -# CONFIG_DVB_CXD2841ER is not set -# CONFIG_DVB_CXD2880 is not set -# CONFIG_DVB_DDBRIDGE is not set -# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set -# CONFIG_DVB_DIB3000MB is not set -# CONFIG_DVB_DIB3000MC is not set -# CONFIG_DVB_DIB7000M is not set -# CONFIG_DVB_DIB7000P is not set -# CONFIG_DVB_DIB8000 is not set -# CONFIG_DVB_DIB9000 is not set -# CONFIG_DVB_DRX39XYJ is not set -# CONFIG_DVB_DRXD is not set -# CONFIG_DVB_DRXK is not set -# CONFIG_DVB_DS3000 is not set -# CONFIG_DVB_DUMMY_FE is not set -# CONFIG_DVB_DYNAMIC_MINORS is not set -# CONFIG_DVB_EC100 is not set -# CONFIG_DVB_FIREDTV is not set -# CONFIG_DVB_HELENE is not set -# CONFIG_DVB_HORUS3A is not set -# CONFIG_DVB_ISL6405 is not set -# CONFIG_DVB_ISL6421 is not set -# CONFIG_DVB_ISL6423 is not set -# CONFIG_DVB_IX2505V is not set -# CONFIG_DVB_L64781 is not set -# CONFIG_DVB_LG2160 is not set -# CONFIG_DVB_LGDT3305 is not set -# CONFIG_DVB_LGDT3306A is not set -# CONFIG_DVB_LGDT330X is not set -# CONFIG_DVB_LGS8GL5 is not set -# CONFIG_DVB_LGS8GXX is not set -# CONFIG_DVB_LNBH25 is not set -# CONFIG_DVB_LNBH29 is not set -# CONFIG_DVB_LNBP21 is not set -# CONFIG_DVB_LNBP22 is not set -# CONFIG_DVB_M88DS3103 is not set -# CONFIG_DVB_M88RS2000 is not set -CONFIG_DVB_MAX_ADAPTERS=16 -# CONFIG_DVB_MB86A16 is not set -# CONFIG_DVB_MB86A20S is not set -# CONFIG_DVB_MMAP is not set -# CONFIG_DVB_MN88443X is not set -# CONFIG_DVB_MN88472 is not set -# CONFIG_DVB_MN88473 is not set -# CONFIG_DVB_MT312 is not set -# CONFIG_DVB_MT352 is not set -# CONFIG_DVB_MXL5XX is not set -# CONFIG_DVB_MXL692 is not set -# CONFIG_DVB_NET is not set -# CONFIG_DVB_NETUP_UNIDVB is not set -# CONFIG_DVB_NGENE is not set -# CONFIG_DVB_NXT200X is not set -# CONFIG_DVB_NXT6000 is not set -# CONFIG_DVB_OR51132 is not set -# CONFIG_DVB_OR51211 is not set -# CONFIG_DVB_PLATFORM_DRIVERS is not set -# CONFIG_DVB_PLL is not set -# CONFIG_DVB_PLUTO2 is not set -# CONFIG_DVB_PT1 is not set -# CONFIG_DVB_PT3 is not set -# CONFIG_DVB_RTL2830 is not set -# CONFIG_DVB_RTL2832 is not set -# CONFIG_DVB_RTL2832_SDR is not set -# CONFIG_DVB_S5H1409 is not set -# CONFIG_DVB_S5H1411 is not set -# CONFIG_DVB_S5H1420 is not set -# CONFIG_DVB_S5H1432 is not set -# CONFIG_DVB_S921 is not set -# CONFIG_DVB_SI2165 is not set -# CONFIG_DVB_SI2168 is not set -# CONFIG_DVB_SI21XX is not set -# CONFIG_DVB_SP2 is not set -# CONFIG_DVB_SP8870 is not set -# CONFIG_DVB_SP887X is not set -# CONFIG_DVB_STB0899 is not set -# CONFIG_DVB_STB6000 is not set -# CONFIG_DVB_STB6100 is not set -# CONFIG_DVB_STV0288 is not set -# CONFIG_DVB_STV0297 is not set -# CONFIG_DVB_STV0299 is not set -# CONFIG_DVB_STV0367 is not set -# CONFIG_DVB_STV0900 is not set -# CONFIG_DVB_STV090x is not set -# CONFIG_DVB_STV0910 is not set -# CONFIG_DVB_STV6110 is not set -# CONFIG_DVB_STV6110x is not set -# CONFIG_DVB_STV6111 is not set -# CONFIG_DVB_TC90522 is not set -# CONFIG_DVB_TDA10021 is not set -# CONFIG_DVB_TDA10023 is not set -# CONFIG_DVB_TDA10048 is not set -# CONFIG_DVB_TDA1004X is not set -# CONFIG_DVB_TDA10071 is not set -# CONFIG_DVB_TDA10086 is not set -# CONFIG_DVB_TDA18271C2DD is not set -# CONFIG_DVB_TDA665x is not set -# CONFIG_DVB_TDA8083 is not set -# CONFIG_DVB_TDA8261 is not set -# CONFIG_DVB_TDA826X is not set -# CONFIG_DVB_TEST_DRIVERS is not set -# CONFIG_DVB_TS2020 is not set -# CONFIG_DVB_TTUSB_BUDGET is not set -# CONFIG_DVB_TTUSB_DEC is not set -# CONFIG_DVB_TUA6100 is not set -# CONFIG_DVB_TUNER_CX24113 is not set -# CONFIG_DVB_TUNER_DIB0070 is not set -# CONFIG_DVB_TUNER_DIB0090 is not set -# CONFIG_DVB_TUNER_ITD1000 is not set -# CONFIG_DVB_ULE_DEBUG is not set -# CONFIG_DVB_USB is not set -# CONFIG_DVB_USB_V2 is not set -# CONFIG_DVB_VES1820 is not set -# CONFIG_DVB_VES1X93 is not set -# CONFIG_DVB_ZD1301_DEMOD is not set -# CONFIG_DVB_ZL10036 is not set -# CONFIG_DVB_ZL10039 is not set -# CONFIG_DVB_ZL10353 is not set -# CONFIG_DWC_XLGMAC is not set -# CONFIG_DWMAC_DWC_QOS_ETH is not set -# CONFIG_DWMAC_INTEL_PLAT is not set -# CONFIG_DWMAC_IPQ806X is not set -# CONFIG_DWMAC_LOONGSON is not set -# CONFIG_DWMAC_LPC18XX is not set -# CONFIG_DWMAC_MESON is not set -# CONFIG_DWMAC_ROCKCHIP is not set -# CONFIG_DWMAC_SOCFPGA is not set -# CONFIG_DWMAC_STI is not set -# CONFIG_DW_AXI_DMAC is not set -# CONFIG_DW_DMAC is not set -# CONFIG_DW_DMAC_PCI is not set -# CONFIG_DW_EDMA is not set -# CONFIG_DW_EDMA_PCIE is not set -# CONFIG_DW_WATCHDOG is not set -# CONFIG_DW_XDATA_PCIE is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_DYNAMIC_DEBUG_CORE is not set -# CONFIG_E100 is not set -# CONFIG_E1000 is not set -# CONFIG_E1000E is not set -# CONFIG_E1000E_HWTS is not set -# CONFIG_EARLY_PRINTK_8250 is not set -# CONFIG_EARLY_PRINTK_USB_XDBC is not set -# CONFIG_EBC_C384_WDT is not set -# CONFIG_ECHO is not set -# CONFIG_ECRYPT_FS is not set -# CONFIG_EDAC is not set -# CONFIG_EEEPC_LAPTOP is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_EEPROM_93XX46 is not set -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_AT25 is not set -# CONFIG_EEPROM_DIGSY_MTC_CFG is not set -# CONFIG_EEPROM_EE1004 is not set -# CONFIG_EEPROM_IDT_89HPESX is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -# CONFIG_EFI is not set -CONFIG_EFI_PARTITION=y -# CONFIG_EFI_VARS_PSTORE is not set -# CONFIG_EFS_FS is not set -CONFIG_ELFCORE=y -# CONFIG_ELF_CORE is not set -# CONFIG_EMAC_ROCKCHIP is not set -CONFIG_EMBEDDED=y -# CONFIG_EM_TIMER_STI is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -# CONFIG_ENA_ETHERNET is not set -# CONFIG_ENC28J60 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -# CONFIG_ENCRYPTED_KEYS is not set -# CONFIG_ENCX24J600 is not set -# CONFIG_ENERGY_MODEL is not set -# CONFIG_ENIC is not set -# CONFIG_ENVELOPE_DETECTOR is not set -# CONFIG_EPAPR_PARAVIRT is not set -# CONFIG_EPIC100 is not set -CONFIG_EPOLL=y -# CONFIG_EQUALIZER is not set -# CONFIG_EROFS_FS is not set -# CONFIG_ET131X is not set -CONFIG_ETHERNET=y -# CONFIG_ETHOC is not set -CONFIG_ETHTOOL_NETLINK=y -CONFIG_EVENTFD=y -# CONFIG_EVM is not set -# CONFIG_EXFAT_FS is not set -CONFIG_EXPERT=y -CONFIG_EXPORTFS=y -# CONFIG_EXPORTFS_BLOCK_OPS is not set -# CONFIG_EXT2_FS is not set -CONFIG_EXT2_FS_XATTR=y -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4_DEBUG is not set -# CONFIG_EXT4_ENCRYPTION is not set -# CONFIG_EXT4_FS is not set -# CONFIG_EXT4_FS_POSIX_ACL is not set -# CONFIG_EXT4_FS_SECURITY is not set -CONFIG_EXT4_USE_FOR_EXT2=y -# CONFIG_EXTCON is not set -# CONFIG_EXTCON_ADC_JACK is not set -# CONFIG_EXTCON_ARIZONA is not set -# CONFIG_EXTCON_AXP288 is not set -# CONFIG_EXTCON_FSA9480 is not set -# CONFIG_EXTCON_GPIO is not set -# CONFIG_EXTCON_INTEL_INT3496 is not set -# CONFIG_EXTCON_MAX3355 is not set -# CONFIG_EXTCON_PTN5150 is not set -# CONFIG_EXTCON_QCOM_SPMI_MISC is not set -# CONFIG_EXTCON_RT8973A is not set -# CONFIG_EXTCON_SM5502 is not set -# CONFIG_EXTCON_USBC_TUSB320 is not set -# CONFIG_EXTCON_USB_GPIO is not set -CONFIG_EXTRA_FIRMWARE="" -CONFIG_EXTRA_TARGETS="" -# CONFIG_EXYNOS_ADC is not set -# CONFIG_EXYNOS_VIDEO is not set -# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set -# CONFIG_EZX_PCAP is not set -# CONFIG_F2FS_CHECK_FS is not set -# CONFIG_F2FS_FAULT_INJECTION is not set -# CONFIG_F2FS_FS is not set -# CONFIG_F2FS_FS_COMPRESSION is not set -# CONFIG_F2FS_FS_ENCRYPTION is not set -# CONFIG_F2FS_FS_POSIX_ACL is not set -# CONFIG_F2FS_FS_SECURITY is not set -CONFIG_F2FS_FS_XATTR=y -# CONFIG_F2FS_IOSTAT is not set -# CONFIG_F2FS_IO_TRACE is not set -CONFIG_F2FS_STAT_FS=y -# CONFIG_F2FS_UNFAIR_RWSEM is not set -# CONFIG_FAILOVER is not set -# CONFIG_FAIR_GROUP_SCHED is not set -# CONFIG_FANOTIFY is not set -# CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_FAT_DEFAULT_UTF8 is not set -# CONFIG_FAT_FS is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_FB is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_ARC is not set -# CONFIG_FB_ARK is not set -# CONFIG_FB_ARMCLCD is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_ATMEL is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_AUO_K190X is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_BIG_ENDIAN is not set -# CONFIG_FB_BOOT_VESA_SUPPORT is not set -# CONFIG_FB_BOTH_ENDIAN is not set -# CONFIG_FB_BROADSHEET is not set -# CONFIG_FB_CARMINE is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_DA8XX is not set -# CONFIG_FB_DDC is not set -# CONFIG_FB_FLEX is not set -# CONFIG_FB_FOREIGN_ENDIAN is not set -# CONFIG_FB_FSL_DIU is not set -# CONFIG_FB_GEODE is not set -# CONFIG_FB_GOLDFISH is not set -# CONFIG_FB_HGA is not set -# CONFIG_FB_I740 is not set -# CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_IMX is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_LE80578 is not set -# CONFIG_FB_LITTLE_ENDIAN is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_MXS is not set -# CONFIG_FB_N411 is not set -# CONFIG_FB_NEOMAGIC is not set -CONFIG_FB_NOTIFY=y -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_OF is not set -# CONFIG_FB_OMAP2 is not set -# CONFIG_FB_OPENCORES is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_PM3 is not set -# CONFIG_FB_PS3 is not set -# CONFIG_FB_PXA is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_RPISENSE is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIMPLE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_SM712 is not set -# CONFIG_FB_SM750 is not set -# CONFIG_FB_SMSCUFX is not set -# CONFIG_FB_SSD1307 is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_SYS_COPYAREA is not set -# CONFIG_FB_SYS_FILLRECT is not set -# CONFIG_FB_SYS_FOPS is not set -# CONFIG_FB_SYS_IMAGEBLIT is not set -# CONFIG_FB_TFT is not set -# CONFIG_FB_TFT_AGM1264K_FL is not set -# CONFIG_FB_TFT_BD663474 is not set -# CONFIG_FB_TFT_FBTFT_DEVICE is not set -# CONFIG_FB_TFT_HX8340BN is not set -# CONFIG_FB_TFT_HX8347D is not set -# CONFIG_FB_TFT_HX8353D is not set -# CONFIG_FB_TFT_HX8357D is not set -# CONFIG_FB_TFT_ILI9163 is not set -# CONFIG_FB_TFT_ILI9320 is not set -# CONFIG_FB_TFT_ILI9325 is not set -# CONFIG_FB_TFT_ILI9340 is not set -# CONFIG_FB_TFT_ILI9341 is not set -# CONFIG_FB_TFT_ILI9481 is not set -# CONFIG_FB_TFT_ILI9486 is not set -# CONFIG_FB_TFT_PCD8544 is not set -# CONFIG_FB_TFT_RA8875 is not set -# CONFIG_FB_TFT_S6D02A1 is not set -# CONFIG_FB_TFT_S6D1121 is not set -# CONFIG_FB_TFT_SEPS525 is not set -# CONFIG_FB_TFT_SH1106 is not set -# CONFIG_FB_TFT_SSD1289 is not set -# CONFIG_FB_TFT_SSD1305 is not set -# CONFIG_FB_TFT_SSD1306 is not set -# CONFIG_FB_TFT_SSD1325 is not set -# CONFIG_FB_TFT_SSD1331 is not set -# CONFIG_FB_TFT_SSD1351 is not set -# CONFIG_FB_TFT_ST7735R is not set -# CONFIG_FB_TFT_ST7789V is not set -# CONFIG_FB_TFT_TINYLCD is not set -# CONFIG_FB_TFT_TLS8204 is not set -# CONFIG_FB_TFT_UC1611 is not set -# CONFIG_FB_TFT_UC1701 is not set -# CONFIG_FB_TFT_UPD161704 is not set -# CONFIG_FB_TFT_WATTEROTT is not set -# CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_TMIO is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_UDL is not set -# CONFIG_FB_UVESA is not set -# CONFIG_FB_VGA16 is not set -# CONFIG_FB_VIA is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_VT8623 is not set -# CONFIG_FB_XGI is not set -# CONFIG_FCOE is not set -# CONFIG_FCOE_FNIC is not set -# CONFIG_FDDI is not set -# CONFIG_FEALNX is not set -# CONFIG_FENCE_TRACE is not set -# CONFIG_FHANDLE is not set -CONFIG_FIB_RULES=y -# CONFIG_FIELDBUS_DEV is not set -CONFIG_FILE_LOCKING=y -# CONFIG_FIND_BIT_BENCHMARK is not set -# CONFIG_FIREWIRE is not set -# CONFIG_FIREWIRE_NOSY is not set -# CONFIG_FIREWIRE_SERIAL is not set -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FIRMWARE_IN_KERNEL is not set -# CONFIG_FIRMWARE_MEMMAP is not set -# CONFIG_FIXED_PHY is not set -CONFIG_FLATMEM=y -CONFIG_FLATMEM_MANUAL=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_FM10K is not set -# CONFIG_FMC is not set -# CONFIG_FONTS is not set -# CONFIG_FONT_6x8 is not set -# CONFIG_FONT_TER16x32 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_FORCE_NR_CPUS is not set -CONFIG_FORTIFY_SOURCE=y -# CONFIG_FPGA is not set -# CONFIG_FPROBE is not set -# CONFIG_FRAMEBUFFER_CONSOLE is not set -# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set -# CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION is not set -# CONFIG_FRAME_POINTER is not set -# CONFIG_FREEZER is not set -# CONFIG_FRONTSWAP is not set -# CONFIG_FSCACHE is not set -# CONFIG_FSI is not set -# CONFIG_FSL_DPAA2_SWITCH is not set -# CONFIG_FSL_EDMA is not set -# CONFIG_FSL_ENETC is not set -# CONFIG_FSL_ENETC_IERB is not set -# CONFIG_FSL_ENETC_MDIO is not set -# CONFIG_FSL_ENETC_VF is not set -# CONFIG_FSL_ERRATUM_A008585 is not set -# CONFIG_FSL_MC_BUS is not set -# CONFIG_FSL_PQ_MDIO is not set -# CONFIG_FSL_QDMA is not set -# CONFIG_FSL_RCPM is not set -# CONFIG_FSL_XGMAC_MDIO is not set -CONFIG_FSNOTIFY=y -# CONFIG_FS_DAX is not set -# CONFIG_FS_ENCRYPTION is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_FS_VERITY is not set -# CONFIG_FTGMAC100 is not set -# CONFIG_FTL is not set -# CONFIG_FTMAC100 is not set -# CONFIG_FTRACE is not set -# CONFIG_FTRACE_RECORD_RECURSION is not set -# CONFIG_FTRACE_SORT_STARTUP_TEST is not set -# CONFIG_FTRACE_STARTUP_TEST is not set -# CONFIG_FTR_FIXUP_SELFTEST is not set -# CONFIG_FTWDT010_WATCHDOG is not set -# CONFIG_FUJITSU_ERRATUM_010001 is not set -# CONFIG_FUJITSU_ES is not set -# CONFIG_FUJITSU_LAPTOP is not set -# CONFIG_FUJITSU_TABLET is not set -# CONFIG_FUNCTION_ERROR_INJECTION is not set -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_FUN_ETH is not set -# CONFIG_FUSE_FS is not set -# CONFIG_FUSION is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set -# CONFIG_FUSION_SPI is not set -CONFIG_FUTEX=y -CONFIG_FUTEX_PI=y -# CONFIG_FW_CFG_SYSFS is not set -CONFIG_FW_LOADER=y -# CONFIG_FW_LOADER_COMPRESS is not set -CONFIG_FW_LOADER_USER_HELPER=y -CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y -# CONFIG_FW_UPLOAD is not set -# CONFIG_FXAS21002C is not set -# CONFIG_FXLS8962AF_I2C is not set -# CONFIG_FXLS8962AF_SPI is not set -# CONFIG_FXOS8700_I2C is not set -# CONFIG_FXOS8700_SPI is not set -CONFIG_GACT_PROB=y -# CONFIG_GADGET_UAC1 is not set -# CONFIG_GAMEPORT is not set -# CONFIG_GATEWORKS_GW16083 is not set -# CONFIG_GCC_PLUGINS is not set -# CONFIG_GCOV is not set -# CONFIG_GCOV_KERNEL is not set -# CONFIG_GDB_SCRIPTS is not set -# CONFIG_GEMINI_ETHERNET is not set -# CONFIG_GENERIC_ADC_BATTERY is not set -# CONFIG_GENERIC_ADC_THERMAL is not set -CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_CPU_DEVICES is not set -CONFIG_GENERIC_HWEIGHT=y -# CONFIG_GENERIC_IRQ_DEBUGFS is not set -CONFIG_GENERIC_IRQ_IPI=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_NET_UTILS=y -# CONFIG_GENERIC_PHY is not set -CONFIG_GENERIC_PTDUMP=y -CONFIG_GENERIC_VDSO_TIME_NS=y -# CONFIG_GENEVE is not set -# CONFIG_GENWQE is not set -# CONFIG_GFS2_FS is not set -# CONFIG_GIGASET_CAPI is not set -# CONFIG_GIGASET_DEBUG is not set -# CONFIG_GIGASET_DUMMYLL is not set -# CONFIG_GLOB_SELFTEST is not set -# CONFIG_GNSS is not set -# CONFIG_GOLDFISH is not set -# CONFIG_GOOGLE_FIRMWARE is not set -# CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT is not set -# CONFIG_GOOGLE_MEMCONSOLE_X86_LEGACY is not set -# CONFIG_GOOGLE_SMI is not set -# CONFIG_GP2AP002 is not set -# CONFIG_GP2AP020A00F is not set -# CONFIG_GPD_POCKET_FAN is not set -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_FASTPATH_LIMIT=512 -# CONFIG_GPIO_104_DIO_48E is not set -# CONFIG_GPIO_104_IDIO_16 is not set -# CONFIG_GPIO_104_IDI_48 is not set -# CONFIG_GPIO_74X164 is not set -# CONFIG_GPIO_74XX_MMIO is not set -# CONFIG_GPIO_ADNP is not set -# CONFIG_GPIO_ADP5588 is not set -# CONFIG_GPIO_AGGREGATOR is not set -# CONFIG_GPIO_ALTERA is not set -# CONFIG_GPIO_AMD8111 is not set -# CONFIG_GPIO_AMDPT is not set -# CONFIG_GPIO_AMD_FCH is not set -# CONFIG_GPIO_BCM_KONA is not set -# CONFIG_GPIO_BRCMSTB is not set -# CONFIG_GPIO_BT8XX is not set -# CONFIG_GPIO_CADENCE is not set -# CONFIG_GPIO_CASCADE is not set -# CONFIG_GPIO_CDEV is not set -# CONFIG_GPIO_CDEV_V1 is not set -# CONFIG_GPIO_CS5535 is not set -# CONFIG_GPIO_DWAPB is not set -# CONFIG_GPIO_EM is not set -# CONFIG_GPIO_EXAR is not set -# CONFIG_GPIO_F7188X is not set -# CONFIG_GPIO_FTGPIO010 is not set -# CONFIG_GPIO_GENERIC_PLATFORM is not set -# CONFIG_GPIO_GPIO_MM is not set -# CONFIG_GPIO_GRGPIO is not set -# CONFIG_GPIO_GW_PLD is not set -# CONFIG_GPIO_HLWD is not set -# CONFIG_GPIO_ICH is not set -# CONFIG_GPIO_IT87 is not set -# CONFIG_GPIO_LOGICVC is not set -# CONFIG_GPIO_LYNXPOINT is not set -# CONFIG_GPIO_MAX3191X is not set -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_MB86S7X is not set -# CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_ML_IOH is not set -# CONFIG_GPIO_MOCKUP is not set -# CONFIG_GPIO_MPC8XXX is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCA953X_IRQ is not set -# CONFIG_GPIO_PCA9570 is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_PCH is not set -# CONFIG_GPIO_PCIE_IDIO_24 is not set -# CONFIG_GPIO_PCI_IDIO_16 is not set -# CONFIG_GPIO_PISOSR is not set -# CONFIG_GPIO_PL061 is not set -# CONFIG_GPIO_PWM is not set -# CONFIG_GPIO_RCAR is not set -# CONFIG_GPIO_RDC321X is not set -# CONFIG_GPIO_SAMA5D2_PIOBU is not set -# CONFIG_GPIO_SCH is not set -# CONFIG_GPIO_SCH311X is not set -# CONFIG_GPIO_SIFIVE is not set -# CONFIG_GPIO_SIM is not set -# CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_SYSCON is not set -CONFIG_GPIO_SYSFS=y -# CONFIG_GPIO_TPIC2810 is not set -# CONFIG_GPIO_TS4900 is not set -# CONFIG_GPIO_TS5500 is not set -# CONFIG_GPIO_VF610 is not set -# CONFIG_GPIO_VIRTIO is not set -# CONFIG_GPIO_VX855 is not set -# CONFIG_GPIO_WATCHDOG is not set -# CONFIG_GPIO_WINBOND is not set -# CONFIG_GPIO_WS16C48 is not set -# CONFIG_GPIO_XGENE is not set -# CONFIG_GPIO_XILINX is not set -# CONFIG_GPIO_XRA1403 is not set -# CONFIG_GPIO_ZEVIO is not set -# CONFIG_GPIO_ZX is not set -# CONFIG_GP_PCI1XXXX is not set -# CONFIG_GREENASIA_FF is not set -# CONFIG_GREYBUS is not set -# CONFIG_GS_FPGABOOT is not set -# CONFIG_GTP is not set -# CONFIG_GUP_BENCHMARK is not set -# CONFIG_GUP_TEST is not set -# CONFIG_GVE is not set -# CONFIG_HABANA_AI is not set -# CONFIG_HAMACHI is not set -# CONFIG_HAMRADIO is not set -# CONFIG_HAPPYMEAL is not set -CONFIG_HARDENED_USERCOPY=y -# CONFIG_HARDENED_USERCOPY_FALLBACK is not set -# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set -CONFIG_HARDEN_BRANCH_HISTORY=y -CONFIG_HARDEN_EL2_VECTORS=y -# CONFIG_HARDLOCKUP_DETECTOR is not set -# CONFIG_HAVE_ARM_ARCH_TIMER is not set -# CONFIG_HCALL_STATS is not set -# CONFIG_HDC100X is not set -# CONFIG_HDC2010 is not set -# CONFIG_HDLC is not set -# CONFIG_HDLC_CISCO is not set -# CONFIG_HDLC_FR is not set -# CONFIG_HDLC_PPP is not set -# CONFIG_HDLC_RAW is not set -# CONFIG_HDLC_RAW_ETH is not set -# CONFIG_HDMI_LPE_AUDIO is not set -# CONFIG_HDQ_MASTER_OMAP is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_HEADERS_INSTALL is not set -# CONFIG_HEADER_TEST is not set -# CONFIG_HERMES is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_HFSPLUS_FS_POSIX_ACL is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFS_FS_POSIX_ACL is not set -# CONFIG_HI6421V600_IRQ is not set -# CONFIG_HI8435 is not set -# CONFIG_HIBERNATION is not set -# CONFIG_HID is not set -# CONFIG_HIDRAW is not set -# CONFIG_HID_A4TECH is not set -# CONFIG_HID_ACCUTOUCH is not set -# CONFIG_HID_ACRUX is not set -# CONFIG_HID_ACRUX_FF is not set -# CONFIG_HID_ALPS is not set -# CONFIG_HID_APPLE is not set -# CONFIG_HID_APPLEIR is not set -# CONFIG_HID_ASUS is not set -# CONFIG_HID_AUREAL is not set -# CONFIG_HID_BATTERY_STRENGTH is not set -# CONFIG_HID_BELKIN is not set -# CONFIG_HID_BETOP_FF is not set -# CONFIG_HID_BIGBEN_FF is not set -# CONFIG_HID_CHERRY is not set -# CONFIG_HID_CHICONY is not set -# CONFIG_HID_CMEDIA is not set -# CONFIG_HID_CORSAIR is not set -# CONFIG_HID_COUGAR is not set -# CONFIG_HID_CP2112 is not set -# CONFIG_HID_CREATIVE_SB0540 is not set -# CONFIG_HID_CYPRESS is not set -# CONFIG_HID_DRAGONRISE is not set -# CONFIG_HID_ELAN is not set -# CONFIG_HID_ELECOM is not set -# CONFIG_HID_ELO is not set -# CONFIG_HID_EMS_FF is not set -# CONFIG_HID_EZKEY is not set -# CONFIG_HID_FT260 is not set -# CONFIG_HID_GEMBIRD is not set -# CONFIG_HID_GENERIC is not set -# CONFIG_HID_GFRM is not set -# CONFIG_HID_GLORIOUS is not set -# CONFIG_HID_GOOGLE_HAMMER is not set -# CONFIG_HID_GREENASIA is not set -# CONFIG_HID_GT683R is not set -# CONFIG_HID_GYRATION is not set -# CONFIG_HID_HOLTEK is not set -# CONFIG_HID_ICADE is not set -# CONFIG_HID_ITE is not set -# CONFIG_HID_JABRA is not set -# CONFIG_HID_KENSINGTON is not set -# CONFIG_HID_KEYTOUCH is not set -# CONFIG_HID_KYE is not set -# CONFIG_HID_LCPOWER is not set -# CONFIG_HID_LED is not set -# CONFIG_HID_LENOVO is not set -# CONFIG_HID_LETSKETCH is not set -# CONFIG_HID_LOGITECH is not set -# CONFIG_HID_LOGITECH_DJ is not set -# CONFIG_HID_LOGITECH_HIDPP is not set -# CONFIG_HID_MACALLY is not set -# CONFIG_HID_MAGICMOUSE is not set -# CONFIG_HID_MALTRON is not set -# CONFIG_HID_MAYFLASH is not set -# CONFIG_HID_MCP2221 is not set -# CONFIG_HID_MEGAWORLD_FF is not set -# CONFIG_HID_MICROSOFT is not set -# CONFIG_HID_MONTEREY is not set -# CONFIG_HID_MULTITOUCH is not set -# CONFIG_HID_NINTENDO is not set -# CONFIG_HID_NTI is not set -# CONFIG_HID_NTRIG is not set -# CONFIG_HID_ORTEK is not set -# CONFIG_HID_PANTHERLORD is not set -# CONFIG_HID_PENMOUNT is not set -# CONFIG_HID_PETALYNX is not set -# CONFIG_HID_PICOLCD is not set -# CONFIG_HID_PID is not set -# CONFIG_HID_PLANTRONICS is not set -# CONFIG_HID_PLAYSTATION is not set -# CONFIG_HID_PRIMAX is not set -# CONFIG_HID_PRODIKEYS is not set -# CONFIG_HID_PXRC is not set -# CONFIG_HID_RAZER is not set -# CONFIG_HID_REDRAGON is not set -# CONFIG_HID_RETRODE is not set -# CONFIG_HID_RMI is not set -# CONFIG_HID_ROCCAT is not set -# CONFIG_HID_SAITEK is not set -# CONFIG_HID_SAMSUNG is not set -# CONFIG_HID_SEMITEK is not set -# CONFIG_HID_SENSOR_HUB is not set -# CONFIG_HID_SIGMAMICRO is not set -# CONFIG_HID_SMARTJOYPLUS is not set -# CONFIG_HID_SONY is not set -# CONFIG_HID_SPEEDLINK is not set -# CONFIG_HID_STEAM is not set -# CONFIG_HID_STEELSERIES is not set -# CONFIG_HID_SUNPLUS is not set -# CONFIG_HID_THINGM is not set -# CONFIG_HID_THRUSTMASTER is not set -# CONFIG_HID_TIVO is not set -# CONFIG_HID_TOPRE is not set -# CONFIG_HID_TOPSEED is not set -# CONFIG_HID_TWINHAN is not set -# CONFIG_HID_U2FZERO is not set -# CONFIG_HID_UCLOGIC is not set -# CONFIG_HID_UDRAW_PS3 is not set -# CONFIG_HID_VIEWSONIC is not set -# CONFIG_HID_VIVALDI is not set -# CONFIG_HID_VRC2 is not set -# CONFIG_HID_WACOM is not set -# CONFIG_HID_WALTOP is not set -# CONFIG_HID_WIIMOTE is not set -# CONFIG_HID_XIAOMI is not set -# CONFIG_HID_XINMO is not set -# CONFIG_HID_ZEROPLUS is not set -# CONFIG_HID_ZYDACRON is not set -# CONFIG_HIGHMEM is not set -CONFIG_HIGH_RES_TIMERS=y -# CONFIG_HINIC is not set -# CONFIG_HIP04_ETH is not set -# CONFIG_HIPPI is not set -# CONFIG_HISILICON_ERRATUM_161010101 is not set -# CONFIG_HISILICON_ERRATUM_161600802 is not set -# CONFIG_HISI_DMA is not set -# CONFIG_HISI_FEMAC is not set -# CONFIG_HISI_HIKEY_USB is not set -# CONFIG_HISI_PCIE_PMU is not set -# CONFIG_HISI_PTT is not set -# CONFIG_HIST_TRIGGERS_DEBUG is not set -# CONFIG_HIX5HD2_GMAC is not set -# CONFIG_HMC425 is not set -# CONFIG_HMC6352 is not set -# CONFIG_HNS is not set -# CONFIG_HNS3 is not set -# CONFIG_HNS3_PMU is not set -# CONFIG_HNS_DSAF is not set -# CONFIG_HNS_ENET is not set -# CONFIG_HOSTAP is not set -# CONFIG_HOSTAP_CS is not set -# CONFIG_HOSTAP_PCI is not set -# CONFIG_HOSTAP_PLX is not set -# CONFIG_HOTPLUG_CPU is not set -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HP03 is not set -# CONFIG_HP100 is not set -# CONFIG_HP206C is not set -CONFIG_HPET_MMAP_DEFAULT=y -# CONFIG_HPFS_FS is not set -# CONFIG_HP_ILO is not set -# CONFIG_HP_WATCHDOG is not set -# CONFIG_HP_WIRELESS is not set -# CONFIG_HSA_AMD is not set -# CONFIG_HSI is not set -# CONFIG_HSR is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_I2CPLD is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTE is not set -# CONFIG_HTS221 is not set -# CONFIG_HTU21 is not set -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_HVC_DCC is not set -# CONFIG_HVC_UDBG is not set -# CONFIG_HWLAT_TRACER is not set -# CONFIG_HWMON is not set -# CONFIG_HWMON_DEBUG_CHIP is not set -# CONFIG_HWMON_VID is not set -# CONFIG_HWSPINLOCK is not set -# CONFIG_HWSPINLOCK_OMAP is not set -CONFIG_HW_PERF_EVENTS=y -# CONFIG_HW_RANDOM is not set -# CONFIG_HW_RANDOM_AMD is not set -# CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set -# CONFIG_HW_RANDOM_ATMEL is not set -# CONFIG_HW_RANDOM_BA431 is not set -# CONFIG_HW_RANDOM_BCM2835 is not set -# CONFIG_HW_RANDOM_CAVIUM is not set -# CONFIG_HW_RANDOM_CCTRNG is not set -# CONFIG_HW_RANDOM_CN10K is not set -# CONFIG_HW_RANDOM_EXYNOS is not set -# CONFIG_HW_RANDOM_GEODE is not set -# CONFIG_HW_RANDOM_INTEL is not set -# CONFIG_HW_RANDOM_IPROC_RNG200 is not set -# CONFIG_HW_RANDOM_MTK is not set -# CONFIG_HW_RANDOM_OMAP is not set -# CONFIG_HW_RANDOM_OMAP3_ROM is not set -# CONFIG_HW_RANDOM_PPC4XX is not set -# CONFIG_HW_RANDOM_TIMERIOMEM is not set -CONFIG_HW_RANDOM_TPM=y -# CONFIG_HW_RANDOM_VIA is not set -# CONFIG_HW_RANDOM_VIRTIO is not set -# CONFIG_HW_RANDOM_XIPHERA is not set -# CONFIG_HX711 is not set -# CONFIG_HYPERV is not set -# CONFIG_HYPERV_TSCPAGE is not set -# CONFIG_HYSDN is not set -CONFIG_HZ=100 -CONFIG_HZ_100=y -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -# CONFIG_HZ_128 is not set -# CONFIG_HZ_200 is not set -# CONFIG_HZ_24 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -# CONFIG_HZ_300 is not set -# CONFIG_HZ_48 is not set -# CONFIG_HZ_500 is not set -# CONFIG_HZ_PERIODIC is not set -# CONFIG_I2C is not set -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCA is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set -# CONFIG_I2C_AU1550 is not set -# CONFIG_I2C_BCM2835 is not set -# CONFIG_I2C_BCM_IPROC is not set -# CONFIG_I2C_BRCMSTB is not set -# CONFIG_I2C_CADENCE is not set -# CONFIG_I2C_CBUS_GPIO is not set -# CONFIG_I2C_CHARDEV is not set -# CONFIG_I2C_COMPAT is not set -# CONFIG_I2C_CP2615 is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEMUX_PINCTRL is not set -# CONFIG_I2C_DESIGNWARE_PCI is not set -# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -# CONFIG_I2C_DESIGNWARE_SLAVE is not set -# CONFIG_I2C_DIOLAN_U2C is not set -# CONFIG_I2C_EG20T is not set -# CONFIG_I2C_ELEKTOR is not set -# CONFIG_I2C_EMEV2 is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set -# CONFIG_I2C_HELPER_AUTO is not set -# CONFIG_I2C_HID is not set -# CONFIG_I2C_HID_OF is not set -# CONFIG_I2C_HID_OF_ELAN is not set -# CONFIG_I2C_HID_OF_GOODIX is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_IBM_IIC is not set -# CONFIG_I2C_IMG is not set -# CONFIG_I2C_ISCH is not set -# CONFIG_I2C_ISMT is not set -# CONFIG_I2C_JZ4780 is not set -# CONFIG_I2C_MLXCPLD is not set -# CONFIG_I2C_MPC is not set -# CONFIG_I2C_MT65XX is not set -# CONFIG_I2C_MUX is not set -# CONFIG_I2C_MUX_GPIO is not set -# CONFIG_I2C_MUX_GPMUX is not set -# CONFIG_I2C_MUX_LTC4306 is not set -# CONFIG_I2C_MUX_MLXCPLD is not set -# CONFIG_I2C_MUX_PCA9541 is not set -# CONFIG_I2C_MUX_PCA954x is not set -# CONFIG_I2C_MUX_PINCTRL is not set -# CONFIG_I2C_MUX_REG is not set -# CONFIG_I2C_MV64XXX is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_NOMADIK is not set -# CONFIG_I2C_NVIDIA_GPU is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_OCTEON is not set -# CONFIG_I2C_PARPORT is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PCA_ISA is not set -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_PCI1XXXX is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_PXA_PCI is not set -# CONFIG_I2C_PXA_SLAVE is not set -# CONFIG_I2C_RCAR is not set -# CONFIG_I2C_RK3X is not set -# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -# CONFIG_I2C_S3C2410 is not set -# CONFIG_I2C_SCMI is not set -# CONFIG_I2C_SH_MOBILE is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_SLAVE is not set -# CONFIG_I2C_SLAVE_EEPROM is not set -# CONFIG_I2C_SMBUS is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_THUNDERX is not set -# CONFIG_I2C_TINY_USB is not set -# CONFIG_I2C_VERSATILE is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VIRTIO is not set -# CONFIG_I2C_XILINX is not set -# CONFIG_I3C is not set -# CONFIG_I40E is not set -# CONFIG_I40EVF is not set -# CONFIG_I6300ESB_WDT is not set -# CONFIG_I82092 is not set -# CONFIG_I82365 is not set -# CONFIG_IAQCORE is not set -# CONFIG_IBM_ASM is not set -# CONFIG_IBM_EMAC_DEBUG is not set -# CONFIG_IBM_EMAC_EMAC4 is not set -# CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_EMAC_MAL_COMMON_ERR is not set -# CONFIG_IBM_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_EMAC_RGMII is not set -# CONFIG_IBM_EMAC_TAH is not set -# CONFIG_IBM_EMAC_ZMII is not set -# CONFIG_ICE is not set -# CONFIG_ICP10100 is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_ICS932S401 is not set -# CONFIG_ICST is not set -# CONFIG_IDE is not set -# CONFIG_IDEAPAD_LAPTOP is not set -# CONFIG_IDE_GD is not set -# CONFIG_IDE_PROC_FS is not set -# CONFIG_IDE_TASK_IOCTL is not set -# CONFIG_IDLE_PAGE_TRACKING is not set -# CONFIG_IEEE802154 is not set -# CONFIG_IEEE802154_ADF7242 is not set -# CONFIG_IEEE802154_ATUSB is not set -# CONFIG_IEEE802154_CA8210 is not set -# CONFIG_IEEE802154_HWSIM is not set -# CONFIG_IEEE802154_MCR20A is not set -# CONFIG_IFB is not set -# CONFIG_IGB is not set -# CONFIG_IGBVF is not set -# CONFIG_IGC is not set -# CONFIG_IIO is not set -# CONFIG_IIO_BUFFER is not set -# CONFIG_IIO_BUFFER_CB is not set -# CONFIG_IIO_BUFFER_DMA is not set -# CONFIG_IIO_BUFFER_DMAENGINE is not set -# CONFIG_IIO_BUFFER_HDC2010 is not set -# CONFIG_IIO_BUFFER_HW_CONSUMER is not set -# CONFIG_IIO_CONFIGFS is not set -CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 -# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set -# CONFIG_IIO_INTERRUPT_TRIGGER is not set -# CONFIG_IIO_MUX is not set -# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set -# CONFIG_IIO_RESCALE is not set -# CONFIG_IIO_SIMPLE_DUMMY is not set -# CONFIG_IIO_SSP_SENSORHUB is not set -# CONFIG_IIO_ST_ACCEL_3AXIS is not set -# CONFIG_IIO_ST_GYRO_3AXIS is not set -# CONFIG_IIO_ST_LSM6DSX is not set -# CONFIG_IIO_ST_LSM9DS0 is not set -# CONFIG_IIO_ST_MAGN_3AXIS is not set -# CONFIG_IIO_ST_PRESS is not set -# CONFIG_IIO_SW_DEVICE is not set -# CONFIG_IIO_SW_TRIGGER is not set -# CONFIG_IIO_SYSFS_TRIGGER is not set -# CONFIG_IIO_TRIGGER is not set -# CONFIG_IIO_TRIGGERED_EVENT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_IKCONFIG_PROC is not set -# CONFIG_IKHEADERS is not set -# CONFIG_IMA is not set -# CONFIG_IMAGE_CMDLINE_HACK is not set -# CONFIG_IMGPDC_WDT is not set -# CONFIG_IMG_MDC_DMA is not set -# CONFIG_IMX7D_ADC is not set -# CONFIG_IMX8QXP_ADC is not set -# CONFIG_IMX_IPUV3_CORE is not set -# CONFIG_IMX_THERMAL is not set -# CONFIG_INA2XX_ADC is not set -# CONFIG_INDIRECT_PIO is not set -CONFIG_INET=y -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_ESPINTCP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_DIAG is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_ESPINTCP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_LRO is not set -CONFIG_INET_TABLE_PERTURB_ORDER=16 -# CONFIG_INET_TCP_DIAG is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_UDP_DIAG is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INFINIBAND is not set -# CONFIG_INFTL is not set -# CONFIG_INGENIC_ADC is not set -# CONFIG_INGENIC_CGU_JZ4725B is not set -# CONFIG_INGENIC_CGU_JZ4740 is not set -# CONFIG_INGENIC_CGU_JZ4760 is not set -# CONFIG_INGENIC_CGU_JZ4770 is not set -# CONFIG_INGENIC_CGU_JZ4780 is not set -# CONFIG_INGENIC_CGU_X1000 is not set -# CONFIG_INGENIC_CGU_X1830 is not set -# CONFIG_INGENIC_OST is not set -# CONFIG_INGENIC_SYSOST is not set -# CONFIG_INGENIC_TCU_CLK is not set -# CONFIG_INGENIC_TCU_IRQ is not set -# CONFIG_INGENIC_TIMER is not set -# CONFIG_INITRAMFS_PRESERVE_MTIME is not set -CONFIG_INIT_ENV_ARG_LIMIT=32 -# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set -# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set -# CONFIG_INIT_STACK_ALL_PATTERN is not set -# CONFIG_INIT_STACK_ALL_ZERO is not set -CONFIG_INIT_STACK_NONE=y -CONFIG_INOTIFY_USER=y -# CONFIG_INPUT is not set -# CONFIG_INPUT_AD714X is not set -# CONFIG_INPUT_ADXL34X is not set -# CONFIG_INPUT_APANEL is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_ATLAS_BTNS is not set -# CONFIG_INPUT_ATMEL_CAPTOUCH is not set -# CONFIG_INPUT_AXP20X_PEK is not set -# CONFIG_INPUT_BMA150 is not set -# CONFIG_INPUT_CM109 is not set -# CONFIG_INPUT_CMA3000 is not set -# CONFIG_INPUT_DA7280_HAPTICS is not set -# CONFIG_INPUT_DRV260X_HAPTICS is not set -# CONFIG_INPUT_DRV2665_HAPTICS is not set -# CONFIG_INPUT_DRV2667_HAPTICS is not set -# CONFIG_INPUT_E3X0_BUTTON is not set -# CONFIG_INPUT_EVBUG is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_GP2A is not set -# CONFIG_INPUT_GPIO_BEEPER is not set -# CONFIG_INPUT_GPIO_DECODER is not set -# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -# CONFIG_INPUT_GPIO_TILT_POLLED is not set -# CONFIG_INPUT_GPIO_VIBRA is not set -# CONFIG_INPUT_IBM_PANEL is not set -# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set -# CONFIG_INPUT_IMS_PCU is not set -# CONFIG_INPUT_IQS269A is not set -# CONFIG_INPUT_IQS626A is not set -# CONFIG_INPUT_IQS7222 is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_KXTJ9 is not set -# CONFIG_INPUT_LEDS is not set -# CONFIG_INPUT_MATRIXKMAP is not set -# CONFIG_INPUT_MAX8997_HAPTIC is not set -CONFIG_INPUT_MISC=y -# CONFIG_INPUT_MMA8450 is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_MPU3050 is not set -# CONFIG_INPUT_MSM_VIBRATOR is not set -# CONFIG_INPUT_PALMAS_PWRBUTTON is not set -# CONFIG_INPUT_PCF8574 is not set -# CONFIG_INPUT_PCSPKR is not set -# CONFIG_INPUT_PM8941_PWRKEY is not set -# CONFIG_INPUT_PM8XXX_VIBRATOR is not set -# CONFIG_INPUT_POLLDEV is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_PWM_BEEPER is not set -# CONFIG_INPUT_PWM_VIBRA is not set -# CONFIG_INPUT_RASPBERRYPI_BUTTON is not set -# CONFIG_INPUT_REGULATOR_HAPTIC is not set -# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set -# CONFIG_INPUT_SPARSEKMAP is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_TPS65218_PWRBUTTON is not set -# CONFIG_INPUT_TWL4030_PWRBUTTON is not set -# CONFIG_INPUT_TWL4030_VIBRA is not set -# CONFIG_INPUT_TWL6040_VIBRA is not set -# CONFIG_INPUT_UINPUT is not set -# CONFIG_INPUT_WISTRON_BTNS is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INT340X_THERMAL is not set -# CONFIG_INTEGRITY is not set -# CONFIG_INTEGRITY_AUDIT is not set -# CONFIG_INTEGRITY_SIGNATURE is not set -# CONFIG_INTEL_ATOMISP2_LED is not set -# CONFIG_INTEL_ATOMISP2_PM is not set -# CONFIG_INTEL_CHT_INT33FE is not set -# CONFIG_INTEL_HID_EVENT is not set -# CONFIG_INTEL_IDLE is not set -# CONFIG_INTEL_IDMA64 is not set -# CONFIG_INTEL_INT0002_VGPIO is not set -# CONFIG_INTEL_IOATDMA is not set -# CONFIG_INTEL_ISH_HID is not set -# CONFIG_INTEL_MEI is not set -# CONFIG_INTEL_MEI_ME is not set -# CONFIG_INTEL_MEI_TXE is not set -# CONFIG_INTEL_MIC_CARD is not set -# CONFIG_INTEL_MIC_HOST is not set -# CONFIG_INTEL_MID_PTI is not set -# CONFIG_INTEL_OAKTRAIL is not set -# CONFIG_INTEL_PMC_CORE is not set -# CONFIG_INTEL_PUNIT_IPC is not set -# CONFIG_INTEL_RST is not set -# CONFIG_INTEL_SMARTCONNECT is not set -# CONFIG_INTEL_SOC_PMIC is not set -# CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set -# CONFIG_INTEL_SOC_PMIC_CHTWC is not set -# CONFIG_INTEL_TH is not set -# CONFIG_INTEL_VBTN is not set -# CONFIG_INTEL_XWAY_PHY is not set -# CONFIG_INTERCONNECT is not set -# CONFIG_INTERVAL_TREE_TEST is not set -# CONFIG_INV_ICM42600_I2C is not set -# CONFIG_INV_ICM42600_SPI is not set -# CONFIG_INV_MPU6050_I2C is not set -# CONFIG_INV_MPU6050_IIO is not set -# CONFIG_INV_MPU6050_SPI is not set -# CONFIG_IOMMU_SUPPORT is not set -# CONFIG_IONIC is not set -# CONFIG_IOSCHED_BFQ is not set -# CONFIG_IOSM is not set -CONFIG_IO_STRICT_DEVMEM=y -# CONFIG_IO_URING is not set -CONFIG_IO_WQ=y -# CONFIG_IP17XX_PHY is not set -# CONFIG_IP5XXX_POWER is not set -# CONFIG_IP6_NF_FILTER is not set -# CONFIG_IP6_NF_IPTABLES is not set -# CONFIG_IP6_NF_MANGLE is not set -# CONFIG_IP6_NF_MATCH_AH is not set -# CONFIG_IP6_NF_MATCH_EUI64 is not set -# CONFIG_IP6_NF_MATCH_FRAG is not set -# CONFIG_IP6_NF_MATCH_HL is not set -# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -# CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_RPFILTER is not set -# CONFIG_IP6_NF_MATCH_RT is not set -# CONFIG_IP6_NF_MATCH_SRH is not set -# CONFIG_IP6_NF_NAT is not set -# CONFIG_IP6_NF_RAW is not set -# CONFIG_IP6_NF_SECURITY is not set -# CONFIG_IP6_NF_TARGET_HL is not set -# CONFIG_IP6_NF_TARGET_MASQUERADE is not set -# CONFIG_IP6_NF_TARGET_REJECT is not set -# CONFIG_IP6_NF_TARGET_SYNPROXY is not set -# CONFIG_IPACK_BUS is not set -# CONFIG_IPC_NS is not set -# CONFIG_IPMB_DEVICE_INTERFACE is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_IPV6 is not set -# CONFIG_IPV6_FOU is not set -# CONFIG_IPV6_FOU_TUNNEL is not set -# CONFIG_IPV6_ILA is not set -# CONFIG_IPV6_IOAM6_LWTUNNEL is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -CONFIG_IPV6_NDISC_NODETYPE=y -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_ROUTE_INFO is not set -# CONFIG_IPV6_RPL_LWTUNNEL is not set -# CONFIG_IPV6_SEG6_HMAC is not set -# CONFIG_IPV6_SEG6_LWTUNNEL is not set -# CONFIG_IPV6_SIT is not set -# CONFIG_IPV6_SIT_6RD is not set -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_VTI is not set -# CONFIG_IPVLAN is not set -# CONFIG_IPVTAP is not set -# CONFIG_IPW2100 is not set -# CONFIG_IPW2100_DEBUG is not set -CONFIG_IPW2100_MONITOR=y -# CONFIG_IPW2200 is not set -# CONFIG_IPW2200_DEBUG is not set -CONFIG_IPW2200_MONITOR=y -# CONFIG_IPW2200_PROMISCUOUS is not set -# CONFIG_IPW2200_QOS is not set -# CONFIG_IPW2200_RADIOTAP is not set -# CONFIG_IPWIRELESS is not set -# CONFIG_IPX is not set -CONFIG_IP_ADVANCED_ROUTER=y -# CONFIG_IP_DCCP is not set -# CONFIG_IP_FIB_TRIE_STATS is not set -# CONFIG_IP_MROUTE is not set -CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_MULTIPLE_TABLES=y -# CONFIG_IP_NF_ARPFILTER is not set -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_ARP_MANGLE is not set -# CONFIG_IP_NF_FILTER is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_MANGLE is not set -# CONFIG_IP_NF_MATCH_AH is not set -# CONFIG_IP_NF_MATCH_ECN is not set -# CONFIG_IP_NF_MATCH_RPFILTER is not set -# CONFIG_IP_NF_MATCH_TTL is not set -# CONFIG_IP_NF_RAW is not set -# CONFIG_IP_NF_SECURITY is not set -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -# CONFIG_IP_NF_TARGET_ECN is not set -# CONFIG_IP_NF_TARGET_MASQUERADE is not set -# CONFIG_IP_NF_TARGET_NETMAP is not set -# CONFIG_IP_NF_TARGET_REDIRECT is not set -# CONFIG_IP_NF_TARGET_REJECT is not set -# CONFIG_IP_NF_TARGET_SYNPROXY is not set -# CONFIG_IP_NF_TARGET_TTL is not set -# CONFIG_IP_PIMSM_V1 is not set -# CONFIG_IP_PIMSM_V2 is not set -# CONFIG_IP_PNP is not set -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_SCTP is not set -# CONFIG_IP_SET is not set -# CONFIG_IP_SET_HASH_IPMAC is not set -# CONFIG_IP_VS is not set -# CONFIG_IP_VS_MH is not set -CONFIG_IP_VS_MH_TAB_INDEX=10 -# CONFIG_IP_VS_TWOS is not set -# CONFIG_IRDA is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_IRQ_ALL_CPUS is not set -# CONFIG_IRQ_DOMAIN_DEBUG is not set -# CONFIG_IRQ_POLL is not set -# CONFIG_IRQ_TIME_ACCOUNTING is not set -# CONFIG_IR_GPIO_CIR is not set -# CONFIG_IR_HIX5HD2 is not set -# CONFIG_IR_IGORPLUGUSB is not set -# CONFIG_IR_IGUANA is not set -# CONFIG_IR_IMG is not set -# CONFIG_IR_IMON is not set -# CONFIG_IR_IMON_RAW is not set -# CONFIG_IR_JVC_DECODER is not set -# CONFIG_IR_LIRC_CODEC is not set -# CONFIG_IR_MCEUSB is not set -# CONFIG_IR_NEC_DECODER is not set -# CONFIG_IR_RC5_DECODER is not set -# CONFIG_IR_RC6_DECODER is not set -# CONFIG_IR_REDRAT3 is not set -# CONFIG_IR_SERIAL is not set -# CONFIG_IR_SIR is not set -# CONFIG_IR_SONY_DECODER is not set -# CONFIG_IR_STREAMZAP is not set -# CONFIG_IR_TOY is not set -# CONFIG_IR_TTUSBIR is not set -# CONFIG_ISA_BUS is not set -# CONFIG_ISA_BUS_API is not set -# CONFIG_ISCSI_BOOT_SYSFS is not set -# CONFIG_ISCSI_TCP is not set -CONFIG_ISDN=y -# CONFIG_ISDN_AUDIO is not set -# CONFIG_ISDN_CAPI is not set -# CONFIG_ISDN_CAPI_CAPIDRV is not set -# CONFIG_ISDN_DIVERSION is not set -# CONFIG_ISDN_DRV_ACT2000 is not set -# CONFIG_ISDN_DRV_GIGASET is not set -# CONFIG_ISDN_DRV_HISAX is not set -# CONFIG_ISDN_DRV_ICN is not set -# CONFIG_ISDN_DRV_LOOP is not set -# CONFIG_ISDN_DRV_PCBIT is not set -# CONFIG_ISDN_DRV_SC is not set -# CONFIG_ISDN_I4L is not set -# CONFIG_ISL29003 is not set -# CONFIG_ISL29020 is not set -# CONFIG_ISL29125 is not set -# CONFIG_ISL29501 is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_ISS4xx is not set -# CONFIG_ITG3200 is not set -# CONFIG_IWL3945 is not set -# CONFIG_IWLWIFI is not set -# CONFIG_IXGB is not set -# CONFIG_IXGBE is not set -# CONFIG_IXGBEVF is not set -# CONFIG_JAILHOUSE_GUEST is not set -# CONFIG_JBD2_DEBUG is not set -# CONFIG_JFFS2_CMODE_FAVOURLZO is not set -# CONFIG_JFFS2_CMODE_NONE is not set -CONFIG_JFFS2_CMODE_PRIORITY=y -# CONFIG_JFFS2_CMODE_SIZE is not set -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_JFFS2_FS_POSIX_ACL is not set -# CONFIG_JFFS2_FS_SECURITY is not set -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -CONFIG_JFFS2_FS_WRITEBUFFER=y -CONFIG_JFFS2_FS_XATTR=y -CONFIG_JFFS2_LZMA=y -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_JFFS2_SUMMARY=y -# CONFIG_JFFS2_ZLIB is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_POSIX_ACL is not set -# CONFIG_JFS_SECURITY is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_JME is not set -CONFIG_JOLIET=y -# CONFIG_JSA1212 is not set -# CONFIG_JUMP_LABEL is not set -# CONFIG_JZ4740_WDT is not set -# CONFIG_JZ4770_PHY is not set -# CONFIG_KALLSYMS is not set -# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set -# CONFIG_KALLSYMS_ALL is not set -CONFIG_KALLSYMS_BASE_RELATIVE=y -# CONFIG_KALLSYMS_UNCOMPRESSED is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_KASAN is not set -# CONFIG_KASAN_MODULE_TEST is not set -CONFIG_KASAN_STACK=y -# CONFIG_KCMP is not set -# CONFIG_KCOV is not set -CONFIG_KCOV_IRQ_AREA_SIZE=0x40000 -# CONFIG_KCSAN is not set -# CONFIG_KERNEL_BZIP2 is not set -# CONFIG_KERNEL_CAT is not set -# CONFIG_KERNEL_GZIP is not set -# CONFIG_KERNEL_LZ4 is not set -# CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_LZO is not set -CONFIG_KERNEL_MODE_NEON=y -CONFIG_KERNEL_XZ=y -# CONFIG_KERNEL_ZSTD is not set -CONFIG_KERNFS=y -# CONFIG_KEXEC is not set -# CONFIG_KEXEC_FILE is not set -# CONFIG_KEXEC_SIG is not set -# CONFIG_KEYBOARD_ADC is not set -# CONFIG_KEYBOARD_ADP5588 is not set -# CONFIG_KEYBOARD_ADP5589 is not set -# CONFIG_KEYBOARD_APPLESPI is not set -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_BCM is not set -# CONFIG_KEYBOARD_CAP11XX is not set -# CONFIG_KEYBOARD_CYPRESS_SF is not set -# CONFIG_KEYBOARD_DLINK_DIR685 is not set -# CONFIG_KEYBOARD_GPIO is not set -# CONFIG_KEYBOARD_GPIO_POLLED is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_LM8333 is not set -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_MAX7359 is not set -# CONFIG_KEYBOARD_MCS is not set -# CONFIG_KEYBOARD_MPR121 is not set -# CONFIG_KEYBOARD_MT6779 is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_OMAP4 is not set -# CONFIG_KEYBOARD_OPENCORES is not set -# CONFIG_KEYBOARD_PINEPHONE is not set -# CONFIG_KEYBOARD_PXA27x is not set -# CONFIG_KEYBOARD_QT1050 is not set -# CONFIG_KEYBOARD_QT1070 is not set -# CONFIG_KEYBOARD_QT2160 is not set -# CONFIG_KEYBOARD_SAMSUNG is not set -# CONFIG_KEYBOARD_SH_KEYSC is not set -# CONFIG_KEYBOARD_SNVS_PWRKEY is not set -# CONFIG_KEYBOARD_STMPE is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_TCA8418 is not set -# CONFIG_KEYBOARD_TEGRA is not set -# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set -# CONFIG_KEYBOARD_TWL4030 is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYS is not set -# CONFIG_KEYS_REQUEST_CACHE is not set -# CONFIG_KEY_DH_OPERATIONS is not set -# CONFIG_KFENCE is not set -# CONFIG_KGDB is not set -# CONFIG_KMEMCHECK is not set -# CONFIG_KMX61 is not set -# CONFIG_KPC2000 is not set -# CONFIG_KPROBES is not set -# CONFIG_KPROBES_SANITY_TEST is not set -# CONFIG_KPROBE_EVENTS_ON_NOTRACE is not set -# CONFIG_KPROBE_EVENT_GEN_TEST is not set -# CONFIG_KS7010 is not set -# CONFIG_KS8842 is not set -# CONFIG_KS8851 is not set -# CONFIG_KS8851_MLL is not set -# CONFIG_KSM is not set -# CONFIG_KSZ884X_PCI is not set -# CONFIG_KUNIT is not set -CONFIG_KUSER_HELPERS=y -# CONFIG_KVM_AMD is not set -# CONFIG_KVM_AMD_SEV is not set -# CONFIG_KVM_GUEST is not set -# CONFIG_KVM_INTEL is not set -# CONFIG_KVM_WERROR is not set -# CONFIG_KVM_XEN is not set -# CONFIG_KXCJK1013 is not set -# CONFIG_KXSD9 is not set -# CONFIG_L2TP is not set -# CONFIG_L2TP_ETH is not set -# CONFIG_L2TP_IP is not set -# CONFIG_L2TP_V3 is not set -# CONFIG_LAN743X is not set -# CONFIG_LAN966X_SWITCH is not set -# CONFIG_LANMEDIA is not set -# CONFIG_LANTIQ is not set -# CONFIG_LAPB is not set -# CONFIG_LASAT is not set -# CONFIG_LATENCYTOP is not set -# CONFIG_LATTICE_ECP3_CONFIG is not set -CONFIG_LBDAF=y -# CONFIG_LCD_AMS369FG06 is not set -# CONFIG_LCD_CLASS_DEVICE is not set -# CONFIG_LCD_HX8357 is not set -# CONFIG_LCD_ILI922X is not set -# CONFIG_LCD_ILI9320 is not set -# CONFIG_LCD_L4F00242T03 is not set -# CONFIG_LCD_LD9040 is not set -# CONFIG_LCD_LMS283GF05 is not set -# CONFIG_LCD_LMS501KF03 is not set -# CONFIG_LCD_LTV350QV is not set -# CONFIG_LCD_OTM3225A is not set -# CONFIG_LCD_S6E63M0 is not set -# CONFIG_LCD_TDO24M is not set -# CONFIG_LCD_VGG2432A4 is not set -CONFIG_LDISC_AUTOLOAD=y -# CONFIG_LDM_PARTITION is not set -CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y -# CONFIG_LD_HEAD_STUB_CATCH is not set -# CONFIG_LEDS_AN30259A is not set -# CONFIG_LEDS_APU is not set -# CONFIG_LEDS_AW2013 is not set -# CONFIG_LEDS_BCM6328 is not set -# CONFIG_LEDS_BCM6358 is not set -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_BLINKM is not set -CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y -CONFIG_LEDS_CLASS=y -# CONFIG_LEDS_CLASS_FLASH is not set -CONFIG_LEDS_CLASS_MULTICOLOR=y -# CONFIG_LEDS_CR0014114 is not set -# CONFIG_LEDS_DAC124S085 is not set -# CONFIG_LEDS_EL15203000 is not set -# CONFIG_LEDS_GPIO is not set -# CONFIG_LEDS_INTEL_SS4200 is not set -# CONFIG_LEDS_IS31FL319X is not set -# CONFIG_LEDS_IS31FL32XX is not set -# CONFIG_LEDS_LM3530 is not set -# CONFIG_LEDS_LM3532 is not set -# CONFIG_LEDS_LM355x is not set -# CONFIG_LEDS_LM3642 is not set -# CONFIG_LEDS_LM3692X is not set -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP3952 is not set -# CONFIG_LEDS_LP50XX is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_LP5562 is not set -# CONFIG_LEDS_LP55XX_COMMON is not set -# CONFIG_LEDS_LP8501 is not set -# CONFIG_LEDS_LP8860 is not set -# CONFIG_LEDS_LT3593 is not set -# CONFIG_LEDS_MLXCPLD is not set -# CONFIG_LEDS_MLXREG is not set -# CONFIG_LEDS_NIC78BX is not set -# CONFIG_LEDS_NS2 is not set -# CONFIG_LEDS_OT200 is not set -# CONFIG_LEDS_PCA9532 is not set -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_PCA963X is not set -# CONFIG_LEDS_PWM is not set -# CONFIG_LEDS_PWM_MULTICOLOR is not set -# CONFIG_LEDS_REGULATOR is not set -# CONFIG_LEDS_SPI_BYTE is not set -# CONFIG_LEDS_SYSCON is not set -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_TI_LMU_COMMON is not set -# CONFIG_LEDS_TLC591XX is not set -CONFIG_LEDS_TRIGGERS=y -# CONFIG_LEDS_TRIGGER_ACTIVITY is not set -# CONFIG_LEDS_TRIGGER_AUDIO is not set -# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set -# CONFIG_LEDS_TRIGGER_CAMERA is not set -# CONFIG_LEDS_TRIGGER_CPU is not set -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -# CONFIG_LEDS_TRIGGER_DISK is not set -# CONFIG_LEDS_TRIGGER_GPIO is not set -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LEDS_TRIGGER_MTD is not set -CONFIG_LEDS_TRIGGER_NETDEV=y -# CONFIG_LEDS_TRIGGER_ONESHOT is not set -# CONFIG_LEDS_TRIGGER_PANIC is not set -# CONFIG_LEDS_TRIGGER_PATTERN is not set -CONFIG_LEDS_TRIGGER_TIMER=y -# CONFIG_LEDS_TRIGGER_TRANSIENT is not set -# CONFIG_LEDS_TRIGGER_TTY is not set -# CONFIG_LEDS_TURRIS_OMNIA is not set -# CONFIG_LEDS_USER is not set -# CONFIG_LED_TRIGGER_PHY is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_LGUEST is not set -# CONFIG_LIB80211 is not set -# CONFIG_LIB80211_CRYPT_CCMP is not set -# CONFIG_LIB80211_CRYPT_TKIP is not set -# CONFIG_LIB80211_CRYPT_WEP is not set -# CONFIG_LIB80211_DEBUG is not set -# CONFIG_LIBCRC32C is not set -# CONFIG_LIBERTAS is not set -# CONFIG_LIBERTAS_THINFIRM is not set -# CONFIG_LIBERTAS_USB is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_LIBIPW_DEBUG is not set -# CONFIG_LIBNVDIMM is not set -CONFIG_LIB_MEMNEQ=y -# CONFIG_LIDAR_LITE_V2 is not set -CONFIG_LINEAR_RANGES=y -# CONFIG_LIQUIDIO is not set -# CONFIG_LIQUIDIO_VF is not set -# CONFIG_LIRC is not set -# CONFIG_LIS3L02DQ is not set -# CONFIG_LITEX_LITEETH is not set -# CONFIG_LITEX_SOC_CONTROLLER is not set -# CONFIG_LIVEPATCH is not set -# CONFIG_LKDTM is not set -CONFIG_LLC=y -# CONFIG_LLC2 is not set -# CONFIG_LMK04832 is not set -# CONFIG_LMP91000 is not set -# CONFIG_LNET is not set -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_LOCKD is not set -CONFIG_LOCKDEP_BITS=15 -CONFIG_LOCKDEP_CHAINS_BITS=16 -CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12 -CONFIG_LOCKDEP_STACK_TRACE_BITS=19 -CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14 -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_LOCKD_V4=y -# CONFIG_LOCKUP_DETECTOR is not set -# CONFIG_LOCK_EVENT_COUNTS is not set -CONFIG_LOCK_MM_AND_FIND_VMA=y -# CONFIG_LOCK_STAT is not set -# CONFIG_LOCK_TORTURE_TEST is not set -# CONFIG_LOGFS is not set -# CONFIG_LOGIG940_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIWHEELS_FF is not set -# CONFIG_LOGO is not set -CONFIG_LOG_BUF_SHIFT=17 -CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 -# CONFIG_LOONGSON_MC146818 is not set -# CONFIG_LPC_ICH is not set -# CONFIG_LPC_SCH is not set -# CONFIG_LP_CONSOLE is not set -CONFIG_LRU_GEN=y -CONFIG_LRU_GEN_ENABLED=y -# CONFIG_LRU_GEN_STATS is not set -# CONFIG_LSI_ET1011C_PHY is not set -CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" -CONFIG_LSM_MMAP_MIN_ADDR=65536 -# CONFIG_LTC1660 is not set -# CONFIG_LTC2471 is not set -# CONFIG_LTC2485 is not set -# CONFIG_LTC2496 is not set -# CONFIG_LTC2497 is not set -# CONFIG_LTC2632 is not set -# CONFIG_LTC2688 is not set -# CONFIG_LTC2983 is not set -# CONFIG_LTE_GDM724X is not set -CONFIG_LTO_NONE=y -# CONFIG_LTPC is not set -# CONFIG_LTR501 is not set -# CONFIG_LTRF216A is not set -# CONFIG_LUSTRE_FS is not set -# CONFIG_LV0104CS is not set -# CONFIG_LWTUNNEL is not set -# CONFIG_LXT_PHY is not set -# CONFIG_LZ4HC_COMPRESS is not set -# CONFIG_LZ4_COMPRESS is not set -# CONFIG_LZ4_DECOMPRESS is not set -CONFIG_LZMA_COMPRESS=y -CONFIG_LZMA_DECOMPRESS=y -# CONFIG_LZO_COMPRESS is not set -# CONFIG_LZO_DECOMPRESS is not set -# CONFIG_M62332 is not set -# CONFIG_MAC80211 is not set -# CONFIG_MAC80211_MESSAGE_TRACING is not set -CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -# CONFIG_MACB is not set -# CONFIG_MACH_ASM9260 is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_INGENIC is not set -# CONFIG_MACH_INGENIC_SOC is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_MACH_JZ4740 is not set -# CONFIG_MACH_LOONGSON2EF is not set -# CONFIG_MACH_LOONGSON32 is not set -# CONFIG_MACH_LOONGSON64 is not set -# CONFIG_MACH_NINTENDO64 is not set -# CONFIG_MACH_PIC32 is not set -# CONFIG_MACH_PISTACHIO is not set -# CONFIG_MACH_REALTEK_RTL is not set -# CONFIG_MACH_TX39XX is not set -# CONFIG_MACH_TX49XX is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_MACH_XILFPGA is not set -# CONFIG_MACINTOSH_DRIVERS is not set -# CONFIG_MACSEC is not set -# CONFIG_MACVLAN is not set -# CONFIG_MACVTAP is not set -# CONFIG_MAC_EMUMOUSEBTN is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MAG3110 is not set -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 -# CONFIG_MAGIC_SYSRQ_SERIAL is not set -CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" -# CONFIG_MAILBOX is not set -# CONFIG_MANAGER_SBS is not set -# CONFIG_MANDATORY_FILE_LOCKING is not set -# CONFIG_MANGLE_BOOTARGS is not set -# CONFIG_MARVELL_10G_PHY is not set -# CONFIG_MARVELL_88X2222_PHY is not set -# CONFIG_MARVELL_PHY is not set -# CONFIG_MAX1027 is not set -# CONFIG_MAX11100 is not set -# CONFIG_MAX1118 is not set -# CONFIG_MAX11205 is not set -# CONFIG_MAX1241 is not set -# CONFIG_MAX1363 is not set -# CONFIG_MAX30100 is not set -# CONFIG_MAX30102 is not set -# CONFIG_MAX31856 is not set -# CONFIG_MAX31865 is not set -# CONFIG_MAX44000 is not set -# CONFIG_MAX44009 is not set -# CONFIG_MAX517 is not set -# CONFIG_MAX5432 is not set -# CONFIG_MAX5481 is not set -# CONFIG_MAX5487 is not set -# CONFIG_MAX5821 is not set -# CONFIG_MAX63XX_WATCHDOG is not set -# CONFIG_MAX9611 is not set -# CONFIG_MAXIM_THERMOCOUPLE is not set -# CONFIG_MAXLINEAR_GPHY is not set -CONFIG_MAY_USE_DEVLINK=y -# CONFIG_MB1232 is not set -# CONFIG_MC3230 is not set -# CONFIG_MCB is not set -# CONFIG_MCP320X is not set -# CONFIG_MCP3422 is not set -# CONFIG_MCP3911 is not set -# CONFIG_MCP4018 is not set -# CONFIG_MCP41010 is not set -# CONFIG_MCP4131 is not set -# CONFIG_MCP4531 is not set -# CONFIG_MCP4725 is not set -# CONFIG_MCP4922 is not set -# CONFIG_MCPM is not set -# CONFIG_MCTP is not set -# CONFIG_MD is not set -# CONFIG_MDIO_BCM_UNIMAC is not set -# CONFIG_MDIO_BITBANG is not set -# CONFIG_MDIO_BUS_MUX_GPIO is not set -# CONFIG_MDIO_BUS_MUX_MMIOREG is not set -# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set -# CONFIG_MDIO_DEVICE is not set -# CONFIG_MDIO_DEVRES is not set -# CONFIG_MDIO_HISI_FEMAC is not set -# CONFIG_MDIO_IPQ4019 is not set -# CONFIG_MDIO_IPQ8064 is not set -# CONFIG_MDIO_MSCC_MIIM is not set -# CONFIG_MDIO_MVUSB is not set -# CONFIG_MDIO_OCTEON is not set -# CONFIG_MDIO_THUNDER is not set -# CONFIG_MDIO_XPCS is not set -# CONFIG_MDM_GCC_9607 is not set -# CONFIG_MD_FAULTY is not set -# CONFIG_MEDIATEK_GE_PHY is not set -# CONFIG_MEDIATEK_MT6577_AUXADC is not set -# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set -# CONFIG_MEDIA_ATTACH is not set -# CONFIG_MEDIA_CAMERA_SUPPORT is not set -# CONFIG_MEDIA_CEC_SUPPORT is not set -# CONFIG_MEDIA_CONTROLLER is not set -# CONFIG_MEDIA_CONTROLLER_DVB is not set -# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set -# CONFIG_MEDIA_PCI_SUPPORT is not set -# CONFIG_MEDIA_PLATFORM_DRIVERS is not set -# CONFIG_MEDIA_PLATFORM_SUPPORT is not set -# CONFIG_MEDIA_RADIO_SUPPORT is not set -# CONFIG_MEDIA_RC_SUPPORT is not set -# CONFIG_MEDIA_SDR_SUPPORT is not set -# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -# CONFIG_MEDIA_SUPPORT is not set -# CONFIG_MEDIA_SUPPORT_FILTER is not set -# CONFIG_MEDIA_TEST_SUPPORT is not set -# CONFIG_MEDIA_TUNER_E4000 is not set -# CONFIG_MEDIA_TUNER_FC0011 is not set -# CONFIG_MEDIA_TUNER_FC0012 is not set -# CONFIG_MEDIA_TUNER_FC0013 is not set -# CONFIG_MEDIA_TUNER_FC2580 is not set -# CONFIG_MEDIA_TUNER_IT913X is not set -# CONFIG_MEDIA_TUNER_M88RS6000T is not set -# CONFIG_MEDIA_TUNER_MAX2165 is not set -# CONFIG_MEDIA_TUNER_MC44S803 is not set -# CONFIG_MEDIA_TUNER_MSI001 is not set -# CONFIG_MEDIA_TUNER_MT2060 is not set -# CONFIG_MEDIA_TUNER_MT2063 is not set -# CONFIG_MEDIA_TUNER_MT20XX is not set -# CONFIG_MEDIA_TUNER_MT2131 is not set -# CONFIG_MEDIA_TUNER_MT2266 is not set -# CONFIG_MEDIA_TUNER_MXL301RF is not set -# CONFIG_MEDIA_TUNER_MXL5005S is not set -# CONFIG_MEDIA_TUNER_MXL5007T is not set -# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set -# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set -# CONFIG_MEDIA_TUNER_QT1010 is not set -# CONFIG_MEDIA_TUNER_R820T is not set -# CONFIG_MEDIA_TUNER_SI2157 is not set -# CONFIG_MEDIA_TUNER_SIMPLE is not set -# CONFIG_MEDIA_TUNER_TDA18212 is not set -# CONFIG_MEDIA_TUNER_TDA18218 is not set -# CONFIG_MEDIA_TUNER_TDA18250 is not set -# CONFIG_MEDIA_TUNER_TDA18271 is not set -# CONFIG_MEDIA_TUNER_TDA827X is not set -# CONFIG_MEDIA_TUNER_TDA8290 is not set -# CONFIG_MEDIA_TUNER_TDA9887 is not set -# CONFIG_MEDIA_TUNER_TEA5761 is not set -# CONFIG_MEDIA_TUNER_TEA5767 is not set -# CONFIG_MEDIA_TUNER_TUA9001 is not set -# CONFIG_MEDIA_TUNER_XC2028 is not set -# CONFIG_MEDIA_TUNER_XC4000 is not set -# CONFIG_MEDIA_TUNER_XC5000 is not set -# CONFIG_MEDIA_USB_SUPPORT is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_MELLANOX_PLATFORM is not set -CONFIG_MEMBARRIER=y -# CONFIG_MEMORY is not set -# CONFIG_MEMORY_FAILURE is not set -# CONFIG_MEMORY_HOTPLUG is not set -# CONFIG_MEMSTICK is not set -# CONFIG_MEMTEST is not set -# CONFIG_MEN_A21_WDT is not set -# CONFIG_MESON_SM is not set -CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -# CONFIG_MFD_88PM800 is not set -# CONFIG_MFD_88PM805 is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_MFD_AC100 is not set -# CONFIG_MFD_ACT8945A is not set -# CONFIG_MFD_ARIZONA_I2C is not set -# CONFIG_MFD_ARIZONA_SPI is not set -# CONFIG_MFD_AS3711 is not set -# CONFIG_MFD_AS3722 is not set -# CONFIG_MFD_ASIC3 is not set -# CONFIG_MFD_ATC260X_I2C is not set -# CONFIG_MFD_ATMEL_FLEXCOM is not set -# CONFIG_MFD_ATMEL_HLCDC is not set -# CONFIG_MFD_AXP20X is not set -# CONFIG_MFD_AXP20X_I2C is not set -# CONFIG_MFD_BCM590XX is not set -# CONFIG_MFD_BD9571MWV is not set -# CONFIG_MFD_CORE is not set -# CONFIG_MFD_CPCAP is not set -# CONFIG_MFD_CROS_EC is not set -# CONFIG_MFD_CS5535 is not set -# CONFIG_MFD_DA9052_I2C is not set -# CONFIG_MFD_DA9052_SPI is not set -# CONFIG_MFD_DA9055 is not set -# CONFIG_MFD_DA9062 is not set -# CONFIG_MFD_DA9063 is not set -# CONFIG_MFD_DA9150 is not set -# CONFIG_MFD_DLN2 is not set -# CONFIG_MFD_EXYNOS_LPASS is not set -# CONFIG_MFD_GATEWORKS_GSC is not set -# CONFIG_MFD_HI6421_PMIC is not set -# CONFIG_MFD_INTEL_M10_BMC is not set -# CONFIG_MFD_INTEL_PMT is not set -# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set -# CONFIG_MFD_IQS62X is not set -# CONFIG_MFD_JANZ_CMODIO is not set -# CONFIG_MFD_KEMPLD is not set -# CONFIG_MFD_LM3533 is not set -# CONFIG_MFD_LOCHNAGAR is not set -# CONFIG_MFD_LP3943 is not set -# CONFIG_MFD_LP8788 is not set -# CONFIG_MFD_MADERA is not set -# CONFIG_MFD_MAX14577 is not set -# CONFIG_MFD_MAX77620 is not set -# CONFIG_MFD_MAX77650 is not set -# CONFIG_MFD_MAX77686 is not set -# CONFIG_MFD_MAX77693 is not set -# CONFIG_MFD_MAX77714 is not set -# CONFIG_MFD_MAX77843 is not set -# CONFIG_MFD_MAX8907 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_MC13XXX is not set -# CONFIG_MFD_MC13XXX_I2C is not set -# CONFIG_MFD_MC13XXX_SPI is not set -# CONFIG_MFD_MENF21BMC is not set -# CONFIG_MFD_MP2629 is not set -# CONFIG_MFD_MT6360 is not set -# CONFIG_MFD_MT6370 is not set -# CONFIG_MFD_MT6397 is not set -# CONFIG_MFD_NTXEC is not set -# CONFIG_MFD_OCELOT is not set -# CONFIG_MFD_OMAP_USB_HOST is not set -# CONFIG_MFD_PALMAS is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_PM8921_CORE is not set -# CONFIG_MFD_PM8XXX is not set -# CONFIG_MFD_QCOM_PM8008 is not set -# CONFIG_MFD_RASPBERRYPI_POE_HAT is not set -# CONFIG_MFD_RC5T583 is not set -# CONFIG_MFD_RDC321X is not set -# CONFIG_MFD_RETU is not set -# CONFIG_MFD_RK808 is not set -# CONFIG_MFD_RN5T618 is not set -# CONFIG_MFD_ROHM_BD70528 is not set -# CONFIG_MFD_ROHM_BD71828 is not set -# CONFIG_MFD_ROHM_BD718XX is not set -# CONFIG_MFD_ROHM_BD957XMUF is not set -# CONFIG_MFD_RP1 is not set -# CONFIG_MFD_RPISENSE_CORE is not set -# CONFIG_MFD_RSMU_I2C is not set -# CONFIG_MFD_RSMU_SPI is not set -# CONFIG_MFD_RT4831 is not set -# CONFIG_MFD_RT5033 is not set -# CONFIG_MFD_RT5120 is not set -# CONFIG_MFD_RTSX_PCI is not set -# CONFIG_MFD_RTSX_USB is not set -# CONFIG_MFD_SEC_CORE is not set -# CONFIG_MFD_SI476X_CORE is not set -# CONFIG_MFD_SKY81452 is not set -# CONFIG_MFD_SL28CPLD is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_SMSC is not set -# CONFIG_MFD_STMFX is not set -# CONFIG_MFD_STMPE is not set -# CONFIG_MFD_STPMIC1 is not set -# CONFIG_MFD_SY7636A is not set -# CONFIG_MFD_SYSCON is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set -# CONFIG_MFD_TIMBERDALE is not set -# CONFIG_MFD_TI_AM335X_TSCADC is not set -# CONFIG_MFD_TI_LMU is not set -# CONFIG_MFD_TI_LP873X is not set -# CONFIG_MFD_TI_LP87565 is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_TPS65086 is not set -# CONFIG_MFD_TPS65090 is not set -# CONFIG_MFD_TPS65217 is not set -# CONFIG_MFD_TPS65218 is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_MFD_TPS68470 is not set -# CONFIG_MFD_TPS80031 is not set -# CONFIG_MFD_TQMX86 is not set -# CONFIG_MFD_VIPERBOARD is not set -# CONFIG_MFD_VX855 is not set -# CONFIG_MFD_WL1273_CORE is not set -# CONFIG_MFD_WM831X is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM8994 is not set -# CONFIG_MG_DISK is not set -# CONFIG_MHI_BUS is not set -# CONFIG_MHI_BUS_DEBUG is not set -# CONFIG_MHI_BUS_EP is not set -# CONFIG_MHI_BUS_PCI_GENERIC is not set -# CONFIG_MHI_NET is not set -# CONFIG_MHI_WWAN_CTRL is not set -# CONFIG_MHI_WWAN_MBIM is not set -# CONFIG_MICREL_KS8995MA is not set -# CONFIG_MICREL_PHY is not set -# CONFIG_MICROCHIP_KSZ is not set -# CONFIG_MICROCHIP_PHY is not set -# CONFIG_MICROCHIP_PIT64B is not set -# CONFIG_MICROCHIP_T1_PHY is not set -# CONFIG_MICROSEMI_PHY is not set -# CONFIG_MIGRATION is not set -CONFIG_MII=y -# CONFIG_MIKROTIK is not set -# CONFIG_MIKROTIK_RB532 is not set -# CONFIG_MINIX_FS is not set -# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_MIPS32_N32 is not set -# CONFIG_MIPS32_O32 is not set -# CONFIG_MIPS_ALCHEMY is not set -# CONFIG_MIPS_CDMM is not set -# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set -# CONFIG_MIPS_CMDLINE_FROM_DTB is not set -# CONFIG_MIPS_CMP is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MIPS_CPS is not set -# CONFIG_MIPS_ELF_APPENDED_DTB is not set -# CONFIG_MIPS_FPU_EMULATOR is not set -# CONFIG_MIPS_FP_SUPPORT is not set -# CONFIG_MIPS_GENERIC is not set -# CONFIG_MIPS_GENERIC_KERNEL is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_O32_FP64_SUPPORT is not set -# CONFIG_MIPS_PARAVIRT is not set -# CONFIG_MIPS_PLATFORM_DEVICES is not set -# CONFIG_MIPS_RAW_APPENDED_DTB is not set -# CONFIG_MIPS_SEAD3 is not set -# CONFIG_MIPS_VA_BITS_48 is not set -# CONFIG_MIPS_VPE_LOADER is not set -# CONFIG_MISC_ALCOR_PCI is not set -CONFIG_MISC_FILESYSTEMS=y -# CONFIG_MISC_RTSX_PCI is not set -# CONFIG_MISC_RTSX_USB is not set -# CONFIG_MISDN is not set -# CONFIG_MISDN_AVMFRITZ is not set -# CONFIG_MISDN_HFCPCI is not set -# CONFIG_MISDN_HFCUSB is not set -# CONFIG_MISDN_INFINEON is not set -# CONFIG_MISDN_NETJET is not set -# CONFIG_MISDN_SPEEDFAX is not set -# CONFIG_MISDN_W6692 is not set -CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y -# CONFIG_MKISS is not set -# CONFIG_MLX4_CORE is not set -# CONFIG_MLX4_EN is not set -# CONFIG_MLX5_CORE is not set -# CONFIG_MLX5_EN_MACSEC is not set -# CONFIG_MLX5_SF is not set -# CONFIG_MLX5_VFIO_PCI is not set -# CONFIG_MLX90614 is not set -# CONFIG_MLX90632 is not set -# CONFIG_MLXFW is not set -# CONFIG_MLXSW_CORE is not set -# CONFIG_MLX_CPLD_PLATFORM is not set -# CONFIG_MLX_PLATFORM is not set -# CONFIG_MMA7455_I2C is not set -# CONFIG_MMA7455_SPI is not set -# CONFIG_MMA7660 is not set -# CONFIG_MMA8452 is not set -# CONFIG_MMA9551 is not set -# CONFIG_MMA9553 is not set -# CONFIG_MMC is not set -# CONFIG_MMC35240 is not set -# CONFIG_MMC_ARMMMCI is not set -# CONFIG_MMC_AU1X is not set -# CONFIG_MMC_BLOCK is not set -CONFIG_MMC_BLOCK_BOUNCE=y -CONFIG_MMC_BLOCK_MINORS=8 -# CONFIG_MMC_CAVIUM_THUNDERX is not set -# CONFIG_MMC_CB710 is not set -# CONFIG_MMC_CQHCI is not set -# CONFIG_MMC_DEBUG is not set -# CONFIG_MMC_DW is not set -# CONFIG_MMC_HSQ is not set -# CONFIG_MMC_JZ4740 is not set -# CONFIG_MMC_MTK is not set -# CONFIG_MMC_MVSDIO is not set -# CONFIG_MMC_S3C is not set -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_SDHCI_ACPI is not set -# CONFIG_MMC_SDHCI_AM654 is not set -# CONFIG_MMC_SDHCI_BCM_KONA is not set -# CONFIG_MMC_SDHCI_BRCMSTB is not set -# CONFIG_MMC_SDHCI_CADENCE is not set -# CONFIG_MMC_SDHCI_F_SDH30 is not set -# CONFIG_MMC_SDHCI_IPROC is not set -# CONFIG_MMC_SDHCI_MILBEAUT is not set -# CONFIG_MMC_SDHCI_MSM is not set -# CONFIG_MMC_SDHCI_OF_ARASAN is not set -# CONFIG_MMC_SDHCI_OF_ASPEED is not set -# CONFIG_MMC_SDHCI_OF_AT91 is not set -# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set -# CONFIG_MMC_SDHCI_OF_ESDHC is not set -# CONFIG_MMC_SDHCI_OF_HLWD is not set -# CONFIG_MMC_SDHCI_OMAP is not set -# CONFIG_MMC_SDHCI_PXAV2 is not set -# CONFIG_MMC_SDHCI_PXAV3 is not set -# CONFIG_MMC_SDHCI_S3C is not set -# CONFIG_MMC_SDHCI_XENON is not set -# CONFIG_MMC_SDRICOH_CS is not set -# CONFIG_MMC_SPI is not set -# CONFIG_MMC_STM32_SDMMC is not set -# CONFIG_MMC_TEST is not set -# CONFIG_MMC_TIFM_SD is not set -# CONFIG_MMC_TOSHIBA_PCI is not set -# CONFIG_MMC_USDHI6ROL0 is not set -# CONFIG_MMC_USHC is not set -# CONFIG_MMC_VIA_SDMMC is not set -# CONFIG_MMC_VUB300 is not set -# CONFIG_MMIOTRACE is not set -CONFIG_MMU=y -CONFIG_MMU_GATHER_RCU_TABLE_FREE=y -CONFIG_MMU_GATHER_TABLE_FREE=y -CONFIG_MODPROBE_PATH="/sbin/modprobe" -CONFIG_MODULES=y -# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set -# CONFIG_MODULE_COMPRESS is not set -# CONFIG_MODULE_COMPRESS_GZIP is not set -CONFIG_MODULE_COMPRESS_NONE=y -# CONFIG_MODULE_COMPRESS_XZ is not set -# CONFIG_MODULE_COMPRESS_ZSTD is not set -# CONFIG_MODULE_FORCE_LOAD is not set -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODULE_SIG is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_MODULE_STRIPPED=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_UNLOAD_TAINT_TRACKING is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MOST is not set -# CONFIG_MOTORCOMM_PHY is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_ELAN_I2C is not set -# CONFIG_MOUSE_GPIO is not set -# CONFIG_MOUSE_INPORT is not set -# CONFIG_MOUSE_LOGIBM is not set -# CONFIG_MOUSE_PC110PAD is not set -# CONFIG_MOUSE_PS2_FOCALTECH is not set -# CONFIG_MOUSE_PS2_SENTELIC is not set -# CONFIG_MOUSE_SYNAPTICS_I2C is not set -# CONFIG_MOUSE_SYNAPTICS_USB is not set -# CONFIG_MOXTET is not set -# CONFIG_MPL115 is not set -# CONFIG_MPL115_I2C is not set -# CONFIG_MPL115_SPI is not set -# CONFIG_MPL3115 is not set -# CONFIG_MPLS is not set -# CONFIG_MPLS_IPTUNNEL is not set -# CONFIG_MPLS_ROUTING is not set -# CONFIG_MPTCP is not set -# CONFIG_MPU3050_I2C is not set -# CONFIG_MQ_IOSCHED_DEADLINE is not set -# CONFIG_MQ_IOSCHED_KYBER is not set -# CONFIG_MS5611 is not set -# CONFIG_MS5637 is not set -# CONFIG_MSA311 is not set -# CONFIG_MSCC_OCELOT_SWITCH is not set -# CONFIG_MSDOS_FS is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_MSE102X is not set -# CONFIG_MSI_BITMAP_SELFTEST is not set -# CONFIG_MSI_LAPTOP is not set -# CONFIG_MSM_GCC_8953 is not set -# CONFIG_MSM_MMCC_8994 is not set -# CONFIG_MST_IRQ is not set -CONFIG_MTD=y -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_MTD_BLOCK2MTD is not set -CONFIG_MTD_CFI=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_CMDLINE_PARTS is not set -CONFIG_MTD_COMPLEX_MAPPINGS=y -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_DOCG3 is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_GPIO_ADDR is not set -# CONFIG_MTD_HYPERBUS is not set -# CONFIG_MTD_IMPA7 is not set -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_JEDECPROBE is not set -# CONFIG_MTD_LATCH_ADDR is not set -# CONFIG_MTD_LPDDR is not set -# CONFIG_MTD_LPDDR2_NVM is not set -# CONFIG_MTD_M25P80 is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -CONFIG_MTD_MAP_BANK_WIDTH_2=y -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MCHP23K256 is not set -# CONFIG_MTD_MCHP48L640 is not set -# CONFIG_MTD_MT81xx_NOR is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_MYLOADER_PARTS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_NAND_AMS_DELTA is not set -# CONFIG_MTD_NAND_AR934X is not set -# CONFIG_MTD_NAND_AR934X_HW_ECC is not set -# CONFIG_MTD_NAND_ARASAN is not set -# CONFIG_MTD_NAND_ATMEL is not set -# CONFIG_MTD_NAND_AU1550 is not set -# CONFIG_MTD_NAND_BCH is not set -# CONFIG_MTD_NAND_BF5XX is not set -# CONFIG_MTD_NAND_BRCMNAND is not set -# CONFIG_MTD_NAND_BRCMNAND_BCM63XX is not set -# CONFIG_MTD_NAND_BRCMNAND_BCMBCA is not set -# CONFIG_MTD_NAND_BRCMNAND_BRCMSTB is not set -# CONFIG_MTD_NAND_BRCMNAND_IPROC is not set -# CONFIG_MTD_NAND_CADENCE is not set -# CONFIG_MTD_NAND_CAFE is not set -# CONFIG_MTD_NAND_CM_X270 is not set -# CONFIG_MTD_NAND_CS553X is not set -# CONFIG_MTD_NAND_DAVINCI is not set -# CONFIG_MTD_NAND_DENALI is not set -# CONFIG_MTD_NAND_DENALI_DT is not set -# CONFIG_MTD_NAND_DENALI_PCI is not set -CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018 -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_DOCG4 is not set -# CONFIG_MTD_NAND_ECC is not set -# CONFIG_MTD_NAND_ECC_BCH is not set -# CONFIG_MTD_NAND_ECC_MXIC is not set -# CONFIG_MTD_NAND_ECC_SMC is not set -# CONFIG_MTD_NAND_ECC_SW_BCH is not set -# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set -# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set -# CONFIG_MTD_NAND_FSL_ELBC is not set -# CONFIG_MTD_NAND_FSL_IFC is not set -# CONFIG_MTD_NAND_FSL_UPM is not set -# CONFIG_MTD_NAND_FSMC is not set -# CONFIG_MTD_NAND_GPIO is not set -# CONFIG_MTD_NAND_GPMI_NAND is not set -# CONFIG_MTD_NAND_HISI504 is not set -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_INTEL_LGM is not set -# CONFIG_MTD_NAND_JZ4740 is not set -# CONFIG_MTD_NAND_MPC5121_NFC is not set -# CONFIG_MTD_NAND_MTK is not set -# CONFIG_MTD_NAND_MTK_BMT is not set -# CONFIG_MTD_NAND_MXC is not set -# CONFIG_MTD_NAND_MXIC is not set -# CONFIG_MTD_NAND_NANDSIM is not set -# CONFIG_MTD_NAND_NDFC is not set -# CONFIG_MTD_NAND_NUC900 is not set -# CONFIG_MTD_NAND_OMAP2 is not set -# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set -# CONFIG_MTD_NAND_ORION is not set -# CONFIG_MTD_NAND_PASEMI is not set -# CONFIG_MTD_NAND_PLATFORM is not set -# CONFIG_MTD_NAND_PXA3xx is not set -# CONFIG_MTD_NAND_RB4XX is not set -# CONFIG_MTD_NAND_RB750 is not set -# CONFIG_MTD_NAND_RB91X is not set -# CONFIG_MTD_NAND_RICOH is not set -# CONFIG_MTD_NAND_S3C2410 is not set -# CONFIG_MTD_NAND_SHARPSL is not set -# CONFIG_MTD_NAND_SH_FLCTL is not set -# CONFIG_MTD_NAND_SOCRATES is not set -# CONFIG_MTD_NAND_TMIO is not set -# CONFIG_MTD_NAND_TXX9NDFMC is not set -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_ONENAND is not set -# CONFIG_MTD_OOPS is not set -# CONFIG_MTD_OTP is not set -# CONFIG_MTD_PARSER_TRX is not set -# CONFIG_MTD_PARTITIONED_MASTER is not set -# CONFIG_MTD_PCI is not set -# CONFIG_MTD_PCMCIA is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PHYSMAP_COMPAT is not set -# CONFIG_MTD_PHYSMAP_GEMINI is not set -# CONFIG_MTD_PHYSMAP_GPIO_ADDR is not set -# CONFIG_MTD_PHYSMAP_IXP4XX is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set -# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set -# CONFIG_MTD_PHYSMAP_VERSATILE is not set -# CONFIG_MTD_PLATRAM is not set -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_RAW_NAND is not set -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set -# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set -# CONFIG_MTD_ROM is not set -CONFIG_MTD_ROOTFS_ROOT_DEV=y -# CONFIG_MTD_ROUTERBOOT_PARTS is not set -# CONFIG_MTD_SERCOMM_PARTS is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_SM_COMMON is not set -# CONFIG_MTD_SPINAND_MT29F is not set -# CONFIG_MTD_SPI_NAND is not set -# CONFIG_MTD_SPI_NOR is not set -# CONFIG_MTD_SPI_NOR_SWP_DISABLE is not set -CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE=y -# CONFIG_MTD_SPI_NOR_SWP_KEEP is not set -# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set -# CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE is not set -CONFIG_MTD_SPLIT=y -# CONFIG_MTD_SPLIT_BCM63XX_FW is not set -# CONFIG_MTD_SPLIT_BCM_WFI_FW is not set -# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set -# CONFIG_MTD_SPLIT_ELF_FW is not set -# CONFIG_MTD_SPLIT_EVA_FW is not set -# CONFIG_MTD_SPLIT_FIRMWARE is not set -CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware" -# CONFIG_MTD_SPLIT_FIT_FW is not set -# CONFIG_MTD_SPLIT_H3C_VFS is not set -# CONFIG_MTD_SPLIT_JIMAGE_FW is not set -# CONFIG_MTD_SPLIT_LZMA_FW is not set -# CONFIG_MTD_SPLIT_MINOR_FW is not set -# CONFIG_MTD_SPLIT_SEAMA_FW is not set -# CONFIG_MTD_SPLIT_SEIL_FW is not set -CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y -CONFIG_MTD_SPLIT_SUPPORT=y -# CONFIG_MTD_SPLIT_TPLINK_FW is not set -# CONFIG_MTD_SPLIT_TRX_FW is not set -# CONFIG_MTD_SPLIT_UIMAGE_FW is not set -# CONFIG_MTD_SPLIT_WRGG_FW is not set -# CONFIG_MTD_SST25L is not set -# CONFIG_MTD_SWAP is not set -# CONFIG_MTD_TESTS is not set -# CONFIG_MTD_UBI is not set -# CONFIG_MTD_UBI_FASTMAP is not set -# CONFIG_MTD_UBI_GLUEBI is not set -# CONFIG_MTD_UBI_NVMEM is not set -# CONFIG_MTD_UIMAGE_SPLIT is not set -# CONFIG_MTD_VIRT_CONCAT is not set -# CONFIG_MTK_DEVAPC is not set -# CONFIG_MTK_MMC is not set -# CONFIG_MTK_MMSYS is not set -# CONFIG_MTK_T7XX is not set -# CONFIG_MTK_THERMAL is not set -# CONFIG_MULTIPLEXER is not set -CONFIG_MULTIUSER=y -# CONFIG_MUTEX_SPIN_ON_OWNER is not set -# CONFIG_MUX_ADG792A is not set -# CONFIG_MUX_ADGS1408 is not set -# CONFIG_MUX_GPIO is not set -# CONFIG_MUX_MMIO is not set -# CONFIG_MV643XX_ETH is not set -# CONFIG_MVMDIO is not set -# CONFIG_MVNETA_BM is not set -# CONFIG_MVSW61XX_PHY is not set -# CONFIG_MV_XOR_V2 is not set -# CONFIG_MWAVE is not set -# CONFIG_MWL8K is not set -# CONFIG_MXC4005 is not set -# CONFIG_MXC6255 is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NAMESPACES is not set -# CONFIG_NATIONAL_PHY is not set -# CONFIG_NATSEMI is not set -# CONFIG_NAU7802 is not set -# CONFIG_NBPFAXI_DMA is not set -# CONFIG_NCP_FS is not set -# CONFIG_NE2000 is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NEC_MARKEINS is not set -CONFIG_NET=y -# CONFIG_NETCONSOLE is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVSIM is not set -# CONFIG_NETFILTER is not set -# CONFIG_NETFILTER_ADVANCED is not set -# CONFIG_NETFILTER_DEBUG is not set -# CONFIG_NETFILTER_EGRESS is not set -# CONFIG_NETFILTER_INGRESS is not set -# CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NETFILTER_NETLINK_ACCT is not set -# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set -# CONFIG_NETFILTER_NETLINK_HOOK is not set -# CONFIG_NETFILTER_NETLINK_LOG is not set -# CONFIG_NETFILTER_NETLINK_OSF is not set -# CONFIG_NETFILTER_NETLINK_QUEUE is not set -# CONFIG_NETFILTER_XTABLES is not set -# CONFIG_NETFILTER_XTABLES_COMPAT is not set -# CONFIG_NETFILTER_XT_CONNMARK is not set -# CONFIG_NETFILTER_XT_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_BPF is not set -# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set -# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set -# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set -# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set -# CONFIG_NETFILTER_XT_MATCH_CPU is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -# CONFIG_NETFILTER_XT_MATCH_ECN is not set -# CONFIG_NETFILTER_XT_MATCH_ESP is not set -# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_HELPER is not set -# CONFIG_NETFILTER_XT_MATCH_HL is not set -# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set -# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set -# CONFIG_NETFILTER_XT_MATCH_L2TP is not set -# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set -# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_MAC is not set -# CONFIG_NETFILTER_XT_MATCH_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set -# CONFIG_NETFILTER_XT_MATCH_OSF is not set -# CONFIG_NETFILTER_XT_MATCH_OWNER is not set -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set -# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set -# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_RECENT is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set -# CONFIG_NETFILTER_XT_MATCH_STATE is not set -# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set -# CONFIG_NETFILTER_XT_MATCH_STRING is not set -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -# CONFIG_NETFILTER_XT_MATCH_TIME is not set -# CONFIG_NETFILTER_XT_MATCH_U32 is not set -# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set -# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set -# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set -# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set -# CONFIG_NETFILTER_XT_TARGET_CT is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_HL is not set -# CONFIG_NETFILTER_XT_TARGET_HMARK is not set -# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set -# CONFIG_NETFILTER_XT_TARGET_LED is not set -# CONFIG_NETFILTER_XT_TARGET_LOG is not set -# CONFIG_NETFILTER_XT_TARGET_MARK is not set -# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set -# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set -# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set -# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set -# CONFIG_NETFILTER_XT_TARGET_TEE is not set -# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set -# CONFIG_NETFILTER_XT_TARGET_TRACE is not set -# CONFIG_NETFS_STATS is not set -# CONFIG_NETLABEL is not set -# CONFIG_NETLINK_DIAG is not set -# CONFIG_NETLINK_MMAP is not set -# CONFIG_NETPOLL is not set -# CONFIG_NETROM is not set -CONFIG_NETWORK_FILESYSTEMS=y -# CONFIG_NETWORK_PHY_TIMESTAMPING is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETXEN_NIC is not set -# CONFIG_NET_9P is not set -# CONFIG_NET_ACT_BPF is not set -# CONFIG_NET_ACT_CSUM is not set -# CONFIG_NET_ACT_CT is not set -# CONFIG_NET_ACT_GACT is not set -# CONFIG_NET_ACT_GATE is not set -# CONFIG_NET_ACT_IFE is not set -# CONFIG_NET_ACT_IPT is not set -# CONFIG_NET_ACT_MIRRED is not set -# CONFIG_NET_ACT_MPLS is not set -# CONFIG_NET_ACT_NAT is not set -# CONFIG_NET_ACT_PEDIT is not set -# CONFIG_NET_ACT_POLICE is not set -# CONFIG_NET_ACT_SAMPLE is not set -# CONFIG_NET_ACT_SIMP is not set -# CONFIG_NET_ACT_SKBEDIT is not set -# CONFIG_NET_ACT_SKBMOD is not set -# CONFIG_NET_ACT_TUNNEL_KEY is not set -# CONFIG_NET_ACT_VLAN is not set -CONFIG_NET_CADENCE=y -# CONFIG_NET_CALXEDA_XGMAC is not set -CONFIG_NET_CLS=y -# CONFIG_NET_CLS_ACT is not set -# CONFIG_NET_CLS_BASIC is not set -# CONFIG_NET_CLS_BPF is not set -# CONFIG_NET_CLS_FLOW is not set -# CONFIG_NET_CLS_FLOWER is not set -# CONFIG_NET_CLS_FW is not set -CONFIG_NET_CLS_IND=y -# CONFIG_NET_CLS_MATCHALL is not set -# CONFIG_NET_CLS_ROUTE4 is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_CLS_U32 is not set -CONFIG_NET_CORE=y -# CONFIG_NET_DEVLINK is not set -# CONFIG_NET_DEV_REFCNT_TRACKER is not set -# CONFIG_NET_DROP_MONITOR is not set -# CONFIG_NET_DSA is not set -# CONFIG_NET_DSA_AR9331 is not set -# CONFIG_NET_DSA_BCM_SF2 is not set -# CONFIG_NET_DSA_LANTIQ_GSWIP is not set -# CONFIG_NET_DSA_LEGACY is not set -# CONFIG_NET_DSA_LOOP is not set -# CONFIG_NET_DSA_MICROCHIP_KSZ8795 is not set -# CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set -# CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON is not set -# CONFIG_NET_DSA_MSCC_FELIX is not set -# CONFIG_NET_DSA_MSCC_SEVILLE is not set -# CONFIG_NET_DSA_MT7530 is not set -# CONFIG_NET_DSA_MV88E6060 is not set -# CONFIG_NET_DSA_MV88E6123_61_65 is not set -# CONFIG_NET_DSA_MV88E6131 is not set -# CONFIG_NET_DSA_MV88E6171 is not set -# CONFIG_NET_DSA_MV88E6352 is not set -# CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set -# CONFIG_NET_DSA_MV88E6XXX_PTP is not set -# CONFIG_NET_DSA_QCA8K is not set -# CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT is not set -# CONFIG_NET_DSA_REALTEK is not set -# CONFIG_NET_DSA_REALTEK_SMI is not set -# CONFIG_NET_DSA_SJA1105 is not set -# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set -# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set -# CONFIG_NET_DSA_TAG_8021Q is not set -# CONFIG_NET_DSA_TAG_AR9331 is not set -# CONFIG_NET_DSA_TAG_BRCM is not set -# CONFIG_NET_DSA_TAG_BRCM_LEGACY is not set -# CONFIG_NET_DSA_TAG_BRCM_PREPEND is not set -# CONFIG_NET_DSA_TAG_DSA is not set -# CONFIG_NET_DSA_TAG_EDSA is not set -# CONFIG_NET_DSA_TAG_GSWIP is not set -# CONFIG_NET_DSA_TAG_HELLCREEK is not set -# CONFIG_NET_DSA_TAG_KSZ is not set -# CONFIG_NET_DSA_TAG_LAN9303 is not set -# CONFIG_NET_DSA_TAG_MTK is not set -# CONFIG_NET_DSA_TAG_OCELOT is not set -# CONFIG_NET_DSA_TAG_OCELOT_8021Q is not set -# CONFIG_NET_DSA_TAG_QCA is not set -# CONFIG_NET_DSA_TAG_RTL4_A is not set -# CONFIG_NET_DSA_TAG_RTL8_4 is not set -# CONFIG_NET_DSA_TAG_RZN1_A5PSW is not set -# CONFIG_NET_DSA_TAG_SJA1105 is not set -# CONFIG_NET_DSA_TAG_TRAILER is not set -# CONFIG_NET_DSA_TAG_XRS700X is not set -# CONFIG_NET_DSA_VITESSE_VSC73XX is not set -# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set -# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set -# CONFIG_NET_DSA_XRS700X_I2C is not set -# CONFIG_NET_DSA_XRS700X_MDIO is not set -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_EMATCH_CANID is not set -# CONFIG_NET_EMATCH_CMP is not set -# CONFIG_NET_EMATCH_IPT is not set -# CONFIG_NET_EMATCH_META is not set -# CONFIG_NET_EMATCH_NBYTE is not set -CONFIG_NET_EMATCH_STACK=32 -# CONFIG_NET_EMATCH_TEXT is not set -# CONFIG_NET_EMATCH_U32 is not set -# CONFIG_NET_FAILOVER is not set -# CONFIG_NET_FC is not set -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set -# CONFIG_NET_IFE is not set -# CONFIG_NET_IPGRE is not set -CONFIG_NET_IPGRE_BROADCAST=y -# CONFIG_NET_IPGRE_DEMUX is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPVTI is not set -# CONFIG_NET_IP_TUNNEL is not set -# CONFIG_NET_KEY is not set -# CONFIG_NET_KEY_MIGRATE is not set -# CONFIG_NET_L3_MASTER_DEV is not set -# CONFIG_NET_MEDIATEK_STAR_EMAC is not set -# CONFIG_NET_MPLS_GSO is not set -# CONFIG_NET_NCSI is not set -# CONFIG_NET_NSH is not set -# CONFIG_NET_NS_REFCNT_TRACKER is not set -# CONFIG_NET_PACKET_ENGINE is not set -# CONFIG_NET_PKTGEN is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_NET_PTP_CLASSIFY is not set -CONFIG_NET_RX_BUSY_POLL=y -# CONFIG_NET_SB1000 is not set -CONFIG_NET_SCHED=y -# CONFIG_NET_SCH_CAKE is not set -# CONFIG_NET_SCH_CBS is not set -# CONFIG_NET_SCH_CHOKE is not set -# CONFIG_NET_SCH_CODEL is not set -CONFIG_NET_SCH_DEFAULT=y -# CONFIG_NET_SCH_DRR is not set -# CONFIG_NET_SCH_ETF is not set -# CONFIG_NET_SCH_ETS is not set -CONFIG_NET_SCH_FIFO=y -# CONFIG_NET_SCH_FQ is not set -CONFIG_NET_SCH_FQ_CODEL=y -# CONFIG_NET_SCH_FQ_PIE is not set -# CONFIG_NET_SCH_GRED is not set -# CONFIG_NET_SCH_HFSC is not set -# CONFIG_NET_SCH_HHF is not set -# CONFIG_NET_SCH_HTB is not set -# CONFIG_NET_SCH_INGRESS is not set -# CONFIG_NET_SCH_MQPRIO is not set -# CONFIG_NET_SCH_MULTIQ is not set -# CONFIG_NET_SCH_NETEM is not set -# CONFIG_NET_SCH_PIE is not set -# CONFIG_NET_SCH_PLUG is not set -# CONFIG_NET_SCH_PRIO is not set -# CONFIG_NET_SCH_QFQ is not set -# CONFIG_NET_SCH_RED is not set -# CONFIG_NET_SCH_SFB is not set -# CONFIG_NET_SCH_SFQ is not set -# CONFIG_NET_SCH_SKBPRIO is not set -# CONFIG_NET_SCH_TAPRIO is not set -# CONFIG_NET_SCH_TBF is not set -# CONFIG_NET_SCH_TEQL is not set -# CONFIG_NET_SCTPPROBE is not set -# CONFIG_NET_SELFTESTS is not set -CONFIG_NET_SOCK_MSG=y -# CONFIG_NET_SWITCHDEV is not set -# CONFIG_NET_TCPPROBE is not set -# CONFIG_NET_TC_SKB_EXT is not set -# CONFIG_NET_TEAM is not set -# CONFIG_NET_TULIP is not set -# CONFIG_NET_UDP_TUNNEL is not set -CONFIG_NET_VENDOR_3COM=y -CONFIG_NET_VENDOR_8390=y -CONFIG_NET_VENDOR_ADAPTEC=y -CONFIG_NET_VENDOR_ADI=y -CONFIG_NET_VENDOR_AGERE=y -CONFIG_NET_VENDOR_ALACRITECH=y -CONFIG_NET_VENDOR_ALTEON=y -CONFIG_NET_VENDOR_AMAZON=y -CONFIG_NET_VENDOR_AMD=y -CONFIG_NET_VENDOR_AQUANTIA=y -CONFIG_NET_VENDOR_ARC=y -# CONFIG_NET_VENDOR_ASIX is not set -CONFIG_NET_VENDOR_ATHEROS=y -CONFIG_NET_VENDOR_AURORA=y -CONFIG_NET_VENDOR_BROADCOM=y -CONFIG_NET_VENDOR_BROCADE=y -CONFIG_NET_VENDOR_CADENCE=y -CONFIG_NET_VENDOR_CAVIUM=y -CONFIG_NET_VENDOR_CHELSIO=y -CONFIG_NET_VENDOR_CIRRUS=y -CONFIG_NET_VENDOR_CISCO=y -CONFIG_NET_VENDOR_CORTINA=y -CONFIG_NET_VENDOR_DAVICOM=y -CONFIG_NET_VENDOR_DEC=y -CONFIG_NET_VENDOR_DLINK=y -CONFIG_NET_VENDOR_EMULEX=y -# CONFIG_NET_VENDOR_ENGLEDER is not set -CONFIG_NET_VENDOR_EXAR=y -CONFIG_NET_VENDOR_EZCHIP=y -CONFIG_NET_VENDOR_FARADAY=y -CONFIG_NET_VENDOR_FREESCALE=y -CONFIG_NET_VENDOR_FUJITSU=y -# CONFIG_NET_VENDOR_FUNGIBLE is not set -CONFIG_NET_VENDOR_GOOGLE=y -CONFIG_NET_VENDOR_HISILICON=y -CONFIG_NET_VENDOR_HP=y -CONFIG_NET_VENDOR_HUAWEI=y -CONFIG_NET_VENDOR_I825XX=y -CONFIG_NET_VENDOR_IBM=y -CONFIG_NET_VENDOR_INTEL=y -# CONFIG_NET_VENDOR_LITEX is not set -CONFIG_NET_VENDOR_MARVELL=y -CONFIG_NET_VENDOR_MELLANOX=y -CONFIG_NET_VENDOR_MICREL=y -CONFIG_NET_VENDOR_MICROCHIP=y -CONFIG_NET_VENDOR_MICROSEMI=y -# CONFIG_NET_VENDOR_MICROSOFT is not set -CONFIG_NET_VENDOR_MYRI=y -CONFIG_NET_VENDOR_NATSEMI=y -CONFIG_NET_VENDOR_NETERION=y -CONFIG_NET_VENDOR_NETRONOME=y -CONFIG_NET_VENDOR_NI=y -CONFIG_NET_VENDOR_NVIDIA=y -CONFIG_NET_VENDOR_OKI=y -CONFIG_NET_VENDOR_PACKET_ENGINES=y -CONFIG_NET_VENDOR_PENSANDO=y -CONFIG_NET_VENDOR_QLOGIC=y -CONFIG_NET_VENDOR_QUALCOMM=y -CONFIG_NET_VENDOR_RDC=y -CONFIG_NET_VENDOR_REALTEK=y -CONFIG_NET_VENDOR_RENESAS=y -CONFIG_NET_VENDOR_ROCKER=y -CONFIG_NET_VENDOR_SAMSUNG=y -CONFIG_NET_VENDOR_SEEQ=y -CONFIG_NET_VENDOR_SILAN=y -CONFIG_NET_VENDOR_SIS=y -CONFIG_NET_VENDOR_SMSC=y -CONFIG_NET_VENDOR_SOCIONEXT=y -CONFIG_NET_VENDOR_SOLARFLARE=y -CONFIG_NET_VENDOR_STMICRO=y -CONFIG_NET_VENDOR_SUN=y -CONFIG_NET_VENDOR_SYNOPSYS=y -CONFIG_NET_VENDOR_TEHUTI=y -CONFIG_NET_VENDOR_TI=y -CONFIG_NET_VENDOR_TOSHIBA=y -# CONFIG_NET_VENDOR_VERTEXCOM is not set -CONFIG_NET_VENDOR_VIA=y -# CONFIG_NET_VENDOR_WANGXUN is not set -CONFIG_NET_VENDOR_WIZNET=y -CONFIG_NET_VENDOR_XILINX=y -CONFIG_NET_VENDOR_XIRCOM=y -# CONFIG_NET_VRF is not set -# CONFIG_NET_XGENE is not set -CONFIG_NEW_LEDS=y -# CONFIG_NFC is not set -# CONFIG_NFP is not set -# CONFIG_NFSD is not set -# CONFIG_NFSD_V2 is not set -# CONFIG_NFSD_V2_ACL is not set -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -# CONFIG_NFSD_V4 is not set -# CONFIG_NFS_ACL_SUPPORT is not set -CONFIG_NFS_COMMON=y -# CONFIG_NFS_DISABLE_UDP_SUPPORT is not set -# CONFIG_NFS_FS is not set -# CONFIG_NFS_FSCACHE is not set -# CONFIG_NFS_SWAP is not set -# CONFIG_NFS_V2 is not set -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_V4_1 is not set -# CONFIG_NFTL is not set -# CONFIG_NFT_BRIDGE_META is not set -# CONFIG_NFT_BRIDGE_REJECT is not set -# CONFIG_NFT_CONNLIMIT is not set -# CONFIG_NFT_DUP_IPV4 is not set -# CONFIG_NFT_DUP_IPV6 is not set -# CONFIG_NFT_FIB_IPV4 is not set -# CONFIG_NFT_FIB_IPV6 is not set -# CONFIG_NFT_FIB_NETDEV is not set -# CONFIG_NFT_FLOW_OFFLOAD is not set -# CONFIG_NFT_OBJREF is not set -# CONFIG_NFT_OSF is not set -# CONFIG_NFT_REJECT_NETDEV is not set -# CONFIG_NFT_RT is not set -# CONFIG_NFT_SET_BITMAP is not set -# CONFIG_NFT_SOCKET is not set -# CONFIG_NFT_SYNPROXY is not set -# CONFIG_NFT_TPROXY is not set -# CONFIG_NFT_TUNNEL is not set -# CONFIG_NFT_XFRM is not set -# CONFIG_NF_CONNTRACK is not set -# CONFIG_NF_CONNTRACK_AMANDA is not set -# CONFIG_NF_CONNTRACK_BRIDGE is not set -# CONFIG_NF_CONNTRACK_EVENTS is not set -# CONFIG_NF_CONNTRACK_FTP is not set -# CONFIG_NF_CONNTRACK_H323 is not set -# CONFIG_NF_CONNTRACK_IRC is not set -# CONFIG_NF_CONNTRACK_LABELS is not set -# CONFIG_NF_CONNTRACK_MARK is not set -# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -# CONFIG_NF_CONNTRACK_PPTP is not set -CONFIG_NF_CONNTRACK_PROCFS=y -# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set -# CONFIG_NF_CONNTRACK_SANE is not set -# CONFIG_NF_CONNTRACK_SECMARK is not set -# CONFIG_NF_CONNTRACK_SIP is not set -# CONFIG_NF_CONNTRACK_SNMP is not set -# CONFIG_NF_CONNTRACK_TFTP is not set -# CONFIG_NF_CONNTRACK_TIMEOUT is not set -# CONFIG_NF_CONNTRACK_TIMESTAMP is not set -# CONFIG_NF_CONNTRACK_ZONES is not set -# CONFIG_NF_CT_NETLINK is not set -# CONFIG_NF_CT_NETLINK_HELPER is not set -# CONFIG_NF_CT_NETLINK_TIMEOUT is not set -# CONFIG_NF_CT_PROTO_DCCP is not set -# CONFIG_NF_CT_PROTO_GRE is not set -# CONFIG_NF_CT_PROTO_SCTP is not set -# CONFIG_NF_CT_PROTO_UDPLITE is not set -# CONFIG_NF_DEFRAG_IPV4 is not set -# CONFIG_NF_DUP_IPV4 is not set -# CONFIG_NF_DUP_IPV6 is not set -# CONFIG_NF_FLOW_TABLE is not set -# CONFIG_NF_FLOW_TABLE_PROCFS is not set -# CONFIG_NF_LOG_ARP is not set -# CONFIG_NF_LOG_BRIDGE is not set -# CONFIG_NF_LOG_IPV4 is not set -# CONFIG_NF_LOG_NETDEV is not set -# CONFIG_NF_LOG_SYSLOG is not set -# CONFIG_NF_NAT is not set -# CONFIG_NF_NAT_AMANDA is not set -# CONFIG_NF_NAT_FTP is not set -# CONFIG_NF_NAT_H323 is not set -# CONFIG_NF_NAT_IRC is not set -# CONFIG_NF_NAT_NEEDED is not set -# CONFIG_NF_NAT_PPTP is not set -# CONFIG_NF_NAT_PROTO_GRE is not set -# CONFIG_NF_NAT_SIP is not set -# CONFIG_NF_NAT_SNMP_BASIC is not set -# CONFIG_NF_NAT_TFTP is not set -# CONFIG_NF_REJECT_IPV4 is not set -# CONFIG_NF_REJECT_IPV6 is not set -# CONFIG_NF_SOCKET_IPV4 is not set -# CONFIG_NF_SOCKET_IPV6 is not set -# CONFIG_NF_TABLES is not set -CONFIG_NF_TABLES_ARP=y -CONFIG_NF_TABLES_BRIDGE=y -CONFIG_NF_TABLES_INET=y -CONFIG_NF_TABLES_IPV4=y -CONFIG_NF_TABLES_IPV6=y -CONFIG_NF_TABLES_NETDEV=y -# CONFIG_NF_TABLES_SET is not set -# CONFIG_NF_TPROXY_IPV4 is not set -# CONFIG_NF_TPROXY_IPV6 is not set -# CONFIG_NGBE is not set -# CONFIG_NI65 is not set -# CONFIG_NI903X_WDT is not set -# CONFIG_NIC7018_WDT is not set -# CONFIG_NILFS2_FS is not set -# CONFIG_NIU is not set -# CONFIG_NI_XGE_MANAGEMENT_ENET is not set -CONFIG_NLATTR=y -# CONFIG_NLMON is not set -# CONFIG_NLM_XLP_BOARD is not set -# CONFIG_NLM_XLR_BOARD is not set -# CONFIG_NLS is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_MAC_CELTIC is not set -# CONFIG_NLS_MAC_CENTEURO is not set -# CONFIG_NLS_MAC_CROATIAN is not set -# CONFIG_NLS_MAC_CYRILLIC is not set -# CONFIG_NLS_MAC_GAELIC is not set -# CONFIG_NLS_MAC_GREEK is not set -# CONFIG_NLS_MAC_ICELAND is not set -# CONFIG_NLS_MAC_INUIT is not set -# CONFIG_NLS_MAC_ROMAN is not set -# CONFIG_NLS_MAC_ROMANIAN is not set -# CONFIG_NLS_MAC_TURKISH is not set -# CONFIG_NLS_UTF8 is not set -CONFIG_NMI_LOG_BUF_SHIFT=13 -# CONFIG_NOA1305 is not set -# CONFIG_NOP_USB_XCEIV is not set -# CONFIG_NORTEL_HERMES is not set -# CONFIG_NOTIFIER_ERROR_INJECTION is not set -# CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT is not set -# CONFIG_NOZOMI is not set -# CONFIG_NO_BOOTMEM is not set -# CONFIG_NO_HZ is not set -# CONFIG_NO_HZ_FULL is not set -# CONFIG_NO_HZ_IDLE is not set -# CONFIG_NS83820 is not set -# CONFIG_NTB is not set -# CONFIG_NTFS3_64BIT_CLUSTER is not set -# CONFIG_NTFS3_FS is not set -# CONFIG_NTFS3_FS_POSIX_ACL is not set -# CONFIG_NTFS3_LZX_XPRESS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_NTP_PPS is not set -# CONFIG_NULL_TTY is not set -# CONFIG_NUMA is not set -# CONFIG_NVIDIA_CARMEL_CNP_ERRATUM is not set -# CONFIG_NVM is not set -# CONFIG_NVMEM is not set -# CONFIG_NVMEM_BCM_OCOTP is not set -# CONFIG_NVMEM_IMX_OCOTP is not set -# CONFIG_NVMEM_LAYOUT_ONIE_TLV is not set -# CONFIG_NVMEM_LAYOUT_SL28_VPD is not set -# CONFIG_NVMEM_LAYOUT_U_BOOT_ENV is not set -# CONFIG_NVMEM_REBOOT_MODE is not set -# CONFIG_NVMEM_RMEM is not set -# CONFIG_NVMEM_SYSFS is not set -# CONFIG_NVMEM_U_BOOT_ENV is not set -# CONFIG_NVME_AUTH is not set -# CONFIG_NVME_FC is not set -# CONFIG_NVME_TARGET is not set -# CONFIG_NVME_TCP is not set -# CONFIG_NVME_VERBOSE_ERRORS is not set -# CONFIG_NVRAM is not set -# CONFIG_NV_TCO is not set -# CONFIG_NXP_C45_TJA11XX_PHY is not set -# CONFIG_NXP_STB220 is not set -# CONFIG_NXP_STB225 is not set -# CONFIG_NXP_TJA11XX_PHY is not set -# CONFIG_N_GSM is not set -# CONFIG_OABI_COMPAT is not set -# CONFIG_OBS600 is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_OCTEONTX2_AF is not set -# CONFIG_OCTEONTX2_PF is not set -# CONFIG_OCTEON_EP is not set -# CONFIG_OF_OVERLAY is not set -CONFIG_OF_RESERVED_MEM=y -# CONFIG_OF_UNITTEST is not set -# CONFIG_OID_REGISTRY is not set -# CONFIG_OMAP2_DSS_DEBUG is not set -# CONFIG_OMAP2_DSS_DEBUGFS is not set -# CONFIG_OMAP2_DSS_SDI is not set -# CONFIG_OMAP_OCP2SCP is not set -# CONFIG_OMAP_USB2 is not set -# CONFIG_OMFS_FS is not set -# CONFIG_OPENVSWITCH is not set -# CONFIG_OPEN_DICE is not set -# CONFIG_OPROFILE is not set -# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set -# CONFIG_OPT3001 is not set -CONFIG_OPTIMIZE_INLINING=y -# CONFIG_ORANGEFS_FS is not set -# CONFIG_ORION_WATCHDOG is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_OSNOISE_TRACER is not set -CONFIG_OVERLAY_FS=y -# CONFIG_OVERLAY_FS_INDEX is not set -# CONFIG_OVERLAY_FS_METACOPY is not set -CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y -# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set -CONFIG_OVERLAY_FS_XINO_AUTO=y -# CONFIG_OWL_LOADER is not set -# CONFIG_P54_COMMON is not set -# CONFIG_PA12203001 is not set -CONFIG_PACKET=y -# CONFIG_PACKET_DIAG is not set -# CONFIG_PACKING is not set -# CONFIG_PAGE_EXTENSION is not set -# CONFIG_PAGE_OWNER is not set -# CONFIG_PAGE_POISONING is not set -# CONFIG_PAGE_POOL is not set -# CONFIG_PAGE_POOL_STATS is not set -# CONFIG_PAGE_REPORTING is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_32KB is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_64KB is not set -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_TABLE_CHECK is not set -# CONFIG_PALMAS_GPADC is not set -# CONFIG_PANASONIC_LAPTOP is not set -# CONFIG_PANEL is not set -CONFIG_PANIC_ON_OOPS=y -CONFIG_PANIC_ON_OOPS_VALUE=1 -CONFIG_PANIC_TIMEOUT=1 -# CONFIG_PANTHERLORD_FF is not set -# CONFIG_PARAVIRT is not set -# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -# CONFIG_PARPORT is not set -# CONFIG_PARPORT_1284 is not set -# CONFIG_PARPORT_AX88796 is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_PC is not set -CONFIG_PARTITION_ADVANCED=y -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARASAN_CF is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_ATP867X is not set -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CS5535 is not set -# CONFIG_PATA_CS5536 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IMX is not set -# CONFIG_PATA_ISAPNP is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_LEGACY is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NINJA32 is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_NS87415 is not set -# CONFIG_PATA_OCTEON_CF is not set -# CONFIG_PATA_OF_PLATFORM is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PCMCIA is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_PLATFORM is not set -# CONFIG_PATA_QDI is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RDC is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SCH is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_TOSHIBA is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -# CONFIG_PATA_WINBOND_VLB is not set -# CONFIG_PC104 is not set -# CONFIG_PC300TOO is not set -# CONFIG_PCCARD is not set -# CONFIG_PCH_DMA is not set -# CONFIG_PCH_GBE is not set -# CONFIG_PCH_PHUB is not set -# CONFIG_PCI is not set -# CONFIG_PCI200SYN is not set -# CONFIG_PCIEAER is not set -# CONFIG_PCIEAER_INJECT is not set -# CONFIG_PCIEASPM is not set -# CONFIG_PCIEPORTBUS is not set -# CONFIG_PCIE_AL is not set -# CONFIG_PCIE_ALTERA is not set -# CONFIG_PCIE_ARMADA_8K is not set -CONFIG_PCIE_BUS_DEFAULT=y -# CONFIG_PCIE_BUS_PEER2PEER is not set -# CONFIG_PCIE_BUS_PERFORMANCE is not set -# CONFIG_PCIE_BUS_SAFE is not set -# CONFIG_PCIE_BUS_TUNE_OFF is not set -# CONFIG_PCIE_BW is not set -# CONFIG_PCIE_CADENCE_HOST is not set -# CONFIG_PCIE_CADENCE_PLAT_HOST is not set -# CONFIG_PCIE_DPC is not set -# CONFIG_PCIE_DW_PLAT is not set -# CONFIG_PCIE_DW_PLAT_HOST is not set -# CONFIG_PCIE_ECRC is not set -# CONFIG_PCIE_IPROC is not set -# CONFIG_PCIE_KIRIN is not set -# CONFIG_PCIE_LAYERSCAPE_GEN4 is not set -# CONFIG_PCIE_MEDIATEK_GEN3 is not set -# CONFIG_PCIE_MICROCHIP_HOST is not set -# CONFIG_PCIE_PTM is not set -# CONFIG_PCIE_XILINX is not set -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_PCI_ATMEL is not set -# CONFIG_PCI_CNB20LE_QUIRK is not set -# CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set -# CONFIG_PCI_ENDPOINT is not set -# CONFIG_PCI_ENDPOINT_TEST is not set -# CONFIG_PCI_FTPCI100 is not set -# CONFIG_PCI_HERMES is not set -# CONFIG_PCI_HISI is not set -# CONFIG_PCI_HOST_GENERIC is not set -# CONFIG_PCI_HOST_THUNDER_ECAM is not set -# CONFIG_PCI_HOST_THUNDER_PEM is not set -# CONFIG_PCI_IOV is not set -# CONFIG_PCI_J721E_HOST is not set -# CONFIG_PCI_LAYERSCAPE is not set -# CONFIG_PCI_MESON is not set -# CONFIG_PCI_MSI is not set -# CONFIG_PCI_PASID is not set -# CONFIG_PCI_PF_STUB is not set -# CONFIG_PCI_PRI is not set -CONFIG_PCI_QUIRKS=y -# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set -# CONFIG_PCI_STUB is not set -# CONFIG_PCI_SW_SWITCHTEC is not set -CONFIG_PCI_SYSCALL=y -# CONFIG_PCI_V3_SEMI is not set -# CONFIG_PCI_XGENE is not set -# CONFIG_PCMCIA is not set -# CONFIG_PCMCIA_3C574 is not set -# CONFIG_PCMCIA_3C589 is not set -# CONFIG_PCMCIA_AHA152X is not set -# CONFIG_PCMCIA_ATMEL is not set -# CONFIG_PCMCIA_AXNET is not set -# CONFIG_PCMCIA_DEBUG is not set -# CONFIG_PCMCIA_FDOMAIN is not set -# CONFIG_PCMCIA_FMVJ18X is not set -# CONFIG_PCMCIA_HERMES is not set -# CONFIG_PCMCIA_LOAD_CIS is not set -# CONFIG_PCMCIA_NINJA_SCSI is not set -# CONFIG_PCMCIA_NMCLAN is not set -# CONFIG_PCMCIA_PCNET is not set -# CONFIG_PCMCIA_QLOGIC is not set -# CONFIG_PCMCIA_RAYCS is not set -# CONFIG_PCMCIA_SMC91C92 is not set -# CONFIG_PCMCIA_SPECTRUM is not set -# CONFIG_PCMCIA_SYM53C500 is not set -# CONFIG_PCMCIA_WL3501 is not set -# CONFIG_PCMCIA_XIRC2PS is not set -# CONFIG_PCMCIA_XIRCOM is not set -# CONFIG_PCNET32 is not set -CONFIG_PCP_BATCH_SCALE_MAX=5 -# CONFIG_PCPU_DEV_REFCNT is not set -# CONFIG_PCSPKR_PLATFORM is not set -# CONFIG_PCS_MTK_USXGMII is not set -# CONFIG_PCS_XPCS is not set -# CONFIG_PD6729 is not set -# CONFIG_PDA_POWER is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_PECI is not set -# CONFIG_PERCPU_STATS is not set -# CONFIG_PERCPU_TEST is not set -# CONFIG_PERF_EVENTS is not set -# CONFIG_PERF_EVENTS_AMD_POWER is not set -# CONFIG_PERSISTENT_KEYRINGS is not set -# CONFIG_PHANTOM is not set -# CONFIG_PHONET is not set -# CONFIG_PHYLIB is not set -# CONFIG_PHYLIB_LEDS is not set -# CONFIG_PHYS_ADDR_T_64BIT is not set -# CONFIG_PHY_BRCM_USB is not set -# CONFIG_PHY_CADENCE_DP is not set -# CONFIG_PHY_CADENCE_DPHY is not set -# CONFIG_PHY_CADENCE_DPHY_RX is not set -# CONFIG_PHY_CADENCE_SALVO is not set -# CONFIG_PHY_CADENCE_SIERRA is not set -# CONFIG_PHY_CADENCE_TORRENT is not set -# CONFIG_PHY_CAN_TRANSCEIVER is not set -# CONFIG_PHY_CPCAP_USB is not set -# CONFIG_PHY_EXYNOS_DP_VIDEO is not set -# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set -# CONFIG_PHY_FSL_IMX8MQ_USB is not set -# CONFIG_PHY_INGENIC_USB is not set -# CONFIG_PHY_INTEL_KEEMBAY_EMMC is not set -# CONFIG_PHY_LAN966X_SERDES is not set -# CONFIG_PHY_MAPPHONE_MDM6600 is not set -# CONFIG_PHY_MIXEL_MIPI_DPHY is not set -# CONFIG_PHY_MTK_HDMI is not set -# CONFIG_PHY_MTK_MIPI_DSI is not set -# CONFIG_PHY_MTK_XFI_TPHY is not set -# CONFIG_PHY_MVEBU_CP110_UTMI is not set -# CONFIG_PHY_OCELOT_SERDES is not set -# CONFIG_PHY_PISTACHIO_USB is not set -# CONFIG_PHY_PXA_28NM_HSIC is not set -# CONFIG_PHY_PXA_28NM_USB2 is not set -# CONFIG_PHY_QCOM_DWC3 is not set -# CONFIG_PHY_QCOM_USB_HS is not set -# CONFIG_PHY_QCOM_USB_HSIC is not set -# CONFIG_PHY_SAMSUNG_USB2 is not set -# CONFIG_PHY_TUSB1210 is not set -# CONFIG_PHY_XGENE is not set -# CONFIG_PI433 is not set -# CONFIG_PID_IN_CONTEXTIDR is not set -# CONFIG_PID_NS is not set -CONFIG_PINCONF=y -# CONFIG_PINCTRL is not set -# CONFIG_PINCTRL_AMD is not set -# CONFIG_PINCTRL_AXP209 is not set -# CONFIG_PINCTRL_BCM2712 is not set -# CONFIG_PINCTRL_CEDARFORK is not set -# CONFIG_PINCTRL_CY8C95X0 is not set -# CONFIG_PINCTRL_EXYNOS is not set -# CONFIG_PINCTRL_EXYNOS5440 is not set -# CONFIG_PINCTRL_ICELAKE is not set -# CONFIG_PINCTRL_INGENIC is not set -# CONFIG_PINCTRL_LPASS_LPI is not set -# CONFIG_PINCTRL_MCP23S08 is not set -# CONFIG_PINCTRL_MDM9607 is not set -# CONFIG_PINCTRL_MICROCHIP_SGPIO is not set -# CONFIG_PINCTRL_MSM8953 is not set -# CONFIG_PINCTRL_MSM8X74 is not set -# CONFIG_PINCTRL_MT6779 is not set -# CONFIG_PINCTRL_MT8167 is not set -# CONFIG_PINCTRL_MT8192 is not set -# CONFIG_PINCTRL_MT8195 is not set -# CONFIG_PINCTRL_MT8365 is not set -# CONFIG_PINCTRL_MTK_V2 is not set -# CONFIG_PINCTRL_OCELOT is not set -# CONFIG_PINCTRL_PISTACHIO is not set -# CONFIG_PINCTRL_RP1 is not set -# CONFIG_PINCTRL_SC7280 is not set -# CONFIG_PINCTRL_SC8180X is not set -# CONFIG_PINCTRL_SDX55 is not set -CONFIG_PINCTRL_SINGLE=y -# CONFIG_PINCTRL_SM6115 is not set -# CONFIG_PINCTRL_SM6125 is not set -# CONFIG_PINCTRL_SM8350 is not set -# CONFIG_PINCTRL_STMFX is not set -# CONFIG_PINCTRL_SX150X is not set -# CONFIG_PING is not set -CONFIG_PINMUX=y -# CONFIG_PKCS7_MESSAGE_PARSER is not set -# CONFIG_PL310_ERRATA_588369 is not set -# CONFIG_PL310_ERRATA_727915 is not set -# CONFIG_PL310_ERRATA_753970 is not set -# CONFIG_PL310_ERRATA_769419 is not set -# CONFIG_PL320_MBOX is not set -# CONFIG_PL330_DMA is not set -# CONFIG_PLATFORM_MHU is not set -# CONFIG_PLAT_SPEAR is not set -# CONFIG_PLIP is not set -# CONFIG_PLX_DMA is not set -# CONFIG_PLX_HERMES is not set -# CONFIG_PM is not set -# CONFIG_PMBUS is not set -# CONFIG_PMC_MSP is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_PMS7003 is not set -# CONFIG_PM_AUTOSLEEP is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_DEVFREQ is not set -# CONFIG_PM_USERSPACE_AUTOSLEEP is not set -# CONFIG_PM_WAKELOCKS is not set -# CONFIG_POSIX_MQUEUE is not set -CONFIG_POSIX_TIMERS=y -# CONFIG_POWERCAP is not set -# CONFIG_POWER_AVS is not set -# CONFIG_POWER_RESET is not set -# CONFIG_POWER_RESET_BRCMKONA is not set -# CONFIG_POWER_RESET_BRCMSTB is not set -# CONFIG_POWER_RESET_GPIO is not set -# CONFIG_POWER_RESET_GPIO_RESTART is not set -# CONFIG_POWER_RESET_LINKSTATION is not set -# CONFIG_POWER_RESET_LTC2952 is not set -# CONFIG_POWER_RESET_PIIX4_POWEROFF is not set -# CONFIG_POWER_RESET_QNAP is not set -# CONFIG_POWER_RESET_REGULATOR is not set -# CONFIG_POWER_RESET_RESTART is not set -# CONFIG_POWER_RESET_SYSCON is not set -# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set -# CONFIG_POWER_RESET_VERSATILE is not set -# CONFIG_POWER_RESET_XGENE is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_POWER_SUPPLY_HWMON is not set -# CONFIG_PPC4xx_GPIO is not set -# CONFIG_PPC_16K_PAGES is not set -# CONFIG_PPC_256K_PAGES is not set -CONFIG_PPC_4K_PAGES=y -# CONFIG_PPC_64K_PAGES is not set -# CONFIG_PPC_DISABLE_WERROR is not set -# CONFIG_PPC_EMULATED_STATS is not set -# CONFIG_PPC_EPAPR_HV_BYTECHAN is not set -# CONFIG_PPC_QUEUED_SPINLOCKS is not set -# CONFIG_PPP is not set -# CONFIG_PPPOATM is not set -# CONFIG_PPPOE is not set -# CONFIG_PPPOL2TP is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_DEFLATE is not set -CONFIG_PPP_FILTER=y -# CONFIG_PPP_MPPE is not set -CONFIG_PPP_MULTILINK=y -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPS is not set -# CONFIG_PPS_CLIENT_GPIO is not set -# CONFIG_PPS_CLIENT_KTIMER is not set -# CONFIG_PPS_CLIENT_LDISC is not set -# CONFIG_PPS_CLIENT_PARPORT is not set -# CONFIG_PPS_DEBUG is not set -# CONFIG_PPTP is not set -# CONFIG_PREEMPT is not set -# CONFIG_PREEMPTIRQ_DELAY_TEST is not set -# CONFIG_PREEMPTIRQ_EVENTS is not set -# CONFIG_PREEMPT_DYNAMIC is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PRESTERA is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_PRIME_NUMBERS is not set -CONFIG_PRINTK=y -# CONFIG_PRINTK_CALLER is not set -# CONFIG_PRINTK_INDEX is not set -CONFIG_PRINTK_NMI=y -CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 -# CONFIG_PRINTK_TIME is not set -CONFIG_PRINT_STACK_DEPTH=64 -# CONFIG_PRISM2_USB is not set -# CONFIG_PRISM54 is not set -# CONFIG_PROC_CHILDREN is not set -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -# CONFIG_PROC_PAGE_MONITOR is not set -# CONFIG_PROC_STRIPPED is not set -CONFIG_PROC_SYSCTL=y -# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILING is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_PROVE_RAW_LOCK_NESTING is not set -# CONFIG_PROVE_RCU is not set -# CONFIG_PROVE_RCU_LIST is not set -# CONFIG_PROVE_RCU_REPEATEDLY is not set -# CONFIG_PSAMPLE is not set -# CONFIG_PSB6970_PHY is not set -# CONFIG_PSE_CONTROLLER is not set -# CONFIG_PSI is not set -# CONFIG_PSTORE is not set -# CONFIG_PSTORE_842_COMPRESS is not set -# CONFIG_PSTORE_BLK is not set -# CONFIG_PSTORE_COMPRESS is not set -# CONFIG_PSTORE_CONSOLE is not set -CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240 -# CONFIG_PSTORE_DEFLATE_COMPRESS is not set -# CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT is not set -# CONFIG_PSTORE_FTRACE is not set -# CONFIG_PSTORE_LZ4HC_COMPRESS is not set -# CONFIG_PSTORE_LZ4_COMPRESS is not set -# CONFIG_PSTORE_LZO_COMPRESS is not set -# CONFIG_PSTORE_PMSG is not set -# CONFIG_PSTORE_RAM is not set -# CONFIG_PSTORE_ZSTD_COMPRESS is not set -# CONFIG_PTDUMP_DEBUGFS is not set -# CONFIG_PTP_1588_CLOCK is not set -# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set -# CONFIG_PTP_1588_CLOCK_IDTCM is not set -# CONFIG_PTP_1588_CLOCK_IXP46X is not set -# CONFIG_PTP_1588_CLOCK_KVM is not set -# CONFIG_PTP_1588_CLOCK_OCP is not set -# CONFIG_PTP_1588_CLOCK_PCH is not set -# CONFIG_PTP_1588_CLOCK_VMW is not set -# CONFIG_PUBLIC_KEY_ALGO_RSA is not set -# CONFIG_PVPANIC is not set -# CONFIG_PWM is not set -# CONFIG_PWM_ATMEL_TCB is not set -# CONFIG_PWM_CLK is not set -# CONFIG_PWM_DEBUG is not set -# CONFIG_PWM_DWC is not set -# CONFIG_PWM_FSL_FTM is not set -# CONFIG_PWM_IMG is not set -# CONFIG_PWM_JZ4740 is not set -# CONFIG_PWM_MEDIATEK is not set -# CONFIG_PWM_PCA9685 is not set -# CONFIG_PWM_RASPBERRYPI_POE is not set -# CONFIG_PWM_RP1 is not set -# CONFIG_PWM_XILINX is not set -CONFIG_PWRSEQ_EMMC=y -# CONFIG_PWRSEQ_SD8787 is not set -CONFIG_PWRSEQ_SIMPLE=y -# CONFIG_QCA7000 is not set -# CONFIG_QCA7000_SPI is not set -# CONFIG_QCA7000_UART is not set -# CONFIG_QCA807X_PHY is not set -# CONFIG_QCA808X_PHY is not set -# CONFIG_QCA83XX_PHY is not set -# CONFIG_QCOM_A7PLL is not set -# CONFIG_QCOM_BAM_DMUX is not set -# CONFIG_QCOM_EMAC is not set -# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set -# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set -# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set -# CONFIG_QCOM_GPI_DMA is not set -# CONFIG_QCOM_HIDMA is not set -# CONFIG_QCOM_HIDMA_MGMT is not set -# CONFIG_QCOM_LMH is not set -# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set -# CONFIG_QCOM_SPMI_ADC5 is not set -# CONFIG_QCOM_SPMI_ADC_TM5 is not set -# CONFIG_QCOM_SPMI_IADC is not set -# CONFIG_QCOM_SPMI_TEMP_ALARM is not set -# CONFIG_QCOM_SPMI_VADC is not set -# CONFIG_QCOM_SSC_BLOCK_BUS is not set -# CONFIG_QED is not set -# CONFIG_QFMT_V1 is not set -# CONFIG_QLA3XXX is not set -# CONFIG_QLCNIC is not set -# CONFIG_QLGE is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX6FS_FS is not set -# CONFIG_QORIQ_CPUFREQ is not set -# CONFIG_QORIQ_THERMAL is not set -# CONFIG_QRTR is not set -# CONFIG_QRTR_MHI is not set -# CONFIG_QRTR_TUN is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_QUEUED_LOCK_STAT is not set -# CONFIG_QUICC_ENGINE is not set -# CONFIG_QUOTA is not set -# CONFIG_QUOTACTL is not set -# CONFIG_QUOTA_DEBUG is not set -# CONFIG_QUOTA_NETLINK_INTERFACE is not set -# CONFIG_R3964 is not set -# CONFIG_R6040 is not set -# CONFIG_R8169 is not set -# CONFIG_R8188EU is not set -# CONFIG_R8712U is not set -# CONFIG_R8723AU is not set -# CONFIG_RADIO_ADAPTERS is not set -# CONFIG_RADIO_AZTECH is not set -# CONFIG_RADIO_CADET is not set -# CONFIG_RADIO_GEMTEK is not set -# CONFIG_RADIO_MAXIRADIO is not set -# CONFIG_RADIO_RTRACK is not set -# CONFIG_RADIO_RTRACK2 is not set -# CONFIG_RADIO_SF16FMI is not set -# CONFIG_RADIO_SF16FMR2 is not set -# CONFIG_RADIO_TERRATEC is not set -# CONFIG_RADIO_TRUST is not set -# CONFIG_RADIO_TYPHOON is not set -# CONFIG_RADIO_ZOLTRIX is not set -# CONFIG_RAID6_PQ_BENCHMARK is not set -# CONFIG_RAID_ATTRS is not set -# CONFIG_RALINK is not set -# CONFIG_RANDOM32_SELFTEST is not set -# CONFIG_RANDOMIZE_BASE is not set -CONFIG_RANDOMIZE_KSTACK_OFFSET=y -# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set -CONFIG_RANDOM_TRUST_BOOTLOADER=y -CONFIG_RANDOM_TRUST_CPU=y -# CONFIG_RANDSTRUCT_NONE is not set -# CONFIG_RAPIDIO is not set -# CONFIG_RAS is not set -# CONFIG_RASPBERRYPI_GPIOMEM is not set -# CONFIG_RBTREE_TEST is not set -# CONFIG_RCU_BOOST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=60 -# CONFIG_RCU_EQS_DEBUG is not set -# CONFIG_RCU_EXPEDITE_BOOT is not set -# CONFIG_RCU_EXPERT is not set -CONFIG_RCU_EXP_CPU_STALL_TIMEOUT=0 -CONFIG_RCU_KTHREAD_PRIO=0 -CONFIG_RCU_NEED_SEGCBLIST=y -# CONFIG_RCU_PERF_TEST is not set -# CONFIG_RCU_REF_SCALE_TEST is not set -# CONFIG_RCU_SCALE_TEST is not set -CONFIG_RCU_STALL_COMMON=y -# CONFIG_RCU_STRICT_GRACE_PERIOD is not set -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 -# CONFIG_RCU_TRACE is not set -# CONFIG_RC_ATI_REMOTE is not set -# CONFIG_RC_CORE is not set -# CONFIG_RC_DECODERS is not set -# CONFIG_RC_LOOPBACK is not set -# CONFIG_RC_MAP is not set -# CONFIG_RC_XBOX_DVD is not set -# CONFIG_RDS is not set -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_GZIP is not set -# CONFIG_RD_LZ4 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_LZO is not set -# CONFIG_RD_XZ is not set -# CONFIG_RD_ZSTD is not set -# CONFIG_READABLE_ASM is not set -# CONFIG_READ_ONLY_THP_FOR_FS is not set -# CONFIG_REALTEK_PHY is not set -# CONFIG_REDWOOD is not set -# CONFIG_REED_SOLOMON is not set -# CONFIG_REED_SOLOMON_DEC8 is not set -# CONFIG_REED_SOLOMON_ENC8 is not set -# CONFIG_REED_SOLOMON_TEST is not set -# CONFIG_REGMAP is not set -# CONFIG_REGMAP_I2C is not set -# CONFIG_REGMAP_MMIO is not set -# CONFIG_REGMAP_SPI is not set -# CONFIG_REGULATOR is not set -# CONFIG_REGULATOR_88PG86X is not set -# CONFIG_REGULATOR_ACT8865 is not set -# CONFIG_REGULATOR_AD5398 is not set -# CONFIG_REGULATOR_ANATOP is not set -# CONFIG_REGULATOR_DA9121 is not set -# CONFIG_REGULATOR_DA9210 is not set -# CONFIG_REGULATOR_DA9211 is not set -# CONFIG_REGULATOR_DEBUG is not set -# CONFIG_REGULATOR_FAN53555 is not set -# CONFIG_REGULATOR_FAN53880 is not set -# CONFIG_REGULATOR_FIXED_VOLTAGE is not set -# CONFIG_REGULATOR_GPIO is not set -# CONFIG_REGULATOR_ISL6271A is not set -# CONFIG_REGULATOR_ISL9305 is not set -# CONFIG_REGULATOR_LP3971 is not set -# CONFIG_REGULATOR_LP3972 is not set -# CONFIG_REGULATOR_LP872X is not set -# CONFIG_REGULATOR_LP8755 is not set -# CONFIG_REGULATOR_LTC3589 is not set -# CONFIG_REGULATOR_LTC3676 is not set -# CONFIG_REGULATOR_MAX1586 is not set -# CONFIG_REGULATOR_MAX20086 is not set -# CONFIG_REGULATOR_MAX77620 is not set -# CONFIG_REGULATOR_MAX77826 is not set -# CONFIG_REGULATOR_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8893 is not set -# CONFIG_REGULATOR_MAX8952 is not set -# CONFIG_REGULATOR_MAX8973 is not set -# CONFIG_REGULATOR_MCP16502 is not set -# CONFIG_REGULATOR_MP5416 is not set -# CONFIG_REGULATOR_MP8859 is not set -# CONFIG_REGULATOR_MP886X is not set -# CONFIG_REGULATOR_MPQ7920 is not set -# CONFIG_REGULATOR_MT6311 is not set -# CONFIG_REGULATOR_MT6315 is not set -# CONFIG_REGULATOR_MT6359 is not set -# CONFIG_REGULATOR_PCA9450 is not set -# CONFIG_REGULATOR_PF8X00 is not set -# CONFIG_REGULATOR_PFUZE100 is not set -# CONFIG_REGULATOR_PV88060 is not set -# CONFIG_REGULATOR_PV88080 is not set -# CONFIG_REGULATOR_PV88090 is not set -# CONFIG_REGULATOR_PWM is not set -# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set -# CONFIG_REGULATOR_RT4801 is not set -# CONFIG_REGULATOR_RT5190A is not set -# CONFIG_REGULATOR_RT5759 is not set -# CONFIG_REGULATOR_RT6160 is not set -# CONFIG_REGULATOR_RT6245 is not set -# CONFIG_REGULATOR_RTMV20 is not set -# CONFIG_REGULATOR_RTQ2134 is not set -# CONFIG_REGULATOR_RTQ6752 is not set -# CONFIG_REGULATOR_SLG51000 is not set -# CONFIG_REGULATOR_SY8106A is not set -# CONFIG_REGULATOR_SY8824X is not set -# CONFIG_REGULATOR_SY8827N is not set -# CONFIG_REGULATOR_TI_ABB is not set -# CONFIG_REGULATOR_TPS51632 is not set -# CONFIG_REGULATOR_TPS62360 is not set -# CONFIG_REGULATOR_TPS6286X is not set -# CONFIG_REGULATOR_TPS65023 is not set -# CONFIG_REGULATOR_TPS6507X is not set -# CONFIG_REGULATOR_TPS65132 is not set -# CONFIG_REGULATOR_TPS6524X is not set -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -# CONFIG_REGULATOR_VCTRL is not set -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_FS_POSIX_ACL is not set -# CONFIG_REISERFS_FS_SECURITY is not set -CONFIG_REISERFS_FS_XATTR=y -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_RELAY is not set -# CONFIG_RELOCATABLE is not set -CONFIG_RELR=y -# CONFIG_REMOTEPROC is not set -# CONFIG_RENESAS_PHY is not set -# CONFIG_RESET_ATH79 is not set -# CONFIG_RESET_BERLIN is not set -# CONFIG_RESET_BRCMSTB is not set -# CONFIG_RESET_BRCMSTB_RESCAL is not set -# CONFIG_RESET_CONTROLLER is not set -# CONFIG_RESET_IMX7 is not set -# CONFIG_RESET_INTEL_GW is not set -# CONFIG_RESET_LANTIQ is not set -# CONFIG_RESET_LPC18XX is not set -# CONFIG_RESET_MESON is not set -# CONFIG_RESET_PISTACHIO is not set -# CONFIG_RESET_SIMPLE is not set -# CONFIG_RESET_SOCFPGA is not set -# CONFIG_RESET_STM32 is not set -# CONFIG_RESET_SUNXI is not set -# CONFIG_RESET_TEGRA_BPMP is not set -# CONFIG_RESET_TI_SYSCON is not set -# CONFIG_RESET_TI_TPS380X is not set -# CONFIG_RESET_ZYNQ is not set -# CONFIG_RFD77402 is not set -# CONFIG_RFD_FTL is not set -CONFIG_RFKILL=y -# CONFIG_RFKILL_FULL is not set -# CONFIG_RFKILL_GPIO is not set -# CONFIG_RFKILL_INPUT is not set -# CONFIG_RFKILL_LEDS is not set -# CONFIG_RFKILL_REGULATOR is not set -# CONFIG_RICHTEK_RTQ6056 is not set -# CONFIG_RING_BUFFER_BENCHMARK is not set -# CONFIG_RING_BUFFER_STARTUP_TEST is not set -# CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS is not set -# CONFIG_RISCV_PMU is not set -# CONFIG_RISCV_PMU_LEGACY is not set -# CONFIG_RISCV_PMU_SBI is not set -# CONFIG_RMI4_CORE is not set -# CONFIG_RMNET is not set -# CONFIG_ROCKCHIP_PHY is not set -# CONFIG_ROCKER is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_ROSE is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPMSG_QCOM_GLINK_RPM is not set -# CONFIG_RPMSG_VIRTIO is not set -# CONFIG_RPMSG_WWAN_CTRL is not set -# CONFIG_RPR0521 is not set -# CONFIG_RSEQ is not set -# CONFIG_RT2X00 is not set -# CONFIG_RTC_CLASS is not set -# CONFIG_RTC_DEBUG is not set -# CONFIG_RTC_DRV_ABB5ZES3 is not set -# CONFIG_RTC_DRV_ABEOZ9 is not set -# CONFIG_RTC_DRV_ABX80X is not set -# CONFIG_RTC_DRV_ARMADA38X is not set -# CONFIG_RTC_DRV_AU1XXX is not set -# CONFIG_RTC_DRV_BQ32K is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_CADENCE is not set -CONFIG_RTC_DRV_CMOS=y -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1302 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1307_CENTURY is not set -# CONFIG_RTC_DRV_DS1307_HWMON is not set -# CONFIG_RTC_DRV_DS1343 is not set -# CONFIG_RTC_DRV_DS1347 is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS1685_FAMILY is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_DS2404 is not set -# CONFIG_RTC_DRV_DS3232 is not set -# CONFIG_RTC_DRV_DS3234 is not set -# CONFIG_RTC_DRV_EM3027 is not set -# CONFIG_RTC_DRV_EP93XX is not set -# CONFIG_RTC_DRV_FM3130 is not set -# CONFIG_RTC_DRV_FTRTC010 is not set -# CONFIG_RTC_DRV_GENERIC is not set -# CONFIG_RTC_DRV_GOLDFISH is not set -# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set -# CONFIG_RTC_DRV_HYM8563 is not set -# CONFIG_RTC_DRV_ISL12022 is not set -# CONFIG_RTC_DRV_ISL12026 is not set -# CONFIG_RTC_DRV_ISL12057 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_JZ4740 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_M41T93 is not set -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_MAX6916 is not set -# CONFIG_RTC_DRV_MAX77686 is not set -# CONFIG_RTC_DRV_MCP795 is not set -# CONFIG_RTC_DRV_MOXART is not set -# CONFIG_RTC_DRV_MPC5121 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_MT2712 is not set -# CONFIG_RTC_DRV_NCT3018Y is not set -# CONFIG_RTC_DRV_OMAP is not set -# CONFIG_RTC_DRV_PCF2123 is not set -# CONFIG_RTC_DRV_PCF2127 is not set -# CONFIG_RTC_DRV_PCF85063 is not set -# CONFIG_RTC_DRV_PCF8523 is not set -# CONFIG_RTC_DRV_PCF85363 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_PL030 is not set -# CONFIG_RTC_DRV_PL031 is not set -# CONFIG_RTC_DRV_PS3 is not set -# CONFIG_RTC_DRV_PT7C4338 is not set -# CONFIG_RTC_DRV_R7301 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_RTC7301 is not set -# CONFIG_RTC_DRV_RV3028 is not set -# CONFIG_RTC_DRV_RV3029C2 is not set -# CONFIG_RTC_DRV_RV3032 is not set -# CONFIG_RTC_DRV_RV8803 is not set -# CONFIG_RTC_DRV_RX4581 is not set -# CONFIG_RTC_DRV_RX6110 is not set -# CONFIG_RTC_DRV_RX8010 is not set -# CONFIG_RTC_DRV_RX8025 is not set -# CONFIG_RTC_DRV_RX8581 is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_SD3078 is not set -# CONFIG_RTC_DRV_SNVS is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_SUN6I is not set -# CONFIG_RTC_DRV_TEGRA is not set -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_XGENE is not set -# CONFIG_RTC_DRV_ZYNQMP is not set -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_LIB=y -# CONFIG_RTC_NVMEM is not set -CONFIG_RTC_SYSTOHC=y -CONFIG_RTC_SYSTOHC_DEVICE="rtc0" -# CONFIG_RTL8180 is not set -# CONFIG_RTL8187 is not set -# CONFIG_RTL8192E is not set -# CONFIG_RTL8192U is not set -# CONFIG_RTL8306_PHY is not set -# CONFIG_RTL8366RB_PHY is not set -# CONFIG_RTL8366S_PHY is not set -# CONFIG_RTL8366_SMI is not set -# CONFIG_RTL8366_SMI_DEBUG_FS is not set -# CONFIG_RTL8367B_PHY is not set -# CONFIG_RTL8367_PHY is not set -# CONFIG_RTLLIB is not set -# CONFIG_RTL_CARDS is not set -# CONFIG_RTS5208 is not set -CONFIG_RT_MUTEXES=y -# CONFIG_RUNTIME_DEBUG is not set -CONFIG_RUNTIME_TESTING_MENU=y -# CONFIG_RV is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_RXKAD=y -# CONFIG_S2IO is not set -# CONFIG_SAMPLES is not set -# CONFIG_SAMSUNG_LAPTOP is not set -# CONFIG_SATA_ACARD_AHCI is not set -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_AHCI_PLATFORM is not set -# CONFIG_SATA_DWC is not set -# CONFIG_SATA_DWC_OLD_DMA is not set -# CONFIG_SATA_FSL is not set -# CONFIG_SATA_HIGHBANK is not set -# CONFIG_SATA_HOST is not set -# CONFIG_SATA_INIC162X is not set -CONFIG_SATA_MOBILE_LPM_POLICY=0 -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_SATA_PMP is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_RCAR is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_SVW is not set -# CONFIG_SATA_SX4 is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_SBC_FITPC2_WATCHDOG is not set -CONFIG_SBITMAP=y -# CONFIG_SC92031 is not set -# CONFIG_SCA3000 is not set -# CONFIG_SCA3300 is not set -# CONFIG_SCACHE_DEBUGFS is not set -# CONFIG_SCC is not set -# CONFIG_SCD30_CORE is not set -# CONFIG_SCD4X is not set -# CONFIG_SCF_TORTURE_TEST is not set -# CONFIG_SCHEDSTATS is not set -# CONFIG_SCHED_AUTOGROUP is not set -# CONFIG_SCHED_CLUSTER is not set -# CONFIG_SCHED_DEBUG is not set -CONFIG_SCHED_HRTICK=y -# CONFIG_SCHED_MC is not set -CONFIG_SCHED_OMIT_FRAME_POINTER=y -# CONFIG_SCHED_SMT is not set -CONFIG_SCHED_STACK_END_CHECK=y -# CONFIG_SCHED_TRACER is not set -# CONFIG_SCR24X is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_3W_SAS is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_SCSI_BFA_FC is not set -# CONFIG_SCSI_BNX2X_FCOE is not set -# CONFIG_SCSI_BNX2_ISCSI is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CHELSIO_FCOE is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_CXGB3_ISCSI is not set -# CONFIG_SCSI_CXGB4_ISCSI is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_DH is not set -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_ESAS2R is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_FDOMAIN_PCI is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set -# CONFIG_SCSI_HISI_SAS is not set -# CONFIG_SCSI_HPSA is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_ISCI is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_LOGGING is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set -# CONFIG_SCSI_LPFC is not set -CONFIG_SCSI_MOD=y -# CONFIG_SCSI_MPI3MR is not set -# CONFIG_SCSI_MPT2SAS is not set -# CONFIG_SCSI_MPT3SAS is not set -# CONFIG_SCSI_MQ_DEFAULT is not set -# CONFIG_SCSI_MVSAS is not set -# CONFIG_SCSI_MVSAS_DEBUG is not set -# CONFIG_SCSI_MVUMI is not set -# CONFIG_SCSI_MYRB is not set -# CONFIG_SCSI_MYRS is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_OSD_INITIATOR is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PM8001 is not set -# CONFIG_SCSI_PMCRAID is not set -CONFIG_SCSI_PROC_FS=y -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -# CONFIG_SCSI_SMARTPQI is not set -# CONFIG_SCSI_SNIC is not set -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_SRP_ATTRS is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_UFSHCD is not set -# CONFIG_SCSI_ULTRASTOR is not set -# CONFIG_SCSI_VIRTIO is not set -# CONFIG_SCSI_WD719X is not set -# CONFIG_SC_CAMCC_7180 is not set -# CONFIG_SC_DISPCC_7280 is not set -# CONFIG_SC_GCC_7280 is not set -# CONFIG_SC_GCC_8180X is not set -# CONFIG_SC_GPUCC_7280 is not set -# CONFIG_SC_GPUCC_8280XP is not set -# CONFIG_SC_VIDEOCC_7280 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_SDIO_UART is not set -# CONFIG_SDM_GPUCC_660 is not set -# CONFIG_SDM_MMCC_660 is not set -# CONFIG_SDR_MAX2175 is not set -# CONFIG_SDR_PLATFORM_DRIVERS is not set -# CONFIG_SDX_GCC_55 is not set -# CONFIG_SD_ADC_MODULATOR is not set -# CONFIG_SECCOMP is not set -# CONFIG_SECCOMP_CACHE_DEBUG is not set -CONFIG_SECTION_MISMATCH_WARN_ONLY=y -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -# CONFIG_SECURITY_APPARMOR is not set -CONFIG_SECURITY_DMESG_RESTRICT=y -# CONFIG_SECURITY_LANDLOCK is not set -# CONFIG_SECURITY_LOADPIN is not set -# CONFIG_SECURITY_LOCKDOWN_LSM is not set -# CONFIG_SECURITY_NETWORK_XFRM is not set -# CONFIG_SECURITY_PATH is not set -# CONFIG_SECURITY_SAFESETID is not set -# CONFIG_SECURITY_SELINUX_AVC_STATS is not set -# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set -CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0 -# CONFIG_SECURITY_SELINUX_DEVELOP is not set -# CONFIG_SECURITY_SELINUX_DISABLE is not set -# CONFIG_SECURITY_SMACK is not set -# CONFIG_SECURITY_TOMOYO is not set -# CONFIG_SECURITY_YAMA is not set -CONFIG_SELECT_MEMORY_MODEL=y -# CONFIG_SENSEAIR_SUNRISE_CO2 is not set -# CONFIG_SENSIRION_SGP30 is not set -# CONFIG_SENSIRION_SGP40 is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ABITUGURU3 is not set -# CONFIG_SENSORS_ACPI_POWER is not set -# CONFIG_SENSORS_AD7314 is not set -# CONFIG_SENSORS_AD7414 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADC128D818 is not set -# CONFIG_SENSORS_ADCXX is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM1177 is not set -# CONFIG_SENSORS_ADM1266 is not set -# CONFIG_SENSORS_ADM1275 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADS1015 is not set -# CONFIG_SENSORS_ADS7828 is not set -# CONFIG_SENSORS_ADS7871 is not set -# CONFIG_SENSORS_ADT7310 is not set -# CONFIG_SENSORS_ADT7410 is not set -# CONFIG_SENSORS_ADT7411 is not set -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7475 is not set -# CONFIG_SENSORS_AHT10 is not set -# CONFIG_SENSORS_AMC6821 is not set -# CONFIG_SENSORS_APDS990X is not set -# CONFIG_SENSORS_APPLESMC is not set -# CONFIG_SENSORS_AQUACOMPUTER_D5NEXT is not set -# CONFIG_SENSORS_AS370 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ASC7621 is not set -# CONFIG_SENSORS_ASPEED is not set -# CONFIG_SENSORS_ATK0110 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_AXI_FAN_CONTROL is not set -# CONFIG_SENSORS_BEL_PFE is not set -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_BH1780 is not set -# CONFIG_SENSORS_BPA_RS600 is not set -# CONFIG_SENSORS_CORETEMP is not set -# CONFIG_SENSORS_CORSAIR_CPRO is not set -# CONFIG_SENSORS_CORSAIR_PSU is not set -# CONFIG_SENSORS_DELL_SMM is not set -# CONFIG_SENSORS_DELTA_AHE50DC_FAN is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_DPS920AB is not set -# CONFIG_SENSORS_DRIVETEMP is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_DS620 is not set -# CONFIG_SENSORS_EMC1403 is not set -# CONFIG_SENSORS_EMC2103 is not set -# CONFIG_SENSORS_EMC2305 is not set -# CONFIG_SENSORS_EMC6W201 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_FAM15H_POWER is not set -# CONFIG_SENSORS_FSCHMD is not set -# CONFIG_SENSORS_FSP_3Y is not set -# CONFIG_SENSORS_FTSTEUTATES is not set -# CONFIG_SENSORS_G760A is not set -# CONFIG_SENSORS_G762 is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_GPIO_FAN is not set -# CONFIG_SENSORS_GSC is not set -# CONFIG_SENSORS_HDAPS is not set -# CONFIG_SENSORS_HIH6130 is not set -# CONFIG_SENSORS_HMC5843 is not set -# CONFIG_SENSORS_HMC5843_I2C is not set -# CONFIG_SENSORS_HMC5843_SPI is not set -# CONFIG_SENSORS_HTU21 is not set -# CONFIG_SENSORS_I5500 is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_IBM_CFFPS is not set -# CONFIG_SENSORS_IIO_HWMON is not set -# CONFIG_SENSORS_INA209 is not set -# CONFIG_SENSORS_INA238 is not set -# CONFIG_SENSORS_INA2XX is not set -# CONFIG_SENSORS_INA3221 is not set -# CONFIG_SENSORS_INSPUR_IPSPS is not set -# CONFIG_SENSORS_IR35221 is not set -# CONFIG_SENSORS_IR36021 is not set -# CONFIG_SENSORS_IR38064 is not set -# CONFIG_SENSORS_IRPS5401 is not set -# CONFIG_SENSORS_ISL29018 is not set -# CONFIG_SENSORS_ISL29028 is not set -# CONFIG_SENSORS_ISL68137 is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_JC42 is not set -# CONFIG_SENSORS_K10TEMP is not set -# CONFIG_SENSORS_K8TEMP is not set -# CONFIG_SENSORS_LINEAGE is not set -# CONFIG_SENSORS_LIS3LV02D is not set -# CONFIG_SENSORS_LIS3_I2C is not set -# CONFIG_SENSORS_LIS3_SPI is not set -# CONFIG_SENSORS_LM25066 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM73 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_LM93 is not set -# CONFIG_SENSORS_LM95234 is not set -# CONFIG_SENSORS_LM95241 is not set -# CONFIG_SENSORS_LM95245 is not set -# CONFIG_SENSORS_LT7182S is not set -# CONFIG_SENSORS_LTC2945 is not set -# CONFIG_SENSORS_LTC2947_I2C is not set -# CONFIG_SENSORS_LTC2947_SPI is not set -# CONFIG_SENSORS_LTC2978 is not set -# CONFIG_SENSORS_LTC2990 is not set -# CONFIG_SENSORS_LTC2992 is not set -# CONFIG_SENSORS_LTC3815 is not set -# CONFIG_SENSORS_LTC4151 is not set -# CONFIG_SENSORS_LTC4215 is not set -# CONFIG_SENSORS_LTC4222 is not set -# CONFIG_SENSORS_LTC4245 is not set -# CONFIG_SENSORS_LTC4260 is not set -# CONFIG_SENSORS_LTC4261 is not set -# CONFIG_SENSORS_LTQ_CPUTEMP is not set -# CONFIG_SENSORS_MAX1111 is not set -# CONFIG_SENSORS_MAX127 is not set -# CONFIG_SENSORS_MAX15301 is not set -# CONFIG_SENSORS_MAX16064 is not set -# CONFIG_SENSORS_MAX16065 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX16601 is not set -# CONFIG_SENSORS_MAX1668 is not set -# CONFIG_SENSORS_MAX197 is not set -# CONFIG_SENSORS_MAX20730 is not set -# CONFIG_SENSORS_MAX20751 is not set -# CONFIG_SENSORS_MAX31722 is not set -# CONFIG_SENSORS_MAX31730 is not set -# CONFIG_SENSORS_MAX31760 is not set -# CONFIG_SENSORS_MAX31785 is not set -# CONFIG_SENSORS_MAX31790 is not set -# CONFIG_SENSORS_MAX34440 is not set -# CONFIG_SENSORS_MAX6620 is not set -# CONFIG_SENSORS_MAX6621 is not set -# CONFIG_SENSORS_MAX6639 is not set -# CONFIG_SENSORS_MAX6642 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_MAX6697 is not set -# CONFIG_SENSORS_MAX8688 is not set -# CONFIG_SENSORS_MCP3021 is not set -# CONFIG_SENSORS_MP2888 is not set -# CONFIG_SENSORS_MP2975 is not set -# CONFIG_SENSORS_MP5023 is not set -# CONFIG_SENSORS_MR75203 is not set -# CONFIG_SENSORS_NCT6683 is not set -# CONFIG_SENSORS_NCT6775 is not set -# CONFIG_SENSORS_NCT6775_I2C is not set -# CONFIG_SENSORS_NCT7802 is not set -# CONFIG_SENSORS_NCT7904 is not set -# CONFIG_SENSORS_NPCM7XX is not set -# CONFIG_SENSORS_NSA320 is not set -# CONFIG_SENSORS_NTC_THERMISTOR is not set -# CONFIG_SENSORS_NZXT_KRAKEN2 is not set -# CONFIG_SENSORS_NZXT_SMART2 is not set -# CONFIG_SENSORS_OCC_P8_I2C is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_PIM4328 is not set -# CONFIG_SENSORS_PLI1209BC is not set -# CONFIG_SENSORS_PM6764TR is not set -# CONFIG_SENSORS_PMBUS is not set -# CONFIG_SENSORS_POWR1220 is not set -# CONFIG_SENSORS_PWM_FAN is not set -# CONFIG_SENSORS_PXE1610 is not set -# CONFIG_SENSORS_Q54SJ108A2 is not set -# CONFIG_SENSORS_RM3100_I2C is not set -# CONFIG_SENSORS_RM3100_SPI is not set -# CONFIG_SENSORS_RP1_ADC is not set -# CONFIG_SENSORS_SBRMI is not set -# CONFIG_SENSORS_SBTSI is not set -# CONFIG_SENSORS_SCH5627 is not set -# CONFIG_SENSORS_SCH5636 is not set -# CONFIG_SENSORS_SCH56XX_COMMON is not set -# CONFIG_SENSORS_SHT15 is not set -# CONFIG_SENSORS_SHT21 is not set -# CONFIG_SENSORS_SHT3x is not set -# CONFIG_SENSORS_SHT4x is not set -# CONFIG_SENSORS_SHTC1 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMM665 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_STPDDC60 is not set -# CONFIG_SENSORS_STTS751 is not set -# CONFIG_SENSORS_TC654 is not set -# CONFIG_SENSORS_TC74 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_TMP102 is not set -# CONFIG_SENSORS_TMP103 is not set -# CONFIG_SENSORS_TMP108 is not set -# CONFIG_SENSORS_TMP401 is not set -# CONFIG_SENSORS_TMP421 is not set -# CONFIG_SENSORS_TMP464 is not set -# CONFIG_SENSORS_TMP513 is not set -# CONFIG_SENSORS_TPS23861 is not set -# CONFIG_SENSORS_TPS40422 is not set -# CONFIG_SENSORS_TPS53679 is not set -# CONFIG_SENSORS_TPS546D24 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_TSL2563 is not set -# CONFIG_SENSORS_UCD9000 is not set -# CONFIG_SENSORS_UCD9200 is not set -# CONFIG_SENSORS_VEXPRESS is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VIA_CPUTEMP is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83773G is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83795 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83L786NG is not set -# CONFIG_SENSORS_XDPE122 is not set -# CONFIG_SENSORS_XDPE152 is not set -# CONFIG_SENSORS_XGENE is not set -# CONFIG_SENSORS_ZL6100 is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_16550A_VARIANTS=y -# CONFIG_SERIAL_8250_ACCENT is not set -# CONFIG_SERIAL_8250_ASPEED_VUART is not set -# CONFIG_SERIAL_8250_BOCA is not set -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_CS is not set -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -CONFIG_SERIAL_8250_DMA=y -# CONFIG_SERIAL_8250_DW is not set -# CONFIG_SERIAL_8250_EM is not set -# CONFIG_SERIAL_8250_EXAR is not set -# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set -# CONFIG_SERIAL_8250_EXTENDED is not set -# CONFIG_SERIAL_8250_FINTEK is not set -# CONFIG_SERIAL_8250_FOURPORT is not set -# CONFIG_SERIAL_8250_HUB6 is not set -# CONFIG_SERIAL_8250_INGENIC is not set -# CONFIG_SERIAL_8250_LPSS is not set -# CONFIG_SERIAL_8250_MANY_PORTS is not set -# CONFIG_SERIAL_8250_MID is not set -# CONFIG_SERIAL_8250_MOXA is not set -CONFIG_SERIAL_8250_NR_UARTS=2 -# CONFIG_SERIAL_8250_PCI is not set -# CONFIG_SERIAL_8250_PERICOM is not set -# CONFIG_SERIAL_8250_RSA is not set -# CONFIG_SERIAL_8250_RT288X is not set -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -# CONFIG_SERIAL_AMBA_PL010 is not set -# CONFIG_SERIAL_AMBA_PL011 is not set -# CONFIG_SERIAL_ARC is not set -# CONFIG_SERIAL_BCM63XX is not set -# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_DEV_BUS is not set -CONFIG_SERIAL_EARLYCON=y -# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -# CONFIG_SERIAL_FSL_LINFLEXUART is not set -# CONFIG_SERIAL_FSL_LPUART is not set -# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set -# CONFIG_SERIAL_IFX6X60 is not set -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX310X is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_SERIAL_OF_PLATFORM is not set -# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set -# CONFIG_SERIAL_PCH_UART is not set -# CONFIG_SERIAL_RP2 is not set -# CONFIG_SERIAL_SC16IS7XX is not set -# CONFIG_SERIAL_SCCNXP is not set -# CONFIG_SERIAL_SH_SCI is not set -# CONFIG_SERIAL_SIFIVE is not set -# CONFIG_SERIAL_SPRD is not set -# CONFIG_SERIAL_STM32 is not set -# CONFIG_SERIAL_ST_ASC is not set -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_UARTLITE is not set -# CONFIG_SERIAL_XILINX_PS_UART is not set -# CONFIG_SERIO is not set -# CONFIG_SERIO_ALTERA_PS2 is not set -# CONFIG_SERIO_AMBAKMI is not set -# CONFIG_SERIO_APBPS2 is not set -# CONFIG_SERIO_ARC_PS2 is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_GPIO_PS2 is not set -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_LIBPS2 is not set -# CONFIG_SERIO_PARKBD is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_PS2MULT is not set -# CONFIG_SERIO_RAW is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_SUN4I_PS2 is not set -# CONFIG_SFC is not set -# CONFIG_SFC_FALCON is not set -# CONFIG_SFC_SIENA is not set -# CONFIG_SFI is not set -# CONFIG_SFP is not set -# CONFIG_SF_PDMA is not set -# CONFIG_SGETMASK_SYSCALL is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP28 is not set -# CONFIG_SGI_IP30 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SGI_MFD_IOC3 is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_SG_POOL is not set -# CONFIG_SG_SPLIT is not set -# CONFIG_SHADOW_CALL_STACK is not set -CONFIG_SHMEM=y -# CONFIG_SHRINKER_DEBUG is not set -# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set -# CONFIG_SH_ETH is not set -# CONFIG_SH_TIMER_CMT is not set -# CONFIG_SH_TIMER_MTU2 is not set -# CONFIG_SH_TIMER_TMU is not set -# CONFIG_SI1133 is not set -# CONFIG_SI1145 is not set -# CONFIG_SI7005 is not set -# CONFIG_SI7020 is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_SWARM is not set -CONFIG_SIGNALFD=y -# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set -# CONFIG_SIMPLE_GPIO is not set -# CONFIG_SIMPLE_PM_BUS is not set -# CONFIG_SIOX is not set -# CONFIG_SIS190 is not set -# CONFIG_SIS900 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SKY2_DEBUG is not set -# CONFIG_SLAB is not set -CONFIG_SLABINFO=y -CONFIG_SLAB_FREELIST_HARDENED=y -CONFIG_SLAB_FREELIST_RANDOM=y -CONFIG_SLAB_MERGE_DEFAULT=y -# CONFIG_SLHC is not set -# CONFIG_SLICOSS is not set -# CONFIG_SLIMBUS is not set -# CONFIG_SLIP is not set -# CONFIG_SLOB is not set -CONFIG_SLUB=y -CONFIG_SLUB_CPU_PARTIAL=y -# CONFIG_SLUB_DEBUG is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_SLUB_MEMCG_SYSFS_ON is not set -# CONFIG_SLUB_STATS is not set -# CONFIG_SMARTJOYPLUS_FF is not set -# CONFIG_SMB_SERVER is not set -# CONFIG_SMC911X is not set -# CONFIG_SMC9194 is not set -# CONFIG_SMC91X is not set -# CONFIG_SMP is not set -# CONFIG_SMSC911X is not set -# CONFIG_SMSC9420 is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_SMS_SDIO_DRV is not set -# CONFIG_SMS_USB_DRV is not set -# CONFIG_SM_CAMCC_8250 is not set -# CONFIG_SM_FTL is not set -# CONFIG_SM_GCC_6115 is not set -# CONFIG_SM_GCC_6125 is not set -# CONFIG_SM_GCC_6350 is not set -# CONFIG_SM_GCC_6375 is not set -# CONFIG_SM_GCC_8350 is not set -# CONFIG_SND is not set -# CONFIG_SND_AC97_POWER_SAVE is not set -# CONFIG_SND_AD1816A is not set -# CONFIG_SND_AD1848 is not set -# CONFIG_SND_AD1889 is not set -# CONFIG_SND_ADLIB is not set -# CONFIG_SND_ALI5451 is not set -# CONFIG_SND_ALOOP is not set -# CONFIG_SND_ALS100 is not set -# CONFIG_SND_ALS300 is not set -# CONFIG_SND_ALS4000 is not set -# CONFIG_SND_AMD_ACP_CONFIG is not set -# CONFIG_SND_ARM is not set -# CONFIG_SND_ASIHPI is not set -# CONFIG_SND_ATIIXP is not set -# CONFIG_SND_ATIIXP_MODEM is not set -# CONFIG_SND_ATMEL_AC97C is not set -# CONFIG_SND_ATMEL_SOC is not set -# CONFIG_SND_AU8810 is not set -# CONFIG_SND_AU8820 is not set -# CONFIG_SND_AU8830 is not set -# CONFIG_SND_AUDIO_GRAPH_CARD is not set -# CONFIG_SND_AUDIO_GRAPH_CARD2 is not set -# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set -# CONFIG_SND_AW2 is not set -# CONFIG_SND_AZT2320 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BCD2000 is not set -# CONFIG_SND_BCM2835 is not set -# CONFIG_SND_BCM63XX_I2S_WHISTLER is not set -# CONFIG_SND_BT87X is not set -# CONFIG_SND_CA0106 is not set -# CONFIG_SND_CMI8330 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_CS4231 is not set -# CONFIG_SND_CS4236 is not set -# CONFIG_SND_CS4281 is not set -# CONFIG_SND_CS46XX is not set -# CONFIG_SND_CS5530 is not set -# CONFIG_SND_CS5535AUDIO is not set -# CONFIG_SND_CTL_FAST_LOOKUP is not set -# CONFIG_SND_CTL_INPUT_VALIDATION is not set -# CONFIG_SND_CTXFI is not set -# CONFIG_SND_DARLA20 is not set -# CONFIG_SND_DARLA24 is not set -# CONFIG_SND_DEBUG is not set -# CONFIG_SND_DESIGNWARE_I2S is not set -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_DYNAMIC_MINORS is not set -# CONFIG_SND_ECHO3G is not set -# CONFIG_SND_EDMA_SOC is not set -# CONFIG_SND_EMU10K1 is not set -# CONFIG_SND_EMU10K1X is not set -# CONFIG_SND_EMU10K1_SEQ is not set -# CONFIG_SND_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_ES1688 is not set -# CONFIG_SND_ES18XX is not set -# CONFIG_SND_ES1938 is not set -# CONFIG_SND_ES1968 is not set -# CONFIG_SND_FIREWIRE is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_GINA20 is not set -# CONFIG_SND_GINA24 is not set -# CONFIG_SND_GUSCLASSIC is not set -# CONFIG_SND_GUSEXTREME is not set -# CONFIG_SND_GUSMAX is not set -# CONFIG_SND_HDA_CODEC_CS8409 is not set -# CONFIG_SND_HDA_INTEL is not set -# CONFIG_SND_HDA_INTEL_DETECT_DMIC is not set -# CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM is not set -CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 -CONFIG_SND_HDA_PREALLOC_SIZE=64 -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM is not set -# CONFIG_SND_HRTIMER is not set -# CONFIG_SND_HWDEP is not set -# CONFIG_SND_I2S_HI6210_I2S is not set -# CONFIG_SND_ICE1712 is not set -# CONFIG_SND_ICE1724 is not set -# CONFIG_SND_INDIGO is not set -# CONFIG_SND_INDIGODJ is not set -# CONFIG_SND_INDIGODJX is not set -# CONFIG_SND_INDIGOIO is not set -# CONFIG_SND_INDIGOIOX is not set -# CONFIG_SND_INTEL8X0 is not set -# CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_INTERWAVE is not set -# CONFIG_SND_INTERWAVE_STB is not set -# CONFIG_SND_ISA is not set -# CONFIG_SND_JZ4740_SOC_I2S is not set -# CONFIG_SND_KIRKWOOD_SOC is not set -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_LAYLA20 is not set -# CONFIG_SND_LAYLA24 is not set -# CONFIG_SND_LOLA is not set -# CONFIG_SND_LX6464ES is not set -# CONFIG_SND_MAESTRO3 is not set -CONFIG_SND_MAX_CARDS=16 -# CONFIG_SND_MIA is not set -# CONFIG_SND_MIPS is not set -# CONFIG_SND_MIRO is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_MONA is not set -# CONFIG_SND_MPC52xx_SOC_EFIKA is not set -# CONFIG_SND_MPU401 is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_MTS64 is not set -# CONFIG_SND_MXS_SOC is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_OPL3SA2 is not set -# CONFIG_SND_OPL3_LIB_SEQ is not set -# CONFIG_SND_OPL4_LIB_SEQ is not set -# CONFIG_SND_OPTI92X_AD1848 is not set -# CONFIG_SND_OPTI92X_CS4231 is not set -# CONFIG_SND_OPTI93X is not set -CONFIG_SND_OSSEMUL=y -# CONFIG_SND_OXYGEN is not set -CONFIG_SND_PCI=y -# CONFIG_SND_PCM is not set -# CONFIG_SND_PCMCIA is not set -# CONFIG_SND_PCM_OSS is not set -CONFIG_SND_PCM_OSS_PLUGINS=y -# CONFIG_SND_PCM_TIMER is not set -# CONFIG_SND_PCM_XRUN_DEBUG is not set -# CONFIG_SND_PCXHR is not set -# CONFIG_SND_PDAUDIOCF is not set -# CONFIG_SND_PORTMAN2X4 is not set -# CONFIG_SND_POWERPC_SOC is not set -# CONFIG_SND_PPC is not set -CONFIG_SND_PROC_FS=y -# CONFIG_SND_RAWMIDI is not set -# CONFIG_SND_RAWMIDI_SEQ is not set -# CONFIG_SND_RIPTIDE is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set -# CONFIG_SND_RTCTIMER is not set -# CONFIG_SND_SB16 is not set -# CONFIG_SND_SB8 is not set -# CONFIG_SND_SBAWE is not set -# CONFIG_SND_SBAWE_SEQ is not set -# CONFIG_SND_SE6X is not set -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_SERIAL_GENERIC is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_SIMPLE_CARD is not set -# CONFIG_SND_SIMPLE_SCU_CARD is not set -# CONFIG_SND_SIS7019 is not set -# CONFIG_SND_SOC is not set -# CONFIG_SND_SOC_AC97_CODEC is not set -# CONFIG_SND_SOC_AD193X_I2C is not set -# CONFIG_SND_SOC_AD193X_SPI is not set -# CONFIG_SND_SOC_ADAU1372_I2C is not set -# CONFIG_SND_SOC_ADAU1372_SPI is not set -# CONFIG_SND_SOC_ADAU1701 is not set -# CONFIG_SND_SOC_ADAU1761_I2C is not set -# CONFIG_SND_SOC_ADAU1761_SPI is not set -# CONFIG_SND_SOC_ADAU7002 is not set -# CONFIG_SND_SOC_ADAU7118_HW is not set -# CONFIG_SND_SOC_ADAU7118_I2C is not set -# CONFIG_SND_SOC_ADI is not set -# CONFIG_SND_SOC_AK4104 is not set -# CONFIG_SND_SOC_AK4118 is not set -# CONFIG_SND_SOC_AK4375 is not set -# CONFIG_SND_SOC_AK4458 is not set -# CONFIG_SND_SOC_AK4554 is not set -# CONFIG_SND_SOC_AK4613 is not set -# CONFIG_SND_SOC_AK4642 is not set -# CONFIG_SND_SOC_AK5386 is not set -# CONFIG_SND_SOC_AK5558 is not set -# CONFIG_SND_SOC_ALC5623 is not set -# CONFIG_SND_SOC_AMD_ACP is not set -# CONFIG_SND_SOC_AMD_ACP3x is not set -# CONFIG_SND_SOC_AMD_ACP5x is not set -# CONFIG_SND_SOC_AMD_RENOIR is not set -# CONFIG_SND_SOC_AU1XAUDIO is not set -# CONFIG_SND_SOC_AU1XPSC is not set -# CONFIG_SND_SOC_AW8738 is not set -# CONFIG_SND_SOC_BD28623 is not set -# CONFIG_SND_SOC_BT_SCO is not set -# CONFIG_SND_SOC_CS35L32 is not set -# CONFIG_SND_SOC_CS35L33 is not set -# CONFIG_SND_SOC_CS35L34 is not set -# CONFIG_SND_SOC_CS35L35 is not set -# CONFIG_SND_SOC_CS35L36 is not set -# CONFIG_SND_SOC_CS35L41_I2C is not set -# CONFIG_SND_SOC_CS35L41_SPI is not set -# CONFIG_SND_SOC_CS35L45_I2C is not set -# CONFIG_SND_SOC_CS35L45_SPI is not set -# CONFIG_SND_SOC_CS4234 is not set -# CONFIG_SND_SOC_CS4265 is not set -# CONFIG_SND_SOC_CS4270 is not set -# CONFIG_SND_SOC_CS4271 is not set -# CONFIG_SND_SOC_CS4271_I2C is not set -# CONFIG_SND_SOC_CS4271_SPI is not set -# CONFIG_SND_SOC_CS42L42 is not set -# CONFIG_SND_SOC_CS42L51_I2C is not set -# CONFIG_SND_SOC_CS42L52 is not set -# CONFIG_SND_SOC_CS42L56 is not set -# CONFIG_SND_SOC_CS42L73 is not set -# CONFIG_SND_SOC_CS42L83 is not set -# CONFIG_SND_SOC_CS42XX8_I2C is not set -# CONFIG_SND_SOC_CS43130 is not set -# CONFIG_SND_SOC_CS4341 is not set -# CONFIG_SND_SOC_CS4349 is not set -# CONFIG_SND_SOC_CS53L30 is not set -# CONFIG_SND_SOC_CX2072X is not set -# CONFIG_SND_SOC_DA7213 is not set -# CONFIG_SND_SOC_DIO2125 is not set -# CONFIG_SND_SOC_DMIC is not set -# CONFIG_SND_SOC_ES7134 is not set -# CONFIG_SND_SOC_ES7241 is not set -# CONFIG_SND_SOC_ES8316 is not set -# CONFIG_SND_SOC_ES8326 is not set -# CONFIG_SND_SOC_ES8328 is not set -# CONFIG_SND_SOC_ES8328_I2C is not set -# CONFIG_SND_SOC_ES8328_SPI is not set -# CONFIG_SND_SOC_EUKREA_TLV320 is not set -# CONFIG_SND_SOC_FSL_ASOC_CARD is not set -# CONFIG_SND_SOC_FSL_ASRC is not set -# CONFIG_SND_SOC_FSL_AUD2HTX is not set -# CONFIG_SND_SOC_FSL_AUDMIX is not set -# CONFIG_SND_SOC_FSL_ESAI is not set -# CONFIG_SND_SOC_FSL_MICFIL is not set -# CONFIG_SND_SOC_FSL_RPMSG is not set -# CONFIG_SND_SOC_FSL_SAI is not set -# CONFIG_SND_SOC_FSL_SPDIF is not set -# CONFIG_SND_SOC_FSL_SSI is not set -# CONFIG_SND_SOC_FSL_XCVR is not set -# CONFIG_SND_SOC_GTM601 is not set -# CONFIG_SND_SOC_HDA is not set -# CONFIG_SND_SOC_ICS43432 is not set -# CONFIG_SND_SOC_IMG is not set -# CONFIG_SND_SOC_IMX_AUDMIX is not set -# CONFIG_SND_SOC_IMX_AUDMUX is not set -# CONFIG_SND_SOC_IMX_CARD is not set -# CONFIG_SND_SOC_IMX_ES8328 is not set -# CONFIG_SND_SOC_IMX_HDMI is not set -# CONFIG_SND_SOC_IMX_RPMSG is not set -# CONFIG_SND_SOC_IMX_SPDIF is not set -# CONFIG_SND_SOC_IMX_WM8962 is not set -# CONFIG_SND_SOC_INNO_RK3036 is not set -# CONFIG_SND_SOC_INTEL_APL is not set -# CONFIG_SND_SOC_INTEL_BAYTRAIL is not set -# CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH is not set -# CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH is not set -# CONFIG_SND_SOC_INTEL_BXT_RT298_MACH is not set -# CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH is not set -# CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH is not set -# CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH is not set -# CONFIG_SND_SOC_INTEL_CATPT is not set -# CONFIG_SND_SOC_INTEL_CFL is not set -# CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH is not set -# CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH is not set -# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH is not set -# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH is not set -# CONFIG_SND_SOC_INTEL_CML_H is not set -# CONFIG_SND_SOC_INTEL_CML_LP is not set -# CONFIG_SND_SOC_INTEL_CNL is not set -# CONFIG_SND_SOC_INTEL_GLK is not set -# CONFIG_SND_SOC_INTEL_HASWELL is not set -# CONFIG_SND_SOC_INTEL_KBL is not set -# CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH is not set -# CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH is not set -# CONFIG_SND_SOC_INTEL_KEEMBAY is not set -# CONFIG_SND_SOC_INTEL_SKL is not set -# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH is not set -# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH is not set -# CONFIG_SND_SOC_INTEL_SKL_RT286_MACH is not set -# CONFIG_SND_SOC_INTEL_SKYLAKE is not set -# CONFIG_SND_SOC_INTEL_SST is not set -CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y -# CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES is not set -# CONFIG_SND_SOC_JZ4725B_CODEC is not set -# CONFIG_SND_SOC_JZ4740_CODEC is not set -# CONFIG_SND_SOC_JZ4770_CODEC is not set -# CONFIG_SND_SOC_LPASS_RX_MACRO is not set -# CONFIG_SND_SOC_LPASS_TX_MACRO is not set -# CONFIG_SND_SOC_LPASS_VA_MACRO is not set -# CONFIG_SND_SOC_LPASS_WSA_MACRO is not set -# CONFIG_SND_SOC_MA120X0P is not set -# CONFIG_SND_SOC_MAX9759 is not set -# CONFIG_SND_SOC_MAX98088 is not set -# CONFIG_SND_SOC_MAX98357A is not set -# CONFIG_SND_SOC_MAX98373 is not set -# CONFIG_SND_SOC_MAX98373_I2C is not set -# CONFIG_SND_SOC_MAX98390 is not set -# CONFIG_SND_SOC_MAX98396 is not set -# CONFIG_SND_SOC_MAX98504 is not set -# CONFIG_SND_SOC_MAX98520 is not set -# CONFIG_SND_SOC_MAX9860 is not set -# CONFIG_SND_SOC_MAX9867 is not set -# CONFIG_SND_SOC_MAX98927 is not set -# CONFIG_SND_SOC_MEDIATEK is not set -# CONFIG_SND_SOC_MPC5200_AC97 is not set -# CONFIG_SND_SOC_MPC5200_I2S is not set -# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set -# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set -# CONFIG_SND_SOC_MT2701 is not set -# CONFIG_SND_SOC_MT6351 is not set -# CONFIG_SND_SOC_MT6358 is not set -# CONFIG_SND_SOC_MT6359 is not set -# CONFIG_SND_SOC_MT6359_ACCDET is not set -# CONFIG_SND_SOC_MT6660 is not set -# CONFIG_SND_SOC_MT6797 is not set -# CONFIG_SND_SOC_MT8173 is not set -# CONFIG_SND_SOC_MT8183 is not set -# CONFIG_SND_SOC_MT8186 is not set -# CONFIG_SND_SOC_MT8192 is not set -# CONFIG_SND_SOC_MT8195 is not set -# CONFIG_SND_SOC_MTK_BTCVSD is not set -# CONFIG_SND_SOC_NAU8315 is not set -# CONFIG_SND_SOC_NAU8540 is not set -# CONFIG_SND_SOC_NAU8810 is not set -# CONFIG_SND_SOC_NAU8821 is not set -# CONFIG_SND_SOC_NAU8822 is not set -# CONFIG_SND_SOC_NAU8824 is not set -# CONFIG_SND_SOC_PCM1681 is not set -# CONFIG_SND_SOC_PCM1789_I2C is not set -# CONFIG_SND_SOC_PCM1792A is not set -# CONFIG_SND_SOC_PCM179X_I2C is not set -# CONFIG_SND_SOC_PCM179X_SPI is not set -# CONFIG_SND_SOC_PCM186X_I2C is not set -# CONFIG_SND_SOC_PCM186X_SPI is not set -# CONFIG_SND_SOC_PCM3060_I2C is not set -# CONFIG_SND_SOC_PCM3060_SPI is not set -# CONFIG_SND_SOC_PCM3168A_I2C is not set -# CONFIG_SND_SOC_PCM3168A_SPI is not set -# CONFIG_SND_SOC_PCM5102A is not set -# CONFIG_SND_SOC_PCM512x_I2C is not set -# CONFIG_SND_SOC_PCM512x_SPI is not set -# CONFIG_SND_SOC_QCOM is not set -# CONFIG_SND_SOC_RK3328 is not set -# CONFIG_SND_SOC_RK817 is not set -# CONFIG_SND_SOC_ROCKCHIP is not set -# CONFIG_SND_SOC_RT5616 is not set -# CONFIG_SND_SOC_RT5631 is not set -# CONFIG_SND_SOC_RT5640 is not set -# CONFIG_SND_SOC_RT5659 is not set -# CONFIG_SND_SOC_RT5677_SPI is not set -# CONFIG_SND_SOC_RT9120 is not set -# CONFIG_SND_SOC_SGTL5000 is not set -# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set -# CONFIG_SND_SOC_SIMPLE_MUX is not set -# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set -# CONFIG_SND_SOC_SOF_TOPLEVEL is not set -# CONFIG_SND_SOC_SPDIF is not set -# CONFIG_SND_SOC_SRC4XXX_I2C is not set -# CONFIG_SND_SOC_SSM2305 is not set -# CONFIG_SND_SOC_SSM2518 is not set -# CONFIG_SND_SOC_SSM2602_I2C is not set -# CONFIG_SND_SOC_SSM2602_SPI is not set -# CONFIG_SND_SOC_SSM4567 is not set -# CONFIG_SND_SOC_STA32X is not set -# CONFIG_SND_SOC_STA350 is not set -# CONFIG_SND_SOC_STI_SAS is not set -# CONFIG_SND_SOC_TAS2552 is not set -# CONFIG_SND_SOC_TAS2562 is not set -# CONFIG_SND_SOC_TAS2764 is not set -# CONFIG_SND_SOC_TAS2770 is not set -# CONFIG_SND_SOC_TAS2780 is not set -# CONFIG_SND_SOC_TAS5086 is not set -# CONFIG_SND_SOC_TAS571X is not set -# CONFIG_SND_SOC_TAS5720 is not set -# CONFIG_SND_SOC_TAS5805M is not set -# CONFIG_SND_SOC_TAS6424 is not set -# CONFIG_SND_SOC_TDA7419 is not set -# CONFIG_SND_SOC_TFA9879 is not set -# CONFIG_SND_SOC_TFA989X is not set -# CONFIG_SND_SOC_TLV320ADC3XXX is not set -# CONFIG_SND_SOC_TLV320ADCX140 is not set -# CONFIG_SND_SOC_TLV320AIC23_I2C is not set -# CONFIG_SND_SOC_TLV320AIC23_SPI is not set -# CONFIG_SND_SOC_TLV320AIC31XX is not set -# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set -# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set -# CONFIG_SND_SOC_TLV320AIC3X is not set -# CONFIG_SND_SOC_TLV320AIC3X_I2C is not set -# CONFIG_SND_SOC_TLV320AIC3X_SPI is not set -# CONFIG_SND_SOC_TPA6130A2 is not set -# CONFIG_SND_SOC_TS3A227E is not set -# CONFIG_SND_SOC_TSCS42XX is not set -# CONFIG_SND_SOC_TSCS454 is not set -# CONFIG_SND_SOC_UDA1334 is not set -# CONFIG_SND_SOC_WM8510 is not set -# CONFIG_SND_SOC_WM8523 is not set -# CONFIG_SND_SOC_WM8524 is not set -# CONFIG_SND_SOC_WM8580 is not set -# CONFIG_SND_SOC_WM8711 is not set -# CONFIG_SND_SOC_WM8728 is not set -# CONFIG_SND_SOC_WM8731 is not set -# CONFIG_SND_SOC_WM8731_I2C is not set -# CONFIG_SND_SOC_WM8731_SPI is not set -# CONFIG_SND_SOC_WM8737 is not set -# CONFIG_SND_SOC_WM8741 is not set -# CONFIG_SND_SOC_WM8750 is not set -# CONFIG_SND_SOC_WM8753 is not set -# CONFIG_SND_SOC_WM8770 is not set -# CONFIG_SND_SOC_WM8776 is not set -# CONFIG_SND_SOC_WM8782 is not set -# CONFIG_SND_SOC_WM8804_I2C is not set -# CONFIG_SND_SOC_WM8804_SPI is not set -# CONFIG_SND_SOC_WM8903 is not set -# CONFIG_SND_SOC_WM8904 is not set -# CONFIG_SND_SOC_WM8940 is not set -# CONFIG_SND_SOC_WM8960 is not set -# CONFIG_SND_SOC_WM8962 is not set -# CONFIG_SND_SOC_WM8974 is not set -# CONFIG_SND_SOC_WM8978 is not set -# CONFIG_SND_SOC_WM8985 is not set -# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set -# CONFIG_SND_SOC_XILINX_I2S is not set -# CONFIG_SND_SOC_XILINX_SPDIF is not set -# CONFIG_SND_SOC_XTFPGA_I2S is not set -# CONFIG_SND_SOC_ZL38060 is not set -# CONFIG_SND_SOC_ZX_AUD96P22 is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_SPI is not set -# CONFIG_SND_SSCAPE is not set -# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI is not set -# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI is not set -# CONFIG_SND_SUN4I_CODEC is not set -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_TEST_COMPONENT is not set -# CONFIG_SND_TIMER is not set -# CONFIG_SND_TRIDENT is not set -CONFIG_SND_USB=y -# CONFIG_SND_USB_6FIRE is not set -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_CAIAQ is not set -# CONFIG_SND_USB_HIFACE is not set -# CONFIG_SND_USB_POD is not set -# CONFIG_SND_USB_PODHD is not set -# CONFIG_SND_USB_TONEPORT is not set -# CONFIG_SND_USB_UA101 is not set -# CONFIG_SND_USB_US122L is not set -# CONFIG_SND_USB_USX2Y is not set -# CONFIG_SND_USB_VARIAX is not set -# CONFIG_SND_VERBOSE_PRINTK is not set -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VIA82XX is not set -# CONFIG_SND_VIA82XX_MODEM is not set -# CONFIG_SND_VIRTIO is not set -# CONFIG_SND_VIRTUOSO is not set -# CONFIG_SND_VX222 is not set -# CONFIG_SND_VXPOCKET is not set -# CONFIG_SND_WAVEFRONT is not set -CONFIG_SND_X86=y -# CONFIG_SND_XEN_FRONTEND is not set -# CONFIG_SND_YMFPCI is not set -# CONFIG_SNI_RM is not set -# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set -# CONFIG_SOCK_CGROUP_DATA is not set -# CONFIG_SOC_AM33XX is not set -# CONFIG_SOC_AM43XX is not set -# CONFIG_SOC_BRCMSTB is not set -# CONFIG_SOC_CAMERA is not set -# CONFIG_SOC_DRA7XX is not set -# CONFIG_SOC_HAS_OMAP2_SDRC is not set -# CONFIG_SOC_OMAP5 is not set -# CONFIG_SOC_TI is not set -# CONFIG_SOFTLOCKUP_DETECTOR is not set -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_SONYPI is not set -# CONFIG_SONY_LAPTOP is not set -# CONFIG_SOUND is not set -# CONFIG_SOUNDWIRE is not set -# CONFIG_SOUND_OSS_CORE is not set -# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set -# CONFIG_SOUND_PRIME is not set -# CONFIG_SP5100_TCO is not set -# CONFIG_SPARSEMEM_MANUAL is not set -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -# CONFIG_SPARSE_IRQ is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_SPEAKUP is not set -# CONFIG_SPI is not set -# CONFIG_SPINLOCK_TEST is not set -# CONFIG_SPI_ALTERA is not set -# CONFIG_SPI_AMD is not set -# CONFIG_SPI_AU1550 is not set -# CONFIG_SPI_AX88796C is not set -# CONFIG_SPI_AXI_SPI_ENGINE is not set -# CONFIG_SPI_BCM2835 is not set -# CONFIG_SPI_BCM63XX_HSSPI is not set -# CONFIG_SPI_BCM_QSPI is not set -# CONFIG_SPI_BITBANG is not set -# CONFIG_SPI_BUTTERFLY is not set -# CONFIG_SPI_CADENCE is not set -# CONFIG_SPI_CADENCE_QUADSPI is not set -# CONFIG_SPI_CADENCE_XSPI is not set -# CONFIG_SPI_DEBUG is not set -# CONFIG_SPI_DESIGNWARE is not set -# CONFIG_SPI_FSL_DSPI is not set -# CONFIG_SPI_FSL_ESPI is not set -# CONFIG_SPI_FSL_SPI is not set -# CONFIG_SPI_GPIO is not set -# CONFIG_SPI_GPIO_OLD is not set -# CONFIG_SPI_IMG_SPFI is not set -# CONFIG_SPI_LANTIQ_SSC is not set -# CONFIG_SPI_LM70_LLP is not set -# CONFIG_SPI_LOOPBACK_TEST is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_SPI_MEM is not set -# CONFIG_SPI_MICROCHIP_CORE is not set -# CONFIG_SPI_MICROCHIP_CORE_QSPI is not set -# CONFIG_SPI_MPC52xx is not set -# CONFIG_SPI_MPC52xx_PSC is not set -# CONFIG_SPI_MTK_QUADSPI is not set -# CONFIG_SPI_MUX is not set -# CONFIG_SPI_MXIC is not set -# CONFIG_SPI_NXP_FLEXSPI is not set -# CONFIG_SPI_OCTEON is not set -# CONFIG_SPI_OC_TINY is not set -# CONFIG_SPI_ORION is not set -# CONFIG_SPI_PL022 is not set -# CONFIG_SPI_PPC4xx is not set -# CONFIG_SPI_PXA2XX is not set -# CONFIG_SPI_PXA2XX_PCI is not set -# CONFIG_SPI_QCOM_QSPI is not set -# CONFIG_SPI_ROCKCHIP is not set -# CONFIG_SPI_S3C64XX is not set -# CONFIG_SPI_SC18IS602 is not set -# CONFIG_SPI_SIFIVE is not set -# CONFIG_SPI_SLAVE is not set -# CONFIG_SPI_SPIDEV is not set -# CONFIG_SPI_THUNDERX is not set -# CONFIG_SPI_TI_QSPI is not set -# CONFIG_SPI_TLE62X0 is not set -# CONFIG_SPI_TOPCLIFF_PCH is not set -# CONFIG_SPI_XCOMM is not set -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_XWAY is not set -# CONFIG_SPI_ZYNQMP_GQSPI is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_SPMI is not set -# CONFIG_SPS30 is not set -# CONFIG_SPS30_I2C is not set -# CONFIG_SPS30_SERIAL is not set -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set -# CONFIG_SQUASHFS_DECOMP_MULTI is not set -CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y -# CONFIG_SQUASHFS_DECOMP_SINGLE is not set -CONFIG_SQUASHFS_EMBEDDED=y -# CONFIG_SQUASHFS_FILE_CACHE is not set -CONFIG_SQUASHFS_FILE_DIRECT=y -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_LZ4 is not set -# CONFIG_SQUASHFS_LZO is not set -# CONFIG_SQUASHFS_XATTR is not set -CONFIG_SQUASHFS_XZ=y -# CONFIG_SQUASHFS_ZLIB is not set -# CONFIG_SQUASHFS_ZSTD is not set -# CONFIG_SRAM is not set -# CONFIG_SRF04 is not set -# CONFIG_SRF08 is not set -# CONFIG_SSB is not set -# CONFIG_SSB_DEBUG is not set -# CONFIG_SSB_DRIVER_GPIO is not set -# CONFIG_SSB_HOST_SOC is not set -# CONFIG_SSB_PCMCIAHOST is not set -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB_SDIOHOST is not set -# CONFIG_SSB_SILENT is not set -# CONFIG_SSFDC is not set -# CONFIG_STACKPROTECTOR is not set -# CONFIG_STACKPROTECTOR_PER_TASK is not set -# CONFIG_STACKPROTECTOR_STRONG is not set -# CONFIG_STACKTRACE is not set -# CONFIG_STACKTRACE_BUILD_ID is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_STACK_HASH_ORDER=20 -# CONFIG_STACK_TRACER is not set -# CONFIG_STACK_VALIDATION is not set -CONFIG_STAGING=y -# CONFIG_STAGING_BOARD is not set -# CONFIG_STAGING_GASKET_FRAMEWORK is not set -# CONFIG_STAGING_MEDIA is not set -CONFIG_STANDALONE=y -# CONFIG_STATIC_KEYS_SELFTEST is not set -# CONFIG_STATIC_USERMODEHELPER is not set -CONFIG_STDBINUTILS=y -# CONFIG_STE10XP is not set -# CONFIG_STE_MODEM_RPROC is not set -# CONFIG_STK3310 is not set -# CONFIG_STK8312 is not set -# CONFIG_STK8BA50 is not set -# CONFIG_STM is not set -# CONFIG_STMMAC_ETH is not set -# CONFIG_STMMAC_PCI is not set -# CONFIG_STMMAC_PLATFORM is not set -# CONFIG_STMMAC_SELFTESTS is not set -# CONFIG_STMPE_ADC is not set -# CONFIG_STM_DUMMY is not set -# CONFIG_STM_SOURCE_CONSOLE is not set -CONFIG_STP=y -# CONFIG_STREAM_PARSER is not set -# CONFIG_STRICT_DEVMEM is not set -CONFIG_STRICT_KERNEL_RWX=y -CONFIG_STRICT_MODULE_RWX=y -# CONFIG_STRING_SELFTEST is not set -CONFIG_STRIP_ASM_SYMS=y -# CONFIG_STX104 is not set -# CONFIG_ST_UVIS25 is not set -# CONFIG_SUN4I_GPADC is not set -# CONFIG_SUN50I_DE2_BUS is not set -# CONFIG_SUN50I_ERRATUM_UNKNOWN1 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_SUNRPC is not set -# CONFIG_SUNRPC_DEBUG is not set -CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y -# CONFIG_SUNRPC_GSS is not set -# CONFIG_SUNXI_SRAM is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_SURFACE_3_BUTTON is not set -# CONFIG_SURFACE_PLATFORMS is not set -# CONFIG_SUSPEND is not set -# CONFIG_SUSPEND_SKIP_SYNC is not set -CONFIG_SWAP=y -# CONFIG_SWCONFIG is not set -# CONFIG_SWCONFIG_B53 is not set -# CONFIG_SWCONFIG_B53_MDIO_DRIVER is not set -# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set -# CONFIG_SWCONFIG_B53_SPI_DRIVER is not set -# CONFIG_SWCONFIG_B53_SRAB_DRIVER is not set -# CONFIG_SWCONFIG_LEDS is not set -# CONFIG_SW_SYNC is not set -# CONFIG_SX9310 is not set -# CONFIG_SX9324 is not set -# CONFIG_SX9360 is not set -# CONFIG_SX9500 is not set -# CONFIG_SXGBE_ETH is not set -CONFIG_SYMBOLIC_ERRNAME=y -# CONFIG_SYNCLINK_CS is not set -# CONFIG_SYNC_FILE is not set -# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set -# CONFIG_SYNTH_EVENTS is not set -# CONFIG_SYNTH_EVENT_GEN_TEST is not set -CONFIG_SYN_COOKIES=y -# CONFIG_SYSCON_REBOOT_MODE is not set -CONFIG_SYSCTL=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_SYSFS=y -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_SYSFS_DEPRECATED_V2 is not set -# CONFIG_SYSFS_SYSCALL is not set -# CONFIG_SYSTEMPORT is not set -# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set -# CONFIG_SYSTEM_DATA_VERIFICATION is not set -# CONFIG_SYSTEM_TRUSTED_KEYRING is not set -CONFIG_SYSTEM_TRUSTED_KEYS="" -# CONFIG_SYSV68_PARTITION is not set -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_SYSV_FS is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_T5403 is not set -# CONFIG_TARGET_CORE is not set -# CONFIG_TASKSTATS is not set -# CONFIG_TASKS_RCU is not set -# CONFIG_TASK_XACCT is not set -# CONFIG_TC35815 is not set -# CONFIG_TCG_ATMEL is not set -# CONFIG_TCG_CRB is not set -# CONFIG_TCG_FTPM_TEE is not set -# CONFIG_TCG_INFINEON is not set -# CONFIG_TCG_NSC is not set -# CONFIG_TCG_ST33_I2C is not set -# CONFIG_TCG_TIS is not set -# CONFIG_TCG_TIS_I2C is not set -# CONFIG_TCG_TIS_I2C_ATMEL is not set -# CONFIG_TCG_TIS_I2C_CR50 is not set -# CONFIG_TCG_TIS_I2C_INFINEON is not set -# CONFIG_TCG_TIS_I2C_NUVOTON is not set -# CONFIG_TCG_TIS_SPI is not set -# CONFIG_TCG_TIS_ST33ZP24_I2C is not set -# CONFIG_TCG_TIS_ST33ZP24_SPI is not set -# CONFIG_TCG_TPM is not set -# CONFIG_TCG_VTPM_PROXY is not set -# CONFIG_TCG_XEN is not set -# CONFIG_TCIC is not set -CONFIG_TCP_CONG_ADVANCED=y -# CONFIG_TCP_CONG_BBR is not set -# CONFIG_TCP_CONG_BIC is not set -# CONFIG_TCP_CONG_CDG is not set -CONFIG_TCP_CONG_CUBIC=y -# CONFIG_TCP_CONG_DCTCP is not set -# CONFIG_TCP_CONG_HSTCP is not set -# CONFIG_TCP_CONG_HTCP is not set -# CONFIG_TCP_CONG_HYBLA is not set -# CONFIG_TCP_CONG_ILLINOIS is not set -# CONFIG_TCP_CONG_LP is not set -# CONFIG_TCP_CONG_NV is not set -# CONFIG_TCP_CONG_SCALABLE is not set -# CONFIG_TCP_CONG_VEGAS is not set -# CONFIG_TCP_CONG_VENO is not set -# CONFIG_TCP_CONG_WESTWOOD is not set -# CONFIG_TCP_CONG_YEAH is not set -# CONFIG_TCP_MD5SIG is not set -# CONFIG_TCS3414 is not set -# CONFIG_TCS3472 is not set -# CONFIG_TEE is not set -# CONFIG_TEGRA210_ADMA is not set -# CONFIG_TEGRA_ACONNECT is not set -# CONFIG_TEGRA_AHB is not set -# CONFIG_TEGRA_HOST1X is not set -# CONFIG_TEHUTI is not set -# CONFIG_TERANETICS_PHY is not set -# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set -# CONFIG_TEST_BITFIELD is not set -# CONFIG_TEST_BITMAP is not set -# CONFIG_TEST_BITOPS is not set -# CONFIG_TEST_BLACKHOLE_DEV is not set -# CONFIG_TEST_BPF is not set -# CONFIG_TEST_CLOCKSOURCE_WATCHDOG is not set -# CONFIG_TEST_DEBUG_VIRTUAL is not set -# CONFIG_TEST_DIV64 is not set -# CONFIG_TEST_DYNAMIC_DEBUG is not set -# CONFIG_TEST_FIRMWARE is not set -# CONFIG_TEST_FREE_PAGES is not set -# CONFIG_TEST_HASH is not set -# CONFIG_TEST_HEXDUMP is not set -# CONFIG_TEST_IDA is not set -# CONFIG_TEST_KASAN_MODULE is not set -# CONFIG_TEST_KMOD is not set -# CONFIG_TEST_KSTRTOX is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_TEST_LKM is not set -# CONFIG_TEST_LOCKUP is not set -# CONFIG_TEST_MAPLE_TREE is not set -# CONFIG_TEST_MEMCAT_P is not set -# CONFIG_TEST_MEMINIT is not set -# CONFIG_TEST_MIN_HEAP is not set -# CONFIG_TEST_OVERFLOW is not set -# CONFIG_TEST_POWER is not set -# CONFIG_TEST_PRINTF is not set -# CONFIG_TEST_REF_TRACKER is not set -# CONFIG_TEST_RHASHTABLE is not set -# CONFIG_TEST_SCANF is not set -# CONFIG_TEST_SIPHASH is not set -# CONFIG_TEST_SORT is not set -# CONFIG_TEST_STACKINIT is not set -# CONFIG_TEST_STATIC_KEYS is not set -# CONFIG_TEST_STRING_HELPERS is not set -# CONFIG_TEST_STRSCPY is not set -# CONFIG_TEST_SYSCTL is not set -# CONFIG_TEST_UBSAN is not set -# CONFIG_TEST_UDELAY is not set -# CONFIG_TEST_USER_COPY is not set -# CONFIG_TEST_UUID is not set -# CONFIG_TEST_VMALLOC is not set -# CONFIG_TEST_XARRAY is not set -CONFIG_TEXTSEARCH=y -# CONFIG_TEXTSEARCH_BM is not set -# CONFIG_TEXTSEARCH_FSM is not set -# CONFIG_TEXTSEARCH_KMP is not set -# CONFIG_THERMAL is not set -# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set -# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set -# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set -# CONFIG_THERMAL_EMULATION is not set -# CONFIG_THERMAL_GOV_BANG_BANG is not set -# CONFIG_THERMAL_GOV_FAIR_SHARE is not set -# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set -# CONFIG_THERMAL_GOV_USER_SPACE is not set -# CONFIG_THERMAL_HWMON is not set -# CONFIG_THERMAL_MMIO is not set -# CONFIG_THERMAL_NETLINK is not set -# CONFIG_THERMAL_STATISTICS is not set -# CONFIG_THERMAL_WRITABLE_TRIPS is not set -# CONFIG_THINKPAD_ACPI is not set -CONFIG_THIN_ARCHIVES=y -# CONFIG_THRUSTMASTER_FF is not set -# CONFIG_THUMB2_KERNEL is not set -# CONFIG_THUNDERBOLT is not set -# CONFIG_THUNDER_NIC_BGX is not set -# CONFIG_THUNDER_NIC_PF is not set -# CONFIG_THUNDER_NIC_RGX is not set -# CONFIG_THUNDER_NIC_VF is not set -# CONFIG_TICK_CPU_ACCOUNTING is not set -CONFIG_TICK_ONESHOT=y -# CONFIG_TIFM_CORE is not set -# CONFIG_TIGON3 is not set -# CONFIG_TIMB_DMA is not set -CONFIG_TIMERFD=y -# CONFIG_TIMERLAT_TRACER is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_TIME_NS is not set -# CONFIG_TINYDRM_HX8357D is not set -# CONFIG_TINYDRM_ILI9163 is not set -# CONFIG_TINYDRM_ILI9225 is not set -# CONFIG_TINYDRM_ILI9341 is not set -# CONFIG_TINYDRM_ILI9486 is not set -# CONFIG_TINYDRM_MI0283QT is not set -# CONFIG_TINYDRM_REPAPER is not set -# CONFIG_TINYDRM_ST7586 is not set -# CONFIG_TINYDRM_ST7735R is not set -CONFIG_TINY_RCU=y -# CONFIG_TIPC is not set -# CONFIG_TI_ADC081C is not set -# CONFIG_TI_ADC0832 is not set -# CONFIG_TI_ADC084S021 is not set -# CONFIG_TI_ADC108S102 is not set -# CONFIG_TI_ADC12138 is not set -# CONFIG_TI_ADC128S052 is not set -# CONFIG_TI_ADC161S626 is not set -# CONFIG_TI_ADS1015 is not set -# CONFIG_TI_ADS124S08 is not set -# CONFIG_TI_ADS131E08 is not set -# CONFIG_TI_ADS7950 is not set -# CONFIG_TI_ADS8344 is not set -# CONFIG_TI_ADS8688 is not set -# CONFIG_TI_AM335X_ADC is not set -# CONFIG_TI_CPSW is not set -# CONFIG_TI_CPSW_ALE is not set -# CONFIG_TI_CPSW_PHY_SEL is not set -# CONFIG_TI_CPTS is not set -# CONFIG_TI_DAC082S085 is not set -# CONFIG_TI_DAC5571 is not set -# CONFIG_TI_DAC7311 is not set -# CONFIG_TI_DAC7512 is not set -# CONFIG_TI_DAC7612 is not set -# CONFIG_TI_DAVINCI_CPDMA is not set -# CONFIG_TI_DAVINCI_MDIO is not set -# CONFIG_TI_ST is not set -# CONFIG_TI_SYSCON_RESET is not set -# CONFIG_TI_TLC4541 is not set -# CONFIG_TI_TSC2046 is not set -# CONFIG_TLAN is not set -# CONFIG_TLS is not set -# CONFIG_TLS_DEVICE is not set -# CONFIG_TLS_TOE is not set -# CONFIG_TMD_HERMES is not set -# CONFIG_TMP006 is not set -# CONFIG_TMP007 is not set -# CONFIG_TMP117 is not set -CONFIG_TMPFS=y -# CONFIG_TMPFS_INODE64 is not set -# CONFIG_TMPFS_POSIX_ACL is not set -CONFIG_TMPFS_XATTR=y -# CONFIG_TOPSTAR_LAPTOP is not set -# CONFIG_TORTURE_TEST is not set -# CONFIG_TOSHIBA_HAPS is not set -# CONFIG_TOUCHSCREEN_88PM860X is not set -# CONFIG_TOUCHSCREEN_AD7877 is not set -# CONFIG_TOUCHSCREEN_AD7879 is not set -# CONFIG_TOUCHSCREEN_AD7879_I2C is not set -# CONFIG_TOUCHSCREEN_AD7879_SPI is not set -# CONFIG_TOUCHSCREEN_ADC is not set -# CONFIG_TOUCHSCREEN_ADS7846 is not set -# CONFIG_TOUCHSCREEN_AR1021_I2C is not set -# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set -# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set -# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set -# CONFIG_TOUCHSCREEN_BU21013 is not set -# CONFIG_TOUCHSCREEN_BU21029 is not set -# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set -# CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 is not set -# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set -# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set -# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set -# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set -# CONFIG_TOUCHSCREEN_CYTTSP4_I2C is not set -# CONFIG_TOUCHSCREEN_CYTTSP4_SPI is not set -# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set -# CONFIG_TOUCHSCREEN_CYTTSP_I2C is not set -# CONFIG_TOUCHSCREEN_CYTTSP_SPI is not set -# CONFIG_TOUCHSCREEN_DA9034 is not set -# CONFIG_TOUCHSCREEN_DA9052 is not set -# CONFIG_TOUCHSCREEN_DYNAPRO is not set -# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set -# CONFIG_TOUCHSCREEN_EETI is not set -# CONFIG_TOUCHSCREEN_EGALAX is not set -# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set -# CONFIG_TOUCHSCREEN_EKTF2127 is not set -# CONFIG_TOUCHSCREEN_ELAN is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_EXC3000 is not set -# CONFIG_TOUCHSCREEN_FUJITSU is not set -# CONFIG_TOUCHSCREEN_GOODIX is not set -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set -# CONFIG_TOUCHSCREEN_HIDEEP is not set -# CONFIG_TOUCHSCREEN_HP600 is not set -# CONFIG_TOUCHSCREEN_HP7XX is not set -# CONFIG_TOUCHSCREEN_HTCPEN is not set -# CONFIG_TOUCHSCREEN_HYCON_HY46XX is not set -# CONFIG_TOUCHSCREEN_ILI210X is not set -# CONFIG_TOUCHSCREEN_ILITEK is not set -# CONFIG_TOUCHSCREEN_IMAGIS is not set -# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set -# CONFIG_TOUCHSCREEN_INEXIO is not set -# CONFIG_TOUCHSCREEN_IPAQ_MICRO is not set -# CONFIG_TOUCHSCREEN_IPROC is not set -# CONFIG_TOUCHSCREEN_IQS5XX is not set -# CONFIG_TOUCHSCREEN_LPC32XX is not set -# CONFIG_TOUCHSCREEN_MAX11801 is not set -# CONFIG_TOUCHSCREEN_MC13783 is not set -# CONFIG_TOUCHSCREEN_MCS5000 is not set -# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set -# CONFIG_TOUCHSCREEN_MIGOR is not set -# CONFIG_TOUCHSCREEN_MK712 is not set -# CONFIG_TOUCHSCREEN_MMS114 is not set -# CONFIG_TOUCHSCREEN_MSG2638 is not set -# CONFIG_TOUCHSCREEN_MTOUCH is not set -# CONFIG_TOUCHSCREEN_MX25 is not set -# CONFIG_TOUCHSCREEN_MXS_LRADC is not set -# CONFIG_TOUCHSCREEN_PCAP is not set -# CONFIG_TOUCHSCREEN_PENMOUNT is not set -# CONFIG_TOUCHSCREEN_PIXCIR is not set -# CONFIG_TOUCHSCREEN_PROPERTIES is not set -# CONFIG_TOUCHSCREEN_RASPBERRYPI_FW is not set -# CONFIG_TOUCHSCREEN_RM_TS is not set -# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set -# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set -# CONFIG_TOUCHSCREEN_S3C2410 is not set -# CONFIG_TOUCHSCREEN_S6SY761 is not set -# CONFIG_TOUCHSCREEN_SILEAD is not set -# CONFIG_TOUCHSCREEN_SIS_I2C is not set -# CONFIG_TOUCHSCREEN_ST1232 is not set -# CONFIG_TOUCHSCREEN_STMFTS is not set -# CONFIG_TOUCHSCREEN_STMPE is not set -# CONFIG_TOUCHSCREEN_SUN4I is not set -# CONFIG_TOUCHSCREEN_SUR40 is not set -# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set -# CONFIG_TOUCHSCREEN_SX8654 is not set -# CONFIG_TOUCHSCREEN_TI_AM335X_TSC is not set -# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set -# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -# CONFIG_TOUCHSCREEN_TPS6507X is not set -# CONFIG_TOUCHSCREEN_TS4800 is not set -# CONFIG_TOUCHSCREEN_TSC2004 is not set -# CONFIG_TOUCHSCREEN_TSC2005 is not set -# CONFIG_TOUCHSCREEN_TSC2007 is not set -# CONFIG_TOUCHSCREEN_TSC2007_IIO is not set -# CONFIG_TOUCHSCREEN_TSC200X_CORE is not set -# CONFIG_TOUCHSCREEN_TSC_SERIO is not set -# CONFIG_TOUCHSCREEN_UCB1400 is not set -# CONFIG_TOUCHSCREEN_USB_3M is not set -# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set -# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set -# CONFIG_TOUCHSCREEN_USB_E2I is not set -# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set -# CONFIG_TOUCHSCREEN_USB_EGALAX is not set -# CONFIG_TOUCHSCREEN_USB_ELO is not set -# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set -# CONFIG_TOUCHSCREEN_USB_ETURBO is not set -# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set -# CONFIG_TOUCHSCREEN_USB_GOTOP is not set -# CONFIG_TOUCHSCREEN_USB_GUNZE is not set -# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set -# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set -# CONFIG_TOUCHSCREEN_USB_ITM is not set -# CONFIG_TOUCHSCREEN_USB_JASTEC is not set -# CONFIG_TOUCHSCREEN_USB_NEXIO is not set -# CONFIG_TOUCHSCREEN_USB_PANJIT is not set -# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set -# CONFIG_TOUCHSCREEN_W90X900 is not set -# CONFIG_TOUCHSCREEN_WACOM_I2C is not set -# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set -# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set -# CONFIG_TOUCHSCREEN_WM831X is not set -# CONFIG_TOUCHSCREEN_WM9705 is not set -# CONFIG_TOUCHSCREEN_WM9712 is not set -# CONFIG_TOUCHSCREEN_WM9713 is not set -# CONFIG_TOUCHSCREEN_WM97XX is not set -# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set -# CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE is not set -# CONFIG_TOUCHSCREEN_ZET6223 is not set -# CONFIG_TOUCHSCREEN_ZFORCE is not set -# CONFIG_TOUCHSCREEN_ZINITIX is not set -# CONFIG_TPL0102 is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS65010 is not set -# CONFIG_TPS6507X is not set -# CONFIG_TRACEPOINT_BENCHMARK is not set -# CONFIG_TRACER_SNAPSHOT is not set -# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set -# CONFIG_TRACE_BRANCH_PROFILING is not set -# CONFIG_TRACE_EVAL_MAP_FILE is not set -# CONFIG_TRACE_EVENT_INJECT is not set -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_TRACE_MMIO_ACCESS is not set -# CONFIG_TRACE_SINK is not set -# CONFIG_TRACING_EVENTS_GPIO is not set -CONFIG_TRACING_SUPPORT=y -CONFIG_TRAD_SIGNALS=y -# CONFIG_TRANSPARENT_HUGEPAGE is not set -# CONFIG_TREE_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_TRIM_UNUSED_KSYMS is not set -# CONFIG_TRUSTED_FOUNDATIONS is not set -# CONFIG_TRUSTED_KEYS is not set -# CONFIG_TRUSTED_KEYS_CAAM is not set -# CONFIG_TRUSTED_KEYS_TEE is not set -# CONFIG_TRUSTED_KEYS_TPM is not set -# CONFIG_TSL2583 is not set -# CONFIG_TSL2591 is not set -# CONFIG_TSL2772 is not set -# CONFIG_TSL2x7x is not set -# CONFIG_TSL4531 is not set -# CONFIG_TSNEP is not set -# CONFIG_TSYS01 is not set -# CONFIG_TSYS02D is not set -# CONFIG_TTPCI_EEPROM is not set -CONFIG_TTY=y -# CONFIG_TTY_PRINTK is not set -# CONFIG_TUN is not set -# CONFIG_TUN_VNET_CROSS_LE is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_TWL4030_MADC is not set -# CONFIG_TWL6030_GPADC is not set -# CONFIG_TWL6040_CORE is not set -# CONFIG_TXGBE is not set -# CONFIG_TYPEC is not set -# CONFIG_TYPEC_DP_ALTMODE is not set -# CONFIG_TYPEC_TCPM is not set -# CONFIG_TYPEC_UCSI is not set -# CONFIG_TYPHOON is not set -# CONFIG_UACCESS_WITH_MEMCPY is not set -# CONFIG_UBIFS_ATIME_SUPPORT is not set -# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set -# CONFIG_UBIFS_FS_AUTHENTICATION is not set -# CONFIG_UBIFS_FS_ENCRYPTION is not set -CONFIG_UBIFS_FS_LZO=y -# CONFIG_UBIFS_FS_SECURITY is not set -CONFIG_UBIFS_FS_XATTR=y -CONFIG_UBIFS_FS_ZLIB=y -CONFIG_UBIFS_FS_ZSTD=y -# CONFIG_UBSAN is not set -CONFIG_UBSAN_ALIGNMENT=y -CONFIG_UBSAN_BOOL=y -# CONFIG_UBSAN_DIV_ZERO is not set -CONFIG_UBSAN_ENUM=y -# CONFIG_UBSAN_MISC is not set -CONFIG_UBSAN_SHIFT=y -# CONFIG_UBSAN_UNREACHABLE is not set -# CONFIG_UCB1400_CORE is not set -# CONFIG_UCSI is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDMABUF is not set -CONFIG_UEVENT_HELPER=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_UFS_FS is not set -# CONFIG_UHID is not set -CONFIG_UID16=y -# CONFIG_UIMAGE_FIT_BLK is not set -# CONFIG_UIO is not set -# CONFIG_ULTRA is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_UNICODE is not set -# CONFIG_UNISYSSPAR is not set -# CONFIG_UNISYS_VISORBUS is not set -CONFIG_UNIX=y -CONFIG_UNIX98_PTYS=y -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_UNIX_DIAG is not set -CONFIG_UNIX_SCM=y -# CONFIG_UNUSED_BOARD_FILES is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_UNWINDER_FRAME_POINTER is not set -# CONFIG_UPROBES is not set -# CONFIG_UPROBE_EVENTS is not set -# CONFIG_US5182D is not set -# CONFIG_USB is not set -# CONFIG_USB4 is not set -# CONFIG_USBIP_CORE is not set -CONFIG_USBIP_VHCI_HC_PORTS=8 -CONFIG_USBIP_VHCI_NR_HCS=1 -# CONFIG_USBIP_VUDC is not set -# CONFIG_USBPCWATCHDOG is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AIRSPY is not set -CONFIG_USB_ALI_M5632=y -# CONFIG_USB_AMD5536UDC is not set -CONFIG_USB_AN2720=y -# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set -# CONFIG_USB_APPLEDISPLAY is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARMLINUX=y -# CONFIG_USB_ATM is not set -# CONFIG_USB_AUDIO is not set -CONFIG_USB_AUTOSUSPEND_DELAY=2 -# CONFIG_USB_BDC_UDC is not set -CONFIG_USB_BELKIN=y -# CONFIG_USB_C67X00_HCD is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDC_COMPOSITE is not set -# CONFIG_USB_CDNS3 is not set -# CONFIG_USB_CDNS3_IMX is not set -# CONFIG_USB_CDNS3_PCI_WRAP is not set -# CONFIG_USB_CDNSP_PCI is not set -# CONFIG_USB_CDNS_SUPPORT is not set -# CONFIG_USB_CHAOSKEY is not set -# CONFIG_USB_CHIPIDEA is not set -# CONFIG_USB_CHIPIDEA_GENERIC is not set -# CONFIG_USB_CHIPIDEA_IMX is not set -# CONFIG_USB_CHIPIDEA_MSM is not set -# CONFIG_USB_CHIPIDEA_PCI is not set -# CONFIG_USB_CHIPIDEA_TEGRA is not set -# CONFIG_USB_CONFIGFS is not set -# CONFIG_USB_CONN_GPIO is not set -# CONFIG_USB_CXACRU is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -CONFIG_USB_DEFAULT_PERSIST=y -# CONFIG_USB_DSBR is not set -# CONFIG_USB_DUMMY_HCD is not set -# CONFIG_USB_DWC2 is not set -# CONFIG_USB_DWC2_DEBUG is not set -# CONFIG_USB_DWC2_DUAL_ROLE is not set -# CONFIG_USB_DWC2_HOST is not set -# CONFIG_USB_DWC2_PERIPHERAL is not set -# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set -# CONFIG_USB_DWC3 is not set -# CONFIG_USB_DWC3_EXYNOS is not set -# CONFIG_USB_DWC3_HAPS is not set -# CONFIG_USB_DWC3_KEYSTONE is not set -# CONFIG_USB_DWC3_OF_SIMPLE is not set -# CONFIG_USB_DWC3_PCI is not set -# CONFIG_USB_DWC3_QCOM is not set -# CONFIG_USB_DWC3_ULPI is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_EG20T is not set -# CONFIG_USB_EHCI_ATH79 is not set -# CONFIG_USB_EHCI_FSL is not set -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_EHCI_HCD_AT91 is not set -# CONFIG_USB_EHCI_HCD_OMAP is not set -# CONFIG_USB_EHCI_HCD_PPC_OF is not set -# CONFIG_USB_EHCI_MSM is not set -# CONFIG_USB_EHCI_MV is not set -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y -# CONFIG_USB_EHSET_TEST_FIXTURE is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EPSON2888 is not set -# CONFIG_USB_ETH is not set -# CONFIG_USB_EZUSB_FX2 is not set -# CONFIG_USB_FEW_INIT_RETRIES is not set -# CONFIG_USB_FOTG210_HCD is not set -# CONFIG_USB_FOTG210_UDC is not set -# CONFIG_USB_FSL_USB2 is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_FUNCTIONFS is not set -# CONFIG_USB_FUSB300 is not set -# CONFIG_USB_GADGET is not set -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_GADGET_DEBUG is not set -# CONFIG_USB_GADGET_DEBUG_FILES is not set -# CONFIG_USB_GADGET_DEBUG_FS is not set -CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 -CONFIG_USB_GADGET_VBUS_DRAW=2 -# CONFIG_USB_GADGET_XILINX is not set -# CONFIG_USB_GL860 is not set -# CONFIG_USB_GOKU is not set -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_USB_GR_UDC is not set -# CONFIG_USB_GSPCA is not set -# CONFIG_USB_GSPCA_BENQ is not set -# CONFIG_USB_GSPCA_CONEX is not set -# CONFIG_USB_GSPCA_CPIA1 is not set -# CONFIG_USB_GSPCA_DTCS033 is not set -# CONFIG_USB_GSPCA_ETOMS is not set -# CONFIG_USB_GSPCA_FINEPIX is not set -# CONFIG_USB_GSPCA_JEILINJ is not set -# CONFIG_USB_GSPCA_JL2005BCD is not set -# CONFIG_USB_GSPCA_KINECT is not set -# CONFIG_USB_GSPCA_KONICA is not set -# CONFIG_USB_GSPCA_MARS is not set -# CONFIG_USB_GSPCA_MR97310A is not set -# CONFIG_USB_GSPCA_NW80X is not set -# CONFIG_USB_GSPCA_OV519 is not set -# CONFIG_USB_GSPCA_OV534 is not set -# CONFIG_USB_GSPCA_OV534_9 is not set -# CONFIG_USB_GSPCA_PAC207 is not set -# CONFIG_USB_GSPCA_PAC7302 is not set -# CONFIG_USB_GSPCA_PAC7311 is not set -# CONFIG_USB_GSPCA_SE401 is not set -# CONFIG_USB_GSPCA_SN9C2028 is not set -# CONFIG_USB_GSPCA_SN9C20X is not set -# CONFIG_USB_GSPCA_SONIXB is not set -# CONFIG_USB_GSPCA_SONIXJ is not set -# CONFIG_USB_GSPCA_SPCA1528 is not set -# CONFIG_USB_GSPCA_SPCA500 is not set -# CONFIG_USB_GSPCA_SPCA501 is not set -# CONFIG_USB_GSPCA_SPCA505 is not set -# CONFIG_USB_GSPCA_SPCA506 is not set -# CONFIG_USB_GSPCA_SPCA508 is not set -# CONFIG_USB_GSPCA_SPCA561 is not set -# CONFIG_USB_GSPCA_SQ905 is not set -# CONFIG_USB_GSPCA_SQ905C is not set -# CONFIG_USB_GSPCA_SQ930X is not set -# CONFIG_USB_GSPCA_STK014 is not set -# CONFIG_USB_GSPCA_STK1135 is not set -# CONFIG_USB_GSPCA_STV0680 is not set -# CONFIG_USB_GSPCA_SUNPLUS is not set -# CONFIG_USB_GSPCA_T613 is not set -# CONFIG_USB_GSPCA_TOPRO is not set -# CONFIG_USB_GSPCA_TOUPTEK is not set -# CONFIG_USB_GSPCA_TV8532 is not set -# CONFIG_USB_GSPCA_VC032X is not set -# CONFIG_USB_GSPCA_VICAM is not set -# CONFIG_USB_GSPCA_XIRLINK_CIT is not set -# CONFIG_USB_GSPCA_ZC3XX is not set -# CONFIG_USB_G_ACM_MS is not set -# CONFIG_USB_G_DBGP is not set -# CONFIG_USB_G_HID is not set -# CONFIG_USB_G_MULTI is not set -# CONFIG_USB_G_NCM is not set -# CONFIG_USB_G_NOKIA is not set -# CONFIG_USB_G_PRINTER is not set -# CONFIG_USB_G_SERIAL is not set -# CONFIG_USB_G_WEBCAM is not set -# CONFIG_USB_HACKRF is not set -# CONFIG_USB_HCD_TEST_MODE is not set -# CONFIG_USB_HID is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_HSIC_USB3503 is not set -# CONFIG_USB_HSIC_USB4604 is not set -# CONFIG_USB_HSO is not set -# CONFIG_USB_HUB_USB251XB is not set -# CONFIG_USB_HWA_HCD is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_IMX21_HCD is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_IPHETH is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_ISP1301 is not set -# CONFIG_USB_ISP1362_HCD is not set -# CONFIG_USB_ISP1760 is not set -# CONFIG_USB_ISP1760_HCD is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_KBD is not set -# CONFIG_USB_KC2190 is not set -# CONFIG_USB_LAN78XX is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set -# CONFIG_USB_LED_TRIG is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LGM_PHY is not set -# CONFIG_USB_LINK_LAYER_TEST is not set -# CONFIG_USB_M5602 is not set -# CONFIG_USB_M66592 is not set -# CONFIG_USB_MASS_STORAGE is not set -# CONFIG_USB_MAX3420_UDC is not set -# CONFIG_USB_MAX3421_HCD is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_MIDI_GADGET is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_MSI2500 is not set -# CONFIG_USB_MSM_OTG is not set -# CONFIG_USB_MTU3 is not set -# CONFIG_USB_MUSB_GADGET is not set -# CONFIG_USB_MUSB_HDRC is not set -# CONFIG_USB_MUSB_HOST is not set -# CONFIG_USB_MV_U3D is not set -# CONFIG_USB_MV_UDC is not set -# CONFIG_USB_MXS_PHY is not set -# CONFIG_USB_NET2272 is not set -# CONFIG_USB_NET2280 is not set -# CONFIG_USB_NET_AQC111 is not set -# CONFIG_USB_NET_AX88179_178A is not set -# CONFIG_USB_NET_AX8817X is not set -# CONFIG_USB_NET_CDCETHER is not set -# CONFIG_USB_NET_CDC_EEM is not set -# CONFIG_USB_NET_CDC_MBIM is not set -# CONFIG_USB_NET_CDC_NCM is not set -# CONFIG_USB_NET_CDC_SUBSET is not set -# CONFIG_USB_NET_CH9200 is not set -# CONFIG_USB_NET_CX82310_ETH is not set -# CONFIG_USB_NET_DM9601 is not set -# CONFIG_USB_NET_DRIVERS is not set -# CONFIG_USB_NET_GL620A is not set -# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set -# CONFIG_USB_NET_INT51X1 is not set -# CONFIG_USB_NET_KALMIA is not set -# CONFIG_USB_NET_MCS7830 is not set -# CONFIG_USB_NET_NET1080 is not set -# CONFIG_USB_NET_PLUSB is not set -# CONFIG_USB_NET_QMI_WWAN is not set -# CONFIG_USB_NET_RNDIS_HOST is not set -# CONFIG_USB_NET_RNDIS_WLAN is not set -# CONFIG_USB_NET_SMSC75XX is not set -# CONFIG_USB_NET_SMSC95XX is not set -# CONFIG_USB_NET_SR9700 is not set -# CONFIG_USB_NET_SR9800 is not set -# CONFIG_USB_NET_ZAURUS is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_OHCI_HCD_PCI is not set -# CONFIG_USB_OHCI_HCD_PPC_OF is not set -# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set -# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set -# CONFIG_USB_OHCI_HCD_SSB is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_ONBOARD_HUB is not set -# CONFIG_USB_OTG is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set -# CONFIG_USB_OTG_FSM is not set -# CONFIG_USB_OTG_PRODUCTLIST is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_PCI is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_PHY is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_PWC_INPUT_EVDEV is not set -# CONFIG_USB_PXA27X is not set -# CONFIG_USB_QCOM_EUD is not set -# CONFIG_USB_R8A66597 is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_RAW_GADGET is not set -# CONFIG_USB_RCAR_PHY is not set -# CONFIG_USB_RENESAS_USBHS is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ROLES_INTEL_XHCI is not set -# CONFIG_USB_ROLE_SWITCH is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_RTL8152 is not set -# CONFIG_USB_RTL8153_ECM is not set -# CONFIG_USB_S2255 is not set -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_AIRCABLE is not set -# CONFIG_USB_SERIAL_ARK3116 is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_CH341 is not set -# CONFIG_USB_SERIAL_CP210X is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_DEBUG is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_F81232 is not set -# CONFIG_USB_SERIAL_F8153X is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_GARMIN is not set -CONFIG_USB_SERIAL_GENERIC=y -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_IUU is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -CONFIG_USB_SERIAL_KEYSPAN_MPR=y -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -CONFIG_USB_SERIAL_KEYSPAN_USA18X=y -CONFIG_USB_SERIAL_KEYSPAN_USA19=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -CONFIG_USB_SERIAL_KEYSPAN_USA19W=y -CONFIG_USB_SERIAL_KEYSPAN_USA28=y -CONFIG_USB_SERIAL_KEYSPAN_USA28X=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y -CONFIG_USB_SERIAL_KEYSPAN_USA49W=y -CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_METRO is not set -# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set -# CONFIG_USB_SERIAL_MOS7720 is not set -# CONFIG_USB_SERIAL_MOS7840 is not set -# CONFIG_USB_SERIAL_MXUPORT is not set -# CONFIG_USB_SERIAL_NAVMAN is not set -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_SERIAL_OPTICON is not set -# CONFIG_USB_SERIAL_OPTION is not set -# CONFIG_USB_SERIAL_OTI6858 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_QCAUX is not set -# CONFIG_USB_SERIAL_QT2 is not set -# CONFIG_USB_SERIAL_QUALCOMM is not set -# CONFIG_USB_SERIAL_SAFE is not set -CONFIG_USB_SERIAL_SAFE_PADDED=y -# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set -# CONFIG_USB_SERIAL_SIMPLE is not set -# CONFIG_USB_SERIAL_SPCP8X5 is not set -# CONFIG_USB_SERIAL_SSU100 is not set -# CONFIG_USB_SERIAL_SYMBOL is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_UPD78F0730 is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_WISHBONE is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_XR is not set -# CONFIG_USB_SERIAL_XSENS_MT is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_SIERRA_NET is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_SNP_UDC_PLAT is not set -# CONFIG_USB_SPEEDTOUCH is not set -# CONFIG_USB_STKWEBCAM is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_ENE_UB6250 is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_REALTEK is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STV06XX is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_USB_SWITCH_FSA9480 is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_TMC is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_UAS is not set -# CONFIG_USB_UEAGLEATM is not set -# CONFIG_USB_ULPI is not set -# CONFIG_USB_ULPI_BUS is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_USS720 is not set -# CONFIG_USB_VIDEO_CLASS is not set -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -# CONFIG_USB_VL600 is not set -# CONFIG_USB_WDM is not set -# CONFIG_USB_WHCI_HCD is not set -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set -# CONFIG_USB_XEN_HCD is not set -# CONFIG_USB_XHCI_DBGCAP is not set -# CONFIG_USB_XHCI_HCD is not set -# CONFIG_USB_XHCI_MVEBU is not set -# CONFIG_USB_XHCI_PCI_RENESAS is not set -# CONFIG_USB_XUSBATM is not set -# CONFIG_USB_YUREX is not set -# CONFIG_USB_ZD1201 is not set -# CONFIG_USB_ZERO is not set -# CONFIG_USB_ZR364XX is not set -# CONFIG_USELIB is not set -# CONFIG_USERFAULTFD is not set -# CONFIG_USERIO is not set -# CONFIG_USER_DECRYPTED_DATA is not set -# CONFIG_USE_OF is not set -# CONFIG_UTS_NS is not set -# CONFIG_UWB is not set -# CONFIG_U_SERIAL_CONSOLE is not set -# CONFIG_V4L_MEM2MEM_DRIVERS is not set -# CONFIG_V4L_PLATFORM_DRIVERS is not set -# CONFIG_V4L_TEST_DRIVERS is not set -# CONFIG_VALIDATE_FS_PARSER is not set -# CONFIG_VBOXGUEST is not set -# CONFIG_VCNL3020 is not set -# CONFIG_VCNL4000 is not set -# CONFIG_VCNL4035 is not set -# CONFIG_VCPU_STALL_DETECTOR is not set -# CONFIG_VDPA is not set -CONFIG_VDSO=y -# CONFIG_VEML6030 is not set -# CONFIG_VEML6070 is not set -# CONFIG_VETH is not set -# CONFIG_VEXPRESS_CONFIG is not set -# CONFIG_VF610_ADC is not set -# CONFIG_VF610_DAC is not set -# CONFIG_VFAT_FS is not set -# CONFIG_VFIO is not set -# CONFIG_VFIO_FSL_MC is not set -# CONFIG_VFIO_PLATFORM is not set -# CONFIG_VGASTATE is not set -# CONFIG_VGA_ARB is not set -# CONFIG_VGA_CONSOLE is not set -# CONFIG_VGA_SWITCHEROO is not set -# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set -CONFIG_VHOST_MENU=y -# CONFIG_VHOST_NET is not set -# CONFIG_VHOST_VSOCK is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_VIDEO_AD5398 is not set -# CONFIG_VIDEO_AD5820 is not set -# CONFIG_VIDEO_AD9389B is not set -# CONFIG_VIDEO_ADP1653 is not set -# CONFIG_VIDEO_ADV7170 is not set -# CONFIG_VIDEO_ADV7175 is not set -# CONFIG_VIDEO_ADV7180 is not set -# CONFIG_VIDEO_ADV7183 is not set -# CONFIG_VIDEO_ADV7343 is not set -# CONFIG_VIDEO_ADV7393 is not set -# CONFIG_VIDEO_ADV748X is not set -# CONFIG_VIDEO_ADV7511 is not set -# CONFIG_VIDEO_ADV7604 is not set -# CONFIG_VIDEO_ADV7842 is not set -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_AK7375 is not set -# CONFIG_VIDEO_AK881X is not set -# CONFIG_VIDEO_AM437X_VPFE is not set -# CONFIG_VIDEO_AR0521 is not set -# CONFIG_VIDEO_ARDUCAM_64MP is not set -# CONFIG_VIDEO_ARDUCAM_PIVARIETY is not set -# CONFIG_VIDEO_ASPEED is not set -# CONFIG_VIDEO_ATMEL_ISC is not set -# CONFIG_VIDEO_ATMEL_ISI is not set -# CONFIG_VIDEO_AU0828 is not set -# CONFIG_VIDEO_BCM2835 is not set -# CONFIG_VIDEO_BCM2835_UNICAM is not set -# CONFIG_VIDEO_BT819 is not set -# CONFIG_VIDEO_BT848 is not set -# CONFIG_VIDEO_BT856 is not set -# CONFIG_VIDEO_BT866 is not set -# CONFIG_VIDEO_BU64754 is not set -# CONFIG_VIDEO_CADENCE is not set -# CONFIG_VIDEO_CADENCE_CSI2RX is not set -# CONFIG_VIDEO_CADENCE_CSI2TX is not set -# CONFIG_VIDEO_CAFE_CCIC is not set -# CONFIG_VIDEO_CAMERA_SENSOR is not set -# CONFIG_VIDEO_CCS is not set -# CONFIG_VIDEO_COBALT is not set -# CONFIG_VIDEO_CODA is not set -# CONFIG_VIDEO_CODEC_BCM2835 is not set -# CONFIG_VIDEO_CS3308 is not set -# CONFIG_VIDEO_CS5345 is not set -# CONFIG_VIDEO_CS53L32A is not set -# CONFIG_VIDEO_CX231XX is not set -# CONFIG_VIDEO_CX2341X is not set -# CONFIG_VIDEO_CX25821 is not set -# CONFIG_VIDEO_CX25840 is not set -# CONFIG_VIDEO_CX88 is not set -# CONFIG_VIDEO_DEV is not set -# CONFIG_VIDEO_DM6446_CCDC is not set -# CONFIG_VIDEO_DT3155 is not set -# CONFIG_VIDEO_DW9714 is not set -# CONFIG_VIDEO_DW9768 is not set -# CONFIG_VIDEO_DW9807_VCM is not set -# CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_ET8EK8 is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_GO7007 is not set -# CONFIG_VIDEO_GS1662 is not set -# CONFIG_VIDEO_HDPVR is not set -# CONFIG_VIDEO_HEXIUM_GEMINI is not set -# CONFIG_VIDEO_HEXIUM_ORION is not set -# CONFIG_VIDEO_HI556 is not set -# CONFIG_VIDEO_HI846 is not set -# CONFIG_VIDEO_HI847 is not set -# CONFIG_VIDEO_I2C is not set -# CONFIG_VIDEO_IMX208 is not set -# CONFIG_VIDEO_IMX214 is not set -# CONFIG_VIDEO_IMX219 is not set -# CONFIG_VIDEO_IMX258 is not set -# CONFIG_VIDEO_IMX274 is not set -# CONFIG_VIDEO_IMX290 is not set -# CONFIG_VIDEO_IMX296 is not set -# CONFIG_VIDEO_IMX319 is not set -# CONFIG_VIDEO_IMX334 is not set -# CONFIG_VIDEO_IMX335 is not set -# CONFIG_VIDEO_IMX355 is not set -# CONFIG_VIDEO_IMX412 is not set -# CONFIG_VIDEO_IMX477 is not set -# CONFIG_VIDEO_IMX519 is not set -# CONFIG_VIDEO_IMX708 is not set -# CONFIG_VIDEO_IMX8_JPEG is not set -# CONFIG_VIDEO_IMX_MIPI_CSIS is not set -# CONFIG_VIDEO_IMX_PXP is not set -# CONFIG_VIDEO_IRS1125 is not set -# CONFIG_VIDEO_IR_I2C is not set -# CONFIG_VIDEO_ISL7998X is not set -# CONFIG_VIDEO_ISP_BCM2835 is not set -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_KS0127 is not set -# CONFIG_VIDEO_LM3560 is not set -# CONFIG_VIDEO_LM3646 is not set -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_M5MOLS is not set -# CONFIG_VIDEO_MAX9286 is not set -# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set -# CONFIG_VIDEO_ML86V7667 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_MT9M001 is not set -# CONFIG_VIDEO_MT9M032 is not set -# CONFIG_VIDEO_MT9M111 is not set -# CONFIG_VIDEO_MT9P031 is not set -# CONFIG_VIDEO_MT9T001 is not set -# CONFIG_VIDEO_MT9T112 is not set -# CONFIG_VIDEO_MT9V011 is not set -# CONFIG_VIDEO_MT9V032 is not set -# CONFIG_VIDEO_MT9V111 is not set -# CONFIG_VIDEO_MUX is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_NOON010PC30 is not set -# CONFIG_VIDEO_OG01A1B is not set -# CONFIG_VIDEO_OMAP2_VOUT is not set -# CONFIG_VIDEO_OV02A10 is not set -# CONFIG_VIDEO_OV08D10 is not set -# CONFIG_VIDEO_OV13858 is not set -# CONFIG_VIDEO_OV13B10 is not set -# CONFIG_VIDEO_OV2311 is not set -# CONFIG_VIDEO_OV2640 is not set -# CONFIG_VIDEO_OV2659 is not set -# CONFIG_VIDEO_OV2680 is not set -# CONFIG_VIDEO_OV2685 is not set -# CONFIG_VIDEO_OV2740 is not set -# CONFIG_VIDEO_OV5640 is not set -# CONFIG_VIDEO_OV5645 is not set -# CONFIG_VIDEO_OV5647 is not set -# CONFIG_VIDEO_OV5648 is not set -# CONFIG_VIDEO_OV5670 is not set -# CONFIG_VIDEO_OV5675 is not set -# CONFIG_VIDEO_OV5693 is not set -# CONFIG_VIDEO_OV5695 is not set -# CONFIG_VIDEO_OV64A40 is not set -# CONFIG_VIDEO_OV6650 is not set -# CONFIG_VIDEO_OV7251 is not set -# CONFIG_VIDEO_OV7640 is not set -# CONFIG_VIDEO_OV7670 is not set -# CONFIG_VIDEO_OV772X is not set -# CONFIG_VIDEO_OV7740 is not set -# CONFIG_VIDEO_OV8856 is not set -# CONFIG_VIDEO_OV8865 is not set -# CONFIG_VIDEO_OV9281 is not set -# CONFIG_VIDEO_OV9282 is not set -# CONFIG_VIDEO_OV9640 is not set -# CONFIG_VIDEO_OV9650 is not set -# CONFIG_VIDEO_OV9734 is not set -# CONFIG_VIDEO_PVRUSB2 is not set -# CONFIG_VIDEO_RASPBERRYPI_PISP_BE is not set -# CONFIG_VIDEO_RCAR_CSI2 is not set -# CONFIG_VIDEO_RCAR_ISP is not set -# CONFIG_VIDEO_RCAR_VIN is not set -# CONFIG_VIDEO_RDACM20 is not set -# CONFIG_VIDEO_RDACM21 is not set -# CONFIG_VIDEO_RJ54N1 is not set -# CONFIG_VIDEO_ROCKCHIP_ISP1 is not set -# CONFIG_VIDEO_RP1_CFE is not set -# CONFIG_VIDEO_S5C73M3 is not set -# CONFIG_VIDEO_S5K4ECGX is not set -# CONFIG_VIDEO_S5K5BAF is not set -# CONFIG_VIDEO_S5K6A3 is not set -# CONFIG_VIDEO_S5K6AA is not set -# CONFIG_VIDEO_SAA6588 is not set -# CONFIG_VIDEO_SAA6752HS is not set -# CONFIG_VIDEO_SAA7110 is not set -# CONFIG_VIDEO_SAA711X is not set -# CONFIG_VIDEO_SAA7127 is not set -# CONFIG_VIDEO_SAA7134 is not set -# CONFIG_VIDEO_SAA7164 is not set -# CONFIG_VIDEO_SAA717X is not set -# CONFIG_VIDEO_SAA7185 is not set -# CONFIG_VIDEO_SH_MOBILE_CEU is not set -# CONFIG_VIDEO_SMIAPP is not set -# CONFIG_VIDEO_SOLO6X10 is not set -# CONFIG_VIDEO_SONY_BTF_MPX is not set -# CONFIG_VIDEO_SR030PC30 is not set -# CONFIG_VIDEO_STK1160_COMMON is not set -# CONFIG_VIDEO_ST_MIPID02 is not set -# CONFIG_VIDEO_SUN4I_CSI is not set -# CONFIG_VIDEO_SUN6I_CSI is not set -# CONFIG_VIDEO_SUN8I_A83T_MIPI_CSI2 is not set -# CONFIG_VIDEO_TC358743 is not set -# CONFIG_VIDEO_TDA1997X is not set -# CONFIG_VIDEO_TDA7432 is not set -# CONFIG_VIDEO_TDA9840 is not set -# CONFIG_VIDEO_TEA6415C is not set -# CONFIG_VIDEO_TEA6420 is not set -# CONFIG_VIDEO_THS7303 is not set -# CONFIG_VIDEO_THS8200 is not set -# CONFIG_VIDEO_TIMBERDALE is not set -# CONFIG_VIDEO_TLV320AIC23B is not set -# CONFIG_VIDEO_TM6000 is not set -# CONFIG_VIDEO_TVAUDIO is not set -# CONFIG_VIDEO_TVP514X is not set -# CONFIG_VIDEO_TVP5150 is not set -# CONFIG_VIDEO_TVP7002 is not set -# CONFIG_VIDEO_TW2804 is not set -# CONFIG_VIDEO_TW5864 is not set -# CONFIG_VIDEO_TW68 is not set -# CONFIG_VIDEO_TW9903 is not set -# CONFIG_VIDEO_TW9906 is not set -# CONFIG_VIDEO_TW9910 is not set -# CONFIG_VIDEO_UDA1342 is not set -# CONFIG_VIDEO_UPD64031A is not set -# CONFIG_VIDEO_UPD64083 is not set -# CONFIG_VIDEO_USBTV is not set -# CONFIG_VIDEO_USBVISION is not set -# CONFIG_VIDEO_V4L2 is not set -# CONFIG_VIDEO_VP27SMPX is not set -# CONFIG_VIDEO_VPX3220 is not set -# CONFIG_VIDEO_VS6624 is not set -# CONFIG_VIDEO_WM8739 is not set -# CONFIG_VIDEO_WM8775 is not set -# CONFIG_VIDEO_XILINX is not set -# CONFIG_VIDEO_ZORAN is not set -# CONFIG_VIRTIO_BALLOON is not set -# CONFIG_VIRTIO_BLK_SCSI is not set -# CONFIG_VIRTIO_CONSOLE is not set -# CONFIG_VIRTIO_FS is not set -# CONFIG_VIRTIO_INPUT is not set -CONFIG_VIRTIO_MENU=y -# CONFIG_VIRTIO_MMIO is not set -# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set -# CONFIG_VIRTIO_PCI is not set -# CONFIG_VIRTUALIZATION is not set -# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set -# CONFIG_VIRT_DRIVERS is not set -CONFIG_VIRT_TO_BUS=y -# CONFIG_VITESSE_PHY is not set -# CONFIG_VL53L0X_I2C is not set -# CONFIG_VL6180 is not set -CONFIG_VLAN_8021Q=y -# CONFIG_VLAN_8021Q_GVRP is not set -# CONFIG_VLAN_8021Q_MVRP is not set -# CONFIG_VMAP_STACK is not set -# CONFIG_VME_BUS is not set -# CONFIG_VMLINUX_MAP is not set -# CONFIG_VMSPLIT_1G is not set -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_2G_OPT is not set -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_3G_OPT is not set -# CONFIG_VMWARE_PVSCSI is not set -# CONFIG_VMWARE_VMCI is not set -# CONFIG_VMXNET3 is not set -# CONFIG_VM_EVENT_COUNTERS is not set -# CONFIG_VOP_BUS is not set -# CONFIG_VORTEX is not set -# CONFIG_VSOCKETS is not set -# CONFIG_VSOCKETS_DIAG is not set -# CONFIG_VT is not set -# CONFIG_VT6655 is not set -# CONFIG_VT6656 is not set -# CONFIG_VXFS_FS is not set -# CONFIG_VXGE is not set -# CONFIG_VXLAN is not set -# CONFIG_VZ89X is not set -# CONFIG_W1 is not set -# CONFIG_W1_CON is not set -# CONFIG_W1_MASTER_DS1WM is not set -# CONFIG_W1_MASTER_DS2482 is not set -# CONFIG_W1_MASTER_DS2490 is not set -# CONFIG_W1_MASTER_GPIO is not set -# CONFIG_W1_MASTER_MATROX is not set -# CONFIG_W1_MASTER_SGI is not set -# CONFIG_W1_SLAVE_DS2405 is not set -# CONFIG_W1_SLAVE_DS2406 is not set -# CONFIG_W1_SLAVE_DS2408 is not set -# CONFIG_W1_SLAVE_DS2413 is not set -# CONFIG_W1_SLAVE_DS2423 is not set -# CONFIG_W1_SLAVE_DS2430 is not set -# CONFIG_W1_SLAVE_DS2431 is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2438 is not set -# CONFIG_W1_SLAVE_DS250X is not set -# CONFIG_W1_SLAVE_DS2780 is not set -# CONFIG_W1_SLAVE_DS2781 is not set -# CONFIG_W1_SLAVE_DS2805 is not set -# CONFIG_W1_SLAVE_DS28E04 is not set -# CONFIG_W1_SLAVE_DS28E17 is not set -# CONFIG_W1_SLAVE_SMEM is not set -# CONFIG_W1_SLAVE_THERM is not set -# CONFIG_W83627HF_WDT is not set -# CONFIG_W83877F_WDT is not set -# CONFIG_W83977F_WDT is not set -# CONFIG_WAN is not set -# CONFIG_WANXL is not set -# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_CORE is not set -CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y -# CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT is not set -# CONFIG_WATCHDOG_NOWAYOUT is not set -CONFIG_WATCHDOG_OPEN_TIMEOUT=0 -# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set -# CONFIG_WATCHDOG_SYSFS is not set -# CONFIG_WATCH_QUEUE is not set -# CONFIG_WD80x3 is not set -# CONFIG_WDAT_WDT is not set -# CONFIG_WDTPCI is not set -# CONFIG_WERROR is not set -# CONFIG_WEXT_CORE is not set -# CONFIG_WEXT_PRIV is not set -# CONFIG_WEXT_PROC is not set -# CONFIG_WEXT_SPY is not set -CONFIG_WILINK_PLATFORM_DATA=y -# CONFIG_WIMAX is not set -# CONFIG_WIREGUARD is not set -CONFIG_WIRELESS=y -# CONFIG_WIRELESS_EXT is not set -# CONFIG_WIRELESS_WDS is not set -# CONFIG_WIZNET_W5100 is not set -# CONFIG_WIZNET_W5300 is not set -# CONFIG_WL1251 is not set -# CONFIG_WL12XX is not set -# CONFIG_WL18XX is not set -CONFIG_WLAN=y -# CONFIG_WLAN_VENDOR_ADMTEK is not set -# CONFIG_WLAN_VENDOR_ATH is not set -# CONFIG_WLAN_VENDOR_ATMEL is not set -# CONFIG_WLAN_VENDOR_BROADCOM is not set -# CONFIG_WLAN_VENDOR_CISCO is not set -# CONFIG_WLAN_VENDOR_INTEL is not set -# CONFIG_WLAN_VENDOR_INTERSIL is not set -# CONFIG_WLAN_VENDOR_MARVELL is not set -# CONFIG_WLAN_VENDOR_MEDIATEK is not set -# CONFIG_WLAN_VENDOR_MICROCHIP is not set -# CONFIG_WLAN_VENDOR_PURELIFI is not set -# CONFIG_WLAN_VENDOR_QUANTENNA is not set -# CONFIG_WLAN_VENDOR_RALINK is not set -# CONFIG_WLAN_VENDOR_REALTEK is not set -# CONFIG_WLAN_VENDOR_RSI is not set -# CONFIG_WLAN_VENDOR_SILABS is not set -# CONFIG_WLAN_VENDOR_ST is not set -# CONFIG_WLAN_VENDOR_TI is not set -# CONFIG_WLAN_VENDOR_ZYDAS is not set -# CONFIG_WLCORE is not set -CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y -# CONFIG_WQ_WATCHDOG is not set -# CONFIG_WWAN is not set -# CONFIG_WWAN_HWSIM is not set -# CONFIG_WW_MUTEX_SELFTEST is not set -# CONFIG_X25 is not set -# CONFIG_X509_CERTIFICATE_PARSER is not set -# CONFIG_X86_PKG_TEMP_THERMAL is not set -CONFIG_X86_SYSFB=y -# CONFIG_XDP_SOCKETS is not set -# CONFIG_XEN is not set -# CONFIG_XEN_GRANT_DMA_ALLOC is not set -# CONFIG_XEN_PVCALLS_FRONTEND is not set -CONFIG_XEN_SCRUB_PAGES_DEFAULT=y -CONFIG_XFRM=y -# CONFIG_XFRM_INTERFACE is not set -# CONFIG_XFRM_IPCOMP is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_USER is not set -# CONFIG_XFS_DEBUG is not set -# CONFIG_XFS_FS is not set -# CONFIG_XFS_ONLINE_SCRUB is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_RT is not set -# CONFIG_XFS_SUPPORT_V4 is not set -# CONFIG_XFS_WARN is not set -# CONFIG_XILINX_AXI_EMAC is not set -# CONFIG_XILINX_DMA is not set -# CONFIG_XILINX_EMACLITE is not set -# CONFIG_XILINX_GMII2RGMII is not set -# CONFIG_XILINX_INTC is not set -# CONFIG_XILINX_LL_TEMAC is not set -# CONFIG_XILINX_SDFEC is not set -# CONFIG_XILINX_VCU is not set -# CONFIG_XILINX_WATCHDOG is not set -# CONFIG_XILINX_XADC is not set -# CONFIG_XILINX_ZYNQMP_DMA is not set -# CONFIG_XILINX_ZYNQMP_DPDMA is not set -# CONFIG_XILLYBUS is not set -# CONFIG_XILLYUSB is not set -# CONFIG_XIL_AXIS_FIFO is not set -# CONFIG_XIP_KERNEL is not set -# CONFIG_XMON is not set -CONFIG_XZ_DEC=y -# CONFIG_XZ_DEC_ARM is not set -# CONFIG_XZ_DEC_ARMTHUMB is not set -# CONFIG_XZ_DEC_BCJ is not set -# CONFIG_XZ_DEC_IA64 is not set -# CONFIG_XZ_DEC_MICROLZMA is not set -# CONFIG_XZ_DEC_POWERPC is not set -# CONFIG_XZ_DEC_SPARC is not set -# CONFIG_XZ_DEC_TEST is not set -# CONFIG_XZ_DEC_X86 is not set -# CONFIG_YAM is not set -# CONFIG_YAMAHA_YAS530 is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_YENTA is not set -# CONFIG_YENTA_O2 is not set -# CONFIG_YENTA_RICOH is not set -# CONFIG_YENTA_TI is not set -# CONFIG_YENTA_TOSHIBA is not set -# CONFIG_ZBUD is not set -# CONFIG_ZD1211RW is not set -# CONFIG_ZD1211RW_DEBUG is not set -# CONFIG_ZEROPLUS_FF is not set -# CONFIG_ZERO_CALL_USED_REGS is not set -# CONFIG_ZIIRAVE_WATCHDOG is not set -# CONFIG_ZISOFS is not set -# CONFIG_ZLIB_DEFLATE is not set -# CONFIG_ZLIB_INFLATE is not set -CONFIG_ZONE_DMA=y -# CONFIG_ZOPT2201 is not set -# CONFIG_ZPA2326 is not set -# CONFIG_ZPOOL is not set -# CONFIG_ZRAM is not set -# CONFIG_ZRAM_DEF_COMP_842 is not set -# CONFIG_ZRAM_DEF_COMP_LZ4 is not set -# CONFIG_ZRAM_DEF_COMP_LZ4HC is not set -# CONFIG_ZRAM_DEF_COMP_LZO is not set -# CONFIG_ZRAM_DEF_COMP_LZORLE is not set -# CONFIG_ZRAM_DEF_COMP_ZSTD is not set -# CONFIG_ZRAM_MEMORY_TRACKING is not set -# CONFIG_ZSMALLOC is not set -# CONFIG_ZSWAP is not set -# CONFIG_ZX_TDM is not set diff --git a/target/linux/generic/hack-6.1/204-module_strip.patch b/target/linux/generic/hack-6.1/204-module_strip.patch deleted file mode 100644 index 9fefd0bd6eff2a..00000000000000 --- a/target/linux/generic/hack-6.1/204-module_strip.patch +++ /dev/null @@ -1,210 +0,0 @@ -From a779a482fb9b9f8fcdf8b2519c789b4b9bb5dd05 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 16:56:48 +0200 -Subject: build: add a hack for removing non-essential module info - -Signed-off-by: Felix Fietkau ---- - include/linux/module.h | 13 ++++++++----- - include/linux/moduleparam.h | 15 ++++++++++++--- - init/Kconfig | 7 +++++++ - kernel/module.c | 5 ++++- - scripts/mod/modpost.c | 12 ++++++++++++ - 5 files changed, 43 insertions(+), 9 deletions(-) - ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -163,6 +163,7 @@ extern void cleanup_module(void); - - /* Generic info of form tag = "info" */ - #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) -+#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info) - - /* For userspace: you can also call me... */ - #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) -@@ -232,12 +233,12 @@ extern void cleanup_module(void); - * Author(s), use "Name " or just "Name", for multiple - * authors use multiple MODULE_AUTHOR() statements/lines. - */ --#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) -+#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author) - - /* What your module does. */ --#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) -+#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description) - --#ifdef MODULE -+#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED) - /* Creates an alias so file2alias.c can find device table. */ - #define MODULE_DEVICE_TABLE(type, name) \ - extern typeof(name) __mod_##type##__##name##_device_table \ -@@ -264,7 +265,9 @@ extern typeof(name) __mod_##type##__##na - */ - - #if defined(MODULE) || !defined(CONFIG_SYSFS) --#define MODULE_VERSION(_version) MODULE_INFO(version, _version) -+#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version) -+#elif defined(CONFIG_MODULE_STRIPPED) -+#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version) - #else - #define MODULE_VERSION(_version) \ - MODULE_INFO(version, _version); \ -@@ -287,7 +290,7 @@ extern typeof(name) __mod_##type##__##na - /* Optional firmware file (or files) needed by the module - * format is simply firmware file name. Multiple firmware - * files require multiple MODULE_FIRMWARE() specifiers */ --#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware) -+#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware) - - #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, __stringify(ns)) - ---- a/include/linux/moduleparam.h -+++ b/include/linux/moduleparam.h -@@ -20,6 +20,16 @@ - /* Chosen so that structs with an unsigned long line up. */ - #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) - -+/* This struct is here for syntactic coherency, it is not used */ -+#define __MODULE_INFO_DISABLED(name) \ -+ struct __UNIQUE_ID(name) {} -+ -+#ifdef CONFIG_MODULE_STRIPPED -+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name) -+#else -+#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info) -+#endif -+ - #define __MODULE_INFO(tag, name, info) \ - static const char __UNIQUE_ID(name)[] \ - __used __section(".modinfo") __aligned(1) \ -@@ -31,7 +41,7 @@ - /* One for each parameter, describing how to use it. Some files do - multiple of these per line, so can't just use MODULE_INFO. */ - #define MODULE_PARM_DESC(_parm, desc) \ -- __MODULE_INFO(parm, _parm, #_parm ":" desc) -+ __MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc) - - struct kernel_param; - ---- a/kernel/module/Kconfig -+++ b/kernel/module/Kconfig -@@ -290,4 +290,11 @@ config MODULES_TREE_LOOKUP - def_bool y - depends on PERF_EVENTS || TRACING || CFI_CLANG - -+config MODULE_STRIPPED -+ bool "Reduce module size" -+ depends on MODULES -+ help -+ Remove module parameter descriptions, author info, version, aliases, -+ device tables, etc. -+ - endif # MODULES ---- a/kernel/module/main.c -+++ b/kernel/module/main.c -@@ -988,6 +988,7 @@ size_t modinfo_attrs_count = ARRAY_SIZE( - - static const char vermagic[] = VERMAGIC_STRING; - -+#if defined(CONFIG_MODVERSIONS) || !defined(CONFIG_MODULE_STRIPPED) - int try_to_force_load(struct module *mod, const char *reason) - { - #ifdef CONFIG_MODULE_FORCE_LOAD -@@ -999,6 +1000,7 @@ int try_to_force_load(struct module *mod - return -ENOEXEC; - #endif - } -+#endif - - static char *get_modinfo(const struct load_info *info, const char *tag); - static char *get_next_modinfo(const struct load_info *info, const char *tag, -@@ -1958,9 +1960,11 @@ static int setup_load_info(struct load_i - - static int check_modinfo(struct module *mod, struct load_info *info, int flags) - { -- const char *modmagic = get_modinfo(info, "vermagic"); - int err; - -+#ifndef CONFIG_MODULE_STRIPPED -+ const char *modmagic = get_modinfo(info, "vermagic"); -+ - if (flags & MODULE_INIT_IGNORE_VERMAGIC) - modmagic = NULL; - -@@ -1981,6 +1985,7 @@ static int check_modinfo(struct module * - mod->name); - add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); - } -+#endif - - check_modinfo_retpoline(mod, info); - ---- a/scripts/mod/modpost.c -+++ b/scripts/mod/modpost.c -@@ -1785,7 +1785,9 @@ static void read_symbols(const char *mod - symname = remove_dot(info.strtab + sym->st_name); - - handle_symbol(mod, &info, sym, symname); -+#ifndef CONFIG_MODULE_STRIPPED - handle_moddevtable(mod, &info, sym, symname); -+#endif - } - - for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { -@@ -1948,8 +1950,10 @@ static void add_header(struct buffer *b, - buf_printf(b, "BUILD_SALT;\n"); - buf_printf(b, "BUILD_LTO_INFO;\n"); - buf_printf(b, "\n"); -+#ifndef CONFIG_MODULE_STRIPPED - buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); - buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); -+#endif - buf_printf(b, "\n"); - buf_printf(b, "__visible struct module __this_module\n"); - buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n"); -@@ -1963,8 +1967,10 @@ static void add_header(struct buffer *b, - buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n"); - buf_printf(b, "};\n"); - -+#ifndef CONFIG_MODULE_STRIPPED - if (!external_module) - buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); -+#endif - - buf_printf(b, - "\n" -@@ -1972,8 +1978,10 @@ static void add_header(struct buffer *b, - "MODULE_INFO(retpoline, \"Y\");\n" - "#endif\n"); - -+#ifndef CONFIG_MODULE_STRIPPED - if (strstarts(mod->name, "drivers/staging")) - buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); -+#endif - - if (strstarts(mod->name, "tools/testing")) - buf_printf(b, "\nMODULE_INFO(test, \"Y\");\n"); -@@ -2069,11 +2077,13 @@ static void add_depends(struct buffer *b - - static void add_srcversion(struct buffer *b, struct module *mod) - { -+#ifndef CONFIG_MODULE_STRIPPED - if (mod->srcversion[0]) { - buf_printf(b, "\n"); - buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n", - mod->srcversion); - } -+#endif - } - - static void write_buf(struct buffer *b, const char *fname) -@@ -2159,7 +2169,9 @@ static void write_mod_c_file(struct modu - add_exported_symbols(&buf, mod); - add_versions(&buf, mod); - add_depends(&buf, mod); -+#ifndef CONFIG_MODULE_STRIPPED - add_moddevtable(&buf, mod); -+#endif - add_srcversion(&buf, mod); - - ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name); diff --git a/target/linux/generic/hack-6.1/205-kconfig-abort-configuration-on-unset-symbol.patch b/target/linux/generic/hack-6.1/205-kconfig-abort-configuration-on-unset-symbol.patch deleted file mode 100644 index df18507041f7be..00000000000000 --- a/target/linux/generic/hack-6.1/205-kconfig-abort-configuration-on-unset-symbol.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 310e8e04a05d9eb43fa9dd7f00143300afcaa37a Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Fri, 11 Nov 2022 13:33:44 +0100 -Subject: [PATCH] kconfig: abort configuration on unset symbol - -When a target configuration has unset Kconfig symbols, the build will -fail when OpenWrt is compiled with V=s and stdin is connected to a tty. - -In case OpenWrt is compiled without either of these preconditions, the -build will succeed with the symbols in question being unset. - -Modify the kernel configuration in a way it fails on unset symbols -regardless of the aforementioned preconditions. - -Signed-off-by: David Bauer ---- - scripts/kconfig/conf.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/scripts/kconfig/conf.c -+++ b/scripts/kconfig/conf.c -@@ -338,6 +338,9 @@ static int conf_askvalue(struct symbol * - } - /* fall through */ - default: -+ if (!tty_stdio && getenv("FAIL_ON_UNCONFIGURED")) { -+ exit(1); -+ } - fflush(stdout); - xfgets(line, sizeof(line), stdin); - break; -@@ -520,6 +523,9 @@ static int conf_choice(struct menu *menu - } - /* fall through */ - case oldaskconfig: -+ if (!tty_stdio && getenv("FAIL_ON_UNCONFIGURED")) { -+ exit(1); -+ } - fflush(stdout); - xfgets(line, sizeof(line), stdin); - strip(line); diff --git a/target/linux/generic/hack-6.1/210-darwin_scripts_include.patch b/target/linux/generic/hack-6.1/210-darwin_scripts_include.patch deleted file mode 100644 index c9612536dec6e5..00000000000000 --- a/target/linux/generic/hack-6.1/210-darwin_scripts_include.patch +++ /dev/null @@ -1,3053 +0,0 @@ -From db7c30dcd9a0391bf13b62c9f91e144d762ef43a Mon Sep 17 00:00:00 2001 -From: Florian Fainelli -Date: Fri, 7 Jul 2017 17:00:49 +0200 -Subject: Add an OSX specific patch to make the kernel be compiled - -lede-commit: 3fc2a24f0422b2f55f9ed43f116db3111f700526 -Signed-off-by: Florian Fainelli ---- - scripts/kconfig/Makefile | 3 + - scripts/mod/elf.h | 3007 ++++++++++++++++++++++++++++++++++++++++++++ - scripts/mod/mk_elfconfig.c | 4 + - scripts/mod/modpost.h | 4 + - 4 files changed, 3018 insertions(+) - create mode 100644 scripts/mod/elf.h - ---- /dev/null -+++ b/scripts/mod/elf.h -@@ -0,0 +1,3007 @@ -+/* This file defines standard ELF types, structures, and macros. -+ Copyright (C) 1995-2012 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#ifndef _ELF_H -+#define _ELF_H 1 -+ -+/* Standard ELF types. */ -+ -+#include -+ -+/* Type for a 16-bit quantity. */ -+typedef uint16_t Elf32_Half; -+typedef uint16_t Elf64_Half; -+ -+/* Types for signed and unsigned 32-bit quantities. */ -+typedef uint32_t Elf32_Word; -+typedef int32_t Elf32_Sword; -+typedef uint32_t Elf64_Word; -+typedef int32_t Elf64_Sword; -+ -+/* Types for signed and unsigned 64-bit quantities. */ -+typedef uint64_t Elf32_Xword; -+typedef int64_t Elf32_Sxword; -+typedef uint64_t Elf64_Xword; -+typedef int64_t Elf64_Sxword; -+ -+/* Type of addresses. */ -+typedef uint32_t Elf32_Addr; -+typedef uint64_t Elf64_Addr; -+ -+/* Type of file offsets. */ -+typedef uint32_t Elf32_Off; -+typedef uint64_t Elf64_Off; -+ -+/* Type for section indices, which are 16-bit quantities. */ -+typedef uint16_t Elf32_Section; -+typedef uint16_t Elf64_Section; -+ -+/* Type for version symbol information. */ -+typedef Elf32_Half Elf32_Versym; -+typedef Elf64_Half Elf64_Versym; -+ -+ -+/* The ELF file header. This appears at the start of every ELF file. */ -+ -+#define EI_NIDENT (16) -+ -+typedef struct -+{ -+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ -+ Elf32_Half e_type; /* Object file type */ -+ Elf32_Half e_machine; /* Architecture */ -+ Elf32_Word e_version; /* Object file version */ -+ Elf32_Addr e_entry; /* Entry point virtual address */ -+ Elf32_Off e_phoff; /* Program header table file offset */ -+ Elf32_Off e_shoff; /* Section header table file offset */ -+ Elf32_Word e_flags; /* Processor-specific flags */ -+ Elf32_Half e_ehsize; /* ELF header size in bytes */ -+ Elf32_Half e_phentsize; /* Program header table entry size */ -+ Elf32_Half e_phnum; /* Program header table entry count */ -+ Elf32_Half e_shentsize; /* Section header table entry size */ -+ Elf32_Half e_shnum; /* Section header table entry count */ -+ Elf32_Half e_shstrndx; /* Section header string table index */ -+} Elf32_Ehdr; -+ -+typedef struct -+{ -+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ -+ Elf64_Half e_type; /* Object file type */ -+ Elf64_Half e_machine; /* Architecture */ -+ Elf64_Word e_version; /* Object file version */ -+ Elf64_Addr e_entry; /* Entry point virtual address */ -+ Elf64_Off e_phoff; /* Program header table file offset */ -+ Elf64_Off e_shoff; /* Section header table file offset */ -+ Elf64_Word e_flags; /* Processor-specific flags */ -+ Elf64_Half e_ehsize; /* ELF header size in bytes */ -+ Elf64_Half e_phentsize; /* Program header table entry size */ -+ Elf64_Half e_phnum; /* Program header table entry count */ -+ Elf64_Half e_shentsize; /* Section header table entry size */ -+ Elf64_Half e_shnum; /* Section header table entry count */ -+ Elf64_Half e_shstrndx; /* Section header string table index */ -+} Elf64_Ehdr; -+ -+/* Fields in the e_ident array. The EI_* macros are indices into the -+ array. The macros under each EI_* macro are the values the byte -+ may have. */ -+ -+#define EI_MAG0 0 /* File identification byte 0 index */ -+#define ELFMAG0 0x7f /* Magic number byte 0 */ -+ -+#define EI_MAG1 1 /* File identification byte 1 index */ -+#define ELFMAG1 'E' /* Magic number byte 1 */ -+ -+#define EI_MAG2 2 /* File identification byte 2 index */ -+#define ELFMAG2 'L' /* Magic number byte 2 */ -+ -+#define EI_MAG3 3 /* File identification byte 3 index */ -+#define ELFMAG3 'F' /* Magic number byte 3 */ -+ -+/* Conglomeration of the identification bytes, for easy testing as a word. */ -+#define ELFMAG "\177ELF" -+#define SELFMAG 4 -+ -+#define EI_CLASS 4 /* File class byte index */ -+#define ELFCLASSNONE 0 /* Invalid class */ -+#define ELFCLASS32 1 /* 32-bit objects */ -+#define ELFCLASS64 2 /* 64-bit objects */ -+#define ELFCLASSNUM 3 -+ -+#define EI_DATA 5 /* Data encoding byte index */ -+#define ELFDATANONE 0 /* Invalid data encoding */ -+#define ELFDATA2LSB 1 /* 2's complement, little endian */ -+#define ELFDATA2MSB 2 /* 2's complement, big endian */ -+#define ELFDATANUM 3 -+ -+#define EI_VERSION 6 /* File version byte index */ -+ /* Value must be EV_CURRENT */ -+ -+#define EI_OSABI 7 /* OS ABI identification */ -+#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -+#define ELFOSABI_SYSV 0 /* Alias. */ -+#define ELFOSABI_HPUX 1 /* HP-UX */ -+#define ELFOSABI_NETBSD 2 /* NetBSD. */ -+#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ -+#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ -+#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ -+#define ELFOSABI_AIX 7 /* IBM AIX. */ -+#define ELFOSABI_IRIX 8 /* SGI Irix. */ -+#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ -+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ -+#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ -+#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ -+#define ELFOSABI_ARM 97 /* ARM */ -+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ -+ -+#define EI_ABIVERSION 8 /* ABI version */ -+ -+#define EI_PAD 9 /* Byte index of padding bytes */ -+ -+/* Legal values for e_type (object file type). */ -+ -+#define ET_NONE 0 /* No file type */ -+#define ET_REL 1 /* Relocatable file */ -+#define ET_EXEC 2 /* Executable file */ -+#define ET_DYN 3 /* Shared object file */ -+#define ET_CORE 4 /* Core file */ -+#define ET_NUM 5 /* Number of defined types */ -+#define ET_LOOS 0xfe00 /* OS-specific range start */ -+#define ET_HIOS 0xfeff /* OS-specific range end */ -+#define ET_LOPROC 0xff00 /* Processor-specific range start */ -+#define ET_HIPROC 0xffff /* Processor-specific range end */ -+ -+/* Legal values for e_machine (architecture). */ -+ -+#define EM_NONE 0 /* No machine */ -+#define EM_M32 1 /* AT&T WE 32100 */ -+#define EM_SPARC 2 /* SUN SPARC */ -+#define EM_386 3 /* Intel 80386 */ -+#define EM_68K 4 /* Motorola m68k family */ -+#define EM_88K 5 /* Motorola m88k family */ -+#define EM_860 7 /* Intel 80860 */ -+#define EM_MIPS 8 /* MIPS R3000 big-endian */ -+#define EM_S370 9 /* IBM System/370 */ -+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ -+ -+#define EM_PARISC 15 /* HPPA */ -+#define EM_VPP500 17 /* Fujitsu VPP500 */ -+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -+#define EM_960 19 /* Intel 80960 */ -+#define EM_PPC 20 /* PowerPC */ -+#define EM_PPC64 21 /* PowerPC 64-bit */ -+#define EM_S390 22 /* IBM S390 */ -+ -+#define EM_V800 36 /* NEC V800 series */ -+#define EM_FR20 37 /* Fujitsu FR20 */ -+#define EM_RH32 38 /* TRW RH-32 */ -+#define EM_RCE 39 /* Motorola RCE */ -+#define EM_ARM 40 /* ARM */ -+#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -+#define EM_SH 42 /* Hitachi SH */ -+#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -+#define EM_TRICORE 44 /* Siemens Tricore */ -+#define EM_ARC 45 /* Argonaut RISC Core */ -+#define EM_H8_300 46 /* Hitachi H8/300 */ -+#define EM_H8_300H 47 /* Hitachi H8/300H */ -+#define EM_H8S 48 /* Hitachi H8S */ -+#define EM_H8_500 49 /* Hitachi H8/500 */ -+#define EM_IA_64 50 /* Intel Merced */ -+#define EM_MIPS_X 51 /* Stanford MIPS-X */ -+#define EM_COLDFIRE 52 /* Motorola Coldfire */ -+#define EM_68HC12 53 /* Motorola M68HC12 */ -+#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ -+#define EM_PCP 55 /* Siemens PCP */ -+#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -+#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -+#define EM_STARCORE 58 /* Motorola Start*Core processor */ -+#define EM_ME16 59 /* Toyota ME16 processor */ -+#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -+#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ -+#define EM_X86_64 62 /* AMD x86-64 architecture */ -+#define EM_PDSP 63 /* Sony DSP Processor */ -+ -+#define EM_FX66 66 /* Siemens FX66 microcontroller */ -+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -+#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -+#define EM_SVX 73 /* Silicon Graphics SVx */ -+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -+#define EM_VAX 75 /* Digital VAX */ -+#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ -+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ -+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ -+#define EM_HUANY 81 /* Harvard University machine-independent object files */ -+#define EM_PRISM 82 /* SiTera Prism */ -+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -+#define EM_FR30 84 /* Fujitsu FR30 */ -+#define EM_D10V 85 /* Mitsubishi D10V */ -+#define EM_D30V 86 /* Mitsubishi D30V */ -+#define EM_V850 87 /* NEC v850 */ -+#define EM_M32R 88 /* Mitsubishi M32R */ -+#define EM_MN10300 89 /* Matsushita MN10300 */ -+#define EM_MN10200 90 /* Matsushita MN10200 */ -+#define EM_PJ 91 /* picoJava */ -+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ -+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -+#define EM_TILEPRO 188 /* Tilera TILEPro */ -+#define EM_TILEGX 191 /* Tilera TILE-Gx */ -+#define EM_NUM 192 -+ -+/* If it is necessary to assign new unofficial EM_* values, please -+ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the -+ chances of collision with official or non-GNU unofficial values. */ -+ -+#define EM_ALPHA 0x9026 -+ -+/* Legal values for e_version (version). */ -+ -+#define EV_NONE 0 /* Invalid ELF version */ -+#define EV_CURRENT 1 /* Current version */ -+#define EV_NUM 2 -+ -+/* Section header. */ -+ -+typedef struct -+{ -+ Elf32_Word sh_name; /* Section name (string tbl index) */ -+ Elf32_Word sh_type; /* Section type */ -+ Elf32_Word sh_flags; /* Section flags */ -+ Elf32_Addr sh_addr; /* Section virtual addr at execution */ -+ Elf32_Off sh_offset; /* Section file offset */ -+ Elf32_Word sh_size; /* Section size in bytes */ -+ Elf32_Word sh_link; /* Link to another section */ -+ Elf32_Word sh_info; /* Additional section information */ -+ Elf32_Word sh_addralign; /* Section alignment */ -+ Elf32_Word sh_entsize; /* Entry size if section holds table */ -+} Elf32_Shdr; -+ -+typedef struct -+{ -+ Elf64_Word sh_name; /* Section name (string tbl index) */ -+ Elf64_Word sh_type; /* Section type */ -+ Elf64_Xword sh_flags; /* Section flags */ -+ Elf64_Addr sh_addr; /* Section virtual addr at execution */ -+ Elf64_Off sh_offset; /* Section file offset */ -+ Elf64_Xword sh_size; /* Section size in bytes */ -+ Elf64_Word sh_link; /* Link to another section */ -+ Elf64_Word sh_info; /* Additional section information */ -+ Elf64_Xword sh_addralign; /* Section alignment */ -+ Elf64_Xword sh_entsize; /* Entry size if section holds table */ -+} Elf64_Shdr; -+ -+/* Special section indices. */ -+ -+#define SHN_UNDEF 0 /* Undefined section */ -+#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ -+#define SHN_LOPROC 0xff00 /* Start of processor-specific */ -+#define SHN_BEFORE 0xff00 /* Order section before all others -+ (Solaris). */ -+#define SHN_AFTER 0xff01 /* Order section after all others -+ (Solaris). */ -+#define SHN_HIPROC 0xff1f /* End of processor-specific */ -+#define SHN_LOOS 0xff20 /* Start of OS-specific */ -+#define SHN_HIOS 0xff3f /* End of OS-specific */ -+#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ -+#define SHN_COMMON 0xfff2 /* Associated symbol is common */ -+#define SHN_XINDEX 0xffff /* Index is in extra table. */ -+#define SHN_HIRESERVE 0xffff /* End of reserved indices */ -+ -+/* Legal values for sh_type (section type). */ -+ -+#define SHT_NULL 0 /* Section header table entry unused */ -+#define SHT_PROGBITS 1 /* Program data */ -+#define SHT_SYMTAB 2 /* Symbol table */ -+#define SHT_STRTAB 3 /* String table */ -+#define SHT_RELA 4 /* Relocation entries with addends */ -+#define SHT_HASH 5 /* Symbol hash table */ -+#define SHT_DYNAMIC 6 /* Dynamic linking information */ -+#define SHT_NOTE 7 /* Notes */ -+#define SHT_NOBITS 8 /* Program space with no data (bss) */ -+#define SHT_REL 9 /* Relocation entries, no addends */ -+#define SHT_SHLIB 10 /* Reserved */ -+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -+#define SHT_INIT_ARRAY 14 /* Array of constructors */ -+#define SHT_FINI_ARRAY 15 /* Array of destructors */ -+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -+#define SHT_GROUP 17 /* Section group */ -+#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -+#define SHT_NUM 19 /* Number of defined types. */ -+#define SHT_LOOS 0x60000000 /* Start OS-specific. */ -+#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ -+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -+#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ -+#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ -+#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ -+#define SHT_SUNW_move 0x6ffffffa -+#define SHT_SUNW_COMDAT 0x6ffffffb -+#define SHT_SUNW_syminfo 0x6ffffffc -+#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -+#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -+#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -+#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -+#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -+#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -+#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -+#define SHT_HIUSER 0x8fffffff /* End of application-specific */ -+ -+/* Legal values for sh_flags (section flags). */ -+ -+#define SHF_WRITE (1 << 0) /* Writable */ -+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -+#define SHF_EXECINSTR (1 << 2) /* Executable */ -+#define SHF_MERGE (1 << 4) /* Might be merged */ -+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ -+#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ -+#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ -+#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling -+ required */ -+#define SHF_GROUP (1 << 9) /* Section is member of a group. */ -+#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ -+#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ -+#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ -+#define SHF_ORDERED (1 << 30) /* Special ordering requirement -+ (Solaris). */ -+#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless -+ referenced or allocated (Solaris).*/ -+ -+/* Section group handling. */ -+#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ -+ -+/* Symbol table entry. */ -+ -+typedef struct -+{ -+ Elf32_Word st_name; /* Symbol name (string tbl index) */ -+ Elf32_Addr st_value; /* Symbol value */ -+ Elf32_Word st_size; /* Symbol size */ -+ unsigned char st_info; /* Symbol type and binding */ -+ unsigned char st_other; /* Symbol visibility */ -+ Elf32_Section st_shndx; /* Section index */ -+} Elf32_Sym; -+ -+typedef struct -+{ -+ Elf64_Word st_name; /* Symbol name (string tbl index) */ -+ unsigned char st_info; /* Symbol type and binding */ -+ unsigned char st_other; /* Symbol visibility */ -+ Elf64_Section st_shndx; /* Section index */ -+ Elf64_Addr st_value; /* Symbol value */ -+ Elf64_Xword st_size; /* Symbol size */ -+} Elf64_Sym; -+ -+/* The syminfo section if available contains additional information about -+ every dynamic symbol. */ -+ -+typedef struct -+{ -+ Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ -+ Elf32_Half si_flags; /* Per symbol flags */ -+} Elf32_Syminfo; -+ -+typedef struct -+{ -+ Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ -+ Elf64_Half si_flags; /* Per symbol flags */ -+} Elf64_Syminfo; -+ -+/* Possible values for si_boundto. */ -+#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ -+#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ -+#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ -+ -+/* Possible bitmasks for si_flags. */ -+#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -+#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ -+#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ -+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy -+ loaded */ -+/* Syminfo version values. */ -+#define SYMINFO_NONE 0 -+#define SYMINFO_CURRENT 1 -+#define SYMINFO_NUM 2 -+ -+ -+/* How to extract and insert information held in the st_info field. */ -+ -+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -+#define ELF32_ST_TYPE(val) ((val) & 0xf) -+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) -+ -+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ -+#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -+#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) -+ -+/* Legal values for ST_BIND subfield of st_info (symbol binding). */ -+ -+#define STB_LOCAL 0 /* Local symbol */ -+#define STB_GLOBAL 1 /* Global symbol */ -+#define STB_WEAK 2 /* Weak symbol */ -+#define STB_NUM 3 /* Number of defined types. */ -+#define STB_LOOS 10 /* Start of OS-specific */ -+#define STB_GNU_UNIQUE 10 /* Unique symbol. */ -+#define STB_HIOS 12 /* End of OS-specific */ -+#define STB_LOPROC 13 /* Start of processor-specific */ -+#define STB_HIPROC 15 /* End of processor-specific */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_NOTYPE 0 /* Symbol type is unspecified */ -+#define STT_OBJECT 1 /* Symbol is a data object */ -+#define STT_FUNC 2 /* Symbol is a code object */ -+#define STT_SECTION 3 /* Symbol associated with a section */ -+#define STT_FILE 4 /* Symbol's name is file name */ -+#define STT_COMMON 5 /* Symbol is a common data object */ -+#define STT_TLS 6 /* Symbol is thread-local data object*/ -+#define STT_NUM 7 /* Number of defined types. */ -+#define STT_LOOS 10 /* Start of OS-specific */ -+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ -+#define STT_HIOS 12 /* End of OS-specific */ -+#define STT_LOPROC 13 /* Start of processor-specific */ -+#define STT_HIPROC 15 /* End of processor-specific */ -+ -+ -+/* Symbol table indices are found in the hash buckets and chain table -+ of a symbol hash table section. This special index value indicates -+ the end of a chain, meaning no further symbols are found in that bucket. */ -+ -+#define STN_UNDEF 0 /* End of a chain. */ -+ -+ -+/* How to extract and insert information held in the st_other field. */ -+ -+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) -+ -+/* For ELF64 the definitions are the same. */ -+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) -+ -+/* Symbol visibility specification encoded in the st_other field. */ -+#define STV_DEFAULT 0 /* Default symbol visibility rules */ -+#define STV_INTERNAL 1 /* Processor specific hidden class */ -+#define STV_HIDDEN 2 /* Sym unavailable in other modules */ -+#define STV_PROTECTED 3 /* Not preemptible, not exported */ -+ -+ -+/* Relocation table entry without addend (in section of type SHT_REL). */ -+ -+typedef struct -+{ -+ Elf32_Addr r_offset; /* Address */ -+ Elf32_Word r_info; /* Relocation type and symbol index */ -+} Elf32_Rel; -+ -+/* I have seen two different definitions of the Elf64_Rel and -+ Elf64_Rela structures, so we'll leave them out until Novell (or -+ whoever) gets their act together. */ -+/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ -+ -+typedef struct -+{ -+ Elf64_Addr r_offset; /* Address */ -+ Elf64_Xword r_info; /* Relocation type and symbol index */ -+} Elf64_Rel; -+ -+/* Relocation table entry with addend (in section of type SHT_RELA). */ -+ -+typedef struct -+{ -+ Elf32_Addr r_offset; /* Address */ -+ Elf32_Word r_info; /* Relocation type and symbol index */ -+ Elf32_Sword r_addend; /* Addend */ -+} Elf32_Rela; -+ -+typedef struct -+{ -+ Elf64_Addr r_offset; /* Address */ -+ Elf64_Xword r_info; /* Relocation type and symbol index */ -+ Elf64_Sxword r_addend; /* Addend */ -+} Elf64_Rela; -+ -+/* How to extract and insert information held in the r_info field. */ -+ -+#define ELF32_R_SYM(val) ((val) >> 8) -+#define ELF32_R_TYPE(val) ((val) & 0xff) -+#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) -+ -+#define ELF64_R_SYM(i) ((i) >> 32) -+#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -+#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) -+ -+/* Program segment header. */ -+ -+typedef struct -+{ -+ Elf32_Word p_type; /* Segment type */ -+ Elf32_Off p_offset; /* Segment file offset */ -+ Elf32_Addr p_vaddr; /* Segment virtual address */ -+ Elf32_Addr p_paddr; /* Segment physical address */ -+ Elf32_Word p_filesz; /* Segment size in file */ -+ Elf32_Word p_memsz; /* Segment size in memory */ -+ Elf32_Word p_flags; /* Segment flags */ -+ Elf32_Word p_align; /* Segment alignment */ -+} Elf32_Phdr; -+ -+typedef struct -+{ -+ Elf64_Word p_type; /* Segment type */ -+ Elf64_Word p_flags; /* Segment flags */ -+ Elf64_Off p_offset; /* Segment file offset */ -+ Elf64_Addr p_vaddr; /* Segment virtual address */ -+ Elf64_Addr p_paddr; /* Segment physical address */ -+ Elf64_Xword p_filesz; /* Segment size in file */ -+ Elf64_Xword p_memsz; /* Segment size in memory */ -+ Elf64_Xword p_align; /* Segment alignment */ -+} Elf64_Phdr; -+ -+/* Special value for e_phnum. This indicates that the real number of -+ program headers is too large to fit into e_phnum. Instead the real -+ value is in the field sh_info of section 0. */ -+ -+#define PN_XNUM 0xffff -+ -+/* Legal values for p_type (segment type). */ -+ -+#define PT_NULL 0 /* Program header table entry unused */ -+#define PT_LOAD 1 /* Loadable program segment */ -+#define PT_DYNAMIC 2 /* Dynamic linking information */ -+#define PT_INTERP 3 /* Program interpreter */ -+#define PT_NOTE 4 /* Auxiliary information */ -+#define PT_SHLIB 5 /* Reserved */ -+#define PT_PHDR 6 /* Entry for header table itself */ -+#define PT_TLS 7 /* Thread-local storage segment */ -+#define PT_NUM 8 /* Number of defined types */ -+#define PT_LOOS 0x60000000 /* Start of OS-specific */ -+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ -+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ -+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ -+#define PT_LOSUNW 0x6ffffffa -+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -+#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ -+#define PT_HISUNW 0x6fffffff -+#define PT_HIOS 0x6fffffff /* End of OS-specific */ -+#define PT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define PT_HIPROC 0x7fffffff /* End of processor-specific */ -+ -+/* Legal values for p_flags (segment flags). */ -+ -+#define PF_X (1 << 0) /* Segment is executable */ -+#define PF_W (1 << 1) /* Segment is writable */ -+#define PF_R (1 << 2) /* Segment is readable */ -+#define PF_MASKOS 0x0ff00000 /* OS-specific */ -+#define PF_MASKPROC 0xf0000000 /* Processor-specific */ -+ -+/* Legal values for note segment descriptor types for core files. */ -+ -+#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ -+#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ -+#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ -+#define NT_PRXREG 4 /* Contains copy of prxregset struct */ -+#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ -+#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ -+#define NT_AUXV 6 /* Contains copy of auxv array */ -+#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ -+#define NT_ASRS 8 /* Contains copy of asrset struct */ -+#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ -+#define NT_PSINFO 13 /* Contains copy of psinfo struct */ -+#define NT_PRCRED 14 /* Contains copy of prcred struct */ -+#define NT_UTSNAME 15 /* Contains copy of utsname struct */ -+#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ -+#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ -+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ -+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ -+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ -+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ -+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ -+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ -+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ -+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ -+ -+/* Legal values for the note segment descriptor types for object files. */ -+ -+#define NT_VERSION 1 /* Contains a version string. */ -+ -+ -+/* Dynamic section entry. */ -+ -+typedef struct -+{ -+ Elf32_Sword d_tag; /* Dynamic entry type */ -+ union -+ { -+ Elf32_Word d_val; /* Integer value */ -+ Elf32_Addr d_ptr; /* Address value */ -+ } d_un; -+} Elf32_Dyn; -+ -+typedef struct -+{ -+ Elf64_Sxword d_tag; /* Dynamic entry type */ -+ union -+ { -+ Elf64_Xword d_val; /* Integer value */ -+ Elf64_Addr d_ptr; /* Address value */ -+ } d_un; -+} Elf64_Dyn; -+ -+/* Legal values for d_tag (dynamic entry type). */ -+ -+#define DT_NULL 0 /* Marks end of dynamic section */ -+#define DT_NEEDED 1 /* Name of needed library */ -+#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ -+#define DT_PLTGOT 3 /* Processor defined value */ -+#define DT_HASH 4 /* Address of symbol hash table */ -+#define DT_STRTAB 5 /* Address of string table */ -+#define DT_SYMTAB 6 /* Address of symbol table */ -+#define DT_RELA 7 /* Address of Rela relocs */ -+#define DT_RELASZ 8 /* Total size of Rela relocs */ -+#define DT_RELAENT 9 /* Size of one Rela reloc */ -+#define DT_STRSZ 10 /* Size of string table */ -+#define DT_SYMENT 11 /* Size of one symbol table entry */ -+#define DT_INIT 12 /* Address of init function */ -+#define DT_FINI 13 /* Address of termination function */ -+#define DT_SONAME 14 /* Name of shared object */ -+#define DT_RPATH 15 /* Library search path (deprecated) */ -+#define DT_SYMBOLIC 16 /* Start symbol search here */ -+#define DT_REL 17 /* Address of Rel relocs */ -+#define DT_RELSZ 18 /* Total size of Rel relocs */ -+#define DT_RELENT 19 /* Size of one Rel reloc */ -+#define DT_PLTREL 20 /* Type of reloc in PLT */ -+#define DT_DEBUG 21 /* For debugging; unspecified */ -+#define DT_TEXTREL 22 /* Reloc might modify .text */ -+#define DT_JMPREL 23 /* Address of PLT relocs */ -+#define DT_BIND_NOW 24 /* Process relocations of object */ -+#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ -+#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ -+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ -+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ -+#define DT_RUNPATH 29 /* Library search path */ -+#define DT_FLAGS 30 /* Flags for the object being loaded */ -+#define DT_ENCODING 32 /* Start of encoded range */ -+#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ -+#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ -+#define DT_NUM 34 /* Number used */ -+#define DT_LOOS 0x6000000d /* Start of OS-specific */ -+#define DT_HIOS 0x6ffff000 /* End of OS-specific */ -+#define DT_LOPROC 0x70000000 /* Start of processor-specific */ -+#define DT_HIPROC 0x7fffffff /* End of processor-specific */ -+#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ -+ -+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the -+ Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's -+ approach. */ -+#define DT_VALRNGLO 0x6ffffd00 -+#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ -+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ -+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ -+#define DT_CHECKSUM 0x6ffffdf8 -+#define DT_PLTPADSZ 0x6ffffdf9 -+#define DT_MOVEENT 0x6ffffdfa -+#define DT_MOVESZ 0x6ffffdfb -+#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ -+#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting -+ the following DT_* entry. */ -+#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ -+#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ -+#define DT_VALRNGHI 0x6ffffdff -+#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ -+#define DT_VALNUM 12 -+ -+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the -+ Dyn.d_un.d_ptr field of the Elf*_Dyn structure. -+ -+ If any adjustment is made to the ELF object after it has been -+ built these entries will need to be adjusted. */ -+#define DT_ADDRRNGLO 0x6ffffe00 -+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ -+#define DT_TLSDESC_PLT 0x6ffffef6 -+#define DT_TLSDESC_GOT 0x6ffffef7 -+#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ -+#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ -+#define DT_CONFIG 0x6ffffefa /* Configuration information. */ -+#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ -+#define DT_AUDIT 0x6ffffefc /* Object auditing. */ -+#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ -+#define DT_MOVETAB 0x6ffffefe /* Move table. */ -+#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ -+#define DT_ADDRRNGHI 0x6ffffeff -+#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ -+#define DT_ADDRNUM 11 -+ -+/* The versioning entry types. The next are defined as part of the -+ GNU extension. */ -+#define DT_VERSYM 0x6ffffff0 -+ -+#define DT_RELACOUNT 0x6ffffff9 -+#define DT_RELCOUNT 0x6ffffffa -+ -+/* These were chosen by Sun. */ -+#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ -+#define DT_VERDEF 0x6ffffffc /* Address of version definition -+ table */ -+#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ -+#define DT_VERNEED 0x6ffffffe /* Address of table with needed -+ versions */ -+#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ -+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -+#define DT_VERSIONTAGNUM 16 -+ -+/* Sun added these machine-independent extensions in the "processor-specific" -+ range. Be compatible. */ -+#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ -+#define DT_FILTER 0x7fffffff /* Shared object to get values from */ -+#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) -+#define DT_EXTRANUM 3 -+ -+/* Values of `d_un.d_val' in the DT_FLAGS entry. */ -+#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ -+#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ -+#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ -+#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ -+#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ -+ -+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 -+ entry in the dynamic section. */ -+#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ -+#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ -+#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ -+#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ -+#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ -+#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ -+#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ -+#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ -+#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ -+#define DF_1_TRANS 0x00000200 -+#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ -+#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ -+#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ -+#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ -+#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ -+#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ -+#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ -+ -+/* Flags for the feature selection in DT_FEATURE_1. */ -+#define DTF_1_PARINIT 0x00000001 -+#define DTF_1_CONFEXP 0x00000002 -+ -+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ -+#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ -+#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not -+ generally available. */ -+ -+/* Version definition sections. */ -+ -+typedef struct -+{ -+ Elf32_Half vd_version; /* Version revision */ -+ Elf32_Half vd_flags; /* Version information */ -+ Elf32_Half vd_ndx; /* Version Index */ -+ Elf32_Half vd_cnt; /* Number of associated aux entries */ -+ Elf32_Word vd_hash; /* Version name hash value */ -+ Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ -+ Elf32_Word vd_next; /* Offset in bytes to next verdef -+ entry */ -+} Elf32_Verdef; -+ -+typedef struct -+{ -+ Elf64_Half vd_version; /* Version revision */ -+ Elf64_Half vd_flags; /* Version information */ -+ Elf64_Half vd_ndx; /* Version Index */ -+ Elf64_Half vd_cnt; /* Number of associated aux entries */ -+ Elf64_Word vd_hash; /* Version name hash value */ -+ Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ -+ Elf64_Word vd_next; /* Offset in bytes to next verdef -+ entry */ -+} Elf64_Verdef; -+ -+ -+/* Legal values for vd_version (version revision). */ -+#define VER_DEF_NONE 0 /* No version */ -+#define VER_DEF_CURRENT 1 /* Current version */ -+#define VER_DEF_NUM 2 /* Given version number */ -+ -+/* Legal values for vd_flags (version information flags). */ -+#define VER_FLG_BASE 0x1 /* Version definition of file itself */ -+#define VER_FLG_WEAK 0x2 /* Weak version identifier */ -+ -+/* Versym symbol index values. */ -+#define VER_NDX_LOCAL 0 /* Symbol is local. */ -+#define VER_NDX_GLOBAL 1 /* Symbol is global. */ -+#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ -+#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ -+ -+/* Auxialiary version information. */ -+ -+typedef struct -+{ -+ Elf32_Word vda_name; /* Version or dependency names */ -+ Elf32_Word vda_next; /* Offset in bytes to next verdaux -+ entry */ -+} Elf32_Verdaux; -+ -+typedef struct -+{ -+ Elf64_Word vda_name; /* Version or dependency names */ -+ Elf64_Word vda_next; /* Offset in bytes to next verdaux -+ entry */ -+} Elf64_Verdaux; -+ -+ -+/* Version dependency section. */ -+ -+typedef struct -+{ -+ Elf32_Half vn_version; /* Version of structure */ -+ Elf32_Half vn_cnt; /* Number of associated aux entries */ -+ Elf32_Word vn_file; /* Offset of filename for this -+ dependency */ -+ Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ -+ Elf32_Word vn_next; /* Offset in bytes to next verneed -+ entry */ -+} Elf32_Verneed; -+ -+typedef struct -+{ -+ Elf64_Half vn_version; /* Version of structure */ -+ Elf64_Half vn_cnt; /* Number of associated aux entries */ -+ Elf64_Word vn_file; /* Offset of filename for this -+ dependency */ -+ Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ -+ Elf64_Word vn_next; /* Offset in bytes to next verneed -+ entry */ -+} Elf64_Verneed; -+ -+ -+/* Legal values for vn_version (version revision). */ -+#define VER_NEED_NONE 0 /* No version */ -+#define VER_NEED_CURRENT 1 /* Current version */ -+#define VER_NEED_NUM 2 /* Given version number */ -+ -+/* Auxiliary needed version information. */ -+ -+typedef struct -+{ -+ Elf32_Word vna_hash; /* Hash value of dependency name */ -+ Elf32_Half vna_flags; /* Dependency specific information */ -+ Elf32_Half vna_other; /* Unused */ -+ Elf32_Word vna_name; /* Dependency name string offset */ -+ Elf32_Word vna_next; /* Offset in bytes to next vernaux -+ entry */ -+} Elf32_Vernaux; -+ -+typedef struct -+{ -+ Elf64_Word vna_hash; /* Hash value of dependency name */ -+ Elf64_Half vna_flags; /* Dependency specific information */ -+ Elf64_Half vna_other; /* Unused */ -+ Elf64_Word vna_name; /* Dependency name string offset */ -+ Elf64_Word vna_next; /* Offset in bytes to next vernaux -+ entry */ -+} Elf64_Vernaux; -+ -+ -+/* Legal values for vna_flags. */ -+#define VER_FLG_WEAK 0x2 /* Weak version identifier */ -+ -+ -+/* Auxiliary vector. */ -+ -+/* This vector is normally only used by the program interpreter. The -+ usual definition in an ABI supplement uses the name auxv_t. The -+ vector is not usually defined in a standard file, but it -+ can't hurt. We rename it to avoid conflicts. The sizes of these -+ types are an arrangement between the exec server and the program -+ interpreter, so we don't fully specify them here. */ -+ -+typedef struct -+{ -+ uint32_t a_type; /* Entry type */ -+ union -+ { -+ uint32_t a_val; /* Integer value */ -+ /* We use to have pointer elements added here. We cannot do that, -+ though, since it does not work when using 32-bit definitions -+ on 64-bit platforms and vice versa. */ -+ } a_un; -+} Elf32_auxv_t; -+ -+typedef struct -+{ -+ uint64_t a_type; /* Entry type */ -+ union -+ { -+ uint64_t a_val; /* Integer value */ -+ /* We use to have pointer elements added here. We cannot do that, -+ though, since it does not work when using 32-bit definitions -+ on 64-bit platforms and vice versa. */ -+ } a_un; -+} Elf64_auxv_t; -+ -+/* Legal values for a_type (entry type). */ -+ -+#define AT_NULL 0 /* End of vector */ -+#define AT_IGNORE 1 /* Entry should be ignored */ -+#define AT_EXECFD 2 /* File descriptor of program */ -+#define AT_PHDR 3 /* Program headers for program */ -+#define AT_PHENT 4 /* Size of program header entry */ -+#define AT_PHNUM 5 /* Number of program headers */ -+#define AT_PAGESZ 6 /* System page size */ -+#define AT_BASE 7 /* Base address of interpreter */ -+#define AT_FLAGS 8 /* Flags */ -+#define AT_ENTRY 9 /* Entry point of program */ -+#define AT_NOTELF 10 /* Program is not ELF */ -+#define AT_UID 11 /* Real uid */ -+#define AT_EUID 12 /* Effective uid */ -+#define AT_GID 13 /* Real gid */ -+#define AT_EGID 14 /* Effective gid */ -+#define AT_CLKTCK 17 /* Frequency of times() */ -+ -+/* Some more special a_type values describing the hardware. */ -+#define AT_PLATFORM 15 /* String identifying platform. */ -+#define AT_HWCAP 16 /* Machine dependent hints about -+ processor capabilities. */ -+ -+/* This entry gives some information about the FPU initialization -+ performed by the kernel. */ -+#define AT_FPUCW 18 /* Used FPU control word. */ -+ -+/* Cache block sizes. */ -+#define AT_DCACHEBSIZE 19 /* Data cache block size. */ -+#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ -+#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ -+ -+/* A special ignored value for PPC, used by the kernel to control the -+ interpretation of the AUXV. Must be > 16. */ -+#define AT_IGNOREPPC 22 /* Entry should be ignored. */ -+ -+#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ -+ -+#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ -+ -+#define AT_RANDOM 25 /* Address of 16 random bytes. */ -+ -+#define AT_EXECFN 31 /* Filename of executable. */ -+ -+/* Pointer to the global system page used for system calls and other -+ nice things. */ -+#define AT_SYSINFO 32 -+#define AT_SYSINFO_EHDR 33 -+ -+/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains -+ log2 of line size; mask those to get cache size. */ -+#define AT_L1I_CACHESHAPE 34 -+#define AT_L1D_CACHESHAPE 35 -+#define AT_L2_CACHESHAPE 36 -+#define AT_L3_CACHESHAPE 37 -+ -+/* Note section contents. Each entry in the note section begins with -+ a header of a fixed form. */ -+ -+typedef struct -+{ -+ Elf32_Word n_namesz; /* Length of the note's name. */ -+ Elf32_Word n_descsz; /* Length of the note's descriptor. */ -+ Elf32_Word n_type; /* Type of the note. */ -+} Elf32_Nhdr; -+ -+typedef struct -+{ -+ Elf64_Word n_namesz; /* Length of the note's name. */ -+ Elf64_Word n_descsz; /* Length of the note's descriptor. */ -+ Elf64_Word n_type; /* Type of the note. */ -+} Elf64_Nhdr; -+ -+/* Known names of notes. */ -+ -+/* Solaris entries in the note section have this name. */ -+#define ELF_NOTE_SOLARIS "SUNW Solaris" -+ -+/* Note entries for GNU systems have this name. */ -+#define ELF_NOTE_GNU "GNU" -+ -+ -+/* Defined types of notes for Solaris. */ -+ -+/* Value of descriptor (one word) is desired pagesize for the binary. */ -+#define ELF_NOTE_PAGESIZE_HINT 1 -+ -+ -+/* Defined note types for GNU systems. */ -+ -+/* ABI information. The descriptor consists of words: -+ word 0: OS descriptor -+ word 1: major version of the ABI -+ word 2: minor version of the ABI -+ word 3: subminor version of the ABI -+*/ -+#define NT_GNU_ABI_TAG 1 -+#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ -+ -+/* Known OSes. These values can appear in word 0 of an -+ NT_GNU_ABI_TAG note section entry. */ -+#define ELF_NOTE_OS_LINUX 0 -+#define ELF_NOTE_OS_GNU 1 -+#define ELF_NOTE_OS_SOLARIS2 2 -+#define ELF_NOTE_OS_FREEBSD 3 -+ -+/* Synthetic hwcap information. The descriptor begins with two words: -+ word 0: number of entries -+ word 1: bitmask of enabled entries -+ Then follow variable-length entries, one byte followed by a -+ '\0'-terminated hwcap name string. The byte gives the bit -+ number to test if enabled, (1U << bit) & bitmask. */ -+#define NT_GNU_HWCAP 2 -+ -+/* Build ID bits as generated by ld --build-id. -+ The descriptor consists of any nonzero number of bytes. */ -+#define NT_GNU_BUILD_ID 3 -+ -+/* Version note generated by GNU gold containing a version string. */ -+#define NT_GNU_GOLD_VERSION 4 -+ -+ -+/* Move records. */ -+typedef struct -+{ -+ Elf32_Xword m_value; /* Symbol value. */ -+ Elf32_Word m_info; /* Size and index. */ -+ Elf32_Word m_poffset; /* Symbol offset. */ -+ Elf32_Half m_repeat; /* Repeat count. */ -+ Elf32_Half m_stride; /* Stride info. */ -+} Elf32_Move; -+ -+typedef struct -+{ -+ Elf64_Xword m_value; /* Symbol value. */ -+ Elf64_Xword m_info; /* Size and index. */ -+ Elf64_Xword m_poffset; /* Symbol offset. */ -+ Elf64_Half m_repeat; /* Repeat count. */ -+ Elf64_Half m_stride; /* Stride info. */ -+} Elf64_Move; -+ -+/* Macro to construct move records. */ -+#define ELF32_M_SYM(info) ((info) >> 8) -+#define ELF32_M_SIZE(info) ((unsigned char) (info)) -+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) -+ -+#define ELF64_M_SYM(info) ELF32_M_SYM (info) -+#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) -+#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) -+ -+ -+/* Motorola 68k specific definitions. */ -+ -+/* Values for Elf32_Ehdr.e_flags. */ -+#define EF_CPU32 0x00810000 -+ -+/* m68k relocs. */ -+ -+#define R_68K_NONE 0 /* No reloc */ -+#define R_68K_32 1 /* Direct 32 bit */ -+#define R_68K_16 2 /* Direct 16 bit */ -+#define R_68K_8 3 /* Direct 8 bit */ -+#define R_68K_PC32 4 /* PC relative 32 bit */ -+#define R_68K_PC16 5 /* PC relative 16 bit */ -+#define R_68K_PC8 6 /* PC relative 8 bit */ -+#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ -+#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ -+#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ -+#define R_68K_GOT32O 10 /* 32 bit GOT offset */ -+#define R_68K_GOT16O 11 /* 16 bit GOT offset */ -+#define R_68K_GOT8O 12 /* 8 bit GOT offset */ -+#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ -+#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ -+#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ -+#define R_68K_PLT32O 16 /* 32 bit PLT offset */ -+#define R_68K_PLT16O 17 /* 16 bit PLT offset */ -+#define R_68K_PLT8O 18 /* 8 bit PLT offset */ -+#define R_68K_COPY 19 /* Copy symbol at runtime */ -+#define R_68K_GLOB_DAT 20 /* Create GOT entry */ -+#define R_68K_JMP_SLOT 21 /* Create PLT entry */ -+#define R_68K_RELATIVE 22 /* Adjust by program base */ -+#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ -+#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ -+#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ -+#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ -+#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ -+#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ -+#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ -+#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ -+#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ -+#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ -+#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ -+#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ -+#define R_68K_TLS_LE32 37 /* 32 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_LE16 38 /* 16 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_LE8 39 /* 8 bit offset relative to -+ static TLS block */ -+#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ -+#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ -+#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ -+/* Keep this the last entry. */ -+#define R_68K_NUM 43 -+ -+/* Intel 80386 specific definitions. */ -+ -+/* i386 relocs. */ -+ -+#define R_386_NONE 0 /* No reloc */ -+#define R_386_32 1 /* Direct 32 bit */ -+#define R_386_PC32 2 /* PC relative 32 bit */ -+#define R_386_GOT32 3 /* 32 bit GOT entry */ -+#define R_386_PLT32 4 /* 32 bit PLT address */ -+#define R_386_COPY 5 /* Copy symbol at runtime */ -+#define R_386_GLOB_DAT 6 /* Create GOT entry */ -+#define R_386_JMP_SLOT 7 /* Create PLT entry */ -+#define R_386_RELATIVE 8 /* Adjust by program base */ -+#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ -+#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ -+#define R_386_32PLT 11 -+#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ -+#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS -+ block offset */ -+#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block -+ offset */ -+#define R_386_TLS_LE 17 /* Offset relative to static TLS -+ block */ -+#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of -+ general dynamic thread local data */ -+#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of -+ local dynamic thread local data -+ in LE code */ -+#define R_386_16 20 -+#define R_386_PC16 21 -+#define R_386_8 22 -+#define R_386_PC8 23 -+#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic -+ thread local data */ -+#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ -+#define R_386_TLS_GD_CALL 26 /* Relocation for call to -+ __tls_get_addr() */ -+#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ -+#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic -+ thread local data in LE code */ -+#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ -+#define R_386_TLS_LDM_CALL 30 /* Relocation for call to -+ __tls_get_addr() in LDM code */ -+#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ -+#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ -+#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS -+ block offset */ -+#define R_386_TLS_LE_32 34 /* Negated offset relative to static -+ TLS block */ -+#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ -+#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ -+#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ -+/* 38? */ -+#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ -+#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS -+ descriptor for -+ relaxation. */ -+#define R_386_TLS_DESC 41 /* TLS descriptor containing -+ pointer to code and to -+ argument, returning the TLS -+ offset for the symbol. */ -+#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ -+/* Keep this the last entry. */ -+#define R_386_NUM 43 -+ -+/* SUN SPARC specific definitions. */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ -+ -+/* Values for Elf64_Ehdr.e_flags. */ -+ -+#define EF_SPARCV9_MM 3 -+#define EF_SPARCV9_TSO 0 -+#define EF_SPARCV9_PSO 1 -+#define EF_SPARCV9_RMO 2 -+#define EF_SPARC_LEDATA 0x800000 /* little endian data */ -+#define EF_SPARC_EXT_MASK 0xFFFF00 -+#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ -+#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ -+#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ -+#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ -+ -+/* SPARC relocs. */ -+ -+#define R_SPARC_NONE 0 /* No reloc */ -+#define R_SPARC_8 1 /* Direct 8 bit */ -+#define R_SPARC_16 2 /* Direct 16 bit */ -+#define R_SPARC_32 3 /* Direct 32 bit */ -+#define R_SPARC_DISP8 4 /* PC relative 8 bit */ -+#define R_SPARC_DISP16 5 /* PC relative 16 bit */ -+#define R_SPARC_DISP32 6 /* PC relative 32 bit */ -+#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ -+#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ -+#define R_SPARC_HI22 9 /* High 22 bit */ -+#define R_SPARC_22 10 /* Direct 22 bit */ -+#define R_SPARC_13 11 /* Direct 13 bit */ -+#define R_SPARC_LO10 12 /* Truncated 10 bit */ -+#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ -+#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ -+#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ -+#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ -+#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ -+#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ -+#define R_SPARC_COPY 19 /* Copy symbol at runtime */ -+#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ -+#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ -+#define R_SPARC_RELATIVE 22 /* Adjust by program base */ -+#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ -+ -+/* Additional Sparc64 relocs. */ -+ -+#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ -+#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ -+#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ -+#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ -+#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ -+#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ -+#define R_SPARC_10 30 /* Direct 10 bit */ -+#define R_SPARC_11 31 /* Direct 11 bit */ -+#define R_SPARC_64 32 /* Direct 64 bit */ -+#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ -+#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ -+#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ -+#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ -+#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ -+#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ -+#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ -+#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ -+#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ -+#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ -+#define R_SPARC_7 43 /* Direct 7 bit */ -+#define R_SPARC_5 44 /* Direct 5 bit */ -+#define R_SPARC_6 45 /* Direct 6 bit */ -+#define R_SPARC_DISP64 46 /* PC relative 64 bit */ -+#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ -+#define R_SPARC_HIX22 48 /* High 22 bit complemented */ -+#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ -+#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ -+#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ -+#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ -+#define R_SPARC_REGISTER 53 /* Global register usage */ -+#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ -+#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ -+#define R_SPARC_TLS_GD_HI22 56 -+#define R_SPARC_TLS_GD_LO10 57 -+#define R_SPARC_TLS_GD_ADD 58 -+#define R_SPARC_TLS_GD_CALL 59 -+#define R_SPARC_TLS_LDM_HI22 60 -+#define R_SPARC_TLS_LDM_LO10 61 -+#define R_SPARC_TLS_LDM_ADD 62 -+#define R_SPARC_TLS_LDM_CALL 63 -+#define R_SPARC_TLS_LDO_HIX22 64 -+#define R_SPARC_TLS_LDO_LOX10 65 -+#define R_SPARC_TLS_LDO_ADD 66 -+#define R_SPARC_TLS_IE_HI22 67 -+#define R_SPARC_TLS_IE_LO10 68 -+#define R_SPARC_TLS_IE_LD 69 -+#define R_SPARC_TLS_IE_LDX 70 -+#define R_SPARC_TLS_IE_ADD 71 -+#define R_SPARC_TLS_LE_HIX22 72 -+#define R_SPARC_TLS_LE_LOX10 73 -+#define R_SPARC_TLS_DTPMOD32 74 -+#define R_SPARC_TLS_DTPMOD64 75 -+#define R_SPARC_TLS_DTPOFF32 76 -+#define R_SPARC_TLS_DTPOFF64 77 -+#define R_SPARC_TLS_TPOFF32 78 -+#define R_SPARC_TLS_TPOFF64 79 -+#define R_SPARC_GOTDATA_HIX22 80 -+#define R_SPARC_GOTDATA_LOX10 81 -+#define R_SPARC_GOTDATA_OP_HIX22 82 -+#define R_SPARC_GOTDATA_OP_LOX10 83 -+#define R_SPARC_GOTDATA_OP 84 -+#define R_SPARC_H34 85 -+#define R_SPARC_SIZE32 86 -+#define R_SPARC_SIZE64 87 -+#define R_SPARC_WDISP10 88 -+#define R_SPARC_JMP_IREL 248 -+#define R_SPARC_IRELATIVE 249 -+#define R_SPARC_GNU_VTINHERIT 250 -+#define R_SPARC_GNU_VTENTRY 251 -+#define R_SPARC_REV32 252 -+/* Keep this the last entry. */ -+#define R_SPARC_NUM 253 -+ -+/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ -+ -+#define DT_SPARC_REGISTER 0x70000001 -+#define DT_SPARC_NUM 2 -+ -+/* MIPS R3000 specific definitions. */ -+ -+/* Legal values for e_flags field of Elf32_Ehdr. */ -+ -+#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ -+#define EF_MIPS_PIC 2 /* Contains PIC code */ -+#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ -+#define EF_MIPS_XGOT 8 -+#define EF_MIPS_64BIT_WHIRL 16 -+#define EF_MIPS_ABI2 32 -+#define EF_MIPS_ABI_ON32 64 -+#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ -+ -+/* Legal values for MIPS architecture level. */ -+ -+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -+#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -+#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ -+ -+/* The following are non-official names and should not be used. */ -+ -+#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -+#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -+#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -+#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -+#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -+#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ -+#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ -+ -+/* Special section indices. */ -+ -+#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ -+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ -+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ -+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ -+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ -+ -+/* Legal values for sh_type field of Elf32_Shdr. */ -+ -+#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ -+#define SHT_MIPS_MSYM 0x70000001 -+#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ -+#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ -+#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ -+#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ -+#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ -+#define SHT_MIPS_PACKAGE 0x70000007 -+#define SHT_MIPS_PACKSYM 0x70000008 -+#define SHT_MIPS_RELD 0x70000009 -+#define SHT_MIPS_IFACE 0x7000000b -+#define SHT_MIPS_CONTENT 0x7000000c -+#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ -+#define SHT_MIPS_SHDR 0x70000010 -+#define SHT_MIPS_FDESC 0x70000011 -+#define SHT_MIPS_EXTSYM 0x70000012 -+#define SHT_MIPS_DENSE 0x70000013 -+#define SHT_MIPS_PDESC 0x70000014 -+#define SHT_MIPS_LOCSYM 0x70000015 -+#define SHT_MIPS_AUXSYM 0x70000016 -+#define SHT_MIPS_OPTSYM 0x70000017 -+#define SHT_MIPS_LOCSTR 0x70000018 -+#define SHT_MIPS_LINE 0x70000019 -+#define SHT_MIPS_RFDESC 0x7000001a -+#define SHT_MIPS_DELTASYM 0x7000001b -+#define SHT_MIPS_DELTAINST 0x7000001c -+#define SHT_MIPS_DELTACLASS 0x7000001d -+#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ -+#define SHT_MIPS_DELTADECL 0x7000001f -+#define SHT_MIPS_SYMBOL_LIB 0x70000020 -+#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ -+#define SHT_MIPS_TRANSLATE 0x70000022 -+#define SHT_MIPS_PIXIE 0x70000023 -+#define SHT_MIPS_XLATE 0x70000024 -+#define SHT_MIPS_XLATE_DEBUG 0x70000025 -+#define SHT_MIPS_WHIRL 0x70000026 -+#define SHT_MIPS_EH_REGION 0x70000027 -+#define SHT_MIPS_XLATE_OLD 0x70000028 -+#define SHT_MIPS_PDR_EXCEPTION 0x70000029 -+ -+/* Legal values for sh_flags field of Elf32_Shdr. */ -+ -+#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ -+#define SHF_MIPS_MERGE 0x20000000 -+#define SHF_MIPS_ADDR 0x40000000 -+#define SHF_MIPS_STRINGS 0x80000000 -+#define SHF_MIPS_NOSTRIP 0x08000000 -+#define SHF_MIPS_LOCAL 0x04000000 -+#define SHF_MIPS_NAMES 0x02000000 -+#define SHF_MIPS_NODUPE 0x01000000 -+ -+ -+/* Symbol tables. */ -+ -+/* MIPS specific values for `st_other'. */ -+#define STO_MIPS_DEFAULT 0x0 -+#define STO_MIPS_INTERNAL 0x1 -+#define STO_MIPS_HIDDEN 0x2 -+#define STO_MIPS_PROTECTED 0x3 -+#define STO_MIPS_PLT 0x8 -+#define STO_MIPS_SC_ALIGN_UNUSED 0xff -+ -+/* MIPS specific values for `st_info'. */ -+#define STB_MIPS_SPLIT_COMMON 13 -+ -+/* Entries found in sections of type SHT_MIPS_GPTAB. */ -+ -+typedef union -+{ -+ struct -+ { -+ Elf32_Word gt_current_g_value; /* -G value used for compilation */ -+ Elf32_Word gt_unused; /* Not used */ -+ } gt_header; /* First entry in section */ -+ struct -+ { -+ Elf32_Word gt_g_value; /* If this value were used for -G */ -+ Elf32_Word gt_bytes; /* This many bytes would be used */ -+ } gt_entry; /* Subsequent entries in section */ -+} Elf32_gptab; -+ -+/* Entry found in sections of type SHT_MIPS_REGINFO. */ -+ -+typedef struct -+{ -+ Elf32_Word ri_gprmask; /* General registers used */ -+ Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ -+ Elf32_Sword ri_gp_value; /* $gp register value */ -+} Elf32_RegInfo; -+ -+/* Entries found in sections of type SHT_MIPS_OPTIONS. */ -+ -+typedef struct -+{ -+ unsigned char kind; /* Determines interpretation of the -+ variable part of descriptor. */ -+ unsigned char size; /* Size of descriptor, including header. */ -+ Elf32_Section section; /* Section header index of section affected, -+ 0 for global options. */ -+ Elf32_Word info; /* Kind-specific information. */ -+} Elf_Options; -+ -+/* Values for `kind' field in Elf_Options. */ -+ -+#define ODK_NULL 0 /* Undefined. */ -+#define ODK_REGINFO 1 /* Register usage information. */ -+#define ODK_EXCEPTIONS 2 /* Exception processing options. */ -+#define ODK_PAD 3 /* Section padding options. */ -+#define ODK_HWPATCH 4 /* Hardware workarounds performed */ -+#define ODK_FILL 5 /* record the fill value used by the linker. */ -+#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ -+#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ -+#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ -+ -+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ -+ -+#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ -+#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ -+#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ -+#define OEX_SMM 0x20000 /* Force sequential memory mode? */ -+#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ -+#define OEX_PRECISEFP OEX_FPDBUG -+#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ -+ -+#define OEX_FPU_INVAL 0x10 -+#define OEX_FPU_DIV0 0x08 -+#define OEX_FPU_OFLO 0x04 -+#define OEX_FPU_UFLO 0x02 -+#define OEX_FPU_INEX 0x01 -+ -+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ -+ -+#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ -+#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ -+#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ -+#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ -+ -+#define OPAD_PREFIX 0x1 -+#define OPAD_POSTFIX 0x2 -+#define OPAD_SYMBOL 0x4 -+ -+/* Entry found in `.options' section. */ -+ -+typedef struct -+{ -+ Elf32_Word hwp_flags1; /* Extra flags. */ -+ Elf32_Word hwp_flags2; /* Extra flags. */ -+} Elf_Options_Hw; -+ -+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ -+ -+#define OHWA0_R4KEOP_CHECKED 0x00000001 -+#define OHWA1_R4KEOP_CLEAN 0x00000002 -+ -+/* MIPS relocs. */ -+ -+#define R_MIPS_NONE 0 /* No reloc */ -+#define R_MIPS_16 1 /* Direct 16 bit */ -+#define R_MIPS_32 2 /* Direct 32 bit */ -+#define R_MIPS_REL32 3 /* PC relative 32 bit */ -+#define R_MIPS_26 4 /* Direct 26 bit shifted */ -+#define R_MIPS_HI16 5 /* High 16 bit */ -+#define R_MIPS_LO16 6 /* Low 16 bit */ -+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ -+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ -+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ -+#define R_MIPS_PC16 10 /* PC relative 16 bit */ -+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ -+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ -+ -+#define R_MIPS_SHIFT5 16 -+#define R_MIPS_SHIFT6 17 -+#define R_MIPS_64 18 -+#define R_MIPS_GOT_DISP 19 -+#define R_MIPS_GOT_PAGE 20 -+#define R_MIPS_GOT_OFST 21 -+#define R_MIPS_GOT_HI16 22 -+#define R_MIPS_GOT_LO16 23 -+#define R_MIPS_SUB 24 -+#define R_MIPS_INSERT_A 25 -+#define R_MIPS_INSERT_B 26 -+#define R_MIPS_DELETE 27 -+#define R_MIPS_HIGHER 28 -+#define R_MIPS_HIGHEST 29 -+#define R_MIPS_CALL_HI16 30 -+#define R_MIPS_CALL_LO16 31 -+#define R_MIPS_SCN_DISP 32 -+#define R_MIPS_REL16 33 -+#define R_MIPS_ADD_IMMEDIATE 34 -+#define R_MIPS_PJUMP 35 -+#define R_MIPS_RELGOT 36 -+#define R_MIPS_JALR 37 -+#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ -+#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ -+#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ -+#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ -+#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ -+#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ -+#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ -+#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ -+#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ -+#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ -+#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ -+#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ -+#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ -+#define R_MIPS_GLOB_DAT 51 -+#define R_MIPS_COPY 126 -+#define R_MIPS_JUMP_SLOT 127 -+/* Keep this the last entry. */ -+#define R_MIPS_NUM 128 -+ -+/* Legal values for p_type field of Elf32_Phdr. */ -+ -+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ -+#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ -+#define PT_MIPS_OPTIONS 0x70000002 -+ -+/* Special program header types. */ -+ -+#define PF_MIPS_LOCAL 0x10000000 -+ -+/* Legal values for d_tag field of Elf32_Dyn. */ -+ -+#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ -+#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ -+#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ -+#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ -+#define DT_MIPS_FLAGS 0x70000005 /* Flags */ -+#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ -+#define DT_MIPS_MSYM 0x70000007 -+#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ -+#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ -+#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ -+#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ -+#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ -+#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ -+#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ -+#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ -+#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ -+#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ -+#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ -+#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in -+ DT_MIPS_DELTA_CLASS. */ -+#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ -+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in -+ DT_MIPS_DELTA_INSTANCE. */ -+#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ -+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in -+ DT_MIPS_DELTA_RELOC. */ -+#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta -+ relocations refer to. */ -+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in -+ DT_MIPS_DELTA_SYM. */ -+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the -+ class declaration. */ -+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in -+ DT_MIPS_DELTA_CLASSSYM. */ -+#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ -+#define DT_MIPS_PIXIE_INIT 0x70000023 -+#define DT_MIPS_SYMBOL_LIB 0x70000024 -+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 -+#define DT_MIPS_LOCAL_GOTIDX 0x70000026 -+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 -+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 -+#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ -+#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ -+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b -+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ -+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve -+ function stored in GOT. */ -+#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added -+ by rld on dlopen() calls. */ -+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ -+#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ -+#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ -+/* The address of .got.plt in an executable using the new non-PIC ABI. */ -+#define DT_MIPS_PLTGOT 0x70000032 -+/* The base of the PLT in an executable using the new non-PIC ABI if that -+ PLT is writable. For a non-writable PLT, this is omitted or has a zero -+ value. */ -+#define DT_MIPS_RWPLT 0x70000034 -+#define DT_MIPS_NUM 0x35 -+ -+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ -+ -+#define RHF_NONE 0 /* No flags */ -+#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ -+#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ -+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ -+#define RHF_NO_MOVE (1 << 3) -+#define RHF_SGI_ONLY (1 << 4) -+#define RHF_GUARANTEE_INIT (1 << 5) -+#define RHF_DELTA_C_PLUS_PLUS (1 << 6) -+#define RHF_GUARANTEE_START_INIT (1 << 7) -+#define RHF_PIXIE (1 << 8) -+#define RHF_DEFAULT_DELAY_LOAD (1 << 9) -+#define RHF_REQUICKSTART (1 << 10) -+#define RHF_REQUICKSTARTED (1 << 11) -+#define RHF_CORD (1 << 12) -+#define RHF_NO_UNRES_UNDEF (1 << 13) -+#define RHF_RLD_ORDER_SAFE (1 << 14) -+ -+/* Entries found in sections of type SHT_MIPS_LIBLIST. */ -+ -+typedef struct -+{ -+ Elf32_Word l_name; /* Name (string table index) */ -+ Elf32_Word l_time_stamp; /* Timestamp */ -+ Elf32_Word l_checksum; /* Checksum */ -+ Elf32_Word l_version; /* Interface version */ -+ Elf32_Word l_flags; /* Flags */ -+} Elf32_Lib; -+ -+typedef struct -+{ -+ Elf64_Word l_name; /* Name (string table index) */ -+ Elf64_Word l_time_stamp; /* Timestamp */ -+ Elf64_Word l_checksum; /* Checksum */ -+ Elf64_Word l_version; /* Interface version */ -+ Elf64_Word l_flags; /* Flags */ -+} Elf64_Lib; -+ -+ -+/* Legal values for l_flags. */ -+ -+#define LL_NONE 0 -+#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ -+#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ -+#define LL_REQUIRE_MINOR (1 << 2) -+#define LL_EXPORTS (1 << 3) -+#define LL_DELAY_LOAD (1 << 4) -+#define LL_DELTA (1 << 5) -+ -+/* Entries found in sections of type SHT_MIPS_CONFLICT. */ -+ -+typedef Elf32_Addr Elf32_Conflict; -+ -+ -+/* HPPA specific definitions. */ -+ -+/* Legal values for e_flags field of Elf32_Ehdr. */ -+ -+#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ -+#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ -+#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ -+#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ -+#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch -+ prediction. */ -+#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ -+#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ -+ -+/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ -+ -+#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ -+#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ -+#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ -+ -+/* Additional section indeces. */ -+ -+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared -+ symbols in ANSI C. */ -+#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ -+ -+/* Legal values for sh_type field of Elf32_Shdr. */ -+ -+#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ -+#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ -+#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ -+ -+/* Legal values for sh_flags field of Elf32_Shdr. */ -+ -+#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ -+#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ -+#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ -+ -+/* Legal values for ST_TYPE subfield of st_info (symbol type). */ -+ -+#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ -+ -+#define STT_HP_OPAQUE (STT_LOOS + 0x1) -+#define STT_HP_STUB (STT_LOOS + 0x2) -+ -+/* HPPA relocs. */ -+ -+#define R_PARISC_NONE 0 /* No reloc. */ -+#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ -+#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ -+#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ -+#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ -+#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ -+#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ -+#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ -+#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ -+#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ -+#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ -+#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ -+#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ -+#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ -+#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ -+#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ -+#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ -+#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ -+#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ -+#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ -+#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ -+#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ -+#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ -+#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ -+#define R_PARISC_FPTR64 64 /* 64 bits function address. */ -+#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ -+#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ -+#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ -+#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ -+#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ -+#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ -+#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ -+#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ -+#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ -+#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ -+#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ -+#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ -+#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ -+#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ -+#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ -+#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ -+#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ -+#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ -+#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ -+#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ -+#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ -+#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ -+#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ -+#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ -+#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ -+#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ -+#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ -+#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ -+#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ -+#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ -+#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ -+#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ -+#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ -+#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ -+#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ -+#define R_PARISC_LORESERVE 128 -+#define R_PARISC_COPY 128 /* Copy relocation. */ -+#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ -+#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ -+#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ -+#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ -+#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ -+#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ -+#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ -+#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ -+#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ -+#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ -+#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ -+#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ -+#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ -+#define R_PARISC_GNU_VTENTRY 232 -+#define R_PARISC_GNU_VTINHERIT 233 -+#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ -+#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ -+#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ -+#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ -+#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ -+#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ -+#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ -+#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ -+#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ -+#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ -+#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ -+#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ -+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L -+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R -+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L -+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R -+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 -+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 -+#define R_PARISC_HIRESERVE 255 -+ -+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ -+ -+#define PT_HP_TLS (PT_LOOS + 0x0) -+#define PT_HP_CORE_NONE (PT_LOOS + 0x1) -+#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) -+#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) -+#define PT_HP_CORE_COMM (PT_LOOS + 0x4) -+#define PT_HP_CORE_PROC (PT_LOOS + 0x5) -+#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) -+#define PT_HP_CORE_STACK (PT_LOOS + 0x7) -+#define PT_HP_CORE_SHM (PT_LOOS + 0x8) -+#define PT_HP_CORE_MMF (PT_LOOS + 0x9) -+#define PT_HP_PARALLEL (PT_LOOS + 0x10) -+#define PT_HP_FASTBIND (PT_LOOS + 0x11) -+#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) -+#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) -+#define PT_HP_STACK (PT_LOOS + 0x14) -+ -+#define PT_PARISC_ARCHEXT 0x70000000 -+#define PT_PARISC_UNWIND 0x70000001 -+ -+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ -+ -+#define PF_PARISC_SBP 0x08000000 -+ -+#define PF_HP_PAGE_SIZE 0x00100000 -+#define PF_HP_FAR_SHARED 0x00200000 -+#define PF_HP_NEAR_SHARED 0x00400000 -+#define PF_HP_CODE 0x01000000 -+#define PF_HP_MODIFY 0x02000000 -+#define PF_HP_LAZYSWAP 0x04000000 -+#define PF_HP_SBP 0x08000000 -+ -+ -+/* Alpha specific definitions. */ -+ -+/* Legal values for e_flags field of Elf64_Ehdr. */ -+ -+#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ -+#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ -+ -+/* Legal values for sh_type field of Elf64_Shdr. */ -+ -+/* These two are primerily concerned with ECOFF debugging info. */ -+#define SHT_ALPHA_DEBUG 0x70000001 -+#define SHT_ALPHA_REGINFO 0x70000002 -+ -+/* Legal values for sh_flags field of Elf64_Shdr. */ -+ -+#define SHF_ALPHA_GPREL 0x10000000 -+ -+/* Legal values for st_other field of Elf64_Sym. */ -+#define STO_ALPHA_NOPV 0x80 /* No PV required. */ -+#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ -+ -+/* Alpha relocs. */ -+ -+#define R_ALPHA_NONE 0 /* No reloc */ -+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -+#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ -+#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ -+#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ -+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ -+#define R_ALPHA_TLS_GD_HI 28 -+#define R_ALPHA_TLSGD 29 -+#define R_ALPHA_TLS_LDM 30 -+#define R_ALPHA_DTPMOD64 31 -+#define R_ALPHA_GOTDTPREL 32 -+#define R_ALPHA_DTPREL64 33 -+#define R_ALPHA_DTPRELHI 34 -+#define R_ALPHA_DTPRELLO 35 -+#define R_ALPHA_DTPREL16 36 -+#define R_ALPHA_GOTTPREL 37 -+#define R_ALPHA_TPREL64 38 -+#define R_ALPHA_TPRELHI 39 -+#define R_ALPHA_TPRELLO 40 -+#define R_ALPHA_TPREL16 41 -+/* Keep this the last entry. */ -+#define R_ALPHA_NUM 46 -+ -+/* Magic values of the LITUSE relocation addend. */ -+#define LITUSE_ALPHA_ADDR 0 -+#define LITUSE_ALPHA_BASE 1 -+#define LITUSE_ALPHA_BYTOFF 2 -+#define LITUSE_ALPHA_JSR 3 -+#define LITUSE_ALPHA_TLS_GD 4 -+#define LITUSE_ALPHA_TLS_LDM 5 -+ -+/* Legal values for d_tag of Elf64_Dyn. */ -+#define DT_ALPHA_PLTRO (DT_LOPROC + 0) -+#define DT_ALPHA_NUM 1 -+ -+/* PowerPC specific declarations */ -+ -+/* Values for Elf32/64_Ehdr.e_flags. */ -+#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ -+ -+/* Cygnus local bits below */ -+#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ -+#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib -+ flag */ -+ -+/* PowerPC relocations defined by the ABIs */ -+#define R_PPC_NONE 0 -+#define R_PPC_ADDR32 1 /* 32bit absolute address */ -+#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -+#define R_PPC_ADDR16 3 /* 16bit absolute address */ -+#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -+#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -+#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -+#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -+#define R_PPC_ADDR14_BRTAKEN 8 -+#define R_PPC_ADDR14_BRNTAKEN 9 -+#define R_PPC_REL24 10 /* PC relative 26 bit */ -+#define R_PPC_REL14 11 /* PC relative 16 bit */ -+#define R_PPC_REL14_BRTAKEN 12 -+#define R_PPC_REL14_BRNTAKEN 13 -+#define R_PPC_GOT16 14 -+#define R_PPC_GOT16_LO 15 -+#define R_PPC_GOT16_HI 16 -+#define R_PPC_GOT16_HA 17 -+#define R_PPC_PLTREL24 18 -+#define R_PPC_COPY 19 -+#define R_PPC_GLOB_DAT 20 -+#define R_PPC_JMP_SLOT 21 -+#define R_PPC_RELATIVE 22 -+#define R_PPC_LOCAL24PC 23 -+#define R_PPC_UADDR32 24 -+#define R_PPC_UADDR16 25 -+#define R_PPC_REL32 26 -+#define R_PPC_PLT32 27 -+#define R_PPC_PLTREL32 28 -+#define R_PPC_PLT16_LO 29 -+#define R_PPC_PLT16_HI 30 -+#define R_PPC_PLT16_HA 31 -+#define R_PPC_SDAREL16 32 -+#define R_PPC_SECTOFF 33 -+#define R_PPC_SECTOFF_LO 34 -+#define R_PPC_SECTOFF_HI 35 -+#define R_PPC_SECTOFF_HA 36 -+ -+/* PowerPC relocations defined for the TLS access ABI. */ -+#define R_PPC_TLS 67 /* none (sym+add)@tls */ -+#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ -+#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ -+#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -+#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -+#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -+#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ -+#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ -+#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -+#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -+#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -+#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ -+#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -+#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -+#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -+#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -+#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -+#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -+#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -+#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -+#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ -+#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ -+#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -+#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -+#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ -+#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ -+#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ -+#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ -+ -+/* The remaining relocs are from the Embedded ELF ABI, and are not -+ in the SVR4 ELF ABI. */ -+#define R_PPC_EMB_NADDR32 101 -+#define R_PPC_EMB_NADDR16 102 -+#define R_PPC_EMB_NADDR16_LO 103 -+#define R_PPC_EMB_NADDR16_HI 104 -+#define R_PPC_EMB_NADDR16_HA 105 -+#define R_PPC_EMB_SDAI16 106 -+#define R_PPC_EMB_SDA2I16 107 -+#define R_PPC_EMB_SDA2REL 108 -+#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ -+#define R_PPC_EMB_MRKREF 110 -+#define R_PPC_EMB_RELSEC16 111 -+#define R_PPC_EMB_RELST_LO 112 -+#define R_PPC_EMB_RELST_HI 113 -+#define R_PPC_EMB_RELST_HA 114 -+#define R_PPC_EMB_BIT_FLD 115 -+#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ -+ -+/* Diab tool relocations. */ -+#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ -+#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ -+#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ -+#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ -+#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ -+#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ -+ -+/* GNU extension to support local ifunc. */ -+#define R_PPC_IRELATIVE 248 -+ -+/* GNU relocs used in PIC code sequences. */ -+#define R_PPC_REL16 249 /* half16 (sym+add-.) */ -+#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ -+#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ -+#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ -+ -+/* This is a phony reloc to handle any old fashioned TOC16 references -+ that may still be in object files. */ -+#define R_PPC_TOC16 255 -+ -+/* PowerPC specific values for the Dyn d_tag field. */ -+#define DT_PPC_GOT (DT_LOPROC + 0) -+#define DT_PPC_NUM 1 -+ -+/* PowerPC64 relocations defined by the ABIs */ -+#define R_PPC64_NONE R_PPC_NONE -+#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ -+#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ -+#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ -+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ -+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ -+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ -+#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ -+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN -+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN -+#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ -+#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ -+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN -+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN -+#define R_PPC64_GOT16 R_PPC_GOT16 -+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO -+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI -+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA -+ -+#define R_PPC64_COPY R_PPC_COPY -+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT -+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT -+#define R_PPC64_RELATIVE R_PPC_RELATIVE -+ -+#define R_PPC64_UADDR32 R_PPC_UADDR32 -+#define R_PPC64_UADDR16 R_PPC_UADDR16 -+#define R_PPC64_REL32 R_PPC_REL32 -+#define R_PPC64_PLT32 R_PPC_PLT32 -+#define R_PPC64_PLTREL32 R_PPC_PLTREL32 -+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO -+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI -+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA -+ -+#define R_PPC64_SECTOFF R_PPC_SECTOFF -+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO -+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI -+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA -+#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ -+#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ -+#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ -+#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ -+#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ -+#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ -+#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ -+#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ -+#define R_PPC64_PLT64 45 /* doubleword64 L + A */ -+#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ -+#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ -+#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ -+#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ -+#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ -+#define R_PPC64_TOC 51 /* doubleword64 .TOC */ -+#define R_PPC64_PLTGOT16 52 /* half16* M + A */ -+#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ -+#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ -+#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ -+ -+#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ -+#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ -+#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ -+#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ -+#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ -+#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ -+#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ -+#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ -+#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ -+#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ -+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ -+ -+/* PowerPC64 relocations defined for the TLS access ABI. */ -+#define R_PPC64_TLS 67 /* none (sym+add)@tls */ -+#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ -+#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ -+#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -+#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -+#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -+#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ -+#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ -+#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -+#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -+#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -+#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ -+#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -+#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -+#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -+#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -+#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -+#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -+#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -+#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -+#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ -+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ -+#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -+#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -+#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ -+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ -+#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ -+#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ -+#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ -+#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ -+#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ -+#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ -+#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ -+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ -+#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ -+#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ -+#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ -+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ -+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ -+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ -+ -+/* GNU extension to support local ifunc. */ -+#define R_PPC64_JMP_IREL 247 -+#define R_PPC64_IRELATIVE 248 -+#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ -+#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ -+#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ -+#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ -+ -+/* PowerPC64 specific values for the Dyn d_tag field. */ -+#define DT_PPC64_GLINK (DT_LOPROC + 0) -+#define DT_PPC64_OPD (DT_LOPROC + 1) -+#define DT_PPC64_OPDSZ (DT_LOPROC + 2) -+#define DT_PPC64_NUM 3 -+ -+ -+/* ARM specific declarations */ -+ -+/* Processor specific flags for the ELF header e_flags field. */ -+#define EF_ARM_RELEXEC 0x01 -+#define EF_ARM_HASENTRY 0x02 -+#define EF_ARM_INTERWORK 0x04 -+#define EF_ARM_APCS_26 0x08 -+#define EF_ARM_APCS_FLOAT 0x10 -+#define EF_ARM_PIC 0x20 -+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -+#define EF_ARM_NEW_ABI 0x80 -+#define EF_ARM_OLD_ABI 0x100 -+#define EF_ARM_SOFT_FLOAT 0x200 -+#define EF_ARM_VFP_FLOAT 0x400 -+#define EF_ARM_MAVERICK_FLOAT 0x800 -+ -+ -+/* Other constants defined in the ARM ELF spec. version B-01. */ -+/* NB. These conflict with values defined above. */ -+#define EF_ARM_SYMSARESORTED 0x04 -+#define EF_ARM_DYNSYMSUSESEGIDX 0x08 -+#define EF_ARM_MAPSYMSFIRST 0x10 -+#define EF_ARM_EABIMASK 0XFF000000 -+ -+/* Constants defined in AAELF. */ -+#define EF_ARM_BE8 0x00800000 -+#define EF_ARM_LE8 0x00400000 -+ -+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) -+#define EF_ARM_EABI_UNKNOWN 0x00000000 -+#define EF_ARM_EABI_VER1 0x01000000 -+#define EF_ARM_EABI_VER2 0x02000000 -+#define EF_ARM_EABI_VER3 0x03000000 -+#define EF_ARM_EABI_VER4 0x04000000 -+#define EF_ARM_EABI_VER5 0x05000000 -+ -+/* Additional symbol types for Thumb. */ -+#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -+#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ -+ -+/* ARM-specific values for sh_flags */ -+#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ -+#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined -+ in the input to a link step. */ -+ -+/* ARM-specific program header flags */ -+#define PF_ARM_SB 0x10000000 /* Segment contains the location -+ addressed by the static base. */ -+#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ -+#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ -+ -+/* Processor specific values for the Phdr p_type field. */ -+#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ -+ -+/* Processor specific values for the Shdr sh_type field. */ -+#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ -+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ -+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ -+ -+ -+/* ARM relocs. */ -+ -+#define R_ARM_NONE 0 /* No reloc */ -+#define R_ARM_PC24 1 /* PC relative 26 bit branch */ -+#define R_ARM_ABS32 2 /* Direct 32 bit */ -+#define R_ARM_REL32 3 /* PC relative 32 bit */ -+#define R_ARM_PC13 4 -+#define R_ARM_ABS16 5 /* Direct 16 bit */ -+#define R_ARM_ABS12 6 /* Direct 12 bit */ -+#define R_ARM_THM_ABS5 7 -+#define R_ARM_ABS8 8 /* Direct 8 bit */ -+#define R_ARM_SBREL32 9 -+#define R_ARM_THM_PC22 10 -+#define R_ARM_THM_PC8 11 -+#define R_ARM_AMP_VCALL9 12 -+#define R_ARM_SWI24 13 /* Obsolete static relocation. */ -+#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ -+#define R_ARM_THM_SWI8 14 -+#define R_ARM_XPC25 15 -+#define R_ARM_THM_XPC22 16 -+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ -+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ -+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ -+#define R_ARM_COPY 20 /* Copy symbol at runtime */ -+#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ -+#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ -+#define R_ARM_RELATIVE 23 /* Adjust by program base */ -+#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ -+#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ -+#define R_ARM_GOT32 26 /* 32 bit GOT entry */ -+#define R_ARM_PLT32 27 /* 32 bit PLT address */ -+#define R_ARM_ALU_PCREL_7_0 32 -+#define R_ARM_ALU_PCREL_15_8 33 -+#define R_ARM_ALU_PCREL_23_15 34 -+#define R_ARM_LDR_SBREL_11_0 35 -+#define R_ARM_ALU_SBREL_19_12 36 -+#define R_ARM_ALU_SBREL_27_20 37 -+#define R_ARM_TLS_GOTDESC 90 -+#define R_ARM_TLS_CALL 91 -+#define R_ARM_TLS_DESCSEQ 92 -+#define R_ARM_THM_TLS_CALL 93 -+#define R_ARM_GNU_VTENTRY 100 -+#define R_ARM_GNU_VTINHERIT 101 -+#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ -+#define R_ARM_THM_PC9 103 /* thumb conditional branch */ -+#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic -+ thread local data */ -+#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic -+ thread local data */ -+#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS -+ block */ -+#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of -+ static TLS block offset */ -+#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static -+ TLS block */ -+#define R_ARM_THM_TLS_DESCSEQ 129 -+#define R_ARM_IRELATIVE 160 -+#define R_ARM_RXPC25 249 -+#define R_ARM_RSBREL32 250 -+#define R_ARM_THM_RPC22 251 -+#define R_ARM_RREL32 252 -+#define R_ARM_RABS22 253 -+#define R_ARM_RPC24 254 -+#define R_ARM_RBASE 255 -+/* Keep this the last entry. */ -+#define R_ARM_NUM 256 -+ -+/* IA-64 specific declarations. */ -+ -+/* Processor specific flags for the Ehdr e_flags field. */ -+#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ -+#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ -+#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ -+ -+/* Processor specific values for the Phdr p_type field. */ -+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ -+#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ -+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) -+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) -+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) -+ -+/* Processor specific flags for the Phdr p_flags field. */ -+#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ -+ -+/* Processor specific values for the Shdr sh_type field. */ -+#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ -+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ -+ -+/* Processor specific flags for the Shdr sh_flags field. */ -+#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ -+#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ -+ -+/* Processor specific values for the Dyn d_tag field. */ -+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) -+#define DT_IA_64_NUM 1 -+ -+/* IA-64 relocations. */ -+#define R_IA64_NONE 0x00 /* none */ -+#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ -+#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ -+#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ -+#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ -+#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ -+#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ -+#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ -+#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ -+#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ -+#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ -+#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ -+#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ -+#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ -+#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ -+#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ -+#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ -+#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ -+#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ -+#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ -+#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ -+#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ -+#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ -+#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ -+#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ -+#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ -+#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ -+#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ -+#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ -+#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ -+#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ -+#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ -+#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ -+#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ -+#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ -+#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ -+#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ -+#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ -+#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ -+#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ -+#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ -+#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ -+#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ -+#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ -+#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ -+#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ -+#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ -+#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ -+#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ -+#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ -+#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ -+#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ -+#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ -+#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ -+#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ -+#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ -+#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ -+#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ -+#define R_IA64_COPY 0x84 /* copy relocation */ -+#define R_IA64_SUB 0x85 /* Addend and symbol difference */ -+#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ -+#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ -+#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ -+#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ -+#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ -+#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ -+#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ -+#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ -+#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ -+#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ -+#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ -+#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ -+#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ -+#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ -+#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ -+#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ -+#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ -+ -+/* SH specific declarations */ -+ -+/* Processor specific flags for the ELF header e_flags field. */ -+#define EF_SH_MACH_MASK 0x1f -+#define EF_SH_UNKNOWN 0x0 -+#define EF_SH1 0x1 -+#define EF_SH2 0x2 -+#define EF_SH3 0x3 -+#define EF_SH_DSP 0x4 -+#define EF_SH3_DSP 0x5 -+#define EF_SH4AL_DSP 0x6 -+#define EF_SH3E 0x8 -+#define EF_SH4 0x9 -+#define EF_SH2E 0xb -+#define EF_SH4A 0xc -+#define EF_SH2A 0xd -+#define EF_SH4_NOFPU 0x10 -+#define EF_SH4A_NOFPU 0x11 -+#define EF_SH4_NOMMU_NOFPU 0x12 -+#define EF_SH2A_NOFPU 0x13 -+#define EF_SH3_NOMMU 0x14 -+#define EF_SH2A_SH4_NOFPU 0x15 -+#define EF_SH2A_SH3_NOFPU 0x16 -+#define EF_SH2A_SH4 0x17 -+#define EF_SH2A_SH3E 0x18 -+ -+/* SH relocs. */ -+#define R_SH_NONE 0 -+#define R_SH_DIR32 1 -+#define R_SH_REL32 2 -+#define R_SH_DIR8WPN 3 -+#define R_SH_IND12W 4 -+#define R_SH_DIR8WPL 5 -+#define R_SH_DIR8WPZ 6 -+#define R_SH_DIR8BP 7 -+#define R_SH_DIR8W 8 -+#define R_SH_DIR8L 9 -+#define R_SH_SWITCH16 25 -+#define R_SH_SWITCH32 26 -+#define R_SH_USES 27 -+#define R_SH_COUNT 28 -+#define R_SH_ALIGN 29 -+#define R_SH_CODE 30 -+#define R_SH_DATA 31 -+#define R_SH_LABEL 32 -+#define R_SH_SWITCH8 33 -+#define R_SH_GNU_VTINHERIT 34 -+#define R_SH_GNU_VTENTRY 35 -+#define R_SH_TLS_GD_32 144 -+#define R_SH_TLS_LD_32 145 -+#define R_SH_TLS_LDO_32 146 -+#define R_SH_TLS_IE_32 147 -+#define R_SH_TLS_LE_32 148 -+#define R_SH_TLS_DTPMOD32 149 -+#define R_SH_TLS_DTPOFF32 150 -+#define R_SH_TLS_TPOFF32 151 -+#define R_SH_GOT32 160 -+#define R_SH_PLT32 161 -+#define R_SH_COPY 162 -+#define R_SH_GLOB_DAT 163 -+#define R_SH_JMP_SLOT 164 -+#define R_SH_RELATIVE 165 -+#define R_SH_GOTOFF 166 -+#define R_SH_GOTPC 167 -+/* Keep this the last entry. */ -+#define R_SH_NUM 256 -+ -+/* S/390 specific definitions. */ -+ -+/* Valid values for the e_flags field. */ -+ -+#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ -+ -+/* Additional s390 relocs */ -+ -+#define R_390_NONE 0 /* No reloc. */ -+#define R_390_8 1 /* Direct 8 bit. */ -+#define R_390_12 2 /* Direct 12 bit. */ -+#define R_390_16 3 /* Direct 16 bit. */ -+#define R_390_32 4 /* Direct 32 bit. */ -+#define R_390_PC32 5 /* PC relative 32 bit. */ -+#define R_390_GOT12 6 /* 12 bit GOT offset. */ -+#define R_390_GOT32 7 /* 32 bit GOT offset. */ -+#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ -+#define R_390_COPY 9 /* Copy symbol at runtime. */ -+#define R_390_GLOB_DAT 10 /* Create GOT entry. */ -+#define R_390_JMP_SLOT 11 /* Create PLT entry. */ -+#define R_390_RELATIVE 12 /* Adjust by program base. */ -+#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ -+#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ -+#define R_390_GOT16 15 /* 16 bit GOT offset. */ -+#define R_390_PC16 16 /* PC relative 16 bit. */ -+#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ -+#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ -+#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ -+#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ -+#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ -+#define R_390_64 22 /* Direct 64 bit. */ -+#define R_390_PC64 23 /* PC relative 64 bit. */ -+#define R_390_GOT64 24 /* 64 bit GOT offset. */ -+#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ -+#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ -+#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ -+#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ -+#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ -+#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ -+#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ -+#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ -+#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ -+#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ -+#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ -+#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ -+#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ -+#define R_390_TLS_GDCALL 38 /* Tag for function call in general -+ dynamic TLS code. */ -+#define R_390_TLS_LDCALL 39 /* Tag for function call in local -+ dynamic TLS code. */ -+#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic -+ thread local data. */ -+#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic -+ thread local data. */ -+#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic -+ thread local data in LE code. */ -+#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic -+ thread local data in LE code. */ -+#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for -+ negated static TLS block offset. */ -+#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to -+ static TLS block. */ -+#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to -+ static TLS block. */ -+#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS -+ block. */ -+#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS -+ block. */ -+#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ -+#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ -+#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS -+ block. */ -+#define R_390_20 57 /* Direct 20 bit. */ -+#define R_390_GOT20 58 /* 20 bit GOT offset. */ -+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ -+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS -+ block offset. */ -+#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ -+/* Keep this the last entry. */ -+#define R_390_NUM 62 -+ -+ -+/* CRIS relocations. */ -+#define R_CRIS_NONE 0 -+#define R_CRIS_8 1 -+#define R_CRIS_16 2 -+#define R_CRIS_32 3 -+#define R_CRIS_8_PCREL 4 -+#define R_CRIS_16_PCREL 5 -+#define R_CRIS_32_PCREL 6 -+#define R_CRIS_GNU_VTINHERIT 7 -+#define R_CRIS_GNU_VTENTRY 8 -+#define R_CRIS_COPY 9 -+#define R_CRIS_GLOB_DAT 10 -+#define R_CRIS_JUMP_SLOT 11 -+#define R_CRIS_RELATIVE 12 -+#define R_CRIS_16_GOT 13 -+#define R_CRIS_32_GOT 14 -+#define R_CRIS_16_GOTPLT 15 -+#define R_CRIS_32_GOTPLT 16 -+#define R_CRIS_32_GOTREL 17 -+#define R_CRIS_32_PLT_GOTREL 18 -+#define R_CRIS_32_PLT_PCREL 19 -+ -+#define R_CRIS_NUM 20 -+ -+ -+/* AMD x86-64 relocations. */ -+#define R_X86_64_NONE 0 /* No reloc */ -+#define R_X86_64_64 1 /* Direct 64 bit */ -+#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -+#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -+#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -+#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -+#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -+#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative -+ offset to GOT */ -+#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -+#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -+#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -+#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ -+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -+#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ -+#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ -+#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset -+ to two GOT entries for GD symbol */ -+#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset -+ to two GOT entries for LD symbol */ -+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -+#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset -+ to GOT entry for IE symbol */ -+#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ -+#define R_X86_64_PC64 24 /* PC relative 64 bit */ -+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ -+#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative -+ offset to GOT */ -+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ -+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset -+ to GOT entry */ -+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ -+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ -+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset -+ to PLT entry */ -+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ -+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ -+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ -+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS -+ descriptor. */ -+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ -+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ -+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ -+ -+#define R_X86_64_NUM 39 -+ -+ -+/* AM33 relocations. */ -+#define R_MN10300_NONE 0 /* No reloc. */ -+#define R_MN10300_32 1 /* Direct 32 bit. */ -+#define R_MN10300_16 2 /* Direct 16 bit. */ -+#define R_MN10300_8 3 /* Direct 8 bit. */ -+#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ -+#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ -+#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ -+#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ -+#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ -+#define R_MN10300_24 9 /* Direct 24 bit. */ -+#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ -+#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ -+#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ -+#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ -+#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ -+#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ -+#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ -+#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ -+#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ -+#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ -+#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ -+#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ -+#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ -+#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ -+ -+#define R_MN10300_NUM 24 -+ -+ -+/* M32R relocs. */ -+#define R_M32R_NONE 0 /* No reloc. */ -+#define R_M32R_16 1 /* Direct 16 bit. */ -+#define R_M32R_32 2 /* Direct 32 bit. */ -+#define R_M32R_24 3 /* Direct 24 bit. */ -+#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ -+#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ -+#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ -+#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ -+#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ -+#define R_M32R_LO16 9 /* Low 16 bit. */ -+#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ -+#define R_M32R_GNU_VTINHERIT 11 -+#define R_M32R_GNU_VTENTRY 12 -+/* M32R relocs use SHT_RELA. */ -+#define R_M32R_16_RELA 33 /* Direct 16 bit. */ -+#define R_M32R_32_RELA 34 /* Direct 32 bit. */ -+#define R_M32R_24_RELA 35 /* Direct 24 bit. */ -+#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ -+#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ -+#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ -+#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ -+#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ -+#define R_M32R_LO16_RELA 41 /* Low 16 bit */ -+#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ -+#define R_M32R_RELA_GNU_VTINHERIT 43 -+#define R_M32R_RELA_GNU_VTENTRY 44 -+#define R_M32R_REL32 45 /* PC relative 32 bit. */ -+ -+#define R_M32R_GOT24 48 /* 24 bit GOT entry */ -+#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ -+#define R_M32R_COPY 50 /* Copy symbol at runtime */ -+#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ -+#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ -+#define R_M32R_RELATIVE 53 /* Adjust by program base */ -+#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ -+#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ -+#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned -+ low */ -+#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed -+ low */ -+#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ -+#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to -+ GOT with unsigned low */ -+#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to -+ GOT with signed low */ -+#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to -+ GOT */ -+#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT -+ with unsigned low */ -+#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT -+ with signed low */ -+#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ -+#define R_M32R_NUM 256 /* Keep this the last entry. */ -+ -+ -+/* TILEPro relocations. */ -+#define R_TILEPRO_NONE 0 /* No reloc */ -+#define R_TILEPRO_32 1 /* Direct 32 bit */ -+#define R_TILEPRO_16 2 /* Direct 16 bit */ -+#define R_TILEPRO_8 3 /* Direct 8 bit */ -+#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ -+#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ -+#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ -+#define R_TILEPRO_LO16 7 /* Low 16 bit */ -+#define R_TILEPRO_HI16 8 /* High 16 bit */ -+#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ -+#define R_TILEPRO_COPY 10 /* Copy relocation */ -+#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ -+#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ -+#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ -+#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ -+#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ -+#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ -+#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ -+#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ -+#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ -+#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ -+#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ -+#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ -+#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ -+#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ -+#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ -+#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ -+#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ -+#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ -+#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ -+#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ -+#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ -+#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ -+#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ -+#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ -+#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ -+#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ -+#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ -+#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ -+#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ -+#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ -+#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ -+#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ -+#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ -+#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ -+#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ -+#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ -+#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ -+#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ -+#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ -+/* Relocs 56-59 are currently not defined. */ -+#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ -+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ -+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ -+#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ -+#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ -+#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ -+#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ -+#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ -+#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ -+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ -+ -+#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -+#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ -+ -+#define R_TILEPRO_NUM 130 -+ -+ -+/* TILE-Gx relocations. */ -+#define R_TILEGX_NONE 0 /* No reloc */ -+#define R_TILEGX_64 1 /* Direct 64 bit */ -+#define R_TILEGX_32 2 /* Direct 32 bit */ -+#define R_TILEGX_16 3 /* Direct 16 bit */ -+#define R_TILEGX_8 4 /* Direct 8 bit */ -+#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ -+#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ -+#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ -+#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ -+#define R_TILEGX_HW0 9 /* hword 0 16-bit */ -+#define R_TILEGX_HW1 10 /* hword 1 16-bit */ -+#define R_TILEGX_HW2 11 /* hword 2 16-bit */ -+#define R_TILEGX_HW3 12 /* hword 3 16-bit */ -+#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ -+#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ -+#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ -+#define R_TILEGX_COPY 16 /* Copy relocation */ -+#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ -+#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ -+#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ -+#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ -+#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ -+#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ -+#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ -+#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ -+#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ -+#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ -+#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ -+#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ -+#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ -+#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ -+#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ -+#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ -+#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ -+#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ -+#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ -+#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ -+#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ -+#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ -+#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ -+#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ -+#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ -+#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ -+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ -+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ -+#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ -+/* Relocs 66-71 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ -+/* Relocs 76-77 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ -+/* Relocs 90-91 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ -+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ -+/* Relocs 94-99 are currently not defined. */ -+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ -+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ -+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ -+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ -+/* Relocs 104-105 are currently not defined. */ -+#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ -+#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ -+#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ -+#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ -+#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ -+#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ -+#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ -+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ -+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ -+#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ -+#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ -+#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ -+ -+#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -+#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ -+ -+#define R_TILEGX_NUM 130 -+ -+#endif /* elf.h */ ---- a/scripts/mod/mk_elfconfig.c -+++ b/scripts/mod/mk_elfconfig.c -@@ -2,7 +2,11 @@ - #include - #include - #include -+#ifndef __APPLE__ - #include -+#else -+#include "elf.h" -+#endif - - int - main(int argc, char **argv) ---- a/scripts/mod/modpost.h -+++ b/scripts/mod/modpost.h -@@ -9,7 +9,11 @@ - #include - #include - #include -+#if !(defined(__APPLE__) || defined(__CYGWIN__)) - #include -+#else -+#include "elf.h" -+#endif - - #include "list.h" - #include "elfconfig.h" diff --git a/target/linux/generic/hack-6.1/211-darwin-uuid-typedef-clash.patch b/target/linux/generic/hack-6.1/211-darwin-uuid-typedef-clash.patch deleted file mode 100644 index 50a6227148f4ea..00000000000000 --- a/target/linux/generic/hack-6.1/211-darwin-uuid-typedef-clash.patch +++ /dev/null @@ -1,22 +0,0 @@ -From e44fc2af1ddc452b6659d08c16973d65c73b7d0a Mon Sep 17 00:00:00 2001 -From: Kevin Darbyshire-Bryant -Date: Wed, 5 Feb 2020 18:36:43 +0000 -Subject: [PATCH] file2alias: build on macos - -Signed-off-by: Kevin Darbyshire-Bryant ---- - scripts/mod/file2alias.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/scripts/mod/file2alias.c -+++ b/scripts/mod/file2alias.c -@@ -38,6 +38,9 @@ typedef struct { - __u8 b[16]; - } guid_t; - -+#ifdef __APPLE__ -+#define uuid_t compat_uuid_t -+#endif - /* backwards compatibility, don't use in new code */ - typedef struct { - __u8 b[16]; diff --git a/target/linux/generic/hack-6.1/212-tools_portability.patch b/target/linux/generic/hack-6.1/212-tools_portability.patch deleted file mode 100644 index 3ee4393006f977..00000000000000 --- a/target/linux/generic/hack-6.1/212-tools_portability.patch +++ /dev/null @@ -1,360 +0,0 @@ -From 48232d3d931c95953ce2ddfe7da7bb164aef6a73 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:03:16 +0200 -Subject: fix portability of some includes files in tools/ used on the host - -Signed-off-by: Felix Fietkau ---- - tools/include/tools/be_byteshift.h | 4 ++++ - tools/include/tools/le_byteshift.h | 4 ++++ - tools/include/tools/linux_types.h | 22 ++++++++++++++++++++++ - 3 files changed, 30 insertions(+) - create mode 100644 tools/include/tools/linux_types.h - ---- a/tools/include/tools/be_byteshift.h -+++ b/tools/include/tools/be_byteshift.h -@@ -2,6 +2,10 @@ - #ifndef _TOOLS_BE_BYTESHIFT_H - #define _TOOLS_BE_BYTESHIFT_H - -+#ifndef __linux__ -+#include "linux_types.h" -+#endif -+ - #include - - static inline uint16_t __get_unaligned_be16(const uint8_t *p) ---- a/tools/include/tools/le_byteshift.h -+++ b/tools/include/tools/le_byteshift.h -@@ -2,6 +2,10 @@ - #ifndef _TOOLS_LE_BYTESHIFT_H - #define _TOOLS_LE_BYTESHIFT_H - -+#ifndef __linux__ -+#include "linux_types.h" -+#endif -+ - #include - - static inline uint16_t __get_unaligned_le16(const uint8_t *p) ---- /dev/null -+++ b/tools/include/tools/linux_types.h -@@ -0,0 +1,18 @@ -+#ifndef __LINUX_TYPES_H -+#define __LINUX_TYPES_H -+ -+#include -+ -+typedef int8_t __s8; -+typedef uint8_t __u8; -+ -+typedef int16_t __s16; -+typedef uint16_t __u16; -+ -+typedef int32_t __s32; -+typedef uint32_t __u32; -+ -+typedef int64_t __s64; -+typedef uint64_t __u64; -+ -+#endif ---- a/tools/include/linux/types.h -+++ b/tools/include/linux/types.h -@@ -10,8 +10,12 @@ - #define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */ - #endif - -+#ifndef __linux__ -+#include -+#else - #include - #include -+#endif - - struct page; - struct kmem_cache; -@@ -51,7 +55,9 @@ typedef __s8 s8; - #define __force - #define __user - #define __must_check -+#ifndef __cold - #define __cold -+#endif - - typedef __u16 __bitwise __le16; - typedef __u16 __bitwise __be16; ---- a/tools/perf/pmu-events/jevents.py -+++ b/tools/perf/pmu-events/jevents.py -@@ -684,6 +684,7 @@ def main() -> None: - #include "util/header.h" - #include "util/pmu.h" - #include -+#include - #include - - struct compact_pmu_event { ---- a/tools/arch/x86/include/asm/insn.h -+++ b/tools/arch/x86/include/asm/insn.h -@@ -7,8 +7,8 @@ - * Copyright (C) IBM Corporation, 2009 - */ - --#include - /* insn_attr_t is defined in inat.h */ -+#include - #include "inat.h" /* __ignore_sync_check__ */ - - #if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) ---- a/tools/arch/x86/include/asm/orc_types.h -+++ b/tools/arch/x86/include/asm/orc_types.h -@@ -40,7 +40,6 @@ - #define ORC_REG_MAX 15 - - #ifndef __ASSEMBLY__ --#include - - /* - * This struct is more or less a vastly simplified version of the DWARF Call -@@ -53,12 +52,12 @@ - struct orc_entry { - s16 sp_offset; - s16 bp_offset; --#if defined(__LITTLE_ENDIAN_BITFIELD) -+#if __BYTE_ORDER == __LITTLE_ENDIAN - unsigned sp_reg:4; - unsigned bp_reg:4; - unsigned type:2; - unsigned end:1; --#elif defined(__BIG_ENDIAN_BITFIELD) -+#elif __BYTE_ORDER == __BIG_ENDIAN - unsigned bp_reg:4; - unsigned sp_reg:4; - unsigned unused:5; ---- a/tools/arch/x86/lib/insn.c -+++ b/tools/arch/x86/lib/insn.c -@@ -15,7 +15,11 @@ - #include "../include/asm/insn.h" /* __ignore_sync_check__ */ - #include "../include/asm-generic/unaligned.h" /* __ignore_sync_check__ */ - -+#ifdef __KERNEL__ - #include -+#else -+#include -+#endif - #include - - #include "../include/asm/emulate_prefix.h" /* __ignore_sync_check__ */ ---- a/tools/include/asm-generic/bitops/fls.h -+++ b/tools/include/asm-generic/bitops/fls.h -@@ -2,6 +2,8 @@ - #ifndef _ASM_GENERIC_BITOPS_FLS_H_ - #define _ASM_GENERIC_BITOPS_FLS_H_ - -+#include -+ - /** - * fls - find last (most-significant) bit set - * @x: the word to search -@@ -10,7 +12,7 @@ - * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. - */ - --static __always_inline int fls(unsigned int x) -+static __always_inline int __generic_fls(unsigned int x) - { - int r = 32; - -@@ -38,5 +40,6 @@ static __always_inline int fls(unsigned - } - return r; - } -+#define fls __generic_fls - - #endif /* _ASM_GENERIC_BITOPS_FLS_H_ */ ---- a/tools/include/asm-generic/bitsperlong.h -+++ b/tools/include/asm-generic/bitsperlong.h -@@ -4,11 +4,13 @@ - - #include - -+#ifndef BITS_PER_LONG - #ifdef __SIZEOF_LONG__ - #define BITS_PER_LONG (__CHAR_BIT__ * __SIZEOF_LONG__) - #else - #define BITS_PER_LONG __WORDSIZE - #endif -+#endif - - #if BITS_PER_LONG != __BITS_PER_LONG - #error Inconsistent word size. Check asm/bitsperlong.h ---- a/tools/include/linux/rbtree.h -+++ b/tools/include/linux/rbtree.h -@@ -18,7 +18,6 @@ - #define __TOOLS_LINUX_PERF_RBTREE_H - - #include --#include - - struct rb_node { - unsigned long __rb_parent_color; ---- a/tools/objtool/Makefile -+++ b/tools/objtool/Makefile -@@ -4,7 +4,7 @@ include ../scripts/Makefile.arch - - # always use the host compiler - AR = $(HOSTAR) --CC = $(HOSTCC) -+CC = $(HOSTCC) $(HOST_EXTRACFLAGS) - LD = $(HOSTLD) - - ifeq ($(srctree),) -@@ -43,6 +43,7 @@ BUILD_ORC := n - - ifeq ($(SRCARCH),x86) - BUILD_ORC := y -+ CFLAGS += -DBUILD_ORC - endif - - export BUILD_ORC ---- a/tools/objtool/check.c -+++ b/tools/objtool/check.c -@@ -1164,11 +1164,12 @@ static int add_ignore_alternatives(struc - return 0; - } - -+#ifndef BUILD_ORC - /* - * Symbols that replace INSN_CALL_DYNAMIC, every (tail) call to such a symbol - * will be added to the .retpoline_sites section. - */ --__weak bool arch_is_retpoline(struct symbol *sym) -+bool arch_is_retpoline(struct symbol *sym) - { - return false; - } -@@ -1177,7 +1178,7 @@ __weak bool arch_is_retpoline(struct sym - * Symbols that replace INSN_RETURN, every (tail) call to such a symbol - * will be added to the .return_sites section. - */ --__weak bool arch_is_rethunk(struct symbol *sym) -+bool arch_is_rethunk(struct symbol *sym) - { - return false; - } -@@ -1186,10 +1187,11 @@ __weak bool arch_is_rethunk(struct symbo - * Symbols that are embedded inside other instructions, because sometimes crazy - * code exists. These are mostly ignored for validation purposes. - */ --__weak bool arch_is_embedded_insn(struct symbol *sym) -+bool arch_is_embedded_insn(struct symbol *sym) - { - return false; - } -+#endif - - #define NEGATIVE_RELOC ((void *)-1L) - ---- a/tools/objtool/include/objtool/objtool.h -+++ b/tools/objtool/include/objtool/objtool.h -@@ -12,7 +12,9 @@ - - #include - -+#ifndef __weak - #define __weak __attribute__((weak)) -+#endif - - struct pv_state { - bool clean; ---- a/tools/objtool/orc_dump.c -+++ b/tools/objtool/orc_dump.c -@@ -5,10 +5,10 @@ - - #include - #include --#include - #include - #include - #include -+#include - - static const char *reg_name(unsigned int reg) - { ---- a/tools/objtool/orc_gen.c -+++ b/tools/objtool/orc_gen.c -@@ -7,11 +7,11 @@ - #include - - #include --#include - - #include - #include - #include -+#include - - static int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, - struct instruction *insn) ---- a/tools/objtool/special.c -+++ b/tools/objtool/special.c -@@ -54,9 +54,11 @@ struct special_entry entries[] = { - {}, - }; - --void __weak arch_handle_alternative(unsigned short feature, struct special_alt *alt) -+#ifndef BUILD_ORC -+void arch_handle_alternative(unsigned short feature, struct special_alt *alt) - { - } -+#endif - - static void reloc_to_sec_off(struct reloc *reloc, struct section **sec, - unsigned long *off) ---- a/tools/objtool/weak.c -+++ b/tools/objtool/weak.c -@@ -15,12 +15,14 @@ - return ENOSYS; \ - }) - --int __weak orc_dump(const char *_objname) -+#ifndef BUILD_ORC -+int orc_dump(const char *_objname) - { - UNSUPPORTED("ORC"); - } - --int __weak orc_create(struct objtool_file *file) -+int orc_create(struct objtool_file *file) - { - UNSUPPORTED("ORC"); - } -+#endif ---- a/tools/scripts/Makefile.include -+++ b/tools/scripts/Makefile.include -@@ -92,7 +92,7 @@ LLVM_OBJCOPY ?= llvm-objcopy - LLVM_STRIP ?= llvm-strip - - ifeq ($(CC_NO_CLANG), 1) --EXTRA_WARNINGS += -Wstrict-aliasing=3 -+# EXTRA_WARNINGS += -Wstrict-aliasing=3 - - else ifneq ($(CROSS_COMPILE),) - # Allow userspace to override CLANG_CROSS_FLAGS to specify their own ---- a/tools/lib/string.c -+++ b/tools/lib/string.c -@@ -100,6 +100,7 @@ int strtobool(const char *s, bool *res) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wignored-attributes" - #endif -+#ifndef __APPLE__ - size_t __weak strlcpy(char *dest, const char *src, size_t size) - { - size_t ret = strlen(src); -@@ -111,6 +112,7 @@ size_t __weak strlcpy(char *dest, const - } - return ret; - } -+#endif - #ifdef __clang__ - #pragma clang diagnostic pop - #endif diff --git a/target/linux/generic/hack-6.1/214-spidev_h_portability.patch b/target/linux/generic/hack-6.1/214-spidev_h_portability.patch deleted file mode 100644 index db754a29033c06..00000000000000 --- a/target/linux/generic/hack-6.1/214-spidev_h_portability.patch +++ /dev/null @@ -1,24 +0,0 @@ -From be9be95ff10e16a5b4ad36f903978d0cc5747024 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:04:08 +0200 -Subject: kernel: fix linux/spi/spidev.h portability issues with musl - -Felix will try to get this define included into musl - -lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff -Signed-off-by: Felix Fietkau ---- - include/uapi/linux/spi/spidev.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/include/uapi/linux/spi/spidev.h -+++ b/include/uapi/linux/spi/spidev.h -@@ -93,7 +93,7 @@ struct spi_ioc_transfer { - - /* not all platforms use or _IOC_TYPECHECK() ... */ - #define SPI_MSGSIZE(N) \ -- ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ -+ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \ - ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0) - #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) - diff --git a/target/linux/generic/hack-6.1/220-arm-gc_sections.patch b/target/linux/generic/hack-6.1/220-arm-gc_sections.patch deleted file mode 100644 index a6a6c7cf2cc9ba..00000000000000 --- a/target/linux/generic/hack-6.1/220-arm-gc_sections.patch +++ /dev/null @@ -1,123 +0,0 @@ -From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 15 Jul 2017 23:42:36 +0200 -Subject: use -ffunction-sections, -fdata-sections and --gc-sections - -In combination with kernel symbol export stripping this significantly reduces -the kernel image size. Used on both ARM and MIPS architectures. - -Signed-off-by: Felix Fietkau -Signed-off-by: Jonas Gorski -Signed-off-by: Gabor Juhos ---- ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -124,6 +124,7 @@ config ARM - select HAVE_VIRT_CPU_ACCOUNTING_GEN - select IRQ_FORCED_THREADING - select LOCK_MM_AND_FIND_VMA -+ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION - select MODULES_USE_ELF_REL - select NEED_DMA_MAP_STATE - select OF_EARLY_FLATTREE if OF ---- a/arch/arm/boot/compressed/Makefile -+++ b/arch/arm/boot/compressed/Makefile -@@ -91,6 +91,7 @@ endif - ifeq ($(CONFIG_USE_OF),y) - OBJS += $(libfdt_objs) fdt_check_mem_start.o - endif -+KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL)) - - OBJS += lib1funcs.o ashldi3.o bswapsdi2.o - ---- a/arch/arm/kernel/vmlinux.lds.S -+++ b/arch/arm/kernel/vmlinux.lds.S -@@ -75,7 +75,7 @@ SECTIONS - . = ALIGN(4); - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { - __start___ex_table = .; -- ARM_MMU_KEEP(*(__ex_table)) -+ KEEP(*(__ex_table)) - __stop___ex_table = .; - } - -@@ -100,24 +100,24 @@ SECTIONS - } - .init.arch.info : { - __arch_info_begin = .; -- *(.arch.info.init) -+ KEEP(*(.arch.info.init)) - __arch_info_end = .; - } - .init.tagtable : { - __tagtable_begin = .; -- *(.taglist.init) -+ KEEP(*(.taglist.init)) - __tagtable_end = .; - } - #ifdef CONFIG_SMP_ON_UP - .init.smpalt : { - __smpalt_begin = .; -- *(.alt.smp.init) -+ KEEP(*(.alt.smp.init)) - __smpalt_end = .; - } - #endif - .init.pv_table : { - __pv_table_begin = .; -- *(.pv_table) -+ KEEP(*(.pv_table)) - __pv_table_end = .; - } - ---- a/arch/arm/include/asm/vmlinux.lds.h -+++ b/arch/arm/include/asm/vmlinux.lds.h -@@ -42,13 +42,13 @@ - #define PROC_INFO \ - . = ALIGN(4); \ - __proc_info_begin = .; \ -- *(.proc.info.init) \ -+ KEEP(*(.proc.info.init)) \ - __proc_info_end = .; - - #define IDMAP_TEXT \ - ALIGN_FUNCTION(); \ - __idmap_text_start = .; \ -- *(.idmap.text) \ -+ KEEP(*(.idmap.text)) \ - __idmap_text_end = .; \ - - #define ARM_DISCARD \ -@@ -109,12 +109,12 @@ - . = ALIGN(8); \ - .ARM.unwind_idx : { \ - __start_unwind_idx = .; \ -- *(.ARM.exidx*) \ -+ KEEP(*(.ARM.exidx*)) \ - __stop_unwind_idx = .; \ - } \ - .ARM.unwind_tab : { \ - __start_unwind_tab = .; \ -- *(.ARM.extab*) \ -+ KEEP(*(.ARM.extab*)) \ - __stop_unwind_tab = .; \ - } - -@@ -126,7 +126,7 @@ - __vectors_lma = .; \ - OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \ - .vectors { \ -- *(.vectors) \ -+ KEEP(*(.vectors)) \ - } \ - .vectors.bhb.loop8 { \ - *(.vectors.bhb.loop8) \ -@@ -144,7 +144,7 @@ - \ - __stubs_lma = .; \ - .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \ -- *(.stubs) \ -+ KEEP(*(.stubs)) \ - } \ - ARM_LMA(__stubs, .stubs); \ - . = __stubs_lma + SIZEOF(.stubs); \ diff --git a/target/linux/generic/hack-6.1/221-module_exports.patch b/target/linux/generic/hack-6.1/221-module_exports.patch deleted file mode 100644 index 573eeb15d7d2bb..00000000000000 --- a/target/linux/generic/hack-6.1/221-module_exports.patch +++ /dev/null @@ -1,126 +0,0 @@ -From b14784e7883390c20ed3ff904892255404a5914b Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:05:53 +0200 -Subject: add an optional config option for stripping all unnecessary symbol exports from the kernel image - -lede-commit: bb5a40c64b7c4f4848509fa0a6625055fc9e66cc -Signed-off-by: Felix Fietkau ---- - include/asm-generic/vmlinux.lds.h | 18 +++++++++++++++--- - include/linux/export.h | 9 ++++++++- - scripts/Makefile.build | 2 +- - 3 files changed, 24 insertions(+), 5 deletions(-) - ---- a/include/asm-generic/vmlinux.lds.h -+++ b/include/asm-generic/vmlinux.lds.h -@@ -81,6 +81,16 @@ - #define RO_EXCEPTION_TABLE - #endif - -+#ifndef SYMTAB_KEEP -+#define SYMTAB_KEEP KEEP(*(SORT(___ksymtab+*))) -+#define SYMTAB_KEEP_GPL KEEP(*(SORT(___ksymtab_gpl+*))) -+#endif -+ -+#ifndef SYMTAB_DISCARD -+#define SYMTAB_DISCARD -+#define SYMTAB_DISCARD_GPL -+#endif -+ - /* Align . to a 8 byte boundary equals to maximum function alignment. */ - #define ALIGN_FUNCTION() . = ALIGN(8) - -@@ -511,14 +521,14 @@ - /* Kernel symbol table: Normal symbols */ \ - __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ - __start___ksymtab = .; \ -- KEEP(*(SORT(___ksymtab+*))) \ -+ SYMTAB_KEEP \ - __stop___ksymtab = .; \ - } \ - \ - /* Kernel symbol table: GPL-only symbols */ \ - __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ - __start___ksymtab_gpl = .; \ -- KEEP(*(SORT(___ksymtab_gpl+*))) \ -+ SYMTAB_KEEP_GPL \ - __stop___ksymtab_gpl = .; \ - } \ - \ -@@ -538,7 +548,7 @@ - \ - /* Kernel symbol table: strings */ \ - __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ -- *(__ksymtab_strings) \ -+ *(__ksymtab_strings+*) \ - } \ - \ - /* __*init sections */ \ -@@ -1042,6 +1052,8 @@ - #define COMMON_DISCARDS \ - SANITIZER_DISCARDS \ - PATCHABLE_DISCARDS \ -+ SYMTAB_DISCARD \ -+ SYMTAB_DISCARD_GPL \ - *(.discard) \ - *(.discard.*) \ - *(.modinfo) \ ---- a/include/linux/export.h -+++ b/include/linux/export.h -@@ -72,6 +72,12 @@ struct kernel_symbol { - - #else - -+#ifdef MODULE -+#define __EXPORT_SUFFIX(sym) -+#else -+#define __EXPORT_SUFFIX(sym) "+" #sym -+#endif -+ - /* - * For every exported symbol, do the following: - * -@@ -87,7 +93,7 @@ struct kernel_symbol { - extern typeof(sym) sym; \ - extern const char __kstrtab_##sym[]; \ - extern const char __kstrtabns_##sym[]; \ -- asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \ -+ asm(" .section \"__ksymtab_strings" __EXPORT_SUFFIX(sym) "\",\"aMS\",%progbits,1 \n" \ - "__kstrtab_" #sym ": \n" \ - " .asciz \"" #sym "\" \n" \ - "__kstrtabns_" #sym ": \n" \ ---- a/include/asm-generic/export.h -+++ b/include/asm-generic/export.h -@@ -31,6 +31,12 @@ - #endif - .endm - -+#ifdef MODULE -+#define __EXPORT_SUFFIX(name) -+#else -+#define __EXPORT_SUFFIX(name) + #name -+#endif -+ - /* - * note on .section use: we specify progbits since usage of the "M" (SHF_MERGE) - * section flag requires it. Use '%progbits' instead of '@progbits' since the -@@ -44,7 +50,7 @@ - __ksymtab_\name: - __put \val, __kstrtab_\name - .previous -- .section __ksymtab_strings,"aMS",%progbits,1 -+ .section __ksymtab_strings __EXPORT_SUFFIX(name),"aMS",%progbits,1 - __kstrtab_\name: - .asciz "\name" - .previous ---- a/scripts/Makefile.build -+++ b/scripts/Makefile.build -@@ -391,7 +391,7 @@ targets += $(real-dtb-y) $(lib-y) $(alwa - # Linker scripts preprocessor (.lds.S -> .lds) - # --------------------------------------------------------------------------- - quiet_cmd_cpp_lds_S = LDS $@ -- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \ -+ cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -U$(ARCH) \ - -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< - - $(obj)/%.lds: $(src)/%.lds.S FORCE diff --git a/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch b/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch deleted file mode 100644 index ddf7f5e0c0c297..00000000000000 --- a/target/linux/generic/hack-6.1/230-openwrt_lzma_options.patch +++ /dev/null @@ -1,38 +0,0 @@ -From b3d00b452467f621317953d9e4c6f9ae8dcfd271 Mon Sep 17 00:00:00 2001 -From: Imre Kaloz -Date: Fri, 7 Jul 2017 17:06:55 +0200 -Subject: use the openwrt lzma options for now - -lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c -Signed-off-by: Imre Kaloz ---- - lib/decompress.c | 1 + - scripts/Makefile.lib | 2 +- - usr/gen_initramfs_list.sh | 10 +++++----- - 3 files changed, 7 insertions(+), 6 deletions(-) - ---- a/lib/decompress.c -+++ b/lib/decompress.c -@@ -53,6 +53,7 @@ static const struct compress_format comp - { {0x1f, 0x9e}, "gzip", gunzip }, - { {0x42, 0x5a}, "bzip2", bunzip2 }, - { {0x5d, 0x00}, "lzma", unlzma }, -+ { {0x6d, 0x00}, "lzma-openwrt", unlzma }, - { {0xfd, 0x37}, "xz", unxz }, - { {0x89, 0x4c}, "lzo", unlzo }, - { {0x02, 0x21}, "lz4", unlz4 }, ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -447,10 +447,10 @@ quiet_cmd_bzip2_with_size = BZIP2 $@ - # --------------------------------------------------------------------------- - - quiet_cmd_lzma = LZMA $@ -- cmd_lzma = cat $(real-prereqs) | $(LZMA) -9 > $@ -+ cmd_lzma = cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so > $@ - - quiet_cmd_lzma_with_size = LZMA $@ -- cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@ -+ cmd_lzma_with_size = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@ - - quiet_cmd_lzo = LZO $@ - cmd_lzo = cat $(real-prereqs) | $(KLZOP) -9 > $@ diff --git a/target/linux/generic/hack-6.1/250-netfilter_depends.patch b/target/linux/generic/hack-6.1/250-netfilter_depends.patch deleted file mode 100644 index fbb5a61157fd16..00000000000000 --- a/target/linux/generic/hack-6.1/250-netfilter_depends.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Felix Fietkau -Subject: hack: net: remove bogus netfilter dependencies - -lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6 -Signed-off-by: Felix Fietkau ---- - net/netfilter/Kconfig | 2 -- - 1 file changed, 2 deletions(-) - ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -253,7 +253,6 @@ config NF_CONNTRACK_FTP - - config NF_CONNTRACK_H323 - tristate "H.323 protocol support" -- depends on IPV6 || IPV6=n - depends on NETFILTER_ADVANCED - help - H.323 is a VoIP signalling protocol from ITU-T. As one of the most -@@ -1118,7 +1117,6 @@ config NETFILTER_XT_TARGET_SECMARK - - config NETFILTER_XT_TARGET_TCPMSS - tristate '"TCPMSS" target support' -- depends on IPV6 || IPV6=n - default m if NETFILTER_ADVANCED=n - help - This option adds a `TCPMSS' target, which allows you to alter the diff --git a/target/linux/generic/hack-6.1/251-kconfig.patch b/target/linux/generic/hack-6.1/251-kconfig.patch deleted file mode 100644 index fcf4eaf6e8d398..00000000000000 --- a/target/linux/generic/hack-6.1/251-kconfig.patch +++ /dev/null @@ -1,157 +0,0 @@ -From da3c50704f14132f4adf80d48e9a4cd5d46e54c9 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 7 Jul 2017 17:09:21 +0200 -Subject: kconfig: owrt specifc dependencies - -Signed-off-by: John Crispin ---- - crypto/Kconfig | 10 +++++----- - drivers/bcma/Kconfig | 1 + - drivers/ssb/Kconfig | 3 ++- - lib/Kconfig | 8 ++++---- - net/netfilter/Kconfig | 2 +- - net/wireless/Kconfig | 17 ++++++++++------- - sound/core/Kconfig | 4 ++-- - 7 files changed, 25 insertions(+), 20 deletions(-) - ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -55,7 +55,7 @@ config CRYPTO_FIPS_VERSION - By default the KERNELRELEASE value is used. - - config CRYPTO_ALGAPI -- tristate -+ tristate "ALGAPI" - select CRYPTO_ALGAPI2 - help - This option provides the API for cryptographic algorithms. -@@ -64,7 +64,7 @@ config CRYPTO_ALGAPI2 - tristate - - config CRYPTO_AEAD -- tristate -+ tristate "AEAD" - select CRYPTO_AEAD2 - select CRYPTO_ALGAPI - -@@ -75,7 +75,7 @@ config CRYPTO_AEAD2 - select CRYPTO_RNG2 - - config CRYPTO_SKCIPHER -- tristate -+ tristate "SKCIPHER" - select CRYPTO_SKCIPHER2 - select CRYPTO_ALGAPI - -@@ -85,7 +85,7 @@ config CRYPTO_SKCIPHER2 - select CRYPTO_RNG2 - - config CRYPTO_HASH -- tristate -+ tristate "HASH" - select CRYPTO_HASH2 - select CRYPTO_ALGAPI - -@@ -94,7 +94,7 @@ config CRYPTO_HASH2 - select CRYPTO_ALGAPI2 - - config CRYPTO_RNG -- tristate -+ tristate "RNG" - select CRYPTO_RNG2 - select CRYPTO_ALGAPI - ---- a/drivers/bcma/Kconfig -+++ b/drivers/bcma/Kconfig -@@ -16,6 +16,7 @@ if BCMA - # Support for Block-I/O. SELECT this from the driver that needs it. - config BCMA_BLOCKIO - bool -+ default y - - config BCMA_HOST_PCI_POSSIBLE - bool ---- a/drivers/ssb/Kconfig -+++ b/drivers/ssb/Kconfig -@@ -29,6 +29,7 @@ config SSB_SPROM - config SSB_BLOCKIO - bool - depends on SSB -+ default y - - config SSB_PCIHOST_POSSIBLE - bool -@@ -49,7 +50,7 @@ config SSB_PCIHOST - config SSB_B43_PCI_BRIDGE - bool - depends on SSB_PCIHOST -- default n -+ default y - - config SSB_PCMCIAHOST_POSSIBLE - bool ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -457,16 +457,16 @@ config BCH_CONST_T - # Textsearch support is select'ed if needed - # - config TEXTSEARCH -- bool -+ bool "Textsearch support" - - config TEXTSEARCH_KMP -- tristate -+ tristate "Textsearch KMP" - - config TEXTSEARCH_BM -- tristate -+ tristate "Textsearch BM" - - config TEXTSEARCH_FSM -- tristate -+ tristate "Textsearch FSM" - - config BTREE - bool ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -22,7 +22,7 @@ config NETFILTER_SKIP_EGRESS - def_bool NETFILTER_EGRESS && (NET_CLS_ACT || IFB) - - config NETFILTER_NETLINK -- tristate -+ tristate "Netfilter NFNETLINK interface" - - config NETFILTER_FAMILY_BRIDGE - bool ---- a/sound/core/Kconfig -+++ b/sound/core/Kconfig -@@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM - tristate - - config SND_HWDEP -- tristate -+ tristate "Sound hardware support" - - config SND_SEQ_DEVICE - tristate -@@ -27,7 +27,7 @@ config SND_RAWMIDI - select SND_SEQ_DEVICE if SND_SEQUENCER != n - - config SND_COMPRESS_OFFLOAD -- tristate -+ tristate "Compression offloading support" - - config SND_JACK - bool ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -430,7 +430,7 @@ config NET_DEVLINK - default n - - config PAGE_POOL -- bool -+ bool "Page pool support" - - config PAGE_POOL_STATS - default n diff --git a/target/linux/generic/hack-6.1/253-ksmbd-config.patch b/target/linux/generic/hack-6.1/253-ksmbd-config.patch deleted file mode 100644 index c968daf081c762..00000000000000 --- a/target/linux/generic/hack-6.1/253-ksmbd-config.patch +++ /dev/null @@ -1,32 +0,0 @@ -From dcd966fa7ca63f38cf7147e1184d13d66e2ca340 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:33:30 +0200 -Subject: [PATCH] Kconfig: add tristate for OID and ASNI string - ---- - init/Kconfig | 2 +- - lib/Kconfig | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -2017,7 +2017,7 @@ config PADATA - bool - - config ASN1 -- tristate -+ tristate "ASN1" - help - Build a simple ASN.1 grammar compiler that produces a bytecode output - that can be interpreted by the ASN.1 stream decoder and used to ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -637,7 +637,7 @@ config LIBFDT - bool - - config OID_REGISTRY -- tristate -+ tristate "OID" - help - Enable fast lookup object identifier registry. - diff --git a/target/linux/generic/hack-6.1/259-regmap_dynamic.patch b/target/linux/generic/hack-6.1/259-regmap_dynamic.patch deleted file mode 100644 index 8d25f59ce2823a..00000000000000 --- a/target/linux/generic/hack-6.1/259-regmap_dynamic.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 811d9e2268a62b830cfe93cd8bc929afcb8b198b Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 15 Jul 2017 21:12:38 +0200 -Subject: kernel: move regmap bloat out of the kernel image if it is only being used in modules - -lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998 -Signed-off-by: Felix Fietkau ---- - drivers/base/regmap/Kconfig | 15 ++++++++++----- - drivers/base/regmap/Makefile | 12 ++++++++---- - drivers/base/regmap/regmap.c | 3 +++ - include/linux/regmap.h | 2 +- - 4 files changed, 22 insertions(+), 10 deletions(-) - ---- a/drivers/base/regmap/Kconfig -+++ b/drivers/base/regmap/Kconfig -@@ -4,10 +4,9 @@ - # subsystems should select the appropriate symbols. - - config REGMAP -- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM || REGMAP_MDIO) - select IRQ_DOMAIN if REGMAP_IRQ - select MDIO_BUS if REGMAP_MDIO -- bool -+ tristate - - config REGCACHE_COMPRESSED - select LZO_COMPRESS -@@ -15,53 +14,67 @@ config REGCACHE_COMPRESSED - bool - - config REGMAP_AC97 -+ select REGMAP - tristate - - config REGMAP_I2C -+ select REGMAP - tristate - depends on I2C - - config REGMAP_SLIMBUS -+ select REGMAP - tristate - depends on SLIMBUS - - config REGMAP_SPI -+ select REGMAP - tristate - depends on SPI - - config REGMAP_SPMI -+ select REGMAP - tristate - depends on SPMI - - config REGMAP_W1 -+ select REGMAP - tristate - depends on W1 - - config REGMAP_MDIO -+ select REGMAP - tristate - - config REGMAP_MMIO -+ select REGMAP - tristate - - config REGMAP_IRQ -+ select REGMAP - bool - - config REGMAP_SOUNDWIRE -+ select REGMAP - tristate - depends on SOUNDWIRE - - config REGMAP_SOUNDWIRE_MBQ -+ select REGMAP - tristate - depends on SOUNDWIRE - - config REGMAP_SCCB -+ select REGMAP - tristate - depends on I2C - - config REGMAP_I3C -+ select REGMAP - tristate - depends on I3C - - config REGMAP_SPI_AVMM -+ select REGMAP - tristate - depends on SPI ---- a/drivers/base/regmap/Makefile -+++ b/drivers/base/regmap/Makefile -@@ -2,10 +2,14 @@ - # For include/trace/define_trace.h to include trace.h - CFLAGS_regmap.o := -I$(src) - --obj-$(CONFIG_REGMAP) += regmap.o regcache.o --obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o --obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o --obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o -+regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o -+ifdef CONFIG_DEBUG_FS -+regmap-core-objs += regmap-debugfs.o -+endif -+ifdef CONFIG_REGCACHE_COMPRESSED -+regmap-core-objs += regcache-lzo.o -+endif -+obj-$(CONFIG_REGMAP) += regmap-core.o - obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o - obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o - obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o ---- a/drivers/base/regmap/regmap.c -+++ b/drivers/base/regmap/regmap.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -3513,3 +3514,5 @@ static int __init regmap_initcall(void) - return 0; - } - postcore_initcall(regmap_initcall); -+ -+MODULE_LICENSE("GPL"); ---- a/include/linux/regmap.h -+++ b/include/linux/regmap.h -@@ -180,7 +180,7 @@ struct reg_sequence { - __ret ?: __tmp; \ - }) - --#ifdef CONFIG_REGMAP -+#if IS_REACHABLE(CONFIG_REGMAP) - - enum regmap_endian { - /* Unspecified -> 0 -> Backwards compatible default */ diff --git a/target/linux/generic/hack-6.1/260-crypto_test_dependencies.patch b/target/linux/generic/hack-6.1/260-crypto_test_dependencies.patch deleted file mode 100644 index 7ea517496e2a12..00000000000000 --- a/target/linux/generic/hack-6.1/260-crypto_test_dependencies.patch +++ /dev/null @@ -1,52 +0,0 @@ -From fd1799b0bf5efa46dd3e6dfbbf3955564807e508 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:12:51 +0200 -Subject: kernel: prevent cryptomgr from pulling in useless extra dependencies for tests that are not run - -Reduces kernel size after LZMA by about 5k on MIPS - -lede-commit: 044c316167e076479a344c59905e5b435b84a77f -Signed-off-by: Felix Fietkau ---- - crypto/Kconfig | 13 ++++++------- - crypto/algboss.c | 4 ++++ - 2 files changed, 10 insertions(+), 7 deletions(-) - ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -142,13 +142,13 @@ config CRYPTO_MANAGER - cbc(aes). - - config CRYPTO_MANAGER2 -- def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y) -- select CRYPTO_AEAD2 -- select CRYPTO_HASH2 -- select CRYPTO_SKCIPHER2 -- select CRYPTO_AKCIPHER2 -- select CRYPTO_KPP2 -- select CRYPTO_ACOMP2 -+ def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS) -+ select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_SKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS -+ select CRYPTO_ACOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS - - config CRYPTO_USER - tristate "Userspace cryptographic algorithm configuration" ---- a/crypto/algboss.c -+++ b/crypto/algboss.c -@@ -211,8 +211,12 @@ static int cryptomgr_schedule_test(struc - type = alg->cra_flags; - - /* Do not test internal algorithms. */ -+#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS -+ type |= CRYPTO_ALG_TESTED; -+#else - if (type & CRYPTO_ALG_INTERNAL) - type |= CRYPTO_ALG_TESTED; -+#endif - - param->type = type; - diff --git a/target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch b/target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch deleted file mode 100644 index 01829b2d51ef95..00000000000000 --- a/target/linux/generic/hack-6.1/261-lib-arc4-unhide.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 241e5d3f7b0dd3c01f8c7fa83cbc9a3882286d53 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:35:18 +0200 -Subject: [PATCH] lib/crypto: add tristate string for ARC4 - -This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We -need this to be able to compile this into the kernel and make use of it -from backports. - ---- - lib/crypto/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/lib/crypto/Kconfig -+++ b/lib/crypto/Kconfig -@@ -9,7 +9,7 @@ config CRYPTO_LIB_AES - tristate - - config CRYPTO_LIB_ARC4 -- tristate -+ tristate "ARC4 cipher library" - - config CRYPTO_ARCH_HAVE_LIB_BLAKE2S - bool diff --git a/target/linux/generic/hack-6.1/280-rfkill-stubs.patch b/target/linux/generic/hack-6.1/280-rfkill-stubs.patch deleted file mode 100644 index 7a650d132eb3ae..00000000000000 --- a/target/linux/generic/hack-6.1/280-rfkill-stubs.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 236c1acdfef5958010ac9814a9872e0a46fd78ee Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Fri, 7 Jul 2017 17:13:44 +0200 -Subject: rfkill: add fake rfkill support - -allow building of modules depending on RFKILL even if RFKILL is not enabled. - -Signed-off-by: John Crispin ---- - include/linux/rfkill.h | 2 +- - net/Makefile | 2 +- - net/rfkill/Kconfig | 14 +++++++++----- - net/rfkill/Makefile | 2 +- - 4 files changed, 12 insertions(+), 8 deletions(-) - ---- a/include/linux/rfkill.h -+++ b/include/linux/rfkill.h -@@ -64,7 +64,7 @@ struct rfkill_ops { - int (*set_block)(void *data, bool blocked); - }; - --#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) -+#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE) - /** - * rfkill_alloc - Allocate rfkill structure - * @name: name of the struct -- the string is not copied internally ---- a/net/Makefile -+++ b/net/Makefile -@@ -52,7 +52,7 @@ obj-$(CONFIG_TIPC) += tipc/ - obj-$(CONFIG_NETLABEL) += netlabel/ - obj-$(CONFIG_IUCV) += iucv/ - obj-$(CONFIG_SMC) += smc/ --obj-$(CONFIG_RFKILL) += rfkill/ -+obj-$(CONFIG_RFKILL_FULL) += rfkill/ - obj-$(CONFIG_NET_9P) += 9p/ - obj-$(CONFIG_CAIF) += caif/ - obj-$(CONFIG_DCB) += dcb/ ---- a/net/rfkill/Kconfig -+++ b/net/rfkill/Kconfig -@@ -2,7 +2,11 @@ - # - # RF switch subsystem configuration - # --menuconfig RFKILL -+config RFKILL -+ bool -+ default y -+ -+menuconfig RFKILL_FULL - tristate "RF switch subsystem support" - help - Say Y here if you want to have control over RF switches -@@ -14,19 +18,19 @@ menuconfig RFKILL - # LED trigger support - config RFKILL_LEDS - bool -- depends on RFKILL -+ depends on RFKILL_FULL - depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS - default y - - config RFKILL_INPUT - bool "RF switch input support" if EXPERT -- depends on RFKILL -+ depends on RFKILL_FULL - depends on INPUT = y || RFKILL = INPUT - default y if !EXPERT - - config RFKILL_GPIO - tristate "GPIO RFKILL driver" -- depends on RFKILL -+ depends on RFKILL_FULL - depends on GPIOLIB || COMPILE_TEST - default n - help ---- a/net/rfkill/Makefile -+++ b/net/rfkill/Makefile -@@ -5,5 +5,5 @@ - - rfkill-y += core.o - rfkill-$(CONFIG_RFKILL_INPUT) += input.o --obj-$(CONFIG_RFKILL) += rfkill.o -+obj-$(CONFIG_RFKILL_FULL) += rfkill.o - obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o diff --git a/target/linux/generic/hack-6.1/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch b/target/linux/generic/hack-6.1/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch deleted file mode 100644 index f21f200136f00b..00000000000000 --- a/target/linux/generic/hack-6.1/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch +++ /dev/null @@ -1,64 +0,0 @@ -From: Ben Menchaca -Date: Fri, 7 Jun 2013 18:35:22 -0500 -Subject: MIPS: r4k_cache: use more efficient cache blast - -Optimize the compiler output for larger cache blast cases that are -common for DMA-based networking. - -Signed-off-by: Ben Menchaca -Signed-off-by: Felix Fietkau ---- ---- a/arch/mips/include/asm/r4kcache.h -+++ b/arch/mips/include/asm/r4kcache.h -@@ -286,14 +286,46 @@ static inline void prot##extra##blast_## - unsigned long end) \ - { \ - unsigned long lsize = cpu_##desc##_line_size(); \ -+ unsigned long lsize_2 = lsize * 2; \ -+ unsigned long lsize_3 = lsize * 3; \ -+ unsigned long lsize_4 = lsize * 4; \ -+ unsigned long lsize_5 = lsize * 5; \ -+ unsigned long lsize_6 = lsize * 6; \ -+ unsigned long lsize_7 = lsize * 7; \ -+ unsigned long lsize_8 = lsize * 8; \ - unsigned long addr = start & ~(lsize - 1); \ -- unsigned long aend = (end - 1) & ~(lsize - 1); \ -+ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \ -+ int lines = (aend - addr) / lsize; \ - \ -- while (1) { \ -+ while (lines >= 8) { \ -+ prot##cache_op(hitop, addr); \ -+ prot##cache_op(hitop, addr + lsize); \ -+ prot##cache_op(hitop, addr + lsize_2); \ -+ prot##cache_op(hitop, addr + lsize_3); \ -+ prot##cache_op(hitop, addr + lsize_4); \ -+ prot##cache_op(hitop, addr + lsize_5); \ -+ prot##cache_op(hitop, addr + lsize_6); \ -+ prot##cache_op(hitop, addr + lsize_7); \ -+ addr += lsize_8; \ -+ lines -= 8; \ -+ } \ -+ \ -+ if (lines & 0x4) { \ -+ prot##cache_op(hitop, addr); \ -+ prot##cache_op(hitop, addr + lsize); \ -+ prot##cache_op(hitop, addr + lsize_2); \ -+ prot##cache_op(hitop, addr + lsize_3); \ -+ addr += lsize_4; \ -+ } \ -+ \ -+ if (lines & 0x2) { \ -+ prot##cache_op(hitop, addr); \ -+ prot##cache_op(hitop, addr + lsize); \ -+ addr += lsize_2; \ -+ } \ -+ \ -+ if (lines & 0x1) { \ - prot##cache_op(hitop, addr); \ -- if (addr == aend) \ -- break; \ -- addr += lsize; \ - } \ - } - diff --git a/target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch b/target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch deleted file mode 100644 index a87b41370e9946..00000000000000 --- a/target/linux/generic/hack-6.1/402-mtd-blktrans-call-add-disks-after-mtd-device.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 0bccc3722bdd88e8ae995e77ef9f7b77ee4cbdee Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 7 Apr 2021 22:45:54 +0100 -Subject: [PATCH 2/2] mtd: blktrans: call add disks after mtd device -To: linux-mtd@lists.infradead.org -Cc: Vignesh Raghavendra , - Richard Weinberger , - Miquel Raynal , - David Woodhouse - -Calling device_add_disk while holding mtd_table_mutex leads -to deadlock in case part_bits!=0 as block partition parsers -will try to open the newly created disks, trying to acquire -mutex once again. -Move device_add_disk to additional function called after -add partitions of an MTD device have been added and locks -have been released. - -Signed-off-by: Daniel Golle ---- - drivers/mtd/mtd_blkdevs.c | 33 ++++++++++++++++++++++++++------- - drivers/mtd/mtdcore.c | 3 +++ - include/linux/mtd/blktrans.h | 1 + - 3 files changed, 30 insertions(+), 7 deletions(-) - ---- a/drivers/mtd/mtd_blkdevs.c -+++ b/drivers/mtd/mtd_blkdevs.c -@@ -386,19 +386,8 @@ int add_mtd_blktrans_dev(struct mtd_blkt - if (new->readonly) - set_disk_ro(gd, 1); - -- ret = device_add_disk(&new->mtd->dev, gd, NULL); -- if (ret) -- goto out_cleanup_disk; -- -- if (new->disk_attributes) { -- ret = sysfs_create_group(&disk_to_dev(gd)->kobj, -- new->disk_attributes); -- WARN_ON(ret); -- } - return 0; - --out_cleanup_disk: -- put_disk(new->disk); - out_free_tag_set: - blk_mq_free_tag_set(new->tag_set); - out_kfree_tag_set: -@@ -408,6 +397,35 @@ out_list_del: - return ret; - } - -+void register_mtd_blktrans_devs(void) -+{ -+ struct mtd_blktrans_ops *tr; -+ struct mtd_blktrans_dev *dev, *next; -+ int ret; -+ -+ list_for_each_entry(tr, &blktrans_majors, list) { -+ list_for_each_entry_safe(dev, next, &tr->devs, list) { -+ if (disk_live(dev->disk)) -+ continue; -+ -+ ret = device_add_disk(&dev->mtd->dev, dev->disk, NULL); -+ if (ret) -+ goto out_cleanup_disk; -+ -+ if (dev->disk_attributes) { -+ ret = sysfs_create_group(&disk_to_dev(dev->disk)->kobj, -+ dev->disk_attributes); -+ WARN_ON(ret); -+ } -+ } -+ } -+ -+ return; -+ -+out_cleanup_disk: -+ put_disk(dev->disk); -+} -+ - int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) - { - unsigned long flags; ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -32,6 +32,7 @@ - - #include - #include -+#include - - #include "mtdcore.h" - -@@ -1100,6 +1101,8 @@ int mtd_device_parse_register(struct mtd - register_reboot_notifier(&mtd->reboot_notifier); - } - -+ register_mtd_blktrans_devs(); -+ - out: - if (ret) { - nvmem_unregister(mtd->otp_user_nvmem); ---- a/include/linux/mtd/blktrans.h -+++ b/include/linux/mtd/blktrans.h -@@ -76,6 +76,7 @@ extern int deregister_mtd_blktrans(struc - extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); - extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); - extern int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev); -+extern void register_mtd_blktrans_devs(void); - - /** - * module_mtd_blktrans() - Helper macro for registering a mtd blktrans driver diff --git a/target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch b/target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch deleted file mode 100644 index 7c7e4c814e611b..00000000000000 --- a/target/linux/generic/hack-6.1/420-mtd-support-OpenWrt-s-MTD_ROOTFS_ROOT_DEV.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Mon, 7 Nov 2022 23:48:24 +0100 -Subject: [PATCH] mtd: support OpenWrt's MTD_ROOTFS_ROOT_DEV -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows setting ROOT_DEV to MTD partition named "rootfs". - -Signed-off-by: Rafał Miłecki ---- - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -773,7 +773,8 @@ int add_mtd_device(struct mtd_info *mtd) - - mutex_unlock(&mtd_table_mutex); - -- if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL)) { -+ if (of_find_property(mtd_get_of_node(mtd), "linux,rootfs", NULL) || -+ (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && !strcmp(mtd->name, "rootfs") && ROOT_DEV == 0)) { - if (IS_BUILTIN(CONFIG_MTD)) { - pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name); - ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); diff --git a/target/linux/generic/hack-6.1/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch b/target/linux/generic/hack-6.1/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch deleted file mode 100644 index 965a331a1905bb..00000000000000 --- a/target/linux/generic/hack-6.1/421-drivers-mtd-parsers-add-nvmem-support-to-cmdlinepart.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 6fa9e3678eb002246df1280322b6a024853950a5 Mon Sep 17 00:00:00 2001 -From: Ansuel Smith -Date: Mon, 11 Oct 2021 00:53:14 +0200 -Subject: [PATCH] drivers: mtd: parsers: add nvmem support to cmdlinepart - -Assuming cmdlinepart is only one level deep partition scheme and that -static partition are also defined in DTS, we can assign an of_node for -partition declared from bootargs. cmdlinepart have priority than -fiexed-partition parser so in this specific case the parser doesn't -assign an of_node. Fix this by searching a defined of_node using a -similar fixed_partition parser and if a partition is found with the same -label, check that it has the same offset and size and return the DT -of_node to correctly use NVMEM cells. - -Signed-off-by: Ansuel Smith ---- - drivers/mtd/parsers/cmdlinepart.c | 71 +++++++++++++++++++++++++++++++ - 1 file changed, 71 insertions(+) - ---- a/drivers/mtd/parsers/cmdlinepart.c -+++ b/drivers/mtd/parsers/cmdlinepart.c -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include - - /* debug macro */ - #if 0 -@@ -323,6 +324,68 @@ static int mtdpart_setup_real(char *s) - return 0; - } - -+static int search_fixed_partition(struct mtd_info *master, -+ struct mtd_partition *target_part, -+ struct mtd_partition *fixed_part) -+{ -+ struct device_node *mtd_node; -+ struct device_node *ofpart_node; -+ struct device_node *pp; -+ struct mtd_partition part; -+ const char *partname; -+ -+ mtd_node = mtd_get_of_node(master); -+ if (!mtd_node) -+ return -EINVAL; -+ -+ ofpart_node = of_get_child_by_name(mtd_node, "partitions"); -+ -+ for_each_child_of_node(ofpart_node, pp) { -+ const __be32 *reg; -+ int len; -+ int a_cells, s_cells; -+ -+ reg = of_get_property(pp, "reg", &len); -+ if (!reg) { -+ pr_debug("%s: ofpart partition %pOF (%pOF) missing reg property.\n", -+ master->name, pp, -+ mtd_node); -+ continue; -+ } -+ -+ a_cells = of_n_addr_cells(pp); -+ s_cells = of_n_size_cells(pp); -+ if (len / 4 != a_cells + s_cells) { -+ pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n", -+ master->name, pp, -+ mtd_node); -+ continue; -+ } -+ -+ part.offset = of_read_number(reg, a_cells); -+ part.size = of_read_number(reg + a_cells, s_cells); -+ part.of_node = pp; -+ -+ partname = of_get_property(pp, "label", &len); -+ if (!partname) -+ partname = of_get_property(pp, "name", &len); -+ part.name = partname; -+ -+ if (!strncmp(target_part->name, part.name, len)) { -+ if (part.offset != target_part->offset) -+ return -EINVAL; -+ -+ if (part.size != target_part->size) -+ return -EINVAL; -+ -+ memcpy(fixed_part, &part, sizeof(struct mtd_partition)); -+ return 0; -+ } -+ } -+ -+ return -EINVAL; -+} -+ - /* - * Main function to be called from the MTD mapping driver/device to - * obtain the partitioning information. At this point the command line -@@ -338,6 +401,7 @@ static int parse_cmdline_partitions(stru - int i, err; - struct cmdline_mtd_partition *part; - const char *mtd_id = master->name; -+ struct mtd_partition fixed_part; - - /* parse command line */ - if (!cmdline_parsed) { -@@ -382,6 +446,13 @@ static int parse_cmdline_partitions(stru - sizeof(*part->parts) * (part->num_parts - i)); - i--; - } -+ -+ err = search_fixed_partition(master, &part->parts[i], &fixed_part); -+ if (!err) { -+ part->parts[i].of_node = fixed_part.of_node; -+ pr_info("Found partition defined in DT for %s. Assigning OF node to support nvmem.", -+ part->parts[i].name); -+ } - } - - *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts, diff --git a/target/linux/generic/hack-6.1/430-mtk-bmt-support.patch b/target/linux/generic/hack-6.1/430-mtk-bmt-support.patch deleted file mode 100644 index 1e69ee644600ff..00000000000000 --- a/target/linux/generic/hack-6.1/430-mtk-bmt-support.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ac84397efb3b3868c71c10ad7521161773228a17 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:41:44 +0200 -Subject: [PATCH] mtd/nand: add MediaTek NAND bad block managment table - ---- - drivers/mtd/nand/Kconfig | 4 ++++ - drivers/mtd/nand/Makefile | 1 + - 2 files changed, 5 insertions(+) - ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -46,6 +46,10 @@ config MTD_NAND_ECC_SW_BCH - ECC codes. They are used with NAND devices requiring more than 1 bit - of error correction. - -+config MTD_NAND_MTK_BMT -+ bool "Support MediaTek NAND Bad-block Management Table" -+ default n -+ - config MTD_NAND_ECC_MXIC - bool "Macronix external hardware ECC engine" - depends on HAS_IOMEM ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -3,6 +3,7 @@ - nandcore-objs := core.o bbt.o - obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o - obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o -+obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o - - obj-y += onenand/ - obj-y += raw/ diff --git a/target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch b/target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch deleted file mode 100644 index 51f990039ca37d..00000000000000 --- a/target/linux/generic/hack-6.1/600-net-enable-fraglist-GRO-by-default.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Felix Fietkau -Date: Tue, 23 Apr 2024 12:35:21 +0200 -Subject: [PATCH] net: enable fraglist GRO by default - -This can significantly improve performance for packet forwarding/bridging - -Signed-off-by: Felix Fietkau ---- - ---- a/include/linux/netdev_features.h -+++ b/include/linux/netdev_features.h -@@ -242,10 +242,10 @@ static inline int find_next_netdev_featu - #define NETIF_F_UPPER_DISABLES NETIF_F_LRO - - /* changeable features with no special hardware requirements */ --#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO) -+#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO | NETIF_F_GRO_FRAGLIST) - - /* Changeable features with no special hardware requirements that defaults to off. */ --#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_FRAGLIST | NETIF_F_GRO_UDP_FWD) -+#define NETIF_F_SOFT_FEATURES_OFF (NETIF_F_GRO_UDP_FWD) - - #define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \ - NETIF_F_HW_VLAN_CTAG_RX | \ diff --git a/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch b/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch deleted file mode 100644 index 444f8edfea7ca2..00000000000000 --- a/target/linux/generic/hack-6.1/645-netfilter-connmark-introduce-set-dscpmark.patch +++ /dev/null @@ -1,214 +0,0 @@ -From eda40b8c8c82e0f2789d6bc8bf63846dce2e8f32 Mon Sep 17 00:00:00 2001 -From: Kevin Darbyshire-Bryant -Date: Sat, 23 Mar 2019 09:29:49 +0000 -Subject: [PATCH] netfilter: connmark: introduce set-dscpmark - -set-dscpmark is a method of storing the DSCP of an ip packet into -conntrack mark. In combination with a suitable tc filter action -(act_ctinfo) DSCP values are able to be stored in the mark on egress and -restored on ingress across links that otherwise alter or bleach DSCP. - -This is useful for qdiscs such as CAKE which are able to shape according -to policies based on DSCP. - -Ingress classification is traditionally a challenging task since -iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT -lookups, hence are unable to see internal IPv4 addresses as used on the -typical home masquerading gateway. - -x_tables CONNMARK set-dscpmark target solves the problem of storing the -DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc -action to restore. - -The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a -32bit 'statemask'. The dscp mask must be 6 contiguous bits and -represents the area where the DSCP will be stored in the connmark. The -state mask is a minimum 1 bit length mask that must not overlap with the -dscpmask. It represents a flag which is set when the DSCP has been -stored in the conntrack mark. This is useful to implement a 'one shot' -iptables based classification where the 'complicated' iptables rules are -only run once to classify the connection on initial (egress) packet and -subsequent packets are all marked/restored with the same DSCP. A state -mask of zero disables the setting of a status bit/s. - -example syntax with a suitably modified iptables user space application: - -iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000 - -Would store the DSCP in the top 6 bits of the 32bit mark field, and use -the LSB of the top byte as the 'DSCP has been stored' marker. - -|----0xFC----conntrack mark----000000---| -| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| -| DSCP | unused | flag |unused | -|-----------------------0x01---000000---| - ^ ^ - | | - ---| Conditional flag - | set this when dscp -|-ip diffserv-| stored in mark -| 6 bits | -|-------------| - -an identically configured tc action to restore looks like: - -tc filter show dev eth0 ingress -filter parent ffff: protocol all pref 10 u32 chain 0 -filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1 -filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw - match 00000000/00000000 at 0 - action order 1: ctinfo zone 0 pipe - index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000 - - action order 2: mirred (Egress Redirect to device ifb4eth0) stolen - index 1 ref 1 bind 1 - -|----0xFC----conntrack mark----000000---| -| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| -| DSCP | unused | flag |unused | -|-----------------------0x01---000000---| - | | - | | - ---| Conditional flag - v only restore if set -|-ip diffserv-| -| 6 bits | -|-------------| - -Signed-off-by: Kevin Darbyshire-Bryant ---- - include/uapi/linux/netfilter/xt_connmark.h | 10 ++++ - net/netfilter/xt_connmark.c | 55 ++++++++++++++++++---- - 2 files changed, 57 insertions(+), 8 deletions(-) - ---- a/include/uapi/linux/netfilter/xt_connmark.h -+++ b/include/uapi/linux/netfilter/xt_connmark.h -@@ -15,6 +15,11 @@ enum { - }; - - enum { -+ XT_CONNMARK_VALUE = (1 << 0), -+ XT_CONNMARK_DSCP = (1 << 1) -+}; -+ -+enum { - D_SHIFT_LEFT = 0, - D_SHIFT_RIGHT, - }; -@@ -29,6 +34,11 @@ struct xt_connmark_tginfo2 { - __u8 shift_dir, shift_bits, mode; - }; - -+struct xt_connmark_tginfo3 { -+ __u32 ctmark, ctmask, nfmask; -+ __u8 shift_dir, shift_bits, mode, func; -+}; -+ - struct xt_connmark_mtinfo1 { - __u32 mark, mask; - __u8 invert; ---- a/net/netfilter/xt_connmark.c -+++ b/net/netfilter/xt_connmark.c -@@ -24,13 +24,13 @@ MODULE_ALIAS("ipt_connmark"); - MODULE_ALIAS("ip6t_connmark"); - - static unsigned int --connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info) -+connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info) - { - enum ip_conntrack_info ctinfo; - u_int32_t new_targetmark; - struct nf_conn *ct; - u_int32_t newmark; -- u_int32_t oldmark; -+ u_int8_t dscp; - - ct = nf_ct_get(skb, &ctinfo); - if (ct == NULL) -@@ -38,13 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, c - - switch (info->mode) { - case XT_CONNMARK_SET: -- oldmark = READ_ONCE(ct->mark); -- newmark = (oldmark & ~info->ctmask) ^ info->ctmark; -- if (info->shift_dir == D_SHIFT_RIGHT) -- newmark >>= info->shift_bits; -- else -- newmark <<= info->shift_bits; -+ newmark = READ_ONCE(ct->mark); -+ if (info->func & XT_CONNMARK_VALUE) { -+ newmark = (newmark & ~info->ctmask) ^ info->ctmark; -+ if (info->shift_dir == D_SHIFT_RIGHT) -+ newmark >>= info->shift_bits; -+ else -+ newmark <<= info->shift_bits; -+ } else if (info->func & XT_CONNMARK_DSCP) { -+ if (skb->protocol == htons(ETH_P_IP)) -+ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2; -+ else if (skb->protocol == htons(ETH_P_IPV6)) -+ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2; -+ else /* protocol doesn't have diffserv */ -+ break; - -+ newmark = (newmark & ~info->ctmark) | -+ (info->ctmask | (dscp << info->shift_bits)); -+ } - if (READ_ONCE(ct->mark) != newmark) { - WRITE_ONCE(ct->mark, newmark); - nf_conntrack_event_cache(IPCT_MARK, ct); -@@ -83,20 +94,36 @@ static unsigned int - connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) - { - const struct xt_connmark_tginfo1 *info = par->targinfo; -- const struct xt_connmark_tginfo2 info2 = { -+ const struct xt_connmark_tginfo3 info3 = { - .ctmark = info->ctmark, - .ctmask = info->ctmask, - .nfmask = info->nfmask, - .mode = info->mode, -+ .func = XT_CONNMARK_VALUE - }; - -- return connmark_tg_shift(skb, &info2); -+ return connmark_tg_shift(skb, &info3); - } - - static unsigned int - connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par) - { - const struct xt_connmark_tginfo2 *info = par->targinfo; -+ const struct xt_connmark_tginfo3 info3 = { -+ .ctmark = info->ctmark, -+ .ctmask = info->ctmask, -+ .nfmask = info->nfmask, -+ .mode = info->mode, -+ .func = XT_CONNMARK_VALUE -+ }; -+ -+ return connmark_tg_shift(skb, &info3); -+} -+ -+static unsigned int -+connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ const struct xt_connmark_tginfo3 *info = par->targinfo; - - return connmark_tg_shift(skb, info); - } -@@ -167,6 +194,16 @@ static struct xt_target connmark_tg_reg[ - .targetsize = sizeof(struct xt_connmark_tginfo2), - .destroy = connmark_tg_destroy, - .me = THIS_MODULE, -+ }, -+ { -+ .name = "CONNMARK", -+ .revision = 3, -+ .family = NFPROTO_UNSPEC, -+ .checkentry = connmark_tg_check, -+ .target = connmark_tg_v3, -+ .targetsize = sizeof(struct xt_connmark_tginfo3), -+ .destroy = connmark_tg_destroy, -+ .me = THIS_MODULE, - } - }; - diff --git a/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch b/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch deleted file mode 100644 index 0822b1a2ddeb8f..00000000000000 --- a/target/linux/generic/hack-6.1/650-netfilter-add-xt_FLOWOFFLOAD-target.patch +++ /dev/null @@ -1,812 +0,0 @@ -From: Felix Fietkau -Date: Tue, 20 Feb 2018 15:56:02 +0100 -Subject: [PATCH] netfilter: add xt_FLOWOFFLOAD target - -Signed-off-by: Felix Fietkau ---- - create mode 100644 net/netfilter/xt_OFFLOAD.c - ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -726,7 +726,6 @@ config NF_FLOW_TABLE - tristate "Netfilter flow table module" - depends on NETFILTER_INGRESS - depends on NF_CONNTRACK -- depends on NF_TABLES - help - This option adds the flow table core infrastructure. - -@@ -1023,6 +1022,15 @@ config NETFILTER_XT_TARGET_NOTRACK - depends on NETFILTER_ADVANCED - select NETFILTER_XT_TARGET_CT - -+config NETFILTER_XT_TARGET_FLOWOFFLOAD -+ tristate '"FLOWOFFLOAD" target support' -+ depends on NF_FLOW_TABLE -+ depends on NETFILTER_INGRESS -+ help -+ This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload -+ module to speed up processing of packets by bypassing the usual -+ netfilter chains -+ - config NETFILTER_XT_TARGET_RATEEST - tristate '"RATEEST" target support' - depends on NETFILTER_ADVANCED ---- a/net/netfilter/Makefile -+++ b/net/netfilter/Makefile -@@ -154,6 +154,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF - obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o - obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o - obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o -+obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o - obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o - obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o - obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o ---- /dev/null -+++ b/net/netfilter/xt_FLOWOFFLOAD.c -@@ -0,0 +1,703 @@ -+/* -+ * Copyright (C) 2018-2021 Felix Fietkau -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct xt_flowoffload_hook { -+ struct hlist_node list; -+ struct nf_hook_ops ops; -+ struct net *net; -+ bool registered; -+ bool used; -+}; -+ -+struct xt_flowoffload_table { -+ struct nf_flowtable ft; -+ struct hlist_head hooks; -+ 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); -+ -+struct xt_flowoffload_table flowtable[2]; -+ -+static unsigned int -+xt_flowoffload_net_hook(void *priv, struct sk_buff *skb, -+ const struct nf_hook_state *state) -+{ -+ struct vlan_ethhdr *veth; -+ __be16 proto; -+ -+ 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): -+ if (!nf_flow_pppoe_proto(skb, &proto)) -+ return NF_ACCEPT; -+ break; -+ default: -+ proto = skb->protocol; -+ break; -+ } -+ -+ switch (proto) { -+ 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 -+xt_flowoffload_create_hook(struct xt_flowoffload_table *table, -+ struct net_device *dev) -+{ -+ struct xt_flowoffload_hook *hook; -+ struct nf_hook_ops *ops; -+ -+ hook = kzalloc(sizeof(*hook), GFP_ATOMIC); -+ if (!hook) -+ return -ENOMEM; -+ -+ ops = &hook->ops; -+ ops->pf = NFPROTO_NETDEV; -+ ops->hooknum = NF_NETDEV_INGRESS; -+ ops->priority = 10; -+ ops->priv = &table->ft; -+ ops->hook = xt_flowoffload_net_hook; -+ ops->dev = dev; -+ -+ hlist_add_head(&hook->list, &table->hooks); -+ mod_delayed_work(system_power_efficient_wq, &table->work, 0); -+ -+ return 0; -+} -+ -+static struct xt_flowoffload_hook * -+flow_offload_lookup_hook(struct xt_flowoffload_table *table, -+ struct net_device *dev) -+{ -+ struct xt_flowoffload_hook *hook; -+ -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->ops.dev == dev) -+ return hook; -+ } -+ -+ return NULL; -+} -+ -+static void -+xt_flowoffload_check_device(struct xt_flowoffload_table *table, -+ struct net_device *dev) -+{ -+ struct xt_flowoffload_hook *hook; -+ -+ if (!dev) -+ return; -+ -+ spin_lock_bh(&hooks_lock); -+ hook = flow_offload_lookup_hook(table, dev); -+ if (hook) -+ hook->used = true; -+ else -+ xt_flowoffload_create_hook(table, dev); -+ spin_unlock_bh(&hooks_lock); -+} -+ -+static void -+xt_flowoffload_register_hooks(struct xt_flowoffload_table *table) -+{ -+ struct xt_flowoffload_hook *hook; -+ -+restart: -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->registered) -+ continue; -+ -+ hook->registered = true; -+ hook->net = dev_net(hook->ops.dev); -+ spin_unlock_bh(&hooks_lock); -+ nf_register_net_hook(hook->net, &hook->ops); -+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD) -+ table->ft.type->setup(&table->ft, hook->ops.dev, -+ FLOW_BLOCK_BIND); -+ spin_lock_bh(&hooks_lock); -+ goto restart; -+ } -+ -+} -+ -+static bool -+xt_flowoffload_cleanup_hooks(struct xt_flowoffload_table *table) -+{ -+ struct xt_flowoffload_hook *hook; -+ bool active = false; -+ -+restart: -+ spin_lock_bh(&hooks_lock); -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->used || !hook->registered) { -+ active = true; -+ continue; -+ } -+ -+ hlist_del(&hook->list); -+ spin_unlock_bh(&hooks_lock); -+ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD) -+ table->ft.type->setup(&table->ft, hook->ops.dev, -+ FLOW_BLOCK_UNBIND); -+ nf_unregister_net_hook(hook->net, &hook->ops); -+ kfree(hook); -+ goto restart; -+ } -+ spin_unlock_bh(&hooks_lock); -+ -+ return active; -+} -+ -+static void -+xt_flowoffload_check_hook(struct nf_flowtable *flowtable, -+ struct flow_offload *flow, void *data) -+{ -+ struct xt_flowoffload_table *table; -+ struct flow_offload_tuple *tuple0 = &flow->tuplehash[0].tuple; -+ struct flow_offload_tuple *tuple1 = &flow->tuplehash[1].tuple; -+ struct xt_flowoffload_hook *hook; -+ -+ table = container_of(flowtable, struct xt_flowoffload_table, ft); -+ -+ spin_lock_bh(&hooks_lock); -+ hlist_for_each_entry(hook, &table->hooks, list) { -+ if (hook->ops.dev->ifindex != tuple0->iifidx && -+ hook->ops.dev->ifindex != tuple1->iifidx) -+ continue; -+ -+ hook->used = true; -+ } -+ spin_unlock_bh(&hooks_lock); -+} -+ -+static void -+xt_flowoffload_hook_work(struct work_struct *work) -+{ -+ struct xt_flowoffload_table *table; -+ struct xt_flowoffload_hook *hook; -+ int err; -+ -+ table = container_of(work, struct xt_flowoffload_table, work.work); -+ -+ spin_lock_bh(&hooks_lock); -+ xt_flowoffload_register_hooks(table); -+ hlist_for_each_entry(hook, &table->hooks, list) -+ hook->used = false; -+ spin_unlock_bh(&hooks_lock); -+ -+ err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook, -+ NULL); -+ if (err && err != -EAGAIN) -+ goto out; -+ -+ if (!xt_flowoffload_cleanup_hooks(table)) -+ return; -+ -+out: -+ queue_delayed_work(system_power_efficient_wq, &table->work, HZ); -+} -+ -+static bool -+xt_flowoffload_skip(struct sk_buff *skb, int family) -+{ -+ if (skb_sec_path(skb)) -+ return true; -+ -+ if (family == NFPROTO_IPV4) { -+ const struct ip_options *opt = &(IPCB(skb)->opt); -+ -+ if (unlikely(opt->optlen)) -+ return true; -+ } -+ -+ return false; -+} -+ -+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 || -+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr)) -+ return false; -+ -+ return true; -+} -+ -+static void nf_dev_path_info(const struct net_device_path_stack *stack, -+ struct nf_forward_info *info, -+ unsigned char *ha) -+{ -+ const struct net_device_path *path; -+ int i; -+ -+ memcpy(info->h_dest, ha, ETH_ALEN); -+ -+ for (i = 0; i < stack->num_paths; i++) { -+ path = &stack->path[i]; -+ switch (path->type) { -+ case DEV_PATH_ETHERNET: -+ case DEV_PATH_DSA: -+ case DEV_PATH_VLAN: -+ case DEV_PATH_PPPOE: -+ info->indev = path->dev; -+ 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; -+ } -+ -+ /* DEV_PATH_VLAN and DEV_PATH_PPPOE */ -+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) { -+ 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) -+ memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN); -+ break; -+ case DEV_PATH_BRIDGE: -+ if (is_zero_ether_addr(info->h_source)) -+ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN); -+ -+ switch (path->bridge.vlan_mode) { -+ case DEV_PATH_BR_VLAN_UNTAG_HW: -+ info->ingress_vlans |= BIT(info->num_encaps - 1); -+ break; -+ 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; -+ case DEV_PATH_BR_VLAN_UNTAG: -+ info->num_encaps--; -+ break; -+ case DEV_PATH_BR_VLAN_KEEP: -+ break; -+ } -+ break; -+ default: -+ info->indev = NULL; -+ break; -+ } -+ } -+ if (!info->outdev) -+ info->outdev = info->indev; -+ -+ info->hw_outdev = info->indev; -+ -+ if (nf_is_valid_ether_device(info->indev)) -+ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT; -+} -+ -+static int nf_dev_fill_forward_path(const struct nf_flow_route *route, -+ const struct dst_entry *dst_cache, -+ const struct nf_conn *ct, -+ enum ip_conntrack_dir dir, u8 *ha, -+ struct net_device_path_stack *stack) -+{ -+ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; -+ struct net_device *dev = dst_cache->dev; -+ struct neighbour *n; -+ u8 nud_state; -+ -+ if (!nf_is_valid_ether_device(dev)) -+ goto out; -+ -+ n = dst_neigh_lookup(dst_cache, daddr); -+ if (!n) -+ return -1; -+ -+ read_lock_bh(&n->lock); -+ nud_state = n->nud_state; -+ ether_addr_copy(ha, n->ha); -+ read_unlock_bh(&n->lock); -+ neigh_release(n); -+ -+ if (!(nud_state & NUD_VALID)) -+ return -1; -+ -+out: -+ return dev_fill_forward_path(dev, ha, stack); -+} -+ -+static void nf_dev_forward_path(struct nf_flow_route *route, -+ const struct nf_conn *ct, -+ 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; -+ -+ if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0) -+ nf_dev_path_info(&stack, &info, ha); -+ -+ 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 -+xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct, -+ const struct xt_action_param *par, -+ struct nf_flow_route *route, enum ip_conntrack_dir dir, -+ struct net_device **devs) -+{ -+ struct dst_entry *this_dst = skb_dst(skb); -+ struct dst_entry *other_dst = NULL; -+ struct flowi fl; -+ -+ memset(&fl, 0, sizeof(fl)); -+ switch (xt_family(par)) { -+ case NFPROTO_IPV4: -+ 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; -+ } -+ -+ if (!dst_hold_safe(this_dst)) -+ return -ENOENT; -+ -+ nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par)); -+ if (!other_dst) { -+ dst_release(this_dst); -+ return -ENOENT; -+ } -+ -+ nf_default_forward_path(route, this_dst, dir, devs); -+ 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; -+} -+ -+static unsigned int -+flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par) -+{ -+ struct xt_flowoffload_table *table; -+ const struct xt_flowoffload_target_info *info = par->targinfo; -+ struct tcphdr _tcph, *tcph = NULL; -+ enum ip_conntrack_info ctinfo; -+ enum ip_conntrack_dir dir; -+ struct nf_flow_route route = {}; -+ struct flow_offload *flow = NULL; -+ struct net_device *devs[2] = {}; -+ struct nf_conn *ct; -+ struct net *net; -+ -+ if (xt_flowoffload_skip(skb, xt_family(par))) -+ return XT_CONTINUE; -+ -+ ct = nf_ct_get(skb, &ctinfo); -+ if (ct == NULL) -+ return XT_CONTINUE; -+ -+ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { -+ case IPPROTO_TCP: -+ if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) -+ return XT_CONTINUE; -+ -+ tcph = skb_header_pointer(skb, par->thoff, -+ sizeof(_tcph), &_tcph); -+ if (unlikely(!tcph || tcph->fin || tcph->rst)) -+ return XT_CONTINUE; -+ break; -+ case IPPROTO_UDP: -+ break; -+ default: -+ return XT_CONTINUE; -+ } -+ -+ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) || -+ ct->status & (IPS_SEQ_ADJUST | IPS_NAT_CLASH)) -+ return XT_CONTINUE; -+ -+ if (!nf_ct_is_confirmed(ct)) -+ return XT_CONTINUE; -+ -+ dir = CTINFO2DIR(ctinfo); -+ -+ devs[dir] = xt_out(par); -+ devs[!dir] = xt_in(par); -+ -+ if (!devs[dir] || !devs[!dir]) -+ return XT_CONTINUE; -+ -+ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status)) -+ return XT_CONTINUE; -+ -+ if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0) -+ goto err_flow_route; -+ -+ flow = flow_offload_alloc(ct); -+ if (!flow) -+ goto err_flow_alloc; -+ -+ flow_offload_route_init(flow, &route); -+ -+ if (tcph) { -+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; -+ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; -+ } -+ -+ table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)]; -+ -+ net = read_pnet(&table->ft.net); -+ if (!net) -+ write_pnet(&table->ft.net, xt_net(par)); -+ -+ __set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags); -+ if (flow_offload_add(&table->ft, flow) < 0) -+ goto err_flow_add; -+ -+ xt_flowoffload_check_device(table, devs[0]); -+ xt_flowoffload_check_device(table, devs[1]); -+ -+ return XT_CONTINUE; -+ -+err_flow_add: -+ flow_offload_free(flow); -+err_flow_alloc: -+ dst_release(route.tuple[dir].dst); -+ dst_release(route.tuple[!dir].dst); -+err_flow_route: -+ clear_bit(IPS_OFFLOAD_BIT, &ct->status); -+ -+ return XT_CONTINUE; -+} -+ -+static int flowoffload_chk(const struct xt_tgchk_param *par) -+{ -+ struct xt_flowoffload_target_info *info = par->targinfo; -+ -+ if (info->flags & ~XT_FLOWOFFLOAD_MASK) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static struct xt_target offload_tg_reg __read_mostly = { -+ .family = NFPROTO_UNSPEC, -+ .name = "FLOWOFFLOAD", -+ .revision = 0, -+ .targetsize = sizeof(struct xt_flowoffload_target_info), -+ .usersize = sizeof(struct xt_flowoffload_target_info), -+ .checkentry = flowoffload_chk, -+ .target = flowoffload_tg, -+ .me = THIS_MODULE, -+}; -+ -+static int flow_offload_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ struct xt_flowoffload_hook *hook0, *hook1; -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ -+ if (event != NETDEV_UNREGISTER) -+ return NOTIFY_DONE; -+ -+ spin_lock_bh(&hooks_lock); -+ hook0 = flow_offload_lookup_hook(&flowtable[0], dev); -+ if (hook0) -+ hlist_del(&hook0->list); -+ -+ hook1 = flow_offload_lookup_hook(&flowtable[1], dev); -+ if (hook1) -+ hlist_del(&hook1->list); -+ spin_unlock_bh(&hooks_lock); -+ -+ if (hook0) { -+ nf_unregister_net_hook(hook0->net, &hook0->ops); -+ kfree(hook0); -+ } -+ -+ if (hook1) { -+ nf_unregister_net_hook(hook1->net, &hook1->ops); -+ kfree(hook1); -+ } -+ -+ nf_flow_table_cleanup(dev); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block flow_offload_netdev_notifier = { -+ .notifier_call = flow_offload_netdev_event, -+}; -+ -+static int nf_flow_rule_route_inet(struct net *net, -+ struct flow_offload *flow, -+ enum flow_offload_tuple_dir dir, -+ struct nf_flow_rule *flow_rule) -+{ -+ const struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; -+ int err; -+ -+ switch (flow_tuple->l3proto) { -+ case NFPROTO_IPV4: -+ err = nf_flow_rule_route_ipv4(net, flow, dir, flow_rule); -+ break; -+ case NFPROTO_IPV6: -+ err = nf_flow_rule_route_ipv6(net, flow, dir, flow_rule); -+ break; -+ default: -+ err = -1; -+ break; -+ } -+ -+ return err; -+} -+ -+static struct nf_flowtable_type flowtable_inet = { -+ .family = NFPROTO_INET, -+ .init = nf_flow_table_init, -+ .setup = nf_flow_table_offload_setup, -+ .action = nf_flow_rule_route_inet, -+ .free = nf_flow_table_free, -+ .hook = xt_flowoffload_net_hook, -+ .owner = THIS_MODULE, -+}; -+ -+static int init_flowtable(struct xt_flowoffload_table *tbl) -+{ -+ INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work); -+ tbl->ft.type = &flowtable_inet; -+ tbl->ft.flags = NF_FLOWTABLE_COUNTER; -+ -+ return nf_flow_table_init(&tbl->ft); -+} -+ -+static int __init xt_flowoffload_tg_init(void) -+{ -+ int ret; -+ -+ register_netdevice_notifier(&flow_offload_netdev_notifier); -+ -+ ret = init_flowtable(&flowtable[0]); -+ if (ret) -+ return ret; -+ -+ ret = init_flowtable(&flowtable[1]); -+ if (ret) -+ goto cleanup; -+ -+ flowtable[1].ft.flags |= NF_FLOWTABLE_HW_OFFLOAD; -+ -+ ret = xt_register_target(&offload_tg_reg); -+ if (ret) -+ goto cleanup2; -+ -+ return 0; -+ -+cleanup2: -+ nf_flow_table_free(&flowtable[1].ft); -+cleanup: -+ nf_flow_table_free(&flowtable[0].ft); -+ return ret; -+} -+ -+static void __exit xt_flowoffload_tg_exit(void) -+{ -+ xt_unregister_target(&offload_tg_reg); -+ unregister_netdevice_notifier(&flow_offload_netdev_notifier); -+ nf_flow_table_free(&flowtable[0].ft); -+ nf_flow_table_free(&flowtable[1].ft); -+} -+ -+MODULE_LICENSE("GPL"); -+module_init(xt_flowoffload_tg_init); -+module_exit(xt_flowoffload_tg_exit); ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -7,7 +7,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -374,8 +373,7 @@ flow_offload_lookup(struct nf_flowtable - } - EXPORT_SYMBOL_GPL(flow_offload_lookup); - --static int --nf_flow_table_iterate(struct nf_flowtable *flow_table, -+int nf_flow_table_iterate(struct nf_flowtable *flow_table, - void (*iter)(struct nf_flowtable *flowtable, - struct flow_offload *flow, void *data), - void *data) -@@ -436,6 +434,7 @@ static void nf_flow_offload_gc_step(stru - nf_flow_offload_stats(flow_table, flow); - } - } -+EXPORT_SYMBOL_GPL(nf_flow_table_iterate); - - void nf_flow_table_gc_run(struct nf_flowtable *flow_table) - { ---- /dev/null -+++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h -@@ -0,0 +1,17 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#ifndef _XT_FLOWOFFLOAD_H -+#define _XT_FLOWOFFLOAD_H -+ -+#include -+ -+enum { -+ XT_FLOWOFFLOAD_HW = 1 << 0, -+ -+ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW -+}; -+ -+struct xt_flowoffload_target_info { -+ __u32 flags; -+}; -+ -+#endif /* _XT_FLOWOFFLOAD_H */ ---- a/include/net/netfilter/nf_flow_table.h -+++ b/include/net/netfilter/nf_flow_table.h -@@ -293,6 +293,11 @@ void nf_flow_table_free(struct nf_flowta - - void flow_offload_teardown(struct flow_offload *flow); - -+int nf_flow_table_iterate(struct nf_flowtable *flow_table, -+ void (*iter)(struct nf_flowtable *flowtable, -+ struct flow_offload *flow, void *data), -+ void *data); -+ - void nf_flow_snat_port(const struct flow_offload *flow, - struct sk_buff *skb, unsigned int thoff, - u8 protocol, enum flow_offload_tuple_dir dir); diff --git a/target/linux/generic/hack-6.1/651-wireless_mesh_header.patch b/target/linux/generic/hack-6.1/651-wireless_mesh_header.patch deleted file mode 100644 index fd7d5346ad99e4..00000000000000 --- a/target/linux/generic/hack-6.1/651-wireless_mesh_header.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 6d3bc769657b0ee7c7506dad9911111c4226a7ea Mon Sep 17 00:00:00 2001 -From: Imre Kaloz -Date: Fri, 7 Jul 2017 17:21:05 +0200 -Subject: mac80211: increase wireless mesh header size - -lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1 -Signed-off-by: Imre Kaloz ---- - include/linux/netdevice.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -149,8 +149,8 @@ static inline bool dev_xmit_complete(int - - #if defined(CONFIG_HYPERV_NET) - # define LL_MAX_HEADER 128 --#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) --# if defined(CONFIG_MAC80211_MESH) -+#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1 -+# if defined(CONFIG_MAC80211_MESH) || 1 - # define LL_MAX_HEADER 128 - # else - # define LL_MAX_HEADER 96 diff --git a/target/linux/generic/hack-6.1/660-fq_codel_defaults.patch b/target/linux/generic/hack-6.1/660-fq_codel_defaults.patch deleted file mode 100644 index b923a2d206da3c..00000000000000 --- a/target/linux/generic/hack-6.1/660-fq_codel_defaults.patch +++ /dev/null @@ -1,27 +0,0 @@ -From a6ccb238939b25851474a279b20367fd24a0e816 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:21:53 +0200 -Subject: hack: net: fq_codel: tune defaults for small devices - -Assume that x86_64 devices always have a big memory and do not need this -optimization compared to devices with only 32 MB or 64 MB RAM. - -Signed-off-by: Felix Fietkau ---- - net/sched/sch_fq_codel.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/net/sched/sch_fq_codel.c -+++ b/net/sched/sch_fq_codel.c -@@ -471,7 +471,11 @@ static int fq_codel_init(struct Qdisc *s - - sch->limit = 10*1024; - q->flows_cnt = 1024; -+#ifdef CONFIG_X86_64 - q->memory_limit = 32 << 20; /* 32 MBytes */ -+#else -+ q->memory_limit = 4 << 20; /* 4 MBytes */ -+#endif - q->drop_batch_size = 64; - q->quantum = psched_mtu(qdisc_dev(sch)); - INIT_LIST_HEAD(&q->new_flows); diff --git a/target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch b/target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch deleted file mode 100644 index fe94a9da0c4ecd..00000000000000 --- a/target/linux/generic/hack-6.1/661-kernel-ct-size-the-hashtable-more-adequately.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 804fbb3f2ec9283f7b778e057a68bfff440a0be6 Mon Sep 17 00:00:00 2001 -From: Rui Salvaterra -Date: Wed, 30 Mar 2022 22:51:55 +0100 -Subject: [PATCH] kernel: ct: size the hashtable more adequately - -To set the default size of the connection tracking hash table, a divider of -16384 becomes inadequate for a router handling lots of connections. Divide by -2048 instead, making the default size scale better with the available RAM. - -Signed-off-by: Rui Salvaterra ---- - net/netfilter/nf_conntrack_core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -2705,7 +2705,7 @@ int nf_conntrack_init_start(void) - - if (!nf_conntrack_htable_size) { - nf_conntrack_htable_size -- = (((nr_pages << PAGE_SHIFT) / 16384) -+ = (((nr_pages << PAGE_SHIFT) / 2048) - / sizeof(struct hlist_head)); - if (BITS_PER_LONG >= 64 && - nr_pages > (4 * (1024 * 1024 * 1024 / PAGE_SIZE))) diff --git a/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch deleted file mode 100644 index 673082d8408e02..00000000000000 --- a/target/linux/generic/hack-6.1/700-swconfig_switch_drivers.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 36e516290611e613aa92996cb4339561452695b4 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:24:23 +0200 -Subject: net: swconfig: adds openwrt switch layer - -Signed-off-by: Felix Fietkau ---- - drivers/net/phy/Kconfig | 83 +++++++++++++++++++++++++++++++++++++++++++++++ - drivers/net/phy/Makefile | 15 +++++++++ - include/uapi/linux/Kbuild | 1 + - 3 files changed, 99 insertions(+) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -67,6 +67,80 @@ config SFP - depends on HWMON || HWMON=n - select MDIO_I2C - -+comment "Switch configuration API + drivers" -+ -+config SWCONFIG -+ tristate "Switch configuration API" -+ help -+ Switch configuration API using netlink. This allows -+ you to configure the VLAN features of certain switches. -+ -+config SWCONFIG_LEDS -+ bool "Switch LED trigger support" -+ depends on (SWCONFIG && LEDS_TRIGGERS) -+ -+config ADM6996_PHY -+ tristate "Driver for ADM6996 switches" -+ select SWCONFIG -+ help -+ Currently supports the ADM6996FC and ADM6996M switches. -+ Support for FC is very limited. -+ -+config AR8216_PHY -+ tristate "Driver for Atheros AR8216/8327 switches" -+ select SWCONFIG -+ select ETHERNET_PACKET_MANGLE -+ -+config AR8216_PHY_LEDS -+ bool "Atheros AR8216 switch LED support" -+ depends on (AR8216_PHY && LEDS_CLASS) -+ -+source "drivers/net/phy/b53/Kconfig" -+ -+config IP17XX_PHY -+ tristate "Driver for IC+ IP17xx switches" -+ select SWCONFIG -+ -+config PSB6970_PHY -+ tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch" -+ select SWCONFIG -+ -+config RTL8306_PHY -+ tristate "Driver for Realtek RTL8306S switches" -+ select SWCONFIG -+ -+config RTL8366_SMI -+ tristate "Driver for the RTL8366 SMI interface" -+ depends on GPIOLIB -+ help -+ This module implements the SMI interface protocol which is used -+ by some RTL8366 ethernet switch devices via the generic GPIO API. -+ -+if RTL8366_SMI -+ -+config RTL8366_SMI_DEBUG_FS -+ bool "RTL8366 SMI interface debugfs support" -+ depends on DEBUG_FS -+ default n -+ -+config RTL8366S_PHY -+ tristate "Driver for the Realtek RTL8366S switch" -+ select SWCONFIG -+ -+config RTL8366RB_PHY -+ tristate "Driver for the Realtek RTL8366RB switch" -+ select SWCONFIG -+ -+config RTL8367_PHY -+ tristate "Driver for the Realtek RTL8367R/M switches" -+ select SWCONFIG -+ -+config RTL8367B_PHY -+ tristate "Driver fot the Realtek RTL8367R-VB switch" -+ select SWCONFIG -+ -+endif # RTL8366_SMI -+ - comment "MII PHY device drivers" - - config AIR_EN8811H_PHY ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -24,6 +24,21 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_ - obj-$(CONFIG_PHYLINK) += phylink.o - obj-$(CONFIG_PHYLIB) += libphy.o - -+obj-$(CONFIG_SWCONFIG) += swconfig.o -+obj-$(CONFIG_ADM6996_PHY) += adm6996.o -+obj-$(CONFIG_AR8216_PHY) += ar8xxx.o -+ar8xxx-y += ar8216.o -+ar8xxx-y += ar8327.o -+obj-$(CONFIG_SWCONFIG_B53) += b53/ -+obj-$(CONFIG_IP17XX_PHY) += ip17xx.o -+obj-$(CONFIG_PSB6970_PHY) += psb6970.o -+obj-$(CONFIG_RTL8306_PHY) += rtl8306.o -+obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o -+obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o -+obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o -+obj-$(CONFIG_RTL8367_PHY) += rtl8367.o -+obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o -+ - obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o - - obj-$(CONFIG_SFP) += sfp.o ---- a/include/linux/platform_data/b53.h -+++ b/include/linux/platform_data/b53.h -@@ -29,6 +29,9 @@ struct b53_platform_data { - u32 chip_id; - u16 enabled_ports; - -+ /* allow to specify an ethX alias */ -+ const char *alias; -+ - /* only used by MMAP'd driver */ - unsigned big_endian:1; - void __iomem *regs; diff --git a/target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch b/target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch deleted file mode 100644 index 75907bf4720102..00000000000000 --- a/target/linux/generic/hack-6.1/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch +++ /dev/null @@ -1,21 +0,0 @@ -From ebd924d773223593142d417c41d4ee6fa16f1805 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:45:56 +0200 -Subject: [PATCH] net/dsa/mv88e6xxx: disable ATU violation - ---- - drivers/net/dsa/mv88e6xxx/chip.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -3510,6 +3510,9 @@ static int mv88e6xxx_setup_port(struct m - else - reg = 1 << port; - -+ /* Disable ATU member violation interrupt */ -+ reg |= MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG; -+ - err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, - reg); - if (err) diff --git a/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch b/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch deleted file mode 100644 index c6306c85ccb142..00000000000000 --- a/target/linux/generic/hack-6.1/721-net-add-packet-mangeling.patch +++ /dev/null @@ -1,167 +0,0 @@ -From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Fri, 7 Jul 2017 17:25:00 +0200 -Subject: net: add packet mangeling - -ar8216 switches have a hardware bug, which renders normal 802.1q support -unusable. Packet mangling is required to fix up the vlan for incoming -packets. - -Signed-off-by: Felix Fietkau ---- - include/linux/netdevice.h | 11 +++++++++++ - include/linux/skbuff.h | 14 ++++---------- - net/Kconfig | 6 ++++++ - net/core/dev.c | 20 +++++++++++++++----- - net/core/skbuff.c | 17 +++++++++++++++++ - net/ethernet/eth.c | 6 ++++++ - 6 files changed, 59 insertions(+), 15 deletions(-) - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -1730,6 +1730,7 @@ enum netdev_priv_flags { - /* was IFF_LIVE_RENAME_OK */ - IFF_TX_SKB_NO_LINEAR = BIT_ULL(31), - IFF_CHANGE_PROTO_DOWN = BIT_ULL(32), -+ IFF_NO_IP_ALIGN = BIT_ULL(33), - }; - - #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN -@@ -1763,6 +1764,7 @@ enum netdev_priv_flags { - #define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE - #define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER - #define IFF_TX_SKB_NO_LINEAR IFF_TX_SKB_NO_LINEAR -+#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN - - /* Specifies the type of the struct net_device::ml_priv pointer */ - enum netdev_ml_priv_type { -@@ -2131,6 +2133,11 @@ struct net_device { - const struct tlsdev_ops *tlsdev_ops; - #endif - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb); -+ struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb); -+#endif -+ - const struct header_ops *header_ops; - - unsigned char operstate; -@@ -2204,6 +2211,10 @@ struct net_device { - struct mctp_dev __rcu *mctp_ptr; - #endif - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ void *phy_ptr; /* PHY device specific data */ -+#endif -+ - /* - * Cache lines mostly used on receive path (including eth_type_trans()) - */ ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -3071,6 +3071,10 @@ static inline int pskb_trim(struct sk_bu - return (len < skb->len) ? __pskb_trim(skb, len) : 0; - } - -+extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -+ unsigned int length, gfp_t gfp); -+ -+ - /** - * pskb_trim_unique - remove end from a paged unique (not cloned) buffer - * @skb: buffer to alter -@@ -3220,16 +3224,6 @@ static inline struct sk_buff *dev_alloc_ - } - - --static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -- unsigned int length, gfp_t gfp) --{ -- struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); -- -- if (NET_IP_ALIGN && skb) -- skb_reserve(skb, NET_IP_ALIGN); -- return skb; --} -- - static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, - unsigned int length) - { ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -26,6 +26,12 @@ menuconfig NET - - if NET - -+config ETHERNET_PACKET_MANGLE -+ bool -+ help -+ This option can be selected by phy drivers that need to mangle -+ packets going in or out of an ethernet device. -+ - config WANT_COMPAT_NETLINK_MESSAGES - bool - help ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -3607,6 +3607,11 @@ static int xmit_one(struct sk_buff *skb, - if (dev_nit_active(dev)) - dev_queue_xmit_nit(skb, dev); - -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev->eth_mangle_tx && !(skb = dev->eth_mangle_tx(dev, skb))) -+ return NETDEV_TX_OK; -+#endif -+ - len = skb->len; - trace_net_dev_start_xmit(skb, dev); - rc = netdev_start_xmit(skb, dev, txq, more); ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -61,6 +61,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -709,6 +710,22 @@ skb_fail: - } - EXPORT_SYMBOL(__napi_alloc_skb); - -+struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, -+ unsigned int length, gfp_t gfp) -+{ -+ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN)) -+ return skb; -+#endif -+ -+ if (NET_IP_ALIGN && skb) -+ skb_reserve(skb, NET_IP_ALIGN); -+ return skb; -+} -+EXPORT_SYMBOL(__netdev_alloc_skb_ip_align); -+ - void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, - int size, unsigned int truesize) - { ---- a/net/ethernet/eth.c -+++ b/net/ethernet/eth.c -@@ -159,6 +159,12 @@ __be16 eth_type_trans(struct sk_buff *sk - const struct ethhdr *eth; - - skb->dev = dev; -+ -+#ifdef CONFIG_ETHERNET_PACKET_MANGLE -+ if (dev->eth_mangle_rx) -+ dev->eth_mangle_rx(dev, skb); -+#endif -+ - skb_reset_mac_header(skb); - - eth = (struct ethhdr *)skb->data; diff --git a/target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch b/target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch deleted file mode 100644 index 42b44d564d94ea..00000000000000 --- a/target/linux/generic/hack-6.1/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 5f62951fba63a9f9cfff564209426bdea5fcc371 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 27 Aug 2019 15:16:56 +0300 -Subject: [PATCH] drivers: net: phy: aquantia: enable AQR112 and AQR412 - -Adds support for AQR112 and AQR412 which is mostly based on existing code -with the addition of code configuring the protocol on system side. -This allows changing the system side protocol without having to deploy a -different firmware on the PHY. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/aquantia/aquantia_main.c | 88 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 88 insertions(+) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -27,6 +27,8 @@ - #define PHY_ID_AQR113 0x31c31c40 - #define PHY_ID_AQR113C 0x31c31c12 - #define PHY_ID_AQR813 0x31c31cb2 -+#define PHY_ID_AQR112 0x03a1b662 -+#define PHY_ID_AQR412 0x03a1b712 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -@@ -99,6 +101,29 @@ - #define AQR107_OP_IN_PROG_SLEEP 1000 - #define AQR107_OP_IN_PROG_TIMEOUT 100000 - -+/* registers in MDIO_MMD_VEND1 region */ -+#define AQUANTIA_VND1_GLOBAL_SC 0x000 -+#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb) -+ -+/* global start rate, the protocol associated with this speed is used by default -+ * on SI. -+ */ -+#define AQUANTIA_VND1_GSTART_RATE 0x31a -+#define AQUANTIA_VND1_GSTART_RATE_OFF 0 -+#define AQUANTIA_VND1_GSTART_RATE_100M 1 -+#define AQUANTIA_VND1_GSTART_RATE_1G 2 -+#define AQUANTIA_VND1_GSTART_RATE_10G 3 -+#define AQUANTIA_VND1_GSTART_RATE_2_5G 4 -+#define AQUANTIA_VND1_GSTART_RATE_5G 5 -+ -+/* SYSCFG registers for 100M, 1G, 2.5G, 5G, 10G */ -+#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b -+#define AQUANTIA_VND1_GSYSCFG_100M 0 -+#define AQUANTIA_VND1_GSYSCFG_1G 1 -+#define AQUANTIA_VND1_GSYSCFG_2_5G 2 -+#define AQUANTIA_VND1_GSYSCFG_5G 3 -+#define AQUANTIA_VND1_GSYSCFG_10G 4 -+ - struct aqr107_hw_stat { - const char *name; - int reg; -@@ -230,6 +255,51 @@ static int aqr_config_aneg(struct phy_de - return genphy_c45_check_and_restart_aneg(phydev, changed); - } - -+static struct { -+ u16 syscfg; -+ int cnt; -+ u16 start_rate; -+} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = { -+ [PHY_INTERFACE_MODE_SGMII] = {0x04b, AQUANTIA_VND1_GSYSCFG_1G, -+ AQUANTIA_VND1_GSTART_RATE_1G}, -+ [PHY_INTERFACE_MODE_2500BASEX] = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G, -+ AQUANTIA_VND1_GSTART_RATE_2_5G}, -+ [PHY_INTERFACE_MODE_XGMII] = {0x100, AQUANTIA_VND1_GSYSCFG_10G, -+ AQUANTIA_VND1_GSTART_RATE_10G}, -+ [PHY_INTERFACE_MODE_USXGMII] = {0x080, AQUANTIA_VND1_GSYSCFG_10G, -+ AQUANTIA_VND1_GSTART_RATE_10G}, -+}; -+ -+/* Sets up protocol on system side before calling aqr_config_aneg */ -+static int aqr_config_aneg_set_prot(struct phy_device *phydev) -+{ -+ int if_type = phydev->interface; -+ int i; -+ -+ if (!aquantia_syscfg[if_type].cnt) -+ return 0; -+ -+ /* set PHY in low power mode so we can configure protocols */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, -+ AQUANTIA_VND1_GLOBAL_SC_LP); -+ mdelay(10); -+ -+ /* set the default rate to enable the SI link */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, -+ aquantia_syscfg[if_type].start_rate); -+ -+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ AQUANTIA_VND1_GSYSCFG_BASE + i, -+ aquantia_syscfg[if_type].syscfg); -+ -+ /* wake PHY back up */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); -+ mdelay(10); -+ -+ return aqr_config_aneg(phydev); -+} -+ - static int aqr_config_intr(struct phy_device *phydev) - { - bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED; -@@ -869,6 +939,30 @@ static struct phy_driver aqr_driver[] = - .get_stats = aqr107_get_stats, - .link_change_notify = aqr107_link_change_notify, - }, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112), -+ .name = "Aquantia AQR112", -+ .probe = aqr107_probe, -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR412), -+ .name = "Aquantia AQR412", -+ .probe = aqr107_probe, -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+}, - }; - - module_phy_driver(aqr_driver); -@@ -886,6 +980,8 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) }, - { } - }; - diff --git a/target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch b/target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch deleted file mode 100644 index 72a70ebc140a94..00000000000000 --- a/target/linux/generic/hack-6.1/723-net-phy-aquantia-fix-system-side-protocol-mi.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5f008cb22f60da4e10375f22266c1a4e20b1252e Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Fri, 20 Sep 2019 18:22:52 +0300 -Subject: [PATCH] drivers: net: phy: aquantia: fix system side protocol - misconfiguration - -Do not set up protocols for speeds that are not supported by FW. Enabling -these protocols leads to link issues on system side. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/aquantia/aquantia_main.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -288,10 +288,16 @@ static int aqr_config_aneg_set_prot(stru - phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, - aquantia_syscfg[if_type].start_rate); - -- for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) -+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) { -+ u16 reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, -+ AQUANTIA_VND1_GSYSCFG_BASE + i); -+ if (!reg) -+ continue; -+ - phy_write_mmd(phydev, MDIO_MMD_VEND1, - AQUANTIA_VND1_GSYSCFG_BASE + i, - aquantia_syscfg[if_type].syscfg); -+ } - - /* wake PHY back up */ - phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); diff --git a/target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch b/target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch deleted file mode 100644 index 6d107c33498edb..00000000000000 --- a/target/linux/generic/hack-6.1/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3b92ee7b7899b6beffb2b484c58326e36612a873 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 23 Dec 2021 14:52:56 +0000 -Subject: [PATCH] net: phy: aquantia: add PHY_ID for AQR112R - -As advised by Ian Chang this PHY is used in Puzzle devices. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/aquantia/aquantia_main.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/net/phy/aquantia/aquantia_main.c -+++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -29,6 +29,8 @@ - #define PHY_ID_AQR813 0x31c31cb2 - #define PHY_ID_AQR112 0x03a1b662 - #define PHY_ID_AQR412 0x03a1b712 -+#define PHY_ID_AQR112C 0x03a1b790 -+#define PHY_ID_AQR112R 0x31c31d12 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -@@ -969,6 +971,30 @@ static struct phy_driver aqr_driver[] = - .get_strings = aqr107_get_strings, - .get_stats = aqr107_get_stats, - }, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112C), -+ .name = "Aquantia AQR112C", -+ .probe = aqr107_probe, -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112R), -+ .name = "Aquantia AQR112R", -+ .probe = aqr107_probe, -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .handle_interrupt = aqr_handle_interrupt, -+ .read_status = aqr107_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, -+}, - }; - - module_phy_driver(aqr_driver); -@@ -988,6 +1014,8 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112C) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112R) }, - { } - }; - diff --git a/target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch b/target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch deleted file mode 100644 index a2bd3a3dbbc26b..00000000000000 --- a/target/linux/generic/hack-6.1/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 880d1311335120f64447ca9d11933872d734e19a Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 27 Mar 2023 18:41:54 +0100 -Subject: [PATCH] generic: pcs-mtk-lynxi: add hack to use 2500Base-X without AN - -Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually -disabling auto-negotiation, e.g. using ethtool. While a proper fix -using SFP quirks is being discussed upstream, bring a work-around to -restore user experience to what it was before the switch to the -dedicated SGMII PCS driver. - -Signed-off-by: Daniel Golle - ---- a/drivers/net/pcs/pcs-mtk-lynxi.c -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -114,14 +114,23 @@ static void mtk_pcs_lynxi_get_state(stru - struct phylink_link_state *state) - { - struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -- unsigned int bm, adv; -+ unsigned int bm, bmsr, adv; - - /* Read the BMSR and LPA */ - regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm); -- regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -+ bmsr = FIELD_GET(SGMII_BMSR, bm); -+ -+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { -+ state->link = !!(bmsr & BMSR_LSTATUS); -+ state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); -+ state->speed = SPEED_2500; -+ state->duplex = DUPLEX_FULL; - -- phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm), -- FIELD_GET(SGMII_LPA, adv)); -+ return; -+ } -+ -+ regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv); -+ phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv)); - } - - static void mtk_sgmii_reset(struct mtk_pcs_lynxi *mpcs) -@@ -163,7 +172,8 @@ static int mtk_pcs_lynxi_config(struct p - if (neg_mode & PHYLINK_PCS_NEG_INBAND) - sgm_mode |= SGMII_REMOTE_FAULT_DIS; - -- if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) { -+ if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED && -+ interface != PHY_INTERFACE_MODE_2500BASEX) { - if (interface == PHY_INTERFACE_MODE_SGMII) - sgm_mode |= SGMII_SPEED_DUPLEX_AN; - bmcr = BMCR_ANENABLE; diff --git a/target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch b/target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch deleted file mode 100644 index 48d4626ed632ef..00000000000000 --- a/target/linux/generic/hack-6.1/760-net-usb-r8152-add-LED-configuration-from-OF.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 82985725e071f2a5735052f18e109a32aeac3a0b Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sun, 26 Jul 2020 02:38:31 +0200 -Subject: [PATCH] net: usb: r8152: add LED configuration from OF - -This adds the ability to configure the LED configuration register using -OF. This way, the correct value for board specific LED configuration can -be determined. - -Signed-off-by: David Bauer ---- - drivers/net/usb/r8152.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - ---- a/drivers/net/usb/r8152.c -+++ b/drivers/net/usb/r8152.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -7034,6 +7035,22 @@ static void rtl_tally_reset(struct r8152 - ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data); - } - -+static int r8152_led_configuration(struct r8152 *tp) -+{ -+ u32 led_data; -+ int ret; -+ -+ ret = of_property_read_u32(tp->udev->dev.of_node, "realtek,led-data", -+ &led_data); -+ -+ if (ret) -+ return ret; -+ -+ ocp_write_word(tp, MCU_TYPE_PLA, PLA_LEDSEL, led_data); -+ -+ return 0; -+} -+ - static void r8152b_init(struct r8152 *tp) - { - u32 ocp_data; -@@ -7075,6 +7092,8 @@ static void r8152b_init(struct r8152 *tp - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); - ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); - ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); -+ -+ r8152_led_configuration(tp); - } - - static void r8153_init(struct r8152 *tp) -@@ -7215,6 +7234,8 @@ static void r8153_init(struct r8152 *tp) - tp->coalesce = COALESCE_SLOW; - break; - } -+ -+ r8152_led_configuration(tp); - } - - static void r8153b_init(struct r8152 *tp) -@@ -7297,6 +7318,8 @@ static void r8153b_init(struct r8152 *tp - rtl_tally_reset(tp); - - tp->coalesce = 15000; /* 15 us */ -+ -+ r8152_led_configuration(tp); - } - - static void r8153c_init(struct r8152 *tp) diff --git a/target/linux/generic/hack-6.1/761-dt-bindings-net-add-RTL8152-binding-documentation.patch b/target/linux/generic/hack-6.1/761-dt-bindings-net-add-RTL8152-binding-documentation.patch deleted file mode 100644 index be262b993cd5d4..00000000000000 --- a/target/linux/generic/hack-6.1/761-dt-bindings-net-add-RTL8152-binding-documentation.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 3ee05f4aa64fc86af3be5bc176ba5808de9260a7 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sun, 26 Jul 2020 15:30:33 +0200 -Subject: [PATCH] dt-bindings: net: add RTL8152 binding documentation - -Add binding documentation for the Realtek RTL8152 / RTL8153 USB ethernet -adapters. - -Signed-off-by: David Bauer ---- - .../bindings/net/realtek,rtl8152.yaml | 36 +++++++++++++++++++ - 1 file changed, 36 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8152.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/realtek,rtl8152.yaml -@@ -0,0 +1,36 @@ -+# SPDX-License-Identifier: GPL-2.0 -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/net/realtek,rtl8152.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Realtek RTL8152/RTL8153 series USB ethernet -+ -+maintainers: -+ - David Bauer -+ -+properties: -+ compatible: -+ oneOf: -+ - items: -+ - enum: -+ - realtek,rtl8152 -+ - realtek,rtl8153 -+ -+ reg: -+ description: The device number on the USB bus -+ -+ realtek,led-data: -+ description: Value to be written to the LED configuration register. -+ -+required: -+ - compatible -+ - reg -+ -+examples: -+ - | -+ usb-eth@2 { -+ compatible = "realtek,rtl8153"; -+ reg = <2>; -+ realtek,led-data = <0x87>; -+ }; -\ No newline at end of file diff --git a/target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch b/target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch deleted file mode 100644 index 70851ec9acbb59..00000000000000 --- a/target/linux/generic/hack-6.1/765-mxl-gpy-control-LED-reg-from-DT.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 94b90966095f3fa625897e8f53d215882f6e19b3 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Sat, 11 Mar 2023 17:00:01 +0100 -Subject: [PATCH] mxl-gpy: control LED reg from DT - -Add dynamic configuration for the LED control registers on MXL PHYs. - -This patch has been tested with MaxLinear GPY211C. It is unlikely to be -accepted upstream, as upstream plans on integrating their own framework -for handling these LEDs. - -For the time being, use this hack to configure PHY driven device-LEDs to -show the correct state. - -A possible alternative might be to expose the LEDs using the kernel LED -framework and bind it to the netdevice. This might also be upstreamable, -although it is a considerable extra amount of work. - -Signed-off-by: David Bauer ---- - drivers/net/phy/mxl-gpy.c | 37 ++++++++++++++++++++++++++++++++++++- - 1 file changed, 36 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/mxl-gpy.c -+++ b/drivers/net/phy/mxl-gpy.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -33,6 +34,7 @@ - #define PHY_MIISTAT 0x18 /* MII state */ - #define PHY_IMASK 0x19 /* interrupt mask */ - #define PHY_ISTAT 0x1A /* interrupt status */ -+#define PHY_LED 0x1B /* LED control */ - #define PHY_FWV 0x1E /* firmware version */ - - #define PHY_MIISTAT_SPD_MASK GENMASK(2, 0) -@@ -56,10 +58,15 @@ - PHY_IMASK_ADSC | \ - PHY_IMASK_ANC) - -+#define PHY_LED_NUM_LEDS 4 -+ - #define PHY_FWV_REL_MASK BIT(15) - #define PHY_FWV_MAJOR_MASK GENMASK(11, 8) - #define PHY_FWV_MINOR_MASK GENMASK(7, 0) - -+/* LED */ -+#define VSPEC1_LED(x) (0x1 + x) -+ - /* SGMII */ - #define VSPEC1_SGMII_CTRL 0x08 - #define VSPEC1_SGMII_CTRL_ANEN BIT(12) /* Aneg enable */ -@@ -258,10 +265,39 @@ out: - return ret; - } - -+static int gpy_led_write(struct phy_device *phydev) -+{ -+ struct device_node *node = phydev->mdio.dev.of_node; -+ u32 led_regs[PHY_LED_NUM_LEDS]; -+ int i, ret; -+ u16 val = 0xff00; -+ -+ if (!IS_ENABLED(CONFIG_OF_MDIO)) -+ return 0; -+ -+ if (of_property_read_u32_array(node, "mxl,led-config", led_regs, PHY_LED_NUM_LEDS)) -+ return 0; -+ -+ if (of_property_read_bool(node, "mxl,led-drive-vdd")) -+ val &= 0x0fff; -+ -+ /* Enable LED function handling on all ports*/ -+ phy_write(phydev, PHY_LED, val); -+ -+ /* Write LED register values */ -+ for (i = 0; i < PHY_LED_NUM_LEDS; i++) { -+ ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_LED(i), (u16)led_regs[i]); -+ if (ret < 0) -+ return ret; -+ } -+ -+ return 0; -+} -+ - static int gpy_config_init(struct phy_device *phydev) - { - /* Nothing to configure. Configuration Requirement Placeholder */ -- return 0; -+ return gpy_led_write(phydev); - } - - static bool gpy_has_broken_mdint(struct phy_device *phydev) diff --git a/target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch b/target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch deleted file mode 100644 index 3405d5c535b6c9..00000000000000 --- a/target/linux/generic/hack-6.1/766-net-phy-mediatek-ge-add-LED-configuration-interface.patch +++ /dev/null @@ -1,72 +0,0 @@ -From cc225d163b5a4f7a0d1968298bf7927306646a47 Mon Sep 17 00:00:00 2001 -From: David Bauer -Date: Fri, 28 Apr 2023 01:53:01 +0200 -Subject: [PATCH] net: phy: mediatek-ge: add LED configuration interface - -This adds a small hack similar to the one used for ar8xxx switches to -read a reg:value map for configuring the LED configuration registers. - -This allows OpenWrt to write device-specific LED action as well as blink -configurations. It is unlikely to be accepted upstream, as upstream -plans on integrating their own framework for handling these LEDs. - -Signed-off-by: David Bauer ---- - drivers/net/phy/mediatek-ge.c | 33 +++++++++++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - ---- a/drivers/net/phy/mediatek-ge.c -+++ b/drivers/net/phy/mediatek-ge.c -@@ -1,4 +1,5 @@ - // SPDX-License-Identifier: GPL-2.0+ -+#include - #include - #include - #include -@@ -53,6 +54,36 @@ static int mt7530_phy_config_init(struct - return 0; - } - -+static int mt7530_led_config_of(struct phy_device *phydev) -+{ -+ struct device_node *np = phydev->mdio.dev.of_node; -+ const __be32 *paddr; -+ int len; -+ int i; -+ -+ paddr = of_get_property(np, "mediatek,led-config", &len); -+ if (!paddr) -+ return 0; -+ -+ if (len < (2 * sizeof(*paddr))) -+ return -EINVAL; -+ -+ len /= sizeof(*paddr); -+ -+ phydev_warn(phydev, "Configure LED registers (num=%d)\n", len); -+ for (i = 0; i < len - 1; i += 2) { -+ u32 reg; -+ u32 val; -+ -+ reg = be32_to_cpup(paddr + i); -+ val = be32_to_cpup(paddr + i + 1); -+ -+ phy_write_mmd(phydev, MDIO_MMD_VEND2, reg, val); -+ } -+ -+ return 0; -+} -+ - static int mt7531_phy_config_init(struct phy_device *phydev) - { - mtk_gephy_config_init(phydev); -@@ -65,6 +96,9 @@ static int mt7531_phy_config_init(struct - phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404); - phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404); - -+ /* LED Config*/ -+ mt7530_led_config_of(phydev); -+ - return 0; - } - diff --git a/target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch b/target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch deleted file mode 100644 index 633cacd1e7c313..00000000000000 --- a/target/linux/generic/hack-6.1/773-bgmac-add-srab-switch.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 3cb240533ab787899dc7f17aa7d6c5b4810e2e58 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Fri, 7 Jul 2017 17:26:01 +0200 -Subject: bcm53xx: bgmac: use srab switch driver - -use the srab switch driver on these SoCs. - -Signed-off-by: Hauke Mehrtens ---- - drivers/net/ethernet/broadcom/bgmac-bcma.c | 1 + - drivers/net/ethernet/broadcom/bgmac.c | 24 ++++++++++++++++++++++++ - drivers/net/ethernet/broadcom/bgmac.h | 4 ++++ - 3 files changed, 29 insertions(+) - ---- a/drivers/net/ethernet/broadcom/bgmac-bcma.c -+++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c -@@ -280,6 +280,7 @@ static int bgmac_probe(struct bcma_devic - bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; - bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; - bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500; -+ bgmac->feature_flags |= BGMAC_FEAT_SRAB; - break; - default: - bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; ---- a/drivers/net/ethernet/broadcom/bgmac.c -+++ b/drivers/net/ethernet/broadcom/bgmac.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1408,6 +1409,17 @@ static const struct ethtool_ops bgmac_et - .set_link_ksettings = phy_ethtool_set_link_ksettings, - }; - -+static struct b53_platform_data bgmac_b53_pdata = { -+}; -+ -+static struct platform_device bgmac_b53_dev = { -+ .name = "b53-srab-switch", -+ .id = -1, -+ .dev = { -+ .platform_data = &bgmac_b53_pdata, -+ }, -+}; -+ - /************************************************** - * MII - **************************************************/ -@@ -1546,6 +1558,14 @@ int bgmac_enet_probe(struct bgmac *bgmac - - bgmac->in_init = false; - -+ if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) { -+ bgmac_b53_pdata.regs = ioremap(0x18007000, 0x1000); -+ -+ err = platform_device_register(&bgmac_b53_dev); -+ if (!err) -+ bgmac->b53_device = &bgmac_b53_dev; -+ } -+ - err = register_netdev(bgmac->net_dev); - if (err) { - dev_err(bgmac->dev, "Cannot register net device\n"); -@@ -1568,6 +1588,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe); - - void bgmac_enet_remove(struct bgmac *bgmac) - { -+ if (bgmac->b53_device) -+ platform_device_unregister(&bgmac_b53_dev); -+ bgmac->b53_device = NULL; -+ - unregister_netdev(bgmac->net_dev); - phy_disconnect(bgmac->net_dev->phydev); - netif_napi_del(&bgmac->napi); ---- a/drivers/net/ethernet/broadcom/bgmac.h -+++ b/drivers/net/ethernet/broadcom/bgmac.h -@@ -388,6 +388,7 @@ - #define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18) - #define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19) - #define BGMAC_FEAT_IDM_MASK BIT(20) -+#define BGMAC_FEAT_SRAB BIT(21) - - struct bgmac_slot_info { - union { -@@ -495,6 +496,9 @@ struct bgmac { - void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask, - u32 set); - int (*phy_connect)(struct bgmac *bgmac); -+ -+ /* platform device for associated switch */ -+ struct platform_device *b53_device; - }; - - struct bgmac *bgmac_alloc(struct device *dev); diff --git a/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch b/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch deleted file mode 100644 index 6e318a6e9a9da0..00000000000000 --- a/target/linux/generic/hack-6.1/780-usb-net-MeigLink_modem_support.patch +++ /dev/null @@ -1,69 +0,0 @@ -From f81700b6bb2eda3756247bce472d8eaf6f466f61 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:49:26 +0200 -Subject: [PATCH] net/usb/qmi_wwan: add MeigLink modem support - ---- - drivers/net/usb/qmi_wwan.c | 1 + - drivers/usb/serial/option.c | 7 +++++++ - 2 files changed, 8 insertions(+) - ---- a/drivers/net/usb/qmi_wwan.c -+++ b/drivers/net/usb/qmi_wwan.c -@@ -1083,12 +1083,18 @@ static const struct usb_device_id produc - USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), - .driver_info = (unsigned long)&qmi_wwan_info, - }, -+ { /* Meiglink SGM828 */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d49, USB_CLASS_VENDOR_SPEC, 0x10, 0x05), -+ .driver_info = (unsigned long)&qmi_wwan_info, -+ }, -+ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ - {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */ -+ {QMI_MATCH_FF_FF_FF(0x05c6, 0xf601)}, /* MeigLink SLM750 */ - - /* 3. Combined interface devices matching on interface number */ - {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -247,6 +247,11 @@ static void option_instat_callback(struc - #define UBLOX_PRODUCT_R410M 0x90b2 - /* These Yuga products use Qualcomm's vendor ID */ - #define YUGA_PRODUCT_CLM920_NC5 0x9625 -+/* These MeigLink products use Qualcomm's vendor ID */ -+#define MEIGLINK_PRODUCT_SLM750 0xf601 -+ -+#define MEIGLINK_VENDOR_ID 0x2dee -+#define MEIGLINK_PRODUCT_SLM828 0x4d49 - - #define QUECTEL_VENDOR_ID 0x2c7c - /* These Quectel products use Quectel's vendor ID */ -@@ -1158,6 +1163,11 @@ static const struct usb_device_id option - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000), /* SIMCom SIM5218 */ - .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | NCTRL(3) | RSVD(4) }, -+ /* MeiG */ -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x01) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x02) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x03) }, -+ { USB_DEVICE_AND_INTERFACE_INFO(MEIGLINK_VENDOR_ID, MEIGLINK_PRODUCT_SLM828, USB_CLASS_VENDOR_SPEC, 0x10, 0x04) }, - /* Quectel products using Qualcomm vendor ID */ - { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, - { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), -@@ -1199,6 +1209,11 @@ static const struct usb_device_id option - .driver_info = ZLP }, - { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), - .driver_info = RSVD(4) }, -+ /* Meiglink products using Qualcomm vendor ID */ -+ // Works OK. In case of some issues check macros that are used by Quectel Products -+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0xff, 0xff), -+ .driver_info = NUMEP2 }, -+ { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750, 0xff, 0, 0) }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), - .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, - { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, diff --git a/target/linux/generic/hack-6.1/781-usb-net-rndis-support-asr.patch b/target/linux/generic/hack-6.1/781-usb-net-rndis-support-asr.patch deleted file mode 100644 index 47339b6c22f7b2..00000000000000 --- a/target/linux/generic/hack-6.1/781-usb-net-rndis-support-asr.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 9fabf60187f1fa19e6f6bb5441587d485bd534b0 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 9 Apr 2024 17:06:38 +0100 -Subject: [PATCH] rndis_host: add a bunch of USB IDs - -Add a bunch of USB IDs found in various places online to the -RNDIS USB network driver. - -Signed-off-by: Daniel Golle ---- - drivers/net/usb/rndis_host.c | 40 ++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - ---- a/drivers/net/usb/rndis_host.c -+++ b/drivers/net/usb/rndis_host.c -@@ -630,6 +630,16 @@ static const struct driver_info zte_rndi - .tx_fixup = rndis_tx_fixup, - }; - -+static const struct driver_info asr_rndis_info = { -+ .description = "Asr RNDIS device", -+ .flags = FLAG_WWAN | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT | FLAG_NOARP, -+ .bind = rndis_bind, -+ .unbind = rndis_unbind, -+ .status = rndis_status, -+ .rx_fixup = rndis_rx_fixup, -+ .tx_fixup = rndis_tx_fixup, -+}; -+ - /*-------------------------------------------------------------------------*/ - - static const struct usb_device_id products [] = { -@@ -666,6 +676,36 @@ static const struct usb_device_id produc - USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3), - .driver_info = (unsigned long) &rndis_info, - }, { -+ /* Quectel EG060V rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6004, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Quectel EC200A rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6005, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Quectel EC200T rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2c7c, 0x6026, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Simcom A7906E rndis device */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x1e0e, 0x9011, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Meig SLM770A */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { -+ /* Meig SLM828 */ -+ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d49, -+ USB_CLASS_WIRELESS_CONTROLLER, 1, 3), -+ .driver_info = (unsigned long) &asr_rndis_info, -+}, { - /* Novatel Verizon USB730L */ - USB_INTERFACE_INFO(USB_CLASS_MISC, 4, 1), - .driver_info = (unsigned long) &rndis_info, diff --git a/target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch b/target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch deleted file mode 100644 index 53f199d09b7fe6..00000000000000 --- a/target/linux/generic/hack-6.1/790-SFP-GE-T-ignore-TX_FAULT.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 7cc39a6bedbd85f3ff7e16845f310e4ce8d9833f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 6 Sep 2022 00:31:19 +0100 -Subject: [PATCH] net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module -To: netdev@vger.kernel.org, - linux-kernel@vger.kernel.org, - Russell King , - Andrew Lunn , - Heiner Kallweit -Cc: David S. Miller , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Josef Schlehofer - -This copper module comes with broken TX_FAULT indicator which must be -ignored for it to work. Implement ignoring TX_FAULT state bit also -during reset/insertion and mute the warning telling the user that the -module indicates TX_FAULT. - -Co-authored-by: Josef Schlehofer -Signed-off-by: Daniel Golle ---- - drivers/net/phy/sfp.c | 14 +++++++++++--- - 1 file changed, 11 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/sfp.c -+++ b/drivers/net/phy/sfp.c -@@ -409,6 +409,9 @@ static const struct sfp_quirk sfp_quirks - SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex, - sfp_fixup_ignore_tx_fault), - -+ // OEM SFP-GE-T is 1000Base-T module -+ SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault), -+ - // Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report - // 2500MBd NRZ in their EEPROM - SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex), -@@ -2343,7 +2346,8 @@ static void sfp_sm_main(struct sfp *sfp, - * or t_start_up, so assume there is a fault. - */ - sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT, -- sfp->sm_fault_retries == N_FAULT_INIT); -+ !sfp->tx_fault_ignore && -+ (sfp->sm_fault_retries == N_FAULT_INIT)); - } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) { - init_done: - /* Create mdiobus and start trying for PHY */ -@@ -2577,10 +2581,12 @@ static void sfp_check_state(struct sfp * - mutex_lock(&sfp->st_mutex); - state = sfp_get_state(sfp); - changed = state ^ sfp->state; -- if (sfp->tx_fault_ignore) -+ if (sfp->tx_fault_ignore) { - changed &= SFP_F_PRESENT | SFP_F_LOS; -- else -+ state &= ~SFP_F_TX_FAULT; -+ } else { - changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT; -+ } - - for (i = 0; i < GPIO_MAX; i++) - if (changed & BIT(i)) diff --git a/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch b/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch deleted file mode 100644 index b60b428dc8a837..00000000000000 --- a/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch +++ /dev/null @@ -1,190 +0,0 @@ -From cc809a441d8f2924f785eb863dfa6aef47a25b0b Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Tue, 12 Aug 2014 20:49:27 +0200 -Subject: [PATCH 30/36] GPIO: add named gpio exports - -Signed-off-by: John Crispin ---- a/drivers/gpio/gpiolib-of.c -+++ b/drivers/gpio/gpiolib-of.c -@@ -19,6 +19,8 @@ - #include - #include - #include -+#include -+#include - - #include "gpiolib.h" - #include "gpiolib-of.h" -@@ -1030,3 +1032,100 @@ void of_gpio_dev_init(struct gpio_chip * - else - gc->of_node = gdev->dev.of_node; - } -+ -+#ifdef CONFIG_GPIO_SYSFS -+ -+static struct of_device_id gpio_export_ids[] = { -+ { .compatible = "gpio-export" }, -+ { /* sentinel */ } -+}; -+ -+static int of_gpio_export_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device_node *cnp; -+ u32 val; -+ int nb = 0; -+ -+ for_each_child_of_node(np, cnp) { -+ const char *name = NULL; -+ int gpio; -+ bool dmc; -+ int max_gpio = 1; -+ int i; -+ -+ of_property_read_string(cnp, "gpio-export,name", &name); -+ -+ if (!name) -+ max_gpio = of_gpio_count(cnp); -+ -+ for (i = 0; i < max_gpio; i++) { -+ struct gpio_desc *desc; -+ unsigned flags = 0; -+ enum of_gpio_flags of_flags; -+ -+ gpio = of_get_gpio_flags(cnp, i, &of_flags); -+ if (!gpio_is_valid(gpio)) -+ return gpio; -+ -+ if (of_flags & OF_GPIO_ACTIVE_LOW) -+ flags |= GPIOF_ACTIVE_LOW; -+ -+ if (!of_property_read_u32(cnp, "gpio-export,output", &val)) { -+ if (of_flags & OF_GPIO_SINGLE_ENDED) { -+ /* -+ * As gpiod_direction_output_raw() is used, we -+ * need to emulate open drain or open source here. -+ */ -+ if (of_flags & OF_GPIO_OPEN_DRAIN) { -+ flags |= GPIOF_OPEN_DRAIN; -+ flags |= val ? GPIOF_IN : GPIOF_OUT_INIT_LOW; -+ } else { -+ flags |= GPIOF_OPEN_SOURCE; -+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_IN; -+ } -+ } else { -+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; -+ } -+ } else { -+ flags |= GPIOF_IN; -+ } -+ -+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np))) -+ continue; -+ -+ /* -+ * When emulating open-source or open-drain functionalities by not -+ * actively driving the line (setting mode to input) we still need to -+ * set the IS_OUT flag or otherwise we won't be able to set the line -+ * value anymore. -+ */ -+ if ((flags & GPIOF_IN) && -+ ((flags & GPIOF_OPEN_DRAIN) || (flags & GPIOF_OPEN_SOURCE))) { -+ desc = gpio_to_desc(gpio); -+ set_bit(FLAG_IS_OUT, &desc->flags); -+ } -+ -+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change"); -+ gpio_export_with_name(gpio, dmc, name); -+ nb++; -+ } -+ } -+ -+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb); -+ -+ return 0; -+} -+ -+static struct platform_driver gpio_export_driver = { -+ .driver = { -+ .name = "gpio-export", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(gpio_export_ids), -+ }, -+ .probe = of_gpio_export_probe, -+}; -+ -+module_platform_driver(gpio_export_driver); -+ -+#endif ---- a/include/asm-generic/gpio.h -+++ b/include/asm-generic/gpio.h -@@ -125,6 +125,12 @@ static inline int gpio_export(unsigned g - return gpiod_export(gpio_to_desc(gpio), direction_may_change); - } - -+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name); -+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name) -+{ -+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name); -+} -+ - static inline int gpio_export_link(struct device *dev, const char *name, - unsigned gpio) - { ---- a/include/linux/gpio/consumer.h -+++ b/include/linux/gpio/consumer.h -@@ -715,6 +715,7 @@ static inline struct gpio_desc *acpi_get - - #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) - -+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name); - int gpiod_export(struct gpio_desc *desc, bool direction_may_change); - int gpiod_export_link(struct device *dev, const char *name, - struct gpio_desc *desc); -@@ -722,6 +723,13 @@ void gpiod_unexport(struct gpio_desc *de - - #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */ - -+static inline int _gpiod_export(struct gpio_desc *desc, -+ bool direction_may_change, -+ const char *name) -+{ -+ return -ENOSYS; -+} -+ - static inline int gpiod_export(struct gpio_desc *desc, - bool direction_may_change) - { ---- a/drivers/gpio/gpiolib-sysfs.c -+++ b/drivers/gpio/gpiolib-sysfs.c -@@ -547,7 +547,7 @@ static struct class gpio_class = { - * - * Returns zero on success, else an error. - */ --int gpiod_export(struct gpio_desc *desc, bool direction_may_change) -+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name) - { - struct gpio_chip *chip; - struct gpio_device *gdev; -@@ -609,6 +609,8 @@ int gpiod_export(struct gpio_desc *desc, - offset = gpio_chip_hwgpio(desc); - if (chip->names && chip->names[offset]) - ioname = chip->names[offset]; -+ if (name) -+ ioname = name; - - dev = device_create_with_groups(&gpio_class, &gdev->dev, - MKDEV(0, 0), data, gpio_groups, -@@ -630,6 +632,12 @@ err_unlock: - gpiod_dbg(desc, "%s: status %d\n", __func__, status); - return status; - } -+EXPORT_SYMBOL_GPL(__gpiod_export); -+ -+int gpiod_export(struct gpio_desc *desc, bool direction_may_change) -+{ -+ return __gpiod_export(desc, direction_may_change, NULL); -+} - EXPORT_SYMBOL_GPL(gpiod_export); - - static int match_export(struct device *dev, const void *desc) diff --git a/target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch b/target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch deleted file mode 100644 index c581a512cbd5d0..00000000000000 --- a/target/linux/generic/hack-6.1/810-bcma-ssb-fallback-sprom.patch +++ /dev/null @@ -1,187 +0,0 @@ -From e4d708702e6c98f2111e33201a264d6788564cb2 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Fri, 12 May 2023 11:08:43 +0200 -Subject: [PATCH] ssb_sprom: add generic kernel support for Broadcom Fallback SPROMs - ---- - drivers/bcma/Kconfig | 4 ++++ - drivers/bcma/Makefile | 1 + - drivers/bcma/bcma_private.h | 4 ++++ - drivers/bcma/main.c | 8 ++++++++ - drivers/bcma/sprom.c | 23 ++++++++++++++--------- - drivers/ssb/Kconfig | 5 +++++ - drivers/ssb/Makefile | 1 + - drivers/ssb/main.c | 8 ++++++++ - drivers/ssb/sprom.c | 12 +++++++++++- - drivers/ssb/ssb_private.h | 4 ++++ - 10 files changed, 60 insertions(+), 10 deletions(-) - ---- a/drivers/bcma/Kconfig -+++ b/drivers/bcma/Kconfig -@@ -18,6 +18,10 @@ config BCMA_BLOCKIO - bool - default y - -+config BCMA_FALLBACK_SPROM -+ bool -+ default y -+ - config BCMA_HOST_PCI_POSSIBLE - bool - depends on PCI = y ---- a/drivers/bcma/Makefile -+++ b/drivers/bcma/Makefile -@@ -11,6 +11,7 @@ bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) - bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o - bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o - bcma-$(CONFIG_BCMA_DRIVER_GPIO) += driver_gpio.o -+bcma-$(CONFIG_BCMA_FALLBACK_SPROM) += fallback-sprom.o - bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o - bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o - obj-$(CONFIG_BCMA) += bcma.o ---- a/drivers/bcma/bcma_private.h -+++ b/drivers/bcma/bcma_private.h -@@ -38,6 +38,10 @@ int bcma_bus_resume(struct bcma_bus *bus - void bcma_detect_chip(struct bcma_bus *bus); - int bcma_bus_scan(struct bcma_bus *bus); - -+/* fallback-sprom.c */ -+int __init bcma_fbs_register(void); -+int bcma_get_fallback_sprom(struct bcma_bus *dev, struct ssb_sprom *out); -+ - /* sprom.c */ - int bcma_sprom_get(struct bcma_bus *bus); - ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -668,6 +668,14 @@ static int __init bcma_modinit(void) - { - int err; - -+#ifdef CONFIG_BCMA_FALLBACK_SPROM -+ err = bcma_fbs_register(); -+ if (err) { -+ pr_err("Fallback SPROM initialization failed\n"); -+ err = 0; -+ } -+#endif /* CONFIG_BCMA_FALLBACK_SPROM */ -+ - err = bcma_init_bus_register(); - if (err) - return err; ---- a/drivers/bcma/sprom.c -+++ b/drivers/bcma/sprom.c -@@ -51,21 +51,26 @@ static int bcma_fill_sprom_with_fallback - { - int err; - -- if (!get_fallback_sprom) { -+ if (get_fallback_sprom) -+ err = get_fallback_sprom(bus, out); -+ -+#ifdef CONFIG_BCMA_FALLBACK_SPROM -+ if (!get_fallback_sprom || err) -+ err = bcma_get_fallback_sprom(bus, out); -+#else -+ if (!get_fallback_sprom) - err = -ENOENT; -- goto fail; -- } -+#endif /* CONFIG_BCMA_FALLBACK_SPROM */ - -- err = get_fallback_sprom(bus, out); -- if (err) -- goto fail; -+ if (err) { -+ bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err); -+ return err; -+ } - - bcma_debug(bus, "Using SPROM revision %d provided by platform.\n", - bus->sprom.revision); -+ - return 0; --fail: -- bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err); -- return err; - } - - /************************************************** ---- a/drivers/ssb/Kconfig -+++ b/drivers/ssb/Kconfig -@@ -25,6 +25,11 @@ if SSB - config SSB_SPROM - bool - -+config SSB_FALLBACK_SPROM -+ bool -+ depends on SSB_PCIHOST -+ default y -+ - # Support for Block-I/O. SELECT this from the driver that needs it. - config SSB_BLOCKIO - bool ---- a/drivers/ssb/Makefile -+++ b/drivers/ssb/Makefile -@@ -2,6 +2,7 @@ - # core - ssb-y += main.o scan.o - ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o -+ssb-$(CONFIG_SSB_FALLBACK_SPROM) += fallback-sprom.o - ssb-$(CONFIG_SSB_SPROM) += sprom.o - - # host support ---- a/drivers/ssb/main.c -+++ b/drivers/ssb/main.c -@@ -1287,6 +1287,14 @@ static int __init ssb_modinit(void) - { - int err; - -+#ifdef CONFIG_SSB_FALLBACK_SPROM -+ err = ssb_fbs_register(); -+ if (err) { -+ pr_err("Fallback SPROM initialization failed\n"); -+ err = 0; -+ } -+#endif /* CONFIG_SSB_FALLBACK_SPROM */ -+ - /* See the comment at the ssb_is_early_boot definition */ - ssb_is_early_boot = 0; - err = bus_register(&ssb_bustype); ---- a/drivers/ssb/sprom.c -+++ b/drivers/ssb/sprom.c -@@ -180,10 +180,20 @@ int ssb_arch_register_fallback_sprom(int - - int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out) - { -+ int err; -+ -+ if (get_fallback_sprom) -+ err = get_fallback_sprom(bus, out); -+ -+#ifdef CONFIG_SSB_FALLBACK_SPROM -+ if (!get_fallback_sprom || err) -+ err = ssb_get_fallback_sprom(bus, out); -+#else - if (!get_fallback_sprom) - return -ENOENT; -+#endif /* CONFIG_SSB_FALLBACK_SPROM */ - -- return get_fallback_sprom(bus, out); -+ return err; - } - - /* https://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */ ---- a/drivers/ssb/ssb_private.h -+++ b/drivers/ssb/ssb_private.h -@@ -143,6 +143,10 @@ extern int ssb_bus_scan(struct ssb_bus * - extern void ssb_iounmap(struct ssb_bus *ssb); - - -+/* fallback-sprom.c */ -+int __init ssb_fbs_register(void); -+int ssb_get_fallback_sprom(struct ssb_bus *dev, struct ssb_sprom *out); -+ - /* sprom.c */ - extern - ssize_t ssb_attr_sprom_show(struct ssb_bus *bus, char *buf, diff --git a/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch b/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch deleted file mode 100644 index 09b59478aae2ba..00000000000000 --- a/target/linux/generic/hack-6.1/901-debloat_sock_diag.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 3b6115d6b57a263bdc8c9b1df273bd4a7955eead Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 8 Jul 2017 08:16:31 +0200 -Subject: debloat: add some debloat patches, strip down procfs and make O_DIRECT support optional, saves ~15K after lzma on MIPS - -Signed-off-by: Felix Fietkau ---- - net/Kconfig | 3 +++ - net/core/Makefile | 3 ++- - net/core/sock.c | 2 ++ - net/ipv4/Kconfig | 1 + - net/netlink/Kconfig | 1 + - net/packet/Kconfig | 1 + - net/unix/Kconfig | 1 + - 7 files changed, 11 insertions(+), 1 deletion(-) - ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -104,6 +104,9 @@ source "net/mptcp/Kconfig" - - endif # if INET - -+config SOCK_DIAG -+ bool -+ - config NETWORK_SECMARK - bool "Security Marking" - help ---- a/net/core/Makefile -+++ b/net/core/Makefile -@@ -11,11 +11,12 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core. - - obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ - neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ -- sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ -+ dev_ioctl.o tso.o sock_reuseport.o \ - fib_notifier.o xdp.o flow_offload.o gro.o - - obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o - -+obj-$(CONFIG_SOCK_DIAG) += sock_diag.o - obj-y += net-sysfs.o - obj-$(CONFIG_PAGE_POOL) += page_pool.o - obj-$(CONFIG_PROC_FS) += net-procfs.o ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -115,6 +115,7 @@ - #include - #include - #include -+#include - - #include - -@@ -146,6 +147,7 @@ - - static DEFINE_MUTEX(proto_list_mutex); - static LIST_HEAD(proto_list); -+DEFINE_COOKIE(sock_cookie); - - static void sock_def_write_space_wfree(struct sock *sk); - static void sock_def_write_space(struct sock *sk); -@@ -586,6 +588,18 @@ discard_and_relse: - } - EXPORT_SYMBOL(__sk_receive_skb); - -+u64 __sock_gen_cookie(struct sock *sk) -+{ -+ while (1) { -+ u64 res = atomic64_read(&sk->sk_cookie); -+ -+ if (res) -+ return res; -+ res = gen_cookie_next(&sock_cookie); -+ atomic64_cmpxchg(&sk->sk_cookie, 0, res); -+ } -+} -+ - INDIRECT_CALLABLE_DECLARE(struct dst_entry *ip6_dst_check(struct dst_entry *, - u32)); - INDIRECT_CALLABLE_DECLARE(struct dst_entry *ipv4_dst_check(struct dst_entry *, -@@ -2189,9 +2203,11 @@ static void __sk_free(struct sock *sk) - if (likely(sk->sk_net_refcnt)) - sock_inuse_add(sock_net(sk), -1); - -+#ifdef CONFIG_SOCK_DIAG - if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk))) - sock_diag_broadcast_destroy(sk); - else -+#endif - sk_destruct(sk); - } - ---- a/net/core/sock_diag.c -+++ b/net/core/sock_diag.c -@@ -12,7 +12,6 @@ - #include - #include - #include --#include - #include - #include - -@@ -21,20 +20,6 @@ static int (*inet_rcv_compat)(struct sk_ - static DEFINE_MUTEX(sock_diag_table_mutex); - static struct workqueue_struct *broadcast_wq; - --DEFINE_COOKIE(sock_cookie); -- --u64 __sock_gen_cookie(struct sock *sk) --{ -- while (1) { -- u64 res = atomic64_read(&sk->sk_cookie); -- -- if (res) -- return res; -- res = gen_cookie_next(&sock_cookie); -- atomic64_cmpxchg(&sk->sk_cookie, 0, res); -- } --} -- - int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie) - { - u64 res; ---- a/net/ipv4/Kconfig -+++ b/net/ipv4/Kconfig -@@ -423,6 +423,7 @@ config INET_TUNNEL - - config INET_DIAG - tristate "INET: socket monitoring interface" -+ select SOCK_DIAG - default y - help - Support for INET (TCP, DCCP, etc) socket monitoring interface used by ---- a/net/netlink/Kconfig -+++ b/net/netlink/Kconfig -@@ -5,6 +5,7 @@ - - config NETLINK_DIAG - tristate "NETLINK: socket monitoring interface" -+ select SOCK_DIAG - default n - help - Support for NETLINK socket monitoring interface used by the ss tool. ---- a/net/packet/Kconfig -+++ b/net/packet/Kconfig -@@ -19,6 +19,7 @@ config PACKET - config PACKET_DIAG - tristate "Packet: sockets monitoring interface" - depends on PACKET -+ select SOCK_DIAG - default n - help - Support for PF_PACKET sockets monitoring interface used by the ss tool. ---- a/net/unix/Kconfig -+++ b/net/unix/Kconfig -@@ -33,6 +33,7 @@ config AF_UNIX_OOB - config UNIX_DIAG - tristate "UNIX: socket monitoring interface" - depends on UNIX -+ select SOCK_DIAG - default n - help - Support for UNIX socket monitoring interface used by the ss tool. ---- a/net/xdp/Kconfig -+++ b/net/xdp/Kconfig -@@ -10,6 +10,7 @@ config XDP_SOCKETS - config XDP_SOCKETS_DIAG - tristate "XDP sockets: monitoring interface" - depends on XDP_SOCKETS -+ select SOCK_DIAG - default n - help - Support for PF_XDP sockets monitoring interface used by the ss tool. diff --git a/target/linux/generic/hack-6.1/902-debloat_proc.patch b/target/linux/generic/hack-6.1/902-debloat_proc.patch deleted file mode 100644 index 2bc86fa1e27f8d..00000000000000 --- a/target/linux/generic/hack-6.1/902-debloat_proc.patch +++ /dev/null @@ -1,419 +0,0 @@ -From 9e3f1d0805b2d919904dd9a4ff0d956314cc3cba Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 8 Jul 2017 08:20:09 +0200 -Subject: debloat: procfs - -Signed-off-by: Felix Fietkau ---- - fs/locks.c | 2 ++ - fs/proc/Kconfig | 5 +++++ - fs/proc/consoles.c | 3 +++ - fs/proc/proc_tty.c | 11 ++++++++++- - include/net/snmp.h | 18 +++++++++++++++++- - ipc/msg.c | 3 +++ - ipc/sem.c | 2 ++ - ipc/shm.c | 2 ++ - ipc/util.c | 3 +++ - kernel/exec_domain.c | 2 ++ - kernel/irq/proc.c | 9 +++++++++ - kernel/time/timer_list.c | 2 ++ - mm/vmalloc.c | 2 ++ - mm/vmstat.c | 8 +++++--- - net/8021q/vlanproc.c | 6 ++++++ - net/core/net-procfs.c | 18 ++++++++++++------ - net/core/sock.c | 2 ++ - net/ipv4/fib_trie.c | 18 ++++++++++++------ - net/ipv4/proc.c | 3 +++ - net/ipv4/route.c | 3 +++ - 20 files changed, 105 insertions(+), 17 deletions(-) - ---- a/fs/locks.c -+++ b/fs/locks.c -@@ -2907,6 +2907,8 @@ static const struct seq_operations locks - - static int __init proc_locks_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - proc_create_seq_private("locks", 0, NULL, &locks_seq_operations, - sizeof(struct locks_iterator), NULL); - return 0; ---- a/fs/proc/Kconfig -+++ b/fs/proc/Kconfig -@@ -101,6 +101,11 @@ config PROC_CHILDREN - Say Y if you are running any user-space software which takes benefit from - this interface. For example, rkt is such a piece of software. - -+config PROC_STRIPPED -+ default n -+ depends on EXPERT -+ bool "Strip non-essential /proc functionality to reduce code size" -+ - config PROC_PID_ARCH_STATUS - def_bool n - depends on PROC_FS ---- a/fs/proc/consoles.c -+++ b/fs/proc/consoles.c -@@ -92,6 +92,9 @@ static const struct seq_operations conso - - static int __init proc_consoles_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - proc_create_seq("consoles", 0, NULL, &consoles_op); - return 0; - } ---- a/fs/proc/proc_tty.c -+++ b/fs/proc/proc_tty.c -@@ -131,7 +131,10 @@ static const struct seq_operations tty_d - void proc_tty_register_driver(struct tty_driver *driver) - { - struct proc_dir_entry *ent; -- -+ -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (!driver->driver_name || driver->proc_entry || - !driver->ops->proc_show) - return; -@@ -148,6 +151,9 @@ void proc_tty_unregister_driver(struct t - { - struct proc_dir_entry *ent; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - ent = driver->proc_entry; - if (!ent) - return; -@@ -162,6 +168,9 @@ void proc_tty_unregister_driver(struct t - */ - void __init proc_tty_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (!proc_mkdir("tty", NULL)) - return; - proc_mkdir("tty/ldisc", NULL); /* Preserved: it's userspace visible */ ---- a/include/net/snmp.h -+++ b/include/net/snmp.h -@@ -124,6 +124,21 @@ struct linux_tls_mib { - #define DECLARE_SNMP_STAT(type, name) \ - extern __typeof__(type) __percpu *name - -+#ifdef CONFIG_PROC_STRIPPED -+#define __SNMP_STATS_DUMMY(mib) \ -+ do { (void) mib->mibs[0]; } while(0) -+ -+#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -+#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib) -+#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -+#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) -+#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) -+#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) -+#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) -+#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) -+ -+#else -+ - #define __SNMP_INC_STATS(mib, field) \ - __this_cpu_inc(mib->mibs[field]) - -@@ -154,8 +169,9 @@ struct linux_tls_mib { - __this_cpu_add(ptr[basefield##OCTETS], addend); \ - } while (0) - -+#endif - --#if BITS_PER_LONG==32 -+#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED) - - #define __SNMP_ADD_STATS64(mib, field, addend) \ - do { \ ---- a/ipc/msg.c -+++ b/ipc/msg.c -@@ -1370,6 +1370,9 @@ void __init msg_init(void) - { - msg_init_ns(&init_ipc_ns); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - ipc_init_proc_interface("sysvipc/msg", - " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n", - IPC_MSG_IDS, sysvipc_msg_proc_show); ---- a/ipc/sem.c -+++ b/ipc/sem.c -@@ -268,6 +268,8 @@ void sem_exit_ns(struct ipc_namespace *n - void __init sem_init(void) - { - sem_init_ns(&init_ipc_ns); -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; - ipc_init_proc_interface("sysvipc/sem", - " key semid perms nsems uid gid cuid cgid otime ctime\n", - IPC_SEM_IDS, sysvipc_sem_proc_show); ---- a/ipc/shm.c -+++ b/ipc/shm.c -@@ -154,6 +154,8 @@ pure_initcall(ipc_ns_init); - - void __init shm_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; - ipc_init_proc_interface("sysvipc/shm", - #if BITS_PER_LONG <= 32 - " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n", ---- a/ipc/util.c -+++ b/ipc/util.c -@@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(cons - struct proc_dir_entry *pde; - struct ipc_proc_iface *iface; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - iface = kmalloc(sizeof(*iface), GFP_KERNEL); - if (!iface) - return; ---- a/kernel/exec_domain.c -+++ b/kernel/exec_domain.c -@@ -29,6 +29,8 @@ static int execdomains_proc_show(struct - - static int __init proc_execdomains_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - proc_create_single("execdomains", 0, NULL, execdomains_proc_show); - return 0; - } ---- a/kernel/irq/proc.c -+++ b/kernel/irq/proc.c -@@ -341,6 +341,9 @@ void register_irq_proc(unsigned int irq, - void __maybe_unused *irqp = (void *)(unsigned long) irq; - char name [MAX_NAMELEN]; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) - return; - -@@ -394,6 +397,9 @@ void unregister_irq_proc(unsigned int ir - { - char name [MAX_NAMELEN]; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - if (!root_irq_dir || !desc->dir) - return; - #ifdef CONFIG_SMP -@@ -432,6 +438,9 @@ void init_irq_proc(void) - unsigned int irq; - struct irq_desc *desc; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) -+ return; -+ - /* create /proc/irq */ - root_irq_dir = proc_mkdir("irq", NULL); - if (!root_irq_dir) ---- a/kernel/time/timer_list.c -+++ b/kernel/time/timer_list.c -@@ -350,6 +350,8 @@ static int __init init_timer_list_procfs - { - struct proc_dir_entry *pe; - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops, - sizeof(struct timer_list_iter), NULL); - if (!pe) ---- a/mm/vmalloc.c -+++ b/mm/vmalloc.c -@@ -4215,6 +4215,8 @@ static const struct seq_operations vmall - - static int __init proc_vmalloc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - if (IS_ENABLED(CONFIG_NUMA)) - proc_create_seq_private("vmallocinfo", 0400, NULL, - &vmalloc_op, ---- a/mm/vmstat.c -+++ b/mm/vmstat.c -@@ -2109,10 +2109,12 @@ void __init init_mm_internals(void) - start_shepherd_timer(); - #endif - #ifdef CONFIG_PROC_FS -- proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); -- proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); -+ proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); -+ proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op); -+ } - proc_create_seq("vmstat", 0444, NULL, &vmstat_op); -- proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op); - #endif - } - ---- a/net/8021q/vlanproc.c -+++ b/net/8021q/vlanproc.c -@@ -93,6 +93,9 @@ void vlan_proc_cleanup(struct net *net) - { - struct vlan_net *vn = net_generic(net, vlan_net_id); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return; -+ - if (vn->proc_vlan_conf) - remove_proc_entry(name_conf, vn->proc_vlan_dir); - -@@ -112,6 +115,9 @@ int __net_init vlan_proc_init(struct net - { - struct vlan_net *vn = net_generic(net, vlan_net_id); - -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net); - if (!vn->proc_vlan_dir) - goto err; ---- a/net/core/net-procfs.c -+++ b/net/core/net-procfs.c -@@ -319,10 +319,12 @@ static int __net_init dev_proc_net_init( - if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops, - sizeof(struct seq_net_private))) - goto out; -- if (!proc_create_seq("softnet_stat", 0444, net->proc_net, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_seq("softnet_stat", 0444, net->proc_net, - &softnet_seq_ops)) - goto out_dev; -- if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops, - sizeof(struct seq_net_private))) - goto out_softnet; - -@@ -332,9 +334,11 @@ static int __net_init dev_proc_net_init( - out: - return rc; - out_ptype: -- remove_proc_entry("ptype", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("ptype", net->proc_net); - out_softnet: -- remove_proc_entry("softnet_stat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("softnet_stat", net->proc_net); - out_dev: - remove_proc_entry("dev", net->proc_net); - goto out; -@@ -344,8 +348,10 @@ static void __net_exit dev_proc_net_exit - { - wext_proc_exit(net); - -- remove_proc_entry("ptype", net->proc_net); -- remove_proc_entry("softnet_stat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ remove_proc_entry("ptype", net->proc_net); -+ remove_proc_entry("softnet_stat", net->proc_net); -+ } - remove_proc_entry("dev", net->proc_net); - } - ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -4118,6 +4118,8 @@ static __net_initdata struct pernet_oper - - static int __init proto_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; - return register_pernet_subsys(&proto_net_ops); - } - ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -3037,11 +3037,13 @@ static const struct seq_operations fib_r - - int __net_init fib_proc_init(struct net *net) - { -- if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops, - sizeof(struct fib_trie_iter))) - goto out1; - -- if (!proc_create_net_single("fib_triestat", 0444, net->proc_net, -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && -+ !proc_create_net_single("fib_triestat", 0444, net->proc_net, - fib_triestat_seq_show, NULL)) - goto out2; - -@@ -3052,17 +3054,21 @@ int __net_init fib_proc_init(struct net - return 0; - - out3: -- remove_proc_entry("fib_triestat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("fib_triestat", net->proc_net); - out2: -- remove_proc_entry("fib_trie", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ remove_proc_entry("fib_trie", net->proc_net); - out1: - return -ENOMEM; - } - - void __net_exit fib_proc_exit(struct net *net) - { -- remove_proc_entry("fib_trie", net->proc_net); -- remove_proc_entry("fib_triestat", net->proc_net); -+ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { -+ remove_proc_entry("fib_trie", net->proc_net); -+ remove_proc_entry("fib_triestat", net->proc_net); -+ } - remove_proc_entry("route", net->proc_net); - } - ---- a/net/ipv4/proc.c -+++ b/net/ipv4/proc.c -@@ -553,5 +553,8 @@ static __net_initdata struct pernet_oper - - int __init ip_misc_proc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - return register_pernet_subsys(&ip_proc_ops); - } ---- a/net/ipv4/route.c -+++ b/net/ipv4/route.c -@@ -381,6 +381,9 @@ static struct pernet_operations ip_rt_pr - - static int __init ip_rt_proc_init(void) - { -+ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) -+ return 0; -+ - return register_pernet_subsys(&ip_rt_proc_ops); - } - ---- a/net/ipv4/inet_timewait_sock.c -+++ b/net/ipv4/inet_timewait_sock.c -@@ -269,7 +269,7 @@ void __inet_twsk_schedule(struct inet_ti - */ - - if (!rearm) { -- bool kill = timeo <= 4*HZ; -+ bool __maybe_unused kill = timeo <= 4*HZ; - - __NET_INC_STATS(twsk_net(tw), kill ? LINUX_MIB_TIMEWAITKILLED : - LINUX_MIB_TIMEWAITED); diff --git a/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch b/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch deleted file mode 100644 index 8b6bd6a7862af4..00000000000000 --- a/target/linux/generic/hack-6.1/904-debloat_dma_buf.patch +++ /dev/null @@ -1,93 +0,0 @@ -From e3692cb2fcd5ba1244512a0f43b8118f65f1c375 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sat, 8 Jul 2017 08:20:43 +0200 -Subject: debloat: dmabuf - -Signed-off-by: Felix Fietkau ---- - drivers/base/Kconfig | 2 +- - drivers/dma-buf/Makefile | 10 +++++++--- - drivers/dma-buf/dma-buf.c | 4 +++- - kernel/sched/core.c | 1 + - 4 files changed, 12 insertions(+), 5 deletions(-) - ---- a/drivers/base/Kconfig -+++ b/drivers/base/Kconfig -@@ -198,7 +198,7 @@ config SOC_BUS - source "drivers/base/regmap/Kconfig" - - config DMA_SHARED_BUFFER -- bool -+ tristate - default n - select IRQ_WORK - help ---- a/drivers/dma-buf/heaps/Makefile -+++ b/drivers/dma-buf/heaps/Makefile -@@ -1,3 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 --obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o --obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o -+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o -+dma-buf-objs-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o ---- a/drivers/dma-buf/Makefile -+++ b/drivers/dma-buf/Makefile -@@ -1,12 +1,14 @@ - # SPDX-License-Identifier: GPL-2.0-only --obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ -+obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o -+ -+dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ - dma-fence-unwrap.o dma-resv.o --obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o --obj-$(CONFIG_DMABUF_HEAPS) += heaps/ --obj-$(CONFIG_SYNC_FILE) += sync_file.o --obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o --obj-$(CONFIG_UDMABUF) += udmabuf.o --obj-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o -+dma-buf-objs-$(CONFIG_DMABUF_HEAPS) += dma-heap.o -+obj-$(CONFIG_DMABUF_HEAPS) += heaps/ -+dma-buf-objs-$(CONFIG_SYNC_FILE) += sync_file.o -+dma-buf-objs-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o -+dma-buf-objs-$(CONFIG_UDMABUF) += udmabuf.o -+dma-buf-objs-$(CONFIG_DMABUF_SYSFS_STATS) += dma-buf-sysfs-stats.o - - dmabuf_selftests-y := \ - selftest.o \ -@@ -15,4 +17,6 @@ dmabuf_selftests-y := \ - st-dma-fence-unwrap.o \ - st-dma-resv.o - --obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o -+dma-buf-objs-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o -+ -+dma-shared-buffer-objs := $(dma-buf-objs-y) ---- a/drivers/dma-buf/dma-buf.c -+++ b/drivers/dma-buf/dma-buf.c -@@ -1636,4 +1636,5 @@ static void __exit dma_buf_deinit(void) - kern_unmount(dma_buf_mnt); - dma_buf_uninit_sysfs_statistics(); - } --__exitcall(dma_buf_deinit); -+module_exit(dma_buf_deinit); -+MODULE_LICENSE("GPL"); ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -4363,6 +4363,7 @@ int wake_up_state(struct task_struct *p, - { - return try_to_wake_up(p, state, 0); - } -+EXPORT_SYMBOL_GPL(wake_up_state); - - /* - * Perform scheduler related setup for a newly forked process p. ---- a/fs/d_path.c -+++ b/fs/d_path.c -@@ -313,6 +313,7 @@ char *dynamic_dname(char *buffer, int bu - buffer += buflen - sz; - return memcpy(buffer, temp, sz); - } -+EXPORT_SYMBOL_GPL(dynamic_dname); - - char *simple_dname(struct dentry *dentry, char *buffer, int buflen) - { diff --git a/target/linux/generic/hack-6.1/910-kobject_uevent.patch b/target/linux/generic/hack-6.1/910-kobject_uevent.patch deleted file mode 100644 index c4c41ca400ae32..00000000000000 --- a/target/linux/generic/hack-6.1/910-kobject_uevent.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sun, 16 Jul 2017 16:56:10 +0200 -Subject: lib: add uevent_next_seqnum() - -Signed-off-by: Felix Fietkau ---- - include/linux/kobject.h | 5 +++++ - lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 42 insertions(+) - ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -179,6 +179,18 @@ out: - return r; - } - -+u64 uevent_next_seqnum(void) -+{ -+ u64 seq; -+ -+ mutex_lock(&uevent_sock_mutex); -+ seq = ++uevent_seqnum; -+ mutex_unlock(&uevent_sock_mutex); -+ -+ return seq; -+} -+EXPORT_SYMBOL_GPL(uevent_next_seqnum); -+ - /** - * kobject_synth_uevent - send synthetic uevent with arguments - * diff --git a/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch deleted file mode 100644 index 99e95ce3523ec4..00000000000000 --- a/target/linux/generic/hack-6.1/911-kobject_add_broadcast_uevent.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sun, 16 Jul 2017 16:56:10 +0200 -Subject: lib: add broadcast_uevent() - -Signed-off-by: Felix Fietkau ---- - include/linux/kobject.h | 5 +++++ - lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 42 insertions(+) - ---- a/include/linux/kobject.h -+++ b/include/linux/kobject.h -@@ -32,6 +32,8 @@ - #define UEVENT_NUM_ENVP 64 /* number of env pointers */ - #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */ - -+struct sk_buff; -+ - #ifdef CONFIG_UEVENT_HELPER - /* path to the userspace helper executed on an event */ - extern char uevent_helper[]; -@@ -224,4 +226,7 @@ int kobject_synth_uevent(struct kobject - __printf(2, 3) - int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); - -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation); -+ - #endif /* _KOBJECT_H_ */ ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -706,6 +706,43 @@ int add_uevent_var(struct kobj_uevent_en - EXPORT_SYMBOL_GPL(add_uevent_var); - - #if defined(CONFIG_NET) -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation) -+{ -+ struct uevent_sock *ue_sk; -+ int err = 0; -+ -+ /* send netlink message */ -+ mutex_lock(&uevent_sock_mutex); -+ list_for_each_entry(ue_sk, &uevent_sock_list, list) { -+ struct sock *uevent_sock = ue_sk->sk; -+ struct sk_buff *skb2; -+ -+ skb2 = skb_clone(skb, allocation); -+ if (!skb2) -+ break; -+ -+ err = netlink_broadcast(uevent_sock, skb2, pid, group, -+ allocation); -+ if (err) -+ break; -+ } -+ mutex_unlock(&uevent_sock_mutex); -+ -+ kfree_skb(skb); -+ return err; -+} -+#else -+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, -+ gfp_t allocation) -+{ -+ kfree_skb(skb); -+ return 0; -+} -+#endif -+EXPORT_SYMBOL_GPL(broadcast_uevent); -+ -+#if defined(CONFIG_NET) - static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb, - struct netlink_ext_ack *extack) - { diff --git a/target/linux/generic/hack-6.1/920-device_tree_cmdline.patch b/target/linux/generic/hack-6.1/920-device_tree_cmdline.patch deleted file mode 100644 index cc384bb553baae..00000000000000 --- a/target/linux/generic/hack-6.1/920-device_tree_cmdline.patch +++ /dev/null @@ -1,21 +0,0 @@ -From e08bcbbaa52fcc41f02743fd2e62a33255ce52da Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 13:52:28 +0200 -Subject: [PATCH] of/ftd: add device tree cmdline - ---- - drivers/of/fdt.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/of/fdt.c -+++ b/drivers/of/fdt.c -@@ -1183,6 +1183,9 @@ int __init early_init_dt_scan_chosen(cha - p = of_get_flat_dt_prop(node, "bootargs", &l); - if (p != NULL && l > 0) - strscpy(cmdline, p, min(l, COMMAND_LINE_SIZE)); -+ p = of_get_flat_dt_prop(node, "bootargs-append", &l); -+ if (p != NULL && l > 0) -+ strlcat(cmdline, p, min_t(int, strlen(cmdline) + (int)l, COMMAND_LINE_SIZE)); - - handle_cmdline: - /* diff --git a/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch b/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch deleted file mode 100644 index 3476aa6edb09a9..00000000000000 --- a/target/linux/generic/hack-6.1/930-Revert-Revert-Revert-driver-core-Set-fw_devlink-on-b.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 19 Jul 2022 06:17:48 +0200 -Subject: [PATCH] Revert "Revert "Revert "driver core: Set fw_devlink=on by - default""" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit ea718c699055c8566eb64432388a04974c43b2ea. - -With of_platform_populate() called for MTD partitions that commit breaks -probing devices which reference MTD in device tree. - -Link: https://lore.kernel.org/all/696cb2da-20b9-b3dd-46d9-de4bf91a1506@gmail.com/T/#u -Signed-off-by: Rafał Miłecki ---- - drivers/base/core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -1718,7 +1718,7 @@ static void device_links_purge(struct de - #define FW_DEVLINK_FLAGS_RPM (FW_DEVLINK_FLAGS_ON | \ - DL_FLAG_PM_RUNTIME) - --static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_ON; -+static u32 fw_devlink_flags = FW_DEVLINK_FLAGS_PERMISSIVE; - static int __init fw_devlink_setup(char *arg) - { - if (!arg) diff --git a/target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch b/target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch deleted file mode 100644 index 7b342e69623314..00000000000000 --- a/target/linux/generic/pending-6.1/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Felix Fietkau -Date: Thu, 22 Oct 2020 22:00:03 +0200 -Subject: [PATCH] compiler.h: only include asm/rwonce.h for kernel code - -This header file is not in uapi, which makes any user space code that includes -linux/compiler.h to fail with the error 'asm/rwonce.h: No such file or directory' - -Fixes: e506ea451254 ("compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h") -Signed-off-by: Felix Fietkau ---- - ---- a/include/linux/compiler.h -+++ b/include/linux/compiler.h -@@ -203,6 +203,8 @@ void ftrace_likely_update(struct ftrace_ - __v; \ - }) - -+#include -+ - #endif /* __KERNEL__ */ - - /* -@@ -243,6 +245,4 @@ static inline void *offset_to_ptr(const - */ - #define prevent_tail_call_optimization() mb() - --#include -- - #endif /* __LINUX_COMPILER_H */ diff --git a/target/linux/generic/pending-6.1/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch b/target/linux/generic/pending-6.1/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch deleted file mode 100644 index d79d03defb3ad4..00000000000000 --- a/target/linux/generic/pending-6.1/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch +++ /dev/null @@ -1,57 +0,0 @@ -From: Felix Fietkau -Date: Wed, 18 Apr 2018 10:50:05 +0200 -Subject: [PATCH] MIPS: only process negative stack offsets on stack traces - -Fixes endless back traces in cases where the compiler emits a stack -pointer increase in a branch delay slot (probably for some form of -function return). - -[ 3.475442] BUG: MAX_STACK_TRACE_ENTRIES too low! -[ 3.480070] turning off the locking correctness validator. -[ 3.485521] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.34 #0 -[ 3.491475] Stack : 00000000 00000000 00000000 00000000 80e0fce2 00000034 00000000 00000000 -[ 3.499764] 87c3838c 80696377 8061047c 00000000 00000001 00000001 87c2d850 6534689f -[ 3.508059] 00000000 00000000 80e10000 00000000 00000000 000000cf 0000000f 00000000 -[ 3.516353] 00000000 806a0000 00076891 00000000 00000000 00000000 ffffffff 00000000 -[ 3.524648] 806c0000 00000004 80e10000 806a0000 00000003 80690000 00000000 80700000 -[ 3.532942] ... -[ 3.535362] Call Trace: -[ 3.537818] [<80010a48>] show_stack+0x58/0x100 -[ 3.542207] [<804c2f78>] dump_stack+0xe8/0x170 -[ 3.546613] [<80079f90>] save_trace+0xf0/0x110 -[ 3.551010] [<8007b1ec>] mark_lock+0x33c/0x78c -[ 3.555413] [<8007bf48>] __lock_acquire+0x2ac/0x1a08 -[ 3.560337] [<8007de60>] lock_acquire+0x64/0x8c -[ 3.564846] [<804e1570>] _raw_spin_lock_irqsave+0x54/0x78 -[ 3.570186] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.574770] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.579257] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.583839] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.588329] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.592911] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.597401] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.601983] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.606473] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.611055] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.615545] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.620125] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.624619] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.629197] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.633691] [<801b618c>] kernfs_notify+0x94/0xac -[ 3.638269] [<801b7b10>] sysfs_notify+0x74/0xa0 -[ 3.642763] [<801b618c>] kernfs_notify+0x94/0xac - -Signed-off-by: Felix Fietkau ---- - ---- a/arch/mips/kernel/process.c -+++ b/arch/mips/kernel/process.c -@@ -395,6 +395,8 @@ static inline int is_sp_move_ins(union m - - if (ip->i_format.opcode == addiu_op || - ip->i_format.opcode == daddiu_op) { -+ if (ip->i_format.simmediate > 0) -+ return 0; - *frame_size = -ip->i_format.simmediate; - return 1; - } diff --git a/target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch b/target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch deleted file mode 100644 index c8c0efaecfa1bb..00000000000000 --- a/target/linux/generic/pending-6.1/103-kbuild-export-SUBARCH.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 173019b66dcc9d68ad9333aa744dad1e369b5aa8 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau -Date: Sun, 9 Jul 2017 00:26:53 +0200 -Subject: [PATCH 34/34] kernel: add compile fix for linux 4.9 on x86 - -Signed-off-by: Felix Fietkau ---- - Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/Makefile -+++ b/Makefile -@@ -605,7 +605,7 @@ endif - # Allows the usage of unstable features in stable compilers. - export RUSTC_BOOTSTRAP := 1 - --export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG -+export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC HOSTPKG_CONFIG - export RUSTC RUSTDOC RUSTFMT RUSTC_OR_CLIPPY_QUIET RUSTC_OR_CLIPPY BINDGEN CARGO - export HOSTRUSTC KBUILD_HOSTRUSTFLAGS - export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL diff --git a/target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch b/target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch deleted file mode 100644 index d6b10491f830e5..00000000000000 --- a/target/linux/generic/pending-6.1/111-watchdog-max63xx_wdt-Add-support-for-specifying-WDI-.patch +++ /dev/null @@ -1,75 +0,0 @@ -From bd1b9f66d5134e518419f4c4dacf1884c1616983 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Thu, 28 Apr 2022 11:13:23 +0200 -Subject: [PATCH] watchdog: max63xx_wdt: Add support for specifying WDI logic - via GPIO -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On some boards is WDI logic of max6370 chip connected via GPIO. -So extend max63xx_wdt driver to allow specifying WDI logic via GPIO. - -Signed-off-by: Pali Rohár ---- - drivers/watchdog/max63xx_wdt.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - ---- a/drivers/watchdog/max63xx_wdt.c -+++ b/drivers/watchdog/max63xx_wdt.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - #define DEFAULT_HEARTBEAT 60 - #define MAX_HEARTBEAT 60 -@@ -53,6 +54,9 @@ struct max63xx_wdt { - void __iomem *base; - spinlock_t lock; - -+ /* GPIOs */ -+ struct gpio_desc *gpio_wdi; -+ - /* WDI and WSET bits write access routines */ - void (*ping)(struct max63xx_wdt *wdt); - void (*set)(struct max63xx_wdt *wdt, u8 set); -@@ -158,6 +162,17 @@ static const struct watchdog_info max63x - .identity = "max63xx Watchdog", - }; - -+static void max63xx_gpio_ping(struct max63xx_wdt *wdt) -+{ -+ spin_lock(&wdt->lock); -+ -+ gpiod_set_value(wdt->gpio_wdi, 1); -+ udelay(1); -+ gpiod_set_value(wdt->gpio_wdi, 0); -+ -+ spin_unlock(&wdt->lock); -+} -+ - static void max63xx_mmap_ping(struct max63xx_wdt *wdt) - { - u8 val; -@@ -225,10 +240,19 @@ static int max63xx_wdt_probe(struct plat - return -EINVAL; - } - -+ wdt->gpio_wdi = devm_gpiod_get(dev, NULL, GPIOD_FLAGS_BIT_DIR_OUT); -+ if (IS_ERR(wdt->gpio_wdi) && PTR_ERR(wdt->gpio_wdi) != -ENOENT) -+ return dev_err_probe(dev, PTR_ERR(wdt->gpio_wdi), -+ "unable to request gpio: %ld\n", -+ PTR_ERR(wdt->gpio_wdi)); -+ - err = max63xx_mmap_init(pdev, wdt); - if (err) - return err; - -+ if (!IS_ERR(wdt->gpio_wdi)) -+ wdt->ping = max63xx_gpio_ping; -+ - platform_set_drvdata(pdev, &wdt->wdd); - watchdog_set_drvdata(&wdt->wdd, wdt); - diff --git a/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch deleted file mode 100644 index 8fea984a330434..00000000000000 --- a/target/linux/generic/pending-6.1/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch +++ /dev/null @@ -1,82 +0,0 @@ -From: Tobias Wolf -Subject: mm: Fix alloc_node_mem_map with ARCH_PFN_OFFSET calculation - -An rt288x (ralink) based router (Belkin F5D8235 v1) does not boot with any -kernel beyond version 4.3 resulting in: - -BUG: Bad page state in process swapper pfn:086ac - -bisect resulted in: - -a1c34a3bf00af2cede839879502e12dc68491ad5 is the first bad commit -commit a1c34a3bf00af2cede839879502e12dc68491ad5 -Author: Laura Abbott -Date: Thu Nov 5 18:48:46 2015 -0800 - - mm: Don't offset memmap for flatmem - - Srinivas Kandagatla reported bad page messages when trying to remove the - bottom 2MB on an ARM based IFC6410 board - - BUG: Bad page state in process swapper pfn:fffa8 - page:ef7fb500 count:0 mapcount:0 mapping: (null) index:0x0 - flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked) - page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set - bad because of flags: - flags: 0x200041(locked|active|mlocked) - Modules linked in: - CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty -#816 - Hardware name: Qualcomm (Flattened Device Tree) - unwind_backtrace - show_stack - dump_stack - bad_page - free_pages_prepare - free_hot_cold_page - __free_pages - free_highmem_page - mem_init - start_kernel - Disabling lock debugging due to kernel taint - [...] -:040000 040000 2de013c372345fd471cd58f0553c9b38b0ef1cc4 -0a8156f848733dfa21e16c196dfb6c0a76290709 M mm - -This fix for ARM does not account ARCH_PFN_OFFSET for mem_map as later used by -page_to_pfn anymore. - -The following output was generated with two hacked in printk statements: - -printk("before %p vs. %p or %p\n", mem_map, mem_map - offset, mem_map - -(pgdat->node_start_pfn - ARCH_PFN_OFFSET)); - if (page_to_pfn(mem_map) != pgdat->node_start_pfn) - mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); -printk("after %p\n", mem_map); - -Output: - -[ 0.000000] before 8861b280 vs. 8861b280 or 8851b280 -[ 0.000000] after 8851b280 - -As seen in the first line mem_map with subtraction of offset does not equal the -mem_map after subtraction of ARCH_PFN_OFFSET. - -After adding the offset of ARCH_PFN_OFFSET as well to mem_map as the -previously calculated offset is zero for the named platform it is able to boot -4.4 and 4.9-rc7 again. - -Signed-off-by: Tobias Wolf ---- - ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -7910,7 +7910,7 @@ static void __init alloc_node_mem_map(st - if (pgdat == NODE_DATA(0)) { - mem_map = NODE_DATA(0)->node_mem_map; - if (page_to_pfn(mem_map) != pgdat->node_start_pfn) -- mem_map -= offset; -+ mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); - } - #endif - } diff --git a/target/linux/generic/pending-6.1/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch b/target/linux/generic/pending-6.1/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch deleted file mode 100644 index 8f40ae3ba2400d..00000000000000 --- a/target/linux/generic/pending-6.1/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch +++ /dev/null @@ -1,81 +0,0 @@ -From: Felix Fietkau -Subject: jffs2: use .rename2 and add RENAME_WHITEOUT support - -It is required for renames on overlayfs - -Signed-off-by: Felix Fietkau ---- - ---- a/fs/jffs2/dir.c -+++ b/fs/jffs2/dir.c -@@ -614,8 +614,8 @@ static int jffs2_rmdir (struct inode *di - return ret; - } - --static int jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i, -- struct dentry *dentry, umode_t mode, dev_t rdev) -+static int __jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i, -+ struct dentry *dentry, umode_t mode, dev_t rdev, bool whiteout) - { - struct jffs2_inode_info *f, *dir_f; - struct jffs2_sb_info *c; -@@ -754,7 +754,11 @@ static int jffs2_mknod (struct user_name - mutex_unlock(&dir_f->sem); - jffs2_complete_reservation(c); - -- d_instantiate_new(dentry, inode); -+ if (!whiteout) -+ d_instantiate_new(dentry, inode); -+ else -+ unlock_new_inode(inode); -+ - return 0; - - fail: -@@ -762,6 +766,19 @@ static int jffs2_mknod (struct user_name - return ret; - } - -+static int jffs2_mknod (struct user_namespace *mnt_userns, struct inode *dir_i, -+ struct dentry *dentry, umode_t mode, dev_t rdev) -+{ -+ return __jffs2_mknod(mnt_userns, dir_i, dentry, mode, rdev, false); -+} -+ -+static int jffs2_whiteout (struct user_namespace *mnt_userns, struct inode *old_dir, -+ struct dentry *old_dentry) -+{ -+ return __jffs2_mknod(mnt_userns, old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, -+ WHITEOUT_DEV, true); -+} -+ - static int jffs2_rename (struct user_namespace *mnt_userns, - struct inode *old_dir_i, struct dentry *old_dentry, - struct inode *new_dir_i, struct dentry *new_dentry, -@@ -773,7 +790,7 @@ static int jffs2_rename (struct user_nam - uint8_t type; - uint32_t now; - -- if (flags & ~RENAME_NOREPLACE) -+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) - return -EINVAL; - - /* The VFS will check for us and prevent trying to rename a -@@ -839,9 +856,14 @@ static int jffs2_rename (struct user_nam - if (d_is_dir(old_dentry) && !victim_f) - inc_nlink(new_dir_i); - -- /* Unlink the original */ -- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -- old_dentry->d_name.name, old_dentry->d_name.len, NULL, now); -+ if (flags & RENAME_WHITEOUT) -+ /* Replace with whiteout */ -+ ret = jffs2_whiteout(mnt_userns, old_dir_i, old_dentry); -+ else -+ /* Unlink the original */ -+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -+ old_dentry->d_name.name, -+ old_dentry->d_name.len, NULL, now); - - /* We don't touch inode->i_nlink */ - diff --git a/target/linux/generic/pending-6.1/141-jffs2-add-RENAME_EXCHANGE-support.patch b/target/linux/generic/pending-6.1/141-jffs2-add-RENAME_EXCHANGE-support.patch deleted file mode 100644 index f58fc791d28157..00000000000000 --- a/target/linux/generic/pending-6.1/141-jffs2-add-RENAME_EXCHANGE-support.patch +++ /dev/null @@ -1,73 +0,0 @@ -From: Felix Fietkau -Subject: jffs2: add RENAME_EXCHANGE support - -Signed-off-by: Felix Fietkau ---- - ---- a/fs/jffs2/dir.c -+++ b/fs/jffs2/dir.c -@@ -787,18 +787,31 @@ static int jffs2_rename (struct user_nam - int ret; - struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); - struct jffs2_inode_info *victim_f = NULL; -+ struct inode *fst_inode = d_inode(old_dentry); -+ struct inode *snd_inode = d_inode(new_dentry); - uint8_t type; - uint32_t now; - -- if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) -+ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT|RENAME_EXCHANGE)) - return -EINVAL; - -+ if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) { -+ if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) { -+ inc_nlink(new_dir_i); -+ drop_nlink(old_dir_i); -+ } -+ else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) { -+ drop_nlink(new_dir_i); -+ inc_nlink(old_dir_i); -+ } -+ } -+ - /* The VFS will check for us and prevent trying to rename a - * file over a directory and vice versa, but if it's a directory, - * the VFS can't check whether the victim is empty. The filesystem - * needs to do that for itself. - */ -- if (d_really_is_positive(new_dentry)) { -+ if (d_really_is_positive(new_dentry) && !(flags & RENAME_EXCHANGE)) { - victim_f = JFFS2_INODE_INFO(d_inode(new_dentry)); - if (d_is_dir(new_dentry)) { - struct jffs2_full_dirent *fd; -@@ -833,7 +846,7 @@ static int jffs2_rename (struct user_nam - if (ret) - return ret; - -- if (victim_f) { -+ if (victim_f && !(flags & RENAME_EXCHANGE)) { - /* There was a victim. Kill it off nicely */ - if (d_is_dir(new_dentry)) - clear_nlink(d_inode(new_dentry)); -@@ -859,6 +872,12 @@ static int jffs2_rename (struct user_nam - if (flags & RENAME_WHITEOUT) - /* Replace with whiteout */ - ret = jffs2_whiteout(mnt_userns, old_dir_i, old_dentry); -+ else if (flags & RENAME_EXCHANGE) -+ /* Replace the original */ -+ ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i), -+ d_inode(new_dentry)->i_ino, type, -+ old_dentry->d_name.name, old_dentry->d_name.len, -+ now); - else - /* Unlink the original */ - ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), -@@ -890,7 +909,7 @@ static int jffs2_rename (struct user_nam - return ret; - } - -- if (d_is_dir(old_dentry)) -+ if (d_is_dir(old_dentry) && !(flags & RENAME_EXCHANGE)) - drop_nlink(old_dir_i); - - new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); diff --git a/target/linux/generic/pending-6.1/142-jffs2-add-splice-ops.patch b/target/linux/generic/pending-6.1/142-jffs2-add-splice-ops.patch deleted file mode 100644 index de847a1f5cd1fc..00000000000000 --- a/target/linux/generic/pending-6.1/142-jffs2-add-splice-ops.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Felix Fietkau -Subject: jffs2: add splice ops - -Add splice_read using generic_file_splice_read. -Add splice_write using iter_file_splice_write - -Signed-off-by: Felix Fietkau ---- - ---- a/fs/jffs2/file.c -+++ b/fs/jffs2/file.c -@@ -53,6 +53,8 @@ const struct file_operations jffs2_file_ - .open = generic_file_open, - .read_iter = generic_file_read_iter, - .write_iter = generic_file_write_iter, -+ .splice_read = generic_file_splice_read, -+ .splice_write = iter_file_splice_write, - .unlocked_ioctl=jffs2_ioctl, - .mmap = generic_file_readonly_mmap, - .fsync = jffs2_fsync, diff --git a/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch deleted file mode 100644 index ac4a3138a55030..00000000000000 --- a/target/linux/generic/pending-6.1/150-bridge_allow_receiption_on_disabled_port.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Stephen Hemminger -Subject: bridge: allow receiption on disabled port - -When an ethernet device is enslaved to a bridge, and the bridge STP -detects loss of carrier (or operational state down), then normally -packet receiption is blocked. - -This breaks control applications like WPA which maybe expecting to -receive packets to negotiate to bring link up. The bridge needs to -block forwarding packets from these disabled ports, but there is no -hard requirement to not allow local packet delivery. - -Signed-off-by: Stephen Hemminger -Signed-off-by: Felix Fietkau - ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -227,6 +227,9 @@ static void __br_handle_local_finish(str - /* note: already called with rcu_read_lock */ - static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) - { -+ struct net_bridge_port *p = br_port_get_rcu(skb->dev); -+ -+ if (p->state != BR_STATE_DISABLED) - __br_handle_local_finish(skb); - - /* return 1 to signal the okfn() was called so it's ok to use the skb */ -@@ -397,6 +400,17 @@ forward: - goto defer_stp_filtering; - - switch (p->state) { -+ case BR_STATE_DISABLED: -+ if (ether_addr_equal(p->br->dev->dev_addr, dest)) -+ skb->pkt_type = PACKET_HOST; -+ -+ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, -+ dev_net(skb->dev), NULL, skb, skb->dev, NULL, -+ br_handle_local_finish) == 1) { -+ return RX_HANDLER_PASS; -+ } -+ break; -+ - case BR_STATE_FORWARDING: - case BR_STATE_LEARNING: - defer_stp_filtering: diff --git a/target/linux/generic/pending-6.1/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch b/target/linux/generic/pending-6.1/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch deleted file mode 100644 index f420d210c27cad..00000000000000 --- a/target/linux/generic/pending-6.1/151-net-bridge-do-not-send-arp-replies-if-src-and-target.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Felix Fietkau -Date: Thu, 4 Jan 2024 15:21:21 +0100 -Subject: [PATCH] net: bridge: do not send arp replies if src and target hw - addr is the same - -There are broken devices in the wild that handle duplicate IP address -detection by sending out ARP requests for the IP that they received from a -DHCP server and refuse the address if they get a reply. -When proxyarp is enabled, they would go into a loop of requesting an address -and then NAKing it again. - -Link: https://github.com/openwrt/openwrt/issues/14309 -Signed-off-by: Felix Fietkau ---- - ---- a/net/bridge/br_arp_nd_proxy.c -+++ b/net/bridge/br_arp_nd_proxy.c -@@ -204,7 +204,10 @@ void br_do_proxy_suppress_arp(struct sk_ - if ((p && (p->flags & BR_PROXYARP)) || - (f->dst && (f->dst->flags & (BR_PROXYARP_WIFI | - BR_NEIGH_SUPPRESS)))) { -- if (!vid) -+ replied = true; -+ if (!memcmp(n->ha, sha, dev->addr_len)) -+ replied = false; -+ else if (!vid) - br_arp_send(br, p, skb->dev, sip, tip, - sha, n->ha, sha, 0, 0); - else -@@ -212,7 +215,6 @@ void br_do_proxy_suppress_arp(struct sk_ - sha, n->ha, sha, - skb->vlan_proto, - skb_vlan_tag_get(skb)); -- replied = true; - } - - /* If we have replied or as long as we know the diff --git a/target/linux/generic/pending-6.1/190-rtc-rs5c372-support_alarms_up_to_1_week.patch b/target/linux/generic/pending-6.1/190-rtc-rs5c372-support_alarms_up_to_1_week.patch deleted file mode 100644 index 2f5c2228c7a4e2..00000000000000 --- a/target/linux/generic/pending-6.1/190-rtc-rs5c372-support_alarms_up_to_1_week.patch +++ /dev/null @@ -1,94 +0,0 @@ -From: Daniel González Cabanelas -Subject: [PATCH 1/2] rtc: rs5c372: support alarms up to 1 week - -The Ricoh R2221x, R2223x, RS5C372, RV5C387A chips can handle 1 week -alarms. - -Read the "wday" alarm register and convert it to a date to support up 1 -week in our driver. - -Signed-off-by: Daniel González Cabanelas ---- - drivers/rtc/rtc-rs5c372.c | 48 ++++++++++++++++++++++++++++++++++----- - 1 file changed, 42 insertions(+), 6 deletions(-) - ---- a/drivers/rtc/rtc-rs5c372.c -+++ b/drivers/rtc/rtc-rs5c372.c -@@ -399,7 +399,9 @@ static int rs5c_read_alarm(struct device - { - struct i2c_client *client = to_i2c_client(dev); - struct rs5c372 *rs5c = i2c_get_clientdata(client); -- int status; -+ int status, wday_offs; -+ struct rtc_time rtc; -+ unsigned long alarm_secs; - - status = rs5c_get_regs(rs5c); - if (status < 0) -@@ -409,6 +411,30 @@ static int rs5c_read_alarm(struct device - t->time.tm_sec = 0; - t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); - t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); -+ t->time.tm_wday = ffs(rs5c->regs[RS5C_REG_ALARM_A_WDAY] & 0x7f) - 1; -+ -+ /* determine the day, month and year based on alarm wday, taking as a -+ * reference the current time from the rtc -+ */ -+ status = rs5c372_rtc_read_time(dev, &rtc); -+ if (status < 0) -+ return status; -+ -+ wday_offs = t->time.tm_wday - rtc.tm_wday; -+ alarm_secs = mktime64(rtc.tm_year + 1900, -+ rtc.tm_mon + 1, -+ rtc.tm_mday + wday_offs, -+ t->time.tm_hour, -+ t->time.tm_min, -+ t->time.tm_sec); -+ -+ if (wday_offs < 0 || (wday_offs == 0 && -+ (t->time.tm_hour < rtc.tm_hour || -+ (t->time.tm_hour == rtc.tm_hour && -+ t->time.tm_min <= rtc.tm_min)))) -+ alarm_secs += 7 * 86400; -+ -+ rtc_time64_to_tm(alarm_secs, &t->time); - - /* ... and status */ - t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); -@@ -423,12 +449,20 @@ static int rs5c_set_alarm(struct device - struct rs5c372 *rs5c = i2c_get_clientdata(client); - int status, addr, i; - unsigned char buf[3]; -+ struct rtc_time rtc_tm; -+ unsigned long rtc_secs, alarm_secs; - -- /* only handle up to 24 hours in the future, like RTC_ALM_SET */ -- if (t->time.tm_mday != -1 -- || t->time.tm_mon != -1 -- || t->time.tm_year != -1) -+ /* chip only can handle alarms up to one week in the future*/ -+ status = rs5c372_rtc_read_time(dev, &rtc_tm); -+ if (status) -+ return status; -+ rtc_secs = rtc_tm_to_time64(&rtc_tm); -+ alarm_secs = rtc_tm_to_time64(&t->time); -+ if (alarm_secs >= rtc_secs + 7 * 86400) { -+ dev_err(dev, "%s: alarm maximum is one week in the future (%d)\n", -+ __func__, status); - return -EINVAL; -+ } - - /* REVISIT: round up tm_sec */ - -@@ -449,7 +483,9 @@ static int rs5c_set_alarm(struct device - /* set alarm */ - buf[0] = bin2bcd(t->time.tm_min); - buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour); -- buf[2] = 0x7f; /* any/all days */ -+ /* each bit is the day of the week, 0x7f means all days */ -+ buf[2] = (t->time.tm_wday >= 0 && t->time.tm_wday < 7) ? -+ BIT(t->time.tm_wday) : 0x7f; - - for (i = 0; i < sizeof(buf); i++) { - addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i); diff --git a/target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch b/target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch deleted file mode 100644 index a9a5cdf8ba2421..00000000000000 --- a/target/linux/generic/pending-6.1/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch +++ /dev/null @@ -1,71 +0,0 @@ -From: Daniel González Cabanelas -Subject: [PATCH 2/2] rtc: rs5c372: let the alarm to be used as wakeup source - -Currently there is no use for the interrupts on the rs5c372 RTC and the -wakealarm isn't enabled. There are some devices like NASes which use this -RTC to wake up from the power off state when the INTR pin is activated by -the alarm clock. - -Enable the alarm and let to be used as a wakeup source. - -Tested on a Buffalo LS421DE NAS. - -Signed-off-by: Daniel González Cabanelas ---- - drivers/rtc/rtc-rs5c372.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/drivers/rtc/rtc-rs5c372.c -+++ b/drivers/rtc/rtc-rs5c372.c -@@ -833,6 +833,7 @@ static int rs5c372_probe(struct i2c_clie - int err = 0; - int smbus_mode = 0; - struct rs5c372 *rs5c372; -+ bool rs5c372_can_wakeup_device = false; - - dev_dbg(&client->dev, "%s\n", __func__); - -@@ -868,6 +869,12 @@ static int rs5c372_probe(struct i2c_clie - else - rs5c372->type = id->driver_data; - -+#ifdef CONFIG_OF -+ if(of_property_read_bool(client->dev.of_node, -+ "wakeup-source")) -+ rs5c372_can_wakeup_device = true; -+#endif -+ - /* we read registers 0x0f then 0x00-0x0f; skip the first one */ - rs5c372->regs = &rs5c372->buf[1]; - rs5c372->smbus = smbus_mode; -@@ -901,6 +908,8 @@ static int rs5c372_probe(struct i2c_clie - goto exit; - } - -+ rs5c372->has_irq = 1; -+ - /* if the oscillator lost power and no other software (like - * the bootloader) set it up, do it here. - * -@@ -927,6 +936,10 @@ static int rs5c372_probe(struct i2c_clie - ); - - /* REVISIT use client->irq to register alarm irq ... */ -+ if (rs5c372_can_wakeup_device) { -+ device_init_wakeup(&client->dev, true); -+ } -+ - rs5c372->rtc = devm_rtc_device_register(&client->dev, - rs5c372_driver.driver.name, - &rs5c372_rtc_ops, THIS_MODULE); -@@ -940,6 +953,10 @@ static int rs5c372_probe(struct i2c_clie - if (err) - goto exit; - -+ /* the rs5c372 alarm only supports a minute accuracy */ -+ set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rs5c372->rtc->features); -+ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rs5c372->rtc->features); -+ - return 0; - - exit: diff --git a/target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch deleted file mode 100644 index 78ed262b786c6a..00000000000000 --- a/target/linux/generic/pending-6.1/203-kallsyms_uncompressed.patch +++ /dev/null @@ -1,118 +0,0 @@ -From: Felix Fietkau -Subject: kernel: add a config option for keeping the kallsyms table uncompressed, saving ~9kb kernel size after lzma on ar71xx - -[john@phrozen.org: added to my upstream queue 30.12.2016] -lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed -Signed-off-by: Felix Fietkau ---- - init/Kconfig | 11 +++++++++++ - kernel/kallsyms.c | 8 ++++++++ - scripts/kallsyms.c | 12 ++++++++++++ - scripts/link-vmlinux.sh | 4 ++++ - 4 files changed, 35 insertions(+) - ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1491,6 +1491,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW - the unaligned access emulation. - see arch/parisc/kernel/unaligned.c for reference - -+config KALLSYMS_UNCOMPRESSED -+ bool "Keep kallsyms uncompressed" -+ depends on KALLSYMS -+ help -+ Normally kallsyms contains compressed symbols (using a token table), -+ reducing the uncompressed kernel image size. Keeping the symbol table -+ uncompressed significantly improves the size of this part in compressed -+ kernel images. -+ -+ Say N unless you need compressed kernel images to be small. -+ - config HAVE_PCSPKR_PLATFORM - bool - ---- a/kernel/kallsyms.c -+++ b/kernel/kallsyms.c -@@ -69,6 +69,11 @@ static unsigned int kallsyms_expand_symb - * For every byte on the compressed symbol data, copy the table - * entry for that byte. - */ -+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED -+ memcpy(result, data + 1, len - 1); -+ result += len - 1; -+ len = 0; -+#endif - while (len) { - tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; - data++; -@@ -101,6 +106,9 @@ tail: - */ - static char kallsyms_get_symbol_type(unsigned int off) - { -+#ifdef CONFIG_KALLSYMS_UNCOMPRESSED -+ return kallsyms_names[off + 1]; -+#endif - /* - * Get just the first code, look it up in the token table, - * and return the first char from this token. ---- a/scripts/kallsyms.c -+++ b/scripts/kallsyms.c -@@ -77,6 +77,7 @@ static struct addr_range percpu_range = - static struct sym_entry **table; - static unsigned int table_size, table_cnt; - static int all_symbols; -+static int uncompressed; - static int absolute_percpu; - static int base_relative; - static int lto_clang; -@@ -608,6 +609,9 @@ static void write_src(void) - (unsigned char)(table[i]->seq >> 0)); - printf("\n"); - -+ if (uncompressed) -+ return; -+ - output_label("kallsyms_token_table"); - off = 0; - for (i = 0; i < 256; i++) { -@@ -659,6 +663,9 @@ static unsigned char *find_token(unsigne - { - int i; - -+ if (uncompressed) -+ return NULL; -+ - for (i = 0; i < len - 1; i++) { - if (str[i] == token[0] && str[i+1] == token[1]) - return &str[i]; -@@ -731,6 +738,9 @@ static void optimize_result(void) - { - int i, best; - -+ if (uncompressed) -+ return; -+ - /* using the '\0' symbol last allows compress_symbols to use standard - * fast string functions */ - for (i = 255; i >= 0; i--) { -@@ -892,6 +902,7 @@ int main(int argc, char **argv) - {"absolute-percpu", no_argument, &absolute_percpu, 1}, - {"base-relative", no_argument, &base_relative, 1}, - {"lto-clang", no_argument, <o_clang, 1}, -+ {"uncompressed", no_argument, &uncompressed, 1}, - {}, - }; - ---- a/scripts/link-vmlinux.sh -+++ b/scripts/link-vmlinux.sh -@@ -165,6 +165,10 @@ kallsyms() - kallsymopt="${kallsymopt} --lto-clang" - fi - -+ if is_enabled CONFIG_KALLSYMS_UNCOMPRESSED; then -+ kallsymopt="${kallsymopt} --uncompressed" -+ fi -+ - info KSYMS ${2} - scripts/kallsyms ${kallsymopt} ${1} > ${2} - } diff --git a/target/linux/generic/pending-6.1/205-backtrace_module_info.patch b/target/linux/generic/pending-6.1/205-backtrace_module_info.patch deleted file mode 100644 index 27a1347981960e..00000000000000 --- a/target/linux/generic/pending-6.1/205-backtrace_module_info.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Felix Fietkau -Subject: kernel: when KALLSYMS is disabled, print module address + size for matching backtrace entries - -[john@phrozen.org: felix will add this to his upstream queue] - -lede-commit 53827cdc824556cda910b23ce5030c363b8f1461 -Signed-off-by: Felix Fietkau ---- - lib/vsprintf.c | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - ---- a/lib/vsprintf.c -+++ b/lib/vsprintf.c -@@ -985,8 +985,10 @@ char *symbol_string(char *buf, char *end - struct printf_spec spec, const char *fmt) - { - unsigned long value; --#ifdef CONFIG_KALLSYMS - char sym[KSYM_SYMBOL_LEN]; -+#ifndef CONFIG_KALLSYMS -+ struct module *mod; -+ int len; - #endif - - if (fmt[1] == 'R') -@@ -1007,8 +1009,14 @@ char *symbol_string(char *buf, char *end - - return string_nocheck(buf, end, sym, spec); - #else -- return special_hex_number(buf, end, value, sizeof(void *)); -+ len = snprintf(sym, sizeof(sym), "0x%lx", value); -+ mod = __module_address(value); -+ if (mod) -+ snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]", -+ mod->name, mod->core_layout.base, -+ mod->core_layout.size); - #endif -+ return string(buf, end, sym, spec); - } - - static const struct printf_spec default_str_spec = { diff --git a/target/linux/generic/pending-6.1/240-remove-unsane-filenames-from-deps_initramfs-list.patch b/target/linux/generic/pending-6.1/240-remove-unsane-filenames-from-deps_initramfs-list.patch deleted file mode 100644 index 9e78284ecf707b..00000000000000 --- a/target/linux/generic/pending-6.1/240-remove-unsane-filenames-from-deps_initramfs-list.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Gabor Juhos -Subject: usr: sanitize deps_initramfs list - -If any filename in the intramfs dependency -list contains a colon, that causes a kernel -build error like this: - -/devel/openwrt/build_dir/linux-ar71xx_generic/linux-3.6.6/usr/Makefile:58: *** multiple target patterns. Stop. -make[5]: *** [usr] Error 2 - -Fix it by removing such filenames from the -deps_initramfs list. - -Signed-off-by: Gabor Juhos -Signed-off-by: Felix Fietkau ---- - usr/Makefile | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/usr/Makefile -+++ b/usr/Makefile -@@ -56,6 +56,8 @@ hostprogs := gen_init_cpio - # The dependency list is generated by gen_initramfs.sh -l - -include $(obj)/.initramfs_data.cpio.d - -+deps_initramfs := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v))) -+ - # do not try to update files included in initramfs - $(deps_initramfs): ; - diff --git a/target/linux/generic/pending-6.1/261-enable_wilink_platform_without_drivers.patch b/target/linux/generic/pending-6.1/261-enable_wilink_platform_without_drivers.patch deleted file mode 100644 index cd31f9d9342925..00000000000000 --- a/target/linux/generic/pending-6.1/261-enable_wilink_platform_without_drivers.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Imre Kaloz -Subject: [PATCH] hack: net: wireless: make the wl12xx glue code available with - compat-wireless, too - -Signed-off-by: Imre Kaloz ---- - drivers/net/wireless/ti/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/ti/Kconfig -+++ b/drivers/net/wireless/ti/Kconfig -@@ -20,7 +20,7 @@ source "drivers/net/wireless/ti/wlcore/K - - config WILINK_PLATFORM_DATA - bool "TI WiLink platform data" -- depends on WLCORE_SDIO || WL1251_SDIO -+ depends on WLCORE_SDIO || WL1251_SDIO || ARCH_OMAP2PLUS - default y - help - Small platform data bit needed to pass data to the sdio modules. diff --git a/target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch b/target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch deleted file mode 100644 index 997e6142a70e62..00000000000000 --- a/target/linux/generic/pending-6.1/270-platform-mikrotik-build-bits.patch +++ /dev/null @@ -1,31 +0,0 @@ -From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= -Date: Sat, 28 Mar 2020 12:11:50 +0100 -Subject: [PATCH] generic: platform/mikrotik build bits (5.4) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds platform/mikrotik kernel build bits - -Signed-off-by: Thibaut VARÈNE ---- - drivers/platform/Kconfig | 2 ++ - drivers/platform/Makefile | 1 + - 2 files changed, 3 insertions(+) - ---- a/drivers/platform/Kconfig -+++ b/drivers/platform/Kconfig -@@ -16,3 +16,5 @@ source "drivers/platform/olpc/Kconfig" - source "drivers/platform/surface/Kconfig" - - source "drivers/platform/x86/Kconfig" -+ -+source "drivers/platform/mikrotik/Kconfig" ---- a/drivers/platform/Makefile -+++ b/drivers/platform/Makefile -@@ -11,3 +11,4 @@ obj-$(CONFIG_OLPC_EC) += olpc/ - obj-$(CONFIG_GOLDFISH) += goldfish/ - obj-$(CONFIG_CHROME_PLATFORMS) += chrome/ - obj-$(CONFIG_SURFACE_PLATFORMS) += surface/ -+obj-$(CONFIG_MIKROTIK) += mikrotik/ diff --git a/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch b/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch deleted file mode 100644 index d222ec060e8b7d..00000000000000 --- a/target/linux/generic/pending-6.1/300-mips_expose_boot_raw.patch +++ /dev/null @@ -1,40 +0,0 @@ -From: Mark Miller -Subject: mips: expose CONFIG_BOOT_RAW - -This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on -certain Broadcom chipsets running CFE in order to load the kernel. - -Signed-off-by: Mark Miller -Acked-by: Rob Landley ---- ---- a/arch/mips/Kconfig -+++ b/arch/mips/Kconfig -@@ -1035,9 +1035,6 @@ config FW_ARC - config ARCH_MAY_HAVE_PC_FDC - bool - --config BOOT_RAW -- bool -- - config CEVT_BCM1480 - bool - -@@ -3093,6 +3090,18 @@ choice - bool "Extend builtin kernel arguments with bootloader arguments" - endchoice - -+config BOOT_RAW -+ bool "Enable the kernel to be executed from the load address" -+ default n -+ help -+ Allow the kernel to be executed from the load address for -+ bootloaders which cannot read the ELF format. This places -+ a jump to start_kernel at the load address. -+ -+ If unsure, say N. -+ -+ -+ - endmenu - - config LOCKDEP_SUPPORT diff --git a/target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch b/target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch deleted file mode 100644 index bd56adad3a057e..00000000000000 --- a/target/linux/generic/pending-6.1/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch +++ /dev/null @@ -1,71 +0,0 @@ -From e6e6ef4275978823ec3a84133fc91f4ffbef5c84 Mon Sep 17 00:00:00 2001 -From: Paul Burton -Date: Mon, 22 Feb 2016 18:09:44 +0000 -Subject: [PATCH] MIPS: Add barriers between dcache & icache flushes - -Index-based cache operations may be arbitrarily reordered by out of -order CPUs. Thus code which writes back the dcache & then invalidates -the icache using indexed cache ops must include a barrier between -operating on the 2 caches in order to prevent the scenario in which: - - - icache invalidation occurs. - - - icache fetch occurs, due to speculation. - - - dcache writeback occurs. - -If the above were allowed to happen then the icache would contain stale -data. Forcing the dcache writeback to complete before the icache -invalidation avoids this. - -Signed-off-by: Paul Burton -Cc: James Hogan ---- - arch/mips/mm/c-r4k.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - ---- a/arch/mips/mm/c-r4k.c -+++ b/arch/mips/mm/c-r4k.c -@@ -514,6 +514,7 @@ static inline void local_r4k___flush_cac - - default: - r4k_blast_dcache(); -+ mb(); /* cache instructions may be reordered */ - r4k_blast_icache(); - break; - } -@@ -594,8 +595,10 @@ static inline void local_r4k_flush_cache - if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) - r4k_blast_dcache(); - /* If executable, blast stale lines from icache */ -- if (exec) -+ if (exec) { -+ mb(); /* cache instructions may be reordered */ - r4k_blast_icache(); -+ } - } - - static void r4k_flush_cache_range(struct vm_area_struct *vma, -@@ -696,8 +699,13 @@ static inline void local_r4k_flush_cache - if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) { - vaddr ? r4k_blast_dcache_page(addr) : - r4k_blast_dcache_user_page(addr); -- if (exec && !cpu_icache_snoops_remote_store) -+ if (exec) -+ mb(); /* cache instructions may be reordered */ -+ -+ if (exec && !cpu_icache_snoops_remote_store) { - r4k_blast_scache_page(addr); -+ mb(); /* cache instructions may be reordered */ -+ } - } - if (exec) { - if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { -@@ -764,6 +772,7 @@ static inline void __local_r4k_flush_ica - else - blast_dcache_range(start, end); - } -+ mb(); /* cache instructions may be reordered */ - } - - if (type == R4K_INDEX || diff --git a/target/linux/generic/pending-6.1/302-mips_no_branch_likely.patch b/target/linux/generic/pending-6.1/302-mips_no_branch_likely.patch deleted file mode 100644 index 542fba651f29db..00000000000000 --- a/target/linux/generic/pending-6.1/302-mips_no_branch_likely.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Subject: mips: use -mno-branch-likely for kernel and userspace - -saves ~11k kernel size after lzma and ~12k squashfs size in the - -lede-commit: 41a039f46450ffae9483d6216422098669da2900 -Signed-off-by: Felix Fietkau ---- - arch/mips/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -94,7 +94,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin - # machines may also. Since BFD is incredibly buggy with respect to - # crossformat linking we rely on the elf2ecoff tool for format conversion. - # --cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -+cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely - cflags-y += -msoft-float - LDFLAGS_vmlinux += -G 0 -static -n -nostdlib - KBUILD_AFLAGS_MODULE += -mlong-calls diff --git a/target/linux/generic/pending-6.1/305-mips_module_reloc.patch b/target/linux/generic/pending-6.1/305-mips_module_reloc.patch deleted file mode 100644 index 5de9019677e1ca..00000000000000 --- a/target/linux/generic/pending-6.1/305-mips_module_reloc.patch +++ /dev/null @@ -1,370 +0,0 @@ -From: Felix Fietkau -Subject: mips: replace -mlong-calls with -mno-long-calls to make function calls faster in kernel modules to achieve this, try to - -lede-commit: 3b3d64743ba2a874df9d70cd19e242205b0a788c -Signed-off-by: Felix Fietkau ---- - arch/mips/Makefile | 5 + - arch/mips/include/asm/module.h | 5 + - arch/mips/kernel/module.c | 279 ++++++++++++++++++++++++++++++++++++++++- - 3 files changed, 284 insertions(+), 5 deletions(-) - ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -97,8 +97,18 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin - cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely - cflags-y += -msoft-float - LDFLAGS_vmlinux += -G 0 -static -n -nostdlib -+ifdef CONFIG_64BIT - KBUILD_AFLAGS_MODULE += -mlong-calls - KBUILD_CFLAGS_MODULE += -mlong-calls -+else -+ ifdef CONFIG_DYNAMIC_FTRACE -+ KBUILD_AFLAGS_MODULE += -mlong-calls -+ KBUILD_CFLAGS_MODULE += -mlong-calls -+ else -+ KBUILD_AFLAGS_MODULE += -mno-long-calls -+ KBUILD_CFLAGS_MODULE += -mno-long-calls -+ endif -+endif - - ifeq ($(CONFIG_RELOCATABLE),y) - LDFLAGS_vmlinux += --emit-relocs ---- a/arch/mips/include/asm/module.h -+++ b/arch/mips/include/asm/module.h -@@ -12,6 +12,11 @@ struct mod_arch_specific { - const struct exception_table_entry *dbe_start; - const struct exception_table_entry *dbe_end; - struct mips_hi16 *r_mips_hi16_list; -+ -+ void *phys_plt_tbl; -+ void *virt_plt_tbl; -+ unsigned int phys_plt_offset; -+ unsigned int virt_plt_offset; - }; - - typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ ---- a/arch/mips/kernel/module.c -+++ b/arch/mips/kernel/module.c -@@ -32,23 +32,261 @@ struct mips_hi16 { - static LIST_HEAD(dbe_list); - static DEFINE_SPINLOCK(dbe_lock); - --#ifdef MODULE_START -+/* -+ * Get the potential max trampolines size required of the init and -+ * non-init sections. Only used if we cannot find enough contiguous -+ * physically mapped memory to put the module into. -+ */ -+static unsigned int -+get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, -+ const char *secstrings, unsigned int symindex, bool is_init) -+{ -+ unsigned long ret = 0; -+ unsigned int i, j; -+ Elf_Sym *syms; -+ -+ /* Everything marked ALLOC (this includes the exported symbols) */ -+ for (i = 1; i < hdr->e_shnum; ++i) { -+ unsigned int info = sechdrs[i].sh_info; -+ -+ if (sechdrs[i].sh_type != SHT_REL -+ && sechdrs[i].sh_type != SHT_RELA) -+ continue; -+ -+ /* Not a valid relocation section? */ -+ if (info >= hdr->e_shnum) -+ continue; -+ -+ /* Don't bother with non-allocated sections */ -+ if (!(sechdrs[info].sh_flags & SHF_ALLOC)) -+ continue; -+ -+ /* If it's called *.init*, and we're not init, we're -+ not interested */ -+ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) -+ != is_init) -+ continue; -+ -+ syms = (Elf_Sym *) sechdrs[symindex].sh_addr; -+ if (sechdrs[i].sh_type == SHT_REL) { -+ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; -+ unsigned int size = sechdrs[i].sh_size / sizeof(*rel); -+ -+ for (j = 0; j < size; ++j) { -+ Elf_Sym *sym; -+ -+ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) -+ continue; -+ -+ sym = syms + ELF_MIPS_R_SYM(rel[j]); -+ if (!is_init && sym->st_shndx != SHN_UNDEF) -+ continue; -+ -+ ret += 4 * sizeof(int); -+ } -+ } else { -+ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; -+ unsigned int size = sechdrs[i].sh_size / sizeof(*rela); -+ -+ for (j = 0; j < size; ++j) { -+ Elf_Sym *sym; -+ -+ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) -+ continue; -+ -+ sym = syms + ELF_MIPS_R_SYM(rela[j]); -+ if (!is_init && sym->st_shndx != SHN_UNDEF) -+ continue; -+ -+ ret += 4 * sizeof(int); -+ } -+ } -+ } -+ -+ return ret; -+} -+ -+#ifndef MODULE_START -+static void *alloc_phys(unsigned long size) -+{ -+ unsigned order; -+ struct page *page; -+ struct page *p; -+ -+ size = PAGE_ALIGN(size); -+ order = get_order(size); -+ -+ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | -+ __GFP_THISNODE, order); -+ if (!page) -+ return NULL; -+ -+ split_page(page, order); -+ -+ /* mark all pages except for the last one */ -+ for (p = page; p + 1 < page + (size >> PAGE_SHIFT); ++p) -+ set_bit(PG_owner_priv_1, &p->flags); -+ -+ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) -+ __free_page(p); -+ -+ return page_address(page); -+} -+#endif -+ -+static void free_phys(void *ptr) -+{ -+ struct page *page; -+ bool free; -+ -+ page = virt_to_page(ptr); -+ do { -+ free = test_and_clear_bit(PG_owner_priv_1, &page->flags); -+ __free_page(page); -+ page++; -+ } while (free); -+} -+ -+ - void *module_alloc(unsigned long size) - { -+#ifdef MODULE_START - return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, - GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, - __builtin_return_address(0)); -+#else -+ void *ptr; -+ -+ if (size == 0) -+ return NULL; -+ -+ ptr = alloc_phys(size); -+ -+ /* If we failed to allocate physically contiguous memory, -+ * fall back to regular vmalloc. The module loader code will -+ * create jump tables to handle long jumps */ -+ if (!ptr) -+ return vmalloc(size); -+ -+ return ptr; -+#endif - } -+ -+static inline bool is_phys_addr(void *ptr) -+{ -+#ifdef CONFIG_64BIT -+ return (KSEGX((unsigned long)ptr) == CKSEG0); -+#else -+ return (KSEGX(ptr) == KSEG0); - #endif -+} -+ -+/* Free memory returned from module_alloc */ -+void module_memfree(void *module_region) -+{ -+ if (is_phys_addr(module_region)) -+ free_phys(module_region); -+ else -+ vfree(module_region); -+} -+ -+static void *__module_alloc(int size, bool phys) -+{ -+ void *ptr; -+ -+ if (phys) -+ ptr = kmalloc(size, GFP_KERNEL); -+ else -+ ptr = vmalloc(size); -+ return ptr; -+} -+ -+static void __module_free(void *ptr) -+{ -+ if (is_phys_addr(ptr)) -+ kfree(ptr); -+ else -+ vfree(ptr); -+} -+ -+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, -+ char *secstrings, struct module *mod) -+{ -+ unsigned int symindex = 0; -+ unsigned int core_size, init_size; -+ int i; -+ -+ mod->arch.phys_plt_offset = 0; -+ mod->arch.virt_plt_offset = 0; -+ mod->arch.phys_plt_tbl = NULL; -+ mod->arch.virt_plt_tbl = NULL; -+ -+ if (IS_ENABLED(CONFIG_64BIT)) -+ return 0; -+ -+ for (i = 1; i < hdr->e_shnum; i++) -+ if (sechdrs[i].sh_type == SHT_SYMTAB) -+ symindex = i; -+ -+ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); -+ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); -+ -+ if ((core_size + init_size) == 0) -+ return 0; -+ -+ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); -+ if (!mod->arch.phys_plt_tbl) -+ return -ENOMEM; -+ -+ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); -+ if (!mod->arch.virt_plt_tbl) { -+ __module_free(mod->arch.phys_plt_tbl); -+ mod->arch.phys_plt_tbl = NULL; -+ return -ENOMEM; -+ } -+ -+ return 0; -+} - - static void apply_r_mips_32(u32 *location, u32 base, Elf_Addr v) - { - *location = base + v; - } - -+static Elf_Addr add_plt_entry_to(unsigned *plt_offset, -+ void *start, Elf_Addr v) -+{ -+ unsigned *tramp = start + *plt_offset; -+ *plt_offset += 4 * sizeof(int); -+ -+ /* adjust carry for addiu */ -+ if (v & 0x00008000) -+ v += 0x10000; -+ -+ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */ -+ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */ -+ tramp[2] = 0x03200008; /* jr t9 */ -+ tramp[3] = 0x00000000; /* nop */ -+ -+ return (Elf_Addr) tramp; -+} -+ -+static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) -+{ -+ if (is_phys_addr(location)) -+ return add_plt_entry_to(&me->arch.phys_plt_offset, -+ me->arch.phys_plt_tbl, v); -+ else -+ return add_plt_entry_to(&me->arch.virt_plt_offset, -+ me->arch.virt_plt_tbl, v); -+ -+} -+ - static int apply_r_mips_26(struct module *me, u32 *location, u32 base, - Elf_Addr v) - { -+ u32 ofs = base & 0x03ffffff; -+ - if (v % 4) { - pr_err("module %s: dangerous R_MIPS_26 relocation\n", - me->name); -@@ -56,13 +294,17 @@ static int apply_r_mips_26(struct module - } - - if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { -- pr_err("module %s: relocation overflow\n", -- me->name); -- return -ENOEXEC; -+ v = add_plt_entry(me, location, v + (ofs << 2)); -+ if (!v) { -+ pr_err("module %s: relocation overflow\n", -+ me->name); -+ return -ENOEXEC; -+ } -+ ofs = 0; - } - - *location = (*location & ~0x03ffffff) | -- ((base + (v >> 2)) & 0x03ffffff); -+ ((ofs + (v >> 2)) & 0x03ffffff); - - return 0; - } -@@ -442,9 +684,36 @@ int module_finalize(const Elf_Ehdr *hdr, - list_add(&me->arch.dbe_list, &dbe_list); - spin_unlock_irq(&dbe_lock); - } -+ -+ /* Get rid of the fixup trampoline if we're running the module -+ * from physically mapped address space */ -+ if (me->arch.phys_plt_offset == 0) { -+ __module_free(me->arch.phys_plt_tbl); -+ me->arch.phys_plt_tbl = NULL; -+ } -+ if (me->arch.virt_plt_offset == 0) { -+ __module_free(me->arch.virt_plt_tbl); -+ me->arch.virt_plt_tbl = NULL; -+ } -+ - return 0; - } - -+void module_arch_freeing_init(struct module *mod) -+{ -+ if (mod->state == MODULE_STATE_LIVE) -+ return; -+ -+ if (mod->arch.phys_plt_tbl) { -+ __module_free(mod->arch.phys_plt_tbl); -+ mod->arch.phys_plt_tbl = NULL; -+ } -+ if (mod->arch.virt_plt_tbl) { -+ __module_free(mod->arch.virt_plt_tbl); -+ mod->arch.virt_plt_tbl = NULL; -+ } -+} -+ - void module_arch_cleanup(struct module *mod) - { - spin_lock_irq(&dbe_lock); diff --git a/target/linux/generic/pending-6.1/308-mips32r2_tune.patch b/target/linux/generic/pending-6.1/308-mips32r2_tune.patch deleted file mode 100644 index db410a6bc06dc3..00000000000000 --- a/target/linux/generic/pending-6.1/308-mips32r2_tune.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Subject: kernel: add -mtune=34kc to MIPS CFLAGS when building for mips32r2 - -This provides a good tradeoff across at least 24Kc-74Kc, while also -producing smaller code. - -Signed-off-by: Felix Fietkau ---- - arch/mips/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -172,7 +172,7 @@ cflags-$(CONFIG_CPU_R4300) += -march=r43 - cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap - cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap - cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap --cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,--trap -+cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -mtune=34kc -Wa,--trap - cflags-$(CONFIG_CPU_MIPS32_R5) += -march=mips32r5 -Wa,--trap -modd-spreg - cflags-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,--trap -modd-spreg - cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap diff --git a/target/linux/generic/pending-6.1/310-arm_module_unresolved_weak_sym.patch b/target/linux/generic/pending-6.1/310-arm_module_unresolved_weak_sym.patch deleted file mode 100644 index 54cc9ba64767d8..00000000000000 --- a/target/linux/generic/pending-6.1/310-arm_module_unresolved_weak_sym.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Subject: fix errors in unresolved weak symbols on arm - -lede-commit: 570699d4838a907c3ef9f2819bf19eb72997b32f -Signed-off-by: Felix Fietkau ---- - arch/arm/kernel/module.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/arm/kernel/module.c -+++ b/arch/arm/kernel/module.c -@@ -146,6 +146,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons - return -ENOEXEC; - } - -+ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) && -+ ELF_ST_BIND(sym->st_info) == STB_WEAK) -+ continue; -+ - loc = dstsec->sh_addr + rel->r_offset; - - switch (ELF32_R_TYPE(rel->r_info)) { diff --git a/target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch b/target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch deleted file mode 100644 index 3f553b28b34be7..00000000000000 --- a/target/linux/generic/pending-6.1/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch +++ /dev/null @@ -1,282 +0,0 @@ -From: Yousong Zhou -Subject: MIPS: kexec: Accept command line parameters from userspace. - -Signed-off-by: Yousong Zhou ---- - arch/mips/kernel/machine_kexec.c | 153 +++++++++++++++++++++++++++++++----- - arch/mips/kernel/machine_kexec.h | 20 +++++ - arch/mips/kernel/relocate_kernel.S | 21 +++-- - 3 files changed, 167 insertions(+), 27 deletions(-) - create mode 100644 arch/mips/kernel/machine_kexec.h - ---- a/arch/mips/kernel/machine_kexec.c -+++ b/arch/mips/kernel/machine_kexec.c -@@ -9,14 +9,11 @@ - #include - #include - -+#include - #include - #include -- --extern const unsigned char relocate_new_kernel[]; --extern const size_t relocate_new_kernel_size; -- --extern unsigned long kexec_start_address; --extern unsigned long kexec_indirection_page; -+#include -+#include "machine_kexec.h" - - static unsigned long reboot_code_buffer; - -@@ -30,6 +27,101 @@ void (*_crash_smp_send_stop)(void) = NUL - void (*_machine_kexec_shutdown)(void) = NULL; - void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL; - -+static void machine_kexec_print_args(void) -+{ -+ unsigned long argc = (int)kexec_args[0]; -+ int i; -+ -+ pr_info("kexec_args[0] (argc): %lu\n", argc); -+ pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]); -+ pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]); -+ pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]); -+ -+ for (i = 0; i < argc; i++) { -+ pr_info("kexec_argv[%d] = %p, %s\n", -+ i, kexec_argv[i], kexec_argv[i]); -+ } -+} -+ -+static void machine_kexec_init_argv(struct kimage *image) -+{ -+ void __user *buf = NULL; -+ size_t bufsz; -+ size_t size; -+ int i; -+ -+ bufsz = 0; -+ for (i = 0; i < image->nr_segments; i++) { -+ struct kexec_segment *seg; -+ -+ seg = &image->segment[i]; -+ if (seg->bufsz < 6) -+ continue; -+ -+ if (strncmp((char *) seg->buf, "kexec ", 6)) -+ continue; -+ -+ buf = seg->buf; -+ bufsz = seg->bufsz; -+ break; -+ } -+ -+ if (!buf) -+ return; -+ -+ size = KEXEC_COMMAND_LINE_SIZE; -+ size = min(size, bufsz); -+ if (size < bufsz) -+ pr_warn("kexec command line truncated to %zd bytes\n", size); -+ -+ /* Copy to kernel space */ -+ if (copy_from_user(kexec_argv_buf, buf, size)) -+ pr_warn("kexec command line copy to kernel space failed\n"); -+ -+ kexec_argv_buf[size - 1] = 0; -+} -+ -+static void machine_kexec_parse_argv(struct kimage *image) -+{ -+ char *reboot_code_buffer; -+ int reloc_delta; -+ char *ptr; -+ int argc; -+ int i; -+ -+ ptr = kexec_argv_buf; -+ argc = 0; -+ -+ /* -+ * convert command line string to array of parameters -+ * (as bootloader does). -+ */ -+ while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) { -+ if (*ptr == ' ') { -+ *ptr++ = '\0'; -+ continue; -+ } -+ -+ kexec_argv[argc++] = ptr; -+ ptr = strchr(ptr, ' '); -+ } -+ -+ if (!argc) -+ return; -+ -+ kexec_args[0] = argc; -+ kexec_args[1] = (unsigned long)kexec_argv; -+ kexec_args[2] = 0; -+ kexec_args[3] = 0; -+ -+ reboot_code_buffer = page_address(image->control_code_page); -+ reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel; -+ -+ kexec_args[1] += reloc_delta; -+ for (i = 0; i < argc; i++) -+ kexec_argv[i] += reloc_delta; -+} -+ - static void kexec_image_info(const struct kimage *kimage) - { - unsigned long i; -@@ -99,6 +191,18 @@ machine_kexec_prepare(struct kimage *kim - #endif - - kexec_image_info(kimage); -+ /* -+ * Whenever arguments passed from kexec-tools, Init the arguments as -+ * the original ones to try avoiding booting failure. -+ */ -+ -+ kexec_args[0] = fw_arg0; -+ kexec_args[1] = fw_arg1; -+ kexec_args[2] = fw_arg2; -+ kexec_args[3] = fw_arg3; -+ -+ machine_kexec_init_argv(kimage); -+ machine_kexec_parse_argv(kimage); - - if (_machine_kexec_prepare) - return _machine_kexec_prepare(kimage); -@@ -161,7 +265,7 @@ machine_crash_shutdown(struct pt_regs *r - void kexec_nonboot_cpu_jump(void) - { - local_flush_icache_range((unsigned long)relocated_kexec_smp_wait, -- reboot_code_buffer + relocate_new_kernel_size); -+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE); - - relocated_kexec_smp_wait(NULL); - } -@@ -199,7 +303,7 @@ void kexec_reboot(void) - * machine_kexec() CPU. - */ - local_flush_icache_range(reboot_code_buffer, -- reboot_code_buffer + relocate_new_kernel_size); -+ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE); - - do_kexec = (void *)reboot_code_buffer; - do_kexec(); -@@ -212,10 +316,12 @@ machine_kexec(struct kimage *image) - unsigned long *ptr; - - reboot_code_buffer = -- (unsigned long)page_address(image->control_code_page); -+ (unsigned long)page_address(image->control_code_page); -+ pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer); - - kexec_start_address = - (unsigned long) phys_to_virt(image->start); -+ pr_info("kexec_start_address = %p\n", (void *)kexec_start_address); - - if (image->type == KEXEC_TYPE_DEFAULT) { - kexec_indirection_page = -@@ -223,9 +329,19 @@ machine_kexec(struct kimage *image) - } else { - kexec_indirection_page = (unsigned long)&image->head; - } -+ pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page); - -- memcpy((void*)reboot_code_buffer, relocate_new_kernel, -- relocate_new_kernel_size); -+ pr_info("Where is memcpy: %p\n", memcpy); -+ pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n", -+ (void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end); -+ pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE, -+ (void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer); -+ memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel, -+ KEXEC_RELOCATE_NEW_KERNEL_SIZE); -+ -+ pr_info("Before _print_args().\n"); -+ machine_kexec_print_args(); -+ pr_info("Before eval loop.\n"); - - /* - * The generic kexec code builds a page list with physical -@@ -256,7 +372,7 @@ machine_kexec(struct kimage *image) - #ifdef CONFIG_SMP - /* All secondary cpus now may jump to kexec_wait cycle */ - relocated_kexec_smp_wait = reboot_code_buffer + -- (void *)(kexec_smp_wait - relocate_new_kernel); -+ (void *)(kexec_smp_wait - kexec_relocate_new_kernel); - smp_wmb(); - atomic_set(&kexec_ready_to_reboot, 1); - #endif ---- /dev/null -+++ b/arch/mips/kernel/machine_kexec.h -@@ -0,0 +1,20 @@ -+#ifndef _MACHINE_KEXEC_H -+#define _MACHINE_KEXEC_H -+ -+#ifndef __ASSEMBLY__ -+extern const unsigned char kexec_relocate_new_kernel[]; -+extern unsigned long kexec_relocate_new_kernel_end; -+extern unsigned long kexec_start_address; -+extern unsigned long kexec_indirection_page; -+ -+extern char kexec_argv_buf[]; -+extern char *kexec_argv[]; -+ -+#define KEXEC_RELOCATE_NEW_KERNEL_SIZE ((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel) -+#endif /* !__ASSEMBLY__ */ -+ -+#define KEXEC_COMMAND_LINE_SIZE 256 -+#define KEXEC_ARGV_SIZE (KEXEC_COMMAND_LINE_SIZE / 16) -+#define KEXEC_MAX_ARGC (KEXEC_ARGV_SIZE / sizeof(long)) -+ -+#endif ---- a/arch/mips/kernel/relocate_kernel.S -+++ b/arch/mips/kernel/relocate_kernel.S -@@ -10,10 +10,11 @@ - #include - #include - #include -+#include "machine_kexec.h" - - #include - --LEAF(relocate_new_kernel) -+LEAF(kexec_relocate_new_kernel) - PTR_L a0, arg0 - PTR_L a1, arg1 - PTR_L a2, arg2 -@@ -98,7 +99,7 @@ done: - #endif - /* jump to kexec_start_address */ - j s1 -- END(relocate_new_kernel) -+ END(kexec_relocate_new_kernel) - - #ifdef CONFIG_SMP - /* -@@ -177,8 +178,15 @@ EXPORT(kexec_indirection_page) - PTR_WD 0 - .size kexec_indirection_page, PTRSIZE - --relocate_new_kernel_end: -+kexec_argv_buf: -+ EXPORT(kexec_argv_buf) -+ .skip KEXEC_COMMAND_LINE_SIZE -+ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE -+ -+kexec_argv: -+ EXPORT(kexec_argv) -+ .skip KEXEC_ARGV_SIZE -+ .size kexec_argv, KEXEC_ARGV_SIZE - --EXPORT(relocate_new_kernel_size) -- PTR_WD relocate_new_kernel_end - relocate_new_kernel -- .size relocate_new_kernel_size, PTRSIZE -+kexec_relocate_new_kernel_end: -+ EXPORT(kexec_relocate_new_kernel_end) diff --git a/target/linux/generic/pending-6.1/332-arc-add-OWRTDTB-section.patch b/target/linux/generic/pending-6.1/332-arc-add-OWRTDTB-section.patch deleted file mode 100644 index 30158cf399b1f2..00000000000000 --- a/target/linux/generic/pending-6.1/332-arc-add-OWRTDTB-section.patch +++ /dev/null @@ -1,84 +0,0 @@ -From bb0c3b0175240bf152fd7c644821a0cf9f77c37c Mon Sep 17 00:00:00 2001 -From: Evgeniy Didin -Date: Fri, 15 Mar 2019 18:53:38 +0300 -Subject: [PATCH] arc add OWRTDTB section - -This change allows OpenWRT to patch resulting kernel binary with -external .dtb. - -That allows us to re-use exactky the same vmlinux on different boards -given its ARC core configurations match (at least cache line sizes etc). - -""patch-dtb" searches for ASCII "OWRTDTB:" strign and copies external -.dtb right after it, keeping the string in place. - -Signed-off-by: Eugeniy Paltsev -Signed-off-by: Alexey Brodkin -Signed-off-by: Evgeniy Didin ---- - arch/arc/kernel/head.S | 10 ++++++++++ - arch/arc/kernel/setup.c | 4 +++- - arch/arc/kernel/vmlinux.lds.S | 13 +++++++++++++ - 3 files changed, 26 insertions(+), 1 deletion(-) - ---- a/arch/arc/kernel/head.S -+++ b/arch/arc/kernel/head.S -@@ -88,6 +88,16 @@ - DSP_EARLY_INIT - .endm - -+ ; Here "patch-dtb" will embed external .dtb -+ ; Note "patch-dtb" searches for ASCII "OWRTDTB:" string -+ ; and pastes .dtb right after it, hense the string precedes -+ ; __image_dtb symbol. -+ .section .owrt, "aw",@progbits -+ .ascii "OWRTDTB:" -+ENTRY(__image_dtb) -+ .fill 0x4000 -+END(__image_dtb) -+ - .section .init.text, "ax",@progbits - - ;---------------------------------------------------------------- ---- a/arch/arc/kernel/setup.c -+++ b/arch/arc/kernel/setup.c -@@ -495,6 +495,8 @@ static inline bool uboot_arg_invalid(uns - /* We always pass 0 as magic from U-boot */ - #define UBOOT_MAGIC_VALUE 0 - -+extern struct boot_param_header __image_dtb; -+ - void __init handle_uboot_args(void) - { - bool use_embedded_dtb = true; -@@ -533,7 +535,7 @@ void __init handle_uboot_args(void) - ignore_uboot_args: - - if (use_embedded_dtb) { -- machine_desc = setup_machine_fdt(__dtb_start); -+ machine_desc = setup_machine_fdt(&__image_dtb); - if (!machine_desc) - panic("Embedded DT invalid\n"); - } ---- a/arch/arc/kernel/vmlinux.lds.S -+++ b/arch/arc/kernel/vmlinux.lds.S -@@ -27,6 +27,19 @@ SECTIONS - - . = CONFIG_LINUX_LINK_BASE; - -+ /* -+ * In OpenWRT we want to patch built binary embedding .dtb of choice. -+ * This is implemented with "patch-dtb" utility which searches for -+ * "OWRTDTB:" string in first 16k of image and if it is found -+ * copies .dtb right after mentioned string. -+ * -+ * Note: "OWRTDTB:" won't be overwritten with .dtb, .dtb will follow it. -+ */ -+ .owrt : { -+ *(.owrt) -+ . = ALIGN(PAGE_SIZE); -+ } -+ - _int_vec_base_lds = .; - .vector : { - *(.vector) diff --git a/target/linux/generic/pending-6.1/333-arc-enable-unaligned-access-in-kernel-mode.patch b/target/linux/generic/pending-6.1/333-arc-enable-unaligned-access-in-kernel-mode.patch deleted file mode 100644 index 1848a84cc4970f..00000000000000 --- a/target/linux/generic/pending-6.1/333-arc-enable-unaligned-access-in-kernel-mode.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Alexey Brodkin -Subject: arc: enable unaligned access in kernel mode - -This enables misaligned access handling even in kernel mode. -Some wireless drivers (ath9k-htc and mt7601u) use misaligned accesses -here and there and to cope with that without fixing stuff in the drivers -we're just gracefully handling it on ARC. - -Signed-off-by: Alexey Brodkin ---- - arch/arc/kernel/unaligned.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arc/kernel/unaligned.c -+++ b/arch/arc/kernel/unaligned.c -@@ -202,7 +202,7 @@ int misaligned_fixup(unsigned long addre - char buf[TASK_COMM_LEN]; - - /* handle user mode only and only if enabled by sysadmin */ -- if (!user_mode(regs) || !unaligned_enabled) -+ if (!unaligned_enabled) - return 1; - - if (no_unaligned_warning) { diff --git a/target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch b/target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch deleted file mode 100644 index e9b47d185d2a4a..00000000000000 --- a/target/linux/generic/pending-6.1/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 66770a004afe10df11d3902e16eaa0c2c39436bb Mon Sep 17 00:00:00 2001 -From: Pawel Dembicki -Date: Fri, 24 May 2019 17:56:19 +0200 -Subject: [PATCH] powerpc: Enable kernel XZ compression option on PPC_85xx - -Enable kernel XZ compression option on PPC_85xx. Tested with -simpleImage on TP-Link TL-WDR4900 (Freescale P1014 processor). - -Suggested-by: Christian Lamparter -Signed-off-by: Pawel Dembicki ---- - arch/powerpc/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/powerpc/Kconfig -+++ b/arch/powerpc/Kconfig -@@ -229,7 +229,7 @@ config PPC - select HAVE_KERNEL_GZIP - select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE - select HAVE_KERNEL_LZO if DEFAULT_UIMAGE -- select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x -+ select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x || PPC_85xx - select HAVE_KPROBES - select HAVE_KPROBES_ON_FTRACE - select HAVE_KRETPROBES diff --git a/target/linux/generic/pending-6.1/350-mips-kernel-fix-detect_memory_region-function.patch b/target/linux/generic/pending-6.1/350-mips-kernel-fix-detect_memory_region-function.patch deleted file mode 100644 index 3bf7ae98bf35f2..00000000000000 --- a/target/linux/generic/pending-6.1/350-mips-kernel-fix-detect_memory_region-function.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Shiji Yang -Date: Wed, 13 Mar 2024 20:28:37 +0800 -Subject: [PATCH] mips: kernel: fix detect_memory_region() function - -1. Do not use memcmp() on unallocated memory, as the new introduced - fortify dynamic object size check[1] will report unexpected result. -2. Use a fixed pattern instead of a random function pointer as the - magic value. -3. Flip magic value and double check it. -4. Enable this feature only for 32-bit CPUs. Currently, only ath79 and - ralink CPUs are using it. - -[1] 439a1bcac648 ("fortify: Use __builtin_dynamic_object_size() when available") -Signed-off-by: Shiji Yang ---- - arch/mips/include/asm/bootinfo.h | 2 ++ - arch/mips/kernel/setup.c | 17 ++++++++++++----- - 2 files changed, 14 insertions(+), 5 deletions(-) - ---- a/arch/mips/include/asm/bootinfo.h -+++ b/arch/mips/include/asm/bootinfo.h -@@ -93,7 +93,9 @@ const char *get_system_type(void); - - extern unsigned long mips_machtype; - -+#ifndef CONFIG_64BIT - extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max); -+#endif - - extern void prom_init(void); - extern void prom_free_prom_memory(void); ---- a/arch/mips/kernel/setup.c -+++ b/arch/mips/kernel/setup.c -@@ -90,21 +90,27 @@ static struct resource bss_resource = { - unsigned long __kaslr_offset __ro_after_init; - EXPORT_SYMBOL(__kaslr_offset); - --static void *detect_magic __initdata = detect_memory_region; -- - #ifdef CONFIG_MIPS_AUTO_PFN_OFFSET - unsigned long ARCH_PFN_OFFSET; - EXPORT_SYMBOL(ARCH_PFN_OFFSET); - #endif - -+#ifndef CONFIG_64BIT -+static u32 detect_magic __initdata; -+#define MIPS_MEM_TEST_PATTERN 0xaa5555aa -+ - void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max) - { -- void *dm = &detect_magic; -+ void *dm = (void *)KSEG1ADDR(&detect_magic); - phys_addr_t size; - - for (size = sz_min; size < sz_max; size <<= 1) { -- if (!memcmp(dm, dm + size, sizeof(detect_magic))) -- break; -+ __raw_writel(MIPS_MEM_TEST_PATTERN, dm); -+ if (__raw_readl(dm) == __raw_readl(dm + size)) { -+ __raw_writel(~MIPS_MEM_TEST_PATTERN, dm); -+ if (__raw_readl(dm) == __raw_readl(dm + size)) -+ break; -+ } - } - - pr_debug("Memory: %lluMB of RAM detected at 0x%llx (min: %lluMB, max: %lluMB)\n", -@@ -115,6 +121,7 @@ void __init detect_memory_region(phys_ad - - memblock_add(start, size); - } -+#endif /* CONFIG_64BIT */ - - /* - * Manage initrd diff --git a/target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch b/target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch deleted file mode 100644 index 2675ca47910de9..00000000000000 --- a/target/linux/generic/pending-6.1/351-irqchip-bcm-6345-l1-request-memory-region.patch +++ /dev/null @@ -1,113 +0,0 @@ -From patchwork Thu Mar 16 19:28:33 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13178238 -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 5EF2AC6FD19 - for ; Thu, 16 Mar 2023 19:28:43 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S230076AbjCPT2l (ORCPT ); - Thu, 16 Mar 2023 15:28:41 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56412 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S230039AbjCPT2k (ORCPT - ); Thu, 16 Mar 2023 15:28:40 -0400 -Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com - [IPv6:2a00:1450:4864:20::42f]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7259B7D9F; - Thu, 16 Mar 2023 12:28:38 -0700 (PDT) -Received: by mail-wr1-x42f.google.com with SMTP id y14so2539231wrq.4; - Thu, 16 Mar 2023 12:28:38 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1678994917; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=j8afldfRZftLeVmekmQfoh01jVdumsVP7nkKoPaU3Q0=; - b=FzMRr5ekh/fDiJqTlezNj6nLjzvn5z92FtYeB8MquVSMB8PuvarccnyqAzsXiccf+v - uwRFIomnTWNLGVjzc1xrB2hGiCKD3jBo5n1u8p/yEV6rpolbxVjfM7eTHXyAHXGXz7ZJ - TPeVbWfAlxiSD6+BPtXr/efehcdI64fIoL6G/U1WHNMo01Tzr/Obf3y5tug17N0fGcXg - CH6E5a2HguZUtwrm26LcK9IOV/7xEx5eIE1cOvTLMxPbGWaZwEjjP16HylJr06xRLhaf - RpiYBT3mXwwuOx0jLOhqavY/2kZ9GVbZRWMMwZrZv9xNO13SBwc1VUVgD4k3FntnSk7Z - AaOQ== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1678994917; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=j8afldfRZftLeVmekmQfoh01jVdumsVP7nkKoPaU3Q0=; - b=OaA5DMgqalrfqO5iOtmmxFPsH90MkN7l4EJpyVnzuiO1Wd6rSCpqPOR7xpxZno8OPP - tdfm4vzn9Ie4AUDbFKDTUlPG+tgkmIruo3K9C0VnY9DD2PRZMEYBbWaJKU1otqKt0NKu - IAAHNvxvQvCESKzbXFLYwWbRKFScOSMGmGBTDfgThz51A18Ff1hJy/BmnuZk7M2TLgHO - wQpy9t7oeB/Hkxl41y46emLc/nESsvwvAG/fx/zPzCe9UiaQLrdZq+BKeOwSBedktzK5 - U/ZTfgzU2UGSI67aGRqqGnI0uXq+MAJMK18qzM0VByxj6W+AXJ6BJr5P0quljeQ8upSg - bEUg== -X-Gm-Message-State: AO0yUKWnqTlccBDnqwCSRdqOBGc2FyfiLy1Tg7EjPENlISpzXuDYwW/R - lJSI06rrfq+Vel/SigfpGJI= -X-Google-Smtp-Source: - AK7set/jYfYl9ttVzIXJO+ZQVfa6cE/yOsP8fx4teiTmGNNWyVlIJRzMAlF3IUGqRAXAmY3hAabIuQ== -X-Received: by 2002:a5d:40ce:0:b0:2cd:ceab:df1a with SMTP id - b14-20020a5d40ce000000b002cdceabdf1amr381006wrq.32.1678994916642; - Thu, 16 Mar 2023 12:28:36 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - l10-20020a5d4bca000000b002cfea3c49d5sm180041wrt.52.2023.03.16.12.28.35 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Thu, 16 Mar 2023 12:28:35 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: f.fainelli@gmail.com, jonas.gorski@gmail.com, - bcm-kernel-feedback-list@broadcom.com, tglx@linutronix.de, - maz@kernel.org, linux-mips@vger.kernel.org, - linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v2] irqchip/bcm-6345-l1: request memory region -Date: Thu, 16 Mar 2023 20:28:33 +0100 -Message-Id: <20230316192833.1603149-1-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230316180701.783785-1-noltari@gmail.com> -References: <20230316180701.783785-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: linux-mips@vger.kernel.org - -Request memory region in order to display it in /proc/iomem. -Also stop printing the MMIO address since it just displays (ptrval). - -Signed-off-by: Álvaro Fernández Rojas -Acked-by: Florian Fainelli ---- - v2: request memory region and stop displaying MMIO address. - - drivers/irqchip/irq-bcm6345-l1.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/irqchip/irq-bcm6345-l1.c -+++ b/drivers/irqchip/irq-bcm6345-l1.c -@@ -253,6 +253,9 @@ static int __init bcm6345_l1_init_one(st - if (!cpu->map_base) - return -ENOMEM; - -+ if (!request_mem_region(res.start, sz, res.name)) -+ pr_err("failed to request intc memory"); -+ - for (i = 0; i < n_words; i++) { - cpu->enable_cache[i] = 0; - __raw_writel(0, cpu->map_base + reg_enable(intc, i)); -@@ -331,8 +334,7 @@ static int __init bcm6345_l1_of_init(str - for_each_cpu(idx, &intc->cpumask) { - struct bcm6345_l1_cpu *cpu = intc->cpus[idx]; - -- pr_info(" CPU%u at MMIO 0x%p (irq = %d)\n", idx, -- cpu->map_base, cpu->parent_irq); -+ pr_info(" CPU%u (irq = %d)\n", idx, cpu->parent_irq); - } - - return 0; diff --git a/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch b/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch deleted file mode 100644 index c619d12ce53985..00000000000000 --- a/target/linux/generic/pending-6.1/400-mtd-mtdsplit-support.patch +++ /dev/null @@ -1,328 +0,0 @@ -From 39717277d5c87bdb183cf2f258957b44ba99b4df Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 11:47:35 +0200 -Subject: [PATCH] mtd: mtdsplit support - ---- - drivers/mtd/Kconfig | 19 ++++ - drivers/mtd/Makefile | 2 + - drivers/mtd/mtdpart.c | 169 ++++++++++++++++++++++++++++----- - include/linux/mtd/mtd.h | 25 +++++ - include/linux/mtd/partitions.h | 7 ++ - 5 files changed, 197 insertions(+), 25 deletions(-) - ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -12,6 +12,25 @@ menuconfig MTD - - if MTD - -+menu "OpenWrt specific MTD options" -+ -+config MTD_ROOTFS_ROOT_DEV -+ bool "Automatically set 'rootfs' partition to be root filesystem" -+ default y -+ -+config MTD_SPLIT_FIRMWARE -+ bool "Automatically split firmware partition for kernel+rootfs" -+ default y -+ -+config MTD_SPLIT_FIRMWARE_NAME -+ string "Firmware partition name" -+ depends on MTD_SPLIT_FIRMWARE -+ default "firmware" -+ -+source "drivers/mtd/mtdsplit/Kconfig" -+ -+endmenu -+ - config MTD_TESTS - tristate "MTD tests support (DANGEROUS)" - depends on m ---- a/drivers/mtd/Makefile -+++ b/drivers/mtd/Makefile -@@ -9,6 +9,8 @@ mtd-y := mtdcore.o mtdsuper.o mtdconc - - obj-y += parsers/ - -+obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ -+ - # 'Users' - code which presents functionality to userspace. - obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o - obj-$(CONFIG_MTD_BLOCK) += mtdblock.o ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -15,11 +15,13 @@ - #include - #include - #include -+#include - #include - #include - #include - - #include "mtdcore.h" -+#include "mtdsplit/mtdsplit.h" - - /* - * MTD methods which simply translate the effective address and pass through -@@ -236,6 +238,147 @@ static int mtd_add_partition_attrs(struc - return ret; - } - -+static DEFINE_SPINLOCK(part_parser_lock); -+static LIST_HEAD(part_parsers); -+ -+static struct mtd_part_parser *mtd_part_parser_get(const char *name) -+{ -+ struct mtd_part_parser *p, *ret = NULL; -+ -+ spin_lock(&part_parser_lock); -+ -+ list_for_each_entry(p, &part_parsers, list) -+ if (!strcmp(p->name, name) && try_module_get(p->owner)) { -+ ret = p; -+ break; -+ } -+ -+ spin_unlock(&part_parser_lock); -+ -+ return ret; -+} -+ -+static inline void mtd_part_parser_put(const struct mtd_part_parser *p) -+{ -+ module_put(p->owner); -+} -+ -+static struct mtd_part_parser * -+get_partition_parser_by_type(enum mtd_parser_type type, -+ struct mtd_part_parser *start) -+{ -+ struct mtd_part_parser *p, *ret = NULL; -+ -+ spin_lock(&part_parser_lock); -+ -+ p = list_prepare_entry(start, &part_parsers, list); -+ if (start) -+ mtd_part_parser_put(start); -+ -+ list_for_each_entry_continue(p, &part_parsers, list) { -+ if (p->type == type && try_module_get(p->owner)) { -+ ret = p; -+ break; -+ } -+ } -+ -+ spin_unlock(&part_parser_lock); -+ -+ return ret; -+} -+ -+static int parse_mtd_partitions_by_type(struct mtd_info *master, -+ enum mtd_parser_type type, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct mtd_part_parser *prev = NULL; -+ int ret = 0; -+ -+ while (1) { -+ struct mtd_part_parser *parser; -+ -+ parser = get_partition_parser_by_type(type, prev); -+ if (!parser) -+ break; -+ -+ ret = (*parser->parse_fn)(master, pparts, data); -+ -+ if (ret > 0) { -+ mtd_part_parser_put(parser); -+ printk(KERN_NOTICE -+ "%d %s partitions found on MTD device %s\n", -+ ret, parser->name, master->name); -+ break; -+ } -+ -+ prev = parser; -+ } -+ -+ return ret; -+} -+ -+static int -+run_parsers_by_type(struct mtd_info *child, enum mtd_parser_type type) -+{ -+ struct mtd_partition *parts; -+ int nr_parts; -+ int i; -+ -+ nr_parts = parse_mtd_partitions_by_type(child, type, (const struct mtd_partition **)&parts, -+ NULL); -+ if (nr_parts <= 0) -+ return nr_parts; -+ -+ if (WARN_ON(!parts)) -+ return 0; -+ -+ for (i = 0; i < nr_parts; i++) { -+ /* adjust partition offsets */ -+ parts[i].offset += child->part.offset; -+ -+ mtd_add_partition(child->parent, -+ parts[i].name, -+ parts[i].offset, -+ parts[i].size); -+ } -+ -+ kfree(parts); -+ -+ return nr_parts; -+} -+ -+#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME -+#else -+#define SPLIT_FIRMWARE_NAME "unused" -+#endif -+ -+static void split_firmware(struct mtd_info *master, struct mtd_info *part) -+{ -+ run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); -+} -+ -+static void mtd_partition_split(struct mtd_info *master, struct mtd_info *part) -+{ -+ static int rootfs_found = 0; -+ -+ if (rootfs_found) -+ return; -+ -+ if (of_find_property(mtd_get_of_node(part), "linux,rootfs", NULL) || -+ !strcmp(part->name, "rootfs")) { -+ run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); -+ -+ rootfs_found = 1; -+ } -+ -+ if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) && -+ !strcmp(part->name, SPLIT_FIRMWARE_NAME) && -+ !of_find_property(mtd_get_of_node(part), "compatible", NULL)) -+ split_firmware(master, part); -+} -+ - int mtd_add_partition(struct mtd_info *parent, const char *name, - long long offset, long long length) - { -@@ -274,6 +417,7 @@ int mtd_add_partition(struct mtd_info *p - if (ret) - goto err_remove_part; - -+ mtd_partition_split(parent, child); - mtd_add_partition_attrs(child); - - return 0; -@@ -422,6 +566,7 @@ int add_mtd_partitions(struct mtd_info * - goto err_del_partitions; - } - -+ mtd_partition_split(master, child); - mtd_add_partition_attrs(child); - - /* Look for subpartitions */ -@@ -438,31 +583,6 @@ err_del_partitions: - return ret; - } - --static DEFINE_SPINLOCK(part_parser_lock); --static LIST_HEAD(part_parsers); -- --static struct mtd_part_parser *mtd_part_parser_get(const char *name) --{ -- struct mtd_part_parser *p, *ret = NULL; -- -- spin_lock(&part_parser_lock); -- -- list_for_each_entry(p, &part_parsers, list) -- if (!strcmp(p->name, name) && try_module_get(p->owner)) { -- ret = p; -- break; -- } -- -- spin_unlock(&part_parser_lock); -- -- return ret; --} -- --static inline void mtd_part_parser_put(const struct mtd_part_parser *p) --{ -- module_put(p->owner); --} -- - /* - * Many partition parsers just expected the core to kfree() all their data in - * one chunk. Do that by default. ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -615,6 +615,24 @@ static inline void mtd_align_erase_req(s - req->len += mtd->erasesize - mod; - } - -+static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd) -+{ -+ if (mtd_mod_by_eb(sz, mtd) == 0) -+ return sz; -+ -+ /* Round up to next erase block */ -+ return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize; -+} -+ -+static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd) -+{ -+ if (mtd_mod_by_eb(sz, mtd) == 0) -+ return sz; -+ -+ /* Round down to the start of the current erase block */ -+ return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize; -+} -+ - static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) - { - if (mtd->writesize_shift) -@@ -688,6 +706,13 @@ extern struct mtd_info *of_get_mtd_devic - extern struct mtd_info *get_mtd_device_nm(const char *name); - extern void put_mtd_device(struct mtd_info *mtd); - -+static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd) -+{ -+ if (!mtd_is_partition(mtd)) -+ return 0; -+ -+ return mtd->part.offset; -+} - - struct mtd_notifier { - void (*add)(struct mtd_info *mtd); ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -75,6 +75,12 @@ struct mtd_part_parser_data { - * Functions dealing with the various ways of partitioning the space - */ - -+enum mtd_parser_type { -+ MTD_PARSER_TYPE_DEVICE = 0, -+ MTD_PARSER_TYPE_ROOTFS, -+ MTD_PARSER_TYPE_FIRMWARE, -+}; -+ - struct mtd_part_parser { - struct list_head list; - struct module *owner; -@@ -83,6 +89,7 @@ struct mtd_part_parser { - int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, - struct mtd_part_parser_data *); - void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); -+ enum mtd_parser_type type; - }; - - /* Container for passing around a set of parsed partitions */ diff --git a/target/linux/generic/pending-6.1/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch b/target/linux/generic/pending-6.1/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch deleted file mode 100644 index 42b5a564b15e2d..00000000000000 --- a/target/linux/generic/pending-6.1/401-mtd-don-t-register-NVMEM-devices-for-partitions-with.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 31 Oct 2023 15:51:01 +0100 -Subject: [PATCH] mtd: don't register NVMEM devices for partitions with custom - drivers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes issue exposed by upstream commit f4cf4e5db331 ("Revert -"nvmem: add new config option""). - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/mtdcore.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -519,6 +519,29 @@ static int mtd_nvmem_add(struct mtd_info - struct device_node *node = mtd_get_of_node(mtd); - struct nvmem_config config = {}; - -+ /* -+ * Do NOT register NVMEM device for any partition that is meant to be -+ * handled by a U-Boot env driver. That would result in associating two -+ * different NVMEM devices with the same OF node. -+ * -+ * An example of unwanted behaviour of above (forwardtrace): -+ * of_get_mac_addr_nvmem() -+ * of_nvmem_cell_get() -+ * __nvmem_device_get() -+ * -+ * We can't have __nvmem_device_get() return "mtdX" NVMEM device instead -+ * of U-Boot env NVMEM device. That would result in failing to find -+ * NVMEM cell. -+ * -+ * This issue seems to affect U-Boot env case only and will go away with -+ * switch to NVMEM layouts. -+ */ -+ if (of_device_is_compatible(node, "u-boot,env") || -+ of_device_is_compatible(node, "u-boot,env-redundant-bool") || -+ of_device_is_compatible(node, "u-boot,env-redundant-count") || -+ of_device_is_compatible(node, "brcm,env")) -+ return 0; -+ - config.id = -1; - config.dev = &mtd->dev; - config.name = dev_name(&mtd->dev); diff --git a/target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch b/target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch deleted file mode 100644 index 66a6feff6065f6..00000000000000 --- a/target/linux/generic/pending-6.1/402-mtd-spi-nor-write-support-for-minor-aligned-partitions.patch +++ /dev/null @@ -1,245 +0,0 @@ -From acacdac272927ae1d96e0bca51eb82899671eaea Mon Sep 17 00:00:00 2001 -From: John Thomson -Date: Fri, 25 Dec 2020 18:50:08 +1000 -Subject: [PATCH] mtd: spi-nor: write support for minor aligned partitions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Do not prevent writing to mtd partitions where a partition boundary sits -on a minor erasesize boundary. -This addresses a FIXME that has been present since the start of the -linux git history: -/* Doesn't start on a boundary of major erase size */ -/* FIXME: Let it be writable if it is on a boundary of - * _minor_ erase size though */ - -Allow a uniform erase region spi-nor device to be configured -to use the non-uniform erase regions code path for an erase with: -CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE=y - -On supporting hardware (SECT_4K: majority of current SPI-NOR device) -provide the facility for an erase to use the least number -of SPI-NOR operations, as well as access to 4K erase without -requiring CONFIG_MTD_SPI_NOR_USE_4K_SECTORS - -Introduce erasesize_minor to the mtd struct, -the smallest erasesize supported by the device - -On existing devices, this is useful where write support is wanted -for data on a 4K partition, such as some u-boot-env partitions, -or RouterBoot soft_config, while still netting the performance -benefits of using 64K sectors - -Performance: -time mtd erase firmware -OpenWrt 5.10 ramips MT7621 w25q128jv 0xfc0000 partition length - -Without this patch -MTD_SPI_NOR_USE_4K_SECTORS=y |n -real 2m 11.66s |0m 50.86s -user 0m 0.00s |0m 0.00s -sys 1m 56.20s |0m 50.80s - -With this patch -MTD_SPI_NOR_USE_VARIABLE_ERASE=n|y |4K_SECTORS=y -real 0m 51.68s |0m 50.85s |2m 12.89s -user 0m 0.00s |0m 0.00s |0m 0.01s -sys 0m 46.94s |0m 50.38s |2m 12.46s - -Signed-off-by: John Thomson -Signed-off-by: Thibaut VARÈNE - ---- - -checkpatch does not like the printk(KERN_WARNING -these should be changed separately beforehand? - -Changes v1 -> v2: -Added mtdcore sysfs for erasesize_minor -Removed finding minor erasesize for variable erase regions device, -as untested and no responses regarding it. -Moved IF_ENABLED for SPINOR variable erase to guard setting -erasesize_minor in spi-nor/core.c -Removed setting erasesize to minor where partition boundaries require -minor erase to be writable -Simplified minor boundary check by relying on minor being a factor of -major - -Changes RFC -> v1: -Fix uninitialized variable smatch warning -Reported-by: kernel test robot -Reported-by: Dan Carpenter ---- - drivers/mtd/mtdcore.c | 10 ++++++++++ - drivers/mtd/mtdpart.c | 35 +++++++++++++++++++++++++---------- - drivers/mtd/spi-nor/Kconfig | 10 ++++++++++ - drivers/mtd/spi-nor/core.c | 11 +++++++++-- - include/linux/mtd/mtd.h | 2 ++ - 5 files changed, 56 insertions(+), 12 deletions(-) - ---- a/drivers/mtd/mtdcore.c -+++ b/drivers/mtd/mtdcore.c -@@ -169,6 +169,15 @@ static ssize_t mtd_erasesize_show(struct - } - MTD_DEVICE_ATTR_RO(erasesize); - -+static ssize_t mtd_erasesize_minor_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct mtd_info *mtd = dev_get_drvdata(dev); -+ -+ return sysfs_emit(buf, "%lu\n", (unsigned long)mtd->erasesize_minor); -+} -+MTD_DEVICE_ATTR_RO(erasesize_minor); -+ - static ssize_t mtd_writesize_show(struct device *dev, - struct device_attribute *attr, char *buf) - { -@@ -314,6 +323,7 @@ static struct attribute *mtd_attrs[] = { - &dev_attr_flags.attr, - &dev_attr_size.attr, - &dev_attr_erasesize.attr, -+ &dev_attr_erasesize_minor.attr, - &dev_attr_writesize.attr, - &dev_attr_subpagesize.attr, - &dev_attr_oobsize.attr, ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -41,6 +41,7 @@ static struct mtd_info *allocate_partiti - struct mtd_info *master = mtd_get_master(parent); - int wr_alignment = (parent->flags & MTD_NO_ERASE) ? - master->writesize : master->erasesize; -+ int wr_alignment_minor = 0; - u64 parent_size = mtd_is_partition(parent) ? - parent->part.size : parent->size; - struct mtd_info *child; -@@ -165,6 +166,7 @@ static struct mtd_info *allocate_partiti - } else { - /* Single erase size */ - child->erasesize = master->erasesize; -+ child->erasesize_minor = master->erasesize_minor; - } - - /* -@@ -172,26 +174,39 @@ static struct mtd_info *allocate_partiti - * exposes several regions with different erasesize. Adjust - * wr_alignment accordingly. - */ -- if (!(child->flags & MTD_NO_ERASE)) -+ if (!(child->flags & MTD_NO_ERASE)) { - wr_alignment = child->erasesize; -+ wr_alignment_minor = child->erasesize_minor; -+ } - - tmp = mtd_get_master_ofs(child, 0); - remainder = do_div(tmp, wr_alignment); - if ((child->flags & MTD_WRITEABLE) && remainder) { -- /* Doesn't start on a boundary of major erase size */ -- /* FIXME: Let it be writable if it is on a boundary of -- * _minor_ erase size though */ -- child->flags &= ~MTD_WRITEABLE; -- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", -- part->name); -+ if (wr_alignment_minor) { -+ /* rely on minor being a factor of major erasesize */ -+ tmp = remainder; -+ remainder = do_div(tmp, wr_alignment_minor); -+ } -+ if (remainder) { -+ child->flags &= ~MTD_WRITEABLE; -+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", -+ part->name); -+ } - } - - tmp = mtd_get_master_ofs(child, 0) + child->part.size; - remainder = do_div(tmp, wr_alignment); - if ((child->flags & MTD_WRITEABLE) && remainder) { -- child->flags &= ~MTD_WRITEABLE; -- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", -- part->name); -+ if (wr_alignment_minor) { -+ tmp = remainder; -+ remainder = do_div(tmp, wr_alignment_minor); -+ } -+ -+ if (remainder) { -+ child->flags &= ~MTD_WRITEABLE; -+ printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", -+ part->name); -+ } - } - - child->size = child->part.size; ---- a/drivers/mtd/spi-nor/Kconfig -+++ b/drivers/mtd/spi-nor/Kconfig -@@ -10,6 +10,16 @@ menuconfig MTD_SPI_NOR - - if MTD_SPI_NOR - -+config MTD_SPI_NOR_USE_VARIABLE_ERASE -+ bool "Disable uniform_erase to allow use of all hardware supported erasesizes" -+ depends on !MTD_SPI_NOR_USE_4K_SECTORS -+ default n -+ help -+ Allow mixed use of all hardware supported erasesizes, -+ by forcing spi_nor to use the multiple eraseregions code path. -+ For example: A 68K erase will use one 64K erase, and one 4K erase -+ on supporting hardware. -+ - config MTD_SPI_NOR_USE_4K_SECTORS - bool "Use small 4096 B erase sectors" - default y ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -1050,6 +1050,8 @@ static u8 spi_nor_convert_3to4_erase(u8 - - static bool spi_nor_has_uniform_erase(const struct spi_nor *nor) - { -+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE)) -+ return false; - return !!nor->params->erase_map.uniform_erase_type; - } - -@@ -2180,6 +2182,7 @@ static int spi_nor_select_erase(struct s - { - struct spi_nor_erase_map *map = &nor->params->erase_map; - const struct spi_nor_erase_type *erase = NULL; -+ const struct spi_nor_erase_type *erase_minor = NULL; - struct mtd_info *mtd = &nor->mtd; - u32 wanted_size = nor->info->sector_size; - int i; -@@ -2212,8 +2215,9 @@ static int spi_nor_select_erase(struct s - */ - for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) { - if (map->erase_type[i].size) { -- erase = &map->erase_type[i]; -- break; -+ if (!erase) -+ erase = &map->erase_type[i]; -+ erase_minor = &map->erase_type[i]; - } - } - -@@ -2221,6 +2225,9 @@ static int spi_nor_select_erase(struct s - return -EINVAL; - - mtd->erasesize = erase->size; -+ if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_VARIABLE_ERASE) && -+ erase_minor && erase_minor->size < erase->size) -+ mtd->erasesize_minor = erase_minor->size; - return 0; - } - ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -245,6 +245,8 @@ struct mtd_info { - * information below if they desire - */ - uint32_t erasesize; -+ /* "Minor" (smallest) erase size supported by the whole device */ -+ uint32_t erasesize_minor; - /* Minimal writable flash unit size. In case of NOR flash it is 1 (even - * though individual bits can be cleared), in case of NAND flash it is - * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR diff --git a/target/linux/generic/pending-6.1/420-mtd-redboot_space.patch b/target/linux/generic/pending-6.1/420-mtd-redboot_space.patch deleted file mode 100644 index 5518ea71dd51f9..00000000000000 --- a/target/linux/generic/pending-6.1/420-mtd-redboot_space.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Felix Fietkau -Subject: add patch for including unpartitioned space in the rootfs partition for redboot devices (if applicable) - -[john@phrozen.org: used by ixp and others] - -lede-commit: 394918851f84e4d00fa16eb900e7700e95091f00 -Signed-off-by: Felix Fietkau ---- - drivers/mtd/redboot.c | 19 +++++++++++++------ - 1 file changed, 13 insertions(+), 6 deletions(-) - ---- a/drivers/mtd/parsers/redboot.c -+++ b/drivers/mtd/parsers/redboot.c -@@ -278,14 +278,21 @@ nogood: - #endif - names += strlen(names) + 1; - --#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED - if (fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { -- i++; -- parts[i].offset = parts[i - 1].size + parts[i - 1].offset; -- parts[i].size = fl->next->img->flash_base - parts[i].offset; -- parts[i].name = nullname; -- } -+ if (!strcmp(parts[i].name, "rootfs")) { -+ parts[i].size = fl->next->img->flash_base; -+ parts[i].size &= ~(master->erasesize - 1); -+ parts[i].size -= parts[i].offset; -+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED -+ nrparts--; -+ } else { -+ i++; -+ parts[i].offset = parts[i-1].size + parts[i-1].offset; -+ parts[i].size = fl->next->img->flash_base - parts[i].offset; -+ parts[i].name = nullname; - #endif -+ } -+ } - tmp_fl = fl; - fl = fl->next; - kfree(tmp_fl); diff --git a/target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch b/target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch deleted file mode 100644 index 35e80d6dcc95b5..00000000000000 --- a/target/linux/generic/pending-6.1/430-mtd-add-myloader-partition-parser.patch +++ /dev/null @@ -1,229 +0,0 @@ -From: Florian Fainelli -Subject: Add myloader partition table parser - -[john@phozen.org: shoud be upstreamable] - -lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8 -Signed-off-by: Florian Fainelli -[adjust for kernel 5.4, add myloader.c to patch] -Signed-off-by: Adrian Schmutzler - ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -67,6 +67,22 @@ config MTD_CMDLINE_PARTS - - If unsure, say 'N'. - -+config MTD_MYLOADER_PARTS -+ tristate "MyLoader partition parsing" -+ depends on ADM5120 || ATH79 -+ help -+ MyLoader is a bootloader which allows the user to define partitions -+ in flash devices, by putting a table in the second erase block -+ on the device, similar to a partition table. This table gives the -+ offsets and lengths of the user defined partitions. -+ -+ If you need code which can detect and parse these tables, and -+ register MTD 'partitions' corresponding to each image detected, -+ enable this option. -+ -+ You will still need the parsing functions to be called by the driver -+ for your particular device. It won't happen automatically. -+ - config MTD_OF_PARTS - tristate "OpenFirmware (device tree) partitioning parser" - default y ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -4,6 +4,7 @@ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm4 - obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o - obj-$(CONFIG_MTD_BRCM_U_BOOT) += brcm_u-boot.o - obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o -+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o - obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o - ofpart-y += ofpart_core.o - ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o ---- /dev/null -+++ b/drivers/mtd/parsers/myloader.c -@@ -0,0 +1,181 @@ -+/* -+ * Parse MyLoader-style flash partition tables and produce a Linux partition -+ * array to match. -+ * -+ * Copyright (C) 2007-2009 Gabor Juhos -+ * -+ * This file was based on drivers/mtd/redboot.c -+ * Author: Red Hat, Inc. - David Woodhouse -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define BLOCK_LEN_MIN 0x10000 -+#define PART_NAME_LEN 32 -+ -+struct part_data { -+ struct mylo_partition_table tab; -+ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN]; -+}; -+ -+static int myloader_parse_partitions(struct mtd_info *master, -+ const struct mtd_partition **pparts, -+ struct mtd_part_parser_data *data) -+{ -+ struct part_data *buf; -+ struct mylo_partition_table *tab; -+ struct mylo_partition *part; -+ struct mtd_partition *mtd_parts; -+ struct mtd_partition *mtd_part; -+ int num_parts; -+ int ret, i; -+ size_t retlen; -+ char *names; -+ unsigned long offset; -+ unsigned long blocklen; -+ -+ buf = vmalloc(sizeof(*buf)); -+ if (!buf) { -+ return -ENOMEM; -+ goto out; -+ } -+ tab = &buf->tab; -+ -+ blocklen = master->erasesize; -+ if (blocklen < BLOCK_LEN_MIN) -+ blocklen = BLOCK_LEN_MIN; -+ -+ offset = blocklen; -+ -+ /* Find the partition table */ -+ for (i = 0; i < 4; i++, offset += blocklen) { -+ printk(KERN_DEBUG "%s: searching for MyLoader partition table" -+ " at offset 0x%lx\n", master->name, offset); -+ -+ ret = mtd_read(master, offset, sizeof(*buf), &retlen, -+ (void *)buf); -+ if (ret) -+ goto out_free_buf; -+ -+ if (retlen != sizeof(*buf)) { -+ ret = -EIO; -+ goto out_free_buf; -+ } -+ -+ /* Check for Partition Table magic number */ -+ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS)) -+ break; -+ -+ } -+ -+ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) { -+ printk(KERN_DEBUG "%s: no MyLoader partition table found\n", -+ master->name); -+ ret = 0; -+ goto out_free_buf; -+ } -+ -+ /* The MyLoader and the Partition Table is always present */ -+ num_parts = 2; -+ -+ /* Detect number of used partitions */ -+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { -+ part = &tab->partitions[i]; -+ -+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) -+ continue; -+ -+ num_parts++; -+ } -+ -+ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) + -+ num_parts * PART_NAME_LEN), GFP_KERNEL); -+ -+ if (!mtd_parts) { -+ ret = -ENOMEM; -+ goto out_free_buf; -+ } -+ -+ mtd_part = mtd_parts; -+ names = (char *)&mtd_parts[num_parts]; -+ -+ strncpy(names, "myloader", PART_NAME_LEN); -+ mtd_part->name = names; -+ mtd_part->offset = 0; -+ mtd_part->size = offset; -+ mtd_part->mask_flags = MTD_WRITEABLE; -+ mtd_part++; -+ names += PART_NAME_LEN; -+ -+ strncpy(names, "partition_table", PART_NAME_LEN); -+ mtd_part->name = names; -+ mtd_part->offset = offset; -+ mtd_part->size = blocklen; -+ mtd_part->mask_flags = MTD_WRITEABLE; -+ mtd_part++; -+ names += PART_NAME_LEN; -+ -+ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { -+ part = &tab->partitions[i]; -+ -+ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) -+ continue; -+ -+ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff')) -+ strncpy(names, buf->names[i], PART_NAME_LEN); -+ else -+ snprintf(names, PART_NAME_LEN, "partition%d", i); -+ -+ mtd_part->offset = le32_to_cpu(part->addr); -+ mtd_part->size = le32_to_cpu(part->size); -+ mtd_part->name = names; -+ mtd_part++; -+ names += PART_NAME_LEN; -+ } -+ -+ *pparts = mtd_parts; -+ ret = num_parts; -+ -+ out_free_buf: -+ vfree(buf); -+ out: -+ return ret; -+} -+ -+static struct mtd_part_parser myloader_mtd_parser = { -+ .owner = THIS_MODULE, -+ .parse_fn = myloader_parse_partitions, -+ .name = "MyLoader", -+}; -+ -+static int __init myloader_mtd_parser_init(void) -+{ -+ register_mtd_parser(&myloader_mtd_parser); -+ -+ return 0; -+} -+ -+static void __exit myloader_mtd_parser_exit(void) -+{ -+ deregister_mtd_parser(&myloader_mtd_parser); -+} -+ -+module_init(myloader_mtd_parser_init); -+module_exit(myloader_mtd_parser_exit); -+ -+MODULE_AUTHOR("Gabor Juhos "); -+MODULE_DESCRIPTION("Parsing code for MyLoader partition tables"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/generic/pending-6.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/pending-6.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch deleted file mode 100644 index bcea45d009bb11..00000000000000 --- a/target/linux/generic/pending-6.1/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating offsets - -Signed-off-by: Rafał Miłecki ---- - ---- a/drivers/mtd/parsers/parser_trx.c -+++ b/drivers/mtd/parsers/parser_trx.c -@@ -25,6 +25,33 @@ struct trx_header { - uint32_t offset[3]; - } __packed; - -+/* -+ * Calculate real end offset (address) for a given amount of data. It checks -+ * all blocks skipping bad ones. -+ */ -+static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes) -+{ -+ size_t real_offset = 0; -+ -+ if (mtd_block_isbad(mtd, real_offset)) -+ pr_warn("Base offset shouldn't be at bad block"); -+ -+ while (bytes >= mtd->erasesize) { -+ bytes -= mtd->erasesize; -+ real_offset += mtd->erasesize; -+ while (mtd_block_isbad(mtd, real_offset)) { -+ real_offset += mtd->erasesize; -+ -+ if (real_offset >= mtd->size) -+ return real_offset - mtd->erasesize; -+ } -+ } -+ -+ real_offset += bytes; -+ -+ return real_offset; -+} -+ - static const char *parser_trx_data_part_name(struct mtd_info *master, - size_t offset) - { -@@ -86,21 +113,21 @@ static int parser_trx_parse(struct mtd_i - if (trx.offset[2]) { - part = &parts[curr_part++]; - part->name = "loader"; -- part->offset = trx.offset[i]; -+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); - i++; - } - - if (trx.offset[i]) { - part = &parts[curr_part++]; - part->name = "linux"; -- part->offset = trx.offset[i]; -+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); - i++; - } - - if (trx.offset[i]) { - part = &parts[curr_part++]; -- part->name = parser_trx_data_part_name(mtd, trx.offset[i]); -- part->offset = trx.offset[i]; -+ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); -+ part->name = parser_trx_data_part_name(mtd, part->offset); - i++; - } - diff --git a/target/linux/generic/pending-6.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/pending-6.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch deleted file mode 100644 index 852654d924a8ce..00000000000000 --- a/target/linux/generic/pending-6.1/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: mtd: bcm47xxpart: detect T_Meter partition - -It can be found on many Netgear devices. It consists of many 0x30 blocks -starting with 4D 54. - -Signed-off-by: Rafał Miłecki ---- - drivers/mtd/bcm47xxpart.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/mtd/parsers/bcm47xxpart.c -+++ b/drivers/mtd/parsers/bcm47xxpart.c -@@ -35,6 +35,7 @@ - #define NVRAM_HEADER 0x48534C46 /* FLSH */ - #define POT_MAGIC1 0x54544f50 /* POTT */ - #define POT_MAGIC2 0x504f /* OP */ -+#define T_METER_MAGIC 0x4D540000 /* MT */ - #define ML_MAGIC1 0x39685a42 - #define ML_MAGIC2 0x26594131 - #define TRX_MAGIC 0x30524448 -@@ -178,6 +179,15 @@ static int bcm47xxpart_parse(struct mtd_ - MTD_WRITEABLE); - continue; - } -+ -+ /* T_Meter */ -+ if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC && -+ (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC && -+ (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) { -+ bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset, -+ MTD_WRITEABLE); -+ continue; -+ } - - /* TRX */ - if (buf[0x000 / 4] == TRX_MAGIC) { diff --git a/target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch b/target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch deleted file mode 100644 index a42dcc868f7baf..00000000000000 --- a/target/linux/generic/pending-6.1/435-mtd-add-routerbootpart-parser-config.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= -Date: Tue, 24 Mar 2020 11:45:07 +0100 -Subject: [PATCH] generic: routerboot partition build bits (5.4) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds routerbootpart kernel build bits - -Signed-off-by: Thibaut VARÈNE ---- - drivers/mtd/parsers/Kconfig | 9 +++++++++ - drivers/mtd/parsers/Makefile | 1 + - 2 files changed, 10 insertions(+) - ---- a/drivers/mtd/parsers/Kconfig -+++ b/drivers/mtd/parsers/Kconfig -@@ -236,3 +236,12 @@ config MTD_SERCOMM_PARTS - partition map. This partition table contains real partition - offsets, which may differ from device to device depending on the - number and location of bad blocks on NAND. -+ -+config MTD_ROUTERBOOT_PARTS -+ tristate "RouterBoot flash partition parser" -+ depends on MTD && OF -+ help -+ MikroTik RouterBoot is implemented as a multi segment system on the -+ flash, some of which are fixed and some of which are located at -+ variable offsets. This parser handles both cases via properly -+ formatted DTS. ---- a/drivers/mtd/parsers/Makefile -+++ b/drivers/mtd/parsers/Makefile -@@ -17,3 +17,4 @@ obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpa - obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o - obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o - obj-$(CONFIG_MTD_QCOMSMEM_PARTS) += qcomsmempart.o -+obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o diff --git a/target/linux/generic/pending-6.1/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch b/target/linux/generic/pending-6.1/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch deleted file mode 100644 index 063d3fa79c99cf..00000000000000 --- a/target/linux/generic/pending-6.1/450-01-dt-bindings-mtd-add-basic-bindings-for-UBI.patch +++ /dev/null @@ -1,121 +0,0 @@ -From ffbbe7d66872ff8957dad2136133e28a1fd5d437 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 7 Aug 2023 22:51:05 +0100 -Subject: [PATCH 01/15] dt-bindings: mtd: add basic bindings for UBI - -Add basic bindings for UBI devices and volumes. - -Signed-off-by: Daniel Golle ---- - .../bindings/mtd/partitions/linux,ubi.yaml | 65 +++++++++++++++++++ - .../bindings/mtd/partitions/ubi-volume.yaml | 35 ++++++++++ - 2 files changed, 100 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml - create mode 100644 Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml -@@ -0,0 +1,65 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/mtd/partitions/linux,ubi.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Unsorted Block Images -+ -+description: | -+ UBI ("Unsorted Block Images") is a volume management system for raw -+ flash devices which manages multiple logical volumes on a single -+ physical flash device and spreads the I/O load (i.e wear-leveling) -+ across the whole flash chip. -+ -+maintainers: -+ - Daniel Golle -+ -+allOf: -+ - $ref: partition.yaml# -+ -+properties: -+ compatible: -+ const: linux,ubi -+ -+ volumes: -+ type: object -+ description: UBI Volumes -+ -+ patternProperties: -+ "^ubi-volume-.*$": -+ $ref: /schemas/mtd/partitions/ubi-volume.yaml# -+ -+ unevaluatedProperties: false -+ -+required: -+ - compatible -+ -+unevaluatedProperties: false -+ -+examples: -+ - | -+ partitions { -+ compatible = "fixed-partitions"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ partition@0 { -+ reg = <0x0 0x100000>; -+ label = "bootloader"; -+ read-only; -+ }; -+ -+ partition@100000 { -+ reg = <0x100000 0x1ff00000>; -+ label = "ubi"; -+ compatible = "linux,ubi"; -+ -+ volumes { -+ ubi-volume-caldata { -+ volid = <2>; -+ volname = "rf"; -+ }; -+ }; -+ }; -+ }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml -@@ -0,0 +1,35 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/mtd/partitions/ubi-volume.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: UBI volume -+ -+description: | -+ This binding describes a single UBI volume. Volumes can be matches either -+ by their ID or their name, or both. -+ -+maintainers: -+ - Daniel Golle -+ -+properties: -+ volid: -+ $ref: "/schemas/types.yaml#/definitions/uint32" -+ description: -+ Match UBI volume ID -+ -+ volname: -+ $ref: "/schemas/types.yaml#/definitions/string" -+ description: -+ Match UBI volume ID -+ -+anyOf: -+ - required: -+ - volid -+ -+ - required: -+ - volname -+ -+# This is a generic file other binding inherit from and extend -+additionalProperties: true diff --git a/target/linux/generic/pending-6.1/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch b/target/linux/generic/pending-6.1/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch deleted file mode 100644 index 823c8e83b715ba..00000000000000 --- a/target/linux/generic/pending-6.1/450-02-dt-bindings-mtd-ubi-volume-allow-UBI-volumes-to-prov.patch +++ /dev/null @@ -1,48 +0,0 @@ -From e4dad3aa5c3ab9c553555dd23c0b85f725f2eb51 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 7 Aug 2023 22:53:01 +0100 -Subject: [PATCH 02/15] dt-bindings: mtd: ubi-volume: allow UBI volumes to - provide NVMEM - -UBI volumes may be used to contain NVMEM bits, typically device MAC -addresses or wireless radio calibration data. - -Signed-off-by: Daniel Golle ---- - .../devicetree/bindings/mtd/partitions/linux,ubi.yaml | 10 ++++++++++ - .../devicetree/bindings/mtd/partitions/ubi-volume.yaml | 5 +++++ - 2 files changed, 15 insertions(+) - ---- a/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml -+++ b/Documentation/devicetree/bindings/mtd/partitions/linux,ubi.yaml -@@ -59,6 +59,16 @@ examples: - ubi-volume-caldata { - volid = <2>; - volname = "rf"; -+ -+ nvmem-layout { -+ compatible = "fixed-layout"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ eeprom@0 { -+ reg = <0x0 0x1000>; -+ }; -+ }; - }; - }; - }; ---- a/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml -+++ b/Documentation/devicetree/bindings/mtd/partitions/ubi-volume.yaml -@@ -24,6 +24,11 @@ properties: - description: - Match UBI volume ID - -+ nvmem-layout: -+ $ref: /schemas/nvmem/layouts/nvmem-layout.yaml# -+ description: -+ This container may reference an NVMEM layout parser. -+ - anyOf: - - required: - - volid diff --git a/target/linux/generic/pending-6.1/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch b/target/linux/generic/pending-6.1/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch deleted file mode 100644 index eda3b108da3d9a..00000000000000 --- a/target/linux/generic/pending-6.1/450-03-mtd-ubi-block-use-notifier-to-create-ubiblock-from-p.patch +++ /dev/null @@ -1,225 +0,0 @@ -From e5cf19bd8204925f3bd2067df9e867313eac388b Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 1 May 2023 11:57:51 +0100 -Subject: [PATCH 03/15] mtd: ubi: block: use notifier to create ubiblock from - parameter - -Use UBI_VOLUME_ADDED notification to create ubiblock device specified -on kernel cmdline or module parameter. -This makes thing more simple and has the advantage that ubiblock devices -on volumes which are not present at the time the ubi module is probed -will still be created. - -Suggested-by: Zhihao Cheng -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/block.c | 154 ++++++++++++++++++++++------------------ - 1 file changed, 85 insertions(+), 69 deletions(-) - ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -67,10 +68,10 @@ struct ubiblock_pdu { - }; - - /* Numbers of elements set in the @ubiblock_param array */ --static int ubiblock_devs __initdata; -+static int ubiblock_devs; - - /* MTD devices specification parameters */ --static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES] __initdata; -+static struct ubiblock_param ubiblock_param[UBIBLOCK_MAX_DEVICES]; - - struct ubiblock { - struct ubi_volume_desc *desc; -@@ -504,7 +505,7 @@ int ubiblock_remove(struct ubi_volume_in - } - - /* Found a device, let's lock it so we can check if it's busy */ -- mutex_lock(&dev->dev_mutex); -+ mutex_lock_nested(&dev->dev_mutex, SINGLE_DEPTH_NESTING); - if (dev->refcnt > 0) { - ret = -EBUSY; - goto out_unlock_dev; -@@ -567,6 +568,85 @@ static int ubiblock_resize(struct ubi_vo - return 0; - } - -+static bool -+match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int vol_id) -+{ -+ int err, len; -+ struct path path; -+ struct kstat stat; -+ -+ if (ubi_num == -1) { -+ /* No ubi num, name must be a vol device path */ -+ err = kern_path(name, LOOKUP_FOLLOW, &path); -+ if (err) -+ return false; -+ -+ err = vfs_getattr(&path, &stat, STATX_TYPE, AT_STATX_SYNC_AS_STAT); -+ path_put(&path); -+ if (err) -+ return false; -+ -+ if (!S_ISCHR(stat.mode)) -+ return false; -+ -+ if (vi->ubi_num != ubi_major2num(MAJOR(stat.rdev))) -+ return false; -+ -+ if (vi->vol_id != MINOR(stat.rdev) - 1) -+ return false; -+ -+ return true; -+ } -+ -+ if (vol_id == -1) { -+ if (vi->ubi_num != ubi_num) -+ return false; -+ -+ len = strnlen(name, UBI_VOL_NAME_MAX + 1); -+ if (len < 1 || vi->name_len != len) -+ return false; -+ -+ if (strcmp(name, vi->name)) -+ return false; -+ -+ return true; -+ } -+ -+ if (vi->ubi_num != ubi_num) -+ return false; -+ -+ if (vi->vol_id != vol_id) -+ return false; -+ -+ return true; -+} -+ -+static void -+ubiblock_create_from_param(struct ubi_volume_info *vi) -+{ -+ int i, ret = 0; -+ struct ubiblock_param *p; -+ -+ /* -+ * Iterate over ubiblock cmdline parameters. If a parameter matches the -+ * newly added volume create the ubiblock device for it. -+ */ -+ for (i = 0; i < ubiblock_devs; i++) { -+ p = &ubiblock_param[i]; -+ -+ if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id)) -+ continue; -+ -+ ret = ubiblock_create(vi); -+ if (ret) { -+ pr_err( -+ "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d\n", -+ vi->name, p->ubi_num, p->vol_id, ret); -+ } -+ break; -+ } -+} -+ - static int ubiblock_notify(struct notifier_block *nb, - unsigned long notification_type, void *ns_ptr) - { -@@ -574,10 +654,7 @@ static int ubiblock_notify(struct notifi - - switch (notification_type) { - case UBI_VOLUME_ADDED: -- /* -- * We want to enforce explicit block device creation for -- * volumes, so when a volume is added we do nothing. -- */ -+ ubiblock_create_from_param(&nt->vi); - break; - case UBI_VOLUME_REMOVED: - ubiblock_remove(&nt->vi); -@@ -603,56 +680,6 @@ static struct notifier_block ubiblock_no - .notifier_call = ubiblock_notify, - }; - --static struct ubi_volume_desc * __init --open_volume_desc(const char *name, int ubi_num, int vol_id) --{ -- if (ubi_num == -1) -- /* No ubi num, name must be a vol device path */ -- return ubi_open_volume_path(name, UBI_READONLY); -- else if (vol_id == -1) -- /* No vol_id, must be vol_name */ -- return ubi_open_volume_nm(ubi_num, name, UBI_READONLY); -- else -- return ubi_open_volume(ubi_num, vol_id, UBI_READONLY); --} -- --static void __init ubiblock_create_from_param(void) --{ -- int i, ret = 0; -- struct ubiblock_param *p; -- struct ubi_volume_desc *desc; -- struct ubi_volume_info vi; -- -- /* -- * If there is an error creating one of the ubiblocks, continue on to -- * create the following ubiblocks. This helps in a circumstance where -- * the kernel command-line specifies multiple block devices and some -- * may be broken, but we still want the working ones to come up. -- */ -- for (i = 0; i < ubiblock_devs; i++) { -- p = &ubiblock_param[i]; -- -- desc = open_volume_desc(p->name, p->ubi_num, p->vol_id); -- if (IS_ERR(desc)) { -- pr_err( -- "UBI: block: can't open volume on ubi%d_%d, err=%ld\n", -- p->ubi_num, p->vol_id, PTR_ERR(desc)); -- continue; -- } -- -- ubi_get_volume_info(desc, &vi); -- ubi_close_volume(desc); -- -- ret = ubiblock_create(&vi); -- if (ret) { -- pr_err( -- "UBI: block: can't add '%s' volume on ubi%d_%d, err=%d\n", -- vi.name, p->ubi_num, p->vol_id, ret); -- continue; -- } -- } --} -- - static void ubiblock_remove_all(void) - { - struct ubiblock *next; -@@ -678,18 +705,7 @@ int __init ubiblock_init(void) - if (ubiblock_major < 0) - return ubiblock_major; - -- /* -- * Attach block devices from 'block=' module param. -- * Even if one block device in the param list fails to come up, -- * still allow the module to load and leave any others up. -- */ -- ubiblock_create_from_param(); -- -- /* -- * Block devices are only created upon user requests, so we ignore -- * existing volumes. -- */ -- ret = ubi_register_volume_notifier(&ubiblock_notifier, 1); -+ ret = ubi_register_volume_notifier(&ubiblock_notifier, 0); - if (ret) - goto err_unreg; - return 0; diff --git a/target/linux/generic/pending-6.1/450-04-mtd-ubi-attach-from-device-tree.patch b/target/linux/generic/pending-6.1/450-04-mtd-ubi-attach-from-device-tree.patch deleted file mode 100644 index 6e10e5ebed401e..00000000000000 --- a/target/linux/generic/pending-6.1/450-04-mtd-ubi-attach-from-device-tree.patch +++ /dev/null @@ -1,264 +0,0 @@ -From 471a17d8d1b838092d1a76e48cdce8b5b67ff809 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 27 Nov 2023 01:54:28 +0000 -Subject: [PATCH 04/15] mtd: ubi: attach from device tree - -Introduce device tree compatible 'linux,ubi' and attach compatible MTD -devices using the MTD add notifier. This is needed for a UBI device to -be available early at boot (and not only after late_initcall), so -volumes on them can be used eg. as NVMEM providers for other drivers. - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/build.c | 146 ++++++++++++++++++++++++++++------------ - drivers/mtd/ubi/cdev.c | 2 +- - drivers/mtd/ubi/ubi.h | 2 +- - 3 files changed, 106 insertions(+), 44 deletions(-) - ---- a/drivers/mtd/ubi/build.c -+++ b/drivers/mtd/ubi/build.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include - #include - #include "ubi.h" -@@ -1071,6 +1072,7 @@ out_free: - * ubi_detach_mtd_dev - detach an MTD device. - * @ubi_num: UBI device number to detach from - * @anyway: detach MTD even if device reference count is not zero -+ * @have_lock: called by MTD notifier holding mtd_table_mutex - * - * This function destroys an UBI device number @ubi_num and detaches the - * underlying MTD device. Returns zero in case of success and %-EBUSY if the -@@ -1080,7 +1082,7 @@ out_free: - * Note, the invocations of this function has to be serialized by the - * @ubi_devices_mutex. - */ --int ubi_detach_mtd_dev(int ubi_num, int anyway) -+int ubi_detach_mtd_dev(int ubi_num, int anyway, bool have_lock) - { - struct ubi_device *ubi; - -@@ -1136,7 +1138,11 @@ int ubi_detach_mtd_dev(int ubi_num, int - vfree(ubi->peb_buf); - vfree(ubi->fm_buf); - ubi_msg(ubi, "mtd%d is detached", ubi->mtd->index); -- put_mtd_device(ubi->mtd); -+ if (have_lock) -+ __put_mtd_device(ubi->mtd); -+ else -+ put_mtd_device(ubi->mtd); -+ - put_device(&ubi->dev); - return 0; - } -@@ -1213,43 +1219,43 @@ static struct mtd_info * __init open_mtd - return mtd; - } - --static int __init ubi_init(void) -+static void ubi_notify_add(struct mtd_info *mtd) - { -- int err, i, k; -+ struct device_node *np = mtd_get_of_node(mtd); -+ int err; - -- /* Ensure that EC and VID headers have correct size */ -- BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64); -- BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); -+ if (!of_device_is_compatible(np, "linux,ubi")) -+ return; - -- if (mtd_devs > UBI_MAX_DEVICES) { -- pr_err("UBI error: too many MTD devices, maximum is %d\n", -- UBI_MAX_DEVICES); -- return -EINVAL; -- } -+ /* -+ * we are already holding &mtd_table_mutex, but still need -+ * to bump refcount -+ */ -+ err = __get_mtd_device(mtd); -+ if (err) -+ return; - -- /* Create base sysfs directory and sysfs files */ -- err = class_register(&ubi_class); -+ /* called while holding mtd_table_mutex */ -+ mutex_lock_nested(&ubi_devices_mutex, SINGLE_DEPTH_NESTING); -+ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false); -+ mutex_unlock(&ubi_devices_mutex); - if (err < 0) -- return err; -- -- err = misc_register(&ubi_ctrl_cdev); -- if (err) { -- pr_err("UBI error: cannot register device\n"); -- goto out; -- } -+ __put_mtd_device(mtd); -+} - -- ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", -- sizeof(struct ubi_wl_entry), -- 0, 0, NULL); -- if (!ubi_wl_entry_slab) { -- err = -ENOMEM; -- goto out_dev_unreg; -- } -+static void ubi_notify_remove(struct mtd_info *mtd) -+{ -+ WARN(1, "mtd%d removed despite UBI still being attached", mtd->index); -+} - -- err = ubi_debugfs_init(); -- if (err) -- goto out_slab; -+static struct mtd_notifier ubi_mtd_notifier = { -+ .add = ubi_notify_add, -+ .remove = ubi_notify_remove, -+}; - -+static int __init ubi_init_attach(void) -+{ -+ int err, i, k; - - /* Attach MTD devices */ - for (i = 0; i < mtd_devs; i++) { -@@ -1297,25 +1303,79 @@ static int __init ubi_init(void) - } - } - -+ return 0; -+ -+out_detach: -+ for (k = 0; k < i; k++) -+ if (ubi_devices[k]) { -+ mutex_lock(&ubi_devices_mutex); -+ ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1, false); -+ mutex_unlock(&ubi_devices_mutex); -+ } -+ return err; -+} -+#ifndef CONFIG_MTD_UBI_MODULE -+late_initcall(ubi_init_attach); -+#endif -+ -+static int __init ubi_init(void) -+{ -+ int err; -+ -+ /* Ensure that EC and VID headers have correct size */ -+ BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64); -+ BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); -+ -+ if (mtd_devs > UBI_MAX_DEVICES) { -+ pr_err("UBI error: too many MTD devices, maximum is %d\n", -+ UBI_MAX_DEVICES); -+ return -EINVAL; -+ } -+ -+ /* Create base sysfs directory and sysfs files */ -+ err = class_register(&ubi_class); -+ if (err < 0) -+ return err; -+ -+ err = misc_register(&ubi_ctrl_cdev); -+ if (err) { -+ pr_err("UBI error: cannot register device\n"); -+ goto out; -+ } -+ -+ ubi_wl_entry_slab = kmem_cache_create("ubi_wl_entry_slab", -+ sizeof(struct ubi_wl_entry), -+ 0, 0, NULL); -+ if (!ubi_wl_entry_slab) { -+ err = -ENOMEM; -+ goto out_dev_unreg; -+ } -+ -+ err = ubi_debugfs_init(); -+ if (err) -+ goto out_slab; -+ - err = ubiblock_init(); - if (err) { - pr_err("UBI error: block: cannot initialize, error %d\n", err); - - /* See comment above re-ubi_is_module(). */ - if (ubi_is_module()) -- goto out_detach; -+ goto out_slab; -+ } -+ -+ register_mtd_user(&ubi_mtd_notifier); -+ -+ if (ubi_is_module()) { -+ err = ubi_init_attach(); -+ if (err) -+ goto out_mtd_notifier; - } - - return 0; - --out_detach: -- for (k = 0; k < i; k++) -- if (ubi_devices[k]) { -- mutex_lock(&ubi_devices_mutex); -- ubi_detach_mtd_dev(ubi_devices[k]->ubi_num, 1); -- mutex_unlock(&ubi_devices_mutex); -- } -- ubi_debugfs_exit(); -+out_mtd_notifier: -+ unregister_mtd_user(&ubi_mtd_notifier); - out_slab: - kmem_cache_destroy(ubi_wl_entry_slab); - out_dev_unreg: -@@ -1325,18 +1385,20 @@ out: - pr_err("UBI error: cannot initialize UBI, error %d\n", err); - return err; - } --late_initcall(ubi_init); -+device_initcall(ubi_init); -+ - - static void __exit ubi_exit(void) - { - int i; - - ubiblock_exit(); -+ unregister_mtd_user(&ubi_mtd_notifier); - - for (i = 0; i < UBI_MAX_DEVICES; i++) - if (ubi_devices[i]) { - mutex_lock(&ubi_devices_mutex); -- ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1); -+ ubi_detach_mtd_dev(ubi_devices[i]->ubi_num, 1, false); - mutex_unlock(&ubi_devices_mutex); - } - ubi_debugfs_exit(); ---- a/drivers/mtd/ubi/cdev.c -+++ b/drivers/mtd/ubi/cdev.c -@@ -1065,7 +1065,7 @@ static long ctrl_cdev_ioctl(struct file - } - - mutex_lock(&ubi_devices_mutex); -- err = ubi_detach_mtd_dev(ubi_num, 0); -+ err = ubi_detach_mtd_dev(ubi_num, 0, false); - mutex_unlock(&ubi_devices_mutex); - break; - } ---- a/drivers/mtd/ubi/ubi.h -+++ b/drivers/mtd/ubi/ubi.h -@@ -939,7 +939,7 @@ int ubi_io_write_vid_hdr(struct ubi_devi - int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, - int vid_hdr_offset, int max_beb_per1024, - bool disable_fm); --int ubi_detach_mtd_dev(int ubi_num, int anyway); -+int ubi_detach_mtd_dev(int ubi_num, int anyway, bool have_lock); - struct ubi_device *ubi_get_device(int ubi_num); - void ubi_put_device(struct ubi_device *ubi); - struct ubi_device *ubi_get_by_major(int major); diff --git a/target/linux/generic/pending-6.1/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch b/target/linux/generic/pending-6.1/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch deleted file mode 100644 index d5da37b8562eda..00000000000000 --- a/target/linux/generic/pending-6.1/450-05-mtd-ubi-introduce-pre-removal-notification-for-UBI-v.patch +++ /dev/null @@ -1,226 +0,0 @@ -From 2d664266cfdd114cc7a1fa28dd64275e99222455 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 8 Jun 2023 17:18:09 +0100 -Subject: [PATCH 05/15] mtd: ubi: introduce pre-removal notification for UBI - volumes - -Introduce a new notification type UBI_VOLUME_SHUTDOWN to inform users -that a volume is just about to be removed. -This is needed because users (such as the NVMEM subsystem) expect that -at the time their removal function is called, the parenting device is -still available (for removal of sysfs nodes, for example, in case of -NVMEM which otherwise WARNs on volume removal). - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/block.c | 26 ++++++++++++++++++++++++++ - drivers/mtd/ubi/build.c | 20 +++++++++++++++----- - drivers/mtd/ubi/kapi.c | 2 +- - drivers/mtd/ubi/ubi.h | 2 ++ - drivers/mtd/ubi/vmt.c | 17 +++++++++++++++-- - include/linux/mtd/ubi.h | 2 ++ - 6 files changed, 61 insertions(+), 8 deletions(-) - ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -568,6 +568,29 @@ static int ubiblock_resize(struct ubi_vo - return 0; - } - -+static int ubiblock_shutdown(struct ubi_volume_info *vi) -+{ -+ struct ubiblock *dev; -+ struct gendisk *disk; -+ int ret = 0; -+ -+ mutex_lock(&devices_mutex); -+ dev = find_dev_nolock(vi->ubi_num, vi->vol_id); -+ if (!dev) { -+ ret = -ENODEV; -+ goto out_unlock; -+ } -+ disk = dev->gd; -+ -+out_unlock: -+ mutex_unlock(&devices_mutex); -+ -+ if (!ret) -+ blk_mark_disk_dead(disk); -+ -+ return ret; -+}; -+ - static bool - match_volume_desc(struct ubi_volume_info *vi, const char *name, int ubi_num, int vol_id) - { -@@ -659,6 +682,9 @@ static int ubiblock_notify(struct notifi - case UBI_VOLUME_REMOVED: - ubiblock_remove(&nt->vi); - break; -+ case UBI_VOLUME_SHUTDOWN: -+ ubiblock_shutdown(&nt->vi); -+ break; - case UBI_VOLUME_RESIZED: - ubiblock_resize(&nt->vi); - break; ---- a/drivers/mtd/ubi/build.c -+++ b/drivers/mtd/ubi/build.c -@@ -89,7 +89,7 @@ static struct ubi_device *ubi_devices[UB - /* Serializes UBI devices creations and removals */ - DEFINE_MUTEX(ubi_devices_mutex); - --/* Protects @ubi_devices and @ubi->ref_count */ -+/* Protects @ubi_devices, @ubi->ref_count and @ubi->is_dead */ - static DEFINE_SPINLOCK(ubi_devices_lock); - - /* "Show" method for files in '//class/ubi/' */ -@@ -258,6 +258,9 @@ struct ubi_device *ubi_get_device(int ub - - spin_lock(&ubi_devices_lock); - ubi = ubi_devices[ubi_num]; -+ if (ubi && ubi->is_dead) -+ ubi = NULL; -+ - if (ubi) { - ubi_assert(ubi->ref_count >= 0); - ubi->ref_count += 1; -@@ -295,7 +298,7 @@ struct ubi_device *ubi_get_by_major(int - spin_lock(&ubi_devices_lock); - for (i = 0; i < UBI_MAX_DEVICES; i++) { - ubi = ubi_devices[i]; -- if (ubi && MAJOR(ubi->cdev.dev) == major) { -+ if (ubi && !ubi->is_dead && MAJOR(ubi->cdev.dev) == major) { - ubi_assert(ubi->ref_count >= 0); - ubi->ref_count += 1; - get_device(&ubi->dev); -@@ -324,7 +327,7 @@ int ubi_major2num(int major) - for (i = 0; i < UBI_MAX_DEVICES; i++) { - struct ubi_device *ubi = ubi_devices[i]; - -- if (ubi && MAJOR(ubi->cdev.dev) == major) { -+ if (ubi && !ubi->is_dead && MAJOR(ubi->cdev.dev) == major) { - ubi_num = ubi->ubi_num; - break; - } -@@ -511,7 +514,7 @@ static void ubi_free_volumes_from(struct - int i; - - for (i = from; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { -- if (!ubi->volumes[i]) -+ if (!ubi->volumes[i] || ubi->volumes[i]->is_dead) - continue; - ubi_eba_replace_table(ubi->volumes[i], NULL); - ubi_fastmap_destroy_checkmap(ubi->volumes[i]); -@@ -1094,10 +1097,10 @@ int ubi_detach_mtd_dev(int ubi_num, int - return -EINVAL; - - spin_lock(&ubi_devices_lock); -- put_device(&ubi->dev); - ubi->ref_count -= 1; - if (ubi->ref_count) { - if (!anyway) { -+ ubi->ref_count += 1; - spin_unlock(&ubi_devices_lock); - return -EBUSY; - } -@@ -1105,6 +1108,13 @@ int ubi_detach_mtd_dev(int ubi_num, int - ubi_err(ubi, "%s reference count %d, destroy anyway", - ubi->ubi_name, ubi->ref_count); - } -+ ubi->is_dead = true; -+ spin_unlock(&ubi_devices_lock); -+ -+ ubi_notify_all(ubi, UBI_VOLUME_SHUTDOWN, NULL); -+ -+ spin_lock(&ubi_devices_lock); -+ put_device(&ubi->dev); - ubi_devices[ubi_num] = NULL; - spin_unlock(&ubi_devices_lock); - ---- a/drivers/mtd/ubi/kapi.c -+++ b/drivers/mtd/ubi/kapi.c -@@ -152,7 +152,7 @@ struct ubi_volume_desc *ubi_open_volume( - - spin_lock(&ubi->volumes_lock); - vol = ubi->volumes[vol_id]; -- if (!vol) -+ if (!vol || vol->is_dead) - goto out_unlock; - - err = -EBUSY; ---- a/drivers/mtd/ubi/ubi.h -+++ b/drivers/mtd/ubi/ubi.h -@@ -345,6 +345,7 @@ struct ubi_volume { - int writers; - int exclusive; - int metaonly; -+ bool is_dead; - - int reserved_pebs; - int vol_type; -@@ -564,6 +565,7 @@ struct ubi_device { - spinlock_t volumes_lock; - int ref_count; - int image_seq; -+ bool is_dead; - - int rsvd_pebs; - int avail_pebs; ---- a/drivers/mtd/ubi/vmt.c -+++ b/drivers/mtd/ubi/vmt.c -@@ -59,7 +59,7 @@ static ssize_t vol_attribute_show(struct - struct ubi_device *ubi = vol->ubi; - - spin_lock(&ubi->volumes_lock); -- if (!ubi->volumes[vol->vol_id]) { -+ if (!ubi->volumes[vol->vol_id] || ubi->volumes[vol->vol_id]->is_dead) { - spin_unlock(&ubi->volumes_lock); - return -ENODEV; - } -@@ -189,7 +189,7 @@ int ubi_create_volume(struct ubi_device - - /* Ensure that the name is unique */ - for (i = 0; i < ubi->vtbl_slots; i++) -- if (ubi->volumes[i] && -+ if (ubi->volumes[i] && !ubi->volumes[i]->is_dead && - ubi->volumes[i]->name_len == req->name_len && - !strcmp(ubi->volumes[i]->name, req->name)) { - ubi_err(ubi, "volume \"%s\" exists (ID %d)", -@@ -352,6 +352,19 @@ int ubi_remove_volume(struct ubi_volume_ - err = -EBUSY; - goto out_unlock; - } -+ -+ /* -+ * Mark volume as dead at this point to prevent that anyone -+ * can take a reference to the volume from now on. -+ * This is necessary as we have to release the spinlock before -+ * calling ubi_volume_notify. -+ */ -+ vol->is_dead = true; -+ spin_unlock(&ubi->volumes_lock); -+ -+ ubi_volume_notify(ubi, vol, UBI_VOLUME_SHUTDOWN); -+ -+ spin_lock(&ubi->volumes_lock); - ubi->volumes[vol_id] = NULL; - spin_unlock(&ubi->volumes_lock); - ---- a/include/linux/mtd/ubi.h -+++ b/include/linux/mtd/ubi.h -@@ -192,6 +192,7 @@ struct ubi_device_info { - * or a volume was removed) - * @UBI_VOLUME_RESIZED: a volume has been re-sized - * @UBI_VOLUME_RENAMED: a volume has been re-named -+ * @UBI_VOLUME_SHUTDOWN: a volume is going to removed, shutdown users - * @UBI_VOLUME_UPDATED: data has been written to a volume - * - * These constants define which type of event has happened when a volume -@@ -202,6 +203,7 @@ enum { - UBI_VOLUME_REMOVED, - UBI_VOLUME_RESIZED, - UBI_VOLUME_RENAMED, -+ UBI_VOLUME_SHUTDOWN, - UBI_VOLUME_UPDATED, - }; - diff --git a/target/linux/generic/pending-6.1/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch b/target/linux/generic/pending-6.1/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch deleted file mode 100644 index 132276696547c3..00000000000000 --- a/target/linux/generic/pending-6.1/450-06-mtd-ubi-populate-ubi-volume-fwnode.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 3a041ee543cdf2e707a1dd72946cd6a583509b28 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 21 Jul 2023 19:26:37 +0100 -Subject: [PATCH 06/15] mtd: ubi: populate ubi volume fwnode - -Look for the 'volumes' subnode of an MTD partition attached to a UBI -device and attach matching child nodes to UBI volumes. -This allows UBI volumes to be referenced in device tree, e.g. for use -as NVMEM providers. - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/vmt.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - ---- a/drivers/mtd/ubi/vmt.c -+++ b/drivers/mtd/ubi/vmt.c -@@ -124,6 +124,31 @@ static void vol_release(struct device *d - kfree(vol); - } - -+static struct fwnode_handle *find_volume_fwnode(struct ubi_volume *vol) -+{ -+ struct fwnode_handle *fw_vols, *fw_vol; -+ const char *volname; -+ u32 volid; -+ -+ fw_vols = device_get_named_child_node(vol->dev.parent->parent, "volumes"); -+ if (!fw_vols) -+ return NULL; -+ -+ fwnode_for_each_child_node(fw_vols, fw_vol) { -+ if (!fwnode_property_read_string(fw_vol, "volname", &volname) && -+ strncmp(volname, vol->name, vol->name_len)) -+ continue; -+ -+ if (!fwnode_property_read_u32(fw_vol, "volid", &volid) && -+ vol->vol_id != volid) -+ continue; -+ -+ return fw_vol; -+ } -+ -+ return NULL; -+} -+ - /** - * ubi_create_volume - create volume. - * @ubi: UBI device description object -@@ -223,6 +248,7 @@ int ubi_create_volume(struct ubi_device - vol->name_len = req->name_len; - memcpy(vol->name, req->name, vol->name_len); - vol->ubi = ubi; -+ device_set_node(&vol->dev, find_volume_fwnode(vol)); - - /* - * Finish all pending erases because there may be some LEBs belonging -@@ -605,6 +631,7 @@ int ubi_add_volume(struct ubi_device *ub - vol->dev.class = &ubi_class; - vol->dev.groups = volume_dev_groups; - dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id); -+ device_set_node(&vol->dev, find_volume_fwnode(vol)); - err = device_register(&vol->dev); - if (err) { - cdev_del(&vol->cdev); diff --git a/target/linux/generic/pending-6.1/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch b/target/linux/generic/pending-6.1/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch deleted file mode 100644 index 59a1eb9374ea62..00000000000000 --- a/target/linux/generic/pending-6.1/450-07-mtd-ubi-provide-NVMEM-layer-over-UBI-volumes.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 7eb6666348f3f2d1f7308c712fa5903cbe189401 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 8 Jun 2023 17:22:04 +0100 -Subject: [PATCH 07/15] mtd: ubi: provide NVMEM layer over UBI volumes - -In an ideal world we would like UBI to be used where ever possible on a -NAND chip. And with UBI support in ARM Trusted Firmware and U-Boot it -is possible to achieve an (almost-)all-UBI flash layout. Hence the need -for a way to also use UBI volumes to store board-level constants, such -as MAC addresses and calibration data of wireless interfaces. - -Add UBI volume NVMEM driver module exposing UBI volumes as NVMEM -providers. Allow UBI devices to have a "volumes" firmware subnode with -volumes which may be compatible with "nvmem-cells". -Access to UBI volumes via the NVMEM interface at this point is -read-only, and it is slow, opening and closing the UBI volume for each -access due to limitations of the NVMEM provider API. - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/Kconfig | 12 +++ - drivers/mtd/ubi/Makefile | 1 + - drivers/mtd/ubi/nvmem.c | 188 +++++++++++++++++++++++++++++++++++++++ - 3 files changed, 201 insertions(+) - create mode 100644 drivers/mtd/ubi/nvmem.c - ---- a/drivers/mtd/ubi/Kconfig -+++ b/drivers/mtd/ubi/Kconfig -@@ -104,4 +104,16 @@ config MTD_UBI_BLOCK - - If in doubt, say "N". - -+config MTD_UBI_NVMEM -+ tristate "UBI virtual NVMEM" -+ default n -+ depends on NVMEM -+ help -+ This option enabled an additional driver exposing UBI volumes as NVMEM -+ providers, intended for platforms where UBI is part of the firmware -+ specification and used to store also e.g. MAC addresses or board- -+ specific Wi-Fi calibration data. -+ -+ If in doubt, say "N". -+ - endif # MTD_UBI ---- a/drivers/mtd/ubi/Makefile -+++ b/drivers/mtd/ubi/Makefile -@@ -7,3 +7,4 @@ ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap - ubi-$(CONFIG_MTD_UBI_BLOCK) += block.o - - obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o -+obj-$(CONFIG_MTD_UBI_NVMEM) += nvmem.o ---- /dev/null -+++ b/drivers/mtd/ubi/nvmem.c -@@ -0,0 +1,191 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (c) 2023 Daniel Golle -+ */ -+ -+/* UBI NVMEM provider */ -+#include "ubi.h" -+#include -+#include -+ -+/* List of all NVMEM devices */ -+static LIST_HEAD(nvmem_devices); -+static DEFINE_MUTEX(devices_mutex); -+ -+struct ubi_nvmem { -+ struct nvmem_device *nvmem; -+ int ubi_num; -+ int vol_id; -+ int usable_leb_size; -+ struct list_head list; -+}; -+ -+static int ubi_nvmem_reg_read(void *priv, unsigned int from, -+ void *val, size_t bytes) -+{ -+ uint32_t offs, to_read, bytes_left; -+ struct ubi_nvmem *unv = priv; -+ struct ubi_volume_desc *desc; -+ uint64_t lnum = from; -+ int err = 0; -+ -+ desc = ubi_open_volume(unv->ubi_num, unv->vol_id, UBI_READONLY); -+ if (IS_ERR(desc)) -+ return PTR_ERR(desc); -+ -+ bytes_left = bytes; -+ offs = do_div(lnum, unv->usable_leb_size); -+ while (bytes_left) { -+ to_read = unv->usable_leb_size - offs; -+ -+ if (to_read > bytes_left) -+ to_read = bytes_left; -+ -+ err = ubi_read(desc, lnum, val, offs, to_read); -+ if (err) -+ break; -+ -+ lnum += 1; -+ offs = 0; -+ bytes_left -= to_read; -+ val += to_read; -+ } -+ ubi_close_volume(desc); -+ -+ if (err) -+ return err; -+ -+ return bytes_left == 0 ? 0 : -EIO; -+} -+ -+static int ubi_nvmem_add(struct ubi_volume_info *vi) -+{ -+ struct device_node *np = dev_of_node(vi->dev); -+ struct nvmem_config config = {}; -+ struct ubi_nvmem *unv; -+ int ret; -+ -+ if (!np) -+ return 0; -+ -+ if (!of_get_child_by_name(np, "nvmem-layout")) -+ return 0; -+ -+ if (WARN_ON_ONCE(vi->usable_leb_size <= 0) || -+ WARN_ON_ONCE(vi->size <= 0)) -+ return -EINVAL; -+ -+ unv = kzalloc(sizeof(struct ubi_nvmem), GFP_KERNEL); -+ if (!unv) -+ return -ENOMEM; -+ -+ config.id = NVMEM_DEVID_NONE; -+ config.dev = vi->dev; -+ config.name = dev_name(vi->dev); -+ config.owner = THIS_MODULE; -+ config.priv = unv; -+ config.reg_read = ubi_nvmem_reg_read; -+ config.size = vi->usable_leb_size * vi->size; -+ config.word_size = 1; -+ config.stride = 1; -+ config.read_only = true; -+ config.root_only = true; -+ config.ignore_wp = true; -+ config.of_node = np; -+ -+ unv->ubi_num = vi->ubi_num; -+ unv->vol_id = vi->vol_id; -+ unv->usable_leb_size = vi->usable_leb_size; -+ unv->nvmem = nvmem_register(&config); -+ if (IS_ERR(unv->nvmem)) { -+ ret = dev_err_probe(vi->dev, PTR_ERR(unv->nvmem), -+ "Failed to register NVMEM device\n"); -+ kfree(unv); -+ return ret; -+ } -+ -+ mutex_lock(&devices_mutex); -+ list_add_tail(&unv->list, &nvmem_devices); -+ mutex_unlock(&devices_mutex); -+ -+ return 0; -+} -+ -+static void ubi_nvmem_remove(struct ubi_volume_info *vi) -+{ -+ struct ubi_nvmem *unv_c, *unv = NULL; -+ -+ mutex_lock(&devices_mutex); -+ list_for_each_entry(unv_c, &nvmem_devices, list) -+ if (unv_c->ubi_num == vi->ubi_num && unv_c->vol_id == vi->vol_id) { -+ unv = unv_c; -+ break; -+ } -+ -+ if (!unv) { -+ mutex_unlock(&devices_mutex); -+ return; -+ } -+ -+ list_del(&unv->list); -+ mutex_unlock(&devices_mutex); -+ nvmem_unregister(unv->nvmem); -+ kfree(unv); -+} -+ -+/** -+ * nvmem_notify - UBI notification handler. -+ * @nb: registered notifier block -+ * @l: notification type -+ * @ns_ptr: pointer to the &struct ubi_notification object -+ */ -+static int nvmem_notify(struct notifier_block *nb, unsigned long l, -+ void *ns_ptr) -+{ -+ struct ubi_notification *nt = ns_ptr; -+ -+ switch (l) { -+ case UBI_VOLUME_RESIZED: -+ ubi_nvmem_remove(&nt->vi); -+ fallthrough; -+ case UBI_VOLUME_ADDED: -+ ubi_nvmem_add(&nt->vi); -+ break; -+ case UBI_VOLUME_SHUTDOWN: -+ ubi_nvmem_remove(&nt->vi); -+ break; -+ default: -+ break; -+ } -+ return NOTIFY_OK; -+} -+ -+static struct notifier_block nvmem_notifier = { -+ .notifier_call = nvmem_notify, -+}; -+ -+static int __init ubi_nvmem_init(void) -+{ -+ return ubi_register_volume_notifier(&nvmem_notifier, 0); -+} -+ -+static void __exit ubi_nvmem_exit(void) -+{ -+ struct ubi_nvmem *unv, *tmp; -+ -+ mutex_lock(&devices_mutex); -+ list_for_each_entry_safe(unv, tmp, &nvmem_devices, list) { -+ nvmem_unregister(unv->nvmem); -+ list_del(&unv->list); -+ kfree(unv); -+ } -+ mutex_unlock(&devices_mutex); -+ -+ ubi_unregister_volume_notifier(&nvmem_notifier); -+} -+ -+module_init(ubi_nvmem_init); -+module_exit(ubi_nvmem_exit); -+MODULE_DESCRIPTION("NVMEM layer over UBI volumes"); -+MODULE_AUTHOR("Daniel Golle"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/pending-6.1/450-08-dt-bindings-block-add-basic-bindings-for-block-devic.patch b/target/linux/generic/pending-6.1/450-08-dt-bindings-block-add-basic-bindings-for-block-devic.patch deleted file mode 100644 index d0727faf3dc195..00000000000000 --- a/target/linux/generic/pending-6.1/450-08-dt-bindings-block-add-basic-bindings-for-block-devic.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 9ffc1d7d73609a89eb264d6066340f8b7b3b0ebe Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 7 Aug 2023 21:19:45 +0100 -Subject: [PATCH 08/15] dt-bindings: block: add basic bindings for block - devices - -Add bindings for block devices which are used to allow referencing -nvmem bits on them. - -Signed-off-by: Daniel Golle ---- - .../bindings/block/block-device.yaml | 22 ++++++++ - .../devicetree/bindings/block/partition.yaml | 50 +++++++++++++++++++ - .../devicetree/bindings/block/partitions.yaml | 20 ++++++++ - 3 files changed, 92 insertions(+) - create mode 100644 Documentation/devicetree/bindings/block/block-device.yaml - create mode 100644 Documentation/devicetree/bindings/block/partition.yaml - create mode 100644 Documentation/devicetree/bindings/block/partitions.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/block/block-device.yaml -@@ -0,0 +1,22 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/block/block-device.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: block storage device -+ -+description: | -+ This binding is generic and describes a block-oriented storage device. -+ -+maintainers: -+ - Daniel Golle -+ -+properties: -+ partitions: -+ $ref: /schemas/block/partitions.yaml -+ -+ nvmem-layout: -+ $ref: /schemas/nvmem/layouts/nvmem-layout.yaml# -+ -+unevaluatedProperties: false ---- /dev/null -+++ b/Documentation/devicetree/bindings/block/partition.yaml -@@ -0,0 +1,50 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/block/partition.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Partition on a block device -+ -+description: | -+ This binding describes a partition on a block device. -+ Partitions may be matched by a combination of partition number, name, -+ and UUID. -+ -+maintainers: -+ - Daniel Golle -+ -+properties: -+ $nodename: -+ pattern: '^block-partition-.+$' -+ -+ partnum: -+ description: -+ Matches partition by number if present. -+ -+ partname: -+ "$ref": "/schemas/types.yaml#/definitions/string" -+ description: -+ Matches partition by PARTNAME if present. -+ -+ uuid: -+ "$ref": "/schemas/types.yaml#/definitions/string" -+ description: -+ Matches partition by PARTUUID if present. -+ -+ nvmem-layout: -+ $ref: /schemas/nvmem/layouts/nvmem-layout.yaml# -+ description: -+ This container may reference an NVMEM layout parser. -+ -+anyOf: -+ - required: -+ - partnum -+ -+ - required: -+ - partname -+ -+ - required: -+ - uuid -+ -+unevaluatedProperties: false ---- /dev/null -+++ b/Documentation/devicetree/bindings/block/partitions.yaml -@@ -0,0 +1,20 @@ -+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/block/partitions.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: Partitions on block devices -+ -+description: | -+ This binding is generic and describes the content of the partitions container -+ node. -+ -+maintainers: -+ - Daniel Golle -+ -+patternProperties: -+ "^block-partition-.+$": -+ $ref: partition.yaml -+ -+unevaluatedProperties: false diff --git a/target/linux/generic/pending-6.1/450-09-block-partitions-populate-fwnode.patch b/target/linux/generic/pending-6.1/450-09-block-partitions-populate-fwnode.patch deleted file mode 100644 index 8aa5cba678897a..00000000000000 --- a/target/linux/generic/pending-6.1/450-09-block-partitions-populate-fwnode.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 614f4f6fdda09e30ecf7ef6c8091579db15018cb Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Fri, 21 Jul 2023 17:51:03 +0100 -Subject: [PATCH 09/15] block: partitions: populate fwnode - -Let block partitions to be represented by a firmware node and hence -allow them to being referenced e.g. for use with blk-nvmem. - -Signed-off-by: Daniel Golle ---- - block/partitions/core.c | 41 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 41 insertions(+) - ---- a/block/partitions/core.c -+++ b/block/partitions/core.c -@@ -10,6 +10,8 @@ - #include - #include - #include -+#include -+ - #include "check.h" - - static int (*check_part[])(struct parsed_partitions *) = { -@@ -298,6 +300,43 @@ static ssize_t whole_disk_show(struct de - } - static DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL); - -+static struct fwnode_handle *find_partition_fwnode(struct block_device *bdev) -+{ -+ struct fwnode_handle *fw_parts, *fw_part; -+ struct device *ddev = disk_to_dev(bdev->bd_disk); -+ const char *partname, *uuid; -+ u32 partno; -+ -+ fw_parts = device_get_named_child_node(ddev, "partitions"); -+ if (!fw_parts) -+ fw_parts = device_get_named_child_node(ddev->parent, "partitions"); -+ -+ if (!fw_parts) -+ return NULL; -+ -+ fwnode_for_each_child_node(fw_parts, fw_part) { -+ if (!fwnode_property_read_string(fw_part, "uuid", &uuid) && -+ (!bdev->bd_meta_info || strncmp(uuid, -+ bdev->bd_meta_info->uuid, -+ PARTITION_META_INFO_UUIDLTH))) -+ continue; -+ -+ if (!fwnode_property_read_string(fw_part, "partname", &partname) && -+ (!bdev->bd_meta_info || strncmp(partname, -+ bdev->bd_meta_info->volname, -+ PARTITION_META_INFO_VOLNAMELTH))) -+ continue; -+ -+ if (!fwnode_property_read_u32(fw_part, "partno", &partno) && -+ bdev->bd_partno != partno) -+ continue; -+ -+ return fw_part; -+ } -+ -+ return NULL; -+} -+ - /* - * Must be called either with open_mutex held, before a disk can be opened or - * after all disk users are gone. -@@ -380,6 +419,8 @@ static struct block_device *add_partitio - goto out_put; - } - -+ device_set_node(pdev, find_partition_fwnode(bdev)); -+ - /* delay uevent until 'holders' subdir is created */ - dev_set_uevent_suppress(pdev, 1); - err = device_add(pdev); diff --git a/target/linux/generic/pending-6.1/450-10-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch b/target/linux/generic/pending-6.1/450-10-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch deleted file mode 100644 index 4cbec14f5c97f6..00000000000000 --- a/target/linux/generic/pending-6.1/450-10-block-add-new-genhd-flag-GENHD_FL_NVMEM.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 65f3ff9672ccd5ee78937047e7a2fc696eee1c8f Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 13 Jul 2023 04:07:16 +0100 -Subject: [PATCH 10/15] block: add new genhd flag GENHD_FL_NVMEM - -Add new flag to destinguish block devices which may act as an NVMEM -provider. - -Signed-off-by: Daniel Golle ---- - include/linux/blkdev.h | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/include/linux/blkdev.h -+++ b/include/linux/blkdev.h -@@ -87,11 +87,13 @@ struct partition_meta_info { - * ``GENHD_FL_NO_PART``: partition support is disabled. The kernel will not - * scan for partitions from add_disk, and users can't add partitions manually. - * -+ * ``GENHD_FL_NVMEM``: the block device should be considered as NVMEM provider. - */ - enum { - GENHD_FL_REMOVABLE = 1 << 0, - GENHD_FL_HIDDEN = 1 << 1, - GENHD_FL_NO_PART = 1 << 2, -+ GENHD_FL_NVMEM = 1 << 3, - }; - - enum { diff --git a/target/linux/generic/pending-6.1/450-11-block-implement-NVMEM-provider.patch b/target/linux/generic/pending-6.1/450-11-block-implement-NVMEM-provider.patch deleted file mode 100644 index e18b0c3a5c7887..00000000000000 --- a/target/linux/generic/pending-6.1/450-11-block-implement-NVMEM-provider.patch +++ /dev/null @@ -1,235 +0,0 @@ -From b9936aa8a3775c2027f655d91a206d0e6e1c7ec0 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 11 Jul 2023 00:17:31 +0100 -Subject: [PATCH 11/15] block: implement NVMEM provider - -On embedded devices using an eMMC it is common that one or more partitions -on the eMMC are used to store MAC addresses and Wi-Fi calibration EEPROM -data. Allow referencing the partition in device tree for the kernel and -Wi-Fi drivers accessing it via the NVMEM layer. - -Signed-off-by: Daniel Golle ---- - block/Kconfig | 9 +++ - block/Makefile | 1 + - block/blk-nvmem.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 196 insertions(+) - create mode 100644 block/blk-nvmem.c - ---- a/block/Kconfig -+++ b/block/Kconfig -@@ -203,6 +203,15 @@ config BLK_INLINE_ENCRYPTION_FALLBACK - by falling back to the kernel crypto API when inline - encryption hardware is not present. - -+config BLK_NVMEM -+ bool "Block device NVMEM provider" -+ depends on OF -+ depends on NVMEM -+ help -+ Allow block devices (or partitions) to act as NVMEM prodivers, -+ typically used with eMMC to store MAC addresses or Wi-Fi -+ calibration data on embedded devices. -+ - source "block/partitions/Kconfig" - - config BLOCK_COMPAT ---- a/block/Makefile -+++ b/block/Makefile -@@ -35,6 +35,7 @@ obj-$(CONFIG_BLK_DEV_ZONED) += blk-zoned - obj-$(CONFIG_BLK_WBT) += blk-wbt.o - obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-debugfs.o - obj-$(CONFIG_BLK_DEBUG_FS_ZONED)+= blk-mq-debugfs-zoned.o -+obj-$(CONFIG_BLK_NVMEM) += blk-nvmem.o - obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o - obj-$(CONFIG_BLK_PM) += blk-pm.o - obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += blk-crypto.o blk-crypto-profile.o \ ---- /dev/null -+++ b/block/blk-nvmem.c -@@ -0,0 +1,186 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * block device NVMEM provider -+ * -+ * Copyright (c) 2023 Daniel Golle -+ * -+ * Useful on devices using a partition on an eMMC for MAC addresses or -+ * Wi-Fi calibration EEPROM data. -+ */ -+ -+#include "blk.h" -+#include -+#include -+#include -+#include -+ -+/* List of all NVMEM devices */ -+static LIST_HEAD(nvmem_devices); -+static DEFINE_MUTEX(devices_mutex); -+ -+struct blk_nvmem { -+ struct nvmem_device *nvmem; -+ struct block_device *bdev; -+ struct list_head list; -+}; -+ -+static int blk_nvmem_reg_read(void *priv, unsigned int from, -+ void *val, size_t bytes) -+{ -+ unsigned long offs = from & ~PAGE_MASK, to_read; -+ pgoff_t f_index = from >> PAGE_SHIFT; -+ struct address_space *mapping; -+ struct blk_nvmem *bnv = priv; -+ size_t bytes_left = bytes; -+ struct folio *folio; -+ void *p; -+ int ret; -+ -+ if (!bnv->bdev) -+ return -ENODEV; -+ -+ if (!bnv->bdev->bd_disk) -+ return -EINVAL; -+ -+ if (!bnv->bdev->bd_disk->fops) -+ return -EIO; -+ -+ if (!bnv->bdev->bd_disk->fops->open) -+ return -EIO; -+ -+ ret = bnv->bdev->bd_disk->fops->open(bnv->bdev, FMODE_READ); -+ if (ret) -+ return ret; -+ -+ mapping = bnv->bdev->bd_inode->i_mapping; -+ -+ while (bytes_left) { -+ folio = read_mapping_folio(mapping, f_index++, NULL); -+ if (IS_ERR(folio)) { -+ ret = PTR_ERR(folio); -+ goto err_release_bdev; -+ } -+ to_read = min_t(unsigned long, bytes_left, PAGE_SIZE - offs); -+ p = folio_address(folio) + offset_in_folio(folio, offs); -+ memcpy(val, p, to_read); -+ offs = 0; -+ bytes_left -= to_read; -+ val += to_read; -+ folio_put(folio); -+ } -+ -+err_release_bdev: -+ bnv->bdev->bd_disk->fops->release(bnv->bdev->bd_disk, FMODE_READ); -+ -+ return ret; -+} -+ -+static int blk_nvmem_register(struct device *dev, struct class_interface *iface) -+{ -+ struct device_node *np = dev_of_node(dev); -+ struct block_device *bdev = dev_to_bdev(dev); -+ struct nvmem_config config = {}; -+ struct blk_nvmem *bnv; -+ -+ /* skip devices which do not have a device tree node */ -+ if (!np) -+ return 0; -+ -+ /* skip devices without an nvmem layout defined */ -+ if (!of_get_child_by_name(np, "nvmem-layout")) -+ return 0; -+ -+ /* -+ * skip devices which don't have GENHD_FL_NVMEM set -+ * -+ * This flag is used for mtdblock and ubiblock devices because -+ * both, MTD and UBI already implement their own NVMEM provider. -+ * To avoid registering multiple NVMEM providers for the same -+ * device node, don't register the block NVMEM provider for them. -+ */ -+ if (!(bdev->bd_disk->flags & GENHD_FL_NVMEM)) -+ return 0; -+ -+ /* -+ * skip block device too large to be represented as NVMEM devices -+ * which are using an 'int' as address -+ */ -+ if (bdev_nr_bytes(bdev) > INT_MAX) -+ return -EFBIG; -+ -+ bnv = kzalloc(sizeof(struct blk_nvmem), GFP_KERNEL); -+ if (!bnv) -+ return -ENOMEM; -+ -+ config.id = NVMEM_DEVID_NONE; -+ config.dev = &bdev->bd_device; -+ config.name = dev_name(&bdev->bd_device); -+ config.owner = THIS_MODULE; -+ config.priv = bnv; -+ config.reg_read = blk_nvmem_reg_read; -+ config.size = bdev_nr_bytes(bdev); -+ config.word_size = 1; -+ config.stride = 1; -+ config.read_only = true; -+ config.root_only = true; -+ config.ignore_wp = true; -+ config.of_node = to_of_node(dev->fwnode); -+ -+ bnv->bdev = bdev; -+ bnv->nvmem = nvmem_register(&config); -+ if (IS_ERR(bnv->nvmem)) { -+ dev_err_probe(&bdev->bd_device, PTR_ERR(bnv->nvmem), -+ "Failed to register NVMEM device\n"); -+ -+ kfree(bnv); -+ return PTR_ERR(bnv->nvmem); -+ } -+ -+ mutex_lock(&devices_mutex); -+ list_add_tail(&bnv->list, &nvmem_devices); -+ mutex_unlock(&devices_mutex); -+ -+ return 0; -+} -+ -+static void blk_nvmem_unregister(struct device *dev, struct class_interface *iface) -+{ -+ struct block_device *bdev = dev_to_bdev(dev); -+ struct blk_nvmem *bnv_c, *bnv = NULL; -+ -+ mutex_lock(&devices_mutex); -+ list_for_each_entry(bnv_c, &nvmem_devices, list) { -+ if (bnv_c->bdev == bdev) { -+ bnv = bnv_c; -+ break; -+ } -+ } -+ -+ if (!bnv) { -+ mutex_unlock(&devices_mutex); -+ return; -+ } -+ -+ list_del(&bnv->list); -+ mutex_unlock(&devices_mutex); -+ nvmem_unregister(bnv->nvmem); -+ kfree(bnv); -+} -+ -+static struct class_interface blk_nvmem_bus_interface __refdata = { -+ .class = &block_class, -+ .add_dev = &blk_nvmem_register, -+ .remove_dev = &blk_nvmem_unregister, -+}; -+ -+static int __init blk_nvmem_init(void) -+{ -+ int ret; -+ -+ ret = class_interface_register(&blk_nvmem_bus_interface); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+device_initcall(blk_nvmem_init); diff --git a/target/linux/generic/pending-6.1/450-12-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch b/target/linux/generic/pending-6.1/450-12-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch deleted file mode 100644 index 77c9bf91a54d9e..00000000000000 --- a/target/linux/generic/pending-6.1/450-12-dt-bindings-mmc-mmc-card-add-block-device-nodes.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 86864bf8f40e84dc881c197ef470a88668329dbf Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 7 Aug 2023 21:21:45 +0100 -Subject: [PATCH 12/15] dt-bindings: mmc: mmc-card: add block device nodes - -Add nodes representing the block devices exposed by an MMC device -including an example involving nvmem-cells. - -Signed-off-by: Daniel Golle ---- - .../devicetree/bindings/mmc/mmc-card.yaml | 45 +++++++++++++++++++ - 1 file changed, 45 insertions(+) - ---- a/Documentation/devicetree/bindings/mmc/mmc-card.yaml -+++ b/Documentation/devicetree/bindings/mmc/mmc-card.yaml -@@ -26,6 +26,18 @@ properties: - Use this to indicate that the mmc-card has a broken hpi - implementation, and that hpi should not be used. - -+ block: -+ $ref: /schemas/block/block-device.yaml# -+ description: -+ Represents the block storage provided by an SD card or the -+ main hardware partition of an eMMC. -+ -+patternProperties: -+ '^boot[0-9]+': -+ $ref: /schemas/block/block-device.yaml# -+ description: -+ Represents a boot hardware partition on an eMMC. -+ - required: - - compatible - - reg -@@ -42,6 +54,39 @@ examples: - compatible = "mmc-card"; - reg = <0>; - broken-hpi; -+ -+ block { -+ partitions { -+ cal_data: block-partition-rf { -+ partnum = <3>; -+ partname = "rf"; -+ -+ nvmem-layout { -+ compatible = "fixed-layout"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ eeprom@0 { -+ reg = <0x0 0x1000>; -+ }; -+ }; -+ }; -+ }; -+ }; -+ -+ boot1 { -+ nvmem-layout { -+ compatible = "fixed-layout"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ macaddr: macaddr@a { -+ compatible = "mac-base"; -+ reg = <0xa 0x6>; -+ #nvmem-cell-cells = <1>; -+ }; -+ }; -+ }; - }; - }; - diff --git a/target/linux/generic/pending-6.1/450-13-mmc-core-set-card-fwnode_handle.patch b/target/linux/generic/pending-6.1/450-13-mmc-core-set-card-fwnode_handle.patch deleted file mode 100644 index fada280437971f..00000000000000 --- a/target/linux/generic/pending-6.1/450-13-mmc-core-set-card-fwnode_handle.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 644942a31719de674e2aa68f83d66bd8ae7e4fb7 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 13 Jul 2023 04:12:21 +0100 -Subject: [PATCH 13/15] mmc: core: set card fwnode_handle - -Set fwnode in case it isn't set yet and of_node is present. - -Signed-off-by: Daniel Golle ---- - drivers/mmc/core/bus.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/mmc/core/bus.c -+++ b/drivers/mmc/core/bus.c -@@ -363,6 +363,8 @@ int mmc_add_card(struct mmc_card *card) - mmc_add_card_debugfs(card); - #endif - card->dev.of_node = mmc_of_find_child_device(card->host, 0); -+ if (card->dev.of_node && !card->dev.fwnode) -+ card->dev.fwnode = &card->dev.of_node->fwnode; - - device_enable_async_suspend(&card->dev); - diff --git a/target/linux/generic/pending-6.1/450-14-mmc-block-set-fwnode-of-disk-devices.patch b/target/linux/generic/pending-6.1/450-14-mmc-block-set-fwnode-of-disk-devices.patch deleted file mode 100644 index 386282459b1e4a..00000000000000 --- a/target/linux/generic/pending-6.1/450-14-mmc-block-set-fwnode-of-disk-devices.patch +++ /dev/null @@ -1,39 +0,0 @@ -From d9143f86330dd038fc48878558dd287ceee5d3d4 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 13 Jul 2023 04:13:04 +0100 -Subject: [PATCH 14/15] mmc: block: set fwnode of disk devices - -Set fwnode of disk devices to 'block', 'boot0' and 'boot1' subnodes of -the mmc-card. This is done in preparation for having the eMMC act as -NVMEM provider. - -Signed-off-by: Daniel Golle ---- - drivers/mmc/core/block.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -2486,6 +2486,8 @@ static struct mmc_blk_data *mmc_blk_allo - int area_type, - unsigned int part_type) - { -+ struct fwnode_handle *fwnode; -+ struct device *ddev; - struct mmc_blk_data *md; - int devidx, ret; - char cap_str[10]; -@@ -2582,6 +2584,13 @@ static struct mmc_blk_data *mmc_blk_allo - - blk_queue_write_cache(md->queue.queue, cache_enabled, fua_enabled); - -+ ddev = disk_to_dev(md->disk); -+ fwnode = device_get_named_child_node(subname ? md->parent->parent : -+ md->parent, -+ subname ? subname : "block"); -+ if (fwnode) -+ device_set_node(ddev, fwnode); -+ - string_get_size((u64)size, 512, STRING_UNITS_2, - cap_str, sizeof(cap_str)); - pr_info("%s: %s %s %s %s\n", diff --git a/target/linux/generic/pending-6.1/450-15-mmc-block-set-GENHD_FL_NVMEM.patch b/target/linux/generic/pending-6.1/450-15-mmc-block-set-GENHD_FL_NVMEM.patch deleted file mode 100644 index 41c257cdeb270c..00000000000000 --- a/target/linux/generic/pending-6.1/450-15-mmc-block-set-GENHD_FL_NVMEM.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 322035ab2b0113d98b6c0ea788d971e0df2952a4 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Thu, 20 Jul 2023 17:36:44 +0100 -Subject: [PATCH 15/15] mmc: block: set GENHD_FL_NVMEM - -Set flag to consider MMC block devices as NVMEM providers. - -Signed-off-by: Daniel Golle ---- - drivers/mmc/core/block.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mmc/core/block.c -+++ b/drivers/mmc/core/block.c -@@ -2540,6 +2540,7 @@ static struct mmc_blk_data *mmc_blk_allo - md->disk->major = MMC_BLOCK_MAJOR; - md->disk->minors = perdev_minors; - md->disk->first_minor = devidx * perdev_minors; -+ md->disk->flags = GENHD_FL_NVMEM; - md->disk->fops = &mmc_bdops; - md->disk->private_data = md; - md->parent = parent; diff --git a/target/linux/generic/pending-6.1/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch b/target/linux/generic/pending-6.1/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch deleted file mode 100644 index 1b653fb735c9e8..00000000000000 --- a/target/linux/generic/pending-6.1/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Felix Fietkau -Subject: kernel: disable cfi cmdset 0002 erase suspend - -on some platforms, erase suspend leads to data corruption and lockups when write -ops collide with erase ops. this has been observed on the buffalo wzr-hp-g300nh. -rather than play whack-a-mole with a hard to reproduce issue on a variety of devices, -simply disable erase suspend, as it will usually not produce any useful gain on -the small filesystems used on embedded hardware. - -Signed-off-by: Felix Fietkau ---- - drivers/mtd/chips/cfi_cmdset_0002.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/mtd/chips/cfi_cmdset_0002.c -+++ b/drivers/mtd/chips/cfi_cmdset_0002.c -@@ -908,7 +908,7 @@ static int get_chip(struct map_info *map - return 0; - - case FL_ERASING: -- if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) || -+ if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) || - !(mode == FL_READY || mode == FL_POINT || - (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) - goto sleep; diff --git a/target/linux/generic/pending-6.1/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch b/target/linux/generic/pending-6.1/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch deleted file mode 100644 index f2788c5214083b..00000000000000 --- a/target/linux/generic/pending-6.1/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch +++ /dev/null @@ -1,17 +0,0 @@ -From: George Kashperko -Subject: Issue map read after Write Buffer Load command to ensure chip is ready to receive data. - -Signed-off-by: George Kashperko ---- - drivers/mtd/chips/cfi_cmdset_0002.c | 1 + - 1 file changed, 1 insertion(+) ---- a/drivers/mtd/chips/cfi_cmdset_0002.c -+++ b/drivers/mtd/chips/cfi_cmdset_0002.c -@@ -2052,6 +2052,7 @@ static int __xipram do_write_buffer(stru - - /* Write Buffer Load */ - map_write(map, CMD(0x25), cmd_adr); -+ (void) map_read(map, cmd_adr); - - chip->state = FL_WRITING_TO_BUFFER; - diff --git a/target/linux/generic/pending-6.1/465-m25p80-mx-disable-software-protection.patch b/target/linux/generic/pending-6.1/465-m25p80-mx-disable-software-protection.patch deleted file mode 100644 index 1e280773381cc1..00000000000000 --- a/target/linux/generic/pending-6.1/465-m25p80-mx-disable-software-protection.patch +++ /dev/null @@ -1,18 +0,0 @@ -From: Felix Fietkau -Subject: Disable software protection bits for Macronix flashes. - -Signed-off-by: Felix Fietkau ---- - drivers/mtd/spi-nor/spi-nor.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/spi-nor/macronix.c -+++ b/drivers/mtd/spi-nor/macronix.c -@@ -106,6 +106,7 @@ static void macronix_nor_default_init(st - { - nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; - nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode; -+ nor->flags |= SNOR_F_HAS_LOCK; - } - - static const struct spi_nor_fixups macronix_nor_fixups = { diff --git a/target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch b/target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch deleted file mode 100644 index 303e488433a07a..00000000000000 --- a/target/linux/generic/pending-6.1/476-mtd-spi-nor-add-eon-en25q128.patch +++ /dev/null @@ -1,19 +0,0 @@ -From: Piotr Dymacz -Subject: kernel/mtd: add support for EON EN25Q128 - -Signed-off-by: Piotr Dymacz ---- - drivers/mtd/spi-nor/spi-nor.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/spi-nor/eon.c -+++ b/drivers/mtd/spi-nor/eon.c -@@ -17,6 +17,8 @@ static const struct flash_info eon_nor_p - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128) }, - { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128) - NO_SFDP_FLAGS(SECT_4K) }, -+ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256) -+ NO_SFDP_FLAGS(SECT_4K) }, - { "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) }, - { "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32) diff --git a/target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch b/target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch deleted file mode 100644 index 6740d1d7beb9f7..00000000000000 --- a/target/linux/generic/pending-6.1/477-mtd-spi-nor-add-eon-en25qx128a.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Christian Marangi -Subject: kernel/mtd: add support for EON EN25QX128A - -Add support for EON EN25QX128A with no flags as it does -support SFDP parsing. - -Signed-off-by: Christian Marangi ---- - drivers/mtd/spi-nor/spi-nor.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/spi-nor/eon.c -+++ b/drivers/mtd/spi-nor/eon.c -@@ -19,6 +19,7 @@ static const struct flash_info eon_nor_p - NO_SFDP_FLAGS(SECT_4K) }, - { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256) - NO_SFDP_FLAGS(SECT_4K) }, -+ { "en25qx128a", INFO(0x1c7118, 0, 64 * 1024, 256) }, - { "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) }, - { "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32) diff --git a/target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch b/target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch deleted file mode 100644 index 371f1a72769412..00000000000000 --- a/target/linux/generic/pending-6.1/479-mtd-spi-nor-add-xtx-xt25f128b.patch +++ /dev/null @@ -1,81 +0,0 @@ -From patchwork Thu Feb 6 17:19:41 2020 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 1234465 -Date: Thu, 6 Feb 2020 19:19:41 +0200 -From: Daniel Golle -To: linux-mtd@lists.infradead.org -Subject: [PATCH v2] mtd: spi-nor: Add support for xt25f128b chip -Message-ID: <20200206171941.GA2398@makrotopia.org> -MIME-Version: 1.0 -Content-Disposition: inline -List-Subscribe: , - -Cc: Eitan Cohen , Piotr Dymacz , - Tudor Ambarus -Sender: "linux-mtd" -Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org - -Add XT25F128B made by XTX Technology (Shenzhen) Limited. -This chip supports dual and quad read and uniform 4K-byte erase. -Verified on Teltonika RUT955 which comes with XT25F128B in recent -versions of the device. - -Signed-off-by: Daniel Golle -Signed-off-by: Felix Fietkau ---- - drivers/mtd/spi-nor/spi-nor.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/mtd/spi-nor/Makefile -+++ b/drivers/mtd/spi-nor/Makefile -@@ -17,6 +17,7 @@ spi-nor-objs += sst.o - spi-nor-objs += winbond.o - spi-nor-objs += xilinx.o - spi-nor-objs += xmc.o -+spi-nor-objs += xtx.o - spi-nor-$(CONFIG_DEBUG_FS) += debugfs.o - obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o - ---- /dev/null -+++ b/drivers/mtd/spi-nor/xtx.c -@@ -0,0 +1,17 @@ -+// SPDX-License-Identifier: GPL-2.0 -+#include -+ -+#include "core.h" -+ -+static const struct flash_info xtx_parts[] = { -+ /* XTX Technology (Shenzhen) Limited */ -+ { "xt25f128b", INFO(0x0B4018, 0, 64 * 1024, 256) -+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | -+ SPI_NOR_QUAD_READ) }, -+}; -+ -+const struct spi_nor_manufacturer spi_nor_xtx = { -+ .name = "xtx", -+ .parts = xtx_parts, -+ .nparts = ARRAY_SIZE(xtx_parts), -+}; ---- a/drivers/mtd/spi-nor/core.c -+++ b/drivers/mtd/spi-nor/core.c -@@ -1636,6 +1636,7 @@ static const struct spi_nor_manufacturer - &spi_nor_winbond, - &spi_nor_xilinx, - &spi_nor_xmc, -+ &spi_nor_xtx, - }; - - static const struct flash_info spi_nor_generic_flash = { ---- a/drivers/mtd/spi-nor/core.h -+++ b/drivers/mtd/spi-nor/core.h -@@ -633,6 +633,7 @@ extern const struct spi_nor_manufacturer - extern const struct spi_nor_manufacturer spi_nor_winbond; - extern const struct spi_nor_manufacturer spi_nor_xilinx; - extern const struct spi_nor_manufacturer spi_nor_xmc; -+extern const struct spi_nor_manufacturer spi_nor_xtx; - - extern const struct attribute_group *spi_nor_sysfs_groups[]; - diff --git a/target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch b/target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch deleted file mode 100644 index 581e06190b5a19..00000000000000 --- a/target/linux/generic/pending-6.1/481-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch +++ /dev/null @@ -1,23 +0,0 @@ -From d68b4aa22e8c625685bfad642dd7337948dc0ad1 Mon Sep 17 00:00:00 2001 -From: Koen Vandeputte -Date: Mon, 6 Jan 2020 13:07:56 +0100 -Subject: [PATCH] mtd: spi-nor: add support for Gigadevice GD25D05 - -Signed-off-by: Koen Vandeputte ---- - drivers/mtd/spi-nor/spi-nor.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/mtd/spi-nor/gigadevice.c -+++ b/drivers/mtd/spi-nor/gigadevice.c -@@ -34,6 +34,10 @@ static const struct spi_nor_fixups gd25q - }; - - static const struct flash_info gigadevice_nor_parts[] = { -+ { "gd25q05", INFO(0xc84010, 0, 64 * 1024, 1) -+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | -+ SPI_NOR_QUAD_READ) }, - { "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32) - FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | diff --git a/target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch b/target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch deleted file mode 100644 index ddd3405ae71dd9..00000000000000 --- a/target/linux/generic/pending-6.1/482-mtd-spi-nor-add-gd25q512.patch +++ /dev/null @@ -1,23 +0,0 @@ -From f8943df3beb0d3f9754bb35320c3a378727175a8 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Thu, 14 Jul 2022 08:38:07 +0200 -Subject: [PATCH] spi-nor/gigadevic: add gd25q512 - ---- - drivers/mtd/spi-nor/gigadevice.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/mtd/spi-nor/gigadevice.c -+++ b/drivers/mtd/spi-nor/gigadevice.c -@@ -71,6 +71,11 @@ static const struct flash_info gigadevic - FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6) - FIXUP_FLAGS(SPI_NOR_4B_OPCODES) - .fixups = &gd25q256_fixups }, -+ { "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024) -+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) -+ FIXUP_FLAGS(SPI_NOR_4B_OPCODES) -+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | -+ SPI_NOR_QUAD_READ) }, - }; - - const struct spi_nor_manufacturer spi_nor_gigadevice = { diff --git a/target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch b/target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch deleted file mode 100644 index d5ebe203097376..00000000000000 --- a/target/linux/generic/pending-6.1/484-mtd-spi-nor-add-esmt-f25l16pa.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 87363cc0e522de3294ea6ae10fb468d2a8d6fb2f Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:17:21 +0200 -Subject: [PATCH] spi-nor/esmt.c: add esmt f25l16pa - -This fixes support for Dongwon T&I DW02-412H which uses F25L16PA(2S) -flash. - ---- - drivers/mtd/spi-nor/esmt.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/mtd/spi-nor/esmt.c -+++ b/drivers/mtd/spi-nor/esmt.c -@@ -10,6 +10,9 @@ - - static const struct flash_info esmt_nor_parts[] = { - /* ESMT */ -+ { "f25l16pa-2s", INFO(0x8c2115, 0, 64 * 1024, 32) -+ FLAGS(SPI_NOR_HAS_LOCK) -+ NO_SFDP_FLAGS(SECT_4K) }, - { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64) - FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE) - NO_SFDP_FLAGS(SECT_4K) }, diff --git a/target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch b/target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch deleted file mode 100644 index e8583cc2571abc..00000000000000 --- a/target/linux/generic/pending-6.1/485-mtd-spi-nor-add-xmc-xm25qh128c.patch +++ /dev/null @@ -1,25 +0,0 @@ -From f6b33d850f7f12555df2fa0e3349b33427bf5890 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:19:01 +0200 -Subject: [PATCH] spi-nor/xmc.c: add xm25qh128c - -The XMC XM25QH128C is a 16MB SPI NOR chip. The patch is verified on -Ruijie RG-EW3200GX PRO. -Datasheet available at https://www.xmcwh.com/uploads/435/XM25QH128C.pdf - ---- - drivers/mtd/spi-nor/xmc.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/mtd/spi-nor/xmc.c -+++ b/drivers/mtd/spi-nor/xmc.c -@@ -16,6 +16,9 @@ static const struct flash_info xmc_nor_p - { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | - SPI_NOR_QUAD_READ) }, -+ { "XM25QH128C", INFO(0x204018, 0, 64 * 1024, 256) -+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | -+ SPI_NOR_QUAD_READ) }, - }; - - const struct spi_nor_manufacturer spi_nor_xmc = { diff --git a/target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch b/target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch deleted file mode 100644 index b8116db84205e2..00000000000000 --- a/target/linux/generic/pending-6.1/486-01-mtd-spinand-add-support-for-ESMT-F50x1G41LB.patch +++ /dev/null @@ -1,143 +0,0 @@ -From a43b844cb40bf1b783055fdc81b7f991e21e7e76 Mon Sep 17 00:00:00 2001 -From: Chuanhong Guo -Date: Wed, 13 Apr 2022 11:58:17 +0800 -Subject: [PATCH] mtd: spinand: add support for ESMT F50x1G41LB - -This patch adds support for ESMT F50L1G41LB and F50D1G41LB. -It seems that ESMT likes to use random JEDEC ID from other vendors. -Their 1G chips uses 0xc8 from GigaDevice and 2G/4G chips uses 0x2c from -Micron. For this reason, the ESMT entry is named esmt_c8 with explicit -JEDEC ID in variable name. - -Datasheets: -https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50L1G41LB(2M).pdf -https://www.esmt.com.tw/upload/pdf/ESMT/datasheets/F50D1G41LB(2M).pdf - -Signed-off-by: Chuanhong Guo ---- - drivers/mtd/nand/spi/Makefile | 2 +- - drivers/mtd/nand/spi/core.c | 1 + - drivers/mtd/nand/spi/esmt.c | 89 +++++++++++++++++++++++++++++++++++ - include/linux/mtd/spinand.h | 1 + - 4 files changed, 92 insertions(+), 1 deletion(-) - create mode 100644 drivers/mtd/nand/spi/esmt.c - ---- a/drivers/mtd/nand/spi/Makefile -+++ b/drivers/mtd/nand/spi/Makefile -@@ -1,3 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 --spinand-objs := core.o ato.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o -+spinand-objs := core.o ato.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o - obj-$(CONFIG_MTD_SPI_NAND) += spinand.o ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -938,6 +938,7 @@ static const struct nand_ops spinand_ops - - static const struct spinand_manufacturer *spinand_manufacturers[] = { - &ato_spinand_manufacturer, -+ &esmt_c8_spinand_manufacturer, - &gigadevice_spinand_manufacturer, - ¯onix_spinand_manufacturer, - µn_spinand_manufacturer, ---- /dev/null -+++ b/drivers/mtd/nand/spi/esmt.c -@@ -0,0 +1,89 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Author: -+ * Chuanhong Guo -+ */ -+ -+#include -+#include -+#include -+ -+/* ESMT uses GigaDevice 0xc8 JECDEC ID on some SPI NANDs */ -+#define SPINAND_MFR_ESMT_C8 0xc8 -+ -+static SPINAND_OP_VARIANTS(read_cache_variants, -+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(write_cache_variants, -+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), -+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(update_cache_variants, -+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), -+ SPINAND_PROG_LOAD(false, 0, NULL, 0)); -+ -+static int f50l1g41lb_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section > 3) -+ return -ERANGE; -+ -+ region->offset = 16 * section + 8; -+ region->length = 8; -+ -+ return 0; -+} -+ -+static int f50l1g41lb_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *region) -+{ -+ if (section > 3) -+ return -ERANGE; -+ -+ region->offset = 16 * section + 2; -+ region->length = 6; -+ -+ return 0; -+} -+ -+static const struct mtd_ooblayout_ops f50l1g41lb_ooblayout = { -+ .ecc = f50l1g41lb_ooblayout_ecc, -+ .free = f50l1g41lb_ooblayout_free, -+}; -+ -+static const struct spinand_info esmt_c8_spinand_table[] = { -+ SPINAND_INFO("F50L1G41LB", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01), -+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(1, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ 0, -+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), -+ SPINAND_INFO("F50D1G41LB", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11), -+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), -+ NAND_ECCREQ(1, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ 0, -+ SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)), -+}; -+ -+static const struct spinand_manufacturer_ops esmt_spinand_manuf_ops = { -+}; -+ -+const struct spinand_manufacturer esmt_c8_spinand_manufacturer = { -+ .id = SPINAND_MFR_ESMT_C8, -+ .name = "ESMT", -+ .chips = esmt_c8_spinand_table, -+ .nchips = ARRAY_SIZE(esmt_c8_spinand_table), -+ .ops = &esmt_spinand_manuf_ops, -+}; ---- a/include/linux/mtd/spinand.h -+++ b/include/linux/mtd/spinand.h -@@ -261,6 +261,7 @@ struct spinand_manufacturer { - - /* SPI NAND manufacturers */ - extern const struct spinand_manufacturer ato_spinand_manufacturer; -+extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; - extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; - extern const struct spinand_manufacturer macronix_spinand_manufacturer; - extern const struct spinand_manufacturer micron_spinand_manufacturer; diff --git a/target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch b/target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch deleted file mode 100644 index 81378fba868ff2..00000000000000 --- a/target/linux/generic/pending-6.1/487-mtd-spinand-Add-support-for-Etron-EM73D044VCx.patch +++ /dev/null @@ -1,168 +0,0 @@ -From f32085fc0b87049491b07e198d924d738a1a2834 Mon Sep 17 00:00:00 2001 -From: Daniel Danzberger -Date: Wed, 3 Aug 2022 17:31:03 +0200 -Subject: [PATCH] mtd: spinand: Add support for Etron EM73D044VCx - -Airoha is a new ARM platform based on Cortex-A53 which has recently been -merged into linux-next. - -Due to BootROM limitations on this platform, the Cortex-A53 can't run in -Aarch64 mode and code must be compiled for 32-Bit ARM. - -This support is based mostly on those linux-next commits backported -for kernel 5.15. - -Patches: -1 - platform support = linux-next -2 - clock driver = linux-next -3 - gpio driver = linux-next -4 - linux,usable-memory-range dts support = linux-next -5 - mtd spinand driver -6 - spi driver -7 - pci driver (kconfig only, uses mediatek PCI) = linux-next - -Still missing: -- Ethernet driver -- Sysupgrade support - -A.t.m there exists one subtarget EN7523 with only one evaluation -board. - -The initramfs can be run with the following commands from u-boot: -- -u-boot> setenv bootfile \ - openwrt-airoha-airoha_en7523-evb-initramfs-kernel.bin -u-boot> tftpboot -u-boot> bootm 0x81800000 -- - -Submitted-by: Daniel Danzberger - ---- a/drivers/mtd/nand/spi/Makefile -+++ b/drivers/mtd/nand/spi/Makefile -@@ -1,3 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 --spinand-objs := core.o ato.o esmt.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o -+spinand-objs := core.o ato.o esmt.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o - obj-$(CONFIG_MTD_SPI_NAND) += spinand.o ---- a/drivers/mtd/nand/spi/core.c -+++ b/drivers/mtd/nand/spi/core.c -@@ -939,6 +939,7 @@ static const struct nand_ops spinand_ops - static const struct spinand_manufacturer *spinand_manufacturers[] = { - &ato_spinand_manufacturer, - &esmt_c8_spinand_manufacturer, -+ &etron_spinand_manufacturer, - &gigadevice_spinand_manufacturer, - ¯onix_spinand_manufacturer, - µn_spinand_manufacturer, ---- /dev/null -+++ b/drivers/mtd/nand/spi/etron.c -@@ -0,0 +1,98 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+ -+#define SPINAND_MFR_ETRON 0xd5 -+ -+ -+static SPINAND_OP_VARIANTS(read_cache_variants, -+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), -+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(write_cache_variants, -+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), -+ SPINAND_PROG_LOAD(true, 0, NULL, 0)); -+ -+static SPINAND_OP_VARIANTS(update_cache_variants, -+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), -+ SPINAND_PROG_LOAD(false, 0, NULL, 0)); -+ -+static int etron_ooblayout_ecc(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) -+ return -ERANGE; -+ -+ oobregion->offset = 72; -+ oobregion->length = 56; -+ -+ return 0; -+} -+ -+static int etron_ooblayout_free(struct mtd_info *mtd, int section, -+ struct mtd_oob_region *oobregion) -+{ -+ if (section) -+ return -ERANGE; -+ -+ oobregion->offset = 1; -+ oobregion->length = 71; -+ -+ return 0; -+} -+ -+static int etron_ecc_get_status(struct spinand_device *spinand, u8 status) -+{ -+ switch (status & STATUS_ECC_MASK) { -+ case STATUS_ECC_NO_BITFLIPS: -+ return 0; -+ -+ case STATUS_ECC_HAS_BITFLIPS: -+ /* Between 1-7 bitflips were corrected */ -+ return 7; -+ -+ case STATUS_ECC_MASK: -+ /* Maximum bitflips were corrected */ -+ return 8; -+ -+ case STATUS_ECC_UNCOR_ERROR: -+ return -EBADMSG; -+ } -+ -+ return -EINVAL; -+} -+ -+static const struct mtd_ooblayout_ops etron_ooblayout = { -+ .ecc = etron_ooblayout_ecc, -+ .free = etron_ooblayout_free, -+}; -+ -+static const struct spinand_info etron_spinand_table[] = { -+ SPINAND_INFO("EM73D044VCx", -+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f), -+ // bpc, pagesize, oobsize, pagesperblock, bperlun, maxbadplun, ppl, lpt, #t -+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), -+ NAND_ECCREQ(8, 512), -+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, -+ &write_cache_variants, -+ &update_cache_variants), -+ SPINAND_HAS_QE_BIT, -+ SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)), -+}; -+ -+static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = { -+}; -+ -+const struct spinand_manufacturer etron_spinand_manufacturer = { -+ .id = SPINAND_MFR_ETRON, -+ .name = "Etron", -+ .chips = etron_spinand_table, -+ .nchips = ARRAY_SIZE(etron_spinand_table), -+ .ops = &etron_spinand_manuf_ops, -+}; ---- a/include/linux/mtd/spinand.h -+++ b/include/linux/mtd/spinand.h -@@ -262,6 +262,7 @@ struct spinand_manufacturer { - /* SPI NAND manufacturers */ - extern const struct spinand_manufacturer ato_spinand_manufacturer; - extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer; -+extern const struct spinand_manufacturer etron_spinand_manufacturer; - extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; - extern const struct spinand_manufacturer macronix_spinand_manufacturer; - extern const struct spinand_manufacturer micron_spinand_manufacturer; diff --git a/target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch b/target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch deleted file mode 100644 index e1e4f25e1192bc..00000000000000 --- a/target/linux/generic/pending-6.1/488-mtd-spi-nor-add-xmc-xm25qh64c.patch +++ /dev/null @@ -1,23 +0,0 @@ -From: Joe Mullally -Subject: mtd/spi-nor/xmc: add support for XMC XM25QH64C - -The XMC XM25QH64C is a 8MB SPI NOR chip. The patch is verified on TL-WPA8631P v3. -Datasheet available at https://www.xmcwh.com/uploads/442/XM25QH64C.pdf - -Signed-off-by: Joe Mullally ---- - drivers/mtd/spi-nor/xmc.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/mtd/spi-nor/xmc.c -+++ b/drivers/mtd/spi-nor/xmc.c -@@ -13,6 +13,9 @@ static const struct flash_info xmc_nor_p - { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | - SPI_NOR_QUAD_READ) }, -+ { "XM25QH64C", INFO(0x204017, 0, 64 * 1024, 128) -+ NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | -+ SPI_NOR_QUAD_READ) }, - { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256) - NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | - SPI_NOR_QUAD_READ) }, diff --git a/target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch b/target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch deleted file mode 100644 index 2eccb9d3bbb513..00000000000000 --- a/target/linux/generic/pending-6.1/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch +++ /dev/null @@ -1,98 +0,0 @@ -From: Daniel Golle -Subject: ubi: auto-attach mtd device named "ubi" or "data" on boot - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - ---- a/drivers/mtd/ubi/build.c -+++ b/drivers/mtd/ubi/build.c -@@ -1263,6 +1263,74 @@ static struct mtd_notifier ubi_mtd_notif - .remove = ubi_notify_remove, - }; - -+ -+/* -+ * This function tries attaching mtd partitions named either "ubi" or "data" -+ * during boot. -+ */ -+static void __init ubi_auto_attach(void) -+{ -+ int err; -+ struct mtd_info *mtd; -+ loff_t offset = 0; -+ size_t len; -+ char magic[4]; -+ -+ /* try attaching mtd device named "ubi" or "data" */ -+ mtd = open_mtd_device("ubi"); -+ if (IS_ERR(mtd)) -+ mtd = open_mtd_device("data"); -+ -+ if (IS_ERR(mtd)) -+ return; -+ -+ /* get the first not bad block */ -+ if (mtd_can_have_bb(mtd)) -+ while (mtd_block_isbad(mtd, offset)) { -+ offset += mtd->erasesize; -+ -+ if (offset > mtd->size) { -+ pr_err("UBI error: Failed to find a non-bad " -+ "block on mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ } -+ -+ /* check if the read from flash was successful */ -+ err = mtd_read(mtd, offset, 4, &len, (void *) magic); -+ if ((err && !mtd_is_bitflip(err)) || len != 4) { -+ pr_err("UBI error: unable to read from mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ -+ /* check for a valid ubi magic */ -+ if (strncmp(magic, "UBI#", 4)) { -+ pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ -+ /* don't auto-add media types where UBI doesn't makes sense */ -+ if (mtd->type != MTD_NANDFLASH && -+ mtd->type != MTD_NORFLASH && -+ mtd->type != MTD_DATAFLASH && -+ mtd->type != MTD_MLCNANDFLASH) -+ goto cleanup; -+ -+ mutex_lock(&ubi_devices_mutex); -+ pr_notice("UBI: auto-attach mtd%d\n", mtd->index); -+ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0, false); -+ mutex_unlock(&ubi_devices_mutex); -+ if (err < 0) { -+ pr_err("UBI error: cannot attach mtd%d\n", mtd->index); -+ goto cleanup; -+ } -+ -+ return; -+ -+cleanup: -+ put_mtd_device(mtd); -+} -+ - static int __init ubi_init_attach(void) - { - int err, i, k; -@@ -1313,6 +1381,12 @@ static int __init ubi_init_attach(void) - } - } - -+ /* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd -+ * parameter was given */ -+ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && -+ !ubi_is_module() && !mtd_devs) -+ ubi_auto_attach(); -+ - return 0; - - out_detach: diff --git a/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch deleted file mode 100644 index f0ea8e8cb54522..00000000000000 --- a/target/linux/generic/pending-6.1/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +++ /dev/null @@ -1,77 +0,0 @@ -From: Daniel Golle -Subject: ubi: auto-create ubiblock device for rootfs - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 42 insertions(+) - ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -644,10 +644,47 @@ match_volume_desc(struct ubi_volume_info - return true; - } - -+#define UBIFS_NODE_MAGIC 0x06101831 -+static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc) -+{ -+ int ret; -+ uint32_t magic_of, magic; -+ ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4); -+ if (ret) -+ return 0; -+ magic = le32_to_cpu(magic_of); -+ return magic == UBIFS_NODE_MAGIC; -+} -+ -+static void ubiblock_create_auto_rootfs(struct ubi_volume_info *vi) -+{ -+ int ret, is_ubifs; -+ struct ubi_volume_desc *desc; -+ -+ if (strcmp(vi->name, "rootfs") && -+ strcmp(vi->name, "fit")) -+ return; -+ -+ desc = ubi_open_volume(vi->ubi_num, vi->vol_id, UBI_READONLY); -+ if (IS_ERR(desc)) -+ return; -+ -+ is_ubifs = ubi_vol_is_ubifs(desc); -+ ubi_close_volume(desc); -+ if (is_ubifs) -+ return; -+ -+ ret = ubiblock_create(vi); -+ if (ret) -+ pr_err("UBI error: block: can't add '%s' volume, err=%d\n", -+ vi->name, ret); -+} -+ - static void - ubiblock_create_from_param(struct ubi_volume_info *vi) - { - int i, ret = 0; -+ bool got_param = false; - struct ubiblock_param *p; - - /* -@@ -660,6 +697,7 @@ ubiblock_create_from_param(struct ubi_vo - if (!match_volume_desc(vi, p->name, p->ubi_num, p->vol_id)) - continue; - -+ got_param = true; - ret = ubiblock_create(vi); - if (ret) { - pr_err( -@@ -668,6 +706,10 @@ ubiblock_create_from_param(struct ubi_vo - } - break; - } -+ -+ /* auto-attach "rootfs" volume if existing and non-ubifs */ -+ if (!got_param && IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV)) -+ ubiblock_create_auto_rootfs(vi); - } - - static int ubiblock_notify(struct notifier_block *nb, diff --git a/target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch b/target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch deleted file mode 100644 index f95ec46f14eb5b..00000000000000 --- a/target/linux/generic/pending-6.1/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: Daniel Golle -Subject: try auto-mounting ubi0:rootfs in init/do_mounts.c - -Signed-off-by: Daniel Golle ---- - init/do_mounts.c | 26 +++++++++++++++++++++++++- - 1 file changed, 25 insertions(+), 1 deletion(-) - ---- a/init/do_mounts.c -+++ b/init/do_mounts.c -@@ -446,7 +446,30 @@ retry: - out: - put_page(page); - } -- -+ -+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV -+static int __init mount_ubi_rootfs(void) -+{ -+ int flags = MS_SILENT; -+ int err, tried = 0; -+ -+ while (tried < 2) { -+ err = do_mount_root("ubi0:rootfs", "ubifs", flags, \ -+ root_mount_data); -+ switch (err) { -+ case -EACCES: -+ flags |= MS_RDONLY; -+ tried++; -+ break; -+ default: -+ return err; -+ } -+ } -+ -+ return -EINVAL; -+} -+#endif -+ - #ifdef CONFIG_ROOT_NFS - - #define NFSROOT_TIMEOUT_MIN 5 -@@ -579,6 +602,10 @@ void __init mount_root(void) - return; - } - #endif -+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV -+ if (!mount_ubi_rootfs()) -+ return; -+#endif - if (ROOT_DEV == 0 && root_device_name && root_fs_names) { - if (mount_nodev_root() == 0) - return; diff --git a/target/linux/generic/pending-6.1/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch b/target/linux/generic/pending-6.1/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch deleted file mode 100644 index 5357c7e15d7b18..00000000000000 --- a/target/linux/generic/pending-6.1/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Daniel Golle -Subject: ubi: set ROOT_DEV to ubiblock "rootfs" if unset - -Signed-off-by: Daniel Golle ---- - drivers/mtd/ubi/block.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/mtd/ubi/block.c -+++ b/drivers/mtd/ubi/block.c -@@ -43,6 +43,7 @@ - #include - #include - #include -+#include - - #include "ubi-media.h" - #include "ubi.h" -@@ -460,6 +461,15 @@ int ubiblock_create(struct ubi_volume_in - dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)", - dev->ubi_num, dev->vol_id, vi->name); - mutex_unlock(&devices_mutex); -+ -+ if (!strcmp(vi->name, "rootfs") && -+ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && -+ ROOT_DEV == 0) { -+ pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n", -+ dev->ubi_num, dev->vol_id, vi->name); -+ ROOT_DEV = MKDEV(gd->major, gd->first_minor); -+ } -+ - return 0; - - out_destroy_wq: diff --git a/target/linux/generic/pending-6.1/494-mtd-ubi-add-EOF-marker-support.patch b/target/linux/generic/pending-6.1/494-mtd-ubi-add-EOF-marker-support.patch deleted file mode 100644 index fc481462212cea..00000000000000 --- a/target/linux/generic/pending-6.1/494-mtd-ubi-add-EOF-marker-support.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: Gabor Juhos -Subject: mtd: add EOF marker support to the UBI layer - -Signed-off-by: Gabor Juhos ---- - drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++--- - drivers/mtd/ubi/ubi.h | 1 + - 2 files changed, 23 insertions(+), 3 deletions(-) - ---- a/drivers/mtd/ubi/attach.c -+++ b/drivers/mtd/ubi/attach.c -@@ -926,6 +926,13 @@ static bool vol_ignored(int vol_id) - #endif - } - -+static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech) -+{ -+ return ech->padding1[0] == 'E' && -+ ech->padding1[1] == 'O' && -+ ech->padding1[2] == 'F'; -+} -+ - /** - * scan_peb - scan and process UBI headers of a PEB. - * @ubi: UBI device description object -@@ -958,9 +965,21 @@ static int scan_peb(struct ubi_device *u - return 0; - } - -- err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); -- if (err < 0) -- return err; -+ if (!ai->eof_found) { -+ err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); -+ if (err < 0) -+ return err; -+ -+ if (ec_hdr_has_eof(ech)) { -+ pr_notice("UBI: EOF marker found, PEBs from %d will be erased\n", -+ pnum); -+ ai->eof_found = true; -+ } -+ } -+ -+ if (ai->eof_found) -+ err = UBI_IO_FF_BITFLIPS; -+ - switch (err) { - case 0: - break; ---- a/drivers/mtd/ubi/ubi.h -+++ b/drivers/mtd/ubi/ubi.h -@@ -780,6 +780,7 @@ struct ubi_attach_info { - int mean_ec; - uint64_t ec_sum; - int ec_count; -+ bool eof_found; - struct kmem_cache *aeb_slab_cache; - struct ubi_ec_hdr *ech; - struct ubi_vid_io_buf *vidb; diff --git a/target/linux/generic/pending-6.1/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch b/target/linux/generic/pending-6.1/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch deleted file mode 100644 index 01f3b9ec2da0ce..00000000000000 --- a/target/linux/generic/pending-6.1/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 5734c6669fba7ddb5ef491ccff7159d15dba0b59 Mon Sep 17 00:00:00 2001 -From: Bernhard Frauendienst -Date: Wed, 5 Sep 2018 01:32:51 +0200 -Subject: [PATCH 496/497] dt-bindings: add bindings for mtd-concat devices - -Document virtual mtd-concat device bindings. - -Signed-off-by: Bernhard Frauendienst ---- - .../devicetree/bindings/mtd/mtd-concat.txt | 36 +++++++++++++++++++ - 1 file changed, 36 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mtd/mtd-concat.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/mtd/mtd-concat.txt -@@ -0,0 +1,36 @@ -+Virtual MTD concat device -+ -+Requires properties: -+- devices: list of phandles to mtd nodes that should be concatenated -+ -+Example: -+ -+&spi { -+ flash0: flash@0 { -+ ... -+ }; -+ flash1: flash@1 { -+ ... -+ }; -+}; -+ -+flash { -+ compatible = "mtd-concat"; -+ -+ devices = <&flash0 &flash1>; -+ -+ partitions { -+ compatible = "fixed-partitions"; -+ -+ partition@0 { -+ label = "boot"; -+ reg = <0x0000000 0x0040000>; -+ read-only; -+ }; -+ -+ partition@40000 { -+ label = "firmware"; -+ reg = <0x0040000 0x1fc0000>; -+ }; -+ } -+} diff --git a/target/linux/generic/pending-6.1/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch b/target/linux/generic/pending-6.1/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch deleted file mode 100644 index e0cbc4508b0607..00000000000000 --- a/target/linux/generic/pending-6.1/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch +++ /dev/null @@ -1,216 +0,0 @@ -From e53f712d8eac71f54399b61038ccf87d2cee99d7 Mon Sep 17 00:00:00 2001 -From: Bernhard Frauendienst -Date: Sat, 25 Aug 2018 12:35:22 +0200 -Subject: [PATCH 497/497] mtd: mtdconcat: add dt driver for concat devices - -Some mtd drivers like physmap variants have support for concatenating -multiple mtd devices, but there is no generic way to define such a -concat device from within the device tree. - -This is useful for some SoC boards that use multiple flash chips as -memory banks of a single mtd device, with partitions spanning chip -borders. - -This commit adds a driver for creating virtual mtd-concat devices. They -must have a compatible = "mtd-concat" line, and define a list of devices -to concat in the 'devices' property, for example: - -flash { - compatible = "mtd-concat"; - - devices = <&flash0 &flash1>; - - partitions { - ... - }; -}; - -The driver is added to the very end of the mtd Makefile to increase the -likelyhood of all child devices already being loaded at the time of -probing, preventing unnecessary deferred probes. - -Signed-off-by: Bernhard Frauendienst ---- - drivers/mtd/Kconfig | 2 + - drivers/mtd/Makefile | 3 + - drivers/mtd/composite/Kconfig | 12 +++ - drivers/mtd/composite/Makefile | 6 ++ - drivers/mtd/composite/virt_concat.c | 128 ++++++++++++++++++++++++++++ - 5 files changed, 151 insertions(+) - create mode 100644 drivers/mtd/composite/Kconfig - create mode 100644 drivers/mtd/composite/Makefile - create mode 100644 drivers/mtd/composite/virt_concat.c - ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -241,4 +241,6 @@ source "drivers/mtd/ubi/Kconfig" - - source "drivers/mtd/hyperbus/Kconfig" - -+source "drivers/mtd/composite/Kconfig" -+ - endif # MTD ---- a/drivers/mtd/Makefile -+++ b/drivers/mtd/Makefile -@@ -33,3 +33,6 @@ obj-y += chips/ lpddr/ maps/ devices/ n - obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ - obj-$(CONFIG_MTD_UBI) += ubi/ - obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/ -+ -+# Composite drivers must be loaded last -+obj-y += composite/ ---- /dev/null -+++ b/drivers/mtd/composite/Kconfig -@@ -0,0 +1,12 @@ -+menu "Composite MTD device drivers" -+ depends on MTD!=n -+ -+config MTD_VIRT_CONCAT -+ tristate "Virtual concat MTD device" -+ help -+ This driver allows creation of a virtual MTD concat device, which -+ concatenates multiple underlying MTD devices to a single device. -+ This is required by some SoC boards where multiple memory banks are -+ used as one device with partitions spanning across device boundaries. -+ -+endmenu ---- /dev/null -+++ b/drivers/mtd/composite/Makefile -@@ -0,0 +1,6 @@ -+# SPDX-License-Identifier: GPL-2.0 -+# -+# linux/drivers/mtd/composite/Makefile -+# -+ -+obj-$(CONFIG_MTD_VIRT_CONCAT) += virt_concat.o ---- /dev/null -+++ b/drivers/mtd/composite/virt_concat.c -@@ -0,0 +1,128 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * Virtual concat MTD device driver -+ * -+ * Copyright (C) 2018 Bernhard Frauendienst -+ * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * struct of_virt_concat - platform device driver data. -+ * @cmtd the final mtd_concat device -+ * @num_devices the number of devices in @devices -+ * @devices points to an array of devices already loaded -+ */ -+struct of_virt_concat { -+ struct mtd_info *cmtd; -+ int num_devices; -+ struct mtd_info **devices; -+}; -+ -+static int virt_concat_remove(struct platform_device *pdev) -+{ -+ struct of_virt_concat *info; -+ int i; -+ -+ info = platform_get_drvdata(pdev); -+ if (!info) -+ return 0; -+ -+ // unset data for when this is called after a probe error -+ platform_set_drvdata(pdev, NULL); -+ -+ if (info->cmtd) { -+ mtd_device_unregister(info->cmtd); -+ mtd_concat_destroy(info->cmtd); -+ } -+ -+ if (info->devices) { -+ for (i = 0; i < info->num_devices; i++) -+ put_mtd_device(info->devices[i]); -+ } -+ -+ return 0; -+} -+ -+static int virt_concat_probe(struct platform_device *pdev) -+{ -+ struct device_node *node = pdev->dev.of_node; -+ struct of_phandle_iterator it; -+ struct of_virt_concat *info; -+ struct mtd_info *mtd; -+ int err = 0, count; -+ -+ count = of_count_phandle_with_args(node, "devices", NULL); -+ if (count <= 0) -+ return -EINVAL; -+ -+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; -+ info->devices = devm_kcalloc(&pdev->dev, count, -+ sizeof(*(info->devices)), GFP_KERNEL); -+ if (!info->devices) { -+ err = -ENOMEM; -+ goto err_remove; -+ } -+ -+ platform_set_drvdata(pdev, info); -+ -+ of_for_each_phandle(&it, err, node, "devices", NULL, 0) { -+ mtd = of_get_mtd_device_by_node(it.node); -+ if (IS_ERR(mtd)) { -+ of_node_put(it.node); -+ err = -EPROBE_DEFER; -+ goto err_remove; -+ } -+ -+ info->devices[info->num_devices++] = mtd; -+ } -+ -+ info->cmtd = mtd_concat_create(info->devices, info->num_devices, -+ dev_name(&pdev->dev)); -+ if (!info->cmtd) { -+ err = -ENXIO; -+ goto err_remove; -+ } -+ -+ info->cmtd->dev.parent = &pdev->dev; -+ mtd_set_of_node(info->cmtd, node); -+ mtd_device_register(info->cmtd, NULL, 0); -+ -+ return 0; -+ -+err_remove: -+ virt_concat_remove(pdev); -+ -+ return err; -+} -+ -+static const struct of_device_id virt_concat_of_match[] = { -+ { .compatible = "mtd-concat", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, virt_concat_of_match); -+ -+static struct platform_driver virt_concat_driver = { -+ .probe = virt_concat_probe, -+ .remove = virt_concat_remove, -+ .driver = { -+ .name = "virt-mtdconcat", -+ .of_match_table = virt_concat_of_match, -+ }, -+}; -+ -+module_platform_driver(virt_concat_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Bernhard Frauendienst "); -+MODULE_DESCRIPTION("Virtual concat MTD device driver"); diff --git a/target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch b/target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch deleted file mode 100644 index 1a4d5a766f2281..00000000000000 --- a/target/linux/generic/pending-6.1/498-mtd-spi-nor-locking-support-for-MX25L6405D.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 8bf2ce6ea4ee840b70f55a27f80e1cd308051b13 Mon Sep 17 00:00:00 2001 -From: Nick Hainke -Date: Mon, 27 Dec 2021 00:38:13 +0100 -Subject: [PATCH 1/2] mtd: spi-nor: locking support for MX25L6405D - -Macronix MX25L6405D supports locking with four block-protection bits. -Currently, the driver only sets three bits. If the bootloader does not -sustain the flash chip in an unlocked state, the flash might be -non-writeable. Add the corresponding flag to enable locking support with -four bits in the status register. - -Tested on Nanostation M2 XM. - -Similar to commit 7ea40b54e83b ("mtd: spi-nor: enable locking support for -MX25L12805D") - -Signed-off-by: David Bauer -Signed-off-by: Nick Hainke ---- - drivers/mtd/spi-nor/macronix.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/spi-nor/macronix.c -+++ b/drivers/mtd/spi-nor/macronix.c -@@ -48,6 +48,7 @@ static const struct flash_info macronix_ - { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64) - NO_SFDP_FLAGS(SECT_4K) }, - { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128) -+ FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP) - NO_SFDP_FLAGS(SECT_4K) }, - { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4) - NO_SFDP_FLAGS(SECT_4K) }, diff --git a/target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch b/target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch deleted file mode 100644 index 99e0fc72bf718a..00000000000000 --- a/target/linux/generic/pending-6.1/499-mtd-spi-nor-disable-16-bit-sr-for-macronix.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 245224608b5368c10407da07557e546743d3c489 Mon Sep 17 00:00:00 2001 -From: Nick Hainke -Date: Mon, 27 Dec 2021 09:33:13 +0100 -Subject: [PATCH 2/2] mtd: spi-nor: disable 16-bit-sr for macronix - -Macronix flash chips seem to consist of only one status register. -These chips will not work with the "16-bit Write Status (01h) Command". -Disable SNOR_F_HAS_16BIT_SR for all Macronix chips. - -Tested with MX25L6405D. - -Fixes: 39d1e3340c73 ("mtd: spi-nor: Fix clearing of QE bit on -lock()/unlock()") - -Signed-off-by: David Bauer -Signed-off-by: Nick Hainke ---- - drivers/mtd/spi-nor/macronix.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/mtd/spi-nor/macronix.c -+++ b/drivers/mtd/spi-nor/macronix.c -@@ -107,6 +107,7 @@ static void macronix_nor_default_init(st - { - nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; - nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode; -+ nor->flags &= ~SNOR_F_HAS_16BIT_SR; - nor->flags |= SNOR_F_HAS_LOCK; - } - diff --git a/target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch b/target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch deleted file mode 100644 index 2053c0fbe2e095..00000000000000 --- a/target/linux/generic/pending-6.1/500-fs_cdrom_dependencies.patch +++ /dev/null @@ -1,52 +0,0 @@ -From af7b91bcecce0eae24e90acd35d96ecee73e1407 Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:21:15 +0200 -Subject: [PATCH] fs: add cdrom dependency - ---- - fs/hfs/Kconfig | 1 + - fs/hfsplus/Kconfig | 1 + - fs/isofs/Kconfig | 1 + - fs/udf/Kconfig | 1 + - 4 files changed, 4 insertions(+) - ---- a/fs/hfs/Kconfig -+++ b/fs/hfs/Kconfig -@@ -2,6 +2,7 @@ - config HFS_FS - tristate "Apple Macintosh file system support" - depends on BLOCK -+ select CDROM - select NLS - help - If you say Y here, you will be able to mount Macintosh-formatted ---- a/fs/hfsplus/Kconfig -+++ b/fs/hfsplus/Kconfig -@@ -2,6 +2,7 @@ - config HFSPLUS_FS - tristate "Apple Extended HFS file system support" - depends on BLOCK -+ select CDROM - select NLS - select NLS_UTF8 - help ---- a/fs/isofs/Kconfig -+++ b/fs/isofs/Kconfig -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - config ISO9660_FS - tristate "ISO 9660 CDROM file system support" -+ select CDROM - help - This is the standard file system used on CD-ROMs. It was previously - known as "High Sierra File System" and is called "hsfs" on other ---- a/fs/udf/Kconfig -+++ b/fs/udf/Kconfig -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - config UDF_FS - tristate "UDF file system support" -+ select CDROM - select CRC_ITU_T - select NLS - help diff --git a/target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch b/target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch deleted file mode 100644 index befc505dbc6bc6..00000000000000 --- a/target/linux/generic/pending-6.1/510-block-add-uImage.FIT-subimage-block-driver.patch +++ /dev/null @@ -1,733 +0,0 @@ -From 6173a065cb395d4a9528c4e49810af127db68141 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 16 Nov 2022 12:49:52 +0000 -Subject: [PATCH 1/2] block: add uImage.FIT subimage block driver - -Add a small block driver which exposes filesystem sub-images contained -in U-Boot uImage.FIT images as block devices. - -The uImage.FIT image has to be stored directly on a block device or -partition, MTD device or partition, or UBI volume. - -The driver is intended for systems using the U-Boot bootloader and -uses the root device hint left by the bootloader (or the user) in -the 'chosen' section of the device-tree. - -Example: -/dts-v1/; -/ { - chosen { - rootdisk = <&mmc0_part3>; - }; -}; - -Signed-off-by: Daniel Golle ---- - MAINTAINERS | 6 + - drivers/block/Kconfig | 12 + - drivers/block/Makefile | 2 + - drivers/block/fitblk.c | 658 ++++++++++++++++++++++++++++++++++++ - drivers/block/open | 4 + - include/uapi/linux/fitblk.h | 10 + - 6 files changed, 692 insertions(+) - create mode 100644 drivers/block/fitblk.c - create mode 100644 drivers/block/open - create mode 100644 include/uapi/linux/fitblk.h - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -21060,6 +21060,12 @@ F: Documentation/filesystems/ubifs-authe - F: Documentation/filesystems/ubifs.rst - F: fs/ubifs/ - -+U-BOOT UIMAGE.FIT PARSER -+M: Daniel Golle -+L: linux-block@vger.kernel.org -+S: Maintained -+F: drivers/block/fitblk.c -+ - UBLK USERSPACE BLOCK DRIVER - M: Ming Lei - L: linux-block@vger.kernel.org ---- a/drivers/block/Kconfig -+++ b/drivers/block/Kconfig -@@ -383,6 +383,18 @@ config VIRTIO_BLK - This is the virtual block driver for virtio. It can be used with - QEMU based VMMs (like KVM or Xen). Say Y or M. - -+config UIMAGE_FIT_BLK -+ bool "uImage.FIT block driver" -+ help -+ This driver allows using filesystems contained in uImage.FIT images -+ by mapping them as block devices. -+ -+ It can currently not be built as a module due to libfdt symbols not -+ being exported. -+ -+ Say Y if you want to mount filesystems sub-images of a uImage.FIT -+ stored in a block device partition, mtdblock or ubiblock device. -+ - config BLK_DEV_RBD - tristate "Rados block device (RBD)" - depends on INET && BLOCK ---- a/drivers/block/Makefile -+++ b/drivers/block/Makefile -@@ -39,4 +39,6 @@ obj-$(CONFIG_BLK_DEV_NULL_BLK) += null_b - - obj-$(CONFIG_BLK_DEV_UBLK) += ublk_drv.o - -+obj-$(CONFIG_UIMAGE_FIT_BLK) += fitblk.o -+ - swim_mod-y := swim.o swim_asm.o ---- /dev/null -+++ b/drivers/block/fitblk.c -@@ -0,0 +1,636 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * uImage.FIT virtual block device driver. -+ * -+ * Copyright (C) 2023 Daniel Golle -+ * Copyright (C) 2007 Nick Piggin -+ * Copyright (C) 2007 Novell Inc. -+ * -+ * Initially derived from drivers/block/brd.c which is in parts derived from -+ * drivers/block/rd.c, and drivers/block/loop.c, copyright of their respective -+ * owners. -+ * -+ * uImage.FIT headers extracted from Das U-Boot -+ * (C) Copyright 2008 Semihalf -+ * (C) Copyright 2000-2005 -+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define FIT_DEVICE_PREFIX "fit" -+ -+/* maximum number of pages used for the uImage.FIT index structure */ -+#define FIT_MAX_PAGES 1024 -+ -+/* minimum free sectors to map as read-write "remainder" volume */ -+#define MIN_FREE_SECT 16 -+ -+/* maximum number of mapped loadables */ -+#define MAX_FIT_LOADABLES 16 -+ -+/* constants for uImage.FIT structrure traversal */ -+#define FIT_IMAGES_PATH "/images" -+#define FIT_CONFS_PATH "/configurations" -+ -+/* hash/signature/key node */ -+#define FIT_HASH_NODENAME "hash" -+#define FIT_ALGO_PROP "algo" -+#define FIT_VALUE_PROP "value" -+#define FIT_IGNORE_PROP "uboot-ignore" -+#define FIT_SIG_NODENAME "signature" -+#define FIT_KEY_REQUIRED "required" -+#define FIT_KEY_HINT "key-name-hint" -+ -+/* cipher node */ -+#define FIT_CIPHER_NODENAME "cipher" -+#define FIT_ALGO_PROP "algo" -+ -+/* image node */ -+#define FIT_DATA_PROP "data" -+#define FIT_DATA_POSITION_PROP "data-position" -+#define FIT_DATA_OFFSET_PROP "data-offset" -+#define FIT_DATA_SIZE_PROP "data-size" -+#define FIT_TIMESTAMP_PROP "timestamp" -+#define FIT_DESC_PROP "description" -+#define FIT_ARCH_PROP "arch" -+#define FIT_TYPE_PROP "type" -+#define FIT_OS_PROP "os" -+#define FIT_COMP_PROP "compression" -+#define FIT_ENTRY_PROP "entry" -+#define FIT_LOAD_PROP "load" -+ -+/* configuration node */ -+#define FIT_KERNEL_PROP "kernel" -+#define FIT_FILESYSTEM_PROP "filesystem" -+#define FIT_RAMDISK_PROP "ramdisk" -+#define FIT_FDT_PROP "fdt" -+#define FIT_LOADABLE_PROP "loadables" -+#define FIT_DEFAULT_PROP "default" -+#define FIT_SETUP_PROP "setup" -+#define FIT_FPGA_PROP "fpga" -+#define FIT_FIRMWARE_PROP "firmware" -+#define FIT_STANDALONE_PROP "standalone" -+ -+/* fitblk driver data */ -+static const char *_fitblk_claim_ptr = "I belong to fitblk"; -+static const char *ubootver; -+struct device_node *rootdisk; -+static struct platform_device *pdev; -+static LIST_HEAD(fitblk_devices); -+static DEFINE_MUTEX(devices_mutex); -+refcount_t num_devs; -+ -+struct fitblk { -+ struct platform_device *pdev; -+ struct block_device *lower_bdev; -+ sector_t start_sect; -+ struct gendisk *disk; -+ struct work_struct remove_work; -+ struct list_head list; -+ bool dead; -+}; -+ -+static int fitblk_open(struct block_device *bdev, fmode_t mode) -+{ -+ struct fitblk *fitblk = bdev->bd_disk->private_data; -+ -+ if (fitblk->dead) -+ return -ENOENT; -+ -+ return 0; -+} -+ -+static void fitblk_release(struct gendisk *disk, fmode_t mode) -+{ -+ return; -+} -+ -+static void fitblk_submit_bio(struct bio *orig_bio) -+{ -+ struct bio *bio = orig_bio; -+ struct fitblk *fitblk = bio->bi_bdev->bd_disk->private_data; -+ -+ if (fitblk->dead) -+ return; -+ -+ /* mangle bio and re-submit */ -+ while (bio) { -+ bio->bi_iter.bi_sector += fitblk->start_sect; -+ bio->bi_bdev = fitblk->lower_bdev; -+ bio = bio->bi_next; -+ } -+ submit_bio(orig_bio); -+} -+ -+static void fitblk_remove(struct fitblk *fitblk) -+{ -+ blk_mark_disk_dead(fitblk->disk); -+ mutex_lock(&devices_mutex); -+ fitblk->dead = true; -+ list_del(&fitblk->list); -+ mutex_unlock(&devices_mutex); -+ -+ schedule_work(&fitblk->remove_work); -+} -+ -+static int fitblk_ioctl(struct block_device *bdev, fmode_t mode, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct fitblk *fitblk = bdev->bd_disk->private_data; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ if (fitblk->dead) -+ return -ENOENT; -+ -+ switch (cmd) { -+ case FITBLK_RELEASE: -+ fitblk_remove(fitblk); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static const struct block_device_operations fitblk_fops = { -+ .owner = THIS_MODULE, -+ .ioctl = fitblk_ioctl, -+ .open = fitblk_open, -+ .release = fitblk_release, -+ .submit_bio = fitblk_submit_bio, -+}; -+ -+static void fitblk_purge(struct work_struct *work) -+{ -+ struct fitblk *fitblk = container_of(work, struct fitblk, remove_work); -+ -+ //del_gendisk(fitblk->disk); // causes crash, not doing it doesn't matter -+ refcount_dec(&num_devs); -+ platform_device_del(fitblk->pdev); -+ platform_device_put(fitblk->pdev); -+ -+ if (refcount_dec_if_one(&num_devs)) { -+ sysfs_remove_link(&pdev->dev.kobj, "lower_dev"); -+ blkdev_put(fitblk->lower_bdev, FMODE_READ | FMODE_EXCL); -+ } -+ -+ kfree(fitblk); -+} -+ -+static int add_fit_subimage_device(struct block_device *lower_bdev, -+ unsigned int slot, sector_t start_sect, -+ sector_t nr_sect, bool readonly) -+{ -+ struct fitblk *fitblk; -+ struct gendisk *disk; -+ int err; -+ -+ mutex_lock(&devices_mutex); -+ if (!refcount_inc_not_zero(&num_devs)) -+ return -EBADF; -+ -+ fitblk = kzalloc(sizeof(struct fitblk), GFP_KERNEL); -+ if (!fitblk) { -+ err = -ENOMEM; -+ goto out_unlock; -+ } -+ -+ fitblk->lower_bdev = lower_bdev; -+ fitblk->start_sect = start_sect; -+ INIT_WORK(&fitblk->remove_work, fitblk_purge); -+ -+ disk = blk_alloc_disk(NUMA_NO_NODE); -+ if (!disk) { -+ err = -ENOMEM; -+ goto out_free_fitblk; -+ } -+ -+ disk->first_minor = 0; -+ disk->flags = lower_bdev->bd_disk->flags | GENHD_FL_NO_PART; -+ disk->fops = &fitblk_fops; -+ disk->private_data = fitblk; -+ if (readonly) { -+ set_disk_ro(disk, 1); -+ snprintf(disk->disk_name, sizeof(disk->disk_name), FIT_DEVICE_PREFIX "%u", slot); -+ } else { -+ strcpy(disk->disk_name, FIT_DEVICE_PREFIX "rw"); -+ } -+ -+ set_capacity(disk, nr_sect); -+ -+ disk->queue->queue_flags = lower_bdev->bd_disk->queue->queue_flags; -+ memcpy(&disk->queue->limits, &lower_bdev->bd_disk->queue->limits, -+ sizeof(struct queue_limits)); -+ -+ fitblk->disk = disk; -+ fitblk->pdev = platform_device_alloc(disk->disk_name, PLATFORM_DEVID_NONE); -+ if (!fitblk->pdev) { -+ err = -ENOMEM; -+ goto out_cleanup_disk; -+ } -+ -+ fitblk->pdev->dev.parent = &pdev->dev; -+ err = platform_device_add(fitblk->pdev); -+ if (err) -+ goto out_put_pdev; -+ -+ err = device_add_disk(&fitblk->pdev->dev, disk, NULL); -+ if (err) -+ goto out_del_pdev; -+ -+ if (!ROOT_DEV) -+ ROOT_DEV = disk->part0->bd_dev; -+ -+ list_add_tail(&fitblk->list, &fitblk_devices); -+ -+ mutex_unlock(&devices_mutex); -+ -+ return 0; -+ -+out_del_pdev: -+ platform_device_del(fitblk->pdev); -+out_put_pdev: -+ platform_device_put(fitblk->pdev); -+out_cleanup_disk: -+ put_disk(disk); -+out_free_fitblk: -+ kfree(fitblk); -+out_unlock: -+ refcount_dec(&num_devs); -+ mutex_unlock(&devices_mutex); -+ return err; -+} -+ -+static int parse_fit_on_dev(struct device *dev) -+{ -+ struct block_device *bdev; -+ struct address_space *mapping; -+ struct folio *folio; -+ pgoff_t f_index = 0; -+ size_t bytes_left, bytes_to_copy; -+ void *pre_fit, *fit, *fit_c; -+ u64 dsize, dsectors, imgmaxsect = 0; -+ u32 size, image_pos, image_len; -+ const __be32 *image_offset_be, *image_len_be, *image_pos_be; -+ int ret = 0, node, images, config; -+ const char *image_name, *image_type, *image_description, -+ *config_default, *config_description, *config_loadables; -+ u32 image_name_len, image_type_len, image_description_len, -+ bootconf_len, config_default_len, config_description_len, -+ config_loadables_len; -+ sector_t start_sect, nr_sects; -+ struct device_node *np = NULL; -+ const char *bootconf_c; -+ const char *loadable; -+ char *bootconf = NULL, *bootconf_term; -+ bool found; -+ int loadables_rem_len, loadable_len; -+ u16 loadcnt; -+ unsigned int slot = 0; -+ -+ /* Exclusive open the block device to receive holder notifications */ -+ bdev = blkdev_get_by_dev(dev->devt, FMODE_READ | FMODE_EXCL, &_fitblk_claim_ptr); -+ if (!bdev) -+ return -ENODEV; -+ -+ if (IS_ERR(bdev)) -+ return PTR_ERR(bdev); -+ -+ mapping = bdev->bd_inode->i_mapping; -+ -+ /* map first page */ -+ folio = read_mapping_folio(mapping, f_index++, NULL); -+ if (IS_ERR(folio)) { -+ ret = PTR_ERR(folio); -+ goto out_blkdev; -+ } -+ pre_fit = folio_address(folio) + offset_in_folio(folio, 0); -+ -+ /* uImage.FIT is based on flattened device tree structure */ -+ if (fdt_check_header(pre_fit)) { -+ ret = -EINVAL; -+ folio_put(folio); -+ goto out_blkdev; -+ } -+ -+ size = fdt_totalsize(pre_fit); -+ -+ if (size > PAGE_SIZE * FIT_MAX_PAGES) { -+ ret = -EOPNOTSUPP; -+ folio_put(folio); -+ goto out_blkdev; -+ } -+ -+ /* acquire disk size */ -+ dsectors = bdev_nr_sectors(bdev); -+ dsize = dsectors << SECTOR_SHIFT; -+ -+ /* abort if FIT structure is larger than disk or partition size */ -+ if (size >= dsize) { -+ ret = -EFBIG; -+ folio_put(folio); -+ goto out_blkdev; -+ } -+ -+ fit = kmalloc(size, GFP_KERNEL); -+ if (!fit) { -+ ret = -ENOMEM; -+ folio_put(folio); -+ goto out_blkdev; -+ } -+ -+ bytes_left = size; -+ fit_c = fit; -+ while (bytes_left > 0) { -+ bytes_to_copy = min_t(size_t, bytes_left, -+ folio_size(folio) - offset_in_folio(folio, 0)); -+ memcpy(fit_c, pre_fit, bytes_to_copy); -+ fit_c += bytes_to_copy; -+ bytes_left -= bytes_to_copy; -+ if (bytes_left) { -+ folio_put(folio); -+ folio = read_mapping_folio(mapping, f_index++, NULL); -+ if (IS_ERR(folio)) { -+ ret = PTR_ERR(folio); -+ goto out_blkdev; -+ }; -+ pre_fit = folio_address(folio) + offset_in_folio(folio, 0); -+ } -+ } -+ folio_put(folio); -+ -+ /* set boot config node name U-Boot may have added to the device tree */ -+ np = of_find_node_by_path("/chosen"); -+ if (np) { -+ bootconf_c = of_get_property(np, "u-boot,bootconf", &bootconf_len); -+ if (bootconf_c && bootconf_len) -+ bootconf = kmemdup_nul(bootconf_c, bootconf_len, GFP_KERNEL); -+ } -+ -+ if (bootconf) { -+ bootconf_term = strchr(bootconf, '#'); -+ if (bootconf_term) -+ *bootconf_term = '\0'; -+ } -+ -+ /* find configuration path in uImage.FIT */ -+ config = fdt_path_offset(fit, FIT_CONFS_PATH); -+ if (config < 0) { -+ pr_err("FIT: Cannot find %s node: %d\n", -+ FIT_CONFS_PATH, config); -+ ret = -ENOENT; -+ goto out_bootconf; -+ } -+ -+ /* get default configuration node name */ -+ config_default = -+ fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len); -+ -+ /* make sure we got either default or selected boot config node name */ -+ if (!config_default && !bootconf) { -+ pr_err("FIT: Cannot find default configuration\n"); -+ ret = -ENOENT; -+ goto out_bootconf; -+ } -+ -+ /* find selected boot config node, fallback on default config node */ -+ node = fdt_subnode_offset(fit, config, bootconf ?: config_default); -+ if (node < 0) { -+ pr_err("FIT: Cannot find %s node: %d\n", -+ bootconf ?: config_default, node); -+ ret = -ENOENT; -+ goto out_bootconf; -+ } -+ -+ pr_info("FIT: Detected U-Boot %s\n", ubootver); -+ -+ /* get selected configuration data */ -+ config_description = -+ fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len); -+ config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP, -+ &config_loadables_len); -+ -+ pr_info("FIT: %s configuration: \"%.*s\"%s%.*s%s\n", -+ bootconf ? "Selected" : "Default", -+ bootconf ? bootconf_len : config_default_len, -+ bootconf ?: config_default, -+ config_description ? " (" : "", -+ config_description ? config_description_len : 0, -+ config_description ?: "", -+ config_description ? ")" : ""); -+ -+ if (!config_loadables || !config_loadables_len) { -+ pr_err("FIT: No loadables configured in \"%s\"\n", -+ bootconf ?: config_default); -+ ret = -ENOENT; -+ goto out_bootconf; -+ } -+ -+ /* get images path in uImage.FIT */ -+ images = fdt_path_offset(fit, FIT_IMAGES_PATH); -+ if (images < 0) { -+ pr_err("FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images); -+ ret = -EINVAL; -+ goto out_bootconf; -+ } -+ -+ /* iterate over images in uImage.FIT */ -+ fdt_for_each_subnode(node, fit, images) { -+ image_name = fdt_get_name(fit, node, &image_name_len); -+ image_type = fdt_getprop(fit, node, FIT_TYPE_PROP, &image_type_len); -+ image_offset_be = fdt_getprop(fit, node, FIT_DATA_OFFSET_PROP, NULL); -+ image_pos_be = fdt_getprop(fit, node, FIT_DATA_POSITION_PROP, NULL); -+ image_len_be = fdt_getprop(fit, node, FIT_DATA_SIZE_PROP, NULL); -+ -+ if (!image_name || !image_type || !image_len_be || -+ !image_name_len || !image_type_len) -+ continue; -+ -+ image_len = be32_to_cpu(*image_len_be); -+ if (!image_len) -+ continue; -+ -+ if (image_offset_be) -+ image_pos = be32_to_cpu(*image_offset_be) + size; -+ else if (image_pos_be) -+ image_pos = be32_to_cpu(*image_pos_be); -+ else -+ continue; -+ -+ image_description = fdt_getprop(fit, node, FIT_DESC_PROP, -+ &image_description_len); -+ -+ pr_info("FIT: %16s sub-image 0x%08x..0x%08x \"%.*s\"%s%.*s%s\n", -+ image_type, image_pos, image_pos + image_len - 1, -+ image_name_len, image_name, image_description ? " (" : "", -+ image_description ? image_description_len : 0, -+ image_description ?: "", image_description ? ") " : ""); -+ -+ /* only 'filesystem' images should be mapped as partitions */ -+ if (strncmp(image_type, FIT_FILESYSTEM_PROP, image_type_len)) -+ continue; -+ -+ /* check if sub-image is part of configured loadables */ -+ found = false; -+ loadable = config_loadables; -+ loadables_rem_len = config_loadables_len; -+ for (loadcnt = 0; loadables_rem_len > 1 && -+ loadcnt < MAX_FIT_LOADABLES; ++loadcnt) { -+ loadable_len = -+ strnlen(loadable, loadables_rem_len - 1) + 1; -+ loadables_rem_len -= loadable_len; -+ if (!strncmp(image_name, loadable, loadable_len)) { -+ found = true; -+ break; -+ } -+ loadable += loadable_len; -+ } -+ if (!found) -+ continue; -+ -+ if (image_pos % (1 << PAGE_SHIFT)) { -+ dev_err(dev, "FIT: image %.*s start not aligned to page boundaries, skipping\n", -+ image_name_len, image_name); -+ continue; -+ } -+ -+ if (image_len % (1 << PAGE_SHIFT)) { -+ dev_err(dev, "FIT: sub-image %.*s end not aligned to page boundaries, skipping\n", -+ image_name_len, image_name); -+ continue; -+ } -+ -+ start_sect = image_pos >> SECTOR_SHIFT; -+ nr_sects = image_len >> SECTOR_SHIFT; -+ imgmaxsect = max_t(sector_t, imgmaxsect, start_sect + nr_sects); -+ -+ if (start_sect + nr_sects > dsectors) { -+ dev_err(dev, "FIT: sub-image %.*s disk access beyond EOD\n", -+ image_name_len, image_name); -+ continue; -+ } -+ -+ if (!slot) { -+ ret = sysfs_create_link_nowarn(&pdev->dev.kobj, bdev_kobj(bdev), "lower_dev"); -+ if (ret && ret != -EEXIST) -+ goto out_bootconf; -+ -+ ret = 0; -+ } -+ -+ add_fit_subimage_device(bdev, slot++, start_sect, nr_sects, true); -+ } -+ -+ if (!found || !slot) -+ goto out_bootconf; -+ -+ dev_info(dev, "mapped %u uImage.FIT filesystem sub-image%s as /dev/fit%s%u%s\n", -+ slot, (slot > 1)?"s":"", (slot > 1)?"[0...":"", slot - 1, -+ (slot > 1)?"]":""); -+ -+ /* in case uImage.FIT is stored in a partition, map the remaining space */ -+ if (!bdev->bd_read_only && bdev_is_partition(bdev) && -+ (imgmaxsect + MIN_FREE_SECT) < dsectors) { -+ add_fit_subimage_device(bdev, slot++, imgmaxsect, -+ dsectors - imgmaxsect, false); -+ dev_info(dev, "mapped remaining space as /dev/fitrw\n"); -+ } -+ -+out_bootconf: -+ kfree(bootconf); -+ kfree(fit); -+out_blkdev: -+ if (!found || ret) -+ blkdev_put(bdev, FMODE_READ | FMODE_EXCL); -+ -+ return ret; -+} -+ -+static int fitblk_match_of_node(struct device *dev, const void *np) -+{ -+ int ret; -+ -+ ret = device_match_of_node(dev, np); -+ if (ret) -+ return ret; -+ -+ /* -+ * To match ubiblock and mtdblock devices by their parent ubi -+ * or mtd device, also consider block device parent -+ */ -+ if (!dev->parent) -+ return 0; -+ -+ return device_match_of_node(dev->parent, np); -+} -+ -+static int fitblk_probe(struct platform_device *pdev) -+{ -+ struct device *dev; -+ -+ dev = class_find_device(&block_class, NULL, rootdisk, fitblk_match_of_node); -+ if (!dev) -+ return -EPROBE_DEFER; -+ -+ return parse_fit_on_dev(dev); -+} -+ -+static struct platform_driver fitblk_driver = { -+ .probe = fitblk_probe, -+ .driver = { -+ .name = "fitblk", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init fitblk_init(void) -+{ -+ /* detect U-Boot firmware */ -+ ubootver = of_get_property(of_chosen, "u-boot,version", NULL); -+ if (!ubootver) -+ return 0; -+ -+ /* parse 'rootdisk' property phandle */ -+ rootdisk = of_parse_phandle(of_chosen, "rootdisk", 0); -+ if (!rootdisk) -+ return 0; -+ -+ if (platform_driver_register(&fitblk_driver)) -+ return -ENODEV; -+ -+ refcount_set(&num_devs, 1); -+ pdev = platform_device_register_simple("fitblk", -1, NULL, 0); -+ if (IS_ERR(pdev)) -+ return PTR_ERR(pdev); -+ -+ return 0; -+} -+device_initcall(fitblk_init); ---- /dev/null -+++ b/include/uapi/linux/fitblk.h -@@ -0,0 +1,10 @@ -+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ -+#ifndef _UAPI_LINUX_FITBLK_H -+#define _UAPI_LINUX_FITBLK_H -+ -+/* -+ * IOCTL commands --- we will commandeer 0x46 ('F') -+ */ -+#define FITBLK_RELEASE 0x4600 -+ -+#endif /* _UAPI_LINUX_FITBLK_H */ diff --git a/target/linux/generic/pending-6.1/511-init-bypass-device-lookup-for-dev-fit-rootfs.patch b/target/linux/generic/pending-6.1/511-init-bypass-device-lookup-for-dev-fit-rootfs.patch deleted file mode 100644 index 685a5f9da510ba..00000000000000 --- a/target/linux/generic/pending-6.1/511-init-bypass-device-lookup-for-dev-fit-rootfs.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 5ede3f8aed9a1a579bf7304142600d1f3500add9 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 12 Jun 2023 03:58:42 +0100 -Subject: [PATCH 2/2] init: bypass device lookup for /dev/fit* rootfs - -Allow 'rootwait' as /dev/fit* can show up late if the underlaying -device is probed late. - -Signed-off-by: Daniel Golle ---- - init/do_mounts.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/init/do_mounts.c -+++ b/init/do_mounts.c -@@ -645,7 +645,8 @@ void __init prepare_namespace(void) - - if (saved_root_name[0]) { - root_device_name = saved_root_name; -- if (!strncmp(root_device_name, "mtd", 3) || -+ if (!strncmp(root_device_name, "fit", 3) || -+ !strncmp(root_device_name, "mtd", 3) || - !strncmp(root_device_name, "ubi", 3)) { - mount_block_root(root_device_name, root_mountflags); - goto out; diff --git a/target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch b/target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch deleted file mode 100644 index 5dd47ef388940e..00000000000000 --- a/target/linux/generic/pending-6.1/530-jffs2_make_lzma_available.patch +++ /dev/null @@ -1,5180 +0,0 @@ -From: Alexandros C. Couloumbis -Subject: fs: add jffs2/lzma support (not activated by default yet) - -lede-commit: c2c88d315fa0e881f8b19da07b62859b915b11b2 -Signed-off-by: Alexandros C. Couloumbis ---- - fs/jffs2/Kconfig | 9 + - fs/jffs2/Makefile | 3 + - fs/jffs2/compr.c | 6 + - fs/jffs2/compr.h | 10 +- - fs/jffs2/compr_lzma.c | 128 +++ - fs/jffs2/super.c | 33 +- - include/linux/lzma.h | 62 ++ - include/linux/lzma/LzFind.h | 115 +++ - include/linux/lzma/LzHash.h | 54 + - include/linux/lzma/LzmaDec.h | 231 +++++ - include/linux/lzma/LzmaEnc.h | 80 ++ - include/linux/lzma/Types.h | 226 +++++ - include/uapi/linux/jffs2.h | 1 + - lib/Kconfig | 6 + - lib/Makefile | 12 + - lib/lzma/LzFind.c | 761 ++++++++++++++ - lib/lzma/LzmaDec.c | 999 +++++++++++++++++++ - lib/lzma/LzmaEnc.c | 2271 ++++++++++++++++++++++++++++++++++++++++++ - lib/lzma/Makefile | 7 + - 19 files changed, 5008 insertions(+), 6 deletions(-) - create mode 100644 fs/jffs2/compr_lzma.c - create mode 100644 include/linux/lzma.h - create mode 100644 include/linux/lzma/LzFind.h - create mode 100644 include/linux/lzma/LzHash.h - create mode 100644 include/linux/lzma/LzmaDec.h - create mode 100644 include/linux/lzma/LzmaEnc.h - create mode 100644 include/linux/lzma/Types.h - create mode 100644 lib/lzma/LzFind.c - create mode 100644 lib/lzma/LzmaDec.c - create mode 100644 lib/lzma/LzmaEnc.c - create mode 100644 lib/lzma/Makefile - ---- a/fs/jffs2/Kconfig -+++ b/fs/jffs2/Kconfig -@@ -136,6 +136,15 @@ config JFFS2_LZO - This feature was added in July, 2007. Say 'N' if you need - compatibility with older bootloaders or kernels. - -+config JFFS2_LZMA -+ bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS -+ select LZMA_COMPRESS -+ select LZMA_DECOMPRESS -+ depends on JFFS2_FS -+ default n -+ help -+ JFFS2 wrapper to the LZMA C SDK -+ - config JFFS2_RTIME - bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS - depends on JFFS2_FS ---- a/fs/jffs2/Makefile -+++ b/fs/jffs2/Makefile -@@ -19,4 +19,7 @@ jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rub - jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o - jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o - jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o -+jffs2-$(CONFIG_JFFS2_LZMA) += compr_lzma.o - jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o -+ -+CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma ---- a/fs/jffs2/compr.c -+++ b/fs/jffs2/compr.c -@@ -378,6 +378,9 @@ int __init jffs2_compressors_init(void) - #ifdef CONFIG_JFFS2_LZO - jffs2_lzo_init(); - #endif -+#ifdef CONFIG_JFFS2_LZMA -+ jffs2_lzma_init(); -+#endif - /* Setting default compression mode */ - #ifdef CONFIG_JFFS2_CMODE_NONE - jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; -@@ -401,6 +404,9 @@ int __init jffs2_compressors_init(void) - int jffs2_compressors_exit(void) - { - /* Unregistering compressors */ -+#ifdef CONFIG_JFFS2_LZMA -+ jffs2_lzma_exit(); -+#endif - #ifdef CONFIG_JFFS2_LZO - jffs2_lzo_exit(); - #endif ---- a/fs/jffs2/compr.h -+++ b/fs/jffs2/compr.h -@@ -29,9 +29,9 @@ - #define JFFS2_DYNRUBIN_PRIORITY 20 - #define JFFS2_LZARI_PRIORITY 30 - #define JFFS2_RTIME_PRIORITY 50 --#define JFFS2_ZLIB_PRIORITY 60 --#define JFFS2_LZO_PRIORITY 80 -- -+#define JFFS2_LZMA_PRIORITY 70 -+#define JFFS2_ZLIB_PRIORITY 80 -+#define JFFS2_LZO_PRIORITY 90 - - #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ - #define JFFS2_DYNRUBIN_DISABLED /* for decompression */ -@@ -101,5 +101,9 @@ void jffs2_zlib_exit(void); - int jffs2_lzo_init(void); - void jffs2_lzo_exit(void); - #endif -+#ifdef CONFIG_JFFS2_LZMA -+int jffs2_lzma_init(void); -+void jffs2_lzma_exit(void); -+#endif - - #endif /* __JFFS2_COMPR_H__ */ ---- /dev/null -+++ b/fs/jffs2/compr_lzma.c -@@ -0,0 +1,128 @@ -+/* -+ * JFFS2 -- Journalling Flash File System, Version 2. -+ * -+ * For licensing information, see the file 'LICENCE' in this directory. -+ * -+ * JFFS2 wrapper to the LZMA C SDK -+ * -+ */ -+ -+#include -+#include "compr.h" -+ -+#ifdef __KERNEL__ -+ static DEFINE_MUTEX(deflate_mutex); -+#endif -+ -+CLzmaEncHandle *p; -+Byte propsEncoded[LZMA_PROPS_SIZE]; -+SizeT propsSize = sizeof(propsEncoded); -+ -+STATIC void lzma_free_workspace(void) -+{ -+ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); -+} -+ -+STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) -+{ -+ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) -+ { -+ PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); -+ return -ENOMEM; -+ } -+ -+ if (LzmaEnc_SetProps(p, props) != SZ_OK) -+ { -+ lzma_free_workspace(); -+ return -1; -+ } -+ -+ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) -+ { -+ lzma_free_workspace(); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t *sourcelen, uint32_t *dstlen) -+{ -+ SizeT compress_size = (SizeT)(*dstlen); -+ int ret; -+ -+ #ifdef __KERNEL__ -+ mutex_lock(&deflate_mutex); -+ #endif -+ -+ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, -+ 0, NULL, &lzma_alloc, &lzma_alloc); -+ -+ #ifdef __KERNEL__ -+ mutex_unlock(&deflate_mutex); -+ #endif -+ -+ if (ret != SZ_OK) -+ return -1; -+ -+ *dstlen = (uint32_t)compress_size; -+ -+ return 0; -+} -+ -+STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, -+ uint32_t srclen, uint32_t destlen) -+{ -+ int ret; -+ SizeT dl = (SizeT)destlen; -+ SizeT sl = (SizeT)srclen; -+ ELzmaStatus status; -+ -+ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, -+ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); -+ -+ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) -+ return -1; -+ -+ return 0; -+} -+ -+static struct jffs2_compressor jffs2_lzma_comp = { -+ .priority = JFFS2_LZMA_PRIORITY, -+ .name = "lzma", -+ .compr = JFFS2_COMPR_LZMA, -+ .compress = &jffs2_lzma_compress, -+ .decompress = &jffs2_lzma_decompress, -+ .disabled = 0, -+}; -+ -+int INIT jffs2_lzma_init(void) -+{ -+ int ret; -+ CLzmaEncProps props; -+ LzmaEncProps_Init(&props); -+ -+ props.dictSize = LZMA_BEST_DICT(0x2000); -+ props.level = LZMA_BEST_LEVEL; -+ props.lc = LZMA_BEST_LC; -+ props.lp = LZMA_BEST_LP; -+ props.pb = LZMA_BEST_PB; -+ props.fb = LZMA_BEST_FB; -+ -+ ret = lzma_alloc_workspace(&props); -+ if (ret < 0) -+ return ret; -+ -+ ret = jffs2_register_compressor(&jffs2_lzma_comp); -+ if (ret) -+ lzma_free_workspace(); -+ -+ return ret; -+} -+ -+void jffs2_lzma_exit(void) -+{ -+ jffs2_unregister_compressor(&jffs2_lzma_comp); -+ lzma_free_workspace(); -+} ---- a/fs/jffs2/super.c -+++ b/fs/jffs2/super.c -@@ -375,14 +375,41 @@ static int __init init_jffs2_fs(void) - BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); - BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); - -- pr_info("version 2.2." -+ pr_info("version 2.2" - #ifdef CONFIG_JFFS2_FS_WRITEBUFFER - " (NAND)" - #endif - #ifdef CONFIG_JFFS2_SUMMARY -- " (SUMMARY) " -+ " (SUMMARY)" - #endif -- " © 2001-2006 Red Hat, Inc.\n"); -+#ifdef CONFIG_JFFS2_ZLIB -+ " (ZLIB)" -+#endif -+#ifdef CONFIG_JFFS2_LZO -+ " (LZO)" -+#endif -+#ifdef CONFIG_JFFS2_LZMA -+ " (LZMA)" -+#endif -+#ifdef CONFIG_JFFS2_RTIME -+ " (RTIME)" -+#endif -+#ifdef CONFIG_JFFS2_RUBIN -+ " (RUBIN)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_NONE -+ " (CMODE_NONE)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_PRIORITY -+ " (CMODE_PRIORITY)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_SIZE -+ " (CMODE_SIZE)" -+#endif -+#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO -+ " (CMODE_FAVOURLZO)" -+#endif -+ " (c) 2001-2006 Red Hat, Inc.\n"); - - jffs2_inode_cachep = kmem_cache_create("jffs2_i", - sizeof(struct jffs2_inode_info), ---- /dev/null -+++ b/include/linux/lzma.h -@@ -0,0 +1,62 @@ -+#ifndef __LZMA_H__ -+#define __LZMA_H__ -+ -+#ifdef __KERNEL__ -+ #include -+ #include -+ #include -+ #include -+ #include -+ #define LZMA_MALLOC vmalloc -+ #define LZMA_FREE vfree -+ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg) -+ #define INIT __init -+ #define STATIC static -+#else -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #include -+ #ifndef PAGE_SIZE -+ extern int page_size; -+ #define PAGE_SIZE page_size -+ #endif -+ #define LZMA_MALLOC malloc -+ #define LZMA_FREE free -+ #define PRINT_ERROR(msg) fprintf(stderr, msg) -+ #define INIT -+ #define STATIC -+#endif -+ -+#include "lzma/LzmaDec.h" -+#include "lzma/LzmaEnc.h" -+ -+#define LZMA_BEST_LEVEL (9) -+#define LZMA_BEST_LC (0) -+#define LZMA_BEST_LP (0) -+#define LZMA_BEST_PB (0) -+#define LZMA_BEST_FB (273) -+ -+#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2) -+ -+static void *p_lzma_malloc(void *p, size_t size) -+{ -+ if (size == 0) -+ return NULL; -+ -+ return LZMA_MALLOC(size); -+} -+ -+static void p_lzma_free(void *p, void *address) -+{ -+ if (address != NULL) -+ LZMA_FREE(address); -+} -+ -+static ISzAlloc lzma_alloc = { .Alloc = p_lzma_malloc, .Free = p_lzma_free }; -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzFind.h -@@ -0,0 +1,115 @@ -+/* LzFind.h -- Match finder for LZ algorithms -+2009-04-22 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZ_FIND_H -+#define __LZ_FIND_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+typedef UInt32 CLzRef; -+ -+typedef struct _CMatchFinder -+{ -+ Byte *buffer; -+ UInt32 pos; -+ UInt32 posLimit; -+ UInt32 streamPos; -+ UInt32 lenLimit; -+ -+ UInt32 cyclicBufferPos; -+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ -+ -+ UInt32 matchMaxLen; -+ CLzRef *hash; -+ CLzRef *son; -+ UInt32 hashMask; -+ UInt32 cutValue; -+ -+ Byte *bufferBase; -+ ISeqInStream *stream; -+ int streamEndWasReached; -+ -+ UInt32 blockSize; -+ UInt32 keepSizeBefore; -+ UInt32 keepSizeAfter; -+ -+ UInt32 numHashBytes; -+ int directInput; -+ size_t directInputRem; -+ int btMode; -+ int bigHash; -+ UInt32 historySize; -+ UInt32 fixedHashSize; -+ UInt32 hashSizeSum; -+ UInt32 numSons; -+ SRes result; -+ UInt32 crc[256]; -+} CMatchFinder; -+ -+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) -+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) -+ -+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) -+ -+int MatchFinder_NeedMove(CMatchFinder *p); -+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); -+void MatchFinder_MoveBlock(CMatchFinder *p); -+void MatchFinder_ReadIfRequired(CMatchFinder *p); -+ -+void MatchFinder_Construct(CMatchFinder *p); -+ -+/* Conditions: -+ historySize <= 3 GB -+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB -+*/ -+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc); -+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); -+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); -+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); -+ -+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, -+ UInt32 *distances, UInt32 maxLen); -+ -+/* -+Conditions: -+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. -+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function -+*/ -+ -+typedef void (*Mf_Init_Func)(void *object); -+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); -+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); -+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); -+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); -+typedef void (*Mf_Skip_Func)(void *object, UInt32); -+ -+typedef struct _IMatchFinder -+{ -+ Mf_Init_Func Init; -+ Mf_GetIndexByte_Func GetIndexByte; -+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; -+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; -+ Mf_GetMatches_Func GetMatches; -+ Mf_Skip_Func Skip; -+} IMatchFinder; -+ -+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); -+ -+void MatchFinder_Init(CMatchFinder *p); -+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); -+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzHash.h -@@ -0,0 +1,54 @@ -+/* LzHash.h -- HASH functions for LZ algorithms -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZ_HASH_H -+#define __LZ_HASH_H -+ -+#define kHash2Size (1 << 10) -+#define kHash3Size (1 << 16) -+#define kHash4Size (1 << 20) -+ -+#define kFix3HashSize (kHash2Size) -+#define kFix4HashSize (kHash2Size + kHash3Size) -+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) -+ -+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); -+ -+#define HASH3_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } -+ -+#define HASH4_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } -+ -+#define HASH5_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ -+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ -+ hash4Value &= (kHash4Size - 1); } -+ -+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ -+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; -+ -+ -+#define MT_HASH2_CALC \ -+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); -+ -+#define MT_HASH3_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } -+ -+#define MT_HASH4_CALC { \ -+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ -+ hash2Value = temp & (kHash2Size - 1); \ -+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ -+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzmaDec.h -@@ -0,0 +1,231 @@ -+/* LzmaDec.h -- LZMA Decoder -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZMA_DEC_H -+#define __LZMA_DEC_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* #define _LZMA_PROB32 */ -+/* _LZMA_PROB32 can increase the speed on some CPUs, -+ but memory usage for CLzmaDec::probs will be doubled in that case */ -+ -+#ifdef _LZMA_PROB32 -+#define CLzmaProb UInt32 -+#else -+#define CLzmaProb UInt16 -+#endif -+ -+ -+/* ---------- LZMA Properties ---------- */ -+ -+#define LZMA_PROPS_SIZE 5 -+ -+typedef struct _CLzmaProps -+{ -+ unsigned lc, lp, pb; -+ UInt32 dicSize; -+} CLzmaProps; -+ -+/* LzmaProps_Decode - decodes properties -+Returns: -+ SZ_OK -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+*/ -+ -+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); -+ -+ -+/* ---------- LZMA Decoder state ---------- */ -+ -+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. -+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ -+ -+#define LZMA_REQUIRED_INPUT_MAX 20 -+ -+typedef struct -+{ -+ CLzmaProps prop; -+ CLzmaProb *probs; -+ Byte *dic; -+ const Byte *buf; -+ UInt32 range, code; -+ SizeT dicPos; -+ SizeT dicBufSize; -+ UInt32 processedPos; -+ UInt32 checkDicSize; -+ unsigned state; -+ UInt32 reps[4]; -+ unsigned remainLen; -+ int needFlush; -+ int needInitState; -+ UInt32 numProbs; -+ unsigned tempBufSize; -+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; -+} CLzmaDec; -+ -+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } -+ -+void LzmaDec_Init(CLzmaDec *p); -+ -+/* There are two types of LZMA streams: -+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. -+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ -+ -+typedef enum -+{ -+ LZMA_FINISH_ANY, /* finish at any point */ -+ LZMA_FINISH_END /* block must be finished at the end */ -+} ELzmaFinishMode; -+ -+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! -+ -+ You must use LZMA_FINISH_END, when you know that current output buffer -+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. -+ -+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, -+ and output value of destLen will be less than output buffer size limit. -+ You can check status result also. -+ -+ You can use multiple checks to test data integrity after full decompression: -+ 1) Check Result and "status" variable. -+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. -+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. -+ You must use correct finish mode in that case. */ -+ -+typedef enum -+{ -+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ -+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ -+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ -+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ -+} ELzmaStatus; -+ -+/* ELzmaStatus is used only as output value for function call */ -+ -+ -+/* ---------- Interfaces ---------- */ -+ -+/* There are 3 levels of interfaces: -+ 1) Dictionary Interface -+ 2) Buffer Interface -+ 3) One Call Interface -+ You can select any of these interfaces, but don't mix functions from different -+ groups for same object. */ -+ -+ -+/* There are two variants to allocate state for Dictionary Interface: -+ 1) LzmaDec_Allocate / LzmaDec_Free -+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs -+ You can use variant 2, if you set dictionary buffer manually. -+ For Buffer Interface you must always use variant 1. -+ -+LzmaDec_Allocate* can return: -+ SZ_OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+*/ -+ -+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); -+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); -+ -+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); -+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); -+ -+/* ---------- Dictionary Interface ---------- */ -+ -+/* You can use it, if you want to eliminate the overhead for data copying from -+ dictionary to some other external buffer. -+ You must work with CLzmaDec variables directly in this interface. -+ -+ STEPS: -+ LzmaDec_Constr() -+ LzmaDec_Allocate() -+ for (each new stream) -+ { -+ LzmaDec_Init() -+ while (it needs more decompression) -+ { -+ LzmaDec_DecodeToDic() -+ use data from CLzmaDec::dic and update CLzmaDec::dicPos -+ } -+ } -+ LzmaDec_Free() -+*/ -+ -+/* LzmaDec_DecodeToDic -+ -+ The decoding to internal dictionary buffer (CLzmaDec::dic). -+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (dicLimit). -+ LZMA_FINISH_ANY - Decode just dicLimit bytes. -+ LZMA_FINISH_END - Stream must be finished after dicLimit. -+ -+Returns: -+ SZ_OK -+ status: -+ LZMA_STATUS_FINISHED_WITH_MARK -+ LZMA_STATUS_NOT_FINISHED -+ LZMA_STATUS_NEEDS_MORE_INPUT -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -+ SZ_ERROR_DATA - Data error -+*/ -+ -+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, -+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -+ -+ -+/* ---------- Buffer Interface ---------- */ -+ -+/* It's zlib-like interface. -+ See LzmaDec_DecodeToDic description for information about STEPS and return results, -+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need -+ to work with CLzmaDec variables manually. -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (*destLen). -+ LZMA_FINISH_ANY - Decode just destLen bytes. -+ LZMA_FINISH_END - Stream must be finished after (*destLen). -+*/ -+ -+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, -+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); -+ -+ -+/* ---------- One Call Interface ---------- */ -+ -+/* LzmaDecode -+ -+finishMode: -+ It has meaning only if the decoding reaches output limit (*destLen). -+ LZMA_FINISH_ANY - Decode just destLen bytes. -+ LZMA_FINISH_END - Stream must be finished after (*destLen). -+ -+Returns: -+ SZ_OK -+ status: -+ LZMA_STATUS_FINISHED_WITH_MARK -+ LZMA_STATUS_NOT_FINISHED -+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -+ SZ_ERROR_DATA - Data error -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_UNSUPPORTED - Unsupported properties -+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -+*/ -+ -+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+ ELzmaStatus *status, ISzAlloc *alloc); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/LzmaEnc.h -@@ -0,0 +1,80 @@ -+/* LzmaEnc.h -- LZMA Encoder -+2009-02-07 : Igor Pavlov : Public domain */ -+ -+#ifndef __LZMA_ENC_H -+#define __LZMA_ENC_H -+ -+#include "Types.h" -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define LZMA_PROPS_SIZE 5 -+ -+typedef struct _CLzmaEncProps -+{ -+ int level; /* 0 <= level <= 9 */ -+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version -+ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version -+ default = (1 << 24) */ -+ int lc; /* 0 <= lc <= 8, default = 3 */ -+ int lp; /* 0 <= lp <= 4, default = 0 */ -+ int pb; /* 0 <= pb <= 4, default = 2 */ -+ int algo; /* 0 - fast, 1 - normal, default = 1 */ -+ int fb; /* 5 <= fb <= 273, default = 32 */ -+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ -+ int numHashBytes; /* 2, 3 or 4, default = 4 */ -+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ -+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ -+ int numThreads; /* 1 or 2, default = 2 */ -+} CLzmaEncProps; -+ -+void LzmaEncProps_Init(CLzmaEncProps *p); -+void LzmaEncProps_Normalize(CLzmaEncProps *p); -+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); -+ -+ -+/* ---------- CLzmaEncHandle Interface ---------- */ -+ -+/* LzmaEnc_* functions can return the following exit codes: -+Returns: -+ SZ_OK - OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_PARAM - Incorrect paramater in props -+ SZ_ERROR_WRITE - Write callback error. -+ SZ_ERROR_PROGRESS - some break from progress callback -+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -+*/ -+ -+typedef void * CLzmaEncHandle; -+ -+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); -+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); -+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); -+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); -+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ -+/* ---------- One Call Interface ---------- */ -+ -+/* LzmaEncode -+Return code: -+ SZ_OK - OK -+ SZ_ERROR_MEM - Memory allocation error -+ SZ_ERROR_PARAM - Incorrect paramater -+ SZ_ERROR_OUTPUT_EOF - output buffer overflow -+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -+*/ -+ -+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif ---- /dev/null -+++ b/include/linux/lzma/Types.h -@@ -0,0 +1,226 @@ -+/* Types.h -- Basic types -+2009-11-23 : Igor Pavlov : Public domain */ -+ -+#ifndef __7Z_TYPES_H -+#define __7Z_TYPES_H -+ -+#include -+ -+#ifdef _WIN32 -+#include -+#endif -+ -+#ifndef EXTERN_C_BEGIN -+#ifdef __cplusplus -+#define EXTERN_C_BEGIN extern "C" { -+#define EXTERN_C_END } -+#else -+#define EXTERN_C_BEGIN -+#define EXTERN_C_END -+#endif -+#endif -+ -+EXTERN_C_BEGIN -+ -+#define SZ_OK 0 -+ -+#define SZ_ERROR_DATA 1 -+#define SZ_ERROR_MEM 2 -+#define SZ_ERROR_CRC 3 -+#define SZ_ERROR_UNSUPPORTED 4 -+#define SZ_ERROR_PARAM 5 -+#define SZ_ERROR_INPUT_EOF 6 -+#define SZ_ERROR_OUTPUT_EOF 7 -+#define SZ_ERROR_READ 8 -+#define SZ_ERROR_WRITE 9 -+#define SZ_ERROR_PROGRESS 10 -+#define SZ_ERROR_FAIL 11 -+#define SZ_ERROR_THREAD 12 -+ -+#define SZ_ERROR_ARCHIVE 16 -+#define SZ_ERROR_NO_ARCHIVE 17 -+ -+typedef int SRes; -+ -+#ifdef _WIN32 -+typedef DWORD WRes; -+#else -+typedef int WRes; -+#endif -+ -+#ifndef RINOK -+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } -+#endif -+ -+typedef unsigned char Byte; -+typedef short Int16; -+typedef unsigned short UInt16; -+ -+#ifdef _LZMA_UINT32_IS_ULONG -+typedef long Int32; -+typedef unsigned long UInt32; -+#else -+typedef int Int32; -+typedef unsigned int UInt32; -+#endif -+ -+#ifdef _SZ_NO_INT_64 -+ -+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. -+ NOTES: Some code will work incorrectly in that case! */ -+ -+typedef long Int64; -+typedef unsigned long UInt64; -+ -+#else -+ -+#if defined(_MSC_VER) || defined(__BORLANDC__) -+typedef __int64 Int64; -+typedef unsigned __int64 UInt64; -+#else -+typedef long long int Int64; -+typedef unsigned long long int UInt64; -+#endif -+ -+#endif -+ -+#ifdef _LZMA_NO_SYSTEM_SIZE_T -+typedef UInt32 SizeT; -+#else -+typedef size_t SizeT; -+#endif -+ -+typedef int Bool; -+#define True 1 -+#define False 0 -+ -+ -+#ifdef _WIN32 -+#define MY_STD_CALL __stdcall -+#else -+#define MY_STD_CALL -+#endif -+ -+#ifdef _MSC_VER -+ -+#if _MSC_VER >= 1300 -+#define MY_NO_INLINE __declspec(noinline) -+#else -+#define MY_NO_INLINE -+#endif -+ -+#define MY_CDECL __cdecl -+#define MY_FAST_CALL __fastcall -+ -+#else -+ -+#define MY_CDECL -+#define MY_FAST_CALL -+ -+#endif -+ -+ -+/* The following interfaces use first parameter as pointer to structure */ -+ -+typedef struct -+{ -+ SRes (*Read)(void *p, void *buf, size_t *size); -+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -+ (output(*size) < input(*size)) is allowed */ -+} ISeqInStream; -+ -+/* it can return SZ_ERROR_INPUT_EOF */ -+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); -+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); -+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); -+ -+typedef struct -+{ -+ size_t (*Write)(void *p, const void *buf, size_t size); -+ /* Returns: result - the number of actually written bytes. -+ (result < size) means error */ -+} ISeqOutStream; -+ -+typedef enum -+{ -+ SZ_SEEK_SET = 0, -+ SZ_SEEK_CUR = 1, -+ SZ_SEEK_END = 2 -+} ESzSeek; -+ -+typedef struct -+{ -+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ -+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -+} ISeekInStream; -+ -+typedef struct -+{ -+ SRes (*Look)(void *p, void **buf, size_t *size); -+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. -+ (output(*size) > input(*size)) is not allowed -+ (output(*size) < input(*size)) is allowed */ -+ SRes (*Skip)(void *p, size_t offset); -+ /* offset must be <= output(*size) of Look */ -+ -+ SRes (*Read)(void *p, void *buf, size_t *size); -+ /* reads directly (without buffer). It's same as ISeqInStream::Read */ -+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); -+} ILookInStream; -+ -+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); -+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); -+ -+/* reads via ILookInStream::Read */ -+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); -+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); -+ -+#define LookToRead_BUF_SIZE (1 << 14) -+ -+typedef struct -+{ -+ ILookInStream s; -+ ISeekInStream *realStream; -+ size_t pos; -+ size_t size; -+ Byte buf[LookToRead_BUF_SIZE]; -+} CLookToRead; -+ -+void LookToRead_CreateVTable(CLookToRead *p, int lookahead); -+void LookToRead_Init(CLookToRead *p); -+ -+typedef struct -+{ -+ ISeqInStream s; -+ ILookInStream *realStream; -+} CSecToLook; -+ -+void SecToLook_CreateVTable(CSecToLook *p); -+ -+typedef struct -+{ -+ ISeqInStream s; -+ ILookInStream *realStream; -+} CSecToRead; -+ -+void SecToRead_CreateVTable(CSecToRead *p); -+ -+typedef struct -+{ -+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); -+ /* Returns: result. (result != SZ_OK) means break. -+ Value (UInt64)(Int64)-1 for size means unknown value. */ -+} ICompressProgress; -+ -+typedef struct -+{ -+ void *(*Alloc)(void *p, size_t size); -+ void (*Free)(void *p, void *address); /* address can be 0 */ -+} ISzAlloc; -+ -+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) -+#define IAlloc_Free(p, a) (p)->Free((p), a) -+ -+EXTERN_C_END -+ -+#endif ---- a/include/uapi/linux/jffs2.h -+++ b/include/uapi/linux/jffs2.h -@@ -46,6 +46,7 @@ - #define JFFS2_COMPR_DYNRUBIN 0x05 - #define JFFS2_COMPR_ZLIB 0x06 - #define JFFS2_COMPR_LZO 0x07 -+#define JFFS2_COMPR_LZMA 0x08 - /* Compatibility flags. */ - #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ - #define JFFS2_NODE_ACCURATE 0x2000 ---- a/lib/Kconfig -+++ b/lib/Kconfig -@@ -354,6 +354,12 @@ config ZSTD_DECOMPRESS - - source "lib/xz/Kconfig" - -+config LZMA_COMPRESS -+ tristate -+ -+config LZMA_DECOMPRESS -+ tristate -+ - # - # These all provide a common interface (hence the apparent duplication with - # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -140,6 +140,16 @@ CFLAGS_kobject.o += -DDEBUG - CFLAGS_kobject_uevent.o += -DDEBUG - endif - -+ifdef CONFIG_JFFS2_ZLIB -+ CONFIG_ZLIB_INFLATE:=y -+ CONFIG_ZLIB_DEFLATE:=y -+endif -+ -+ifdef CONFIG_JFFS2_LZMA -+ CONFIG_LZMA_DECOMPRESS:=y -+ CONFIG_LZMA_COMPRESS:=y -+endif -+ - obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o - CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any) - -@@ -200,6 +210,8 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ - obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ - obj-$(CONFIG_XZ_DEC) += xz/ - obj-$(CONFIG_RAID6_PQ) += raid6/ -+obj-$(CONFIG_LZMA_COMPRESS) += lzma/ -+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ - - lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o - lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o ---- /dev/null -+++ b/lib/lzma/LzFind.c -@@ -0,0 +1,761 @@ -+/* LzFind.c -- Match finder for LZ algorithms -+2009-04-22 : Igor Pavlov : Public domain */ -+ -+#include -+ -+#include "LzFind.h" -+#include "LzHash.h" -+ -+#define kEmptyHashValue 0 -+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) -+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ -+#define kNormalizeMask (~(kNormalizeStepMin - 1)) -+#define kMaxHistorySize ((UInt32)3 << 30) -+ -+#define kStartMaxLen 3 -+ -+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ if (!p->directInput) -+ { -+ alloc->Free(alloc, p->bufferBase); -+ p->bufferBase = 0; -+ } -+} -+ -+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ -+ -+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) -+{ -+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; -+ if (p->directInput) -+ { -+ p->blockSize = blockSize; -+ return 1; -+ } -+ if (p->bufferBase == 0 || p->blockSize != blockSize) -+ { -+ LzInWindow_Free(p, alloc); -+ p->blockSize = blockSize; -+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); -+ } -+ return (p->bufferBase != 0); -+} -+ -+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } -+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } -+ -+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } -+ -+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) -+{ -+ p->posLimit -= subValue; -+ p->pos -= subValue; -+ p->streamPos -= subValue; -+} -+ -+static void MatchFinder_ReadBlock(CMatchFinder *p) -+{ -+ if (p->streamEndWasReached || p->result != SZ_OK) -+ return; -+ if (p->directInput) -+ { -+ UInt32 curSize = 0xFFFFFFFF - p->streamPos; -+ if (curSize > p->directInputRem) -+ curSize = (UInt32)p->directInputRem; -+ p->directInputRem -= curSize; -+ p->streamPos += curSize; -+ if (p->directInputRem == 0) -+ p->streamEndWasReached = 1; -+ return; -+ } -+ for (;;) -+ { -+ Byte *dest = p->buffer + (p->streamPos - p->pos); -+ size_t size = (p->bufferBase + p->blockSize - dest); -+ if (size == 0) -+ return; -+ p->result = p->stream->Read(p->stream, dest, &size); -+ if (p->result != SZ_OK) -+ return; -+ if (size == 0) -+ { -+ p->streamEndWasReached = 1; -+ return; -+ } -+ p->streamPos += (UInt32)size; -+ if (p->streamPos - p->pos > p->keepSizeAfter) -+ return; -+ } -+} -+ -+void MatchFinder_MoveBlock(CMatchFinder *p) -+{ -+ memmove(p->bufferBase, -+ p->buffer - p->keepSizeBefore, -+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); -+ p->buffer = p->bufferBase + p->keepSizeBefore; -+} -+ -+int MatchFinder_NeedMove(CMatchFinder *p) -+{ -+ if (p->directInput) -+ return 0; -+ /* if (p->streamEndWasReached) return 0; */ -+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); -+} -+ -+void MatchFinder_ReadIfRequired(CMatchFinder *p) -+{ -+ if (p->streamEndWasReached) -+ return; -+ if (p->keepSizeAfter >= p->streamPos - p->pos) -+ MatchFinder_ReadBlock(p); -+} -+ -+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) -+{ -+ if (MatchFinder_NeedMove(p)) -+ MatchFinder_MoveBlock(p); -+ MatchFinder_ReadBlock(p); -+} -+ -+static void MatchFinder_SetDefaultSettings(CMatchFinder *p) -+{ -+ p->cutValue = 32; -+ p->btMode = 1; -+ p->numHashBytes = 4; -+ p->bigHash = 0; -+} -+ -+#define kCrcPoly 0xEDB88320 -+ -+void MatchFinder_Construct(CMatchFinder *p) -+{ -+ UInt32 i; -+ p->bufferBase = 0; -+ p->directInput = 0; -+ p->hash = 0; -+ MatchFinder_SetDefaultSettings(p); -+ -+ for (i = 0; i < 256; i++) -+ { -+ UInt32 r = i; -+ int j; -+ for (j = 0; j < 8; j++) -+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); -+ p->crc[i] = r; -+ } -+} -+ -+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->hash); -+ p->hash = 0; -+} -+ -+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) -+{ -+ MatchFinder_FreeThisClassMemory(p, alloc); -+ LzInWindow_Free(p, alloc); -+} -+ -+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) -+{ -+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef); -+ if (sizeInBytes / sizeof(CLzRef) != num) -+ return 0; -+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); -+} -+ -+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, -+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, -+ ISzAlloc *alloc) -+{ -+ UInt32 sizeReserv; -+ if (historySize > kMaxHistorySize) -+ { -+ MatchFinder_Free(p, alloc); -+ return 0; -+ } -+ sizeReserv = historySize >> 1; -+ if (historySize > ((UInt32)2 << 30)) -+ sizeReserv = historySize >> 2; -+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); -+ -+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1; -+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; -+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ -+ if (LzInWindow_Create(p, sizeReserv, alloc)) -+ { -+ UInt32 newCyclicBufferSize = historySize + 1; -+ UInt32 hs; -+ p->matchMaxLen = matchMaxLen; -+ { -+ p->fixedHashSize = 0; -+ if (p->numHashBytes == 2) -+ hs = (1 << 16) - 1; -+ else -+ { -+ hs = historySize - 1; -+ hs |= (hs >> 1); -+ hs |= (hs >> 2); -+ hs |= (hs >> 4); -+ hs |= (hs >> 8); -+ hs >>= 1; -+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */ -+ if (hs > (1 << 24)) -+ { -+ if (p->numHashBytes == 3) -+ hs = (1 << 24) - 1; -+ else -+ hs >>= 1; -+ } -+ } -+ p->hashMask = hs; -+ hs++; -+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; -+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; -+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; -+ hs += p->fixedHashSize; -+ } -+ -+ { -+ UInt32 prevSize = p->hashSizeSum + p->numSons; -+ UInt32 newSize; -+ p->historySize = historySize; -+ p->hashSizeSum = hs; -+ p->cyclicBufferSize = newCyclicBufferSize; -+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); -+ newSize = p->hashSizeSum + p->numSons; -+ if (p->hash != 0 && prevSize == newSize) -+ return 1; -+ MatchFinder_FreeThisClassMemory(p, alloc); -+ p->hash = AllocRefs(newSize, alloc); -+ if (p->hash != 0) -+ { -+ p->son = p->hash + p->hashSizeSum; -+ return 1; -+ } -+ } -+ } -+ MatchFinder_Free(p, alloc); -+ return 0; -+} -+ -+static void MatchFinder_SetLimits(CMatchFinder *p) -+{ -+ UInt32 limit = kMaxValForNormalize - p->pos; -+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; -+ if (limit2 < limit) -+ limit = limit2; -+ limit2 = p->streamPos - p->pos; -+ if (limit2 <= p->keepSizeAfter) -+ { -+ if (limit2 > 0) -+ limit2 = 1; -+ } -+ else -+ limit2 -= p->keepSizeAfter; -+ if (limit2 < limit) -+ limit = limit2; -+ { -+ UInt32 lenLimit = p->streamPos - p->pos; -+ if (lenLimit > p->matchMaxLen) -+ lenLimit = p->matchMaxLen; -+ p->lenLimit = lenLimit; -+ } -+ p->posLimit = p->pos + limit; -+} -+ -+void MatchFinder_Init(CMatchFinder *p) -+{ -+ UInt32 i; -+ for (i = 0; i < p->hashSizeSum; i++) -+ p->hash[i] = kEmptyHashValue; -+ p->cyclicBufferPos = 0; -+ p->buffer = p->bufferBase; -+ p->pos = p->streamPos = p->cyclicBufferSize; -+ p->result = SZ_OK; -+ p->streamEndWasReached = 0; -+ MatchFinder_ReadBlock(p); -+ MatchFinder_SetLimits(p); -+} -+ -+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) -+{ -+ return (p->pos - p->historySize - 1) & kNormalizeMask; -+} -+ -+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) -+{ -+ UInt32 i; -+ for (i = 0; i < numItems; i++) -+ { -+ UInt32 value = items[i]; -+ if (value <= subValue) -+ value = kEmptyHashValue; -+ else -+ value -= subValue; -+ items[i] = value; -+ } -+} -+ -+static void MatchFinder_Normalize(CMatchFinder *p) -+{ -+ UInt32 subValue = MatchFinder_GetSubValue(p); -+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); -+ MatchFinder_ReduceOffsets(p, subValue); -+} -+ -+static void MatchFinder_CheckLimits(CMatchFinder *p) -+{ -+ if (p->pos == kMaxValForNormalize) -+ MatchFinder_Normalize(p); -+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) -+ MatchFinder_CheckAndMoveAndRead(p); -+ if (p->cyclicBufferPos == p->cyclicBufferSize) -+ p->cyclicBufferPos = 0; -+ MatchFinder_SetLimits(p); -+} -+ -+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+ UInt32 *distances, UInt32 maxLen) -+{ -+ son[_cyclicBufferPos] = curMatch; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ return distances; -+ { -+ const Byte *pb = cur - delta; -+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; -+ if (pb[maxLen] == cur[maxLen] && *pb == *cur) -+ { -+ UInt32 len = 0; -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ if (maxLen < len) -+ { -+ *distances++ = maxLen = len; -+ *distances++ = delta - 1; -+ if (len == lenLimit) -+ return distances; -+ } -+ } -+ } -+ } -+} -+ -+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, -+ UInt32 *distances, UInt32 maxLen) -+{ -+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -+ UInt32 len0 = 0, len1 = 0; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ { -+ *ptr0 = *ptr1 = kEmptyHashValue; -+ return distances; -+ } -+ { -+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -+ const Byte *pb = cur - delta; -+ UInt32 len = (len0 < len1 ? len0 : len1); -+ if (pb[len] == cur[len]) -+ { -+ if (++len != lenLimit && pb[len] == cur[len]) -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ if (maxLen < len) -+ { -+ *distances++ = maxLen = len; -+ *distances++ = delta - 1; -+ if (len == lenLimit) -+ { -+ *ptr1 = pair[0]; -+ *ptr0 = pair[1]; -+ return distances; -+ } -+ } -+ } -+ if (pb[len] < cur[len]) -+ { -+ *ptr1 = curMatch; -+ ptr1 = pair + 1; -+ curMatch = *ptr1; -+ len1 = len; -+ } -+ else -+ { -+ *ptr0 = curMatch; -+ ptr0 = pair; -+ curMatch = *ptr0; -+ len0 = len; -+ } -+ } -+ } -+} -+ -+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, -+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) -+{ -+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; -+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); -+ UInt32 len0 = 0, len1 = 0; -+ for (;;) -+ { -+ UInt32 delta = pos - curMatch; -+ if (cutValue-- == 0 || delta >= _cyclicBufferSize) -+ { -+ *ptr0 = *ptr1 = kEmptyHashValue; -+ return; -+ } -+ { -+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); -+ const Byte *pb = cur - delta; -+ UInt32 len = (len0 < len1 ? len0 : len1); -+ if (pb[len] == cur[len]) -+ { -+ while (++len != lenLimit) -+ if (pb[len] != cur[len]) -+ break; -+ { -+ if (len == lenLimit) -+ { -+ *ptr1 = pair[0]; -+ *ptr0 = pair[1]; -+ return; -+ } -+ } -+ } -+ if (pb[len] < cur[len]) -+ { -+ *ptr1 = curMatch; -+ ptr1 = pair + 1; -+ curMatch = *ptr1; -+ len1 = len; -+ } -+ else -+ { -+ *ptr0 = curMatch; -+ ptr0 = pair; -+ curMatch = *ptr0; -+ len0 = len; -+ } -+ } -+ } -+} -+ -+#define MOVE_POS \ -+ ++p->cyclicBufferPos; \ -+ p->buffer++; \ -+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); -+ -+#define MOVE_POS_RET MOVE_POS return offset; -+ -+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } -+ -+#define GET_MATCHES_HEADER2(minLen, ret_op) \ -+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ -+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ -+ cur = p->buffer; -+ -+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) -+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) -+ -+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue -+ -+#define GET_MATCHES_FOOTER(offset, maxLen) \ -+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ -+ distances + offset, maxLen) - distances); MOVE_POS_RET; -+ -+#define SKIP_FOOTER \ -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; -+ -+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(2) -+ HASH2_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = 0; -+ GET_MATCHES_FOOTER(offset, 1) -+} -+ -+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = 0; -+ GET_MATCHES_FOOTER(offset, 2) -+} -+ -+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value, delta2, maxLen, offset; -+ GET_MATCHES_HEADER(3) -+ -+ HASH3_CALC; -+ -+ delta2 = p->pos - p->hash[hash2Value]; -+ curMatch = p->hash[kFix3HashSize + hashValue]; -+ -+ p->hash[hash2Value] = -+ p->hash[kFix3HashSize + hashValue] = p->pos; -+ -+ -+ maxLen = 2; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+ { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[0] = maxLen; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ if (maxLen == lenLimit) -+ { -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -+ MOVE_POS_RET; -+ } -+ } -+ GET_MATCHES_FOOTER(offset, maxLen) -+} -+ -+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -+ GET_MATCHES_HEADER(4) -+ -+ HASH4_CALC; -+ -+ delta2 = p->pos - p->hash[ hash2Value]; -+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ -+ maxLen = 1; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+ { -+ distances[0] = maxLen = 2; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ } -+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -+ { -+ maxLen = 3; -+ distances[offset + 1] = delta3 - 1; -+ offset += 2; -+ delta2 = delta3; -+ } -+ if (offset != 0) -+ { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[offset - 2] = maxLen; -+ if (maxLen == lenLimit) -+ { -+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); -+ MOVE_POS_RET; -+ } -+ } -+ if (maxLen < 3) -+ maxLen = 3; -+ GET_MATCHES_FOOTER(offset, maxLen) -+} -+ -+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; -+ GET_MATCHES_HEADER(4) -+ -+ HASH4_CALC; -+ -+ delta2 = p->pos - p->hash[ hash2Value]; -+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ -+ maxLen = 1; -+ offset = 0; -+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) -+ { -+ distances[0] = maxLen = 2; -+ distances[1] = delta2 - 1; -+ offset = 2; -+ } -+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) -+ { -+ maxLen = 3; -+ distances[offset + 1] = delta3 - 1; -+ offset += 2; -+ delta2 = delta3; -+ } -+ if (offset != 0) -+ { -+ for (; maxLen != lenLimit; maxLen++) -+ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) -+ break; -+ distances[offset - 2] = maxLen; -+ if (maxLen == lenLimit) -+ { -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS_RET; -+ } -+ } -+ if (maxLen < 3) -+ maxLen = 3; -+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -+ distances + offset, maxLen) - (distances)); -+ MOVE_POS_RET -+} -+ -+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) -+{ -+ UInt32 offset; -+ GET_MATCHES_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), -+ distances, 2) - (distances)); -+ MOVE_POS_RET -+} -+ -+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ SKIP_HEADER(2) -+ HASH2_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ SKIP_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ UInt32 hash2Value; -+ SKIP_HEADER(3) -+ HASH3_CALC; -+ curMatch = p->hash[kFix3HashSize + hashValue]; -+ p->hash[hash2Value] = -+ p->hash[kFix3HashSize + hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ UInt32 hash2Value, hash3Value; -+ SKIP_HEADER(4) -+ HASH4_CALC; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = p->pos; -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ SKIP_FOOTER -+ } -+ while (--num != 0); -+} -+ -+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ UInt32 hash2Value, hash3Value; -+ SKIP_HEADER(4) -+ HASH4_CALC; -+ curMatch = p->hash[kFix4HashSize + hashValue]; -+ p->hash[ hash2Value] = -+ p->hash[kFix3HashSize + hash3Value] = -+ p->hash[kFix4HashSize + hashValue] = p->pos; -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS -+ } -+ while (--num != 0); -+} -+ -+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) -+{ -+ do -+ { -+ SKIP_HEADER(3) -+ HASH_ZIP_CALC; -+ curMatch = p->hash[hashValue]; -+ p->hash[hashValue] = p->pos; -+ p->son[p->cyclicBufferPos] = curMatch; -+ MOVE_POS -+ } -+ while (--num != 0); -+} -+ -+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) -+{ -+ vTable->Init = (Mf_Init_Func)MatchFinder_Init; -+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; -+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; -+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; -+ if (!p->btMode) -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; -+ } -+ else if (p->numHashBytes == 2) -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; -+ } -+ else if (p->numHashBytes == 3) -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; -+ } -+ else -+ { -+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; -+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; -+ } -+} ---- /dev/null -+++ b/lib/lzma/LzmaDec.c -@@ -0,0 +1,999 @@ -+/* LzmaDec.c -- LZMA Decoder -+2009-09-20 : Igor Pavlov : Public domain */ -+ -+#include "LzmaDec.h" -+ -+#include -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+ -+#define RC_INIT_SIZE 5 -+ -+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } -+ -+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); -+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ -+ { UPDATE_0(p); i = (i + i); A0; } else \ -+ { UPDATE_1(p); i = (i + i) + 1; A1; } -+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) -+ -+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } -+#define TREE_DECODE(probs, limit, i) \ -+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } -+ -+/* #define _LZMA_SIZE_OPT */ -+ -+#ifdef _LZMA_SIZE_OPT -+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) -+#else -+#define TREE_6_DECODE(probs, i) \ -+ { i = 1; \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ TREE_GET_BIT(probs, i); \ -+ i -= 0x40; } -+#endif -+ -+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } -+ -+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) -+#define UPDATE_0_CHECK range = bound; -+#define UPDATE_1_CHECK range -= bound; code -= bound; -+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ -+ { UPDATE_0_CHECK; i = (i + i); A0; } else \ -+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } -+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) -+#define TREE_DECODE_CHECK(probs, limit, i) \ -+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } -+ -+ -+#define kNumPosBitsMax 4 -+#define kNumPosStatesMax (1 << kNumPosBitsMax) -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define LenChoice 0 -+#define LenChoice2 (LenChoice + 1) -+#define LenLow (LenChoice2 + 1) -+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) -+ -+ -+#define kNumStates 12 -+#define kNumLitStates 7 -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#define kNumPosSlotBits 6 -+#define kNumLenToPosStates 4 -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+ -+#define kMatchMinLen 2 -+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -+ -+#define IsMatch 0 -+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -+#define IsRepG0 (IsRep + kNumStates) -+#define IsRepG1 (IsRepG0 + kNumStates) -+#define IsRepG2 (IsRepG1 + kNumStates) -+#define IsRep0Long (IsRepG2 + kNumStates) -+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -+#define LenCoder (Align + kAlignTableSize) -+#define RepLenCoder (LenCoder + kNumLenProbs) -+#define Literal (RepLenCoder + kNumLenProbs) -+ -+#define LZMA_BASE_SIZE 1846 -+#define LZMA_LIT_SIZE 768 -+ -+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) -+ -+#if Literal != LZMA_BASE_SIZE -+StopCompilingDueBUG -+#endif -+ -+#define LZMA_DIC_MIN (1 << 12) -+ -+/* First LZMA-symbol is always decoded. -+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization -+Out: -+ Result: -+ SZ_OK - OK -+ SZ_ERROR_DATA - Error -+ p->remainLen: -+ < kMatchSpecLenStart : normal remain -+ = kMatchSpecLenStart : finished -+ = kMatchSpecLenStart + 1 : Flush marker -+ = kMatchSpecLenStart + 2 : State Init Marker -+*/ -+ -+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -+{ -+ CLzmaProb *probs = p->probs; -+ -+ unsigned state = p->state; -+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; -+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; -+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; -+ unsigned lc = p->prop.lc; -+ -+ Byte *dic = p->dic; -+ SizeT dicBufSize = p->dicBufSize; -+ SizeT dicPos = p->dicPos; -+ -+ UInt32 processedPos = p->processedPos; -+ UInt32 checkDicSize = p->checkDicSize; -+ unsigned len = 0; -+ -+ const Byte *buf = p->buf; -+ UInt32 range = p->range; -+ UInt32 code = p->code; -+ -+ do -+ { -+ CLzmaProb *prob; -+ UInt32 bound; -+ unsigned ttt; -+ unsigned posState = processedPos & pbMask; -+ -+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0(prob) -+ { -+ unsigned symbol; -+ UPDATE_0(prob); -+ prob = probs + Literal; -+ if (checkDicSize != 0 || processedPos != 0) -+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + -+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); -+ -+ if (state < kNumLitStates) -+ { -+ state -= (state < 4) ? state : 3; -+ symbol = 1; -+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); -+ } -+ else -+ { -+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ unsigned offs = 0x100; -+ state -= (state < 10) ? 3 : 6; -+ symbol = 1; -+ do -+ { -+ unsigned bit; -+ CLzmaProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & offs); -+ probLit = prob + offs + bit + symbol; -+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) -+ } -+ while (symbol < 0x100); -+ } -+ dic[dicPos++] = (Byte)symbol; -+ processedPos++; -+ continue; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ prob = probs + IsRep + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ state += kNumStates; -+ prob = probs + LenCoder; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ if (checkDicSize == 0 && processedPos == 0) -+ return SZ_ERROR_DATA; -+ prob = probs + IsRepG0 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ dicPos++; -+ processedPos++; -+ state = state < kNumLitStates ? 9 : 11; -+ continue; -+ } -+ UPDATE_1(prob); -+ } -+ else -+ { -+ UInt32 distance; -+ UPDATE_1(prob); -+ prob = probs + IsRepG1 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ distance = rep1; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ prob = probs + IsRepG2 + state; -+ IF_BIT_0(prob) -+ { -+ UPDATE_0(prob); -+ distance = rep2; -+ } -+ else -+ { -+ UPDATE_1(prob); -+ distance = rep3; -+ rep3 = rep2; -+ } -+ rep2 = rep1; -+ } -+ rep1 = rep0; -+ rep0 = distance; -+ } -+ state = state < kNumLitStates ? 8 : 11; -+ prob = probs + RepLenCoder; -+ } -+ { -+ unsigned limit, offset; -+ CLzmaProb *probLen = prob + LenChoice; -+ IF_BIT_0(probLen) -+ { -+ UPDATE_0(probLen); -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ limit = (1 << kLenNumLowBits); -+ } -+ else -+ { -+ UPDATE_1(probLen); -+ probLen = prob + LenChoice2; -+ IF_BIT_0(probLen) -+ { -+ UPDATE_0(probLen); -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ limit = (1 << kLenNumMidBits); -+ } -+ else -+ { -+ UPDATE_1(probLen); -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ limit = (1 << kLenNumHighBits); -+ } -+ } -+ TREE_DECODE(probLen, limit, len); -+ len += offset; -+ } -+ -+ if (state >= kNumStates) -+ { -+ UInt32 distance; -+ prob = probs + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); -+ TREE_6_DECODE(prob, distance); -+ if (distance >= kStartPosModelIndex) -+ { -+ unsigned posSlot = (unsigned)distance; -+ int numDirectBits = (int)(((distance >> 1) - 1)); -+ distance = (2 | (distance & 1)); -+ if (posSlot < kEndPosModelIndex) -+ { -+ distance <<= numDirectBits; -+ prob = probs + SpecPos + distance - posSlot - 1; -+ { -+ UInt32 mask = 1; -+ unsigned i = 1; -+ do -+ { -+ GET_BIT2(prob + i, i, ; , distance |= mask); -+ mask <<= 1; -+ } -+ while (--numDirectBits != 0); -+ } -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ NORMALIZE -+ range >>= 1; -+ -+ { -+ UInt32 t; -+ code -= range; -+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ -+ distance = (distance << 1) + (t + 1); -+ code += range & t; -+ } -+ /* -+ distance <<= 1; -+ if (code >= range) -+ { -+ code -= range; -+ distance |= 1; -+ } -+ */ -+ } -+ while (--numDirectBits != 0); -+ prob = probs + Align; -+ distance <<= kNumAlignBits; -+ { -+ unsigned i = 1; -+ GET_BIT2(prob + i, i, ; , distance |= 1); -+ GET_BIT2(prob + i, i, ; , distance |= 2); -+ GET_BIT2(prob + i, i, ; , distance |= 4); -+ GET_BIT2(prob + i, i, ; , distance |= 8); -+ } -+ if (distance == (UInt32)0xFFFFFFFF) -+ { -+ len += kMatchSpecLenStart; -+ state -= kNumStates; -+ break; -+ } -+ } -+ } -+ rep3 = rep2; -+ rep2 = rep1; -+ rep1 = rep0; -+ rep0 = distance + 1; -+ if (checkDicSize == 0) -+ { -+ if (distance >= processedPos) -+ return SZ_ERROR_DATA; -+ } -+ else if (distance >= checkDicSize) -+ return SZ_ERROR_DATA; -+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; -+ } -+ -+ len += kMatchMinLen; -+ -+ if (limit == dicPos) -+ return SZ_ERROR_DATA; -+ { -+ SizeT rem = limit - dicPos; -+ unsigned curLen = ((rem < len) ? (unsigned)rem : len); -+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); -+ -+ processedPos += curLen; -+ -+ len -= curLen; -+ if (pos + curLen <= dicBufSize) -+ { -+ Byte *dest = dic + dicPos; -+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; -+ const Byte *lim = dest + curLen; -+ dicPos += curLen; -+ do -+ *(dest) = (Byte)*(dest + src); -+ while (++dest != lim); -+ } -+ else -+ { -+ do -+ { -+ dic[dicPos++] = dic[pos]; -+ if (++pos == dicBufSize) -+ pos = 0; -+ } -+ while (--curLen != 0); -+ } -+ } -+ } -+ } -+ while (dicPos < limit && buf < bufLimit); -+ NORMALIZE; -+ p->buf = buf; -+ p->range = range; -+ p->code = code; -+ p->remainLen = len; -+ p->dicPos = dicPos; -+ p->processedPos = processedPos; -+ p->reps[0] = rep0; -+ p->reps[1] = rep1; -+ p->reps[2] = rep2; -+ p->reps[3] = rep3; -+ p->state = state; -+ -+ return SZ_OK; -+} -+ -+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) -+{ -+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) -+ { -+ Byte *dic = p->dic; -+ SizeT dicPos = p->dicPos; -+ SizeT dicBufSize = p->dicBufSize; -+ unsigned len = p->remainLen; -+ UInt32 rep0 = p->reps[0]; -+ if (limit - dicPos < len) -+ len = (unsigned)(limit - dicPos); -+ -+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) -+ p->checkDicSize = p->prop.dicSize; -+ -+ p->processedPos += len; -+ p->remainLen -= len; -+ while (len-- != 0) -+ { -+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; -+ dicPos++; -+ } -+ p->dicPos = dicPos; -+ } -+} -+ -+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) -+{ -+ do -+ { -+ SizeT limit2 = limit; -+ if (p->checkDicSize == 0) -+ { -+ UInt32 rem = p->prop.dicSize - p->processedPos; -+ if (limit - p->dicPos > rem) -+ limit2 = p->dicPos + rem; -+ } -+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); -+ if (p->processedPos >= p->prop.dicSize) -+ p->checkDicSize = p->prop.dicSize; -+ LzmaDec_WriteRem(p, limit); -+ } -+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); -+ -+ if (p->remainLen > kMatchSpecLenStart) -+ { -+ p->remainLen = kMatchSpecLenStart; -+ } -+ return 0; -+} -+ -+typedef enum -+{ -+ DUMMY_ERROR, /* unexpected end of input stream */ -+ DUMMY_LIT, -+ DUMMY_MATCH, -+ DUMMY_REP -+} ELzmaDummy; -+ -+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) -+{ -+ UInt32 range = p->range; -+ UInt32 code = p->code; -+ const Byte *bufLimit = buf + inSize; -+ CLzmaProb *probs = p->probs; -+ unsigned state = p->state; -+ ELzmaDummy res; -+ -+ { -+ CLzmaProb *prob; -+ UInt32 bound; -+ unsigned ttt; -+ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); -+ -+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK -+ -+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ -+ -+ prob = probs + Literal; -+ if (p->checkDicSize != 0 || p->processedPos != 0) -+ prob += (LZMA_LIT_SIZE * -+ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + -+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); -+ -+ if (state < kNumLitStates) -+ { -+ unsigned symbol = 1; -+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); -+ } -+ else -+ { -+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + -+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; -+ unsigned offs = 0x100; -+ unsigned symbol = 1; -+ do -+ { -+ unsigned bit; -+ CLzmaProb *probLit; -+ matchByte <<= 1; -+ bit = (matchByte & offs); -+ probLit = prob + offs + bit + symbol; -+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) -+ } -+ while (symbol < 0x100); -+ } -+ res = DUMMY_LIT; -+ } -+ else -+ { -+ unsigned len; -+ UPDATE_1_CHECK; -+ -+ prob = probs + IsRep + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ state = 0; -+ prob = probs + LenCoder; -+ res = DUMMY_MATCH; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ res = DUMMY_REP; -+ prob = probs + IsRepG0 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ NORMALIZE_CHECK; -+ return DUMMY_REP; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ } -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ prob = probs + IsRepG1 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ prob = probs + IsRepG2 + state; -+ IF_BIT_0_CHECK(prob) -+ { -+ UPDATE_0_CHECK; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ } -+ } -+ } -+ state = kNumStates; -+ prob = probs + RepLenCoder; -+ } -+ { -+ unsigned limit, offset; -+ CLzmaProb *probLen = prob + LenChoice; -+ IF_BIT_0_CHECK(probLen) -+ { -+ UPDATE_0_CHECK; -+ probLen = prob + LenLow + (posState << kLenNumLowBits); -+ offset = 0; -+ limit = 1 << kLenNumLowBits; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ probLen = prob + LenChoice2; -+ IF_BIT_0_CHECK(probLen) -+ { -+ UPDATE_0_CHECK; -+ probLen = prob + LenMid + (posState << kLenNumMidBits); -+ offset = kLenNumLowSymbols; -+ limit = 1 << kLenNumMidBits; -+ } -+ else -+ { -+ UPDATE_1_CHECK; -+ probLen = prob + LenHigh; -+ offset = kLenNumLowSymbols + kLenNumMidSymbols; -+ limit = 1 << kLenNumHighBits; -+ } -+ } -+ TREE_DECODE_CHECK(probLen, limit, len); -+ len += offset; -+ } -+ -+ if (state < 4) -+ { -+ unsigned posSlot; -+ prob = probs + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << -+ kNumPosSlotBits); -+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); -+ if (posSlot >= kStartPosModelIndex) -+ { -+ int numDirectBits = ((posSlot >> 1) - 1); -+ -+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ -+ -+ if (posSlot < kEndPosModelIndex) -+ { -+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; -+ } -+ else -+ { -+ numDirectBits -= kNumAlignBits; -+ do -+ { -+ NORMALIZE_CHECK -+ range >>= 1; -+ code -= range & (((code - range) >> 31) - 1); -+ /* if (code >= range) code -= range; */ -+ } -+ while (--numDirectBits != 0); -+ prob = probs + Align; -+ numDirectBits = kNumAlignBits; -+ } -+ { -+ unsigned i = 1; -+ do -+ { -+ GET_BIT_CHECK(prob + i, i); -+ } -+ while (--numDirectBits != 0); -+ } -+ } -+ } -+ } -+ } -+ NORMALIZE_CHECK; -+ return res; -+} -+ -+ -+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) -+{ -+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); -+ p->range = 0xFFFFFFFF; -+ p->needFlush = 0; -+} -+ -+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) -+{ -+ p->needFlush = 1; -+ p->remainLen = 0; -+ p->tempBufSize = 0; -+ -+ if (initDic) -+ { -+ p->processedPos = 0; -+ p->checkDicSize = 0; -+ p->needInitState = 1; -+ } -+ if (initState) -+ p->needInitState = 1; -+} -+ -+void LzmaDec_Init(CLzmaDec *p) -+{ -+ p->dicPos = 0; -+ LzmaDec_InitDicAndState(p, True, True); -+} -+ -+static void LzmaDec_InitStateReal(CLzmaDec *p) -+{ -+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); -+ UInt32 i; -+ CLzmaProb *probs = p->probs; -+ for (i = 0; i < numProbs; i++) -+ probs[i] = kBitModelTotal >> 1; -+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; -+ p->state = 0; -+ p->needInitState = 0; -+} -+ -+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, -+ ELzmaFinishMode finishMode, ELzmaStatus *status) -+{ -+ SizeT inSize = *srcLen; -+ (*srcLen) = 0; -+ LzmaDec_WriteRem(p, dicLimit); -+ -+ *status = LZMA_STATUS_NOT_SPECIFIED; -+ -+ while (p->remainLen != kMatchSpecLenStart) -+ { -+ int checkEndMarkNow; -+ -+ if (p->needFlush != 0) -+ { -+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) -+ p->tempBuf[p->tempBufSize++] = *src++; -+ if (p->tempBufSize < RC_INIT_SIZE) -+ { -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (p->tempBuf[0] != 0) -+ return SZ_ERROR_DATA; -+ -+ LzmaDec_InitRc(p, p->tempBuf); -+ p->tempBufSize = 0; -+ } -+ -+ checkEndMarkNow = 0; -+ if (p->dicPos >= dicLimit) -+ { -+ if (p->remainLen == 0 && p->code == 0) -+ { -+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; -+ return SZ_OK; -+ } -+ if (finishMode == LZMA_FINISH_ANY) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_OK; -+ } -+ if (p->remainLen != 0) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ checkEndMarkNow = 1; -+ } -+ -+ if (p->needInitState) -+ LzmaDec_InitStateReal(p); -+ -+ if (p->tempBufSize == 0) -+ { -+ SizeT processed; -+ const Byte *bufLimit; -+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -+ { -+ int dummyRes = LzmaDec_TryDummy(p, src, inSize); -+ if (dummyRes == DUMMY_ERROR) -+ { -+ memcpy(p->tempBuf, src, inSize); -+ p->tempBufSize = (unsigned)inSize; -+ (*srcLen) += inSize; -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ bufLimit = src; -+ } -+ else -+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; -+ p->buf = src; -+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) -+ return SZ_ERROR_DATA; -+ processed = (SizeT)(p->buf - src); -+ (*srcLen) += processed; -+ src += processed; -+ inSize -= processed; -+ } -+ else -+ { -+ unsigned rem = p->tempBufSize, lookAhead = 0; -+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) -+ p->tempBuf[rem++] = src[lookAhead++]; -+ p->tempBufSize = rem; -+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) -+ { -+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); -+ if (dummyRes == DUMMY_ERROR) -+ { -+ (*srcLen) += lookAhead; -+ *status = LZMA_STATUS_NEEDS_MORE_INPUT; -+ return SZ_OK; -+ } -+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) -+ { -+ *status = LZMA_STATUS_NOT_FINISHED; -+ return SZ_ERROR_DATA; -+ } -+ } -+ p->buf = p->tempBuf; -+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) -+ return SZ_ERROR_DATA; -+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); -+ (*srcLen) += lookAhead; -+ src += lookAhead; -+ inSize -= lookAhead; -+ p->tempBufSize = 0; -+ } -+ } -+ if (p->code == 0) -+ *status = LZMA_STATUS_FINISHED_WITH_MARK; -+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -+} -+ -+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -+{ -+ SizeT outSize = *destLen; -+ SizeT inSize = *srcLen; -+ *srcLen = *destLen = 0; -+ for (;;) -+ { -+ SizeT inSizeCur = inSize, outSizeCur, dicPos; -+ ELzmaFinishMode curFinishMode; -+ SRes res; -+ if (p->dicPos == p->dicBufSize) -+ p->dicPos = 0; -+ dicPos = p->dicPos; -+ if (outSize > p->dicBufSize - dicPos) -+ { -+ outSizeCur = p->dicBufSize; -+ curFinishMode = LZMA_FINISH_ANY; -+ } -+ else -+ { -+ outSizeCur = dicPos + outSize; -+ curFinishMode = finishMode; -+ } -+ -+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); -+ src += inSizeCur; -+ inSize -= inSizeCur; -+ *srcLen += inSizeCur; -+ outSizeCur = p->dicPos - dicPos; -+ memcpy(dest, p->dic + dicPos, outSizeCur); -+ dest += outSizeCur; -+ outSize -= outSizeCur; -+ *destLen += outSizeCur; -+ if (res != 0) -+ return res; -+ if (outSizeCur == 0 || outSize == 0) -+ return SZ_OK; -+ } -+} -+ -+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->probs); -+ p->probs = 0; -+} -+ -+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->dic); -+ p->dic = 0; -+} -+ -+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) -+{ -+ LzmaDec_FreeProbs(p, alloc); -+ LzmaDec_FreeDict(p, alloc); -+} -+ -+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) -+{ -+ UInt32 dicSize; -+ Byte d; -+ -+ if (size < LZMA_PROPS_SIZE) -+ return SZ_ERROR_UNSUPPORTED; -+ else -+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); -+ -+ if (dicSize < LZMA_DIC_MIN) -+ dicSize = LZMA_DIC_MIN; -+ p->dicSize = dicSize; -+ -+ d = data[0]; -+ if (d >= (9 * 5 * 5)) -+ return SZ_ERROR_UNSUPPORTED; -+ -+ p->lc = d % 9; -+ d /= 9; -+ p->pb = d / 5; -+ p->lp = d % 5; -+ -+ return SZ_OK; -+} -+ -+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) -+{ -+ UInt32 numProbs = LzmaProps_GetNumProbs(propNew); -+ if (p->probs == 0 || numProbs != p->numProbs) -+ { -+ LzmaDec_FreeProbs(p, alloc); -+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); -+ p->numProbs = numProbs; -+ if (p->probs == 0) -+ return SZ_ERROR_MEM; -+ } -+ return SZ_OK; -+} -+ -+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+{ -+ CLzmaProps propNew; -+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -+ p->prop = propNew; -+ return SZ_OK; -+} -+ -+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) -+{ -+ CLzmaProps propNew; -+ SizeT dicBufSize; -+ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); -+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); -+ dicBufSize = propNew.dicSize; -+ if (p->dic == 0 || dicBufSize != p->dicBufSize) -+ { -+ LzmaDec_FreeDict(p, alloc); -+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); -+ if (p->dic == 0) -+ { -+ LzmaDec_FreeProbs(p, alloc); -+ return SZ_ERROR_MEM; -+ } -+ } -+ p->dicBufSize = dicBufSize; -+ p->prop = propNew; -+ return SZ_OK; -+} -+ -+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, -+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, -+ ELzmaStatus *status, ISzAlloc *alloc) -+{ -+ CLzmaDec p; -+ SRes res; -+ SizeT inSize = *srcLen; -+ SizeT outSize = *destLen; -+ *srcLen = *destLen = 0; -+ if (inSize < RC_INIT_SIZE) -+ return SZ_ERROR_INPUT_EOF; -+ -+ LzmaDec_Construct(&p); -+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); -+ if (res != 0) -+ return res; -+ p.dic = dest; -+ p.dicBufSize = outSize; -+ -+ LzmaDec_Init(&p); -+ -+ *srcLen = inSize; -+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); -+ -+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) -+ res = SZ_ERROR_INPUT_EOF; -+ -+ (*destLen) = p.dicPos; -+ LzmaDec_FreeProbs(&p, alloc); -+ return res; -+} ---- /dev/null -+++ b/lib/lzma/LzmaEnc.c -@@ -0,0 +1,2271 @@ -+/* LzmaEnc.c -- LZMA Encoder -+2009-11-24 : Igor Pavlov : Public domain */ -+ -+#include -+ -+/* #define SHOW_STAT */ -+/* #define SHOW_STAT2 */ -+ -+#if defined(SHOW_STAT) || defined(SHOW_STAT2) -+#include -+#endif -+ -+#include "LzmaEnc.h" -+ -+/* disable MT */ -+#define _7ZIP_ST -+ -+#include "LzFind.h" -+#ifndef _7ZIP_ST -+#include "LzFindMt.h" -+#endif -+ -+#ifdef SHOW_STAT -+static int ttt = 0; -+#endif -+ -+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) -+ -+#define kBlockSize (9 << 10) -+#define kUnpackBlockSize (1 << 18) -+#define kMatchArraySize (1 << 21) -+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) -+ -+#define kNumMaxDirectBits (31) -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+#define kProbInitValue (kBitModelTotal >> 1) -+ -+#define kNumMoveReducingBits 4 -+#define kNumBitPriceShiftBits 4 -+#define kBitPrice (1 << kNumBitPriceShiftBits) -+ -+void LzmaEncProps_Init(CLzmaEncProps *p) -+{ -+ p->level = 5; -+ p->dictSize = p->mc = 0; -+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; -+ p->writeEndMark = 0; -+} -+ -+void LzmaEncProps_Normalize(CLzmaEncProps *p) -+{ -+ int level = p->level; -+ if (level < 0) level = 5; -+ p->level = level; -+ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); -+ if (p->lc < 0) p->lc = 3; -+ if (p->lp < 0) p->lp = 0; -+ if (p->pb < 0) p->pb = 2; -+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); -+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); -+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); -+ if (p->numHashBytes < 0) p->numHashBytes = 4; -+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); -+ if (p->numThreads < 0) -+ p->numThreads = -+ #ifndef _7ZIP_ST -+ ((p->btMode && p->algo) ? 2 : 1); -+ #else -+ 1; -+ #endif -+} -+ -+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) -+{ -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+ return props.dictSize; -+} -+ -+/* #define LZMA_LOG_BSR */ -+/* Define it for Intel's CPU */ -+ -+ -+#ifdef LZMA_LOG_BSR -+ -+#define kDicLogSizeMaxCompress 30 -+ -+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } -+ -+UInt32 GetPosSlot1(UInt32 pos) -+{ -+ UInt32 res; -+ BSR2_RET(pos, res); -+ return res; -+} -+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } -+ -+#else -+ -+#define kNumLogBits (9 + (int)sizeof(size_t) / 2) -+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) -+ -+void LzmaEnc_FastPosInit(Byte *g_FastPos) -+{ -+ int c = 2, slotFast; -+ g_FastPos[0] = 0; -+ g_FastPos[1] = 1; -+ -+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) -+ { -+ UInt32 k = (1 << ((slotFast >> 1) - 1)); -+ UInt32 j; -+ for (j = 0; j < k; j++, c++) -+ g_FastPos[c] = (Byte)slotFast; -+ } -+} -+ -+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ -+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ -+ res = p->g_FastPos[pos >> i] + (i * 2); } -+/* -+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ -+ p->g_FastPos[pos >> 6] + 12 : \ -+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } -+*/ -+ -+#define GetPosSlot1(pos) p->g_FastPos[pos] -+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } -+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } -+ -+#endif -+ -+ -+#define LZMA_NUM_REPS 4 -+ -+typedef unsigned CState; -+ -+typedef struct -+{ -+ UInt32 price; -+ -+ CState state; -+ int prev1IsChar; -+ int prev2; -+ -+ UInt32 posPrev2; -+ UInt32 backPrev2; -+ -+ UInt32 posPrev; -+ UInt32 backPrev; -+ UInt32 backs[LZMA_NUM_REPS]; -+} COptimal; -+ -+#define kNumOpts (1 << 12) -+ -+#define kNumLenToPosStates 4 -+#define kNumPosSlotBits 6 -+#define kDicLogSizeMin 0 -+#define kDicLogSizeMax 32 -+#define kDistTableSizeMax (kDicLogSizeMax * 2) -+ -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+#define kAlignMask (kAlignTableSize - 1) -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) -+ -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#ifdef _LZMA_PROB32 -+#define CLzmaProb UInt32 -+#else -+#define CLzmaProb UInt16 -+#endif -+ -+#define LZMA_PB_MAX 4 -+#define LZMA_LC_MAX 8 -+#define LZMA_LP_MAX 4 -+ -+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) -+ -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) -+ -+#define LZMA_MATCH_LEN_MIN 2 -+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) -+ -+#define kNumStates 12 -+ -+typedef struct -+{ -+ CLzmaProb choice; -+ CLzmaProb choice2; -+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; -+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; -+ CLzmaProb high[kLenNumHighSymbols]; -+} CLenEnc; -+ -+typedef struct -+{ -+ CLenEnc p; -+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; -+ UInt32 tableSize; -+ UInt32 counters[LZMA_NUM_PB_STATES_MAX]; -+} CLenPriceEnc; -+ -+typedef struct -+{ -+ UInt32 range; -+ Byte cache; -+ UInt64 low; -+ UInt64 cacheSize; -+ Byte *buf; -+ Byte *bufLim; -+ Byte *bufBase; -+ ISeqOutStream *outStream; -+ UInt64 processed; -+ SRes res; -+} CRangeEnc; -+ -+typedef struct -+{ -+ CLzmaProb *litProbs; -+ -+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ CLzmaProb isRep[kNumStates]; -+ CLzmaProb isRepG0[kNumStates]; -+ CLzmaProb isRepG1[kNumStates]; -+ CLzmaProb isRepG2[kNumStates]; -+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ -+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -+ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -+ -+ CLenPriceEnc lenEnc; -+ CLenPriceEnc repLenEnc; -+ -+ UInt32 reps[LZMA_NUM_REPS]; -+ UInt32 state; -+} CSaveState; -+ -+typedef struct -+{ -+ IMatchFinder matchFinder; -+ void *matchFinderObj; -+ -+ #ifndef _7ZIP_ST -+ Bool mtMode; -+ CMatchFinderMt matchFinderMt; -+ #endif -+ -+ CMatchFinder matchFinderBase; -+ -+ #ifndef _7ZIP_ST -+ Byte pad[128]; -+ #endif -+ -+ UInt32 optimumEndIndex; -+ UInt32 optimumCurrentIndex; -+ -+ UInt32 longestMatchLength; -+ UInt32 numPairs; -+ UInt32 numAvail; -+ COptimal opt[kNumOpts]; -+ -+ #ifndef LZMA_LOG_BSR -+ Byte g_FastPos[1 << kNumLogBits]; -+ #endif -+ -+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; -+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; -+ UInt32 numFastBytes; -+ UInt32 additionalOffset; -+ UInt32 reps[LZMA_NUM_REPS]; -+ UInt32 state; -+ -+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; -+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; -+ UInt32 alignPrices[kAlignTableSize]; -+ UInt32 alignPriceCount; -+ -+ UInt32 distTableSize; -+ -+ unsigned lc, lp, pb; -+ unsigned lpMask, pbMask; -+ -+ CLzmaProb *litProbs; -+ -+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ CLzmaProb isRep[kNumStates]; -+ CLzmaProb isRepG0[kNumStates]; -+ CLzmaProb isRepG1[kNumStates]; -+ CLzmaProb isRepG2[kNumStates]; -+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; -+ -+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; -+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; -+ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; -+ -+ CLenPriceEnc lenEnc; -+ CLenPriceEnc repLenEnc; -+ -+ unsigned lclp; -+ -+ Bool fastMode; -+ -+ CRangeEnc rc; -+ -+ Bool writeEndMark; -+ UInt64 nowPos64; -+ UInt32 matchPriceCount; -+ Bool finished; -+ Bool multiThread; -+ -+ SRes result; -+ UInt32 dictSize; -+ UInt32 matchFinderCycles; -+ -+ int needInit; -+ -+ CSaveState saveState; -+} CLzmaEnc; -+ -+void LzmaEnc_SaveState(CLzmaEncHandle pp) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ CSaveState *dest = &p->saveState; -+ int i; -+ dest->lenEnc = p->lenEnc; -+ dest->repLenEnc = p->repLenEnc; -+ dest->state = p->state; -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -+ } -+ for (i = 0; i < kNumLenToPosStates; i++) -+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -+ memcpy(dest->reps, p->reps, sizeof(p->reps)); -+ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); -+} -+ -+void LzmaEnc_RestoreState(CLzmaEncHandle pp) -+{ -+ CLzmaEnc *dest = (CLzmaEnc *)pp; -+ const CSaveState *p = &dest->saveState; -+ int i; -+ dest->lenEnc = p->lenEnc; -+ dest->repLenEnc = p->repLenEnc; -+ dest->state = p->state; -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); -+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); -+ } -+ for (i = 0; i < kNumLenToPosStates; i++) -+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); -+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); -+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); -+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); -+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); -+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); -+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); -+ memcpy(dest->reps, p->reps, sizeof(p->reps)); -+ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); -+} -+ -+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ CLzmaEncProps props = *props2; -+ LzmaEncProps_Normalize(&props); -+ -+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || -+ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) -+ return SZ_ERROR_PARAM; -+ p->dictSize = props.dictSize; -+ p->matchFinderCycles = props.mc; -+ { -+ unsigned fb = props.fb; -+ if (fb < 5) -+ fb = 5; -+ if (fb > LZMA_MATCH_LEN_MAX) -+ fb = LZMA_MATCH_LEN_MAX; -+ p->numFastBytes = fb; -+ } -+ p->lc = props.lc; -+ p->lp = props.lp; -+ p->pb = props.pb; -+ p->fastMode = (props.algo == 0); -+ p->matchFinderBase.btMode = props.btMode; -+ { -+ UInt32 numHashBytes = 4; -+ if (props.btMode) -+ { -+ if (props.numHashBytes < 2) -+ numHashBytes = 2; -+ else if (props.numHashBytes < 4) -+ numHashBytes = props.numHashBytes; -+ } -+ p->matchFinderBase.numHashBytes = numHashBytes; -+ } -+ -+ p->matchFinderBase.cutValue = props.mc; -+ -+ p->writeEndMark = props.writeEndMark; -+ -+ #ifndef _7ZIP_ST -+ /* -+ if (newMultiThread != _multiThread) -+ { -+ ReleaseMatchFinder(); -+ _multiThread = newMultiThread; -+ } -+ */ -+ p->multiThread = (props.numThreads > 1); -+ #endif -+ -+ return SZ_OK; -+} -+ -+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; -+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; -+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; -+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; -+ -+#define IsCharState(s) ((s) < 7) -+ -+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) -+ -+#define kInfinityPrice (1 << 30) -+ -+static void RangeEnc_Construct(CRangeEnc *p) -+{ -+ p->outStream = 0; -+ p->bufBase = 0; -+} -+ -+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) -+ -+#define RC_BUF_SIZE (1 << 16) -+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) -+{ -+ if (p->bufBase == 0) -+ { -+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); -+ if (p->bufBase == 0) -+ return 0; -+ p->bufLim = p->bufBase + RC_BUF_SIZE; -+ } -+ return 1; -+} -+ -+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->bufBase); -+ p->bufBase = 0; -+} -+ -+static void RangeEnc_Init(CRangeEnc *p) -+{ -+ /* Stream.Init(); */ -+ p->low = 0; -+ p->range = 0xFFFFFFFF; -+ p->cacheSize = 1; -+ p->cache = 0; -+ -+ p->buf = p->bufBase; -+ -+ p->processed = 0; -+ p->res = SZ_OK; -+} -+ -+static void RangeEnc_FlushStream(CRangeEnc *p) -+{ -+ size_t num; -+ if (p->res != SZ_OK) -+ return; -+ num = p->buf - p->bufBase; -+ if (num != p->outStream->Write(p->outStream, p->bufBase, num)) -+ p->res = SZ_ERROR_WRITE; -+ p->processed += num; -+ p->buf = p->bufBase; -+} -+ -+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) -+{ -+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) -+ { -+ Byte temp = p->cache; -+ do -+ { -+ Byte *buf = p->buf; -+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); -+ p->buf = buf; -+ if (buf == p->bufLim) -+ RangeEnc_FlushStream(p); -+ temp = 0xFF; -+ } -+ while (--p->cacheSize != 0); -+ p->cache = (Byte)((UInt32)p->low >> 24); -+ } -+ p->cacheSize++; -+ p->low = (UInt32)p->low << 8; -+} -+ -+static void RangeEnc_FlushData(CRangeEnc *p) -+{ -+ int i; -+ for (i = 0; i < 5; i++) -+ RangeEnc_ShiftLow(p); -+} -+ -+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) -+{ -+ do -+ { -+ p->range >>= 1; -+ p->low += p->range & (0 - ((value >> --numBits) & 1)); -+ if (p->range < kTopValue) -+ { -+ p->range <<= 8; -+ RangeEnc_ShiftLow(p); -+ } -+ } -+ while (numBits != 0); -+} -+ -+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) -+{ -+ UInt32 ttt = *prob; -+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; -+ if (symbol == 0) -+ { -+ p->range = newBound; -+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits; -+ } -+ else -+ { -+ p->low += newBound; -+ p->range -= newBound; -+ ttt -= ttt >> kNumMoveBits; -+ } -+ *prob = (CLzmaProb)ttt; -+ if (p->range < kTopValue) -+ { -+ p->range <<= 8; -+ RangeEnc_ShiftLow(p); -+ } -+} -+ -+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) -+{ -+ symbol |= 0x100; -+ do -+ { -+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); -+ symbol <<= 1; -+ } -+ while (symbol < 0x10000); -+} -+ -+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) -+{ -+ UInt32 offs = 0x100; -+ symbol |= 0x100; -+ do -+ { -+ matchByte <<= 1; -+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); -+ symbol <<= 1; -+ offs &= ~(matchByte ^ symbol); -+ } -+ while (symbol < 0x10000); -+} -+ -+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) -+{ -+ UInt32 i; -+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) -+ { -+ const int kCyclesBits = kNumBitPriceShiftBits; -+ UInt32 w = i; -+ UInt32 bitCount = 0; -+ int j; -+ for (j = 0; j < kCyclesBits; j++) -+ { -+ w = w * w; -+ bitCount <<= 1; -+ while (w >= ((UInt32)1 << 16)) -+ { -+ w >>= 1; -+ bitCount++; -+ } -+ } -+ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); -+ } -+} -+ -+ -+#define GET_PRICE(prob, symbol) \ -+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -+ -+#define GET_PRICEa(prob, symbol) \ -+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; -+ -+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] -+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -+ -+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] -+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] -+ -+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ symbol |= 0x100; -+ do -+ { -+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); -+ symbol <<= 1; -+ } -+ while (symbol < 0x10000); -+ return price; -+} -+ -+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ UInt32 offs = 0x100; -+ symbol |= 0x100; -+ do -+ { -+ matchByte <<= 1; -+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); -+ symbol <<= 1; -+ offs &= ~(matchByte ^ symbol); -+ } -+ while (symbol < 0x10000); -+ return price; -+} -+ -+ -+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -+{ -+ UInt32 m = 1; -+ int i; -+ for (i = numBitLevels; i != 0;) -+ { -+ UInt32 bit; -+ i--; -+ bit = (symbol >> i) & 1; -+ RangeEnc_EncodeBit(rc, probs + m, bit); -+ m = (m << 1) | bit; -+ } -+} -+ -+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) -+{ -+ UInt32 m = 1; -+ int i; -+ for (i = 0; i < numBitLevels; i++) -+ { -+ UInt32 bit = symbol & 1; -+ RangeEnc_EncodeBit(rc, probs + m, bit); -+ m = (m << 1) | bit; -+ symbol >>= 1; -+ } -+} -+ -+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ symbol |= (1 << numBitLevels); -+ while (symbol != 1) -+ { -+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1); -+ symbol >>= 1; -+ } -+ return price; -+} -+ -+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) -+{ -+ UInt32 price = 0; -+ UInt32 m = 1; -+ int i; -+ for (i = numBitLevels; i != 0; i--) -+ { -+ UInt32 bit = symbol & 1; -+ symbol >>= 1; -+ price += GET_PRICEa(probs[m], bit); -+ m = (m << 1) | bit; -+ } -+ return price; -+} -+ -+ -+static void LenEnc_Init(CLenEnc *p) -+{ -+ unsigned i; -+ p->choice = p->choice2 = kProbInitValue; -+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) -+ p->low[i] = kProbInitValue; -+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) -+ p->mid[i] = kProbInitValue; -+ for (i = 0; i < kLenNumHighSymbols; i++) -+ p->high[i] = kProbInitValue; -+} -+ -+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) -+{ -+ if (symbol < kLenNumLowSymbols) -+ { -+ RangeEnc_EncodeBit(rc, &p->choice, 0); -+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); -+ } -+ else -+ { -+ RangeEnc_EncodeBit(rc, &p->choice, 1); -+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) -+ { -+ RangeEnc_EncodeBit(rc, &p->choice2, 0); -+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); -+ } -+ else -+ { -+ RangeEnc_EncodeBit(rc, &p->choice2, 1); -+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); -+ } -+ } -+} -+ -+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) -+{ -+ UInt32 a0 = GET_PRICE_0a(p->choice); -+ UInt32 a1 = GET_PRICE_1a(p->choice); -+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); -+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); -+ UInt32 i = 0; -+ for (i = 0; i < kLenNumLowSymbols; i++) -+ { -+ if (i >= numSymbols) -+ return; -+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); -+ } -+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) -+ { -+ if (i >= numSymbols) -+ return; -+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); -+ } -+ for (; i < numSymbols; i++) -+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); -+} -+ -+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) -+{ -+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); -+ p->counters[posState] = p->tableSize; -+} -+ -+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) -+{ -+ UInt32 posState; -+ for (posState = 0; posState < numPosStates; posState++) -+ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -+} -+ -+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) -+{ -+ LenEnc_Encode(&p->p, rc, symbol, posState); -+ if (updatePrice) -+ if (--p->counters[posState] == 0) -+ LenPriceEnc_UpdateTable(p, posState, ProbPrices); -+} -+ -+ -+ -+ -+static void MovePos(CLzmaEnc *p, UInt32 num) -+{ -+ #ifdef SHOW_STAT -+ ttt += num; -+ printf("\n MovePos %d", num); -+ #endif -+ if (num != 0) -+ { -+ p->additionalOffset += num; -+ p->matchFinder.Skip(p->matchFinderObj, num); -+ } -+} -+ -+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) -+{ -+ UInt32 lenRes = 0, numPairs; -+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); -+ #ifdef SHOW_STAT -+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); -+ ttt++; -+ { -+ UInt32 i; -+ for (i = 0; i < numPairs; i += 2) -+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); -+ } -+ #endif -+ if (numPairs > 0) -+ { -+ lenRes = p->matches[numPairs - 2]; -+ if (lenRes == p->numFastBytes) -+ { -+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ UInt32 distance = p->matches[numPairs - 1] + 1; -+ UInt32 numAvail = p->numAvail; -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ { -+ const Byte *pby2 = pby - distance; -+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); -+ } -+ } -+ } -+ p->additionalOffset++; -+ *numDistancePairsRes = numPairs; -+ return lenRes; -+} -+ -+ -+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; -+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; -+#define IsShortRep(p) ((p)->backPrev == 0) -+ -+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) -+{ -+ return -+ GET_PRICE_0(p->isRepG0[state]) + -+ GET_PRICE_0(p->isRep0Long[state][posState]); -+} -+ -+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) -+{ -+ UInt32 price; -+ if (repIndex == 0) -+ { -+ price = GET_PRICE_0(p->isRepG0[state]); -+ price += GET_PRICE_1(p->isRep0Long[state][posState]); -+ } -+ else -+ { -+ price = GET_PRICE_1(p->isRepG0[state]); -+ if (repIndex == 1) -+ price += GET_PRICE_0(p->isRepG1[state]); -+ else -+ { -+ price += GET_PRICE_1(p->isRepG1[state]); -+ price += GET_PRICE(p->isRepG2[state], repIndex - 2); -+ } -+ } -+ return price; -+} -+ -+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) -+{ -+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + -+ GetPureRepPrice(p, repIndex, state, posState); -+} -+ -+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) -+{ -+ UInt32 posMem = p->opt[cur].posPrev; -+ UInt32 backMem = p->opt[cur].backPrev; -+ p->optimumEndIndex = cur; -+ do -+ { -+ if (p->opt[cur].prev1IsChar) -+ { -+ MakeAsChar(&p->opt[posMem]) -+ p->opt[posMem].posPrev = posMem - 1; -+ if (p->opt[cur].prev2) -+ { -+ p->opt[posMem - 1].prev1IsChar = False; -+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; -+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; -+ } -+ } -+ { -+ UInt32 posPrev = posMem; -+ UInt32 backCur = backMem; -+ -+ backMem = p->opt[posPrev].backPrev; -+ posMem = p->opt[posPrev].posPrev; -+ -+ p->opt[posPrev].backPrev = backCur; -+ p->opt[posPrev].posPrev = cur; -+ cur = posPrev; -+ } -+ } -+ while (cur != 0); -+ *backRes = p->opt[0].backPrev; -+ p->optimumCurrentIndex = p->opt[0].posPrev; -+ return p->optimumCurrentIndex; -+} -+ -+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) -+ -+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) -+{ -+ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; -+ UInt32 matchPrice, repMatchPrice, normalMatchPrice; -+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; -+ UInt32 *matches; -+ const Byte *data; -+ Byte curByte, matchByte; -+ if (p->optimumEndIndex != p->optimumCurrentIndex) -+ { -+ const COptimal *opt = &p->opt[p->optimumCurrentIndex]; -+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; -+ *backRes = opt->backPrev; -+ p->optimumCurrentIndex = opt->posPrev; -+ return lenRes; -+ } -+ p->optimumCurrentIndex = p->optimumEndIndex = 0; -+ -+ if (p->additionalOffset == 0) -+ mainLen = ReadMatchDistances(p, &numPairs); -+ else -+ { -+ mainLen = p->longestMatchLength; -+ numPairs = p->numPairs; -+ } -+ -+ numAvail = p->numAvail; -+ if (numAvail < 2) -+ { -+ *backRes = (UInt32)(-1); -+ return 1; -+ } -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ repMaxIndex = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 lenTest; -+ const Byte *data2; -+ reps[i] = p->reps[i]; -+ data2 = data - (reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ { -+ repLens[i] = 0; -+ continue; -+ } -+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -+ repLens[i] = lenTest; -+ if (lenTest > repLens[repMaxIndex]) -+ repMaxIndex = i; -+ } -+ if (repLens[repMaxIndex] >= p->numFastBytes) -+ { -+ UInt32 lenRes; -+ *backRes = repMaxIndex; -+ lenRes = repLens[repMaxIndex]; -+ MovePos(p, lenRes - 1); -+ return lenRes; -+ } -+ -+ matches = p->matches; -+ if (mainLen >= p->numFastBytes) -+ { -+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 1); -+ return mainLen; -+ } -+ curByte = *data; -+ matchByte = *(data - (reps[0] + 1)); -+ -+ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) -+ { -+ *backRes = (UInt32)-1; -+ return 1; -+ } -+ -+ p->opt[0].state = (CState)p->state; -+ -+ posState = (position & p->pbMask); -+ -+ { -+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + -+ (!IsCharState(p->state) ? -+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -+ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -+ } -+ -+ MakeAsChar(&p->opt[1]); -+ -+ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); -+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); -+ -+ if (matchByte == curByte) -+ { -+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); -+ if (shortRepPrice < p->opt[1].price) -+ { -+ p->opt[1].price = shortRepPrice; -+ MakeAsShortRep(&p->opt[1]); -+ } -+ } -+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); -+ -+ if (lenEnd < 2) -+ { -+ *backRes = p->opt[1].backPrev; -+ return 1; -+ } -+ -+ p->opt[1].posPrev = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ p->opt[0].backs[i] = reps[i]; -+ -+ len = lenEnd; -+ do -+ p->opt[len--].price = kInfinityPrice; -+ while (len >= 2); -+ -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 repLen = repLens[i]; -+ UInt32 price; -+ if (repLen < 2) -+ continue; -+ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); -+ do -+ { -+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; -+ COptimal *opt = &p->opt[repLen]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = 0; -+ opt->backPrev = i; -+ opt->prev1IsChar = False; -+ } -+ } -+ while (--repLen >= 2); -+ } -+ -+ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); -+ -+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); -+ if (len <= mainLen) -+ { -+ UInt32 offs = 0; -+ while (len > matches[offs]) -+ offs += 2; -+ for (; ; len++) -+ { -+ COptimal *opt; -+ UInt32 distance = matches[offs + 1]; -+ -+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; -+ UInt32 lenToPosState = GetLenToPosState(len); -+ if (distance < kNumFullDistances) -+ curAndLenPrice += p->distancesPrices[lenToPosState][distance]; -+ else -+ { -+ UInt32 slot; -+ GetPosSlot2(distance, slot); -+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; -+ } -+ opt = &p->opt[len]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = 0; -+ opt->backPrev = distance + LZMA_NUM_REPS; -+ opt->prev1IsChar = False; -+ } -+ if (len == matches[offs]) -+ { -+ offs += 2; -+ if (offs == numPairs) -+ break; -+ } -+ } -+ } -+ -+ cur = 0; -+ -+ #ifdef SHOW_STAT2 -+ if (position >= 0) -+ { -+ unsigned i; -+ printf("\n pos = %4X", position); -+ for (i = cur; i <= lenEnd; i++) -+ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); -+ } -+ #endif -+ -+ for (;;) -+ { -+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; -+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; -+ Bool nextIsChar; -+ Byte curByte, matchByte; -+ const Byte *data; -+ COptimal *curOpt; -+ COptimal *nextOpt; -+ -+ cur++; -+ if (cur == lenEnd) -+ return Backward(p, backRes, cur); -+ -+ newLen = ReadMatchDistances(p, &numPairs); -+ if (newLen >= p->numFastBytes) -+ { -+ p->numPairs = numPairs; -+ p->longestMatchLength = newLen; -+ return Backward(p, backRes, cur); -+ } -+ position++; -+ curOpt = &p->opt[cur]; -+ posPrev = curOpt->posPrev; -+ if (curOpt->prev1IsChar) -+ { -+ posPrev--; -+ if (curOpt->prev2) -+ { -+ state = p->opt[curOpt->posPrev2].state; -+ if (curOpt->backPrev2 < LZMA_NUM_REPS) -+ state = kRepNextStates[state]; -+ else -+ state = kMatchNextStates[state]; -+ } -+ else -+ state = p->opt[posPrev].state; -+ state = kLiteralNextStates[state]; -+ } -+ else -+ state = p->opt[posPrev].state; -+ if (posPrev == cur - 1) -+ { -+ if (IsShortRep(curOpt)) -+ state = kShortRepNextStates[state]; -+ else -+ state = kLiteralNextStates[state]; -+ } -+ else -+ { -+ UInt32 pos; -+ const COptimal *prevOpt; -+ if (curOpt->prev1IsChar && curOpt->prev2) -+ { -+ posPrev = curOpt->posPrev2; -+ pos = curOpt->backPrev2; -+ state = kRepNextStates[state]; -+ } -+ else -+ { -+ pos = curOpt->backPrev; -+ if (pos < LZMA_NUM_REPS) -+ state = kRepNextStates[state]; -+ else -+ state = kMatchNextStates[state]; -+ } -+ prevOpt = &p->opt[posPrev]; -+ if (pos < LZMA_NUM_REPS) -+ { -+ UInt32 i; -+ reps[0] = prevOpt->backs[pos]; -+ for (i = 1; i <= pos; i++) -+ reps[i] = prevOpt->backs[i - 1]; -+ for (; i < LZMA_NUM_REPS; i++) -+ reps[i] = prevOpt->backs[i]; -+ } -+ else -+ { -+ UInt32 i; -+ reps[0] = (pos - LZMA_NUM_REPS); -+ for (i = 1; i < LZMA_NUM_REPS; i++) -+ reps[i] = prevOpt->backs[i - 1]; -+ } -+ } -+ curOpt->state = (CState)state; -+ -+ curOpt->backs[0] = reps[0]; -+ curOpt->backs[1] = reps[1]; -+ curOpt->backs[2] = reps[2]; -+ curOpt->backs[3] = reps[3]; -+ -+ curPrice = curOpt->price; -+ nextIsChar = False; -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ curByte = *data; -+ matchByte = *(data - (reps[0] + 1)); -+ -+ posState = (position & p->pbMask); -+ -+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); -+ { -+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); -+ curAnd1Price += -+ (!IsCharState(state) ? -+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : -+ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); -+ } -+ -+ nextOpt = &p->opt[cur + 1]; -+ -+ if (curAnd1Price < nextOpt->price) -+ { -+ nextOpt->price = curAnd1Price; -+ nextOpt->posPrev = cur; -+ MakeAsChar(nextOpt); -+ nextIsChar = True; -+ } -+ -+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); -+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); -+ -+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) -+ { -+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); -+ if (shortRepPrice <= nextOpt->price) -+ { -+ nextOpt->price = shortRepPrice; -+ nextOpt->posPrev = cur; -+ MakeAsShortRep(nextOpt); -+ nextIsChar = True; -+ } -+ } -+ numAvailFull = p->numAvail; -+ { -+ UInt32 temp = kNumOpts - 1 - cur; -+ if (temp < numAvailFull) -+ numAvailFull = temp; -+ } -+ -+ if (numAvailFull < 2) -+ continue; -+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); -+ -+ if (!nextIsChar && matchByte != curByte) /* speed optimization */ -+ { -+ /* try Literal + rep0 */ -+ UInt32 temp; -+ UInt32 lenTest2; -+ const Byte *data2 = data - (reps[0] + 1); -+ UInt32 limit = p->numFastBytes + 1; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ -+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); -+ lenTest2 = temp - 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kLiteralNextStates[state]; -+ UInt32 posStateNext = (position + 1) & p->pbMask; -+ UInt32 nextRepMatchPrice = curAnd1Price + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ UInt32 offset = cur + 1 + lenTest2; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = False; -+ } -+ } -+ } -+ } -+ -+ startLen = 2; /* speed optimization */ -+ { -+ UInt32 repIndex; -+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) -+ { -+ UInt32 lenTest; -+ UInt32 lenTestTemp; -+ UInt32 price; -+ const Byte *data2 = data - (reps[repIndex] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); -+ while (lenEnd < cur + lenTest) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ lenTestTemp = lenTest; -+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); -+ do -+ { -+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; -+ COptimal *opt = &p->opt[cur + lenTest]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur; -+ opt->backPrev = repIndex; -+ opt->prev1IsChar = False; -+ } -+ } -+ while (--lenTest >= 2); -+ lenTest = lenTestTemp; -+ -+ if (repIndex == 0) -+ startLen = lenTest + 1; -+ -+ /* if (_maxMode) */ -+ { -+ UInt32 lenTest2 = lenTest + 1; -+ UInt32 limit = lenTest2 + p->numFastBytes; -+ UInt32 nextRepMatchPrice; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -+ lenTest2 -= lenTest + 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kRepNextStates[state]; -+ UInt32 posStateNext = (position + lenTest) & p->pbMask; -+ UInt32 curAndLenCharPrice = -+ price + p->repLenEnc.prices[posState][lenTest - 2] + -+ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -+ data[lenTest], data2[lenTest], p->ProbPrices); -+ state2 = kLiteralNextStates[state2]; -+ posStateNext = (position + lenTest + 1) & p->pbMask; -+ nextRepMatchPrice = curAndLenCharPrice + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ UInt32 offset = cur + lenTest + 1 + lenTest2; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + lenTest + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = True; -+ opt->posPrev2 = cur; -+ opt->backPrev2 = repIndex; -+ } -+ } -+ } -+ } -+ } -+ } -+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ -+ if (newLen > numAvail) -+ { -+ newLen = numAvail; -+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); -+ matches[numPairs] = newLen; -+ numPairs += 2; -+ } -+ if (newLen >= startLen) -+ { -+ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); -+ UInt32 offs, curBack, posSlot; -+ UInt32 lenTest; -+ while (lenEnd < cur + newLen) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ -+ offs = 0; -+ while (startLen > matches[offs]) -+ offs += 2; -+ curBack = matches[offs + 1]; -+ GetPosSlot2(curBack, posSlot); -+ for (lenTest = /*2*/ startLen; ; lenTest++) -+ { -+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; -+ UInt32 lenToPosState = GetLenToPosState(lenTest); -+ COptimal *opt; -+ if (curBack < kNumFullDistances) -+ curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; -+ else -+ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; -+ -+ opt = &p->opt[cur + lenTest]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur; -+ opt->backPrev = curBack + LZMA_NUM_REPS; -+ opt->prev1IsChar = False; -+ } -+ -+ if (/*_maxMode && */lenTest == matches[offs]) -+ { -+ /* Try Match + Literal + Rep0 */ -+ const Byte *data2 = data - (curBack + 1); -+ UInt32 lenTest2 = lenTest + 1; -+ UInt32 limit = lenTest2 + p->numFastBytes; -+ UInt32 nextRepMatchPrice; -+ if (limit > numAvailFull) -+ limit = numAvailFull; -+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); -+ lenTest2 -= lenTest + 1; -+ if (lenTest2 >= 2) -+ { -+ UInt32 state2 = kMatchNextStates[state]; -+ UInt32 posStateNext = (position + lenTest) & p->pbMask; -+ UInt32 curAndLenCharPrice = curAndLenPrice + -+ GET_PRICE_0(p->isMatch[state2][posStateNext]) + -+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), -+ data[lenTest], data2[lenTest], p->ProbPrices); -+ state2 = kLiteralNextStates[state2]; -+ posStateNext = (posStateNext + 1) & p->pbMask; -+ nextRepMatchPrice = curAndLenCharPrice + -+ GET_PRICE_1(p->isMatch[state2][posStateNext]) + -+ GET_PRICE_1(p->isRep[state2]); -+ -+ /* for (; lenTest2 >= 2; lenTest2--) */ -+ { -+ UInt32 offset = cur + lenTest + 1 + lenTest2; -+ UInt32 curAndLenPrice; -+ COptimal *opt; -+ while (lenEnd < offset) -+ p->opt[++lenEnd].price = kInfinityPrice; -+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); -+ opt = &p->opt[offset]; -+ if (curAndLenPrice < opt->price) -+ { -+ opt->price = curAndLenPrice; -+ opt->posPrev = cur + lenTest + 1; -+ opt->backPrev = 0; -+ opt->prev1IsChar = True; -+ opt->prev2 = True; -+ opt->posPrev2 = cur; -+ opt->backPrev2 = curBack + LZMA_NUM_REPS; -+ } -+ } -+ } -+ offs += 2; -+ if (offs == numPairs) -+ break; -+ curBack = matches[offs + 1]; -+ if (curBack >= kNumFullDistances) -+ GetPosSlot2(curBack, posSlot); -+ } -+ } -+ } -+ } -+} -+ -+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) -+ -+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) -+{ -+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; -+ const Byte *data; -+ const UInt32 *matches; -+ -+ if (p->additionalOffset == 0) -+ mainLen = ReadMatchDistances(p, &numPairs); -+ else -+ { -+ mainLen = p->longestMatchLength; -+ numPairs = p->numPairs; -+ } -+ -+ numAvail = p->numAvail; -+ *backRes = (UInt32)-1; -+ if (numAvail < 2) -+ return 1; -+ if (numAvail > LZMA_MATCH_LEN_MAX) -+ numAvail = LZMA_MATCH_LEN_MAX; -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ -+ repLen = repIndex = 0; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 len; -+ const Byte *data2 = data - (p->reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ for (len = 2; len < numAvail && data[len] == data2[len]; len++); -+ if (len >= p->numFastBytes) -+ { -+ *backRes = i; -+ MovePos(p, len - 1); -+ return len; -+ } -+ if (len > repLen) -+ { -+ repIndex = i; -+ repLen = len; -+ } -+ } -+ -+ matches = p->matches; -+ if (mainLen >= p->numFastBytes) -+ { -+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 1); -+ return mainLen; -+ } -+ -+ mainDist = 0; /* for GCC */ -+ if (mainLen >= 2) -+ { -+ mainDist = matches[numPairs - 1]; -+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) -+ { -+ if (!ChangePair(matches[numPairs - 3], mainDist)) -+ break; -+ numPairs -= 2; -+ mainLen = matches[numPairs - 2]; -+ mainDist = matches[numPairs - 1]; -+ } -+ if (mainLen == 2 && mainDist >= 0x80) -+ mainLen = 1; -+ } -+ -+ if (repLen >= 2 && ( -+ (repLen + 1 >= mainLen) || -+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || -+ (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) -+ { -+ *backRes = repIndex; -+ MovePos(p, repLen - 1); -+ return repLen; -+ } -+ -+ if (mainLen < 2 || numAvail <= 2) -+ return 1; -+ -+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); -+ if (p->longestMatchLength >= 2) -+ { -+ UInt32 newDistance = matches[p->numPairs - 1]; -+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || -+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || -+ (p->longestMatchLength > mainLen + 1) || -+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) -+ return 1; -+ } -+ -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; -+ for (i = 0; i < LZMA_NUM_REPS; i++) -+ { -+ UInt32 len, limit; -+ const Byte *data2 = data - (p->reps[i] + 1); -+ if (data[0] != data2[0] || data[1] != data2[1]) -+ continue; -+ limit = mainLen - 1; -+ for (len = 2; len < limit && data[len] == data2[len]; len++); -+ if (len >= limit) -+ return 1; -+ } -+ *backRes = mainDist + LZMA_NUM_REPS; -+ MovePos(p, mainLen - 2); -+ return mainLen; -+} -+ -+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) -+{ -+ UInt32 len; -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -+ p->state = kMatchNextStates[p->state]; -+ len = LZMA_MATCH_LEN_MIN; -+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); -+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); -+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); -+} -+ -+static SRes CheckErrors(CLzmaEnc *p) -+{ -+ if (p->result != SZ_OK) -+ return p->result; -+ if (p->rc.res != SZ_OK) -+ p->result = SZ_ERROR_WRITE; -+ if (p->matchFinderBase.result != SZ_OK) -+ p->result = SZ_ERROR_READ; -+ if (p->result != SZ_OK) -+ p->finished = True; -+ return p->result; -+} -+ -+static SRes Flush(CLzmaEnc *p, UInt32 nowPos) -+{ -+ /* ReleaseMFStream(); */ -+ p->finished = True; -+ if (p->writeEndMark) -+ WriteEndMarker(p, nowPos & p->pbMask); -+ RangeEnc_FlushData(&p->rc); -+ RangeEnc_FlushStream(&p->rc); -+ return CheckErrors(p); -+} -+ -+static void FillAlignPrices(CLzmaEnc *p) -+{ -+ UInt32 i; -+ for (i = 0; i < kAlignTableSize; i++) -+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); -+ p->alignPriceCount = 0; -+} -+ -+static void FillDistancesPrices(CLzmaEnc *p) -+{ -+ UInt32 tempPrices[kNumFullDistances]; -+ UInt32 i, lenToPosState; -+ for (i = kStartPosModelIndex; i < kNumFullDistances; i++) -+ { -+ UInt32 posSlot = GetPosSlot1(i); -+ UInt32 footerBits = ((posSlot >> 1) - 1); -+ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -+ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); -+ } -+ -+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) -+ { -+ UInt32 posSlot; -+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; -+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; -+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++) -+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); -+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) -+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); -+ -+ { -+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; -+ UInt32 i; -+ for (i = 0; i < kStartPosModelIndex; i++) -+ distancesPrices[i] = posSlotPrices[i]; -+ for (; i < kNumFullDistances; i++) -+ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; -+ } -+ } -+ p->matchPriceCount = 0; -+} -+ -+void LzmaEnc_Construct(CLzmaEnc *p) -+{ -+ RangeEnc_Construct(&p->rc); -+ MatchFinder_Construct(&p->matchFinderBase); -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Construct(&p->matchFinderMt); -+ p->matchFinderMt.MatchFinder = &p->matchFinderBase; -+ #endif -+ -+ { -+ CLzmaEncProps props; -+ LzmaEncProps_Init(&props); -+ LzmaEnc_SetProps(p, &props); -+ } -+ -+ #ifndef LZMA_LOG_BSR -+ LzmaEnc_FastPosInit(p->g_FastPos); -+ #endif -+ -+ LzmaEnc_InitPriceTables(p->ProbPrices); -+ p->litProbs = 0; -+ p->saveState.litProbs = 0; -+} -+ -+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) -+{ -+ void *p; -+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); -+ if (p != 0) -+ LzmaEnc_Construct((CLzmaEnc *)p); -+ return p; -+} -+ -+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) -+{ -+ alloc->Free(alloc, p->litProbs); -+ alloc->Free(alloc, p->saveState.litProbs); -+ p->litProbs = 0; -+ p->saveState.litProbs = 0; -+} -+ -+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ #ifndef _7ZIP_ST -+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); -+ #endif -+ MatchFinder_Free(&p->matchFinderBase, allocBig); -+ LzmaEnc_FreeLits(p, alloc); -+ RangeEnc_Free(&p->rc, alloc); -+} -+ -+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); -+ alloc->Free(alloc, p); -+} -+ -+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) -+{ -+ UInt32 nowPos32, startPos32; -+ if (p->needInit) -+ { -+ p->matchFinder.Init(p->matchFinderObj); -+ p->needInit = 0; -+ } -+ -+ if (p->finished) -+ return p->result; -+ RINOK(CheckErrors(p)); -+ -+ nowPos32 = (UInt32)p->nowPos64; -+ startPos32 = nowPos32; -+ -+ if (p->nowPos64 == 0) -+ { -+ UInt32 numPairs; -+ Byte curByte; -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -+ return Flush(p, nowPos32); -+ ReadMatchDistances(p, &numPairs); -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); -+ p->state = kLiteralNextStates[p->state]; -+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); -+ LitEnc_Encode(&p->rc, p->litProbs, curByte); -+ p->additionalOffset--; -+ nowPos32++; -+ } -+ -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) -+ for (;;) -+ { -+ UInt32 pos, len, posState; -+ -+ if (p->fastMode) -+ len = GetOptimumFast(p, &pos); -+ else -+ len = GetOptimum(p, nowPos32, &pos); -+ -+ #ifdef SHOW_STAT2 -+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); -+ #endif -+ -+ posState = nowPos32 & p->pbMask; -+ if (len == 1 && pos == (UInt32)-1) -+ { -+ Byte curByte; -+ CLzmaProb *probs; -+ const Byte *data; -+ -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); -+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -+ curByte = *data; -+ probs = LIT_PROBS(nowPos32, *(data - 1)); -+ if (IsCharState(p->state)) -+ LitEnc_Encode(&p->rc, probs, curByte); -+ else -+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); -+ p->state = kLiteralNextStates[p->state]; -+ } -+ else -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); -+ if (pos < LZMA_NUM_REPS) -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); -+ if (pos == 0) -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); -+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); -+ } -+ else -+ { -+ UInt32 distance = p->reps[pos]; -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); -+ if (pos == 1) -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); -+ else -+ { -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); -+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); -+ if (pos == 3) -+ p->reps[3] = p->reps[2]; -+ p->reps[2] = p->reps[1]; -+ } -+ p->reps[1] = p->reps[0]; -+ p->reps[0] = distance; -+ } -+ if (len == 1) -+ p->state = kShortRepNextStates[p->state]; -+ else -+ { -+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ p->state = kRepNextStates[p->state]; -+ } -+ } -+ else -+ { -+ UInt32 posSlot; -+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); -+ p->state = kMatchNextStates[p->state]; -+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); -+ pos -= LZMA_NUM_REPS; -+ GetPosSlot(pos, posSlot); -+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); -+ -+ if (posSlot >= kStartPosModelIndex) -+ { -+ UInt32 footerBits = ((posSlot >> 1) - 1); -+ UInt32 base = ((2 | (posSlot & 1)) << footerBits); -+ UInt32 posReduced = pos - base; -+ -+ if (posSlot < kEndPosModelIndex) -+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); -+ else -+ { -+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); -+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); -+ p->alignPriceCount++; -+ } -+ } -+ p->reps[3] = p->reps[2]; -+ p->reps[2] = p->reps[1]; -+ p->reps[1] = p->reps[0]; -+ p->reps[0] = pos; -+ p->matchPriceCount++; -+ } -+ } -+ p->additionalOffset -= len; -+ nowPos32 += len; -+ if (p->additionalOffset == 0) -+ { -+ UInt32 processed; -+ if (!p->fastMode) -+ { -+ if (p->matchPriceCount >= (1 << 7)) -+ FillDistancesPrices(p); -+ if (p->alignPriceCount >= kAlignTableSize) -+ FillAlignPrices(p); -+ } -+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) -+ break; -+ processed = nowPos32 - startPos32; -+ if (useLimits) -+ { -+ if (processed + kNumOpts + 300 >= maxUnpackSize || -+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) -+ break; -+ } -+ else if (processed >= (1 << 15)) -+ { -+ p->nowPos64 += nowPos32 - startPos32; -+ return CheckErrors(p); -+ } -+ } -+ } -+ p->nowPos64 += nowPos32 - startPos32; -+ return Flush(p, nowPos32); -+} -+ -+#define kBigHashDicLimit ((UInt32)1 << 24) -+ -+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ UInt32 beforeSize = kNumOpts; -+ Bool btMode; -+ if (!RangeEnc_Alloc(&p->rc, alloc)) -+ return SZ_ERROR_MEM; -+ btMode = (p->matchFinderBase.btMode != 0); -+ #ifndef _7ZIP_ST -+ p->mtMode = (p->multiThread && !p->fastMode && btMode); -+ #endif -+ -+ { -+ unsigned lclp = p->lc + p->lp; -+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) -+ { -+ LzmaEnc_FreeLits(p, alloc); -+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); -+ if (p->litProbs == 0 || p->saveState.litProbs == 0) -+ { -+ LzmaEnc_FreeLits(p, alloc); -+ return SZ_ERROR_MEM; -+ } -+ p->lclp = lclp; -+ } -+ } -+ -+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); -+ -+ if (beforeSize + p->dictSize < keepWindowSize) -+ beforeSize = keepWindowSize - p->dictSize; -+ -+ #ifndef _7ZIP_ST -+ if (p->mtMode) -+ { -+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); -+ p->matchFinderObj = &p->matchFinderMt; -+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); -+ } -+ else -+ #endif -+ { -+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) -+ return SZ_ERROR_MEM; -+ p->matchFinderObj = &p->matchFinderBase; -+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); -+ } -+ return SZ_OK; -+} -+ -+void LzmaEnc_Init(CLzmaEnc *p) -+{ -+ UInt32 i; -+ p->state = 0; -+ for (i = 0 ; i < LZMA_NUM_REPS; i++) -+ p->reps[i] = 0; -+ -+ RangeEnc_Init(&p->rc); -+ -+ -+ for (i = 0; i < kNumStates; i++) -+ { -+ UInt32 j; -+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) -+ { -+ p->isMatch[i][j] = kProbInitValue; -+ p->isRep0Long[i][j] = kProbInitValue; -+ } -+ p->isRep[i] = kProbInitValue; -+ p->isRepG0[i] = kProbInitValue; -+ p->isRepG1[i] = kProbInitValue; -+ p->isRepG2[i] = kProbInitValue; -+ } -+ -+ { -+ UInt32 num = 0x300 << (p->lp + p->lc); -+ for (i = 0; i < num; i++) -+ p->litProbs[i] = kProbInitValue; -+ } -+ -+ { -+ for (i = 0; i < kNumLenToPosStates; i++) -+ { -+ CLzmaProb *probs = p->posSlotEncoder[i]; -+ UInt32 j; -+ for (j = 0; j < (1 << kNumPosSlotBits); j++) -+ probs[j] = kProbInitValue; -+ } -+ } -+ { -+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) -+ p->posEncoders[i] = kProbInitValue; -+ } -+ -+ LenEnc_Init(&p->lenEnc.p); -+ LenEnc_Init(&p->repLenEnc.p); -+ -+ for (i = 0; i < (1 << kNumAlignBits); i++) -+ p->posAlignEncoder[i] = kProbInitValue; -+ -+ p->optimumEndIndex = 0; -+ p->optimumCurrentIndex = 0; -+ p->additionalOffset = 0; -+ -+ p->pbMask = (1 << p->pb) - 1; -+ p->lpMask = (1 << p->lp) - 1; -+} -+ -+void LzmaEnc_InitPrices(CLzmaEnc *p) -+{ -+ if (!p->fastMode) -+ { -+ FillDistancesPrices(p); -+ FillAlignPrices(p); -+ } -+ -+ p->lenEnc.tableSize = -+ p->repLenEnc.tableSize = -+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; -+ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); -+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); -+} -+ -+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ UInt32 i; -+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) -+ if (p->dictSize <= ((UInt32)1 << i)) -+ break; -+ p->distTableSize = i * 2; -+ -+ p->finished = False; -+ p->result = SZ_OK; -+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); -+ LzmaEnc_Init(p); -+ LzmaEnc_InitPrices(p); -+ p->nowPos64 = 0; -+ return SZ_OK; -+} -+ -+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ p->matchFinderBase.stream = inStream; -+ p->needInit = 1; -+ p->rc.outStream = outStream; -+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); -+} -+ -+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, -+ ISeqInStream *inStream, UInt32 keepWindowSize, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ p->matchFinderBase.stream = inStream; -+ p->needInit = 1; -+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+} -+ -+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) -+{ -+ p->matchFinderBase.directInput = 1; -+ p->matchFinderBase.bufferBase = (Byte *)src; -+ p->matchFinderBase.directInputRem = srcLen; -+} -+ -+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, -+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ LzmaEnc_SetInputBuf(p, src, srcLen); -+ p->needInit = 1; -+ -+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); -+} -+ -+void LzmaEnc_Finish(CLzmaEncHandle pp) -+{ -+ #ifndef _7ZIP_ST -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ if (p->mtMode) -+ MatchFinderMt_ReleaseStream(&p->matchFinderMt); -+ #else -+ pp = pp; -+ #endif -+} -+ -+typedef struct -+{ -+ ISeqOutStream funcTable; -+ Byte *data; -+ SizeT rem; -+ Bool overflow; -+} CSeqOutStreamBuf; -+ -+static size_t MyWrite(void *pp, const void *data, size_t size) -+{ -+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; -+ if (p->rem < size) -+ { -+ size = p->rem; -+ p->overflow = True; -+ } -+ memcpy(p->data, data, size); -+ p->rem -= size; -+ p->data += size; -+ return size; -+} -+ -+ -+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) -+{ -+ const CLzmaEnc *p = (CLzmaEnc *)pp; -+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); -+} -+ -+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) -+{ -+ const CLzmaEnc *p = (CLzmaEnc *)pp; -+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; -+} -+ -+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, -+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ UInt64 nowPos64; -+ SRes res; -+ CSeqOutStreamBuf outStream; -+ -+ outStream.funcTable.Write = MyWrite; -+ outStream.data = dest; -+ outStream.rem = *destLen; -+ outStream.overflow = False; -+ -+ p->writeEndMark = False; -+ p->finished = False; -+ p->result = SZ_OK; -+ -+ if (reInit) -+ LzmaEnc_Init(p); -+ LzmaEnc_InitPrices(p); -+ nowPos64 = p->nowPos64; -+ RangeEnc_Init(&p->rc); -+ p->rc.outStream = &outStream.funcTable; -+ -+ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); -+ -+ *unpackSize = (UInt32)(p->nowPos64 - nowPos64); -+ *destLen -= outStream.rem; -+ if (outStream.overflow) -+ return SZ_ERROR_OUTPUT_EOF; -+ -+ return res; -+} -+ -+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) -+{ -+ SRes res = SZ_OK; -+ -+ #ifndef _7ZIP_ST -+ Byte allocaDummy[0x300]; -+ int i = 0; -+ for (i = 0; i < 16; i++) -+ allocaDummy[i] = (Byte)i; -+ #endif -+ -+ for (;;) -+ { -+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0); -+ if (res != SZ_OK || p->finished != 0) -+ break; -+ if (progress != 0) -+ { -+ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); -+ if (res != SZ_OK) -+ { -+ res = SZ_ERROR_PROGRESS; -+ break; -+ } -+ } -+ } -+ LzmaEnc_Finish(p); -+ return res; -+} -+ -+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, -+ ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); -+ return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); -+} -+ -+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ int i; -+ UInt32 dictSize = p->dictSize; -+ if (*size < LZMA_PROPS_SIZE) -+ return SZ_ERROR_PARAM; -+ *size = LZMA_PROPS_SIZE; -+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); -+ -+ for (i = 11; i <= 30; i++) -+ { -+ if (dictSize <= ((UInt32)2 << i)) -+ { -+ dictSize = (2 << i); -+ break; -+ } -+ if (dictSize <= ((UInt32)3 << i)) -+ { -+ dictSize = (3 << i); -+ break; -+ } -+ } -+ -+ for (i = 0; i < 4; i++) -+ props[1 + i] = (Byte)(dictSize >> (8 * i)); -+ return SZ_OK; -+} -+ -+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ SRes res; -+ CLzmaEnc *p = (CLzmaEnc *)pp; -+ -+ CSeqOutStreamBuf outStream; -+ -+ LzmaEnc_SetInputBuf(p, src, srcLen); -+ -+ outStream.funcTable.Write = MyWrite; -+ outStream.data = dest; -+ outStream.rem = *destLen; -+ outStream.overflow = False; -+ -+ p->writeEndMark = writeEndMark; -+ -+ p->rc.outStream = &outStream.funcTable; -+ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); -+ if (res == SZ_OK) -+ res = LzmaEnc_Encode2(p, progress); -+ -+ *destLen -= outStream.rem; -+ if (outStream.overflow) -+ return SZ_ERROR_OUTPUT_EOF; -+ return res; -+} -+ -+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, -+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, -+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) -+{ -+ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); -+ SRes res; -+ if (p == 0) -+ return SZ_ERROR_MEM; -+ -+ res = LzmaEnc_SetProps(p, props); -+ if (res == SZ_OK) -+ { -+ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); -+ if (res == SZ_OK) -+ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, -+ writeEndMark, progress, alloc, allocBig); -+ } -+ -+ LzmaEnc_Destroy(p, alloc, allocBig); -+ return res; -+} ---- /dev/null -+++ b/lib/lzma/Makefile -@@ -0,0 +1,7 @@ -+lzma_compress-objs := LzFind.o LzmaEnc.o -+lzma_decompress-objs := LzmaDec.o -+ -+obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o -+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o -+ -+EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h diff --git a/target/linux/generic/pending-6.1/532-jffs2_eofdetect.patch b/target/linux/generic/pending-6.1/532-jffs2_eofdetect.patch deleted file mode 100644 index 744fbd0e21790b..00000000000000 --- a/target/linux/generic/pending-6.1/532-jffs2_eofdetect.patch +++ /dev/null @@ -1,65 +0,0 @@ -From: Felix Fietkau -Subject: fs: jffs2: EOF marker - -Signed-off-by: Felix Fietkau ---- - fs/jffs2/build.c | 10 ++++++++++ - fs/jffs2/scan.c | 21 +++++++++++++++++++-- - 2 files changed, 29 insertions(+), 2 deletions(-) - ---- a/fs/jffs2/build.c -+++ b/fs/jffs2/build.c -@@ -117,6 +117,16 @@ static int jffs2_build_filesystem(struct - dbg_fsbuild("scanned flash completely\n"); - jffs2_dbg_dump_block_lists_nolock(c); - -+ if (c->flags & (1 << 7)) { -+ printk("%s(): unlocking the mtd device... ", __func__); -+ mtd_unlock(c->mtd, 0, c->mtd->size); -+ printk("done.\n"); -+ -+ printk("%s(): erasing all blocks after the end marker... ", __func__); -+ jffs2_erase_pending_blocks(c, -1); -+ printk("done.\n"); -+ } -+ - dbg_fsbuild("pass 1 starting\n"); - c->flags |= JFFS2_SB_FLAG_BUILDING; - /* Now scan the directory tree, increasing nlink according to every dirent found. */ ---- a/fs/jffs2/scan.c -+++ b/fs/jffs2/scan.c -@@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_in - /* reset summary info for next eraseblock scan */ - jffs2_sum_reset_collected(s); - -- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -- buf_size, s); -+ if (c->flags & (1 << 7)) { -+ if (mtd_block_isbad(c->mtd, jeb->offset)) -+ ret = BLK_STATE_BADBLOCK; -+ else -+ ret = BLK_STATE_ALLFF; -+ } else -+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -+ buf_size, s); - - if (ret < 0) - goto out; -@@ -567,6 +573,17 @@ full_scan: - return err; - } - -+ if ((buf[0] == 0xde) && -+ (buf[1] == 0xad) && -+ (buf[2] == 0xc0) && -+ (buf[3] == 0xde)) { -+ /* end of filesystem. erase everything after this point */ -+ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset); -+ c->flags |= (1 << 7); -+ -+ return BLK_STATE_ALLFF; -+ } -+ - /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ - ofs = 0; - max_ofs = EMPTY_SCAN_SIZE(c->sector_size); diff --git a/target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch b/target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch deleted file mode 100644 index d7548c14199789..00000000000000 --- a/target/linux/generic/pending-6.1/600-netfilter_conntrack_flush.patch +++ /dev/null @@ -1,90 +0,0 @@ -From: Felix Fietkau -Subject: netfilter: add support for flushing conntrack via /proc - -lede-commit 8193bbe59a74d34d6a26d4a8cb857b1952905314 -Signed-off-by: Felix Fietkau ---- - net/netfilter/nf_conntrack_standalone.c | 59 ++++++++++++++++++++++++++++++++- - 1 file changed, 58 insertions(+), 1 deletion(-) - ---- a/net/netfilter/nf_conntrack_standalone.c -+++ b/net/netfilter/nf_conntrack_standalone.c -@@ -9,6 +9,7 @@ - #include - #include - #include -+#include - #include - #ifdef CONFIG_SYSCTL - #include -@@ -465,6 +466,58 @@ static int ct_cpu_seq_show(struct seq_fi - return 0; - } - -+struct kill_request { -+ u16 family; -+ union nf_inet_addr addr; -+}; -+ -+static int kill_matching(struct nf_conn *i, void *data) -+{ -+ struct kill_request *kr = data; -+ struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple; -+ struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple; -+ -+ if (!kr->family) -+ return 1; -+ -+ if (t1->src.l3num != kr->family) -+ return 0; -+ -+ return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t2->src.u3) || -+ nf_inet_addr_cmp(&kr->addr, &t2->dst.u3)); -+} -+ -+static int ct_file_write(struct file *file, char *buf, size_t count) -+{ -+ struct seq_file *seq = file->private_data; -+ struct nf_ct_iter_data iter_data; -+ struct kill_request kr = { }; -+ -+ if (count == 0) -+ return 0; -+ -+ if (count >= INET6_ADDRSTRLEN) -+ count = INET6_ADDRSTRLEN - 1; -+ -+ if (strnchr(buf, count, ':')) { -+ kr.family = AF_INET6; -+ if (!in6_pton(buf, count, (void *)&kr.addr, '\n', NULL)) -+ return -EINVAL; -+ } else if (strnchr(buf, count, '.')) { -+ kr.family = AF_INET; -+ if (!in4_pton(buf, count, (void *)&kr.addr, '\n', NULL)) -+ return -EINVAL; -+ } -+ -+ iter_data.net = seq_file_net(seq); -+ iter_data.data = &kr; -+ nf_ct_iterate_cleanup_net(kill_matching, &iter_data); -+ -+ return 0; -+} -+ - static const struct seq_operations ct_cpu_seq_ops = { - .start = ct_cpu_seq_start, - .next = ct_cpu_seq_next, -@@ -478,8 +531,9 @@ static int nf_conntrack_standalone_init_ - kuid_t root_uid; - kgid_t root_gid; - -- pde = proc_create_net("nf_conntrack", 0440, net->proc_net, &ct_seq_ops, -- sizeof(struct ct_iter_state)); -+ pde = proc_create_net_data_write("nf_conntrack", 0440, net->proc_net, -+ &ct_seq_ops, &ct_file_write, -+ sizeof(struct ct_iter_state), NULL); - if (!pde) - goto out_nf_conntrack; - diff --git a/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch deleted file mode 100644 index 0ab89564eeb1d3..00000000000000 --- a/target/linux/generic/pending-6.1/610-netfilter_match_bypass_default_checks.patch +++ /dev/null @@ -1,110 +0,0 @@ -From: Felix Fietkau -Subject: kernel: add a new version of my netfilter speedup patches for linux 2.6.39 and 3.0 - -Signed-off-by: Felix Fietkau ---- - include/uapi/linux/netfilter_ipv4/ip_tables.h | 1 + - net/ipv4/netfilter/ip_tables.c | 37 +++++++++++++++++++++++++++ - 2 files changed, 38 insertions(+) - ---- a/include/uapi/linux/netfilter_ipv4/ip_tables.h -+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h -@@ -89,6 +89,7 @@ struct ipt_ip { - #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ - #define IPT_F_GOTO 0x02 /* Set if jump is a goto */ - #define IPT_F_MASK 0x03 /* All possible flag bits mask. */ -+#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */ - - /* Values for "inv" field in struct ipt_ip. */ - #define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */ ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -50,6 +50,9 @@ ip_packet_match(const struct iphdr *ip, - { - unsigned long ret; - -+ if (ipinfo->flags & IPT_F_NO_DEF_MATCH) -+ return true; -+ - if (NF_INVF(ipinfo, IPT_INV_SRCIP, - (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) || - NF_INVF(ipinfo, IPT_INV_DSTIP, -@@ -80,6 +83,29 @@ ip_packet_match(const struct iphdr *ip, - return true; - } - -+static void -+ip_checkdefault(struct ipt_ip *ip) -+{ -+ static const char iface_mask[IFNAMSIZ] = {}; -+ -+ if (ip->invflags || ip->flags & IPT_F_FRAG) -+ return; -+ -+ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0) -+ return; -+ -+ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0) -+ return; -+ -+ if (ip->smsk.s_addr || ip->dmsk.s_addr) -+ return; -+ -+ if (ip->proto) -+ return; -+ -+ ip->flags |= IPT_F_NO_DEF_MATCH; -+} -+ - static bool - ip_checkentry(const struct ipt_ip *ip) - { -@@ -525,6 +551,8 @@ find_check_entry(struct ipt_entry *e, st - struct xt_mtchk_param mtpar; - struct xt_entry_match *ematch; - -+ ip_checkdefault(&e->ip); -+ - if (!xt_percpu_counter_alloc(alloc_state, &e->counters)) - return -ENOMEM; - -@@ -819,6 +847,7 @@ copy_entries_to_user(unsigned int total_ - const struct xt_table_info *private = table->private; - int ret = 0; - const void *loc_cpu_entry; -+ u8 flags; - - counters = alloc_counters(table); - if (IS_ERR(counters)) -@@ -846,6 +875,14 @@ copy_entries_to_user(unsigned int total_ - goto free_counters; - } - -+ flags = e->ip.flags & IPT_F_MASK; -+ if (copy_to_user(userptr + off -+ + offsetof(struct ipt_entry, ip.flags), -+ &flags, sizeof(flags)) != 0) { -+ ret = -EFAULT; -+ goto free_counters; -+ } -+ - for (i = sizeof(struct ipt_entry); - i < e->target_offset; - i += m->u.match_size) { -@@ -1227,12 +1264,15 @@ compat_copy_entry_to_user(struct ipt_ent - compat_uint_t origsize; - const struct xt_entry_match *ematch; - int ret = 0; -+ u8 flags = e->ip.flags & IPT_F_MASK; - - origsize = *size; - ce = *dstptr; - if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 || - copy_to_user(&ce->counters, &counters[i], -- sizeof(counters[i])) != 0) -+ sizeof(counters[i])) != 0 || -+ copy_to_user(&ce->ip.flags, &flags, -+ sizeof(flags)) != 0) - return -EFAULT; - - *dstptr += sizeof(struct compat_ipt_entry); diff --git a/target/linux/generic/pending-6.1/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/pending-6.1/611-netfilter_match_bypass_default_table.patch deleted file mode 100644 index dd557fd3eaae32..00000000000000 --- a/target/linux/generic/pending-6.1/611-netfilter_match_bypass_default_table.patch +++ /dev/null @@ -1,106 +0,0 @@ -From: Felix Fietkau -Subject: netfilter: match bypass default table - -Signed-off-by: Felix Fietkau ---- - net/ipv4/netfilter/ip_tables.c | 79 +++++++++++++++++++++++++++++++----------- - 1 file changed, 58 insertions(+), 21 deletions(-) - ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -246,6 +246,33 @@ struct ipt_entry *ipt_next_entry(const s - return (void *)entry + entry->next_offset; - } - -+static bool -+ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict) -+{ -+ struct xt_entry_target *t; -+ struct xt_standard_target *st; -+ -+ if (e->target_offset != sizeof(struct ipt_entry)) -+ return false; -+ -+ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH)) -+ return false; -+ -+ t = ipt_get_target(e); -+ if (t->u.kernel.target->target) -+ return false; -+ -+ st = (struct xt_standard_target *) t; -+ if (st->verdict == XT_RETURN) -+ return false; -+ -+ if (st->verdict >= 0) -+ return false; -+ -+ *verdict = (unsigned)(-st->verdict) - 1; -+ return true; -+} -+ - /* Returns one of the generic firewall policies, like NF_ACCEPT. */ - unsigned int - ipt_do_table(void *priv, -@@ -267,27 +294,28 @@ ipt_do_table(void *priv, - unsigned int addend; - - /* Initialization */ -+ WARN_ON(!(table->valid_hooks & (1 << hook))); -+ local_bh_disable(); -+ private = READ_ONCE(table->private); /* Address dependency. */ -+ cpu = smp_processor_id(); -+ table_base = private->entries; -+ -+ e = get_entry(table_base, private->hook_entry[hook]); -+ if (ipt_handle_default_rule(e, &verdict)) { -+ struct xt_counters *counter; -+ -+ counter = xt_get_this_cpu_counter(&e->counters); -+ ADD_COUNTER(*counter, skb->len, 1); -+ local_bh_enable(); -+ return verdict; -+ } -+ - stackidx = 0; - ip = ip_hdr(skb); - indev = state->in ? state->in->name : nulldevname; - outdev = state->out ? state->out->name : nulldevname; -- /* We handle fragments by dealing with the first fragment as -- * if it was a normal packet. All other fragments are treated -- * normally, except that they will NEVER match rules that ask -- * things we don't know, ie. tcp syn flag or ports). If the -- * rule is also a fragment-specific rule, non-fragments won't -- * match it. */ -- acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -- acpar.thoff = ip_hdrlen(skb); -- acpar.hotdrop = false; -- acpar.state = state; - -- WARN_ON(!(table->valid_hooks & (1 << hook))); -- local_bh_disable(); - addend = xt_write_recseq_begin(); -- private = READ_ONCE(table->private); /* Address dependency. */ -- cpu = smp_processor_id(); -- table_base = private->entries; - jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; - - /* Switch to alternate jumpstack if we're being invoked via TEE. -@@ -300,7 +328,16 @@ ipt_do_table(void *priv, - if (static_key_false(&xt_tee_enabled)) - jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated); - -- e = get_entry(table_base, private->hook_entry[hook]); -+ /* We handle fragments by dealing with the first fragment as -+ * if it was a normal packet. All other fragments are treated -+ * normally, except that they will NEVER match rules that ask -+ * things we don't know, ie. tcp syn flag or ports). If the -+ * rule is also a fragment-specific rule, non-fragments won't -+ * match it. */ -+ acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -+ acpar.thoff = ip_hdrlen(skb); -+ acpar.hotdrop = false; -+ acpar.state = state; - - do { - const struct xt_entry_target *t; diff --git a/target/linux/generic/pending-6.1/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/pending-6.1/612-netfilter_match_reduce_memory_access.patch deleted file mode 100644 index 79da6778b684a5..00000000000000 --- a/target/linux/generic/pending-6.1/612-netfilter_match_reduce_memory_access.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Subject: netfilter: reduce match memory access - -Signed-off-by: Felix Fietkau ---- - net/ipv4/netfilter/ip_tables.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/net/ipv4/netfilter/ip_tables.c -+++ b/net/ipv4/netfilter/ip_tables.c -@@ -53,9 +53,9 @@ ip_packet_match(const struct iphdr *ip, - if (ipinfo->flags & IPT_F_NO_DEF_MATCH) - return true; - -- if (NF_INVF(ipinfo, IPT_INV_SRCIP, -+ if (NF_INVF(ipinfo, IPT_INV_SRCIP, ipinfo->smsk.s_addr && - (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) || -- NF_INVF(ipinfo, IPT_INV_DSTIP, -+ NF_INVF(ipinfo, IPT_INV_DSTIP, ipinfo->dmsk.s_addr && - (ip->daddr & ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr)) - return false; - diff --git a/target/linux/generic/pending-6.1/620-net_sched-codel-do-not-defer-queue-length-update.patch b/target/linux/generic/pending-6.1/620-net_sched-codel-do-not-defer-queue-length-update.patch deleted file mode 100644 index 4b4825ae3b9a4a..00000000000000 --- a/target/linux/generic/pending-6.1/620-net_sched-codel-do-not-defer-queue-length-update.patch +++ /dev/null @@ -1,86 +0,0 @@ -From: Konstantin Khlebnikov -Date: Mon, 21 Aug 2017 11:14:14 +0300 -Subject: [PATCH] net_sched/codel: do not defer queue length update - -When codel wants to drop last packet in ->dequeue() it cannot call -qdisc_tree_reduce_backlog() right away - it will notify parent qdisc -about zero qlen and HTB/HFSC will deactivate class. The same class will -be deactivated second time by caller of ->dequeue(). Currently codel and -fq_codel defer update. This triggers warning in HFSC when it's qlen != 0 -but there is no active classes. - -This patch update parent queue length immediately: just temporary increase -qlen around qdisc_tree_reduce_backlog() to prevent first class deactivation -if we have skb to return. - -This might open another problem in HFSC - now operation peek could fail and -deactivate parent class. - -Signed-off-by: Konstantin Khlebnikov -Link: https://bugzilla.kernel.org/show_bug.cgi?id=109581 ---- - ---- a/net/sched/sch_codel.c -+++ b/net/sched/sch_codel.c -@@ -95,11 +95,17 @@ static struct sk_buff *codel_qdisc_deque - &q->stats, qdisc_pkt_len, codel_get_enqueue_time, - drop_func, dequeue_func); - -- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0, -- * or HTB crashes. Defer it for next round. -+ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate -+ * parent class, dequeue in parent qdisc will do the same if we -+ * return skb. Temporary increment qlen if we have skb. - */ -- if (q->stats.drop_count && sch->q.qlen) { -- qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len); -+ if (q->stats.drop_count) { -+ if (skb) -+ sch->q.qlen++; -+ qdisc_tree_reduce_backlog(sch, q->stats.drop_count, -+ q->stats.drop_len); -+ if (skb) -+ sch->q.qlen--; - q->stats.drop_count = 0; - q->stats.drop_len = 0; - } ---- a/net/sched/sch_fq_codel.c -+++ b/net/sched/sch_fq_codel.c -@@ -304,6 +304,21 @@ begin: - &flow->cvars, &q->cstats, qdisc_pkt_len, - codel_get_enqueue_time, drop_func, dequeue_func); - -+ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate -+ * parent class, dequeue in parent qdisc will do the same if we -+ * return skb. Temporary increment qlen if we have skb. -+ */ -+ if (q->cstats.drop_count) { -+ if (skb) -+ sch->q.qlen++; -+ qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, -+ q->cstats.drop_len); -+ if (skb) -+ sch->q.qlen--; -+ q->cstats.drop_count = 0; -+ q->cstats.drop_len = 0; -+ } -+ - if (!skb) { - /* force a pass through old_flows to prevent starvation */ - if ((head == &q->new_flows) && !list_empty(&q->old_flows)) -@@ -314,15 +329,6 @@ begin: - } - qdisc_bstats_update(sch, skb); - flow->deficit -= qdisc_pkt_len(skb); -- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0, -- * or HTB crashes. Defer it for next round. -- */ -- if (q->cstats.drop_count && sch->q.qlen) { -- qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, -- q->cstats.drop_len); -- q->cstats.drop_count = 0; -- q->cstats.drop_len = 0; -- } - return skb; - } - diff --git a/target/linux/generic/pending-6.1/630-packet_socket_type.patch b/target/linux/generic/pending-6.1/630-packet_socket_type.patch deleted file mode 100644 index 5553fba94b4075..00000000000000 --- a/target/linux/generic/pending-6.1/630-packet_socket_type.patch +++ /dev/null @@ -1,138 +0,0 @@ -From: Felix Fietkau -Subject: net: add an optimization for dealing with raw sockets - -lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6 -Signed-off-by: Felix Fietkau ---- - include/uapi/linux/if_packet.h | 3 +++ - net/packet/af_packet.c | 34 +++++++++++++++++++++++++++------- - net/packet/internal.h | 1 + - 3 files changed, 31 insertions(+), 7 deletions(-) - ---- a/include/uapi/linux/if_packet.h -+++ b/include/uapi/linux/if_packet.h -@@ -33,6 +33,8 @@ struct sockaddr_ll { - #define PACKET_KERNEL 7 /* To kernel space */ - /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */ - #define PACKET_FASTROUTE 6 /* Fastrouted frame */ -+#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */ -+ - - /* Packet socket options */ - -@@ -59,6 +61,7 @@ struct sockaddr_ll { - #define PACKET_ROLLOVER_STATS 21 - #define PACKET_FANOUT_DATA 22 - #define PACKET_IGNORE_OUTGOING 23 -+#define PACKET_RECV_TYPE 24 - - #define PACKET_FANOUT_HASH 0 - #define PACKET_FANOUT_LB 1 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -1927,6 +1927,7 @@ static int packet_rcv_spkt(struct sk_buf - { - struct sock *sk; - struct sockaddr_pkt *spkt; -+ struct packet_sock *po; - - /* - * When we registered the protocol we saved the socket in the data -@@ -1934,6 +1935,7 @@ static int packet_rcv_spkt(struct sk_buf - */ - - sk = pt->af_packet_priv; -+ po = pkt_sk(sk); - - /* - * Yank back the headers [hope the device set this -@@ -1946,7 +1948,7 @@ static int packet_rcv_spkt(struct sk_buf - * so that this procedure is noop. - */ - -- if (skb->pkt_type == PACKET_LOOPBACK) -+ if (!(po->pkt_type & (1 << skb->pkt_type))) - goto out; - - if (!net_eq(dev_net(dev), sock_net(sk))) -@@ -2192,12 +2194,12 @@ static int packet_rcv(struct sk_buff *sk - unsigned int snaplen, res; - bool is_drop_n_account = false; - -- if (skb->pkt_type == PACKET_LOOPBACK) -- goto drop; -- - sk = pt->af_packet_priv; - po = pkt_sk(sk); - -+ if (!(po->pkt_type & (1 << skb->pkt_type))) -+ goto drop; -+ - if (!net_eq(dev_net(dev), sock_net(sk))) - goto drop; - -@@ -2324,12 +2326,12 @@ static int tpacket_rcv(struct sk_buff *s - BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32); - BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48); - -- if (skb->pkt_type == PACKET_LOOPBACK) -- goto drop; -- - sk = pt->af_packet_priv; - po = pkt_sk(sk); - -+ if (!(po->pkt_type & (1 << skb->pkt_type))) -+ goto drop; -+ - if (!net_eq(dev_net(dev), sock_net(sk))) - goto drop; - -@@ -3443,6 +3445,7 @@ static int packet_create(struct net *net - mutex_init(&po->pg_vec_lock); - po->rollover = NULL; - po->prot_hook.func = packet_rcv; -+ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK); - - if (sock->type == SOCK_PACKET) - po->prot_hook.func = packet_rcv_spkt; -@@ -4096,6 +4099,16 @@ packet_setsockopt(struct socket *sock, i - WRITE_ONCE(po->xmit, val ? packet_direct_xmit : dev_queue_xmit); - return 0; - } -+ case PACKET_RECV_TYPE: -+ { -+ unsigned int val; -+ if (optlen != sizeof(val)) -+ return -EINVAL; -+ if (copy_from_sockptr(&val, optval, sizeof(val))) -+ return -EFAULT; -+ po->pkt_type = val & ~BIT(PACKET_LOOPBACK); -+ return 0; -+ } - default: - return -ENOPROTOOPT; - } -@@ -4152,6 +4165,13 @@ static int packet_getsockopt(struct sock - case PACKET_VNET_HDR: - val = po->has_vnet_hdr; - break; -+ case PACKET_RECV_TYPE: -+ if (len > sizeof(unsigned int)) -+ len = sizeof(unsigned int); -+ val = po->pkt_type; -+ -+ data = &val; -+ break; - case PACKET_VERSION: - val = po->tp_version; - break; ---- a/net/packet/internal.h -+++ b/net/packet/internal.h -@@ -136,6 +136,7 @@ struct packet_sock { - int (*xmit)(struct sk_buff *skb); - struct packet_type prot_hook ____cacheline_aligned_in_smp; - atomic_t tp_drops ____cacheline_aligned_in_smp; -+ unsigned int pkt_type; - }; - - static inline struct packet_sock *pkt_sk(struct sock *sk) diff --git a/target/linux/generic/pending-6.1/655-increase_skb_pad.patch b/target/linux/generic/pending-6.1/655-increase_skb_pad.patch deleted file mode 100644 index 22c479311a496b..00000000000000 --- a/target/linux/generic/pending-6.1/655-increase_skb_pad.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Felix Fietkau -Subject: kernel: add a few patches for avoiding unnecessary skb reallocations - significantly improves ethernet<->wireless performance - -lede-commit: 6f89cffc9add6939d44a6b54cf9a5e77849aa7fd -Signed-off-by: Felix Fietkau ---- - include/linux/skbuff.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -3038,7 +3038,7 @@ static inline int pskb_network_may_pull( - * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) - */ - #ifndef NET_SKB_PAD --#define NET_SKB_PAD max(32, L1_CACHE_BYTES) -+#define NET_SKB_PAD max(64, L1_CACHE_BYTES) - #endif - - int ___pskb_trim(struct sk_buff *skb, unsigned int len); diff --git a/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch deleted file mode 100644 index a2f88d79e633ff..00000000000000 --- a/target/linux/generic/pending-6.1/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch +++ /dev/null @@ -1,511 +0,0 @@ -From: Steven Barth -Subject: Add support for MAP-E FMRs (mesh mode) - -MAP-E FMRs (draft-ietf-softwire-map-10) are rules for IPv4-communication -between MAP CEs (mesh mode) without the need to forward such data to a -border relay. This is similar to how 6rd works but for IPv4 over IPv6. - -Signed-off-by: Steven Barth ---- - include/net/ip6_tunnel.h | 13 ++ - include/uapi/linux/if_tunnel.h | 13 ++ - net/ipv6/ip6_tunnel.c | 276 +++++++++++++++++++++++++++++++++++++++-- - 3 files changed, 291 insertions(+), 11 deletions(-) - ---- a/include/net/ip6_tunnel.h -+++ b/include/net/ip6_tunnel.h -@@ -18,6 +18,18 @@ - /* determine capability on a per-packet basis */ - #define IP6_TNL_F_CAP_PER_PACKET 0x40000 - -+/* IPv6 tunnel FMR */ -+struct __ip6_tnl_fmr { -+ struct __ip6_tnl_fmr *next; /* next fmr in list */ -+ struct in6_addr ip6_prefix; -+ struct in_addr ip4_prefix; -+ -+ __u8 ip6_prefix_len; -+ __u8 ip4_prefix_len; -+ __u8 ea_len; -+ __u8 offset; -+}; -+ - struct __ip6_tnl_parm { - char name[IFNAMSIZ]; /* name of tunnel device */ - int link; /* ifindex of underlying L2 interface */ -@@ -29,6 +41,7 @@ struct __ip6_tnl_parm { - __u32 flags; /* tunnel flags */ - struct in6_addr laddr; /* local tunnel end-point address */ - struct in6_addr raddr; /* remote tunnel end-point address */ -+ struct __ip6_tnl_fmr *fmrs; /* FMRs */ - - __be16 i_flags; - __be16 o_flags; ---- a/include/uapi/linux/if_tunnel.h -+++ b/include/uapi/linux/if_tunnel.h -@@ -77,10 +77,23 @@ enum { - IFLA_IPTUN_ENCAP_DPORT, - IFLA_IPTUN_COLLECT_METADATA, - IFLA_IPTUN_FWMARK, -+ IFLA_IPTUN_FMRS, - __IFLA_IPTUN_MAX, - }; - #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) - -+enum { -+ IFLA_IPTUN_FMR_UNSPEC, -+ IFLA_IPTUN_FMR_IP6_PREFIX, -+ IFLA_IPTUN_FMR_IP4_PREFIX, -+ IFLA_IPTUN_FMR_IP6_PREFIX_LEN, -+ IFLA_IPTUN_FMR_IP4_PREFIX_LEN, -+ IFLA_IPTUN_FMR_EA_LEN, -+ IFLA_IPTUN_FMR_OFFSET, -+ __IFLA_IPTUN_FMR_MAX, -+}; -+#define IFLA_IPTUN_FMR_MAX (__IFLA_IPTUN_FMR_MAX - 1) -+ - enum tunnel_encap_types { - TUNNEL_ENCAP_NONE, - TUNNEL_ENCAP_FOU, ---- a/net/ipv6/ip6_tunnel.c -+++ b/net/ipv6/ip6_tunnel.c -@@ -11,6 +11,9 @@ - * linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c - * - * RFC 2473 -+ * -+ * Changes: -+ * Steven Barth : MAP-E FMR support - */ - - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -@@ -67,9 +70,9 @@ static bool log_ecn_error = true; - module_param(log_ecn_error, bool, 0644); - MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); - --static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) -+static u32 HASH(const struct in6_addr *addr) - { -- u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2); -+ u32 hash = ipv6_addr_hash(addr); - - return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT); - } -@@ -114,17 +117,33 @@ static struct ip6_tnl * - ip6_tnl_lookup(struct net *net, int link, - const struct in6_addr *remote, const struct in6_addr *local) - { -- unsigned int hash = HASH(remote, local); -+ unsigned int hash = HASH(local); - struct ip6_tnl *t, *cand = NULL; - struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - struct in6_addr any; - - for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { - if (!ipv6_addr_equal(local, &t->parms.laddr) || -- !ipv6_addr_equal(remote, &t->parms.raddr) || - !(t->dev->flags & IFF_UP)) - continue; - -+ if (!ipv6_addr_equal(remote, &t->parms.raddr)) { -+ struct __ip6_tnl_fmr *fmr; -+ bool found = false; -+ -+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { -+ if (!ipv6_prefix_equal(remote, &fmr->ip6_prefix, -+ fmr->ip6_prefix_len)) -+ continue; -+ -+ found = true; -+ break; -+ } -+ -+ if (!found) -+ continue; -+ } -+ - if (link == t->parms.link) - return t; - else -@@ -132,7 +151,7 @@ ip6_tnl_lookup(struct net *net, int link - } - - memset(&any, 0, sizeof(any)); -- hash = HASH(&any, local); -+ hash = HASH(local); - for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { - if (!ipv6_addr_equal(local, &t->parms.laddr) || - !ipv6_addr_any(&t->parms.raddr) || -@@ -145,7 +164,7 @@ ip6_tnl_lookup(struct net *net, int link - cand = t; - } - -- hash = HASH(remote, &any); -+ hash = HASH(&any); - for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { - if (!ipv6_addr_equal(remote, &t->parms.raddr) || - !ipv6_addr_any(&t->parms.laddr) || -@@ -194,7 +213,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, - - if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) { - prio = 1; -- h = HASH(remote, local); -+ h = HASH(local); - } - return &ip6n->tnls[prio][h]; - } -@@ -376,6 +395,12 @@ ip6_tnl_dev_uninit(struct net_device *de - struct net *net = t->net; - struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - -+ while (t->parms.fmrs) { -+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; -+ kfree(t->parms.fmrs); -+ t->parms.fmrs = next; -+ } -+ - if (dev == ip6n->fb_tnl_dev) - RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL); - else -@@ -788,6 +813,107 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t, - } - EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl); - -+/** -+ * ip4ip6_fmr_calc - calculate target / source IPv6-address based on FMR -+ * @dest: destination IPv6 address buffer -+ * @skb: received socket buffer -+ * @fmr: MAP FMR -+ * @xmit: Calculate for xmit or rcv -+ **/ -+static void ip4ip6_fmr_calc(struct in6_addr *dest, -+ const struct iphdr *iph, const uint8_t *end, -+ const struct __ip6_tnl_fmr *fmr, bool xmit) -+{ -+ int psidlen = fmr->ea_len - (32 - fmr->ip4_prefix_len); -+ u8 *portp = NULL; -+ bool use_dest_addr; -+ const struct iphdr *dsth = iph; -+ -+ if ((u8*)dsth >= end) -+ return; -+ -+ /* find significant IP header */ -+ if (iph->protocol == IPPROTO_ICMP) { -+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); -+ if (ih && ((u8*)&ih[1]) <= end && ( -+ ih->type == ICMP_DEST_UNREACH || -+ ih->type == ICMP_SOURCE_QUENCH || -+ ih->type == ICMP_TIME_EXCEEDED || -+ ih->type == ICMP_PARAMETERPROB || -+ ih->type == ICMP_REDIRECT)) -+ dsth = (const struct iphdr*)&ih[1]; -+ } -+ -+ /* in xmit-path use dest port by default and source port only if -+ this is an ICMP reply to something else; vice versa in rcv-path */ -+ use_dest_addr = (xmit && dsth == iph) || (!xmit && dsth != iph); -+ -+ /* get dst port */ -+ if (((u8*)&dsth[1]) <= end && ( -+ dsth->protocol == IPPROTO_UDP || -+ dsth->protocol == IPPROTO_TCP || -+ dsth->protocol == IPPROTO_SCTP || -+ dsth->protocol == IPPROTO_DCCP)) { -+ /* for UDP, TCP, SCTP and DCCP source and dest port -+ follow IPv4 header directly */ -+ portp = ((u8*)dsth) + dsth->ihl * 4; -+ -+ if (use_dest_addr) -+ portp += sizeof(u16); -+ } else if (iph->protocol == IPPROTO_ICMP) { -+ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); -+ -+ /* use icmp identifier as port */ -+ if (((u8*)&ih) <= end && ( -+ (use_dest_addr && ( -+ ih->type == ICMP_ECHOREPLY || -+ ih->type == ICMP_TIMESTAMPREPLY || -+ ih->type == ICMP_INFO_REPLY || -+ ih->type == ICMP_ADDRESSREPLY)) || -+ (!use_dest_addr && ( -+ ih->type == ICMP_ECHO || -+ ih->type == ICMP_TIMESTAMP || -+ ih->type == ICMP_INFO_REQUEST || -+ ih->type == ICMP_ADDRESS) -+ ))) -+ portp = (u8*)&ih->un.echo.id; -+ } -+ -+ if ((portp && &portp[2] <= end) || psidlen == 0) { -+ int frombyte = fmr->ip6_prefix_len / 8; -+ int fromrem = fmr->ip6_prefix_len % 8; -+ int bytes = sizeof(struct in6_addr) - frombyte; -+ const u32 *addr = (use_dest_addr) ? &iph->daddr : &iph->saddr; -+ u64 eabits = ((u64)ntohl(*addr)) << (32 + fmr->ip4_prefix_len); -+ u64 t = 0; -+ -+ /* extract PSID from port and add it to eabits */ -+ u16 psidbits = 0; -+ if (psidlen > 0) { -+ psidbits = ((u16)portp[0]) << 8 | ((u16)portp[1]); -+ psidbits >>= 16 - psidlen - fmr->offset; -+ psidbits = (u16)(psidbits << (16 - psidlen)); -+ eabits |= ((u64)psidbits) << (48 - (fmr->ea_len - psidlen)); -+ } -+ -+ /* rewrite destination address */ -+ *dest = fmr->ip6_prefix; -+ memcpy(&dest->s6_addr[10], addr, sizeof(*addr)); -+ dest->s6_addr16[7] = htons(psidbits >> (16 - psidlen)); -+ -+ if (bytes > sizeof(u64)) -+ bytes = sizeof(u64); -+ -+ /* insert eabits */ -+ memcpy(&t, &dest->s6_addr[frombyte], bytes); -+ t = be64_to_cpu(t) & ~(((((u64)1) << fmr->ea_len) - 1) -+ << (64 - fmr->ea_len - fromrem)); -+ t = cpu_to_be64(t | (eabits >> fromrem)); -+ memcpy(&dest->s6_addr[frombyte], &t, bytes); -+ } -+} -+ -+ - static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, - const struct tnl_ptk_info *tpi, - struct metadata_dst *tun_dst, -@@ -855,6 +981,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl - - memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); - -+ if (tpi->proto == htons(ETH_P_IP) && tunnel->parms.fmrs && -+ !ipv6_addr_equal(&ipv6h->saddr, &tunnel->parms.raddr)) { -+ /* Packet didn't come from BR, so lookup FMR */ -+ struct __ip6_tnl_fmr *fmr; -+ struct in6_addr expected = tunnel->parms.raddr; -+ for (fmr = tunnel->parms.fmrs; fmr; fmr = fmr->next) -+ if (ipv6_prefix_equal(&ipv6h->saddr, -+ &fmr->ip6_prefix, fmr->ip6_prefix_len)) -+ break; -+ -+ /* Check that IPv6 matches IPv4 source to prevent spoofing */ -+ if (fmr) -+ ip4ip6_fmr_calc(&expected, ip_hdr(skb), -+ skb_tail_pointer(skb), fmr, false); -+ -+ if (!ipv6_addr_equal(&ipv6h->saddr, &expected)) { -+ rcu_read_unlock(); -+ goto drop; -+ } -+ } -+ - __skb_tunnel_rx(skb, tunnel->dev, tunnel->net); - - err = dscp_ecn_decapsulate(tunnel, ipv6h, skb); -@@ -1002,6 +1149,7 @@ static void init_tel_txopt(struct ipv6_t - opt->ops.opt_nflen = 8; - } - -+ - /** - * ip6_tnl_addr_conflict - compare packet addresses to tunnel's own - * @t: the outgoing tunnel device -@@ -1293,6 +1441,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str - u8 protocol) - { - struct ip6_tnl *t = netdev_priv(dev); -+ struct __ip6_tnl_fmr *fmr; - struct ipv6hdr *ipv6h; - const struct iphdr *iph; - int encap_limit = -1; -@@ -1392,6 +1541,18 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str - fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); - dsfield = INET_ECN_encapsulate(dsfield, orig_dsfield); - -+ /* try to find matching FMR */ -+ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { -+ unsigned mshift = 32 - fmr->ip4_prefix_len; -+ if (ntohl(fmr->ip4_prefix.s_addr) >> mshift == -+ ntohl(ip_hdr(skb)->daddr) >> mshift) -+ break; -+ } -+ -+ /* change dstaddr according to FMR */ -+ if (fmr) -+ ip4ip6_fmr_calc(&fl6.daddr, ip_hdr(skb), skb_tail_pointer(skb), fmr, true); -+ - if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) - return -1; - -@@ -1546,6 +1707,14 @@ ip6_tnl_change(struct ip6_tnl *t, const - t->parms.link = p->link; - t->parms.proto = p->proto; - t->parms.fwmark = p->fwmark; -+ -+ while (t->parms.fmrs) { -+ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; -+ kfree(t->parms.fmrs); -+ t->parms.fmrs = next; -+ } -+ t->parms.fmrs = p->fmrs; -+ - dst_cache_reset(&t->dst_cache); - ip6_tnl_link_config(t); - } -@@ -1580,6 +1749,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_ - p->flowinfo = u->flowinfo; - p->link = u->link; - p->proto = u->proto; -+ p->fmrs = NULL; - memcpy(p->name, u->name, sizeof(u->name)); - } - -@@ -1967,6 +2137,15 @@ static int ip6_tnl_validate(struct nlatt - return 0; - } - -+static const struct nla_policy ip6_tnl_fmr_policy[IFLA_IPTUN_FMR_MAX + 1] = { -+ [IFLA_IPTUN_FMR_IP6_PREFIX] = { .len = sizeof(struct in6_addr) }, -+ [IFLA_IPTUN_FMR_IP4_PREFIX] = { .len = sizeof(struct in_addr) }, -+ [IFLA_IPTUN_FMR_IP6_PREFIX_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_IP4_PREFIX_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_EA_LEN] = { .type = NLA_U8 }, -+ [IFLA_IPTUN_FMR_OFFSET] = { .type = NLA_U8 } -+}; -+ - static void ip6_tnl_netlink_parms(struct nlattr *data[], - struct __ip6_tnl_parm *parms) - { -@@ -2004,6 +2183,46 @@ static void ip6_tnl_netlink_parms(struct - - if (data[IFLA_IPTUN_FWMARK]) - parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]); -+ -+ if (data[IFLA_IPTUN_FMRS]) { -+ unsigned rem; -+ struct nlattr *fmr; -+ nla_for_each_nested(fmr, data[IFLA_IPTUN_FMRS], rem) { -+ struct nlattr *fmrd[IFLA_IPTUN_FMR_MAX + 1], *c; -+ struct __ip6_tnl_fmr *nfmr; -+ -+ nla_parse_nested(fmrd, IFLA_IPTUN_FMR_MAX, -+ fmr, ip6_tnl_fmr_policy, NULL); -+ -+ if (!(nfmr = kzalloc(sizeof(*nfmr), GFP_KERNEL))) -+ continue; -+ -+ nfmr->offset = 6; -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX])) -+ nla_memcpy(&nfmr->ip6_prefix, fmrd[IFLA_IPTUN_FMR_IP6_PREFIX], -+ sizeof(nfmr->ip6_prefix)); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX])) -+ nla_memcpy(&nfmr->ip4_prefix, fmrd[IFLA_IPTUN_FMR_IP4_PREFIX], -+ sizeof(nfmr->ip4_prefix)); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX_LEN])) -+ nfmr->ip6_prefix_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX_LEN])) -+ nfmr->ip4_prefix_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_EA_LEN])) -+ nfmr->ea_len = nla_get_u8(c); -+ -+ if ((c = fmrd[IFLA_IPTUN_FMR_OFFSET])) -+ nfmr->offset = nla_get_u8(c); -+ -+ nfmr->next = parms->fmrs; -+ parms->fmrs = nfmr; -+ } -+ } - } - - static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev, -@@ -2087,6 +2306,12 @@ static void ip6_tnl_dellink(struct net_d - - static size_t ip6_tnl_get_size(const struct net_device *dev) - { -+ const struct ip6_tnl *t = netdev_priv(dev); -+ struct __ip6_tnl_fmr *c; -+ int fmrs = 0; -+ for (c = t->parms.fmrs; c; c = c->next) -+ ++fmrs; -+ - return - /* IFLA_IPTUN_LINK */ - nla_total_size(4) + -@@ -2116,6 +2341,24 @@ static size_t ip6_tnl_get_size(const str - nla_total_size(0) + - /* IFLA_IPTUN_FWMARK */ - nla_total_size(4) + -+ /* IFLA_IPTUN_FMRS */ -+ nla_total_size(0) + -+ ( -+ /* nest */ -+ nla_total_size(0) + -+ /* IFLA_IPTUN_FMR_IP6_PREFIX */ -+ nla_total_size(sizeof(struct in6_addr)) + -+ /* IFLA_IPTUN_FMR_IP4_PREFIX */ -+ nla_total_size(sizeof(struct in_addr)) + -+ /* IFLA_IPTUN_FMR_EA_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_IP6_PREFIX_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_IP4_PREFIX_LEN */ -+ nla_total_size(1) + -+ /* IFLA_IPTUN_FMR_OFFSET */ -+ nla_total_size(1) -+ ) * fmrs + - 0; - } - -@@ -2123,6 +2366,9 @@ static int ip6_tnl_fill_info(struct sk_b - { - struct ip6_tnl *tunnel = netdev_priv(dev); - struct __ip6_tnl_parm *parm = &tunnel->parms; -+ struct __ip6_tnl_fmr *c; -+ int fmrcnt = 0; -+ struct nlattr *fmrs; - - if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || - nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) || -@@ -2132,9 +2378,27 @@ static int ip6_tnl_fill_info(struct sk_b - nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || - nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) || - nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) || -- nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark)) -+ nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark) || -+ !(fmrs = nla_nest_start(skb, IFLA_IPTUN_FMRS))) - goto nla_put_failure; - -+ for (c = parm->fmrs; c; c = c->next) { -+ struct nlattr *fmr = nla_nest_start(skb, ++fmrcnt); -+ if (!fmr || -+ nla_put(skb, IFLA_IPTUN_FMR_IP6_PREFIX, -+ sizeof(c->ip6_prefix), &c->ip6_prefix) || -+ nla_put(skb, IFLA_IPTUN_FMR_IP4_PREFIX, -+ sizeof(c->ip4_prefix), &c->ip4_prefix) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, c->ip6_prefix_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, c->ip4_prefix_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_EA_LEN, c->ea_len) || -+ nla_put_u8(skb, IFLA_IPTUN_FMR_OFFSET, c->offset)) -+ goto nla_put_failure; -+ -+ nla_nest_end(skb, fmr); -+ } -+ nla_nest_end(skb, fmrs); -+ - if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) || - nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) || - nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) || -@@ -2174,6 +2438,7 @@ static const struct nla_policy ip6_tnl_p - [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 }, - [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG }, - [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 }, -+ [IFLA_IPTUN_FMRS] = { .type = NLA_NESTED }, - }; - - static struct rtnl_link_ops ip6_link_ops __read_mostly = { diff --git a/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch deleted file mode 100644 index 1d16b81543b7e3..00000000000000 --- a/target/linux/generic/pending-6.1/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch +++ /dev/null @@ -1,263 +0,0 @@ -From: Jonas Gorski -Subject: ipv6: allow rejecting with "source address failed policy" - -RFC6204 L-14 requires rejecting traffic from invalid addresses with -ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/ -egress policy) on the LAN side, so add an appropriate rule for that. - -Signed-off-by: Jonas Gorski ---- - include/net/netns/ipv6.h | 1 + - include/uapi/linux/fib_rules.h | 4 +++ - include/uapi/linux/rtnetlink.h | 1 + - net/ipv4/fib_semantics.c | 4 +++ - net/ipv4/fib_trie.c | 1 + - net/ipv4/ipmr.c | 1 + - net/ipv6/fib6_rules.c | 4 +++ - net/ipv6/ip6mr.c | 2 ++ - net/ipv6/route.c | 58 +++++++++++++++++++++++++++++++++++++++++- - 9 files changed, 75 insertions(+), 1 deletion(-) - ---- a/include/net/netns/ipv6.h -+++ b/include/net/netns/ipv6.h -@@ -85,6 +85,7 @@ struct netns_ipv6 { - unsigned int fib6_routes_require_src; - #endif - struct rt6_info *ip6_prohibit_entry; -+ struct rt6_info *ip6_policy_failed_entry; - struct rt6_info *ip6_blk_hole_entry; - struct fib6_table *fib6_local_tbl; - struct fib_rules_ops *fib6_rules_ops; ---- a/include/uapi/linux/fib_rules.h -+++ b/include/uapi/linux/fib_rules.h -@@ -82,6 +82,10 @@ enum { - FR_ACT_BLACKHOLE, /* Drop without notification */ - FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ - FR_ACT_PROHIBIT, /* Drop with EACCES */ -+ FR_ACT_RES9, -+ FR_ACT_RES10, -+ FR_ACT_RES11, -+ FR_ACT_POLICY_FAILED, /* Drop with EACCES */ - __FR_ACT_MAX, - }; - ---- a/include/uapi/linux/rtnetlink.h -+++ b/include/uapi/linux/rtnetlink.h -@@ -265,6 +265,7 @@ enum { - RTN_THROW, /* Not in this table */ - RTN_NAT, /* Translate this address */ - RTN_XRESOLVE, /* Use external resolver */ -+ RTN_POLICY_FAILED, /* Failed ingress/egress policy */ - __RTN_MAX - }; - ---- a/net/ipv4/fib_semantics.c -+++ b/net/ipv4/fib_semantics.c -@@ -145,6 +145,10 @@ const struct fib_prop fib_props[RTN_MAX - .error = -EINVAL, - .scope = RT_SCOPE_NOWHERE, - }, -+ [RTN_POLICY_FAILED] = { -+ .error = -EACCES, -+ .scope = RT_SCOPE_UNIVERSE, -+ }, - }; - - static void rt_fibinfo_free(struct rtable __rcu **rtp) ---- a/net/ipv4/fib_trie.c -+++ b/net/ipv4/fib_trie.c -@@ -2784,6 +2784,7 @@ static const char *const rtn_type_names[ - [RTN_THROW] = "THROW", - [RTN_NAT] = "NAT", - [RTN_XRESOLVE] = "XRESOLVE", -+ [RTN_POLICY_FAILED] = "POLICY_FAILED", - }; - - static inline const char *rtn_type(char *buf, size_t len, unsigned int t) ---- a/net/ipv4/ipmr.c -+++ b/net/ipv4/ipmr.c -@@ -180,6 +180,7 @@ static int ipmr_rule_action(struct fib_r - case FR_ACT_UNREACHABLE: - return -ENETUNREACH; - case FR_ACT_PROHIBIT: -+ case FR_ACT_POLICY_FAILED: - return -EACCES; - case FR_ACT_BLACKHOLE: - default: ---- a/net/ipv6/fib6_rules.c -+++ b/net/ipv6/fib6_rules.c -@@ -221,6 +221,10 @@ static int __fib6_rule_action(struct fib - err = -EACCES; - rt = net->ipv6.ip6_prohibit_entry; - goto discard_pkt; -+ case FR_ACT_POLICY_FAILED: -+ err = -EACCES; -+ rt = net->ipv6.ip6_policy_failed_entry; -+ goto discard_pkt; - } - - tb_id = fib_rule_get_table(rule, arg); ---- a/net/ipv6/ip6mr.c -+++ b/net/ipv6/ip6mr.c -@@ -170,6 +170,8 @@ static int ip6mr_rule_action(struct fib_ - return -ENETUNREACH; - case FR_ACT_PROHIBIT: - return -EACCES; -+ case FR_ACT_POLICY_FAILED: -+ return -EACCES; - case FR_ACT_BLACKHOLE: - default: - return -EINVAL; ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -98,6 +98,8 @@ static int ip6_pkt_discard(struct sk_bu - static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); - static int ip6_pkt_prohibit(struct sk_buff *skb); - static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); -+static int ip6_pkt_policy_failed(struct sk_buff *skb); -+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb); - static void ip6_link_failure(struct sk_buff *skb); - static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, - struct sk_buff *skb, u32 mtu, -@@ -318,6 +320,18 @@ static const struct rt6_info ip6_prohibi - .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), - }; - -+static const struct rt6_info ip6_policy_failed_entry_template = { -+ .dst = { -+ .__refcnt = ATOMIC_INIT(1), -+ .__use = 1, -+ .obsolete = DST_OBSOLETE_FORCE_CHK, -+ .error = -EACCES, -+ .input = ip6_pkt_policy_failed, -+ .output = ip6_pkt_policy_failed_out, -+ }, -+ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), -+}; -+ - static const struct rt6_info ip6_blk_hole_entry_template = { - .dst = { - .__refcnt = ATOMIC_INIT(1), -@@ -1042,6 +1056,7 @@ static const int fib6_prop[RTN_MAX + 1] - [RTN_BLACKHOLE] = -EINVAL, - [RTN_UNREACHABLE] = -EHOSTUNREACH, - [RTN_PROHIBIT] = -EACCES, -+ [RTN_POLICY_FAILED] = -EACCES, - [RTN_THROW] = -EAGAIN, - [RTN_NAT] = -EINVAL, - [RTN_XRESOLVE] = -EINVAL, -@@ -1077,6 +1092,10 @@ static void ip6_rt_init_dst_reject(struc - rt->dst.output = ip6_pkt_prohibit_out; - rt->dst.input = ip6_pkt_prohibit; - break; -+ case RTN_POLICY_FAILED: -+ rt->dst.output = ip6_pkt_policy_failed_out; -+ rt->dst.input = ip6_pkt_policy_failed; -+ break; - case RTN_THROW: - case RTN_UNREACHABLE: - default: -@@ -4547,6 +4566,17 @@ static int ip6_pkt_prohibit_out(struct n - return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); - } - -+static int ip6_pkt_policy_failed(struct sk_buff *skb) -+{ -+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES); -+} -+ -+static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb) -+{ -+ skb->dev = skb_dst(skb)->dev; -+ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES); -+} -+ - /* - * Allocate a dst for local (unicast / anycast) address. - */ -@@ -5040,7 +5070,8 @@ static int rtm_to_fib6_config(struct sk_ - if (rtm->rtm_type == RTN_UNREACHABLE || - rtm->rtm_type == RTN_BLACKHOLE || - rtm->rtm_type == RTN_PROHIBIT || -- rtm->rtm_type == RTN_THROW) -+ rtm->rtm_type == RTN_THROW || -+ rtm->rtm_type == RTN_POLICY_FAILED) - cfg->fc_flags |= RTF_REJECT; - - if (rtm->rtm_type == RTN_LOCAL) -@@ -6287,6 +6318,8 @@ static int ip6_route_dev_notify(struct n - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - net->ipv6.ip6_prohibit_entry->dst.dev = dev; - net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); -+ net->ipv6.ip6_policy_failed_entry->dst.dev = dev; -+ net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev); - net->ipv6.ip6_blk_hole_entry->dst.dev = dev; - net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); - #endif -@@ -6298,6 +6331,7 @@ static int ip6_route_dev_notify(struct n - in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); -+ in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev); - in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); - #endif - } -@@ -6489,6 +6523,8 @@ static int __net_init ip6_route_net_init - - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - net->ipv6.fib6_has_custom_rules = false; -+ -+ - net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, - sizeof(*net->ipv6.ip6_prohibit_entry), - GFP_KERNEL); -@@ -6499,11 +6535,21 @@ static int __net_init ip6_route_net_init - ip6_template_metrics, true); - INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached); - -+ net->ipv6.ip6_policy_failed_entry = -+ kmemdup(&ip6_policy_failed_entry_template, -+ sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL); -+ if (!net->ipv6.ip6_policy_failed_entry) -+ goto out_ip6_prohibit_entry; -+ net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops; -+ dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst, -+ ip6_template_metrics, true); -+ INIT_LIST_HEAD(&net->ipv6.ip6_policy_failed_entry->rt6i_uncached); -+ - net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, - sizeof(*net->ipv6.ip6_blk_hole_entry), - GFP_KERNEL); - if (!net->ipv6.ip6_blk_hole_entry) -- goto out_ip6_prohibit_entry; -+ goto out_ip6_policy_failed_entry; - net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; - dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, - ip6_template_metrics, true); -@@ -6530,6 +6576,8 @@ out: - return ret; - - #ifdef CONFIG_IPV6_MULTIPLE_TABLES -+out_ip6_policy_failed_entry: -+ kfree(net->ipv6.ip6_policy_failed_entry); - out_ip6_prohibit_entry: - kfree(net->ipv6.ip6_prohibit_entry); - out_ip6_null_entry: -@@ -6549,6 +6597,7 @@ static void __net_exit ip6_route_net_exi - kfree(net->ipv6.ip6_null_entry); - #ifdef CONFIG_IPV6_MULTIPLE_TABLES - kfree(net->ipv6.ip6_prohibit_entry); -+ kfree(net->ipv6.ip6_policy_failed_entry); - kfree(net->ipv6.ip6_blk_hole_entry); - #endif - dst_entries_destroy(&net->ipv6.ip6_dst_ops); -@@ -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_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_policy_failed_entry->dst.dev = init_net.loopback_dev; -+ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev = -+ in6_dev_get(init_net.loopback_dev); - #endif - } - diff --git a/target/linux/generic/pending-6.1/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch b/target/linux/generic/pending-6.1/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch deleted file mode 100644 index 94416a5d70e536..00000000000000 --- a/target/linux/generic/pending-6.1/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Jonas Gorski -Subject: net: provide defines for _POLICY_FAILED until all code is updated - -Upstream introduced ICMPV6_POLICY_FAIL for code 5 of destination -unreachable, conflicting with our name. - -Add appropriate defines to allow our code to build with the new -name until we have updated our local patches for older kernels -and userspace packages. - -Signed-off-by: Jonas Gorski ---- - include/uapi/linux/fib_rules.h | 2 ++ - include/uapi/linux/icmpv6.h | 2 ++ - include/uapi/linux/rtnetlink.h | 2 ++ - 3 files changed, 6 insertions(+) - ---- a/include/uapi/linux/fib_rules.h -+++ b/include/uapi/linux/fib_rules.h -@@ -89,6 +89,8 @@ enum { - __FR_ACT_MAX, - }; - -+#define FR_ACT_FAILED_POLICY FR_ACT_POLICY_FAILED -+ - #define FR_ACT_MAX (__FR_ACT_MAX - 1) - - #endif ---- a/include/uapi/linux/icmpv6.h -+++ b/include/uapi/linux/icmpv6.h -@@ -126,6 +126,8 @@ struct icmp6hdr { - #define ICMPV6_POLICY_FAIL 5 - #define ICMPV6_REJECT_ROUTE 6 - -+#define ICMPV6_FAILED_POLICY ICMPV6_POLICY_FAIL -+ - /* - * Codes for Time Exceeded - */ ---- a/include/uapi/linux/rtnetlink.h -+++ b/include/uapi/linux/rtnetlink.h -@@ -269,6 +269,8 @@ enum { - __RTN_MAX - }; - -+#define RTN_FAILED_POLICY RTN_POLICY_FAILED -+ - #define RTN_MAX (__RTN_MAX - 1) - - diff --git a/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch b/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch deleted file mode 100644 index 012d6b87bacd77..00000000000000 --- a/target/linux/generic/pending-6.1/680-net-add-TCP-fraglist-GRO-support.patch +++ /dev/null @@ -1,627 +0,0 @@ -From: Felix Fietkau -Date: Tue, 23 Apr 2024 11:23:03 +0200 -Subject: [PATCH] net: add TCP fraglist GRO support - -When forwarding TCP after GRO, software segmentation is very expensive, -especially when the checksum needs to be recalculated. -One case where that's currently unavoidable is when routing packets over -PPPoE. Performance improves significantly when using fraglist GRO -implemented in the same way as for UDP. - -Here's a measurement of running 2 TCP streams through a MediaTek MT7622 -device (2-core Cortex-A53), which runs NAT with flow offload enabled from -one ethernet port to PPPoE on another ethernet port + cake qdisc set to -1Gbps. - -rx-gro-list off: 630 Mbit/s, CPU 35% idle -rx-gro-list on: 770 Mbit/s, CPU 40% idle - -Signe-off-by: Felix Fietkau ---- - ---- a/include/net/gro.h -+++ b/include/net/gro.h -@@ -424,6 +424,7 @@ static inline __wsum ip6_gro_compute_pse - } - - int skb_gro_receive(struct sk_buff *p, struct sk_buff *skb); -+int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb); - - /* Pass the currently batched GRO_NORMAL SKBs up to the stack. */ - static inline void gro_normal_list(struct napi_struct *napi) -@@ -446,5 +447,48 @@ static inline void gro_normal_one(struct - gro_normal_list(napi); - } - -+/* This function is the alternative of 'inet_iif' and 'inet_sdif' -+ * functions in case we can not rely on fields of IPCB. -+ * -+ * The caller must verify skb_valid_dst(skb) is false and skb->dev is initialized. -+ * The caller must hold the RCU read lock. -+ */ -+static inline void inet_get_iif_sdif(const struct sk_buff *skb, int *iif, int *sdif) -+{ -+ *iif = inet_iif(skb) ?: skb->dev->ifindex; -+ *sdif = 0; -+ -+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) -+ if (netif_is_l3_slave(skb->dev)) { -+ struct net_device *master = netdev_master_upper_dev_get_rcu(skb->dev); -+ -+ *sdif = *iif; -+ *iif = master ? master->ifindex : 0; -+ } -+#endif -+} -+ -+/* This function is the alternative of 'inet6_iif' and 'inet6_sdif' -+ * functions in case we can not rely on fields of IP6CB. -+ * -+ * The caller must verify skb_valid_dst(skb) is false and skb->dev is initialized. -+ * The caller must hold the RCU read lock. -+ */ -+static inline void inet6_get_iif_sdif(const struct sk_buff *skb, int *iif, int *sdif) -+{ -+ /* using skb->dev->ifindex because skb_dst(skb) is not initialized */ -+ *iif = skb->dev->ifindex; -+ *sdif = 0; -+ -+#if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV) -+ if (netif_is_l3_slave(skb->dev)) { -+ struct net_device *master = netdev_master_upper_dev_get_rcu(skb->dev); -+ -+ *sdif = *iif; -+ *iif = master ? master->ifindex : 0; -+ } -+#endif -+} -+ - - #endif /* _NET_IPV6_GRO_H */ ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -2058,7 +2058,10 @@ void tcp_v4_destroy_sock(struct sock *sk - - struct sk_buff *tcp_gso_segment(struct sk_buff *skb, - netdev_features_t features); --struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb); -+struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb); -+struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th); -+struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb, -+ struct tcphdr *th); - INDIRECT_CALLABLE_DECLARE(int tcp4_gro_complete(struct sk_buff *skb, int thoff)); - INDIRECT_CALLABLE_DECLARE(struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb)); - INDIRECT_CALLABLE_DECLARE(int tcp6_gro_complete(struct sk_buff *skb, int thoff)); ---- a/net/core/gro.c -+++ b/net/core/gro.c -@@ -290,6 +290,33 @@ done: - return 0; - } - -+int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb) -+{ -+ if (unlikely(p->len + skb->len >= 65536)) -+ return -E2BIG; -+ -+ if (NAPI_GRO_CB(p)->last == p) -+ skb_shinfo(p)->frag_list = skb; -+ else -+ NAPI_GRO_CB(p)->last->next = skb; -+ -+ skb_pull(skb, skb_gro_offset(skb)); -+ -+ NAPI_GRO_CB(p)->last = skb; -+ NAPI_GRO_CB(p)->count++; -+ p->data_len += skb->len; -+ -+ /* sk ownership - if any - completely transferred to the aggregated packet */ -+ skb->destructor = NULL; -+ skb->sk = NULL; -+ p->truesize += skb->truesize; -+ p->len += skb->len; -+ -+ NAPI_GRO_CB(skb)->same_flow = 1; -+ -+ return 0; -+} -+ - - static void napi_gro_complete(struct napi_struct *napi, struct sk_buff *skb) - { ---- a/net/ipv4/tcp_offload.c -+++ b/net/ipv4/tcp_offload.c -@@ -27,6 +27,70 @@ static void tcp_gso_tstamp(struct sk_buf - } - } - -+static void __tcpv4_gso_segment_csum(struct sk_buff *seg, -+ __be32 *oldip, __be32 newip, -+ __be16 *oldport, __be16 newport) -+{ -+ struct tcphdr *th; -+ struct iphdr *iph; -+ -+ if (*oldip == newip && *oldport == newport) -+ return; -+ -+ th = tcp_hdr(seg); -+ iph = ip_hdr(seg); -+ -+ inet_proto_csum_replace4(&th->check, seg, *oldip, newip, true); -+ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false); -+ *oldport = newport; -+ -+ csum_replace4(&iph->check, *oldip, newip); -+ *oldip = newip; -+} -+ -+static struct sk_buff *__tcpv4_gso_segment_list_csum(struct sk_buff *segs) -+{ -+ const struct tcphdr *th; -+ const struct iphdr *iph; -+ struct sk_buff *seg; -+ struct tcphdr *th2; -+ struct iphdr *iph2; -+ -+ seg = segs; -+ th = tcp_hdr(seg); -+ iph = ip_hdr(seg); -+ th2 = tcp_hdr(seg->next); -+ iph2 = ip_hdr(seg->next); -+ -+ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) && -+ iph->daddr == iph2->daddr && iph->saddr == iph2->saddr) -+ return segs; -+ -+ while ((seg = seg->next)) { -+ th2 = tcp_hdr(seg); -+ iph2 = ip_hdr(seg); -+ -+ __tcpv4_gso_segment_csum(seg, -+ &iph2->saddr, iph->saddr, -+ &th2->source, th->source); -+ __tcpv4_gso_segment_csum(seg, -+ &iph2->daddr, iph->daddr, -+ &th2->dest, th->dest); -+ } -+ -+ return segs; -+} -+ -+static struct sk_buff *__tcp4_gso_segment_list(struct sk_buff *skb, -+ netdev_features_t features) -+{ -+ skb = skb_segment_list(skb, features, skb_mac_header_len(skb)); -+ if (IS_ERR(skb)) -+ return skb; -+ -+ return __tcpv4_gso_segment_list_csum(skb); -+} -+ - static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb, - netdev_features_t features) - { -@@ -36,6 +100,9 @@ static struct sk_buff *tcp4_gso_segment( - if (!pskb_may_pull(skb, sizeof(struct tcphdr))) - return ERR_PTR(-EINVAL); - -+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) -+ return __tcp4_gso_segment_list(skb, features); -+ - if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { - const struct iphdr *iph = ip_hdr(skb); - struct tcphdr *th = tcp_hdr(skb); -@@ -180,61 +247,76 @@ out: - return segs; - } - --struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb) -+struct sk_buff *tcp_gro_lookup(struct list_head *head, struct tcphdr *th) - { -- struct sk_buff *pp = NULL; -+ struct tcphdr *th2; - struct sk_buff *p; -+ -+ list_for_each_entry(p, head, list) { -+ if (!NAPI_GRO_CB(p)->same_flow) -+ continue; -+ -+ th2 = tcp_hdr(p); -+ if (*(u32 *)&th->source ^ *(u32 *)&th2->source) { -+ NAPI_GRO_CB(p)->same_flow = 0; -+ continue; -+ } -+ -+ return p; -+ } -+ -+ return NULL; -+} -+ -+struct tcphdr *tcp_gro_pull_header(struct sk_buff *skb) -+{ -+ unsigned int thlen, hlen, off; - struct tcphdr *th; -- struct tcphdr *th2; -- unsigned int len; -- unsigned int thlen; -- __be32 flags; -- unsigned int mss = 1; -- unsigned int hlen; -- unsigned int off; -- int flush = 1; -- int i; - - off = skb_gro_offset(skb); - hlen = off + sizeof(*th); - th = skb_gro_header(skb, hlen, off); - if (unlikely(!th)) -- goto out; -+ return NULL; - - thlen = th->doff * 4; - if (thlen < sizeof(*th)) -- goto out; -+ return NULL; - - hlen = off + thlen; - if (skb_gro_header_hard(skb, hlen)) { - th = skb_gro_header_slow(skb, hlen, off); - if (unlikely(!th)) -- goto out; -+ return NULL; - } - - skb_gro_pull(skb, thlen); - -- len = skb_gro_len(skb); -- flags = tcp_flag_word(th); -- -- list_for_each_entry(p, head, list) { -- if (!NAPI_GRO_CB(p)->same_flow) -- continue; -+ return th; -+} - -- th2 = tcp_hdr(p); -+struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb, -+ struct tcphdr *th) -+{ -+ unsigned int thlen = th->doff * 4; -+ struct sk_buff *pp = NULL; -+ struct sk_buff *p; -+ struct tcphdr *th2; -+ unsigned int len; -+ __be32 flags; -+ unsigned int mss = 1; -+ int flush = 1; -+ int i; - -- if (*(u32 *)&th->source ^ *(u32 *)&th2->source) { -- NAPI_GRO_CB(p)->same_flow = 0; -- continue; -- } -+ len = skb_gro_len(skb); -+ flags = tcp_flag_word(th); - -- goto found; -- } -- p = NULL; -- goto out_check_final; -+ p = tcp_gro_lookup(head, th); -+ if (!p) -+ goto out_check_final; - --found: - /* Include the IP ID check below from the inner most IP hdr */ -+ th2 = tcp_hdr(p); - flush = NAPI_GRO_CB(p)->flush; - flush |= (__force int)(flags & TCP_FLAG_CWR); - flush |= (__force int)((flags ^ tcp_flag_word(th2)) & -@@ -271,6 +353,19 @@ found: - flush |= p->decrypted ^ skb->decrypted; - #endif - -+ if (unlikely(NAPI_GRO_CB(p)->is_flist)) { -+ flush |= (__force int)(flags ^ tcp_flag_word(th2)); -+ flush |= skb->ip_summed != p->ip_summed; -+ flush |= skb->csum_level != p->csum_level; -+ flush |= !pskb_may_pull(skb, skb_gro_offset(skb)); -+ flush |= NAPI_GRO_CB(p)->count >= 64; -+ -+ if (flush || skb_gro_receive_list(p, skb)) -+ mss = 1; -+ -+ goto out_check_final; -+ } -+ - if (flush || skb_gro_receive(p, skb)) { - mss = 1; - goto out_check_final; -@@ -292,7 +387,6 @@ out_check_final: - if (p && (!NAPI_GRO_CB(skb)->same_flow || flush)) - pp = p; - --out: - NAPI_GRO_CB(skb)->flush |= (flush != 0); - - return pp; -@@ -318,18 +412,58 @@ int tcp_gro_complete(struct sk_buff *skb - } - EXPORT_SYMBOL(tcp_gro_complete); - -+static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb, -+ struct tcphdr *th) -+{ -+ const struct iphdr *iph; -+ struct sk_buff *p; -+ struct sock *sk; -+ struct net *net; -+ int iif, sdif; -+ -+ if (!(skb->dev->features & NETIF_F_GRO_FRAGLIST)) -+ return; -+ -+ p = tcp_gro_lookup(head, th); -+ if (p) { -+ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist; -+ return; -+ } -+ -+ inet_get_iif_sdif(skb, &iif, &sdif); -+ iph = skb_gro_network_header(skb); -+ net = dev_net(skb->dev); -+ sk = __inet_lookup_established(net, net->ipv4.tcp_death_row.hashinfo, -+ iph->saddr, th->source, -+ iph->daddr, ntohs(th->dest), -+ iif, sdif); -+ NAPI_GRO_CB(skb)->is_flist = !sk; -+ if (sk) -+ sock_put(sk); -+} -+ - INDIRECT_CALLABLE_SCOPE - struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb) - { -+ struct tcphdr *th; -+ - /* Don't bother verifying checksum if we're going to flush anyway. */ - if (!NAPI_GRO_CB(skb)->flush && - skb_gro_checksum_validate(skb, IPPROTO_TCP, -- inet_gro_compute_pseudo)) { -- NAPI_GRO_CB(skb)->flush = 1; -- return NULL; -- } -+ inet_gro_compute_pseudo)) -+ goto flush; -+ -+ th = tcp_gro_pull_header(skb); -+ if (!th) -+ goto flush; - -- return tcp_gro_receive(head, skb); -+ tcp4_check_fraglist_gro(head, skb, th); -+ -+ return tcp_gro_receive(head, skb, th); -+ -+flush: -+ NAPI_GRO_CB(skb)->flush = 1; -+ return NULL; - } - - INDIRECT_CALLABLE_SCOPE int tcp4_gro_complete(struct sk_buff *skb, int thoff) -@@ -337,6 +471,15 @@ INDIRECT_CALLABLE_SCOPE int tcp4_gro_com - const struct iphdr *iph = ip_hdr(skb); - struct tcphdr *th = tcp_hdr(skb); - -+ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) { -+ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV4; -+ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count; -+ -+ __skb_incr_checksum_unnecessary(skb); -+ -+ return 0; -+ } -+ - th->check = ~tcp_v4_check(skb->len - thoff, iph->saddr, - iph->daddr, 0); - skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; ---- a/net/ipv4/udp_offload.c -+++ b/net/ipv4/udp_offload.c -@@ -437,33 +437,6 @@ out: - return segs; - } - --static int skb_gro_receive_list(struct sk_buff *p, struct sk_buff *skb) --{ -- if (unlikely(p->len + skb->len >= 65536)) -- return -E2BIG; -- -- if (NAPI_GRO_CB(p)->last == p) -- skb_shinfo(p)->frag_list = skb; -- else -- NAPI_GRO_CB(p)->last->next = skb; -- -- skb_pull(skb, skb_gro_offset(skb)); -- -- NAPI_GRO_CB(p)->last = skb; -- NAPI_GRO_CB(p)->count++; -- p->data_len += skb->len; -- -- /* sk ownership - if any - completely transferred to the aggregated packet */ -- skb->destructor = NULL; -- skb->sk = NULL; -- p->truesize += skb->truesize; -- p->len += skb->len; -- -- NAPI_GRO_CB(skb)->same_flow = 1; -- -- return 0; --} -- - - #define UDP_GRO_CNT_MAX 64 - static struct sk_buff *udp_gro_receive_segment(struct list_head *head, ---- a/net/ipv6/tcpv6_offload.c -+++ b/net/ipv6/tcpv6_offload.c -@@ -7,24 +7,67 @@ - */ - #include - #include -+#include - #include - #include - #include - #include - #include "ip6_offload.h" - -+static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb, -+ struct tcphdr *th) -+{ -+#if IS_ENABLED(CONFIG_IPV6) -+ const struct ipv6hdr *hdr; -+ struct sk_buff *p; -+ struct sock *sk; -+ struct net *net; -+ int iif, sdif; -+ -+ if (!(skb->dev->features & NETIF_F_GRO_FRAGLIST)) -+ return; -+ -+ p = tcp_gro_lookup(head, th); -+ if (p) { -+ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist; -+ return; -+ } -+ -+ inet6_get_iif_sdif(skb, &iif, &sdif); -+ hdr = skb_gro_network_header(skb); -+ net = dev_net(skb->dev); -+ sk = __inet6_lookup_established(net, net->ipv4.tcp_death_row.hashinfo, -+ &hdr->saddr, th->source, -+ &hdr->daddr, ntohs(th->dest), -+ iif, sdif); -+ NAPI_GRO_CB(skb)->is_flist = !sk; -+ if (sk) -+ sock_put(sk); -+#endif /* IS_ENABLED(CONFIG_IPV6) */ -+} -+ - INDIRECT_CALLABLE_SCOPE - struct sk_buff *tcp6_gro_receive(struct list_head *head, struct sk_buff *skb) - { -+ struct tcphdr *th; -+ - /* Don't bother verifying checksum if we're going to flush anyway. */ - if (!NAPI_GRO_CB(skb)->flush && - skb_gro_checksum_validate(skb, IPPROTO_TCP, -- ip6_gro_compute_pseudo)) { -- NAPI_GRO_CB(skb)->flush = 1; -- return NULL; -- } -+ ip6_gro_compute_pseudo)) -+ goto flush; - -- return tcp_gro_receive(head, skb); -+ th = tcp_gro_pull_header(skb); -+ if (!th) -+ goto flush; -+ -+ tcp6_check_fraglist_gro(head, skb, th); -+ -+ return tcp_gro_receive(head, skb, th); -+ -+flush: -+ NAPI_GRO_CB(skb)->flush = 1; -+ return NULL; - } - - INDIRECT_CALLABLE_SCOPE int tcp6_gro_complete(struct sk_buff *skb, int thoff) -@@ -32,6 +75,15 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com - const struct ipv6hdr *iph = ipv6_hdr(skb); - struct tcphdr *th = tcp_hdr(skb); - -+ if (unlikely(NAPI_GRO_CB(skb)->is_flist)) { -+ skb_shinfo(skb)->gso_type |= SKB_GSO_FRAGLIST | SKB_GSO_TCPV6; -+ skb_shinfo(skb)->gso_segs = NAPI_GRO_CB(skb)->count; -+ -+ __skb_incr_checksum_unnecessary(skb); -+ -+ return 0; -+ } -+ - th->check = ~tcp_v6_check(skb->len - thoff, &iph->saddr, - &iph->daddr, 0); - skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6; -@@ -39,6 +91,61 @@ INDIRECT_CALLABLE_SCOPE int tcp6_gro_com - return tcp_gro_complete(skb); - } - -+static void __tcpv6_gso_segment_csum(struct sk_buff *seg, -+ __be16 *oldport, __be16 newport) -+{ -+ struct tcphdr *th; -+ -+ if (*oldport == newport) -+ return; -+ -+ th = tcp_hdr(seg); -+ inet_proto_csum_replace2(&th->check, seg, *oldport, newport, false); -+ *oldport = newport; -+} -+ -+static struct sk_buff *__tcpv6_gso_segment_list_csum(struct sk_buff *segs) -+{ -+ const struct tcphdr *th; -+ const struct ipv6hdr *iph; -+ struct sk_buff *seg; -+ struct tcphdr *th2; -+ struct ipv6hdr *iph2; -+ -+ seg = segs; -+ th = tcp_hdr(seg); -+ iph = ipv6_hdr(seg); -+ th2 = tcp_hdr(seg->next); -+ iph2 = ipv6_hdr(seg->next); -+ -+ if (!(*(const u32 *)&th->source ^ *(const u32 *)&th2->source) && -+ ipv6_addr_equal(&iph->saddr, &iph2->saddr) && -+ ipv6_addr_equal(&iph->daddr, &iph2->daddr)) -+ return segs; -+ -+ while ((seg = seg->next)) { -+ th2 = tcp_hdr(seg); -+ iph2 = ipv6_hdr(seg); -+ -+ iph2->saddr = iph->saddr; -+ iph2->daddr = iph->daddr; -+ __tcpv6_gso_segment_csum(seg, &th2->source, th->source); -+ __tcpv6_gso_segment_csum(seg, &th2->dest, th->dest); -+ } -+ -+ return segs; -+} -+ -+static struct sk_buff *__tcp6_gso_segment_list(struct sk_buff *skb, -+ netdev_features_t features) -+{ -+ skb = skb_segment_list(skb, features, skb_mac_header_len(skb)); -+ if (IS_ERR(skb)) -+ return skb; -+ -+ return __tcpv6_gso_segment_list_csum(skb); -+} -+ - static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb, - netdev_features_t features) - { -@@ -50,6 +157,9 @@ static struct sk_buff *tcp6_gso_segment( - if (!pskb_may_pull(skb, sizeof(*th))) - return ERR_PTR(-EINVAL); - -+ if (skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST) -+ return __tcp6_gso_segment_list(skb, features); -+ - if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { - const struct ipv6hdr *ipv6h = ipv6_hdr(skb); - struct tcphdr *th = tcp_hdr(skb); diff --git a/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch b/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch deleted file mode 100644 index 03ee537fb8f8ad..00000000000000 --- a/target/linux/generic/pending-6.1/683-of_net-add-mac-address-to-of-tree.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 8585756342caa6d27008d1ad0c18023e4211a40a Mon Sep 17 00:00:00 2001 -From: OpenWrt community -Date: Wed, 13 Jul 2022 12:22:48 +0200 -Subject: [PATCH] of/of_net: write back netdev MAC-address to device-tree - -The label-mac logic relies on the mac-address property of a netdev -devices of-node. However, the mac address can also be stored as a -different property or read from e.g. an mtd device. - -Create this node when reading a mac-address from OF if it does not -already exist and copy the mac-address used for the device to this -property. This way, the MAC address can be accessed using procfs. - ---- - net/core/of_net.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - ---- a/net/core/of_net.c -+++ b/net/core/of_net.c -@@ -95,6 +95,27 @@ static int of_get_mac_addr_nvmem(struct - return 0; - } - -+static int of_add_mac_address(struct device_node *np, u8* addr) -+{ -+ struct property *prop; -+ -+ prop = kzalloc(sizeof(*prop), GFP_KERNEL); -+ if (!prop) -+ return -ENOMEM; -+ -+ prop->name = "mac-address"; -+ prop->length = ETH_ALEN; -+ prop->value = kmemdup(addr, ETH_ALEN, GFP_KERNEL); -+ if (!prop->value || of_update_property(np, prop)) -+ goto free; -+ -+ return 0; -+free: -+ kfree(prop->value); -+ kfree(prop); -+ return -ENOMEM; -+} -+ - /** - * of_get_mac_address() - * @np: Caller's Device Node -@@ -130,17 +151,23 @@ int of_get_mac_address(struct device_nod - - ret = of_get_mac_addr(np, "mac-address", addr); - if (!ret) -- return 0; -+ goto found; - - ret = of_get_mac_addr(np, "local-mac-address", addr); - if (!ret) -- return 0; -+ goto found; - - ret = of_get_mac_addr(np, "address", addr); - if (!ret) -- return 0; -+ goto found; - -- return of_get_mac_addr_nvmem(np, addr); -+ ret = of_get_mac_addr_nvmem(np, addr); -+ if (ret) -+ return ret; -+ -+found: -+ ret = of_add_mac_address(np, addr); -+ return ret; - } - EXPORT_SYMBOL(of_get_mac_address); - diff --git a/target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch deleted file mode 100644 index b335748705db76..00000000000000 --- a/target/linux/generic/pending-6.1/700-netfilter-nft_flow_offload-handle-netdevice-events-f.patch +++ /dev/null @@ -1,110 +0,0 @@ -From: Pablo Neira Ayuso -Date: Thu, 25 Jan 2018 12:58:55 +0100 -Subject: [PATCH] netfilter: nft_flow_offload: handle netdevice events from - nf_flow_table - -Move the code that deals with device events to the core. - -Signed-off-by: Pablo Neira Ayuso ---- - ---- a/net/netfilter/nf_flow_table_core.c -+++ b/net/netfilter/nf_flow_table_core.c -@@ -659,6 +659,23 @@ static struct pernet_operations nf_flow_ - .exit_batch = nf_flow_table_pernet_exit, - }; - -+static int nf_flow_table_netdev_event(struct notifier_block *this, -+ unsigned long event, void *ptr) -+{ -+ struct net_device *dev = netdev_notifier_info_to_dev(ptr); -+ -+ if (event != NETDEV_DOWN) -+ return NOTIFY_DONE; -+ -+ nf_flow_table_cleanup(dev); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block flow_offload_netdev_notifier = { -+ .notifier_call = nf_flow_table_netdev_event, -+}; -+ - static int __init nf_flow_table_module_init(void) - { - int ret; -@@ -671,8 +688,14 @@ static int __init nf_flow_table_module_i - if (ret) - goto out_offload; - -+ ret = register_netdevice_notifier(&flow_offload_netdev_notifier); -+ if (ret) -+ goto out_offload_init; -+ - return 0; - -+out_offload_init: -+ nf_flow_table_offload_exit(); - out_offload: - unregister_pernet_subsys(&nf_flow_table_net_ops); - return ret; -@@ -680,6 +703,7 @@ out_offload: - - static void __exit nf_flow_table_module_exit(void) - { -+ unregister_netdevice_notifier(&flow_offload_netdev_notifier); - nf_flow_table_offload_exit(); - unregister_pernet_subsys(&nf_flow_table_net_ops); - } ---- a/net/netfilter/nft_flow_offload.c -+++ b/net/netfilter/nft_flow_offload.c -@@ -479,47 +479,14 @@ static struct nft_expr_type nft_flow_off - .owner = THIS_MODULE, - }; - --static int flow_offload_netdev_event(struct notifier_block *this, -- unsigned long event, void *ptr) --{ -- struct net_device *dev = netdev_notifier_info_to_dev(ptr); -- -- if (event != NETDEV_DOWN) -- return NOTIFY_DONE; -- -- nf_flow_table_cleanup(dev); -- -- return NOTIFY_DONE; --} -- --static struct notifier_block flow_offload_netdev_notifier = { -- .notifier_call = flow_offload_netdev_event, --}; -- - static int __init nft_flow_offload_module_init(void) - { -- int err; -- -- err = register_netdevice_notifier(&flow_offload_netdev_notifier); -- if (err) -- goto err; -- -- err = nft_register_expr(&nft_flow_offload_type); -- if (err < 0) -- goto register_expr; -- -- return 0; -- --register_expr: -- unregister_netdevice_notifier(&flow_offload_netdev_notifier); --err: -- return err; -+ return nft_register_expr(&nft_flow_offload_type); - } - - static void __exit nft_flow_offload_module_exit(void) - { - nft_unregister_expr(&nft_flow_offload_type); -- unregister_netdevice_notifier(&flow_offload_netdev_notifier); - } - - module_init(nft_flow_offload_module_init); diff --git a/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch b/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch deleted file mode 100644 index 99ea09ae8f38ab..00000000000000 --- a/target/linux/generic/pending-6.1/701-netfilter-nf_tables-ignore-EOPNOTSUPP-on-flowtable-d.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Felix Fietkau -Date: Thu, 31 Aug 2023 21:48:38 +0200 -Subject: [PATCH] netfilter: nf_tables: ignore -EOPNOTSUPP on flowtable device - offload setup - -On many embedded devices, it is common to configure flowtable offloading for -a mix of different devices, some of which have hardware offload support and -some of which don't. -The current code limits the ability of user space to properly set up such a -configuration by only allowing adding devices with hardware offload support to -a offload-enabled flowtable. -Given that offload-enabled flowtables also imply fallback to pure software -offloading, this limitation makes little sense. -Fix it by not bailing out when the offload setup returns -EOPNOTSUPP - -Signed-off-by: Felix Fietkau ---- - ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -8012,7 +8012,7 @@ static int nft_register_flowtable_net_ho - err = flowtable->data.type->setup(&flowtable->data, - hook->ops.dev, - FLOW_BLOCK_BIND); -- if (err < 0) -+ if (err < 0 && err != -EOPNOTSUPP) - goto err_unregister_net_hooks; - - err = nf_register_net_hook(net, &hook->ops); diff --git a/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch b/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch deleted file mode 100644 index 90b60def6b6cce..00000000000000 --- a/target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Felix Fietkau -Date: Mon, 21 Mar 2022 20:39:59 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: enable threaded NAPI - -This can improve performance under load by ensuring that NAPI processing is -not pinned on CPU 0. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4940,6 +4940,8 @@ static int mtk_probe(struct platform_dev - * for NAPI to work - */ - init_dummy_netdev(ð->dummy_dev); -+ eth->dummy_dev.threaded = 1; -+ strcpy(eth->dummy_dev.name, "mtk_eth"); - netif_napi_add(ð->dummy_dev, ð->tx_napi, mtk_napi_tx); - netif_napi_add(ð->dummy_dev, ð->rx_napi, mtk_napi_rx); - diff --git a/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch deleted file mode 100644 index d50bc9cd4cb662..00000000000000 --- a/target/linux/generic/pending-6.1/703-phy-add-detach-callback-to-struct-phy_driver.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Gabor Juhos -Subject: generic: add detach callback to struct phy_driver - -lede-commit: fe61fc2d7d0b3fb348b502f68f98243b3ddf5867 - -Signed-off-by: Gabor Juhos ---- - drivers/net/phy/phy_device.c | 3 +++ - include/linux/phy.h | 6 ++++++ - 2 files changed, 9 insertions(+) - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -1852,6 +1852,9 @@ void phy_detach(struct phy_device *phyde - struct module *ndev_owner = NULL; - struct mii_bus *bus; - -+ if (phydev->drv && phydev->drv->detach) -+ phydev->drv->detach(phydev); -+ - if (phydev->sysfs_links) { - if (dev) - sysfs_remove_link(&dev->dev.kobj, "phydev"); ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -903,6 +903,12 @@ struct phy_driver { - /** @handle_interrupt: Override default interrupt handling */ - irqreturn_t (*handle_interrupt)(struct phy_device *phydev); - -+ /* -+ * Called before an ethernet device is detached -+ * from the PHY. -+ */ -+ void (*detach)(struct phy_device *phydev); -+ - /** @remove: Clears up any memory if needed */ - void (*remove)(struct phy_device *phydev); - diff --git a/target/linux/generic/pending-6.1/704-netfilter-nf_tables-fix-bidirectional-offload-regres.patch b/target/linux/generic/pending-6.1/704-netfilter-nf_tables-fix-bidirectional-offload-regres.patch deleted file mode 100644 index d1d6fa3fe1f12c..00000000000000 --- a/target/linux/generic/pending-6.1/704-netfilter-nf_tables-fix-bidirectional-offload-regres.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Felix Fietkau -Date: Wed, 14 Feb 2024 15:24:41 +0100 -Subject: [PATCH] netfilter: nf_tables: fix bidirectional offload regression - -Commit 8f84780b84d6 ("netfilter: flowtable: allow unidirectional rules") -made unidirectional flow offload possible, while completely ignoring (and -breaking) bidirectional flow offload for nftables. -Add the missing flag that was left out as an exercise for the reader :) - -Cc: Vlad Buslov -Fixes: 8f84780b84d6 ("netfilter: flowtable: allow unidirectional rules") -Signed-off-by: Felix Fietkau ---- - ---- a/net/netfilter/nft_flow_offload.c -+++ b/net/netfilter/nft_flow_offload.c -@@ -361,6 +361,7 @@ static void nft_flow_offload_eval(const - ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; - } - -+ __set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags); - ret = flow_offload_add(flowtable, flow); - if (ret < 0) - goto err_flow_add; diff --git a/target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch b/target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch deleted file mode 100644 index d444b2027cb462..00000000000000 --- a/target/linux/generic/pending-6.1/705-net-dsa-tag_mtk-add-padding-for-tx-packets.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Felix Fietkau -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 ---- - ---- a/net/dsa/tag_mtk.c -+++ b/net/dsa/tag_mtk.c -@@ -27,6 +27,13 @@ static struct sk_buff *mtk_tag_xmit(stru - - skb_set_queue_mapping(skb, dp->index); - -+ /* 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). -+ */ -+ eth_skb_pad(skb); -+ - /* 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 diff --git a/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch b/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch deleted file mode 100644 index 367c41bff0ea7c..00000000000000 --- a/target/linux/generic/pending-6.1/710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch +++ /dev/null @@ -1,174 +0,0 @@ -From: Felix Fietkau -Date: Fri, 27 Aug 2021 12:22:32 +0200 -Subject: [PATCH] bridge: add knob for filtering rx/tx BPDU packets on a port - -Some devices (e.g. wireless APs) can't have devices behind them be part of -a bridge topology with redundant links, due to address limitations. -Additionally, broadcast traffic on these devices is somewhat expensive, due to -the low data rate and wakeups of clients in powersave mode. -This knob can be used to ensure that BPDU packets are never sent or forwarded -to/from these devices - -Signed-off-by: Felix Fietkau ---- - ---- a/include/linux/if_bridge.h -+++ b/include/linux/if_bridge.h -@@ -59,6 +59,7 @@ struct br_ip_list { - #define BR_MRP_LOST_IN_CONT BIT(19) - #define BR_TX_FWD_OFFLOAD BIT(20) - #define BR_PORT_LOCKED BIT(21) -+#define BR_BPDU_FILTER BIT(22) - - #define BR_DEFAULT_AGEING_TIME (300 * HZ) - ---- a/net/bridge/br_forward.c -+++ b/net/bridge/br_forward.c -@@ -199,6 +199,7 @@ out: - void br_flood(struct net_bridge *br, struct sk_buff *skb, - enum br_pkt_type pkt_type, bool local_rcv, bool local_orig) - { -+ const unsigned char *dest = eth_hdr(skb)->h_dest; - struct net_bridge_port *prev = NULL; - struct net_bridge_port *p; - -@@ -214,6 +215,10 @@ void br_flood(struct net_bridge *br, str - case BR_PKT_MULTICAST: - if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev) - continue; -+ if ((p->flags & BR_BPDU_FILTER) && -+ unlikely(is_link_local_ether_addr(dest) && -+ dest[5] == 0)) -+ continue; - break; - case BR_PKT_BROADCAST: - if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev) ---- a/net/bridge/br_input.c -+++ b/net/bridge/br_input.c -@@ -349,6 +349,8 @@ static rx_handler_result_t br_handle_fra - fwd_mask |= p->group_fwd_mask; - switch (dest[5]) { - case 0x00: /* Bridge Group Address */ -+ if (p->flags & BR_BPDU_FILTER) -+ goto drop; - /* If STP is turned off, - then must forward to keep loop detection */ - if (p->br->stp_enabled == BR_NO_STP || ---- a/net/bridge/br_sysfs_if.c -+++ b/net/bridge/br_sysfs_if.c -@@ -240,6 +240,7 @@ BRPORT_ATTR_FLAG(multicast_flood, BR_MCA - BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD); - BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS); - BRPORT_ATTR_FLAG(isolated, BR_ISOLATED); -+BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER); - - #ifdef CONFIG_BRIDGE_IGMP_SNOOPING - static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) -@@ -292,6 +293,7 @@ static const struct brport_attribute *br - &brport_attr_group_fwd_mask, - &brport_attr_neigh_suppress, - &brport_attr_isolated, -+ &brport_attr_bpdu_filter, - &brport_attr_backup_port, - NULL - }; ---- a/net/bridge/br_stp_bpdu.c -+++ b/net/bridge/br_stp_bpdu.c -@@ -80,7 +80,8 @@ void br_send_config_bpdu(struct net_brid - { - unsigned char buf[35]; - -- if (p->br->stp_enabled != BR_KERNEL_STP) -+ if (p->br->stp_enabled != BR_KERNEL_STP || -+ (p->flags & BR_BPDU_FILTER)) - return; - - buf[0] = 0; -@@ -127,7 +128,8 @@ void br_send_tcn_bpdu(struct net_bridge_ - { - unsigned char buf[4]; - -- if (p->br->stp_enabled != BR_KERNEL_STP) -+ if (p->br->stp_enabled != BR_KERNEL_STP || -+ (p->flags & BR_BPDU_FILTER)) - return; - - buf[0] = 0; -@@ -172,6 +174,9 @@ void br_stp_rcv(const struct stp_proto * - if (!(br->dev->flags & IFF_UP)) - goto out; - -+ if (p->flags & BR_BPDU_FILTER) -+ goto out; -+ - if (p->state == BR_STATE_DISABLED) - goto out; - ---- a/include/uapi/linux/if_link.h -+++ b/include/uapi/linux/if_link.h -@@ -561,6 +561,7 @@ enum { - IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT, - IFLA_BRPORT_MCAST_EHT_HOSTS_CNT, - IFLA_BRPORT_LOCKED, -+ IFLA_BRPORT_BPDU_FILTER, - __IFLA_BRPORT_MAX - }; - #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) ---- a/net/bridge/br_netlink.c -+++ b/net/bridge/br_netlink.c -@@ -188,6 +188,7 @@ static inline size_t br_port_info_size(v - + nla_total_size(1) /* IFLA_BRPORT_NEIGH_SUPPRESS */ - + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */ - + nla_total_size(1) /* IFLA_BRPORT_LOCKED */ -+ + nla_total_size(1) /* IFLA_BRPORT_BPDU_FILTER */ - + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */ - + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */ - + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */ -@@ -274,7 +275,8 @@ static int br_port_fill_attrs(struct sk_ - nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN, - !!(p->flags & BR_MRP_LOST_IN_CONT)) || - nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) || -- nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED))) -+ nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED)) || -+ nla_put_u8(skb, IFLA_BRPORT_BPDU_FILTER, !!(p->flags & BR_BPDU_FILTER))) - return -EMSGSIZE; - - timerval = br_timer_value(&p->message_age_timer); -@@ -879,6 +881,7 @@ static const struct nla_policy br_port_p - [IFLA_BRPORT_LOCKED] = { .type = NLA_U8 }, - [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 }, - [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 }, -+ [IFLA_BRPORT_BPDU_FILTER] = { .type = NLA_U8 }, - }; - - /* Change the state of the port and notify spanning tree */ -@@ -944,6 +947,7 @@ static int br_setport(struct net_bridge_ - br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS, BR_NEIGH_SUPPRESS); - br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED); - br_set_port_flag(p, tb, IFLA_BRPORT_LOCKED, BR_PORT_LOCKED); -+ br_set_port_flag(p, tb, IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER); - - changed_mask = old_flags ^ p->flags; - ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -57,7 +57,7 @@ - #include "dev.h" - - #define RTNL_MAX_TYPE 50 --#define RTNL_SLAVE_MAX_TYPE 40 -+#define RTNL_SLAVE_MAX_TYPE 41 - - struct rtnl_link { - rtnl_doit_func doit; -@@ -4840,7 +4840,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu - brport_nla_put_flag(skb, flags, mask, - IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) || - brport_nla_put_flag(skb, flags, mask, -- IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD)) { -+ IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD) || -+ brport_nla_put_flag(skb, flags, mask, -+ IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER)) { - nla_nest_cancel(skb, protinfo); - goto nla_put_failure; - } diff --git a/target/linux/generic/pending-6.1/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch b/target/linux/generic/pending-6.1/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch deleted file mode 100644 index 629b141572dbc7..00000000000000 --- a/target/linux/generic/pending-6.1/711-01-net-dsa-qca8k-implement-lag_fdb_add-del-ops.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 3b4329230db8750bea7a56ef07f07cbbf5fc6c5a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 4 Jul 2023 22:50:12 +0200 -Subject: [PATCH 19/20] net: dsa: qca8k: implement lag_fdb_add/del ops - -Implement lag_fdb_add/del ops to correctly support using LAG interface. -Qca8k switch supports declaring fdb entry for link aggregation by simply -setting the DES_PORT bits to all the LAG member. - -Signed-off-by: Christian Marangi ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 2 ++ - drivers/net/dsa/qca/qca8k-common.c | 48 ++++++++++++++++++++++++++++++ - drivers/net/dsa/qca/qca8k.h | 6 ++++ - 3 files changed, 56 insertions(+) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -2015,6 +2015,8 @@ static const struct dsa_switch_ops qca8k - .port_fdb_add = qca8k_port_fdb_add, - .port_fdb_del = qca8k_port_fdb_del, - .port_fdb_dump = qca8k_port_fdb_dump, -+ .lag_fdb_add = qca8k_lag_fdb_add, -+ .lag_fdb_del = qca8k_lag_fdb_del, - .port_mdb_add = qca8k_port_mdb_add, - .port_mdb_del = qca8k_port_mdb_del, - .port_mirror_add = qca8k_port_mirror_add, ---- a/drivers/net/dsa/qca/qca8k-common.c -+++ b/drivers/net/dsa/qca/qca8k-common.c -@@ -1215,6 +1215,42 @@ int qca8k_port_lag_leave(struct dsa_swit - return qca8k_lag_refresh_portmap(ds, port, lag, true); - } - -+int qca8k_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ struct dsa_port *dp; -+ u16 port_mask = 0; -+ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = QCA8K_PORT_VID_DEF; -+ -+ dsa_lag_foreach_port(dp, ds->dst, &lag) -+ port_mask |= BIT(dp->index); -+ -+ return qca8k_port_fdb_insert(priv, addr, port_mask, vid); -+} -+ -+int qca8k_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db) -+{ -+ struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; -+ struct dsa_port *dp; -+ u16 port_mask = 0; -+ -+ /* Set the vid to the port vlan id if no vid is set */ -+ if (!vid) -+ vid = QCA8K_PORT_VID_DEF; -+ -+ dsa_lag_foreach_port(dp, ds->dst, &lag) -+ port_mask |= BIT(dp->index); -+ -+ return qca8k_fdb_del(priv, addr, port_mask, vid); -+} -+ - int qca8k_read_switch_id(struct qca8k_priv *priv) - { - u32 val; ---- a/drivers/net/dsa/qca/qca8k.h -+++ b/drivers/net/dsa/qca/qca8k.h -@@ -590,5 +590,11 @@ int qca8k_port_lag_join(struct dsa_switc - struct netlink_ext_ack *extack); - int qca8k_port_lag_leave(struct dsa_switch *ds, int port, - struct dsa_lag lag); -+int qca8k_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db); -+int qca8k_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag, -+ const unsigned char *addr, u16 vid, -+ struct dsa_db db); - - #endif /* __QCA8K_H */ diff --git a/target/linux/generic/pending-6.1/711-02-net-dsa-qca8k-enable-flooding-to-both-CPU-port.patch b/target/linux/generic/pending-6.1/711-02-net-dsa-qca8k-enable-flooding-to-both-CPU-port.patch deleted file mode 100644 index 24243468a8fa83..00000000000000 --- a/target/linux/generic/pending-6.1/711-02-net-dsa-qca8k-enable-flooding-to-both-CPU-port.patch +++ /dev/null @@ -1,37 +0,0 @@ -From b954d61d9ecfa64450fc178586719dc2a95b92a7 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 20 Jun 2023 21:48:24 +0200 -Subject: [PATCH 3/4] net: dsa: qca8k: enable flooding to both CPU port - -To permit a multi-CPU setup, flood all unknown frames to all CPU ports. -Each CPU port should have correct LOOKUP MEMBER configuration to -prevent receiving duplicate packets from user ports. - -Signed-off-by: Christian Marangi ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 13 +++++-------- - 1 file changed, 5 insertions(+), 8 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1904,15 +1904,12 @@ qca8k_setup(struct dsa_switch *ds) - } - } - -- /* Forward all unknown frames to CPU port for Linux processing -- * Notice that in multi-cpu config only one port should be set -- * for igmp, unknown, multicast and broadcast packet -- */ -+ /* Forward all unknown frames to CPU port for Linux processing */ - ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) | -- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port))); -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, dsa_cpu_ports(ds)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, dsa_cpu_ports(ds)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, dsa_cpu_ports(ds)) | -+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, dsa_cpu_ports(ds))); - if (ret) - return ret; - diff --git a/target/linux/generic/pending-6.1/711-03-net-dsa-qca8k-add-support-for-port_change_master.patch b/target/linux/generic/pending-6.1/711-03-net-dsa-qca8k-add-support-for-port_change_master.patch deleted file mode 100644 index 8a58e0f76e0e61..00000000000000 --- a/target/linux/generic/pending-6.1/711-03-net-dsa-qca8k-add-support-for-port_change_master.patch +++ /dev/null @@ -1,158 +0,0 @@ -From b2d6ebf2f92f8695c83fa6979f4ab579c588df76 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Tue, 20 Jun 2023 07:57:38 +0200 -Subject: [PATCH 4/4] net: dsa: qca8k: add support for port_change_master - -Add support for port_change_master to permit assigning an alternative -CPU port if the switch have both CPU port connected or create a LAG on -both CPU port and assign the LAG as DSA master. - -On port change master request, we check if the master is a LAG. -With LAG we compose the cpu_port_mask with the CPU port in the LAG, if -master is a simple dsa_port, we derive the index. - -Finally we apply the new cpu_port_mask to the LOOKUP MEMBER to permit -the port to receive packet by the new CPU port setup for the port and we -refresh the CPU ports LOOKUP MEMBER configuration to reflect the new -user port state. - -port_lag_join/leave is updated to refresh the user ports if we detect -that the LAG is a DSA master and we have user port using it as a master. - -Signed-off-by: Christian Marangi ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 116 ++++++++++++++++++++++++++++++- - 1 file changed, 114 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -1741,6 +1741,117 @@ qca8k_get_tag_protocol(struct dsa_switch - return DSA_TAG_PROTO_QCA; - } - -+static int qca8k_port_change_master(struct dsa_switch *ds, int port, -+ struct net_device *master, -+ struct netlink_ext_ack *extack) -+{ -+ struct dsa_switch_tree *dst = ds->dst; -+ struct qca8k_priv *priv = ds->priv; -+ u8 cpu_port_mask = 0; -+ struct dsa_port *dp; -+ u32 val; -+ int ret; -+ -+ /* With LAG of CPU port, compose the mask for port LOOKUP MEMBER */ -+ if (netif_is_lag_master(master)) { -+ struct dsa_lag *lag; -+ int id; -+ -+ id = dsa_lag_id(dst, master); -+ lag = dsa_lag_by_id(dst, id); -+ -+ dsa_lag_foreach_port(dp, dst, lag) -+ if (dsa_port_is_cpu(dp)) -+ cpu_port_mask |= BIT(dp->index); -+ } else { -+ dp = master->dsa_ptr; -+ cpu_port_mask |= BIT(dp->index); -+ } -+ -+ /* Connect port to new cpu port */ -+ ret = regmap_read(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), &val); -+ if (ret) -+ return ret; -+ -+ /* Reset connected CPU port in port LOOKUP MEMBER */ -+ val &= ~dsa_cpu_ports(ds); -+ /* Assign the new CPU port in port LOOKUP MEMBER */ -+ val |= cpu_port_mask; -+ -+ ret = regmap_update_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), -+ QCA8K_PORT_LOOKUP_MEMBER, -+ val); -+ if (ret) -+ return ret; -+ -+ /* Refresh CPU port LOOKUP MEMBER with new port */ -+ dsa_tree_for_each_cpu_port(dp, ds->dst) { -+ u32 reg = QCA8K_PORT_LOOKUP_CTRL(dp->index); -+ -+ /* If CPU port in mask assign port, else remove port */ -+ if (BIT(dp->index) & cpu_port_mask) -+ ret = regmap_set_bits(priv->regmap, reg, BIT(port)); -+ else -+ ret = regmap_clear_bits(priv->regmap, reg, BIT(port)); -+ -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int qca8k_port_lag_refresh_user_ports(struct dsa_switch *ds, -+ struct dsa_lag lag) -+{ -+ struct net_device *lag_dev = lag.dev; -+ struct dsa_port *dp; -+ int ret; -+ -+ /* Ignore if LAG is not a DSA master */ -+ if (!netif_is_lag_master(lag_dev)) -+ return 0; -+ -+ dsa_switch_for_each_user_port(dp, ds) { -+ /* Skip if assigned master is not the LAG */ -+ if (dsa_port_to_master(dp) != lag_dev) -+ continue; -+ -+ ret = qca8k_port_change_master(ds, dp->index, -+ lag_dev, NULL); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int qca8xxx_port_lag_join(struct dsa_switch *ds, int port, -+ struct dsa_lag lag, -+ struct netdev_lag_upper_info *info, -+ struct netlink_ext_ack *extack) -+{ -+ int ret; -+ -+ ret = qca8k_port_lag_join(ds, port, lag, info, extack); -+ if (ret) -+ return ret; -+ -+ return qca8k_port_lag_refresh_user_ports(ds, lag); -+} -+ -+static int qca8xxx_port_lag_leave(struct dsa_switch *ds, int port, -+ struct dsa_lag lag) -+{ -+ int ret; -+ -+ ret = qca8k_port_lag_leave(ds, port, lag); -+ if (ret) -+ return ret; -+ -+ return qca8k_port_lag_refresh_user_ports(ds, lag); -+} -+ - static void - qca8k_master_change(struct dsa_switch *ds, const struct net_device *master, - bool operational) -@@ -2027,8 +2138,9 @@ static const struct dsa_switch_ops qca8k - .phylink_mac_link_down = qca8k_phylink_mac_link_down, - .phylink_mac_link_up = qca8k_phylink_mac_link_up, - .get_phy_flags = qca8k_get_phy_flags, -- .port_lag_join = qca8k_port_lag_join, -- .port_lag_leave = qca8k_port_lag_leave, -+ .port_lag_join = qca8xxx_port_lag_join, -+ .port_lag_leave = qca8xxx_port_lag_leave, -+ .port_change_master = qca8k_port_change_master, - .master_state_change = qca8k_master_change, - .connect_tag_protocol = qca8k_connect_tag_protocol, - }; diff --git a/target/linux/generic/pending-6.1/712-net-dsa-qca8k-enable-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-6.1/712-net-dsa-qca8k-enable-assisted-learning-on-CPU-port.patch deleted file mode 100644 index 23816fe3660cde..00000000000000 --- a/target/linux/generic/pending-6.1/712-net-dsa-qca8k-enable-assisted-learning-on-CPU-port.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0f6599167c126ce32c85d4f8a1f3d1775a268572 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Fri, 6 Oct 2023 12:44:00 +0200 -Subject: [PATCH] net: dsa: qca8k: enable assisted learning on CPU port - -Enable assisted learning on CPU port. - -It has been verified that there is a problem in packet roaming -from one BSS to another in the same security settings from one -physical R7800 to another physical R7800 where they are in the -same L2 broadcast domain backhauled/linked together via one -of the ethernet ports. -DHCP will fail to complete and traffic cannot flow for around 300 -seconds. - -Signed-off-by: Christian Marangi ---- - drivers/net/dsa/qca/qca8k-8xxx.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - ---- a/drivers/net/dsa/qca/qca8k-8xxx.c -+++ b/drivers/net/dsa/qca/qca8k-8xxx.c -@@ -2013,6 +2013,12 @@ qca8k_setup(struct dsa_switch *ds) - dev_err(priv->dev, "failed enabling QCA header mode on port %d", dp->index); - return ret; - } -+ -+ /* Disable learning by default on all ports */ -+ ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(dp->index), -+ QCA8K_PORT_LOOKUP_LEARN); -+ if (ret) -+ return ret; - } - - /* Forward all unknown frames to CPU port for Linux processing */ -@@ -2042,11 +2048,6 @@ qca8k_setup(struct dsa_switch *ds) - if (ret) - return ret; - -- ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), -- QCA8K_PORT_LOOKUP_LEARN); -- if (ret) -- return ret; -- - /* For port based vlans to work we need to set the - * default egress vid - */ -@@ -2098,6 +2099,9 @@ qca8k_setup(struct dsa_switch *ds) - /* Set max number of LAGs supported */ - ds->num_lag_ids = QCA8K_NUM_LAGS; - -+ /* HW learn on CPU port is limited and require manual setting */ -+ ds->assisted_learning_on_cpu_port = true; -+ - return 0; - } - diff --git a/target/linux/generic/pending-6.1/713-03-arm64-dts-qcom-ipq8074-add-clock-frequency-to-MDIO-n.patch b/target/linux/generic/pending-6.1/713-03-arm64-dts-qcom-ipq8074-add-clock-frequency-to-MDIO-n.patch deleted file mode 100644 index 55f116ec5f2c3d..00000000000000 --- a/target/linux/generic/pending-6.1/713-03-arm64-dts-qcom-ipq8074-add-clock-frequency-to-MDIO-n.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 3b5a603bf66236b956287909556fd7ad4904450c Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 24 Jan 2024 19:38:01 +0100 -Subject: [PATCH 3/3] arm64: dts: qcom: ipq8074: add clock-frequency to MDIO - node - -Add clock-frequency to MDIO node to set the MDC rate to 6.25Mhz instead -of using the default value of 390KHz from MDIO default divider. - -Signed-off-by: Christian Marangi ---- - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi -@@ -263,6 +263,8 @@ - clocks = <&gcc GCC_MDIO_AHB_CLK>; - clock-names = "gcc_mdio_ahb_clk"; - -+ clock-frequency = <6250000>; -+ - status = "disabled"; - }; - diff --git a/target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch b/target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch deleted file mode 100644 index ed13b004e4ecf0..00000000000000 --- a/target/linux/generic/pending-6.1/721-net-phy-realtek-rtl8221-allow-to-configure-SERDES-mo.patch +++ /dev/null @@ -1,106 +0,0 @@ -From ace6abaa0f9203083fe4c0a6a74da2d96410b625 Mon Sep 17 00:00:00 2001 -From: Alexander Couzens -Date: Sat, 13 Aug 2022 12:49:33 +0200 -Subject: [PATCH 01/10] net: phy: realtek: rtl8221: allow to configure SERDES - mode - -The rtl8221 supports multiple SERDES modes: -- SGMII -- 2500base-x -- HiSGMII - -Further it supports rate adaption on SERDES links to allow -slow ethernet speeds (10/100/1000mbit) to work on 2500base-x/HiSGMII -links without reducing the SERDES speed. - -When operating without rate adapters the SERDES link will follow the -ethernet speed. - -Signed-off-by: Alexander Couzens ---- - drivers/net/phy/realtek.c | 48 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 48 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -53,6 +53,15 @@ - RTL8201F_ISR_LINK) - #define RTL8201F_IER 0x13 - -+#define RTL8221B_MMD_SERDES_CTRL MDIO_MMD_VEND1 -+#define RTL8221B_MMD_PHY_CTRL MDIO_MMD_VEND2 -+#define RTL8221B_SERDES_OPTION 0x697a -+#define RTL8221B_SERDES_OPTION_MODE_MASK GENMASK(5, 0) -+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII 0 -+#define RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII 1 -+#define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2 -+#define RTL8221B_SERDES_OPTION_MODE_HISGMII 3 -+ - #define RTL8366RB_POWER_SAVE 0x15 - #define RTL8366RB_POWER_SAVE_ON BIT(12) - -@@ -851,6 +860,48 @@ static irqreturn_t rtl9000a_handle_inter - return IRQ_HANDLED; - } - -+static int rtl8221b_config_init(struct phy_device *phydev) -+{ -+ u16 option_mode; -+ -+ switch (phydev->interface) { -+ case PHY_INTERFACE_MODE_2500BASEX: -+ if (!phydev->is_c45) { -+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX; -+ break; -+ } -+ fallthrough; -+ case PHY_INTERFACE_MODE_SGMII: -+ option_mode = RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII; -+ break; -+ default: -+ return 0; -+ } -+ -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, -+ 0x75f3, 0); -+ -+ phy_modify_mmd_changed(phydev, RTL8221B_MMD_SERDES_CTRL, -+ RTL8221B_SERDES_OPTION, -+ RTL8221B_SERDES_OPTION_MODE_MASK, option_mode); -+ switch (option_mode) { -+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX_SGMII: -+ case RTL8221B_SERDES_OPTION_MODE_2500BASEX: -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd455); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020); -+ break; -+ case RTL8221B_SERDES_OPTION_MODE_HISGMII_SGMII: -+ case RTL8221B_SERDES_OPTION_MODE_HISGMII: -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6a04, 0x0503); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f10, 0xd433); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x6f11, 0x8020); -+ break; -+ } -+ -+ return 0; -+} -+ - static struct phy_driver realtek_drvs[] = { - { - PHY_ID_MATCH_EXACT(0x00008201), -@@ -1003,6 +1054,7 @@ static struct phy_driver realtek_drvs[] - PHY_ID_MATCH_EXACT(0x001cc849), - .name = "RTL8221B-VB-CG 2.5Gbps PHY", - .get_features = rtl822x_get_features, -+ .config_init = rtl8221b_config_init, - .config_aneg = rtl822x_config_aneg, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, -@@ -1014,6 +1066,7 @@ static struct phy_driver realtek_drvs[] - .name = "RTL8221B-VM-CG 2.5Gbps PHY", - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, -+ .config_init = rtl8221b_config_init, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, diff --git a/target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch b/target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch deleted file mode 100644 index abe31e66afe9ed..00000000000000 --- a/target/linux/generic/pending-6.1/722-net-phy-realtek-support-switching-between-SGMII-and-.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 312753d0aadba0f58841ae513b80fdbabc887523 Mon Sep 17 00:00:00 2001 -From: Chukun Pan -Date: Wed, 8 Feb 2023 16:32:18 +0800 -Subject: [PATCH] net: phy: realtek: support switching between SGMII and - 2500BASE-X for RTL822x series - -After commit ace6aba ("net: phy: realtek: rtl8221: allow to configure -SERDES mode"), the rtl8221 phy can work in SGMII and 2500base-x modes -respectively. So add interface automatic switching for rtl8221 phy to -match various wire speeds. - -Signed-off-by: Chukun Pan ---- - drivers/net/phy/realtek.c | 26 ++++++++++++++++++++++++-- - 1 file changed, 24 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -686,6 +686,25 @@ static int rtl822x_config_aneg(struct ph - return __genphy_config_aneg(phydev, ret); - } - -+static void rtl822x_update_interface(struct phy_device *phydev) -+{ -+ /* Automatically switch SERDES interface between -+ * SGMII and 2500-BaseX according to speed. -+ */ -+ switch (phydev->speed) { -+ case SPEED_2500: -+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX; -+ break; -+ case SPEED_1000: -+ case SPEED_100: -+ case SPEED_10: -+ phydev->interface = PHY_INTERFACE_MODE_SGMII; -+ break; -+ default: -+ break; -+ } -+} -+ - static int rtl822x_read_status(struct phy_device *phydev) - { - int ret; -@@ -704,11 +723,14 @@ static int rtl822x_read_status(struct ph - phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL); - } - -- ret = genphy_read_status(phydev); -+ ret = rtlgen_read_status(phydev); - if (ret < 0) - return ret; - -- return rtlgen_get_speed(phydev); -+ if (phydev->is_c45 && phydev->link) -+ rtl822x_update_interface(phydev); -+ -+ return 0; - } - - static bool rtlgen_supports_2_5gbps(struct phy_device *phydev) diff --git a/target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch b/target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch deleted file mode 100644 index 8e0e4b1fdd43fe..00000000000000 --- a/target/linux/generic/pending-6.1/724-net-phy-realtek-use-genphy_soft_reset-for-2.5G-PHYs.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 85cd45580f5e3b26068cccb7d6173f200e754dc0 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 2 Apr 2023 23:56:16 +0100 -Subject: [PATCH 1/2] net: phy: realtek: use genphy_soft_reset for 2.5G PHYs - -Some vendor bootloaders do weird things with those PHYs which result in -link modes being reported wrongly. Start from a clean sheet by resetting -the PHY. - -Reported-by: Yevhen Kolomeiko -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -1040,6 +1040,7 @@ static struct phy_driver realtek_drvs[] - .write_page = rtl821x_write_page, - .read_mmd = rtl822x_read_mmd, - .write_mmd = rtl822x_write_mmd, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc840), - .name = "RTL8226B_RTL8221B 2.5Gbps PHY", -@@ -1052,6 +1053,7 @@ static struct phy_driver realtek_drvs[] - .write_page = rtl821x_write_page, - .read_mmd = rtl822x_read_mmd, - .write_mmd = rtl822x_write_mmd, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc838), - .name = "RTL8226-CG 2.5Gbps PHY", -@@ -1062,6 +1064,7 @@ static struct phy_driver realtek_drvs[] - .resume = rtlgen_resume, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc848), - .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY", -@@ -1072,6 +1075,7 @@ static struct phy_driver realtek_drvs[] - .resume = rtlgen_resume, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc849), - .name = "RTL8221B-VB-CG 2.5Gbps PHY", -@@ -1083,6 +1087,7 @@ static struct phy_driver realtek_drvs[] - .resume = rtlgen_resume, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc84a), - .name = "RTL8221B-VM-CG 2.5Gbps PHY", -@@ -1094,6 +1099,7 @@ static struct phy_driver realtek_drvs[] - .resume = rtlgen_resume, - .read_page = rtl821x_read_page, - .write_page = rtl821x_write_page, -+ .soft_reset = genphy_soft_reset, - }, { - PHY_ID_MATCH_EXACT(0x001cc961), - .name = "RTL8366RB Gigabit Ethernet", diff --git a/target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch b/target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch deleted file mode 100644 index babaa47aedcd90..00000000000000 --- a/target/linux/generic/pending-6.1/725-net-phy-realtek-disable-SGMII-in-band-AN-for-2-5G-PHYs.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 2b1b8c4c215af7988136401c902338d091d408a1 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Mon, 3 Apr 2023 01:21:57 +0300 -Subject: [PATCH 2/2] net: phy: realtek: disable SGMII in-band AN for 2.5G PHYs - -MAC drivers don't use SGMII in-band autonegotiation unless told to do so -in device tree using 'managed = "in-band-status"'. When using MDIO to -access a PHY, in-band-status is unneeded as we have link-status via -MDIO. Switch off SGMII in-band autonegotiation using magic values. - -Reported-by: Chen Minqiang -Reported-by: Chukun Pan -Reported-by: Yevhen Kolomeiko -Tested-by: Yevhen Kolomeiko -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -885,6 +885,7 @@ static irqreturn_t rtl9000a_handle_inter - static int rtl8221b_config_init(struct phy_device *phydev) - { - u16 option_mode; -+ int val; - - switch (phydev->interface) { - case PHY_INTERFACE_MODE_2500BASEX: -@@ -921,6 +922,13 @@ static int rtl8221b_config_init(struct p - break; - } - -+ /* Disable SGMII AN */ -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7588, 0x2); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7589, 0x71d0); -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, 0x3); -+ phy_read_mmd_poll_timeout(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, -+ val, !(val & BIT(0)), 500, 100000, false); -+ - return 0; - } - diff --git a/target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch b/target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch deleted file mode 100644 index 6e338d94741e4b..00000000000000 --- a/target/linux/generic/pending-6.1/726-net-phy-realtek-make-sure-paged-read-is-protected-by.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 4dd2cc9b91ecb25f278a2c55e07e6455e9000e6b Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 22 Apr 2023 01:21:14 +0100 -Subject: [PATCH] net: phy: realtek: make sure paged read is protected by mutex - -As we cannot rely on phy_read_paged function before the PHY is -identified, the paged read in rtlgen_supports_2_5gbps needs to be open -coded as it is being called by the match_phy_device function, ie. before -.read_page and .write_page have been populated. - -Make sure it is also protected by the MDIO bus mutex and use -rtl821x_write_page instead of 3 individually locked MDIO bus operations. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -737,9 +737,11 @@ static bool rtlgen_supports_2_5gbps(stru - { - int val; - -- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa61); -- val = phy_read(phydev, 0x13); -- phy_write(phydev, RTL821x_PAGE_SELECT, 0); -+ mutex_lock(&phydev->mdio.bus->mdio_lock); -+ rtl821x_write_page(phydev, 0xa61); -+ val = __phy_read(phydev, 0x13); -+ rtl821x_write_page(phydev, 0); -+ mutex_unlock(&phydev->mdio.bus->mdio_lock); - - return val >= 0 && val & RTL_SUPPORTS_2500FULL; - } diff --git a/target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch b/target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch deleted file mode 100644 index cafaefd3bf9bb0..00000000000000 --- a/target/linux/generic/pending-6.1/727-net-phy-realtek-use-inline-functions-for-10GbE-adver.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 92c8b9d558160d94b981dd8a2b9c47657627ffdc Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 22 Apr 2023 01:23:08 +0100 -Subject: [PATCH 2/3] net: phy: realtek: use inline functions for 10GbE - advertisement - -Use existing generic inline functions to encode local advertisement -of 10GbE link modes as well as to decode link-partner advertisement. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 22 +++++----------------- - 1 file changed, 5 insertions(+), 17 deletions(-) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -68,10 +68,6 @@ - #define RTL_SUPPORTS_5000FULL BIT(14) - #define RTL_SUPPORTS_2500FULL BIT(13) - #define RTL_SUPPORTS_10000FULL BIT(0) --#define RTL_ADV_2500FULL BIT(7) --#define RTL_LPADV_10000FULL BIT(11) --#define RTL_LPADV_5000FULL BIT(6) --#define RTL_LPADV_2500FULL BIT(5) - - #define RTL9000A_GINMR 0x14 - #define RTL9000A_GINMR_LINK_STATUS BIT(4) -@@ -671,14 +667,11 @@ static int rtl822x_config_aneg(struct ph - int ret = 0; - - if (phydev->autoneg == AUTONEG_ENABLE) { -- u16 adv2500 = 0; -- -- if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -- phydev->advertising)) -- adv2500 = RTL_ADV_2500FULL; -- - ret = phy_modify_paged_changed(phydev, 0xa5d, 0x12, -- RTL_ADV_2500FULL, adv2500); -+ MDIO_AN_10GBT_CTRL_ADV10G | -+ MDIO_AN_10GBT_CTRL_ADV5G | -+ MDIO_AN_10GBT_CTRL_ADV2_5G, -+ linkmode_adv_to_mii_10gbt_adv_t(phydev->advertising)); - if (ret < 0) - return ret; - } -@@ -715,12 +708,7 @@ static int rtl822x_read_status(struct ph - if (lpadv < 0) - return lpadv; - -- linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, -- phydev->lp_advertising, lpadv & RTL_LPADV_10000FULL); -- linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, -- phydev->lp_advertising, lpadv & RTL_LPADV_5000FULL); -- linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, -- phydev->lp_advertising, lpadv & RTL_LPADV_2500FULL); -+ mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv); - } - - ret = rtlgen_read_status(phydev); diff --git a/target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch b/target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch deleted file mode 100644 index 8be1af6e505d1b..00000000000000 --- a/target/linux/generic/pending-6.1/728-net-phy-realtek-check-validity-of-10GbE-link-partner.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 929bb4d3cfbc7878326c0771a01a636d49c54b40 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 22 Apr 2023 01:25:39 +0100 -Subject: [PATCH 3/3] net: phy: realtek: check validity of 10GbE link-partner - advertisement - -Only use link-partner advertisement bits for 10GbE modes if they are -actually valid. Check LOCALOK and REMOTEOK bits and clear 10GbE modes -unless both of them are set. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -708,6 +708,10 @@ static int rtl822x_read_status(struct ph - if (lpadv < 0) - return lpadv; - -+ if (!(lpadv & MDIO_AN_10GBT_STAT_REMOK) || -+ !(lpadv & MDIO_AN_10GBT_STAT_LOCOK)) -+ lpadv = 0; -+ - mii_10gbt_stat_mod_linkmode_lpa_t(phydev->lp_advertising, lpadv); - } - diff --git a/target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch b/target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch deleted file mode 100644 index 92e7a8742af7fb..00000000000000 --- a/target/linux/generic/pending-6.1/729-net-phy-realtek-introduce-rtl822x_probe.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 9155098547fb1172d4fa536f3f6bc9d42f59d08c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sat, 22 Apr 2023 03:26:01 +0100 -Subject: [PATCH] net: phy: realtek: setup ALDPS on RTL822x - -Setup Link Down Power Saving Mode according the DTS property -just like for RTL821x 1GE PHYs. - -Signed-off-by: Daniel Golle ---- - drivers/net/phy/realtek.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -62,6 +62,10 @@ - #define RTL8221B_SERDES_OPTION_MODE_2500BASEX 2 - #define RTL8221B_SERDES_OPTION_MODE_HISGMII 3 - -+#define RTL8221B_PHYCR1 0xa430 -+#define RTL8221B_PHYCR1_ALDPS_EN BIT(2) -+#define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12) -+ - #define RTL8366RB_POWER_SAVE 0x15 - #define RTL8366RB_POWER_SAVE_ON BIT(12) - -@@ -750,6 +754,25 @@ static int rtl8226_match_phy_device(stru - rtlgen_supports_2_5gbps(phydev); - } - -+static int rtl822x_probe(struct phy_device *phydev) -+{ -+ struct device *dev = &phydev->mdio.dev; -+ int val; -+ -+ val = phy_read_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1); -+ if (val < 0) -+ return val; -+ -+ if (of_property_read_bool(dev->of_node, "realtek,aldps-enable")) -+ val |= RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN; -+ else -+ val &= ~(RTL8221B_PHYCR1_ALDPS_EN | RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN); -+ -+ phy_write_mmd(phydev, RTL8221B_MMD_SERDES_CTRL, RTL8221B_PHYCR1, val); -+ -+ return 0; -+} -+ - static int rtlgen_resume(struct phy_device *phydev) - { - int ret = genphy_resume(phydev); -@@ -1061,6 +1084,7 @@ static struct phy_driver realtek_drvs[] - .name = "RTL8226-CG 2.5Gbps PHY", - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, -+ .probe = rtl822x_probe, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, -@@ -1072,6 +1096,7 @@ static struct phy_driver realtek_drvs[] - .name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY", - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, -+ .probe = rtl822x_probe, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, -@@ -1084,6 +1109,7 @@ static struct phy_driver realtek_drvs[] - .get_features = rtl822x_get_features, - .config_init = rtl8221b_config_init, - .config_aneg = rtl822x_config_aneg, -+ .probe = rtl822x_probe, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, -@@ -1096,6 +1122,7 @@ static struct phy_driver realtek_drvs[] - .get_features = rtl822x_get_features, - .config_aneg = rtl822x_config_aneg, - .config_init = rtl8221b_config_init, -+ .probe = rtl822x_probe, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, - .resume = rtlgen_resume, diff --git a/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch b/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch deleted file mode 100644 index 05edcc8bf43cb6..00000000000000 --- a/target/linux/generic/pending-6.1/730-net-phy-realtek-detect-early-version-of-RTL8221B.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0de82310d2b32e78ff79d42c08b1122a6ede3778 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Sun, 30 Apr 2023 00:15:41 +0100 -Subject: [PATCH] net: phy: realtek: detect early version of RTL8221B - -Early versions (?) of the RTL8221B PHY cannot be identified in a regular -Clause-45 bus scan as the PHY doesn't report the implemented MMDs -correctly but returns 0 instead. -Implement custom identify function using the PKGID instead of iterating -over the implemented MMDs. - -Signed-off-by: Daniel Golle - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -80,6 +80,7 @@ - - #define RTL_GENERIC_PHYID 0x001cc800 - #define RTL_8211FVD_PHYID 0x001cc878 -+#define RTL_8221B_VB_CG_PHYID 0x001cc849 - - MODULE_DESCRIPTION("Realtek PHY driver"); - MODULE_AUTHOR("Johnson Leung"); -@@ -754,6 +755,38 @@ static int rtl8226_match_phy_device(stru - rtlgen_supports_2_5gbps(phydev); - } - -+static int rtl8221b_vb_cg_match_phy_device(struct phy_device *phydev) -+{ -+ int val; -+ u32 id; -+ -+ if (phydev->mdio.bus->probe_capabilities >= MDIOBUS_C45) { -+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID1); -+ if (val < 0) -+ return 0; -+ -+ id = val << 16; -+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PKGID2); -+ if (val < 0) -+ return 0; -+ -+ id |= val; -+ } else { -+ val = phy_read(phydev, MII_PHYSID1); -+ if (val < 0) -+ return 0; -+ -+ id = val << 16; -+ val = phy_read(phydev, MII_PHYSID2); -+ if (val < 0) -+ return 0; -+ -+ id |= val; -+ } -+ -+ return (id == RTL_8221B_VB_CG_PHYID); -+} -+ - static int rtl822x_probe(struct phy_device *phydev) - { - struct device *dev = &phydev->mdio.dev; -@@ -1104,7 +1137,7 @@ static struct phy_driver realtek_drvs[] - .write_page = rtl821x_write_page, - .soft_reset = genphy_soft_reset, - }, { -- PHY_ID_MATCH_EXACT(0x001cc849), -+ .match_phy_device = rtl8221b_vb_cg_match_phy_device, - .name = "RTL8221B-VB-CG 2.5Gbps PHY", - .get_features = rtl822x_get_features, - .config_init = rtl8221b_config_init, diff --git a/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch b/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch deleted file mode 100644 index f3725bf7d35bfb..00000000000000 --- a/target/linux/generic/pending-6.1/731-net-permit-ieee80211_ptr-even-with-no-CFG82111-suppo.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 686c603f67ae87bf21a61b5e4b1564443f41c3ee Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 20 Oct 2022 03:34:43 +0200 -Subject: [PATCH] net: permit ieee80211_ptr even with no CFG82111 support - -Introduce a new flag CONFIG_CFG80211_HEADERS to compile in ieee80211_ptr -even if CFG80211 support is not compiled in. This is needed for the -backports project and for any downstream wireless driver that loads in -the kernel dynamically. - -Signed-off-by: Christian Marangi ---- - include/linux/netdevice.h | 2 +- - net/batman-adv/hard-interface.c | 2 +- - net/wireless/Kconfig | 4 ++++ - 3 files changed, 6 insertions(+), 2 deletions(-) - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -2190,7 +2190,7 @@ struct net_device { - #if IS_ENABLED(CONFIG_AX25) - void *ax25_ptr; - #endif --#if IS_ENABLED(CONFIG_CFG80211) -+#if IS_ENABLED(CONFIG_CFG80211_HEADERS) - struct wireless_dev *ieee80211_ptr; - #endif - #if IS_ENABLED(CONFIG_IEEE802154) || IS_ENABLED(CONFIG_6LOWPAN) ---- a/net/batman-adv/hard-interface.c -+++ b/net/batman-adv/hard-interface.c -@@ -308,7 +308,7 @@ static bool batadv_is_cfg80211_netdev(st - if (!net_device) - return false; - --#if IS_ENABLED(CONFIG_CFG80211) -+#if IS_ENABLED(CONFIG_CFG80211_HEADERS) - /* cfg80211 drivers have to set ieee80211_ptr */ - if (net_device->ieee80211_ptr) - return true; ---- a/net/wireless/Kconfig -+++ b/net/wireless/Kconfig -@@ -26,6 +26,7 @@ config CFG80211 - # using a different algorithm, though right now they shouldn't - # (this is here rather than below to allow it to be a module) - select CRYPTO_SHA256 if CFG80211_USE_KERNEL_REGDB_KEYS -+ select CFG80211_HEADERS - help - cfg80211 is the Linux wireless LAN (802.11) configuration API. - Enable this if you have a wireless device. -@@ -36,6 +37,9 @@ config CFG80211 - - When built as a module it will be called cfg80211. - -+config CFG80211_HEADERS -+ bool "cfg80211 - headers support" -+ - if CFG80211 - - config NL80211_TESTMODE diff --git a/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch deleted file mode 100644 index decf647bce9eda..00000000000000 --- a/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From: Felix Fietkau -Date: Thu, 27 Oct 2022 23:39:52 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code - on mt7621 - -Avoid some branches in the hot path on low-end devices with limited CPU power, -and reduce code size - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -1326,6 +1326,22 @@ struct mtk_mac { - /* the struct describing the SoC. these are declared in the soc_xyz.c files */ - extern const struct of_device_id of_mtk_match[]; - -+#ifdef CONFIG_SOC_MT7621 -+static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) -+{ -+ return true; -+} -+ -+static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth) -+{ -+ return false; -+} -+ -+static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth) -+{ -+ return false; -+} -+#else - static inline bool mtk_is_netsys_v1(struct mtk_eth *eth) - { - return eth->soc->version == 1; -@@ -1340,6 +1356,7 @@ static inline bool mtk_is_netsys_v3_or_g - { - return eth->soc->version > 2; - } -+#endif - - static inline struct mtk_foe_entry * - mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash) diff --git a/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch b/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch deleted file mode 100644 index 600109a9505099..00000000000000 --- a/target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch +++ /dev/null @@ -1,94 +0,0 @@ -From: Felix Fietkau -Date: Thu, 3 Nov 2022 12:38:49 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: work around issue with sending - small fragments - -When lots of frames are sent with a number of very small fragments, an -internal FIFO can overflow, causing the DMA engine to lock up lock up and -transmit attempts time out. - -Fix this on MT7986 by increasing the reserved FIFO space. -Fix this on older chips by detecting the presence of small fragments and use -skb_gso_segment + skb_linearize to deal with them. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -1561,12 +1561,28 @@ static void mtk_wake_queue(struct mtk_et - } - } - -+static bool mtk_skb_has_small_frag(struct sk_buff *skb) -+{ -+ int min_size = 16; -+ int i; -+ -+ if (skb_headlen(skb) < min_size) -+ return true; -+ -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -+ if (skb_frag_size(&skb_shinfo(skb)->frags[i]) < min_size) -+ return true; -+ -+ return false; -+} -+ - static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_eth *eth = mac->hw; - struct mtk_tx_ring *ring = ð->tx_ring; - struct net_device_stats *stats = &dev->stats; -+ struct sk_buff *segs, *next; - bool gso = false; - int tx_num; - -@@ -1588,6 +1604,18 @@ static netdev_tx_t mtk_start_xmit(struct - return NETDEV_TX_BUSY; - } - -+ if (mtk_is_netsys_v1(eth) && -+ skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) { -+ segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO); -+ if (IS_ERR(segs)) -+ goto drop; -+ -+ if (segs) { -+ consume_skb(skb); -+ skb = segs; -+ } -+ } -+ - /* TSO: fill MSS info in tcp checksum field */ - if (skb_is_gso(skb)) { - if (skb_cow_head(skb, 0)) { -@@ -1603,8 +1631,14 @@ static netdev_tx_t mtk_start_xmit(struct - } - } - -- if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) -- goto drop; -+ skb_list_walk_safe(skb, skb, next) { -+ if ((mtk_is_netsys_v1(eth) && -+ mtk_skb_has_small_frag(skb) && skb_linearize(skb)) || -+ mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) { -+ stats->tx_dropped++; -+ dev_kfree_skb_any(skb); -+ } -+ } - - if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) - netif_tx_stop_all_queues(dev); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -268,7 +268,7 @@ - #define MTK_CHK_DDONE_EN BIT(28) - #define MTK_DMAD_WR_WDONE BIT(26) - #define MTK_WCOMP_EN BIT(24) --#define MTK_RESV_BUF (0x40 << 16) -+#define MTK_RESV_BUF (0x80 << 16) - #define MTK_MUTLI_CNT (0x4 << 12) - #define MTK_LEAKY_BUCKET_EN BIT(11) - diff --git a/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch b/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch deleted file mode 100644 index 11a81dd0bfdc9b..00000000000000 --- a/target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Felix Fietkau -Date: Fri, 28 Oct 2022 12:54:48 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: set NETIF_F_ALL_TSO - -Significantly improves performance by avoiding unnecessary segmentation - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -47,8 +47,7 @@ - #define MTK_HW_FEATURES (NETIF_F_IP_CSUM | \ - NETIF_F_RXCSUM | \ - NETIF_F_HW_VLAN_CTAG_TX | \ -- NETIF_F_SG | NETIF_F_TSO | \ -- NETIF_F_TSO6 | \ -+ NETIF_F_SG | NETIF_F_ALL_TSO | \ - NETIF_F_IPV6_CSUM |\ - NETIF_F_HW_TC) - #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM) diff --git a/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch b/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch deleted file mode 100644 index aa8607541731b7..00000000000000 --- a/target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Felix Fietkau -Date: Wed, 29 Mar 2023 16:02:54 +0200 -Subject: [PATCH] net: ethernet: mtk_eth_soc: fix remaining throughput - regression - -Based on further tests, it seems that the QDMA shaper is not able to -perform shaping close to the MAC link rate without throughput loss. -This cannot be compensated by increasing the shaping rate, so it seems -to be an internal limit. - -Fix the remaining throughput regression by detecting that condition and -limiting shaping to ports with lower link speed. - -This patch intentionally ignores link speed gain from TRGMII, because -even on such links, shaping to 1000 Mbit/s incurs some throughput -degradation. - -Fixes: f63959c7eec3 ("net: ethernet: mtk_eth_soc: implement multi-queue support for per-port queues") -Reported-by: Frank Wunderlich -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -766,6 +766,7 @@ static void mtk_mac_link_up(struct phyli - MAC_MCR_FORCE_RX_FC); - - /* Configure speed */ -+ mac->speed = speed; - switch (speed) { - case SPEED_2500: - case SPEED_1000: -@@ -3347,6 +3348,9 @@ found: - if (dp->index >= MTK_QDMA_NUM_QUEUES) - return NOTIFY_DONE; - -+ if (mac->speed > 0 && mac->speed <= s.base.speed) -+ s.base.speed = 0; -+ - mtk_set_queue_speed(eth, dp->index + 3, s.base.speed); - - return NOTIFY_DONE; diff --git a/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch b/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch deleted file mode 100644 index 61042c1ad0f8cf..00000000000000 --- a/target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Felix Fietkau -Date: Tue, 27 Dec 2022 15:02:51 +0100 -Subject: [PATCH] net: ethernet: mtk_eth_soc: ppe: fix L2 offloading with DSA - untagging offload enabled - -Check for skb metadata in order to detect the case where the DSA header is not -present. - -Fixes: 2d7605a72906 ("net: ethernet: mtk_eth_soc: enable hardware DSA untagging") -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/ethernet/mediatek/mtk_ppe.c -+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include "mtk_eth_soc.h" - #include "mtk_ppe.h" -@@ -829,7 +830,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe - skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK) - goto out; - -- tag += 4; -+ if (!skb_metadata_dst(skb)) -+ tag += 4; -+ - if (get_unaligned_be16(tag) != ETH_P_8021Q) - break; - diff --git a/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch deleted file mode 100644 index 2b379c915867d9..00000000000000 --- a/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch +++ /dev/null @@ -1,936 +0,0 @@ -From d5e337e7aecc2e1cc9e96768062610adb95f8f72 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 12 Dec 2023 03:51:14 +0000 -Subject: [PATCH] net: ethernet: mtk_eth_soc: add paths and SerDes modes for - MT7988 - -MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to -connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R, -2500Base-X, 1000Base-X and Cisco SGMII interface modes. - -Implement support for configuring for the new paths to SerDes interfaces -and the internal 2.5G PHY. - -Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and -setup the new PHYA on MT7988 to access the also still existing old -LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface -modes. - -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_eth_path.c | 122 +++++++- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 292 +++++++++++++++++-- - drivers/net/ethernet/mediatek/mtk_eth_soc.h | 107 ++++++- - 3 files changed, 470 insertions(+), 51 deletions(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c -@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64 - return "gmac2_rgmii"; - case MTK_ETH_PATH_GMAC2_SGMII: - return "gmac2_sgmii"; -+ case MTK_ETH_PATH_GMAC2_2P5GPHY: -+ return "gmac2_2p5gphy"; - case MTK_ETH_PATH_GMAC2_GEPHY: - return "gmac2_gephy"; -+ case MTK_ETH_PATH_GMAC3_SGMII: -+ return "gmac3_sgmii"; - case MTK_ETH_PATH_GDM1_ESW: - return "gdm1_esw"; -+ case MTK_ETH_PATH_GMAC1_USXGMII: -+ return "gmac1_usxgmii"; -+ case MTK_ETH_PATH_GMAC2_USXGMII: -+ return "gmac2_usxgmii"; -+ case MTK_ETH_PATH_GMAC3_USXGMII: -+ return "gmac3_usxgmii"; - default: - return "unknown path"; - } -@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(stru - return 0; - } - -+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path) -+{ -+ int ret; -+ -+ if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) { -+ ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2); -+ if (ret) -+ return ret; -+ -+ /* Setup mux to 2p5g PHY */ -+ ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL); -+ if (ret) -+ return ret; -+ -+ dev_dbg(eth->dev, "path %s in %s updated\n", -+ mtk_eth_path_name(path), __func__); -+ } -+ -+ return 0; -+} -+ - static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; -@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_ - return 0; - } - --static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path) -+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path) -+{ -+ unsigned int val = 0; -+ bool updated = true; -+ int mac_id = 0; -+ -+ /* Disable SYSCFG1 SGMII */ -+ regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val); -+ -+ switch (path) { -+ case MTK_ETH_PATH_GMAC1_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2; -+ mac_id = MTK_GMAC1_ID; -+ break; -+ case MTK_ETH_PATH_GMAC2_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2; -+ mac_id = MTK_GMAC2_ID; -+ break; -+ case MTK_ETH_PATH_GMAC3_USXGMII: -+ val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2; -+ mac_id = MTK_GMAC3_ID; -+ break; -+ default: -+ updated = false; -+ }; -+ -+ if (updated) { -+ regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0, -+ SYSCFG0_SGMII_MASK, val); -+ -+ if (mac_id == MTK_GMAC2_ID) -+ regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, -+ MUX_G2_USXGMII_SEL); -+ } -+ -+ dev_dbg(eth->dev, "path %s in %s updated = %d\n", -+ mtk_eth_path_name(path), __func__, updated); -+ -+ return 0; -+} -+ -+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path) - { - unsigned int val = 0; - bool updated = true; -@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii - case MTK_ETH_PATH_GMAC2_SGMII: - val |= SYSCFG0_SGMII_GMAC2_V2; - break; -+ case MTK_ETH_PATH_GMAC3_SGMII: -+ val |= SYSCFG0_SGMII_GMAC3_V2; -+ break; - default: - updated = false; - } -@@ -210,13 +285,25 @@ static const struct mtk_eth_muxc mtk_eth - .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY, - .set_path = set_mux_u3_gmac2_to_qphy, - }, { -+ .name = "mux_gmac2_to_2p5gphy", -+ .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY, -+ .set_path = set_mux_gmac2_to_2p5gphy, -+ }, { - .name = "mux_gmac1_gmac2_to_sgmii_rgmii", - .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII, - .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii, - }, { - .name = "mux_gmac12_to_gephy_sgmii", - .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII, -- .set_path = set_mux_gmac12_to_gephy_sgmii, -+ .set_path = set_mux_gmac123_to_gephy_sgmii, -+ }, { -+ .name = "mux_gmac123_to_gephy_sgmii", -+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII, -+ .set_path = set_mux_gmac123_to_gephy_sgmii, -+ }, { -+ .name = "mux_gmac123_to_usxgmii", -+ .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII, -+ .set_path = set_mux_gmac123_to_usxgmii, - }, - }; - -@@ -249,12 +336,39 @@ out: - return err; - } - -+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id) -+{ -+ u64 path; -+ -+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_USXGMII : -+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_USXGMII : -+ MTK_ETH_PATH_GMAC3_USXGMII; -+ -+ /* Setup proper MUXes along the path */ -+ return mtk_eth_mux_setup(eth, path); -+} -+ - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id) - { - u64 path; - -- path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII : -- MTK_ETH_PATH_GMAC2_SGMII; -+ path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII : -+ (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII : -+ MTK_ETH_PATH_GMAC3_SGMII; -+ -+ /* Setup proper MUXes along the path */ -+ return mtk_eth_mux_setup(eth, path); -+} -+ -+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id) -+{ -+ u64 path = 0; -+ -+ if (mac_id == MTK_GMAC2_ID) -+ path = MTK_ETH_PATH_GMAC2_2P5GPHY; -+ -+ if (!path) -+ return -EINVAL; - - /* Setup proper MUXes along the path */ - return mtk_eth_mux_setup(eth, path); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -21,6 +21,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -258,12 +260,8 @@ static const char * const mtk_clks_sourc - "ethwarp_wocpu2", - "ethwarp_wocpu1", - "ethwarp_wocpu0", -- "top_usxgmii0_sel", -- "top_usxgmii1_sel", - "top_sgm0_sel", - "top_sgm1_sel", -- "top_xfi_phy0_xtal_sel", -- "top_xfi_phy1_xtal_sel", - "top_eth_gmii_sel", - "top_eth_refck_50m_sel", - "top_eth_sys_200m_sel", -@@ -475,6 +473,30 @@ static void mtk_setup_bridge_switch(stru - MTK_GSW_CFG); - } - -+static bool mtk_check_gmac23_idle(struct mtk_mac *mac) -+{ -+ u32 mac_fsm, gdm_fsm; -+ -+ mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id)); -+ -+ switch (mac->id) { -+ case MTK_GMAC2_ID: -+ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM); -+ break; -+ case MTK_GMAC3_ID: -+ gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM); -+ break; -+ default: -+ return true; -+ }; -+ -+ if ((mac_fsm & 0xFFFF0000) == 0x01010000 && -+ (gdm_fsm & 0xFFFF0000) == 0x00000000) -+ return true; -+ -+ return false; -+} -+ - static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config, - phy_interface_t interface) - { -@@ -483,6 +505,21 @@ static struct phylink_pcs *mtk_mac_selec - struct mtk_eth *eth = mac->hw; - unsigned int sid; - -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ switch (interface) { -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ case PHY_INTERFACE_MODE_SGMII: -+ return mac->sgmii_pcs; -+ case PHY_INTERFACE_MODE_5GBASER: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_USXGMII: -+ return mac->usxgmii_pcs; -+ default: -+ return NULL; -+ } -+ } -+ - if (interface == PHY_INTERFACE_MODE_SGMII || - phy_interface_mode_is_8023z(interface)) { - sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ? -@@ -544,7 +581,22 @@ static void mtk_mac_config(struct phylin - goto init_err; - } - break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_5GBASER: -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) { -+ err = mtk_gmac_usxgmii_path_setup(eth, mac->id); -+ if (err) -+ goto init_err; -+ } -+ break; - case PHY_INTERFACE_MODE_INTERNAL: -+ if (mac->id == MTK_GMAC2_ID && -+ MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) { -+ err = mtk_gmac_2p5gphy_path_setup(eth, mac->id); -+ if (err) -+ goto init_err; -+ } - break; - default: - goto err_phy; -@@ -599,8 +651,6 @@ static void mtk_mac_config(struct phylin - val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id); - val |= SYSCFG0_GE_MODE(ge_mode, mac->id); - regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val); -- -- mac->interface = state->interface; - } - - /* SGMII */ -@@ -617,21 +667,40 @@ static void mtk_mac_config(struct phylin - - /* Save the syscfg0 value for mac_finish */ - mac->syscfg0 = val; -- } else if (phylink_autoneg_inband(mode)) { -+ } else if (state->interface != PHY_INTERFACE_MODE_USXGMII && -+ state->interface != PHY_INTERFACE_MODE_10GBASER && -+ state->interface != PHY_INTERFACE_MODE_5GBASER && -+ phylink_autoneg_inband(mode)) { - dev_err(eth->dev, -- "In-band mode not supported in non SGMII mode!\n"); -+ "In-band mode not supported in non-SerDes modes!\n"); - return; - } - - /* Setup gmac */ -- if (mtk_is_netsys_v3_or_greater(eth) && -- mac->interface == PHY_INTERFACE_MODE_INTERNAL) { -- mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); -- mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); -+ if (mtk_is_netsys_v3_or_greater(eth)) { -+ if (mtk_interface_mode_is_xgmii(state->interface)) { -+ mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id)); -+ mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id)); -+ -+ if (mac->id == MTK_GMAC1_ID) -+ mtk_setup_bridge_switch(eth); -+ } else { -+ mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id)); - -- mtk_setup_bridge_switch(eth); -+ /* FIXME: In current hardware design, we have to reset FE -+ * when swtiching XGDM to GDM. Therefore, here trigger an SER -+ * to let GDM go back to the initial state. -+ */ -+ if ((mtk_interface_mode_is_xgmii(mac->interface) || -+ mac->interface == PHY_INTERFACE_MODE_NA) && -+ !mtk_check_gmac23_idle(mac) && -+ !test_bit(MTK_RESETTING, ð->state)) -+ schedule_work(ð->pending_work); -+ } - } - -+ mac->interface = state->interface; -+ - return; - - err_phy: -@@ -644,6 +713,18 @@ init_err: - mac->id, phy_modes(state->interface), err); - } - -+static int mtk_mac_prepare(struct phylink_config *config, unsigned int mode, -+ phy_interface_t interface) -+{ -+ struct mtk_mac *mac = container_of(config, struct mtk_mac, -+ phylink_config); -+ -+ if (mac->pextp && mac->interface != interface) -+ phy_reset(mac->pextp); -+ -+ return 0; -+} -+ - static int mtk_mac_finish(struct phylink_config *config, unsigned int mode, - phy_interface_t interface) - { -@@ -652,6 +733,10 @@ static int mtk_mac_finish(struct phylink - struct mtk_eth *eth = mac->hw; - u32 mcr_cur, mcr_new; - -+ /* Setup PMA/PMD */ -+ if (mac->pextp) -+ phy_set_mode_ext(mac->pextp, PHY_MODE_ETHERNET, interface); -+ - /* Enable SGMII */ - if (interface == PHY_INTERFACE_MODE_SGMII || - phy_interface_mode_is_8023z(interface)) -@@ -676,10 +761,14 @@ static void mtk_mac_link_down(struct phy - { - struct mtk_mac *mac = container_of(config, struct mtk_mac, - phylink_config); -- u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); - -- mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK); -- mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); -+ if (!mtk_interface_mode_is_xgmii(interface)) { -+ mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK, 0, MTK_MAC_MCR(mac->id)); -+ if (mtk_is_netsys_v3_or_greater(mac->hw)) -+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id)); -+ } else if (mtk_is_netsys_v3_or_greater(mac->hw) && mac->id != MTK_GMAC1_ID) { -+ mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id)); -+ } - } - - static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx, -@@ -751,13 +840,11 @@ static void mtk_set_queue_speed(struct m - mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs); - } - --static void mtk_mac_link_up(struct phylink_config *config, -- struct phy_device *phy, -- unsigned int mode, phy_interface_t interface, -- int speed, int duplex, bool tx_pause, bool rx_pause) -+static void mtk_gdm_mac_link_up(struct mtk_mac *mac, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) - { -- struct mtk_mac *mac = container_of(config, struct mtk_mac, -- phylink_config); - u32 mcr; - - mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id)); -@@ -791,9 +878,63 @@ static void mtk_mac_link_up(struct phyli - mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); - } - -+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ u32 mcr, force_link = 0; -+ -+ if (mac->id == MTK_GMAC1_ID) -+ return; -+ -+ /* Eliminate the interference(before link-up) caused by PHY noise */ -+ mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id)); -+ mdelay(20); -+ mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id)); -+ -+ if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID) -+ force_link = MTK_XGMAC_FORCE_LINK(mac->id); -+ -+ mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id)); -+ -+ mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id)); -+ mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE); -+ /* Configure pause modes - -+ * phylink will avoid these for half duplex -+ */ -+ if (tx_pause) -+ mcr |= XMAC_MCR_FORCE_TX_FC; -+ if (rx_pause) -+ mcr |= XMAC_MCR_FORCE_RX_FC; -+ -+ mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id)); -+} -+ -+static void mtk_mac_link_up(struct phylink_config *config, -+ struct phy_device *phy, -+ unsigned int mode, phy_interface_t interface, -+ int speed, int duplex, bool tx_pause, bool rx_pause) -+{ -+ struct mtk_mac *mac = container_of(config, struct mtk_mac, -+ phylink_config); -+ -+ if (mtk_is_netsys_v3_or_greater(mac->hw) && mtk_interface_mode_is_xgmii(interface)) -+ mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex, -+ tx_pause, rx_pause); -+ else -+ mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex, -+ tx_pause, rx_pause); -+ -+ /* Repeat pextp setup to tune link */ -+ if (mac->pextp) -+ phy_set_mode_ext(mac->pextp, PHY_MODE_ETHERNET, interface); -+} -+ - static const struct phylink_mac_ops mtk_phylink_ops = { - .mac_select_pcs = mtk_mac_select_pcs, - .mac_config = mtk_mac_config, -+ .mac_prepare = mtk_mac_prepare, - .mac_finish = mtk_mac_finish, - .mac_link_down = mtk_mac_link_down, - .mac_link_up = mtk_mac_link_up, -@@ -3372,6 +3513,9 @@ static int mtk_open(struct net_device *d - struct mtk_eth *eth = mac->hw; - int i, err; - -+ if (mac->pextp) -+ phy_power_on(mac->pextp); -+ - err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0); - if (err) { - netdev_err(dev, "%s: could not attach PHY: %d\n", __func__, -@@ -3500,6 +3644,9 @@ static int mtk_stop(struct net_device *d - for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) - mtk_ppe_stop(eth->ppe[i]); - -+ if (mac->pextp) -+ phy_power_off(mac->pextp); -+ - return 0; - } - -@@ -4497,6 +4644,7 @@ static const struct net_device_ops mtk_n - static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) - { - const __be32 *_id = of_get_property(np, "reg", NULL); -+ struct device_node *pcs_np; - phy_interface_t phy_mode; - struct phylink *phylink; - struct mtk_mac *mac; -@@ -4532,16 +4680,41 @@ static int mtk_add_mac(struct mtk_eth *e - mac->id = id; - mac->hw = eth; - mac->of_node = np; -+ pcs_np = of_parse_phandle(mac->of_node, "pcs-handle", 0); -+ if (pcs_np) { -+ mac->sgmii_pcs = mtk_pcs_lynxi_get(eth->dev, pcs_np); -+ if (IS_ERR(mac->sgmii_pcs)) { -+ if (PTR_ERR(mac->sgmii_pcs) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; - -- err = of_get_ethdev_address(mac->of_node, eth->netdev[id]); -- if (err == -EPROBE_DEFER) -- return err; -+ dev_err(eth->dev, "cannot select SGMII PCS, error %ld\n", -+ PTR_ERR(mac->sgmii_pcs)); -+ return PTR_ERR(mac->sgmii_pcs); -+ } -+ } - -- if (err) { -- /* If the mac address is invalid, use random mac address */ -- eth_hw_addr_random(eth->netdev[id]); -- dev_err(eth->dev, "generated random MAC address %pM\n", -- eth->netdev[id]->dev_addr); -+ pcs_np = of_parse_phandle(mac->of_node, "pcs-handle", 1); -+ if (pcs_np) { -+ mac->usxgmii_pcs = mtk_usxgmii_pcs_get(eth->dev, pcs_np); -+ if (IS_ERR(mac->usxgmii_pcs)) { -+ if (PTR_ERR(mac->usxgmii_pcs) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ -+ dev_err(eth->dev, "cannot select USXGMII PCS, error %ld\n", -+ PTR_ERR(mac->usxgmii_pcs)); -+ return PTR_ERR(mac->usxgmii_pcs); -+ } -+ } -+ -+ if (mtk_is_netsys_v3_or_greater(eth) && (mac->sgmii_pcs || mac->usxgmii_pcs)) { -+ mac->pextp = devm_of_phy_get(eth->dev, mac->of_node, NULL); -+ if (IS_ERR(mac->pextp)) { -+ if (PTR_ERR(mac->pextp) != -EPROBE_DEFER) -+ dev_err(eth->dev, "cannot get PHY, error %ld\n", -+ PTR_ERR(mac->pextp)); -+ -+ return PTR_ERR(mac->pextp); -+ } - } - - memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip)); -@@ -4615,8 +4788,21 @@ static int mtk_add_mac(struct mtk_eth *e - phy_interface_zero(mac->phylink_config.supported_interfaces); - __set_bit(PHY_INTERFACE_MODE_INTERNAL, - mac->phylink_config.supported_interfaces); -+ } else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) { -+ mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD; -+ __set_bit(PHY_INTERFACE_MODE_5GBASER, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_10GBASER, -+ mac->phylink_config.supported_interfaces); -+ __set_bit(PHY_INTERFACE_MODE_USXGMII, -+ mac->phylink_config.supported_interfaces); - } - -+ if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) && -+ id == MTK_GMAC2_ID) -+ __set_bit(PHY_INTERFACE_MODE_INTERNAL, -+ mac->phylink_config.supported_interfaces); -+ - phylink = phylink_create(&mac->phylink_config, - of_fwnode_handle(mac->of_node), - phy_mode, &mtk_phylink_ops); -@@ -4661,6 +4847,26 @@ free_netdev: - return err; - } - -+static int mtk_mac_assign_address(struct mtk_eth *eth, int i, bool test_defer_only) -+{ -+ int err = of_get_ethdev_address(eth->mac[i]->of_node, eth->netdev[i]); -+ -+ if (err == -EPROBE_DEFER) -+ return err; -+ -+ if (test_defer_only) -+ return 0; -+ -+ if (err) { -+ /* If the mac address is invalid, use random mac address */ -+ eth_hw_addr_random(eth->netdev[i]); -+ dev_err(eth->dev, "generated random MAC address %pM\n", -+ eth->netdev[i]); -+ } -+ -+ return 0; -+} -+ - void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev) - { - struct net_device *dev, *tmp; -@@ -4804,7 +5010,8 @@ static int mtk_probe(struct platform_dev - regmap_write(cci, 0, 3); - } - -- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { -+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII) && -+ !mtk_is_netsys_v3_or_greater(eth)) { - err = mtk_sgmii_init(eth); - - if (err) -@@ -4915,6 +5122,24 @@ static int mtk_probe(struct platform_dev - } - } - -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ if (!eth->netdev[i]) -+ continue; -+ -+ err = mtk_mac_assign_address(eth, i, true); -+ if (err) -+ goto err_deinit_hw; -+ } -+ -+ for (i = 0; i < MTK_MAX_DEVS; i++) { -+ if (!eth->netdev[i]) -+ continue; -+ -+ err = mtk_mac_assign_address(eth, i, false); -+ if (err) -+ goto err_deinit_hw; -+ } -+ - if (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_INT)) { - err = devm_request_irq(eth->dev, eth->irq[0], - mtk_handle_irq, 0, -@@ -5017,6 +5242,11 @@ static int mtk_remove(struct platform_de - mtk_stop(eth->netdev[i]); - mac = netdev_priv(eth->netdev[i]); - phylink_disconnect_phy(mac->phylink); -+ if (mac->sgmii_pcs) -+ mtk_pcs_lynxi_put(mac->sgmii_pcs); -+ -+ if (mac->usxgmii_pcs) -+ mtk_usxgmii_pcs_put(mac->usxgmii_pcs); - } - - mtk_wed_exit(); ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -502,6 +503,21 @@ - #define INTF_MODE_RGMII_1000 (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED) - #define INTF_MODE_RGMII_10_100 0 - -+/* XFI Mac control registers */ -+#define MTK_XMAC_BASE(x) (0x12000 + (((x) - 1) * 0x1000)) -+#define MTK_XMAC_MCR(x) (MTK_XMAC_BASE(x)) -+#define XMAC_MCR_TRX_DISABLE 0xf -+#define XMAC_MCR_FORCE_TX_FC BIT(5) -+#define XMAC_MCR_FORCE_RX_FC BIT(4) -+ -+/* XFI Mac logic reset registers */ -+#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10) -+#define XMAC_LOGIC_RST BIT(0) -+ -+/* XFI Mac count global control */ -+#define MTK_XMAC_CNT_CTRL(x) (MTK_XMAC_BASE(x) + 0x100) -+#define XMAC_GLB_CNTCLR BIT(0) -+ - /* GPIO port control registers for GMAC 2*/ - #define GPIO_OD33_CTRL8 0x4c0 - #define GPIO_BIAS_CTRL 0xed0 -@@ -527,6 +543,7 @@ - #define SYSCFG0_SGMII_GMAC2 ((3 << 8) & SYSCFG0_SGMII_MASK) - #define SYSCFG0_SGMII_GMAC1_V2 BIT(9) - #define SYSCFG0_SGMII_GMAC2_V2 BIT(8) -+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7) - - - /* ethernet subsystem clock register */ -@@ -565,6 +582,11 @@ - #define GEPHY_MAC_SEL BIT(1) - - /* Top misc registers */ -+#define TOP_MISC_NETSYS_PCS_MUX 0x84 -+#define NETSYS_PCS_MUX_MASK GENMASK(1, 0) -+#define MUX_G2_USXGMII_SEL BIT(1) -+#define MUX_HSGMII1_G1_SEL BIT(0) -+ - #define USB_PHY_SWITCH_REG 0x218 - #define QPHY_SEL_MASK GENMASK(1, 0) - #define SGMII_QPHY_SEL 0x2 -@@ -589,6 +611,8 @@ - #define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) - #define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) - -+/* Debug Purpose Register */ -+#define MTK_PSE_FQFC_CFG 0x100 - #define MTK_FE_CDM1_FSM 0x220 - #define MTK_FE_CDM2_FSM 0x224 - #define MTK_FE_CDM3_FSM 0x238 -@@ -597,6 +621,11 @@ - #define MTK_FE_CDM6_FSM 0x328 - #define MTK_FE_GDM1_FSM 0x228 - #define MTK_FE_GDM2_FSM 0x22C -+#define MTK_FE_GDM3_FSM 0x23C -+#define MTK_FE_PSE_FREE 0x240 -+#define MTK_FE_DROP_FQ 0x244 -+#define MTK_FE_DROP_FC 0x248 -+#define MTK_FE_DROP_PPE 0x24C - - #define MTK_MAC_FSM(x) (0x1010C + ((x) * 0x100)) - -@@ -721,12 +750,8 @@ enum mtk_clks_map { - MTK_CLK_ETHWARP_WOCPU2, - MTK_CLK_ETHWARP_WOCPU1, - MTK_CLK_ETHWARP_WOCPU0, -- MTK_CLK_TOP_USXGMII_SBUS_0_SEL, -- MTK_CLK_TOP_USXGMII_SBUS_1_SEL, - MTK_CLK_TOP_SGM_0_SEL, - MTK_CLK_TOP_SGM_1_SEL, -- MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL, -- MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL, - MTK_CLK_TOP_ETH_GMII_SEL, - MTK_CLK_TOP_ETH_REFCK_50M_SEL, - MTK_CLK_TOP_ETH_SYS_200M_SEL, -@@ -797,19 +822,9 @@ enum mtk_clks_map { - BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \ - BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \ - BIT_ULL(MTK_CLK_CRYPTO) | \ -- BIT_ULL(MTK_CLK_SGMII_TX_250M) | \ -- BIT_ULL(MTK_CLK_SGMII_RX_250M) | \ -- BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \ -- BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \ - BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \ - BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \ - BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \ -- BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \ -- BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \ -- BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \ -- BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \ -- BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \ -- BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \ - BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \ - BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \ - BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \ -@@ -943,6 +958,8 @@ enum mkt_eth_capabilities { - MTK_RGMII_BIT = 0, - MTK_TRGMII_BIT, - MTK_SGMII_BIT, -+ MTK_USXGMII_BIT, -+ MTK_2P5GPHY_BIT, - MTK_ESW_BIT, - MTK_GEPHY_BIT, - MTK_MUX_BIT, -@@ -963,8 +980,11 @@ enum mkt_eth_capabilities { - MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT, - MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT, - MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT, -+ MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT, - MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT, - MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT, -+ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT, -+ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT, - - /* PATH BITS */ - MTK_ETH_PATH_GMAC1_RGMII_BIT, -@@ -972,14 +992,21 @@ enum mkt_eth_capabilities { - MTK_ETH_PATH_GMAC1_SGMII_BIT, - MTK_ETH_PATH_GMAC2_RGMII_BIT, - MTK_ETH_PATH_GMAC2_SGMII_BIT, -+ MTK_ETH_PATH_GMAC2_2P5GPHY_BIT, - MTK_ETH_PATH_GMAC2_GEPHY_BIT, -+ MTK_ETH_PATH_GMAC3_SGMII_BIT, - MTK_ETH_PATH_GDM1_ESW_BIT, -+ MTK_ETH_PATH_GMAC1_USXGMII_BIT, -+ MTK_ETH_PATH_GMAC2_USXGMII_BIT, -+ MTK_ETH_PATH_GMAC3_USXGMII_BIT, - }; - - /* Supported hardware group on SoCs */ - #define MTK_RGMII BIT_ULL(MTK_RGMII_BIT) - #define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT) - #define MTK_SGMII BIT_ULL(MTK_SGMII_BIT) -+#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT) -+#define MTK_2P5GPHY BIT_ULL(MTK_2P5GPHY_BIT) - #define MTK_ESW BIT_ULL(MTK_ESW_BIT) - #define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT) - #define MTK_MUX BIT_ULL(MTK_MUX_BIT) -@@ -1002,10 +1029,16 @@ enum mkt_eth_capabilities { - BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT) - #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \ - BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT) -+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY \ -+ BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT) - #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \ - BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT) - #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \ - BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT) -+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \ -+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT) -+#define MTK_ETH_MUX_GMAC123_TO_USXGMII \ -+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT) - - /* Supported path present on SoCs */ - #define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT) -@@ -1013,8 +1046,13 @@ enum mkt_eth_capabilities { - #define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT) - #define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT) - #define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_2P5GPHY BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT) - #define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT) -+#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT) - #define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT) -+#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT) -+#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT) -+#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT) - - #define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII) - #define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) -@@ -1022,7 +1060,12 @@ enum mkt_eth_capabilities { - #define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII) - #define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII) - #define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY) -+#define MTK_GMAC2_2P5GPHY (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY) -+#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII) - #define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW) -+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII) -+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII) -+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII) - - /* MUXes present on SoCs */ - /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */ -@@ -1041,10 +1084,20 @@ enum mkt_eth_capabilities { - (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \ - MTK_SHARED_SGMII) - -+/* 2: GMAC2 -> XGMII */ -+#define MTK_MUX_GMAC2_TO_2P5GPHY \ -+ (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA) -+ - /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */ - #define MTK_MUX_GMAC12_TO_GEPHY_SGMII \ - (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX) - -+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \ -+ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX) -+ -+#define MTK_MUX_GMAC123_TO_USXGMII \ -+ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA) -+ - #define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) - - #define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \ -@@ -1076,8 +1129,12 @@ enum mkt_eth_capabilities { - MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \ - MTK_RSTCTRL_PPE1 | MTK_SRAM) - --#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \ -- MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) -+#define MT7988_CAPS (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \ -+ MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \ -+ MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \ -+ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \ -+ MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \ -+ MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM) - - struct mtk_tx_dma_desc_info { - dma_addr_t addr; -@@ -1314,6 +1371,9 @@ struct mtk_mac { - struct device_node *of_node; - struct phylink *phylink; - struct phylink_config phylink_config; -+ struct phylink_pcs *sgmii_pcs; -+ struct phylink_pcs *usxgmii_pcs; -+ struct phy *pextp; - struct mtk_eth *hw; - struct mtk_hw_stats *hw_stats; - __be32 hwlro_ip[MTK_MAX_LRO_IP_CNT]; -@@ -1437,6 +1497,19 @@ static inline u32 mtk_get_ib2_multicast_ - return MTK_FOE_IB2_MULTICAST; - } - -+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface) -+{ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_INTERNAL: -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_5GBASER: -+ return true; -+ default: -+ return false; -+ } -+} -+ - /* read the hardware status register */ - void mtk_stats_update_mac(struct mtk_mac *mac); - -@@ -1445,8 +1518,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne - u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg); - - int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id); -+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); - int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); -+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id); - - int mtk_eth_offload_init(struct mtk_eth *eth); - int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, diff --git a/target/linux/generic/pending-6.1/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch b/target/linux/generic/pending-6.1/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch deleted file mode 100644 index b598d15866efa4..00000000000000 --- a/target/linux/generic/pending-6.1/738-net-ethernet-mtk_eth_soc-set-coherent-mask-to-get-PP.patch +++ /dev/null @@ -1,46 +0,0 @@ -From dee3f591103910c8d8b2a6d57879ccd2a4be4b10 Mon Sep 17 00:00:00 2001 -Message-ID: -From: Daniel Golle -Date: Wed, 24 Jan 2024 03:19:49 +0000 -Subject: [PATCH net] net: ethernet: mtk_eth_soc: set coherent mask to get PPE - working -To: Felix Fietkau , - Sean Wang , - Mark Lee , - Lorenzo Bianconi , - David S. Miller , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Matthias Brugger , - AngeloGioacchino Del Regno , - Daniel Golle , - netdev@vger.kernel.org, - linux-kernel@vger.kernel.org, - linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org - -Set DMA coherent mask to 32-bit which makes PPE offloading engine start -working on BPi-R4 which got 4 GiB of RAM. - -Fixes: 2d75891ebc09 ("net: ethernet: mtk_eth_soc: support 36-bit DMA addressing on MT7988") -Suggested-by: Elad Yifee -Signed-off-by: Daniel Golle ---- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -4963,7 +4963,10 @@ static int mtk_probe(struct platform_dev - } - - if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) { -- err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); -+ err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(36)); -+ if (!err) -+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); -+ - if (err) { - dev_err(&pdev->dev, "Wrong DMA config\n"); - return -EINVAL; diff --git a/target/linux/generic/pending-6.1/739-01-dt-bindings-phy-mediatek-xfi-tphy-add-new-bindings.patch b/target/linux/generic/pending-6.1/739-01-dt-bindings-phy-mediatek-xfi-tphy-add-new-bindings.patch deleted file mode 100644 index 1f1c40b1d91589..00000000000000 --- a/target/linux/generic/pending-6.1/739-01-dt-bindings-phy-mediatek-xfi-tphy-add-new-bindings.patch +++ /dev/null @@ -1,136 +0,0 @@ -From patchwork Thu Feb 1 21:52:20 2024 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 13541842 -Date: Thu, 1 Feb 2024 21:52:20 +0000 -From: Daniel Golle -To: Bc-bocun Chen , - Steven Liu , - John Crispin , - Chunfeng Yun , - Vinod Koul , - Kishon Vijay Abraham I , - Rob Herring , - Krzysztof Kozlowski , - Conor Dooley , - Daniel Golle , - Qingfang Deng , - SkyLake Huang , - Matthias Brugger , - AngeloGioacchino Del Regno , - Philipp Zabel , - linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, - netdev@vger.kernel.org -Subject: [PATCH 1/2] dt-bindings: phy: mediatek,xfi-tphy: add new bindings -Message-ID: - <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org> -MIME-Version: 1.0 -Content-Disposition: inline -List-Id: Linux Phy Mailing list - -Add bindings for the MediaTek XFI T-PHY Ethernet SerDes PHY found in the -MediaTek MT7988 SoC which can operate at various interfaces modes: - -via USXGMII PCS: - * USXGMII - * 10GBase-R - * 5GBase-R - -via LynxI SGMII PCS: - * 2500Base-X - * 1000Base-X - * Cisco SGMII (MAC side) - -Signed-off-by: Daniel Golle ---- - .../bindings/phy/mediatek,xfi-tphy.yaml | 80 +++++++++++++++++++ - 1 file changed, 80 insertions(+) - create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-tphy.yaml -@@ -0,0 +1,80 @@ -+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/phy/mediatek,xfi-tphy.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: MediaTek XFI T-PHY -+ -+maintainers: -+ - Daniel Golle -+ -+description: -+ The MediaTek XFI SerDes T-PHY provides the physical SerDes lanes -+ used by the (10G/5G) USXGMII PCS and (1G/2.5G) LynxI PCS found in -+ MediaTek's 10G-capabale SoCs. -+ -+properties: -+ $nodename: -+ pattern: "^phy@[0-9a-f]+$" -+ -+ compatible: -+ const: mediatek,mt7988-xfi-tphy -+ -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ items: -+ - description: XFI PHY clock -+ - description: XFI register clock -+ -+ clock-names: -+ items: -+ - const: xfipll -+ - const: topxtal -+ -+ resets: -+ items: -+ - description: PEXTP reset -+ -+ mediatek,usxgmii-performance-errata: -+ $ref: /schemas/types.yaml#/definitions/flag -+ description: -+ One instance of the T-PHY on MT7988 suffers from a performance -+ problem in 10GBase-R mode which needs a work-around in the driver. -+ The work-around is enabled using this flag. -+ -+ "#phy-cells": -+ const: 0 -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - clock-names -+ - resets -+ - "#phy-cells" -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include -+ soc { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ -+ phy@11f20000 { -+ compatible = "mediatek,mt7988-xfi-tphy"; -+ reg = <0 0x11f20000 0 0x10000>; -+ clocks = <&xfi_pll CLK_XFIPLL_PLL_EN>, -+ <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>; -+ clock-names = "xfipll", "topxtal"; -+ resets = <&watchdog 14>; -+ mediatek,usxgmii-performance-errata; -+ #phy-cells = <0>; -+ }; -+ }; -+ -+... diff --git a/target/linux/generic/pending-6.1/739-02-phy-add-driver-for-MediaTek-XFI-T-PHY.patch b/target/linux/generic/pending-6.1/739-02-phy-add-driver-for-MediaTek-XFI-T-PHY.patch deleted file mode 100644 index 1aa36fcd3dc4f0..00000000000000 --- a/target/linux/generic/pending-6.1/739-02-phy-add-driver-for-MediaTek-XFI-T-PHY.patch +++ /dev/null @@ -1,498 +0,0 @@ -From patchwork Thu Feb 1 21:53:06 2024 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 13541843 -Date: Thu, 1 Feb 2024 21:53:06 +0000 -From: Daniel Golle -To: Bc-bocun Chen , - Chunfeng Yun , - Vinod Koul , - Kishon Vijay Abraham I , - Rob Herring , - Krzysztof Kozlowski , - Conor Dooley , - Daniel Golle , - Qingfang Deng , - SkyLake Huang , - Matthias Brugger , - AngeloGioacchino Del Regno , - Philipp Zabel , - linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org, linux-phy@lists.infradead.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, - netdev@vger.kernel.org -Subject: [PATCH 2/2] phy: add driver for MediaTek XFI T-PHY -Message-ID: - -References: - <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org> -MIME-Version: 1.0 -Content-Disposition: inline -In-Reply-To: - <702afb0c1246d95c90b22e57105304028bdd3083.1706823233.git.daniel@makrotopia.org> -List-Id: Linux Phy Mailing list - -Add driver for MediaTek's XFI T-PHY, 10 Gigabit/s Ethernet SerDes PHY -which can be found in the MT7988 SoC. - -The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of -PHY_INTERFACE_MODE_* corresponding to the supported modes: - - * USXGMII \ - * 10GBase-R }- USXGMII PCS - XGDM \ - * 5GBase-R / \ - }- Ethernet MAC - * 2500Base-X \ / - * 1000Base-X }- LynxI PCS - GDM / - * Cisco SGMII (MAC side) / - -In order to work-around a performance issue present on the first of -two XFI T-PHYs present in MT7988, special tuning is applied which can be -selected by adding the 'mediatek,usxgmii-performance-errata' property to -the device tree node. - -There is no documentation for most registers used for the -analog/tuning part, however, most of the registers have been partially -reverse-engineered from MediaTek's SDK implementation (an opaque -sequence of 32-bit register writes) and descriptions for all relevant -digital registers and bits such as resets and muxes have been supplied -by MediaTek. - -Signed-off-by: Daniel Golle ---- - MAINTAINERS | 1 + - drivers/phy/mediatek/Kconfig | 12 + - drivers/phy/mediatek/Makefile | 1 + - drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 392 ++++++++++++++++++++++++ - 4 files changed, 406 insertions(+) - create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c - ---- a/drivers/phy/mediatek/Kconfig -+++ b/drivers/phy/mediatek/Kconfig -@@ -13,6 +13,18 @@ config PHY_MTK_PCIE - callback for PCIe GEN3 port, it supports software efuse - initialization. - -+config PHY_MTK_XFI_TPHY -+ tristate "MediaTek XFI T-PHY Driver" -+ depends on ARCH_MEDIATEK || COMPILE_TEST -+ depends on OF && OF_ADDRESS -+ depends on HAS_IOMEM -+ select GENERIC_PHY -+ help -+ Say 'Y' here to add support for MediaTek XFI T-PHY driver. -+ The driver provides access to the Ethernet SerDes T-PHY supporting -+ 1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes -+ via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet. -+ - config PHY_MTK_TPHY - tristate "MediaTek T-PHY Driver" - depends on ARCH_MEDIATEK || COMPILE_TEST ---- a/drivers/phy/mediatek/Makefile -+++ b/drivers/phy/mediatek/Makefile -@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE) += phy-mtk-p - obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o - obj-$(CONFIG_PHY_MTK_UFS) += phy-mtk-ufs.o - obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o -+obj-$(CONFIG_PHY_MTK_XFI_TPHY) += phy-mtk-xfi-tphy.o - - phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o - phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o ---- /dev/null -+++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c -@@ -0,0 +1,393 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* MediaTek 10GE SerDes PHY driver -+ * -+ * Copyright (c) 2024 Daniel Golle -+ * Bc-bocun Chen -+ * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0 -+ * Copyright (c) 2022 MediaTek Inc. -+ * Author: Henry Yen -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MTK_XFI_TPHY_NUM_CLOCKS 2 -+ -+#define REG_DIG_GLB_70 0x0070 -+#define XTP_PCS_RX_EQ_IN_PROGRESS(x) FIELD_PREP(GENMASK(25, 24), (x)) -+#define XTP_PCS_MODE_MASK GENMASK(17, 16) -+#define XTP_PCS_MODE(x) FIELD_PREP(GENMASK(17, 16), (x)) -+#define XTP_PCS_RST_B BIT(15) -+#define XTP_FRC_PCS_RST_B BIT(14) -+#define XTP_PCS_PWD_SYNC_MASK GENMASK(13, 12) -+#define XTP_PCS_PWD_SYNC(x) FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x)) -+#define XTP_PCS_PWD_ASYNC_MASK GENMASK(11, 10) -+#define XTP_PCS_PWD_ASYNC(x) FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x)) -+#define XTP_FRC_PCS_PWD_ASYNC BIT(8) -+#define XTP_PCS_UPDT BIT(4) -+#define XTP_PCS_IN_FR_RG BIT(0) -+ -+#define REG_DIG_GLB_F4 0x00f4 -+#define XFI_DPHY_PCS_SEL BIT(0) -+#define XFI_DPHY_PCS_SEL_SGMII FIELD_PREP(XFI_DPHY_PCS_SEL, 1) -+#define XFI_DPHY_PCS_SEL_USXGMII FIELD_PREP(XFI_DPHY_PCS_SEL, 0) -+#define XFI_DPHY_AD_SGDT_FRC_EN BIT(5) -+ -+#define REG_DIG_LN_TRX_40 0x3040 -+#define XTP_LN_FRC_TX_DATA_EN BIT(29) -+#define XTP_LN_TX_DATA_EN BIT(28) -+ -+#define REG_DIG_LN_TRX_B0 0x30b0 -+#define XTP_LN_FRC_TX_MACCK_EN BIT(5) -+#define XTP_LN_TX_MACCK_EN BIT(4) -+ -+#define REG_ANA_GLB_D0 0x90d0 -+#define XTP_GLB_USXGMII_SEL_MASK GENMASK(3, 1) -+#define XTP_GLB_USXGMII_SEL(x) FIELD_PREP(GENMASK(3, 1), (x)) -+#define XTP_GLB_USXGMII_EN BIT(0) -+ -+struct mtk_xfi_tphy { -+ void __iomem *base; -+ struct device *dev; -+ struct reset_control *reset; -+ struct clk_bulk_data clocks[MTK_XFI_TPHY_NUM_CLOCKS]; -+ bool da_war; -+}; -+ -+static void mtk_xfi_tphy_write(struct mtk_xfi_tphy *xfi_tphy, u16 reg, -+ u32 value) -+{ -+ iowrite32(value, xfi_tphy->base + reg); -+} -+ -+static void mtk_xfi_tphy_rmw(struct mtk_xfi_tphy *xfi_tphy, u16 reg, -+ u32 clr, u32 set) -+{ -+ u32 val; -+ -+ val = ioread32(xfi_tphy->base + reg); -+ val &= ~clr; -+ val |= set; -+ iowrite32(val, xfi_tphy->base + reg); -+} -+ -+static void mtk_xfi_tphy_set(struct mtk_xfi_tphy *xfi_tphy, u16 reg, -+ u32 set) -+{ -+ mtk_xfi_tphy_rmw(xfi_tphy, reg, 0, set); -+} -+ -+static void mtk_xfi_tphy_clear(struct mtk_xfi_tphy *xfi_tphy, u16 reg, -+ u32 clr) -+{ -+ mtk_xfi_tphy_rmw(xfi_tphy, reg, clr, 0); -+} -+ -+static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy, -+ phy_interface_t interface) -+{ -+ bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX); -+ bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX || -+ interface == PHY_INTERFACE_MODE_SGMII); -+ bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER || -+ interface == PHY_INTERFACE_MODE_USXGMII); -+ bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER); -+ bool is_xgmii = (is_10g || is_5g); -+ -+ dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface)); -+ -+ /* Setup PLL setting */ -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x9024, 0x100000, is_10g ? 0x0 : 0x100000); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2020, 0x202000, is_5g ? 0x202000 : 0x0); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2030, 0x500, is_1g ? 0x0 : 0x500); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2034, 0xa00, is_1g ? 0x0 : 0xa00); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x2040, 0x340000, is_1g ? 0x200000 : -+ 0x140000); -+ -+ /* Setup RXFE BW setting */ -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50f0, 0xc10, is_1g ? 0x410 : -+ is_5g ? 0x800 : 0x400); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000); -+ -+ /* Setup RX CDR setting */ -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x506c, 0x30000, is_5g ? 0x0 : 0x30000); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5074, 0x180000, is_5g ? 0x180000 : 0x0); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5078, 0xf000400, is_5g ? 0x8000000 : -+ 0x7000400); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x507c, 0x5000500, is_5g ? 0x4000400 : -+ 0x1000100); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5080, 0x1410, is_1g ? 0x400 : -+ is_5g ? 0x1010 : 0x0); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5084, 0x30300, is_1g ? 0x30300 : -+ is_5g ? 0x30100 : -+ 0x100); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x5088, 0x60200, is_1g ? 0x20200 : -+ is_5g ? 0x40000 : -+ 0x20000); -+ -+ /* Setting RXFE adaptation range setting */ -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50ec, 0xa00, is_1g ? 0x200 : 0x800); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x50a8, 0xee0000, is_5g ? 0x800000 : -+ 0x6e0000); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x6004, 0x190000, is_5g ? 0x0 : 0x190000); -+ if (is_10g) -+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x01423342); -+ else if (is_5g) -+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00a132a1); -+ else if (is_2p5g) -+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x009c329c); -+ else -+ mtk_xfi_tphy_write(xfi_tphy, 0x00f8, 0x00fa32fa); -+ -+ /* Force SGDT_OUT off and select PCS */ -+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_F4, -+ XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL, -+ XFI_DPHY_AD_SGDT_FRC_EN | -+ (is_xgmii ? XFI_DPHY_PCS_SEL_USXGMII : -+ XFI_DPHY_PCS_SEL_SGMII)); -+ -+ -+ /* Force GLB_CKDET_OUT */ -+ mtk_xfi_tphy_set(xfi_tphy, 0x0030, 0xc00); -+ -+ /* Force AEQ on */ -+ mtk_xfi_tphy_write(xfi_tphy, REG_DIG_GLB_70, -+ XTP_PCS_RX_EQ_IN_PROGRESS(2) | -+ XTP_PCS_PWD_SYNC(2) | -+ XTP_PCS_PWD_ASYNC(2)); -+ -+ usleep_range(1, 5); -+ writel(XTP_LN_FRC_TX_DATA_EN, xfi_tphy->base + REG_DIG_LN_TRX_40); -+ -+ /* Setup TX DA default value */ -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x30b0, 0x30, 0x20); -+ mtk_xfi_tphy_write(xfi_tphy, 0x3028, 0x00008a01); -+ mtk_xfi_tphy_write(xfi_tphy, 0x302c, 0x0000a884); -+ mtk_xfi_tphy_write(xfi_tphy, 0x3024, 0x00083002); -+ -+ /* Setup RG default value */ -+ if (is_xgmii) { -+ mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00022220); -+ mtk_xfi_tphy_write(xfi_tphy, 0x5064, 0x0f020a01); -+ mtk_xfi_tphy_write(xfi_tphy, 0x50b4, 0x06100600); -+ if (interface == PHY_INTERFACE_MODE_USXGMII) -+ mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000); -+ else -+ mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x47684100); -+ } else { -+ mtk_xfi_tphy_write(xfi_tphy, 0x3010, 0x00011110); -+ mtk_xfi_tphy_write(xfi_tphy, 0x3048, 0x40704000); -+ } -+ -+ if (is_1g) -+ mtk_xfi_tphy_write(xfi_tphy, 0x3064, 0x0000c000); -+ -+ /* Setup RX EQ initial value */ -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x3050, 0xa8000000, -+ (interface != PHY_INTERFACE_MODE_10GBASER) ? -+ 0xa8000000 : 0x0); -+ mtk_xfi_tphy_rmw(xfi_tphy, 0x3054, 0xaa, -+ (interface != PHY_INTERFACE_MODE_10GBASER) ? -+ 0xaa : 0x0); -+ -+ if (is_xgmii) -+ mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x00000f00); -+ else if (is_2p5g) -+ mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x22000f00); -+ else -+ mtk_xfi_tphy_write(xfi_tphy, 0x306c, 0x20200f00); -+ -+ if (interface == PHY_INTERFACE_MODE_10GBASER && xfi_tphy->da_war) -+ mtk_xfi_tphy_rmw(xfi_tphy, 0xa008, 0x10000, 0x10000); -+ -+ mtk_xfi_tphy_rmw(xfi_tphy, 0xa060, 0x50000, is_xgmii ? 0x40000 : -+ 0x50000); -+ -+ /* Setup PHYA speed */ -+ mtk_xfi_tphy_rmw(xfi_tphy, REG_ANA_GLB_D0, -+ XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN, -+ is_10g ? XTP_GLB_USXGMII_SEL(0) : -+ is_5g ? XTP_GLB_USXGMII_SEL(1) : -+ is_2p5g ? XTP_GLB_USXGMII_SEL(2) : -+ XTP_GLB_USXGMII_SEL(3)); -+ mtk_xfi_tphy_set(xfi_tphy, REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN); -+ -+ /* Release reset */ -+ mtk_xfi_tphy_set(xfi_tphy, REG_DIG_GLB_70, -+ XTP_PCS_RST_B | XTP_FRC_PCS_RST_B); -+ usleep_range(150, 500); -+ -+ /* Switch to P0 */ -+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70, -+ XTP_PCS_PWD_SYNC_MASK | -+ XTP_PCS_PWD_ASYNC_MASK, -+ XTP_FRC_PCS_PWD_ASYNC | -+ XTP_PCS_UPDT | XTP_PCS_IN_FR_RG); -+ usleep_range(1, 5); -+ -+ mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT); -+ usleep_range(15, 50); -+ -+ if (is_xgmii) { -+ /* Switch to Gen3 */ -+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70, -+ XTP_PCS_MODE_MASK | XTP_PCS_UPDT, -+ XTP_PCS_MODE(2) | XTP_PCS_UPDT); -+ } else { -+ /* Switch to Gen2 */ -+ mtk_xfi_tphy_rmw(xfi_tphy, REG_DIG_GLB_70, -+ XTP_PCS_MODE_MASK | XTP_PCS_UPDT, -+ XTP_PCS_MODE(1) | XTP_PCS_UPDT); -+ } -+ usleep_range(1, 5); -+ -+ mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_70, XTP_PCS_UPDT); -+ -+ usleep_range(100, 500); -+ -+ /* Enable MAC CK */ -+ mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN); -+ mtk_xfi_tphy_clear(xfi_tphy, REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN); -+ -+ /* Enable TX data */ -+ mtk_xfi_tphy_set(xfi_tphy, REG_DIG_LN_TRX_40, -+ XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN); -+ usleep_range(400, 1000); -+} -+ -+static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int -+ submode) -+{ -+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy); -+ -+ if (mode != PHY_MODE_ETHERNET) -+ return -EINVAL; -+ -+ switch (submode) { -+ case PHY_INTERFACE_MODE_1000BASEX: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_5GBASER: -+ case PHY_INTERFACE_MODE_10GBASER: -+ case PHY_INTERFACE_MODE_USXGMII: -+ mtk_xfi_tphy_setup(xfi_tphy, submode); -+ return 0; -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int mtk_xfi_tphy_reset(struct phy *phy) -+{ -+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy); -+ -+ reset_control_assert(xfi_tphy->reset); -+ usleep_range(100, 500); -+ reset_control_deassert(xfi_tphy->reset); -+ usleep_range(1, 10); -+ -+ return 0; -+} -+ -+static int mtk_xfi_tphy_power_on(struct phy *phy) -+{ -+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy); -+ -+ return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks); -+} -+ -+static int mtk_xfi_tphy_power_off(struct phy *phy) -+{ -+ struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy); -+ -+ clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks); -+ -+ return 0; -+} -+ -+static const struct phy_ops mtk_xfi_tphy_ops = { -+ .power_on = mtk_xfi_tphy_power_on, -+ .power_off = mtk_xfi_tphy_power_off, -+ .set_mode = mtk_xfi_tphy_set_mode, -+ .reset = mtk_xfi_tphy_reset, -+ .owner = THIS_MODULE, -+}; -+ -+static int mtk_xfi_tphy_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct phy_provider *phy_provider; -+ struct mtk_xfi_tphy *xfi_tphy; -+ struct phy *phy; -+ -+ if (!np) -+ return -ENODEV; -+ -+ xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL); -+ if (!xfi_tphy) -+ return -ENOMEM; -+ -+ xfi_tphy->base = devm_of_iomap(&pdev->dev, np, 0, NULL); -+ if (!xfi_tphy->base) -+ return -EIO; -+ -+ xfi_tphy->dev = &pdev->dev; -+ -+ xfi_tphy->clocks[0].id = "topxtal"; -+ xfi_tphy->clocks[0].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[0].id); -+ if (IS_ERR(xfi_tphy->clocks[0].clk)) -+ return PTR_ERR(xfi_tphy->clocks[0].clk); -+ -+ xfi_tphy->clocks[1].id = "xfipll"; -+ xfi_tphy->clocks[1].clk = devm_clk_get(&pdev->dev, xfi_tphy->clocks[1].id); -+ if (IS_ERR(xfi_tphy->clocks[1].clk)) -+ return PTR_ERR(xfi_tphy->clocks[1].clk); -+ -+ xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); -+ if (IS_ERR(xfi_tphy->reset)) -+ return PTR_ERR(xfi_tphy->reset); -+ -+ xfi_tphy->da_war = of_property_read_bool(np, -+ "mediatek,usxgmii-performance-errata"); -+ -+ phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops); -+ if (IS_ERR(phy)) -+ return PTR_ERR(phy); -+ -+ phy_set_drvdata(phy, xfi_tphy); -+ -+ phy_provider = devm_of_phy_provider_register(&pdev->dev, -+ of_phy_simple_xlate); -+ -+ return PTR_ERR_OR_ZERO(phy_provider); -+} -+ -+static const struct of_device_id mtk_xfi_tphy_match[] = { -+ { .compatible = "mediatek,mt7988-xfi-tphy", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match); -+ -+static struct platform_driver mtk_xfi_tphy_driver = { -+ .probe = mtk_xfi_tphy_probe, -+ .driver = { -+ .name = "mtk-xfi-tphy", -+ .of_match_table = mtk_xfi_tphy_match, -+ }, -+}; -+module_platform_driver(mtk_xfi_tphy_driver); -+ -+MODULE_DESCRIPTION("MediaTek XFI T-PHY driver"); -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_AUTHOR("Bc-bocun Chen "); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/pending-6.1/739-03-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch b/target/linux/generic/pending-6.1/739-03-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch deleted file mode 100644 index adb95e9587f1f3..00000000000000 --- a/target/linux/generic/pending-6.1/739-03-net-pcs-pcs-mtk-lynxi-add-platform-driver-for-MT7988.patch +++ /dev/null @@ -1,371 +0,0 @@ -From 4b1a2716299c0e96a698044aebf3f80513509ae7 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 12 Dec 2023 03:47:18 +0000 -Subject: [PATCH 3/5] net: pcs: pcs-mtk-lynxi: add platform driver for MT7988 - -Introduce a proper platform MFD driver for the LynxI (H)SGMII PCS which -is going to initially be used for the MT7988 SoC. - -Signed-off-by: Daniel Golle ---- - drivers/net/pcs/pcs-mtk-lynxi.c | 227 ++++++++++++++++++++++++++++-- - include/linux/pcs/pcs-mtk-lynxi.h | 11 ++ - 2 files changed, 227 insertions(+), 11 deletions(-) - ---- a/drivers/net/pcs/pcs-mtk-lynxi.c -+++ b/drivers/net/pcs/pcs-mtk-lynxi.c -@@ -1,6 +1,6 @@ - // SPDX-License-Identifier: GPL-2.0 - // Copyright (c) 2018-2019 MediaTek Inc. --/* A library for MediaTek SGMII circuit -+/* A library and platform driver for the MediaTek LynxI SGMII circuit - * - * Author: Sean Wang - * Author: Alexander Couzens -@@ -8,11 +8,17 @@ - * - */ - -+#include - #include -+#include -+#include - #include -+#include - #include - #include -+#include - #include -+#include - - /* SGMII subsystem config registers */ - /* BMCR (low 16) BMSR (high 16) */ -@@ -65,6 +71,8 @@ - #define SGMII_PN_SWAP_MASK GENMASK(1, 0) - #define SGMII_PN_SWAP_TX_RX (BIT(0) | BIT(1)) - -+#define MTK_NETSYS_V3_AMA_RGC3 0x128 -+ - /* struct mtk_pcs_lynxi - This structure holds each sgmii regmap andassociated - * data - * @regmap: The register map pointing at the range used to setup -@@ -74,15 +82,29 @@ - * @interface: Currently configured interface mode - * @pcs: Phylink PCS structure - * @flags: Flags indicating hardware properties -+ * @rstc: Reset controller -+ * @sgmii_sel: SGMII Register Clock -+ * @sgmii_rx: SGMII RX Clock -+ * @sgmii_tx: SGMII TX Clock -+ * @node: List node - */ - struct mtk_pcs_lynxi { - struct regmap *regmap; -+ struct device *dev; - u32 ana_rgc3; - phy_interface_t interface; - struct phylink_pcs pcs; - u32 flags; -+ struct reset_control *rstc; -+ struct clk *sgmii_sel; -+ struct clk *sgmii_rx; -+ struct clk *sgmii_tx; -+ struct list_head node; - }; - -+static LIST_HEAD(mtk_pcs_lynxi_instances); -+static DEFINE_MUTEX(instance_mutex); -+ - static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs) - { - return container_of(pcs, struct mtk_pcs_lynxi, pcs); -@@ -102,6 +124,17 @@ static void mtk_pcs_lynxi_get_state(stru - FIELD_GET(SGMII_LPA, adv)); - } - -+static void mtk_sgmii_reset(struct mtk_pcs_lynxi *mpcs) -+{ -+ if (!mpcs->rstc) -+ return; -+ -+ reset_control_assert(mpcs->rstc); -+ udelay(100); -+ reset_control_deassert(mpcs->rstc); -+ mdelay(1); -+} -+ - static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode, - phy_interface_t interface, - const unsigned long *advertising, -@@ -148,6 +181,7 @@ static int mtk_pcs_lynxi_config(struct p - SGMII_PHYA_PWD); - - /* Reset SGMII PCS state */ -+ mtk_sgmii_reset(mpcs); - regmap_set_bits(mpcs->regmap, SGMSYS_RESERVED_0, - SGMII_SW_RESET); - -@@ -234,10 +268,29 @@ static void mtk_pcs_lynxi_link_up(struct - } - } - -+static int mtk_pcs_lynxi_enable(struct phylink_pcs *pcs) -+{ -+ struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); -+ -+ if (mpcs->sgmii_tx && mpcs->sgmii_rx) { -+ clk_prepare_enable(mpcs->sgmii_rx); -+ clk_prepare_enable(mpcs->sgmii_tx); -+ } -+ -+ return 0; -+} -+ - static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs) - { - struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs); - -+ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD); -+ -+ if (mpcs->sgmii_tx && mpcs->sgmii_rx) { -+ clk_disable_unprepare(mpcs->sgmii_tx); -+ clk_disable_unprepare(mpcs->sgmii_rx); -+ } -+ - mpcs->interface = PHY_INTERFACE_MODE_NA; - } - -@@ -247,11 +300,12 @@ static const struct phylink_pcs_ops mtk_ - .pcs_an_restart = mtk_pcs_lynxi_restart_an, - .pcs_link_up = mtk_pcs_lynxi_link_up, - .pcs_disable = mtk_pcs_lynxi_disable, -+ .pcs_enable = mtk_pcs_lynxi_enable, - }; - --struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, -- struct regmap *regmap, u32 ana_rgc3, -- u32 flags) -+static struct phylink_pcs *mtk_pcs_lynxi_init(struct device *dev, struct regmap *regmap, -+ u32 ana_rgc3, u32 flags, -+ struct mtk_pcs_lynxi *prealloc) - { - struct mtk_pcs_lynxi *mpcs; - u32 id, ver; -@@ -259,29 +313,33 @@ struct phylink_pcs *mtk_pcs_lynxi_create - - ret = regmap_read(regmap, SGMSYS_PCS_DEVICE_ID, &id); - if (ret < 0) -- return NULL; -+ return ERR_PTR(ret); - - if (id != SGMII_LYNXI_DEV_ID) { - dev_err(dev, "unknown PCS device id %08x\n", id); -- return NULL; -+ return ERR_PTR(-ENODEV); - } - - ret = regmap_read(regmap, SGMSYS_PCS_SCRATCH, &ver); - if (ret < 0) -- return NULL; -+ return ERR_PTR(ret); - - ver = FIELD_GET(SGMII_DEV_VERSION, ver); - if (ver != 0x1) { - dev_err(dev, "unknown PCS device version %04x\n", ver); -- return NULL; -+ return ERR_PTR(-ENODEV); - } - - dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id, - ver); - -- mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); -- if (!mpcs) -- return NULL; -+ if (prealloc) { -+ mpcs = prealloc; -+ } else { -+ mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); -+ if (!mpcs) -+ return ERR_PTR(-ENOMEM); -+ }; - - mpcs->ana_rgc3 = ana_rgc3; - mpcs->regmap = regmap; -@@ -292,6 +350,13 @@ struct phylink_pcs *mtk_pcs_lynxi_create - mpcs->interface = PHY_INTERFACE_MODE_NA; - - return &mpcs->pcs; -+}; -+ -+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, -+ struct regmap *regmap, u32 ana_rgc3, -+ u32 flags) -+{ -+ return mtk_pcs_lynxi_init(dev, regmap, ana_rgc3, flags, NULL); - } - EXPORT_SYMBOL(mtk_pcs_lynxi_create); - -@@ -304,4 +369,144 @@ void mtk_pcs_lynxi_destroy(struct phylin - } - EXPORT_SYMBOL(mtk_pcs_lynxi_destroy); - -+static int mtk_pcs_lynxi_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct mtk_pcs_lynxi *mpcs; -+ struct phylink_pcs *pcs; -+ struct regmap *regmap; -+ u32 flags = 0; -+ -+ mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL); -+ if (!mpcs) -+ return -ENOMEM; -+ -+ mpcs->dev = dev; -+ regmap = syscon_node_to_regmap(np->parent); -+ if (IS_ERR(regmap)) -+ return PTR_ERR(regmap); -+ -+ if (of_property_read_bool(np->parent, "mediatek,pnswap")) -+ flags |= MTK_SGMII_FLAG_PN_SWAP; -+ -+ mpcs->rstc = of_reset_control_get_shared(np->parent, NULL); -+ if (IS_ERR(mpcs->rstc)) -+ return PTR_ERR(mpcs->rstc); -+ -+ reset_control_deassert(mpcs->rstc); -+ mpcs->sgmii_sel = devm_clk_get_enabled(dev, "sgmii_sel"); -+ if (IS_ERR(mpcs->sgmii_sel)) -+ return PTR_ERR(mpcs->sgmii_sel); -+ -+ mpcs->sgmii_rx = devm_clk_get(dev, "sgmii_rx"); -+ if (IS_ERR(mpcs->sgmii_rx)) -+ return PTR_ERR(mpcs->sgmii_rx); -+ -+ mpcs->sgmii_tx = devm_clk_get(dev, "sgmii_tx"); -+ if (IS_ERR(mpcs->sgmii_tx)) -+ return PTR_ERR(mpcs->sgmii_tx); -+ -+ pcs = mtk_pcs_lynxi_init(dev, regmap, (uintptr_t)of_device_get_match_data(dev), -+ flags, mpcs); -+ if (IS_ERR(pcs)) -+ return PTR_ERR(pcs); -+ -+ regmap_set_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD); -+ -+ platform_set_drvdata(pdev, mpcs); -+ -+ mutex_lock(&instance_mutex); -+ list_add_tail(&mpcs->node, &mtk_pcs_lynxi_instances); -+ mutex_unlock(&instance_mutex); -+ -+ return 0; -+} -+ -+static int mtk_pcs_lynxi_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct mtk_pcs_lynxi *cur, *tmp; -+ -+ mutex_lock(&instance_mutex); -+ list_for_each_entry_safe(cur, tmp, &mtk_pcs_lynxi_instances, node) -+ if (cur->dev == dev) { -+ list_del(&cur->node); -+ kfree(cur); -+ break; -+ } -+ mutex_unlock(&instance_mutex); -+ -+ return 0; -+} -+ -+static const struct of_device_id mtk_pcs_lynxi_of_match[] = { -+ { .compatible = "mediatek,mt7988-sgmii", .data = (void *)MTK_NETSYS_V3_AMA_RGC3 }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, mtk_pcs_lynxi_of_match); -+ -+struct phylink_pcs *mtk_pcs_lynxi_get(struct device *dev, struct device_node *np) -+{ -+ struct platform_device *pdev; -+ struct mtk_pcs_lynxi *mpcs; -+ -+ if (!np) -+ return NULL; -+ -+ if (!of_device_is_available(np)) -+ return ERR_PTR(-ENODEV); -+ -+ if (!of_match_node(mtk_pcs_lynxi_of_match, np)) -+ return ERR_PTR(-EINVAL); -+ -+ pdev = of_find_device_by_node(np); -+ if (!pdev || !platform_get_drvdata(pdev)) { -+ if (pdev) -+ put_device(&pdev->dev); -+ return ERR_PTR(-EPROBE_DEFER); -+ } -+ -+ mpcs = platform_get_drvdata(pdev); -+ device_link_add(dev, mpcs->dev, DL_FLAG_AUTOREMOVE_CONSUMER); -+ -+ return &mpcs->pcs; -+} -+EXPORT_SYMBOL(mtk_pcs_lynxi_get); -+ -+void mtk_pcs_lynxi_put(struct phylink_pcs *pcs) -+{ -+ struct mtk_pcs_lynxi *cur, *mpcs = NULL; -+ -+ if (!pcs) -+ return; -+ -+ mutex_lock(&instance_mutex); -+ list_for_each_entry(cur, &mtk_pcs_lynxi_instances, node) -+ if (pcs == &cur->pcs) { -+ mpcs = cur; -+ break; -+ } -+ mutex_unlock(&instance_mutex); -+ -+ if (WARN_ON(!mpcs)) -+ return; -+ -+ put_device(mpcs->dev); -+} -+EXPORT_SYMBOL(mtk_pcs_lynxi_put); -+ -+static struct platform_driver mtk_pcs_lynxi_driver = { -+ .driver = { -+ .name = "mtk-pcs-lynxi", -+ .suppress_bind_attrs = true, -+ .of_match_table = mtk_pcs_lynxi_of_match, -+ }, -+ .probe = mtk_pcs_lynxi_probe, -+ .remove = mtk_pcs_lynxi_remove, -+}; -+module_platform_driver(mtk_pcs_lynxi_driver); -+ -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_DESCRIPTION("MediaTek LynxI HSGMII PCS"); - MODULE_LICENSE("GPL"); ---- a/include/linux/pcs/pcs-mtk-lynxi.h -+++ b/include/linux/pcs/pcs-mtk-lynxi.h -@@ -10,4 +10,15 @@ struct phylink_pcs *mtk_pcs_lynxi_create - struct regmap *regmap, - u32 ana_rgc3, u32 flags); - void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs); -+ -+#if IS_ENABLED(CONFIG_PCS_MTK_LYNXI) -+struct phylink_pcs *mtk_pcs_lynxi_get(struct device *dev, struct device_node *np); -+void mtk_pcs_lynxi_put(struct phylink_pcs *pcs); -+#else -+static inline struct phylink_pcs *mtk_pcs_lynxi_get(struct device *dev, struct device_node *np) -+{ -+ return NULL; -+} -+static inline void mtk_pcs_lynxi_put(struct phylink_pcs *pcs) { } -+#endif /* IS_ENABLED(CONFIG_PCS_MTK_LYNXI) */ - #endif diff --git a/target/linux/generic/pending-6.1/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch b/target/linux/generic/pending-6.1/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch deleted file mode 100644 index 215bd2ca2ef415..00000000000000 --- a/target/linux/generic/pending-6.1/739-04-dt-bindings-net-pcs-add-bindings-for-MediaTek-USXGMI.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 7d88d79c0f65b27a92754d7547f7af098b3de67b Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 12 Dec 2023 03:47:31 +0000 -Subject: [PATCH 4/5] dt-bindings: net: pcs: add bindings for MediaTek USXGMII - PCS - -MediaTek's USXGMII can be found in the MT7988 SoC. We need to access -it in order to configure and monitor the Ethernet SerDes link in -USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped -legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those -interface modes are also available. - -Signed-off-by: Daniel Golle ---- - .../bindings/net/pcs/mediatek,usxgmii.yaml | 60 +++++++++++++++++++ - 1 file changed, 60 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml - ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml -@@ -0,0 +1,60 @@ -+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) -+%YAML 1.2 -+--- -+$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml# -+$schema: http://devicetree.org/meta-schemas/core.yaml# -+ -+title: MediaTek USXGMII PCS -+ -+maintainers: -+ - Daniel Golle -+ -+description: -+ The MediaTek USXGMII PCS provides physical link control and status -+ for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces -+ provided by the PEXTP PHY. -+ In order to also support legacy 2500Base-X, 1000Base-X and Cisco -+ SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to -+ provide those interfaces modes on the same SerDes interfaces shared -+ with the USXGMII PCS. -+ -+properties: -+ $nodename: -+ pattern: "^pcs@[0-9a-f]+$" -+ -+ compatible: -+ const: mediatek,mt7988-usxgmiisys -+ -+ reg: -+ maxItems: 1 -+ -+ clocks: -+ items: -+ - description: USXGMII top-level clock -+ -+ resets: -+ items: -+ - description: XFI reset -+ -+required: -+ - compatible -+ - reg -+ - clocks -+ - resets -+ -+additionalProperties: false -+ -+examples: -+ - | -+ #include -+ #define MT7988_TOPRGU_XFI0_GRST 12 -+ soc { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ usxgmiisys0: pcs@10080000 { -+ compatible = "mediatek,mt7988-usxgmiisys"; -+ reg = <0 0x10080000 0 0x1000>; -+ clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>; -+ resets = <&watchdog MT7988_TOPRGU_XFI0_GRST>; -+ }; -+ }; diff --git a/target/linux/generic/pending-6.1/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch b/target/linux/generic/pending-6.1/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch deleted file mode 100644 index fd1bba3089a032..00000000000000 --- a/target/linux/generic/pending-6.1/739-05-net-pcs-add-driver-for-MediaTek-USXGMII-PCS.patch +++ /dev/null @@ -1,547 +0,0 @@ -From dde0e95fff92e9f5009f3bea75278e0e34a48822 Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Tue, 12 Dec 2023 03:47:47 +0000 -Subject: [PATCH 5/5] net: pcs: add driver for MediaTek USXGMII PCS - -Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting -USXGMII, 10GBase-R and 5GBase-R interface modes. - -Signed-off-by: Daniel Golle ---- - MAINTAINERS | 2 + - drivers/net/pcs/Kconfig | 11 + - drivers/net/pcs/Makefile | 1 + - drivers/net/pcs/pcs-mtk-usxgmii.c | 456 ++++++++++++++++++++++++++++ - include/linux/pcs/pcs-mtk-usxgmii.h | 27 ++ - 5 files changed, 497 insertions(+) - create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c - create mode 100644 include/linux/pcs/pcs-mtk-usxgmii.h - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -12941,7 +12941,9 @@ M: Daniel Golle - L: netdev@vger.kernel.org - S: Maintained - F: drivers/net/pcs/pcs-mtk-lynxi.c -+F: drivers/net/pcs/pcs-mtk-usxgmii.c - F: include/linux/pcs/pcs-mtk-lynxi.h -+F: include/linux/pcs/pcs-mtk-usxgmii.h - - MEDIATEK I2C CONTROLLER DRIVER - M: Qii Wang ---- a/drivers/net/pcs/Kconfig -+++ b/drivers/net/pcs/Kconfig -@@ -18,6 +18,17 @@ config PCS_LYNX - This module provides helpers to phylink for managing the Lynx PCS - which is part of the Layerscape and QorIQ Ethernet SERDES. - -+config PCS_MTK_USXGMII -+ tristate "MediaTek USXGMII PCS" -+ select PCS_MTK_LYNXI -+ select PHY_MTK_PEXTP -+ select PHYLINK -+ help -+ This module provides a driver for MediaTek's USXGMII PCS supporting -+ 10GBase-R, 5GBase-R and USXGMII interface modes. -+ 1000Base-X, 2500Base-X and Cisco SGMII are supported on the same -+ differential pairs via an embedded LynxI PHY. -+ - config PCS_RZN1_MIIC - tristate "Renesas RZ/N1 MII converter" - depends on OF && (ARCH_RZN1 || COMPILE_TEST) ---- a/drivers/net/pcs/Makefile -+++ b/drivers/net/pcs/Makefile -@@ -8,3 +8,4 @@ obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o - obj-$(CONFIG_PCS_RZN1_MIIC) += pcs-rzn1-miic.o - obj-$(CONFIG_PCS_ALTERA_TSE) += pcs-altera-tse.o - obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o -+obj-$(CONFIG_PCS_MTK_USXGMII) += pcs-mtk-usxgmii.o ---- /dev/null -+++ b/drivers/net/pcs/pcs-mtk-usxgmii.c -@@ -0,0 +1,456 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (c) 2023 MediaTek Inc. -+ * Author: Henry Yen -+ * Daniel Golle -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* USXGMII subsystem config registers */ -+/* Register to control speed */ -+#define RG_PHY_TOP_SPEED_CTRL1 0x80c -+#define USXGMII_RATE_UPDATE_MODE BIT(31) -+#define USXGMII_MAC_CK_GATED BIT(29) -+#define USXGMII_IF_FORCE_EN BIT(28) -+#define USXGMII_RATE_ADAPT_MODE GENMASK(10, 8) -+#define USXGMII_RATE_ADAPT_MODE_X1 0 -+#define USXGMII_RATE_ADAPT_MODE_X2 1 -+#define USXGMII_RATE_ADAPT_MODE_X4 2 -+#define USXGMII_RATE_ADAPT_MODE_X10 3 -+#define USXGMII_RATE_ADAPT_MODE_X100 4 -+#define USXGMII_RATE_ADAPT_MODE_X5 5 -+#define USXGMII_RATE_ADAPT_MODE_X50 6 -+#define USXGMII_XFI_RX_MODE GENMASK(6, 4) -+#define USXGMII_XFI_TX_MODE GENMASK(2, 0) -+#define USXGMII_XFI_MODE_10G 0 -+#define USXGMII_XFI_MODE_5G 1 -+#define USXGMII_XFI_MODE_2P5G 3 -+ -+/* Register to control PCS AN */ -+#define RG_PCS_AN_CTRL0 0x810 -+#define USXGMII_AN_RESTART BIT(31) -+#define USXGMII_AN_SYNC_CNT GENMASK(30, 11) -+#define USXGMII_AN_ENABLE BIT(0) -+ -+#define RG_PCS_AN_CTRL2 0x818 -+#define USXGMII_LINK_TIMER_IDLE_DETECT GENMASK(29, 20) -+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT GENMASK(19, 10) -+#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0) -+ -+/* Register to read PCS AN status */ -+#define RG_PCS_AN_STS0 0x81c -+#define USXGMII_LPA GENMASK(15, 0) -+#define USXGMII_LPA_LATCH BIT(31) -+ -+/* Register to read PCS link status */ -+#define RG_PCS_RX_STATUS0 0x904 -+#define RG_PCS_RX_STATUS_UPDATE BIT(16) -+#define RG_PCS_RX_LINK_STATUS BIT(2) -+ -+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii PCS -+ * @pcs: Phylink PCS structure -+ * @dev: Pointer to device structure -+ * @base: IO memory to access PCS hardware -+ * @clk: Pointer to USXGMII clk -+ * @reset: Pointer to USXGMII reset control -+ * @interface: Currently selected interface mode -+ * @neg_mode: Currently used phylink neg_mode -+ * @node: List node -+ */ -+struct mtk_usxgmii_pcs { -+ struct phylink_pcs pcs; -+ struct device *dev; -+ void __iomem *base; -+ struct clk *clk; -+ struct reset_control *reset; -+ phy_interface_t interface; -+ unsigned int neg_mode; -+ struct list_head node; -+}; -+ -+static LIST_HEAD(mtk_usxgmii_pcs_instances); -+static DEFINE_MUTEX(instance_mutex); -+ -+static u32 mtk_r32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg) -+{ -+ return ioread32(mpcs->base + reg); -+} -+ -+static void mtk_m32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg, u32 mask, u32 set) -+{ -+ u32 val; -+ -+ val = ioread32(mpcs->base + reg); -+ val &= ~mask; -+ val |= set; -+ iowrite32(val, mpcs->base + reg); -+} -+ -+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs) -+{ -+ return container_of(pcs, struct mtk_usxgmii_pcs, pcs); -+} -+ -+static void mtk_usxgmii_reset(struct mtk_usxgmii_pcs *mpcs) -+{ -+ reset_control_assert(mpcs->reset); -+ udelay(100); -+ reset_control_deassert(mpcs->reset); -+ -+ mdelay(10); -+} -+ -+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, -+ phy_interface_t interface, -+ const unsigned long *advertising, -+ bool permit_pause_to_mac) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0; -+ bool mode_changed = false; -+ -+ if (interface == PHY_INTERFACE_MODE_USXGMII) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE; -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G); -+ } else if (interface == PHY_INTERFACE_MODE_10GBASER) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF); -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G); -+ adapt_mode = USXGMII_RATE_UPDATE_MODE; -+ } else if (interface == PHY_INTERFACE_MODE_5GBASER) { -+ an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF); -+ link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) | -+ FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) | -+ FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D); -+ xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_5G) | -+ FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_5G); -+ adapt_mode = USXGMII_RATE_UPDATE_MODE; -+ } else { -+ return -EINVAL; -+ } -+ -+ adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1); -+ -+ if (mpcs->interface != interface) { -+ mpcs->interface = interface; -+ mode_changed = true; -+ } -+ -+ mtk_usxgmii_reset(mpcs); -+ -+ /* Setup USXGMII AN ctrl */ -+ mtk_m32(mpcs, RG_PCS_AN_CTRL0, -+ USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE, -+ an_ctrl); -+ -+ mtk_m32(mpcs, RG_PCS_AN_CTRL2, -+ USXGMII_LINK_TIMER_IDLE_DETECT | -+ USXGMII_LINK_TIMER_COMP_ACK_DETECT | -+ USXGMII_LINK_TIMER_AN_RESTART, -+ link_timer); -+ -+ mpcs->neg_mode = neg_mode; -+ -+ /* Gated MAC CK */ -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED); -+ -+ /* Enable interface force mode */ -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN); -+ -+ /* Setup USXGMII adapt mode */ -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE, -+ adapt_mode); -+ -+ /* Setup USXGMII speed */ -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, -+ USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE, -+ xfi_mode); -+ -+ usleep_range(1, 10); -+ -+ /* Un-gated MAC CK */ -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_MAC_CK_GATED, 0); -+ -+ usleep_range(1, 10); -+ -+ /* Disable interface force mode for the AN mode */ -+ if (an_ctrl & USXGMII_AN_ENABLE) -+ mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_IF_FORCE_EN, 0); -+ -+ return mode_changed; -+} -+ -+static void mtk_usxgmii_pcs_get_fixed_speed(struct mtk_usxgmii_pcs *mpcs, -+ struct phylink_link_state *state) -+{ -+ u32 val = mtk_r32(mpcs, RG_PHY_TOP_SPEED_CTRL1); -+ int speed; -+ -+ /* Calculate speed from interface speed and rate adapt mode */ -+ switch (FIELD_GET(USXGMII_XFI_RX_MODE, val)) { -+ case USXGMII_XFI_MODE_10G: -+ speed = 10000; -+ break; -+ case USXGMII_XFI_MODE_5G: -+ speed = 5000; -+ break; -+ case USXGMII_XFI_MODE_2P5G: -+ speed = 2500; -+ break; -+ default: -+ state->speed = SPEED_UNKNOWN; -+ return; -+ } -+ -+ switch (FIELD_GET(USXGMII_RATE_ADAPT_MODE, val)) { -+ case USXGMII_RATE_ADAPT_MODE_X100: -+ speed /= 100; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X50: -+ speed /= 50; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X10: -+ speed /= 10; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X5: -+ speed /= 5; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X4: -+ speed /= 4; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X2: -+ speed /= 2; -+ break; -+ case USXGMII_RATE_ADAPT_MODE_X1: -+ break; -+ default: -+ state->speed = SPEED_UNKNOWN; -+ return; -+ } -+ -+ state->speed = speed; -+ state->duplex = DUPLEX_FULL; -+} -+ -+static void mtk_usxgmii_pcs_get_an_state(struct mtk_usxgmii_pcs *mpcs, -+ struct phylink_link_state *state) -+{ -+ u16 lpa; -+ -+ /* Refresh LPA by toggling LPA_LATCH */ -+ mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, USXGMII_LPA_LATCH); -+ ndelay(1020); -+ mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, 0); -+ ndelay(1020); -+ lpa = FIELD_GET(USXGMII_LPA, mtk_r32(mpcs, RG_PCS_AN_STS0)); -+ -+ phylink_decode_usxgmii_word(state, lpa); -+} -+ -+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs, -+ struct phylink_link_state *state) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ -+ /* Refresh USXGMII link status by toggling RG_PCS_AN_STATUS_UPDATE */ -+ mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE, -+ RG_PCS_RX_STATUS_UPDATE); -+ ndelay(1020); -+ mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE, 0); -+ ndelay(1020); -+ -+ /* Read USXGMII link status */ -+ state->link = FIELD_GET(RG_PCS_RX_LINK_STATUS, -+ mtk_r32(mpcs, RG_PCS_RX_STATUS0)); -+ -+ /* Continuously repeat re-configuration sequence until link comes up */ -+ if (!state->link) { -+ mtk_usxgmii_pcs_config(pcs, mpcs->neg_mode, -+ state->interface, NULL, false); -+ return; -+ } -+ -+ if (FIELD_GET(USXGMII_AN_ENABLE, mtk_r32(mpcs, RG_PCS_AN_CTRL0))) -+ mtk_usxgmii_pcs_get_an_state(mpcs, state); -+ else -+ mtk_usxgmii_pcs_get_fixed_speed(mpcs, state); -+} -+ -+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ -+ mtk_m32(mpcs, RG_PCS_AN_CTRL0, USXGMII_AN_RESTART, USXGMII_AN_RESTART); -+} -+ -+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, -+ phy_interface_t interface, -+ int speed, int duplex) -+{ -+ /* Reconfiguring USXGMII to ensure the quality of the RX signal -+ * after the line side link up. -+ */ -+ mtk_usxgmii_pcs_config(pcs, neg_mode, interface, NULL, false); -+} -+ -+static void mtk_usxgmii_pcs_disable(struct phylink_pcs *pcs) -+{ -+ struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs); -+ -+ mpcs->interface = PHY_INTERFACE_MODE_NA; -+ mpcs->neg_mode = -1; -+} -+ -+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = { -+ .pcs_config = mtk_usxgmii_pcs_config, -+ .pcs_get_state = mtk_usxgmii_pcs_get_state, -+ .pcs_an_restart = mtk_usxgmii_pcs_restart_an, -+ .pcs_link_up = mtk_usxgmii_pcs_link_up, -+ .pcs_disable = mtk_usxgmii_pcs_disable, -+}; -+ -+static int mtk_usxgmii_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct mtk_usxgmii_pcs *mpcs; -+ -+ mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL); -+ if (!mpcs) -+ return -ENOMEM; -+ -+ mpcs->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(mpcs->base)) -+ return PTR_ERR(mpcs->base); -+ -+ mpcs->dev = dev; -+ mpcs->pcs.ops = &mtk_usxgmii_pcs_ops; -+ mpcs->pcs.poll = true; -+ mpcs->pcs.neg_mode = true; -+ mpcs->interface = PHY_INTERFACE_MODE_NA; -+ mpcs->neg_mode = -1; -+ -+ mpcs->clk = devm_clk_get_enabled(mpcs->dev, NULL); -+ if (IS_ERR(mpcs->clk)) -+ return PTR_ERR(mpcs->clk); -+ -+ mpcs->reset = devm_reset_control_get_shared(dev, NULL); -+ if (IS_ERR(mpcs->reset)) -+ return PTR_ERR(mpcs->reset); -+ -+ reset_control_deassert(mpcs->reset); -+ -+ platform_set_drvdata(pdev, mpcs); -+ -+ mutex_lock(&instance_mutex); -+ list_add_tail(&mpcs->node, &mtk_usxgmii_pcs_instances); -+ mutex_unlock(&instance_mutex); -+ -+ return 0; -+} -+ -+static int mtk_usxgmii_remove(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct mtk_usxgmii_pcs *cur, *tmp; -+ -+ mutex_lock(&instance_mutex); -+ list_for_each_entry_safe(cur, tmp, &mtk_usxgmii_pcs_instances, node) -+ if (cur->dev == dev) { -+ list_del(&cur->node); -+ break; -+ } -+ mutex_unlock(&instance_mutex); -+ -+ return 0; -+} -+ -+static const struct of_device_id mtk_usxgmii_of_mtable[] = { -+ { .compatible = "mediatek,mt7988-usxgmiisys" }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, mtk_usxgmii_of_mtable); -+ -+struct phylink_pcs *mtk_usxgmii_pcs_get(struct device *dev, struct device_node *np) -+{ -+ struct platform_device *pdev; -+ struct mtk_usxgmii_pcs *mpcs; -+ -+ if (!np) -+ return NULL; -+ -+ if (!of_device_is_available(np)) -+ return ERR_PTR(-ENODEV); -+ -+ if (!of_match_node(mtk_usxgmii_of_mtable, np)) -+ return ERR_PTR(-EINVAL); -+ -+ pdev = of_find_device_by_node(np); -+ if (!pdev || !platform_get_drvdata(pdev)) { -+ if (pdev) -+ put_device(&pdev->dev); -+ return ERR_PTR(-EPROBE_DEFER); -+ } -+ -+ mpcs = platform_get_drvdata(pdev); -+ device_link_add(dev, mpcs->dev, DL_FLAG_AUTOREMOVE_CONSUMER); -+ -+ return &mpcs->pcs; -+} -+EXPORT_SYMBOL(mtk_usxgmii_pcs_get); -+ -+void mtk_usxgmii_pcs_put(struct phylink_pcs *pcs) -+{ -+ struct mtk_usxgmii_pcs *cur, *mpcs = NULL; -+ -+ if (!pcs) -+ return; -+ -+ mutex_lock(&instance_mutex); -+ list_for_each_entry(cur, &mtk_usxgmii_pcs_instances, node) -+ if (pcs == &cur->pcs) { -+ mpcs = cur; -+ break; -+ } -+ mutex_unlock(&instance_mutex); -+ -+ if (WARN_ON(!mpcs)) -+ return; -+ -+ put_device(mpcs->dev); -+} -+EXPORT_SYMBOL(mtk_usxgmii_pcs_put); -+ -+static struct platform_driver mtk_usxgmii_driver = { -+ .driver = { -+ .name = "mtk_usxgmii", -+ .suppress_bind_attrs = true, -+ .of_match_table = mtk_usxgmii_of_mtable, -+ }, -+ .probe = mtk_usxgmii_probe, -+ .remove = mtk_usxgmii_remove, -+}; -+module_platform_driver(mtk_usxgmii_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("MediaTek USXGMII PCS driver"); -+MODULE_AUTHOR("Daniel Golle "); ---- /dev/null -+++ b/include/linux/pcs/pcs-mtk-usxgmii.h -@@ -0,0 +1,27 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __LINUX_PCS_MTK_USXGMII_H -+#define __LINUX_PCS_MTK_USXGMII_H -+ -+#include -+ -+/** -+ * mtk_usxgmii_select_pcs() - Get MediaTek PCS instance -+ * @np: Pointer to device node indentifying a MediaTek USXGMII PCS -+ * @mode: Ethernet PHY interface mode -+ * -+ * Return PCS identified by a device node and the PHY interface mode in use -+ * -+ * Return: Pointer to phylink PCS instance of NULL -+ */ -+#if IS_ENABLED(CONFIG_PCS_MTK_USXGMII) -+struct phylink_pcs *mtk_usxgmii_pcs_get(struct device *dev, struct device_node *np); -+void mtk_usxgmii_pcs_put(struct phylink_pcs *pcs); -+#else -+static inline struct phylink_pcs *mtk_usxgmii_pcs_get(struct device *dev, struct device_node *np) -+{ -+ return NULL; -+} -+static inline void mtk_usxgmii_pcs_put(struct phylink_pcs *pcs) { } -+#endif /* IS_ENABLED(CONFIG_PCS_MTK_USXGMII) */ -+ -+#endif /* __LINUX_PCS_MTK_USXGMII_H */ diff --git a/target/linux/generic/pending-6.1/740-net-phy-motorcomm-Add-missing-include.patch b/target/linux/generic/pending-6.1/740-net-phy-motorcomm-Add-missing-include.patch deleted file mode 100644 index 2a1f908cfb32e6..00000000000000 --- a/target/linux/generic/pending-6.1/740-net-phy-motorcomm-Add-missing-include.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 6f291aa7da199c6486cc229b055dcbcd5cee7a21 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Sun, 21 May 2023 22:24:56 +0200 -Subject: [PATCH] net: phy: motorcomm: Add missing include - -Directly include linux/bitfield.h which provides FIELD_PREP. - -Signed-off-by: Hauke Mehrtens ---- - drivers/net/phy/motorcomm.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/phy/motorcomm.c -+++ b/drivers/net/phy/motorcomm.c -@@ -6,6 +6,7 @@ - * Author: Frank - */ - -+#include - #include - #include - #include diff --git a/target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch b/target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch deleted file mode 100644 index 249ba5c496caaa..00000000000000 --- a/target/linux/generic/pending-6.1/741-net-phy-realtek-support-interrupt-of-RTL8221B.patch +++ /dev/null @@ -1,75 +0,0 @@ -From d7943c31d57c11e1a517aa3ce2006fca44866870 Mon Sep 17 00:00:00 2001 -From: Jianhui Zhao -Date: Sun, 24 Sep 2023 22:15:00 +0800 -Subject: [PATCH] net: phy: realtek: add interrupt support for RTL8221B - -This commit introduces interrupt support for RTL8221B. - -Signed-off-by: Jianhui Zhao ---- - drivers/net/phy/realtek.c | 47 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 47 insertions(+) - ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -982,6 +982,51 @@ static int rtl8221b_config_init(struct p - return 0; - } - -+static int rtl8221b_ack_interrupt(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = phy_read_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d4); -+ -+ return (err < 0) ? err : 0; -+} -+ -+static int rtl8221b_config_intr(struct phy_device *phydev) -+{ -+ int err; -+ -+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { -+ err = rtl8221b_ack_interrupt(phydev); -+ if (err) -+ return err; -+ -+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x7ff); -+ } else { -+ err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x0); -+ if (err) -+ return err; -+ -+ err = rtl8221b_ack_interrupt(phydev); -+ } -+ -+ return err; -+} -+ -+static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev) -+{ -+ int err; -+ -+ err = rtl8221b_ack_interrupt(phydev); -+ if (err) { -+ phy_error(phydev); -+ return IRQ_NONE; -+ } -+ -+ phy_trigger_machine(phydev); -+ -+ return IRQ_HANDLED; -+} -+ - static struct phy_driver realtek_drvs[] = { - { - PHY_ID_MATCH_EXACT(0x00008201), -@@ -1142,6 +1187,8 @@ static struct phy_driver realtek_drvs[] - .get_features = rtl822x_get_features, - .config_init = rtl8221b_config_init, - .config_aneg = rtl822x_config_aneg, -+ .config_intr = rtl8221b_config_intr, -+ .handle_interrupt = rtl8221b_handle_interrupt, - .probe = rtl822x_probe, - .read_status = rtl822x_read_status, - .suspend = genphy_suspend, diff --git a/target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch b/target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch deleted file mode 100644 index 500567b4ed05b7..00000000000000 --- a/target/linux/generic/pending-6.1/742-net-phy-air_en8811h-reset-netdev-rules-when-LED-is-s.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 9be9a00adfac8118b6d685e71696f83187308c66 Mon Sep 17 00:00:00 2001 -Message-ID: <9be9a00adfac8118b6d685e71696f83187308c66.1715125851.git.daniel@makrotopia.org> -From: Daniel Golle -Date: Tue, 7 May 2024 22:43:30 +0100 -Subject: [PATCH net] net: phy: air_en8811h: reset netdev rules when LED is set - manually -To: Andrew Lunn , - Heiner Kallweit , - Russell King , - David S. Miller , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - SkyLake Huang , - Eric Woudstra , - netdev@vger.kernel.org, - linux-kernel@vger.kernel.org - -Setting LED_OFF via the brightness_set should deactivate hw control, -so make sure netdev trigger rules also get cleared in that case. - -Fixes: 71e79430117d ("net: phy: air_en8811h: Add the Airoha EN8811H PHY driver") -Signed-off-by: Daniel Golle ---- -This is basically a stop-gap measure until unified LED handling has -been implemented accross all MediaTek and Airoha PHYs. -See also -https://patchwork.kernel.org/project/netdevbpf/patch/20240425023325.15586-3-SkyLake.Huang@mediatek.com/ - - drivers/net/phy/air_en8811h.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/phy/air_en8811h.c -+++ b/drivers/net/phy/air_en8811h.c -@@ -544,6 +544,10 @@ static int air_hw_led_on_set(struct phy_ - - changed |= (priv->led[index].rules != 0); - -+ /* clear netdev trigger rules in case LED_OFF has been set */ -+ if (!on) -+ priv->led[index].rules = 0; -+ - if (changed) - return phy_modify_mmd(phydev, MDIO_MMD_VEND2, - AIR_PHY_LED_ON(index), diff --git a/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch b/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch deleted file mode 100644 index 7d5727bda683aa..00000000000000 --- a/target/linux/generic/pending-6.1/760-net-core-add-optional-threading-for-backlog-processi.patch +++ /dev/null @@ -1,227 +0,0 @@ -From: Felix Fietkau -Date: Thu, 16 Feb 2023 18:39:04 +0100 -Subject: [PATCH] net/core: add optional threading for backlog processing - -When dealing with few flows or an imbalance on CPU utilization, static RPS -CPU assignment can be too inflexible. Add support for enabling threaded NAPI -for backlog processing in order to allow the scheduler to better balance -processing. This helps better spread the load across idle CPUs. - -Signed-off-by: Felix Fietkau ---- - ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -543,6 +543,7 @@ static inline bool napi_complete(struct - } - - int dev_set_threaded(struct net_device *dev, bool threaded); -+int backlog_set_threaded(bool threaded); - - /** - * napi_disable - prevent NAPI from scheduling -@@ -3150,6 +3151,7 @@ struct softnet_data { - unsigned int processed; - unsigned int time_squeeze; - unsigned int received_rps; -+ unsigned int process_queue_empty; - #ifdef CONFIG_RPS - struct softnet_data *rps_ipi_list; - #endif ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -4625,7 +4625,7 @@ static int napi_schedule_rps(struct soft - struct softnet_data *mysd = this_cpu_ptr(&softnet_data); - - #ifdef CONFIG_RPS -- if (sd != mysd) { -+ if (sd != mysd && !test_bit(NAPI_STATE_THREADED, &sd->backlog.state)) { - sd->rps_ipi_next = mysd->rps_ipi_list; - mysd->rps_ipi_list = sd; - -@@ -5806,6 +5806,8 @@ static DEFINE_PER_CPU(struct work_struct - /* Network device is going away, flush any packets still pending */ - static void flush_backlog(struct work_struct *work) - { -+ unsigned int process_queue_empty; -+ bool threaded, flush_processq; - struct sk_buff *skb, *tmp; - struct softnet_data *sd; - -@@ -5820,8 +5822,17 @@ static void flush_backlog(struct work_st - input_queue_head_incr(sd); - } - } -+ -+ threaded = test_bit(NAPI_STATE_THREADED, &sd->backlog.state); -+ flush_processq = threaded && -+ !skb_queue_empty_lockless(&sd->process_queue); -+ if (flush_processq) -+ process_queue_empty = sd->process_queue_empty; - rps_unlock_irq_enable(sd); - -+ if (threaded) -+ goto out; -+ - skb_queue_walk_safe(&sd->process_queue, skb, tmp) { - if (skb->dev->reg_state == NETREG_UNREGISTERING) { - __skb_unlink(skb, &sd->process_queue); -@@ -5829,7 +5840,16 @@ static void flush_backlog(struct work_st - input_queue_head_incr(sd); - } - } -+ -+out: - local_bh_enable(); -+ -+ while (flush_processq) { -+ msleep(1); -+ rps_lock_irq_disable(sd); -+ flush_processq = process_queue_empty == sd->process_queue_empty; -+ rps_unlock_irq_enable(sd); -+ } - } - - static bool flush_required(int cpu) -@@ -5961,6 +5981,7 @@ static int process_backlog(struct napi_s - } - - rps_lock_irq_disable(sd); -+ sd->process_queue_empty++; - if (skb_queue_empty(&sd->input_pkt_queue)) { - /* - * Inline a custom version of __napi_complete(). -@@ -5970,7 +5991,8 @@ static int process_backlog(struct napi_s - * We can use a plain write instead of clear_bit(), - * and we dont need an smp_mb() memory barrier. - */ -- napi->state = 0; -+ napi->state &= ~(NAPIF_STATE_SCHED | -+ NAPIF_STATE_SCHED_THREADED); - again = false; - } else { - skb_queue_splice_tail_init(&sd->input_pkt_queue, -@@ -6386,6 +6408,55 @@ int dev_set_threaded(struct net_device * - } - EXPORT_SYMBOL(dev_set_threaded); - -+int backlog_set_threaded(bool threaded) -+{ -+ static bool backlog_threaded; -+ int err = 0; -+ int i; -+ -+ if (backlog_threaded == threaded) -+ return 0; -+ -+ for_each_possible_cpu(i) { -+ struct softnet_data *sd = &per_cpu(softnet_data, i); -+ struct napi_struct *n = &sd->backlog; -+ -+ if (n->thread) -+ continue; -+ n->thread = kthread_run(napi_threaded_poll, n, "napi/backlog-%d", i); -+ if (IS_ERR(n->thread)) { -+ err = PTR_ERR(n->thread); -+ pr_err("kthread_run failed with err %d\n", err); -+ n->thread = NULL; -+ threaded = false; -+ break; -+ } -+ -+ } -+ -+ backlog_threaded = threaded; -+ -+ /* Make sure kthread is created before THREADED bit -+ * is set. -+ */ -+ smp_mb__before_atomic(); -+ -+ for_each_possible_cpu(i) { -+ struct softnet_data *sd = &per_cpu(softnet_data, i); -+ struct napi_struct *n = &sd->backlog; -+ unsigned long flags; -+ -+ rps_lock_irqsave(sd, &flags); -+ if (threaded) -+ n->state |= NAPIF_STATE_THREADED; -+ else -+ n->state &= ~NAPIF_STATE_THREADED; -+ rps_unlock_irq_restore(sd, &flags); -+ } -+ -+ return err; -+} -+ - void netif_napi_add_weight(struct net_device *dev, struct napi_struct *napi, - int (*poll)(struct napi_struct *, int), int weight) - { -@@ -11127,6 +11198,9 @@ static int dev_cpu_dead(unsigned int old - raise_softirq_irqoff(NET_TX_SOFTIRQ); - local_irq_enable(); - -+ if (test_bit(NAPI_STATE_THREADED, &oldsd->backlog.state)) -+ return 0; -+ - #ifdef CONFIG_RPS - remsd = oldsd->rps_ipi_list; - oldsd->rps_ipi_list = NULL; -@@ -11439,6 +11513,7 @@ static int __init net_dev_init(void) - INIT_CSD(&sd->defer_csd, trigger_rx_softirq, sd); - spin_lock_init(&sd->defer_lock); - -+ INIT_LIST_HEAD(&sd->backlog.poll_list); - init_gro_hash(&sd->backlog); - sd->backlog.poll = process_backlog; - sd->backlog.weight = weight_p; ---- a/net/core/sysctl_net_core.c -+++ b/net/core/sysctl_net_core.c -@@ -30,6 +30,7 @@ static int min_sndbuf = SOCK_MIN_SNDBUF; - static int min_rcvbuf = SOCK_MIN_RCVBUF; - static int max_skb_frags = MAX_SKB_FRAGS; - static int min_mem_pcpu_rsv = SK_MEMORY_PCPU_RESERVE; -+static int backlog_threaded; - - static int net_msg_warn; /* Unused, but still a sysctl */ - -@@ -113,6 +114,23 @@ static int rps_sock_flow_sysctl(struct c - } - #endif /* CONFIG_RPS */ - -+static int backlog_threaded_sysctl(struct ctl_table *table, int write, -+ void *buffer, size_t *lenp, loff_t *ppos) -+{ -+ static DEFINE_MUTEX(backlog_threaded_mutex); -+ int ret; -+ -+ mutex_lock(&backlog_threaded_mutex); -+ -+ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); -+ if (write && !ret) -+ ret = backlog_set_threaded(backlog_threaded); -+ -+ mutex_unlock(&backlog_threaded_mutex); -+ -+ return ret; -+} -+ - #ifdef CONFIG_NET_FLOW_LIMIT - static DEFINE_MUTEX(flow_limit_update_mutex); - -@@ -482,6 +500,15 @@ static struct ctl_table net_core_table[] - .proc_handler = rps_sock_flow_sysctl - }, - #endif -+ { -+ .procname = "backlog_threaded", -+ .data = &backlog_threaded, -+ .maxlen = sizeof(unsigned int), -+ .mode = 0644, -+ .proc_handler = backlog_threaded_sysctl, -+ .extra1 = SYSCTL_ZERO, -+ .extra2 = SYSCTL_ONE -+ }, - #ifdef CONFIG_NET_FLOW_LIMIT - { - .procname = "flow_limit_cpu_bitmap", diff --git a/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch deleted file mode 100644 index 6fa33ee1a81d60..00000000000000 --- a/target/linux/generic/pending-6.1/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Tobias Waldekranz -Subject: [RFC net-next 7/7] net: dsa: mv88e6xxx: Request assisted learning on CPU port -Date: Sat, 16 Jan 2021 02:25:15 +0100 -Archived-At: - -While the hardware is capable of performing learning on the CPU port, -it requires alot of additions to the bridge's forwarding path in order -to handle multi-destination traffic correctly. - -Until that is in place, opt for the next best thing and let DSA sync -the relevant addresses down to the hardware FDB. - -Signed-off-by: Tobias Waldekranz ---- - drivers/net/dsa/mv88e6xxx/chip.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/dsa/mv88e6xxx/chip.c -+++ b/drivers/net/dsa/mv88e6xxx/chip.c -@@ -7080,6 +7080,7 @@ static int mv88e6xxx_register_switch(str - ds->ops = &mv88e6xxx_switch_ops; - ds->ageing_time_min = chip->info->age_time_coeff; - ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; -+ ds->assisted_learning_on_cpu_port = true; - - /* Some chips support up to 32, but that requires enabling the - * 5-bit port mode, which we do not support. 640k^W16 ought to diff --git a/target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch b/target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch deleted file mode 100644 index 23859816fa8525..00000000000000 --- a/target/linux/generic/pending-6.1/772-net-dsa-b53-add-support-for-BCM63xx-RGMIIs.patch +++ /dev/null @@ -1,174 +0,0 @@ -From patchwork Sun Mar 19 22:08:05 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13180645 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id A7A46C6FD1F - for ; Sun, 19 Mar 2023 22:08:15 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S230223AbjCSWIN (ORCPT ); - Sun, 19 Mar 2023 18:08:13 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32878 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S229565AbjCSWIM (ORCPT - ); Sun, 19 Mar 2023 18:08:12 -0400 -Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com - [IPv6:2a00:1450:4864:20::42e]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 605D3E062; - Sun, 19 Mar 2023 15:08:10 -0700 (PDT) -Received: by mail-wr1-x42e.google.com with SMTP id h17so8695188wrt.8; - Sun, 19 Mar 2023 15:08:10 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679263689; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=GmPK75Q9ZD3h3IYflWYuDwS99V2e532KgDlnNucAoJg=; - b=PSdrywW48P4Lq8z9wOSPXFB/ZdO/JfuyiGlw3Gz1Iriy+Smo/cBnJ0Ve9zKkX3AKTO - Tr7/g8xhSQX8sU5WAOEPC13uVjKpO4VZsamXHTmMKL4mmfII3K/piAsQcMQkkNpgouab - Ci9yr+7ASSmqEUHIbYTM6sl6a47rPwqk3b3DcTIE2CwJsPPNXnpQ/aSVbJAcEdhcZICc - X4rAmjrYjcsl8coFIGHHPlrMH9ShekQWxB84vEb6bO1nXOORNPizOHuY1vJ3wa3WgXsx - YwlvutMFVIUXfgL2ZwCmQAKWJPiAaFk+CCk3oxSeOYoAzkjcbMyapz9VnooStfvR2aV3 - k+2g== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679263689; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=GmPK75Q9ZD3h3IYflWYuDwS99V2e532KgDlnNucAoJg=; - b=NGjqrGERyaxRwINtevHaY97h9X9W+1UY62YYwotqwv5+cfvB8myjBbD3WH2WzaqMes - o9MMER9RE8/arW3jIVlBv4ORDUuEZ7AeGgy5UbFyQZIPHlp+hJ/sxFrGvYUwamg4Qrr9 - ojargh8ORsEiMeqaf+5AkmEagNhrrV3ax0pUuWDzbJ3vXGoHjfCetHz5xyNL46dvXBfb - l/OZqjv9IYob552uUoUmCy/TbEQDqvmjkFrROFK9gtBNxgxUJkwbyiWIOVsf6RR8OarP - f7bbvSJYkvTvzx2u/g0Up7NW5ZyihMGBmDs377M3yW6AnSxW6jlfl30QmMU1aEigYXvy - v3mA== -X-Gm-Message-State: AO0yUKUm1PYmYa4xlHuVD23mZcZm83a+xbhcbs0Xryi3yF/+UnjM4Cho - GAfqSh5MZ/rlOAm3Vnpn//9hOG5Lc8vLYg== -X-Google-Smtp-Source: - AK7set+5pTahGGgk1hF/mHGkGBhsMf0//oQjZd4QFHx+HaeSgP5f6q7g0bRUcTX8kRtgHH0T7l1/hQ== -X-Received: by 2002:a5d:474f:0:b0:2d6:2ae8:70d with SMTP id - o15-20020a5d474f000000b002d62ae8070dmr2382593wrs.39.1679263688549; - Sun, 19 Mar 2023 15:08:08 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - d6-20020a5d6dc6000000b002c53f6c7599sm7354727wrz.29.2023.03.19.15.08.07 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Sun, 19 Mar 2023 15:08:07 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, - olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, netdev@vger.kernel.org, - linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v2] net: dsa: b53: add support for BCM63xx RGMIIs -Date: Sun, 19 Mar 2023 23:08:05 +0100 -Message-Id: <20230319220805.124024-1-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230319183330.761251-1-noltari@gmail.com> -References: <20230319183330.761251-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -BCM63xx RGMII ports require additional configuration in order to work. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Andrew Lunn ---- - v2: add changes suggested by Andrew: - - Use a switch statement. - - Use dev_dbg() instead of dev_info(). - - drivers/net/dsa/b53/b53_common.c | 46 ++++++++++++++++++++++++++++++++ - drivers/net/dsa/b53/b53_priv.h | 1 + - 2 files changed, 47 insertions(+) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -1209,6 +1209,46 @@ static void b53_force_port_config(struct - b53_write8(dev, B53_CTRL_PAGE, off, reg); - } - -+static void b53_adjust_63xx_rgmii(struct dsa_switch *ds, int port, -+ phy_interface_t interface) -+{ -+ struct b53_device *dev = ds->priv; -+ u8 rgmii_ctrl = 0, off; -+ -+ if (port == dev->imp_port) -+ off = B53_RGMII_CTRL_IMP; -+ else -+ off = B53_RGMII_CTRL_P(port); -+ -+ b53_read8(dev, B53_CTRL_PAGE, off, &rgmii_ctrl); -+ -+ switch (interface) { -+ case PHY_INTERFACE_MODE_RGMII_ID: -+ rgmii_ctrl |= (RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC); -+ break; -+ case PHY_INTERFACE_MODE_RGMII_RXID: -+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_TXC); -+ rgmii_ctrl |= RGMII_CTRL_DLL_RXC; -+ break; -+ case PHY_INTERFACE_MODE_RGMII_TXID: -+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC); -+ rgmii_ctrl |= RGMII_CTRL_DLL_TXC; -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ default: -+ rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC); -+ break; -+ } -+ -+ if (port != dev->imp_port) -+ rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII; -+ -+ b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl); -+ -+ dev_dbg(ds->dev, "Configured port %d for %s\n", port, -+ phy_modes(interface)); -+} -+ - static void b53_adjust_link(struct dsa_switch *ds, int port, - struct phy_device *phydev) - { -@@ -1235,6 +1275,9 @@ static void b53_adjust_link(struct dsa_s - tx_pause, rx_pause); - b53_force_link(dev, port, phydev->link); - -+ if (is63xx(dev) && port >= B53_63XX_RGMII0) -+ b53_adjust_63xx_rgmii(ds, port, phydev->interface); -+ - if (is531x5(dev) && phy_interface_is_rgmii(phydev)) { - if (port == dev->imp_port) - off = B53_RGMII_CTRL_IMP; -@@ -1402,6 +1445,9 @@ void b53_phylink_mac_link_up(struct dsa_ - { - struct b53_device *dev = ds->priv; - -+ if (is63xx(dev) && port >= B53_63XX_RGMII0) -+ b53_adjust_63xx_rgmii(ds, port, interface); -+ - if (mode == MLO_AN_PHY) - return; - ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -211,6 +211,7 @@ static inline int is58xx(struct b53_devi - dev->chip_id == BCM7278_DEVICE_ID; - } - -+#define B53_63XX_RGMII0 4 - #define B53_CPU_PORT_25 5 - #define B53_CPU_PORT 8 - diff --git a/target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch b/target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch deleted file mode 100644 index 8ab701ef563a7a..00000000000000 --- a/target/linux/generic/pending-6.1/773-net-dsa-b53-mmap-add-more-63xx-SoCs.patch +++ /dev/null @@ -1,108 +0,0 @@ -From patchwork Tue Mar 21 17:33:57 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13183003 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 823A1C761AF - for ; Tue, 21 Mar 2023 17:35:06 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S230490AbjCURfE (ORCPT ); - Tue, 21 Mar 2023 13:35:04 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47440 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S230357AbjCURex (ORCPT - ); Tue, 21 Mar 2023 13:34:53 -0400 -Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com - [IPv6:2a00:1450:4864:20::430]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9A45559D8; - Tue, 21 Mar 2023 10:34:26 -0700 (PDT) -Received: by mail-wr1-x430.google.com with SMTP id m2so14547588wrh.6; - Tue, 21 Mar 2023 10:34:26 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679420063; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=cUvnluVaZPzfEQB9fMRuYo+4/361t/7po7nyUBBJfxc=; - b=F0pa8JmQZ1FeXVtdpCygur8UmLrgKwxCcjaMn312u5zNvsXsEPeCAIDqP2tvNNTwv/ - UYjaNaoZ77HSvv/gSqeG808AXGyNs1PvLuHZYuUTJRNuLaMixKtkNFi4ypheCdk0WCiE - IWz0DIm6ojmdwMqafDUKQ6Qwkv5R0vo8Wh5vpjimEmCelOyMvfuLZNqubsiGqpnCguBp - uWlmKh95/VubCGgiGG2xK1IXQayL14ENuWseDds7nVpVK50NycrFgJbL17Bd6qJKYkbo - m70IC+9jM0hjwKXpyi6ipCBNcW+1E6JIwILVC04Xi+BTpOGhbUAQ59Yn2hyq7tQM7dzs - 4PLg== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679420063; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=cUvnluVaZPzfEQB9fMRuYo+4/361t/7po7nyUBBJfxc=; - b=SCX78yTuGjdnE5nuL0p7+kxGnOzsCExsigLdaV+x/JswmwxSpZvxn223i1yM95klj9 - Rk0RnXqATLF1wZA7L1YmbeZ66zxUwW/osnCjJHPeEF8AGgjK/qawtLl/HJQHN67NaRNQ - bDsRn2nWQ2GRTRFpvD+iGRy4uyQCDu9HFxLbn43fBsBmRnXWGPQP5cEb90tL83/Onp4D - Lx/XcyZOh9QRfJNhj+G1BAeRCLRA/sdA0W3Ecu5SCFs+LtS6uvLVGWDKEDfnZhYY8Xqf - Mx9evWzdW2OorEN2FI6+xTglvnEBcVhHIJ7XEGAhCG6ocgMZeck++774S8RWumWl8xpy - /K9Q== -X-Gm-Message-State: AO0yUKUORAlGfbkNwnYmQnTWcGPqW6sp4g9WfgQmRZGCV+9tCB0OebSP - ICq6v4YPmUPNRl/WNnVCbps= -X-Google-Smtp-Source: - AK7set8pFDl8fHRwGPhAguqxIfqnQ4PY+b57IHEsybIaQ/HPNwdJ1cs1+IPBGHe3TL14dTS4aVNpHA== -X-Received: by 2002:a5d:6991:0:b0:2ce:aab5:f96b with SMTP id - g17-20020a5d6991000000b002ceaab5f96bmr2965175wru.67.1679420062764; - Tue, 21 Mar 2023 10:34:22 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.21 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Tue, 21 Mar 2023 10:34:21 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, - olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v2 2/4] net: dsa: b53: mmap: add more 63xx SoCs -Date: Tue, 21 Mar 2023 18:33:57 +0100 -Message-Id: <20230321173359.251778-3-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230321173359.251778-1-noltari@gmail.com> -References: <20230320155024.164523-1-noltari@gmail.com> - <20230321173359.251778-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -BCM6318, BCM6362 and BCM63268 are SoCs with a B53 MMAP switch. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Florian Fainelli ---- - v2: no changes. - - drivers/net/dsa/b53/b53_mmap.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/dsa/b53/b53_mmap.c -+++ b/drivers/net/dsa/b53/b53_mmap.c -@@ -345,8 +345,11 @@ static void b53_mmap_shutdown(struct pla - - static const struct of_device_id b53_mmap_of_table[] = { - { .compatible = "brcm,bcm3384-switch" }, -+ { .compatible = "brcm,bcm6318-switch" }, - { .compatible = "brcm,bcm6328-switch" }, -+ { .compatible = "brcm,bcm6362-switch" }, - { .compatible = "brcm,bcm6368-switch" }, -+ { .compatible = "brcm,bcm63268-switch" }, - { .compatible = "brcm,bcm63xx-switch" }, - { /* sentinel */ }, - }; diff --git a/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch b/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch deleted file mode 100644 index bb632b5eff4d99..00000000000000 --- a/target/linux/generic/pending-6.1/774-net-dsa-b53-mmap-allow-passing-a-chip-ID.patch +++ /dev/null @@ -1,195 +0,0 @@ -From patchwork Tue Mar 21 17:33:58 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13183004 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id B2B12C74A5B - for ; Tue, 21 Mar 2023 17:35:12 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S230297AbjCURfK (ORCPT ); - Tue, 21 Mar 2023 13:35:10 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47438 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S230374AbjCURex (ORCPT - ); Tue, 21 Mar 2023 13:34:53 -0400 -Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com - [IPv6:2a00:1450:4864:20::432]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C906B5550A; - Tue, 21 Mar 2023 10:34:26 -0700 (PDT) -Received: by mail-wr1-x432.google.com with SMTP id y14so14546846wrq.4; - Tue, 21 Mar 2023 10:34:26 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679420064; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=vnvnwWc5Tmg09HBQo/m9RbRM6yM8KLx8r1VA+Abfg3k=; - b=eFv+mwe94Y2YZMiJP5gydXVrGlbIAR5HCrY0rdcoGoMPzQUHLFckZeYCgEKudI55I7 - gMLZYCtLwvDXvKeHM2AUigsq2YuJSeF5QwICPrhTnMwUGBg4yyyltrc3+J0lSd6/4kQv - h0yM1Oo4v0d8CuqjBU6bXienIk34AFVJfsPq+vWQTjAbUL7ht4WHZ2Ez2MFoTvZpkIJA - 5iWMyVoMbugZl6eqNRjvDHFmtBtrZIv8AFs10r2Ca6+Yxm+aq0v33DRkbSVVqgFPNEzy - q5QOXOeLBPL6BvyovOpmVSWGoHf1zFV7lrzcqi+uc+FuYxQ9dyN3ND73DrrhWSkLaSg9 - r8yA== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679420064; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=vnvnwWc5Tmg09HBQo/m9RbRM6yM8KLx8r1VA+Abfg3k=; - b=jIRB8pIlrLA/ovhnEoePs/6SX8fn6l7l4fY2CxX2pLrTbP1JI8AAetPavvrNVQTr2M - Vm0iLbKyL/VpTq9+bSN1SMjaoi4lAMj0pgafoHrwABMVZpFauYvtCfSYTstZ2pw4Dr1j - wYQGj3BUSpFIYHtSIDMkb5449WA3T3TONhaQLRFAUCBD6gAFyEky5fY+DIHrGaj352B6 - 9ST/tkqHgPpuFlmromr42KQWoTFU+Pj0Uhyp7ru4BsnF7tTshWroZZIHUJmSACudEadr - fBPiuurX9jgp9zNqj8Oy0HjiVUnULFCapj8yICGp5s44uDAK/XFqFXpOuJ8ptS6uPazU - xUwg== -X-Gm-Message-State: AO0yUKX2w6QZfaGDHtlZAlY/U8F8VuJa3HwlgXbxgGChgdgvIoFThawv - oDyFAhWbVfe4DxwXTwxgJ/I= -X-Google-Smtp-Source: - AK7set+sH60XiJYup7bqrZTzFJVNe1YGcX/UTfjWV9xfGwNyodc34cHvKpqNagw5J+vEpv6CKvNHaA== -X-Received: by 2002:adf:f344:0:b0:2cd:de25:1c76 with SMTP id - e4-20020adff344000000b002cdde251c76mr12989754wrp.17.1679420064464; - Tue, 21 Mar 2023 10:34:24 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.22 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Tue, 21 Mar 2023 10:34:23 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, - olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v2 3/4] net: dsa: b53: mmap: allow passing a chip ID -Date: Tue, 21 Mar 2023 18:33:58 +0100 -Message-Id: <20230321173359.251778-4-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230321173359.251778-1-noltari@gmail.com> -References: <20230320155024.164523-1-noltari@gmail.com> - <20230321173359.251778-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -BCM6318 and BCM63268 SoCs require a special handling for their RGMIIs, so we -should be able to identify them as a special BCM63xx switch. - -Signed-off-by: Álvaro Fernández Rojas ---- - v2: - - Add missing chip to b53_switch_chips[]. - - Fix device_get_match_data() casting warning. - - Add BCM63268_DEVICE_ID to BCM6318 too. - - Add BCM6318 in commit description. - - drivers/net/dsa/b53/b53_common.c | 13 +++++++++++++ - drivers/net/dsa/b53/b53_mmap.c | 32 +++++++++++++++++++++++--------- - drivers/net/dsa/b53/b53_priv.h | 9 ++++++++- - 3 files changed, 44 insertions(+), 10 deletions(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -2469,6 +2469,19 @@ static const struct b53_chip_data b53_sw - .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, - }, - { -+ .chip_id = BCM63268_DEVICE_ID, -+ .dev_name = "BCM63268", -+ .vlans = 4096, -+ .enabled_ports = 0, /* pdata must provide them */ -+ .arl_bins = 4, -+ .arl_buckets = 1024, -+ .imp_port = 8, -+ .vta_regs = B53_VTA_REGS_63XX, -+ .duplex_reg = B53_DUPLEX_STAT_63XX, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, -+ }, -+ { - .chip_id = BCM53010_DEVICE_ID, - .dev_name = "BCM53010", - .vlans = 4096, ---- a/drivers/net/dsa/b53/b53_mmap.c -+++ b/drivers/net/dsa/b53/b53_mmap.c -@@ -262,7 +262,7 @@ static int b53_mmap_probe_of(struct plat - return -ENOMEM; - - pdata->regs = mem; -- pdata->chip_id = BCM63XX_DEVICE_ID; -+ pdata->chip_id = (u32)(unsigned long)device_get_match_data(dev); - pdata->big_endian = of_property_read_bool(np, "big-endian"); - - of_ports = of_get_child_by_name(np, "ports"); -@@ -344,14 +344,28 @@ static void b53_mmap_shutdown(struct pla - } - - static const struct of_device_id b53_mmap_of_table[] = { -- { .compatible = "brcm,bcm3384-switch" }, -- { .compatible = "brcm,bcm6318-switch" }, -- { .compatible = "brcm,bcm6328-switch" }, -- { .compatible = "brcm,bcm6362-switch" }, -- { .compatible = "brcm,bcm6368-switch" }, -- { .compatible = "brcm,bcm63268-switch" }, -- { .compatible = "brcm,bcm63xx-switch" }, -- { /* sentinel */ }, -+ { -+ .compatible = "brcm,bcm3384-switch", -+ .data = (void *)BCM63XX_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm6318-switch", -+ .data = (void *)BCM63268_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm6328-switch", -+ .data = (void *)BCM63XX_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm6362-switch", -+ .data = (void *)BCM63XX_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm6368-switch", -+ .data = (void *)BCM63XX_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm63268-switch", -+ .data = (void *)BCM63268_DEVICE_ID, -+ }, { -+ .compatible = "brcm,bcm63xx-switch", -+ .data = (void *)BCM63XX_DEVICE_ID, -+ }, { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, b53_mmap_of_table); - ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -70,6 +70,7 @@ enum { - BCM53125_DEVICE_ID = 0x53125, - BCM53128_DEVICE_ID = 0x53128, - BCM63XX_DEVICE_ID = 0x6300, -+ BCM63268_DEVICE_ID = 0x63268, - BCM53010_DEVICE_ID = 0x53010, - BCM53011_DEVICE_ID = 0x53011, - BCM53012_DEVICE_ID = 0x53012, -@@ -191,7 +192,13 @@ static inline int is531x5(struct b53_dev - - static inline int is63xx(struct b53_device *dev) - { -- return dev->chip_id == BCM63XX_DEVICE_ID; -+ return dev->chip_id == BCM63XX_DEVICE_ID || -+ dev->chip_id == BCM63268_DEVICE_ID; -+} -+ -+static inline int is63268(struct b53_device *dev) -+{ -+ return dev->chip_id == BCM63268_DEVICE_ID; - } - - static inline int is5301x(struct b53_device *dev) diff --git a/target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch b/target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch deleted file mode 100644 index d90d757fb2c2ae..00000000000000 --- a/target/linux/generic/pending-6.1/775-net-dsa-b53-add-BCM63268-RGMII-configuration.patch +++ /dev/null @@ -1,123 +0,0 @@ -From patchwork Tue Mar 21 17:33:59 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13183005 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 31BE4C761A6 - for ; Tue, 21 Mar 2023 17:35:16 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S229674AbjCURfN (ORCPT ); - Tue, 21 Mar 2023 13:35:13 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47684 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S230327AbjCURfB (ORCPT - ); Tue, 21 Mar 2023 13:35:01 -0400 -Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com - [IPv6:2a00:1450:4864:20::436]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E1D855507D; - Tue, 21 Mar 2023 10:34:27 -0700 (PDT) -Received: by mail-wr1-x436.google.com with SMTP id i9so14537769wrp.3; - Tue, 21 Mar 2023 10:34:27 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679420066; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=asmFs22xWYwR1Ql9m/IrNv+MPUNDn8hSjmwDRYvO7mE=; - b=Cqj2C6aG5vEOlhh9N3ybvDA0CV38nhQODnfdnr7utNddd323iDagoJty1Wmi3MAzj1 - 5ORmYT5fQvUnild7C4RhcCNTBn+MoYZ+wDZwZYelu6BKHkW11YFK949ax5B50by+ASR2 - z+rGI3wR5fVXd4VDgmcsT6zF5x69wKyhbhqIfrhG9BVFTctfaBgDS/l+bX1C56kSqv82 - bQkKSSAehSLGpFoCU3q62OGoZVi3jDe6HDb5M1Dp2mgHhqsW19otZpJ57DjtZ1CmtPai - o7T/ew6WoIYSl6whBmV36jeNaDJ3TItOBrKc4nMJBDWaCg4DNzUSe0ei5Xz7Oik5lb3p - y9ew== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679420066; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=asmFs22xWYwR1Ql9m/IrNv+MPUNDn8hSjmwDRYvO7mE=; - b=UdI2iQNBYwRf40ivf3ROR132t95BU/p3RUzXdZLCyz6c6JWtECQ5byyGeEwoX10n5u - HlepoNTJxMFLYrAHGvNLDPpWPuLXMa645S1mCVZ7NyWp8W96XzSynNZPeXHuJdb464QU - A7UTRSW3mlvKe9OR3EcB2CfBZv0yHWR0ldbnxcxGUFw8z78PNqpOVnITtjBdfpGesJ9c - VJw+fiM6hCcahor4nk9LLcAryPm8xmhDLxBKaLILO8wyTUiHY8G9hsXnFCtcpetnF5wS - pW13beAE+odb7ZZaXZUYpWGYhCe/hLzNjbo8YpgzHwadZthxPrT5YvNIYwyrvoViLM0n - KDRQ== -X-Gm-Message-State: AO0yUKW+9H/kqcAUyWeZhZJhiJjsBcYn1THmZaSDrPrk/pNuGXJXGtJd - NgsGZW8iSqLEv81yK+U5Os8= -X-Google-Smtp-Source: - AK7set/lzQZwCSxVaOe5dZ+7TR3xaQty/vg5xvZDpRW8TwTiPQblIbw5kJJTPLp67RySehrPIlCqSg== -X-Received: by 2002:a5d:65c9:0:b0:2ce:ac31:54ff with SMTP id - e9-20020a5d65c9000000b002ceac3154ffmr2776515wrw.2.1679420066191; - Tue, 21 Mar 2023 10:34:26 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - b13-20020a056000054d00b002da1261aa44sm184775wrf.48.2023.03.21.10.34.24 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Tue, 21 Mar 2023 10:34:25 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: f.fainelli@gmail.com, jonas.gorski@gmail.com, andrew@lunn.ch, - olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, - kuba@kernel.org, pabeni@redhat.com, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= , - Simon Horman -Subject: [PATCH v2 4/4] net: dsa: b53: add BCM63268 RGMII configuration -Date: Tue, 21 Mar 2023 18:33:59 +0100 -Message-Id: <20230321173359.251778-5-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230321173359.251778-1-noltari@gmail.com> -References: <20230320155024.164523-1-noltari@gmail.com> - <20230321173359.251778-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -BCM63268 requires special RGMII configuration to work. - -Signed-off-by: Álvaro Fernández Rojas -Reviewed-by: Florian Fainelli -Reviewed-by: Simon Horman ---- - v2: no changes. - - drivers/net/dsa/b53/b53_common.c | 6 +++++- - drivers/net/dsa/b53/b53_regs.h | 1 + - 2 files changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -1240,8 +1240,12 @@ static void b53_adjust_63xx_rgmii(struct - break; - } - -- if (port != dev->imp_port) -+ if (port != dev->imp_port) { -+ if (is63268(dev)) -+ rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE; -+ - rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII; -+ } - - b53_write8(dev, B53_CTRL_PAGE, off, rgmii_ctrl); - ---- a/drivers/net/dsa/b53/b53_regs.h -+++ b/drivers/net/dsa/b53/b53_regs.h -@@ -138,6 +138,7 @@ - - #define B53_RGMII_CTRL_IMP 0x60 - #define RGMII_CTRL_ENABLE_GMII BIT(7) -+#define RGMII_CTRL_MII_OVERRIDE BIT(6) - #define RGMII_CTRL_TIMING_SEL BIT(2) - #define RGMII_CTRL_DLL_RXC BIT(1) - #define RGMII_CTRL_DLL_TXC BIT(0) diff --git a/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch b/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch deleted file mode 100644 index 7bed8c22a4a8c8..00000000000000 --- a/target/linux/generic/pending-6.1/777-net-dsa-b53-mdio-add-support-for-BCM53134.patch +++ /dev/null @@ -1,189 +0,0 @@ -From patchwork Fri Mar 24 08:41:38 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13186549 -X-Patchwork-Delegate: kuba@kernel.org -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id EF744C76195 - for ; Fri, 24 Mar 2023 08:42:01 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S231807AbjCXImA (ORCPT ); - Fri, 24 Mar 2023 04:42:00 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32956 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S231272AbjCXIly (ORCPT - ); Fri, 24 Mar 2023 04:41:54 -0400 -Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com - [IPv6:2a00:1450:4864:20::535]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 113A517CF3; - Fri, 24 Mar 2023 01:41:46 -0700 (PDT) -Received: by mail-ed1-x535.google.com with SMTP id ek18so4877175edb.6; - Fri, 24 Mar 2023 01:41:45 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679647304; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=OfUWRaFIQIQw/lRivER+LHryfdLliXzvabGrcmkQVEU=; - b=JMrl6Eay1FS0JZqgPHsbcVzuNAbFELc0SLNGyzYtOVQXcI+YwKDM9Ls7I9PsQVEPoZ - CthomCTYoz5G9DU7uBuia207rnjOhssZJRu0syrCoU+O/ZiQyGLJDvq61z5oZJxC2S40 - kzRsUsC6MRjn64DKPWmxhsSTMKLzn2+P233LKNFbHtfi3NWF5Qu/85sUkxMurnfUgja0 - qQhl25qYY7ZIvmlFHYefaI5UkITQFuiybrqJW9tztCdHf/gS+f33YkkvQ8njmMQa1DW0 - ppedfOUotX+6kmHZGX1yea2V5ezEGGvRourZtYMoecTiD0E5d1J1bKhktKslVLIDm0ig - oc2g== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679647304; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=OfUWRaFIQIQw/lRivER+LHryfdLliXzvabGrcmkQVEU=; - b=b3Gmga5ZDbnmQfnw1GCz+eU2JwgsVzfciZuSmfYAiVxpW4c6cur3MHbpzDPhi99wzA - ZYAM7ryLv88rXl/tQB5g2Nte5rvMfxUeHXsT/JpsRcSSocFRbRrk0QJyiA/Xj86NiD5N - C1sKz50Im190FmrvPcBh6OHQbv/3MQyE+1fQx+9q3jW5rQiAWQaYk4Ng8GlWA7gtG3jB - fHO6Fuoenn32pgkveJbQLYL/2t2f53wGf3QLQ3IeKW7jdfIHNThwrwqBMxdHoIDaTBT9 - UWMeJuiYtylIibo/3zbORbWOgIERlWxZRf3BCOFpnzUn4eBzio4LgjtNxZ77ITRxsmbk - 3+Hg== -X-Gm-Message-State: AAQBX9dfyBfbR7Sdd5wqxMiAv3Yhk47pK1XzD87MZyAF3AxyoFyKcMaF - EbwJLyRvTGQEFdVWCGw1eMU= -X-Google-Smtp-Source: - AKy350bpDVLq7k1FxG2Mek/VIobZL4KhufiKx8qfmpxpcWmLI3bLg8wfQKEAKJRNJBleo/7CZuCL5g== -X-Received: by 2002:aa7:c711:0:b0:4a2:588f:b3c5 with SMTP id - i17-20020aa7c711000000b004a2588fb3c5mr2261236edq.21.1679647304260; - Fri, 24 Mar 2023 01:41:44 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - z21-20020a50cd15000000b004acbda55f6bsm10323728edi.27.2023.03.24.01.41.43 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Fri, 24 Mar 2023 01:41:43 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: paul.geurts@prodrive-technologies.com, f.fainelli@gmail.com, - jonas.gorski@gmail.com, andrew@lunn.ch, olteanv@gmail.com, - davem@davemloft.net, edumazet@google.com, kuba@kernel.org, - pabeni@redhat.com, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, netdev@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v2 2/2] net: dsa: b53: mdio: add support for BCM53134 -Date: Fri, 24 Mar 2023 09:41:38 +0100 -Message-Id: <20230324084138.664285-3-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230324084138.664285-1-noltari@gmail.com> -References: <20230323121804.2249605-1-noltari@gmail.com> - <20230324084138.664285-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: netdev@vger.kernel.org -X-Patchwork-Delegate: kuba@kernel.org - -From: Paul Geurts - -Add support for the BCM53134 Ethernet switch in the existing b53 dsa driver. -BCM53134 is very similar to the BCM58XX series. - -Signed-off-by: Paul Geurts -Signed-off-by: Álvaro Fernández Rojas ---- - v2: add BCM53134 to is531x5() and remove special RGMII config - - drivers/net/dsa/b53/b53_common.c | 15 +++++++++++++++ - drivers/net/dsa/b53/b53_mdio.c | 5 ++++- - drivers/net/dsa/b53/b53_priv.h | 7 +++++-- - 3 files changed, 24 insertions(+), 3 deletions(-) - ---- a/drivers/net/dsa/b53/b53_common.c -+++ b/drivers/net/dsa/b53/b53_common.c -@@ -2616,6 +2616,20 @@ static const struct b53_chip_data b53_sw - .jumbo_pm_reg = B53_JUMBO_PORT_MASK, - .jumbo_size_reg = B53_JUMBO_MAX_SIZE, - }, -+ { -+ .chip_id = BCM53134_DEVICE_ID, -+ .dev_name = "BCM53134", -+ .vlans = 4096, -+ .enabled_ports = 0x12f, -+ .imp_port = 8, -+ .cpu_port = B53_CPU_PORT, -+ .vta_regs = B53_VTA_REGS, -+ .arl_bins = 4, -+ .arl_buckets = 1024, -+ .duplex_reg = B53_DUPLEX_STAT_GE, -+ .jumbo_pm_reg = B53_JUMBO_PORT_MASK, -+ .jumbo_size_reg = B53_JUMBO_MAX_SIZE, -+ }, - }; - - static int b53_switch_init(struct b53_device *dev) -@@ -2793,6 +2807,7 @@ int b53_switch_detect(struct b53_device - case BCM53012_DEVICE_ID: - case BCM53018_DEVICE_ID: - case BCM53019_DEVICE_ID: -+ case BCM53134_DEVICE_ID: - dev->chip_id = id32; - break; - default: ---- a/drivers/net/dsa/b53/b53_mdio.c -+++ b/drivers/net/dsa/b53/b53_mdio.c -@@ -286,6 +286,7 @@ static const struct b53_io_ops b53_mdio_ - #define B53_BRCM_OUI_2 0x03625c00 - #define B53_BRCM_OUI_3 0x00406000 - #define B53_BRCM_OUI_4 0x01410c00 -+#define B53_BRCM_OUI_5 0xae025000 - - static int b53_mdio_probe(struct mdio_device *mdiodev) - { -@@ -313,7 +314,8 @@ static int b53_mdio_probe(struct mdio_de - if ((phy_id & 0xfffffc00) != B53_BRCM_OUI_1 && - (phy_id & 0xfffffc00) != B53_BRCM_OUI_2 && - (phy_id & 0xfffffc00) != B53_BRCM_OUI_3 && -- (phy_id & 0xfffffc00) != B53_BRCM_OUI_4) { -+ (phy_id & 0xfffffc00) != B53_BRCM_OUI_4 && -+ (phy_id & 0xfffffc00) != B53_BRCM_OUI_5) { - dev_err(&mdiodev->dev, "Unsupported device: 0x%08x\n", phy_id); - return -ENODEV; - } -@@ -375,6 +377,7 @@ static const struct of_device_id b53_of_ - { .compatible = "brcm,bcm53115" }, - { .compatible = "brcm,bcm53125" }, - { .compatible = "brcm,bcm53128" }, -+ { .compatible = "brcm,bcm53134" }, - { .compatible = "brcm,bcm5365" }, - { .compatible = "brcm,bcm5389" }, - { .compatible = "brcm,bcm5395" }, ---- a/drivers/net/dsa/b53/b53_priv.h -+++ b/drivers/net/dsa/b53/b53_priv.h -@@ -80,6 +80,7 @@ enum { - BCM583XX_DEVICE_ID = 0x58300, - BCM7445_DEVICE_ID = 0x7445, - BCM7278_DEVICE_ID = 0x7278, -+ BCM53134_DEVICE_ID = 0x5075, - }; - - struct b53_pcs { -@@ -187,7 +188,8 @@ static inline int is531x5(struct b53_dev - { - return dev->chip_id == BCM53115_DEVICE_ID || - dev->chip_id == BCM53125_DEVICE_ID || -- dev->chip_id == BCM53128_DEVICE_ID; -+ dev->chip_id == BCM53128_DEVICE_ID || -+ dev->chip_id == BCM53134_DEVICE_ID; - } - - static inline int is63xx(struct b53_device *dev) -@@ -215,7 +217,8 @@ static inline int is58xx(struct b53_devi - return dev->chip_id == BCM58XX_DEVICE_ID || - dev->chip_id == BCM583XX_DEVICE_ID || - dev->chip_id == BCM7445_DEVICE_ID || -- dev->chip_id == BCM7278_DEVICE_ID; -+ dev->chip_id == BCM7278_DEVICE_ID || -+ dev->chip_id == BCM53134_DEVICE_ID; - } - - #define B53_63XX_RGMII0 4 diff --git a/target/linux/generic/pending-6.1/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch b/target/linux/generic/pending-6.1/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch deleted file mode 100644 index 39ba71606ec235..00000000000000 --- a/target/linux/generic/pending-6.1/780-ARM-kirkwood-add-missing-linux-if_ether.h-for-ETH_AL.patch +++ /dev/null @@ -1,61 +0,0 @@ -From patchwork Thu Aug 5 22:23:30 2021 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Daniel Golle -X-Patchwork-Id: 12422209 -Date: Thu, 5 Aug 2021 23:23:30 +0100 -From: Daniel Golle -To: linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org, - linux-kernel@vger.kernel.org -Cc: "David S. Miller" , Andrew Lunn , - Michael Walle -Subject: [PATCH] ARM: kirkwood: add missing for ETH_ALEN -Message-ID: -MIME-Version: 1.0 -Content-Disposition: inline -X-BeenThere: linux-arm-kernel@lists.infradead.org -X-Mailman-Version: 2.1.34 -Precedence: list -List-Id: -List-Archive: -Sender: "linux-arm-kernel" - -After commit 83216e3988cd1 ("of: net: pass the dst buffer to -of_get_mac_address()") build fails for kirkwood as ETH_ALEN is not -defined. - -arch/arm/mach-mvebu/kirkwood.c: In function 'kirkwood_dt_eth_fixup': -arch/arm/mach-mvebu/kirkwood.c:87:13: error: 'ETH_ALEN' undeclared (first use in this function); did you mean 'ESTALE'? - u8 tmpmac[ETH_ALEN]; - ^~~~~~~~ - ESTALE -arch/arm/mach-mvebu/kirkwood.c:87:13: note: each undeclared identifier is reported only once for each function it appears in -arch/arm/mach-mvebu/kirkwood.c:87:6: warning: unused variable 'tmpmac' [-Wunused-variable] - u8 tmpmac[ETH_ALEN]; - ^~~~~~ -make[5]: *** [scripts/Makefile.build:262: arch/arm/mach-mvebu/kirkwood.o] Error 1 -make[5]: *** Waiting for unfinished jobs.... - -Add missing #include to fix this. - -Cc: David S. Miller -Cc: Andrew Lunn -Cc: Michael Walle -Reported-by: https://buildbot.openwrt.org/master/images/#/builders/56/builds/220/steps/44/logs/stdio -Fixes: 83216e3988cd1 ("of: net: pass the dst buffer to of_get_mac_address()") -Signed-off-by: Daniel Golle ---- - arch/arm/mach-mvebu/kirkwood.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/mach-mvebu/kirkwood.c -+++ b/arch/arm/mach-mvebu/kirkwood.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/target/linux/generic/pending-6.1/790-bus-mhi-core-add-SBL-state-callback.patch b/target/linux/generic/pending-6.1/790-bus-mhi-core-add-SBL-state-callback.patch deleted file mode 100644 index fe0f260ae36c6f..00000000000000 --- a/target/linux/generic/pending-6.1/790-bus-mhi-core-add-SBL-state-callback.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 5f7c5e1c0d7a79be144e5efc1f24728ddd7fc25c Mon Sep 17 00:00:00 2001 -From: Robert Marko -Date: Sat, 5 Nov 2022 20:02:56 +0100 -Subject: [PATCH 1/2] bus: mhi: core: add SBL state callback - -Add support for SBL state callback in MHI core. - -It is required for ath11k MHI devices in order to be able to set QRTR -instance ID in the SBL state so that QRTR instance ID-s dont conflict in -case of multiple PCI/MHI cards or AHB + PCI/MHI card. -Setting QRTR instance ID is only possible in SBL state and there is -currently no way to ensure that we are in that state, so provide a -callback that the controller can trigger off. - -Signed-off-by: Robert Marko ---- - drivers/bus/mhi/host/main.c | 1 + - include/linux/mhi.h | 2 ++ - 2 files changed, 3 insertions(+) - ---- a/drivers/bus/mhi/host/main.c -+++ b/drivers/bus/mhi/host/main.c -@@ -906,6 +906,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_ - switch (event) { - case MHI_EE_SBL: - st = DEV_ST_TRANSITION_SBL; -+ mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_SBL_MODE); - break; - case MHI_EE_WFW: - case MHI_EE_AMSS: ---- a/include/linux/mhi.h -+++ b/include/linux/mhi.h -@@ -34,6 +34,7 @@ struct mhi_buf_info; - * @MHI_CB_SYS_ERROR: MHI device entered error state (may recover) - * @MHI_CB_FATAL_ERROR: MHI device entered fatal error state - * @MHI_CB_BW_REQ: Received a bandwidth switch request from device -+ * @MHI_CB_EE_SBL_MODE: MHI device entered SBL mode - */ - enum mhi_callback { - MHI_CB_IDLE, -@@ -45,6 +46,7 @@ enum mhi_callback { - MHI_CB_SYS_ERROR, - MHI_CB_FATAL_ERROR, - MHI_CB_BW_REQ, -+ MHI_CB_EE_SBL_MODE, - }; - - /** diff --git a/target/linux/generic/pending-6.1/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch b/target/linux/generic/pending-6.1/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch deleted file mode 100644 index 478a2cb27d8014..00000000000000 --- a/target/linux/generic/pending-6.1/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch +++ /dev/null @@ -1,73 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH] bcma: get SoC device struct & copy its DMA params to the - subdevices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -For bus devices to be fully usable it's required to set their DMA -parameters. - -For years it has been missing and remained unnoticed because of -mips_dma_alloc_coherent() silently handling the empty coherent_dma_mask. -Kernel 4.19 came with a lot of DMA changes and caused a regression on -the bcm47xx. Starting with the commit f8c55dc6e828 ("MIPS: use generic -dma noncoherent ops for simple noncoherent platforms") DMA coherent -allocations just fail. Example: -[ 1.114914] bgmac_bcma bcma0:2: Allocation of TX ring 0x200 failed -[ 1.121215] bgmac_bcma bcma0:2: Unable to alloc memory for DMA -[ 1.127626] bgmac_bcma: probe of bcma0:2 failed with error -12 -[ 1.133838] bgmac_bcma: Broadcom 47xx GBit MAC driver loaded - -This change fixes above regression in addition to the MIPS bcm47xx -commit 321c46b91550 ("MIPS: BCM47XX: Setup struct device for the SoC"). - -It also fixes another *old* GPIO regression caused by a parent pointing -to the NULL: -[ 0.157054] missing gpiochip .dev parent pointer -[ 0.157287] bcma: bus0: Error registering GPIO driver: -22 -introduced by the commit 74f4e0cc6108 ("bcma: switch GPIO portions to -use GPIOLIB_IRQCHIP"). - -Fixes: f8c55dc6e828 ("MIPS: use generic dma noncoherent ops for simple noncoherent platforms") -Fixes: 74f4e0cc6108 ("bcma: switch GPIO portions to use GPIOLIB_IRQCHIP") -Cc: linux-mips@linux-mips.org -Cc: Christoph Hellwig -Cc: Linus Walleij -Signed-off-by: Rafał Miłecki ---- - ---- a/drivers/bcma/host_soc.c -+++ b/drivers/bcma/host_soc.c -@@ -191,6 +191,8 @@ int __init bcma_host_soc_init(struct bcm - struct bcma_bus *bus = &soc->bus; - int err; - -+ bus->dev = soc->dev; -+ - /* Scan bus and initialize it */ - err = bcma_bus_early_register(bus); - if (err) ---- a/drivers/bcma/main.c -+++ b/drivers/bcma/main.c -@@ -236,13 +236,17 @@ EXPORT_SYMBOL(bcma_core_irq); - - void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) - { -- device_initialize(&core->dev); -+ struct device *dev = &core->dev; -+ -+ device_initialize(dev); - core->dev.release = bcma_release_core_dev; - core->dev.bus = &bcma_bus_type; -- dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); -+ dev_set_name(dev, "bcma%d:%d", bus->num, core->core_index); - core->dev.parent = bus->dev; -- if (bus->dev) -+ if (bus->dev) { - bcma_of_fill_device(bus->dev, core); -+ dma_coerce_mask_and_coherent(dev, bus->dev->coherent_dma_mask); -+ } - - switch (bus->hosttype) { - case BCMA_HOSTTYPE_PCI: diff --git a/target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch b/target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch deleted file mode 100644 index 815231973d9ff3..00000000000000 --- a/target/linux/generic/pending-6.1/801-gpio-gpio-cascade-add-generic-GPIO-cascade.patch +++ /dev/null @@ -1,222 +0,0 @@ -From fc23ea48ba52c24f201fe5ca0132ee1a3de5a70a Mon Sep 17 00:00:00 2001 -From: Mauri Sandberg -Date: Thu, 25 Mar 2021 11:48:05 +0200 -Subject: [PATCH 2/2] gpio: gpio-cascade: add generic GPIO cascade - -Adds support for building cascades of GPIO lines. That is, it allows -setups when there is one upstream line and multiple cascaded lines, out -of which one can be chosen at a time. The status of the upstream line -can be conveyed to the selected cascaded line or, vice versa, the status -of the cascaded line can be conveyed to the upstream line. - -A multiplexer is being used to select, which cascaded GPIO line is being -used at any given time. - -At the moment only input direction is supported. In future it should be -possible to add support for output direction, too. - -Signed-off-by: Mauri Sandberg -Reviewed-by: Linus Walleij -Reviewed-by: Andy Shevchenko ---- -v7 -> v8: - - rearrange members in struct gpio_cascade - - cosmetic changes in file header and in one function declaration - - added Reviewed-by tags by Linus and Andy -v6 -> v7: - - In Kconfig add info about module name - - adhere to new convention that allows lines longer than 80 chars - - use dev_probe_err with upstream gpio line too - - refactor for cleaner exit of probe function. -v5 -> v6: - - In Kconfig, remove dependency to OF_GPIO and select only MULTIPLEXER - - refactor code preferring one-liners - - clean up prints, removing them from success-path. - - don't explicitly set gpio_chip.of_node as it's done in the GPIO library - - use devm_gpiochip_add_data instead of gpiochip_add -v4 -> v5: - - renamed gpio-mux-input -> gpio-cascade. refactored code accordingly - here and there and changed to use new bindings and compatible string - - ambigious and vague 'pin' was rename to 'upstream_line' - - dropped Tested-by and Reviewed-by due to changes in bindings - - dropped Reported-by suggested by an automatic bot as it was not really - appropriate to begin with - - functionally it's the same as v4 -v3 -> v4: - - Changed author email - - Included Tested-by and Reviewed-by from Drew -v2 -> v3: - - use managed device resources - - update Kconfig description -v1 -> v2: - - removed .owner from platform_driver as per test bot's instruction - - added MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE - - added gpio_mux_input_get_direction as it's recommended for all chips - - removed because this is input only chip: gpio_mux_input_set_value - - removed because they are not needed for input/output only chips: - gpio_mux_input_direction_input - gpio_mux_input_direction_output - - fixed typo in an error message - - added info message about successful registration - - removed can_sleep flag as this does not sleep while getting GPIO value - like I2C or SPI do - - Updated description in Kconfig ---- - drivers/gpio/Kconfig | 15 +++++ - drivers/gpio/Makefile | 1 + - drivers/gpio/gpio-cascade.c | 117 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 133 insertions(+) - create mode 100644 drivers/gpio/gpio-cascade.c - ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -1712,4 +1712,19 @@ config GPIO_SIM - - endmenu - -+comment "Other GPIO expanders" -+ -+config GPIO_CASCADE -+ tristate "General GPIO cascade" -+ select MULTIPLEXER -+ help -+ Say yes here to enable support for generic GPIO cascade. -+ -+ This allows building one-to-many cascades of GPIO lines using -+ different types of multiplexers readily available. At the -+ moment only input lines are supported. -+ -+ To build the driver as a module choose 'm' and the resulting module -+ will be called 'gpio-cascade'. -+ - endif ---- a/drivers/gpio/Makefile -+++ b/drivers/gpio/Makefile -@@ -43,6 +43,7 @@ obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd - obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o - obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o - obj-$(CONFIG_GPIO_CADENCE) += gpio-cadence.o -+obj-$(CONFIG_GPIO_CASCADE) += gpio-cascade.o - obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o - obj-$(CONFIG_GPIO_SNPS_CREG) += gpio-creg-snps.o - obj-$(CONFIG_GPIO_CRYSTAL_COVE) += gpio-crystalcove.o ---- /dev/null -+++ b/drivers/gpio/gpio-cascade.c -@@ -0,0 +1,117 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * A generic GPIO cascade driver -+ * -+ * Copyright (C) 2021 Mauri Sandberg -+ * -+ * This allows building cascades of GPIO lines in a manner illustrated -+ * below: -+ * -+ * /|---- Cascaded GPIO line 0 -+ * Upstream | |---- Cascaded GPIO line 1 -+ * GPIO line ----+ | . -+ * | | . -+ * \|---- Cascaded GPIO line n -+ * -+ * A multiplexer is being used to select, which cascaded line is being -+ * addressed at any given time. -+ * -+ * At the moment only input mode is supported due to lack of means for -+ * testing output functionality. At least theoretically output should be -+ * possible with open drain constructions. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+struct gpio_cascade { -+ struct gpio_chip gpio_chip; -+ struct device *parent; -+ struct mux_control *mux_control; -+ struct gpio_desc *upstream_line; -+}; -+ -+static struct gpio_cascade *chip_to_cascade(struct gpio_chip *gc) -+{ -+ return container_of(gc, struct gpio_cascade, gpio_chip); -+} -+ -+static int gpio_cascade_get_direction(struct gpio_chip *gc, unsigned int offset) -+{ -+ return GPIO_LINE_DIRECTION_IN; -+} -+ -+static int gpio_cascade_get_value(struct gpio_chip *gc, unsigned int offset) -+{ -+ struct gpio_cascade *cas = chip_to_cascade(gc); -+ int ret; -+ -+ ret = mux_control_select(cas->mux_control, offset); -+ if (ret) -+ return ret; -+ -+ ret = gpiod_get_value(cas->upstream_line); -+ mux_control_deselect(cas->mux_control); -+ return ret; -+} -+ -+static int gpio_cascade_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct gpio_cascade *cas; -+ struct mux_control *mc; -+ struct gpio_desc *upstream; -+ struct gpio_chip *gc; -+ -+ cas = devm_kzalloc(dev, sizeof(*cas), GFP_KERNEL); -+ if (!cas) -+ return -ENOMEM; -+ -+ mc = devm_mux_control_get(dev, NULL); -+ if (IS_ERR(mc)) -+ return dev_err_probe(dev, PTR_ERR(mc), "unable to get mux-control\n"); -+ -+ cas->mux_control = mc; -+ upstream = devm_gpiod_get(dev, "upstream", GPIOD_IN); -+ if (IS_ERR(upstream)) -+ return dev_err_probe(dev, PTR_ERR(upstream), "unable to claim upstream GPIO line\n"); -+ -+ cas->upstream_line = upstream; -+ cas->parent = dev; -+ -+ gc = &cas->gpio_chip; -+ gc->get = gpio_cascade_get_value; -+ gc->get_direction = gpio_cascade_get_direction; -+ gc->base = -1; -+ gc->ngpio = mux_control_states(mc); -+ gc->label = dev_name(cas->parent); -+ gc->parent = cas->parent; -+ gc->owner = THIS_MODULE; -+ -+ platform_set_drvdata(pdev, cas); -+ return devm_gpiochip_add_data(dev, &cas->gpio_chip, NULL); -+} -+ -+static const struct of_device_id gpio_cascade_id[] = { -+ { .compatible = "gpio-cascade" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, gpio_cascade_id); -+ -+static struct platform_driver gpio_cascade_driver = { -+ .driver = { -+ .name = "gpio-cascade", -+ .of_match_table = gpio_cascade_id, -+ }, -+ .probe = gpio_cascade_probe, -+}; -+module_platform_driver(gpio_cascade_driver); -+ -+MODULE_AUTHOR("Mauri Sandberg "); -+MODULE_DESCRIPTION("Generic GPIO cascade"); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch b/target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch deleted file mode 100644 index 2b3e4bbf716259..00000000000000 --- a/target/linux/generic/pending-6.1/802-OPP-Provide-old-opp-to-config_clks-on-_set_opp.patch +++ /dev/null @@ -1,108 +0,0 @@ -From fd59b838dd90452f61a17dc9e5ff175205003068 Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Thu, 15 Sep 2022 18:49:43 +0200 -Subject: [PATCH] OPP: Provide old opp to config_clks on _set_opp - -With the target opp, also pass the old opp to config_clks function. -This can be useful when a driver needs to take decision on what fequency -to set based on what is the current frequency without using a -clk_get_freq call. -Update the only user of custom config_clks (tegra30 devfreq driver) to -this new implementation. - -Signed-off-by: Christian Marangi ---- - drivers/devfreq/tegra30-devfreq.c | 5 +++-- - drivers/opp/core.c | 11 ++++++----- - include/linux/pm_opp.h | 11 ++++++----- - 3 files changed, 15 insertions(+), 12 deletions(-) - ---- a/drivers/devfreq/tegra30-devfreq.c -+++ b/drivers/devfreq/tegra30-devfreq.c -@@ -823,8 +823,9 @@ static int devm_tegra_devfreq_init_hw(st - - static int tegra_devfreq_config_clks_nop(struct device *dev, - struct opp_table *opp_table, -- struct dev_pm_opp *opp, void *data, -- bool scaling_down) -+ struct dev_pm_opp *old_opp, -+ struct dev_pm_opp *opp, -+ void *data, bool scaling_down) - { - /* We want to skip clk configuration via dev_pm_opp_set_opp() */ - return 0; ---- a/drivers/opp/core.c -+++ b/drivers/opp/core.c -@@ -816,7 +816,8 @@ static int _set_opp_voltage(struct devic - - static int - _opp_config_clk_single(struct device *dev, struct opp_table *opp_table, -- struct dev_pm_opp *opp, void *data, bool scaling_down) -+ struct dev_pm_opp *old_opp, struct dev_pm_opp *opp, -+ void *data, bool scaling_down) - { - unsigned long *target = data; - unsigned long freq; -@@ -848,8 +849,8 @@ _opp_config_clk_single(struct device *de - * the order in which they are present in the array while scaling up. - */ - int dev_pm_opp_config_clks_simple(struct device *dev, -- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, -- bool scaling_down) -+ struct opp_table *opp_table, struct dev_pm_opp *old_opp, -+ struct dev_pm_opp *opp, void *data, bool scaling_down) - { - int ret, i; - -@@ -1121,7 +1122,7 @@ static int _set_opp(struct device *dev, - } - - if (opp_table->config_clks) { -- ret = opp_table->config_clks(dev, opp_table, opp, clk_data, scaling_down); -+ ret = opp_table->config_clks(dev, opp_table, old_opp, opp, clk_data, scaling_down); - if (ret) - return ret; - } -@@ -1196,7 +1197,7 @@ int dev_pm_opp_set_rate(struct device *d - * equivalent to a clk_set_rate() - */ - if (!_get_opp_count(opp_table)) { -- ret = opp_table->config_clks(dev, opp_table, NULL, -+ ret = opp_table->config_clks(dev, opp_table, NULL, NULL, - &target_freq, false); - goto put_opp_table; - } ---- a/include/linux/pm_opp.h -+++ b/include/linux/pm_opp.h -@@ -61,7 +61,8 @@ typedef int (*config_regulators_t)(struc - struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp, - struct regulator **regulators, unsigned int count); - --typedef int (*config_clks_t)(struct device *dev, struct opp_table *opp_table, -+typedef int (*config_clks_t)(struct device *dev, -+ struct opp_table *opp_table, struct dev_pm_opp *old_opp, - struct dev_pm_opp *opp, void *data, bool scaling_down); - - /** -@@ -160,8 +161,8 @@ int dev_pm_opp_set_config(struct device - int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config); - void dev_pm_opp_clear_config(int token); - int dev_pm_opp_config_clks_simple(struct device *dev, -- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, -- bool scaling_down); -+ struct opp_table *opp_table, struct dev_pm_opp *old_opp, -+ struct dev_pm_opp *opp, void *data, bool scaling_down); - - struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp); - int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); -@@ -346,8 +347,8 @@ static inline int devm_pm_opp_set_config - static inline void dev_pm_opp_clear_config(int token) {} - - static inline int dev_pm_opp_config_clks_simple(struct device *dev, -- struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, -- bool scaling_down) -+ struct opp_table *opp_table, struct dev_pm_opp *old_opp, -+ struct dev_pm_opp *opp, void *data, bool scaling_down) - { - return -EOPNOTSUPP; - } diff --git a/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch b/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch deleted file mode 100644 index 29fe668f8de98a..00000000000000 --- a/target/linux/generic/pending-6.1/802-nvmem-u-boot-env-align-endianness-of-crc32-values.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0e71cac033bb7689c4dfa2e6814191337ef770f5 Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Thu, 13 Oct 2022 00:51:33 +0900 -Subject: [PATCH] nvmem: layouts: u-boot-env: align endianness of crc32 values -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch fixes crc32 error on Big-Endianness system by conversion of -calculated crc32 value. - -Little-Endianness system: - - obtained crc32: Little -calculated crc32: Little - -Big-Endianness system: - - obtained crc32: Little -calculated crc32: Big - -log (APRESIA ApresiaLightGS120GT-SS, RTL8382M, Big-Endianness): - -[ 8.570000] u_boot_env 18001200.spi:flash@0:partitions:partition@c0000: Invalid calculated CRC32: 0x88cd6f09 (expected: 0x096fcd88) -[ 8.580000] u_boot_env: probe of 18001200.spi:flash@0:partitions:partition@c0000 failed with error -22 - -Fixes: f955dc1445069 ("nvmem: add driver handling U-Boot environment variables") - -Signed-off-by: INAGAKI Hiroshi -Acked-by: Rafał Miłecki -Tested-by: Christian Lamparter -Signed-off-by: Srinivas Kandagatla ---- - ---- a/drivers/nvmem/layouts/u-boot-env.c -+++ b/drivers/nvmem/layouts/u-boot-env.c -@@ -148,7 +148,7 @@ int u_boot_env_parse(struct device *dev, - crc32_data_len = dev_size - crc32_data_offset; - data_len = dev_size - data_offset; - -- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L; -+ calc = le32_to_cpu((__le32)crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L); - if (calc != crc32) { - dev_err(dev, "Invalid calculated CRC32: 0x%08x (expected: 0x%08x)\n", calc, crc32); - err = -EINVAL; diff --git a/target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch b/target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch deleted file mode 100644 index 29cda1824e2ed0..00000000000000 --- a/target/linux/generic/pending-6.1/804-nvmem-core-support-mac-base-fixed-layout-cells.patch +++ /dev/null @@ -1,124 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 13 Jul 2023 18:29:19 +0200 -Subject: [PATCH] nvmem: core: support "mac-base" fixed layout cells - -Fixed layout binding allows specifying "mac-base" NVMEM cells. It's used -for base MAC address (that can be used for calculating relative -addresses). It can be stored in a raw binary format or as an ASCII -string. ---- - ---- a/drivers/nvmem/Kconfig -+++ b/drivers/nvmem/Kconfig -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0-only - menuconfig NVMEM - bool "NVMEM Support" -+ select GENERIC_NET_UTILS - imply NVMEM_LAYOUTS - help - Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES... ---- a/drivers/nvmem/core.c -+++ b/drivers/nvmem/core.c -@@ -7,9 +7,12 @@ - */ - - #include -+#include -+#include - #include - #include - #include -+#include - #include - #include - #include -@@ -797,6 +800,62 @@ static int nvmem_validate_keepouts(struc - return 0; - } - -+static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ if (WARN_ON(bytes != ETH_ALEN)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(buf, index); -+ -+ return 0; -+} -+ -+static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN]; -+ -+ if (WARN_ON(bytes != 3 * ETH_ALEN - 1)) -+ return -EINVAL; -+ -+ if (!mac_pton(buf, mac)) -+ return -EINVAL; -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ -+static int nvmem_mac_base_hex_read(void *context, const char *id, int index, unsigned int offset, -+ void *buf, size_t bytes) -+{ -+ u8 mac[ETH_ALEN], *hexstr; -+ int i; -+ -+ if (WARN_ON(bytes != 2 * ETH_ALEN)) -+ return -EINVAL; -+ -+ hexstr = (u8 *)buf; -+ for (i = 0; i < ETH_ALEN; i++) { -+ if (!isxdigit(hexstr[i * 2]) || !isxdigit(hexstr[i * 2 + 1])) -+ return -EINVAL; -+ -+ mac[i] = (hex_to_bin(hexstr[i * 2]) << 4) | hex_to_bin(hexstr[i * 2 + 1]); -+ } -+ -+ if (index) -+ eth_addr_add(mac, index); -+ -+ ether_addr_copy(buf, mac); -+ -+ return 0; -+} -+ - static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) - { - struct device *dev = &nvmem->dev; -@@ -836,6 +895,25 @@ static int nvmem_add_cells_from_dt(struc - if (nvmem->fixup_dt_cell_info) - nvmem->fixup_dt_cell_info(nvmem, &info); - -+ if (of_device_is_compatible(np, "fixed-layout")) { -+ if (of_device_is_compatible(child, "mac-base")) { -+ if (info.bytes == ETH_ALEN) { -+ info.raw_len = info.bytes; -+ info.bytes = ETH_ALEN; -+ info.read_post_process = nvmem_mac_base_raw_read; -+ } else if (info.bytes == 2 * ETH_ALEN) { -+ info.raw_len = info.bytes; -+ info.bytes = ETH_ALEN; -+ info.read_post_process = nvmem_mac_base_hex_read; -+ } else if (info.bytes == 3 * ETH_ALEN - 1) { -+ info.raw_len = info.bytes; -+ info.bytes = ETH_ALEN; -+ info.read_post_process = nvmem_mac_base_ascii_read; -+ } -+ -+ } -+ } -+ - ret = nvmem_add_one_cell(nvmem, &info); - kfree(info.name); - if (ret) { diff --git a/target/linux/generic/pending-6.1/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-6.1/810-pci_disable_common_quirks.patch deleted file mode 100644 index ba06196f7cbbff..00000000000000 --- a/target/linux/generic/pending-6.1/810-pci_disable_common_quirks.patch +++ /dev/null @@ -1,62 +0,0 @@ -From: Gabor Juhos -Subject: debloat: add kernel config option to disabling common PCI quirks - -Signed-off-by: Gabor Juhos ---- - drivers/pci/Kconfig | 6 ++++++ - drivers/pci/quirks.c | 6 ++++++ - 2 files changed, 12 insertions(+) - ---- a/drivers/pci/Kconfig -+++ b/drivers/pci/Kconfig -@@ -118,6 +118,13 @@ config XEN_PCIDEV_FRONTEND - The PCI device frontend driver allows the kernel to import arbitrary - PCI devices from a PCI backend to support PCI driver domains. - -+config PCI_DISABLE_COMMON_QUIRKS -+ bool "PCI disable common quirks" -+ depends on PCI -+ help -+ If you don't know what to do here, say N. -+ -+ - config PCI_ATS - bool - ---- a/drivers/pci/quirks.c -+++ b/drivers/pci/quirks.c -@@ -207,6 +207,7 @@ static void quirk_mmio_always_on(struct - DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS - /* - * The Mellanox Tavor device gives false positive parity errors. Disable - * parity error reporting. -@@ -3393,6 +3394,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); - -+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ - /* - * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. - * To work around this, query the size it should be configured to by the -@@ -3418,6 +3421,8 @@ static void quirk_intel_ntb(struct pci_d - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb); - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ - /* - * Some BIOS implementations leave the Intel GPU interrupts enabled, even - * though no one is handling them (e.g., if the i915 driver is never -@@ -3456,6 +3461,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq); - -+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ - /* - * PCI devices which are on Intel chips can skip the 10ms delay - * before entering D3 mode. diff --git a/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch deleted file mode 100644 index fcb77e51747003..00000000000000 --- a/target/linux/generic/pending-6.1/811-pci_disable_usb_common_quirks.patch +++ /dev/null @@ -1,115 +0,0 @@ -From: Felix Fietkau -Subject: debloat: disable common USB quirks - -Signed-off-by: Felix Fietkau ---- - drivers/usb/host/pci-quirks.c | 16 ++++++++++++++++ - drivers/usb/host/pci-quirks.h | 18 +++++++++++++++++- - include/linux/usb/hcd.h | 7 +++++++ - 3 files changed, 40 insertions(+), 1 deletion(-) - ---- a/drivers/usb/host/pci-quirks.c -+++ b/drivers/usb/host/pci-quirks.c -@@ -128,6 +128,8 @@ struct amd_chipset_type { - u8 rev; - }; - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ - static struct amd_chipset_info { - struct pci_dev *nb_dev; - struct pci_dev *smbus_dev; -@@ -631,6 +633,10 @@ bool usb_amd_pt_check_port(struct device - } - EXPORT_SYMBOL_GPL(usb_amd_pt_check_port); - -+#endif /* CONFIG_PCI_DISABLE_COMMON_QUIRKS */ -+ -+#if IS_ENABLED(CONFIG_USB_UHCI_HCD) -+ - /* - * Make sure the controller is completely inactive, unable to - * generate interrupts or do DMA. -@@ -710,8 +716,17 @@ reset_needed: - uhci_reset_hc(pdev, base); - return 1; - } -+#else -+int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) -+{ -+ return 0; -+} -+ -+#endif - EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS -+ - static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) - { - u16 cmd; -@@ -1283,3 +1298,4 @@ static void quirk_usb_early_handoff(stru - } - DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff); -+#endif ---- a/drivers/usb/host/pci-quirks.h -+++ b/drivers/usb/host/pci-quirks.h -@@ -5,6 +5,9 @@ - #ifdef CONFIG_USB_PCI - void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); - int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); -+#endif /* CONFIG_USB_PCI */ -+ -+#if defined(CONFIG_USB_PCI) && !defined(CONFIG_PCI_DISABLE_COMMON_QUIRKS) - int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev); - bool usb_amd_hang_symptom_quirk(void); - bool usb_amd_prefetch_quirk(void); -@@ -19,6 +22,18 @@ void sb800_prefetch(struct device *dev, - bool usb_amd_pt_check_port(struct device *device, int port); - #else - struct pci_dev; -+static inline int usb_amd_quirk_pll_check(void) -+{ -+ return 0; -+} -+static inline bool usb_amd_hang_symptom_quirk(void) -+{ -+ return false; -+} -+static inline bool usb_amd_prefetch_quirk(void) -+{ -+ return false; -+} - static inline void usb_amd_quirk_pll_disable(void) {} - static inline void usb_amd_quirk_pll_enable(void) {} - static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {} -@@ -29,6 +44,11 @@ static inline bool usb_amd_pt_check_port - { - return false; - } -+static inline void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) {} -+static inline bool usb_xhci_needs_pci_reset(struct pci_dev *pdev) -+{ -+ return false; -+} - #endif /* CONFIG_USB_PCI */ - - #endif /* __LINUX_USB_PCI_QUIRKS_H */ ---- a/include/linux/usb/hcd.h -+++ b/include/linux/usb/hcd.h -@@ -484,7 +484,14 @@ extern int usb_hcd_pci_probe(struct pci_ - extern void usb_hcd_pci_remove(struct pci_dev *dev); - extern void usb_hcd_pci_shutdown(struct pci_dev *dev); - -+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS - extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev); -+#else -+static inline int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev) -+{ -+ return 0; -+} -+#endif - - #ifdef CONFIG_PM - extern const struct dev_pm_ops usb_hcd_pci_pm_ops; diff --git a/target/linux/generic/pending-6.1/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch b/target/linux/generic/pending-6.1/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch deleted file mode 100644 index 33eb34c913ea4a..00000000000000 --- a/target/linux/generic/pending-6.1/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d9c8bc8c1408f3e8529db6e4e04017b4c579c342 Mon Sep 17 00:00:00 2001 -From: Pawel Dembicki -Date: Sun, 18 Feb 2018 17:08:04 +0100 -Subject: [PATCH] w1: gpio: fix problem with platfom data in w1-gpio - -In devices, where fdt is used, is impossible to apply platform data -without proper fdt node. - -This patch allow to use platform data in devices with fdt. - -Signed-off-by: Pawel Dembicki ---- - drivers/w1/masters/w1-gpio.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/w1/masters/w1-gpio.c -+++ b/drivers/w1/masters/w1-gpio.c -@@ -76,7 +76,7 @@ static int w1_gpio_probe(struct platform - enum gpiod_flags gflags = GPIOD_OUT_LOW_OPEN_DRAIN; - int err; - -- if (of_have_populated_dt()) { -+ if (of_have_populated_dt() && !dev_get_platdata(&pdev->dev)) { - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; diff --git a/target/linux/generic/pending-6.1/834-ledtrig-libata.patch b/target/linux/generic/pending-6.1/834-ledtrig-libata.patch deleted file mode 100644 index 7ca586c67636d3..00000000000000 --- a/target/linux/generic/pending-6.1/834-ledtrig-libata.patch +++ /dev/null @@ -1,149 +0,0 @@ -From: Daniel Golle -Subject: libata: add ledtrig support - -This adds a LED trigger for each ATA port indicating disk activity. - -As this is needed only on specific platforms (NAS SoCs and such), -these platforms should define ARCH_WANTS_LIBATA_LEDS if there -are boards with LED(s) intended to indicate ATA disk activity and -need the OS to take care of that. -In that way, if not selected, LED trigger support not will be -included in libata-core and both, codepaths and structures remain -untouched. - -Signed-off-by: Daniel Golle ---- - drivers/ata/Kconfig | 16 ++++++++++++++++ - drivers/ata/libata-core.c | 41 +++++++++++++++++++++++++++++++++++++++++ - include/linux/libata.h | 9 +++++++++ - 3 files changed, 66 insertions(+) - ---- a/drivers/ata/Kconfig -+++ b/drivers/ata/Kconfig -@@ -67,6 +67,22 @@ config ATA_FORCE - - If unsure, say Y. - -+config ARCH_WANT_LIBATA_LEDS -+ bool -+ -+config ATA_LEDS -+ bool "support ATA port LED triggers" -+ depends on ARCH_WANT_LIBATA_LEDS -+ select NEW_LEDS -+ select LEDS_CLASS -+ select LEDS_TRIGGERS -+ default y -+ help -+ This option adds a LED trigger for each registered ATA port. -+ It is used to drive disk activity leds connected via GPIO. -+ -+ If unsure, say N. -+ - config ATA_ACPI - bool "ATA ACPI Support" - depends on ACPI ---- a/drivers/ata/libata-core.c -+++ b/drivers/ata/libata-core.c -@@ -663,6 +663,19 @@ u64 ata_tf_read_block(const struct ata_t - return block; - } - -+#ifdef CONFIG_ATA_LEDS -+#define LIBATA_BLINK_DELAY 20 /* ms */ -+static inline void ata_led_act(struct ata_port *ap) -+{ -+ unsigned long led_delay = LIBATA_BLINK_DELAY; -+ -+ if (unlikely(!ap->ledtrig)) -+ return; -+ -+ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0); -+} -+#endif -+ - /** - * ata_build_rw_tf - Build ATA taskfile for given read/write request - * @qc: Metadata associated with the taskfile to build -@@ -4716,6 +4729,9 @@ void __ata_qc_complete(struct ata_queued - link->active_tag = ATA_TAG_POISON; - ap->nr_active_links--; - } -+#ifdef CONFIG_ATA_LEDS -+ ata_led_act(ap); -+#endif - - /* clear exclusive status */ - if (unlikely(qc->flags & ATA_QCFLAG_CLEAR_EXCL && -@@ -5438,6 +5454,9 @@ struct ata_port *ata_port_alloc(struct a - ap->stats.unhandled_irq = 1; - ap->stats.idle_irq = 1; - #endif -+#ifdef CONFIG_ATA_LEDS -+ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); -+#endif - ata_sff_port_init(ap); - - return ap; -@@ -5476,6 +5495,12 @@ static void ata_host_release(struct kref - - kfree(ap->pmp_link); - kfree(ap->slave_link); -+#ifdef CONFIG_ATA_LEDS -+ if (ap->ledtrig) { -+ led_trigger_unregister(ap->ledtrig); -+ kfree(ap->ledtrig); -+ }; -+#endif - kfree(ap); - host->ports[i] = NULL; - } -@@ -5878,7 +5903,23 @@ int ata_host_register(struct ata_host *h - host->ports[i]->print_id = atomic_inc_return(&ata_print_id); - host->ports[i]->local_port_no = i + 1; - } -+#ifdef CONFIG_ATA_LEDS -+ for (i = 0; i < host->n_ports; i++) { -+ if (unlikely(!host->ports[i]->ledtrig)) -+ continue; - -+ snprintf(host->ports[i]->ledtrig_name, -+ sizeof(host->ports[i]->ledtrig_name), "ata%u", -+ host->ports[i]->print_id); -+ -+ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name; -+ -+ if (led_trigger_register(host->ports[i]->ledtrig)) { -+ kfree(host->ports[i]->ledtrig); -+ host->ports[i]->ledtrig = NULL; -+ } -+ } -+#endif - /* Create associated sysfs transport objects */ - for (i = 0; i < host->n_ports; i++) { - rc = ata_tport_add(host->dev,host->ports[i]); ---- a/include/linux/libata.h -+++ b/include/linux/libata.h -@@ -23,6 +23,9 @@ - #include - #include - #include -+#ifdef CONFIG_ATA_LEDS -+#include -+#endif - - /* - * Define if arch has non-standard setup. This is a _PCI_ standard -@@ -865,6 +868,12 @@ struct ata_port { - #ifdef CONFIG_ATA_ACPI - struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ - #endif -+ -+#ifdef CONFIG_ATA_LEDS -+ struct led_trigger *ledtrig; -+ char ledtrig_name[8]; -+#endif -+ - /* owned by EH */ - u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; - }; diff --git a/target/linux/generic/pending-6.1/840-hwrng-bcm2835-set-quality-to-1000.patch b/target/linux/generic/pending-6.1/840-hwrng-bcm2835-set-quality-to-1000.patch deleted file mode 100644 index 5ca8933d6fef4b..00000000000000 --- a/target/linux/generic/pending-6.1/840-hwrng-bcm2835-set-quality-to-1000.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d6988cf1d16faac56899918bb2b1be8d85155e3f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= -Date: Sat, 20 Feb 2021 18:36:38 +0100 -Subject: [PATCH] hwrng: bcm2835: set quality to 1000 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This allows devices without a high precission timer to reduce boot from >100s -to <30s. - -Signed-off-by: Álvaro Fernández Rojas ---- - drivers/char/hw_random/bcm2835-rng.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/char/hw_random/bcm2835-rng.c -+++ b/drivers/char/hw_random/bcm2835-rng.c -@@ -170,6 +170,7 @@ static int bcm2835_rng_probe(struct plat - priv->rng.init = bcm2835_rng_init; - priv->rng.read = bcm2835_rng_read; - priv->rng.cleanup = bcm2835_rng_cleanup; -+ priv->rng.quality = 1000; - - if (dev_of_node(dev)) { - rng_id = of_match_node(bcm2835_rng_of_match, dev->of_node); diff --git a/target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch b/target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch deleted file mode 100644 index fc61ee202a509a..00000000000000 --- a/target/linux/generic/pending-6.1/850-0023-PCI-aardvark-Make-main-irq_chip-structure-a-static-d.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 663b9f99bb35dbc0c7b685f71ee3668a60d31320 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marek=20Beh=C3=BAn?= -Date: Mon, 10 Jan 2022 02:02:00 +0100 -Subject: [PATCH] PCI: aardvark: Make main irq_chip structure a static driver - structure -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Marc Zyngier says [1] that we should use struct irq_chip as a global -static struct in the driver. Even though the structure currently -contains a dynamic member (parent_device), Marc says [2] that he plans -to kill it and make the structure completely static. - -We have already converted others irq_chip structures in this driver in -this way, but we omitted this one because the .name member is -dynamically created from device's name, and the name is displayed in -sysfs, so changing it would break sysfs ABI. - -The rationale for changing the name (to "advk-INT") in spite of sysfs -ABI, and thus allowing to convert to a static structure, is that after -the other changes we made in this series, the IRQ chip is basically -something different: it no logner generates ERR and PME interrupts (they -are generated by emulated bridge's rp_irq_chip). - -[1] https://lore.kernel.org/linux-pci/877dbcvngf.wl-maz@kernel.org/ -[2] https://lore.kernel.org/linux-pci/874k6gvkhz.wl-maz@kernel.org/ - -Signed-off-by: Marek Behún ---- - drivers/pci/controller/pci-aardvark.c | 25 +++++++------------------ - 1 file changed, 7 insertions(+), 18 deletions(-) - ---- a/drivers/pci/controller/pci-aardvark.c -+++ b/drivers/pci/controller/pci-aardvark.c -@@ -277,7 +277,6 @@ struct advk_pcie { - u8 wins_count; - struct irq_domain *rp_irq_domain; - struct irq_domain *irq_domain; -- struct irq_chip irq_chip; - raw_spinlock_t irq_lock; - struct irq_domain *msi_domain; - struct irq_domain *msi_inner_domain; -@@ -1426,14 +1425,19 @@ static void advk_pcie_irq_unmask(struct - raw_spin_unlock_irqrestore(&pcie->irq_lock, flags); - } - -+static struct irq_chip advk_irq_chip = { -+ .name = "advk-INT", -+ .irq_mask = advk_pcie_irq_mask, -+ .irq_unmask = advk_pcie_irq_unmask, -+}; -+ - static int advk_pcie_irq_map(struct irq_domain *h, - unsigned int virq, irq_hw_number_t hwirq) - { - struct advk_pcie *pcie = h->host_data; - - irq_set_status_flags(virq, IRQ_LEVEL); -- irq_set_chip_and_handler(virq, &pcie->irq_chip, -- handle_level_irq); -+ irq_set_chip_and_handler(virq, &advk_irq_chip, handle_level_irq); - irq_set_chip_data(virq, pcie); - - return 0; -@@ -1492,7 +1496,6 @@ static int advk_pcie_init_irq_domain(str - struct device *dev = &pcie->pdev->dev; - struct device_node *node = dev->of_node; - struct device_node *pcie_intc_node; -- struct irq_chip *irq_chip; - int ret = 0; - - raw_spin_lock_init(&pcie->irq_lock); -@@ -1503,28 +1506,14 @@ static int advk_pcie_init_irq_domain(str - return -ENODEV; - } - -- irq_chip = &pcie->irq_chip; -- -- irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq", -- dev_name(dev)); -- if (!irq_chip->name) { -- ret = -ENOMEM; -- goto out_put_node; -- } -- -- irq_chip->irq_mask = advk_pcie_irq_mask; -- irq_chip->irq_unmask = advk_pcie_irq_unmask; -- - pcie->irq_domain = - irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, - &advk_pcie_irq_domain_ops, pcie); - if (!pcie->irq_domain) { - dev_err(dev, "Failed to get a INTx IRQ domain\n"); - ret = -ENOMEM; -- goto out_put_node; - } - --out_put_node: - of_node_put(pcie_intc_node); - return ret; - } diff --git a/target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch b/target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch deleted file mode 100644 index cc6f1e0d9dbec4..00000000000000 --- a/target/linux/generic/pending-6.1/850-dt-bindings-clk-add-BCM63268-timer-clock-definitions.patch +++ /dev/null @@ -1,114 +0,0 @@ -From patchwork Wed Mar 22 17:15:12 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13184389 -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 73F2DC6FD1C - for ; Wed, 22 Mar 2023 17:15:59 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S231363AbjCVRP5 (ORCPT ); - Wed, 22 Mar 2023 13:15:57 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58824 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S231408AbjCVRPy (ORCPT - ); Wed, 22 Mar 2023 13:15:54 -0400 -Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com - [IPv6:2a00:1450:4864:20::32d]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70E4C64B28; - Wed, 22 Mar 2023 10:15:24 -0700 (PDT) -Received: by mail-wm1-x32d.google.com with SMTP id n19so1740892wms.0; - Wed, 22 Mar 2023 10:15:24 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679505322; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=dEknM98Izmc8d/crPsoJ+ejZxfl78958Ei6SPYhYDHs=; - b=LTOQ75W3s5nYo+nEfiJAKqytSopONB4jCtU3zRygzPMasugVOrYFMsUR+WrpsAjuRT - v4HgWpJxEsIWeRXrUN9W21mFXhGgJLJXSxRnrio0CsZZBNMdkebbNOphgKXIWAdm+2iM - PzqAdGm5t38wT2mmm6V/9hCy90+12raHM82tNFdhhiezfg2cukVOKP3j/TeOVCwas0gQ - iFc+CuZB6y73zYXvMUMUpTsqI5vev4xJsSMHIQJVmUxJAwqhOBhN9JCRo7Ao+wayjn2d - Fxo6AV3A8v68nVfoQ0K0I+eWXG48nMCX45iWh/lVvVTOFcR99kn4va7NY1oVnPsh+WQz - WcLA== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679505322; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=dEknM98Izmc8d/crPsoJ+ejZxfl78958Ei6SPYhYDHs=; - b=wv2NSR1B5RnsdoEE7mgJSHAfSs1JHZbQ1HPMldyaGWAk1dcucqh/uDzM3Flz+ADRi1 - 19NoaB2Ur7QaWZejbuplnIOK/nte3PnmqJ9ZNw8HejmuS4eU8mB1V1aJUSKSPGsfUi4a - LYe3HSw87l0jrAC7ptdKvdUtzBoIkX0CeFvfguTQQkDhUTyAFIG144hY6uPXY9Mga96b - gnNe2dLCzHQLbEJpaDaavT7FEEcLDxaq7jNcR2xqEEZaIwfcew+Q05t4xL/3i8GAj9Ru - 6ivQjIbBKfYQF88o7KnOW9o1wjrGsk+Nd4Iy0OLZix3JQasCJGrKV7ib5awI9J39upYV - fa4A== -X-Gm-Message-State: AO0yUKWw75I1M5Vjrd4vXq4GTruQu0H84pycgyi2CT3bczTYRJpWmEWg - +bHDhvp1n5IWW85GI9vKWpbclB13a/S0RQ== -X-Google-Smtp-Source: - AK7set9T/2oJsVetUb2L4mPEWu8YqDrnK8EzHK5bJf1ABIa1Et8f7BFJ7AA3j14ITZuf8cH0HqlRtg== -X-Received: by 2002:a05:600c:2304:b0:3ed:2949:985b with SMTP id - 4-20020a05600c230400b003ed2949985bmr206833wmo.23.1679505322457; - Wed, 22 Mar 2023 10:15:22 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.21 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Wed, 22 Mar 2023 10:15:22 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de, - f.fainelli@gmail.com, jonas.gorski@gmail.com, - william.zhang@broadcom.com, linux-clk@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= , - Rob Herring -Subject: [PATCH v4 1/4] dt-bindings: clk: add BCM63268 timer clock definitions -Date: Wed, 22 Mar 2023 18:15:12 +0100 -Message-Id: <20230322171515.120353-2-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230322171515.120353-1-noltari@gmail.com> -References: <20230322171515.120353-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: linux-clk@vger.kernel.org - -Add missing timer clock definitions for BCM63268. - -Signed-off-by: Álvaro Fernández Rojas -Acked-by: Rob Herring ---- - v4: no changes - v3: no changes - v2: change commit title, as suggested by Stephen Boyd - - include/dt-bindings/clock/bcm63268-clock.h | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - ---- a/include/dt-bindings/clock/bcm63268-clock.h -+++ b/include/dt-bindings/clock/bcm63268-clock.h -@@ -27,4 +27,17 @@ - #define BCM63268_CLK_TBUS 27 - #define BCM63268_CLK_ROBOSW250 31 - -+#define BCM63268_TCLK_EPHY1 0 -+#define BCM63268_TCLK_EPHY2 1 -+#define BCM63268_TCLK_EPHY3 2 -+#define BCM63268_TCLK_GPHY1 3 -+#define BCM63268_TCLK_DSL 4 -+#define BCM63268_TCLK_WAKEON_EPHY 6 -+#define BCM63268_TCLK_WAKEON_DSL 7 -+#define BCM63268_TCLK_FAP1 11 -+#define BCM63268_TCLK_FAP2 15 -+#define BCM63268_TCLK_UTO_50 16 -+#define BCM63268_TCLK_UTO_EXTIN 17 -+#define BCM63268_TCLK_USB_REF 18 -+ - #endif /* __DT_BINDINGS_CLOCK_BCM63268_H */ diff --git a/target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch b/target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch deleted file mode 100644 index 5f1be105ac7295..00000000000000 --- a/target/linux/generic/pending-6.1/851-dt-bindings-reset-add-BCM63268-timer-reset-definitions.patch +++ /dev/null @@ -1,107 +0,0 @@ -From patchwork Wed Mar 22 17:15:13 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13184390 -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id D0B1AC6FD1C - for ; Wed, 22 Mar 2023 17:16:08 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S231472AbjCVRQI (ORCPT ); - Wed, 22 Mar 2023 13:16:08 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58934 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S231435AbjCVRP5 (ORCPT - ); Wed, 22 Mar 2023 13:15:57 -0400 -Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com - [IPv6:2a00:1450:4864:20::329]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9655064863; - Wed, 22 Mar 2023 10:15:25 -0700 (PDT) -Received: by mail-wm1-x329.google.com with SMTP id - v4-20020a05600c470400b003ee4f06428fso2424553wmo.4; - Wed, 22 Mar 2023 10:15:25 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679505324; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=C7ykhArT1dO7P8wtmI92eo4c7KtPZI9w182/5+cB3T0=; - b=WRZRU2SM9n1LfUj4SgTPfQczADC2pfvoIrOsNpBLTym2eOfmkTetb/WbGSla5kw2Wb - SH5MIC2fFeScJg6T5FFAUOOLmRVW9xvl8Q3T3NKb3z/9wvPHO767nrdIbffRWMJFs7gW - wT/kuTpn8GYdfY0sZ/dMTkq41DVusEkxfX6GxtG85O98ZP8xMHQog8aPs9fRfUvI5ZKB - eGYcRz/Wn1cHhjey9jtWzQEEmZ/BT3b0HQTF9Tl88oofhiEgbyjFXr91+vRsLbsJpGXH - /1FjjaLG5DnonKubV9rmbuCU8KzwH331gi2KuRjvLD2V+OMewqSa5i+GvgVv8x2zC8y+ - /mLQ== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679505324; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=C7ykhArT1dO7P8wtmI92eo4c7KtPZI9w182/5+cB3T0=; - b=bhd0fNh0jDOMlGSC4F+p5igV8AUlGEPj2cXUwgdgqRfSSuUy9z+Li8cT0MbY/aWH5Z - qInRVA+R1cWV3ubrDyKag6oEc0LDU234bnMFcP9b7MRlrM8Dpit9TFSyqJU4sDUWNDs5 - KOe2k/SNIdat6munC9VOuEBDO0eB/UDMN+repKwXNdHChp/Toq9qMvW4Uy8uHxosbQlD - 8P88GbKFjynb1E8I8croGjfub7+y8PPsWB0xNUcafIv6xs3MnVOP1Mk4KwBCbqS509la - mfjsriXtIybO8XFqtn100ungjvbFWdogEplLdSPVdgAqdfF5J8gHxAoApoeYejYkL5/R - kOhQ== -X-Gm-Message-State: AO0yUKWdzr3dMmjKhD8tF+ec4Dfdq9VGZ/WCU4d85npKQvxSwhNPZZ1J - 5WYRIqivh0suFC1OqEidwenpiJYvXedYjw== -X-Google-Smtp-Source: - AK7set87ew2/mKWeShXTTW/YBbBJNR2zeGFV0CfuqLXhiJEU6tqFuyKcW+vFEoKHIbNUS8wRy1SzLA== -X-Received: by 2002:a05:600c:290:b0:3ee:6d88:774a with SMTP id - 16-20020a05600c029000b003ee6d88774amr160734wmk.14.1679505323514; - Wed, 22 Mar 2023 10:15:23 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.22 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Wed, 22 Mar 2023 10:15:23 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de, - f.fainelli@gmail.com, jonas.gorski@gmail.com, - william.zhang@broadcom.com, linux-clk@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= , - Rob Herring -Subject: [PATCH v4 2/4] dt-bindings: reset: add BCM63268 timer reset - definitions -Date: Wed, 22 Mar 2023 18:15:13 +0100 -Message-Id: <20230322171515.120353-3-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230322171515.120353-1-noltari@gmail.com> -References: <20230322171515.120353-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: linux-clk@vger.kernel.org - -Add missing timer reset definitions for BCM63268. - -Signed-off-by: Álvaro Fernández Rojas -Acked-by: Rob Herring ---- - v4: no changes - v3: no changes - v2: change commit title, as suggested by Stephen Boyd - - include/dt-bindings/reset/bcm63268-reset.h | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/include/dt-bindings/reset/bcm63268-reset.h -+++ b/include/dt-bindings/reset/bcm63268-reset.h -@@ -23,4 +23,8 @@ - #define BCM63268_RST_PCIE_HARD 17 - #define BCM63268_RST_GPHY 18 - -+#define BCM63268_TRST_SW 29 -+#define BCM63268_TRST_HW 30 -+#define BCM63268_TRST_POR 31 -+ - #endif /* __DT_BINDINGS_RESET_BCM63268_H */ diff --git a/target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch b/target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch deleted file mode 100644 index 7e500cd1b58c85..00000000000000 --- a/target/linux/generic/pending-6.1/852-clk-bcm-Add-BCM63268-timer-clock-and-reset-driver.patch +++ /dev/null @@ -1,345 +0,0 @@ -From patchwork Wed Mar 22 17:15:15 2023 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -X-Patchwork-Submitter: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= - -X-Patchwork-Id: 13184392 -Return-Path: -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org -Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) - by smtp.lore.kernel.org (Postfix) with ESMTP id 199D9C76196 - for ; Wed, 22 Mar 2023 17:16:11 +0000 (UTC) -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S231512AbjCVRQJ (ORCPT ); - Wed, 22 Mar 2023 13:16:09 -0400 -Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58942 "EHLO - lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org - with ESMTP id S231442AbjCVRP5 (ORCPT - ); Wed, 22 Mar 2023 13:15:57 -0400 -Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com - [IPv6:2a00:1450:4864:20::32c]) - by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DDB36487D; - Wed, 22 Mar 2023 10:15:27 -0700 (PDT) -Received: by mail-wm1-x32c.google.com with SMTP id - i5-20020a05600c354500b003edd24054e0so6717370wmq.4; - Wed, 22 Mar 2023 10:15:27 -0700 (PDT) -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=gmail.com; s=20210112; t=1679505325; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:from:to:cc:subject:date - :message-id:reply-to; - bh=rkv/eZYA1ncHp5FnV2ZWc3hgYnAx28S86QA9vmcXFCY=; - b=Y1mva2Bt3sUbKxLgEUS331CJbGxUc4z8kTQW8qiHWGhYlFKtm+d5z4sT40E5BeZAnU - zmTbCI7jbroe9NYBxGUmSli6LNVDPjND80ChbhWTqbqMQTmeQFWut9KmeBWK6Oze2lC/ - XMSOorUzowjcU2xtHNrzoq2KH2pstW573lsB8WnzFVfhMaRkE9DfRr6WNyA7zC8DyxM5 - ezxlCQtCmgPfCqlyksbIDKrgrRf3GiUR0yUd6xRU+MssyvH1FkYGDCerPctDto6lGHBz - 8Y15jT3l6OnQMT6dkekgpPF5/XrSUY93u9g0B4U8+0dhNj+K7vmDen+jqdess+tpLnq/ - gFrA== -X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; - d=1e100.net; s=20210112; t=1679505325; - h=content-transfer-encoding:mime-version:references:in-reply-to - :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc - :subject:date:message-id:reply-to; - bh=rkv/eZYA1ncHp5FnV2ZWc3hgYnAx28S86QA9vmcXFCY=; - b=Ym4+u8bbTQGNkewUBrLf+89vE0EFJBQp2f1crwUxZFboKTROF9ltZonY1CGepo7b0B - fkx3TbWQy5X65g3ScuieqtClCI8WanPeNBJ48+JipJYO3ODVNBxnVaTuW/0FOIcahfqe - sG5GvggHhzRz+Yeybsbnupmzxnw8Ez0BpMl3p7zcjHL7BGZDdOOX2Zbw3zfyYa5sg2nX - UXYJT36zy2h39gxUsy9QkhQ76CG3w6omniohZpYidpojpiDjbOy0nKFky4kUe+YyA1fF - 4IBhjAm6mH+uh6wHSG1qj+NAXHs0xDDJps16PbJwAgL7Qt9K5WW+R/UAYPmHFgaRIHOw - /seA== -X-Gm-Message-State: AO0yUKXRtoYO8Nfus6Ca8lhM39P1Xn6TGkhatEfoISd1YNOkTJJN2hW+ - xRphLgxlzNfCLcVPlpGK9dk= -X-Google-Smtp-Source: - AK7set9VnMEykugk8ZYnkXuqK41bX1dzlvKsAXHEjr8i2NZBld0buKhQLcGYEcwxnBgVTtC7eRGfXw== -X-Received: by 2002:a1c:7c0b:0:b0:3e2:1dac:b071 with SMTP id - x11-20020a1c7c0b000000b003e21dacb071mr178053wmc.13.1679505325582; - Wed, 22 Mar 2023 10:15:25 -0700 (PDT) -Received: from atlantis.lan (255.red-79-146-124.dynamicip.rima-tde.net. - [79.146.124.255]) - by smtp.gmail.com with ESMTPSA id - v10-20020a05600c470a00b003ee11ac2288sm8414333wmo.21.2023.03.22.10.15.24 - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Wed, 22 Mar 2023 10:15:25 -0700 (PDT) -From: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -To: mturquette@baylibre.com, sboyd@kernel.org, robh+dt@kernel.org, - krzysztof.kozlowski+dt@linaro.org, p.zabel@pengutronix.de, - f.fainelli@gmail.com, jonas.gorski@gmail.com, - william.zhang@broadcom.com, linux-clk@vger.kernel.org, - devicetree@vger.kernel.org, linux-kernel@vger.kernel.org -Cc: =?utf-8?q?=C3=81lvaro_Fern=C3=A1ndez_Rojas?= -Subject: [PATCH v4 4/4] clk: bcm: Add BCM63268 timer clock and reset driver -Date: Wed, 22 Mar 2023 18:15:15 +0100 -Message-Id: <20230322171515.120353-5-noltari@gmail.com> -X-Mailer: git-send-email 2.30.2 -In-Reply-To: <20230322171515.120353-1-noltari@gmail.com> -References: <20230322171515.120353-1-noltari@gmail.com> -MIME-Version: 1.0 -Precedence: bulk -List-ID: -X-Mailing-List: linux-clk@vger.kernel.org - -Add driver for BCM63268 timer clock and reset controller. - -Signed-off-by: Álvaro Fernández Rojas ---- - v4: add changes suggested by Stephen Boyd: - - Usage of of_device_get_match_data() isn't needed. - - Use devm_clk_hw_register_gate(). - - Drop clk_hw_unregister_gate(). - v3: add missing include to fix build warning - v2: add changes suggested by Stephen Boyd - - drivers/clk/bcm/Kconfig | 9 ++ - drivers/clk/bcm/Makefile | 1 + - drivers/clk/bcm/clk-bcm63268-timer.c | 215 +++++++++++++++++++++++++++ - 3 files changed, 225 insertions(+) - create mode 100644 drivers/clk/bcm/clk-bcm63268-timer.c - ---- a/drivers/clk/bcm/Kconfig -+++ b/drivers/clk/bcm/Kconfig -@@ -37,6 +37,15 @@ config CLK_BCM_63XX_GATE - Enable common clock framework support for Broadcom BCM63xx DSL SoCs - based on the MIPS architecture - -+config CLK_BCM63268_TIMER -+ bool "Broadcom BCM63268 timer clock and reset support" -+ depends on BMIPS_GENERIC || COMPILE_TEST -+ default BMIPS_GENERIC -+ select RESET_CONTROLLER -+ help -+ Enable timer clock and reset support for Broadcom BCM63268 DSL SoCs -+ based on the MIPS architecture. -+ - config CLK_BCM_KONA - bool "Broadcom Kona CCU clock support" - depends on ARCH_BCM_MOBILE || COMPILE_TEST ---- a/drivers/clk/bcm/Makefile -+++ b/drivers/clk/bcm/Makefile -@@ -1,6 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o - obj-$(CONFIG_CLK_BCM_63XX_GATE) += clk-bcm63xx-gate.o -+obj-$(CONFIG_CLK_BCM63268_TIMER) += clk-bcm63268-timer.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o - obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o ---- /dev/null -+++ b/drivers/clk/bcm/clk-bcm63268-timer.c -@@ -0,0 +1,215 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * BCM63268 Timer Clock and Reset Controller Driver -+ * -+ * Copyright (C) 2023 Álvaro Fernández Rojas -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define BCM63268_TIMER_RESET_SLEEP_MIN_US 10000 -+#define BCM63268_TIMER_RESET_SLEEP_MAX_US 20000 -+ -+struct bcm63268_tclkrst_hw { -+ void __iomem *regs; -+ spinlock_t lock; -+ -+ struct reset_controller_dev rcdev; -+ struct clk_hw_onecell_data data; -+}; -+ -+struct bcm63268_tclk_table_entry { -+ const char * const name; -+ u8 bit; -+}; -+ -+static const struct bcm63268_tclk_table_entry bcm63268_timer_clocks[] = { -+ { -+ .name = "ephy1", -+ .bit = BCM63268_TCLK_EPHY1, -+ }, { -+ .name = "ephy2", -+ .bit = BCM63268_TCLK_EPHY2, -+ }, { -+ .name = "ephy3", -+ .bit = BCM63268_TCLK_EPHY3, -+ }, { -+ .name = "gphy1", -+ .bit = BCM63268_TCLK_GPHY1, -+ }, { -+ .name = "dsl", -+ .bit = BCM63268_TCLK_DSL, -+ }, { -+ .name = "wakeon_ephy", -+ .bit = BCM63268_TCLK_WAKEON_EPHY, -+ }, { -+ .name = "wakeon_dsl", -+ .bit = BCM63268_TCLK_WAKEON_DSL, -+ }, { -+ .name = "fap1_pll", -+ .bit = BCM63268_TCLK_FAP1, -+ }, { -+ .name = "fap2_pll", -+ .bit = BCM63268_TCLK_FAP2, -+ }, { -+ .name = "uto_50", -+ .bit = BCM63268_TCLK_UTO_50, -+ }, { -+ .name = "uto_extin", -+ .bit = BCM63268_TCLK_UTO_EXTIN, -+ }, { -+ .name = "usb_ref", -+ .bit = BCM63268_TCLK_USB_REF, -+ }, { -+ /* sentinel */ -+ } -+}; -+ -+static inline struct bcm63268_tclkrst_hw * -+to_bcm63268_timer_reset(struct reset_controller_dev *rcdev) -+{ -+ return container_of(rcdev, struct bcm63268_tclkrst_hw, rcdev); -+} -+ -+static int bcm63268_timer_reset_update(struct reset_controller_dev *rcdev, -+ unsigned long id, bool assert) -+{ -+ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev); -+ unsigned long flags; -+ uint32_t val; -+ -+ spin_lock_irqsave(&reset->lock, flags); -+ val = __raw_readl(reset->regs); -+ if (assert) -+ val &= ~BIT(id); -+ else -+ val |= BIT(id); -+ __raw_writel(val, reset->regs); -+ spin_unlock_irqrestore(&reset->lock, flags); -+ -+ return 0; -+} -+ -+static int bcm63268_timer_reset_assert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ return bcm63268_timer_reset_update(rcdev, id, true); -+} -+ -+static int bcm63268_timer_reset_deassert(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ return bcm63268_timer_reset_update(rcdev, id, false); -+} -+ -+static int bcm63268_timer_reset_reset(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ bcm63268_timer_reset_update(rcdev, id, true); -+ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US, -+ BCM63268_TIMER_RESET_SLEEP_MAX_US); -+ -+ bcm63268_timer_reset_update(rcdev, id, false); -+ /* -+ * Ensure component is taken out reset state by sleeping also after -+ * deasserting the reset. Otherwise, the component may not be ready -+ * for operation. -+ */ -+ usleep_range(BCM63268_TIMER_RESET_SLEEP_MIN_US, -+ BCM63268_TIMER_RESET_SLEEP_MAX_US); -+ -+ return 0; -+} -+ -+static int bcm63268_timer_reset_status(struct reset_controller_dev *rcdev, -+ unsigned long id) -+{ -+ struct bcm63268_tclkrst_hw *reset = to_bcm63268_timer_reset(rcdev); -+ -+ return !(__raw_readl(reset->regs) & BIT(id)); -+} -+ -+static struct reset_control_ops bcm63268_timer_reset_ops = { -+ .assert = bcm63268_timer_reset_assert, -+ .deassert = bcm63268_timer_reset_deassert, -+ .reset = bcm63268_timer_reset_reset, -+ .status = bcm63268_timer_reset_status, -+}; -+ -+static int bcm63268_tclk_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ const struct bcm63268_tclk_table_entry *entry; -+ struct bcm63268_tclkrst_hw *hw; -+ struct clk_hw *clk; -+ u8 maxbit = 0; -+ int i, ret; -+ -+ for (entry = bcm63268_timer_clocks; entry->name; entry++) -+ maxbit = max(maxbit, entry->bit); -+ maxbit++; -+ -+ hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit), -+ GFP_KERNEL); -+ if (!hw) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, hw); -+ -+ spin_lock_init(&hw->lock); -+ -+ hw->data.num = maxbit; -+ for (i = 0; i < maxbit; i++) -+ hw->data.hws[i] = ERR_PTR(-ENODEV); -+ -+ hw->regs = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(hw->regs)) -+ return PTR_ERR(hw->regs); -+ -+ for (entry = bcm63268_timer_clocks; entry->name; entry++) { -+ clk = devm_clk_hw_register_gate(dev, entry->name, NULL, 0, -+ hw->regs, entry->bit, -+ CLK_GATE_BIG_ENDIAN, -+ &hw->lock); -+ if (IS_ERR(clk)) -+ return PTR_ERR(clk); -+ -+ hw->data.hws[entry->bit] = clk; -+ } -+ -+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, -+ &hw->data); -+ if (ret) -+ return ret; -+ -+ hw->rcdev.of_node = dev->of_node; -+ hw->rcdev.ops = &bcm63268_timer_reset_ops; -+ -+ ret = devm_reset_controller_register(dev, &hw->rcdev); -+ if (ret) -+ dev_err(dev, "Failed to register reset controller\n"); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm63268_tclk_dt_ids[] = { -+ { .compatible = "brcm,bcm63268-timer-clocks" }, -+ { /* sentinel */ } -+}; -+ -+static struct platform_driver bcm63268_tclk = { -+ .probe = bcm63268_tclk_probe, -+ .driver = { -+ .name = "bcm63268-timer-clock", -+ .of_match_table = bcm63268_tclk_dt_ids, -+ }, -+}; -+builtin_platform_driver(bcm63268_tclk); diff --git a/target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch b/target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch deleted file mode 100644 index 013261cb8f1136..00000000000000 --- a/target/linux/generic/pending-6.1/860-serial-8250_mtk-track-busclk-state-to-avoid-bus-error.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 629c701fc39f1ada9416e0766a86729e83bde86c Mon Sep 17 00:00:00 2001 -Message-ID: <629c701fc39f1ada9416e0766a86729e83bde86c.1694465766.git.daniel@makrotopia.org> -From: Daniel Golle -Date: Mon, 11 Sep 2023 21:27:44 +0100 -Subject: [PATCH] serial: 8250_mtk: track busclk state to avoid bus error -To: Greg Kroah-Hartman , - Jiri Slaby , - Matthias Brugger , - AngeloGioacchino Del Regno , - Daniel Golle , - John Ogness , - Chen-Yu Tsai , - Changqi Hu , - linux-kernel@vger.kernel.org, - linux-serial@vger.kernel.org, - linux-arm-kernel@lists.infradead.org, - linux-mediatek@lists.infradead.org - -Commit e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and -clock management") introduced polling a debug register to make sure -the UART is idle before disabling the bus clock. However, at least on -some MediaTek SoCs access to that very debug register requires the bus -clock being enabled. Hence calling the suspend function while already -in suspended state results in that register access triggering a bus -error. In order to avoid that, track the state of the bus clock and -only poll the debug register if not already in suspended state. - -Fixes: e32a83c70cf9 ("serial: 8250-mtk: modify mtk uart power and clock management") -Signed-off-by: Daniel Golle ---- - drivers/tty/serial/8250/8250_mtk.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - ---- a/drivers/tty/serial/8250/8250_mtk.c -+++ b/drivers/tty/serial/8250/8250_mtk.c -@@ -32,7 +32,7 @@ - #define MTK_UART_RXTRI_AD 0x14 /* RX Trigger address */ - #define MTK_UART_FRACDIV_L 0x15 /* Fractional divider LSB address */ - #define MTK_UART_FRACDIV_M 0x16 /* Fractional divider MSB address */ --#define MTK_UART_DEBUG0 0x18 -+#define MTK_UART_DEBUG0 0x18 - #define MTK_UART_IER_XOFFI 0x20 /* Enable XOFF character interrupt */ - #define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */ - #define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */ -@@ -422,13 +422,12 @@ static int __maybe_unused mtk8250_runtim - struct mtk8250_data *data = dev_get_drvdata(dev); - struct uart_8250_port *up = serial8250_get_port(data->line); - -- /* wait until UART in idle status */ -- while -- (serial_in(up, MTK_UART_DEBUG0)); -- - if (data->clk_count == 0U) { - dev_dbg(dev, "%s clock count is 0\n", __func__); - } else { -+ /* wait until UART in idle status */ -+ while -+ (serial_in(up, MTK_UART_DEBUG0)); - clk_disable_unprepare(data->bus_clk); - data->clk_count--; - } diff --git a/target/linux/generic/pending-6.1/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch b/target/linux/generic/pending-6.1/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch deleted file mode 100644 index e25389363ffd8d..00000000000000 --- a/target/linux/generic/pending-6.1/870-ARM-dts-nxp-imx7d-pico-add-cpu-supply-nodes.patch +++ /dev/null @@ -1,43 +0,0 @@ -From d0562705bcd4cb9849156f095b2af0ec1bb53b56 Mon Sep 17 00:00:00 2001 -From: Lech Perczak -Date: Fri, 17 Nov 2023 21:33:04 +0100 -Subject: [PATCH] ARM: dts: nxp: imx7d-pico: add cpu-supply nodes - -The PICO-IMX7D SoM has the usual power supply configuration using -output sw1a of PF3000 PMIC, which was defined in downstream derivative -of linux-imx (see link) in the sources for "Android Things" devkit. -It is required to support CPU frequency scaling. - -Map the respective "cpu-supply" nodes of each core to sw1a of the PMIC. - -Enabling them causes cpufreq-dt, and imx-thermal drivers to probe -successfully, and CPU frequency scaling to function. - -Link: https://android.googlesource.com/platform/hardware/bsp/kernel/nxp/imx-v4.1/+/o-iot-preview-5/arch/arm/boot/dts/imx7d-pico.dtsi#849 - -Cc: Fabio Estevam -Cc: Shawn Guo -Cc: Sascha Hauer - -Signed-off-by: Lech Perczak ---- - arch/arm/boot/dts/imx7d-pico.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/arch/arm/boot/dts/imx7d-pico.dtsi -+++ b/arch/arm/boot/dts/imx7d-pico.dtsi -@@ -108,6 +108,14 @@ - assigned-clock-rates = <0>, <32768>; - }; - -+&cpu0 { -+ cpu-supply = <&sw1a_reg>; -+}; -+ -+&cpu1 { -+ cpu-supply = <&sw1a_reg>; -+}; -+ - &ecspi3 { - cs-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; - pinctrl-names = "default"; diff --git a/target/linux/generic/pending-6.1/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch b/target/linux/generic/pending-6.1/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch deleted file mode 100644 index 3321b03f28722d..00000000000000 --- a/target/linux/generic/pending-6.1/880-01-dt-bindings-leds-add-LED_FUNCTION_MOBILE-for-mobile-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 38eb5b3370c29515d2ce92adac2d6eba96f276f5 Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Wed, 20 Mar 2024 15:32:18 +0900 -Subject: [PATCH v2 1/2] dt-bindings: leds: add LED_FUNCTION_MOBILE for mobile - network - -Add LED_FUNCTION_MOBILE for LEDs that indicate status of mobile network -connection. This is useful to distinguish those LEDs from LEDs that -indicates status of wired "wan" connection. - -example (on stock fw): - -IIJ SA-W2 has "Mobile" LEDs that indicate status (no signal, too low, -low, good) of mobile network connection via dongle connected to USB -port. - -- no signal: (none, turned off) -- too low: green:mobile & red:mobile (amber, blink) -- low: green:mobile & red:mobile (amber, turned on) -- good: green:mobile (turned on) - -Suggested-by: Hauke Mehrtens -Signed-off-by: INAGAKI Hiroshi ---- - include/dt-bindings/leds/common.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/dt-bindings/leds/common.h -+++ b/include/dt-bindings/leds/common.h -@@ -90,6 +90,7 @@ - #define LED_FUNCTION_INDICATOR "indicator" - #define LED_FUNCTION_LAN "lan" - #define LED_FUNCTION_MAIL "mail" -+#define LED_FUNCTION_MOBILE "mobile" - #define LED_FUNCTION_MTD "mtd" - #define LED_FUNCTION_PANIC "panic" - #define LED_FUNCTION_PROGRAMMING "programming" diff --git a/target/linux/generic/pending-6.1/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch b/target/linux/generic/pending-6.1/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch deleted file mode 100644 index ab27cd33997bf8..00000000000000 --- a/target/linux/generic/pending-6.1/880-02-dt-bindings-leds-add-LED_FUNCTION_SPEED_-for-link-sp.patch +++ /dev/null @@ -1,37 +0,0 @@ -From e22afe910afcfb51b6ba6a0ae776939959727f54 Mon Sep 17 00:00:00 2001 -From: INAGAKI Hiroshi -Date: Wed, 20 Mar 2024 15:59:06 +0900 -Subject: [PATCH v2 2/2] dt-bindings: leds: add LED_FUNCTION_SPEED_* for link - speed on LAN/WAN - -Add LED_FUNCTION_SPEED_LAN and LED_FUNCTION_SPEED_WAN for LEDs that -indicate link speed of ethernet ports on LAN/WAN. This is useful to -distinguish those LEDs from LEDs that indicate link status (up/down). - -example: - -Fortinet FortiGate 30E/50E have LEDs that indicate link speed on each -of the ethernet ports in addition to LEDs that indicate link status -(up/down). - -- 1000 Mbps: green:speed-(lan|wan)-N -- 100 Mbps: amber:speed-(lan|wan)-N -- 10 Mbps: (none, turned off) - -Reviewed-by: Rob Herring -Signed-off-by: INAGAKI Hiroshi ---- - include/dt-bindings/leds/common.h | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/include/dt-bindings/leds/common.h -+++ b/include/dt-bindings/leds/common.h -@@ -96,6 +96,8 @@ - #define LED_FUNCTION_PROGRAMMING "programming" - #define LED_FUNCTION_RX "rx" - #define LED_FUNCTION_SD "sd" -+#define LED_FUNCTION_SPEED_LAN "speed-lan" -+#define LED_FUNCTION_SPEED_WAN "speed-wan" - #define LED_FUNCTION_STANDBY "standby" - #define LED_FUNCTION_TORCH "torch" - #define LED_FUNCTION_TX "tx" diff --git a/target/linux/generic/pending-6.1/920-mangle_bootargs.patch b/target/linux/generic/pending-6.1/920-mangle_bootargs.patch deleted file mode 100644 index f239c5824fd108..00000000000000 --- a/target/linux/generic/pending-6.1/920-mangle_bootargs.patch +++ /dev/null @@ -1,71 +0,0 @@ -From: Imre Kaloz -Subject: init: add CONFIG_MANGLE_BOOTARGS and disable it by default - -Enabling this option renames the bootloader supplied root= -and rootfstype= variables, which might have to be know but -would break the automatisms OpenWrt uses. - -Signed-off-by: Imre Kaloz ---- - init/Kconfig | 9 +++++++++ - init/main.c | 24 ++++++++++++++++++++++++ - 2 files changed, 33 insertions(+) - ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1836,6 +1836,15 @@ config EMBEDDED - an embedded system so certain expert options are available - for configuration. - -+config MANGLE_BOOTARGS -+ bool "Rename offending bootargs" -+ depends on EXPERT -+ help -+ Sometimes the bootloader passed bogus root= and rootfstype= -+ parameters to the kernel, and while you want to ignore them, -+ you need to know the values f.e. to support dual firmware -+ layouts on the flash. -+ - config HAVE_PERF_EVENTS - bool - help ---- a/init/main.c -+++ b/init/main.c -@@ -611,6 +611,29 @@ static inline void setup_nr_cpu_ids(void - static inline void smp_prepare_cpus(unsigned int maxcpus) { } - #endif - -+#ifdef CONFIG_MANGLE_BOOTARGS -+static void __init mangle_bootargs(char *command_line) -+{ -+ char *rootdev; -+ char *rootfs; -+ -+ rootdev = strstr(command_line, "root=/dev/mtdblock"); -+ -+ if (rootdev) -+ strncpy(rootdev, "mangled_rootblock=", 18); -+ -+ rootfs = strstr(command_line, "rootfstype"); -+ -+ if (rootfs) -+ strncpy(rootfs, "mangled_fs", 10); -+ -+} -+#else -+static void __init mangle_bootargs(char *command_line) -+{ -+} -+#endif -+ - /* - * We need to store the untouched command line for future reference. - * We also need to store the touched command line since the parameter -@@ -960,6 +983,7 @@ asmlinkage __visible void __init __no_sa - pr_notice("%s", linux_banner); - early_security_init(); - setup_arch(&command_line); -+ mangle_bootargs(command_line); - setup_boot_config(); - setup_command_line(command_line); - setup_nr_cpu_ids(); diff --git a/target/linux/generic/pending-6.1/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch b/target/linux/generic/pending-6.1/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch deleted file mode 100644 index 6a0a19987fad6b..00000000000000 --- a/target/linux/generic/pending-6.1/980-tools-thermal-tmon-Fix-compilation-warning-for-wrong.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a7a94ca21ac0f347f683d33c72b4aab57ce5eec3 Mon Sep 17 00:00:00 2001 -From: Florian Eckert -Date: Mon, 20 Nov 2023 11:13:20 +0100 -Subject: [PATCH] tools/thermal/tmon: Fix compilation warning for wrong format - -The following warnings are shown during compilation: - -tui.c: In function 'show_cooling_device': - tui.c:216:40: warning: format '%d' expects argument of type 'int', but -argument 7 has type 'long unsigned int' [-Wformat=] - 216 | "%02d %12.12s%6d %6d", - | ~~^ - | | - | int - | %6ld - ...... - 219 | ptdata.cdi[j].cur_state, - | ~~~~~~~~~~~~~~~~~~~~~~~ - | | - | long unsigned int - tui.c:216:44: warning: format '%d' expects argument of type 'int', but -argument 8 has type 'long unsigned int' [-Wformat=] - 216 | "%02d %12.12s%6d %6d", - | ~~^ - | | - | int - | %6ld - ...... - 220 | ptdata.cdi[j].max_state); - | ~~~~~~~~~~~~~~~~~~~~~~~ - | | - | long unsigned int - -To fix this, the correct string format must be used for printing. - -Signed-off-by: Florian Eckert ---- - tools/thermal/tmon/tui.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/tools/thermal/tmon/tui.c -+++ b/tools/thermal/tmon/tui.c -@@ -213,7 +213,7 @@ void show_cooling_device(void) - * cooling device instances. skip unused idr. - */ - mvwprintw(cooling_device_window, j + 2, 1, -- "%02d %12.12s%6d %6d", -+ "%02d %12.12s%6lu %6lu", - ptdata.cdi[j].instance, - ptdata.cdi[j].type, - ptdata.cdi[j].cur_state, From 3660ddb8ab6e6e4673576a0ee520ea38c67b9d75 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 20 Sep 2024 19:24:17 +0100 Subject: [PATCH 18/23] generic: ar8216: remove support for Linux before version 6.1 Drop support for older kernel versions from legacy AR8216 switch driver. Signed-off-by: Daniel Golle --- target/linux/generic/files/drivers/net/phy/ar8216.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index 850bcefb74e26e..84b923ffc12518 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -35,7 +35,6 @@ #include #include #include -#include #include "ar8216.h" @@ -2458,11 +2457,7 @@ ar8xxx_phy_config_init(struct phy_device *phydev) /* VID fixup only needed on ar8216 */ if (chip_is_ar8216(priv)) { dev->phy_ptr = priv; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) dev->priv_flags |= IFF_NO_IP_ALIGN; -#else - dev->extra_priv_flags |= IFF_NO_IP_ALIGN; -#endif dev->eth_mangle_rx = ar8216_mangle_rx; dev->eth_mangle_tx = ar8216_mangle_tx; } @@ -2697,11 +2692,7 @@ ar8xxx_phy_detach(struct phy_device *phydev) #ifdef CONFIG_ETHERNET_PACKET_MANGLE dev->phy_ptr = NULL; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) dev->priv_flags &= ~IFF_NO_IP_ALIGN; -#else - dev->extra_priv_flags &= ~IFF_NO_IP_ALIGN; -#endif dev->eth_mangle_rx = NULL; dev->eth_mangle_tx = NULL; #endif From 8181f09049a0e3188f35f27e5b53fc47b39eec87 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Fri, 20 Sep 2024 19:26:52 +0100 Subject: [PATCH 19/23] generic: remove support for older kernels from swconfig The legacy swconfig switch driver framework supports kernels older than Linux 6.6 by using #ifdef'ery with LINUX_VERSION_CODE. Remove all that. Signed-off-by: Daniel Golle --- .../generic/files/drivers/net/phy/swconfig.c | 3 --- .../files/drivers/net/phy/swconfig_leds.c | 16 ---------------- 2 files changed, 19 deletions(-) diff --git a/target/linux/generic/files/drivers/net/phy/swconfig.c b/target/linux/generic/files/drivers/net/phy/swconfig.c index 5fa2b147c6fca4..10dc8d0607aa93 100644 --- a/target/linux/generic/files/drivers/net/phy/swconfig.c +++ b/target/linux/generic/files/drivers/net/phy/swconfig.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #define SWCONFIG_DEVNAME "switch%d" @@ -1054,9 +1053,7 @@ static struct genl_family switch_fam = { .module = THIS_MODULE, .ops = swconfig_ops, .n_ops = ARRAY_SIZE(swconfig_ops), -#if LINUX_VERSION_CODE > KERNEL_VERSION(6,0,0) .resv_start_op = SWITCH_CMD_SET_VLAN + 1, -#endif }; #ifdef CONFIG_OF diff --git a/target/linux/generic/files/drivers/net/phy/swconfig_leds.c b/target/linux/generic/files/drivers/net/phy/swconfig_leds.c index 1d309c046c8df8..1fcd4432b54ef8 100644 --- a/target/linux/generic/files/drivers/net/phy/swconfig_leds.c +++ b/target/linux/generic/files/drivers/net/phy/swconfig_leds.c @@ -85,11 +85,7 @@ swconfig_trig_update_port_mask(struct led_trigger *trigger) sw_trig = (void *) trigger; port_mask = 0; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0) spin_lock(&trigger->leddev_list_lock); -#else - read_lock(&trigger->leddev_list_lock); -#endif list_for_each(entry, &trigger->led_cdevs) { struct led_classdev *led_cdev; struct swconfig_trig_data *trig_data; @@ -102,11 +98,7 @@ swconfig_trig_update_port_mask(struct led_trigger *trigger) read_unlock(&trig_data->lock); } } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0) spin_unlock(&trigger->leddev_list_lock); -#else - read_unlock(&trigger->leddev_list_lock); -#endif sw_trig->port_mask = port_mask; @@ -426,22 +418,14 @@ swconfig_trig_update_leds(struct switch_led_trigger *sw_trig) struct led_trigger *trigger; trigger = &sw_trig->trig; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0) spin_lock(&trigger->leddev_list_lock); -#else - read_lock(&trigger->leddev_list_lock); -#endif list_for_each(entry, &trigger->led_cdevs) { struct led_classdev *led_cdev; led_cdev = list_entry(entry, struct led_classdev, trig_list); swconfig_trig_led_event(sw_trig, led_cdev); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0) spin_unlock(&trigger->leddev_list_lock); -#else - read_unlock(&trigger->leddev_list_lock); -#endif } static void From 3efdc8e16d65e4404b1e29963e52b003c9b37dfc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 20 Sep 2024 23:15:24 +0200 Subject: [PATCH 20/23] qosify: update to Git HEAD (2024-09-20) 850cc271083d qosify: add support for keeping stats 1501e0935175 bpf_skb_utils.h: add missing include to fix build against newer kernel headers Signed-off-by: Felix Fietkau --- package/network/config/qosify/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/network/config/qosify/Makefile b/package/network/config/qosify/Makefile index 8e8c1b87135955..3c53c81f19cf32 100644 --- a/package/network/config/qosify/Makefile +++ b/package/network/config/qosify/Makefile @@ -11,9 +11,9 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=qosify PKG_SOURCE_URL=$(PROJECT_GIT)/project/qosify.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-03-07 -PKG_SOURCE_VERSION:=9a47ea4b683dd845ec94534fcd82d3117c9ab313 -PKG_MIRROR_HASH:=3d97456dcd13f481beff9a87d939e4bd671577865ed7cfc11b00d6e40f3e5621 +PKG_SOURCE_DATE:=2024-09-20 +PKG_SOURCE_VERSION:=1501e0935175d713ad229d88a8401dbfddc0a6b4 +PKG_MIRROR_HASH:=6d6e07285a6c46f040ba88555accc64c291837f9726944b9e41ec4efbaaf6c20 PKG_RELEASE:=1 PKG_LICENSE:=GPL-2.0 From 86251a7034942ecd7cc2cbfeb0625c0475bc0780 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 20 Sep 2024 23:17:28 +0200 Subject: [PATCH 21/23] bpf-headers: update to version 6.6 Signed-off-by: Felix Fietkau --- package/kernel/bpf-headers/Makefile | 2 +- .../patches/100-support_hz_300.patch | 4 +-- ...op-NL_SET_ERR_MSG-for-kernel-modules.patch | 30 ------------------- ...-use-NL_SET_ERR_MSG-instead-of-NL_SE.patch | 9 ++---- 4 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 package/kernel/bpf-headers/patches/101-linux-netlink-drop-NL_SET_ERR_MSG-for-kernel-modules.patch diff --git a/package/kernel/bpf-headers/Makefile b/package/kernel/bpf-headers/Makefile index e75da738e6862e..a644f47ab726f8 100644 --- a/package/kernel/bpf-headers/Makefile +++ b/package/kernel/bpf-headers/Makefile @@ -13,7 +13,7 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=linux -PKG_PATCHVER:=5.15 +PKG_PATCHVER:=6.6 # Manually include kernel version and hash from kernel details file include $(INCLUDE_DIR)/kernel-$(PKG_PATCHVER) diff --git a/package/kernel/bpf-headers/patches/100-support_hz_300.patch b/package/kernel/bpf-headers/patches/100-support_hz_300.patch index 9629958598e7a4..f2fba44bce42ab 100644 --- a/package/kernel/bpf-headers/patches/100-support_hz_300.patch +++ b/package/kernel/bpf-headers/patches/100-support_hz_300.patch @@ -1,6 +1,6 @@ --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -2988,6 +2988,9 @@ choice +@@ -2820,6 +2820,9 @@ choice config HZ_256 bool "256 HZ" if SYS_SUPPORTS_256HZ || SYS_SUPPORTS_ARBIT_HZ @@ -10,7 +10,7 @@ config HZ_1000 bool "1000 HZ" if SYS_SUPPORTS_1000HZ || SYS_SUPPORTS_ARBIT_HZ -@@ -3039,6 +3042,7 @@ config HZ +@@ -2871,6 +2874,7 @@ config HZ default 128 if HZ_128 default 250 if HZ_250 default 256 if HZ_256 diff --git a/package/kernel/bpf-headers/patches/101-linux-netlink-drop-NL_SET_ERR_MSG-for-kernel-modules.patch b/package/kernel/bpf-headers/patches/101-linux-netlink-drop-NL_SET_ERR_MSG-for-kernel-modules.patch deleted file mode 100644 index 5771b329540d44..00000000000000 --- a/package/kernel/bpf-headers/patches/101-linux-netlink-drop-NL_SET_ERR_MSG-for-kernel-modules.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7ed95633bff19950069c348b94c9c13164a57a2a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Wed, 18 Jan 2023 20:20:39 +0100 -Subject: [PATCH] linux/netlink: drop NL_SET_ERR_MSG for kernel modules - -We don't need NL_SET_ERR_MSG_MOD for bpf modules and we can drop it to -solve missing KBUILD_MODNAME define. - -Signed-off-by: Christian Marangi ---- - include/linux/netlink.h | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/include/linux/netlink.h b/include/linux/netlink.h -index 61b1c7f..93561fb 100644 ---- a/include/linux/netlink.h -+++ b/include/linux/netlink.h -@@ -98,9 +98,6 @@ struct netlink_ext_ack { - __extack->_msg = __msg; \ - } while (0) - --#define NL_SET_ERR_MSG_MOD(extack, msg) \ -- NL_SET_ERR_MSG((extack), KBUILD_MODNAME ": " msg) -- - #define NL_SET_BAD_ATTR_POLICY(extack, attr, pol) do { \ - if ((extack)) { \ - (extack)->bad_attr = (attr); \ --- -2.38.1 - diff --git a/package/kernel/bpf-headers/patches/102-net-flow_offload-use-NL_SET_ERR_MSG-instead-of-NL_SE.patch b/package/kernel/bpf-headers/patches/102-net-flow_offload-use-NL_SET_ERR_MSG-instead-of-NL_SE.patch index 4dec16874ef19c..bcaadc95a01297 100644 --- a/package/kernel/bpf-headers/patches/102-net-flow_offload-use-NL_SET_ERR_MSG-instead-of-NL_SE.patch +++ b/package/kernel/bpf-headers/patches/102-net-flow_offload-use-NL_SET_ERR_MSG-instead-of-NL_SE.patch @@ -12,11 +12,9 @@ Signed-off-by: Christian Marangi include/net/flow_offload.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) -diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h -index 7a2b022..f17c485 100644 --- a/include/net/flow_offload.h +++ b/include/net/flow_offload.h -@@ -321,7 +321,7 @@ flow_action_mixed_hw_stats_check(const struct flow_action *action, +@@ -376,7 +376,7 @@ flow_action_mixed_hw_stats_check(const s flow_action_for_each(i, action_entry, action) { if (i && action_entry->hw_stats != last_hw_stats) { @@ -25,7 +23,7 @@ index 7a2b022..f17c485 100644 return false; } last_hw_stats = action_entry->hw_stats; -@@ -356,11 +356,11 @@ __flow_action_hw_stats_check(const struct flow_action *action, +@@ -411,11 +411,11 @@ __flow_action_hw_stats_check(const struc if (!check_allow_bit && ~action_entry->hw_stats & FLOW_ACTION_HW_STATS_ANY) { @@ -39,6 +37,3 @@ index 7a2b022..f17c485 100644 return false; } return true; --- -2.38.1 - From cb2a11f49c989d46bd366e52deac529e33118ce4 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Wed, 21 Aug 2024 23:46:10 +0100 Subject: [PATCH 22/23] generic: phy: aquantia: add pending patch to force MDI pair order Import pending patch to force MDI pair order. Signed-off-by: Daniel Golle --- ...hy-aquantia-enable-AQR112-and-AQR412.patch | 8 +- ...aquantia-fix-system-side-protocol-mi.patch | 2 +- ...ntia-add-PHY_IDs-for-AQR112-variants.patch | 6 +- ...tia-allow-forcing-order-of-MDI-pairs.patch | 104 ++++++++++++++++++ 4 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 target/linux/generic/pending-6.6/752-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch diff --git a/target/linux/generic/hack-6.6/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch b/target/linux/generic/hack-6.6/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch index cba05f4bbcd77c..4ebddb3b4560af 100644 --- a/target/linux/generic/hack-6.6/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch +++ b/target/linux/generic/hack-6.6/722-net-phy-aquantia-enable-AQR112-and-AQR412.patch @@ -15,7 +15,7 @@ Signed-off-by: Alex Marginean --- a/drivers/net/phy/aquantia/aquantia_main.c +++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -90,6 +90,29 @@ +@@ -96,6 +96,29 @@ #define AQR107_OP_IN_PROG_SLEEP 1000 #define AQR107_OP_IN_PROG_TIMEOUT 100000 @@ -45,7 +45,7 @@ Signed-off-by: Alex Marginean static int aqr107_get_sset_count(struct phy_device *phydev) { return AQR107_SGMII_STAT_SZ; -@@ -196,6 +219,51 @@ static int aqr_config_aneg(struct phy_de +@@ -202,6 +225,51 @@ static int aqr_config_aneg(struct phy_de return genphy_c45_check_and_restart_aneg(phydev, changed); } @@ -97,7 +97,7 @@ Signed-off-by: Alex Marginean static int aqr_config_intr(struct phy_device *phydev) { bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED; -@@ -815,7 +883,7 @@ static struct phy_driver aqr_driver[] = +@@ -848,7 +916,7 @@ static struct phy_driver aqr_driver[] = PHY_ID_MATCH_MODEL(PHY_ID_AQR112), .name = "Aquantia AQR112", .probe = aqr107_probe, @@ -106,7 +106,7 @@ Signed-off-by: Alex Marginean .config_intr = aqr_config_intr, .handle_interrupt = aqr_handle_interrupt, .get_tunable = aqr107_get_tunable, -@@ -838,7 +906,7 @@ static struct phy_driver aqr_driver[] = +@@ -871,7 +939,7 @@ static struct phy_driver aqr_driver[] = PHY_ID_MATCH_MODEL(PHY_ID_AQR412), .name = "Aquantia AQR412", .probe = aqr107_probe, diff --git a/target/linux/generic/hack-6.6/723-net-phy-aquantia-fix-system-side-protocol-mi.patch b/target/linux/generic/hack-6.6/723-net-phy-aquantia-fix-system-side-protocol-mi.patch index b5e35dfdd75892..b0cd8016018beb 100644 --- a/target/linux/generic/hack-6.6/723-net-phy-aquantia-fix-system-side-protocol-mi.patch +++ b/target/linux/generic/hack-6.6/723-net-phy-aquantia-fix-system-side-protocol-mi.patch @@ -14,7 +14,7 @@ Signed-off-by: Alex Marginean --- a/drivers/net/phy/aquantia/aquantia_main.c +++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -252,10 +252,16 @@ static int aqr_config_aneg_set_prot(stru +@@ -258,10 +258,16 @@ static int aqr_config_aneg_set_prot(stru phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, aquantia_syscfg[if_type].start_rate); diff --git a/target/linux/generic/hack-6.6/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch b/target/linux/generic/hack-6.6/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch index 78ba501145dbc9..b3767f13464ecf 100644 --- a/target/linux/generic/hack-6.6/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch +++ b/target/linux/generic/hack-6.6/725-net-phy-aquantia-add-PHY_IDs-for-AQR112-variants.patch @@ -12,7 +12,7 @@ Signed-off-by: Daniel Golle --- a/drivers/net/phy/aquantia/aquantia_main.c +++ b/drivers/net/phy/aquantia/aquantia_main.c -@@ -30,6 +30,8 @@ +@@ -31,6 +31,8 @@ #define PHY_ID_AQR113C 0x31c31c12 #define PHY_ID_AQR114C 0x31c31c22 #define PHY_ID_AQR813 0x31c31cb2 @@ -21,7 +21,7 @@ Signed-off-by: Daniel Golle #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -@@ -1022,6 +1024,30 @@ static struct phy_driver aqr_driver[] = +@@ -1055,6 +1057,30 @@ static struct phy_driver aqr_driver[] = .led_hw_control_get = aqr_phy_led_hw_control_get, .led_polarity_set = aqr_phy_led_polarity_set, }, @@ -52,7 +52,7 @@ Signed-off-by: Daniel Golle }; module_phy_driver(aqr_driver); -@@ -1042,6 +1068,8 @@ static struct mdio_device_id __maybe_unu +@@ -1075,6 +1101,8 @@ static struct mdio_device_id __maybe_unu { PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) }, { PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) }, { PHY_ID_MATCH_MODEL(PHY_ID_AQR813) }, diff --git a/target/linux/generic/pending-6.6/752-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch b/target/linux/generic/pending-6.6/752-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch new file mode 100644 index 00000000000000..97e2953a5073e9 --- /dev/null +++ b/target/linux/generic/pending-6.6/752-net-phy-aquantia-allow-forcing-order-of-MDI-pairs.patch @@ -0,0 +1,104 @@ +From 49d46df79404a37685e0f32deb36506f5723e3a0 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Wed, 28 Aug 2024 23:52:09 +0100 +Subject: [PATCH] net: phy: aquantia: allow forcing order of MDI pairs + +Despite supporting Auto MDI-X, it looks like Aquantia only supports +swapping pair (1,2) with pair (3,6) like it used to be for MDI-X on +100MBit/s networks. + +When all 4 pairs are in use (for 1000MBit/s or faster) the link does not +come up with pair order is not configured correctly, either using +MDI_CFG pin or using the "PMA Receive Reserved Vendor Provisioning 1" +register. + +Normally, the order of MDI pairs being either ABCD or DCBA is configured +by pulling the MDI_CFG pin. + +However, some hardware designs require overriding the value configured +by that bootstrap pin. The PHY allows doing that by setting a bit in +"PMA Receive Reserved Vendor Provisioning 1" register which allows +ignoring the state of the MDI_CFG pin and another bit configuring +whether the order of MDI pairs should be normal (ABCD) or reverse +(DCBA). Pair polarity is not affected and remains identical in both +settings. + +Introduce property "marvell,mdi-cfg-order" which allows forcing either +normal or reverse order of the MDI pairs from DT. + +If the property isn't present, the behavior is unchanged and MDI pair +order configuration is untouched (ie. either the result of MDI_CFG pin +pull-up/pull-down, or pair order override already configured by the +bootloader before Linux is started). + +Forcing normal pair order is required on the Adtran SDG-8733A Wi-Fi 7 +residential gateway. + +Signed-off-by: Daniel Golle +--- + drivers/net/phy/aquantia/aquantia_main.c | 33 ++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +--- a/drivers/net/phy/aquantia/aquantia_main.c ++++ b/drivers/net/phy/aquantia/aquantia_main.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + + #include "aquantia.h" +@@ -70,6 +71,11 @@ + #define MDIO_AN_TX_VEND_INT_MASK2 0xd401 + #define MDIO_AN_TX_VEND_INT_MASK2_LINK BIT(0) + ++#define PMAPMD_RSVD_VEND_PROV 0xe400 ++#define PMAPMD_RSVD_VEND_PROV_MDI_CONF GENMASK(1, 0) ++#define PMAPMD_RSVD_VEND_PROV_MDI_REVERSE BIT(0) ++#define PMAPMD_RSVD_VEND_PROV_MDI_FORCE BIT(1) ++ + #define MDIO_AN_RX_LP_STAT1 0xe820 + #define MDIO_AN_RX_LP_STAT1_1000BASET_FULL BIT(15) + #define MDIO_AN_RX_LP_STAT1_1000BASET_HALF BIT(14) +@@ -497,6 +503,29 @@ static int aqr107_wait_processor_intensi + return 0; + } + ++static int aqr107_config_mdi(struct phy_device *phydev) ++{ ++ struct device_node *np = phydev->mdio.dev.of_node; ++ u32 mdi_conf; ++ int ret; ++ ++ ret = of_property_read_u32(np, "marvell,mdi-cfg-order", &mdi_conf); ++ ++ /* Do nothing in case property "marvell,mdi-cfg-order" is not present */ ++ if (ret == -ENOENT) ++ return 0; ++ ++ if (ret) ++ return ret; ++ ++ if (mdi_conf & ~PMAPMD_RSVD_VEND_PROV_MDI_REVERSE) ++ return -EINVAL; ++ ++ return phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_RSVD_VEND_PROV, ++ PMAPMD_RSVD_VEND_PROV_MDI_CONF, ++ mdi_conf | PMAPMD_RSVD_VEND_PROV_MDI_FORCE); ++} ++ + static int aqr107_config_init(struct phy_device *phydev) + { + struct aqr107_priv *priv = phydev->priv; +@@ -535,6 +564,10 @@ static int aqr107_config_init(struct phy + if (ret) + return ret; + ++ ret = aqr107_config_mdi(phydev); ++ if (ret) ++ return ret; ++ + /* Restore LED polarity state after reset */ + for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) { + ret = aqr_phy_led_active_low_set(phydev, led_active_low, true); From d0a2b3f824c5e283caf31ceea49abf3022e7dc51 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Tue, 20 Aug 2024 23:14:30 +0100 Subject: [PATCH 23/23] mediatek: add Adtran SmartRG SDG-8733A Specification is similar to other devices of the MT Stuart series: * Mediatek MT7988D (3x Cortex-A73, up to 1.8 GHz clock speed) * 8 GiB eMMC * 2 GiB DDR4 RAM * 2500M/1000M/100M LAN port * 10000M/5000M/2500M/1000M/100M/10M WAN port * MT7992 Tri-band (2.4G, 5G, 6G) 2T2R+3T3R+3T3R 802.11be Wi-Fi * Renesas DA14531MOD Bluetooth * 2 buttons (Reset, Mesh/WPS) * uC-controlled RGB LED via I2C * 2x LED for the 2.5G port, 3x LED for the 10G port * 3.3V-level 115200 baud UART console via 4-pin Dupont connector exposed at the bottom of the device * USB-C PD power input Signed-off-by: Daniel Golle --- .../uboot-envtools/files/mediatek_filogic | 1 + .../lib/preinit/05_set_preinit_iface | 3 +- .../dts/mt7988a-smartrg-mt-stuart.dtsi | 6 +- .../dts/mt7988d-smartrg-SDG-8733A.dts | 153 ++++++++++++++++++ .../filogic/base-files/etc/board.d/01_leds | 8 + .../filogic/base-files/etc/board.d/02_network | 1 + .../etc/hotplug.d/ieee80211/11_fix_wifi_mac | 1 + .../base-files/lib/preinit/10_fix_eth_mac.sh | 3 +- .../base-files/lib/upgrade/platform.sh | 2 + target/linux/mediatek/image/filogic.mk | 8 + ...freq-mediatek-Add-support-for-MT7988.patch | 3 +- 11 files changed, 183 insertions(+), 6 deletions(-) create mode 100644 target/linux/mediatek/dts/mt7988d-smartrg-SDG-8733A.dts diff --git a/package/boot/uboot-envtools/files/mediatek_filogic b/package/boot/uboot-envtools/files/mediatek_filogic index 417a3ad9de0cb7..73a7dc1517091d 100644 --- a/package/boot/uboot-envtools/files/mediatek_filogic +++ b/package/boot/uboot-envtools/files/mediatek_filogic @@ -108,6 +108,7 @@ openwrt,one) ubootenv_add_ubi_default ;; smartrg,sdg-8733|\ +smartrg,sdg-8733a|\ smartrg,sdg-8734) local envdev=$(find_mmc_part "u-boot-env" "mmcblk0") ubootenv_add_uci_config "$envdev" "0x0" "0x8000" "0x8000" diff --git a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface b/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface index 8e74c577cd505b..c982a8f1d8fc0c 100644 --- a/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface +++ b/target/linux/mediatek/base-files/lib/preinit/05_set_preinit_iface @@ -14,7 +14,8 @@ set_preinit_iface() { ifname=eth0 ;; smartrg,sdg-8622|\ - smartrg,sdg-8632) + smartrg,sdg-8632|\ + smartrg,sdg-8733a) ip link set lan up ifname=lan ;; diff --git a/target/linux/mediatek/dts/mt7988a-smartrg-mt-stuart.dtsi b/target/linux/mediatek/dts/mt7988a-smartrg-mt-stuart.dtsi index fac267abf4cd94..93bbd0103bb011 100644 --- a/target/linux/mediatek/dts/mt7988a-smartrg-mt-stuart.dtsi +++ b/target/linux/mediatek/dts/mt7988a-smartrg-mt-stuart.dtsi @@ -451,19 +451,19 @@ #address-cells = <1>; #size-cells = <0>; - led@0 { + aqr_green_led: led@0 { reg = <0>; function = LED_FUNCTION_LAN; color = ; }; - led@1 { + aqr_orange_led: led@1 { reg = <1>; function = LED_FUNCTION_LAN; color = ; }; - led@2 { + aqr_white_led: led@2 { reg = <2>; function = LED_FUNCTION_LAN; color = ; diff --git a/target/linux/mediatek/dts/mt7988d-smartrg-SDG-8733A.dts b/target/linux/mediatek/dts/mt7988d-smartrg-SDG-8733A.dts new file mode 100644 index 00000000000000..54fbbea0ba4253 --- /dev/null +++ b/target/linux/mediatek/dts/mt7988d-smartrg-SDG-8733A.dts @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2024 SmartRG Inc. + * Author: Chad Monroe + */ + +#include "mt7988a-smartrg-mt-stuart.dtsi" + +/ { + model = "SmartRG SDG-8733A"; + compatible = "smartrg,sdg-8733a", "mediatek,mt7988d"; + + cpus { + /delete-node/ cpu@3; + }; + + /delete-node/ gpio-export; + /delete-node/ gpio-leds; + + gpio-export { + compatible = "gpio-export"; + + bluetooth_reset: bluetooth-reset { + gpio-export,name = "bt_reset"; + gpio-export,direction_may_change; + gpios = <&pio 36 GPIO_ACTIVE_HIGH>; + }; + + bluetooth_txrx_ctl: bluetooth-txrx-ctl { + gpio-export,name = "bt_txrx_ctl"; + gpio-export,direction_may_change; + gpios = <&pio 37 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + lan_amber { + color = ; + function = "lan"; + gpios = <&pio 59 GPIO_ACTIVE_HIGH>; + }; + + lan_green { + color = ; + function = "lan"; + gpios = <&pio 60 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&fan { + pwms = <&pwm 1 40000 0>; + + interrupts = <57 IRQ_TYPE_EDGE_FALLING>; +}; + +&gmac0 { + status = "disabled"; +}; + +&gmac1 { + label = "lan"; + phy-mode = "internal"; + phy-connection-type = "internal"; + phy = <&int_2p5g_phy>; +}; + +&gmac2 { + label = "wan"; + phy-mode = "usxgmii"; + phy-connection-type = "usxgmii"; + phy = <&phy8>; +}; + +&int_2p5g_phy { + pinctrl-names = "i2p5gbe-led"; + pinctrl-0 = <&i2p5gbe_led0_pins>; +}; + +&mdio_bus { + /delete-node/ ethernet-phy@0; +}; + +&pio { + pcie3_1_pins: pcie3-pins-g1 { + mux { + function = "pcie"; + groups = "pcie_1l_1_pereset", "pcie_clk_req_n3"; + }; + }; +}; + +&pcie0 { + reset-gpios = <&pio 9 GPIO_ACTIVE_HIGH>; +}; + +&pcie1 { + status = "disabled"; +}; + +&pcie3 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie3_1_pins>; + status = "okay"; +}; + +&phy8 { + reset-gpios = <&pio 62 GPIO_ACTIVE_LOW>; + marvell,mdi-cfg-order = <0>; +}; + +&aqr_green_led { + function = LED_FUNCTION_WAN; +}; + +&aqr_orange_led { + function = LED_FUNCTION_WAN; +}; + +&aqr_white_led { + function = LED_FUNCTION_WAN; +}; + +&i2p5gbe_led0 { + color = ; + status = "okay"; +}; + +&ssusb0 { + status = "disabled"; +}; + +&ssusb1 { + status = "disabled"; +}; + +&switch { + status = "disabled"; +}; + +&tphy { + status = "disabled"; +}; + +&uart1 { + status = "disabled"; +}; + +&xphy { + status = "disabled"; +}; diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds index 82f61dd5d9b932..1437a120f56ed5 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds @@ -97,6 +97,14 @@ smartrg,sdg-8734) ucidef_set_led_netdev "wan-orange" "WAN" "mdio-bus:00:orange:wan" "wan" "link_100 link_1000" ucidef_set_led_netdev "wan-white" "WAN" "mdio-bus:00:white:wan" "wan" "link_10000" ;; +smartrg,sdg-8733a) + ucidef_set_led_netdev "lan-green-act" "LAN" "mdio-bus:0f:green:lan" "lan" "link_2500" + ucidef_set_led_netdev "lan-amber" "LAN" "amber:lan" "lan" "link_100" + ucidef_set_led_netdev "lan-green" "LAN" "green:lan" "lan" "link_1000" + ucidef_set_led_netdev "wan-green" "WAN" "mdio-bus:08:green:wan" "wan" "link_2500 link_5000" + ucidef_set_led_netdev "wan-orange" "WAN" "mdio-bus:08:orange:wan" "wan" "link_100 link_1000" + ucidef_set_led_netdev "wan-white" "WAN" "mdio-bus:08:white:wan" "wan" "link_10000" + ;; wavlink,wl-wn586x3) ucidef_set_led_netdev "lan-1" "lan-1" "blue:lan-1" "lan1" "link tx rx" ucidef_set_led_netdev "lan-2" "lan-2" "blue:lan-2" "lan2" "link tx rx" diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network index 1eecfa81e34181..74ee571bc02865 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network @@ -96,6 +96,7 @@ mediatek_setup_interfaces() ;; smartrg,sdg-8622|\ smartrg,sdg-8632|\ + smartrg,sdg-8733a|\ yuncore,ax835) ucidef_set_interfaces_lan_wan lan wan ;; diff --git a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac index 0b483bfa879149..3600e323409a37 100644 --- a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac +++ b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac @@ -149,6 +149,7 @@ case "$board" in [ "$PHYNBR" = "2" ] && macaddr_add $addr 4 > /sys${DEVPATH}/macaddress ;; smartrg,sdg-8733|\ + smartrg,sdg-8733a|\ smartrg,sdg-8734) addr=$(mmc_get_mac_ascii mfginfo MFG_MAC) [ "$PHYNBR" = "0" ] && macaddr_add $addr 4 > /sys${DEVPATH}/macaddress diff --git a/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh b/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh index fefca2327b5723..65bd5178242c1b 100644 --- a/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh +++ b/target/linux/mediatek/filogic/base-files/lib/preinit/10_fix_eth_mac.sh @@ -36,7 +36,8 @@ preinit_set_mac_address() { ip link set dev lan4 address "$lan_addr" ;; smartrg,sdg-8622|\ - smartrg,sdg-8632) + smartrg,sdg-8632|\ + smartrg,sdg-8733a) addr=$(mmc_get_mac_ascii mfginfo MFG_MAC) ip link set dev wan address "$addr" ip link set dev lan address "$(macaddr_add $addr 1)" diff --git a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh index bf4919653f4da1..429728392a1dbe 100755 --- a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh +++ b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh @@ -95,6 +95,7 @@ platform_do_upgrade() { smartrg,sdg-8622|\ smartrg,sdg-8632|\ smartrg,sdg-8733|\ + smartrg,sdg-8733a|\ smartrg,sdg-8734) CI_KERNPART="kernel" CI_ROOTPART="rootfs" @@ -211,6 +212,7 @@ platform_copy_config() { smartrg,sdg-8622|\ smartrg,sdg-8632|\ smartrg,sdg-8733|\ + smartrg,sdg-8733a|\ smartrg,sdg-8734|\ ubnt,unifi-6-plus) emmc_copy_config diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index e21794600dada9..522c7a01802e08 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -208,6 +208,14 @@ $(call Device/adtran_smartrg) endef TARGET_DEVICES += smartrg_sdg-8733 +define Device/smartrg_sdg-8733a +$(call Device/adtran_smartrg) + DEVICE_MODEL := SDG-8733A + DEVICE_DTS := mt7988d-smartrg-SDG-8733A + DEVICE_PACKAGES += mt7988-2p5g-phy-firmware kmod-mt7996-firmware kmod-phy-aquantia +endef +TARGET_DEVICES += smartrg_sdg-8733a + define Device/smartrg_sdg-8734 $(call Device/adtran_smartrg) DEVICE_MODEL := SDG-8734 diff --git a/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch b/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch index fbaac13b64358a..499918f3655519 100644 --- a/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch +++ b/target/linux/mediatek/patches-6.6/350-21-cpufreq-mediatek-Add-support-for-MT7988.patch @@ -51,11 +51,12 @@ Signed-off-by: Sam Shih static const struct mtk_cpufreq_platform_data mt8183_platform_data = { .min_volt_shift = 100000, .max_volt_shift = 200000, -@@ -740,6 +749,7 @@ static const struct of_device_id mtk_cpu +@@ -740,6 +749,8 @@ static const struct of_device_id mtk_cpu { .compatible = "mediatek,mt2712", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt7622", .data = &mt7622_platform_data }, { .compatible = "mediatek,mt7623", .data = &mt7623_platform_data }, + { .compatible = "mediatek,mt7988a", .data = &mt7988_platform_data }, ++ { .compatible = "mediatek,mt7988d", .data = &mt7988_platform_data }, { .compatible = "mediatek,mt8167", .data = &mt8516_platform_data }, { .compatible = "mediatek,mt817x", .data = &mt2701_platform_data }, { .compatible = "mediatek,mt8173", .data = &mt2701_platform_data },